STM32F411CEU6 — WeAct "Black Pill"
The STM32F411CEU6 (Arm Cortex-M4F, up to 100 MHz, 512 KiB flash, 128 KiB SRAM, UFQFPN48) is the MCU on the widely-cloned WeAct "Black Pill" board. It is the same silicon row as the STM32F401 already in the fleet — RM0383 vs RM0368, identical peripheral bases and IRQ numbers — with three differences that matter to the model:
| STM32F401CDU6 | STM32F411CEU6 | |
|---|---|---|
| Flash | 384 KiB | 512 KiB |
| SRAM | 96 KiB | 128 KiB |
| Extra peripheral | — | SPI5 @ 0x4001_5000, IRQ 85 |
| Max SYSCLK | 84 MHz | 100 MHz (not representable, see below) |
Because the RCC register offsets (AHB1ENR 0x30, APB1ENR 0x40, APB2ENR
0x44) are byte-identical to the shipped stm32f4 profile — verified against
the F411 SVD directly, not assumed — onboarding required no new peripheral
model and no new RCC layout. SPI5 reuses the existing classic-SPI IP.
Fidelity: SIM-DERIVED. LabWired has no F411 bench part. Every value comes from ST's CMSIS device header (
stm32f411xe.h) and the vendored modm-io F411 SVD. There is noreg_oracle, no MMIO diff, and no silicon UART parity check. Promote the tier only when a real F411 is diffed over SWD.
Status at a glance
Live status: this table is a hand-maintained snapshot. The authoritative, auto-generated views are the chip conformance scoreboard and the tier-1 matrix.
| Aspect | Status |
|---|---|
| Chip yaml | configs/chips/stm32f411ceu6.yaml |
| System yaml | configs/systems/stm32f411ceu6-blackpill.yaml |
| Example | examples/stm32f411ceu6-blackpill/ |
| Fixture firmware | examples/tier1-fixture/stm32f411/ |
| Vendored SVD | tests/fixtures/real_world/stm32f411.svd (modm-io, 56 IRQs) |
| Validation | tier-1 fixture: clock/gpio/timer/i2c/spi/adc/wdt/rtc PASS + UART via TIER1 done; io-smoke asserts the transcript; chip_conformance estate OK |
| Tier | sim-validated — no silicon diff |
| Core type | Arm Cortex-M4F (thumbv7em) |
Modelled peripherals
- RCC (
stm32f4) — HSI/HSE ready gating, source-ready-gated SYSCLK switch, AHB1/APB1/APB2 enable round-trip. - GPIO ports A, B, C, D, E, H (
stm32v2) — MODER/OTYPER/OSPEEDR/PUPDR/ IDR/ODR/BSRR, with SWD (PA13/14/15) and JTAG (PB3/PB4) reset defaults. There is no GPIOF/GPIOG: the AHB1ENR bit set is 0,1,2,3,4,7 and the gap at 5/6 is real silicon, not an omission. - USART1/2/6 —
stm32f1register layout (SR @0x00, DR @0x04), which is what F4 silicon actually implements. USART2 is the fixture console. - I2C1/2/3 — legacy I2C IP with a real transaction engine (START→SB, address phase, NACK→AF).
- SPI1/2/3/4/5 — classic SPI (
cr1_mask 0xEFFF), cycle-counted transfers. - TIM1/2/3/4/5/9/10/11 — TIM2 and TIM5 are the 32-bit instances.
- ADC1, IWDG (0x5555 key protection), RTC (calendar, WPR unlock),
EXTI, SysTick, PWR (
stm32f4), FLASH interface (stm32f4).
Known omissions and honest caveats
DMA1/DMA2 are stubs. The F4 DMA is a stream controller; the only DMA IP
modelled in the engine is the F1/L4 channel layout. Declaring dma1 with that
model would claim a register map that does not match the silicon, so the
windows are mapped and inert instead. dma is na in the tier-1 matrix, not
pass.
Clock gating is partial. Only TIM2, ADC1, SPI1 and SPI5 carry a clock:
gate — the four the tier-1 fixture proves. Every other block responds without
its RCC enable bit set, which is not silicon behaviour. This is the same gap the
F401 descriptors carry; the verified enable bits needed to close it are listed
in the chip yaml so the next person does not have to re-derive them.
DBGMCU IDCODE is not shipped. The F411 DEV_ID/REV_ID appears in neither
the SVD nor the CMSIS header — it needs a part on SWD. dbg is a stub with no
IDCODE and no value was invented. F401CDU6's 0x10016433 is F401's; copying
it would make probe-identify silently wrong.
The Black Pill LED/button pinout is unverified. LED PC13 (active-low) and button PA0 (active-high) are carried over from the F401 Black Pill. That is a board-level fact no chip source can settle and no board was in hand.
Max SYSCLK is documentation only. 100 MHz (vs F401's 84) is unrepresentable
in the current schema: the stm32f4 RCC model stores CR/CFGR/PLLCFGR as gated
bit-fields and derives no frequency. Do not read a timing claim into the model.
SPI5EN has a single source. RCC_APB2ENR bit 20 comes from
stm32f411xe.h; the string SPI5EN does not occur in either public F411 SVD,
so it is cross-checkable against nothing. The tier-1 fixture exercises it (gate
off → CR1 write dropped; gate on → transfer completes) so it is at least
executable rather than an unchecked constant.
Also not modelled: USB OTG FS, SDIO, CRC, SYSCFG, WWDG and the I2S extension windows are mapped as stubs.
A note on the SVD
Two public F411 SVDs exist and only one is usable as a gate. The
cmsis-svd/cmsis-svd-data file declares just 34 interrupts and omits USART1/2/6,
TIM4, TIM5, every DMA stream and SPI5 — a coverage scan against it would pass
while verifying nothing about any of them. The vendored file is
modm-io/cmsis-svd-stm32 (47 peripherals, 56 interrupts up to 85). See
tests/fixtures/real_world/README.md.
Run it
# raw-register peripheral self-tests
labwired run --chip configs/chips/stm32f411ceu6.yaml \
--firmware tests/fixtures/tier1/stm32f411.elf --max-steps 5000000
# → TIER1 clock PASS … TIER1 rtc PASS … TIER1 done
# the committed smoke (same blob, with assertions)
cargo run -q -p labwired-cli -- test \
--script examples/stm32f411ceu6-blackpill/io-smoke.yaml \
--output-dir out/stm32f411ceu6-blackpill/io-smoke --no-uart-stdout