diff options
| -rw-r--r-- | embassy-stm32/build.rs | 17 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/mod.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/v4.rs | 74 |
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: | |||
| 56 | pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} | 56 | pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} |
| 57 | pub trait InternalChannel<T>: sealed::InternalChannel<T> {} | 57 | pub trait InternalChannel<T>: sealed::InternalChannel<T> {} |
| 58 | 58 | ||
| 59 | #[cfg(not(any(stm32h7, adc_f3)))] | 59 | #[cfg(not(any(stm32h7, adc_f3, adc_v4)))] |
| 60 | foreach_peripheral!( | 60 | foreach_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))] |
| 81 | foreach_peripheral!( | 81 | foreach_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 @@ | |||
| 1 | use core::sync::atomic::{AtomicU8, Ordering}; | ||
| 2 | |||
| 3 | use embedded_hal_02::blocking::delay::DelayUs; | 1 | use embedded_hal_02::blocking::delay::DelayUs; |
| 4 | #[allow(unused)] | 2 | #[allow(unused)] |
| 5 | use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel}; | 3 | use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel}; |
| 6 | use pac::adccommon::vals::Presc; | 4 | use pac::adccommon::vals::Presc; |
| 7 | use paste::paste; | ||
| 8 | 5 | ||
| 9 | use super::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; | 6 | use super::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; |
| 10 | use crate::time::Hertz; | 7 | use crate::time::Hertz; |
| @@ -59,77 +56,6 @@ impl<T: Instance> super::sealed::InternalChannel<T> for Vbat { | |||
| 59 | } | 56 | } |
| 60 | } | 57 | } |
| 61 | 58 | ||
| 62 | static ADC12_ENABLE_COUNTER: AtomicU8 = AtomicU8::new(0); | ||
| 63 | #[cfg(any(stm32g4x3, stm32g4x4))] | ||
| 64 | static ADC345_ENABLE_COUNTER: AtomicU8 = AtomicU8::new(0); | ||
| 65 | |||
| 66 | macro_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)] | ||
| 109 | foreach_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)] | ||
| 115 | foreach_peripheral!( | ||
| 116 | (adc, ADC3) => { rcc_peripheral!(ADC3, adc34, ahb2, adc345); }; | ||
| 117 | ); | ||
| 118 | |||
| 119 | #[cfg(any(stm32g4x3, stm32g4x4))] | ||
| 120 | foreach_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)] | ||
| 127 | foreach_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)] |
