HAL and Micro Library
The micro/* packages are Flint’s cross-chip peripheral APIs. They provide a stable, typed interface to hardware without exposing registers, memory-mapped IO addresses, or vendor-specific SDK calls.
The Four Layers
Flint’s hardware support is organized into four layers:
┌─────────────────────────────────────────────┐
│ Application Code │
├─────────────────────────────────────────────┤
│ micro/* board/* │ ← What you use
├─────────────────────────────────────────────┤
│ hal/* │ ← Target-selected implementation
└─────────────────────────────────────────────┘
| Package | What it is |
|---|---|
hal/* | Target-selected runtime, boot/startup, peripheral implementation. Internal. |
micro/* | Cross-chip peripheral interfaces. This is what you import. |
board/* | Board pin maps, default clocks, convenience constructors. |
| Application | Your code. |
You import micro/* and board/*. You do not import hal/* directly.
Startup
When your main runs, the target hal/* package has already:
- Released resets
- Brought up the clock tree and PLLs
- Configured the watchdog
- Initialized the timer/timebase
- Configured XIP/flash for normal operation
You do not write startup code. You do not call SystemInit(). You write application code.
Builder-Style APIs
Peripherals with many options use builder-style initialization:
use micro/i2c
let mut bus = i2c.bus(0)
.sda(gpio.pin(4))
.scl(gpio.pin(5))
.freq(400_000)
.init()?
Builder methods shape configuration. The terminal init() (or open(), attach()) is the one fallible step. Once initialized, steady-state operations are infallible:
bus.write(0x68, data)? // fallible: I2C can NACK
bus.flush()? // fallible: flush can timeout
led.high() // infallible: GPIO state change always works
led.low() // infallible
Capability Discovery
Optional features are exposed through Option<T>. Use standard control flow to adapt:
use board/pico
use micro/dma
if pico.capabilities().dma_channels > 0 {
if let Some(mut ch) = dma.channel(0) {
ch.start_transfer()?
}
}
Because the selected target and board are known at compile time, constant-folding removes dead branches for unsupported capabilities.
What Is Available
Required:
- GPIO: digital I/O
- UART: serial communication
- ADC: analog-to-digital conversion
- PWM: pulse-width modulation
- I2C and SPI: bus protocols
- DMA: direct memory access
- PIO: RP2040 programmable IO state machines
micro/cpu: CPU hints (WFI, breakpoint, spin-loop)micro/multicore: secondary core launch (RP2040)- USB device (CDC, HID, MSC)
- XIP/SPI flash access
- SD card over SPI
- FAT filesystem
- Interrupt registration