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