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

Problem putting PIC24 to sleep()

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



Joined: 02 Aug 2008
Posts: 8

View user's profile Send private message Visit poster's website

Problem putting PIC24 to sleep()
PostPosted: Sun Oct 18, 2015 9:42 am     Reply with quote

Am trying to put PIC24FJ128GC006 to sleep. The test code below keeps running (i.e. through "test loop"). It seems like it is either not going to sleep, or it is waking up immediately from something. I was originally trying to wake up from RTC alarm, but have disabled all interrupts including INT_RTC at this point (just for test). Also tried sleep(SLEEP_FULL);, sleep(SLEEP_IDLE); without success.

Primary clock is 16mhz internal; RTC running from SOSC 32768 xtal

Any suggestions appreciated. Thanks.

Code:

// Using PIC24FJ128GC006

// Main clock is 16 MHZ internal oscillator
// RTC is enabled using SOSC and external 32768 Xtal

// test code segment that tries to put system in sleep()


// ?? TEMPORARY SLEEP TEST AREA below ---------10/17/15-------------------------


   fputc(RTCCChimeF,USBst);  // output number of RTC Interrupts to USB port
   while(TRUE) // test loop
   {
       LoggerLowPower();   // puts powers logger down; prepares to sleep
       sleep();  // also tried sleep(SLEEP_FULL), sleep(SLEEP_IDLE) without success
       LoggerFullPower();  // wakes up; powers up after sleep
       fputc(RTCCChimeF,USBst);  // output number of RTC Interrupts to USB port
       fputc(test[2],USBst);  // output number of RTC Interrupts to USB port
   }


// ?? TEMPORARY SLEEP TEST AREA above ----------------------------------



void LoggerFullPower(void) //  powers up logger
   // Input: none
   // Output: none
   // Comment:
{
   
   output_bit(EnExcitCh03_3,1); // turn Ch 0 +3.3 excitation OFF
   output_bit(EnExcitCh13_3,1); // turn Ch 1 +3.3 excitation OFF
   output_bit(EnExcitCh05_0,0); // turn Ch 0 +3.3 excitation OFF
   output_bit(EnExcitCh15_0,0); // turn Ch 1 +3.3 excitation OFF
   output_bit(En5sp,1); // turn signal processor OFF
   delay_ms(1000);   // allow time for regulators to stabilize
   
   enable_interrupts(INT_TIMER1);
   clear_interrupt(INT_TIMER1);
   enable_interrupts(INT_RDA);
   clear_interrupt(INT_RDA);
   enable_interrupts(INT_RTC);
   clear_interrupt(INT_RTC);
   enable_interrupts(INT_EXT0);
   clear_interrupt(INT_EXT0);
   enable_interrupts(INTR_GLOBAL);
   return;
}

void LoggerLowPower(void) // Put logger in low power state; then sleeps
   // Input: none
   // Output: none
   // Comment:
{
   output_bit(EnExcitCh03_3,0); // turn Ch 0 +3.3 excitation OFF
   output_bit(EnExcitCh13_3,0); // turn Ch 1 +3.3 excitation OFF
   output_bit(EnExcitCh05_0,0); // turn Ch 0 +5.0 excitation OFF
   output_bit(EnExcitCh15_0,0); // turn Ch 1 +5.0 excitation OFF
   output_bit(En5sp,0); // turn signal processor OFF
   disable_interrupts(INT_TIMER2);
   disable_interrupts(INT_EXT1);
   disable_interrupts(INTR_GLOBAL);
   disable_interrupts(INT_TIMER1);
   clear_interrupt(INT_TIMER1);
   disable_interrupts(INT_RDA);
   clear_interrupt(INT_RDA);
   clear_interrupt(INT_RTC);
   disable_interrupts(INT_RTC);
   clear_interrupt(INT_RTC);
   clear_interrupt(INT_EXT0);
   disable_interrupts(INT_EXT0);
   disable_interrupts(INTR_GLOBAL);
   test[2] = 9;   // ?? for test only 10/18/15
   
   return;
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 19, 2015 3:27 am     Reply with quote

I don't see your fuses or #device statements. Are you trying to run this
in Debug mode ? The MPLAB ICD3 help file says:
Quote:
dsPIC30F SMPS, dsPIC33F, PIC24F/H Limitations

The SLEEP instruction cannot be used when debugging unless the
device is set to “Break on SLEEP Instruction” (Debugger>Breakpoints,
Event Break­points).
ronewart



Joined: 02 Aug 2008
Posts: 8

View user's profile Send private message Visit poster's website

PostPosted: Mon Oct 19, 2015 5:17 am     Reply with quote

Thanks for the reply PCM Programmer --
I don't have a debugger, but may have selected fuses improperly.
Fuses are shown below.
I did not know whether #FUSE DS_SW should or should not be used with the sleep() instruction. I tried it both ways without success.
Code:
#include <24FJ128GC006.h>
#device ADC=12

#FUSES NOWDT                    //No Watch Dog Timer

#FUSES LVR                      //Low Voltage Regulator Enabled, Controlled in Software
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOPROTECT                //Code not protected from reading
#FUSES JTAG                     //JTAG enabled

#FUSES NOOSCIO                  //OSC2 is clock output
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES VREFALT                  //VREF is on a alternate pins, VREF+ on RB0 and VREF- on RB1
#FUSES CVREFALT             

#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES WPFP                     //Write/Erase Protect Page Start/End Location, set to last page or use WPFP=x to set page
#FUSES SOSC_SEL                 //SOSC circuit selected

#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES WPDIS                    //All Flash memory may be erased or written
#FUSES NOWPCFG                  //Configuration Words page is not erase/write-protected
#FUSES WPEND                    //Flash pages WPFP to Configuration Words page are write/erase protected

#FUSES NODSWDT                  //Deep Sleep Watchdog Timer disabled
// #FUSES DS_SW                    //Deep Sleep is controlled by the register bit DSEN
   // tested with & without this fuse; does not enter sleep (or immediately exits)
#FUSES RTCBAT                   //RTC operation is continued through VBAT
#FUSES NOPLL                 
#FUSES NOALTI2C2                //I2C2 mapped to SDA2/SCL2 pins
#FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins

#device ICSP=1
#use delay(internal=16000000)
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon Oct 19, 2015 8:23 am     Reply with quote

Old question.
Are you perhaps using MPLAB?.

If so, this _by default_ will program the chip for debug mode unless you override this setting....
ronewart



Joined: 02 Aug 2008
Posts: 8

View user's profile Send private message Visit poster's website

PostPosted: Mon Oct 19, 2015 11:08 am     Reply with quote

Thanks Ttelmah & PCM Programmer!

Am using the CCS PCD compiler to generate .hex file. Am using MPLAB, to "Import Hex (Prebuilt) Project" which interfaces to PM3 programmer. I don't think that MPLAB does anything other than program the hex file, but could be wrong.
Under the "Debug" tab in the PCD compiler, most of the options are greyed out since I don't have ICD. When I click on the "enable button" it comes up with "Your code does not have ICD mode enabled" error message.

PCM Programmer -- am looking for the "Break on SLEEP Instruction" (Debugger>Breakpoints> Event Breakpoints) that you described. Should that be in the PCD compiler, or is that something that I might not have since I don't have ICD? Is there a specific #device . . . or preprocessor command that I could insert into my header file to ensure that the system does not get compiled in the debugger mode?

Thanks for your help.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 19, 2015 12:03 pm     Reply with quote

Look at the bottom of the .LST file created by the CCS compiler.
It will have a list of the fuses that the compiler set for the project.
The file will be in your CCS project directory. What does it show
for the debug fuse ?


Quote:
(Debugger>Breakpoints> Event Breakpoints)

I don't have the CCS IDE so I can't answer questions on it.
ronewart



Joined: 02 Aug 2008
Posts: 8

View user's profile Send private message Visit poster's website

PostPosted: Mon Oct 19, 2015 12:25 pm     Reply with quote

"NODEBUG" fuse --> whole fuse .lst shown below.

Also found #fuses NODEBUG in CCS's FAQ section which I added to the header file. It did not make any difference in the .hex checksum, nor in the operation of the test program.

Thanks again PCM Programmer -- I appreciate your expertise.

Code:

Configuration Fuses:
   Word  1L: 7B3F   WPOSTS16 WDT128 WINDIS NOWDT ICSP1 LVR NODEBUG NOWRT NOPROTECT JTAG
          H: 0000 
   Word  2L: F93B   NOPR WDTCLK_LPRC NOOSCIO CKSFSM FRC_PLL VREFALT CVREFALT WDTCMX IESO
          H: 0000 
   Word  3L: FFFF   WPFP SOSC_SEL WDTWIN_25% BROWNOUT WPDIS NOWPCFG WPEND
          H: 0000 
   Word  4L: 477F   DSWDT_25DAYS DSWDTCK_LPRC DSBOR NODSWDT DS_SW RTCBAT PLL2 NOALTI2C2 NOIOL1WAY
          H: 0000 
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 19, 2015 4:50 pm     Reply with quote

So it's not the debug fuse. The first thing I would do is to greatly simplify
the test program, like this:
Code:

void main()
{
output_low(LED2);  // Ensure that LED2 is off
output_high(LED1);   // Turn on LED1 to show that PIC is running

sleep(SLEEP_FULL);

output_high(LED2);  // If PIC doesn't stay in sleep mode, turn on LED2

while(TRUE);
}
 
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue Oct 20, 2015 1:25 am     Reply with quote

If I remember correctly, these chips have a more complex sleep than most of the older chips. Full 'deep sleep', loses everything, and can only be exited via a reset. Then there is deep sleep with the memory retained (configured by the RETEN' bit. Because deep sleep is so dangerous, the chips have this locked, so you have to unlock it before enabling the sleep instruction. CCS does not do this for you. So you need something like:
Code:

//the low voltage regulator must be set to be available in the fuses
#bit DSEN=getenv("bit:DSEN")
#bit RETEN=getenv("bit:RETEN")

     disable_interrupts(INTR_GLOBAL);
     RETEN=TRUE; //enable the low power regulator
     DSEN=TRUE;
     DSEN=TRUE; //This must be set _twice_
     sleep(SLEEP_FULL);
     delay_cycles(1);


This enables the internal regulator to keep the RAM alive (so deep sleep
can wake), and then unlocks the deep sleep bit, and executes the sleep.
I played with this on an 'ancestor' chip, and found this was what was needed. On PIC 18's that need this sort of setup, CCS usually supply it via the setup_oscillator instruction, but I couldn't see any such option on the chip I was using.

Good luck... Smile
ronewart



Joined: 02 Aug 2008
Posts: 8

View user's profile Send private message Visit poster's website

PostPosted: Tue Oct 20, 2015 6:13 am     Reply with quote

PCM_Programmer -- thanks for pointing the way. I read your post yesterday, but did not have time to try. I went to bed thinking about your KISS program, and woke up in the middle of the night thinking -- "maybe the SDADC is kicking out interrupts and waking it up".

It ended up that I had two offenders, that needed to be disabled before calling sleep(); see below.

Thanks Ttelmah -- although this was not my particular problem, it is a great reference that I'll archive for next time.

Thanks PCM-Programmer and Ttelmah -- your suggestions and expertise got me going in the right direction. I appreciate the time you took to consider my problem, and your help.



Code:
   
// The solution was to DISABLE both the SDADC and the PWM Oscillator before calling sleep()

setup_SD_adc(SDADC_ENABLED | SDADC_NO_HALT | SDADC_GAIN_1 | SDADC_DITHER_LOW
      | SDADC_SVDD_SVSS | SDADC_BW_NORMAL , SDADC_CHOPPING_ENABLED |
      SDADC_INT_EVERY_5TH_SAMPLE | SDADC_RES_UPDATED_EVERY_INT_READY |
      SDADC_ROUND_16_BITS , SDADC_CLOCK_DIV_4 | SDADC_OSR_256 | SDADC_CLK_SYSTEM );

// also disable
//#use pwm(OC2,OUTPUT=PIN_D2,TIMER=2,FREQUENCY=2000,DUTY=50)




   


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