1#![macro_use]
4#![allow(missing_docs)] #[cfg_attr(adc_v1, path = "v1.rs")]
11#[cfg_attr(adc_v1b, path = "v1.rs")]
12#[cfg_attr(adc_v2, path = "v2.rs")]
13mod _version;
14
15#[allow(unused)]
16pub use _version::*;
17
18use core::marker::PhantomData;
19use embassy_sync::waitqueue::AtomicWaker;
20
21pub use crate::pac::adc::vals;
22pub use crate::pac::adc::vals::Res as Resolution;
23pub use crate::pac::adc::vals::SampleTime;
24use crate::peripherals;
25
26#[cfg(dma)]
27dma_trait!(RxDma, Instance);
28
29pub struct Adc<'d, T: Instance> {
31 #[allow(unused)]
32 adc: crate::PeripheralRef<'d, T>,
33 sample_time: SampleTime,
34}
35
36pub struct State {
37 pub waker: AtomicWaker,
38}
39
40impl State {
41 pub const fn new() -> Self {
42 Self {
43 waker: AtomicWaker::new(),
44 }
45 }
46}
47
48trait SealedInstance {
49 #[allow(unused)]
50 fn regs() -> crate::pac::adc::Adc;
51 #[allow(unused)]
52 fn state() -> &'static State;
53}
54
55pub(crate) trait SealedAdcChannel<T> {
56 fn setup(&mut self) {}
57
58 #[allow(unused)]
59 fn channel(&self) -> u8;
60}
61
62#[allow(unused)]
64pub(crate) fn blocking_delay_us(us: u32) {
65 #[cfg(feature = "time")]
66 embassy_time::block_for(embassy_time::Duration::from_micros(us as u64));
67 #[cfg(not(feature = "time"))]
68 {
69 let freq = unsafe { crate::rcc::get_freqs() }.sys.to_hertz().unwrap().0 as u64;
70 let us = us as u64;
71 let cycles = freq * us / 1_000_000;
72 cortex_m::asm::delay(cycles as u32);
73 }
74}
75
76#[allow(private_bounds)]
78pub trait Instance:
79 SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral
80{
81 type Interrupt: crate::interrupt::typelevel::Interrupt;
82}
83
84#[allow(private_bounds)]
86pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized {
87 #[allow(unused_mut)]
88 fn degrade_adc(mut self) -> AnyAdcChannel<T> {
89 self.setup();
90
91 AnyAdcChannel {
92 channel: self.channel(),
93 _phantom: PhantomData,
94 }
95 }
96}
97
98pub struct AnyAdcChannel<T> {
103 channel: u8,
104 _phantom: PhantomData<T>,
105}
106
107impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {}
108impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> {
109 fn channel(&self) -> u8 {
110 self.channel
111 }
112}
113
114foreach_adc!(
115 ($inst:ident, $common_inst:ident, $clock:ident) => {
116 impl crate::adc::SealedInstance for peripherals::$inst {
117 fn regs() -> crate::pac::adc::Adc {
118 crate::pac::$inst
119 }
120
121 fn state() -> &'static State {
122 static STATE: State = State::new();
123 &STATE
124 }
125 }
126
127 impl crate::adc::Instance for peripherals::$inst {
128 type Interrupt = crate::_generated::peripheral_interrupts::$inst::GLOBAL;
129 }
130 };
131);
132
133#[allow(unused_macros)]
134macro_rules! impl_adc_pin {
135 ($inst:ident, $pin:ident, $ch:expr) => {
136 impl crate::adc::AdcChannel<peripherals::$inst> for crate::peripherals::$pin {}
137 impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::peripherals::$pin {
138 fn setup(&mut self) {
139 <Self as crate::gpio::SealedPin>::set_as_analog(self);
140 }
141
142 fn channel(&self) -> u8 {
143 $ch
144 }
145 }
146 };
147}
148
149pub const fn resolution_to_max_count(res: Resolution) -> u32 {
153 match res {
154 Resolution::BITS12 => (1 << 12) - 1,
155 Resolution::BITS10 => (1 << 10) - 1,
156 Resolution::BITS8 => (1 << 8) - 1,
157 Resolution::BITS6 => (1 << 6) - 1,
158 #[allow(unreachable_patterns)]
159 _ => core::unreachable!(),
160 }
161}