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:

AreaWhat it covers
GPIO & Digital I/OPin modes, read/write, toggle, debounce, pin groups
Analog & PWMADC reads, PWM output, voltage conversion
Communication BusesUART, I2C, SPI with typed device accessors
Hardware EventsInterrupts, async edge detection, callback management
Signal UtilitiesTone 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 pin

The 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 boot

Constants

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.