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.

Power management CC2650STK + Power analyzer questions

Other Parts Discussed in Thread: CC2650STK, SYSBIOS, HDC1000, CC2650, ENERGYTRACE, OPT3001

Hi,

I'm now under my first development project based on CC2650STK with DevPack, but I have some problems with Power managment.

In my cfg I have:

var Power = xdc.useModule('ti.sysbios.family.arm.cc26xx.Power');

Power.idle = true;
Power.policyFunc = Power.standbyPolicy;
Power.calibrateRCOSC = false;

In my main:

#include <ti/sysbios/family/arm/cc26xx/Power.h>
#include <ti/sysbios/family/arm/cc26xx/PowerCC2650.h>

But I can't find any AppNote according to power managment in TI-RTOS, I have simple main file which toggle led in task and goes to sleep for 60 secs, but the power consumption is 3.5mA during sleep (with LED off). Is there any documents according power managment?

And about power analyzing is there any debugger with energy trace for simple link MCUs?

Best regars

  • Hello,

    Indeed there is a document about CC26xx Power Management: file:///C:/ti/tirtos_simplelink_2_11_01_09/docs/Power_Management_CC26xx.pdf

    Note that if you are executing code prior to BIOS_start(), then no power management is applied.

    There is no debugger with energy trace, but you can follow the guidance in the Measuring Bluetooth Smart Power Consumption app note, available on the TI BLE wiki: www.ti.com/ble-wiki.

    Best wishes
  • Thank you for fast reply.

    I may not understand it correctly, but is there any examples using Power Managment? Maybe I'll paste here my code I just added empty_min from TI-RTOS example resources - added policy settings to cfg and extended task_sleep to 30 secs. I hoped that it'll go to standby during task_sleep but with led off it's power consumption is around 6,5 mA. Can you just check and maybe verify what I did wrong? 

    /*
     *  ======== empty_min.c ========
     */
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    
    #include <ti/sysbios/family/arm/cc26xx/Power.h>
    #include <ti/sysbios/family/arm/cc26xx/PowerCC2650.h>
    
    /* TI-RTOS Header files */
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    // #include <ti/drivers/SPI.h>
    // #include <ti/drivers/UART.h>
    // #include <ti/drivers/Watchdog.h>
    
    /* Board Header files */
    #include "Board.h"
    
    /* Pin driver handle */
    static PIN_Handle ledPinHandle;
    static PIN_State ledPinState;
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config ledPinTable[] = {
        Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        Board_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        PIN_TERMINATE
    };
    
    /*
     *  ======== heartBeatFxn ========
     *  Toggle the Board_LED0. The Task_sleep is determined by arg0 which
     *  is configured for the heartBeat Task instance.
     */
    Void heartBeatFxn(UArg arg0, UArg arg1)
    {
        while (1) {
            Task_sleep(3000000);
            PIN_setOutputValue(ledPinHandle, Board_LED1,
                               !PIN_getOutputValue(Board_LED1));
        }
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call board init functions. */
        Board_initGeneral();
        // Board_initI2C();
        // Board_initSPI();
        // Board_initUART();
        // Board_initWatchdog();
    
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, ledPinTable);
        if(!ledPinHandle) {
            System_abort("Error initializing board LED pins\n");
        }
    
        PIN_setOutputValue(ledPinHandle, Board_LED1, 1);
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    
    /*
     * Copyright (c) 2015, 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.
     */
    
    /*
     *  ======== empty_min.cfg ========
     */
    
    /* ================ General configuration ================ */
    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Main = xdc.useModule('xdc.runtime.Main');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');
    
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var m3Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
    
    var Power = xdc.useModule('ti.sysbios.family.arm.cc26xx.Power');
    var Boot = xdc.useModule('ti.sysbios.family.arm.cc26xx.Boot');
    Boot.customerConfig = true;
    
    /*
     * use the kernel in the ROM
     */
    var ROM = xdc.useModule('ti.sysbios.rom.ROM');
    if (Program.cpu.deviceName.match(/CC26/)) {
        ROM.romName = ROM.CC2650;
    }
    else if (Program.cpu.deviceName.match(/CC13/)) {
        ROM.romName = ROM.CC1350;
    }
    
    /*
     *  Program.stack is ignored with IAR. Use the project options in
     *  IAR Embedded Workbench to alter the system stack size.
     */
    if (!Program.build.target.$name.match(/iar/)) {
        /*
         *  Reducing the system stack size (used by ISRs and Swis) to reduce
         *  RAM usage.
         */
        Program.stack = 512;
    }
    
    /* ================ System configuration ================ */
    var SysCallback = xdc.useModule('xdc.runtime.SysCallback');
    System.SupportProxy = SysCallback;
    System.maxAtexitHandlers = 0;
    
    /* Remove debug strings from the application */
    Text.isLoaded = false;
    
    /* Remove the raise hook from the application */
    Error.raiseHook = null;
    
    /* ================ Kernel configuration ================ */
    /* Use Custom library with no logging or asserts */
    BIOS.libType = BIOS.LibType_Custom;
    BIOS.logsEnabled = false;
    BIOS.assertsEnabled = false;
    
    BIOS.heapSize = 1024;
    
    /* Do not use Hwi_excHandlerMin */
    m3Hwi.excHandlerFunc = null;
    
    /* Do not check Task or System stacks  */
    Task.checkStackFlag = false;
    Hwi.checkStackFlag = false;
    
    /* Reduce the number of Task priorities */
    Task.numPriorities = 4;
    
    /* Reduce the default stack size */
    Task.defaultStackSize = 512;
    
    /* Do not create an Idle thread */
    Task.enableIdleTask = false;
    
    /*
     * With default Clock tick mode by default is TickMode_DYNAMIC, we can set the
     * tick period to 10 us without additional interrupt overhead.
     */
    Clock.tickPeriod = 10;
    
    /* ================ Task configuration ================ */
    var task0Params = new Task.Params();
    task0Params.instance.name = "heartBeat";
    task0Params.arg0 = 1000000 / Clock.tickPeriod;
    task0Params.stackSize = 512;
    Program.global.task = Task.create("&heartBeatFxn", task0Params);
    
    /* ================ Driver configuration ============== */
    var TIRTOS = xdc.useModule('ti.tirtos.TIRTOS');
    
    Power.idle = true;
    Power.policyFunc = Power.standbyPolicy;
    Power.calibrateRCOSC = false;
    

    Best regards

  • Hi Koper,

    You have disabled the Idle task so I think RTOS will just stay in a while() loop when nothing is happening in the system.

    I suggest using our example config files and example projects to get started. For reference, here is a copy of the configuration used by all our examples (appBLE.cfg):

    var ROM = xdc.useModule('ti.sysbios.rom.ROM');
    ROM.romName = ROM.CC2650;
    
    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Types = xdc.useModule('xdc.runtime.Types');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Main = xdc.useModule('xdc.runtime.Main');
    var Memory = xdc.useModule('xdc.runtime.Memory')
    var SysCallback = xdc.useModule('xdc.runtime.SysCallback');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');
    var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
    var Reset = xdc.useModule('xdc.runtime.Reset');
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var M3Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
    var Power = xdc.useModule('ti.sysbios.family.arm.cc26xx.Power');
    
    /* Enable idle task (default). */
    Task.enableIdleTask = true;
    
    /* Idle CPU when threads blocked waiting for an interrupt */
    Power.idle = true;
    Power.policyFunc = Power.standbyPolicy;
    
    /* compile out all Assert's */
    Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
    
    /* Don't load string names of modules on the target */
    Defaults.common$.namedModule = false;
    
    /* Allow Mod_create() and Mod_construct() but not delete() or destruct() */
    Defaults.common$.memoryPolicy = Types.CREATE_POLICY;
    
    /* Don't load diagnostic/descriptive text strings on the target */
    Text.isLoaded = false;
    
    /* Use the minimal user-supplied callback provider */
    System.SupportProxy = SysCallback;
    /* no exit handlers needed */
    System.maxAtexitHandlers = 0;
    
    /* main() and Hwi, Swi stack size */
    Program.stack = 1024;
    /* no command-line arguments main(argc, argv) needed */
    Program.argSize = 0;
    
    /* build a custom, optimized version of SYS/BIOS */
    BIOS.libType = BIOS.LibType_Custom;
    
    /* no logging - all compiled out */
    BIOS.logsEnabled = false;
    
    /* disable Asserts in SYS/BIOS code */
    BIOS.assertsEnabled = false;
    
    /* Reduce number of Task priority levels to save RAM */
    Task.numPriorities = 6;
    
    /* Set the default Task stack size - used if one is not specified */
    Task.defaultStackSize = 512;
    
    /* Don't check stacks for overflow - saves cycles (and power) and Flash */
    Task.checkStackFlag = false;
    
    /* Disable exception handling to save Flash - undo during active development */
    M3Hwi.enableException = true;
    M3Hwi.excHandlerFunc = null; /* null = default while loop function. Use e.g. "&myFxn" to use your own function. */
    M3Hwi.nvicCCR.UNALIGN_TRP = 0;
    M3Hwi.nvicCCR.DIV_0_TRP = 0;
    
    /* Don't check for interrupt stack overflow during Idle loop */
    Hwi.checkStackFlag = false;
    
    /* Minimize Flash and RAM usage of Error module */
    Error.raiseHook = null; /* null = default while loop function. Use e.g. "&myFxn" to your own handler function. */
    Error.maxDepth = 2;
    
    /* Set the default CPU frequency */
    BIOS.cpuFreq.lo = 48000000;
    
    /* Put reset vector at start of Flash */
    M3Hwi.resetVectorAddress  = 0x0;
    
    /* Put interrupt vector at start of RAM so interrupts can be configured at runtime */
    M3Hwi.vectorTableAddress  = 0x20000000;
    
    /* CC2650 has 50 interrupts */
    M3Hwi.NUM_INTERRUPTS = 50;
    
    /* Set heap size */
    BIOS.heapSize = 1668;
    
    var Swi = xdc.useModule('ti.sysbios.knl.Swi');
    Swi.numPriorities = 6;
    BIOS.swiEnabled = true;
    
    BIOS.includeXdcRuntime = true;
    
    /* Tasks cannot pend based on priority */
    Semaphore.supportsPriority = false;
    
    /* Change default error function -- just spin */
    Error.policyFxn = Error.policySpin;
    
    /* true:  Allow runtime creation of e.g. semaphores
     * false: Compile out reference to Memory in BIOS */
    BIOS.runtimeCreatesEnabled = true;
    
    /* Abort and exit functions -- just spin */
    System.abortFxn = System.abortSpin;
    System.exitFxn = System.exitSpin;
    
    /* CC26xx Boot module */
    var Boot = xdc.useModule('ti.sysbios.family.arm.cc26xx.Boot');
    Boot.driverlibVersion = 2;
    Boot.customerConfig = false;
    //Boot.checkBackdoor = false;
    
    /* Turn on RCOSC_HF calibration, thus enabling fast startup */
    Power.calibrateRCOSC = true;
    //Power.calibrateRCOSC = false;
    
    /* 10 us tick period */
    Clock.tickPeriod = 10;
    

    Regards,

    Svend

  • Hello Svend,

    Thank you for reply, but after changing cfg I still have 3.5mA in idle, maybe some of devices on CC2650STK need to be disabled first? And the one I use is an example project called Empty Project from TI Resources, I don't want to use BLE Stack for now, because I want to have as much control of device as I can to clarify some things. And to your example cfg I needed to add:

    var TIRTOS = xdc.useModule('ti.tirtos.TIRTOS');

    because I had errors that PIN_init PIN_open etc are unresolved symbols.  I'm using 2.13.1.09 version of TI-RTOS for SimpleLink, CC2650 STK (version with HDC1000 instead of SHT20). Do you have any clues what I can do more? Measurment of current I made after debug process (i disconnect devpack and take off CR2032 battery and I power it from battery pins.

    Best regards,

    Koper

  • Hi Koper,

    I'm having the same problem myself. I think I'll have to go through the datasheets of all the sensors I'm not using and check they're set up for lowest power consumption. I'm not convinced that's the only issue, but if I have any success I'll report back.

    koper89 said:
    And about power analyzing is there any debugger with energy trace for simple link MCUs?

    Officially, no. Unofficially any of the MSP launchpads with onboard EnergyTrace can be used to power the SensorTag. You need to disconnect the on-board target from power and run leads over to the SensorTag's battery pack connection points. Then you can open an EnergyTrace session without using the debugger in CCS to take measurements.

    The MSP-EXP432P401R is the best option, as it only costs $12.99 (20/08/2015). It's also possible to modify that board to add a Cortex debug JTAG cable which allows EnergyTrace use while debugging the SensorTag. You need razor-sharp vision and nerves of steel for that, however!

  • I've discovered the main issues that were causing the excessive power consumption.

    The first was specific to my SensorTag, which appears to have suffered damage to the TMP007 die on the board. The TMP007 was unresponsive even when using TI's sample code. Removing the damaged chip reduced the current drawn by ~4mA. This confirms that it was damaged, as the maximum quiescent current is specified as 350uA.

    The second problem was that the version of TI-RTOS I used with BLE Stack 2.0 doesn't enable the idle task and power profile by default. This leaves the CPU active when all tasks are sleeping. Enabling the standbyProfile saves 2.9mA when all tasks are sleeping, assuming the CPU clock is 48MHz when active. After switching to BLE Stack 2.1 and TI-RTOS 2.14.01.19 I found that the standbyProfile is correctly configured in the empty_min project.

    The next issue is that the MPU is powered on by default (check the BoardGpioInitTable in board.c). Turning that off saves another 3mA.

    The final major issue is caused by an interaction between the W25X40CL serial flash and the SPI bus pins. The problem is that board.c doesn't provide a configuration for the SPI bus pins, so they take the default of input with no pull resistor. When the W25X40CL chip select is inactive it allows its SPI pins to float, and this results in shoot-through current in the CC2650 input drivers. EDIT: I think the problem is actually the other way around. The default configuration disables both the input buffer and pull resistor on the CC2650 SPI pins. That lets the SPI CLK and MOSI pins float, and the shoot-through occurs in the W25X40CL serial flash. Providing a proper configuration saved 0.5mA

    Implementing these fixes took the current consumption of the empty_min project down to ~10uA with the LED off.

    I also looked into putting the W25X40CL flash into power-down mode. That saved just 7.5uA.

    Checking through all the components on the SensorTag it seems that the following are already configured for minimum power consumption at startup: BMP280, HDC1000, OPT3001, microphone, reed switch, buzzer, buttons and LEDs. The CC2650 RF core is inactive too.

    Components which can have their power consumption reduced after startup are TMP007, W25X40CL and the MPU.