BRD2709A — Silicon Labs xG26-EK2709A Explorer Kit (EFR32MG26)
The BRD2709A carries an EFR32MG26B510F3200IM48-B: a Series-2 "Mighty Gecko" wireless SoC with a 78 MHz Cortex-M33 (ARMv8-M), 3200 KiB flash and 512 KiB SRAM, plus a 2.4 GHz radio (not modelled). This LabWired profile covers the MCU core and the VCOM console path.
Live status: see the support rubric and the chip conformance scoreboard. This target is L1 smoke — deterministic UART smoke passes; it is not silicon-diffed.
Two things make this part different from the EFR32 Series-1 chips, and both are places where a wrong profile fails silently rather than loudly:
- Flash is at
0x0800_0000, not0x0. The vector table and reset entry live at the flash base, unlike Series-1 EFR32 and the nRF parts. - The USART register block shifted. Same flag semantics as Series 1
(STATUS reset
0x2040= TXBL|TXIDLE, RXDATAV = bit 7), but STATUS moved to0x18, TXDATA to0x38, RXDATA to0x24. The engine models this as the dedicatedefr32s2UART layout; the Series-1efr32layout transmits nothing here.
There is no public SVD for the EFR32MG26 — Silicon Labs ships CMSIS headers
only (simplicity_sdk). Every register fact below is header-derived, and no
debug_schema descriptors exist for that reason.
Status at a glance
| Aspect | Status |
|---|---|
| Chip yaml | configs/chips/efr32mg26.yaml |
| System yaml | configs/systems/brd2709a.yaml |
| Reference firmware | crates/firmware-mg26-demo/ (bare-metal Rust, no SDK) |
| Example | examples/brd2709a/ |
| Validation | labwired test --script examples/brd2709a/uart-smoke.yaml + io-smoke.yaml (deterministic, in-repo) |
| Tier | L1 smoke — no silicon register diff; CMU/TIMER0 stubbed |
What is proven
A bare-metal Rust firmware, built for thumbv7m-none-eabi with no vendor
SDK, no CMSIS and no emlib, boots end to end:
- reset vector at flash
0x0800_0000; initial SP0x2008_0000(512 KiB SRAM) - USART1 enable (
EN,CMD.TXEN) and TXBL-polled TX at the Series-2 offsets - console banner
brd2709a: MG26 OKcaptured on the UART sink - GPIO PC08/PC09 (LED0/LED1) driven through the Series-2 port model —
MODEH pin-mode programming, DOUT writes, and DIN reads that report the
driven pin level back to firmware (asserted by
io-smoke.yaml, including a directmemory_valuecheck of the DOUT register)
The unsupported-instruction audit over the smoke ELF is clean (0 unknown Thumb-16/32 instructions over 200000 steps).
The physical board was identified over SWD (probe-rs via the on-board J-Link
OB, 1366:0105): Energy Micro DP part 0x1013, CPUID PARTNO = Cortex-M33. No
reset-state register capture has been taken — there is no silicon oracle.
Bench-proven (2026-08-20, J-Link OB 1366:0105:000440338937): the
custom UART XMODEM bootloader (firmware-mg26-bootloader) was SWD-burned
once, then the app-slot firmware-mg26-demo (linked at 0x08008000) was
sent over VCOM with bench_xmodem.py (knock LWBL, XMODEM-1K). Probe
readback matched the image; after reset the bootloader jumped (VTOR
0x08008000) and VCOM printed the full banner + IO lines.
Bench-proven (2026-08-18, J-Link OB 1366:0105:000440338937): the
sim-built firmware-mg26-demo ELF, flashed with probe-rs download, prints
the full banner + IO lines on the physical VCOM (115200 8N1, clean ASCII).
That one run pins three silicon facts the sim does not model: the CMU clock
gates (before CMU_CLKEN0.GPIO/CMU_CLKEN2.USART1 writes, probe reads of
USART1/GPIOC bus-FAULT; after, USART1 STATUS reads 0x2062 and GPIOC DOUT
0x300), the USART1→PB02 ROUTE programming, and the 19 MHz out-of-reset
EM01GRPA (HFRCO startup band) baud basis behind CLKDIV=2384. One honest
divergence the bench surfaced: silicon reads BTN0=0 BTN1=0 (PB00/PB01 left
in DISABLED mode, input buffer off), while the sim's board_io model drives
the DIN latch to the released-active-low level and prints BTN0=1 BTN1=1.
What is NOT proven
- GPIO pin-mux (ROUTE) and interrupts: the ROUTE registers and the EXTI/EM4 path live in the GPIO block head, outside the modelled per-port windows. WIREDAND open-source modes are approximated as push-pull.
- Clocks: CMU is a zero-read stub; nothing gates the simulated 78 MHz.
- Everything else on the die: TIMER0 (stub), MSC, WDOG, EMU, SMU, PRS, LDMA, the radio, USERDATA/DEVINFO pages — all unmapped by design.
- Interrupt-driven UART RX/TX (the smoke path is polled).
Pins (board label → GPIO)
| Board label | Pin | Direction | Notes |
|---|---|---|---|
| LED0 | PC08 | output | active-high |
| LED1 | PC09 | output | active-high |
| BTN0 | PB00 | input | active-low |
| BTN1 | PB01 | input | active-low |
| VCOM TX | PB02 | USART1 TX | on-board J-Link OB, 115200 8N1 |
| VCOM RX | PB03 | USART1 RX |
Expansion: mikroBUS socket + Qwiic connector (documented in UG594; not modelled, nothing wired by default).
Support matrix
| Peripheral | Status | Notes |
|---|---|---|
| Reset/boot | ✅ | vector table at 0x0800_0000, SP/PC sane |
| UART (USART1) | ✅ | Series-2 efr32s2 layout; polled TX proven by smoke |
| GPIO | ✅ | Series-2 port layout (DOUT/DIN/MODEL/MODEH); LED toggle + button read proven by io-smoke; ROUTE/EXTI not modelled |
| SysTick / NVIC | ⚠️ | declared, not exercised by the smoke |
| CMU | ⚠️ | explicit type: stub window; no clock tree |
| TIMER0 | ⚠️ | explicit type: stub window |
| USART0/2, EUSART0–3, I2C, MSC, radio | ❌ | not mapped |
What it catches vs bench
Catches: wrong flash base (a Series-1-style image at 0x0 faults at reset),
the Series-1-vs-Series-2 USART register shift (a Series-1 driver hangs polling
STATUS at 0x10), LED firmware that programs the wrong mode nibble or writes
the wrong data register (DIN never follows, and the io-smoke prints zeros),
and unmapped-peripheral accesses on the smoke path (loud bus faults, not zero
reads — CMU/TIMER0/ROUTE stubs are the deliberate exceptions, declared with
type: stub).
Bench cross-check (2026-08-18): the same ELF on the physical board produces the identical banner + IO line sequence on VCOM, and the silicon-required init it carries (CMU clock gates, PB02 route) is exactly the part the sim stubs out — so the two environments now agree line-for-line except the button nibble noted above (sim models the contact; silicon's disabled input buffer reads 0).
Does not catch: clock-tree misconfiguration (no CMU model), pin-mux/ROUTE errors (UART TX reaches the sink and LED pads move regardless of ROUTE programming), GPIO interrupt delivery, radio behaviour.
Browser / UART flashing
The EFR32MG26 has no ROM serial loader. Burn the LabWired UART bootloader
once over SWD, then the playground (and bench_xmodem.py) send an app-slot
.bin over the J-Link VCOM with XMODEM-CRC.
One-time SWD burn (J-Link OB 1366:0105):
cd core
cargo build -p firmware-mg26-bootloader --target thumbv7m-none-eabi --release
~/.labwired/bin/probe-rs download \
--chip EFR32MG26B510F3200IM48 \
target/thumbv7m-none-eabi/release/firmware-mg26-bootloader
Entry: send the 4-byte knock LWBL after reset, or hold BTN0 while
pressing RESET. The bootloader answers with LWBL ready then 'C'
(XMODEM-CRC). Apps must link at 0x08008000 (the bootloader owns the first
32 KiB). Hosted Arduino (silabs-arduino / xg26explorerkit) already does.
cargo build -p firmware-mg26-demo --target thumbv7m-none-eabi --release --features app-slot
arm-none-eabi-objcopy -O binary \
target/thumbv7m-none-eabi/release/firmware-mg26-demo /tmp/mg26-app.bin
python3 crates/firmware-mg26-bootloader/bench_xmodem.py \
--port /dev/cu.usbmodem0004403389371 /tmp/mg26-app.bin
How to run
CLI, from core/:
make -C examples/brd2709a # build firmware
cargo run -p labwired-cli -- test --script examples/brd2709a/uart-smoke.yaml
cargo run -p labwired-cli -- test --script examples/brd2709a/io-smoke.yaml
Expected UART output: brd2709a: MG26 OK, then the IO lines
(MG26-IO, PC08=1 PC09=1, PC08=0 PC09=0, BTN0=1 BTN1=1, MG26-IO DONE).
On silicon the same ELF prints BTN0=0 BTN1=0 because PB00/PB01 stay in
DISABLED mode (input buffer off); VALIDATION.md records that split.
Related systems & examples
- Example package:
examples/brd2709a/(runbook in itsVALIDATION.md) - Nearest in-tree relatives:
nrf54l15(Cortex-M33, secure-alias peripheral map),mkw41z4(vendor MCU onboarded without STM32 IP)