$ show rp-rs/rp-hal
This repository provides Hardware Abstraction Layers (HAL) for Raspberry Pi RP2040 and RP235x microcontrollers. It consists of separate HAL crates for each microcontroller family (rp2040-hal, rp235x-hal), a shared common library (rp-hal-common), binary info generation for picotool (rp-binary-info), examples demonstrating peripheral usage, and on-target tests. The HALs expose peripherals like GPIO, UART, SPI, I2C, PWM, PIO, USB, and more through safe Rust abstractions using the typestate pattern and embedded-hal traits. The architecture follows embedded Rust best practices with clear separation of concerns. Each HAL crate can be used as a dependency in embedded projects. Key innovations include a bidirectional DMA abstraction for full-duplex communication, split UART reader/writer peripherals preventing data races, a glitchless clock configuration system with typestate safety, and a comprehensive PIO driver for programmable I/O. The project is actively maintained with regular commits, CI workflows for multiple platforms, and issue triage. While some code duplication exists between the HALs due to architectural differences, ongoing efforts rationalize shared code into rp-hal-common. The HALs are suitable for production use in embedded applications targeting these microcontrollers. Examples demonstrate real-world usage patterns like ADC with DMA, USB device implementation, multicore FIFO communication, and low-power dormant mode. Dependencies are current with the embedded Rust ecosystem (embedded-hal 1.0.0-beta, fugit, etc.), and the project avoids deprecated patterns. The binary info generation utility is a reusable component that could apply to any embedded Rust project requiring picotool compatibility.
The LLM identified 5 files worth highlighting for reuse:
Implements safe bidirectional DMA transfers for full-duplex peripherals like SPI. Uses two DMA channels with ping-pong buffering to enable simultaneous transmit and receive. Abstracts DMA channel setup, buffer management, and transfer handling into a reusable typestate API. Demonstrates non-obvious skill in managing DMA resources safely without runtime overhead.
Provides UART receive functionality as a separate consumable type that owns the UART peripheral. Combined with Writer, allows independent use of UART TX/RX without data races. Uses typestate to enforce proper configuration (e.g., baud rate set before use). Shows excellent embedded HAL design by splitting a peripheral into orthogonal, reusable components.
Configures system clocks (ROS, XOSC, PLL) with glitchless switching via typestate safety. Tracks clock validity at compile time, preventing invalid frequency transitions. Handles PLL locking and clock source selection with zero-cost abstractions. Reusable across projects needing reliable clock management on RP-series MCUs.
Abstracts the complex Programmable IO (PIO) peripheral into safe Rust types. Manages instruction memory allocation, program installation, and state machine lifecycle (uninitialized → stopped → running). Provides DMA integration via ReadTarget/WriteTarget for FIFOs. Exemplifies craftsmanship in making a powerful but intricate peripheral accessible and safe.
Generates ELF binary metadata sections compatible with Raspberry Pi picotool for debugging and inspection. Encodes program name, version, and build attributes into standardized sections. Self-contained utility with no HAL dependencies, making it reusable in any embedded Rust project targeting RP-series MCUs for picotool compatibility.