From 1479fbbee76b52e04bf658244fc535e462e17637 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Sat, 22 Nov 2025 00:37:19 +0100 Subject: Restructure build script and pin traits a little bit --- embassy-stm32/build.rs | 16 ++++++------ embassy-stm32/src/lcd.rs | 33 ++++++++++++++++-------- 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() { (("tsc", "G8_IO2"), quote!(crate::tsc::G8IO2Pin)), (("tsc", "G8_IO3"), quote!(crate::tsc::G8IO3Pin)), (("tsc", "G8_IO4"), quote!(crate::tsc::G8IO4Pin)), - (("lcd", "SEG"), quote!(crate::lcd::SegComPin)), - (("lcd", "COM"), quote!(crate::lcd::SegComPin)), + (("lcd", "SEG"), quote!(crate::lcd::SegPin)), + (("lcd", "COM"), quote!(crate::lcd::ComPin)), + (("lcd", "VLCD"), quote!(crate::lcd::VlcdPin)), (("dac", "OUT1"), quote!(crate::dac::DacPin)), (("dac", "OUT2"), quote!(crate::dac::DacPin)), ].into(); - let mut seen_lcd_pins = HashSet::new(); - for p in METADATA.peripherals { if let Some(regs) = &p.registers { let mut adc_pairs: BTreeMap, Option)> = BTreeMap::new(); + let mut seen_lcd_seg_pins = HashSet::new(); for pin in p.pins { let mut key = (regs.kind, pin.signal); - // LCD is special + // LCD is special. There are so many pins! if regs.kind == "lcd" { key.1 = pin.signal.trim_end_matches(char::is_numeric); - // Some lcd pins have multiple lcd functions - // Dedup so they don't get the trait implemented twice - if !seen_lcd_pins.insert(pin.pin) { + if key.1 == "SEG" && !seen_lcd_seg_pins.insert(pin.pin) { + // LCD has SEG pins multiplexed in the peripheral + // This means we can see them twice. We need to skip those so we're not impl'ing the trait twice continue; } } 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> { AfType::output(crate::gpio::OutputType::PushPull, crate::gpio::Speed::VeryHigh), ); + assert_eq!( + pins.iter().filter(|pin| !pin.is_seg).count(), + config.duty.num_com_pins() as usize, + "The number of provided COM pins is not the same as the duty configures" + ); + // Set the pins for pin in pins { pin.pin.set_as_af( @@ -375,23 +381,31 @@ impl<'d, T: Instance> Drop for Lcd<'d, T> { pub struct LcdPin<'d, T: Instance> { pin: Peri<'d, AnyPin>, af_num: u8, + is_seg: bool, _phantom: PhantomData, } -impl<'d, T: Instance, Pin: SegComPin> From> for LcdPin<'d, T> { - fn from(value: Peri<'d, Pin>) -> Self { - Self::new(value) +impl<'d, T: Instance> LcdPin<'d, T> { + /// Construct an LCD pin from any pin that supports it + pub fn new_seg(pin: Peri<'d, impl SegPin>) -> Self { + let af = pin.af_num(); + + Self { + pin: pin.into(), + af_num: af, + is_seg: true, + _phantom: PhantomData, + } } -} -impl<'d, T: Instance> LcdPin<'d, T> { /// Construct an LCD pin from any pin that supports it - pub fn new(pin: Peri<'d, impl SegComPin>) -> Self { + pub fn new_com(pin: Peri<'d, impl ComPin>) -> Self { let af = pin.af_num(); Self { pin: pin.into(), af_num: af, + is_seg: false, _phantom: PhantomData, } } @@ -405,13 +419,10 @@ trait SealedInstance: crate::rcc::SealedRccPeripheral + PeripheralType { #[allow(private_bounds)] pub trait Instance: SealedInstance + RccPeripheral + 'static {} -pin_trait!(SegComPin, Instance); +pin_trait!(SegPin, Instance); +pin_trait!(ComPin, Instance); pin_trait!(VlcdPin, Instance); -// TODO: pull into build.rs, but the metapack doesn't have this info -pin_trait_impl!(crate::lcd::VlcdPin, LCD, PC3, 11); -pin_trait_impl!(crate::lcd::VlcdPin, LCD, PB2, 11); - foreach_peripheral!( (lcd, $inst:ident) => { 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) { config, p.PC3, [ - LcdPin::from(p.PA8), - LcdPin::from(p.PA9), - LcdPin::from(p.PA10), - LcdPin::from(p.PB1), - LcdPin::from(p.PB9), - LcdPin::from(p.PB11), - LcdPin::from(p.PB14), - LcdPin::from(p.PB15), - LcdPin::from(p.PC4), - LcdPin::from(p.PC5), - LcdPin::from(p.PC6), - LcdPin::from(p.PC8), - LcdPin::from(p.PC9), - LcdPin::from(p.PC10), - LcdPin::from(p.PC11), - LcdPin::from(p.PD8), - LcdPin::from(p.PD9), - LcdPin::from(p.PD12), - LcdPin::from(p.PD13), - LcdPin::from(p.PD0), - LcdPin::from(p.PD1), - LcdPin::from(p.PD3), - LcdPin::from(p.PD4), - LcdPin::from(p.PD5), - LcdPin::from(p.PD6), - LcdPin::from(p.PE7), - LcdPin::from(p.PE8), - LcdPin::from(p.PE9), + LcdPin::new_com(p.PA8), + LcdPin::new_com(p.PA9), + LcdPin::new_com(p.PA10), + LcdPin::new_seg(p.PB1), + LcdPin::new_com(p.PB9), + LcdPin::new_seg(p.PB11), + LcdPin::new_seg(p.PB14), + LcdPin::new_seg(p.PB15), + LcdPin::new_seg(p.PC4), + LcdPin::new_seg(p.PC5), + LcdPin::new_seg(p.PC6), + LcdPin::new_seg(p.PC8), + LcdPin::new_seg(p.PC9), + LcdPin::new_seg(p.PC10), + LcdPin::new_seg(p.PC11), + LcdPin::new_seg(p.PD8), + LcdPin::new_seg(p.PD9), + LcdPin::new_seg(p.PD12), + LcdPin::new_seg(p.PD13), + LcdPin::new_seg(p.PD0), + LcdPin::new_seg(p.PD1), + LcdPin::new_seg(p.PD3), + LcdPin::new_seg(p.PD4), + LcdPin::new_seg(p.PD5), + LcdPin::new_seg(p.PD6), + LcdPin::new_seg(p.PE7), + LcdPin::new_seg(p.PE8), + LcdPin::new_seg(p.PE9), ], ); -- cgit