Skip to content

Commit

Permalink
Add trait SpiWord
Browse files Browse the repository at this point in the history
  • Loading branch information
usbalbin committed Dec 21, 2024
1 parent e777c7e commit 9cb658e
Showing 1 changed file with 33 additions and 11 deletions.
44 changes: 33 additions & 11 deletions src/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use crate::{
rcc::{self, Clocks},
time::rate,
};
use num_traits::{AsPrimitive, PrimInt};

/// SPI error
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -331,15 +330,42 @@ where
}
}

/// A trait for types that can be used as SPI words
///
/// This is typically [u8] and [u16]
pub trait SpiWord {
/// Read word from SPI data register
fn read(r: &impl Instance) -> Self;

/// Write word to SPI data register
fn write(r: &impl Instance, data: Self);
}

macro_rules! impl_spi_word {
($t:ty, $dr:ident) => {
impl SpiWord for $t {
fn read(r: &impl Instance) -> Self {
r.$dr().read().bits()
}

fn write(r: &impl Instance, data: Self) {
r.$dr().write(|w| w.dr().set(data));
}
}
};
}

impl_spi_word!(u16, dr);
impl_spi_word!(u8, dr8);

impl<SPI, Sck, Miso, Mosi, Word> FullDuplex<Word> for Spi<SPI, (Sck, Miso, Mosi), Word>
where
SPI: Instance,
// Full Duplex needs the Miso and Mosi pins.
// SckPin could technically be omitted, though not advisable.
Miso: MisoPin<SPI>,
Mosi: MosiPin<SPI>,
Word: PrimInt + Into<u32> + 'static,
u32: AsPrimitive<Word>,
Word: SpiWord,
{
type Error = Error;

Expand All @@ -353,9 +379,8 @@ where
} else if sr.crcerr().is_no_match() {
nb::Error::Other(Error::Crc)
} else if sr.rxne().is_not_empty() {
let read_ptr = self.spi.dr().as_ptr() as *const Word;
// SAFETY: Read from register owned by this Spi struct
let value = unsafe { core::ptr::read_volatile(read_ptr) };
let value = SpiWord::read(&self.spi);
return Ok(value);
} else {
nb::Error::WouldBlock
Expand All @@ -372,9 +397,8 @@ where
} else if sr.crcerr().is_no_match() {
nb::Error::Other(Error::Crc)
} else if sr.txe().is_empty() {
let write_ptr = self.spi.dr().as_ptr() as *mut Word;
// SAFETY: Write to register owned by this Spi struct
unsafe { core::ptr::write_volatile(write_ptr, word) };
SpiWord::write(&self.spi, word);
return Ok(());
} else {
nb::Error::WouldBlock
Expand All @@ -387,8 +411,7 @@ where
SPI: Instance,
Miso: MisoPin<SPI>,
Mosi: MosiPin<SPI>,
Word: PrimInt + Into<u32> + 'static,
u32: AsPrimitive<Word>,
Word: SpiWord,
{
}

Expand All @@ -397,8 +420,7 @@ where
SPI: Instance,
Miso: MisoPin<SPI>,
Mosi: MosiPin<SPI>,
Word: PrimInt + Into<u32> + 'static,
u32: AsPrimitive<Word>,
Word: SpiWord,
{
}

Expand Down

0 comments on commit 9cb658e

Please sign in to comment.