diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index bb81736b..6d7f788d 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -817,6 +817,17 @@ fn main() { let mut peripherals_table: Vec> = Vec::new(); let mut pins_table: Vec> = Vec::new(); let mut dma_channels_table: Vec> = Vec::new(); + let mut adc_common_table: Vec> = Vec::new(); + + /* + If ADC3_COMMON exists, ADC3 and higher are assigned to it + All other ADCs are assigned to ADC_COMMON + + ADC3 and higher are assigned to the adc34 clock in the table + The adc3_common cfg directive is added if ADC3_COMMON exists + */ + let has_adc3 = METADATA.peripherals.iter().find(|p| p.name == "ADC3_COMMON").is_some(); + let set_adc345 = HashSet::from(["ADC3", "ADC4", "ADC5"]); for m in METADATA .memory @@ -854,6 +865,17 @@ fn main() { } } + if regs.kind == "adc" { + let (adc_common, adc_clock) = if set_adc345.contains(p.name) && has_adc3 { + ("ADC3_COMMON", "adc34") + } else { + ("ADC_COMMON", "adc") + }; + + let row = vec![p.name.to_string(), adc_common.to_string(), adc_clock.to_string()]; + adc_common_table.push(row); + } + for irq in p.interrupts { let row = vec![ p.name.to_string(), @@ -932,6 +954,7 @@ fn main() { make_table(&mut m, "foreach_peripheral", &peripherals_table); make_table(&mut m, "foreach_pin", &pins_table); make_table(&mut m, "foreach_dma_channel", &dma_channels_table); + make_table(&mut m, "foreach_adc", &adc_common_table); let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); let out_file = out_dir.join("_macros.rs").to_string_lossy().to_string(); @@ -973,6 +996,12 @@ fn main() { println!("cargo:rustc-cfg={}x{}", &chip_name[..9], &chip_name[10..11]); } + // ======= + // ADC3_COMMON is present + if has_adc3 { + println!("cargo:rustc-cfg={}", "adc3_common"); + } + // ======= // Features for targeting groups of chips diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index d1cfd8fb..9334deac 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs @@ -56,127 +56,21 @@ pub trait Instance: sealed::Instance + crate::Peripheral

+ crate::rcc: pub trait AdcPin: sealed::AdcPin {} pub trait InternalChannel: sealed::InternalChannel {} -#[cfg(not(any(stm32h7, adc_f3, adc_v4)))] -foreach_peripheral!( - (adc, $inst:ident) => { +foreach_adc!( + ($inst:ident, $common_inst:ident, $clock:ident) => { impl crate::adc::sealed::Instance for peripherals::$inst { fn regs() -> crate::pac::adc::Adc { crate::pac::$inst } + #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_g0)))] fn common_regs() -> crate::pac::adccommon::AdcCommon { - foreach_peripheral!{ - (adccommon, $common_inst:ident) => { - return crate::pac::$common_inst - }; - } - } - } - - impl crate::adc::Instance for peripherals::$inst {} - }; -); - -#[cfg(any(stm32h7, adc_f3, adc_v4))] -foreach_peripheral!( - (adc, ADC3) => { - impl crate::adc::sealed::Instance for peripherals::ADC3 { - fn regs() -> crate::pac::adc::Adc { - crate::pac::ADC3 - } - #[cfg(all(not(adc_f1), not(adc_v1)))] - #[allow(unreachable_code)] - fn common_regs() -> crate::pac::adccommon::AdcCommon { - foreach_peripheral!{ - (adccommon, ADC3_COMMON) => { - return crate::pac::ADC3_COMMON - }; - // Fall back to ADC_COMMON if ADC3_COMMON does not exist - (adccommon, ADC_COMMON) => { - return crate::pac::ADC_COMMON - }; - } + return crate::pac::$common_inst } #[cfg(adc_f3)] fn frequency() -> crate::time::Hertz { - unsafe { crate::rcc::get_freqs() }.adc34.unwrap() - } - } - - impl crate::adc::Instance for peripherals::ADC3 {} - }; - (adc, ADC4) => { - impl crate::adc::sealed::Instance for peripherals::ADC4 { - fn regs() -> crate::pac::adc::Adc { - crate::pac::ADC4 - } - #[cfg(not(any(adc_f1, adc_v1)))] - #[allow(unreachable_code)] - fn common_regs() -> crate::pac::adccommon::AdcCommon { - foreach_peripheral!{ - (adccommon, ADC3_COMMON) => { - return crate::pac::ADC3_COMMON - }; - // Fall back to ADC_COMMON if ADC3_COMMON does not exist - (adccommon, ADC_COMMON) => { - return crate::pac::ADC_COMMON - }; - } - } - - #[cfg(adc_f3)] - fn frequency() -> crate::time::Hertz { - unsafe { crate::rcc::get_freqs() }.adc34.unwrap() - } - } - - impl crate::adc::Instance for peripherals::ADC4 {} - }; - (adc, ADC5) => { - impl crate::adc::sealed::Instance for peripherals::ADC5 { - fn regs() -> crate::pac::adc::Adc { - crate::pac::ADC5 - } - #[cfg(not(any(adc_f1, adc_v1)))] - #[allow(unreachable_code)] - fn common_regs() -> crate::pac::adccommon::AdcCommon { - foreach_peripheral!{ - (adccommon, ADC3_COMMON) => { - return crate::pac::ADC3_COMMON - }; - // Fall back to ADC_COMMON if ADC3_COMMON does not exist - (adccommon, ADC_COMMON) => { - return crate::pac::ADC_COMMON - }; - } - } - - #[cfg(adc_f3)] - fn frequency() -> crate::time::Hertz { - unsafe { crate::rcc::get_freqs() }.adc34.unwrap() - } - } - - impl crate::adc::Instance for peripherals::ADC5 {} - }; - (adc, $inst:ident) => { - impl crate::adc::sealed::Instance for peripherals::$inst { - fn regs() -> crate::pac::adc::Adc { - crate::pac::$inst - } - #[cfg(not(any(adc_f1, adc_v1)))] - fn common_regs() -> crate::pac::adccommon::AdcCommon { - foreach_peripheral!{ - (adccommon, ADC_COMMON) => { - return crate::pac::ADC_COMMON - }; - } - } - - #[cfg(adc_f3)] - fn frequency() -> crate::time::Hertz { - unsafe { crate::rcc::get_freqs() }.adc.unwrap() + unsafe { crate::rcc::get_freqs() }.$clock.unwrap() } } diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index cbbe4f98..630dbd4f 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs @@ -280,7 +280,7 @@ pub(crate) unsafe fn init(config: Config) { } }); - #[cfg(rcc_f3)] + #[cfg(all(rcc_f3, adc3_common))] let adc34 = config.adc.map(|adc| { if !adc.is_bus() { RCC.cfgr2().modify(|w| { @@ -291,9 +291,13 @@ pub(crate) unsafe fn init(config: Config) { Hertz(sysclk / adc as u32) }) } else { - // TODO: need to use only if adc32_common is present + crate::pac::ADC3_COMMON.ccr().modify(|w| { + assert!(!(adc.bus_div() == 1 && hpre_bits != Hpre::DIV1)); - todo!() + w.set_ckmode(adc.into()); + + Hertz(sysclk / adc.bus_div() as u32) + }) } }); @@ -323,8 +327,10 @@ pub(crate) unsafe fn init(config: Config) { ahb1: Hertz(hclk), #[cfg(rcc_f3)] adc: adc, - #[cfg(rcc_f3)] + #[cfg(all(rcc_f3, adc3_common))] adc34: adc34, + #[cfg(all(rcc_f3, not(adc3_common)))] + adc34: None, #[cfg(stm32f334)] hrtim: hrtim, });