CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Software control of WDT on PIC18F87K22

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
embedder



Joined: 11 Feb 2010
Posts: 19

View user's profile Send private message

Software control of WDT on PIC18F87K22
PostPosted: Tue Nov 08, 2011 5:47 pm     Reply with quote

PCH 4.125

I am trying to enable/disable the PIC18F87K22 WDT under software control. I've read the few posts that there are here and the help files, and the fuse definitions but no luck.

The help for setup_wdt() says:

"For PCH parts .... with software controlled WDT, setup_wdt( ) would enable/disable watchdog timer only if NOWDT fuse is set."

So I have set-up my WD like this:
Code:
#fuses NOWDT
#fuses WDT1024
#fuses WDT_SW
setup_wdt(WDT_ON);

But:
Code:
setup_wdt(WDT_OFF);
has no effect

The NOWDT fuse setting seems to contradict some other posts here, but it too has no effect either way.

Am I missing something obvious? Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 6:50 pm     Reply with quote

This thread discusses turning on the WDT under software control, and
it has code to demonstrate this:
http://www.ccsinfo.com/forum/viewtopic.php?t=45439

Can you post a small program that shows how you turn off the WDT,
and how it fails ? Post a program that demonstrates the failure mode.
embedder



Joined: 11 Feb 2010
Posts: 19

View user's profile Send private message

PostPosted: Wed Nov 09, 2011 7:55 am     Reply with quote

Thanks PCM programmer. I read and followed that thread, but it doesn't show the WD being successfully turned off - that's one of the problems highlighted. I will post some code.
embedder



Joined: 11 Feb 2010
Posts: 19

View user's profile Send private message

PostPosted: Wed Nov 09, 2011 10:19 am     Reply with quote

OK, here's some code.

After setup_wdt(WDT_OFF) the LED should stay on for 8 seconds, then off for 1 sec, then back on and finally the WD should cause a reset after 4 seconds. However, the PIC is always reset by the WD after 4 sec. From the visible flutter of the LED the "reason" is a WDT_TIMEOUT every time after the initial power-up.

Is setup_wdt(WDT_OFF) intended to be used to disable the WD in this scenario?

Code:
#include <18F87K22.h>

// *** Watchdog Timer *** //
// WDT resolution    = 4ms
// WDT post-scalers  = 256   512,  1024  2048  4096   8192   16384  32768
// WDT time-outs     = 1.024 2.048 4.096 8.192 16.384 32.768 65.536 131.027 sec
#FUSES WDT1024       // WDT = 1024 * 4 ms = 4.0960 sec.
#FUSES WDT_SW        // WDT is s/w controlled
#FUSES WDT_NOSLEEP   // WD disabled during sleep

#FUSES NOPLLEN

//#use delay(internal=64mhz)
#use delay(internal=16mhz)

void main()
{
   //setup_oscillator(OSC_16MHZ | OSC_PLL_ON);  // Fosc = 64 MHz
   setup_oscillator(OSC_16MHZ);  // Fosc = 16 MHz
   
   int8 i, reason;
   
   reason = restart_cause();
   if(reason==WDT_TIMEOUT){
      for(i=0;i<3;i++){
         output_high(PIN_A4);    // LED on
         delay_ms(30);         
         output_low(PIN_A4);     // LED off
         delay_ms(30);         
      }
   }
   
   setup_wdt(WDT_OFF);     // Disable WDT.
   
   output_low(PIN_A4);     // LED off
   delay_ms(1000);         // Wait one second   
   output_high(PIN_A4);    // LED on
   delay_ms(8000);         // Wait eight seconds. WD should not bark
   output_low(PIN_A4);     // LED off
   delay_ms(1000);         // Wait one second
   output_high(PIN_A4);    // LED on

   setup_wdt(WDT_ON);      // Enable WDT. It will reset in 4 seconds.

   while(1);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 09, 2011 2:22 pm     Reply with quote

I made a better test program. I didn't like your LED stuff because it
didn't give me enough information, etc. The program below displays
the reason for the restart. Then it turns on the WDT and waits in a
getc() loop. If you don't press a key, it will do a WDT timeout while
in that loop. (The loop is in the internal code for getc). If you do
press a key, then the WDT is turned off, and it will tell you this.

For this test, I programmed the PIC and then unplugged the DC power
cord and the ICD2 from the board. Then I plugged in the power and
I got this output. I didn't press a key for several seconds, to prove that
it's restarting due to a WDT timeout. Then I pressed Enter and no more
WDT timeouts. So this shows that it's working:
Quote:

Normal power up
Press any key within 4 seconds to turn off the WDT
Restart because of WDT timeout
Press any key within 4 seconds to turn off the WDT
Restart because of WDT timeout
Press any key within 4 seconds to turn off the WDT
Restart because of WDT timeout
Press any key within 4 seconds to turn off the WDT
WDT disabled. Nothing more should print.


I don't have your exact PIC, but it's similar. It's in the K22 series.
I tested this with compiler vs. 4.125.
Code:

#include <18F45K22.h>
#fuses INTRC_IO, WDT_SW, WDT1024, NOPLLEN, NOPBADEN 
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

//===================================
void main()
{

switch(restart_cause())
  {
  case WDT_TIMEOUT:
    {
     printf("Restart because of WDT timeout \n\r");
     break;
    }

  case NORMAL_POWER_UP:
    {
     printf("Normal power up \n\r");
     break;
    }
 }

setup_wdt(WDT_ON);

printf("Press any key within 4 seconds to turn off the WDT \r\n");
getc();
setup_wdt(WDT_OFF);

printf("WDT disabled.  Nothing more should print. \n\r");

while(1);
}
embedder



Joined: 11 Feb 2010
Posts: 19

View user's profile Send private message

PostPosted: Wed Nov 09, 2011 3:24 pm     Reply with quote

There is one essential difference between your code and mine, and it turns out to be the answer:

Code:
#FUSES WDT_NOSLEEP


This fuse disables s/w control of the WD.

I don't know if it is meant too, but I can just manually turn-off/on the WD prior to going to sleep and waking-up.

Thanks for your help.
embedder



Joined: 11 Feb 2010
Posts: 19

View user's profile Send private message

PostPosted: Wed Nov 09, 2011 3:35 pm     Reply with quote

Page 419 of the datasheet seems to mean that there are four mutually exclusive WD modes. i.e. Setting fuse WDT_NOSLEEP after fuse WDT_SW changes the mode to h/w enabled (but disabled when asleep)

The WDT can be operated in one of four modes as
determined by CONFIG2H<WDTEN<1:0> The four
modes are:
• WDT Enabled
• WDT Disabled
• WDT under software control,
- SWDTEN (WDTCON<0>)
• WDT
- Enabled during normal operation
- Disabled during Sleep
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group