8
8
//! - [Inverted Signal Levels](https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/serial-inverted-loopback.rs)
9
9
10
10
use core:: cell:: UnsafeCell ;
11
- use core:: fmt ;
11
+ use core:: convert :: Infallible ;
12
12
use core:: marker:: PhantomData ;
13
13
use core:: ptr;
14
14
15
- use embedded_hal:: blocking:: serial as serial_block;
16
- use embedded_hal:: prelude:: * ;
17
- use embedded_hal:: serial;
18
- use nb :: block ;
15
+ // use embedded_hal::blocking::serial as serial_block;
16
+ // use embedded_hal::prelude::*;
17
+ // use embedded_hal::serial;
18
+ use embedded_io as eio ;
19
19
20
20
use stm32:: usart1:: cr2:: {
21
21
CLKEN_A , CPHA_A , CPOL_A , LBCL_A , MSBFIRST_A , RXINV_A , TXINV_A ,
@@ -44,6 +44,8 @@ use crate::time::Hertz;
44
44
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
45
45
#[ non_exhaustive]
46
46
pub enum Error {
47
+ /// An attempted write could not write any data
48
+ WriteZero ,
47
49
/// Framing error
48
50
Framing ,
49
51
/// Noise error
@@ -53,6 +55,14 @@ pub enum Error {
53
55
/// Parity check error
54
56
Parity ,
55
57
}
58
+ impl eio:: Error for Error {
59
+ fn kind ( & self ) -> eio:: ErrorKind {
60
+ match self {
61
+ Error :: WriteZero => eio:: ErrorKind :: WriteZero ,
62
+ _ => eio:: ErrorKind :: Other ,
63
+ }
64
+ }
65
+ }
56
66
57
67
/// Interrupt event
58
68
#[ derive( Copy , Clone , PartialEq , Eq ) ]
@@ -964,22 +974,60 @@ macro_rules! usart {
964
974
}
965
975
}
966
976
967
- impl serial:: Read <u8 > for Serial <$USARTX> {
968
- type Error = Error ;
977
+ // Implement embedded_io::Write
969
978
970
- fn read( & mut self ) -> nb:: Result <u8 , Error > {
979
+ impl eio:: ErrorType for Serial <$USARTX> {
980
+ type Error = Error ;
981
+ }
982
+ impl eio:: Read for Serial <$USARTX> {
983
+ fn read( & mut self , buf: & mut [ u8 ] ) -> Result <usize , Error > {
971
984
let mut rx: Rx <$USARTX> = Rx {
972
985
_usart: PhantomData ,
973
986
ker_ck: self . ker_ck,
974
987
} ;
975
- rx. read( )
988
+ rx. read( buf )
976
989
}
977
990
}
978
-
979
- impl serial:: Read <u8 > for Rx <$USARTX> {
991
+ impl eio:: ErrorType for Rx <$USARTX> {
980
992
type Error = Error ;
993
+ }
994
+ impl eio:: Read for Rx <$USARTX> {
995
+ fn read( & mut self , buf: & mut [ u8 ] ) -> Result <usize , Error > {
996
+ for ( i, byte) in buf. iter_mut( ) . enumerate( ) {
997
+ while true {
998
+ match self . read_byte( ) {
999
+ Ok ( b) => {
1000
+ * byte = b;
1001
+ continue ;
1002
+ } ,
1003
+ Err ( nb:: Error :: WouldBlock ) => {
1004
+ if i > 0 {
1005
+ return Ok ( i) ;
1006
+ }
1007
+ } ,
1008
+ Err ( nb:: Error :: Other ( e) ) => {
1009
+ return Err ( e) ;
1010
+ }
1011
+ }
1012
+ }
1013
+ }
1014
+ Ok ( buf. len( ) )
1015
+ }
1016
+ }
981
1017
982
- fn read( & mut self ) -> nb:: Result <u8 , Error > {
1018
+ impl Serial <$USARTX> {
1019
+ /// Reads a single word from the serial interface
1020
+ pub fn read_byte( & mut self ) -> nb:: Result <u8 , Error > {
1021
+ let mut rx: Rx <$USARTX> = Rx {
1022
+ _usart: PhantomData ,
1023
+ ker_ck: self . ker_ck,
1024
+ } ;
1025
+ rx. read_byte( )
1026
+ }
1027
+ }
1028
+ impl Rx <$USARTX> {
1029
+ /// Reads a single word from the serial interface
1030
+ pub fn read_byte( & mut self ) -> nb:: Result <u8 , Error > {
983
1031
// NOTE(unsafe) atomic read with no side effects
984
1032
let isr = unsafe { ( * $USARTX:: ptr( ) ) . isr. read( ) } ;
985
1033
@@ -1004,9 +1052,7 @@ macro_rules! usart {
1004
1052
nb:: Error :: WouldBlock
1005
1053
} )
1006
1054
}
1007
- }
1008
1055
1009
- impl Rx <$USARTX> {
1010
1056
/// Start listening for `Rxne` event
1011
1057
pub fn listen( & mut self ) {
1012
1058
// unsafe: rxneie bit accessed by Rx part only
@@ -1064,49 +1110,66 @@ macro_rules! usart {
1064
1110
}
1065
1111
}
1066
1112
1067
- impl serial:: Write <u8 > for Serial <$USARTX> {
1068
- type Error = core:: convert:: Infallible ;
1113
+ // Implement embedded_io::Write
1069
1114
1070
- fn flush( & mut self ) -> nb:: Result <( ) , Self :: Error > {
1115
+ impl eio:: Write for Serial <$USARTX> {
1116
+ fn flush( & mut self ) -> Result <( ) , Error > {
1071
1117
let mut tx: Tx <$USARTX> = Tx {
1072
1118
_usart: PhantomData ,
1073
1119
} ;
1074
1120
tx. flush( )
1075
1121
}
1076
-
1077
- fn write( & mut self , byte: u8 ) -> nb:: Result <( ) , Self :: Error > {
1122
+ fn write( & mut self , buf: & [ u8 ] ) -> Result <usize , Error > {
1078
1123
let mut tx: Tx <$USARTX> = Tx {
1079
1124
_usart: PhantomData ,
1080
1125
} ;
1081
- tx. write( byte )
1126
+ tx. write( buf )
1082
1127
}
1083
1128
}
1129
+ impl eio:: ErrorType for Tx <$USARTX> {
1130
+ type Error = Error ;
1131
+ }
1132
+ impl eio:: Write for Tx <$USARTX> {
1133
+ fn write( & mut self , buf: & [ u8 ] ) -> Result <usize , Error > {
1134
+ for ( i, byte) in buf. iter( ) . enumerate( ) {
1135
+ if self . write_byte( * byte) . is_ok( ) {
1136
+ continue ;
1137
+ } else if i == 0 {
1138
+ return Err ( Error :: WriteZero ) ;
1139
+ } else {
1140
+ return Ok ( i) ;
1141
+ }
1142
+ }
1143
+ Ok ( buf. len( ) )
1144
+ }
1145
+ fn flush( & mut self ) -> Result <( ) , Error > {
1146
+ // NOTE(unsafe) atomic read with no side effects
1147
+ let isr = unsafe { ( * $USARTX:: ptr( ) ) . isr. read( ) } ;
1084
1148
1085
- impl serial_block:: write:: Default <u8 > for Serial <$USARTX> {
1086
- //implement marker trait to opt-in to default blocking write implementation
1149
+ while !isr. tc( ) . bit_is_set( ) { }
1150
+ Ok ( ( ) )
1151
+ }
1087
1152
}
1088
1153
1089
- impl serial:: Write <u8 > for Tx <$USARTX> {
1154
+ impl Serial <$USARTX> {
1155
+ /// Writes a single word to the serial interface
1156
+ pub fn write_byte( & mut self , byte: u8 ) -> nb:: Result <( ) , Infallible > {
1157
+ let mut tx: Tx <$USARTX> = Tx {
1158
+ _usart: PhantomData ,
1159
+ } ;
1160
+ tx. write_byte( byte)
1161
+ }
1162
+ }
1163
+ impl Tx <$USARTX> {
1090
1164
// NOTE(Void) See section "29.7 USART interrupts"; the
1091
1165
// only possible errors during transmission are: clear
1092
1166
// to send (which is disabled in this case) errors and
1093
1167
// framing errors (which only occur in SmartCard
1094
1168
// mode); neither of these apply to our hardware
1095
1169
// configuration
1096
- type Error = core:: convert:: Infallible ;
1097
-
1098
- fn flush( & mut self ) -> nb:: Result <( ) , Self :: Error > {
1099
- // NOTE(unsafe) atomic read with no side effects
1100
- let isr = unsafe { ( * $USARTX:: ptr( ) ) . isr. read( ) } ;
1101
-
1102
- if isr. tc( ) . bit_is_set( ) {
1103
- Ok ( ( ) )
1104
- } else {
1105
- Err ( nb:: Error :: WouldBlock )
1106
- }
1107
- }
1108
1170
1109
- fn write( & mut self , byte: u8 ) -> nb:: Result <( ) , Self :: Error > {
1171
+ /// Writes a single word to the serial interface
1172
+ pub fn write_byte( & mut self , byte: u8 ) -> nb:: Result <( ) , Infallible > {
1110
1173
// NOTE(unsafe) atomic read with no side effects
1111
1174
let isr = unsafe { ( * $USARTX:: ptr( ) ) . isr. read( ) } ;
1112
1175
@@ -1124,9 +1187,7 @@ macro_rules! usart {
1124
1187
Err ( nb:: Error :: WouldBlock )
1125
1188
}
1126
1189
}
1127
- }
1128
1190
1129
- impl Tx <$USARTX> {
1130
1191
/// Start listening for `Txe` event
1131
1192
pub fn listen( & mut self ) {
1132
1193
// unsafe: txeie bit accessed by Tx part only
@@ -1294,23 +1355,3 @@ usart_sel! {
1294
1355
UART8 : "UART8" ,
1295
1356
UART7 : "UART7" ,
1296
1357
}
1297
-
1298
- impl < USART > fmt:: Write for Tx < USART >
1299
- where
1300
- Tx < USART > : serial:: Write < u8 > ,
1301
- {
1302
- fn write_str ( & mut self , s : & str ) -> fmt:: Result {
1303
- let _ = s. as_bytes ( ) . iter ( ) . map ( |c| block ! ( self . write( * c) ) ) . last ( ) ;
1304
- Ok ( ( ) )
1305
- }
1306
- }
1307
-
1308
- impl < USART > fmt:: Write for Serial < USART >
1309
- where
1310
- Serial < USART > : serial:: Write < u8 > ,
1311
- {
1312
- fn write_str ( & mut self , s : & str ) -> fmt:: Result {
1313
- let _ = s. as_bytes ( ) . iter ( ) . map ( |c| block ! ( self . write( * c) ) ) . last ( ) ;
1314
- Ok ( ( ) )
1315
- }
1316
- }
0 commit comments