From bb2d6c854273ea57eb7d898c0f67dd9f8020f3e7 Mon Sep 17 00:00:00 2001
From: Olle Sandberg <olle@b3rg.se>
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 0eeadfa93..013debca8 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 821cc7f6a..7d63b0cee 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -26,9 +26,9 @@ pub struct VrefInt;
 impl<T: Instance> AdcPin<T> for VrefInt {}
 impl<T: Instance> super::sealed::AdcPin<T> 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<T: Instance> AdcPin<T> for Temperature {}
 impl<T: Instance> super::sealed::AdcPin<T> 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<T: Instance> AdcPin<T> for Vbat {}
 impl<T: Instance> super::sealed::AdcPin<T> 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<u32>) -> 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 <olle@b3rg.se>
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 7d63b0cee..011ecc281 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 e33690d10..47be00ad8 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<u8> 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 <olle@b3rg.se>
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 306945962..ded58aee3 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"]