USB
Plug a Core into a computer and it shows up as a serial port — no drivers, no crystal. core_usb is a USB CDC device with printf and buffered RX, plus a vendor HID path for raw 64-byte reports. It sits on hal_usb_cdc. Use the Core / HAL / LL toggle at the top of the sidebar to switch.
Overview
USB device is available on the Cores with a USB peripheral — Core.ST.L4 and Core.ST.H5. It runs crystal-less: the HSI48 oscillator plus the Clock Recovery System (synced to USB SOF) keeps the clock USB-accurate, so no external part is needed.
/dev/tty.usbmodem*, a COM port on Windows) — no driver install on modern OSes. The same port is what make flash-dfu touches at 1200 baud to enter the bootloader — and, on Core.ST.L4, what make flash-serial opens at 2400 baud to update the firmware without one (serial update).CDC serial
Init once, then write like any serial port. core_usb_connected() tells you the host has actually opened the port (so you don’t spew into the void):
#include "core.h" // Core.ST.L4 / H5
core_usb_init();
while (1) {
if (core_usb_connected()) {
core_usb_printf("adc=%u ticks=%lu\r\n", raw, core_millis());
}
core_delay_ms(500);
}Receiving
Two RX modes. Poll a background ring buffer, or register a callback that fires from the USB interrupt as bytes arrive (when set, data isn’t buffered for polling):
// Polling:
while (core_usb_available()) {
uint8_t b = core_usb_getc();
}
// Or callback-driven:
static void on_rx(const uint8_t *data, uint16_t len, void *ctx) { /* ... */ }
core_usb_on_receive(on_rx, NULL);HID reports
Alongside CDC, the device exposes a vendor HID interface for raw 64-byte reports — handy for a custom host tool (via hidapi / pyusb) with no OS driver. It’s TX-only today:
uint8_t report[8] = { 0x01, 0x02, 0x03, 0x04 };
core_usb_hid_send(report, sizeof(report)); // zero-padded to 64 bytesCross-architecture support
CDC serial is the verified path on the USB-capable Cores; HID rides the same stack. MSC and USB host are not implemented. (The ROM DFU bootloader is covered in bootloading.)
See the implementation status for the full matrix.
Known gaps
What the SDK itself lists as missing here, straight from the headers:
The Core.USB.receive event handles inbound bytes one at a time, but DSL programs can't poll core_usb_available() / core_usb_read(). That makes message-framed protocols (read N bytes after a header) awkward — the workaround is to accumulate bytes in a DSL array inside the receive handler.
print_int / float / bool emit one value per call, each on its own line. For multi-field log lines DSL programs concatenate with string ops (or call print multiple times). A `print_fmt(template, ...args)` host call would be the next step.
SDK roadmap Tier 3: drag-and-drop firmware / datalog volume needs SCSI + FAT. A feature gap, not a workflow blocker — projects that need persistent storage today reach for NVM or SD via SPI.
Core.ST.H5 has DRD silicon but the wrapper is device-only. Most projects don't need host mode; the few that do (USB-keyboard / thumb-drive readers) drop into the lower-layer USB stack.
Host-side baud changes (1200-touch bootloader trigger included) land in the lower stack. The header doesn't expose a hook for programs that want to react to baud / DTR changes.
Sending a HID report needs a buffer pointer + length. The DSL's array-host ABI (used for tile reads) could carry it, but no default-instance wrapper is wired up.
The HID descriptor is hard-coded as a 64-byte vendor report with usage page 0xFF00. No way to register custom reports (keyboard, mouse, gamepad) — that needs the full HID descriptor tooling.
From the @studio unsupported notes in core_usb.h, core_usb_hid.h — tiles@6af026f.
API reference
void core_usb_print(const char * s);void core_usb_print_int(int v);void core_usb_print_float(double v);void core_usb_print_bool(int v);void core_usb_init(void);int core_usb_connected(void);int core_usb_wait_host(uint32_t timeout_ms);int core_usb_write(const uint8_t * buf, uint16_t len);int core_usb_try_write(const uint8_t * buf, uint16_t len);void core_usb_on_receive(hal_usb_cdc_rx_cb_t cb, void * ctx);uint16_t core_usb_available(void);uint8_t core_usb_getc(void);uint16_t core_usb_read(uint8_t * buf, uint16_t max);int core_usb_try_read(uint8_t * byte);int core_usb_hid_send(const uint8_t * buf, uint16_t len);void core_usb_hid_set_rx_callback(hal_usb_hid_rx_cb_t cb, void * ctx);Generated from core_usb.h, core_usb_hid.h — tiles@6af026f.

