Expand description
The bus layer for the pamoja SDK.
Every part a node talks to sits on a bus: I2C for the dense breakout sensors, SPI
for displays and radios, a GPIO line for a relay or a button, 1-Wire for a
waterproof thermometer on a long cable. The drivers in
pamoja-sensors and
pamoja-actuators are written against traits
rather than against a board, and this crate is where those traits come from and
where the buses that implement them live:
i2c,spi,digital, anddelayare theembedded-hal1.0 traits, re-exported so a driver and the code that opens its bus name one thing. Any HAL that implements them drives every pamoja part unchanged:embassy-rpon an RP2040,esp-halon an ESP32, the Linux backends below on a Raspberry Pi.onewireis the busembedded-haldoes not define: the 1-Wire protocol a DS18B20 speaks, bit-banged over any open-drain pin and a delay, with the reset and presence handshake, the ROM commands, and the search that enumerates a bus.scriptplays a part’s side of a conversation: an I2C bus that checks each transfer against a script and answers with the bytes a real part would send, a pin that records what it was driven to, and a delay that records how long it was asked to wait. A driver is tested against the datasheet’s own sequence with nothing plugged in.simis a part that is not there, answering from a register map in whatever order a driver reads and writes it, so a driver runs before the hardware arrives.linux(featurelinux, Linux only) opens the kernel’s/dev/i2c-*,/dev/spidev*, and GPIO character devices as those same traits, so a gateway reads a sensor with one call and no glue.bus(featurestd) is one I2C bus that a program and every driver on it share, over the kernel’s adapter, simulated parts, or a script, with a delay that sleeps only when real parts are on the other end. It is what a language binding hands a driver.port(featurestd) is one serial port shared the same way, over the kernel’s serial device, a looped line, a null-modem pair, a simulated device, or a script, with reads that wait for real bytes and only count the wait anywhere else.
§Examples
A script stands in for a BME280 answering the first thing a driver asks it: its chip
id, which register 0xD0 holds as 0x60 on every BME280 (datasheet section 5.4.1).
A driver that asked for anything else would be refused with the transfer the part
expected.
use pamoja_hal::i2c::I2c;
use pamoja_hal::script::{I2cScript, I2cStep};
const BME280: u8 = 0x76;
const CHIP_ID_REGISTER: u8 = 0xD0;
const BME280_CHIP_ID: u8 = 0x60;
let mut bus = I2cScript::new([I2cStep::write_read(
BME280,
[CHIP_ID_REGISTER],
[BME280_CHIP_ID],
)]);
let mut id = [0u8; 1];
bus.write_read(BME280, &[CHIP_ID_REGISTER], &mut id)?;
assert_eq!(id, [BME280_CHIP_ID]);
assert!(bus.done(), "every transfer the part expected has happened");Re-exports§
pub use embedded_hal;
Modules§
- bus
- One I2C bus, shared by a program and every driver on it.
- delay
- Delays.
- digital
- Digital I/O.
- i2c
- Blocking I2C API.
- linux
- Linux backends: the kernel’s I2C, SPI, and GPIO character devices as the bus traits.
- onewire
- The 1-Wire bus: one data line, a pull-up resistor, and strict timing.
- port
- One serial port, shared by a program and every driver on it.
- script
- Scripted buses: a part’s side of the conversation, for tests with nothing plugged in.
- sim
- A part that is not there, answering from a register map.
- spi
- Blocking SPI master mode traits.