aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/uart/buffered.rs369
-rw-r--r--embassy-rp/src/uart/mod.rs2
2 files changed, 310 insertions, 61 deletions
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs
index c31af8018..3eb96e3d5 100644
--- a/embassy-rp/src/uart/buffered.rs
+++ b/embassy-rp/src/uart/buffered.rs
@@ -9,31 +9,70 @@ use futures::future::poll_fn;
9 9
10use super::*; 10use super::*;
11 11
12pub struct State<'d, T: Instance>(StateStorage<StateInner<'d, T>>); 12pub struct State<'d, T: Instance>(StateStorage<FullStateInner<'d, T>>);
13impl<'d, T: Instance> State<'d, T> { 13impl<'d, T: Instance> State<'d, T> {
14 pub fn new() -> Self { 14 pub const fn new() -> Self {
15 Self(StateStorage::new()) 15 Self(StateStorage::new())
16 } 16 }
17} 17}
18 18
19struct StateInner<'d, T: Instance> { 19pub struct RxState<'d, T: Instance>(StateStorage<RxStateInner<'d, T>>);
20impl<'d, T: Instance> RxState<'d, T> {
21 pub const fn new() -> Self {
22 Self(StateStorage::new())
23 }
24}
25
26pub struct TxState<'d, T: Instance>(StateStorage<TxStateInner<'d, T>>);
27impl<'d, T: Instance> TxState<'d, T> {
28 pub const fn new() -> Self {
29 Self(StateStorage::new())
30 }
31}
32
33struct RxStateInner<'d, T: Instance> {
34 phantom: PhantomData<&'d mut T>,
35
36 waker: WakerRegistration,
37 buf: RingBuffer<'d>,
38}
39
40struct TxStateInner<'d, T: Instance> {
20 phantom: PhantomData<&'d mut T>, 41 phantom: PhantomData<&'d mut T>,
21 42
22 rx_waker: WakerRegistration, 43 waker: WakerRegistration,
23 rx: RingBuffer<'d>, 44 buf: RingBuffer<'d>,
45}
24 46
25 tx_waker: WakerRegistration, 47struct FullStateInner<'d, T: Instance> {
26 tx: RingBuffer<'d>, 48 rx: RxStateInner<'d, T>,
49 tx: TxStateInner<'d, T>,
27} 50}
28 51
29unsafe impl<'d, T: Instance> Send for StateInner<'d, T> {} 52unsafe impl<'d, T: Instance> Send for RxStateInner<'d, T> {}
30unsafe impl<'d, T: Instance> Sync for StateInner<'d, T> {} 53unsafe impl<'d, T: Instance> Sync for RxStateInner<'d, T> {}
54
55unsafe impl<'d, T: Instance> Send for TxStateInner<'d, T> {}
56unsafe impl<'d, T: Instance> Sync for TxStateInner<'d, T> {}
57
58unsafe impl<'d, T: Instance> Send for FullStateInner<'d, T> {}
59unsafe impl<'d, T: Instance> Sync for FullStateInner<'d, T> {}
31 60
32pub struct BufferedUart<'d, T: Instance> { 61pub struct BufferedUart<'d, T: Instance> {
33 inner: PeripheralMutex<'d, StateInner<'d, T>>, 62 inner: PeripheralMutex<'d, FullStateInner<'d, T>>,
63}
64
65pub struct RxBufferedUart<'d, T: Instance> {
66 inner: PeripheralMutex<'d, RxStateInner<'d, T>>,
67}
68
69pub struct TxBufferedUart<'d, T: Instance> {
70 inner: PeripheralMutex<'d, TxStateInner<'d, T>>,
34} 71}
35 72
36impl<'d, T: Instance> Unpin for BufferedUart<'d, T> {} 73impl<'d, T: Instance> Unpin for BufferedUart<'d, T> {}
74impl<'d, T: Instance> Unpin for RxBufferedUart<'d, T> {}
75impl<'d, T: Instance> Unpin for TxBufferedUart<'d, T> {}
37 76
38impl<'d, T: Instance> BufferedUart<'d, T> { 77impl<'d, T: Instance> BufferedUart<'d, T> {
39 pub fn new<M: Mode>( 78 pub fn new<M: Mode>(
@@ -55,66 +94,158 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
55 } 94 }
56 95
57 Self { 96 Self {
58 inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner { 97 inner: PeripheralMutex::new(irq, &mut state.0, move || FullStateInner {
98 tx: TxStateInner {
99 phantom: PhantomData,
100 waker: WakerRegistration::new(),
101 buf: RingBuffer::new(tx_buffer),
102 },
103 rx: RxStateInner {
104 phantom: PhantomData,
105 waker: WakerRegistration::new(),
106 buf: RingBuffer::new(rx_buffer),
107 },
108 }),
109 }
110 }
111}
112
113impl<'d, T: Instance> RxBufferedUart<'d, T> {
114 pub fn new<M: Mode>(
115 state: &'d mut RxState<'d, T>,
116 _uart: UartRx<'d, T, M>,
117 irq: impl Peripheral<P = T::Interrupt> + 'd,
118 rx_buffer: &'d mut [u8],
119 ) -> RxBufferedUart<'d, T> {
120 into_ref!(irq);
121
122 let r = T::regs();
123 unsafe {
124 r.uartimsc().modify(|w| {
125 // TODO: Should and more or fewer interrupts be enabled?
126 w.set_rxim(true);
127 w.set_rtim(true);
128 });
129 }
130
131 Self {
132 inner: PeripheralMutex::new(irq, &mut state.0, move || RxStateInner {
133 phantom: PhantomData,
134
135 buf: RingBuffer::new(rx_buffer),
136 waker: WakerRegistration::new(),
137 }),
138 }
139 }
140}
141
142impl<'d, T: Instance> TxBufferedUart<'d, T> {
143 pub fn new<M: Mode>(
144 state: &'d mut TxState<'d, T>,
145 _uart: UartTx<'d, T, M>,
146 irq: impl Peripheral<P = T::Interrupt> + 'd,
147 tx_buffer: &'d mut [u8],
148 ) -> TxBufferedUart<'d, T> {
149 into_ref!(irq);
150
151 let r = T::regs();
152 unsafe {
153 r.uartimsc().modify(|w| {
154 // TODO: Should and more or fewer interrupts be enabled?
155 w.set_rxim(true);
156 w.set_rtim(true);
157 });
158 }
159
160 Self {
161 inner: PeripheralMutex::new(irq, &mut state.0, move || TxStateInner {
59 phantom: PhantomData, 162 phantom: PhantomData,
60 tx: RingBuffer::new(tx_buffer),
61 tx_waker: WakerRegistration::new(),
62 163
63 rx: RingBuffer::new(rx_buffer), 164 buf: RingBuffer::new(tx_buffer),
64 rx_waker: WakerRegistration::new(), 165 waker: WakerRegistration::new(),
65 }), 166 }),
66 } 167 }
67 } 168 }
68} 169}
69 170
70impl<'d, T: Instance> StateInner<'d, T> 171impl<'d, T: Instance> PeripheralState for FullStateInner<'d, T>
71where 172where
72 Self: 'd, 173 Self: 'd,
73{ 174{
74 fn on_rx(&mut self) { 175 type Interrupt = T::Interrupt;
176 fn on_interrupt(&mut self) {
177 self.rx.on_interrupt();
178 self.tx.on_interrupt();
179 }
180}
181
182impl<'d, T: Instance> PeripheralState for RxStateInner<'d, T>
183where
184 Self: 'd,
185{
186 type Interrupt = T::Interrupt;
187 fn on_interrupt(&mut self) {
75 let r = T::regs(); 188 let r = T::regs();
76 unsafe { 189 unsafe {
77 let ris = r.uartris().read(); 190 let ris = r.uartmis().read();
78 // Clear interrupt flags 191 // Clear interrupt flags
79 r.uarticr().write(|w| { 192 r.uarticr().modify(|w| {
80 w.set_rxic(true); 193 w.set_rxic(true);
81 w.set_rtic(true); 194 w.set_rtic(true);
82 }); 195 });
83 196
84 if ris.rxris() { 197 if ris.rxmis() {
85 if ris.peris() { 198 if ris.pemis() {
86 warn!("Parity error"); 199 warn!("Parity error");
200 r.uarticr().modify(|w| {
201 w.set_peic(true);
202 });
87 } 203 }
88 if ris.feris() { 204 if ris.femis() {
89 warn!("Framing error"); 205 warn!("Framing error");
206 r.uarticr().modify(|w| {
207 w.set_feic(true);
208 });
90 } 209 }
91 if ris.beris() { 210 if ris.bemis() {
92 warn!("Break error"); 211 warn!("Break error");
212 r.uarticr().modify(|w| {
213 w.set_beic(true);
214 });
93 } 215 }
94 if ris.oeris() { 216 if ris.oemis() {
95 warn!("Overrun error"); 217 warn!("Overrun error");
218 r.uarticr().modify(|w| {
219 w.set_oeic(true);
220 });
96 } 221 }
97 222
98 let buf = self.rx.push_buf(); 223 let buf = self.buf.push_buf();
99 if !buf.is_empty() { 224 if !buf.is_empty() {
100 buf[0] = r.uartdr().read().data(); 225 buf[0] = r.uartdr().read().data();
101 self.rx.push(1); 226 self.buf.push(1);
102 } else { 227 } else {
103 warn!("RX buffer full, discard received byte"); 228 warn!("RX buffer full, discard received byte");
104 } 229 }
105 230
106 if self.rx.is_full() { 231 if self.buf.is_full() {
107 self.rx_waker.wake(); 232 self.waker.wake();
108 } 233 }
109 } 234 }
110 235
111 if ris.rtris() { 236 if ris.rtmis() {
112 self.rx_waker.wake(); 237 self.waker.wake();
113 }; 238 };
114 } 239 }
115 } 240 }
241}
116 242
117 fn on_tx(&mut self) { 243impl<'d, T: Instance> PeripheralState for TxStateInner<'d, T>
244where
245 Self: 'd,
246{
247 type Interrupt = T::Interrupt;
248 fn on_interrupt(&mut self) {
118 let r = T::regs(); 249 let r = T::regs();
119 unsafe { 250 unsafe {
120 let ris = r.uartris().read(); 251 let ris = r.uartris().read();
@@ -124,14 +255,14 @@ where
124 }); 255 });
125 256
126 if ris.txris() { 257 if ris.txris() {
127 let buf = self.tx.pop_buf(); 258 let buf = self.buf.pop_buf();
128 if !buf.is_empty() { 259 if !buf.is_empty() {
129 r.uartimsc().modify(|w| { 260 r.uartimsc().modify(|w| {
130 w.set_txim(true); 261 w.set_txim(true);
131 }); 262 });
132 r.uartdr().write(|w| w.set_data(buf[0].into())); 263 r.uartdr().write(|w| w.set_data(buf[0].into()));
133 self.tx.pop(1); 264 self.buf.pop(1);
134 self.tx_waker.wake(); 265 self.waker.wake();
135 } else { 266 } else {
136 // Disable interrupt until we have something to transmit again 267 // Disable interrupt until we have something to transmit again
137 r.uartimsc().modify(|w| { 268 r.uartimsc().modify(|w| {
@@ -143,17 +274,6 @@ where
143 } 274 }
144} 275}
145 276
146impl<'d, T: Instance> PeripheralState for StateInner<'d, T>
147where
148 Self: 'd,
149{
150 type Interrupt = T::Interrupt;
151 fn on_interrupt(&mut self) {
152 self.on_rx();
153 self.on_tx();
154 }
155}
156
157impl embedded_io::Error for Error { 277impl embedded_io::Error for Error {
158 fn kind(&self) -> embedded_io::ErrorKind { 278 fn kind(&self) -> embedded_io::ErrorKind {
159 embedded_io::ErrorKind::Other 279 embedded_io::ErrorKind::Other
@@ -164,8 +284,54 @@ impl<'d, T: Instance> embedded_io::Io for BufferedUart<'d, T> {
164 type Error = Error; 284 type Error = Error;
165} 285}
166 286
287impl<'d, T: Instance> embedded_io::Io for RxBufferedUart<'d, T> {
288 type Error = Error;
289}
290
291impl<'d, T: Instance> embedded_io::Io for TxBufferedUart<'d, T> {
292 type Error = Error;
293}
294
167impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUart<'d, T> { 295impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUart<'d, T> {
168 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> 296 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
297 where
298 Self: 'a;
299
300 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
301 poll_fn(move |cx| {
302 let mut do_pend = false;
303 let res = self.inner.with(|state| {
304 compiler_fence(Ordering::SeqCst);
305
306 // We have data ready in buffer? Return it.
307 let data = state.rx.buf.pop_buf();
308 if !data.is_empty() {
309 let len = data.len().min(buf.len());
310 buf[..len].copy_from_slice(&data[..len]);
311
312 if state.rx.buf.is_full() {
313 do_pend = true;
314 }
315 state.rx.buf.pop(len);
316
317 return Poll::Ready(Ok(len));
318 }
319
320 state.rx.waker.register(cx.waker());
321 Poll::Pending
322 });
323
324 if do_pend {
325 self.inner.pend();
326 }
327
328 res
329 })
330 }
331}
332
333impl<'d, T: Instance + 'd> embedded_io::asynch::Read for RxBufferedUart<'d, T> {
334 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
169 where 335 where
170 Self: 'a; 336 Self: 'a;
171 337
@@ -176,20 +342,20 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUart<'d, T> {
176 compiler_fence(Ordering::SeqCst); 342 compiler_fence(Ordering::SeqCst);
177 343
178 // We have data ready in buffer? Return it. 344 // We have data ready in buffer? Return it.
179 let data = state.rx.pop_buf(); 345 let data = state.buf.pop_buf();
180 if !data.is_empty() { 346 if !data.is_empty() {
181 let len = data.len().min(buf.len()); 347 let len = data.len().min(buf.len());
182 buf[..len].copy_from_slice(&data[..len]); 348 buf[..len].copy_from_slice(&data[..len]);
183 349
184 if state.rx.is_full() { 350 if state.buf.is_full() {
185 do_pend = true; 351 do_pend = true;
186 } 352 }
187 state.rx.pop(len); 353 state.buf.pop(len);
188 354
189 return Poll::Ready(Ok(len)); 355 return Poll::Ready(Ok(len));
190 } 356 }
191 357
192 state.rx_waker.register(cx.waker()); 358 state.waker.register(cx.waker());
193 Poll::Pending 359 Poll::Pending
194 }); 360 });
195 361
@@ -213,7 +379,44 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUart<'d, T>
213 compiler_fence(Ordering::SeqCst); 379 compiler_fence(Ordering::SeqCst);
214 380
215 // We have data ready in buffer? Return it. 381 // We have data ready in buffer? Return it.
216 let buf = state.rx.pop_buf(); 382 let buf = state.rx.buf.pop_buf();
383 if !buf.is_empty() {
384 let buf: &[u8] = buf;
385 // Safety: buffer lives as long as uart
386 let buf: &[u8] = unsafe { core::mem::transmute(buf) };
387 return Poll::Ready(Ok(buf));
388 }
389
390 state.rx.waker.register(cx.waker());
391 Poll::<Result<&[u8], Self::Error>>::Pending
392 })
393 })
394 }
395
396 fn consume(&mut self, amt: usize) {
397 let signal = self.inner.with(|state| {
398 let full = state.rx.buf.is_full();
399 state.rx.buf.pop(amt);
400 full
401 });
402 if signal {
403 self.inner.pend();
404 }
405 }
406}
407
408impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for RxBufferedUart<'d, T> {
409 type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>>
410 where
411 Self: 'a;
412
413 fn fill_buf<'a>(&'a mut self) -> Self::FillBufFuture<'a> {
414 poll_fn(move |cx| {
415 self.inner.with(|state| {
416 compiler_fence(Ordering::SeqCst);
417
418 // We have data ready in buffer? Return it.
419 let buf = state.buf.pop_buf();
217 if !buf.is_empty() { 420 if !buf.is_empty() {
218 let buf: &[u8] = buf; 421 let buf: &[u8] = buf;
219 // Safety: buffer lives as long as uart 422 // Safety: buffer lives as long as uart
@@ -221,7 +424,7 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUart<'d, T>
221 return Poll::Ready(Ok(buf)); 424 return Poll::Ready(Ok(buf));
222 } 425 }
223 426
224 state.rx_waker.register(cx.waker()); 427 state.waker.register(cx.waker());
225 Poll::<Result<&[u8], Self::Error>>::Pending 428 Poll::<Result<&[u8], Self::Error>>::Pending
226 }) 429 })
227 }) 430 })
@@ -229,8 +432,8 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUart<'d, T>
229 432
230 fn consume(&mut self, amt: usize) { 433 fn consume(&mut self, amt: usize) {
231 let signal = self.inner.with(|state| { 434 let signal = self.inner.with(|state| {
232 let full = state.rx.is_full(); 435 let full = state.buf.is_full();
233 state.rx.pop(amt); 436 state.buf.pop(amt);
234 full 437 full
235 }); 438 });
236 if signal { 439 if signal {
@@ -247,16 +450,62 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUart<'d, T> {
247 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { 450 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
248 poll_fn(move |cx| { 451 poll_fn(move |cx| {
249 let (poll, empty) = self.inner.with(|state| { 452 let (poll, empty) = self.inner.with(|state| {
250 let empty = state.tx.is_empty(); 453 let empty = state.tx.buf.is_empty();
251 let tx_buf = state.tx.push_buf(); 454 let tx_buf = state.tx.buf.push_buf();
455 if tx_buf.is_empty() {
456 state.tx.waker.register(cx.waker());
457 return (Poll::Pending, empty);
458 }
459
460 let n = core::cmp::min(tx_buf.len(), buf.len());
461 tx_buf[..n].copy_from_slice(&buf[..n]);
462 state.tx.buf.push(n);
463
464 (Poll::Ready(Ok(n)), empty)
465 });
466 if empty {
467 self.inner.pend();
468 }
469 poll
470 })
471 }
472
473 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
474 where
475 Self: 'a;
476
477 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
478 poll_fn(move |cx| {
479 self.inner.with(|state| {
480 if !state.tx.buf.is_empty() {
481 state.tx.waker.register(cx.waker());
482 return Poll::Pending;
483 }
484
485 Poll::Ready(Ok(()))
486 })
487 })
488 }
489}
490
491impl<'d, T: Instance + 'd> embedded_io::asynch::Write for TxBufferedUart<'d, T> {
492 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
493 where
494 Self: 'a;
495
496 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
497 poll_fn(move |cx| {
498 let (poll, empty) = self.inner.with(|state| {
499 let empty = state.buf.is_empty();
500 let tx_buf = state.buf.push_buf();
252 if tx_buf.is_empty() { 501 if tx_buf.is_empty() {
253 state.tx_waker.register(cx.waker()); 502 state.waker.register(cx.waker());
254 return (Poll::Pending, empty); 503 return (Poll::Pending, empty);
255 } 504 }
256 505
257 let n = core::cmp::min(tx_buf.len(), buf.len()); 506 let n = core::cmp::min(tx_buf.len(), buf.len());
258 tx_buf[..n].copy_from_slice(&buf[..n]); 507 tx_buf[..n].copy_from_slice(&buf[..n]);
259 state.tx.push(n); 508 state.buf.push(n);
260 509
261 (Poll::Ready(Ok(n)), empty) 510 (Poll::Ready(Ok(n)), empty)
262 }); 511 });
@@ -274,8 +523,8 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUart<'d, T> {
274 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { 523 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
275 poll_fn(move |cx| { 524 poll_fn(move |cx| {
276 self.inner.with(|state| { 525 self.inner.with(|state| {
277 if !state.tx.is_empty() { 526 if !state.buf.is_empty() {
278 state.tx_waker.register(cx.waker()); 527 state.waker.register(cx.waker());
279 return Poll::Pending; 528 return Poll::Pending;
280 } 529 }
281 530
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs
index 3b71d87be..67e24b605 100644
--- a/embassy-rp/src/uart/mod.rs
+++ b/embassy-rp/src/uart/mod.rs
@@ -343,7 +343,7 @@ impl<'d, T: Instance, M: Mode> Uart<'d, T, M> {
343 w.set_stp2(config.stop_bits == StopBits::STOP2); 343 w.set_stp2(config.stop_bits == StopBits::STOP2);
344 w.set_pen(pen); 344 w.set_pen(pen);
345 w.set_eps(eps); 345 w.set_eps(eps);
346 w.set_fen(true); 346 w.set_fen(false);
347 }); 347 });
348 348
349 r.uartcr().write(|w| { 349 r.uartcr().write(|w| {