aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrant Miller <[email protected]>2023-04-05 14:31:32 -0500
committerGrant Miller <[email protected]>2023-04-05 15:01:31 -0500
commitf5881054297713f6224d5d81f407f8a6cf591ef4 (patch)
tree6c44d00677c38ee045b649863387ca6d2224d218
parent28b8ac4b62d952918ddfe143cf6925e1402fc2ce (diff)
wip
-rw-r--r--embassy-stm32/src/adc/mod.rs11
-rw-r--r--embassy-stm32/src/adc/resolution.rs8
-rw-r--r--embassy-stm32/src/adc/sample_time.rs2
-rw-r--r--embassy-stm32/src/adc/v1.rs129
4 files changed, 20 insertions, 130 deletions
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index ec49dace7..56ecd63ca 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -7,21 +7,18 @@
7#[cfg_attr(adc_v4, path = "v4.rs")] 7#[cfg_attr(adc_v4, path = "v4.rs")]
8mod _version; 8mod _version;
9 9
10#[cfg(not(any(adc_f1, adc_v1)))] 10#[cfg(not(adc_f1))]
11mod resolution; 11mod resolution;
12#[cfg(not(adc_v1))]
13mod sample_time; 12mod sample_time;
14 13
15#[allow(unused)] 14#[allow(unused)]
16pub use _version::*; 15pub use _version::*;
17#[cfg(not(any(adc_f1, adc_v1)))] 16#[cfg(not(adc_f1))]
18pub use resolution::Resolution; 17pub use resolution::Resolution;
19#[cfg(not(adc_v1))]
20pub use sample_time::SampleTime; 18pub use sample_time::SampleTime;
21 19
22use crate::peripherals; 20use crate::peripherals;
23 21
24#[cfg(not(adc_v1))]
25pub struct Adc<'d, T: Instance> { 22pub struct Adc<'d, T: Instance> {
26 #[allow(unused)] 23 #[allow(unused)]
27 adc: crate::PeripheralRef<'d, T>, 24 adc: crate::PeripheralRef<'d, T>,
@@ -44,9 +41,9 @@ pub(crate) mod sealed {
44 } 41 }
45} 42}
46 43
47#[cfg(not(any(adc_f1, adc_v2, adc_v4)))] 44#[cfg(not(any(adc_f1, adc_v1, adc_v2, adc_v4)))]
48pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {} 45pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {}
49#[cfg(any(adc_f1, adc_v2, adc_v4))] 46#[cfg(any(adc_f1, adc_v1, adc_v2, adc_v4))]
50pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {} 47pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {}
51 48
52pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} 49pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {}
diff --git a/embassy-stm32/src/adc/resolution.rs b/embassy-stm32/src/adc/resolution.rs
index 62b52a46c..67fb9b8c0 100644
--- a/embassy-stm32/src/adc/resolution.rs
+++ b/embassy-stm32/src/adc/resolution.rs
@@ -1,4 +1,4 @@
1#[cfg(any(adc_v2, adc_v3, adc_g0))] 1#[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0))]
2#[derive(Clone, Copy, Debug, Eq, PartialEq)] 2#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3pub enum Resolution { 3pub enum Resolution {
4 TwelveBit, 4 TwelveBit,
@@ -19,7 +19,7 @@ pub enum Resolution {
19 19
20impl Default for Resolution { 20impl Default for Resolution {
21 fn default() -> Self { 21 fn default() -> Self {
22 #[cfg(any(adc_v2, adc_v3, adc_g0))] 22 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0))]
23 { 23 {
24 Self::TwelveBit 24 Self::TwelveBit
25 } 25 }
@@ -40,7 +40,7 @@ impl From<Resolution> for crate::pac::adc::vals::Res {
40 Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT, 40 Resolution::TwelveBit => crate::pac::adc::vals::Res::TWELVEBIT,
41 Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT, 41 Resolution::TenBit => crate::pac::adc::vals::Res::TENBIT,
42 Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT, 42 Resolution::EightBit => crate::pac::adc::vals::Res::EIGHTBIT,
43 #[cfg(any(adc_v2, adc_v3, adc_g0))] 43 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0))]
44 Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT, 44 Resolution::SixBit => crate::pac::adc::vals::Res::SIXBIT,
45 } 45 }
46 } 46 }
@@ -56,7 +56,7 @@ impl Resolution {
56 Resolution::TwelveBit => (1 << 12) - 1, 56 Resolution::TwelveBit => (1 << 12) - 1,
57 Resolution::TenBit => (1 << 10) - 1, 57 Resolution::TenBit => (1 << 10) - 1,
58 Resolution::EightBit => (1 << 8) - 1, 58 Resolution::EightBit => (1 << 8) - 1,
59 #[cfg(any(adc_v2, adc_v3, adc_g0))] 59 #[cfg(any(adc_v1, adc_v2, adc_v3, adc_g0))]
60 Resolution::SixBit => (1 << 6) - 1, 60 Resolution::SixBit => (1 << 6) - 1,
61 } 61 }
62 } 62 }
diff --git a/embassy-stm32/src/adc/sample_time.rs b/embassy-stm32/src/adc/sample_time.rs
index bc5fb1d6f..0faa1e3c0 100644
--- a/embassy-stm32/src/adc/sample_time.rs
+++ b/embassy-stm32/src/adc/sample_time.rs
@@ -25,7 +25,7 @@ macro_rules! impl_sample_time {
25 }; 25 };
26} 26}
27 27
28#[cfg(adc_f1)] 28#[cfg(any(adc_f1, adc_v1))]
29impl_sample_time!( 29impl_sample_time!(
30 "1.5", 30 "1.5",
31 Cycles1_5, 31 Cycles1_5,
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index f787f72ac..0fdb95562 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -1,10 +1,8 @@
1use core::marker::PhantomData;
2
3use embassy_hal_common::into_ref; 1use embassy_hal_common::into_ref;
4use embedded_hal_02::blocking::delay::DelayUs; 2use embedded_hal_02::blocking::delay::DelayUs;
5 3
6use crate::adc::{AdcPin, Instance}; 4use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
7use crate::{pac, Peripheral}; 5use crate::Peripheral;
8 6
9pub const VDDA_CALIB_MV: u32 = 3300; 7pub const VDDA_CALIB_MV: u32 = 3300;
10pub const VREF_INT: u32 = 1230; 8pub const VREF_INT: u32 = 1230;
@@ -15,39 +13,6 @@ fn enable() {
15 }); 13 });
16} 14}
17 15
18pub enum Resolution {
19 TwelveBit,
20 TenBit,
21 EightBit,
22 SixBit,
23}
24
25impl Default for Resolution {
26 fn default() -> Self {
27 Self::TwelveBit
28 }
29}
30
31impl Resolution {
32 fn res(&self) -> pac::adc::vals::Res {
33 match self {
34 Resolution::TwelveBit => pac::adc::vals::Res::TWELVEBIT,
35 Resolution::TenBit => pac::adc::vals::Res::TENBIT,
36 Resolution::EightBit => pac::adc::vals::Res::EIGHTBIT,
37 Resolution::SixBit => pac::adc::vals::Res::SIXBIT,
38 }
39 }
40
41 pub fn to_max_count(&self) -> u32 {
42 match self {
43 Resolution::TwelveBit => (1 << 12) - 1,
44 Resolution::TenBit => (1 << 10) - 1,
45 Resolution::EightBit => (1 << 8) - 1,
46 Resolution::SixBit => (1 << 6) - 1,
47 }
48 }
49}
50
51pub trait InternalChannel<T>: sealed::InternalChannel<T> {} 16pub trait InternalChannel<T>: sealed::InternalChannel<T> {}
52 17
53mod sealed { 18mod sealed {
@@ -80,68 +45,9 @@ impl<T: Instance> sealed::InternalChannel<T> for Temperature {
80 } 45 }
81} 46}
82 47
83mod sample_time {
84 #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
85 pub enum SampleTime {
86 /// 1.5 ADC clock cycles
87 Cycles1_5 = 0b000,
88
89 /// 7.5 ADC clock cycles
90 Cycles7_5 = 0b001,
91
92 /// 13.5 ADC clock cycles
93 Cycles13_5 = 0b010,
94
95 /// 28.5 ADC clock cycles
96 Cycles28_5 = 0b011,
97
98 /// 41.5 ADC clock cycles
99 Cycles41_5 = 0b100,
100
101 /// 55.5 ADC clock cycles
102 Cycles55_5 = 0b101,
103
104 /// 71.5 ADC clock cycles
105 Cycles71_5 = 0b110,
106
107 /// 239.5 ADC clock cycles
108 Cycles239_5 = 0b111,
109 }
110
111 impl SampleTime {
112 pub(crate) fn sample_time(&self) -> crate::pac::adc::vals::Smp {
113 match self {
114 SampleTime::Cycles1_5 => crate::pac::adc::vals::Smp::CYCLES1_5,
115 SampleTime::Cycles7_5 => crate::pac::adc::vals::Smp::CYCLES7_5,
116 SampleTime::Cycles13_5 => crate::pac::adc::vals::Smp::CYCLES13_5,
117 SampleTime::Cycles28_5 => crate::pac::adc::vals::Smp::CYCLES28_5,
118 SampleTime::Cycles41_5 => crate::pac::adc::vals::Smp::CYCLES41_5,
119 SampleTime::Cycles55_5 => crate::pac::adc::vals::Smp::CYCLES55_5,
120 SampleTime::Cycles71_5 => crate::pac::adc::vals::Smp::CYCLES71_5,
121 SampleTime::Cycles239_5 => crate::pac::adc::vals::Smp::CYCLES239_5,
122 }
123 }
124 }
125
126 impl Default for SampleTime {
127 fn default() -> Self {
128 Self::Cycles1_5
129 }
130 }
131}
132
133pub use sample_time::SampleTime;
134
135pub struct Adc<'d, T: Instance> {
136 sample_time: SampleTime,
137 vref_mv: u32,
138 resolution: Resolution,
139 phantom: PhantomData<&'d mut T>,
140}
141
142impl<'d, T: Instance> Adc<'d, T> { 48impl<'d, T: Instance> Adc<'d, T> {
143 pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { 49 pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
144 into_ref!(_peri); 50 into_ref!(adc);
145 enable(); 51 enable();
146 52
147 // Delay 1μs when using HSI14 as the ADC clock. 53 // Delay 1μs when using HSI14 as the ADC clock.
@@ -151,10 +57,8 @@ impl<'d, T: Instance> Adc<'d, T> {
151 delay.delay_us(1); 57 delay.delay_us(1);
152 58
153 let s = Self { 59 let s = Self {
60 adc,
154 sample_time: Default::default(), 61 sample_time: Default::default(),
155 vref_mv: VDDA_CALIB_MV,
156 resolution: Resolution::default(),
157 phantom: PhantomData,
158 }; 62 };
159 s.calibrate(); 63 s.calibrate();
160 s 64 s
@@ -215,16 +119,10 @@ impl<'d, T: Instance> Adc<'d, T> {
215 self.sample_time = sample_time; 119 self.sample_time = sample_time;
216 } 120 }
217 121
218 pub fn set_vref_mv(&mut self, vref_mv: u32) {
219 self.vref_mv = vref_mv;
220 }
221
222 pub fn set_resolution(&mut self, resolution: Resolution) { 122 pub fn set_resolution(&mut self, resolution: Resolution) {
223 self.resolution = resolution; 123 unsafe {
224 } 124 T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into()));
225 125 }
226 pub fn to_millivolts(&self, sample: u16) -> u16 {
227 ((u32::from(sample) * self.vref_mv) / self.resolution.to_max_count()) as u16
228 } 126 }
229 127
230 pub fn read<P>(&mut self, pin: &mut P) -> u16 128 pub fn read<P>(&mut self, pin: &mut P) -> u16
@@ -240,9 +138,7 @@ impl<'d, T: Instance> Adc<'d, T> {
240 138
241 pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 { 139 pub fn read_internal(&mut self, channel: &mut impl InternalChannel<T>) -> u16 {
242 let channel = channel.channel(); 140 let channel = channel.channel();
243 unsafe { 141 unsafe { self.read_channel(channel) }
244 self.read_channel(channel)
245 }
246 } 142 }
247 143
248 unsafe fn read_channel(&mut self, channel: u8) -> u16 { 144 unsafe fn read_channel(&mut self, channel: u8) -> u16 {
@@ -258,17 +154,14 @@ impl<'d, T: Instance> Adc<'d, T> {
258 T::regs().cr().modify(|reg| reg.set_aden(true)); 154 T::regs().cr().modify(|reg| reg.set_aden(true));
259 } 155 }
260 156
261 T::regs().cfgr1().modify(|reg| reg.set_res(self.resolution.res()));
262 T::regs().isr().modify(|reg| { 157 T::regs().isr().modify(|reg| {
263 reg.set_eoc(true); 158 reg.set_eoc(true);
264 reg.set_eosmp(true); 159 reg.set_eosmp(true);
265 }); 160 });
266 161
267 // A.7.5 Single conversion sequence code example - Software trigger 162 // A.7.5 Single conversion sequence code example - Software trigger
268 T::regs() 163 T::regs().chselr().write(|reg| reg.set_chselx(channel as usize, true));
269 .chselr() 164 T::regs().smpr().modify(|reg| reg.set_smp(self.sample_time.into()));
270 .write(|reg| reg.set_chselx(channel as usize, true));
271 T::regs().smpr().modify(|reg| reg.set_smp(self.sample_time.sample_time()));
272 T::regs().cr().modify(|reg| reg.set_adstart(true)); 165 T::regs().cr().modify(|reg| reg.set_adstart(true));
273 while !T::regs().isr().read().eoc() { 166 while !T::regs().isr().read().eoc() {
274 // spin 167 // spin