Added anomaly workaround from the HAL to improve the UARTE
This commit is contained in:
parent
2c2c284482
commit
ddcee446c1
@ -114,6 +114,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||
irq.enable();
|
||||
|
||||
// Enable
|
||||
Self::apply_workaround_for_enable_anomaly();
|
||||
r.enable.write(|w| w.enable().enabled());
|
||||
|
||||
Self {
|
||||
@ -121,6 +122,61 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "nrf9160", feature = "nrf5340")))]
|
||||
fn apply_workaround_for_enable_anomaly() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "nrf9160", feature = "nrf5340"))]
|
||||
fn apply_workaround_for_enable_anomaly() {
|
||||
use core::ops::Deref;
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
// Apply workaround for anomalies:
|
||||
// - nRF9160 - anomaly 23
|
||||
// - nRF5340 - anomaly 44
|
||||
let rxenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x564) as *const u32;
|
||||
let txenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x568) as *const u32;
|
||||
|
||||
// NB Safety: This is taken from Nordic's driver -
|
||||
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
|
||||
if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 {
|
||||
r.tasks_stoptx.write(|w| unsafe { w.bits(1) });
|
||||
}
|
||||
|
||||
// NB Safety: This is taken from Nordic's driver -
|
||||
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
|
||||
if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 {
|
||||
r.enable.write(|w| w.enable().enabled());
|
||||
r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
|
||||
|
||||
let mut workaround_succeded = false;
|
||||
// The UARTE is able to receive up to four bytes after the STOPRX task has been triggered.
|
||||
// On lowest supported baud rate (1200 baud), with parity bit and two stop bits configured
|
||||
// (resulting in 12 bits per data byte sent), this may take up to 40 ms.
|
||||
for _ in 0..40000 {
|
||||
// NB Safety: This is taken from Nordic's driver -
|
||||
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
|
||||
if unsafe { core::ptr::read_volatile(rxenable_reg) } == 0 {
|
||||
workaround_succeded = true;
|
||||
break;
|
||||
} else {
|
||||
// Need to sleep for 1us here
|
||||
}
|
||||
}
|
||||
|
||||
if !workaround_succeded {
|
||||
panic!("Failed to apply workaround for UART");
|
||||
}
|
||||
|
||||
let errors = r.errorsrc.read().bits();
|
||||
// NB Safety: safe to write back the bits we just read to clear them
|
||||
r.errorsrc.write(|w| unsafe { w.bits(errors) });
|
||||
r.enable.write(|w| w.enable().disabled());
|
||||
}
|
||||
}
|
||||
|
||||
fn on_interrupt(_: *mut ()) {
|
||||
let r = T::regs();
|
||||
let s = T::state();
|
||||
|
Loading…
Reference in New Issue
Block a user