@@ -486,6 +486,7 @@ where
486486 mem_guard,
487487 rts_pin,
488488 tx_pin,
489+ baudrate : config. baudrate ,
489490 } ,
490491 } ;
491492 serial. init ( config) ?;
@@ -523,6 +524,7 @@ pub struct UartTx<'d, Dm: DriverMode> {
523524 mem_guard : MemoryGuard < ' d > ,
524525 rts_pin : PinGuard ,
525526 tx_pin : PinGuard ,
527+ baudrate : u32 ,
526528}
527529
528530/// UART (Receive)
@@ -623,6 +625,7 @@ where
623625 type ConfigError = ConfigError ;
624626
625627 fn set_config ( & mut self , config : & Self :: Config ) -> Result < ( ) , Self :: ConfigError > {
628+ self . baudrate = config. baudrate ;
626629 self . apply_config ( config)
627630 }
628631}
@@ -667,6 +670,7 @@ impl<'d> UartTx<'d, Blocking> {
667670 mem_guard : self . mem_guard ,
668671 rts_pin : self . rts_pin ,
669672 tx_pin : self . tx_pin ,
673+ baudrate : self . baudrate ,
670674 }
671675 }
672676}
@@ -690,6 +694,7 @@ impl<'d> UartTx<'d, Async> {
690694 mem_guard : self . mem_guard ,
691695 rts_pin : self . rts_pin ,
692696 tx_pin : self . tx_pin ,
697+ baudrate : self . baudrate ,
693698 }
694699 }
695700
@@ -863,6 +868,44 @@ where
863868 while !self . is_tx_idle ( ) { }
864869 }
865870
871+ /// Sends a break signal for a specified duration in bit time.
872+ ///
873+ /// Duration is in bits, the time it takes to transfer one bit at the
874+ /// current baud rate. The delay during the break is just busy-waiting.
875+ #[ instability:: unstable]
876+ pub fn send_break ( & mut self , bits : u32 ) {
877+ // Read the current TX inversion state
878+ let original_conf0 = self . uart . info ( ) . regs ( ) . conf0 ( ) . read ( ) ;
879+ let original_txd_inv = original_conf0. txd_inv ( ) . bit ( ) ;
880+
881+ // Invert the TX line (toggle the current state)
882+ self . uart
883+ . info ( )
884+ . regs ( )
885+ . conf0 ( )
886+ . modify ( |_, w| w. txd_inv ( ) . bit ( !original_txd_inv) ) ;
887+
888+ #[ cfg( any( esp32c3, esp32c6, esp32h2, esp32s3) ) ]
889+ sync_regs ( self . uart . info ( ) . regs ( ) ) ;
890+
891+ // Calculate total delay in microseconds: (bits * 1_000_000) / baudrate_bps
892+ // Use u64 to avoid overflow, then convert back to u32
893+ let total_delay_us = ( bits as u64 * 1_000_000 ) / self . baudrate as u64 ;
894+ let delay_us = ( total_delay_us as u32 ) . max ( 1 ) ;
895+
896+ crate :: rom:: ets_delay_us ( delay_us) ;
897+
898+ // Restore the original register state
899+ self . uart
900+ . info ( )
901+ . regs ( )
902+ . conf0 ( )
903+ . write ( |w| unsafe { w. bits ( original_conf0. bits ( ) ) } ) ;
904+
905+ #[ cfg( any( esp32c3, esp32c6, esp32h2, esp32s3) ) ]
906+ sync_regs ( self . uart . info ( ) . regs ( ) ) ;
907+ }
908+
866909 /// Checks if the TX line is idle for this UART instance.
867910 ///
868911 /// Returns `true` if the transmit line is idle, meaning no data is
@@ -944,6 +987,50 @@ impl<'d> UartRx<'d, Blocking> {
944987 Ok ( uart_rx)
945988 }
946989
990+ /// Waits for a break condition to be detected.
991+ ///
992+ /// This is a blocking function that will continuously check for a break condition.
993+ /// After detection, the break interrupt flag is automatically cleared.
994+ #[ instability:: unstable]
995+ pub fn wait_for_break ( & mut self ) {
996+ self . enable_break_detection ( ) ;
997+
998+ while !self . regs ( ) . int_raw ( ) . read ( ) . brk_det ( ) . bit_is_set ( ) {
999+ // wait
1000+ }
1001+
1002+ self . regs ( )
1003+ . int_clr ( )
1004+ . write ( |w| w. brk_det ( ) . clear_bit_by_one ( ) ) ;
1005+ }
1006+
1007+ /// Waits for a break condition to be detected with a timeout.
1008+ ///
1009+ /// This is a blocking function that will check for a break condition up to
1010+ /// the specified timeout. Returns `true` if a break was detected, `false` if
1011+ /// the timeout elapsed. After successful detection, the break interrupt flag
1012+ /// is automatically cleared.
1013+ ///
1014+ /// ## Arguments
1015+ /// * `timeout` - Maximum time to wait for a break condition
1016+ #[ instability:: unstable]
1017+ pub fn wait_for_break_with_timeout ( & mut self , timeout : crate :: time:: Duration ) -> bool {
1018+ self . enable_break_detection ( ) ;
1019+
1020+ let start = crate :: time:: Instant :: now ( ) ;
1021+
1022+ while !self . regs ( ) . int_raw ( ) . read ( ) . brk_det ( ) . bit_is_set ( ) {
1023+ if crate :: time:: Instant :: now ( ) - start >= timeout {
1024+ return false ;
1025+ }
1026+ }
1027+
1028+ self . regs ( )
1029+ . int_clr ( )
1030+ . write ( |w| w. brk_det ( ) . clear_bit_by_one ( ) ) ;
1031+ true
1032+ }
1033+
9471034 /// Reconfigures the driver to operate in [`Async`] mode.
9481035 #[ instability:: unstable]
9491036 pub fn into_async ( self ) -> UartRx < ' d , Async > {
@@ -1099,6 +1186,19 @@ impl<'d> UartRx<'d, Async> {
10991186
11001187 Ok ( ( ) )
11011188 }
1189+
1190+ /// Waits for a break condition to be detected asynchronously.
1191+ ///
1192+ /// This is an async function that will await until a break condition is
1193+ /// detected on the RX line. After detection, the break interrupt flag is
1194+ /// automatically cleared.
1195+ #[ instability:: unstable]
1196+ pub async fn wait_for_break_async ( & mut self ) {
1197+ UartRxFuture :: new ( self . uart . reborrow ( ) , RxEvent :: BreakDetected ) . await ;
1198+ self . regs ( )
1199+ . int_clr ( )
1200+ . write ( |w| w. brk_det ( ) . clear_bit_by_one ( ) ) ;
1201+ }
11021202}
11031203
11041204impl < ' d , Dm > UartRx < ' d , Dm >
@@ -1144,6 +1244,23 @@ where
11441244 self
11451245 }
11461246
1247+ /// Enable break detection.
1248+ ///
1249+ /// This must be called before any breaks are expected to be received.
1250+ /// Break detection is enabled automatically by [`Self::wait_for_break`]
1251+ /// and [`Self::wait_for_break_with_timeout`], but calling this method
1252+ /// explicitly ensures that breaks occurring before the first wait call
1253+ /// will be reliably detected.
1254+ #[ instability:: unstable]
1255+ pub fn enable_break_detection ( & mut self ) {
1256+ self . uart
1257+ . info ( )
1258+ . enable_listen_rx ( RxEvent :: BreakDetected . into ( ) , true ) ;
1259+
1260+ #[ cfg( any( esp32c6, esp32h2) ) ]
1261+ sync_regs ( self . regs ( ) ) ;
1262+ }
1263+
11471264 /// Change the configuration.
11481265 ///
11491266 /// ## Errors
@@ -1389,6 +1506,29 @@ impl<'d> Uart<'d, Blocking> {
13891506 pub fn clear_interrupts ( & mut self , interrupts : EnumSet < UartInterrupt > ) {
13901507 self . tx . uart . info ( ) . clear_interrupts ( interrupts)
13911508 }
1509+
1510+ /// Waits for a break condition to be detected.
1511+ ///
1512+ /// This is a blocking function that will continuously check for a break condition.
1513+ /// After detection, the break interrupt flag is automatically cleared.
1514+ #[ instability:: unstable]
1515+ pub fn wait_for_break ( & mut self ) {
1516+ self . rx . wait_for_break ( )
1517+ }
1518+
1519+ /// Waits for a break condition to be detected with a timeout.
1520+ ///
1521+ /// This is a blocking function that will check for a break condition up to
1522+ /// the specified timeout. Returns `true` if a break was detected, `false` if
1523+ /// the timeout elapsed. After successful detection, the break interrupt flag
1524+ /// is automatically cleared.
1525+ ///
1526+ /// ## Arguments
1527+ /// * `timeout` - Maximum time to wait for a break condition
1528+ #[ instability:: unstable]
1529+ pub fn wait_for_break_with_timeout ( & mut self , timeout : crate :: time:: Duration ) -> bool {
1530+ self . rx . wait_for_break_with_timeout ( timeout)
1531+ }
13921532}
13931533
13941534impl < ' d > Uart < ' d , Async > {
@@ -1528,6 +1668,16 @@ impl<'d> Uart<'d, Async> {
15281668 pub async fn read_exact_async ( & mut self , buf : & mut [ u8 ] ) -> Result < ( ) , RxError > {
15291669 self . rx . read_exact_async ( buf) . await
15301670 }
1671+
1672+ /// Waits for a break condition to be detected asynchronously.
1673+ ///
1674+ /// This is an async function that will await until a break condition is
1675+ /// detected on the RX line. After detection, the break interrupt flag is
1676+ /// automatically cleared.
1677+ #[ instability:: unstable]
1678+ pub async fn wait_for_break_async ( & mut self ) {
1679+ self . rx . wait_for_break_async ( ) . await
1680+ }
15311681}
15321682
15331683/// List of exposed UART events.
@@ -1543,6 +1693,11 @@ pub enum UartInterrupt {
15431693 /// The transmitter has finished sending out all data from the FIFO.
15441694 TxDone ,
15451695
1696+ /// Break condition has been detected.
1697+ /// Triggered when the receiver detects a NULL character (i.e. logic 0 for
1698+ /// one NULL character transmission) after stop bits.
1699+ RxBreakDetected ,
1700+
15461701 /// The receiver has received more data than what
15471702 /// [`RxConfig::fifo_full_threshold`] specifies.
15481703 RxFifoFull ,
@@ -1700,6 +1855,12 @@ where
17001855 self . tx . flush ( )
17011856 }
17021857
1858+ /// Sends a break signal for a specified duration
1859+ #[ instability:: unstable]
1860+ pub fn send_break ( & mut self , bits : u32 ) {
1861+ self . tx . send_break ( bits)
1862+ }
1863+
17031864 /// Returns whether the UART buffer has data.
17041865 ///
17051866 /// If this function returns `true`, [`Self::read`] will not block.
@@ -2233,6 +2394,7 @@ pub(crate) enum RxEvent {
22332394 GlitchDetected ,
22342395 FrameError ,
22352396 ParityError ,
2397+ BreakDetected ,
22362398}
22372399
22382400fn rx_event_check_for_error ( events : EnumSet < RxEvent > ) -> Result < ( ) , RxError > {
@@ -2242,7 +2404,10 @@ fn rx_event_check_for_error(events: EnumSet<RxEvent>) -> Result<(), RxError> {
22422404 RxEvent :: GlitchDetected => return Err ( RxError :: GlitchOccurred ) ,
22432405 RxEvent :: FrameError => return Err ( RxError :: FrameFormatViolated ) ,
22442406 RxEvent :: ParityError => return Err ( RxError :: ParityMismatch ) ,
2245- RxEvent :: FifoFull | RxEvent :: CmdCharDetected | RxEvent :: FifoTout => continue ,
2407+ RxEvent :: FifoFull
2408+ | RxEvent :: CmdCharDetected
2409+ | RxEvent :: FifoTout
2410+ | RxEvent :: BreakDetected => continue ,
22462411 }
22472412 }
22482413
@@ -2804,6 +2969,7 @@ impl Info {
28042969 match interrupt {
28052970 UartInterrupt :: AtCmd => w. at_cmd_char_det ( ) . bit ( enable) ,
28062971 UartInterrupt :: TxDone => w. tx_done ( ) . bit ( enable) ,
2972+ UartInterrupt :: RxBreakDetected => w. brk_det ( ) . bit ( enable) ,
28072973 UartInterrupt :: RxFifoFull => w. rxfifo_full ( ) . bit ( enable) ,
28082974 UartInterrupt :: RxTimeout => w. rxfifo_tout ( ) . bit ( enable) ,
28092975 } ;
@@ -2824,6 +2990,9 @@ impl Info {
28242990 if ints. tx_done ( ) . bit_is_set ( ) {
28252991 res. insert ( UartInterrupt :: TxDone ) ;
28262992 }
2993+ if ints. brk_det ( ) . bit_is_set ( ) {
2994+ res. insert ( UartInterrupt :: RxBreakDetected ) ;
2995+ }
28272996 if ints. rxfifo_full ( ) . bit_is_set ( ) {
28282997 res. insert ( UartInterrupt :: RxFifoFull ) ;
28292998 }
@@ -2842,6 +3011,7 @@ impl Info {
28423011 match interrupt {
28433012 UartInterrupt :: AtCmd => w. at_cmd_char_det ( ) . clear_bit_by_one ( ) ,
28443013 UartInterrupt :: TxDone => w. tx_done ( ) . clear_bit_by_one ( ) ,
3014+ UartInterrupt :: RxBreakDetected => w. brk_det ( ) . clear_bit_by_one ( ) ,
28453015 UartInterrupt :: RxFifoFull => w. rxfifo_full ( ) . clear_bit_by_one ( ) ,
28463016 UartInterrupt :: RxTimeout => w. rxfifo_tout ( ) . clear_bit_by_one ( ) ,
28473017 } ;
@@ -2905,6 +3075,7 @@ impl Info {
29053075 for event in events {
29063076 match event {
29073077 RxEvent :: FifoFull => w. rxfifo_full ( ) . bit ( enable) ,
3078+ RxEvent :: BreakDetected => w. brk_det ( ) . bit ( enable) ,
29083079 RxEvent :: CmdCharDetected => w. at_cmd_char_det ( ) . bit ( enable) ,
29093080
29103081 RxEvent :: FifoOvf => w. rxfifo_ovf ( ) . bit ( enable) ,
@@ -2925,6 +3096,9 @@ impl Info {
29253096 if pending_interrupts. rxfifo_full ( ) . bit_is_set ( ) {
29263097 active_events |= RxEvent :: FifoFull ;
29273098 }
3099+ if pending_interrupts. brk_det ( ) . bit_is_set ( ) {
3100+ active_events |= RxEvent :: BreakDetected ;
3101+ }
29283102 if pending_interrupts. at_cmd_char_det ( ) . bit_is_set ( ) {
29293103 active_events |= RxEvent :: CmdCharDetected ;
29303104 }
@@ -2953,6 +3127,7 @@ impl Info {
29533127 for event in events {
29543128 match event {
29553129 RxEvent :: FifoFull => w. rxfifo_full ( ) . clear_bit_by_one ( ) ,
3130+ RxEvent :: BreakDetected => w. brk_det ( ) . clear_bit_by_one ( ) ,
29563131 RxEvent :: CmdCharDetected => w. at_cmd_char_det ( ) . clear_bit_by_one ( ) ,
29573132
29583133 RxEvent :: FifoOvf => w. rxfifo_ovf ( ) . clear_bit_by_one ( ) ,
0 commit comments