AnsweredAssumed Answered

LPC1768 UART1 Interrupt not firing

Question asked by Exequiel Beker on Jan 11, 2018

Hi folks!

I'm working with UART communication between LPC1768 and a terminal antenna, at 115200 bps (8bits -Parity none-1 stop bit) though UART1 port.

I'm interfacing the UART line with a LTC2851 transceiver.

 

In some point of the communication, due the transmission speed, perhaps, the MCU starts receiving some corrupted bytes. Sometimes, but just sometimes, UART peripheral reports Framing Error and data is correctly discarded.

After that, after a few cycles of bad-received data, Interrupts for UART1 stops firing, and no data is readed until a power on reset (Software reset doesnt seems to help). 

I checked the peripheral registers, and still enabled when data is suppose to arrive (using an oscilloscope in the Rx pin).

 

This is my interrupt code:

 

 

void UART1_IRQHandler()
{
uint8_t read_byte, count;
uint8_t IIR_value, LSR_value;

CoEnterISR(); /* Enter the interrupt */

/* reading IIR register will clear the interrupt flags */
IIR_value = UART1->IIR;
/*-------------------------------*/
/* Receive Line Status interrupt */
/*-------------------------------*/
if ((IIR_value & IIR_RLS) == IIR_RLS)
{
/* reading the LSR register will clear the interrupt flag
and error bits */
LSR_value = UART1->LSR;
if (LSR_value & (LSR_RXFE|LSR_BI|LSR_FE|LSR_PE|LSR_OE))
{
/* There's, at least, one error bit set */
uart_lines[UART1_ID].line_status |= (LSR_value & (LSR_BI|LSR_FE|LSR_PE|LSR_OE));
while (LSR_value & LSR_RXFE) {
/* watchdog */
//os_feed_wdt();

/* Dummy reads on RX to discard the corrupted bytes */
read_byte = UART1->RBR;
LSR_value = UART1->LSR;
}
}
}
/*--------------------------------------------------------*/
/* Is it a data received or character time-out interrupt? */
/*--------------------------------------------------------*/
else if ((IIR_value & IIR_RDA) == IIR_RDA || (IIR_value & IIR_CTI) == IIR_CTI)
{
/* The RDA is activated when the UARTn Rx FIFO reaches the
trigger level. The CTI is set when the UART0 Rx FIFO contains
at least one character and no UARTn Rx FIFO activity has
occurred in 3.5 to 4.5 character times. */

LSR_value = UART1->LSR;
/* Check (and clear) FIFO overrun error */
uart_lines[UART1_ID].line_status |= (LSR_value & LSR_OE);

/* Repeat until receiver FIFO is empty */
count = 0;
while (LSR_value & LSR_RDR) {
/* watchdog */
//os_feed_wdt();

/* Get errors */
uart_lines[UART1_ID].line_status |= (LSR_value & (LSR_BI|LSR_FE|LSR_PE));
/* Get byte */
read_byte = UART1->RBR;

/* if the queue is full, don't increment the in index */
if (((uart_lines[UART1_ID].in + 1) % INPUT_QUEUE_MASK) == uart_lines[UART1_ID].out)
{
uart_lines[UART1_ID].line_status |= U_ST_CQOE; /* Overrun Error */
}
else
{
uart_lines[UART1_ID].ibuf[uart_lines[UART1_ID].in] = read_byte;
uart_lines[UART1_ID].in = (uart_lines[UART1_ID].in + 1) % INPUT_QUEUE_MASK;
}

count++;
LSR_value = UART1->LSR;
}
/* Increment the semaphore. This tells the task that the incoming bytes have been read. */
isr_PostSem(uart_lines[UART1_ID].semRx, count);
}
/*---------------------------------*/
/* Is it a transmission interrupt? */
/*---------------------------------*/
else if ((IIR_value & IIR_THRE) == IIR_THRE)
{
fill_output_fifo(UART1_ID, 16);

if (uart_lines[UART1_ID].olen == 0) /* All bytes transmitted? */
{
/* disable transmission interrupt */
UART1->IER &= ~IER_THRE;

/* Release the semaphore.
This tells the task that its output buffer has been
copied to the uart fifo. */
isr_PostSem(uart_lines[UART1_ID].semTx, 1);
}
}

CoExitISR(); /* Exit the interrupt */
}

 

Do you have any clue for this behaviour?

 

My best regards,

 

Exequiel Beker.

Outcomes