aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
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
parent4160184b314473c582ca8c4f50b880f4e42cf6e3 (diff)
adc: type-erase regs instance
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/adc/adc4.rs207
-rw-r--r--embassy-stm32/src/adc/c0.rs64
-rw-r--r--embassy-stm32/src/adc/g4.rs100
-rw-r--r--embassy-stm32/src/adc/injected.rs12
-rw-r--r--embassy-stm32/src/adc/mod.rs223
-rw-r--r--embassy-stm32/src/adc/ringbuffered.rs48
-rw-r--r--embassy-stm32/src/adc/v2.rs58
-rw-r--r--embassy-stm32/src/adc/v3.rs91
-rw-r--r--embassy-stm32/src/adc/v4.rs76
9 files changed, 441 insertions, 438 deletions
diff --git a/embassy-stm32/src/adc/adc4.rs b/embassy-stm32/src/adc/adc4.rs
index 453513309..43509873f 100644
--- a/embassy-stm32/src/adc/adc4.rs
+++ b/embassy-stm32/src/adc/adc4.rs
@@ -5,7 +5,7 @@ use pac::adc::vals::{Adc4Dmacfg as Dmacfg, Adc4Exten as Exten, Adc4OversamplingR
5use pac::adc::vals::{Chselrmod, Cont, Dmacfg, Exten, OversamplingRatio, Ovss, Smpsel}; 5use pac::adc::vals::{Chselrmod, Cont, Dmacfg, Exten, OversamplingRatio, Ovss, Smpsel};
6 6
7use super::blocking_delay_us; 7use super::blocking_delay_us;
8use crate::adc::ConversionMode; 8use crate::adc::{AdcRegs, ConversionMode, Instance};
9#[cfg(stm32u5)] 9#[cfg(stm32u5)]
10pub use crate::pac::adc::regs::Adc4Chselrmod0 as Chselr; 10pub use crate::pac::adc::regs::Adc4Chselrmod0 as Chselr;
11#[cfg(stm32wba)] 11#[cfg(stm32wba)]
@@ -90,135 +90,112 @@ fn from_ker_ck(frequency: Hertz) -> Presc {
90 } 90 }
91} 91}
92 92
93pub trait SealedInstance { 93impl AdcRegs for crate::pac::adc::Adc4 {
94 #[allow(unused)] 94 fn data(&self) -> *mut u16 {
95 fn regs() -> crate::pac::adc::Adc4; 95 crate::pac::adc::Adc4::dr(*self).as_ptr() as *mut u16
96} 96 }
97 97
98pub trait Instance: SealedInstance + crate::PeripheralType + crate::rcc::RccPeripheral { 98 fn enable(&self) {
99 type Interrupt: crate::interrupt::typelevel::Interrupt; 99 if !self.cr().read().aden() || !self.isr().read().adrdy() {
100} 100 self.isr().write(|w| w.set_adrdy(true));
101 self.cr().modify(|w| w.set_aden(true));
102 while !self.isr().read().adrdy() {}
103 }
104 }
101 105
102foreach_adc!( 106 fn start(&self) {
103 (ADC4, $common_inst:ident, $clock:ident) => { 107 // Start conversion
104 use crate::peripherals::ADC4; 108 self.cr().modify(|reg| {
109 reg.set_adstart(true);
110 });
111 }
105 112
106 impl super::BasicAnyInstance for ADC4 { 113 fn stop(&self) {
107 type SampleTime = SampleTime; 114 let cr = self.cr().read();
115 if cr.adstart() {
116 self.cr().modify(|w| w.set_adstp(true));
117 while self.cr().read().adstart() {}
108 } 118 }
109 119
110 impl super::SealedAnyInstance for ADC4 { 120 if cr.aden() || cr.adstart() {
111 fn dr() -> *mut u16 { 121 self.cr().modify(|w| w.set_addis(true));
112 ADC4::regs().dr().as_ptr() as *mut u16 122 while self.cr().read().aden() {}
113 } 123 }
114 124
115 fn enable() { 125 // Reset configuration.
116 if !ADC4::regs().cr().read().aden() || !ADC4::regs().isr().read().adrdy() { 126 self.cfgr1().modify(|reg| {
117 ADC4::regs().isr().write(|w| w.set_adrdy(true)); 127 reg.set_dmaen(false);
118 ADC4::regs().cr().modify(|w| w.set_aden(true)); 128 });
119 while !ADC4::regs().isr().read().adrdy() {} 129 }
120 }
121 }
122 130
123 fn start() { 131 fn configure_dma(&self, conversion_mode: ConversionMode) {
124 // Start conversion 132 match conversion_mode {
125 ADC4::regs().cr().modify(|reg| { 133 ConversionMode::Singular => {
126 reg.set_adstart(true); 134 self.isr().modify(|reg| {
135 reg.set_ovr(true);
136 reg.set_eos(true);
137 reg.set_eoc(true);
127 }); 138 });
128 }
129 139
130 fn stop() { 140 self.cfgr1().modify(|reg| {
131 let cr = ADC4::regs().cr().read(); 141 reg.set_dmaen(true);
132 if cr.adstart() { 142 reg.set_dmacfg(Dmacfg::ONE_SHOT);
133 ADC4::regs().cr().modify(|w| w.set_adstp(true)); 143 #[cfg(stm32u5)]
134 while ADC4::regs().cr().read().adstart() {} 144 reg.set_chselrmod(false);
135 } 145 #[cfg(stm32wba)]
136 146 reg.set_chselrmod(Chselrmod::ENABLE_INPUT)
137 if cr.aden() || cr.adstart() {
138 ADC4::regs().cr().modify(|w| w.set_addis(true));
139 while ADC4::regs().cr().read().aden() {}
140 }
141
142 // Reset configuration.
143 ADC4::regs().cfgr1().modify(|reg| {
144 reg.set_dmaen(false);
145 }); 147 });
146 } 148 }
149 #[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))]
150 _ => unreachable!(),
151 }
152 }
147 153
148 fn configure_dma(conversion_mode: ConversionMode) { 154 fn configure_sequence(&self, sequence: impl ExactSizeIterator<Item = ((u8, bool), SampleTime)>) {
149 match conversion_mode { 155 let mut prev_channel: i16 = -1;
150 ConversionMode::Singular => { 156 #[cfg(stm32wba)]
151 ADC4::regs().isr().modify(|reg| { 157 self.chselr().write_value(Chselr(0_u32));
152 reg.set_ovr(true); 158 #[cfg(stm32u5)]
153 reg.set_eos(true); 159 self.chselrmod0().write_value(Chselr(0_u32));
154 reg.set_eoc(true); 160 for (_i, ((channel, _), sample_time)) in sequence.enumerate() {
155 }); 161 self.smpr().modify(|w| {
156 162 w.set_smp(_i, sample_time);
157 ADC4::regs().cfgr1().modify(|reg| { 163 });
158 reg.set_dmaen(true); 164
159 reg.set_dmacfg(Dmacfg::ONE_SHOT); 165 let channel_num = channel;
160 #[cfg(stm32u5)] 166 if channel_num as i16 <= prev_channel {
161 reg.set_chselrmod(false); 167 return;
162 #[cfg(stm32wba)] 168 };
163 reg.set_chselrmod(Chselrmod::ENABLE_INPUT) 169 prev_channel = channel_num as i16;
164 });
165 }
166 #[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))]
167 _ => unreachable!(),
168 }
169 }
170
171 fn configure_sequence(sequence: impl ExactSizeIterator<Item = ((u8, bool), SampleTime)>) {
172 let mut prev_channel: i16 = -1;
173 #[cfg(stm32wba)]
174 ADC4::regs().chselr().write_value(Chselr(0_u32));
175 #[cfg(stm32u5)]
176 ADC4::regs().chselrmod0().write_value(Chselr(0_u32));
177 for (_i, ((channel, _), sample_time)) in sequence.enumerate() {
178 ADC4::regs().smpr().modify(|w| {
179 w.set_smp(_i, sample_time);
180 });
181
182 let channel_num = channel;
183 if channel_num as i16 <= prev_channel {
184 return;
185 };
186 prev_channel = channel_num as i16;
187
188 #[cfg(stm32wba)]
189 ADC4::regs().chselr().modify(|w| {
190 w.set_chsel0(channel as usize, true);
191 });
192 #[cfg(stm32u5)]
193 ADC4::regs().chselrmod0().modify(|w| {
194 w.set_chsel(channel as usize, true);
195 });
196 }
197 }
198 170
199 fn convert() -> u16 { 171 #[cfg(stm32wba)]
200 // Reset interrupts 172 self.chselr().modify(|w| {
201 ADC4::regs().isr().modify(|reg| { 173 w.set_chsel0(channel as usize, true);
202 reg.set_eos(true); 174 });
203 reg.set_eoc(true); 175 #[cfg(stm32u5)]
204 }); 176 self.chselrmod0().modify(|w| {
177 w.set_chsel(channel as usize, true);
178 });
179 }
180 }
205 181
206 // Start conversion 182 fn convert(&self) {
207 ADC4::regs().cr().modify(|reg| { 183 // Reset interrupts
208 reg.set_adstart(true); 184 self.isr().modify(|reg| {
209 }); 185 reg.set_eos(true);
186 reg.set_eoc(true);
187 });
210 188
211 while !ADC4::regs().isr().read().eos() { 189 // Start conversion
212 // spin 190 self.cr().modify(|reg| {
213 } 191 reg.set_adstart(true);
192 });
214 193
215 ADC4::regs().dr().read().0 as u16 194 while !self.isr().read().eos() {
216 } 195 // spin
217 } 196 }
218 197 }
219 impl super::AnyInstance for ADC4 {} 198}
220 };
221);
222 199
223pub struct Adc4<'d, T: Instance> { 200pub struct Adc4<'d, T: Instance> {
224 #[allow(unused)] 201 #[allow(unused)]
@@ -231,7 +208,7 @@ pub enum Adc4Error {
231 DMAError, 208 DMAError,
232} 209}
233 210
234impl<'d, T: Instance + super::AnyInstance> super::Adc<'d, T> { 211impl<'d, T: Instance<Regs = crate::pac::adc::Adc4>> super::Adc<'d, T> {
235 /// Create a new ADC driver. 212 /// Create a new ADC driver.
236 pub fn new_adc4(adc: Peri<'d, T>) -> Self { 213 pub fn new_adc4(adc: Peri<'d, T>) -> Self {
237 rcc::enable_and_reset::<T>(); 214 rcc::enable_and_reset::<T>();
@@ -267,7 +244,7 @@ impl<'d, T: Instance + super::AnyInstance> super::Adc<'d, T> {
267 244
268 blocking_delay_us(1); 245 blocking_delay_us(1);
269 246
270 T::enable(); 247 T::regs().enable();
271 248
272 // single conversion mode, software trigger 249 // single conversion mode, software trigger
273 T::regs().cfgr1().modify(|w| { 250 T::regs().cfgr1().modify(|w| {
diff --git a/embassy-stm32/src/adc/c0.rs b/embassy-stm32/src/adc/c0.rs
index 3e109e429..2f0f326af 100644
--- a/embassy-stm32/src/adc/c0.rs
+++ b/embassy-stm32/src/adc/c0.rs
@@ -4,7 +4,7 @@ use pac::adccommon::vals::Presc;
4use stm32_metapac::adc::vals::{SampleTime, Scandir}; 4use stm32_metapac::adc::vals::{SampleTime, Scandir};
5 5
6use super::{Adc, Instance, Resolution, blocking_delay_us}; 6use super::{Adc, Instance, Resolution, blocking_delay_us};
7use crate::adc::{AnyInstance, ConversionMode}; 7use crate::adc::{AdcRegs, ConversionMode};
8use crate::time::Hertz; 8use crate::time::Hertz;
9use crate::{Peri, pac, rcc}; 9use crate::{Peri, pac, rcc};
10 10
@@ -43,52 +43,52 @@ fn from_ker_ck(frequency: Hertz) -> Presc {
43 } 43 }
44} 44}
45 45
46impl<T: Instance> super::SealedAnyInstance for T { 46impl AdcRegs for crate::pac::adc::Adc {
47 fn dr() -> *mut u16 { 47 fn data(&self) -> *mut u16 {
48 T::regs().dr().as_ptr() as *mut u16 48 crate::pac::adc::Adc::dr(*self).as_ptr() as *mut u16
49 } 49 }
50 50
51 fn enable() { 51 fn enable(&self) {
52 T::regs().isr().modify(|w| w.set_adrdy(true)); 52 self.isr().modify(|w| w.set_adrdy(true));
53 T::regs().cr().modify(|w| w.set_aden(true)); 53 self.cr().modify(|w| w.set_aden(true));
54 // ADRDY is "ADC ready". Wait until it will be True. 54 // ADRDY is "ADC ready". Wait until it will be True.
55 while !T::regs().isr().read().adrdy() {} 55 while !self.isr().read().adrdy() {}
56 } 56 }
57 57
58 fn start() { 58 fn start(&self) {
59 // Start conversion 59 // Start conversion
60 T::regs().cr().modify(|reg| { 60 self.cr().modify(|reg| {
61 reg.set_adstart(true); 61 reg.set_adstart(true);
62 }); 62 });
63 } 63 }
64 64
65 fn stop() { 65 fn stop(&self) {
66 if T::regs().cr().read().adstart() && !T::regs().cr().read().addis() { 66 if self.cr().read().adstart() && !self.cr().read().addis() {
67 T::regs().cr().modify(|reg| { 67 self.cr().modify(|reg| {
68 reg.set_adstp(Adstp::STOP); 68 reg.set_adstp(Adstp::STOP);
69 }); 69 });
70 while T::regs().cr().read().adstart() {} 70 while self.cr().read().adstart() {}
71 } 71 }
72 72
73 // Reset configuration. 73 // Reset configuration.
74 T::regs().cfgr1().modify(|reg| { 74 self.cfgr1().modify(|reg| {
75 reg.set_cont(false); 75 reg.set_cont(false);
76 reg.set_dmacfg(Dmacfg::from_bits(0)); 76 reg.set_dmacfg(Dmacfg::from_bits(0));
77 reg.set_dmaen(false); 77 reg.set_dmaen(false);
78 }); 78 });
79 } 79 }
80 80
81 fn configure_dma(conversion_mode: super::ConversionMode) { 81 fn configure_dma(&self, conversion_mode: super::ConversionMode) {
82 match conversion_mode { 82 match conversion_mode {
83 ConversionMode::Singular => { 83 ConversionMode::Singular => {
84 // Enable overrun control, so no new DMA requests will be generated until 84 // Enable overrun control, so no new DMA requests will be generated until
85 // previous DR values is read. 85 // previous DR values is read.
86 T::regs().isr().modify(|reg| { 86 self.isr().modify(|reg| {
87 reg.set_ovr(true); 87 reg.set_ovr(true);
88 }); 88 });
89 89
90 // Set continuous mode with oneshot dma. 90 // Set continuous mode with oneshot dma.
91 T::regs().cfgr1().modify(|reg| { 91 self.cfgr1().modify(|reg| {
92 reg.set_discen(false); 92 reg.set_discen(false);
93 reg.set_cont(true); 93 reg.set_cont(true);
94 reg.set_dmacfg(Dmacfg::DMA_ONE_SHOT); 94 reg.set_dmacfg(Dmacfg::DMA_ONE_SHOT);
@@ -99,7 +99,7 @@ impl<T: Instance> super::SealedAnyInstance for T {
99 } 99 }
100 } 100 }
101 101
102 fn configure_sequence(sequence: impl ExactSizeIterator<Item = ((u8, bool), Self::SampleTime)>) { 102 fn configure_sequence(&self, sequence: impl ExactSizeIterator<Item = ((u8, bool), Self::SampleTime)>) {
103 let mut needs_hw = sequence.len() == 1 || sequence.len() > CHSELR_SQ_SIZE; 103 let mut needs_hw = sequence.len() == 1 || sequence.len() > CHSELR_SQ_SIZE;
104 let mut is_ordered_up = true; 104 let mut is_ordered_up = true;
105 let mut is_ordered_down = true; 105 let mut is_ordered_down = true;
@@ -109,7 +109,7 @@ impl<T: Instance> super::SealedAnyInstance for T {
109 let mut last_channel: u8 = 0; 109 let mut last_channel: u8 = 0;
110 let mut sample_time: Self::SampleTime = SampleTime::CYCLES2_5; 110 let mut sample_time: Self::SampleTime = SampleTime::CYCLES2_5;
111 111
112 T::regs().chselr_sq().write(|w| { 112 self.chselr_sq().write(|w| {
113 for (i, ((channel, _), _sample_time)) in sequence.enumerate() { 113 for (i, ((channel, _), _sample_time)) in sequence.enumerate() {
114 assert!( 114 assert!(
115 sample_time == _sample_time || i == 0, 115 sample_time == _sample_time || i == 0,
@@ -146,42 +146,40 @@ impl<T: Instance> super::SealedAnyInstance for T {
146 ); 146 );
147 147
148 // Set required channels for multi-convert. 148 // Set required channels for multi-convert.
149 unsafe { (T::regs().chselr().as_ptr() as *mut u32).write_volatile(hw_channel_selection) } 149 unsafe { (self.chselr().as_ptr() as *mut u32).write_volatile(hw_channel_selection) }
150 } 150 }
151 151
152 T::regs().smpr().modify(|w| { 152 self.smpr().modify(|w| {
153 w.smpsel(0); 153 w.smpsel(0);
154 w.set_smp1(sample_time); 154 w.set_smp1(sample_time);
155 }); 155 });
156 156
157 T::regs().cfgr1().modify(|reg| { 157 self.cfgr1().modify(|reg| {
158 reg.set_chselrmod(!needs_hw); 158 reg.set_chselrmod(!needs_hw);
159 reg.set_align(Align::RIGHT); 159 reg.set_align(Align::RIGHT);
160 reg.set_scandir(if is_ordered_up { Scandir::UP } else { Scandir::BACK }); 160 reg.set_scandir(if is_ordered_up { Scandir::UP } else { Scandir::BACK });
161 }); 161 });
162 162
163 // Trigger and wait for the channel selection procedure to complete. 163 // Trigger and wait for the channel selection procedure to complete.
164 T::regs().isr().modify(|w| w.set_ccrdy(false)); 164 self.isr().modify(|w| w.set_ccrdy(false));
165 while !T::regs().isr().read().ccrdy() {} 165 while !self.isr().read().ccrdy() {}
166 } 166 }
167 167
168 fn convert() -> u16 { 168 fn convert(&self) {
169 // Set single conversion mode. 169 // Set single conversion mode.
170 T::regs().cfgr1().modify(|w| w.set_cont(false)); 170 self.cfgr1().modify(|w| w.set_cont(false));
171 171
172 // Start conversion 172 // Start conversion
173 T::regs().cr().modify(|reg| { 173 self.cr().modify(|reg| {
174 reg.set_adstart(true); 174 reg.set_adstart(true);
175 }); 175 });
176 176
177 // Waiting for End Of Conversion (EOC). 177 // Waiting for End Of Conversion (EOC).
178 while !T::regs().isr().read().eoc() {} 178 while !self.isr().read().eoc() {}
179
180 T::regs().dr().read().data() as u16
181 } 179 }
182} 180}
183 181
184impl<'d, T: AnyInstance> Adc<'d, T> { 182impl<'d, T: Instance<Regs = crate::pac::adc::Adc>> Adc<'d, T> {
185 /// Create a new ADC driver. 183 /// Create a new ADC driver.
186 pub fn new(adc: Peri<'d, T>, resolution: Resolution) -> Self { 184 pub fn new(adc: Peri<'d, T>, resolution: Resolution) -> Self {
187 rcc::enable_and_reset::<T>(); 185 rcc::enable_and_reset::<T>();
@@ -225,7 +223,7 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
225 223
226 T::regs().cfgr1().modify(|w| w.set_autoff(autoff_value)); 224 T::regs().cfgr1().modify(|w| w.set_autoff(autoff_value));
227 225
228 T::enable(); 226 T::regs().enable();
229 227
230 // single conversion mode, software trigger 228 // single conversion mode, software trigger
231 T::regs().cfgr1().modify(|w| { 229 T::regs().cfgr1().modify(|w| {
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index d4e526061..53c1ecd31 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -12,7 +12,7 @@ use super::{
12 Adc, AnyAdcChannel, ConversionMode, Instance, RegularConversionMode, Resolution, RxDma, SampleTime, 12 Adc, AnyAdcChannel, ConversionMode, Instance, RegularConversionMode, Resolution, RxDma, SampleTime,
13 blocking_delay_us, 13 blocking_delay_us,
14}; 14};
15use crate::adc::{AnyInstance, SealedAdcChannel}; 15use crate::adc::{AdcRegs, BasicAdcRegs, SealedAdcChannel};
16use crate::time::Hertz; 16use crate::time::Hertz;
17use crate::{Peri, pac, rcc}; 17use crate::{Peri, pac, rcc};
18 18
@@ -68,79 +68,77 @@ pub struct ConversionTrigger {
68 pub edge: Exten, 68 pub edge: Exten,
69} 69}
70 70
71impl<T: Instance> super::SealedAnyInstance for T { 71impl super::AdcRegs for crate::pac::adc::Adc {
72 fn dr() -> *mut u16 { 72 fn data(&self) -> *mut u16 {
73 T::regs().dr().as_ptr() as *mut u16 73 crate::pac::adc::Adc::dr(*self).as_ptr() as *mut u16
74 } 74 }
75 75
76 fn enable() { 76 fn enable(&self) {
77 // Make sure bits are off 77 // Make sure bits are off
78 while T::regs().cr().read().addis() { 78 while self.cr().read().addis() {
79 // spin 79 // spin
80 } 80 }
81 81
82 if !T::regs().cr().read().aden() { 82 if !self.cr().read().aden() {
83 // Enable ADC 83 // Enable ADC
84 T::regs().isr().modify(|reg| { 84 self.isr().modify(|reg| {
85 reg.set_adrdy(true); 85 reg.set_adrdy(true);
86 }); 86 });
87 T::regs().cr().modify(|reg| { 87 self.cr().modify(|reg| {
88 reg.set_aden(true); 88 reg.set_aden(true);
89 }); 89 });
90 90
91 while !T::regs().isr().read().adrdy() { 91 while !self.isr().read().adrdy() {
92 // spin 92 // spin
93 } 93 }
94 } 94 }
95 } 95 }
96 96
97 fn start() { 97 fn start(&self) {
98 T::regs().cr().modify(|reg| { 98 self.cr().modify(|reg| {
99 reg.set_adstart(true); 99 reg.set_adstart(true);
100 }); 100 });
101 } 101 }
102 102
103 fn stop() { 103 fn stop(&self) {
104 if T::regs().cr().read().adstart() && !T::regs().cr().read().addis() { 104 if self.cr().read().adstart() && !self.cr().read().addis() {
105 T::regs().cr().modify(|reg| { 105 self.cr().modify(|reg| {
106 reg.set_adstp(Adstp::STOP); 106 reg.set_adstp(Adstp::STOP);
107 }); 107 });
108 // The software must poll ADSTART until the bit is reset before assuming the 108 // The software must poll ADSTART until the bit is reset before assuming the
109 // ADC is completely stopped 109 // ADC is completely stopped
110 while T::regs().cr().read().adstart() {} 110 while self.cr().read().adstart() {}
111 } 111 }
112 112
113 // Disable dma control and continuous conversion, if enabled 113 // Disable dma control and continuous conversion, if enabled
114 T::regs().cfgr().modify(|reg| { 114 self.cfgr().modify(|reg| {
115 reg.set_cont(false); 115 reg.set_cont(false);
116 reg.set_dmaen(Dmaen::DISABLE); 116 reg.set_dmaen(Dmaen::DISABLE);
117 }); 117 });
118 } 118 }
119 119
120 fn convert() -> u16 { 120 fn convert(&self) {
121 T::regs().isr().modify(|reg| { 121 self.isr().modify(|reg| {
122 reg.set_eos(true); 122 reg.set_eos(true);
123 reg.set_eoc(true); 123 reg.set_eoc(true);
124 }); 124 });
125 125
126 // Start conversion 126 // Start conversion
127 T::regs().cr().modify(|reg| { 127 self.cr().modify(|reg| {
128 reg.set_adstart(true); 128 reg.set_adstart(true);
129 }); 129 });
130 130
131 while !T::regs().isr().read().eos() { 131 while !self.isr().read().eos() {
132 // spin 132 // spin
133 } 133 }
134
135 T::regs().dr().read().0 as u16
136 } 134 }
137 135
138 fn configure_dma(conversion_mode: ConversionMode) { 136 fn configure_dma(&self, conversion_mode: ConversionMode) {
139 T::regs().isr().modify(|reg| { 137 self.isr().modify(|reg| {
140 reg.set_ovr(true); 138 reg.set_ovr(true);
141 }); 139 });
142 140
143 T::regs().cfgr().modify(|reg| { 141 self.cfgr().modify(|reg| {
144 reg.set_discen(false); // Convert all channels for each trigger 142 reg.set_discen(false); // Convert all channels for each trigger
145 reg.set_dmacfg(match conversion_mode { 143 reg.set_dmacfg(match conversion_mode {
146 ConversionMode::Singular => Dmacfg::ONE_SHOT, 144 ConversionMode::Singular => Dmacfg::ONE_SHOT,
@@ -152,43 +150,43 @@ impl<T: Instance> super::SealedAnyInstance for T {
152 if let ConversionMode::Repeated(mode) = conversion_mode { 150 if let ConversionMode::Repeated(mode) = conversion_mode {
153 match mode { 151 match mode {
154 RegularConversionMode::Continuous => { 152 RegularConversionMode::Continuous => {
155 T::regs().cfgr().modify(|reg| { 153 self.cfgr().modify(|reg| {
156 reg.set_cont(true); 154 reg.set_cont(true);
157 }); 155 });
158 } 156 }
159 RegularConversionMode::Triggered(trigger) => { 157 RegularConversionMode::Triggered(trigger) => {
160 T::regs().cfgr().modify(|r| { 158 self.cfgr().modify(|r| {
161 r.set_cont(false); // New trigger is neede for each sample to be read 159 r.set_cont(false); // New trigger is neede for each sample to be read
162 }); 160 });
163 161
164 T::regs().cfgr().modify(|r| { 162 self.cfgr().modify(|r| {
165 r.set_extsel(trigger.channel); 163 r.set_extsel(trigger.channel);
166 r.set_exten(trigger.edge); 164 r.set_exten(trigger.edge);
167 }); 165 });
168 166
169 // Regular conversions uses DMA so no need to generate interrupt 167 // Regular conversions uses DMA so no need to generate interrupt
170 T::regs().ier().modify(|r| r.set_eosie(false)); 168 self.ier().modify(|r| r.set_eosie(false));
171 } 169 }
172 } 170 }
173 } 171 }
174 } 172 }
175 173
176 fn configure_sequence(sequence: impl ExactSizeIterator<Item = ((u8, bool), SampleTime)>) { 174 fn configure_sequence(&self, sequence: impl ExactSizeIterator<Item = ((u8, bool), SampleTime)>) {
177 T::regs().cr().modify(|w| w.set_aden(false)); 175 self.cr().modify(|w| w.set_aden(false));
178 176
179 // Set sequence length 177 // Set sequence length
180 T::regs().sqr1().modify(|w| { 178 self.sqr1().modify(|w| {
181 w.set_l(sequence.len() as u8 - 1); 179 w.set_l(sequence.len() as u8 - 1);
182 }); 180 });
183 181
184 #[cfg(stm32g4)] 182 #[cfg(stm32g4)]
185 let mut difsel = DifselReg::default(); 183 let mut difsel = DifselReg::default();
186 let mut smpr = T::regs().smpr().read(); 184 let mut smpr = self.smpr().read();
187 let mut smpr2 = T::regs().smpr2().read(); 185 let mut smpr2 = self.smpr2().read();
188 let mut sqr1 = T::regs().sqr1().read(); 186 let mut sqr1 = self.sqr1().read();
189 let mut sqr2 = T::regs().sqr2().read(); 187 let mut sqr2 = self.sqr2().read();
190 let mut sqr3 = T::regs().sqr3().read(); 188 let mut sqr3 = self.sqr3().read();
191 let mut sqr4 = T::regs().sqr4().read(); 189 let mut sqr4 = self.sqr4().read();
192 190
193 // Configure channels and ranks 191 // Configure channels and ranks
194 for (_i, ((ch, is_differential), sample_time)) in sequence.enumerate() { 192 for (_i, ((ch, is_differential), sample_time)) in sequence.enumerate() {
@@ -230,18 +228,18 @@ impl<T: Instance> super::SealedAnyInstance for T {
230 } 228 }
231 } 229 }
232 230
233 T::regs().smpr().write_value(smpr); 231 self.smpr().write_value(smpr);
234 T::regs().smpr2().write_value(smpr2); 232 self.smpr2().write_value(smpr2);
235 T::regs().sqr1().write_value(sqr1); 233 self.sqr1().write_value(sqr1);
236 T::regs().sqr2().write_value(sqr2); 234 self.sqr2().write_value(sqr2);
237 T::regs().sqr3().write_value(sqr3); 235 self.sqr3().write_value(sqr3);
238 T::regs().sqr4().write_value(sqr4); 236 self.sqr4().write_value(sqr4);
239 #[cfg(stm32g4)] 237 #[cfg(stm32g4)]
240 T::regs().difsel().write_value(difsel); 238 self.difsel().write_value(difsel);
241 } 239 }
242} 240}
243 241
244impl<'d, T: Instance + AnyInstance> Adc<'d, T> { 242impl<'d, T: Instance<Regs = crate::pac::adc::Adc>> Adc<'d, T> {
245 /// Create a new ADC driver. 243 /// Create a new ADC driver.
246 pub fn new(adc: Peri<'d, T>, config: AdcConfig) -> Self { 244 pub fn new(adc: Peri<'d, T>, config: AdcConfig) -> Self {
247 rcc::enable_and_reset::<T>(); 245 rcc::enable_and_reset::<T>();
@@ -293,7 +291,7 @@ impl<'d, T: Instance + AnyInstance> Adc<'d, T> {
293 291
294 blocking_delay_us(20); 292 blocking_delay_us(20);
295 293
296 T::enable(); 294 T::regs().enable();
297 295
298 // single conversion mode, software trigger 296 // single conversion mode, software trigger
299 T::regs().cfgr().modify(|w| { 297 T::regs().cfgr().modify(|w| {
@@ -420,7 +418,7 @@ impl<'d, T: Instance + AnyInstance> Adc<'d, T> {
420 NR_INJECTED_RANKS 418 NR_INJECTED_RANKS
421 ); 419 );
422 420
423 T::enable(); 421 T::regs().enable();
424 422
425 T::regs().jsqr().modify(|w| w.set_jl(N as u8 - 1)); 423 T::regs().jsqr().modify(|w| w.set_jl(N as u8 - 1));
426 424
@@ -491,7 +489,7 @@ impl<'d, T: Instance + AnyInstance> Adc<'d, T> {
491 self, 489 self,
492 dma: Peri<'a, impl RxDma<T>>, 490 dma: Peri<'a, impl RxDma<T>>,
493 dma_buf: &'a mut [u16], 491 dma_buf: &'a mut [u16],
494 regular_sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<'b, T>, T::SampleTime)>, 492 regular_sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<'b, T>, <T::Regs as BasicAdcRegs>::SampleTime)>,
495 regular_conversion_mode: RegularConversionMode, 493 regular_conversion_mode: RegularConversionMode,
496 injected_sequence: [(AnyAdcChannel<'b, T>, SampleTime); N], 494 injected_sequence: [(AnyAdcChannel<'b, T>, SampleTime); N],
497 injected_trigger: ConversionTrigger, 495 injected_trigger: ConversionTrigger,
@@ -531,7 +529,7 @@ impl<'d, T: Instance + AnyInstance> Adc<'d, T> {
531 } 529 }
532} 530}
533 531
534impl<'a, T: Instance, const N: usize> InjectedAdc<'a, T, N> { 532impl<'a, T: Instance<Regs = crate::pac::adc::Adc>, const N: usize> InjectedAdc<'a, T, N> {
535 /// Read sampled data from all injected ADC injected ranks 533 /// Read sampled data from all injected ADC injected ranks
536 /// Clear the JEOS flag to allow a new injected sequence 534 /// Clear the JEOS flag to allow a new injected sequence
537 pub(super) fn read_injected_data() -> [u16; N] { 535 pub(super) fn read_injected_data() -> [u16; N] {
diff --git a/embassy-stm32/src/adc/injected.rs b/embassy-stm32/src/adc/injected.rs
index 1af055644..029722b84 100644
--- a/embassy-stm32/src/adc/injected.rs
+++ b/embassy-stm32/src/adc/injected.rs
@@ -4,18 +4,18 @@ use core::sync::atomic::{Ordering, compiler_fence};
4#[allow(unused_imports)] 4#[allow(unused_imports)]
5use embassy_hal_internal::Peri; 5use embassy_hal_internal::Peri;
6 6
7use super::{AnyAdcChannel, SampleTime}; 7use super::{AdcRegs, AnyAdcChannel, SampleTime};
8use crate::adc::Adc;
8#[allow(unused_imports)] 9#[allow(unused_imports)]
9use crate::adc::Instance; 10use crate::adc::Instance;
10use crate::adc::{Adc, AnyInstance};
11 11
12/// Injected ADC sequence with owned channels. 12/// Injected ADC sequence with owned channels.
13pub struct InjectedAdc<'a, T: Instance, const N: usize> { 13pub struct InjectedAdc<'a, T: Instance<Regs = crate::pac::adc::Adc>, const N: usize> {
14 _channels: [(AnyAdcChannel<'a, T>, SampleTime); N], 14 _channels: [(AnyAdcChannel<'a, T>, SampleTime); N],
15 _phantom: PhantomData<T>, 15 _phantom: PhantomData<T>,
16} 16}
17 17
18impl<'a, T: Instance, const N: usize> InjectedAdc<'a, T, N> { 18impl<'a, T: Instance<Regs = crate::pac::adc::Adc>, const N: usize> InjectedAdc<'a, T, N> {
19 pub(crate) fn new(channels: [(AnyAdcChannel<'a, T>, SampleTime); N]) -> Self { 19 pub(crate) fn new(channels: [(AnyAdcChannel<'a, T>, SampleTime); N]) -> Self {
20 Self { 20 Self {
21 _channels: channels, 21 _channels: channels,
@@ -36,9 +36,9 @@ impl<'a, T: Instance, const N: usize> InjectedAdc<'a, T, N> {
36 } 36 }
37} 37}
38 38
39impl<'a, T: Instance + AnyInstance, const N: usize> Drop for InjectedAdc<'a, T, N> { 39impl<'a, T: Instance<Regs = crate::pac::adc::Adc>, const N: usize> Drop for InjectedAdc<'a, T, N> {
40 fn drop(&mut self) { 40 fn drop(&mut self) {
41 T::stop(); 41 T::regs().stop();
42 compiler_fence(Ordering::SeqCst); 42 compiler_fence(Ordering::SeqCst);
43 } 43 }
44} 44}
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 9040eefe5..a6af1175a 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -32,6 +32,11 @@ use embassy_sync::waitqueue::AtomicWaker;
32#[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))] 32#[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))]
33pub use ringbuffered::RingBufferedAdc; 33pub use ringbuffered::RingBufferedAdc;
34 34
35#[cfg(adc_u5)]
36use crate::pac::adc::vals::Adc4SampleTime;
37#[cfg(adc_wba)]
38use crate::pac::adc::vals::SampleTime as Adc4SampleTime;
39
35#[cfg(any(adc_u5, adc_wba))] 40#[cfg(any(adc_u5, adc_wba))]
36#[path = "adc4.rs"] 41#[path = "adc4.rs"]
37pub mod adc4; 42pub mod adc4;
@@ -44,10 +49,10 @@ pub use crate::pac::adc::vals::Res as Resolution;
44pub use crate::pac::adc::vals::SampleTime; 49pub use crate::pac::adc::vals::SampleTime;
45use crate::peripherals; 50use crate::peripherals;
46 51
47dma_trait!(RxDma, AnyInstance); 52dma_trait!(RxDma, Instance);
48 53
49/// Analog to Digital driver. 54/// Analog to Digital driver.
50pub struct Adc<'d, T: AnyInstance> { 55pub struct Adc<'d, T: Instance> {
51 #[allow(unused)] 56 #[allow(unused)]
52 adc: crate::Peri<'d, T>, 57 adc: crate::Peri<'d, T>,
53} 58}
@@ -66,10 +71,53 @@ impl State {
66 } 71 }
67} 72}
68 73
69trait SealedInstance { 74#[cfg(any(adc_f1, adc_f3v1, adc_f3v2, adc_v1, adc_l0))]
70 #[cfg(not(adc_wba))] 75trait_set::trait_set! {
71 #[allow(unused)] 76 pub trait DefaultInstance = Instance;
77}
78
79#[cfg(any(adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_g4, adc_c0))]
80trait_set::trait_set! {
81 pub trait DefaultInstance = Instance<Regs = crate::pac::adc::Adc>;
82}
83
84#[cfg(adc_wba)]
85trait_set::trait_set! {
86 pub trait DefaultInstance = Instance<Regs = crate::pac::adc::Adc4>;
87}
88
89pub trait BasicAdcRegs {
90 type SampleTime;
91}
92
93#[cfg(any(
94 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
95))]
96trait AdcRegs: BasicAdcRegs {
97 fn enable(&self);
98 fn start(&self);
99 fn stop(&self);
100 fn convert(&self);
101 fn configure_dma(&self, conversion_mode: ConversionMode);
102 fn configure_sequence(&self, sequence: impl ExactSizeIterator<Item = ((u8, bool), Self::SampleTime)>);
103 fn data(&self) -> *mut u16;
104}
105
106#[allow(private_bounds)]
107pub trait BasicInstance {
108 #[cfg(any(
109 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
110 ))]
111 type Regs: AdcRegs;
112}
113
114trait SealedInstance: BasicInstance {
115 #[cfg(any(adc_f1, adc_f3v1, adc_f3v2, adc_v1, adc_l0))]
72 fn regs() -> crate::pac::adc::Adc; 116 fn regs() -> crate::pac::adc::Adc;
117 #[cfg(any(
118 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
119 ))]
120 fn regs() -> Self::Regs;
73 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3v3, adc_f3v2, adc_g0)))] 121 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3v3, adc_f3v2, adc_g0)))]
74 #[allow(unused)] 122 #[allow(unused)]
75 fn common_regs() -> crate::pac::adccommon::AdcCommon; 123 fn common_regs() -> crate::pac::adccommon::AdcCommon;
@@ -90,56 +138,6 @@ pub(crate) trait SealedAdcChannel<T> {
90 } 138 }
91} 139}
92 140
93// Temporary patch for ADCs that have not implemented the standard iface yet
94#[cfg(any(adc_v1, adc_l0, adc_f1, adc_f3v1, adc_f3v2, adc_f3v3, adc_v1))]
95trait_set::trait_set! {
96 pub trait AnyInstance = Instance;
97}
98
99#[cfg(any(
100 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
101))]
102pub trait BasicAnyInstance {
103 type SampleTime;
104}
105
106#[cfg(any(
107 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
108))]
109pub(self) trait SealedAnyInstance: BasicAnyInstance {
110 fn enable();
111 fn start();
112 fn stop();
113 fn convert() -> u16;
114 fn configure_dma(conversion_mode: ConversionMode);
115 fn configure_sequence(sequence: impl ExactSizeIterator<Item = ((u8, bool), Self::SampleTime)>);
116 #[allow(dead_code)]
117 fn dr() -> *mut u16;
118}
119
120// On chips without ADC4, AnyInstance is an Instance
121#[cfg(any(adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_g4, adc_c0))]
122#[allow(private_bounds)]
123pub trait AnyInstance: SealedAnyInstance + Instance {}
124
125// On chips with ADC4, AnyInstance is an Instance or adc4::Instance
126#[cfg(any(adc_v4, adc_u5, adc_wba))]
127#[allow(private_bounds)]
128pub trait AnyInstance: SealedAnyInstance + crate::PeripheralType + crate::rcc::RccPeripheral {}
129
130// Implement AnyInstance automatically for SealedAnyInstance
131#[cfg(any(
132 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
133))]
134impl<T: SealedAnyInstance + Instance> BasicAnyInstance for T {
135 type SampleTime = SampleTime;
136}
137
138#[cfg(any(
139 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
140))]
141impl<T: SealedAnyInstance + Instance> AnyInstance for T {}
142
143#[cfg(any(adc_c0, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5))] 141#[cfg(any(adc_c0, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5))]
144/// Number of samples used for averaging. 142/// Number of samples used for averaging.
145#[derive(Copy, Clone, Debug)] 143#[derive(Copy, Clone, Debug)]
@@ -184,28 +182,33 @@ pub enum RegularConversionMode {
184 Triggered(ConversionTrigger), 182 Triggered(ConversionTrigger),
185} 183}
186 184
187impl<'d, T: AnyInstance> Adc<'d, T> { 185impl<'d, T: Instance> Adc<'d, T> {
188 #[cfg(any( 186 #[cfg(any(
189 adc_v2, adc_g4, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_u5, adc_v3, adc_v4, adc_wba, adc_c0 187 adc_v2, adc_g4, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_u5, adc_v3, adc_v4, adc_wba, adc_c0
190 ))] 188 ))]
191 /// Read an ADC pin. 189 /// Read an ADC pin.
192 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: T::SampleTime) -> u16 { 190 pub fn blocking_read(
191 &mut self,
192 channel: &mut impl AdcChannel<T>,
193 sample_time: <T::Regs as BasicAdcRegs>::SampleTime,
194 ) -> u16 {
193 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v3, adc_v4, adc_u5, adc_wba))] 195 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v3, adc_v4, adc_u5, adc_wba))]
194 channel.setup(); 196 channel.setup();
195 197
196 // Ensure no conversions are ongoing 198 // Ensure no conversions are ongoing
197 T::stop(); 199 T::regs().stop();
198 #[cfg(any(adc_v2, adc_v3, adc_g0, adc_h7rs, adc_u0, adc_u5, adc_wba, adc_c0))] 200 #[cfg(any(adc_v2, adc_v3, adc_g0, adc_h7rs, adc_u0, adc_u5, adc_wba, adc_c0))]
199 T::enable(); 201 T::regs().enable();
200 T::configure_sequence([((channel.channel(), channel.is_differential()), sample_time)].into_iter()); 202 T::regs().configure_sequence([((channel.channel(), channel.is_differential()), sample_time)].into_iter());
201 203
202 // On chips with differential channels, enable after configure_sequence to allow setting differential channels 204 // On chips with differential channels, enable after configure_sequence to allow setting differential channels
203 // 205 //
204 // TODO: If hardware allows, enable after configure_sequence on all chips 206 // TODO: If hardware allows, enable after configure_sequence on all chips
205 #[cfg(any(adc_g4, adc_h5))] 207 #[cfg(any(adc_g4, adc_h5))]
206 T::enable(); 208 T::regs().enable();
209 T::regs().convert();
207 210
208 T::convert() 211 unsafe { *T::regs().data() }
209 } 212 }
210 213
211 #[cfg(any(adc_g4, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))] 214 #[cfg(any(adc_g4, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))]
@@ -245,7 +248,7 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
245 pub async fn read<'a, 'b: 'a>( 248 pub async fn read<'a, 'b: 'a>(
246 &mut self, 249 &mut self,
247 rx_dma: embassy_hal_internal::Peri<'_, impl RxDma<T>>, 250 rx_dma: embassy_hal_internal::Peri<'_, impl RxDma<T>>,
248 sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<'b, T>, T::SampleTime)>, 251 sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<'b, T>, <T::Regs as BasicAdcRegs>::SampleTime)>,
249 readings: &mut [u16], 252 readings: &mut [u16],
250 ) { 253 ) {
251 assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty"); 254 assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty");
@@ -259,11 +262,11 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
259 ); 262 );
260 263
261 // Ensure no conversions are ongoing 264 // Ensure no conversions are ongoing
262 T::stop(); 265 T::regs().stop();
263 #[cfg(any(adc_g0, adc_v3, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))] 266 #[cfg(any(adc_g0, adc_v3, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))]
264 T::enable(); 267 T::regs().enable();
265 268
266 T::configure_sequence( 269 T::regs().configure_sequence(
267 sequence.map(|(channel, sample_time)| ((channel.channel, channel.is_differential), sample_time)), 270 sequence.map(|(channel, sample_time)| ((channel.channel, channel.is_differential), sample_time)),
268 ); 271 );
269 272
@@ -271,20 +274,20 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
271 // 274 //
272 // TODO: If hardware allows, enable after configure_sequence on all chips 275 // TODO: If hardware allows, enable after configure_sequence on all chips
273 #[cfg(any(adc_g4, adc_h5))] 276 #[cfg(any(adc_g4, adc_h5))]
274 T::enable(); 277 T::regs().enable();
275 T::configure_dma(ConversionMode::Singular); 278 T::regs().configure_dma(ConversionMode::Singular);
276 279
277 let request = rx_dma.request(); 280 let request = rx_dma.request();
278 let transfer = 281 let transfer =
279 unsafe { crate::dma::Transfer::new_read(rx_dma, request, T::dr(), readings, Default::default()) }; 282 unsafe { crate::dma::Transfer::new_read(rx_dma, request, T::regs().data(), readings, Default::default()) };
280 283
281 T::start(); 284 T::regs().start();
282 285
283 // Wait for conversion sequence to finish. 286 // Wait for conversion sequence to finish.
284 transfer.await; 287 transfer.await;
285 288
286 // Ensure conversions are finished. 289 // Ensure conversions are finished.
287 T::stop(); 290 T::regs().stop();
288 } 291 }
289 292
290 #[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))] 293 #[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))]
@@ -318,7 +321,7 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
318 self, 321 self,
319 dma: embassy_hal_internal::Peri<'a, impl RxDma<T>>, 322 dma: embassy_hal_internal::Peri<'a, impl RxDma<T>>,
320 dma_buf: &'a mut [u16], 323 dma_buf: &'a mut [u16],
321 sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<'b, T>, T::SampleTime)>, 324 sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<'b, T>, <T::Regs as BasicAdcRegs>::SampleTime)>,
322 mode: RegularConversionMode, 325 mode: RegularConversionMode,
323 ) -> RingBufferedAdc<'a, T> { 326 ) -> RingBufferedAdc<'a, T> {
324 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); 327 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
@@ -328,11 +331,11 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
328 "Asynchronous read sequence cannot be more than 16 in length" 331 "Asynchronous read sequence cannot be more than 16 in length"
329 ); 332 );
330 // Ensure no conversions are ongoing 333 // Ensure no conversions are ongoing
331 T::stop(); 334 T::regs().stop();
332 #[cfg(any(adc_g0, adc_v3, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))] 335 #[cfg(any(adc_g0, adc_v3, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))]
333 T::enable(); 336 T::regs().enable();
334 337
335 T::configure_sequence( 338 T::regs().configure_sequence(
336 sequence.map(|(channel, sample_time)| ((channel.channel, channel.is_differential), sample_time)), 339 sequence.map(|(channel, sample_time)| ((channel.channel, channel.is_differential), sample_time)),
337 ); 340 );
338 341
@@ -340,8 +343,8 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
340 // 343 //
341 // TODO: If hardware allows, enable after configure_sequence on all chips 344 // TODO: If hardware allows, enable after configure_sequence on all chips
342 #[cfg(any(adc_g4, adc_h5))] 345 #[cfg(any(adc_g4, adc_h5))]
343 T::enable(); 346 T::regs().enable();
344 T::configure_dma(ConversionMode::Repeated(mode)); 347 T::regs().configure_dma(ConversionMode::Repeated(mode));
345 348
346 core::mem::forget(self); 349 core::mem::forget(self);
347 350
@@ -442,8 +445,8 @@ pub struct AnyAdcChannel<'a, T> {
442 is_differential: bool, 445 is_differential: bool,
443 _phantom: PhantomData<&'a mut T>, 446 _phantom: PhantomData<&'a mut T>,
444} 447}
445impl<T: AnyInstance> AdcChannel<T> for AnyAdcChannel<'_, T> {} 448impl<T: Instance> AdcChannel<T> for AnyAdcChannel<'_, T> {}
446impl<T: AnyInstance> SealedAdcChannel<T> for AnyAdcChannel<'_, T> { 449impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<'_, T> {
447 fn channel(&self) -> u8 { 450 fn channel(&self) -> u8 {
448 self.channel 451 self.channel
449 } 452 }
@@ -459,16 +462,35 @@ impl<T> AnyAdcChannel<'_, T> {
459 self.channel 462 self.channel
460 } 463 }
461} 464}
465
466#[cfg(not(adc_wba))]
467impl BasicAdcRegs for crate::pac::adc::Adc {
468 type SampleTime = SampleTime;
469}
470
471#[cfg(any(adc_wba, adc_u5))]
472impl BasicAdcRegs for crate::pac::adc::Adc4 {
473 type SampleTime = Adc4SampleTime;
474}
475
462#[cfg(adc_wba)] 476#[cfg(adc_wba)]
463foreach_adc!( 477foreach_adc!(
464 (ADC4, $common_inst:ident, $clock:ident) => { 478 (ADC4, $common_inst:ident, $clock:ident) => {
465 impl crate::adc::adc4::SealedInstance for peripherals::ADC4 { 479 impl crate::adc::BasicInstance for peripherals::ADC4 {
466 fn regs() -> crate::pac::adc::Adc4 { 480 type Regs = crate::pac::adc::Adc4;
481 }
482
483 impl crate::adc::SealedInstance for peripherals::ADC4 {
484 fn regs() -> Self::Regs {
467 crate::pac::ADC4 485 crate::pac::ADC4
468 } 486 }
487
488 fn common_regs() -> crate::pac::adccommon::AdcCommon {
489 return crate::pac::$common_inst
490 }
469 } 491 }
470 492
471 impl crate::adc::adc4::Instance for peripherals::ADC4 { 493 impl crate::adc::Instance for peripherals::ADC4 {
472 type Interrupt = crate::_generated::peripheral_interrupts::ADC4::GLOBAL; 494 type Interrupt = crate::_generated::peripheral_interrupts::ADC4::GLOBAL;
473 } 495 }
474 }; 496 };
@@ -493,20 +515,32 @@ foreach_adc!(
493#[cfg(adc_u5)] 515#[cfg(adc_u5)]
494foreach_adc!( 516foreach_adc!(
495 (ADC4, $common_inst:ident, $clock:ident) => { 517 (ADC4, $common_inst:ident, $clock:ident) => {
496 impl crate::adc::adc4::SealedInstance for peripherals::ADC4 { 518 impl crate::adc::BasicInstance for peripherals::ADC4 {
497 fn regs() -> crate::pac::adc::Adc4 { 519 type Regs = crate::pac::adc::Adc4;
520 }
521
522 impl crate::adc::SealedInstance for peripherals::ADC4 {
523 fn regs() -> Self::Regs {
498 crate::pac::ADC4 524 crate::pac::ADC4
499 } 525 }
526
527 fn common_regs() -> crate::pac::adccommon::AdcCommon {
528 return crate::pac::$common_inst
529 }
500 } 530 }
501 531
502 impl crate::adc::adc4::Instance for peripherals::ADC4 { 532 impl crate::adc::Instance for peripherals::ADC4 {
503 type Interrupt = crate::_generated::peripheral_interrupts::ADC4::GLOBAL; 533 type Interrupt = crate::_generated::peripheral_interrupts::ADC4::GLOBAL;
504 } 534 }
505 }; 535 };
506 536
507 ($inst:ident, $common_inst:ident, $clock:ident) => { 537 ($inst:ident, $common_inst:ident, $clock:ident) => {
538 impl crate::adc::BasicInstance for peripherals::$inst {
539 type Regs = crate::pac::adc::Adc;
540 }
541
508 impl crate::adc::SealedInstance for peripherals::$inst { 542 impl crate::adc::SealedInstance for peripherals::$inst {
509 fn regs() -> crate::pac::adc::Adc { 543 fn regs() -> Self::Regs {
510 crate::pac::$inst 544 crate::pac::$inst
511 } 545 }
512 546
@@ -524,14 +558,23 @@ foreach_adc!(
524#[cfg(not(any(adc_u5, adc_wba)))] 558#[cfg(not(any(adc_u5, adc_wba)))]
525foreach_adc!( 559foreach_adc!(
526 ($inst:ident, $common_inst:ident, $clock:ident) => { 560 ($inst:ident, $common_inst:ident, $clock:ident) => {
561 impl crate::adc::BasicInstance for peripherals::$inst {
562 #[cfg(any(
563 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
564 ))]
565 type Regs = crate::pac::adc::Adc;
566 }
567
527 impl crate::adc::SealedInstance for peripherals::$inst { 568 impl crate::adc::SealedInstance for peripherals::$inst {
528 #[cfg(not(adc_wba))] 569 #[cfg(any(
529 fn regs() -> crate::pac::adc::Adc { 570 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
571 ))]
572 fn regs() -> Self::Regs {
530 crate::pac::$inst 573 crate::pac::$inst
531 } 574 }
532 575
533 #[cfg(adc_wba)] 576 #[cfg(any(adc_f1, adc_f3v1, adc_f3v2, adc_v1, adc_l0))]
534 fn regs() -> crate::pac::adc::Adc4 { 577 fn regs() -> crate::pac::adc::Adc {
535 crate::pac::$inst 578 crate::pac::$inst
536 } 579 }
537 580
diff --git a/embassy-stm32/src/adc/ringbuffered.rs b/embassy-stm32/src/adc/ringbuffered.rs
index 5437866d3..242a1a89c 100644
--- a/embassy-stm32/src/adc/ringbuffered.rs
+++ b/embassy-stm32/src/adc/ringbuffered.rs
@@ -4,7 +4,7 @@ use core::sync::atomic::{Ordering, compiler_fence};
4#[allow(unused_imports)] 4#[allow(unused_imports)]
5use embassy_hal_internal::Peri; 5use embassy_hal_internal::Peri;
6 6
7use crate::adc::AnyInstance; 7use super::AdcRegs;
8#[allow(unused_imports)] 8#[allow(unused_imports)]
9use crate::adc::{Instance, RxDma}; 9use crate::adc::{Instance, RxDma};
10#[allow(unused_imports)] 10#[allow(unused_imports)]
@@ -19,7 +19,7 @@ pub struct RingBufferedAdc<'d, T: Instance> {
19 ring_buf: ReadableRingBuffer<'d, u16>, 19 ring_buf: ReadableRingBuffer<'d, u16>,
20} 20}
21 21
22impl<'d, T: Instance + AnyInstance> RingBufferedAdc<'d, T> { 22impl<'d, T: Instance> RingBufferedAdc<'d, T> {
23 pub(crate) fn new(dma: Peri<'d, impl RxDma<T>>, dma_buf: &'d mut [u16]) -> Self { 23 pub(crate) fn new(dma: Peri<'d, impl RxDma<T>>, dma_buf: &'d mut [u16]) -> Self {
24 //dma side setup 24 //dma side setup
25 let opts = TransferOptions { 25 let opts = TransferOptions {
@@ -31,8 +31,7 @@ impl<'d, T: Instance + AnyInstance> RingBufferedAdc<'d, T> {
31 // Safety: we forget the struct before this function returns. 31 // Safety: we forget the struct before this function returns.
32 let request = dma.request(); 32 let request = dma.request();
33 33
34 let ring_buf = 34 let ring_buf = unsafe { ReadableRingBuffer::new(dma, request, T::regs().data(), dma_buf, opts) };
35 unsafe { ReadableRingBuffer::new(dma, request, T::regs().dr().as_ptr() as *mut u16, dma_buf, opts) };
36 35
37 Self { 36 Self {
38 _phantom: PhantomData, 37 _phantom: PhantomData,
@@ -45,7 +44,7 @@ impl<'d, T: Instance + AnyInstance> RingBufferedAdc<'d, T> {
45 compiler_fence(Ordering::SeqCst); 44 compiler_fence(Ordering::SeqCst);
46 self.ring_buf.start(); 45 self.ring_buf.start();
47 46
48 T::start(); 47 T::regs().start();
49 } 48 }
50 49
51 pub fn stop(&mut self) { 50 pub fn stop(&mut self) {
@@ -117,15 +116,15 @@ impl<'d, T: Instance + AnyInstance> RingBufferedAdc<'d, T> {
117 self.start(); 116 self.start();
118 } 117 }
119 118
120 #[cfg(adc_v2)] 119 // #[cfg(adc_v2)]
121 { 120 // {
122 // Clear overrun flag if set. 121 // // Clear overrun flag if set.
123 if T::regs().sr().read().ovr() { 122 // if T::regs().sr().read().ovr() {
124 self.stop(); 123 // self.stop();
125 124 //
126 return Err(OverrunError); 125 // return Err(OverrunError);
127 } 126 // }
128 } 127 // }
129 128
130 self.ring_buf.read_exact(measurements).await.map_err(|_| OverrunError) 129 self.ring_buf.read_exact(measurements).await.map_err(|_| OverrunError)
131 } 130 }
@@ -143,15 +142,16 @@ impl<'d, T: Instance + AnyInstance> RingBufferedAdc<'d, T> {
143 self.start(); 142 self.start();
144 } 143 }
145 144
146 #[cfg(adc_v2)] 145 // #[cfg(adc_v2)]
147 { 146 // {
148 // Clear overrun flag if set. 147 // // Clear overrun flag if set.
149 if T::regs().sr().read().ovr() { 148 // if T::regs().sr().read().ovr() {
150 self.stop(); 149 // self.stop();
150 //
151 // return Err(OverrunError);
152 // }
153 // }
151 154
152 return Err(OverrunError);
153 }
154 }
155 loop { 155 loop {
156 match self.ring_buf.read(buf) { 156 match self.ring_buf.read(buf) {
157 Ok((0, _)) => {} 157 Ok((0, _)) => {}
@@ -168,9 +168,9 @@ impl<'d, T: Instance + AnyInstance> RingBufferedAdc<'d, T> {
168 } 168 }
169} 169}
170 170
171impl<T: Instance + AnyInstance> Drop for RingBufferedAdc<'_, T> { 171impl<T: Instance> Drop for RingBufferedAdc<'_, T> {
172 fn drop(&mut self) { 172 fn drop(&mut self) {
173 T::stop(); 173 T::regs().stop();
174 174
175 compiler_fence(Ordering::SeqCst); 175 compiler_fence(Ordering::SeqCst);
176 176
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 }
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index b270588c4..9cc44aa9a 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -146,63 +146,63 @@ pub struct AdcConfig {
146 pub averaging: Option<Averaging>, 146 pub averaging: Option<Averaging>,
147} 147}
148 148
149impl<T: Instance> super::SealedAnyInstance for T { 149impl super::AdcRegs for crate::pac::adc::Adc {
150 fn dr() -> *mut u16 { 150 fn data(&self) -> *mut u16 {
151 T::regs().dr().as_ptr() as *mut u16 151 crate::pac::adc::Adc::dr(*self).as_ptr() as *mut u16
152 } 152 }
153 153
154 // Enable ADC only when it is not already running. 154 // Enable ADC only when it is not already running.
155 fn enable() { 155 fn enable(&self) {
156 // Make sure bits are off 156 // Make sure bits are off
157 while T::regs().cr().read().addis() { 157 while self.cr().read().addis() {
158 // spin 158 // spin
159 } 159 }
160 160
161 if !T::regs().cr().read().aden() { 161 if !self.cr().read().aden() {
162 // Enable ADC 162 // Enable ADC
163 T::regs().isr().modify(|reg| { 163 self.isr().modify(|reg| {
164 reg.set_adrdy(true); 164 reg.set_adrdy(true);
165 }); 165 });
166 T::regs().cr().modify(|reg| { 166 self.cr().modify(|reg| {
167 reg.set_aden(true); 167 reg.set_aden(true);
168 }); 168 });
169 169
170 while !T::regs().isr().read().adrdy() { 170 while !self.isr().read().adrdy() {
171 // spin 171 // spin
172 } 172 }
173 } 173 }
174 } 174 }
175 175
176 fn start() { 176 fn start(&self) {
177 T::regs().cr().modify(|reg| { 177 self.cr().modify(|reg| {
178 reg.set_adstart(true); 178 reg.set_adstart(true);
179 }); 179 });
180 } 180 }
181 181
182 fn stop() { 182 fn stop(&self) {
183 // Ensure conversions are finished. 183 // Ensure conversions are finished.
184 if T::regs().cr().read().adstart() && !T::regs().cr().read().addis() { 184 if self.cr().read().adstart() && !self.cr().read().addis() {
185 T::regs().cr().modify(|reg| { 185 self.cr().modify(|reg| {
186 reg.set_adstp(true); 186 reg.set_adstp(true);
187 }); 187 });
188 while T::regs().cr().read().adstart() {} 188 while self.cr().read().adstart() {}
189 } 189 }
190 190
191 // Reset configuration. 191 // Reset configuration.
192 #[cfg(not(any(adc_g0, adc_u0)))] 192 #[cfg(not(any(adc_g0, adc_u0)))]
193 T::regs().cfgr().modify(|reg| { 193 self.cfgr().modify(|reg| {
194 reg.set_cont(false); 194 reg.set_cont(false);
195 reg.set_dmaen(false); 195 reg.set_dmaen(false);
196 }); 196 });
197 #[cfg(any(adc_g0, adc_u0))] 197 #[cfg(any(adc_g0, adc_u0))]
198 T::regs().cfgr1().modify(|reg| { 198 self.cfgr1().modify(|reg| {
199 reg.set_cont(false); 199 reg.set_cont(false);
200 reg.set_dmaen(false); 200 reg.set_dmaen(false);
201 }); 201 });
202 } 202 }
203 203
204 /// Perform a single conversion. 204 /// Perform a single conversion.
205 fn convert() -> u16 { 205 fn convert(&self) {
206 // Some models are affected by an erratum: 206 // Some models are affected by an erratum:
207 // If we perform conversions slower than 1 kHz, the first read ADC value can be 207 // If we perform conversions slower than 1 kHz, the first read ADC value can be
208 // corrupted, so we discard it and measure again. 208 // corrupted, so we discard it and measure again.
@@ -216,36 +216,34 @@ impl<T: Instance> super::SealedAnyInstance for T {
216 let len = 1; 216 let len = 1;
217 217
218 for _ in 0..len { 218 for _ in 0..len {
219 T::regs().isr().modify(|reg| { 219 self.isr().modify(|reg| {
220 reg.set_eos(true); 220 reg.set_eos(true);
221 reg.set_eoc(true); 221 reg.set_eoc(true);
222 }); 222 });
223 223
224 // Start conversion 224 // Start conversion
225 T::regs().cr().modify(|reg| { 225 self.cr().modify(|reg| {
226 reg.set_adstart(true); 226 reg.set_adstart(true);
227 }); 227 });
228 228
229 while !T::regs().isr().read().eos() { 229 while !self.isr().read().eos() {
230 // spin 230 // spin
231 } 231 }
232 } 232 }
233
234 T::regs().dr().read().0 as u16
235 } 233 }
236 234
237 fn configure_dma(conversion_mode: ConversionMode) { 235 fn configure_dma(&self, conversion_mode: ConversionMode) {
238 // Set continuous mode with oneshot dma. 236 // Set continuous mode with oneshot dma.
239 // Clear overrun flag before starting transfer. 237 // Clear overrun flag before starting transfer.
240 T::regs().isr().modify(|reg| { 238 self.isr().modify(|reg| {
241 reg.set_ovr(true); 239 reg.set_ovr(true);
242 }); 240 });
243 241
244 #[cfg(not(any(adc_g0, adc_u0)))] 242 #[cfg(not(any(adc_g0, adc_u0)))]
245 let regs = T::regs().cfgr(); 243 let regs = self.cfgr();
246 244
247 #[cfg(any(adc_g0, adc_u0))] 245 #[cfg(any(adc_g0, adc_u0))]
248 let regs = T::regs().cfgr1(); 246 let regs = self.cfgr1();
249 247
250 regs.modify(|reg| { 248 regs.modify(|reg| {
251 reg.set_discen(false); 249 reg.set_discen(false);
@@ -259,13 +257,13 @@ impl<T: Instance> super::SealedAnyInstance for T {
259 }); 257 });
260 } 258 }
261 259
262 fn configure_sequence(sequence: impl ExactSizeIterator<Item = ((u8, bool), SampleTime)>) { 260 fn configure_sequence(&self, sequence: impl ExactSizeIterator<Item = ((u8, bool), SampleTime)>) {
263 #[cfg(adc_h5)] 261 #[cfg(adc_h5)]
264 T::regs().cr().modify(|w| w.set_aden(false)); 262 self.cr().modify(|w| w.set_aden(false));
265 263
266 // Set sequence length 264 // Set sequence length
267 #[cfg(not(any(adc_g0, adc_u0)))] 265 #[cfg(not(any(adc_g0, adc_u0)))]
268 T::regs().sqr1().modify(|w| { 266 self.sqr1().modify(|w| {
269 w.set_l(sequence.len() as u8 - 1); 267 w.set_l(sequence.len() as u8 - 1);
270 }); 268 });
271 269
@@ -273,8 +271,8 @@ impl<T: Instance> super::SealedAnyInstance for T {
273 { 271 {
274 let mut sample_times = Vec::<SampleTime, SAMPLE_TIMES_CAPACITY>::new(); 272 let mut sample_times = Vec::<SampleTime, SAMPLE_TIMES_CAPACITY>::new();
275 273
276 T::regs().chselr().write(|chselr| { 274 self.chselr().write(|chselr| {
277 T::regs().smpr().write(|smpr| { 275 self.smpr().write(|smpr| {
278 for ((channel, _), sample_time) in sequence { 276 for ((channel, _), sample_time) in sequence {
279 chselr.set_chsel(channel.into(), true); 277 chselr.set_chsel(channel.into(), true);
280 if let Some(i) = sample_times.iter().position(|&t| t == sample_time) { 278 if let Some(i) = sample_times.iter().position(|&t| t == sample_time) {
@@ -306,22 +304,22 @@ impl<T: Instance> super::SealedAnyInstance for T {
306 // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected." 304 // "This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected."
307 #[cfg(any(adc_h5, adc_h7rs))] 305 #[cfg(any(adc_h5, adc_h7rs))]
308 if channel == 0 { 306 if channel == 0 {
309 T::regs().or().modify(|reg| reg.set_op0(true)); 307 self.or().modify(|reg| reg.set_op0(true));
310 } 308 }
311 309
312 // Configure channel 310 // Configure channel
313 cfg_if! { 311 cfg_if! {
314 if #[cfg(adc_u0)] { 312 if #[cfg(adc_u0)] {
315 // On G0 and U6 all channels use the same sampling time. 313 // On G0 and U6 all channels use the same sampling time.
316 T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.into())); 314 self.smpr().modify(|reg| reg.set_smp1(sample_time.into()));
317 } else if #[cfg(any(adc_h5, adc_h7rs))] { 315 } else if #[cfg(any(adc_h5, adc_h7rs))] {
318 match channel { 316 match channel {
319 0..=9 => T::regs().smpr1().modify(|w| w.set_smp(channel as usize % 10, sample_time.into())), 317 0..=9 => self.smpr1().modify(|w| w.set_smp(channel as usize % 10, sample_time.into())),
320 _ => T::regs().smpr2().modify(|w| w.set_smp(channel as usize % 10, sample_time.into())), 318 _ => self.smpr2().modify(|w| w.set_smp(channel as usize % 10, sample_time.into())),
321 } 319 }
322 } else { 320 } else {
323 let sample_time = sample_time.into(); 321 let sample_time = sample_time.into();
324 T::regs() 322 self
325 .smpr(channel as usize / 10) 323 .smpr(channel as usize / 10)
326 .modify(|reg| reg.set_smp(channel as usize % 10, sample_time)); 324 .modify(|reg| reg.set_smp(channel as usize % 10, sample_time));
327 } 325 }
@@ -331,9 +329,8 @@ impl<T: Instance> super::SealedAnyInstance for T {
331 { 329 {
332 use crate::pac::adc::vals::Pcsel; 330 use crate::pac::adc::vals::Pcsel;
333 331
334 T::regs().cfgr2().modify(|w| w.set_lshift(0)); 332 self.cfgr2().modify(|w| w.set_lshift(0));
335 T::regs() 333 self.pcsel()
336 .pcsel()
337 .write(|w| w.set_pcsel(channel.channel() as _, Pcsel::PRESELECTED)); 334 .write(|w| w.set_pcsel(channel.channel() as _, Pcsel::PRESELECTED));
338 } 335 }
339 336
@@ -341,22 +338,22 @@ impl<T: Instance> super::SealedAnyInstance for T {
341 #[cfg(not(any(adc_g0, adc_u0)))] 338 #[cfg(not(any(adc_g0, adc_u0)))]
342 match _i { 339 match _i {
343 0..=3 => { 340 0..=3 => {
344 T::regs().sqr1().modify(|w| { 341 self.sqr1().modify(|w| {
345 w.set_sq(_i, channel); 342 w.set_sq(_i, channel);
346 }); 343 });
347 } 344 }
348 4..=8 => { 345 4..=8 => {
349 T::regs().sqr2().modify(|w| { 346 self.sqr2().modify(|w| {
350 w.set_sq(_i - 4, channel); 347 w.set_sq(_i - 4, channel);
351 }); 348 });
352 } 349 }
353 9..=13 => { 350 9..=13 => {
354 T::regs().sqr3().modify(|w| { 351 self.sqr3().modify(|w| {
355 w.set_sq(_i - 9, channel); 352 w.set_sq(_i - 9, channel);
356 }); 353 });
357 } 354 }
358 14..=15 => { 355 14..=15 => {
359 T::regs().sqr4().modify(|w| { 356 self.sqr4().modify(|w| {
360 w.set_sq(_i - 14, channel); 357 w.set_sq(_i - 14, channel);
361 }); 358 });
362 } 359 }
@@ -375,20 +372,20 @@ impl<T: Instance> super::SealedAnyInstance for T {
375 } 372 }
376 373
377 #[cfg(adc_h5)] 374 #[cfg(adc_h5)]
378 T::regs().difsel().write(|w| w.set_difsel(difsel)); 375 self.difsel().write(|w| w.set_difsel(difsel));
379 376
380 // On G0 and U0 enabled channels are sampled from 0 to last channel. 377 // On G0 and U0 enabled channels are sampled from 0 to last channel.
381 // It is possible to add up to 8 sequences if CHSELRMOD = 1. 378 // It is possible to add up to 8 sequences if CHSELRMOD = 1.
382 // However for supporting more than 8 channels alternative CHSELRMOD = 0 approach is used. 379 // However for supporting more than 8 channels alternative CHSELRMOD = 0 approach is used.
383 #[cfg(adc_u0)] 380 #[cfg(adc_u0)]
384 T::regs().chselr().modify(|reg| { 381 self.chselr().modify(|reg| {
385 reg.set_chsel(channel_mask); 382 reg.set_chsel(channel_mask);
386 }); 383 });
387 } 384 }
388 } 385 }
389} 386}
390 387
391impl<'d, T: Instance> Adc<'d, T> { 388impl<'d, T: Instance<Regs = crate::pac::adc::Adc>> Adc<'d, T> {
392 /// Enable the voltage regulator 389 /// Enable the voltage regulator
393 fn init_regulator() { 390 fn init_regulator() {
394 rcc::enable_and_reset::<T>(); 391 rcc::enable_and_reset::<T>();
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| {