stm32_hal2/
adc.rs

1//! Support for the ADC (Analog to Digital Converter) peripheral.
2
3use core::ptr;
4
5use cfg_if::cfg_if;
6use cortex_m::asm;
7use paste::paste;
8
9#[cfg(any(feature = "f3", feature = "l4"))]
10use crate::dma::DmaInput;
11#[cfg(not(any(feature = "f4", feature = "l552", feature = "h5")))]
12use crate::dma::{self, ChannelCfg, DmaChannel};
13use crate::{
14    clocks::Clocks,
15    error::{Error, Result},
16    pac::{self, RCC},
17    util::{bounded_loop, rcc_en_reset},
18};
19
20// Address of the ADCinterval voltage reference. This address is found in the User manual. It appears
21// to be the same for most STM32s. The voltage this is measured at my vary by variant; eg 3.0 vice 3.3.
22// So far, it seems it's always on ADC1, but the channel depends on variant.
23// G474 manual implies you can use *any* ADC on ch 18. G491 shows ADC 1 and 3, ch 18 on both.
24// L4x2 implies ADC1 only.
25cfg_if! {
26    if #[cfg(feature = "h7")] {
27        // These values are from the H723 User manual
28        const VREFINT_ADDR: u32 = 0x1FF1_E860;
29        const VREFINT_VOLTAGE: f32 = 3.3;
30        const VREFINT_CH: u8 = 0; // todo: Unknown. What is it?
31    } else if #[cfg(feature = "g4")] {
32        const VREFINT_ADDR: u32 = 0x1FFF_75AA;
33        const VREFINT_VOLTAGE: f32 = 3.0;
34        const VREFINT_CH: u8 = 18; // G491, G431
35    } else {
36        const VREFINT_ADDR: u32 = 0x1FFF_75AA;
37        const VREFINT_VOLTAGE: f32 = 3.0;
38        const VREFINT_CH: u8 = 0; // L412
39    }
40}
41
42const MAX_ADVREGEN_STARTUP_US: u32 = 10;
43
44#[derive(Clone, Copy, PartialEq)]
45pub enum AdcDevice {
46    One,
47    Two,
48    Three,
49    #[cfg(feature = "g4")] // todo: Check the specifics.
50    Four,
51    #[cfg(feature = "g4")]
52    Five,
53}
54
55#[derive(Clone, Copy)]
56#[repr(u8)]
57/// Select a trigger. Sets CFGR reg, EXTSEL field. See G4 RM, table 163: ADC1/2 - External
58/// triggers for regular channels.
59pub enum Trigger {
60    // todo: Injected.
61    Tim1Cc1 = 0b00000,
62    Tim1Cc2 = 0b00001,
63    Tim1Cc3 = 0b00010,
64    Tim2Cc2 = 0b00011,
65    Tim3Trgo = 0b00100,
66    Tim4Cc4 = 0b00101,
67    Exti11 = 0b00110,
68    Tim8Trgo = 0b00111,
69    Tim8Trgo2 = 0b01000,
70    Tim1Trgo = 0b01001,
71    Tim1Trgo2 = 0b01010,
72    Tim2Trgo = 0b01011,
73    Tim4Trgo = 0b01100,
74    Tim6Trgo = 0b01101,
75    Tim15Trgo = 0b01110,
76    Tim3Cc4 = 0b01111,
77    // todo: Fill in remaining ones.
78    Tim7Trgo = 0b11110,
79}
80
81#[derive(Clone, Copy)]
82#[repr(u8)]
83/// Select a trigger. Sets CFGR reg, EXTEN field. See G4 RM, table 161:
84/// Configuring the trigger polarity for regular external triggers
85/// (Also applies for injected)
86pub enum TriggerEdge {
87    /// Hardware Trigger detection disabled, software trigger detection enabled
88    Software = 0b00,
89    /// Hardware Trigger with detection on the rising edge
90    HardwareRising = 0b01,
91    /// Hardware Trigger with detection on the falling edge
92    HardwareFalling = 0b10,
93    /// Hardware Trigger with detection on both the rising and falling edges
94    HardwareBoth = 0b11,
95}
96
97#[derive(Copy, Clone)]
98#[repr(u8)]
99/// ADC interrupts. See L44 RM, section 16.5: ADC interrupts. Set in the IER register, and cleared
100/// in the ISR register.
101pub enum AdcInterrupt {
102    /// ADC ready (ADRDYIE field)
103    Ready,
104    /// End of regular conversion interrupt enable (EOCIE field)
105    EndOfConversion,
106    /// End of regular sequence of conversions (EOSIE field)
107    EndOfSequence,
108    /// End of injected conversion (JEOCIE field)
109    EndofConversionInjected,
110    /// End of injected sequence of conversions (JEOSIE field)
111    EndOfSequenceInjected,
112    /// Analog watchdog 1 interrupt (AWD1IE field)
113    Watchdog1,
114    /// Analog watchdog 2 interrupt (AWD2IE field)
115    Watchdog2,
116    /// Analog watchdog 3 interrupt (AWD3IE field)
117    Watchdog3,
118    /// End of sampling flag interrupt enable for regular conversions (EOSMPIE field)
119    EndOfSamplingPhase,
120    /// Overrun (OVRIE field)
121    Overrun,
122    /// Injected Context Queue Overflow (JQOVFIE field)
123    InjectedOverflow,
124}
125
126// todo: Adc sampling time below depends on the STM32 family. Eg the numbers below
127// todo are wrong for L4, but the idea is the same.
128/// ADC sampling time. Sets ADC_SMPRx register, SMPy field.
129///
130/// Each channel can be sampled with a different sample time.
131/// There is always an overhead of 13 ADC clock cycles.
132/// E.g. For Sampletime T_19 the total conversion time (in ADC clock cycles) is
133/// 13 + 19 = 32 ADC Clock Cycles
134#[derive(Clone, Copy)]
135#[repr(u8)]
136pub enum SampleTime {
137    /// 1.5 ADC clock cycles (2.5 on G4)
138    T1 = 0b000,
139    /// 2.5 ADC clock cycles (6.5 on G4)
140    T2 = 0b001,
141    /// 4.5 ADC clock cycles (12.5 on G4)
142    T4 = 0b010,
143    /// 7.5 ADC clock cycles (24.5 on G4)
144    T7 = 0b011,
145    /// 19.5 ADC clock cycles (47.5 on G4)
146    T19 = 0b100,
147    /// 61.5 ADC clock cycles (92.5 on G4)
148    T61 = 0b101,
149    /// 181.5 ADC clock cycles (247.5 on G4)
150    T181 = 0b110,
151    /// 601.5 ADC clock cycles (640.5 on G4 and H7)
152    T601 = 0b111,
153}
154
155impl Default for SampleTime {
156    /// T_1 is the reset value; pick a higher one, as the lower values may cause significantly
157    /// lower-than-accurate readings.
158    fn default() -> Self {
159        SampleTime::T181
160    }
161}
162
163#[derive(Clone, Copy)]
164#[repr(u8)]
165/// Select single-ended, or differential inputs. Sets bits in the ADC\[x\]_DIFSEL register.
166pub enum InputType {
167    SingleEnded = 0,
168    Differential = 1,
169}
170
171#[derive(Clone, Copy)]
172#[repr(u8)]
173/// ADC operation mode
174pub enum OperationMode {
175    /// OneShot Mode
176    OneShot = 0,
177    Continuous = 1,
178}
179
180// todo: Check the diff ways of configuring clock; i don't think teh enum below covers all.(?)
181
182#[derive(Clone, Copy, PartialEq)]
183#[repr(u8)]
184/// ADC Clock mode
185/// (L44 RM, Section 16.4.3) The input clock is the same for the three ADCs and can be selected between two different
186/// clock sources (see Figure 40: ADC clock scheme):
187/// 1. The ADC clock can be a specific clock source. It can be derived from the following
188/// clock sources:
189/// – The system clock
190/// – PLLSAI1 (single ADC implementation)
191/// Refer to RCC Section for more information on how to generate ADC dedicated clock.
192/// To select this scheme, bits CKMODE\[1:0\] of the ADCx_CCR register must be reset.
193/// 2. The ADC clock can be derived from the AHB clock of the ADC bus interface, divided by
194/// a programmable factor (1, 2 or 4). In this mode, a programmable divider factor can be
195/// selected (/1, 2 or 4 according to bits CKMODE\[1:0\]).
196/// To select this scheme, bits CKMODE\[1:0\] of the ADCx_CCR register must be different
197/// from “00”.
198pub enum ClockMode {
199    /// Use Kernel Clock adc_ker_ck_input divided by PRESC. Asynchronous to AHB clock
200    Async = 0b00,
201    /// Use AHB clock rcc_hclk3 (or just hclk depending on variant).
202    /// "For option 2), a prescaling factor of 1 (CKMODE\[1:0\]=01) can be used only if the AHB
203    /// prescaler is set to 1 (HPRE\[3:0\] = 0xxx in RCC_CFGR register)."
204    SyncDiv1 = 0b01,
205    /// Use AHB clock rcc_hclk3 (or just hclk depending on variant) divided by 2
206    SyncDiv2 = 0b10,
207    /// Use AHB clock rcc_hclk3 (or just hclk depending on variant) divided by 4
208    SyncDiv4 = 0b11,
209}
210
211/// Sets ADC clock prescaler; ADCx_CCR register, PRESC field.
212#[derive(Clone, Copy)]
213#[repr(u8)]
214pub enum Prescaler {
215    D1 = 0b0000,
216    D2 = 0b0001,
217    D4 = 0b0010,
218    D6 = 0b0011,
219    D8 = 0b0100,
220    D10 = 0b0101,
221    D12 = 0b0110,
222    D16 = 0b0111,
223    D32 = 0b1000,
224    D64 = 0b1001,
225    D128 = 0b1010,
226    D256 = 0b1011,
227}
228
229#[cfg(not(feature = "h7"))]
230/// ADC data register alignment
231#[derive(Clone, Copy)]
232#[repr(u8)]
233pub enum Align {
234    /// Right alignment of output data
235    Right = 0,
236    /// Left alignment of output data
237    Left = 1,
238}
239
240#[cfg(not(feature = "h7"))]
241impl Default for Align {
242    fn default() -> Self {
243        Align::Right
244    }
245}
246
247#[cfg(feature = "h7")]
248/// ADC data register alignment
249#[derive(Clone, Copy)]
250#[repr(u8)]
251pub enum Align {
252    NoShift = 0,
253    L1 = 1,
254    L2 = 2,
255    L3 = 3,
256    L4 = 4,
257    L5 = 5,
258    L6 = 6,
259    L7 = 7,
260    L8 = 8,
261    L9 = 9,
262    L10 = 10,
263    L11 = 11,
264    L12 = 12,
265    L13 = 13,
266    L14 = 14,
267    L15 = 15,
268}
269
270#[cfg(feature = "h7")]
271impl Default for Align {
272    fn default() -> Self {
273        Align::NoShift
274    }
275}
276
277// todo impl
278// /// Ratio options for oversampling.
279// #[derive(Clone, Copy)]
280// #[repr(u8)]
281// pub enum OversamplingRatio {
282//     Times2 = 0b000,
283//     Times4 = 0b001,
284//     Times8 = 0b010,
285//     Times16 = 0b011,
286//     Times32 = 0b100,
287//     Times64 = 0b101,
288//     Times128 = 0b110,
289//     Times256 = 0b111,
290// }
291//
292// /// Shift options for oversampling.
293// #[derive(Clone, Copy)]
294// #[repr(u8)]
295// pub enum OversamplingShift {
296//     None = 0b0000,
297//     Bits1 = 0b0001,
298//     Bits2 = 0b0010,
299//     Bits3 = 0b0011,
300//     Bits4 = 0b0100,
301//     Bits5 = 0b0101,
302//     Bits6 = 0b0110,
303//     Bits7 = 0b0111,
304//     Bits8 = 0b1000,
305// }
306
307/// Initial configuration data for the ADC peripheral.
308#[derive(Clone)]
309pub struct AdcConfig {
310    /// ADC clock mode. Defaults to AHB clock rcc_hclk3 (or hclk) divided by 2.
311    pub clock_mode: ClockMode,
312    /// ADC sample time. See the `SampleTime` enum for details. Higher values
313    ///  result in more accurate readings.
314    pub sample_time: SampleTime,
315    /// ADC clock prescaler. Defaults to no division.
316    pub prescaler: Prescaler,
317    /// One-shot, or continuous measurements. Defaults to one-shot.
318    pub operation_mode: OperationMode,
319    // Most families use u8 values for calibration, but H7 uses u16.
320    /// Optional calibration data for single-ended measurements.
321    pub cal_single_ended: Option<u16>,
322    /// Optional calibration data for differential measurements.
323    pub cal_differential: Option<u16>,
324}
325
326impl Default for AdcConfig {
327    fn default() -> Self {
328        Self {
329            // todo: What should this be? Async seems to be having trouble.
330            // clock_mode: ClockMode::Async,
331            clock_mode: ClockMode::SyncDiv1,
332            sample_time: Default::default(),
333            prescaler: Prescaler::D1,
334            operation_mode: OperationMode::OneShot,
335            cal_single_ended: None,
336            cal_differential: None,
337        }
338    }
339}
340
341/// Represents an Analog to Digital Converter (ADC) peripheral.
342pub struct Adc<R> {
343    /// ADC Register
344    pub regs: R,
345    // Note: We don't own the common regs; pass them mutably where required, since they may be used
346    // by a different ADC.
347    device: AdcDevice,
348    pub cfg: AdcConfig,
349    /// This field is managed internally, and is set up on init.
350    pub vdda_calibrated: f32,
351}
352
353// todo: Remove this macro, and replace using a `regs` fn like you use in GPIO.
354macro_rules! hal {
355    ($ADC:ident, $ADC_COMMON:ident, $adc:ident, $rcc_num:tt) => {
356        impl Adc<pac::$ADC> {
357            paste! {
358                /// Initialize an ADC peripheral, including configuration register writes, enabling and resetting
359                /// its RCC peripheral clock, and calibrtation.
360                ///
361                /// If used with ADC1, this also performs VDDA measurement,
362                /// used for converting raw output to voltage. If using an ADC other than ADC1, this measurement
363                /// is skipped, and 3.3V is assumed. In this case, it's recommended to setup ADC1, read
364                /// it's VDDA value (`vdda_calibrated` field), and update the ADC in question with it.
365                pub fn [<new_ $adc>](
366                    regs: pac::$ADC,
367                    device: AdcDevice,
368                    cfg: AdcConfig,
369                    ahb_freq: u32, // Used for blocking delays in init.
370                ) -> Result<Self> {
371                    let mut adc = Self {
372                        regs,
373                        device,
374                        cfg,
375                        vdda_calibrated: 0.
376                    };
377
378                    let rcc = unsafe { &(*RCC::ptr()) };
379                    let common_regs = unsafe { &*pac::$ADC_COMMON::ptr() };
380
381                    // Note: We only perform RCC enabling, not resetingg; resetting will
382                    // cause ADCs that share RCC en/reset registers (eg ADC1/2 on G4) that
383                    // were previously set up to stop working.
384                    paste! {
385                        cfg_if! {
386                            if #[cfg(feature = "f3")] {
387                                rcc_en_reset!(ahb1, [<adc $rcc_num>], rcc);
388                            } else if #[cfg(feature = "f4")] {
389                                rcc_en_reset!(2, [<adc $rcc_num>], rcc);
390                            } else if #[cfg(feature = "h7")] {
391                                match device {
392                                    AdcDevice::One | AdcDevice::Two => {
393                                        rcc.ahb1enr().modify(|_, w| w.adc12en().bit(true));
394                                    }
395                                    AdcDevice::Three => {
396                                        rcc.ahb4enr().modify(|_, w| w.adc3en().bit(true));
397                                    }
398                                }
399                            } else if #[cfg(any(feature = "g4"))] {
400                                rcc.ahb2enr().modify(|_, w| w.adc12en().bit(true));
401                                // rcc_en_reset!(ahb2, [<adc $rcc_num>], rcc);
402                            } else {  // ie L4, L5, G0(?)
403                                rcc_en_reset!(ahb2, adc, rcc);
404                            }
405                        }
406                    }
407
408                    common_regs.ccr().modify(|_, w| unsafe {
409                        #[cfg(not(any(feature = "f3", feature = "l4x5")))] // PAC ommission l4x5?
410                        w.presc().bits(adc.cfg.prescaler as u8);
411                        return w.ckmode().bits(adc.cfg.clock_mode as u8);
412                    });
413
414                    adc.set_align(Align::default());
415
416
417                    adc.advregen_enable(ahb_freq);
418
419                    adc.calibrate(InputType::SingleEnded, ahb_freq)?;
420                    adc.calibrate(InputType::Differential, ahb_freq)?;
421
422                    // Reference Manual: "ADEN bit cannot be set during ADCAL=1
423                    // and 4 ADC clock cycle after the ADCAL
424                    // bit is cleared by hardware."
425                    let adc_per_cpu_cycles = match adc.cfg.clock_mode {
426                        ClockMode::Async => 1,
427                        ClockMode::SyncDiv1 => 1,
428                        ClockMode::SyncDiv2 => 2,
429                        ClockMode::SyncDiv4 => 4,
430                    };
431                    asm::delay(adc_per_cpu_cycles * 4 * 2); // additional x2 is a pad;
432
433                    // "Must be used when ADC clock > 20 MHz
434                    // ...The software is allowed to write this bit only when ADSTART=0 and JADSTART=0 (which
435                    // ensures that no conversion is ongoing)."
436                    // todo: On H7, allow disabling boost, either manually, or by checking the clock speed.
437                    #[cfg(all(feature = "h7", not(any(feature = "h743", feature = "h753", feature = "h735"))))]
438                    adc.regs.cr().modify(|_, w| unsafe { w.boost().bits(1)});
439
440                    #[cfg(any(feature = "h743", feature = "h753"))]
441                    adc.regs.cr().modify(|_, w| w.boost().bit(true));
442
443                    // #[cfg(feature = "h735")]
444                    // result.regs.cr().modify(|_, w| w.boost().bits(1));
445
446                    adc.enable()?;
447
448                    // Set up VDDA only after the ADC is otherwise enabled.
449                    adc.setup_vdda(ahb_freq)?;
450
451                    // Don't set continuous mode until after configuring VDDA, since it needs
452                    // to take a oneshot reading.
453                    adc.regs.cfgr().modify(|_, w| w.cont().bit(adc.cfg.operation_mode as u8 != 0));
454
455                    for ch in 1..10 {
456                        adc.set_sample_time(ch, adc.cfg.sample_time)?;
457                    }
458                    // Note: We are getting a hardfault on G431 when setting this for channel 10.
459                    for ch in 11..19 {
460                        adc.set_sample_time(ch, adc.cfg.sample_time)?;
461                    }
462
463                    Ok(adc)
464                }
465            }
466
467            // /// Get the current ADC effective clock speed, in Mhz.
468            // pub fn speed(clocks: &ClockCfg) -> u32 {
469            //     0 // todo
470            // }
471
472            /// Set the ADC conversion sequence length, between 1 and 16.
473            pub fn set_sequence_len(&mut self, len: u8) {
474                if len - 1 >= 16 {
475                    panic!("ADC sequence length must be in 1..=16")
476                }
477
478                self.regs.sqr1().modify(|_, w| unsafe { w.l().bits(len - 1) });
479            }
480
481            /// Set the alignment mode.
482            pub fn set_align(&self, align: Align) {
483                #[cfg(all(feature = "h7", not(feature = "h735")))]
484                self.regs.cfgr2().modify(|_, w| unsafe { w.lshift().bits(align as u8)});
485                // todo: How to do on H735?
486
487                #[cfg(not(feature = "h7"))]
488                self.regs.cfgr().modify(|_, w| w.align().bit(align as u8 != 0));
489            }
490
491            /// Enable the ADC.
492            /// ADEN=1 enables the ADC. The flag ADRDY will be set once the ADC is ready for
493            /// operation.
494            pub fn enable(&mut self) -> Result<()> {
495                // 1. Clear the ADRDY bit in the ADC_ISR register by writing ‘1’.
496                self.regs.isr().modify(|_, w| w.adrdy().bit(true));
497                // 2. Set ADEN=1.
498                self.regs.cr().modify(|_, w| w.aden().bit(true));  // Enable
499                // 3. Wait until ADRDY=1 (ADRDY is set after the ADC startup time). This can be done
500                // using the associated interrupt (setting ADRDYIE=1).
501                // Wait until ready
502                bounded_loop!(self.regs.isr().read().adrdy().bit_is_clear(), Error::RegisterUnchanged);
503                // 4. Clear the ADRDY bit in the ADC_ISR register by writing ‘1’ (optional).
504                self.regs.isr().modify(|_, w| w.adrdy().bit(true));
505
506                Ok(())
507            }
508
509            /// Disable the ADC.
510            /// ADDIS=1 disables the ADC. ADEN and ADDIS are then automatically cleared by
511            /// hardware as soon as the analog ADC is effectively disabled
512            pub fn disable(&mut self) -> Result<()> {
513                // 1. Check that both ADSTART=0 and JADSTART=0 to ensure that no conversion is
514                // ongoing. If required, stop any regular and injected conversion ongoing by setting
515                // ADSTP=1 and JADSTP=1 and then wait until ADSTP=0 and JADSTP=0.
516                self.stop_conversions()?;
517
518                // 2. Set ADDIS=1.
519                self.regs.cr().modify(|_, w| w.addis().bit(true)); // Disable
520
521                // 3. If required by the application, wait until ADEN=0, until the analog
522                // ADC is effectively disabled (ADDIS will automatically be reset once ADEN=0)
523                bounded_loop!(self.regs.cr().read().aden().bit_is_set(), Error::RegisterUnchanged);
524
525                Ok(())
526            }
527
528            /// If any conversions are in progress, stop them. This is a step listed in the RMs
529            /// for disable, and calibration procedures. See L4 RM: 16.4.17.
530            /// When the ADSTP bit is set by software, any ongoing regular conversion is aborted with
531            /// partial result discarded (ADC_DR register is not updated with the current conversion).
532            /// When the JADSTP bit is set by software, any ongoing injected conversion is aborted with
533            /// partial result discarded (ADC_JDRy register is not updated with the current conversion).
534            /// The scan sequence is also aborted and reset (meaning that relaunching the ADC would
535            /// restart a new sequence).
536            pub fn stop_conversions(&mut self) -> Result<()> {
537                // The software can decide to stop regular conversions ongoing by setting ADSTP=1 and
538                // injected conversions ongoing by setting JADSTP=1.
539                // Stopping conversions will reset the ongoing ADC operation. Then the ADC can be
540                // reconfigured (ex: changing the channel selection or the trigger) ready for a new operation.
541                let cr_val = self.regs.cr().read();
542                if cr_val.adstart().bit_is_set() || self.regs.cr().read().jadstart().bit_is_set() {
543                    self.regs.cr().modify(|_, w| {
544                        w.adstp().bit(true);
545                        w.jadstp().bit(true)
546                    });
547                    bounded_loop!(
548                        self.regs.cr().read().adstart().bit_is_set() || self.regs.cr().read().jadstart().bit_is_set(),
549                        Error::RegisterUnchanged
550                    );
551                }
552                Ok(())
553            }
554
555            /// Check if the ADC is enabled.
556            pub fn is_enabled(&self) -> bool {
557                self.regs.cr().read().aden().bit_is_set()
558            }
559
560            /// Check if the ADC voltage regulator is enabled.
561            pub fn is_advregen_enabled(&self) -> bool {
562                cfg_if! {
563                    if #[cfg(feature = "f3")] {
564                        self.regs.cr().read().advregen().bits() == 1
565                    } else {
566                        self.regs.cr().read().advregen().bit_is_set()
567                    }
568                }
569            }
570
571            /// Enable the ADC voltage regulator, and exit deep sleep mode (some MCUs)
572            pub fn advregen_enable(&mut self, ahb_freq: u32) {
573                cfg_if! {
574                    if #[cfg(feature = "f3")] {
575                        // `F303 RM, 15.3.6:
576                        // 1. Change ADVREGEN\[1:0\] bits from ‘10’ (disabled state, reset state) into ‘00’.
577                        // 2. Change ADVREGEN\[1:0\] bits from ‘00’ into ‘01’ (enabled state).
578                        self.regs.cr().modify(|_, w| unsafe { w.advregen().bits(0b00)});
579                        self.regs.cr().modify(|_, w| unsafe { w.advregen().bits(0b01)});
580                    } else {
581                        // L443 RM, 16.4.6; G4 RM, section 21.4.6: Deep-power-down mode (DEEPPWD) and ADC voltage
582                        // regulator (ADVREGEN)
583                        //
584                        // "By default, the ADC is in Deep-power-down mode where its supply is internally switched off
585                        // to reduce the leakage currents (the reset state of bit DEEPPWD is 1 in the ADC_CR
586                        // register).
587                        // To start ADC operations, it is first needed to exit Deep-power-down mode by setting bit
588                        // DEEPPWD=0.""
589                        self.regs.cr().modify(|_, w| {
590                            w.deeppwd().clear_bit();   // Exit deep sleep mode.
591                            w.advregen().bit(true)   // Enable voltage regulator.
592
593                        });
594                    }
595                }
596
597                self.wait_advregen_startup(ahb_freq)
598            }
599
600            /// Disable power, eg to save power in low power modes. Inferred from RM,
601            /// we should run this before entering `STOP` mode, in conjunction with with
602            /// disabling the ADC.
603            pub fn advregen_disable(&mut self) {
604                cfg_if! {
605                    if #[cfg(feature = "f3")] {
606                        // `F303 RM, 15.3.6:
607                        // 1. Change ADVREGEN\[1:0\] bits from ‘01’ (enabled state) into ‘00’.
608                        // 2. Change ADVREGEN\[1:0\] bits from ‘00’ into ‘10’ (disabled state)
609                        self.regs.cr().modify(|_, w| unsafe { w.advregen().bits(0b00) });
610                        self.regs.cr().modify(|_, w| unsafe { w.advregen().bits(0b10) });
611                    } else {
612                        // L4 RM, 16.4.6: Writing DEEPPWD=1 automatically disables the ADC voltage
613                        // regulator and bit ADVREGEN is automatically cleared.
614                        // When the internal voltage regulator is disabled (ADVREGEN=0), the internal analog
615                        // calibration is kept.
616                        // In ADC Deep-power-down mode (DEEPPWD=1), the internal analog calibration is lost and
617                        // it is necessary to either relaunch a calibration or re-apply the calibration factor which was
618                        // previously saved (
619                        self.regs.cr().modify(|_, w| w.deeppwd().bit(true));
620                        // todo: We could offer an option to disable advregen without setting deeppwd,
621                        // todo, which would keep calibration.
622                    }
623                }
624            }
625
626            /// Wait for the advregen to startup.
627            ///
628            /// This is based on the MAX_ADVREGEN_STARTUP_US of the device.
629            fn wait_advregen_startup(&self, ahb_freq: u32) {
630                crate::delay_us(MAX_ADVREGEN_STARTUP_US, ahb_freq)
631            }
632
633            /// Calibrate. See L4 RM, 16.5.8, or F404 RM, section 15.3.8.
634            /// Stores calibration values, which can be re-inserted later,
635            /// eg after entering ADC deep sleep mode, or MCU STANDBY or VBAT.
636            pub fn calibrate(&mut self, input_type: InputType, ahb_freq: u32) -> Result<()> {
637                // 1. Ensure DEEPPWD=0, ADVREGEN=1 and that ADC voltage regulator startup time has
638                // elapsed.
639                if !self.is_advregen_enabled() {
640                    self.advregen_enable(ahb_freq);
641                }
642
643                let was_enabled = self.is_enabled();
644                // Calibration can only be initiated when the ADC is disabled (when ADEN=0).
645                // 2. Ensure that ADEN=0
646                if was_enabled {
647                    self.disable()?;
648                }
649
650                self.regs.cr().modify(|_, w| w
651                    // RM:
652                    // The calibration factor to be applied for single-ended input conversions is different from the
653                    // factor to be applied for differential input conversions:
654                    // • Write ADCALDIF=0 before launching a calibration which will be applied for singleended input conversions.
655                    // • Write ADCALDIF=1 before launching a calibration which will be applied for differential
656                    // input conversions.
657                    // 3. Select the input mode for this calibration by setting ADCALDIF=0 (single-ended input)
658                    // or ADCALDIF=1 (differential input).
659                    .adcaldif().bit(input_type as u8 != 0)
660                    // The calibration is then initiated by software by setting bit ADCAL=1.
661                    // 4. Set ADCAL=1.
662                    .adcal().bit(true)); // start calibration.
663
664                // ADCAL bit stays at 1 during all the
665                // calibration sequence. It is then cleared by hardware as soon the calibration completes. At
666                // this time, the associated calibration factor is stored internally in the analog ADC and also in
667                // the bits CALFACT_S\[6:0\] or CALFACT_D\[6:0\] of ADC_CALFACT register (depending on
668                // single-ended or differential input calibration)
669                // 5. Wait until ADCAL=0.
670                bounded_loop!(
671                    self.regs.cr().read().adcal().bit_is_set(),
672                    Error::RegisterUnchanged
673                );
674
675                // 6. The calibration factor can be read from ADC_CALFACT register.
676                match input_type {
677                    InputType::SingleEnded => {
678                        let val = self.regs.calfact().read().calfact_s().bits();
679                        #[cfg(not(feature = "h7"))]
680                        let val = val as u16;
681                        #[cfg(feature = "h735")]
682                        let val = val as u16;
683                        self.cfg.cal_single_ended = Some(val);
684                    }
685                    InputType::Differential => {
686                         let val = self.regs.calfact().read().calfact_d().bits();
687                         #[cfg(not(feature = "h7"))]
688                         let val = val as u16;
689                         #[cfg(feature = "h735")]
690                         let val = val as u16;
691                         self.cfg.cal_differential = Some(val);
692                    }
693                }
694
695                if was_enabled {
696                    self.enable()?;
697                }
698
699                Ok(())
700            }
701
702            /// Insert a previously-saved calibration value into the ADC.
703            /// Se L4 RM, 16.4.8.
704            pub fn inject_calibration(&mut self) -> Result<()> {
705                // 1. Ensure ADEN=1 and ADSTART=0 and JADSTART=0 (ADC enabled and no
706                // conversion is ongoing).
707                if !self.is_enabled() {
708                    self.enable()?;
709                }
710                self.stop_conversions()?;
711
712
713                // 2. Write CALFACT_S and CALFACT_D with the new calibration factors.
714                if let Some(cal) = self.cfg.cal_single_ended {
715                    #[cfg(not(feature = "h7"))]
716                    let cal = cal as u8;
717                    self.regs.calfact().modify(|_, w| unsafe { w.calfact_s().bits(cal.try_into().unwrap()) });
718                }
719                if let Some(cal) = self.cfg.cal_differential {
720                    #[cfg(not(feature = "h7"))]
721                    let cal = cal as u8;
722                    self.regs.calfact().modify(|_, w| unsafe { w.calfact_d().bits(cal.try_into().unwrap()) });
723                }
724
725                // 3. When a conversion is launched, the calibration factor will be injected into the analog
726                // ADC only if the internal analog calibration factor differs from the one stored in bits
727                // CALFACT_S for single-ended input channel or bits CALFACT_D for differential input
728                // channel.
729                Ok(())
730            }
731
732            /// Select single-ended, or differential conversions for a given channel.
733            pub fn set_input_type(&mut self, channel: u8, input_type: InputType) -> Result<()> {
734                // L44 RM, 16.4.7:
735                // Channels can be configured to be either single-ended input or differential input by writing
736                // into bits DIFSEL\[15:1\] in the ADC_DIFSEL register. This configuration must be written while
737                // the ADC is disabled (ADEN=0). Note that DIFSEL\[18:16,0\] are fixed to single ended
738                // channels and are always read as 0.
739                let was_enabled = self.is_enabled();
740                if was_enabled {
741                    self.disable()?;
742                }
743
744                // Note that we don't use the `difsel` PAC accessor here, due to its varying
745                // implementations across different PACs.
746                // todo: 1 offset? Experiment in firmware.
747                let val = self.regs.difsel().read().bits();
748
749                let val_new = match input_type {
750                    InputType::SingleEnded => val & !(1 << channel),
751                    InputType::Differential => val | (1 << channel),
752                };
753                self.regs.difsel().write(|w| unsafe { w.bits(val_new)});
754
755                // The commented code below is for some PAC variants taht support a method to
756                // choose the diffsel field.
757
758                // let v = input_type as u8 != 0;
759                // self.regs.difsel().modify(|_, w| {
760                //     match channel {
761                //         // todo: Do these need to be offset by 1??
762                //         0 => w.difsel_0().bit(v),
763                //         1 => w.difsel_1().bit(v),
764                //         2 => w.difsel_2().bit(v),
765                //         3 => w.difsel_3().bit(v),
766                //         4 => w.difsel_4().bit(v),
767                //         5 => w.difsel_5().bit(v),
768                //         6 => w.difsel_6().bit(v),
769                //         7 => w.difsel_7().bit(v),
770                //         8 => w.difsel_8().bit(v),
771                //         9 => w.difsel_9().bit(v),
772                //         10 => w.difsel_10().bit(v),
773                //         11 => w.difsel_11().bit(v),
774                //         12 => w.difsel_12().bit(v),
775                //         13 => w.difsel_13().bit(v),
776                //         14 => w.difsel_14().bit(v),
777                //         15 => w.difsel_15().bit(v),
778                //         16 => w.difsel_16().bit(v),
779                //         17 => w.difsel_17().bit(v),
780                //         18 => w.difsel_18().bit(v),
781                //         _ => panic!(),
782                //     }
783                // });
784
785                if was_enabled {
786                    self.enable()?;
787                }
788                Ok(())
789            }
790
791            /// Select a sequence to sample, by inputting a single channel and position.
792            pub fn set_sequence(&mut self, chan: u8, position: u8) {
793                match position {
794                    1 => self.regs.sqr1().modify(|_, w| unsafe { w.sq1().bits(chan) }),
795                    2 => self.regs.sqr1().modify(|_, w| unsafe { w.sq2().bits(chan) }),
796                    3 => self.regs.sqr1().modify(|_, w| unsafe { w.sq3().bits(chan) }),
797                    4 => self.regs.sqr1().modify(|_, w| unsafe { w.sq4().bits(chan) }),
798                    5 => self.regs.sqr2().modify(|_, w| unsafe { w.sq5().bits(chan) }),
799                    6 => self.regs.sqr2().modify(|_, w| unsafe { w.sq6().bits(chan) }),
800                    7 => self.regs.sqr2().modify(|_, w| unsafe { w.sq7().bits(chan) }),
801                    8 => self.regs.sqr2().modify(|_, w| unsafe { w.sq8().bits(chan) }),
802                    9 => self.regs.sqr2().modify(|_, w| unsafe { w.sq9().bits(chan) }),
803                    10 => self.regs.sqr3().modify(|_, w| unsafe { w.sq10().bits(chan) }),
804                    11 => self.regs.sqr3().modify(|_, w| unsafe { w.sq11().bits(chan) }),
805                    12 => self.regs.sqr3().modify(|_, w| unsafe { w.sq12().bits(chan) }),
806                    13 => self.regs.sqr3().modify(|_, w| unsafe { w.sq13().bits(chan) }),
807                    14 => self.regs.sqr3().modify(|_, w| unsafe { w.sq14().bits(chan) }),
808                    15 => self.regs.sqr4().modify(|_, w| unsafe { w.sq15().bits(chan) }),
809                    16 => self.regs.sqr4().modify(|_, w| unsafe { w.sq16().bits(chan) }),
810                    _ => panic!("Sequence out of bounds. Only 16 positions are available, starting at 1."),
811                };
812
813                #[cfg(all(feature = "h7", not(feature = "h735")))]
814                self.regs.pcsel().modify(|r, w| unsafe { w.pcsel().bits(r.pcsel().bits() | (1 << chan)) });
815
816                // todo: Figure this out, and put back (July 2025/pack 0.16)
817                // #[cfg(feature = "h735")]
818                // match chan {
819                //     0 => self.regs.pcsel().modify(|r, w| w.pcsel0().bit(true)),
820                //     1 => self.regs.pcsel().modify(|r, w| w.pcsel1().bit(true)),
821                //     2 => self.regs.pcsel().modify(|r, w| w.pcsel2().bit(true)),
822                //     3 => self.regs.pcsel().modify(|r, w| w.pcsel3().bit(true)),
823                //     4 => self.regs.pcsel().modify(|r, w| w.pcsel4().bit(true)),
824                //     5 => self.regs.pcsel().modify(|r, w| w.pcsel5().bit(true)),
825                //     6 => self.regs.pcsel().modify(|r, w| w.pcsel6().bit(true)),
826                //     7 => self.regs.pcsel().modify(|r, w| w.pcsel7().bit(true)),
827                //     8 => self.regs.pcsel().modify(|r, w| w.pcsel8().bit(true)),
828                //     9 => self.regs.pcsel().modify(|r, w| w.pcsel9().bit(true)),
829                //     10 => self.regs.pcsel().modify(|r, w| w.pcsel10().bit(true)),
830                //     11 => self.regs.pcsel().modify(|r, w| w.pcsel11().bit(true)),
831                //     12 => self.regs.pcsel().modify(|r, w| w.pcsel12().bit(true)),
832                //     13 => self.regs.pcsel().modify(|r, w| w.pcsel13().bit(true)),
833                //     14 => self.regs.pcsel().modify(|r, w| w.pcsel14().bit(true)),
834                //     15 => self.regs.pcsel().modify(|r, w| w.pcsel15().bit(true)),
835                //     16 => self.regs.pcsel().modify(|r, w| w.pcsel16().bit(true)),
836                //     17 => self.regs.pcsel().modify(|r, w| w.pcsel17().bit(true)),
837                //     18 => self.regs.pcsel().modify(|r, w| w.pcsel18().bit(true)),
838                //     19=> self.regs.pcsel().modify(|r, w| w.pcsel19().bit(true)),
839                //     _ => ()
840                // };
841            }
842
843            /// Select the sample time for a given channel.
844            pub fn set_sample_time(&mut self, chan: u8, smp: SampleTime) -> Result<()> {
845                // Channel is the ADC channel to use.
846
847                // RM: Note: only allowed when ADSTART = 0 and JADSTART = 0.
848                self.stop_conversions()?;
849
850                // self.disable();
851                // while self.regs.cr().read().adstart().bit_is_set() || self.regs.cr().read().jadstart().bit_is_set() {}
852
853                unsafe {
854                    match chan {
855                        #[cfg(not(feature = "f3"))]
856                        0 => self.regs.smpr1().modify(|_, w| w.smp0().bits(smp as u8)),
857                        1 => self.regs.smpr1().modify(|_, w| w.smp1().bits(smp as u8)),
858                        2 => self.regs.smpr1().modify(|_, w| w.smp2().bits(smp as u8)),
859                        3 => self.regs.smpr1().modify(|_, w| w.smp3().bits(smp as u8)),
860                        4 => self.regs.smpr1().modify(|_, w| w.smp4().bits(smp as u8)),
861                        5 => self.regs.smpr1().modify(|_, w| w.smp5().bits(smp as u8)),
862                        6 => self.regs.smpr1().modify(|_, w| w.smp6().bits(smp as u8)),
863                        7 => self.regs.smpr1().modify(|_, w| w.smp7().bits(smp as u8)),
864                        8 => self.regs.smpr1().modify(|_, w| w.smp8().bits(smp as u8)),
865                        9 => self.regs.smpr1().modify(|_, w| w.smp9().bits(smp as u8)),
866                        11 => self.regs.smpr2().modify(|_, w| w.smp10().bits(smp as u8)),
867                        12 => self.regs.smpr2().modify(|_, w| w.smp12().bits(smp as u8)),
868                        13 => self.regs.smpr2().modify(|_, w| w.smp13().bits(smp as u8)),
869                        14 => self.regs.smpr2().modify(|_, w| w.smp14().bits(smp as u8)),
870                        15 => self.regs.smpr2().modify(|_, w| w.smp15().bits(smp as u8)),
871                        16 => self.regs.smpr2().modify(|_, w| w.smp16().bits(smp as u8)),
872                        17 => self.regs.smpr2().modify(|_, w| w.smp17().bits(smp as u8)),
873                        18 => self.regs.smpr2().modify(|_, w| w.smp18().bits(smp as u8)),
874                        // 19 => self.regs.smpr2().modify(|_, w| w.smp19().bits(smp as u8)),
875                        // 20 => self.regs.smpr2().modify(|_, w| w.smp20().bits(smp as u8)),
876                        _ => unreachable!(),
877                    };
878                }
879
880                Ok(())
881                // self.enable();
882            }
883
884
885            /// Find and store the internal voltage reference, to improve conversion from reading
886            /// to voltage accuracy. See L44 RM, section 16.4.34: "Monitoring the internal voltage reference"
887            fn setup_vdda(&mut self, ahb_freq: u32) -> Result<()> {
888                let common_regs = unsafe { &*pac::$ADC_COMMON::ptr() };
889                // RM: It is possible to monitor the internal voltage reference (VREFINT) to have a reference point for
890                // evaluating the ADC VREF+ voltage level.
891                // The internal voltage reference is internally connected to the input channel 0 of the ADC1
892                // (ADC1_INP0).
893
894                // todo: On H7, you may need to use ADC3 for this...
895
896                // Regardless of which ADC we're on, we take this reading using ADC1.
897                self.vdda_calibrated = if self.device != AdcDevice::One {
898                    // todo: What if ADC1 is already enabled and configured differently?
899                    // todo: Either way, if you're also using ADC1, this will screw things up⋅.
900
901                    // let dp = unsafe { pac::Peripherals::steal() };
902                    //
903                    // #[cfg(feature = "l5")]
904                    // let dp_adc = dp.ADC;
905                    // #[cfg(not(feature = "l5"))]
906                    // let dp_adc = dp.ADC1;
907
908                    // If we're currently using ADC1 (and this is a different ADC), skip this step for now;
909                    // VDDA will be wrong,
910                    // and all readings using voltage conversion will be wrong.
911                    // todo: Take an ADC1 reading if this is the case, or let the user pass in VDDA from there.
912                    // if dp_adc.cr().read().aden().bit_is_set() {
913                    //     self.vdda_calibrated = 3.3; // A guess.
914                    //     return
915                    // }
916
917                    // todo: Get this working.
918                    // let mut adc1 = Adc::new_adc1(
919                    //     dp_adc,
920                    //     AdcDevice::One,
921                    //     // We use self cfg, in case ADC1 is on the same common regs as this; we don't
922                    //     // want it overwriting prescaler and clock cfg.
923                    //     self.cfg.clone(),
924                    //     ahb_freq,
925                    // );
926                    // adc1.disable();
927
928                    // This fn will be called recursively for ADC1, generating the vdda value we need.
929                    // adc1.vdda_calibrated
930                    3.3
931                } else {
932                    // "Table 24. Embedded internal voltage reference" states that the sample time needs to be
933                    // at a minimum 4 us. With 640.5 ADC cycles we have a minimum of 8 us at 80 MHz, leaving
934                    // some headroom.
935
936                    common_regs.ccr().modify(|_, w| w.vrefen().bit(true));
937                    // User manual table: "Embedded internal voltage reference" states that it takes a maximum of 12 us
938                    // to stabilize the internal voltage reference, we wait a little more.
939
940                    // todo: Not sure what to set this delay to and how to change it based on variant, so picking
941                    // todo something conservative.
942                    crate::delay_us(100, ahb_freq);
943
944                    // This sample time is overkill.
945                    // Note that you will need to reset the sample time if you use this channel on this
946                    // ADC for something other than reading vref later.
947                    self.set_sample_time(VREFINT_CH, SampleTime::T601)?;
948                    let reading = self.read(VREFINT_CH)?;
949                    self.stop_conversions()?;
950
951                    common_regs.ccr().modify(|_, w| w.vrefen().clear_bit());
952
953                    // The VDDA power supply voltage applied to the microcontroller may be subject to variation or
954                    // not precisely known. The embedded internal voltage reference (VREFINT) and its calibration
955                    // data acquired by the ADC during the manufacturing process at VDDA = 3.0 V can be used to
956                    // evaluate the actual VDDA voltage level.
957                    // The following formula gives the actual VDDA voltage supplying the device:
958                    // VDDA = 3.0 V x VREFINT_CAL / VREFINT_DATA
959                    // where:
960                    // • VREFINT_CAL is the VREFINT calibration value
961                    // • VREFINT_DATA is the actual VREFINT output value converted by ADC
962
963                    // todo: This address may be different on different MCUs, even within the same family.
964                    // Although, it seems relatively consistent. Check User Manuals.
965                    let vrefint_cal: u16 = unsafe { ptr::read_volatile(&*(VREFINT_ADDR as *const _)) };
966                    VREFINT_VOLTAGE * vrefint_cal as f32 / reading as f32
967                };
968
969                Ok(())
970            }
971
972            /// Convert a raw measurement into a voltage in Volts, using the calibrated VDDA.
973            /// See RM0394, section 16.4.34
974            pub fn reading_to_voltage(&self, reading: u16) -> f32 {
975                // RM:
976                // Converting a supply-relative ADC measurement to an absolute voltage value
977                // The ADC is designed to deliver a digital value corresponding to the ratio between the analog
978                // power supply and the voltage applied on the converted channel. For most application use
979                // cases, it is necessary to convert this ratio into a voltage independent of VDDA. For
980                // applications where VDDA is known and ADC converted values are right-aligned you can use
981                // the following formula to get this absolute value:
982
983                // V_CHANNELx = V_DDA / FULL_SCALE x ADCx_DATA
984
985                // Where:
986                // • VREFINT_CAL is the VREFINT calibration value
987                // • ADC_DATA is the value measured by the ADC on channel x (right-aligned)
988                // • VREFINT_DATA is the actual VREFINT output value converted by the ADC
989                // • FULL_SCALE is the maximum digital value of the ADC output. For example with 12-bit
990                // resolution, it will be 212 − 1 = 4095 or with 8-bit resolution, 28 − 1 = 255
991                // todo: FULL_SCALE will be different for 16-bit. And differential?
992
993                self.vdda_calibrated / 4_096. * reading as f32
994            }
995
996            /// Start a conversion: Either a single measurement, or continuous conversions.
997            /// Blocks until the conversion is complete.
998            /// See L4 RM 16.4.15 for details.
999            pub fn start_conversion(&mut self, sequence: &[u8]) -> Result<()> {
1000                // todo: You should call this elsewhere, once, to prevent unneded reg writes.
1001                for (i, channel) in sequence.iter().enumerate() {
1002                    self.set_sequence(*channel, i as u8 + 1); // + 1, since sequences start at 1.
1003                }
1004
1005                // L4 RM: In Single conversion mode, the ADC performs once all the conversions of the channels.
1006                // This mode is started with the CONT bit at 0 by either:
1007                // • Setting the ADSTART bit in the ADC_CR register (for a regular channel)
1008                // • Setting the JADSTART bit in the ADC_CR register (for an injected channel)
1009                // • External hardware trigger event (for a regular or injected channel)
1010                // (Here, we assume a regular channel)
1011                self.regs.cr().modify(|_, w| w.adstart().bit(true));  // Start
1012
1013                // After the regular sequence is complete, after each conversion is complete,
1014                // the EOC (end of regular conversion) flag is set.
1015                // After the regular sequence is complete: The EOS (end of regular sequence) flag is set.
1016                // wait until complete.
1017                bounded_loop!(
1018                    self.regs.isr().read().eos().bit_is_clear(),
1019                    Error::RegisterUnchanged
1020                );
1021
1022                Ok(())
1023            }
1024
1025            #[cfg(feature = "h7")]
1026            /// Read data from a conversion. In OneShot mode, this will generally be run right
1027            /// after `start_conversion`.
1028            pub fn read_result(&mut self, ch: u8) -> u16 {
1029                #[cfg(not(feature = "h735"))]
1030                self.regs.pcsel().modify(|r, w| unsafe { w.pcsel().bits(r.pcsel().bits() & !(1 << ch)) });
1031
1032                // todo: Figure this out, and put back (July 2025/pack 0.16)
1033                // #[cfg(feature = "h735")]
1034                // match ch {
1035                //     0 => self.regs.pcsel().modify(|r, w| w.pcsel0().bit(true)),
1036                //     1 => self.regs.pcsel().modify(|r, w| w.pcsel1().bit(true)),
1037                //     2 => self.regs.pcsel().modify(|r, w| w.pcsel2().bit(true)),
1038                //     3 => self.regs.pcsel().modify(|r, w| w.pcsel3().bit(true)),
1039                //     4 => self.regs.pcsel().modify(|r, w| w.pcsel4().bit(true)),
1040                //     5 => self.regs.pcsel().modify(|r, w| w.pcsel5().bit(true)),
1041                //     6 => self.regs.pcsel().modify(|r, w| w.pcsel6().bit(true)),
1042                //     7 => self.regs.pcsel().modify(|r, w| w.pcsel7().bit(true)),
1043                //     8 => self.regs.pcsel().modify(|r, w| w.pcsel8().bit(true)),
1044                //     9 => self.regs.pcsel().modify(|r, w| w.pcsel9().bit(true)),
1045                //     10 => self.regs.pcsel().modify(|r, w| w.pcsel10().bit(true)),
1046                //     11 => self.regs.pcsel().modify(|r, w| w.pcsel11().bit(true)),
1047                //     12 => self.regs.pcsel().modify(|r, w| w.pcsel12().bit(true)),
1048                //     13 => self.regs.pcsel().modify(|r, w| w.pcsel13().bit(true)),
1049                //     14 => self.regs.pcsel().modify(|r, w| w.pcsel14().bit(true)),
1050                //     15 => self.regs.pcsel().modify(|r, w| w.pcsel15().bit(true)),
1051                //     16 => self.regs.pcsel().modify(|r, w| w.pcsel16().bit(true)),
1052                //     17 => self.regs.pcsel().modify(|r, w| w.pcsel17().bit(true)),
1053                //     18 => self.regs.pcsel().modify(|r, w| w.pcsel18().bit(true)),
1054                //     19=> self.regs.pcsel().modify(|r, w| w.pcsel19().bit(true)),
1055                //     _ => ()
1056                // }
1057
1058                return self.regs.dr().read().bits() as u16;
1059                return self.regs.dr().read().rdata().bits() as u16;
1060            }
1061
1062            #[cfg(not(feature = "h7"))]
1063            /// Read data from a conversion. In OneShot mode, this will generally be run right
1064            /// after `start_conversion`.
1065            pub fn read_result(&mut self) -> u16 {
1066                #[cfg(feature = "l4")]
1067                return self.regs.dr().read().bits() as u16;
1068                #[cfg(not(feature = "l4"))]
1069                return self.regs.dr().read().rdata().bits() as u16;
1070            }
1071
1072            /// Take a single reading; return a raw integer value.
1073            pub fn read(&mut self, channel: u8) -> Result<u16> {
1074                self.start_conversion(&[channel])?;
1075                #[cfg(feature = "h7")]
1076                return Ok(self.read_result(channel));
1077                #[cfg(not(feature = "h7"))]
1078                return Ok(self.read_result());
1079            }
1080
1081            /// Take a single reading; return a voltage.
1082            pub fn read_voltage(&mut self, channel: u8) -> Result<f32> {
1083                let reading = self.read(channel)?;
1084                Ok(self.reading_to_voltage(reading))
1085            }
1086
1087            /// Select and activate a trigger. See G4 RM, section 21.4.18:
1088            /// Conversion on external trigger and trigger polarit
1089            pub fn set_trigger(&mut self, trigger: Trigger, edge: TriggerEdge) {
1090                self.regs.cfgr().modify(|_, w| unsafe {
1091                    w.exten().bits(edge as u8);
1092                    w.extsel().bits(trigger as u8)
1093                });
1094            }
1095
1096            #[cfg(not(any(feature = "f4", feature = "l552", feature = "h5")))]
1097            /// Take a reading, using DMA. Sets conversion sequence; no need to set it directly.
1098            /// Note that the `channel` argument is unused on F3 and L4, since it is hard-coded,
1099            /// and can't be configured using the DMAMUX peripheral. (`dma::mux()` fn).
1100            pub unsafe fn read_dma(
1101                &mut self, buf: &mut [u16],
1102                adc_channels: &[u8],
1103                dma_channel: DmaChannel,
1104                channel_cfg: ChannelCfg,
1105                dma_periph: dma::DmaPeriph,
1106            ) -> Result<()> {
1107                let (ptr, len) = (buf.as_mut_ptr(), buf.len());
1108                // The software is allowed to write (dmaen and dmacfg) only when ADSTART=0 and JADSTART=0 (which
1109                // ensures that no conversion is ongoing)
1110                self.stop_conversions()?;
1111
1112                #[cfg(not(feature = "h7"))]
1113                self.regs.cfgr().modify(|_, w| {
1114                    w.dmacfg().bit(channel_cfg.circular == dma::Circular::Enabled);
1115                    w.dmaen().bit(true)
1116                });
1117
1118                #[cfg(all(feature = "h7", not(feature = "h735")))]
1119                self.regs.cfgr().modify(|_, w| {
1120                    // Note: To use non-DMA after this has been set, need to configure manually.
1121                    // ie set back to 0b00.
1122                    w.dmngt().bits(if channel_cfg.circular == dma::Circular::Enabled { 0b11 } else { 0b01 })
1123                });
1124
1125                // todo: How to do in H735? Pac 0.16 change? Jully 2025.
1126
1127                // L44 RM, Table 41. "DMA1 requests for each channel
1128                // todo: DMA2 support.
1129                #[cfg(any(feature = "f3", feature = "l4"))]
1130                let dma_channel = match self.device {
1131                    AdcDevice::One => DmaInput::Adc1.dma1_channel(),
1132                    AdcDevice::Two => DmaInput::Adc2.dma1_channel(),
1133                    _ => panic!("DMA on ADC beyond 2 is not supported. If it is for your MCU, please submit an issue \
1134                or PR on Github.")
1135                };
1136
1137                #[cfg(feature = "l4")]
1138                match dma_periph {
1139                    dma::DmaPeriph::Dma1 => {
1140                        let mut regs = unsafe { &(*pac::DMA1::ptr()) };
1141                        match self.device {
1142                            AdcDevice::One => dma::channel_select(&mut regs, DmaInput::Adc1),
1143                            AdcDevice::Two => dma::channel_select(&mut regs, DmaInput::Adc2),
1144                            _ => unimplemented!(),
1145                        }
1146                    }
1147                    dma::DmaPeriph::Dma2 => {
1148                        let mut regs = unsafe { &(*pac::DMA2::ptr()) };
1149                        match self.device {
1150                            AdcDevice::One => dma::channel_select(&mut regs, DmaInput::Adc1),
1151                            AdcDevice::Two => dma::channel_select(&mut regs, DmaInput::Adc2),
1152                            _ => unimplemented!(),
1153                        }
1154                    }
1155                }
1156
1157                let mut seq_len = 0;
1158                for (i, ch) in adc_channels.iter().enumerate() {
1159                    self.set_sequence(*ch, i as u8 + 1);
1160                    seq_len += 1;
1161                }
1162                self.set_sequence_len(seq_len);
1163
1164                self.regs.cr().modify(|_, w| w.adstart().bit(true));  // Start
1165
1166                // Since converted channel values are stored into a unique data register, it is useful to use
1167                // DMA for conversion of more than one channel. This avoids the loss of the data already
1168                // stored in the ADC_DR register.
1169                // When the DMA mode is enabled (DMAEN bit set to 1 in the ADC_CFGR register in single
1170                // ADC mode or MDMA different from 0b00 in dual ADC mode), a DMA request is generated
1171                // after each conversion of a channel. This allows the transfer of the converted data from the
1172                // ADC_DR register to the destination location selected by the software.
1173                // Despite this, if an overrun occurs (OVR=1) because the DMA could not serve the DMA
1174                // transfer request in time, the ADC stops generating DMA requests and the data
1175                // corresponding to the new conversion is not transferred by the DMA. Which means that all
1176                // the data transferred to the RAM can be considered as valid.
1177                // Depending on the configuration of OVRMOD bit, the data is either preserved or overwritten
1178                // (refer to Section : ADC overrun (OVR, OVRMOD)).
1179                // The DMA transfer requests are blocked until the software clears the OVR bit.
1180                // Two different DMA modes are proposed depending on the application use and are
1181                // configured with bit DMACFG of the ADC_CFGR register in single ADC mode, or with bit
1182                // DMACFG of the ADC_CCR register in dual ADC mode:
1183                // • DMA one shot mode (DMACFG=0).
1184                // This mode is suitable when the DMA is programmed to transfer a fixed number of data.
1185                // • DMA circular mode (DMACFG=1)
1186                // This mode is suitable when programming the DMA in circular mode.
1187
1188
1189                // In [DMA one shot mode], the ADC generates a DMA transfer request each time a new conversion data
1190                // is available and stops generating DMA requests once the DMA has reached the last DMA
1191                // transfer (when DMA_EOT interrupt occurs - refer to DMA paragraph) even if a conversion
1192                // has been started again.
1193                // When the DMA transfer is complete (all the transfers configured in the DMA controller have
1194                // been done):
1195                // • The content of the ADC data register is frozen.
1196                // • Any ongoing conversion is aborted with partial result discarded.
1197                // • No new DMA request is issued to the DMA controller. This avoids generating an
1198                // overrun error if there are still conversions which are started.
1199                // • Scan sequence is stopped and reset.
1200                // • The DMA is stopped.
1201
1202                let num_data = len as u32;
1203
1204                match dma_periph {
1205                    dma::DmaPeriph::Dma1 => {
1206                        let mut regs = unsafe { &(*pac::DMA1::ptr()) };
1207                        dma::cfg_channel(
1208                            &mut regs,
1209                            dma_channel,
1210                            self.regs.dr().as_ptr() as u32,
1211                            ptr as u32,
1212                            num_data,
1213                            dma::Direction::ReadFromPeriph,
1214                            dma::DataSize::S16,
1215                            dma::DataSize::S16,
1216                            channel_cfg,
1217                        )
1218                    }
1219                    #[cfg(dma2)]
1220                    dma::DmaPeriph::Dma2 => {
1221                        let mut regs = unsafe { &(*pac::DMA2::ptr()) };
1222                        dma::cfg_channel(
1223                            &mut regs,
1224                            dma_channel,
1225                            self.regs.dr().as_ptr() as u32,
1226                            ptr as u32,
1227                            num_data,
1228                            dma::Direction::ReadFromPeriph,
1229                            dma::DataSize::S16,
1230                            dma::DataSize::S16,
1231                            channel_cfg,
1232                        )
1233                    }
1234                }
1235            }
1236
1237            /// Enable a specific type of ADC interrupt.
1238            pub fn enable_interrupt(&mut self, interrupt: AdcInterrupt) {
1239                self.regs.ier().modify(|_, w| match interrupt {
1240                    AdcInterrupt::Ready => w.adrdyie().bit(true),
1241                    AdcInterrupt::EndOfConversion => w.eocie().bit(true),
1242                    AdcInterrupt::EndOfSequence => w.eosie().bit(true),
1243                    AdcInterrupt::EndofConversionInjected => w.jeocie().bit(true),
1244                    AdcInterrupt::EndOfSequenceInjected => w.jeosie().bit(true),
1245                    AdcInterrupt::Watchdog1 => w.awd1ie().bit(true),
1246                    AdcInterrupt::Watchdog2 => w.awd2ie().bit(true),
1247                    AdcInterrupt::Watchdog3 => w.awd3ie().bit(true),
1248                    AdcInterrupt::EndOfSamplingPhase => w.eosmpie().bit(true),
1249                    AdcInterrupt::Overrun => w.ovrie().bit(true),
1250                    AdcInterrupt::InjectedOverflow => w.jqovfie().bit(true),
1251                });
1252            }
1253
1254            /// Clear an interrupt flag of the specified type. Consider running this in the
1255            /// corresponding ISR.
1256            pub fn clear_interrupt(&mut self, interrupt: AdcInterrupt) {
1257                self.regs.isr().write(|w| match interrupt {
1258                    AdcInterrupt::Ready => w.adrdy().bit(true),
1259                    AdcInterrupt::EndOfConversion => w.eoc().bit(true),
1260                    AdcInterrupt::EndOfSequence => w.eos().bit(true),
1261                    AdcInterrupt::EndofConversionInjected => w.jeoc().bit(true),
1262                    AdcInterrupt::EndOfSequenceInjected => w.jeos().bit(true),
1263                    AdcInterrupt::Watchdog1 => w.awd1().bit(true),
1264                    AdcInterrupt::Watchdog2 => w.awd2().bit(true),
1265                    AdcInterrupt::Watchdog3 => w.awd3().bit(true),
1266                    AdcInterrupt::EndOfSamplingPhase => w.eosmp().bit(true),
1267                    AdcInterrupt::Overrun => w.ovr().bit(true),
1268                    AdcInterrupt::InjectedOverflow => w.jqovf().bit(true),
1269                });
1270                // match interrupt {
1271                //     AdcInterrupt::Ready => self.regs.icr().write(|_w| w.adrdy().bit(true)),
1272                //     AdcInterrupt::EndOfConversion => self.regs.icr().write(|w| w.eoc().bit(true)),
1273                //     AdcInterrupt::EndOfSequence => self.regs.icr().write(|_w| w.eos().bit(true)),
1274                //     AdcInterrupt::EndofConversionInjected => self.regs.icr().write(|_w| w.jeoc().bit(true)),
1275                //     AdcInterrupt::EndOfSequenceInjected => self.regs.icr().write(|_w| w.jeos().bit(true)),
1276                //     AdcInterrupt::Watchdog1 => self.regs.icr().write(|_w| w.awd1().bit(true)),
1277                //     AdcInterrupt::Watchdog2 => self.regs.icr().write(|_w| w.awd2().bit(true)),
1278                //     AdcInterrupt::Watchdog3 => self.regs.icr().write(|_w| w.awd3().bit(true)),
1279                //     AdcInterrupt::EndOfSamplingPhase => self.regs.icr().write(|_w| w.eosmp().bit(true)),
1280                //     AdcInterrupt::Overrun => self.regs.icr().write(|_w| w.ovr().bit(true)),
1281                //     AdcInterrupt::InjectedOverflow => self.regs.icr().write(|_w| w.jqovf().bit(true)),
1282                // }
1283            }
1284
1285
1286        /// Print the (raw) contents of the status register.
1287    pub fn read_status(&self) -> u32 {
1288        unsafe { self.regs.isr().read().bits() }
1289    }
1290        }
1291    }
1292}
1293
1294#[cfg(any(feature = "f301", feature = "f302", feature = "f303",))]
1295hal!(ADC1, ADC1_2, adc1, 12);
1296
1297#[cfg(any(feature = "f302", feature = "f303",))]
1298hal!(ADC2, ADC1_2, adc2, 12);
1299
1300#[cfg(any(feature = "f303"))]
1301hal!(ADC3, ADC3_4, adc3, 34);
1302
1303#[cfg(any(feature = "f303"))]
1304hal!(ADC4, ADC3_4, adc4, 34);
1305
1306#[cfg(any(feature = "l4", feature = "l5"))]
1307hal!(ADC1, ADC_COMMON, adc1, _);
1308
1309#[cfg(any(
1310    feature = "l4x1",
1311    feature = "l4x2",
1312    feature = "l412",
1313    feature = "l4x5",
1314    feature = "l4x6",
1315))]
1316hal!(ADC2, ADC_COMMON, adc2, _);
1317
1318#[cfg(any(feature = "l4x5", feature = "l4x6",))]
1319hal!(ADC3, ADC_COMMON, adc3, _);
1320
1321// todo Implement ADC3 on H7. The issue is the enable / reset being on ahb4.
1322cfg_if! {
1323    if #[cfg(feature = "h7")] {
1324        hal!(ADC1, ADC12_COMMON, adc1, 12);
1325        hal!(ADC2, ADC12_COMMON, adc2, 12);
1326        hal!(ADC3, ADC3_COMMON, adc3, 3);
1327    }
1328}
1329
1330cfg_if! {
1331    if #[cfg(feature = "g4")] {
1332        hal!(ADC1, ADC12_COMMON, adc1, 12);
1333        hal!(ADC2, ADC12_COMMON, adc2, 12);
1334    }
1335}
1336
1337#[cfg(all(feature = "g4", not(any(feature = "g431", feature = "g441"))))]
1338hal!(ADC3, ADC345_COMMON, adc3, 345);
1339
1340cfg_if! {
1341    if #[cfg(any(feature = "g473", feature = "g474", feature = "g483", feature = "g484"))] {
1342        hal!(ADC4, ADC345_COMMON, adc4, 345);
1343        hal!(ADC5, ADC345_COMMON, adc5, 345);
1344    }
1345}
1346
1347// todo F4 as (depending on variant?) ADC 1, 2, 3