diff options
| author | shufps <[email protected]> | 2024-02-08 10:47:26 +0100 |
|---|---|---|
| committer | shufps <[email protected]> | 2024-02-08 10:47:26 +0100 |
| commit | ab8f25fd78582aab68c9820e4b4dd9771a1ded65 (patch) | |
| tree | 67d9ccbabfb9dd9166f61c5d9ad06f268aa193a1 | |
| parent | 2e15d1371a891cc3456d7b9fd22a68291770df41 (diff) | |
added support for ADC of L0s
| -rw-r--r-- | embassy-stm32/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/mod.rs | 23 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/resolution.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/sample_time.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/v1.rs | 21 |
5 files changed, 40 insertions, 18 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 8f0fc1c59..61d70b732 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -68,7 +68,7 @@ rand_core = "0.6.3" | |||
| 68 | sdio-host = "0.5.0" | 68 | sdio-host = "0.5.0" |
| 69 | critical-section = "1.1" | 69 | critical-section = "1.1" |
| 70 | #stm32-metapac = { version = "15" } | 70 | #stm32-metapac = { version = "15" } |
| 71 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e702b4d564bc9e3c8a5c0141a11efdc5f7ee8f24" } | 71 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d7c933984fe0cbd120b6aaa7742bd585f89fa786" } |
| 72 | vcell = "0.1.3" | 72 | vcell = "0.1.3" |
| 73 | bxcan = "0.7.0" | 73 | bxcan = "0.7.0" |
| 74 | nb = "1.0.0" | 74 | nb = "1.0.0" |
| @@ -89,7 +89,7 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 89 | proc-macro2 = "1.0.36" | 89 | proc-macro2 = "1.0.36" |
| 90 | quote = "1.0.15" | 90 | quote = "1.0.15" |
| 91 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} | 91 | #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} |
| 92 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e702b4d564bc9e3c8a5c0141a11efdc5f7ee8f24", default-features = false, features = ["metadata"]} | 92 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-d7c933984fe0cbd120b6aaa7742bd585f89fa786", default-features = false, features = ["metadata"]} |
| 93 | 93 | ||
| 94 | 94 | ||
| 95 | [features] | 95 | [features] |
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index d21c3053f..51b4b5fcc 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #[cfg_attr(adc_f3, path = "f3.rs")] | 8 | #[cfg_attr(adc_f3, path = "f3.rs")] |
| 9 | #[cfg_attr(adc_f3_v1_1, path = "f3_v1_1.rs")] | 9 | #[cfg_attr(adc_f3_v1_1, path = "f3_v1_1.rs")] |
| 10 | #[cfg_attr(adc_v1, path = "v1.rs")] | 10 | #[cfg_attr(adc_v1, path = "v1.rs")] |
| 11 | #[cfg_attr(adc_l0, path = "v1.rs")] | ||
| 11 | #[cfg_attr(adc_v2, path = "v2.rs")] | 12 | #[cfg_attr(adc_v2, path = "v2.rs")] |
| 12 | #[cfg_attr(any(adc_v3, adc_g0), path = "v3.rs")] | 13 | #[cfg_attr(any(adc_v3, adc_g0), path = "v3.rs")] |
| 13 | #[cfg_attr(adc_v4, path = "v4.rs")] | 14 | #[cfg_attr(adc_v4, path = "v4.rs")] |
| @@ -36,15 +37,15 @@ pub struct Adc<'d, T: Instance> { | |||
| 36 | } | 37 | } |
| 37 | 38 | ||
| 38 | pub(crate) mod sealed { | 39 | pub(crate) mod sealed { |
| 39 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))] | 40 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] |
| 40 | use embassy_sync::waitqueue::AtomicWaker; | 41 | use embassy_sync::waitqueue::AtomicWaker; |
| 41 | 42 | ||
| 42 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))] | 43 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] |
| 43 | pub struct State { | 44 | pub struct State { |
| 44 | pub waker: AtomicWaker, | 45 | pub waker: AtomicWaker, |
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))] | 48 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] |
| 48 | impl State { | 49 | impl State { |
| 49 | pub const fn new() -> Self { | 50 | pub const fn new() -> Self { |
| 50 | Self { | 51 | Self { |
| @@ -59,14 +60,14 @@ pub(crate) mod sealed { | |||
| 59 | 60 | ||
| 60 | pub trait Instance: InterruptableInstance { | 61 | pub trait Instance: InterruptableInstance { |
| 61 | fn regs() -> crate::pac::adc::Adc; | 62 | fn regs() -> crate::pac::adc::Adc; |
| 62 | #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_f3_v1_1, adc_g0)))] | 63 | #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))] |
| 63 | fn common_regs() -> crate::pac::adccommon::AdcCommon; | 64 | fn common_regs() -> crate::pac::adccommon::AdcCommon; |
| 64 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))] | 65 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] |
| 65 | fn state() -> &'static State; | 66 | fn state() -> &'static State; |
| 66 | } | 67 | } |
| 67 | 68 | ||
| 68 | pub trait AdcPin<T: Instance> { | 69 | pub trait AdcPin<T: Instance> { |
| 69 | #[cfg(any(adc_v1, adc_v2))] | 70 | #[cfg(any(adc_v1, adc_l0, adc_v2))] |
| 70 | fn set_as_analog(&mut self) {} | 71 | fn set_as_analog(&mut self) {} |
| 71 | 72 | ||
| 72 | fn channel(&self) -> u8; | 73 | fn channel(&self) -> u8; |
| @@ -78,10 +79,10 @@ pub(crate) mod sealed { | |||
| 78 | } | 79 | } |
| 79 | 80 | ||
| 80 | /// ADC instance. | 81 | /// ADC instance. |
| 81 | #[cfg(not(any(adc_f1, adc_v1, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0)))] | 82 | #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0)))] |
| 82 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {} | 83 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {} |
| 83 | /// ADC instance. | 84 | /// ADC instance. |
| 84 | #[cfg(any(adc_f1, adc_v1, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0))] | 85 | #[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0))] |
| 85 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {} | 86 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {} |
| 86 | 87 | ||
| 87 | /// ADC pin. | 88 | /// ADC pin. |
| @@ -96,12 +97,12 @@ foreach_adc!( | |||
| 96 | crate::pac::$inst | 97 | crate::pac::$inst |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 99 | #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_f3_v1_1, adc_g0)))] | 100 | #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))] |
| 100 | fn common_regs() -> crate::pac::adccommon::AdcCommon { | 101 | fn common_regs() -> crate::pac::adccommon::AdcCommon { |
| 101 | return crate::pac::$common_inst | 102 | return crate::pac::$common_inst |
| 102 | } | 103 | } |
| 103 | 104 | ||
| 104 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))] | 105 | #[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))] |
| 105 | fn state() -> &'static sealed::State { | 106 | fn state() -> &'static sealed::State { |
| 106 | static STATE: sealed::State = sealed::State::new(); | 107 | static STATE: sealed::State = sealed::State::new(); |
| 107 | &STATE | 108 | &STATE |
| @@ -125,7 +126,7 @@ macro_rules! impl_adc_pin { | |||
| 125 | impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} | 126 | impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} |
| 126 | 127 | ||
| 127 | impl crate::adc::sealed::AdcPin<peripherals::$inst> for crate::peripherals::$pin { | 128 | impl crate::adc::sealed::AdcPin<peripherals::$inst> for crate::peripherals::$pin { |
| 128 | #[cfg(any(adc_v1, adc_v2))] | 129 | #[cfg(any(adc_v1, adc_l0, adc_v2))] |
| 129 | fn set_as_analog(&mut self) { | 130 | fn set_as_analog(&mut self) { |
| 130 | <Self as crate::gpio::sealed::Pin>::set_as_analog(self); | 131 | <Self as crate::gpio::sealed::Pin>::set_as_analog(self); |
| 131 | } | 132 | } |
diff --git a/embassy-stm32/src/adc/resolution.rs b/embassy-stm32/src/adc/resolution.rs index 9513e1df7..0e6c45c65 100644 --- a/embassy-stm32/src/adc/resolution.rs +++ b/embassy-stm32/src/adc/resolution.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /// ADC resolution | 1 | /// ADC resolution |
| 2 | #[allow(missing_docs)] | 2 | #[allow(missing_docs)] |
| 3 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3, adc_f3_v1_1))] | 3 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_l0, adc_g0, adc_f3, adc_f3_v1_1))] |
| 4 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] | 4 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] |
| 5 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 5 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 6 | pub enum Resolution { | 6 | pub enum Resolution { |
| @@ -25,7 +25,7 @@ pub enum Resolution { | |||
| 25 | 25 | ||
| 26 | impl Default for Resolution { | 26 | impl Default for Resolution { |
| 27 | fn default() -> Self { | 27 | fn default() -> Self { |
| 28 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3, adc_f3_v1_1))] | 28 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_l0, adc_g0, adc_f3, adc_f3_v1_1))] |
| 29 | { | 29 | { |
| 30 | Self::TwelveBit | 30 | Self::TwelveBit |
| 31 | } | 31 | } |
| @@ -46,7 +46,7 @@ impl From<Resolution> for crate::pac::adc::vals::Res { | |||
| 46 | Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT, | 46 | Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT, |
| 47 | Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT, | 47 | Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT, |
| 48 | Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT, | 48 | Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT, |
| 49 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3, adc_f3_v1_1))] | 49 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_l0, adc_g0, adc_f3, adc_f3_v1_1))] |
| 50 | Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT, | 50 | Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT, |
| 51 | } | 51 | } |
| 52 | } | 52 | } |
| @@ -65,7 +65,7 @@ impl Resolution { | |||
| 65 | Resolution::TwelveBit => (1 << 12) - 1, | 65 | Resolution::TwelveBit => (1 << 12) - 1, |
| 66 | Resolution::TenBit => (1 << 10) - 1, | 66 | Resolution::TenBit => (1 << 10) - 1, |
| 67 | Resolution::EightBit => (1 << 8) - 1, | 67 | Resolution::EightBit => (1 << 8) - 1, |
| 68 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0, adc_f3, adc_f3_v1_1))] | 68 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_l0, adc_g0, adc_f3, adc_f3_v1_1))] |
| 69 | Resolution::SixBit => (1 << 6) - 1, | 69 | Resolution::SixBit => (1 << 6) - 1, |
| 70 | } | 70 | } |
| 71 | } | 71 | } |
diff --git a/embassy-stm32/src/adc/sample_time.rs b/embassy-stm32/src/adc/sample_time.rs index 5a06f1a5a..f4b22b462 100644 --- a/embassy-stm32/src/adc/sample_time.rs +++ b/embassy-stm32/src/adc/sample_time.rs | |||
| @@ -83,7 +83,7 @@ impl_sample_time!( | |||
| 83 | ) | 83 | ) |
| 84 | ); | 84 | ); |
| 85 | 85 | ||
| 86 | #[cfg(adc_g0)] | 86 | #[cfg(any(adc_l0, adc_g0))] |
| 87 | impl_sample_time!( | 87 | impl_sample_time!( |
| 88 | "1.5", | 88 | "1.5", |
| 89 | Cycles1_5, | 89 | Cycles1_5, |
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs index 852b027df..13a7ead3e 100644 --- a/embassy-stm32/src/adc/v1.rs +++ b/embassy-stm32/src/adc/v1.rs | |||
| @@ -6,6 +6,10 @@ use embassy_hal_internal::into_ref; | |||
| 6 | use embedded_hal_02::blocking::delay::DelayUs; | 6 | use embedded_hal_02::blocking::delay::DelayUs; |
| 7 | 7 | ||
| 8 | use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; | 8 | use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; |
| 9 | |||
| 10 | #[cfg(adc_l0)] | ||
| 11 | use stm32_metapac::adc::vals::Ckmode; | ||
| 12 | |||
| 9 | use crate::interrupt::typelevel::Interrupt; | 13 | use crate::interrupt::typelevel::Interrupt; |
| 10 | use crate::peripherals::ADC; | 14 | use crate::peripherals::ADC; |
| 11 | use crate::{interrupt, Peripheral}; | 15 | use crate::{interrupt, Peripheral}; |
| @@ -30,8 +34,13 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 30 | } | 34 | } |
| 31 | } | 35 | } |
| 32 | 36 | ||
| 37 | #[cfg(not(adc_l0))] | ||
| 33 | pub struct Vbat; | 38 | pub struct Vbat; |
| 39 | |||
| 40 | #[cfg(not(adc_l0))] | ||
| 34 | impl AdcPin<ADC> for Vbat {} | 41 | impl AdcPin<ADC> for Vbat {} |
| 42 | |||
| 43 | #[cfg(not(adc_l0))] | ||
| 35 | impl super::sealed::AdcPin<ADC> for Vbat { | 44 | impl super::sealed::AdcPin<ADC> for Vbat { |
| 36 | fn channel(&self) -> u8 { | 45 | fn channel(&self) -> u8 { |
| 37 | 18 | 46 | 18 |
| @@ -72,6 +81,11 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 72 | // A.7.1 ADC calibration code example | 81 | // A.7.1 ADC calibration code example |
| 73 | T::regs().cfgr1().modify(|reg| reg.set_dmaen(false)); | 82 | T::regs().cfgr1().modify(|reg| reg.set_dmaen(false)); |
| 74 | T::regs().cr().modify(|reg| reg.set_adcal(true)); | 83 | T::regs().cr().modify(|reg| reg.set_adcal(true)); |
| 84 | |||
| 85 | #[cfg(adc_l0)] | ||
| 86 | while !T::regs().isr().read().eocal() {} | ||
| 87 | |||
| 88 | #[cfg(not(adc_l0))] | ||
| 75 | while T::regs().cr().read().adcal() {} | 89 | while T::regs().cr().read().adcal() {} |
| 76 | 90 | ||
| 77 | // A.7.2 ADC enable sequence code example | 91 | // A.7.2 ADC enable sequence code example |
| @@ -97,6 +111,7 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 97 | } | 111 | } |
| 98 | } | 112 | } |
| 99 | 113 | ||
| 114 | #[cfg(not(adc_l0))] | ||
| 100 | pub fn enable_vbat(&self, _delay: &mut impl DelayUs<u32>) -> Vbat { | 115 | pub fn enable_vbat(&self, _delay: &mut impl DelayUs<u32>) -> Vbat { |
| 101 | // SMP must be ≥ 56 ADC clock cycles when using HSI14. | 116 | // SMP must be ≥ 56 ADC clock cycles when using HSI14. |
| 102 | // | 117 | // |
| @@ -133,6 +148,12 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 133 | T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into())); | 148 | T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into())); |
| 134 | } | 149 | } |
| 135 | 150 | ||
| 151 | #[cfg(adc_l0)] | ||
| 152 | pub fn set_ckmode(&mut self, ckmode: Ckmode) { | ||
| 153 | // set ADC clock mode | ||
| 154 | T::regs().cfgr2().modify(|reg| reg.set_ckmode(ckmode)); | ||
| 155 | } | ||
| 156 | |||
| 136 | pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { | 157 | pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { |
| 137 | let channel = pin.channel(); | 158 | let channel = pin.channel(); |
| 138 | pin.set_as_analog(); | 159 | pin.set_as_analog(); |
