cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 DMA Data Reception Issue..

Vel
Associate III

Hi,

I'm using USART2 in DMA mode. But i'm receving data was incorrect alignment. (i.e) Data last byte was get in my first byte of data. I don't know why its happen.

I'm enabled I & D-Cache memory also and the DMA buffer was stored in in RAM_D2(0x30000000) memory reign. and I'm try 3 example of blow mentioned link.

https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices

Thanks,

vel

1 ACCEPTED SOLUTION

Accepted Solutions
Ons KOOLI
Senior III

Hi @Vel​ ,

When working with DMA for STM32H7 devices, you should pay attention to the memory allocation.

The default memory used by most of ST projects is DTCM which is not accessible by DMA in STM32H7 devices.

So, you should change it to something else which is accessible by DTCM (for example AXI SRAM 0x2400 0000). Please refer to the corresponding reference manual, under System Architecture section.

In most cases this can solve the issue. However sometimes for more advanced applications, the D-Cache can affect the functionality of DMA transfers, since the default cache policy for product SRAMs is normal memory (cacheable). Cache will hold the new data in the internal cache and don't write them to SRAM memory. However, the DMA controller loads the data from SRAM memory and not D-Cache. Same behavior can happen when reading data, as DMA will update buffers in SRAM, and the content of SRAM will not be immediately visible to CPU as CPU will see previously cached data. This will result in data coherency issues.

So if changing memory allocation did not solve the problem, you have to disable the D-Cache. But I think in your case changing memory allocation to AXI SRAM (for example) is enough to solve the issue.

Best Regards,

Ons.

View solution in original post

8 REPLIES 8
Ons KOOLI
Senior III

Hi @Vel​ ,

When working with DMA for STM32H7 devices, you should pay attention to the memory allocation.

The default memory used by most of ST projects is DTCM which is not accessible by DMA in STM32H7 devices.

So, you should change it to something else which is accessible by DTCM (for example AXI SRAM 0x2400 0000). Please refer to the corresponding reference manual, under System Architecture section.

In most cases this can solve the issue. However sometimes for more advanced applications, the D-Cache can affect the functionality of DMA transfers, since the default cache policy for product SRAMs is normal memory (cacheable). Cache will hold the new data in the internal cache and don't write them to SRAM memory. However, the DMA controller loads the data from SRAM memory and not D-Cache. Same behavior can happen when reading data, as DMA will update buffers in SRAM, and the content of SRAM will not be immediately visible to CPU as CPU will see previously cached data. This will result in data coherency issues.

So if changing memory allocation did not solve the problem, you have to disable the D-Cache. But I think in your case changing memory allocation to AXI SRAM (for example) is enough to solve the issue.

Best Regards,

Ons.

> Data last byte was get in my first byte of data. 

To avoid synchronization loss for whatever reason, it's always a good idea to use some form of packetization, e.g. use dedicated characters for "start of frame"/"end of frame".

You can also try to find the reason for data/synchronization loss by observing the data link using oscilloscope/logic analyzer.

JW

Hi @Ons KOOLI ,

Thanks for your response and your detailed explanation.. It was very useful and understand for me.

Hi waclawek.jan,

Thanks for your response,

> e.g. use dedicated characters for "start of frame"/"end of frame".

In my commutation start and end of communication using dedicated characters.

here mentioned the observation may be this observation cause the Pblm in my last data byte get 1st byte.

1st communication data was received as expected length+1 characters than next communication data length was received as expected.

Here mentioned my configurations;-

UART Config:-

huart2.Instance = USART2;

 huart2.Init.BaudRate = 115200;

 huart2.Init.WordLength = UART_WORDLENGTH_8B;

 huart2.Init.StopBits = UART_STOPBITS_1;

 huart2.Init.Parity = UART_PARITY_NONE;

 huart2.Init.Mode = UART_MODE_TX_RX;

 huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;

 huart2.Init.OverSampling = UART_OVERSAMPLING_16;

 huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

 huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;

 huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT|UART_ADVFEATURE_DMADISABLEONERROR_INIT;

 huart2.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_ENABLE;

 huart2.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;

 if (HAL_UART_Init(&huart2) != HAL_OK)

 {

   Error_Handler();

 }

 if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)

 {

   Error_Handler();

 }

 if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)

 {

   Error_Handler();

 }

 if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)

 {

   Error_Handler();

 }

DMA & PIN Config:-

   GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;

   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

   GPIO_InitStruct.Pull = GPIO_NOPULL;

   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

   GPIO_InitStruct.Alternate = GPIO_AF7_USART2;

   HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

   /* USART2 DMA Init */

   /* USART2_RX Init */

   hdma_usart2_rx.Instance = DMA1_Stream0;

   hdma_usart2_rx.Init.Request = DMA_REQUEST_USART2_RX;

   hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;

   hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;

   hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;

   hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

   hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

   hdma_usart2_rx.Init.Mode = DMA_NORMAL;

   hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;

   hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

   if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)

   {

    Error_Handler();

   }

   __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);

main.cpp

std::array<char, 30> rxData1;

   for(int i=0;i<30;i++){

      rxData1.at(i) = 'A';

   }

   while ((HAL_UART_GetState(&huart2) != HAL_UART_STATE_READY)) {}

   while(1){

      SCB_CleanInvalidateDCache_by_Addr((uint32_t*)&rxData1[0U], sizeof rxData1);

      if(HAL_UART_Transmit_DMA(&huart2, reinterpret_cast<uint8_t *>(&rxData1), sizeof rxData1)!= HAL_OK){    }

      while (UartReady != SET) {}

      UartReady = RESET;

      SCB_CleanInvalidateDCache_by_Addr((uint32_t*)&rxData1[0U], sizeof rxData1);

      if(HAL_UART_Receive_DMA(&huart2, reinterpret_cast<uint8_t *>(&rxData1), sizeof rxData1)!= HAL_OK){    }

      while (UartReady != SET) {}

      UartReady = RESET;

      HAL_UART_Transmit(&huart1, reinterpret_cast<uint8_t *>(&rxData1), sizeof rxData1, 1000);

   }

Thanks,

Vel

Ons KOOLI
Senior III

Hi @Vel​ ,

You can also refer to the STM32CubeH7 firmware package.

Under directory Projects/$Board_Name$/Examples/UART/UART_HyperTerminal_DMA if you are transmitting data between a board and a terminal in DMA mode &

Projects/$Board_Name$/Examples/UART/UART_TwoBoards_ComDMA if you are transmitting data between two boards in DMA mode.

Best Regards,

Ons.

Hi Ons KOOLI,

Thanks for your response, I have obtained the DMA mode working.

Thanks,

vel

Hi @Vel​ ,

Great!

You are welcome.

Please check this question as answered by choosing the "Select as Best" option for the response you found that it helped you and solved your claim.

Best Regards,

Ons.

Gdsfs.1
Associate

I am also facing data reception issues in my account and also tried to solve these issues but not succeed to make any changes in it please help us to solve the issue.