Skip to content

Commit 6e034b6

Browse files
author
Jonathan Pallant (42 Technology)
committed
1 parent 377348c commit 6e034b6

File tree

1 file changed

+60
-4
lines changed

1 file changed

+60
-4
lines changed

nrf-hal-common/src/uarte.rs

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,6 @@ where
7373
}
7474
});
7575

76-
// Enable UARTE instance.
77-
uarte.enable.write(|w| w.enable().enabled());
78-
7976
// Configure.
8077
let hardware_flow_control = pins.rts.is_some() && pins.cts.is_some();
8178
uarte
@@ -84,8 +81,67 @@ where
8481

8582
// Configure frequency.
8683
uarte.baudrate.write(|w| w.baudrate().variant(baudrate));
84+
85+
let mut u = Uarte(uarte);
86+
87+
#[cfg(any(feature = "9160", feature = "5340"))]
88+
u.apply_workaround_for_enable_anomaly();
89+
90+
// Enable UARTE instance.
91+
u.0.enable.write(|w| w.enable().enabled());
92+
93+
u
94+
}
95+
96+
#[cfg(any(feature = "9160", feature = "5340"))]
97+
fn apply_workaround_for_enable_anomaly(&mut self)
98+
{
99+
// Apply workaround for anomalies:
100+
// - nRF9160 - anomaly 23
101+
// - nRF5340 - anomaly 44
102+
let rxenable_reg: *const u32 = ((self.0.deref() as *const _ as usize) + 0x564) as *const u32;
103+
let txenable_reg: *const u32 = ((self.0.deref() as *const _ as usize) + 0x568) as *const u32;
104+
105+
// NB Safety: This is taken from Nordic's driver -
106+
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
107+
if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 {
108+
self.0.tasks_stoprx.write(|w| unsafe { w.bits(1) });
109+
}
110+
111+
// NB Safety: This is taken from Nordic's driver -
112+
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
113+
if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 {
114+
self.0.enable.write(|w| w.enable().enabled());
115+
self.0.tasks_stoprx.write(|w| unsafe { w.bits(1) });
116+
117+
118+
let mut workaround_succeded = false;
119+
// The UARTE is able to receive up to four bytes after the STOPRX task has been triggered.
120+
// On lowest supported baud rate (1200 baud), with parity bit and two stop bits configured
121+
// (resulting in 12 bits per data byte sent), this may take up to 40 ms.
122+
for _ in 0..40000 {
123+
// NB Safety: This is taken from Nordic's driver -
124+
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
125+
if unsafe { core::ptr::read_volatile(rxenable_reg) } == 0 {
126+
workaround_succeded = true;
127+
break;
128+
}
129+
else
130+
{
131+
// Need to sleep for 1us here
132+
}
133+
}
87134

88-
Uarte(uarte)
135+
if !workaround_succeded
136+
{
137+
panic!("Failed to apply workaround for UART");
138+
}
139+
140+
let errors = self.0.errorsrc.read().bits();
141+
// NB Safety: safe to write back the bits we just read to clear them
142+
self.0.errorsrc.write(|w| unsafe { w.bits(errors) });
143+
self.0.enable.write(|w| w.enable().disabled());
144+
}
89145
}
90146

91147
/// Write via UARTE.

0 commit comments

Comments
 (0)