1
1
use core:: fmt:: { Result , Write } ;
2
- use core:: marker :: PhantomData ;
2
+ use core:: ops :: Deref ;
3
3
use core:: ptr;
4
4
5
5
use embedded_hal:: prelude:: * ;
6
6
use nb:: block;
7
7
use void:: Void ;
8
8
9
9
#[ cfg( any( feature = "stm32f042" , feature = "stm32f030" ) ) ]
10
- use crate :: stm32:: { RCC , USART1 , USART2 } ;
10
+ use crate :: stm32:: { usart1 , RCC , USART1 , USART2 } ;
11
11
12
12
use crate :: gpio:: * ;
13
13
use crate :: rcc:: Clocks ;
@@ -83,12 +83,14 @@ pub struct Serial<USART, PINS> {
83
83
84
84
/// Serial receiver
85
85
pub struct Rx < USART > {
86
- _usart : PhantomData < USART > ,
86
+ // This is ok, because the USART types only contains PhantomData
87
+ usart : * const USART ,
87
88
}
88
89
89
90
/// Serial transmitter
90
91
pub struct Tx < USART > {
91
- _usart : PhantomData < USART > ,
92
+ // This is ok, because the USART types only contains PhantomData
93
+ usart : * const USART ,
92
94
}
93
95
94
96
/// USART1
@@ -117,75 +119,6 @@ impl<PINS> Serial<USART1, PINS> {
117
119
118
120
Serial { usart, pins }
119
121
}
120
-
121
- pub fn split ( self ) -> ( Tx < USART1 > , Rx < USART1 > ) {
122
- (
123
- Tx {
124
- _usart : PhantomData ,
125
- } ,
126
- Rx {
127
- _usart : PhantomData ,
128
- } ,
129
- )
130
- }
131
- pub fn release ( self ) -> ( USART1 , PINS ) {
132
- ( self . usart , self . pins )
133
- }
134
- }
135
-
136
- #[ cfg( any( feature = "stm32f042" , feature = "stm32f030" ) ) ]
137
- impl embedded_hal:: serial:: Read < u8 > for Rx < USART1 > {
138
- type Error = Error ;
139
-
140
- fn read ( & mut self ) -> nb:: Result < u8 , Error > {
141
- // NOTE(unsafe) atomic read with no side effects
142
- let isr = unsafe { ( * USART1 :: ptr ( ) ) . isr . read ( ) } ;
143
-
144
- Err ( if isr. pe ( ) . bit_is_set ( ) {
145
- nb:: Error :: Other ( Error :: Parity )
146
- } else if isr. fe ( ) . bit_is_set ( ) {
147
- nb:: Error :: Other ( Error :: Framing )
148
- } else if isr. nf ( ) . bit_is_set ( ) {
149
- nb:: Error :: Other ( Error :: Noise )
150
- } else if isr. ore ( ) . bit_is_set ( ) {
151
- nb:: Error :: Other ( Error :: Overrun )
152
- } else if isr. rxne ( ) . bit_is_set ( ) {
153
- // NOTE(read_volatile) see `write_volatile` below
154
- return Ok ( unsafe { ptr:: read_volatile ( & ( * USART1 :: ptr ( ) ) . rdr as * const _ as * const _ ) } ) ;
155
- } else {
156
- nb:: Error :: WouldBlock
157
- } )
158
- }
159
- }
160
-
161
- #[ cfg( any( feature = "stm32f042" , feature = "stm32f030" ) ) ]
162
- impl embedded_hal:: serial:: Write < u8 > for Tx < USART1 > {
163
- type Error = Void ;
164
-
165
- fn flush ( & mut self ) -> nb:: Result < ( ) , Self :: Error > {
166
- // NOTE(unsafe) atomic read with no side effects
167
- let isr = unsafe { ( * USART1 :: ptr ( ) ) . isr . read ( ) } ;
168
-
169
- if isr. tc ( ) . bit_is_set ( ) {
170
- Ok ( ( ) )
171
- } else {
172
- Err ( nb:: Error :: WouldBlock )
173
- }
174
- }
175
-
176
- fn write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Self :: Error > {
177
- // NOTE(unsafe) atomic read with no side effects
178
- let isr = unsafe { ( * USART1 :: ptr ( ) ) . isr . read ( ) } ;
179
-
180
- if isr. txe ( ) . bit_is_set ( ) {
181
- // NOTE(unsafe) atomic write to stateless register
182
- // NOTE(write_volatile) 8-bit write that's not possible through the svd2rust API
183
- unsafe { ptr:: write_volatile ( & ( * USART1 :: ptr ( ) ) . tdr as * const _ as * mut _ , byte) }
184
- Ok ( ( ) )
185
- } else {
186
- Err ( nb:: Error :: WouldBlock )
187
- }
188
- }
189
122
}
190
123
191
124
/// USART2
@@ -218,33 +151,21 @@ impl<PINS> Serial<USART2, PINS> {
218
151
219
152
Serial { usart, pins }
220
153
}
221
-
222
- pub fn split ( self ) -> ( Tx < USART2 > , Rx < USART2 > ) {
223
- (
224
- Tx {
225
- _usart : PhantomData ,
226
- } ,
227
- Rx {
228
- _usart : PhantomData ,
229
- } ,
230
- )
231
- }
232
- pub fn release ( self ) -> ( USART2 , PINS ) {
233
- ( self . usart , self . pins )
234
- }
235
154
}
236
155
237
- #[ cfg( any(
238
- feature = "stm32f042" ,
239
- feature = "stm32f030x8" ,
240
- feature = "stm32f030x8"
241
- ) ) ]
242
- impl embedded_hal:: serial:: Read < u8 > for Rx < USART2 > {
156
+ // It's s needed for the impls, but rustc doesn't recognize that
157
+ #[ allow( dead_code) ]
158
+ type SerialRegisterBlock = usart1:: RegisterBlock ;
159
+
160
+ impl < USART > embedded_hal:: serial:: Read < u8 > for Rx < USART >
161
+ where
162
+ USART : Deref < Target = SerialRegisterBlock > ,
163
+ {
243
164
type Error = Error ;
244
165
245
166
fn read ( & mut self ) -> nb:: Result < u8 , Error > {
246
167
// NOTE(unsafe) atomic read with no side effects
247
- let isr = unsafe { ( * USART2 :: ptr ( ) ) . isr . read ( ) } ;
168
+ let isr = unsafe { ( * self . usart ) . isr . read ( ) } ;
248
169
249
170
Err ( if isr. pe ( ) . bit_is_set ( ) {
250
171
nb:: Error :: Other ( Error :: Parity )
@@ -256,24 +177,22 @@ impl embedded_hal::serial::Read<u8> for Rx<USART2> {
256
177
nb:: Error :: Other ( Error :: Overrun )
257
178
} else if isr. rxne ( ) . bit_is_set ( ) {
258
179
// NOTE(read_volatile) see `write_volatile` below
259
- return Ok ( unsafe { ptr:: read_volatile ( & ( * USART2 :: ptr ( ) ) . rdr as * const _ as * const _ ) } ) ;
180
+ return Ok ( unsafe { ptr:: read_volatile ( & ( * self . usart ) . rdr as * const _ as * const _ ) } ) ;
260
181
} else {
261
182
nb:: Error :: WouldBlock
262
183
} )
263
184
}
264
185
}
265
186
266
- #[ cfg( any(
267
- feature = "stm32f042" ,
268
- feature = "stm32f030x8" ,
269
- feature = "stm32f030x8"
270
- ) ) ]
271
- impl embedded_hal:: serial:: Write < u8 > for Tx < USART2 > {
187
+ impl < USART > embedded_hal:: serial:: Write < u8 > for Tx < USART >
188
+ where
189
+ USART : Deref < Target = SerialRegisterBlock > ,
190
+ {
272
191
type Error = Void ;
273
192
274
193
fn flush ( & mut self ) -> nb:: Result < ( ) , Self :: Error > {
275
194
// NOTE(unsafe) atomic read with no side effects
276
- let isr = unsafe { ( * USART2 :: ptr ( ) ) . isr . read ( ) } ;
195
+ let isr = unsafe { ( * self . usart ) . isr . read ( ) } ;
277
196
278
197
if isr. tc ( ) . bit_is_set ( ) {
279
198
Ok ( ( ) )
@@ -284,19 +203,39 @@ impl embedded_hal::serial::Write<u8> for Tx<USART2> {
284
203
285
204
fn write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Self :: Error > {
286
205
// NOTE(unsafe) atomic read with no side effects
287
- let isr = unsafe { ( * USART2 :: ptr ( ) ) . isr . read ( ) } ;
206
+ let isr = unsafe { ( * self . usart ) . isr . read ( ) } ;
288
207
289
208
if isr. txe ( ) . bit_is_set ( ) {
290
209
// NOTE(unsafe) atomic write to stateless register
291
210
// NOTE(write_volatile) 8-bit write that's not possible through the svd2rust API
292
- unsafe { ptr:: write_volatile ( & ( * USART2 :: ptr ( ) ) . tdr as * const _ as * mut _ , byte) }
211
+ unsafe { ptr:: write_volatile ( & ( * self . usart ) . tdr as * const _ as * mut _ , byte) }
293
212
Ok ( ( ) )
294
213
} else {
295
214
Err ( nb:: Error :: WouldBlock )
296
215
}
297
216
}
298
217
}
299
218
219
+ impl < USART , PINS > Serial < USART , PINS >
220
+ where
221
+ USART : Deref < Target = SerialRegisterBlock > ,
222
+ PINS : Pins < USART > ,
223
+ {
224
+ pub fn split ( self ) -> ( Tx < USART > , Rx < USART > ) {
225
+ (
226
+ Tx {
227
+ usart : & self . usart as * const _ ,
228
+ } ,
229
+ Rx {
230
+ usart : & self . usart as * const _ ,
231
+ } ,
232
+ )
233
+ }
234
+ pub fn release ( self ) -> ( USART , PINS ) {
235
+ ( self . usart , self . pins )
236
+ }
237
+ }
238
+
300
239
impl < USART > Write for Tx < USART >
301
240
where
302
241
Tx < USART > : embedded_hal:: serial:: Write < u8 > ,
0 commit comments