[STM32L031G6Ux] LPUART LL ISR Routine - defense code for prevent unknown error
As follows, LL UART interrupt code with ring buffer were compose.


< stm32l0xx_it.c >
uint8_t Uart1_recvData[64];
uint8_t Uart1_sendData[64];
volatile uint8_t Uart1_sendDataSize;
volatile uint16_t Uart1_sendPush;
volatile uint16_t Uart1_sendPop;
volatile uint8_t Uart1_recvDataSize;
volatile uint16_t Uart1_recvPush;
volatile uint16_t Uart1_recvPop;
void LPUART1_IRQHandler(void)
{
/* USER CODE BEGIN LPUART1_IRQn 0 */
/* USER CODE END LPUART1_IRQn 0 */
/* USER CODE BEGIN LPUART1_IRQn 1 */
uint32_t isrflags = READ_REG(LPUART1->ISR);
uint8_t UartRDR = LL_USART_ReceiveData8(LPUART1);
WRITE_REG(LPUART1->ICR, ((uint32_t)isrflags) & (USART_ICR_PECF | USART_ICR_FECF | USART_ICR_ORECF | USART_ICR_NCF | USART_ICR_RTOCF));
if ((isrflags & USART_ISR_RXNE)) {
if (Uart1_recvDataSize < (COUNTOF(Uart1_recvData)-1)) {
if (0 == Uart1_recvDataSize) { Uart1_recvPop = Uart1_recvPush = (Uart1_recvPush % COUNTOF(Uart1_recvData)); }//fix error, problem about 1 hour with field work
Uart1_recvData[Uart1_recvPush] = UartRDR;
Uart1_recvPush = (Uart1_recvPush + 1) % COUNTOF(Uart1_recvData);
Uart1_recvDataSize++;
}
}
if ((isrflags & USART_ISR_TXE)) {
// if (Uart1_sendDataSize) {
// Uart1_sendDataSize--;
// LL_USART_TransmitData8(LPUART1, Uart1_sendData[Uart1_sendPop]);
// Uart1_sendPop = (Uart1_sendPop + 1) % COUNTOF(Uart1_sendData);
// }
// else {
// ATOMIC_CLEAR_BIT(LPUART1->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));//Disable TXEIE and TCIE interrupts
// }
}
/* USER CODE END LPUART1_IRQn 1 */
}
< main.c >
uint8_t UART1Send(uint8_t *a_pbuff, uint8_t a_len)
{
uint32_t count;
for (count = 0; count < a_len; count++) {
Uart1_sendData[Uart1_sendPush] = a_pbuff[count];
Uart1_sendPush = (Uart1_sendPush + 1) % COUNTOF(Uart1_sendData);
Uart1_sendDataSize += 1;
}
// LL_USART_EnableIT_TXE(LPUART1);
return 1;
}
int main(void)
{
/* USER CODE BEGIN 1 */
...................................
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (Uart1_sendDataSize) {
if (LL_USART_IsActiveFlag_TXE(LPUART1)) {//lpuart1 TX Send
Uart1_sendDataSize--;
LL_USART_TransmitData8(LPUART1, Uart1_sendData[Uart1_sendPop]);
Uart1_sendPop = (Uart1_sendPop + 1) % COUNTOF(Uart1_sendData);
}
}
...................................
}I don't know why, but in connection with a particular device, the ring buffer's head & tail index mismatch error was solved by adding the following if statement in the ISR function.
if (0 == Uart1_recvDataSize) { Uart1_recvPop = Uart1_recvPush = (Uart1_recvPush % COUNTOF(Uart1_recvData));
And the reason is unknown, but when the interrupt UART TX function was used using the TX function below, the first & second BYTEs were broken, so the TX function was moved to the main() function and resolved the data was broken.
// LL_USART_EnableIT_TXE(LPUART1);
I don't know if it was caused by another problem with my code,
If there is a user who can experience something similar to me,
I leave the above test results to help you.
