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 while self.uart.info().rx_fifo_count() < minimum {
1083 let info = self.uart.info();
1087 unwrap!(info.set_rx_fifo_full_threshold(max_threshold));
1088 let _guard = DropGuard::new((), |_| {
1089 unwrap!(info.set_rx_fifo_full_threshold(current_threshold));
1090 });
1091
1092 let mut events = RxEvent::FifoFull
1094 | RxEvent::FifoOvf
1095 | RxEvent::FrameError
1096 | RxEvent::GlitchDetected
1097 | RxEvent::ParityError;
1098
1099 if self.regs().at_cmd_char().read().char_num().bits() > 0 {
1100 events |= RxEvent::CmdCharDetected;
1101 }
1102
1103 cfg_if::cfg_if! {
1104 if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
1105 let reg_en = self.regs().tout_conf();
1106 } else {
1107 let reg_en = self.regs().conf1();
1108 }
1109 };
1110 if listen_for_timeout && reg_en.read().rx_tout_en().bit_is_set() {
1111 events |= RxEvent::FifoTout;
1112 }
1113
1114 let events = UartRxFuture::new(self.uart.reborrow(), events).await;
1115
1116 let result = rx_event_check_for_error(events);
1117 if let Err(error) = result {
1118 if error == RxError::FifoOverflowed {
1119 self.uart.info().rxfifo_reset();
1120 }
1121 return Err(error);
1122 }
1123 }
1124
1125 Ok(())
1126 }
1127
1128 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1147 if buf.is_empty() {
1148 return Ok(0);
1149 }
1150
1151 self.wait_for_buffered_data(1, buf.len(), true).await?;
1152
1153 self.read_buffered(buf)
1154 }
1155
1156 pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
1171 if buf.is_empty() {
1172 return Ok(());
1173 }
1174
1175 let read = self.uart.info().read_buffered(buf)?;
1177 buf = &mut buf[read..];
1178
1179 while !buf.is_empty() {
1180 self.wait_for_buffered_data(buf.len(), buf.len(), false)
1184 .await?;
1185
1186 let read = self.uart.info().read_buffered(buf)?;
1187 buf = &mut buf[read..];
1188 }
1189
1190 Ok(())
1191 }
1192
1193 #[instability::unstable]
1199 pub async fn wait_for_break_async(&mut self) {
1200 UartRxFuture::new(self.uart.reborrow(), RxEvent::BreakDetected).await;
1201 self.regs()
1202 .int_clr()
1203 .write(|w| w.brk_det().clear_bit_by_one());
1204 }
1205}
1206
1207impl<'d, Dm> UartRx<'d, Dm>
1208where
1209 Dm: DriverMode,
1210{
1211 fn regs(&self) -> &RegisterBlock {
1212 self.uart.info().regs()
1213 }
1214
1215 #[instability::unstable]
1219 pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
1220 let cts = cts.into();
1221
1222 cts.apply_input_config(&InputConfig::default());
1223 cts.set_input_enable(true);
1224
1225 self.uart.info().cts_signal.connect_to(&cts);
1226
1227 self
1228 }
1229
1230 #[instability::unstable]
1239 pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
1240 let rx = rx.into();
1241
1242 rx.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
1243 rx.set_input_enable(true);
1244
1245 self.uart.info().rx_signal.connect_to(&rx);
1246
1247 self
1248 }
1249
1250 #[instability::unstable]
1258 pub fn enable_break_detection(&mut self) {
1259 self.uart
1260 .info()
1261 .enable_listen_rx(RxEvent::BreakDetected.into(), true);
1262
1263 sync_regs(self.regs());
1264 }
1265
1266 #[instability::unstable]
1273 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1274 self.uart
1275 .info()
1276 .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
1277 self.uart
1278 .info()
1279 .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
1280
1281 self.uart.info().rxfifo_reset();
1282 Ok(())
1283 }
1284
1285 #[instability::unstable]
1289 pub fn check_for_errors(&mut self) -> Result<(), RxError> {
1290 self.uart.info().check_for_errors()
1291 }
1292
1293 #[instability::unstable]
1297 pub fn read_ready(&self) -> bool {
1298 self.uart.info().rx_fifo_count() > 0
1299 }
1300
1301 #[instability::unstable]
1322 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1323 self.uart.info().read(buf)
1324 }
1325
1326 #[instability::unstable]
1344 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1345 self.uart.info().read_buffered(buf)
1346 }
1347
1348 fn disable_rx_interrupts(&self) {
1354 self.regs().int_clr().write(|w| {
1355 w.rxfifo_full().clear_bit_by_one();
1356 w.rxfifo_ovf().clear_bit_by_one();
1357 w.rxfifo_tout().clear_bit_by_one();
1358 w.at_cmd_char_det().clear_bit_by_one()
1359 });
1360
1361 self.regs().int_ena().write(|w| {
1362 w.rxfifo_full().clear_bit();
1363 w.rxfifo_ovf().clear_bit();
1364 w.rxfifo_tout().clear_bit();
1365 w.at_cmd_char_det().clear_bit()
1366 });
1367 }
1368}
1369
1370impl<'d> Uart<'d, Blocking> {
1371 #[procmacros::doc_replace]
1372 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1390 UartBuilder::new(uart).init(config)
1391 }
1392
1393 pub fn into_async(self) -> Uart<'d, Async> {
1398 Uart {
1399 rx: self.rx.into_async(),
1400 tx: self.tx.into_async(),
1401 }
1402 }
1403
1404 #[cfg_attr(
1405 not(multi_core),
1406 doc = "Registers an interrupt handler for the peripheral."
1407 )]
1408 #[cfg_attr(
1409 multi_core,
1410 doc = "Registers an interrupt handler for the peripheral on the current core."
1411 )]
1412 #[doc = ""]
1413 #[instability::unstable]
1419 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1420 self.tx.uart.set_interrupt_handler(handler);
1422 }
1423
1424 #[procmacros::doc_replace]
1425 #[instability::unstable]
1492 pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1493 self.tx.uart.info().enable_listen(interrupts.into(), true)
1494 }
1495
1496 #[instability::unstable]
1498 pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1499 self.tx.uart.info().enable_listen(interrupts.into(), false)
1500 }
1501
1502 #[instability::unstable]
1504 pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1505 self.tx.uart.info().interrupts()
1506 }
1507
1508 #[instability::unstable]
1510 pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1511 self.tx.uart.info().clear_interrupts(interrupts)
1512 }
1513
1514 #[instability::unstable]
1519 pub fn wait_for_break(&mut self) {
1520 self.rx.wait_for_break()
1521 }
1522
1523 #[instability::unstable]
1533 pub fn wait_for_break_with_timeout(&mut self, timeout: crate::time::Duration) -> bool {
1534 self.rx.wait_for_break_with_timeout(timeout)
1535 }
1536}
1537
1538impl<'d> Uart<'d, Async> {
1539 pub fn into_blocking(self) -> Uart<'d, Blocking> {
1544 Uart {
1545 rx: self.rx.into_blocking(),
1546 tx: self.tx.into_blocking(),
1547 }
1548 }
1549
1550 #[procmacros::doc_replace]
1551 pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1582 self.tx.write_async(words).await
1583 }
1584
1585 #[procmacros::doc_replace]
1586 pub async fn flush_async(&mut self) -> Result<(), TxError> {
1612 self.tx.flush_async().await
1613 }
1614
1615 #[procmacros::doc_replace]
1616 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1654 self.rx.read_async(buf).await
1655 }
1656
1657 #[instability::unstable]
1672 pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1673 self.rx.read_exact_async(buf).await
1674 }
1675
1676 #[instability::unstable]
1682 pub async fn wait_for_break_async(&mut self) {
1683 self.rx.wait_for_break_async().await
1684 }
1685}
1686
1687#[derive(Debug, EnumSetType)]
1689#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1690#[non_exhaustive]
1691#[instability::unstable]
1692pub enum UartInterrupt {
1693 AtCmd,
1696
1697 TxDone,
1699
1700 RxBreakDetected,
1704
1705 RxFifoFull,
1708
1709 RxTimeout,
1712}
1713
1714impl<'d, Dm> Uart<'d, Dm>
1715where
1716 Dm: DriverMode,
1717{
1718 #[procmacros::doc_replace]
1719 pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
1738 self.rx = self.rx.with_rx(rx);
1739 self
1740 }
1741
1742 #[procmacros::doc_replace]
1743 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
1758 self.tx = self.tx.with_tx(tx);
1759 self
1760 }
1761
1762 #[procmacros::doc_replace]
1763 pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
1777 self.rx = self.rx.with_cts(cts);
1778 self
1779 }
1780
1781 #[procmacros::doc_replace]
1782 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
1796 self.tx = self.tx.with_rts(rts);
1797 self
1798 }
1799
1800 fn regs(&self) -> &RegisterBlock {
1801 self.tx.uart.info().regs()
1803 }
1804
1805 #[procmacros::doc_replace]
1806 pub fn write_ready(&self) -> bool {
1831 self.tx.write_ready()
1832 }
1833
1834 #[procmacros::doc_replace]
1835 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
1861 self.tx.write(data)
1862 }
1863
1864 #[procmacros::doc_replace]
1865 pub fn flush(&mut self) -> Result<(), TxError> {
1880 self.tx.flush()
1881 }
1882
1883 #[instability::unstable]
1885 pub fn send_break(&mut self, bits: u32) {
1886 self.tx.send_break(bits)
1887 }
1888
1889 #[procmacros::doc_replace]
1890 pub fn read_ready(&self) -> bool {
1915 self.rx.read_ready()
1916 }
1917
1918 #[procmacros::doc_replace]
1919 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1956 self.rx.read(buf)
1957 }
1958
1959 #[procmacros::doc_replace]
1960 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1978 self.rx.uart.info().apply_config(config)?;
1981
1982 self.rx.apply_config(config)?;
1983 self.tx.apply_config(config)?;
1984 Ok(())
1985 }
1986
1987 #[procmacros::doc_replace]
1988 #[instability::unstable]
2012 pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
2013 (self.rx, self.tx)
2014 }
2015
2016 #[instability::unstable]
2018 pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
2019 self.rx.check_for_errors()
2020 }
2021
2022 #[instability::unstable]
2039 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
2040 self.rx.read_buffered(buf)
2041 }
2042
2043 #[instability::unstable]
2045 pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
2046 #[cfg(not(any(esp32, esp32s2)))]
2047 self.regs()
2048 .clk_conf()
2049 .modify(|_, w| w.sclk_en().clear_bit());
2050
2051 self.regs().at_cmd_char().write(|w| unsafe {
2052 w.at_cmd_char().bits(config.cmd_char);
2053 w.char_num().bits(config.char_num)
2054 });
2055
2056 if let Some(pre_idle_count) = config.pre_idle_count {
2057 self.regs()
2058 .at_cmd_precnt()
2059 .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
2060 }
2061
2062 if let Some(post_idle_count) = config.post_idle_count {
2063 self.regs()
2064 .at_cmd_postcnt()
2065 .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
2066 }
2067
2068 if let Some(gap_timeout) = config.gap_timeout {
2069 self.regs()
2070 .at_cmd_gaptout()
2071 .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
2072 }
2073
2074 #[cfg(not(any(esp32, esp32s2)))]
2075 self.regs().clk_conf().modify(|_, w| w.sclk_en().set_bit());
2076
2077 sync_regs(self.regs());
2078 }
2079
2080 #[inline(always)]
2081 fn init(&mut self, config: Config) -> Result<(), ConfigError> {
2082 self.rx.disable_rx_interrupts();
2083 self.tx.disable_tx_interrupts();
2084
2085 self.rx.uart.info().rxfifo_reset();
2087 self.rx.uart.info().txfifo_reset();
2088
2089 self.apply_config(&config)?;
2090
2091 self.regs()
2094 .idle_conf()
2095 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2096
2097 self.regs().conf0().modify(|_, w| w.err_wr_mask().set_bit());
2100
2101 crate::rom::ets_delay_us(15);
2102
2103 self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
2106
2107 Ok(())
2108 }
2109}
2110
2111impl crate::private::Sealed for Uart<'_, Blocking> {}
2112
2113#[instability::unstable]
2114impl crate::interrupt::InterruptConfigurable for Uart<'_, Blocking> {
2115 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
2116 self.tx.uart.set_interrupt_handler(handler);
2118 }
2119}
2120
2121#[instability::unstable]
2122impl<Dm> ufmt_write::uWrite for Uart<'_, Dm>
2123where
2124 Dm: DriverMode,
2125{
2126 type Error = TxError;
2127
2128 #[inline]
2129 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
2130 self.tx.write_str(s)
2131 }
2132
2133 #[inline]
2134 fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
2135 self.tx.write_char(ch)
2136 }
2137}
2138
2139#[instability::unstable]
2140impl<Dm> ufmt_write::uWrite for UartTx<'_, Dm>
2141where
2142 Dm: DriverMode,
2143{
2144 type Error = TxError;
2145
2146 #[inline]
2147 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
2148 self.write_all(s.as_bytes())
2149 }
2150}
2151
2152impl<Dm> core::fmt::Write for Uart<'_, Dm>
2153where
2154 Dm: DriverMode,
2155{
2156 #[inline]
2157 fn write_str(&mut self, s: &str) -> core::fmt::Result {
2158 self.tx.write_str(s)
2159 }
2160}
2161
2162impl<Dm> core::fmt::Write for UartTx<'_, Dm>
2163where
2164 Dm: DriverMode,
2165{
2166 #[inline]
2167 fn write_str(&mut self, s: &str) -> core::fmt::Result {
2168 self.write_all(s.as_bytes()).map_err(|_| core::fmt::Error)
2169 }
2170}
2171
2172#[instability::unstable]
2174#[derive(Debug, Clone, Copy, PartialEq)]
2175#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2176#[non_exhaustive]
2177pub enum IoError {
2178 Tx(TxError),
2180 Rx(RxError),
2182}
2183
2184#[instability::unstable]
2185impl core::error::Error for IoError {}
2186
2187#[instability::unstable]
2188impl core::fmt::Display for IoError {
2189 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2190 match self {
2191 IoError::Tx(e) => e.fmt(f),
2192 IoError::Rx(e) => e.fmt(f),
2193 }
2194 }
2195}
2196
2197#[instability::unstable]
2198impl embedded_io_06::Error for IoError {
2199 fn kind(&self) -> embedded_io_06::ErrorKind {
2200 embedded_io_06::ErrorKind::Other
2201 }
2202}
2203
2204#[instability::unstable]
2205impl embedded_io_07::Error for IoError {
2206 fn kind(&self) -> embedded_io_07::ErrorKind {
2207 embedded_io_07::ErrorKind::Other
2208 }
2209}
2210
2211#[instability::unstable]
2212impl From<RxError> for IoError {
2213 fn from(e: RxError) -> Self {
2214 IoError::Rx(e)
2215 }
2216}
2217
2218#[instability::unstable]
2219impl From<TxError> for IoError {
2220 fn from(e: TxError) -> Self {
2221 IoError::Tx(e)
2222 }
2223}
2224
2225#[instability::unstable]
2226impl<Dm: DriverMode> embedded_io_06::ErrorType for Uart<'_, Dm> {
2227 type Error = IoError;
2228}
2229
2230#[instability::unstable]
2231impl<Dm: DriverMode> embedded_io_06::ErrorType for UartTx<'_, Dm> {
2232 type Error = TxError;
2233}
2234
2235#[instability::unstable]
2236impl<Dm: DriverMode> embedded_io_06::ErrorType for UartRx<'_, Dm> {
2237 type Error = RxError;
2238}
2239
2240#[instability::unstable]
2241impl<Dm> embedded_io_06::Read for Uart<'_, Dm>
2242where
2243 Dm: DriverMode,
2244{
2245 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2246 self.rx.read(buf).map_err(IoError::Rx)
2247 }
2248}
2249
2250#[instability::unstable]
2251impl<Dm> embedded_io_06::Read for UartRx<'_, Dm>
2252where
2253 Dm: DriverMode,
2254{
2255 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2256 self.read(buf)
2257 }
2258}
2259
2260#[instability::unstable]
2261impl<Dm> embedded_io_06::ReadReady for Uart<'_, Dm>
2262where
2263 Dm: DriverMode,
2264{
2265 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2266 Ok(self.rx.read_ready())
2267 }
2268}
2269
2270#[instability::unstable]
2271impl<Dm> embedded_io_06::ReadReady for UartRx<'_, Dm>
2272where
2273 Dm: DriverMode,
2274{
2275 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2276 Ok(UartRx::read_ready(self))
2277 }
2278}
2279
2280#[instability::unstable]
2281impl<Dm> embedded_io_06::Write for Uart<'_, Dm>
2282where
2283 Dm: DriverMode,
2284{
2285 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2286 self.tx.write(buf).map_err(IoError::Tx)
2287 }
2288
2289 fn flush(&mut self) -> Result<(), Self::Error> {
2290 self.tx.flush().map_err(IoError::Tx)
2291 }
2292}
2293
2294#[instability::unstable]
2295impl<Dm> embedded_io_06::Write for UartTx<'_, Dm>
2296where
2297 Dm: DriverMode,
2298{
2299 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2300 self.write(buf)
2301 }
2302
2303 fn flush(&mut self) -> Result<(), Self::Error> {
2304 self.flush()
2305 }
2306}
2307
2308#[instability::unstable]
2309impl<Dm> embedded_io_06::WriteReady for UartTx<'_, Dm>
2310where
2311 Dm: DriverMode,
2312{
2313 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2314 Ok(UartTx::write_ready(self))
2315 }
2316}
2317
2318#[instability::unstable]
2319impl<Dm> embedded_io_06::WriteReady for Uart<'_, Dm>
2320where
2321 Dm: DriverMode,
2322{
2323 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2324 Ok(self.tx.write_ready())
2325 }
2326}
2327
2328#[instability::unstable]
2329impl<Dm: DriverMode> embedded_io_07::ErrorType for Uart<'_, Dm> {
2330 type Error = IoError;
2331}
2332
2333#[instability::unstable]
2334impl<Dm: DriverMode> embedded_io_07::ErrorType for UartTx<'_, Dm> {
2335 type Error = TxError;
2336}
2337
2338#[instability::unstable]
2339impl<Dm: DriverMode> embedded_io_07::ErrorType for UartRx<'_, Dm> {
2340 type Error = RxError;
2341}
2342
2343#[instability::unstable]
2344impl<Dm> embedded_io_07::Read for Uart<'_, Dm>
2345where
2346 Dm: DriverMode,
2347{
2348 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2349 self.rx.read(buf).map_err(IoError::Rx)
2350 }
2351}
2352
2353#[instability::unstable]
2354impl<Dm> embedded_io_07::Read for UartRx<'_, Dm>
2355where
2356 Dm: DriverMode,
2357{
2358 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2359 self.read(buf)
2360 }
2361}
2362
2363#[instability::unstable]
2364impl<Dm> embedded_io_07::ReadReady for Uart<'_, Dm>
2365where
2366 Dm: DriverMode,
2367{
2368 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2369 Ok(self.rx.read_ready())
2370 }
2371}
2372
2373#[instability::unstable]
2374impl<Dm> embedded_io_07::ReadReady for UartRx<'_, Dm>
2375where
2376 Dm: DriverMode,
2377{
2378 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2379 Ok(UartRx::read_ready(self))
2380 }
2381}
2382
2383#[instability::unstable]
2384impl<Dm> embedded_io_07::Write for Uart<'_, Dm>
2385where
2386 Dm: DriverMode,
2387{
2388 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2389 self.tx.write(buf).map_err(IoError::Tx)
2390 }
2391
2392 fn flush(&mut self) -> Result<(), Self::Error> {
2393 self.tx.flush().map_err(IoError::Tx)
2394 }
2395}
2396
2397#[instability::unstable]
2398impl<Dm> embedded_io_07::Write for UartTx<'_, Dm>
2399where
2400 Dm: DriverMode,
2401{
2402 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2403 self.write(buf)
2404 }
2405
2406 fn flush(&mut self) -> Result<(), Self::Error> {
2407 self.flush()
2408 }
2409}
2410
2411#[instability::unstable]
2412impl<Dm> embedded_io_07::WriteReady for UartTx<'_, Dm>
2413where
2414 Dm: DriverMode,
2415{
2416 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2417 Ok(UartTx::write_ready(self))
2418 }
2419}
2420
2421#[instability::unstable]
2422impl<Dm> embedded_io_07::WriteReady for Uart<'_, Dm>
2423where
2424 Dm: DriverMode,
2425{
2426 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2427 Ok(self.tx.write_ready())
2428 }
2429}
2430
2431#[derive(Debug, EnumSetType)]
2432pub(crate) enum TxEvent {
2433 Done,
2434 FiFoEmpty,
2435}
2436
2437#[derive(Debug, EnumSetType)]
2438pub(crate) enum RxEvent {
2439 FifoFull,
2440 CmdCharDetected,
2441 FifoOvf,
2442 FifoTout,
2443 GlitchDetected,
2444 FrameError,
2445 ParityError,
2446 BreakDetected,
2447}
2448
2449fn rx_event_check_for_error(events: EnumSet<RxEvent>) -> Result<(), RxError> {
2450 for event in events {
2451 match event {
2452 RxEvent::FifoOvf => return Err(RxError::FifoOverflowed),
2453 RxEvent::GlitchDetected => return Err(RxError::GlitchOccurred),
2454 RxEvent::FrameError => return Err(RxError::FrameFormatViolated),
2455 RxEvent::ParityError => return Err(RxError::ParityMismatch),
2456 RxEvent::FifoFull
2457 | RxEvent::CmdCharDetected
2458 | RxEvent::FifoTout
2459 | RxEvent::BreakDetected => continue,
2460 }
2461 }
2462
2463 Ok(())
2464}
2465
2466#[must_use = "futures do nothing unless you `.await` or poll them"]
2472struct UartRxFuture {
2473 events: EnumSet<RxEvent>,
2474 uart: &'static Info,
2475 state: &'static State,
2476 registered: bool,
2477}
2478
2479impl UartRxFuture {
2480 fn new(uart: impl Instance, events: impl Into<EnumSet<RxEvent>>) -> Self {
2481 Self {
2482 events: events.into(),
2483 uart: uart.info(),
2484 state: uart.state(),
2485 registered: false,
2486 }
2487 }
2488}
2489
2490impl core::future::Future for UartRxFuture {
2491 type Output = EnumSet<RxEvent>;
2492
2493 fn poll(
2494 mut self: core::pin::Pin<&mut Self>,
2495 cx: &mut core::task::Context<'_>,
2496 ) -> core::task::Poll<Self::Output> {
2497 let events = self.uart.rx_events().intersection(self.events);
2498 if !events.is_empty() {
2499 self.uart.clear_rx_events(events);
2500 Poll::Ready(events)
2501 } else {
2502 self.state.rx_waker.register(cx.waker());
2503 if !self.registered {
2504 self.uart.enable_listen_rx(self.events, true);
2505 self.registered = true;
2506 }
2507 Poll::Pending
2508 }
2509 }
2510}
2511
2512impl Drop for UartRxFuture {
2513 fn drop(&mut self) {
2514 self.uart.enable_listen_rx(self.events, false);
2518 }
2519}
2520
2521#[must_use = "futures do nothing unless you `.await` or poll them"]
2522struct UartTxFuture {
2523 events: EnumSet<TxEvent>,
2524 uart: &'static Info,
2525 state: &'static State,
2526 registered: bool,
2527}
2528
2529impl UartTxFuture {
2530 fn new(uart: impl Instance, events: impl Into<EnumSet<TxEvent>>) -> Self {
2531 Self {
2532 events: events.into(),
2533 uart: uart.info(),
2534 state: uart.state(),
2535 registered: false,
2536 }
2537 }
2538}
2539
2540impl core::future::Future for UartTxFuture {
2541 type Output = ();
2542
2543 fn poll(
2544 mut self: core::pin::Pin<&mut Self>,
2545 cx: &mut core::task::Context<'_>,
2546 ) -> core::task::Poll<Self::Output> {
2547 let events = self.uart.tx_events().intersection(self.events);
2548 if !events.is_empty() {
2549 self.uart.clear_tx_events(events);
2550 Poll::Ready(())
2551 } else {
2552 self.state.tx_waker.register(cx.waker());
2553 if !self.registered {
2554 self.uart.enable_listen_tx(self.events, true);
2555 self.registered = true;
2556 }
2557 Poll::Pending
2558 }
2559 }
2560}
2561
2562impl Drop for UartTxFuture {
2563 fn drop(&mut self) {
2564 self.uart.enable_listen_tx(self.events, false);
2568 }
2569}
2570
2571#[instability::unstable]
2572impl embedded_io_async_06::Read for Uart<'_, Async> {
2573 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2574 self.read_async(buf).await.map_err(IoError::Rx)
2575 }
2576
2577 async fn read_exact(
2578 &mut self,
2579 buf: &mut [u8],
2580 ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2581 self.read_exact_async(buf)
2582 .await
2583 .map_err(|e| embedded_io_06::ReadExactError::Other(IoError::Rx(e)))
2584 }
2585}
2586
2587#[instability::unstable]
2588impl embedded_io_async_06::Read for UartRx<'_, Async> {
2589 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2590 self.read_async(buf).await
2591 }
2592
2593 async fn read_exact(
2594 &mut self,
2595 buf: &mut [u8],
2596 ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2597 self.read_exact_async(buf)
2598 .await
2599 .map_err(embedded_io_06::ReadExactError::Other)
2600 }
2601}
2602
2603#[instability::unstable]
2604impl embedded_io_async_06::Write for Uart<'_, Async> {
2605 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2606 self.write_async(buf).await.map_err(IoError::Tx)
2607 }
2608
2609 async fn flush(&mut self) -> Result<(), Self::Error> {
2610 self.flush_async().await.map_err(IoError::Tx)
2611 }
2612}
2613
2614#[instability::unstable]
2615impl embedded_io_async_06::Write for UartTx<'_, Async> {
2616 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2617 self.write_async(buf).await
2618 }
2619
2620 async fn flush(&mut self) -> Result<(), Self::Error> {
2621 self.flush_async().await
2622 }
2623}
2624
2625#[instability::unstable]
2626impl embedded_io_async_07::Read for Uart<'_, Async> {
2627 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2628 self.read_async(buf).await.map_err(IoError::Rx)
2629 }
2630
2631 async fn read_exact(
2632 &mut self,
2633 buf: &mut [u8],
2634 ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2635 self.read_exact_async(buf)
2636 .await
2637 .map_err(|e| embedded_io_07::ReadExactError::Other(IoError::Rx(e)))
2638 }
2639}
2640
2641#[instability::unstable]
2642impl embedded_io_async_07::Read for UartRx<'_, Async> {
2643 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2644 self.read_async(buf).await
2645 }
2646
2647 async fn read_exact(
2648 &mut self,
2649 buf: &mut [u8],
2650 ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2651 self.read_exact_async(buf)
2652 .await
2653 .map_err(embedded_io_07::ReadExactError::Other)
2654 }
2655}
2656
2657#[instability::unstable]
2658impl embedded_io_async_07::Write for Uart<'_, Async> {
2659 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2660 self.write_async(buf).await.map_err(IoError::Tx)
2661 }
2662
2663 async fn flush(&mut self) -> Result<(), Self::Error> {
2664 self.flush_async().await.map_err(IoError::Tx)
2665 }
2666}
2667
2668#[instability::unstable]
2669impl embedded_io_async_07::Write for UartTx<'_, Async> {
2670 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2671 self.write_async(buf).await
2672 }
2673
2674 async fn flush(&mut self) -> Result<(), Self::Error> {
2675 self.flush_async().await
2676 }
2677}
2678
2679#[ram]
2684pub(super) fn intr_handler(uart: &Info, state: &State) {
2685 let interrupts = uart.regs().int_st().read();
2686 let interrupt_bits = interrupts.bits(); let rx_wake = interrupts.rxfifo_full().bit_is_set()
2688 | interrupts.rxfifo_ovf().bit_is_set()
2689 | interrupts.rxfifo_tout().bit_is_set()
2690 | interrupts.at_cmd_char_det().bit_is_set()
2691 | interrupts.glitch_det().bit_is_set()
2692 | interrupts.frm_err().bit_is_set()
2693 | interrupts.parity_err().bit_is_set()
2694 | interrupts.brk_det().bit_is_set();
2695 let tx_wake = interrupts.tx_done().bit_is_set() | interrupts.txfifo_empty().bit_is_set();
2696
2697 uart.regs()
2698 .int_ena()
2699 .modify(|r, w| unsafe { w.bits(r.bits() & !interrupt_bits) });
2700
2701 if tx_wake {
2702 state.tx_waker.wake();
2703 }
2704 if rx_wake {
2705 state.rx_waker.wake();
2706 }
2707}
2708
2709#[cfg(lp_uart_driver_supported)]
2711#[instability::unstable]
2712pub mod lp_uart {
2713 use crate::{
2714 gpio::lp_io::{LowPowerInput, LowPowerOutput},
2715 peripherals::{LP_AON, LP_CLKRST, LP_IO, LP_UART, LPWR},
2716 soc::clocks::ClockTree,
2717 uart::{DataBits, Parity, StopBits},
2718 };
2719
2720 #[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
2722 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
2723 #[non_exhaustive]
2724 pub struct Config {
2725 baudrate: u32,
2728 data_bits: DataBits,
2730 parity: Parity,
2732 stop_bits: StopBits,
2734 #[builder_lite(unstable)]
2736 clock_source: ClockSource,
2737 }
2738
2739 impl Default for Config {
2740 fn default() -> Config {
2741 Config {
2742 baudrate: 115_200,
2743 data_bits: Default::default(),
2744 parity: Default::default(),
2745 stop_bits: Default::default(),
2746 clock_source: Default::default(),
2747 }
2748 }
2749 }
2750
2751 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
2753 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
2754 #[non_exhaustive]
2755 #[instability::unstable]
2756 pub enum ClockSource {
2757 RcFast,
2759
2760 #[default]
2762 Xtal,
2763 }
2764
2765 pub struct LpUart {
2767 uart: LP_UART<'static>,
2768 }
2769
2770 impl LpUart {
2771 pub fn new(
2774 uart: LP_UART<'static>,
2775 config: Config,
2776 _tx: LowPowerOutput<'_, 5>,
2777 _rx: LowPowerInput<'_, 4>,
2778 ) -> Self {
2779 LP_AON::regs()
2781 .gpio_mux()
2782 .modify(|r, w| unsafe { w.sel().bits(r.sel().bits() | (1 << 4) | (1 << 5)) });
2783
2784 LP_IO::regs()
2785 .gpio(4)
2786 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2787 LP_IO::regs()
2788 .gpio(5)
2789 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2790
2791 let mut me = Self { uart };
2792 let uart = me.uart.register_block();
2793
2794 uart.conf0().modify(|_, w| unsafe {
2800 w.parity().clear_bit();
2801 w.parity_en().clear_bit();
2802 w.bit_num().bits(0x3);
2803 w.stop_bit_num().bits(0x1)
2804 });
2805 uart.idle_conf()
2807 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2808 uart.hwfc_conf().modify(|_, w| w.rx_flow_en().clear_bit());
2810
2811 LPWR::regs()
2816 .lpperi()
2817 .modify(|_, w| w.lp_uart_clk_sel().clear_bit());
2818
2819 me.change_baud_internal(&config);
2822 me.change_parity(config.parity);
2824 me.change_data_bits(config.data_bits);
2826 me.change_stop_bits(config.stop_bits);
2828 me.change_tx_idle(0); me.rxfifo_reset();
2833 me.txfifo_reset();
2834
2835 me
2836 }
2837
2838 fn rxfifo_reset(&mut self) {
2839 self.uart
2840 .register_block()
2841 .conf0()
2842 .modify(|_, w| w.rxfifo_rst().set_bit());
2843 self.update();
2844
2845 self.uart
2846 .register_block()
2847 .conf0()
2848 .modify(|_, w| w.rxfifo_rst().clear_bit());
2849 self.update();
2850 }
2851
2852 fn txfifo_reset(&mut self) {
2853 self.uart
2854 .register_block()
2855 .conf0()
2856 .modify(|_, w| w.txfifo_rst().set_bit());
2857 self.update();
2858
2859 self.uart
2860 .register_block()
2861 .conf0()
2862 .modify(|_, w| w.txfifo_rst().clear_bit());
2863 self.update();
2864 }
2865
2866 fn update(&mut self) {
2867 let register_block = self.uart.register_block();
2868 register_block
2869 .reg_update()
2870 .modify(|_, w| w.reg_update().set_bit());
2871 while register_block.reg_update().read().reg_update().bit_is_set() {
2872 }
2874 }
2875
2876 fn change_baud_internal(&mut self, config: &Config) {
2877 let clk = ClockTree::with(|clocks| match config.clock_source {
2878 ClockSource::RcFast => crate::soc::clocks::rc_fast_clk_frequency(clocks),
2879 ClockSource::Xtal => crate::soc::clocks::xtal_d2_clk_frequency(clocks),
2880 });
2881
2882 LP_CLKRST::regs().lpperi().modify(|_, w| {
2883 w.lp_uart_clk_sel().bit(match config.clock_source {
2884 ClockSource::RcFast => false,
2885 ClockSource::Xtal => true,
2886 })
2887 });
2888 self.uart.register_block().clk_conf().modify(|_, w| {
2889 w.rx_sclk_en().set_bit();
2890 w.tx_sclk_en().set_bit()
2891 });
2892
2893 let divider = clk / config.baudrate;
2894 let divider = divider as u16;
2895
2896 self.uart
2897 .register_block()
2898 .clkdiv()
2899 .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) });
2900
2901 self.update();
2902 }
2903
2904 pub fn change_baud(&mut self, config: &Config) {
2906 self.change_baud_internal(config);
2907 self.txfifo_reset();
2908 self.rxfifo_reset();
2909 }
2910
2911 fn change_parity(&mut self, parity: Parity) -> &mut Self {
2912 if parity != Parity::None {
2913 self.uart
2914 .register_block()
2915 .conf0()
2916 .modify(|_, w| w.parity().bit((parity as u8 & 0x1) != 0));
2917 }
2918
2919 self.uart
2920 .register_block()
2921 .conf0()
2922 .modify(|_, w| match parity {
2923 Parity::None => w.parity_en().clear_bit(),
2924 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2925 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2926 });
2927
2928 self
2929 }
2930
2931 fn change_data_bits(&mut self, data_bits: DataBits) -> &mut Self {
2932 self.uart
2933 .register_block()
2934 .conf0()
2935 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2936
2937 self.update();
2938 self
2939 }
2940
2941 fn change_stop_bits(&mut self, stop_bits: StopBits) -> &mut Self {
2942 self.uart
2943 .register_block()
2944 .conf0()
2945 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2946
2947 self.update();
2948 self
2949 }
2950
2951 fn change_tx_idle(&mut self, idle_num: u16) -> &mut Self {
2952 self.uart
2953 .register_block()
2954 .idle_conf()
2955 .modify(|_, w| unsafe { w.tx_idle_num().bits(idle_num) });
2956
2957 self.update();
2958 self
2959 }
2960 }
2961}
2962
2963pub trait Instance: crate::private::Sealed + any::Degrade {
2965 #[doc(hidden)]
2966 fn parts(&self) -> (&'static Info, &'static State);
2968
2969 #[inline(always)]
2971 #[doc(hidden)]
2972 fn info(&self) -> &'static Info {
2973 self.parts().0
2974 }
2975
2976 #[inline(always)]
2978 #[doc(hidden)]
2979 fn state(&self) -> &'static State {
2980 self.parts().1
2981 }
2982}
2983
2984#[doc(hidden)]
2986#[non_exhaustive]
2987#[allow(private_interfaces, reason = "Unstable details")]
2988pub struct Info {
2989 pub register_block: *const RegisterBlock,
2993
2994 pub peripheral: crate::system::Peripheral,
2996
2997 pub clock_instance: clocks::UartInstance,
2999
3000 pub async_handler: InterruptHandler,
3002
3003 pub tx_signal: OutputSignal,
3005
3006 pub rx_signal: InputSignal,
3008
3009 pub cts_signal: InputSignal,
3011
3012 pub rts_signal: OutputSignal,
3014}
3015
3016#[doc(hidden)]
3018#[non_exhaustive]
3019pub struct State {
3020 pub rx_waker: AtomicWaker,
3022
3023 pub tx_waker: AtomicWaker,
3025
3026 pub is_rx_async: AtomicBool,
3028
3029 pub is_tx_async: AtomicBool,
3031}
3032
3033impl Info {
3034 const UART_FIFO_SIZE: u16 = property!("uart.ram_size");
3037 const RX_FIFO_MAX_THRHD: u16 = Self::UART_FIFO_SIZE - 1;
3038 const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
3039
3040 pub fn regs(&self) -> &RegisterBlock {
3042 unsafe { &*self.register_block }
3043 }
3044
3045 fn enable_listen(&self, interrupts: EnumSet<UartInterrupt>, enable: bool) {
3047 let reg_block = self.regs();
3048
3049 reg_block.int_ena().modify(|_, w| {
3050 for interrupt in interrupts {
3051 match interrupt {
3052 UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable),
3053 UartInterrupt::TxDone => w.tx_done().bit(enable),
3054 UartInterrupt::RxBreakDetected => w.brk_det().bit(enable),
3055 UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable),
3056 UartInterrupt::RxTimeout => w.rxfifo_tout().bit(enable),
3057 };
3058 }
3059 w
3060 });
3061 }
3062
3063 fn interrupts(&self) -> EnumSet<UartInterrupt> {
3064 let mut res = EnumSet::new();
3065 let reg_block = self.regs();
3066
3067 let ints = reg_block.int_raw().read();
3068
3069 if ints.at_cmd_char_det().bit_is_set() {
3070 res.insert(UartInterrupt::AtCmd);
3071 }
3072 if ints.tx_done().bit_is_set() {
3073 res.insert(UartInterrupt::TxDone);
3074 }
3075 if ints.brk_det().bit_is_set() {
3076 res.insert(UartInterrupt::RxBreakDetected);
3077 }
3078 if ints.rxfifo_full().bit_is_set() {
3079 res.insert(UartInterrupt::RxFifoFull);
3080 }
3081 if ints.rxfifo_tout().bit_is_set() {
3082 res.insert(UartInterrupt::RxTimeout);
3083 }
3084
3085 res
3086 }
3087
3088 fn clear_interrupts(&self, interrupts: EnumSet<UartInterrupt>) {
3089 let reg_block = self.regs();
3090
3091 reg_block.int_clr().write(|w| {
3092 for interrupt in interrupts {
3093 match interrupt {
3094 UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(),
3095 UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
3096 UartInterrupt::RxBreakDetected => w.brk_det().clear_bit_by_one(),
3097 UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(),
3098 UartInterrupt::RxTimeout => w.rxfifo_tout().clear_bit_by_one(),
3099 };
3100 }
3101 w
3102 });
3103 }
3104
3105 fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
3106 config.validate()?;
3107 self.change_baud(config)?;
3108 self.change_data_bits(config.data_bits);
3109 self.change_parity(config.parity);
3110 self.change_stop_bits(config.stop_bits);
3111 self.change_flow_control(config.sw_flow_ctrl, config.hw_flow_ctrl);
3112
3113 self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
3115
3116 Ok(())
3117 }
3118
3119 fn enable_listen_tx(&self, events: EnumSet<TxEvent>, enable: bool) {
3120 self.regs().int_ena().modify(|_, w| {
3121 for event in events {
3122 match event {
3123 TxEvent::Done => w.tx_done().bit(enable),
3124 TxEvent::FiFoEmpty => w.txfifo_empty().bit(enable),
3125 };
3126 }
3127 w
3128 });
3129 }
3130
3131 fn tx_events(&self) -> EnumSet<TxEvent> {
3132 let pending_interrupts = self.regs().int_raw().read();
3133 let mut active_events = EnumSet::new();
3134
3135 if pending_interrupts.tx_done().bit_is_set() {
3136 active_events |= TxEvent::Done;
3137 }
3138 if pending_interrupts.txfifo_empty().bit_is_set() {
3139 active_events |= TxEvent::FiFoEmpty;
3140 }
3141
3142 active_events
3143 }
3144
3145 fn clear_tx_events(&self, events: impl Into<EnumSet<TxEvent>>) {
3146 let events = events.into();
3147 self.regs().int_clr().write(|w| {
3148 for event in events {
3149 match event {
3150 TxEvent::FiFoEmpty => w.txfifo_empty().clear_bit_by_one(),
3151 TxEvent::Done => w.tx_done().clear_bit_by_one(),
3152 };
3153 }
3154 w
3155 });
3156 }
3157
3158 fn enable_listen_rx(&self, events: EnumSet<RxEvent>, enable: bool) {
3159 self.regs().int_ena().modify(|_, w| {
3160 for event in events {
3161 match event {
3162 RxEvent::FifoFull => w.rxfifo_full().bit(enable),
3163 RxEvent::BreakDetected => w.brk_det().bit(enable),
3164 RxEvent::CmdCharDetected => w.at_cmd_char_det().bit(enable),
3165
3166 RxEvent::FifoOvf => w.rxfifo_ovf().bit(enable),
3167 RxEvent::FifoTout => w.rxfifo_tout().bit(enable),
3168 RxEvent::GlitchDetected => w.glitch_det().bit(enable),
3169 RxEvent::FrameError => w.frm_err().bit(enable),
3170 RxEvent::ParityError => w.parity_err().bit(enable),
3171 };
3172 }
3173 w
3174 });
3175 }
3176
3177 fn rx_events(&self) -> EnumSet<RxEvent> {
3178 let pending_interrupts = self.regs().int_raw().read();
3179 let mut active_events = EnumSet::new();
3180
3181 if pending_interrupts.rxfifo_full().bit_is_set() {
3182 active_events |= RxEvent::FifoFull;
3183 }
3184 if pending_interrupts.brk_det().bit_is_set() {
3185 active_events |= RxEvent::BreakDetected;
3186 }
3187 if pending_interrupts.at_cmd_char_det().bit_is_set() {
3188 active_events |= RxEvent::CmdCharDetected;
3189 }
3190 if pending_interrupts.rxfifo_ovf().bit_is_set() {
3191 active_events |= RxEvent::FifoOvf;
3192 }
3193 if pending_interrupts.rxfifo_tout().bit_is_set() {
3194 active_events |= RxEvent::FifoTout;
3195 }
3196 if pending_interrupts.glitch_det().bit_is_set() {
3197 active_events |= RxEvent::GlitchDetected;
3198 }
3199 if pending_interrupts.frm_err().bit_is_set() {
3200 active_events |= RxEvent::FrameError;
3201 }
3202 if pending_interrupts.parity_err().bit_is_set() {
3203 active_events |= RxEvent::ParityError;
3204 }
3205
3206 active_events
3207 }
3208
3209 fn clear_rx_events(&self, events: impl Into<EnumSet<RxEvent>>) {
3210 let events = events.into();
3211 self.regs().int_clr().write(|w| {
3212 for event in events {
3213 match event {
3214 RxEvent::FifoFull => w.rxfifo_full().clear_bit_by_one(),
3215 RxEvent::BreakDetected => w.brk_det().clear_bit_by_one(),
3216 RxEvent::CmdCharDetected => w.at_cmd_char_det().clear_bit_by_one(),
3217
3218 RxEvent::FifoOvf => w.rxfifo_ovf().clear_bit_by_one(),
3219 RxEvent::FifoTout => w.rxfifo_tout().clear_bit_by_one(),
3220 RxEvent::GlitchDetected => w.glitch_det().clear_bit_by_one(),
3221 RxEvent::FrameError => w.frm_err().clear_bit_by_one(),
3222 RxEvent::ParityError => w.parity_err().clear_bit_by_one(),
3223 };
3224 }
3225 w
3226 });
3227 }
3228
3229 fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3236 if threshold == 0 || threshold > Self::RX_FIFO_MAX_THRHD {
3237 return Err(ConfigError::RxFifoThresholdNotSupported);
3238 }
3239
3240 self.regs()
3241 .conf1()
3242 .modify(|_, w| unsafe { w.rxfifo_full_thrhd().bits(threshold as _) });
3243
3244 Ok(())
3245 }
3246
3247 #[allow(clippy::useless_conversion)]
3249 fn rx_fifo_full_threshold(&self) -> u16 {
3250 self.regs().conf1().read().rxfifo_full_thrhd().bits().into()
3251 }
3252
3253 fn set_tx_fifo_empty_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3260 if threshold > Self::TX_FIFO_MAX_THRHD {
3261 return Err(ConfigError::TxFifoThresholdNotSupported);
3262 }
3263
3264 self.regs()
3265 .conf1()
3266 .modify(|_, w| unsafe { w.txfifo_empty_thrhd().bits(threshold as _) });
3267
3268 Ok(())
3269 }
3270
3271 fn set_rx_timeout(&self, timeout: Option<u8>, _symbol_len: u8) -> Result<(), ConfigError> {
3286 cfg_if::cfg_if! {
3287 if #[cfg(esp32)] {
3288 const MAX_THRHD: u8 = 0x7F; } else {
3290 const MAX_THRHD: u16 = 0x3FF; }
3292 }
3293
3294 let register_block = self.regs();
3295
3296 if let Some(timeout) = timeout {
3297 #[cfg(esp32)]
3299 let timeout_reg = timeout;
3300 #[cfg(not(esp32))]
3302 let timeout_reg = timeout as u16 * _symbol_len as u16;
3303
3304 if timeout_reg > MAX_THRHD {
3305 return Err(ConfigError::TimeoutTooLong);
3306 }
3307
3308 cfg_if::cfg_if! {
3309 if #[cfg(esp32)] {
3310 let reg_thrhd = register_block.conf1();
3311 } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3312 let reg_thrhd = register_block.tout_conf();
3313 } else {
3314 let reg_thrhd = register_block.mem_conf();
3315 }
3316 }
3317 reg_thrhd.modify(|_, w| unsafe { w.rx_tout_thrhd().bits(timeout_reg) });
3318 }
3319
3320 cfg_if::cfg_if! {
3321 if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3322 let reg_en = register_block.tout_conf();
3323 } else {
3324 let reg_en = register_block.conf1();
3325 }
3326 }
3327 reg_en.modify(|_, w| w.rx_tout_en().bit(timeout.is_some()));
3328
3329 self.sync_regs();
3330
3331 Ok(())
3332 }
3333
3334 fn sync_regs(&self) {
3335 sync_regs(self.regs());
3336 }
3337
3338 fn change_baud(&self, config: &Config) -> Result<(), ConfigError> {
3339 ClockTree::with(|clocks| {
3340 let clock = self.clock_instance;
3341
3342 let source_config = ClockConfig::new(
3343 config.clock_source,
3344 #[cfg(any(uart_has_sclk_divider, soc_has_pcr))]
3345 0,
3346 );
3347 let clk = clock.function_clock_config_frequency(clocks, source_config);
3348
3349 const FRAC_BITS: u32 = const {
3352 let largest_divider: u32 =
3353 property!("clock_tree.uart.baud_rate_generator.fractional").1;
3354 ::core::assert!((largest_divider + 1).is_power_of_two());
3355 largest_divider.count_ones()
3356 };
3357 const FRAC_MASK: u32 = (1 << FRAC_BITS) - 1;
3358
3359 cfg_if::cfg_if! {
3362 if #[cfg(any(uart_has_sclk_divider, soc_has_pcr))] {
3363 const MAX_DIV: u32 = property!("clock_tree.uart.baud_rate_generator.integral").1;
3364 let clk_div = clk.div_ceil(MAX_DIV).div_ceil(config.baudrate);
3365 debug!("SCLK: {} divider: {}", clk, clk_div);
3366
3367 let conf = ClockConfig::new(config.clock_source, clk_div - 1);
3368 let divider = (clk << FRAC_BITS) / (config.baudrate * clk_div);
3369 } else {
3370 debug!("SCLK: {}", clk);
3371 let conf = ClockConfig::new(config.clock_source);
3372 let divider = (clk << FRAC_BITS) / config.baudrate;
3373 }
3374 }
3375
3376 let divider_integer = divider >> FRAC_BITS;
3377 let divider_frag = divider & FRAC_MASK;
3378 debug!(
3379 "UART CLK divider: {} + {}/16",
3380 divider_integer, divider_frag
3381 );
3382
3383 clock.configure_function_clock(clocks, conf);
3384 clock.configure_baud_rate_generator(
3385 clocks,
3386 BaudRateConfig::new(divider_frag, divider_integer),
3387 );
3388
3389 self.sync_regs();
3390
3391 #[cfg(feature = "unstable")]
3392 {
3393 let deviation_limit = match config.baudrate_tolerance {
3394 BaudrateTolerance::Exact => 1, BaudrateTolerance::ErrorPercent(percent) => percent as u32,
3396 _ => return Ok(()),
3397 };
3398
3399 let actual_baud = clock.baud_rate_generator_frequency(clocks);
3400 if actual_baud == 0 {
3401 return Err(ConfigError::BaudrateNotAchievable);
3402 }
3403
3404 let deviation = (config.baudrate.abs_diff(actual_baud) * 100) / actual_baud;
3405 debug!(
3406 "Nominal baud: {}, actual: {}, deviation: {}%",
3407 config.baudrate, actual_baud, deviation
3408 );
3409
3410 if deviation > deviation_limit {
3411 return Err(ConfigError::BaudrateNotAchievable);
3412 }
3413 }
3414
3415 Ok(())
3416 })
3417 }
3418
3419 fn change_data_bits(&self, data_bits: DataBits) {
3420 self.regs()
3421 .conf0()
3422 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
3423 }
3424
3425 fn change_parity(&self, parity: Parity) {
3426 self.regs().conf0().modify(|_, w| match parity {
3427 Parity::None => w.parity_en().clear_bit(),
3428 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
3429 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
3430 });
3431 }
3432
3433 fn change_stop_bits(&self, stop_bits: StopBits) {
3434 #[cfg(esp32)]
3435 {
3436 if stop_bits == StopBits::_2 {
3438 self.regs()
3439 .rs485_conf()
3440 .modify(|_, w| w.dl1_en().bit(stop_bits == StopBits::_2));
3441
3442 self.regs()
3443 .conf0()
3444 .modify(|_, w| unsafe { w.stop_bit_num().bits(1) });
3445 }
3446 }
3447
3448 #[cfg(not(esp32))]
3449 self.regs()
3450 .conf0()
3451 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
3452 }
3453
3454 fn change_flow_control(&self, sw_flow_ctrl: SwFlowControl, hw_flow_ctrl: HwFlowControl) {
3455 match sw_flow_ctrl {
3457 SwFlowControl::Enabled {
3458 xon_char,
3459 xoff_char,
3460 xon_threshold,
3461 xoff_threshold,
3462 } => {
3463 cfg_if::cfg_if! {
3464 if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3465 self.regs().swfc_conf0().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3466 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold)});
3467 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3468 } else if #[cfg(esp32)]{
3469 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3470 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold) });
3471 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3472 } else {
3473 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3474 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold as u16) });
3475 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_threshold().bits(xoff_threshold as u16) });
3476 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_char().bits(xon_char) });
3477 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_char().bits(xoff_char) });
3478 }
3479 }
3480 }
3481 SwFlowControl::Disabled => {
3482 cfg_if::cfg_if! {
3483 if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3484 let reg = self.regs().swfc_conf0();
3485 } else {
3486 let reg = self.regs().flow_conf();
3487 }
3488 }
3489
3490 reg.modify(|_, w| w.sw_flow_con_en().clear_bit());
3491 reg.modify(|_, w| w.xonoff_del().clear_bit());
3492 }
3493 }
3494
3495 self.regs().conf0().modify(|_, w| {
3496 w.tx_flow_en()
3497 .bit(matches!(hw_flow_ctrl.cts, CtsConfig::Enabled))
3498 });
3499
3500 match hw_flow_ctrl.rts {
3501 RtsConfig::Enabled(threshold) => self.configure_rts_flow_ctrl(true, Some(threshold)),
3502 RtsConfig::Disabled => self.configure_rts_flow_ctrl(false, None),
3503 }
3504
3505 sync_regs(self.regs());
3506 }
3507
3508 fn configure_rts_flow_ctrl(&self, enable: bool, threshold: Option<u8>) {
3509 if let Some(threshold) = threshold {
3510 cfg_if::cfg_if! {
3511 if #[cfg(esp32)] {
3512 self.regs().conf1().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3513 } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3514 self.regs().hwfc_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3515 } else {
3516 self.regs().mem_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold as u16) });
3517 }
3518 }
3519 }
3520
3521 cfg_if::cfg_if! {
3522 if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3523 self.regs().hwfc_conf().modify(|_, w| {
3524 w.rx_flow_en().bit(enable)
3525 });
3526 } else {
3527 self.regs().conf1().modify(|_, w| {
3528 w.rx_flow_en().bit(enable)
3529 });
3530 }
3531 }
3532 }
3533
3534 fn rxfifo_reset(&self) {
3535 fn rxfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3536 reg_block.conf0().modify(|_, w| w.rxfifo_rst().bit(enable));
3537 sync_regs(reg_block);
3538 }
3539
3540 rxfifo_rst(self.regs(), true);
3541 rxfifo_rst(self.regs(), false);
3542 }
3543
3544 fn txfifo_reset(&self) {
3545 fn txfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3546 reg_block.conf0().modify(|_, w| w.txfifo_rst().bit(enable));
3547 sync_regs(reg_block);
3548 }
3549
3550 txfifo_rst(self.regs(), true);
3551 txfifo_rst(self.regs(), false);
3552 }
3553
3554 fn current_symbol_length(&self) -> u8 {
3555 let conf0 = self.regs().conf0().read();
3556 let data_bits = conf0.bit_num().bits() + 5; let parity = conf0.parity_en().bit() as u8;
3558 let mut stop_bits = conf0.stop_bit_num().bits();
3559
3560 match stop_bits {
3561 1 => {
3562 #[cfg(esp32)]
3564 if self.regs().rs485_conf().read().dl1_en().bit_is_set() {
3565 stop_bits = 2;
3566 }
3567 }
3568 _ => stop_bits = 2,
3570 }
3571
3572 1 + data_bits + parity + stop_bits
3573 }
3574
3575 fn read_next_from_fifo(&self) -> u8 {
3579 fn access_fifo_register<R>(f: impl Fn() -> R) -> R {
3580 cfg_if::cfg_if! {
3582 if #[cfg(esp32)] {
3583 crate::interrupt::free(f)
3584 } else {
3585 f()
3586 }
3587 }
3588 }
3589
3590 let fifo_reg = self.regs().fifo();
3591 cfg_if::cfg_if! {
3592 if #[cfg(esp32s2)] {
3593 let fifo_reg = unsafe {
3595 &*fifo_reg.as_ptr().cast::<u8>().add(0x20C00000).cast::<crate::pac::uart0::FIFO>()
3596 };
3597 }
3598 }
3599
3600 access_fifo_register(|| fifo_reg.read().rxfifo_rd_byte().bits())
3601 }
3602
3603 #[allow(clippy::useless_conversion)]
3604 fn tx_fifo_count(&self) -> u16 {
3605 u16::from(self.regs().status().read().txfifo_cnt().bits())
3606 }
3607
3608 fn write_byte(&self, byte: u8) {
3609 self.regs()
3610 .fifo()
3611 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
3612 }
3613
3614 fn check_for_errors(&self) -> Result<(), RxError> {
3615 let errors = RxEvent::FifoOvf
3616 | RxEvent::FifoTout
3617 | RxEvent::GlitchDetected
3618 | RxEvent::FrameError
3619 | RxEvent::ParityError;
3620 let events = self.rx_events().intersection(errors);
3621 let result = rx_event_check_for_error(events);
3622 if result.is_err() {
3623 self.clear_rx_events(errors);
3624 if events.contains(RxEvent::FifoOvf) {
3625 self.rxfifo_reset();
3626 }
3627 }
3628 result
3629 }
3630
3631 #[cfg(not(esp32))]
3632 #[allow(clippy::unnecessary_cast)]
3633 fn rx_fifo_count(&self) -> u16 {
3634 self.regs().status().read().rxfifo_cnt().bits() as u16
3635 }
3636
3637 #[cfg(esp32)]
3638 fn rx_fifo_count(&self) -> u16 {
3639 let fifo_cnt = self.regs().status().read().rxfifo_cnt().bits();
3640
3641 let status = self.regs().mem_rx_status().read();
3644 let rd_addr: u16 = status.mem_rx_rd_addr().bits();
3645 let wr_addr: u16 = status.mem_rx_wr_addr().bits();
3646
3647 if wr_addr > rd_addr {
3648 wr_addr - rd_addr
3649 } else if wr_addr < rd_addr {
3650 (wr_addr + Info::UART_FIFO_SIZE) - rd_addr
3651 } else if fifo_cnt > 0 {
3652 Info::UART_FIFO_SIZE
3653 } else {
3654 0
3655 }
3656 }
3657
3658 fn write(&self, data: &[u8]) -> Result<usize, TxError> {
3659 if data.is_empty() {
3660 return Ok(0);
3661 }
3662
3663 while self.tx_fifo_count() >= Info::UART_FIFO_SIZE {}
3664
3665 let space = (Info::UART_FIFO_SIZE - self.tx_fifo_count()) as usize;
3666 let to_write = space.min(data.len());
3667 for &byte in &data[..to_write] {
3668 self.write_byte(byte);
3669 }
3670
3671 Ok(to_write)
3672 }
3673
3674 fn read(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3675 if buf.is_empty() {
3676 return Ok(0);
3677 }
3678
3679 while self.rx_fifo_count() == 0 {
3680 self.check_for_errors()?;
3682 }
3683
3684 self.read_buffered(buf)
3685 }
3686
3687 fn read_buffered(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3688 let to_read = (self.rx_fifo_count() as usize).min(buf.len());
3691 self.check_for_errors()?;
3692
3693 for byte_into in buf[..to_read].iter_mut() {
3694 *byte_into = self.read_next_from_fifo();
3695 }
3696
3697 self.clear_rx_events(RxEvent::FifoFull);
3699
3700 Ok(to_read)
3701 }
3702}
3703
3704impl PartialEq for Info {
3705 fn eq(&self, other: &Self) -> bool {
3706 core::ptr::eq(self.register_block, other.register_block)
3707 }
3708}
3709
3710unsafe impl Sync for Info {}
3711
3712for_each_uart! {
3713 ($id:literal, $inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident) => {
3714 impl Instance for crate::peripherals::$inst<'_> {
3715 fn parts(&self) -> (&'static Info, &'static State) {
3716 #[handler]
3717 #[ram]
3718 pub(super) fn irq_handler() {
3719 intr_handler(&PERIPHERAL, &STATE);
3720 }
3721
3722 static STATE: State = State {
3723 tx_waker: AtomicWaker::new(),
3724 rx_waker: AtomicWaker::new(),
3725 is_rx_async: AtomicBool::new(false),
3726 is_tx_async: AtomicBool::new(false),
3727 };
3728
3729 static PERIPHERAL: Info = Info {
3730 register_block: crate::peripherals::$inst::ptr(),
3731 peripheral: crate::system::Peripheral::$peri,
3732 clock_instance: clocks::UartInstance::$peri,
3733 async_handler: irq_handler,
3734 tx_signal: OutputSignal::$txd,
3735 rx_signal: InputSignal::$rxd,
3736 cts_signal: InputSignal::$cts,
3737 rts_signal: OutputSignal::$rts,
3738 };
3739 (&PERIPHERAL, &STATE)
3740 }
3741 }
3742 };
3743}
3744
3745crate::any_peripheral! {
3746 pub peripheral AnyUart<'d> {
3748 #[cfg(soc_has_uart0)]
3749 Uart0(crate::peripherals::UART0<'d>),
3750 #[cfg(soc_has_uart1)]
3751 Uart1(crate::peripherals::UART1<'d>),
3752 #[cfg(soc_has_uart2)]
3753 Uart2(crate::peripherals::UART2<'d>),
3754 }
3755}
3756
3757impl Instance for AnyUart<'_> {
3758 #[inline]
3759 fn parts(&self) -> (&'static Info, &'static State) {
3760 any::delegate!(self, uart => { uart.parts() })
3761 }
3762}
3763
3764impl AnyUart<'_> {
3765 fn bind_peri_interrupt(&self, handler: InterruptHandler) {
3766 any::delegate!(self, uart => { uart.bind_peri_interrupt(handler) })
3767 }
3768
3769 fn disable_peri_interrupt_on_all_cores(&self) {
3770 any::delegate!(self, uart => { uart.disable_peri_interrupt_on_all_cores() })
3771 }
3772
3773 fn set_interrupt_handler(&self, handler: InterruptHandler) {
3774 self.disable_peri_interrupt_on_all_cores();
3775
3776 self.info().enable_listen(EnumSet::all(), false);
3777 self.info().clear_interrupts(EnumSet::all());
3778
3779 self.bind_peri_interrupt(handler);
3780 }
3781}
3782
3783struct UartClockGuard<'t> {
3784 uart: AnyUart<'t>,
3785}
3786
3787impl<'t> UartClockGuard<'t> {
3788 fn new(uart: AnyUart<'t>) -> Self {
3789 ClockTree::with(|clocks| {
3790 let clock = uart.info().clock_instance;
3791
3792 let sclk_config = ClockConfig::new(
3794 Default::default(),
3795 #[cfg(any(uart_has_sclk_divider, soc_has_pcr))]
3796 0,
3797 );
3798 clock.configure_function_clock(clocks, sclk_config);
3799 clock.request_function_clock(clocks);
3800 clock.request_baud_rate_generator(clocks);
3801 #[cfg(soc_has_clock_node_uart_mem_clock)]
3802 clock.request_mem_clock(clocks);
3803 });
3804
3805 Self { uart }
3806 }
3807}
3808
3809impl Clone for UartClockGuard<'_> {
3810 fn clone(&self) -> Self {
3811 Self::new(unsafe { self.uart.clone_unchecked() })
3812 }
3813}
3814
3815impl Drop for UartClockGuard<'_> {
3816 fn drop(&mut self) {
3817 ClockTree::with(|clocks| {
3818 let clock = self.uart.info().clock_instance;
3819
3820 #[cfg(soc_has_clock_node_uart_mem_clock)]
3821 clock.release_mem_clock(clocks);
3822 clock.release_baud_rate_generator(clocks);
3823 clock.release_function_clock(clocks);
3824 });
3825 }
3826}