Yahoo Groups archive

Lpc2000

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

Message

Re: [lpc2000] Re: transmit interrupt kicker

2005-01-21 by Robert Adsett

At 08:52 PM 1/21/05 +0000, you wrote:
>--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> wrote:
> >
> > 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.


What about all the other interrupt sources?  Are you doing transmit only? I 
would consider that an unusual case but it might work then.  If you are 
dealing with both transmit and receive (or any of the other serial 
interrupt sources) though you mist read the IIR, if for no other reason 
than to clear the interrupt.


>  >  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.


OK, that's just a disable and restore interrupts.  You should check some of 
the earlier threads in the archives, there was a discussion about spurious 
interrupts occurring under this kind of scenario.  I've forgotten the exact 
details as to whether they occur in this particular scenario or not.

> > 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.

Apparently the fill routine is faster that the UART state machine :)

>  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()

UART_interrupt maybe?  It doesn't make sense to me labelled as timer given 
your following comments.

>     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

I'd have to see how you disable and enable interrupts here but I do see 
danger areas.  In particular I can see the following; THRE flags interrupt 
but before the interrupt can respond you disable interrupts (this is 
essentially the core of the spurious interrupt issue), you then send a byte 
and re-enable interrupts.  The interrupt routine picks up and stuffs 16 
bytes into a FIFO that only has room for 15.  Whether that's an issue and 
how often it would show up if it is depends a lot on the details.

The key to this is getting the disabling done in the proper places so that 
the only way you send to the UART manually is if the interrupt will no 
longer send and the flag to send manually will always be set if the 
interrupt will not respond unless you send manually.  I hope that is 
somewhat understandable.

Worse I can see this working by accident and failing when the right 
combination of parameters hit and the phasing of various signals change.

BTW this pseudo code is at odds with your switch commentary above.


>  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.

You're welcome.  I find them useful too.  I don't know that I'd ever have 
thought of using that method of avoiding priming flags.  Even now I can't 
imagine being desperate enough to try it ;)

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,
be they legal, genetic, or physical.  If you don't believe me, try to
chew a radio signal. "

                         Kelvin Throop, III

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.