UART
A classic asynchronous serial port — the simplest way to talk to a sensor, a host terminal, or another MCU. core_serial gives you blocking printf-style TX and buffered RX over any USART; the hal_uart and ll_uart layers sit underneath. Use the Core / HAL / LL toggle at the top of the sidebar to switch.
Overview
A UART is identified by its USART instance (USART1, USART2, …). You give it a baud rate; everything is 8 data bits, no parity, 1 stop bit (8N1). The peripheral clock is resolved for you, so init is just the instance and a baud rate.
core_serial is handle-based (Tier 1): you hold a hal_uart_t and pass it to each call. There’s also a small Tier 2 *_bus surface (print / putc by config-declared bus id) for Studio.
Transmit
Initialize once, then write strings, bytes, or formatted output. All TX is blocking — the call returns once the bytes are on the wire:
#include "core.h"
hal_uart_t uart;
hal_uart_config_t cfg = { .baud = 115200, .rx_interrupt = 0 };
core_serial_init(&uart, USART2, &cfg);
core_serial_print(&uart, "boot\r\n");
core_serial_printf(&uart, "adc=%u mv=%lu\r\n", raw, mv);Receive
RX has two modes, chosen at init. With rx_interrupt = 0 you poll; with rx_interrupt = 1 the driver fills a background ring buffer you drain at your own pace:
hal_uart_config_t cfg = { .baud = 115200, .rx_interrupt = 1 };
core_serial_init(&uart, USART2, &cfg);
// later, in your loop:
while (core_serial_available(&uart)) {
uint8_t b = core_serial_getc(&uart); // blocking; pair with available()
handle(b);
}*_bus Studio surface is TX-only — there’s no default-instance read / available yet (a known coverage gap). Use the handle calls above for RX.DMA transmit
hal_uart_tx_dma exists in the API but returns HAL_ERROR on every Core and never calls its callback: UART DMA needs a DMA channel assignment from coregen and per-family DMA setup that haven’t been written. Transmit is blocking today (core_serial_write / hal_uart_tx); for background receive, use the interrupt-driven ring buffer above.Cross-architecture support
Polling TX/RX is the verified baseline; interrupt-driven RX and LPUART are further along on some Cores than others. The same core_serial contract holds across the family:
See the implementation status for the full matrix.
Known gaps
What the SDK itself lists as missing from serial, straight from the header:
Tier 2 wraps the write side (print_bus, putc_bus) only. getc_bus, read_bus, available_bus need a Twin input affordance to be meaningful — without one the read functions would just return -1/0 always, defeating the point. Adding a "serial input" pane (analog of the GPIO toggle / ADC slider) closes both ends.
Tier 2 wrappers assume the user has called core_serial_init on the matching handle before any send. Coregen doesn't yet read a `serial: { 1: { baud: 115200 } }` block out of config.json and emit the init in core_init(). Until it does, the bus has to be primed by hand even when using Tier 2.
All calls block. SDK roadmap Tier 1 item: "UART IRQ + coregen" for non-blocking serial (GPS, RS-485). Long reads currently stall the main loop until the buffer fills or times out.
The thin wrappers expose only the basics — RTS/CTS, parity, stop bits, 9-bit data, and inversion are reachable only via the hal_uart_config_t struct passed to init.
SDK roadmap Tier 2: LPUART works in Stop mode for wake-on-serial. Compile-only on every Core today; not surfaced through this header.
From the @studio unsupported notes in core_serial.h — tiles@6af026f.
API reference
int core_serial_print_bus(uint8_t bus, const char * str);int core_serial_putc_bus(uint8_t bus, uint8_t byte);hal_status_t core_serial_init(hal_uart_t * h, USART_TypeDef * instance, const hal_uart_config_t * cfg);hal_status_t core_serial_init_clk(hal_uart_t * h, USART_TypeDef * instance, uint32_t pclk_hz, const hal_uart_config_t * cfg);void core_serial_write(hal_uart_t * h, const uint8_t * data, uint32_t len);void core_serial_print(hal_uart_t * h, const char * str);void core_serial_putc(hal_uart_t * h, uint8_t byte);uint16_t core_serial_available(hal_uart_t * h);uint8_t core_serial_getc(hal_uart_t * h);uint16_t core_serial_read(hal_uart_t * h, uint8_t * buf, uint16_t max_len);hal_uart_t * core_serial_handle_for_bus(uint8_t bus);Generated from core_serial.h — tiles@f70bca2.

