Weird problem with WDT on PIC18F2420

Discussion in 'Embedded Systems and Microcontrollers' started by THE_RB, Jun 28, 2013.

  1. THE_RB

    Thread Starter AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Hi, this little problem has me pulling hair out and I can't work out why! :)

    I have a PIC 18F2420 running on 8MHz xtal HS mode, and it needs to be a low power app that sleeps most of the time and wakes up on the WDT timeout, performs a few mS of code, and back to sleep.

    The test code for the moment is literally as simple as this;
    Code ( (Unknown Language)):
    1.  
    2. main
    3. {
    4.   TRISB = 0;        // outputs for test LEDs
    5.  
    6.   LATB.F4 = 1;  // test LED on
    7.   Delay_mS(20);
    8.   LATB.F4 = 0;  // test LED off
    9.  
    10.   asm SLEEP;        // back to sleep
    11. }
    12.  
    The result on the 'scope looks like this;
    1. LED on for 20mS, 2.5mA
    2. SLEEP for 272mS, approx 0mA
    3. Powers up, 2.0mA, for 272mS, before code execution starts
    (The 272mS period is the correct WDT period for the WDT /64 setting in the config.)

    It should do this;
    1. LED on for 20mS, 2.5mA
    2. SLEEP for 272mS, approx 0mA

    So, apparently after osc powers up it is stuck for ANOTHER WDT timeout period, before code execution starts! This is terrible as I need it to sleep for a WDT for about 10 seconds, then be awake for a couple mS.

    Testing everything I can think of showed both the periods match, and both are the WDT timeout period.

    I have messed with the majority of the settings, FSCM, 2speed startup, PWRT on/off etc and it does not matter what settings are used, there is always a delay of 1 WDT timeout after power up and BEFORE code execution starts! As you can understand this is killing my low power application as the best power reduction I can get is 50:50 by time (sleep/powered).

    Changing osc type does not help, even on the internal osc block the WDT problem is identical.

    If anyone has a suggestion (like I have forgotten something really silly) then please speak up!
     
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    Do you have a reason to exit the main() routine every time the watchdog wakes you up, or is that an oversight?

    Drop out of main() and you get stuck in the C start-up code which may not be handling the watchdog flag as you want it too.
     
  3. JohnInTX

    Moderator

    Jun 26, 2012
    2,347
    1,029
    Agreed. Also, I've had to bracket the SLEEP instruction with 2 NOPs (before and after the sleep). I don't recall whether it was a chip errata or a compiler issue but that's what it took to settle things down.

    Also the standard stuff applies, clear any pending IRQs and clear the WDT before sleeping and mind the oscillator startup time after wakeup. Some emulators (the old ICE 2K/4K for sure, maybe others) don't support sleep, you have to test it on the programmed chip.

    That said, it is weird..
    Good luck.
     
    Last edited: Jun 28, 2013
  4. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,364
    Agreed with John. Seems like you're getting stuck in the start-up code.
     
  5. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Then the WDT timer is used for wakeup in in sleep. The MCU will not go through the WDT reset operation. But instead go through a "exit from power-managed mode" See figure
    "FIGURE 23-1: WDT BLOCK DIAGRAM", and section "3.5.2 EXIT BY WDT TIME-OUT"
    So the start-up code should not be executed
     
    Last edited: Jun 28, 2013
  6. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    I think in the midrange app notes it says you need a nop after sleep because it skips an instruction when it wakes. It's quite possibly true for 18F as well.
     
    Eric007 likes this.
  7. blueroomelectronics

    AAC Fanatic!

    Jul 22, 2007
    1,758
    98
    I'm new with C on the PIC so I'm not sure if you need to put an endless loop in at the end. The NOP sounds like a solid idea too, also do you need to clear the WDT on reset? (I would)
     
  8. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    If the PIC is awake then WDT overflow resets the PIC so it will go back to the startup code. If the PIC is asleep then it continues execution with the second instruction after the sleep command.
    I think it's probably waking, getting stuck somewhere, then resetting.
    Unless C is resetting the WDT I think that it has already started before the 20ms delay, so it will sleep 20ms less than you expect.
     
  9. THE_RB

    Thread Starter AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Thanks for the suggestions guys, you have given me a couple of things to try out.

    After I have a feed i'll run some tests and reply back. :)
     
  10. THE_RB

    Thread Starter AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Thanks to everyone (especially Markd77) who offered help, you made me check a couple of things and I found out I made two silly mistakes;

    1. I assumed the WDT timeout would cause a reset, because this PIC had no option to select reset/restart on the WDT timeout. I changed all the possible power management config modes etc, and assumed at least one mode would always give a device reset on WDT timeout.

    2. I forgot that the MikroC compiler ALWAYS puts an invisible "goto here" at the end of main()!

    Code ( (Unknown Language)):
    1.  
    2. // like this;
    3. main()
    4. {
    5.   asm sleep;   // my code
    6.   goto here;   // INVISIBLE
    7. }
    8.  
    Because the WDT did not cause a device reset, it simply woke from sleep and hung totally in the invisible "goto here" until a second WDT reset.

    Buried in the datasheet I found info that basically says this;

    "The WDT timeout will cause a device reset if the code is executing at the time. If the device is in SLEEP mode, the WDT timeout causes wakeup and code starts running from that point".

    So now it makes perfect sense, one WDT period caused the sleep to end, the second WDT period made it break out of the invisible hang.

    Not being able to set the WDT to be able to do what I wanted (always reset), the only solution was to force a reset on wakeup from sleep;

    Code ( (Unknown Language)):
    1.  
    2. // like this;
    3. main()
    4. {
    5.   asm sleep;   // my code
    6.   asm reset;   // my code
    7.   goto here;   // INVISIBLE
    8. }
    9.  
    Thanks to the people that helped. I feel like a bit of an idiot not catching this immediately, but it was after many hours of coding and tuning other functions, and then at the last minute I thought "right! I'll stick this thing in WDT sleep mode and see the power consumption on the 'scope". One of those late night "I'll just add this ONE thing" moments. ;)
     
  11. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Did you also know that if the microcontroller’s global interrupt (GIE/PEIE) is enabled
    the CPU will branch to an interrupt vector, and service the wake-up event (if coded of course).
    http://ww1.microchip.com/downloads/en/appnotes/00950b.pdf
    I also add this You may allready have read it though
    http://ww1.microchip.com/downloads/en/devicedoc/41200B.pdf
     
  12. THE_RB

    Thread Starter AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Thanks for that, I had not read those. The second one looks good. :)
     
  13. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
Loading...