0
\$\begingroup\$

I have quite a large codebase running on a PIC24F (PIC24FJ128GB106) and have a Change Notification IRQ handler managing external inputs from the user. Everything's been working well for quite some time, until I changed some clocking to slow the CPU down to it's FRC oscillator during standby.

The problem I'm finding is that one single CN interrupt source isn't triggering the interrupt correctly anymore (the CNIF flag isn't being set), but is still waking the system up from sleep() mode.

All the other external sources which I'm running through this handler are setting the IFS1 register CNIF bit and then immediately entering the IRQ handler after sleep() and being processed as I'd expect.

The troublesome source is waking the system from sleep() then running the next 10 or so lines of code after sleep(), THEN triggering CNIF and entering the interrupt. When it finally goes through the interrupt, the startup conditions have changed and it's redundant.

Everything else is working as before, which is why I'm at a loss. To my knowledge nothing serious was changed.

CN priority is at 7, I've enabled all CNEN bits for each individual source, I've checked all other sources and they all raise the CNIF flag and the CN interrupt enable bit is set. The actual source I'm monitoring is definitely alternating between 0 and 1 (it's a 12v trigger line) when off/on.

Are there any glaring things I might not have checked here?

Edit:

It's worth mentioning this one external source also causes MPLABX to breakpoint at an imaginary breakpoint after sleep().

...
Sleep();
/* Woken up! */
}

The code breakpoints ON the closing brace. I can't stop this happening on this source, but there seems to be no clear reason why. No breakpoint set up, traps, RCON seems OK etc.

All other sources (there are 3 other CN enabled sources) work correctly...

\$\endgroup\$
  • \$\begingroup\$ Hmm.. Seems to work if I step through with my ICD3 but just not normally. I suspect some race conditions. \$\endgroup\$ – njt Jun 24 '13 at 15:20
  • \$\begingroup\$ Can you code some assembly language NOPs before the closing bracket ? That can help with the "hardware skidding" thing. I forget the skid factor; I think it's probably two; maybe; I just normally put in ten and that always caught it before the skidding let the execution go too far \$\endgroup\$ – User.1 Jun 26 '13 at 19:05
1
\$\begingroup\$

This doesn't explain exactly what you describe, but could be relevant. Remember that on most PICs (don't remember whether the PIC 24 does this specifically) the instruction following SLEEP is fetched and in the pipeline, therefore always executed as the first instruction after the processor wakes up. This is true whether the wakeup condition causes a interrupt or not. Often this extra instruction is harmless, but not if it messes with interrupt state. To be safe, you can put a NOP immediately following SLEEP.

\$\endgroup\$
  • \$\begingroup\$ Hi Olin, Thanks for the idea. I've just tried this but to no avail, but it's useful to know! \$\endgroup\$ – njt Jun 24 '13 at 15:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.