1#![macro_use]
4#![allow(missing_docs)] #![cfg_attr(adc_f3_v2, allow(unused))]
6
7#[cfg(not(any(adc_f3_v2)))]
8#[cfg_attr(adc_f1, path = "f1.rs")]
9#[cfg_attr(adc_f3, path = "f3.rs")]
10#[cfg_attr(adc_f3_v1_1, path = "f3_v1_1.rs")]
11#[cfg_attr(adc_v1, path = "v1.rs")]
12#[cfg_attr(adc_l0, path = "v1.rs")]
13#[cfg_attr(adc_v2, path = "v2.rs")]
14#[cfg_attr(any(adc_v3, adc_g0, adc_h5, adc_u0), path = "v3.rs")]
15#[cfg_attr(any(adc_v4, adc_u5), path = "v4.rs")]
16#[cfg_attr(adc_g4, path = "g4.rs")]
17mod _version;
18
19use core::marker::PhantomData;
20
21#[allow(unused)]
22#[cfg(not(any(adc_f3_v2)))]
23pub use _version::*;
24#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
25use embassy_sync::waitqueue::AtomicWaker;
26
27#[cfg(adc_u5)]
28#[path = "u5_adc4.rs"]
29pub mod adc4;
30
31pub use crate::pac::adc::vals;
32#[cfg(not(any(adc_f1, adc_f3_v2)))]
33pub use crate::pac::adc::vals::Res as Resolution;
34pub use crate::pac::adc::vals::SampleTime;
35use crate::peripherals;
36
37dma_trait!(RxDma, Instance);
38#[cfg(adc_u5)]
39dma_trait!(RxDma4, adc4::Instance);
40
41pub struct Adc<'d, T: Instance> {
43 #[allow(unused)]
44 adc: crate::PeripheralRef<'d, T>,
45 #[cfg(not(any(adc_f3_v2, adc_f3_v1_1)))]
46 sample_time: SampleTime,
47}
48
49#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
50pub struct State {
51 pub waker: AtomicWaker,
52}
53
54#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
55impl State {
56 pub const fn new() -> Self {
57 Self {
58 waker: AtomicWaker::new(),
59 }
60 }
61}
62
63trait SealedInstance {
64 #[allow(unused)]
65 fn regs() -> crate::pac::adc::Adc;
66 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
67 #[allow(unused)]
68 fn common_regs() -> crate::pac::adccommon::AdcCommon;
69 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
70 fn state() -> &'static State;
71}
72
73pub(crate) trait SealedAdcChannel<T> {
74 #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5))]
75 fn setup(&mut self) {}
76
77 #[allow(unused)]
78 fn channel(&self) -> u8;
79}
80
81#[allow(unused)]
83pub(crate) fn blocking_delay_us(us: u32) {
84 #[cfg(feature = "time")]
85 embassy_time::block_for(embassy_time::Duration::from_micros(us as u64));
86 #[cfg(not(feature = "time"))]
87 {
88 let freq = unsafe { crate::rcc::get_freqs() }.sys.to_hertz().unwrap().0 as u64;
89 let us = us as u64;
90 let cycles = freq * us / 1_000_000;
91 cortex_m::asm::delay(cycles as u32);
92 }
93}
94
95#[cfg(not(any(
97 adc_f1,
98 adc_v1,
99 adc_l0,
100 adc_v2,
101 adc_v3,
102 adc_v4,
103 adc_g4,
104 adc_f3,
105 adc_f3_v1_1,
106 adc_g0,
107 adc_u0,
108 adc_h5,
109 adc_u5
110)))]
111#[allow(private_bounds)]
112pub trait Instance: SealedInstance + crate::Peripheral<P = Self> {
113 type Interrupt: crate::interrupt::typelevel::Interrupt;
114}
115#[cfg(any(
117 adc_f1,
118 adc_v1,
119 adc_l0,
120 adc_v2,
121 adc_v3,
122 adc_v4,
123 adc_g4,
124 adc_f3,
125 adc_f3_v1_1,
126 adc_g0,
127 adc_u0,
128 adc_h5,
129 adc_u5
130))]
131#[allow(private_bounds)]
132pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {
133 type Interrupt: crate::interrupt::typelevel::Interrupt;
134}
135
136#[allow(private_bounds)]
138pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized {
139 #[allow(unused_mut)]
140 fn degrade_adc(mut self) -> AnyAdcChannel<T> {
141 #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5))]
142 self.setup();
143
144 AnyAdcChannel {
145 channel: self.channel(),
146 _phantom: PhantomData,
147 }
148 }
149}
150
151pub struct AnyAdcChannel<T> {
156 channel: u8,
157 _phantom: PhantomData<T>,
158}
159
160impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {}
161impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> {
162 fn channel(&self) -> u8 {
163 self.channel
164 }
165}
166
167#[cfg(adc_u5)]
168foreach_adc!(
169 (ADC4, $common_inst:ident, $clock:ident) => {
170 impl crate::adc::adc4::SealedInstance for peripherals::ADC4 {
171 fn regs() -> crate::pac::adc::Adc4 {
172 crate::pac::ADC4
173 }
174 }
175
176 impl crate::adc::adc4::Instance for peripherals::ADC4 {
177 type Interrupt = crate::_generated::peripheral_interrupts::ADC4::GLOBAL;
178 }
179 };
180
181 ($inst:ident, $common_inst:ident, $clock:ident) => {
182 impl crate::adc::SealedInstance for peripherals::$inst {
183 fn regs() -> crate::pac::adc::Adc {
184 crate::pac::$inst
185 }
186
187 fn common_regs() -> crate::pac::adccommon::AdcCommon {
188 return crate::pac::$common_inst
189 }
190 }
191
192 impl crate::adc::Instance for peripherals::$inst {
193 type Interrupt = crate::_generated::peripheral_interrupts::$inst::GLOBAL;
194 }
195 };
196);
197
198#[cfg(not(adc_u5))]
199foreach_adc!(
200 ($inst:ident, $common_inst:ident, $clock:ident) => {
201 impl crate::adc::SealedInstance for peripherals::$inst {
202 fn regs() -> crate::pac::adc::Adc {
203 crate::pac::$inst
204 }
205
206 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
207 fn common_regs() -> crate::pac::adccommon::AdcCommon {
208 return crate::pac::$common_inst
209 }
210
211 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
212 fn state() -> &'static State {
213 static STATE: State = State::new();
214 &STATE
215 }
216 }
217
218 impl crate::adc::Instance for peripherals::$inst {
219 type Interrupt = crate::_generated::peripheral_interrupts::$inst::GLOBAL;
220 }
221 };
222);
223
224macro_rules! impl_adc_pin {
225 ($inst:ident, $pin:ident, $ch:expr) => {
226 impl crate::adc::AdcChannel<peripherals::$inst> for crate::peripherals::$pin {}
227 impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::peripherals::$pin {
228 #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5))]
229 fn setup(&mut self) {
230 <Self as crate::gpio::SealedPin>::set_as_analog(self);
231 }
232
233 fn channel(&self) -> u8 {
234 $ch
235 }
236 }
237 };
238}
239
240#[cfg(not(any(adc_f1, adc_f3_v2)))]
244pub const fn resolution_to_max_count(res: Resolution) -> u32 {
245 match res {
246 #[cfg(adc_v4)]
247 Resolution::BITS16 => (1 << 16) - 1,
248 #[cfg(any(adc_v4, adc_u5))]
249 Resolution::BITS14 => (1 << 14) - 1,
250 #[cfg(adc_v4)]
251 Resolution::BITS14V => (1 << 14) - 1,
252 #[cfg(adc_v4)]
253 Resolution::BITS12V => (1 << 12) - 1,
254 Resolution::BITS12 => (1 << 12) - 1,
255 Resolution::BITS10 => (1 << 10) - 1,
256 Resolution::BITS8 => (1 << 8) - 1,
257 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_l0, adc_g0, adc_f3, adc_f3_v1_1, adc_h5))]
258 Resolution::BITS6 => (1 << 6) - 1,
259 #[allow(unreachable_patterns)]
260 _ => core::unreachable!(),
261 }
262}