Skip to content

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:

  1. Flash is at 0x0800_0000, not 0x0. The vector table and reset entry live at the flash base, unlike Series-1 EFR32 and the nRF parts.
  2. The USART register block shifted. Same flag semantics as Series 1 (STATUS reset 0x2040 = TXBL|TXIDLE, RXDATAV = bit 7), but STATUS moved to 0x18, TXDATA to 0x38, RXDATA to 0x24. The engine models this as the dedicated efr32s2 UART layout; the Series-1 efr32 layout 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 SP 0x2008_0000 (512 KiB SRAM)
  • USART1 enable (EN, CMD.TXEN) and TXBL-polled TX at the Series-2 offsets
  • console banner brd2709a: MG26 OK captured 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 direct memory_value check 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.

  • Example package: examples/brd2709a/ (runbook in its VALIDATION.md)
  • Nearest in-tree relatives: nrf54l15 (Cortex-M33, secure-alias peripheral map), mkw41z4 (vendor MCU onboarded without STM32 IP)