I'm working with an LPC11U68 based board and did not have the above described issue until I started work on our standard method of invoking the manufacturing test routine. Invoking manufacturing test is supposed to be extremely difficult for anyone [in the field] to accidentally do and involves using the bootstrap loader to branch to a routine that simply sets a variable and then branches to the normal startup code. The application can test this variable and execute the manufacturing test code or the normal application code. The initialization of everything on the board is common for either mode of operation.
The problem I have is that when I start via the bootloader, as soon as the normal startup code enables the USART0 RX data ready interrupt, this continuous UART character timeout problem shows up and the ISR triggers in an infinite loop. Worse, no matter how many ways I've tried to handle this problem, I can find no way to clear this flag in the IIR register, so the RX data ready interrupt is *always* active.
Interestingly, this apparent chip bug and any *official* workaround for it is not in the chip errata.
This is my ISR code. The preprocessor directives show the things I've tried. None of them work. Can anyone suggest some other thing I could try to fix this problem?
extern "C" void USART0_IRQHandler(void){
enter_critical();
uint8_t c; // for interacting with FIFO's
uint8_t * p; // for interacting with FIFO's
fifo_size_t count; // for interacting with FIFO's
bool bCTI; // tracks interrupt ID register character timeout flag
uint32_t status; // for saving status register contents
LPC_USART0_Type * pUART = LPC_USART0;
for(;;){
status = pUART->LSR;
if(((pUART->IIR & 0xE) >> 1) == 6u){ // save state of character timeout flag
bCTI = true;
}else{
bCTI = false;
}
if(bCTI){
LED_error(1);
}
c = (uint8_t) pUART->RBR;
if(status & RDR){ // receive data available?
p = &c;
count = 1;
uart[0].rxfifo->write(&p,&count); //lint !e534
#if 1
}else{
break; // error LED blinks continuously
}
#elif 0
}else if(!bCTI){
break; // error LED never turns off
}
#else
}
break; // error LED blinks continuously
#endif
}
if(status & THRE){ // transmit holding register empty?
count = 1;
if(uart[0].txfifo->read(&c, count)){
pUART->THR = c;
}else{
pUART->IER &= ~THRE_INT;
}
}
if(bCTI){ // make error LED blink
uint32_t i;
i = 300000;
while(i--);
LED_error(0);
i = 300000;
while(i--);
}
exit_critical();
}