Is there any documentation for configuring UART RX DMA in circular mode properly?
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();
}