status-led 0.5.1

no_std monochrome status LED abstraction with optional PWM gamma correction and breathing effect.
Documentation

status-led

CI crates.io docs.rs

no_std monochrome status LED abstraction for the embassy ecosystem.

  • PolarityActiveHigh / ActiveLow chosen at construction time via [PolarityMode].
  • Reads hardware directly — no internal state cache; is_on() reads the ODR register and applies polarity conversion.
  • Optional PWM — CIE L* perceptual brightness via PwmLed with a compact 32-byte lookup table + shift-add interpolation (zero multiply/divide).
  • Optional breathing — Sinusoidal brightness animation via Breath (CORDIC algorithm — zero float/mul/large tables) and BreathLed wrapper.
  • Zero mandatory dependencies — only embedded-hal 1.0.

Usage

use embassy_stm32::gpio::{Output, Level, Speed};
use status_led::{Led, PolarityMode};

let pin = Output::new(p.PA5, Level::High, Speed::Low);
let mut led = Led::from_pin(pin, PolarityMode::ActiveLow);

led.on().unwrap();
led.off().unwrap();

PWM with gamma correction

Enable the pwm feature:

status-led = { version = "0.4", features = ["pwm"] }
use status_led::pwm::{GammaCorrection, PwmLed};
use status_led::PolarityMode;

let mut led = PwmLed::new(ch, GammaCorrection::CieLStar, PolarityMode::ActiveLow).unwrap();
led.set_brightness(128).unwrap(); // ~50% perceived brightness

Breathing effect

Enable the breath feature:

status-led = { version = "0.5", features = ["breath"] }

Breath generates a stream of brightness values (0–255) following a sinusoidal pattern. Combine with BreathLed for a ready-to-use PWM LED wrapper:

use status_led::breath::{Breath, BreathLed};
use status_led::pwm::GammaCorrection;
use status_led::PolarityMode;

// Manual breath loop with Breath
let mut breath = Breath::new(12_800, 50);
loop {
    led.set_brightness(breath.next()).unwrap();
    Timer::after_millis(50).await;
}

// Or use BreathLed for a single-call wrapper
let mut led = BreathLed::new(
    ch,
    GammaCorrection::CieLStar,
    PolarityMode::ActiveLow,
    12_800,
    50,
).unwrap();

loop {
    led.breath().unwrap();
    Timer::after_millis(50).await;
}

### Runtime polarity

When the polarity is read from configuration at runtime:

```rust
use status_led::{Led, PolarityMode};

let pol = if config.active_low {
    PolarityMode::ActiveLow
} else {
    PolarityMode::ActiveHigh
};
let mut led = Led::new(pin, pol).unwrap();
led.toggle().unwrap();

Features

Feature Description Extra deps
(none) GPIO LED with runtime polarity
pwm PwmLed with CIE L* perceptual brightness, zero runtime multiply/divide
breath Breath + BreathLed — CORDIC sinusoidal breathing effect — (enables pwm)
defmt defmt::Format impls for all public types defmt

License

Licensed under either of Apache License 2.0 or MIT license at your option.