aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/uart/buffered.rs215
1 files changed, 89 insertions, 126 deletions
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs
index 3eb96e3d5..6d395b6f4 100644
--- a/embassy-rp/src/uart/buffered.rs
+++ b/embassy-rp/src/uart/buffered.rs
@@ -1,5 +1,5 @@
1use core::future::Future; 1use core::future::Future;
2use core::task::Poll; 2use core::task::{Poll, Waker};
3 3
4use atomic_polyfill::{compiler_fence, Ordering}; 4use atomic_polyfill::{compiler_fence, Ordering};
5use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 5use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
@@ -87,9 +87,9 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
87 let r = T::regs(); 87 let r = T::regs();
88 unsafe { 88 unsafe {
89 r.uartimsc().modify(|w| { 89 r.uartimsc().modify(|w| {
90 // TODO: Should and more or fewer interrupts be enabled?
91 w.set_rxim(true); 90 w.set_rxim(true);
92 w.set_rtim(true); 91 w.set_rtim(true);
92 w.set_txim(true);
93 }); 93 });
94 } 94 }
95 95
@@ -122,7 +122,6 @@ impl<'d, T: Instance> RxBufferedUart<'d, T> {
122 let r = T::regs(); 122 let r = T::regs();
123 unsafe { 123 unsafe {
124 r.uartimsc().modify(|w| { 124 r.uartimsc().modify(|w| {
125 // TODO: Should and more or fewer interrupts be enabled?
126 w.set_rxim(true); 125 w.set_rxim(true);
127 w.set_rtim(true); 126 w.set_rtim(true);
128 }); 127 });
@@ -151,9 +150,7 @@ impl<'d, T: Instance> TxBufferedUart<'d, T> {
151 let r = T::regs(); 150 let r = T::regs();
152 unsafe { 151 unsafe {
153 r.uartimsc().modify(|w| { 152 r.uartimsc().modify(|w| {
154 // TODO: Should and more or fewer interrupts be enabled? 153 w.set_txim(true);
155 w.set_rxim(true);
156 w.set_rtim(true);
157 }); 154 });
158 } 155 }
159 156
@@ -179,6 +176,51 @@ where
179 } 176 }
180} 177}
181 178
179impl<'d, T: Instance> RxStateInner<'d, T>
180where
181 Self: 'd,
182{
183 fn read(&mut self, buf: &mut [u8], waker: &Waker) -> (Poll<Result<usize, Error>>, bool) {
184 // We have data ready in buffer? Return it.
185 let mut do_pend = false;
186 let data = self.buf.pop_buf();
187 if !data.is_empty() {
188 let len = data.len().min(buf.len());
189 buf[..len].copy_from_slice(&data[..len]);
190
191 if self.buf.is_full() {
192 do_pend = true;
193 }
194 self.buf.pop(len);
195
196 return (Poll::Ready(Ok(len)), do_pend);
197 }
198
199 self.waker.register(waker);
200 (Poll::Pending, do_pend)
201 }
202
203 fn fill_buf<'a>(&mut self, waker: &Waker) -> Poll<Result<&'a [u8], Error>> {
204 // We have data ready in buffer? Return it.
205 let buf = self.buf.pop_buf();
206 if !buf.is_empty() {
207 let buf: &[u8] = buf;
208 // Safety: buffer lives as long as uart
209 let buf: &[u8] = unsafe { core::mem::transmute(buf) };
210 return Poll::Ready(Ok(buf));
211 }
212
213 self.waker.register(waker);
214 Poll::Pending
215 }
216
217 fn consume(&mut self, amt: usize) -> bool {
218 let full = self.buf.is_full();
219 self.buf.pop(amt);
220 full
221 }
222}
223
182impl<'d, T: Instance> PeripheralState for RxStateInner<'d, T> 224impl<'d, T: Instance> PeripheralState for RxStateInner<'d, T>
183where 225where
184 Self: 'd, 226 Self: 'd,
@@ -240,6 +282,35 @@ where
240 } 282 }
241} 283}
242 284
285impl<'d, T: Instance> TxStateInner<'d, T>
286where
287 Self: 'd,
288{
289 fn write(&mut self, buf: &[u8], waker: &Waker) -> (Poll<Result<usize, Error>>, bool) {
290 let empty = self.buf.is_empty();
291 let tx_buf = self.buf.push_buf();
292 if tx_buf.is_empty() {
293 self.waker.register(waker);
294 return (Poll::Pending, empty);
295 }
296
297 let n = core::cmp::min(tx_buf.len(), buf.len());
298 tx_buf[..n].copy_from_slice(&buf[..n]);
299 self.buf.push(n);
300
301 (Poll::Ready(Ok(n)), empty)
302 }
303
304 fn flush(&mut self, waker: &Waker) -> Poll<Result<(), Error>> {
305 if !self.buf.is_empty() {
306 self.waker.register(waker);
307 return Poll::Pending;
308 }
309
310 Poll::Ready(Ok(()))
311 }
312}
313
243impl<'d, T: Instance> PeripheralState for TxStateInner<'d, T> 314impl<'d, T: Instance> PeripheralState for TxStateInner<'d, T>
244where 315where
245 Self: 'd, 316 Self: 'd,
@@ -299,26 +370,9 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUart<'d, T> {
299 370
300 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { 371 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
301 poll_fn(move |cx| { 372 poll_fn(move |cx| {
302 let mut do_pend = false; 373 let (res, do_pend) = self.inner.with(|state| {
303 let res = self.inner.with(|state| {
304 compiler_fence(Ordering::SeqCst); 374 compiler_fence(Ordering::SeqCst);
305 375 state.rx.read(buf, cx.waker())
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 }); 376 });
323 377
324 if do_pend { 378 if do_pend {
@@ -337,26 +391,9 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Read for RxBufferedUart<'d, T> {
337 391
338 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { 392 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
339 poll_fn(move |cx| { 393 poll_fn(move |cx| {
340 let mut do_pend = false; 394 let (res, do_pend) = self.inner.with(|state| {
341 let res = self.inner.with(|state| {
342 compiler_fence(Ordering::SeqCst); 395 compiler_fence(Ordering::SeqCst);
343 396 state.read(buf, cx.waker())
344 // We have data ready in buffer? Return it.
345 let data = state.buf.pop_buf();
346 if !data.is_empty() {
347 let len = data.len().min(buf.len());
348 buf[..len].copy_from_slice(&data[..len]);
349
350 if state.buf.is_full() {
351 do_pend = true;
352 }
353 state.buf.pop(len);
354
355 return Poll::Ready(Ok(len));
356 }
357
358 state.waker.register(cx.waker());
359 Poll::Pending
360 }); 397 });
361 398
362 if do_pend { 399 if do_pend {
@@ -377,28 +414,13 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUart<'d, T>
377 poll_fn(move |cx| { 414 poll_fn(move |cx| {
378 self.inner.with(|state| { 415 self.inner.with(|state| {
379 compiler_fence(Ordering::SeqCst); 416 compiler_fence(Ordering::SeqCst);
380 417 state.rx.fill_buf(cx.waker())
381 // We have data ready in buffer? Return it.
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 }) 418 })
393 }) 419 })
394 } 420 }
395 421
396 fn consume(&mut self, amt: usize) { 422 fn consume(&mut self, amt: usize) {
397 let signal = self.inner.with(|state| { 423 let signal = self.inner.with(|state| state.rx.consume(amt));
398 let full = state.rx.buf.is_full();
399 state.rx.buf.pop(amt);
400 full
401 });
402 if signal { 424 if signal {
403 self.inner.pend(); 425 self.inner.pend();
404 } 426 }
@@ -414,28 +436,13 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for RxBufferedUart<'d, T
414 poll_fn(move |cx| { 436 poll_fn(move |cx| {
415 self.inner.with(|state| { 437 self.inner.with(|state| {
416 compiler_fence(Ordering::SeqCst); 438 compiler_fence(Ordering::SeqCst);
417 439 state.fill_buf(cx.waker())
418 // We have data ready in buffer? Return it.
419 let buf = state.buf.pop_buf();
420 if !buf.is_empty() {
421 let buf: &[u8] = buf;
422 // Safety: buffer lives as long as uart
423 let buf: &[u8] = unsafe { core::mem::transmute(buf) };
424 return Poll::Ready(Ok(buf));
425 }
426
427 state.waker.register(cx.waker());
428 Poll::<Result<&[u8], Self::Error>>::Pending
429 }) 440 })
430 }) 441 })
431 } 442 }
432 443
433 fn consume(&mut self, amt: usize) { 444 fn consume(&mut self, amt: usize) {
434 let signal = self.inner.with(|state| { 445 let signal = self.inner.with(|state| state.consume(amt));
435 let full = state.buf.is_full();
436 state.buf.pop(amt);
437 full
438 });
439 if signal { 446 if signal {
440 self.inner.pend(); 447 self.inner.pend();
441 } 448 }
@@ -449,20 +456,7 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUart<'d, T> {
449 456
450 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { 457 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
451 poll_fn(move |cx| { 458 poll_fn(move |cx| {
452 let (poll, empty) = self.inner.with(|state| { 459 let (poll, empty) = self.inner.with(|state| state.tx.write(buf, cx.waker()));
453 let empty = state.tx.buf.is_empty();
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 { 460 if empty {
467 self.inner.pend(); 461 self.inner.pend();
468 } 462 }
@@ -475,16 +469,7 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUart<'d, T> {
475 Self: 'a; 469 Self: 'a;
476 470
477 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { 471 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
478 poll_fn(move |cx| { 472 poll_fn(move |cx| self.inner.with(|state| state.tx.flush(cx.waker())))
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 } 473 }
489} 474}
490 475
@@ -495,20 +480,7 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for TxBufferedUart<'d, T>
495 480
496 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { 481 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
497 poll_fn(move |cx| { 482 poll_fn(move |cx| {
498 let (poll, empty) = self.inner.with(|state| { 483 let (poll, empty) = self.inner.with(|state| state.write(buf, cx.waker()));
499 let empty = state.buf.is_empty();
500 let tx_buf = state.buf.push_buf();
501 if tx_buf.is_empty() {
502 state.waker.register(cx.waker());
503 return (Poll::Pending, empty);
504 }
505
506 let n = core::cmp::min(tx_buf.len(), buf.len());
507 tx_buf[..n].copy_from_slice(&buf[..n]);
508 state.buf.push(n);
509
510 (Poll::Ready(Ok(n)), empty)
511 });
512 if empty { 484 if empty {
513 self.inner.pend(); 485 self.inner.pend();
514 } 486 }
@@ -521,15 +493,6 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for TxBufferedUart<'d, T>
521 Self: 'a; 493 Self: 'a;
522 494
523 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { 495 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
524 poll_fn(move |cx| { 496 poll_fn(move |cx| self.inner.with(|state| state.flush(cx.waker())))
525 self.inner.with(|state| {
526 if !state.buf.is_empty() {
527 state.waker.register(cx.waker());
528 return Poll::Pending;
529 }
530
531 Poll::Ready(Ok(()))
532 })
533 })
534 } 497 }
535} 498}