2025-07-28 9:37 PM - edited 2025-07-28 9:40 PM
Hi ST community,
I am using the B-L4S5I-IOT01A board to record 3 sec of 16 kHz audio using DFSDM + DMA, and then transmit it offline via UART (after recording is complete). Since two MP34DT01-M microphones are connected to DFSDM Channel 2, I configured Filter 0 to use only one microphone. I am using a Python script to receive the DFSDM data and save it in .WAV format. I am able to record 3 sec of audio; however, when I play the audio on my laptop, it seems to play at 10× speed.
Here is my code :
------------------------------------
#define SAMPLE_RATE 16000
#define RECORD_SECONDS 3
#define TOTAL_SAMPLES (SAMPLE_RATE * RECORD_SECONDS)
#define DFSDM_BUFFER_SIZE TOTAL_SAMPLES
#define UART_TX_TIMEOUT 1000
static int32_t dfsdm_rec_buf[DFSDM_BUFFER_SIZE]; // Raw 32-bit DFSDM samples
static int16_t audio_output[DFSDM_BUFFER_SIZE]; // 16-bit PCM samples
static volatile bool record_done = false;
extern DFSDM_Filter_HandleTypeDef hdfsdm1_filter0;
extern UART_HandleTypeDef huart1;
int16_t clamp(int32_t val, int32_t min, int32_t max) {
if (val < min) return min;
else if (val > max) return max;
return (int16_t)val;
}
// DMA complete callback
void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter) {
if (hdfsdm_filter == &hdfsdm1_filter0) {
record_done = true;
}
}
void StartMonoRecordingAndTransmitOffline(void) {
// Start DFSDM + DMA
if (HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, dfsdm_rec_buf, DFSDM_BUFFER_SIZE) != HAL_OK) {
Error_Handler();
}
// Wait for 3 seconds of recording
while (!record_done);
// Stop DFSDM
HAL_DFSDM_FilterRegularStop_DMA(&hdfsdm1_filter0);
// Convert 24-bit DFSDM -> int16 PCM
for (uint32_t i = 0; i < DFSDM_BUFFER_SIZE; i++) {
audio_output[i] = clamp(dfsdm_rec_buf[i] >> 8, -32768, 32767);
}
// Transmit via UART in 512-sample chunks
for (uint32_t offset = 0; offset < DFSDM_BUFFER_SIZE; offset += 512) {
HAL_UART_Transmit(&huart1,
(uint8_t*)&audio_output[offset],
512 * sizeof(int16_t),
UART_TX_TIMEOUT);
HAL_Delay(100); // Prevent PC UART buffer overflow
}
record_done = false;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_DFSDM1_Init();
MX_USART1_UART_Init();
HAL_Delay(500); // Optional: wait for PC UART terminal to get ready
StartMonoRecordingAndTransmitOffline();
while (1) {
}
}
Here is my DFSDM1 setting :
/* USER CODE END DFSDM1_Init 1 */
hdfsdm1_filter0.Instance = DFSDM1_Filter0;
hdfsdm1_filter0.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
hdfsdm1_filter0.Init.RegularParam.FastMode = DISABLE;
hdfsdm1_filter0.Init.RegularParam.DmaMode = ENABLE;
hdfsdm1_filter0.Init.FilterParam.SincOrder = DFSDM_FILTER_SINC3_ORDER;
hdfsdm1_filter0.Init.FilterParam.Oversampling = 200;
hdfsdm1_filter0.Init.FilterParam.IntOversampling = 1;
if (HAL_DFSDM_FilterInit(&hdfsdm1_filter0) != HAL_OK)
{
Error_Handler();
}
hdfsdm1_filter1.Instance = DFSDM1_Filter1;
hdfsdm1_filter1.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
hdfsdm1_filter1.Init.RegularParam.FastMode = DISABLE;
hdfsdm1_filter1.Init.RegularParam.DmaMode = DISABLE;
hdfsdm1_filter1.Init.InjectedParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
hdfsdm1_filter1.Init.InjectedParam.ScanMode = DISABLE;
hdfsdm1_filter1.Init.InjectedParam.DmaMode = DISABLE;
hdfsdm1_filter1.Init.InjectedParam.ExtTrigger = DFSDM_FILTER_EXT_TRIG_TIM1_TRGO;
hdfsdm1_filter1.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_RISING_EDGE;
hdfsdm1_filter1.Init.FilterParam.SincOrder = DFSDM_FILTER_FASTSINC_ORDER;
hdfsdm1_filter1.Init.FilterParam.Oversampling = 1;
hdfsdm1_filter1.Init.FilterParam.IntOversampling = 1;
if (HAL_DFSDM_FilterInit(&hdfsdm1_filter1) != HAL_OK)
{
Error_Handler();
}
hdfsdm1_channel2.Instance = DFSDM1_Channel2;
hdfsdm1_channel2.Init.OutputClock.Activation = ENABLE;
hdfsdm1_channel2.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM;
hdfsdm1_channel2.Init.OutputClock.Divider = 25;
hdfsdm1_channel2.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
hdfsdm1_channel2.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
hdfsdm1_channel2.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
hdfsdm1_channel2.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING;
hdfsdm1_channel2.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
hdfsdm1_channel2.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER;
hdfsdm1_channel2.Init.Awd.Oversampling = 1;
hdfsdm1_channel2.Init.Offset = 0;
hdfsdm1_channel2.Init.RightBitShift = 8;
Can someone explain what might be causing this issue?