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