2021-09-16 12:34 PM
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.
Solved! Go to Solution.
2021-09-16 03:23 PM
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
2021-09-16 01:25 PM
Probably is interrupting, but is flagging some overflow or noise error, which is not being properly cleared/handled.
2021-09-16 01:45 PM
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?
2021-09-16 03:23 PM
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