USART silicon errata? CTI w/o RDR

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

USART silicon errata? CTI w/o RDR

1,144 Views
conurus
Contributor I

It's a rare occurrence on a LPC11U35FHI33. IIR (the interrupt reason register) says UART interrupt is owing to CTI (character time-out), but LSR (line status register) is all zero. My ISR ends up in an infinite loop, because it reads the Rx FIFO only if the data ready bit is set, but there is nothing to read here as the Rx FIFO is empty. CTI won't clear without reading the Rx FIFO, so it keeps on reasserting the interrupt endlessly.

On the surface this seems something impossible to happen. If Rx FIFO is empty why can't CTI de-assert itself? Right now I (think I) have a workaround by reading Rx FIFO anyway even if it is empty, if it is a CTI and LSR says no data is ready.

Labels (1)
0 Kudos
2 Replies

714 Views
funbotix
Contributor I

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();
}
0 Kudos

853 Views
isaacavila
NXP Employee
NXP Employee

Hello,

It seems to be a familiar error where CTI will be set eventhough there is no data on Rx FIFO. This post also has a similiar issue and it recommends to read Rx FIFO (in order to clear CTI) no matter if LSR register specifies no received data: Continuous UART Character Timeout Interrupts (CTI) but not characters in FIFO | www.LPCware.com 

Solution basically implements:

  1. Read the line status register into a variable.
  2. Read character from the FIFO into a variable (even if RDR is not set so that CTI is cleared).
  3. If the RDR flag is set in the line status variable then the saved character is processed (stored in the ring buffer etc...) and we go back to step 1 and repeat to empty FIFO.
  4. If the RDR flag was not set then exit the loop.

I hope this can help you!

Regards,

Isaac

0 Kudos