stm32: remove paste and use refcount statics

This commit is contained in:
xoviat 2023-09-05 17:45:52 -05:00
parent 7622d2eb61
commit fd22f4fac5
3 changed files with 10 additions and 87 deletions

View file

@ -308,20 +308,11 @@ fn main() {
// ======== // ========
// Generate RccPeripheral impls // Generate RccPeripheral impls
// TODO: maybe get this from peripheral kind? Not sure let refcounted_peripherals = HashSet::from(["usart", "adc"]);
let mut refcounted_peripherals = HashSet::from(["usart"]);
let mut refcount_statics = HashSet::new(); let mut refcount_statics = HashSet::new();
if chip_name.starts_with("stm32f3") {
refcounted_peripherals.insert("adc");
}
for p in METADATA.peripherals { for p in METADATA.peripherals {
// generating RccPeripheral impl for H7 ADC3 would result in bad frequency if !singletons.contains(&p.name.to_string()) {
if !singletons.contains(&p.name.to_string())
|| (p.name == "ADC3" && METADATA.line.starts_with("STM32H7"))
|| (p.name.starts_with("ADC") && p.registers.as_ref().map_or(false, |r| r.version == "v4"))
{
continue; continue;
} }
@ -711,6 +702,10 @@ fn main() {
// ADC is special // ADC is special
if regs.kind == "adc" { if regs.kind == "adc" {
if p.rcc.is_none() {
continue;
}
let peri = format_ident!("{}", p.name); let peri = format_ident!("{}", p.name);
let pin_name = format_ident!("{}", pin.pin); let pin_name = format_ident!("{}", pin.pin);

View file

@ -56,7 +56,7 @@ pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc:
pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {}
pub trait InternalChannel<T>: sealed::InternalChannel<T> {} pub trait InternalChannel<T>: sealed::InternalChannel<T> {}
#[cfg(not(any(stm32h7, adc_f3)))] #[cfg(not(any(stm32h7, adc_f3, adc_v4)))]
foreach_peripheral!( foreach_peripheral!(
(adc, $inst:ident) => { (adc, $inst:ident) => {
impl crate::adc::sealed::Instance for peripherals::$inst { impl crate::adc::sealed::Instance for peripherals::$inst {
@ -77,9 +77,10 @@ foreach_peripheral!(
}; };
); );
#[cfg(any(stm32h7, adc_f3))] #[cfg(any(stm32h7, adc_f3, adc_v4))]
foreach_peripheral!( foreach_peripheral!(
(adc, ADC3) => { (adc, ADC3) => {
#[cfg(not(any(stm32g4x1, stm32g4x2, stm32g4x3, stm32g4x4)))]
impl crate::adc::sealed::Instance for peripherals::ADC3 { impl crate::adc::sealed::Instance for peripherals::ADC3 {
fn regs() -> crate::pac::adc::Adc { fn regs() -> crate::pac::adc::Adc {
crate::pac::ADC3 crate::pac::ADC3
@ -99,6 +100,7 @@ foreach_peripheral!(
} }
} }
#[cfg(not(any(stm32g4x1, stm32g4x2, stm32g4x3, stm32g4x4)))]
impl crate::adc::Instance for peripherals::ADC3 {} impl crate::adc::Instance for peripherals::ADC3 {}
}; };
(adc, ADC4) => { (adc, ADC4) => {

View file

@ -1,10 +1,7 @@
use core::sync::atomic::{AtomicU8, Ordering};
use embedded_hal_02::blocking::delay::DelayUs; use embedded_hal_02::blocking::delay::DelayUs;
#[allow(unused)] #[allow(unused)]
use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel}; use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
use pac::adccommon::vals::Presc; use pac::adccommon::vals::Presc;
use paste::paste;
use super::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; use super::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
use crate::time::Hertz; use crate::time::Hertz;
@ -59,77 +56,6 @@ impl<T: Instance> super::sealed::InternalChannel<T> for Vbat {
} }
} }
static ADC12_ENABLE_COUNTER: AtomicU8 = AtomicU8::new(0);
#[cfg(any(stm32g4x3, stm32g4x4))]
static ADC345_ENABLE_COUNTER: AtomicU8 = AtomicU8::new(0);
macro_rules! rcc_peripheral {
($adc_name:ident, $freqs:ident, $ahb:ident, $reg:ident $(, $counter:ident )? ) => {
impl crate::rcc::sealed::RccPeripheral for crate::peripherals::$adc_name {
fn frequency() -> crate::time::Hertz {
critical_section::with(|_| {
match unsafe { crate::rcc::get_freqs() }.$freqs {
Some(ck) => ck,
None => panic!("Invalid ADC clock configuration, AdcClockSource was likely not properly configured.")
}
})
}
fn enable() {
critical_section::with(|_| {
paste!{crate::pac::RCC.[< $ahb enr >]().modify(|w| w.[< set_ $reg en >](true))}
});
$ ( $counter.fetch_add(1, Ordering::SeqCst); )?
}
fn disable() {
$ ( if $counter.load(Ordering::SeqCst) == 1 )? {
critical_section::with(|_| {
paste!{crate::pac::RCC.[< $ahb enr >]().modify(|w| w.[< set_ $reg en >](false))}
})
}
$ ( $counter.fetch_sub(1, Ordering::SeqCst); )?
}
fn reset() {
$ ( if $counter.load(Ordering::SeqCst) == 1 )? {
critical_section::with(|_| {
paste!{crate::pac::RCC.[< $ahb rstr >]().modify(|w| w.[< set_ $reg rst >](true))}
paste!{crate::pac::RCC.[< $ahb rstr >]().modify(|w| w.[< set_ $reg rst >](false))}
});
}
}
}
impl crate::rcc::RccPeripheral for crate::peripherals::$adc_name {}
};
}
#[cfg(stm32g4)]
foreach_peripheral!(
(adc, ADC1) => { rcc_peripheral!(ADC1, adc, ahb2, adc12, ADC12_ENABLE_COUNTER); };
(adc, ADC2) => { rcc_peripheral!(ADC2, adc, ahb2, adc12, ADC12_ENABLE_COUNTER); };
);
#[cfg(stm32g4x1)]
foreach_peripheral!(
(adc, ADC3) => { rcc_peripheral!(ADC3, adc34, ahb2, adc345); };
);
#[cfg(any(stm32g4x3, stm32g4x4))]
foreach_peripheral!(
(adc, ADC3) => { rcc_peripheral!(ADC3, adc34, ahb2, adc345, ADC345_ENABLE_COUNTER); };
(adc, ADC4) => { rcc_peripheral!(ADC4, adc34, ahb2, adc345, ADC345_ENABLE_COUNTER); };
(adc, ADC5) => { rcc_peripheral!(ADC5, adc34, ahb2, adc345, ADC345_ENABLE_COUNTER); };
);
#[cfg(stm32h7)]
foreach_peripheral!(
(adc, ADC1) => { rcc_peripheral!(ADC1, adc, ahb1, adc12, ADC12_ENABLE_COUNTER); };
(adc, ADC2) => { rcc_peripheral!(ADC2, adc, ahb1, adc12, ADC12_ENABLE_COUNTER); };
(adc, ADC3) => { rcc_peripheral!(ADC3, adc, ahb4, adc3); };
);
// NOTE (unused): The prescaler enum closely copies the hardware capabilities, // NOTE (unused): The prescaler enum closely copies the hardware capabilities,
// but high prescaling doesn't make a lot of sense in the current implementation and is ommited. // but high prescaling doesn't make a lot of sense in the current implementation and is ommited.
#[allow(unused)] #[allow(unused)]