|
73 | 73 | }
|
74 | 74 | });
|
75 | 75 |
|
76 |
| - // Enable UARTE instance. |
77 |
| - uarte.enable.write(|w| w.enable().enabled()); |
78 |
| - |
79 | 76 | // Configure.
|
80 | 77 | let hardware_flow_control = pins.rts.is_some() && pins.cts.is_some();
|
81 | 78 | uarte
|
|
84 | 81 |
|
85 | 82 | // Configure frequency.
|
86 | 83 | 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 | + } |
87 | 134 |
|
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 | + } |
89 | 145 | }
|
90 | 146 |
|
91 | 147 | /// Write via UARTE.
|
|
0 commit comments