stm32f7x7_hal/
adc.rs

1//! Analog to digital converter configuration.
2//! According to CubeMx, all STM32F4 chips use the same ADC IP so this should be correct for all variants.
3
4#![deny(missing_docs)]
5
6/*
7    Currently unused but this is the formula for using temperature calibration:
8    Temperature in °C = (110-30)/(VtempCal110::get().read()-VtempCal30::get().read()) * (adc_sample - VtempCal30::get().read()) + 30
9*/
10
11use crate::{gpio::*, signature::VrefCal, signature::VDDA_CALIB, stm32};
12use core::fmt;
13use embedded_hal::adc::{Channel, OneShot};
14
15/// Vref internal signal, used for calibration
16pub struct Vref;
17
18/// Vbat internal signal, used for monitoring the battery (if used)
19pub struct Vbat;
20
21/// Core temperature internal signal
22pub struct Temperature;
23
24macro_rules! adc_pins {
25    ($($pin:ty => ($adc:ident, $chan:expr)),+ $(,)*) => {
26        $(
27            impl Channel<stm32::$adc> for $pin {
28                type ID = u8;
29                fn channel() -> u8 { $chan }
30            }
31        )+
32    };
33}
34
35/// Contains types related to ADC configuration
36pub mod config {
37    /// The place in the sequence a given channel should be captured
38    #[derive(Debug, PartialEq, PartialOrd, Copy, Clone)]
39    pub enum Sequence {
40        /// 1
41        One,
42        /// 2
43        Two,
44        /// 3
45        Three,
46        /// 4
47        Four,
48        /// 5
49        Five,
50        /// 6
51        Six,
52        /// 7
53        Seven,
54        /// 8
55        Eight,
56        /// 9
57        Nine,
58        /// 10
59        Ten,
60        /// 11
61        Eleven,
62        /// 12
63        Twelve,
64        /// 13
65        Thirteen,
66        /// 14
67        Fourteen,
68        /// 15
69        Fifteen,
70        /// 16
71        Sixteen,
72    }
73
74    impl From<Sequence> for u8 {
75        fn from(s: Sequence) -> u8 {
76            match s {
77                Sequence::One => 0,
78                Sequence::Two => 1,
79                Sequence::Three => 2,
80                Sequence::Four => 3,
81                Sequence::Five => 4,
82                Sequence::Six => 5,
83                Sequence::Seven => 6,
84                Sequence::Eight => 7,
85                Sequence::Nine => 8,
86                Sequence::Ten => 9,
87                Sequence::Eleven => 10,
88                Sequence::Twelve => 11,
89                Sequence::Thirteen => 12,
90                Sequence::Fourteen => 13,
91                Sequence::Fifteen => 14,
92                Sequence::Sixteen => 15,
93            }
94        }
95    }
96
97    impl From<u8> for Sequence {
98        fn from(bits: u8) -> Self {
99            match bits {
100                0 => Sequence::One,
101                1 => Sequence::Two,
102                2 => Sequence::Three,
103                3 => Sequence::Four,
104                4 => Sequence::Five,
105                5 => Sequence::Six,
106                6 => Sequence::Seven,
107                7 => Sequence::Eight,
108                8 => Sequence::Nine,
109                9 => Sequence::Ten,
110                10 => Sequence::Eleven,
111                11 => Sequence::Twelve,
112                12 => Sequence::Thirteen,
113                13 => Sequence::Fourteen,
114                14 => Sequence::Fifteen,
115                15 => Sequence::Sixteen,
116                _ => unimplemented!(),
117            }
118        }
119    }
120
121    /// The number of cycles to sample a given channel for
122    #[derive(Debug, PartialEq, Copy, Clone)]
123    pub enum SampleTime {
124        /// 3 cycles
125        Cycles_3,
126        /// 15 cycles
127        Cycles_15,
128        /// 28 cycles
129        Cycles_28,
130        /// 56 cycles
131        Cycles_56,
132        /// 84 cycles
133        Cycles_84,
134        /// 112 cycles
135        Cycles_112,
136        /// 144 cycles
137        Cycles_144,
138        /// 480 cycles
139        Cycles_480,
140    }
141
142    impl From<u8> for SampleTime {
143        fn from(f: u8) -> SampleTime {
144            match f {
145                0 => SampleTime::Cycles_3,
146                1 => SampleTime::Cycles_15,
147                2 => SampleTime::Cycles_28,
148                3 => SampleTime::Cycles_56,
149                4 => SampleTime::Cycles_84,
150                5 => SampleTime::Cycles_112,
151                6 => SampleTime::Cycles_144,
152                7 => SampleTime::Cycles_480,
153                _ => unimplemented!(),
154            }
155        }
156    }
157
158    impl From<SampleTime> for u8 {
159        fn from(l: SampleTime) -> u8 {
160            match l {
161                SampleTime::Cycles_3 => 0,
162                SampleTime::Cycles_15 => 1,
163                SampleTime::Cycles_28 => 2,
164                SampleTime::Cycles_56 => 3,
165                SampleTime::Cycles_84 => 4,
166                SampleTime::Cycles_112 => 5,
167                SampleTime::Cycles_144 => 6,
168                SampleTime::Cycles_480 => 7,
169            }
170        }
171    }
172
173    /// Clock config for the ADC
174    /// Check the datasheet for the maximum speed the ADC supports
175    #[derive(Debug, Clone, Copy)]
176    pub enum Clock {
177        /// PCLK2 (APB2) divided by 2
178        Pclk2_div_2,
179        /// PCLK2 (APB2) divided by 4
180        Pclk2_div_4,
181        /// PCLK2 (APB2) divided by 6
182        Pclk2_div_6,
183        /// PCLK2 (APB2) divided by 8
184        Pclk2_div_8,
185    }
186
187    impl From<Clock> for u8 {
188        fn from(c: Clock) -> u8 {
189            match c {
190                Clock::Pclk2_div_2 => 0,
191                Clock::Pclk2_div_4 => 1,
192                Clock::Pclk2_div_6 => 2,
193                Clock::Pclk2_div_8 => 3,
194            }
195        }
196    }
197
198    /// Resolution to sample at
199    #[derive(Debug, Clone, Copy)]
200    pub enum Resolution {
201        /// 12-bit
202        Twelve,
203        /// 10-bit
204        Ten,
205        /// 8-bit
206        Eight,
207        /// 6-bit
208        Six,
209    }
210    impl From<Resolution> for u8 {
211        fn from(r: Resolution) -> u8 {
212            match r {
213                Resolution::Twelve => 0,
214                Resolution::Ten => 1,
215                Resolution::Eight => 2,
216                Resolution::Six => 3,
217            }
218        }
219    }
220
221    /// Possible external triggers the ADC can listen to
222    #[derive(Debug, Clone, Copy)]
223    pub enum ExternalTrigger {
224        /// TIM1 compare channel 1
225        Tim_1_cc_1,
226        /// TIM1 compare channel 2
227        Tim_1_cc_2,
228        /// TIM1 compare channel 3
229        Tim_1_cc_3,
230        /// TIM2 compare channel 2
231        Tim_2_cc_2,
232        /// TIM2 compare channel 3
233        Tim_2_cc_3,
234        /// TIM2 compare channel 4
235        Tim_2_cc_4,
236        /// TIM2 trigger out
237        Tim_2_trgo,
238        /// TIM3 compare channel 1
239        Tim_3_cc_1,
240        /// TIM3 trigger out
241        Tim_3_trgo,
242        /// TIM4 compare channel 4
243        Tim_4_cc_4,
244        /// TIM5 compare channel 1
245        Tim_5_cc_1,
246        /// TIM5 compare channel 2
247        Tim_5_cc_2,
248        /// TIM5 compare channel 3
249        Tim_5_cc_3,
250        /// External interupt line 11
251        Exti_11,
252    }
253    impl From<ExternalTrigger> for u8 {
254        fn from(et: ExternalTrigger) -> u8 {
255            match et {
256                ExternalTrigger::Tim_1_cc_1 => 0b0000,
257                ExternalTrigger::Tim_1_cc_2 => 0b0001,
258                ExternalTrigger::Tim_1_cc_3 => 0b0010,
259                ExternalTrigger::Tim_2_cc_2 => 0b0011,
260                ExternalTrigger::Tim_2_cc_3 => 0b0100,
261                ExternalTrigger::Tim_2_cc_4 => 0b0101,
262                ExternalTrigger::Tim_2_trgo => 0b0110,
263                ExternalTrigger::Tim_3_cc_1 => 0b0111,
264                ExternalTrigger::Tim_3_trgo => 0b1000,
265                ExternalTrigger::Tim_4_cc_4 => 0b1001,
266                ExternalTrigger::Tim_5_cc_1 => 0b1010,
267                ExternalTrigger::Tim_5_cc_2 => 0b1011,
268                ExternalTrigger::Tim_5_cc_3 => 0b1100,
269                ExternalTrigger::Exti_11 => 0b1111,
270            }
271        }
272    }
273
274    /// Possible trigger modes
275    #[derive(Debug, Clone, Copy)]
276    pub enum TriggerMode {
277        /// Don't listen to external trigger
278        Disabled,
279        /// Listen for rising edges of external trigger
280        RisingEdge,
281        /// Listen for falling edges of external trigger
282        FallingEdge,
283        /// Listen for both rising and falling edges of external trigger
284        BothEdges,
285    }
286    impl From<TriggerMode> for u8 {
287        fn from(tm: TriggerMode) -> u8 {
288            match tm {
289                TriggerMode::Disabled => 0,
290                TriggerMode::RisingEdge => 1,
291                TriggerMode::FallingEdge => 2,
292                TriggerMode::BothEdges => 3,
293            }
294        }
295    }
296
297    /// Data register alignment
298    #[derive(Debug, Clone, Copy)]
299    pub enum Align {
300        /// Right align output data
301        Right,
302        /// Left align output data
303        Left,
304    }
305    impl From<Align> for bool {
306        fn from(a: Align) -> bool {
307            match a {
308                Align::Right => false,
309                Align::Left => true,
310            }
311        }
312    }
313
314    /// Scan enable/disable
315    #[derive(Debug, Clone, Copy)]
316    pub enum Scan {
317        /// Scan mode disabled
318        Disabled,
319        /// Scan mode enabled
320        Enabled,
321    }
322    impl From<Scan> for bool {
323        fn from(s: Scan) -> bool {
324            match s {
325                Scan::Disabled => false,
326                Scan::Enabled => true,
327            }
328        }
329    }
330
331    /// Continuous mode enable/disable
332    #[derive(Debug, Clone, Copy)]
333    pub enum Continuous {
334        /// Single mode, continuous disabled
335        Single,
336        /// Continuous mode enabled
337        Continuous,
338    }
339    impl From<Continuous> for bool {
340        fn from(c: Continuous) -> bool {
341            match c {
342                Continuous::Single => false,
343                Continuous::Continuous => true,
344            }
345        }
346    }
347
348    /// DMA mode
349    #[derive(Debug, Clone, Copy)]
350    pub enum Dma {
351        /// No DMA, disabled
352        Disabled,
353        /// Single DMA, DMA will be disabled after each conversion sequence
354        Single,
355        /// Continuous DMA, DMA will remain enabled after conversion
356        Continuous,
357    }
358
359    /// End-of-conversion interrupt enabled/disabled
360    #[derive(Debug, Clone, Copy)]
361    pub enum Eoc {
362        /// End-of-conversion interrupt disabled
363        Disabled,
364        /// End-of-conversion interrupt enabled per conversion
365        Conversion,
366        /// End-of-conversion interrupt enabled per sequence
367        Sequence,
368    }
369
370    /// Configuration for the adc.
371    /// There are some additional parameters on the adc peripheral that can be
372    /// added here when needed but this covers several basic usecases.
373    #[derive(Debug, Clone, Copy)]
374    pub struct AdcConfig {
375        pub(crate) clock: Clock,
376        pub(crate) resolution: Resolution,
377        pub(crate) align: Align,
378        pub(crate) scan: Scan,
379        pub(crate) external_trigger: (TriggerMode, ExternalTrigger),
380        pub(crate) continuous: Continuous,
381        pub(crate) dma: Dma,
382        pub(crate) end_of_conversion_interrupt: Eoc,
383        pub(crate) default_sample_time: SampleTime,
384    }
385
386    impl AdcConfig {
387        /// change the clock field
388        pub fn clock(mut self, clock: Clock) -> Self {
389            self.clock = clock;
390            self
391        }
392        /// change the resolution field
393        pub fn resolution(mut self, resolution: Resolution) -> Self {
394            self.resolution = resolution;
395            self
396        }
397        /// change the align field
398        pub fn align(mut self, align: Align) -> Self {
399            self.align = align;
400            self
401        }
402        /// change the scan field
403        pub fn scan(mut self, scan: Scan) -> Self {
404            self.scan = scan;
405            self
406        }
407        /// change the external_trigger field
408        pub fn external_trigger(
409            mut self,
410            trigger_mode: TriggerMode,
411            trigger: ExternalTrigger,
412        ) -> Self {
413            self.external_trigger = (trigger_mode, trigger);
414            self
415        }
416        /// change the continuous field
417        pub fn continuous(mut self, continuous: Continuous) -> Self {
418            self.continuous = continuous;
419            self
420        }
421        /// change the dma field
422        pub fn dma(mut self, dma: Dma) -> Self {
423            self.dma = dma;
424            self
425        }
426        /// change the end_of_conversion_interrupt field
427        pub fn end_of_conversion_interrupt(mut self, end_of_conversion_interrupt: Eoc) -> Self {
428            self.end_of_conversion_interrupt = end_of_conversion_interrupt;
429            self
430        }
431        /// change the default_sample_time field
432        pub fn default_sample_time(mut self, default_sample_time: SampleTime) -> Self {
433            self.default_sample_time = default_sample_time;
434            self
435        }
436    }
437
438    impl Default for AdcConfig {
439        fn default() -> Self {
440            Self {
441                clock: Clock::Pclk2_div_2,
442                resolution: Resolution::Twelve,
443                align: Align::Right,
444                scan: Scan::Disabled,
445                external_trigger: (TriggerMode::Disabled, ExternalTrigger::Tim_1_cc_1),
446                continuous: Continuous::Single,
447                dma: Dma::Disabled,
448                end_of_conversion_interrupt: Eoc::Disabled,
449                default_sample_time: SampleTime::Cycles_480,
450            }
451        }
452    }
453}
454
455/// Analog to Digital Converter
456/// # Status
457/// Most options relating to regular conversions are implemented. One-shot and sequences of conversions
458/// have been tested and work as expected.
459///
460/// GPIO to channel mapping should be correct for all supported F4 devices. The mappings were taken from
461/// CubeMX. The mappings are feature gated per 4xx device but there are actually sub variants for some
462/// devices and some pins may be missing on some variants. The implementation has been split up and commented
463/// to show which pins are available on certain device variants but currently the library doesn't enforce this.
464/// To fully support the right pins would require 10+ more features for the various variants.
465/// ## Todo
466/// * Injected conversions
467/// * Analog watchdog config
468/// * Discontinuous mode
469/// # Examples
470/// ## One-shot conversion
471/// ```
472/// use stm32f7x7_hal::{
473///   gpio::gpioa,
474///   adc::{
475///     Adc,
476///     config::AdcConfig,
477///     config::SampleTime,
478///   },
479/// };
480///
481/// fn main() {
482///     let mut adc = Adc::adc1(device.ADC1, true, AdcConfig::default());
483///     let pa3 = gpioa.pa3.into_analog();
484///     let sample = adc.convert(&pa3, SampleTime::Cycles_480);
485///     let millivolts = adc.sample_to_millivolts(sample);
486///     info!("pa3: {}mV", millivolts);
487/// }
488/// ```
489///
490/// ## Sequence conversion
491/// ```
492/// use stm32f7x7_hal::{
493///   gpio::gpioa,
494///   adc::{
495///     Adc,
496///     config::AdcConfig,
497///     config::SampleTime,
498///     config::Sequence,
499///     config::Eoc,
500///     config::Scan,
501///     config::Clock,
502///   },
503/// };
504///
505/// fn main() {
506///     let config = AdcConfig::default()
507///         //We'll either need DMA or an interrupt per conversion to convert
508///         //multiple values in a sequence
509///         .end_of_conversion_interrupt(Eoc::Conversion);
510///         //Scan mode is also required to convert a sequence
511///         .scan(Scan::Enabled)
512///         //And since we're looking for one interrupt per conversion the
513///         //clock will need to be fairly slow to avoid overruns breaking
514///         //the sequence. If you are running in debug mode and logging in
515///         //the interrupt, good luck... try setting pclk2 really low.
516///         //(Better yet use DMA)
517///         .clock(Clock::Pclk2_div_8);
518///     let mut adc = Adc::adc1(device.ADC1, true, config);
519///     let pa0 = gpioa.pa0.into_analog();
520///     let pa3 = gpioa.pa3.into_analog();
521///     adc.configure_channel(&pa0, Sequence::One, SampleTime::Cycles_112);
522///     adc.configure_channel(&pa3, Sequence::Two, SampleTime::Cycles_480);
523///     adc.configure_channel(&pa0, Sequence::Three, SampleTime::Cycles_112);
524///     adc.start_conversion();
525/// }
526/// ```
527///
528/// ## External trigger
529///
530/// A common mistake on STM forums is enabling continuous mode but that causes it to start
531/// capturing on the first trigger and capture as fast as possible forever, regardless of
532/// future triggers. Continuous mode is disabled by default but I thought it was worth
533/// highlighting.
534///
535/// Getting the timer config right to make sure it's sending the event the ADC is listening
536/// to can be a bit of a pain but the key fields are highlighted below. Try hooking a timer
537/// channel up to an external pin with an LED or oscilloscope attached to check it's really
538/// generating pulses if the ADC doesn't seem to be triggering.
539/// ```
540/// use stm32f7x7_hal::{
541///   gpio::gpioa,
542///   adc::{
543///     Adc,
544///     config::AdcConfig,
545///     config::SampleTime,
546///     config::Sequence,
547///     config::Eoc,
548///     config::Scan,
549///     config::Clock,
550///   },
551/// };
552///
553/// fn main() {
554///     let config = AdcConfig::default()
555///         //Set the trigger you want
556///         .external_trigger(TriggerMode::RisingEdge, ExternalTrigger::Tim_1_cc_1);
557///     let mut adc = Adc::adc1(device.ADC1, true, config);
558///     let pa0 = gpioa.pa0.into_analog();
559///     adc.configure_channel(&pa0, Sequence::One, SampleTime::Cycles_112);
560///     //Make sure it's enabled but don't start the conversion
561///     adc.enable();
562///
563///    //Configure the timer
564///    let mut tim = Timer::tim1(device.TIM1, 1.hz(), clocks);
565///    unsafe {
566///        let tim = &(*TIM1::ptr());
567///
568///        //This is pwm mode 1, the default mode is "frozen" which won't work
569///        let mode = 0b0110;
570///
571///        //Channel 1
572///        //Disable the channel before configuring it
573///        tim.ccer.modify(|_, w| w.cc1e().clear_bit());
574///
575///        tim.ccmr1_output.modify(|_, w| w
576///          //Preload enable for channel
577///          .oc1pe().set_bit()
578///
579///          //Set mode for channel
580///          .oc1m().bits(mode)
581///        );
582///
583///        //Set the duty cycle, 0 won't work in pwm mode but might be ok in
584///        //toggle mode or match mode
585///        let max_duty = tim.arr.read().arr().bits() as u16;
586///        tim.ccr1.modify(|_, w| w.ccr1().bits(max_duty / 2));
587///
588///        //Enable the channel
589///        tim.ccer.modify(|_, w| w.cc1e().set_bit());
590///
591///        //Enable the TIM main Output
592///        tim.bdtr.modify(|_, w| w.moe().set_bit());
593///    }
594/// ```
595#[derive(Clone, Copy)]
596pub struct Adc<ADC> {
597    /// Current config of the ADC, kept up to date by the various set methods
598    config: config::AdcConfig,
599    /// The adc peripheral
600    adc_reg: ADC,
601    /// VDDA in millivolts calculated from the factory calibration and vrefint
602    calibrated_vdda: u32,
603    /// Maximum sample value possible for the configured resolution
604    max_sample: u32,
605}
606impl<ADC> fmt::Debug for Adc<ADC> {
607    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
608        write!(
609            f,
610            "Adc: {{ calibrated_vdda: {:?}, max_sample: {:?}, config: {:?}, ... }}",
611            self.calibrated_vdda, self.max_sample, self.config
612        )
613    }
614}
615
616macro_rules! adc {
617    ($($adc_type:ident => ($constructor_fn_name:ident, $common_type:ident, $rcc_enr_reg:ident, $rcc_enr_field: ident, $rcc_rst_reg: ident, $rcc_rst_field: ident)),+ $(,)*) => {
618        $(
619            impl Adc<stm32::$adc_type> {
620                /// Enables the ADC clock, resets the peripheral (optionally), runs calibration and applies the supplied config
621                /// # Arguments
622                /// * `reset` - should a reset be performed. This is provided because on some devices multiple ADCs share the same common reset
623                pub fn $constructor_fn_name(adc: stm32::$adc_type, reset: bool, config: config::AdcConfig) -> Adc<stm32::$adc_type> {
624                    unsafe {
625                        let rcc = &(*stm32::RCC::ptr());
626                        //Enable the common clock
627                        rcc.$rcc_enr_reg.modify(|_, w| w.$rcc_enr_field().set_bit());
628                        if reset {
629                            //Reset the peripheral(s)
630                            rcc.$rcc_rst_reg.modify(|_, w| w.$rcc_rst_field().set_bit());
631                            rcc.$rcc_rst_reg.modify(|_, w| w.$rcc_rst_field().clear_bit());
632                        }
633                    }
634
635                    let mut s = Self {
636                        config,
637                        adc_reg: adc,
638                        calibrated_vdda: VDDA_CALIB,
639                        max_sample: 0,
640                    };
641
642                    //Probably unnecessary to disable the ADC in most cases but it shouldn't do any harm either
643                    s.disable();
644                    s.apply_config(config);
645
646                    s.enable();
647                    s.calibrate();
648
649                    s
650                }
651
652                /// Applies all fields in AdcConfig
653                pub fn apply_config(&mut self, config: config::AdcConfig) {
654                    self.set_clock(config.clock);
655                    self.set_resolution(config.resolution);
656                    self.set_align(config.align);
657                    self.set_scan(config.scan);
658                    self.set_external_trigger(config.external_trigger);
659                    self.set_continuous(config.continuous);
660                    self.set_dma(config.dma);
661                    self.set_end_of_conversion_interrupt(config.end_of_conversion_interrupt);
662                    self.set_default_sample_time(config.default_sample_time);
663                }
664
665                /// Calculates the system VDDA by sampling the internal VREF channel and comparing
666                /// the result with the value stored at the factory.
667                pub fn calibrate(&mut self) {
668                    self.enable();
669
670                    let vref_en = self.temperature_and_vref_enabled();
671                    if !vref_en {
672                        self.enable_temperature_and_vref();
673                    }
674
675                    let vref_cal = VrefCal::get().read();
676                    let vref_samp = self.read(&mut Vref).unwrap(); //This can't actually fail, it's just in a result to satisfy hal trait
677
678                    self.calibrated_vdda = (VDDA_CALIB * u32::from(vref_cal)) / u32::from(vref_samp);
679                    if !vref_en {
680                        self.disable_temperature_and_vref();
681                    }
682                }
683
684                /// Enables the vbat internal channel
685                pub fn enable_vbat(&self) {
686                    unsafe {
687                        let common = &(*stm32::$common_type::ptr());
688                        common.ccr.modify(|_, w| w.vbate().set_bit());
689                    }
690                }
691
692                /// Enables the vbat internal channel
693                pub fn disable_vbat(&self) {
694                    unsafe {
695                        let common = &(*stm32::$common_type::ptr());
696                        common.ccr.modify(|_, w| w.vbate().clear_bit());
697                    }
698                }
699
700                /// Enables the temp and vref internal channels.
701                /// They can't work while vbat is also enabled so this method also disables vbat.
702                pub fn enable_temperature_and_vref(&mut self) {
703                    //VBAT prevents TS and VREF from being sampled
704                    self.disable_vbat();
705                    unsafe {
706                        let common = &(*stm32::$common_type::ptr());
707                        common.ccr.modify(|_, w| w.tsvrefe().set_bit());
708                    }
709                }
710
711                /// Disables the temp and vref internal channels
712                pub fn disable_temperature_and_vref(&mut self) {
713                    unsafe {
714                        let common = &(*stm32::$common_type::ptr());
715                        common.ccr.modify(|_, w| w.tsvrefe().clear_bit());
716                    }
717                }
718
719                /// Returns if the temp and vref internal channels are enabled
720                pub fn temperature_and_vref_enabled(&mut self) -> bool {
721                    unsafe {
722                        let common = &(*stm32::$common_type::ptr());
723                        common.ccr.read().tsvrefe().bit_is_set()
724                    }
725                }
726
727                /// Returns if the adc is enabled
728                pub fn is_enabled(&self) -> bool {
729                    self.adc_reg.cr2.read().adon().bit_is_set()
730                }
731
732                /// Enables the adc
733                pub fn enable(&mut self) {
734                    self.adc_reg.cr2.modify(|_, w| w.adon().set_bit());
735                }
736
737                /// Disables the adc
738                /// # Note
739                /// The ADC in the f4 has few restrictions on what can be configured while the ADC
740                /// is enabled. If any bugs are found where some settings aren't "sticking" try disabling
741                /// the ADC before changing them. The reference manual for the chip I'm using only states
742                /// that the sequence registers are locked when they are being converted.
743                pub fn disable(&mut self) {
744                    self.adc_reg.cr2.modify(|_, w| w.adon().clear_bit());
745                }
746
747                /// Starts conversion sequence. Waits for the hardware to indicate it's actually started.
748                pub fn start_conversion(&mut self) {
749                    self.enable();
750                    self.clear_end_of_conversion_flag();
751                    //Start conversion
752                    self.adc_reg.cr2.modify(|_, w| w.swstart().set_bit());
753
754                    while !self.adc_reg.sr.read().strt().bit_is_set() {}
755                }
756
757                /// Sets the clock for the adc
758                pub fn set_clock(&mut self, clock: config::Clock) {
759                    self.config.clock = clock;
760                    unsafe {
761                        let common = &(*stm32::$common_type::ptr());
762                        common.ccr.modify(|_, w| w.adcpre().bits(clock.into()));
763                    }
764                }
765
766                /// Sets the sampling resolution
767                pub fn set_resolution(&mut self, resolution: config::Resolution) {
768                    self.max_sample = match resolution {
769                        config::Resolution::Twelve => (1 << 12) - 1,
770                        config::Resolution::Ten => (1 << 10) - 1,
771                        config::Resolution::Eight => (1 << 8) - 1,
772                        config::Resolution::Six => (1 << 6) -1,
773                    };
774                    self.config.resolution = resolution;
775                    self.adc_reg.cr1.modify(|_, w| w.res().bits(resolution.into()));
776                }
777
778                /// Sets the DR register alignment to left or right
779                pub fn set_align(&mut self, align: config::Align) {
780                    self.config.align = align;
781                    self.adc_reg.cr2.modify(|_, w| w.align().bit(align.into()));
782                }
783
784                /// Enables and disables scan mode
785                pub fn set_scan(&mut self, scan: config::Scan) {
786                    self.config.scan = scan;
787                    self.adc_reg.cr1.modify(|_, w| w.scan().bit(scan.into()));
788                }
789
790                /// Sets which external trigger to use and if it is disabled, rising, falling or both
791                pub fn set_external_trigger(&mut self, (edge, extsel): (config::TriggerMode, config::ExternalTrigger)) {
792                    self.config.external_trigger = (edge, extsel);
793                    self.adc_reg.cr2.modify(|_, w| unsafe { w
794                        .extsel().bits(extsel.into())
795                        .exten().bits(edge.into())
796                    });
797                }
798
799                /// Enables and disables continuous mode
800                pub fn set_continuous(&mut self, continuous: config::Continuous) {
801                    self.config.continuous = continuous;
802                    self.adc_reg.cr2.modify(|_, w| w.cont().bit(continuous.into()));
803                }
804
805                /// Sets DMA to disabled, single or continuous
806                pub fn set_dma(&mut self, dma: config::Dma) {
807                    self.config.dma = dma;
808                    let (dds, en) = match dma {
809                        config::Dma::Disabled => (false, false),
810                        config::Dma::Single => (false, true),
811                        config::Dma::Continuous => (true, true),
812                    };
813                    self.adc_reg.cr2.modify(|_, w| w
814                        //DDS stands for "DMA disable selection"
815                        //0 means do one DMA then stop
816                        //1 means keep sending DMA requests as long as DMA=1
817                        .dds().bit(dds)
818                        .dma().bit(en)
819                    );
820                }
821
822                /// Sets if the end-of-conversion behaviour.
823                /// The end-of-conversion interrupt occur either per conversion or for the whole sequence.
824                pub fn set_end_of_conversion_interrupt(&mut self, eoc: config::Eoc) {
825                    self.config.end_of_conversion_interrupt = eoc;
826                    let (en, eocs) = match eoc {
827                        config::Eoc::Disabled => (false, false),
828                        config::Eoc::Conversion => (true, true),
829                        config::Eoc::Sequence => (true, false),
830                    };
831                    self.adc_reg.cr1.modify(|_, w| w.eocie().bit(en));
832                    self.adc_reg.cr2.modify(|_, w| w.eocs().bit(eocs));
833                }
834
835                /// Resets the end-of-conversion flag
836                pub fn clear_end_of_conversion_flag(&mut self) {
837                    self.adc_reg.sr.modify(|_, w| w.eoc().clear_bit());
838                }
839
840                /// Sets the default sample time that is used for one-shot conversions.
841                /// [configure_channel](#method.configure_channel) and [start_conversion](#method.start_conversion) can be \
842                /// used for configurations where different sampling times are required per channel.
843                pub fn set_default_sample_time(&mut self, sample_time: config::SampleTime) {
844                    self.config.default_sample_time = sample_time;
845                }
846
847                /// Returns the current sequence length. Primarily useful for configuring DMA.
848                pub fn sequence_length(&mut self) -> u8 {
849                    self.adc_reg.sqr1.read().l().bits() + 1
850                }
851
852                /// Reset the sequence
853                pub fn reset_sequence(&mut self) {
854                    //The reset state is One conversion selected
855                    self.adc_reg.sqr1.modify(|_, w| w.l().bits(config::Sequence::One.into()));
856                }
857
858                /// Returns the address of the ADC data register. Primarily useful for configuring DMA.
859                pub fn data_register_address(&mut self) -> u32 {
860                    &self.adc_reg.dr as *const _ as u32
861                }
862
863                /// Configure a channel for sampling.
864                /// It will make sure the sequence is at least as long as the `sequence` provided.
865                /// # Arguments
866                /// * `channel` - channel to configure
867                /// * `sequence` - where in the sequence to sample the channel. Also called rank in some STM docs/code
868                /// * `sample_time` - how long to sample for. See datasheet and ref manual to work out how long you need\
869                /// to sample for at a given ADC clock frequency
870                pub fn configure_channel<CHANNEL>(&mut self, _channel: &CHANNEL, sequence: config::Sequence, sample_time: config::SampleTime)
871                where
872                    CHANNEL: Channel<stm32::$adc_type, ID=u8>
873                {
874                    //Check the sequence is long enough
875                    self.adc_reg.sqr1.modify(|r, w| {
876                        let prev: config::Sequence = r.l().bits().into();
877                        if prev < sequence {
878                            w.l().bits(sequence.into())
879                        } else {
880                            w
881                        }
882                    });
883
884                    let channel = CHANNEL::channel();
885
886                    //Set the channel in the right sequence field
887                    match sequence {
888                        config::Sequence::One      => self.adc_reg.sqr3.modify(|_, w| unsafe {w.sq1().bits(channel) }),
889                        config::Sequence::Two      => self.adc_reg.sqr3.modify(|_, w| unsafe {w.sq2().bits(channel) }),
890                        config::Sequence::Three    => self.adc_reg.sqr3.modify(|_, w| unsafe {w.sq3().bits(channel) }),
891                        config::Sequence::Four     => self.adc_reg.sqr3.modify(|_, w| unsafe {w.sq4().bits(channel) }),
892                        config::Sequence::Five     => self.adc_reg.sqr3.modify(|_, w| unsafe {w.sq5().bits(channel) }),
893                        config::Sequence::Six      => self.adc_reg.sqr3.modify(|_, w| unsafe {w.sq6().bits(channel) }),
894                        config::Sequence::Seven    => self.adc_reg.sqr2.modify(|_, w| unsafe {w.sq7().bits(channel) }),
895                        config::Sequence::Eight    => self.adc_reg.sqr2.modify(|_, w| unsafe {w.sq8().bits(channel) }),
896                        config::Sequence::Nine     => self.adc_reg.sqr2.modify(|_, w| unsafe {w.sq9().bits(channel) }),
897                        config::Sequence::Ten      => self.adc_reg.sqr2.modify(|_, w| unsafe {w.sq10().bits(channel) }),
898                        config::Sequence::Eleven   => self.adc_reg.sqr2.modify(|_, w| unsafe {w.sq11().bits(channel) }),
899                        config::Sequence::Twelve   => self.adc_reg.sqr2.modify(|_, w| unsafe {w.sq12().bits(channel) }),
900                        config::Sequence::Thirteen => self.adc_reg.sqr1.modify(|_, w| unsafe {w.sq13().bits(channel) }),
901                        config::Sequence::Fourteen => self.adc_reg.sqr1.modify(|_, w| unsafe {w.sq14().bits(channel) }),
902                        config::Sequence::Fifteen  => self.adc_reg.sqr1.modify(|_, w| unsafe {w.sq15().bits(channel) }),
903                        config::Sequence::Sixteen  => self.adc_reg.sqr1.modify(|_, w| unsafe {w.sq16().bits(channel) }),
904                    }
905
906                    fn replace_bits(mut v: u32, offset: u32, width: u32, value: u32) -> u32 {
907                        let mask = !(((1 << width) -1) << (offset * width));
908                        v &= mask;
909                        v |= value << (offset * width);
910                        v
911                    }
912
913                    //Set the sample time for the channel
914                    let st = u8::from(sample_time);
915                    let st = u32::from(st);
916                    let ch = u32::from(channel);
917                    match channel {
918                        0...9   => self.adc_reg.smpr2.modify(|r, w| unsafe { w.bits(replace_bits(r.bits(), ch, 3, st)) }),
919                        10...18 => self.adc_reg.smpr1.modify(|r, w| unsafe { w.bits(replace_bits(r.bits(), ch-10, 3, st)) }),
920                        _ => unimplemented!(),
921                    }
922                }
923
924                /// Returns the current sample stored in the ADC data register
925                pub fn current_sample(&self) -> u16 {
926                    self.adc_reg.dr.read().data().bits()
927                }
928
929                /// Converts a sample value to millivolts using calibrated VDDA and configured resolution
930                pub fn sample_to_millivolts(&self, sample: u16) -> u16 {
931                    ((u32::from(sample) * self.calibrated_vdda) / self.max_sample) as u16
932                }
933
934                /// Block until the conversion is completed
935                /// # Panics
936                /// Will panic if there is no conversion started and the end-of-conversion bit is not set
937                pub fn wait_for_conversion_sequence(&self) {
938                    if !self.adc_reg.sr.read().strt().bit_is_set() && !self.adc_reg.sr.read().eoc().bit_is_set() {
939                        panic!("Waiting for end-of-conversion but no conversion started");
940                    }
941                    while !self.adc_reg.sr.read().eoc().bit_is_set() {}
942                    //Clear the conversion started flag
943                    self.adc_reg.sr.modify(|_, w| w.strt().clear_bit());
944                }
945
946                /// Synchronously convert a single sample
947                /// Note that it reconfigures the adc sequence and doesn't restore it
948                pub fn convert<PIN>(&mut self, pin: &PIN, sample_time: config::SampleTime) -> u16
949                where
950                    PIN: Channel<stm32::$adc_type, ID=u8>
951                {
952                    self.adc_reg.cr2.modify(|_, w| w
953                        .dma().clear_bit() //Disable dma
954                        .cont().clear_bit() //Disable continuous mode
955                        .exten().bits(config::TriggerMode::Disabled.into()) //Disable trigger
956                        .eocs().clear_bit() //EOC is set at the end of the sequence
957                    );
958                    self.adc_reg.cr1.modify(|_, w| w
959                        .scan().clear_bit() //Disable scan mode
960                        .eocie().clear_bit() //Disable end of conversion interrupt
961                    );
962
963                    self.reset_sequence();
964                    self.configure_channel(pin, config::Sequence::One, sample_time);
965                    self.enable();
966                    self.clear_end_of_conversion_flag();
967                    self.start_conversion();
968
969                    //Wait for the sequence to complete
970                    self.wait_for_conversion_sequence();
971
972                    let result = self.current_sample();
973
974                    //Reset the config
975                    self.apply_config(self.config);
976
977                    result
978                }
979            }
980
981            impl<PIN> OneShot<stm32::$adc_type, u16, PIN> for Adc<stm32::$adc_type>
982            where
983                PIN: Channel<stm32::$adc_type, ID=u8>,
984            {
985                type Error = ();
986
987                fn read(&mut self, pin: &mut PIN) -> nb::Result<u16, Self::Error> {
988                    let enabled = self.is_enabled();
989                    if !enabled {
990                        self.enable();
991                    }
992
993                    let sample = self.convert(pin, self.config.default_sample_time);
994
995                    if !enabled {
996                        self.disable();
997                    }
998
999                    Ok(sample)
1000                }
1001            }
1002        )+
1003    };
1004} 
1005
1006adc!(ADC1 => (adc1, ADC_COMMON, apb2enr, adc1en, apb2rstr, adcrst));
1007adc!(ADC2 => (adc2, ADC_COMMON, apb2enr, adc2en, apb2rstr, adcrst));
1008adc!(ADC3 => (adc3, ADC_COMMON, apb2enr, adc3en, apb2rstr, adcrst));
1009
1010adc_pins!(
1011    gpioa::PA0<Analog> => (ADC1, 0),
1012    gpioa::PA0<Analog> => (ADC2, 0),
1013    gpioa::PA0<Analog> => (ADC3, 0),
1014    gpioa::PA1<Analog> => (ADC1, 1),
1015    gpioa::PA1<Analog> => (ADC2, 1),
1016    gpioa::PA1<Analog> => (ADC3, 1),
1017    gpioa::PA2<Analog> => (ADC1, 2),
1018    gpioa::PA2<Analog> => (ADC2, 2),
1019    gpioa::PA2<Analog> => (ADC3, 2),
1020    gpioa::PA3<Analog> => (ADC1, 3),
1021    gpioa::PA3<Analog> => (ADC2, 3),
1022    gpioa::PA3<Analog> => (ADC3, 3),
1023    gpioa::PA4<Analog> => (ADC1, 4),
1024    gpioa::PA4<Analog> => (ADC2, 4),
1025    gpioa::PA5<Analog> => (ADC1, 5),
1026    gpioa::PA5<Analog> => (ADC2, 5),
1027    gpioa::PA6<Analog> => (ADC1, 6),
1028    gpioa::PA6<Analog> => (ADC2, 6),
1029    gpioa::PA7<Analog> => (ADC1, 7),
1030    gpioa::PA7<Analog> => (ADC2, 7),
1031    gpiob::PB0<Analog> => (ADC1, 8),
1032    gpiob::PB0<Analog> => (ADC2, 8),
1033    gpiob::PB1<Analog> => (ADC1, 9),
1034    gpiob::PB1<Analog> => (ADC2, 9),
1035    gpioc::PC0<Analog> => (ADC1, 10),
1036    gpioc::PC0<Analog> => (ADC2, 10),
1037    gpioc::PC0<Analog> => (ADC3, 10),
1038    gpioc::PC1<Analog> => (ADC1, 11),
1039    gpioc::PC1<Analog> => (ADC2, 11),
1040    gpioc::PC1<Analog> => (ADC3, 11),
1041    gpioc::PC2<Analog> => (ADC1, 12),
1042    gpioc::PC2<Analog> => (ADC2, 12),
1043    gpioc::PC2<Analog> => (ADC3, 12),
1044    gpioc::PC3<Analog> => (ADC1, 13),
1045    gpioc::PC3<Analog> => (ADC2, 13),
1046    gpioc::PC3<Analog> => (ADC3, 13),
1047    gpioc::PC4<Analog> => (ADC1, 14),
1048    gpioc::PC4<Analog> => (ADC2, 14),
1049    gpioc::PC5<Analog> => (ADC1, 15),
1050    gpioc::PC5<Analog> => (ADC2, 15),
1051    Temperature => (ADC1, 18),
1052    Temperature => (ADC2, 18),
1053    Temperature => (ADC3, 18),
1054    Vbat => (ADC1, 18),
1055    Vbat => (ADC2, 18),
1056    Vbat => (ADC3, 18),
1057    Vref => (ADC1, 17),
1058    Vref => (ADC2, 17),
1059    Vref => (ADC3, 17),
1060);
1061
1062adc_pins!(
1063    gpiof::PF10<Analog> => (ADC3, 8),
1064    gpiof::PF3<Analog> => (ADC3, 9),
1065    gpiof::PF4<Analog> => (ADC3, 14),
1066    gpiof::PF5<Analog> => (ADC3, 15),
1067    gpiof::PF6<Analog> => (ADC3, 4),
1068    gpiof::PF7<Analog> => (ADC3, 5),
1069    gpiof::PF8<Analog> => (ADC3, 6),
1070    gpiof::PF9<Analog> => (ADC3, 7),
1071);