From c90e4b3135283070bddc6a8e64df3139909ac8ce Mon Sep 17 00:00:00 2001 From: xoviat Date: Mon, 10 Nov 2025 12:37:38 -0600 Subject: adc: use common vref scheme --- embassy-stm32/src/adc/c0.rs | 32 ++++---------- embassy-stm32/src/adc/f1.rs | 24 ++++------ embassy-stm32/src/adc/f3.rs | 26 ++++------- embassy-stm32/src/adc/g4.rs | 85 ++++++++++-------------------------- embassy-stm32/src/adc/mod.rs | 41 ++++++++++++++++++ embassy-stm32/src/adc/v1.rs | 40 +++++++---------- embassy-stm32/src/adc/v2.rs | 47 ++++++++------------ embassy-stm32/src/adc/v3.rs | 101 +++++++++++++++++++++---------------------- embassy-stm32/src/adc/v4.rs | 61 +++++++++++--------------- 9 files changed, 195 insertions(+), 262 deletions(-) diff --git a/embassy-stm32/src/adc/c0.rs b/embassy-stm32/src/adc/c0.rs index 70302ef96..1869993a5 100644 --- a/embassy-stm32/src/adc/c0.rs +++ b/embassy-stm32/src/adc/c0.rs @@ -19,33 +19,17 @@ const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(25); const TIME_ADC_VOLTAGE_REGUALTOR_STARTUP_US: u32 = 20; -const TEMP_CHANNEL: u8 = 9; -const VREF_CHANNEL: u8 = 10; - const NUM_HW_CHANNELS: u8 = 22; const CHSELR_SQ_SIZE: usize = 8; const CHSELR_SQ_MAX_CHANNEL: u8 = 14; const CHSELR_SQ_SEQUENCE_END_MARKER: u8 = 0b1111; -// NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, -// this currently cannot be modeled with stm32-data, -// so these are available from the software on all ADCs. -/// Internal voltage reference channel. -pub struct VrefInt; -impl AdcChannel for VrefInt {} -impl SealedAdcChannel for VrefInt { - fn channel(&self) -> u8 { - VREF_CHANNEL - } +impl super::VrefConverter for T { + const CHANNEL: u8 = 10; } -/// Internal temperature channel. -pub struct Temperature; -impl AdcChannel for Temperature {} -impl SealedAdcChannel for Temperature { - fn channel(&self) -> u8 { - TEMP_CHANNEL - } +impl super::TemperatureConverter for T { + const CHANNEL: u8 = 9; } #[derive(Copy, Clone, Debug)] @@ -232,22 +216,22 @@ impl<'d, T: Instance> Adc<'d, T> { } /// Enable reading the voltage reference internal channel. - pub fn enable_vrefint(&self) -> VrefInt { + pub fn enable_vrefint(&self) -> super::VrefInt { T::common_regs().ccr().modify(|reg| { reg.set_vrefen(true); }); - VrefInt {} + super::VrefInt {} } /// Enable reading the temperature internal channel. - pub fn enable_temperature(&self) -> Temperature { + pub fn enable_temperature(&self) -> super::Temperature { debug!("Ensure that sample time is set to more than temperature sensor T_start from the datasheet!"); T::common_regs().ccr().modify(|reg| { reg.set_tsen(true); }); - Temperature {} + super::Temperature {} } /// Set the ADC sample time. diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs index 32e330d76..835cc8c63 100644 --- a/embassy-stm32/src/adc/f1.rs +++ b/embassy-stm32/src/adc/f1.rs @@ -28,20 +28,12 @@ impl interrupt::typelevel::Handler for InterruptHandl } } -pub struct Vref; -impl AdcChannel for Vref {} -impl super::SealedAdcChannel for Vref { - fn channel(&self) -> u8 { - 17 - } +impl super::VrefConverter for T { + const CHANNEL: u8 = 17; } -pub struct Temperature; -impl AdcChannel for Temperature {} -impl super::SealedAdcChannel for Temperature { - fn channel(&self) -> u8 { - 16 - } +impl super::TemperatureConverter for T { + const CHANNEL: u8 = 16; } impl<'d, T: Instance> Adc<'d, T> { @@ -91,18 +83,18 @@ impl<'d, T: Instance> Adc<'d, T> { } } - pub fn enable_vref(&self) -> Vref { + pub fn enable_vref(&self) -> super::VrefInt { T::regs().cr2().modify(|reg| { reg.set_tsvrefe(true); }); - Vref {} + super::VrefInt {} } - pub fn enable_temperature(&self) -> Temperature { + pub fn enable_temperature(&self) -> super::Temperature { T::regs().cr2().modify(|reg| { reg.set_tsvrefe(true); }); - Temperature {} + super::Temperature {} } /// Perform a single conversion. diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs index cf31aa81b..da185e875 100644 --- a/embassy-stm32/src/adc/f3.rs +++ b/embassy-stm32/src/adc/f3.rs @@ -29,27 +29,19 @@ impl interrupt::typelevel::Handler for InterruptHandl } } -pub struct Vref; -impl AdcChannel for Vref {} -impl super::SealedAdcChannel for Vref { - fn channel(&self) -> u8 { - 18 - } +impl super::VrefConverter for T { + const CHANNEL: u8 = 18; } -impl Vref { +impl super::VrefInt { /// The value that vref would be if vdda was at 3300mv pub fn value(&self) -> u16 { crate::pac::VREFINTCAL.data().read() } } -pub struct Temperature; -impl AdcChannel for Temperature {} -impl super::SealedAdcChannel for Temperature { - fn channel(&self) -> u8 { - 16 - } +impl super::TemperatureConverter for T { + const CHANNEL: u8 = 16; } impl<'d, T: Instance> Adc<'d, T> { @@ -109,16 +101,16 @@ impl<'d, T: Instance> Adc<'d, T> { } } - pub fn enable_vref(&self) -> Vref { + pub fn enable_vref(&self) -> super::VrefInt { T::common_regs().ccr().modify(|w| w.set_vrefen(true)); - Vref {} + super::VrefInt {} } - pub fn enable_temperature(&self) -> Temperature { + pub fn enable_temperature(&self) -> super::Temperature { T::common_regs().ccr().modify(|w| w.set_tsen(true)); - Temperature {} + super::Temperature {} } /// Perform a single conversion. diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs index 5066aeec0..2138a82b4 100644 --- a/embassy-stm32/src/adc/g4.rs +++ b/embassy-stm32/src/adc/g4.rs @@ -35,34 +35,6 @@ const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(60); #[cfg(stm32h7)] const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50); -// NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs -/// Internal voltage reference channel. -pub struct VrefInt; -impl AdcChannel for VrefInt {} -impl super::SealedAdcChannel for VrefInt { - fn channel(&self) -> u8 { - T::CHANNEL - } -} - -/// Internal temperature channel. -pub struct Temperature; -impl AdcChannel for Temperature {} -impl super::SealedAdcChannel for Temperature { - fn channel(&self) -> u8 { - T::CHANNEL - } -} - -/// Internal battery voltage channel. -pub struct Vbat; -impl AdcChannel for Vbat {} -impl super::SealedAdcChannel for Vbat { - fn channel(&self) -> u8 { - T::CHANNEL - } -} - // 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. #[allow(unused)] @@ -250,39 +222,39 @@ impl<'d, T: Instance> Adc<'d, T> { } /// Enable reading the voltage reference internal channel. - pub fn enable_vrefint(&self) -> VrefInt + pub fn enable_vrefint(&self) -> super::VrefInt where - T: VrefChannel, + T: super::VrefConverter, { T::common_regs().ccr().modify(|reg| { reg.set_vrefen(true); }); - VrefInt {} + super::VrefInt {} } /// Enable reading the temperature internal channel. - pub fn enable_temperature(&self) -> Temperature + pub fn enable_temperature(&self) -> super::Temperature where - T: TemperatureChannel, + T: super::TemperatureConverter, { T::common_regs().ccr().modify(|reg| { reg.set_vsenseen(true); }); - Temperature {} + super::Temperature {} } /// Enable reading the vbat internal channel. - pub fn enable_vbat(&self) -> Vbat + pub fn enable_vbat(&self) -> super::Vbat where - T: VBatChannel, + T: super::VBatConverter, { T::common_regs().ccr().modify(|reg| { reg.set_vbaten(true); }); - Vbat {} + super::Vbat {} } /// Enable differential channel. @@ -850,62 +822,49 @@ impl InjectedAdc { } } -/// Implemented for ADCs that have a Temperature channel -pub trait TemperatureChannel { - const CHANNEL: u8; -} -/// Implemented for ADCs that have a Vref channel -pub trait VrefChannel { - const CHANNEL: u8; -} -/// Implemented for ADCs that have a VBat channel -pub trait VBatChannel { - const CHANNEL: u8; -} - #[cfg(stm32g4)] mod g4 { - pub use super::*; + use crate::adc::{TemperatureConverter, VBatConverter, VrefConverter}; - impl TemperatureChannel for crate::peripherals::ADC1 { + impl TemperatureConverter for crate::peripherals::ADC1 { const CHANNEL: u8 = 16; } - impl VrefChannel for crate::peripherals::ADC1 { + impl VrefConverter for crate::peripherals::ADC1 { const CHANNEL: u8 = 18; } - impl VBatChannel for crate::peripherals::ADC1 { + impl VBatConverter for crate::peripherals::ADC1 { const CHANNEL: u8 = 17; } #[cfg(peri_adc3_common)] - impl VrefChannel for crate::peripherals::ADC3 { + impl VrefConverter for crate::peripherals::ADC3 { const CHANNEL: u8 = 18; } #[cfg(peri_adc3_common)] - impl VBatChannel for crate::peripherals::ADC3 { + impl VBatConverter for crate::peripherals::ADC3 { const CHANNEL: u8 = 17; } #[cfg(not(stm32g4x1))] - impl VrefChannel for crate::peripherals::ADC4 { + impl VrefConverter for crate::peripherals::ADC4 { const CHANNEL: u8 = 18; } #[cfg(not(stm32g4x1))] - impl TemperatureChannel for crate::peripherals::ADC5 { + impl TemperatureConverter for crate::peripherals::ADC5 { const CHANNEL: u8 = 4; } #[cfg(not(stm32g4x1))] - impl VrefChannel for crate::peripherals::ADC5 { + impl VrefConverter for crate::peripherals::ADC5 { const CHANNEL: u8 = 18; } #[cfg(not(stm32g4x1))] - impl VBatChannel for crate::peripherals::ADC5 { + impl VBatConverter for crate::peripherals::ADC5 { const CHANNEL: u8 = 17; } } @@ -913,13 +872,13 @@ mod g4 { // TODO this should look at each ADC individually and impl the correct channels #[cfg(stm32h7)] mod h7 { - impl TemperatureChannel for T { + impl TemperatureConverter for T { const CHANNEL: u8 = 18; } - impl VrefChannel for T { + impl VrefConverter for T { const CHANNEL: u8 = 19; } - impl VBatChannel for T { + impl VBatConverter for T { // TODO this should be 14 for H7a/b/35 const CHANNEL: u8 = 17; } diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index a6b796fb9..a5ca6277f 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs @@ -100,6 +100,47 @@ pub(crate) fn blocking_delay_us(us: u32) { } } +/// Implemented for ADCs that have a Temperature channel +pub trait TemperatureConverter { + const CHANNEL: u8; +} +/// Implemented for ADCs that have a Vref channel +pub trait VrefConverter { + const CHANNEL: u8; +} +/// Implemented for ADCs that have a VBat channel +pub trait VBatConverter { + const CHANNEL: u8; +} + +// NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs +/// Internal voltage reference channel. +pub struct VrefInt; +impl AdcChannel for VrefInt {} +impl SealedAdcChannel for VrefInt { + fn channel(&self) -> u8 { + T::CHANNEL + } +} + +/// Internal temperature channel. +pub struct Temperature; +impl AdcChannel for Temperature {} +impl SealedAdcChannel for Temperature { + fn channel(&self) -> u8 { + T::CHANNEL + } +} + +/// Internal battery voltage channel. +pub struct Vbat; +impl AdcChannel for Vbat {} +impl SealedAdcChannel for Vbat { + fn channel(&self) -> u8 { + T::CHANNEL + } +} + /// ADC instance. #[cfg(not(any( adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_g4, adc_f3v1, adc_f3v2, adc_g0, adc_u0, adc_h5, adc_h7rs, diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs index 3838cc12a..97557ee8a 100644 --- a/embassy-stm32/src/adc/v1.rs +++ b/embassy-stm32/src/adc/v1.rs @@ -5,10 +5,11 @@ use core::task::Poll; #[cfg(adc_l0)] use stm32_metapac::adc::vals::Ckmode; -use super::blocking_delay_us; +#[cfg(not(adc_l0))] +use super::Vbat; +use super::{Temperature, VrefInt, blocking_delay_us}; use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; use crate::interrupt::typelevel::Interrupt; -use crate::peripherals::ADC1; use crate::{Peri, interrupt, rcc}; mod watchdog_v1; @@ -42,32 +43,23 @@ impl interrupt::typelevel::Handler for InterruptHandl } #[cfg(not(adc_l0))] -pub struct Vbat; - -#[cfg(not(adc_l0))] -impl AdcChannel for Vbat {} +impl super::VBatConverter for crate::peripherals::ADC1 { + const CHANNEL: u8 = 18; +} #[cfg(not(adc_l0))] -impl super::SealedAdcChannel for Vbat { - fn channel(&self) -> u8 { - 18 - } +impl super::VrefConverter for crate::peripherals::ADC1 { + const CHANNEL: u8 = 17; } -pub struct Vref; -impl AdcChannel for Vref {} -impl super::SealedAdcChannel for Vref { - fn channel(&self) -> u8 { - 17 - } +#[cfg(adc_l0)] +impl super::VrefConverter for crate::peripherals::ADC1 { + const CHANNEL: u8 = 18; } -pub struct Temperature; -impl AdcChannel for Temperature {} -impl super::SealedAdcChannel for Temperature { - fn channel(&self) -> u8 { - if cfg!(adc_l0) { 18 } else { 16 } - } +#[cfg(not(adc_l0))] +impl super::TemperatureConverter for crate::peripherals::ADC1 { + const CHANNEL: u8 = 16; } impl<'d, T: Instance> Adc<'d, T> { @@ -127,12 +119,12 @@ impl<'d, T: Instance> Adc<'d, T> { Vbat } - pub fn enable_vref(&self) -> Vref { + pub fn enable_vref(&self) -> VrefInt { // Table 28. Embedded internal reference voltage // tstart = 10μs T::regs().ccr().modify(|reg| reg.set_vrefen(true)); blocking_delay_us(10); - Vref + VrefInt } pub fn enable_temperature(&self) -> Temperature { diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index 67721770a..af5d486d9 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.rs @@ -1,10 +1,9 @@ use core::mem; use core::sync::atomic::{Ordering, compiler_fence}; -use super::blocking_delay_us; +use super::{Temperature, Vbat, VrefInt, blocking_delay_us}; use crate::adc::{Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel}; use crate::pac::adc::vals; -use crate::peripherals::ADC1; use crate::time::Hertz; use crate::{Peri, rcc}; @@ -23,12 +22,22 @@ pub const VREF_DEFAULT_MV: u32 = 3300; /// VREF voltage used for factory calibration of VREFINTCAL register. pub const VREF_CALIB_MV: u32 = 3300; -pub struct VrefInt; -impl AdcChannel for VrefInt {} -impl super::SealedAdcChannel for VrefInt { - fn channel(&self) -> u8 { - 17 - } +impl super::VrefConverter for crate::peripherals::ADC1 { + const CHANNEL: u8 = 17; +} + +#[cfg(any(stm32f2, stm32f40x, stm32f41x))] +impl super::TemperatureConverter for crate::peripherals::ADC1 { + const CHANNEL: u8 = 16; +} + +#[cfg(not(any(stm32f2, stm32f40x, stm32f41x)))] +impl super::TemperatureConverter for crate::peripherals::ADC1 { + const CHANNEL: u8 = 18; +} + +impl super::VBatConverter for crate::peripherals::ADC1 { + const CHANNEL: u8 = 18; } impl VrefInt { @@ -38,20 +47,6 @@ impl VrefInt { } } -pub struct Temperature; -impl AdcChannel for Temperature {} -impl super::SealedAdcChannel for Temperature { - fn channel(&self) -> u8 { - cfg_if::cfg_if! { - if #[cfg(any(stm32f2, stm32f40x, stm32f41x))] { - 16 - } else { - 18 - } - } - } -} - impl Temperature { /// Time needed for temperature sensor readings to stabilize pub fn start_time_us() -> u32 { @@ -59,14 +54,6 @@ impl Temperature { } } -pub struct Vbat; -impl AdcChannel for Vbat {} -impl super::SealedAdcChannel for Vbat { - fn channel(&self) -> u8 { - 18 - } -} - enum Prescaler { Div2, Div4, diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index bbbaf73c8..0822fbb69 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs @@ -9,8 +9,11 @@ use pac::adc::vals::{OversamplingRatio, OversamplingShift, Rovsm, Trovs}; #[cfg(adc_g0)] pub use pac::adc::vals::{Ovsr, Ovss, Presc}; +#[allow(unused_imports)] +use super::SealedAdcChannel; use super::{ - Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, blocking_delay_us, + Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, Temperature, Vbat, VrefInt, + blocking_delay_us, }; #[cfg(any(adc_v3, adc_g0, adc_u0))] @@ -32,61 +35,55 @@ pub const VREF_CALIB_MV: u32 = 3000; // TODO: Use [#![feature(variant_count)]](https://github.com/rust-lang/rust/issues/73662) when stable const SAMPLE_TIMES_CAPACITY: usize = 2; -pub struct VrefInt; -impl AdcChannel for VrefInt {} -impl SealedAdcChannel for VrefInt { - fn channel(&self) -> u8 { - cfg_if! { - if #[cfg(adc_g0)] { - let val = 13; - } else if #[cfg(any(adc_h5, adc_h7rs))] { - let val = 17; - } else if #[cfg(adc_u0)] { - let val = 12; - } else { - let val = 0; - } - } - val - } +#[cfg(adc_g0)] +impl super::VrefConverter for T { + const CHANNEL: u8 = 13; +} +#[cfg(any(adc_h5, adc_h7rs))] +impl super::VrefConverter for T { + const CHANNEL: u8 = 17; +} +#[cfg(adc_u0)] +impl super::VrefConverter for T { + const CHANNEL: u8 = 12; +} +#[cfg(not(any(adc_g0, adc_h5, adc_h7rs, adc_u0)))] +impl super::VrefConverter for T { + const CHANNEL: u8 = 0; } -pub struct Temperature; -impl AdcChannel for Temperature {} -impl SealedAdcChannel for Temperature { - fn channel(&self) -> u8 { - cfg_if! { - if #[cfg(adc_g0)] { - let val = 12; - } else if #[cfg(any(adc_h5, adc_h7rs))] { - let val = 16; - } else if #[cfg(adc_u0)] { - let val = 11; - } else { - let val = 17; - } - } - val - } +#[cfg(adc_g0)] +impl super::TemperatureConverter for T { + const CHANNEL: u8 = 12; +} +#[cfg(any(adc_h5, adc_h7rs))] +impl super::TemperatureConverter for T { + const CHANNEL: u8 = 16; +} +#[cfg(adc_u0)] +impl super::TemperatureConverter for T { + const CHANNEL: u8 = 11; +} +#[cfg(not(any(adc_g0, adc_h5, adc_h7rs, adc_u0)))] +impl super::TemperatureConverter for T { + const CHANNEL: u8 = 17; } -pub struct Vbat; -impl AdcChannel for Vbat {} -impl SealedAdcChannel for Vbat { - fn channel(&self) -> u8 { - cfg_if! { - if #[cfg(adc_g0)] { - let val = 14; - } else if #[cfg(any(adc_h5, adc_h7rs))] { - let val = 2; - } else if #[cfg(any(adc_h5, adc_h7rs))] { - let val = 13; - } else { - let val = 18; - } - } - val - } +#[cfg(adc_g0)] +impl super::VBatConverter for T { + const CHANNEL: u8 = 14; +} +#[cfg(any(adc_h5, adc_h7rs))] +impl super::VBatConverter for T { + const CHANNEL: u8 = 2; +} +#[cfg(adc_u0)] +impl super::VBatConverter for T { + const CHANNEL: u8 = 13; +} +#[cfg(not(any(adc_g0, adc_h5, adc_h7rs, adc_u0)))] +impl super::VBatConverter for T { + const CHANNEL: u8 = 18; } cfg_if! { diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs index cc3f8b34e..2f7baf3bf 100644 --- a/embassy-stm32/src/adc/v4.rs +++ b/embassy-stm32/src/adc/v4.rs @@ -5,7 +5,8 @@ use pac::adc::vals::{Adstp, Difsel, Dmngt, Exten, Pcsel}; use pac::adccommon::vals::Presc; use super::{ - Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, blocking_delay_us, + Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel, Temperature, Vbat, + VrefInt, blocking_delay_us, }; use crate::dma::Transfer; use crate::time::Hertz; @@ -25,52 +26,40 @@ const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(50); const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55); #[cfg(stm32g4)] -const VREF_CHANNEL: u8 = 18; +impl super::VrefConverter for T { + const CHANNEL: u8 = 18; +} #[cfg(stm32g4)] -const TEMP_CHANNEL: u8 = 16; +impl super::TemperatureConverter for T { + const CHANNEL: u8 = 16; +} #[cfg(stm32h7)] -const VREF_CHANNEL: u8 = 19; +impl super::VrefConverter for T { + const CHANNEL: u8 = 19; +} #[cfg(stm32h7)] -const TEMP_CHANNEL: u8 = 18; +impl super::TemperatureConverter for T { + const CHANNEL: u8 = 18; +} // TODO this should be 14 for H7a/b/35 #[cfg(not(stm32u5))] -const VBAT_CHANNEL: u8 = 17; +impl super::VBatConverter for T { + const CHANNEL: u8 = 17; +} #[cfg(stm32u5)] -const VREF_CHANNEL: u8 = 0; -#[cfg(stm32u5)] -const TEMP_CHANNEL: u8 = 19; -#[cfg(stm32u5)] -const VBAT_CHANNEL: u8 = 18; - -// NOTE: Vrefint/Temperature/Vbat are not available on all ADCs, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs -/// Internal voltage reference channel. -pub struct VrefInt; -impl AdcChannel for VrefInt {} -impl SealedAdcChannel for VrefInt { - fn channel(&self) -> u8 { - VREF_CHANNEL - } +impl super::VrefConverter for T { + const CHANNEL: u8 = 0; } - -/// Internal temperature channel. -pub struct Temperature; -impl AdcChannel for Temperature {} -impl SealedAdcChannel for Temperature { - fn channel(&self) -> u8 { - TEMP_CHANNEL - } +#[cfg(stm32u5)] +impl super::TemperatureConverter for T { + const CHANNEL: u8 = 19; } - -/// Internal battery voltage channel. -pub struct Vbat; -impl AdcChannel for Vbat {} -impl SealedAdcChannel for Vbat { - fn channel(&self) -> u8 { - VBAT_CHANNEL - } +#[cfg(stm32u5)] +impl super::VBatConverter for T { + const CHANNEL: u8 = 18; } // NOTE (unused): The prescaler enum closely copies the hardware capabilities, -- cgit