--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> wrote:
> At 08:49 AM 1/21/05 +0000, you wrote:
> > --- In lpc2000@yahoogroups.com, Peter Jakacki <peterjak@t...> wrote:
> > > Yeah, you'd think that the transmit routine would be simple hey? As Rob
> > > brought out, you have to kick it. Usually I do this by a separate
> > > polling routine called from a timer interrupt. It checks the queue and
> > > the UART and decides whether it needs to load up the UART. Mind you, I
> > > *still* check to see if I need to kick it from my queue filler such as
> > > when the first character is transmitted etc. But there are conditions
> > > where the micro won't detect that the transmitter is ready (I'm trying
> > > to think why now, but funny things happen). Anyway, the polling routine
> > > also checks for receive lockups/timeouts etc, so it's a good idea and
> > > also good practice.
> >
> > When you get down to it, there are always a few skellies lurkin.
> >
> > Interrupts are always such tricky stuff because you can
> > be in the middle of doing anything when these things
> > go off. After posting and pondering, here's a thought
> > experiment that might work:
> >
> > Start up the UART in loopback mode (via the MCR) and
> > then write two initial bytes to create the initial transmit
> > empty interrupt. Then set to normal mode and when the
> > interrupt is serviced, it can only clear the interrupt by writing
> > more characters to the hw fifo. If no more characters
> > are to be sent, then instead of clearing the interrupt, block it.
> > When data is put into the software queue, then unblock the
> > interrupt and the interrupt routine will do the transferring.
> > This creates harmonious asynchronous threads and a simple
> > on/off switch for the transmitter.
>
> Nope, the interrupt is cleared when you read the identification register so
> that won't work.
If you don't read the identification register then it will work. That
is my premise. The only way that you do clear the interrupt is to write
to the THR. Since I know why I got the interrupt, I don't need to
identify it by reading the identification register and then I can use
that to keep the interrupt alive till more data becomes available.
> In the switch case if the switch gets turned on as a
> > result of a contention of writing to the register, then the
> > interrupt will just recognize this as a known condition and
> > handle it. In the case that switch is turned off accidentally
> > with data to send, then the next data will clear it. But it
> > could introduce a fifo empty period. Since the interrupt
> > routine is the only one that can turn off the interrupt, it
> > must write the register just after it was set to on for data
> > in the software queue. But if the software queue is written
> > first and then the switch is turned on, then the interrupt
> > routine would have already transferred data to the hw fifo
> > so it would be ok because the interrupt had already been
> > there,... before the other routine had finished. So that is
> > ok 2.
>
> Huh? I don't understand what you are getting at. The interrupt protection
> is there to protect access to the SW queue. What switch are you referring to?
The switch is created with the bit to block or unblock the interrupt
source such as the combination of VICIntEnClr and VICIntEnable. The
interrupt writes to clear while the other routine writes to enable
thus creating a switch. In the above I was exploring all scenarios
and making sure that none created a situation where data was lost or
blocked. When interrupts are blocked it is easy to see who is operating
exclusively, but when they are not blocked, you must consider combinations
of threads interrupting each other to see what states are possible.
>
> >--- In lpc2000@yahoogroups.com, Peter Jakacki <peterjak@t...> wrote:
> > > BTW, especially at higher baud rates it's advantageous to have the
> > > transmit interrupt handler loop and check the queue again before
> > > exiting. This way it keeps the transmit fifo filled and makes for more
> > > efficient operation. If the interrupt handler routine has a high
> > > overhead it might even pay to "tread water" in the handler, timing out
> > > if the UART is not ready yet. This is can be very beneficial when
> > > operating at higher baud rates as the handler can empty the queue in one
> > > tight burst.
> >
> > Initially I didn't even check the status of the fifo to see how many I could
> > stuff in there and just wrote 16 each time. This worked ok under low
> > loading but failed under high loading. So I added a quick check to see
> > if the fifo was ready (THRE) and finished the interrupt if it wasn't ready
> > or if 16 had been sent. I thought about putting in a wait loop as you
> > suggested but that stretches the interrupt and I'm not sure of how
> > much time that might end up costing. In the worst case, 15 could be
> > queued but the 16th would have to wait for the other 15 @ 230400 is
> > about 650us!
>
> Um, if you write any number of bytes to the FIFO it will clear THRE until
> all bytes in the FIFO have been sent. If you check THRE after putting the
> first byte in and exit you effectively eliminated the FIFO. There is no
> indication on the UART of the send FIFO status other than empty and not empty.
Actually in my transmit loop I checked the THRE bit before I wrote to the
THR because I was having data loss problems. As it turns out, this way I was
able to send 5 bytes before the THRE bit cleared. Then after reading your post
I tried to send the full 16 without checking and that worked. The place I have
to check is in the other routine where I kick the transmitter. In pseudo
code:
timer_interrupt()
send 16 \ no THRE check needed interrupt means 16 can be sent
other_code()
queue bytes in sw queue
send 1 \ THRE check needed as interrupt might also be active
In the place where I send 16, there is no need to check the THRE since the
interrupt is only called when there is room for 16. In the place where the
interrupt is kicked, if I don't check for THRE then data stream corruption
will occur. In retrospect, with the problem well understood, it makes sense.
These discussions help.
RobMessage
Re: transmit interrupt kicker
2005-01-21 by chazeltopman
Attachments
- No local attachments were found for this message.