Skip to main content
ECarr.1
Associate
September 16, 2021
Solved

LL_USART_EnableIT_RXNE_RXFNE() not setting the flags correctly

I am basing an application of off the LoRaWAN_AT_Slave_DualCore_CM4. I'm currently working on adding USART1 into the application and have successfully used LL_USART_TransmitData8() to transmit data from the MCU.

I'm running into a weird behavior that I can't explained. I'm calling the following function every seconds:

void GPS_routine(GPS_data *gpsData, uint8_t *GPS_fix, uint16_t currSeconds)
{
 static uint8_t GPS_activeRx = false;
 
 if (!(*GPS_fix))
 {
 if (currSeconds > GPS_TIMEOUT_SEC)
 {
 if (GPS_activeRx){
 GPS_activeRx = false;
// GPIO_setOutputHighOnPin(nGPS_ON_PORT, nGPS_ON_PIN); // Turn off GPS
 LL_USART_DisableIT_RXNE_RXFNE(USART1);
 }
 } // if (GPS_TIMEOUT_SEC > secondsCtr)
 
 else if (currSeconds > GPS_START_SEC)
 {
 if (!GPS_activeRx){
 GPS_activeRx = true;
 LL_USART_EnableIT_RXNE_RXFNE(USART1);
// LL_USART_EnableIT_RXNE_RXFNE(USART1);
 }
 
 *GPS_fix = GPS_aquireData(gpsData);
 
 if (*GPS_fix){
// GPIO_setOutputHighOnPin(nGPS_ON_PORT, nGPS_ON_PIN); // Turn off GPS
 LL_USART_DisableIT_RXNE_RXFNE(USART1);
 }
 } // else if (secondsCtr > GPS_START_SEC)
 } // if (!GPS_fix)
}

For some reason the USART1 RX ISR is not being triggered:

if(LL_USART_IsActiveFlag_RXNE(USART1) && LL_USART_IsEnabledIT_RXNE(USART1))
	 {
	 /* RXNE flag will be cleared by reading of RDR register (done in call) */
	 /* Call function in charge of handling Character reception */
	 UART_CharReception_Callback();
	 }

The ONLY way I can make the ISR for RX USART1 to work is to call LL_USART_EnableIT_RXNE_RXFNE() twice:

if (!GPS_activeRx){
 GPS_activeRx = true;
 LL_USART_EnableIT_RXNE_RXFNE(USART1);
 LL_USART_EnableIT_RXNE_RXFNE(USART1);
 }

If I only call it once, the Rx ISR never gets called. I thought that maybe the RXNE isn't cleared, so I also tried:

LL_USART_ReceiveData8(USART1);
LL_USART_EnableIT_RXNE_RXFNE(USART1);

Thinking maybe the RXNE needs to be cleared first, but it still doesn't work. The only way I can get it to to work is by either calling LL_USART_EnableIT_RXNE_RXFNE() in main OR calling twice in the gps_routine:

LL_USART_EnableIT_RXNE_RXFNE(USART1);
LL_USART_EnableIT_RXNE_RXFNE(USART1);

Why is this the case? Optimization is turned off, so the compiler is not optimization it out.

This topic has been closed for replies.
Tesla DeLorean
Tesla DeLoreanBest answer
Guru
September 16, 2021

I wouldn't bother with all the qualification and callback stuff, and instead put a check in the IRQ Handler for the error flags within the status register, and then explicitly clear them.

In any case you should check the status register to see what's flagging

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..

3 replies

Tesla DeLorean
Guru
September 16, 2021

Probably is interrupting, but is flagging some overflow or noise error, which is not being properly cleared/handled.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
ECarr.1
ECarr.1Author
Associate
September 16, 2021

Thanks for your suggestion, I know I can just call LL_USART_EnableIT_RXNE_RXFNE() twice and move on with my life, but that doesn't really add value towards me becoming a better embedded engineer.

Regarding your point, I set up UART_Error_Callback() in my stm32wlxx_it.c source and put a breakpoint for the UART_Error_Callback():

if (!GPS_activeRx){
 GPS_activeRx = true;
 LL_USART_EnableIT_RXNE_RXFNE(USART1);
 LL_USART_EnableIT_ERROR(USART1);
// LL_USART_EnableIT_RXNE_RXFNE(USART1);
 }

if(LL_USART_IsEnabledIT_ERROR(USART1) && LL_USART_IsActiveFlag_NE(USART1))
	 {
	 /* Call Error function */
	 UART_Error_Callback();
	 }

But it seems the system never enters this callback. Is there somewhere else I should be looking for error flags?

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
September 16, 2021

I wouldn't bother with all the qualification and callback stuff, and instead put a check in the IRQ Handler for the error flags within the status register, and then explicitly clear them.

In any case you should check the status register to see what's flagging

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..