Record audio using DFSDM and send the data over UART
I have a B-L475E-IOT01A2 board. I'm trying to use the onboard microphones to record audio, using the DFSDM peripheral, and then send the data over UART to my PC to play it back. The thing is, the data I get is basically just static.
Here is how I configured the DFSDM peripheral in CubeMX, based on the "DFSDM_AudioRecord" example for the eval boards
- Source for output clock is audio clock. SAI1 is clocked at 13.714286 MHz, the divider is set at 5 to get 2.74 MHz.
- Channel 1 and 2:
- SPI with falling (resp. rising) edge, internal SPI clock
- Offset = 0, right bit shift = 0x02
- Analog watchdog (I think is unused): FastSinc, oversampling = 10
- Filter 0 and 1:
- Regular channel selection 1 (resp. 2)
- Continuous mode, software trigger, fast mode and DMA mode enabled
- No injected channels
- Sinc 3 filter
- Filter oversampling : 64 to get 42.85 kHz. Integrator oversampling: 1 (bypass).
- DMA channels set for both filters, peripheral to memory, high priority, circular mode, increment memory address automatically, data width = word.
- DMA channels and filter interrupts enabled.
Now, for the code:
#define DFSDM_RECORDING_SIZE 2048
static bool left_dma_half_complete = false;
static bool left_dma_full_complete = false;
static bool right_dma_half_complete = false;
static bool right_dma_full_complete = false;
static int32_t left_rec_buf[DFSDM_RECORDING_SIZE];
static int32_t right_rec_buf[DFSDM_RECORDING_SIZE];
static int16_t output_buf[DFSDM_RECORDING_SIZE * 2];
static HAL_StatusTypeDef status;
// ...
// in main():
if (HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, left_rec_buf,
DFSDM_RECORDING_SIZE) != HAL_OK) {
Error_Handler();
}
if (HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter1, right_rec_buf,
DFSDM_RECORDING_SIZE) != HAL_OK) {
Error_Handler();
}
while (1) {
if (left_dma_half_complete && right_dma_half_complete) {
for (int i = 0; i < DFSDM_RECORDING_SIZE; i++) {
output_buf[i * 2] = clamp(left_rec_buf[i] / 256, -32768, 32767);
output_buf[i * 2 + 1] = clamp(right_rec_buf[i] / 256, -32768, 32767);
}
status = HAL_UART_Transmit(&huart1, (uint8_t *)output_buf,
DFSDM_RECORDING_SIZE * 4, 1000);
if (status != HAL_OK) {
Error_Handler();
}
left_dma_half_complete = false;
right_dma_half_complete = false;
}
if (left_dma_full_complete && right_dma_full_complete) {
for (int i = 0; i < DFSDM_RECORDING_SIZE; i++) {
output_buf[i * 2] = clamp(left_rec_buf[i] / 256, -32768, 32767);
output_buf[i * 2 + 1] = clamp(right_rec_buf[i] / 256, -32768, 32767);
}
status = HAL_UART_Transmit(&huart1, (uint8_t *)output_buf,
DFSDM_RECORDING_SIZE * 4, 1000);
if (status != HAL_OK) {
Error_Handler();
}
left_dma_full_complete = false;
right_dma_full_complete = false;
}
}
void HAL_DFSDM_FilterRegConvHalfCpltCallback(
DFSDM_Filter_HandleTypeDef *hdfsdm_filter) {
if (hdfsdm_filter == &hdfsdm1_filter0) {
left_dma_half_complete = true;
} else if (hdfsdm_filter == &hdfsdm1_filter1) {
right_dma_half_complete = true;
}
}
void HAL_DFSDM_FilterRegConvCpltCallback(
DFSDM_Filter_HandleTypeDef *hdfsdm_filter) {
if (hdfsdm_filter == &hdfsdm1_filter0) {
left_dma_full_complete = true;
} else if (hdfsdm_filter == &hdfsdm1_filter1) {
right_dma_full_complete = true;
}
}
