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