Skip to content

hal::pio

Programmed digital I/O, not an addressed bus. Backends lower this small, portable instruction set; applications never provide native opcodes. This initial contract has one board-routed input and one output, explicit 32-bit FIFOs, and no interrupt, DMA, side-set or arbitrary instruction access.

struct Config {
pub frequency_hz: u32,
pub input: bool,
pub output: bool,
}

Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq

struct Instruction {
pub operation: Operation,
pub delay: u8,
}

Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq

References: Operation

enum Error {
Busy,
Invalid,
NoSpace,
NotConfigured,
WouldBlock,
Timeout,
Hardware,
Unsupported,
}

Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq

enum Operation {
Pull,
Push,
OutputBit,
InputBit,
SetOutput(bool),
WaitInput(bool),
SetCounter(u8),
Jump(u8),
JumpDecrement(u8),
Nop,
}

Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq

trait ProgrammableIo: Send {
fn configure(&mut self, machine: u8, program: &[Instruction], config: Config) -> Result<(), Error>
fn start(&mut self, machine: u8) -> Result<(), Error>
fn try_write(&mut self, machine: u8, word: u32) -> Result<(), Error>
fn try_read(&mut self, machine: u8) -> Result<u32, Error>
fn exchange(&mut self, machine: u8, word: u32, timeout_us: u32) -> Result<u32, Error>
fn cancel(&mut self, machine: u8) -> Result<(), Error>
fn reset(&mut self)
}

Exclusive owner of an engine and its board-routed pins. Machine indices are local to this owner, not globally transferable handles. Every method takes exclusive access; external synchronization belongs to the caller. Programs wrap from their last instruction to their first. Configure reserves program memory and a machine but leaves it stopped. Each routed pin can be used by only one configured machine, even for input.