Searching \ for '[PIC] Odd interrupt behaviour' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/ints.htm?key=interrupt
Search entire site for: 'Odd interrupt behaviour'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Odd interrupt behaviour'
2005\10\04@010931 by PicDude

flavicon
face
Another head-scratcher...

In short, on a PIC16F874A, with TMR0IE cleared, Timer-0 interrupts are still
being generated.  As a test, in the ISR code after checking that TMR0 flag
was set, I added a few lines of code to verify that TMR0IE is really set,
before performing the appropriate Timer-0 code for my app.  This makes the
code work properly, but it's a very odd workaround.

I'm also seeing odd, but somewhat different behaviours with Timer 1 and Timer
2.

Partially fried PIC?  I'll say no for now, since another one (from the same
batch) does the same thing.  And shockingly, these came to me as samples from
Microchip just a few weeks ago, but are rev b4 (dated April 2004).  Is it
Mchip's practice to send out really old chips as samples?

I've checked and checked for odd bank/page problems with my code, but even if
the bank was off, it should not affect INTCON, which is shared across all
banks.

Anyone seen this before and can shed some light on why this is occurring?

Cheers,
-Neil.


2005\10\04@013942 by Jinx

face picon face
> Mchip's practice to send out really old chips as samples?

Would have thought the 874 is mature enough now not to have
any f/w issues, and 2004 isn't that old

And don't forget, from time to time they actually SELL buggy
chips ;-)

> INTCON, which is shared across all banks

What about corruption via FSR ?

2005\10\04@022024 by Chen Xiao Fan

face
flavicon
face
Not so sure if this is related to the following
errata (DS80128F). It is supposed to be solved
with Rev B2 silicon. Maybe the bug resurfaces.

Long log time ago, there was a bug with some 16F chips.
In order to disable all interrupt, the following sequences
were needed (in PICC).

/* Disable all interrupt*/
       do GIE = 0;
               while (GIE);
         INTCON = 0;

Maybe this is a similar bug. Try
/* Disable TMR0IE interrupt*/
       do TMR0IE = 0;
               while (TMR0IE);

Regards,
Xiaofan

"3. Module: Core
Certain code sequence and placement may cause
the corruption of a few bits in the instruction fetch
when the part is used above 4 MHz. A corrupted
instruction fetch will cause the part to execute an
improper instruction and result in unpredictable
outputs.

Microchip cannot predict which code sequences
and placement will cause this failure. If this failure
mechanism exists in your system, it should be evident
during statistically significant preproduction
testing (minimum suggested sample size 100
units) of your particular code sequence and
placement.

Any code change should be tested in the same
manner prior to their implementation. If most parts
fail your tests, or if failures are seen at all voltages
or at all frequencies, this indicates that the problem
experienced does not relate to this failure
mechanism.

This problem has not been observed at operating
frequencies below 4 MHz.
Work around
Use the part at or below 4 MHz.

This problem is specific to Rev. B0 and has been
resolved by Rev. B2 of the silicon (date codes later
than 0242xxx)."

{Original Message removed}

2005\10\04@022852 by PicDude

flavicon
face
On Tuesday 04 October 2005 12:39 am, Jinx scribbled:
> > Mchip's practice to send out really old chips as samples?
>
> Would have thought the 874 is mature enough now not to have
> any f/w issues, and 2004 isn't that old
>
> And don't forget, from time to time they actually SELL buggy
> chips ;-)
>
> > INTCON, which is shared across all banks
>
> What about corruption via FSR ?


Actually not using FSR for anything in this code.

Cheers,
-Neil.


2005\10\04@024204 by PicDude

flavicon
face
On Tuesday 04 October 2005 01:20 am, Chen Xiao Fan scribbled:
> Not so sure if this is related to the following
> errata (DS80128F). It is supposed to be solved
> with Rev B2 silicon. Maybe the bug resurfaces.
>
> Long log time ago, there was a bug with some 16F chips.
> In order to disable all interrupt, the following sequences
> were needed (in PICC).
>
> /* Disable all interrupt*/
>        do GIE = 0;
>                while (GIE);
>            INTCON = 0;
>
> Maybe this is a similar bug. Try
> /* Disable TMR0IE interrupt*/
>        do TMR0IE = 0;
>                while (TMR0IE);

Difference here is that in the interrupt routine, after I check for the TMR0IF
flag, I am now checking the state of the the TMR0IE enable bit.  And it's
verifying that that interrupt really is not set.  So it's not a matter of the
TMR0IE enable bit not being set, but that the interrupt system within the PIC
is ignoring it.

I'm ordering a non-A version to see how it compares.

Cheers,
-Neil.




{Quote hidden}

> {Original Message removed}

2005\10\04@032121 by Jinx

face picon face
> flag, I am now checking the state of the the TMR0IE enable bit.
> And it's verifying that that interrupt really is not set.  So it's not
> a matter of the TMR0IE enable bit not being set, but that the
> interrupt system within the PIC is ignoring it

You're working with the correct bits ? (just checking)

2005\10\04@041632 by Alan B. Pearce

face picon face
>Another head-scratcher...
>
>In short, on a PIC16F874A, with TMR0IE cleared,
>Timer-0 interrupts are still being generated.

I bet they are not being generated (see below).

>As a test, in the ISR code after checking that TMR0
>flag was set, I added a few lines of code to verify
>that TMR0IE is really set, before performing the
>appropriate Timer-0 code for my app.  This makes the
>code work properly, but it's a very odd workaround.

I bet what happens when you turn TMR0IE off is an interrupt is generated by
something else, whose flag you check AFTER the TMR0IF flag, and so the
interrupt routine acts as though it has had a TMR0 interrupt. The fix you
have is the normal way of making sure that a turned off interrupt does not
fire off the interrupt routine.

Thou shalt write 1000 lines
"When I turn an interrupt off using the IE flag, my interrupt routine shall
check the IE flag before the IF flag."

2005\10\04@075718 by olin piclist

face picon face
PicDude wrote:
> In short, on a PIC16F874A, with TMR0IE cleared, Timer-0 interrupts are
> still being generated.  As a test, in the ISR code after checking that
> TMR0 flag was set, I added a few lines of code to verify that TMR0IE is
> really set, before performing the appropriate Timer-0 code for my app.
> This makes the code work properly, but it's a very odd workaround.

Not at all.  This is the normal thing to do if you've got multiple
interrupts but some of them can be occasionally disabled.

The 16F PIC only has one interrupt vector.  Let's say you get an interrupt
for reason A.  The code checks all interrupt causes, and finds interrupt
flag B set.  This is perfectly normal if B interrupts are disabled.  The
only way to determine not to handle interrupt B is to check the B enable
flag.

This symptom is usually seen with the UART transmit interrupt, since that is
the most common interrupt to be toggled between enabled and disabled during
normal operation.  But the same effect applies to any interrupt that could
be disabled but is still checked in the interrupt routine.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\10\04@081949 by olin piclist

face picon face
Chen Xiao Fan wrote:
> Long log time ago, there was a bug with some 16F chips.
> In order to disable all interrupt, the following sequences
> were needed (in PICC).
>
> /* Disable all interrupt*/
> do GIE = 0;
> while (GIE);
>   INTCON = 0;

Actually this bug never applied to a 16F chip as far as I know.  I deal with
this in my PIC development environment by setting INTR_OFF_BUG to 1 for the
afflicted chips.  I got the list from Microchip a long time ago, and it can
be seen in the STD_DEF.INS.ASPIC file.  The effect of INTR_OFF_BUG 1 is to
have my INTR_OFF macro perform the additional checking you show above,
whereas when INTR_OFF_BUG is 0 it just emits BCF INTCON, GIE.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\10\04@082057 by olin piclist

face picon face
PicDude wrote:
> Actually not using FSR for anything in this code.

Maybe not deliberately.  If we're talking about a bug, anything is possible.

*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\10\04@103504 by Gerhard Fiedler

picon face
Alan B. Pearce wrote:

> Thou shalt write 1000 lines
> "When I turn an interrupt off using the IE flag, my interrupt routine shall
> check the IE flag before the IF flag."

Right... this actually belongs to Wouter's "stupid mistakes (everybody
makes once)" thread :)

That's why I write  

 if( ADIF ) // ADC handler (gets never disabled individually)

or

 if( TXIF && TXIE ) // UART Tx handler

at the start of the individual parts of an interrupt routine. Note the
explicit comment for the ADC interrupt... you probably now know why :)

BTW, I don't think it matters whether you check the IE flag before the IF
flag or afterwards. Which way round may have a (very) slight impact on
performance, depending on whether (IE && !IF) or (IF && !IE) is more common
when the PC gets to that location.

Gerhard

2005\10\04@114112 by Alan B. Pearce

face picon face
>BTW, I don't think it matters whether you check the
>IE flag before the IF flag or afterwards. Which way
>round may have a (very) slight impact on performance,
>depending on whether (IE && !IF) or (IF && !IE) is
>more common when the PC gets to that location.

I guess if you are ANDing the register, so you can test both bits at once,
then probably not, but testing each bit individually in assembler using Bit
Test instructions, I would automatically put the Enable bit test first for
two reasons -

1. If there is any speed requirements where time in the interrupt routine
needs to be minimised, then this saves a couple of instruction times when
that interrupt is not enabled.

2. It makes the logic of the program flow clearer to anyone following along
behind to do maintenance.

Sure there is minimal if anything in it, but if there is anything to be
gained, even if only clarity, why not.

2005\10\04@125426 by PicDude

flavicon
face
On Tuesday 04 October 2005 03:16 am, Alan B. Pearce scribbled:
> I bet what happens when you turn TMR0IE off is an interrupt is generated by
> something else, whose flag you check AFTER the TMR0IF flag,

Correct.  TMR0 is checked first, then TMR1, then TMR2.


> and so the
> interrupt routine acts as though it has had a TMR0 interrupt. The fix you
> have is the normal way of making sure that a turned off interrupt does not
> fire off the interrupt routine.

What bugs me is why should interrupts be generated if the corresponding
interrupt-enable flag is off.

Consider this...

The very first instruction in my code is "clrf        INTCON".  This clears both
TMR0IE and TMR0IF.  Then there's some init stuff, then I explicitly set
INTCON to "11000000" (TMR0 off, and TMR0IF cleared still).

In the ISR, I check the TMR0IF, and if so, it does the normal processing, then
clears the flag and exits.  If it was not TMR0IF, it checks for TMR1, etc.  
At no point in the ISR are the Timer enable bits set.  Just the flags are
cleared.

No where else in the code does the interrupt get switched on.

But still, Timer-0 interrupts are being continuously generated.


>
> Thou shalt write 1000 lines
> "When I turn an interrupt off using the IE flag, my interrupt routine shall
> check the IE flag before the IF flag."

Not yet :-)  I still can't accept this as being normal/expected behaviour.

Cheers,
-Neil.




2005\10\04@132950 by PicDude

flavicon
face
On Tuesday 04 October 2005 06:58 am, Olin Lathrop scribbled:
> PicDude wrote:
> > In short, on a PIC16F874A, with TMR0IE cleared, Timer-0 interrupts are
> > still being generated.  As a test, in the ISR code after checking that
> > TMR0 flag was set, I added a few lines of code to verify that TMR0IE is
> > really set, before performing the appropriate Timer-0 code for my app.
> > This makes the code work properly, but it's a very odd workaround.
>
> Not at all.  This is the normal thing to do if you've got multiple
> interrupts but some of them can be occasionally disabled.

If you're suggesting that there may be a Timer-0 flag set before the interrupt
gets disabled, then perhaps.  But what if the Timer-0 flag was never enabled
anywhere in the code, but keeps getting generated?  And yes, the ISR code
clears the flag properly.


> The 16F PIC only has one interrupt vector.  Let's say you get an interrupt
> for reason A.  The code checks all interrupt causes, and finds interrupt
> flag B set.  This is perfectly normal if B interrupts are disabled.  

???  So what is the point of the "enable" bit?  The datasheet says "The TMR0
interrupt is generated when the TMR0 register overflows from FFh to 00h.  
This overflow sets bit TMR0IF.  The interrupt can be masked by clearing bit
TMR0IE."  I take this to mean that the TMR0IF interrupt would not be set on
overflow (of the TMR0 counter/register) if TMR0IE is cleared.

However, looking at the interrupt logic diagram on the datasheet, the TMR0IE
and TMR0IF signals are ANDed together and eventually lead to the interrupt
signal (which I take to mean the one that causes the processor to jump to the
interrupt vector).

So you're saying that with the TMR0 enable bit cleared, the TMR0IF's are
really still generated, but masking the TMR0 enable bit just causes the
TMR0IF flag not to generate an interrupt?


Cheers,
-Neil.



2005\10\04@133155 by PicDude

flavicon
face
On Tuesday 04 October 2005 02:21 am, Jinx scribbled:
> > flag, I am now checking the state of the the TMR0IE enable bit.
> > And it's verifying that that interrupt really is not set.  So it's not
> > a matter of the TMR0IE enable bit not being set, but that the
> > interrupt system within the PIC is ignoring it
>
> You're working with the correct bits ? (just checking)

Yep -- I checked these explicitly, and had tried it by setting B'11000000'
into INTCON, by individually setting bits using "TMR0IE", etc and by manually
setting bits 7,6, etc.  I had even checked the .inc to see if all was correct
there, which it was (matching the datasheet).

Cheers,
-Neil.


2005\10\04@134748 by Jan-Erik Soderholm

face picon face
PicDude wrote :

> So you're saying that with the TMR0 enable bit cleared, the
> TMR0IF's are really still generated,...

"Generated" is the wrong word, "set" is correct.
And there is just *one* TMR0IF flag.

This is by design, and realy the only reasonable way
it could work. Note that you *might* want to service the
TMR0 overflow later (after re-setting the xxxIE flag), right ?

> but masking the TMR0 enable bit just
> causes the TMR0IF flag not to generate an interrupt?

As has been explained in *all* replies to this thread...

And checking the xxxxIE flags in the ISR *is* the way
to go.

Regards,
Jan-Erik.



2005\10\04@135823 by PicDude

flavicon
face
On Tuesday 04 October 2005 12:47 pm, Jan-Erik Soderholm scribbled:
> PicDude wrote :
> > So you're saying that with the TMR0 enable bit cleared, the
> > TMR0IF's are really still generated,...
>
> "Generated" is the wrong word, "set" is correct.
> And there is just *one* TMR0IF flag.

Of course.  By "TMR0IF's", I meant repeated setting of the TMR0IF flag.


> This is by design, and realy the only reasonable way
> it could work. Note that you *might* want to service the
> TMR0 overflow later (after re-setting the xxxIE flag), right ?
>
> > but masking the TMR0 enable bit just
> > causes the TMR0IF flag not to generate an interrupt?
>
> As has been explained in *all* replies to this thread...

Okay, misinterpretation on my part.  I am surprised (at myself) that I had
always interpreted this incorrectly.

Thanks,
-Neil.


> And checking the xxxxIE flags in the ISR *is* the way
> to go.
>
> Regards,
> Jan-Erik.


2005\10\04@140609 by Howard Winter

face
flavicon
picon face
Neil,

On Tue, 4 Oct 2005 12:30:52 -0500, PicDude wrote:

>...<
> So you're saying that with the TMR0 enable bit cleared, the TMR0IF's are
> really still generated, but masking the TMR0 enable bit just causes the
> TMR0IF flag not to generate an interrupt?

That's the way Interrupts work on PICs - when an Event occurs that has an Interrupt associated with it, its
Interrupt Flag is set, then if its Interrupt Enable is set, and if the General Interrupt Enable is set, an
actual "Interrupt" occurs (similar to a CALL 0x04).  The only thing that is stopped ("gated") by the Enables,
is the Interrupt itself - the Flags are always set by the Event.

There is a good reason for this - if you have disabled one of the Interrupts temporarily and during that time
an Event occurs, when you Enable it you would have "lost" the fact that the Event occurred if the Flag wasn't
set.  In the case of a real time clock it would lose time, but other more serious consequences could happen in
other applications.

So to sum up, the correct procedure (unless you *never* clear an Enable in the program) when you want to know
if an Event needs handling is:

 IF an Event's Enable AND Flag are set
      an Event occurred and should be handled
 ELSE
      ignore this Event

The language doesn't help - some people tend to use "Interrupt", "Flag" and so on ambiguously.  I prefer these
definitions:

Interrupt: The act of passing control to the Interrupt Service Routine
Event: Something which happens, and which may cause an Interrupt
Flag (or Interrupt Flag): A bit which indicates that an Event has occurred
Enable (or Interrupt Enable): A bit which indicates that an Event will cause an Interrupt

Of course there are two types of Enable - the General one which prevents all Interrupts from occurring, and
the specific ones which relate to individual Events, and both have to be set to allow an Interrupt to occur.

Cheers,


Howard Winter
St.Albans, England


2005\10\04@144642 by olin piclist

face picon face
PicDude wrote:
> But still, Timer-0 interrupts are being continuously generated.

No, they're not.  You are getting an interrupt for some other reason and
TMRIF happens to be set.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\10\04@145231 by Jan-Erik Soderholm

face picon face
Howard Winter wrote :

> That's the way Interrupts work on PICs - when an Event occurs
> that has an Interrupt associated with it, its
> Interrupt Flag is set, then if its Interrupt Enable is set,
> and if the General Interrupt Enable is set, an
> actual "Interrupt" occurs...

That should have read :

> That's the way Interrupts work on PICs - when an Event occurs
> that has an Interrupt associated with it, its
> Interrupt Flag is set, then if its Interrupt Enable is set,
> and if the General Interrupt Enable is set,

*and* (for some interrupt sources, see the datasheet) the
Peripherial Interrupt Enable is set,

> an actual "Interrupt" occurs (similar to a CALL 0x04).


Better make the picture complete... :-)

Jan-Erik.



2005\10\04@151955 by PicDude

flavicon
face
As I also now understand from the other responses.  Slap on my own wrist.

Thanks,
-Neil.



On Tuesday 04 October 2005 01:06 pm, Howard Winter scribbled:
{Quote hidden}

2005\10\04@152426 by olin piclist

face picon face
PicDude wrote:
> If you're suggesting that there may be a Timer-0 flag set before the
> interrupt gets disabled, then perhaps.  But what if the Timer-0 flag
> was never enabled anywhere in the code, but keeps getting generated?

That would be normal for a free running timer 0.

{Quote hidden}

There is no such thing as an interrupt geting "set".  Flags get set but
interrupts happen.  A timer 0 interrupt will happen if GIE is set, TMR0IF is
set, *and* TMR0IE is set.  TMR0IF set by itself does not cause an interrupt.
It gets set every time timer 1 wraps around.

> So you're saying that with the TMR0 enable bit cleared, the TMR0IF's are
> really still generated, but masking the TMR0 enable bit just causes the
> TMR0IF flag not to generate an interrupt?

Yes, I think, but it's important to use the right terms.  Your terms are
part of what is causing your confusion.  TMR0IFs are not "generated".  It is
simply a flag that is set whenever timer 0 wraps around.  Nothing more,
nothing less.  You seem to be confusing the setting of this flag with the
causing of an interrupt.  The setting of this flag will only cause an
interrupt if both GIE and TMR0IE are also set.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\10\04@152945 by michael brown

picon face


> So you're saying that with the TMR0 enable bit cleared, the TMR0IF's
are
> really still generated, but masking the TMR0 enable bit just causes
the
> TMR0IF flag not to generate an interrupt?

Ding ding ding, give that man a cigar.  This is perzactly the case.
TMR0IF is set every time a roll over occurs.  Its behavior has nothing
do with TMR0IE being set or not.

What you were seeing is that your ISR ran and noticed that TMR0IF was
set (because at some point during the execution of your program TMR0
rolled over).  Your ISR then (wrongly) assumed that TMR0 had generated
the interrupt since it saw TMR0IF set.  You cleared the flag and then at
some point you did a RETFIE.  This caused your ISR to immediately run
again since the original reason for its invocation is still true (i.e.
some other IF is still set).

2005\10\04@153402 by olin piclist

face picon face
Howard Winter wrote:
> There is a good reason for this - if you have disabled one of the
> Interrupts temporarily and during that time an Event occurs, when you
> Enable it you would have "lost" the fact that the Event occurred if the
> Flag wasn't set.  In the case of a real time clock it would lose time,
> but other more serious consequences could happen in other applications.

And these events don't have to be captured with interrupts at all.  Code may
simply poll TMR0IF at various intervals to check whether the event occurred
or not.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\10\04@154103 by PicDude

flavicon
face
For clarification/completeness, I'm going to ask one more thing...

Say a TMR0 interrupt occurs, and is being processed in the ISR.  During that
time say a TMR1 event occurs.  The TMR1IF flag gets set, but GIE is off.  
Let's even go one step further and say a TMR2 event occurs as well before the
ISR Timer-0 code is complete, so the TMR2IF flag gets set.

We'll say that no more events occur after this.

Now, upon exit of the ISR, GIE gets reset to it's enabled state.  As I
understand it, another interrupt will be generated, which I can then use to
check for the other interrupt flags.  If say I process the appropriate
Timer-1 code, then exit the ISR again, would it generate another interrupt
for the pending TMR2 flag?

Pretty-much, on each resetting of GIE to it's enabled state (via retfie), does
the PIC recognize that another event flag is set (TMR1IF, TMR2IF, etc) with
its corresponding enable flag (TMR1IE, TMR2IE, etc), and generate an
interrupt for it, or does it queue just one interrupt signal if GIE is
disabled?  This would of course affect how I handle each section in the ISR
-- whether I leave the ISR and let it come back for the other events due to
an interrupt, or if I need to have it sequentially run thru all sections to
process all possible interrupt sources in one call of the ISR.

Cheers,
-Neil.




On Tuesday 04 October 2005 01:06 pm, Howard Winter scribbled:
{Quote hidden}

2005\10\04@154615 by PicDude

flavicon
face
On Tuesday 04 October 2005 02:25 pm, Olin Lathrop scribbled:
> There is no such thing as an interrupt geting "set".  Flags get set but
> interrupts happen.  A timer 0 interrupt will happen if GIE is set, TMR0IF
> is set, *and* TMR0IE is set.  TMR0IF set by itself does not cause an
> interrupt. It gets set every time timer 1 wraps around.
>
> Yes, I think, but it's important to use the right terms.  Your terms are
> part of what is causing your confusion.  TMR0IFs are not "generated".  It
> is simply a flag that is set whenever timer 0 wraps around.  Nothing more,
> nothing less.  You seem to be confusing the setting of this flag with the
> causing of an interrupt.  The setting of this flag will only cause an
> interrupt if both GIE and TMR0IE are also set.


Okay, I guess I'm thinking the right thing (now), but saying it wrong.  Part
of my slangy upbringing I guess.

Cheers,
-Neil.




2005\10\04@155158 by Jan-Erik Soderholm

face picon face
PicDude wrote :

> then exit the ISR again, would it generate
> another interrupt
> for the pending TMR2 flag?

As long as *any* xxxIF flag is set (and the xxxIE and
maybe the PEIE bit), new interrupts will happen.

> -- whether I leave the ISR and let it come back for the other
> events due to
> an interrupt, or if I need to have it sequentially run thru
> all sections to
> process all possible interrupt sources in one call of the ISR.

That's up to you.
Both methods are beeing used and works.

Of course, if the first flag checked is the external INT pin,
and the external source triggering this pin runs to fast, you could
end up with not all int sources beeing serviced. But that's
a design flaw... :-)

Jan-Erik.



2005\10\04@155554 by Byron A Jeff

face picon face
On Tue, Oct 04, 2005 at 02:42:07PM -0500, PicDude wrote:
> For clarification/completeness, I'm going to ask one more thing...
>
> Say a TMR0 interrupt occurs, and is being processed in the ISR.

So GIE, TMR0IF, and TMR0IE are all set.

>  During that
> time say a TMR1 event occurs.

>  The TMR1IF flag gets set, but GIE is off.  

And TMR1IE is also set right?

> Let's even go one step further and say a TMR2 event occurs as well before the
> ISR Timer-0 code is complete, so the TMR2IF flag gets set.

And again TMR2IE is also set.

> We'll say that no more events occur after this.

OK.

>
> Now, upon exit of the ISR, GIE gets reset to it's enabled state.  

Yes.

>As I
> understand it, another interrupt will be generated, which I can then use to
> check for the other interrupt flags.

Under the presumption that the TMR1IE and TMR2IE are set, then yes.

>  If say I process the appropriate
> Timer-1 code, then exit the ISR again, would it generate another interrupt
> for the pending TMR2 flag?

Yes. An interrupt is generated whenever GIE, and both the IE and corresponding
IF flags for a device are all set. And after an interrupt another will be
generated as long as that's true.

> Pretty-much, on each resetting of GIE to it's enabled state (via retfie), does
> the PIC recognize that another event flag is set (TMR1IF, TMR2IF, etc) with
> its corresponding enable flag (TMR1IE, TMR2IE, etc), and generate an
> interrupt for it, or does it queue just one interrupt signal if GIE is
> disabled?

It's not a signal. It's a condition. An interrupt is generated whenever the
condition that GIE along with the IE and corresponding IF are all set. It's
a level triggered event. That's why entering the ISR autodisables the GIE.
Otherwise you'd get an interrupt race condition where the ISR keeps getting
interrupted. In fact an interrupt can be generated if GIE is reenabled in
the ISR. A low priority interrupt may actually want to do this if it wishes
for a higher priority interrupt to interrupt its interrupt service. However
multiple levels of W/STATUS saving can get a bit dicey.

>  This would of course affect how I handle each section in the ISR
> -- whether I leave the ISR and let it come back for the other events due to
> an interrupt, or if I need to have it sequentially run thru all sections to
> process all possible interrupt sources in one call of the ISR.

Well there you go. It's possible to quickly AND the IF and IE flags to see if
there are pending interrupts. You can use the result to decide whether to loop
the ISR or not. It can save you the overhead of reloading and then resaving the
W and STATUS registers at the beginning and end of the ISR.

BAJ

2005\10\04@160046 by olin piclist

face picon face
PicDude wrote:
> Say a TMR0 interrupt occurs, and is being processed in the ISR.  During
> that time say a TMR1 event occurs.  The TMR1IF flag gets set, but GIE
> is off. Let's even go one step further and say a TMR2 event occurs as
> well before the ISR Timer-0 code is complete, so the TMR2IF flag gets
> set.
>
> We'll say that no more events occur after this.
>
> Now, upon exit of the ISR, GIE gets reset to it's enabled state.  As I
> understand it, another interrupt will be generated, which I can then
> use to check for the other interrupt flags.  If say I process the
> appropriate Timer-1 code, then exit the ISR again, would it generate
> another interrupt for the pending TMR2 flag?

Yes.  Take a look at the interrupt logic in the data sheet.  There is no
special magic, and no such thing as "being in" an interrupt.  The PIC logic
is very simple, if a flag is set, AND if its interrupt enable bit is set,
AND GIE is set, and in some cases AND if PIE is set, then the processor
executes a call to 4 and clears GIE.  That's it.  Don't try to read anything
more into it than that.

> Pretty-much, on each resetting of GIE to it's enabled state (via
> retfie), does the PIC recognize that another event flag is set (TMR1IF,
> TMR2IF, etc) with its corresponding enable flag (TMR1IE, TMR2IE, etc),
> and generate an interrupt for it,

Yes, see above.

> or does it queue just one interrupt
> signal if GIE is disabled?

Where in the data sheet is there any mention of an interrupt queue?  Stick
to what the data sheet says instead of trying to invent your own mechanisms.

> whether I leave the ISR and let it come back
> for the other events due to an interrupt,

That's what I do most of the time.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\10\04@162819 by PicDude

flavicon
face
Got it.  Thanks for all the replies and setting me straight.

Cheers,
-Neil.



On Tuesday 04 October 2005 02:55 pm, Byron A Jeff scribbled:
{Quote hidden}

2005\10\04@212750 by Gerhard Fiedler

picon face
Alan B. Pearce wrote:

>> Which way round may have a (very) slight impact on performance,
>> depending on whether (IE && !IF) or (IF && !IE) is more common when the
>> PC gets to that location.

> testing each bit individually in assembler using Bit Test instructions,
> I would automatically put the Enable bit test first for two reasons -
>
> 1. If there is any speed requirements where time in the interrupt
> routine needs to be minimised, then this saves a couple of instruction
> times when that interrupt is not enabled.

I think which way round saves instruction times depends on whether (IE &&
!IF) or (IF && !IE) is more common when the PC gets there. And this depends
on a lot of factors: time the interrupt is enabled vs. disabled, how often
other interrupts hit while it is disabled or not active, how often its own
IF flag is set while it is disabled, possibly some more factors.

For example, for interrupts that hit less frequent than (all) other
interrupts (together) and are rarely disabled, checking IF before IE saves
cycles, on average. Say it is only active 1 out of 10 times the interrupt
routine gets called. So you have 9 out of 10 times where you would check
the IE flag (most of the time set) just to discover afterwards that the IF
is not even set -- requires two bit tests. Checking the IF first requires
only one bit test in these 9 out of 10 cases. If you have a number of
interrupts working, this is probably a rather common case.

> 2. It makes the logic of the program flow clearer to anyone following
> along behind to do maintenance.

That's why I do it in C :) -- it's almost equally clear both ways (look at
the code lines in my previous post).

But there could also be made a case that starting each clause with the IF
flag test is a tad clearer, because that's the one that's always tested,
and thus the code for the various clauses is more consistent (always
starting with the IF flag, vs. sometimes starting with the IF flag test,
other times starting with the IE flag test).

Gerhard

2005\10\05@043330 by Alan B. Pearce

face picon face
>???  So what is the point of the "enable" bit?  The
>datasheet says "The TMR0 interrupt is generated when
>the TMR0 register overflows from FFh to 00h.  This
>overflow sets bit TMR0IF.  The interrupt can be
>masked by clearing bit TMR0IE."  I take this to mean
>that the TMR0IF interrupt would not be set on overflow
>(of the TMR0 counter/register) if TMR0IE is cleared.

I think you are forgetting about how the hardware works.

The timer counts, and on overflow (underflow?) sets the TMR0IF flag. This
occurs if the counter is counting irrespective of the state of the TMR0IE
bit. The only way to stop the TMR0IF flag being set is to stop the counter
totally.

The TMR0IE bit is used to gate the state of the TMR0IF bit into the
interrupt logic. The TMR0IF bit can still be polled by the software even if
the interrupt is not enabled.

The same is true for all cases where there is both F and E bits. The E bit
only gates the state of the F bit through to the interrupt logic.

Now about those 1000 lines ... ;)

More... (looser matching)
- Last day of these posts
- In 2005 , 2006 only
- Today
- New search...