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.

TM4C129X and Deep Sleep APIs

I am trying to minimize the deep sleep current of the TM4C129X microcontroller. Before I start digging into hardware too much I want to verify that the micro is in the proper deep sleep low current state. Here is how the sleep parameters are setup:

   // set the deep sleep clock source: use the low-frequency internal osc with
   // a div/64, disable the MOSC and internal oscillator in deep sleep.
   SysCtlDeepSleepClockConfigSet( SYSCTL_DSLP_DIV_64,
                                ( SYSCTL_DSLP_OSC_INT30 | SYSCTL_DSLP_PIOSC_PD |
                                  SYSCTL_DSLP_MOSC_PD ) );
   // set the SRAM and flash to low power modes during sleep
   SysCtlDeepSleepPowerSet( SYSCTL_FLASH_LOW_POWER | SYSCTL_SRAM_LOW_POWER |
                            SYSCTL_LDO_SLEEP | SYSCTL_TEMP_LOW_POWER );
   
   // Set LDO Voltage to 0.9V
   SysCtlLDODeepSleepSet( SYSCTL_LDO_0_90V );

   // use clock gating for peripherals during sleep
   SysCtlPeripheralClockGating( true );

   // disable most peripherals during deep sleep - these are peripherals which
   // have been previously enabled at startup. Leave GPIOD enabled, since we
   // want to wake on a button press
   SysCtlPeripheralDeepSleepDisable( SYSCTL_PERIPH_ADC0   | SYSCTL_PERIPH_ADC1      |
                                    SYSCTL_PERIPH_CAN0    | SYSCTL_PERIPH_CAN1      | 
                                    SYSCTL_PERIPH_CCM0    | SYSCTL_PERIPH_COMP0     | 
                                    SYSCTL_PERIPH_EEPROM0 | SYSCTL_PERIPH_EMAC0     |
                                    SYSCTL_PERIPH_EPHY0   | SYSCTL_PERIPH_EPI0      | 
                                    SYSCTL_PERIPH_GPIOA   | SYSCTL_PERIPH_GPIOB     | 
                                    SYSCTL_PERIPH_GPIOC   | SYSCTL_PERIPH_GPIOE     | 
                                    SYSCTL_PERIPH_GPIOF   | SYSCTL_PERIPH_GPIOG     |
                                    SYSCTL_PERIPH_GPIOH   | SYSCTL_PERIPH_GPIOJ     |  
                                    SYSCTL_PERIPH_GPIOK   | SYSCTL_PERIPH_GPIOL     | 
                                    SYSCTL_PERIPH_GPIOM   | SYSCTL_PERIPH_GPION     |
                                    SYSCTL_PERIPH_GPIOP   | SYSCTL_PERIPH_GPIOQ     | 
                                    SYSCTL_PERIPH_GPIOR   | SYSCTL_PERIPH_GPIOS     | 
                                    SYSCTL_PERIPH_GPIOT   | SYSCTL_PERIPH_HIBERNATE |
                                    SYSCTL_PERIPH_I2C0    | SYSCTL_PERIPH_I2C1      |   
                                    SYSCTL_PERIPH_I2C2    | SYSCTL_PERIPH_I2C3      | 
                                    SYSCTL_PERIPH_I2C4    | SYSCTL_PERIPH_I2C5      |
                                    SYSCTL_PERIPH_I2C6    | SYSCTL_PERIPH_I2C7      | 
                                    SYSCTL_PERIPH_I2C8    | SYSCTL_PERIPH_I2C9      | 
                                    SYSCTL_PERIPH_LCD0    | SYSCTL_PERIPH_ONEWIRE0  |
                                    SYSCTL_PERIPH_PWM0    | SYSCTL_PERIPH_PWM1      | 
                                    SYSCTL_PERIPH_QEI0    | SYSCTL_PERIPH_QEI1      | 
                                    SYSCTL_PERIPH_SSI0    | SYSCTL_PERIPH_SSI1      |
                                    SYSCTL_PERIPH_SSI2    | SYSCTL_PERIPH_SSI3      | 
                                    SYSCTL_PERIPH_TIMER0  | SYSCTL_PERIPH_TIMER1    |   
                                    SYSCTL_PERIPH_TIMER2  | SYSCTL_PERIPH_TIMER3    |
                                    SYSCTL_PERIPH_TIMER4  | SYSCTL_PERIPH_TIMER5    | 
                                    SYSCTL_PERIPH_TIMER6  | SYSCTL_PERIPH_TIMER7    | 
                                    SYSCTL_PERIPH_UART0   | SYSCTL_PERIPH_UART1     |
                                    SYSCTL_PERIPH_UART2   | SYSCTL_PERIPH_UART3     |   
                                    SYSCTL_PERIPH_UART4   | SYSCTL_PERIPH_UART5     | 
                                    SYSCTL_PERIPH_UART6   | SYSCTL_PERIPH_UART7     |
                                    SYSCTL_PERIPH_UDMA    | SYSCTL_PERIPH_USB0      | 
                                    SYSCTL_PERIPH_WDOG0   | SYSCTL_PERIPH_WDOG1     | 
                                    SYSCTL_PERIPH_WTIMER0 | SYSCTL_PERIPH_WTIMER1   |
                                    SYSCTL_PERIPH_WTIMER2 | SYSCTL_PERIPH_WTIMER3   |
                                    SYSCTL_PERIPH_WTIMER4 | SYSCTL_PERIPH_WTIMER5 );
   
   // explicitly set GPIOD to enabled during deep-sleep
   SysCtlPeripheralDeepSleepEnable( SYSCTL_PERIPH_GPIOD );

In the datasheet for the TM4C129XNZCAD in the Current Consumption Table (Page 2183-2185) Note E states "To achieve the lowest possible Deep-Sleep current, one or more wait states must be configured in the MEMTIM0 register. If there are no wait states applied in Run mode, then lowest possible Deep-Sleep current is not achieved."

My question is...do the TivaWare Peripheral Driver APIs configure MEMTIM0 register in order to get the lowest possible current or do I need to modify that? As I have it configured should the micro be in the lowest deep sleep state?

  • Brayden,

    I have moved this thread over to the device forum in hopes that you will get a faster response there.

  • Hello Brayden,

    No, the TivaWare does not configure the MEMTIM0 unless the SysCtlClockFreqSet is called with a system frequency >16MHz. Only then does the Wait State gets configured in MEMTIM0.

    In the case you have mentioned if the System Clock is >16MHz then it would be taken care of.

    Regards

    Amit

  • I have the clock configured like this on startup: SysCtlClockFreqSet( ( SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480 ), SYSTEM_CLOCK_FREQ ); SYSTEM_CLOCK_FREQ is set to 120MHz.

    In this case, I would need to configure the MEMTIM0 to achieve the lowest possible sleep current? I'm trying to get to the sleep current highlighted in the image below.

  • Hello Brayden,

    No in this case you would not need to configure the MEMTIM0 as the SysCtlClockFreqSet would already have done that for you

    Regards

    Amit

  • Thank you Amit. I will start digging into the hardware and see where the excess current draw is coming from.

  • Hello Brayden,

    What is the current you are measuring?

    Regards

    Amit

  • My entire circuit during sleep is down to ~6mA. I need to make some hardware modifications so that I can figure out exactly what the microcontroller is using by itself. I did notice that the current was fluctuating 2mA and could sometimes take a while to drop down and settle at 6mA. There is a lot going on in the circuit so there are many paths for current to leak. I'll work on getting the current measurement for the micro only and update with results.

  • Hello Brayden

    Was the debugger disconnected before the run to deep sleep was made?

    A simple method would be to power cycle the setup with the debugger physically disconnected and then a current measurement made.

    Regards

    Amit

  • Amit,

    I am taking all the measurements with the debugger disconnected. 

    Isolating the 3.3V rail to the micro I was able to measure a current of 5.7mA into the micro with an overall system current of 6.2mA. It seems the micro is not going to deep sleep. Is there anything else I am missing in software in order to get the processor into deep sleep or is this looking like a hardware issue?

    -Brayden

  • Hello Brayden,

    Can you check if the VDDC Pin is dropping to 0.9V. That will tell us if the device is in deep sleep or not

    Regards

    Amit

  • Yes, the VDDC pin is dropping down to 0.9V. The current definitely drops when the sleep command is executed (~65mA down to the 5.8mA), just not enough.

  • Hello Brayden,

    If it is 0.9V then the deep sleep has been entered. What may be happening is there is some pin sourcing current to an external device or the VDD supply to a pull up is connected to 0V causing a current drain.

    Regards

    Amit

  • Amit,

    I tried moving back to the TM4C129X Development Kit to work on the sleep current. Using the above code I see 0.009V across J14, or 9mA of current while in deep sleep. What can I do to get the micro sleep current on the dev kit down to microamps that the datasheet is claiming?

    -Brayden

  • Hello Brayden,

    Correct me if I am wrong. There is no external component connected on the DK-TM4C129 when you did the measurements?

    Also can you share any changes that you did to the DK-TM4C129 to do the current measurements and the exact settings for all the deep sleep registers including clock gating?

    Regards

    Amit

  • Nope, no external components connected. I also tried removing the debugger and powering the 3.3V from an external power supply. 

    I haven't made any changes to the dev kit, except for removing most of the I/O jumpers. I am using the following code:

    // set the deep sleep clock source: use the low-frequency internal osc with
          // a div/64, disable the MOSC and internal oscillator in deep sleep.
          SysCtlDeepSleepClockConfigSet( SYSCTL_DSLP_DIV_64,
                                       ( SYSCTL_DSLP_OSC_INT30 | SYSCTL_DSLP_PIOSC_PD |
                                         SYSCTL_DSLP_MOSC_PD ) );
          // set the SRAM and flash to low power modes during sleep
          SysCtlDeepSleepPowerSet( SYSCTL_FLASH_LOW_POWER | SYSCTL_SRAM_LOW_POWER |
                                   SYSCTL_LDO_SLEEP | SYSCTL_TEMP_LOW_POWER );
          
          // Set LDO Voltage to 0.9V
          SysCtlLDODeepSleepSet( SYSCTL_LDO_0_90V );
    
          // use clock gating for peripherals during sleep
          SysCtlPeripheralClockGating( true );
    
          // disable most peripherals during deep sleep - these are peripherals which
          // have been previously enabled at startup. Leave GPIOD enabled, since we
          // want to wake on a button press
          SysCtlPeripheralDeepSleepDisable( SYSCTL_PERIPH_ADC0   | SYSCTL_PERIPH_ADC1      |
                                           SYSCTL_PERIPH_CAN0    | SYSCTL_PERIPH_CAN1      | 
                                           SYSCTL_PERIPH_CCM0    | SYSCTL_PERIPH_COMP0     | 
                                           SYSCTL_PERIPH_EEPROM0 | SYSCTL_PERIPH_EMAC0     |
                                           SYSCTL_PERIPH_EPHY0   | SYSCTL_PERIPH_EPI0      | 
                                           SYSCTL_PERIPH_GPIOA   | SYSCTL_PERIPH_GPIOB     | 
                                           SYSCTL_PERIPH_GPIOC   | SYSCTL_PERIPH_GPIOE     | 
                                           SYSCTL_PERIPH_GPIOF   | SYSCTL_PERIPH_GPIOG     |
                                           SYSCTL_PERIPH_GPIOH   | SYSCTL_PERIPH_GPIOJ     |  
                                           SYSCTL_PERIPH_GPIOK   | SYSCTL_PERIPH_GPIOL     | 
                                           SYSCTL_PERIPH_GPIOM   | SYSCTL_PERIPH_GPION     |
                                           SYSCTL_PERIPH_GPIOP   | SYSCTL_PERIPH_GPIOQ     | 
                                           SYSCTL_PERIPH_GPIOR   | SYSCTL_PERIPH_GPIOS     | 
                                           SYSCTL_PERIPH_GPIOT   | SYSCTL_PERIPH_HIBERNATE |
                                           SYSCTL_PERIPH_I2C0    | SYSCTL_PERIPH_I2C1      |   
                                           SYSCTL_PERIPH_I2C2    | SYSCTL_PERIPH_I2C3      | 
                                           SYSCTL_PERIPH_I2C4    | SYSCTL_PERIPH_I2C5      |
                                           SYSCTL_PERIPH_I2C6    | SYSCTL_PERIPH_I2C7      | 
                                           SYSCTL_PERIPH_I2C8    | SYSCTL_PERIPH_I2C9      | 
                                           SYSCTL_PERIPH_LCD0    | SYSCTL_PERIPH_ONEWIRE0  |
                                           SYSCTL_PERIPH_PWM0    | SYSCTL_PERIPH_PWM1      | 
                                           SYSCTL_PERIPH_QEI0    | SYSCTL_PERIPH_QEI1      | 
                                           SYSCTL_PERIPH_SSI0    | SYSCTL_PERIPH_SSI1      |
                                           SYSCTL_PERIPH_SSI2    | SYSCTL_PERIPH_SSI3      | 
                                           SYSCTL_PERIPH_TIMER0  | SYSCTL_PERIPH_TIMER1    |   
                                           SYSCTL_PERIPH_TIMER2  | SYSCTL_PERIPH_TIMER3    |
                                           SYSCTL_PERIPH_TIMER4  | SYSCTL_PERIPH_TIMER5    | 
                                           SYSCTL_PERIPH_TIMER6  | SYSCTL_PERIPH_TIMER7    | 
                                           SYSCTL_PERIPH_UART0   | SYSCTL_PERIPH_UART1     |
                                           SYSCTL_PERIPH_UART2   | SYSCTL_PERIPH_UART3     |   
                                           SYSCTL_PERIPH_UART4   | SYSCTL_PERIPH_UART5     | 
                                           SYSCTL_PERIPH_UART6   | SYSCTL_PERIPH_UART7     |
                                           SYSCTL_PERIPH_UDMA    | SYSCTL_PERIPH_USB0      | 
                                           SYSCTL_PERIPH_WDOG0   | SYSCTL_PERIPH_WDOG1     | 
                                           SYSCTL_PERIPH_WTIMER0 | SYSCTL_PERIPH_WTIMER1   |
                                           SYSCTL_PERIPH_WTIMER2 | SYSCTL_PERIPH_WTIMER3   |
                                           SYSCTL_PERIPH_WTIMER4 | SYSCTL_PERIPH_WTIMER5 );
          
          // explicitly set GPIOD to enabled during deep-sleep
          SysCtlPeripheralDeepSleepEnable( SYSCTL_PERIPH_GPIOD );
          
          GPIO_write( CELL_REGULATOR_PWR_SAVE_PIN, Board_PIN_OFF );
          
          // disable routing of interrupts to CPU - this avoids hard bus faults when
          // waking
          IntMasterDisable();
          
          // debug print may be printing - turn that interrupt off
          UARTIntDisable( UART0_BASE, UART_INT_TX );
          UARTIntClear( UART0_BASE, UART_INT_TX );
          
          // turn off ints used by the system, and others that may be pending,
          // and clear pending ints.
          TimerIntDisable( TIMER0_BASE, TIMER_TIMA_TIMEOUT );
          IntPendClear( INT_TIMER0A );
          IntPendClear( INT_UART0 );
          
          while( wakeFromGPIOD == false )
          {
             SysCtlDeepSleep();
             pendingInts = HWREG( NVIC_PEND0 );
             if( pendingInts & ( 1 << 3 ) )
             {
                wakeFromGPIOD = true;
             }
          }
          
          wakeFromGPIOD = false;

  • Hello Brayden,

    The use if DIV in SysCtlDeepSleepClockConfigSet is the direct divisor value. By using the same as you have the current on a DK-TM4C129 went up to 2.3mA in Deep Sleep with LDO voltage at 0.9V. I changed it to 63 instead of SYSCTL_DSPL_DIV_64 and it came down to 1mA.

    Also I have a CCS project that I have used to baseline boards and devices. It could be useful for you as I measured 1mA on my board

    http://e2e.ti.com/cfs-file.ashx/__key/communityserver-discussions-components-files/908/1817.TM4C129_5F00_DeepSleep.7z

    Regards

    Amit

  • Amit,

    I am having trouble getting the project to build. I have not really used CCS before. Seems I am having an issue with the includes. I have the directories for the includes with the files showing errors, but I am still getting:

    Description Resource Path Location Type
    #1965 cannot open source file "inc/hw_ints.h" uartstdio.c /TM4C129_DeepSleep line 28 C/C++ Problem

    Description Resource Path Location Type
    #1965 cannot open source file "inc/hw_memmap.h" TM4C129_DeepSleep.c /TM4C129_DeepSleep line 43 C/C++ Problem

    Description Resource Path Location Type
    #1965 cannot open source file "inc/hw_nvic.h" startup_ccs.c /TM4C129_DeepSleep line 26 C/C++ Problem

    How do I get the project to search my c:/ti directory with all the rtos files? I followed the steps here: http://www.ti.com/lit/ug/spruhd3g/spruhd3g.pdf

  • Hello Brayden,

    The include file option during compilation must point to the TivaWare installation on your PC. In my case I have it installed C:\ti as C:\ti\TivaWare_C_Series-2.1.0.12573

    So that is what I add to the --include option in CCS.

    Regards

    Amit

  • Amit,

    Thank you for the help and prompt answers thus far. I was able to get the code to compile, just had to get my include directories setup properly.

    Using the dev kit I was able to see ~1mA of current across J14 with your CCS project. I realized that this is not using the TI-RTOS. I copied your code and placed it into my main function before BIOS_start()  and am now seeing ~3.5mA across J14. 

    What do I need to do when in the TI-RTOS to minimize the deep sleep current? Do I need to turn off hw interrupts?

    It is also interesting why I am not seeing the ~1mA when compiling and running the code in IAR vs. CCS. Could this be a clock speed issue?

    -Brayden

  • Hello Brayden,

    OK, now that is a relief that you have the same result as mine. Indeed, It would be worthwhile to check before the SysCtlDeepSleep if any of the settings in SysCtl Module are being updated by the RTOS.

    The raw code should yield the same result irrespective of the IDE.

    Regards

    Amit