PDM

The PDM (Pulse Density Modulation) module is used to filter PDM signals output from external PDM microphones, convert them to PCM signals, and provide them to the CPU for subsequent processing.

Supported Configurations

  • Mono (left/right), stereo

  • Sample rates: 8/12/16/24/32/48KHz

  • 24-bit sampling depth

  • Left and right channel gain adjustment

  • Circular buffer/single buffer

Output Data Formats

  • 8-bit + mono

  • 16-bit + mono

  • 32-bit + mono: Upper 8 bits are 0, actual valid data is lower 24 bits

  • 16-bit + stereo: Left and right channels each occupy 16 bits forming one 32-bit data (supports left/right channel swapping)

  • 32-bit + stereo: Only supports left and right channels stored in separate 2 buffers

Example

PDM1 mono 16KHz, 16-bit depth, using DMA to read 1024 bytes of data

static PDM_HandleTypeDef PDM_Handle = {0};
static DMA_HandleTypeDef DMA_Handle = {0};
static uint32_t DMA_cplt_flag = 0;

void DMAC1_CH3_IRQHandler(void)
{
    HAL_DMA_IRQHandler(PDM_Handle.hdmarx);
}

void HAL_PDM_RxCpltCallback(PDM_HandleTypeDef *hpdm)
{
    if(hpdm == &PDM_Handle)
        DMA_cplt_flag = 1;
}

void pdm_receive(void)
{
    DMA_Handle.Instance = DMA1_Channel3;
    DMA_Handle.Init.Request = DMA_REQUEST_18;

    PDM_Handle.hdmarx = &DMA_Handle;
    PDM_Handle.Instance = hwp_pdm1;
    PDM_Handle.Init.Mode = PDM_MODE_LOOP; //Ring buffer mode
    PDM_Handle.Init.Channels = PDM_CHANNEL_LEFT_ONLY;
    PDM_Handle.Init.SampleRate = PDM_SAMPLE_16KHZ;
    PDM_Handle.Init.ChannelDepth = PDM_CHANNEL_DEPTH_16BIT;
    PDM_Handle.RxXferSize = 1024;
    PDM_Handle.pRxBuffPtr = (uint8_t *) 0x2000c000;

    HAL_PDM_Init(&PDM_Handle);
    HAL_NVIC_EnableIRQ(DMAC1_CH3_IRQn);

    HAL_PDM_Receive_DMA(&PDM_Handle, PDM_Handle.pRxBuffPtr, PDM_Handle.RxXferSize);

    while(DMA_cplt_flag == 0);

    HAL_NVIC_DisableIRQ(DMAC1_CH3_IRQn);
    HAL_PDM_DMAStop(&PDM_Handle);
    HAL_PDM_DeInit(&PDM_Handle);
}
...

API Reference

bf0_hal_pdm.h