aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/adc/c0.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/adc/c0.rs')
-rw-r--r--embassy-stm32/src/adc/c0.rs64
1 files changed, 31 insertions, 33 deletions
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| {