Skip to main content

pamoja_hal/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3//! The bus layer for the pamoja SDK.
4//!
5//! Every part a node talks to sits on a bus: I2C for the dense breakout sensors, SPI
6//! for displays and radios, a GPIO line for a relay or a button, 1-Wire for a
7//! waterproof thermometer on a long cable. The drivers in
8//! [`pamoja-sensors`](https://docs.rs/pamoja-sensors) and
9//! [`pamoja-actuators`](https://docs.rs/pamoja-actuators) are written against traits
10//! rather than against a board, and this crate is where those traits come from and
11//! where the buses that implement them live:
12//!
13//! - [`i2c`], [`spi`], [`digital`], and [`delay`] are the `embedded-hal` 1.0 traits,
14//!   re-exported so a driver and the code that opens its bus name one thing. Any HAL
15//!   that implements them drives every pamoja part unchanged: `embassy-rp` on an
16//!   RP2040, `esp-hal` on an ESP32, the Linux backends below on a Raspberry Pi.
17//! - [`onewire`] is the bus `embedded-hal` does not define: the 1-Wire protocol a
18//!   DS18B20 speaks, bit-banged over any open-drain pin and a delay, with the reset
19//!   and presence handshake, the ROM commands, and the search that enumerates a bus.
20//! - [`script`] plays a part's side of a conversation: an I2C bus that checks each
21//!   transfer against a script and answers with the bytes a real part would send, a
22//!   pin that records what it was driven to, and a delay that records how long it was
23//!   asked to wait. A driver is tested against the datasheet's own sequence with
24//!   nothing plugged in.
25//! - `linux` (feature `linux`, Linux only) opens the kernel's `/dev/i2c-*`,
26//!   `/dev/spidev*`, and GPIO character devices as those same traits, so a gateway
27//!   reads a sensor with one call and no glue.
28//!
29//! # Examples
30//!
31//! A script stands in for a part that answers a one-byte register read: the chip id
32//! a BME280 returns for register `0xD0`.
33//!
34//! ```
35//! use pamoja_hal::i2c::I2c;
36//! use pamoja_hal::script::{I2cScript, I2cStep};
37//!
38//! let mut bus = I2cScript::new([I2cStep::write_read(0x76, [0xD0], [0x60])]);
39//! let mut id = [0u8; 1];
40//! bus.write_read(0x76, &[0xD0], &mut id)?;
41//! assert_eq!(id, [0x60]);
42//! assert!(bus.done());
43//! # Ok::<(), pamoja_hal::script::ScriptError>(())
44//! ```
45
46#[cfg(feature = "alloc")]
47extern crate alloc;
48
49pub use embedded_hal;
50pub use embedded_hal::{delay, digital, i2c, spi};
51
52#[cfg(all(feature = "linux", target_os = "linux"))]
53pub mod linux;
54pub mod onewire;
55#[cfg(feature = "alloc")]
56pub mod script;