use crate::silicon::*;
fn af(pin: &str, signal: PeripheralSignal) -> Option<u8> {
let chip = find_target("stm32g431vb").unwrap();
chip.find_pin(pin)?.get_af(&signal).map(|f| f.af_number)
}
#[test]
fn covers_every_gpio_of_the_largest_package() {
let chip = find_target("stm32g431vb").unwrap();
let expected = (0..16)
.flat_map(|n| ["PA", "PB", "PC", "PD", "PE"].map(|p| format!("{p}{n}")))
.chain(["PF0", "PF1", "PF2", "PF9", "PF10", "PG10"].map(String::from));
for pin in expected {
assert!(chip.find_pin(&pin).is_some(), "{pin} missing");
}
assert_eq!(chip.pins.len(), 86);
}
#[test]
fn rejects_pins_that_do_not_exist() {
let chip = find_target("stm32g431vb").unwrap();
for pin in ["PA16", "PB16", "PC16", "PF3", "PG0", "PG9"] {
assert!(chip.find_pin(pin).is_none(), "{pin} must not exist");
}
}
#[test]
fn matches_datasheet_alternate_functions() {
assert_eq!(af("PA9", PeripheralSignal::UartTx(1)), Some(7));
assert_eq!(af("PA9", PeripheralSignal::I2cScl(2)), Some(4));
assert_eq!(af("PB8", PeripheralSignal::I2cScl(1)), Some(4));
assert_eq!(af("PB3", PeripheralSignal::SpiSck(1)), Some(5));
assert_eq!(af("PB3", PeripheralSignal::SpiSck(3)), Some(6));
assert_eq!(af("PC10", PeripheralSignal::UartTx(4)), Some(5));
assert_eq!(af("PC10", PeripheralSignal::UartTx(3)), Some(7));
assert_eq!(af("PA0", PeripheralSignal::UartCts(2)), Some(7));
assert_eq!(af("PA13", PeripheralSignal::SwdDio), Some(0));
assert_eq!(af("PA14", PeripheralSignal::SwdClk), Some(0));
}
#[test]
fn omits_signals_the_datasheet_does_not_list() {
let chip = find_target("stm32g431vb").unwrap();
let pc13 = chip.find_pin("PC13").unwrap();
assert!(pc13.functions.iter().all(|f| f.af_number != 7));
assert_eq!(af("PB6", PeripheralSignal::I2cScl(1)), None);
assert_eq!(af("PA0", PeripheralSignal::UartTx(2)), None);
assert_eq!(af("PA11", PeripheralSignal::UsbDm), None);
}
#[test]
fn marks_adc_pins_analog() {
let chip = find_target("stm32g431vb").unwrap();
assert!(chip.find_pin("PC4").unwrap().capabilities.is_analog);
assert!(!chip.find_pin("PA9").unwrap().capabilities.is_analog);
assert_eq!(af("PC4", PeripheralSignal::AdcChannel(2, 5)), Some(0));
assert_eq!(af("PC0", PeripheralSignal::AdcChannel(1, 6)), Some(0));
assert_eq!(af("PC0", PeripheralSignal::AdcChannel(2, 6)), Some(0));
}
#[test]
fn gates_pins_by_package() {
let bonded = |chip: &str, pin: &str| find_target(chip).unwrap().find_pin(pin).is_some();
assert!(bonded("stm32g431cb", "PA9"));
assert!(!bonded("stm32g431cb", "PE5"));
assert!(!bonded("stm32g431cb", "PD2"));
assert!(!bonded("stm32g431cb", "PC4"));
assert!(!bonded("stm32g431kb", "PB10"));
assert!(!bonded("stm32g431kb", "PC13"));
assert!(bonded("stm32g431kb", "PB8"));
assert!(bonded("stm32g431rb", "PD2"));
assert!(!bonded("stm32g431rb", "PD0"));
assert!(bonded("stm32g431mb", "PE7"));
assert!(!bonded("stm32g431mb", "PE6"));
assert!(bonded("stm32g431vb", "PE5"));
assert!(find_target("stm32g431gb").is_none());
for (chip, count) in [
("stm32g431", 26),
("stm32g431kb", 26),
("stm32g431cb", 38),
("stm32g431rb", 52),
("stm32g431mb", 66),
("stm32g431vb", 86),
] {
assert_eq!(find_target(chip).unwrap().pins.len(), count, "{chip}");
}
}
#[test]
fn pin_mux_flags_pins_the_package_does_not_bond() {
let chip = find_target("stm32g431cb").unwrap();
let conflicts = validate_pin_assignments(chip, &[super::assigned("PE5", "UART1_TX", false)]);
assert!(
conflicts
.iter()
.any(|c| matches!(c, PinConflict::UnknownPin { pin_name, .. } if pin_name == "PE5")),
"{conflicts:?}"
);
}