diff options
| -rw-r--r-- | embassy-stm32/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32/build.rs | 37 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/g4.rs | 36 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/mod.rs | 44 |
4 files changed, 86 insertions, 35 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 108321d0a..86c995ec2 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -197,11 +197,11 @@ aligned = "0.4.1" | |||
| 197 | heapless = "0.9.1" | 197 | heapless = "0.9.1" |
| 198 | 198 | ||
| 199 | #stm32-metapac = { version = "18" } | 199 | #stm32-metapac = { version = "18" } |
| 200 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-22374e3344a2c9150b9b3d4da45c03f398fdc54e" } | 200 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-b77c8d968f53b18d6bdcd052e354b5070ec2bbc2" } |
| 201 | 201 | ||
| 202 | [build-dependencies] | 202 | [build-dependencies] |
| 203 | #stm32-metapac = { version = "18", default-features = false, features = ["metadata"]} | 203 | #stm32-metapac = { version = "18", default-features = false, features = ["metadata"]} |
| 204 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-22374e3344a2c9150b9b3d4da45c03f398fdc54e", default-features = false, features = ["metadata"] } | 204 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-b77c8d968f53b18d6bdcd052e354b5070ec2bbc2", default-features = false, features = ["metadata"] } |
| 205 | 205 | ||
| 206 | proc-macro2 = "1.0.36" | 206 | proc-macro2 = "1.0.36" |
| 207 | quote = "1.0.15" | 207 | quote = "1.0.15" |
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 940e29417..017b0f196 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -1346,6 +1346,8 @@ fn main() { | |||
| 1346 | 1346 | ||
| 1347 | for p in METADATA.peripherals { | 1347 | for p in METADATA.peripherals { |
| 1348 | if let Some(regs) = &p.registers { | 1348 | if let Some(regs) = &p.registers { |
| 1349 | let mut adc_pairs: BTreeMap<u8, (Option<Ident>, Option<Ident>)> = BTreeMap::new(); | ||
| 1350 | |||
| 1349 | for pin in p.pins { | 1351 | for pin in p.pins { |
| 1350 | let key = (regs.kind, pin.signal); | 1352 | let key = (regs.kind, pin.signal); |
| 1351 | if let Some(tr) = signals.get(&key) { | 1353 | if let Some(tr) = signals.get(&key) { |
| @@ -1467,25 +1469,29 @@ fn main() { | |||
| 1467 | }; | 1469 | }; |
| 1468 | 1470 | ||
| 1469 | // H7 has differential voltage measurements | 1471 | // H7 has differential voltage measurements |
| 1470 | let ch: Option<u8> = if pin.signal.starts_with("INP") { | 1472 | let ch: Option<(u8, bool)> = if pin.signal.starts_with("INP") { |
| 1471 | Some(pin.signal.strip_prefix("INP").unwrap().parse().unwrap()) | 1473 | Some((pin.signal.strip_prefix("INP").unwrap().parse().unwrap(), false)) |
| 1472 | } else if pin.signal.starts_with("INN") { | 1474 | } else if pin.signal.starts_with("INN") { |
| 1473 | // TODO handle in the future when embassy supports differential measurements | 1475 | Some((pin.signal.strip_prefix("INN").unwrap().parse().unwrap(), true)) |
| 1474 | None | ||
| 1475 | } else if pin.signal.starts_with("IN") && pin.signal.ends_with('b') { | 1476 | } else if pin.signal.starts_with("IN") && pin.signal.ends_with('b') { |
| 1476 | // we number STM32L1 ADC bank 1 as 0..=31, bank 2 as 32..=63 | 1477 | // we number STM32L1 ADC bank 1 as 0..=31, bank 2 as 32..=63 |
| 1477 | let signal = pin.signal.strip_prefix("IN").unwrap().strip_suffix('b').unwrap(); | 1478 | let signal = pin.signal.strip_prefix("IN").unwrap().strip_suffix('b').unwrap(); |
| 1478 | Some(32u8 + signal.parse::<u8>().unwrap()) | 1479 | Some((32u8 + signal.parse::<u8>().unwrap(), false)) |
| 1479 | } else if pin.signal.starts_with("IN") { | 1480 | } else if pin.signal.starts_with("IN") { |
| 1480 | Some(pin.signal.strip_prefix("IN").unwrap().parse().unwrap()) | 1481 | Some((pin.signal.strip_prefix("IN").unwrap().parse().unwrap(), false)) |
| 1481 | } else { | 1482 | } else { |
| 1482 | None | 1483 | None |
| 1483 | }; | 1484 | }; |
| 1484 | if let Some(ch) = ch { | 1485 | if let Some((ch, false)) = ch { |
| 1486 | adc_pairs.entry(ch).or_insert((None, None)).0.replace(pin_name.clone()); | ||
| 1487 | |||
| 1485 | g.extend(quote! { | 1488 | g.extend(quote! { |
| 1486 | impl_adc_pin!( #peri, #pin_name, #ch); | 1489 | impl_adc_pin!( #peri, #pin_name, #ch); |
| 1487 | }) | 1490 | }) |
| 1488 | } | 1491 | } |
| 1492 | if let Some((ch, true)) = ch { | ||
| 1493 | adc_pairs.entry(ch).or_insert((None, None)).1.replace(pin_name.clone()); | ||
| 1494 | } | ||
| 1489 | } | 1495 | } |
| 1490 | 1496 | ||
| 1491 | if regs.kind == "opamp" { | 1497 | if regs.kind == "opamp" { |
| @@ -1524,6 +1530,23 @@ fn main() { | |||
| 1524 | }) | 1530 | }) |
| 1525 | } | 1531 | } |
| 1526 | } | 1532 | } |
| 1533 | |||
| 1534 | { | ||
| 1535 | let peri = format_ident!("{}", p.name); | ||
| 1536 | |||
| 1537 | for (ch, (pin, npin)) in adc_pairs { | ||
| 1538 | let (pin_name, npin_name) = match (pin, npin) { | ||
| 1539 | (Some(pin), Some(npin)) => (pin, npin), | ||
| 1540 | _ => { | ||
| 1541 | continue; | ||
| 1542 | } | ||
| 1543 | }; | ||
| 1544 | |||
| 1545 | g.extend(quote! { | ||
| 1546 | impl_adc_pair!( #peri, #pin_name, #npin_name, #ch); | ||
| 1547 | }) | ||
| 1548 | } | ||
| 1549 | } | ||
| 1527 | } | 1550 | } |
| 1528 | } | 1551 | } |
| 1529 | 1552 | ||
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs index 5d9c6ff74..c0fb7c733 100644 --- a/embassy-stm32/src/adc/g4.rs +++ b/embassy-stm32/src/adc/g4.rs | |||
| @@ -140,37 +140,19 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 140 | ); | 140 | ); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | let mut s = Self { adc }; | ||
| 144 | s.power_up(); | ||
| 145 | s.configure_differential_inputs(); | ||
| 146 | |||
| 147 | s.calibrate(); | ||
| 148 | blocking_delay_us(1); | ||
| 149 | |||
| 150 | Self::enable(); | ||
| 151 | s.configure(); | ||
| 152 | |||
| 153 | s | ||
| 154 | } | ||
| 155 | |||
| 156 | fn power_up(&mut self) { | ||
| 157 | T::regs().cr().modify(|reg| { | 143 | T::regs().cr().modify(|reg| { |
| 158 | reg.set_deeppwd(false); | 144 | reg.set_deeppwd(false); |
| 159 | reg.set_advregen(true); | 145 | reg.set_advregen(true); |
| 160 | }); | 146 | }); |
| 161 | 147 | ||
| 162 | blocking_delay_us(20); | 148 | blocking_delay_us(20); |
| 163 | } | ||
| 164 | 149 | ||
| 165 | fn configure_differential_inputs(&mut self) { | ||
| 166 | T::regs().difsel().modify(|w| { | 150 | T::regs().difsel().modify(|w| { |
| 167 | for n in 0..18 { | 151 | for n in 0..18 { |
| 168 | w.set_difsel(n, Difsel::SINGLE_ENDED); | 152 | w.set_difsel(n, Difsel::SINGLE_ENDED); |
| 169 | } | 153 | } |
| 170 | }); | 154 | }); |
| 171 | } | ||
| 172 | 155 | ||
| 173 | fn calibrate(&mut self) { | ||
| 174 | T::regs().cr().modify(|w| { | 156 | T::regs().cr().modify(|w| { |
| 175 | w.set_adcaldif(Adcaldif::SINGLE_ENDED); | 157 | w.set_adcaldif(Adcaldif::SINGLE_ENDED); |
| 176 | }); | 158 | }); |
| @@ -190,6 +172,16 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 190 | while T::regs().cr().read().adcal() {} | 172 | while T::regs().cr().read().adcal() {} |
| 191 | 173 | ||
| 192 | blocking_delay_us(20); | 174 | blocking_delay_us(20); |
| 175 | |||
| 176 | Self::enable(); | ||
| 177 | |||
| 178 | // single conversion mode, software trigger | ||
| 179 | T::regs().cfgr().modify(|w| { | ||
| 180 | w.set_cont(false); | ||
| 181 | w.set_exten(Exten::DISABLED); | ||
| 182 | }); | ||
| 183 | |||
| 184 | Self { adc } | ||
| 193 | } | 185 | } |
| 194 | 186 | ||
| 195 | fn enable() { | 187 | fn enable() { |
| @@ -213,14 +205,6 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 213 | } | 205 | } |
| 214 | } | 206 | } |
| 215 | 207 | ||
| 216 | fn configure(&mut self) { | ||
| 217 | // single conversion mode, software trigger | ||
| 218 | T::regs().cfgr().modify(|w| { | ||
| 219 | w.set_cont(false); | ||
| 220 | w.set_exten(Exten::DISABLED); | ||
| 221 | }); | ||
| 222 | } | ||
| 223 | |||
| 224 | /// Enable reading the voltage reference internal channel. | 208 | /// Enable reading the voltage reference internal channel. |
| 225 | pub fn enable_vrefint(&self) -> super::VrefInt | 209 | pub fn enable_vrefint(&self) -> super::VrefInt |
| 226 | where | 210 | where |
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index 3bf893a35..a11e0c1b4 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs | |||
| @@ -80,6 +80,11 @@ pub(crate) trait SealedAdcChannel<T> { | |||
| 80 | 80 | ||
| 81 | #[allow(unused)] | 81 | #[allow(unused)] |
| 82 | fn channel(&self) -> u8; | 82 | fn channel(&self) -> u8; |
| 83 | |||
| 84 | #[allow(unused)] | ||
| 85 | fn is_differential(&self) -> bool { | ||
| 86 | false | ||
| 87 | } | ||
| 83 | } | 88 | } |
| 84 | 89 | ||
| 85 | /// Performs a busy-wait delay for a specified number of microseconds. | 90 | /// Performs a busy-wait delay for a specified number of microseconds. |
| @@ -178,6 +183,7 @@ pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized { | |||
| 178 | 183 | ||
| 179 | AnyAdcChannel { | 184 | AnyAdcChannel { |
| 180 | channel: self.channel(), | 185 | channel: self.channel(), |
| 186 | is_differential: self.is_differential(), | ||
| 181 | _phantom: PhantomData, | 187 | _phantom: PhantomData, |
| 182 | } | 188 | } |
| 183 | } | 189 | } |
| @@ -189,6 +195,7 @@ pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized { | |||
| 189 | /// storing them in an array. | 195 | /// storing them in an array. |
| 190 | pub struct AnyAdcChannel<T> { | 196 | pub struct AnyAdcChannel<T> { |
| 191 | channel: u8, | 197 | channel: u8, |
| 198 | is_differential: bool, | ||
| 192 | _phantom: PhantomData<T>, | 199 | _phantom: PhantomData<T>, |
| 193 | } | 200 | } |
| 194 | impl_peripheral!(AnyAdcChannel<T: Instance>); | 201 | impl_peripheral!(AnyAdcChannel<T: Instance>); |
| @@ -197,6 +204,10 @@ impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> { | |||
| 197 | fn channel(&self) -> u8 { | 204 | fn channel(&self) -> u8 { |
| 198 | self.channel | 205 | self.channel |
| 199 | } | 206 | } |
| 207 | |||
| 208 | fn is_differential(&self) -> bool { | ||
| 209 | self.is_differential | ||
| 210 | } | ||
| 200 | } | 211 | } |
| 201 | 212 | ||
| 202 | impl<T> AnyAdcChannel<T> { | 213 | impl<T> AnyAdcChannel<T> { |
| @@ -315,6 +326,39 @@ macro_rules! impl_adc_pin { | |||
| 315 | }; | 326 | }; |
| 316 | } | 327 | } |
| 317 | 328 | ||
| 329 | #[allow(unused_macros)] | ||
| 330 | macro_rules! impl_adc_pair { | ||
| 331 | ($inst:ident, $pin:ident, $npin:ident, $ch:expr) => { | ||
| 332 | impl crate::adc::AdcChannel<peripherals::$inst> | ||
| 333 | for ( | ||
| 334 | crate::Peri<'_, crate::peripherals::$pin>, | ||
| 335 | crate::Peri<'_, crate::peripherals::$npin>, | ||
| 336 | ) | ||
| 337 | { | ||
| 338 | } | ||
| 339 | impl crate::adc::SealedAdcChannel<peripherals::$inst> | ||
| 340 | for ( | ||
| 341 | crate::Peri<'_, crate::peripherals::$pin>, | ||
| 342 | crate::Peri<'_, crate::peripherals::$npin>, | ||
| 343 | ) | ||
| 344 | { | ||
| 345 | #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v4, adc_u5, adc_wba))] | ||
| 346 | fn setup(&mut self) { | ||
| 347 | <crate::peripherals::$pin as crate::gpio::SealedPin>::set_as_analog(&mut self.0); | ||
| 348 | <crate::peripherals::$npin as crate::gpio::SealedPin>::set_as_analog(&mut self.1); | ||
| 349 | } | ||
| 350 | |||
| 351 | fn channel(&self) -> u8 { | ||
| 352 | $ch | ||
| 353 | } | ||
| 354 | |||
| 355 | fn is_differential(&self) -> bool { | ||
| 356 | true | ||
| 357 | } | ||
| 358 | } | ||
| 359 | }; | ||
| 360 | } | ||
| 361 | |||
| 318 | /// Get the maximum reading value for this resolution. | 362 | /// Get the maximum reading value for this resolution. |
| 319 | /// | 363 | /// |
| 320 | /// This is `2**n - 1`. | 364 | /// This is `2**n - 1`. |
