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 asynch::AtomicWaker,
53 clock::Clocks,
54 gpio::{
55 interconnect::{OutputConnection, PeripheralInput, PeripheralOutput},
56 InputSignal,
57 OutputSignal,
58 PinGuard,
59 Pull,
60 },
61 interrupt::InterruptHandler,
62 pac::uart0::RegisterBlock,
63 peripheral::{Peripheral, PeripheralRef},
64 peripherals::Interrupt,
65 system::{PeripheralClockControl, PeripheralGuard},
66 Async,
67 Blocking,
68 DriverMode,
69};
70
71#[derive(Debug, Clone, Copy, PartialEq)]
73#[cfg_attr(feature = "defmt", derive(defmt::Format))]
74#[non_exhaustive]
75pub enum RxError {
76 FifoOverflowed,
80
81 GlitchOccurred,
87
88 FrameFormatViolated,
93
94 ParityMismatch,
99}
100
101impl core::error::Error for RxError {}
102
103impl core::fmt::Display for RxError {
104 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
105 match self {
106 RxError::FifoOverflowed => write!(f, "The RX FIFO overflowed"),
107 RxError::GlitchOccurred => write!(f, "A glitch was detected on the RX line"),
108 RxError::FrameFormatViolated => {
109 write!(f, "A framing error was detected on the RX line")
110 }
111 RxError::ParityMismatch => write!(f, "A parity error was detected on the RX line"),
112 }
113 }
114}
115
116#[instability::unstable]
117impl embedded_io::Error for RxError {
118 fn kind(&self) -> embedded_io::ErrorKind {
119 embedded_io::ErrorKind::Other
120 }
121}
122
123#[derive(Debug, Clone, Copy, PartialEq)]
125#[cfg_attr(feature = "defmt", derive(defmt::Format))]
126#[non_exhaustive]
127pub enum TxError {}
128
129impl core::fmt::Display for TxError {
130 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
131 write!(f, "Tx error")
132 }
133}
134
135#[instability::unstable]
136impl embedded_io::Error for TxError {
137 fn kind(&self) -> embedded_io::ErrorKind {
138 embedded_io::ErrorKind::Other
139 }
140}
141
142#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
144#[cfg_attr(feature = "defmt", derive(defmt::Format))]
145#[non_exhaustive]
146#[instability::unstable]
147pub enum ClockSource {
148 #[cfg_attr(not(any(esp32c6, esp32h2, lp_uart)), default)]
150 Apb,
151 #[cfg(not(any(esp32, esp32s2)))]
153 RcFast,
154 #[cfg(not(any(esp32, esp32s2)))]
156 #[cfg_attr(any(esp32c6, esp32h2, lp_uart), default)]
157 Xtal,
158 #[cfg(any(esp32, esp32s2))]
160 RefTick,
161}
162
163#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
169#[cfg_attr(feature = "defmt", derive(defmt::Format))]
170pub enum DataBits {
171 _5,
173 _6,
175 _7,
177 #[default]
179 _8,
180}
181
182#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
189#[cfg_attr(feature = "defmt", derive(defmt::Format))]
190pub enum Parity {
191 #[default]
193 None,
194 Even,
197 Odd,
200}
201
202#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
208#[cfg_attr(feature = "defmt", derive(defmt::Format))]
209pub enum StopBits {
210 #[default]
212 _1,
213 _1p5,
215 _2,
217}
218
219#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
221#[cfg_attr(feature = "defmt", derive(defmt::Format))]
222#[instability::unstable]
223pub enum BaudrateTolerance {
224 #[default]
226 Closest,
227 Exact,
230 ErrorPercent(u8),
232}
233
234#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
236#[cfg_attr(feature = "defmt", derive(defmt::Format))]
237#[non_exhaustive]
238pub struct Config {
239 baudrate: u32,
242 baudrate_tolerance: BaudrateTolerance,
245 data_bits: DataBits,
247 parity: Parity,
249 stop_bits: StopBits,
251 #[cfg_attr(not(feature = "unstable"), builder_lite(skip))]
253 clock_source: ClockSource,
254 rx: RxConfig,
256 tx: TxConfig,
258}
259
260impl Default for Config {
261 fn default() -> Config {
262 Config {
263 rx: RxConfig::default(),
264 tx: TxConfig::default(),
265 baudrate: 115_200,
266 baudrate_tolerance: BaudrateTolerance::default(),
267 data_bits: Default::default(),
268 parity: Default::default(),
269 stop_bits: Default::default(),
270 clock_source: Default::default(),
271 }
272 }
273}
274
275impl Config {
276 fn validate(&self) -> Result<(), ConfigError> {
277 if let BaudrateTolerance::ErrorPercent(percentage) = self.baudrate_tolerance {
278 assert!(percentage > 0 && percentage <= 100);
279 }
280
281 if self.baudrate == 0 || self.baudrate > 5_000_000 {
283 return Err(ConfigError::UnsupportedBaudrate);
284 }
285 Ok(())
286 }
287}
288
289#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
291#[cfg_attr(feature = "defmt", derive(defmt::Format))]
292#[non_exhaustive]
293pub struct RxConfig {
294 fifo_full_threshold: u16,
296 timeout: Option<u8>,
298}
299
300impl Default for RxConfig {
301 fn default() -> RxConfig {
302 RxConfig {
303 fifo_full_threshold: 120,
305 timeout: Some(10),
307 }
308 }
309}
310
311#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
313#[cfg_attr(feature = "defmt", derive(defmt::Format))]
314#[non_exhaustive]
315pub struct TxConfig {
316 fifo_empty_threshold: u16,
318}
319
320impl Default for TxConfig {
321 fn default() -> TxConfig {
322 TxConfig {
323 fifo_empty_threshold: 10,
325 }
326 }
327}
328
329#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
331#[cfg_attr(feature = "defmt", derive(defmt::Format))]
332#[instability::unstable]
333#[non_exhaustive]
334pub struct AtCmdConfig {
335 pre_idle_count: Option<u16>,
338 post_idle_count: Option<u16>,
341 gap_timeout: Option<u16>,
344 cmd_char: u8,
346 char_num: u8,
348}
349
350impl Default for AtCmdConfig {
351 fn default() -> Self {
352 Self {
353 pre_idle_count: None,
354 post_idle_count: None,
355 gap_timeout: None,
356 cmd_char: b'+',
357 char_num: 1,
358 }
359 }
360}
361
362struct UartBuilder<'d, Dm: DriverMode> {
363 uart: PeripheralRef<'d, AnyUart>,
364 phantom: PhantomData<Dm>,
365}
366
367impl<'d, Dm> UartBuilder<'d, Dm>
368where
369 Dm: DriverMode,
370{
371 fn new(uart: impl Peripheral<P = impl Instance> + 'd) -> Self {
372 crate::into_mapped_ref!(uart);
373 Self {
374 uart,
375 phantom: PhantomData,
376 }
377 }
378
379 fn init(self, config: Config) -> Result<Uart<'d, Dm>, ConfigError> {
380 let rx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
381 let tx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
382
383 let rts_pin = PinGuard::new_unconnected(self.uart.info().rts_signal);
384 let tx_pin = PinGuard::new_unconnected(self.uart.info().tx_signal);
385
386 let mut serial = Uart {
387 rx: UartRx {
388 uart: unsafe { self.uart.clone_unchecked() },
389 phantom: PhantomData,
390 guard: rx_guard,
391 },
392 tx: UartTx {
393 uart: self.uart,
394 phantom: PhantomData,
395 guard: tx_guard,
396 rts_pin,
397 tx_pin,
398 },
399 };
400 serial.init(config)?;
401
402 Ok(serial)
403 }
404}
405
406#[doc = crate::before_snippet!()]
410pub struct Uart<'d, Dm: DriverMode> {
422 rx: UartRx<'d, Dm>,
423 tx: UartTx<'d, Dm>,
424}
425
426#[instability::unstable]
428pub struct UartTx<'d, Dm: DriverMode> {
429 uart: PeripheralRef<'d, AnyUart>,
430 phantom: PhantomData<Dm>,
431 guard: PeripheralGuard,
432 rts_pin: PinGuard,
433 tx_pin: PinGuard,
434}
435
436#[instability::unstable]
438pub struct UartRx<'d, Dm: DriverMode> {
439 uart: PeripheralRef<'d, AnyUart>,
440 phantom: PhantomData<Dm>,
441 guard: PeripheralGuard,
442}
443
444#[derive(Debug, Clone, Copy, PartialEq, Eq)]
446#[cfg_attr(feature = "defmt", derive(defmt::Format))]
447#[non_exhaustive]
448pub enum ConfigError {
449 #[cfg(any(doc, feature = "unstable"))]
451 #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
452 UnachievableBaudrate,
453
454 UnsupportedBaudrate,
462
463 #[cfg_attr(esp32, doc = "127")]
465 #[cfg_attr(not(esp32), doc = "1023")]
466 UnsupportedTimeout,
468
469 UnsupportedRxFifoThreshold,
471
472 UnsupportedTxFifoThreshold,
474}
475
476impl core::error::Error for ConfigError {}
477
478impl core::fmt::Display for ConfigError {
479 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
480 match self {
481 #[cfg(feature = "unstable")]
482 ConfigError::UnachievableBaudrate => {
483 write!(f, "The requested baud rate is not achievable")
484 }
485 ConfigError::UnsupportedBaudrate => {
486 write!(f, "The requested baud rate is not supported")
487 }
488 ConfigError::UnsupportedTimeout => write!(f, "The requested timeout is not supported"),
489 ConfigError::UnsupportedRxFifoThreshold => {
490 write!(f, "The requested RX FIFO threshold is not supported")
491 }
492 ConfigError::UnsupportedTxFifoThreshold => {
493 write!(f, "The requested TX FIFO threshold is not supported")
494 }
495 }
496 }
497}
498
499#[instability::unstable]
500impl<Dm> embassy_embedded_hal::SetConfig for Uart<'_, Dm>
501where
502 Dm: DriverMode,
503{
504 type Config = Config;
505 type ConfigError = ConfigError;
506
507 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
508 self.apply_config(config)
509 }
510}
511
512#[instability::unstable]
513impl<Dm> embassy_embedded_hal::SetConfig for UartRx<'_, Dm>
514where
515 Dm: DriverMode,
516{
517 type Config = Config;
518 type ConfigError = ConfigError;
519
520 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
521 self.apply_config(config)
522 }
523}
524
525#[instability::unstable]
526impl<Dm> embassy_embedded_hal::SetConfig for UartTx<'_, Dm>
527where
528 Dm: DriverMode,
529{
530 type Config = Config;
531 type ConfigError = ConfigError;
532
533 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
534 self.apply_config(config)
535 }
536}
537
538impl<'d, Dm> UartTx<'d, Dm>
539where
540 Dm: DriverMode,
541{
542 #[instability::unstable]
544 pub fn with_rts(mut self, rts: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
545 crate::into_mapped_ref!(rts);
546 rts.set_to_push_pull_output();
547 self.rts_pin = OutputConnection::connect_with_guard(rts, self.uart.info().rts_signal);
548
549 self
550 }
551
552 #[instability::unstable]
559 pub fn with_tx(mut self, tx: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
560 crate::into_mapped_ref!(tx);
561 tx.set_output_high(true);
563 tx.set_to_push_pull_output();
564 self.tx_pin = OutputConnection::connect_with_guard(tx, self.uart.info().tx_signal);
565
566 self
567 }
568
569 #[instability::unstable]
576 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
577 self.uart
578 .info()
579 .set_tx_fifo_empty_threshold(config.tx.fifo_empty_threshold)?;
580 self.uart.info().txfifo_reset();
581 Ok(())
582 }
583
584 #[instability::unstable]
598 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
599 if data.is_empty() {
600 return Ok(0);
601 }
602
603 while self.tx_fifo_count() >= Info::UART_FIFO_SIZE {}
604
605 let space = ((Info::UART_FIFO_SIZE - self.tx_fifo_count()) as usize).min(data.len());
606 for &byte in &data[..space] {
607 self.write_byte(byte)?;
608 }
609
610 Ok(space)
611 }
612
613 fn write_byte(&mut self, word: u8) -> Result<(), TxError> {
614 self.regs()
615 .fifo()
616 .write(|w| unsafe { w.rxfifo_rd_byte().bits(word) });
617
618 Ok(())
619 }
620
621 #[allow(clippy::useless_conversion)]
622 fn tx_fifo_count(&self) -> u16 {
625 self.regs().status().read().txfifo_cnt().bits().into()
626 }
627
628 #[instability::unstable]
633 pub fn flush(&mut self) -> Result<(), TxError> {
634 while self.tx_fifo_count() > 0 {}
635 crate::rom::ets_delay_us(10);
639 while !self.is_tx_idle() {}
640 Ok(())
641 }
642
643 fn is_tx_idle(&self) -> bool {
648 #[cfg(esp32)]
649 let status = self.regs().status();
650 #[cfg(not(esp32))]
651 let status = self.regs().fsm_status();
652
653 status.read().st_utx_out().bits() == 0x0
654 }
655
656 fn disable_tx_interrupts(&self) {
662 self.regs().int_clr().write(|w| {
663 w.txfifo_empty().clear_bit_by_one();
664 w.tx_brk_done().clear_bit_by_one();
665 w.tx_brk_idle_done().clear_bit_by_one();
666 w.tx_done().clear_bit_by_one()
667 });
668
669 self.regs().int_ena().write(|w| {
670 w.txfifo_empty().clear_bit();
671 w.tx_brk_done().clear_bit();
672 w.tx_brk_idle_done().clear_bit();
673 w.tx_done().clear_bit()
674 });
675 }
676
677 fn regs(&self) -> &RegisterBlock {
678 self.uart.info().regs()
679 }
680}
681
682impl<'d> UartTx<'d, Blocking> {
683 #[doc = crate::before_snippet!()]
694 #[instability::unstable]
703 pub fn new(
704 uart: impl Peripheral<P = impl Instance> + 'd,
705 config: Config,
706 ) -> Result<Self, ConfigError> {
707 let (_, uart_tx) = UartBuilder::new(uart).init(config)?.split();
708
709 Ok(uart_tx)
710 }
711
712 #[instability::unstable]
714 pub fn into_async(self) -> UartTx<'d, Async> {
715 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
716 self.uart
717 .info()
718 .set_interrupt_handler(self.uart.info().async_handler);
719 }
720 self.uart.state().is_tx_async.store(true, Ordering::Release);
721
722 UartTx {
723 uart: self.uart,
724 phantom: PhantomData,
725 guard: self.guard,
726 rts_pin: self.rts_pin,
727 tx_pin: self.tx_pin,
728 }
729 }
730}
731
732impl<'d> UartTx<'d, Async> {
733 #[instability::unstable]
735 pub fn into_blocking(self) -> UartTx<'d, Blocking> {
736 self.uart
737 .state()
738 .is_tx_async
739 .store(false, Ordering::Release);
740 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
741 self.uart.info().disable_interrupts();
742 }
743
744 UartTx {
745 uart: self.uart,
746 phantom: PhantomData,
747 guard: self.guard,
748 rts_pin: self.rts_pin,
749 tx_pin: self.tx_pin,
750 }
751 }
752}
753
754#[inline(always)]
755fn sync_regs(_register_block: &RegisterBlock) {
756 #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
757 {
758 cfg_if::cfg_if! {
759 if #[cfg(any(esp32c6, esp32h2))] {
760 let update_reg = _register_block.reg_update();
761 } else {
762 let update_reg = _register_block.id();
763 }
764 }
765
766 update_reg.modify(|_, w| w.reg_update().set_bit());
767
768 while update_reg.read().reg_update().bit_is_set() {
769 }
771 }
772}
773
774impl<'d, Dm> UartRx<'d, Dm>
775where
776 Dm: DriverMode,
777{
778 fn regs(&self) -> &RegisterBlock {
779 self.uart.info().regs()
780 }
781
782 #[instability::unstable]
784 pub fn with_cts(self, cts: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
785 crate::into_mapped_ref!(cts);
786 cts.init_input(Pull::None);
787 self.uart.info().cts_signal.connect_to(cts);
788
789 self
790 }
791
792 #[instability::unstable]
801 pub fn with_rx(self, rx: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
802 crate::into_mapped_ref!(rx);
803 rx.init_input(Pull::Up);
804 self.uart.info().rx_signal.connect_to(rx);
805
806 self
807 }
808
809 #[instability::unstable]
816 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
817 self.uart
818 .info()
819 .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
820 self.uart
821 .info()
822 .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
823
824 self.uart.info().rxfifo_reset();
825 Ok(())
826 }
827
828 #[instability::unstable]
830 pub fn check_for_errors(&mut self) -> Result<(), RxError> {
831 let errors = RxEvent::FifoOvf
832 | RxEvent::FifoTout
833 | RxEvent::GlitchDetected
834 | RxEvent::FrameError
835 | RxEvent::ParityError;
836 let events = self.uart.info().rx_events().intersection(errors);
837 let result = rx_event_check_for_error(events);
838 if result.is_err() {
839 self.uart.info().clear_rx_events(errors);
840 }
841 result
842 }
843
844 #[instability::unstable]
863 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
864 if buf.is_empty() {
865 return Ok(0);
866 }
867
868 while self.rx_fifo_count() == 0 {
869 self.check_for_errors()?;
871 }
872
873 self.read_buffered(buf)
874 }
875
876 #[instability::unstable]
894 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
895 let to_read = (self.rx_fifo_count() as usize).min(buf.len());
898 self.check_for_errors()?;
899
900 for byte_into in buf[..to_read].iter_mut() {
901 *byte_into = self.uart.info().read_next_from_fifo();
902 }
903
904 Ok(to_read)
905 }
906
907 #[allow(clippy::useless_conversion)]
908 fn rx_fifo_count(&self) -> u16 {
909 let fifo_cnt: u16 = self.regs().status().read().rxfifo_cnt().bits().into();
910
911 #[cfg(esp32)]
914 {
915 let status = self.regs().mem_rx_status().read();
916 let rd_addr = status.mem_rx_rd_addr().bits();
917 let wr_addr = status.mem_rx_wr_addr().bits();
918
919 if wr_addr > rd_addr {
920 wr_addr - rd_addr
921 } else if wr_addr < rd_addr {
922 (wr_addr + Info::UART_FIFO_SIZE) - rd_addr
923 } else if fifo_cnt > 0 {
924 Info::UART_FIFO_SIZE
925 } else {
926 0
927 }
928 }
929
930 #[cfg(not(esp32))]
931 fifo_cnt
932 }
933
934 fn disable_rx_interrupts(&self) {
940 self.regs().int_clr().write(|w| {
941 w.rxfifo_full().clear_bit_by_one();
942 w.rxfifo_ovf().clear_bit_by_one();
943 w.rxfifo_tout().clear_bit_by_one();
944 w.at_cmd_char_det().clear_bit_by_one()
945 });
946
947 self.regs().int_ena().write(|w| {
948 w.rxfifo_full().clear_bit();
949 w.rxfifo_ovf().clear_bit();
950 w.rxfifo_tout().clear_bit();
951 w.at_cmd_char_det().clear_bit()
952 });
953 }
954}
955
956impl<'d> UartRx<'d, Blocking> {
957 #[doc = crate::before_snippet!()]
966 #[instability::unstable]
975 pub fn new(
976 uart: impl Peripheral<P = impl Instance> + 'd,
977 config: Config,
978 ) -> Result<Self, ConfigError> {
979 let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();
980
981 Ok(uart_rx)
982 }
983
984 #[instability::unstable]
986 pub fn into_async(self) -> UartRx<'d, Async> {
987 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
988 self.uart
989 .info()
990 .set_interrupt_handler(self.uart.info().async_handler);
991 }
992 self.uart.state().is_rx_async.store(true, Ordering::Release);
993
994 UartRx {
995 uart: self.uart,
996 phantom: PhantomData,
997 guard: self.guard,
998 }
999 }
1000}
1001
1002impl<'d> UartRx<'d, Async> {
1003 #[instability::unstable]
1005 pub fn into_blocking(self) -> UartRx<'d, Blocking> {
1006 self.uart
1007 .state()
1008 .is_rx_async
1009 .store(false, Ordering::Release);
1010 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
1011 self.uart.info().disable_interrupts();
1012 }
1013
1014 UartRx {
1015 uart: self.uart,
1016 phantom: PhantomData,
1017 guard: self.guard,
1018 }
1019 }
1020}
1021
1022impl<'d> Uart<'d, Blocking> {
1023 #[doc = crate::before_snippet!()]
1034 pub fn new(
1044 uart: impl Peripheral<P = impl Instance> + 'd,
1045 config: Config,
1046 ) -> Result<Self, ConfigError> {
1047 UartBuilder::new(uart).init(config)
1048 }
1049
1050 pub fn into_async(self) -> Uart<'d, Async> {
1052 Uart {
1053 rx: self.rx.into_async(),
1054 tx: self.tx.into_async(),
1055 }
1056 }
1057
1058 pub fn with_rx(mut self, rx: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
1067 self.rx = self.rx.with_rx(rx);
1068 self
1069 }
1070
1071 pub fn with_tx(mut self, tx: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
1076 self.tx = self.tx.with_tx(tx);
1077 self
1078 }
1079}
1080
1081impl<'d> Uart<'d, Async> {
1082 pub fn into_blocking(self) -> Uart<'d, Blocking> {
1084 Uart {
1085 rx: self.rx.into_blocking(),
1086 tx: self.tx.into_blocking(),
1087 }
1088 }
1089}
1090
1091#[derive(Debug, EnumSetType)]
1093#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1094#[non_exhaustive]
1095#[instability::unstable]
1096pub enum UartInterrupt {
1097 AtCmd,
1100
1101 TxDone,
1103
1104 RxFifoFull,
1107}
1108
1109impl<'d, Dm> Uart<'d, Dm>
1110where
1111 Dm: DriverMode,
1112{
1113 pub fn with_cts(mut self, cts: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
1115 self.rx = self.rx.with_cts(cts);
1116 self
1117 }
1118
1119 pub fn with_rts(mut self, rts: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
1121 self.tx = self.tx.with_rts(rts);
1122 self
1123 }
1124
1125 fn regs(&self) -> &RegisterBlock {
1126 self.tx.uart.info().regs()
1128 }
1129
1130 #[doc = crate::before_snippet!()]
1139 #[instability::unstable]
1156 pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
1157 (self.rx, self.tx)
1158 }
1159
1160 #[doc = crate::before_snippet!()]
1178 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
1188 self.tx.write(data)
1189 }
1190
1191 #[instability::unstable]
1193 pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
1194 self.rx.check_for_errors()
1195 }
1196
1197 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1215 self.rx.read(buf)
1216 }
1217
1218 #[instability::unstable]
1235 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1236 self.rx.read_buffered(buf)
1237 }
1238
1239 #[instability::unstable]
1241 pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
1242 #[cfg(not(any(esp32, esp32s2)))]
1243 self.regs()
1244 .clk_conf()
1245 .modify(|_, w| w.sclk_en().clear_bit());
1246
1247 self.regs().at_cmd_char().write(|w| unsafe {
1248 w.at_cmd_char().bits(config.cmd_char);
1249 w.char_num().bits(config.char_num)
1250 });
1251
1252 if let Some(pre_idle_count) = config.pre_idle_count {
1253 self.regs()
1254 .at_cmd_precnt()
1255 .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
1256 }
1257
1258 if let Some(post_idle_count) = config.post_idle_count {
1259 self.regs()
1260 .at_cmd_postcnt()
1261 .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
1262 }
1263
1264 if let Some(gap_timeout) = config.gap_timeout {
1265 self.regs()
1266 .at_cmd_gaptout()
1267 .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
1268 }
1269
1270 #[cfg(not(any(esp32, esp32s2)))]
1271 self.regs().clk_conf().modify(|_, w| w.sclk_en().set_bit());
1272
1273 sync_regs(self.regs());
1274 }
1275
1276 pub fn flush(&mut self) -> Result<(), TxError> {
1278 self.tx.flush()
1279 }
1280
1281 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1288 self.rx.uart.info().apply_config(config)?;
1291 self.rx.apply_config(config)?;
1292 self.tx.apply_config(config)?;
1293 Ok(())
1294 }
1295
1296 #[inline(always)]
1297 fn init(&mut self, config: Config) -> Result<(), ConfigError> {
1298 cfg_if::cfg_if! {
1299 if #[cfg(any(esp32, esp32s2))] {
1300 } else if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
1302 crate::peripherals::SYSTEM::regs()
1303 .perip_clk_en0()
1304 .modify(|_, w| w.uart_mem_clk_en().set_bit());
1305 } else {
1306 self.regs()
1307 .conf0()
1308 .modify(|_, w| w.mem_clk_en().set_bit());
1309 }
1310 };
1311
1312 self.uart_peripheral_reset();
1313
1314 self.rx.disable_rx_interrupts();
1315 self.tx.disable_tx_interrupts();
1316
1317 self.apply_config(&config)?;
1318
1319 self.rx.uart.info().rxfifo_reset();
1321 self.rx.uart.info().txfifo_reset();
1322
1323 self.regs()
1326 .idle_conf()
1327 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
1328
1329 self.regs().conf0().modify(|_, w| w.err_wr_mask().set_bit());
1332
1333 crate::rom::ets_delay_us(15);
1334
1335 self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
1338
1339 Ok(())
1340 }
1341
1342 fn is_instance(&self, other: impl Instance) -> bool {
1343 self.tx.uart.info().is_instance(other)
1344 }
1345
1346 #[inline(always)]
1347 fn uart_peripheral_reset(&self) {
1348 if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
1359 return;
1360 }
1361
1362 fn rst_core(_reg_block: &RegisterBlock, _enable: bool) {
1363 #[cfg(not(any(esp32, esp32s2, esp32c6, esp32h2)))]
1364 _reg_block
1365 .clk_conf()
1366 .modify(|_, w| w.rst_core().bit(_enable));
1367 }
1368
1369 rst_core(self.regs(), true);
1370 PeripheralClockControl::reset(self.tx.uart.info().peripheral);
1371 rst_core(self.regs(), false);
1372 }
1373}
1374
1375impl crate::private::Sealed for Uart<'_, Blocking> {}
1376
1377#[instability::unstable]
1378impl crate::interrupt::InterruptConfigurable for Uart<'_, Blocking> {
1379 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1380 self.tx.uart.info().set_interrupt_handler(handler);
1382 }
1383}
1384
1385impl Uart<'_, Blocking> {
1386 #[cfg_attr(
1387 not(multi_core),
1388 doc = "Registers an interrupt handler for the peripheral."
1389 )]
1390 #[cfg_attr(
1391 multi_core,
1392 doc = "Registers an interrupt handler for the peripheral on the current core."
1393 )]
1394 #[doc = ""]
1395 #[instability::unstable]
1401 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1402 self.tx.uart.info().set_interrupt_handler(handler);
1404 }
1405
1406 #[doc = crate::before_snippet!()]
1415 #[instability::unstable]
1472 pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1473 self.tx.uart.info().enable_listen(interrupts.into(), true)
1474 }
1475
1476 #[instability::unstable]
1478 pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1479 self.tx.uart.info().enable_listen(interrupts.into(), false)
1480 }
1481
1482 #[instability::unstable]
1484 pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1485 self.tx.uart.info().interrupts()
1486 }
1487
1488 #[instability::unstable]
1490 pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1491 self.tx.uart.info().clear_interrupts(interrupts)
1492 }
1493}
1494
1495#[instability::unstable]
1496impl<Dm> ufmt_write::uWrite for Uart<'_, Dm>
1497where
1498 Dm: DriverMode,
1499{
1500 type Error = TxError;
1501
1502 #[inline]
1503 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1504 self.tx.write_str(s)
1505 }
1506
1507 #[inline]
1508 fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
1509 self.tx.write_char(ch)
1510 }
1511}
1512
1513#[instability::unstable]
1514impl<Dm> ufmt_write::uWrite for UartTx<'_, Dm>
1515where
1516 Dm: DriverMode,
1517{
1518 type Error = TxError;
1519
1520 #[inline]
1521 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1522 self.write(s.as_bytes())?;
1523 Ok(())
1524 }
1525}
1526
1527impl<Dm> core::fmt::Write for Uart<'_, Dm>
1528where
1529 Dm: DriverMode,
1530{
1531 #[inline]
1532 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1533 self.tx.write_str(s)
1534 }
1535}
1536
1537impl<Dm> core::fmt::Write for UartTx<'_, Dm>
1538where
1539 Dm: DriverMode,
1540{
1541 #[inline]
1542 fn write_str(&mut self, s: &str) -> core::fmt::Result {
1543 self.write(s.as_bytes()).map_err(|_| core::fmt::Error)?;
1544 Ok(())
1545 }
1546}
1547
1548#[instability::unstable]
1550#[derive(Debug, Clone, Copy, PartialEq)]
1551#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1552#[non_exhaustive]
1553pub enum IoError {
1554 Tx(TxError),
1556 Rx(RxError),
1558}
1559
1560#[instability::unstable]
1561impl core::error::Error for IoError {}
1562
1563#[instability::unstable]
1564impl core::fmt::Display for IoError {
1565 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1566 match self {
1567 IoError::Tx(e) => e.fmt(f),
1568 IoError::Rx(e) => e.fmt(f),
1569 }
1570 }
1571}
1572
1573#[instability::unstable]
1574impl embedded_io::Error for IoError {
1575 fn kind(&self) -> embedded_io::ErrorKind {
1576 embedded_io::ErrorKind::Other
1577 }
1578}
1579
1580#[instability::unstable]
1581impl From<RxError> for IoError {
1582 fn from(e: RxError) -> Self {
1583 IoError::Rx(e)
1584 }
1585}
1586
1587#[instability::unstable]
1588impl From<TxError> for IoError {
1589 fn from(e: TxError) -> Self {
1590 IoError::Tx(e)
1591 }
1592}
1593
1594#[instability::unstable]
1595impl<Dm: DriverMode> embedded_io::ErrorType for Uart<'_, Dm> {
1596 type Error = IoError;
1597}
1598
1599#[instability::unstable]
1600impl<Dm: DriverMode> embedded_io::ErrorType for UartTx<'_, Dm> {
1601 type Error = TxError;
1602}
1603
1604#[instability::unstable]
1605impl<Dm: DriverMode> embedded_io::ErrorType for UartRx<'_, Dm> {
1606 type Error = RxError;
1607}
1608
1609#[instability::unstable]
1610impl<Dm> embedded_io::Read for Uart<'_, Dm>
1611where
1612 Dm: DriverMode,
1613{
1614 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
1615 self.rx.read(buf).map_err(IoError::Rx)
1616 }
1617}
1618
1619#[instability::unstable]
1620impl<Dm> embedded_io::Read for UartRx<'_, Dm>
1621where
1622 Dm: DriverMode,
1623{
1624 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
1625 self.read(buf)
1626 }
1627}
1628
1629#[instability::unstable]
1630impl<Dm> embedded_io::ReadReady for Uart<'_, Dm>
1631where
1632 Dm: DriverMode,
1633{
1634 fn read_ready(&mut self) -> Result<bool, Self::Error> {
1635 self.rx.read_ready().map_err(IoError::Rx)
1636 }
1637}
1638
1639#[instability::unstable]
1640impl<Dm> embedded_io::ReadReady for UartRx<'_, Dm>
1641where
1642 Dm: DriverMode,
1643{
1644 fn read_ready(&mut self) -> Result<bool, Self::Error> {
1645 Ok(self.rx_fifo_count() > 0)
1646 }
1647}
1648
1649#[instability::unstable]
1650impl<Dm> embedded_io::Write for Uart<'_, Dm>
1651where
1652 Dm: DriverMode,
1653{
1654 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1655 self.tx.write(buf).map_err(IoError::Tx)
1656 }
1657
1658 fn flush(&mut self) -> Result<(), Self::Error> {
1659 self.tx.flush().map_err(IoError::Tx)
1660 }
1661}
1662
1663#[instability::unstable]
1664impl<Dm> embedded_io::Write for UartTx<'_, Dm>
1665where
1666 Dm: DriverMode,
1667{
1668 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1669 self.write(buf)
1670 }
1671
1672 fn flush(&mut self) -> Result<(), Self::Error> {
1673 self.flush()
1674 }
1675}
1676
1677#[derive(Debug, EnumSetType)]
1678pub(crate) enum TxEvent {
1679 Done,
1680 FiFoEmpty,
1681}
1682
1683#[derive(Debug, EnumSetType)]
1684pub(crate) enum RxEvent {
1685 FifoFull,
1686 CmdCharDetected,
1687 FifoOvf,
1688 FifoTout,
1689 GlitchDetected,
1690 FrameError,
1691 ParityError,
1692}
1693
1694fn rx_event_check_for_error(events: EnumSet<RxEvent>) -> Result<(), RxError> {
1695 for event in events {
1696 match event {
1697 RxEvent::FifoOvf => return Err(RxError::FifoOverflowed),
1698 RxEvent::GlitchDetected => return Err(RxError::GlitchOccurred),
1699 RxEvent::FrameError => return Err(RxError::FrameFormatViolated),
1700 RxEvent::ParityError => return Err(RxError::ParityMismatch),
1701 RxEvent::FifoFull | RxEvent::CmdCharDetected | RxEvent::FifoTout => continue,
1702 }
1703 }
1704
1705 Ok(())
1706}
1707
1708#[must_use = "futures do nothing unless you `.await` or poll them"]
1714struct UartRxFuture {
1715 events: EnumSet<RxEvent>,
1716 uart: &'static Info,
1717 state: &'static State,
1718 registered: bool,
1719}
1720
1721impl UartRxFuture {
1722 fn new(uart: impl Peripheral<P = impl Instance>, events: impl Into<EnumSet<RxEvent>>) -> Self {
1723 crate::into_ref!(uart);
1724 Self {
1725 events: events.into(),
1726 uart: uart.info(),
1727 state: uart.state(),
1728 registered: false,
1729 }
1730 }
1731}
1732
1733impl core::future::Future for UartRxFuture {
1734 type Output = EnumSet<RxEvent>;
1735
1736 fn poll(
1737 mut self: core::pin::Pin<&mut Self>,
1738 cx: &mut core::task::Context<'_>,
1739 ) -> core::task::Poll<Self::Output> {
1740 let events = self.uart.rx_events().intersection(self.events);
1741 if !events.is_empty() {
1742 self.uart.clear_rx_events(events);
1743 Poll::Ready(events)
1744 } else {
1745 self.state.rx_waker.register(cx.waker());
1746 if !self.registered {
1747 self.uart.enable_listen_rx(self.events, true);
1748 self.registered = true;
1749 }
1750 Poll::Pending
1751 }
1752 }
1753}
1754
1755impl Drop for UartRxFuture {
1756 fn drop(&mut self) {
1757 self.uart.enable_listen_rx(self.events, false);
1761 }
1762}
1763
1764#[must_use = "futures do nothing unless you `.await` or poll them"]
1765struct UartTxFuture {
1766 events: EnumSet<TxEvent>,
1767 uart: &'static Info,
1768 state: &'static State,
1769 registered: bool,
1770}
1771
1772impl UartTxFuture {
1773 fn new(uart: impl Peripheral<P = impl Instance>, events: impl Into<EnumSet<TxEvent>>) -> Self {
1774 crate::into_ref!(uart);
1775 Self {
1776 events: events.into(),
1777 uart: uart.info(),
1778 state: uart.state(),
1779 registered: false,
1780 }
1781 }
1782}
1783
1784impl core::future::Future for UartTxFuture {
1785 type Output = ();
1786
1787 fn poll(
1788 mut self: core::pin::Pin<&mut Self>,
1789 cx: &mut core::task::Context<'_>,
1790 ) -> core::task::Poll<Self::Output> {
1791 let events = self.uart.tx_events().intersection(self.events);
1792 if !events.is_empty() {
1793 self.uart.clear_tx_events(events);
1794 Poll::Ready(())
1795 } else {
1796 self.state.tx_waker.register(cx.waker());
1797 if !self.registered {
1798 self.uart.enable_listen_tx(self.events, true);
1799 self.registered = true;
1800 }
1801 Poll::Pending
1802 }
1803 }
1804}
1805
1806impl Drop for UartTxFuture {
1807 fn drop(&mut self) {
1808 self.uart.enable_listen_tx(self.events, false);
1812 }
1813}
1814
1815impl Uart<'_, Async> {
1816 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1835 self.rx.read_async(buf).await
1836 }
1837
1838 #[instability::unstable]
1853 pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1854 self.rx.read_exact_async(buf).await
1855 }
1856
1857 pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1873 self.tx.write_async(words).await
1874 }
1875
1876 pub async fn flush_async(&mut self) -> Result<(), TxError> {
1886 self.tx.flush_async().await
1887 }
1888}
1889
1890impl UartTx<'_, Async> {
1891 pub async fn write_async(&mut self, bytes: &[u8]) -> Result<usize, TxError> {
1907 let space = loop {
1910 let space = Info::UART_FIFO_SIZE - self.tx_fifo_count();
1911 if space != 0 {
1912 break space;
1913 }
1914 UartTxFuture::new(self.uart.reborrow(), TxEvent::FiFoEmpty).await;
1915 };
1916
1917 let free = (space as usize).min(bytes.len());
1918
1919 for &byte in &bytes[..free] {
1920 self.regs()
1921 .fifo()
1922 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
1923 }
1924
1925 Ok(free)
1926 }
1927
1928 pub async fn flush_async(&mut self) -> Result<(), TxError> {
1938 if self.tx_fifo_count() > 0 {
1939 UartTxFuture::new(self.uart.reborrow(), TxEvent::Done).await;
1940 }
1941
1942 Ok(())
1943 }
1944}
1945
1946impl UartRx<'_, Async> {
1947 async fn wait_for_buffered_data(
1948 &mut self,
1949 minimum: usize,
1950 preferred: usize,
1951 listen_for_timeout: bool,
1952 ) -> Result<(), RxError> {
1953 while self.rx_fifo_count() < (minimum as u16).min(Info::RX_FIFO_MAX_THRHD) {
1954 let amount = u16::try_from(preferred)
1955 .unwrap_or(Info::RX_FIFO_MAX_THRHD)
1956 .min(Info::RX_FIFO_MAX_THRHD);
1957
1958 let current = self.uart.info().rx_fifo_full_threshold();
1959 let _guard = if current > amount {
1960 let info = self.uart.info();
1964 unwrap!(info.set_rx_fifo_full_threshold(amount));
1965 Some(OnDrop::new(|| {
1966 unwrap!(info.set_rx_fifo_full_threshold(current));
1967 }))
1968 } else {
1969 None
1970 };
1971
1972 let mut events = RxEvent::FifoFull
1974 | RxEvent::FifoOvf
1975 | RxEvent::FrameError
1976 | RxEvent::GlitchDetected
1977 | RxEvent::ParityError;
1978
1979 if self.regs().at_cmd_char().read().char_num().bits() > 0 {
1980 events |= RxEvent::CmdCharDetected;
1981 }
1982
1983 cfg_if::cfg_if! {
1984 if #[cfg(any(esp32c6, esp32h2))] {
1985 let reg_en = self.regs().tout_conf();
1986 } else {
1987 let reg_en = self.regs().conf1();
1988 }
1989 };
1990 if listen_for_timeout && reg_en.read().rx_tout_en().bit_is_set() {
1991 events |= RxEvent::FifoTout;
1992 }
1993
1994 let event = UartRxFuture::new(self.uart.reborrow(), events).await;
1995 rx_event_check_for_error(event)?;
1996 }
1997
1998 Ok(())
1999 }
2000
2001 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
2020 if buf.is_empty() {
2021 return Ok(0);
2022 }
2023
2024 self.wait_for_buffered_data(1, buf.len(), true).await?;
2025
2026 self.read_buffered(buf)
2027 }
2028
2029 pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
2044 while !buf.is_empty() {
2045 self.wait_for_buffered_data(buf.len(), buf.len(), false)
2049 .await?;
2050
2051 let read = self.read_buffered(buf)?;
2052 buf = &mut buf[read..];
2053 }
2054
2055 Ok(())
2056 }
2057}
2058
2059#[instability::unstable]
2060impl embedded_io_async::Read for Uart<'_, Async> {
2061 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2062 self.read_async(buf).await.map_err(IoError::Rx)
2063 }
2064
2065 async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError<Self::Error>> {
2066 self.read_exact_async(buf)
2067 .await
2068 .map_err(|e| ReadExactError::Other(IoError::Rx(e)))
2069 }
2070}
2071
2072#[instability::unstable]
2073impl embedded_io_async::Read for UartRx<'_, Async> {
2074 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2075 self.read_async(buf).await
2076 }
2077
2078 async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError<Self::Error>> {
2079 self.read_exact_async(buf)
2080 .await
2081 .map_err(ReadExactError::Other)
2082 }
2083}
2084
2085#[instability::unstable]
2086impl embedded_io_async::Write for Uart<'_, Async> {
2087 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2088 self.write_async(buf).await.map_err(IoError::Tx)
2089 }
2090
2091 async fn flush(&mut self) -> Result<(), Self::Error> {
2092 self.flush_async().await.map_err(IoError::Tx)
2093 }
2094}
2095
2096#[instability::unstable]
2097impl embedded_io_async::Write for UartTx<'_, Async> {
2098 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2099 self.write_async(buf).await
2100 }
2101
2102 async fn flush(&mut self) -> Result<(), Self::Error> {
2103 self.flush_async().await
2104 }
2105}
2106
2107pub(super) fn intr_handler(uart: &Info, state: &State) {
2112 let interrupts = uart.regs().int_st().read();
2113 let interrupt_bits = interrupts.bits(); let rx_wake = interrupts.rxfifo_full().bit_is_set()
2115 | interrupts.rxfifo_ovf().bit_is_set()
2116 | interrupts.rxfifo_tout().bit_is_set()
2117 | interrupts.at_cmd_char_det().bit_is_set()
2118 | interrupts.glitch_det().bit_is_set()
2119 | interrupts.frm_err().bit_is_set()
2120 | interrupts.parity_err().bit_is_set();
2121 let tx_wake = interrupts.tx_done().bit_is_set() | interrupts.txfifo_empty().bit_is_set();
2122
2123 uart.regs()
2124 .int_ena()
2125 .modify(|r, w| unsafe { w.bits(r.bits() & !interrupt_bits) });
2126
2127 if tx_wake {
2128 state.tx_waker.wake();
2129 }
2130 if rx_wake {
2131 state.rx_waker.wake();
2132 }
2133}
2134
2135#[cfg(lp_uart)]
2137#[instability::unstable]
2138pub mod lp_uart {
2139 use crate::{
2140 gpio::lp_io::{LowPowerInput, LowPowerOutput},
2141 peripherals::{LPWR, LP_AON, LP_IO, LP_UART},
2142 uart::{Config, DataBits, Parity, StopBits},
2143 };
2144 pub struct LpUart {
2148 uart: LP_UART,
2149 }
2150
2151 impl LpUart {
2152 pub fn new(
2161 uart: LP_UART,
2162 config: Config,
2163 _tx: LowPowerOutput<'_, 5>,
2164 _rx: LowPowerInput<'_, 4>,
2165 ) -> Self {
2166 LP_AON::regs()
2168 .gpio_mux()
2169 .modify(|r, w| unsafe { w.sel().bits(r.sel().bits() | (1 << 4) | (1 << 5)) });
2170
2171 LP_IO::regs()
2172 .gpio(4)
2173 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2174 LP_IO::regs()
2175 .gpio(5)
2176 .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2177
2178 let mut me = Self { uart };
2179 let uart = me.uart.register_block();
2180
2181 uart.conf0().modify(|_, w| unsafe {
2187 w.parity().clear_bit();
2188 w.parity_en().clear_bit();
2189 w.bit_num().bits(0x3);
2190 w.stop_bit_num().bits(0x1)
2191 });
2192 uart.idle_conf()
2194 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2195 uart.hwfc_conf().modify(|_, w| w.rx_flow_en().clear_bit());
2197
2198 LPWR::regs()
2203 .lpperi()
2204 .modify(|_, w| w.lp_uart_clk_sel().clear_bit());
2205
2206 me.change_baud_internal(&config);
2209 me.change_parity(config.parity);
2211 me.change_data_bits(config.data_bits);
2213 me.change_stop_bits(config.stop_bits);
2215 me.change_tx_idle(0); me.rxfifo_reset();
2220 me.txfifo_reset();
2221
2222 me
2223 }
2224
2225 fn rxfifo_reset(&mut self) {
2226 self.uart
2227 .register_block()
2228 .conf0()
2229 .modify(|_, w| w.rxfifo_rst().set_bit());
2230 self.update();
2231
2232 self.uart
2233 .register_block()
2234 .conf0()
2235 .modify(|_, w| w.rxfifo_rst().clear_bit());
2236 self.update();
2237 }
2238
2239 fn txfifo_reset(&mut self) {
2240 self.uart
2241 .register_block()
2242 .conf0()
2243 .modify(|_, w| w.txfifo_rst().set_bit());
2244 self.update();
2245
2246 self.uart
2247 .register_block()
2248 .conf0()
2249 .modify(|_, w| w.txfifo_rst().clear_bit());
2250 self.update();
2251 }
2252
2253 fn update(&mut self) {
2254 let register_block = self.uart.register_block();
2255 register_block
2256 .reg_update()
2257 .modify(|_, w| w.reg_update().set_bit());
2258 while register_block.reg_update().read().reg_update().bit_is_set() {
2259 }
2261 }
2262
2263 fn change_baud_internal(&mut self, config: &Config) {
2264 let clk = 16_000_000_u32;
2266 let max_div = 0b1111_1111_1111 - 1;
2267 let clk_div = clk.div_ceil(max_div * config.baudrate);
2268
2269 self.uart.register_block().clk_conf().modify(|_, w| unsafe {
2270 w.sclk_div_a().bits(0);
2271 w.sclk_div_b().bits(0);
2272 w.sclk_div_num().bits(clk_div as u8 - 1);
2273 w.sclk_sel().bits(match config.clock_source {
2274 super::ClockSource::Xtal => 3,
2275 super::ClockSource::RcFast => 2,
2276 super::ClockSource::Apb => panic!("Wrong clock source for LP_UART"),
2277 });
2278 w.sclk_en().set_bit()
2279 });
2280
2281 let clk = clk / clk_div;
2282 let divider = clk / config.baudrate;
2283 let divider = divider as u16;
2284
2285 self.uart
2286 .register_block()
2287 .clkdiv()
2288 .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) });
2289
2290 self.update();
2291 }
2292
2293 pub fn change_baud(&mut self, config: &Config) {
2301 self.change_baud_internal(config);
2302 self.txfifo_reset();
2303 self.rxfifo_reset();
2304 }
2305
2306 fn change_parity(&mut self, parity: Parity) -> &mut Self {
2307 if parity != Parity::None {
2308 self.uart
2309 .register_block()
2310 .conf0()
2311 .modify(|_, w| w.parity().bit((parity as u8 & 0x1) != 0));
2312 }
2313
2314 self.uart
2315 .register_block()
2316 .conf0()
2317 .modify(|_, w| match parity {
2318 Parity::None => w.parity_en().clear_bit(),
2319 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2320 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2321 });
2322
2323 self
2324 }
2325
2326 fn change_data_bits(&mut self, data_bits: DataBits) -> &mut Self {
2327 self.uart
2328 .register_block()
2329 .conf0()
2330 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2331
2332 self.update();
2333 self
2334 }
2335
2336 fn change_stop_bits(&mut self, stop_bits: StopBits) -> &mut Self {
2337 self.uart
2338 .register_block()
2339 .conf0()
2340 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2341
2342 self.update();
2343 self
2344 }
2345
2346 fn change_tx_idle(&mut self, idle_num: u16) -> &mut Self {
2347 self.uart
2348 .register_block()
2349 .idle_conf()
2350 .modify(|_, w| unsafe { w.tx_idle_num().bits(idle_num) });
2351
2352 self.update();
2353 self
2354 }
2355 }
2356}
2357
2358#[doc(hidden)]
2360pub trait Instance: Peripheral<P = Self> + Into<AnyUart> + 'static {
2361 fn parts(&self) -> (&'static Info, &'static State);
2363
2364 #[inline(always)]
2366 fn info(&self) -> &'static Info {
2367 self.parts().0
2368 }
2369
2370 #[inline(always)]
2372 fn state(&self) -> &'static State {
2373 self.parts().1
2374 }
2375}
2376
2377#[doc(hidden)]
2379#[non_exhaustive]
2380pub struct Info {
2381 pub register_block: *const RegisterBlock,
2385
2386 pub peripheral: crate::system::Peripheral,
2388
2389 pub async_handler: InterruptHandler,
2391
2392 pub interrupt: Interrupt,
2394
2395 pub tx_signal: OutputSignal,
2397
2398 pub rx_signal: InputSignal,
2400
2401 pub cts_signal: InputSignal,
2403
2404 pub rts_signal: OutputSignal,
2406}
2407
2408#[doc(hidden)]
2410#[non_exhaustive]
2411pub struct State {
2412 pub rx_waker: AtomicWaker,
2414
2415 pub tx_waker: AtomicWaker,
2417
2418 pub is_rx_async: AtomicBool,
2420
2421 pub is_tx_async: AtomicBool,
2423}
2424
2425impl Info {
2426 const UART_FIFO_SIZE: u16 = 128;
2429 const RX_FIFO_MAX_THRHD: u16 = 127;
2430 const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
2431
2432 pub fn regs(&self) -> &RegisterBlock {
2434 unsafe { &*self.register_block }
2435 }
2436
2437 fn enable_listen(&self, interrupts: EnumSet<UartInterrupt>, enable: bool) {
2439 let reg_block = self.regs();
2440
2441 reg_block.int_ena().modify(|_, w| {
2442 for interrupt in interrupts {
2443 match interrupt {
2444 UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable),
2445 UartInterrupt::TxDone => w.tx_done().bit(enable),
2446 UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable),
2447 };
2448 }
2449 w
2450 });
2451 }
2452
2453 fn interrupts(&self) -> EnumSet<UartInterrupt> {
2454 let mut res = EnumSet::new();
2455 let reg_block = self.regs();
2456
2457 let ints = reg_block.int_raw().read();
2458
2459 if ints.at_cmd_char_det().bit_is_set() {
2460 res.insert(UartInterrupt::AtCmd);
2461 }
2462 if ints.tx_done().bit_is_set() {
2463 res.insert(UartInterrupt::TxDone);
2464 }
2465 if ints.rxfifo_full().bit_is_set() {
2466 res.insert(UartInterrupt::RxFifoFull);
2467 }
2468
2469 res
2470 }
2471
2472 fn clear_interrupts(&self, interrupts: EnumSet<UartInterrupt>) {
2473 let reg_block = self.regs();
2474
2475 reg_block.int_clr().write(|w| {
2476 for interrupt in interrupts {
2477 match interrupt {
2478 UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(),
2479 UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
2480 UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(),
2481 };
2482 }
2483 w
2484 });
2485 }
2486
2487 fn set_interrupt_handler(&self, handler: InterruptHandler) {
2488 for core in crate::system::Cpu::other() {
2489 crate::interrupt::disable(core, self.interrupt);
2490 }
2491 self.enable_listen(EnumSet::all(), false);
2492 self.clear_interrupts(EnumSet::all());
2493 unsafe { crate::interrupt::bind_interrupt(self.interrupt, handler.handler()) };
2494 unwrap!(crate::interrupt::enable(self.interrupt, handler.priority()));
2495 }
2496
2497 fn disable_interrupts(&self) {
2498 crate::interrupt::disable(crate::system::Cpu::current(), self.interrupt);
2499 }
2500
2501 fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
2502 config.validate()?;
2503 self.change_baud(config)?;
2504 self.change_data_bits(config.data_bits);
2505 self.change_parity(config.parity);
2506 self.change_stop_bits(config.stop_bits);
2507
2508 Ok(())
2509 }
2510
2511 fn enable_listen_tx(&self, events: EnumSet<TxEvent>, enable: bool) {
2512 self.regs().int_ena().modify(|_, w| {
2513 for event in events {
2514 match event {
2515 TxEvent::Done => w.tx_done().bit(enable),
2516 TxEvent::FiFoEmpty => w.txfifo_empty().bit(enable),
2517 };
2518 }
2519 w
2520 });
2521 }
2522
2523 fn tx_events(&self) -> EnumSet<TxEvent> {
2524 let pending_interrupts = self.regs().int_raw().read();
2525 let mut active_events = EnumSet::new();
2526
2527 if pending_interrupts.tx_done().bit_is_set() {
2528 active_events |= TxEvent::Done;
2529 }
2530 if pending_interrupts.txfifo_empty().bit_is_set() {
2531 active_events |= TxEvent::FiFoEmpty;
2532 }
2533
2534 active_events
2535 }
2536
2537 fn clear_tx_events(&self, events: impl Into<EnumSet<TxEvent>>) {
2538 let events = events.into();
2539 self.regs().int_clr().write(|w| {
2540 for event in events {
2541 match event {
2542 TxEvent::FiFoEmpty => w.txfifo_empty().clear_bit_by_one(),
2543 TxEvent::Done => w.tx_done().clear_bit_by_one(),
2544 };
2545 }
2546 w
2547 });
2548 }
2549
2550 fn enable_listen_rx(&self, events: EnumSet<RxEvent>, enable: bool) {
2551 self.regs().int_ena().modify(|_, w| {
2552 for event in events {
2553 match event {
2554 RxEvent::FifoFull => w.rxfifo_full().bit(enable),
2555 RxEvent::CmdCharDetected => w.at_cmd_char_det().bit(enable),
2556
2557 RxEvent::FifoOvf => w.rxfifo_ovf().bit(enable),
2558 RxEvent::FifoTout => w.rxfifo_tout().bit(enable),
2559 RxEvent::GlitchDetected => w.glitch_det().bit(enable),
2560 RxEvent::FrameError => w.frm_err().bit(enable),
2561 RxEvent::ParityError => w.parity_err().bit(enable),
2562 };
2563 }
2564 w
2565 });
2566 }
2567
2568 fn rx_events(&self) -> EnumSet<RxEvent> {
2569 let pending_interrupts = self.regs().int_raw().read();
2570 let mut active_events = EnumSet::new();
2571
2572 if pending_interrupts.rxfifo_full().bit_is_set() {
2573 active_events |= RxEvent::FifoFull;
2574 }
2575 if pending_interrupts.at_cmd_char_det().bit_is_set() {
2576 active_events |= RxEvent::CmdCharDetected;
2577 }
2578 if pending_interrupts.rxfifo_ovf().bit_is_set() {
2579 active_events |= RxEvent::FifoOvf;
2580 }
2581 if pending_interrupts.rxfifo_tout().bit_is_set() {
2582 active_events |= RxEvent::FifoTout;
2583 }
2584 if pending_interrupts.glitch_det().bit_is_set() {
2585 active_events |= RxEvent::GlitchDetected;
2586 }
2587 if pending_interrupts.frm_err().bit_is_set() {
2588 active_events |= RxEvent::FrameError;
2589 }
2590 if pending_interrupts.parity_err().bit_is_set() {
2591 active_events |= RxEvent::ParityError;
2592 }
2593
2594 active_events
2595 }
2596
2597 fn clear_rx_events(&self, events: impl Into<EnumSet<RxEvent>>) {
2598 let events = events.into();
2599 self.regs().int_clr().write(|w| {
2600 for event in events {
2601 match event {
2602 RxEvent::FifoFull => w.rxfifo_full().clear_bit_by_one(),
2603 RxEvent::CmdCharDetected => w.at_cmd_char_det().clear_bit_by_one(),
2604
2605 RxEvent::FifoOvf => w.rxfifo_ovf().clear_bit_by_one(),
2606 RxEvent::FifoTout => w.rxfifo_tout().clear_bit_by_one(),
2607 RxEvent::GlitchDetected => w.glitch_det().clear_bit_by_one(),
2608 RxEvent::FrameError => w.frm_err().clear_bit_by_one(),
2609 RxEvent::ParityError => w.parity_err().clear_bit_by_one(),
2610 };
2611 }
2612 w
2613 });
2614 }
2615
2616 fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
2623 if threshold > Self::RX_FIFO_MAX_THRHD {
2624 return Err(ConfigError::UnsupportedRxFifoThreshold);
2625 }
2626
2627 self.regs()
2628 .conf1()
2629 .modify(|_, w| unsafe { w.rxfifo_full_thrhd().bits(threshold as _) });
2630
2631 Ok(())
2632 }
2633
2634 #[allow(clippy::useless_conversion)]
2636 fn rx_fifo_full_threshold(&self) -> u16 {
2637 self.regs().conf1().read().rxfifo_full_thrhd().bits().into()
2638 }
2639
2640 fn set_tx_fifo_empty_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
2647 if threshold > Self::TX_FIFO_MAX_THRHD {
2648 return Err(ConfigError::UnsupportedTxFifoThreshold);
2649 }
2650
2651 self.regs()
2652 .conf1()
2653 .modify(|_, w| unsafe { w.txfifo_empty_thrhd().bits(threshold as _) });
2654
2655 Ok(())
2656 }
2657
2658 fn set_rx_timeout(&self, timeout: Option<u8>, _symbol_len: u8) -> Result<(), ConfigError> {
2673 cfg_if::cfg_if! {
2674 if #[cfg(esp32)] {
2675 const MAX_THRHD: u8 = 0x7F; } else {
2677 const MAX_THRHD: u16 = 0x3FF; }
2679 }
2680
2681 let register_block = self.regs();
2682
2683 if let Some(timeout) = timeout {
2684 #[cfg(esp32)]
2686 let timeout_reg = timeout;
2687 #[cfg(not(esp32))]
2689 let timeout_reg = timeout as u16 * _symbol_len as u16;
2690
2691 if timeout_reg > MAX_THRHD {
2692 return Err(ConfigError::UnsupportedTimeout);
2693 }
2694
2695 cfg_if::cfg_if! {
2696 if #[cfg(esp32)] {
2697 let reg_thrhd = register_block.conf1();
2698 } else if #[cfg(any(esp32c6, esp32h2))] {
2699 let reg_thrhd = register_block.tout_conf();
2700 } else {
2701 let reg_thrhd = register_block.mem_conf();
2702 }
2703 }
2704 reg_thrhd.modify(|_, w| unsafe { w.rx_tout_thrhd().bits(timeout_reg) });
2705 }
2706
2707 cfg_if::cfg_if! {
2708 if #[cfg(any(esp32c6, esp32h2))] {
2709 let reg_en = register_block.tout_conf();
2710 } else {
2711 let reg_en = register_block.conf1();
2712 }
2713 }
2714 reg_en.modify(|_, w| w.rx_tout_en().bit(timeout.is_some()));
2715
2716 self.sync_regs();
2717
2718 Ok(())
2719 }
2720
2721 fn is_instance(&self, other: impl Instance) -> bool {
2722 self == other.info()
2723 }
2724
2725 fn sync_regs(&self) {
2726 sync_regs(self.regs());
2727 }
2728
2729 fn change_baud(&self, config: &Config) -> Result<(), ConfigError> {
2730 let clocks = Clocks::get();
2731 let clk = match config.clock_source {
2732 ClockSource::Apb => clocks.apb_clock.as_hz(),
2733 #[cfg(not(any(esp32, esp32s2)))]
2734 ClockSource::Xtal => clocks.xtal_clock.as_hz(),
2735 #[cfg(not(any(esp32, esp32s2)))]
2736 ClockSource::RcFast => crate::soc::constants::RC_FAST_CLK.as_hz(),
2737 #[cfg(any(esp32, esp32s2))]
2738 ClockSource::RefTick => crate::soc::constants::REF_TICK.as_hz(),
2739 };
2740
2741 cfg_if::cfg_if! {
2742 if #[cfg(any(esp32c2, esp32c3, esp32s3, esp32c6, esp32h2))] {
2743
2744 const MAX_DIV: u32 = 0b1111_1111_1111 - 1;
2745 let clk_div = (clk.div_ceil(MAX_DIV)).div_ceil(config.baudrate);
2746
2747 cfg_if::cfg_if! {
2749 if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
2750 if matches!(config.clock_source, ClockSource::RcFast) {
2751 crate::peripherals::LPWR::regs()
2752 .clk_conf()
2753 .modify(|_, w| w.dig_clk8m_en().variant(true));
2754 crate::rom::ets_delay_us(5);
2756 }
2757
2758 let conf = self.regs().clk_conf();
2759 } else {
2760 let pcr = crate::peripherals::PCR::regs();
2762 let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
2763 pcr.uart(0).clk_conf()
2764 } else {
2765 pcr.uart(1).clk_conf()
2766 };
2767 }
2768 };
2769
2770 conf.write(|w| unsafe {
2771 w.sclk_sel().bits(match config.clock_source {
2772 ClockSource::Apb => 1,
2773 ClockSource::RcFast => 2,
2774 ClockSource::Xtal => 3,
2775 });
2776 w.sclk_div_a().bits(0);
2777 w.sclk_div_b().bits(0);
2778 w.sclk_div_num().bits(clk_div as u8 - 1)
2779 });
2780
2781 let divider = (clk << 4) / (config.baudrate * clk_div);
2782 } else {
2783 self.regs().conf0().modify(|_, w| {
2784 w.tick_ref_always_on()
2785 .bit(config.clock_source == ClockSource::Apb)
2786 });
2787
2788 let divider = (clk << 4) / config.baudrate;
2789 }
2790 }
2791
2792 let divider_integer = divider >> 4;
2793 let divider_frag = (divider & 0xf) as u8;
2794
2795 self.regs().clkdiv().write(|w| unsafe {
2796 w.clkdiv()
2797 .bits(divider_integer as _)
2798 .frag()
2799 .bits(divider_frag)
2800 });
2801
2802 self.sync_regs();
2803
2804 #[cfg(feature = "unstable")]
2805 self.verify_baudrate(clk, config)?;
2806
2807 Ok(())
2808 }
2809
2810 fn change_data_bits(&self, data_bits: DataBits) {
2811 self.regs()
2812 .conf0()
2813 .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2814 }
2815
2816 fn change_parity(&self, parity: Parity) {
2817 self.regs().conf0().modify(|_, w| match parity {
2818 Parity::None => w.parity_en().clear_bit(),
2819 Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2820 Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2821 });
2822 }
2823
2824 fn change_stop_bits(&self, stop_bits: StopBits) {
2825 #[cfg(esp32)]
2826 {
2827 if stop_bits == StopBits::_2 {
2829 self.regs()
2830 .rs485_conf()
2831 .modify(|_, w| w.dl1_en().bit(stop_bits == StopBits::_2));
2832
2833 self.regs()
2834 .conf0()
2835 .modify(|_, w| unsafe { w.stop_bit_num().bits(1) });
2836 }
2837 }
2838
2839 #[cfg(not(esp32))]
2840 self.regs()
2841 .conf0()
2842 .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2843 }
2844
2845 fn rxfifo_reset(&self) {
2846 fn rxfifo_rst(reg_block: &RegisterBlock, enable: bool) {
2847 reg_block.conf0().modify(|_, w| w.rxfifo_rst().bit(enable));
2848 sync_regs(reg_block);
2849 }
2850
2851 rxfifo_rst(self.regs(), true);
2852 rxfifo_rst(self.regs(), false);
2853 }
2854
2855 fn txfifo_reset(&self) {
2856 fn txfifo_rst(reg_block: &RegisterBlock, enable: bool) {
2857 reg_block.conf0().modify(|_, w| w.txfifo_rst().bit(enable));
2858 sync_regs(reg_block);
2859 }
2860
2861 txfifo_rst(self.regs(), true);
2862 txfifo_rst(self.regs(), false);
2863 }
2864
2865 #[cfg(feature = "unstable")]
2866 fn verify_baudrate(&self, clk: u32, config: &Config) -> Result<(), ConfigError> {
2867 let clkdiv_reg = self.regs().clkdiv().read();
2870 let clkdiv_frag = clkdiv_reg.frag().bits() as u32;
2871 let clkdiv = clkdiv_reg.clkdiv().bits();
2872
2873 cfg_if::cfg_if! {
2874 if #[cfg(any(esp32, esp32s2))] {
2875 let actual_baud = (clk << 4) / ((clkdiv << 4) | clkdiv_frag);
2876 } else if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
2877 let sclk_div_num = self.regs().clk_conf().read().sclk_div_num().bits() as u32;
2878 let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
2879 } else { let pcr = crate::peripherals::PCR::regs();
2881 let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
2882 pcr.uart(0).clk_conf()
2883 } else {
2884 pcr.uart(1).clk_conf()
2885 };
2886 let sclk_div_num = conf.read().sclk_div_num().bits() as u32;
2887 let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
2888 }
2889 };
2890
2891 match config.baudrate_tolerance {
2892 BaudrateTolerance::Exact => {
2893 let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
2894 * 100)
2895 / actual_baud;
2896 if deviation > 1_u32 {
2899 return Err(ConfigError::UnachievableBaudrate);
2900 }
2901 }
2902 BaudrateTolerance::ErrorPercent(percent) => {
2903 let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
2904 * 100)
2905 / actual_baud;
2906 if deviation > percent as u32 {
2907 return Err(ConfigError::UnachievableBaudrate);
2908 }
2909 }
2910 _ => {}
2911 }
2912
2913 Ok(())
2914 }
2915
2916 fn current_symbol_length(&self) -> u8 {
2917 let conf0 = self.regs().conf0().read();
2918 let data_bits = conf0.bit_num().bits() + 5; let parity = conf0.parity_en().bit() as u8;
2920 let mut stop_bits = conf0.stop_bit_num().bits();
2921
2922 match stop_bits {
2923 1 => {
2924 #[cfg(esp32)]
2926 if self.regs().rs485_conf().read().dl1_en().bit_is_set() {
2927 stop_bits = 2;
2928 }
2929 }
2930 _ => stop_bits = 2,
2932 }
2933
2934 1 + data_bits + parity + stop_bits
2935 }
2936
2937 fn read_next_from_fifo(&self) -> u8 {
2941 fn access_fifo_register<R>(f: impl Fn() -> R) -> R {
2942 cfg_if::cfg_if! {
2944 if #[cfg(esp32)] {
2945 crate::interrupt::free(f)
2946 } else {
2947 f()
2948 }
2949 }
2950 }
2951
2952 let fifo_reg = self.regs().fifo();
2953 cfg_if::cfg_if! {
2954 if #[cfg(esp32s2)] {
2955 let fifo_reg = unsafe {
2957 &*fifo_reg.as_ptr().cast::<u8>().add(0x20C00000).cast::<crate::pac::uart0::FIFO>()
2958 };
2959 }
2960 }
2961
2962 access_fifo_register(|| fifo_reg.read().rxfifo_rd_byte().bits())
2963 }
2964}
2965
2966impl PartialEq for Info {
2967 fn eq(&self, other: &Self) -> bool {
2968 self.register_block == other.register_block
2969 }
2970}
2971
2972unsafe impl Sync for Info {}
2973
2974macro_rules! impl_instance {
2975 ($inst:ident, $peri:ident, $txd:ident, $rxd:ident, $cts:ident, $rts:ident) => {
2976 impl Instance for crate::peripherals::$inst {
2977 fn parts(&self) -> (&'static Info, &'static State) {
2978 #[crate::handler]
2979 pub(super) fn irq_handler() {
2980 intr_handler(&PERIPHERAL, &STATE);
2981 }
2982
2983 static STATE: State = State {
2984 tx_waker: AtomicWaker::new(),
2985 rx_waker: AtomicWaker::new(),
2986 is_rx_async: AtomicBool::new(false),
2987 is_tx_async: AtomicBool::new(false),
2988 };
2989
2990 static PERIPHERAL: Info = Info {
2991 register_block: crate::peripherals::$inst::ptr(),
2992 peripheral: crate::system::Peripheral::$peri,
2993 async_handler: irq_handler,
2994 interrupt: Interrupt::$inst,
2995 tx_signal: OutputSignal::$txd,
2996 rx_signal: InputSignal::$rxd,
2997 cts_signal: InputSignal::$cts,
2998 rts_signal: OutputSignal::$rts,
2999 };
3000 (&PERIPHERAL, &STATE)
3001 }
3002 }
3003 };
3004}
3005
3006impl_instance!(UART0, Uart0, U0TXD, U0RXD, U0CTS, U0RTS);
3007impl_instance!(UART1, Uart1, U1TXD, U1RXD, U1CTS, U1RTS);
3008#[cfg(uart2)]
3009impl_instance!(UART2, Uart2, U2TXD, U2RXD, U2CTS, U2RTS);
3010
3011crate::any_peripheral! {
3012 pub peripheral AnyUart {
3014 #[cfg(uart0)]
3015 Uart0(crate::peripherals::UART0),
3016 #[cfg(uart1)]
3017 Uart1(crate::peripherals::UART1),
3018 #[cfg(uart2)]
3019 Uart2(crate::peripherals::UART2),
3020 }
3021}
3022
3023impl Instance for AnyUart {
3024 #[inline]
3025 fn parts(&self) -> (&'static Info, &'static State) {
3026 match &self.0 {
3027 #[cfg(uart0)]
3028 AnyUartInner::Uart0(uart) => uart.parts(),
3029 #[cfg(uart1)]
3030 AnyUartInner::Uart1(uart) => uart.parts(),
3031 #[cfg(uart2)]
3032 AnyUartInner::Uart2(uart) => uart.parts(),
3033 }
3034 }
3035}
3036
3037struct OnDrop<F: FnOnce()>(Option<F>);
3038impl<F: FnOnce()> OnDrop<F> {
3039 fn new(cb: F) -> Self {
3040 Self(Some(cb))
3041 }
3042}
3043
3044impl<F: FnOnce()> Drop for OnDrop<F> {
3045 fn drop(&mut self) {
3046 if let Some(cb) = self.0.take() {
3047 cb();
3048 }
3049 }
3050}