diff options
| author | Grant Miller <[email protected]> | 2023-04-05 14:31:32 -0500 |
|---|---|---|
| committer | Grant Miller <[email protected]> | 2023-04-05 15:01:31 -0500 |
| commit | f5881054297713f6224d5d81f407f8a6cf591ef4 (patch) | |
| tree | 6c44d00677c38ee045b649863387ca6d2224d218 | |
| parent | 28b8ac4b62d952918ddfe143cf6925e1402fc2ce (diff) | |
wip
| -rw-r--r-- | embassy-stm32/src/adc/mod.rs | 11 | ||||
| -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 | 129 |
4 files changed, 20 insertions, 130 deletions
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index ec49dace7..56ecd63ca 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs | |||
| @@ -7,21 +7,18 @@ | |||
| 7 | #[cfg_attr(adc_v4, path = "v4.rs")] | 7 | #[cfg_attr(adc_v4, path = "v4.rs")] |
| 8 | mod _version; | 8 | mod _version; |
| 9 | 9 | ||
| 10 | #[cfg(not(any(adc_f1, adc_v1)))] | 10 | #[cfg(not(adc_f1))] |
| 11 | mod resolution; | 11 | mod resolution; |
| 12 | #[cfg(not(adc_v1))] | ||
| 13 | mod sample_time; | 12 | mod sample_time; |
| 14 | 13 | ||
| 15 | #[allow(unused)] | 14 | #[allow(unused)] |
| 16 | pub use _version::*; | 15 | pub use _version::*; |
| 17 | #[cfg(not(any(adc_f1, adc_v1)))] | 16 | #[cfg(not(adc_f1))] |
| 18 | pub use resolution::Resolution; | 17 | pub use resolution::Resolution; |
| 19 | #[cfg(not(adc_v1))] | ||
| 20 | pub use sample_time::SampleTime; | 18 | pub use sample_time::SampleTime; |
| 21 | 19 | ||
| 22 | use crate::peripherals; | 20 | use crate::peripherals; |
| 23 | 21 | ||
| 24 | #[cfg(not(adc_v1))] | ||
| 25 | pub struct Adc<'d, T: Instance> { | 22 | pub struct Adc<'d, T: Instance> { |
| 26 | #[allow(unused)] | 23 | #[allow(unused)] |
| 27 | adc: crate::PeripheralRef<'d, T>, | 24 | adc: crate::PeripheralRef<'d, T>, |
| @@ -44,9 +41,9 @@ pub(crate) mod sealed { | |||
| 44 | } | 41 | } |
| 45 | } | 42 | } |
| 46 | 43 | ||
| 47 | #[cfg(not(any(adc_f1, adc_v2, adc_v4)))] | 44 | #[cfg(not(any(adc_f1, adc_v1, adc_v2, adc_v4)))] |
| 48 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {} | 45 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {} |
| 49 | #[cfg(any(adc_f1, adc_v2, adc_v4))] | 46 | #[cfg(any(adc_f1, adc_v1, adc_v2, adc_v4))] |
| 50 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {} | 47 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {} |
| 51 | 48 | ||
| 52 | pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} | 49 | pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} |
diff --git a/embassy-stm32/src/adc/resolution.rs b/embassy-stm32/src/adc/resolution.rs index 62b52a46c..67fb9b8c0 100644 --- a/embassy-stm32/src/adc/resolution.rs +++ b/embassy-stm32/src/adc/resolution.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | #[cfg(any(adc_v2, adc_v3, adc_g0))] | 1 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0))] |
| 2 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] | 2 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] |
| 3 | pub enum Resolution { | 3 | pub enum Resolution { |
| 4 | TwelveBit, | 4 | TwelveBit, |
| @@ -19,7 +19,7 @@ pub enum Resolution { | |||
| 19 | 19 | ||
| 20 | impl Default for Resolution { | 20 | impl Default for Resolution { |
| 21 | fn default() -> Self { | 21 | fn default() -> Self { |
| 22 | #[cfg(any(adc_v2, adc_v3, adc_g0))] | 22 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0))] |
| 23 | { | 23 | { |
| 24 | Self::TwelveBit | 24 | Self::TwelveBit |
| 25 | } | 25 | } |
| @@ -40,7 +40,7 @@ impl From<Resolution> for crate::pac::adc::vals::Res { | |||
| 40 | Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT, | 40 | Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT, |
| 41 | Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT, | 41 | Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT, |
| 42 | Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT, | 42 | Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT, |
| 43 | #[cfg(any(adc_v2, adc_v3, adc_g0))] | 43 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0))] |
| 44 | Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT, | 44 | Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT, |
| 45 | } | 45 | } |
| 46 | } | 46 | } |
| @@ -56,7 +56,7 @@ impl Resolution { | |||
| 56 | Resolution::TwelveBit => (1 << 12) - 1, | 56 | Resolution::TwelveBit => (1 << 12) - 1, |
| 57 | Resolution::TenBit => (1 << 10) - 1, | 57 | Resolution::TenBit => (1 << 10) - 1, |
| 58 | Resolution::EightBit => (1 << 8) - 1, | 58 | Resolution::EightBit => (1 << 8) - 1, |
| 59 | #[cfg(any(adc_v2, adc_v3, adc_g0))] | 59 | #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0))] |
| 60 | Resolution::SixBit => (1 << 6) - 1, | 60 | Resolution::SixBit => (1 << 6) - 1, |
| 61 | } | 61 | } |
| 62 | } | 62 | } |
diff --git a/embassy-stm32/src/adc/sample_time.rs b/embassy-stm32/src/adc/sample_time.rs index bc5fb1d6f..0faa1e3c0 100644 --- a/embassy-stm32/src/adc/sample_time.rs +++ b/embassy-stm32/src/adc/sample_time.rs | |||
| @@ -25,7 +25,7 @@ macro_rules! impl_sample_time { | |||
| 25 | }; | 25 | }; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | #[cfg(adc_f1)] | 28 | #[cfg(any(adc_f1, adc_v1))] |
| 29 | impl_sample_time!( | 29 | impl_sample_time!( |
| 30 | "1.5", | 30 | "1.5", |
| 31 | Cycles1_5, | 31 | Cycles1_5, |
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs index f787f72ac..0fdb95562 100644 --- a/embassy-stm32/src/adc/v1.rs +++ b/embassy-stm32/src/adc/v1.rs | |||
| @@ -1,10 +1,8 @@ | |||
| 1 | use core::marker::PhantomData; | ||
| 2 | |||
| 3 | use embassy_hal_common::into_ref; | 1 | use embassy_hal_common::into_ref; |
| 4 | use embedded_hal_02::blocking::delay::DelayUs; | 2 | use embedded_hal_02::blocking::delay::DelayUs; |
| 5 | 3 | ||
| 6 | use crate::adc::{AdcPin, Instance}; | 4 | use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; |
| 7 | use crate::{pac, Peripheral}; | 5 | use crate::Peripheral; |
| 8 | 6 | ||
| 9 | pub const VDDA_CALIB_MV: u32 = 3300; | 7 | pub const VDDA_CALIB_MV: u32 = 3300; |
| 10 | pub const VREF_INT: u32 = 1230; | 8 | pub const VREF_INT: u32 = 1230; |
| @@ -15,39 +13,6 @@ fn enable() { | |||
| 15 | }); | 13 | }); |
| 16 | } | 14 | } |
| 17 | 15 | ||
| 18 | pub enum Resolution { | ||
| 19 | TwelveBit, | ||
| 20 | TenBit, | ||
| 21 | EightBit, | ||
| 22 | SixBit, | ||
| 23 | } | ||
| 24 | |||
| 25 | impl Default for Resolution { | ||
| 26 | fn default() -> Self { | ||
| 27 | Self::TwelveBit | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | impl Resolution { | ||
| 32 | fn res(&self) -> pac::adc::vals::Res { | ||
| 33 | match self { | ||
| 34 | Resolution::TwelveBit => pac::adc::vals::Res::TWELVEBIT, | ||
| 35 | Resolution::TenBit => pac::adc::vals::Res::TENBIT, | ||
| 36 | Resolution::EightBit => pac::adc::vals::Res::EIGHTBIT, | ||
| 37 | Resolution::SixBit => pac::adc::vals::Res::SIXBIT, | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | pub fn to_max_count(&self) -> u32 { | ||
| 42 | match self { | ||
| 43 | Resolution::TwelveBit => (1 << 12) - 1, | ||
| 44 | Resolution::TenBit => (1 << 10) - 1, | ||
| 45 | Resolution::EightBit => (1 << 8) - 1, | ||
| 46 | Resolution::SixBit => (1 << 6) - 1, | ||
| 47 | } | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | pub trait InternalChannel<T>: sealed::InternalChannel<T> {} | 16 | pub trait InternalChannel<T>: sealed::InternalChannel<T> {} |
| 52 | 17 | ||
| 53 | mod sealed { | 18 | mod sealed { |
| @@ -80,68 +45,9 @@ impl<T: Instance> sealed::InternalChannel<T> for Temperature { | |||
| 80 | } | 45 | } |
| 81 | } | 46 | } |
| 82 | 47 | ||
| 83 | mod sample_time { | ||
| 84 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] | ||
| 85 | pub enum SampleTime { | ||
| 86 | /// 1.5 ADC clock cycles | ||
| 87 | Cycles1_5 = 0b000, | ||
| 88 | |||
| 89 | /// 7.5 ADC clock cycles | ||
| 90 | Cycles7_5 = 0b001, | ||
| 91 | |||
| 92 | /// 13.5 ADC clock cycles | ||
| 93 | Cycles13_5 = 0b010, | ||
| 94 | |||
| 95 | /// 28.5 ADC clock cycles | ||
| 96 | Cycles28_5 = 0b011, | ||
| 97 | |||
| 98 | /// 41.5 ADC clock cycles | ||
| 99 | Cycles41_5 = 0b100, | ||
| 100 | |||
| 101 | /// 55.5 ADC clock cycles | ||
| 102 | Cycles55_5 = 0b101, | ||
| 103 | |||
| 104 | /// 71.5 ADC clock cycles | ||
| 105 | Cycles71_5 = 0b110, | ||
| 106 | |||
| 107 | /// 239.5 ADC clock cycles | ||
| 108 | Cycles239_5 = 0b111, | ||
| 109 | } | ||
| 110 | |||
| 111 | impl SampleTime { | ||
| 112 | pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::Smp { | ||
| 113 | match self { | ||
| 114 | SampleTime::Cycles1_5 => crate::pac::adc::vals::Smp::CYCLES1_5, | ||
| 115 | SampleTime::Cycles7_5 => crate::pac::adc::vals::Smp::CYCLES7_5, | ||
| 116 | SampleTime::Cycles13_5 => crate::pac::adc::vals::Smp::CYCLES13_5, | ||
| 117 | SampleTime::Cycles28_5 => crate::pac::adc::vals::Smp::CYCLES28_5, | ||
| 118 | SampleTime::Cycles41_5 => crate::pac::adc::vals::Smp::CYCLES41_5, | ||
| 119 | SampleTime::Cycles55_5 => crate::pac::adc::vals::Smp::CYCLES55_5, | ||
| 120 | SampleTime::Cycles71_5 => crate::pac::adc::vals::Smp::CYCLES71_5, | ||
| 121 | SampleTime::Cycles239_5 => crate::pac::adc::vals::Smp::CYCLES239_5, | ||
| 122 | } | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | impl Default for SampleTime { | ||
| 127 | fn default() -> Self { | ||
| 128 | Self::Cycles1_5 | ||
| 129 | } | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | pub use sample_time::SampleTime; | ||
| 134 | |||
| 135 | pub struct Adc<'d, T: Instance> { | ||
| 136 | sample_time: SampleTime, | ||
| 137 | vref_mv: u32, | ||
| 138 | resolution: Resolution, | ||
| 139 | phantom: PhantomData<&'d mut T>, | ||
| 140 | } | ||
| 141 | |||
| 142 | impl<'d, T: Instance> Adc<'d, T> { | 48 | impl<'d, T: Instance> Adc<'d, T> { |
| 143 | pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { | 49 | pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { |
| 144 | into_ref!(_peri); | 50 | into_ref!(adc); |
| 145 | enable(); | 51 | enable(); |
| 146 | 52 | ||
| 147 | // Delay 1μs when using HSI14 as the ADC clock. | 53 | // Delay 1μs when using HSI14 as the ADC clock. |
| @@ -151,10 +57,8 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 151 | delay.delay_us(1); | 57 | delay.delay_us(1); |
| 152 | 58 | ||
| 153 | let s = Self { | 59 | let s = Self { |
| 60 | adc, | ||
| 154 | sample_time: Default::default(), | 61 | sample_time: Default::default(), |
| 155 | vref_mv: VDDA_CALIB_MV, | ||
| 156 | resolution: Resolution::default(), | ||
| 157 | phantom: PhantomData, | ||
| 158 | }; | 62 | }; |
| 159 | s.calibrate(); | 63 | s.calibrate(); |
| 160 | s | 64 | s |
| @@ -215,16 +119,10 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 215 | self.sample_time = sample_time; | 119 | self.sample_time = sample_time; |
| 216 | } | 120 | } |
| 217 | 121 | ||
| 218 | pub fn set_vref_mv(&mut self, vref_mv: u32) { | ||
| 219 | self.vref_mv = vref_mv; | ||
| 220 | } | ||
| 221 | |||
| 222 | pub fn set_resolution(&mut self, resolution: Resolution) { | 122 | pub fn set_resolution(&mut self, resolution: Resolution) { |
| 223 | self.resolution = resolution; | 123 | unsafe { |
| 224 | } | 124 | T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into())); |
| 225 | 125 | } | |
| 226 | pub fn to_millivolts(&self, sample: u16) -> u16 { | ||
| 227 | ((u32::from(sample) * self.vref_mv) / self.resolution.to_max_count()) as u16 | ||
| 228 | } | 126 | } |
| 229 | 127 | ||
| 230 | pub fn read<P>(&mut self, pin: &mut P) -> u16 | 128 | pub fn read<P>(&mut self, pin: &mut P) -> u16 |
| @@ -240,9 +138,7 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 240 | 138 | ||
| 241 | pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 { | 139 | pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 { |
| 242 | let channel = channel.channel(); | 140 | let channel = channel.channel(); |
| 243 | unsafe { | 141 | unsafe { self.read_channel(channel) } |
| 244 | self.read_channel(channel) | ||
| 245 | } | ||
| 246 | } | 142 | } |
| 247 | 143 | ||
| 248 | unsafe fn read_channel(&mut self, channel: u8) -> u16 { | 144 | unsafe fn read_channel(&mut self, channel: u8) -> u16 { |
| @@ -258,17 +154,14 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 258 | T::regs().cr().modify(|reg| reg.set_aden(true)); | 154 | T::regs().cr().modify(|reg| reg.set_aden(true)); |
| 259 | } | 155 | } |
| 260 | 156 | ||
| 261 | T::regs().cfgr1().modify(|reg| reg.set_res(self.resolution.res())); | ||
| 262 | T::regs().isr().modify(|reg| { | 157 | T::regs().isr().modify(|reg| { |
| 263 | reg.set_eoc(true); | 158 | reg.set_eoc(true); |
| 264 | reg.set_eosmp(true); | 159 | reg.set_eosmp(true); |
| 265 | }); | 160 | }); |
| 266 | 161 | ||
| 267 | // A.7.5 Single conversion sequence code example - Software trigger | 162 | // A.7.5 Single conversion sequence code example - Software trigger |
| 268 | T::regs() | 163 | T::regs().chselr().write(|reg| reg.set_chselx(channel as usize, true)); |
| 269 | .chselr() | 164 | T::regs().smpr().modify(|reg| reg.set_smp(self.sample_time.into())); |
| 270 | .write(|reg| reg.set_chselx(channel as usize, true)); | ||
| 271 | T::regs().smpr().modify(|reg| reg.set_smp(self.sample_time.sample_time())); | ||
| 272 | T::regs().cr().modify(|reg| reg.set_adstart(true)); | 165 | T::regs().cr().modify(|reg| reg.set_adstart(true)); |
| 273 | while !T::regs().isr().read().eoc() { | 166 | while !T::regs().isr().read().eoc() { |
| 274 | // spin | 167 | // spin |
