aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/build.rs17
-rw-r--r--embassy-stm32/src/adc/mod.rs6
-rw-r--r--embassy-stm32/src/adc/v4.rs74
3 files changed, 10 insertions, 87 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index d3bfd24fb..bb81736ba 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -308,20 +308,11 @@ fn main() {
308 // ======== 308 // ========
309 // Generate RccPeripheral impls 309 // Generate RccPeripheral impls
310 310
311 // TODO: maybe get this from peripheral kind? Not sure 311 let refcounted_peripherals = HashSet::from(["usart", "adc"]);
312 let mut refcounted_peripherals = HashSet::from(["usart"]);
313 let mut refcount_statics = HashSet::new(); 312 let mut refcount_statics = HashSet::new();
314 313
315 if chip_name.starts_with("stm32f3") {
316 refcounted_peripherals.insert("adc");
317 }
318
319 for p in METADATA.peripherals { 314 for p in METADATA.peripherals {
320 // generating RccPeripheral impl for H7 ADC3 would result in bad frequency 315 if !singletons.contains(&p.name.to_string()) {
321 if !singletons.contains(&p.name.to_string())
322 || (p.name == "ADC3" && METADATA.line.starts_with("STM32H7"))
323 || (p.name.starts_with("ADC") && p.registers.as_ref().map_or(false, |r| r.version == "v4"))
324 {
325 continue; 316 continue;
326 } 317 }
327 318
@@ -711,6 +702,10 @@ fn main() {
711 702
712 // ADC is special 703 // ADC is special
713 if regs.kind == "adc" { 704 if regs.kind == "adc" {
705 if p.rcc.is_none() {
706 continue;
707 }
708
714 let peri = format_ident!("{}", p.name); 709 let peri = format_ident!("{}", p.name);
715 let pin_name = format_ident!("{}", pin.pin); 710 let pin_name = format_ident!("{}", pin.pin);
716 711
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index a127445d8..023a94f2f 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -56,7 +56,7 @@ pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc:
56pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} 56pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {}
57pub trait InternalChannel<T>: sealed::InternalChannel<T> {} 57pub trait InternalChannel<T>: sealed::InternalChannel<T> {}
58 58
59#[cfg(not(any(stm32h7, adc_f3)))] 59#[cfg(not(any(stm32h7, adc_f3, adc_v4)))]
60foreach_peripheral!( 60foreach_peripheral!(
61 (adc, $inst:ident) => { 61 (adc, $inst:ident) => {
62 impl crate::adc::sealed::Instance for peripherals::$inst { 62 impl crate::adc::sealed::Instance for peripherals::$inst {
@@ -77,9 +77,10 @@ foreach_peripheral!(
77 }; 77 };
78); 78);
79 79
80#[cfg(any(stm32h7, adc_f3))] 80#[cfg(any(stm32h7, adc_f3, adc_v4))]
81foreach_peripheral!( 81foreach_peripheral!(
82 (adc, ADC3) => { 82 (adc, ADC3) => {
83 #[cfg(not(any(stm32g4x1, stm32g4x2, stm32g4x3, stm32g4x4)))]
83 impl crate::adc::sealed::Instance for peripherals::ADC3 { 84 impl crate::adc::sealed::Instance for peripherals::ADC3 {
84 fn regs() -> crate::pac::adc::Adc { 85 fn regs() -> crate::pac::adc::Adc {
85 crate::pac::ADC3 86 crate::pac::ADC3
@@ -99,6 +100,7 @@ foreach_peripheral!(
99 } 100 }
100 } 101 }
101 102
103 #[cfg(not(any(stm32g4x1, stm32g4x2, stm32g4x3, stm32g4x4)))]
102 impl crate::adc::Instance for peripherals::ADC3 {} 104 impl crate::adc::Instance for peripherals::ADC3 {}
103 }; 105 };
104 (adc, ADC4) => { 106 (adc, ADC4) => {
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index 2ff5c8f9e..655c0cb6a 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -1,10 +1,7 @@
1use core::sync::atomic::{AtomicU8, Ordering};
2
3use embedded_hal_02::blocking::delay::DelayUs; 1use embedded_hal_02::blocking::delay::DelayUs;
4#[allow(unused)] 2#[allow(unused)]
5use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel}; 3use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
6use pac::adccommon::vals::Presc; 4use pac::adccommon::vals::Presc;
7use paste::paste;
8 5
9use super::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; 6use super::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
10use crate::time::Hertz; 7use crate::time::Hertz;
@@ -59,77 +56,6 @@ impl<T: Instance> super::sealed::InternalChannel<T> for Vbat {
59 } 56 }
60} 57}
61 58
62static ADC12_ENABLE_COUNTER: AtomicU8 = AtomicU8::new(0);
63#[cfg(any(stm32g4x3, stm32g4x4))]
64static ADC345_ENABLE_COUNTER: AtomicU8 = AtomicU8::new(0);
65
66macro_rules! rcc_peripheral {
67 ($adc_name:ident, $freqs:ident, $ahb:ident, $reg:ident $(, $counter:ident )? ) => {
68 impl crate::rcc::sealed::RccPeripheral for crate::peripherals::$adc_name {
69 fn frequency() -> crate::time::Hertz {
70 critical_section::with(|_| {
71 match unsafe { crate::rcc::get_freqs() }.$freqs {
72 Some(ck) => ck,
73 None => panic!("Invalid ADC clock configuration, AdcClockSource was likely not properly configured.")
74 }
75 })
76 }
77
78 fn enable() {
79 critical_section::with(|_| {
80 paste!{crate::pac::RCC.[< $ahb enr >]().modify(|w| w.[< set_ $reg en >](true))}
81 });
82 $ ( $counter.fetch_add(1, Ordering::SeqCst); )?
83 }
84
85 fn disable() {
86 $ ( if $counter.load(Ordering::SeqCst) == 1 )? {
87 critical_section::with(|_| {
88 paste!{crate::pac::RCC.[< $ahb enr >]().modify(|w| w.[< set_ $reg en >](false))}
89 })
90 }
91 $ ( $counter.fetch_sub(1, Ordering::SeqCst); )?
92 }
93
94 fn reset() {
95 $ ( if $counter.load(Ordering::SeqCst) == 1 )? {
96 critical_section::with(|_| {
97 paste!{crate::pac::RCC.[< $ahb rstr >]().modify(|w| w.[< set_ $reg rst >](true))}
98 paste!{crate::pac::RCC.[< $ahb rstr >]().modify(|w| w.[< set_ $reg rst >](false))}
99 });
100 }
101 }
102 }
103
104 impl crate::rcc::RccPeripheral for crate::peripherals::$adc_name {}
105 };
106}
107
108#[cfg(stm32g4)]
109foreach_peripheral!(
110 (adc, ADC1) => { rcc_peripheral!(ADC1, adc, ahb2, adc12, ADC12_ENABLE_COUNTER); };
111 (adc, ADC2) => { rcc_peripheral!(ADC2, adc, ahb2, adc12, ADC12_ENABLE_COUNTER); };
112);
113
114#[cfg(stm32g4x1)]
115foreach_peripheral!(
116 (adc, ADC3) => { rcc_peripheral!(ADC3, adc34, ahb2, adc345); };
117);
118
119#[cfg(any(stm32g4x3, stm32g4x4))]
120foreach_peripheral!(
121 (adc, ADC3) => { rcc_peripheral!(ADC3, adc34, ahb2, adc345, ADC345_ENABLE_COUNTER); };
122 (adc, ADC4) => { rcc_peripheral!(ADC4, adc34, ahb2, adc345, ADC345_ENABLE_COUNTER); };
123 (adc, ADC5) => { rcc_peripheral!(ADC5, adc34, ahb2, adc345, ADC345_ENABLE_COUNTER); };
124);
125
126#[cfg(stm32h7)]
127foreach_peripheral!(
128 (adc, ADC1) => { rcc_peripheral!(ADC1, adc, ahb1, adc12, ADC12_ENABLE_COUNTER); };
129 (adc, ADC2) => { rcc_peripheral!(ADC2, adc, ahb1, adc12, ADC12_ENABLE_COUNTER); };
130 (adc, ADC3) => { rcc_peripheral!(ADC3, adc, ahb4, adc3); };
131);
132
133// NOTE (unused): The prescaler enum closely copies the hardware capabilities, 59// NOTE (unused): The prescaler enum closely copies the hardware capabilities,
134// but high prescaling doesn't make a lot of sense in the current implementation and is ommited. 60// but high prescaling doesn't make a lot of sense in the current implementation and is ommited.
135#[allow(unused)] 61#[allow(unused)]