diff options
| author | Raul Alimbekov <[email protected]> | 2025-12-16 09:05:22 +0300 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-16 09:05:22 +0300 |
| commit | c9a04b4b732b7a3b696eb8223664c1a7942b1875 (patch) | |
| tree | 6dbe5c02e66eed8d8762f13f95afd24f8db2b38c /embassy-rp/src/uart/mod.rs | |
| parent | cde24a3ef1117653ba5ed4184102b33f745782fb (diff) | |
| parent | 5ae6e060ec1c90561719aabdc29d5b6e7b8b0a82 (diff) | |
Merge branch 'main' into main
Diffstat (limited to 'embassy-rp/src/uart/mod.rs')
| -rw-r--r-- | embassy-rp/src/uart/mod.rs | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index 6f4e2ee07..b7b569dd5 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | //! UART driver. | 1 | //! UART driver. |
| 2 | use core::future::poll_fn; | 2 | use core::future::poll_fn; |
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | use core::sync::atomic::{AtomicU16, Ordering}; | ||
| 4 | use core::task::Poll; | 5 | use core::task::Poll; |
| 5 | 6 | ||
| 6 | use atomic_polyfill::{AtomicU16, Ordering}; | 7 | use embassy_futures::select::{Either, select}; |
| 7 | use embassy_futures::select::{select, Either}; | ||
| 8 | use embassy_hal_internal::{Peri, PeripheralType}; | 8 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | use embassy_time::{Delay, Timer}; | 10 | use embassy_time::{Delay, Timer}; |
| @@ -16,7 +16,7 @@ use crate::gpio::{AnyPin, SealedPin}; | |||
| 16 | use crate::interrupt::typelevel::{Binding, Interrupt as _}; | 16 | use crate::interrupt::typelevel::{Binding, Interrupt as _}; |
| 17 | use crate::interrupt::{Interrupt, InterruptExt}; | 17 | use crate::interrupt::{Interrupt, InterruptExt}; |
| 18 | use crate::pac::io::vals::{Inover, Outover}; | 18 | use crate::pac::io::vals::{Inover, Outover}; |
| 19 | use crate::{interrupt, pac, peripherals, RegExt}; | 19 | use crate::{RegExt, interrupt, pac, peripherals}; |
| 20 | 20 | ||
| 21 | mod buffered; | 21 | mod buffered; |
| 22 | pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx}; | 22 | pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx}; |
| @@ -315,7 +315,7 @@ impl<'d, M: Mode> UartRx<'d, M> { | |||
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | /// Returns Ok(len) if no errors occurred. Returns Err((len, err)) if an error was | 317 | /// Returns Ok(len) if no errors occurred. Returns Err((len, err)) if an error was |
| 318 | /// encountered. in both cases, `len` is the number of *good* bytes copied into | 318 | /// encountered. In both cases, `len` is the number of *good* bytes copied into |
| 319 | /// `buffer`. | 319 | /// `buffer`. |
| 320 | fn drain_fifo(&mut self, buffer: &mut [u8]) -> Result<usize, (usize, Error)> { | 320 | fn drain_fifo(&mut self, buffer: &mut [u8]) -> Result<usize, (usize, Error)> { |
| 321 | let r = self.info.regs; | 321 | let r = self.info.regs; |
| @@ -456,7 +456,12 @@ impl<'d> UartRx<'d, Async> { | |||
| 456 | transfer, | 456 | transfer, |
| 457 | poll_fn(|cx| { | 457 | poll_fn(|cx| { |
| 458 | self.dma_state.rx_err_waker.register(cx.waker()); | 458 | self.dma_state.rx_err_waker.register(cx.waker()); |
| 459 | match self.dma_state.rx_errs.swap(0, Ordering::Relaxed) { | 459 | let rx_errs = critical_section::with(|_| { |
| 460 | let val = self.dma_state.rx_errs.load(Ordering::Relaxed); | ||
| 461 | self.dma_state.rx_errs.store(0, Ordering::Relaxed); | ||
| 462 | val | ||
| 463 | }); | ||
| 464 | match rx_errs { | ||
| 460 | 0 => Poll::Pending, | 465 | 0 => Poll::Pending, |
| 461 | e => Poll::Ready(Uartris(e as u32)), | 466 | e => Poll::Ready(Uartris(e as u32)), |
| 462 | } | 467 | } |
| @@ -468,7 +473,11 @@ impl<'d> UartRx<'d, Async> { | |||
| 468 | Either::First(()) => { | 473 | Either::First(()) => { |
| 469 | // We're here because the DMA finished, BUT if an error occurred on the LAST | 474 | // We're here because the DMA finished, BUT if an error occurred on the LAST |
| 470 | // byte, then we may still need to grab the error state! | 475 | // byte, then we may still need to grab the error state! |
| 471 | Uartris(self.dma_state.rx_errs.swap(0, Ordering::Relaxed) as u32) | 476 | Uartris(critical_section::with(|_| { |
| 477 | let val = self.dma_state.rx_errs.load(Ordering::Relaxed); | ||
| 478 | self.dma_state.rx_errs.store(0, Ordering::Relaxed); | ||
| 479 | val | ||
| 480 | }) as u32) | ||
| 472 | } | 481 | } |
| 473 | Either::Second(e) => { | 482 | Either::Second(e) => { |
| 474 | // We're here because we errored, which means this is the error that | 483 | // We're here because we errored, which means this is the error that |
| @@ -616,7 +625,12 @@ impl<'d> UartRx<'d, Async> { | |||
| 616 | transfer, | 625 | transfer, |
| 617 | poll_fn(|cx| { | 626 | poll_fn(|cx| { |
| 618 | self.dma_state.rx_err_waker.register(cx.waker()); | 627 | self.dma_state.rx_err_waker.register(cx.waker()); |
| 619 | match self.dma_state.rx_errs.swap(0, Ordering::Relaxed) { | 628 | let rx_errs = critical_section::with(|_| { |
| 629 | let val = self.dma_state.rx_errs.load(Ordering::Relaxed); | ||
| 630 | self.dma_state.rx_errs.store(0, Ordering::Relaxed); | ||
| 631 | val | ||
| 632 | }); | ||
| 633 | match rx_errs { | ||
| 620 | 0 => Poll::Pending, | 634 | 0 => Poll::Pending, |
| 621 | e => Poll::Ready(Uartris(e as u32)), | 635 | e => Poll::Ready(Uartris(e as u32)), |
| 622 | } | 636 | } |
| @@ -629,7 +643,11 @@ impl<'d> UartRx<'d, Async> { | |||
| 629 | Either::First(()) => { | 643 | Either::First(()) => { |
| 630 | // We're here because the DMA finished, BUT if an error occurred on the LAST | 644 | // We're here because the DMA finished, BUT if an error occurred on the LAST |
| 631 | // byte, then we may still need to grab the error state! | 645 | // byte, then we may still need to grab the error state! |
| 632 | Uartris(self.dma_state.rx_errs.swap(0, Ordering::Relaxed) as u32) | 646 | Uartris(critical_section::with(|_| { |
| 647 | let val = self.dma_state.rx_errs.load(Ordering::Relaxed); | ||
| 648 | self.dma_state.rx_errs.store(0, Ordering::Relaxed); | ||
| 649 | val | ||
| 650 | }) as u32) | ||
| 633 | } | 651 | } |
| 634 | Either::Second(e) => { | 652 | Either::Second(e) => { |
| 635 | // We're here because we errored, which means this is the error that | 653 | // We're here because we errored, which means this is the error that |
| @@ -863,11 +881,7 @@ impl<'d, M: Mode> Uart<'d, M> { | |||
| 863 | if let Some(pin) = &tx { | 881 | if let Some(pin) = &tx { |
| 864 | let funcsel = { | 882 | let funcsel = { |
| 865 | let pin_number = ((pin.gpio().as_ptr() as u32) & 0x1FF) / 8; | 883 | let pin_number = ((pin.gpio().as_ptr() as u32) & 0x1FF) / 8; |
| 866 | if (pin_number % 4) == 0 { | 884 | if (pin_number % 4) == 0 { 2 } else { 11 } |
| 867 | 2 | ||
| 868 | } else { | ||
| 869 | 11 | ||
| 870 | } | ||
| 871 | }; | 885 | }; |
| 872 | pin.gpio().ctrl().write(|w| { | 886 | pin.gpio().ctrl().write(|w| { |
| 873 | w.set_funcsel(funcsel); | 887 | w.set_funcsel(funcsel); |
| @@ -886,11 +900,7 @@ impl<'d, M: Mode> Uart<'d, M> { | |||
| 886 | if let Some(pin) = &rx { | 900 | if let Some(pin) = &rx { |
| 887 | let funcsel = { | 901 | let funcsel = { |
| 888 | let pin_number = ((pin.gpio().as_ptr() as u32) & 0x1FF) / 8; | 902 | let pin_number = ((pin.gpio().as_ptr() as u32) & 0x1FF) / 8; |
| 889 | if ((pin_number - 1) % 4) == 0 { | 903 | if ((pin_number - 1) % 4) == 0 { 2 } else { 11 } |
| 890 | 2 | ||
| 891 | } else { | ||
| 892 | 11 | ||
| 893 | } | ||
| 894 | }; | 904 | }; |
| 895 | pin.gpio().ctrl().write(|w| { | 905 | pin.gpio().ctrl().write(|w| { |
| 896 | w.set_funcsel(funcsel); | 906 | w.set_funcsel(funcsel); |
