MCU HAL
Flint’s MCU-facing standard library lives under micro/*.
The long-term goal is a broad, portable hardware abstraction layer that lets the same Flint source move between boards and chips with minimal rewriting. The current implementation is narrower than that vision, so this chapter only documents what is actually present in the repository today.
Implemented Today
These micro modules have real RP2040-backed APIs and working examples:
| Module | Status | What it provides |
|---|---|---|
micro/gpio | Implemented | Output GPIO setup, toggle, set high, set low, builtin LED lookup |
micro/pwm | Implemented | PWM output setup and duty-cycle updates |
micro/uart | Implemented | UART0 initialization and byte-by-byte TX output |
micro/gpio
micro/gpio is the current foundation for board bring-up and LED examples.
Available surface today:
gpio.output(pin)returns anOutputPingpio.builtin_led()returnsOption<OutputPin>OutputPin.pin()OutputPin.toggle()OutputPin.set_high()OutputPin.set_low()
Example:
use micro/gpio
use time/delay
fn main() {
let builtin_led = gpio.builtin_led()
if builtin_led.is_none() {
return
}
if let Option.Some(led) = builtin_led {
loop {
led.toggle()
delay.millis(500)
}
}
}
builtin_led() is intentionally optional because not every board has a directly usable onboard LED.
micro/pwm
micro/pwm builds on a resolved GPIO pin and configures it for PWM output.
Available surface today:
pwm.output(pin, top)returns aPwmPinPwmPin.set_duty(duty)
Example:
use micro/gpio
use micro/pwm
use time/delay
fn main() {
let builtin_led = gpio.builtin_led()
if builtin_led.is_none() {
return
}
if let Option.Some(pin) = builtin_led {
let led = pwm.output(pin.pin(), 1000)
loop {
mut duty = 0
while duty < 1000 {
led.set_duty(duty)
duty = duty + 10
delay.millis(5)
}
while duty > 0 {
led.set_duty(duty)
duty = duty - 10
delay.millis(5)
}
}
}
}
The current implementation is tuned for RP2040 PWM slices and channels.
micro/uart
micro/uart currently exposes a small UART0 transmit path for debugging and bring-up.
Available surface today:
uart.init()uart.write_byte(byte)
Example:
use micro/uart
use time/delay
fn write_hello() {
uart.write_byte(72)
uart.write_byte(105)
uart.write_byte(10)
}
fn main() {
uart.init()
loop {
write_hello()
delay.millis(1000)
}
}
Right now this is intentionally small and practical: enough to get serial output on RP2040 without needing an external runtime or SDK.
Present But Not Implemented Yet
These module files already exist in stdlib/micro, but they are still placeholders at the moment:
micro/adcmicro/i2cmicro/interruptmicro/spimicro/systemmicro/timer
They are part of the intended HAL surface, but they should not be treated as available APIs yet.
Scope Today
The honest current picture is:
- GPIO is usable.
- PWM is usable.
- UART TX is usable.
- The rest of the MCU HAL surface is still being filled in.
That narrower surface is enough for real RP2040 bring-up work, and it gives the language a concrete place to prove out its embedded model before the broader HAL is expanded.