• AVR Freaks

Hot!PIC24FJ128GA204 can not wake up from DEEP SLEEP

Author
Daijie
New Member
  • Total Posts : 2
  • Reward points : 0
  • Joined: 2017/10/03 03:09:18
  • Location: 0
  • Status: offline
2017/10/17 04:59:21 (permalink)
0

PIC24FJ128GA204 can not wake up from DEEP SLEEP

Hi,
 
I am using PIC24FJ128GA204, and I attempt to set the device into DEEP SLEEP. Below is code: 
#include "mcc_generated_files/mcc.h"

void delay(){
    unsigned int i;unsigned int j;
    for(i=1;i<1000;i++){
        for (j=1;j<110;j++)
        {
            {asm("NOP");}
        }
    } 
}
int main(void) {
    delay();
    SYSTEM_Initialize();
    if (RCONbits.DPSLP==1) // it wakes up from DEEP SLEEP, the LED blinks.
    {
        RCONbits.DPSLP=0; 
        _RA8=1; // RA8 pin-->LED
        _TRISA8=0;
        delay();
        _TRISA8=1;
        delay();
        _TRISA8=0;
        delay();
        _TRISA8=1;
        delay();
        _TRISA8=0;
        delay();
        _TRISA8=1;
        delay();
        _RELEASE = 0;
    }
    _RA8=1;
    _TRISA8=0;
    delay();
    _TRISA8=1;
    delay();
    _TRISA8=0;
    delay();
    _TRISA8=1;
    delay();
    asm("MOV #0x8000, w2");
    asm("MOV w2, DSCON");
    asm("MOV w2, DSCON");
    asm("PWRSAV #0");
    while(1);
    return 0;
}

and the system configuration bits are :

// CONFIG4
#pragma config DSWDTPS = DSWDTPSC // Deep Sleep Watchdog Timer Postscale Select bits->1:131072 (4.228 Secs)
#pragma config DSWDTOSC = LPRC // DSWDT Reference Clock Select->DSWDT uses LPRC as reference clock
#pragma config DSBOREN = ON // Deep Sleep BOR Enable bit->DSBOR Enabled
#pragma config DSWDTEN = ON // Deep Sleep Watchdog Timer Enable->DSWDT Enabled
#pragma config DSSWEN = ON // DSEN Bit Enable->Deep Sleep is controlled by the register bit DSEN
#pragma config PLLDIV = DISABLED // USB 96 MHz PLL Prescaler Select bits->PLL Disabled
#pragma config I2C1SEL = DISABLE // Alternate I2C1 enable bit->I2C1 uses SCL1 and SDA1 pins
#pragma config IOL1WAY = ON // PPS IOLOCK Set Only Once Enable bit->Once set, the IOLOCK bit cannot be cleared

// CONFIG3
#pragma config WPFP = WPFP127 // Write Protection Flash Page Segment Boundary->Page 127 (0x1FC00)
#pragma config SOSCSEL = OFF // SOSC Selection bits->Digital (SCLKI) mode
#pragma config WDTWIN = PS25_0 // Window Mode Watchdog Timer Window Width Select->Watch Dog Timer Window Width is 25 percent
#pragma config PLLSS = PLL_PRI // PLL Secondary Selection Configuration bit->PLL is fed by the Primary oscillator
#pragma config BOREN = ON // Brown-out Reset Enable->Brown-out Reset Enable
#pragma config WPDIS = WPDIS // Segment Write Protection Disable->Disabled
#pragma config WPCFG = WPCFGDIS // Write Protect Configuration Page Select->Disabled
#pragma config WPEND = WPENDMEM // Segment Write Protection End Page Select->Write Protect from WPFP to the last page of memory

// CONFIG2
#pragma config POSCMD = NONE // Primary Oscillator Select->Primary Oscillator Disabled
#pragma config WDTCLK = LPRC // WDT Clock Source Select bits->WDT uses LPRC
#pragma config OSCIOFCN = OFF // OSCO Pin Configuration->OSCO/CLKO/RA3 functions as CLKO (FOSC/2)
#pragma config FCKSM = CSDCMD // Clock Switching and Fail-Safe Clock Monitor Configuration bits->Clock switching and Fail-Safe Clock Monitor are disabled
#pragma config FNOSC = FRCDIV // Initial Oscillator Select->Fast RC Oscillator with Postscaler (FRCDIV)
#pragma config ALTCMPI = CxINC_RB // Alternate Comparator Input bit->C1INC is on RB13, C2INC is on RB9 and C3INC is on RA0
#pragma config WDTCMX = LPRC // WDT Clock Source Select bits->WDT always uses LPRC as its clock source
#pragma config IESO = ON // Internal External Switchover->Enabled

// CONFIG1
#pragma config WDTPS = PS32768 // Watchdog Timer Postscaler Select->1:32768
#pragma config FWPSA = PR128 // WDT Prescaler Ratio Select->1:128
#pragma config WINDIS = OFF // Windowed WDT Disable->Standard Watchdog Timer
#pragma config FWDTEN = OFF // Watchdog Timer Enable->WDT disabled in hardware; SWDTEN bit disabled
#pragma config ICS = PGx1 // Emulator Pin Placement Select bits->Emulator functions are shared with PGEC1/PGED1
#pragma config LPCFG = OFF // Low power regulator control->Disabled - regardless of RETEN
#pragma config GWRP = OFF // General Segment Write Protect->Write to program memory allowed
#pragma config GCP = OFF // General Segment Code Protect->Code protection is disabled
#pragma config JTAGEN = OFF // JTAG Port Enable->Disabled

 
If pic24fj is connected with a current meter, it can easily enter into and wake up from DEEP SLEEP. However, if the PIC24 device is directly connected with a battery, the PIC24 can enter into DEEP SLEEP, while it can not be wakened by DeepSleepWatchdogTimer.
 
Is there anyone once meeting the same problem? Or could you please give me some tips?
#1

7 Replies Related Threads

    Daijie
    New Member
    • Total Posts : 2
    • Reward points : 0
    • Joined: 2017/10/03 03:09:18
    • Location: 0
    • Status: offline
    Re: PIC24FJ128GA204 can not wake up from DEEP SLEEP 2017/10/18 00:39:53 (permalink)
    +1 (1)
    Hi,
     
    The problem above mentioned has been solved. After the MCU wakes up from DEEP SLEEP, the status of pins should be released before the blink of the LED. For more detail, just read Page 159 of the PIC24FJ128A204 datasheet.
    #2
    mk1907
    New Member
    • Total Posts : 3
    • Reward points : 0
    • Joined: 2020/07/29 01:58:44
    • Location: 0
    • Status: offline
    Re: PIC24FJ128GA204 can not wake up from DEEP SLEEP 2020/07/31 05:17:44 (permalink)
    -1 (1)
    Hello,
    I checked this code and tried to compile it and it does goes into sleep however I think this is not a deep sleep code. When I measured the microcontroller's current it was 80 uA, it was supposed to be nano amperes. I defined every port as input so that they would not connect to Vdd but still no change. Are you 100% sure that the controller goes into deep sleep? 
     
    Kind Regards
    #3
    upand_at_them
    Super Member
    • Total Posts : 588
    • Reward points : 0
    • Joined: 2005/05/16 07:02:38
    • Location: Pennsylvania
    • Status: online
    Re: PIC24FJ128GA204 can not wake up from DEEP SLEEP 2020/07/31 11:20:05 (permalink)
    +1 (1)
    Please create your own thread.  This one is almost three years old and the poster hasn't returned since then.
    #4
    dan1138
    Super Member
    • Total Posts : 3731
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: PIC24FJ128GA204 can not wake up from DEEP SLEEP 2020/07/31 20:14:22 (permalink)
    +1 (1)
    With respect upand_at_them, to me it seem that the post from mk1907 is relevant even though the Original Poster may be long gone.
     
    It seems that getting the PIC24FJ128GA204 in and out of deep sleep is very tricky and impossible to debug.
     
    I just got this code working in the DM240004 / PIC24F Curiosity Board
    /*
     * File:   main.c
     * Author: dan1138
     * Target: PIC24FJ128GA204
     * Compiler: XC16 v1.41
     * IDEP MPLABX v5.40
     *
     *                                                           PIC24FJ128GA204
     *               +----------------+               +--------------+                +-----------+                +--------------+
     *         <>  1 : RB9/RP9        :    LED2 <> 12 : RA10         :          <> 23 : RB2/RP2   : X2-32KHZ <> 34 : RA4/SOSCO    :
     *  RGB_G  <>  2 : RC6/RP22       :         <> 13 : RA7          :          <> 24 : RB3/RP3   :     LED1 <> 35 : RA9          :
     *  RGB_B  <>  3 : RC7/RP23       :         <> 14 : RB14/RP14    :      POT <> 25 : RC0/RP16  :          <> 36 : RC3/RP19     :
     *     S2  <>  4 : RC8/RP24       :         <> 15 : RB15/RP15    :          <> 26 : RC1/RP17  :          <> 37 : RC4/RP20     :
     *     S1  <>  5 : RC9/RP25       :     GND -> 16 : AVSS         :          <> 27 : RC2/RP18  :    RGB_R <> 38 : RC5/RP21     :
     *    3v3  <>  6 : VBAT           :     3v3 -> 17 : AVDD         :      3v3 -> 28 : VDD       :      GND -> 39 : VSS          :
     *   10uF  ->  7 : VCAP           : ICD_VPP -> 18 : MCLR         :      GND -> 29 : VSS       :      3v3 -> 40 : VDD          :
     *         <>  8 : RB10/RP11/PGD2 :         <> 19 : RA0/AN0      :          <> 30 : RA2/OSCI  :          <> 41 : RB5/RP5/PGD3 :
     *         <>  9 : RB11/RP11/PGC2 :         <> 20 : RA1/AN1      :          <> 31 : RA3/OSCO  :          <> 42 : RB6/RP6/PGC3 :
     *         <> 10 : RB12/RP12      : ICD_PGD <> 21 : RB0/RP0/PGD1 :          <> 32 : RA8       :          <> 43 : RB7/RP7/INT0 :
     *         <> 11 : RB13/RP13      : ICD_PGC <> 22 : RB1/RP1/PGC1 : X2-32KHZ <> 33 : RB4/SOSCI :          <> 44 : RB8/RP8      :
     *               +----------------+               +--------------+                +-----------+                +--------------+
     *                                                              TQFP-44
     *
     * Created on July 24, 2020, 2:51 PM
     *
     * Description:
     *
     * This application tests how to enter and leave the Deep sleep mode of the PIC24FJ128GA204.
     *
     * Code runs on the DM240004 / PIC24F Curiosity Board
     *
     * The "normal" operation is:
     *  1 - Power-On-Reset
     *  2 - Report reset event
     *  3 - Configure GPIO pins
     *  4 - Clear Deep Sleep flags
     *  5 - Setup to enter Deep Sleep
     *  6 - Enter power save mode and enter Deep Sleep state
     *  7 - Wake from Deep Sleep and repeat from step 2.
     *
     * Notes:
     *  Waking from sleep when the system oscillator uses the PLL will
     *  cause the system clock to be unstable and address error traps.
     *
     *  The workaround is to set IESO = ON in the configuration words.
     *
     *  And another thing, writes to the DSGPR0 and DSGPR1 deep sleep
     *  context save register require two writes.
     *
     *  And another thing, bits in the DSWAKE register cannot be cleared
     *  individually even using two write when the DSCONbits.RELEASE bit
     *  is set.
     */

    #pragma config FNOSC = FRC, POSCMD = NONE, PLLSS = PLL_FRC, PLLDIV = PLL4X
    #pragma config FCKSM = CSECME, IESO = ON

    #pragma config DSWDTPS = DSWDTPSC       /* Deep Sleep Watchdog Timer Postscale Select bits (1:131072 (4.228 Secs)) */
    #pragma config DSWDTOSC = LPRC, DSBOREN = OFF, DSWDTEN = ON, DSSWEN = ON

    #pragma config FWPSA = PR128, WDTPS = PS2048 /* Sleep Watchdog Timer Pre(1:128) and Post(1:2048) scale Select bits for about 8.4 Secs */
    #pragma config WINDIS = OFF, FWDTEN = ON

    #pragma config WPFP = WPFP127, WPDIS = WPDIS, WPCFG = WPCFGDIS
    #pragma config WPEND = WPENDMEM, WDTCLK = LPRC, WDTWIN = PS25_0, WDTCMX = LPRC, LPCFG = OFF

    #pragma config I2C1SEL = DISABLE, OSCIOFCN = ON
    #pragma config IOL1WAY = OFF, BOREN = OFF, SOSCSEL = ON
    #pragma config GWRP = OFF, ALTCMPI = CxINC_RB
    #pragma config ICS = PGx1, GCP = OFF, JTAGEN = OFF

    #include <xc.h>
    #include <stdio.h>

    #define FSYS        (32000000L)
    #define FCY         (FSYS/2)    /* Instruction Cycle Frequency */
    #define UARTNUM     2               //Which device UART to use
        
    #define BAUDRATE    9600L
    //#define USE_HI_SPEED_BRG            //Use BRGH=1, UART high speed mode
        
    //UART Baud Rate Calculation *******************************************************
    #ifdef USE_HI_SPEED_BRG
        #define BRG_DIV 4L
    #else
        #define BRG_DIV 16L
    #endif
        
    #define BAUDRATEREG    ( ((FCY + (BRG_DIV * BAUDRATE / 2L)) / (BRG_DIV * BAUDRATE)) - 1L)
    #define BAUD_ACTUAL    (FCY/BRG_DIV/(BAUDRATEREG+1))
        
    #define BAUD_ERROR          ((BAUD_ACTUAL > BAUDRATE) ? BAUD_ACTUAL-BAUDRATE : BAUDRATE-BAUD_ACTUAL)
    #define BAUD_ERROR_PRECENT  ((BAUD_ERROR*100L+BAUDRATE/2L)/BAUDRATE)
        
    #if (BAUD_ERROR_PRECENT > 3)
        #error "UART frequency error is worse than 3%"
    #elif (BAUD_ERROR_PRECENT > 2)
        #warning "UART frequency error is worse than 2%"
    #endif
        
    //UART Configuration ***************************************************************
    #define UARTREG2(a,b)     U##a##b
    #define UARTREG(a,b)    UARTREG2(a,b)
        
    #define UxMODE      UARTREG(UARTNUM,MODE)
    #define UxBRG       UARTREG(UARTNUM,BRG)
    #define UxSTA       UARTREG(UARTNUM,STA)
    #define UxRXREG     UARTREG(UARTNUM,RXREG)
    #define UxTXREG     UARTREG(UARTNUM,TXREG)
    #define UxMODEbits  UARTREG(UARTNUM,MODEbits)
    #define UxSTAbits   UARTREG(UARTNUM,STAbits)
    #define UxTX_IO     UARTREG(UARTNUM,TX_IO)
    /*
     * Select UART as the default standard I/O port
     */
    int __C30_UART = UARTNUM;
    /*
     * WARNING: Not a portable function.
     *          Maximum 16MHz instruction cycle clock.
     *          Minimum  8KHz instruction cycle clock.
     *
     */
    void delay_ms( unsigned long delay )
    {
        if(delay)
        {
            __asm(  "0: repeat %0         \n"
                    "   nop               \n"
                    "   sub  %1,#0x1,%1   \n"
                    "   subb %d1,#0x0,%d1 \n"
                    "   bra  nz,0b        \n"
            :: "r" (FCY/1000L-6L), "C" (delay));
        }
    }
    /*
     * Process flags in the RCON register
     *
     * Returns Power On Reset state:
     *   0 = Power On Reset
     *   1 = Deep sleep wake up, fault
     *   2 = MCLR reset
     *   3 = Watchdog timeout reset, never in sleep or deep sleep
     *   4 = Wake from sleep
     *   5 = Wake from idle
     *   6 = Software reset instruction
     *   7 = Deep sleep wake up, MCLR event
     *   8 = Deep sleep wake up, WDTO event
     *   9 = Deep sleep wake up, RTCC event
     *  10 = Deep sleep wake up, INT0 event
     *  11 = Deep sleep wake up, Unknown
     * 255 = Unknown reset type, might be a jump to zero.
     */  

    unsigned short RCON_Event(void)
    {
        unsigned short Result;
        
        Result = RCON;
        
        if(RCONbits.DPSLP)
        {
            RCONbits.DPSLP = 0;
            if(DSWAKEbits.DSFLT)
            {
                Result = 1;
            } else if(DSWAKEbits.DSMCLR)
            {
                Result = 7;
            } else if (DSWAKEbits.DSWDT)
            {
                Result = 8;
            } else if(DSWAKEbits.DSRTCC)
            {
                Result = 9;
            } else if(DSWAKEbits.DSINT0)
            {
                Result = 10;
            } else
            {
                Result = 11;
            }
        }
        else if(RCONbits.POR)
        {
            Result = 0;
            RCONbits.POR = 0;
        }
        else if(RCONbits.BOR)
        {
            Result = 0;
            RCONbits.BOR = 0;
        }
        else if(RCONbits.EXTR)
        {
            Result = 2;
            RCONbits.EXTR = 0;
        }
        else if(RCONbits.WDTO)
        {
            Result = 3;
            RCONbits.WDTO = 0;
        }
        else if(RCONbits.SWR)
        {
            Result = 6;
            RCONbits.SWR = 0;
        }
        else if(RCONbits.SLEEP)
        {
            Result = 4;
            RCONbits.SLEEP = 0;
        }
        else if(RCONbits.IDLE)
        {
            Result = 5;
            RCONbits.IDLE = 0;
        }
        else
        {
            printf("RCON=%04X\r\n",Result);
            Result = 255;    /* Unknown reset type */
        }
        return Result;
    }
    /*  
     * Trap Handler for oscillator fail
     */  
    volatile unsigned short Trap = 0;

    void __attribute__((interrupt,no_auto_psv)) _OscillatorFail(void)
    {
        while(!Trap)
        {
            INTCON1bits.OSCFAIL = 0;
            LATCbits.LATC5  = 1;     /* turn RED LED on */
            delay_ms(1);
            ClrWdt();
            LATCbits.LATC5  = 0;     /* turn RED LED off */
            delay_ms(249);
            ClrWdt();
        }
        Trap = 0;
     }
    void __attribute__((interrupt,no_auto_psv)) _AddressError(void)
    {
        ClrWdt();
        printf("\r\nAddress error trap\r\n");
        while(!Trap)
        {
            LATCbits.LATC6  = 1;     /* turn GREEN LED on */
            delay_ms(1);
            ClrWdt();
            LATCbits.LATC6  = 0;     /* turn GREEN LED off */
            delay_ms(249);
            ClrWdt();
        }
        Trap = 0;
    }
    void __attribute__((interrupt,no_auto_psv)) _StackError(void)
    {
        while(!Trap)
        {
            LATCbits.LATC7  = 1;     /* turn BLUE LED on */
            delay_ms(1);
            ClrWdt();
            LATCbits.LATC7  = 0;     /* turn BLUE LED off */
            delay_ms(249);
            ClrWdt();
        }
        Trap = 0;
    }
    void __attribute__((interrupt,no_auto_psv)) _MathError(void)
    {
            LATCbits.LATC5  = 1;     /* turn RED LED on */
            delay_ms(1);
            ClrWdt();
            LATCbits.LATC5  = 0;     /* turn RED LED off */
            delay_ms(249);
            ClrWdt();
    }
    void __attribute__((interrupt,no_auto_psv)) _DefaultInterrupt(void)
    {
        while(!Trap)
        {
            ClrWdt();
        }
        Trap = 0;
    }
    /*  
     * Handler to catch INT0 interrupt
     */  
    void __attribute__((interrupt,no_auto_psv)) _INT0Interrupt(void)
    {
        IFS0bits.INT0IF = 0;    /* clear request flag */
        while(!UxSTAbits.TRMT);
        printf("  INT0 event\r\n");
        while(!UxSTAbits.TRMT);
    }
    /*  
     * Handler to catch INT1 interrupt
     */  
    void __attribute__((interrupt,no_auto_psv)) _INT1Interrupt(void)
    {
        IFS1bits.INT1IF = 0;    /* clear request flag */
        while(!UxSTAbits.TRMT);
        printf("  INT1 event\r\n");
        while(!UxSTAbits.TRMT);
    }
    /*
     * Setup INT0 external interrupt
     */
    void INT0_Init(void)
    {
        ANSC   &= ~(1<<9);      /* make pins digital I/O */
        TRISC  |=  (1<<9);      /* make pin an input */
        CNPD2bits.CN19PDE = 0;  /* disable weak pull-down on RC9/RP25/CN19 */
        CNPU2bits.CN19PUE = 1;  /* enable weak pull-up on RC9/RP25/CN19 */
        ANSB   &= ~(1<<7);      /* make pins digital I/O */
        TRISB  |=  (1<<7);      /* make pin an input */
        CNPD2bits.CN23PDE = 0;  /* disable weak pull-down on RB7/RP7/CN23 */
        CNPU2bits.CN23PUE = 1;  /* enable weak pull-up on RB7/RP7/CN23 */
        INTCON2bits.INT0EP = 1; /* negative edge */
        IPC0bits.INT0IP = 4;    /* select priority level 4 */
        IFS0bits.INT0IF = 0;    /* clear request flag */
        IEC0bits.INT0IE = 1;    /* enable interrupt source */
    }
    /*
     * Setup INT1 external interrupt
     */
    void INT1_Init(void)
    {
        /* Unlock Registers */
        __builtin_write_OSCCONL(OSCCON & ~_OSCCON_IOLOCK_MASK);
        _INT1R = 0b011000;      /* Switch S2 on RC8/RP24 */
        /* Lock Registers */
        __builtin_write_OSCCONL(OSCCON | _OSCCON_IOLOCK_MASK);
        ANSC   &= ~(1<<8);      /* make pins digital I/O */
        TRISC  |=  (1<<8);      /* make pin an input */
        CNPD2bits.CN20PDE = 0;  /* disable weak pull-down on RC8/RP24/CN20 */
        CNPU2bits.CN20PUE = 1;  /* enable weak pull-up on RC8/RP24/CN20 */
        INTCON2bits.INT1EP = 1; /* negative edge */
        IPC5bits.INT1IP = 4;    /* select priority level 4 */
        IFS1bits.INT1IF = 0;    /* clear request flag */
        IEC1bits.INT1IE = 1;    /* enable interrupt source */
    }
    /*  
     * SETUP UART: No parity, one stop bit, polled
     */  
    void Uart_Init(void)
    {   
        /* Unlock Registers */
        __builtin_write_OSCCONL(OSCCON & ~_OSCCON_IOLOCK_MASK);
        _U2RXR = 0b0000101;   /* U2RXD   := RP5/RB5 */
        _RP6R  = 0b0000101;   /* RP6/RB6 := U2TXD   */        
        /* Lock Registers */
        __builtin_write_OSCCONL(OSCCON | _OSCCON_IOLOCK_MASK);
        UxMODEbits.UARTEN = 1;      //enable UART
        UxBRG = BAUDRATEREG;
        
    #ifdef USE_HI_SPEED_BRG
        UxMODEbits.BRGH = 1;    //use high speed mode
    #else
        UxMODEbits.BRGH = 0;    //use low speed mode
    #endif
        
        UxSTA = 0x0400;  //Enable TX
    }   
    /*
     * Initialize this PIC
     */
    void PIC_Init(unsigned short ResetType)
    {
        unsigned short ClockSwitchTimeout;

        /*
         * Disable all interrupt sources
         */
        __builtin_disi(0x3FFF); /* disable interrupts for 16383 cycles */
        IEC0 = 0;
        IEC1 = 0;
        IEC2 = 0;
        IEC3 = 0;
        IEC4 = 0;
        IEC5 = 0;
        IEC6 = 0;
        IEC7 = 0;
        __builtin_disi(0x0000); /* enable interrupts */

        ANSA   =  0x0000; /* Set for digital I/O */
        ANSB   =  0x0000; /* Set for digital I/O */
        ANSC   =  0x0001; /* Set for digital I/O */
        
        _NSTDIS = 1;    /* disable interrupt nesting */
            
        LATA = 0;
        LATB = 0;
        LATC = 0;

        TRISA   = 0xF9FF;
        TRISB   = 0xFFFF;
        TRISC   = 0xFF9F;
        
        /* enable pull-down on digital inputs */
        CNPU1   = 0;
        CNPU2   = 0;
        CNPU3   = 0;
        CNPD1   = 0xFEFF;
        CNPD2   = 0x7BCB;
        CNPD3   = 0x0006;

        CLKDIV  = 0x0000; /* set for FRC clock 8MHZ operations */

        /*
         * Release deep sleep freeze
         */
        DSCONbits.RELEASE = 0;
        DSCONbits.RELEASE = 0;
        
        /* Spin wait to let things settle after a reset */
        for(ClockSwitchTimeout=60000; ClockSwitchTimeout;--ClockSwitchTimeout) Nop();

        /*
         * At Power On Reset the configuration words set the system clock
         * to use the FRC oscillator. At this point we need to enable the
         * PLL to get the system clock running at 32MHz.
         *
         * Clock switching on the 24FJ family with the PLL can be a bit tricky.
         *
         * First we need to check if the configuration words enabled clock
         * switching at all, then turn off the PLL, then setup the PLL and
         * finally enable it. Sounds simple, I know. Make sure you verify this
         * clock setup on the real hardware.
         */
        if(!OSCCONbits.CLKLOCK) /* if primary oscillator switching is unlocked */
        {
            if(OSCCONbits.COSC != 0b000)
            {
                /* The system oscillator is not the FRC so switch to FRC */
                LATAbits.LATA9 = 1;    /* turn on LED1 for debug, show we are switching to FRC */
                /* Spin wait so LED can be seen */
                delay_ms(4);

                /* Select primary oscillator as OSCFDIV */
                __builtin_write_OSCCONH(0b000);

                /* Request switch primary to new selection */
                __builtin_write_OSCCONL(OSCCON | (1 << _OSCCON_OSWEN_POSITION));

                /* wait, with timeout, for clock switch to complete */
                for(ClockSwitchTimeout=10; ClockSwitchTimeout;--ClockSwitchTimeout)
                {
                    if ((OSCCONbits.OSWEN == 0) && (OSCCONbits.COSC == 0b000)) break;
                    ClrWdt();
                    LATAbits.LATA9 = 0;
                    delay_ms(96);
                    LATAbits.LATA9 = 1;
                    delay_ms(4);
                }
                if(ClockSwitchTimeout != 0) LATAbits.LATA8 = 0;    /* turn off LED for debug, show that switch to FRC worked */
            }

            LATAbits.LATA10 = 1;    /* turn on LED2 for debug, show we are trying to switch to FRCPLL */
            /* Spin wait so LED can be seen */
            delay_ms(4);
            
            /* Select primary oscillator as FRCPLL */
            __builtin_write_OSCCONH(0b001);

            /* Request switch primary to new selection */
            __builtin_write_OSCCONL(OSCCON | (1 << _OSCCON_OSWEN_POSITION));
            
            /* wait, with timeout, for clock switch to complete */
            for(ClockSwitchTimeout=5; ClockSwitchTimeout;--ClockSwitchTimeout)
            {
                ClrWdt();
                if ((OSCCONbits.OSWEN == 0) && (OSCCONbits.COSC == 0b001)) break;
                ClrWdt();
                LATAbits.LATA10 = 0;
                delay_ms(96);
                LATAbits.LATA10 = 1;
                delay_ms(4);
            }

            /* wait, with timeout, for the PLL to lock */
            for(ClockSwitchTimeout=5; ClockSwitchTimeout;--ClockSwitchTimeout)
            {
                if (OSCCONbits.LOCK) break;
                ClrWdt();
                delay_ms(100);
            }
            
            if(ClockSwitchTimeout != 0) LATAbits.LATA10 = 0;    /* turn off LED2 for debug, show that switch to FRCPLL worked */
            
            /* at this point the system oscillator should be 32MHz */
        }
    }
    /*
     * Main Application
     */
    int main(void)
    {
        unsigned short ResetType;
        unsigned short WakeType;
        unsigned short Count;
        unsigned short Temp;

        ResetType = RCON_Event();

        Uart_Init();
        PIC_Init(ResetType);
        INT0_Init();
        INT1_Init();

        ClrWdt();
        
        if ((ResetType == 0) || (ResetType == 2) || (ResetType == 9))
        {
            /* Spin wait for UART TX output initialization glitch to settle */
            unsigned int SpinWait;
            for(SpinWait=60000;SpinWait;SpinWait--) Nop();
        }
        
        if (ResetType == 0)
        {
            printf("  Power on reset, hello there\r\n");
            //DSGPR0 = 0;
            //DSGPR0 = 0;
            __asm("disi #2\n mov %0,%1\n mov %0,%1\n":: "a" (0), "U" (DSGPR0));
            //DSGPR1 = 0;
            //DSGPR1 = 0;
            __asm("disi #2\n mov %0,%1\n mov %0,%1\n":: "a" (0), "U" (DSGPR1));
        }
        else if (ResetType == 1)
        {
            printf("  Wake from Deep Sleep, fault\r\n");
        }
        else if (ResetType == 7)
        {
            //Temp = DSGPR1 + 1;
            //DSGPR1 = Temp;
            //DSGPR1 = Temp;
            __asm("disi #2\n mov %0,%1\n mov %0,%1\n":: "a" (DSGPR1 + 1), "U" (DSGPR1));
            printf("  Wake from Deep Sleep, MCLR, %u\r\n", DSGPR1);
        }
        else if (ResetType == 8)
        {
            //Temp = DSGPR0 + 1;
            //DSGPR0 = Temp;
            //DSGPR0 = Temp;
            __asm("disi #2\n mov %0,%1\n mov %0,%1\n":: "a" (DSGPR0 + 1), "U" (DSGPR0));
            printf("  Wake from Deep Sleep, DSWDT timeout, %u\r\n", DSGPR0);
        }
        else if (ResetType == 9)
        {
            printf("  Wake from Deep Sleep, RTCC\r\n");
        }
        else if (ResetType == 10)
        {
            printf("  Wake from Deep Sleep, INT0\r\n");
        }
        else if (ResetType == 11)
        {
            printf("  Wake from Deep Sleep, Unknown, DSWAKE=0x%04X\r\n", DSWAKE);
        }
        else if (ResetType == 2)
        {
            printf("  MCLR reset\r\n");
        }
        else if (ResetType == 3)
        {
            printf("  WDT timeout reset\r\n");
        }
        else if (ResetType == 4)
        {
            printf("  WDT wake from sleep\r\n");
        }
        else if (ResetType == 5)
        {
            printf("  WDT wake from idle\r\n");
        }
        else if (ResetType == 6)
        {
            printf("  Software reset\r\n");
        }
        else
        {
            printf("  Unknown reset\r\n");
        }
        
    #if defined(USE_IPL_TO_DISABLE_INTERRUPTS)
        _NSTDIS = 0;        /* enable interrupt nesting */
        SRbits.IPL = 7;     /* Disable user interrupts */
        _NSTDIS = 1;        /* disable interrupt nesting */
        if (ResetType == 0) printf("  Interrupts disabled using IPL\r\n");
    #elif defined(USE_GIE_TO_DISABLE_INTERRUPTS)
        INTCON2bits.GIE = 0;
        if (ResetType == 0) printf("  Interrupts disabled using GIE\r\n");
    #else
        if (ResetType == 0) printf("  Interrupts are enabled\r\n");
    #endif
        /* Main application loop */
        Count = 0;
        for(;;)
        {
            while(!UxSTAbits.TRMT);
            
            IFS0bits.INT0IF = 0;    /* clear request flag */
            IFS1bits.INT1IF = 0;    /* clear request flag */
            IFS3bits.RTCIF  = 0;    /* clear request flag */

    #define ENTER_DEEP_SLEEP
            /* enter sleep  */
    #if defined(ENTER_DEEP_SLEEP)
            __asm("disi #6");
            __asm("bset DSCON, #15");
            __asm("nop");
            __asm("nop");
            __asm("nop");
            __asm("bset DSCON, #15");
            __asm("pwrsav #0");     /* deep sleep */
    #elif defined(ENTER_SLEEP)
            RCONbits.RETEN = 1;
            __asm("pwrsav #0");     /* sleep */
    #else
            __asm("pwrsav #1");     /* idle */
    #endif

            Temp = RCON;
            WakeType = RCON_Event();

            printf("AppLoop, WDT wake from sleep, type %u, RCON=%04X, %u\r\n", WakeType, Temp,++Count);
        }
        
        return 0;
    }

    It is long and complicated but it does work.
     
    In the process I saw some very strange things. The controller does not always clear the DSCONbits.RELEASE bit on the first try and weirdness begins when trying to enter Deep Sleep with this be still set.
     
    Keep in mind that a lot of the bits associated with the Deep Sleep only get cleared from a Power-On-Reset and remain set for MCLR, Brown out, and WDT resets.
    post edited by dan1138 - 2020/08/02 09:09:50
    #5
    mk1907
    New Member
    • Total Posts : 3
    • Reward points : 0
    • Joined: 2020/07/29 01:58:44
    • Location: 0
    • Status: offline
    Re: PIC24FJ128GA204 can not wake up from DEEP SLEEP 2020/08/03 17:34:24 (permalink)
    0
    Hello, thank you for the code I am working on it now I'll let you know about the process but I need to ask you about the UART code. Why do we need UART configuration in here? For debugging? Because I am using UART pins for connecting a quectel GSM module on the curiousity board.
    #6
    dan1138
    Super Member
    • Total Posts : 3731
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: PIC24FJ128GA204 can not wake up from DEEP SLEEP 2020/08/03 20:29:05 (permalink)
    0
    mk1907
    Why do we need UART configuration in here?
     
    Because I am using UART pins for connecting a quectel GSM module on the curiousity board.

    It is only for debugging. Without a serial port for debug messages it is impossible to see some of the issues with only the In-Circuit-Debug tool. This is only a demonstration so if you want a comprehensive integration with your current hardware design you need to provide a complete specification, a contract and a non-returnable retainer. :)
    #7
    mk1907
    New Member
    • Total Posts : 3
    • Reward points : 0
    • Joined: 2020/07/29 01:58:44
    • Location: 0
    • Status: offline
    Re: PIC24FJ128GA204 can not wake up from DEEP SLEEP 2020/08/05 00:32:59 (permalink)
    0
    I just want my deep sleep watchdog timer to be clocked but even I define it in the beginning of the programme the deep sleep watchdog timer does not work. So the microcontroller does not wake up from deep sleep in my code. Do we need to make some configurations on the deep sleep watchdog timer before the mcu goes into deep sleep?  I am just thinking is that once in deep sleep, the clock should change from FRC to LPRC and I am suspecting that this is not happening maybe this is why the program gets stuck. Do I need to configure oscilaltor switching just before entering deep sleep. I even tried to configure my main oscillator as LPRC so that I wouldn't have to change it  but still no action.
    post edited by mk1907 - 2020/08/05 00:42:55
    #8
    Jump to:
    © 2020 APG vNext Commercial Version 4.5