aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/build.rs16
-rw-r--r--embassy-stm32/src/lcd.rs33
-rw-r--r--examples/stm32u0/src/bin/lcd.rs56
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> {
375pub struct LcdPin<'d, T: Instance> { 381pub 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
381impl<'d, T: Instance, Pin: SegComPin<T>> From<Peri<'d, Pin>> for LcdPin<'d, T> { 388impl<'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
387impl<'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)]
406pub trait Instance: SealedInstance + RccPeripheral + 'static {} 420pub trait Instance: SealedInstance + RccPeripheral + 'static {}
407 421
408pin_trait!(SegComPin, Instance); 422pin_trait!(SegPin, Instance);
423pin_trait!(ComPin, Instance);
409pin_trait!(VlcdPin, Instance); 424pin_trait!(VlcdPin, Instance);
410 425
411// TODO: pull into build.rs, but the metapack doesn't have this info
412pin_trait_impl!(crate::lcd::VlcdPin, LCD, PC3, 11);
413pin_trait_impl!(crate::lcd::VlcdPin, LCD, PB2, 11);
414
415foreach_peripheral!( 426foreach_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