Yahoo Groups archive

Lpc2000

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

Thread

transmit interrupt kicker

transmit interrupt kicker

2005-01-20 by chazeltopman

Is anyone aware of another way to start the transmit interrupt running on the UART on an 
LPC2106 other than writing to the THR?  I'd rather the interrupt routine take care of 
writing to the UART instead of another asynchronous thread of code doing that.  I'm 
interfacing to a serial LCD using the UART and it runs at 230400. With the UART hardware 
queue I can write 16 bytes every 700us or so and update the display fairly rapidly.  To 
keep the hardware queue from staying empty I keep a software queue which can hold a lot 
of display commands and feed the hardware queue each time the THR empty interrupt 
happens.  This is the easy part.  The hard part is when the software queue runs empty and 
the hardware queue runs empty the interrupt happens but does not persist (this might be 
my libel assumption) and when the interrupt routine exits, the THR empty status bit is still 
set but there is no more interrupt.  Now if the software queue is loaded up, to get the 
interrupt to trigger the queue transfer to the hardware queue, I have to transfer one value 
to trigger the interrupt to do the rest.  In other tx interrupt on other micros the interrupt 
persists and you just flip a control register bit and turn it off to block the interrupt until 
the software queue is loaded again whereupon you set the bit back on.  This way there is 
no asynchronous writing sharing.  After reset, two bytes have to be written for the initial 
interrupt to happen.

Rob

Re: [lpc2000] transmit interrupt kicker

2005-01-20 by Robert Adsett

At 09:23 AM 1/20/05 +0000, you wrote:
>Is anyone aware of another way to start the transmit interrupt running on 
>the UART on an
>LPC2106 other than writing to the THR?

There isn't another way.

>I'd rather the interrupt routine take care of
>writing to the UART instead of another asynchronous thread of code doing 
>that.

Well, one way or another you've got to start the UART going.  I haven't run 
across a UART that doesn't need to be primed by writing to the transmit 
register.  (I trust you that they exist, I just don't remember running into 
one)

>  The hard part is when the software queue runs empty and
>the hardware queue runs empty the interrupt happens but does not persist 
>(this might be
>my libel assumption) and when the interrupt routine exits, the THR empty 
>status bit is still
>set but there is no more interrupt.

You need to set a flag when both queues have emptied so that the queuing 
routine can start up the UART again.

>Now if the software queue is loaded up, to get the
>interrupt to trigger the queue transfer to the hardware queue, I have to 
>transfer one value
>to trigger the interrupt to do the rest.  In other tx interrupt on other 
>micros the interrupt
>persists and you just flip a control register bit and turn it off to block 
>the interrupt until
>the software queue is loaded again whereupon you set the bit back on.

I don't see this as substantively different.  In one case you write to the 
transmit register, in the other the interrupt enable register, but in both 
cases you need to set a flag when both queues are empty and respond 
accordingly.

For the 16550 style case the routines look something like

transmit ()
{

if( SW queue is empty) {
    empty_flag = 1;
    }
else {
    stuff the 16550 HW queue appropriately
    }

}


interrupt_transmit_routine()
{
transmit()
}

queueing_routine( void *ptr, size_t len)
{

Add  incoming data to queue

when all data added (or queue filled) {
    if( empty_flag != 0) {
          disable interrupts
          transmit()
          restore interrupts
          }
    }
}

The only difference from the peripheral interrupt enable/disable approach 
is the use of the transmit call in the queuing routine rather than a set 
interrupt on call (or line).  All the rest of the code is necessary anyway.

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

Re: [lpc2000] transmit interrupt kicker

2005-01-20 by Peter Jakacki

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.

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.

*Peter*


chazeltopman wrote:

>Is anyone aware of another way to start the transmit interrupt running on the UART on an 
>LPC2106 other than writing to the THR?  I'd rather the interrupt routine take care of 
>writing to the UART instead of another asynchronous thread of code doing that.  
>
<snip>


-- 
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.300 / Virus Database: 265.7.1 - Release Date: 1/19/05

Re: transmit interrupt kicker

2005-01-21 by chazeltopman

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

--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> wrote:
>disable interrupts
>transmit()
>restore interrupts
 When working with interrupts, as a general rule I try to
 write code that does not require blocking other interrupts.
 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.

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

 Things are purring along right now. I'm updating two scrolling graphs
 plotting 220 data points every second.  If I can think of a simple
 change to try the above thought experiment, I'll give it a go.

 Rob

Re: [lpc2000] transmit interrupt kicker

2005-01-21 by Robert Adsett

At 09:38 AM 1/21/05 +1000, you 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.

You they re-occur to you let us know, I can't think of any conditions that 
shouldn't be dealt with without needing a watch process.


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


Remember the FIFO has no indicator of being partially empty.  So if you 
check after sending 16 bytes to the FIFO and it indicates empty then it's 
sending as fast as you can put them in.  If that's the case why run a 
transmit interrupt?  Just poll the darn thing it will be less overhead.

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

Re: [lpc2000] Re: transmit interrupt kicker

2005-01-21 by Robert Adsett

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.


>--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> wrote:
> >disable interrupts
> >transmit()
> >restore interrupts
>  When working with interrupts, as a general rule I try to
>  write code that does not require blocking other interrupts.

Fair enough, that was just a general outline of what was required.

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

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


Robert

Re: transmit interrupt kicker

2005-01-21 by chazeltopman

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

 Rob

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

Re: transmit interrupt kicker

2005-01-21 by chazeltopman

--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> wrote:
> 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.

 I'm just sending a data stream to an LCD which never talks back so the
 interrupt only comes from the transmitter.  Which gives me the option of not
 having to check the IR.  Although the LSR is an option to avoid IR.

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

 Thanks for the reminder.  I remember that as well but so far I haven't
 had any problems with that.  I should probably reread the erratta dox.
 
> 
> > > 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 :)

 It is probably tied to the transmit clock which is slower than the
 processor clock.
 
> 
> >  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.

 Uh, whoops, too many interrupts on the go!  I'm using the timer for another
 sensor, but that might end up as another thread.
 
> 
> >     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.

 I don't disable interrupts with the above code.  I also ran some test cases
 to see if I could get the THRE before it causes an interrupt and that never
 happens.  So the above case can not occur.   The other_code() puts data into
 the software queue and then it checks to see if the THRE is set.  If it is
 not set then the interrupt is running and things are fine.  If it is set
 then the interrupt has run empty and is not running and then it is ok to
 transfer one byte from the software queue to the fifo to restart the interrupt.

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

 The switch commentary is on a thought experiment not actual code while
 the pseudo code is what I am currently crafting.
 
 Rob

Re: [lpc2000] Re: transmit interrupt kicker

2005-01-22 by Robert Adsett

At 10:45 PM 1/21/05 +0000, you wrote:
>  I'm just sending a data stream to an LCD which never talks back so the
>  interrupt only comes from the transmitter.


Ah, that does allow you to explore specialized solutions.

> > 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.
>
>  Thanks for the reminder.  I remember that as well but so far I haven't
>  had any problems with that.  I should probably reread the erratta dox.


I don't think you will find it in an errata.  I doubt it's actually 
considered one.  Hmm, this should probably be added to the FAQ.


> >
> > >     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.
>
>  I don't disable interrupts with the above code.  I also ran some test cases
>  to see if I could get the THRE before it causes an interrupt and that never
>  happens.  So the above case can not occur.

You ran some tests, it didn't happen, therefore it can't occur?!!

That's a bit of a leap.  I wouldn't trust that without at least some 
underlying reason to believe it's true and preferably some 
documentation.  Even if I had some reason to believe it to be true I'd be 
suspicious and with the code to be sure being so simple ....

Avoiding race conditions on interrupts can be difficult enough without 
borrowing trouble.

And that avoids any questions about whether you can have issues with the 
queue itself due to race conditions.  No code but I'm assuming you've 
protected yourself there.

> > BTW this pseudo code is at odds with your switch commentary above.
>
>  The switch commentary is on a thought experiment not actual code while
>  the pseudo code is what I am currently crafting.


OK, the two were getting mixed up.

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

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.