Skip to content

STM32U575 (NUCLEO-U575ZI-Q)

The STM32U575ZI (Arm Cortex-M33 with FPU, up to 160 MHz, 2 MB flash, 768 KB SRAM + 16 KB SRAM4) is LabWired's first STM32U5 target and the first U5 part in the fleet. The port reuses the shared V2 register engines (gpio/uart stm32v2, i2c stm32l4, spi stm32h5, timers, ADC), and adds the U5-specific pieces the bring-up needs: the full U5 RCC map (the stm32v2 RCC profile is U5-only — ICSCR1/2/3 0x08/0x0C/0x10, CRRCR 0x14, CFGR1/2/3 0x1C/0x20/0x24, PLL1/2/3 blocks 0x28..0x48, CIER/CIFR/CICR 0x50..0x58, AHB1ENR 0x88, AHB2ENR1/2 0x8C/0x90, AHB3ENR 0x94, APB1ENR1/2 0x9C/0xA0, APB2ENR 0xA4, APB3ENR 0xA8 plus the eight *RSTRs at 0x60..0x80, BDCR 0xF0, CSR 0xF4), the U5 CR ready pairs (MSISRDY/HSI48RDY and PLL1/2/3 ready), clock: gates for every RCC-gated peripheral (RM0456 enable bits, verified against the vendored SVD), and a CRS register-surface model (CR/CFGR/ISR/ICR).

Fidelity: SIM-DERIVED. LabWired has no U575 bench part. Every reset value and behaviour is SVD / RM0456 / DS13736-derived, not a silicon capture — there is no reg_oracle, no MMIO diff and no Renode differential (Renode master ships no STM32U5 platform; closest references are stm32wba52.repl and stm32l552.repl, checked 2026-09-17). Promote to a silicon tier only when a real NUCLEO-U575ZI-Q is diffed over SWD.

Status at a glance

Live status: the table below is a hand-maintained snapshot. For the authoritative, auto-generated view see the chip conformance scoreboard and the tier-1 matrix.

Aspect Status
Chip yaml configs/chips/stm32u575.yaml
System yaml configs/systems/nucleo-u575zi.yaml
Example examples/nucleo-u575zi/ (VALIDATION.md = runbook + evidence)
Reference firmware crates/firmware-stm32u575-demo (Rust io-smoke), examples/nucleo-u575zi/board_firmware/ (stock STM32CubeU5 HAL, 160 MHz PLL1 + USART1 VCP + LD1 loop)
Validation real CubeU5 HAL firmware runs in-sim (U575-HAL OK + BLINK n LD1=<0\|1>); stock Zephyr nucleo_u575zi_q hello boots (test_stm32u575_zephyr_survival); Arduino matrix L0–L8 (CI lane); Zephyr matrix L0–L3 (local run; no CI workflow yet); flash unlock→erase→program→flags pinned by the u575_flash tests over the committed chip yaml; unsupported-instruction audit 0/0/0 at 200k steps
Tier sim-validated — reference-manual-derived, no silicon diff
Core type Arm Cortex-M33 (TrustZone present in the core, factory-disabled per UM2883)

Peripherals (from chip yaml)

Peripheral Base Status Notes
Cortex-M33 — ✅ modeled Thumb-2 + FPU; RRX (ror #0) rotate-through-carry modeled in interpreter + JIT lockstep
RCC 0x46020C00 ✅ tested in-sim stm32v2 is U5-only: full enable/reset block (AHB1/AHB2ENR1+2/AHB3/APB1ENR1+2/APB2/APB3 + RSTRs), ICSCR1/2/3, CRRCR@0x14, CFGR1/2/3, PLL1/2/3 blocks, CIER/CIFR/CICR, BDCR@0xF0/CSR@0xF4 (RMVF W1C), U5 CR ready pairs; per-peripheral clock: gates
PWR 0x46020800 ✅ tested in-sim wba profile — VOSR ready + supply config for the 160 MHz bring-up
FLASH 0x40022000 ✅ tested in-sim stm32u5 profile: ACR latency read-back + full non-secure program/erase controller (RM0456 §7) — NSKEYR/OPTKEYR unlock, NSCR PG/PER/PNB/BKER/STRT, NSSR EOP/WRPERR W1C, 2 × 1 MiB banks / 8 KiB pages, 128-bit quad-word program; option-byte OPTR storage
GPIOA–I 0x42020000 ✅ tested in-sim stm32v2 MODER/AFR/ODR/BSRR; LD1 on PC7
USART1 0x40013800 ✅ tested in-sim VCP console (PA9/PA10), IRQ 61 — Cube HAL + Zephyr + Arduino all use it
USART2–3, UART4 0x40004400.. ✅ modeled stm32v2; no VCP wiring on the board
LPUART1 0x46002400 ✅ modeled stm32v2
I2C1–3 0x40005400 ✅ tested in-sim stm32l4 engine; INA219 @0x40 ACKs on I2C1 (Arduino L3, Zephyr L3)
SPI1–3 0x40013000 ✅ tested in-sim stm32h5 engine + declared pad_map: "stm32u5" (DS13737 Table 27); MAX31855 frame 0x01901600 over SPI1 (Arduino L4), pad edges scored by bus_visibility
FDCAN1 0x4000A400 ✅ tested in-sim Bosch M_CAN, register/reset-identical to the H563 file (SVD CREL 0x3214_1218, ENDN 0x8765_4321, 37 registers); 4 KiB window includes FDCAN1_RAM @ 0x4000_AC00 (+0x800, hardwired SRAMCAN layout); RCC_APB1ENR2.FDCAN1EN bit 9 gate (0xA0, SVD/RM0456 — not APB1ENR1); internal loopback (TEST.LBCK) runs Arduino L8 (LW_L8_OK)
TIM1/2/3/6/7 0x40000000 (TIM1: 0x40012C00) ✅ modeled TIM2 32-bit; TIM1 advanced/PWM; Arduino L6/L7 exercise the timer path
GPDMA1 0x40020000 ✅ modeled 16 channels (SVD map to 0x84C, 4 KiB window); CH0–7 IRQs 29–36 via irq_base: 29. The SVD puts CH8–15 on separate NVIC lines 80–87 — not routed yet
ADC1 0x42028000 ✅ tested in-sim stm32u5 map, SVD-verified: CFGR1.RES[3:2] = 14/12/10/8, PCSEL@0x1C, LTR1-3/HTR1-3@0xA8..0xBC (HTRx reset 0x01FF_FFFF), GCOMP@0x70, CALFACT2@0xC8, DR@0x40; Arduino L5 analogRead passes
RTC 0x46007800 ✅ modeled rtc_v3 calendar
IWDG 0x40003000 ✅ modeled
CRC 0x40023000 ✅ tested in-sim Arduino core startup writes CRC->POL; the Arduino survival case pins the path
CRS 0x40006000 ⚠️ register surface reset/writable fields + SWSYNC→SYNCOKF; no SYNC source, no trim loop
RNG 0x420C0800 ✅ modeled seeded in-sim, not silicon-faithful
ICACHE 0x40030400 ⚠️ stub declared so Cube HAL's HAL_ICACHE_Enable cannot bus-fault
DBGMCU 0xE0044000 ✅ modeled IDCODE reset 0x30016482 per SVD
SysTick / NVIC 0xE000E010 / 0xE000E100 ✅ modeled scheduler-backed counter; NVIC masking exercised by the matrices

Flash / firmware artifacts

Use Artifact Notes
Rust io-smoke crates/firmware-stm32u575-demo (thumbv8m.main-none-eabi) built from source by strict_onboarding / the onboarding workflow
Vendor HAL examples/nucleo-u575zi/board_firmware/build/u575_hal_smoke.elf stock STM32CubeU5 HAL checkout; not committed (build it locally)
Zephyr stock hello_world for nucleo_u575zi_q (Zephyr 3.7.2) committed fixture tests/fixtures/stm32u575-zephyr-hello.elf
Arduino PlatformIO stm32 core sketch ELF committed fixture tests/fixtures/stm32u575-arduino-serial.elf (L0 marker)

Pins (NUCLEO-U575ZI-Q)

Board label MCU pin Notes
LD1 (green) PC7 Arduino LED_BUILTIN (LED_GREEN = LED_LD1); led_watch: gpioc:7 in the matrix
LD2 (blue) PB7
LD3 (red) PG2
USER button PC13
VCP TX/RX PA9 / PA10 USART1 (AF7), 115200 8N1 — CubeU5 COM1, Zephyr console, Arduino Serial
Arduino SPI PA5/PA6/PA7 + PA4 NSS SPI1; pad_map: "stm32u5" publishes SCK/MISO/MOSI onto the pads (NSS is AF5 but not routable)
Arduino I2C I2C1 (default Wire) INA219 kit attaches at 0x40
FDCAN1 PB8 / PB9 AF9 (RX/TX); alternates PA11/PA12, PD0/PD1, PF7/PF8 also AF9 (DS13737 Table 27, PlatformIO variant). Not on the Arduino headers — the L8 sketch uses internal loopback, so no pad is wired

Known omissions / documented gaps

The chip yaml does not declare: TrustZone/GTZC/SAU enforcement (factory TZEN=0, so the non-secure 0x0800_0000 alias is the boot path), OCTOSPI/HSPI, USB OTG, ADC4, ethernet. Extra honest gaps:

  • Flash program/erase is modeled (RM0456 §7, SVD-verified offsets): the stm32u5 profile keeps the ACR latency read-back the HAL polls and adds the non-secure controller — NSKEYR/OPTKEYR unlock (LOCK@NSCR.31, OPTLOCK@NSCR.30), NSCR PG/PER/PNB/BKER/STRT, NSSR EOP/WRPERR/PGAERR/ PGSERR/SIZERR/OPTWERR as write-1-to-clear, 8 KiB page erase drained per instruction and filled with 0xFF, and 128-bit quad-word programming as four successive 32-bit stores (flash only flips 1→0). Remaining gaps: mass erase (MER1/MER2) is accepted but not applied, read-while-write is not enforced (flash routines need not run from SRAM in-sim), and program-over-not-erased commits the bitwise AND instead of raising PROGERR. Option bytes are storage-only: OPTR reads back when written after the OPTKEYR sequence, NSCR.OPTSTRT completes with EOP, and no option reload/SWAP_BANK is applied to the backing store.
  • FDCAN1 is the only CAN instance: DS13737 lists "1 CAN FD controller", and both the vendored SVD and ST's stm32u575xx.h declare only FDCAN1, so there is no fdcan2 at 0x4000_A800. As with the H563 sibling, acceptance filtering, dedicated RX buffers and the FDCAN1_IT1 (ILS line 1, NVIC 40) routing are not modeled — all enabled interrupts assert IT0 (NVIC 39) and loopback frames follow the model's fixed FIFO0 path.
  • SPI NSS is not routable: the stm32u5 AF table covers all SCK/MISO/MOSI rows for SPI1–3 (DS13737 Table 27), but the pad mechanism carries only those three signals, so PA4 (SPI1_NSS, AF5) and the other NSS alternates stay unrouted. Port-I alternates (PI1/PI2/PI3 = SPI2 SCK/MISO/MOSI, AF5) are not transcribed either: the router walks ports A–H only.
  • CRS has no SYNC source: SWSYNC latches SYNCOKF, but USB SOF/LSE synchronization and HSI48 trimming are not simulated.
  • ADC4 is not declared: the vendored SVD's ADC4 (0x46021000, IRQ 113) is a different 12-bit class from ADC1 — SMPR/AWDxTR/CHSELRMOD0/1, no PCSEL, no LTR/HTR pairs, no CALFACT2, CR reset 0 — so it is not a register-compatible sibling of the new stm32u5 ADC1 map. ADC1 is fully modeled and exercised by Arduino L5 (analogRead).
  • GPDMA1 models all 16 channels; per-channel NVIC routing is irq_base + n, so the SVD's CH8–15 lines (80–87) are not yet routed while CH0–7 (29–36) are.
  • Clock gating is modeled: every RCC-gated peripheral in the chip yaml declares its RM0456 enable bit (and the RTC additionally its BDCR kernel clock), so an unclocked register access reads 0 / drops the write. IWDG, ICACHE and DBGMCU stay deliberately ungated — U5 has no RCC bus-enable bit for them (IWDG is always-on LSI-clocked, ICACHE has only the sleep-mode SMENR bit, DBGMCU is in the debug domain).
  • PLL2/PLL3 register blocks (PLL2/3CFGR, PLL2/3DIVR, PLL2/3FRACR) and their CR ready pairs are modeled as storage/status — frequencies are not computed.
  • CFGR2/CFGR3 (AHB/APB prescalers + domain clock-disable bits) are plain storage; prescaler effects on peripheral timing are not modeled.
  • CIER/CIFR/CICR (RCC clock-interrupt block) are storage + W1C; the RCC IRQ itself is not wired to the NVIC.
  • CSR.RMVF is write-1-to-clear for the reset flags, matching RM0456.

Firmware that touches an undeclared window hits MemoryAccessViolation or stalls in a polling loop; see docs/getting_started_firmware.md.

What this catches (and what it cannot)

This target catches model regressions on the U5 boot path: PLL1/2/3 bring-up and ready-bit gating, RCC clock-enable gating (an unclocked peripheral reads 0 / drops writes), flash-latency sequencing, VOS/supply config, USART1 VCP bytes, GPIO output state, I2C device ACK/readback, SPI device frames, FDCAN internal-loopback ID/data, timer irq delivery, and CPU decode gaps — driven by three independent real firmware stacks (STM32CubeU5 HAL, upstream Zephyr, Arduino STM32 core). Because there is no bench part, it cannot catch a divergence from silicon that all three stacks happen to avoid, and no silicon-parity claim is made.

How to run

Run from the repo root.

# Rust io-smoke (builds firmware-stm32u575-demo, asserts "OK" on USART1)
labwired test --script examples/nucleo-u575zi/io-smoke.yaml

# Vendor CubeU5 HAL firmware (needs an STM32CubeU5 checkout; see
# examples/nucleo-u575zi/EXTERNAL_COMPONENTS.md)
make -C examples/nucleo-u575zi/board_firmware
labwired run --chip configs/chips/stm32u575.yaml \
  --firmware examples/nucleo-u575zi/board_firmware/build/u575_hal_smoke.elf \
  --max-steps 20000000
# → U575-HAL OK / BLINK 0 LD1=1

The hosted playground does not carry a U575 board id yet (the superproject's BOARDS array has no U575 entry). The example directory is the supported entry point: examples/nucleo-u575zi/README.md.