Hi all, I have a problem with USART interrupts, it is the first time I use them, I would also appreciate if someone could tell me where I can find some information about them.
I am using a LPC55SS14.
I am trying to receive data from an external device to the micro via the USART interrupt method. I have followed NXP examples and it did not work for me.
The problem is as follows: The MCU is detecting the interrupt, what happens is that it goes through it 3 or 4 times having only received one interrupt. I think it may be because it is not able to read all the information coming from the port, I am receiving 5 bytes, I have tried different ways but I have not been able to find the solution for the moment.
Another curious fact that I think is important to mention is that if I put a breakpoint in the first lines of the interrupt, it only enters it once and it does it correctly, however, if I put the breakpoint at the end of the interrupt instead of at the beginning, the failure mentioned above is repeated.
I have also used different read methods, USART_ReadBlocking, USART_ReadByte....
Attached is the code part of the interrupt.
Thank you very much.
Best regards.
/* FLEXCOMM2_IRQn interrupt handler */
void FLEXCOMM2_FLEXCOMM_IRQHANDLER(void)
{
uint8_t data[5];
if ((kUSART_RxFifoNotEmptyFlag | kUSART_RxError) & USART_GetStatusFlags(FLEXCOMM2_PERIPHERAL))
{
//
data [0] = USART_ReadByte(FLEXCOMM2_PERIPHERAL);
data [1] = USART_ReadByte(FLEXCOMM2_PERIPHERAL);
data [2] = USART_ReadByte(FLEXCOMM2_PERIPHERAL);
data [3] = USART_ReadByte(FLEXCOMM2_PERIPHERAL);
data [4] = USART_ReadByte(FLEXCOMM2_PERIPHERAL);
}
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
// SDK_ISR_EXIT_BARRIER;
vTaskNotifyGiveFromISR(_tskHandleCntDh, &tskWoken);
SDK_ISR_EXIT_BARRIER;
}
Hi, Nadia,
As you know that USART module has only one interrupt vector, mutiple interrupt trigger sources share the same interrupt vector. So in the ISR, you have to poll the trigger source and take action.
For the receiver of USART, it uses FIFO to receive data, so in the ISR, you can check how many bytes have been received, then read them.
uint8_t index;
/* FLEXCOMM2_IRQn interrupt handler */
void FLEXCOMM2_FLEXCOMM_IRQHANDLER(void)
{
uint8_t data[5];
uint8_t receiveByteNumber;
receiveByteNumber=(USART2->FIFOSTAT>>16)&0x1F;
while(receiveByteNumber)
{
data [index] = USART_ReadByte(FLEXCOMM2_PERIPHERAL);
receiveByteNumber--;
}
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
// SDK_ISR_EXIT_BARRIER;
vTaskNotifyGiveFromISR(_tskHandleCntDh, &tskWoken);
SDK_ISR_EXIT_BARRIER;
}
For the usart status register, pls refer to the table in UM11295.pdf
Hope it can help you
BR
XiangJun Rong
Ok, but if I disable the interrupt, how can I empty the buffer, so that when I enable it again it starts from zero?
I generate an external interrupt, and what I do is read the data sent to me by the interrupt, but I only want to read it once, until I finish a process and re-enable that interrupt reading, and when this happens, I want that buffer to be empty and not read interrupts that have been generated previously.
Hi,
I think when you read the receiver, you have to check the FIFO status register and guarantee there is data in the receiver FIFO.
If you want to empty the receiver FIFO, you can set the EmptyRX bit in the configuration register.
Hope it can help you
BR
Xiangjun Rong
Hi,
You can set the EMPTYRX bit with the code:
If you use USART0, you can use the code:
USART0->FIFOCFG|=USART_FIFOCFG_EMPTYRX(1);
or
USART0->FIFOCFG|=1<<17;
If you use USART1, you can use the code:
USART1->FIFOCFG|=USART_FIFOCFG_EMPTYRX(1);
or
USART1->FIFOCFG|=1<<17;
Hope it can help you
BR
XiangJun Rong