aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Mason <[email protected]>2023-12-04 14:03:31 +1100
committerSam Mason <[email protected]>2023-12-04 14:03:31 +1100
commit35f16c6003b4be69ee18d24440560ce8a700169c (patch)
tree05791f59e137d22334d9f0f7256493785a7058b9
parente5fdd35bd680b30b03372d44f8b29129a8f49f3e (diff)
stm32: add ADC f3_v1_1
-rw-r--r--embassy-stm32/src/adc/f3_v1_1.rs408
-rw-r--r--embassy-stm32/src/adc/mod.rs21
-rw-r--r--embassy-stm32/src/adc/resolution.rs26
-rw-r--r--embassy-stm32/src/adc/sample_time.rs25
4 files changed, 466 insertions, 14 deletions
diff --git a/embassy-stm32/src/adc/f3_v1_1.rs b/embassy-stm32/src/adc/f3_v1_1.rs
new file mode 100644
index 000000000..0bbfd3137
--- /dev/null
+++ b/embassy-stm32/src/adc/f3_v1_1.rs
@@ -0,0 +1,408 @@
1use core::future::poll_fn;
2use core::marker::PhantomData;
3use core::task::Poll;
4
5use embassy_futures::yield_now;
6use embassy_hal_internal::into_ref;
7use embassy_time::Instant;
8
9use super::Resolution;
10use crate::adc::{Adc, AdcPin, Instance, SampleTime};
11use crate::interrupt::typelevel::Interrupt;
12use crate::time::Hertz;
13use crate::{interrupt, Peripheral};
14
15const ADC_FREQ: Hertz = crate::rcc::HSI_FREQ;
16
17pub const VDDA_CALIB_MV: u32 = 3300;
18pub const ADC_MAX: u32 = (1 << 12) - 1;
19pub const VREF_INT: u32 = 1230;
20
21pub enum AdcPowerMode {
22 AlwaysOn,
23 DelayOff,
24 IdleOff,
25 DelayIdleOff,
26}
27
28pub enum Prescaler {
29 Div1,
30 Div2,
31 Div3,
32 Div4,
33}
34
35/// Interrupt handler.
36pub struct InterruptHandler<T: Instance> {
37 _phantom: PhantomData<T>,
38}
39
40impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
41 unsafe fn on_interrupt() {
42 if T::regs().sr().read().eoc() {
43 T::regs().cr1().modify(|w| w.set_eocie(false));
44 } else {
45 return;
46 }
47
48 T::state().waker.wake();
49 }
50}
51
52fn update_vref<T: Instance>(op: i8) {
53 static VREF_STATUS: core::sync::atomic::AtomicU8 = core::sync::atomic::AtomicU8::new(0);
54
55 if op > 0 {
56 if VREF_STATUS.fetch_add(1, core::sync::atomic::Ordering::SeqCst) == 0 {
57 T::regs().ccr().modify(|w| w.set_tsvrefe(true));
58 }
59 } else {
60 if VREF_STATUS.fetch_sub(1, core::sync::atomic::Ordering::SeqCst) == 1 {
61 T::regs().ccr().modify(|w| w.set_tsvrefe(false));
62 }
63 }
64}
65
66pub struct Vref<T: Instance>(core::marker::PhantomData<T>);
67impl<T: Instance> AdcPin<T> for Vref<T> {}
68impl<T: Instance> super::sealed::AdcPin<T> for Vref<T> {
69 fn channel(&self) -> u8 {
70 17
71 }
72}
73
74impl<T: Instance> Vref<T> {
75 /// The value that vref would be if vdda was at 3000mv
76 pub fn calibrated_value(&self) -> u16 {
77 crate::pac::VREFINTCAL.data().read().value()
78 }
79
80 pub async fn calibrate(&mut self, adc: &mut Adc<'_, T>) -> Calibration {
81 let vref_val = adc.read(self).await;
82 Calibration {
83 vref_cal: self.calibrated_value(),
84 vref_val,
85 }
86 }
87}
88
89pub struct Calibration {
90 vref_cal: u16,
91 vref_val: u16,
92}
93
94impl Calibration {
95 /// The millivolts that the calibration value was measured at
96 pub const CALIBRATION_UV: u32 = 3_000_000;
97
98 /// Returns the measured VddA in microvolts (uV)
99 pub fn vdda_uv(&self) -> u32 {
100 (Self::CALIBRATION_UV * self.vref_cal as u32) / self.vref_val as u32
101 }
102
103 /// Returns the measured VddA as an f32
104 pub fn vdda_f32(&self) -> f32 {
105 (Self::CALIBRATION_UV as f32 / 1_000.0) * (self.vref_cal as f32 / self.vref_val as f32)
106 }
107
108 /// Returns a calibrated voltage value as in microvolts (uV)
109 pub fn cal_uv(&self, raw: u16, resolution: super::Resolution) -> u32 {
110 (self.vdda_uv() / resolution.to_max_count()) * raw as u32
111 }
112
113 /// Returns a calibrated voltage value as an f32
114 pub fn cal_f32(&self, raw: u16, resolution: super::Resolution) -> f32 {
115 raw as f32 * self.vdda_f32() / resolution.to_max_count() as f32
116 }
117}
118
119impl<T: Instance> Drop for Vref<T> {
120 fn drop(&mut self) {
121 update_vref::<T>(-1)
122 }
123}
124
125pub struct Temperature<T: Instance>(core::marker::PhantomData<T>);
126impl<T: Instance> AdcPin<T> for Temperature<T> {}
127impl<T: Instance> super::sealed::AdcPin<T> for Temperature<T> {
128 fn channel(&self) -> u8 {
129 16
130 }
131}
132
133impl<T: Instance> Drop for Temperature<T> {
134 fn drop(&mut self) {
135 update_vref::<T>(-1)
136 }
137}
138
139impl<'d, T: Instance> Adc<'d, T> {
140 pub fn new(
141 adc: impl Peripheral<P = T> + 'd,
142 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
143 ) -> Self {
144 into_ref!(adc);
145
146 T::enable_and_reset();
147
148 //let r = T::regs();
149 //r.cr2().write(|w| w.set_align(true));
150
151 T::Interrupt::unpend();
152 unsafe {
153 T::Interrupt::enable();
154 }
155
156 Self { adc }
157 }
158
159 fn freq() -> Hertz {
160 let div = T::regs().ccr().read().adcpre() + 1;
161 ADC_FREQ / div as u32
162 }
163
164 pub async fn set_resolution(&mut self, res: Resolution) {
165 let was_on = Self::is_on();
166 if was_on {
167 self.stop_adc().await;
168 }
169
170 T::regs().cr1().modify(|w| w.set_res(res.into()));
171
172 if was_on {
173 self.start_adc().await;
174 }
175 }
176
177 pub fn resolution(&self) -> Resolution {
178 T::regs().cr1().read().res().into()
179 }
180
181 pub fn enable_vref(&self) -> Vref<T> {
182 update_vref::<T>(1);
183
184 Vref(core::marker::PhantomData)
185 }
186
187 pub fn enable_temperature(&self) -> Temperature<T> {
188 T::regs().ccr().modify(|w| w.set_tsvrefe(true));
189
190 Temperature::<T>(core::marker::PhantomData)
191 }
192
193 /// Perform a single conversion.
194 async fn convert(&mut self) -> u16 {
195 let was_on = Self::is_on();
196
197 if !was_on {
198 self.start_adc().await;
199 }
200
201 self.wait_sample_ready().await;
202
203 T::regs().sr().write(|_| {});
204 T::regs().cr1().modify(|w| {
205 w.set_eocie(true);
206 w.set_scan(false);
207 });
208 T::regs().cr2().modify(|w| {
209 w.set_swstart(true);
210 w.set_cont(false);
211 }); // swstart cleared by HW
212
213 let res = poll_fn(|cx| {
214 T::state().waker.register(cx.waker());
215
216 if T::regs().sr().read().eoc() {
217 let res = T::regs().dr().read().rdata();
218 Poll::Ready(res)
219 } else {
220 Poll::Pending
221 }
222 })
223 .await;
224
225 if !was_on {
226 self.stop_adc().await;
227 }
228
229 res
230 }
231
232 #[inline(always)]
233 fn is_on() -> bool {
234 T::regs().sr().read().adons() || T::regs().cr2().read().adon()
235 }
236
237 pub async fn start_adc(&self) {
238 //defmt::trace!("Turn ADC on");
239 T::regs().cr2().modify(|w| w.set_adon(true));
240 //defmt::trace!("Waiting for ADC to turn on");
241
242 let mut t = Instant::now();
243
244 while !T::regs().sr().read().adons() {
245 yield_now().await;
246 if t.elapsed() > embassy_time::Duration::from_millis(1000) {
247 t = Instant::now();
248 //defmt::trace!("ADC still not on");
249 }
250 }
251
252 //defmt::trace!("ADC on");
253 }
254
255 pub async fn stop_adc(&self) {
256 if T::regs().cr2().read().adon() {
257 //defmt::trace!("ADC should be on, wait for it to start");
258 while !T::regs().csr().read().adons1() {
259 yield_now().await;
260 }
261 }
262
263 //defmt::trace!("Turn ADC off");
264
265 T::regs().cr2().modify(|w| w.set_adon(false));
266
267 //defmt::trace!("Waiting for ADC to turn off");
268
269 while T::regs().csr().read().adons1() {
270 yield_now().await;
271 }
272 }
273
274 pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
275 self.set_sample_sequence(&[pin.channel()]).await;
276 self.convert().await
277 }
278
279 async fn wait_sample_ready(&self) {
280 //trace!("Waiting for sample channel to be ready");
281 while T::regs().sr().read().rcnr() {
282 yield_now().await;
283 }
284 }
285
286 pub async fn set_sample_time(&mut self, pin: &mut impl AdcPin<T>, sample_time: SampleTime) {
287 if Self::get_channel_sample_time(pin.channel()) != sample_time {
288 self.stop_adc().await;
289 unsafe {
290 Self::set_channel_sample_time(pin.channel(), sample_time);
291 }
292 self.start_adc().await;
293 }
294 }
295
296 pub fn get_sample_time(&self, pin: &impl AdcPin<T>) -> SampleTime {
297 Self::get_channel_sample_time(pin.channel())
298 }
299
300 /// Sets the channel sample time
301 ///
302 /// ## SAFETY:
303 /// - ADON == 0 i.e ADC must not be enabled when this is called.
304 unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
305 let sample_time = sample_time.into();
306
307 match ch {
308 0..=9 => T::regs().smpr3().modify(|reg| reg.set_smp(ch as _, sample_time)),
309 10..=19 => T::regs()
310 .smpr2()
311 .modify(|reg| reg.set_smp(ch as usize - 10, sample_time)),
312 20..=29 => T::regs()
313 .smpr1()
314 .modify(|reg| reg.set_smp(ch as usize - 20, sample_time)),
315 30..=31 => T::regs()
316 .smpr0()
317 .modify(|reg| reg.set_smp(ch as usize - 30, sample_time)),
318 _ => panic!("Invalid channel to sample"),
319 }
320 }
321
322 fn get_channel_sample_time(ch: u8) -> SampleTime {
323 match ch {
324 0..=9 => T::regs().smpr3().read().smp(ch as _),
325 10..=19 => T::regs().smpr2().read().smp(ch as usize - 10),
326 20..=29 => T::regs().smpr1().read().smp(ch as usize - 20),
327 30..=31 => T::regs().smpr0().read().smp(ch as usize - 30),
328 _ => panic!("Invalid channel to sample"),
329 }
330 .into()
331 }
332
333 /// Sets the sequence to sample the ADC. Must be less than 28 elements.
334 async fn set_sample_sequence(&self, sequence: &[u8]) {
335 assert!(sequence.len() <= 28);
336 let mut iter = sequence.iter();
337 T::regs().sqr1().modify(|w| w.set_l((sequence.len() - 1) as _));
338 for (idx, ch) in iter.by_ref().take(6).enumerate() {
339 T::regs().sqr5().modify(|w| w.set_sq(idx, *ch));
340 }
341 for (idx, ch) in iter.by_ref().take(6).enumerate() {
342 T::regs().sqr4().modify(|w| w.set_sq(idx, *ch));
343 }
344 for (idx, ch) in iter.by_ref().take(6).enumerate() {
345 T::regs().sqr3().modify(|w| w.set_sq(idx, *ch));
346 }
347 for (idx, ch) in iter.by_ref().take(6).enumerate() {
348 T::regs().sqr2().modify(|w| w.set_sq(idx, *ch));
349 }
350 for (idx, ch) in iter.by_ref().take(4).enumerate() {
351 T::regs().sqr1().modify(|w| w.set_sq(idx, *ch));
352 }
353 }
354
355 fn get_res_clks(res: Resolution) -> u32 {
356 match res {
357 Resolution::TwelveBit => 12,
358 Resolution::TenBit => 11,
359 Resolution::EightBit => 9,
360 Resolution::SixBit => 7,
361 }
362 }
363
364 fn get_sample_time_clks(sample_time: SampleTime) -> u32 {
365 match sample_time {
366 SampleTime::Cycles4 => 4,
367 SampleTime::Cycles9 => 9,
368 SampleTime::Cycles16 => 16,
369 SampleTime::Cycles24 => 24,
370 SampleTime::Cycles48 => 48,
371 SampleTime::Cycles96 => 96,
372 SampleTime::Cycles192 => 192,
373 SampleTime::Cycles384 => 384,
374 }
375 }
376
377 pub fn sample_time_for_us(&self, us: u32) -> SampleTime {
378 let res_clks = Self::get_res_clks(self.resolution());
379 let us_clks = us * Self::freq().0 / 1_000_000;
380 let clks = us_clks.saturating_sub(res_clks);
381 match clks {
382 0..=4 => SampleTime::Cycles4,
383 5..=9 => SampleTime::Cycles9,
384 10..=16 => SampleTime::Cycles16,
385 17..=24 => SampleTime::Cycles24,
386 25..=48 => SampleTime::Cycles48,
387 49..=96 => SampleTime::Cycles96,
388 97..=192 => SampleTime::Cycles192,
389 193.. => SampleTime::Cycles384,
390 }
391 }
392
393 pub fn us_for_cfg(&self, res: Resolution, sample_time: SampleTime) -> u32 {
394 let res_clks = Self::get_res_clks(res);
395 let sample_clks = Self::get_sample_time_clks(sample_time);
396 (res_clks + sample_clks) * 1_000_000 / Self::freq().0
397 }
398}
399
400impl<'d, T: Instance> Drop for Adc<'d, T> {
401 fn drop(&mut self) {
402 while !T::regs().sr().read().adons() {}
403
404 T::regs().cr2().modify(|w| w.set_adon(false));
405
406 T::disable();
407 }
408}
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 3e2980bf4..dbe53c807 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -3,6 +3,7 @@
3#[cfg(not(adc_f3_v2))] 3#[cfg(not(adc_f3_v2))]
4#[cfg_attr(adc_f1, path = "f1.rs")] 4#[cfg_attr(adc_f1, path = "f1.rs")]
5#[cfg_attr(adc_f3, path = "f3.rs")] 5#[cfg_attr(adc_f3, path = "f3.rs")]
6#[cfg_attr(adc_f3_v1_1, path = "f3_v1_1.rs")]
6#[cfg_attr(adc_v1, path = "v1.rs")] 7#[cfg_attr(adc_v1, path = "v1.rs")]
7#[cfg_attr(adc_v2, path = "v2.rs")] 8#[cfg_attr(adc_v2, path = "v2.rs")]
8#[cfg_attr(any(adc_v3, adc_g0), path = "v3.rs")] 9#[cfg_attr(any(adc_v3, adc_g0), path = "v3.rs")]
@@ -26,20 +27,20 @@ use crate::peripherals;
26pub struct Adc<'d, T: Instance> { 27pub struct Adc<'d, T: Instance> {
27 #[allow(unused)] 28 #[allow(unused)]
28 adc: crate::PeripheralRef<'d, T>, 29 adc: crate::PeripheralRef<'d, T>,
29 #[cfg(not(adc_f3_v2))] 30 #[cfg(not(any(adc_f3_v2, adc_f3_v1_1)))]
30 sample_time: SampleTime, 31 sample_time: SampleTime,
31} 32}
32 33
33pub(crate) mod sealed { 34pub(crate) mod sealed {
34 #[cfg(any(adc_f1, adc_f3, adc_v1))] 35 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))]
35 use embassy_sync::waitqueue::AtomicWaker; 36 use embassy_sync::waitqueue::AtomicWaker;
36 37
37 #[cfg(any(adc_f1, adc_f3, adc_v1))] 38 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))]
38 pub struct State { 39 pub struct State {
39 pub waker: AtomicWaker, 40 pub waker: AtomicWaker,
40 } 41 }
41 42
42 #[cfg(any(adc_f1, adc_f3, adc_v1))] 43 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))]
43 impl State { 44 impl State {
44 pub const fn new() -> Self { 45 pub const fn new() -> Self {
45 Self { 46 Self {
@@ -54,11 +55,11 @@ pub(crate) mod sealed {
54 55
55 pub trait Instance: InterruptableInstance { 56 pub trait Instance: InterruptableInstance {
56 fn regs() -> crate::pac::adc::Adc; 57 fn regs() -> crate::pac::adc::Adc;
57 #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_g0)))] 58 #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
58 fn common_regs() -> crate::pac::adccommon::AdcCommon; 59 fn common_regs() -> crate::pac::adccommon::AdcCommon;
59 #[cfg(adc_f3)] 60 #[cfg(adc_f3)]
60 fn frequency() -> crate::time::Hertz; 61 fn frequency() -> crate::time::Hertz;
61 #[cfg(any(adc_f1, adc_f3, adc_v1))] 62 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))]
62 fn state() -> &'static State; 63 fn state() -> &'static State;
63 } 64 }
64 65
@@ -74,9 +75,9 @@ pub(crate) mod sealed {
74 } 75 }
75} 76}
76 77
77#[cfg(not(any(adc_f1, adc_v1, adc_v2, adc_v3, adc_v4, adc_f3, adc_g0)))] 78#[cfg(not(any(adc_f1, adc_v1, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0)))]
78pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {} 79pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {}
79#[cfg(any(adc_f1, adc_v1, adc_v2, adc_v3, adc_v4, adc_f3, adc_g0))] 80#[cfg(any(adc_f1, adc_v1, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0))]
80pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {} 81pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {}
81 82
82pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} 83pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {}
@@ -89,7 +90,7 @@ foreach_adc!(
89 crate::pac::$inst 90 crate::pac::$inst
90 } 91 }
91 92
92 #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_g0)))] 93 #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
93 fn common_regs() -> crate::pac::adccommon::AdcCommon { 94 fn common_regs() -> crate::pac::adccommon::AdcCommon {
94 return crate::pac::$common_inst 95 return crate::pac::$common_inst
95 } 96 }
@@ -99,7 +100,7 @@ foreach_adc!(
99 unsafe { crate::rcc::get_freqs() }.$clock.unwrap() 100 unsafe { crate::rcc::get_freqs() }.$clock.unwrap()
100 } 101 }
101 102
102 #[cfg(any(adc_f1, adc_f3, adc_v1))] 103 #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))]
103 fn state() -> &'static sealed::State { 104 fn state() -> &'static sealed::State {
104 static STATE: sealed::State = sealed::State::new(); 105 static STATE: sealed::State = sealed::State::new();
105 &STATE 106 &STATE
diff --git a/embassy-stm32/src/adc/resolution.rs b/embassy-stm32/src/adc/resolution.rs
index 5668137b5..b1597a821 100644
--- a/embassy-stm32/src/adc/resolution.rs
+++ b/embassy-stm32/src/adc/resolution.rs
@@ -1,5 +1,6 @@
1#[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3))] 1#[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3, adc_f3_v1_1))]
2#[derive(Clone, Copy, Debug, Eq, PartialEq)] 2#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3pub enum Resolution { 4pub enum Resolution {
4 TwelveBit, 5 TwelveBit,
5 TenBit, 6 TenBit,
@@ -9,6 +10,7 @@ pub enum Resolution {
9 10
10#[cfg(adc_v4)] 11#[cfg(adc_v4)]
11#[derive(Clone, Copy, Debug, Eq, PartialEq)] 12#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13#[cfg_attr(feature = "defmt", derive(defmt::Format))]
12pub enum Resolution { 14pub enum Resolution {
13 SixteenBit, 15 SixteenBit,
14 FourteenBit, 16 FourteenBit,
@@ -19,7 +21,7 @@ pub enum Resolution {
19 21
20impl Default for Resolution { 22impl Default for Resolution {
21 fn default() -> Self { 23 fn default() -> Self {
22 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3))] 24 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3, adc_f3_v1_1))]
23 { 25 {
24 Self::TwelveBit 26 Self::TwelveBit
25 } 27 }
@@ -40,12 +42,28 @@ impl From<Resolution> for crate::pac::adc::vals::Res {
40 Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT, 42 Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT,
41 Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT, 43 Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT,
42 Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT, 44 Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT,
43 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3))] 45 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3, adc_f3_v1_1))]
44 Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT, 46 Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT,
45 } 47 }
46 } 48 }
47} 49}
48 50
51impl From<crate::pac::adc::vals::Res> for Resolution {
52 fn from(res: crate::pac::adc::vals::Res) -> Resolution {
53 match res {
54 #[cfg(adc_v4)]
55 crate::pac::adc::vals::Res::SIXTEENBIT => Resolution::SixteenBit,
56 #[cfg(adc_v4)]
57 crate::pac::adc::vals::Res::FOURTEENBITV => Resolution::FourteenBit,
58 crate::pac::adc::vals::Res::TWELVEBIT => Resolution::TwelveBit,
59 crate::pac::adc::vals::Res::TENBIT => Resolution::TenBit,
60 crate::pac::adc::vals::Res::EIGHTBIT => Resolution::EightBit,
61 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3, adc_f3_v1_1, adc_f3_v3))]
62 crate::pac::adc::vals::Res::SIXBIT => Resolution::SixBit,
63 }
64 }
65}
66
49impl Resolution { 67impl Resolution {
50 pub fn to_max_count(&self) -> u32 { 68 pub fn to_max_count(&self) -> u32 {
51 match self { 69 match self {
@@ -56,7 +74,7 @@ impl Resolution {
56 Resolution::TwelveBit => (1 << 12) - 1, 74 Resolution::TwelveBit => (1 << 12) - 1,
57 Resolution::TenBit => (1 << 10) - 1, 75 Resolution::TenBit => (1 << 10) - 1,
58 Resolution::EightBit => (1 << 8) - 1, 76 Resolution::EightBit => (1 << 8) - 1,
59 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3))] 77 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3, adc_f3_v1_1))]
60 Resolution::SixBit => (1 << 6) - 1, 78 Resolution::SixBit => (1 << 6) - 1,
61 } 79 }
62 } 80 }
diff --git a/embassy-stm32/src/adc/sample_time.rs b/embassy-stm32/src/adc/sample_time.rs
index 6a6619299..5a06f1a5a 100644
--- a/embassy-stm32/src/adc/sample_time.rs
+++ b/embassy-stm32/src/adc/sample_time.rs
@@ -3,6 +3,7 @@ macro_rules! impl_sample_time {
3 ($default_doc:expr, $default:ident, ($(($doc:expr, $variant:ident, $pac_variant:ident)),*)) => { 3 ($default_doc:expr, $default:ident, ($(($doc:expr, $variant:ident, $pac_variant:ident)),*)) => {
4 #[doc = concat!("ADC sample time\n\nThe default setting is ", $default_doc, " ADC clock cycles.")] 4 #[doc = concat!("ADC sample time\n\nThe default setting is ", $default_doc, " ADC clock cycles.")]
5 #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] 5 #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
6 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
6 pub enum SampleTime { 7 pub enum SampleTime {
7 $( 8 $(
8 #[doc = concat!($doc, " ADC clock cycles.")] 9 #[doc = concat!($doc, " ADC clock cycles.")]
@@ -18,6 +19,14 @@ macro_rules! impl_sample_time {
18 } 19 }
19 } 20 }
20 21
22 impl From<crate::pac::adc::vals::SampleTime> for SampleTime {
23 fn from(sample_time: crate::pac::adc::vals::SampleTime) -> SampleTime {
24 match sample_time {
25 $(crate::pac::adc::vals::SampleTime::$pac_variant => SampleTime::$variant),*
26 }
27 }
28 }
29
21 impl Default for SampleTime { 30 impl Default for SampleTime {
22 fn default() -> Self { 31 fn default() -> Self {
23 Self::$default 32 Self::$default
@@ -121,3 +130,19 @@ impl_sample_time!(
121 ("601.5", Cycles601_5, CYCLES601_5) 130 ("601.5", Cycles601_5, CYCLES601_5)
122 ) 131 )
123); 132);
133
134#[cfg(any(adc_f3_v1_1))]
135impl_sample_time!(
136 "4",
137 Cycles4,
138 (
139 ("4", Cycles4, CYCLES4),
140 ("9", Cycles9, CYCLES9),
141 ("16", Cycles16, CYCLES16),
142 ("24", Cycles24, CYCLES24),
143 ("48", Cycles48, CYCLES48),
144 ("96", Cycles96, CYCLES96),
145 ("192", Cycles192, CYCLES192),
146 ("384", Cycles384, CYCLES384)
147 )
148);