SolarOS

SolarOS 4.13.4 manual · api

Lua buses and expansion API

API overview · Python buses and expansion

solaros.buses

solaros.expansion

Named buses and expansion devices

solaros.buses discovers board-defined and runtime-created buses independently of the legacy single-board-bus and direct-pin service tables.

Bus tables contain id, name, protocol, origin, sharing, attached, detachable, ready, and lease_count, plus protocol-specific pins and configuration. create_spi requires host, sclk, mosi, and a one-to-four-element cs array. miso and max_transfer_size are optional. I2C bus tables include port, sda_pin, scl_pin, and speed_hz. Named I2C operations take and release a shared lease automatically; the legacy solaros.i2c table remains an i2c0 shortcut. OneWire bus tables include pin. Named OneWire operations take and release an exclusive lease automatically; solaros.onewire remains the direct-pin compatibility API. UART bus tables include port, tx_pin, rx_pin, and baud_rate; named UART I/O takes and releases an exclusive lease automatically.

create_i2c requires port, sda, and scl; optional speed_hz defaults to

  1. create_onewire requires pin. Both claim their approved runtime pins
  2. until remove(name).

create_uart requires port, tx, and rx; optional baud_rate defaults to

  1. Runtime descriptors are detachable and removable. Board descriptors
  2. whose signal pins are marked releasable are detachable but never removable; fixed-pin board descriptors reject detach. Attached buses own their hardware endpoint and signal pins, while protocol hardware starts on first lease.

create_midi requires tx and rx; optional baud_rate defaults to 31250. SolarOS selects an unused board-approved UART controller. The returned port is diagnostic backend information, not an input to the MIDI API.

local solaros = require("solaros")

local bus = solaros.buses.create_spi("spi1", {
    host = solaros.buses.SPI3_HOST,
    sclk = 1,
    mosi = 2,
    miso = 3,
    cs = {17},
})
print(bus.name, bus.origin)

local reply = solaros.buses.spi_xfer("spi1", "gpio17", "\x9f\x00\x00\x00")
print(#reply)
solaros.buses.remove("spi1")
local solaros = require("solaros")

local i2c1 = solaros.buses.create_i2c("i2c1", {
    port = 1,
    sda = 14,
    scl = 15,
    speed_hz = 100000,
})
print(#solaros.buses.i2c_scan(i2c1.name))
solaros.buses.remove(i2c1.name)

local onewire0 = solaros.buses.create_onewire("onewire0", {pin = 16})
print(#solaros.buses.onewire_scan(onewire0.name))
solaros.buses.remove(onewire0.name)

local uart1 = solaros.buses.create_uart("uart1", {
    port = 1,
    tx = 14,
    rx = 15,
    baud_rate = 115200,
})
solaros.buses.uart_write(uart1.name, "AT\r\n")
print(solaros.buses.uart_read(uart1.name, 64, 500))
solaros.buses.detach(uart1.name)
solaros.buses.attach(uart1.name)
solaros.buses.remove(uart1.name)
local solaros = require("solaros")

local bus = solaros.buses.get("i2c0")
print(bus.name, bus.speed_hz)
local addresses = solaros.buses.i2c_scan("i2c0")
solaros.buses.i2c_probe("i2c0", 0x3c)
local solaros = require("solaros")

local bus = solaros.buses.get("onewire0")
print(bus.name, bus.pin)
local devices = solaros.buses.onewire_scan("onewire0")
local reply = solaros.buses.onewire_xfer("onewire0", 9, "\xcc\x44")

solaros.expansion.drivers() lists compiled drivers with their categories. devices() lists active devices with name, driver, origin (board or runtime), ready, autostart, detachable, and normalized bindings. Each binding contains kind, role, target, value, and aux. attach(driver, name, bindings) and detach(name) mirror the shell lifecycle. Binding tables accept spi, cs (or ce), i2c, addr, alt_addr, uart, ps2, gpio, irq, reset (or rst), dc, busy, data, bck, din, rck, mclk, ws, dout, adc, pwm, count, keys, x, y, min, center, max, and deadzone. ps2 names an existing PS/2 bus; x and y name scalar streams; keys maps logical key names to GPIO numbers. cs requires spi; addr and alt_addr require i2c; unknown fields are rejected.

solaros.expansion.attach("pcd8544", "lcd0", {
    spi = "spi0",
    cs = 10,
    dc = 4,
    reset = 5,
})
print(#solaros.expansion.devices())
solaros.expansion.detach("lcd0")

NeoPixel set and fill update a buffer; call show once after a batch of changes. clear updates and transmits immediately.

solaros.expansion.attach("neopixel", "pixels0", {data = 1, count = 8})
solaros.neopixel.fill("pixels0", 0, 0, 8)
solaros.neopixel.set("pixels0", 3, 16, 0, 0)
solaros.neopixel.show("pixels0")

solaros.spi is a compatibility table that selects spi0 when present, otherwise the first registered named SPI bus. On a dynamic-only board its status().available value remains false until a bus is created. status() reports the selected bus pins, transfer limit, and configured chip-select slots. xfer(cs, data[, mode[, speed_hz]]) performs a full-duplex transaction. read(cs, length[, fill[, mode[, speed_hz]]]) and write(cs, data[, mode[, speed_hz]]) provide one-direction convenience forms. The cs argument accepts a configured slot name or its numeric GPIO. Lua data and return values are binary-safe strings. New code should address buses explicitly through solaros.buses.spi_*.

Quick reference

Use solaros.buses, solaros.expansion for buses and expansion. See man lua for runtime conventions and service availability.

Join us on: