diff options
| author | Ulf Lilleengen <[email protected]> | 2021-06-02 16:34:37 +0200 |
|---|---|---|
| committer | Ulf Lilleengen <[email protected]> | 2021-06-08 17:20:29 +0200 |
| commit | ee3b82b74347cef97b58fee075972e175f98874b (patch) | |
| tree | 328641858941b22f38814b9e0f4bb5a797998d5b | |
| parent | af0f8082f079bb80d8b478331ff505f5462a9120 (diff) | |
Auto generate SPI v2 clock enable
Adds RccPeripheral trait for peripherals implementing clock enable and reset for a given peripheral.
Add macro table generting implementations of RccPeripheral for peripherals with clock set, currently restricted to SPI.
| -rw-r--r-- | embassy-stm32/src/dac/mod.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 38 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v2.rs | 17 | ||||
| -rw-r--r-- | stm32-metapac/build.rs | 15 |
4 files changed, 65 insertions, 7 deletions
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs index 0a15563ef..c74261595 100644 --- a/embassy-stm32/src/dac/mod.rs +++ b/embassy-stm32/src/dac/mod.rs | |||
| @@ -51,3 +51,5 @@ crate::pac::peripheral_pins!( | |||
| 51 | } | 51 | } |
| 52 | }; | 52 | }; |
| 53 | ); | 53 | ); |
| 54 | |||
| 55 | |||
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 7112ad02f..6ad90eb82 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -1,3 +1,6 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | use crate::peripherals; | ||
| 1 | use crate::time::Hertz; | 4 | use crate::time::Hertz; |
| 2 | use core::mem::MaybeUninit; | 5 | use core::mem::MaybeUninit; |
| 3 | 6 | ||
| @@ -44,3 +47,38 @@ cfg_if::cfg_if! { | |||
| 44 | } | 47 | } |
| 45 | } | 48 | } |
| 46 | } | 49 | } |
| 50 | |||
| 51 | pub(crate) mod sealed { | ||
| 52 | pub trait RccPeripheral { | ||
| 53 | fn reset(); | ||
| 54 | fn enable(); | ||
| 55 | fn disable(); | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | pub trait RccPeripheral: sealed::RccPeripheral + 'static {} | ||
| 60 | |||
| 61 | crate::pac::peripheral_rcc!( | ||
| 62 | ($inst:ident, $enable:ident, $reset:ident, $perien:ident, $perirst:ident) => { | ||
| 63 | impl sealed::RccPeripheral for peripherals::$inst { | ||
| 64 | fn enable() { | ||
| 65 | unsafe { | ||
| 66 | crate::pac::RCC.$enable().modify(|w| w.$perien(true)); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | fn disable() { | ||
| 70 | unsafe { | ||
| 71 | crate::pac::RCC.$enable().modify(|w| w.$perien(false)); | ||
| 72 | } | ||
| 73 | } | ||
| 74 | fn reset() { | ||
| 75 | unsafe { | ||
| 76 | crate::pac::RCC.$reset().modify(|w| w.$perirst(true)); | ||
| 77 | crate::pac::RCC.$reset().modify(|w| w.$perirst(false)); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | impl RccPeripheral for peripherals::$inst {} | ||
| 83 | }; | ||
| 84 | ); | ||
diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs index 46fe817ea..8f91ca5a7 100644 --- a/embassy-stm32/src/spi/v2.rs +++ b/embassy-stm32/src/spi/v2.rs | |||
| @@ -4,6 +4,7 @@ use crate::gpio::{AnyPin, Pin}; | |||
| 4 | use crate::pac::gpio::vals::{Afr, Moder}; | 4 | use crate::pac::gpio::vals::{Afr, Moder}; |
| 5 | use crate::pac::gpio::Gpio; | 5 | use crate::pac::gpio::Gpio; |
| 6 | use crate::pac::spi; | 6 | use crate::pac::spi; |
| 7 | use crate::rcc::RccPeripheral; | ||
| 7 | use crate::spi::{ByteOrder, Config, Error, Instance, MisoPin, MosiPin, SckPin, WordSize}; | 8 | use crate::spi::{ByteOrder, Config, Error, Instance, MisoPin, MosiPin, SckPin, WordSize}; |
| 8 | use crate::time::Hertz; | 9 | use crate::time::Hertz; |
| 9 | use core::marker::PhantomData; | 10 | use core::marker::PhantomData; |
| @@ -28,14 +29,14 @@ impl WordSize { | |||
| 28 | } | 29 | } |
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | pub struct Spi<'d, T: Instance> { | 32 | pub struct Spi<'d, T: Instance + RccPeripheral> { |
| 32 | sck: AnyPin, | 33 | sck: AnyPin, |
| 33 | mosi: AnyPin, | 34 | mosi: AnyPin, |
| 34 | miso: AnyPin, | 35 | miso: AnyPin, |
| 35 | phantom: PhantomData<&'d mut T>, | 36 | phantom: PhantomData<&'d mut T>, |
| 36 | } | 37 | } |
| 37 | 38 | ||
| 38 | impl<'d, T: Instance> Spi<'d, T> { | 39 | impl<'d, T: Instance + RccPeripheral> Spi<'d, T> { |
| 39 | pub fn new<F>( | 40 | pub fn new<F>( |
| 40 | pclk: Hertz, | 41 | pclk: Hertz, |
| 41 | _peri: impl Unborrow<Target = T> + 'd, | 42 | _peri: impl Unborrow<Target = T> + 'd, |
| @@ -63,6 +64,8 @@ impl<'d, T: Instance> Spi<'d, T> { | |||
| 63 | let br = Self::compute_baud_rate(pclk, freq.into()); | 64 | let br = Self::compute_baud_rate(pclk, freq.into()); |
| 64 | 65 | ||
| 65 | unsafe { | 66 | unsafe { |
| 67 | T::enable(); | ||
| 68 | T::reset(); | ||
| 66 | T::regs().cr2().modify(|w| { | 69 | T::regs().cr2().modify(|w| { |
| 67 | w.set_ssoe(false); | 70 | w.set_ssoe(false); |
| 68 | }); | 71 | }); |
| @@ -140,7 +143,7 @@ impl<'d, T: Instance> Spi<'d, T> { | |||
| 140 | } | 143 | } |
| 141 | } | 144 | } |
| 142 | 145 | ||
| 143 | impl<'d, T: Instance> Drop for Spi<'d, T> { | 146 | impl<'d, T: Instance + RccPeripheral> Drop for Spi<'d, T> { |
| 144 | fn drop(&mut self) { | 147 | fn drop(&mut self) { |
| 145 | unsafe { | 148 | unsafe { |
| 146 | Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _); | 149 | Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _); |
| @@ -198,7 +201,7 @@ fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> { | |||
| 198 | } | 201 | } |
| 199 | } | 202 | } |
| 200 | 203 | ||
| 201 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> { | 204 | impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> { |
| 202 | type Error = Error; | 205 | type Error = Error; |
| 203 | 206 | ||
| 204 | fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { | 207 | fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { |
| @@ -214,7 +217,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> { | |||
| 214 | } | 217 | } |
| 215 | } | 218 | } |
| 216 | 219 | ||
| 217 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> { | 220 | impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> { |
| 218 | type Error = Error; | 221 | type Error = Error; |
| 219 | 222 | ||
| 220 | fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { | 223 | 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<u8> for Spi<'d, T> { | |||
| 230 | } | 233 | } |
| 231 | } | 234 | } |
| 232 | 235 | ||
| 233 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> { | 236 | impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> { |
| 234 | type Error = Error; | 237 | type Error = Error; |
| 235 | 238 | ||
| 236 | fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { | 239 | fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { |
| @@ -246,7 +249,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> { | |||
| 246 | } | 249 | } |
| 247 | } | 250 | } |
| 248 | 251 | ||
| 249 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T> { | 252 | impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T> { |
| 250 | type Error = Error; | 253 | type Error = Error; |
| 251 | 254 | ||
| 252 | fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> { | 255 | 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 083e06bfd..91b76b2a4 100644 --- a/stm32-metapac/build.rs +++ b/stm32-metapac/build.rs | |||
| @@ -136,6 +136,7 @@ fn main() { | |||
| 136 | let mut interrupt_table: Vec<Vec<String>> = Vec::new(); | 136 | let mut interrupt_table: Vec<Vec<String>> = Vec::new(); |
| 137 | let mut peripherals_table: Vec<Vec<String>> = Vec::new(); | 137 | let mut peripherals_table: Vec<Vec<String>> = Vec::new(); |
| 138 | let mut peripheral_pins_table: Vec<Vec<String>> = Vec::new(); | 138 | let mut peripheral_pins_table: Vec<Vec<String>> = Vec::new(); |
| 139 | let mut peripheral_rcc_table: Vec<Vec<String>> = Vec::new(); | ||
| 139 | 140 | ||
| 140 | let dma_base = chip | 141 | let dma_base = chip |
| 141 | .peripherals | 142 | .peripherals |
| @@ -216,6 +217,19 @@ fn main() { | |||
| 216 | }; | 217 | }; |
| 217 | assert_eq!(p.address, dma_base + dma_stride * dma_num); | 218 | assert_eq!(p.address, dma_base + dma_stride * dma_num); |
| 218 | } | 219 | } |
| 220 | "spi" => { | ||
| 221 | if let Some(clock) = &p.clock { | ||
| 222 | let reg = clock.to_ascii_lowercase(); | ||
| 223 | let field = name.to_ascii_lowercase(); | ||
| 224 | peripheral_rcc_table.push(vec![ | ||
| 225 | name.clone(), | ||
| 226 | format!("{}enr", reg), | ||
| 227 | format!("{}rstr", reg), | ||
| 228 | format!("set_{}en", field), | ||
| 229 | format!("set_{}rst", field), | ||
| 230 | ]); | ||
| 231 | } | ||
| 232 | } | ||
| 219 | _ => {} | 233 | _ => {} |
| 220 | } | 234 | } |
| 221 | } | 235 | } |
| @@ -255,6 +269,7 @@ fn main() { | |||
| 255 | make_table(&mut extra, "peripherals", &peripherals_table); | 269 | make_table(&mut extra, "peripherals", &peripherals_table); |
| 256 | make_table(&mut extra, "peripheral_versions", &peripheral_version_table); | 270 | make_table(&mut extra, "peripheral_versions", &peripheral_version_table); |
| 257 | make_table(&mut extra, "peripheral_pins", &peripheral_pins_table); | 271 | make_table(&mut extra, "peripheral_pins", &peripheral_pins_table); |
| 272 | make_table(&mut extra, "peripheral_rcc", &peripheral_rcc_table); | ||
| 258 | 273 | ||
| 259 | for (module, version) in peripheral_versions { | 274 | for (module, version) in peripheral_versions { |
| 260 | println!("loading {} {}", module, version); | 275 | println!("loading {} {}", module, version); |
