Communication Buses
Four buses come ready to use as board singletons: UART0 for serial, USB0 for the USB console, and I2C0/SPI0 for devices. I2C0.device(0x44) and SPI0.device(PA4) hand you a working handle to one
device — an address, or a chip-select — with nothing else to configure. Constructing anything
yourself only matters for non-default facts: a different baud, a bigger receive buffer, a faster
bus.
The board singletons
Every bus the board has is exported, ready to use — numbered by instance when the board has more than one: UART0 and UART1, I2C0 and I2C1, SPI0 and SPI1, USB0. A board without a bus doesn't export its name — using it is a build error at import, not a runtime surprise.
Example first
import { UART0, I2C0, SPI0, PA4 } from '@typecad/hal';
UART0.writeLine('hello'); // the controller, default 115200
const dev = I2C0.device(0x44); // device at address 0x44
const id = dev.readReg(0xD0);
const flash = SPI0.device(PA4); // device behind chip-select PA4I2C
Talk to one device at one address. I2C0.device(address) hands back a working handle — register verbs callable immediately. (The handle is an I2CTarget instance, a name you'll rarely need to type.)
Example first
import { I2C0 } from '@typecad/hal';
const sensor = I2C0.device(0x44);
sensor.writeReg(0xF4, 0x27); // one-byte register write
const id = sensor.readReg(0xD0); // one-byte register read
sensor.updateReg(0xF5, 0x0F, 0x02); // read-modify-write
sensor.write([0x2C, 0x06]); // raw bytesAll methods
| Member | Description |
|---|---|
| I2C0.device(address) | Handle to the device at a 7-bit address |
| new I2CTarget(I2C0, address, opts?) | Explicit equivalent, only for a custom bus speed (hz) |
| writeReg(r, v) | One-byte register write |
| readReg(r) | One-byte register read |
| updateReg(r, mask, v) | Read-modify-write |
| write(bytes) | Raw bytes |
SPI
Talk to one device behind one chip-select. SPI0.device(cs, { hz, mode }) hands back a working handle, and the chip select is handled around every operation — there is no transaction API to get wrong.
Example first
import { SPI0, PA4 } from '@typecad/hal';
const display = SPI0.device(PA4, { hz: 10000000, mode: 0 });
const rx = new Uint8Array(4);
display.transceive([0x42, 0x00, 0x00, 0x00], rx); // full duplex
display.write([0xAA, 0xBB]); // write only
const id = display.readReg(0x00); // one-byte register readMultiple devices on one bus is the normal shape — one SPI0.device(...) per
chip-select.
All methods
| Member | Description |
|---|---|
| SPI0.device(cs, opts?) | Handle to the device behind one chip-select; hz and mode (0-3) set at creation |
| new SPITarget(SPI0, cs, opts?) | Explicit equivalent |
| transceive(tx, rx?) | Full-duplex transfer |
| write(tx) | Write-only transfer |
| readReg(r) | One-byte register read |
UART
A serial port. The UART0 / UART1 singletons work with default facts (115200); construct a UART only for a different baud or a bigger receive buffer.
Example first
import { UART, UART0 } from '@typecad/hal';
UART0.writeLine("hello"); // default 115200 — no construction
const gps = new UART(UART0, { baud: 9600, rxBufferBytes: 128 });
gps.write("$PMTK220,1000*2F\r\n"); // no newline appended
gps.writeLine("hello"); // with a newline
if (gps.available() > 0) { // bytes waiting
const b = gps.read(); // pop the oldest byte (-1 when empty)
const next = gps.peek(); // look without consuming
}All methods
| Member | Description |
|---|---|
| UART0 / UART1 … | Board singletons — ready to use, default 115200 |
| new UART(UART0, opts?) | Only for non-default facts: baud, rxBufferBytes (default 64) |
| write(v) / writeLine(v) | Send — v is text, a number, or a boolean |
| available() | Bytes waiting in the receive buffer |
| read() / peek() | Pop the oldest byte / look without consuming (byte or -1) |
USB
The USB serial port the host sees as a COM/tty device. USB0 is ready to use; early output written before the host opens the port is dropped by most hosts, so gate it on linked() or waitLinked().
Example first
import { USB0 } from '@typecad/hal';
if (!USB0.linked()) {
USB0.waitLinked(3000); // bounded wait — returns once the host opens the port
}
USB0.writeLine('hello, host');All methods
| Member | Description |
|---|---|
| USB0 | The USB serial port singleton, ready to use |
| write(v) / writeLine(v) | Send — v is text, a number, or a boolean |
| linked() / waitLinked(ms) | Host-opened check / bounded blocking wait |
| read() / available() | Input from the host |