aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorDion Dokter <[email protected]>2024-04-14 00:04:13 +0200
committerDion Dokter <[email protected]>2024-04-14 00:04:13 +0200
commitb659e3d529e427cfc2fb38f514825b60eded784f (patch)
tree068ef8b8af12ab413a75c887fa4e3c6d51d6bb42 /embassy-stm32/src
parent5f23e3905226551a001da9bf4051c6efb552f636 (diff)
Add ADC
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/adc/mod.rs4
-rw-r--r--embassy-stm32/src/adc/v3.rs40
2 files changed, 32 insertions, 12 deletions
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 12c5751bd..1ab2bc5c4 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -10,7 +10,7 @@
10#[cfg_attr(adc_v1, path = "v1.rs")] 10#[cfg_attr(adc_v1, path = "v1.rs")]
11#[cfg_attr(adc_l0, path = "v1.rs")] 11#[cfg_attr(adc_l0, path = "v1.rs")]
12#[cfg_attr(adc_v2, path = "v2.rs")] 12#[cfg_attr(adc_v2, path = "v2.rs")]
13#[cfg_attr(any(adc_v3, adc_g0, adc_h5), path = "v3.rs")] 13#[cfg_attr(any(adc_v3, adc_g0, adc_h5, adc_u0), path = "v3.rs")]
14#[cfg_attr(adc_v4, path = "v4.rs")] 14#[cfg_attr(adc_v4, path = "v4.rs")]
15#[cfg_attr(adc_g4, path = "g4.rs")] 15#[cfg_attr(adc_g4, path = "g4.rs")]
16mod _version; 16mod _version;
@@ -91,6 +91,7 @@ pub(crate) fn blocking_delay_us(us: u32) {
91 adc_f3, 91 adc_f3,
92 adc_f3_v1_1, 92 adc_f3_v1_1,
93 adc_g0, 93 adc_g0,
94 adc_u0,
94 adc_h5 95 adc_h5
95)))] 96)))]
96#[allow(private_bounds)] 97#[allow(private_bounds)]
@@ -109,6 +110,7 @@ pub trait Instance: SealedInstance + crate::Peripheral<P = Self> {
109 adc_f3, 110 adc_f3,
110 adc_f3_v1_1, 111 adc_f3_v1_1,
111 adc_g0, 112 adc_g0,
113 adc_u0,
112 adc_h5 114 adc_h5
113))] 115))]
114#[allow(private_bounds)] 116#[allow(private_bounds)]
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index 4fd8558ba..dc418297e 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -19,6 +19,8 @@ impl<T: Instance> super::SealedAdcPin<T> for VrefInt {
19 let val = 13; 19 let val = 13;
20 } else if #[cfg(adc_h5)] { 20 } else if #[cfg(adc_h5)] {
21 let val = 17; 21 let val = 17;
22 } else if #[cfg(adc_u0)] {
23 let val = 12;
22 } else { 24 } else {
23 let val = 0; 25 let val = 0;
24 } 26 }
@@ -36,6 +38,8 @@ impl<T: Instance> super::SealedAdcPin<T> for Temperature {
36 let val = 12; 38 let val = 12;
37 } else if #[cfg(adc_h5)] { 39 } else if #[cfg(adc_h5)] {
38 let val = 16; 40 let val = 16;
41 } else if #[cfg(adc_u0)] {
42 let val = 11;
39 } else { 43 } else {
40 let val = 17; 44 let val = 17;
41 } 45 }
@@ -53,6 +57,8 @@ impl<T: Instance> super::SealedAdcPin<T> for Vbat {
53 let val = 14; 57 let val = 14;
54 } else if #[cfg(adc_h5)] { 58 } else if #[cfg(adc_h5)] {
55 let val = 2; 59 let val = 2;
60 } else if #[cfg(adc_h5)] {
61 let val = 13;
56 } else { 62 } else {
57 let val = 18; 63 let val = 18;
58 } 64 }
@@ -73,17 +79,29 @@ cfg_if! {
73 } 79 }
74} 80}
75 81
82cfg_if! {
83 if #[cfg(adc_u0)] {
84 pub struct DacOut;
85 impl<T: Instance> AdcPin<T> for DacOut {}
86 impl<T: Instance> super::SealedAdcPin<T> for DacOut {
87 fn channel(&self) -> u8 {
88 19
89 }
90 }
91 }
92}
93
76impl<'d, T: Instance> Adc<'d, T> { 94impl<'d, T: Instance> Adc<'d, T> {
77 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 95 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
78 into_ref!(adc); 96 into_ref!(adc);
79 T::enable_and_reset(); 97 T::enable_and_reset();
80 T::regs().cr().modify(|reg| { 98 T::regs().cr().modify(|reg| {
81 #[cfg(not(adc_g0))] 99 #[cfg(not(any(adc_g0, adc_u0)))]
82 reg.set_deeppwd(false); 100 reg.set_deeppwd(false);
83 reg.set_advregen(true); 101 reg.set_advregen(true);
84 }); 102 });
85 103
86 #[cfg(adc_g0)] 104 #[cfg(any(adc_g0, adc_u0))]
87 T::regs().cfgr1().modify(|reg| { 105 T::regs().cfgr1().modify(|reg| {
88 reg.set_chselrmod(false); 106 reg.set_chselrmod(false);
89 }); 107 });
@@ -107,11 +125,11 @@ impl<'d, T: Instance> Adc<'d, T> {
107 } 125 }
108 126
109 pub fn enable_vrefint(&self) -> VrefInt { 127 pub fn enable_vrefint(&self) -> VrefInt {
110 #[cfg(not(adc_g0))] 128 #[cfg(not(any(adc_g0, adc_u0)))]
111 T::common_regs().ccr().modify(|reg| { 129 T::common_regs().ccr().modify(|reg| {
112 reg.set_vrefen(true); 130 reg.set_vrefen(true);
113 }); 131 });
114 #[cfg(adc_g0)] 132 #[cfg(any(adc_g0, adc_u0))]
115 T::regs().ccr().modify(|reg| { 133 T::regs().ccr().modify(|reg| {
116 reg.set_vrefen(true); 134 reg.set_vrefen(true);
117 }); 135 });
@@ -125,7 +143,7 @@ impl<'d, T: Instance> Adc<'d, T> {
125 143
126 pub fn enable_temperature(&self) -> Temperature { 144 pub fn enable_temperature(&self) -> Temperature {
127 cfg_if! { 145 cfg_if! {
128 if #[cfg(adc_g0)] { 146 if #[cfg(any(adc_g0, adc_u0))] {
129 T::regs().ccr().modify(|reg| { 147 T::regs().ccr().modify(|reg| {
130 reg.set_tsen(true); 148 reg.set_tsen(true);
131 }); 149 });
@@ -145,7 +163,7 @@ impl<'d, T: Instance> Adc<'d, T> {
145 163
146 pub fn enable_vbat(&self) -> Vbat { 164 pub fn enable_vbat(&self) -> Vbat {
147 cfg_if! { 165 cfg_if! {
148 if #[cfg(adc_g0)] { 166 if #[cfg(any(adc_g0, adc_u0))] {
149 T::regs().ccr().modify(|reg| { 167 T::regs().ccr().modify(|reg| {
150 reg.set_vbaten(true); 168 reg.set_vbaten(true);
151 }); 169 });
@@ -168,9 +186,9 @@ impl<'d, T: Instance> Adc<'d, T> {
168 } 186 }
169 187
170 pub fn set_resolution(&mut self, resolution: Resolution) { 188 pub fn set_resolution(&mut self, resolution: Resolution) {
171 #[cfg(not(adc_g0))] 189 #[cfg(not(any(adc_g0, adc_u0)))]
172 T::regs().cfgr().modify(|reg| reg.set_res(resolution.into())); 190 T::regs().cfgr().modify(|reg| reg.set_res(resolution.into()));
173 #[cfg(adc_g0)] 191 #[cfg(any(adc_g0, adc_u0))]
174 T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into())); 192 T::regs().cfgr1().modify(|reg| reg.set_res(resolution.into()));
175 } 193 }
176 194
@@ -231,9 +249,9 @@ impl<'d, T: Instance> Adc<'d, T> {
231 Self::set_channel_sample_time(pin.channel(), self.sample_time); 249 Self::set_channel_sample_time(pin.channel(), self.sample_time);
232 250
233 // Select channel 251 // Select channel
234 #[cfg(not(adc_g0))] 252 #[cfg(not(any(adc_g0, adc_u0)))]
235 T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel())); 253 T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel()));
236 #[cfg(adc_g0)] 254 #[cfg(any(adc_g0, adc_u0))]
237 T::regs().chselr().write(|reg| reg.set_chsel(1 << pin.channel())); 255 T::regs().chselr().write(|reg| reg.set_chsel(1 << pin.channel()));
238 256
239 // Some models are affected by an erratum: 257 // Some models are affected by an erratum:
@@ -261,7 +279,7 @@ impl<'d, T: Instance> Adc<'d, T> {
261 279
262 fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) { 280 fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) {
263 cfg_if! { 281 cfg_if! {
264 if #[cfg(adc_g0)] { 282 if #[cfg(any(adc_g0, adc_u0))] {
265 T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.into())); 283 T::regs().smpr().modify(|reg| reg.set_smp1(sample_time.into()));
266 } else if #[cfg(adc_h5)] { 284 } else if #[cfg(adc_h5)] {
267 match _ch { 285 match _ch {