BERGSONNE

Onboard LED

Every Core has one onboard LED on a dedicated pin — the simplest way to see firmware is alive. It’s really just a GPIO, so you can drive it at whichever level suits you: the core_* helpers, or the raw ll_gpio writes underneath. Use the Core / HAL / LL toggle at the top of the sidebar to switch.

Overview

The onboard LED is wired to a dedicated GPIO on every Core, auto-configured by core_init() — no pad to assign. How you drive it depends on the layer:

Core — header-only helpers (core_led_*): on / off / toggle plus blink and heartbeat patterns. The everyday path, and what Studio emits.

It’s also the SDK’s failure indicator: the fault handler blinks SOS on it.

On, off, toggle

The direct controls. toggle is non-blocking — good from an event handler that already fires at the rate you want:

#include "core.h"

  core_led_on();       // light it
  core_led_off();      // and off
  core_led_toggle();   // flip — no delay

Patterns

Two timed helpers. core_led_blink blinks a fixed number of times and blocks; core_led_heartbeat toggles + delays once per call, for a main-loop “alive” indicator:

core_led_blink(3, 100, 100);   // 3 quick blinks, then return

  while (1) {
      do_work();
      core_led_heartbeat(500);   // ~1 Hz idle blink
  }
SOS for the unrecoverable
core_led_sos() blinks SOS forever and never returns — the fault handler already calls it for you.

Cross-architecture support

The onboard LED is part of every Core’s baseline (and its GPIO underpinning is verified everywhere):

●L0M0+●L4M4●W5M33●H5M33WCH (RISC-V) · Nordic (nRF54) — in development

See the implementation status for the full matrix.

Known gaps

What the SDK itself lists as missing here, straight from the header:

lowDSLNo DSL access to SOS

core_led_sos is `__attribute__((noreturn))` so it can't be exposed safely — DSL programs that "call SOS" would deadlock the worker. Reserved for fault-handler escape-to-C use.

lowC APINo PWM brightness / color

The onboard LED is hard-wired as a digital push-pull output. No PWM dimming wrapper, no RGB/RGBW support (tiles with addressable LEDs use Disp.RGBW or similar, not core_led).

From the @studio unsupported notes in core_led.h — tiles@6af026f.

API reference

Default-instance · Tier 2
void core_led_on(void);
Turn the onboard LED on. Simplest possible light control — useful alongside blink/heartbeat when the user wants explicit on/off state rather than a timed pattern.
void core_led_off(void);
Turn the onboard LED off.
void core_led_toggle(void);
Flip the onboard LED's current state. Non-blocking — no delay. Good for driving the LED from an event handler that fires at a rate you've already chosen (e.g., a pad-edge ISR on a button).
void core_led_blink(int n, int on_ms, int off_ms);
Blink the LED n times. Each cycle turns the LED on for on_ms milliseconds and off for off_ms milliseconds. Blocking — returns after the last off period. A short on_ms (under 50 ms) is the on-time at 3.3 V: at lower supply voltages it is lengthened so the blink looks as bright (the off-time shrinks to keep the rhythm). See core_led_heartbeat().
void core_led_heartbeat(int period_ms, int on_ms);
Start a free-running, asymmetric heartbeat on the onboard LED. Set it up once (e.g. at startup) and it runs on its own — the LED turns on for on_ms, off for the rest of period_ms, repeating forever. Serviced from the 1 ms SysTick interrupt, so it does NOT block your main loop the way a toggle-and-delay would: the loop stays free for tile reads and logic. Call again at any time to change the rhythm; pass period_ms = 0 to stop the heartbeat (the LED is left off). on_ms is clamped to period_ms. Brightness holds across the supply: a short on_ms (under 50 ms, e.g. a 2 ms blip) is the on-time at 3.3 V, and is lengthened as VDD drops (about 32 ms at 1.8 V), because the LED carries far less current there and the eye adds up the light of a short flash. VDD is read through VREFINT when the heartbeat is set (at most once a minute) on the L0, L4 and W5; the H5 uses the on-time as given. Examples: heartbeat(1000, 2) — a 1 Hz 2 ms blip, the same brightness at any VDD. heartbeat(1000, 100) — a 1 Hz "blip": 100 ms on, 900 ms off. heartbeat(500, 250) — a steady 1 Hz, 50%-duty pulse. Defined in core_led.c (not header-only) because it owns persistent state shared with the SysTick handler.
Lower-level · Tier 1
void core_led_init(void);
Enable the GPIO clock and configure the LED pin as a push-pull output. Call once after core_init(). The LED starts in the off state.
void core_led_sos(void);
Blink the SOS pattern (3 short, 3 long, 3 short) in an infinite loop. Use for unrecoverable errors. This function never returns.

Generated from core_led.h — tiles@f356b04.