Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: Questions on the UART Interface

2004-11-17 by Karl Olsen

--- In lpc2000@yahoogroups.com, "Leighton Rowe" <leightonsrowe@y...> 
wrote:
> 
> Just for clarification on the UART Block Diagram (see UM)...
> 1. Do U0TSR & U0RSR actually representthe Tx & Rx FIFO buffers? I 
> only see U0TSR & U0RSR illustrated here and I can't find any other 
> documentation for it.

No, they are the actual shift registers.  U0TSR can be checked with 
U0LSR bit 6, TEMT.  TEMT=0 => U0TSR is shifting out a byte, TEMT=1 => 
U0TSR is idle.  The 16-byte FIFOs aren't shown in the figure, but 
would rather correspond to U0THR and U0RBR.  For better 
documentation, Google for 16C550.

 
> Now concerning U0THR & U0RBR (data registers)...
> 2. Why do they both share the same memory address? I'd really like 
> to know the purpose of this.

Writing to the address means writing to U0THR, and reading from the 
address means reading from U0RBR.  They occupy the same address 
because Philips chose to be software compatible with the 16C550, 
which was designed to be hardware and software compatible with the 
8250, which was designed at a time when I/O addresses apparently were 
very precious.  For an even worse example of this mindset, see the 
Intel 8259 interrupt controller which occupies two(!) I/O addresses.
 

> 3. What will happen if the lpc receives a character while I'm 
> writing to the transmit register?

Nothing special, the receiver and transmitter work independently.  
But make sure that you don't miss any of them in your interrupt 
handler.


> I ask this because currently, I'm having trouble running the serial 
> port both ways (with interrupts) while sending replies and 
receiving 
> command packets from the PC. Sometimes the protocol I'm using 
works. 
> However, while debugging I always notice the lpc losing receiver 
> bytes whenever communication goes wrong. I only observe this 
> happening if the lpc's replying to a command packet and another 
> command packet's coming in the same time.

When you enable more than one interrupt in U0IER (such as both 
receive and transmit interrupt), you should in your interrupt handler 
check U0IIR to see what caused the interrupt.  More than one 
interrupt can occur at a time, and the highest priority one is 
indicated in U0IIR.

Pay close attention to the "Interrupt Reset" column in the UART0 
Interrupt Handling table.  When you have seen in U0IIR what caused 
the interrupt, you should handle it, and then do the action in 
the "Interrupt Reset" column to tell the UART that you have handled 
it.  For a receive interrupt, the Interrupt Reset action is to 
read U0RBR, so it is a quite normal part of handling a receive 
interrupt.  For a transmit interrupt, the reset action is simply 
reading U0IIR, which you have already done since you know it is a 
transmit interrupt.

If you don't do the Interrupt Reset action in your interrupt handler 
for a pending interrupt, the UART will immediately interrupt again.  
So you can write your interrupt handler in two ways:

a. Check U0IIR, handle the highest-priority pending interrupt, 
thereby doing the Interrupt Reset action, and return.  If more than 
one interrupt was pending, the UART will immediately interrupt again, 
and then present the next-highest priority interrupt in U0IIR, and so 
on.  This way is the easiest, and the best one if multiple 
simultaneous interrupts are rare.

b. Check U0IIR, handle the highest-priority pending interrupt, 
thereby doing the Interrupt Reset action.  Re-check U0IIR, and loop 
around if another interrupt is pending.  When no more interrupts are 
pending, return.  This way is better if multiple simultaneous 
interrupts are so likely that it pays off to save the multiple 
interrupt entry/exit code.


Regards,
Karl Olsen

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.