From bb2d6c854273ea57eb7d898c0f67dd9f8020f3e7 Mon Sep 17 00:00:00 2001 From: Olle Sandberg Date: Tue, 5 Sep 2023 12:10:31 +0200 Subject: [PATCH 1/3] adc_v3: replace cfg(stm32g0) + friends with cfg(adc_g0) Since any MCU (not just STM32G0) using adc_g0 should probably be handled the same way. --- embassy-stm32/src/adc/mod.rs | 4 ++-- embassy-stm32/src/adc/v3.rs | 39 +++++++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index 0eeadfa9..013debca 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs @@ -33,7 +33,7 @@ pub struct Adc<'d, T: Instance> { pub(crate) mod sealed { pub trait Instance { fn regs() -> crate::pac::adc::Adc; - #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2)))] + #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_g0)))] fn common_regs() -> crate::pac::adccommon::AdcCommon; #[cfg(adc_f3)] fn frequency() -> crate::time::Hertz; @@ -63,7 +63,7 @@ foreach_peripheral!( fn regs() -> crate::pac::adc::Adc { crate::pac::$inst } - #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2)))] + #[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) => { diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index 821cc7f6..7d63b0ce 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs @@ -26,9 +26,9 @@ pub struct VrefInt; impl AdcPin for VrefInt {} impl super::sealed::AdcPin for VrefInt { fn channel(&self) -> u8 { - #[cfg(not(stm32g0))] + #[cfg(not(adc_g0))] let val = 0; - #[cfg(stm32g0)] + #[cfg(adc_g0)] let val = 13; val } @@ -38,9 +38,9 @@ pub struct Temperature; impl AdcPin for Temperature {} impl super::sealed::AdcPin for Temperature { fn channel(&self) -> u8 { - #[cfg(not(stm32g0))] + #[cfg(not(adc_g0))] let val = 17; - #[cfg(stm32g0)] + #[cfg(adc_g0)] let val = 12; val } @@ -50,9 +50,9 @@ pub struct Vbat; impl AdcPin for Vbat {} impl super::sealed::AdcPin for Vbat { fn channel(&self) -> u8 { - #[cfg(not(stm32g0))] + #[cfg(not(adc_g0))] let val = 18; - #[cfg(stm32g0)] + #[cfg(adc_g0)] let val = 14; val } @@ -92,9 +92,14 @@ impl<'d, T: Instance> Adc<'d, T> { } pub fn enable_vrefint(&self, delay: &mut impl DelayUs) -> VrefInt { + #[cfg(not(adc_g0))] T::common_regs().ccr().modify(|reg| { reg.set_vrefen(true); }); + #[cfg(adc_g0)] + T::regs().ccr().modify(|reg| { + reg.set_vrefen(true); + }); // "Table 24. Embedded internal voltage reference" states that it takes a maximum of 12 us // to stabilize the internal voltage reference, we wait a little more. @@ -106,17 +111,27 @@ impl<'d, T: Instance> Adc<'d, T> { } pub fn enable_temperature(&self) -> Temperature { + #[cfg(not(adc_g0))] T::common_regs().ccr().modify(|reg| { reg.set_ch17sel(true); }); + #[cfg(adc_g0)] + T::regs().ccr().modify(|reg| { + reg.set_tsen(true); + }); Temperature {} } pub fn enable_vbat(&self) -> Vbat { + #[cfg(not(adc_g0))] T::common_regs().ccr().modify(|reg| { reg.set_ch18sel(true); }); + #[cfg(adc_g0)] + T::regs().ccr().modify(|reg| { + reg.set_vbaten(true); + }); Vbat {} } @@ -126,9 +141,9 @@ impl<'d, T: Instance> Adc<'d, T> { } pub fn set_resolution(&mut self, resolution: Resolution) { - #[cfg(not(stm32g0))] + #[cfg(not(adc_g0))] T::regs().cfgr().modify(|reg| reg.set_res(resolution.into())); - #[cfg(stm32g0)] + #[cfg(adc_g0)] T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into())); } @@ -182,9 +197,9 @@ impl<'d, T: Instance> Adc<'d, T> { Self::set_channel_sample_time(pin.channel(), self.sample_time); // Select channel - #[cfg(not(stm32g0))] + #[cfg(not(adc_g0))] T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel())); - #[cfg(stm32g0)] + #[cfg(adc_g0)] T::regs().chselr().write(|reg| reg.set_chsel(1 << pin.channel())); // Some models are affected by an erratum: @@ -203,12 +218,12 @@ impl<'d, T: Instance> Adc<'d, T> { val } - #[cfg(stm32g0)] + #[cfg(adc_g0)] fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) { T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.into())); } - #[cfg(not(stm32g0))] + #[cfg(not(adc_g0))] fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { let sample_time = sample_time.into(); T::regs() From 0d3ff34d80c98f62a1f6e8b4df1226f6c36337a0 Mon Sep 17 00:00:00 2001 From: Olle Sandberg Date: Tue, 5 Sep 2023 12:14:04 +0200 Subject: [PATCH 2/3] adc: enable ADC and clock selection for STM32WLx --- embassy-stm32/src/adc/v3.rs | 2 +- embassy-stm32/src/rcc/wl.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index 7d63b0ce..011ecc28 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs @@ -13,7 +13,7 @@ pub const VREF_CALIB_MV: u32 = 3000; /// configuration. fn enable() { critical_section::with(|_| { - #[cfg(stm32h7)] + #[cfg(any(stm32h7, stm32wl))] crate::pac::RCC.apb2enr().modify(|w| w.set_adcen(true)); #[cfg(stm32g0)] crate::pac::RCC.apbenr2().modify(|w| w.set_adcen(true)); diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index e33690d1..47be00ad 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs @@ -1,4 +1,5 @@ pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; +use crate::pac::rcc::vals::Adcsel; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks}; @@ -106,6 +107,29 @@ impl Into for MSIRange { } } +#[derive(Clone, Copy)] +pub enum AdcClockSource { + HSI16, + PLLPCLK, + SYSCLK, +} + +impl AdcClockSource { + pub fn adcsel(&self) -> Adcsel { + match self { + AdcClockSource::HSI16 => Adcsel::HSI16, + AdcClockSource::PLLPCLK => Adcsel::PLLPCLK, + AdcClockSource::SYSCLK => Adcsel::SYSCLK, + } + } +} + +impl Default for AdcClockSource { + fn default() -> Self { + Self::HSI16 + } +} + /// Clocks configutation pub struct Config { pub mux: ClockSrc, @@ -116,6 +140,7 @@ pub struct Config { pub enable_lsi: bool, pub enable_rtc_apb: bool, pub rtc_mux: RtcClockSource, + pub adc_clock_source: AdcClockSource, } impl Default for Config { @@ -130,6 +155,7 @@ impl Default for Config { enable_lsi: false, enable_rtc_apb: false, rtc_mux: RtcClockSource::LSI, + adc_clock_source: AdcClockSource::default(), } } } @@ -299,6 +325,9 @@ pub(crate) unsafe fn init(config: Config) { w.set_ppre2(config.apb2_pre.into()); }); + // ADC clock MUX + RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source.adcsel())); + // TODO: switch voltage range if config.enable_lsi { From c356585a5918f1c66f5fc0e12edd82094dacd5c9 Mon Sep 17 00:00:00 2001 From: Olle Sandberg Date: Wed, 6 Sep 2023 11:49:18 +0200 Subject: [PATCH 3/3] update metapac tag --- embassy-stm32/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 30694596..ded58aee 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -58,7 +58,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7e2310f49fa123fbc3225b91be73522b212703f0" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-eaa4987e523408dfb31c1b76765dd345d2761373" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -77,7 +77,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7e2310f49fa123fbc3225b91be73522b212703f0", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-eaa4987e523408dfb31c1b76765dd345d2761373", default-features = false, features = ["metadata"]} [features] default = ["rt"]