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.

CC3220SF-LAUNCHXL: Confused on CC3220 power modes

Part Number: CC3220SF-LAUNCHXL
Other Parts Discussed in Thread: CC3220SF, INA3221

Dear Support:

I have been working on trying to use my CC3220SF LP using SDK v1.50 to get the CPU to go to sleep on command using either hibernate mode (i.e. Power_shutdown(...)) or LPDS mode (i.e., Power_enablePolicy()).  I have been using the power_measurement example from the SDK to understand how to do this and have been able to get this example to boot up from hibernate mode and execute the callback method as well as entering LPDS mode and having it come out as a result of a GPIO transition for LPDS mode.  However upon taking this code and getting it to work with my larger project, I am running into problems getting the same code to come out of LPDS mode with the same GPIO that is being used with the power_measurement example that I am using.  I have noticed in my power_measurement example that when it goes into LPDS mode, that the current draw from the CC3220SF is pretty much zero.  And it comes out of LPDS mode with a GPIO (currently using the pushbutton on the LP) and resumes operation - as expected and no issues.  In the power_measurement example the WiFi is not running since sl_Start(...) has not been called prior to going into LPDS which I assume explains why the current is pretty much zero.   

However when I do the same operation with pretty much the same method of going into LPDS as is done with my power_measurent example, I notice that the current does not go to zero, but instead drops by about 10 mA (i.e. from 80 mA prior to LPDS being initiated to 70 mA) after LPDS being initiated.  And the callback routine that was working with the power_measurement example is not being called when the GPIO (i.e. pushbutton is pressed) is toggled.  In this larger project, I have the I2S, I2C and UART, peripherals running as well as WiFi and several other TI-RTOS tasks, whereas with the power_measurement example, only the UART is running. So do you know what is wrong here as to why the current doesn't go to zero with this larger project, but it does go to zero with the power_measurement example?  I assume it has to do with WiFi running and other driver peripherals being opened.  Is that the case?

But my more bigger issue is why doesn't the LPDS callback routine get entered like it does with the power_measurement example?  Below is the PowerCC32XX_config definition I am using:

void gpioButtonFxn1(uint32_t index);

const PowerCC32XX_ConfigV1 PowerCC32XX_config = {
.policyInitFxn = &PowerCC32XX_initPolicy,
.policyFxn = &PowerCC32XX_sleepPolicy,
.enterLPDSHookFxn = NULL,
.resumeLPDSHookFxn = NULL,
.enablePolicy = false,
.enableGPIOWakeupLPDS = true,
.enableGPIOWakeupShutdown = true,
.enableNetworkWakeupLPDS = true,
.wakeupGPIOSourceLPDS = PRCM_LPDS_GPIO13,
.wakeupGPIOTypeLPDS = PRCM_LPDS_FALL_EDGE,
.wakeupGPIOFxnLPDS = gpioButtonFxn1,
.wakeupGPIOFxnLPDSArg = 3,
.wakeupGPIOSourceShutdown = 0,
.wakeupGPIOTypeShutdown = 0,
.ramRetentionMaskLPDS = PRCM_SRAM_COL_1 | PRCM_SRAM_COL_2 |
PRCM_SRAM_COL_3 | PRCM_SRAM_COL_4,
.keepDebugActiveDuringLPDS = false,
.ioRetentionShutdown = PRCM_IO_RET_GRP_1,
.pinParkDefs = parkInfo,
.numPins = sizeof(parkInfo) / sizeof(PowerCC32XX_ParkInfo)
};

So although the current drops by 10 mA by going into LPDS, it's a long ways from zero (~70 mA), the callback routine of gpioButtonFxn1 does not get called like it does with power_measurement and that's a problem.  Please advise as to what may be the problem.

Also when going into hibernate mode, there is an element in the PowerCC32XX_config structure defined as such:

.enableGPIOWakeupShutdown = true,

which suggests that the hibernate mode can be exited with a GPIO pin.  However from the reading of the documentation, this suggests otherwise.  From the power_measurement example that I have been using, the power_shutdown(...) call is only exited by a timeout by entering a non-zero value for the shutdownTime in the argument list of this function call.  This works fine with the power_measurement example as well as with the larger project that I am using, but would really like to go into hibernate mode indefinitely until a specific GPIO pin transition is detected and then come out as a result of a falling or rising edge of the GPIO pin.  Is this possible?  And if not, then what is the purpose of the element:

.enableGPIOWakeupShutdown

in the PowerCC32XX_config structure defined in the file CC3220SF_LAUNCHXL.c?  Please advise.

Thanks,
Tim

  • Hi Tim,

    The current you get in LPDS should be in line with the always connected case of the power measurement example. In that case, the NWP is connected to the AP but should be able to dynamically change it's own power state into lower power modes when able.

    If you are not getting the numbers indicated in the power measurement appnote, then most likely your application is not spending much time in LPDS. When you mention your current measurement of ~70mA, how are you measuring this? Is this the average current, the instantaneous max current you see in your sample, or is this is the baseline current during what should be LPDS?

    One thing to keep in mind is that Power_enablePolicy() doesn't put the application into LPDS immediately. It only enables the use of LPDS when the MCU is idle. The way the power management engine in TIRTOS works is that when the MCU is idle, that is to say when all threads are blocked, it will automatically enter LPDS for you as a way to save power. However, if you have tasks that are constantly running then the device will not enter LPDS as often and consume more power than expected.

    As the device is entering and exiting LPDS very frequently based on your thread activity, the wakeupGPIOFxnLPDS is not invoked as much, if at all since the state transitions are not being triggered by the GPIO. If you want to have a specific function fire every time you exit LPDS, you should assign it as the resumeLPDSHookFxn. As for ensuring you get lower power numbers with LPDS, I would suggest you take a look at the threads you have running, and whether you can optimize your threads to be active less of the time. If you think that your threads should be blocked or sleeping most of the time and still run into abnormally high power numbers, please show me a scope capture of the current measured for analysis.

    As for the hibernate power state, you are correct in that current the Power_shutdown() function requires you to provide a non-zero timeout value, after which the device will be woken from the RTC. Changing the behavior to support an indefinite shutdown time is something in the pipeline in future releases of the SDK.

    Let me know if you have more questions or need more clarification.

    Regards,
    Michael
  • Hey Michael:

    Thanks for responding back and your answers.  I am sorry for the delay in responding back - I have been traveling all this week with very limited internet access. 

    I am using an INA3221 EVM to measure the current, using a series resistor across J19 of the RevA board, which is taking a sample every few seconds.  Understand your points on the issues of not getting low current numbers because of all the stuff I have running.  I think the better approach here would be to start from a minimal project and work my way upwards and analyzing the current along the ways vs using a large project with lots of stuff running and trying to figure out based on what is all running as to what is causing the device to consume too much current.  I will try to do that and get back with you so I can minimize the number of variables that are contributing to the problem. 

    Thanks for your input on the resumeLPDSHookFxn - I will try that out as well.

    As for your comments about using a non-zero timeout value for the Power_shutdown() function,  I understand that this requires you to enter a valid timeout value for this to work properly.   But even if I enter a very large timeout value and try to get it to come out of hibernate, I can't get this work by recognizing a GPIO transition?  Is that the case such that the CC3220 won't come out of hibernate mode prematurely with a GPIO transition that occurs before the timeout value?  Hence the only way it currently works is with a timeout value being entered regardless of any GPIO transitions that may occur before the timeout value expires?  Please advise.

    Thanks,
    Tim

  • Hi Tim,

    You should be able to use the TI drivers power config struct to set a GPIO wakeup source out of hibernate. Which GPIO are you currently trying to use? If the GPIO interrupt on the configured GPIO occurs before the Power_shutdown() timeout then it should wake the device up.

    Regards,
    Michael
  • Hey Michael:

    I am using GPIO13. So if I cause a transition on a GPIO before the timeout in hibernate mode, the CPU should come out and start running again? If so, what is not what I am seeing. Below is the power structure that I am using:

    const PowerCC32XX_ConfigV1 PowerCC32XX_config = {
    .policyInitFxn = &PowerCC32XX_initPolicy,
    .policyFxn = &PowerCC32XX_sleepPolicy,
    .enterLPDSHookFxn = NULL,
    .resumeLPDSHookFxn = NULL,
    .enablePolicy = false,
    .enableGPIOWakeupLPDS = true,
    .enableGPIOWakeupShutdown = true,
    .enableNetworkWakeupLPDS = true,
    .wakeupGPIOSourceLPDS = PRCM_LPDS_GPIO13,
    .wakeupGPIOTypeLPDS = PRCM_LPDS_FALL_EDGE,
    .wakeupGPIOFxnLPDS = gpioButtonFxn1,
    .wakeupGPIOFxnLPDSArg = 3,
    .wakeupGPIOSourceShutdown = 0,
    .wakeupGPIOTypeShutdown = 0,
    .ramRetentionMaskLPDS = PRCM_SRAM_COL_1 | PRCM_SRAM_COL_2 |
    PRCM_SRAM_COL_3 | PRCM_SRAM_COL_4,
    .keepDebugActiveDuringLPDS = false,
    .ioRetentionShutdown = PRCM_IO_RET_GRP_1,
    .pinParkDefs = parkInfo,
    .numPins = sizeof(parkInfo) / sizeof(PowerCC32XX_ParkInfo)
    };

    Does this look ok? Do you see anything I may be doing wrong to test this?

    Thanks,
    Tim
  • Hi Tim,

    You need to have the .wakeupGPIOSourceShutdown variable of that struct be set to PRCM_HIB_GPIO13 in order for you to have GPIO13 be a wakeup source out of hibernate.

    With that change, you should be able to run the power_measurement example, select the hibernate case and then wakeup the CC3220 from hibernate by pressing the appropriate button marked 'P4' on your launchpad.

    Regards,
    Michael
  • Hey Michael:

    Well that's interesting and makes sense, but how did you know that?  I went through both documents on power management that I know of (i.e.,SPRUI18F and SWRA502C) and don't see that addressed?  So this being the case, I can just set the timeout to a very high value and perform a GPIO transition before the timeout and use the value you indicated above for GPIO13 in the power structure and this should take the chip out of hibernate mode prematurely - that's good news.  I will check this out and let you know of my result.

    Thanks,
    Tim

  • Hi Tim,

    I looked at the actual implementation of the power driver functions and how it invoked the low-level driverlib calls for my full understanding of how it implements hibernate on the CC3220 and the need to set that power struct member variable for the GPIO13 wakeup. The struct itself is defined and documented in the PowerCC32XX.h header file, and in the doxygen html docs available at /docs/tidrivers/tidriversAPIs.html of the CC3220 SDK.

    Regards,
    Michael
  • Hey Michael:

    Thanks for getting back with me on this.  Sorry for the delay - had a few things to do before I could get back on this.  I did confirm that this works.  In addition to setting wakeupGPIOSourceShutdown to PRCM_HIB_GPIO13, I also needed to set enableGPIOWakeupShutdown to "true" and wakeupGPIOTypeShutdown to the type of edge for the pushbutton (I.e., PRCM_HIB_RISE_EDGE) and then I was able to get it to work.  It would have been nice if this would have been in the power_measurement example code vs me having to figure this out - that was not trivial, but as you indicated, it does work and no issues now - thanks for your help and follow-up.

    Thanks,
    Tim