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

Wake result from Deep Sleep on PIC24FJ128GA204
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
JamesW



Joined: 23 Apr 2007
Posts: 91
Location: Rochester, England

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

Wake result from Deep Sleep on PIC24FJ128GA204
PostPosted: Mon Sep 17, 2018 5:37 am     Reply with quote

Hi Folks,

I am trying to get a PIC24FJ128GA204 to go into deep sleep, and then wake up and give me an accurate reason as to whether it was a conventional wake up, or whether it has woken from Deep sleep.

I can put it to sleep perfectly well, however determining the reason for wake isn't quite so simple. The restart_cause() routine from CCS doesn't seem to return anything of value/use so I've tried to do it using registers and reading it directly.

I'm putting it to sleep with both INT_EXT enabled and the RTCC alarm clock running on internal crystal, set to wake once a minute.

The code goes to deep sleep (at the moment the processor current is 78uA)

When I press the int_ext button I wake up and it tells me it's woken from deep sleep - but the contents of the DSWAKE register are zero

Any Ideas?
Code:

/* DEEP SLEEP REGISTERS */
#word DSCON_REG = getenv("SFR:DSCON")
#word RCON_REG = getenv("SFR:RCON")
#word DEEP_SLEEP_WAKE_REG = getenv("SFR:DSWAKE")
#bit  DEEP_SLEEP_WAKE_BIT=getenv("BIT:DPSLP")
#bit  DEEP_SLEEP_INT0_BIT=getenv("BIT:DSINT0")
#bit  DEEP_SLEEP_RTCC_BIT=getenv("BIT:DSRTCC")
#bit  DEEP_SLEEP_RELEASE_BIT=getenv("BIT:RELEASE")

/* ------------------------------------------------------------------------- */
/* MAIN CODE */
void main()
{
   /* STAGE 1 - READ THE DEEP SLEEP BIT */
   if (DEEP_SLEEP_WAKE_BIT == TRUE)
   {
      /* CLEAR THIS BIT */
      DEEP_SLEEP_WAKE_BIT = 0;
     
      UI_16 DSWakeReg = DEEP_SLEEP_WAKE_REG;
      UI_16 RConRegister = RCON_REG;

      DEEP_SLEEP_RELEASE_BIT = 0;
     
      delay_ms(100); /* DELAY TO ALLOW THE UART TO WAKE */
      fprintf(DEBUG_PORT,"\r\nDEEP SLEEP DSWAKE:%04X RCON:%04X INT0:%u RTCC:%u",DSWakeReg, RConRegister, DEEP_SLEEP_INT0_BIT, DEEP_SLEEP_RTCC_BIT);
     


My RS232 debug output looks like this

SLEEPING·¿
DEEP SLEEP DSWAKE:0000 RCON:0003 INT0:0 RTCC:0
UNKNOWN WAKE FROM DEEP SLEEP:0000
DSCON:0000 DSWAKE:0000
AWAKE NOW

Thanks in advance

James
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Mon Sep 17, 2018 7:03 am     Reply with quote

How is the interrupt setup before you go to sleep?. Show this.

Check the assembler being generated, and that the compiler is actually selecting the right registers/bits.

Have you got the three NOP's between setting DSEN and the sleep instruction?.

Have you got a handler for INT0?. If not, and you are happy to only poll the detection, disable and clear this interrupt before triggering the sleep.
JamesW



Joined: 23 Apr 2007
Posts: 91
Location: Rochester, England

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

PostPosted: Mon Sep 17, 2018 7:15 am     Reply with quote

My state machine that handles the sleep setup of the system is shown below

There is quite a lot commented out at the moment, as I've been experimenting with what I physically have to disable, and what is turned off automatically when entering sleep.

I'm using the CCS sleep command - which hopefully does the job its supposed to! I stuck a delay_cycles(10) after calling it just to be safe (although never entirely sure that this is in the right place!)


Code:

void Manage_Sleep_System()
{

   switch (System.SleepManagerState)
   {
      /* UNIT IS RUNNING NORMALLY - SLEEP NOT REQUIRED */
      case NORMAL_MODE:
      {
         break;
      }
      /* WE WANT TO START THE SHUTDOWN PROCESS */
      /* TELL ALL OPEN TASKS TO SHUTDOWN       */
      case START_SHUTDOWN:
      {
     
         fprintf(DEBUG_PORT,"\r\n STARTING SLEEP");
         delay_ms(500);
     
         /* IF THE LCD DISPLAY IS RUNNING - INSTRUCT SHUTDOWN */
         if (GraphicsDisplay.CurrentState != LCD_OFF)
         {
            DRV_SSD1327_Power(0);
         }
     
         /* SWITCH AND WAIT FOR SHUTDOWN TO COMPLETE */
         System.SleepManagerState = WAIT_SHUTDOWN_PROCESSES;
         break;
      }
     
      /* WAIT FOR ALL TASKS TO SHUT DOWN */
      case WAIT_SHUTDOWN_PROCESSES:
      {
     
         /* HAS THE LCD SHUTDOWN */
         if (GraphicsDisplay.CurrentState == LCD_OFF)
         {
            System.SleepManagerState = START_SLEEPING;
         }
     
         break;
      }
     
     
      case START_SLEEPING:
      {
         /* TURN OFF THE SERIAL PORTS */
        // Uart_Disable();
         
//!         /* TURN OFF THE ADC */
//!         setup_adc(ADC_OFF);
//!         
//!         /* TURN OFF THE I2C */
//!         i2c_init(I2C_PORT1, FALSE);
//!         
//!         /* MAKE SURE THE PINS ARE LOW */
//!         output_drive(PIN_B2);
//!         output_high(PIN_B2);
//!         output_drive(PIN_B3);
//!         output_high(PIN_B3);   
         
         setup_wdt(WDT_OFF);
         
//!         spi_init(LCD_DISPLAY,FALSE);
//!         
//!         setup_timer2(TMR_DISABLED);
//!         setup_timer4(TMR_DISABLED);
//!         setup_timer5(TMR_DISABLED);
//!
 
//!         SPI1_EN = FALSE;
//!         SPI2_EN = FALSE;
//!         SPI3_EN = FALSE;
//!         UART3_EN = FALSE;
//!         UART4_EN = FALSE;
//!         
//!         PMD1_REG = 0xFFFF;
//!         PMD2_REG = 0xFFFF;
//!         PMD3_REG = 0xFFFF;
//!         PMD4_REG = 0xFFFF;
//!         PMD5_REG = 0xFFFF;
//!         PMD6_REG = 0xFFFF;
//!         PMD7_REG = 0xFFFF;
//!         PMD8_REG = 0xFFFF;       
         
         /* TURN OFF DMA CONTROLLER */
        // DMA_ENABLE_BIT = FALSE;
         
 
         
         Disable_And_Clear_All_Interrupts();
         
         /* TURN OFF LED'S */
         output_low(PANEL_LED);
         output_low(BOARD_LED);
         
         System.SleepManagerState = SLEEPING;
         
          break;
      }
     
      case SLEEPING:
      {
     
         fprintf(DEBUG_PORT,"\r\nSLEEPING");
         delay_ms(100);
         
         /* ALLOW US TO WAKE UP ON A PUSHBUTTON */
         ext_int_edge(0, H_TO_L); 
         clear_interrupt(INT_EXT0);
         enable_interrupts(INT_EXT0);
         
         /* TURN ON THE MINUTE ALARM */
         RTC_Enable_Minute_Alarm();
         clear_interrupt(INT_RTC);
         enable_interrupts(INT_RTC);
       
     
         /* SWITCH STATE TO THE STATE WE WILL BE IN ON WAKE UP */
         System.SleepManagerState = WAKING;
         
         sleep(DEEP_SLEEP);
         delay_cycles(10);
         
         
         break;
      }
     
     
      case WAKING:
      {

         fprintf(DEBUG_PORT,"\r\n AWAKE NOW");
     
         System.SleepManagerState = NORMAL_MODE;
     
         break;
      }

      default:
      {
         break;
      }
   
   }
}



Just to be sure - I am disabling/clearing every Interrupt individually

Code:

void Disable_And_Clear_All_Interrupts()
{
   disable_interrupts(INTR_GLOBAL);

   disable_interrupts(INT_ADC1);
   clear_interrupt(INT_ADC1);
   //disable_interrupts(INT_ADDRERR);
   clear_interrupt(INT_ADDRERR);
   disable_interrupts(INT_BUSCOL);
   clear_interrupt(INT_BUSCOL);
   disable_interrupts(INT_CNI);
   clear_interrupt(INT_CNI);
   disable_interrupts(INT_COMP);
   clear_interrupt(INT_COMP);
   disable_interrupts(INT_CRC);
   clear_interrupt(INT_CRC);
   disable_interrupts(INT_CTMU);
   clear_interrupt(INT_CTMU);
   disable_interrupts(INT_DMA0);
   clear_interrupt(INT_DMA0);
   disable_interrupts(INT_DMA1);
   clear_interrupt(INT_DMA1);
   disable_interrupts(INT_DMA2);
   clear_interrupt(INT_DMA2);
   disable_interrupts(INT_DMA3);
   clear_interrupt(INT_DMA3);
   disable_interrupts(INT_DMA4);
   clear_interrupt(INT_DMA4);
   disable_interrupts(INT_DMA5);
   clear_interrupt(INT_DMA5);
   disable_interrupts(INT_EXT0);
   clear_interrupt(INT_EXT0);
   disable_interrupts(INT_EXT1);
   clear_interrupt(INT_EXT1);
   disable_interrupts(INT_EXT2);
   clear_interrupt(INT_EXT2);
   disable_interrupts(INT_EXT3);
   clear_interrupt(INT_EXT3);
   disable_interrupts(INT_EXT4);
   clear_interrupt(INT_EXT4);
   disable_interrupts(INT_FRC);
   clear_interrupt(INT_FRC);
   disable_interrupts(INT_IC1);
   clear_interrupt(INT_IC1);
   disable_interrupts(INT_IC2);
   clear_interrupt(INT_IC2);
   disable_interrupts(INT_IC3);
   clear_interrupt(INT_IC3);
   disable_interrupts(INT_IC4);
   clear_interrupt(INT_IC4);
   disable_interrupts(INT_IC5);
   clear_interrupt(INT_IC5);
   disable_interrupts(INT_IC6);
   clear_interrupt(INT_IC6);
   disable_interrupts(INT_LVD);
   clear_interrupt(INT_LVD);
   //disable_interrupts(INT_MATHERR);
   clear_interrupt(INT_MATHERR);
   disable_interrupts(INT_MI2C);
   clear_interrupt(INT_MI2C);
   disable_interrupts(INT_MI2C2);
   clear_interrupt(INT_MI2C2);
   disable_interrupts(INT_OC1);
   clear_interrupt(INT_OC1);
   disable_interrupts(INT_OC2);
   clear_interrupt(INT_OC2);
   disable_interrupts(INT_OC3);
   clear_interrupt(INT_OC3);
   disable_interrupts(INT_OC4);
   clear_interrupt(INT_OC4);
   disable_interrupts(INT_OC5);
   clear_interrupt(INT_OC5);
   disable_interrupts(INT_OC6);
   clear_interrupt(INT_OC6);
   //disable_interrupts(INT_OSCFAIL);
   clear_interrupt(INT_OSCFAIL);
   disable_interrupts(INT_PMP);
   clear_interrupt(INT_PMP);
   disable_interrupts(INT_RDA);
   clear_interrupt(INT_RDA);
   disable_interrupts(INT_RDA2);
   clear_interrupt(INT_RDA2);
   disable_interrupts(INT_RDA3);
   clear_interrupt(INT_RDA3);
   disable_interrupts(INT_RDA4);
   clear_interrupt(INT_RDA4);
   disable_interrupts(INT_RTC);
   clear_interrupt(INT_RTC);
   disable_interrupts(INT_SI2C);
   clear_interrupt(INT_SI2C);
   disable_interrupts(INT_SI2C2);
   clear_interrupt(INT_SI2C2);
   disable_interrupts(INT_SPI1E);
   clear_interrupt(INT_SPI1E);
   disable_interrupts(INT_SPI1RX);
   clear_interrupt(INT_SPI1RX);
   disable_interrupts(INT_SPI1TX);
   clear_interrupt(INT_SPI1TX);
   disable_interrupts(INT_SPI2E);
   clear_interrupt(INT_SPI2E);
   disable_interrupts(INT_SPI2RX);
   clear_interrupt(INT_SPI2RX);
   disable_interrupts(INT_SPI2TX);
   clear_interrupt(INT_SPI2TX);
   disable_interrupts(INT_SPI3E);
   clear_interrupt(INT_SPI3E);
   disable_interrupts(INT_SPI3RX);
   clear_interrupt(INT_SPI3RX);
   disable_interrupts(INT_SPI3TX);
   clear_interrupt(INT_SPI3TX);
   //disable_interrupts(INT_STACKERR);
   clear_interrupt(INT_STACKERR);
   disable_interrupts(INT_TBE);
   clear_interrupt(INT_TBE);
   disable_interrupts(INT_TBE2);
   clear_interrupt(INT_TBE2);
   disable_interrupts(INT_TBE3);
   clear_interrupt(INT_TBE3);
   disable_interrupts(INT_TBE4);
   clear_interrupt(INT_TBE4);
   disable_interrupts(INT_TIMER1);
   clear_interrupt(INT_TIMER1);
   disable_interrupts(INT_TIMER2);
   clear_interrupt(INT_TIMER2);
   disable_interrupts(INT_TIMER3);
   clear_interrupt(INT_TIMER3);
   disable_interrupts(INT_TIMER4);
   clear_interrupt(INT_TIMER4);
   disable_interrupts(INT_TIMER5);
   clear_interrupt(INT_TIMER5);
   disable_interrupts(INT_UART1E);
   clear_interrupt(INT_UART1E);
   disable_interrupts(INT_UART2E);
   clear_interrupt(INT_UART2E);
   disable_interrupts(INT_UART3E);
   clear_interrupt(INT_UART3E);
   disable_interrupts(INT_UART4E);
   clear_interrupt(INT_UART4E);


}


I've got handlers for the two Interrupts as well

Code:

#INT_EXT0
void HandlePushbutton()
{

}

#INT_RTC
void HandleRTCIRQ()
{


}




As to what the compiler has done with the sleep I am not sure

Code:

010A8:  MOV.B   #5,W0L
010AA:  MOV.B   W0L,826
....................           
....................          sleep(DEEP_SLEEP);
010AC:  DISI    #3
010AE:  BSET.B  10F.7
010B0:  BSET.B  10F.7
010B2:  PWRSAV  #0
....................          delay_cycles(10);
010B4:  REPEAT  #8
010B6:  NOP     
....................           
....................           
....................          break;
010B8:  GOTO    10DE
....................       }


JamesW



Joined: 23 Apr 2007
Posts: 91
Location: Rochester, England

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

PostPosted: Mon Sep 17, 2018 7:23 am     Reply with quote

Looking at the assembler - it doesn't look too far off the example in the datasheet, albeit the datasheet doesnt mention the PWRSAV #0 line

Quote:



EXAMPLE 10-2: THE REPEAT SEQUENCE

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.
Note: A repeat sequence is required to set the
DSEN bit. The repeat sequence (repeating
the instruction twice) is required to write
into any of the Deep Sleep registers
(DSCON, DSWAKE, DSGPR0, DSGPR1).
This is required to prevent the user from
entering Deep Sleep by mistake. Any
write to these registers has to be done
twice to actually complete the write (see
Example 10-2).

Example 1:
mov #8000, w2 ; enable DS
mov w2, DSCON
mov w2, DSCON ; second write required to
actually write to DSCON

Example 2:
bset DSCON, #15
nop
nop
nop
bset DSCON, #15 ; enable DS (two writes required)


Last edited by JamesW on Mon Sep 17, 2018 7:37 am; edited 1 time in total
JamesW



Joined: 23 Apr 2007
Posts: 91
Location: Rochester, England

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

PostPosted: Mon Sep 17, 2018 7:37 am     Reply with quote

Out of curiosity I've had a go at doing it in assembler as well - but it doesn't seem to make any difference - in fact on about half the wakes the deep sleep flag itself isn't set, so it boots thinking it's a normal boot

Code:

      case SLEEPING:
      {
     
         fprintf(DEBUG_PORT,"\r\nSLEEPING");
         delay_ms(100);
         
         /* ALLOW US TO WAKE UP ON A PUSHBUTTON */
         ext_int_edge(0, H_TO_L); 
         clear_interrupt(INT_EXT0);
         enable_interrupts(INT_EXT0);
         
         /* TURN ON THE MINUTE ALARM */
         RTC_Enable_Minute_Alarm();
         clear_interrupt(INT_RTC);
         enable_interrupts(INT_RTC);
       
     
         /* SWITCH STATE TO THE STATE WE WILL BE IN ON WAKE UP */
         System.SleepManagerState = WAKING;
         
         /* TRY USING HARD REGISTER ACCESS */
         DEEP_SLEEP_ENABLE_BIT = 1;
         DEEP_SLEEP_ENABLE_BIT = 1;

         #asm
         NOP
         NOP
         NOP
         PWRSAV #0
         #endasm
//!         sleep(DEEP_SLEEP);
//!         delay_cycles(3);
//!         
         
         break;
      }

JamesW



Joined: 23 Apr 2007
Posts: 91
Location: Rochester, England

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

PostPosted: Mon Sep 17, 2018 7:52 am     Reply with quote

Also - to add further to the confusion - the unit looks like it's attempting to boot up after the minute expires on the RTCC. The power increases, I get a little garbage out of the RS232 port - and then the power decreases to 42uA but it doesn't wake.

When I then press the ext int button, it tells me it's not woken from deep sleep.
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Mon Sep 17, 2018 8:29 am     Reply with quote

OK. Good start. Smile

The instruction after the sleep shouldn't matter here (since deep_sleep resets). However if it did, you need delay_cycles(1), not 15. It has to be a NOP, which the longer delay does not guarantee to give...

The data sheet differs slightly from 39727b. Probably worth having a look at this!...

In the data sheet it says you have to set the enable bit twice (as the CCS driver is doing), but in the more detailed power saving note, it says that you have to enter sleep within one to three cycles of setting the DSEN bit, and that in the specific case of wanting to use the external interrupt, this must be three cycles. It also warns that if using a bit set to access the DSEN bit there must be a delay between the bit set operations.
The delay after setting the bit allows the interrupt hardware to get into the state required. So I'd use assembler:
Code:

    DEEP_SLEEP_ENABLE_BIT = 1;
    delay_cycles(1);
    delay_cycles(1);
    delay_cycles(1);
    DEEP_SLEEP_ENABLE_BIT = 1;
#asm
    nop  //This is meant to be needed to let the hardware get ready
    nop
    nop
    pwrsav #0
#endasm


This gives the delays specified in the more detailed section. Will be interesting to see if it has any effect!...
The stupid thing is that the data sheet gives the first half of this, while the power save note gives the second. Stupidity!...
JamesW



Joined: 23 Apr 2007
Posts: 91
Location: Rochester, England

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

PostPosted: Mon Sep 17, 2018 8:47 am     Reply with quote

OK - I've now coded this in . . .

Code:

      case SLEEPING:
      {
     
         fprintf(DEBUG_PORT,"\r\nSLEEPING");
         delay_ms(100);
         
         /* ALLOW US TO WAKE UP ON A PUSHBUTTON */
         ext_int_edge(0, H_TO_L); 
         clear_interrupt(INT_EXT0);
         enable_interrupts(INT_EXT0);
         
         /* TURN ON THE MINUTE ALARM */
         RTC_Enable_Minute_Alarm();
         clear_interrupt(INT_RTC);
         enable_interrupts(INT_RTC);
         
         delay_cycles(4);
       
     
         /* SWITCH STATE TO THE STATE WE WILL BE IN ON WAKE UP */
         System.SleepManagerState = WAKING;
         
//!         /* TRY USING HARD REGISTER ACCESS */
//!         DEEP_SLEEP_ENABLE_BIT = 1;
//!         DEEP_SLEEP_ENABLE_BIT = 1;
//!
//!         #asm
//!         NOP
//!         NOP
//!         NOP
//!         PWRSAV #0
//!         #endasm
//!         sleep(DEEP_SLEEP);
//!         delay_cycles(10);
         
    DEEP_SLEEP_ENABLE_BIT = 1;
    delay_cycles(1);
    delay_cycles(1);
    delay_cycles(1);
    DEEP_SLEEP_ENABLE_BIT = 1;
   
   #asm
       nop  //This is meant to be needed to let the hardware get ready
       nop
       nop
       pwrsav #0
   #endasm       


         break;
      }


Which has given me this output

Code:

.................... //!         /* TRY USING HARD REGISTER ACCESS */
.................... //!         DEEP_SLEEP_ENABLE_BIT = 1;
.................... //!         DEEP_SLEEP_ENABLE_BIT = 1;
.................... //!
.................... //!         #asm
.................... //!         NOP
.................... //!         NOP
.................... //!         NOP
.................... //!         PWRSAV #0
.................... //!         #endasm
.................... //!         sleep(DEEP_SLEEP);
.................... //!         delay_cycles(10);
....................           
....................     DEEP_SLEEP_ENABLE_BIT = 1; 
010B0:  BSET.B  10F.7
....................     delay_cycles(1); 
010B2:  NOP     
....................     delay_cycles(1); 
010B4:  NOP     
....................     delay_cycles(1); 
010B6:  NOP     
....................     DEEP_SLEEP_ENABLE_BIT = 1; 
010B8:  BSET.B  10F.7
....................     
....................    #asm
....................        nop  //This is meant to be needed to let the hardware get ready 
010BA:  NOP     
....................        nop 
010BC:  NOP     
....................        nop 
010BE:  NOP     
....................        pwrsav #0 
010C0:  PWRSAV  #0
....................    #endasm         



I have also altered the start of main - as the act of reading the RCON register seems to clear it, so for clarity I read the register and bit test it.

Code:

/* ------------------------------------------------------------------------- */
/* MAIN CODE */
void main()
{
   UI_16 RConRegister = RCON_REG;

   /* STAGE 1 - READ THE DEEP SLEEP BIT */
   //if (DEEP_SLEEP_WAKE_BIT == TRUE)
   if (bit_test( RConRegister,10) == TRUE)
   {
      /* CLEAR THIS BIT */
      DEEP_SLEEP_WAKE_BIT = 0;
     
      UI_16 DSWakeReg = DEEP_SLEEP_WAKE_REG;
      //UI_16 RConRegister = RCON_REG;

      DEEP_SLEEP_RELEASE_BIT = 0;
     
      delay_ms(100); /* DELAY TO ALLOW THE UART TO WAKE */
      fprintf(DEBUG_PORT,"\r\nDEEP SLEEP DSWAKE:%04X RCON:%04X INT0:%u RTCC:%u",DSWakeReg, RConRegister, DEEP_SLEEP_INT0_BIT, DEEP_SLEEP_RTCC_BIT);


When I wake on pushing the button I get this over RS232

Quote:

STARTING SLEEP
SLEEPING
DEEP SLEEP DSWAKE:0000 RCON:0403 INT0:0 RTCC:0
UNKNOWN WAKE FROM DEEP SLEEP:0000


If I stay asleep for over a minute, the current starts off at 78uA, after a minute drops to 43uA (after rising for a second or so and outputting a couple of garbage characters to the screen - turned to red below)

Quote:


SLEEPING÷·¿¿


If I then press the wake button - I get the message informing me that it hasn't woken from sleep as below

Quote:

SLEEPING÷·¿¿ 766 NOT WOKEN FROM DEEP SLEEP:0000
DSCON:0000 DSWAKE:0000
JamesW



Joined: 23 Apr 2007
Posts: 91
Location: Rochester, England

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

PostPosted: Mon Sep 17, 2018 8:52 am     Reply with quote

OK - for completeness I've looked at the start of the code.

Where I declare the variable for the RCON register, it doesn't appear to be reading the register contents into the variable - am I reading this right?

Code:

.................... {
.................... 
.................... 
....................     
....................    UI_16 RConRegister = RCON_REG;
.................... 
....................    /* STAGE 1 - READ THE DEEP SLEEP BIT */
....................    //if (DEEP_SLEEP_WAKE_BIT == TRUE)
....................    if (bit_test( RConRegister,10) == TRUE)
011A6:  BTSS.B  1181.2
011A8:  BRA     1340
....................    {
....................       /* CLEAR THIS BIT */
....................       DEEP_SLEEP_WAKE_BIT = 0;
011AA:  BCLR.B  109.2
....................       
....................       UI_16 DSWakeReg = DEEP_SLEEP_WAKE_REG;
011AC:  PUSH    110
011AE:  POP     1182
....................       //UI_16 RConRegister = RCON_REG;
.................... 
....................       DEEP_SLEEP_RELEASE_BIT = 0;
011B0:  BCLR.B  10E.0
....................       
....................       delay_ms(100); /* DELAY TO ALLOW THE UART TO WAKE */
011B2:  MOV     #64,W0
011B4:  CALL    59C
....................       fprintf(DEBUG_PORT,"\r\nDEEP SLEEP DSWAKE:%04X RCON:%04X INT0:%u RTCC:%u",DSWakeReg, RConRegister, DEEP_SLEEP_INT0_BIT, DEEP_SLEEP_RTCC_BIT);

JamesW



Joined: 23 Apr 2007
Posts: 91
Location: Rochester, England

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

PostPosted: Mon Sep 17, 2018 8:55 am     Reply with quote

However if I declare the start of main like this instead. . . .

Code:

/* MAIN CODE */
void main()
{
   UI_16 RConRegister;
   
   RConRegister = RCON_REG;

   /* STAGE 1 - READ THE DEEP SLEEP BIT */
   //if (DEEP_SLEEP_WAKE_BIT == TRUE)
   if (bit_test( RConRegister,10) == TRUE)
   {



I get this
Code:


.................... {
....................    UI_16 RConRegister;
....................     
....................    RConRegister = RCON_REG;
0116E:  PUSH    108
01170:  POP     1180
.................... 
....................    /* STAGE 1 - READ THE DEEP SLEEP BIT */
....................    //if (DEEP_SLEEP_WAKE_BIT == TRUE)
....................    if (bit_test( RConRegister,10) == TRUE)
01172:  BTSS.B  1181.2
01174:  BRA     130C
....................    {
....................       /* CLEAR THIS BIT */
....................       DEEP_SLEEP_WAKE_BIT = 0;
01176:  BCLR.B  109.2



I am assuming that there is some weird byte addressing thing going on here and bit 10 of 1180 is the same as 1181.2????
JamesW



Joined: 23 Apr 2007
Posts: 91
Location: Rochester, England

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

PostPosted: Mon Sep 17, 2018 8:57 am     Reply with quote

However I can report that neither of those has made any difference to how it works - and it still half wakes up when the RTC interrupts the system and then the power drops - and then says it wasn't woken from deep sleep.
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Mon Sep 17, 2018 8:59 am     Reply with quote

It should be in the initialisation code for the block.

This is one reason why I hate declaring registers and initialising them in one line (except to fixed values). The actual initialisation does not occur where the code line appears.
Declare the variable and initialise it separately. You should then see the value being loaded.
JamesW



Joined: 23 Apr 2007
Posts: 91
Location: Rochester, England

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

PostPosted: Mon Sep 17, 2018 9:31 am     Reply with quote

This gets even stranger, I have now amended my main code to look like this (declaring both registers and then reading them, then forcing a clear of the release bit.

Code:


/* MAIN CODE */
void main()
{
   UI_16 RConRegister = 0, DSWakeReg = 0;
   
   RConRegister = RCON_REG;
   DSWakeReg = DEEP_SLEEP_WAKE_REG;

   DEEP_SLEEP_RELEASE_BIT = 0;

   /* STAGE 1 - READ THE DEEP SLEEP BIT */
   //if (DEEP_SLEEP_WAKE_BIT == TRUE)
   if (bit_test( RConRegister,10) == TRUE)
   {
      /* CLEAR THIS BIT */
      DEEP_SLEEP_WAKE_BIT = 0;


My output of the code FROM A POWER UP looks like this.

In each case I am waiting approximately 2 seconds after the processor goes to sleep before triggering the INT0 pushbutton.

Quote:

NOT WOKEN FROM DEEP SLEEP:0000
DSCON:0000 DSWAKE:0000
TICK:1 POWER BUT:1
TICK:2 POWER BUT:1
TICK:3 POWER BUT:1
TICK:4 POWER BUT:1
TICK:5 POWER BUT:1
TICK:6 POWER BUT:1
TICK:7 POWER BUT:1
TICK:8 POWER BUT:1
TICK:9 POWER BUT:1
TICK:10 POWER BUT:1
STARTING SLEEP
SLEEPING
DEEP SLEEP DSWAKE:0100 RCON:0403 INT0:1 RTCC:0
WAKE BUTTON FROM DEEP SLEEP:0100
DSCON:0000 DSWAKE:0100
AWAKE NOW
TICK:1 POWER BUT:1
TICK:2 POWER BUT:1
TICK:3 POWER BUT:1
TICK:4 POWER BUT:1
TICK:5 POWER BUT:1
TICK:6 POWER BUT:1
TICK:7 POWER BUT:1
TICK:8 POWER BUT:1
TICK:9 POWER BUT:1
TICK:10 POWER BUT:1
STARTING SLEEP
SLEEPING
DEEP SLEEP DSWAKE:0100 RCON:0403 INT0:1 RTCC:0
WAKE BUTTON FROM DEEP SLEEP:0100
DSCON:0000 DSWAKE:0100
AWAKE NOW
TICK:1 POWER BUT:1
TICK:2 POWER BUT:1
TICK:3 POWER BUT:1
TICK:4 POWER BUT:1
TICK:5 POWER BUT:1
TICK:6 POWER BUT:1
TICK:7 POWER BUT:1
TICK:8 POWER BUT:1
TICK:9 POWER BUT:1
TICK:10 POWER BUT:1
STARTING SLEEP
SLEEPING
DEEP SLEEP DSWAKE:0000 RCON:0403 INT0:0 RTCC:0
UNKNOWN WAKE FROM DEEP SLEEP:0000
DSCON:0000 DSWAKE:0000
AWAKE NOW
TICK:1 POWER BUT:1
TICK:2 POWER BUT:1
TICK:3 POWER BUT:1
TICK:4 POWER BUT:1


The first couple of times it woke - it tells me that the INT0 has triggered the wake, however then it reverts to telling me it has no idea what woke it
JamesW



Joined: 23 Apr 2007
Posts: 91
Location: Rochester, England

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

PostPosted: Mon Sep 17, 2018 9:32 am     Reply with quote

RTCC still has no real effect
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Mon Sep 17, 2018 11:23 am     Reply with quote

OK. You've moved forwards. Doesn't look like something odd like a watchdog triggering.
The one thing that will wake from deep sleep without setting a bit in the DSWAKE register, is DSBOR. Worth checking this.
As a comment, the deep sleep enable bit is cleared by the hardware on wake. You don't have to clear this.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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