pamoja-gpio
On-board bus addressing and pin logic for pamoja: I2C 7-bit and 10-bit address-frame encoding (NXP UM10204) with reserved-range checks, the four SPI clock modes from CPOL/CPHA, and a GPIO pin model with active-high/active-low logical levels, no_std and allocation-free. The addressing-and-mode half ahead of the GPIO/I2C/SPI driver.
The same capability in every language
| 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 |
On-board bus addressing and pin logic for the pamoja SDK.
Before a node reaches any network it has to talk to the chips wired to the board it sits on. Three interfaces cover almost everything cheap hardware uses: I2C for the dense breakout sensors (a BME280, an INA226, an MPU9250, an SSD1306 screen), SPI for displays, SD cards, and LoRa radios, and plain GPIO pins for the relays, valves, buttons, and motion sensors that switch a single line. Each carries a small, exact piece of logic that is pure arithmetic with no hardware attached, and getting it wrong is a classic field bug: the wrong I2C address byte, the wrong SPI clock mode, or an active-low relay driven as if it were active-high.
This crate is that logic, with no pins toggled and no allocation:
i2c- I2C addressing per the NXP I2C-bus specification (UM10204): the 7-bit address byte(address << 1) | r/w, the two-byte11110xxframe for a 10-bit address, and the reserved ranges (0x00..=0x07and0x78..=0x7F) that leave0x08..=0x77for real devices, so a bad address is caught before it reaches the bus.spi- the four SPI clockModes as the(CPOL, CPHA)pair every datasheet quotes, plus bit order, so "mode 3, MSB first" is a checked value rather than two booleans a caller can transpose.pin- the GPIO pin model: physicalLevel, input pull and output drive, the interruptEdge, and an active-high/active-lowPolaritythat maps a logical "asserted" onto the physical level, so an active-low button or relay is handled by the type rather than by remembering to invert.
Everything is exact integer work over Copy values, so the same logic runs on the
smallest microcontroller driving the bus. Clocking the bytes and toggling the lines
themselves arrives with the hardware-I/O layer; this is the addressing-and-mode half
ahead of it.
Examples
use ;
use ;
use Mode;
// A DS3231 real-time clock answers at 7-bit address 0x68; its read frame is one byte.
let rtc = seven_bit?;
let mut frame = ;
let n = rtc.write_frame?;
assert_eq!; // (0x68 << 1) | 1
// SPI clock mode 0 is the (CPOL, CPHA) pair (false, false), as a datasheet quotes it.
assert_eq!;
// An active-low relay is energised by driving its pin low.
assert_eq!;
License
MIT - part of the pamoja workspace: one memory-safe Rust core with bindings for every language.