Yahoo Groups archive

Lpc2000

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

Message

RE: [lpc2000] UART TX FIFO, INTs problem

2004-02-18 by Musharraf Hanif

I am just wondering.... are you using GCC compiler?
if yes, from what i have heard, it is not very good in context switches.... 
ie. it can mess up when storing registers R0 to R12 in ISRs. A nice way 
arroung is to have an interrupt wrapper.

Regards,

Musharraf


>From: "microbit" <microbit@...>
>Reply-To: lpc2000@yahoogroups.com
>To: "LPC2000_group" <lpc2000@yahoogroups.com>
>Subject: [lpc2000] UART TX FIFO, INTs problem
>Date: Wed, 18 Feb 2004 05:16:39 +1100
>
>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 <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
>
>

_________________________________________________________________
Add photos to your e-mail with MSN 8. Get 2 months FREE*. 
http://join.msn.com/?page=features/featuredemail

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.