aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/build.rs33
-rw-r--r--embassy-stm32/src/opamp.rs56
3 files changed, 43 insertions, 50 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 1031baa2d..4ee43e600 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -81,7 +81,7 @@ futures-util = { version = "0.3.30", default-features = false }
81sdio-host = "0.9.0" 81sdio-host = "0.9.0"
82critical-section = "1.1" 82critical-section = "1.1"
83#stm32-metapac = { version = "16" } 83#stm32-metapac = { version = "16" }
84stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-778e3d102186ebb12a8c8b60b7cafdd15858bab3" } 84stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8a502cec14512a6b833beb8f6e15f4a7b5ee7c06" }
85 85
86vcell = "0.1.3" 86vcell = "0.1.3"
87nb = "1.0.0" 87nb = "1.0.0"
@@ -110,7 +110,7 @@ proc-macro2 = "1.0.36"
110quote = "1.0.15" 110quote = "1.0.15"
111 111
112#stm32-metapac = { version = "16", default-features = false, features = ["metadata"]} 112#stm32-metapac = { version = "16", default-features = false, features = ["metadata"]}
113stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-778e3d102186ebb12a8c8b60b7cafdd15858bab3", default-features = false, features = ["metadata"] } 113stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8a502cec14512a6b833beb8f6e15f4a7b5ee7c06", default-features = false, features = ["metadata"] }
114 114
115[features] 115[features]
116default = ["rt"] 116default = ["rt"]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index bb5ef53d7..8143c9a23 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -1402,31 +1402,24 @@ fn main() {
1402 } 1402 }
1403 1403
1404 if regs.kind == "opamp" { 1404 if regs.kind == "opamp" {
1405 if pin.signal.starts_with("VP") { 1405 let peri = format_ident!("{}", p.name);
1406 // Impl NonInvertingPin for the VP* signals (VP0, VP1, VP2, etc) 1406 let pin_name = format_ident!("{}", pin.pin);
1407 let peri = format_ident!("{}", p.name); 1407 if let Some(ch_str) = pin.signal.strip_prefix("VINP") {
1408 let pin_name = format_ident!("{}", pin.pin); 1408 // Impl NonInvertingPin for VINP0, VINP1 etc.
1409 let ch: u8 = pin.signal.strip_prefix("VP").unwrap().parse().unwrap(); 1409 if let Ok(ch) = ch_str.parse::<u8>() {
1410 1410 g.extend(quote! {
1411 g.extend(quote! { 1411 impl_opamp_vp_pin!( #peri, #pin_name, #ch );
1412 impl_opamp_vp_pin!( #peri, #pin_name, #ch); 1412 });
1413 }) 1413 }
1414 } else if pin.signal.starts_with("VINM") { 1414 } else if let Some(ch_str) = pin.signal.strip_prefix("VINM") {
1415 // Impl NonInvertingPin for the VINM* signals ( VINM0, VINM1, etc) 1415 // Impl InvertingPin for VINM0, VINM1 etc.
1416 // STM32G4 1416 if let Ok(ch) = ch_str.parse::<u8>() {
1417 let peri = format_ident!("{}", p.name);
1418 let pin_name = format_ident!("{}", pin.pin);
1419 let ch: Result<u8, _> = pin.signal.strip_prefix("VINM").unwrap().parse();
1420
1421 if let Ok(ch) = ch {
1422 g.extend(quote! { 1417 g.extend(quote! {
1423 impl_opamp_vn_pin!( #peri, #pin_name, #ch); 1418 impl_opamp_vn_pin!( #peri, #pin_name, #ch);
1424 }) 1419 });
1425 } 1420 }
1426 } else if pin.signal == "VOUT" { 1421 } else if pin.signal == "VOUT" {
1427 // Impl OutputPin for the VOUT pin 1422 // Impl OutputPin for the VOUT pin
1428 let peri = format_ident!("{}", p.name);
1429 let pin_name = format_ident!("{}", pin.pin);
1430 g.extend(quote! { 1423 g.extend(quote! {
1431 impl_opamp_vout_pin!( #peri, #pin_name ); 1424 impl_opamp_vout_pin!( #peri, #pin_name );
1432 }) 1425 })
diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs
index 2eb2e61c1..0467dbce3 100644
--- a/embassy-stm32/src/opamp.rs
+++ b/embassy-stm32/src/opamp.rs
@@ -7,7 +7,7 @@ use crate::pac::opamp::vals::*;
7use crate::Peri; 7use crate::Peri;
8 8
9/// Performs a busy-wait delay for a specified number of microseconds. 9/// Performs a busy-wait delay for a specified number of microseconds.
10#[cfg(opamp_g4)] 10#[cfg(opamp_v5)]
11fn blocking_delay_ms(ms: u32) { 11fn blocking_delay_ms(ms: u32) {
12 #[cfg(feature = "time")] 12 #[cfg(feature = "time")]
13 embassy_time::block_for(embassy_time::Duration::from_millis(ms as u64)); 13 embassy_time::block_for(embassy_time::Duration::from_millis(ms as u64));
@@ -23,13 +23,13 @@ pub enum OpAmpGain {
23 Mul4, 23 Mul4,
24 Mul8, 24 Mul8,
25 Mul16, 25 Mul16,
26 #[cfg(opamp_g4)] 26 #[cfg(opamp_v5)]
27 Mul32, 27 Mul32,
28 #[cfg(opamp_g4)] 28 #[cfg(opamp_v5)]
29 Mul64, 29 Mul64,
30} 30}
31 31
32#[cfg(opamp_g4)] 32#[cfg(opamp_v5)]
33enum OpAmpDifferentialPair { 33enum OpAmpDifferentialPair {
34 P, 34 P,
35 N, 35 N,
@@ -53,7 +53,7 @@ pub struct OpAmpOutput<'d, T: Instance> {
53/// OpAmp internal outputs, wired directly to ADC inputs. 53/// OpAmp internal outputs, wired directly to ADC inputs.
54/// 54///
55/// This struct can be used as an ADC input. 55/// This struct can be used as an ADC input.
56#[cfg(opamp_g4)] 56#[cfg(opamp_v5)]
57pub struct OpAmpInternalOutput<'d, T: Instance> { 57pub struct OpAmpInternalOutput<'d, T: Instance> {
58 _inner: &'d OpAmp<'d, T>, 58 _inner: &'d OpAmp<'d, T>,
59} 59}
@@ -67,8 +67,8 @@ impl<'d, T: Instance> OpAmp<'d, T> {
67 /// Create a new driver instance. 67 /// Create a new driver instance.
68 /// 68 ///
69 /// Does not enable the opamp, but does set the speed mode on some families. 69 /// Does not enable the opamp, but does set the speed mode on some families.
70 pub fn new(opamp: Peri<'d, T>, #[cfg(opamp_g4)] speed: OpAmpSpeed) -> Self { 70 pub fn new(opamp: Peri<'d, T>, #[cfg(opamp_v5)] speed: OpAmpSpeed) -> Self {
71 #[cfg(opamp_g4)] 71 #[cfg(opamp_v5)]
72 T::regs().csr().modify(|w| { 72 T::regs().csr().modify(|w| {
73 w.set_opahsm(speed == OpAmpSpeed::HighSpeed); 73 w.set_opahsm(speed == OpAmpSpeed::HighSpeed);
74 }); 74 });
@@ -94,15 +94,15 @@ impl<'d, T: Instance> OpAmp<'d, T> {
94 in_pin.set_as_analog(); 94 in_pin.set_as_analog();
95 out_pin.set_as_analog(); 95 out_pin.set_as_analog();
96 96
97 #[cfg(opamp_g4)] 97 #[cfg(opamp_v5)]
98 let vm_sel = VmSel::OUTPUT; 98 let vm_sel = VmSel::OUTPUT;
99 #[cfg(not(opamp_g4))] 99 #[cfg(not(opamp_v5))]
100 let vm_sel = VmSel::from_bits(0b11); 100 let vm_sel = VmSel::from_bits(0b11);
101 101
102 T::regs().csr().modify(|w| { 102 T::regs().csr().modify(|w| {
103 w.set_vp_sel(VpSel::from_bits(in_pin.channel())); 103 w.set_vp_sel(VpSel::from_bits(in_pin.channel()));
104 w.set_vm_sel(vm_sel); 104 w.set_vm_sel(vm_sel);
105 #[cfg(opamp_g4)] 105 #[cfg(opamp_v5)]
106 w.set_opaintoen(false); 106 w.set_opaintoen(false);
107 w.set_opampen(true); 107 w.set_opampen(true);
108 }); 108 });
@@ -129,12 +129,12 @@ impl<'d, T: Instance> OpAmp<'d, T> {
129 in_pin.set_as_analog(); 129 in_pin.set_as_analog();
130 out_pin.set_as_analog(); 130 out_pin.set_as_analog();
131 131
132 #[cfg(opamp_g4)] 132 #[cfg(opamp_v5)]
133 let vm_sel = VmSel::PGA; 133 let vm_sel = VmSel::PGA;
134 #[cfg(not(opamp_g4))] 134 #[cfg(not(opamp_v5))]
135 let vm_sel = VmSel::from_bits(0b10); 135 let vm_sel = VmSel::from_bits(0b10);
136 136
137 #[cfg(opamp_g4)] 137 #[cfg(opamp_v5)]
138 let pga_gain = match gain { 138 let pga_gain = match gain {
139 OpAmpGain::Mul2 => PgaGain::GAIN2, 139 OpAmpGain::Mul2 => PgaGain::GAIN2,
140 OpAmpGain::Mul4 => PgaGain::GAIN4, 140 OpAmpGain::Mul4 => PgaGain::GAIN4,
@@ -143,7 +143,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
143 OpAmpGain::Mul32 => PgaGain::GAIN32, 143 OpAmpGain::Mul32 => PgaGain::GAIN32,
144 OpAmpGain::Mul64 => PgaGain::GAIN64, 144 OpAmpGain::Mul64 => PgaGain::GAIN64,
145 }; 145 };
146 #[cfg(not(opamp_g4))] 146 #[cfg(not(opamp_v5))]
147 let pga_gain = PgaGain::from_bits(match gain { 147 let pga_gain = PgaGain::from_bits(match gain {
148 OpAmpGain::Mul2 => 0b00, 148 OpAmpGain::Mul2 => 0b00,
149 OpAmpGain::Mul4 => 0b01, 149 OpAmpGain::Mul4 => 0b01,
@@ -155,7 +155,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
155 w.set_vp_sel(VpSel::from_bits(in_pin.channel())); 155 w.set_vp_sel(VpSel::from_bits(in_pin.channel()));
156 w.set_vm_sel(vm_sel); 156 w.set_vm_sel(vm_sel);
157 w.set_pga_gain(pga_gain); 157 w.set_pga_gain(pga_gain);
158 #[cfg(opamp_g4)] 158 #[cfg(opamp_v5)]
159 w.set_opaintoen(false); 159 w.set_opaintoen(false);
160 w.set_opampen(true); 160 w.set_opampen(true);
161 }); 161 });
@@ -170,7 +170,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
170 /// preventing it being used elsewhere. The `OpAmpOutput` can then be 170 /// preventing it being used elsewhere. The `OpAmpOutput` can then be
171 /// directly used as an ADC input. The opamp will be disabled when the 171 /// directly used as an ADC input. The opamp will be disabled when the
172 /// [`OpAmpOutput`] is dropped. 172 /// [`OpAmpOutput`] is dropped.
173 #[cfg(opamp_g4)] 173 #[cfg(opamp_v5)]
174 pub fn buffer_dac(&mut self, out_pin: Peri<'_, impl OutputPin<T> + crate::gpio::Pin>) -> OpAmpOutput<'_, T> { 174 pub fn buffer_dac(&mut self, out_pin: Peri<'_, impl OutputPin<T> + crate::gpio::Pin>) -> OpAmpOutput<'_, T> {
175 out_pin.set_as_analog(); 175 out_pin.set_as_analog();
176 176
@@ -194,7 +194,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
194 /// 194 ///
195 /// The returned `OpAmpInternalOutput` struct may be used as an ADC input. 195 /// The returned `OpAmpInternalOutput` struct may be used as an ADC input.
196 /// The opamp output will be disabled when it is dropped. 196 /// The opamp output will be disabled when it is dropped.
197 #[cfg(opamp_g4)] 197 #[cfg(opamp_v5)]
198 pub fn buffer_int( 198 pub fn buffer_int(
199 &mut self, 199 &mut self,
200 pin: Peri<'_, impl NonInvertingPin<T> + crate::gpio::Pin>, 200 pin: Peri<'_, impl NonInvertingPin<T> + crate::gpio::Pin>,
@@ -204,7 +204,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
204 T::regs().csr().modify(|w| { 204 T::regs().csr().modify(|w| {
205 w.set_vp_sel(VpSel::from_bits(pin.channel())); 205 w.set_vp_sel(VpSel::from_bits(pin.channel()));
206 w.set_vm_sel(VmSel::OUTPUT); 206 w.set_vm_sel(VmSel::OUTPUT);
207 #[cfg(opamp_g4)] 207 #[cfg(opamp_v5)]
208 w.set_opaintoen(true); 208 w.set_opaintoen(true);
209 w.set_opampen(true); 209 w.set_opampen(true);
210 }); 210 });
@@ -220,7 +220,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
220 /// 220 ///
221 /// The returned `OpAmpInternalOutput` struct may be used as an ADC input. 221 /// The returned `OpAmpInternalOutput` struct may be used as an ADC input.
222 /// The opamp output will be disabled when it is dropped. 222 /// The opamp output will be disabled when it is dropped.
223 #[cfg(opamp_g4)] 223 #[cfg(opamp_v5)]
224 pub fn pga_int( 224 pub fn pga_int(
225 &mut self, 225 &mut self,
226 pin: Peri<'_, impl NonInvertingPin<T> + crate::gpio::Pin>, 226 pin: Peri<'_, impl NonInvertingPin<T> + crate::gpio::Pin>,
@@ -257,7 +257,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
257 /// 257 ///
258 /// The returned `OpAmpInternalOutput` struct may be used as an ADC 258 /// The returned `OpAmpInternalOutput` struct may be used as an ADC
259 /// input. The opamp output will be disabled when it is dropped. 259 /// input. The opamp output will be disabled when it is dropped.
260 #[cfg(opamp_g4)] 260 #[cfg(opamp_v5)]
261 pub fn standalone_dac_int( 261 pub fn standalone_dac_int(
262 &mut self, 262 &mut self,
263 m_pin: Peri<'_, impl InvertingPin<T> + crate::gpio::Pin>, 263 m_pin: Peri<'_, impl InvertingPin<T> + crate::gpio::Pin>,
@@ -285,7 +285,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
285 /// The output pin is held within the returned [`OpAmpOutput`] struct, 285 /// The output pin is held within the returned [`OpAmpOutput`] struct,
286 /// preventing it being used elsewhere. The opamp will be disabled when 286 /// preventing it being used elsewhere. The opamp will be disabled when
287 /// the [`OpAmpOutput`] is dropped. 287 /// the [`OpAmpOutput`] is dropped.
288 #[cfg(opamp_g4)] 288 #[cfg(opamp_v5)]
289 pub fn standalone_dac_ext( 289 pub fn standalone_dac_ext(
290 &mut self, 290 &mut self,
291 m_pin: Peri<'_, impl InvertingPin<T> + crate::gpio::Pin>, 291 m_pin: Peri<'_, impl InvertingPin<T> + crate::gpio::Pin>,
@@ -315,7 +315,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
315 /// The output pin is held within the returned [`OpAmpOutput`] struct, 315 /// The output pin is held within the returned [`OpAmpOutput`] struct,
316 /// preventing it being used elsewhere. The opamp will be disabled when 316 /// preventing it being used elsewhere. The opamp will be disabled when
317 /// the [`OpAmpOutput`] is dropped. 317 /// the [`OpAmpOutput`] is dropped.
318 #[cfg(opamp_g4)] 318 #[cfg(opamp_v5)]
319 pub fn standalone_ext( 319 pub fn standalone_ext(
320 &mut self, 320 &mut self,
321 p_pin: Peri<'d, impl NonInvertingPin<T> + crate::gpio::Pin>, 321 p_pin: Peri<'d, impl NonInvertingPin<T> + crate::gpio::Pin>,
@@ -346,7 +346,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
346 /// 346 ///
347 /// The returned `OpAmpOutput` struct may be used as an ADC 347 /// The returned `OpAmpOutput` struct may be used as an ADC
348 /// input. The opamp output will be disabled when it is dropped. 348 /// input. The opamp output will be disabled when it is dropped.
349 #[cfg(opamp_g4)] 349 #[cfg(opamp_v5)]
350 pub fn standalone_int( 350 pub fn standalone_int(
351 &mut self, 351 &mut self,
352 p_pin: Peri<'d, impl NonInvertingPin<T> + crate::gpio::Pin>, 352 p_pin: Peri<'d, impl NonInvertingPin<T> + crate::gpio::Pin>,
@@ -374,7 +374,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
374 /// while for high-speed mode, only the P differential pair is calibrated. 374 /// while for high-speed mode, only the P differential pair is calibrated.
375 /// 375 ///
376 /// Calibrating a differential pair requires waiting 12ms in the worst case (binary method). 376 /// Calibrating a differential pair requires waiting 12ms in the worst case (binary method).
377 #[cfg(opamp_g4)] 377 #[cfg(opamp_v5)]
378 pub fn calibrate(&mut self) { 378 pub fn calibrate(&mut self) {
379 T::regs().csr().modify(|w| { 379 T::regs().csr().modify(|w| {
380 w.set_opampen(true); 380 w.set_opampen(true);
@@ -403,7 +403,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
403 /// The calibration range is from 0 to 31. 403 /// The calibration range is from 0 to 31.
404 /// 404 ///
405 /// The result is stored in the OPAMP_CSR register. 405 /// The result is stored in the OPAMP_CSR register.
406 #[cfg(opamp_g4)] 406 #[cfg(opamp_v5)]
407 fn calibrate_differential_pair(&mut self, pair: OpAmpDifferentialPair) { 407 fn calibrate_differential_pair(&mut self, pair: OpAmpDifferentialPair) {
408 let mut low = 0; 408 let mut low = 0;
409 let mut high = 31; 409 let mut high = 31;
@@ -460,7 +460,7 @@ impl<'d, T: Instance> Drop for OpAmpOutput<'d, T> {
460 } 460 }
461} 461}
462 462
463#[cfg(opamp_g4)] 463#[cfg(opamp_v5)]
464impl<'d, T: Instance> Drop for OpAmpInternalOutput<'d, T> { 464impl<'d, T: Instance> Drop for OpAmpInternalOutput<'d, T> {
465 fn drop(&mut self) { 465 fn drop(&mut self) {
466 T::regs().csr().modify(|w| { 466 T::regs().csr().modify(|w| {
@@ -545,7 +545,7 @@ foreach_peripheral!(
545 }; 545 };
546); 546);
547 547
548#[cfg(opamp_g4)] 548#[cfg(opamp_v5)]
549macro_rules! impl_opamp_internal_output { 549macro_rules! impl_opamp_internal_output {
550 ($inst:ident, $adc:ident, $ch:expr) => { 550 ($inst:ident, $adc:ident, $ch:expr) => {
551 foreach_adc!( 551 foreach_adc!(
@@ -567,7 +567,7 @@ macro_rules! impl_opamp_internal_output {
567 }; 567 };
568} 568}
569 569
570#[cfg(opamp_g4)] 570#[cfg(opamp_v5)]
571foreach_peripheral!( 571foreach_peripheral!(
572 (opamp, OPAMP1) => { 572 (opamp, OPAMP1) => {
573 impl_opamp_internal_output!(OPAMP1, ADC1, 13); 573 impl_opamp_internal_output!(OPAMP1, ADC1, 13);