aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/build.rs4
-rw-r--r--embassy-stm32/src/adc/adc4.rs (renamed from embassy-stm32/src/adc/u5_adc4.rs)100
-rw-r--r--embassy-stm32/src/adc/mod.rs66
-rw-r--r--embassy-stm32/src/rcc/wba.rs1
-rw-r--r--examples/stm32wba/src/bin/adc.rs49
6 files changed, 192 insertions, 32 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 552113a79..d54f8dbae 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -81,7 +81,7 @@ futures-util = { version = "0.3.30", default-features = false }
81sdio-host = "0.9.0" 81sdio-host = "0.9.0"
82critical-section = "1.1" 82critical-section = "1.1"
83#stm32-metapac = { version = "16" } 83#stm32-metapac = { version = "16" }
84stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-0069be7389d0378d826003304d72a13008f3ebce" } 84stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-019a3ce0ea3b5bd832ec2ad53465a0d80b0f4e0a" }
85 85
86vcell = "0.1.3" 86vcell = "0.1.3"
87nb = "1.0.0" 87nb = "1.0.0"
@@ -110,7 +110,7 @@ proc-macro2 = "1.0.36"
110quote = "1.0.15" 110quote = "1.0.15"
111 111
112#stm32-metapac = { version = "16", default-features = false, features = ["metadata"]} 112#stm32-metapac = { version = "16", default-features = false, features = ["metadata"]}
113stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-0069be7389d0378d826003304d72a13008f3ebce", default-features = false, features = ["metadata"] } 113stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-019a3ce0ea3b5bd832ec2ad53465a0d80b0f4e0a", default-features = false, features = ["metadata"] }
114 114
115[features] 115[features]
116default = ["rt"] 116default = ["rt"]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 13fc23e54..753f241c7 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -1490,6 +1490,10 @@ fn main() {
1490 signals.insert(("adc", "ADC4"), quote!(crate::adc::RxDma)); 1490 signals.insert(("adc", "ADC4"), quote!(crate::adc::RxDma));
1491 } 1491 }
1492 1492
1493 if chip_name.starts_with("stm32wba") {
1494 signals.insert(("adc", "ADC4"), quote!(crate::adc::RxDma4));
1495 }
1496
1493 if chip_name.starts_with("stm32g4") { 1497 if chip_name.starts_with("stm32g4") {
1494 let line_number = chip_name.chars().skip(8).next().unwrap(); 1498 let line_number = chip_name.chars().skip(8).next().unwrap();
1495 if line_number == '3' || line_number == '4' { 1499 if line_number == '3' || line_number == '4' {
diff --git a/embassy-stm32/src/adc/u5_adc4.rs b/embassy-stm32/src/adc/adc4.rs
index 1dd664366..98483489f 100644
--- a/embassy-stm32/src/adc/u5_adc4.rs
+++ b/embassy-stm32/src/adc/adc4.rs
@@ -1,10 +1,19 @@
1#[cfg(stm32u5)]
2use pac::adc::vals::{Adc4Dmacfg as Dmacfg, Adc4Exten as Exten, Adc4OversamplingRatio as OversamplingRatio};
1#[allow(unused)] 3#[allow(unused)]
2use pac::adc::vals::{Adc4Dmacfg, Adc4Exten, Adc4OversamplingRatio}; 4#[cfg(stm32wba)]
5use pac::adc::vals::{Chselrmod, Cont, Dmacfg, Exten, OversamplingRatio, Ovss, Smpsel};
3 6
4use super::{blocking_delay_us, AdcChannel, AnyAdcChannel, RxDma4, SealedAdcChannel}; 7use super::{blocking_delay_us, AdcChannel, AnyAdcChannel, RxDma4, SealedAdcChannel};
5use crate::dma::Transfer; 8use crate::dma::Transfer;
6pub use crate::pac::adc::regs::Adc4Chselrmod0; 9#[cfg(stm32u5)]
10pub use crate::pac::adc::regs::Adc4Chselrmod0 as Chselr;
11#[cfg(stm32wba)]
12pub use crate::pac::adc::regs::Chselr;
13#[cfg(stm32u5)]
7pub use crate::pac::adc::vals::{Adc4Presc as Presc, Adc4Res as Resolution, Adc4SampleTime as SampleTime}; 14pub use crate::pac::adc::vals::{Adc4Presc as Presc, Adc4Res as Resolution, Adc4SampleTime as SampleTime};
15#[cfg(stm32wba)]
16pub use crate::pac::adc::vals::{Presc, Res as Resolution, SampleTime};
8use crate::time::Hertz; 17use crate::time::Hertz;
9use crate::{pac, rcc, Peri}; 18use crate::{pac, rcc, Peri};
10 19
@@ -242,17 +251,28 @@ impl<'d, T: Instance> Adc4<'d, T> {
242 fn configure(&mut self) { 251 fn configure(&mut self) {
243 // single conversion mode, software trigger 252 // single conversion mode, software trigger
244 T::regs().cfgr1().modify(|w| { 253 T::regs().cfgr1().modify(|w| {
254 #[cfg(stm32u5)]
245 w.set_cont(false); 255 w.set_cont(false);
256 #[cfg(stm32wba)]
257 w.set_cont(Cont::SINGLE);
246 w.set_discen(false); 258 w.set_discen(false);
247 w.set_exten(Adc4Exten::DISABLED); 259 w.set_exten(Exten::DISABLED);
260 #[cfg(stm32u5)]
248 w.set_chselrmod(false); 261 w.set_chselrmod(false);
262 #[cfg(stm32wba)]
263 w.set_chselrmod(Chselrmod::ENABLE_INPUT);
249 }); 264 });
250 265
251 // only use one channel at the moment 266 // only use one channel at the moment
252 T::regs().smpr().modify(|w| { 267 T::regs().smpr().modify(|w| {
268 #[cfg(stm32u5)]
253 for i in 0..24 { 269 for i in 0..24 {
254 w.set_smpsel(i, false); 270 w.set_smpsel(i, false);
255 } 271 }
272 #[cfg(stm32wba)]
273 for i in 0..14 {
274 w.set_smpsel(i, Smpsel::SMP1);
275 }
256 }); 276 });
257 } 277 }
258 278
@@ -275,6 +295,7 @@ impl<'d, T: Instance> Adc4<'d, T> {
275 } 295 }
276 296
277 /// Enable reading the vbat internal channel. 297 /// Enable reading the vbat internal channel.
298 #[cfg(stm32u5)]
278 pub fn enable_vbat(&self) -> Vbat { 299 pub fn enable_vbat(&self) -> Vbat {
279 T::regs().ccr().modify(|w| { 300 T::regs().ccr().modify(|w| {
280 w.set_vbaten(true); 301 w.set_vbaten(true);
@@ -289,6 +310,7 @@ impl<'d, T: Instance> Adc4<'d, T> {
289 } 310 }
290 311
291 /// Enable reading the vbat internal channel. 312 /// Enable reading the vbat internal channel.
313 #[cfg(stm32u5)]
292 pub fn enable_dac_channel(&self, dac: DacChannel) -> Dac { 314 pub fn enable_dac_channel(&self, dac: DacChannel) -> Dac {
293 let mux; 315 let mux;
294 match dac { 316 match dac {
@@ -317,17 +339,38 @@ impl<'d, T: Instance> Adc4<'d, T> {
317 } 339 }
318 340
319 /// Set hardware averaging. 341 /// Set hardware averaging.
342 #[cfg(stm32u5)]
343 pub fn set_averaging(&mut self, averaging: Averaging) {
344 let (enable, samples, right_shift) = match averaging {
345 Averaging::Disabled => (false, OversamplingRatio::OVERSAMPLE2X, 0),
346 Averaging::Samples2 => (true, OversamplingRatio::OVERSAMPLE2X, 1),
347 Averaging::Samples4 => (true, OversamplingRatio::OVERSAMPLE4X, 2),
348 Averaging::Samples8 => (true, OversamplingRatio::OVERSAMPLE8X, 3),
349 Averaging::Samples16 => (true, OversamplingRatio::OVERSAMPLE16X, 4),
350 Averaging::Samples32 => (true, OversamplingRatio::OVERSAMPLE32X, 5),
351 Averaging::Samples64 => (true, OversamplingRatio::OVERSAMPLE64X, 6),
352 Averaging::Samples128 => (true, OversamplingRatio::OVERSAMPLE128X, 7),
353 Averaging::Samples256 => (true, OversamplingRatio::OVERSAMPLE256X, 8),
354 };
355
356 T::regs().cfgr2().modify(|w| {
357 w.set_ovsr(samples);
358 w.set_ovss(right_shift);
359 w.set_ovse(enable)
360 })
361 }
362 #[cfg(stm32wba)]
320 pub fn set_averaging(&mut self, averaging: Averaging) { 363 pub fn set_averaging(&mut self, averaging: Averaging) {
321 let (enable, samples, right_shift) = match averaging { 364 let (enable, samples, right_shift) = match averaging {
322 Averaging::Disabled => (false, Adc4OversamplingRatio::OVERSAMPLE2X, 0), 365 Averaging::Disabled => (false, OversamplingRatio::OVERSAMPLE2X, Ovss::SHIFT0),
323 Averaging::Samples2 => (true, Adc4OversamplingRatio::OVERSAMPLE2X, 1), 366 Averaging::Samples2 => (true, OversamplingRatio::OVERSAMPLE2X, Ovss::SHIFT1),
324 Averaging::Samples4 => (true, Adc4OversamplingRatio::OVERSAMPLE4X, 2), 367 Averaging::Samples4 => (true, OversamplingRatio::OVERSAMPLE4X, Ovss::SHIFT2),
325 Averaging::Samples8 => (true, Adc4OversamplingRatio::OVERSAMPLE8X, 3), 368 Averaging::Samples8 => (true, OversamplingRatio::OVERSAMPLE8X, Ovss::SHIFT3),
326 Averaging::Samples16 => (true, Adc4OversamplingRatio::OVERSAMPLE16X, 4), 369 Averaging::Samples16 => (true, OversamplingRatio::OVERSAMPLE16X, Ovss::SHIFT4),
327 Averaging::Samples32 => (true, Adc4OversamplingRatio::OVERSAMPLE32X, 5), 370 Averaging::Samples32 => (true, OversamplingRatio::OVERSAMPLE32X, Ovss::SHIFT5),
328 Averaging::Samples64 => (true, Adc4OversamplingRatio::OVERSAMPLE64X, 6), 371 Averaging::Samples64 => (true, OversamplingRatio::OVERSAMPLE64X, Ovss::SHIFT6),
329 Averaging::Samples128 => (true, Adc4OversamplingRatio::OVERSAMPLE128X, 7), 372 Averaging::Samples128 => (true, OversamplingRatio::OVERSAMPLE128X, Ovss::SHIFT7),
330 Averaging::Samples256 => (true, Adc4OversamplingRatio::OVERSAMPLE256X, 8), 373 Averaging::Samples256 => (true, OversamplingRatio::OVERSAMPLE256X, Ovss::SHIFT8),
331 }; 374 };
332 375
333 T::regs().cfgr2().modify(|w| { 376 T::regs().cfgr2().modify(|w| {
@@ -342,10 +385,20 @@ impl<'d, T: Instance> Adc4<'d, T> {
342 channel.setup(); 385 channel.setup();
343 386
344 // Select channel 387 // Select channel
345 T::regs().chselrmod0().write_value(Adc4Chselrmod0(0_u32)); 388 #[cfg(stm32wba)]
346 T::regs().chselrmod0().modify(|w| { 389 {
347 w.set_chsel(channel.channel() as usize, true); 390 T::regs().chselr().write_value(Chselr(0_u32));
348 }); 391 T::regs().chselr().modify(|w| {
392 w.set_chsel0(channel.channel() as usize, true);
393 });
394 }
395 #[cfg(stm32u5)]
396 {
397 T::regs().chselrmod0().write_value(Chselr(0_u32));
398 T::regs().chselrmod0().modify(|w| {
399 w.set_chsel(channel.channel() as usize, true);
400 });
401 }
349 402
350 // Reset interrupts 403 // Reset interrupts
351 T::regs().isr().modify(|reg| { 404 T::regs().isr().modify(|reg| {
@@ -415,13 +468,19 @@ impl<'d, T: Instance> Adc4<'d, T> {
415 468
416 T::regs().cfgr1().modify(|reg| { 469 T::regs().cfgr1().modify(|reg| {
417 reg.set_dmaen(true); 470 reg.set_dmaen(true);
418 reg.set_dmacfg(Adc4Dmacfg::ONE_SHOT); 471 reg.set_dmacfg(Dmacfg::ONE_SHOT);
472 #[cfg(stm32u5)]
419 reg.set_chselrmod(false); 473 reg.set_chselrmod(false);
474 #[cfg(stm32wba)]
475 reg.set_chselrmod(Chselrmod::ENABLE_INPUT)
420 }); 476 });
421 477
422 // Verify and activate sequence 478 // Verify and activate sequence
423 let mut prev_channel: i16 = -1; 479 let mut prev_channel: i16 = -1;
424 T::regs().chselrmod0().write_value(Adc4Chselrmod0(0_u32)); 480 #[cfg(stm32wba)]
481 T::regs().chselr().write_value(Chselr(0_u32));
482 #[cfg(stm32u5)]
483 T::regs().chselrmod0().write_value(Chselr(0_u32));
425 for channel in sequence { 484 for channel in sequence {
426 let channel_num = channel.channel; 485 let channel_num = channel.channel;
427 if channel_num as i16 <= prev_channel { 486 if channel_num as i16 <= prev_channel {
@@ -429,6 +488,11 @@ impl<'d, T: Instance> Adc4<'d, T> {
429 }; 488 };
430 prev_channel = channel_num as i16; 489 prev_channel = channel_num as i16;
431 490
491 #[cfg(stm32wba)]
492 T::regs().chselr().modify(|w| {
493 w.set_chsel0(channel.channel as usize, true);
494 });
495 #[cfg(stm32u5)]
432 T::regs().chselrmod0().modify(|w| { 496 T::regs().chselrmod0().modify(|w| {
433 w.set_chsel(channel.channel as usize, true); 497 w.set_chsel(channel.channel as usize, true);
434 }); 498 });
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index f46e87f38..778edc6f6 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -4,7 +4,7 @@
4#![allow(missing_docs)] // TODO 4#![allow(missing_docs)] // TODO
5#![cfg_attr(adc_f3_v2, allow(unused))] 5#![cfg_attr(adc_f3_v2, allow(unused))]
6 6
7#[cfg(not(any(adc_f3_v2)))] 7#[cfg(not(any(adc_f3_v2, adc_wba)))]
8#[cfg_attr(adc_f1, path = "f1.rs")] 8#[cfg_attr(adc_f1, path = "f1.rs")]
9#[cfg_attr(adc_f3, path = "f3.rs")] 9#[cfg_attr(adc_f3, path = "f3.rs")]
10#[cfg_attr(adc_f3_v1_1, path = "f3_v1_1.rs")] 10#[cfg_attr(adc_f3_v1_1, path = "f3_v1_1.rs")]
@@ -20,14 +20,14 @@ mod _version;
20use core::marker::PhantomData; 20use core::marker::PhantomData;
21 21
22#[allow(unused)] 22#[allow(unused)]
23#[cfg(not(any(adc_f3_v2)))] 23#[cfg(not(any(adc_f3_v2, adc_wba)))]
24pub use _version::*; 24pub use _version::*;
25use embassy_hal_internal::{impl_peripheral, PeripheralType}; 25use embassy_hal_internal::{impl_peripheral, PeripheralType};
26#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] 26#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
27use embassy_sync::waitqueue::AtomicWaker; 27use embassy_sync::waitqueue::AtomicWaker;
28 28
29#[cfg(adc_u5)] 29#[cfg(any(adc_u5, adc_wba))]
30#[path = "u5_adc4.rs"] 30#[path = "adc4.rs"]
31pub mod adc4; 31pub mod adc4;
32 32
33pub use crate::pac::adc::vals; 33pub use crate::pac::adc::vals;
@@ -36,15 +36,18 @@ pub use crate::pac::adc::vals::Res as Resolution;
36pub use crate::pac::adc::vals::SampleTime; 36pub use crate::pac::adc::vals::SampleTime;
37use crate::peripherals; 37use crate::peripherals;
38 38
39#[cfg(not(adc_wba))]
39dma_trait!(RxDma, Instance); 40dma_trait!(RxDma, Instance);
40#[cfg(adc_u5)] 41#[cfg(adc_u5)]
41dma_trait!(RxDma4, adc4::Instance); 42dma_trait!(RxDma4, adc4::Instance);
43#[cfg(adc_wba)]
44dma_trait!(RxDma4, adc4::Instance);
42 45
43/// Analog to Digital driver. 46/// Analog to Digital driver.
44pub struct Adc<'d, T: Instance> { 47pub struct Adc<'d, T: Instance> {
45 #[allow(unused)] 48 #[allow(unused)]
46 adc: crate::Peri<'d, T>, 49 adc: crate::Peri<'d, T>,
47 #[cfg(not(any(adc_f3_v2, adc_f3_v1_1)))] 50 #[cfg(not(any(adc_f3_v2, adc_f3_v1_1, adc_wba)))]
48 sample_time: SampleTime, 51 sample_time: SampleTime,
49} 52}
50 53
@@ -63,6 +66,7 @@ impl State {
63} 66}
64 67
65trait SealedInstance { 68trait SealedInstance {
69 #[cfg(not(adc_wba))]
66 #[allow(unused)] 70 #[allow(unused)]
67 fn regs() -> crate::pac::adc::Adc; 71 fn regs() -> crate::pac::adc::Adc;
68 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))] 72 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
@@ -73,7 +77,7 @@ trait SealedInstance {
73} 77}
74 78
75pub(crate) trait SealedAdcChannel<T> { 79pub(crate) trait SealedAdcChannel<T> {
76 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5))] 80 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5, adc_wba))]
77 fn setup(&mut self) {} 81 fn setup(&mut self) {}
78 82
79 #[allow(unused)] 83 #[allow(unused)]
@@ -110,7 +114,8 @@ pub(crate) fn blocking_delay_us(us: u32) {
110 adc_h5, 114 adc_h5,
111 adc_h7rs, 115 adc_h7rs,
112 adc_u5, 116 adc_u5,
113 adc_c0 117 adc_c0,
118 adc_wba,
114)))] 119)))]
115#[allow(private_bounds)] 120#[allow(private_bounds)]
116pub trait Instance: SealedInstance + crate::PeripheralType { 121pub trait Instance: SealedInstance + crate::PeripheralType {
@@ -132,7 +137,8 @@ pub trait Instance: SealedInstance + crate::PeripheralType {
132 adc_h5, 137 adc_h5,
133 adc_h7rs, 138 adc_h7rs,
134 adc_u5, 139 adc_u5,
135 adc_c0 140 adc_c0,
141 adc_wba,
136))] 142))]
137#[allow(private_bounds)] 143#[allow(private_bounds)]
138pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeripheral { 144pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeripheral {
@@ -144,7 +150,7 @@ pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeri
144pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized { 150pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized {
145 #[allow(unused_mut)] 151 #[allow(unused_mut)]
146 fn degrade_adc(mut self) -> AnyAdcChannel<T> { 152 fn degrade_adc(mut self) -> AnyAdcChannel<T> {
147 #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5))] 153 #[cfg(any(adc_v1, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5, adc_wba))]
148 self.setup(); 154 self.setup();
149 155
150 AnyAdcChannel { 156 AnyAdcChannel {
@@ -176,6 +182,36 @@ impl<T> AnyAdcChannel<T> {
176 self.channel 182 self.channel
177 } 183 }
178} 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);
179 215
180#[cfg(adc_u5)] 216#[cfg(adc_u5)]
181foreach_adc!( 217foreach_adc!(
@@ -208,15 +244,21 @@ foreach_adc!(
208 }; 244 };
209); 245);
210 246
211#[cfg(not(adc_u5))] 247#[cfg(not(any(adc_u5, adc_wba)))]
212foreach_adc!( 248foreach_adc!(
213 ($inst:ident, $common_inst:ident, $clock:ident) => { 249 ($inst:ident, $common_inst:ident, $clock:ident) => {
214 impl crate::adc::SealedInstance for peripherals::$inst { 250 impl crate::adc::SealedInstance for peripherals::$inst {
251 #[cfg(not(adc_wba))]
215 fn regs() -> crate::pac::adc::Adc { 252 fn regs() -> crate::pac::adc::Adc {
216 crate::pac::$inst 253 crate::pac::$inst
217 } 254 }
218 255
219 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))] 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)))]
220 fn common_regs() -> crate::pac::adccommon::AdcCommon { 262 fn common_regs() -> crate::pac::adccommon::AdcCommon {
221 return crate::pac::$common_inst 263 return crate::pac::$common_inst
222 } 264 }
@@ -238,7 +280,7 @@ macro_rules! impl_adc_pin {
238 ($inst:ident, $pin:ident, $ch:expr) => { 280 ($inst:ident, $pin:ident, $ch:expr) => {
239 impl crate::adc::AdcChannel<peripherals::$inst> for crate::Peri<'_, crate::peripherals::$pin> {} 281 impl crate::adc::AdcChannel<peripherals::$inst> for crate::Peri<'_, crate::peripherals::$pin> {}
240 impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::Peri<'_, crate::peripherals::$pin> { 282 impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::Peri<'_, crate::peripherals::$pin> {
241 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5))] 283 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5, adc_wba))]
242 fn setup(&mut self) { 284 fn setup(&mut self) {
243 <crate::peripherals::$pin as crate::gpio::SealedPin>::set_as_analog(self); 285 <crate::peripherals::$pin as crate::gpio::SealedPin>::set_as_analog(self);
244 } 286 }
diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs
index b9fc4e423..b494997b3 100644
--- a/embassy-stm32/src/rcc/wba.rs
+++ b/embassy-stm32/src/rcc/wba.rs
@@ -176,6 +176,7 @@ pub(crate) unsafe fn init(config: Config) {
176 // TODO 176 // TODO
177 lse: None, 177 lse: None,
178 lsi: None, 178 lsi: None,
179 pll1_p: None,
179 pll1_q: None, 180 pll1_q: None,
180 ); 181 );
181} 182}
diff --git a/examples/stm32wba/src/bin/adc.rs b/examples/stm32wba/src/bin/adc.rs
new file mode 100644
index 000000000..a9651d57e
--- /dev/null
+++ b/examples/stm32wba/src/bin/adc.rs
@@ -0,0 +1,49 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_stm32::adc::{adc4, AdcChannel};
6use {defmt_rtt as _, panic_probe as _};
7
8#[embassy_executor::main]
9async fn main(_spawner: embassy_executor::Spawner) {
10 let config = embassy_stm32::Config::default();
11
12 let mut p = embassy_stm32::init(config);
13
14 // **** ADC4 init ****
15 let mut adc4 = adc4::Adc4::new(p.ADC4);
16 let mut adc4_pin1 = p.PA0; // A4
17 let mut adc4_pin2 = p.PA1; // A5
18 adc4.set_resolution(adc4::Resolution::BITS12);
19 adc4.set_averaging(adc4::Averaging::Samples256);
20 adc4.set_sample_time(adc4::SampleTime::CYCLES1_5);
21 let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12);
22
23 // **** ADC4 blocking read ****
24 let raw: u16 = adc4.blocking_read(&mut adc4_pin1);
25 let volt: f32 = 3.0 * raw as f32 / max4 as f32;
26 info!("Read adc4 pin 1 {}", volt);
27
28 let raw: u16 = adc4.blocking_read(&mut adc4_pin2);
29 let volt: f32 = 3.3 * raw as f32 / max4 as f32;
30 info!("Read adc4 pin 2 {}", volt);
31
32 // **** ADC4 async read ****
33 let mut degraded41 = adc4_pin1.degrade_adc();
34 let mut degraded42 = adc4_pin2.degrade_adc();
35 let mut measurements = [0u16; 2];
36
37 // The channels must be in ascending order and can't repeat for ADC4
38 adc4.read(
39 p.GPDMA1_CH1.reborrow(),
40 [&mut degraded42, &mut degraded41].into_iter(),
41 &mut measurements,
42 )
43 .await
44 .unwrap();
45 let volt2: f32 = 3.3 * measurements[0] as f32 / max4 as f32;
46 let volt1: f32 = 3.0 * measurements[1] as f32 / max4 as f32;
47 info!("Async read 4 pin 1 {}", volt1);
48 info!("Async read 4 pin 2 {}", volt2);
49}