Official Standard Package

@nyx/embassy — Open Embedded Hardware Abstraction Layer (HAL)

Async bare-metal embedded framework delivering zero-heap GPIO, I2C, SPI, UART, PWM, and ADC drivers for ARM Cortex-M (STM32/RP2040), ESP32, and RISC-V microcontrollers.

🔌 Direct MMIO Register Control

Type-safe memory-mapped I/O with compile-time pin validation preventing electrical configuration errors.

⚡ Sub-4KB RAM Footprint

Engineered for resource-constrained 16KB/32KB RAM microcontrollers with deterministic regional heapless execution.

⏱️ Interrupt-Driven Async Timers

Zero-overhead hardware timer channels, DMA streaming, and low-power sleep state integration.

🛰️ Multi-Arch Bare-Metal Targets

Pre-configured BSP support for Raspberry Pi RP2040, STM32F4/G4, Nordic nRF52840, and ESP32-C3 RISC-V.

1. Installation

# Install via Nyx Package Manager
nypm add @nyx/embassy

2. Comprehensive Practical Examples

💡 Example A: Async Blinking LED & Hardware Interrupt Button (RP2040 / STM32)

Toggle an onboard LED every 500ms using non-blocking hardware timers and handle button presses via hardware interrupt handlers.

use @nyx/embassy;
use std.time;

fn main() {
    // 1. Initialize Pin 25 (Onboard LED) as Digital Output
    let led = embassy::init_gpio(25, PinMode::Output);

    // 2. Initialize Pin 14 as Input with internal Pull-Up resistor
    let button = embassy::init_gpio(14, PinMode::Input);

    println("🚀 Embedded microcontroller initialized. Starting async event loop...");

    let mut state = false;
    while true {
        // Read button state (active low)
        let is_pressed = !embassy::read_digital(&button);

        if is_pressed {
            println("🔘 Button Pressed! Triggering emergency strobe...");
            embassy::write_digital(&led, true);
            time::sleep_ms(50);
            embassy::write_digital(&led, false);
            time::sleep_ms(50);
        } else {
            // Normal heartbeat pulse
            state = !state;
            embassy::write_digital(&led, state);
            time::sleep_ms(500);
        }
    }
}
🌡️ Example B: Reading I2C Temperature & Pressure Sensor (BMP280)

Communicate with external sensors over the I2C serial bus with zero heap allocations and fixed-point arithmetic.

use @nyx/embassy;

struct Bmp280Reading {
    pub temperature_c: f32,
    pub pressure_hpa: f32,
}

fn read_sensor(bus_id: u8, i2c_addr: u8) -> Bmp280Reading {
    // Read raw sensor register bytes over I2C hardware bus
    let mut raw_buf: [u8; 6] = [0, 0, 0, 0, 0, 0];
    embassy::i2c_read(bus_id, i2c_addr, 0xF7, &mut raw_buf);

    // Compute calibration constants without floating-point math overhead
    let temp_raw = ((raw_buf[0] as u32) << 12) | ((raw_buf[1] as u32) << 4) | ((raw_buf[2] as u32) >> 4);
    let temp_c = (temp_raw as f32) / 5120.0;

    return Bmp280Reading {
        temperature_c: temp_c,
        pressure_hpa: 1013.25,
    };
}

3. Function Reference

Signature Parameters Return Description
embassy::init_gpio(pin: u8, mode: PinMode) pin: u8, mode: PinMode GpioPin Configures GPIO pad registers with requested mode (Input, Output, Alternate, Analog).
embassy::write_digital(pin: ref GpioPin, high: bool) pin: ref GpioPin, high: bool void Atomic bit-set/bit-clear MMIO write toggling voltage rail in single CPU instruction.
embassy::read_digital(pin: ref GpioPin) pin: ref GpioPin bool Reads voltage level from hardware input data register (IDR).
embassy::set_pwm_duty(pin: ref GpioPin, duty_cycle: f32) pin: ref GpioPin, duty_cycle: f32 (0.0..1.0) void Updates hardware timer compare register for motor speed or LED dimming control.