aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-09-28 01:59:51 +0000
committerGitHub <[email protected]>2023-09-28 01:59:51 +0000
commit901d31e8f8b982ff041452038102b46e7314b201 (patch)
tree88c5620e1dd3c403ff937b6ad9b8a1054cfc3439 /embassy-stm32
parentfec4194ae61f9c227c5e6df1e2d8f1344bb6a990 (diff)
parent79146c4bd5cdbd8337d0dbdfd93219b9cb330c47 (diff)
Merge pull request #1933 from xoviat/adc
stm32: more adc cleanup
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/adc/f1.rs51
-rw-r--r--embassy-stm32/src/adc/f3.rs20
-rw-r--r--embassy-stm32/src/adc/mod.rs18
-rw-r--r--embassy-stm32/src/adc/v1.rs35
-rw-r--r--embassy-stm32/src/adc/v2.rs36
5 files changed, 103 insertions, 57 deletions
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index 147349de6..c13264819 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -1,16 +1,37 @@
1use core::future::poll_fn;
2use core::marker::PhantomData;
3use core::task::Poll;
4
1use embassy_hal_internal::into_ref; 5use embassy_hal_internal::into_ref;
2use embedded_hal_02::blocking::delay::DelayUs; 6use embedded_hal_02::blocking::delay::DelayUs;
3 7
4use crate::adc::{Adc, AdcPin, Instance, SampleTime}; 8use crate::adc::{Adc, AdcPin, Instance, SampleTime};
5use crate::rcc::get_freqs; 9use crate::rcc::get_freqs;
6use crate::time::Hertz; 10use crate::time::Hertz;
7use crate::Peripheral; 11use crate::{interrupt, Peripheral};
8 12
9pub const VDDA_CALIB_MV: u32 = 3300; 13pub const VDDA_CALIB_MV: u32 = 3300;
10pub const ADC_MAX: u32 = (1 << 12) - 1; 14pub const ADC_MAX: u32 = (1 << 12) - 1;
11// No calibration data for F103, voltage should be 1.2v 15// No calibration data for F103, voltage should be 1.2v
12pub const VREF_INT: u32 = 1200; 16pub const VREF_INT: u32 = 1200;
13 17
18/// Interrupt handler.
19pub struct InterruptHandler<T: Instance> {
20 _phantom: PhantomData<T>,
21}
22
23impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
24 unsafe fn on_interrupt() {
25 if T::regs().sr().read().eoc() {
26 T::regs().cr1().modify(|w| w.set_eocie(false));
27 } else {
28 return;
29 }
30
31 T::state().waker.wake();
32 }
33}
34
14pub struct Vref; 35pub struct Vref;
15impl<T: Instance> AdcPin<T> for Vref {} 36impl<T: Instance> AdcPin<T> for Vref {}
16impl<T: Instance> super::sealed::AdcPin<T> for Vref { 37impl<T: Instance> super::sealed::AdcPin<T> for Vref {
@@ -95,18 +116,28 @@ impl<'d, T: Instance> Adc<'d, T> {
95 } 116 }
96 117
97 /// Perform a single conversion. 118 /// Perform a single conversion.
98 fn convert(&mut self) -> u16 { 119 async fn convert(&mut self) -> u16 {
99 T::regs().cr2().modify(|reg| { 120 T::regs().cr2().modify(|reg| {
100 reg.set_adon(true); 121 reg.set_adon(true);
101 reg.set_swstart(true); 122 reg.set_swstart(true);
102 }); 123 });
103 while T::regs().cr2().read().swstart() {} 124 T::regs().cr1().modify(|w| w.set_eocie(true));
104 while !T::regs().sr().read().eoc() {} 125
126 poll_fn(|cx| {
127 T::state().waker.register(cx.waker());
128
129 if !T::regs().cr2().read().swstart() && T::regs().sr().read().eoc() {
130 Poll::Ready(())
131 } else {
132 Poll::Pending
133 }
134 })
135 .await;
105 136
106 T::regs().dr().read().0 as u16 137 T::regs().dr().read().0 as u16
107 } 138 }
108 139
109 pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 { 140 pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
110 Self::set_channel_sample_time(pin.channel(), self.sample_time); 141 Self::set_channel_sample_time(pin.channel(), self.sample_time);
111 T::regs().cr1().modify(|reg| { 142 T::regs().cr1().modify(|reg| {
112 reg.set_scan(false); 143 reg.set_scan(false);
@@ -123,7 +154,7 @@ impl<'d, T: Instance> Adc<'d, T> {
123 154
124 // Configure the channel to sample 155 // Configure the channel to sample
125 T::regs().sqr3().write(|reg| reg.set_sq(0, pin.channel())); 156 T::regs().sqr3().write(|reg| reg.set_sq(0, pin.channel()));
126 self.convert() 157 self.convert().await
127 } 158 }
128 159
129 fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { 160 fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
@@ -135,3 +166,11 @@ impl<'d, T: Instance> Adc<'d, T> {
135 } 166 }
136 } 167 }
137} 168}
169
170impl<'d, T: Instance> Drop for Adc<'d, T> {
171 fn drop(&mut self) {
172 T::regs().cr2().modify(|reg| reg.set_adon(false));
173
174 T::disable();
175 }
176}
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index 5d2ea1daa..7c13f8106 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -173,3 +173,23 @@ impl<'d, T: Instance> Adc<'d, T> {
173 } 173 }
174 } 174 }
175} 175}
176
177impl<'d, T: Instance> Drop for Adc<'d, T> {
178 fn drop(&mut self) {
179 use crate::pac::adc::vals;
180
181 T::regs().cr().modify(|w| w.set_adstp(true));
182
183 while T::regs().cr().read().adstp() {}
184
185 T::regs().cr().modify(|w| w.set_addis(true));
186
187 while T::regs().cr().read().aden() {}
188
189 // Disable the adc regulator
190 T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE));
191 T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::DISABLED));
192
193 T::disable();
194 }
195}
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 2f8f8f9e3..365738a31 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -31,15 +31,15 @@ pub struct Adc<'d, T: Instance> {
31} 31}
32 32
33pub(crate) mod sealed { 33pub(crate) mod sealed {
34 #[cfg(any(adc_f3, adc_v1))] 34 #[cfg(any(adc_f1, adc_f3, adc_v1))]
35 use embassy_sync::waitqueue::AtomicWaker; 35 use embassy_sync::waitqueue::AtomicWaker;
36 36
37 #[cfg(any(adc_f3, adc_v1))] 37 #[cfg(any(adc_f1, adc_f3, adc_v1))]
38 pub struct State { 38 pub struct State {
39 pub waker: AtomicWaker, 39 pub waker: AtomicWaker,
40 } 40 }
41 41
42 #[cfg(any(adc_f3, adc_v1))] 42 #[cfg(any(adc_f1, adc_f3, adc_v1))]
43 impl State { 43 impl State {
44 pub const fn new() -> Self { 44 pub const fn new() -> Self {
45 Self { 45 Self {
@@ -58,11 +58,14 @@ pub(crate) mod sealed {
58 fn common_regs() -> crate::pac::adccommon::AdcCommon; 58 fn common_regs() -> crate::pac::adccommon::AdcCommon;
59 #[cfg(adc_f3)] 59 #[cfg(adc_f3)]
60 fn frequency() -> crate::time::Hertz; 60 fn frequency() -> crate::time::Hertz;
61 #[cfg(any(adc_f3, adc_v1))] 61 #[cfg(any(adc_f1, adc_f3, adc_v1))]
62 fn state() -> &'static State; 62 fn state() -> &'static State;
63 } 63 }
64 64
65 pub trait AdcPin<T: Instance> { 65 pub trait AdcPin<T: Instance> {
66 #[cfg(any(adc_v1, adc_v2))]
67 fn set_as_analog(&mut self) {}
68
66 fn channel(&self) -> u8; 69 fn channel(&self) -> u8;
67 } 70 }
68 71
@@ -96,7 +99,7 @@ foreach_adc!(
96 unsafe { crate::rcc::get_freqs() }.$clock.unwrap() 99 unsafe { crate::rcc::get_freqs() }.$clock.unwrap()
97 } 100 }
98 101
99 #[cfg(any(adc_f3, adc_v1))] 102 #[cfg(any(adc_f1, adc_f3, adc_v1))]
100 fn state() -> &'static sealed::State { 103 fn state() -> &'static sealed::State {
101 static STATE: sealed::State = sealed::State::new(); 104 static STATE: sealed::State = sealed::State::new();
102 &STATE 105 &STATE
@@ -120,6 +123,11 @@ macro_rules! impl_adc_pin {
120 impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {} 123 impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
121 124
122 impl crate::adc::sealed::AdcPin<peripherals::$inst> for crate::peripherals::$pin { 125 impl crate::adc::sealed::AdcPin<peripherals::$inst> for crate::peripherals::$pin {
126 #[cfg(any(adc_v1, adc_v2))]
127 fn set_as_analog(&mut self) {
128 <Self as crate::gpio::sealed::Pin>::set_as_analog(self);
129 }
130
123 fn channel(&self) -> u8 { 131 fn channel(&self) -> u8 {
124 $ch 132 $ch
125 } 133 }
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index 15b2dc593..fded26e40 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -5,7 +5,7 @@ use core::task::Poll;
5use embassy_hal_internal::into_ref; 5use embassy_hal_internal::into_ref;
6use embedded_hal_02::blocking::delay::DelayUs; 6use embedded_hal_02::blocking::delay::DelayUs;
7 7
8use crate::adc::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime}; 8use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
9use crate::interrupt::typelevel::Interrupt; 9use crate::interrupt::typelevel::Interrupt;
10use crate::peripherals::ADC; 10use crate::peripherals::ADC;
11use crate::{interrupt, Peripheral}; 11use crate::{interrupt, Peripheral};
@@ -31,24 +31,24 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
31} 31}
32 32
33pub struct Vbat; 33pub struct Vbat;
34impl InternalChannel<ADC> for Vbat {} 34impl AdcPin<ADC> for Vbat {}
35impl super::sealed::InternalChannel<ADC> for Vbat { 35impl super::sealed::AdcPin<ADC> for Vbat {
36 fn channel(&self) -> u8 { 36 fn channel(&self) -> u8 {
37 18 37 18
38 } 38 }
39} 39}
40 40
41pub struct Vref; 41pub struct Vref;
42impl InternalChannel<ADC> for Vref {} 42impl AdcPin<ADC> for Vref {}
43impl super::sealed::InternalChannel<ADC> for Vref { 43impl super::sealed::AdcPin<ADC> for Vref {
44 fn channel(&self) -> u8 { 44 fn channel(&self) -> u8 {
45 17 45 17
46 } 46 }
47} 47}
48 48
49pub struct Temperature; 49pub struct Temperature;
50impl InternalChannel<ADC> for Temperature {} 50impl AdcPin<ADC> for Temperature {}
51impl super::sealed::InternalChannel<ADC> for Temperature { 51impl super::sealed::AdcPin<ADC> for Temperature {
52 fn channel(&self) -> u8 { 52 fn channel(&self) -> u8 {
53 16 53 16
54 } 54 }
@@ -134,18 +134,14 @@ impl<'d, T: Instance> Adc<'d, T> {
134 T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into())); 134 T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into()));
135 } 135 }
136 136
137 pub async fn read<P>(&mut self, pin: &mut P) -> u16 137 pub async fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
138 where
139 P: AdcPin<T> + crate::gpio::sealed::Pin,
140 {
141 let channel = pin.channel(); 138 let channel = pin.channel();
142 pin.set_as_analog(); 139 pin.set_as_analog();
143 self.read_channel(channel).await
144 }
145 140
146 pub async fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 { 141 // A.7.5 Single conversion sequence code example - Software trigger
147 let channel = channel.channel(); 142 T::regs().chselr().write(|reg| reg.set_chselx(channel as usize, true));
148 self.read_channel(channel).await 143
144 self.convert().await
149 } 145 }
150 146
151 async fn convert(&mut self) -> u16 { 147 async fn convert(&mut self) -> u16 {
@@ -171,13 +167,6 @@ impl<'d, T: Instance> Adc<'d, T> {
171 167
172 T::regs().dr().read().data() 168 T::regs().dr().read().data()
173 } 169 }
174
175 async fn read_channel(&mut self, channel: u8) -> u16 {
176 // A.7.5 Single conversion sequence code example - Software trigger
177 T::regs().chselr().write(|reg| reg.set_chselx(channel as usize, true));
178
179 self.convert().await
180 }
181} 170}
182 171
183impl<'d, T: Instance> Drop for Adc<'d, T> { 172impl<'d, T: Instance> Drop for Adc<'d, T> {
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index f583c08a9..a669013c9 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,7 +1,6 @@
1use embassy_hal_internal::into_ref; 1use embassy_hal_internal::into_ref;
2use embedded_hal_02::blocking::delay::DelayUs; 2use embedded_hal_02::blocking::delay::DelayUs;
3 3
4use super::InternalChannel;
5use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; 4use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
6use crate::peripherals::ADC1; 5use crate::peripherals::ADC1;
7use crate::time::Hertz; 6use crate::time::Hertz;
@@ -16,8 +15,8 @@ pub const VREF_CALIB_MV: u32 = 3300;
16pub const ADC_POWERUP_TIME_US: u32 = 3; 15pub const ADC_POWERUP_TIME_US: u32 = 3;
17 16
18pub struct VrefInt; 17pub struct VrefInt;
19impl InternalChannel<ADC1> for VrefInt {} 18impl AdcPin<ADC1> for VrefInt {}
20impl super::sealed::InternalChannel<ADC1> for VrefInt { 19impl super::sealed::AdcPin<ADC1> for VrefInt {
21 fn channel(&self) -> u8 { 20 fn channel(&self) -> u8 {
22 17 21 17
23 } 22 }
@@ -31,8 +30,8 @@ impl VrefInt {
31} 30}
32 31
33pub struct Temperature; 32pub struct Temperature;
34impl InternalChannel<ADC1> for Temperature {} 33impl AdcPin<ADC1> for Temperature {}
35impl super::sealed::InternalChannel<ADC1> for Temperature { 34impl super::sealed::AdcPin<ADC1> for Temperature {
36 fn channel(&self) -> u8 { 35 fn channel(&self) -> u8 {
37 cfg_if::cfg_if! { 36 cfg_if::cfg_if! {
38 if #[cfg(any(stm32f40, stm32f41))] { 37 if #[cfg(any(stm32f40, stm32f41))] {
@@ -52,8 +51,8 @@ impl Temperature {
52} 51}
53 52
54pub struct Vbat; 53pub struct Vbat;
55impl InternalChannel<ADC1> for Vbat {} 54impl AdcPin<ADC1> for Vbat {}
56impl super::sealed::InternalChannel<ADC1> for Vbat { 55impl super::sealed::AdcPin<ADC1> for Vbat {
57 fn channel(&self) -> u8 { 56 fn channel(&self) -> u8 {
58 18 57 18
59 } 58 }
@@ -176,22 +175,11 @@ where
176 T::regs().dr().read().0 as u16 175 T::regs().dr().read().0 as u16
177 } 176 }
178 177
179 pub fn read<P>(&mut self, pin: &mut P) -> u16 178 pub fn read(&mut self, pin: &mut impl AdcPin<T>) -> u16 {
180 where
181 P: AdcPin<T>,
182 P: crate::gpio::sealed::Pin,
183 {
184 pin.set_as_analog(); 179 pin.set_as_analog();
185 180
186 self.read_channel(pin.channel())
187 }
188
189 pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 {
190 self.read_channel(channel.channel())
191 }
192
193 fn read_channel(&mut self, channel: u8) -> u16 {
194 // Configure ADC 181 // Configure ADC
182 let channel = pin.channel();
195 183
196 // Select channel 184 // Select channel
197 T::regs().sqr3().write(|reg| reg.set_sq(0, channel)); 185 T::regs().sqr3().write(|reg| reg.set_sq(0, channel));
@@ -199,9 +187,7 @@ where
199 // Configure channel 187 // Configure channel
200 Self::set_channel_sample_time(channel, self.sample_time); 188 Self::set_channel_sample_time(channel, self.sample_time);
201 189
202 let val = self.convert(); 190 self.convert()
203
204 val
205 } 191 }
206 192
207 fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { 193 fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
@@ -216,6 +202,10 @@ where
216 202
217impl<'d, T: Instance> Drop for Adc<'d, T> { 203impl<'d, T: Instance> Drop for Adc<'d, T> {
218 fn drop(&mut self) { 204 fn drop(&mut self) {
205 T::regs().cr2().modify(|reg| {
206 reg.set_adon(false);
207 });
208
219 T::disable(); 209 T::disable();
220 } 210 }
221} 211}