I2S — Audio Bus Driver
Header: ove/i2s.h | Kconfig: CONFIG_OVE_I2S
Overview
I2S / SAI master driver for DMA-based audio streaming. Uses double-buffered (ping-pong) DMA with half-buffer completion callbacks delivered from ISR context, enabling continuous low-latency capture and playback.
The codec attached to the bus is not initialised by this driver — codec bring-up is board-specific and is normally done from the board BSP (e.g. via I2C register writes).
Configuration
struct ove_i2s_cfg {
unsigned int instance; // Peripheral index (0, 1, ...)
uint32_t sample_rate; // Hz (e.g. 44100, 48000)
uint8_t bit_depth; // 16, 24, or 32
uint8_t channels; // 1 (mono) or 2 (stereo)
ove_i2s_dir_t direction; // TX, RX, or TXRX
size_t dma_buf_samples; // Total samples in DMA buffer (both halves)
};
ove_i2s_dir_t values: OVE_I2S_DIR_TX, OVE_I2S_DIR_RX, OVE_I2S_DIR_TXRX.
API
| Function | Description |
|---|---|
ove_i2s_init() |
Initialise with static storage and caller-supplied DMA buffers |
ove_i2s_create() / ove_i2s_destroy() |
Heap or zero-heap per-call-site storage |
ove_i2s_set_rx_callback() |
Register RX half-buffer-complete ISR callback |
ove_i2s_set_tx_callback() |
Register TX half-buffer-complete ISR callback |
ove_i2s_start() / ove_i2s_stop() |
Start / stop circular DMA streaming |
ove_i2s_pause() / ove_i2s_resume() |
Pause and resume a running stream |
ove_i2s_rx_buf() |
Pointer to the completed RX half-buffer (call from RX callback) |
ove_i2s_tx_buf() |
Pointer to the TX half-buffer safe to refill |
ove_i2s_half_buf_size() |
Size of one half-buffer in bytes |
Callback signature:
typedef void (*ove_i2s_cb_t)(ove_i2s_t i2s, void *user_data);
Callbacks run in ISR context. Keep them short — typically they just signal a worker thread to process the buffer.
Example: Capturing Microphone Audio
static void rx_ready(ove_i2s_t i2s, void *user_data)
{
ove_sem_t *sem = user_data;
ove_sem_give_from_isr(*sem);
}
struct ove_i2s_cfg cfg = {
.instance = 2,
.sample_rate = 16000,
.bit_depth = 16,
.channels = 1,
.direction = OVE_I2S_DIR_RX,
.dma_buf_samples = 1024, /* two halves of 512 samples */
};
ove_i2s_t i2s;
ove_i2s_create(&i2s, &cfg);
ove_i2s_set_rx_callback(i2s, rx_ready, &buf_ready_sem);
ove_i2s_start(i2s);
for (;;) {
ove_sem_take(buf_ready_sem, OVE_WAIT_FOREVER);
const int16_t *samples = ove_i2s_rx_buf(i2s);
size_t bytes = ove_i2s_half_buf_size(i2s);
/* process samples ... */
}
Backend Notes
| Backend | Implementation |
|---|---|
| FreeRTOS/STM32 | HAL SAI / I2S with HAL_SAI_Transmit/Receive_DMA and half/full-complete ISR hooks |
| Zephyr | i2s_configure() + i2s_write() / i2s_read() with ping-pong buffers |
| NuttX | Audio subsystem /dev/audio* with DMA ring buffers |
| POSIX | Routed through the sim framework to the browser dashboard (Web Audio API) |
| WASM | Browser Web Audio API output; input capture depends on getUserMedia permission |
Kconfig Options
| Option | Default | Description |
|---|---|---|
CONFIG_OVE_I2S |
n |
Enable the I2S / SAI driver |
ove_i2s is the low-level transport used by the higher-level
audio graph engine when the graph is connected to I2S device
nodes.