diff --git a/examples/spi.rs b/examples/spi.rs index 4e210eb..77dcb32 100644 --- a/examples/spi.rs +++ b/examples/spi.rs @@ -6,7 +6,7 @@ use cortex_m_rt::entry; mod utilities; use embedded_hal::delay::DelayNs; use embedded_hal::spi::SpiBus; -use stm32h5xx_hal::{delay::Delay, pac, prelude::*, spi, time::Seconds}; +use stm32h5xx_hal::{delay::Delay, pac, prelude::*, spi, time::MilliSeconds}; use log::info; @@ -58,7 +58,7 @@ fn main() -> ! { info!("Transfer starting"); let mut delay = Delay::new(cp.SYST, &ccdr.clocks); - let duration = Seconds::secs(1).to_millis(); + let duration = MilliSeconds::secs(1).to_millis(); // Echo what is received on the SPI let write = TEST_STR; let read = &mut [0u8; TEST_STR.len()]; diff --git a/src/spi.rs b/src/spi.rs index 6de9af1..c2fbfa7 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -198,7 +198,12 @@ use crate::rcc::{rec, CoreClocks, ResetEnable}; use crate::stm32; use crate::stm32::rcc::ccipr3; use crate::stm32::spi1; +#[cfg(any(feature = "h523_h533", feature = "h56x_h573"))] +use crate::stm32::SPI4; use crate::stm32::{SPI1, SPI2, SPI3}; +#[cfg(feature = "h56x_h573")] +use crate::stm32::{SPI5, SPI6}; + use crate::time::Hertz; use spi1::{cfg1::MBR, cfg2::COMM, cfg2::LSBFRST, cfg2::SSIOP}; @@ -613,6 +618,198 @@ pins! { ] } +// Note: pin data is taken from stm32h56x, stm32h573, stm32h523 and stm32h533 datasheets +#[cfg(any(feature = "h523_h533", feature = "h56x_h573"))] +pins! { + SPI1: + SCK: [ + NoSck, + gpio::PA5>, + gpio::PB3>, + gpio::PG11> + ] + MISO: [ + NoMiso, + gpio::PA6>, + gpio::PB4>, + gpio::PG9> + ] + MOSI: [ + NoMosi, + gpio::PA7>, + gpio::PB5>, + #[cfg(feature = "h523_h533")] + gpio::PB15>, + gpio::PD7> + ] + HCS: [ + gpio::PA4>, + gpio::PA15>, + gpio::PG10> + ] + SPI2: + SCK: [ + NoSck, + gpio::PA9>, + gpio::PA12>, + gpio::PB10>, + gpio::PB13>, + gpio::PD3>, + #[cfg(feature = "h56x_h573")] + gpio::PI1> + ] + MISO: [ + NoMiso, + gpio::PB14>, + gpio::PC2>, + #[cfg(feature = "h56x_h573")] + gpio::PI2> + ] + MOSI: [ + NoMosi, + gpio::PB15>, + gpio::PC1>, + gpio::PC3>, + gpio::PG1>, + #[cfg(feature = "h56x_h573")] + gpio::PI3> + ] + HCS: [ + gpio::PA3>, + gpio::PA11>, + #[cfg(feature = "h523_h533")] + gpio::PB1>, + gpio::PB4>, + gpio::PB9>, + gpio::PB12>, + #[cfg(feature = "h56x_h573")] + gpio::PI0> + ] + SPI3: + SCK: [ + NoSck, + #[cfg(feature = "h523_h533")] + gpio::PB1>, + gpio::PB3>, + #[cfg(feature = "h523_h533")] + gpio::PB9>, + gpio::PC10> + ] + MISO: [ + NoMiso, + #[cfg(feature = "h523_h533")] + gpio::PB0>, + gpio::PB4>, + gpio::PC11>, + #[cfg(feature = "h523_h533")] + gpio::PD7> + ] + MOSI: [ + NoMosi, + #[cfg(feature = "h523_h533")] + gpio::PA3>, + #[cfg(feature = "h523_h533")] + gpio::PA4>, + gpio::PB2>, + gpio::PB5>, + gpio::PC12>, + gpio::PD6>, + #[cfg(feature = "h523_h533")] + gpio::PG8> + ] + HCS: [ + gpio::PA4>, + gpio::PA15>, + #[cfg(feature = "h523_h533")] + gpio::PB8> + ] + SPI4: + SCK: [ + NoSck, + #[cfg(feature = "h523_h533")] + gpio::PA0>, + #[cfg(feature = "h523_h533")] + gpio::PC5>, + gpio::PE2>, + gpio::PE12> + ] + MISO: [ + NoMiso, + #[cfg(feature = "h523_h533")] + gpio::PC0>, + #[cfg(feature = "h523_h533")] + gpio::PB7>, + gpio::PE5>, + gpio::PE13> + ] + MOSI: [ + NoMosi, + #[cfg(feature = "h523_h533")] + gpio::PA8>, + #[cfg(feature = "stm32h523")] + gpio::PC1>, + gpio::PE6>, + gpio::PE14> + ] + HCS: [ + gpio::PE4>, + gpio::PE11> + ] + +} + +#[cfg(feature = "h56x_h573")] +pins! { + SPI5: + SCK: [ + NoSck, + gpio::PF7>, + gpio::PH6> + ] + MISO: [ + NoMiso, + gpio::PF8>, + gpio::PH7> + ] + MOSI: [ + NoMosi, + gpio::PF9>, + gpio::PF11>, + gpio::PH8> + ] + HCS: [ + gpio::PF6>, + gpio::PH5>, + gpio::PH9> + ] + SPI6: + SCK: [ + NoSck, + gpio::PA5>, + gpio::PB3>, + gpio::PC12>, + gpio::PG13> + ] + MISO: [ + NoMiso, + gpio::PA6>, + gpio::PB4>, + gpio::PG12> + ] + MOSI: [ + NoMosi, + gpio::PA7>, + gpio::PB5>, + gpio::PG14> + ] + HCS: [ + gpio::PA0>, + gpio::PA4>, + gpio::PA15>, + gpio::PG8> + ] +} + /// Interrupt events #[derive(Copy, Clone, PartialEq, Eq)] pub enum Event { @@ -627,26 +824,26 @@ pub enum Event { } #[derive(Debug)] -pub struct Inner { +pub struct Inner> { spi: SPI, _word: PhantomData, } /// Spi in Master mode #[derive(Debug)] -pub struct Spi { +pub struct Spi = u8> { inner: Inner, _word: PhantomData, } -impl Deref for Spi { +impl> Deref for Spi { type Target = Inner; fn deref(&self) -> &Self::Target { &self.inner } } -impl DerefMut for Spi { +impl> DerefMut for Spi { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } @@ -706,24 +903,37 @@ instance! { SPI1: Spi1, SPI123 } instance! { SPI2: Spi2, SPI123 } instance! { SPI3: Spi3, SPI123 } -pub trait FrameSize: Copy + Default + 'static + crate::Sealed { +pub trait FrameSize: Copy + Default + 'static + crate::Sealed { const BITS: u8; } macro_rules! framesize { ($type:ty) => { - impl FrameSize for $type { + impl FrameSize for $type { const BITS: u8 = <$type>::BITS as u8; } impl crate::Sealed for $type {} }; } -framesize!(u32); +macro_rules! framesize_u32 { + ($SPIx:ty) => { + impl FrameSize<$SPIx> for u32 { + const BITS: u8 = u32::BITS as u8; + } + }; +} +impl crate::Sealed for u32 {} + framesize!(u16); framesize!(u8); -pub trait SpiExt { +// Only SPI[1,2,3] support 32bit data size +framesize_u32!(SPI1); +framesize_u32!(SPI2); +framesize_u32!(SPI3); + +pub trait SpiExt = u8> { fn spi( self, _pins: PINS, @@ -747,7 +957,7 @@ pub trait SpiExt { CONFIG: Into; } -impl SpiExt for SPI { +impl> SpiExt for SPI { fn spi( self, _pins: PINS, @@ -796,7 +1006,7 @@ fn calc_mbr(spi_ker_ck: u32, spi_freq: u32) -> MBR { } } -impl Spi { +impl> Spi { fn new( spi: SPI, config: impl Into, @@ -917,7 +1127,7 @@ macro_rules! check_status_error { }; } -impl Inner { +impl> Inner { fn new(spi: SPI) -> Self { Self { spi, @@ -1190,7 +1400,7 @@ impl Inner { } } -impl Spi { +impl> Spi { /// Sets up a frame transaction with the given amount of data words. /// /// If this is called when a transaction has already started, @@ -1244,7 +1454,7 @@ impl Spi { } #[derive(Debug)] -pub struct NonBlockingTransfer<'a, W: FrameSize> { +pub struct NonBlockingTransfer<'a, W> { write: &'a [W], read: &'a mut [W], write_idx: usize, @@ -1252,7 +1462,7 @@ pub struct NonBlockingTransfer<'a, W: FrameSize> { len: usize, } -impl<'a, W: FrameSize> NonBlockingTransfer<'a, W> { +impl<'a, W> NonBlockingTransfer<'a, W> { pub fn new(write: &'a [W], read: &'a mut [W]) -> Self { let len = core::cmp::max(read.len(), write.len()); NonBlockingTransfer { @@ -1272,10 +1482,14 @@ impl<'a, W: FrameSize> NonBlockingTransfer<'a, W> { self.read_idx >= self.read.len() && self.write_idx >= self.write.len() } - fn write_to_spi_nb( + fn write_to_spi_nb( &mut self, spi: &mut Inner, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + SPI: Instance, + W: FrameSize, + { if self.write_idx < self.write.len() { self.write_idx += spi.write_nb(&self.write[self.write_idx..])?; } @@ -1287,10 +1501,14 @@ impl<'a, W: FrameSize> NonBlockingTransfer<'a, W> { Ok(()) } - fn read_from_spi_nb( + fn read_from_spi_nb( &mut self, spi: &mut Inner, - ) -> Result<(), Error> { + ) -> Result<(), Error> + where + SPI: Instance, + W: FrameSize, + { if self.read_idx < self.read.len() { self.read_idx += spi.read_nb(&mut self.read[self.read_idx..])?; } @@ -1302,10 +1520,14 @@ impl<'a, W: FrameSize> NonBlockingTransfer<'a, W> { Ok(()) } - fn exchange_nb( + fn exchange_nb( &mut self, spi: &mut Inner, - ) -> nb::Result<(), Error> { + ) -> nb::Result<(), Error> + where + SPI: Instance, + W: FrameSize, + { self.write_to_spi_nb(spi)?; self.read_from_spi_nb(spi)?; if self.is_complete() { @@ -1317,7 +1539,7 @@ impl<'a, W: FrameSize> NonBlockingTransfer<'a, W> { } // Non-blocking operations -impl Spi { +impl> Spi { /// Ends the current transaction. This must always be called when all data has been sent to /// properly terminate the transaction and reset the SPI peripheral. Returns /// nb::Error::WouldBlock while a transfer is in progress (according to SR:TXC) @@ -1363,7 +1585,7 @@ impl Spi { } // Implement blocking transaction interface for Spi -impl Spi { +impl> Spi { /// Write-only transfer fn write(&mut self, words: &[W]) -> Result<(), Error> { let communication_mode = self.communication_mode(); diff --git a/src/spi/hal.rs b/src/spi/hal.rs index 8decba7..806e28b 100644 --- a/src/spi/hal.rs +++ b/src/spi/hal.rs @@ -22,11 +22,11 @@ impl HalError for Error { } } -impl ErrorType for Spi { +impl> ErrorType for Spi { type Error = Error; } -impl FullDuplex for Spi { +impl> FullDuplex for Spi { fn read(&mut self) -> nb::Result { self.check_read() } @@ -36,7 +36,7 @@ impl FullDuplex for Spi { } } -impl SpiBus for Spi { +impl> SpiBus for Spi { #[inline] fn read(&mut self, words: &mut [W]) -> Result<(), Self::Error> { self.read(words) @@ -75,7 +75,7 @@ trait OperationExt { fn len(&self) -> usize; } -impl OperationExt for Operation<'_, W> { +impl OperationExt for Operation<'_, W> { fn len(&self) -> usize { match self { Operation::Read(words) => words.len(), @@ -89,7 +89,7 @@ impl OperationExt for Operation<'_, W> { } } -impl SpiDevice for Spi { +impl> SpiDevice for Spi { fn transaction( &mut self, operations: &mut [Operation<'_, W>],