From b32ff0c8f790379074c38d0409a3bf7709023f8b Mon Sep 17 00:00:00 2001 From: Thomas Giesel Date: Thu, 24 Apr 2025 22:15:41 +0200 Subject: [PATCH 1/2] Update opamp code to current stm32-metapac Some trivial enums have been removed from the OpAmp API in stm32-metapac, this commit updates the HAL accordingly. --- embassy-stm32/Cargo.toml | 4 ++-- embassy-stm32/src/opamp.rs | 49 ++++++++++++++------------------------ 2 files changed, 20 insertions(+), 33 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 82bc76883..a1dc75dba 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -73,7 +73,7 @@ rand_core = "0.6.3" sdio-host = "0.9.0" critical-section = "1.1" #stm32-metapac = { version = "16" } -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-380f03cb71f43a242adc45e83607a380ffe0447b" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9385c0824aff194913a2eab3c957791d0de06771" } vcell = "0.1.3" nb = "1.0.0" @@ -102,7 +102,7 @@ proc-macro2 = "1.0.36" quote = "1.0.15" #stm32-metapac = { version = "16", default-features = false, features = ["metadata"]} -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-380f03cb71f43a242adc45e83607a380ffe0447b", default-features = false, features = ["metadata"] } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9385c0824aff194913a2eab3c957791d0de06771", default-features = false, features = ["metadata"] } [features] default = ["rt"] diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index 82de4a89b..a76389495 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs @@ -37,22 +37,12 @@ enum OpAmpDifferentialPair { /// Speed #[allow(missing_docs)] -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq)] pub enum OpAmpSpeed { Normal, HighSpeed, } -#[cfg(opamp_g4)] -impl From for crate::pac::opamp::vals::Opahsm { - fn from(v: OpAmpSpeed) -> Self { - match v { - OpAmpSpeed::Normal => crate::pac::opamp::vals::Opahsm::NORMAL, - OpAmpSpeed::HighSpeed => crate::pac::opamp::vals::Opahsm::HIGH_SPEED, - } - } -} - /// OpAmp external outputs, wired to a GPIO pad. /// /// This struct can also be used as an ADC input. @@ -80,7 +70,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { pub fn new(opamp: Peri<'d, T>, #[cfg(opamp_g4)] speed: OpAmpSpeed) -> Self { #[cfg(opamp_g4)] T::regs().csr().modify(|w| { - w.set_opahsm(speed.into()); + w.set_opahsm(speed == OpAmpSpeed::HighSpeed); }); Self { _inner: opamp } @@ -113,7 +103,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { w.set_vp_sel(VpSel::from_bits(in_pin.channel())); w.set_vm_sel(vm_sel); #[cfg(opamp_g4)] - w.set_opaintoen(Opaintoen::OUTPUT_PIN); + w.set_opaintoen(false); w.set_opampen(true); }); @@ -166,7 +156,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { w.set_vm_sel(vm_sel); w.set_pga_gain(pga_gain); #[cfg(opamp_g4)] - w.set_opaintoen(Opaintoen::OUTPUT_PIN); + w.set_opaintoen(false); w.set_opampen(true); }); @@ -189,7 +179,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { w.set_vm_sel(VmSel::OUTPUT); w.set_vp_sel(VpSel::DAC3_CH1); - w.set_opaintoen(Opaintoen::OUTPUT_PIN); + w.set_opaintoen(false); w.set_opampen(true); }); @@ -215,7 +205,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { w.set_vp_sel(VpSel::from_bits(pin.channel())); w.set_vm_sel(VmSel::OUTPUT); #[cfg(opamp_g4)] - w.set_opaintoen(Opaintoen::ADCCHANNEL); + w.set_opaintoen(true); w.set_opampen(true); }); @@ -251,7 +241,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { w.set_vp_sel(VpSel::from_bits(pin.channel())); w.set_vm_sel(VmSel::OUTPUT); w.set_pga_gain(pga_gain); - w.set_opaintoen(Opaintoen::ADCCHANNEL); + w.set_opaintoen(true); w.set_opampen(true); }); @@ -278,7 +268,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { use crate::pac::opamp::vals::*; w.set_vp_sel(VpSel::DAC3_CH1); // Actually DAC3_CHx w.set_vm_sel(VmSel::from_bits(m_pin.channel())); - w.set_opaintoen(Opaintoen::ADCCHANNEL); + w.set_opaintoen(true); w.set_opampen(true); }); @@ -308,7 +298,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { use crate::pac::opamp::vals::*; w.set_vp_sel(VpSel::DAC3_CH1); // Actually DAC3_CHx w.set_vm_sel(VmSel::from_bits(m_pin.channel())); - w.set_opaintoen(Opaintoen::OUTPUT_PIN); + w.set_opaintoen(false); w.set_opampen(true); }); @@ -340,7 +330,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { use crate::pac::opamp::vals::*; w.set_vp_sel(VpSel::from_bits(p_pin.channel())); w.set_vm_sel(VmSel::from_bits(m_pin.channel())); - w.set_opaintoen(Opaintoen::OUTPUT_PIN); + w.set_opaintoen(false); w.set_opampen(true); }); @@ -369,7 +359,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { use crate::pac::opamp::vals::*; w.set_vp_sel(VpSel::from_bits(p_pin.channel())); w.set_vm_sel(VmSel::from_bits(m_pin.channel())); - w.set_opaintoen(Opaintoen::ADCCHANNEL); + w.set_opaintoen(true); w.set_opampen(true); }); @@ -389,17 +379,14 @@ impl<'d, T: Instance> OpAmp<'d, T> { T::regs().csr().modify(|w| { w.set_opampen(true); w.set_calon(true); - w.set_usertrim(Usertrim::USER); + w.set_usertrim(true); }); - match T::regs().csr().read().opahsm() { - Opahsm::NORMAL => { - self.calibrate_differential_pair(OpAmpDifferentialPair::P); - self.calibrate_differential_pair(OpAmpDifferentialPair::N); - } - Opahsm::HIGH_SPEED => { - self.calibrate_differential_pair(OpAmpDifferentialPair::P); - } + if T::regs().csr().read().opahsm() { + self.calibrate_differential_pair(OpAmpDifferentialPair::P); + } else { + self.calibrate_differential_pair(OpAmpDifferentialPair::P); + self.calibrate_differential_pair(OpAmpDifferentialPair::N); } T::regs().csr().modify(|w| { @@ -448,7 +435,7 @@ impl<'d, T: Instance> OpAmp<'d, T> { // (with a maximum stabilization time remaining below 2 ms in any case) -- RM0440 25.3.7 blocking_delay_ms(2); - if T::regs().csr().read().outcal() == Outcal::LOW { + if !T::regs().csr().read().calout() { if mid == 0 { break; } From 18eea73d198b4cc1bed3e034c912518ce47888cc Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 25 Apr 2025 00:09:13 +0200 Subject: [PATCH 2/2] stm32/adc: add h7rs support. --- embassy-stm32/src/adc/mod.rs | 4 +++- embassy-stm32/src/adc/v3.rs | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index 321db7431..f46e87f38 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs @@ -11,7 +11,7 @@ #[cfg_attr(adc_v1, path = "v1.rs")] #[cfg_attr(adc_l0, path = "v1.rs")] #[cfg_attr(adc_v2, path = "v2.rs")] -#[cfg_attr(any(adc_v3, adc_g0, adc_h5, adc_u0), path = "v3.rs")] +#[cfg_attr(any(adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0), path = "v3.rs")] #[cfg_attr(any(adc_v4, adc_u5), path = "v4.rs")] #[cfg_attr(adc_g4, path = "g4.rs")] #[cfg_attr(adc_c0, path = "c0.rs")] @@ -108,6 +108,7 @@ pub(crate) fn blocking_delay_us(us: u32) { adc_g0, adc_u0, adc_h5, + adc_h7rs, adc_u5, adc_c0 )))] @@ -129,6 +130,7 @@ pub trait Instance: SealedInstance + crate::PeripheralType { adc_g0, adc_u0, adc_h5, + adc_h7rs, adc_u5, adc_c0 ))] diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index 2de12d1d6..1c5ad16e9 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs @@ -19,7 +19,7 @@ impl SealedAdcChannel for VrefInt { cfg_if! { if #[cfg(adc_g0)] { let val = 13; - } else if #[cfg(adc_h5)] { + } else if #[cfg(any(adc_h5, adc_h7rs))] { let val = 17; } else if #[cfg(adc_u0)] { let val = 12; @@ -38,7 +38,7 @@ impl SealedAdcChannel for Temperature { cfg_if! { if #[cfg(adc_g0)] { let val = 12; - } else if #[cfg(adc_h5)] { + } else if #[cfg(any(adc_h5, adc_h7rs))] { let val = 16; } else if #[cfg(adc_u0)] { let val = 11; @@ -57,9 +57,9 @@ impl SealedAdcChannel for Vbat { cfg_if! { if #[cfg(adc_g0)] { let val = 14; - } else if #[cfg(adc_h5)] { + } else if #[cfg(any(adc_h5, adc_h7rs))] { let val = 2; - } else if #[cfg(adc_h5)] { + } else if #[cfg(any(adc_h5, adc_h7rs))] { let val = 13; } else { let val = 18; @@ -70,7 +70,7 @@ impl SealedAdcChannel for Vbat { } cfg_if! { - if #[cfg(adc_h5)] { + if #[cfg(any(adc_h5, adc_h7rs))] { pub struct VddCore; impl AdcChannel for VddCore {} impl super::SealedAdcChannel for VddCore { @@ -171,7 +171,7 @@ impl<'d, T: Instance> Adc<'d, T> { T::regs().ccr().modify(|reg| { reg.set_tsen(true); }); - } else if #[cfg(adc_h5)] { + } else if #[cfg(any(adc_h5, adc_h7rs))] { T::common_regs().ccr().modify(|reg| { reg.set_tsen(true); }); @@ -191,7 +191,7 @@ impl<'d, T: Instance> Adc<'d, T> { T::regs().ccr().modify(|reg| { reg.set_vbaten(true); }); - } else if #[cfg(adc_h5)] { + } else if #[cfg(any(adc_h5, adc_h7rs))] { T::common_regs().ccr().modify(|reg| { reg.set_vbaten(true); }); @@ -414,7 +414,7 @@ impl<'d, T: Instance> Adc<'d, T> { fn configure_channel(channel: &mut impl AdcChannel, sample_time: SampleTime) { // RM0492, RM0481, etc. // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected." - #[cfg(adc_h5)] + #[cfg(any(adc_h5, adc_h7rs))] if channel.channel() == 0 { T::regs().or().modify(|reg| reg.set_op0(true)); } @@ -447,7 +447,7 @@ impl<'d, T: Instance> Adc<'d, T> { // RM0492, RM0481, etc. // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected." - #[cfg(adc_h5)] + #[cfg(any(adc_h5, adc_h7rs))] if channel.channel() == 0 { T::regs().or().modify(|reg| reg.set_op0(false)); } @@ -475,7 +475,7 @@ impl<'d, T: Instance> Adc<'d, T> { if #[cfg(any(adc_g0, adc_u0))] { // On G0 and U6 all channels use the same sampling time. T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.into())); - } else if #[cfg(adc_h5)] { + } else if #[cfg(any(adc_h5, adc_h7rs))] { match _ch { 0..=9 => T::regs().smpr1().modify(|w| w.set_smp(_ch as usize % 10, sample_time.into())), _ => T::regs().smpr2().modify(|w| w.set_smp(_ch as usize % 10, sample_time.into())),