Hardware Abstraction Layer (HAL)
The HAL (hardware abstraction layer) is the set of TypeScript objects you use to talk to the board — each pin, bus, and built-in feature is an object, and Cuttlefish checks that you’re using them in ways the hardware actually supports. So a wrong pin assignment, a missing setup step, or two features fighting over the same pin is caught before the firmware reaches the board.
Overview
The HAL is organized into five areas:
| Area | What it covers |
|---|---|
| GPIO & Digital I/O | Pin modes, read/write, toggle, debounce, pin groups |
| Analog & PWM | ADC reads, PWM output, voltage conversion |
| Communication Buses | UART, I2C, SPI with typed device accessors |
| Hardware Events | Interrupts, async edge detection, callback management |
| Signal Utilities | Tone generation, pulse measurement, shift registers, RNG |
Compile-Time Directives
The HAL uses three compile-time functions that exist purely for code generation:
emit(text)
Injects raw C++ at the call site. The TypeScript never executes.
import { emit } from '@typecad/hal';
emit("PORTB |= (1 << PB5)");include(text)
Adds a C++ #include to the output. No-op during type-checking.
import { include } from '@typecad/hal';
include("<Wire.h>");board(path)
Resolves a board definition value at compile time.
import { board } from '@typecad/hal';
const resolution = board("peripherals.pwm.resolution");Pin Model
Pins are typed objects, not integer constants. Each board package exports named pin objects with known capabilities:
import { D13, A0, D3 } from '@typecad/board-arduino-uno';
const led = D13.asOutput(); // OutputPin — high(), low(), toggle(), write(), pwm(), tone()
const sensor = A0.asInput(); // InputPin — read(), readAnalog(), readVoltage(), onFalling()
const motor = D3.asOutput(); // OutputPin — also supports PWM on this pinThe type system switches to the right set of methods after you pick a mode — calling read() on an OutputPin is a compile error.
Timing and Utility Functions
The HAL provides timing functions that become their C++ equivalents at build time:
import { delay, millis, micros } from '@typecad/hal';
delay(1000); // Block for 1 second
const elapsed = millis(); // Milliseconds since boot
const us = micros(); // Microseconds since bootConstants
import { HIGH, LOW, OUTPUT, INPUT, INPUT_PULLUP, LED_BUILTIN } from '@typecad/hal';These map directly to their Arduino/AVR equivalents in the generated C++.
Getting Started
Start with GPIO & Digital I/O to learn pin basics, then explore Communication Buses for I2C/SPI/UART.
On This Page