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 CCS Technical Support

remaining problem with wdt / sleep

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



Joined: 01 Apr 2007
Posts: 195

View user's profile Send private message

remaining problem with wdt / sleep
PostPosted: Sun Jun 03, 2007 3:34 pm     Reply with quote

I'm using a PIC18LF2525 at 10MHz with the internal X4 PLL for 40MHz op.
CCS compiler version 3.249

I created a testbed program to examine the interactions with different parameters of the #fuses WDTxxxxx, where xxxxx was 32768, 16384, and 8192. I initially had the #fuses NOWDT set, also.

The program was the following simple loop (used #fuses WDT8192):
Code:

...
   printf("Init completed successfully\r\n");
   printf("delay_ms(200)\r\n");
   printf("#fuses WDT8192\r\n");
   printf("watchdog enabled...\r\n");
   setup_wdt(WDT_ON);

   while(TRUE)
   {
      printf("doing 1 second delay...\r\n");
      delay_ms(1000);
     
      printf("going to sleep...\r\n");
      sleep();

      delay_ms(100);

      printf("waking from sleep... %u\r\n", i++);
   }
}


The output looked like this:

    Init completed successfully
    delay_ms(200)
    #fuses WDT8192
    watchdog enabled...
    doing 1 second delay...
    Cáwaking from sleep... 0
    doing 1 second delay...
    Cáwaking from sleep... 1
    doing 1 second delay...
    Cáwaking from sleep... 2
    doing 1 second delay...
    Cáwaking from sleep... 3
    doing 1 second delay...
    Cáwaking from sleep... 4
    doing 1 second delay...


Why is the printf() after the delay_ms(1000) not being printed?

Would someone please post a code example of how to set up and use the WDT this way? I would like to have an executing backgorund loop, put the system to sleep for a period of time, have the system wake back up, and resume where it left off. I can't use any external stimulus to wake it (like EXT0) and I can't modify the circuit to include an external 32768 crystal for Timer1.

With this set up, #fuses WDT8192 gave about a 34 second delay, #fuses WDT16384 gave about a 68 second delay, and #fuses WDT32768 gave about a 136 second delay.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 03, 2007 4:10 pm     Reply with quote

Post the missing lines of the test program. Post the #include, #fuses
and #use statements. Post the main() and the variable declarations.
The program should be able to be copied and pasted into MPLAB and
then compile without errors.
starfire151



Joined: 01 Apr 2007
Posts: 195

View user's profile Send private message

PostPosted: Sun Jun 03, 2007 8:00 pm     Reply with quote

complete .c file:
Code:

#include <sleep_wdt.h>

// ---- variable definitions ----
int i;


#zero_ram
void main(void)
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   port_b_pullups(TRUE);

   set_rtcc(0);
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED, 0, 1);
   setup_timer_3(T3_DISABLED | T3_DIV_BY_1);

   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_low_volt_detect(FALSE);
   setup_oscillator(False);

   delay_ms(200);    // system stability time

   i = 0;

   printf("Init completed successfully\r\n");
   printf("delay_ms(200)\r\n");
   printf("#fuses WDT8192\r\n");
   printf("watchdog enabled...\r\n");
   setup_wdt(WDT_ON);

   while(TRUE)
   {
      printf("doing 1 second delay...\r\n");
      delay_ms(1000);
     
      printf("going to sleep...\r\n");
      sleep();

      delay_ms(100);

      printf("waking from sleep... %u\r\n", i++);
   }
}


complete sleep_wdt.h file:
Code:

#include <18F2525.h>
//#include <18F2620.h>

#device *=16
#device ICD=TRUE
#device adc=10

#FUSES NOWDT         // No Watch Dog Timer
//#FUSES WDT           // Watch Dog Timer
#FUSES WDT8192       // Watch Dog Timer uses 1:8192 Postscale
#FUSES H4            // High speed osc with 40MHz osc
#FUSES NOPROTECT     // Code not protected from reading
#FUSES IESO          // Internal External Switch Over mode enabled
#FUSES NOBROWNOUT    // No brownout reset
#FUSES BORV20        // 18F2525 Brownout reset at 2.0V
//#FUSES BORV21        // 18F2620 Brownout reset at 2.1V
#FUSES PUT           // Power Up Timer <<< COMMENT OUT FOR DEBUGGING >>>
//#FUSES NOPUT         // No Power Up Timer <<< COMMENT OUT FOR NORMAL OP >>>
#FUSES NOCPD         // No EE protection
#FUSES STVREN        // Stack full/underflow will cause reset
#FUSES NODEBUG       // No Debug mode for ICD <<< COMMENT OUT FOR DEBUGGING >>>
//#FUSES DEBUG         // Debug mode for ICD <<< COMMENT OUT FOR NORMAL OP >>>
#FUSES NOLVP         // No low volt prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT         // Program memory not write protected
#FUSES NOWRTD        // Data EEPROM not write protected
#FUSES NOEBTR        // Memory not protected from table reads
#FUSES NOCPB         // No Boot Block code protection
#FUSES NOEBTRB       // Boot block not protected from table reads
#FUSES NOWRTC        // configuration not registers write protected
#FUSES NOWRTB        // Boot block not write protected
#FUSES FCMEN         // Fail-safe clock monitor enabled
#FUSES NOXINST       // Ext set exten and Index Addr mode disabled (Legacy mode)
#FUSES MCLR          // Master Clear pin enabled

#use delay(clock=40000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)


thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 03, 2007 9:18 pm     Reply with quote

Quote:
#include <18F2525.h>
//#include <18F2620.h>

#device *=16
#device ICD=TRUE
#device adc=10

#FUSES NOWDT // No Watch Dog Timer
//#FUSES WDT // Watch Dog Timer
#FUSES WDT8192

You have a "#device ICD=TRUE" line above. According to the MPLAB
help file for the ICD2:
Quote:
The Watchdog Timer (WDT) cannot be used when debugging.

Comment out or delete that line.

Also you have a "#device *=16" line. That option doesn't apply to 18F
PICs. It's for 16F PICs. Delete that line.

I don't have your PIC to test. I tested the program with an 18F4550,
and it works. Though, I ran it at 4 MHz, and without the PLL.
The WDT8192 period is rather long. I timed it at about 38 seconds.
I'm stating that in case you weren't aware of it.
starfire151



Joined: 01 Apr 2007
Posts: 195

View user's profile Send private message

PostPosted: Sun Jun 03, 2007 10:30 pm     Reply with quote

I made the modifications, per your suggestion. I get the following output:

    Init completed successfully
    delay_ms(200)
    #fuses WDT8192
    watchdog enabled...
    doing 1 second delay...
    Cáwaking from sleep... 0
    doing 1 second delay...
    going toCáwaking from sleep... 1
    doing 1 second delay...
    going toCáwaking from sleep... 2
    doing 1 second delay...
    going toCáwaking from sleep... 3
    doing 1 second delay...
    Cáwaking from sleep... 4
    doing 1 second delay...
    going to sleep..Cáwaking from sleep... 5
    doing 1 second delay...
    going to sleep..Cáwaking from sleep... 6
    doing 1 second delay...
    going to sleep..Cáwaking from sleep... 7
    doing 1 second delay...

Notice the inconsistency in output and the bogus characters with partial lines being printed.

Is there something else besides just placing a sleep() statement in the code and having the watchdog wake it up? It seems the program continues from where it left off but some data is getting corrupted.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 03, 2007 11:57 pm     Reply with quote

I was able to get rid of the extra characters "Cá" by adding a short
delay before going to sleep. Add the line shown in bold below.
Quote:

while(TRUE)
{
printf("doing 1 second delay...\r\n");
delay_ms(1000);

printf("going to sleep...\r\n");
delay_ms(5); // Allow time to xmit last two chars
sleep();

delay_ms(100);

printf("waking from sleep... %u\r\n", i++);
}
Ttelmah
Guest







PostPosted: Mon Jun 04, 2007 2:28 am     Reply with quote

It is perhaps worth explaining 'why' PCM Programmer added the delay.
His 'remark', explains why, but this may not be clear unless you understand the hardware.
The RS232 stops when the chip goes to sleep. There can be up to 1.999... untransmitted characters in the hardware, when a 'printf' returns. (basically, the chips has one character of buffering, plus the 'output shift register', containing the character currently being transmitted - this should have only just started being transmitted, so fractionally 'under' a second character in the hardware). At 9600bps, these could need up to 2.083mSec to send. Hence PCM, is delaying to _ensure_ that these characters are sent, before triggering the sleep. '5mSec', is a safe 'overkill'.
An alternative, if you wanted to just delay 'as long as necessary', rather than erring on the side of safety, would be:
Code:

#byte TXSTA=0xFAC  //Address of the UART transmit status register
#bit TRMT=TXSTA.1  //Bit reflecting transmit shift register status

#define wait_for_RS232_to_complete() while(TRMT==0)

Called as the line:

wait_forRS232_to_complete();

Will wait till the UART's buffers _are_ empty, and no longer.

Best Wishes
starfire151



Joined: 01 Apr 2007
Posts: 195

View user's profile Send private message

PostPosted: Mon Jun 04, 2007 8:44 am     Reply with quote

Laughing Excellent! Thanks, I will try that tonight.

Thanks very much for taking the time to address the issue and, more importantly, to address the reason for the issue...

So is the small time delay I've added after the sleep() (the 100ms time delay) necessary? I inserted it to allow the system enough time to have the internal clocks stabilize before attempting a print out. Was this incorrect?
Ttelmah
Guest







PostPosted: Mon Jun 04, 2007 9:07 am     Reply with quote

The 'PUT' fuse already gives a delay.
This makes the system wait for typically 65mSec, after the oscillator is stable.

Best Wishes
starfire151



Joined: 01 Apr 2007
Posts: 195

View user's profile Send private message

watchdog / sleep problem solved...
PostPosted: Mon Jun 04, 2007 5:47 pm     Reply with quote

I tried the suggestion of inserting the 5 ms delay before the sleep() and I removed the 100 ms delay after the sleep(). I worked perfectly! I got the following results:
    delay_ms(200)
    #fuses WDT8192
    watchdog enabled...
    doing 1 second delay...
    going to sleep...
    waking from sleep... 0
    doing 1 second delay...
    going to sleep...
    waking from sleep... 1
    doing 1 second delay...
    going to sleep...
    waking from sleep... 2
    doing 1 second delay...
    going to sleep...
    waking from sleep... 3
    doing 1 second delay...
    going to sleep...
    waking from sleep... 4
    doing 1 second delay...
    going to sleep...
    waking from sleep... 5
    doing 1 second delay...
    going to sleep...

I will additionally try it with the #define wait_for_RS232_to_complete() (as suggested by Ttelmah), as this looks to be a little more efficient and I wouldn't have to change the delay value dependant on the baud rate.

Thanks, again, for the help! Very Happy
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