diff options
| author | Dion Dokter <[email protected]> | 2025-11-22 00:37:19 +0100 |
|---|---|---|
| committer | Dion Dokter <[email protected]> | 2025-11-22 00:37:19 +0100 |
| commit | 1479fbbee76b52e04bf658244fc535e462e17637 (patch) | |
| tree | db3f79c3c3516b28253a1f2c966eca1c9e6a2f07 | |
| parent | c972b81a737e43e5580a76d6538caa625a39f829 (diff) | |
Restructure build script and pin traits a little bit
| -rw-r--r-- | embassy-stm32/build.rs | 16 | ||||
| -rw-r--r-- | embassy-stm32/src/lcd.rs | 33 | ||||
| -rw-r--r-- | examples/stm32u0/src/bin/lcd.rs | 56 |
3 files changed, 58 insertions, 47 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 8cddb68f9..fa493da84 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -1352,28 +1352,28 @@ fn main() { | |||
| 1352 | (("tsc", "G8_IO2"), quote!(crate::tsc::G8IO2Pin)), | 1352 | (("tsc", "G8_IO2"), quote!(crate::tsc::G8IO2Pin)), |
| 1353 | (("tsc", "G8_IO3"), quote!(crate::tsc::G8IO3Pin)), | 1353 | (("tsc", "G8_IO3"), quote!(crate::tsc::G8IO3Pin)), |
| 1354 | (("tsc", "G8_IO4"), quote!(crate::tsc::G8IO4Pin)), | 1354 | (("tsc", "G8_IO4"), quote!(crate::tsc::G8IO4Pin)), |
| 1355 | (("lcd", "SEG"), quote!(crate::lcd::SegComPin)), | 1355 | (("lcd", "SEG"), quote!(crate::lcd::SegPin)), |
| 1356 | (("lcd", "COM"), quote!(crate::lcd::SegComPin)), | 1356 | (("lcd", "COM"), quote!(crate::lcd::ComPin)), |
| 1357 | (("lcd", "VLCD"), quote!(crate::lcd::VlcdPin)), | ||
| 1357 | (("dac", "OUT1"), quote!(crate::dac::DacPin<Ch1>)), | 1358 | (("dac", "OUT1"), quote!(crate::dac::DacPin<Ch1>)), |
| 1358 | (("dac", "OUT2"), quote!(crate::dac::DacPin<Ch2>)), | 1359 | (("dac", "OUT2"), quote!(crate::dac::DacPin<Ch2>)), |
| 1359 | ].into(); | 1360 | ].into(); |
| 1360 | 1361 | ||
| 1361 | let mut seen_lcd_pins = HashSet::new(); | ||
| 1362 | |||
| 1363 | for p in METADATA.peripherals { | 1362 | for p in METADATA.peripherals { |
| 1364 | if let Some(regs) = &p.registers { | 1363 | if let Some(regs) = &p.registers { |
| 1365 | let mut adc_pairs: BTreeMap<u8, (Option<Ident>, Option<Ident>)> = BTreeMap::new(); | 1364 | let mut adc_pairs: BTreeMap<u8, (Option<Ident>, Option<Ident>)> = BTreeMap::new(); |
| 1365 | let mut seen_lcd_seg_pins = HashSet::new(); | ||
| 1366 | 1366 | ||
| 1367 | for pin in p.pins { | 1367 | for pin in p.pins { |
| 1368 | let mut key = (regs.kind, pin.signal); | 1368 | let mut key = (regs.kind, pin.signal); |
| 1369 | 1369 | ||
| 1370 | // LCD is special | 1370 | // LCD is special. There are so many pins! |
| 1371 | if regs.kind == "lcd" { | 1371 | if regs.kind == "lcd" { |
| 1372 | key.1 = pin.signal.trim_end_matches(char::is_numeric); | 1372 | key.1 = pin.signal.trim_end_matches(char::is_numeric); |
| 1373 | 1373 | ||
| 1374 | // Some lcd pins have multiple lcd functions | 1374 | if key.1 == "SEG" && !seen_lcd_seg_pins.insert(pin.pin) { |
| 1375 | // Dedup so they don't get the trait implemented twice | 1375 | // LCD has SEG pins multiplexed in the peripheral |
| 1376 | if !seen_lcd_pins.insert(pin.pin) { | 1376 | // This means we can see them twice. We need to skip those so we're not impl'ing the trait twice |
| 1377 | continue; | 1377 | continue; |
| 1378 | } | 1378 | } |
| 1379 | } | 1379 | } |
diff --git a/embassy-stm32/src/lcd.rs b/embassy-stm32/src/lcd.rs index 3a890e529..66a9386b7 100644 --- a/embassy-stm32/src/lcd.rs +++ b/embassy-stm32/src/lcd.rs | |||
| @@ -168,6 +168,12 @@ impl<'d, T: Instance> Lcd<'d, T> { | |||
| 168 | AfType::output(crate::gpio::OutputType::PushPull, crate::gpio::Speed::VeryHigh), | 168 | AfType::output(crate::gpio::OutputType::PushPull, crate::gpio::Speed::VeryHigh), |
| 169 | ); | 169 | ); |
| 170 | 170 | ||
| 171 | assert_eq!( | ||
| 172 | pins.iter().filter(|pin| !pin.is_seg).count(), | ||
| 173 | config.duty.num_com_pins() as usize, | ||
| 174 | "The number of provided COM pins is not the same as the duty configures" | ||
| 175 | ); | ||
| 176 | |||
| 171 | // Set the pins | 177 | // Set the pins |
| 172 | for pin in pins { | 178 | for pin in pins { |
| 173 | pin.pin.set_as_af( | 179 | pin.pin.set_as_af( |
| @@ -375,23 +381,31 @@ impl<'d, T: Instance> Drop for Lcd<'d, T> { | |||
| 375 | pub struct LcdPin<'d, T: Instance> { | 381 | pub struct LcdPin<'d, T: Instance> { |
| 376 | pin: Peri<'d, AnyPin>, | 382 | pin: Peri<'d, AnyPin>, |
| 377 | af_num: u8, | 383 | af_num: u8, |
| 384 | is_seg: bool, | ||
| 378 | _phantom: PhantomData<T>, | 385 | _phantom: PhantomData<T>, |
| 379 | } | 386 | } |
| 380 | 387 | ||
| 381 | impl<'d, T: Instance, Pin: SegComPin<T>> From<Peri<'d, Pin>> for LcdPin<'d, T> { | 388 | impl<'d, T: Instance> LcdPin<'d, T> { |
| 382 | fn from(value: Peri<'d, Pin>) -> Self { | 389 | /// Construct an LCD pin from any pin that supports it |
| 383 | Self::new(value) | 390 | pub fn new_seg(pin: Peri<'d, impl SegPin<T>>) -> Self { |
| 391 | let af = pin.af_num(); | ||
| 392 | |||
| 393 | Self { | ||
| 394 | pin: pin.into(), | ||
| 395 | af_num: af, | ||
| 396 | is_seg: true, | ||
| 397 | _phantom: PhantomData, | ||
| 398 | } | ||
| 384 | } | 399 | } |
| 385 | } | ||
| 386 | 400 | ||
| 387 | impl<'d, T: Instance> LcdPin<'d, T> { | ||
| 388 | /// Construct an LCD pin from any pin that supports it | 401 | /// Construct an LCD pin from any pin that supports it |
| 389 | pub fn new(pin: Peri<'d, impl SegComPin<T>>) -> Self { | 402 | pub fn new_com(pin: Peri<'d, impl ComPin<T>>) -> Self { |
| 390 | let af = pin.af_num(); | 403 | let af = pin.af_num(); |
| 391 | 404 | ||
| 392 | Self { | 405 | Self { |
| 393 | pin: pin.into(), | 406 | pin: pin.into(), |
| 394 | af_num: af, | 407 | af_num: af, |
| 408 | is_seg: false, | ||
| 395 | _phantom: PhantomData, | 409 | _phantom: PhantomData, |
| 396 | } | 410 | } |
| 397 | } | 411 | } |
| @@ -405,13 +419,10 @@ trait SealedInstance: crate::rcc::SealedRccPeripheral + PeripheralType { | |||
| 405 | #[allow(private_bounds)] | 419 | #[allow(private_bounds)] |
| 406 | pub trait Instance: SealedInstance + RccPeripheral + 'static {} | 420 | pub trait Instance: SealedInstance + RccPeripheral + 'static {} |
| 407 | 421 | ||
| 408 | pin_trait!(SegComPin, Instance); | 422 | pin_trait!(SegPin, Instance); |
| 423 | pin_trait!(ComPin, Instance); | ||
| 409 | pin_trait!(VlcdPin, Instance); | 424 | pin_trait!(VlcdPin, Instance); |
| 410 | 425 | ||
| 411 | // TODO: pull into build.rs, but the metapack doesn't have this info | ||
| 412 | pin_trait_impl!(crate::lcd::VlcdPin, LCD, PC3, 11); | ||
| 413 | pin_trait_impl!(crate::lcd::VlcdPin, LCD, PB2, 11); | ||
| 414 | |||
| 415 | foreach_peripheral!( | 426 | foreach_peripheral!( |
| 416 | (lcd, $inst:ident) => { | 427 | (lcd, $inst:ident) => { |
| 417 | impl crate::lcd::SealedInstance for peripherals::$inst { | 428 | impl crate::lcd::SealedInstance for peripherals::$inst { |
diff --git a/examples/stm32u0/src/bin/lcd.rs b/examples/stm32u0/src/bin/lcd.rs index f401b1dcd..39db5c9c8 100644 --- a/examples/stm32u0/src/bin/lcd.rs +++ b/examples/stm32u0/src/bin/lcd.rs | |||
| @@ -43,34 +43,34 @@ async fn main(_spawner: Spawner) { | |||
| 43 | config, | 43 | config, |
| 44 | p.PC3, | 44 | p.PC3, |
| 45 | [ | 45 | [ |
| 46 | LcdPin::from(p.PA8), | 46 | LcdPin::new_com(p.PA8), |
| 47 | LcdPin::from(p.PA9), | 47 | LcdPin::new_com(p.PA9), |
| 48 | LcdPin::from(p.PA10), | 48 | LcdPin::new_com(p.PA10), |
| 49 | LcdPin::from(p.PB1), | 49 | LcdPin::new_seg(p.PB1), |
| 50 | LcdPin::from(p.PB9), | 50 | LcdPin::new_com(p.PB9), |
| 51 | LcdPin::from(p.PB11), | 51 | LcdPin::new_seg(p.PB11), |
| 52 | LcdPin::from(p.PB14), | 52 | LcdPin::new_seg(p.PB14), |
| 53 | LcdPin::from(p.PB15), | 53 | LcdPin::new_seg(p.PB15), |
| 54 | LcdPin::from(p.PC4), | 54 | LcdPin::new_seg(p.PC4), |
| 55 | LcdPin::from(p.PC5), | 55 | LcdPin::new_seg(p.PC5), |
| 56 | LcdPin::from(p.PC6), | 56 | LcdPin::new_seg(p.PC6), |
| 57 | LcdPin::from(p.PC8), | 57 | LcdPin::new_seg(p.PC8), |
| 58 | LcdPin::from(p.PC9), | 58 | LcdPin::new_seg(p.PC9), |
| 59 | LcdPin::from(p.PC10), | 59 | LcdPin::new_seg(p.PC10), |
| 60 | LcdPin::from(p.PC11), | 60 | LcdPin::new_seg(p.PC11), |
| 61 | LcdPin::from(p.PD8), | 61 | LcdPin::new_seg(p.PD8), |
| 62 | LcdPin::from(p.PD9), | 62 | LcdPin::new_seg(p.PD9), |
| 63 | LcdPin::from(p.PD12), | 63 | LcdPin::new_seg(p.PD12), |
| 64 | LcdPin::from(p.PD13), | 64 | LcdPin::new_seg(p.PD13), |
| 65 | LcdPin::from(p.PD0), | 65 | LcdPin::new_seg(p.PD0), |
| 66 | LcdPin::from(p.PD1), | 66 | LcdPin::new_seg(p.PD1), |
| 67 | LcdPin::from(p.PD3), | 67 | LcdPin::new_seg(p.PD3), |
| 68 | LcdPin::from(p.PD4), | 68 | LcdPin::new_seg(p.PD4), |
| 69 | LcdPin::from(p.PD5), | 69 | LcdPin::new_seg(p.PD5), |
| 70 | LcdPin::from(p.PD6), | 70 | LcdPin::new_seg(p.PD6), |
| 71 | LcdPin::from(p.PE7), | 71 | LcdPin::new_seg(p.PE7), |
| 72 | LcdPin::from(p.PE8), | 72 | LcdPin::new_seg(p.PE8), |
| 73 | LcdPin::from(p.PE9), | 73 | LcdPin::new_seg(p.PE9), |
| 74 | ], | 74 | ], |
| 75 | ); | 75 | ); |
| 76 | 76 | ||
