Identifying source of interrupts: nonsense?

I’ve seen countless mention of the “fact” that, to identify the source of an interrupt (in the 16F family of Mid-range devices) one simply checks the interrupt flags. Thus with all three timers running, we simply need to scan the three IFs to see which one is high. Nonsense!

Unless I’m completely wrong (in which case, someone PLEASE clarify for me) an interrupt from a source like a timer occurs only when BOTH the IF AND the IE are active. Yet it can happen that a source in the chip (eg. a timer) can have its interrupt flag set while not causing the interrupt currently being serviced - because the enable bit is not set - yet the perceived wisdom is that the interrupt flag is the only thing we need to test in the ISR. Surely that’s rubbish?

“Nonsense” and “rubbish” are unnecessary superlatives. The process described to you is by far the most common one that people encounter. Obviously if you are continuing to run a timer while disabling its interrupt, you need logic in your ISR to accommodate that if you have other active interrupts. Your scenario is definitely atypical.

-Bill

Thanks Bill, and I apologise for the robust language. :slight_smile:

I’m running all three timers and T0 cannot be switched off, so it continually sets the IF, which is then taken by my ISR as an interrupt since I’ve been only checking for timer IFs high, which is what absolutely every information source I have read says I should do. I have no idea if running all three timers is atypical!

I’m now checking IE as well, to ensure that I’m only executing the T0 stuff whenever T0 is the cause of the interrupt, and the issues I had with the software execution have disapppeared. Nowhere have I seen any mention of a problem with this “common process,” so I was wondering about my software technique of replicating what the interrupt logic of the device is doing (according to the Mid-Range manual, fig 8-1 in my copy), where an interrupt source’s AND gates combine IF and IE to produce an interrupt request.

Why aren’t programmers given access to the outputs of the AND gates for testing interrupt source in the ISR, instead of just one of its inputs? I don’t believe that Microchip dropped the ball on this - even though their manuals have many errors, their logic seems to me to be extremely robust and far-sighted, so I’m left wondering what it is that I don’t understand.

What you’re describing isn’t making clear sense to me. Running 3 timers is not atypical. What I originally thought you were doing with the 3 timers is what’s atypical.

I’m running all three timers and T0 cannot be switched off, so it continually sets the IF, which is then taken by my ISR as an interrupt since I’ve been only checking for timer IFs high…

Assuming you can't turn Timer 0 off because of your application requirements, so far this is normal...

I’m now checking IE as well, to ensure that I’m only executing the T0 stuff whenever T0 is the cause of the interrupt, and the issues I had with the software execution have disapppeared.

The T0IE bit is completely under your control and is not set or cleared by the hardware during execution. If you are enabling and disabling T0IE in the main software loop, then you have to conditionally check the T0IF bit in your ISR depending on the state of T0IE.

Why aren’t programmers given access to the outputs of the AND gates for testing interrupt source in the ISR, instead of just one of its inputs?

You have access to both inputs of the AND gates in the interrupt combinational logic.

Do you, or do you NOT want interrupts with Timer 0? If you do NOT, clear the T0IE register and Timer 0 will not generate interrupts. Since it won’t be generating interrupts, your ISR should not be looking at T0IF. You will need some other polling routine to check for overflows (if that matters) or let it run with T0IF set.

Perhaps you should explain what you are trying to do and post your source code for analysis. I’ll wager that this probably boils down to not fully understanding how the interrupt logic works.

-Bill

Bill:
Assuming you can’t turn Timer 0 off because of your application requirements, so far this is normal…

Actually, T1 and T2 can be turned off, but T0 cannot. It can only be disabled. It’s when it is disabled that the ISR still executes the code designed to service a T0 interrupt, because of the recommended test of T0IF, which only tests for overflow, not for interrupt. I now also test for T0IE, which is what I originally thought was a fudge, and therefore probably wrong.

Bill:
If you are enabling and disabling T0IE in the main software loop, then you have to conditionally check the T0IF bit in your ISR depending on the state of T0IE.

Exactly - “depending on the state of T0IE” and everyone says test the IF, but it seems that you also have to test the IE in some cases. I started doing that, and I think you’re saying that I got it right. I had thought that I was getting it wrong and that my IE test was a crowbar solution, since I have never seen any reference to it in this context. My contention is that Microchip providing a direct test of interrupt might have been appropriate.

Bill:
Do you, or do you NOT want interrupts with Timer 0? If you do NOT, clear the T0IE register and Timer 0 will not generate interrupts. Since it won’t be generating interrupts, your ISR should not be looking at T0IF. You will need some other polling routine to check for overflows (if that matters) or let it run with T0IF set.

T0 will be required sporadically, enabled by an external stimulus (emulated by a momentary push switch on my breadboard) and when T0 times out the ISR will disable it. Thus there will be no further interrupts until the button is pressed again, but T0IF will be high for all of that time, since it is still running and timing out. Therefore unless I also test T0IE, the timeout will be responded to in the polling code, which I cannot allow to happen.

Bill:
Perhaps you should explain what you are trying to do and post your source code for analysis. I’ll wager that this probably boils down to not fully understanding how the interrupt logic works.

It’s 469 lines of assembly code, and now that it includes testing of IE in the ISR, it works as required. I can readily describe what the software is doing and provide the code, but doesn’t the above describe exactly what I’m getting at?

But I think you have supported my “fudge” of testing of IE as well as IF in cases where the timer is needed but not always enabled. That’s probably pretty blindingly obvious, but as I said, I have never seen it mentioned.

Or is there still something fundamentally wrong somewhere?

I started doing that, and I think you’re saying that I got it right.

Now that I understand the way you want to implement this, it makes sense to check if your interrupt is enabled before processing TMR0 data.

…since I have never seen any reference to it in this context.

This is why I said your case is atypical. Just about every instance I've seen of people using interrupts with timers never involved disabling the interrupt while still allowing the timer to free run. Keep in mind that you still need to clear the T0IF bit so that you don't immediately vector to your ISR when you reenable interrupts.

My contention is that Microchip providing a direct test of interrupt might have been appropriate.

You are dealing with mid-range 8-bit controllers so you can't expect too much. If you want better interrupt handling, the PIC18F parts have configurable high and low priorities and the 16-bit parts have unique vectors for each interrupt source.

-Bill