@@ -28,7 +28,7 @@ pub use crate::{
28
28
gpio:: gpiob:: * ,
29
29
gpio:: gpioc:: * ,
30
30
gpio:: gpiod:: * ,
31
- gpio:: gpioe:: * ,
31
+ gpio:: gpioe:: * ,
32
32
pac:: { LPUART1 , USART1 , USART4 , USART5 } ,
33
33
} ;
34
34
@@ -52,11 +52,19 @@ pub enum Error {
52
52
53
53
/// Interrupt event
54
54
pub 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.
56
58
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.
58
66
Txe ,
59
- /// Idle line state detected
67
+ /// Idle line state detected.
60
68
Idle ,
61
69
}
62
70
@@ -181,7 +189,7 @@ impl_pins!(
181
189
USART4 , PC10 , PC11 , AF6 ;
182
190
USART4 , PE8 , PE9 , AF6 ;
183
191
USART5 , PB3 , PB4 , AF6 ;
184
- USART5 , PE10 , PE11 , AF6 ;
192
+ USART5 , PE10 , PE11 , AF6 ;
185
193
) ;
186
194
187
195
/// Serial abstraction
@@ -330,13 +338,47 @@ macro_rules! usart {
330
338
}
331
339
}
332
340
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
337
366
}
338
367
}
339
368
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
+
340
382
pub fn split( self ) -> ( Tx <$USARTX>, Rx <$USARTX>) {
341
383
( self . tx, self . rx)
342
384
}
@@ -366,7 +408,49 @@ macro_rules! usart {
366
408
}
367
409
}
368
410
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" ) ) ]
370
454
impl Rx <$USARTX> {
371
455
pub fn read_all<Buffer , Channel >( self ,
372
456
dma: & mut dma:: Handle ,
@@ -423,44 +507,20 @@ macro_rules! usart {
423
507
type Error = Error ;
424
508
425
509
fn read( & mut self ) -> nb:: Result <u8 , Error > {
510
+ self . check_errors( ) ?;
511
+
426
512
// NOTE(unsafe) atomic read with no side effects
427
513
let isr = unsafe { ( * $USARTX:: ptr( ) ) . isr. read( ) } ;
428
514
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
445
518
// 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
+ } )
453
522
} 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 )
464
524
}
465
525
}
466
526
}
@@ -569,7 +629,7 @@ usart! {
569
629
USART1 : ( usart1, apb2enr, usart1en, apb1_clk, Serial1Ext ) ,
570
630
USART2 : ( usart2, apb1enr, usart2en, apb1_clk, Serial2Ext ) ,
571
631
USART4 : ( usart4, apb1enr, usart4en, apb1_clk, Serial4Ext ) ,
572
- USART5 : ( usart5, apb1enr, usart5en, apb1_clk, Serial5Ext ) ,
632
+ USART5 : ( usart5, apb1enr, usart5en, apb1_clk, Serial5Ext ) ,
573
633
}
574
634
575
635
impl < USART > fmt:: Write for Serial < USART >
0 commit comments