Skip to content

Commit 9cb658e

Browse files
committed
Add trait SpiWord
1 parent e777c7e commit 9cb658e

File tree

1 file changed

+33
-11
lines changed

1 file changed

+33
-11
lines changed

src/spi.rs

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
334361
impl<SPI, Sck, Miso, Mosi, Word> FullDuplex<Word> for Spi<SPI, (Sck, Miso, Mosi), Word>
335362
where
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

Comments
 (0)