Yahoo Groups archive

Lpc2000

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

Message

UART TX FIFO, INTs problem

2004-02-17 by microbit

Hi all,
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 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 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.