Continuous UART Character Timeout Interrupts (CTI) but not characters in FIFO

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

Continuous UART Character Timeout Interrupts (CTI) but not characters in FIFO

4,089 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gregd on Thu Apr 09 09:51:02 MST 2015
There appears to be a problem with the UART driver in LPCOpen version 2_12, 2_16 and probably previous versions also.

This problem was seen on the LPC4350 but also seems to be occurring on other LPC microcontrollers according to internet searches.  See the following link for info:
http://www.embeddedrelated.com/showthread/lpc2000/24824.php

There seems to be a condition with the LPC4350 (and other LPC microcontrollers) where you can receive Character Timeout Interrupts (CTI) even when there are no characters in the receive FIFO.  This causes a continuous repeated interrupt which appears to lock up the application with the LPCOpen code.

Here are the details of what is happening:

A UARTx_IRQ is triggered.
The LPC_USARTx->IIR register indicates a UART_IIR_INTID_CTI interrupt.
The Chip_UART_IRQRBHandler function calls Chip_UART_RXIntHandlerRB.
Chip_UART_RXIntHandlerRB calls Chip_UART_ReadLineStatus but the UART_LSR_RDR bit is not set so Chip_UART_ReadByte is not called, this results in the CTI flag never being cleared.  The interrupt is continuously triggers as soon as it exits the handler and never allows normal application execution.

The solution presented in internet link above, always reads a character from the FIFO even if the RDR bit is not set in the line status register so that the CTI interrupt is cleared.  This seems to solve the problem but I have a concern with the logic:

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.

My concern is what would happen if a character is actually received in the UART and written to the FIFO between steps 1 and 2 above.  The character would be missed and not processed since the RDR flag was not set when read in stop 1.


Are there any suggestions for solving this problem?  LPCOpen needs to be modified to fix this issue as well. I believe the interrupt and blocking versions of the UART driver in LPCOpen all have this same problem.


Thanks,
Greg Dunn





Labels (1)
0 Kudos
5 Replies

1,676 Views
funbotix
Contributor I

The code I jump to from the bootstrap loader is tiny and merely sets a variable and branches to where the reset vector normally starts code execution from. There's nothing special, tricky, or extensive in it. If I start up with the BOOT pin high, everything works great. Otherwise, when I eventually enable the USART0 receive data ready interrupt the character timeout interrupt starts and remains active forever. There does not appear to be any way to clear it. Is there anyone out there who interacts with the bootstrap loader like this with an LPC11U68 that doesn't have this problem, or who figured out how to clear this interrupt? Thanks for any help with this.

0 Kudos

1,683 Views
funbotix
Contributor I

Note that the bootstrap loader interaction is quite minimal, and is used merely to jump (GO command) to a specific address to set a value in memory and then branches to where the RESET vector goes to normally to execute the startup code. So, all the initialization is identical (other than writing one value to memory first) whether the BOOT pin is high or low on startup. So, I'm certain that there's no odd-user-code thing happening due to this tiny piece of code that gets branched to [when the user wants to start manufacturing test mode]. I didn't see any chip errata that mentions this bug, but it seems like there should be (and a workaround provided for it).

0 Kudos

2,405 Views
roberthulsebos
Contributor I

We have a similar problem with some LPC1769 devices. Not all of them. In a debug session, after restarting a device using the 'Restart' button on the toolbar of MCUXpresso, the device ends up in an loop of eternal interrupt handling for either a serial port device or the CAN bus controller. The interrupt sources it self are bogus, as for example nothing is transmitted to the serial port. (Rx, Tx lines verified with scope)  Once the device is in such a state, then the only way to get it out is by hard resetting the device (power cycle or issuing the WIRETIMEDRESET reset command on the RedlinkServer console) - trying another restart with the 'Restart' button will not help... Note that most devices do not have this behavior, but the ones that do are very persistent in it. NXP: Is this a known problem?  Additional note: On advise from other developers, I already tried setting following debug options: Reset Handling = SYSRESETREQ, Semihosting support = Off, Vector catch = True. But this does not seem to help...

0 Kudos

2,405 Views
roberthenderson
Contributor I

I discovered this problem with continuous repeating CTI interrupts during embedded testing. I tried the fix suggested above, read LSR and RBR every time the UART IRQ fires. That did not solve the problem in all cases. Through trial and error I discovered that reading the Interrupt Identification register (IIR) every time the UART IRQ fires did prevent the continuous repeating CTI interrupts in all of our test cases. Other scenarios may exist where this method does not work.

0 Kudos

1,701 Views
funbotix
Contributor I

I have the same problem with my LPC11U68 based board, although only in a certain scenario. If I power up my board with the BOOT pin high (normal start mode) I do not have have this problem. However, if I power up with the BOOT pin low and interact with the built-in bootstrap loader I do have the problem. Worse, none of the above fixes make the problem go away. Basically, as soon as I clear then enable the USART0 interrupt the USART ISR gets stuck in a loop where the interrupt ID is 6 (character timeout) and nothing I do actually clears this interrupt so that the ISR will stop triggering. I too have used an o-scope to verify that the RX line is stable in the mark state. For debug, I decided to read the IIR, LSR, MSR, and RBR every time the ISR is vectored to, but even that won't clear this interrupt. Can anyone provide some guidance to help me resolve this?

P.S. I'm using the bootstrap loader interaction to allow my app to know which way it started (normal reset, or bootstrap loader interaction) to make my app act in a special way when started via the bootstrap loader (i.e., to enable manufacturing test mode). We use this technique on a variety of ARM Cortex M based boards, but this is the only one that has this behavior. It's also the first LPC11U68 board we've tried this on.

0 Kudos