cancel
Showing results for 
Search instead for 
Did you mean: 

DFSDM CubeMX DMA Callback Issue

fwald
Associate II

Hi 

I configured the DFSDM1 on the STM32H753VIT6 for a MEMS Mic.
I got the problem that the DMA Callback on (Half)/Full buffer never gets called. 

I used AN5027 as guideline and the DFSDM Audio Example
D-Cache disabled and set the Audio Sampling Frequency low (4kHz) to debug over UART. 

Main (snippets):

DFSDM_Filter_HandleTypeDef hdfsdm1_filter0;
DFSDM_Channel_HandleTypeDef hdfsdm1_channel4;
DMA_HandleTypeDef hdma_dfsdm1_flt0;
.
.
.
.

int32_t LeftRecBuff[1024];
void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
{
/*Never Reached*/
}
int main(void)
{
  HAL_Init();
  SystemClock_Config();

/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_DFSDM1_Init();
  /* USER CODE BEGIN 2 */

  // imu_init(&hspi4, GPIOE, GPIO_PIN_4  /* IIM-42652 CS */);
  HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, LeftRecBuff, 1024);
while (1)
  {}
}


Config (CubeMX)

/**
  * @brief DFSDM1 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_DFSDM1_Init(void)
{

  /* USER CODE BEGIN DFSDM1_Init 0 */

  /* USER CODE END DFSDM1_Init 0 */

  /* USER CODE BEGIN DFSDM1_Init 1 */

  /* 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 = ENABLE;
  hdfsdm1_filter0.Init.RegularParam.DmaMode = ENABLE;
  hdfsdm1_filter0.Init.FilterParam.SincOrder = DFSDM_FILTER_FASTSINC_ORDER;
  hdfsdm1_filter0.Init.FilterParam.Oversampling = 750;
  hdfsdm1_filter0.Init.FilterParam.IntOversampling = 1;
  if (HAL_DFSDM_FilterInit(&hdfsdm1_filter0) != HAL_OK)
  {
    Error_Handler();
  }

  hdfsdm1_channel4.Instance = DFSDM1_Channel4;
  hdfsdm1_channel4.Init.OutputClock.Activation = ENABLE;
  hdfsdm1_channel4.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM;
  hdfsdm1_channel4.Init.OutputClock.Divider = 40;
  hdfsdm1_channel4.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
  hdfsdm1_channel4.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
  hdfsdm1_channel4.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
  hdfsdm1_channel4.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING;
  hdfsdm1_channel4.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
  hdfsdm1_channel4.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER;
  hdfsdm1_channel4.Init.Awd.Oversampling = 1;
  hdfsdm1_channel4.Init.Offset = 0;
  hdfsdm1_channel4.Init.RightBitShift = 0x03;
  if (HAL_DFSDM_ChannelInit(&hdfsdm1_channel4) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_DFSDM_FilterConfigRegChannel(&hdfsdm1_filter0, DFSDM_CHANNEL_4, DFSDM_CONTINUOUS_CONV_ON) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN DFSDM1_Init 2 */

  /* USER CODE END DFSDM1_Init 2 */

}

  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);

}

 

15 REPLIES 15
fwald
Associate II

Can someone help me here out?

If checked the register values and it seems all fine to me. But the DMA dont grab the data
after HAL_DFSDM_FilterRegularStart_DMA()

DFSDM1_Filter0
- FLTCR1 = 606339073
- FLTISR = 16728074
- FLTRDATAR = is changing
The DFSDM is therefore reading the Mic data

DMAMUX1_Channel1
- CCR = 101   (dfsdm1_dma0)

The DMA Handler hdma_dfsdm1_flt0
- Init->Request = 101 (so matches the MUX CCR)

DMA1_Stream1
- CR =  218394
- M0AR = 536871496 matches the address of the Buffer (0x20000248 <LeftRecBuff>)
- PAR = 1073836316 matches the addess of the &DFSDM1_Filter0.FLTRDATAR 0x4001711c

In my understanding the data gets read from the input gets filtered and placed in the Filters data register. The DMA should start and has the correct register to read from and right to. Whats wrong?





Hello @fwald 

Did you check the return value of HAL_DFSDM_FilterRegularStart_DMA() ?

if (HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, LeftRecBuff, 1024) != HAL_OK)

{

  while(1);

}

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

Yes returns HAL_OK 

fwald
Associate II

It seems a DMA Problem. I tried a simple UART_Transmit_DMA (Example: GettingStarted ) and it didnt work either. 
Without DMA no problem.
Tried another MCU same issue.


Khaled_DHIF
ST Employee

Hello @fwald ,

The problem is most likely the RAM location of your buffer.

On STM32H7 devices, the DMA cannot access DTCM/ITCM memories. Those memories are tightly coupled to the CPU, so even if the DFSDM is working and FLTRDATAR is changing, the DMA transfer will not complete if the destination buffer is placed there.

This is visible in the block interconnect matrix from RM0433:

Khaled_DHIF_0-1775816585229.png

 

So please make sure your buffer is located in a DMA-accessible RAM region, for example SRAM1 or SRAM2.

You can do that by placing the buffer in the proper section with an attribute macro, depending on your linker script, for example:

 
__attribute__((section(".RAM_D2")))
int32_t LeftRecBuff[1024];

or another SRAM section that is accessible by DMA in your project. 

You can find more details about this kind of issue in the community article linked here.

Also, if D-Cache is enabled later, remember that cache maintenance may be needed for DMA buffers.

So, in short:

  • DFSDM looks OK
  • DMA request / callbacks are not the real issue 
  • the buffer is probably in a memory region not reachable by DMA

Move the buffer to SRAM1/SRAM2, and the callbacks should start working. 

Best regards,

DHIF Khaled

Please mark my answer as best by clicking on the “Accept as solution" button if it fully answered your question. This will help other users find this solution faster.​

Hi @Khaled_DHIF  thanks you very much. I came across the article yesterday as well which solved the problem.

But I have to say, it is a bit frustrating that the default configuration in CubeMX doesn't work when using DMA.
Maybe I missed it, but in CubeMX should at least be a obvious message or warning pointing to the article. That would have saved me—and probably other users as well—a lot of bother.

Glad it works now. :)

Kind Regards
F.