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.

RTOS/LAUNCHXL-CC26X2R1: power management

Part Number: LAUNCHXL-CC26X2R1


Tool/software: TI-RTOS

Hi, 

I've read through this documentation already: http://www.ti.com/lit/ug/sprui18c/sprui18c.pdf

I am trying to add basic power management functionality on the SimplePeripheral example project. So far, in main.c I've added

  /* Enable the configured power policy to run when the CPU is idle */

  Power_enablePolicy();

 

The application build and runs in debug mode fine. I was wondering if there is a way to check what mode I am in and if I have actually started the default power policy. I would like to add that when the app is on sleep or on wake up events to print out via UART (time stamp). I also want to be in WFI low power mode, and then wake up on bluetooth event or to service a notification period. 

Thanks!

Are there example projects I could look at?

Best, 

Ida Huang

  • Have you seen dev.ti.com/.../power.html

    What you are referring to is typically done in the power driver (PowerCC26X2.c) and ble_debug.cfg/ ble_realese.cfg files.
  • Hi,

    So in main.c . after adding Power_enablePolicy(); and

    Power_registerNotify(&CC26XXPowerNotifyObj,
    PowerCC26XX_ENTERING_STANDBY | PowerCC26XX_AWAKE_STANDBY,
    (Power_NotifyFxn) CC26XXPowerNotifyObjCb, NULL);

    I don't see my device on the bluetooth tool and can't connect to it. I was wondering if instead I need to call ICallPlatform_pwrRegisterNotify in the application main so in SimplePeripheral_taskFxn()?

    Where can I find ble_debug.cfg/ ble_realese.cfg files?


    Thanks!
  • /******************************************************************************
    
     @file  main.c
    
     @brief main entry of the BLE stack sample application.
    
     Group: CMCU, LPRF
     Target Device: CC2652
    
     ******************************************************************************
     
     Copyright (c) 2013-2018, Texas Instruments Incorporated
     All rights reserved.
    
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
     are met:
    
     *  Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    
     *  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    
     *  Neither the name of Texas Instruments Incorporated nor the names of
        its contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     ******************************************************************************
     Release Name: simplelink_cc26x2_sdk_2_20_00_36
     Release Date: 2018-06-27 10:07:01
     *****************************************************************************/
    
    /*******************************************************************************
     * INCLUDES
     */
    
    #include <xdc/runtime/Error.h>
    
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26XX.h>
    #include <ti/sysbios/BIOS.h>
    #include "ti/ti154stack/icall/src/inc/ICall_CC26xx_DEFS.h"
    #include <icall.h>
    #include "hal_assert.h"
    #include "bcomdef.h"
    #include "simple_peripheral.h"
    #ifdef PTM_MODE
    #include "npi_task.h"
    #endif // PTM_MODE
    
    /* Header files required to enable instruction fetch cache */
    #include <inc/hw_memmap.h>
    #include <driverlib/vims.h>
    
    #ifndef USE_DEFAULT_USER_CFG
    #include "ble_user_config.h"
    // BLE user defined configuration
    icall_userCfg_t user0Cfg = BLE_USER_CFG;
    #endif // USE_DEFAULT_USER_CFG
    
    #include <ti/display/Display.h>
    
    /*******************************************************************************
     * MACROS
     */
    #define POWER_SAVING                 1
    /*******************************************************************************
     * CONSTANTS
     */
    
    /*******************************************************************************
     * TYPEDEFS
     */
    
    /*******************************************************************************
     * LOCAL VARIABLES
     */
    
    /*******************************************************************************
     * GLOBAL VARIABLES
     */
    #ifdef POWER_SAVING
    // Power Notify Object for wake-up callbacks
    Power_NotifyObj CC26XXPowerNotifyObj;
    static uint8_t CC26XXPowerNotifyObjCb(uint8_t eventType, uint32_t *eventArg,
                                    uint32_t *clientArg);
    #endif //POWER_SAVING
    
    /*******************************************************************************
     * EXTERNS
     */
    
    extern void AssertHandler(uint8 assertCause, uint8 assertSubcause);
    
    extern Display_Handle dispHandle;
    
    /*******************************************************************************
     * @fn          Main
     *
     * @brief       Application Main
     *
     * input parameters
     *
     * @param       None.
     *
     * output parameters
     *
     * @param       None.
     *
     * @return      None.
     */
    int main()
    {
      /* Register Application callback to trap asserts raised in the Stack */
      RegisterAssertCback(AssertHandler);
    
      /* Call board init functions */
      Board_initGeneral();
    
      /* Enable the configured power policy to run when the CPU is idle */
      Power_enablePolicy();
    
    #ifdef POWER_SAVING
      Power_registerNotify(&CC26XXPowerNotifyObj,
                           PowerCC26XX_ENTERING_STANDBY | PowerCC26XX_AWAKE_STANDBY,
                           (Power_NotifyFxn) CC26XXPowerNotifyObjCb, NULL);
    #endif //POWER_SAVING
    
      // Enable iCache prefetching
    
      VIMSConfigure(VIMS_BASE, TRUE, TRUE);
      // Enable cache
      VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED);
    
    #if !defined( POWER_SAVING )
      /* Set constraints for Standby, powerdown and idle mode */
      // PowerCC26XX_SB_DISALLOW may be redundant
      Power_setConstraint(PowerCC26XX_SB_DISALLOW);
      Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
    #endif // POWER_SAVING
    
      /* Update User Configuration of the stack */
      user0Cfg.appServiceInfo->timerTickPeriod = Clock_tickPeriod;
      user0Cfg.appServiceInfo->timerMaxMillisecond  = ICall_getMaxMSecs();
    
      /* Initialize ICall module */
      ICall_init();
    
      /* Start tasks of external images - Priority 5 */
      ICall_createRemoteTasks();
    #ifdef PTM_MODE
      /* Start task for NPI task */
      NPITask_createTask(ICALL_SERVICE_CLASS_BLE);
    #endif // PTM_MODE
    
      SimplePeripheral_createTask();
    
      /* enable interrupts and start SYS/BIOS */
      BIOS_start();
    
      return 0;
    }
    
    
    /*******************************************************************************
     * @fn          AssertHandler
     *
     * @brief       This is the Application's callback handler for asserts raised
     *              in the stack.  When EXT_HAL_ASSERT is defined in the Stack
     *              project this function will be called when an assert is raised,
     *              and can be used to observe or trap a violation from expected
     *              behavior.
     *
     *              As an example, for Heap allocation failures the Stack will raise
     *              HAL_ASSERT_CAUSE_OUT_OF_MEMORY as the assertCause and
     *              HAL_ASSERT_SUBCAUSE_NONE as the assertSubcause.  An application
     *              developer could trap any malloc failure on the stack by calling
     *              HAL_ASSERT_SPINLOCK under the matching case.
     *
     *              An application developer is encouraged to extend this function
     *              for use by their own application.  To do this, add hal_assert.c
     *              to your project workspace, the path to hal_assert.h (this can
     *              be found on the stack side). Asserts are raised by including
     *              hal_assert.h and using macro HAL_ASSERT(cause) to raise an
     *              assert with argument assertCause.  the assertSubcause may be
     *              optionally set by macro HAL_ASSERT_SET_SUBCAUSE(subCause) prior
     *              to asserting the cause it describes. More information is
     *              available in hal_assert.h.
     *
     * input parameters
     *
     * @param       assertCause    - Assert cause as defined in hal_assert.h.
     * @param       assertSubcause - Optional assert subcause (see hal_assert.h).
     *
     * output parameters
     *
     * @param       None.
     *
     * @return      None.
     */
    void AssertHandler(uint8 assertCause, uint8 assertSubcause)
    {
      // Open the display if the app has not already done so
      if ( !dispHandle )
      {
        dispHandle = Display_open(Display_Type_ANY, NULL);
      }
    
      Display_print0(dispHandle, 0, 0, ">>>STACK ASSERT");
    
      // check the assert cause
      switch (assertCause)
      {
        case HAL_ASSERT_CAUSE_OUT_OF_MEMORY:
          Display_print0(dispHandle, 0, 0, "***ERROR***");
          Display_print0(dispHandle, 2, 0, ">> OUT OF MEMORY!");
          break;
    
        case HAL_ASSERT_CAUSE_INTERNAL_ERROR:
          // check the subcause
          if (assertSubcause == HAL_ASSERT_SUBCAUSE_FW_INERNAL_ERROR)
          {
            Display_print0(dispHandle, 0, 0, "***ERROR***");
            Display_print0(dispHandle, 2, 0, ">> INTERNAL FW ERROR!");
          }
          else
          {
            Display_print0(dispHandle, 0, 0, "***ERROR***");
            Display_print0(dispHandle, 2, 0, ">> INTERNAL ERROR!");
          }
          break;
    
        case HAL_ASSERT_CAUSE_ICALL_ABORT:
          Display_print0(dispHandle, 0, 0, "***ERROR***");
          Display_print0(dispHandle, 2, 0, ">> ICALL ABORT!");
          HAL_ASSERT_SPINLOCK;
          break;
    
        case HAL_ASSERT_CAUSE_ICALL_TIMEOUT:
          Display_print0(dispHandle, 0, 0, "***ERROR***");
          Display_print0(dispHandle, 2, 0, ">> ICALL TIMEOUT!");
          HAL_ASSERT_SPINLOCK;
          break;
    
        case HAL_ASSERT_CAUSE_WRONG_API_CALL:
          Display_print0(dispHandle, 0, 0, "***ERROR***");
          Display_print0(dispHandle, 2, 0, ">> WRONG API CALL!");
          HAL_ASSERT_SPINLOCK;
          break;
    
      default:
          Display_print0(dispHandle, 0, 0, "***ERROR***");
          Display_print0(dispHandle, 2, 0, ">> DEFAULT SPINLOCK!");
          HAL_ASSERT_SPINLOCK;
      }
    
      return;
    }
    
    
    /*******************************************************************************
     * @fn          smallErrorHook
     *
     * @brief       Error handler to be hooked into TI-RTOS.
     *
     * input parameters
     *
     * @param       eb - Pointer to Error Block.
     *
     * output parameters
     *
     * @param       None.
     *
     * @return      None.
     */
    void smallErrorHook(Error_Block *eb)
    {
      for (;;);
    }
    
    #if defined (POWER_SAVING)
    /*******************************************************************************
     * @fn          CC26XXPowerNotifyObjCb
     *
     * @brief       Power driver callback to print Power state transitions over UART
     *
     *
     * input parameters
     *
     * @param   eventType - The state change.
     * @param   eventArg  - Not used.
     * @param   clientArg - Not used.
     *
     * @return  Power_NOTIFYDONE to indicate success.
     */
    static uint8_t CC26XXPowerNotifyObjCb (uint8_t eventType, uint32_t *eventArg,
                                           uint32_t *clientArg)
    {
        // Open the display if the app has not already done so
        if ( !dispHandle )
        {
            dispHandle = Display_open(Display_Type_ANY, NULL);
        }
        if (eventType == ICALL_PWR_ENTER_STANDBY)
        {
            Display_print0(dispHandle, 20, 0, "Entering STANDBY mode...");
        }
        else if (eventType == ICALL_PWR_AWAKE_FROM_STANDBY)
        {
            Display_print0(dispHandle, 20, 0, "Waking up from STANDBY mode...");
        }
    
     // Notification handled successfully
     return Power_NOTIFYDONE;
    }
    #endif //POWER_SAVING
    
    /*******************************************************************************
     */
    
    Seems like the bluetooth does not work after I call Power_registerNotify

  • For the .cfg files, check the TOOLS folder in the example.

    Have you checked that the power management works if you use the example right out of the box? It should not be required to add anything extra to your code to get that to work.
  • I think there is a conflict with the display two button menu set up in simple_peripheral.c and the one in main.c.
  • Are you referring to the project unmodified directly from the SDK?

    And which impact does the conflict have? Please elaborate a bit what you mean.
  • No I am referring to Display prints I added to

    static uint8_t CC26XXPowerNotifyObjCb (uint8_t eventType, uint32_t *eventArg,
    uint32_t *clientArg)

    which I have is at the end of main.c. Seems like this conflicts with the bluetooth displays in application.
  • That circles back to my first question: Why have you added the power policy code to the example? Have you tested without to check if the power consumption is as expected? I'm trying to understand your end goal here.
  • I'm just trying understand how the power policy works with bluetooth and sensors. In which situations is it in low power mode (standby) and when is it awake. To me it seems like, I am mostly in standby and when I call Event_pend in simple peripheral it was waking up.

    I'd like to figure out how I can add timestamps to see how long it is in each of these power modes. 

    Ida

  • Hi Ida,

    Reading this document might help. When there is no event the device goes to standby mode.

    www.ti.com/.../swra478c.pdf

    -kel