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.
This commit is contained in:
parent
af0f8082f0
commit
ee3b82b743
@ -51,3 +51,5 @@ crate::pac::peripheral_pins!(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
#![macro_use]
|
||||||
|
|
||||||
|
use crate::peripherals;
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
use core::mem::MaybeUninit;
|
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 {}
|
||||||
|
};
|
||||||
|
);
|
||||||
|
@ -4,6 +4,7 @@ use crate::gpio::{AnyPin, Pin};
|
|||||||
use crate::pac::gpio::vals::{Afr, Moder};
|
use crate::pac::gpio::vals::{Afr, Moder};
|
||||||
use crate::pac::gpio::Gpio;
|
use crate::pac::gpio::Gpio;
|
||||||
use crate::pac::spi;
|
use crate::pac::spi;
|
||||||
|
use crate::rcc::RccPeripheral;
|
||||||
use crate::spi::{ByteOrder, Config, Error, Instance, MisoPin, MosiPin, SckPin, WordSize};
|
use crate::spi::{ByteOrder, Config, Error, Instance, MisoPin, MosiPin, SckPin, WordSize};
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
use core::marker::PhantomData;
|
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,
|
sck: AnyPin,
|
||||||
mosi: AnyPin,
|
mosi: AnyPin,
|
||||||
miso: AnyPin,
|
miso: AnyPin,
|
||||||
phantom: PhantomData<&'d mut T>,
|
phantom: PhantomData<&'d mut T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> Spi<'d, T> {
|
impl<'d, T: Instance + RccPeripheral> Spi<'d, T> {
|
||||||
pub fn new<F>(
|
pub fn new<F>(
|
||||||
pclk: Hertz,
|
pclk: Hertz,
|
||||||
_peri: impl Unborrow<Target = T> + 'd,
|
_peri: impl Unborrow<Target = T> + 'd,
|
||||||
@ -63,6 +64,8 @@ impl<'d, T: Instance> Spi<'d, T> {
|
|||||||
let br = Self::compute_baud_rate(pclk, freq.into());
|
let br = Self::compute_baud_rate(pclk, freq.into());
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
T::enable();
|
||||||
|
T::reset();
|
||||||
T::regs().cr2().modify(|w| {
|
T::regs().cr2().modify(|w| {
|
||||||
w.set_ssoe(false);
|
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) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _);
|
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> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> {
|
impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
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> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> {
|
impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::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<u8> for Spi<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> {
|
impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> {
|
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> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T> {
|
impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> {
|
fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> {
|
||||||
|
@ -136,6 +136,7 @@ fn main() {
|
|||||||
let mut interrupt_table: Vec<Vec<String>> = Vec::new();
|
let mut interrupt_table: Vec<Vec<String>> = Vec::new();
|
||||||
let mut peripherals_table: Vec<Vec<String>> = Vec::new();
|
let mut peripherals_table: Vec<Vec<String>> = Vec::new();
|
||||||
let mut peripheral_pins_table: Vec<Vec<String>> = Vec::new();
|
let mut peripheral_pins_table: Vec<Vec<String>> = Vec::new();
|
||||||
|
let mut peripheral_rcc_table: Vec<Vec<String>> = Vec::new();
|
||||||
|
|
||||||
let dma_base = chip
|
let dma_base = chip
|
||||||
.peripherals
|
.peripherals
|
||||||
@ -216,6 +217,19 @@ fn main() {
|
|||||||
};
|
};
|
||||||
assert_eq!(p.address, dma_base + dma_stride * dma_num);
|
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, "peripherals", &peripherals_table);
|
||||||
make_table(&mut extra, "peripheral_versions", &peripheral_version_table);
|
make_table(&mut extra, "peripheral_versions", &peripheral_version_table);
|
||||||
make_table(&mut extra, "peripheral_pins", &peripheral_pins_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 {
|
for (module, version) in peripheral_versions {
|
||||||
println!("loading {} {}", module, version);
|
println!("loading {} {}", module, version);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user