Concepts First
- UART (serial): like a telegraph line, transferring data byte by byte on TX/RX wires.
- Baud rate: bits per second; the example uses 2000000 (2M) — both ends must match or you get garbage.
- 8N1: 8 data bits + no parity + 1 stop bit, the most common serial configuration.
- FIFO interrupt: the hardware notifies the CPU only when data accumulates to a threshold, reducing interruptions — good for high-speed communication.
Example Overview
This page is based on the uart_fifo_interrupt example in the official Bouffalo SDK (examples/peripherals/uart/uart_fifo_interrupt), which demonstrates UART send/receive with FIFO interrupts:
- Serial parameters: baud rate 2000000, 8 data bits, 1 stop bit, no parity (8N1);
- TX direction: when the TX FIFO interrupt fires, 27 test bytes (0x00–0x1A) are sent;
- RX direction: the RX FIFO and receive-timeout (RTO) interrupts store received data, and the main loop prints it in hex as
0xXX. - Sibling examples (
examples/peripherals/uart/):uart_poll(polling),uart_dma(DMA),uart_cts(hardware flow control),uart_sw_rts(software RTS),uart_rs485(RS485),uart_lin(LIN),uart_auto_baudrate(auto baud),uart_ir(IR carrier),uart_end_interrupt/uart_error_interrupt/uart_dma_rto/uart_feature_control(interrupt/feature tests).
Operation Steps
Use the board’s built-in USB serial port (the default test UART DEFAULT_TEST_UART is defined by the board, usually uart0). No extra wiring is needed — just connect the data cable to your computer.
Open a terminal and enter the UART example directory (prerequisite: set up the environment as in Quick Start (Linux) or Windows):
cd examples/peripherals/uart/uart_fifo_interruptRun the build command. The Ai-M62 (BL616) and Ai-M61 (BL618) belong to the same series, so both use bl616:
make CHIP=bl616 BOARD=bl616dkConnect the board with a USB cable, hold the BOOT button (IO2 on the Ai-M61-32S-Kit), briefly press EN/RST to enter download mode, then flash (replace the serial port with the one on your computer):
make flash CHIP=bl616 COMX=/dev/ttyUSB0Open a serial tool (baud rate 2000000). After startup the example sends 27 bytes (0x00–0x1A) through the TX FIFO interrupt and prints tx fifo; then any data you send is received and printed as 0xXX in hex.
Code Execution Flow
The complete execution flow from startup to running is shown below (loop arrows mean repeated execution):
APIs Used by the Example
bflb_uart_init(uart, config)
Initializes the UART. In struct bflb_uart_config_s:
baudrate: baud rate,2000000in the exampledata_bits:UART_DATA_BITS_8stop_bits:UART_STOP_BITS_1parity:UART_PARITY_NONEtx_fifo_threshold/rx_fifo_threshold: FIFO interrupt thresholds,7bit_order:UART_LSB_FIRST
Parameters:
uart: UART device handle (bflb_device_get_by_name(DEFAULT_TEST_UART))config: pointer to the config struct
Return: 0 on success; negative error code on failure
bflb_uart_get_intstatus(uart)
Reads the interrupt status in the ISR to determine which event fired.
Parameters:
uart: UART device handle
Return: interrupt status bits, commonly UART_INTSTS_RX_FIFO, UART_INTSTS_RTO, UART_INTSTS_TX_FIFO
bflb_uart_rxavailable(uart)
Checks how many bytes are available in the RX FIFO.
Parameters:
uart: UART device handle
Return: number of readable bytes
bflb_uart_getchar(uart)
Reads one byte from the RX FIFO.
Parameters:
uart: UART device handle
Return: the byte read; -1 if no data
bflb_uart_putchar(uart, data)
Writes one byte into the TX FIFO.
Parameters:
uart: UART device handledata: byte to send
Return: 0 on success; negative error code on failure
bflb_uart_txint_mask / bflb_uart_rxint_mask(uart, mask)
Masks/unmasks the TX/RX interrupts: false unmasks (enables), true masks.
Parameters:
uart: UART device handlemask:falseenable /truemask
Return: none
Complete Code
The complete source below matches the effect described on this page. It is based on the official example (examples/peripherals/uart/uart_fifo_interrupt); the LED pins are adapted to the Ai-M61/62-32S-Kit onboard RGB LED. Collapsed by default, click to expand:
📜 Click to expand uart_fifo_interrupt/main.c full code
#include "bflb_mtimer.h"
#include "bflb_uart.h"
#include "board.h"
struct bflb_device_s *uartx;
#define RX_BUFF_SIZE 1024
static uint8_t uart_txbuf[128] = { 0 };
static uint8_t uart_rxbuf[RX_BUFF_SIZE] = { 0 };
static uint32_t uart_rx_count = 0;
void uart_isr(int irq, void *arg)
{
uint32_t intstatus = bflb_uart_get_intstatus(uartx);
if (intstatus & UART_INTSTS_RX_FIFO) {
while (bflb_uart_rxavailable(uartx)) {
uart_rxbuf[uart_rx_count++] = bflb_uart_getchar(uartx);
}
}
if (intstatus & UART_INTSTS_RTO) {
bflb_uart_int_clear(uartx, UART_INTCLR_RTO);
printf("rto\r\n");
while (bflb_uart_rxavailable(uartx)) {
uart_rxbuf[uart_rx_count++] = bflb_uart_getchar(uartx);
}
}
if (intstatus & UART_INTSTS_TX_FIFO) {
printf("tx fifo\r\n");
for (uint8_t i = 0; i < 27; i++) {
bflb_uart_putchar(uartx, uart_txbuf[i]);
}
bflb_uart_txint_mask(uartx, true);
}
}
int main(void)
{
board_init();
board_uartx_gpio_init();
uartx = bflb_device_get_by_name(DEFAULT_TEST_UART);
for (uint8_t i = 0; i < 128; i++) {
uart_txbuf[i] = i;
}
struct bflb_uart_config_s cfg;
cfg.baudrate = 2000000;
cfg.data_bits = UART_DATA_BITS_8;
cfg.stop_bits = UART_STOP_BITS_1;
cfg.parity = UART_PARITY_NONE;
cfg.flow_ctrl = 0;
cfg.tx_fifo_threshold = 7;
cfg.rx_fifo_threshold = 7;
cfg.bit_order = UART_LSB_FIRST;
bflb_uart_init(uartx, &cfg);
bflb_uart_txint_mask(uartx, false);
bflb_uart_rxint_mask(uartx, false);
bflb_irq_attach(uartx->irq_num, uart_isr, NULL);
bflb_irq_enable(uartx->irq_num);
while (1) {
if (uart_rx_count > RX_BUFF_SIZE) {
uart_rx_count = RX_BUFF_SIZE;
}
if (uart_rx_count) {
for (uint32_t i = 0; i < uart_rx_count; i++) {
printf("0x%02x\r\n", uart_rxbuf[i]);
}
uart_rx_count = 0;
}
bflb_mtimer_delay_ms(100);
}
}FAQ
No serial output
Set the baud rate to 2000000; make sure you are connected to the USB port of the default test UART; if nothing appears after flashing, press the reset button.
Sent data is not echoed as 0xXX
Make sure the serial tool sends characters/HEX as expected; the example prints every received byte in hex, one 0xXX line per byte.
Can I change the baud rate?
Yes. Change cfg.baudrate, rebuild and flash, and set the serial tool to the same value — both ends must match.
Related Best Practices
Have questions?
For any other questions, visit the unified Q&A and discussion board: Ai-Thinker Discussions

