diff options
| author | Ben Gamari <[email protected]> | 2021-08-30 15:34:37 -0400 |
|---|---|---|
| committer | Ben Gamari <[email protected]> | 2021-09-28 21:19:10 -0400 |
| commit | aa4069fe1032c68977bea9c006a3be83304d8427 (patch) | |
| tree | 3fb5aa7ceb3b7c4c8e3b6f3b8008abc268bce3b0 | |
| parent | e2e0464d04ba2fa16ec5217dd651dae157279efb (diff) | |
stm32/adc: Fix ADC support for STM32G0
| -rw-r--r-- | embassy-stm32/src/adc/g0.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/mod.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/v3.rs | 177 |
3 files changed, 139 insertions, 41 deletions
diff --git a/embassy-stm32/src/adc/g0.rs b/embassy-stm32/src/adc/g0.rs deleted file mode 100644 index 8b1378917..000000000 --- a/embassy-stm32/src/adc/g0.rs +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | |||
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index 9955502a6..af98d1777 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | #[cfg_attr(adc_v3, path = "v3.rs")] | 3 | #[cfg_attr(adc_v3, path = "v3.rs")] |
| 4 | #[cfg_attr(adc_g0, path = "g0.rs")] | 4 | #[cfg_attr(adc_g0, path = "v3.rs")] |
| 5 | mod _version; | 5 | mod _version; |
| 6 | 6 | ||
| 7 | #[allow(unused)] | 7 | #[allow(unused)] |
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index d80c9ffc0..5fa5b9bc1 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs | |||
| @@ -43,7 +43,11 @@ pub struct Vref; | |||
| 43 | impl<T: Instance> AdcPin<T> for Vref {} | 43 | impl<T: Instance> AdcPin<T> for Vref {} |
| 44 | impl<T: Instance> super::sealed::AdcPin<T> for Vref { | 44 | impl<T: Instance> super::sealed::AdcPin<T> for Vref { |
| 45 | fn channel(&self) -> u8 { | 45 | fn channel(&self) -> u8 { |
| 46 | 0 | 46 | #[cfg(not(rcc_g0))] |
| 47 | let val = 0; | ||
| 48 | #[cfg(rcc_g0)] | ||
| 49 | let val = 13; | ||
| 50 | val | ||
| 47 | } | 51 | } |
| 48 | } | 52 | } |
| 49 | 53 | ||
| @@ -51,7 +55,11 @@ pub struct Temperature; | |||
| 51 | impl<T: Instance> AdcPin<T> for Temperature {} | 55 | impl<T: Instance> AdcPin<T> for Temperature {} |
| 52 | impl<T: Instance> super::sealed::AdcPin<T> for Temperature { | 56 | impl<T: Instance> super::sealed::AdcPin<T> for Temperature { |
| 53 | fn channel(&self) -> u8 { | 57 | fn channel(&self) -> u8 { |
| 54 | 17 | 58 | #[cfg(not(rcc_g0))] |
| 59 | let val = 17; | ||
| 60 | #[cfg(rcc_g0)] | ||
| 61 | let val = 12; | ||
| 62 | val | ||
| 55 | } | 63 | } |
| 56 | } | 64 | } |
| 57 | 65 | ||
| @@ -59,61 +67,124 @@ pub struct Vbat; | |||
| 59 | impl<T: Instance> AdcPin<T> for Vbat {} | 67 | impl<T: Instance> AdcPin<T> for Vbat {} |
| 60 | impl<T: Instance> super::sealed::AdcPin<T> for Vbat { | 68 | impl<T: Instance> super::sealed::AdcPin<T> for Vbat { |
| 61 | fn channel(&self) -> u8 { | 69 | fn channel(&self) -> u8 { |
| 62 | 18 | 70 | #[cfg(not(rcc_g0))] |
| 71 | let val = 18; | ||
| 72 | #[cfg(rcc_g0)] | ||
| 73 | let val = 14; | ||
| 74 | val | ||
| 63 | } | 75 | } |
| 64 | } | 76 | } |
| 65 | 77 | ||
| 66 | /// ADC sample time | 78 | #[cfg(not(adc_g0))] |
| 67 | /// | 79 | mod sample_time { |
| 68 | /// The default setting is 2.5 ADC clock cycles. | 80 | /// ADC sample time |
| 69 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] | 81 | /// |
| 70 | pub enum SampleTime { | 82 | /// The default setting is 2.5 ADC clock cycles. |
| 71 | /// 2.5 ADC clock cycles | 83 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] |
| 72 | Cycles2_5 = 0b000, | 84 | pub enum SampleTime { |
| 85 | /// 2.5 ADC clock cycles | ||
| 86 | Cycles2_5 = 0b000, | ||
| 73 | 87 | ||
| 74 | /// 6.5 ADC clock cycles | 88 | /// 6.5 ADC clock cycles |
| 75 | Cycles6_5 = 0b001, | 89 | Cycles6_5 = 0b001, |
| 76 | 90 | ||
| 77 | /// 12.5 ADC clock cycles | 91 | /// 12.5 ADC clock cycles |
| 78 | Cycles12_5 = 0b010, | 92 | Cycles12_5 = 0b010, |
| 79 | 93 | ||
| 80 | /// 24.5 ADC clock cycles | 94 | /// 24.5 ADC clock cycles |
| 81 | Cycles24_5 = 0b011, | 95 | Cycles24_5 = 0b011, |
| 82 | 96 | ||
| 83 | /// 47.5 ADC clock cycles | 97 | /// 47.5 ADC clock cycles |
| 84 | Cycles47_5 = 0b100, | 98 | Cycles47_5 = 0b100, |
| 85 | 99 | ||
| 86 | /// 92.5 ADC clock cycles | 100 | /// 92.5 ADC clock cycles |
| 87 | Cycles92_5 = 0b101, | 101 | Cycles92_5 = 0b101, |
| 88 | 102 | ||
| 89 | /// 247.5 ADC clock cycles | 103 | /// 247.5 ADC clock cycles |
| 90 | Cycles247_5 = 0b110, | 104 | Cycles247_5 = 0b110, |
| 91 | 105 | ||
| 92 | /// 640.5 ADC clock cycles | 106 | /// 640.5 ADC clock cycles |
| 93 | Cycles640_5 = 0b111, | 107 | Cycles640_5 = 0b111, |
| 94 | } | 108 | } |
| 95 | 109 | ||
| 96 | impl SampleTime { | 110 | impl SampleTime { |
| 97 | fn sample_time(&self) -> crate::pac::adc::vals::SampleTime { | 111 | pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::SampleTime { |
| 98 | match self { | 112 | match self { |
| 99 | SampleTime::Cycles2_5 => crate::pac::adc::vals::SampleTime::CYCLES2_5, | 113 | SampleTime::Cycles2_5 => crate::pac::adc::vals::SampleTime::CYCLES2_5, |
| 100 | SampleTime::Cycles6_5 => crate::pac::adc::vals::SampleTime::CYCLES6_5, | 114 | SampleTime::Cycles6_5 => crate::pac::adc::vals::SampleTime::CYCLES6_5, |
| 101 | SampleTime::Cycles12_5 => crate::pac::adc::vals::SampleTime::CYCLES12_5, | 115 | SampleTime::Cycles12_5 => crate::pac::adc::vals::SampleTime::CYCLES12_5, |
| 102 | SampleTime::Cycles24_5 => crate::pac::adc::vals::SampleTime::CYCLES24_5, | 116 | SampleTime::Cycles24_5 => crate::pac::adc::vals::SampleTime::CYCLES24_5, |
| 103 | SampleTime::Cycles47_5 => crate::pac::adc::vals::SampleTime::CYCLES47_5, | 117 | SampleTime::Cycles47_5 => crate::pac::adc::vals::SampleTime::CYCLES47_5, |
| 104 | SampleTime::Cycles92_5 => crate::pac::adc::vals::SampleTime::CYCLES92_5, | 118 | SampleTime::Cycles92_5 => crate::pac::adc::vals::SampleTime::CYCLES92_5, |
| 105 | SampleTime::Cycles247_5 => crate::pac::adc::vals::SampleTime::CYCLES247_5, | 119 | SampleTime::Cycles247_5 => crate::pac::adc::vals::SampleTime::CYCLES247_5, |
| 106 | SampleTime::Cycles640_5 => crate::pac::adc::vals::SampleTime::CYCLES640_5, | 120 | SampleTime::Cycles640_5 => crate::pac::adc::vals::SampleTime::CYCLES640_5, |
| 121 | } | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | impl Default for SampleTime { | ||
| 126 | fn default() -> Self { | ||
| 127 | Self::Cycles2_5 | ||
| 107 | } | 128 | } |
| 108 | } | 129 | } |
| 109 | } | 130 | } |
| 110 | 131 | ||
| 111 | impl Default for SampleTime { | 132 | #[cfg(adc_g0)] |
| 112 | fn default() -> Self { | 133 | mod sample_time { |
| 113 | Self::Cycles2_5 | 134 | /// ADC sample time |
| 135 | /// | ||
| 136 | /// The default setting is 1.5 ADC clock cycles. | ||
| 137 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] | ||
| 138 | pub enum SampleTime { | ||
| 139 | /// 1.5 ADC clock cycles | ||
| 140 | Cycles1_5 = 0b000, | ||
| 141 | |||
| 142 | /// 3.5 ADC clock cycles | ||
| 143 | Cycles3_5 = 0b001, | ||
| 144 | |||
| 145 | /// 7.5 ADC clock cycles | ||
| 146 | Cycles7_5 = 0b010, | ||
| 147 | |||
| 148 | /// 12.5 ADC clock cycles | ||
| 149 | Cycles12_5 = 0b011, | ||
| 150 | |||
| 151 | /// 19.5 ADC clock cycles | ||
| 152 | Cycles19_5 = 0b100, | ||
| 153 | |||
| 154 | /// 39.5 ADC clock cycles | ||
| 155 | Cycles39_5 = 0b101, | ||
| 156 | |||
| 157 | /// 79.5 ADC clock cycles | ||
| 158 | Cycles79_5 = 0b110, | ||
| 159 | |||
| 160 | /// 160.5 ADC clock cycles | ||
| 161 | Cycles160_5 = 0b111, | ||
| 162 | } | ||
| 163 | |||
| 164 | impl SampleTime { | ||
| 165 | pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::SampleTime { | ||
| 166 | match self { | ||
| 167 | SampleTime::Cycles1_5 => crate::pac::adc::vals::SampleTime::CYCLES1_5, | ||
| 168 | SampleTime::Cycles3_5 => crate::pac::adc::vals::SampleTime::CYCLES3_5, | ||
| 169 | SampleTime::Cycles7_5 => crate::pac::adc::vals::SampleTime::CYCLES7_5, | ||
| 170 | SampleTime::Cycles12_5 => crate::pac::adc::vals::SampleTime::CYCLES12_5, | ||
| 171 | SampleTime::Cycles19_5 => crate::pac::adc::vals::SampleTime::CYCLES19_5, | ||
| 172 | SampleTime::Cycles39_5 => crate::pac::adc::vals::SampleTime::CYCLES39_5, | ||
| 173 | SampleTime::Cycles79_5 => crate::pac::adc::vals::SampleTime::CYCLES79_5, | ||
| 174 | SampleTime::Cycles160_5 => crate::pac::adc::vals::SampleTime::CYCLES160_5, | ||
| 175 | } | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | impl Default for SampleTime { | ||
| 180 | fn default() -> Self { | ||
| 181 | Self::Cycles1_5 | ||
| 182 | } | ||
| 114 | } | 183 | } |
| 115 | } | 184 | } |
| 116 | 185 | ||
| 186 | pub use sample_time::SampleTime; | ||
| 187 | |||
| 117 | pub struct Adc<'d, T: Instance> { | 188 | pub struct Adc<'d, T: Instance> { |
| 118 | sample_time: SampleTime, | 189 | sample_time: SampleTime, |
| 119 | calibrated_vdda: u32, | 190 | calibrated_vdda: u32, |
| @@ -126,14 +197,24 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 126 | unborrow!(_peri); | 197 | unborrow!(_peri); |
| 127 | unsafe { | 198 | unsafe { |
| 128 | T::regs().cr().modify(|reg| { | 199 | T::regs().cr().modify(|reg| { |
| 200 | #[cfg(not(adc_g0))] | ||
| 129 | reg.set_deeppwd(false); | 201 | reg.set_deeppwd(false); |
| 130 | reg.set_advregen(true); | 202 | reg.set_advregen(true); |
| 131 | }); | 203 | }); |
| 204 | |||
| 205 | #[cfg(adc_g0)] | ||
| 206 | T::regs().cfgr1().modify(|reg| { | ||
| 207 | reg.set_chselrmod(true); | ||
| 208 | }); | ||
| 132 | } | 209 | } |
| 133 | 210 | ||
| 134 | delay.delay_us(20); | 211 | delay.delay_us(20); |
| 135 | 212 | ||
| 136 | unsafe { | 213 | unsafe { |
| 214 | T::regs().cr().modify(|reg| { | ||
| 215 | reg.set_adcal(true); | ||
| 216 | }); | ||
| 217 | |||
| 137 | while T::regs().cr().read().adcal() { | 218 | while T::regs().cr().read().adcal() { |
| 138 | // spin | 219 | // spin |
| 139 | } | 220 | } |
| @@ -270,15 +351,25 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 270 | } | 351 | } |
| 271 | 352 | ||
| 272 | // Configure ADC | 353 | // Configure ADC |
| 354 | #[cfg(not(rcc_g0))] | ||
| 273 | T::regs() | 355 | T::regs() |
| 274 | .cfgr() | 356 | .cfgr() |
| 275 | .modify(|reg| reg.set_res(self.resolution.res())); | 357 | .modify(|reg| reg.set_res(self.resolution.res())); |
| 358 | #[cfg(rcc_g0)] | ||
| 359 | T::regs() | ||
| 360 | .cfgr1() | ||
| 361 | .modify(|reg| reg.set_res(self.resolution.res())); | ||
| 276 | 362 | ||
| 277 | // Configure channel | 363 | // Configure channel |
| 278 | Self::set_channel_sample_time(pin.channel(), self.sample_time); | 364 | Self::set_channel_sample_time(pin.channel(), self.sample_time); |
| 279 | 365 | ||
| 280 | // Select channel | 366 | // Select channel |
| 367 | #[cfg(not(rcc_g0))] | ||
| 281 | T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel())); | 368 | T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel())); |
| 369 | #[cfg(rcc_g0)] | ||
| 370 | T::regs() | ||
| 371 | .chselr() | ||
| 372 | .write(|reg| reg.set_chsel(pin.channel() as u32)); | ||
| 282 | 373 | ||
| 283 | // Some models are affected by an erratum: | 374 | // Some models are affected by an erratum: |
| 284 | // If we perform conversions slower than 1 kHz, the first read ADC value can be | 375 | // If we perform conversions slower than 1 kHz, the first read ADC value can be |
| @@ -297,6 +388,14 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 297 | } | 388 | } |
| 298 | } | 389 | } |
| 299 | 390 | ||
| 391 | #[cfg(rcc_g0)] | ||
| 392 | unsafe fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) { | ||
| 393 | T::regs() | ||
| 394 | .smpr() | ||
| 395 | .modify(|reg| reg.set_smp1(sample_time.sample_time())); | ||
| 396 | } | ||
| 397 | |||
| 398 | #[cfg(not(rcc_g0))] | ||
| 300 | unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { | 399 | unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { |
| 301 | if ch <= 9 { | 400 | if ch <= 9 { |
| 302 | T::regs() | 401 | T::regs() |
