1use core::future::poll_fn;
6use core::marker::PhantomData;
7use core::task::Poll;
8
9use embassy_hal_internal::into_ref;
10
11use super::blocking_delay_us;
12use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
13use crate::interrupt::typelevel::Interrupt;
14use crate::pac::adc::vals::Extsel;
15use crate::pac::RCC;
16use crate::peripherals::ADC1;
17use crate::time::Hertz;
18use crate::{interrupt, rcc, Peripheral};
19
20mod ringbuffered_v2;
21pub use ringbuffered_v2::{RingBufferedAdc, Sequence};
22
23pub const VREF_DEFAULT_MV: u32 = 3300;
25pub const VREF_CALIB_MV: u32 = 3300;
27
28pub struct InterruptHandler<T: Instance> {
30 _phantom: PhantomData<T>,
31}
32
33impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
34 unsafe fn on_interrupt() {
35 if T::regs().sr().read().eoc() {
36 T::regs().cr1().modify(|reg| reg.set_eocie(false));
37 } else {
38 return;
39 }
40
41 T::state().waker.wake();
42 }
43}
44
45pub struct VrefInt;
46impl AdcChannel<ADC1> for VrefInt {}
47impl super::SealedAdcChannel<ADC1> for VrefInt {
48 fn channel(&self) -> u8 {
49 17
50 }
51}
52
53impl VrefInt {
54 pub fn start_time_us() -> u32 {
56 10
57 }
58}
59
60pub struct Temperature;
61impl AdcChannel<ADC1> for Temperature {}
62impl super::SealedAdcChannel<ADC1> for Temperature {
63 fn channel(&self) -> u8 {
64 16
65 }
66}
67
68impl Temperature {
69 pub fn start_time_us() -> u32 {
71 10
72 }
73}
74
75pub enum Prescaler {
84 Div2,
85 Div4,
86 Div6,
87 Div8,
88}
89
90impl Prescaler {
91 fn from_pclk(freq: Hertz) -> Self {
92 #[cfg(py32f072)]
93 const MAX_FREQUENCY: Hertz = Hertz(16_000_000);
94 let raw_div = freq.0 / MAX_FREQUENCY.0;
95 match raw_div {
96 0..=1 => Self::Div2,
97 2..=3 => Self::Div4,
98 4..=5 => Self::Div6,
99 6..=7 => Self::Div8,
100 _ => panic!(
101 "Selected PCLK frequency is too high for ADC with largest possible prescaler."
102 ),
103 }
104 }
105
106 fn adcdiv(&self) -> crate::pac::rcc::vals::Adcdiv {
107 match self {
108 Prescaler::Div2 => crate::pac::rcc::vals::Adcdiv::DIV2,
109 Prescaler::Div4 => crate::pac::rcc::vals::Adcdiv::DIV4,
110 Prescaler::Div6 => crate::pac::rcc::vals::Adcdiv::DIV6,
111 Prescaler::Div8 => crate::pac::rcc::vals::Adcdiv::DIV8,
112 }
113 }
114}
115
116impl<'d, T> Adc<'d, T>
117where
118 T: Instance,
119{
120 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
121 let presc = Prescaler::from_pclk(T::frequency());
122 Self::new_with_prediv(adc, presc)
123 }
124
125 pub fn new_async(
126 adc: impl Peripheral<P = T> + 'd,
127 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
128 ) -> Self {
129 let presc = Prescaler::from_pclk(T::frequency());
130 Self::new_with_prediv_async(adc, presc, _irq)
131 }
132
133 pub fn new_with_prediv(adc: impl Peripheral<P = T> + 'd, adc_div: Prescaler) -> Self {
135 into_ref!(adc);
136 rcc::enable_and_reset::<T>();
137
138 RCC.cr().modify(|reg| {
139 reg.set_adcdiv(adc_div.adcdiv());
140 });
141 T::regs().cr2().modify(|reg| {
142 reg.set_extsel(Extsel::SWSTART);
143 });
144
145 Self::calibrate();
146
147 T::regs().cr2().modify(|reg| {
148 reg.set_adon(true);
149 });
150
151 blocking_delay_us(3);
152
153 Self {
154 adc,
155 sample_time: SampleTime::from_bits(0),
156 }
157 }
158
159 pub fn new_with_prediv_async(
161 adc: impl Peripheral<P = T> + 'd,
162 adc_div: Prescaler,
163 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
164 ) -> Self {
165 let adc = Self::new_with_prediv(adc, adc_div);
166
167 T::Interrupt::unpend();
168 unsafe {
169 T::Interrupt::enable();
170 }
171
172 adc
173 }
174
175 pub fn set_sample_time(&mut self, sample_time: SampleTime) {
176 self.sample_time = sample_time;
177 }
178
179 pub fn set_resolution(&mut self, resolution: Resolution) {
180 T::regs().cr1().modify(|reg| reg.set_res(resolution.into()));
181 }
182
183 pub fn enable_vrefint(&self) -> VrefInt {
186 T::regs().cr2().modify(|reg| {
187 reg.set_tsvrefe(true);
188 });
189
190 VrefInt {}
191 }
192
193 pub fn enable_temperature(&self) -> Temperature {
199 T::regs().cr2().modify(|reg| {
200 reg.set_tsvrefe(true);
201 });
202
203 Temperature {}
204 }
205
206 fn convert(&mut self) -> u16 {
218 T::regs().sr().modify(|reg| {
220 reg.set_eoc(false);
221 });
222
223 T::regs().cr2().modify(|reg| {
225 reg.set_swstart(true);
226 reg.set_exttrig(true);
227 });
228
229 while T::regs().sr().read().strt() == false {
230 }
232 while T::regs().sr().read().eoc() == false {
233 }
235
236 T::regs().dr().read().0 as u16
237 }
238
239 async fn convert_async(&mut self) -> u16 {
240 T::regs().sr().modify(|reg| {
241 reg.set_eoc(false);
242 });
243
244 T::regs().cr1().modify(|reg| reg.set_eocie(true));
245
246 T::regs().cr2().modify(|reg| {
247 reg.set_swstart(true);
248 reg.set_exttrig(true);
249 });
250
251 poll_fn(|cx| {
252 T::state().waker.register(cx.waker());
253
254 if T::regs().sr().read().eoc() {
255 Poll::Ready(())
256 } else {
257 Poll::Pending
258 }
259 })
260 .await;
261
262 T::regs().dr().read().0 as u16
263 }
264
265 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
266 channel.setup();
267
268 let channel = channel.channel();
270
271 T::regs().sqr3().write(|reg| reg.set_sq(0, channel));
273
274 Self::set_channel_sample_time(channel, self.sample_time);
276
277 self.convert()
278 }
279
280 pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 {
281 channel.setup();
282
283 let channel = channel.channel();
284
285 T::regs().sqr1().modify(|reg| reg.set_l(0));
287 T::regs().sqr3().write(|reg| reg.set_sq(0, channel));
288
289 Self::set_channel_sample_time(channel, self.sample_time);
291
292 self.convert_async().await
293 }
294
295 fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
296 let sample_time = sample_time.into();
297 match ch {
298 ..=9 => T::regs()
299 .smpr3()
300 .modify(|reg| reg.set_smp(ch as _, sample_time)),
301 ..=19 => T::regs()
302 .smpr2()
303 .modify(|reg| reg.set_smp((ch - 10) as _, sample_time)),
304 _ => T::regs()
305 .smpr3()
306 .modify(|reg| reg.set_smp((ch - 20) as _, sample_time)),
307 }
308 }
309
310 pub fn calibrate() {
312 T::regs().cr2().modify(|reg| {
313 reg.set_adon(false);
314 });
315
316 while T::regs().cr2().read().adon() {}
317
318 let adc_clock_mhz = 72_u32; let cpu_clock_mhz = unsafe { rcc::get_freqs() }.sys.to_hertz().unwrap().0 / 1_000_000;
323 #[cfg(py32f072)]
324 let precalibration_cycles = 2_u32;
325
326 let delay_us = (precalibration_cycles * adc_clock_mhz) / cpu_clock_mhz;
327 blocking_delay_us(delay_us);
328
329 if T::regs().cr2().read().adon() {
331 panic!();
332 }
333
334 T::regs().cr2().modify(|reg| {
336 reg.set_rstcal(true);
337 });
338
339 while T::regs().cr2().read().rstcal() {}
341
342 T::regs().cr2().modify(|reg| {
344 reg.set_cal(true);
345 });
346
347 while T::regs().cr2().read().cal() {}
349 }
350}
351
352impl<'d, T: Instance> Drop for Adc<'d, T> {
353 fn drop(&mut self) {
354 T::regs().cr2().modify(|reg| {
355 reg.set_adon(false);
356 });
357
358 rcc::disable::<T>();
359 }
360}