diff options
| author | xoviat <[email protected]> | 2025-12-06 12:17:00 -0600 |
|---|---|---|
| committer | xoviat <[email protected]> | 2025-12-06 12:17:00 -0600 |
| commit | 4f66b2f2090e2fcfd7d92f9ebd07cc9048eb70d7 (patch) | |
| tree | 8cc00b76c76aa08358e0959496cd7e1a77c6da76 /embassy-stm32/src/adc/v2.rs | |
| parent | 4160184b314473c582ca8c4f50b880f4e42cf6e3 (diff) | |
adc: type-erase regs instance
Diffstat (limited to 'embassy-stm32/src/adc/v2.rs')
| -rw-r--r-- | embassy-stm32/src/adc/v2.rs | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index e18098281..b026383d5 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | use core::sync::atomic::{Ordering, compiler_fence}; | 1 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 2 | 2 | ||
| 3 | use super::{ConversionMode, Temperature, Vbat, VrefInt, blocking_delay_us}; | 3 | use super::{ConversionMode, Temperature, Vbat, VrefInt, blocking_delay_us}; |
| 4 | use crate::adc::{Adc, Instance, Resolution, SampleTime}; | 4 | use crate::adc::{Adc, AdcRegs, Instance, Resolution, SampleTime}; |
| 5 | use crate::pac::adc::vals; | 5 | use crate::pac::adc::vals; |
| 6 | pub use crate::pac::adccommon::vals::Adcpre; | 6 | pub use crate::pac::adccommon::vals::Adcpre; |
| 7 | use crate::time::Hertz; | 7 | use crate::time::Hertz; |
| @@ -74,28 +74,28 @@ pub struct AdcConfig { | |||
| 74 | pub resolution: Option<Resolution>, | 74 | pub resolution: Option<Resolution>, |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | impl<T: Instance> super::SealedAnyInstance for T { | 77 | impl super::AdcRegs for crate::pac::adc::Adc { |
| 78 | fn dr() -> *mut u16 { | 78 | fn data(&self) -> *mut u16 { |
| 79 | T::regs().dr().as_ptr() as *mut u16 | 79 | crate::pac::adc::Adc::dr(*self).as_ptr() as *mut u16 |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | fn enable() { | 82 | fn enable(&self) { |
| 83 | T::regs().cr2().modify(|reg| { | 83 | self.cr2().modify(|reg| { |
| 84 | reg.set_adon(true); | 84 | reg.set_adon(true); |
| 85 | }); | 85 | }); |
| 86 | 86 | ||
| 87 | blocking_delay_us(3); | 87 | blocking_delay_us(3); |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | fn start() { | 90 | fn start(&self) { |
| 91 | // Begin ADC conversions | 91 | // Begin ADC conversions |
| 92 | T::regs().cr2().modify(|reg| { | 92 | self.cr2().modify(|reg| { |
| 93 | reg.set_swstart(true); | 93 | reg.set_swstart(true); |
| 94 | }); | 94 | }); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | fn stop() { | 97 | fn stop(&self) { |
| 98 | let r = T::regs(); | 98 | let r = self; |
| 99 | 99 | ||
| 100 | // Stop ADC | 100 | // Stop ADC |
| 101 | r.cr2().modify(|reg| { | 101 | r.cr2().modify(|reg| { |
| @@ -114,36 +114,34 @@ impl<T: Instance> super::SealedAnyInstance for T { | |||
| 114 | w.set_ovrie(false); | 114 | w.set_ovrie(false); |
| 115 | }); | 115 | }); |
| 116 | 116 | ||
| 117 | clear_interrupt_flags(r); | 117 | clear_interrupt_flags(*r); |
| 118 | 118 | ||
| 119 | compiler_fence(Ordering::SeqCst); | 119 | compiler_fence(Ordering::SeqCst); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | fn convert() -> u16 { | 122 | fn convert(&self) { |
| 123 | // clear end of conversion flag | 123 | // clear end of conversion flag |
| 124 | T::regs().sr().modify(|reg| { | 124 | self.sr().modify(|reg| { |
| 125 | reg.set_eoc(false); | 125 | reg.set_eoc(false); |
| 126 | }); | 126 | }); |
| 127 | 127 | ||
| 128 | // Start conversion | 128 | // Start conversion |
| 129 | T::regs().cr2().modify(|reg| { | 129 | self.cr2().modify(|reg| { |
| 130 | reg.set_swstart(true); | 130 | reg.set_swstart(true); |
| 131 | }); | 131 | }); |
| 132 | 132 | ||
| 133 | while T::regs().sr().read().strt() == false { | 133 | while self.sr().read().strt() == false { |
| 134 | // spin //wait for actual start | 134 | // spin //wait for actual start |
| 135 | } | 135 | } |
| 136 | while T::regs().sr().read().eoc() == false { | 136 | while self.sr().read().eoc() == false { |
| 137 | // spin //wait for finish | 137 | // spin //wait for finish |
| 138 | } | 138 | } |
| 139 | |||
| 140 | T::regs().dr().read().0 as u16 | ||
| 141 | } | 139 | } |
| 142 | 140 | ||
| 143 | fn configure_dma(conversion_mode: ConversionMode) { | 141 | fn configure_dma(&self, conversion_mode: ConversionMode) { |
| 144 | match conversion_mode { | 142 | match conversion_mode { |
| 145 | ConversionMode::Repeated(_) => { | 143 | ConversionMode::Repeated(_) => { |
| 146 | let r = T::regs(); | 144 | let r = self; |
| 147 | 145 | ||
| 148 | // Clear all interrupts | 146 | // Clear all interrupts |
| 149 | r.sr().modify(|regs| { | 147 | r.sr().modify(|regs| { |
| @@ -177,25 +175,25 @@ impl<T: Instance> super::SealedAnyInstance for T { | |||
| 177 | } | 175 | } |
| 178 | } | 176 | } |
| 179 | 177 | ||
| 180 | fn configure_sequence(sequence: impl ExactSizeIterator<Item = ((u8, bool), SampleTime)>) { | 178 | fn configure_sequence(&self, sequence: impl ExactSizeIterator<Item = ((u8, bool), SampleTime)>) { |
| 181 | T::regs().cr2().modify(|reg| { | 179 | self.cr2().modify(|reg| { |
| 182 | reg.set_adon(true); | 180 | reg.set_adon(true); |
| 183 | }); | 181 | }); |
| 184 | 182 | ||
| 185 | // Check the sequence is long enough | 183 | // Check the sequence is long enough |
| 186 | T::regs().sqr1().modify(|r| { | 184 | self.sqr1().modify(|r| { |
| 187 | r.set_l((sequence.len() - 1).try_into().unwrap()); | 185 | r.set_l((sequence.len() - 1).try_into().unwrap()); |
| 188 | }); | 186 | }); |
| 189 | 187 | ||
| 190 | for (i, ((ch, _), sample_time)) in sequence.enumerate() { | 188 | for (i, ((ch, _), sample_time)) in sequence.enumerate() { |
| 191 | // Set the channel in the right sequence field. | 189 | // Set the channel in the right sequence field. |
| 192 | T::regs().sqr3().modify(|w| w.set_sq(i, ch)); | 190 | self.sqr3().modify(|w| w.set_sq(i, ch)); |
| 193 | 191 | ||
| 194 | let sample_time = sample_time.into(); | 192 | let sample_time = sample_time.into(); |
| 195 | if ch <= 9 { | 193 | if ch <= 9 { |
| 196 | T::regs().smpr2().modify(|reg| reg.set_smp(ch as _, sample_time)); | 194 | self.smpr2().modify(|reg| reg.set_smp(ch as _, sample_time)); |
| 197 | } else { | 195 | } else { |
| 198 | T::regs().smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time)); | 196 | self.smpr1().modify(|reg| reg.set_smp((ch - 10) as _, sample_time)); |
| 199 | } | 197 | } |
| 200 | } | 198 | } |
| 201 | } | 199 | } |
| @@ -203,7 +201,7 @@ impl<T: Instance> super::SealedAnyInstance for T { | |||
| 203 | 201 | ||
| 204 | impl<'d, T> Adc<'d, T> | 202 | impl<'d, T> Adc<'d, T> |
| 205 | where | 203 | where |
| 206 | T: Instance + super::AnyInstance, | 204 | T: Instance<Regs = crate::pac::adc::Adc>, |
| 207 | { | 205 | { |
| 208 | pub fn new(adc: Peri<'d, T>) -> Self { | 206 | pub fn new(adc: Peri<'d, T>) -> Self { |
| 209 | Self::new_with_config(adc, Default::default()) | 207 | Self::new_with_config(adc, Default::default()) |
| @@ -214,7 +212,7 @@ where | |||
| 214 | 212 | ||
| 215 | let presc = from_pclk2(T::frequency()); | 213 | let presc = from_pclk2(T::frequency()); |
| 216 | T::common_regs().ccr().modify(|w| w.set_adcpre(presc)); | 214 | T::common_regs().ccr().modify(|w| w.set_adcpre(presc)); |
| 217 | T::enable(); | 215 | T::regs().enable(); |
| 218 | 216 | ||
| 219 | if let Some(resolution) = config.resolution { | 217 | if let Some(resolution) = config.resolution { |
| 220 | T::regs().cr1().modify(|reg| reg.set_res(resolution.into())); | 218 | T::regs().cr1().modify(|reg| reg.set_res(resolution.into())); |
| @@ -259,9 +257,7 @@ where | |||
| 259 | 257 | ||
| 260 | impl<'d, T: Instance> Drop for Adc<'d, T> { | 258 | impl<'d, T: Instance> Drop for Adc<'d, T> { |
| 261 | fn drop(&mut self) { | 259 | fn drop(&mut self) { |
| 262 | T::regs().cr2().modify(|reg| { | 260 | T::regs().stop(); |
| 263 | reg.set_adon(false); | ||
| 264 | }); | ||
| 265 | 261 | ||
| 266 | rcc::disable::<T>(); | 262 | rcc::disable::<T>(); |
| 267 | } | 263 | } |
