esp_hal/analog/adc/
riscv.rs

1use core::marker::PhantomData;
2
3cfg_if::cfg_if! {
4    if #[cfg(esp32c6)] {
5        use Interrupt::APB_SARADC as InterruptSource;
6    } else {
7        use Interrupt::APB_ADC as InterruptSource;
8    }
9}
10
11use core::{
12    pin::Pin,
13    task::{Context, Poll},
14};
15
16// We only have to count on devices that have multiple ADCs sharing the same interrupt
17#[cfg(all(adc_adc1, adc_adc2))]
18use portable_atomic::{AtomicU32, Ordering};
19use procmacros::handler;
20
21pub use self::calibration::*;
22use super::{AdcCalSource, AdcConfig, Attenuation};
23#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2))]
24use crate::efuse::Efuse;
25use crate::{
26    Async,
27    Blocking,
28    asynch::AtomicWaker,
29    interrupt::{InterruptConfigurable, InterruptHandler},
30    peripherals::{APB_SARADC, Interrupt},
31    soc::regi2c,
32    system::{GenericPeripheralGuard, Peripheral},
33};
34
35mod calibration;
36
37// Constants taken from:
38// https://github.com/espressif/esp-idf/blob/903af13e8/components/soc/esp32c2/include/soc/regi2c_saradc.h
39// https://github.com/espressif/esp-idf/blob/903af13e8/components/soc/esp32c3/include/soc/regi2c_saradc.h
40// https://github.com/espressif/esp-idf/blob/903af13e8/components/soc/esp32c6/include/soc/regi2c_saradc.h
41// https://github.com/espressif/esp-idf/blob/903af13e8/components/soc/esp32h2/include/soc/regi2c_saradc.h
42// https://github.com/espressif/esp-idf/blob/903af13e8/components/soc/esp32h4/include/soc/regi2c_saradc.h
43cfg_if::cfg_if! {
44    if #[cfg(adc_adc1)] {
45        const ADC_VAL_MASK: u16 = 0xfff;
46        const ADC_CAL_CNT_MAX: u16 = 32;
47        const ADC_CAL_CHANNEL: u16 = 15;
48    }
49}
50
51// The number of analog IO pins, and in turn the number of attentuations,
52// depends on which chip is being used
53cfg_if::cfg_if! {
54    if #[cfg(esp32c6)] {
55        pub(super) const NUM_ATTENS: usize = 7;
56    } else {
57        pub(super) const NUM_ATTENS: usize = 5;
58    }
59}
60
61/// The sampling/readout resolution of the ADC.
62#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
63#[cfg_attr(feature = "defmt", derive(defmt::Format))]
64#[allow(clippy::enum_variant_names, reason = "peripheral is unstable")]
65pub enum Resolution {
66    /// 12-bit resolution
67    #[default]
68    Resolution12Bit,
69}
70
71impl<ADCI> AdcConfig<ADCI>
72where
73    ADCI: RegisterAccess,
74{
75    /// Calibrate ADC with specified attenuation and voltage source
76    pub fn adc_calibrate(atten: Attenuation, source: AdcCalSource) -> u16
77    where
78        ADCI: super::CalibrationAccess,
79    {
80        let mut adc_max: u16 = 0;
81        let mut adc_min: u16 = u16::MAX;
82        let mut adc_sum: u32 = 0;
83
84        ADCI::enable_vdef(true);
85
86        // Start sampling
87        ADCI::config_onetime_sample(ADC_CAL_CHANNEL as u8, atten as u8);
88
89        // Connect calibration source
90        ADCI::connect_cal(source, true);
91
92        for _ in 0..ADC_CAL_CNT_MAX {
93            ADCI::set_init_code(0);
94
95            // Trigger ADC sampling
96            ADCI::start_onetime_sample();
97
98            // Wait until ADC1 sampling is done
99            while !ADCI::is_done() {}
100
101            let adc = ADCI::read_data() & ADC_VAL_MASK;
102
103            ADCI::reset();
104
105            adc_sum += adc as u32;
106            adc_max = adc.max(adc_max);
107            adc_min = adc.min(adc_min);
108        }
109
110        let cal_val = (adc_sum - adc_max as u32 - adc_min as u32) as u16 / (ADC_CAL_CNT_MAX - 2);
111
112        // Disconnect calibration source
113        ADCI::connect_cal(source, false);
114
115        cal_val
116    }
117}
118
119#[doc(hidden)]
120pub trait RegisterAccess {
121    /// Configure onetime sampling parameters
122    fn config_onetime_sample(channel: u8, attenuation: u8);
123
124    /// Start onetime sampling
125    fn start_onetime_sample();
126
127    /// Check if sampling is done
128    fn is_done() -> bool;
129
130    /// Read sample data
131    fn read_data() -> u16;
132
133    /// Reset flags
134    fn reset();
135
136    /// Set calibration parameter to ADC hardware
137    fn set_init_code(data: u16);
138}
139
140#[cfg(adc_adc1)]
141impl RegisterAccess for crate::peripherals::ADC1<'_> {
142    fn config_onetime_sample(channel: u8, attenuation: u8) {
143        APB_SARADC::regs().onetime_sample().modify(|_, w| unsafe {
144            w.saradc1_onetime_sample().set_bit();
145            w.onetime_channel().bits(channel);
146            w.onetime_atten().bits(attenuation)
147        });
148    }
149
150    fn start_onetime_sample() {
151        APB_SARADC::regs()
152            .onetime_sample()
153            .modify(|_, w| w.onetime_start().set_bit());
154    }
155
156    fn is_done() -> bool {
157        APB_SARADC::regs().int_raw().read().adc1_done().bit()
158    }
159
160    fn read_data() -> u16 {
161        APB_SARADC::regs()
162            .sar1data_status()
163            .read()
164            .saradc1_data()
165            .bits() as u16
166            & 0xfff
167    }
168
169    fn reset() {
170        // Clear ADC1 sampling done interrupt bit
171        APB_SARADC::regs()
172            .int_clr()
173            .write(|w| w.adc1_done().clear_bit_by_one());
174
175        // Disable ADC sampling
176        APB_SARADC::regs()
177            .onetime_sample()
178            .modify(|_, w| w.onetime_start().clear_bit());
179    }
180
181    fn set_init_code(data: u16) {
182        let [msb, lsb] = data.to_be_bytes();
183
184        regi2c::ADC_SAR1_INITIAL_CODE_HIGH.write_field(msb);
185        regi2c::ADC_SAR1_INITIAL_CODE_LOW.write_field(lsb);
186    }
187}
188
189#[cfg(adc_adc1)]
190impl super::CalibrationAccess for crate::peripherals::ADC1<'_> {
191    const ADC_CAL_CNT_MAX: u16 = ADC_CAL_CNT_MAX;
192    const ADC_CAL_CHANNEL: u16 = ADC_CAL_CHANNEL;
193    const ADC_VAL_MASK: u16 = ADC_VAL_MASK;
194
195    fn enable_vdef(enable: bool) {
196        regi2c::ADC_SAR1_DREF.write_field(enable as _);
197    }
198
199    fn connect_cal(source: AdcCalSource, enable: bool) {
200        match source {
201            AdcCalSource::Gnd => regi2c::ADC_SAR1_ENCAL_GND.write_field(enable as _),
202            #[cfg(not(esp32h2))]
203            AdcCalSource::Ref => regi2c::ADC_SAR1_ENCAL_REF.write_field(enable as _),
204            // For the ESP32-H2 ground and internal reference voltage are mutually exclusive and
205            // you can toggle between them.
206            //
207            // See: <https://github.com/espressif/esp-idf/blob/5c51472e82a58098dda8d40a1c4f250c374fc900/components/hal/esp32h2/include/hal/adc_ll.h#L645>
208            #[cfg(esp32h2)]
209            AdcCalSource::Ref => regi2c::ADC_SAR1_ENCAL_GND.write_field(!enable as _),
210        }
211    }
212}
213
214#[cfg(adc_adc2)]
215impl RegisterAccess for crate::peripherals::ADC2<'_> {
216    fn config_onetime_sample(channel: u8, attenuation: u8) {
217        APB_SARADC::regs().onetime_sample().modify(|_, w| unsafe {
218            w.saradc2_onetime_sample().set_bit();
219            w.onetime_channel().bits(channel);
220            w.onetime_atten().bits(attenuation)
221        });
222    }
223
224    fn start_onetime_sample() {
225        APB_SARADC::regs()
226            .onetime_sample()
227            .modify(|_, w| w.onetime_start().set_bit());
228    }
229
230    fn is_done() -> bool {
231        APB_SARADC::regs().int_raw().read().adc2_done().bit()
232    }
233
234    fn read_data() -> u16 {
235        APB_SARADC::regs()
236            .sar2data_status()
237            .read()
238            .saradc2_data()
239            .bits() as u16
240            & 0xfff
241    }
242
243    fn reset() {
244        APB_SARADC::regs()
245            .int_clr()
246            .write(|w| w.adc2_done().clear_bit_by_one());
247
248        APB_SARADC::regs()
249            .onetime_sample()
250            .modify(|_, w| w.onetime_start().clear_bit());
251    }
252
253    fn set_init_code(data: u16) {
254        let [msb, lsb] = data.to_be_bytes();
255
256        regi2c::ADC_SAR2_INITIAL_CODE_HIGH.write_field(msb as _);
257        regi2c::ADC_SAR2_INITIAL_CODE_LOW.write_field(lsb as _);
258    }
259}
260
261#[cfg(adc_adc2)]
262impl super::CalibrationAccess for crate::peripherals::ADC2<'_> {
263    const ADC_CAL_CNT_MAX: u16 = ADC_CAL_CNT_MAX;
264    const ADC_CAL_CHANNEL: u16 = ADC_CAL_CHANNEL;
265    const ADC_VAL_MASK: u16 = ADC_VAL_MASK;
266
267    fn enable_vdef(enable: bool) {
268        regi2c::ADC_SAR2_DREF.write_field(enable as _);
269    }
270
271    fn connect_cal(source: AdcCalSource, enable: bool) {
272        match source {
273            AdcCalSource::Gnd => regi2c::ADC_SAR2_ENCAL_GND.write_field(enable as _),
274            AdcCalSource::Ref => regi2c::ADC_SAR2_ENCAL_REF.write_field(enable as _),
275        }
276    }
277}
278
279/// Analog-to-Digital Converter peripheral driver.
280pub struct Adc<'d, ADCI, Dm: crate::DriverMode> {
281    _adc: ADCI,
282    attenuations: [Option<Attenuation>; NUM_ATTENS],
283    active_channel: Option<u8>,
284    _guard: GenericPeripheralGuard<{ Peripheral::ApbSarAdc as u8 }>,
285    _phantom: PhantomData<(Dm, &'d mut ())>,
286}
287
288impl<'d, ADCI> Adc<'d, ADCI, Blocking>
289where
290    ADCI: RegisterAccess + 'd,
291{
292    /// Configure a given ADC instance using the provided configuration, and
293    /// initialize the ADC for use
294    pub fn new(adc_instance: ADCI, config: AdcConfig<ADCI>) -> Self {
295        let guard = GenericPeripheralGuard::new();
296
297        APB_SARADC::regs().ctrl().modify(|_, w| unsafe {
298            w.start_force().set_bit();
299            w.start().set_bit();
300            w.sar_clk_gated().set_bit();
301            w.xpd_sar_force().bits(0b11)
302        });
303
304        Adc {
305            _adc: adc_instance,
306            attenuations: config.attenuations,
307            active_channel: None,
308            _guard: guard,
309            _phantom: PhantomData,
310        }
311    }
312
313    /// Reconfigures the ADC driver to operate in asynchronous mode.
314    pub fn into_async(mut self) -> Adc<'d, ADCI, Async> {
315        acquire_async_adc();
316        self.set_interrupt_handler(adc_interrupt_handler);
317
318        // Reset interrupt flags and disable oneshot reading to normalize state before
319        // entering async mode, otherwise there can be '0' readings, happening initially
320        // using ADC2
321        ADCI::reset();
322
323        Adc {
324            _adc: self._adc,
325            attenuations: self.attenuations,
326            active_channel: self.active_channel,
327            _guard: self._guard,
328            _phantom: PhantomData,
329        }
330    }
331
332    /// Request that the ADC begin a conversion on the specified pin
333    ///
334    /// This method takes an [AdcPin](super::AdcPin) reference, as it is
335    /// expected that the ADC will be able to sample whatever channel
336    /// underlies the pin.
337    pub fn read_oneshot<PIN, CS>(
338        &mut self,
339        pin: &mut super::AdcPin<PIN, ADCI, CS>,
340    ) -> nb::Result<u16, ()>
341    where
342        PIN: super::AdcChannel,
343        CS: super::AdcCalScheme<ADCI>,
344    {
345        if self.attenuations[PIN::CHANNEL as usize].is_none() {
346            panic!("Channel {} is not configured reading!", PIN::CHANNEL);
347        }
348
349        if let Some(active_channel) = self.active_channel {
350            // There is conversion in progress:
351            // - if it's for a different channel try again later
352            // - if it's for the given channel, go ahead and check progress
353            if active_channel != PIN::CHANNEL {
354                return Err(nb::Error::WouldBlock);
355            }
356        } else {
357            // If no conversions are in progress, start a new one for given channel
358            self.active_channel = Some(PIN::CHANNEL);
359
360            // Set ADC unit calibration according used scheme for pin
361            ADCI::set_init_code(pin.cal_scheme.adc_cal());
362
363            let channel = self.active_channel.unwrap();
364            let attenuation = self.attenuations[channel as usize].unwrap() as u8;
365            ADCI::config_onetime_sample(channel, attenuation);
366            ADCI::start_onetime_sample();
367
368            // see https://github.com/espressif/esp-idf/blob/b4268c874a4cf8fcf7c0c4153cffb76ad2ddda4e/components/hal/adc_oneshot_hal.c#L105-L107
369            // the delay might be a bit generous but longer delay seem to not cause problems
370            #[cfg(esp32c6)]
371            {
372                crate::rom::ets_delay_us(40);
373                ADCI::start_onetime_sample();
374            }
375        }
376
377        // Wait for ADC to finish conversion
378        let conversion_finished = ADCI::is_done();
379        if !conversion_finished {
380            return Err(nb::Error::WouldBlock);
381        }
382
383        // Get converted value
384        let converted_value = ADCI::read_data();
385        ADCI::reset();
386
387        // Postprocess converted value according to calibration scheme used for pin
388        let converted_value = pin.cal_scheme.adc_val(converted_value);
389
390        // There is a hardware limitation. If the APB clock frequency is high, the step
391        // of this reg signal: ``onetime_start`` may not be captured by the
392        // ADC digital controller (when its clock frequency is too slow). A rough
393        // estimate for this step should be at least 3 ADC digital controller
394        // clock cycle.
395        //
396        // This limitation will be removed in hardware future versions.
397        // We reset ``onetime_start`` in `reset` and assume enough time has passed until
398        // the next sample is requested.
399
400        // Mark that no conversions are currently in progress
401        self.active_channel = None;
402
403        Ok(converted_value)
404    }
405}
406
407impl<ADCI> crate::private::Sealed for Adc<'_, ADCI, Blocking> {}
408
409impl<ADCI> InterruptConfigurable for Adc<'_, ADCI, Blocking> {
410    fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
411        for core in crate::system::Cpu::other() {
412            crate::interrupt::disable(core, InterruptSource);
413        }
414        unsafe { crate::interrupt::bind_interrupt(InterruptSource, handler.handler()) };
415        unwrap!(crate::interrupt::enable(
416            InterruptSource,
417            handler.priority()
418        ));
419    }
420}
421
422#[cfg(adc_adc1)]
423impl super::AdcCalEfuse for crate::peripherals::ADC1<'_> {
424    fn init_code(atten: Attenuation) -> Option<u16> {
425        Efuse::rtc_calib_init_code(1, atten)
426    }
427
428    fn cal_mv(atten: Attenuation) -> u16 {
429        Efuse::rtc_calib_cal_mv(1, atten)
430    }
431
432    fn cal_code(atten: Attenuation) -> Option<u16> {
433        Efuse::rtc_calib_cal_code(1, atten)
434    }
435}
436
437#[cfg(adc_adc2)]
438impl super::AdcCalEfuse for crate::peripherals::ADC2<'_> {
439    fn init_code(atten: Attenuation) -> Option<u16> {
440        Efuse::rtc_calib_init_code(2, atten)
441    }
442
443    fn cal_mv(atten: Attenuation) -> u16 {
444        Efuse::rtc_calib_cal_mv(2, atten)
445    }
446
447    fn cal_code(atten: Attenuation) -> Option<u16> {
448        Efuse::rtc_calib_cal_code(2, atten)
449    }
450}
451
452#[cfg(esp32c2)]
453mod adc_implementation {
454    crate::analog::adc::impl_adc_interface! {
455        ADC1 [
456            (GPIO0<'_>, 0),
457            (GPIO1<'_>, 1),
458            (GPIO2<'_>, 2),
459            (GPIO3<'_>, 3),
460            (GPIO4<'_>, 4),
461        ]
462    }
463}
464
465#[cfg(esp32c3)]
466mod adc_implementation {
467    crate::analog::adc::impl_adc_interface! {
468        ADC1 [
469            (GPIO0<'_>, 0),
470            (GPIO1<'_>, 1),
471            (GPIO2<'_>, 2),
472            (GPIO3<'_>, 3),
473            (GPIO4<'_>, 4),
474        ]
475    }
476
477    crate::analog::adc::impl_adc_interface! {
478        ADC2 [
479            (GPIO5<'_>, 0),
480        ]
481    }
482}
483
484#[cfg(esp32c6)]
485mod adc_implementation {
486    crate::analog::adc::impl_adc_interface! {
487        ADC1 [
488            (GPIO0<'_>, 0),
489            (GPIO1<'_>, 1),
490            (GPIO2<'_>, 2),
491            (GPIO3<'_>, 3),
492            (GPIO4<'_>, 4),
493            (GPIO5<'_>, 5),
494            (GPIO6<'_>, 6),
495        ]
496    }
497}
498
499#[cfg(esp32h2)]
500mod adc_implementation {
501    crate::analog::adc::impl_adc_interface! {
502        ADC1 [
503            (GPIO1<'_>, 0),
504            (GPIO2<'_>, 1),
505            (GPIO3<'_>, 2),
506            (GPIO4<'_>, 3),
507            (GPIO5<'_>, 4),
508        ]
509    }
510}
511
512impl<'d, ADCI> Adc<'d, ADCI, Async>
513where
514    ADCI: RegisterAccess + 'd,
515{
516    /// Create a new instance in [crate::Blocking] mode.
517    pub fn into_blocking(self) -> Adc<'d, ADCI, Blocking> {
518        if release_async_adc() {
519            // Disable ADC interrupt on all cores if the last async ADC instance is disabled
520            for cpu in crate::system::Cpu::all() {
521                crate::interrupt::disable(cpu, InterruptSource);
522            }
523        }
524        Adc {
525            _adc: self._adc,
526            attenuations: self.attenuations,
527            active_channel: self.active_channel,
528            _guard: self._guard,
529            _phantom: PhantomData,
530        }
531    }
532
533    /// Request that the ADC begin a conversion on the specified pin
534    ///
535    /// This method takes an [AdcPin](super::AdcPin) reference, as it is
536    /// expected that the ADC will be able to sample whatever channel
537    /// underlies the pin.
538    pub async fn read_oneshot<PIN, CS>(&mut self, pin: &mut super::AdcPin<PIN, ADCI, CS>) -> u16
539    where
540        ADCI: Instance,
541        PIN: super::AdcChannel,
542        CS: super::AdcCalScheme<ADCI>,
543    {
544        let channel = PIN::CHANNEL;
545        if self.attenuations[channel as usize].is_none() {
546            panic!("Channel {} is not configured reading!", channel);
547        }
548
549        // Set ADC unit calibration according used scheme for pin
550        ADCI::set_init_code(pin.cal_scheme.adc_cal());
551
552        let attenuation = self.attenuations[channel as usize].unwrap() as u8;
553        ADCI::config_onetime_sample(channel, attenuation);
554        ADCI::start_onetime_sample();
555
556        // Wait for ADC to finish conversion and get value
557        let adc_ready_future = AdcFuture::new(self);
558        adc_ready_future.await;
559        let converted_value = ADCI::read_data();
560
561        // There is a hardware limitation. If the APB clock frequency is high, the step
562        // of this reg signal: ``onetime_start`` may not be captured by the
563        // ADC digital controller (when its clock frequency is too slow). A rough
564        // estimate for this step should be at least 3 ADC digital controller
565        // clock cycle.
566        //
567        // This limitation will be removed in hardware future versions.
568        // We reset ``onetime_start`` in `reset` and assume enough time has passed until
569        // the next sample is requested.
570
571        ADCI::reset();
572
573        // Postprocess converted value according to calibration scheme used for pin
574        pin.cal_scheme.adc_val(converted_value)
575    }
576}
577
578#[cfg(all(adc_adc1, adc_adc2))]
579static ASYNC_ADC_COUNT: AtomicU32 = AtomicU32::new(0);
580
581pub(super) fn acquire_async_adc() {
582    #[cfg(all(adc_adc1, adc_adc2))]
583    ASYNC_ADC_COUNT.fetch_add(1, Ordering::Relaxed);
584}
585
586pub(super) fn release_async_adc() -> bool {
587    cfg_if::cfg_if! {
588        if #[cfg(all(adc_adc1, adc_adc2))] {
589            ASYNC_ADC_COUNT.fetch_sub(1, Ordering::Relaxed) == 1
590        } else {
591            true
592        }
593    }
594}
595
596#[handler]
597pub(crate) fn adc_interrupt_handler() {
598    let saradc = APB_SARADC::regs();
599    let interrupt_status = saradc.int_st().read();
600
601    #[cfg(adc_adc1)]
602    if interrupt_status.adc1_done().bit_is_set() {
603        unsafe { handle_async(crate::peripherals::ADC1::steal()) }
604    }
605
606    #[cfg(adc_adc2)]
607    if interrupt_status.adc2_done().bit_is_set() {
608        unsafe { handle_async(crate::peripherals::ADC2::steal()) }
609    }
610}
611
612fn handle_async<ADCI: Instance>(_instance: ADCI) {
613    ADCI::waker().wake();
614    ADCI::disable_interrupt();
615}
616
617/// Enable asynchronous access.
618pub trait Instance: crate::private::Sealed {
619    /// Enable the ADC interrupt
620    fn enable_interrupt();
621
622    /// Disable the ADC interrupt
623    fn disable_interrupt();
624
625    /// Clear the ADC interrupt
626    fn clear_interrupt();
627
628    /// Obtain the waker for the ADC interrupt
629    fn waker() -> &'static AtomicWaker;
630}
631
632#[cfg(adc_adc1)]
633impl Instance for crate::peripherals::ADC1<'_> {
634    fn enable_interrupt() {
635        APB_SARADC::regs()
636            .int_ena()
637            .modify(|_, w| w.adc1_done().set_bit());
638    }
639
640    fn disable_interrupt() {
641        APB_SARADC::regs()
642            .int_ena()
643            .modify(|_, w| w.adc1_done().clear_bit());
644    }
645
646    fn clear_interrupt() {
647        APB_SARADC::regs()
648            .int_clr()
649            .write(|w| w.adc1_done().clear_bit_by_one());
650    }
651
652    fn waker() -> &'static AtomicWaker {
653        static WAKER: AtomicWaker = AtomicWaker::new();
654
655        &WAKER
656    }
657}
658
659#[cfg(adc_adc2)]
660impl Instance for crate::peripherals::ADC2<'_> {
661    fn enable_interrupt() {
662        APB_SARADC::regs()
663            .int_ena()
664            .modify(|_, w| w.adc2_done().set_bit());
665    }
666
667    fn disable_interrupt() {
668        APB_SARADC::regs()
669            .int_ena()
670            .modify(|_, w| w.adc2_done().clear_bit());
671    }
672
673    fn clear_interrupt() {
674        APB_SARADC::regs()
675            .int_clr()
676            .write(|w| w.adc2_done().clear_bit_by_one());
677    }
678
679    fn waker() -> &'static AtomicWaker {
680        static WAKER: AtomicWaker = AtomicWaker::new();
681
682        &WAKER
683    }
684}
685
686#[must_use = "futures do nothing unless you `.await` or poll them"]
687pub(crate) struct AdcFuture<ADCI: Instance> {
688    phantom: PhantomData<ADCI>,
689}
690
691impl<ADCI: Instance> AdcFuture<ADCI> {
692    pub fn new(_self: &super::Adc<'_, ADCI, Async>) -> Self {
693        Self {
694            phantom: PhantomData,
695        }
696    }
697}
698
699impl<ADCI: Instance + super::RegisterAccess> core::future::Future for AdcFuture<ADCI> {
700    type Output = ();
701
702    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
703        if ADCI::is_done() {
704            ADCI::clear_interrupt();
705            Poll::Ready(())
706        } else {
707            ADCI::waker().register(cx.waker());
708            ADCI::enable_interrupt();
709            Poll::Pending
710        }
711    }
712}
713
714impl<ADCI: Instance> Drop for AdcFuture<ADCI> {
715    fn drop(&mut self) {
716        ADCI::disable_interrupt();
717    }
718}