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::{PeripheralClockControl, 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.parts().0.peripheral);
468 let tx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
469
470 let rts_pin = PinGuard::new_unconnected(self.uart.info().rts_signal);
471 let tx_pin = PinGuard::new_unconnected(self.uart.info().tx_signal);
472
473 let mut serial = Uart {
474 rx: UartRx {
475 uart: unsafe { self.uart.clone_unchecked() },
476 phantom: PhantomData,
477 guard: rx_guard,
478 },
479 tx: UartTx {
480 uart: self.uart,
481 phantom: PhantomData,
482 guard: tx_guard,
483 rts_pin,
484 tx_pin,
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 rts_pin: PinGuard,
520 tx_pin: PinGuard,
521}
522
523#[instability::unstable]
525pub struct UartRx<'d, Dm: DriverMode> {
526 uart: AnyUart<'d>,
527 phantom: PhantomData<Dm>,
528 guard: PeripheralGuard,
529}
530
531#[derive(Debug, Clone, Copy, PartialEq, Eq)]
533#[cfg_attr(feature = "defmt", derive(defmt::Format))]
534#[non_exhaustive]
535pub enum ConfigError {
536 #[cfg(feature = "unstable")]
538 #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
539 BaudrateNotAchievable,
540
541 BaudrateNotSupported,
548
549 #[cfg_attr(esp32, doc = "127")]
551 #[cfg_attr(not(esp32), doc = "1023")]
552 TimeoutTooLong,
554
555 RxFifoThresholdNotSupported,
557
558 TxFifoThresholdNotSupported,
560}
561
562impl core::error::Error for ConfigError {}
563
564impl core::fmt::Display for ConfigError {
565 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
566 match self {
567 #[cfg(feature = "unstable")]
568 ConfigError::BaudrateNotAchievable => {
569 write!(f, "The requested baud rate is not achievable")
570 }
571 ConfigError::BaudrateNotSupported => {
572 write!(f, "The requested baud rate is not supported")
573 }
574 ConfigError::TimeoutTooLong => write!(f, "The requested timeout is not supported"),
575 ConfigError::RxFifoThresholdNotSupported => {
576 write!(f, "The requested RX FIFO threshold is not supported")
577 }
578 ConfigError::TxFifoThresholdNotSupported => {
579 write!(f, "The requested TX FIFO threshold is not supported")
580 }
581 }
582 }
583}
584
585#[instability::unstable]
586impl<Dm> embassy_embedded_hal::SetConfig for Uart<'_, Dm>
587where
588 Dm: DriverMode,
589{
590 type Config = Config;
591 type ConfigError = ConfigError;
592
593 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
594 self.apply_config(config)
595 }
596}
597
598#[instability::unstable]
599impl<Dm> embassy_embedded_hal::SetConfig for UartRx<'_, Dm>
600where
601 Dm: DriverMode,
602{
603 type Config = Config;
604 type ConfigError = ConfigError;
605
606 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
607 self.apply_config(config)
608 }
609}
610
611#[instability::unstable]
612impl<Dm> embassy_embedded_hal::SetConfig for UartTx<'_, Dm>
613where
614 Dm: DriverMode,
615{
616 type Config = Config;
617 type ConfigError = ConfigError;
618
619 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
620 self.apply_config(config)
621 }
622}
623
624impl<'d> UartTx<'d, Blocking> {
625 #[procmacros::doc_replace]
626 #[instability::unstable]
642 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
643 let (_, uart_tx) = UartBuilder::new(uart).init(config)?.split();
644
645 Ok(uart_tx)
646 }
647
648 #[instability::unstable]
650 pub fn into_async(self) -> UartTx<'d, Async> {
651 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
652 self.uart
653 .set_interrupt_handler(self.uart.info().async_handler);
654 }
655 self.uart.state().is_tx_async.store(true, Ordering::Release);
656
657 UartTx {
658 uart: self.uart,
659 phantom: PhantomData,
660 guard: self.guard,
661 rts_pin: self.rts_pin,
662 tx_pin: self.tx_pin,
663 }
664 }
665}
666
667impl<'d> UartTx<'d, Async> {
668 #[instability::unstable]
670 pub fn into_blocking(self) -> UartTx<'d, Blocking> {
671 self.uart
672 .state()
673 .is_tx_async
674 .store(false, Ordering::Release);
675 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
676 self.uart.disable_peri_interrupt();
677 }
678
679 UartTx {
680 uart: self.uart,
681 phantom: PhantomData,
682 guard: self.guard,
683 rts_pin: self.rts_pin,
684 tx_pin: self.tx_pin,
685 }
686 }
687
688 pub async fn write_async(&mut self, bytes: &[u8]) -> Result<usize, TxError> {
704 let space = loop {
707 let tx_fifo_count = self.uart.info().tx_fifo_count();
708 let space = Info::UART_FIFO_SIZE - tx_fifo_count;
709 if space != 0 {
710 break space;
711 }
712 UartTxFuture::new(self.uart.reborrow(), TxEvent::FiFoEmpty).await;
713 };
714
715 let free = (space as usize).min(bytes.len());
716
717 for &byte in &bytes[..free] {
718 self.uart
719 .info()
720 .regs()
721 .fifo()
722 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
723 }
724
725 Ok(free)
726 }
727
728 pub async fn flush_async(&mut self) -> Result<(), TxError> {
738 while self.uart.info().tx_fifo_count() > 0 {
742 UartTxFuture::new(self.uart.reborrow(), TxEvent::Done).await;
743 }
744
745 self.flush_last_byte();
746
747 Ok(())
748 }
749}
750
751impl<'d, Dm> UartTx<'d, Dm>
752where
753 Dm: DriverMode,
754{
755 #[instability::unstable]
757 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
758 let rts = rts.into();
759
760 rts.apply_output_config(&OutputConfig::default());
761 rts.set_output_enable(true);
762
763 self.rts_pin = rts.connect_with_guard(self.uart.info().rts_signal);
764
765 self
766 }
767
768 #[instability::unstable]
775 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
776 let tx = tx.into();
777
778 tx.set_output_high(true);
780 tx.apply_output_config(&OutputConfig::default());
781 tx.set_output_enable(true);
782
783 self.tx_pin = tx.connect_with_guard(self.uart.info().tx_signal);
784
785 self
786 }
787
788 #[instability::unstable]
795 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
796 self.uart
797 .info()
798 .set_tx_fifo_empty_threshold(config.tx.fifo_empty_threshold)?;
799 self.uart.info().txfifo_reset();
800 Ok(())
801 }
802
803 #[instability::unstable]
807 pub fn write_ready(&mut self) -> bool {
808 self.uart.info().tx_fifo_count() < Info::UART_FIFO_SIZE
809 }
810
811 #[instability::unstable]
825 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
826 self.uart.info().write(data)
827 }
828
829 fn write_all(&mut self, mut data: &[u8]) -> Result<(), TxError> {
830 while !data.is_empty() {
831 let bytes_written = self.write(data)?;
832 data = &data[bytes_written..];
833 }
834 Ok(())
835 }
836
837 #[instability::unstable]
842 pub fn flush(&mut self) -> Result<(), TxError> {
843 while self.uart.info().tx_fifo_count() > 0 {}
844 self.flush_last_byte();
845 Ok(())
846 }
847
848 fn flush_last_byte(&mut self) {
849 crate::rom::ets_delay_us(10);
855 while !self.is_tx_idle() {}
856 }
857
858 fn is_tx_idle(&self) -> bool {
863 #[cfg(esp32)]
864 let status = self.regs().status();
865 #[cfg(not(esp32))]
866 let status = self.regs().fsm_status();
867
868 status.read().st_utx_out().bits() == 0x0
869 }
870
871 fn disable_tx_interrupts(&self) {
877 self.regs().int_clr().write(|w| {
878 w.txfifo_empty().clear_bit_by_one();
879 w.tx_brk_done().clear_bit_by_one();
880 w.tx_brk_idle_done().clear_bit_by_one();
881 w.tx_done().clear_bit_by_one()
882 });
883
884 self.regs().int_ena().write(|w| {
885 w.txfifo_empty().clear_bit();
886 w.tx_brk_done().clear_bit();
887 w.tx_brk_idle_done().clear_bit();
888 w.tx_done().clear_bit()
889 });
890 }
891
892 fn regs(&self) -> &RegisterBlock {
893 self.uart.info().regs()
894 }
895}
896
897#[inline(always)]
898fn sync_regs(_register_block: &RegisterBlock) {
899 #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
900 {
901 cfg_if::cfg_if! {
902 if #[cfg(any(esp32c6, esp32h2))] {
903 let update_reg = _register_block.reg_update();
904 } else {
905 let update_reg = _register_block.id();
906 }
907 }
908
909 update_reg.modify(|_, w| w.reg_update().set_bit());
910
911 while update_reg.read().reg_update().bit_is_set() {
912 }
914 }
915}
916
917impl<'d> UartRx<'d, Blocking> {
918 #[procmacros::doc_replace]
919 #[instability::unstable]
933 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
934 let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();
935
936 Ok(uart_rx)
937 }
938
939 #[instability::unstable]
941 pub fn into_async(self) -> UartRx<'d, Async> {
942 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
943 self.uart
944 .set_interrupt_handler(self.uart.info().async_handler);
945 }
946 self.uart.state().is_rx_async.store(true, Ordering::Release);
947
948 UartRx {
949 uart: self.uart,
950 phantom: PhantomData,
951 guard: self.guard,
952 }
953 }
954}
955
956impl<'d> UartRx<'d, Async> {
957 #[instability::unstable]
959 pub fn into_blocking(self) -> UartRx<'d, Blocking> {
960 self.uart
961 .state()
962 .is_rx_async
963 .store(false, Ordering::Release);
964 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
965 self.uart.disable_peri_interrupt();
966 }
967
968 UartRx {
969 uart: self.uart,
970 phantom: PhantomData,
971 guard: self.guard,
972 }
973 }
974
975 async fn wait_for_buffered_data(
976 &mut self,
977 minimum: usize,
978 preferred: usize,
979 listen_for_timeout: bool,
980 ) -> Result<(), RxError> {
981 while self.uart.info().rx_fifo_count() < (minimum as u16).min(Info::RX_FIFO_MAX_THRHD) {
982 let amount = u16::try_from(preferred)
983 .unwrap_or(Info::RX_FIFO_MAX_THRHD)
984 .min(Info::RX_FIFO_MAX_THRHD);
985
986 let current = self.uart.info().rx_fifo_full_threshold();
987 let _guard = if current > amount {
988 let info = self.uart.info();
992 unwrap!(info.set_rx_fifo_full_threshold(amount));
993 Some(OnDrop::new(|| {
994 unwrap!(info.set_rx_fifo_full_threshold(current));
995 }))
996 } else {
997 None
998 };
999
1000 let mut events = RxEvent::FifoFull
1002 | RxEvent::FifoOvf
1003 | RxEvent::FrameError
1004 | RxEvent::GlitchDetected
1005 | RxEvent::ParityError;
1006
1007 if self.regs().at_cmd_char().read().char_num().bits() > 0 {
1008 events |= RxEvent::CmdCharDetected;
1009 }
1010
1011 cfg_if::cfg_if! {
1012 if #[cfg(any(esp32c6, esp32h2))] {
1013 let reg_en = self.regs().tout_conf();
1014 } else {
1015 let reg_en = self.regs().conf1();
1016 }
1017 };
1018 if listen_for_timeout && reg_en.read().rx_tout_en().bit_is_set() {
1019 events |= RxEvent::FifoTout;
1020 }
1021
1022 let events = UartRxFuture::new(self.uart.reborrow(), events).await;
1023
1024 let result = rx_event_check_for_error(events);
1025 if let Err(error) = result {
1026 if error == RxError::FifoOverflowed {
1027 self.uart.info().rxfifo_reset();
1028 }
1029 return Err(error);
1030 }
1031 }
1032
1033 Ok(())
1034 }
1035
1036 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1055 if buf.is_empty() {
1056 return Ok(0);
1057 }
1058
1059 self.wait_for_buffered_data(1, buf.len(), true).await?;
1060
1061 self.read_buffered(buf)
1062 }
1063
1064 pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
1079 while !buf.is_empty() {
1080 self.wait_for_buffered_data(buf.len(), buf.len(), false)
1084 .await?;
1085
1086 let read = self.uart.info().read_buffered(buf)?;
1087 buf = &mut buf[read..];
1088 }
1089
1090 Ok(())
1091 }
1092}
1093
1094impl<'d, Dm> UartRx<'d, Dm>
1095where
1096 Dm: DriverMode,
1097{
1098 fn regs(&self) -> &RegisterBlock {
1099 self.uart.info().regs()
1100 }
1101
1102 #[instability::unstable]
1106 pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
1107 let cts = cts.into();
1108
1109 cts.apply_input_config(&InputConfig::default());
1110 cts.set_input_enable(true);
1111
1112 self.uart.info().cts_signal.connect_to(&cts);
1113
1114 self
1115 }
1116
1117 #[instability::unstable]
1126 pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
1127 let rx = rx.into();
1128
1129 rx.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
1130 rx.set_input_enable(true);
1131
1132 self.uart.info().rx_signal.connect_to(&rx);
1133
1134 self
1135 }
1136
1137 #[instability::unstable]
1144 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1145 self.uart
1146 .info()
1147 .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
1148 self.uart
1149 .info()
1150 .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
1151
1152 self.uart.info().rxfifo_reset();
1153 Ok(())
1154 }
1155
1156 #[instability::unstable]
1160 pub fn check_for_errors(&mut self) -> Result<(), RxError> {
1161 self.uart.info().check_for_errors()
1162 }
1163
1164 #[instability::unstable]
1168 pub fn read_ready(&mut self) -> bool {
1169 self.uart.info().rx_fifo_count() > 0
1170 }
1171
1172 #[instability::unstable]
1191 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1192 self.uart.info().read(buf)
1193 }
1194
1195 #[instability::unstable]
1213 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1214 self.uart.info().read_buffered(buf)
1215 }
1216
1217 fn disable_rx_interrupts(&self) {
1223 self.regs().int_clr().write(|w| {
1224 w.rxfifo_full().clear_bit_by_one();
1225 w.rxfifo_ovf().clear_bit_by_one();
1226 w.rxfifo_tout().clear_bit_by_one();
1227 w.at_cmd_char_det().clear_bit_by_one()
1228 });
1229
1230 self.regs().int_ena().write(|w| {
1231 w.rxfifo_full().clear_bit();
1232 w.rxfifo_ovf().clear_bit();
1233 w.rxfifo_tout().clear_bit();
1234 w.at_cmd_char_det().clear_bit()
1235 });
1236 }
1237}
1238
1239impl<'d> Uart<'d, Blocking> {
1240 #[procmacros::doc_replace]
1241 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1259 UartBuilder::new(uart).init(config)
1260 }
1261
1262 pub fn into_async(self) -> Uart<'d, Async> {
1267 Uart {
1268 rx: self.rx.into_async(),
1269 tx: self.tx.into_async(),
1270 }
1271 }
1272
1273 #[cfg_attr(
1274 not(multi_core),
1275 doc = "Registers an interrupt handler for the peripheral."
1276 )]
1277 #[cfg_attr(
1278 multi_core,
1279 doc = "Registers an interrupt handler for the peripheral on the current core."
1280 )]
1281 #[doc = ""]
1282 #[instability::unstable]
1288 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1289 self.tx.uart.set_interrupt_handler(handler);
1291 }
1292
1293 #[procmacros::doc_replace]
1294 #[instability::unstable]
1361 pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1362 self.tx.uart.info().enable_listen(interrupts.into(), true)
1363 }
1364
1365 #[instability::unstable]
1367 pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1368 self.tx.uart.info().enable_listen(interrupts.into(), false)
1369 }
1370
1371 #[instability::unstable]
1373 pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1374 self.tx.uart.info().interrupts()
1375 }
1376
1377 #[instability::unstable]
1379 pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1380 self.tx.uart.info().clear_interrupts(interrupts)
1381 }
1382}
1383
1384impl<'d> Uart<'d, Async> {
1385 pub fn into_blocking(self) -> Uart<'d, Blocking> {
1390 Uart {
1391 rx: self.rx.into_blocking(),
1392 tx: self.tx.into_blocking(),
1393 }
1394 }
1395
1396 #[procmacros::doc_replace]
1397 pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1428 self.tx.write_async(words).await
1429 }
1430
1431 #[procmacros::doc_replace]
1432 pub async fn flush_async(&mut self) -> Result<(), TxError> {
1458 self.tx.flush_async().await
1459 }
1460
1461 #[procmacros::doc_replace]
1462 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1500 self.rx.read_async(buf).await
1501 }
1502
1503 #[instability::unstable]
1518 pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1519 self.rx.read_exact_async(buf).await
1520 }
1521}
1522
1523#[derive(Debug, EnumSetType)]
1525#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1526#[non_exhaustive]
1527#[instability::unstable]
1528pub enum UartInterrupt {
1529 AtCmd,
1532
1533 TxDone,
1535
1536 RxFifoFull,
1539
1540 RxTimeout,
1543}
1544
1545impl<'d, Dm> Uart<'d, Dm>
1546where
1547 Dm: DriverMode,
1548{
1549 #[procmacros::doc_replace]
1550 pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
1569 self.rx = self.rx.with_rx(rx);
1570 self
1571 }
1572
1573 #[procmacros::doc_replace]
1574 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
1589 self.tx = self.tx.with_tx(tx);
1590 self
1591 }
1592
1593 #[procmacros::doc_replace]
1594 pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
1608 self.rx = self.rx.with_cts(cts);
1609 self
1610 }
1611
1612 #[procmacros::doc_replace]
1613 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
1627 self.tx = self.tx.with_rts(rts);
1628 self
1629 }
1630
1631 fn regs(&self) -> &RegisterBlock {
1632 self.tx.uart.info().regs()
1634 }
1635
1636 #[instability::unstable]
1640 pub fn write_ready(&mut self) -> bool {
1641 self.tx.write_ready()
1642 }
1643
1644 #[procmacros::doc_replace]
1645 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
1671 self.tx.write(data)
1672 }
1673
1674 #[procmacros::doc_replace]
1675 pub fn flush(&mut self) -> Result<(), TxError> {
1690 self.tx.flush()
1691 }
1692
1693 #[instability::unstable]
1697 pub fn read_ready(&mut self) -> bool {
1698 self.rx.read_ready()
1699 }
1700
1701 #[procmacros::doc_replace]
1702 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1737 self.rx.read(buf)
1738 }
1739
1740 #[procmacros::doc_replace]
1741 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1759 self.rx.uart.info().apply_config(config)?;
1762 self.rx.apply_config(config)?;
1763 self.tx.apply_config(config)?;
1764 Ok(())
1765 }
1766
1767 #[procmacros::doc_replace]
1768 #[instability::unstable]
1792 pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
1793 (self.rx, self.tx)
1794 }
1795
1796 #[instability::unstable]
1798 pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
1799 self.rx.check_for_errors()
1800 }
1801
1802 #[instability::unstable]
1819 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1820 self.rx.read_buffered(buf)
1821 }
1822
1823 #[instability::unstable]
1825 pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
1826 #[cfg(not(any(esp32, esp32s2)))]
1827 self.regs()
1828 .clk_conf()
1829 .modify(|_, w| w.sclk_en().clear_bit());
1830
1831 self.regs().at_cmd_char().write(|w| unsafe {
1832 w.at_cmd_char().bits(config.cmd_char);
1833 w.char_num().bits(config.char_num)
1834 });
1835
1836 if let Some(pre_idle_count) = config.pre_idle_count {
1837 self.regs()
1838 .at_cmd_precnt()
1839 .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
1840 }
1841
1842 if let Some(post_idle_count) = config.post_idle_count {
1843 self.regs()
1844 .at_cmd_postcnt()
1845 .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
1846 }
1847
1848 if let Some(gap_timeout) = config.gap_timeout {
1849 self.regs()
1850 .at_cmd_gaptout()
1851 .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
1852 }
1853
1854 #[cfg(not(any(esp32, esp32s2)))]
1855 self.regs().clk_conf().modify(|_, w| w.sclk_en().set_bit());
1856
1857 sync_regs(self.regs());
1858 }
1859
1860 #[inline(always)]
1861 fn init(&mut self, config: Config) -> Result<(), ConfigError> {
1862 cfg_if::cfg_if! {
1863 if #[cfg(any(esp32, esp32s2))] {
1864 } else if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
1866 crate::peripherals::SYSTEM::regs()
1867 .perip_clk_en0()
1868 .modify(|_, w| w.uart_mem_clk_en().set_bit());
1869 } else {
1870 self.regs()
1871 .conf0()
1872 .modify(|_, w| w.mem_clk_en().set_bit());
1873 }
1874 };
1875
1876 self.uart_peripheral_reset();
1877
1878 self.rx.disable_rx_interrupts();
1879 self.tx.disable_tx_interrupts();
1880
1881 self.apply_config(&config)?;
1882
1883 self.rx.uart.info().rxfifo_reset();
1885 self.rx.uart.info().txfifo_reset();
1886
1887 self.regs()
1890 .idle_conf()
1891 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
1892
1893 self.regs().conf0().modify(|_, w| w.err_wr_mask().set_bit());
1896
1897 crate::rom::ets_delay_us(15);
1898
1899 self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
1902
1903 Ok(())
1904 }
1905
1906 fn is_instance(&self, other: impl Instance) -> bool {
1907 self.tx.uart.info().is_instance(other)
1908 }
1909
1910 #[inline(always)]
1911 fn uart_peripheral_reset(&self) {
1912 if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
1923 return;
1924 }
1925
1926 fn rst_core(_reg_block: &RegisterBlock, _enable: bool) {
1927 #[cfg(not(any(esp32, esp32s2, esp32c6, esp32h2)))]
1928 _reg_block
1929 .clk_conf()
1930 .modify(|_, w| w.rst_core().bit(_enable));
1931 }
1932
1933 rst_core(self.regs(), true);
1934 PeripheralClockControl::reset(self.tx.uart.info().peripheral);
1935 rst_core(self.regs(), false);
1936 }
1937}
1938
1939impl crate::private::Sealed for Uart<'_, Blocking> {}
1940
1941#[instability::unstable]
1942impl crate::interrupt::InterruptConfigurable for Uart<'_, Blocking> {
1943 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1944 self.tx.uart.set_interrupt_handler(handler);
1946 }
1947}
1948
1949#[instability::unstable]
1950impl<Dm> ufmt_write::uWrite for Uart<'_, Dm>
1951where
1952 Dm: DriverMode,
1953{
1954 type Error = TxError;
1955
1956 #[inline]
1957 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1958 self.tx.write_str(s)
1959 }
1960
1961 #[inline]
1962 fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
1963 self.tx.write_char(ch)
1964 }
1965}
1966
1967#[instability::unstable]
1968impl<Dm> ufmt_write::uWrite for UartTx<'_, Dm>
1969where
1970 Dm: DriverMode,
1971{
1972 type Error = TxError;
1973
1974 #[inline]
1975 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1976 self.write_all(s.as_bytes())
1977 }
1978}
1979
1980impl<Dm> core::fmt::Write for Uart<'_, Dm>
1981where
1982 Dm: DriverMode,
1983{
1984 #[inline]
1985 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1986 self.tx.write_str(s)
1987 }
1988}
1989
1990impl<Dm> core::fmt::Write for UartTx<'_, Dm>
1991where
1992 Dm: DriverMode,
1993{
1994 #[inline]
1995 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1996 self.write_all(s.as_bytes()).map_err(|_| core::fmt::Error)
1997 }
1998}
1999
2000#[instability::unstable]
2002#[derive(Debug, Clone, Copy, PartialEq)]
2003#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2004#[non_exhaustive]
2005pub enum IoError {
2006 Tx(TxError),
2008 Rx(RxError),
2010}
2011
2012#[instability::unstable]
2013impl core::error::Error for IoError {}
2014
2015#[instability::unstable]
2016impl core::fmt::Display for IoError {
2017 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2018 match self {
2019 IoError::Tx(e) => e.fmt(f),
2020 IoError::Rx(e) => e.fmt(f),
2021 }
2022 }
2023}
2024
2025#[instability::unstable]
2026impl embedded_io_06::Error for IoError {
2027 fn kind(&self) -> embedded_io_06::ErrorKind {
2028 embedded_io_06::ErrorKind::Other
2029 }
2030}
2031
2032#[instability::unstable]
2033impl embedded_io_07::Error for IoError {
2034 fn kind(&self) -> embedded_io_07::ErrorKind {
2035 embedded_io_07::ErrorKind::Other
2036 }
2037}
2038
2039#[instability::unstable]
2040impl From<RxError> for IoError {
2041 fn from(e: RxError) -> Self {
2042 IoError::Rx(e)
2043 }
2044}
2045
2046#[instability::unstable]
2047impl From<TxError> for IoError {
2048 fn from(e: TxError) -> Self {
2049 IoError::Tx(e)
2050 }
2051}
2052
2053#[instability::unstable]
2054impl<Dm: DriverMode> embedded_io_06::ErrorType for Uart<'_, Dm> {
2055 type Error = IoError;
2056}
2057
2058#[instability::unstable]
2059impl<Dm: DriverMode> embedded_io_06::ErrorType for UartTx<'_, Dm> {
2060 type Error = TxError;
2061}
2062
2063#[instability::unstable]
2064impl<Dm: DriverMode> embedded_io_06::ErrorType for UartRx<'_, Dm> {
2065 type Error = RxError;
2066}
2067
2068#[instability::unstable]
2069impl<Dm> embedded_io_06::Read for Uart<'_, Dm>
2070where
2071 Dm: DriverMode,
2072{
2073 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2074 self.rx.read(buf).map_err(IoError::Rx)
2075 }
2076}
2077
2078#[instability::unstable]
2079impl<Dm> embedded_io_06::Read for UartRx<'_, Dm>
2080where
2081 Dm: DriverMode,
2082{
2083 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2084 self.read(buf)
2085 }
2086}
2087
2088#[instability::unstable]
2089impl<Dm> embedded_io_06::ReadReady for Uart<'_, Dm>
2090where
2091 Dm: DriverMode,
2092{
2093 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2094 Ok(self.rx.read_ready())
2095 }
2096}
2097
2098#[instability::unstable]
2099impl<Dm> embedded_io_06::ReadReady for UartRx<'_, Dm>
2100where
2101 Dm: DriverMode,
2102{
2103 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2104 Ok(self.read_ready())
2105 }
2106}
2107
2108#[instability::unstable]
2109impl<Dm> embedded_io_06::Write for Uart<'_, Dm>
2110where
2111 Dm: DriverMode,
2112{
2113 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2114 self.tx.write(buf).map_err(IoError::Tx)
2115 }
2116
2117 fn flush(&mut self) -> Result<(), Self::Error> {
2118 self.tx.flush().map_err(IoError::Tx)
2119 }
2120}
2121
2122#[instability::unstable]
2123impl<Dm> embedded_io_06::Write for UartTx<'_, Dm>
2124where
2125 Dm: DriverMode,
2126{
2127 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2128 self.write(buf)
2129 }
2130
2131 fn flush(&mut self) -> Result<(), Self::Error> {
2132 self.flush()
2133 }
2134}
2135
2136#[instability::unstable]
2137impl<Dm> embedded_io_06::WriteReady for UartTx<'_, Dm>
2138where
2139 Dm: DriverMode,
2140{
2141 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2142 Ok(self.write_ready())
2143 }
2144}
2145
2146#[instability::unstable]
2147impl<Dm> embedded_io_06::WriteReady for Uart<'_, Dm>
2148where
2149 Dm: DriverMode,
2150{
2151 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2152 Ok(self.tx.write_ready())
2153 }
2154}
2155
2156#[instability::unstable]
2157impl<Dm: DriverMode> embedded_io_07::ErrorType for Uart<'_, Dm> {
2158 type Error = IoError;
2159}
2160
2161#[instability::unstable]
2162impl<Dm: DriverMode> embedded_io_07::ErrorType for UartTx<'_, Dm> {
2163 type Error = TxError;
2164}
2165
2166#[instability::unstable]
2167impl<Dm: DriverMode> embedded_io_07::ErrorType for UartRx<'_, Dm> {
2168 type Error = RxError;
2169}
2170
2171#[instability::unstable]
2172impl<Dm> embedded_io_07::Read for Uart<'_, Dm>
2173where
2174 Dm: DriverMode,
2175{
2176 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2177 self.rx.read(buf).map_err(IoError::Rx)
2178 }
2179}
2180
2181#[instability::unstable]
2182impl<Dm> embedded_io_07::Read for UartRx<'_, Dm>
2183where
2184 Dm: DriverMode,
2185{
2186 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2187 self.read(buf)
2188 }
2189}
2190
2191#[instability::unstable]
2192impl<Dm> embedded_io_07::ReadReady for Uart<'_, Dm>
2193where
2194 Dm: DriverMode,
2195{
2196 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2197 Ok(self.rx.read_ready())
2198 }
2199}
2200
2201#[instability::unstable]
2202impl<Dm> embedded_io_07::ReadReady for UartRx<'_, Dm>
2203where
2204 Dm: DriverMode,
2205{
2206 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2207 Ok(self.read_ready())
2208 }
2209}
2210
2211#[instability::unstable]
2212impl<Dm> embedded_io_07::Write for Uart<'_, Dm>
2213where
2214 Dm: DriverMode,
2215{
2216 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2217 self.tx.write(buf).map_err(IoError::Tx)
2218 }
2219
2220 fn flush(&mut self) -> Result<(), Self::Error> {
2221 self.tx.flush().map_err(IoError::Tx)
2222 }
2223}
2224
2225#[instability::unstable]
2226impl<Dm> embedded_io_07::Write for UartTx<'_, Dm>
2227where
2228 Dm: DriverMode,
2229{
2230 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2231 self.write(buf)
2232 }
2233
2234 fn flush(&mut self) -> Result<(), Self::Error> {
2235 self.flush()
2236 }
2237}
2238
2239#[instability::unstable]
2240impl<Dm> embedded_io_07::WriteReady for UartTx<'_, Dm>
2241where
2242 Dm: DriverMode,
2243{
2244 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2245 Ok(self.write_ready())
2246 }
2247}
2248
2249#[instability::unstable]
2250impl<Dm> embedded_io_07::WriteReady for Uart<'_, Dm>
2251where
2252 Dm: DriverMode,
2253{
2254 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2255 Ok(self.tx.write_ready())
2256 }
2257}
2258
2259#[derive(Debug, EnumSetType)]
2260pub(crate) enum TxEvent {
2261 Done,
2262 FiFoEmpty,
2263}
2264
2265#[derive(Debug, EnumSetType)]
2266pub(crate) enum RxEvent {
2267 FifoFull,
2268 CmdCharDetected,
2269 FifoOvf,
2270 FifoTout,
2271 GlitchDetected,
2272 FrameError,
2273 ParityError,
2274}
2275
2276fn rx_event_check_for_error(events: EnumSet<RxEvent>) -> Result<(), RxError> {
2277 for event in events {
2278 match event {
2279 RxEvent::FifoOvf => return Err(RxError::FifoOverflowed),
2280 RxEvent::GlitchDetected => return Err(RxError::GlitchOccurred),
2281 RxEvent::FrameError => return Err(RxError::FrameFormatViolated),
2282 RxEvent::ParityError => return Err(RxError::ParityMismatch),
2283 RxEvent::FifoFull | RxEvent::CmdCharDetected | RxEvent::FifoTout => continue,
2284 }
2285 }
2286
2287 Ok(())
2288}
2289
2290#[must_use = "futures do nothing unless you `.await` or poll them"]
2296struct UartRxFuture {
2297 events: EnumSet<RxEvent>,
2298 uart: &'static Info,
2299 state: &'static State,
2300 registered: bool,
2301}
2302
2303impl UartRxFuture {
2304 fn new(uart: impl Instance, events: impl Into<EnumSet<RxEvent>>) -> Self {
2305 Self {
2306 events: events.into(),
2307 uart: uart.info(),
2308 state: uart.state(),
2309 registered: false,
2310 }
2311 }
2312}
2313
2314impl core::future::Future for UartRxFuture {
2315 type Output = EnumSet<RxEvent>;
2316
2317 fn poll(
2318 mut self: core::pin::Pin<&mut Self>,
2319 cx: &mut core::task::Context<'_>,
2320 ) -> core::task::Poll<Self::Output> {
2321 let events = self.uart.rx_events().intersection(self.events);
2322 if !events.is_empty() {
2323 self.uart.clear_rx_events(events);
2324 Poll::Ready(events)
2325 } else {
2326 self.state.rx_waker.register(cx.waker());
2327 if !self.registered {
2328 self.uart.enable_listen_rx(self.events, true);
2329 self.registered = true;
2330 }
2331 Poll::Pending
2332 }
2333 }
2334}
2335
2336impl Drop for UartRxFuture {
2337 fn drop(&mut self) {
2338 self.uart.enable_listen_rx(self.events, false);
2342 }
2343}
2344
2345#[must_use = "futures do nothing unless you `.await` or poll them"]
2346struct UartTxFuture {
2347 events: EnumSet<TxEvent>,
2348 uart: &'static Info,
2349 state: &'static State,
2350 registered: bool,
2351}
2352
2353impl UartTxFuture {
2354 fn new(uart: impl Instance, events: impl Into<EnumSet<TxEvent>>) -> Self {
2355 Self {
2356 events: events.into(),
2357 uart: uart.info(),
2358 state: uart.state(),
2359 registered: false,
2360 }
2361 }
2362}
2363
2364impl core::future::Future for UartTxFuture {
2365 type Output = ();
2366
2367 fn poll(
2368 mut self: core::pin::Pin<&mut Self>,
2369 cx: &mut core::task::Context<'_>,
2370 ) -> core::task::Poll<Self::Output> {
2371 let events = self.uart.tx_events().intersection(self.events);
2372 if !events.is_empty() {
2373 self.uart.clear_tx_events(events);
2374 Poll::Ready(())
2375 } else {
2376 self.state.tx_waker.register(cx.waker());
2377 if !self.registered {
2378 self.uart.enable_listen_tx(self.events, true);
2379 self.registered = true;
2380 }
2381 Poll::Pending
2382 }
2383 }
2384}
2385
2386impl Drop for UartTxFuture {
2387 fn drop(&mut self) {
2388 self.uart.enable_listen_tx(self.events, false);
2392 }
2393}
2394
2395#[instability::unstable]
2396impl embedded_io_async_06::Read for Uart<'_, Async> {
2397 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2398 self.read_async(buf).await.map_err(IoError::Rx)
2399 }
2400
2401 async fn read_exact(
2402 &mut self,
2403 buf: &mut [u8],
2404 ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2405 self.read_exact_async(buf)
2406 .await
2407 .map_err(|e| embedded_io_06::ReadExactError::Other(IoError::Rx(e)))
2408 }
2409}
2410
2411#[instability::unstable]
2412impl embedded_io_async_06::Read for UartRx<'_, Async> {
2413 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2414 self.read_async(buf).await
2415 }
2416
2417 async fn read_exact(
2418 &mut self,
2419 buf: &mut [u8],
2420 ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2421 self.read_exact_async(buf)
2422 .await
2423 .map_err(embedded_io_06::ReadExactError::Other)
2424 }
2425}
2426
2427#[instability::unstable]
2428impl embedded_io_async_06::Write for Uart<'_, Async> {
2429 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2430 self.write_async(buf).await.map_err(IoError::Tx)
2431 }
2432
2433 async fn flush(&mut self) -> Result<(), Self::Error> {
2434 self.flush_async().await.map_err(IoError::Tx)
2435 }
2436}
2437
2438#[instability::unstable]
2439impl embedded_io_async_06::Write for UartTx<'_, Async> {
2440 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2441 self.write_async(buf).await
2442 }
2443
2444 async fn flush(&mut self) -> Result<(), Self::Error> {
2445 self.flush_async().await
2446 }
2447}
2448
2449#[instability::unstable]
2450impl embedded_io_async_07::Read for Uart<'_, Async> {
2451 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2452 self.read_async(buf).await.map_err(IoError::Rx)
2453 }
2454
2455 async fn read_exact(
2456 &mut self,
2457 buf: &mut [u8],
2458 ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2459 self.read_exact_async(buf)
2460 .await
2461 .map_err(|e| embedded_io_07::ReadExactError::Other(IoError::Rx(e)))
2462 }
2463}
2464
2465#[instability::unstable]
2466impl embedded_io_async_07::Read for UartRx<'_, Async> {
2467 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2468 self.read_async(buf).await
2469 }
2470
2471 async fn read_exact(
2472 &mut self,
2473 buf: &mut [u8],
2474 ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2475 self.read_exact_async(buf)
2476 .await
2477 .map_err(embedded_io_07::ReadExactError::Other)
2478 }
2479}
2480
2481#[instability::unstable]
2482impl embedded_io_async_07::Write for Uart<'_, Async> {
2483 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2484 self.write_async(buf).await.map_err(IoError::Tx)
2485 }
2486
2487 async fn flush(&mut self) -> Result<(), Self::Error> {
2488 self.flush_async().await.map_err(IoError::Tx)
2489 }
2490}
2491
2492#[instability::unstable]
2493impl embedded_io_async_07::Write for UartTx<'_, Async> {
2494 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2495 self.write_async(buf).await
2496 }
2497
2498 async fn flush(&mut self) -> Result<(), Self::Error> {
2499 self.flush_async().await
2500 }
2501}
2502
2503pub(super) fn intr_handler(uart: &Info, state: &State) {
2508 let interrupts = uart.regs().int_st().read();
2509 let interrupt_bits = interrupts.bits(); let rx_wake = interrupts.rxfifo_full().bit_is_set()
2511 | interrupts.rxfifo_ovf().bit_is_set()
2512 | interrupts.rxfifo_tout().bit_is_set()
2513 | interrupts.at_cmd_char_det().bit_is_set()
2514 | interrupts.glitch_det().bit_is_set()
2515 | interrupts.frm_err().bit_is_set()
2516 | interrupts.parity_err().bit_is_set();
2517 let tx_wake = interrupts.tx_done().bit_is_set() | interrupts.txfifo_empty().bit_is_set();
2518
2519 uart.regs()
2520 .int_ena()
2521 .modify(|r, w| unsafe { w.bits(r.bits() & !interrupt_bits) });
2522
2523 if tx_wake {
2524 state.tx_waker.wake();
2525 }
2526 if rx_wake {
2527 state.rx_waker.wake();
2528 }
2529}
2530
2531#[cfg(lp_uart)]
2533#[instability::unstable]
2534pub mod lp_uart {
2535 use crate::{
2536 gpio::lp_io::{LowPowerInput, LowPowerOutput},
2537 peripherals::{LP_AON, LP_IO, LP_UART, LPWR},
2538 uart::{Config, DataBits, Parity, StopBits},
2539 };
2540 pub struct LpUart {
2544 uart: LP_UART<'static>,
2545 }
2546
2547 impl LpUart {
2548 pub fn new(
2557 uart: LP_UART<'static>,
2558 config: Config,
2559 _tx: LowPowerOutput<'_, 5>,
2560 _rx: LowPowerInput<'_, 4>,
2561 ) -> Self {
2562 LP_AON::regs()
2564 .gpio_mux()
2565 .modify(|r, w| unsafe { w.sel().bits(r.sel().bits() | (1 << 4) | (1 << 5)) });
2566
2567 LP_IO::regs()
2568 .gpio(4)
2569 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2570 LP_IO::regs()
2571 .gpio(5)
2572 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2573
2574 let mut me = Self { uart };
2575 let uart = me.uart.register_block();
2576
2577 uart.conf0().modify(|_, w| unsafe {
2583 w.parity().clear_bit();
2584 w.parity_en().clear_bit();
2585 w.bit_num().bits(0x3);
2586 w.stop_bit_num().bits(0x1)
2587 });
2588 uart.idle_conf()
2590 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2591 uart.hwfc_conf().modify(|_, w| w.rx_flow_en().clear_bit());
2593
2594 LPWR::regs()
2599 .lpperi()
2600 .modify(|_, w| w.lp_uart_clk_sel().clear_bit());
2601
2602 me.change_baud_internal(&config);
2605 me.change_parity(config.parity);
2607 me.change_data_bits(config.data_bits);
2609 me.change_stop_bits(config.stop_bits);
2611 me.change_tx_idle(0); me.rxfifo_reset();
2616 me.txfifo_reset();
2617
2618 me
2619 }
2620
2621 fn rxfifo_reset(&mut self) {
2622 self.uart
2623 .register_block()
2624 .conf0()
2625 .modify(|_, w| w.rxfifo_rst().set_bit());
2626 self.update();
2627
2628 self.uart
2629 .register_block()
2630 .conf0()
2631 .modify(|_, w| w.rxfifo_rst().clear_bit());
2632 self.update();
2633 }
2634
2635 fn txfifo_reset(&mut self) {
2636 self.uart
2637 .register_block()
2638 .conf0()
2639 .modify(|_, w| w.txfifo_rst().set_bit());
2640 self.update();
2641
2642 self.uart
2643 .register_block()
2644 .conf0()
2645 .modify(|_, w| w.txfifo_rst().clear_bit());
2646 self.update();
2647 }
2648
2649 fn update(&mut self) {
2650 let register_block = self.uart.register_block();
2651 register_block
2652 .reg_update()
2653 .modify(|_, w| w.reg_update().set_bit());
2654 while register_block.reg_update().read().reg_update().bit_is_set() {
2655 }
2657 }
2658
2659 fn change_baud_internal(&mut self, config: &Config) {
2660 let clk = 16_000_000_u32;
2662 let max_div = 0b1111_1111_1111 - 1;
2663 let clk_div = clk.div_ceil(max_div * config.baudrate);
2664
2665 self.uart.register_block().clk_conf().modify(|_, w| unsafe {
2666 w.sclk_div_a().bits(0);
2667 w.sclk_div_b().bits(0);
2668 w.sclk_div_num().bits(clk_div as u8 - 1);
2669 w.sclk_sel().bits(match config.clock_source {
2670 super::ClockSource::Xtal => 3,
2671 super::ClockSource::RcFast => 2,
2672 super::ClockSource::Apb => panic!("Wrong clock source for LP_UART"),
2673 });
2674 w.sclk_en().set_bit()
2675 });
2676
2677 let clk = clk / clk_div;
2678 let divider = clk / config.baudrate;
2679 let divider = divider as u16;
2680
2681 self.uart
2682 .register_block()
2683 .clkdiv()
2684 .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) });
2685
2686 self.update();
2687 }
2688
2689 pub fn change_baud(&mut self, config: &Config) {
2697 self.change_baud_internal(config);
2698 self.txfifo_reset();
2699 self.rxfifo_reset();
2700 }
2701
2702 fn change_parity(&mut self, parity: Parity) -> &mut Self {
2703 if parity != Parity::None {
2704 self.uart
2705 .register_block()
2706 .conf0()
2707 .modify(|_, w| w.parity().bit((parity as u8 & 0x1) != 0));
2708 }
2709
2710 self.uart
2711 .register_block()
2712 .conf0()
2713 .modify(|_, w| match parity {
2714 Parity::None => w.parity_en().clear_bit(),
2715 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2716 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2717 });
2718
2719 self
2720 }
2721
2722 fn change_data_bits(&mut self, data_bits: DataBits) -> &mut Self {
2723 self.uart
2724 .register_block()
2725 .conf0()
2726 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2727
2728 self.update();
2729 self
2730 }
2731
2732 fn change_stop_bits(&mut self, stop_bits: StopBits) -> &mut Self {
2733 self.uart
2734 .register_block()
2735 .conf0()
2736 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2737
2738 self.update();
2739 self
2740 }
2741
2742 fn change_tx_idle(&mut self, idle_num: u16) -> &mut Self {
2743 self.uart
2744 .register_block()
2745 .idle_conf()
2746 .modify(|_, w| unsafe { w.tx_idle_num().bits(idle_num) });
2747
2748 self.update();
2749 self
2750 }
2751 }
2752}
2753
2754pub trait Instance: crate::private::Sealed + any::Degrade {
2756 #[doc(hidden)]
2757 fn parts(&self) -> (&'static Info, &'static State);
2759
2760 #[inline(always)]
2762 #[doc(hidden)]
2763 fn info(&self) -> &'static Info {
2764 self.parts().0
2765 }
2766
2767 #[inline(always)]
2769 #[doc(hidden)]
2770 fn state(&self) -> &'static State {
2771 self.parts().1
2772 }
2773}
2774
2775#[doc(hidden)]
2777#[non_exhaustive]
2778pub struct Info {
2779 pub register_block: *const RegisterBlock,
2783
2784 pub peripheral: crate::system::Peripheral,
2786
2787 pub async_handler: InterruptHandler,
2789
2790 pub tx_signal: OutputSignal,
2792
2793 pub rx_signal: InputSignal,
2795
2796 pub cts_signal: InputSignal,
2798
2799 pub rts_signal: OutputSignal,
2801}
2802
2803#[doc(hidden)]
2805#[non_exhaustive]
2806pub struct State {
2807 pub rx_waker: AtomicWaker,
2809
2810 pub tx_waker: AtomicWaker,
2812
2813 pub is_rx_async: AtomicBool,
2815
2816 pub is_tx_async: AtomicBool,
2818}
2819
2820impl Info {
2821 const UART_FIFO_SIZE: u16 = property!("uart.ram_size");
2824 const RX_FIFO_MAX_THRHD: u16 = Self::UART_FIFO_SIZE - 1;
2825 const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
2826
2827 pub fn regs(&self) -> &RegisterBlock {
2829 unsafe { &*self.register_block }
2830 }
2831
2832 fn enable_listen(&self, interrupts: EnumSet<UartInterrupt>, enable: bool) {
2834 let reg_block = self.regs();
2835
2836 reg_block.int_ena().modify(|_, w| {
2837 for interrupt in interrupts {
2838 match interrupt {
2839 UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable),
2840 UartInterrupt::TxDone => w.tx_done().bit(enable),
2841 UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable),
2842 UartInterrupt::RxTimeout => w.rxfifo_tout().bit(enable),
2843 };
2844 }
2845 w
2846 });
2847 }
2848
2849 fn interrupts(&self) -> EnumSet<UartInterrupt> {
2850 let mut res = EnumSet::new();
2851 let reg_block = self.regs();
2852
2853 let ints = reg_block.int_raw().read();
2854
2855 if ints.at_cmd_char_det().bit_is_set() {
2856 res.insert(UartInterrupt::AtCmd);
2857 }
2858 if ints.tx_done().bit_is_set() {
2859 res.insert(UartInterrupt::TxDone);
2860 }
2861 if ints.rxfifo_full().bit_is_set() {
2862 res.insert(UartInterrupt::RxFifoFull);
2863 }
2864 if ints.rxfifo_tout().bit_is_set() {
2865 res.insert(UartInterrupt::RxTimeout);
2866 }
2867
2868 res
2869 }
2870
2871 fn clear_interrupts(&self, interrupts: EnumSet<UartInterrupt>) {
2872 let reg_block = self.regs();
2873
2874 reg_block.int_clr().write(|w| {
2875 for interrupt in interrupts {
2876 match interrupt {
2877 UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(),
2878 UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
2879 UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(),
2880 UartInterrupt::RxTimeout => w.rxfifo_tout().clear_bit_by_one(),
2881 };
2882 }
2883 w
2884 });
2885 }
2886
2887 fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
2888 config.validate()?;
2889 self.change_baud(config)?;
2890 self.change_data_bits(config.data_bits);
2891 self.change_parity(config.parity);
2892 self.change_stop_bits(config.stop_bits);
2893 self.change_flow_control(config.sw_flow_ctrl, config.hw_flow_ctrl);
2894
2895 Ok(())
2896 }
2897
2898 fn enable_listen_tx(&self, events: EnumSet<TxEvent>, enable: bool) {
2899 self.regs().int_ena().modify(|_, w| {
2900 for event in events {
2901 match event {
2902 TxEvent::Done => w.tx_done().bit(enable),
2903 TxEvent::FiFoEmpty => w.txfifo_empty().bit(enable),
2904 };
2905 }
2906 w
2907 });
2908 }
2909
2910 fn tx_events(&self) -> EnumSet<TxEvent> {
2911 let pending_interrupts = self.regs().int_raw().read();
2912 let mut active_events = EnumSet::new();
2913
2914 if pending_interrupts.tx_done().bit_is_set() {
2915 active_events |= TxEvent::Done;
2916 }
2917 if pending_interrupts.txfifo_empty().bit_is_set() {
2918 active_events |= TxEvent::FiFoEmpty;
2919 }
2920
2921 active_events
2922 }
2923
2924 fn clear_tx_events(&self, events: impl Into<EnumSet<TxEvent>>) {
2925 let events = events.into();
2926 self.regs().int_clr().write(|w| {
2927 for event in events {
2928 match event {
2929 TxEvent::FiFoEmpty => w.txfifo_empty().clear_bit_by_one(),
2930 TxEvent::Done => w.tx_done().clear_bit_by_one(),
2931 };
2932 }
2933 w
2934 });
2935 }
2936
2937 fn enable_listen_rx(&self, events: EnumSet<RxEvent>, enable: bool) {
2938 self.regs().int_ena().modify(|_, w| {
2939 for event in events {
2940 match event {
2941 RxEvent::FifoFull => w.rxfifo_full().bit(enable),
2942 RxEvent::CmdCharDetected => w.at_cmd_char_det().bit(enable),
2943
2944 RxEvent::FifoOvf => w.rxfifo_ovf().bit(enable),
2945 RxEvent::FifoTout => w.rxfifo_tout().bit(enable),
2946 RxEvent::GlitchDetected => w.glitch_det().bit(enable),
2947 RxEvent::FrameError => w.frm_err().bit(enable),
2948 RxEvent::ParityError => w.parity_err().bit(enable),
2949 };
2950 }
2951 w
2952 });
2953 }
2954
2955 fn rx_events(&self) -> EnumSet<RxEvent> {
2956 let pending_interrupts = self.regs().int_raw().read();
2957 let mut active_events = EnumSet::new();
2958
2959 if pending_interrupts.rxfifo_full().bit_is_set() {
2960 active_events |= RxEvent::FifoFull;
2961 }
2962 if pending_interrupts.at_cmd_char_det().bit_is_set() {
2963 active_events |= RxEvent::CmdCharDetected;
2964 }
2965 if pending_interrupts.rxfifo_ovf().bit_is_set() {
2966 active_events |= RxEvent::FifoOvf;
2967 }
2968 if pending_interrupts.rxfifo_tout().bit_is_set() {
2969 active_events |= RxEvent::FifoTout;
2970 }
2971 if pending_interrupts.glitch_det().bit_is_set() {
2972 active_events |= RxEvent::GlitchDetected;
2973 }
2974 if pending_interrupts.frm_err().bit_is_set() {
2975 active_events |= RxEvent::FrameError;
2976 }
2977 if pending_interrupts.parity_err().bit_is_set() {
2978 active_events |= RxEvent::ParityError;
2979 }
2980
2981 active_events
2982 }
2983
2984 fn clear_rx_events(&self, events: impl Into<EnumSet<RxEvent>>) {
2985 let events = events.into();
2986 self.regs().int_clr().write(|w| {
2987 for event in events {
2988 match event {
2989 RxEvent::FifoFull => w.rxfifo_full().clear_bit_by_one(),
2990 RxEvent::CmdCharDetected => w.at_cmd_char_det().clear_bit_by_one(),
2991
2992 RxEvent::FifoOvf => w.rxfifo_ovf().clear_bit_by_one(),
2993 RxEvent::FifoTout => w.rxfifo_tout().clear_bit_by_one(),
2994 RxEvent::GlitchDetected => w.glitch_det().clear_bit_by_one(),
2995 RxEvent::FrameError => w.frm_err().clear_bit_by_one(),
2996 RxEvent::ParityError => w.parity_err().clear_bit_by_one(),
2997 };
2998 }
2999 w
3000 });
3001 }
3002
3003 fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3010 if threshold > Self::RX_FIFO_MAX_THRHD {
3011 return Err(ConfigError::RxFifoThresholdNotSupported);
3012 }
3013
3014 self.regs()
3015 .conf1()
3016 .modify(|_, w| unsafe { w.rxfifo_full_thrhd().bits(threshold as _) });
3017
3018 Ok(())
3019 }
3020
3021 #[allow(clippy::useless_conversion)]
3023 fn rx_fifo_full_threshold(&self) -> u16 {
3024 self.regs().conf1().read().rxfifo_full_thrhd().bits().into()
3025 }
3026
3027 fn set_tx_fifo_empty_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3034 if threshold > Self::TX_FIFO_MAX_THRHD {
3035 return Err(ConfigError::TxFifoThresholdNotSupported);
3036 }
3037
3038 self.regs()
3039 .conf1()
3040 .modify(|_, w| unsafe { w.txfifo_empty_thrhd().bits(threshold as _) });
3041
3042 Ok(())
3043 }
3044
3045 fn set_rx_timeout(&self, timeout: Option<u8>, _symbol_len: u8) -> Result<(), ConfigError> {
3060 cfg_if::cfg_if! {
3061 if #[cfg(esp32)] {
3062 const MAX_THRHD: u8 = 0x7F; } else {
3064 const MAX_THRHD: u16 = 0x3FF; }
3066 }
3067
3068 let register_block = self.regs();
3069
3070 if let Some(timeout) = timeout {
3071 #[cfg(esp32)]
3073 let timeout_reg = timeout;
3074 #[cfg(not(esp32))]
3076 let timeout_reg = timeout as u16 * _symbol_len as u16;
3077
3078 if timeout_reg > MAX_THRHD {
3079 return Err(ConfigError::TimeoutTooLong);
3080 }
3081
3082 cfg_if::cfg_if! {
3083 if #[cfg(esp32)] {
3084 let reg_thrhd = register_block.conf1();
3085 } else if #[cfg(any(esp32c6, esp32h2))] {
3086 let reg_thrhd = register_block.tout_conf();
3087 } else {
3088 let reg_thrhd = register_block.mem_conf();
3089 }
3090 }
3091 reg_thrhd.modify(|_, w| unsafe { w.rx_tout_thrhd().bits(timeout_reg) });
3092 }
3093
3094 cfg_if::cfg_if! {
3095 if #[cfg(any(esp32c6, esp32h2))] {
3096 let reg_en = register_block.tout_conf();
3097 } else {
3098 let reg_en = register_block.conf1();
3099 }
3100 }
3101 reg_en.modify(|_, w| w.rx_tout_en().bit(timeout.is_some()));
3102
3103 self.sync_regs();
3104
3105 Ok(())
3106 }
3107
3108 fn is_instance(&self, other: impl Instance) -> bool {
3109 self == other.info()
3110 }
3111
3112 fn sync_regs(&self) {
3113 sync_regs(self.regs());
3114 }
3115
3116 fn change_baud(&self, config: &Config) -> Result<(), ConfigError> {
3117 let clocks = Clocks::get();
3118 let clk = match config.clock_source {
3119 ClockSource::Apb => clocks.apb_clock.as_hz(),
3120 #[cfg(not(any(esp32, esp32s2)))]
3121 ClockSource::Xtal => clocks.xtal_clock.as_hz(),
3122 #[cfg(not(any(esp32, esp32s2)))]
3123 ClockSource::RcFast => property!("soc.rc_fast_clk_default"), #[cfg(soc_ref_tick_hz_is_set)]
3125 ClockSource::RefTick => property!("soc.ref_tick_hz"),
3126 };
3127
3128 cfg_if::cfg_if! {
3129 if #[cfg(any(esp32c2, esp32c3, esp32s3, esp32c6, esp32h2))] {
3130
3131 const MAX_DIV: u32 = 0b1111_1111_1111 - 1;
3132 let clk_div = (clk.div_ceil(MAX_DIV)).div_ceil(config.baudrate);
3133
3134 cfg_if::cfg_if! {
3136 if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
3137 if matches!(config.clock_source, ClockSource::RcFast) {
3138 crate::peripherals::LPWR::regs()
3139 .clk_conf()
3140 .modify(|_, w| w.dig_clk8m_en().variant(true));
3141 crate::rom::ets_delay_us(5);
3143 }
3144
3145 let conf = self.regs().clk_conf();
3146 } else {
3147 let pcr = crate::peripherals::PCR::regs();
3149 let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
3150 pcr.uart(0).clk_conf()
3151 } else {
3152 pcr.uart(1).clk_conf()
3153 };
3154 }
3155 };
3156
3157 conf.write(|w| unsafe {
3158 w.sclk_sel().bits(match config.clock_source {
3159 ClockSource::Apb => 1,
3160 ClockSource::RcFast => 2,
3161 ClockSource::Xtal => 3,
3162 });
3163 w.sclk_div_a().bits(0);
3164 w.sclk_div_b().bits(0);
3165 w.sclk_div_num().bits(clk_div as u8 - 1)
3166 });
3167
3168 let divider = (clk << 4) / (config.baudrate * clk_div);
3169 } else {
3170 self.regs().conf0().modify(|_, w| {
3171 w.tick_ref_always_on()
3172 .bit(config.clock_source == ClockSource::Apb)
3173 });
3174
3175 let divider = (clk << 4) / config.baudrate;
3176 }
3177 }
3178
3179 let divider_integer = divider >> 4;
3180 let divider_frag = (divider & 0xf) as u8;
3181
3182 self.regs().clkdiv().write(|w| unsafe {
3183 w.clkdiv()
3184 .bits(divider_integer as _)
3185 .frag()
3186 .bits(divider_frag)
3187 });
3188
3189 self.sync_regs();
3190
3191 #[cfg(feature = "unstable")]
3192 self.verify_baudrate(clk, config)?;
3193
3194 Ok(())
3195 }
3196
3197 fn change_data_bits(&self, data_bits: DataBits) {
3198 self.regs()
3199 .conf0()
3200 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
3201 }
3202
3203 fn change_parity(&self, parity: Parity) {
3204 self.regs().conf0().modify(|_, w| match parity {
3205 Parity::None => w.parity_en().clear_bit(),
3206 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
3207 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
3208 });
3209 }
3210
3211 fn change_stop_bits(&self, stop_bits: StopBits) {
3212 #[cfg(esp32)]
3213 {
3214 if stop_bits == StopBits::_2 {
3216 self.regs()
3217 .rs485_conf()
3218 .modify(|_, w| w.dl1_en().bit(stop_bits == StopBits::_2));
3219
3220 self.regs()
3221 .conf0()
3222 .modify(|_, w| unsafe { w.stop_bit_num().bits(1) });
3223 }
3224 }
3225
3226 #[cfg(not(esp32))]
3227 self.regs()
3228 .conf0()
3229 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
3230 }
3231
3232 fn change_flow_control(&self, sw_flow_ctrl: SwFlowControl, hw_flow_ctrl: HwFlowControl) {
3233 match sw_flow_ctrl {
3235 SwFlowControl::Enabled {
3236 xon_char,
3237 xoff_char,
3238 xon_threshold,
3239 xoff_threshold,
3240 } => {
3241 cfg_if::cfg_if! {
3242 if #[cfg(any(esp32c6, esp32h2))] {
3243 self.regs().swfc_conf0().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3244 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold)});
3245 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3246 } else if #[cfg(esp32)]{
3247 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3248 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold) });
3249 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3250 } else {
3251 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3252 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold as u16) });
3253 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_threshold().bits(xoff_threshold as u16) });
3254 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_char().bits(xon_char) });
3255 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_char().bits(xoff_char) });
3256 }
3257 }
3258 }
3259 SwFlowControl::Disabled => {
3260 cfg_if::cfg_if! {
3261 if #[cfg(any(esp32c6, esp32h2))] {
3262 let reg = self.regs().swfc_conf0();
3263 } else {
3264 let reg = self.regs().flow_conf();
3265 }
3266 }
3267
3268 reg.modify(|_, w| w.sw_flow_con_en().clear_bit());
3269 reg.modify(|_, w| w.xonoff_del().clear_bit());
3270 }
3271 }
3272
3273 self.regs().conf0().modify(|_, w| {
3274 w.tx_flow_en()
3275 .bit(matches!(hw_flow_ctrl.cts, CtsConfig::Enabled))
3276 });
3277
3278 match hw_flow_ctrl.rts {
3279 RtsConfig::Enabled(threshold) => self.configure_rts_flow_ctrl(true, Some(threshold)),
3280 RtsConfig::Disabled => self.configure_rts_flow_ctrl(false, None),
3281 }
3282
3283 #[cfg(any(esp32c6, esp32h2))]
3284 sync_regs(self.regs());
3285 }
3286
3287 fn configure_rts_flow_ctrl(&self, enable: bool, threshold: Option<u8>) {
3288 if let Some(threshold) = threshold {
3289 cfg_if::cfg_if! {
3290 if #[cfg(esp32)] {
3291 self.regs().conf1().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3292 } else if #[cfg(any(esp32c6, esp32h2))] {
3293 self.regs().hwfc_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3294 } else {
3295 self.regs().mem_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold as u16) });
3296 }
3297 }
3298 }
3299
3300 cfg_if::cfg_if! {
3301 if #[cfg(any(esp32c6, esp32h2))] {
3302 self.regs().hwfc_conf().modify(|_, w| {
3303 w.rx_flow_en().bit(enable)
3304 });
3305 } else {
3306 self.regs().conf1().modify(|_, w| {
3307 w.rx_flow_en().bit(enable)
3308 });
3309 }
3310 }
3311 }
3312
3313 fn rxfifo_reset(&self) {
3314 fn rxfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3315 reg_block.conf0().modify(|_, w| w.rxfifo_rst().bit(enable));
3316 sync_regs(reg_block);
3317 }
3318
3319 rxfifo_rst(self.regs(), true);
3320 rxfifo_rst(self.regs(), false);
3321 }
3322
3323 fn txfifo_reset(&self) {
3324 fn txfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3325 reg_block.conf0().modify(|_, w| w.txfifo_rst().bit(enable));
3326 sync_regs(reg_block);
3327 }
3328
3329 txfifo_rst(self.regs(), true);
3330 txfifo_rst(self.regs(), false);
3331 }
3332
3333 #[cfg(feature = "unstable")]
3334 fn verify_baudrate(&self, clk: u32, config: &Config) -> Result<(), ConfigError> {
3335 let clkdiv_reg = self.regs().clkdiv().read();
3338 let clkdiv_frag = clkdiv_reg.frag().bits() as u32;
3339 let clkdiv = clkdiv_reg.clkdiv().bits();
3340
3341 cfg_if::cfg_if! {
3342 if #[cfg(any(esp32, esp32s2))] {
3343 let actual_baud = (clk << 4) / ((clkdiv << 4) | clkdiv_frag);
3344 } else if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
3345 let sclk_div_num = self.regs().clk_conf().read().sclk_div_num().bits() as u32;
3346 let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
3347 } else { let pcr = crate::peripherals::PCR::regs();
3349 let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
3350 pcr.uart(0).clk_conf()
3351 } else {
3352 pcr.uart(1).clk_conf()
3353 };
3354 let sclk_div_num = conf.read().sclk_div_num().bits() as u32;
3355 let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
3356 }
3357 };
3358
3359 match config.baudrate_tolerance {
3360 BaudrateTolerance::Exact => {
3361 let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
3362 * 100)
3363 / actual_baud;
3364 if deviation > 1_u32 {
3367 return Err(ConfigError::BaudrateNotAchievable);
3368 }
3369 }
3370 BaudrateTolerance::ErrorPercent(percent) => {
3371 let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
3372 * 100)
3373 / actual_baud;
3374 if deviation > percent as u32 {
3375 return Err(ConfigError::BaudrateNotAchievable);
3376 }
3377 }
3378 _ => {}
3379 }
3380
3381 Ok(())
3382 }
3383
3384 fn current_symbol_length(&self) -> u8 {
3385 let conf0 = self.regs().conf0().read();
3386 let data_bits = conf0.bit_num().bits() + 5; let parity = conf0.parity_en().bit() as u8;
3388 let mut stop_bits = conf0.stop_bit_num().bits();
3389
3390 match stop_bits {
3391 1 => {
3392 #[cfg(esp32)]
3394 if self.regs().rs485_conf().read().dl1_en().bit_is_set() {
3395 stop_bits = 2;
3396 }
3397 }
3398 _ => stop_bits = 2,
3400 }
3401
3402 1 + data_bits + parity + stop_bits
3403 }
3404
3405 fn read_next_from_fifo(&self) -> u8 {
3409 fn access_fifo_register<R>(f: impl Fn() -> R) -> R {
3410 cfg_if::cfg_if! {
3412 if #[cfg(esp32)] {
3413 crate::interrupt::free(f)
3414 } else {
3415 f()
3416 }
3417 }
3418 }
3419
3420 let fifo_reg = self.regs().fifo();
3421 cfg_if::cfg_if! {
3422 if #[cfg(esp32s2)] {
3423 let fifo_reg = unsafe {
3425 &*fifo_reg.as_ptr().cast::<u8>().add(0x20C00000).cast::<crate::pac::uart0::FIFO>()
3426 };
3427 }
3428 }
3429
3430 access_fifo_register(|| fifo_reg.read().rxfifo_rd_byte().bits())
3431 }
3432
3433 #[allow(clippy::useless_conversion)]
3434 fn tx_fifo_count(&self) -> u16 {
3435 u16::from(self.regs().status().read().txfifo_cnt().bits())
3436 }
3437
3438 fn write_byte(&self, byte: u8) {
3439 self.regs()
3440 .fifo()
3441 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
3442 }
3443
3444 fn check_for_errors(&self) -> Result<(), RxError> {
3445 let errors = RxEvent::FifoOvf
3446 | RxEvent::FifoTout
3447 | RxEvent::GlitchDetected
3448 | RxEvent::FrameError
3449 | RxEvent::ParityError;
3450 let events = self.rx_events().intersection(errors);
3451 let result = rx_event_check_for_error(events);
3452 if result.is_err() {
3453 self.clear_rx_events(errors);
3454 if events.contains(RxEvent::FifoOvf) {
3455 self.rxfifo_reset();
3456 }
3457 }
3458 result
3459 }
3460
3461 #[cfg(not(esp32))]
3462 #[allow(clippy::unnecessary_cast)]
3463 fn rx_fifo_count(&self) -> u16 {
3464 self.regs().status().read().rxfifo_cnt().bits() as u16
3465 }
3466
3467 #[cfg(esp32)]
3468 fn rx_fifo_count(&self) -> u16 {
3469 let fifo_cnt = self.regs().status().read().rxfifo_cnt().bits();
3470
3471 let status = self.regs().mem_rx_status().read();
3474 let rd_addr: u16 = status.mem_rx_rd_addr().bits();
3475 let wr_addr: u16 = status.mem_rx_wr_addr().bits();
3476
3477 if wr_addr > rd_addr {
3478 wr_addr - rd_addr
3479 } else if wr_addr < rd_addr {
3480 (wr_addr + Info::UART_FIFO_SIZE) - rd_addr
3481 } else if fifo_cnt > 0 {
3482 Info::UART_FIFO_SIZE
3483 } else {
3484 0
3485 }
3486 }
3487
3488 fn write(&self, data: &[u8]) -> Result<usize, TxError> {
3489 if data.is_empty() {
3490 return Ok(0);
3491 }
3492
3493 while self.tx_fifo_count() >= Info::UART_FIFO_SIZE {}
3494
3495 let space = (Info::UART_FIFO_SIZE - self.tx_fifo_count()) as usize;
3496 let to_write = space.min(data.len());
3497 for &byte in &data[..to_write] {
3498 self.write_byte(byte);
3499 }
3500
3501 Ok(to_write)
3502 }
3503
3504 fn read(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3505 if buf.is_empty() {
3506 return Ok(0);
3507 }
3508
3509 while self.rx_fifo_count() == 0 {
3510 self.check_for_errors()?;
3512 }
3513
3514 self.read_buffered(buf)
3515 }
3516
3517 fn read_buffered(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3518 let to_read = (self.rx_fifo_count() as usize).min(buf.len());
3521 self.check_for_errors()?;
3522
3523 for byte_into in buf[..to_read].iter_mut() {
3524 *byte_into = self.read_next_from_fifo();
3525 }
3526
3527 Ok(to_read)
3528 }
3529}
3530
3531impl PartialEq for Info {
3532 fn eq(&self, other: &Self) -> bool {
3533 core::ptr::eq(self.register_block, other.register_block)
3534 }
3535}
3536
3537unsafe impl Sync for Info {}
3538
3539for_each_uart! {
3540 ($inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident) => {
3541 impl Instance for crate::peripherals::$inst<'_> {
3542 fn parts(&self) -> (&'static Info, &'static State) {
3543 #[crate::handler]
3544 pub(super) fn irq_handler() {
3545 intr_handler(&PERIPHERAL, &STATE);
3546 }
3547
3548 static STATE: State = State {
3549 tx_waker: AtomicWaker::new(),
3550 rx_waker: AtomicWaker::new(),
3551 is_rx_async: AtomicBool::new(false),
3552 is_tx_async: AtomicBool::new(false),
3553 };
3554
3555 static PERIPHERAL: Info = Info {
3556 register_block: crate::peripherals::$inst::ptr(),
3557 peripheral: crate::system::Peripheral::$peri,
3558 async_handler: irq_handler,
3559 tx_signal: OutputSignal::$txd,
3560 rx_signal: InputSignal::$rxd,
3561 cts_signal: InputSignal::$cts,
3562 rts_signal: OutputSignal::$rts,
3563 };
3564 (&PERIPHERAL, &STATE)
3565 }
3566 }
3567 };
3568}
3569
3570crate::any_peripheral! {
3571 pub peripheral AnyUart<'d> {
3573 #[cfg(soc_has_uart0)]
3574 Uart0(crate::peripherals::UART0<'d>),
3575 #[cfg(soc_has_uart1)]
3576 Uart1(crate::peripherals::UART1<'d>),
3577 #[cfg(soc_has_uart2)]
3578 Uart2(crate::peripherals::UART2<'d>),
3579 }
3580}
3581
3582impl Instance for AnyUart<'_> {
3583 #[inline]
3584 fn parts(&self) -> (&'static Info, &'static State) {
3585 any::delegate!(self, uart => { uart.parts() })
3586 }
3587}
3588
3589impl AnyUart<'_> {
3590 fn bind_peri_interrupt(&self, handler: crate::interrupt::IsrCallback) {
3591 any::delegate!(self, uart => { uart.bind_peri_interrupt(handler) })
3592 }
3593
3594 fn disable_peri_interrupt(&self) {
3595 any::delegate!(self, uart => { uart.disable_peri_interrupt() })
3596 }
3597
3598 fn enable_peri_interrupt(&self, priority: crate::interrupt::Priority) {
3599 any::delegate!(self, uart => { uart.enable_peri_interrupt(priority) })
3600 }
3601
3602 fn set_interrupt_handler(&self, handler: InterruptHandler) {
3603 self.disable_peri_interrupt();
3604
3605 self.info().enable_listen(EnumSet::all(), false);
3606 self.info().clear_interrupts(EnumSet::all());
3607
3608 self.bind_peri_interrupt(handler.handler());
3609 self.enable_peri_interrupt(handler.priority());
3610 }
3611}