|
|
View previous topic :: View next topic |
Author |
Message |
Eugeneo
Joined: 30 Aug 2005 Posts: 155 Location: Calgary, AB
|
Pic24 deep sleep wakes up but doesn't run |
Posted: Sun Nov 08, 2015 1:33 pm |
|
|
Hi all. I've been trying to get this Pic to wake up on a RTCC interrupt with no luck.
The RTCC is functioning fine on SOSC.
Here's the strange thing - Right after programming the chip, it functions fine. When it's running stand alone, the measured currents show function and sequence as normal, but the serial ports and leds are not active.
Compiler version: 5.036
Chip: 24FJ128GC006
Code:
Code: |
#device adc=16
#use delay(internal = 8000000)
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOWRT //Program memory not write protected
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOJTAG //JTAG disabled
#FUSES NODEBUG //No Debug mode for ICD
#FUSES ICSP1 //ICD uses PGC1/PGD1 pins
#FUSES NOIESO //No Internal External Switch Over mode enabled
#FUSES NOBROWNOUT //No brownout reset
#fuses NOLVR //Low Voltage Regulator Disabled and RETEN has no effect
//#FUSES LVR //Low Voltage Regulator Enabled, Controlled in Software
#FUSES FRC_PS //Fast RC Oscillator with Post Scaler
#FUSES SOSC_SEL // Enable Secondary OSC as 32767 24pF xtal
//#FUSES SOSC
#FUSES OSCIO //OSC1 is I/O
//#FUSES NOOSCIO //OSC1 is clock output - strange, it consumes less power if left unconnected
#FUSES NOJTAG //JTAG disabled
#build(STACK = 0x400)
#define LED1 PIN_D10 // upper right output
#define led_on output_low(led1)
#define led_off output_high(led1)
#define TEST_FLASH {led_on; delay_ms(200); led_off; delay_ms(200);}
#define stop do{}while(1)
#define flash do{test_flash;}while(1)
int8 restart_value = 0;
// ******* Debug port ****
#pin_select U1TX = PIN_D1
#pin_select U1RX = PIN_D2
#use rs232(UART1, baud=19200, stream=SP1, errors)
rtc_time_t write_clock, read_clock; // use CSS defined struct
void set_clock(rtc_time_t &date_time)
{
date_time.tm_year=15;
date_time.tm_mon=11;
date_time.tm_mday=8;
date_time.tm_wday=4;
date_time.tm_hour=7;
date_time.tm_min=27;
date_time.tm_sec=0;
}
#int_default
void default_isr(void) {
reset_cpu();
}
#INT_RTC
void RTC(void)
{
rtc_read(&read_clock); //reads clock value from RTCC
printf("\r%02u/%02u/20%02u %02u:%02u:%02u",read_clock.tm_mon,read_clock.tm_mday,read_clock.tm_year,read_clock.tm_hour,read_clock.tm_min,read_clock.tm_sec);
}
/****************************************************************************
* Main app
****************************************************************************/
void Main(void) {
disable_interrupts(INTR_GLOBAL);
setup_oscillator(OSC_INTERNAL, 8000000);
//delay_ms(10);
#byte DSWAKE = getenv("byte:DSWAKE")
#bit DPSLP = getenv("bit:DPSLP")
#bit POR = getenv("bit:POR")
#bit RELEASE = getenv("bit:RELEASE")
#bit VREGS = getenv("bit:VREGS")
#bit PMSLP = getenv("bit:PMSLP")
#bit DSBOR = getenv("bit:DSBOR")
VREGS = 0;
DSBOR = 0;
if(DPSLP == 1)
{
// delay_ms(100);
DPSLP = 0;
RELEASE = 0;
//DSWAKE = 0;
// delay_ms(100);
}
restart_value = restart_cause();
if (restart_value==RESTART_POWER_UP)
{
// Enable RTCC module with seconds clock and no calibration
setup_rtc(RTC_ENABLE, 0x00);
set_clock(write_clock);
rtc_write(&write_clock);
fprintf(SP1, "\n\r\n\r\n\r\n\r\n\r\n\r\n\r");
fprintf(SP1, "Wait for clock to stabilize \n\r");
do {
rtc_read(&read_clock); //reads clock value from RTCC
}while (read_clock.tm_sec <2);
fprintf(SP1, "Starting \n\r");
}
setup_rtc_alarm(RTC_CHIME_ENABLE | RTC_ALARM_ENABLE, RTC_ALARM_10_SECONDS, 100);
enable_interrupts(INTR_GLOBAL);
enable_interrupts(INT_RTC);
test_flash;
fprintf(SP1, "DSWAKE = %u \n\r", DSWAKE);
fprintf(SP1, "RELEASE = %u \n\r", RELEASE);
fprintf(SP1, "DPSLP = %u \n\r", DPSLP);
fprintf(SP1, "POR = %u \n\r", POR);
fprintf(SP1, "Restart = %u \n\r", restart_value);
delay_ms(3000);
fprintf(SP1, "START Sleep \n\r");
delay_ms(10); // allow buffer(4) to print before sleep
#bit DSEN=getenv("bit:DSEN")
#bit RETEN=getenv("bit:RETEN")
RETEN=FALSE; //do not retain - normal voltages are present
//RETEN=TRUE; //enable the low power regulator
DSEN=TRUE;
DSEN=TRUE; //This must be set _twice_
sleep(SLEEP_FULL);
delay_ms(100);
fprintf(SP1, "Should never get here \n\r");
//reset_cpu();
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Tue Nov 10, 2015 6:50 am |
|
|
Ok, I don't use that PIC so some general comments....
1) go back and get the serial ports and LEDs to work right. Forget about the 'go to sleep' part of the program.
2) get the RTC_ISR to work properly. it's bad 'form' to have prints inside an ISR!! Simply set a flag and have main() check if set or not.
3) first thing in main() you do is disable all interrupts,after that your code looks 'confusing to me' and I'm not convinced you can/or have enable interrupts BEFORE the PIC goes to sleep. If the RTCC INT is not enabled before then it'll never wakeup the PIC!
4) no need for the setup_osc in main() , already done at beginning....
Jay |
|
|
Eugeneo
Joined: 30 Aug 2005 Posts: 155 Location: Calgary, AB
|
|
Posted: Tue Nov 10, 2015 9:13 am |
|
|
Thanks for the pointers temtronic.
I'll try these things out.
So I've narrowed the problem down. When the MCU restarts and detects a wake up condition from deep sleep (DPSLP == 1), Clearing the DPSLP doesn't fully active all the IO.
Code: |
Main
{
if(DPSLP == 1)
{
DPSLP = 0; // These 2 lines seem to have no effect on the IO
RELEASE = 0;
}
The rest of the code with sleep works fine
}
|
Last edited by Eugeneo on Tue Nov 10, 2015 10:06 am; edited 2 times in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Tue Nov 10, 2015 9:57 am |
|
|
As a comment, you do realise that deep sleep will erase all the RAM.
There are a number of sleep modes:
sleep
low voltage sleep
retention deep sleep
deep sleep
The last one erases the memory. Only 'retention deep sleep' keeps the memory contents alive when in deep sleep.
Without the variables maintained, all your variables will need to be re-initialised after waking. All the peripherals will need to be re-initialised (including the initialisation the compiler normally does 'for you' in automatically). This is why the code will restart _at the reset vector_ from such a sleep. Look at the table on 'exiting power saving modes'. |
|
|
Eugeneo
Joined: 30 Aug 2005 Posts: 155 Location: Calgary, AB
|
|
Posted: Tue Nov 10, 2015 10:14 am |
|
|
Ttelmah wrote: | As a comment, you do realise that deep sleep will erase all the RAM.
There are a number of sleep modes:
sleep
low voltage sleep
retention deep sleep
deep sleep
The last one erases the memory. Only 'retention deep sleep' keeps the memory contents alive when in deep sleep.
Without the variables maintained, all your variables will need to be re-initialised after waking.... |
Deep sleep with no retention with the lowest possible power consumption is the goal. So far the consumption is about 90 -110 uA most of which are from the LDOs and power switches in their off states.
Upon waking up from deep sleep without retention, can I force a soft reset and expect the MCU to run from an "almost" power up condition?
Thanks for you're help guys! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Tue Nov 10, 2015 11:32 am |
|
|
To go that low, you are stopping the RTCC as well. The RTCC draws over three hundred uA.
If you are doing that, why not just switch the processor off?. A FET switch, can power it down completely.... |
|
|
Eugeneo
Joined: 30 Aug 2005 Posts: 155 Location: Calgary, AB
|
|
Posted: Tue Nov 10, 2015 11:59 am |
|
|
Ttelmah wrote: | To go that low, you are stopping the RTCC as well. The RTCC draws over three hundred uA.
If you are doing that, why not just switch the processor off?. A FET switch, can power it down completely.... |
A FET switch with a dedicated RTC using the interrupts and an ultra low consumption front end for battery management (maybe a 10F322) would be nice.
Unfortunately I have some boards that have been populated ready for testing deployment. |
|
|
Eugeneo
Joined: 30 Aug 2005 Posts: 155 Location: Calgary, AB
|
|
Posted: Tue Nov 10, 2015 2:58 pm |
|
|
This is very odd. If you set the RELEASE bit low twice, it works.
This does not work:
Code: |
#bit DPSLP = getenv("bit:DPSLP")
#bit RELEASE = getenv("bit:RELEASE")
main
{
if(DPSLP == 1)
{
DPSLP = 0;
RELEASE = 0;
delay_cycles(1);
delay_cycles(1);
delay_cycles(1);
}
}
|
This does:
Code: |
#bit DPSLP = getenv("bit:DPSLP")
#bit RELEASE = getenv("bit:RELEASE")
main
{
If(DPSLP == 1)
{
DPSLP = 0;
RELEASE = 0;
RELEASE = 0;
delay_cycles(1);
delay_cycles(1);
delay_cycles(1);
}
}
|
From the datasheet: (just in case)
Code: |
Note: To re-enter Deep Sleep after a Deep Sleep
wake-up, allow a delay of at least 3 TCY
after clearing the RELEASE bit.
|
|
|
|
|
|
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
|