aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-12-08 19:30:50 +0000
committerGitHub <[email protected]>2023-12-08 19:30:50 +0000
commita9ec623622de294478506630c02bb003a9e15734 (patch)
tree100cf3c9b11b0d181d6866074cc36e42568bca11
parentc94a9b8d75ef938aaeb3df18c1eaeb996d655ba0 (diff)
parentfe218ed978a76014b45410e188f974e20adba1a0 (diff)
Merge pull request #2246 from CaptainMaso/adc_f3_v1_1
stm32: add ADC f3_v1_1
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/build.rs4
-rw-r--r--embassy-stm32/src/adc/f1.rs2
-rw-r--r--embassy-stm32/src/adc/f3_v1_1.rs413
-rw-r--r--embassy-stm32/src/adc/mod.rs21
-rw-r--r--embassy-stm32/src/adc/resolution.rs10
-rw-r--r--embassy-stm32/src/adc/sample_time.rs25
-rw-r--r--embassy-stm32/src/can/mod.rs2
-rw-r--r--embassy-stm32/src/rcc/g4.rs2
-rw-r--r--embassy-stm32/src/rcc/mod.rs4
-rw-r--r--tests/stm32/Cargo.toml17
-rw-r--r--tests/stm32/src/bin/dac.rs5
-rw-r--r--tests/stm32/src/bin/dac_l1.rs86
-rw-r--r--tests/stm32/src/common.rs9
14 files changed, 572 insertions, 32 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index a8790ce63..979d15c0c 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -58,7 +58,7 @@ rand_core = "0.6.3"
58sdio-host = "0.5.0" 58sdio-host = "0.5.0"
59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } 59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
60critical-section = "1.1" 60critical-section = "1.1"
61stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7117ad49c06fa00c388130a34977e029910083bd" } 61stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-019a5da1c47c092c199bc39a7f84fb444f2adcdf" }
62vcell = "0.1.3" 62vcell = "0.1.3"
63bxcan = "0.7.0" 63bxcan = "0.7.0"
64nb = "1.0.0" 64nb = "1.0.0"
@@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] }
76[build-dependencies] 76[build-dependencies]
77proc-macro2 = "1.0.36" 77proc-macro2 = "1.0.36"
78quote = "1.0.15" 78quote = "1.0.15"
79stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-7117ad49c06fa00c388130a34977e029910083bd", default-features = false, features = ["metadata"]} 79stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-019a5da1c47c092c199bc39a7f84fb444f2adcdf", default-features = false, features = ["metadata"]}
80 80
81 81
82[features] 82[features]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 7bfd290d2..0eef43ac4 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -930,6 +930,10 @@ fn main() {
930 } else if pin.signal.starts_with("INN") { 930 } else if pin.signal.starts_with("INN") {
931 // TODO handle in the future when embassy supports differential measurements 931 // TODO handle in the future when embassy supports differential measurements
932 None 932 None
933 } else if pin.signal.starts_with("IN") && pin.signal.ends_with("b") {
934 // we number STM32L1 ADC bank 1 as 0..=31, bank 2 as 32..=63
935 let signal = pin.signal.strip_prefix("IN").unwrap().strip_suffix("b").unwrap();
936 Some(32u8 + signal.parse::<u8>().unwrap())
933 } else if pin.signal.starts_with("IN") { 937 } else if pin.signal.starts_with("IN") {
934 Some(pin.signal.strip_prefix("IN").unwrap().parse().unwrap()) 938 Some(pin.signal.strip_prefix("IN").unwrap().parse().unwrap())
935 } else { 939 } else {
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index ad0f13826..fb27bb87b 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -148,7 +148,7 @@ impl<'d, T: Instance> Adc<'d, T> {
148 reg.set_cont(false); 148 reg.set_cont(false);
149 reg.set_exttrig(true); 149 reg.set_exttrig(true);
150 reg.set_swstart(false); 150 reg.set_swstart(false);
151 reg.set_extsel(crate::pac::adc::vals::Extsel::SWSTART); 151 reg.set_extsel(7); // SWSTART
152 }); 152 });
153 153
154 // Configure the channel to sample 154 // Configure the channel to sample
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..6915a8f1c
--- /dev/null
+++ b/embassy-stm32/src/adc/f3_v1_1.rs
@@ -0,0 +1,413 @@
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 match T::regs().cr1().read().res() {
179 crate::pac::adc::vals::Res::TWELVEBIT => Resolution::TwelveBit,
180 crate::pac::adc::vals::Res::TENBIT => Resolution::TenBit,
181 crate::pac::adc::vals::Res::EIGHTBIT => Resolution::EightBit,
182 crate::pac::adc::vals::Res::SIXBIT => Resolution::SixBit,
183 }
184 }
185
186 pub fn enable_vref(&self) -> Vref<T> {
187 update_vref::<T>(1);
188
189 Vref(core::marker::PhantomData)
190 }
191
192 pub fn enable_temperature(&self) -> Temperature<T> {
193 T::regs().ccr().modify(|w| w.set_tsvrefe(true));
194
195 Temperature::<T>(core::marker::PhantomData)
196 }
197
198 /// Perform a single conversion.
199 async fn convert(&mut self) -> u16 {
200 let was_on = Self::is_on();
201
202 if !was_on {
203 self.start_adc().await;
204 }
205
206 self.wait_sample_ready().await;
207
208 T::regs().sr().write(|_| {});
209 T::regs().cr1().modify(|w| {
210 w.set_eocie(true);
211 w.set_scan(false);
212 });
213 T::regs().cr2().modify(|w| {
214 w.set_swstart(true);
215 w.set_cont(false);
216 }); // swstart cleared by HW
217
218 let res = poll_fn(|cx| {
219 T::state().waker.register(cx.waker());
220
221 if T::regs().sr().read().eoc() {
222 let res = T::regs().dr().read().rdata();
223 Poll::Ready(res)
224 } else {
225 Poll::Pending
226 }
227 })
228 .await;
229
230 if !was_on {
231 self.stop_adc().await;
232 }
233
234 res
235 }
236
237 #[inline(always)]
238 fn is_on() -> bool {
239 T::regs().sr().read().adons() || T::regs().cr2().read().adon()
240 }
241
242 pub async fn start_adc(&self) {
243 //defmt::trace!("Turn ADC on");
244 T::regs().cr2().modify(|w| w.set_adon(true));
245 //defmt::trace!("Waiting for ADC to turn on");
246
247 let mut t = Instant::now();
248
249 while !T::regs().sr().read().adons() {
250 yield_now().await;
251 if t.elapsed() > embassy_time::Duration::from_millis(1000) {
252 t = Instant::now();
253 //defmt::trace!("ADC still not on");
254 }
255 }
256
257 //defmt::trace!("ADC on");
258 }
259
260 pub async fn stop_adc(&self) {
261 if T::regs().cr2().read().adon() {
262 //defmt::trace!("ADC should be on, wait for it to start");
263 while !T::regs().csr().read().adons1() {
264 yield_now().await;
265 }
266 }
267
268 //defmt::trace!("Turn ADC off");
269
270 T::regs().cr2().modify(|w| w.set_adon(false));
271
272 //defmt::trace!("Waiting for ADC to turn off");
273
274 while T::regs().csr().read().adons1() {
275 yield_now().await;
276 }
277 }
278
279 pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
280 self.set_sample_sequence(&[pin.channel()]).await;
281 self.convert().await
282 }
283
284 async fn wait_sample_ready(&self) {
285 //trace!("Waiting for sample channel to be ready");
286 while T::regs().sr().read().rcnr() {
287 yield_now().await;
288 }
289 }
290
291 pub async fn set_sample_time(&mut self, pin: &mut impl AdcPin<T>, sample_time: SampleTime) {
292 if Self::get_channel_sample_time(pin.channel()) != sample_time {
293 self.stop_adc().await;
294 unsafe {
295 Self::set_channel_sample_time(pin.channel(), sample_time);
296 }
297 self.start_adc().await;
298 }
299 }
300
301 pub fn get_sample_time(&self, pin: &impl AdcPin<T>) -> SampleTime {
302 Self::get_channel_sample_time(pin.channel())
303 }
304
305 /// Sets the channel sample time
306 ///
307 /// ## SAFETY:
308 /// - ADON == 0 i.e ADC must not be enabled when this is called.
309 unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
310 let sample_time = sample_time.into();
311
312 match ch {
313 0..=9 => T::regs().smpr3().modify(|reg| reg.set_smp(ch as _, sample_time)),
314 10..=19 => T::regs()
315 .smpr2()
316 .modify(|reg| reg.set_smp(ch as usize - 10, sample_time)),
317 20..=29 => T::regs()
318 .smpr1()
319 .modify(|reg| reg.set_smp(ch as usize - 20, sample_time)),
320 30..=31 => T::regs()
321 .smpr0()
322 .modify(|reg| reg.set_smp(ch as usize - 30, sample_time)),
323 _ => panic!("Invalid channel to sample"),
324 }
325 }
326
327 fn get_channel_sample_time(ch: u8) -> SampleTime {
328 match ch {
329 0..=9 => T::regs().smpr3().read().smp(ch as _),
330 10..=19 => T::regs().smpr2().read().smp(ch as usize - 10),
331 20..=29 => T::regs().smpr1().read().smp(ch as usize - 20),
332 30..=31 => T::regs().smpr0().read().smp(ch as usize - 30),
333 _ => panic!("Invalid channel to sample"),
334 }
335 .into()
336 }
337
338 /// Sets the sequence to sample the ADC. Must be less than 28 elements.
339 async fn set_sample_sequence(&self, sequence: &[u8]) {
340 assert!(sequence.len() <= 28);
341 let mut iter = sequence.iter();
342 T::regs().sqr1().modify(|w| w.set_l((sequence.len() - 1) as _));
343 for (idx, ch) in iter.by_ref().take(6).enumerate() {
344 T::regs().sqr5().modify(|w| w.set_sq(idx, *ch));
345 }
346 for (idx, ch) in iter.by_ref().take(6).enumerate() {
347 T::regs().sqr4().modify(|w| w.set_sq(idx, *ch));
348 }
349 for (idx, ch) in iter.by_ref().take(6).enumerate() {
350 T::regs().sqr3().modify(|w| w.set_sq(idx, *ch));
351 }
352 for (idx, ch) in iter.by_ref().take(6).enumerate() {
353 T::regs().sqr2().modify(|w| w.set_sq(idx, *ch));
354 }
355 for (idx, ch) in iter.by_ref().take(4).enumerate() {
356 T::regs().sqr1().modify(|w| w.set_sq(idx, *ch));
357 }
358 }
359
360 fn get_res_clks(res: Resolution) -> u32 {
361 match res {
362 Resolution::TwelveBit => 12,
363 Resolution::TenBit => 11,
364 Resolution::EightBit => 9,
365 Resolution::SixBit => 7,
366 }
367 }
368
369 fn get_sample_time_clks(sample_time: SampleTime) -> u32 {
370 match sample_time {
371 SampleTime::Cycles4 => 4,
372 SampleTime::Cycles9 => 9,
373 SampleTime::Cycles16 => 16,
374 SampleTime::Cycles24 => 24,
375 SampleTime::Cycles48 => 48,
376 SampleTime::Cycles96 => 96,
377 SampleTime::Cycles192 => 192,
378 SampleTime::Cycles384 => 384,
379 }
380 }
381
382 pub fn sample_time_for_us(&self, us: u32) -> SampleTime {
383 let res_clks = Self::get_res_clks(self.resolution());
384 let us_clks = us * Self::freq().0 / 1_000_000;
385 let clks = us_clks.saturating_sub(res_clks);
386 match clks {
387 0..=4 => SampleTime::Cycles4,
388 5..=9 => SampleTime::Cycles9,
389 10..=16 => SampleTime::Cycles16,
390 17..=24 => SampleTime::Cycles24,
391 25..=48 => SampleTime::Cycles48,
392 49..=96 => SampleTime::Cycles96,
393 97..=192 => SampleTime::Cycles192,
394 193.. => SampleTime::Cycles384,
395 }
396 }
397
398 pub fn us_for_cfg(&self, res: Resolution, sample_time: SampleTime) -> u32 {
399 let res_clks = Self::get_res_clks(res);
400 let sample_clks = Self::get_sample_time_clks(sample_time);
401 (res_clks + sample_clks) * 1_000_000 / Self::freq().0
402 }
403}
404
405impl<'d, T: Instance> Drop for Adc<'d, T> {
406 fn drop(&mut self) {
407 while !T::regs().sr().read().adons() {}
408
409 T::regs().cr2().modify(|w| w.set_adon(false));
410
411 T::disable();
412 }
413}
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..383980b5a 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,7 +42,7 @@ 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 }
@@ -56,7 +58,7 @@ impl Resolution {
56 Resolution::TwelveBit => (1 << 12) - 1, 58 Resolution::TwelveBit => (1 << 12) - 1,
57 Resolution::TenBit => (1 << 10) - 1, 59 Resolution::TenBit => (1 << 10) - 1,
58 Resolution::EightBit => (1 << 8) - 1, 60 Resolution::EightBit => (1 << 8) - 1,
59 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3))] 61 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3, adc_f3_v1_1))]
60 Resolution::SixBit => (1 << 6) - 1, 62 Resolution::SixBit => (1 << 6) - 1,
61 } 63 }
62 } 64 }
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);
diff --git a/embassy-stm32/src/can/mod.rs b/embassy-stm32/src/can/mod.rs
index 4ff5aa0de..425f9ac2e 100644
--- a/embassy-stm32/src/can/mod.rs
+++ b/embassy-stm32/src/can/mod.rs
@@ -1,6 +1,6 @@
1#![macro_use] 1#![macro_use]
2 2
3#[cfg_attr(can_bxcan, path = "bxcan.rs")] 3#[cfg_attr(can_bxcan, path = "bxcan.rs")]
4#[cfg_attr(can_fdcan, path = "fdcan.rs")] 4#[cfg_attr(any(can_fdcan_v1, can_fdcan_h7), path = "fdcan.rs")]
5mod _version; 5mod _version;
6pub use _version::*; 6pub use _version::*;
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs
index 48b27255d..7af05b485 100644
--- a/embassy-stm32/src/rcc/g4.rs
+++ b/embassy-stm32/src/rcc/g4.rs
@@ -315,6 +315,8 @@ pub(crate) unsafe fn init(config: Config) {
315 adc: adc12_ck, 315 adc: adc12_ck,
316 adc34: adc345_ck, 316 adc34: adc345_ck,
317 pll1_p: None, 317 pll1_p: None,
318 pll1_q: None, // TODO
319 hse: None, // TODO
318 rtc, 320 rtc,
319 }); 321 });
320} 322}
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 2e144dc77..40a5a619d 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -119,7 +119,7 @@ pub struct Clocks {
119 119
120 #[cfg(any(stm32g4, rcc_l4))] 120 #[cfg(any(stm32g4, rcc_l4))]
121 pub pll1_p: Option<Hertz>, 121 pub pll1_p: Option<Hertz>,
122 #[cfg(any(stm32h5, stm32h7, rcc_f2, rcc_f4, rcc_f410, rcc_f7, rcc_l4))] 122 #[cfg(any(stm32h5, stm32h7, stm32f2, stm32f4, stm32f7, rcc_l4, stm32g4))]
123 pub pll1_q: Option<Hertz>, 123 pub pll1_q: Option<Hertz>,
124 #[cfg(any(stm32h5, stm32h7))] 124 #[cfg(any(stm32h5, stm32h7))]
125 pub pll2_p: Option<Hertz>, 125 pub pll2_p: Option<Hertz>,
@@ -167,7 +167,7 @@ pub struct Clocks {
167 167
168 #[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0))] 168 #[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0))]
169 pub lse: Option<Hertz>, 169 pub lse: Option<Hertz>,
170 #[cfg(any(stm32h5, stm32h7))] 170 #[cfg(any(stm32h5, stm32h7, stm32g4))]
171 pub hse: Option<Hertz>, 171 pub hse: Option<Hertz>,
172 172
173 #[cfg(stm32h5)] 173 #[cfg(stm32h5)]
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index c37d89a40..4f53e84f0 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -10,14 +10,14 @@ stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"]
10stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] 10stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"]
11stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth", "rng"] 11stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth", "rng"]
12stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] 12stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"]
13stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin", "rng"] 13stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"]
14stm32f446re = ["embassy-stm32/stm32f446re", "chrono", "stop", "can", "not-gpdma", "dac-adc-pin", "sdmmc"] 14stm32f446re = ["embassy-stm32/stm32f446re", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"]
15stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] 15stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"]
16stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac-adc-pin"] 16stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac"]
17stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng"] 17stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng"]
18stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng"] 18stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng"]
19stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng"] 19stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng"]
20stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin", "rng"] 20stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac", "rng"]
21stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng"] 21stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng"]
22stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"] 22stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"]
23stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] 23stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"]
@@ -41,7 +41,7 @@ ble = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/ble"]
41mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] 41mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"]
42embassy-stm32-wpan = [] 42embassy-stm32-wpan = []
43not-gpdma = [] 43not-gpdma = []
44dac-adc-pin = [] 44dac = []
45 45
46cm0 = ["portable-atomic/unsafe-assume-single-core"] 46cm0 = ["portable-atomic/unsafe-assume-single-core"]
47 47
@@ -84,7 +84,12 @@ required-features = [ "can",]
84[[bin]] 84[[bin]]
85name = "dac" 85name = "dac"
86path = "src/bin/dac.rs" 86path = "src/bin/dac.rs"
87required-features = [ "dac-adc-pin",] 87required-features = [ "dac",]
88
89[[bin]]
90name = "dac_l1"
91path = "src/bin/dac_l1.rs"
92required-features = [ "stm32l152re",]
88 93
89[[bin]] 94[[bin]]
90name = "eth" 95name = "eth"
diff --git a/tests/stm32/src/bin/dac.rs b/tests/stm32/src/bin/dac.rs
index cf43106b3..9d64742df 100644
--- a/tests/stm32/src/bin/dac.rs
+++ b/tests/stm32/src/bin/dac.rs
@@ -1,7 +1,7 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4// required-features: dac-adc-pin 4// required-features: dac
5 5
6#[path = "../common.rs"] 6#[path = "../common.rs"]
7mod common; 7mod common;
@@ -22,12 +22,13 @@ async fn main(_spawner: Spawner) {
22 // Initialize the board and obtain a Peripherals instance 22 // Initialize the board and obtain a Peripherals instance
23 let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); 23 let p: embassy_stm32::Peripherals = embassy_stm32::init(config());
24 24
25 let adc = peri!(p, ADC);
25 let dac = peri!(p, DAC); 26 let dac = peri!(p, DAC);
26 let dac_pin = peri!(p, DAC_PIN); 27 let dac_pin = peri!(p, DAC_PIN);
27 let mut adc_pin = unsafe { core::ptr::read(&dac_pin) }; 28 let mut adc_pin = unsafe { core::ptr::read(&dac_pin) };
28 29
29 let mut dac = DacCh1::new(dac, NoDma, dac_pin); 30 let mut dac = DacCh1::new(dac, NoDma, dac_pin);
30 let mut adc = Adc::new(p.ADC1, &mut Delay); 31 let mut adc = Adc::new(adc, &mut Delay);
31 32
32 #[cfg(feature = "stm32h755zi")] 33 #[cfg(feature = "stm32h755zi")]
33 let normalization_factor = 256; 34 let normalization_factor = 256;
diff --git a/tests/stm32/src/bin/dac_l1.rs b/tests/stm32/src/bin/dac_l1.rs
new file mode 100644
index 000000000..f8b00aaef
--- /dev/null
+++ b/tests/stm32/src/bin/dac_l1.rs
@@ -0,0 +1,86 @@
1#![no_std]
2#![no_main]
3
4// required-features: stm32l152re
5
6#[path = "../common.rs"]
7mod common;
8use core::f32::consts::PI;
9
10use common::*;
11use defmt::assert;
12use embassy_executor::Spawner;
13use embassy_stm32::adc::Adc;
14use embassy_stm32::dac::{DacCh1, Value};
15use embassy_stm32::dma::NoDma;
16use embassy_stm32::{bind_interrupts, peripherals};
17use embassy_time::Timer;
18use micromath::F32Ext;
19use {defmt_rtt as _, panic_probe as _};
20
21bind_interrupts!(struct Irqs {
22 ADC1 => embassy_stm32::adc::InterruptHandler<peripherals::ADC>;
23});
24
25#[embassy_executor::main]
26async fn main(_spawner: Spawner) {
27 // Initialize the board and obtain a Peripherals instance
28 let p: embassy_stm32::Peripherals = embassy_stm32::init(config());
29
30 let adc = peri!(p, ADC);
31 let dac = peri!(p, DAC);
32 let dac_pin = peri!(p, DAC_PIN);
33 let mut adc_pin = unsafe { core::ptr::read(&dac_pin) };
34
35 let mut dac = DacCh1::new(dac, NoDma, dac_pin);
36 let mut adc = Adc::new(adc, Irqs);
37
38 #[cfg(feature = "stm32h755zi")]
39 let normalization_factor = 256;
40 #[cfg(any(
41 feature = "stm32f429zi",
42 feature = "stm32f446re",
43 feature = "stm32g071rb",
44 feature = "stm32l152re",
45 ))]
46 let normalization_factor: i32 = 16;
47
48 dac.set(Value::Bit8(0));
49 // Now wait a little to obtain a stable value
50 Timer::after_millis(30).await;
51 let offset = adc.read(&mut adc_pin).await;
52
53 for v in 0..=255 {
54 // First set the DAC output value
55 let dac_output_val = to_sine_wave(v);
56 dac.set(Value::Bit8(dac_output_val));
57
58 // Now wait a little to obtain a stable value
59 Timer::after_millis(30).await;
60
61 // Need to steal the peripherals here because PA4 is obviously in use already
62 let measured = adc.read(&mut unsafe { embassy_stm32::Peripherals::steal() }.PA4).await;
63 // Calibrate and normalize the measurement to get close to the dac_output_val
64 let measured_normalized = ((measured as i32 - offset as i32) / normalization_factor) as i16;
65
66 info!("value / measured: {} / {}", dac_output_val, measured_normalized);
67
68 // The deviations are quite enormous but that does not matter since this is only a quick test
69 assert!((dac_output_val as i16 - measured_normalized).abs() < 15);
70 }
71
72 info!("Test OK");
73 cortex_m::asm::bkpt();
74}
75
76fn to_sine_wave(v: u8) -> u8 {
77 if v >= 128 {
78 // top half
79 let r = PI * ((v - 128) as f32 / 128.0);
80 (r.sin() * 128.0 + 127.0) as u8
81 } else {
82 // bottom half
83 let r = PI + PI * (v as f32 / 128.0);
84 (r.sin() * 128.0 + 127.0) as u8
85 }
86}
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index 155e1d9df..313380b35 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -101,14 +101,14 @@ define_peris!(
101define_peris!( 101define_peris!(
102 UART = USART1, UART_TX = PC4, UART_RX = PC5, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2, 102 UART = USART1, UART_TX = PC4, UART_RX = PC5, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2,
103 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2, 103 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2,
104 DAC = DAC1, DAC_PIN = PA4, 104 ADC = ADC1, DAC = DAC1, DAC_PIN = PA4,
105 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, 105 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
106); 106);
107#[cfg(feature = "stm32f429zi")] 107#[cfg(feature = "stm32f429zi")]
108define_peris!( 108define_peris!(
109 UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1, 109 UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1,
110 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, 110 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2,
111 DAC = DAC, DAC_PIN = PA4, 111 ADC = ADC1, DAC = DAC, DAC_PIN = PA4,
112 CAN = CAN1, CAN_RX = PD0, CAN_TX = PD1, 112 CAN = CAN1, CAN_RX = PD0, CAN_TX = PD1,
113 @irq UART = {USART6 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART6>;}, 113 @irq UART = {USART6 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART6>;},
114); 114);
@@ -116,7 +116,7 @@ define_peris!(
116define_peris!( 116define_peris!(
117 UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA2_CH7, UART_RX_DMA = DMA2_CH5, 117 UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA2_CH7, UART_RX_DMA = DMA2_CH5,
118 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, 118 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2,
119 DAC = DAC, DAC_PIN = PA4, 119 ADC = ADC1, DAC = DAC, DAC_PIN = PA4,
120 CAN = CAN1, CAN_RX = PA11, CAN_TX = PA12, 120 CAN = CAN1, CAN_RX = PA11, CAN_TX = PA12,
121 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, 121 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
122); 122);
@@ -130,7 +130,7 @@ define_peris!(
130define_peris!( 130define_peris!(
131 UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1, 131 UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1,
132 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1, 132 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1,
133 DAC = DAC1, DAC_PIN = PA4, 133 ADC = ADC1, DAC = DAC1, DAC_PIN = PA4,
134 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, 134 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
135); 135);
136#[cfg(feature = "stm32h7a3zi")] 136#[cfg(feature = "stm32h7a3zi")]
@@ -191,6 +191,7 @@ define_peris!(
191define_peris!( 191define_peris!(
192 UART = USART3, UART_TX = PB10, UART_RX = PB11, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3, 192 UART = USART3, UART_TX = PB10, UART_RX = PB11, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3,
193 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, 193 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
194 ADC = ADC, DAC = DAC, DAC_PIN = PA4,
194 @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;}, 195 @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;},
195); 196);
196#[cfg(feature = "stm32l552ze")] 197#[cfg(feature = "stm32l552ze")]