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.

How to keep CC3200 kernel clock running during sleep ?

Expert 1570 points
Other Parts Discussed in Thread: SYSBIOS, CC3200

I have an application working on the CC3200 using TI-RTOS, and I want to have the device go to sleep at certain times, waking on a GPIO interrupt, and going back to sleep.  I have the interrupt working so it goes to sleep and wakes as expected, however during the time that it is in sleep mode, the kernel clock stops.  So when I call ti_sysbios_knl_Clock_getTicks() after waking it has lost the time that elapsed while it was in sleep mode.  Is there a way to prevent this from happening?


I tried using both sleep and deep sleep modes and I get the same results.  I'm calling SysTickDisable() and SysTickEnable() before and after PRCMDeepSleepEnter(), but if I don't do this the device doesn't stay in sleep mode.  I understand these calls are disabling/enabling a timer interrupt and I suspect this is why the clock stops also when going to sleep.  I tried some suggestions in this post (e2e.ti.com/.../1357560) to enable the RTC clock but it wouldn't compile.

I would appreciate any help or suggestions on this.

Thanks,

Angelo

  • Hi Angelo,

    Which version of TI-RTOS are you using? What are the compiler errors that you are seeing?

    I checked with our experts on Power Management. You are correct. By default, the Clock module uses SYSTICK timer which will halt when deep sleep mode is entered. The best alternative would be to configure Clock module to use RTC that keeps running during deep sleep mode.

    It can be configured in *.cfg by adding these two statements:

    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    
    Clock.TimerProxy =  xdc.useModule('ti.sysbios.family.arm.cc32xx.Timer');

    This support should be available in TI-RTOS 2.12.01.33 and onwards.

    But note, from docs:

    Some of the RTC timer registers are accessed from the 32KHz clock domain, making reads/writes to these registers on the order of 100 microseconds. If using the RTC timer for the Clock module's tick source, the interrupt latency will be as high as 200 microseconds, as the Clock ISR makes two RTC register accesses on the 32KHz clock domain.

    Hope this helps,

    Vikram

  • Thanks Vikram, this sounds promising.
    I was using 2.01, and the error I was getting was this:

    can't locate the package 'ti.sysbios.family.arm.cc32xx' along the path: 'C:/TI/ccsv6/ccs_base;C:/TI/tirtos_simplelink_2_01_00_03/packages;C:/TI/tirtos_simplelink_2_01_00_03/products/bios_6_40_03_39/packages;C:/TI/tirtos_simplelink_2_01_00_03/products/uia_2_00_01_34/packages;c:/ti/xdctools_3_30_06_67_core/packages;..;'. Ensure that the package path is set correctly. .xdchelp /ti_rtos_config line 185 C/C++ Problem

    I went to the App Center and updated TI-RTOS to 2.13, but I continue to get the same error. I tried switching to the new version, but apparently there is some setting somewhere I'm missing because the path continues to show tirtos_simplelink_2_01_00_03.

    Angelo
  • Select your project and navigate Project > Properties > General > RTSC. Under the RTSC tab, select the correct TI-RTOS for SimpleLink Wireless MCUs.

    Vikram
  • I had tried that, but the error didn't change.

  • The build files may still be pointing to the older version. Can you clean the project and then build? 

    Vikram

  • Right, I should have thought of that. I also needed to restart CCS for some reason, but that did allow me to finally compile without errors.

    However now the device doesn't stay in LP mode. It immediately wakes after calling the PRCMDeepSleepEnter() call. This is the same thing it did when I didn't have the SysTickDisable() and SysTickEnable() calls before and after entering sleep, except I do have them there now. To be sure I only changed the line for the Clock.TimerProxy back to 'ti.sysbios.family.arm.m3.Timer' and the device stays asleep.

    Are there any other changes I need to make for this? The cfg file also has a Timer.TimerProxy which is still set to xdc.useModule('ti.sysbios.family.arm.m3.Timer'). Should that one be changed to '...arm.cc32xx...' also?
  • Hi AQ,

    I am not an expert on Power Management. The only other configuration that I know is for Timestamp:

    Timestamp = xdc.useModule('xdc.runtime.Timestamp');
    Timestamp.SupportProxy = xdc.useModule('ti.sysbios.family.arm.cc32xx.TimestampProvider');

    Have you checked the "sprui18.pdf" in TI-RTOS docs? It has documentation for "TI-RTOS Power Management for CC3200 SimpleLink Wireless MCUs and MSP432".

    Meanwhile, let me check with Power Management experts about the issue you are encountering.

    Vikram

  • Hi Vikram, I'm still trying to understand the PDF and make this work but not having any further success. I was wondering if you found out anything from the power management team.

    Thanks,
    Angelo
  • Hi Angelo,

    I checked with our power management experts. I think you probably should change the Timer.TimerProxy to ti.sysbios.family.arm.cc32xx.Timer instead of M3 timer.

    A few questions for you:

    Can you also post your .cfg if possible? We can take a closer look to see what may be causing the issue.

    Are there any other interrupts that may wake up the device? Can you tell us from where are you invoking PRCMDeepSleepEnter() in your code?

    Also, how are you checking if the device is in sleep or not?

    Thanks,
    Vikram
  • Thanks Vikram,

    When you say I should change Timer.TimerProxy, do you mean in addition to changing Clock.TimerProxy, or instead of that?

    I attached the cfg file.  I don't believe there are any other interrupts enabled.  I have enabled a pin interrupt which is triggered by an external device (accelerometer) periodically.  I called something like this in one of my tasks:

    while (1) {
    		UART_PRINT("sleep\n");
    		MAP_UtilsDelay(80000);
    
    		SysTickDisable();
    //		PRCMSleepEnter();
    		PRCMDeepSleepEnter();
    		SysTickEnable();
    
    		UART_PRINT("wake\n");
    		UART_PRINT("%ld\n", ti_sysbios_knl_Clock_getTicks()); 
    }

    When I use the original Clock.TimerProxy setting (M3), the device goes to sleep, then about a second later the external pin interrupt is generated and the device wakes up. The clock time is reported to the console, and it goes to sleep again. I can see from the time values reported that during sleep the clock is not running (only several milliseconds elapse).

    When I change to the CC32xx TimerProxy setting, the same code continuously reports sleep...wake...sleep...wake...etc. without waiting for the pin interrupt.

    I hope that answers all your questions. Let me know if you have any other questions about this.

    Thanks,

    Angelo

    4276.CloudBurst.cfg

  • Hi Angelo,

    Thanks for sharing your cfg file. It looks like you are using Clock, Timer and Timestamp modules in your application. The TimerProxy/SupportProxy of all these modules have to use cc32xx configuration that I have mentioned in my previous posts.

    I believe TI-RTOS power management is supported for CC3200. It internally takes care of the putting the device in sleep mode when the device is Idle. So instead of  directly invoking  the CC300 driverlib APIs SysTickDisable()/ SysTickEnable() and PRCMDeepSleepEnter() which may cause conflict with the TI-RTOS setup, please use TI-RTOS Power Management APIs. Please have a look at the  "sprui18.pdf" - TI-RTOS Power Management for CC3200 SimpleLink Wireless MCUs and MSP432.  

    Also, TI-RTOS provides out of box examples for Power Management. Please read the TI-RTOS Getting Started Guide for the list of examples. I found an example "UART Power" which I believe is similar to your use case - it periodically wakes up and prints to the UART console.

    Hope this helps,

    Vikram

  • Thank you Vikram, this is helpful.

    As it turns out the issue I had before where it kept waking up was because I had another task running with a Task_Sleep() call and that was apparently setting an interrupt that woke it up. So with that task disabled the device stays asleep (even if I only have the clock.timerproxy set to the cc32x, and not all three (clock.timerproxy, timestamp.supportproxy, and timer.timerproxy).

    But I noticed a problem ... after it wakes up again I found that if I call a function that includes this line it hangs:
    time_t t_of_day = time(NULL);

    The declaration for time() is:
    _CODE_ACCESS time_t time(time_t *_timer);

    If I remove this, so far it works fine. Any ideas why this?

    In the meantime I looked briefly through the UART power example you mentioned and I'll look into that further. I'm a little concerned about this significantly increasing the code size though.
  • Hi Angelo,

    By default, the time() is pulled from the C Std runtime. I don't know how it works. But TI-RTOS has an implementation of time() module which can be configured. Can you add the following line to your .cfg?

    var Seconds = xdc.useModule('ti.sysbios.hal.Seconds');

    You don't need to change anything else in your code.

    Regarding using TI-RTOS power management framework, I don't know the code size details but I would definitely recommend you using it as it optimized for TI-RTOS.

    Vikram