STM32H7 USART RX with FIFO - not working
Dear experts,
I'm trying to receive continuously from a USART with interrupts.
For some reason I don't want to use DMA (the Tilen Majerle's DMA example on github works well, though)
So I'm enabling RX FIFO and Receive timeout (RTO) for receiving less than FIFO threshold.
Then, loss of data occurs. Many sent bytes are not received in the ISR.
Without RX FIFO threshold interrupt + RTO; only with RXNE interrupt; RX works well as expected.
Does anybody have idea what is missing for RX FIFO threshold interrupt?
Below are two variants : with only RXNE interrupt (working) and with RXFTIE + RTO interrupts (failing).
Note that in both cases the FIFO mode is enabled, and any RX errors are ignored.
I've tried to reproduce the logic from the HAL UART driver, HAL_UART_Receive_IT.
Cannot use this function as is because need continuous RX (unlimited size) .
// INIT
void UART_init(UART_HandleTypeDef *pu, USART_TypeDef *U)
{
pu->Instance = U;
pu->Init.BaudRate = baud_rate;
pu->Init.WordLength = UART_WORDLENGTH_8B;
pu->Init.StopBits = UART_STOPBITS_1;
pu->Init.Parity = UART_PARITY_NONE;
pu->Init.HwFlowCtl = UART_HWCONTROL_NONE;
pu->Init.Mode = UART_MODE_TX_RX;
pu->Init.OverSampling = UART_OVERSAMPLING_8;
pu->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT;
pu->AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
if (HAL_UART_Init(pu) != HAL_OK)
Error_Handler();
HAL_UARTEx_SetTxFifoThreshold(pu, UART_TXFIFO_THRESHOLD_3_4);
HAL_UARTEx_SetRxFifoThreshold(pu, UART_RXFIFO_THRESHOLD_1_2);
if (HAL_UARTEx_EnableFifoMode(pu) != HAL_OK)
{
Error_Handler();
}
SET_BIT(U->CR1, USART_CR1_RXNEIE);
HAL_NVIC_SetPriority(USART_X_IRQn, USART_X_IRQ_PRIO_UART, 0);
HAL_NVIC_EnableIRQ(USART_X_IRQn);
}
// ISR
void USART1_IRQHandler()
{
USART_TypeDef *Instance = USART1;
uint32_t isrflags = READ_REG(Instance->ISR);
while ((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
{
uint32_t udata = READ_REG(Instance->RDR);
usart_rx_handler(udata); // consume data
isrflags = READ_REG(Instance->ISR);
}
}FIFO variant - failing:
// INIT
void UART_init(UART_HandleTypeDef *pu, USART_TypeDef *U)
{
pu->Instance = U;
pu->Init.BaudRate = baud_rate;
pu->Init.WordLength = UART_WORDLENGTH_8B;
pu->Init.StopBits = UART_STOPBITS_1;
pu->Init.Parity = UART_PARITY_NONE;
pu->Init.HwFlowCtl = UART_HWCONTROL_NONE;
pu->Init.Mode = UART_MODE_TX_RX;
pu->Init.OverSampling = UART_OVERSAMPLING_8;
pu->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT;
pu->AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
if (HAL_UART_Init(pu) != HAL_OK)
Error_Handler();
HAL_UARTEx_SetTxFifoThreshold(pu, UART_TXFIFO_THRESHOLD_3_4);
HAL_UARTEx_SetRxFifoThreshold(pu, UART_RXFIFO_THRESHOLD_1_2);
if (HAL_UARTEx_EnableFifoMode(pu) != HAL_OK)
{
Error_Handler();
}
HAL_UART_ReceiverTimeout_Config(pu, 4 *10); // RTO, in bit times ~ 4 bytes
HAL_UART_EnableReceiverTimeout(pu);
SET_BIT(U->CR3, USART_CR3_RXFTIE);
SET_BIT(U->CR1, USART_CR1_RTOIE);
// Clear pending things:
U->ICR = UART_CLEAR_RTOF;
HAL_NVIC_SetPriority(USART_X_IRQn, USART_X_IRQ_PRIO_UART, 0);
HAL_NVIC_EnableIRQ(USART_X_IRQn);
}
// ISR
void USART1_IRQHandler()
{
USART_TypeDef *Instance = USART1;
uint32_t isrflags = READ_REG(Instance->ISR);
if (isrflags & USART_ISR_RTOF) {
Instance->ICR = UART_CLEAR_RTOF;
}
// no way to clear RXFT ineterrupt?
while ((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
{
uint32_t udata = READ_REG(Instance->RDR);
usart_rx_handler(udata); // consume data
isrflags = READ_REG(Instance->ISR);
}
}*** ADDED ***
Debugging shows that the RXFT interrupt is never activated. Only RTOF interrupt is activated.
If I don't enable RTOIE, no interrupts occur.
What is missing to get interrupts from RXFT?

