cancel
Showing results for 
Search instead for 
Did you mean: 

UART fired only once - STM32U5 Custom Board

TV79
Associate II

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

 

If I execute the code above, the interrupt is fired only once. I can read text back on my terminal but I never gets executed again.
1 ACCEPTED SOLUTION

Accepted Solutions
Karl Yamashita
Lead III

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

 

 

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

View solution in original post

5 REPLIES 5
Bob S
Principal

Implement a HAL_UART_ErrorCallback() function and see if that ever gets called.  If so, see what error flag gets set.

Karl Yamashita
Lead III

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

 

 

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
TV79
Associate II

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

 

 

 


@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"