@@ -28,7 +28,7 @@ pub use crate::{
2828 gpio:: gpiob:: * ,
2929 gpio:: gpioc:: * ,
3030 gpio:: gpiod:: * ,
31- gpio:: gpioe:: * ,
31+ gpio:: gpioe:: * ,
3232 pac:: { LPUART1 , USART1 , USART4 , USART5 } ,
3333} ;
3434
@@ -52,11 +52,19 @@ pub enum Error {
5252
5353/// Interrupt event
5454pub enum Event {
55- /// New data has been received
55+ /// New data has been received.
56+ ///
57+ /// This event is cleared by reading a character from the UART.
5658 Rxne ,
57- /// New data can be sent
59+ /// New data can be sent.
60+ ///
61+ /// This event is cleared by writing a character to the UART.
62+ ///
63+ /// Note that this event does not mean that the character in the TX buffer
64+ /// is fully transmitted. It only means that the TX buffer is ready to take
65+ /// another character to be transmitted.
5866 Txe ,
59- /// Idle line state detected
67+ /// Idle line state detected.
6068 Idle ,
6169}
6270
@@ -181,7 +189,7 @@ impl_pins!(
181189 USART4 , PC10 , PC11 , AF6 ;
182190 USART4 , PE8 , PE9 , AF6 ;
183191 USART5 , PB3 , PB4 , AF6 ;
184- USART5 , PE10 , PE11 , AF6 ;
192+ USART5 , PE10 , PE11 , AF6 ;
185193) ;
186194
187195/// Serial abstraction
@@ -330,13 +338,47 @@ macro_rules! usart {
330338 }
331339 }
332340
333- /// Clears interrupt flag
334- pub fn clear_irq( & mut self , event: Event ) {
335- if let Event :: Rxne = event {
336- self . usart. rqr. write( |w| w. rxfrq( ) . discard( ) )
341+ /// Returns a pending and enabled `Event`.
342+ ///
343+ /// Multiple `Event`s can be signaled at the same time. In that case, an arbitrary
344+ /// pending event will be returned. Clearing the event condition will cause this
345+ /// method to return the other pending event(s).
346+ ///
347+ /// For an event to be returned by this method, it must first be enabled by calling
348+ /// `listen`.
349+ ///
350+ /// This method will never clear a pending event. If the event condition is not
351+ /// resolved by the user, it will be returned again by the next call to
352+ /// `pending_event`.
353+ pub fn pending_event( & self ) -> Option <Event > {
354+ let cr1 = self . usart. cr1. read( ) ;
355+ let isr = self . usart. isr. read( ) ;
356+
357+ if cr1. rxneie( ) . bit_is_set( ) && isr. rxne( ) . bit_is_set( ) {
358+ // Give highest priority to RXNE to help with avoiding overrun
359+ Some ( Event :: Rxne )
360+ } else if cr1. txeie( ) . bit_is_set( ) && isr. txe( ) . bit_is_set( ) {
361+ Some ( Event :: Txe )
362+ } else if cr1. idleie( ) . bit_is_set( ) && isr. idle( ) . bit_is_set( ) {
363+ Some ( Event :: Idle )
364+ } else {
365+ None
337366 }
338367 }
339368
369+ /// Checks for reception errors that may have occurred.
370+ ///
371+ /// Note that multiple errors can be signaled at the same time. In that case,
372+ /// calling this function repeatedly will return the remaining errors.
373+ pub fn check_errors( & mut self ) -> Result <( ) , Error > {
374+ self . rx. check_errors( )
375+ }
376+
377+ /// Clears any signaled errors without returning them.
378+ pub fn clear_errors( & mut self ) {
379+ self . rx. clear_errors( )
380+ }
381+
340382 pub fn split( self ) -> ( Tx <$USARTX>, Rx <$USARTX>) {
341383 ( self . tx, self . rx)
342384 }
@@ -366,7 +408,49 @@ macro_rules! usart {
366408 }
367409 }
368410
369- #[ cfg( any( feature = "stm32l0x2" , feature = "stm32l0x3" ) ) ]
411+ impl Rx <$USARTX> {
412+ /// Checks for reception errors that may have occurred.
413+ ///
414+ /// Note that multiple errors can be signaled at the same time. In that case,
415+ /// calling this function repeatedly will return the remaining errors.
416+ pub fn check_errors( & mut self ) -> Result <( ) , Error > {
417+ let isr = unsafe { ( * $USARTX:: ptr( ) ) . isr. read( ) } ;
418+ let icr = unsafe { & ( * $USARTX:: ptr( ) ) . icr } ;
419+
420+ // We don't want to drop any errors, so check each error bit in sequence. If
421+ // any bit is set, clear it and return its error.
422+ if isr. pe( ) . bit_is_set( ) {
423+ icr. write( |w| { w. pecf( ) . set_bit( ) } ) ;
424+ return Err ( Error :: Parity . into( ) ) ;
425+ } else if isr. fe( ) . bit_is_set( ) {
426+ icr. write( |w| { w. fecf( ) . set_bit( ) } ) ;
427+ return Err ( Error :: Framing . into( ) ) ;
428+ } else if isr. nf( ) . bit_is_set( ) {
429+ icr. write( |w| { w. ncf( ) . set_bit( ) } ) ;
430+ return Err ( Error :: Noise . into( ) ) ;
431+ } else if isr. ore( ) . bit_is_set( ) {
432+ icr. write( |w| { w. orecf( ) . set_bit( ) } ) ;
433+ return Err ( Error :: Overrun . into( ) ) ;
434+ }
435+
436+ Ok ( ( ) )
437+ }
438+
439+ /// Clears any signaled errors without returning them.
440+ pub fn clear_errors( & mut self ) {
441+ let icr = unsafe { & ( * $USARTX:: ptr( ) ) . icr } ;
442+
443+ icr. write( |w| w
444+ . pecf( ) . set_bit( )
445+ . fecf( ) . set_bit( )
446+ . ncf( ) . set_bit( )
447+ . orecf( ) . set_bit( )
448+ ) ;
449+ }
450+ }
451+
452+ /// DMA operations.
453+ #[ cfg( any( feature = "stm32l0x2" , feature = "stm32l0x3" ) ) ]
370454 impl Rx <$USARTX> {
371455 pub fn read_all<Buffer , Channel >( self ,
372456 dma: & mut dma:: Handle ,
@@ -423,44 +507,20 @@ macro_rules! usart {
423507 type Error = Error ;
424508
425509 fn read( & mut self ) -> nb:: Result <u8 , Error > {
510+ self . check_errors( ) ?;
511+
426512 // NOTE(unsafe) atomic read with no side effects
427513 let isr = unsafe { ( * $USARTX:: ptr( ) ) . isr. read( ) } ;
428514
429- // Check for any errors
430- let _err = if isr. pe( ) . bit_is_set( ) {
431- Some ( Error :: Parity )
432- } else if isr. fe( ) . bit_is_set( ) {
433- Some ( Error :: Framing )
434- } else if isr. nf( ) . bit_is_set( ) {
435- Some ( Error :: Noise )
436- } else if isr. ore( ) . bit_is_set( ) {
437- Some ( Error :: Overrun )
438- } else {
439- None
440- } ;
441-
442- if let Some ( _err) = _err {
443- // Some error occured. Clear the error flags by writing to ICR
444- // followed by a read from the rdr register
515+ // Check if a byte is available
516+ if isr. rxne( ) . bit_is_set( ) {
517+ // Read the received byte
445518 // NOTE(read_volatile) see `write_volatile` below
446- unsafe {
447- ( * $USARTX:: ptr( ) ) . icr. write( |w| { w. pecf( ) . set_bit( ) } ) ;
448- ( * $USARTX:: ptr( ) ) . icr. write( |w| { w. fecf( ) . set_bit( ) } ) ;
449- ( * $USARTX:: ptr( ) ) . icr. write( |w| { w. ncf( ) . set_bit( ) } ) ;
450- ( * $USARTX:: ptr( ) ) . icr. write( |w| { w. orecf( ) . set_bit( ) } ) ;
451- }
452- Err ( nb:: Error :: WouldBlock )
519+ Ok ( unsafe {
520+ ptr:: read_volatile( & ( * $USARTX:: ptr( ) ) . rdr as * const _ as * const _)
521+ } )
453522 } else {
454- // Check if a byte is available
455- if isr. rxne( ) . bit_is_set( ) {
456- // Read the received byte
457- // NOTE(read_volatile) see `write_volatile` below
458- Ok ( unsafe {
459- ptr:: read_volatile( & ( * $USARTX:: ptr( ) ) . rdr as * const _ as * const _)
460- } )
461- } else {
462- Err ( nb:: Error :: WouldBlock )
463- }
523+ Err ( nb:: Error :: WouldBlock )
464524 }
465525 }
466526 }
@@ -569,7 +629,7 @@ usart! {
569629 USART1 : ( usart1, apb2enr, usart1en, apb1_clk, Serial1Ext ) ,
570630 USART2 : ( usart2, apb1enr, usart2en, apb1_clk, Serial2Ext ) ,
571631 USART4 : ( usart4, apb1enr, usart4en, apb1_clk, Serial4Ext ) ,
572- USART5 : ( usart5, apb1enr, usart5en, apb1_clk, Serial5Ext ) ,
632+ USART5 : ( usart5, apb1enr, usart5en, apb1_clk, Serial5Ext ) ,
573633}
574634
575635impl < USART > fmt:: Write for Serial < USART >
0 commit comments