cancel
Showing results for 
Search instead for 
Did you mean: 

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

cfilipescu
Senior

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();
        }

1 ACCEPTED SOLUTION

Accepted Solutions
cfilipescu
Senior

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

View solution in original post

2 REPLIES 2
PatrickF
ST Employee

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.
cfilipescu
Senior

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