1use core::{marker::PhantomData, sync::atomic::Ordering, task::Poll};
45
46#[cfg(feature = "unstable")]
47use embedded_io::ReadExactError;
48use enumset::{EnumSet, EnumSetType};
49use portable_atomic::AtomicBool;
50
51use crate::{
52 Async,
53 Blocking,
54 DriverMode,
55 asynch::AtomicWaker,
56 clock::Clocks,
57 gpio::{
58 InputConfig,
59 InputSignal,
60 OutputConfig,
61 OutputSignal,
62 PinGuard,
63 Pull,
64 interconnect::{PeripheralInput, PeripheralOutput},
65 },
66 interrupt::InterruptHandler,
67 pac::uart0::RegisterBlock,
68 peripherals::Interrupt,
69 private::OnDrop,
70 system::{PeripheralClockControl, PeripheralGuard},
71};
72
73#[derive(Debug, Clone, Copy, PartialEq)]
75#[cfg_attr(feature = "defmt", derive(defmt::Format))]
76#[non_exhaustive]
77pub enum RxError {
78 FifoOverflowed,
83
84 GlitchOccurred,
90
91 FrameFormatViolated,
96
97 ParityMismatch,
102}
103
104impl core::error::Error for RxError {}
105
106impl core::fmt::Display for RxError {
107 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
108 match self {
109 RxError::FifoOverflowed => write!(f, "The RX FIFO overflowed"),
110 RxError::GlitchOccurred => write!(f, "A glitch was detected on the RX line"),
111 RxError::FrameFormatViolated => {
112 write!(f, "A framing error was detected on the RX line")
113 }
114 RxError::ParityMismatch => write!(f, "A parity error was detected on the RX line"),
115 }
116 }
117}
118
119#[instability::unstable]
120impl embedded_io::Error for RxError {
121 fn kind(&self) -> embedded_io::ErrorKind {
122 embedded_io::ErrorKind::Other
123 }
124}
125
126#[derive(Debug, Clone, Copy, PartialEq)]
128#[cfg_attr(feature = "defmt", derive(defmt::Format))]
129#[non_exhaustive]
130pub enum TxError {}
131
132impl core::fmt::Display for TxError {
133 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
134 write!(f, "Tx error")
135 }
136}
137
138#[instability::unstable]
139impl embedded_io::Error for TxError {
140 fn kind(&self) -> embedded_io::ErrorKind {
141 embedded_io::ErrorKind::Other
142 }
143}
144
145#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
147#[cfg_attr(feature = "defmt", derive(defmt::Format))]
148#[non_exhaustive]
149#[instability::unstable]
150pub enum ClockSource {
151 #[cfg_attr(not(any(esp32c6, esp32h2, lp_uart)), default)]
153 Apb,
154 #[cfg(not(any(esp32, esp32s2)))]
156 RcFast,
157 #[cfg(not(any(esp32, esp32s2)))]
159 #[cfg_attr(any(esp32c6, esp32h2, lp_uart), default)]
160 Xtal,
161 #[cfg(any(esp32, esp32s2))]
163 RefTick,
164}
165
166#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
172#[cfg_attr(feature = "defmt", derive(defmt::Format))]
173pub enum DataBits {
174 _5,
176 _6,
178 _7,
180 #[default]
182 _8,
183}
184
185#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
192#[cfg_attr(feature = "defmt", derive(defmt::Format))]
193pub enum Parity {
194 #[default]
196 None,
197 Even,
200 Odd,
203}
204
205#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
211#[cfg_attr(feature = "defmt", derive(defmt::Format))]
212pub enum StopBits {
213 #[default]
215 _1,
216 _1p5,
218 _2,
220}
221
222#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
224#[cfg_attr(feature = "defmt", derive(defmt::Format))]
225#[instability::unstable]
226pub enum SwFlowControl {
227 #[default]
228 Disabled,
230 Enabled {
232 xon_char: u8,
234 xoff_char: u8,
236 xon_threshold: u8,
239 xoff_threshold: u8,
242 },
243}
244
245#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
247#[cfg_attr(feature = "defmt", derive(defmt::Format))]
248#[instability::unstable]
249pub enum CtsConfig {
250 Enabled,
252 #[default]
253 Disabled,
255}
256
257#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
259#[cfg_attr(feature = "defmt", derive(defmt::Format))]
260#[instability::unstable]
261pub enum RtsConfig {
262 Enabled(u8),
264 #[default]
265 Disabled,
267}
268
269#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
271#[cfg_attr(feature = "defmt", derive(defmt::Format))]
272#[instability::unstable]
273pub struct HwFlowControl {
274 pub cts: CtsConfig,
276 pub rts: RtsConfig,
278}
279
280#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
282#[cfg_attr(feature = "defmt", derive(defmt::Format))]
283#[instability::unstable]
284pub enum BaudrateTolerance {
285 #[default]
287 Closest,
288 Exact,
291 ErrorPercent(u8),
293}
294
295#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
297#[cfg_attr(feature = "defmt", derive(defmt::Format))]
298#[non_exhaustive]
299pub struct Config {
300 baudrate: u32,
303 #[builder_lite(unstable)]
306 baudrate_tolerance: BaudrateTolerance,
307 data_bits: DataBits,
309 parity: Parity,
311 stop_bits: StopBits,
313 #[builder_lite(unstable)]
315 sw_flow_ctrl: SwFlowControl,
316 #[builder_lite(unstable)]
318 hw_flow_ctrl: HwFlowControl,
319 #[builder_lite(unstable)]
321 clock_source: ClockSource,
322 rx: RxConfig,
324 tx: TxConfig,
326}
327
328impl Default for Config {
329 fn default() -> Config {
330 Config {
331 rx: RxConfig::default(),
332 tx: TxConfig::default(),
333 baudrate: 115_200,
334 baudrate_tolerance: BaudrateTolerance::default(),
335 data_bits: Default::default(),
336 parity: Default::default(),
337 stop_bits: Default::default(),
338 sw_flow_ctrl: Default::default(),
339 hw_flow_ctrl: Default::default(),
340 clock_source: Default::default(),
341 }
342 }
343}
344
345impl Config {
346 fn validate(&self) -> Result<(), ConfigError> {
347 if let BaudrateTolerance::ErrorPercent(percentage) = self.baudrate_tolerance {
348 assert!(percentage > 0 && percentage <= 100);
349 }
350
351 if self.baudrate == 0 || self.baudrate > 5_000_000 {
353 return Err(ConfigError::UnsupportedBaudrate);
354 }
355 Ok(())
356 }
357}
358
359#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
361#[cfg_attr(feature = "defmt", derive(defmt::Format))]
362#[non_exhaustive]
363pub struct RxConfig {
364 fifo_full_threshold: u16,
366 timeout: Option<u8>,
368}
369
370impl Default for RxConfig {
371 fn default() -> RxConfig {
372 RxConfig {
373 fifo_full_threshold: 120,
375 timeout: Some(10),
377 }
378 }
379}
380
381#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
383#[cfg_attr(feature = "defmt", derive(defmt::Format))]
384#[non_exhaustive]
385pub struct TxConfig {
386 fifo_empty_threshold: u16,
388}
389
390impl Default for TxConfig {
391 fn default() -> TxConfig {
392 TxConfig {
393 fifo_empty_threshold: 10,
395 }
396 }
397}
398
399#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
401#[cfg_attr(feature = "defmt", derive(defmt::Format))]
402#[instability::unstable]
403#[non_exhaustive]
404pub struct AtCmdConfig {
405 pre_idle_count: Option<u16>,
408 post_idle_count: Option<u16>,
411 gap_timeout: Option<u16>,
414 cmd_char: u8,
416 char_num: u8,
418}
419
420impl Default for AtCmdConfig {
421 fn default() -> Self {
422 Self {
423 pre_idle_count: None,
424 post_idle_count: None,
425 gap_timeout: None,
426 cmd_char: b'+',
427 char_num: 1,
428 }
429 }
430}
431
432struct UartBuilder<'d, Dm: DriverMode> {
433 uart: AnyUart<'d>,
434 phantom: PhantomData<Dm>,
435}
436
437impl<'d, Dm> UartBuilder<'d, Dm>
438where
439 Dm: DriverMode,
440{
441 fn new(uart: impl Instance + 'd) -> Self {
442 Self {
443 uart: uart.degrade(),
444 phantom: PhantomData,
445 }
446 }
447
448 fn init(self, config: Config) -> Result<Uart<'d, Dm>, ConfigError> {
449 let rx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
450 let tx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
451
452 let rts_pin = PinGuard::new_unconnected(self.uart.info().rts_signal);
453 let tx_pin = PinGuard::new_unconnected(self.uart.info().tx_signal);
454
455 let mut serial = Uart {
456 rx: UartRx {
457 uart: unsafe { self.uart.clone_unchecked() },
458 phantom: PhantomData,
459 guard: rx_guard,
460 },
461 tx: UartTx {
462 uart: self.uart,
463 phantom: PhantomData,
464 guard: tx_guard,
465 rts_pin,
466 tx_pin,
467 },
468 };
469 serial.init(config)?;
470
471 Ok(serial)
472 }
473}
474
475#[doc = crate::before_snippet!()]
479pub struct Uart<'d, Dm: DriverMode> {
491 rx: UartRx<'d, Dm>,
492 tx: UartTx<'d, Dm>,
493}
494
495#[instability::unstable]
497pub struct UartTx<'d, Dm: DriverMode> {
498 uart: AnyUart<'d>,
499 phantom: PhantomData<Dm>,
500 guard: PeripheralGuard,
501 rts_pin: PinGuard,
502 tx_pin: PinGuard,
503}
504
505#[instability::unstable]
507pub struct UartRx<'d, Dm: DriverMode> {
508 uart: AnyUart<'d>,
509 phantom: PhantomData<Dm>,
510 guard: PeripheralGuard,
511}
512
513#[derive(Debug, Clone, Copy, PartialEq, Eq)]
515#[cfg_attr(feature = "defmt", derive(defmt::Format))]
516#[non_exhaustive]
517pub enum ConfigError {
518 #[cfg(feature = "unstable")]
520 #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
521 UnachievableBaudrate,
522
523 UnsupportedBaudrate,
531
532 #[cfg_attr(esp32, doc = "127")]
534 #[cfg_attr(not(esp32), doc = "1023")]
535 UnsupportedTimeout,
537
538 UnsupportedRxFifoThreshold,
540
541 UnsupportedTxFifoThreshold,
543}
544
545impl core::error::Error for ConfigError {}
546
547impl core::fmt::Display for ConfigError {
548 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
549 match self {
550 #[cfg(feature = "unstable")]
551 ConfigError::UnachievableBaudrate => {
552 write!(f, "The requested baud rate is not achievable")
553 }
554 ConfigError::UnsupportedBaudrate => {
555 write!(f, "The requested baud rate is not supported")
556 }
557 ConfigError::UnsupportedTimeout => write!(f, "The requested timeout is not supported"),
558 ConfigError::UnsupportedRxFifoThreshold => {
559 write!(f, "The requested RX FIFO threshold is not supported")
560 }
561 ConfigError::UnsupportedTxFifoThreshold => {
562 write!(f, "The requested TX FIFO threshold is not supported")
563 }
564 }
565 }
566}
567
568#[instability::unstable]
569impl<Dm> embassy_embedded_hal::SetConfig for Uart<'_, Dm>
570where
571 Dm: DriverMode,
572{
573 type Config = Config;
574 type ConfigError = ConfigError;
575
576 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
577 self.apply_config(config)
578 }
579}
580
581#[instability::unstable]
582impl<Dm> embassy_embedded_hal::SetConfig for UartRx<'_, Dm>
583where
584 Dm: DriverMode,
585{
586 type Config = Config;
587 type ConfigError = ConfigError;
588
589 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
590 self.apply_config(config)
591 }
592}
593
594#[instability::unstable]
595impl<Dm> embassy_embedded_hal::SetConfig for UartTx<'_, Dm>
596where
597 Dm: DriverMode,
598{
599 type Config = Config;
600 type ConfigError = ConfigError;
601
602 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
603 self.apply_config(config)
604 }
605}
606
607impl<'d> UartTx<'d, Blocking> {
608 #[doc = crate::before_snippet!()]
619 #[instability::unstable]
628 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
629 let (_, uart_tx) = UartBuilder::new(uart).init(config)?.split();
630
631 Ok(uart_tx)
632 }
633
634 #[instability::unstable]
636 pub fn into_async(self) -> UartTx<'d, Async> {
637 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
638 self.uart
639 .info()
640 .set_interrupt_handler(self.uart.info().async_handler);
641 }
642 self.uart.state().is_tx_async.store(true, Ordering::Release);
643
644 UartTx {
645 uart: self.uart,
646 phantom: PhantomData,
647 guard: self.guard,
648 rts_pin: self.rts_pin,
649 tx_pin: self.tx_pin,
650 }
651 }
652}
653
654impl<'d> UartTx<'d, Async> {
655 #[instability::unstable]
657 pub fn into_blocking(self) -> UartTx<'d, Blocking> {
658 self.uart
659 .state()
660 .is_tx_async
661 .store(false, Ordering::Release);
662 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
663 self.uart.info().disable_interrupts();
664 }
665
666 UartTx {
667 uart: self.uart,
668 phantom: PhantomData,
669 guard: self.guard,
670 rts_pin: self.rts_pin,
671 tx_pin: self.tx_pin,
672 }
673 }
674
675 pub async fn write_async(&mut self, bytes: &[u8]) -> Result<usize, TxError> {
691 let space = loop {
694 let tx_fifo_count = self.uart.info().tx_fifo_count();
695 let space = Info::UART_FIFO_SIZE - tx_fifo_count;
696 if space != 0 {
697 break space;
698 }
699 UartTxFuture::new(self.uart.reborrow(), TxEvent::FiFoEmpty).await;
700 };
701
702 let free = (space as usize).min(bytes.len());
703
704 for &byte in &bytes[..free] {
705 self.uart
706 .info()
707 .regs()
708 .fifo()
709 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
710 }
711
712 Ok(free)
713 }
714
715 pub async fn flush_async(&mut self) -> Result<(), TxError> {
725 while self.uart.info().tx_fifo_count() > 0 {
729 UartTxFuture::new(self.uart.reborrow(), TxEvent::Done).await;
730 }
731
732 self.flush_last_byte();
733
734 Ok(())
735 }
736}
737
738impl<'d, Dm> UartTx<'d, Dm>
739where
740 Dm: DriverMode,
741{
742 #[instability::unstable]
744 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
745 let rts = rts.into();
746
747 rts.apply_output_config(&OutputConfig::default());
748 rts.set_output_enable(true);
749
750 self.rts_pin = rts.connect_with_guard(self.uart.info().rts_signal);
751
752 self
753 }
754
755 #[instability::unstable]
762 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
763 let tx = tx.into();
764
765 tx.set_output_high(true);
767 tx.apply_output_config(&OutputConfig::default());
768 tx.set_output_enable(true);
769
770 self.tx_pin = tx.connect_with_guard(self.uart.info().tx_signal);
771
772 self
773 }
774
775 #[instability::unstable]
782 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
783 self.uart
784 .info()
785 .set_tx_fifo_empty_threshold(config.tx.fifo_empty_threshold)?;
786 self.uart.info().txfifo_reset();
787 Ok(())
788 }
789
790 #[instability::unstable]
794 pub fn write_ready(&mut self) -> bool {
795 self.uart.info().tx_fifo_count() < Info::UART_FIFO_SIZE
796 }
797
798 #[instability::unstable]
812 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
813 self.uart.info().write(data)
814 }
815
816 fn write_all(&mut self, mut data: &[u8]) -> Result<(), TxError> {
817 while !data.is_empty() {
818 let bytes_written = self.write(data)?;
819 data = &data[bytes_written..];
820 }
821 Ok(())
822 }
823
824 #[instability::unstable]
829 pub fn flush(&mut self) -> Result<(), TxError> {
830 while self.uart.info().tx_fifo_count() > 0 {}
831 self.flush_last_byte();
832 Ok(())
833 }
834
835 fn flush_last_byte(&mut self) {
836 crate::rom::ets_delay_us(10);
842 while !self.is_tx_idle() {}
843 }
844
845 fn is_tx_idle(&self) -> bool {
850 #[cfg(esp32)]
851 let status = self.regs().status();
852 #[cfg(not(esp32))]
853 let status = self.regs().fsm_status();
854
855 status.read().st_utx_out().bits() == 0x0
856 }
857
858 fn disable_tx_interrupts(&self) {
864 self.regs().int_clr().write(|w| {
865 w.txfifo_empty().clear_bit_by_one();
866 w.tx_brk_done().clear_bit_by_one();
867 w.tx_brk_idle_done().clear_bit_by_one();
868 w.tx_done().clear_bit_by_one()
869 });
870
871 self.regs().int_ena().write(|w| {
872 w.txfifo_empty().clear_bit();
873 w.tx_brk_done().clear_bit();
874 w.tx_brk_idle_done().clear_bit();
875 w.tx_done().clear_bit()
876 });
877 }
878
879 fn regs(&self) -> &RegisterBlock {
880 self.uart.info().regs()
881 }
882}
883
884#[inline(always)]
885fn sync_regs(_register_block: &RegisterBlock) {
886 #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
887 {
888 cfg_if::cfg_if! {
889 if #[cfg(any(esp32c6, esp32h2))] {
890 let update_reg = _register_block.reg_update();
891 } else {
892 let update_reg = _register_block.id();
893 }
894 }
895
896 update_reg.modify(|_, w| w.reg_update().set_bit());
897
898 while update_reg.read().reg_update().bit_is_set() {
899 }
901 }
902}
903
904impl<'d> UartRx<'d, Blocking> {
905 #[doc = crate::before_snippet!()]
914 #[instability::unstable]
923 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
924 let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();
925
926 Ok(uart_rx)
927 }
928
929 #[instability::unstable]
931 pub fn into_async(self) -> UartRx<'d, Async> {
932 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
933 self.uart
934 .info()
935 .set_interrupt_handler(self.uart.info().async_handler);
936 }
937 self.uart.state().is_rx_async.store(true, Ordering::Release);
938
939 UartRx {
940 uart: self.uart,
941 phantom: PhantomData,
942 guard: self.guard,
943 }
944 }
945}
946
947impl<'d> UartRx<'d, Async> {
948 #[instability::unstable]
950 pub fn into_blocking(self) -> UartRx<'d, Blocking> {
951 self.uart
952 .state()
953 .is_rx_async
954 .store(false, Ordering::Release);
955 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
956 self.uart.info().disable_interrupts();
957 }
958
959 UartRx {
960 uart: self.uart,
961 phantom: PhantomData,
962 guard: self.guard,
963 }
964 }
965
966 async fn wait_for_buffered_data(
967 &mut self,
968 minimum: usize,
969 preferred: usize,
970 listen_for_timeout: bool,
971 ) -> Result<(), RxError> {
972 while self.uart.info().rx_fifo_count() < (minimum as u16).min(Info::RX_FIFO_MAX_THRHD) {
973 let amount = u16::try_from(preferred)
974 .unwrap_or(Info::RX_FIFO_MAX_THRHD)
975 .min(Info::RX_FIFO_MAX_THRHD);
976
977 let current = self.uart.info().rx_fifo_full_threshold();
978 let _guard = if current > amount {
979 let info = self.uart.info();
983 unwrap!(info.set_rx_fifo_full_threshold(amount));
984 Some(OnDrop::new(|| {
985 unwrap!(info.set_rx_fifo_full_threshold(current));
986 }))
987 } else {
988 None
989 };
990
991 let mut events = RxEvent::FifoFull
993 | RxEvent::FifoOvf
994 | RxEvent::FrameError
995 | RxEvent::GlitchDetected
996 | RxEvent::ParityError;
997
998 if self.regs().at_cmd_char().read().char_num().bits() > 0 {
999 events |= RxEvent::CmdCharDetected;
1000 }
1001
1002 cfg_if::cfg_if! {
1003 if #[cfg(any(esp32c6, esp32h2))] {
1004 let reg_en = self.regs().tout_conf();
1005 } else {
1006 let reg_en = self.regs().conf1();
1007 }
1008 };
1009 if listen_for_timeout && reg_en.read().rx_tout_en().bit_is_set() {
1010 events |= RxEvent::FifoTout;
1011 }
1012
1013 let events = UartRxFuture::new(self.uart.reborrow(), events).await;
1014
1015 let result = rx_event_check_for_error(events);
1016 if let Err(error) = result {
1017 if error == RxError::FifoOverflowed {
1018 self.uart.info().rxfifo_reset();
1019 }
1020 return Err(error);
1021 }
1022 }
1023
1024 Ok(())
1025 }
1026
1027 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1046 if buf.is_empty() {
1047 return Ok(0);
1048 }
1049
1050 self.wait_for_buffered_data(1, buf.len(), true).await?;
1051
1052 self.read_buffered(buf)
1053 }
1054
1055 pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
1070 while !buf.is_empty() {
1071 self.wait_for_buffered_data(buf.len(), buf.len(), false)
1075 .await?;
1076
1077 let read = self.uart.info().read_buffered(buf)?;
1078 buf = &mut buf[read..];
1079 }
1080
1081 Ok(())
1082 }
1083}
1084
1085impl<'d, Dm> UartRx<'d, Dm>
1086where
1087 Dm: DriverMode,
1088{
1089 fn regs(&self) -> &RegisterBlock {
1090 self.uart.info().regs()
1091 }
1092
1093 #[instability::unstable]
1097 pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
1098 let cts = cts.into();
1099
1100 cts.apply_input_config(&InputConfig::default());
1101 cts.set_input_enable(true);
1102
1103 self.uart.info().cts_signal.connect_to(&cts);
1104
1105 self
1106 }
1107
1108 #[instability::unstable]
1117 pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
1118 let rx = rx.into();
1119
1120 rx.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
1121 rx.set_input_enable(true);
1122
1123 self.uart.info().rx_signal.connect_to(&rx);
1124
1125 self
1126 }
1127
1128 #[instability::unstable]
1135 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1136 self.uart
1137 .info()
1138 .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
1139 self.uart
1140 .info()
1141 .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
1142
1143 self.uart.info().rxfifo_reset();
1144 Ok(())
1145 }
1146
1147 #[instability::unstable]
1151 pub fn check_for_errors(&mut self) -> Result<(), RxError> {
1152 self.uart.info().check_for_errors()
1153 }
1154
1155 #[instability::unstable]
1159 pub fn read_ready(&mut self) -> bool {
1160 self.uart.info().rx_fifo_count() > 0
1161 }
1162
1163 #[instability::unstable]
1182 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1183 self.uart.info().read(buf)
1184 }
1185
1186 #[instability::unstable]
1204 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1205 self.uart.info().read_buffered(buf)
1206 }
1207
1208 fn disable_rx_interrupts(&self) {
1214 self.regs().int_clr().write(|w| {
1215 w.rxfifo_full().clear_bit_by_one();
1216 w.rxfifo_ovf().clear_bit_by_one();
1217 w.rxfifo_tout().clear_bit_by_one();
1218 w.at_cmd_char_det().clear_bit_by_one()
1219 });
1220
1221 self.regs().int_ena().write(|w| {
1222 w.rxfifo_full().clear_bit();
1223 w.rxfifo_ovf().clear_bit();
1224 w.rxfifo_tout().clear_bit();
1225 w.at_cmd_char_det().clear_bit()
1226 });
1227 }
1228}
1229
1230impl<'d> Uart<'d, Blocking> {
1231 #[doc = crate::before_snippet!()]
1242 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1252 UartBuilder::new(uart).init(config)
1253 }
1254
1255 pub fn into_async(self) -> Uart<'d, Async> {
1257 Uart {
1258 rx: self.rx.into_async(),
1259 tx: self.tx.into_async(),
1260 }
1261 }
1262
1263 #[cfg_attr(
1264 not(multi_core),
1265 doc = "Registers an interrupt handler for the peripheral."
1266 )]
1267 #[cfg_attr(
1268 multi_core,
1269 doc = "Registers an interrupt handler for the peripheral on the current core."
1270 )]
1271 #[doc = ""]
1272 #[instability::unstable]
1278 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1279 self.tx.uart.info().set_interrupt_handler(handler);
1281 }
1282
1283 #[doc = crate::before_snippet!()]
1292 #[instability::unstable]
1349 pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1350 self.tx.uart.info().enable_listen(interrupts.into(), true)
1351 }
1352
1353 #[instability::unstable]
1355 pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1356 self.tx.uart.info().enable_listen(interrupts.into(), false)
1357 }
1358
1359 #[instability::unstable]
1361 pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1362 self.tx.uart.info().interrupts()
1363 }
1364
1365 #[instability::unstable]
1367 pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1368 self.tx.uart.info().clear_interrupts(interrupts)
1369 }
1370}
1371
1372impl<'d> Uart<'d, Async> {
1373 pub fn into_blocking(self) -> Uart<'d, Blocking> {
1375 Uart {
1376 rx: self.rx.into_blocking(),
1377 tx: self.tx.into_blocking(),
1378 }
1379 }
1380
1381 pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1397 self.tx.write_async(words).await
1398 }
1399
1400 pub async fn flush_async(&mut self) -> Result<(), TxError> {
1410 self.tx.flush_async().await
1411 }
1412
1413 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1432 self.rx.read_async(buf).await
1433 }
1434
1435 #[instability::unstable]
1450 pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1451 self.rx.read_exact_async(buf).await
1452 }
1453}
1454
1455#[derive(Debug, EnumSetType)]
1457#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1458#[non_exhaustive]
1459#[instability::unstable]
1460pub enum UartInterrupt {
1461 AtCmd,
1464
1465 TxDone,
1467
1468 RxFifoFull,
1471
1472 RxTimeout,
1475}
1476
1477impl<'d, Dm> Uart<'d, Dm>
1478where
1479 Dm: DriverMode,
1480{
1481 pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
1490 self.rx = self.rx.with_rx(rx);
1491 self
1492 }
1493
1494 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
1499 self.tx = self.tx.with_tx(tx);
1500 self
1501 }
1502
1503 pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
1505 self.rx = self.rx.with_cts(cts);
1506 self
1507 }
1508
1509 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
1511 self.tx = self.tx.with_rts(rts);
1512 self
1513 }
1514
1515 fn regs(&self) -> &RegisterBlock {
1516 self.tx.uart.info().regs()
1518 }
1519
1520 #[instability::unstable]
1524 pub fn write_ready(&mut self) -> bool {
1525 self.tx.write_ready()
1526 }
1527
1528 #[doc = crate::before_snippet!()]
1546 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
1556 self.tx.write(data)
1557 }
1558
1559 pub fn flush(&mut self) -> Result<(), TxError> {
1561 self.tx.flush()
1562 }
1563
1564 #[instability::unstable]
1568 pub fn read_ready(&mut self) -> bool {
1569 self.rx.read_ready()
1570 }
1571
1572 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1590 self.rx.read(buf)
1591 }
1592
1593 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1600 self.rx.uart.info().apply_config(config)?;
1603 self.rx.apply_config(config)?;
1604 self.tx.apply_config(config)?;
1605 Ok(())
1606 }
1607
1608 #[doc = crate::before_snippet!()]
1617 #[instability::unstable]
1634 pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
1635 (self.rx, self.tx)
1636 }
1637
1638 #[instability::unstable]
1640 pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
1641 self.rx.check_for_errors()
1642 }
1643
1644 #[instability::unstable]
1661 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1662 self.rx.read_buffered(buf)
1663 }
1664
1665 #[instability::unstable]
1667 pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
1668 #[cfg(not(any(esp32, esp32s2)))]
1669 self.regs()
1670 .clk_conf()
1671 .modify(|_, w| w.sclk_en().clear_bit());
1672
1673 self.regs().at_cmd_char().write(|w| unsafe {
1674 w.at_cmd_char().bits(config.cmd_char);
1675 w.char_num().bits(config.char_num)
1676 });
1677
1678 if let Some(pre_idle_count) = config.pre_idle_count {
1679 self.regs()
1680 .at_cmd_precnt()
1681 .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
1682 }
1683
1684 if let Some(post_idle_count) = config.post_idle_count {
1685 self.regs()
1686 .at_cmd_postcnt()
1687 .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
1688 }
1689
1690 if let Some(gap_timeout) = config.gap_timeout {
1691 self.regs()
1692 .at_cmd_gaptout()
1693 .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
1694 }
1695
1696 #[cfg(not(any(esp32, esp32s2)))]
1697 self.regs().clk_conf().modify(|_, w| w.sclk_en().set_bit());
1698
1699 sync_regs(self.regs());
1700 }
1701
1702 #[inline(always)]
1703 fn init(&mut self, config: Config) -> Result<(), ConfigError> {
1704 cfg_if::cfg_if! {
1705 if #[cfg(any(esp32, esp32s2))] {
1706 } else if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
1708 crate::peripherals::SYSTEM::regs()
1709 .perip_clk_en0()
1710 .modify(|_, w| w.uart_mem_clk_en().set_bit());
1711 } else {
1712 self.regs()
1713 .conf0()
1714 .modify(|_, w| w.mem_clk_en().set_bit());
1715 }
1716 };
1717
1718 self.uart_peripheral_reset();
1719
1720 self.rx.disable_rx_interrupts();
1721 self.tx.disable_tx_interrupts();
1722
1723 self.apply_config(&config)?;
1724
1725 self.rx.uart.info().rxfifo_reset();
1727 self.rx.uart.info().txfifo_reset();
1728
1729 self.regs()
1732 .idle_conf()
1733 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
1734
1735 self.regs().conf0().modify(|_, w| w.err_wr_mask().set_bit());
1738
1739 crate::rom::ets_delay_us(15);
1740
1741 self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
1744
1745 Ok(())
1746 }
1747
1748 fn is_instance(&self, other: impl Instance) -> bool {
1749 self.tx.uart.info().is_instance(other)
1750 }
1751
1752 #[inline(always)]
1753 fn uart_peripheral_reset(&self) {
1754 if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
1765 return;
1766 }
1767
1768 fn rst_core(_reg_block: &RegisterBlock, _enable: bool) {
1769 #[cfg(not(any(esp32, esp32s2, esp32c6, esp32h2)))]
1770 _reg_block
1771 .clk_conf()
1772 .modify(|_, w| w.rst_core().bit(_enable));
1773 }
1774
1775 rst_core(self.regs(), true);
1776 PeripheralClockControl::reset(self.tx.uart.info().peripheral);
1777 rst_core(self.regs(), false);
1778 }
1779}
1780
1781impl crate::private::Sealed for Uart<'_, Blocking> {}
1782
1783#[instability::unstable]
1784impl crate::interrupt::InterruptConfigurable for Uart<'_, Blocking> {
1785 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1786 self.tx.uart.info().set_interrupt_handler(handler);
1788 }
1789}
1790
1791#[instability::unstable]
1792impl<Dm> ufmt_write::uWrite for Uart<'_, Dm>
1793where
1794 Dm: DriverMode,
1795{
1796 type Error = TxError;
1797
1798 #[inline]
1799 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1800 self.tx.write_str(s)
1801 }
1802
1803 #[inline]
1804 fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
1805 self.tx.write_char(ch)
1806 }
1807}
1808
1809#[instability::unstable]
1810impl<Dm> ufmt_write::uWrite for UartTx<'_, Dm>
1811where
1812 Dm: DriverMode,
1813{
1814 type Error = TxError;
1815
1816 #[inline]
1817 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1818 self.write_all(s.as_bytes())
1819 }
1820}
1821
1822impl<Dm> core::fmt::Write for Uart<'_, Dm>
1823where
1824 Dm: DriverMode,
1825{
1826 #[inline]
1827 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1828 self.tx.write_str(s)
1829 }
1830}
1831
1832impl<Dm> core::fmt::Write for UartTx<'_, Dm>
1833where
1834 Dm: DriverMode,
1835{
1836 #[inline]
1837 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1838 self.write_all(s.as_bytes()).map_err(|_| core::fmt::Error)
1839 }
1840}
1841
1842#[instability::unstable]
1844#[derive(Debug, Clone, Copy, PartialEq)]
1845#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1846#[non_exhaustive]
1847pub enum IoError {
1848 Tx(TxError),
1850 Rx(RxError),
1852}
1853
1854#[instability::unstable]
1855impl core::error::Error for IoError {}
1856
1857#[instability::unstable]
1858impl core::fmt::Display for IoError {
1859 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1860 match self {
1861 IoError::Tx(e) => e.fmt(f),
1862 IoError::Rx(e) => e.fmt(f),
1863 }
1864 }
1865}
1866
1867#[instability::unstable]
1868impl embedded_io::Error for IoError {
1869 fn kind(&self) -> embedded_io::ErrorKind {
1870 embedded_io::ErrorKind::Other
1871 }
1872}
1873
1874#[instability::unstable]
1875impl From<RxError> for IoError {
1876 fn from(e: RxError) -> Self {
1877 IoError::Rx(e)
1878 }
1879}
1880
1881#[instability::unstable]
1882impl From<TxError> for IoError {
1883 fn from(e: TxError) -> Self {
1884 IoError::Tx(e)
1885 }
1886}
1887
1888#[instability::unstable]
1889impl<Dm: DriverMode> embedded_io::ErrorType for Uart<'_, Dm> {
1890 type Error = IoError;
1891}
1892
1893#[instability::unstable]
1894impl<Dm: DriverMode> embedded_io::ErrorType for UartTx<'_, Dm> {
1895 type Error = TxError;
1896}
1897
1898#[instability::unstable]
1899impl<Dm: DriverMode> embedded_io::ErrorType for UartRx<'_, Dm> {
1900 type Error = RxError;
1901}
1902
1903#[instability::unstable]
1904impl<Dm> embedded_io::Read for Uart<'_, Dm>
1905where
1906 Dm: DriverMode,
1907{
1908 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
1909 self.rx.read(buf).map_err(IoError::Rx)
1910 }
1911}
1912
1913#[instability::unstable]
1914impl<Dm> embedded_io::Read for UartRx<'_, Dm>
1915where
1916 Dm: DriverMode,
1917{
1918 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
1919 self.read(buf)
1920 }
1921}
1922
1923#[instability::unstable]
1924impl<Dm> embedded_io::ReadReady for Uart<'_, Dm>
1925where
1926 Dm: DriverMode,
1927{
1928 fn read_ready(&mut self) -> Result<bool, Self::Error> {
1929 Ok(self.rx.read_ready())
1930 }
1931}
1932
1933#[instability::unstable]
1934impl<Dm> embedded_io::ReadReady for UartRx<'_, Dm>
1935where
1936 Dm: DriverMode,
1937{
1938 fn read_ready(&mut self) -> Result<bool, Self::Error> {
1939 Ok(self.read_ready())
1940 }
1941}
1942
1943#[instability::unstable]
1944impl<Dm> embedded_io::Write for Uart<'_, Dm>
1945where
1946 Dm: DriverMode,
1947{
1948 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1949 self.tx.write(buf).map_err(IoError::Tx)
1950 }
1951
1952 fn flush(&mut self) -> Result<(), Self::Error> {
1953 self.tx.flush().map_err(IoError::Tx)
1954 }
1955}
1956
1957#[instability::unstable]
1958impl<Dm> embedded_io::Write for UartTx<'_, Dm>
1959where
1960 Dm: DriverMode,
1961{
1962 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1963 self.write(buf)
1964 }
1965
1966 fn flush(&mut self) -> Result<(), Self::Error> {
1967 self.flush()
1968 }
1969}
1970
1971#[instability::unstable]
1972impl<Dm> embedded_io::WriteReady for UartTx<'_, Dm>
1973where
1974 Dm: DriverMode,
1975{
1976 fn write_ready(&mut self) -> Result<bool, Self::Error> {
1977 Ok(self.write_ready())
1978 }
1979}
1980
1981#[instability::unstable]
1982impl<Dm> embedded_io::WriteReady for Uart<'_, Dm>
1983where
1984 Dm: DriverMode,
1985{
1986 fn write_ready(&mut self) -> Result<bool, Self::Error> {
1987 Ok(self.tx.write_ready())
1988 }
1989}
1990
1991#[derive(Debug, EnumSetType)]
1992pub(crate) enum TxEvent {
1993 Done,
1994 FiFoEmpty,
1995}
1996
1997#[derive(Debug, EnumSetType)]
1998pub(crate) enum RxEvent {
1999 FifoFull,
2000 CmdCharDetected,
2001 FifoOvf,
2002 FifoTout,
2003 GlitchDetected,
2004 FrameError,
2005 ParityError,
2006}
2007
2008fn rx_event_check_for_error(events: EnumSet<RxEvent>) -> Result<(), RxError> {
2009 for event in events {
2010 match event {
2011 RxEvent::FifoOvf => return Err(RxError::FifoOverflowed),
2012 RxEvent::GlitchDetected => return Err(RxError::GlitchOccurred),
2013 RxEvent::FrameError => return Err(RxError::FrameFormatViolated),
2014 RxEvent::ParityError => return Err(RxError::ParityMismatch),
2015 RxEvent::FifoFull | RxEvent::CmdCharDetected | RxEvent::FifoTout => continue,
2016 }
2017 }
2018
2019 Ok(())
2020}
2021
2022#[must_use = "futures do nothing unless you `.await` or poll them"]
2028struct UartRxFuture {
2029 events: EnumSet<RxEvent>,
2030 uart: &'static Info,
2031 state: &'static State,
2032 registered: bool,
2033}
2034
2035impl UartRxFuture {
2036 fn new(uart: impl Instance, events: impl Into<EnumSet<RxEvent>>) -> Self {
2037 Self {
2038 events: events.into(),
2039 uart: uart.info(),
2040 state: uart.state(),
2041 registered: false,
2042 }
2043 }
2044}
2045
2046impl core::future::Future for UartRxFuture {
2047 type Output = EnumSet<RxEvent>;
2048
2049 fn poll(
2050 mut self: core::pin::Pin<&mut Self>,
2051 cx: &mut core::task::Context<'_>,
2052 ) -> core::task::Poll<Self::Output> {
2053 let events = self.uart.rx_events().intersection(self.events);
2054 if !events.is_empty() {
2055 self.uart.clear_rx_events(events);
2056 Poll::Ready(events)
2057 } else {
2058 self.state.rx_waker.register(cx.waker());
2059 if !self.registered {
2060 self.uart.enable_listen_rx(self.events, true);
2061 self.registered = true;
2062 }
2063 Poll::Pending
2064 }
2065 }
2066}
2067
2068impl Drop for UartRxFuture {
2069 fn drop(&mut self) {
2070 self.uart.enable_listen_rx(self.events, false);
2074 }
2075}
2076
2077#[must_use = "futures do nothing unless you `.await` or poll them"]
2078struct UartTxFuture {
2079 events: EnumSet<TxEvent>,
2080 uart: &'static Info,
2081 state: &'static State,
2082 registered: bool,
2083}
2084
2085impl UartTxFuture {
2086 fn new(uart: impl Instance, events: impl Into<EnumSet<TxEvent>>) -> Self {
2087 Self {
2088 events: events.into(),
2089 uart: uart.info(),
2090 state: uart.state(),
2091 registered: false,
2092 }
2093 }
2094}
2095
2096impl core::future::Future for UartTxFuture {
2097 type Output = ();
2098
2099 fn poll(
2100 mut self: core::pin::Pin<&mut Self>,
2101 cx: &mut core::task::Context<'_>,
2102 ) -> core::task::Poll<Self::Output> {
2103 let events = self.uart.tx_events().intersection(self.events);
2104 if !events.is_empty() {
2105 self.uart.clear_tx_events(events);
2106 Poll::Ready(())
2107 } else {
2108 self.state.tx_waker.register(cx.waker());
2109 if !self.registered {
2110 self.uart.enable_listen_tx(self.events, true);
2111 self.registered = true;
2112 }
2113 Poll::Pending
2114 }
2115 }
2116}
2117
2118impl Drop for UartTxFuture {
2119 fn drop(&mut self) {
2120 self.uart.enable_listen_tx(self.events, false);
2124 }
2125}
2126
2127#[instability::unstable]
2128impl embedded_io_async::Read for Uart<'_, Async> {
2129 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2130 self.read_async(buf).await.map_err(IoError::Rx)
2131 }
2132
2133 async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError<Self::Error>> {
2134 self.read_exact_async(buf)
2135 .await
2136 .map_err(|e| ReadExactError::Other(IoError::Rx(e)))
2137 }
2138}
2139
2140#[instability::unstable]
2141impl embedded_io_async::Read for UartRx<'_, Async> {
2142 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2143 self.read_async(buf).await
2144 }
2145
2146 async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError<Self::Error>> {
2147 self.read_exact_async(buf)
2148 .await
2149 .map_err(ReadExactError::Other)
2150 }
2151}
2152
2153#[instability::unstable]
2154impl embedded_io_async::Write for Uart<'_, Async> {
2155 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2156 self.write_async(buf).await.map_err(IoError::Tx)
2157 }
2158
2159 async fn flush(&mut self) -> Result<(), Self::Error> {
2160 self.flush_async().await.map_err(IoError::Tx)
2161 }
2162}
2163
2164#[instability::unstable]
2165impl embedded_io_async::Write for UartTx<'_, Async> {
2166 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2167 self.write_async(buf).await
2168 }
2169
2170 async fn flush(&mut self) -> Result<(), Self::Error> {
2171 self.flush_async().await
2172 }
2173}
2174
2175pub(super) fn intr_handler(uart: &Info, state: &State) {
2180 let interrupts = uart.regs().int_st().read();
2181 let interrupt_bits = interrupts.bits(); let rx_wake = interrupts.rxfifo_full().bit_is_set()
2183 | interrupts.rxfifo_ovf().bit_is_set()
2184 | interrupts.rxfifo_tout().bit_is_set()
2185 | interrupts.at_cmd_char_det().bit_is_set()
2186 | interrupts.glitch_det().bit_is_set()
2187 | interrupts.frm_err().bit_is_set()
2188 | interrupts.parity_err().bit_is_set();
2189 let tx_wake = interrupts.tx_done().bit_is_set() | interrupts.txfifo_empty().bit_is_set();
2190
2191 uart.regs()
2192 .int_ena()
2193 .modify(|r, w| unsafe { w.bits(r.bits() & !interrupt_bits) });
2194
2195 if tx_wake {
2196 state.tx_waker.wake();
2197 }
2198 if rx_wake {
2199 state.rx_waker.wake();
2200 }
2201}
2202
2203#[cfg(lp_uart)]
2205#[instability::unstable]
2206pub mod lp_uart {
2207 use crate::{
2208 gpio::lp_io::{LowPowerInput, LowPowerOutput},
2209 peripherals::{LP_AON, LP_IO, LP_UART, LPWR},
2210 uart::{Config, DataBits, Parity, StopBits},
2211 };
2212 pub struct LpUart {
2216 uart: LP_UART<'static>,
2217 }
2218
2219 impl LpUart {
2220 pub fn new(
2229 uart: LP_UART<'static>,
2230 config: Config,
2231 _tx: LowPowerOutput<'_, 5>,
2232 _rx: LowPowerInput<'_, 4>,
2233 ) -> Self {
2234 LP_AON::regs()
2236 .gpio_mux()
2237 .modify(|r, w| unsafe { w.sel().bits(r.sel().bits() | (1 << 4) | (1 << 5)) });
2238
2239 LP_IO::regs()
2240 .gpio(4)
2241 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2242 LP_IO::regs()
2243 .gpio(5)
2244 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2245
2246 let mut me = Self { uart };
2247 let uart = me.uart.register_block();
2248
2249 uart.conf0().modify(|_, w| unsafe {
2255 w.parity().clear_bit();
2256 w.parity_en().clear_bit();
2257 w.bit_num().bits(0x3);
2258 w.stop_bit_num().bits(0x1)
2259 });
2260 uart.idle_conf()
2262 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2263 uart.hwfc_conf().modify(|_, w| w.rx_flow_en().clear_bit());
2265
2266 LPWR::regs()
2271 .lpperi()
2272 .modify(|_, w| w.lp_uart_clk_sel().clear_bit());
2273
2274 me.change_baud_internal(&config);
2277 me.change_parity(config.parity);
2279 me.change_data_bits(config.data_bits);
2281 me.change_stop_bits(config.stop_bits);
2283 me.change_tx_idle(0); me.rxfifo_reset();
2288 me.txfifo_reset();
2289
2290 me
2291 }
2292
2293 fn rxfifo_reset(&mut self) {
2294 self.uart
2295 .register_block()
2296 .conf0()
2297 .modify(|_, w| w.rxfifo_rst().set_bit());
2298 self.update();
2299
2300 self.uart
2301 .register_block()
2302 .conf0()
2303 .modify(|_, w| w.rxfifo_rst().clear_bit());
2304 self.update();
2305 }
2306
2307 fn txfifo_reset(&mut self) {
2308 self.uart
2309 .register_block()
2310 .conf0()
2311 .modify(|_, w| w.txfifo_rst().set_bit());
2312 self.update();
2313
2314 self.uart
2315 .register_block()
2316 .conf0()
2317 .modify(|_, w| w.txfifo_rst().clear_bit());
2318 self.update();
2319 }
2320
2321 fn update(&mut self) {
2322 let register_block = self.uart.register_block();
2323 register_block
2324 .reg_update()
2325 .modify(|_, w| w.reg_update().set_bit());
2326 while register_block.reg_update().read().reg_update().bit_is_set() {
2327 }
2329 }
2330
2331 fn change_baud_internal(&mut self, config: &Config) {
2332 let clk = 16_000_000_u32;
2334 let max_div = 0b1111_1111_1111 - 1;
2335 let clk_div = clk.div_ceil(max_div * config.baudrate);
2336
2337 self.uart.register_block().clk_conf().modify(|_, w| unsafe {
2338 w.sclk_div_a().bits(0);
2339 w.sclk_div_b().bits(0);
2340 w.sclk_div_num().bits(clk_div as u8 - 1);
2341 w.sclk_sel().bits(match config.clock_source {
2342 super::ClockSource::Xtal => 3,
2343 super::ClockSource::RcFast => 2,
2344 super::ClockSource::Apb => panic!("Wrong clock source for LP_UART"),
2345 });
2346 w.sclk_en().set_bit()
2347 });
2348
2349 let clk = clk / clk_div;
2350 let divider = clk / config.baudrate;
2351 let divider = divider as u16;
2352
2353 self.uart
2354 .register_block()
2355 .clkdiv()
2356 .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) });
2357
2358 self.update();
2359 }
2360
2361 pub fn change_baud(&mut self, config: &Config) {
2369 self.change_baud_internal(config);
2370 self.txfifo_reset();
2371 self.rxfifo_reset();
2372 }
2373
2374 fn change_parity(&mut self, parity: Parity) -> &mut Self {
2375 if parity != Parity::None {
2376 self.uart
2377 .register_block()
2378 .conf0()
2379 .modify(|_, w| w.parity().bit((parity as u8 & 0x1) != 0));
2380 }
2381
2382 self.uart
2383 .register_block()
2384 .conf0()
2385 .modify(|_, w| match parity {
2386 Parity::None => w.parity_en().clear_bit(),
2387 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2388 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2389 });
2390
2391 self
2392 }
2393
2394 fn change_data_bits(&mut self, data_bits: DataBits) -> &mut Self {
2395 self.uart
2396 .register_block()
2397 .conf0()
2398 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2399
2400 self.update();
2401 self
2402 }
2403
2404 fn change_stop_bits(&mut self, stop_bits: StopBits) -> &mut Self {
2405 self.uart
2406 .register_block()
2407 .conf0()
2408 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2409
2410 self.update();
2411 self
2412 }
2413
2414 fn change_tx_idle(&mut self, idle_num: u16) -> &mut Self {
2415 self.uart
2416 .register_block()
2417 .idle_conf()
2418 .modify(|_, w| unsafe { w.tx_idle_num().bits(idle_num) });
2419
2420 self.update();
2421 self
2422 }
2423 }
2424}
2425
2426pub trait Instance: crate::private::Sealed + IntoAnyUart {
2428 #[doc(hidden)]
2429 fn parts(&self) -> (&'static Info, &'static State);
2431
2432 #[inline(always)]
2434 #[doc(hidden)]
2435 fn info(&self) -> &'static Info {
2436 self.parts().0
2437 }
2438
2439 #[inline(always)]
2441 #[doc(hidden)]
2442 fn state(&self) -> &'static State {
2443 self.parts().1
2444 }
2445}
2446
2447#[doc(hidden)]
2449#[non_exhaustive]
2450pub struct Info {
2451 pub register_block: *const RegisterBlock,
2455
2456 pub peripheral: crate::system::Peripheral,
2458
2459 pub async_handler: InterruptHandler,
2461
2462 pub interrupt: Interrupt,
2464
2465 pub tx_signal: OutputSignal,
2467
2468 pub rx_signal: InputSignal,
2470
2471 pub cts_signal: InputSignal,
2473
2474 pub rts_signal: OutputSignal,
2476}
2477
2478#[doc(hidden)]
2480#[non_exhaustive]
2481pub struct State {
2482 pub rx_waker: AtomicWaker,
2484
2485 pub tx_waker: AtomicWaker,
2487
2488 pub is_rx_async: AtomicBool,
2490
2491 pub is_tx_async: AtomicBool,
2493}
2494
2495impl Info {
2496 const UART_FIFO_SIZE: u16 = 128;
2499 const RX_FIFO_MAX_THRHD: u16 = 127;
2500 const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
2501
2502 pub fn regs(&self) -> &RegisterBlock {
2504 unsafe { &*self.register_block }
2505 }
2506
2507 fn enable_listen(&self, interrupts: EnumSet<UartInterrupt>, enable: bool) {
2509 let reg_block = self.regs();
2510
2511 reg_block.int_ena().modify(|_, w| {
2512 for interrupt in interrupts {
2513 match interrupt {
2514 UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable),
2515 UartInterrupt::TxDone => w.tx_done().bit(enable),
2516 UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable),
2517 UartInterrupt::RxTimeout => w.rxfifo_tout().bit(enable),
2518 };
2519 }
2520 w
2521 });
2522 }
2523
2524 fn interrupts(&self) -> EnumSet<UartInterrupt> {
2525 let mut res = EnumSet::new();
2526 let reg_block = self.regs();
2527
2528 let ints = reg_block.int_raw().read();
2529
2530 if ints.at_cmd_char_det().bit_is_set() {
2531 res.insert(UartInterrupt::AtCmd);
2532 }
2533 if ints.tx_done().bit_is_set() {
2534 res.insert(UartInterrupt::TxDone);
2535 }
2536 if ints.rxfifo_full().bit_is_set() {
2537 res.insert(UartInterrupt::RxFifoFull);
2538 }
2539 if ints.rxfifo_tout().bit_is_set() {
2540 res.insert(UartInterrupt::RxTimeout);
2541 }
2542
2543 res
2544 }
2545
2546 fn clear_interrupts(&self, interrupts: EnumSet<UartInterrupt>) {
2547 let reg_block = self.regs();
2548
2549 reg_block.int_clr().write(|w| {
2550 for interrupt in interrupts {
2551 match interrupt {
2552 UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(),
2553 UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
2554 UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(),
2555 UartInterrupt::RxTimeout => w.rxfifo_tout().clear_bit_by_one(),
2556 };
2557 }
2558 w
2559 });
2560 }
2561
2562 fn set_interrupt_handler(&self, handler: InterruptHandler) {
2563 for core in crate::system::Cpu::other() {
2564 crate::interrupt::disable(core, self.interrupt);
2565 }
2566 self.enable_listen(EnumSet::all(), false);
2567 self.clear_interrupts(EnumSet::all());
2568 unsafe { crate::interrupt::bind_interrupt(self.interrupt, handler.handler()) };
2569 unwrap!(crate::interrupt::enable(self.interrupt, handler.priority()));
2570 }
2571
2572 fn disable_interrupts(&self) {
2573 crate::interrupt::disable(crate::system::Cpu::current(), self.interrupt);
2574 }
2575
2576 fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
2577 config.validate()?;
2578 self.change_baud(config)?;
2579 self.change_data_bits(config.data_bits);
2580 self.change_parity(config.parity);
2581 self.change_stop_bits(config.stop_bits);
2582 self.change_flow_control(config.sw_flow_ctrl, config.hw_flow_ctrl);
2583
2584 Ok(())
2585 }
2586
2587 fn enable_listen_tx(&self, events: EnumSet<TxEvent>, enable: bool) {
2588 self.regs().int_ena().modify(|_, w| {
2589 for event in events {
2590 match event {
2591 TxEvent::Done => w.tx_done().bit(enable),
2592 TxEvent::FiFoEmpty => w.txfifo_empty().bit(enable),
2593 };
2594 }
2595 w
2596 });
2597 }
2598
2599 fn tx_events(&self) -> EnumSet<TxEvent> {
2600 let pending_interrupts = self.regs().int_raw().read();
2601 let mut active_events = EnumSet::new();
2602
2603 if pending_interrupts.tx_done().bit_is_set() {
2604 active_events |= TxEvent::Done;
2605 }
2606 if pending_interrupts.txfifo_empty().bit_is_set() {
2607 active_events |= TxEvent::FiFoEmpty;
2608 }
2609
2610 active_events
2611 }
2612
2613 fn clear_tx_events(&self, events: impl Into<EnumSet<TxEvent>>) {
2614 let events = events.into();
2615 self.regs().int_clr().write(|w| {
2616 for event in events {
2617 match event {
2618 TxEvent::FiFoEmpty => w.txfifo_empty().clear_bit_by_one(),
2619 TxEvent::Done => w.tx_done().clear_bit_by_one(),
2620 };
2621 }
2622 w
2623 });
2624 }
2625
2626 fn enable_listen_rx(&self, events: EnumSet<RxEvent>, enable: bool) {
2627 self.regs().int_ena().modify(|_, w| {
2628 for event in events {
2629 match event {
2630 RxEvent::FifoFull => w.rxfifo_full().bit(enable),
2631 RxEvent::CmdCharDetected => w.at_cmd_char_det().bit(enable),
2632
2633 RxEvent::FifoOvf => w.rxfifo_ovf().bit(enable),
2634 RxEvent::FifoTout => w.rxfifo_tout().bit(enable),
2635 RxEvent::GlitchDetected => w.glitch_det().bit(enable),
2636 RxEvent::FrameError => w.frm_err().bit(enable),
2637 RxEvent::ParityError => w.parity_err().bit(enable),
2638 };
2639 }
2640 w
2641 });
2642 }
2643
2644 fn rx_events(&self) -> EnumSet<RxEvent> {
2645 let pending_interrupts = self.regs().int_raw().read();
2646 let mut active_events = EnumSet::new();
2647
2648 if pending_interrupts.rxfifo_full().bit_is_set() {
2649 active_events |= RxEvent::FifoFull;
2650 }
2651 if pending_interrupts.at_cmd_char_det().bit_is_set() {
2652 active_events |= RxEvent::CmdCharDetected;
2653 }
2654 if pending_interrupts.rxfifo_ovf().bit_is_set() {
2655 active_events |= RxEvent::FifoOvf;
2656 }
2657 if pending_interrupts.rxfifo_tout().bit_is_set() {
2658 active_events |= RxEvent::FifoTout;
2659 }
2660 if pending_interrupts.glitch_det().bit_is_set() {
2661 active_events |= RxEvent::GlitchDetected;
2662 }
2663 if pending_interrupts.frm_err().bit_is_set() {
2664 active_events |= RxEvent::FrameError;
2665 }
2666 if pending_interrupts.parity_err().bit_is_set() {
2667 active_events |= RxEvent::ParityError;
2668 }
2669
2670 active_events
2671 }
2672
2673 fn clear_rx_events(&self, events: impl Into<EnumSet<RxEvent>>) {
2674 let events = events.into();
2675 self.regs().int_clr().write(|w| {
2676 for event in events {
2677 match event {
2678 RxEvent::FifoFull => w.rxfifo_full().clear_bit_by_one(),
2679 RxEvent::CmdCharDetected => w.at_cmd_char_det().clear_bit_by_one(),
2680
2681 RxEvent::FifoOvf => w.rxfifo_ovf().clear_bit_by_one(),
2682 RxEvent::FifoTout => w.rxfifo_tout().clear_bit_by_one(),
2683 RxEvent::GlitchDetected => w.glitch_det().clear_bit_by_one(),
2684 RxEvent::FrameError => w.frm_err().clear_bit_by_one(),
2685 RxEvent::ParityError => w.parity_err().clear_bit_by_one(),
2686 };
2687 }
2688 w
2689 });
2690 }
2691
2692 fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
2699 if threshold > Self::RX_FIFO_MAX_THRHD {
2700 return Err(ConfigError::UnsupportedRxFifoThreshold);
2701 }
2702
2703 self.regs()
2704 .conf1()
2705 .modify(|_, w| unsafe { w.rxfifo_full_thrhd().bits(threshold as _) });
2706
2707 Ok(())
2708 }
2709
2710 #[allow(clippy::useless_conversion)]
2712 fn rx_fifo_full_threshold(&self) -> u16 {
2713 self.regs().conf1().read().rxfifo_full_thrhd().bits().into()
2714 }
2715
2716 fn set_tx_fifo_empty_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
2723 if threshold > Self::TX_FIFO_MAX_THRHD {
2724 return Err(ConfigError::UnsupportedTxFifoThreshold);
2725 }
2726
2727 self.regs()
2728 .conf1()
2729 .modify(|_, w| unsafe { w.txfifo_empty_thrhd().bits(threshold as _) });
2730
2731 Ok(())
2732 }
2733
2734 fn set_rx_timeout(&self, timeout: Option<u8>, _symbol_len: u8) -> Result<(), ConfigError> {
2749 cfg_if::cfg_if! {
2750 if #[cfg(esp32)] {
2751 const MAX_THRHD: u8 = 0x7F; } else {
2753 const MAX_THRHD: u16 = 0x3FF; }
2755 }
2756
2757 let register_block = self.regs();
2758
2759 if let Some(timeout) = timeout {
2760 #[cfg(esp32)]
2762 let timeout_reg = timeout;
2763 #[cfg(not(esp32))]
2765 let timeout_reg = timeout as u16 * _symbol_len as u16;
2766
2767 if timeout_reg > MAX_THRHD {
2768 return Err(ConfigError::UnsupportedTimeout);
2769 }
2770
2771 cfg_if::cfg_if! {
2772 if #[cfg(esp32)] {
2773 let reg_thrhd = register_block.conf1();
2774 } else if #[cfg(any(esp32c6, esp32h2))] {
2775 let reg_thrhd = register_block.tout_conf();
2776 } else {
2777 let reg_thrhd = register_block.mem_conf();
2778 }
2779 }
2780 reg_thrhd.modify(|_, w| unsafe { w.rx_tout_thrhd().bits(timeout_reg) });
2781 }
2782
2783 cfg_if::cfg_if! {
2784 if #[cfg(any(esp32c6, esp32h2))] {
2785 let reg_en = register_block.tout_conf();
2786 } else {
2787 let reg_en = register_block.conf1();
2788 }
2789 }
2790 reg_en.modify(|_, w| w.rx_tout_en().bit(timeout.is_some()));
2791
2792 self.sync_regs();
2793
2794 Ok(())
2795 }
2796
2797 fn is_instance(&self, other: impl Instance) -> bool {
2798 self == other.info()
2799 }
2800
2801 fn sync_regs(&self) {
2802 sync_regs(self.regs());
2803 }
2804
2805 fn change_baud(&self, config: &Config) -> Result<(), ConfigError> {
2806 let clocks = Clocks::get();
2807 let clk = match config.clock_source {
2808 ClockSource::Apb => clocks.apb_clock.as_hz(),
2809 #[cfg(not(any(esp32, esp32s2)))]
2810 ClockSource::Xtal => clocks.xtal_clock.as_hz(),
2811 #[cfg(not(any(esp32, esp32s2)))]
2812 ClockSource::RcFast => crate::soc::constants::RC_FAST_CLK.as_hz(),
2813 #[cfg(any(esp32, esp32s2))]
2814 ClockSource::RefTick => crate::soc::constants::REF_TICK.as_hz(),
2815 };
2816
2817 cfg_if::cfg_if! {
2818 if #[cfg(any(esp32c2, esp32c3, esp32s3, esp32c6, esp32h2))] {
2819
2820 const MAX_DIV: u32 = 0b1111_1111_1111 - 1;
2821 let clk_div = (clk.div_ceil(MAX_DIV)).div_ceil(config.baudrate);
2822
2823 cfg_if::cfg_if! {
2825 if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
2826 if matches!(config.clock_source, ClockSource::RcFast) {
2827 crate::peripherals::LPWR::regs()
2828 .clk_conf()
2829 .modify(|_, w| w.dig_clk8m_en().variant(true));
2830 crate::rom::ets_delay_us(5);
2832 }
2833
2834 let conf = self.regs().clk_conf();
2835 } else {
2836 let pcr = crate::peripherals::PCR::regs();
2838 let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
2839 pcr.uart(0).clk_conf()
2840 } else {
2841 pcr.uart(1).clk_conf()
2842 };
2843 }
2844 };
2845
2846 conf.write(|w| unsafe {
2847 w.sclk_sel().bits(match config.clock_source {
2848 ClockSource::Apb => 1,
2849 ClockSource::RcFast => 2,
2850 ClockSource::Xtal => 3,
2851 });
2852 w.sclk_div_a().bits(0);
2853 w.sclk_div_b().bits(0);
2854 w.sclk_div_num().bits(clk_div as u8 - 1)
2855 });
2856
2857 let divider = (clk << 4) / (config.baudrate * clk_div);
2858 } else {
2859 self.regs().conf0().modify(|_, w| {
2860 w.tick_ref_always_on()
2861 .bit(config.clock_source == ClockSource::Apb)
2862 });
2863
2864 let divider = (clk << 4) / config.baudrate;
2865 }
2866 }
2867
2868 let divider_integer = divider >> 4;
2869 let divider_frag = (divider & 0xf) as u8;
2870
2871 self.regs().clkdiv().write(|w| unsafe {
2872 w.clkdiv()
2873 .bits(divider_integer as _)
2874 .frag()
2875 .bits(divider_frag)
2876 });
2877
2878 self.sync_regs();
2879
2880 #[cfg(feature = "unstable")]
2881 self.verify_baudrate(clk, config)?;
2882
2883 Ok(())
2884 }
2885
2886 fn change_data_bits(&self, data_bits: DataBits) {
2887 self.regs()
2888 .conf0()
2889 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2890 }
2891
2892 fn change_parity(&self, parity: Parity) {
2893 self.regs().conf0().modify(|_, w| match parity {
2894 Parity::None => w.parity_en().clear_bit(),
2895 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2896 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2897 });
2898 }
2899
2900 fn change_stop_bits(&self, stop_bits: StopBits) {
2901 #[cfg(esp32)]
2902 {
2903 if stop_bits == StopBits::_2 {
2905 self.regs()
2906 .rs485_conf()
2907 .modify(|_, w| w.dl1_en().bit(stop_bits == StopBits::_2));
2908
2909 self.regs()
2910 .conf0()
2911 .modify(|_, w| unsafe { w.stop_bit_num().bits(1) });
2912 }
2913 }
2914
2915 #[cfg(not(esp32))]
2916 self.regs()
2917 .conf0()
2918 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2919 }
2920
2921 fn change_flow_control(&self, sw_flow_ctrl: SwFlowControl, hw_flow_ctrl: HwFlowControl) {
2922 match sw_flow_ctrl {
2924 SwFlowControl::Enabled {
2925 xon_char,
2926 xoff_char,
2927 xon_threshold,
2928 xoff_threshold,
2929 } => {
2930 cfg_if::cfg_if! {
2931 if #[cfg(any(esp32c6, esp32h2))] {
2932 self.regs().swfc_conf0().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
2933 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold)});
2934 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
2935 } else if #[cfg(esp32)]{
2936 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
2937 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold) });
2938 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
2939 } else {
2940 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
2941 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold as u16) });
2942 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_threshold().bits(xoff_threshold as u16) });
2943 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_char().bits(xon_char) });
2944 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_char().bits(xoff_char) });
2945 }
2946 }
2947 }
2948 SwFlowControl::Disabled => {
2949 cfg_if::cfg_if! {
2950 if #[cfg(any(esp32c6, esp32h2))] {
2951 let reg = self.regs().swfc_conf0();
2952 } else {
2953 let reg = self.regs().flow_conf();
2954 }
2955 }
2956
2957 reg.modify(|_, w| w.sw_flow_con_en().clear_bit());
2958 reg.modify(|_, w| w.xonoff_del().clear_bit());
2959 }
2960 }
2961
2962 self.regs().conf0().modify(|_, w| {
2963 w.tx_flow_en()
2964 .bit(matches!(hw_flow_ctrl.cts, CtsConfig::Enabled))
2965 });
2966
2967 match hw_flow_ctrl.rts {
2968 RtsConfig::Enabled(threshold) => self.configure_rts_flow_ctrl(true, Some(threshold)),
2969 RtsConfig::Disabled => self.configure_rts_flow_ctrl(false, None),
2970 }
2971
2972 #[cfg(any(esp32c6, esp32h2))]
2973 sync_regs(self.regs());
2974 }
2975
2976 fn configure_rts_flow_ctrl(&self, enable: bool, threshold: Option<u8>) {
2977 if let Some(threshold) = threshold {
2978 cfg_if::cfg_if! {
2979 if #[cfg(esp32)] {
2980 self.regs().conf1().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
2981 } else if #[cfg(any(esp32c6, esp32h2))] {
2982 self.regs().hwfc_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
2983 } else {
2984 self.regs().mem_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold as u16) });
2985 }
2986 }
2987 }
2988
2989 cfg_if::cfg_if! {
2990 if #[cfg(any(esp32c6, esp32h2))] {
2991 self.regs().hwfc_conf().modify(|_, w| {
2992 w.rx_flow_en().bit(enable)
2993 });
2994 } else {
2995 self.regs().conf1().modify(|_, w| {
2996 w.rx_flow_en().bit(enable)
2997 });
2998 }
2999 }
3000 }
3001
3002 fn rxfifo_reset(&self) {
3003 fn rxfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3004 reg_block.conf0().modify(|_, w| w.rxfifo_rst().bit(enable));
3005 sync_regs(reg_block);
3006 }
3007
3008 rxfifo_rst(self.regs(), true);
3009 rxfifo_rst(self.regs(), false);
3010 }
3011
3012 fn txfifo_reset(&self) {
3013 fn txfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3014 reg_block.conf0().modify(|_, w| w.txfifo_rst().bit(enable));
3015 sync_regs(reg_block);
3016 }
3017
3018 txfifo_rst(self.regs(), true);
3019 txfifo_rst(self.regs(), false);
3020 }
3021
3022 #[cfg(feature = "unstable")]
3023 fn verify_baudrate(&self, clk: u32, config: &Config) -> Result<(), ConfigError> {
3024 let clkdiv_reg = self.regs().clkdiv().read();
3027 let clkdiv_frag = clkdiv_reg.frag().bits() as u32;
3028 let clkdiv = clkdiv_reg.clkdiv().bits();
3029
3030 cfg_if::cfg_if! {
3031 if #[cfg(any(esp32, esp32s2))] {
3032 let actual_baud = (clk << 4) / ((clkdiv << 4) | clkdiv_frag);
3033 } else if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
3034 let sclk_div_num = self.regs().clk_conf().read().sclk_div_num().bits() as u32;
3035 let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
3036 } else { let pcr = crate::peripherals::PCR::regs();
3038 let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
3039 pcr.uart(0).clk_conf()
3040 } else {
3041 pcr.uart(1).clk_conf()
3042 };
3043 let sclk_div_num = conf.read().sclk_div_num().bits() as u32;
3044 let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
3045 }
3046 };
3047
3048 match config.baudrate_tolerance {
3049 BaudrateTolerance::Exact => {
3050 let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
3051 * 100)
3052 / actual_baud;
3053 if deviation > 1_u32 {
3056 return Err(ConfigError::UnachievableBaudrate);
3057 }
3058 }
3059 BaudrateTolerance::ErrorPercent(percent) => {
3060 let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
3061 * 100)
3062 / actual_baud;
3063 if deviation > percent as u32 {
3064 return Err(ConfigError::UnachievableBaudrate);
3065 }
3066 }
3067 _ => {}
3068 }
3069
3070 Ok(())
3071 }
3072
3073 fn current_symbol_length(&self) -> u8 {
3074 let conf0 = self.regs().conf0().read();
3075 let data_bits = conf0.bit_num().bits() + 5; let parity = conf0.parity_en().bit() as u8;
3077 let mut stop_bits = conf0.stop_bit_num().bits();
3078
3079 match stop_bits {
3080 1 => {
3081 #[cfg(esp32)]
3083 if self.regs().rs485_conf().read().dl1_en().bit_is_set() {
3084 stop_bits = 2;
3085 }
3086 }
3087 _ => stop_bits = 2,
3089 }
3090
3091 1 + data_bits + parity + stop_bits
3092 }
3093
3094 fn read_next_from_fifo(&self) -> u8 {
3098 fn access_fifo_register<R>(f: impl Fn() -> R) -> R {
3099 cfg_if::cfg_if! {
3101 if #[cfg(esp32)] {
3102 crate::interrupt::free(f)
3103 } else {
3104 f()
3105 }
3106 }
3107 }
3108
3109 let fifo_reg = self.regs().fifo();
3110 cfg_if::cfg_if! {
3111 if #[cfg(esp32s2)] {
3112 let fifo_reg = unsafe {
3114 &*fifo_reg.as_ptr().cast::<u8>().add(0x20C00000).cast::<crate::pac::uart0::FIFO>()
3115 };
3116 }
3117 }
3118
3119 access_fifo_register(|| fifo_reg.read().rxfifo_rd_byte().bits())
3120 }
3121
3122 #[allow(clippy::useless_conversion)]
3123 fn tx_fifo_count(&self) -> u16 {
3124 u16::from(self.regs().status().read().txfifo_cnt().bits())
3125 }
3126
3127 fn write_byte(&self, byte: u8) {
3128 self.regs()
3129 .fifo()
3130 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
3131 }
3132
3133 fn check_for_errors(&self) -> Result<(), RxError> {
3134 let errors = RxEvent::FifoOvf
3135 | RxEvent::FifoTout
3136 | RxEvent::GlitchDetected
3137 | RxEvent::FrameError
3138 | RxEvent::ParityError;
3139 let events = self.rx_events().intersection(errors);
3140 let result = rx_event_check_for_error(events);
3141 if result.is_err() {
3142 self.clear_rx_events(errors);
3143 if events.contains(RxEvent::FifoOvf) {
3144 self.rxfifo_reset();
3145 }
3146 }
3147 result
3148 }
3149
3150 #[cfg(not(esp32))]
3151 #[allow(clippy::unnecessary_cast)]
3152 fn rx_fifo_count(&self) -> u16 {
3153 self.regs().status().read().rxfifo_cnt().bits() as u16
3154 }
3155
3156 #[cfg(esp32)]
3157 fn rx_fifo_count(&self) -> u16 {
3158 let fifo_cnt = self.regs().status().read().rxfifo_cnt().bits();
3159
3160 let status = self.regs().mem_rx_status().read();
3163 let rd_addr: u16 = status.mem_rx_rd_addr().bits();
3164 let wr_addr: u16 = status.mem_rx_wr_addr().bits();
3165
3166 if wr_addr > rd_addr {
3167 wr_addr - rd_addr
3168 } else if wr_addr < rd_addr {
3169 (wr_addr + Info::UART_FIFO_SIZE) - rd_addr
3170 } else if fifo_cnt > 0 {
3171 Info::UART_FIFO_SIZE
3172 } else {
3173 0
3174 }
3175 }
3176
3177 fn write(&self, data: &[u8]) -> Result<usize, TxError> {
3178 if data.is_empty() {
3179 return Ok(0);
3180 }
3181
3182 while self.tx_fifo_count() >= Info::UART_FIFO_SIZE {}
3183
3184 let space = (Info::UART_FIFO_SIZE - self.tx_fifo_count()) as usize;
3185 let to_write = space.min(data.len());
3186 for &byte in &data[..to_write] {
3187 self.write_byte(byte);
3188 }
3189
3190 Ok(to_write)
3191 }
3192
3193 fn read(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3194 if buf.is_empty() {
3195 return Ok(0);
3196 }
3197
3198 while self.rx_fifo_count() == 0 {
3199 self.check_for_errors()?;
3201 }
3202
3203 self.read_buffered(buf)
3204 }
3205
3206 fn read_buffered(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3207 let to_read = (self.rx_fifo_count() as usize).min(buf.len());
3210 self.check_for_errors()?;
3211
3212 for byte_into in buf[..to_read].iter_mut() {
3213 *byte_into = self.read_next_from_fifo();
3214 }
3215
3216 Ok(to_read)
3217 }
3218}
3219
3220impl PartialEq for Info {
3221 fn eq(&self, other: &Self) -> bool {
3222 core::ptr::eq(self.register_block, other.register_block)
3223 }
3224}
3225
3226unsafe impl Sync for Info {}
3227
3228macro_rules! impl_instance {
3229 ($inst:ident, $peri:ident, $txd:ident, $rxd:ident, $cts:ident, $rts:ident) => {
3230 impl Instance for crate::peripherals::$inst<'_> {
3231 fn parts(&self) -> (&'static Info, &'static State) {
3232 #[crate::handler]
3233 pub(super) fn irq_handler() {
3234 intr_handler(&PERIPHERAL, &STATE);
3235 }
3236
3237 static STATE: State = State {
3238 tx_waker: AtomicWaker::new(),
3239 rx_waker: AtomicWaker::new(),
3240 is_rx_async: AtomicBool::new(false),
3241 is_tx_async: AtomicBool::new(false),
3242 };
3243
3244 static PERIPHERAL: Info = Info {
3245 register_block: crate::peripherals::$inst::ptr(),
3246 peripheral: crate::system::Peripheral::$peri,
3247 async_handler: irq_handler,
3248 interrupt: Interrupt::$inst,
3249 tx_signal: OutputSignal::$txd,
3250 rx_signal: InputSignal::$rxd,
3251 cts_signal: InputSignal::$cts,
3252 rts_signal: OutputSignal::$rts,
3253 };
3254 (&PERIPHERAL, &STATE)
3255 }
3256 }
3257 };
3258}
3259
3260impl_instance!(UART0, Uart0, U0TXD, U0RXD, U0CTS, U0RTS);
3261impl_instance!(UART1, Uart1, U1TXD, U1RXD, U1CTS, U1RTS);
3262#[cfg(uart2)]
3263impl_instance!(UART2, Uart2, U2TXD, U2RXD, U2CTS, U2RTS);
3264
3265crate::any_peripheral! {
3266 pub peripheral AnyUart<'d> {
3268 #[cfg(uart0)]
3269 Uart0(crate::peripherals::UART0<'d>),
3270 #[cfg(uart1)]
3271 Uart1(crate::peripherals::UART1<'d>),
3272 #[cfg(uart2)]
3273 Uart2(crate::peripherals::UART2<'d>),
3274 }
3275}
3276
3277impl Instance for AnyUart<'_> {
3278 #[inline]
3279 fn parts(&self) -> (&'static Info, &'static State) {
3280 match &self.0 {
3281 #[cfg(uart0)]
3282 AnyUartInner::Uart0(uart) => uart.parts(),
3283 #[cfg(uart1)]
3284 AnyUartInner::Uart1(uart) => uart.parts(),
3285 #[cfg(uart2)]
3286 AnyUartInner::Uart2(uart) => uart.parts(),
3287 }
3288 }
3289}