2025-08-03 11:18 PM
I am trying to use the DFSDM in parallel mode. However my output sample rate is significantly lower than expected.
My input is an MEMS microphone, with 2.048MHz leading to 128kS/s of 16bit samples that arrive at the MPU.
The desired output is 32kS/s PCM.
My filters are configured as follows (everything except for Continuous mode is done by CubeMX)
hdfsdm1_filter0.RegularContMode = DFSDM_CONTINUOUS_CONV_ON;
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 = DISABLE;
hdfsdm1_filter0.Init.FilterParam.SincOrder = DFSDM_FILTER_SINC3_ORDER;
hdfsdm1_filter0.Init.FilterParam.Oversampling = 64;
hdfsdm1_filter0.Init.FilterParam.IntOversampling = 1;
if (HAL_DFSDM_FilterInit(&hdfsdm1_filter0) != HAL_OK)
{
Error_Handler();
}
hdfsdm1_channel0.Instance = DFSDM1_Channel0;
hdfsdm1_channel0.Init.OutputClock.Activation = DISABLE;
hdfsdm1_channel0.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM;
hdfsdm1_channel0.Init.OutputClock.Divider = 1;
hdfsdm1_channel0.Init.Input.Multiplexer = DFSDM_CHANNEL_INTERNAL_REGISTER;
hdfsdm1_channel0.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
hdfsdm1_channel0.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
hdfsdm1_channel0.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING;
hdfsdm1_channel0.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL;
hdfsdm1_channel0.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER;
hdfsdm1_channel0.Init.Awd.Oversampling = 1;
hdfsdm1_channel0.Init.Offset = 0x00;
hdfsdm1_channel0.Init.RightBitShift = 0x00;
if (HAL_DFSDM_ChannelInit(&hdfsdm1_channel0) != HAL_OK)
{
Error_Handler();
}
if (HAL_DFSDM_FilterConfigRegChannel(&hdfsdm1_filter0, DFSDM_CHANNEL_0, DFSDM_CONTINUOUS_CONV_ON) != HAL_OK)
{
Error_Handler();
}
The code writing and reading is done as follows (result is the input, use is an indicator if there is new data available):
DFSDM_Channel_HandleTypeDef channel = hdfsdm1_channel0;
DFSDM_Filter_HandleTypeDef filter = hdfsdm1_filter0;
channel.Instance->CHDATINR = result & 0xffff;
use = false;
if (filter.Instance->FLTISR & DFSDM_FLTISR_REOCF) {
use = true;
result = filter.Instance->FLTRDATAR >> 16;
}
If my understanding is correct, I believe I need 64x oversampling. However, when I do select 64x oversampling, I only get ~500 Samples per second.
When I set the oversampling to 4x, I get 8kS/s. But setting the oversampling ration to 1x, I get 64kS/s.
Since I discovered that I am apparently unable to properly reset the filters, I always reset the MCU after changing the filter configuration.
2025-08-04 12:48 AM
Setting the Filter to Sinc1, and the oversampling to "2" (so 3x oversampling) does yield the correct amount of samples.
But the output is very noisy (just reading the top 16bit, it appears as [-225,225] all the time, regardless of real world noise level).