Audio (PDM mic)
A PDM digital microphone emits a 1-bit sigma-delta bitstream clocked at a few megahertz. The SAI drives that clock and DMAs the raw bitstream into RAM (hal_sai); a software CIC decimator (core_pdm) then low-pass-filters and downsamples it to signed-16 PCM. Use the Core / HAL / LL toggle at the top of the sidebar to switch layers.
Overview
The PDM interface on the SAI clocks one or more microphone pairs and de-interleaves their bitstreams. On the WBA there is a single SAI and no hardware decimator, so the path is: SAI in PDM master-RX mode generates the bit clock and captures the raw 1-bit stream over GPDMA, then the application decimates in software. There is no Studio DSL block for audio — capture is escape-to-C; the Core layer here is the core_pdm decimator helper, with core_audio as a thin convenience wrapper that ties the SAI and the decimator together.
Capturing the bitstream
core_audio wraps the whole pipeline: it configures the SAI for the microphone’s data/clock lines, starts a circular GPDMA capture, and runs the decimator on each half-buffer, handing you finished PCM through a callback.
#include "core_audio.h"
static uint8_t pdm[4096] __attribute__((aligned(4))); // raw bitstream
static int16_t pcm[256]; // decimated output
static core_audio_t mic;
static void on_pcm(const int16_t *samples, uint32_t n, void *ctx) {
// n PCM samples ready (per DMA half-buffer)
}
// kernel clock, PCM rate, data line (SAI_D2), clock line (CK2),
// CIC order, extra gain shift:
core_audio_init(&mic, 16000000, 16000, 2, 2, 4, 0);
core_audio_start(&mic, GPDMA1_CH0, pdm, sizeof pdm, pcm, on_pcm, NULL);
// route GPDMA1_Channel0_IRQHandler -> core_audio_irq(&mic)Decimating to PCM
core_pdm is an integer CIC decimator (N integrator stages at the bit rate, a /R downsample, N comb stages) followed by a one-pole DC blocker. Feed it successive DMA half-buffers — filter state carries across calls, so block boundaries are seamless. The decimation factor is the PDM clock divided by the output rate (e.g. 2.048 MHz / 128 = 16 kHz).
#include "core_pdm.h"
static int16_t pcm[256];
static core_pdm_cic_t cic;
core_pdm_init(&cic, 4, 128, 0, 0); // order 4, /128, unity gain, MSB-first
// in the SAI DMA half/complete callback:
uint32_t n = core_pdm_process(&cic, pdm_half, half_bytes, pcm);
// gain_shift (arg 4) is an extra left shift on the output — lift it to
// pull up a quiet mic; a single-mic capture takes the first slot byte.Cross-architecture support
PDM capture rides on the SAI, which is present on the W5, L4, and H5 Cores (not L0). The decimator is portable integer C and runs anywhere. See the implementation status for the full matrix.
API reference
void core_pdm_init(core_pdm_cic_t * st, uint8_t order, uint16_t decimation, uint8_t gain_shift, uint8_t lsb_first);uint32_t core_pdm_process(core_pdm_cic_t * st, const uint8_t * pdm, uint32_t nbytes, int16_t * out);Generated from core_pdm.h — tiles@1f69849.

