diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 0a15563e..c7426159 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -51,3 +51,5 @@ crate::pac::peripheral_pins!( } }; ); + + diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 7112ad02..6ad90eb8 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -1,3 +1,6 @@ +#![macro_use] + +use crate::peripherals; use crate::time::Hertz; use core::mem::MaybeUninit; @@ -44,3 +47,38 @@ cfg_if::cfg_if! { } } } + +pub(crate) mod sealed { + pub trait RccPeripheral { + fn reset(); + fn enable(); + fn disable(); + } +} + +pub trait RccPeripheral: sealed::RccPeripheral + 'static {} + +crate::pac::peripheral_rcc!( + ($inst:ident, $enable:ident, $reset:ident, $perien:ident, $perirst:ident) => { + impl sealed::RccPeripheral for peripherals::$inst { + fn enable() { + unsafe { + crate::pac::RCC.$enable().modify(|w| w.$perien(true)); + } + } + fn disable() { + unsafe { + crate::pac::RCC.$enable().modify(|w| w.$perien(false)); + } + } + fn reset() { + unsafe { + crate::pac::RCC.$reset().modify(|w| w.$perirst(true)); + crate::pac::RCC.$reset().modify(|w| w.$perirst(false)); + } + } + } + + impl RccPeripheral for peripherals::$inst {} + }; +); diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index 46fe817e..8f91ca5a 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs @@ -4,6 +4,7 @@ use crate::gpio::{AnyPin, Pin}; use crate::pac::gpio::vals::{Afr, Moder}; use crate::pac::gpio::Gpio; use crate::pac::spi; +use crate::rcc::RccPeripheral; use crate::spi::{ByteOrder, Config, Error, Instance, MisoPin, MosiPin, SckPin, WordSize}; use crate::time::Hertz; use core::marker::PhantomData; @@ -28,14 +29,14 @@ impl WordSize { } } -pub struct Spi<'d, T: Instance> { +pub struct Spi<'d, T: Instance + RccPeripheral> { sck: AnyPin, mosi: AnyPin, miso: AnyPin, phantom: PhantomData<&'d mut T>, } -impl<'d, T: Instance> Spi<'d, T> { +impl<'d, T: Instance + RccPeripheral> Spi<'d, T> { pub fn new( pclk: Hertz, _peri: impl Unborrow + 'd, @@ -63,6 +64,8 @@ impl<'d, T: Instance> Spi<'d, T> { let br = Self::compute_baud_rate(pclk, freq.into()); unsafe { + T::enable(); + T::reset(); T::regs().cr2().modify(|w| { w.set_ssoe(false); }); @@ -140,7 +143,7 @@ impl<'d, T: Instance> Spi<'d, T> { } } -impl<'d, T: Instance> Drop for Spi<'d, T> { +impl<'d, T: Instance + RccPeripheral> Drop for Spi<'d, T> { fn drop(&mut self) { unsafe { Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _); @@ -198,7 +201,7 @@ fn read_word(regs: &'static crate::pac::spi::Spi) -> Result { } } -impl<'d, T: Instance> embedded_hal::blocking::spi::Write for Spi<'d, T> { +impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Write for Spi<'d, T> { type Error = Error; fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { @@ -214,7 +217,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write for Spi<'d, T> { } } -impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer for Spi<'d, T> { +impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Transfer for Spi<'d, T> { type Error = Error; fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { @@ -230,7 +233,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer for Spi<'d, T> { } } -impl<'d, T: Instance> embedded_hal::blocking::spi::Write for Spi<'d, T> { +impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Write for Spi<'d, T> { type Error = Error; fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { @@ -246,7 +249,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write for Spi<'d, T> { } } -impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer for Spi<'d, T> { +impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Transfer for Spi<'d, T> { type Error = Error; fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> { diff --git a/stm32-metapac/build.rs b/stm32-metapac/build.rs index 083e06bf..91b76b2a 100644 --- a/stm32-metapac/build.rs +++ b/stm32-metapac/build.rs @@ -136,6 +136,7 @@ fn main() { let mut interrupt_table: Vec> = Vec::new(); let mut peripherals_table: Vec> = Vec::new(); let mut peripheral_pins_table: Vec> = Vec::new(); + let mut peripheral_rcc_table: Vec> = Vec::new(); let dma_base = chip .peripherals @@ -216,6 +217,19 @@ fn main() { }; assert_eq!(p.address, dma_base + dma_stride * dma_num); } + "spi" => { + if let Some(clock) = &p.clock { + let reg = clock.to_ascii_lowercase(); + let field = name.to_ascii_lowercase(); + peripheral_rcc_table.push(vec![ + name.clone(), + format!("{}enr", reg), + format!("{}rstr", reg), + format!("set_{}en", field), + format!("set_{}rst", field), + ]); + } + } _ => {} } } @@ -255,6 +269,7 @@ fn main() { make_table(&mut extra, "peripherals", &peripherals_table); make_table(&mut extra, "peripheral_versions", &peripheral_version_table); make_table(&mut extra, "peripheral_pins", &peripheral_pins_table); + make_table(&mut extra, "peripheral_rcc", &peripheral_rcc_table); for (module, version) in peripheral_versions { println!("loading {} {}", module, version);