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 private::OnDrop,
69 system::{PeripheralClockControl, PeripheralGuard},
70};
71
72#[derive(Debug, Clone, Copy, PartialEq)]
74#[cfg_attr(feature = "defmt", derive(defmt::Format))]
75#[non_exhaustive]
76pub enum RxError {
77 FifoOverflowed,
82
83 GlitchOccurred,
89
90 FrameFormatViolated,
95
96 ParityMismatch,
101}
102
103impl core::error::Error for RxError {}
104
105impl core::fmt::Display for RxError {
106 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
107 match self {
108 RxError::FifoOverflowed => write!(f, "The RX FIFO overflowed"),
109 RxError::GlitchOccurred => write!(f, "A glitch was detected on the RX line"),
110 RxError::FrameFormatViolated => {
111 write!(f, "A framing error was detected on the RX line")
112 }
113 RxError::ParityMismatch => write!(f, "A parity error was detected on the RX line"),
114 }
115 }
116}
117
118#[instability::unstable]
119impl embedded_io::Error for RxError {
120 fn kind(&self) -> embedded_io::ErrorKind {
121 embedded_io::ErrorKind::Other
122 }
123}
124
125#[derive(Debug, Clone, Copy, PartialEq)]
127#[cfg_attr(feature = "defmt", derive(defmt::Format))]
128#[non_exhaustive]
129pub enum TxError {}
130
131impl core::fmt::Display for TxError {
132 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
133 write!(f, "Tx error")
134 }
135}
136
137#[instability::unstable]
138impl embedded_io::Error for TxError {
139 fn kind(&self) -> embedded_io::ErrorKind {
140 embedded_io::ErrorKind::Other
141 }
142}
143
144#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
146#[cfg_attr(feature = "defmt", derive(defmt::Format))]
147#[non_exhaustive]
148#[instability::unstable]
149pub enum ClockSource {
150 #[cfg_attr(not(any(esp32c6, esp32h2, soc_has_lp_uart)), default)]
152 Apb,
153 #[cfg(not(any(esp32, esp32s2)))]
155 RcFast,
156 #[cfg(not(any(esp32, esp32s2)))]
158 #[cfg_attr(any(esp32c6, esp32h2, soc_has_lp_uart), default)]
159 Xtal,
160 #[cfg(any(esp32, esp32s2))]
162 RefTick,
163}
164
165#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
171#[cfg_attr(feature = "defmt", derive(defmt::Format))]
172pub enum DataBits {
173 _5,
175 _6,
177 _7,
179 #[default]
181 _8,
182}
183
184#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
191#[cfg_attr(feature = "defmt", derive(defmt::Format))]
192pub enum Parity {
193 #[default]
195 None,
196 Even,
199 Odd,
202}
203
204#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
210#[cfg_attr(feature = "defmt", derive(defmt::Format))]
211pub enum StopBits {
212 #[default]
214 _1,
215 _1p5,
217 _2,
219}
220
221#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
223#[cfg_attr(feature = "defmt", derive(defmt::Format))]
224#[instability::unstable]
225pub enum SwFlowControl {
226 #[default]
227 Disabled,
229 Enabled {
231 xon_char: u8,
233 xoff_char: u8,
235 xon_threshold: u8,
238 xoff_threshold: u8,
241 },
242}
243
244#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
246#[cfg_attr(feature = "defmt", derive(defmt::Format))]
247#[instability::unstable]
248pub enum CtsConfig {
249 Enabled,
251 #[default]
252 Disabled,
254}
255
256#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
258#[cfg_attr(feature = "defmt", derive(defmt::Format))]
259#[instability::unstable]
260pub enum RtsConfig {
261 Enabled(u8),
263 #[default]
264 Disabled,
266}
267
268#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
270#[cfg_attr(feature = "defmt", derive(defmt::Format))]
271#[instability::unstable]
272pub struct HwFlowControl {
273 pub cts: CtsConfig,
275 pub rts: RtsConfig,
277}
278
279#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
281#[cfg_attr(feature = "defmt", derive(defmt::Format))]
282#[instability::unstable]
283pub enum BaudrateTolerance {
284 #[default]
286 Closest,
287 Exact,
290 ErrorPercent(u8),
292}
293
294#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
296#[cfg_attr(feature = "defmt", derive(defmt::Format))]
297#[non_exhaustive]
298pub struct Config {
299 baudrate: u32,
302 #[builder_lite(unstable)]
305 baudrate_tolerance: BaudrateTolerance,
306 data_bits: DataBits,
308 parity: Parity,
310 stop_bits: StopBits,
312 #[builder_lite(unstable)]
314 sw_flow_ctrl: SwFlowControl,
315 #[builder_lite(unstable)]
317 hw_flow_ctrl: HwFlowControl,
318 #[builder_lite(unstable)]
320 clock_source: ClockSource,
321 rx: RxConfig,
323 tx: TxConfig,
325}
326
327impl Default for Config {
328 fn default() -> Config {
329 Config {
330 rx: RxConfig::default(),
331 tx: TxConfig::default(),
332 baudrate: 115_200,
333 baudrate_tolerance: BaudrateTolerance::default(),
334 data_bits: Default::default(),
335 parity: Default::default(),
336 stop_bits: Default::default(),
337 sw_flow_ctrl: Default::default(),
338 hw_flow_ctrl: Default::default(),
339 clock_source: Default::default(),
340 }
341 }
342}
343
344impl Config {
345 fn validate(&self) -> Result<(), ConfigError> {
346 if let BaudrateTolerance::ErrorPercent(percentage) = self.baudrate_tolerance {
347 assert!(percentage > 0 && percentage <= 100);
348 }
349
350 if self.baudrate == 0 || self.baudrate > 5_000_000 {
352 return Err(ConfigError::BaudrateNotSupported);
353 }
354 Ok(())
355 }
356}
357
358#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
360#[cfg_attr(feature = "defmt", derive(defmt::Format))]
361#[non_exhaustive]
362pub struct RxConfig {
363 fifo_full_threshold: u16,
365 timeout: Option<u8>,
367}
368
369impl Default for RxConfig {
370 fn default() -> RxConfig {
371 RxConfig {
372 fifo_full_threshold: 120,
374 timeout: Some(10),
376 }
377 }
378}
379
380#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
382#[cfg_attr(feature = "defmt", derive(defmt::Format))]
383#[non_exhaustive]
384pub struct TxConfig {
385 fifo_empty_threshold: u16,
387}
388
389impl Default for TxConfig {
390 fn default() -> TxConfig {
391 TxConfig {
392 fifo_empty_threshold: 10,
394 }
395 }
396}
397
398#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
400#[cfg_attr(feature = "defmt", derive(defmt::Format))]
401#[instability::unstable]
402#[non_exhaustive]
403pub struct AtCmdConfig {
404 pre_idle_count: Option<u16>,
407 post_idle_count: Option<u16>,
410 gap_timeout: Option<u16>,
413 cmd_char: u8,
415 char_num: u8,
417}
418
419impl Default for AtCmdConfig {
420 fn default() -> Self {
421 Self {
422 pre_idle_count: None,
423 post_idle_count: None,
424 gap_timeout: None,
425 cmd_char: b'+',
426 char_num: 1,
427 }
428 }
429}
430
431struct UartBuilder<'d, Dm: DriverMode> {
432 uart: AnyUart<'d>,
433 phantom: PhantomData<Dm>,
434}
435
436impl<'d, Dm> UartBuilder<'d, Dm>
437where
438 Dm: DriverMode,
439{
440 fn new(uart: impl Instance + 'd) -> Self {
441 Self {
442 uart: uart.degrade(),
443 phantom: PhantomData,
444 }
445 }
446
447 fn init(self, config: Config) -> Result<Uart<'d, Dm>, ConfigError> {
448 let rx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
449 let tx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
450
451 let rts_pin = PinGuard::new_unconnected(self.uart.info().rts_signal);
452 let tx_pin = PinGuard::new_unconnected(self.uart.info().tx_signal);
453
454 let mut serial = Uart {
455 rx: UartRx {
456 uart: unsafe { self.uart.clone_unchecked() },
457 phantom: PhantomData,
458 guard: rx_guard,
459 },
460 tx: UartTx {
461 uart: self.uart,
462 phantom: PhantomData,
463 guard: tx_guard,
464 rts_pin,
465 tx_pin,
466 },
467 };
468 serial.init(config)?;
469
470 Ok(serial)
471 }
472}
473
474#[procmacros::doc_replace]
475pub struct Uart<'d, Dm: DriverMode> {
490 rx: UartRx<'d, Dm>,
491 tx: UartTx<'d, Dm>,
492}
493
494#[instability::unstable]
496pub struct UartTx<'d, Dm: DriverMode> {
497 uart: AnyUart<'d>,
498 phantom: PhantomData<Dm>,
499 guard: PeripheralGuard,
500 rts_pin: PinGuard,
501 tx_pin: PinGuard,
502}
503
504#[instability::unstable]
506pub struct UartRx<'d, Dm: DriverMode> {
507 uart: AnyUart<'d>,
508 phantom: PhantomData<Dm>,
509 guard: PeripheralGuard,
510}
511
512#[derive(Debug, Clone, Copy, PartialEq, Eq)]
514#[cfg_attr(feature = "defmt", derive(defmt::Format))]
515#[non_exhaustive]
516pub enum ConfigError {
517 #[cfg(feature = "unstable")]
519 #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
520 BaudrateNotAchievable,
521
522 BaudrateNotSupported,
529
530 #[cfg_attr(esp32, doc = "127")]
532 #[cfg_attr(not(esp32), doc = "1023")]
533 TimeoutTooLong,
535
536 RxFifoThresholdNotSupported,
538
539 TxFifoThresholdNotSupported,
541}
542
543impl core::error::Error for ConfigError {}
544
545impl core::fmt::Display for ConfigError {
546 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
547 match self {
548 #[cfg(feature = "unstable")]
549 ConfigError::BaudrateNotAchievable => {
550 write!(f, "The requested baud rate is not achievable")
551 }
552 ConfigError::BaudrateNotSupported => {
553 write!(f, "The requested baud rate is not supported")
554 }
555 ConfigError::TimeoutTooLong => write!(f, "The requested timeout is not supported"),
556 ConfigError::RxFifoThresholdNotSupported => {
557 write!(f, "The requested RX FIFO threshold is not supported")
558 }
559 ConfigError::TxFifoThresholdNotSupported => {
560 write!(f, "The requested TX FIFO threshold is not supported")
561 }
562 }
563 }
564}
565
566#[instability::unstable]
567impl<Dm> embassy_embedded_hal::SetConfig for Uart<'_, Dm>
568where
569 Dm: DriverMode,
570{
571 type Config = Config;
572 type ConfigError = ConfigError;
573
574 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
575 self.apply_config(config)
576 }
577}
578
579#[instability::unstable]
580impl<Dm> embassy_embedded_hal::SetConfig for UartRx<'_, Dm>
581where
582 Dm: DriverMode,
583{
584 type Config = Config;
585 type ConfigError = ConfigError;
586
587 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
588 self.apply_config(config)
589 }
590}
591
592#[instability::unstable]
593impl<Dm> embassy_embedded_hal::SetConfig for UartTx<'_, Dm>
594where
595 Dm: DriverMode,
596{
597 type Config = Config;
598 type ConfigError = ConfigError;
599
600 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
601 self.apply_config(config)
602 }
603}
604
605impl<'d> UartTx<'d, Blocking> {
606 #[procmacros::doc_replace]
607 #[instability::unstable]
623 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
624 let (_, uart_tx) = UartBuilder::new(uart).init(config)?.split();
625
626 Ok(uart_tx)
627 }
628
629 #[instability::unstable]
631 pub fn into_async(self) -> UartTx<'d, Async> {
632 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
633 self.uart
634 .set_interrupt_handler(self.uart.info().async_handler);
635 }
636 self.uart.state().is_tx_async.store(true, Ordering::Release);
637
638 UartTx {
639 uart: self.uart,
640 phantom: PhantomData,
641 guard: self.guard,
642 rts_pin: self.rts_pin,
643 tx_pin: self.tx_pin,
644 }
645 }
646}
647
648impl<'d> UartTx<'d, Async> {
649 #[instability::unstable]
651 pub fn into_blocking(self) -> UartTx<'d, Blocking> {
652 self.uart
653 .state()
654 .is_tx_async
655 .store(false, Ordering::Release);
656 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
657 self.uart.disable_peri_interrupt();
658 }
659
660 UartTx {
661 uart: self.uart,
662 phantom: PhantomData,
663 guard: self.guard,
664 rts_pin: self.rts_pin,
665 tx_pin: self.tx_pin,
666 }
667 }
668
669 pub async fn write_async(&mut self, bytes: &[u8]) -> Result<usize, TxError> {
685 let space = loop {
688 let tx_fifo_count = self.uart.info().tx_fifo_count();
689 let space = Info::UART_FIFO_SIZE - tx_fifo_count;
690 if space != 0 {
691 break space;
692 }
693 UartTxFuture::new(self.uart.reborrow(), TxEvent::FiFoEmpty).await;
694 };
695
696 let free = (space as usize).min(bytes.len());
697
698 for &byte in &bytes[..free] {
699 self.uart
700 .info()
701 .regs()
702 .fifo()
703 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
704 }
705
706 Ok(free)
707 }
708
709 pub async fn flush_async(&mut self) -> Result<(), TxError> {
719 while self.uart.info().tx_fifo_count() > 0 {
723 UartTxFuture::new(self.uart.reborrow(), TxEvent::Done).await;
724 }
725
726 self.flush_last_byte();
727
728 Ok(())
729 }
730}
731
732impl<'d, Dm> UartTx<'d, Dm>
733where
734 Dm: DriverMode,
735{
736 #[instability::unstable]
738 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
739 let rts = rts.into();
740
741 rts.apply_output_config(&OutputConfig::default());
742 rts.set_output_enable(true);
743
744 self.rts_pin = rts.connect_with_guard(self.uart.info().rts_signal);
745
746 self
747 }
748
749 #[instability::unstable]
756 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
757 let tx = tx.into();
758
759 tx.set_output_high(true);
761 tx.apply_output_config(&OutputConfig::default());
762 tx.set_output_enable(true);
763
764 self.tx_pin = tx.connect_with_guard(self.uart.info().tx_signal);
765
766 self
767 }
768
769 #[instability::unstable]
776 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
777 self.uart
778 .info()
779 .set_tx_fifo_empty_threshold(config.tx.fifo_empty_threshold)?;
780 self.uart.info().txfifo_reset();
781 Ok(())
782 }
783
784 #[instability::unstable]
788 pub fn write_ready(&mut self) -> bool {
789 self.uart.info().tx_fifo_count() < Info::UART_FIFO_SIZE
790 }
791
792 #[instability::unstable]
806 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
807 self.uart.info().write(data)
808 }
809
810 fn write_all(&mut self, mut data: &[u8]) -> Result<(), TxError> {
811 while !data.is_empty() {
812 let bytes_written = self.write(data)?;
813 data = &data[bytes_written..];
814 }
815 Ok(())
816 }
817
818 #[instability::unstable]
823 pub fn flush(&mut self) -> Result<(), TxError> {
824 while self.uart.info().tx_fifo_count() > 0 {}
825 self.flush_last_byte();
826 Ok(())
827 }
828
829 fn flush_last_byte(&mut self) {
830 crate::rom::ets_delay_us(10);
836 while !self.is_tx_idle() {}
837 }
838
839 fn is_tx_idle(&self) -> bool {
844 #[cfg(esp32)]
845 let status = self.regs().status();
846 #[cfg(not(esp32))]
847 let status = self.regs().fsm_status();
848
849 status.read().st_utx_out().bits() == 0x0
850 }
851
852 fn disable_tx_interrupts(&self) {
858 self.regs().int_clr().write(|w| {
859 w.txfifo_empty().clear_bit_by_one();
860 w.tx_brk_done().clear_bit_by_one();
861 w.tx_brk_idle_done().clear_bit_by_one();
862 w.tx_done().clear_bit_by_one()
863 });
864
865 self.regs().int_ena().write(|w| {
866 w.txfifo_empty().clear_bit();
867 w.tx_brk_done().clear_bit();
868 w.tx_brk_idle_done().clear_bit();
869 w.tx_done().clear_bit()
870 });
871 }
872
873 fn regs(&self) -> &RegisterBlock {
874 self.uart.info().regs()
875 }
876}
877
878#[inline(always)]
879fn sync_regs(_register_block: &RegisterBlock) {
880 #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
881 {
882 cfg_if::cfg_if! {
883 if #[cfg(any(esp32c6, esp32h2))] {
884 let update_reg = _register_block.reg_update();
885 } else {
886 let update_reg = _register_block.id();
887 }
888 }
889
890 update_reg.modify(|_, w| w.reg_update().set_bit());
891
892 while update_reg.read().reg_update().bit_is_set() {
893 }
895 }
896}
897
898impl<'d> UartRx<'d, Blocking> {
899 #[procmacros::doc_replace]
900 #[instability::unstable]
914 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
915 let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();
916
917 Ok(uart_rx)
918 }
919
920 #[instability::unstable]
922 pub fn into_async(self) -> UartRx<'d, Async> {
923 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
924 self.uart
925 .set_interrupt_handler(self.uart.info().async_handler);
926 }
927 self.uart.state().is_rx_async.store(true, Ordering::Release);
928
929 UartRx {
930 uart: self.uart,
931 phantom: PhantomData,
932 guard: self.guard,
933 }
934 }
935}
936
937impl<'d> UartRx<'d, Async> {
938 #[instability::unstable]
940 pub fn into_blocking(self) -> UartRx<'d, Blocking> {
941 self.uart
942 .state()
943 .is_rx_async
944 .store(false, Ordering::Release);
945 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
946 self.uart.disable_peri_interrupt();
947 }
948
949 UartRx {
950 uart: self.uart,
951 phantom: PhantomData,
952 guard: self.guard,
953 }
954 }
955
956 async fn wait_for_buffered_data(
957 &mut self,
958 minimum: usize,
959 preferred: usize,
960 listen_for_timeout: bool,
961 ) -> Result<(), RxError> {
962 while self.uart.info().rx_fifo_count() < (minimum as u16).min(Info::RX_FIFO_MAX_THRHD) {
963 let amount = u16::try_from(preferred)
964 .unwrap_or(Info::RX_FIFO_MAX_THRHD)
965 .min(Info::RX_FIFO_MAX_THRHD);
966
967 let current = self.uart.info().rx_fifo_full_threshold();
968 let _guard = if current > amount {
969 let info = self.uart.info();
973 unwrap!(info.set_rx_fifo_full_threshold(amount));
974 Some(OnDrop::new(|| {
975 unwrap!(info.set_rx_fifo_full_threshold(current));
976 }))
977 } else {
978 None
979 };
980
981 let mut events = RxEvent::FifoFull
983 | RxEvent::FifoOvf
984 | RxEvent::FrameError
985 | RxEvent::GlitchDetected
986 | RxEvent::ParityError;
987
988 if self.regs().at_cmd_char().read().char_num().bits() > 0 {
989 events |= RxEvent::CmdCharDetected;
990 }
991
992 cfg_if::cfg_if! {
993 if #[cfg(any(esp32c6, esp32h2))] {
994 let reg_en = self.regs().tout_conf();
995 } else {
996 let reg_en = self.regs().conf1();
997 }
998 };
999 if listen_for_timeout && reg_en.read().rx_tout_en().bit_is_set() {
1000 events |= RxEvent::FifoTout;
1001 }
1002
1003 let events = UartRxFuture::new(self.uart.reborrow(), events).await;
1004
1005 let result = rx_event_check_for_error(events);
1006 if let Err(error) = result {
1007 if error == RxError::FifoOverflowed {
1008 self.uart.info().rxfifo_reset();
1009 }
1010 return Err(error);
1011 }
1012 }
1013
1014 Ok(())
1015 }
1016
1017 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1036 if buf.is_empty() {
1037 return Ok(0);
1038 }
1039
1040 self.wait_for_buffered_data(1, buf.len(), true).await?;
1041
1042 self.read_buffered(buf)
1043 }
1044
1045 pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
1060 while !buf.is_empty() {
1061 self.wait_for_buffered_data(buf.len(), buf.len(), false)
1065 .await?;
1066
1067 let read = self.uart.info().read_buffered(buf)?;
1068 buf = &mut buf[read..];
1069 }
1070
1071 Ok(())
1072 }
1073}
1074
1075impl<'d, Dm> UartRx<'d, Dm>
1076where
1077 Dm: DriverMode,
1078{
1079 fn regs(&self) -> &RegisterBlock {
1080 self.uart.info().regs()
1081 }
1082
1083 #[instability::unstable]
1087 pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
1088 let cts = cts.into();
1089
1090 cts.apply_input_config(&InputConfig::default());
1091 cts.set_input_enable(true);
1092
1093 self.uart.info().cts_signal.connect_to(&cts);
1094
1095 self
1096 }
1097
1098 #[instability::unstable]
1107 pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
1108 let rx = rx.into();
1109
1110 rx.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
1111 rx.set_input_enable(true);
1112
1113 self.uart.info().rx_signal.connect_to(&rx);
1114
1115 self
1116 }
1117
1118 #[instability::unstable]
1125 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1126 self.uart
1127 .info()
1128 .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
1129 self.uart
1130 .info()
1131 .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
1132
1133 self.uart.info().rxfifo_reset();
1134 Ok(())
1135 }
1136
1137 #[instability::unstable]
1141 pub fn check_for_errors(&mut self) -> Result<(), RxError> {
1142 self.uart.info().check_for_errors()
1143 }
1144
1145 #[instability::unstable]
1149 pub fn read_ready(&mut self) -> bool {
1150 self.uart.info().rx_fifo_count() > 0
1151 }
1152
1153 #[instability::unstable]
1172 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1173 self.uart.info().read(buf)
1174 }
1175
1176 #[instability::unstable]
1194 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1195 self.uart.info().read_buffered(buf)
1196 }
1197
1198 fn disable_rx_interrupts(&self) {
1204 self.regs().int_clr().write(|w| {
1205 w.rxfifo_full().clear_bit_by_one();
1206 w.rxfifo_ovf().clear_bit_by_one();
1207 w.rxfifo_tout().clear_bit_by_one();
1208 w.at_cmd_char_det().clear_bit_by_one()
1209 });
1210
1211 self.regs().int_ena().write(|w| {
1212 w.rxfifo_full().clear_bit();
1213 w.rxfifo_ovf().clear_bit();
1214 w.rxfifo_tout().clear_bit();
1215 w.at_cmd_char_det().clear_bit()
1216 });
1217 }
1218}
1219
1220impl<'d> Uart<'d, Blocking> {
1221 #[procmacros::doc_replace]
1222 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1240 UartBuilder::new(uart).init(config)
1241 }
1242
1243 pub fn into_async(self) -> Uart<'d, Async> {
1248 Uart {
1249 rx: self.rx.into_async(),
1250 tx: self.tx.into_async(),
1251 }
1252 }
1253
1254 #[cfg_attr(
1255 not(multi_core),
1256 doc = "Registers an interrupt handler for the peripheral."
1257 )]
1258 #[cfg_attr(
1259 multi_core,
1260 doc = "Registers an interrupt handler for the peripheral on the current core."
1261 )]
1262 #[doc = ""]
1263 #[instability::unstable]
1269 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1270 self.tx.uart.set_interrupt_handler(handler);
1272 }
1273
1274 #[procmacros::doc_replace]
1275 #[instability::unstable]
1342 pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1343 self.tx.uart.info().enable_listen(interrupts.into(), true)
1344 }
1345
1346 #[instability::unstable]
1348 pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1349 self.tx.uart.info().enable_listen(interrupts.into(), false)
1350 }
1351
1352 #[instability::unstable]
1354 pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1355 self.tx.uart.info().interrupts()
1356 }
1357
1358 #[instability::unstable]
1360 pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1361 self.tx.uart.info().clear_interrupts(interrupts)
1362 }
1363}
1364
1365impl<'d> Uart<'d, Async> {
1366 pub fn into_blocking(self) -> Uart<'d, Blocking> {
1371 Uart {
1372 rx: self.rx.into_blocking(),
1373 tx: self.tx.into_blocking(),
1374 }
1375 }
1376
1377 #[procmacros::doc_replace]
1378 pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1409 self.tx.write_async(words).await
1410 }
1411
1412 #[procmacros::doc_replace]
1413 pub async fn flush_async(&mut self) -> Result<(), TxError> {
1439 self.tx.flush_async().await
1440 }
1441
1442 #[procmacros::doc_replace]
1443 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1481 self.rx.read_async(buf).await
1482 }
1483
1484 #[instability::unstable]
1499 pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1500 self.rx.read_exact_async(buf).await
1501 }
1502}
1503
1504#[derive(Debug, EnumSetType)]
1506#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1507#[non_exhaustive]
1508#[instability::unstable]
1509pub enum UartInterrupt {
1510 AtCmd,
1513
1514 TxDone,
1516
1517 RxFifoFull,
1520
1521 RxTimeout,
1524}
1525
1526impl<'d, Dm> Uart<'d, Dm>
1527where
1528 Dm: DriverMode,
1529{
1530 #[procmacros::doc_replace]
1531 pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
1550 self.rx = self.rx.with_rx(rx);
1551 self
1552 }
1553
1554 #[procmacros::doc_replace]
1555 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
1570 self.tx = self.tx.with_tx(tx);
1571 self
1572 }
1573
1574 #[procmacros::doc_replace]
1575 pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
1589 self.rx = self.rx.with_cts(cts);
1590 self
1591 }
1592
1593 #[procmacros::doc_replace]
1594 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
1608 self.tx = self.tx.with_rts(rts);
1609 self
1610 }
1611
1612 fn regs(&self) -> &RegisterBlock {
1613 self.tx.uart.info().regs()
1615 }
1616
1617 #[instability::unstable]
1621 pub fn write_ready(&mut self) -> bool {
1622 self.tx.write_ready()
1623 }
1624
1625 #[procmacros::doc_replace]
1626 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
1652 self.tx.write(data)
1653 }
1654
1655 #[procmacros::doc_replace]
1656 pub fn flush(&mut self) -> Result<(), TxError> {
1671 self.tx.flush()
1672 }
1673
1674 #[instability::unstable]
1678 pub fn read_ready(&mut self) -> bool {
1679 self.rx.read_ready()
1680 }
1681
1682 #[procmacros::doc_replace]
1683 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1718 self.rx.read(buf)
1719 }
1720
1721 #[procmacros::doc_replace]
1722 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1740 self.rx.uart.info().apply_config(config)?;
1743 self.rx.apply_config(config)?;
1744 self.tx.apply_config(config)?;
1745 Ok(())
1746 }
1747
1748 #[procmacros::doc_replace]
1749 #[instability::unstable]
1773 pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
1774 (self.rx, self.tx)
1775 }
1776
1777 #[instability::unstable]
1779 pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
1780 self.rx.check_for_errors()
1781 }
1782
1783 #[instability::unstable]
1800 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1801 self.rx.read_buffered(buf)
1802 }
1803
1804 #[instability::unstable]
1806 pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
1807 #[cfg(not(any(esp32, esp32s2)))]
1808 self.regs()
1809 .clk_conf()
1810 .modify(|_, w| w.sclk_en().clear_bit());
1811
1812 self.regs().at_cmd_char().write(|w| unsafe {
1813 w.at_cmd_char().bits(config.cmd_char);
1814 w.char_num().bits(config.char_num)
1815 });
1816
1817 if let Some(pre_idle_count) = config.pre_idle_count {
1818 self.regs()
1819 .at_cmd_precnt()
1820 .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
1821 }
1822
1823 if let Some(post_idle_count) = config.post_idle_count {
1824 self.regs()
1825 .at_cmd_postcnt()
1826 .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
1827 }
1828
1829 if let Some(gap_timeout) = config.gap_timeout {
1830 self.regs()
1831 .at_cmd_gaptout()
1832 .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
1833 }
1834
1835 #[cfg(not(any(esp32, esp32s2)))]
1836 self.regs().clk_conf().modify(|_, w| w.sclk_en().set_bit());
1837
1838 sync_regs(self.regs());
1839 }
1840
1841 #[inline(always)]
1842 fn init(&mut self, config: Config) -> Result<(), ConfigError> {
1843 cfg_if::cfg_if! {
1844 if #[cfg(any(esp32, esp32s2))] {
1845 } else if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
1847 crate::peripherals::SYSTEM::regs()
1848 .perip_clk_en0()
1849 .modify(|_, w| w.uart_mem_clk_en().set_bit());
1850 } else {
1851 self.regs()
1852 .conf0()
1853 .modify(|_, w| w.mem_clk_en().set_bit());
1854 }
1855 };
1856
1857 self.uart_peripheral_reset();
1858
1859 self.rx.disable_rx_interrupts();
1860 self.tx.disable_tx_interrupts();
1861
1862 self.apply_config(&config)?;
1863
1864 self.rx.uart.info().rxfifo_reset();
1866 self.rx.uart.info().txfifo_reset();
1867
1868 self.regs()
1871 .idle_conf()
1872 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
1873
1874 self.regs().conf0().modify(|_, w| w.err_wr_mask().set_bit());
1877
1878 crate::rom::ets_delay_us(15);
1879
1880 self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
1883
1884 Ok(())
1885 }
1886
1887 fn is_instance(&self, other: impl Instance) -> bool {
1888 self.tx.uart.info().is_instance(other)
1889 }
1890
1891 #[inline(always)]
1892 fn uart_peripheral_reset(&self) {
1893 if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
1904 return;
1905 }
1906
1907 fn rst_core(_reg_block: &RegisterBlock, _enable: bool) {
1908 #[cfg(not(any(esp32, esp32s2, esp32c6, esp32h2)))]
1909 _reg_block
1910 .clk_conf()
1911 .modify(|_, w| w.rst_core().bit(_enable));
1912 }
1913
1914 rst_core(self.regs(), true);
1915 PeripheralClockControl::reset(self.tx.uart.info().peripheral);
1916 rst_core(self.regs(), false);
1917 }
1918}
1919
1920impl crate::private::Sealed for Uart<'_, Blocking> {}
1921
1922#[instability::unstable]
1923impl crate::interrupt::InterruptConfigurable for Uart<'_, Blocking> {
1924 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1925 self.tx.uart.set_interrupt_handler(handler);
1927 }
1928}
1929
1930#[instability::unstable]
1931impl<Dm> ufmt_write::uWrite for Uart<'_, Dm>
1932where
1933 Dm: DriverMode,
1934{
1935 type Error = TxError;
1936
1937 #[inline]
1938 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1939 self.tx.write_str(s)
1940 }
1941
1942 #[inline]
1943 fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
1944 self.tx.write_char(ch)
1945 }
1946}
1947
1948#[instability::unstable]
1949impl<Dm> ufmt_write::uWrite for UartTx<'_, Dm>
1950where
1951 Dm: DriverMode,
1952{
1953 type Error = TxError;
1954
1955 #[inline]
1956 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1957 self.write_all(s.as_bytes())
1958 }
1959}
1960
1961impl<Dm> core::fmt::Write for Uart<'_, Dm>
1962where
1963 Dm: DriverMode,
1964{
1965 #[inline]
1966 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1967 self.tx.write_str(s)
1968 }
1969}
1970
1971impl<Dm> core::fmt::Write for UartTx<'_, Dm>
1972where
1973 Dm: DriverMode,
1974{
1975 #[inline]
1976 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1977 self.write_all(s.as_bytes()).map_err(|_| core::fmt::Error)
1978 }
1979}
1980
1981#[instability::unstable]
1983#[derive(Debug, Clone, Copy, PartialEq)]
1984#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1985#[non_exhaustive]
1986pub enum IoError {
1987 Tx(TxError),
1989 Rx(RxError),
1991}
1992
1993#[instability::unstable]
1994impl core::error::Error for IoError {}
1995
1996#[instability::unstable]
1997impl core::fmt::Display for IoError {
1998 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1999 match self {
2000 IoError::Tx(e) => e.fmt(f),
2001 IoError::Rx(e) => e.fmt(f),
2002 }
2003 }
2004}
2005
2006#[instability::unstable]
2007impl embedded_io::Error for IoError {
2008 fn kind(&self) -> embedded_io::ErrorKind {
2009 embedded_io::ErrorKind::Other
2010 }
2011}
2012
2013#[instability::unstable]
2014impl From<RxError> for IoError {
2015 fn from(e: RxError) -> Self {
2016 IoError::Rx(e)
2017 }
2018}
2019
2020#[instability::unstable]
2021impl From<TxError> for IoError {
2022 fn from(e: TxError) -> Self {
2023 IoError::Tx(e)
2024 }
2025}
2026
2027#[instability::unstable]
2028impl<Dm: DriverMode> embedded_io::ErrorType for Uart<'_, Dm> {
2029 type Error = IoError;
2030}
2031
2032#[instability::unstable]
2033impl<Dm: DriverMode> embedded_io::ErrorType for UartTx<'_, Dm> {
2034 type Error = TxError;
2035}
2036
2037#[instability::unstable]
2038impl<Dm: DriverMode> embedded_io::ErrorType for UartRx<'_, Dm> {
2039 type Error = RxError;
2040}
2041
2042#[instability::unstable]
2043impl<Dm> embedded_io::Read for Uart<'_, Dm>
2044where
2045 Dm: DriverMode,
2046{
2047 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2048 self.rx.read(buf).map_err(IoError::Rx)
2049 }
2050}
2051
2052#[instability::unstable]
2053impl<Dm> embedded_io::Read for UartRx<'_, Dm>
2054where
2055 Dm: DriverMode,
2056{
2057 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2058 self.read(buf)
2059 }
2060}
2061
2062#[instability::unstable]
2063impl<Dm> embedded_io::ReadReady for Uart<'_, Dm>
2064where
2065 Dm: DriverMode,
2066{
2067 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2068 Ok(self.rx.read_ready())
2069 }
2070}
2071
2072#[instability::unstable]
2073impl<Dm> embedded_io::ReadReady for UartRx<'_, Dm>
2074where
2075 Dm: DriverMode,
2076{
2077 fn read_ready(&mut self) -> Result<bool, Self::Error> {
2078 Ok(self.read_ready())
2079 }
2080}
2081
2082#[instability::unstable]
2083impl<Dm> embedded_io::Write for Uart<'_, Dm>
2084where
2085 Dm: DriverMode,
2086{
2087 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2088 self.tx.write(buf).map_err(IoError::Tx)
2089 }
2090
2091 fn flush(&mut self) -> Result<(), Self::Error> {
2092 self.tx.flush().map_err(IoError::Tx)
2093 }
2094}
2095
2096#[instability::unstable]
2097impl<Dm> embedded_io::Write for UartTx<'_, Dm>
2098where
2099 Dm: DriverMode,
2100{
2101 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2102 self.write(buf)
2103 }
2104
2105 fn flush(&mut self) -> Result<(), Self::Error> {
2106 self.flush()
2107 }
2108}
2109
2110#[instability::unstable]
2111impl<Dm> embedded_io::WriteReady for UartTx<'_, Dm>
2112where
2113 Dm: DriverMode,
2114{
2115 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2116 Ok(self.write_ready())
2117 }
2118}
2119
2120#[instability::unstable]
2121impl<Dm> embedded_io::WriteReady for Uart<'_, Dm>
2122where
2123 Dm: DriverMode,
2124{
2125 fn write_ready(&mut self) -> Result<bool, Self::Error> {
2126 Ok(self.tx.write_ready())
2127 }
2128}
2129
2130#[derive(Debug, EnumSetType)]
2131pub(crate) enum TxEvent {
2132 Done,
2133 FiFoEmpty,
2134}
2135
2136#[derive(Debug, EnumSetType)]
2137pub(crate) enum RxEvent {
2138 FifoFull,
2139 CmdCharDetected,
2140 FifoOvf,
2141 FifoTout,
2142 GlitchDetected,
2143 FrameError,
2144 ParityError,
2145}
2146
2147fn rx_event_check_for_error(events: EnumSet<RxEvent>) -> Result<(), RxError> {
2148 for event in events {
2149 match event {
2150 RxEvent::FifoOvf => return Err(RxError::FifoOverflowed),
2151 RxEvent::GlitchDetected => return Err(RxError::GlitchOccurred),
2152 RxEvent::FrameError => return Err(RxError::FrameFormatViolated),
2153 RxEvent::ParityError => return Err(RxError::ParityMismatch),
2154 RxEvent::FifoFull | RxEvent::CmdCharDetected | RxEvent::FifoTout => continue,
2155 }
2156 }
2157
2158 Ok(())
2159}
2160
2161#[must_use = "futures do nothing unless you `.await` or poll them"]
2167struct UartRxFuture {
2168 events: EnumSet<RxEvent>,
2169 uart: &'static Info,
2170 state: &'static State,
2171 registered: bool,
2172}
2173
2174impl UartRxFuture {
2175 fn new(uart: impl Instance, events: impl Into<EnumSet<RxEvent>>) -> Self {
2176 Self {
2177 events: events.into(),
2178 uart: uart.info(),
2179 state: uart.state(),
2180 registered: false,
2181 }
2182 }
2183}
2184
2185impl core::future::Future for UartRxFuture {
2186 type Output = EnumSet<RxEvent>;
2187
2188 fn poll(
2189 mut self: core::pin::Pin<&mut Self>,
2190 cx: &mut core::task::Context<'_>,
2191 ) -> core::task::Poll<Self::Output> {
2192 let events = self.uart.rx_events().intersection(self.events);
2193 if !events.is_empty() {
2194 self.uart.clear_rx_events(events);
2195 Poll::Ready(events)
2196 } else {
2197 self.state.rx_waker.register(cx.waker());
2198 if !self.registered {
2199 self.uart.enable_listen_rx(self.events, true);
2200 self.registered = true;
2201 }
2202 Poll::Pending
2203 }
2204 }
2205}
2206
2207impl Drop for UartRxFuture {
2208 fn drop(&mut self) {
2209 self.uart.enable_listen_rx(self.events, false);
2213 }
2214}
2215
2216#[must_use = "futures do nothing unless you `.await` or poll them"]
2217struct UartTxFuture {
2218 events: EnumSet<TxEvent>,
2219 uart: &'static Info,
2220 state: &'static State,
2221 registered: bool,
2222}
2223
2224impl UartTxFuture {
2225 fn new(uart: impl Instance, events: impl Into<EnumSet<TxEvent>>) -> Self {
2226 Self {
2227 events: events.into(),
2228 uart: uart.info(),
2229 state: uart.state(),
2230 registered: false,
2231 }
2232 }
2233}
2234
2235impl core::future::Future for UartTxFuture {
2236 type Output = ();
2237
2238 fn poll(
2239 mut self: core::pin::Pin<&mut Self>,
2240 cx: &mut core::task::Context<'_>,
2241 ) -> core::task::Poll<Self::Output> {
2242 let events = self.uart.tx_events().intersection(self.events);
2243 if !events.is_empty() {
2244 self.uart.clear_tx_events(events);
2245 Poll::Ready(())
2246 } else {
2247 self.state.tx_waker.register(cx.waker());
2248 if !self.registered {
2249 self.uart.enable_listen_tx(self.events, true);
2250 self.registered = true;
2251 }
2252 Poll::Pending
2253 }
2254 }
2255}
2256
2257impl Drop for UartTxFuture {
2258 fn drop(&mut self) {
2259 self.uart.enable_listen_tx(self.events, false);
2263 }
2264}
2265
2266#[instability::unstable]
2267impl embedded_io_async::Read for Uart<'_, Async> {
2268 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2269 self.read_async(buf).await.map_err(IoError::Rx)
2270 }
2271
2272 async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError<Self::Error>> {
2273 self.read_exact_async(buf)
2274 .await
2275 .map_err(|e| ReadExactError::Other(IoError::Rx(e)))
2276 }
2277}
2278
2279#[instability::unstable]
2280impl embedded_io_async::Read for UartRx<'_, Async> {
2281 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2282 self.read_async(buf).await
2283 }
2284
2285 async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError<Self::Error>> {
2286 self.read_exact_async(buf)
2287 .await
2288 .map_err(ReadExactError::Other)
2289 }
2290}
2291
2292#[instability::unstable]
2293impl embedded_io_async::Write for Uart<'_, Async> {
2294 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2295 self.write_async(buf).await.map_err(IoError::Tx)
2296 }
2297
2298 async fn flush(&mut self) -> Result<(), Self::Error> {
2299 self.flush_async().await.map_err(IoError::Tx)
2300 }
2301}
2302
2303#[instability::unstable]
2304impl embedded_io_async::Write for UartTx<'_, Async> {
2305 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2306 self.write_async(buf).await
2307 }
2308
2309 async fn flush(&mut self) -> Result<(), Self::Error> {
2310 self.flush_async().await
2311 }
2312}
2313
2314pub(super) fn intr_handler(uart: &Info, state: &State) {
2319 let interrupts = uart.regs().int_st().read();
2320 let interrupt_bits = interrupts.bits(); let rx_wake = interrupts.rxfifo_full().bit_is_set()
2322 | interrupts.rxfifo_ovf().bit_is_set()
2323 | interrupts.rxfifo_tout().bit_is_set()
2324 | interrupts.at_cmd_char_det().bit_is_set()
2325 | interrupts.glitch_det().bit_is_set()
2326 | interrupts.frm_err().bit_is_set()
2327 | interrupts.parity_err().bit_is_set();
2328 let tx_wake = interrupts.tx_done().bit_is_set() | interrupts.txfifo_empty().bit_is_set();
2329
2330 uart.regs()
2331 .int_ena()
2332 .modify(|r, w| unsafe { w.bits(r.bits() & !interrupt_bits) });
2333
2334 if tx_wake {
2335 state.tx_waker.wake();
2336 }
2337 if rx_wake {
2338 state.rx_waker.wake();
2339 }
2340}
2341
2342#[cfg(soc_has_lp_uart)]
2344#[instability::unstable]
2345pub mod lp_uart {
2346 use crate::{
2347 gpio::lp_io::{LowPowerInput, LowPowerOutput},
2348 peripherals::{LP_AON, LP_IO, LP_UART, LPWR},
2349 uart::{Config, DataBits, Parity, StopBits},
2350 };
2351 pub struct LpUart {
2355 uart: LP_UART<'static>,
2356 }
2357
2358 impl LpUart {
2359 pub fn new(
2368 uart: LP_UART<'static>,
2369 config: Config,
2370 _tx: LowPowerOutput<'_, 5>,
2371 _rx: LowPowerInput<'_, 4>,
2372 ) -> Self {
2373 LP_AON::regs()
2375 .gpio_mux()
2376 .modify(|r, w| unsafe { w.sel().bits(r.sel().bits() | (1 << 4) | (1 << 5)) });
2377
2378 LP_IO::regs()
2379 .gpio(4)
2380 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2381 LP_IO::regs()
2382 .gpio(5)
2383 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2384
2385 let mut me = Self { uart };
2386 let uart = me.uart.register_block();
2387
2388 uart.conf0().modify(|_, w| unsafe {
2394 w.parity().clear_bit();
2395 w.parity_en().clear_bit();
2396 w.bit_num().bits(0x3);
2397 w.stop_bit_num().bits(0x1)
2398 });
2399 uart.idle_conf()
2401 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2402 uart.hwfc_conf().modify(|_, w| w.rx_flow_en().clear_bit());
2404
2405 LPWR::regs()
2410 .lpperi()
2411 .modify(|_, w| w.lp_uart_clk_sel().clear_bit());
2412
2413 me.change_baud_internal(&config);
2416 me.change_parity(config.parity);
2418 me.change_data_bits(config.data_bits);
2420 me.change_stop_bits(config.stop_bits);
2422 me.change_tx_idle(0); me.rxfifo_reset();
2427 me.txfifo_reset();
2428
2429 me
2430 }
2431
2432 fn rxfifo_reset(&mut self) {
2433 self.uart
2434 .register_block()
2435 .conf0()
2436 .modify(|_, w| w.rxfifo_rst().set_bit());
2437 self.update();
2438
2439 self.uart
2440 .register_block()
2441 .conf0()
2442 .modify(|_, w| w.rxfifo_rst().clear_bit());
2443 self.update();
2444 }
2445
2446 fn txfifo_reset(&mut self) {
2447 self.uart
2448 .register_block()
2449 .conf0()
2450 .modify(|_, w| w.txfifo_rst().set_bit());
2451 self.update();
2452
2453 self.uart
2454 .register_block()
2455 .conf0()
2456 .modify(|_, w| w.txfifo_rst().clear_bit());
2457 self.update();
2458 }
2459
2460 fn update(&mut self) {
2461 let register_block = self.uart.register_block();
2462 register_block
2463 .reg_update()
2464 .modify(|_, w| w.reg_update().set_bit());
2465 while register_block.reg_update().read().reg_update().bit_is_set() {
2466 }
2468 }
2469
2470 fn change_baud_internal(&mut self, config: &Config) {
2471 let clk = 16_000_000_u32;
2473 let max_div = 0b1111_1111_1111 - 1;
2474 let clk_div = clk.div_ceil(max_div * config.baudrate);
2475
2476 self.uart.register_block().clk_conf().modify(|_, w| unsafe {
2477 w.sclk_div_a().bits(0);
2478 w.sclk_div_b().bits(0);
2479 w.sclk_div_num().bits(clk_div as u8 - 1);
2480 w.sclk_sel().bits(match config.clock_source {
2481 super::ClockSource::Xtal => 3,
2482 super::ClockSource::RcFast => 2,
2483 super::ClockSource::Apb => panic!("Wrong clock source for LP_UART"),
2484 });
2485 w.sclk_en().set_bit()
2486 });
2487
2488 let clk = clk / clk_div;
2489 let divider = clk / config.baudrate;
2490 let divider = divider as u16;
2491
2492 self.uart
2493 .register_block()
2494 .clkdiv()
2495 .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) });
2496
2497 self.update();
2498 }
2499
2500 pub fn change_baud(&mut self, config: &Config) {
2508 self.change_baud_internal(config);
2509 self.txfifo_reset();
2510 self.rxfifo_reset();
2511 }
2512
2513 fn change_parity(&mut self, parity: Parity) -> &mut Self {
2514 if parity != Parity::None {
2515 self.uart
2516 .register_block()
2517 .conf0()
2518 .modify(|_, w| w.parity().bit((parity as u8 & 0x1) != 0));
2519 }
2520
2521 self.uart
2522 .register_block()
2523 .conf0()
2524 .modify(|_, w| match parity {
2525 Parity::None => w.parity_en().clear_bit(),
2526 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2527 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2528 });
2529
2530 self
2531 }
2532
2533 fn change_data_bits(&mut self, data_bits: DataBits) -> &mut Self {
2534 self.uart
2535 .register_block()
2536 .conf0()
2537 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2538
2539 self.update();
2540 self
2541 }
2542
2543 fn change_stop_bits(&mut self, stop_bits: StopBits) -> &mut Self {
2544 self.uart
2545 .register_block()
2546 .conf0()
2547 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2548
2549 self.update();
2550 self
2551 }
2552
2553 fn change_tx_idle(&mut self, idle_num: u16) -> &mut Self {
2554 self.uart
2555 .register_block()
2556 .idle_conf()
2557 .modify(|_, w| unsafe { w.tx_idle_num().bits(idle_num) });
2558
2559 self.update();
2560 self
2561 }
2562 }
2563}
2564
2565pub trait Instance: crate::private::Sealed + any::Degrade {
2567 #[doc(hidden)]
2568 fn parts(&self) -> (&'static Info, &'static State);
2570
2571 #[inline(always)]
2573 #[doc(hidden)]
2574 fn info(&self) -> &'static Info {
2575 self.parts().0
2576 }
2577
2578 #[inline(always)]
2580 #[doc(hidden)]
2581 fn state(&self) -> &'static State {
2582 self.parts().1
2583 }
2584}
2585
2586#[doc(hidden)]
2588#[non_exhaustive]
2589pub struct Info {
2590 pub register_block: *const RegisterBlock,
2594
2595 pub peripheral: crate::system::Peripheral,
2597
2598 pub async_handler: InterruptHandler,
2600
2601 pub tx_signal: OutputSignal,
2603
2604 pub rx_signal: InputSignal,
2606
2607 pub cts_signal: InputSignal,
2609
2610 pub rts_signal: OutputSignal,
2612}
2613
2614#[doc(hidden)]
2616#[non_exhaustive]
2617pub struct State {
2618 pub rx_waker: AtomicWaker,
2620
2621 pub tx_waker: AtomicWaker,
2623
2624 pub is_rx_async: AtomicBool,
2626
2627 pub is_tx_async: AtomicBool,
2629}
2630
2631impl Info {
2632 const UART_FIFO_SIZE: u16 = 128;
2635 const RX_FIFO_MAX_THRHD: u16 = 127;
2636 const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
2637
2638 pub fn regs(&self) -> &RegisterBlock {
2640 unsafe { &*self.register_block }
2641 }
2642
2643 fn enable_listen(&self, interrupts: EnumSet<UartInterrupt>, enable: bool) {
2645 let reg_block = self.regs();
2646
2647 reg_block.int_ena().modify(|_, w| {
2648 for interrupt in interrupts {
2649 match interrupt {
2650 UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable),
2651 UartInterrupt::TxDone => w.tx_done().bit(enable),
2652 UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable),
2653 UartInterrupt::RxTimeout => w.rxfifo_tout().bit(enable),
2654 };
2655 }
2656 w
2657 });
2658 }
2659
2660 fn interrupts(&self) -> EnumSet<UartInterrupt> {
2661 let mut res = EnumSet::new();
2662 let reg_block = self.regs();
2663
2664 let ints = reg_block.int_raw().read();
2665
2666 if ints.at_cmd_char_det().bit_is_set() {
2667 res.insert(UartInterrupt::AtCmd);
2668 }
2669 if ints.tx_done().bit_is_set() {
2670 res.insert(UartInterrupt::TxDone);
2671 }
2672 if ints.rxfifo_full().bit_is_set() {
2673 res.insert(UartInterrupt::RxFifoFull);
2674 }
2675 if ints.rxfifo_tout().bit_is_set() {
2676 res.insert(UartInterrupt::RxTimeout);
2677 }
2678
2679 res
2680 }
2681
2682 fn clear_interrupts(&self, interrupts: EnumSet<UartInterrupt>) {
2683 let reg_block = self.regs();
2684
2685 reg_block.int_clr().write(|w| {
2686 for interrupt in interrupts {
2687 match interrupt {
2688 UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(),
2689 UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
2690 UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(),
2691 UartInterrupt::RxTimeout => w.rxfifo_tout().clear_bit_by_one(),
2692 };
2693 }
2694 w
2695 });
2696 }
2697
2698 fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
2699 config.validate()?;
2700 self.change_baud(config)?;
2701 self.change_data_bits(config.data_bits);
2702 self.change_parity(config.parity);
2703 self.change_stop_bits(config.stop_bits);
2704 self.change_flow_control(config.sw_flow_ctrl, config.hw_flow_ctrl);
2705
2706 Ok(())
2707 }
2708
2709 fn enable_listen_tx(&self, events: EnumSet<TxEvent>, enable: bool) {
2710 self.regs().int_ena().modify(|_, w| {
2711 for event in events {
2712 match event {
2713 TxEvent::Done => w.tx_done().bit(enable),
2714 TxEvent::FiFoEmpty => w.txfifo_empty().bit(enable),
2715 };
2716 }
2717 w
2718 });
2719 }
2720
2721 fn tx_events(&self) -> EnumSet<TxEvent> {
2722 let pending_interrupts = self.regs().int_raw().read();
2723 let mut active_events = EnumSet::new();
2724
2725 if pending_interrupts.tx_done().bit_is_set() {
2726 active_events |= TxEvent::Done;
2727 }
2728 if pending_interrupts.txfifo_empty().bit_is_set() {
2729 active_events |= TxEvent::FiFoEmpty;
2730 }
2731
2732 active_events
2733 }
2734
2735 fn clear_tx_events(&self, events: impl Into<EnumSet<TxEvent>>) {
2736 let events = events.into();
2737 self.regs().int_clr().write(|w| {
2738 for event in events {
2739 match event {
2740 TxEvent::FiFoEmpty => w.txfifo_empty().clear_bit_by_one(),
2741 TxEvent::Done => w.tx_done().clear_bit_by_one(),
2742 };
2743 }
2744 w
2745 });
2746 }
2747
2748 fn enable_listen_rx(&self, events: EnumSet<RxEvent>, enable: bool) {
2749 self.regs().int_ena().modify(|_, w| {
2750 for event in events {
2751 match event {
2752 RxEvent::FifoFull => w.rxfifo_full().bit(enable),
2753 RxEvent::CmdCharDetected => w.at_cmd_char_det().bit(enable),
2754
2755 RxEvent::FifoOvf => w.rxfifo_ovf().bit(enable),
2756 RxEvent::FifoTout => w.rxfifo_tout().bit(enable),
2757 RxEvent::GlitchDetected => w.glitch_det().bit(enable),
2758 RxEvent::FrameError => w.frm_err().bit(enable),
2759 RxEvent::ParityError => w.parity_err().bit(enable),
2760 };
2761 }
2762 w
2763 });
2764 }
2765
2766 fn rx_events(&self) -> EnumSet<RxEvent> {
2767 let pending_interrupts = self.regs().int_raw().read();
2768 let mut active_events = EnumSet::new();
2769
2770 if pending_interrupts.rxfifo_full().bit_is_set() {
2771 active_events |= RxEvent::FifoFull;
2772 }
2773 if pending_interrupts.at_cmd_char_det().bit_is_set() {
2774 active_events |= RxEvent::CmdCharDetected;
2775 }
2776 if pending_interrupts.rxfifo_ovf().bit_is_set() {
2777 active_events |= RxEvent::FifoOvf;
2778 }
2779 if pending_interrupts.rxfifo_tout().bit_is_set() {
2780 active_events |= RxEvent::FifoTout;
2781 }
2782 if pending_interrupts.glitch_det().bit_is_set() {
2783 active_events |= RxEvent::GlitchDetected;
2784 }
2785 if pending_interrupts.frm_err().bit_is_set() {
2786 active_events |= RxEvent::FrameError;
2787 }
2788 if pending_interrupts.parity_err().bit_is_set() {
2789 active_events |= RxEvent::ParityError;
2790 }
2791
2792 active_events
2793 }
2794
2795 fn clear_rx_events(&self, events: impl Into<EnumSet<RxEvent>>) {
2796 let events = events.into();
2797 self.regs().int_clr().write(|w| {
2798 for event in events {
2799 match event {
2800 RxEvent::FifoFull => w.rxfifo_full().clear_bit_by_one(),
2801 RxEvent::CmdCharDetected => w.at_cmd_char_det().clear_bit_by_one(),
2802
2803 RxEvent::FifoOvf => w.rxfifo_ovf().clear_bit_by_one(),
2804 RxEvent::FifoTout => w.rxfifo_tout().clear_bit_by_one(),
2805 RxEvent::GlitchDetected => w.glitch_det().clear_bit_by_one(),
2806 RxEvent::FrameError => w.frm_err().clear_bit_by_one(),
2807 RxEvent::ParityError => w.parity_err().clear_bit_by_one(),
2808 };
2809 }
2810 w
2811 });
2812 }
2813
2814 fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
2821 if threshold > Self::RX_FIFO_MAX_THRHD {
2822 return Err(ConfigError::RxFifoThresholdNotSupported);
2823 }
2824
2825 self.regs()
2826 .conf1()
2827 .modify(|_, w| unsafe { w.rxfifo_full_thrhd().bits(threshold as _) });
2828
2829 Ok(())
2830 }
2831
2832 #[allow(clippy::useless_conversion)]
2834 fn rx_fifo_full_threshold(&self) -> u16 {
2835 self.regs().conf1().read().rxfifo_full_thrhd().bits().into()
2836 }
2837
2838 fn set_tx_fifo_empty_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
2845 if threshold > Self::TX_FIFO_MAX_THRHD {
2846 return Err(ConfigError::TxFifoThresholdNotSupported);
2847 }
2848
2849 self.regs()
2850 .conf1()
2851 .modify(|_, w| unsafe { w.txfifo_empty_thrhd().bits(threshold as _) });
2852
2853 Ok(())
2854 }
2855
2856 fn set_rx_timeout(&self, timeout: Option<u8>, _symbol_len: u8) -> Result<(), ConfigError> {
2871 cfg_if::cfg_if! {
2872 if #[cfg(esp32)] {
2873 const MAX_THRHD: u8 = 0x7F; } else {
2875 const MAX_THRHD: u16 = 0x3FF; }
2877 }
2878
2879 let register_block = self.regs();
2880
2881 if let Some(timeout) = timeout {
2882 #[cfg(esp32)]
2884 let timeout_reg = timeout;
2885 #[cfg(not(esp32))]
2887 let timeout_reg = timeout as u16 * _symbol_len as u16;
2888
2889 if timeout_reg > MAX_THRHD {
2890 return Err(ConfigError::TimeoutTooLong);
2891 }
2892
2893 cfg_if::cfg_if! {
2894 if #[cfg(esp32)] {
2895 let reg_thrhd = register_block.conf1();
2896 } else if #[cfg(any(esp32c6, esp32h2))] {
2897 let reg_thrhd = register_block.tout_conf();
2898 } else {
2899 let reg_thrhd = register_block.mem_conf();
2900 }
2901 }
2902 reg_thrhd.modify(|_, w| unsafe { w.rx_tout_thrhd().bits(timeout_reg) });
2903 }
2904
2905 cfg_if::cfg_if! {
2906 if #[cfg(any(esp32c6, esp32h2))] {
2907 let reg_en = register_block.tout_conf();
2908 } else {
2909 let reg_en = register_block.conf1();
2910 }
2911 }
2912 reg_en.modify(|_, w| w.rx_tout_en().bit(timeout.is_some()));
2913
2914 self.sync_regs();
2915
2916 Ok(())
2917 }
2918
2919 fn is_instance(&self, other: impl Instance) -> bool {
2920 self == other.info()
2921 }
2922
2923 fn sync_regs(&self) {
2924 sync_regs(self.regs());
2925 }
2926
2927 fn change_baud(&self, config: &Config) -> Result<(), ConfigError> {
2928 let clocks = Clocks::get();
2929 let clk = match config.clock_source {
2930 ClockSource::Apb => clocks.apb_clock.as_hz(),
2931 #[cfg(not(any(esp32, esp32s2)))]
2932 ClockSource::Xtal => clocks.xtal_clock.as_hz(),
2933 #[cfg(not(any(esp32, esp32s2)))]
2934 ClockSource::RcFast => crate::soc::constants::RC_FAST_CLK.as_hz(),
2935 #[cfg(any(esp32, esp32s2))]
2936 ClockSource::RefTick => crate::soc::constants::REF_TICK.as_hz(),
2937 };
2938
2939 cfg_if::cfg_if! {
2940 if #[cfg(any(esp32c2, esp32c3, esp32s3, esp32c6, esp32h2))] {
2941
2942 const MAX_DIV: u32 = 0b1111_1111_1111 - 1;
2943 let clk_div = (clk.div_ceil(MAX_DIV)).div_ceil(config.baudrate);
2944
2945 cfg_if::cfg_if! {
2947 if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
2948 if matches!(config.clock_source, ClockSource::RcFast) {
2949 crate::peripherals::LPWR::regs()
2950 .clk_conf()
2951 .modify(|_, w| w.dig_clk8m_en().variant(true));
2952 crate::rom::ets_delay_us(5);
2954 }
2955
2956 let conf = self.regs().clk_conf();
2957 } else {
2958 let pcr = crate::peripherals::PCR::regs();
2960 let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
2961 pcr.uart(0).clk_conf()
2962 } else {
2963 pcr.uart(1).clk_conf()
2964 };
2965 }
2966 };
2967
2968 conf.write(|w| unsafe {
2969 w.sclk_sel().bits(match config.clock_source {
2970 ClockSource::Apb => 1,
2971 ClockSource::RcFast => 2,
2972 ClockSource::Xtal => 3,
2973 });
2974 w.sclk_div_a().bits(0);
2975 w.sclk_div_b().bits(0);
2976 w.sclk_div_num().bits(clk_div as u8 - 1)
2977 });
2978
2979 let divider = (clk << 4) / (config.baudrate * clk_div);
2980 } else {
2981 self.regs().conf0().modify(|_, w| {
2982 w.tick_ref_always_on()
2983 .bit(config.clock_source == ClockSource::Apb)
2984 });
2985
2986 let divider = (clk << 4) / config.baudrate;
2987 }
2988 }
2989
2990 let divider_integer = divider >> 4;
2991 let divider_frag = (divider & 0xf) as u8;
2992
2993 self.regs().clkdiv().write(|w| unsafe {
2994 w.clkdiv()
2995 .bits(divider_integer as _)
2996 .frag()
2997 .bits(divider_frag)
2998 });
2999
3000 self.sync_regs();
3001
3002 #[cfg(feature = "unstable")]
3003 self.verify_baudrate(clk, config)?;
3004
3005 Ok(())
3006 }
3007
3008 fn change_data_bits(&self, data_bits: DataBits) {
3009 self.regs()
3010 .conf0()
3011 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
3012 }
3013
3014 fn change_parity(&self, parity: Parity) {
3015 self.regs().conf0().modify(|_, w| match parity {
3016 Parity::None => w.parity_en().clear_bit(),
3017 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
3018 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
3019 });
3020 }
3021
3022 fn change_stop_bits(&self, stop_bits: StopBits) {
3023 #[cfg(esp32)]
3024 {
3025 if stop_bits == StopBits::_2 {
3027 self.regs()
3028 .rs485_conf()
3029 .modify(|_, w| w.dl1_en().bit(stop_bits == StopBits::_2));
3030
3031 self.regs()
3032 .conf0()
3033 .modify(|_, w| unsafe { w.stop_bit_num().bits(1) });
3034 }
3035 }
3036
3037 #[cfg(not(esp32))]
3038 self.regs()
3039 .conf0()
3040 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
3041 }
3042
3043 fn change_flow_control(&self, sw_flow_ctrl: SwFlowControl, hw_flow_ctrl: HwFlowControl) {
3044 match sw_flow_ctrl {
3046 SwFlowControl::Enabled {
3047 xon_char,
3048 xoff_char,
3049 xon_threshold,
3050 xoff_threshold,
3051 } => {
3052 cfg_if::cfg_if! {
3053 if #[cfg(any(esp32c6, esp32h2))] {
3054 self.regs().swfc_conf0().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3055 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold)});
3056 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3057 } else if #[cfg(esp32)]{
3058 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3059 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold) });
3060 self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3061 } else {
3062 self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3063 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold as u16) });
3064 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_threshold().bits(xoff_threshold as u16) });
3065 self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_char().bits(xon_char) });
3066 self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_char().bits(xoff_char) });
3067 }
3068 }
3069 }
3070 SwFlowControl::Disabled => {
3071 cfg_if::cfg_if! {
3072 if #[cfg(any(esp32c6, esp32h2))] {
3073 let reg = self.regs().swfc_conf0();
3074 } else {
3075 let reg = self.regs().flow_conf();
3076 }
3077 }
3078
3079 reg.modify(|_, w| w.sw_flow_con_en().clear_bit());
3080 reg.modify(|_, w| w.xonoff_del().clear_bit());
3081 }
3082 }
3083
3084 self.regs().conf0().modify(|_, w| {
3085 w.tx_flow_en()
3086 .bit(matches!(hw_flow_ctrl.cts, CtsConfig::Enabled))
3087 });
3088
3089 match hw_flow_ctrl.rts {
3090 RtsConfig::Enabled(threshold) => self.configure_rts_flow_ctrl(true, Some(threshold)),
3091 RtsConfig::Disabled => self.configure_rts_flow_ctrl(false, None),
3092 }
3093
3094 #[cfg(any(esp32c6, esp32h2))]
3095 sync_regs(self.regs());
3096 }
3097
3098 fn configure_rts_flow_ctrl(&self, enable: bool, threshold: Option<u8>) {
3099 if let Some(threshold) = threshold {
3100 cfg_if::cfg_if! {
3101 if #[cfg(esp32)] {
3102 self.regs().conf1().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3103 } else if #[cfg(any(esp32c6, esp32h2))] {
3104 self.regs().hwfc_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3105 } else {
3106 self.regs().mem_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold as u16) });
3107 }
3108 }
3109 }
3110
3111 cfg_if::cfg_if! {
3112 if #[cfg(any(esp32c6, esp32h2))] {
3113 self.regs().hwfc_conf().modify(|_, w| {
3114 w.rx_flow_en().bit(enable)
3115 });
3116 } else {
3117 self.regs().conf1().modify(|_, w| {
3118 w.rx_flow_en().bit(enable)
3119 });
3120 }
3121 }
3122 }
3123
3124 fn rxfifo_reset(&self) {
3125 fn rxfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3126 reg_block.conf0().modify(|_, w| w.rxfifo_rst().bit(enable));
3127 sync_regs(reg_block);
3128 }
3129
3130 rxfifo_rst(self.regs(), true);
3131 rxfifo_rst(self.regs(), false);
3132 }
3133
3134 fn txfifo_reset(&self) {
3135 fn txfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3136 reg_block.conf0().modify(|_, w| w.txfifo_rst().bit(enable));
3137 sync_regs(reg_block);
3138 }
3139
3140 txfifo_rst(self.regs(), true);
3141 txfifo_rst(self.regs(), false);
3142 }
3143
3144 #[cfg(feature = "unstable")]
3145 fn verify_baudrate(&self, clk: u32, config: &Config) -> Result<(), ConfigError> {
3146 let clkdiv_reg = self.regs().clkdiv().read();
3149 let clkdiv_frag = clkdiv_reg.frag().bits() as u32;
3150 let clkdiv = clkdiv_reg.clkdiv().bits();
3151
3152 cfg_if::cfg_if! {
3153 if #[cfg(any(esp32, esp32s2))] {
3154 let actual_baud = (clk << 4) / ((clkdiv << 4) | clkdiv_frag);
3155 } else if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
3156 let sclk_div_num = self.regs().clk_conf().read().sclk_div_num().bits() as u32;
3157 let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
3158 } else { let pcr = crate::peripherals::PCR::regs();
3160 let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
3161 pcr.uart(0).clk_conf()
3162 } else {
3163 pcr.uart(1).clk_conf()
3164 };
3165 let sclk_div_num = conf.read().sclk_div_num().bits() as u32;
3166 let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
3167 }
3168 };
3169
3170 match config.baudrate_tolerance {
3171 BaudrateTolerance::Exact => {
3172 let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
3173 * 100)
3174 / actual_baud;
3175 if deviation > 1_u32 {
3178 return Err(ConfigError::BaudrateNotAchievable);
3179 }
3180 }
3181 BaudrateTolerance::ErrorPercent(percent) => {
3182 let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
3183 * 100)
3184 / actual_baud;
3185 if deviation > percent as u32 {
3186 return Err(ConfigError::BaudrateNotAchievable);
3187 }
3188 }
3189 _ => {}
3190 }
3191
3192 Ok(())
3193 }
3194
3195 fn current_symbol_length(&self) -> u8 {
3196 let conf0 = self.regs().conf0().read();
3197 let data_bits = conf0.bit_num().bits() + 5; let parity = conf0.parity_en().bit() as u8;
3199 let mut stop_bits = conf0.stop_bit_num().bits();
3200
3201 match stop_bits {
3202 1 => {
3203 #[cfg(esp32)]
3205 if self.regs().rs485_conf().read().dl1_en().bit_is_set() {
3206 stop_bits = 2;
3207 }
3208 }
3209 _ => stop_bits = 2,
3211 }
3212
3213 1 + data_bits + parity + stop_bits
3214 }
3215
3216 fn read_next_from_fifo(&self) -> u8 {
3220 fn access_fifo_register<R>(f: impl Fn() -> R) -> R {
3221 cfg_if::cfg_if! {
3223 if #[cfg(esp32)] {
3224 crate::interrupt::free(f)
3225 } else {
3226 f()
3227 }
3228 }
3229 }
3230
3231 let fifo_reg = self.regs().fifo();
3232 cfg_if::cfg_if! {
3233 if #[cfg(esp32s2)] {
3234 let fifo_reg = unsafe {
3236 &*fifo_reg.as_ptr().cast::<u8>().add(0x20C00000).cast::<crate::pac::uart0::FIFO>()
3237 };
3238 }
3239 }
3240
3241 access_fifo_register(|| fifo_reg.read().rxfifo_rd_byte().bits())
3242 }
3243
3244 #[allow(clippy::useless_conversion)]
3245 fn tx_fifo_count(&self) -> u16 {
3246 u16::from(self.regs().status().read().txfifo_cnt().bits())
3247 }
3248
3249 fn write_byte(&self, byte: u8) {
3250 self.regs()
3251 .fifo()
3252 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
3253 }
3254
3255 fn check_for_errors(&self) -> Result<(), RxError> {
3256 let errors = RxEvent::FifoOvf
3257 | RxEvent::FifoTout
3258 | RxEvent::GlitchDetected
3259 | RxEvent::FrameError
3260 | RxEvent::ParityError;
3261 let events = self.rx_events().intersection(errors);
3262 let result = rx_event_check_for_error(events);
3263 if result.is_err() {
3264 self.clear_rx_events(errors);
3265 if events.contains(RxEvent::FifoOvf) {
3266 self.rxfifo_reset();
3267 }
3268 }
3269 result
3270 }
3271
3272 #[cfg(not(esp32))]
3273 #[allow(clippy::unnecessary_cast)]
3274 fn rx_fifo_count(&self) -> u16 {
3275 self.regs().status().read().rxfifo_cnt().bits() as u16
3276 }
3277
3278 #[cfg(esp32)]
3279 fn rx_fifo_count(&self) -> u16 {
3280 let fifo_cnt = self.regs().status().read().rxfifo_cnt().bits();
3281
3282 let status = self.regs().mem_rx_status().read();
3285 let rd_addr: u16 = status.mem_rx_rd_addr().bits();
3286 let wr_addr: u16 = status.mem_rx_wr_addr().bits();
3287
3288 if wr_addr > rd_addr {
3289 wr_addr - rd_addr
3290 } else if wr_addr < rd_addr {
3291 (wr_addr + Info::UART_FIFO_SIZE) - rd_addr
3292 } else if fifo_cnt > 0 {
3293 Info::UART_FIFO_SIZE
3294 } else {
3295 0
3296 }
3297 }
3298
3299 fn write(&self, data: &[u8]) -> Result<usize, TxError> {
3300 if data.is_empty() {
3301 return Ok(0);
3302 }
3303
3304 while self.tx_fifo_count() >= Info::UART_FIFO_SIZE {}
3305
3306 let space = (Info::UART_FIFO_SIZE - self.tx_fifo_count()) as usize;
3307 let to_write = space.min(data.len());
3308 for &byte in &data[..to_write] {
3309 self.write_byte(byte);
3310 }
3311
3312 Ok(to_write)
3313 }
3314
3315 fn read(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3316 if buf.is_empty() {
3317 return Ok(0);
3318 }
3319
3320 while self.rx_fifo_count() == 0 {
3321 self.check_for_errors()?;
3323 }
3324
3325 self.read_buffered(buf)
3326 }
3327
3328 fn read_buffered(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3329 let to_read = (self.rx_fifo_count() as usize).min(buf.len());
3332 self.check_for_errors()?;
3333
3334 for byte_into in buf[..to_read].iter_mut() {
3335 *byte_into = self.read_next_from_fifo();
3336 }
3337
3338 Ok(to_read)
3339 }
3340}
3341
3342impl PartialEq for Info {
3343 fn eq(&self, other: &Self) -> bool {
3344 core::ptr::eq(self.register_block, other.register_block)
3345 }
3346}
3347
3348unsafe impl Sync for Info {}
3349
3350for_each_uart! {
3351 ($inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident) => {
3352 impl Instance for crate::peripherals::$inst<'_> {
3353 fn parts(&self) -> (&'static Info, &'static State) {
3354 #[crate::handler]
3355 pub(super) fn irq_handler() {
3356 intr_handler(&PERIPHERAL, &STATE);
3357 }
3358
3359 static STATE: State = State {
3360 tx_waker: AtomicWaker::new(),
3361 rx_waker: AtomicWaker::new(),
3362 is_rx_async: AtomicBool::new(false),
3363 is_tx_async: AtomicBool::new(false),
3364 };
3365
3366 static PERIPHERAL: Info = Info {
3367 register_block: crate::peripherals::$inst::ptr(),
3368 peripheral: crate::system::Peripheral::$peri,
3369 async_handler: irq_handler,
3370 tx_signal: OutputSignal::$txd,
3371 rx_signal: InputSignal::$rxd,
3372 cts_signal: InputSignal::$cts,
3373 rts_signal: OutputSignal::$rts,
3374 };
3375 (&PERIPHERAL, &STATE)
3376 }
3377 }
3378 };
3379}
3380
3381crate::any_peripheral! {
3382 pub peripheral AnyUart<'d> {
3384 #[cfg(soc_has_uart0)]
3385 Uart0(crate::peripherals::UART0<'d>),
3386 #[cfg(soc_has_uart1)]
3387 Uart1(crate::peripherals::UART1<'d>),
3388 #[cfg(soc_has_uart2)]
3389 Uart2(crate::peripherals::UART2<'d>),
3390 }
3391}
3392
3393impl Instance for AnyUart<'_> {
3394 #[inline]
3395 fn parts(&self) -> (&'static Info, &'static State) {
3396 any::delegate!(self, uart => { uart.parts() })
3397 }
3398}
3399
3400impl AnyUart<'_> {
3401 fn bind_peri_interrupt(&self, handler: unsafe extern "C" fn() -> ()) {
3402 any::delegate!(self, uart => { uart.bind_peri_interrupt(handler) })
3403 }
3404
3405 fn disable_peri_interrupt(&self) {
3406 any::delegate!(self, uart => { uart.disable_peri_interrupt() })
3407 }
3408
3409 fn enable_peri_interrupt(&self, priority: crate::interrupt::Priority) {
3410 any::delegate!(self, uart => { uart.enable_peri_interrupt(priority) })
3411 }
3412
3413 fn set_interrupt_handler(&self, handler: InterruptHandler) {
3414 self.disable_peri_interrupt();
3415
3416 self.info().enable_listen(EnumSet::all(), false);
3417 self.info().clear_interrupts(EnumSet::all());
3418
3419 self.bind_peri_interrupt(handler.handler());
3420 self.enable_peri_interrupt(handler.priority());
3421 }
3422}