aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/adc/v4.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/adc/v4.rs')
-rw-r--r--embassy-stm32/src/adc/v4.rs76
1 files changed, 35 insertions, 41 deletions
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index a3d9e6176..09fc2ab22 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -5,7 +5,7 @@ use pac::adc::vals::{Adstp, Difsel, Dmngt, Exten, Pcsel};
5use pac::adccommon::vals::Presc; 5use pac::adccommon::vals::Presc;
6 6
7use super::{Adc, Averaging, Instance, Resolution, SampleTime, Temperature, Vbat, VrefInt, blocking_delay_us}; 7use super::{Adc, Averaging, Instance, Resolution, SampleTime, Temperature, Vbat, VrefInt, blocking_delay_us};
8use crate::adc::ConversionMode; 8use crate::adc::{AdcRegs, ConversionMode};
9use crate::time::Hertz; 9use crate::time::Hertz;
10use crate::{Peri, pac, rcc}; 10use crate::{Peri, pac, rcc};
11 11
@@ -80,65 +80,63 @@ pub struct AdcConfig {
80 pub averaging: Option<Averaging>, 80 pub averaging: Option<Averaging>,
81} 81}
82 82
83impl<T: Instance> super::SealedAnyInstance for T { 83impl AdcRegs for crate::pac::adc::Adc {
84 fn dr() -> *mut u16 { 84 fn data(&self) -> *mut u16 {
85 T::regs().dr().as_ptr() as *mut u16 85 crate::pac::adc::Adc::dr(*self).as_ptr() as *mut u16
86 } 86 }
87 87
88 fn enable() { 88 fn enable(&self) {
89 T::regs().isr().write(|w| w.set_adrdy(true)); 89 self.isr().write(|w| w.set_adrdy(true));
90 T::regs().cr().modify(|w| w.set_aden(true)); 90 self.cr().modify(|w| w.set_aden(true));
91 while !T::regs().isr().read().adrdy() {} 91 while !self.isr().read().adrdy() {}
92 T::regs().isr().write(|w| w.set_adrdy(true)); 92 self.isr().write(|w| w.set_adrdy(true));
93 } 93 }
94 94
95 fn start() { 95 fn start(&self) {
96 // Start conversion 96 // Start conversion
97 T::regs().cr().modify(|reg| { 97 self.cr().modify(|reg| {
98 reg.set_adstart(true); 98 reg.set_adstart(true);
99 }); 99 });
100 } 100 }
101 101
102 fn stop() { 102 fn stop(&self) {
103 if T::regs().cr().read().adstart() && !T::regs().cr().read().addis() { 103 if self.cr().read().adstart() && !self.cr().read().addis() {
104 T::regs().cr().modify(|reg| { 104 self.cr().modify(|reg| {
105 reg.set_adstp(Adstp::STOP); 105 reg.set_adstp(Adstp::STOP);
106 }); 106 });
107 while T::regs().cr().read().adstart() {} 107 while self.cr().read().adstart() {}
108 } 108 }
109 109
110 // Reset configuration. 110 // Reset configuration.
111 T::regs().cfgr().modify(|reg| { 111 self.cfgr().modify(|reg| {
112 reg.set_cont(false); 112 reg.set_cont(false);
113 reg.set_dmngt(Dmngt::from_bits(0)); 113 reg.set_dmngt(Dmngt::from_bits(0));
114 }); 114 });
115 } 115 }
116 116
117 fn convert() -> u16 { 117 fn convert(&self) {
118 T::regs().isr().modify(|reg| { 118 self.isr().modify(|reg| {
119 reg.set_eos(true); 119 reg.set_eos(true);
120 reg.set_eoc(true); 120 reg.set_eoc(true);
121 }); 121 });
122 122
123 // Start conversion 123 // Start conversion
124 T::regs().cr().modify(|reg| { 124 self.cr().modify(|reg| {
125 reg.set_adstart(true); 125 reg.set_adstart(true);
126 }); 126 });
127 127
128 while !T::regs().isr().read().eos() { 128 while !self.isr().read().eos() {
129 // spin 129 // spin
130 } 130 }
131
132 T::regs().dr().read().0 as u16
133 } 131 }
134 132
135 fn configure_dma(conversion_mode: ConversionMode) { 133 fn configure_dma(&self, conversion_mode: ConversionMode) {
136 match conversion_mode { 134 match conversion_mode {
137 ConversionMode::Singular => { 135 ConversionMode::Singular => {
138 T::regs().isr().modify(|reg| { 136 self.isr().modify(|reg| {
139 reg.set_ovr(true); 137 reg.set_ovr(true);
140 }); 138 });
141 T::regs().cfgr().modify(|reg| { 139 self.cfgr().modify(|reg| {
142 reg.set_cont(true); 140 reg.set_cont(true);
143 reg.set_dmngt(Dmngt::DMA_ONE_SHOT); 141 reg.set_dmngt(Dmngt::DMA_ONE_SHOT);
144 }); 142 });
@@ -148,9 +146,9 @@ impl<T: Instance> super::SealedAnyInstance for T {
148 } 146 }
149 } 147 }
150 148
151 fn configure_sequence(sequence: impl ExactSizeIterator<Item = ((u8, bool), SampleTime)>) { 149 fn configure_sequence(&self, sequence: impl ExactSizeIterator<Item = ((u8, bool), SampleTime)>) {
152 // Set sequence length 150 // Set sequence length
153 T::regs().sqr1().modify(|w| { 151 self.sqr1().modify(|w| {
154 w.set_l(sequence.len() as u8 - 1); 152 w.set_l(sequence.len() as u8 - 1);
155 }); 153 });
156 154
@@ -158,39 +156,35 @@ impl<T: Instance> super::SealedAnyInstance for T {
158 for (i, ((channel, _), sample_time)) in sequence.enumerate() { 156 for (i, ((channel, _), sample_time)) in sequence.enumerate() {
159 let sample_time = sample_time.into(); 157 let sample_time = sample_time.into();
160 if channel <= 9 { 158 if channel <= 9 {
161 T::regs().smpr(0).modify(|reg| reg.set_smp(channel as _, sample_time)); 159 self.smpr(0).modify(|reg| reg.set_smp(channel as _, sample_time));
162 } else { 160 } else {
163 T::regs() 161 self.smpr(1).modify(|reg| reg.set_smp((channel - 10) as _, sample_time));
164 .smpr(1)
165 .modify(|reg| reg.set_smp((channel - 10) as _, sample_time));
166 } 162 }
167 163
168 #[cfg(any(stm32h7, stm32u5))] 164 #[cfg(any(stm32h7, stm32u5))]
169 { 165 {
170 T::regs().cfgr2().modify(|w| w.set_lshift(0)); 166 self.cfgr2().modify(|w| w.set_lshift(0));
171 T::regs() 167 self.pcsel().modify(|w| w.set_pcsel(channel as _, Pcsel::PRESELECTED));
172 .pcsel()
173 .modify(|w| w.set_pcsel(channel as _, Pcsel::PRESELECTED));
174 } 168 }
175 169
176 match i { 170 match i {
177 0..=3 => { 171 0..=3 => {
178 T::regs().sqr1().modify(|w| { 172 self.sqr1().modify(|w| {
179 w.set_sq(i, channel); 173 w.set_sq(i, channel);
180 }); 174 });
181 } 175 }
182 4..=8 => { 176 4..=8 => {
183 T::regs().sqr2().modify(|w| { 177 self.sqr2().modify(|w| {
184 w.set_sq(i - 4, channel); 178 w.set_sq(i - 4, channel);
185 }); 179 });
186 } 180 }
187 9..=13 => { 181 9..=13 => {
188 T::regs().sqr3().modify(|w| { 182 self.sqr3().modify(|w| {
189 w.set_sq(i - 9, channel); 183 w.set_sq(i - 9, channel);
190 }); 184 });
191 } 185 }
192 14..=15 => { 186 14..=15 => {
193 T::regs().sqr4().modify(|w| { 187 self.sqr4().modify(|w| {
194 w.set_sq(i - 14, channel); 188 w.set_sq(i - 14, channel);
195 }); 189 });
196 } 190 }
@@ -200,7 +194,7 @@ impl<T: Instance> super::SealedAnyInstance for T {
200 } 194 }
201} 195}
202 196
203impl<'d, T: Instance + super::AnyInstance> Adc<'d, T> { 197impl<'d, T: Instance<Regs = crate::pac::adc::Adc>> Adc<'d, T> {
204 pub fn new_with_config(adc: Peri<'d, T>, config: AdcConfig) -> Self { 198 pub fn new_with_config(adc: Peri<'d, T>, config: AdcConfig) -> Self {
205 let s = Self::new(adc); 199 let s = Self::new(adc);
206 200
@@ -292,7 +286,7 @@ impl<'d, T: Instance + super::AnyInstance> Adc<'d, T> {
292 286
293 blocking_delay_us(1); 287 blocking_delay_us(1);
294 288
295 T::enable(); 289 T::regs().enable();
296 290
297 // single conversion mode, software trigger 291 // single conversion mode, software trigger
298 T::regs().cfgr().modify(|w| { 292 T::regs().cfgr().modify(|w| {