2024-06-05 09:42 AM - last edited on 2024-06-05 02:33 PM by Tesla DeLorean
Hello,
I'm working with an STM32U5 custom board.
I use the LPUART1 to read input with an interrupt as shown below and to write it back on the same LPUART1 :
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_GPIO_TogglePin (GPIOA, GPIO_PIN_8);
HAL_UART_Transmit_IT(huart, (uint8_t *)aRxBuffer, 10);
HAL_UART_Receive_IT(huart, (uint8_t *)aRxBuffer, 10);
}
Solved! Go to Solution.
2024-06-05 02:18 PM
You don't check the HAL status when you call HAL_UART_Receive_IT
If it returns HAL_BUSY, then you'll never get another interrupt.
Avoid doing any non crucial stuff from inside the interrupt. Just set a flag and exit the interrupt. Then in the main while loop you can check the flag and do what you need to do.
Below is an example for checking HAL status for Rx. I didn't write code for checking the HAL status for the HAL_UART_Transmit_IT as I have a ring buffer that does check it. If you need an example of that, I have a project on Github that you can look at.
#include "main.h"
extern UART_HandleTypeDef hlpuart1;
uint8_t aRxBuffer[10];
bool dataRdyFlag = false;
HAL_StatusTypeDef hal_status;
// call before main while loop
void PollingInit(void)
{
UART_EnableInt();
}
// called from inside main while loop
void PollingRoutine(void)
{
UART_CheckRdyFlag();
UART_CheckRxStatus();
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &hlpuart1)
{
dataRdyFlag = true;
UART_EnableInt();
}
}
void UART_CheckRdyFlag(void)
{
if(dataRdyFlag)
{
dataRdyFlag = false;
HAL_UART_Transmit_IT(&hlpuart1, (uint8_t *)aRxBuffer, 10);
}
}
void UART_EnableInt(void)
{
hal_status = HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)aRxBuffer, 10);
}
void UART_CheckRxStatus(void)
{
if(hal_status != HAL_OK)
{
UART_EnableInt();
}
}
2024-06-05 10:07 AM
Implement a HAL_UART_ErrorCallback() function and see if that ever gets called. If so, see what error flag gets set.
2024-06-05 02:18 PM
You don't check the HAL status when you call HAL_UART_Receive_IT
If it returns HAL_BUSY, then you'll never get another interrupt.
Avoid doing any non crucial stuff from inside the interrupt. Just set a flag and exit the interrupt. Then in the main while loop you can check the flag and do what you need to do.
Below is an example for checking HAL status for Rx. I didn't write code for checking the HAL status for the HAL_UART_Transmit_IT as I have a ring buffer that does check it. If you need an example of that, I have a project on Github that you can look at.
#include "main.h"
extern UART_HandleTypeDef hlpuart1;
uint8_t aRxBuffer[10];
bool dataRdyFlag = false;
HAL_StatusTypeDef hal_status;
// call before main while loop
void PollingInit(void)
{
UART_EnableInt();
}
// called from inside main while loop
void PollingRoutine(void)
{
UART_CheckRdyFlag();
UART_CheckRxStatus();
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &hlpuart1)
{
dataRdyFlag = true;
UART_EnableInt();
}
}
void UART_CheckRdyFlag(void)
{
if(dataRdyFlag)
{
dataRdyFlag = false;
HAL_UART_Transmit_IT(&hlpuart1, (uint8_t *)aRxBuffer, 10);
}
}
void UART_EnableInt(void)
{
hal_status = HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)aRxBuffer, 10);
}
void UART_CheckRxStatus(void)
{
if(hal_status != HAL_OK)
{
UART_EnableInt();
}
}
2024-06-05 02:31 PM
Probably want to ponder the repercussions of sending out an active receive buffer.
As Bob indicates, you should pay attention to function return codes, and perhaps probed deeper as to what errors on the UART would preclude a second go around
2024-06-06 08:09 AM
Thank you all for taking the time to answer my question and for reminding me all these good practices.
And thank you @Karl Yamashita for the code, this is a much better approach than mine and it work like this.
I will especially focus on this advice "Avoid doing any non crucial stuff from inside the interrupt. Just set a flag and exit the interrupt. Then in the main while loop you can check the flag and do what you need to do."
Best regards
2024-06-06 08:26 AM
@TV79 wrote:I will especially focus on this advice "Avoid doing any non crucial stuff from inside the interrupt. Just set a flag and exit the interrupt. Then in the main while loop you can check the flag and do what you need to do."
It is excellent advice, and well worth paying attention to!
Also note @Tesla DeLorean's important advice: "pay attention to function return codes"