1use core::ops::Deref;
13use core::{convert::TryInto, marker::PhantomData};
14
15use cortex_m::asm;
16use embedded_hal::adc::Channel;
17
18#[track_caller]
19unsafe fn unreachable_unchecked() -> ! {
20 #[cfg(debug_assertions)]
21 crate::unreachable!();
22 #[cfg(not(debug_assertions))]
23 #[allow(unused_unsafe)]
24 unsafe {
25 core::hint::unreachable_unchecked();
26 }
27}
28
29use crate::{
30 pac::{self, adc1, Interrupt},
31 rcc::{Clocks, Enable, AHB},
32 time::{duration::Microseconds, fixed_point::FixedPoint, rate::Hertz},
33 Switch,
34};
35
36use crate::pac::{adc1_2, adc1_2::ccr::CKMODE_A};
37
38#[cfg(feature = "enumset")]
39use enumset::{EnumSet, EnumSetType};
40
41const MAX_ADVREGEN_STARTUP: Microseconds = Microseconds(10);
42
43#[derive(Debug)]
45#[cfg_attr(feature = "defmt", derive(defmt::Format))]
46#[doc(alias = "V_REFINT")]
47pub struct VoltageInternalReference<ADC> {
48 _adc: PhantomData<ADC>,
49}
50
51#[derive(Debug)]
53#[cfg_attr(feature = "defmt", derive(defmt::Format))]
54#[doc(alias = "V_BAT")]
55pub struct VoltageBattery<ADC> {
56 _adc: PhantomData<ADC>,
57}
58
59#[derive(Debug)]
61#[cfg_attr(feature = "defmt", derive(defmt::Format))]
62#[doc(alias = "V_TS")]
63pub struct TemperatureSensor<ADC> {
64 _adc: PhantomData<ADC>,
65}
66
67#[allow(clippy::module_name_repetitions)]
101pub struct CommonAdc<ADC> {
102 reg: ADC,
103}
104
105impl<ADC> CommonAdc<ADC>
106where
107 ADC: CommonInstance,
108{
109 pub fn new(mut common_adc: ADC, clocks: &Clocks, ahb: &mut AHB) -> Self {
111 common_adc.enable_clock(clocks, ahb);
112
113 Self { reg: common_adc }
114 }
115
116 pub unsafe fn peripheral(&mut self) -> &mut ADC {
126 &mut self.reg
127 }
128}
129
130impl<ADC> CommonAdc<ADC>
131where
132 ADC: CommonInstance + crate::rcc::Enable,
133{
134 pub fn free(self, _adcs: &<ADC as CommonInstance>::Childs) -> ADC {
136 critical_section::with(|_| {
137 unsafe { ADC::disable_unchecked() };
141 });
142 self.reg
143 }
144}
145
146#[derive(Debug)]
151#[cfg_attr(feature = "defmt", derive(defmt::Format))]
152#[cfg_attr(feature = "enumset", derive(EnumSetType))]
153#[cfg_attr(not(feature = "enumset"), derive(Copy, Clone, PartialEq, Eq))]
154#[non_exhaustive]
155pub enum Event {
156 #[doc(alias = "ADRDY")]
159 AdcReady,
160 #[doc(alias = "EOSMP")]
163 EndOfSamplingPhase,
164 #[doc(alias = "EOC")]
167 EndOfConversion,
168 #[doc(alias = "EOS")]
173 EndOfSequence,
174 #[doc(alias = "OVR")]
184 Overrun,
185 #[doc(alias = "JEOC")]
188 InjectedChannelEndOfConversion,
189 #[doc(alias = "JEOS")]
191 InjectedChannelEndOfSequence,
192 #[doc(alias = "AWD1")]
196 AnalogWatchdog1,
197 #[doc(alias = "AWD2")]
201 AnalogWatchdog2,
202 #[doc(alias = "AWD3")]
206 AnalogWatchdog3,
207 #[doc(alias = "JQOVF")]
209 InjectedContextQueueOverfow,
210}
211
212#[derive(Debug)]
214pub struct Adc<ADC, State = Enabled> {
215 reg: ADC,
217 state: PhantomData<State>,
219}
220
221pub mod channel;
223
224pub mod config;
225
226macro_rules! sp_channel {
228 ([$(($Pin:ident, $ADC:ident, $chan:expr)),+ $(,)*]) => {
229 $(
230 impl Channel<pac::$ADC> for $Pin<<pac::$ADC as Instance>::SharedInstance> {
231 type ID = channel::Id;
232 fn channel() -> Self::ID { $chan }
233 }
234 )+
235 };
236}
237
238macro_rules! sp_pins {
239 ([$(($Pin:ident, $en:ident)),+ $(,)*]) => {
240 $(
241 impl<Common> $Pin<Common>
242 where
243 Common: CommonInstance,
244 {
245 #[inline]
265 pub fn new(
266 common_adc: &mut CommonAdc<Common>,
268 _adcs: &mut <Common as CommonInstance>::Childs,
275 ) -> Self {
276 common_adc.reg.ccr.modify(|_, w| w.$en().enabled());
277 Self { _adc: PhantomData }
278 }
279 }
280 )+
281 };
282}
283
284sp_channel!([
286 (TemperatureSensor, ADC1, channel::Id::Sixteen),
287 (VoltageBattery, ADC1, channel::Id::Seventeen),
288 (VoltageInternalReference, ADC1, channel::Id::Eighteen),
289]);
290
291#[cfg(any(feature = "svd-f302", feature = "svd-f303", feature = "svd-f3x4"))]
292sp_channel!([(VoltageInternalReference, ADC2, channel::Id::Eighteen),]);
293
294#[cfg(feature = "svd-f303")]
295sp_channel!([
296 (VoltageInternalReference, ADC3, channel::Id::Eighteen),
297 (VoltageInternalReference, ADC4, channel::Id::Eighteen),
298]);
299
300sp_pins!([
301 (TemperatureSensor, tsen),
302 (VoltageBattery, vbaten),
303 (VoltageInternalReference, vrefen),
304]);
305
306impl<ADC> Adc<ADC, Enabled>
307where
308 ADC: Instance,
309{
310 #[inline]
314 pub fn new(
315 adc: ADC,
316 config: impl Into<config::Config>,
317 clocks: &Clocks,
318 common_adc: &CommonAdc<<ADC as Instance>::SharedInstance>,
319 ) -> Adc<ADC, Enabled> {
320 let mut adc = Adc::new_disabled(adc);
321 let config: config::Config = config.into();
322 adc.set_config(config);
323 adc.calibrate(clocks, common_adc);
324 adc.into_enabled()
325 }
326
327 #[doc(alias = "ADC_DR")]
342 #[must_use]
343 #[inline]
344 pub fn data_register(&self) -> u16 {
345 self.reg.dr.read().rdata().bits()
346 }
347
348 #[inline]
351 pub fn data_register_address(&self) -> u32 {
352 core::ptr::addr_of!(self.reg.dr) as u32
353 }
354
355 #[inline]
360 pub fn start_conversion(&mut self) {
361 self.reg.cr.modify(|_, w| w.adstart().start_conversion());
362 }
363
364 #[inline]
366 #[must_use]
367 pub fn into_oneshot(mut self) -> Adc<ADC, OneShot> {
368 self.stop_conversion();
369 while self.is_conversion_ongoing() {}
370 self.set_conversion_mode(config::ConversionMode::Single);
371 self.set_dma_mode(config::DmaMode::Disabled);
372 self.set_external_trigger(None);
373
374 self.disable_interrupt(Event::EndOfConversion);
375 self.disable_interrupt(Event::EndOfSequence);
376
377 self.set_sequence_length(config::Sequence::One);
378
379 Adc {
380 reg: self.reg,
381 state: PhantomData,
382 }
383 }
384
385 #[inline]
387 #[must_use]
388 pub fn into_disabled(self) -> Adc<ADC, Disabled> {
389 if self.reg.cr.read().aden().bit()
395 && (self.reg.cr.read().adstart().bit() || self.reg.cr.read().jadstart().bit())
396 {
397 self.reg.cr.modify(|_, w| w.adstp().stop_conversion());
398 if !self.reg.cfgr.read().jauto().is_enabled() {
401 self.reg.cr.modify(|_, w| w.jadstp().stop_conversion());
402 }
403 while self.reg.cr.read().adstp().bit() || self.reg.cr.read().jadstp().bit() {}
404 }
405
406 if self.reg.cr.read().aden().is_enabled() {
409 self.reg.cr.modify(|_, w| w.addis().set_bit());
412 while self.reg.cr.read().aden().is_enabled() {}
414 }
415
416 Adc {
417 reg: self.reg,
418 state: PhantomData,
419 }
420 }
421
422 #[inline]
424 pub fn free(self) -> ADC {
425 self.into_disabled().reg
426 }
427}
428
429impl<ADC> Adc<ADC, Disabled>
430where
431 ADC: Instance,
432{
433 #[inline]
448 pub fn new_disabled(adc: ADC) -> Self {
449 Self {
450 reg: adc,
451 state: PhantomData,
452 }
453 }
454
455 #[inline]
457 #[must_use]
458 pub fn into_enabled(self) -> Adc<ADC, Enabled> {
459 if !self.reg.cr.read().aden().is_enabled() {
465 self.reg.cr.modify(|_, w| w.aden().enabled());
467 while self.reg.isr.read().adrdy().is_not_ready() {}
470 }
471
472 Adc {
473 reg: self.reg,
474 state: PhantomData,
475 }
476 }
477
478 #[inline]
490 pub fn calibrate(
491 &mut self,
492 clocks: &Clocks,
493 common_adc: &CommonAdc<<ADC as Instance>::SharedInstance>,
494 ) {
497 self.configure_voltage_regulator(Switch::On, clocks);
498
499 self.reg
500 .cr
501 .modify(|_, w| w.adcaldif().single_ended().adcal().calibration());
502
503 while self.reg.cr.read().adcal().is_calibration() {}
504
505 let adc_cycles = 4;
508 let frequency = common_adc
509 .reg
510 .clock(clocks)
511 .unwrap_or_else(|| clocks.sysclk());
512 let cpu_cycles = adc_cycles * clocks.sysclk().0 / frequency.0;
513 asm::delay(cpu_cycles);
514
515 self.configure_voltage_regulator(Switch::Off, clocks);
517 }
518
519 fn configure_voltage_regulator(&mut self, toggle: impl Into<Switch>, clocks: &Clocks) {
521 let already_on = self.reg.cr.read().advregen().is_enabled();
522 let toggle = toggle.into();
523 self.reg.cr.modify(|_, w| w.advregen().intermediate());
524 self.reg.cr.modify(|_, w| {
525 w.advregen().variant(match toggle {
526 Switch::On => adc1::cr::ADVREGEN_A::Enabled,
527 Switch::Off => adc1::cr::ADVREGEN_A::Disabled,
528 })
529 });
530 if toggle == Switch::On && !already_on {
531 let wait = MAX_ADVREGEN_STARTUP.integer()
532 * clocks.sysclk().integer()
533 * <Microseconds as FixedPoint>::SCALING_FACTOR;
534 asm::delay(wait);
535 }
536 }
537
538 #[inline]
540 pub fn free(self) -> ADC {
541 self.reg
542 }
543}
544
545impl<ADC, State> Adc<ADC, State>
546where
547 ADC: Instance,
548{
549 #[inline]
551 pub fn overrun_mode(&self) -> config::OverrunMode {
552 self.reg.cfgr.read().ovrmod().variant().into()
553 }
554
555 #[inline]
557 pub fn resolution(&self) -> config::Resolution {
558 self.reg.cfgr.read().res().variant().into()
559 }
560
561 #[inline]
563 pub fn data_alignment(&self) -> config::DataAlignment {
564 self.reg.cfgr.read().align().variant().into()
565 }
566
567 #[inline]
571 pub fn external_trigger(&self) -> Option<config::ExternalTrigger> {
572 use adc1::cfgr::{EXTEN_A, EXTSEL_A};
573 use config::ExternalTrigger;
574 let cfgr = self.reg.cfgr.read();
575
576 match (cfgr.exten().variant(), cfgr.extsel().variant()) {
577 (EXTEN_A::Disabled, _) | (_, None) => None,
578 (edge, Some(ext)) => {
579 let edge = match edge {
580 EXTEN_A::Disabled => {
581 unsafe { unreachable_unchecked() }
584 }
585 EXTEN_A::RisingEdge => config::TriggerMode::RisingEdge,
586 EXTEN_A::FallingEdge => config::TriggerMode::FallingEdge,
587 EXTEN_A::BothEdges => config::TriggerMode::BothEdges,
588 };
589
590 Some(match ext {
591 EXTSEL_A::HrtimAdctrg1 => ExternalTrigger::HrtimAdcTrg1(edge),
592 EXTSEL_A::HrtimAdctrg3 => ExternalTrigger::HrtimAdcTrg3(edge),
593 EXTSEL_A::Tim1Cc1 => ExternalTrigger::Tim1Cc1(edge),
594 EXTSEL_A::Tim1Cc2 => ExternalTrigger::Tim1Cc2(edge),
595 EXTSEL_A::Tim1Cc3 => ExternalTrigger::Tim1Cc3(edge),
596 EXTSEL_A::Tim2Cc2 => ExternalTrigger::Tim2Cc2(edge),
597 EXTSEL_A::Tim3Trgo => ExternalTrigger::Tim3Trgo(edge),
598 EXTSEL_A::Exti11 => ExternalTrigger::Exti11(edge),
599 EXTSEL_A::Tim1Trgo => ExternalTrigger::Tim1Trgo(edge),
600 EXTSEL_A::Tim1Trgo2 => ExternalTrigger::Tim1Trgo2(edge),
601 EXTSEL_A::Tim2Trgo => ExternalTrigger::Tim2Trgo(edge),
602 EXTSEL_A::Tim6Trgo => ExternalTrigger::Tim6Trgo(edge),
603 EXTSEL_A::Tim15Trgo => ExternalTrigger::Tim15Trgo(edge),
604 EXTSEL_A::Tim3Cc4 => ExternalTrigger::Tim3Cc4(edge),
605 })
606 }
607 }
608 }
609
610 #[inline]
612 pub fn conversion_mode(&self) -> config::ConversionMode {
613 use adc1::cfgr::{CONT_A, DISCEN_A};
614 let cfgr = self.reg.cfgr.read();
615
616 match (
617 cfgr.cont().variant(),
618 cfgr.discen().variant(),
619 cfgr.discnum().bits(),
620 ) {
621 (CONT_A::Single, DISCEN_A::Disabled, _) => config::ConversionMode::Single,
622 (CONT_A::Continuous, DISCEN_A::Disabled, _) => config::ConversionMode::Continuous,
623 (_, DISCEN_A::Enabled, n) => config::ConversionMode::Discontinuous(n),
627 }
628 }
629
630 #[inline]
632 pub fn dma_mode(&self) -> config::DmaMode {
633 use adc1::cfgr::{DMACFG_A, DMAEN_A};
634
635 let cfgr = self.reg.cfgr.read();
636 match (cfgr.dmaen().variant(), cfgr.dmacfg().variant()) {
637 (DMAEN_A::Disabled, _) => config::DmaMode::Disabled,
638 (DMAEN_A::Enabled, DMACFG_A::OneShot) => config::DmaMode::OneShot,
639 (DMAEN_A::Enabled, DMACFG_A::Circular) => config::DmaMode::Circular,
640 }
641 }
642
643 #[inline]
644 #[cfg(feature = "svd-f373")]
645 pub fn scan(&self) -> config::Scan {
647 self.reg.cr1.modify(|_, w| w.scan().variant(scan.into()));
648 }
649
650 pub fn config(&self) -> config::Config {
652 config::Config {
653 resolution: self.resolution(),
654 data_alignment: self.data_alignment(),
655 #[cfg(feature = "svd-f373")]
656 scan: self.scan(),
657 overrun: self.overrun_mode(),
658 external_trigger: self.external_trigger(),
659 conversion: self.conversion_mode(),
660 dma: self.dma_mode(),
661 }
663 }
664
665 #[inline]
673 pub fn is_conversion_ongoing(&self) -> bool {
674 self.reg.cr.read().adstart().is_active()
675 }
676
677 #[inline]
689 #[rustfmt::skip]
690 pub fn channel_sequence(&self, sequence: config::Sequence) -> Option<channel::Id> {
691 match sequence {
693 config::Sequence::One => self.reg.sqr1.read().sq1().bits().try_into().ok(),
694 config::Sequence::Two => self.reg.sqr1.read().sq2().bits().try_into().ok(),
695 config::Sequence::Three => self.reg.sqr1.read().sq3().bits().try_into().ok(),
696 config::Sequence::Four => self.reg.sqr1.read().sq4().bits().try_into().ok(),
697 config::Sequence::Five => self.reg.sqr2.read().sq5().bits().try_into().ok(),
698 config::Sequence::Six => self.reg.sqr2.read().sq6().bits().try_into().ok(),
699 config::Sequence::Seven => self.reg.sqr2.read().sq7().bits().try_into().ok(),
700 config::Sequence::Eight => self.reg.sqr2.read().sq8().bits().try_into().ok(),
701 config::Sequence::Nine => self.reg.sqr2.read().sq9().bits().try_into().ok(),
702 config::Sequence::Ten => self.reg.sqr3.read().sq10().bits().try_into().ok(),
703 config::Sequence::Eleven => self.reg.sqr3.read().sq11().bits().try_into().ok(),
704 config::Sequence::Twelve => self.reg.sqr3.read().sq12().bits().try_into().ok(),
705 config::Sequence::Thirteen => self.reg.sqr3.read().sq13().bits().try_into().ok(),
706 config::Sequence::Fourteen => self.reg.sqr3.read().sq14().bits().try_into().ok(),
707 config::Sequence::Fifteen => self.reg.sqr4.read().sq15().bits().try_into().ok(),
708 config::Sequence::Sixteen => self.reg.sqr4.read().sq16().bits().try_into().ok(),
709 }
710 }
711
712 pub fn sample_time<Pin>(&self, _pin: &Pin) -> config::SampleTime
715 where
716 Pin: Channel<ADC, ID = channel::Id>,
717 {
718 let channel = Pin::channel();
719 match channel {
721 #[cfg(feature = "gpio-f373")]
722 channel::Id::Zero => self.adc.smpr1.read().smp0().variant().into(),
723 channel::Id::One => self.reg.smpr1.read().smp1().variant().into(),
724 channel::Id::Two => self.reg.smpr1.read().smp2().variant().into(),
725 channel::Id::Three => self.reg.smpr1.read().smp3().variant().into(),
726 channel::Id::Four => self.reg.smpr1.read().smp4().variant().into(),
727 channel::Id::Five => self.reg.smpr1.read().smp5().variant().into(),
728 channel::Id::Six => self.reg.smpr1.read().smp6().variant().into(),
729 channel::Id::Seven => self.reg.smpr1.read().smp7().variant().into(),
730 channel::Id::Eight => self.reg.smpr1.read().smp8().variant().into(),
731 channel::Id::Nine => self.reg.smpr1.read().smp9().variant().into(),
732 channel::Id::Ten => self.reg.smpr2.read().smp10().variant().into(),
733 channel::Id::Eleven => self.reg.smpr2.read().smp11().variant().into(),
734 channel::Id::Twelve => self.reg.smpr2.read().smp12().variant().into(),
735 channel::Id::Thirteen => self.reg.smpr2.read().smp13().variant().into(),
736 channel::Id::Fourteen => self.reg.smpr2.read().smp14().variant().into(),
737 channel::Id::Fifteen => self.reg.smpr2.read().smp15().variant().into(),
738 channel::Id::Sixteen => self.reg.smpr2.read().smp16().variant().into(),
739 channel::Id::Seventeen => self.reg.smpr2.read().smp17().variant().into(),
740 channel::Id::Eighteen => self.reg.smpr2.read().smp18().variant().into(),
741 }
745 }
746
747 #[inline]
749 pub fn sequence_length(&self) -> config::Sequence {
750 match self.reg.sqr1.read().l().bits().try_into() {
751 Ok(seq) => seq,
752 Err(_) => unsafe { unreachable_unchecked() },
755 }
756 }
757
758 #[inline]
759 #[cfg(feature = "__disabled")]
760 pub fn is_injected_conversion_stopped(&self) -> bool {
761 self.adc.cr.read().jadstp().is_stop()
762 }
763
764 #[inline]
766 pub fn is_interrupt_configured(&self, event: Event) -> bool {
767 match event {
768 Event::AdcReady => self.reg.ier.read().adrdyie().is_enabled(),
769 Event::EndOfSamplingPhase => self.reg.ier.read().eosmpie().is_enabled(),
770 Event::EndOfConversion => self.reg.ier.read().eocie().is_enabled(),
771 Event::EndOfSequence => self.reg.ier.read().eosie().is_enabled(),
772 Event::Overrun => self.reg.ier.read().ovrie().is_enabled(),
773 Event::InjectedChannelEndOfConversion => self.reg.ier.read().jeocie().is_enabled(),
774 Event::InjectedChannelEndOfSequence => self.reg.ier.read().jeosie().is_enabled(),
775 Event::AnalogWatchdog1 => self.reg.ier.read().awd1ie().is_enabled(),
776 Event::AnalogWatchdog2 => self.reg.ier.read().awd2ie().is_enabled(),
777 Event::AnalogWatchdog3 => self.reg.ier.read().awd3ie().is_enabled(),
778 Event::InjectedContextQueueOverfow => self.reg.ier.read().jqovfie().is_enabled(),
779 }
780 }
781
782 #[cfg(feature = "enumset")]
784 #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
785 #[inline]
786 pub fn configured_interrupts(&mut self) -> EnumSet<Event> {
787 let mut events = EnumSet::new();
788
789 for event in EnumSet::<Event>::all().iter() {
790 if self.is_interrupt_configured(event) {
791 events |= event;
792 }
793 }
794
795 events
796 }
797
798 #[inline]
800 pub fn is_event_triggered(&self, event: Event) -> bool {
801 let isr = self.reg.isr.read();
802 match event {
803 Event::AdcReady => isr.adrdy().is_ready(),
804 Event::EndOfSamplingPhase => isr.eosmp().is_ended(),
805 Event::EndOfConversion => isr.eoc().is_complete(),
806 Event::EndOfSequence => isr.eos().is_complete(),
807 Event::Overrun => isr.ovr().is_overrun(),
808 Event::InjectedChannelEndOfConversion => isr.jeoc().is_complete(),
809 Event::InjectedChannelEndOfSequence => isr.jeos().is_complete(),
810 Event::AnalogWatchdog1 => isr.awd1().is_event(),
811 Event::AnalogWatchdog2 => isr.awd2().is_event(),
812 Event::AnalogWatchdog3 => isr.awd3().is_event(),
813 Event::InjectedContextQueueOverfow => isr.jqovf().is_overflow(),
814 }
815 }
816
817 #[cfg(feature = "enumset")]
829 #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
830 pub fn triggered_events(&self) -> EnumSet<Event> {
831 let mut events = EnumSet::new();
832
833 for event in EnumSet::<Event>::all().iter() {
834 if self.is_event_triggered(event) {
835 events |= event;
836 }
837 }
838
839 events
840 }
841
842 #[inline]
852 pub unsafe fn peripheral(&mut self) -> &mut ADC {
853 &mut self.reg
854 }
855}
856
857impl<ADC, State> Adc<ADC, State>
858where
859 ADC: Instance,
860 State: Configurable,
861{
862 pub fn set_config(&mut self, config: config::Config) {
864 self.set_resolution(config.resolution);
865 self.set_data_alignment(config.data_alignment);
866 #[cfg(feature = "svd-f373")]
867 self.set_scan(config.scan);
868 self.set_overrun_mode(config.overrun);
869 self.set_external_trigger(config.external_trigger);
870 self.set_conversion_mode(config.conversion);
871 self.set_dma_mode(config.dma);
872 }
873
874 #[inline]
876 pub fn set_overrun_mode(&mut self, mode: config::OverrunMode) {
877 self.reg.cfgr.modify(|_, w| w.ovrmod().variant(mode.into()));
878 }
879
880 #[inline]
882 pub fn set_resolution(&mut self, resolution: config::Resolution) {
883 self.reg
884 .cfgr
885 .modify(|_, w| w.res().variant(resolution.into()));
886 }
887
888 #[inline]
890 pub fn set_data_alignment(&mut self, align: config::DataAlignment) {
891 self.reg.cfgr.modify(|_, w| w.align().variant(align.into()));
892 }
893
894 #[inline]
902 pub fn set_external_trigger(&mut self, trigger: Option<config::ExternalTrigger>) {
904 self.stop_conversion();
906
907 self.reg.cfgr.modify(|_, w| {
908 if let Some(ext) = trigger {
909 w.extsel().variant(ext.into()).exten().variant(ext.into())
910 } else {
911 w.exten().disabled()
912 }
913 });
914 }
915
916 #[inline]
926 pub fn set_conversion_mode(&mut self, conversion_mode: config::ConversionMode) {
927 self.reg.cfgr.modify(|_, w| {
929 w.discen()
930 .variant(conversion_mode.into())
931 .cont()
932 .variant(conversion_mode.into())
933 });
934
935 if let config::ConversionMode::Discontinuous(n) = conversion_mode {
936 self.reg
937 .cfgr
938 .modify(|_, w| w.discnum().bits(if n < 0b111 { n } else { 0b111 }));
939 }
940 }
941
942 #[inline]
945 pub fn set_dma_mode(&mut self, dma: config::DmaMode) {
946 use adc1::cfgr::{DMACFG_A, DMAEN_A};
947 let (en, mode) = match dma {
948 config::DmaMode::Disabled => (DMAEN_A::Disabled, DMACFG_A::OneShot),
949 config::DmaMode::OneShot => (DMAEN_A::Enabled, DMACFG_A::OneShot),
950 config::DmaMode::Circular => (DMAEN_A::Enabled, DMACFG_A::Circular),
951 };
952
953 self.reg
954 .cfgr
955 .modify(|_, w| w.dmaen().variant(en).dmacfg().variant(mode));
956 }
957
958 #[inline]
960 #[cfg(feature = "svd-f373")]
961 pub fn set_scan(&mut self, scan: config::Scan) {
965 self.reg.cr1.modify(|_, w| w.scan().variant(scan.into()));
966 }
967
968 #[inline]
976 pub fn stop_conversion(&mut self) {
977 if self.is_conversion_ongoing() {
979 self.reg.cr.modify(|_, w| w.adstp().stop_conversion());
980 }
981
982 while self.reg.cr.read().adstp().bit_is_set() {}
983 }
984
985 #[inline]
987 pub fn set_pin_sequence_position<Pin>(&mut self, sequence: config::Sequence, _pin: &mut Pin)
988 where
989 Pin: Channel<ADC, ID = channel::Id>,
990 {
991 let channel = Pin::channel();
992
993 unsafe { self.set_channel_sequence_position(sequence, channel) };
996 }
997
998 #[inline]
1018 #[rustfmt::skip]
1019 pub unsafe fn set_channel_sequence_position(&mut self, sequence: config::Sequence, channel: channel::Id) {
1020 self.stop_conversion();
1021
1022 if self.sequence_length() < sequence {
1024 self.set_sequence_length(sequence);
1025 }
1026
1027 unsafe {
1030 match sequence {
1031 config::Sequence::One => self.reg.sqr1.modify(|_, w| w.sq1().bits(channel.into())),
1032 config::Sequence::Two => self.reg.sqr1.modify(|_, w| w.sq2().bits(channel.into())),
1033 config::Sequence::Three => self.reg.sqr1.modify(|_, w| w.sq3().bits(channel.into())),
1034 config::Sequence::Four => self.reg.sqr1.modify(|_, w| w.sq4().bits(channel.into())),
1035 config::Sequence::Five => self.reg.sqr2.modify(|_, w| w.sq5().bits(channel.into())),
1036 config::Sequence::Six => self.reg.sqr2.modify(|_, w| w.sq6().bits(channel.into())),
1037 config::Sequence::Seven => self.reg.sqr2.modify(|_, w| w.sq7().bits(channel.into())),
1038 config::Sequence::Eight => self.reg.sqr2.modify(|_, w| w.sq8().bits(channel.into())),
1039 config::Sequence::Nine => self.reg.sqr2.modify(|_, w| w.sq9().bits(channel.into())),
1040 config::Sequence::Ten => self.reg.sqr3.modify(|_, w| w.sq10().bits(channel.into())),
1041 config::Sequence::Eleven => self.reg.sqr3.modify(|_, w| w.sq11().bits(channel.into())),
1042 config::Sequence::Twelve => self.reg.sqr3.modify(|_, w| w.sq12().bits(channel.into())),
1043 config::Sequence::Thirteen => self.reg.sqr3.modify(|_, w| w.sq13().bits(channel.into())),
1044 config::Sequence::Fourteen => self.reg.sqr3.modify(|_, w| w.sq14().bits(channel.into())),
1045 config::Sequence::Fifteen => self.reg.sqr4.modify(|_, w| w.sq15().bits(channel.into())),
1046 config::Sequence::Sixteen => self.reg.sqr4.modify(|_, w| w.sq16().bits(channel.into())),
1047 }
1048 }
1049 }
1050
1051 #[rustfmt::skip]
1060 pub fn set_sample_time<Pin>(&mut self, _pin: &Pin, sample_time: config::SampleTime)
1061 where
1062 Pin: Channel<ADC, ID = channel::Id>,
1063 {
1064 let channel = Pin::channel();
1065 match channel {
1067 #[cfg(feature = "gpio-f373")]
1068 channel::Id::Zero => self.adc.smpr1.modify(|_, w| w.smp0().variant(sample_time.into())),
1069 channel::Id::One => self.reg.smpr1.modify(|_, w| w.smp1().variant(sample_time.into())),
1070 channel::Id::Two => self.reg.smpr1.modify(|_, w| w.smp2().variant(sample_time.into())),
1071 channel::Id::Three => self.reg.smpr1.modify(|_, w| w.smp3().variant(sample_time.into())),
1072 channel::Id::Four => self.reg.smpr1.modify(|_, w| w.smp4().variant(sample_time.into())),
1073 channel::Id::Five => self.reg.smpr1.modify(|_, w| w.smp5().variant(sample_time.into())),
1074 channel::Id::Six => self.reg.smpr1.modify(|_, w| w.smp6().variant(sample_time.into())),
1075 channel::Id::Seven => self.reg.smpr1.modify(|_, w| w.smp7().variant(sample_time.into())),
1076 channel::Id::Eight => self.reg.smpr1.modify(|_, w| w.smp8().variant(sample_time.into())),
1077 channel::Id::Nine => self.reg.smpr1.modify(|_, w| w.smp9().variant(sample_time.into())),
1078 channel::Id::Ten => self.reg.smpr2.modify(|_, w| w.smp10().variant(sample_time.into())),
1079 channel::Id::Eleven => self.reg.smpr2.modify(|_, w| w.smp11().variant(sample_time.into())),
1080 channel::Id::Twelve => self.reg.smpr2.modify(|_, w| w.smp12().variant(sample_time.into())),
1081 channel::Id::Thirteen => self.reg.smpr2.modify(|_, w| w.smp13().variant(sample_time.into())),
1082 channel::Id::Fourteen => self.reg.smpr2.modify(|_, w| w.smp14().variant(sample_time.into())),
1083 channel::Id::Fifteen => self.reg.smpr2.modify(|_, w| w.smp15().variant(sample_time.into())),
1084 channel::Id::Sixteen => self.reg.smpr2.modify(|_, w| w.smp16().variant(sample_time.into())),
1085 channel::Id::Seventeen => self.reg.smpr2.modify(|_, w| w.smp17().variant(sample_time.into())),
1086 channel::Id::Eighteen => self.reg.smpr2.modify(|_, w| w.smp18().variant(sample_time.into())),
1087 }
1090 }
1091
1092 #[inline]
1097 pub fn set_sequence_length(&mut self, sequence: config::Sequence) {
1098 self.reg.sqr1.modify(|_, w| w.l().bits(sequence.into()));
1099 }
1100
1101 #[inline]
1103 #[cfg(feature = "__disabled")]
1104 pub fn stop_injected_conversion(&mut self) {
1105 self.adc.cr.modify(|_, w| w.jadstp().stop());
1106 }
1107
1108 #[inline]
1110 pub fn enable_interrupt(&mut self, event: Event) {
1111 self.configure_interrupt(event, Switch::On);
1112 }
1113
1114 #[inline]
1116 pub fn disable_interrupt(&mut self, event: Event) {
1117 self.configure_interrupt(event, Switch::Off);
1118 }
1119
1120 #[inline]
1122 pub fn configure_interrupt(&mut self, event: Event, enable: impl Into<Switch>) {
1123 let enable: Switch = enable.into();
1125 let enable: bool = enable.into();
1126 match event {
1127 Event::AdcReady => self.reg.ier.modify(|_, w| w.adrdyie().bit(enable)),
1128 Event::EndOfSamplingPhase => self.reg.ier.modify(|_, w| w.eosmpie().bit(enable)),
1129 Event::EndOfConversion => self.reg.ier.modify(|_, w| w.eocie().bit(enable)),
1130 Event::EndOfSequence => self.reg.ier.modify(|_, w| w.eosie().bit(enable)),
1131 Event::Overrun => self.reg.ier.modify(|_, w| w.ovrie().bit(enable)),
1132 Event::InjectedChannelEndOfConversion => {
1133 self.reg.ier.modify(|_, w| w.jeocie().bit(enable));
1134 }
1135 Event::InjectedChannelEndOfSequence => {
1136 self.reg.ier.modify(|_, w| w.jeosie().bit(enable));
1137 }
1138 Event::AnalogWatchdog1 => self.reg.ier.modify(|_, w| w.awd1ie().bit(enable)),
1139 Event::AnalogWatchdog2 => self.reg.ier.modify(|_, w| w.awd2ie().bit(enable)),
1140 Event::AnalogWatchdog3 => self.reg.ier.modify(|_, w| w.awd3ie().bit(enable)),
1141 Event::InjectedContextQueueOverfow => {
1142 self.reg.ier.modify(|_, w| w.jqovfie().bit(enable));
1143 }
1144 };
1145 }
1146
1147 #[cfg(feature = "enumset")]
1153 #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
1154 #[inline]
1155 pub fn configure_interrupts(&mut self, events: EnumSet<Event>) {
1156 for event in events.complement().iter() {
1157 self.configure_interrupt(event, false);
1158 }
1159 for event in events.iter() {
1160 self.configure_interrupt(event, true);
1161 }
1162 }
1163
1164 #[inline]
1166 pub fn clear_event(&mut self, event: Event) {
1167 self.reg.isr.write(|w| match event {
1168 Event::AdcReady => w.adrdy().clear(),
1169 Event::EndOfSamplingPhase => w.eosmp().clear(),
1170 Event::EndOfConversion => w.eoc().clear(),
1171 Event::EndOfSequence => w.eos().clear(),
1172 Event::Overrun => w.ovr().clear(),
1173 Event::InjectedChannelEndOfConversion => w.jeoc().clear(),
1174 Event::InjectedChannelEndOfSequence => w.jeos().clear(),
1175 Event::AnalogWatchdog1 => w.awd1().clear(),
1176 Event::AnalogWatchdog2 => w.awd2().clear(),
1177 Event::AnalogWatchdog3 => w.awd3().clear(),
1178 Event::InjectedContextQueueOverfow => w.jqovf().clear(),
1179 });
1180 }
1181
1182 #[inline]
1184 pub fn clear_events(&mut self) {
1185 self.reg.isr.write(|w| unsafe { w.bits(u32::MAX) });
1187 }
1188}
1189
1190impl<ADC> Adc<ADC, OneShot>
1191where
1192 ADC: Instance,
1193{
1194 pub fn into_enabled(self) -> Adc<ADC, Enabled> {
1197 Adc {
1198 reg: self.reg,
1199 state: PhantomData,
1200 }
1201 }
1202
1203 #[inline]
1205 pub fn free(self) -> ADC {
1206 self.into_enabled().into_disabled().reg
1207 }
1208}
1209
1210impl<ADC> Adc<ADC>
1211where
1212 ADC: crate::interrupts::InterruptNumber,
1213{
1214 pub fn interrupt(&self) -> <ADC as crate::interrupts::InterruptNumber>::Interrupt {
1234 <ADC as crate::interrupts::InterruptNumber>::INTERRUPT
1235 }
1236}
1237
1238pub trait Configurable: crate::private::Sealed {}
1240
1241impl<ADC, Word, Pin> embedded_hal::adc::OneShot<ADC, Word, Pin> for Adc<ADC>
1242where
1243 ADC: Instance,
1244 Word: From<u16>,
1245 Pin: Channel<ADC, ID = channel::Id>,
1246{
1247 type Error = ();
1248
1249 fn read(&mut self, pin: &mut Pin) -> nb::Result<Word, Self::Error> {
1261 let conv = self.conversion_mode();
1262 let dma = self.dma_mode();
1263 let ext = self.external_trigger();
1264 self.set_conversion_mode(config::ConversionMode::Single);
1265 self.set_dma_mode(config::DmaMode::Disabled);
1266 self.set_external_trigger(None);
1267
1268 #[cfg(feature = "svd-f373")]
1270 let scan = self.scan();
1271 #[cfg(feature = "svd-f373")]
1272 self.set_scan(config::Scan::Disabled);
1273
1274 let is_end_of_conversion_enabled = self.is_interrupt_configured(Event::EndOfConversion);
1275 let is_end_of_sequence_enabled = self.is_interrupt_configured(Event::EndOfSequence);
1276 self.disable_interrupt(Event::EndOfConversion);
1277 self.disable_interrupt(Event::EndOfSequence);
1278
1279 let seq_len = self.sequence_length();
1280 let old_id = self.channel_sequence(config::Sequence::One);
1281 self.set_sequence_length(config::Sequence::One);
1282 self.set_pin_sequence_position(config::Sequence::One, pin);
1283
1284 self.clear_event(Event::EndOfConversion);
1286 self.clear_event(Event::EndOfSequence);
1287 self.start_conversion();
1288 while !self.is_event_triggered(Event::EndOfConversion)
1289 && !self.is_event_triggered(Event::EndOfSequence)
1290 {}
1291 self.clear_event(Event::EndOfConversion);
1292 self.clear_event(Event::EndOfSequence);
1293
1294 let result = self.data_register();
1296
1297 if let Some(id) = old_id {
1299 unsafe { self.set_channel_sequence_position(config::Sequence::One, id) };
1302 }
1303 self.set_sequence_length(seq_len);
1304
1305 self.configure_interrupt(Event::EndOfSequence, is_end_of_sequence_enabled);
1306 self.configure_interrupt(Event::EndOfConversion, is_end_of_conversion_enabled);
1307
1308 #[cfg(feature = "svd-f373")]
1309 self.set_scan(config::Scan::Disabled);
1310
1311 self.set_external_trigger(ext);
1312 self.set_dma_mode(dma);
1313 self.set_conversion_mode(conv);
1314
1315 Ok(result.into())
1316 }
1317}
1318
1319impl<ADC, Word, Pin> embedded_hal::adc::OneShot<ADC, Word, Pin> for Adc<ADC, OneShot>
1320where
1321 ADC: Instance,
1322 Word: From<u16>,
1323 Pin: Channel<ADC, ID = channel::Id>,
1324{
1325 type Error = ();
1326
1327 fn read(&mut self, _pin: &mut Pin) -> nb::Result<Word, Self::Error> {
1329 self.reg.sqr1.modify(|_, w|
1335 unsafe { w.sq1().bits(Pin::channel().into()) });
1337
1338 self.reg.isr.reset();
1342 self.reg.cr.modify(|_, w| w.adstart().start_conversion());
1344 while !self.reg.isr.read().eoc().is_complete() && !self.reg.isr.read().eos().is_complete() {
1348 }
1349 self.reg.isr.reset();
1351
1352 Ok(self.reg.dr.read().rdata().bits().into())
1355 }
1356}
1357
1358pub trait Instance: Deref<Target = adc1::RegisterBlock> + crate::private::Sealed {
1360 type SharedInstance: CommonInstance;
1362}
1363
1364pub trait CommonInstance: Deref<Target = adc1_2::RegisterBlock> + crate::private::Sealed {
1366 type Childs;
1368
1369 #[doc(hidden)]
1370 fn enable_clock(&mut self, clocks: &Clocks, ahb: &mut AHB);
1371 #[doc(hidden)]
1372 fn clock(&self, clocks: &Clocks) -> Option<Hertz>;
1374}
1375
1376pub struct Enabled;
1380impl crate::private::Sealed for Enabled {}
1381impl Configurable for Enabled {}
1382
1383pub struct Disabled;
1387impl crate::private::Sealed for Disabled {}
1388impl Configurable for Disabled {}
1389
1390pub struct OneShot;
1402
1403macro_rules! adc {
1405 ($(
1406 $ADC:ident: (
1407 $ADCX_Y:ident,
1408 $INTERRUPT:path
1409 ),
1410 )+) => {
1411 $(
1412 impl crate::private::Sealed for pac::$ADC {}
1413
1414 impl Instance for pac::$ADC {
1415 type SharedInstance = pac::$ADCX_Y;
1416 }
1417
1418 impl crate::interrupts::InterruptNumber for pac::$ADC {
1419 type Interrupt = Interrupt;
1420 const INTERRUPT: Interrupt = $INTERRUPT;
1421 }
1422 )+
1423 };
1424
1425 ([ $(($A:literal, $X:literal, $Y:literal, $INTERRUPT:path)),+ ]) => {
1426 paste::paste! {
1427 adc!(
1428 $(
1429 [<ADC $A>]: (
1430 [<ADC $X _ $Y>],
1431 $INTERRUPT
1432 ),
1433 )+
1434 );
1435 }
1436 };
1437}
1438
1439macro_rules! adc_common {
1440 ($(
1441 $ADCX_Y:ident: (
1442 $ADC_CHILDS:ty,
1443 $ADCXYPRES_A:ident,
1444 $adcXYen:ident,
1445 $adcXYpres:ident
1446 ),
1447 )+) => {
1448 $(
1449
1450 impl CommonInstance for pac::$ADCX_Y {
1451 type Childs = $ADC_CHILDS;
1452
1453 fn enable_clock(&mut self, clocks: &Clocks, ahb: &mut AHB) {
1454 pac::$ADCX_Y::enable(ahb);
1455 if self.clock(clocks).is_none() {
1460 self.ccr.modify(|_, w| w
1461 .ckmode().variant(CKMODE_A::SyncDiv1)
1462 );
1463 };
1464 }
1465
1466 fn clock(&self, clocks: &Clocks) -> Option<Hertz> {
1467 use crate::pac::rcc::cfgr2::$ADCXYPRES_A;
1468 use crate::pac::RCC;
1469 let adc_pres = unsafe { &(*RCC::ptr()).cfgr2.read().$adcXYpres() };
1471 Some(match clocks.pllclk() {
1477 Some(pllclk) if !adc_pres.is_no_clock() => {
1478 pllclk
1479 / match adc_pres.variant() {
1480 Some($ADCXYPRES_A::Div1) => 1,
1481 Some($ADCXYPRES_A::Div2) => 2,
1482 Some($ADCXYPRES_A::Div4) => 4,
1483 Some($ADCXYPRES_A::Div6) => 6,
1484 Some($ADCXYPRES_A::Div8) => 8,
1485 Some($ADCXYPRES_A::Div10) => 10,
1486 Some($ADCXYPRES_A::Div12) => 12,
1487 Some($ADCXYPRES_A::Div16) => 16,
1488 Some($ADCXYPRES_A::Div32) => 32,
1489 Some($ADCXYPRES_A::Div64) => 64,
1490 Some($ADCXYPRES_A::Div128) => 128,
1491 Some($ADCXYPRES_A::Div256) => 256,
1492 Some($ADCXYPRES_A::NoClock) | None => 1,
1493 }
1494 }
1495 _ => {
1496 clocks.sysclk()
1497 / match self.ccr.read().ckmode().variant() {
1498 CKMODE_A::SyncDiv1 => 1,
1499 CKMODE_A::SyncDiv2 => 2,
1500 CKMODE_A::SyncDiv4 => 4,
1501 CKMODE_A::Asynchronous => return None,
1505 }
1506 }
1507 })
1508 }
1509 }
1510 )+
1511 };
1512
1513 ([ $(($X:literal, $Y:literal)),+ ]) => {
1514 paste::paste! {
1515 adc_common!(
1516 $(
1517 [<ADC $X _ $Y>]: (
1518 (pac::[<ADC $X>], pac::[<ADC $Y>]),
1519 [<ADC $X $Y PRES_A>],
1520 [<adc $X $Y en>],
1521 [<adc $X $Y pres>]
1522 ),
1523 )+
1524 );
1525 }
1526 };
1527
1528 ([ $(($X:literal, $Y:literal, $ADC:ident)),+ ]) => {
1530 paste::paste! {
1531 adc_common!(
1532 $(
1533 $ADC: (
1534 (pac::[<ADC $X>], pac::[<ADC $Y>]),
1535 [<ADC $X $Y PRES_A>],
1536 [<adc $X $Y en>],
1537 [<adc $X $Y pres>]
1538 ),
1539 )+
1540 );
1541 }
1542 };
1543
1544 ([ $(($A:literal, $X:literal, $Y:literal)),+ ]) => {
1545 paste::paste! {
1546 adc_common!(
1547 $(
1548 [<ADC $X _ $Y>]: (
1549 pac::[<ADC $A>],
1550 [<ADC $X PRES_A>],
1551 [<adc $X en>],
1552 [<adc $X pres>]
1553 ),
1554 )+
1555 );
1556 }
1557 };
1558}
1559
1560cfg_if::cfg_if! {
1561 if #[cfg(feature = "svd-f301")] {
1562 adc_common!([(1, 1, 2)]);
1563 adc!([(1, 1, 2, Interrupt::ADC1_IRQ)]);
1564 } else {
1565 adc_common!([(1, 2)]);
1566 adc!([(1, 1, 2, Interrupt::ADC1_2)]);
1567 }
1568}
1569
1570#[cfg(any(feature = "svd-f302", feature = "svd-f303", feature = "svd-f3x4"))]
1575adc!([(2, 1, 2, Interrupt::ADC1_2)]);
1576
1577cfg_if::cfg_if! {
1578 if #[cfg(feature = "svd-f303")] {
1579 adc_common!([(3, 4)]);
1580 adc!([(3, 3, 4, Interrupt::ADC3), (4, 3, 4, Interrupt::ADC4)]);
1581 }
1582}