@@ -24,7 +24,6 @@ use crate::{
24
24
rcc:: { self , Clocks } ,
25
25
time:: rate,
26
26
} ;
27
- use num_traits:: { AsPrimitive , PrimInt } ;
28
27
29
28
/// SPI error
30
29
#[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
@@ -331,15 +330,42 @@ where
331
330
}
332
331
}
333
332
333
+ /// A trait for types that can be used as SPI words
334
+ ///
335
+ /// This is typically [u8] and [u16]
336
+ pub trait SpiWord {
337
+ /// Read word from SPI data register
338
+ fn read ( r : & impl Instance ) -> Self ;
339
+
340
+ /// Write word to SPI data register
341
+ fn write ( r : & impl Instance , data : Self ) ;
342
+ }
343
+
344
+ macro_rules! impl_spi_word {
345
+ ( $t: ty, $dr: ident) => {
346
+ impl SpiWord for $t {
347
+ fn read( r: & impl Instance ) -> Self {
348
+ r. $dr( ) . read( ) . bits( )
349
+ }
350
+
351
+ fn write( r: & impl Instance , data: Self ) {
352
+ r. $dr( ) . write( |w| w. dr( ) . set( data) ) ;
353
+ }
354
+ }
355
+ } ;
356
+ }
357
+
358
+ impl_spi_word ! ( u16 , dr) ;
359
+ impl_spi_word ! ( u8 , dr8) ;
360
+
334
361
impl < SPI , Sck , Miso , Mosi , Word > FullDuplex < Word > for Spi < SPI , ( Sck , Miso , Mosi ) , Word >
335
362
where
336
363
SPI : Instance ,
337
364
// Full Duplex needs the Miso and Mosi pins.
338
365
// SckPin could technically be omitted, though not advisable.
339
366
Miso : MisoPin < SPI > ,
340
367
Mosi : MosiPin < SPI > ,
341
- Word : PrimInt + Into < u32 > + ' static ,
342
- u32 : AsPrimitive < Word > ,
368
+ Word : SpiWord ,
343
369
{
344
370
type Error = Error ;
345
371
@@ -353,9 +379,8 @@ where
353
379
} else if sr. crcerr ( ) . is_no_match ( ) {
354
380
nb:: Error :: Other ( Error :: Crc )
355
381
} else if sr. rxne ( ) . is_not_empty ( ) {
356
- let read_ptr = self . spi . dr ( ) . as_ptr ( ) as * const Word ;
357
382
// SAFETY: Read from register owned by this Spi struct
358
- let value = unsafe { core :: ptr :: read_volatile ( read_ptr ) } ;
383
+ let value = SpiWord :: read ( & self . spi ) ;
359
384
return Ok ( value) ;
360
385
} else {
361
386
nb:: Error :: WouldBlock
@@ -372,9 +397,8 @@ where
372
397
} else if sr. crcerr ( ) . is_no_match ( ) {
373
398
nb:: Error :: Other ( Error :: Crc )
374
399
} else if sr. txe ( ) . is_empty ( ) {
375
- let write_ptr = self . spi . dr ( ) . as_ptr ( ) as * mut Word ;
376
400
// SAFETY: Write to register owned by this Spi struct
377
- unsafe { core :: ptr :: write_volatile ( write_ptr , word) } ;
401
+ SpiWord :: write ( & self . spi , word) ;
378
402
return Ok ( ( ) ) ;
379
403
} else {
380
404
nb:: Error :: WouldBlock
@@ -387,8 +411,7 @@ where
387
411
SPI : Instance ,
388
412
Miso : MisoPin < SPI > ,
389
413
Mosi : MosiPin < SPI > ,
390
- Word : PrimInt + Into < u32 > + ' static ,
391
- u32 : AsPrimitive < Word > ,
414
+ Word : SpiWord ,
392
415
{
393
416
}
394
417
@@ -397,8 +420,7 @@ where
397
420
SPI : Instance ,
398
421
Miso : MisoPin < SPI > ,
399
422
Mosi : MosiPin < SPI > ,
400
- Word : PrimInt + Into < u32 > + ' static ,
401
- u32 : AsPrimitive < Word > ,
423
+ Word : SpiWord ,
402
424
{
403
425
}
404
426
0 commit comments