pamoja for TypeScript - v0.1.17
    Preparing search index...

    Module @pamoja/gpio

    Ergonomic facade over the generated on-board bus binding.

    Before a node reaches any network it talks to the chips wired to its own board. Three interfaces cover almost everything cheap hardware uses, and each carries one small piece of logic that is a classic field bug when it is wrong: the I2C address byte, the SPI clock mode, and whether a relay is active high or active low.

    @pamoja/gpio

    I2C address frames with reserved-range checks, the four SPI clock modes, and active-high or active-low pins. One capability of pamoja, one memory-safe Rust core with bindings for TypeScript, Python, and C#.

    API reference read the guide documentation

    npm install @pamoja/gpio
    

    This pulls in @pamoja/native, the compiled engine. npm install pamoja is the whole framework in one package.

    The test that runs in CI, spliced here as it ran.

    From bindings/node/guides/gpio.ts:

    import { PinEdge, PinLevel, PinPolarity, i2c, pin, spi } from '@pamoja/gpio'

    // A BME280 answers at the 7-bit address its datasheet gives. That is not the byte that
    // goes on the wire: the address shifts up one and the low bit says whether this
    // transaction reads or writes, which is the step easiest to get wrong by hand.
    const BME280 = 0x76
    const hex = (byte: number) => `0x${byte.toString(16).toUpperCase()}`
    console.log(`write to ${hex(i2c.addressFrame(BME280)[0]!)}`)
    console.log(`read from ${hex(i2c.addressFrame(BME280, { read: true })[0]!)}`)

    // The I2C specification keeps two ranges of addresses for itself, so a part answering in
    // either is a wiring mistake rather than a device.
    console.log(
    `${hex(BME280)} reserved: ${i2c.isReserved(BME280)}, ` +
    `${hex(i2c.RESERVED_FROM)} reserved: ${i2c.isReserved(i2c.RESERVED_FROM)}`,
    )

    // A 10-bit address spends a reserved prefix over two bytes rather than one, so a bus
    // driver has to send a different number of bytes depending on the address it holds.
    // This is the worked example UM10204 itself prints.
    const TEN_BIT_DEVICE = 0x2a5
    console.log(`a 10-bit address takes ${i2c.frameLen(TEN_BIT_DEVICE, true)} bytes`)

    // Datasheets quote clock polarity and phase as one mode number. Mode 3 idles the clock
    // high and samples on the trailing edge.
    const clock = spi.clockFor(3)
    console.log(`spi mode 3: idles high ${clock.cpol}, samples on the trailing edge ${clock.cpha}`)

    // A relay board sold as active low energises when its pin is driven low. The polarity
    // carries that inversion, so no call site has to remember which way round it is.
    const energise = pin.levelFor(PinPolarity.ActiveLow, true)
    console.log(`to energise an active-low relay, drive the pin ${energise}`)

    // Releasing it drives the line back high, an edge a falling trigger ignores.
    const rising = pin.triggers(PinEdge.Rising, PinLevel.Low, PinLevel.High)
    const falling = pin.triggers(PinEdge.Falling, PinLevel.Low, PinLevel.High)
    console.log(`release seen by a rising trigger: ${rising}, by a falling trigger: ${falling}`)
    Language Package Reference
    Rust pamoja-gpio reference, docs.rs, install
    TypeScript @pamoja/gpio reference, install
    Python pamoja-gpio reference, install
    C# Pamoja.Gpio reference, install

    MIT

    SpiClock
    PinEdge
    PinLevel
    PinPolarity
    i2c
    pin
    PinEdge
    PinLevel
    PinPolarity
    spi