Sleeping PICs Lie ? - WDT + GIE <> ISR but Just Resumes Main Code

OK ... a minor mystery ...

While I've used PICs for many things, I've never made use of the SLEEP mode. For my 18f2620, the docs state :

"All external interrupts (INT0, INT1 and INT2) can wake-up the processor from SLEEP, if bit INTxE was set prior to going into SLEEP. If the global interrupt enable bit GIE is set, the processor will branch to the interrupt vector following wake-up."

Well, it doesn't.

I *do* have GIE enabled, and INT1, because the PIC needs to be awakened by an external device. WDT timeouts DO happen. The external interrupt DOES work also, awakening from sleep and calling the ISR just like it's supposed to.

BUT ... a WDT timeout while sleeping does NOT branch to the ISR, but instead just picks up the program exactly where it left off, ie executing the code beyond the SLEEP instruction. This is OK, convenient even ... but not what the docs SAY it will do.

The program is writ in MikroPascal, but the actual SLEEP command is an in-line ASM statement, so MP ought not be saving the current program counter or anything else before SLEEP.

Any clues as to why this may be happening ? Mystery registers that could de-rail the call to the ISR when interrupts are enabled ? Any info helpful.

Reply to
B1ackwater
Loading thread data ...

The paragraph that you quoted doesn't seem to mention the WDT. I downloaded the data sheet and a quick check turned up this:

That suggests to me that the operation you're observing is what the chip was designed to do. It's been a very long time since I've written code for a PIC, but that's also how I remember sleep mode working.

Peter

Reply to
Pete

[...]

The WDT does not generate an interrupt, so it will not branch to the ISR. When it times out, it wakes from sleep if sleeping, or resets the PIC if running.

--
John W. Temples, III
Reply to
John Temples

You need to decide whether you want the WDT or the interrupt to wake up the processor. If it's the latter, then you must turn off the WDT before putting the processor to sleep.

--
John B
Reply to
John B

I'll check that section and see (this is what you get with 350+ page documents ... the info you need is scattered all over the place).

Apparently it means that if the CPU is righteously hung (or most anything that delays clearing the WDT) then it WILL jump to the ISR on WDT timeout if GIE is set - but if it's sleeping, then it just resumes where it left off regardless of the GIE status.

Alas, section 3 says "all run modes" but doesn't mention the effect of GIE ... where you don't get a true "reset" but instead a jump to the ISR. There oughtta be an "also see ..." footnote at least.

Anyway, this is fine with me ... except it means I have to write a little extra code to deal with THREE modes of program resumption now ... GIE enabled (->ISR), GIE disabled or power-cycle (->reset) and SLEEP (->resume) :-(

Thanks.

Reply to
B1ackwater

After reading some other parts of the manual pointed out by another poster, it's clear that what I had first read applied only to exiting SLEEP because of an external interrupt ... where the state of GIE will decide whether you jump to the ISR or do a device reset.

A WDT exit from SLEEP resumes from where you left off while a WDT trigger during normal running (or a hang) causes a device reset.

Another case of where the info you need is scattered in several places across 350+ pages of small print.

Hmmm ... does MicroChip have a seperate document entitled "About Interrupts" or something, where all the pertinent data and possible register/state interactions are brought together in one place ? As so many people seem to go so wrong with interrupts it would seem a smart thing to do. I'll try to search ...

Reply to
B1ackwater

Actually, I need BOTH to wake up the processor. The "normal" mode is a wakeup interrupt from one of several possible external devices saying "I've got something for you !".

However I'd ALSO like the WDT to kick in every so often just in case the processor got hung-up and can't hear the external requests anymore. "Wastes" a tiny speck of power every few minutes, but ensures the device is always working (these are going out "in the field" ... WAY out).

A couple of good docuphiles pointed out ANOTHER section that affected my interpretation of events ... that it's only an INTERRUPT during sleep that can cause a jump to the ISR if GIE is set. A WDT timeout during sleep just resumes the code, regardless of GIE, and a WDT timeout during normal running (or a hang-up) resets the processor as if the power had been cycled.

So, I've gotta write code to deal with each possible scenerio ... POR/WDT, SLEEP+GIE & SLEEP+WDT. What fun ... :-)

Reply to
B1ackwater

Hmmm, sounds pretty chaotic. I think I'll stick with my tried and tested AVRs thanks.

--
John B
Reply to
John B

No it make perfect sense if you are asleep and an interrupt happens you expect to goto an interrupt. If the watchdog is used to wake from sleep it would require it own flag so you could tell which interrupt happened.

Reply to
Neil

Followup :

Although the WDT does indeed set its own flag so you can tell if that's why the CPU restarted, I didn't actually need to use it. Just set up my initiallization code so it didn't care whether it was a WDT or a power-on reset ... a restart was a restart regardless. This was easier than using a seperate re-init routine JUST for WDT resets.

My app is working just fine now ... waits for an external interrupt to wake it up and, if the wait is long enough, the WDT periodically reboots the thing so it will never become 'stuck' (for long) - whereupon it just goes back to sleep again almost immediately. Power is conserved and the app remains robust ... who could ask for more ?

Reply to
B1ackwater

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.