This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2430DB Entering DEEP sleep

Other Parts Discussed in Thread: Z-STACK, TIMAC, CC2430, MANDO, CC2530

Hi Everyone,

I'm using Z-stack 1.4.2 1.1.0 with the evaluation kit. I'm just trying to program my end device to enter in DEEP sleep mode. I've already followed the instruccions in Power Management documentation but I can only get what it feels like LITE sleep.

The thing is although I'm setting poll rate to 0, it still recieves every message that I send to it, and in DEEP sleep mode it should'n happen.

Any clue?

 

  • I also am trying to get deep sleep working.  In my case I am not using Z-Stack, but only TIMAC + HAL + OSAL.  I am using the osal_pwrmgr_device(PWRMGR_BATTERY) call, and I'm not doing any transmitting or receiving at all (nor do I have any timers of my own running), but when I measure the current draw, it is about 380-400 uA.  It should be entering PM2, right?

    I hacked a counter into hal_sleep.c and my code displays the number of times CPU sleep mode is entered, and it is waking up about 10 times per second even though I have no timers running.  Do I need to tell the MAC layer not to poll the receiver?  This is a "transmit-only" node that needs to have very low average power usage -- it only wakes up to transmit a tiny MAC packet every few seconds, and it is of the utmost importance that the sleep mode be very low power.

    Thanks for any help -- it is really hard to find good documentation on the TIMAC and the details of how it should be used.

    Regards,
    Colin

  • I'm also ZStack 1.4.2-1.1.0 with CC2430 and need to go into deep sleep. Documentation about the ZStack and how to enter the different sleep modes is equals ZERO. I just can't find documentation about the Sleep Modes exept the CC2430 datasheet itself, which is not very useful when using the ZStack.

    Does anybody use the Sleep Modes already or has any even small experience with it?

    Any help even tiny hints are highly appreciated!!

    Thanks,

    Flo

  • Hi,

    In order to support deep sleep mode, you should also set the following in onboard.c:

     /* Initialize Key stuff */
        OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;   //HAL_KEY_INTERRUPT_DISABLE;
        HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);

    If you don't set OnboardKeyIntEnable to HAL_KEY_INTERRUPT_ENABLE, then a key polling event triggers for every 200ms (I think that's what it is offhand),
    and so the chip would never get into a deep sleep mode because there is always a timer event scheduled.

    Please try this and let me know the result.

    From HalKeyConfig:

     osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_POLLING_VALUE);    /* Kick off polling */

  • Hi,

    In order to support deep sleep mode, you should also set the following in onboard.c:

     /* Initialize Key stuff */
        OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;   //HAL_KEY_INTERRUPT_DISABLE;
        HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);

    If you don't set OnboardKeyIntEnable to HAL_KEY_INTERRUPT_ENABLE, then a key polling event triggers for every 200ms (I think that's what it is offhand),
    and so the chip would never get into a deep sleep mode because there is always a timer event scheduled.

    Please try this and let me know the result.

    From HalKeyConfig:

     osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_POLLING_VALUE);    /* Kick off polling */

    Thanks, Z!  I will try this ASAP.

    After watching the current draw vs time on a digital oscilliscope, I observe pulses of current every 100 ms.  This must be what is causing it.  I am glad to have this forum; it's a lifesaver.

    Regards,
    Colin

  • I'm already away from polling and using real interrupts.

     

    So I just call HalKeyEnterSleep() and my device goes to sleep?

  • Hi FGreber,

    #define OSAL_SET_CPU_INTO_SLEEP(timeout) halSleep(timeout); /* Called from OSAL_PwrMgr */

    is defined in Onboard.h

    This gets called by the OSAL_PwrMgr if there are no scheduled timers, so you don't have to call halSleep specifically from the application.
    halSleep is the function in hal_sleep.c.

    HalKeyEnterSleep() is a house-keeping function, and it is by default blank, so the user can add any housekeeping function they like
    that has to do with keys.

    -Z

  • Hello Z,

    firstly thanks for your info.

    I just have a problem in my application using a timeout for teh power management, so I guess, that when I would like to enter sleep, I call halSleep and my device will enter a different power mode when power saving is defined.

    I'll try it out. Thanks for your info. It was very helpful!

  • Z,

    I changed the line

      HalKeyConfig(FALSE, Mobile_HandleKeys);

    to

      HalKeyConfig(TRUE, Mobile_HandleKeys);

    and noticed that the HandleKeys function is not getting reliably called when a key is pressed.  I have to click the button about 30 times sometimes before the key handler function is called (I turn on an LED when the function is called).  It doesn't matter if I hold it down for a while or click it as quickly as possible; it just doesn't work except intermittently.

    So, for now to test things, I have commented out the HalKeyConfig() call and I am not configuring keys.

    I am now getting lower current draw, about 110 to 120 uA at 3.0 V in sleep mode.  However, shouldn't this be significantly lower still?  We should be in PM2, which should draw only 0.5 uA.  What could be causing it to draw so much more power?  Is there anything I can do to diagnose what peripherals (timers, etc.?) might be running that should not be?  Only the "sleep timer" should be running in PM2, right?

    I also #defined HAL_ADC, HAL_KEY, HAL_UART, HAL_AES, HAL_DMA, and HAL_LCD all to false to see if it helps; it did not make a difference.

    Thanks for any help!
    Regards, Colin

  • colinb said:
    ...
    I am now getting lower current draw, about 110 to 120 uA at 3.0 V in sleep mode.  However, shouldn't this be significantly lower still?  We should be in PM2, which should draw only 0.5 uA.  What could be causing it to draw so much more power?  Is there anything I can do to diagnose what peripherals (timers, etc.?) might be running that should not be?  Only the "sleep timer" should be running in PM2, right?

    I also #defined HAL_ADC, HAL_KEY, HAL_UART, HAL_AES, HAL_DMA, and HAL_LCD all to false to see if it helps; it did not make a difference.
    ...

    Update!  It turns out it was the CC2430BB board drawing the 100+ uA... when I supplied power directly to the CC2430EM through probes, I get 0.6 uA of sleep current!  We are very excited to see this!

    Thanks for the help,
    Colin

     

  • Thanks for the update Colin! I think the something on the BB board is left floating or is still driving the LED on that board. Yes, the best way to measure current consumption is at the EM directly.
    Cheers,

    -Z

  • As far as the key interrupt, you should be able to see that the P0 ISR is entered everytime you press the 'S1' pushbutton.
    The handle keys function is used to poll for the joystick press on the EB and DB boards.

    HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
    {
      /* P0IF is cleared by HW for CHVER < REV_E */

      halProcessKeyInterrupt();

      if( CHVER >= REV_E )
      {
        /* Make sure that we clear all enabled, but unused P0IFG bits.
         * For P0 we can only enable or disable high or low nibble, not bit by
         * bit. For P1 and P2 enabling of single bits are possible, therefore
         * will not any unused pins generate interrupts on P1 or P2.
         * We could have checked for low and high nibble in P0, but this
         * isn't necessary as long as we only clear unused pin interrupts.
         */
        P0IFG = (HAL_KEY_P0INT_LOW_USED | HAL_KEY_POINT_HIGH_USED);
        P0IF = 0;
        CLEAR_SLEEP_MODE();
      }
    }

    I usually just set an osal event in the ISR and send it to my app task id:

    osal_set_event (MyAppTaskID, KEY_INTERRUPT_EVENT); //example

  • As far as the key interrupt, you should be able to see that the P0 ISR is entered everytime you press the 'S1' pushbutton.
    The handle keys function is used to poll for the joystick press on the EB and DB boards.

    After hours of tracking down what was wrong, I realized the following:

    1. Pressing S1 (SW6) *should* cause the HandleKeys callback to get called, based on my reading of the code.
    2. The ISR is *never* invoked.
    3. The reason is that hal_key.c has the wrong interrupt trigger edge for the CC2430EB SW6.
    4. After fixing 3., the HandleKeys callback (see 1.) is getting called as I expect.

    Here is my patch to fix hal_key.c:

     

    --- hal_key.c	2008-09-27 00:22:56 +0000
    +++ hal_key.c	2008-10-10 23:26:21 +0000
    @@ -158,7 +158,7 @@
       #define HAL_KEY_SW_6_DIR      P0DIR                   /* Port Direction Register for SW1 */
       #define HAL_KEY_SW_6_IEN      IEN1                    /* Interrupt Enable Register for SW1 */
       #define HAL_KEY_SW_6_IENBIT   HAL_KEY_BIT5            /* Interrupt Enable bit for SW1 */
    -  #define HAL_KEY_SW_6_EDGE     HAL_KEY_RISING_EDGE     /* Type of interrupt for SW1 */
    +  #define HAL_KEY_SW_6_EDGE     HAL_KEY_FALLING_EDGE    /* Type of interrupt for SW1 */
       #define HAL_KEY_SW_6_EDGEBIT  HAL_KEY_BIT0            /* EdgeType enable bit SW1 */
       #define HAL_KEY_SW_6_ICTL     PICTL                   /* Port Interrupt Control for SW1 */
       #define HAL_KEY_SW_6_ICTLBIT  HAL_KEY_BIT3            /* Interrupt enable bit for SW1 */
    


    Regards,
    Colin

     

  • Hi everybody,

    WorkingAgain? said:
    I just have a problem in my application using a timeout for teh power management, so I guess, that when I would like to enter sleep, I call halSleep and my device will enter a different power mode when power saving is defined.

    After lots of tries, it seems that I also have problems with the timeout to pass from PM2 to PM3. I'm working with key interrupts and I've set de Poll rate to 0, so there shouldn't be any other code to change, but I still can't enter PM3.

    Any idea of how to debug it?

    Sandra

     

  • Colin,

    Thanks for the feedback!

    -Z

  • Sandra,

    Did you try turning on the key interrupt enable as mentioned above?

    Also, you can't use the debugger if you are using PM2 or PM3, so set the flag PM1_ONLY=TRUE if you want to use the IAR debugger.

  • Hi Everyone,

    I'm using TI-MAC-1.2.1 on CC2430 (rev. E) devices (no ZigBee).

    I'm able to enter in PM2 mode but I'm not able to exit from it. I use the internal Sleep Timer.

    From the manual I have understand that the wake up procedure starts when the Sleep Timer expires, is it right?

    Because it seems that some parts of the devices don't wake up.

    Are there documents that describe the procedure to enter or exit by sleep modes?

    If not, is there someone that has solved this problem?

    Thanks
    Bye

  • Hello mat,

    I have uploaded the AN044 to "My Files", which is a draft release for the Rev.D. Some parts may not be accurate, but it gave me some ideas.

    Maybe it helps you too. =)

  • Thank you for the document.

    Before to check the hardware problem I should verify the software.


    From the reading of your document I observe that, in PM1 the consumption should be 190 microA while I have a consumption of 2mA.

    Are there documents related to software implementation related to power modes applications? I work with CC2430EB chip, are there differences from DBCC2430 chip?

    Thanks

    Bye

  • For power consumptions you can also check page 11 of the CC2430 datasheet (Section 7 Electrical Specifications)

  • How are you measuring the current draw?  We determined that at least using the CC2430BB battery board, the board circuitry itself draws 100 mA or so even when the MCU is sleeping (pull-up/pull-down resistors, maybe?).

    Now I use a *bare* CC2430EM module and supply power to it through two wires, through the P2 connector pins 2 (GND) and 9 (Vcc).  We observe <1uA current draw with this setup in PM2.

    Regards,
    Colin

  • Thank you.

    I check with attention the circuitry.

    But I have also a problem in the software, which procedure or commands are you using to start sleep and wake up modality ?

    Are there documents that specify how to do this?

    Regards

     

  • Hi,

    i'm trying to configure power modes for cc2430, and was trying to get some informations about it.

    All of you were speaking about a paper called "Application Note AN044 CC2430 Revision D". I tryed to find it but without sucess.

    Can you help telling me where you found it, and if you allready where an example of how to switch from Power Mode 2 to Power Mode 0 using the Sleep Timer?

     

    Would be very pleased if sombody could help me

    Best regards to all

  • Luis Bras said:

    Hi,

    i'm trying to configure power modes for cc2430, and was trying to get some informations about it.

    All of you were speaking about a paper called "Application Note AN044 CC2430 Revision D". I tryed to find it but without sucess.

    The document mentioned in prior posts is located http://community.ti.com/members/1187708/default.aspx.

     

    Luis Bras said:

    Can you help telling me where you found it, and if you allready where an example of how to switch from Power Mode 2 to Power Mode 0 using the Sleep Timer?

    I would suggest reviewing the CC2430 datasheet and application notes, including DN106 -- Power Modes in CC111xFx, CC243xFx, and CC251xFx (Rev. A) (SWRA162) found on the CC2430 Product Folder as a starting point.

  • Thanks very much Brandon, this will help me a lot.

    Best regards

  • I'm also ZStack 1.4.2-1.1.0 with CC2430 and need to go into deep sleep after the router or enddevice send  date to the coordinator,and then the node will awake and sent data again

    i defined POWER_SAVING and replace the  f8w2430.xcl with f8w2430pm.xcl for DEEP sleep devices as the document said.

    but it never work,the child node keep sending data to the coordinator in periodic ,

    what is wrong?

    waiting for your reply

    thank you

  • In ZStack, DEEP sleep only occurs when there is no scheduled activity for the device to perform. Also, an external interrupt will be required to wake the device from DEEP sleep. You state that "the child node keep sending data..." so that indicates that some process is running on a timer basis (most likely NWK_AUTO_POLL), so DEEP sleep will not happen.

  • first,thank you for your reply:)

    I have some questions:

    1)If I want to make the child node get into sleep,the only work  is that  define POWER_SAVING and replace the  f8w2430.xcl with f8w2430pm.xcl in the project. We don't need to write any code for the deep sleep(PM2),is it right?

    2)When I set the compiler and linker as the document said ,rebild all the project then the error appeared:

     Error[e16]: Segment XDATA_I (size: 0xe9 align: 0) is too long for segment definition. At least 0x7b more bytes needed. The problem occurred while  processing the segment placement command "-Z(XDATA)XDATA_N,XDATA_Z,XDATA_I=_XDATA_START-_XDATA_END", where at the moment of  placement the available memory ranges were "XDATA:fce8-fd55"

    3)Can we implement the deep sleep like this:

    The child node in the sleep state,the sleep time is set by ST register,when the timeout the node will wake up.

  • Hi,

    Tks it's very helpful.

    I have the same problem, I use the cc2430bb soft description target to configure mu costum target..
    I have a key in the p0_7 pin, so I modified the sw6 like that;

    #if defined (HAL_BOARD_CC2430BB)
      #define HAL_KEY_SW_6_ENABLE
      #define HAL_KEY_SW_6_PORT     P0                      /* Port location of SW1 */
      #define HAL_KEY_SW_6_BIT      HAL_KEY_BIT7            /* Bit location of SW1 */
      #define HAL_KEY_SW_6_SEL      P0SEL                   /* Port Select Register for SW1 */
      #define HAL_KEY_SW_6_DIR      P0DIR                   /* Port Direction Register for SW1 */
      #define HAL_KEY_SW_6_IEN      IEN1                    /* Interrupt Enable Register for SW1 */
      #define HAL_KEY_SW_6_IENBIT   HAL_KEY_BIT5            /* Interrupt Enable bit for SW1 */
      #define HAL_KEY_SW_6_EDGE     HAL_KEY_RISING_EDGE     /* Type of interrupt for SW1 */
      #define HAL_KEY_SW_6_EDGEBIT  HAL_KEY_BIT0            /* EdgeType enable bit SW1 */
      #define HAL_KEY_SW_6_ICTL     PICTL                   /* Port Interrupt Control for SW1 */
      #define HAL_KEY_SW_6_ICTLBIT  HAL_KEY_BIT4            /* Interrupt enable bit for SW1 */
      #define HAL_KEY_SW_6_PXIFG         P0IFG                   /* Port Interrupt Flag for SW1 */
      #define HAL_KEY_P0INT_LOW_USED0    HAL_KEY_SW_6_BIT    /* P0 can only be enabled/disabled as group of high or low nibble */
      #define HAL_KEY_POINT_HIGH_USED0   0

    I would to set an interrupt button; so in the Onboard.c "InitBoard()" I modify the function to have an interrupt no a polling


     OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;   
     HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);

    In the ISR function; I sent a event message to the application; but there's a problem,

    HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR ) // port 0 input vector
    {
      /* P0IF is cleared by HW for CHVER < REV_E */
     
      // halProcessKeyInterrupt();   // USED FOR THE JOYSTICK EB AND DB BOARDS
     
      byte Zphone_TaskID;

      if( CHVER >= REV_E )  // CHVER : CHIP VERSION; REV_E: DEFINED AS 0X04
      {
        P0IF = 0; // interrupt not pending
      
        P0IFG = (HAL_KEY_P0INT_LOW_USED0 | HAL_KEY_POINT_HIGH_USED0);
       
        //CLEAR_SLEEP_MODE();
        osal_set_event( app_TaskID, app_KEY_EVENT); // SEND AN EVENT TO THE APP TASK
      }
    }


    in the app.c

      if (events & app_KEY_EVENT)
      {
        HAL_TURN_ON_LED1();
        return (events ^ app_SEND_MSG_EVT);
      }

  • elo

    I work with the CC2430DB and the Z stack 1,4,3 1,2,1.

    I would like to make a timer but i don't know how to make and place the program of time in the stack

    can anyone give me helps

    thanks

    Oussama

  • elo

    I work with the CC2430DB and the Z stack 1,4,3 1,2,1.

    I would like to make a timer but i don't know how to make and place the program of time in the stack

    My idea is:every 10 sec the coordinator send message to all router.

    can anyone give me helps

    thanks

    Oussama

  • Hello BrandonAzbell,

    I work with the cc 2430 db with the Z stack

    My task is to make a timer to count 10 s and then the coordiantor send a message to all router in the network.

    Can you help me how can  i program this timer in cc 2430 db by some documentation or your experience in TI

    Thank you

    Oussama

     

  • See the sampleApp application with Zigbee stack for the same.

  •  

    My name is Luis Bras,

    and i was working with cc2430 modules last year.

    I think you are speaking about Lite Sleep and not Deep Sleep, Deep sleep turn off timers and consume 0,3 micro amperes if i remember well, and only works with interruptions.
    Lite Sleep let you sleep for maximum 510 seconds and consume 0,5 micro amperes.

    For you to use timers with the Z-Stach you can do

      osal_start_timerEx( BlindNode_TaskID, BLINDNODE_START_EVT, SLEEP_TIME );

      SLEEP_TIME - time you want the device to sleep in milisseconds;

      BLINDNODE_START_EVT - event that will run when the device will wake up.

     

    Offcourse for this you need to enter before in Sleep Mode,

    something like

      SampleApp_Sleep( TRUE );

     

    and you could also turn of the receiver.

     

    I was doing this with end devices RFD, not sure if with coordinator and routers you can do it, cause before enter in sleep mode you all tasks need to finish in Power Saving, and tasks of routers and coordinators are diferent.

     

    Hope i had help you somehow,

    Good luck

     

  • Hello everybody,

    I have been for three months trying to achieve the PM2 working with Sleep Timer to get a 1 second polling and I do not get good results. I just get one cycle but no more. I am using TIMAC and I have followed the Power Modes Application Notes to blink a led every 1 second using Sleep Timer. I enter into PM2 without problem and the micro wakes up after 1 second, the led blinks and it enter into PM2 again but never wake up once again. The sleep timer after the first loop rests to FFFFFF and so it wake up after one minute more or less.

     

    I am using chips rev E and IAR compiler. I have also try to use the hal_sleep.c code to solve it but it does not work. It works alike my code.

    Has anybody experience to solve the problem?

     

    Can anybody help me?

    Thanks

  • Which version of TIMAC are you using?

  • Hello. I am using rev E software examples from 23 Jan 2008 to implement the software.

    Here you have the code I am using to achive the led blinking. As I told, it just work once in the Sleep Timer Time set, and the next times blinks after some minutes (ST=0xFFFFFF).

    I am quite desperated because it is very important for me and I do not achieve a good result.

     

    Thanks for your help.

     

    /***********************************************************************************
    * LOCAL VARIABLES
    */
    static uint8 pTxData[APP_PAYLOAD_LENGTH];
    static uint8 pRxData[APP_PAYLOAD_LENGTH];
    static basicRfCfg_t basicRfConfig;
    int SleepTimerInterrupt;

    //Rutina de Interrupcion

    _Pragma("vector=0x2B") __near_func __interrupt void ST_ISR(void);
    _Pragma("vector=0x2B") __near_func __interrupt void ST_ISR(void)
    {

      SLEEP &= 0xFC;
     
      IRCON = 0x00; //PRUEBA
       
      SleepTimerInterrupt = 1;
     
     
    }

     

    #ifdef SECURITY_CCM
    // Security key
    static uint8 key[]= {
        0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
        0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
    };
    #endif

     


    /***********************************************************************************
    * @fn          main
    *
    * @brief       This is the main entry of the "Light Switch" application.
    *              After the application modes are chosen the switch can
    *              send toggle commands to a light device.
    *
    * @param       basicRfConfig - file scope variable. Basic RF configuration
    *              data
    *              appState - file scope variable. Holds application state
    *
    * @return      none
    */
    void main(void)
    {

        // Config basicRF
        basicRfConfig.panId = PAN_ID;
        basicRfConfig.channel = RF_CHANNEL;
        basicRfConfig.ackRequest = TRUE;
    #ifdef SECURITY_CCM
        basicRfConfig.securityKey = key;
    #endif

        // Initalise board peripherals
        halBoardInit();

        // Initalise hal_rf
        if(halRfInit()==FAILED) {
          HAL_ASSERT(FALSE);
        }
      // Initialize BasicRF
        basicRfConfig.myAddr = MANDO_ADDR;
        if(basicRfInit(&basicRfConfig)==FAILED) {
          HAL_ASSERT(FALSE);
         
        }
       

     //   basicRfReceiveOn();
       
            // Main loop
          while (1) {
           
            // Sleep Timer Enable
           ST2 = 0x02;
           ST1 = 0x80;
           ST0 = 0x40;         

           STIF = 0;
           STIE = 1;
           EA = 1;

         
           //HS RCOSC Power Up
           SLEEP &= ~0x04;
           while (!(SLEEP & 0x20));
           CLKCON |= 0x40;
           while (!(CLKCON & 0x40));
           SLEEP |= 0x04;
            


            // Mode PM2
            SLEEP = (SLEEP & 0xFC) | 0x02;
            asm ("NOP");
            asm ("NOP");
            asm ("NOP");
            if (SLEEP & 0x03)
            {
              PCON |= 0x02;
              asm ("NOP");
            }
           
            if ( SleepTimerInterrupt == 1 )
            {
              SleepTimerInterrupt = 0;
             
              //XOSC ON
              SLEEP &= ~0x04;
              while (!(SLEEP & 0x40));
              asm("NOP");
              CLKCON &= ~0X40;
              while (CLKCON & 0x40);
              SLEEP |= 0x04;
                  

              
              halLedToggle(3);

                                  
          }
     
        }
    }

  • Hi.

    Been a long time since i looked at the CC2430, but if memory serves me correctly the sleeptimer counts continuously and does not reset to 0 when there is a match. In your loop above the sleep time will be different the first time compared to all others as the first time the timer will be somewhere between (0x0000) and your ST value. For the next loop it will have to wait 0xFFFFFF as it will need to count all the way around.

    What you need is something that adds the sleep period to the current ST value. The code below shows how to add a second.


    void addToSleepTimer(UINT16 sec)
    {
      UINT32 sleepTimer = 0;

      sleepTimer |= ST0;
      sleepTimer |= (UINT32)ST1 <<  8;
      sleepTimer |= (UINT32)ST2 << 16;

      sleepTimer += ((UINT32)sec * (UINT32)32768);

      ST2 = (UINT8)(sleepTimer >> 16);
      ST1 = (UINT8)(sleepTimer >> 8);
      ST0 = (UINT8) sleepTimer;
    }

    Hope this helps.
    Regards,

    Kjetil

  • Hello Kjetil,

    Thank you very much for your answer. That problem is more or less what I thought that it should be the problem, but I tryied some change and I did not achive nothing, so I started to think about other problems. I have check your code into my software and I do not get nothing. In fact, I do not get the led on anytime, neither the first time, so, it works worst than before.

    I copy the actual code below, and I really claim TI employees to test the software into a SFR04 board with a CC2430 rev E chip on it, using the CC2430 Software Examples (Rev. E)(ZIP 479 KB ) 10441 views 23 Jun 2008 available in the web page, using the light_switch application and just using my code in the light_switch.c file with my code on it instead that one used in the sample, compile it and just the the led 3 blinking every 1 second (aprox). It is the unique thing I need and I suppose it is a very simple application such as to be developed as an example by TI employees.  I need to solve this problem this week to continue with 4 different projects. My e-mail address is javier.herrero@hc-technologies.com. If you want to send me the code for testing, or something similar, please, you can use my e-mail address but I suggest to post it here to be usefull to all the users.

     

    I hope this will be solve at the end this week after 3 long months.

     

    Javier

     

    /***********************************************************************************
    * INCLUDES
    */
    #include <hal_led.h>
    #include <hal_assert.h>
    #include <hal_board.h>
    #include <hal_int.h>
    #include "hal_mcu.h"
    //#include "hal_button.h"
    //#include "hal_rf.h"
    //#include "basic_rf.h"

     

    /***********************************************************************************
    * LOCAL VARIABLES
    */
    int SleepTimerInterrupt;

    //Rutina de Interrupcion

    _Pragma("vector=0x2B") __near_func __interrupt void ST_ISR(void);
    _Pragma("vector=0x2B") __near_func __interrupt void ST_ISR(void)
    {
      // Clear IRCON.STIF (Sleep Timer CPU interrupt flag)
     
     
      SLEEP &= 0xFC;
     

      IRCON &= ~0x80;
       
      SleepTimerInterrupt = 1;
     
     
    }

     

    #ifdef SECURITY_CCM
    // Security key
    static uint8 key[]= {
        0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
        0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
    };
    #endif

    void addToSleepTimer(UINT16 sec);


    main(void)
    {

    UINT16 seconds = 0x01;

    halBoardInit();

        // Main loop
      while (1) {
       
       
      EA = 1;
      
     
      addToSleepTimer (seconds);
     

       /*Set Sleep Timer in Ticks */
     /*   ST2 = 0x02;
        ST1 = 0x80;
        ST0 = 0x40; */
       
        /*Clear flag and enable interrupts */
        IRCON &= ~0x80;
        IEN0 = 0x00;
        STIE = 1;
       
       
        /*If Sleep interrupt Disable Interrupts and toggle led */
        if ( SleepTimerInterrupt == 1 )
        {
          SleepTimerInterrupt = 0;
         
          STIE = 0;
          EA=1;
         
          halLedToggle(3);
                       
        }
     
      }
    }

    void addToSleepTimer(UINT16 sec)
    {
      UINT32 sleepTimer = 0;
     
      sleepTimer |= ST0;
      sleepTimer |= (UINT32)ST1 <<  8;
      sleepTimer |= (UINT32)ST2 << 16;
     
      sleepTimer += ((UINT32)sec * (UINT32)32768);
     
      ST2 = (UINT8)(sleepTimer >> 16);
      ST1 = (UINT8)(sleepTimer >> 8);
      ST0 = (UINT8) sleepTimer;
    }

  • Hi again,

    The reason it does not work even the first time is that right before you set STIE = 1 in your code you disable EA (through setting IEN0 = 0x00).
    Secondly, you have a check for SleepTimerInterrupt that happens way earlier than the interrupt itself (which now is ~1 second).

    Change the code above to have a IEN0 = 0x80 instead of IEN0 = 0x00 and replace the if statement with while( SleepTimerInterrupt == 0 );

    With the above fixes, the code runs well on my SmartRF04EB with a rev.E of the device (CHVER = 0x04)

    The below code sleeps for ~1 second in low power mode 2 (based on the code you have posted earlier in this thread)


    /***********************************************************************************
    * INCLUDES
    */
    #include <hal_led.h>
    #include <hal_assert.h>
    #include <hal_board.h>
    #include <hal_int.h>
    #include "hal_mcu.h"

    /***********************************************************************************
    * LOCAL VARIABLES
    */
    int SleepTimerInterrupt;

    //Rutina de Interrupcion
    _Pragma("vector=0x2B") __near_func __interrupt void ST_ISR(void);
    _Pragma("vector=0x2B") __near_func __interrupt void ST_ISR(void)
    {
      // Clear IRCON.STIF (Sleep Timer CPU interrupt flag)
      SLEEP &= 0xFC;
      IRCON &= ~0x80;
      SleepTimerInterrupt = 1;
    }

    void addToSleepTimer(UINT16 sec);


    main(void)
    {
      UINT16 seconds = 0x01;
      halBoardInit();
     
      // Main loop
      while (1) {
        EA = 1;
        addToSleepTimer (seconds);
       
        /*Clear flag and enable interrupts */
        IRCON &= ~0x80;
        IEN0 = 0x80;
        STIE = 1;
       
        SLEEP = (SLEEP & 0xFC) | 0x02;
        asm ("NOP");
        asm ("NOP");
        asm ("NOP");
        if (SLEEP & 0x03)
        {
          PCON |= 0x02;
          asm ("NOP");
        }
       
       
        /*If Sleep interrupt Disable Interrupts and toggle led */
        if ( SleepTimerInterrupt == 1 )
          SleepTimerInterrupt = 0;
       
        STIE = 0;
        EA=1;
       
        halLedToggle(3);
      }
    }

    void addToSleepTimer(UINT16 sec)
    {
      UINT32 sleepTimer = 0;
     
      sleepTimer |= ST0;
      sleepTimer |= (UINT32)ST1 <<  8;
      sleepTimer |= (UINT32)ST2 << 16;
     
      sleepTimer += ((UINT32)sec * (UINT32)32768);
     
      ST2 = (UINT8)(sleepTimer >> 16);
      ST1 = (UINT8)(sleepTimer >> 8);
      ST0 = (UINT8) sleepTimer;
    }

    Hope this helps.

  • Hi Kjetil,

    I just wanted to point out that the code you supplied for reading the Sleep Timer will not correctly deal with the metastability issues that the Sleep Timer has. If you read at the exact instant the the registers are overflowing from one register to the next, there is a chance that the value read will not be correct. Let's focus on the increment of ST0 into ST1. There are two erroneous situations possible. First, it might be the case that ST1 might have incremented while ST0 has not (still 0xFF). Second, it might be the case that ST1 might not have incremented while ST0 has wrapped around to zero.

    Here is a quick piece of code you can put at the start of main to confirm the issue. Just put a breakpoint on the "BreakOccured" variable:

      uint32 value1;
      uint32 value2;
      int32  diff;
      bool   BreakOccurred = 0;

      // Documents Sleep Timer latch failure
      // breakpoint hit with:
      //   value1 = 0x0002A0FF
      //   value2 = 0x0002A1FF
      //   diff   = 256
      //
      //  value1 = 0x0003B9FF
      //  value2 = 0x0003B900
      //  diff   = -255
      MEMCTR |= MEMCTR_CACHDIS;
      value1 = 0;
      value2 = 0;
      diff   = 0;
      while (1) {
        ((uint8 *)&value1)[0] = ST0;
        ((uint8 *)&value1)[1] = ST1;
        ((uint8 *)&value1)[2] = ST2;
        ((uint8 *)&value2)[0] = ST0;
        ((uint8 *)&value2)[1] = ST1;
        ((uint8 *)&value2)[2] = ST2;
        diff  = value2 - value1;
        diff &= 0x00FFFFFFUL;
        if (diff > 10)
          BreakOccurred = true;
      }

     

    I would recommend that you replace the code that you use to read the Sleep Timer in function addToSleepTimer(UINT16 sec), with that below. From there you can add to the sleepTimer as normal.

     

    //*****************************************************************************
    //!
    //! Get the current value of the Sleep Timer (does an asynchronous read)
    //!
    //! \return SleepTimerValue
    //
    //*****************************************************************************
    uint32 TimerTask_GetSleepTimer(void) {
      uint32 value1;
      uint32 value2;

      // Init the upper bytes to zero since we never set these values
      // using the Sleep Timer read sequence.
      ((uint8 *)&value1)[3] = 0;
      ((uint8 *)&value2)[3] = 0;

      // Read the current value of the Sleep Timer. Read in order of least to
      // most significant because Chipcon is SUPPOSED to latch the ST2 and ST1 values
      // when ST0 is read.
      //
      // The latching, however, doesn't work. I have proven that if you read
      // the Sleep Timer twice in a row, you can get two different errors.
      // 1. 0x0002A0FF -> 0x0002A1FF (ST2, and ST1 did the increment but ST0 didn't)
      // 2. 0x0003B9FF -> 0x0003B900 (ST2, and ST1 didn't increment but ST0 did)
      //
      // Therefore, just do the read twice, just like we would expect from a normal
      // asynchronous timer read.
      //
      // I initially caught this one by reading the E2E forums on TI's website..
      // http://e2e.ti.com/forums/p/2409/9173.aspx#9173
      do {
        ((uint8 *)&value1)[0] = ST0;
        ((uint8 *)&value1)[1] = ST1;
        ((uint8 *)&value1)[2] = ST2;

        ((uint8 *)&value2)[0] = ST0;
        ((uint8 *)&value2)[1] = ST1;
        ((uint8 *)&value2)[2] = ST2;
        } while (value1 != value2);

      // return either value since they are both equal
      return value1;
    }

     

    Thanks

    darkwzrd

     

  • Hello,

    Thanks to Darkwzrd and Kjetil. The coder is now working ok with the Kjetil´s code with the fuction from Darkwazrd.

    Appart to thank both people who have help me very good, I would like to say TI people, that I have checked that the first mail to the technical support was sent on 2nd February, 6 month ago with some problems with the Power Modes (after that an Application Note was changed) and 5 months ago about the Sleep Timer. The question was posted in the forum some months ago, it was discussed with every step to which I could contact and finally the solution posted says that this problem was known more than one year before and today any Application Note, or Errata note, or the corrected datasheet has been changed. Today, after more than one year it was detected, CC2430 datasheet says that ST2, ST1 and ST0 are latched when ST0 change the value, and it is not true. So, please, I hope this problem will help to pay more attention in the documentation published to avoid more problems in this way.

    One more time, Kjetil and Darkwzrd, you have been my savers.... thanks a lot.

     

    Javier

     

  • I started with a fresh GenericApp. I want to use both SW5 and SW6 on CC2430DB. Right now, SW5 works in polling but SW6 does not have any effect. Fixing the bug according to your suggestion does not change anything either.

    I also tried to use 'OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;'. After joining the network, the red led is lit, but neither of SW5 and SW6 works.

    Did you experience this kind of problem?

  • I find the problem which was pointed out by another poster here before.

     

    MUST use "#define HAL_KEY_SW_6_EDGE     HAL_KEY_RISING_EDGE" instead in hal_key.c

  • Hi everybody,

    I find this discussion  the most appropriate place for my question.

    Has anybody had a problem with the power consumption when using TIMAC 1.3.0 library(banked version). I have been using TIMAC 1.2.1 quite a long time and I know the main issues about power saving (same things mentioned in this discussion.)

    I have noticed that everything works when I am debugging with IAR but when I power up the board(own proto) with battery PM1 remains. Funny thing is that when debug clock 2.2 is connected to groung after few seconds the CC2430 enters PM2 but does not wake up.

    Any opinions what to do? I don't want SmartRF04EB + PC to be always carried with the small sensor board:)

  • Problem solved.

    Definition that selects internal or external oscillator for sleep timer was missing.

    Strange behaviour of P2_2 remains but I have no time to learn more of that.

  • Hi I am using SmartRF05 EB with CC2530 CC2530ZDK_EM .

    I am trying to implement TIMAC on CC2530 with lowest power option. Problem is that when i am making

    #define MSA_KEY_INT_ENABLED       TRUE //  Changed to TRUE from false to avoid polling. in msa.h

    it is going for sleep but without pressing any keys (without touching the Joy stick) it is taking interrupt and it stops posting data. When again i am pressing sw2(Joy stick position 2) it starts sending data and after sending 2-3 packets it stops again. I mean to say it is taking interrupt without pressing any keys.

    I removed the CC2530 EM from RF05EB and just supplied power through connecting through burg stick to power supply it is not at all sending any data.

    I tried to disbale keys and without key press i want to send data to avoid this .

    When I am making change in hal_board_cfg.h to disable keys

    #ifndef HAL_KEY
    #define HAL_KEY FALSE //TRUE To disable the keys
    #endif

    The red LED blinks and it never sends any data.

    Please Help me in this regard

     

     

  • Very helpfule! thanks Kjetil and guys very much!

    I got the same problem and very desperate.

    You guys helped me well!

    thanks again!

    :)

  •  

    Hi,

    I'm using TIMAC to send the data to co-ordinator at regular interval ( once in an hour ), so my end device has to send the data  to co-ordinator and go back to sleep and needs to wake up at after 1 hr . I'm using hal_sleep(10000)  fun to send this to sleep. its going to sleep but the problem when its in sleep mode voltage on the I/0 pins are high only and LED is also ON..

     

    When I send to sleep mode it should be switch off all I/O pins led etc , since I want send it in Power mode 2(i.e except sleep timer evrry thing should be OFF , according to data sheet) .

     And in data sheet it shows that when it goes to sleep mode it should consume only  0.2micro to 0.3micro amps but my EM device is consuming 2mA when its in sleepmode .

    How to send this to powermode 2 properly ..? How to switch of the digital regulator ?

     

    regards

    chethan 

  • Hi everyone,

    after an hard work of some moths we discovered the trick to make a low power application, so the CC2430 or CC2530 can enter in a deep sleep mode ( PM2).

    Before the sleep procedure is necessary set the MAC_RX_ON_WHEN_IDLE to False and after the sleep period set this to True, so:

    MAC_MlmeSetReq(MAC_RX_ON_WHEN_IDLE, &MACTrue);   // set True after the sleep procedure

    MAC_MlmeSetReq(MAC_RX_ON_WHEN_IDLE, &MACFalse);   // set False before the sleep procedure so the chip can enter in PM2

    I use a function that call theese sets and the chip works ok.

    Regards,

    Emanuele Tavelli

     

     

     

  • Hi,

    After including these function only its going to sleep , . My worry is , it is consuming 2mA current when it's in sleep ,according to data sheet when its sleep mode(POWER MODE2) it should not consume more than 0.3mA ,. Have you checked the current consuption of your board ..?

    regards

    chethan