aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Lilleengen <[email protected]>2021-06-02 16:34:37 +0200
committerUlf Lilleengen <[email protected]>2021-06-08 17:20:29 +0200
commitee3b82b74347cef97b58fee075972e175f98874b (patch)
tree328641858941b22f38814b9e0f4bb5a797998d5b
parentaf0f8082f079bb80d8b478331ff505f5462a9120 (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.rs2
-rw-r--r--embassy-stm32/src/rcc/mod.rs38
-rw-r--r--embassy-stm32/src/spi/v2.rs17
-rw-r--r--stm32-metapac/build.rs15
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
3use crate::peripherals;
1use crate::time::Hertz; 4use crate::time::Hertz;
2use core::mem::MaybeUninit; 5use core::mem::MaybeUninit;
3 6
@@ -44,3 +47,38 @@ cfg_if::cfg_if! {
44 } 47 }
45 } 48 }
46} 49}
50
51pub(crate) mod sealed {
52 pub trait RccPeripheral {
53 fn reset();
54 fn enable();
55 fn disable();
56 }
57}
58
59pub trait RccPeripheral: sealed::RccPeripheral + 'static {}
60
61crate::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};
4use crate::pac::gpio::vals::{Afr, Moder}; 4use crate::pac::gpio::vals::{Afr, Moder};
5use crate::pac::gpio::Gpio; 5use crate::pac::gpio::Gpio;
6use crate::pac::spi; 6use crate::pac::spi;
7use crate::rcc::RccPeripheral;
7use crate::spi::{ByteOrder, Config, Error, Instance, MisoPin, MosiPin, SckPin, WordSize}; 8use crate::spi::{ByteOrder, Config, Error, Instance, MisoPin, MosiPin, SckPin, WordSize};
8use crate::time::Hertz; 9use crate::time::Hertz;
9use core::marker::PhantomData; 10use core::marker::PhantomData;
@@ -28,14 +29,14 @@ impl WordSize {
28 } 29 }
29} 30}
30 31
31pub struct Spi<'d, T: Instance> { 32pub 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
38impl<'d, T: Instance> Spi<'d, T> { 39impl<'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
143impl<'d, T: Instance> Drop for Spi<'d, T> { 146impl<'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
201impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> { 204impl<'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
217impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> { 220impl<'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
233impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> { 236impl<'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
249impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T> { 252impl<'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);