aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/adc/v2.rs
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-12-06 12:17:00 -0600
committerxoviat <[email protected]>2025-12-06 12:17:00 -0600
commit4f66b2f2090e2fcfd7d92f9ebd07cc9048eb70d7 (patch)
tree8cc00b76c76aa08358e0959496cd7e1a77c6da76 /embassy-stm32/src/adc/v2.rs
parent4160184b314473c582ca8c4f50b880f4e42cf6e3 (diff)
adc: type-erase regs instance
Diffstat (limited to 'embassy-stm32/src/adc/v2.rs')
-rw-r--r--embassy-stm32/src/adc/v2.rs58
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 @@
1use core::sync::atomic::{Ordering, compiler_fence}; 1use core::sync::atomic::{Ordering, compiler_fence};
2 2
3use super::{ConversionMode, Temperature, Vbat, VrefInt, blocking_delay_us}; 3use super::{ConversionMode, Temperature, Vbat, VrefInt, blocking_delay_us};
4use crate::adc::{Adc, Instance, Resolution, SampleTime}; 4use crate::adc::{Adc, AdcRegs, Instance, Resolution, SampleTime};
5use crate::pac::adc::vals; 5use crate::pac::adc::vals;
6pub use crate::pac::adccommon::vals::Adcpre; 6pub use crate::pac::adccommon::vals::Adcpre;
7use crate::time::Hertz; 7use crate::time::Hertz;
@@ -74,28 +74,28 @@ pub struct AdcConfig {
74 pub resolution: Option<Resolution>, 74 pub resolution: Option<Resolution>,
75} 75}
76 76
77impl<T: Instance> super::SealedAnyInstance for T { 77impl 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
204impl<'d, T> Adc<'d, T> 202impl<'d, T> Adc<'d, T>
205where 203where
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
260impl<'d, T: Instance> Drop for Adc<'d, T> { 258impl<'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 }