1crate::unstable_driver! {
45 #[cfg(uhci_driver_supported)]
47 pub mod uhci;
48}
49
50use core::{marker::PhantomData, sync::atomic::Ordering, task::Poll};
51
52use enumset::{EnumSet, EnumSetType};
53use portable_atomic::AtomicBool;
54
55use crate::{
56 Async,
57 Blocking,
58 DriverMode,
59 asynch::AtomicWaker,
60 gpio::{
61 InputConfig,
62 InputSignal,
63 OutputConfig,
64 OutputSignal,
65 PinGuard,
66 Pull,
67 interconnect::{PeripheralInput, PeripheralOutput},
68 },
69 handler,
70 interrupt::InterruptHandler,
71 pac::uart0::RegisterBlock,
72 private::DropGuard,
73 ram,
74 soc::clocks::{self, ClockTree},
75 system::PeripheralGuard,
76};
77
78#[derive(Debug, Clone, Copy, PartialEq)]
80#[cfg_attr(feature = "defmt", derive(defmt::Format))]
81#[non_exhaustive]
82pub enum RxError {
83 FifoOverflowed,
88
89 GlitchOccurred,
95
96 FrameFormatViolated,
101
102 ParityMismatch,
107}
108
109impl core::error::Error for RxError {}
110
111impl core::fmt::Display for RxError {
112 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
113 match self {
114 RxError::FifoOverflowed => write!(f, "The RX FIFO overflowed"),
115 RxError::GlitchOccurred => write!(f, "A glitch was detected on the RX line"),
116 RxError::FrameFormatViolated => {
117 write!(f, "A framing error was detected on the RX line")
118 }
119 RxError::ParityMismatch => write!(f, "A parity error was detected on the RX line"),
120 }
121 }
122}
123
124#[instability::unstable]
125impl embedded_io_06::Error for RxError {
126 fn kind(&self) -> embedded_io_06::ErrorKind {
127 embedded_io_06::ErrorKind::Other
128 }
129}
130
131#[instability::unstable]
132impl embedded_io_07::Error for RxError {
133 fn kind(&self) -> embedded_io_07::ErrorKind {
134 embedded_io_07::ErrorKind::Other
135 }
136}
137
138#[derive(Debug, Clone, Copy, PartialEq)]
140#[cfg_attr(feature = "defmt", derive(defmt::Format))]
141#[non_exhaustive]
142pub enum TxError {}
143
144impl core::fmt::Display for TxError {
145 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
146 write!(f, "Tx error")
147 }
148}
149
150impl core::error::Error for TxError {}
151
152#[instability::unstable]
153impl embedded_io_06::Error for TxError {
154 fn kind(&self) -> embedded_io_06::ErrorKind {
155 embedded_io_06::ErrorKind::Other
156 }
157}
158#[instability::unstable]
159impl embedded_io_07::Error for TxError {
160 fn kind(&self) -> embedded_io_07::ErrorKind {
161 embedded_io_07::ErrorKind::Other
162 }
163}
164
165#[instability::unstable]
166pub use crate::soc::clocks::UartFunctionClockSclk as ClockSource;
167use crate::soc::clocks::{
168 UartBaudRateGeneratorConfig as BaudRateConfig,
169 UartFunctionClockConfig as ClockConfig,
170};
171
172#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
178#[cfg_attr(feature = "defmt", derive(defmt::Format))]
179pub enum DataBits {
180 _5,
182 _6,
184 _7,
186 #[default]
188 _8,
189}
190
191#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
198#[cfg_attr(feature = "defmt", derive(defmt::Format))]
199pub enum Parity {
200 #[default]
202 None,
203 Even,
206 Odd,
209}
210
211#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
217#[cfg_attr(feature = "defmt", derive(defmt::Format))]
218pub enum StopBits {
219 #[default]
221 _1,
222 _1p5,
224 _2,
226}
227
228#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
230#[cfg_attr(feature = "defmt", derive(defmt::Format))]
231#[instability::unstable]
232pub enum SwFlowControl {
233 #[default]
234 Disabled,
236 Enabled {
238 xon_char: u8,
240 xoff_char: u8,
242 xon_threshold: u8,
245 xoff_threshold: u8,
248 },
249}
250
251#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
253#[cfg_attr(feature = "defmt", derive(defmt::Format))]
254#[instability::unstable]
255pub enum CtsConfig {
256 Enabled,
258 #[default]
259 Disabled,
261}
262
263#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
265#[cfg_attr(feature = "defmt", derive(defmt::Format))]
266#[instability::unstable]
267pub enum RtsConfig {
268 Enabled(u8),
270 #[default]
271 Disabled,
273}
274
275#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
277#[cfg_attr(feature = "defmt", derive(defmt::Format))]
278#[instability::unstable]
279pub struct HwFlowControl {
280 pub cts: CtsConfig,
282 pub rts: RtsConfig,
284}
285
286#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
288#[cfg_attr(feature = "defmt", derive(defmt::Format))]
289#[instability::unstable]
290pub enum BaudrateTolerance {
291 #[default]
293 Closest,
294 Exact,
297 ErrorPercent(u8),
299}
300
301#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
303#[cfg_attr(feature = "defmt", derive(defmt::Format))]
304#[non_exhaustive]
305pub struct Config {
306 baudrate: u32,
309 #[builder_lite(unstable)]
312 baudrate_tolerance: BaudrateTolerance,
313 data_bits: DataBits,
315 parity: Parity,
317 stop_bits: StopBits,
319 #[builder_lite(unstable)]
321 sw_flow_ctrl: SwFlowControl,
322 #[builder_lite(unstable)]
324 hw_flow_ctrl: HwFlowControl,
325 #[builder_lite(unstable)]
327 clock_source: ClockSource,
328 rx: RxConfig,
330 tx: TxConfig,
332}
333
334impl Default for Config {
335 fn default() -> Config {
336 Config {
337 rx: RxConfig::default(),
338 tx: TxConfig::default(),
339 baudrate: 115_200,
340 baudrate_tolerance: BaudrateTolerance::default(),
341 data_bits: Default::default(),
342 parity: Default::default(),
343 stop_bits: Default::default(),
344 sw_flow_ctrl: Default::default(),
345 hw_flow_ctrl: Default::default(),
346 clock_source: Default::default(),
347 }
348 }
349}
350
351impl Config {
352 fn validate(&self) -> Result<(), ConfigError> {
353 if let BaudrateTolerance::ErrorPercent(percentage) = self.baudrate_tolerance {
354 assert!(percentage > 0 && percentage <= 100);
355 }
356
357 if self.baudrate == 0 || self.baudrate > 5_000_000 {
359 return Err(ConfigError::BaudrateNotSupported);
360 }
361 Ok(())
362 }
363}
364
365#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
367#[cfg_attr(feature = "defmt", derive(defmt::Format))]
368#[non_exhaustive]
369pub struct RxConfig {
370 fifo_full_threshold: u16,
372 timeout: Option<u8>,
374}
375
376impl Default for RxConfig {
377 fn default() -> RxConfig {
378 RxConfig {
379 fifo_full_threshold: 120,
381 timeout: Some(10),
383 }
384 }
385}
386
387#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
389#[cfg_attr(feature = "defmt", derive(defmt::Format))]
390#[non_exhaustive]
391pub struct TxConfig {
392 fifo_empty_threshold: u16,
394}
395
396impl Default for TxConfig {
397 fn default() -> TxConfig {
398 TxConfig {
399 fifo_empty_threshold: 10,
401 }
402 }
403}
404
405#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
407#[cfg_attr(feature = "defmt", derive(defmt::Format))]
408#[instability::unstable]
409#[non_exhaustive]
410pub struct AtCmdConfig {
411 pre_idle_count: Option<u16>,
414 post_idle_count: Option<u16>,
417 gap_timeout: Option<u16>,
420 cmd_char: u8,
422 char_num: u8,
424}
425
426impl Default for AtCmdConfig {
427 fn default() -> Self {
428 Self {
429 pre_idle_count: None,
430 post_idle_count: None,
431 gap_timeout: None,
432 cmd_char: b'+',
433 char_num: 1,
434 }
435 }
436}
437
438struct UartBuilder<'d, Dm: DriverMode> {
439 uart: AnyUart<'d>,
440 phantom: PhantomData<Dm>,
441}
442
443impl<'d, Dm> UartBuilder<'d, Dm>
444where
445 Dm: DriverMode,
446{
447 fn new(uart: impl Instance + 'd) -> Self {
448 let uart = uart.degrade();
449
450 uart.info().rx_signal.connect_to(&crate::gpio::Level::High);
453 uart.info().cts_signal.connect_to(&crate::gpio::Level::Low);
454
455 Self {
456 uart,
457 phantom: PhantomData,
458 }
459 }
460
461 fn init(self, config: Config) -> Result<Uart<'d, Dm>, ConfigError> {
462 let rx_guard = PeripheralGuard::new(self.uart.info().peripheral);
463 let tx_guard = PeripheralGuard::new(self.uart.info().peripheral);
464
465 let peri_clock_guard = UartClockGuard::new(unsafe { self.uart.clone_unchecked() });
466
467 let rts_pin = PinGuard::new_unconnected();
468 let tx_pin = PinGuard::new_unconnected();
469
470 let mut serial = Uart {
471 rx: UartRx {
472 uart: unsafe { self.uart.clone_unchecked() },
473 phantom: PhantomData,
474 guard: rx_guard,
475 peri_clock_guard: peri_clock_guard.clone(),
476 },
477 tx: UartTx {
478 uart: self.uart,
479 phantom: PhantomData,
480 guard: tx_guard,
481 peri_clock_guard,
482 rts_pin,
483 tx_pin,
484 baudrate: config.baudrate,
485 },
486 };
487 serial.init(config)?;
488
489 Ok(serial)
490 }
491}
492
493#[procmacros::doc_replace]
494pub struct Uart<'d, Dm: DriverMode> {
509 rx: UartRx<'d, Dm>,
510 tx: UartTx<'d, Dm>,
511}
512
513#[instability::unstable]
515pub struct UartTx<'d, Dm: DriverMode> {
516 uart: AnyUart<'d>,
517 phantom: PhantomData<Dm>,
518 guard: PeripheralGuard,
519 peri_clock_guard: UartClockGuard<'d>,
520 rts_pin: PinGuard,
521 tx_pin: PinGuard,
522 baudrate: u32,
523}
524
525#[instability::unstable]
527pub struct UartRx<'d, Dm: DriverMode> {
528 uart: AnyUart<'d>,
529 phantom: PhantomData<Dm>,
530 guard: PeripheralGuard,
531 peri_clock_guard: UartClockGuard<'d>,
532}
533
534#[derive(Debug, Clone, Copy, PartialEq, Eq)]
536#[cfg_attr(feature = "defmt", derive(defmt::Format))]
537#[non_exhaustive]
538pub enum ConfigError {
539 #[cfg(feature = "unstable")]
541 #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
542 BaudrateNotAchievable,
543
544 BaudrateNotSupported,
551
552 #[cfg_attr(esp32, doc = "127")]
554 #[cfg_attr(not(esp32), doc = "1023")]
555 TimeoutTooLong,
557
558 RxFifoThresholdNotSupported,
560
561 TxFifoThresholdNotSupported,
563}
564
565impl core::error::Error for ConfigError {}
566
567impl core::fmt::Display for ConfigError {
568 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
569 match self {
570 #[cfg(feature = "unstable")]
571 ConfigError::BaudrateNotAchievable => {
572 write!(f, "The requested baud rate is not achievable")
573 }
574 ConfigError::BaudrateNotSupported => {
575 write!(f, "The requested baud rate is not supported")
576 }
577 ConfigError::TimeoutTooLong => write!(f, "The requested timeout is not supported"),
578 ConfigError::RxFifoThresholdNotSupported => {
579 write!(f, "The requested RX FIFO threshold is not supported")
580 }
581 ConfigError::TxFifoThresholdNotSupported => {
582 write!(f, "The requested TX FIFO threshold is not supported")
583 }
584 }
585 }
586}
587
588#[instability::unstable]
589impl<Dm> embassy_embedded_hal::SetConfig for Uart<'_, Dm>
590where
591 Dm: DriverMode,
592{
593 type Config = Config;
594 type ConfigError = ConfigError;
595
596 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
597 self.apply_config(config)
598 }
599}
600
601#[instability::unstable]
602impl<Dm> embassy_embedded_hal::SetConfig for UartRx<'_, Dm>
603where
604 Dm: DriverMode,
605{
606 type Config = Config;
607 type ConfigError = ConfigError;
608
609 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
610 self.apply_config(config)
611 }
612}
613
614#[instability::unstable]
615impl<Dm> embassy_embedded_hal::SetConfig for UartTx<'_, Dm>
616where
617 Dm: DriverMode,
618{
619 type Config = Config;
620 type ConfigError = ConfigError;
621
622 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
623 self.baudrate = config.baudrate;
624 self.apply_config(config)
625 }
626}
627
628impl<'d> UartTx<'d, Blocking> {
629 #[procmacros::doc_replace]
630 #[instability::unstable]
646 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
647 let (_, uart_tx) = UartBuilder::new(uart).init(config)?.split();
648
649 Ok(uart_tx)
650 }
651
652 #[instability::unstable]
654 pub fn into_async(self) -> UartTx<'d, Async> {
655 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
656 self.uart
657 .set_interrupt_handler(self.uart.info().async_handler);
658 }
659 self.uart.state().is_tx_async.store(true, Ordering::Release);
660
661 UartTx {
662 uart: self.uart,
663 phantom: PhantomData,
664 guard: self.guard,
665 peri_clock_guard: self.peri_clock_guard,
666 rts_pin: self.rts_pin,
667 tx_pin: self.tx_pin,
668 baudrate: self.baudrate,
669 }
670 }
671}
672
673impl<'d> UartTx<'d, Async> {
674 #[instability::unstable]
676 pub fn into_blocking(self) -> UartTx<'d, Blocking> {
677 self.uart
678 .state()
679 .is_tx_async
680 .store(false, Ordering::Release);
681 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
682 self.uart.disable_peri_interrupt_on_all_cores();
683 }
684
685 UartTx {
686 uart: self.uart,
687 phantom: PhantomData,
688 guard: self.guard,
689 peri_clock_guard: self.peri_clock_guard,
690 rts_pin: self.rts_pin,
691 tx_pin: self.tx_pin,
692 baudrate: self.baudrate,
693 }
694 }
695
696 pub async fn write_async(&mut self, bytes: &[u8]) -> Result<usize, TxError> {
712 let space = loop {
715 let tx_fifo_count = self.uart.info().tx_fifo_count();
716 let space = Info::UART_FIFO_SIZE - tx_fifo_count;
717 if space != 0 {
718 break space;
719 }
720 UartTxFuture::new(self.uart.reborrow(), TxEvent::FiFoEmpty).await;
721 };
722
723 let free = (space as usize).min(bytes.len());
724
725 for &byte in &bytes[..free] {
726 self.uart
727 .info()
728 .regs()
729 .fifo()
730 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
731 }
732
733 Ok(free)
734 }
735
736 pub async fn flush_async(&mut self) -> Result<(), TxError> {
746 while self.uart.info().tx_fifo_count() > 0 {
750 UartTxFuture::new(self.uart.reborrow(), TxEvent::Done).await;
751 }
752
753 self.flush_last_byte();
754
755 Ok(())
756 }
757}
758
759impl<'d, Dm> UartTx<'d, Dm>
760where
761 Dm: DriverMode,
762{
763 #[instability::unstable]
765 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
766 let rts = rts.into();
767
768 rts.apply_output_config(&OutputConfig::default());
769 rts.set_output_enable(true);
770
771 self.rts_pin = rts.connect_with_guard(self.uart.info().rts_signal);
772
773 self
774 }
775
776 #[instability::unstable]
783 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
784 let tx = tx.into();
785
786 tx.set_output_high(true);
788 tx.apply_output_config(&OutputConfig::default());
789 tx.set_output_enable(true);
790
791 self.tx_pin = tx.connect_with_guard(self.uart.info().tx_signal);
792
793 self
794 }
795
796 #[instability::unstable]
803 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
804 self.uart
805 .info()
806 .set_tx_fifo_empty_threshold(config.tx.fifo_empty_threshold)?;
807 self.uart.info().txfifo_reset();
808 Ok(())
809 }
810
811 #[instability::unstable]
815 pub fn write_ready(&self) -> bool {
816 self.uart.info().tx_fifo_count() < Info::UART_FIFO_SIZE
817 }
818
819 #[instability::unstable]
833 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
834 self.uart.info().write(data)
835 }
836
837 fn write_all(&mut self, mut data: &[u8]) -> Result<(), TxError> {
838 while !data.is_empty() {
839 let bytes_written = self.write(data)?;
840 data = &data[bytes_written..];
841 }
842 Ok(())
843 }
844
845 #[instability::unstable]
850 pub fn flush(&mut self) -> Result<(), TxError> {
851 while self.uart.info().tx_fifo_count() > 0 {}
852 self.flush_last_byte();
853 Ok(())
854 }
855
856 fn flush_last_byte(&mut self) {
857 crate::rom::ets_delay_us(10);
863 while !self.is_tx_idle() {}
864 }
865
866 #[instability::unstable]
871 pub fn send_break(&mut self, bits: u32) {
872 let original_conf0 = self.uart.info().regs().conf0().read();
874 let original_txd_inv = original_conf0.txd_inv().bit();
875
876 self.uart
878 .info()
879 .regs()
880 .conf0()
881 .modify(|_, w| w.txd_inv().bit(!original_txd_inv));
882
883 sync_regs(self.uart.info().regs());
884
885 let total_delay_us = (bits as u64 * 1_000_000) / self.baudrate as u64;
888 let delay_us = (total_delay_us as u32).max(1);
889
890 crate::rom::ets_delay_us(delay_us);
891
892 self.uart
894 .info()
895 .regs()
896 .conf0()
897 .write(|w| unsafe { w.bits(original_conf0.bits()) });
898
899 sync_regs(self.uart.info().regs());
900 }
901
902 fn is_tx_idle(&self) -> bool {
907 #[cfg(esp32)]
908 let status = self.regs().status();
909 #[cfg(not(esp32))]
910 let status = self.regs().fsm_status();
911
912 status.read().st_utx_out().bits() == 0x0
913 }
914
915 fn disable_tx_interrupts(&self) {
921 self.regs().int_clr().write(|w| {
922 w.txfifo_empty().clear_bit_by_one();
923 w.tx_brk_done().clear_bit_by_one();
924 w.tx_brk_idle_done().clear_bit_by_one();
925 w.tx_done().clear_bit_by_one()
926 });
927
928 self.regs().int_ena().write(|w| {
929 w.txfifo_empty().clear_bit();
930 w.tx_brk_done().clear_bit();
931 w.tx_brk_idle_done().clear_bit();
932 w.tx_done().clear_bit()
933 });
934 }
935
936 fn regs(&self) -> &RegisterBlock {
937 self.uart.info().regs()
938 }
939}
940
941#[inline(always)]
942fn sync_regs(_register_block: &RegisterBlock) {
943 #[cfg(not(any(esp32, esp32s2)))]
944 {
945 cfg_if::cfg_if! {
946 if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
947 let update_reg = _register_block.id();
948 } else {
949 let update_reg = _register_block.reg_update();
950 }
951 }
952
953 update_reg.modify(|_, w| w.reg_update().set_bit());
954
955 while update_reg.read().reg_update().bit_is_set() {
956 core::hint::spin_loop();
957 }
958 }
959}
960
961impl<'d> UartRx<'d, Blocking> {
962 #[procmacros::doc_replace]
963 #[instability::unstable]
977 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
978 let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();
979
980 Ok(uart_rx)
981 }
982
983 #[instability::unstable]
988 pub fn wait_for_break(&mut self) {
989 self.enable_break_detection();
990
991 while !self.regs().int_raw().read().brk_det().bit_is_set() {
992 }
994
995 self.regs()
996 .int_clr()
997 .write(|w| w.brk_det().clear_bit_by_one());
998 }
999
1000 #[instability::unstable]
1010 pub fn wait_for_break_with_timeout(&mut self, timeout: crate::time::Duration) -> bool {
1011 self.enable_break_detection();
1012
1013 let start = crate::time::Instant::now();
1014
1015 while !self.regs().int_raw().read().brk_det().bit_is_set() {
1016 if crate::time::Instant::now() - start >= timeout {
1017 return false;
1018 }
1019 }
1020
1021 self.regs()
1022 .int_clr()
1023 .write(|w| w.brk_det().clear_bit_by_one());
1024 true
1025 }
1026
1027 #[instability::unstable]
1029 pub fn into_async(self) -> UartRx<'d, Async> {
1030 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
1031 self.uart
1032 .set_interrupt_handler(self.uart.info().async_handler);
1033 }
1034 self.uart.state().is_rx_async.store(true, Ordering::Release);
1035
1036 UartRx {
1037 uart: self.uart,
1038 phantom: PhantomData,
1039 guard: self.guard,
1040 peri_clock_guard: self.peri_clock_guard,
1041 }
1042 }
1043}
1044
1045impl<'d> UartRx<'d, Async> {
1046 #[instability::unstable]
1048 pub fn into_blocking(self) -> UartRx<'d, Blocking> {
1049 self.uart
1050 .state()
1051 .is_rx_async
1052 .store(false, Ordering::Release);
1053 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
1054 self.uart.disable_peri_interrupt_on_all_cores();
1055 }
1056
1057 UartRx {
1058 uart: self.uart,
1059 phantom: PhantomData,
1060 guard: self.guard,
1061 peri_clock_guard: self.peri_clock_guard,
1062 }
1063 }
1064
1065 async fn wait_for_buffered_data(
1066 &mut self,
1067 minimum: usize,
1068 max_threshold: usize,
1069 listen_for_timeout: bool,
1070 ) -> Result<(), RxError> {
1071 let current_threshold = self.uart.info().rx_fifo_full_threshold();
1072
1073 let max_threshold = max_threshold.min(current_threshold as usize) as u16;
1075 let minimum = minimum.min(Info::RX_FIFO_MAX_THRHD as usize) as u16;
1076
1077 let minimum = minimum.min(max_threshold);
1080
1081 if self.uart.info().rx_fifo_count() < minimum {
1082 let info = self.uart.info();
1086 unwrap!(info.set_rx_fifo_full_threshold(max_threshold));
1087 let _guard = DropGuard::new((), |_| {
1088 unwrap!(info.set_rx_fifo_full_threshold(current_threshold));
1089 });
1090
1091 let mut events = RxEvent::FifoFull
1093 | RxEvent::FifoOvf
1094 | RxEvent::FrameError
1095 | RxEvent::GlitchDetected
1096 | RxEvent::ParityError;
1097
1098 if self.regs().at_cmd_char().read().char_num().bits() > 0 {
1099 events |= RxEvent::CmdCharDetected;
1100 }
1101
1102 cfg_if::cfg_if! {
1103 if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
1104 let reg_en = self.regs().tout_conf();
1105 } else {
1106 let reg_en = self.regs().conf1();
1107 }
1108 };
1109 if listen_for_timeout && reg_en.read().rx_tout_en().bit_is_set() {
1110 events |= RxEvent::FifoTout;
1111 }
1112
1113 let events = UartRxFuture::new(self.uart.reborrow(), events).await;
1114
1115 let result = rx_event_check_for_error(events);
1116 if let Err(error) = result {
1117 if error == RxError::FifoOverflowed {
1118 self.uart.info().rxfifo_reset();
1119 }
1120 return Err(error);
1121 }
1122 }
1123
1124 Ok(())
1125 }
1126
1127 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1146 if buf.is_empty() {
1147 return Ok(0);
1148 }
1149
1150 self.wait_for_buffered_data(1, buf.len(), true).await?;
1151
1152 self.read_buffered(buf)
1153 }
1154
1155 pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
1170 if buf.is_empty() {
1171 return Ok(());
1172 }
1173
1174 let read = self.uart.info().read_buffered(buf)?;
1176 buf = &mut buf[read..];
1177
1178 while !buf.is_empty() {
1179 self.wait_for_buffered_data(buf.len(), buf.len(), false)
1183 .await?;
1184
1185 let read = self.uart.info().read_buffered(buf)?;
1186 buf = &mut buf[read..];
1187 }
1188
1189 Ok(())
1190 }
1191
1192 #[instability::unstable]
1198 pub async fn wait_for_break_async(&mut self) {
1199 UartRxFuture::new(self.uart.reborrow(), RxEvent::BreakDetected).await;
1200 self.regs()
1201 .int_clr()
1202 .write(|w| w.brk_det().clear_bit_by_one());
1203 }
1204}
1205
1206impl<'d, Dm> UartRx<'d, Dm>
1207where
1208 Dm: DriverMode,
1209{
1210 fn regs(&self) -> &RegisterBlock {
1211 self.uart.info().regs()
1212 }
1213
1214 #[instability::unstable]
1218 pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
1219 let cts = cts.into();
1220
1221 cts.apply_input_config(&InputConfig::default());
1222 cts.set_input_enable(true);
1223
1224 self.uart.info().cts_signal.connect_to(&cts);
1225
1226 self
1227 }
1228
1229 #[instability::unstable]
1238 pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
1239 let rx = rx.into();
1240
1241 rx.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
1242 rx.set_input_enable(true);
1243
1244 self.uart.info().rx_signal.connect_to(&rx);
1245
1246 self
1247 }
1248
1249 #[instability::unstable]
1257 pub fn enable_break_detection(&mut self) {
1258 self.uart
1259 .info()
1260 .enable_listen_rx(RxEvent::BreakDetected.into(), true);
1261
1262 sync_regs(self.regs());
1263 }
1264
1265 #[instability::unstable]
1272 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1273 self.uart
1274 .info()
1275 .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
1276 self.uart
1277 .info()
1278 .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
1279
1280 self.uart.info().rxfifo_reset();
1281 Ok(())
1282 }
1283
1284 #[instability::unstable]
1288 pub fn check_for_errors(&mut self) -> Result<(), RxError> {
1289 self.uart.info().check_for_errors()
1290 }
1291
1292 #[instability::unstable]
1296 pub fn read_ready(&self) -> bool {
1297 self.uart.info().rx_fifo_count() > 0
1298 }
1299
1300 #[instability::unstable]
1321 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1322 self.uart.info().read(buf)
1323 }
1324
1325 #[instability::unstable]
1343 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1344 self.uart.info().read_buffered(buf)
1345 }
1346
1347 fn disable_rx_interrupts(&self) {
1353 self.regs().int_clr().write(|w| {
1354 w.rxfifo_full().clear_bit_by_one();
1355 w.rxfifo_ovf().clear_bit_by_one();
1356 w.rxfifo_tout().clear_bit_by_one();
1357 w.at_cmd_char_det().clear_bit_by_one()
1358 });
1359
1360 self.regs().int_ena().write(|w| {
1361 w.rxfifo_full().clear_bit();
1362 w.rxfifo_ovf().clear_bit();
1363 w.rxfifo_tout().clear_bit();
1364 w.at_cmd_char_det().clear_bit()
1365 });
1366 }
1367}
1368
1369impl<'d> Uart<'d, Blocking> {
1370 #[procmacros::doc_replace]
1371 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1389 UartBuilder::new(uart).init(config)
1390 }
1391
1392 pub fn into_async(self) -> Uart<'d, Async> {
1397 Uart {
1398 rx: self.rx.into_async(),
1399 tx: self.tx.into_async(),
1400 }
1401 }
1402
1403 #[cfg_attr(
1404 not(multi_core),
1405 doc = "Registers an interrupt handler for the peripheral."
1406 )]
1407 #[cfg_attr(
1408 multi_core,
1409 doc = "Registers an interrupt handler for the peripheral on the current core."
1410 )]
1411 #[doc = ""]
1412 #[instability::unstable]
1418 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1419 self.tx.uart.set_interrupt_handler(handler);
1421 }
1422
1423 #[procmacros::doc_replace]
1424 #[instability::unstable]
1491 pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1492 self.tx.uart.info().enable_listen(interrupts.into(), true)
1493 }
1494
1495 #[instability::unstable]
1497 pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1498 self.tx.uart.info().enable_listen(interrupts.into(), false)
1499 }
1500
1501 #[instability::unstable]
1503 pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1504 self.tx.uart.info().interrupts()
1505 }
1506
1507 #[instability::unstable]
1509 pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1510 self.tx.uart.info().clear_interrupts(interrupts)
1511 }
1512
1513 #[instability::unstable]
1518 pub fn wait_for_break(&mut self) {
1519 self.rx.wait_for_break()
1520 }
1521
1522 #[instability::unstable]
1532 pub fn wait_for_break_with_timeout(&mut self, timeout: crate::time::Duration) -> bool {
1533 self.rx.wait_for_break_with_timeout(timeout)
1534 }
1535}
1536
1537impl<'d> Uart<'d, Async> {
1538 pub fn into_blocking(self) -> Uart<'d, Blocking> {
1543 Uart {
1544 rx: self.rx.into_blocking(),
1545 tx: self.tx.into_blocking(),
1546 }
1547 }
1548
1549 #[procmacros::doc_replace]
1550 pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1581 self.tx.write_async(words).await
1582 }
1583
1584 #[procmacros::doc_replace]
1585 pub async fn flush_async(&mut self) -> Result<(), TxError> {
1611 self.tx.flush_async().await
1612 }
1613
1614 #[procmacros::doc_replace]
1615 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1653 self.rx.read_async(buf).await
1654 }
1655
1656 #[instability::unstable]
1671 pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1672 self.rx.read_exact_async(buf).await
1673 }
1674
1675 #[instability::unstable]
1681 pub async fn wait_for_break_async(&mut self) {
1682 self.rx.wait_for_break_async().await
1683 }
1684}
1685
1686#[derive(Debug, EnumSetType)]
1688#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1689#[non_exhaustive]
1690#[instability::unstable]
1691pub enum UartInterrupt {
1692 AtCmd,
1695
1696 TxDone,
1698
1699 RxBreakDetected,
1703
1704 RxFifoFull,
1707
1708 RxTimeout,
1711}
1712
1713impl<'d, Dm> Uart<'d, Dm>
1714where
1715 Dm: DriverMode,
1716{
1717 #[procmacros::doc_replace]
1718 pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
1737 self.rx = self.rx.with_rx(rx);
1738 self
1739 }
1740
1741 #[procmacros::doc_replace]
1742 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
1757 self.tx = self.tx.with_tx(tx);
1758 self
1759 }
1760
1761 #[procmacros::doc_replace]
1762 pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
1776 self.rx = self.rx.with_cts(cts);
1777 self
1778 }
1779
1780 #[procmacros::doc_replace]
1781 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
1795 self.tx = self.tx.with_rts(rts);
1796 self
1797 }
1798
1799 fn regs(&self) -> &RegisterBlock {
1800 self.tx.uart.info().regs()
1802 }
1803
1804 #[procmacros::doc_replace]
1805 pub fn write_ready(&self) -> bool {
1830 self.tx.write_ready()
1831 }
1832
1833 #[procmacros::doc_replace]
1834 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
1860 self.tx.write(data)
1861 }
1862
1863 #[procmacros::doc_replace]
1864 pub fn flush(&mut self) -> Result<(), TxError> {
1879 self.tx.flush()
1880 }
1881
1882 #[instability::unstable]
1884 pub fn send_break(&mut self, bits: u32) {
1885 self.tx.send_break(bits)
1886 }
1887
1888 #[procmacros::doc_replace]
1889 pub fn read_ready(&self) -> bool {
1914 self.rx.read_ready()
1915 }
1916
1917 #[procmacros::doc_replace]
1918 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1955 self.rx.read(buf)
1956 }
1957
1958 #[procmacros::doc_replace]
1959 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1977 self.rx.uart.info().apply_config(config)?;
1980
1981 self.rx.apply_config(config)?;
1982 self.tx.apply_config(config)?;
1983 Ok(())
1984 }
1985
1986 #[procmacros::doc_replace]
1987 #[instability::unstable]
2011 pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
2012 (self.rx, self.tx)
2013 }
2014
2015 #[instability::unstable]
2017 pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
2018 self.rx.check_for_errors()
2019 }
2020
2021 #[instability::unstable]
2038 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
2039 self.rx.read_buffered(buf)
2040 }
2041
2042 #[instability::unstable]
2044 pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
2045 #[cfg(not(any(esp32, esp32s2)))]
2046 self.regs()
2047 .clk_conf()
2048 .modify(|_, w| w.sclk_en().clear_bit());
2049
2050 self.regs().at_cmd_char().write(|w| unsafe {
2051 w.at_cmd_char().bits(config.cmd_char);
2052 w.char_num().bits(config.char_num)
2053 });
2054
2055 if let Some(pre_idle_count) = config.pre_idle_count {
2056 self.regs()
2057 .at_cmd_precnt()
2058 .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
2059 }
2060
2061 if let Some(post_idle_count) = config.post_idle_count {
2062 self.regs()
2063 .at_cmd_postcnt()
2064 .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
2065 }
2066
2067 if let Some(gap_timeout) = config.gap_timeout {
2068 self.regs()
2069 .at_cmd_gaptout()
2070 .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
2071 }
2072
2073 #[cfg(not(any(esp32, esp32s2)))]
2074 self.regs().clk_conf().modify(|_, w| w.sclk_en().set_bit());
2075
2076 sync_regs(self.regs());
2077 }
2078
2079 #[inline(always)]
2080 fn init(&mut self, config: Config) -> Result<(), ConfigError> {
2081 self.rx.disable_rx_interrupts();
2082 self.tx.disable_tx_interrupts();
2083
2084 self.rx.uart.info().rxfifo_reset();
2086 self.rx.uart.info().txfifo_reset();
2087
2088 self.apply_config(&config)?;
2089
2090 self.regs()
2093 .idle_conf()
2094 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2095
2096 self.regs().conf0().modify(|_, w| w.err_wr_mask().set_bit());
2099
2100 crate::rom::ets_delay_us(15);
2101
2102 self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
2105
2106 Ok(())
2107 }
2108}
2109
2110impl crate::private::Sealed for Uart<'_, Blocking> {}
2111
2112#[instability::unstable]
2113impl crate::interrupt::InterruptConfigurable for Uart<'_, Blocking> {
2114 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
2115 self.tx.uart.set_interrupt_handler(handler);
2117 }
2118}
2119
2120#[instability::unstable]
2121impl<Dm> ufmt_write::uWrite for Uart<'_, Dm>
2122where
2123 Dm: DriverMode,
2124{
2125 type Error = TxError;
2126
2127 #[inline]
2128 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
2129 self.tx.write_str(s)
2130 }
2131
2132 #[inline]
2133 fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
2134 self.tx.write_char(ch)
2135 }
2136}
2137
2138#[instability::unstable]
2139impl<Dm> ufmt_write::uWrite for UartTx<'_, Dm>
2140where
2141 Dm: DriverMode,
2142{
2143 type Error = TxError;
2144
2145 #[inline]
2146 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
2147 self.write_all(s.as_bytes())
2148 }
2149}
2150
2151impl<Dm> core::fmt::Write for Uart<'_, Dm>
2152where
2153 Dm: DriverMode,
2154{
2155 #[inline]
2156 fn write_str(&mut self, s: &str) -> core::fmt::Result {
2157 self.tx.write_str(s)
2158 }
2159}
2160
2161impl<Dm> core::fmt::Write for UartTx<'_, Dm>
2162where
2163 Dm: DriverMode,
2164{
2165 #[inline]
2166 fn write_str(&mut self, s: &str) -> core::fmt::Result {
2167 self.write_all(s.as_bytes()).map_err(|_| core::fmt::Error)
2168 }
2169}
2170
2171#[instability::unstable]
2173#[derive(Debug, Clone, Copy, PartialEq)]
2174#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2175#[non_exhaustive]
2176pub enum IoError {
2177 Tx(TxError),
2179 Rx(RxError),
2181}
2182
2183#[instability::unstable]
2184impl core::error::Error for IoError {}
2185
2186#[instability::unstable]
2187impl core::fmt::Display for IoError {
2188 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2189 match self {
2190 IoError::Tx(e) => e.fmt(f),
2191 IoError::Rx(e) => e.fmt(f),
2192 }
2193 }
2194}
2195
2196#[instability::unstable]
2197impl embedded_io_06::Error for IoError {
2198 fn kind(&self) -> embedded_io_06::ErrorKind {
2199 embedded_io_06::ErrorKind::Other
2200 }
2201}
2202
2203#[instability::unstable]
2204impl embedded_io_07::Error for IoError {
2205 fn kind(&self) -> embedded_io_07::ErrorKind {
2206 embedded_io_07::ErrorKind::Other
2207 }
2208}
2209
2210#[instability::unstable]
2211impl From<RxError> for IoError {
2212 fn from(e: RxError) -> Self {
2213 IoError::Rx(e)
2214 }
2215}
2216
2217#[instability::unstable]
2218impl From<TxError> for IoError {
2219 fn from(e: TxError) -> Self {
2220 IoError::Tx(e)
2221 }
2222}
2223
2224#[instability::unstable]
2225impl<Dm: DriverMode> embedded_io_06::ErrorType for Uart<'_, Dm> {
2226 type Error = IoError;
2227}
2228
2229#[instability::unstable]
2230impl<Dm: DriverMode> embedded_io_06::ErrorType for UartTx<'_, Dm> {
2231 type Error = TxError;
2232}
2233
2234#[instability::unstable]
2235impl<Dm: DriverMode> embedded_io_06::ErrorType for UartRx<'_, Dm> {
2236 type Error = RxError;
2237}
2238
2239#[instability::unstable]
2240impl<Dm> embedded_io_06::Read for Uart<'_, Dm>
2241where
2242 Dm: DriverMode,
2243{
2244 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2245 self.rx.read(buf).map_err(IoError::Rx)
2246 }
2247}
2248
2249#[instability::unstable]
2250impl<Dm> embedded_io_06::Read for UartRx<'_, Dm>
2251where
2252 Dm: DriverMode,
2253{
2254 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2255 self.read(buf)
2256 }
2257}
2258
2259#[instability::unstable]
2260impl<Dm> embedded_io_06::ReadReady for Uart<'_, Dm>
2261where
2262 Dm: DriverMode,
2263{
2264 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2265 Ok(self.rx.read_ready())
2266 }
2267}
2268
2269#[instability::unstable]
2270impl<Dm> embedded_io_06::ReadReady for UartRx<'_, Dm>
2271where
2272 Dm: DriverMode,
2273{
2274 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2275 Ok(UartRx::read_ready(self))
2276 }
2277}
2278
2279#[instability::unstable]
2280impl<Dm> embedded_io_06::Write for Uart<'_, Dm>
2281where
2282 Dm: DriverMode,
2283{
2284 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2285 self.tx.write(buf).map_err(IoError::Tx)
2286 }
2287
2288 fn flush(&mut self) -> Result<(), Self::Error> {
2289 self.tx.flush().map_err(IoError::Tx)
2290 }
2291}
2292
2293#[instability::unstable]
2294impl<Dm> embedded_io_06::Write for UartTx<'_, Dm>
2295where
2296 Dm: DriverMode,
2297{
2298 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2299 self.write(buf)
2300 }
2301
2302 fn flush(&mut self) -> Result<(), Self::Error> {
2303 self.flush()
2304 }
2305}
2306
2307#[instability::unstable]
2308impl<Dm> embedded_io_06::WriteReady for UartTx<'_, Dm>
2309where
2310 Dm: DriverMode,
2311{
2312 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2313 Ok(UartTx::write_ready(self))
2314 }
2315}
2316
2317#[instability::unstable]
2318impl<Dm> embedded_io_06::WriteReady for Uart<'_, Dm>
2319where
2320 Dm: DriverMode,
2321{
2322 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2323 Ok(self.tx.write_ready())
2324 }
2325}
2326
2327#[instability::unstable]
2328impl<Dm: DriverMode> embedded_io_07::ErrorType for Uart<'_, Dm> {
2329 type Error = IoError;
2330}
2331
2332#[instability::unstable]
2333impl<Dm: DriverMode> embedded_io_07::ErrorType for UartTx<'_, Dm> {
2334 type Error = TxError;
2335}
2336
2337#[instability::unstable]
2338impl<Dm: DriverMode> embedded_io_07::ErrorType for UartRx<'_, Dm> {
2339 type Error = RxError;
2340}
2341
2342#[instability::unstable]
2343impl<Dm> embedded_io_07::Read for Uart<'_, Dm>
2344where
2345 Dm: DriverMode,
2346{
2347 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2348 self.rx.read(buf).map_err(IoError::Rx)
2349 }
2350}
2351
2352#[instability::unstable]
2353impl<Dm> embedded_io_07::Read for UartRx<'_, Dm>
2354where
2355 Dm: DriverMode,
2356{
2357 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2358 self.read(buf)
2359 }
2360}
2361
2362#[instability::unstable]
2363impl<Dm> embedded_io_07::ReadReady for Uart<'_, Dm>
2364where
2365 Dm: DriverMode,
2366{
2367 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2368 Ok(self.rx.read_ready())
2369 }
2370}
2371
2372#[instability::unstable]
2373impl<Dm> embedded_io_07::ReadReady for UartRx<'_, Dm>
2374where
2375 Dm: DriverMode,
2376{
2377 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2378 Ok(UartRx::read_ready(self))
2379 }
2380}
2381
2382#[instability::unstable]
2383impl<Dm> embedded_io_07::Write for Uart<'_, Dm>
2384where
2385 Dm: DriverMode,
2386{
2387 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2388 self.tx.write(buf).map_err(IoError::Tx)
2389 }
2390
2391 fn flush(&mut self) -> Result<(), Self::Error> {
2392 self.tx.flush().map_err(IoError::Tx)
2393 }
2394}
2395
2396#[instability::unstable]
2397impl<Dm> embedded_io_07::Write for UartTx<'_, Dm>
2398where
2399 Dm: DriverMode,
2400{
2401 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2402 self.write(buf)
2403 }
2404
2405 fn flush(&mut self) -> Result<(), Self::Error> {
2406 self.flush()
2407 }
2408}
2409
2410#[instability::unstable]
2411impl<Dm> embedded_io_07::WriteReady for UartTx<'_, Dm>
2412where
2413 Dm: DriverMode,
2414{
2415 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2416 Ok(UartTx::write_ready(self))
2417 }
2418}
2419
2420#[instability::unstable]
2421impl<Dm> embedded_io_07::WriteReady for Uart<'_, Dm>
2422where
2423 Dm: DriverMode,
2424{
2425 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2426 Ok(self.tx.write_ready())
2427 }
2428}
2429
2430#[derive(Debug, EnumSetType)]
2431pub(crate) enum TxEvent {
2432 Done,
2433 FiFoEmpty,
2434}
2435
2436#[derive(Debug, EnumSetType)]
2437pub(crate) enum RxEvent {
2438 FifoFull,
2439 CmdCharDetected,
2440 FifoOvf,
2441 FifoTout,
2442 GlitchDetected,
2443 FrameError,
2444 ParityError,
2445 BreakDetected,
2446}
2447
2448fn rx_event_check_for_error(events: EnumSet<RxEvent>) -> Result<(), RxError> {
2449 for event in events {
2450 match event {
2451 RxEvent::FifoOvf => return Err(RxError::FifoOverflowed),
2452 RxEvent::GlitchDetected => return Err(RxError::GlitchOccurred),
2453 RxEvent::FrameError => return Err(RxError::FrameFormatViolated),
2454 RxEvent::ParityError => return Err(RxError::ParityMismatch),
2455 RxEvent::FifoFull
2456 | RxEvent::CmdCharDetected
2457 | RxEvent::FifoTout
2458 | RxEvent::BreakDetected => continue,
2459 }
2460 }
2461
2462 Ok(())
2463}
2464
2465#[must_use = "futures do nothing unless you `.await` or poll them"]
2471struct UartRxFuture {
2472 events: EnumSet<RxEvent>,
2473 uart: &'static Info,
2474 state: &'static State,
2475 registered: bool,
2476}
2477
2478impl UartRxFuture {
2479 fn new(uart: impl Instance, events: impl Into<EnumSet<RxEvent>>) -> Self {
2480 Self {
2481 events: events.into(),
2482 uart: uart.info(),
2483 state: uart.state(),
2484 registered: false,
2485 }
2486 }
2487}
2488
2489impl core::future::Future for UartRxFuture {
2490 type Output = EnumSet<RxEvent>;
2491
2492 fn poll(
2493 mut self: core::pin::Pin<&mut Self>,
2494 cx: &mut core::task::Context<'_>,
2495 ) -> core::task::Poll<Self::Output> {
2496 let events = self.uart.rx_events().intersection(self.events);
2497 if !events.is_empty() {
2498 self.uart.clear_rx_events(events);
2499 Poll::Ready(events)
2500 } else {
2501 self.state.rx_waker.register(cx.waker());
2502 if !self.registered {
2503 self.uart.enable_listen_rx(self.events, true);
2504 self.registered = true;
2505 }
2506 Poll::Pending
2507 }
2508 }
2509}
2510
2511impl Drop for UartRxFuture {
2512 fn drop(&mut self) {
2513 self.uart.enable_listen_rx(self.events, false);
2517 }
2518}
2519
2520#[must_use = "futures do nothing unless you `.await` or poll them"]
2521struct UartTxFuture {
2522 events: EnumSet<TxEvent>,
2523 uart: &'static Info,
2524 state: &'static State,
2525 registered: bool,
2526}
2527
2528impl UartTxFuture {
2529 fn new(uart: impl Instance, events: impl Into<EnumSet<TxEvent>>) -> Self {
2530 Self {
2531 events: events.into(),
2532 uart: uart.info(),
2533 state: uart.state(),
2534 registered: false,
2535 }
2536 }
2537}
2538
2539impl core::future::Future for UartTxFuture {
2540 type Output = ();
2541
2542 fn poll(
2543 mut self: core::pin::Pin<&mut Self>,
2544 cx: &mut core::task::Context<'_>,
2545 ) -> core::task::Poll<Self::Output> {
2546 let events = self.uart.tx_events().intersection(self.events);
2547 if !events.is_empty() {
2548 self.uart.clear_tx_events(events);
2549 Poll::Ready(())
2550 } else {
2551 self.state.tx_waker.register(cx.waker());
2552 if !self.registered {
2553 self.uart.enable_listen_tx(self.events, true);
2554 self.registered = true;
2555 }
2556 Poll::Pending
2557 }
2558 }
2559}
2560
2561impl Drop for UartTxFuture {
2562 fn drop(&mut self) {
2563 self.uart.enable_listen_tx(self.events, false);
2567 }
2568}
2569
2570#[instability::unstable]
2571impl embedded_io_async_06::Read for Uart<'_, Async> {
2572 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2573 self.read_async(buf).await.map_err(IoError::Rx)
2574 }
2575
2576 async fn read_exact(
2577 &mut self,
2578 buf: &mut [u8],
2579 ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2580 self.read_exact_async(buf)
2581 .await
2582 .map_err(|e| embedded_io_06::ReadExactError::Other(IoError::Rx(e)))
2583 }
2584}
2585
2586#[instability::unstable]
2587impl embedded_io_async_06::Read for UartRx<'_, Async> {
2588 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2589 self.read_async(buf).await
2590 }
2591
2592 async fn read_exact(
2593 &mut self,
2594 buf: &mut [u8],
2595 ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2596 self.read_exact_async(buf)
2597 .await
2598 .map_err(embedded_io_06::ReadExactError::Other)
2599 }
2600}
2601
2602#[instability::unstable]
2603impl embedded_io_async_06::Write for Uart<'_, Async> {
2604 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2605 self.write_async(buf).await.map_err(IoError::Tx)
2606 }
2607
2608 async fn flush(&mut self) -> Result<(), Self::Error> {
2609 self.flush_async().await.map_err(IoError::Tx)
2610 }
2611}
2612
2613#[instability::unstable]
2614impl embedded_io_async_06::Write for UartTx<'_, Async> {
2615 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2616 self.write_async(buf).await
2617 }
2618
2619 async fn flush(&mut self) -> Result<(), Self::Error> {
2620 self.flush_async().await
2621 }
2622}
2623
2624#[instability::unstable]
2625impl embedded_io_async_07::Read for Uart<'_, Async> {
2626 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2627 self.read_async(buf).await.map_err(IoError::Rx)
2628 }
2629
2630 async fn read_exact(
2631 &mut self,
2632 buf: &mut [u8],
2633 ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2634 self.read_exact_async(buf)
2635 .await
2636 .map_err(|e| embedded_io_07::ReadExactError::Other(IoError::Rx(e)))
2637 }
2638}
2639
2640#[instability::unstable]
2641impl embedded_io_async_07::Read for UartRx<'_, Async> {
2642 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2643 self.read_async(buf).await
2644 }
2645
2646 async fn read_exact(
2647 &mut self,
2648 buf: &mut [u8],
2649 ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2650 self.read_exact_async(buf)
2651 .await
2652 .map_err(embedded_io_07::ReadExactError::Other)
2653 }
2654}
2655
2656#[instability::unstable]
2657impl embedded_io_async_07::Write for Uart<'_, Async> {
2658 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2659 self.write_async(buf).await.map_err(IoError::Tx)
2660 }
2661
2662 async fn flush(&mut self) -> Result<(), Self::Error> {
2663 self.flush_async().await.map_err(IoError::Tx)
2664 }
2665}
2666
2667#[instability::unstable]
2668impl embedded_io_async_07::Write for UartTx<'_, Async> {
2669 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2670 self.write_async(buf).await
2671 }
2672
2673 async fn flush(&mut self) -> Result<(), Self::Error> {
2674 self.flush_async().await
2675 }
2676}
2677
2678#[ram]
2683pub(super) fn intr_handler(uart: &Info, state: &State) {
2684 let interrupts = uart.regs().int_st().read();
2685 let interrupt_bits = interrupts.bits(); let rx_wake = interrupts.rxfifo_full().bit_is_set()
2687 | interrupts.rxfifo_ovf().bit_is_set()
2688 | interrupts.rxfifo_tout().bit_is_set()
2689 | interrupts.at_cmd_char_det().bit_is_set()
2690 | interrupts.glitch_det().bit_is_set()
2691 | interrupts.frm_err().bit_is_set()
2692 | interrupts.parity_err().bit_is_set();
2693 let tx_wake = interrupts.tx_done().bit_is_set() | interrupts.txfifo_empty().bit_is_set();
2694
2695 uart.regs()
2696 .int_ena()
2697 .modify(|r, w| unsafe { w.bits(r.bits() & !interrupt_bits) });
2698
2699 if tx_wake {
2700 state.tx_waker.wake();
2701 }
2702 if rx_wake {
2703 state.rx_waker.wake();
2704 }
2705}
2706
2707#[cfg(lp_uart_driver_supported)]
2709#[instability::unstable]
2710pub mod lp_uart {
2711 use crate::{
2712 gpio::lp_io::{LowPowerInput, LowPowerOutput},
2713 peripherals::{LP_AON, LP_CLKRST, LP_IO, LP_UART, LPWR},
2714 soc::clocks::ClockTree,
2715 uart::{DataBits, Parity, StopBits},
2716 };
2717
2718 #[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
2720 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
2721 #[non_exhaustive]
2722 pub struct Config {
2723 baudrate: u32,
2726 data_bits: DataBits,
2728 parity: Parity,
2730 stop_bits: StopBits,
2732 #[builder_lite(unstable)]
2734 clock_source: ClockSource,
2735 }
2736
2737 impl Default for Config {
2738 fn default() -> Config {
2739 Config {
2740 baudrate: 115_200,
2741 data_bits: Default::default(),
2742 parity: Default::default(),
2743 stop_bits: Default::default(),
2744 clock_source: Default::default(),
2745 }
2746 }
2747 }
2748
2749 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
2751 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
2752 #[non_exhaustive]
2753 #[instability::unstable]
2754 pub enum ClockSource {
2755 RcFast,
2757
2758 #[default]
2760 Xtal,
2761 }
2762
2763 pub struct LpUart {
2765 uart: LP_UART<'static>,
2766 }
2767
2768 impl LpUart {
2769 pub fn new(
2772 uart: LP_UART<'static>,
2773 config: Config,
2774 _tx: LowPowerOutput<'_, 5>,
2775 _rx: LowPowerInput<'_, 4>,
2776 ) -> Self {
2777 LP_AON::regs()
2779 .gpio_mux()
2780 .modify(|r, w| unsafe { w.sel().bits(r.sel().bits() | (1 << 4) | (1 << 5)) });
2781
2782 LP_IO::regs()
2783 .gpio(4)
2784 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2785 LP_IO::regs()
2786 .gpio(5)
2787 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2788
2789 let mut me = Self { uart };
2790 let uart = me.uart.register_block();
2791
2792 uart.conf0().modify(|_, w| unsafe {
2798 w.parity().clear_bit();
2799 w.parity_en().clear_bit();
2800 w.bit_num().bits(0x3);
2801 w.stop_bit_num().bits(0x1)
2802 });
2803 uart.idle_conf()
2805 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2806 uart.hwfc_conf().modify(|_, w| w.rx_flow_en().clear_bit());
2808
2809 LPWR::regs()
2814 .lpperi()
2815 .modify(|_, w| w.lp_uart_clk_sel().clear_bit());
2816
2817 me.change_baud_internal(&config);
2820 me.change_parity(config.parity);
2822 me.change_data_bits(config.data_bits);
2824 me.change_stop_bits(config.stop_bits);
2826 me.change_tx_idle(0); me.rxfifo_reset();
2831 me.txfifo_reset();
2832
2833 me
2834 }
2835
2836 fn rxfifo_reset(&mut self) {
2837 self.uart
2838 .register_block()
2839 .conf0()
2840 .modify(|_, w| w.rxfifo_rst().set_bit());
2841 self.update();
2842
2843 self.uart
2844 .register_block()
2845 .conf0()
2846 .modify(|_, w| w.rxfifo_rst().clear_bit());
2847 self.update();
2848 }
2849
2850 fn txfifo_reset(&mut self) {
2851 self.uart
2852 .register_block()
2853 .conf0()
2854 .modify(|_, w| w.txfifo_rst().set_bit());
2855 self.update();
2856
2857 self.uart
2858 .register_block()
2859 .conf0()
2860 .modify(|_, w| w.txfifo_rst().clear_bit());
2861 self.update();
2862 }
2863
2864 fn update(&mut self) {
2865 let register_block = self.uart.register_block();
2866 register_block
2867 .reg_update()
2868 .modify(|_, w| w.reg_update().set_bit());
2869 while register_block.reg_update().read().reg_update().bit_is_set() {
2870 }
2872 }
2873
2874 fn change_baud_internal(&mut self, config: &Config) {
2875 let clk = ClockTree::with(|clocks| match config.clock_source {
2876 ClockSource::RcFast => crate::soc::clocks::rc_fast_clk_frequency(clocks),
2877 ClockSource::Xtal => crate::soc::clocks::xtal_d2_clk_frequency(clocks),
2878 });
2879
2880 LP_CLKRST::regs().lpperi().modify(|_, w| {
2881 w.lp_uart_clk_sel().bit(match config.clock_source {
2882 ClockSource::RcFast => false,
2883 ClockSource::Xtal => true,
2884 })
2885 });
2886 self.uart.register_block().clk_conf().modify(|_, w| {
2887 w.rx_sclk_en().set_bit();
2888 w.tx_sclk_en().set_bit()
2889 });
2890
2891 let divider = clk / config.baudrate;
2892 let divider = divider as u16;
2893
2894 self.uart
2895 .register_block()
2896 .clkdiv()
2897 .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) });
2898
2899 self.update();
2900 }
2901
2902 pub fn change_baud(&mut self, config: &Config) {
2904 self.change_baud_internal(config);
2905 self.txfifo_reset();
2906 self.rxfifo_reset();
2907 }
2908
2909 fn change_parity(&mut self, parity: Parity) -> &mut Self {
2910 if parity != Parity::None {
2911 self.uart
2912 .register_block()
2913 .conf0()
2914 .modify(|_, w| w.parity().bit((parity as u8 & 0x1) != 0));
2915 }
2916
2917 self.uart
2918 .register_block()
2919 .conf0()
2920 .modify(|_, w| match parity {
2921 Parity::None => w.parity_en().clear_bit(),
2922 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2923 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2924 });
2925
2926 self
2927 }
2928
2929 fn change_data_bits(&mut self, data_bits: DataBits) -> &mut Self {
2930 self.uart
2931 .register_block()
2932 .conf0()
2933 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2934
2935 self.update();
2936 self
2937 }
2938
2939 fn change_stop_bits(&mut self, stop_bits: StopBits) -> &mut Self {
2940 self.uart
2941 .register_block()
2942 .conf0()
2943 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2944
2945 self.update();
2946 self
2947 }
2948
2949 fn change_tx_idle(&mut self, idle_num: u16) -> &mut Self {
2950 self.uart
2951 .register_block()
2952 .idle_conf()
2953 .modify(|_, w| unsafe { w.tx_idle_num().bits(idle_num) });
2954
2955 self.update();
2956 self
2957 }
2958 }
2959}
2960
2961pub trait Instance: crate::private::Sealed + any::Degrade {
2963 #[doc(hidden)]
2964 fn parts(&self) -> (&'static Info, &'static State);
2966
2967 #[inline(always)]
2969 #[doc(hidden)]
2970 fn info(&self) -> &'static Info {
2971 self.parts().0
2972 }
2973
2974 #[inline(always)]
2976 #[doc(hidden)]
2977 fn state(&self) -> &'static State {
2978 self.parts().1
2979 }
2980}
2981
2982#[doc(hidden)]
2984#[non_exhaustive]
2985#[allow(private_interfaces, reason = "Unstable details")]
2986pub struct Info {
2987 pub register_block: *const RegisterBlock,
2991
2992 pub peripheral: crate::system::Peripheral,
2994
2995 pub clock_instance: clocks::UartInstance,
2997
2998 pub async_handler: InterruptHandler,
3000
3001 pub tx_signal: OutputSignal,
3003
3004 pub rx_signal: InputSignal,
3006
3007 pub cts_signal: InputSignal,
3009
3010 pub rts_signal: OutputSignal,
3012}
3013
3014#[doc(hidden)]
3016#[non_exhaustive]
3017pub struct State {
3018 pub rx_waker: AtomicWaker,
3020
3021 pub tx_waker: AtomicWaker,
3023
3024 pub is_rx_async: AtomicBool,
3026
3027 pub is_tx_async: AtomicBool,
3029}
3030
3031impl Info {
3032 const UART_FIFO_SIZE: u16 = property!("uart.ram_size");
3035 const RX_FIFO_MAX_THRHD: u16 = Self::UART_FIFO_SIZE - 1;
3036 const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
3037
3038 pub fn regs(&self) -> &RegisterBlock {
3040 unsafe { &*self.register_block }
3041 }
3042
3043 fn enable_listen(&self, interrupts: EnumSet<UartInterrupt>, enable: bool) {
3045 let reg_block = self.regs();
3046
3047 reg_block.int_ena().modify(|_, w| {
3048 for interrupt in interrupts {
3049 match interrupt {
3050 UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable),
3051 UartInterrupt::TxDone => w.tx_done().bit(enable),
3052 UartInterrupt::RxBreakDetected => w.brk_det().bit(enable),
3053 UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable),
3054 UartInterrupt::RxTimeout => w.rxfifo_tout().bit(enable),
3055 };
3056 }
3057 w
3058 });
3059 }
3060
3061 fn interrupts(&self) -> EnumSet<UartInterrupt> {
3062 let mut res = EnumSet::new();
3063 let reg_block = self.regs();
3064
3065 let ints = reg_block.int_raw().read();
3066
3067 if ints.at_cmd_char_det().bit_is_set() {
3068 res.insert(UartInterrupt::AtCmd);
3069 }
3070 if ints.tx_done().bit_is_set() {
3071 res.insert(UartInterrupt::TxDone);
3072 }
3073 if ints.brk_det().bit_is_set() {
3074 res.insert(UartInterrupt::RxBreakDetected);
3075 }
3076 if ints.rxfifo_full().bit_is_set() {
3077 res.insert(UartInterrupt::RxFifoFull);
3078 }
3079 if ints.rxfifo_tout().bit_is_set() {
3080 res.insert(UartInterrupt::RxTimeout);
3081 }
3082
3083 res
3084 }
3085
3086 fn clear_interrupts(&self, interrupts: EnumSet<UartInterrupt>) {
3087 let reg_block = self.regs();
3088
3089 reg_block.int_clr().write(|w| {
3090 for interrupt in interrupts {
3091 match interrupt {
3092 UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(),
3093 UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
3094 UartInterrupt::RxBreakDetected => w.brk_det().clear_bit_by_one(),
3095 UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(),
3096 UartInterrupt::RxTimeout => w.rxfifo_tout().clear_bit_by_one(),
3097 };
3098 }
3099 w
3100 });
3101 }
3102
3103 fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
3104 config.validate()?;
3105 self.change_baud(config)?;
3106 self.change_data_bits(config.data_bits);
3107 self.change_parity(config.parity);
3108 self.change_stop_bits(config.stop_bits);
3109 self.change_flow_control(config.sw_flow_ctrl, config.hw_flow_ctrl);
3110
3111 self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
3113
3114 Ok(())
3115 }
3116
3117 fn enable_listen_tx(&self, events: EnumSet<TxEvent>, enable: bool) {
3118 self.regs().int_ena().modify(|_, w| {
3119 for event in events {
3120 match event {
3121 TxEvent::Done => w.tx_done().bit(enable),
3122 TxEvent::FiFoEmpty => w.txfifo_empty().bit(enable),
3123 };
3124 }
3125 w
3126 });
3127 }
3128
3129 fn tx_events(&self) -> EnumSet<TxEvent> {
3130 let pending_interrupts = self.regs().int_raw().read();
3131 let mut active_events = EnumSet::new();
3132
3133 if pending_interrupts.tx_done().bit_is_set() {
3134 active_events |= TxEvent::Done;
3135 }
3136 if pending_interrupts.txfifo_empty().bit_is_set() {
3137 active_events |= TxEvent::FiFoEmpty;
3138 }
3139
3140 active_events
3141 }
3142
3143 fn clear_tx_events(&self, events: impl Into<EnumSet<TxEvent>>) {
3144 let events = events.into();
3145 self.regs().int_clr().write(|w| {
3146 for event in events {
3147 match event {
3148 TxEvent::FiFoEmpty => w.txfifo_empty().clear_bit_by_one(),
3149 TxEvent::Done => w.tx_done().clear_bit_by_one(),
3150 };
3151 }
3152 w
3153 });
3154 }
3155
3156 fn enable_listen_rx(&self, events: EnumSet<RxEvent>, enable: bool) {
3157 self.regs().int_ena().modify(|_, w| {
3158 for event in events {
3159 match event {
3160 RxEvent::FifoFull => w.rxfifo_full().bit(enable),
3161 RxEvent::BreakDetected => w.brk_det().bit(enable),
3162 RxEvent::CmdCharDetected => w.at_cmd_char_det().bit(enable),
3163
3164 RxEvent::FifoOvf => w.rxfifo_ovf().bit(enable),
3165 RxEvent::FifoTout => w.rxfifo_tout().bit(enable),
3166 RxEvent::GlitchDetected => w.glitch_det().bit(enable),
3167 RxEvent::FrameError => w.frm_err().bit(enable),
3168 RxEvent::ParityError => w.parity_err().bit(enable),
3169 };
3170 }
3171 w
3172 });
3173 }
3174
3175 fn rx_events(&self) -> EnumSet<RxEvent> {
3176 let pending_interrupts = self.regs().int_raw().read();
3177 let mut active_events = EnumSet::new();
3178
3179 if pending_interrupts.rxfifo_full().bit_is_set() {
3180 active_events |= RxEvent::FifoFull;
3181 }
3182 if pending_interrupts.brk_det().bit_is_set() {
3183 active_events |= RxEvent::BreakDetected;
3184 }
3185 if pending_interrupts.at_cmd_char_det().bit_is_set() {
3186 active_events |= RxEvent::CmdCharDetected;
3187 }
3188 if pending_interrupts.rxfifo_ovf().bit_is_set() {
3189 active_events |= RxEvent::FifoOvf;
3190 }
3191 if pending_interrupts.rxfifo_tout().bit_is_set() {
3192 active_events |= RxEvent::FifoTout;
3193 }
3194 if pending_interrupts.glitch_det().bit_is_set() {
3195 active_events |= RxEvent::GlitchDetected;
3196 }
3197 if pending_interrupts.frm_err().bit_is_set() {
3198 active_events |= RxEvent::FrameError;
3199 }
3200 if pending_interrupts.parity_err().bit_is_set() {
3201 active_events |= RxEvent::ParityError;
3202 }
3203
3204 active_events
3205 }
3206
3207 fn clear_rx_events(&self, events: impl Into<EnumSet<RxEvent>>) {
3208 let events = events.into();
3209 self.regs().int_clr().write(|w| {
3210 for event in events {
3211 match event {
3212 RxEvent::FifoFull => w.rxfifo_full().clear_bit_by_one(),
3213 RxEvent::BreakDetected => w.brk_det().clear_bit_by_one(),
3214 RxEvent::CmdCharDetected => w.at_cmd_char_det().clear_bit_by_one(),
3215
3216 RxEvent::FifoOvf => w.rxfifo_ovf().clear_bit_by_one(),
3217 RxEvent::FifoTout => w.rxfifo_tout().clear_bit_by_one(),
3218 RxEvent::GlitchDetected => w.glitch_det().clear_bit_by_one(),
3219 RxEvent::FrameError => w.frm_err().clear_bit_by_one(),
3220 RxEvent::ParityError => w.parity_err().clear_bit_by_one(),
3221 };
3222 }
3223 w
3224 });
3225 }
3226
3227 fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3234 if threshold > Self::RX_FIFO_MAX_THRHD {
3235 return Err(ConfigError::RxFifoThresholdNotSupported);
3236 }
3237
3238 self.regs()
3239 .conf1()
3240 .modify(|_, w| unsafe { w.rxfifo_full_thrhd().bits(threshold as _) });
3241
3242 Ok(())
3243 }
3244
3245 #[allow(clippy::useless_conversion)]
3247 fn rx_fifo_full_threshold(&self) -> u16 {
3248 self.regs().conf1().read().rxfifo_full_thrhd().bits().into()
3249 }
3250
3251 fn set_tx_fifo_empty_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3258 if threshold > Self::TX_FIFO_MAX_THRHD {
3259 return Err(ConfigError::TxFifoThresholdNotSupported);
3260 }
3261
3262 self.regs()
3263 .conf1()
3264 .modify(|_, w| unsafe { w.txfifo_empty_thrhd().bits(threshold as _) });
3265
3266 Ok(())
3267 }
3268
3269 fn set_rx_timeout(&self, timeout: Option<u8>, _symbol_len: u8) -> Result<(), ConfigError> {
3284 cfg_if::cfg_if! {
3285 if #[cfg(esp32)] {
3286 const MAX_THRHD: u8 = 0x7F; } else {
3288 const MAX_THRHD: u16 = 0x3FF; }
3290 }
3291
3292 let register_block = self.regs();
3293
3294 if let Some(timeout) = timeout {
3295 #[cfg(esp32)]
3297 let timeout_reg = timeout;
3298 #[cfg(not(esp32))]
3300 let timeout_reg = timeout as u16 * _symbol_len as u16;
3301
3302 if timeout_reg > MAX_THRHD {
3303 return Err(ConfigError::TimeoutTooLong);
3304 }
3305
3306 cfg_if::cfg_if! {
3307 if #[cfg(esp32)] {
3308 let reg_thrhd = register_block.conf1();
3309 } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3310 let reg_thrhd = register_block.tout_conf();
3311 } else {
3312 let reg_thrhd = register_block.mem_conf();
3313 }
3314 }
3315 reg_thrhd.modify(|_, w| unsafe { w.rx_tout_thrhd().bits(timeout_reg) });
3316 }
3317
3318 cfg_if::cfg_if! {
3319 if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3320 let reg_en = register_block.tout_conf();
3321 } else {
3322 let reg_en = register_block.conf1();
3323 }
3324 }
3325 reg_en.modify(|_, w| w.rx_tout_en().bit(timeout.is_some()));
3326
3327 self.sync_regs();
3328
3329 Ok(())
3330 }
3331
3332 fn sync_regs(&self) {
3333 sync_regs(self.regs());
3334 }
3335
3336 fn change_baud(&self, config: &Config) -> Result<(), ConfigError> {
3337 ClockTree::with(|clocks| {
3338 let clock = self.clock_instance;
3339
3340 let source_config = ClockConfig::new(
3341 config.clock_source,
3342 #[cfg(any(uart_has_sclk_divider, soc_has_pcr))]
3343 0,
3344 );
3345 let clk = clock.function_clock_config_frequency(clocks, source_config);
3346
3347 const FRAC_BITS: u32 = const {
3350 let largest_divider: u32 =
3351 property!("clock_tree.uart.baud_rate_generator.fractional").1;
3352 ::core::assert!((largest_divider + 1).is_power_of_two());
3353 largest_divider.count_ones()
3354 };
3355 const FRAC_MASK: u32 = (1 << FRAC_BITS) - 1;
3356
3357 cfg_if::cfg_if! {
3360 if #[cfg(any(uart_has_sclk_divider, soc_has_pcr))] {
3361 const MAX_DIV: u32 = property!("clock_tree.uart.baud_rate_generator.integral").1;
3362 let clk_div = clk.div_ceil(MAX_DIV).div_ceil(config.baudrate);
3363 debug!("SCLK: {} divider: {}", clk, clk_div);
3364
3365 let conf = ClockConfig::new(config.clock_source, clk_div - 1);
3366 let divider = (clk << FRAC_BITS) / (config.baudrate * clk_div);
3367 } else {
3368 debug!("SCLK: {}", clk);
3369 let conf = ClockConfig::new(config.clock_source);
3370 let divider = (clk << FRAC_BITS) / config.baudrate;
3371 }
3372 }
3373
3374 let divider_integer = divider >> FRAC_BITS;
3375 let divider_frag = divider & FRAC_MASK;
3376 debug!(
3377 "UART CLK divider: {} + {}/16",
3378 divider_integer, divider_frag
3379 );
3380
3381 clock.configure_function_clock(clocks, conf);
3382 clock.configure_baud_rate_generator(
3383 clocks,
3384 BaudRateConfig::new(divider_frag, divider_integer),
3385 );
3386
3387 self.sync_regs();
3388
3389 #[cfg(feature = "unstable")]
3390 {
3391 let deviation_limit = match config.baudrate_tolerance {
3392 BaudrateTolerance::Exact => 1, BaudrateTolerance::ErrorPercent(percent) => percent as u32,
3394 _ => return Ok(()),
3395 };
3396
3397 let actual_baud = clock.baud_rate_generator_frequency(clocks);
3398 if actual_baud == 0 {
3399 return Err(ConfigError::BaudrateNotAchievable);
3400 }
3401
3402 let deviation = (config.baudrate.abs_diff(actual_baud) * 100) / actual_baud;
3403 debug!(
3404 "Nominal baud: {}, actual: {}, deviation: {}%",
3405 config.baudrate, actual_baud, deviation
3406 );
3407
3408 if deviation > deviation_limit {
3409 return Err(ConfigError::BaudrateNotAchievable);
3410 }
3411 }
3412
3413 Ok(())
3414 })
3415 }
3416
3417 fn change_data_bits(&self, data_bits: DataBits) {
3418 self.regs()
3419 .conf0()
3420 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
3421 }
3422
3423 fn change_parity(&self, parity: Parity) {
3424 self.regs().conf0().modify(|_, w| match parity {
3425 Parity::None => w.parity_en().clear_bit(),
3426 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
3427 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
3428 });
3429 }
3430
3431 fn change_stop_bits(&self, stop_bits: StopBits) {
3432 #[cfg(esp32)]
3433 {
3434 if stop_bits == StopBits::_2 {
3436 self.regs()
3437 .rs485_conf()
3438 .modify(|_, w| w.dl1_en().bit(stop_bits == StopBits::_2));
3439
3440 self.regs()
3441 .conf0()
3442 .modify(|_, w| unsafe { w.stop_bit_num().bits(1) });
3443 }
3444 }
3445
3446 #[cfg(not(esp32))]
3447 self.regs()
3448 .conf0()
3449 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
3450 }
3451
3452 fn change_flow_control(&self, sw_flow_ctrl: SwFlowControl, hw_flow_ctrl: HwFlowControl) {
3453 match sw_flow_ctrl {
3455 SwFlowControl::Enabled {
3456 xon_char,
3457 xoff_char,
3458 xon_threshold,
3459 xoff_threshold,
3460 } => {
3461 cfg_if::cfg_if! {
3462 if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3463 self.regs().swfc_conf0().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3464 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold)});
3465 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3466 } else if #[cfg(esp32)]{
3467 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3468 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold) });
3469 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3470 } else {
3471 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3472 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold as u16) });
3473 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_threshold().bits(xoff_threshold as u16) });
3474 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_char().bits(xon_char) });
3475 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_char().bits(xoff_char) });
3476 }
3477 }
3478 }
3479 SwFlowControl::Disabled => {
3480 cfg_if::cfg_if! {
3481 if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3482 let reg = self.regs().swfc_conf0();
3483 } else {
3484 let reg = self.regs().flow_conf();
3485 }
3486 }
3487
3488 reg.modify(|_, w| w.sw_flow_con_en().clear_bit());
3489 reg.modify(|_, w| w.xonoff_del().clear_bit());
3490 }
3491 }
3492
3493 self.regs().conf0().modify(|_, w| {
3494 w.tx_flow_en()
3495 .bit(matches!(hw_flow_ctrl.cts, CtsConfig::Enabled))
3496 });
3497
3498 match hw_flow_ctrl.rts {
3499 RtsConfig::Enabled(threshold) => self.configure_rts_flow_ctrl(true, Some(threshold)),
3500 RtsConfig::Disabled => self.configure_rts_flow_ctrl(false, None),
3501 }
3502
3503 sync_regs(self.regs());
3504 }
3505
3506 fn configure_rts_flow_ctrl(&self, enable: bool, threshold: Option<u8>) {
3507 if let Some(threshold) = threshold {
3508 cfg_if::cfg_if! {
3509 if #[cfg(esp32)] {
3510 self.regs().conf1().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3511 } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3512 self.regs().hwfc_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3513 } else {
3514 self.regs().mem_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold as u16) });
3515 }
3516 }
3517 }
3518
3519 cfg_if::cfg_if! {
3520 if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3521 self.regs().hwfc_conf().modify(|_, w| {
3522 w.rx_flow_en().bit(enable)
3523 });
3524 } else {
3525 self.regs().conf1().modify(|_, w| {
3526 w.rx_flow_en().bit(enable)
3527 });
3528 }
3529 }
3530 }
3531
3532 fn rxfifo_reset(&self) {
3533 fn rxfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3534 reg_block.conf0().modify(|_, w| w.rxfifo_rst().bit(enable));
3535 sync_regs(reg_block);
3536 }
3537
3538 rxfifo_rst(self.regs(), true);
3539 rxfifo_rst(self.regs(), false);
3540 }
3541
3542 fn txfifo_reset(&self) {
3543 fn txfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3544 reg_block.conf0().modify(|_, w| w.txfifo_rst().bit(enable));
3545 sync_regs(reg_block);
3546 }
3547
3548 txfifo_rst(self.regs(), true);
3549 txfifo_rst(self.regs(), false);
3550 }
3551
3552 fn current_symbol_length(&self) -> u8 {
3553 let conf0 = self.regs().conf0().read();
3554 let data_bits = conf0.bit_num().bits() + 5; let parity = conf0.parity_en().bit() as u8;
3556 let mut stop_bits = conf0.stop_bit_num().bits();
3557
3558 match stop_bits {
3559 1 => {
3560 #[cfg(esp32)]
3562 if self.regs().rs485_conf().read().dl1_en().bit_is_set() {
3563 stop_bits = 2;
3564 }
3565 }
3566 _ => stop_bits = 2,
3568 }
3569
3570 1 + data_bits + parity + stop_bits
3571 }
3572
3573 fn read_next_from_fifo(&self) -> u8 {
3577 fn access_fifo_register<R>(f: impl Fn() -> R) -> R {
3578 cfg_if::cfg_if! {
3580 if #[cfg(esp32)] {
3581 crate::interrupt::free(f)
3582 } else {
3583 f()
3584 }
3585 }
3586 }
3587
3588 let fifo_reg = self.regs().fifo();
3589 cfg_if::cfg_if! {
3590 if #[cfg(esp32s2)] {
3591 let fifo_reg = unsafe {
3593 &*fifo_reg.as_ptr().cast::<u8>().add(0x20C00000).cast::<crate::pac::uart0::FIFO>()
3594 };
3595 }
3596 }
3597
3598 access_fifo_register(|| fifo_reg.read().rxfifo_rd_byte().bits())
3599 }
3600
3601 #[allow(clippy::useless_conversion)]
3602 fn tx_fifo_count(&self) -> u16 {
3603 u16::from(self.regs().status().read().txfifo_cnt().bits())
3604 }
3605
3606 fn write_byte(&self, byte: u8) {
3607 self.regs()
3608 .fifo()
3609 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
3610 }
3611
3612 fn check_for_errors(&self) -> Result<(), RxError> {
3613 let errors = RxEvent::FifoOvf
3614 | RxEvent::FifoTout
3615 | RxEvent::GlitchDetected
3616 | RxEvent::FrameError
3617 | RxEvent::ParityError;
3618 let events = self.rx_events().intersection(errors);
3619 let result = rx_event_check_for_error(events);
3620 if result.is_err() {
3621 self.clear_rx_events(errors);
3622 if events.contains(RxEvent::FifoOvf) {
3623 self.rxfifo_reset();
3624 }
3625 }
3626 result
3627 }
3628
3629 #[cfg(not(esp32))]
3630 #[allow(clippy::unnecessary_cast)]
3631 fn rx_fifo_count(&self) -> u16 {
3632 self.regs().status().read().rxfifo_cnt().bits() as u16
3633 }
3634
3635 #[cfg(esp32)]
3636 fn rx_fifo_count(&self) -> u16 {
3637 let fifo_cnt = self.regs().status().read().rxfifo_cnt().bits();
3638
3639 let status = self.regs().mem_rx_status().read();
3642 let rd_addr: u16 = status.mem_rx_rd_addr().bits();
3643 let wr_addr: u16 = status.mem_rx_wr_addr().bits();
3644
3645 if wr_addr > rd_addr {
3646 wr_addr - rd_addr
3647 } else if wr_addr < rd_addr {
3648 (wr_addr + Info::UART_FIFO_SIZE) - rd_addr
3649 } else if fifo_cnt > 0 {
3650 Info::UART_FIFO_SIZE
3651 } else {
3652 0
3653 }
3654 }
3655
3656 fn write(&self, data: &[u8]) -> Result<usize, TxError> {
3657 if data.is_empty() {
3658 return Ok(0);
3659 }
3660
3661 while self.tx_fifo_count() >= Info::UART_FIFO_SIZE {}
3662
3663 let space = (Info::UART_FIFO_SIZE - self.tx_fifo_count()) as usize;
3664 let to_write = space.min(data.len());
3665 for &byte in &data[..to_write] {
3666 self.write_byte(byte);
3667 }
3668
3669 Ok(to_write)
3670 }
3671
3672 fn read(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3673 if buf.is_empty() {
3674 return Ok(0);
3675 }
3676
3677 while self.rx_fifo_count() == 0 {
3678 self.check_for_errors()?;
3680 }
3681
3682 self.read_buffered(buf)
3683 }
3684
3685 fn read_buffered(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3686 let to_read = (self.rx_fifo_count() as usize).min(buf.len());
3689 self.check_for_errors()?;
3690
3691 for byte_into in buf[..to_read].iter_mut() {
3692 *byte_into = self.read_next_from_fifo();
3693 }
3694
3695 self.clear_rx_events(RxEvent::FifoFull);
3697
3698 Ok(to_read)
3699 }
3700}
3701
3702impl PartialEq for Info {
3703 fn eq(&self, other: &Self) -> bool {
3704 core::ptr::eq(self.register_block, other.register_block)
3705 }
3706}
3707
3708unsafe impl Sync for Info {}
3709
3710for_each_uart! {
3711 ($id:literal, $inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident) => {
3712 impl Instance for crate::peripherals::$inst<'_> {
3713 fn parts(&self) -> (&'static Info, &'static State) {
3714 #[handler]
3715 #[ram]
3716 pub(super) fn irq_handler() {
3717 intr_handler(&PERIPHERAL, &STATE);
3718 }
3719
3720 static STATE: State = State {
3721 tx_waker: AtomicWaker::new(),
3722 rx_waker: AtomicWaker::new(),
3723 is_rx_async: AtomicBool::new(false),
3724 is_tx_async: AtomicBool::new(false),
3725 };
3726
3727 static PERIPHERAL: Info = Info {
3728 register_block: crate::peripherals::$inst::ptr(),
3729 peripheral: crate::system::Peripheral::$peri,
3730 clock_instance: clocks::UartInstance::$peri,
3731 async_handler: irq_handler,
3732 tx_signal: OutputSignal::$txd,
3733 rx_signal: InputSignal::$rxd,
3734 cts_signal: InputSignal::$cts,
3735 rts_signal: OutputSignal::$rts,
3736 };
3737 (&PERIPHERAL, &STATE)
3738 }
3739 }
3740 };
3741}
3742
3743crate::any_peripheral! {
3744 pub peripheral AnyUart<'d> {
3746 #[cfg(soc_has_uart0)]
3747 Uart0(crate::peripherals::UART0<'d>),
3748 #[cfg(soc_has_uart1)]
3749 Uart1(crate::peripherals::UART1<'d>),
3750 #[cfg(soc_has_uart2)]
3751 Uart2(crate::peripherals::UART2<'d>),
3752 }
3753}
3754
3755impl Instance for AnyUart<'_> {
3756 #[inline]
3757 fn parts(&self) -> (&'static Info, &'static State) {
3758 any::delegate!(self, uart => { uart.parts() })
3759 }
3760}
3761
3762impl AnyUart<'_> {
3763 fn bind_peri_interrupt(&self, handler: InterruptHandler) {
3764 any::delegate!(self, uart => { uart.bind_peri_interrupt(handler) })
3765 }
3766
3767 fn disable_peri_interrupt_on_all_cores(&self) {
3768 any::delegate!(self, uart => { uart.disable_peri_interrupt_on_all_cores() })
3769 }
3770
3771 fn set_interrupt_handler(&self, handler: InterruptHandler) {
3772 self.disable_peri_interrupt_on_all_cores();
3773
3774 self.info().enable_listen(EnumSet::all(), false);
3775 self.info().clear_interrupts(EnumSet::all());
3776
3777 self.bind_peri_interrupt(handler);
3778 }
3779}
3780
3781struct UartClockGuard<'t> {
3782 uart: AnyUart<'t>,
3783}
3784
3785impl<'t> UartClockGuard<'t> {
3786 fn new(uart: AnyUart<'t>) -> Self {
3787 ClockTree::with(|clocks| {
3788 let clock = uart.info().clock_instance;
3789
3790 let sclk_config = ClockConfig::new(
3792 Default::default(),
3793 #[cfg(any(uart_has_sclk_divider, soc_has_pcr))]
3794 0,
3795 );
3796 clock.configure_function_clock(clocks, sclk_config);
3797 clock.request_function_clock(clocks);
3798 clock.request_baud_rate_generator(clocks);
3799 #[cfg(soc_has_clock_node_uart_mem_clock)]
3800 clock.request_mem_clock(clocks);
3801 });
3802
3803 Self { uart }
3804 }
3805}
3806
3807impl Clone for UartClockGuard<'_> {
3808 fn clone(&self) -> Self {
3809 Self::new(unsafe { self.uart.clone_unchecked() })
3810 }
3811}
3812
3813impl Drop for UartClockGuard<'_> {
3814 fn drop(&mut self) {
3815 ClockTree::with(|clocks| {
3816 let clock = self.uart.info().clock_instance;
3817
3818 #[cfg(soc_has_clock_node_uart_mem_clock)]
3819 clock.release_mem_clock(clocks);
3820 clock.release_baud_rate_generator(clocks);
3821 clock.release_function_clock(clocks);
3822 });
3823 }
3824}