@@ -332,6 +332,123 @@ impl<USART, PINS, WORD> AsMut<Rx<USART, WORD>> for Serial<USART, PINS, WORD> {
332
332
}
333
333
}
334
334
335
+ /// Serial receiver containing RX pin
336
+ pub struct URx < USART , RX , WORD = u8 > {
337
+ _usart : PhantomData < USART > ,
338
+ pin : RX ,
339
+ _word : PhantomData < WORD > ,
340
+ }
341
+
342
+ /// Serial transmitter containing TX pin
343
+ pub struct UTx < USART , TX , WORD = u8 > {
344
+ usart : USART ,
345
+ pin : TX ,
346
+ _word : PhantomData < WORD > ,
347
+ }
348
+
349
+ impl < USART : Instance , RX , WORD > URx < USART , RX , WORD > {
350
+ fn new ( pin : RX ) -> Self {
351
+ Self {
352
+ _usart : PhantomData ,
353
+ pin,
354
+ _word : PhantomData ,
355
+ }
356
+ }
357
+
358
+ pub fn erase ( self ) -> Rx < USART , WORD > {
359
+ Rx :: new ( )
360
+ }
361
+
362
+ /// Start listening for an rx not empty interrupt event
363
+ ///
364
+ /// Note, you will also have to enable the corresponding interrupt
365
+ /// in the NVIC to start receiving events.
366
+ pub fn listen ( & mut self ) {
367
+ unsafe { ( * USART :: ptr ( ) ) . cr1 . modify ( |_, w| w. rxneie ( ) . set_bit ( ) ) }
368
+ }
369
+
370
+ /// Stop listening for the rx not empty interrupt event
371
+ pub fn unlisten ( & mut self ) {
372
+ unsafe { ( * USART :: ptr ( ) ) . cr1 . modify ( |_, w| w. rxneie ( ) . clear_bit ( ) ) }
373
+ }
374
+
375
+ /// Start listening for a line idle interrupt event
376
+ ///
377
+ /// Note, you will also have to enable the corresponding interrupt
378
+ /// in the NVIC to start receiving events.
379
+ pub fn listen_idle ( & mut self ) {
380
+ unsafe { ( * USART :: ptr ( ) ) . cr1 . modify ( |_, w| w. idleie ( ) . set_bit ( ) ) }
381
+ }
382
+
383
+ /// Stop listening for the line idle interrupt event
384
+ pub fn unlisten_idle ( & mut self ) {
385
+ unsafe { ( * USART :: ptr ( ) ) . cr1 . modify ( |_, w| w. idleie ( ) . clear_bit ( ) ) }
386
+ }
387
+
388
+ /// Return true if the line idle status is set
389
+ pub fn is_idle ( & self ) -> bool {
390
+ unsafe { ( * USART :: ptr ( ) ) . sr . read ( ) . idle ( ) . bit_is_set ( ) }
391
+ }
392
+
393
+ /// Return true if the rx register is not empty (and can be read)
394
+ pub fn is_rx_not_empty ( & self ) -> bool {
395
+ unsafe { ( * USART :: ptr ( ) ) . sr . read ( ) . rxne ( ) . bit_is_set ( ) }
396
+ }
397
+
398
+ /// Clear idle line interrupt flag
399
+ pub fn clear_idle_interrupt ( & self ) {
400
+ unsafe {
401
+ let _ = ( * USART :: ptr ( ) ) . sr . read ( ) ;
402
+ let _ = ( * USART :: ptr ( ) ) . dr . read ( ) ;
403
+ }
404
+ }
405
+ }
406
+
407
+ impl < USART : Instance , TX , WORD > UTx < USART , TX , WORD > {
408
+ fn new ( usart : USART , pin : TX ) -> Self {
409
+ Self {
410
+ usart,
411
+ pin,
412
+ _word : PhantomData ,
413
+ }
414
+ }
415
+
416
+ pub fn erase ( self ) -> Tx < USART , WORD > {
417
+ Tx :: new ( )
418
+ }
419
+
420
+ pub fn join < RX > ( self , rx : URx < USART , RX , WORD > ) -> Serial < USART , ( TX , RX ) , WORD >
421
+ where
422
+ ( TX , RX ) : Pins < USART > ,
423
+ {
424
+ Serial {
425
+ usart : self . usart ,
426
+ pins : ( self . pin , rx. pin ) ,
427
+ tx : Tx :: new ( ) ,
428
+ rx : Rx :: new ( ) ,
429
+ }
430
+ }
431
+
432
+ /// Start listening for a tx empty interrupt event
433
+ ///
434
+ /// Note, you will also have to enable the corresponding interrupt
435
+ /// in the NVIC to start receiving events.
436
+ // TODO: replace with "self.usart"
437
+ pub fn listen ( & mut self ) {
438
+ unsafe { ( * USART :: ptr ( ) ) . cr1 . modify ( |_, w| w. txeie ( ) . set_bit ( ) ) }
439
+ }
440
+
441
+ /// Stop listening for the tx empty interrupt event
442
+ pub fn unlisten ( & mut self ) {
443
+ unsafe { ( * USART :: ptr ( ) ) . cr1 . modify ( |_, w| w. txeie ( ) . clear_bit ( ) ) }
444
+ }
445
+
446
+ /// Return true if the tx register is empty (and can accept data)
447
+ pub fn is_tx_empty ( & self ) -> bool {
448
+ unsafe { ( * USART :: ptr ( ) ) . sr . read ( ) . txe ( ) . bit_is_set ( ) }
449
+ }
450
+ }
451
+
335
452
pub trait SerialExt : Sized + Instance {
336
453
fn serial < TX , RX , WORD > (
337
454
self ,
@@ -614,6 +731,12 @@ impl<USART: Instance, PINS, WORD> Serial<USART, PINS, WORD> {
614
731
}
615
732
}
616
733
734
+ impl < USART : Instance , TX , RX , WORD > Serial < USART , ( TX , RX ) , WORD > {
735
+ pub fn split_nondestructive ( self ) -> ( UTx < USART , TX , WORD > , URx < USART , RX , WORD > ) {
736
+ ( UTx :: new ( self . usart , self . pins . 0 ) , URx :: new ( self . pins . 1 ) )
737
+ }
738
+ }
739
+
617
740
impl < USART : Instance , PINS > Serial < USART , PINS , u8 > {
618
741
/// Converts this Serial into a version that can read and write `u16` values instead of `u8`s
619
742
///
@@ -912,3 +1035,109 @@ impl<USART: Instance> Tx<USART, u16> {
912
1035
nb:: block!( self . flush( ) )
913
1036
}
914
1037
}
1038
+
1039
+ impl < USART : Instance , TX > fmt:: Write for UTx < USART , TX > {
1040
+ fn write_str ( & mut self , s : & str ) -> fmt:: Result {
1041
+ s. bytes ( )
1042
+ . try_for_each ( |c| block ! ( self . write( c) ) )
1043
+ . map_err ( |_| fmt:: Error )
1044
+ }
1045
+ }
1046
+
1047
+ impl < USART : Instance , RX > URx < USART , RX , u8 > {
1048
+ fn read ( & mut self ) -> nb:: Result < u8 , Error > {
1049
+ // Delegate to the Read<u16> implementation, then truncate to 8 bits
1050
+ Rx :: < USART , u16 > :: new ( ) . read ( ) . map ( |word16| word16 as u8 )
1051
+ }
1052
+ }
1053
+
1054
+ impl < USART : Instance , RX > URx < USART , RX , u16 > {
1055
+ fn read ( & mut self ) -> nb:: Result < u16 , Error > {
1056
+ // NOTE(unsafe) atomic read with no side effects
1057
+ let sr = unsafe { ( * USART :: ptr ( ) ) . sr . read ( ) } ;
1058
+
1059
+ // Any error requires the dr to be read to clear
1060
+ if sr. pe ( ) . bit_is_set ( )
1061
+ || sr. fe ( ) . bit_is_set ( )
1062
+ || sr. nf ( ) . bit_is_set ( )
1063
+ || sr. ore ( ) . bit_is_set ( )
1064
+ {
1065
+ unsafe { ( * USART :: ptr ( ) ) . dr . read ( ) } ;
1066
+ }
1067
+
1068
+ Err ( if sr. pe ( ) . bit_is_set ( ) {
1069
+ Error :: Parity . into ( )
1070
+ } else if sr. fe ( ) . bit_is_set ( ) {
1071
+ Error :: FrameFormat . into ( )
1072
+ } else if sr. nf ( ) . bit_is_set ( ) {
1073
+ Error :: Noise . into ( )
1074
+ } else if sr. ore ( ) . bit_is_set ( ) {
1075
+ Error :: Overrun . into ( )
1076
+ } else if sr. rxne ( ) . bit_is_set ( ) {
1077
+ // NOTE(unsafe) atomic read from stateless register
1078
+ return Ok ( unsafe { & * USART :: ptr ( ) } . dr . read ( ) . dr ( ) . bits ( ) ) ;
1079
+ } else {
1080
+ nb:: Error :: WouldBlock
1081
+ } )
1082
+ }
1083
+ }
1084
+
1085
+ impl < USART : Instance , TX > UTx < USART , TX , u8 > {
1086
+ fn write ( & mut self , word : u8 ) -> nb:: Result < ( ) , Error > {
1087
+ // Delegate to u16 version
1088
+ Tx :: < USART , u16 > :: new ( ) . write ( u16:: from ( word) )
1089
+ }
1090
+
1091
+ fn flush ( & mut self ) -> nb:: Result < ( ) , Error > {
1092
+ // Delegate to u16 version
1093
+ Tx :: < USART , u16 > :: new ( ) . flush ( )
1094
+ }
1095
+
1096
+ fn bwrite_all ( & mut self , bytes : & [ u8 ] ) -> Result < ( ) , Error > {
1097
+ for & b in bytes {
1098
+ nb:: block!( self . write( b) ) ?;
1099
+ }
1100
+ Ok ( ( ) )
1101
+ }
1102
+
1103
+ fn bflush ( & mut self ) -> Result < ( ) , Error > {
1104
+ nb:: block!( self . flush( ) )
1105
+ }
1106
+ }
1107
+
1108
+ impl < USART : Instance , TX > UTx < USART , TX , u16 > {
1109
+ fn write ( & mut self , word : u16 ) -> nb:: Result < ( ) , Error > {
1110
+ // NOTE(unsafe) atomic read with no side effects
1111
+ let sr = unsafe { ( * USART :: ptr ( ) ) . sr . read ( ) } ;
1112
+
1113
+ if sr. txe ( ) . bit_is_set ( ) {
1114
+ // NOTE(unsafe) atomic write to stateless register
1115
+ unsafe { & * USART :: ptr ( ) } . dr . write ( |w| w. dr ( ) . bits ( word) ) ;
1116
+ Ok ( ( ) )
1117
+ } else {
1118
+ Err ( nb:: Error :: WouldBlock )
1119
+ }
1120
+ }
1121
+
1122
+ fn flush ( & mut self ) -> nb:: Result < ( ) , Error > {
1123
+ // NOTE(unsafe) atomic read with no side effects
1124
+ let sr = unsafe { ( * USART :: ptr ( ) ) . sr . read ( ) } ;
1125
+
1126
+ if sr. tc ( ) . bit_is_set ( ) {
1127
+ Ok ( ( ) )
1128
+ } else {
1129
+ Err ( nb:: Error :: WouldBlock )
1130
+ }
1131
+ }
1132
+
1133
+ fn bwrite_all ( & mut self , buffer : & [ u16 ] ) -> Result < ( ) , Error > {
1134
+ for & b in buffer {
1135
+ nb:: block!( self . write( b) ) ?;
1136
+ }
1137
+ Ok ( ( ) )
1138
+ }
1139
+
1140
+ fn bflush ( & mut self ) -> Result < ( ) , Error > {
1141
+ nb:: block!( self . flush( ) )
1142
+ }
1143
+ }
0 commit comments