diff options
| -rw-r--r-- | embassy-stm32/src/adc/f1.rs | 79 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/mod.rs | 80 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/resolution.rs | 63 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/sample_time.rs | 111 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/v2.rs | 100 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/v3.rs | 184 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/v4.rs | 122 |
7 files changed, 254 insertions, 485 deletions
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs index c5b317ce9..d30ec001d 100644 --- a/embassy-stm32/src/adc/f1.rs +++ b/embassy-stm32/src/adc/f1.rs | |||
| @@ -1,9 +1,7 @@ | |||
| 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, SampleTime}; |
| 7 | use crate::rcc::get_freqs; | 5 | use crate::rcc::get_freqs; |
| 8 | use crate::time::Hertz; | 6 | use crate::time::Hertz; |
| 9 | use crate::Peripheral; | 7 | use crate::Peripheral; |
| @@ -29,69 +27,9 @@ impl<T: Instance> super::sealed::AdcPin<T> for Temperature { | |||
| 29 | } | 27 | } |
| 30 | } | 28 | } |
| 31 | 29 | ||
| 32 | mod sample_time { | ||
| 33 | /// ADC sample time | ||
| 34 | /// | ||
| 35 | /// The default setting is 1.5 ADC clock cycles. | ||
| 36 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] | ||
| 37 | pub enum SampleTime { | ||
| 38 | /// 1.5 ADC clock cycles | ||
| 39 | Cycles1_5 = 0b000, | ||
| 40 | |||
| 41 | /// 7.5 ADC clock cycles | ||
| 42 | Cycles7_5 = 0b001, | ||
| 43 | |||
| 44 | /// 13.5 ADC clock cycles | ||
| 45 | Cycles13_5 = 0b010, | ||
| 46 | |||
| 47 | /// 28.5 ADC clock cycles | ||
| 48 | Cycles28_5 = 0b011, | ||
| 49 | |||
| 50 | /// 41.5 ADC clock cycles | ||
| 51 | Cycles41_5 = 0b100, | ||
| 52 | |||
| 53 | /// 55.5 ADC clock cycles | ||
| 54 | Cycles55_5 = 0b101, | ||
| 55 | |||
| 56 | /// 71.5 ADC clock cycles | ||
| 57 | Cycles71_5 = 0b110, | ||
| 58 | |||
| 59 | /// 239.5 ADC clock cycles | ||
| 60 | Cycles239_5 = 0b111, | ||
| 61 | } | ||
| 62 | |||
| 63 | impl SampleTime { | ||
| 64 | pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::SampleTime { | ||
| 65 | match self { | ||
| 66 | SampleTime::Cycles1_5 => crate::pac::adc::vals::SampleTime::CYCLES1_5, | ||
| 67 | SampleTime::Cycles7_5 => crate::pac::adc::vals::SampleTime::CYCLES7_5, | ||
| 68 | SampleTime::Cycles13_5 => crate::pac::adc::vals::SampleTime::CYCLES13_5, | ||
| 69 | SampleTime::Cycles28_5 => crate::pac::adc::vals::SampleTime::CYCLES28_5, | ||
| 70 | SampleTime::Cycles41_5 => crate::pac::adc::vals::SampleTime::CYCLES41_5, | ||
| 71 | SampleTime::Cycles55_5 => crate::pac::adc::vals::SampleTime::CYCLES55_5, | ||
| 72 | SampleTime::Cycles71_5 => crate::pac::adc::vals::SampleTime::CYCLES71_5, | ||
| 73 | SampleTime::Cycles239_5 => crate::pac::adc::vals::SampleTime::CYCLES239_5, | ||
| 74 | } | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | impl Default for SampleTime { | ||
| 79 | fn default() -> Self { | ||
| 80 | Self::Cycles28_5 | ||
| 81 | } | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | pub use sample_time::SampleTime; | ||
| 86 | |||
| 87 | pub struct Adc<'d, T: Instance> { | ||
| 88 | sample_time: SampleTime, | ||
| 89 | phantom: PhantomData<&'d mut T>, | ||
| 90 | } | ||
| 91 | |||
| 92 | impl<'d, T: Instance> Adc<'d, T> { | 30 | impl<'d, T: Instance> Adc<'d, T> { |
| 93 | pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { | 31 | pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { |
| 94 | into_ref!(_peri); | 32 | into_ref!(adc); |
| 95 | T::enable(); | 33 | T::enable(); |
| 96 | T::reset(); | 34 | T::reset(); |
| 97 | unsafe { | 35 | unsafe { |
| @@ -120,8 +58,8 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 120 | delay.delay_us((1_000_000) / Self::freq().0 + 1); | 58 | delay.delay_us((1_000_000) / Self::freq().0 + 1); |
| 121 | 59 | ||
| 122 | Self { | 60 | Self { |
| 61 | adc, | ||
| 123 | sample_time: Default::default(), | 62 | sample_time: Default::default(), |
| 124 | phantom: PhantomData, | ||
| 125 | } | 63 | } |
| 126 | } | 64 | } |
| 127 | 65 | ||
| @@ -201,14 +139,11 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 201 | } | 139 | } |
| 202 | 140 | ||
| 203 | unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { | 141 | unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { |
| 142 | let sample_time = sample_time.into(); | ||
| 204 | if ch <= 9 { | 143 | if ch <= 9 { |
| 205 | T::regs() | 144 | T::regs().smpr2().modify(|reg| reg.set_smp(ch as _, sample_time)); |
| 206 | .smpr2() | ||
| 207 | .modify(|reg| reg.set_smp(ch as _, sample_time.sample_time())); | ||
| 208 | } else { | 145 | } else { |
| 209 | T::regs() | 146 | T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time)); |
| 210 | .smpr1() | ||
| 211 | .modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time())); | ||
| 212 | } | 147 | } |
| 213 | } | 148 | } |
| 214 | } | 149 | } |
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index 0eb4eba73..ec49dace7 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs | |||
| @@ -1,28 +1,38 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | #[cfg_attr(adc_v4, path = "v4.rs")] | ||
| 4 | #[cfg_attr(adc_v3, path = "v3.rs")] | ||
| 5 | #[cfg_attr(adc_v2, path = "v2.rs")] | ||
| 6 | #[cfg_attr(adc_g0, path = "v3.rs")] | ||
| 7 | #[cfg_attr(adc_f1, path = "f1.rs")] | 3 | #[cfg_attr(adc_f1, path = "f1.rs")] |
| 8 | #[cfg_attr(adc_v1, path = "v1.rs")] | 4 | #[cfg_attr(adc_v1, path = "v1.rs")] |
| 5 | #[cfg_attr(adc_v2, path = "v2.rs")] | ||
| 6 | #[cfg_attr(any(adc_v3, adc_g0), path = "v3.rs")] | ||
| 7 | #[cfg_attr(adc_v4, path = "v4.rs")] | ||
| 9 | mod _version; | 8 | mod _version; |
| 10 | 9 | ||
| 10 | #[cfg(not(any(adc_f1, adc_v1)))] | ||
| 11 | mod resolution; | ||
| 12 | #[cfg(not(adc_v1))] | ||
| 13 | mod sample_time; | ||
| 14 | |||
| 11 | #[allow(unused)] | 15 | #[allow(unused)] |
| 12 | pub use _version::*; | 16 | pub use _version::*; |
| 17 | #[cfg(not(any(adc_f1, adc_v1)))] | ||
| 18 | pub use resolution::Resolution; | ||
| 19 | #[cfg(not(adc_v1))] | ||
| 20 | pub use sample_time::SampleTime; | ||
| 13 | 21 | ||
| 14 | use crate::peripherals; | 22 | use crate::peripherals; |
| 15 | 23 | ||
| 24 | #[cfg(not(adc_v1))] | ||
| 25 | pub struct Adc<'d, T: Instance> { | ||
| 26 | #[allow(unused)] | ||
| 27 | adc: crate::PeripheralRef<'d, T>, | ||
| 28 | sample_time: SampleTime, | ||
| 29 | } | ||
| 30 | |||
| 16 | pub(crate) mod sealed { | 31 | pub(crate) mod sealed { |
| 17 | pub trait Instance { | 32 | pub trait Instance { |
| 18 | fn regs() -> &'static crate::pac::adc::Adc; | 33 | fn regs() -> crate::pac::adc::Adc; |
| 19 | #[cfg(all(not(adc_f1), not(adc_v1)))] | 34 | #[cfg(all(not(adc_f1), not(adc_v1)))] |
| 20 | fn common_regs() -> &'static crate::pac::adccommon::AdcCommon; | 35 | fn common_regs() -> crate::pac::adccommon::AdcCommon; |
| 21 | } | ||
| 22 | |||
| 23 | #[cfg(all(not(adc_f1), not(adc_v1)))] | ||
| 24 | pub trait Common { | ||
| 25 | fn regs() -> &'static crate::pac::adccommon::AdcCommon; | ||
| 26 | } | 36 | } |
| 27 | 37 | ||
| 28 | pub trait AdcPin<T: Instance> { | 38 | pub trait AdcPin<T: Instance> { |
| @@ -34,12 +44,11 @@ pub(crate) mod sealed { | |||
| 34 | } | 44 | } |
| 35 | } | 45 | } |
| 36 | 46 | ||
| 37 | #[cfg(not(any(adc_f1, adc_v2)))] | 47 | #[cfg(not(any(adc_f1, adc_v2, adc_v4)))] |
| 38 | pub trait Instance: sealed::Instance + 'static {} | 48 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {} |
| 39 | #[cfg(any(adc_f1, adc_v2))] | 49 | #[cfg(any(adc_f1, adc_v2, adc_v4))] |
| 40 | pub trait Instance: sealed::Instance + crate::rcc::RccPeripheral + 'static {} | 50 | pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {} |
| 41 | #[cfg(all(not(adc_f1), not(adc_v1)))] | 51 | |
| 42 | pub trait Common: sealed::Common + 'static {} | ||
| 43 | pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} | 52 | pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} |
| 44 | pub trait InternalChannel<T>: sealed::InternalChannel<T> {} | 53 | pub trait InternalChannel<T>: sealed::InternalChannel<T> {} |
| 45 | 54 | ||
| @@ -47,14 +56,14 @@ pub trait InternalChannel<T>: sealed::InternalChannel<T> {} | |||
| 47 | foreach_peripheral!( | 56 | foreach_peripheral!( |
| 48 | (adc, $inst:ident) => { | 57 | (adc, $inst:ident) => { |
| 49 | impl crate::adc::sealed::Instance for peripherals::$inst { | 58 | impl crate::adc::sealed::Instance for peripherals::$inst { |
| 50 | fn regs() -> &'static crate::pac::adc::Adc { | 59 | fn regs() -> crate::pac::adc::Adc { |
| 51 | &crate::pac::$inst | 60 | crate::pac::$inst |
| 52 | } | 61 | } |
| 53 | #[cfg(all(not(adc_f1), not(adc_v1)))] | 62 | #[cfg(all(not(adc_f1), not(adc_v1)))] |
| 54 | fn common_regs() -> &'static crate::pac::adccommon::AdcCommon { | 63 | fn common_regs() -> crate::pac::adccommon::AdcCommon { |
| 55 | foreach_peripheral!{ | 64 | foreach_peripheral!{ |
| 56 | (adccommon, $common_inst:ident) => { | 65 | (adccommon, $common_inst:ident) => { |
| 57 | return &crate::pac::$common_inst | 66 | return crate::pac::$common_inst |
| 58 | }; | 67 | }; |
| 59 | } | 68 | } |
| 60 | } | 69 | } |
| @@ -68,14 +77,14 @@ foreach_peripheral!( | |||
| 68 | foreach_peripheral!( | 77 | foreach_peripheral!( |
| 69 | (adc, ADC3) => { | 78 | (adc, ADC3) => { |
| 70 | impl crate::adc::sealed::Instance for peripherals::ADC3 { | 79 | impl crate::adc::sealed::Instance for peripherals::ADC3 { |
| 71 | fn regs() -> &'static crate::pac::adc::Adc { | 80 | fn regs() -> crate::pac::adc::Adc { |
| 72 | &crate::pac::ADC3 | 81 | crate::pac::ADC3 |
| 73 | } | 82 | } |
| 74 | #[cfg(all(not(adc_f1), not(adc_v1)))] | 83 | #[cfg(all(not(adc_f1), not(adc_v1)))] |
| 75 | fn common_regs() -> &'static crate::pac::adccommon::AdcCommon { | 84 | fn common_regs() -> crate::pac::adccommon::AdcCommon { |
| 76 | foreach_peripheral!{ | 85 | foreach_peripheral!{ |
| 77 | (adccommon, ADC3_COMMON) => { | 86 | (adccommon, ADC3_COMMON) => { |
| 78 | return &crate::pac::ADC3_COMMON | 87 | return crate::pac::ADC3_COMMON |
| 79 | }; | 88 | }; |
| 80 | } | 89 | } |
| 81 | } | 90 | } |
| @@ -85,14 +94,14 @@ foreach_peripheral!( | |||
| 85 | }; | 94 | }; |
| 86 | (adc, $inst:ident) => { | 95 | (adc, $inst:ident) => { |
| 87 | impl crate::adc::sealed::Instance for peripherals::$inst { | 96 | impl crate::adc::sealed::Instance for peripherals::$inst { |
| 88 | fn regs() -> &'static crate::pac::adc::Adc { | 97 | fn regs() -> crate::pac::adc::Adc { |
| 89 | &crate::pac::$inst | 98 | crate::pac::$inst |
| 90 | } | 99 | } |
| 91 | #[cfg(all(not(adc_f1), not(adc_v1)))] | 100 | #[cfg(all(not(adc_f1), not(adc_v1)))] |
| 92 | fn common_regs() -> &'static crate::pac::adccommon::AdcCommon { | 101 | fn common_regs() -> crate::pac::adccommon::AdcCommon { |
| 93 | foreach_peripheral!{ | 102 | foreach_peripheral!{ |
| 94 | (adccommon, ADC_COMMON) => { | 103 | (adccommon, ADC_COMMON) => { |
| 95 | return &crate::pac::ADC_COMMON | 104 | return crate::pac::ADC_COMMON |
| 96 | }; | 105 | }; |
| 97 | } | 106 | } |
| 98 | } | 107 | } |
| @@ -102,19 +111,6 @@ foreach_peripheral!( | |||
| 102 | }; | 111 | }; |
| 103 | ); | 112 | ); |
| 104 | 113 | ||
| 105 | #[cfg(all(not(adc_f1), not(adc_v1)))] | ||
| 106 | foreach_peripheral!( | ||
| 107 | (adccommon, $inst:ident) => { | ||
| 108 | impl sealed::Common for peripherals::$inst { | ||
| 109 | fn regs() -> &'static crate::pac::adccommon::AdcCommon { | ||
| 110 | &crate::pac::$inst | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | impl crate::adc::Common for peripherals::$inst {} | ||
| 115 | }; | ||
| 116 | ); | ||
| 117 | |||
| 118 | macro_rules! impl_adc_pin { | 114 | macro_rules! impl_adc_pin { |
| 119 | ($inst:ident, $pin:ident, $ch:expr) => { | 115 | ($inst:ident, $pin:ident, $ch:expr) => { |
| 120 | impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} | 116 | impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} |
diff --git a/embassy-stm32/src/adc/resolution.rs b/embassy-stm32/src/adc/resolution.rs new file mode 100644 index 000000000..62b52a46c --- /dev/null +++ b/embassy-stm32/src/adc/resolution.rs | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | #[cfg(any(adc_v2, adc_v3, adc_g0))] | ||
| 2 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
| 3 | pub enum Resolution { | ||
| 4 | TwelveBit, | ||
| 5 | TenBit, | ||
| 6 | EightBit, | ||
| 7 | SixBit, | ||
| 8 | } | ||
| 9 | |||
| 10 | #[cfg(adc_v4)] | ||
| 11 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
| 12 | pub enum Resolution { | ||
| 13 | SixteenBit, | ||
| 14 | FourteenBit, | ||
| 15 | TwelveBit, | ||
| 16 | TenBit, | ||
| 17 | EightBit, | ||
| 18 | } | ||
| 19 | |||
| 20 | impl Default for Resolution { | ||
| 21 | fn default() -> Self { | ||
| 22 | #[cfg(any(adc_v2, adc_v3, adc_g0))] | ||
| 23 | { | ||
| 24 | Self::TwelveBit | ||
| 25 | } | ||
| 26 | #[cfg(adc_v4)] | ||
| 27 | { | ||
| 28 | Self::SixteenBit | ||
| 29 | } | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | impl From<Resolution> for crate::pac::adc::vals::Res { | ||
| 34 | fn from(res: Resolution) -> crate::pac::adc::vals::Res { | ||
| 35 | match res { | ||
| 36 | #[cfg(adc_v4)] | ||
| 37 | Resolution::SixteenBit => crate::pac::adc::vals::Res::SIXTEENBIT, | ||
| 38 | #[cfg(adc_v4)] | ||
| 39 | Resolution::FourteenBit => crate::pac::adc::vals::Res::FOURTEENBITV, | ||
| 40 | Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT, | ||
| 41 | Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT, | ||
| 42 | Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT, | ||
| 43 | #[cfg(any(adc_v2, adc_v3, adc_g0))] | ||
| 44 | Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT, | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | impl Resolution { | ||
| 50 | pub fn to_max_count(&self) -> u32 { | ||
| 51 | match self { | ||
| 52 | #[cfg(adc_v4)] | ||
| 53 | Resolution::SixteenBit => (1 << 16) - 1, | ||
| 54 | #[cfg(adc_v4)] | ||
| 55 | Resolution::FourteenBit => (1 << 14) - 1, | ||
| 56 | Resolution::TwelveBit => (1 << 12) - 1, | ||
| 57 | Resolution::TenBit => (1 << 10) - 1, | ||
| 58 | Resolution::EightBit => (1 << 8) - 1, | ||
| 59 | #[cfg(any(adc_v2, adc_v3, adc_g0))] | ||
| 60 | Resolution::SixBit => (1 << 6) - 1, | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
diff --git a/embassy-stm32/src/adc/sample_time.rs b/embassy-stm32/src/adc/sample_time.rs new file mode 100644 index 000000000..60ba80048 --- /dev/null +++ b/embassy-stm32/src/adc/sample_time.rs | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | macro_rules! impl_sample_time { | ||
| 2 | ($default_doc:expr, $default:ident, $pac:ty, ($(($doc:expr, $variant:ident, $pac_variant:ident)),*)) => { | ||
| 3 | #[doc = concat!("ADC sample time\n\nThe default setting is ", $default_doc, " ADC clock cycles.")] | ||
| 4 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] | ||
| 5 | pub enum SampleTime { | ||
| 6 | $( | ||
| 7 | #[doc = concat!($doc, " ADC clock cycles.")] | ||
| 8 | $variant, | ||
| 9 | )* | ||
| 10 | } | ||
| 11 | |||
| 12 | impl From<SampleTime> for $pac { | ||
| 13 | fn from(sample_time: SampleTime) -> $pac { | ||
| 14 | match sample_time { | ||
| 15 | $(SampleTime::$variant => <$pac>::$pac_variant),* | ||
| 16 | } | ||
| 17 | } | ||
| 18 | } | ||
| 19 | |||
| 20 | impl Default for SampleTime { | ||
| 21 | fn default() -> Self { | ||
| 22 | Self::$default | ||
| 23 | } | ||
| 24 | } | ||
| 25 | }; | ||
| 26 | } | ||
| 27 | |||
| 28 | #[cfg(adc_f1)] | ||
| 29 | impl_sample_time!( | ||
| 30 | "1.5", | ||
| 31 | Cycles1_5, | ||
| 32 | crate::pac::adc::vals::SampleTime, | ||
| 33 | ( | ||
| 34 | ("1.5", Cycles1_5, CYCLES1_5), | ||
| 35 | ("7.5", Cycles7_5, CYCLES7_5), | ||
| 36 | ("13.5", Cycles13_5, CYCLES13_5), | ||
| 37 | ("28.5", Cycles28_5, CYCLES28_5), | ||
| 38 | ("41.5", Cycles41_5, CYCLES41_5), | ||
| 39 | ("55.5", Cycles55_5, CYCLES55_5), | ||
| 40 | ("71.5", Cycles71_5, CYCLES71_5), | ||
| 41 | ("239.5", Cycles239_5, CYCLES239_5) | ||
| 42 | ) | ||
| 43 | ); | ||
| 44 | |||
| 45 | #[cfg(adc_v2)] | ||
| 46 | impl_sample_time!( | ||
| 47 | "3", | ||
| 48 | Cycles3, | ||
| 49 | crate::pac::adc::vals::Smp, | ||
| 50 | ( | ||
| 51 | ("3", Cycles3, CYCLES3), | ||
| 52 | ("15", Cycles15, CYCLES15), | ||
| 53 | ("28", Cycles28, CYCLES28), | ||
| 54 | ("56", Cycles56, CYCLES56), | ||
| 55 | ("84", Cycles84, CYCLES84), | ||
| 56 | ("112", Cycles112, CYCLES112), | ||
| 57 | ("144", Cycles144, CYCLES144), | ||
| 58 | ("480", Cycles480, CYCLES480) | ||
| 59 | ) | ||
| 60 | ); | ||
| 61 | |||
| 62 | #[cfg(adc_v3)] | ||
| 63 | impl_sample_time!( | ||
| 64 | "2.5", | ||
| 65 | Cycles2_5, | ||
| 66 | crate::pac::adc::vals::SampleTime, | ||
| 67 | ( | ||
| 68 | ("2.5", Cycles2_5, CYCLES2_5), | ||
| 69 | ("6.5", Cycles6_5, CYCLES6_5), | ||
| 70 | ("12.5", Cycles12_5, CYCLES12_5), | ||
| 71 | ("24.5", Cycles24_5, CYCLES24_5), | ||
| 72 | ("47.5", Cycles47_5, CYCLES47_5), | ||
| 73 | ("92.5", Cycles92_5, CYCLES92_5), | ||
| 74 | ("247.5", Cycles247_5, CYCLES247_5), | ||
| 75 | ("640.5", Cycles640_5, CYCLES640_5) | ||
| 76 | ) | ||
| 77 | ); | ||
| 78 | |||
| 79 | #[cfg(adc_g0)] | ||
| 80 | impl_sample_time!( | ||
| 81 | "1.5", | ||
| 82 | Cycles1_5, | ||
| 83 | crate::pac::adc::vals::SampleTime, | ||
| 84 | ( | ||
| 85 | ("1.5", Cycles1_5, CYCLES1_5), | ||
| 86 | ("3.5", Cycles3_5, CYCLES3_5), | ||
| 87 | ("7.5", Cycles7_5, CYCLES7_5), | ||
| 88 | ("12.5", Cycles12_5, CYCLES12_5), | ||
| 89 | ("19.5", Cycles19_5, CYCLES19_5), | ||
| 90 | ("39.5", Cycles39_5, CYCLES39_5), | ||
| 91 | ("79.5", Cycles79_5, CYCLES79_5), | ||
| 92 | ("160.5", Cycles160_5, CYCLES160_5) | ||
| 93 | ) | ||
| 94 | ); | ||
| 95 | |||
| 96 | #[cfg(adc_v4)] | ||
| 97 | impl_sample_time!( | ||
| 98 | "1.5", | ||
| 99 | Cycles1_5, | ||
| 100 | crate::pac::adc::vals::Smp, | ||
| 101 | ( | ||
| 102 | ("1.5", Cycles1_5, CYCLES1_5), | ||
| 103 | ("2.5", Cycles2_5, CYCLES2_5), | ||
| 104 | ("8.5", Cycles8_5, CYCLES8_5), | ||
| 105 | ("16.5", Cycles16_5, CYCLES16_5), | ||
| 106 | ("32.5", Cycles32_5, CYCLES32_5), | ||
| 107 | ("64.5", Cycles64_5, CYCLES64_5), | ||
| 108 | ("387.5", Cycles387_5, CYCLES387_5), | ||
| 109 | ("810.5", Cycles810_5, CYCLES810_5) | ||
| 110 | ) | ||
| 111 | ); | ||
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index 53419c7f2..11a51f993 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.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 super::InternalChannel; | 4 | use super::InternalChannel; |
| 7 | use crate::adc::{AdcPin, Instance}; | 5 | use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; |
| 8 | use crate::peripherals::ADC1; | 6 | use crate::peripherals::ADC1; |
| 9 | use crate::time::Hertz; | 7 | use crate::time::Hertz; |
| 10 | use crate::Peripheral; | 8 | use crate::Peripheral; |
| @@ -17,39 +15,6 @@ pub const VREF_CALIB_MV: u32 = 3300; | |||
| 17 | /// ADC turn-on time | 15 | /// ADC turn-on time |
| 18 | pub const ADC_POWERUP_TIME_US: u32 = 3; | 16 | pub const ADC_POWERUP_TIME_US: u32 = 3; |
| 19 | 17 | ||
| 20 | pub enum Resolution { | ||
| 21 | TwelveBit, | ||
| 22 | TenBit, | ||
| 23 | EightBit, | ||
| 24 | SixBit, | ||
| 25 | } | ||
| 26 | |||
| 27 | impl Default for Resolution { | ||
| 28 | fn default() -> Self { | ||
| 29 | Self::TwelveBit | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | impl Resolution { | ||
| 34 | fn res(&self) -> crate::pac::adc::vals::Res { | ||
| 35 | match self { | ||
| 36 | Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT, | ||
| 37 | Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT, | ||
| 38 | Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT, | ||
| 39 | Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT, | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | pub fn to_max_count(&self) -> u32 { | ||
| 44 | match self { | ||
| 45 | Resolution::TwelveBit => (1 << 12) - 1, | ||
| 46 | Resolution::TenBit => (1 << 10) - 1, | ||
| 47 | Resolution::EightBit => (1 << 8) - 1, | ||
| 48 | Resolution::SixBit => (1 << 6) - 1, | ||
| 49 | } | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | pub struct VrefInt; | 18 | pub struct VrefInt; |
| 54 | impl InternalChannel<ADC1> for VrefInt {} | 19 | impl InternalChannel<ADC1> for VrefInt {} |
| 55 | impl super::sealed::InternalChannel<ADC1> for VrefInt { | 20 | impl super::sealed::InternalChannel<ADC1> for VrefInt { |
| @@ -94,42 +59,6 @@ impl super::sealed::InternalChannel<ADC1> for Vbat { | |||
| 94 | } | 59 | } |
| 95 | } | 60 | } |
| 96 | 61 | ||
| 97 | /// ADC sample time | ||
| 98 | /// | ||
| 99 | /// The default setting is 3 ADC clock cycles. | ||
| 100 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] | ||
| 101 | pub enum SampleTime { | ||
| 102 | Cycles3 = 0b000, | ||
| 103 | Cycles15 = 0b001, | ||
| 104 | Cycles28 = 0b010, | ||
| 105 | Cycles56 = 0b011, | ||
| 106 | Cycles85 = 0b100, | ||
| 107 | Cycles112 = 0b101, | ||
| 108 | Cycles144 = 0b110, | ||
| 109 | Cycles480 = 0b111, | ||
| 110 | } | ||
| 111 | |||
| 112 | impl SampleTime { | ||
| 113 | pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::Smp { | ||
| 114 | match self { | ||
| 115 | SampleTime::Cycles3 => crate::pac::adc::vals::Smp::CYCLES3, | ||
| 116 | SampleTime::Cycles15 => crate::pac::adc::vals::Smp::CYCLES15, | ||
| 117 | SampleTime::Cycles28 => crate::pac::adc::vals::Smp::CYCLES28, | ||
| 118 | SampleTime::Cycles56 => crate::pac::adc::vals::Smp::CYCLES56, | ||
| 119 | SampleTime::Cycles85 => crate::pac::adc::vals::Smp::CYCLES84, | ||
| 120 | SampleTime::Cycles112 => crate::pac::adc::vals::Smp::CYCLES112, | ||
| 121 | SampleTime::Cycles144 => crate::pac::adc::vals::Smp::CYCLES144, | ||
| 122 | SampleTime::Cycles480 => crate::pac::adc::vals::Smp::CYCLES480, | ||
| 123 | } | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | impl Default for SampleTime { | ||
| 128 | fn default() -> Self { | ||
| 129 | Self::Cycles3 | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | enum Prescaler { | 62 | enum Prescaler { |
| 134 | Div2, | 63 | Div2, |
| 135 | Div4, | 64 | Div4, |
| @@ -161,18 +90,12 @@ impl Prescaler { | |||
| 161 | } | 90 | } |
| 162 | } | 91 | } |
| 163 | 92 | ||
| 164 | pub struct Adc<'d, T: Instance> { | ||
| 165 | sample_time: SampleTime, | ||
| 166 | resolution: Resolution, | ||
| 167 | phantom: PhantomData<&'d mut T>, | ||
| 168 | } | ||
| 169 | |||
| 170 | impl<'d, T> Adc<'d, T> | 93 | impl<'d, T> Adc<'d, T> |
| 171 | where | 94 | where |
| 172 | T: Instance, | 95 | T: Instance, |
| 173 | { | 96 | { |
| 174 | pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { | 97 | pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { |
| 175 | into_ref!(_peri); | 98 | into_ref!(adc); |
| 176 | T::enable(); | 99 | T::enable(); |
| 177 | T::reset(); | 100 | T::reset(); |
| 178 | 101 | ||
| @@ -188,9 +111,8 @@ where | |||
| 188 | delay.delay_us(ADC_POWERUP_TIME_US); | 111 | delay.delay_us(ADC_POWERUP_TIME_US); |
| 189 | 112 | ||
| 190 | Self { | 113 | Self { |
| 114 | adc, | ||
| 191 | sample_time: Default::default(), | 115 | sample_time: Default::default(), |
| 192 | resolution: Resolution::default(), | ||
| 193 | phantom: PhantomData, | ||
| 194 | } | 116 | } |
| 195 | } | 117 | } |
| 196 | 118 | ||
| @@ -199,7 +121,9 @@ where | |||
| 199 | } | 121 | } |
| 200 | 122 | ||
| 201 | pub fn set_resolution(&mut self, resolution: Resolution) { | 123 | pub fn set_resolution(&mut self, resolution: Resolution) { |
| 202 | self.resolution = resolution; | 124 | unsafe { |
| 125 | T::regs().cr1().modify(|reg| reg.set_res(resolution.into())); | ||
| 126 | } | ||
| 203 | } | 127 | } |
| 204 | 128 | ||
| 205 | /// Enables internal voltage reference and returns [VrefInt], which can be used in | 129 | /// Enables internal voltage reference and returns [VrefInt], which can be used in |
| @@ -283,7 +207,6 @@ where | |||
| 283 | 207 | ||
| 284 | unsafe fn read_channel(&mut self, channel: u8) -> u16 { | 208 | unsafe fn read_channel(&mut self, channel: u8) -> u16 { |
| 285 | // Configure ADC | 209 | // Configure ADC |
| 286 | T::regs().cr1().modify(|reg| reg.set_res(self.resolution.res())); | ||
| 287 | 210 | ||
| 288 | // Select channel | 211 | // Select channel |
| 289 | T::regs().sqr3().write(|reg| reg.set_sq(0, channel)); | 212 | T::regs().sqr3().write(|reg| reg.set_sq(0, channel)); |
| @@ -297,14 +220,11 @@ where | |||
| 297 | } | 220 | } |
| 298 | 221 | ||
| 299 | unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { | 222 | unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { |
| 223 | let sample_time = sample_time.into(); | ||
| 300 | if ch <= 9 { | 224 | if ch <= 9 { |
| 301 | T::regs() | 225 | T::regs().smpr2().modify(|reg| reg.set_smp(ch as _, sample_time)); |
| 302 | .smpr2() | ||
| 303 | .modify(|reg| reg.set_smp(ch as _, sample_time.sample_time())); | ||
| 304 | } else { | 226 | } else { |
| 305 | T::regs() | 227 | T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time)); |
| 306 | .smpr1() | ||
| 307 | .modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time())); | ||
| 308 | } | 228 | } |
| 309 | } | 229 | } |
| 310 | } | 230 | } |
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index 816feeac7..8f81cb7a3 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs | |||
| @@ -1,9 +1,7 @@ | |||
| 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::Peripheral; | 5 | use crate::Peripheral; |
| 8 | 6 | ||
| 9 | /// Default VREF voltage used for sample conversion to millivolts. | 7 | /// Default VREF voltage used for sample conversion to millivolts. |
| @@ -24,39 +22,6 @@ fn enable() { | |||
| 24 | }); | 22 | }); |
| 25 | } | 23 | } |
| 26 | 24 | ||
| 27 | pub enum Resolution { | ||
| 28 | TwelveBit, | ||
| 29 | TenBit, | ||
| 30 | EightBit, | ||
| 31 | SixBit, | ||
| 32 | } | ||
| 33 | |||
| 34 | impl Default for Resolution { | ||
| 35 | fn default() -> Self { | ||
| 36 | Self::TwelveBit | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | impl Resolution { | ||
| 41 | fn res(&self) -> crate::pac::adc::vals::Res { | ||
| 42 | match self { | ||
| 43 | Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT, | ||
| 44 | Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT, | ||
| 45 | Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT, | ||
| 46 | Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT, | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | pub fn to_max_count(&self) -> u32 { | ||
| 51 | match self { | ||
| 52 | Resolution::TwelveBit => (1 << 12) - 1, | ||
| 53 | Resolution::TenBit => (1 << 10) - 1, | ||
| 54 | Resolution::EightBit => (1 << 8) - 1, | ||
| 55 | Resolution::SixBit => (1 << 6) - 1, | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | pub struct VrefInt; | 25 | pub struct VrefInt; |
| 61 | impl<T: Instance> AdcPin<T> for VrefInt {} | 26 | impl<T: Instance> AdcPin<T> for VrefInt {} |
| 62 | impl<T: Instance> super::sealed::AdcPin<T> for VrefInt { | 27 | impl<T: Instance> super::sealed::AdcPin<T> for VrefInt { |
| @@ -93,125 +58,9 @@ impl<T: Instance> super::sealed::AdcPin<T> for Vbat { | |||
| 93 | } | 58 | } |
| 94 | } | 59 | } |
| 95 | 60 | ||
| 96 | #[cfg(not(adc_g0))] | ||
| 97 | mod sample_time { | ||
| 98 | /// ADC sample time | ||
| 99 | /// | ||
| 100 | /// The default setting is 2.5 ADC clock cycles. | ||
| 101 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] | ||
| 102 | pub enum SampleTime { | ||
| 103 | /// 2.5 ADC clock cycles | ||
| 104 | Cycles2_5 = 0b000, | ||
| 105 | |||
| 106 | /// 6.5 ADC clock cycles | ||
| 107 | Cycles6_5 = 0b001, | ||
| 108 | |||
| 109 | /// 12.5 ADC clock cycles | ||
| 110 | Cycles12_5 = 0b010, | ||
| 111 | |||
| 112 | /// 24.5 ADC clock cycles | ||
| 113 | Cycles24_5 = 0b011, | ||
| 114 | |||
| 115 | /// 47.5 ADC clock cycles | ||
| 116 | Cycles47_5 = 0b100, | ||
| 117 | |||
| 118 | /// 92.5 ADC clock cycles | ||
| 119 | Cycles92_5 = 0b101, | ||
| 120 | |||
| 121 | /// 247.5 ADC clock cycles | ||
| 122 | Cycles247_5 = 0b110, | ||
| 123 | |||
| 124 | /// 640.5 ADC clock cycles | ||
| 125 | Cycles640_5 = 0b111, | ||
| 126 | } | ||
| 127 | |||
| 128 | impl SampleTime { | ||
| 129 | pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::SampleTime { | ||
| 130 | match self { | ||
| 131 | SampleTime::Cycles2_5 => crate::pac::adc::vals::SampleTime::CYCLES2_5, | ||
| 132 | SampleTime::Cycles6_5 => crate::pac::adc::vals::SampleTime::CYCLES6_5, | ||
| 133 | SampleTime::Cycles12_5 => crate::pac::adc::vals::SampleTime::CYCLES12_5, | ||
| 134 | SampleTime::Cycles24_5 => crate::pac::adc::vals::SampleTime::CYCLES24_5, | ||
| 135 | SampleTime::Cycles47_5 => crate::pac::adc::vals::SampleTime::CYCLES47_5, | ||
| 136 | SampleTime::Cycles92_5 => crate::pac::adc::vals::SampleTime::CYCLES92_5, | ||
| 137 | SampleTime::Cycles247_5 => crate::pac::adc::vals::SampleTime::CYCLES247_5, | ||
| 138 | SampleTime::Cycles640_5 => crate::pac::adc::vals::SampleTime::CYCLES640_5, | ||
| 139 | } | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | impl Default for SampleTime { | ||
| 144 | fn default() -> Self { | ||
| 145 | Self::Cycles2_5 | ||
| 146 | } | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | #[cfg(adc_g0)] | ||
| 151 | mod sample_time { | ||
| 152 | /// ADC sample time | ||
| 153 | /// | ||
| 154 | /// The default setting is 1.5 ADC clock cycles. | ||
| 155 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] | ||
| 156 | pub enum SampleTime { | ||
| 157 | /// 1.5 ADC clock cycles | ||
| 158 | Cycles1_5 = 0b000, | ||
| 159 | |||
| 160 | /// 3.5 ADC clock cycles | ||
| 161 | Cycles3_5 = 0b001, | ||
| 162 | |||
| 163 | /// 7.5 ADC clock cycles | ||
| 164 | Cycles7_5 = 0b010, | ||
| 165 | |||
| 166 | /// 12.5 ADC clock cycles | ||
| 167 | Cycles12_5 = 0b011, | ||
| 168 | |||
| 169 | /// 19.5 ADC clock cycles | ||
| 170 | Cycles19_5 = 0b100, | ||
| 171 | |||
| 172 | /// 39.5 ADC clock cycles | ||
| 173 | Cycles39_5 = 0b101, | ||
| 174 | |||
| 175 | /// 79.5 ADC clock cycles | ||
| 176 | Cycles79_5 = 0b110, | ||
| 177 | |||
| 178 | /// 160.5 ADC clock cycles | ||
| 179 | Cycles160_5 = 0b111, | ||
| 180 | } | ||
| 181 | |||
| 182 | impl SampleTime { | ||
| 183 | pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::SampleTime { | ||
| 184 | match self { | ||
| 185 | SampleTime::Cycles1_5 => crate::pac::adc::vals::SampleTime::CYCLES1_5, | ||
| 186 | SampleTime::Cycles3_5 => crate::pac::adc::vals::SampleTime::CYCLES3_5, | ||
| 187 | SampleTime::Cycles7_5 => crate::pac::adc::vals::SampleTime::CYCLES7_5, | ||
| 188 | SampleTime::Cycles12_5 => crate::pac::adc::vals::SampleTime::CYCLES12_5, | ||
| 189 | SampleTime::Cycles19_5 => crate::pac::adc::vals::SampleTime::CYCLES19_5, | ||
| 190 | SampleTime::Cycles39_5 => crate::pac::adc::vals::SampleTime::CYCLES39_5, | ||
| 191 | SampleTime::Cycles79_5 => crate::pac::adc::vals::SampleTime::CYCLES79_5, | ||
| 192 | SampleTime::Cycles160_5 => crate::pac::adc::vals::SampleTime::CYCLES160_5, | ||
| 193 | } | ||
| 194 | } | ||
| 195 | } | ||
| 196 | |||
| 197 | impl Default for SampleTime { | ||
| 198 | fn default() -> Self { | ||
| 199 | Self::Cycles1_5 | ||
| 200 | } | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | pub use sample_time::SampleTime; | ||
| 205 | |||
| 206 | pub struct Adc<'d, T: Instance> { | ||
| 207 | sample_time: SampleTime, | ||
| 208 | resolution: Resolution, | ||
| 209 | phantom: PhantomData<&'d mut T>, | ||
| 210 | } | ||
| 211 | |||
| 212 | impl<'d, T: Instance> Adc<'d, T> { | 61 | impl<'d, T: Instance> Adc<'d, T> { |
| 213 | pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { | 62 | pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { |
| 214 | into_ref!(_peri); | 63 | into_ref!(adc); |
| 215 | enable(); | 64 | enable(); |
| 216 | unsafe { | 65 | unsafe { |
| 217 | T::regs().cr().modify(|reg| { | 66 | T::regs().cr().modify(|reg| { |
| @@ -241,9 +90,8 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 241 | delay.delay_us(1); | 90 | delay.delay_us(1); |
| 242 | 91 | ||
| 243 | Self { | 92 | Self { |
| 93 | adc, | ||
| 244 | sample_time: Default::default(), | 94 | sample_time: Default::default(), |
| 245 | resolution: Resolution::default(), | ||
| 246 | phantom: PhantomData, | ||
| 247 | } | 95 | } |
| 248 | } | 96 | } |
| 249 | 97 | ||
| @@ -288,7 +136,12 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 288 | } | 136 | } |
| 289 | 137 | ||
| 290 | pub fn set_resolution(&mut self, resolution: Resolution) { | 138 | pub fn set_resolution(&mut self, resolution: Resolution) { |
| 291 | self.resolution = resolution; | 139 | unsafe { |
| 140 | #[cfg(not(stm32g0))] | ||
| 141 | T::regs().cfgr().modify(|reg| reg.set_res(resolution.into())); | ||
| 142 | #[cfg(stm32g0)] | ||
| 143 | T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into())); | ||
| 144 | } | ||
| 292 | } | 145 | } |
| 293 | 146 | ||
| 294 | /* | 147 | /* |
| @@ -340,12 +193,6 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 340 | // spin | 193 | // spin |
| 341 | } | 194 | } |
| 342 | 195 | ||
| 343 | // Configure ADC | ||
| 344 | #[cfg(not(stm32g0))] | ||
| 345 | T::regs().cfgr().modify(|reg| reg.set_res(self.resolution.res())); | ||
| 346 | #[cfg(stm32g0)] | ||
| 347 | T::regs().cfgr1().modify(|reg| reg.set_res(self.resolution.res())); | ||
| 348 | |||
| 349 | // Configure channel | 196 | // Configure channel |
| 350 | Self::set_channel_sample_time(pin.channel(), self.sample_time); | 197 | Self::set_channel_sample_time(pin.channel(), self.sample_time); |
| 351 | 198 | ||
| @@ -374,19 +221,16 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 374 | 221 | ||
| 375 | #[cfg(stm32g0)] | 222 | #[cfg(stm32g0)] |
| 376 | unsafe fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) { | 223 | unsafe fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) { |
| 377 | T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.sample_time())); | 224 | T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.into())); |
| 378 | } | 225 | } |
| 379 | 226 | ||
| 380 | #[cfg(not(stm32g0))] | 227 | #[cfg(not(stm32g0))] |
| 381 | unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { | 228 | unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { |
| 229 | let sample_time = sample_time.into(); | ||
| 382 | if ch <= 9 { | 230 | if ch <= 9 { |
| 383 | T::regs() | 231 | T::regs().smpr1().modify(|reg| reg.set_smp(ch as _, sample_time)); |
| 384 | .smpr1() | ||
| 385 | .modify(|reg| reg.set_smp(ch as _, sample_time.sample_time())); | ||
| 386 | } else { | 232 | } else { |
| 387 | T::regs() | 233 | T::regs().smpr2().modify(|reg| reg.set_smp((ch - 10) as _, sample_time)); |
| 388 | .smpr2() | ||
| 389 | .modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time())); | ||
| 390 | } | 234 | } |
| 391 | } | 235 | } |
| 392 | } | 236 | } |
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs index 2b8f10533..f5aa0e63d 100644 --- a/embassy-stm32/src/adc/v4.rs +++ b/embassy-stm32/src/adc/v4.rs | |||
| @@ -1,11 +1,9 @@ | |||
| 1 | use core::marker::PhantomData; | ||
| 2 | |||
| 3 | use atomic_polyfill::{AtomicU8, Ordering}; | 1 | use atomic_polyfill::{AtomicU8, Ordering}; |
| 4 | use embedded_hal_02::blocking::delay::DelayUs; | 2 | use embedded_hal_02::blocking::delay::DelayUs; |
| 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 | 5 | ||
| 8 | use super::{AdcPin, Instance, InternalChannel}; | 6 | use super::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; |
| 9 | use crate::time::Hertz; | 7 | use crate::time::Hertz; |
| 10 | use crate::{pac, Peripheral}; | 8 | use crate::{pac, Peripheral}; |
| 11 | 9 | ||
| @@ -14,42 +12,6 @@ pub const VREF_DEFAULT_MV: u32 = 3300; | |||
| 14 | /// VREF voltage used for factory calibration of VREFINTCAL register. | 12 | /// VREF voltage used for factory calibration of VREFINTCAL register. |
| 15 | pub const VREF_CALIB_MV: u32 = 3300; | 13 | pub const VREF_CALIB_MV: u32 = 3300; |
| 16 | 14 | ||
| 17 | pub enum Resolution { | ||
| 18 | SixteenBit, | ||
| 19 | FourteenBit, | ||
| 20 | TwelveBit, | ||
| 21 | TenBit, | ||
| 22 | EightBit, | ||
| 23 | } | ||
| 24 | |||
| 25 | impl Default for Resolution { | ||
| 26 | fn default() -> Self { | ||
| 27 | Self::SixteenBit | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | impl Resolution { | ||
| 32 | fn res(&self) -> pac::adc::vals::Res { | ||
| 33 | match self { | ||
| 34 | Resolution::SixteenBit => pac::adc::vals::Res::SIXTEENBIT, | ||
| 35 | Resolution::FourteenBit => pac::adc::vals::Res::FOURTEENBITV, | ||
| 36 | Resolution::TwelveBit => pac::adc::vals::Res::TWELVEBITV, | ||
| 37 | Resolution::TenBit => pac::adc::vals::Res::TENBIT, | ||
| 38 | Resolution::EightBit => pac::adc::vals::Res::EIGHTBIT, | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | pub fn to_max_count(&self) -> u32 { | ||
| 43 | match self { | ||
| 44 | Resolution::SixteenBit => (1 << 16) - 1, | ||
| 45 | Resolution::FourteenBit => (1 << 14) - 1, | ||
| 46 | Resolution::TwelveBit => (1 << 12) - 1, | ||
| 47 | Resolution::TenBit => (1 << 10) - 1, | ||
| 48 | Resolution::EightBit => (1 << 8) - 1, | ||
| 49 | } | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | // NOTE: Vrefint/Temperature/Vbat are only available on ADC3 on H7, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs | 15 | // NOTE: Vrefint/Temperature/Vbat are only available on ADC3 on H7, this currently cannot be modeled with stm32-data, so these are available from the software on all ADCs |
| 54 | pub struct VrefInt; | 16 | pub struct VrefInt; |
| 55 | impl<T: Instance> InternalChannel<T> for VrefInt {} | 17 | impl<T: Instance> InternalChannel<T> for VrefInt {} |
| @@ -193,57 +155,6 @@ foreach_peripheral!( | |||
| 193 | }; | 155 | }; |
| 194 | ); | 156 | ); |
| 195 | 157 | ||
| 196 | /// ADC sample time | ||
| 197 | /// | ||
| 198 | /// The default setting is 2.5 ADC clock cycles. | ||
| 199 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] | ||
| 200 | pub enum SampleTime { | ||
| 201 | /// 1.5 ADC clock cycles | ||
| 202 | Cycles1_5, | ||
| 203 | |||
| 204 | /// 2.5 ADC clock cycles | ||
| 205 | Cycles2_5, | ||
| 206 | |||
| 207 | /// 8.5 ADC clock cycles | ||
| 208 | Cycles8_5, | ||
| 209 | |||
| 210 | /// 16.5 ADC clock cycles | ||
| 211 | Cycles16_5, | ||
| 212 | |||
| 213 | /// 32.5 ADC clock cycles | ||
| 214 | Cycles32_5, | ||
| 215 | |||
| 216 | /// 64.5 ADC clock cycles | ||
| 217 | Cycles64_5, | ||
| 218 | |||
| 219 | /// 387.5 ADC clock cycles | ||
| 220 | Cycles387_5, | ||
| 221 | |||
| 222 | /// 810.5 ADC clock cycles | ||
| 223 | Cycles810_5, | ||
| 224 | } | ||
| 225 | |||
| 226 | impl SampleTime { | ||
| 227 | pub(crate) fn sample_time(&self) -> pac::adc::vals::Smp { | ||
| 228 | match self { | ||
| 229 | SampleTime::Cycles1_5 => pac::adc::vals::Smp::CYCLES1_5, | ||
| 230 | SampleTime::Cycles2_5 => pac::adc::vals::Smp::CYCLES2_5, | ||
| 231 | SampleTime::Cycles8_5 => pac::adc::vals::Smp::CYCLES8_5, | ||
| 232 | SampleTime::Cycles16_5 => pac::adc::vals::Smp::CYCLES16_5, | ||
| 233 | SampleTime::Cycles32_5 => pac::adc::vals::Smp::CYCLES32_5, | ||
| 234 | SampleTime::Cycles64_5 => pac::adc::vals::Smp::CYCLES64_5, | ||
| 235 | SampleTime::Cycles387_5 => pac::adc::vals::Smp::CYCLES387_5, | ||
| 236 | SampleTime::Cycles810_5 => pac::adc::vals::Smp::CYCLES810_5, | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | impl Default for SampleTime { | ||
| 242 | fn default() -> Self { | ||
| 243 | Self::Cycles1_5 | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 | // NOTE (unused): The prescaler enum closely copies the hardware capabilities, | 158 | // NOTE (unused): The prescaler enum closely copies the hardware capabilities, |
| 248 | // but high prescaling doesn't make a lot of sense in the current implementation and is ommited. | 159 | // but high prescaling doesn't make a lot of sense in the current implementation and is ommited. |
| 249 | #[allow(unused)] | 160 | #[allow(unused)] |
| @@ -312,15 +223,9 @@ impl Prescaler { | |||
| 312 | } | 223 | } |
| 313 | } | 224 | } |
| 314 | 225 | ||
| 315 | pub struct Adc<'d, T: Instance> { | 226 | impl<'d, T: Instance> Adc<'d, T> { |
| 316 | sample_time: SampleTime, | 227 | pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self { |
| 317 | resolution: Resolution, | 228 | embassy_hal_common::into_ref!(adc); |
| 318 | phantom: PhantomData<&'d mut T>, | ||
| 319 | } | ||
| 320 | |||
| 321 | impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> { | ||
| 322 | pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self { | ||
| 323 | embassy_hal_common::into_ref!(_peri); | ||
| 324 | T::enable(); | 229 | T::enable(); |
| 325 | T::reset(); | 230 | T::reset(); |
| 326 | 231 | ||
| @@ -350,9 +255,8 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> { | |||
| 350 | } | 255 | } |
| 351 | 256 | ||
| 352 | let mut s = Self { | 257 | let mut s = Self { |
| 258 | adc, | ||
| 353 | sample_time: Default::default(), | 259 | sample_time: Default::default(), |
| 354 | resolution: Resolution::default(), | ||
| 355 | phantom: PhantomData, | ||
| 356 | }; | 260 | }; |
| 357 | s.power_up(delay); | 261 | s.power_up(delay); |
| 358 | s.configure_differential_inputs(); | 262 | s.configure_differential_inputs(); |
| @@ -454,7 +358,9 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> { | |||
| 454 | } | 358 | } |
| 455 | 359 | ||
| 456 | pub fn set_resolution(&mut self, resolution: Resolution) { | 360 | pub fn set_resolution(&mut self, resolution: Resolution) { |
| 457 | self.resolution = resolution; | 361 | unsafe { |
| 362 | T::regs().cfgr().modify(|reg| reg.set_res(resolution.into())); | ||
| 363 | } | ||
| 458 | } | 364 | } |
| 459 | 365 | ||
| 460 | /// Perform a single conversion. | 366 | /// Perform a single conversion. |
| @@ -495,9 +401,6 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> { | |||
| 495 | } | 401 | } |
| 496 | 402 | ||
| 497 | unsafe fn read_channel(&mut self, channel: u8) -> u16 { | 403 | unsafe fn read_channel(&mut self, channel: u8) -> u16 { |
| 498 | // Configure ADC | ||
| 499 | T::regs().cfgr().modify(|reg| reg.set_res(self.resolution.res())); | ||
| 500 | |||
| 501 | // Configure channel | 404 | // Configure channel |
| 502 | Self::set_channel_sample_time(channel, self.sample_time); | 405 | Self::set_channel_sample_time(channel, self.sample_time); |
| 503 | 406 | ||
| @@ -514,14 +417,11 @@ impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> { | |||
| 514 | } | 417 | } |
| 515 | 418 | ||
| 516 | unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { | 419 | unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { |
| 420 | let sample_time = sample_time.into(); | ||
| 517 | if ch <= 9 { | 421 | if ch <= 9 { |
| 518 | T::regs() | 422 | T::regs().smpr(0).modify(|reg| reg.set_smp(ch as _, sample_time)); |
| 519 | .smpr(0) | ||
| 520 | .modify(|reg| reg.set_smp(ch as _, sample_time.sample_time())); | ||
| 521 | } else { | 423 | } else { |
| 522 | T::regs() | 424 | T::regs().smpr(1).modify(|reg| reg.set_smp((ch - 10) as _, sample_time)); |
| 523 | .smpr(1) | ||
| 524 | .modify(|reg| reg.set_smp((ch - 10) as _, sample_time.sample_time())); | ||
| 525 | } | 425 | } |
| 526 | } | 426 | } |
| 527 | } | 427 | } |
