aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/uarte.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-03-27 02:08:58 +0100
committerDario Nieuwenhuis <[email protected]>2021-03-29 00:58:58 +0200
commit3eccddc44db8d6c91d874a7be353aef3c90b8d43 (patch)
treee7aa2daaa40dad75500f4e17d02a4ad60d0f5e62 /embassy-nrf/src/uarte.rs
parent1c9f98e1b63296602da2aac0103bea917dcbdcd9 (diff)
nrf/uarte: use rxstarted/txstarted events to track whether a wait for stop is necessary on drop.
Diffstat (limited to 'embassy-nrf/src/uarte.rs')
-rw-r--r--embassy-nrf/src/uarte.rs23
1 files changed, 9 insertions, 14 deletions
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 06493da69..63dedcdcc 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -40,8 +40,6 @@ impl Default for Config {
40 40
41struct State<T: Instance> { 41struct State<T: Instance> {
42 peri: T, 42 peri: T,
43 did_stoprx: AtomicBool,
44 did_stoptx: AtomicBool,
45 43
46 endrx_waker: AtomicWaker, 44 endrx_waker: AtomicWaker,
47 endtx_waker: AtomicWaker, 45 endtx_waker: AtomicWaker,
@@ -102,6 +100,11 @@ impl<'d, T: Instance> Uarte<'d, T> {
102 // Disable all interrupts 100 // Disable all interrupts
103 r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); 101 r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) });
104 102
103 // Reset rxstarted, txstarted. These are used by drop to know whether a transfer was
104 // stopped midway or not.
105 r.events_rxstarted.reset();
106 r.events_txstarted.reset();
107
105 // Enable 108 // Enable
106 r.enable.write(|w| w.enable().enabled()); 109 r.enable.write(|w| w.enable().enabled());
107 110
@@ -109,8 +112,6 @@ impl<'d, T: Instance> Uarte<'d, T> {
109 inner: Peripheral::new( 112 inner: Peripheral::new(
110 irq, 113 irq,
111 State { 114 State {
112 did_stoprx: AtomicBool::new(false),
113 did_stoptx: AtomicBool::new(false),
114 peri: uarte, 115 peri: uarte,
115 endrx_waker: AtomicWaker::new(), 116 endrx_waker: AtomicWaker::new(),
116 endtx_waker: AtomicWaker::new(), 117 endtx_waker: AtomicWaker::new(),
@@ -129,8 +130,6 @@ impl<T: Instance> PeripheralState for State<T> {
129 type Interrupt = T::Interrupt; 130 type Interrupt = T::Interrupt;
130 131
131 fn on_interrupt(&self) { 132 fn on_interrupt(&self) {
132 info!("irq");
133
134 let r = self.peri.regs(); 133 let r = self.peri.regs();
135 if r.events_endrx.read().bits() != 0 { 134 if r.events_endrx.read().bits() != 0 {
136 self.endrx_waker.wake(); 135 self.endrx_waker.wake();
@@ -157,8 +156,8 @@ impl<'a, T: Instance> Drop for Uarte<'a, T> {
157 let s = unsafe { Pin::new_unchecked(&mut self.inner) }.state(); 156 let s = unsafe { Pin::new_unchecked(&mut self.inner) }.state();
158 let r = s.peri.regs(); 157 let r = s.peri.regs();
159 158
160 let did_stoprx = s.did_stoprx.load(Ordering::Relaxed); 159 let did_stoprx = r.events_rxstarted.read().bits() != 0;
161 let did_stoptx = s.did_stoptx.load(Ordering::Relaxed); 160 let did_stoptx = r.events_txstarted.read().bits() != 0;
162 info!("did_stoprx {} did_stoptx {}", did_stoprx, did_stoptx); 161 info!("did_stoprx {} did_stoptx {}", did_stoprx, did_stoptx);
163 162
164 // Wait for rxto or txstopped, if needed. 163 // Wait for rxto or txstopped, if needed.
@@ -196,7 +195,6 @@ impl<'d, T: Instance> Read for Uarte<'d, T> {
196 let s = self.inner().state(); 195 let s = self.inner().state();
197 let r = s.peri.regs(); 196 let r = s.peri.regs();
198 197
199 let did_stoprx = &s.did_stoprx;
200 let drop = OnDrop::new(move || { 198 let drop = OnDrop::new(move || {
201 info!("read drop: stopping"); 199 info!("read drop: stopping");
202 200
@@ -207,7 +205,6 @@ impl<'d, T: Instance> Read for Uarte<'d, T> {
207 while r.events_endrx.read().bits() == 0 {} 205 while r.events_endrx.read().bits() == 0 {}
208 206
209 info!("read drop: stopped"); 207 info!("read drop: stopped");
210 did_stoprx.store(true, Ordering::Relaxed);
211 }); 208 });
212 209
213 r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); 210 r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
@@ -231,7 +228,7 @@ impl<'d, T: Instance> Read for Uarte<'d, T> {
231 .await; 228 .await;
232 229
233 compiler_fence(Ordering::SeqCst); 230 compiler_fence(Ordering::SeqCst);
234 s.did_stoprx.store(false, Ordering::Relaxed); 231 r.events_rxstarted.reset();
235 drop.defuse(); 232 drop.defuse();
236 233
237 Ok(()) 234 Ok(())
@@ -255,7 +252,6 @@ impl<'d, T: Instance> Write for Uarte<'d, T> {
255 let s = self.inner().state(); 252 let s = self.inner().state();
256 let r = s.peri.regs(); 253 let r = s.peri.regs();
257 254
258 let did_stoptx = &s.did_stoptx;
259 let drop = OnDrop::new(move || { 255 let drop = OnDrop::new(move || {
260 info!("write drop: stopping"); 256 info!("write drop: stopping");
261 257
@@ -266,7 +262,6 @@ impl<'d, T: Instance> Write for Uarte<'d, T> {
266 // TX is stopped almost instantly, spinning is fine. 262 // TX is stopped almost instantly, spinning is fine.
267 while r.events_endtx.read().bits() == 0 {} 263 while r.events_endtx.read().bits() == 0 {}
268 info!("write drop: stopped"); 264 info!("write drop: stopped");
269 did_stoptx.store(true, Ordering::Relaxed);
270 }); 265 });
271 266
272 r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); 267 r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
@@ -290,7 +285,7 @@ impl<'d, T: Instance> Write for Uarte<'d, T> {
290 .await; 285 .await;
291 286
292 compiler_fence(Ordering::SeqCst); 287 compiler_fence(Ordering::SeqCst);
293 s.did_stoptx.store(false, Ordering::Relaxed); 288 r.events_txstarted.reset();
294 drop.defuse(); 289 drop.defuse();
295 290
296 Ok(()) 291 Ok(())