On an LPC1769, reading the LPC_UART0->IIR clears the RBR register

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

On an LPC1769, reading the LPC_UART0->IIR clears the RBR register

368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Fklein23 on Fri Oct 10 06:58:51 MST 2014
I added UART0 to my UART interrupt handler, and the code is virtually the same as your quoted code (the variables are even named the same).
The handler for all 4 UARTS start the same (usual) way:

IIRValue = LPC_UART0->IIR;

IIRValue >>= 1; /* skip pending bit in IIR */
IIRValue &= 0x07; /* check bit 1~3, interrupt identification */
if ( IIRValue == IIR_RLS ) /* Receive Line Status */
{  ...
   rbr_value = LPC_UART0->RBR   // the program NEVER gets here for reasons explained below.
   ...

... and so on...

Here is the strange thing I am seeing. This instruction: "IIRValue = LPC_UART0->IIR;" clears the RBR register!!!!

Without breakpoints, the symptom is that the transmit functionality works perfectly, but the receive function doesn't do ANYTHING.
I can see the character sent by the terminal on the oscilloscope, the interrupt fires, but no characters appear in the application's input channel.
WITH breakpoints, I stopped the IRQ handler at this instruction and before reading the IIR register, my watch window shows

LPC_UART0->IIRconst volatile uint32_t196
LPC_UART0->RBRconst volatile uint8_t85 'U'

Then after a single step through THIS instruction: "IIRValue = LPC_UART0->IIR;"

Now my watch windows look like this:

LPC_UART0->IIRconst volatile uint32_t193
LPC_UART0->RBRconst volatile uint8_t0 '\0'

Note that not only does the RBR register get cleared, but the
I have tried several workarounds, because I was concerned that the very existence of the watch window, which displayed the value of the RBR register, might have caused the actual register to clear as if my program had read it. (I get paranoid about stuff like that after 30 years of living with the "errata" of the microprocessor world! :-)

Note not only does the RBR register get cleared by reading the IIR register, but the RX data available bit ALSO clears in the IIR register after reading it.

So I put the "read RBR"  instruction BEFORE the "read IIR" register and set a breakpoint AFTER both instructions. I then hit a key on the terminal and rbr_value was ZERO!  ????????

I am not sure what to do. The interrupt handler is straight out of the "LPC_17xx bible", chapter and verse, and I was assured by my colleagues here that the same handler, when aimed at UART2 works flawlessly.

So my next step is to rewire the breadboard temporarily, to use UART2 instead of UART0 and try the same experiment and see what happens in the UART2 IRQ handler (which is identical to the UART0 handler).

I wonder if UART0 has some known quirks that make it different that UART2 and 3. I know that 0,2 and 3 are different than UART1, but the same method should work for AT LEAST UART0 and 2.

Any thoughts?
Anyone else ever seen this?

Thanks - Frank

Labels (1)
0 Kudos
1 Reply

299 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Fklein23 on Fri Oct 10 13:14:00 MST 2014

I discovered the problem and the root cause was not the UART, as such.
The problem was an Eclipse issue.

1. We do not create projects from scratch, we use import and export
2. I had a workspace that contained three projects:
    a. My application
    b. The CMSISv2p00_LPC17xx library code (not as a library, but as statically linked code)
    c. A modification of the CMSISv2p00_LPC17xx library that we use as "common code" for all of our projects
3. The original CMSIS code is deprecated and superceded by out modified version.
4. I had the deprecated code in a CLOSED project in my workspace.

I kept noticing a warning message that came up during the first phase of the project build, that disappeared and was overwritten on the IDE output window by warnings during the second phase of the build.

So I hit the cancel button during phase 2 and was able to read the warning. (It took multiple tries, because the compiler/linker is pretty persistent!)
The warning said: "Invalid project path: Duplicate path entries found (/CMSISv2p00_LPC17xx [Include path] isSystemInclude:true includePath:C:/ [... etc., ... ] pathentryPath Entry Problem"

Since CMSISv2p00_LPC17xx was closed, and I did not specify the deprecated include locations in the build properties, I thought maybe the problem might be related to the old code somehow getting linked in and causing conflicts. So I deleted the deprecated library code and tried to build...

The result was that the warning now escalated to an error that prevented the axf file being built. The new error was much more pointed. Now it said that it could not FIND -ICMSISv2p00_LPC17xx

What to do?  I then did a search of my .cproject file and found that there were multiple options blocks that mentioned CMSISv2p00_LPC17xx.
I deleted all those options blocks and then I rebuilt the code and the receive IRQ worked.

0 Kudos