Files
stm32PinValidator/ioc_parser.py
T
janik 5f9e0b221b initial commit: STM32 Pin Validator KiCad plugin
Validates STM32 MCU pin assignments between KiCad PCB/schematic
and STM32CubeMX .ioc files with colour-coded results.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:11:46 +07:00

57 lines
1.8 KiB
Python

"""Parser for STM32CubeMX .ioc files (key=value format)."""
import re
# Matches GPIO pin names like PA0, PB12, PC3, PD2, PF0-OSC_IN, PB8-BOOT0
# Also handles CubeMX aliases like "PC14-OSC32_IN\ (PC14)" or "PA11\ [PA9]"
_GPIO_RE = re.compile(r"^(P[A-K]\d+(?:-[A-Z_0-9]+)?)(?:\\\s*[\[(][^\])]*[\])])?\.(.*)")
# Extracts remap aliases from Mcu.Pin entries, e.g. "PA11 [PA9]" → base=PA11, alias=PA9
_MCU_PIN_RE = re.compile(
r"^(P[A-K]\d+)(?:-[A-Z_0-9]+)?\s*[\[(](P[A-K]\d+)[\])]$"
)
def parse_ioc(ioc_path):
"""
Parse a .ioc file and return per-pin configuration and remap info.
Returns:
(pins, remaps)
pins: {gpio_base_name: {property: value, ...}}
remaps: {alias_gpio: base_gpio}
e.g. {'PA9': 'PA11'} means PA11 is remapped to PA9's
function — PA11 is the physical port for that pin.
"""
pins = {}
remaps = {}
with open(ioc_path, "r", encoding="utf-8") as fh:
for raw in fh:
line = raw.strip()
if "=" not in line:
continue
key, _, value = line.partition("=")
# Mcu.PinXX entries — extract remap aliases
if key.startswith("Mcu.Pin"):
m = _MCU_PIN_RE.match(value)
if m and m.group(1) != m.group(2):
# e.g. PA11 [PA9] → remaps["PA9"] = "PA11"
remaps[m.group(2)] = m.group(1)
continue
m = _GPIO_RE.match(key)
if not m:
continue
full_pin = m.group(1) # e.g. "PF0-OSC_IN"
prop = m.group(2) # e.g. "Signal"
base = full_pin.split("-")[0] # e.g. "PF0"
pins.setdefault(base, {})[prop] = value
return pins, remaps