Skip to main content

Crate pamoja_hal

Crate pamoja_hal 

Source
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, and delay are the embedded-hal 1.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-rp on an RP2040, esp-hal on an ESP32, the Linux backends below on a Raspberry Pi.
  • onewire is the bus embedded-hal does 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.
  • script plays 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.
  • sim is 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 (feature linux, 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 (feature std) 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 (feature std) 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.