1#[cfg(all(soc_has_uhci0, gdma))]
47#[cfg(feature = "unstable")]
48pub mod uhci;
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 clock::Clocks,
61 gpio::{
62 InputConfig,
63 InputSignal,
64 OutputConfig,
65 OutputSignal,
66 PinGuard,
67 Pull,
68 interconnect::{PeripheralInput, PeripheralOutput},
69 },
70 interrupt::InterruptHandler,
71 pac::uart0::RegisterBlock,
72 private::OnDrop,
73 system::PeripheralGuard,
74};
75
76#[derive(Debug, Clone, Copy, PartialEq)]
78#[cfg_attr(feature = "defmt", derive(defmt::Format))]
79#[non_exhaustive]
80pub enum RxError {
81 FifoOverflowed,
86
87 GlitchOccurred,
93
94 FrameFormatViolated,
99
100 ParityMismatch,
105}
106
107impl core::error::Error for RxError {}
108
109impl core::fmt::Display for RxError {
110 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
111 match self {
112 RxError::FifoOverflowed => write!(f, "The RX FIFO overflowed"),
113 RxError::GlitchOccurred => write!(f, "A glitch was detected on the RX line"),
114 RxError::FrameFormatViolated => {
115 write!(f, "A framing error was detected on the RX line")
116 }
117 RxError::ParityMismatch => write!(f, "A parity error was detected on the RX line"),
118 }
119 }
120}
121
122#[instability::unstable]
123impl embedded_io_06::Error for RxError {
124 fn kind(&self) -> embedded_io_06::ErrorKind {
125 embedded_io_06::ErrorKind::Other
126 }
127}
128
129#[instability::unstable]
130impl embedded_io_07::Error for RxError {
131 fn kind(&self) -> embedded_io_07::ErrorKind {
132 embedded_io_07::ErrorKind::Other
133 }
134}
135
136#[derive(Debug, Clone, Copy, PartialEq)]
138#[cfg_attr(feature = "defmt", derive(defmt::Format))]
139#[non_exhaustive]
140pub enum TxError {}
141
142impl core::fmt::Display for TxError {
143 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
144 write!(f, "Tx error")
145 }
146}
147
148impl core::error::Error for TxError {}
149
150#[instability::unstable]
151impl embedded_io_06::Error for TxError {
152 fn kind(&self) -> embedded_io_06::ErrorKind {
153 embedded_io_06::ErrorKind::Other
154 }
155}
156#[instability::unstable]
157impl embedded_io_07::Error for TxError {
158 fn kind(&self) -> embedded_io_07::ErrorKind {
159 embedded_io_07::ErrorKind::Other
160 }
161}
162
163#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
165#[cfg_attr(feature = "defmt", derive(defmt::Format))]
166#[non_exhaustive]
167#[instability::unstable]
168pub enum ClockSource {
169 #[cfg_attr(not(any(esp32c6, esp32h2, soc_has_lp_uart)), default)]
171 Apb,
172 #[cfg(not(any(esp32, esp32s2)))]
174 RcFast,
175 #[cfg(not(any(esp32, esp32s2)))]
177 #[cfg_attr(any(esp32c6, esp32h2, soc_has_lp_uart), default)]
178 Xtal,
179 #[cfg(any(esp32, esp32s2))]
181 RefTick,
182}
183
184#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
190#[cfg_attr(feature = "defmt", derive(defmt::Format))]
191pub enum DataBits {
192 _5,
194 _6,
196 _7,
198 #[default]
200 _8,
201}
202
203#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
210#[cfg_attr(feature = "defmt", derive(defmt::Format))]
211pub enum Parity {
212 #[default]
214 None,
215 Even,
218 Odd,
221}
222
223#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
229#[cfg_attr(feature = "defmt", derive(defmt::Format))]
230pub enum StopBits {
231 #[default]
233 _1,
234 _1p5,
236 _2,
238}
239
240#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
242#[cfg_attr(feature = "defmt", derive(defmt::Format))]
243#[instability::unstable]
244pub enum SwFlowControl {
245 #[default]
246 Disabled,
248 Enabled {
250 xon_char: u8,
252 xoff_char: u8,
254 xon_threshold: u8,
257 xoff_threshold: u8,
260 },
261}
262
263#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
265#[cfg_attr(feature = "defmt", derive(defmt::Format))]
266#[instability::unstable]
267pub enum CtsConfig {
268 Enabled,
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 enum RtsConfig {
280 Enabled(u8),
282 #[default]
283 Disabled,
285}
286
287#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
289#[cfg_attr(feature = "defmt", derive(defmt::Format))]
290#[instability::unstable]
291pub struct HwFlowControl {
292 pub cts: CtsConfig,
294 pub rts: RtsConfig,
296}
297
298#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
300#[cfg_attr(feature = "defmt", derive(defmt::Format))]
301#[instability::unstable]
302pub enum BaudrateTolerance {
303 #[default]
305 Closest,
306 Exact,
309 ErrorPercent(u8),
311}
312
313#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
315#[cfg_attr(feature = "defmt", derive(defmt::Format))]
316#[non_exhaustive]
317pub struct Config {
318 baudrate: u32,
321 #[builder_lite(unstable)]
324 baudrate_tolerance: BaudrateTolerance,
325 data_bits: DataBits,
327 parity: Parity,
329 stop_bits: StopBits,
331 #[builder_lite(unstable)]
333 sw_flow_ctrl: SwFlowControl,
334 #[builder_lite(unstable)]
336 hw_flow_ctrl: HwFlowControl,
337 #[builder_lite(unstable)]
339 clock_source: ClockSource,
340 rx: RxConfig,
342 tx: TxConfig,
344}
345
346impl Default for Config {
347 fn default() -> Config {
348 Config {
349 rx: RxConfig::default(),
350 tx: TxConfig::default(),
351 baudrate: 115_200,
352 baudrate_tolerance: BaudrateTolerance::default(),
353 data_bits: Default::default(),
354 parity: Default::default(),
355 stop_bits: Default::default(),
356 sw_flow_ctrl: Default::default(),
357 hw_flow_ctrl: Default::default(),
358 clock_source: Default::default(),
359 }
360 }
361}
362
363impl Config {
364 fn validate(&self) -> Result<(), ConfigError> {
365 if let BaudrateTolerance::ErrorPercent(percentage) = self.baudrate_tolerance {
366 assert!(percentage > 0 && percentage <= 100);
367 }
368
369 if self.baudrate == 0 || self.baudrate > 5_000_000 {
371 return Err(ConfigError::BaudrateNotSupported);
372 }
373 Ok(())
374 }
375}
376
377#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
379#[cfg_attr(feature = "defmt", derive(defmt::Format))]
380#[non_exhaustive]
381pub struct RxConfig {
382 fifo_full_threshold: u16,
384 timeout: Option<u8>,
386}
387
388impl Default for RxConfig {
389 fn default() -> RxConfig {
390 RxConfig {
391 fifo_full_threshold: 120,
393 timeout: Some(10),
395 }
396 }
397}
398
399#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
401#[cfg_attr(feature = "defmt", derive(defmt::Format))]
402#[non_exhaustive]
403pub struct TxConfig {
404 fifo_empty_threshold: u16,
406}
407
408impl Default for TxConfig {
409 fn default() -> TxConfig {
410 TxConfig {
411 fifo_empty_threshold: 10,
413 }
414 }
415}
416
417#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
419#[cfg_attr(feature = "defmt", derive(defmt::Format))]
420#[instability::unstable]
421#[non_exhaustive]
422pub struct AtCmdConfig {
423 pre_idle_count: Option<u16>,
426 post_idle_count: Option<u16>,
429 gap_timeout: Option<u16>,
432 cmd_char: u8,
434 char_num: u8,
436}
437
438impl Default for AtCmdConfig {
439 fn default() -> Self {
440 Self {
441 pre_idle_count: None,
442 post_idle_count: None,
443 gap_timeout: None,
444 cmd_char: b'+',
445 char_num: 1,
446 }
447 }
448}
449
450struct UartBuilder<'d, Dm: DriverMode> {
451 uart: AnyUart<'d>,
452 phantom: PhantomData<Dm>,
453}
454
455impl<'d, Dm> UartBuilder<'d, Dm>
456where
457 Dm: DriverMode,
458{
459 fn new(uart: impl Instance + 'd) -> Self {
460 Self {
461 uart: uart.degrade(),
462 phantom: PhantomData,
463 }
464 }
465
466 fn init(self, config: Config) -> Result<Uart<'d, Dm>, ConfigError> {
467 let rx_guard = PeripheralGuard::new(self.uart.info().peripheral);
468 let tx_guard = PeripheralGuard::new(self.uart.info().peripheral);
469
470 let mem_guard = create_mem_guard(unsafe { self.uart.clone_unchecked() });
471
472 let rts_pin = PinGuard::new_unconnected(self.uart.info().rts_signal);
473 let tx_pin = PinGuard::new_unconnected(self.uart.info().tx_signal);
474
475 let mut serial = Uart {
476 rx: UartRx {
477 uart: unsafe { self.uart.clone_unchecked() },
478 phantom: PhantomData,
479 guard: rx_guard,
480 mem_guard: mem_guard.clone(),
481 },
482 tx: UartTx {
483 uart: self.uart,
484 phantom: PhantomData,
485 guard: tx_guard,
486 mem_guard,
487 rts_pin,
488 tx_pin,
489 },
490 };
491 serial.init(config)?;
492
493 Ok(serial)
494 }
495}
496
497#[procmacros::doc_replace]
498pub struct Uart<'d, Dm: DriverMode> {
513 rx: UartRx<'d, Dm>,
514 tx: UartTx<'d, Dm>,
515}
516
517#[instability::unstable]
519pub struct UartTx<'d, Dm: DriverMode> {
520 uart: AnyUart<'d>,
521 phantom: PhantomData<Dm>,
522 guard: PeripheralGuard,
523 mem_guard: MemoryGuard<'d>,
524 rts_pin: PinGuard,
525 tx_pin: PinGuard,
526}
527
528#[instability::unstable]
530pub struct UartRx<'d, Dm: DriverMode> {
531 uart: AnyUart<'d>,
532 phantom: PhantomData<Dm>,
533 guard: PeripheralGuard,
534 mem_guard: MemoryGuard<'d>,
535}
536
537#[derive(Debug, Clone, Copy, PartialEq, Eq)]
539#[cfg_attr(feature = "defmt", derive(defmt::Format))]
540#[non_exhaustive]
541pub enum ConfigError {
542 #[cfg(feature = "unstable")]
544 #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
545 BaudrateNotAchievable,
546
547 BaudrateNotSupported,
554
555 #[cfg_attr(esp32, doc = "127")]
557 #[cfg_attr(not(esp32), doc = "1023")]
558 TimeoutTooLong,
560
561 RxFifoThresholdNotSupported,
563
564 TxFifoThresholdNotSupported,
566}
567
568impl core::error::Error for ConfigError {}
569
570impl core::fmt::Display for ConfigError {
571 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
572 match self {
573 #[cfg(feature = "unstable")]
574 ConfigError::BaudrateNotAchievable => {
575 write!(f, "The requested baud rate is not achievable")
576 }
577 ConfigError::BaudrateNotSupported => {
578 write!(f, "The requested baud rate is not supported")
579 }
580 ConfigError::TimeoutTooLong => write!(f, "The requested timeout is not supported"),
581 ConfigError::RxFifoThresholdNotSupported => {
582 write!(f, "The requested RX FIFO threshold is not supported")
583 }
584 ConfigError::TxFifoThresholdNotSupported => {
585 write!(f, "The requested TX FIFO threshold is not supported")
586 }
587 }
588 }
589}
590
591#[instability::unstable]
592impl<Dm> embassy_embedded_hal::SetConfig for Uart<'_, Dm>
593where
594 Dm: DriverMode,
595{
596 type Config = Config;
597 type ConfigError = ConfigError;
598
599 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
600 self.apply_config(config)
601 }
602}
603
604#[instability::unstable]
605impl<Dm> embassy_embedded_hal::SetConfig for UartRx<'_, Dm>
606where
607 Dm: DriverMode,
608{
609 type Config = Config;
610 type ConfigError = ConfigError;
611
612 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
613 self.apply_config(config)
614 }
615}
616
617#[instability::unstable]
618impl<Dm> embassy_embedded_hal::SetConfig for UartTx<'_, Dm>
619where
620 Dm: DriverMode,
621{
622 type Config = Config;
623 type ConfigError = ConfigError;
624
625 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
626 self.apply_config(config)
627 }
628}
629
630impl<'d> UartTx<'d, Blocking> {
631 #[procmacros::doc_replace]
632 #[instability::unstable]
648 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
649 let (_, uart_tx) = UartBuilder::new(uart).init(config)?.split();
650
651 Ok(uart_tx)
652 }
653
654 #[instability::unstable]
656 pub fn into_async(self) -> UartTx<'d, Async> {
657 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
658 self.uart
659 .set_interrupt_handler(self.uart.info().async_handler);
660 }
661 self.uart.state().is_tx_async.store(true, Ordering::Release);
662
663 UartTx {
664 uart: self.uart,
665 phantom: PhantomData,
666 guard: self.guard,
667 mem_guard: self.mem_guard,
668 rts_pin: self.rts_pin,
669 tx_pin: self.tx_pin,
670 }
671 }
672}
673
674impl<'d> UartTx<'d, Async> {
675 #[instability::unstable]
677 pub fn into_blocking(self) -> UartTx<'d, Blocking> {
678 self.uart
679 .state()
680 .is_tx_async
681 .store(false, Ordering::Release);
682 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
683 self.uart.disable_peri_interrupt();
684 }
685
686 UartTx {
687 uart: self.uart,
688 phantom: PhantomData,
689 guard: self.guard,
690 mem_guard: self.mem_guard,
691 rts_pin: self.rts_pin,
692 tx_pin: self.tx_pin,
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(&mut 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 fn is_tx_idle(&self) -> bool {
871 #[cfg(esp32)]
872 let status = self.regs().status();
873 #[cfg(not(esp32))]
874 let status = self.regs().fsm_status();
875
876 status.read().st_utx_out().bits() == 0x0
877 }
878
879 fn disable_tx_interrupts(&self) {
885 self.regs().int_clr().write(|w| {
886 w.txfifo_empty().clear_bit_by_one();
887 w.tx_brk_done().clear_bit_by_one();
888 w.tx_brk_idle_done().clear_bit_by_one();
889 w.tx_done().clear_bit_by_one()
890 });
891
892 self.regs().int_ena().write(|w| {
893 w.txfifo_empty().clear_bit();
894 w.tx_brk_done().clear_bit();
895 w.tx_brk_idle_done().clear_bit();
896 w.tx_done().clear_bit()
897 });
898 }
899
900 fn regs(&self) -> &RegisterBlock {
901 self.uart.info().regs()
902 }
903}
904
905#[inline(always)]
906fn sync_regs(_register_block: &RegisterBlock) {
907 #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
908 {
909 cfg_if::cfg_if! {
910 if #[cfg(any(esp32c6, esp32h2))] {
911 let update_reg = _register_block.reg_update();
912 } else {
913 let update_reg = _register_block.id();
914 }
915 }
916
917 update_reg.modify(|_, w| w.reg_update().set_bit());
918
919 while update_reg.read().reg_update().bit_is_set() {
920 }
922 }
923}
924
925impl<'d> UartRx<'d, Blocking> {
926 #[procmacros::doc_replace]
927 #[instability::unstable]
941 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
942 let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();
943
944 Ok(uart_rx)
945 }
946
947 #[instability::unstable]
949 pub fn into_async(self) -> UartRx<'d, Async> {
950 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
951 self.uart
952 .set_interrupt_handler(self.uart.info().async_handler);
953 }
954 self.uart.state().is_rx_async.store(true, Ordering::Release);
955
956 UartRx {
957 uart: self.uart,
958 phantom: PhantomData,
959 guard: self.guard,
960 mem_guard: self.mem_guard,
961 }
962 }
963}
964
965impl<'d> UartRx<'d, Async> {
966 #[instability::unstable]
968 pub fn into_blocking(self) -> UartRx<'d, Blocking> {
969 self.uart
970 .state()
971 .is_rx_async
972 .store(false, Ordering::Release);
973 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
974 self.uart.disable_peri_interrupt();
975 }
976
977 UartRx {
978 uart: self.uart,
979 phantom: PhantomData,
980 guard: self.guard,
981 mem_guard: self.mem_guard,
982 }
983 }
984
985 async fn wait_for_buffered_data(
986 &mut self,
987 minimum: usize,
988 preferred: usize,
989 listen_for_timeout: bool,
990 ) -> Result<(), RxError> {
991 while self.uart.info().rx_fifo_count() < (minimum as u16).min(Info::RX_FIFO_MAX_THRHD) {
992 let amount = u16::try_from(preferred)
993 .unwrap_or(Info::RX_FIFO_MAX_THRHD)
994 .min(Info::RX_FIFO_MAX_THRHD);
995
996 let current = self.uart.info().rx_fifo_full_threshold();
997 let _guard = if current > amount {
998 let info = self.uart.info();
1002 unwrap!(info.set_rx_fifo_full_threshold(amount));
1003 Some(OnDrop::new(|| {
1004 unwrap!(info.set_rx_fifo_full_threshold(current));
1005 }))
1006 } else {
1007 None
1008 };
1009
1010 let mut events = RxEvent::FifoFull
1012 | RxEvent::FifoOvf
1013 | RxEvent::FrameError
1014 | RxEvent::GlitchDetected
1015 | RxEvent::ParityError;
1016
1017 if self.regs().at_cmd_char().read().char_num().bits() > 0 {
1018 events |= RxEvent::CmdCharDetected;
1019 }
1020
1021 cfg_if::cfg_if! {
1022 if #[cfg(any(esp32c6, esp32h2))] {
1023 let reg_en = self.regs().tout_conf();
1024 } else {
1025 let reg_en = self.regs().conf1();
1026 }
1027 };
1028 if listen_for_timeout && reg_en.read().rx_tout_en().bit_is_set() {
1029 events |= RxEvent::FifoTout;
1030 }
1031
1032 let events = UartRxFuture::new(self.uart.reborrow(), events).await;
1033
1034 let result = rx_event_check_for_error(events);
1035 if let Err(error) = result {
1036 if error == RxError::FifoOverflowed {
1037 self.uart.info().rxfifo_reset();
1038 }
1039 return Err(error);
1040 }
1041 }
1042
1043 Ok(())
1044 }
1045
1046 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1065 if buf.is_empty() {
1066 return Ok(0);
1067 }
1068
1069 self.wait_for_buffered_data(1, buf.len(), true).await?;
1070
1071 self.read_buffered(buf)
1072 }
1073
1074 pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
1089 while !buf.is_empty() {
1090 self.wait_for_buffered_data(buf.len(), buf.len(), false)
1094 .await?;
1095
1096 let read = self.uart.info().read_buffered(buf)?;
1097 buf = &mut buf[read..];
1098 }
1099
1100 Ok(())
1101 }
1102}
1103
1104impl<'d, Dm> UartRx<'d, Dm>
1105where
1106 Dm: DriverMode,
1107{
1108 fn regs(&self) -> &RegisterBlock {
1109 self.uart.info().regs()
1110 }
1111
1112 #[instability::unstable]
1116 pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
1117 let cts = cts.into();
1118
1119 cts.apply_input_config(&InputConfig::default());
1120 cts.set_input_enable(true);
1121
1122 self.uart.info().cts_signal.connect_to(&cts);
1123
1124 self
1125 }
1126
1127 #[instability::unstable]
1136 pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
1137 let rx = rx.into();
1138
1139 rx.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
1140 rx.set_input_enable(true);
1141
1142 self.uart.info().rx_signal.connect_to(&rx);
1143
1144 self
1145 }
1146
1147 #[instability::unstable]
1154 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1155 self.uart
1156 .info()
1157 .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
1158 self.uart
1159 .info()
1160 .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
1161
1162 self.uart.info().rxfifo_reset();
1163 Ok(())
1164 }
1165
1166 #[instability::unstable]
1170 pub fn check_for_errors(&mut self) -> Result<(), RxError> {
1171 self.uart.info().check_for_errors()
1172 }
1173
1174 #[instability::unstable]
1178 pub fn read_ready(&mut self) -> bool {
1179 self.uart.info().rx_fifo_count() > 0
1180 }
1181
1182 #[instability::unstable]
1201 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1202 self.uart.info().read(buf)
1203 }
1204
1205 #[instability::unstable]
1223 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1224 self.uart.info().read_buffered(buf)
1225 }
1226
1227 fn disable_rx_interrupts(&self) {
1233 self.regs().int_clr().write(|w| {
1234 w.rxfifo_full().clear_bit_by_one();
1235 w.rxfifo_ovf().clear_bit_by_one();
1236 w.rxfifo_tout().clear_bit_by_one();
1237 w.at_cmd_char_det().clear_bit_by_one()
1238 });
1239
1240 self.regs().int_ena().write(|w| {
1241 w.rxfifo_full().clear_bit();
1242 w.rxfifo_ovf().clear_bit();
1243 w.rxfifo_tout().clear_bit();
1244 w.at_cmd_char_det().clear_bit()
1245 });
1246 }
1247}
1248
1249impl<'d> Uart<'d, Blocking> {
1250 #[procmacros::doc_replace]
1251 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1269 UartBuilder::new(uart).init(config)
1270 }
1271
1272 pub fn into_async(self) -> Uart<'d, Async> {
1277 Uart {
1278 rx: self.rx.into_async(),
1279 tx: self.tx.into_async(),
1280 }
1281 }
1282
1283 #[cfg_attr(
1284 not(multi_core),
1285 doc = "Registers an interrupt handler for the peripheral."
1286 )]
1287 #[cfg_attr(
1288 multi_core,
1289 doc = "Registers an interrupt handler for the peripheral on the current core."
1290 )]
1291 #[doc = ""]
1292 #[instability::unstable]
1298 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1299 self.tx.uart.set_interrupt_handler(handler);
1301 }
1302
1303 #[procmacros::doc_replace]
1304 #[instability::unstable]
1371 pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1372 self.tx.uart.info().enable_listen(interrupts.into(), true)
1373 }
1374
1375 #[instability::unstable]
1377 pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1378 self.tx.uart.info().enable_listen(interrupts.into(), false)
1379 }
1380
1381 #[instability::unstable]
1383 pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1384 self.tx.uart.info().interrupts()
1385 }
1386
1387 #[instability::unstable]
1389 pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1390 self.tx.uart.info().clear_interrupts(interrupts)
1391 }
1392}
1393
1394impl<'d> Uart<'d, Async> {
1395 pub fn into_blocking(self) -> Uart<'d, Blocking> {
1400 Uart {
1401 rx: self.rx.into_blocking(),
1402 tx: self.tx.into_blocking(),
1403 }
1404 }
1405
1406 #[procmacros::doc_replace]
1407 pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1438 self.tx.write_async(words).await
1439 }
1440
1441 #[procmacros::doc_replace]
1442 pub async fn flush_async(&mut self) -> Result<(), TxError> {
1468 self.tx.flush_async().await
1469 }
1470
1471 #[procmacros::doc_replace]
1472 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1510 self.rx.read_async(buf).await
1511 }
1512
1513 #[instability::unstable]
1528 pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1529 self.rx.read_exact_async(buf).await
1530 }
1531}
1532
1533#[derive(Debug, EnumSetType)]
1535#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1536#[non_exhaustive]
1537#[instability::unstable]
1538pub enum UartInterrupt {
1539 AtCmd,
1542
1543 TxDone,
1545
1546 RxFifoFull,
1549
1550 RxTimeout,
1553}
1554
1555impl<'d, Dm> Uart<'d, Dm>
1556where
1557 Dm: DriverMode,
1558{
1559 #[procmacros::doc_replace]
1560 pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
1579 self.rx = self.rx.with_rx(rx);
1580 self
1581 }
1582
1583 #[procmacros::doc_replace]
1584 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
1599 self.tx = self.tx.with_tx(tx);
1600 self
1601 }
1602
1603 #[procmacros::doc_replace]
1604 pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
1618 self.rx = self.rx.with_cts(cts);
1619 self
1620 }
1621
1622 #[procmacros::doc_replace]
1623 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
1637 self.tx = self.tx.with_rts(rts);
1638 self
1639 }
1640
1641 fn regs(&self) -> &RegisterBlock {
1642 self.tx.uart.info().regs()
1644 }
1645
1646 #[instability::unstable]
1650 pub fn write_ready(&mut self) -> bool {
1651 self.tx.write_ready()
1652 }
1653
1654 #[procmacros::doc_replace]
1655 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
1681 self.tx.write(data)
1682 }
1683
1684 #[procmacros::doc_replace]
1685 pub fn flush(&mut self) -> Result<(), TxError> {
1700 self.tx.flush()
1701 }
1702
1703 #[instability::unstable]
1707 pub fn read_ready(&mut self) -> bool {
1708 self.rx.read_ready()
1709 }
1710
1711 #[procmacros::doc_replace]
1712 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1747 self.rx.read(buf)
1748 }
1749
1750 #[procmacros::doc_replace]
1751 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1769 self.rx.uart.info().apply_config(config)?;
1772 self.rx.apply_config(config)?;
1773 self.tx.apply_config(config)?;
1774 Ok(())
1775 }
1776
1777 #[procmacros::doc_replace]
1778 #[instability::unstable]
1802 pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
1803 (self.rx, self.tx)
1804 }
1805
1806 #[instability::unstable]
1808 pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
1809 self.rx.check_for_errors()
1810 }
1811
1812 #[instability::unstable]
1829 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1830 self.rx.read_buffered(buf)
1831 }
1832
1833 #[instability::unstable]
1835 pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
1836 #[cfg(not(any(esp32, esp32s2)))]
1837 self.regs()
1838 .clk_conf()
1839 .modify(|_, w| w.sclk_en().clear_bit());
1840
1841 self.regs().at_cmd_char().write(|w| unsafe {
1842 w.at_cmd_char().bits(config.cmd_char);
1843 w.char_num().bits(config.char_num)
1844 });
1845
1846 if let Some(pre_idle_count) = config.pre_idle_count {
1847 self.regs()
1848 .at_cmd_precnt()
1849 .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
1850 }
1851
1852 if let Some(post_idle_count) = config.post_idle_count {
1853 self.regs()
1854 .at_cmd_postcnt()
1855 .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
1856 }
1857
1858 if let Some(gap_timeout) = config.gap_timeout {
1859 self.regs()
1860 .at_cmd_gaptout()
1861 .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
1862 }
1863
1864 #[cfg(not(any(esp32, esp32s2)))]
1865 self.regs().clk_conf().modify(|_, w| w.sclk_en().set_bit());
1866
1867 sync_regs(self.regs());
1868 }
1869
1870 #[inline(always)]
1871 fn init(&mut self, config: Config) -> Result<(), ConfigError> {
1872 self.rx.disable_rx_interrupts();
1873 self.tx.disable_tx_interrupts();
1874
1875 self.apply_config(&config)?;
1876
1877 self.rx.uart.info().rxfifo_reset();
1879 self.rx.uart.info().txfifo_reset();
1880
1881 self.regs()
1884 .idle_conf()
1885 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
1886
1887 self.regs().conf0().modify(|_, w| w.err_wr_mask().set_bit());
1890
1891 crate::rom::ets_delay_us(15);
1892
1893 self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
1896
1897 Ok(())
1898 }
1899}
1900
1901impl crate::private::Sealed for Uart<'_, Blocking> {}
1902
1903#[instability::unstable]
1904impl crate::interrupt::InterruptConfigurable for Uart<'_, Blocking> {
1905 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1906 self.tx.uart.set_interrupt_handler(handler);
1908 }
1909}
1910
1911#[instability::unstable]
1912impl<Dm> ufmt_write::uWrite for Uart<'_, Dm>
1913where
1914 Dm: DriverMode,
1915{
1916 type Error = TxError;
1917
1918 #[inline]
1919 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1920 self.tx.write_str(s)
1921 }
1922
1923 #[inline]
1924 fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
1925 self.tx.write_char(ch)
1926 }
1927}
1928
1929#[instability::unstable]
1930impl<Dm> ufmt_write::uWrite for UartTx<'_, Dm>
1931where
1932 Dm: DriverMode,
1933{
1934 type Error = TxError;
1935
1936 #[inline]
1937 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1938 self.write_all(s.as_bytes())
1939 }
1940}
1941
1942impl<Dm> core::fmt::Write for Uart<'_, Dm>
1943where
1944 Dm: DriverMode,
1945{
1946 #[inline]
1947 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1948 self.tx.write_str(s)
1949 }
1950}
1951
1952impl<Dm> core::fmt::Write for UartTx<'_, Dm>
1953where
1954 Dm: DriverMode,
1955{
1956 #[inline]
1957 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1958 self.write_all(s.as_bytes()).map_err(|_| core::fmt::Error)
1959 }
1960}
1961
1962#[instability::unstable]
1964#[derive(Debug, Clone, Copy, PartialEq)]
1965#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1966#[non_exhaustive]
1967pub enum IoError {
1968 Tx(TxError),
1970 Rx(RxError),
1972}
1973
1974#[instability::unstable]
1975impl core::error::Error for IoError {}
1976
1977#[instability::unstable]
1978impl core::fmt::Display for IoError {
1979 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1980 match self {
1981 IoError::Tx(e) => e.fmt(f),
1982 IoError::Rx(e) => e.fmt(f),
1983 }
1984 }
1985}
1986
1987#[instability::unstable]
1988impl embedded_io_06::Error for IoError {
1989 fn kind(&self) -> embedded_io_06::ErrorKind {
1990 embedded_io_06::ErrorKind::Other
1991 }
1992}
1993
1994#[instability::unstable]
1995impl embedded_io_07::Error for IoError {
1996 fn kind(&self) -> embedded_io_07::ErrorKind {
1997 embedded_io_07::ErrorKind::Other
1998 }
1999}
2000
2001#[instability::unstable]
2002impl From<RxError> for IoError {
2003 fn from(e: RxError) -> Self {
2004 IoError::Rx(e)
2005 }
2006}
2007
2008#[instability::unstable]
2009impl From<TxError> for IoError {
2010 fn from(e: TxError) -> Self {
2011 IoError::Tx(e)
2012 }
2013}
2014
2015#[instability::unstable]
2016impl<Dm: DriverMode> embedded_io_06::ErrorType for Uart<'_, Dm> {
2017 type Error = IoError;
2018}
2019
2020#[instability::unstable]
2021impl<Dm: DriverMode> embedded_io_06::ErrorType for UartTx<'_, Dm> {
2022 type Error = TxError;
2023}
2024
2025#[instability::unstable]
2026impl<Dm: DriverMode> embedded_io_06::ErrorType for UartRx<'_, Dm> {
2027 type Error = RxError;
2028}
2029
2030#[instability::unstable]
2031impl<Dm> embedded_io_06::Read for Uart<'_, Dm>
2032where
2033 Dm: DriverMode,
2034{
2035 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2036 self.rx.read(buf).map_err(IoError::Rx)
2037 }
2038}
2039
2040#[instability::unstable]
2041impl<Dm> embedded_io_06::Read for UartRx<'_, Dm>
2042where
2043 Dm: DriverMode,
2044{
2045 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2046 self.read(buf)
2047 }
2048}
2049
2050#[instability::unstable]
2051impl<Dm> embedded_io_06::ReadReady for Uart<'_, Dm>
2052where
2053 Dm: DriverMode,
2054{
2055 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2056 Ok(self.rx.read_ready())
2057 }
2058}
2059
2060#[instability::unstable]
2061impl<Dm> embedded_io_06::ReadReady for UartRx<'_, Dm>
2062where
2063 Dm: DriverMode,
2064{
2065 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2066 Ok(self.read_ready())
2067 }
2068}
2069
2070#[instability::unstable]
2071impl<Dm> embedded_io_06::Write for Uart<'_, Dm>
2072where
2073 Dm: DriverMode,
2074{
2075 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2076 self.tx.write(buf).map_err(IoError::Tx)
2077 }
2078
2079 fn flush(&mut self) -> Result<(), Self::Error> {
2080 self.tx.flush().map_err(IoError::Tx)
2081 }
2082}
2083
2084#[instability::unstable]
2085impl<Dm> embedded_io_06::Write for UartTx<'_, Dm>
2086where
2087 Dm: DriverMode,
2088{
2089 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2090 self.write(buf)
2091 }
2092
2093 fn flush(&mut self) -> Result<(), Self::Error> {
2094 self.flush()
2095 }
2096}
2097
2098#[instability::unstable]
2099impl<Dm> embedded_io_06::WriteReady for UartTx<'_, Dm>
2100where
2101 Dm: DriverMode,
2102{
2103 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2104 Ok(self.write_ready())
2105 }
2106}
2107
2108#[instability::unstable]
2109impl<Dm> embedded_io_06::WriteReady for Uart<'_, Dm>
2110where
2111 Dm: DriverMode,
2112{
2113 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2114 Ok(self.tx.write_ready())
2115 }
2116}
2117
2118#[instability::unstable]
2119impl<Dm: DriverMode> embedded_io_07::ErrorType for Uart<'_, Dm> {
2120 type Error = IoError;
2121}
2122
2123#[instability::unstable]
2124impl<Dm: DriverMode> embedded_io_07::ErrorType for UartTx<'_, Dm> {
2125 type Error = TxError;
2126}
2127
2128#[instability::unstable]
2129impl<Dm: DriverMode> embedded_io_07::ErrorType for UartRx<'_, Dm> {
2130 type Error = RxError;
2131}
2132
2133#[instability::unstable]
2134impl<Dm> embedded_io_07::Read for Uart<'_, Dm>
2135where
2136 Dm: DriverMode,
2137{
2138 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2139 self.rx.read(buf).map_err(IoError::Rx)
2140 }
2141}
2142
2143#[instability::unstable]
2144impl<Dm> embedded_io_07::Read for UartRx<'_, Dm>
2145where
2146 Dm: DriverMode,
2147{
2148 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2149 self.read(buf)
2150 }
2151}
2152
2153#[instability::unstable]
2154impl<Dm> embedded_io_07::ReadReady for Uart<'_, Dm>
2155where
2156 Dm: DriverMode,
2157{
2158 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2159 Ok(self.rx.read_ready())
2160 }
2161}
2162
2163#[instability::unstable]
2164impl<Dm> embedded_io_07::ReadReady for UartRx<'_, Dm>
2165where
2166 Dm: DriverMode,
2167{
2168 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2169 Ok(self.read_ready())
2170 }
2171}
2172
2173#[instability::unstable]
2174impl<Dm> embedded_io_07::Write for Uart<'_, Dm>
2175where
2176 Dm: DriverMode,
2177{
2178 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2179 self.tx.write(buf).map_err(IoError::Tx)
2180 }
2181
2182 fn flush(&mut self) -> Result<(), Self::Error> {
2183 self.tx.flush().map_err(IoError::Tx)
2184 }
2185}
2186
2187#[instability::unstable]
2188impl<Dm> embedded_io_07::Write for UartTx<'_, Dm>
2189where
2190 Dm: DriverMode,
2191{
2192 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2193 self.write(buf)
2194 }
2195
2196 fn flush(&mut self) -> Result<(), Self::Error> {
2197 self.flush()
2198 }
2199}
2200
2201#[instability::unstable]
2202impl<Dm> embedded_io_07::WriteReady for UartTx<'_, Dm>
2203where
2204 Dm: DriverMode,
2205{
2206 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2207 Ok(self.write_ready())
2208 }
2209}
2210
2211#[instability::unstable]
2212impl<Dm> embedded_io_07::WriteReady for Uart<'_, Dm>
2213where
2214 Dm: DriverMode,
2215{
2216 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2217 Ok(self.tx.write_ready())
2218 }
2219}
2220
2221#[derive(Debug, EnumSetType)]
2222pub(crate) enum TxEvent {
2223 Done,
2224 FiFoEmpty,
2225}
2226
2227#[derive(Debug, EnumSetType)]
2228pub(crate) enum RxEvent {
2229 FifoFull,
2230 CmdCharDetected,
2231 FifoOvf,
2232 FifoTout,
2233 GlitchDetected,
2234 FrameError,
2235 ParityError,
2236}
2237
2238fn rx_event_check_for_error(events: EnumSet<RxEvent>) -> Result<(), RxError> {
2239 for event in events {
2240 match event {
2241 RxEvent::FifoOvf => return Err(RxError::FifoOverflowed),
2242 RxEvent::GlitchDetected => return Err(RxError::GlitchOccurred),
2243 RxEvent::FrameError => return Err(RxError::FrameFormatViolated),
2244 RxEvent::ParityError => return Err(RxError::ParityMismatch),
2245 RxEvent::FifoFull | RxEvent::CmdCharDetected | RxEvent::FifoTout => continue,
2246 }
2247 }
2248
2249 Ok(())
2250}
2251
2252#[must_use = "futures do nothing unless you `.await` or poll them"]
2258struct UartRxFuture {
2259 events: EnumSet<RxEvent>,
2260 uart: &'static Info,
2261 state: &'static State,
2262 registered: bool,
2263}
2264
2265impl UartRxFuture {
2266 fn new(uart: impl Instance, events: impl Into<EnumSet<RxEvent>>) -> Self {
2267 Self {
2268 events: events.into(),
2269 uart: uart.info(),
2270 state: uart.state(),
2271 registered: false,
2272 }
2273 }
2274}
2275
2276impl core::future::Future for UartRxFuture {
2277 type Output = EnumSet<RxEvent>;
2278
2279 fn poll(
2280 mut self: core::pin::Pin<&mut Self>,
2281 cx: &mut core::task::Context<'_>,
2282 ) -> core::task::Poll<Self::Output> {
2283 let events = self.uart.rx_events().intersection(self.events);
2284 if !events.is_empty() {
2285 self.uart.clear_rx_events(events);
2286 Poll::Ready(events)
2287 } else {
2288 self.state.rx_waker.register(cx.waker());
2289 if !self.registered {
2290 self.uart.enable_listen_rx(self.events, true);
2291 self.registered = true;
2292 }
2293 Poll::Pending
2294 }
2295 }
2296}
2297
2298impl Drop for UartRxFuture {
2299 fn drop(&mut self) {
2300 self.uart.enable_listen_rx(self.events, false);
2304 }
2305}
2306
2307#[must_use = "futures do nothing unless you `.await` or poll them"]
2308struct UartTxFuture {
2309 events: EnumSet<TxEvent>,
2310 uart: &'static Info,
2311 state: &'static State,
2312 registered: bool,
2313}
2314
2315impl UartTxFuture {
2316 fn new(uart: impl Instance, events: impl Into<EnumSet<TxEvent>>) -> Self {
2317 Self {
2318 events: events.into(),
2319 uart: uart.info(),
2320 state: uart.state(),
2321 registered: false,
2322 }
2323 }
2324}
2325
2326impl core::future::Future for UartTxFuture {
2327 type Output = ();
2328
2329 fn poll(
2330 mut self: core::pin::Pin<&mut Self>,
2331 cx: &mut core::task::Context<'_>,
2332 ) -> core::task::Poll<Self::Output> {
2333 let events = self.uart.tx_events().intersection(self.events);
2334 if !events.is_empty() {
2335 self.uart.clear_tx_events(events);
2336 Poll::Ready(())
2337 } else {
2338 self.state.tx_waker.register(cx.waker());
2339 if !self.registered {
2340 self.uart.enable_listen_tx(self.events, true);
2341 self.registered = true;
2342 }
2343 Poll::Pending
2344 }
2345 }
2346}
2347
2348impl Drop for UartTxFuture {
2349 fn drop(&mut self) {
2350 self.uart.enable_listen_tx(self.events, false);
2354 }
2355}
2356
2357#[instability::unstable]
2358impl embedded_io_async_06::Read for Uart<'_, Async> {
2359 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2360 self.read_async(buf).await.map_err(IoError::Rx)
2361 }
2362
2363 async fn read_exact(
2364 &mut self,
2365 buf: &mut [u8],
2366 ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2367 self.read_exact_async(buf)
2368 .await
2369 .map_err(|e| embedded_io_06::ReadExactError::Other(IoError::Rx(e)))
2370 }
2371}
2372
2373#[instability::unstable]
2374impl embedded_io_async_06::Read for UartRx<'_, Async> {
2375 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2376 self.read_async(buf).await
2377 }
2378
2379 async fn read_exact(
2380 &mut self,
2381 buf: &mut [u8],
2382 ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2383 self.read_exact_async(buf)
2384 .await
2385 .map_err(embedded_io_06::ReadExactError::Other)
2386 }
2387}
2388
2389#[instability::unstable]
2390impl embedded_io_async_06::Write for Uart<'_, Async> {
2391 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2392 self.write_async(buf).await.map_err(IoError::Tx)
2393 }
2394
2395 async fn flush(&mut self) -> Result<(), Self::Error> {
2396 self.flush_async().await.map_err(IoError::Tx)
2397 }
2398}
2399
2400#[instability::unstable]
2401impl embedded_io_async_06::Write for UartTx<'_, Async> {
2402 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2403 self.write_async(buf).await
2404 }
2405
2406 async fn flush(&mut self) -> Result<(), Self::Error> {
2407 self.flush_async().await
2408 }
2409}
2410
2411#[instability::unstable]
2412impl embedded_io_async_07::Read for Uart<'_, Async> {
2413 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2414 self.read_async(buf).await.map_err(IoError::Rx)
2415 }
2416
2417 async fn read_exact(
2418 &mut self,
2419 buf: &mut [u8],
2420 ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2421 self.read_exact_async(buf)
2422 .await
2423 .map_err(|e| embedded_io_07::ReadExactError::Other(IoError::Rx(e)))
2424 }
2425}
2426
2427#[instability::unstable]
2428impl embedded_io_async_07::Read for UartRx<'_, Async> {
2429 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2430 self.read_async(buf).await
2431 }
2432
2433 async fn read_exact(
2434 &mut self,
2435 buf: &mut [u8],
2436 ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2437 self.read_exact_async(buf)
2438 .await
2439 .map_err(embedded_io_07::ReadExactError::Other)
2440 }
2441}
2442
2443#[instability::unstable]
2444impl embedded_io_async_07::Write for Uart<'_, Async> {
2445 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2446 self.write_async(buf).await.map_err(IoError::Tx)
2447 }
2448
2449 async fn flush(&mut self) -> Result<(), Self::Error> {
2450 self.flush_async().await.map_err(IoError::Tx)
2451 }
2452}
2453
2454#[instability::unstable]
2455impl embedded_io_async_07::Write for UartTx<'_, Async> {
2456 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2457 self.write_async(buf).await
2458 }
2459
2460 async fn flush(&mut self) -> Result<(), Self::Error> {
2461 self.flush_async().await
2462 }
2463}
2464
2465pub(super) fn intr_handler(uart: &Info, state: &State) {
2470 let interrupts = uart.regs().int_st().read();
2471 let interrupt_bits = interrupts.bits(); let rx_wake = interrupts.rxfifo_full().bit_is_set()
2473 | interrupts.rxfifo_ovf().bit_is_set()
2474 | interrupts.rxfifo_tout().bit_is_set()
2475 | interrupts.at_cmd_char_det().bit_is_set()
2476 | interrupts.glitch_det().bit_is_set()
2477 | interrupts.frm_err().bit_is_set()
2478 | interrupts.parity_err().bit_is_set();
2479 let tx_wake = interrupts.tx_done().bit_is_set() | interrupts.txfifo_empty().bit_is_set();
2480
2481 uart.regs()
2482 .int_ena()
2483 .modify(|r, w| unsafe { w.bits(r.bits() & !interrupt_bits) });
2484
2485 if tx_wake {
2486 state.tx_waker.wake();
2487 }
2488 if rx_wake {
2489 state.rx_waker.wake();
2490 }
2491}
2492
2493#[cfg(lp_uart)]
2495#[instability::unstable]
2496pub mod lp_uart {
2497 use crate::{
2498 gpio::lp_io::{LowPowerInput, LowPowerOutput},
2499 peripherals::{LP_AON, LP_IO, LP_UART, LPWR},
2500 uart::{Config, DataBits, Parity, StopBits},
2501 };
2502 pub struct LpUart {
2506 uart: LP_UART<'static>,
2507 }
2508
2509 impl LpUart {
2510 pub fn new(
2519 uart: LP_UART<'static>,
2520 config: Config,
2521 _tx: LowPowerOutput<'_, 5>,
2522 _rx: LowPowerInput<'_, 4>,
2523 ) -> Self {
2524 LP_AON::regs()
2526 .gpio_mux()
2527 .modify(|r, w| unsafe { w.sel().bits(r.sel().bits() | (1 << 4) | (1 << 5)) });
2528
2529 LP_IO::regs()
2530 .gpio(4)
2531 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2532 LP_IO::regs()
2533 .gpio(5)
2534 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2535
2536 let mut me = Self { uart };
2537 let uart = me.uart.register_block();
2538
2539 uart.conf0().modify(|_, w| unsafe {
2545 w.parity().clear_bit();
2546 w.parity_en().clear_bit();
2547 w.bit_num().bits(0x3);
2548 w.stop_bit_num().bits(0x1)
2549 });
2550 uart.idle_conf()
2552 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2553 uart.hwfc_conf().modify(|_, w| w.rx_flow_en().clear_bit());
2555
2556 LPWR::regs()
2561 .lpperi()
2562 .modify(|_, w| w.lp_uart_clk_sel().clear_bit());
2563
2564 me.change_baud_internal(&config);
2567 me.change_parity(config.parity);
2569 me.change_data_bits(config.data_bits);
2571 me.change_stop_bits(config.stop_bits);
2573 me.change_tx_idle(0); me.rxfifo_reset();
2578 me.txfifo_reset();
2579
2580 me
2581 }
2582
2583 fn rxfifo_reset(&mut self) {
2584 self.uart
2585 .register_block()
2586 .conf0()
2587 .modify(|_, w| w.rxfifo_rst().set_bit());
2588 self.update();
2589
2590 self.uart
2591 .register_block()
2592 .conf0()
2593 .modify(|_, w| w.rxfifo_rst().clear_bit());
2594 self.update();
2595 }
2596
2597 fn txfifo_reset(&mut self) {
2598 self.uart
2599 .register_block()
2600 .conf0()
2601 .modify(|_, w| w.txfifo_rst().set_bit());
2602 self.update();
2603
2604 self.uart
2605 .register_block()
2606 .conf0()
2607 .modify(|_, w| w.txfifo_rst().clear_bit());
2608 self.update();
2609 }
2610
2611 fn update(&mut self) {
2612 let register_block = self.uart.register_block();
2613 register_block
2614 .reg_update()
2615 .modify(|_, w| w.reg_update().set_bit());
2616 while register_block.reg_update().read().reg_update().bit_is_set() {
2617 }
2619 }
2620
2621 fn change_baud_internal(&mut self, config: &Config) {
2622 let clk = 16_000_000_u32;
2624 let max_div = 0b1111_1111_1111 - 1;
2625 let clk_div = clk.div_ceil(max_div * config.baudrate);
2626
2627 self.uart.register_block().clk_conf().modify(|_, w| unsafe {
2628 w.sclk_div_a().bits(0);
2629 w.sclk_div_b().bits(0);
2630 w.sclk_div_num().bits(clk_div as u8 - 1);
2631 w.sclk_sel().bits(match config.clock_source {
2632 super::ClockSource::Xtal => 3,
2633 super::ClockSource::RcFast => 2,
2634 super::ClockSource::Apb => panic!("Wrong clock source for LP_UART"),
2635 });
2636 w.sclk_en().set_bit()
2637 });
2638
2639 let clk = clk / clk_div;
2640 let divider = clk / config.baudrate;
2641 let divider = divider as u16;
2642
2643 self.uart
2644 .register_block()
2645 .clkdiv()
2646 .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) });
2647
2648 self.update();
2649 }
2650
2651 pub fn change_baud(&mut self, config: &Config) {
2659 self.change_baud_internal(config);
2660 self.txfifo_reset();
2661 self.rxfifo_reset();
2662 }
2663
2664 fn change_parity(&mut self, parity: Parity) -> &mut Self {
2665 if parity != Parity::None {
2666 self.uart
2667 .register_block()
2668 .conf0()
2669 .modify(|_, w| w.parity().bit((parity as u8 & 0x1) != 0));
2670 }
2671
2672 self.uart
2673 .register_block()
2674 .conf0()
2675 .modify(|_, w| match parity {
2676 Parity::None => w.parity_en().clear_bit(),
2677 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2678 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2679 });
2680
2681 self
2682 }
2683
2684 fn change_data_bits(&mut self, data_bits: DataBits) -> &mut Self {
2685 self.uart
2686 .register_block()
2687 .conf0()
2688 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2689
2690 self.update();
2691 self
2692 }
2693
2694 fn change_stop_bits(&mut self, stop_bits: StopBits) -> &mut Self {
2695 self.uart
2696 .register_block()
2697 .conf0()
2698 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2699
2700 self.update();
2701 self
2702 }
2703
2704 fn change_tx_idle(&mut self, idle_num: u16) -> &mut Self {
2705 self.uart
2706 .register_block()
2707 .idle_conf()
2708 .modify(|_, w| unsafe { w.tx_idle_num().bits(idle_num) });
2709
2710 self.update();
2711 self
2712 }
2713 }
2714}
2715
2716pub trait Instance: crate::private::Sealed + any::Degrade {
2718 #[doc(hidden)]
2719 fn parts(&self) -> (&'static Info, &'static State);
2721
2722 #[inline(always)]
2724 #[doc(hidden)]
2725 fn info(&self) -> &'static Info {
2726 self.parts().0
2727 }
2728
2729 #[inline(always)]
2731 #[doc(hidden)]
2732 fn state(&self) -> &'static State {
2733 self.parts().1
2734 }
2735}
2736
2737#[doc(hidden)]
2739#[non_exhaustive]
2740pub struct Info {
2741 pub register_block: *const RegisterBlock,
2745
2746 pub peripheral: crate::system::Peripheral,
2748
2749 pub async_handler: InterruptHandler,
2751
2752 pub tx_signal: OutputSignal,
2754
2755 pub rx_signal: InputSignal,
2757
2758 pub cts_signal: InputSignal,
2760
2761 pub rts_signal: OutputSignal,
2763}
2764
2765#[doc(hidden)]
2767#[non_exhaustive]
2768pub struct State {
2769 pub rx_waker: AtomicWaker,
2771
2772 pub tx_waker: AtomicWaker,
2774
2775 pub is_rx_async: AtomicBool,
2777
2778 pub is_tx_async: AtomicBool,
2780
2781 #[cfg(uart_peripheral_controls_mem_clk)]
2783 pub mem_ref_count: AtomicUsize,
2784}
2785
2786impl Info {
2787 const UART_FIFO_SIZE: u16 = property!("uart.ram_size");
2790 const RX_FIFO_MAX_THRHD: u16 = Self::UART_FIFO_SIZE - 1;
2791 const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
2792
2793 pub fn regs(&self) -> &RegisterBlock {
2795 unsafe { &*self.register_block }
2796 }
2797
2798 fn enable_listen(&self, interrupts: EnumSet<UartInterrupt>, enable: bool) {
2800 let reg_block = self.regs();
2801
2802 reg_block.int_ena().modify(|_, w| {
2803 for interrupt in interrupts {
2804 match interrupt {
2805 UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable),
2806 UartInterrupt::TxDone => w.tx_done().bit(enable),
2807 UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable),
2808 UartInterrupt::RxTimeout => w.rxfifo_tout().bit(enable),
2809 };
2810 }
2811 w
2812 });
2813 }
2814
2815 fn interrupts(&self) -> EnumSet<UartInterrupt> {
2816 let mut res = EnumSet::new();
2817 let reg_block = self.regs();
2818
2819 let ints = reg_block.int_raw().read();
2820
2821 if ints.at_cmd_char_det().bit_is_set() {
2822 res.insert(UartInterrupt::AtCmd);
2823 }
2824 if ints.tx_done().bit_is_set() {
2825 res.insert(UartInterrupt::TxDone);
2826 }
2827 if ints.rxfifo_full().bit_is_set() {
2828 res.insert(UartInterrupt::RxFifoFull);
2829 }
2830 if ints.rxfifo_tout().bit_is_set() {
2831 res.insert(UartInterrupt::RxTimeout);
2832 }
2833
2834 res
2835 }
2836
2837 fn clear_interrupts(&self, interrupts: EnumSet<UartInterrupt>) {
2838 let reg_block = self.regs();
2839
2840 reg_block.int_clr().write(|w| {
2841 for interrupt in interrupts {
2842 match interrupt {
2843 UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(),
2844 UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
2845 UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(),
2846 UartInterrupt::RxTimeout => w.rxfifo_tout().clear_bit_by_one(),
2847 };
2848 }
2849 w
2850 });
2851 }
2852
2853 fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
2854 config.validate()?;
2855 self.change_baud(config)?;
2856 self.change_data_bits(config.data_bits);
2857 self.change_parity(config.parity);
2858 self.change_stop_bits(config.stop_bits);
2859 self.change_flow_control(config.sw_flow_ctrl, config.hw_flow_ctrl);
2860
2861 Ok(())
2862 }
2863
2864 fn enable_listen_tx(&self, events: EnumSet<TxEvent>, enable: bool) {
2865 self.regs().int_ena().modify(|_, w| {
2866 for event in events {
2867 match event {
2868 TxEvent::Done => w.tx_done().bit(enable),
2869 TxEvent::FiFoEmpty => w.txfifo_empty().bit(enable),
2870 };
2871 }
2872 w
2873 });
2874 }
2875
2876 fn tx_events(&self) -> EnumSet<TxEvent> {
2877 let pending_interrupts = self.regs().int_raw().read();
2878 let mut active_events = EnumSet::new();
2879
2880 if pending_interrupts.tx_done().bit_is_set() {
2881 active_events |= TxEvent::Done;
2882 }
2883 if pending_interrupts.txfifo_empty().bit_is_set() {
2884 active_events |= TxEvent::FiFoEmpty;
2885 }
2886
2887 active_events
2888 }
2889
2890 fn clear_tx_events(&self, events: impl Into<EnumSet<TxEvent>>) {
2891 let events = events.into();
2892 self.regs().int_clr().write(|w| {
2893 for event in events {
2894 match event {
2895 TxEvent::FiFoEmpty => w.txfifo_empty().clear_bit_by_one(),
2896 TxEvent::Done => w.tx_done().clear_bit_by_one(),
2897 };
2898 }
2899 w
2900 });
2901 }
2902
2903 fn enable_listen_rx(&self, events: EnumSet<RxEvent>, enable: bool) {
2904 self.regs().int_ena().modify(|_, w| {
2905 for event in events {
2906 match event {
2907 RxEvent::FifoFull => w.rxfifo_full().bit(enable),
2908 RxEvent::CmdCharDetected => w.at_cmd_char_det().bit(enable),
2909
2910 RxEvent::FifoOvf => w.rxfifo_ovf().bit(enable),
2911 RxEvent::FifoTout => w.rxfifo_tout().bit(enable),
2912 RxEvent::GlitchDetected => w.glitch_det().bit(enable),
2913 RxEvent::FrameError => w.frm_err().bit(enable),
2914 RxEvent::ParityError => w.parity_err().bit(enable),
2915 };
2916 }
2917 w
2918 });
2919 }
2920
2921 fn rx_events(&self) -> EnumSet<RxEvent> {
2922 let pending_interrupts = self.regs().int_raw().read();
2923 let mut active_events = EnumSet::new();
2924
2925 if pending_interrupts.rxfifo_full().bit_is_set() {
2926 active_events |= RxEvent::FifoFull;
2927 }
2928 if pending_interrupts.at_cmd_char_det().bit_is_set() {
2929 active_events |= RxEvent::CmdCharDetected;
2930 }
2931 if pending_interrupts.rxfifo_ovf().bit_is_set() {
2932 active_events |= RxEvent::FifoOvf;
2933 }
2934 if pending_interrupts.rxfifo_tout().bit_is_set() {
2935 active_events |= RxEvent::FifoTout;
2936 }
2937 if pending_interrupts.glitch_det().bit_is_set() {
2938 active_events |= RxEvent::GlitchDetected;
2939 }
2940 if pending_interrupts.frm_err().bit_is_set() {
2941 active_events |= RxEvent::FrameError;
2942 }
2943 if pending_interrupts.parity_err().bit_is_set() {
2944 active_events |= RxEvent::ParityError;
2945 }
2946
2947 active_events
2948 }
2949
2950 fn clear_rx_events(&self, events: impl Into<EnumSet<RxEvent>>) {
2951 let events = events.into();
2952 self.regs().int_clr().write(|w| {
2953 for event in events {
2954 match event {
2955 RxEvent::FifoFull => w.rxfifo_full().clear_bit_by_one(),
2956 RxEvent::CmdCharDetected => w.at_cmd_char_det().clear_bit_by_one(),
2957
2958 RxEvent::FifoOvf => w.rxfifo_ovf().clear_bit_by_one(),
2959 RxEvent::FifoTout => w.rxfifo_tout().clear_bit_by_one(),
2960 RxEvent::GlitchDetected => w.glitch_det().clear_bit_by_one(),
2961 RxEvent::FrameError => w.frm_err().clear_bit_by_one(),
2962 RxEvent::ParityError => w.parity_err().clear_bit_by_one(),
2963 };
2964 }
2965 w
2966 });
2967 }
2968
2969 fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
2976 if threshold > Self::RX_FIFO_MAX_THRHD {
2977 return Err(ConfigError::RxFifoThresholdNotSupported);
2978 }
2979
2980 self.regs()
2981 .conf1()
2982 .modify(|_, w| unsafe { w.rxfifo_full_thrhd().bits(threshold as _) });
2983
2984 Ok(())
2985 }
2986
2987 #[allow(clippy::useless_conversion)]
2989 fn rx_fifo_full_threshold(&self) -> u16 {
2990 self.regs().conf1().read().rxfifo_full_thrhd().bits().into()
2991 }
2992
2993 fn set_tx_fifo_empty_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3000 if threshold > Self::TX_FIFO_MAX_THRHD {
3001 return Err(ConfigError::TxFifoThresholdNotSupported);
3002 }
3003
3004 self.regs()
3005 .conf1()
3006 .modify(|_, w| unsafe { w.txfifo_empty_thrhd().bits(threshold as _) });
3007
3008 Ok(())
3009 }
3010
3011 fn set_rx_timeout(&self, timeout: Option<u8>, _symbol_len: u8) -> Result<(), ConfigError> {
3026 cfg_if::cfg_if! {
3027 if #[cfg(esp32)] {
3028 const MAX_THRHD: u8 = 0x7F; } else {
3030 const MAX_THRHD: u16 = 0x3FF; }
3032 }
3033
3034 let register_block = self.regs();
3035
3036 if let Some(timeout) = timeout {
3037 #[cfg(esp32)]
3039 let timeout_reg = timeout;
3040 #[cfg(not(esp32))]
3042 let timeout_reg = timeout as u16 * _symbol_len as u16;
3043
3044 if timeout_reg > MAX_THRHD {
3045 return Err(ConfigError::TimeoutTooLong);
3046 }
3047
3048 cfg_if::cfg_if! {
3049 if #[cfg(esp32)] {
3050 let reg_thrhd = register_block.conf1();
3051 } else if #[cfg(any(esp32c6, esp32h2))] {
3052 let reg_thrhd = register_block.tout_conf();
3053 } else {
3054 let reg_thrhd = register_block.mem_conf();
3055 }
3056 }
3057 reg_thrhd.modify(|_, w| unsafe { w.rx_tout_thrhd().bits(timeout_reg) });
3058 }
3059
3060 cfg_if::cfg_if! {
3061 if #[cfg(any(esp32c6, esp32h2))] {
3062 let reg_en = register_block.tout_conf();
3063 } else {
3064 let reg_en = register_block.conf1();
3065 }
3066 }
3067 reg_en.modify(|_, w| w.rx_tout_en().bit(timeout.is_some()));
3068
3069 self.sync_regs();
3070
3071 Ok(())
3072 }
3073
3074 #[cfg(soc_has_pcr)]
3075 fn is_instance(&self, other: impl Instance) -> bool {
3076 self == other.info()
3077 }
3078
3079 fn sync_regs(&self) {
3080 sync_regs(self.regs());
3081 }
3082
3083 fn change_baud(&self, config: &Config) -> Result<(), ConfigError> {
3084 let clocks = Clocks::get();
3085 let clk = match config.clock_source {
3086 ClockSource::Apb => clocks.apb_clock.as_hz(),
3087 #[cfg(not(any(esp32, esp32s2)))]
3088 ClockSource::Xtal => clocks.xtal_clock.as_hz(),
3089 #[cfg(not(any(esp32, esp32s2)))]
3090 ClockSource::RcFast => property!("soc.rc_fast_clk_default"), #[cfg(soc_ref_tick_hz_is_set)]
3092 ClockSource::RefTick => property!("soc.ref_tick_hz"),
3093 };
3094
3095 cfg_if::cfg_if! {
3096 if #[cfg(any(esp32c2, esp32c3, esp32s3, esp32c6, esp32h2))] {
3097
3098 const MAX_DIV: u32 = 0b1111_1111_1111 - 1;
3099 let clk_div = (clk.div_ceil(MAX_DIV)).div_ceil(config.baudrate);
3100
3101 cfg_if::cfg_if! {
3103 if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
3104 if matches!(config.clock_source, ClockSource::RcFast) {
3105 crate::peripherals::LPWR::regs()
3106 .clk_conf()
3107 .modify(|_, w| w.dig_clk8m_en().variant(true));
3108 crate::rom::ets_delay_us(5);
3110 }
3111
3112 let conf = self.regs().clk_conf();
3113 } else {
3114 let pcr = crate::peripherals::PCR::regs();
3116 let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
3117 pcr.uart(0).clk_conf()
3118 } else {
3119 pcr.uart(1).clk_conf()
3120 };
3121 }
3122 };
3123
3124 conf.write(|w| unsafe {
3125 w.sclk_sel().bits(match config.clock_source {
3126 ClockSource::Apb => 1,
3127 ClockSource::RcFast => 2,
3128 ClockSource::Xtal => 3,
3129 });
3130 w.sclk_div_a().bits(0);
3131 w.sclk_div_b().bits(0);
3132 w.sclk_div_num().bits(clk_div as u8 - 1)
3133 });
3134
3135 let divider = (clk << 4) / (config.baudrate * clk_div);
3136 } else {
3137 self.regs().conf0().modify(|_, w| {
3138 w.tick_ref_always_on()
3139 .bit(config.clock_source == ClockSource::Apb)
3140 });
3141
3142 let divider = (clk << 4) / config.baudrate;
3143 }
3144 }
3145
3146 let divider_integer = divider >> 4;
3147 let divider_frag = (divider & 0xf) as u8;
3148
3149 self.regs().clkdiv().write(|w| unsafe {
3150 w.clkdiv()
3151 .bits(divider_integer as _)
3152 .frag()
3153 .bits(divider_frag)
3154 });
3155
3156 self.sync_regs();
3157
3158 #[cfg(feature = "unstable")]
3159 self.verify_baudrate(clk, config)?;
3160
3161 Ok(())
3162 }
3163
3164 fn change_data_bits(&self, data_bits: DataBits) {
3165 self.regs()
3166 .conf0()
3167 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
3168 }
3169
3170 fn change_parity(&self, parity: Parity) {
3171 self.regs().conf0().modify(|_, w| match parity {
3172 Parity::None => w.parity_en().clear_bit(),
3173 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
3174 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
3175 });
3176 }
3177
3178 fn change_stop_bits(&self, stop_bits: StopBits) {
3179 #[cfg(esp32)]
3180 {
3181 if stop_bits == StopBits::_2 {
3183 self.regs()
3184 .rs485_conf()
3185 .modify(|_, w| w.dl1_en().bit(stop_bits == StopBits::_2));
3186
3187 self.regs()
3188 .conf0()
3189 .modify(|_, w| unsafe { w.stop_bit_num().bits(1) });
3190 }
3191 }
3192
3193 #[cfg(not(esp32))]
3194 self.regs()
3195 .conf0()
3196 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
3197 }
3198
3199 fn change_flow_control(&self, sw_flow_ctrl: SwFlowControl, hw_flow_ctrl: HwFlowControl) {
3200 match sw_flow_ctrl {
3202 SwFlowControl::Enabled {
3203 xon_char,
3204 xoff_char,
3205 xon_threshold,
3206 xoff_threshold,
3207 } => {
3208 cfg_if::cfg_if! {
3209 if #[cfg(any(esp32c6, esp32h2))] {
3210 self.regs().swfc_conf0().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3211 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold)});
3212 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3213 } else if #[cfg(esp32)]{
3214 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3215 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold) });
3216 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3217 } else {
3218 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3219 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold as u16) });
3220 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_threshold().bits(xoff_threshold as u16) });
3221 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_char().bits(xon_char) });
3222 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_char().bits(xoff_char) });
3223 }
3224 }
3225 }
3226 SwFlowControl::Disabled => {
3227 cfg_if::cfg_if! {
3228 if #[cfg(any(esp32c6, esp32h2))] {
3229 let reg = self.regs().swfc_conf0();
3230 } else {
3231 let reg = self.regs().flow_conf();
3232 }
3233 }
3234
3235 reg.modify(|_, w| w.sw_flow_con_en().clear_bit());
3236 reg.modify(|_, w| w.xonoff_del().clear_bit());
3237 }
3238 }
3239
3240 self.regs().conf0().modify(|_, w| {
3241 w.tx_flow_en()
3242 .bit(matches!(hw_flow_ctrl.cts, CtsConfig::Enabled))
3243 });
3244
3245 match hw_flow_ctrl.rts {
3246 RtsConfig::Enabled(threshold) => self.configure_rts_flow_ctrl(true, Some(threshold)),
3247 RtsConfig::Disabled => self.configure_rts_flow_ctrl(false, None),
3248 }
3249
3250 #[cfg(any(esp32c6, esp32h2))]
3251 sync_regs(self.regs());
3252 }
3253
3254 fn configure_rts_flow_ctrl(&self, enable: bool, threshold: Option<u8>) {
3255 if let Some(threshold) = threshold {
3256 cfg_if::cfg_if! {
3257 if #[cfg(esp32)] {
3258 self.regs().conf1().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3259 } else if #[cfg(any(esp32c6, esp32h2))] {
3260 self.regs().hwfc_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3261 } else {
3262 self.regs().mem_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold as u16) });
3263 }
3264 }
3265 }
3266
3267 cfg_if::cfg_if! {
3268 if #[cfg(any(esp32c6, esp32h2))] {
3269 self.regs().hwfc_conf().modify(|_, w| {
3270 w.rx_flow_en().bit(enable)
3271 });
3272 } else {
3273 self.regs().conf1().modify(|_, w| {
3274 w.rx_flow_en().bit(enable)
3275 });
3276 }
3277 }
3278 }
3279
3280 fn rxfifo_reset(&self) {
3281 fn rxfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3282 reg_block.conf0().modify(|_, w| w.rxfifo_rst().bit(enable));
3283 sync_regs(reg_block);
3284 }
3285
3286 rxfifo_rst(self.regs(), true);
3287 rxfifo_rst(self.regs(), false);
3288 }
3289
3290 fn txfifo_reset(&self) {
3291 fn txfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3292 reg_block.conf0().modify(|_, w| w.txfifo_rst().bit(enable));
3293 sync_regs(reg_block);
3294 }
3295
3296 txfifo_rst(self.regs(), true);
3297 txfifo_rst(self.regs(), false);
3298 }
3299
3300 #[cfg(feature = "unstable")]
3301 fn verify_baudrate(&self, clk: u32, config: &Config) -> Result<(), ConfigError> {
3302 let clkdiv_reg = self.regs().clkdiv().read();
3305 let clkdiv_frag = clkdiv_reg.frag().bits() as u32;
3306 let clkdiv = clkdiv_reg.clkdiv().bits();
3307
3308 cfg_if::cfg_if! {
3309 if #[cfg(any(esp32, esp32s2))] {
3310 let actual_baud = (clk << 4) / ((clkdiv << 4) | clkdiv_frag);
3311 } else if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
3312 let sclk_div_num = self.regs().clk_conf().read().sclk_div_num().bits() as u32;
3313 let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
3314 } else { let pcr = crate::peripherals::PCR::regs();
3316 let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
3317 pcr.uart(0).clk_conf()
3318 } else {
3319 pcr.uart(1).clk_conf()
3320 };
3321 let sclk_div_num = conf.read().sclk_div_num().bits() as u32;
3322 let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
3323 }
3324 };
3325
3326 match config.baudrate_tolerance {
3327 BaudrateTolerance::Exact => {
3328 let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
3329 * 100)
3330 / actual_baud;
3331 if deviation > 1_u32 {
3334 return Err(ConfigError::BaudrateNotAchievable);
3335 }
3336 }
3337 BaudrateTolerance::ErrorPercent(percent) => {
3338 let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
3339 * 100)
3340 / actual_baud;
3341 if deviation > percent as u32 {
3342 return Err(ConfigError::BaudrateNotAchievable);
3343 }
3344 }
3345 _ => {}
3346 }
3347
3348 Ok(())
3349 }
3350
3351 fn current_symbol_length(&self) -> u8 {
3352 let conf0 = self.regs().conf0().read();
3353 let data_bits = conf0.bit_num().bits() + 5; let parity = conf0.parity_en().bit() as u8;
3355 let mut stop_bits = conf0.stop_bit_num().bits();
3356
3357 match stop_bits {
3358 1 => {
3359 #[cfg(esp32)]
3361 if self.regs().rs485_conf().read().dl1_en().bit_is_set() {
3362 stop_bits = 2;
3363 }
3364 }
3365 _ => stop_bits = 2,
3367 }
3368
3369 1 + data_bits + parity + stop_bits
3370 }
3371
3372 fn read_next_from_fifo(&self) -> u8 {
3376 fn access_fifo_register<R>(f: impl Fn() -> R) -> R {
3377 cfg_if::cfg_if! {
3379 if #[cfg(esp32)] {
3380 crate::interrupt::free(f)
3381 } else {
3382 f()
3383 }
3384 }
3385 }
3386
3387 let fifo_reg = self.regs().fifo();
3388 cfg_if::cfg_if! {
3389 if #[cfg(esp32s2)] {
3390 let fifo_reg = unsafe {
3392 &*fifo_reg.as_ptr().cast::<u8>().add(0x20C00000).cast::<crate::pac::uart0::FIFO>()
3393 };
3394 }
3395 }
3396
3397 access_fifo_register(|| fifo_reg.read().rxfifo_rd_byte().bits())
3398 }
3399
3400 #[allow(clippy::useless_conversion)]
3401 fn tx_fifo_count(&self) -> u16 {
3402 u16::from(self.regs().status().read().txfifo_cnt().bits())
3403 }
3404
3405 fn write_byte(&self, byte: u8) {
3406 self.regs()
3407 .fifo()
3408 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
3409 }
3410
3411 fn check_for_errors(&self) -> Result<(), RxError> {
3412 let errors = RxEvent::FifoOvf
3413 | RxEvent::FifoTout
3414 | RxEvent::GlitchDetected
3415 | RxEvent::FrameError
3416 | RxEvent::ParityError;
3417 let events = self.rx_events().intersection(errors);
3418 let result = rx_event_check_for_error(events);
3419 if result.is_err() {
3420 self.clear_rx_events(errors);
3421 if events.contains(RxEvent::FifoOvf) {
3422 self.rxfifo_reset();
3423 }
3424 }
3425 result
3426 }
3427
3428 #[cfg(not(esp32))]
3429 #[allow(clippy::unnecessary_cast)]
3430 fn rx_fifo_count(&self) -> u16 {
3431 self.regs().status().read().rxfifo_cnt().bits() as u16
3432 }
3433
3434 #[cfg(esp32)]
3435 fn rx_fifo_count(&self) -> u16 {
3436 let fifo_cnt = self.regs().status().read().rxfifo_cnt().bits();
3437
3438 let status = self.regs().mem_rx_status().read();
3441 let rd_addr: u16 = status.mem_rx_rd_addr().bits();
3442 let wr_addr: u16 = status.mem_rx_wr_addr().bits();
3443
3444 if wr_addr > rd_addr {
3445 wr_addr - rd_addr
3446 } else if wr_addr < rd_addr {
3447 (wr_addr + Info::UART_FIFO_SIZE) - rd_addr
3448 } else if fifo_cnt > 0 {
3449 Info::UART_FIFO_SIZE
3450 } else {
3451 0
3452 }
3453 }
3454
3455 fn write(&self, data: &[u8]) -> Result<usize, TxError> {
3456 if data.is_empty() {
3457 return Ok(0);
3458 }
3459
3460 while self.tx_fifo_count() >= Info::UART_FIFO_SIZE {}
3461
3462 let space = (Info::UART_FIFO_SIZE - self.tx_fifo_count()) as usize;
3463 let to_write = space.min(data.len());
3464 for &byte in &data[..to_write] {
3465 self.write_byte(byte);
3466 }
3467
3468 Ok(to_write)
3469 }
3470
3471 fn read(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3472 if buf.is_empty() {
3473 return Ok(0);
3474 }
3475
3476 while self.rx_fifo_count() == 0 {
3477 self.check_for_errors()?;
3479 }
3480
3481 self.read_buffered(buf)
3482 }
3483
3484 fn read_buffered(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3485 let to_read = (self.rx_fifo_count() as usize).min(buf.len());
3488 self.check_for_errors()?;
3489
3490 for byte_into in buf[..to_read].iter_mut() {
3491 *byte_into = self.read_next_from_fifo();
3492 }
3493
3494 Ok(to_read)
3495 }
3496}
3497
3498impl PartialEq for Info {
3499 fn eq(&self, other: &Self) -> bool {
3500 core::ptr::eq(self.register_block, other.register_block)
3501 }
3502}
3503
3504unsafe impl Sync for Info {}
3505
3506for_each_uart! {
3507 ($inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident) => {
3508 impl Instance for crate::peripherals::$inst<'_> {
3509 fn parts(&self) -> (&'static Info, &'static State) {
3510 #[crate::handler]
3511 pub(super) fn irq_handler() {
3512 intr_handler(&PERIPHERAL, &STATE);
3513 }
3514
3515 static STATE: State = State {
3516 tx_waker: AtomicWaker::new(),
3517 rx_waker: AtomicWaker::new(),
3518 is_rx_async: AtomicBool::new(false),
3519 is_tx_async: AtomicBool::new(false),
3520 #[cfg(uart_peripheral_controls_mem_clk)]
3521 mem_ref_count: AtomicUsize::new(0),
3522 };
3523
3524 static PERIPHERAL: Info = Info {
3525 register_block: crate::peripherals::$inst::ptr(),
3526 peripheral: crate::system::Peripheral::$peri,
3527 async_handler: irq_handler,
3528 tx_signal: OutputSignal::$txd,
3529 rx_signal: InputSignal::$rxd,
3530 cts_signal: InputSignal::$cts,
3531 rts_signal: OutputSignal::$rts,
3532 };
3533 (&PERIPHERAL, &STATE)
3534 }
3535 }
3536 };
3537}
3538
3539crate::any_peripheral! {
3540 pub peripheral AnyUart<'d> {
3542 #[cfg(soc_has_uart0)]
3543 Uart0(crate::peripherals::UART0<'d>),
3544 #[cfg(soc_has_uart1)]
3545 Uart1(crate::peripherals::UART1<'d>),
3546 #[cfg(soc_has_uart2)]
3547 Uart2(crate::peripherals::UART2<'d>),
3548 }
3549}
3550
3551impl Instance for AnyUart<'_> {
3552 #[inline]
3553 fn parts(&self) -> (&'static Info, &'static State) {
3554 any::delegate!(self, uart => { uart.parts() })
3555 }
3556}
3557
3558impl AnyUart<'_> {
3559 fn bind_peri_interrupt(&self, handler: crate::interrupt::IsrCallback) {
3560 any::delegate!(self, uart => { uart.bind_peri_interrupt(handler) })
3561 }
3562
3563 fn disable_peri_interrupt(&self) {
3564 any::delegate!(self, uart => { uart.disable_peri_interrupt() })
3565 }
3566
3567 fn enable_peri_interrupt(&self, priority: crate::interrupt::Priority) {
3568 any::delegate!(self, uart => { uart.enable_peri_interrupt(priority) })
3569 }
3570
3571 fn set_interrupt_handler(&self, handler: InterruptHandler) {
3572 self.disable_peri_interrupt();
3573
3574 self.info().enable_listen(EnumSet::all(), false);
3575 self.info().clear_interrupts(EnumSet::all());
3576
3577 self.bind_peri_interrupt(handler.handler());
3578 self.enable_peri_interrupt(handler.priority());
3579 }
3580}
3581
3582cfg_if::cfg_if! {
3589 if #[cfg(uart_peripheral_controls_mem_clk)] {
3590 use portable_atomic::AtomicUsize;
3592
3593 struct MemoryGuard<'t> {
3594 uart: AnyUart<'t>
3595 }
3596
3597 impl<'t> MemoryGuard<'t> {
3598 fn new(uart: AnyUart<'t>) -> Self {
3599 let this = Self { uart };
3600
3601 if this.refcount().fetch_add(1, Ordering::SeqCst) == 0 {
3602 this.enable_memory_clk(true);
3603 }
3604
3605 this
3606 }
3607
3608 fn enable_memory_clk(&self, clk: bool) {
3609 self.uart.info().regs().conf0().modify(|_, w| w.mem_clk_en().bit(clk));
3610 }
3611
3612 fn refcount(&self) -> &AtomicUsize {
3613 &self.uart.state().mem_ref_count
3614 }
3615 }
3616
3617 impl Clone for MemoryGuard<'_> {
3618 fn clone(&self) -> Self {
3619 self.refcount().fetch_add(1, Ordering::SeqCst);
3620
3621 Self { uart: unsafe { self.uart.clone_unchecked() } }
3622 }
3623 }
3624
3625 impl Drop for MemoryGuard<'_> {
3626 fn drop(&mut self) {
3627 if self.refcount().fetch_sub(1, Ordering::SeqCst) == 1 {
3628 self.enable_memory_clk(false);
3629 }
3630 }
3631 }
3632
3633 fn create_mem_guard(uart: AnyUart<'_>) -> MemoryGuard<'_> {
3634 MemoryGuard::new(uart)
3635 }
3636 } else {
3637 use crate::system::{Peripheral, GenericPeripheralGuard};
3639 type MemoryGuard<'t> = GenericPeripheralGuard<{ Peripheral::UartMem as u8 }>;
3640
3641 fn create_mem_guard(_uart: AnyUart<'_>) -> MemoryGuard<'_> {
3642 MemoryGuard::new()
3643 }
3644 }
3645}