Skip to content

Commit

Permalink
stm32: generate singletons only for pins that actually exist.
Browse files Browse the repository at this point in the history
Before we'd generate all pins Px0..Px15 for each GPIOx port. This changes
codegen to only generate singletons for actually-existing pins.

(AFs were already previously filtered, so these non-existing pins were already mostly useless)
  • Loading branch information
Dirbaio committed Jan 7, 2025
1 parent 2fecaeb commit 103bb0d
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 46 deletions.
4 changes: 2 additions & 2 deletions embassy-stm32/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ rand_core = "0.6.3"
sdio-host = "0.5.0"
critical-section = "1.1"
#stm32-metapac = { version = "15" }
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-fad4bc0f2baac29ecebb5153d2997b649b71025f" }
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-db71f6aa03b7db26548b461d3844fc404d40c98c" }

vcell = "0.1.3"
nb = "1.0.0"
Expand Down Expand Up @@ -102,7 +102,7 @@ proc-macro2 = "1.0.36"
quote = "1.0.15"

#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-fad4bc0f2baac29ecebb5153d2997b649b71025f", default-features = false, features = ["metadata"] }
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-db71f6aa03b7db26548b461d3844fc404d40c98c", default-features = false, features = ["metadata"] }

[features]
default = ["rt"]
Expand Down
85 changes: 43 additions & 42 deletions embassy-stm32/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ fn main() {
// Generate singletons

let mut singletons: Vec<String> = Vec::new();

// Generate one singleton per pin
for p in METADATA.pins {
singletons.push(p.name.to_string());
}

// generate one singleton per peripheral (with many exceptions...)
for p in METADATA.peripherals {
if let Some(r) = &p.registers {
if r.kind == "adccommon" || r.kind == "sai" || r.kind == "ucpd" || r.kind == "otg" || r.kind == "octospi" {
Expand All @@ -63,13 +70,8 @@ fn main() {
}

match r.kind {
// Generate singletons per pin, not per port
"gpio" => {
let port_letter = p.name.strip_prefix("GPIO").unwrap();
for pin_num in 0..16 {
singletons.push(format!("P{}{}", port_letter, pin_num));
}
}
// handled above
"gpio" => {}

// No singleton for these, the HAL handles them specially.
"exti" => {}
Expand Down Expand Up @@ -1478,43 +1480,42 @@ fn main() {
let gpio_base = METADATA.peripherals.iter().find(|p| p.name == "GPIOA").unwrap().address as u32;
let gpio_stride = 0x400;

for p in METADATA.peripherals {
if let Some(regs) = &p.registers {
if regs.kind == "gpio" {
let port_letter = p.name.chars().nth(4).unwrap();
assert_eq!(0, (p.address as u32 - gpio_base) % gpio_stride);
let port_num = (p.address as u32 - gpio_base) / gpio_stride;

for pin_num in 0u32..16 {
let pin_name = format!("P{}{}", port_letter, pin_num);

pins_table.push(vec![
pin_name.clone(),
p.name.to_string(),
port_num.to_string(),
pin_num.to_string(),
format!("EXTI{}", pin_num),
]);

// If we have the split pins, we need to do a little extra work:
// Add the "_C" variant to the table. The solution is not optimal, though.
// Adding them only when the corresponding GPIOx also appears.
// This should avoid unintended side-effects as much as possible.
#[cfg(feature = "_split-pins-enabled")]
for split_feature in &split_features {
if split_feature.pin_name_without_c == pin_name {
pins_table.push(vec![
split_feature.pin_name_with_c.to_string(),
p.name.to_string(),
port_num.to_string(),
pin_num.to_string(),
format!("EXTI{}", pin_num),
]);
}
}
}
for pin in METADATA.pins {
let port_letter = pin.name.chars().nth(1).unwrap();
let pname = format!("GPIO{}", port_letter);
let p = METADATA.peripherals.iter().find(|p| p.name == pname).unwrap();
assert_eq!(0, (p.address as u32 - gpio_base) % gpio_stride);
let port_num = (p.address as u32 - gpio_base) / gpio_stride;
let pin_num: u32 = pin.name[2..].parse().unwrap();

pins_table.push(vec![
pin.name.to_string(),
p.name.to_string(),
port_num.to_string(),
pin_num.to_string(),
format!("EXTI{}", pin_num),
]);

// If we have the split pins, we need to do a little extra work:
// Add the "_C" variant to the table. The solution is not optimal, though.
// Adding them only when the corresponding GPIOx also appears.
// This should avoid unintended side-effects as much as possible.
#[cfg(feature = "_split-pins-enabled")]
for split_feature in &split_features {
if split_feature.pin_name_without_c == pin_name {
pins_table.push(vec![
split_feature.pin_name_with_c.to_string(),
p.name.to_string(),
port_num.to_string(),
pin_num.to_string(),
format!("EXTI{}", pin_num),
]);
}
}
}

for p in METADATA.peripherals {
if let Some(regs) = &p.registers {
if regs.kind == "adc" {
let adc_num = p.name.strip_prefix("ADC").unwrap();
let mut adc_common = None;
Expand Down
2 changes: 1 addition & 1 deletion examples/stm32u0/src/bin/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn main() -> ! {

let mut spi = Spi::new_blocking(p.SPI3, p.PC10, p.PC12, p.PC11, spi_config);

let mut cs = Output::new(p.PE0, Level::High, Speed::VeryHigh);
let mut cs = Output::new(p.PC13, Level::High, Speed::VeryHigh);

loop {
let mut buf = [0x0Au8; 4];
Expand Down
3 changes: 2 additions & 1 deletion examples/stm32u5/src/bin/blinky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ async fn main(_spawner: Spawner) -> ! {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");

let mut led = Output::new(p.PH7, Level::Low, Speed::Medium);
// replace PC13 with the right pin for your board.
let mut led = Output::new(p.PC13, Level::Low, Speed::Medium);

loop {
defmt::info!("on!");
Expand Down

0 comments on commit 103bb0d

Please sign in to comment.