@@ -24,7 +24,6 @@ use crate::{
2424 rcc:: { self , Clocks } ,
2525 time:: rate,
2626} ;
27- use num_traits:: { AsPrimitive , PrimInt } ;
2827
2928/// SPI error
3029#[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
@@ -331,15 +330,42 @@ where
331330 }
332331}
333332
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+
334361impl < SPI , Sck , Miso , Mosi , Word > FullDuplex < Word > for Spi < SPI , ( Sck , Miso , Mosi ) , Word >
335362where
336363 SPI : Instance ,
337364 // Full Duplex needs the Miso and Mosi pins.
338365 // SckPin could technically be omitted, though not advisable.
339366 Miso : MisoPin < SPI > ,
340367 Mosi : MosiPin < SPI > ,
341- Word : PrimInt + Into < u32 > + ' static ,
342- u32 : AsPrimitive < Word > ,
368+ Word : SpiWord ,
343369{
344370 type Error = Error ;
345371
@@ -353,9 +379,8 @@ where
353379 } else if sr. crcerr ( ) . is_no_match ( ) {
354380 nb:: Error :: Other ( Error :: Crc )
355381 } else if sr. rxne ( ) . is_not_empty ( ) {
356- let read_ptr = self . spi . dr ( ) . as_ptr ( ) as * const Word ;
357382 // 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 ) ;
359384 return Ok ( value) ;
360385 } else {
361386 nb:: Error :: WouldBlock
@@ -372,9 +397,8 @@ where
372397 } else if sr. crcerr ( ) . is_no_match ( ) {
373398 nb:: Error :: Other ( Error :: Crc )
374399 } else if sr. txe ( ) . is_empty ( ) {
375- let write_ptr = self . spi . dr ( ) . as_ptr ( ) as * mut Word ;
376400 // SAFETY: Write to register owned by this Spi struct
377- unsafe { core :: ptr :: write_volatile ( write_ptr , word) } ;
401+ SpiWord :: write ( & self . spi , word) ;
378402 return Ok ( ( ) ) ;
379403 } else {
380404 nb:: Error :: WouldBlock
@@ -387,8 +411,7 @@ where
387411 SPI : Instance ,
388412 Miso : MisoPin < SPI > ,
389413 Mosi : MosiPin < SPI > ,
390- Word : PrimInt + Into < u32 > + ' static ,
391- u32 : AsPrimitive < Word > ,
414+ Word : SpiWord ,
392415{
393416}
394417
@@ -397,8 +420,7 @@ where
397420 SPI : Instance ,
398421 Miso : MisoPin < SPI > ,
399422 Mosi : MosiPin < SPI > ,
400- Word : PrimInt + Into < u32 > + ' static ,
401- u32 : AsPrimitive < Word > ,
423+ Word : SpiWord ,
402424{
403425}
404426
0 commit comments