Yahoo Groups archive

Lpc2000

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

Message

Missing THRE interrupt?

2004-06-23 by Robert Adsett

I've been working on a interrupt driven serial interface and have run into 
an odd problem.  I seem to be missing THRE interrupts.

I'm running a simple echo type program for initial testing.  I've got a 
file I'm feeding in via realterm to test (It just sits there pumping the 
file out over and over).  When I run the program it will eventually stop 
(I've never got a full three file dumps sucessfully).

I started adding bit toggles to see why it was stopping and determined that 
the SW transmit buffer was filling up and the interrupt was not emptying 
it.  I have a flag (I call it a prime flag) to indicated that the transmit 
interrupt has emptied the pipe and needs restarted.  At that point I 
figured there was a bug in my interrupt routine such that the prime flag 
was not being set when it was supposed to be but I haven't been able to 
find it.

Finally today I instrumented the interrupt response with a number of bit 
toggles and it started to look like the reason the prime flag was not being 
set was because the THRE interrupt was not being fired.  I added a short 
piece to the end of the interrupt to check for this:

  if( (U0LSR & TX_MASK) != 0) {
     temp_id = U0IIR;
     if( (temp_id & PENDING_MASK) == 0) {
          if( (temp_id & IDENT_MASK) == TRANSMIT_AVAILABLE) {
               IOSET = 0x200;
               transmit();
               IOCLR = 0x200;
               }
          }
      else {
          IOSET = 0x8000;
          transmit();
          IOCLR = 0x8000;
          }
     }

The only way that the IOSET/IOCLR 0x8000 should occur is if 1) I've ended 
the main body of the interrupt, 2) THRE is set in the line status register 
and 3) the THRE interrupt is not set.

Much to my surprise that pin is being toggled which indicated to me that 
THRE is being set (as it should be) but the IIR is not being set.

Now the THRE interrupt source is the only one that can be cleared simply by 
reading the IIR so an extra read of the IIR would cause a problem but I 
don't see that in my code.  Main interrupt body below:

  temp_id = U0IIR;
/* IOCLR = 0x8000;*/
  while( ( temp_id & PENDING_MASK) == 0) {
     IOSET = 0x100;
     switch(temp_id & IDENT_MASK) {

                 /*  DATA_AVAILABLE occurs when data has passed the FIFO */
                 /* threshold.  DATA_TIMEOUT occurs when data has been   */
                 /* sitting in the FIFO for longer than the timeout      */
                 /* period (3.5-4.5 character times).  In either case we */
                 /* call Receive to empty the FIFO.                      */
          case DATA_AVAILABLE:
          case DATA_TIMEOUT:
               IOSET = 0x400;
               receive();
               IOCLR = 0x400;
               break;
               /*doc!!*/
          case TRANSMIT_AVAILABLE:
               IOSET = 0x200;
               transmit();
               IOCLR = 0x200;
               break;

          case LINE_STATUS:
          default:
               break;
          }
     IOCLR = 0x100;
/*    IOSET = 0x8000;*/
     temp_id = U0IIR;
/*    IOCLR = 0x8000;*/
     }

U0IIR is declared volatile and I also checked the generated assembly and it 
appears to be read only once per loop.

At this point it appears to be acting as if the THRE interrupt is swallowed 
by the hardware if it occurs at the same time as a RDA interrupt.  I'm 
loathe to believe that, I suspect I've done something silly that I can't 
see because I'm too close to it.

Oh and the FIFOs are off.  I turned them off shortly before doing the full 
instrumentation just to eliminate them as a problem source.

What I have here won't do as a workaround, I have an idea of what would be 
needed for that if indeed the THRE interrupt is indeed being swallowed by 
the HW but I want to identify the problem rather than just put in a 
symptomatic workaround.

Finally, the test program has been running something like 7x longer than 
the longest it ran before putting in the missing THRE interrupt as I sit 
here typing.  I'll let it run for a while yet while I think.

Anyone else seen this behaviour or have any ideas as to what I've missed.?

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.