Yahoo Groups archive

Lpc2000

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

Message

UART TX FIFO and INTs problem

2004-02-17 by forum_microbit

Hi all,
 
[I'm reposting on the URL, the new lpc2000 address doesn't seem to wor

I'm a bit stuck with this one, and hope someone has some advice,
I must be overlooking something and I just don't see it.......
 
I'm using Two 256 byte circular buffers for RX and TX Interrupts on 
UART0.
 
Putchar() writes a char to the TX buffer's current head pointer and 
post increments it (auto wrap on index byte). It then increments the 
# of TX chars in the buffer (tx_chars) and enables the THRE Interrupt.
 
The THRE handler part takes a character from the tail pointer, and 
post increments. It then decrements tx_chars.
If TX buffer tail equals TX buffer Head, the THRE Interrupt is 
disabled.
 
Of course in case I write too fast to the TX buffer and it overflows 
(to simplify for the time being) at the end of Putchar() I check if 
tx_chars is larger than say, 200 Chars.
If it is, I wait in a while loop for tx_chars to drop below a 
threshold, say 32.
 
I've used this principle on many MCUs, and never had a problem.
 
The problem is that if I write a _constant_ flow of characters much 
faster than the Baudrate after quite some time the transmission INTs 
stop. [ NO other interrupts are running during this test ]
To test it, I set a pin HIGH when Putchar() is waiting for the TX 
buffer to empty a bit, and clear it when buffer filling resumes - a 
bit like this :
 
volatile unsigned char tx_chars;
 
.....                            /* write char to buffer */
++tx_chars ;                     /* another char in TX buffer */
if ( tx_chars > 200 )
    {    
    /* set test pin HIGH */    
    while ( tx_chars > 32 ) ;    /* let TX buffer flush out a bit */
    }
/* set test pin LOW */
}
 
I can see all is fine, the TEST pin spends time HIGH while the buffer 
is being flushed, and is then LOW for a few mS (printf() is re-
filling up the buffer from 32 or less to > 200 chars)
 
When the transmit out of UART0 TX stops, tx_chars is set to one more 
than the threshold (for example - here 33 ), and Tail and Head 
Pointer of TX buffer are equal, hence the THRE interrupt is disabled.
The code of course is stuck in the while ( tx_chars > 32 ) loop ......
 
A plausible explanation would be that at times, the TX FIFO holds 
more than one byte, and when the THRE interrupt occurs, more than one 
char should be subtracted from tx_chars.
This could explain why tx_chars isn't <Zero> when TX Head and TX Tail 
become equal and THRE INTs turn OFF.
On the other hand this doesn't make sense, as the TX FIFO should be 
transparent to that process. Also, if this was a simple FIFO issue, 
that process should lock up after a few hundred characters are 
transmitted.
 
There is nothing in the user guide on LPC2106 that clarifies how 
exactly the TX FIFO and the THRE interact.
Although the guide says that FIFOs should be enabled for proper UART 
operation, leaving U0FCR to ZERO makes no difference, nor does 
changing the FIFO trigger level (again wording is ambiguous here, 
left column implies RX FIFO only , right column bitmap implies both 
RX and TX FIFOs.
 
In fact I don't see the point of the TX FIFO if your THRE/TEMT can't 
tell you whether you just flushed out 1 or <trigger level> bytes.
 
Is anyone seeing what the problem is ?
I'm stumped.
 
Best regards,
Kris

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.