Skip to main content
cfilipescu
Senior
July 20, 2022
Solved

Is there any documentation for configuring UART RX DMA in circular mode properly?

  • July 20, 2022
  • 2 replies
  • 1577 views

I am trying to configure a DMA stream to capture the RX channel of a UART core on the m4, however, I get very undesirable behaviour.

I am trying to set up a circular rx buffer that is of size 10 since the data coming back is of multiples of 5. Unfortunately, I don't get the trigger at half full for many seconds, and when I finally deinit the uart and DMA and abort any tx or rx the half transfer complete callback finally comes.

If I change the dma receive size to 8 I get the trigger at half full (4), so is there a limitation or alignment problem?

static void MX_USART3_UART_Init(void) {
 
 /* USER CODE BEGIN USART3_Init 0 */
 
 /* USER CODE END USART3_Init 0 */
 
 /* USER CODE BEGIN USART3_Init 1 */
 
 /* USER CODE END USART3_Init 1 */
 huart3.Instance = USART3;
 huart3.Init.BaudRate = 2500000;
 huart3.Init.WordLength = UART_WORDLENGTH_9B;
 huart3.Init.StopBits = UART_STOPBITS_1;
 huart3.Init.Parity = UART_PARITY_NONE;
 huart3.Init.Mode = UART_MODE_TX_RX;
 huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart3.Init.OverSampling = UART_OVERSAMPLING_16;
 huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
 huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart3) != HAL_OK) {
 Error_Handler();
 }
 if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) {
 Error_Handler();
 }
 if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) {
 Error_Handler();
 }
 if (HAL_UARTEx_EnableFifoMode(&huart3) != HAL_OK) {
 Error_Handler();
 }
 /* USER CODE BEGIN USART3_Init 2 */
 if (HAL_UART_Receive_DMA(&huart3, (uint8_t *)uart3_rx_buffer, 10) != HAL_OK) {
 log_err("Failed setting up the DMA for USART3 \r\n");
 }
 /* USER CODE END USART3_Init 2 */
}
/* USART3_RX Init */
 hdma_usart3_rx.Instance = DMA2_Stream2;
 hdma_usart3_rx.Init.Request = DMA_REQUEST_USART3_RX;
 hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
 hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
 hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
 hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
 hdma_usart3_rx.Init.Mode = DMA_CIRCULAR;
 hdma_usart3_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
 hdma_usart3_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
 hdma_usart3_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
 hdma_usart3_rx.Init.MemBurst = DMA_MBURST_SINGLE;
 hdma_usart3_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
 if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK) {
 Error_Handler();
 }

This topic has been closed for replies.
Best answer by cfilipescu

Had to disable fifomode in order to use the circular dma when the data was 5 bytes

2 replies

PatrickF
Technical Moderator
July 21, 2022

Hi @cfilipescu​ 

as already mentioned in one of your other post, https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx might be a good source of information.

Regards,

In order to give better visibility on the answered topics, please click on 'Select as Best' on the reply which solved your issue or answered your question. See also 'Best Answers'

In order 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.NEW ! Sidekick STM32 AI agent, see here
cfilipescu
cfilipescuAuthorBest answer
Senior
August 12, 2022

Had to disable fifomode in order to use the circular dma when the data was 5 bytes