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 get MSP432 to the lowest power state in LPM3.5

Other Parts Discussed in Thread: ENERGYTRACE

Hi,

I have been running the low power mode examples on our EVM board, but so far, we have not gotten the current to be lower than around 8.5 uA in LPM3.5 with RTC on. Do we need to do anything else, maybe hw wise to make it go lower?

Thanks,

Dan

  • Hi Dan,

    How are you measuring the current consumption? If you happen to be using a multimeter, I'd recommend using our EnergyTrace+ Technology in CCS instead. EnergyTrace+ Technology allows the user to see energy consumed as the application progresses. More details about this can be found in Section 2.3.5 of the LaunchPad's User's Guide.

    Also, please follow the guidelines in Section 2.5 for achieving the most accurate current measurement.

    Regards,

    James

    MSP Customer Applications

  • Dan,

    Are you running RTC with LF? Or are you running RTC with REFO? Can you share some of your code where you set up the RTC and send it to LPM3.5? Also, just to double check, you are using Rev C silicon correct?
  • Hi again Dan,

    Take a look at the Designing an Ultra-Low-Power (ULP) Application With MSP432™ Microcontrollers app note below. It features several power optimization strategies and should be helpful for your design.

    Regards,

    James

    MSP Customer Applications

  • Dan,

    Attached is the ZIP file that contains the latest LPM3.5 code example which has been validated against Rev C silicon. The update examples will be on the web this week.

    Regards,

    William

    msp432p401x_rtc_lpm35_01.zip

  • Will,
    Tried the software you sent and the average current was higher at 8.7uA.

    Earlier this week, we used the EnergyTrace feature of CCS and measured about 1.5 mA average current while in LPM3.5 low power mode. Obviously, the EnergyTrace feature is not giving us accurate values.

    Not using CCS, but with the USB connected to provide power, we measured an average current of 5.8 uA while in LPM 3.5. This was with all jumpers from the USB board side to the processor side of the board disconnected, except the 3..3V and GND jumpers. The value of 5.8 uA is still high.

    Is there any information or help you can provide to allow us to get accurate current consumption values? Perhaps there is a specific setup or procedure required. At this point the value we are getting at 5.8 uA is too high and does not meet our requirements.
    Thanks,
    Dan
  • Dan Wieland said:
    Earlier this week, we used the EnergyTrace feature of CCS and measured about 1.5 mA average current while in LPM3.5 low power mode. Obviously, the EnergyTrace feature is not giving us accurate values.

    Let's step back and understand how this code example (shared above by Will) works. The RTC is configured with the original time (11:59:45 am on Friday October 7, 2016) and an alarm is set for the next minute. Then, the MSP432 enters LPM3.5 mode until being woken up by the alarm event, which puts the device into Active mode. For me, EnergyTrace correctly showed that the MSP432 was in LPM3.5 mode for around 15 seconds before shifting to Active mode.

    NOTE: As pointed out in the code example comments, using JTAG will put the CPU in LPM0 mode and prevent it from entering LPM3.5 mode. I'll discuss how this can be prevented later.

    Dan Wieland said:
    Not using CCS, but with the USB connected to provide power, we measured an average current of 5.8 uA while in LPM 3.5. This was with all jumpers from the USB board side to the processor side of the board disconnected, except the 3..3V and GND jumpers. The value of 5.8 uA is still high.

    Is there any information or help you can provide to allow us to get accurate current consumption values? Perhaps there is a specific setup or procedure required. At this point the value we are getting at 5.8 uA is too high and does not meet our requirements.

    As I mentioned before, I'd strongly recommend using EnergyTrace in CCS to accurately measure the current consumption. Even at 5.8 uA, EnergyTrace is accurately measuring the current consumption - it's essentially measuring the current flow through a resistor and calculating/plotting the energy consumption versus time. If the code is not entering LPM3.5 mode correctly, this level of current consumption is not surprising.

    To highlight the low power consumption achieved in LPM3.5 mode, I've modified the code example above to wait for nearly an hour before the alarm is triggered.

    Here's my process for changing the code and measuring the current consumption:

    • Changed the RTC interval from a minute to an hour alarm event interrupt (RTC_C_CTL13_TEV_0 to RTC_C_CTL13_TEV_1 for RTC_C->CTL13)
    • Set the original time from 11:59:45 am to 11:01:45 am instead (0x59 to 0x01 for RTC_C->TIM0)
    • Populated GND, 3.3V, RST, TMS, TCK, TDO, TDI jumpers on LaunchPad
    • Programmed the device, then halted debug session
    • Unplugged LaunchPad, removed all jumpers except GND and 3.3V jumpers (prevents JTAG from preventing LPM3.5 mode)
    • Plugged the LaunchPad back into my PC
    • In CCS, launched and started EnergyTrace standalone (without debugging!)

    Here's some screenshots showing an average of 0.9 uA (or 900 nA) current consumption over 248 seconds.

    For your reference, here's the modified code.

    /* --COPYRIGHT--,BSD_EX
     * Copyright (c) 2013, 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.
     *
     *******************************************************************************
     *
     *                       MSP432 CODE EXAMPLE DISCLAIMER
     *
     * MSP432 code examples are self-contained low-level programs that typically
     * demonstrate a single peripheral function or device feature in a highly
     * concise manner. For this the code may rely on the device's power-on default
     * register values and settings such as the clock configuration and care must
     * be taken when combining code from several examples to avoid potential side
     * effects. Also see www.ti.com/.../mspdriverlib for an API functional
     * library & https://dev.ti.com/pinmux/ for a GUI approach to peripheral configuration.
     *
     * --/COPYRIGHT--*/
    //******************************************************************************
    //   MSP432P401 Demo - RTC, LPM3.5, & alarm
    //
    //   Description: The RTC module is used to set the time, start RTC operation,
    //   and read the time from the respective RTC registers. Software will set the
    //   original time to 11:01:45 am on Friday October 7, 2016. Then the RTC will
    //   be activated through software, and an alarm will be created for the next
    //   hour (12:00:00 pm). The device will then enter LPM3.5 awaiting
    //   the event interrupt. Upon being woken up by the event, the LED on the board
    //   will be set.
    //
    //   NOTE: To ensure that LPM3.5 is entered properly, you would need to exit
    //         debug mode first and use an external power supply.
    //
    //  //* An external watch crystal on XIN XOUT is required for ACLK *//
    //   ACLK = 32.768kHz, MCLK = SMCLK = default DCO~3MHz
    //
    //                MSP432P401x
    //
    //             -----------------
    //         /|\|              XIN|-
    //          | |                 | 32kHz
    //          --|RST          XOUT|-
    //            |                 |
    //            |             P1.0|--> LED
    //
    //   William Goh
    //   Texas Instruments Inc.
    //   June 2016 (updated) | November 2013 (created)
    //   Built with CCSv6.1, IAR, Keil, GCC
    //******************************************************************************
    #include "msp.h"
    
    void boardInit(void);
    void rtcInit(void);
    void enterLpm35(void);
    void wakeUpLPM35(void);
    
    int main(void)
    {
        volatile unsigned int i;
    
        WDT_A->CTL = WDT_A_CTL_PW |             // Stop WDT
                WDT_A_CTL_HOLD;
    
        // Check if the MCU is waking-up from LPM3.5
        if (RSTCTL->PCMRESET_STAT & RSTCTL_PCMRESET_STAT_LPM35)
        {
            wakeUpLPM35();
        }
        else
        {
            // Else it is a cold-start
    
            // Initialize GPIO and clocks
            boardInit();
    
            // Initialize RTC
            rtcInit();
    
            // Wake up on exit from ISR
            SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk;
    
            // Turn off PSS high-side & low-side supervisors
            PSS->KEY = PSS_KEY_KEY_VAL;
            PSS->CTL0 |= PSS_CTL0_SVSMHOFF;
            PSS->KEY = 0;
    
            // Enter LPM3.5
            enterLpm35();
        }
    
        // Code should NOT get here. This means that LPM3.5 was not properly entered.
        // Ensure that an external power supply was ued. Or else JTAG will put the CPU
        // in LPM0 mode.
    
        // Stop the RTC
        RTC_C->CTL0 = RTCKEY_VAL;               // Unlock RTC_C module
        RTC_C->CTL13 |= RTC_C_CTL13_HOLD;       // RTC hold
        RTC_C->CTL0 &= ~(RTC_C_CTL0_KEY_MASK);  // Lock RTC_C module
    
        // Blink LED slowly if LPM3.5 not entered properly
        while(1)
        {
            P1->OUT ^= BIT0;                    // XOR P1.0
            for (i = 500000; i > 0; i--);       // Delay
        }
    }
    
    void wakeUpLPM35(void)
    {
        // Re-initialize the GPIO and system clocks
        boardInit();
    
        // Configure RTC_C but ensure the IFG flag is not cleared
        RTC_C->CTL0 = (RTC_C->CTL0 & ~(RTC_C_CTL0_KEY_MASK)) |
                RTCKEY_VAL |                    // Unlock RTC key protected registers
                RTC_C_CTL0_TEVIE;               // Enable RTC time event interrupt
        RTC_C->CTL13 |= RTC_C_CTL13_BCD |       // BCD mode
                RTC_C_CTL13_TEV_1 |             // Set RTCTEV for 1 hour alarm event interrupt
                RTC_C_CTL13_HOLD;               // RTC hold
    
        RTC_C->CTL13 &= ~(RTC_C_CTL13_HOLD);    // Start RTC calendar mode
        RTC_C->CTL0 &= ~(RTC_C_CTL0_KEY_MASK);  // Lock the RTC registers
    
        // Clear LPM lock
        PCM->CTL1 = PCM_CTL1_KEY_VAL;
    
        // Re-enable the interrupt
        __enable_irq();
    
        NVIC->ISER[0] = 1 << ((RTC_C_IRQn) & 31);
    }
    
    void rtcInit(void)
    {
        // Configure RTC_C
        RTC_C->CTL0 = RTCKEY_VAL|               // Unlock RTC key protected registers
                RTC_C_CTL0_TEVIE;               // Enable RTC time event interrupt
        RTC_C->CTL13 |= RTC_C_CTL13_BCD |       // BCD mode
                RTC_C_CTL13_TEV_1 |             // Set RTCTEV for 1 hour alarm event interrupt
                RTC_C_CTL13_HOLD;               // RTC hold
    
        RTC_C->YEAR = 0x2016;                   // Year = 0x2016
        RTC_C->DATE = (0x10 << RTC_C_DATE_MON_OFS) | // Month = 0x10 = October
                (0x07 | RTC_C_DATE_DAY_OFS);    // Day = 0x07 = 7th
        RTC_C->TIM1 = (0x05 << RTC_C_TIM1_DOW_OFS) | // Day of week = 0x05 = Friday
                (0x11 << RTC_C_TIM1_HOUR_OFS);  // Hour = 0x11
        RTC_C->TIM0 = (0x01 << RTC_C_TIM0_MIN_OFS) | // Minute = 0x01
                (0x45 << RTC_C_TIM0_SEC_OFS);   // Seconds = 0x45
    
        RTC_C->CTL13 &= ~(RTC_C_CTL13_HOLD);    // Start RTC calendar mode
        RTC_C->CTL0 &= ~(RTC_C_CTL0_KEY_MASK);  // Lock the RTC registers
    
        // Enable global interrupt
        __enable_irq();
    
        NVIC->ISER[0] = 1 << ((RTC_C_IRQn) & 31);
    }
    
    void boardInit(void)
    {
        // GPIO Port Configuration for lowest power configuration
        P1->OUT = 0x00; P1->DIR = 0xFF;
        P2->OUT = 0x00; P2->DIR = 0xFF;
        P3->OUT = 0x00; P3->DIR = 0xFF;
        P4->OUT = 0x00; P4->DIR = 0xFF;
        P5->OUT = 0x00; P5->DIR = 0xFF;
        P6->OUT = 0x00; P6->DIR = 0xFF;
        P7->OUT = 0x00; P7->DIR = 0xFF;
        P8->OUT = 0x00; P8->DIR = 0xFF;
        P9->OUT = 0x00; P9->DIR = 0xFF;
        P10->OUT = 0x00; P10->DIR = 0xFF;
        PJ->OUT = 0x00; PJ->DIR = 0xFF;
    
        // Initialize LFXT1
        PJ->SEL0 |= BIT0 | BIT1;                // Select for LFXT ports
        CS->KEY = CS_KEY_VAL;                   // Unlock CS module for register access
        CS->CTL2 |= CS_CTL2_LFXT_EN;            // LFXT on
    
        // Loop until XT1, XT2 & DCO fault flag is cleared
        do
        {
           // Clear XT2,XT1,DCO fault flags
           CS->CLRIFG |= CS_CLRIFG_CLR_DCOR_OPNIFG | CS_CLRIFG_CLR_HFXTIFG |
                   CS_CLRIFG_CLR_LFXTIFG | CS_CLRIFG_CLR_FCNTLFIFG;
           SYSCTL->NMI_CTLSTAT &= ~ SYSCTL_NMI_CTLSTAT_CS_SRC;
        } while ((SYSCTL->NMI_CTLSTAT | SYSCTL_NMI_CTLSTAT_CS_FLG)
                && (CS->IFG & CS_IFG_LFXTIFG)); // Test oscillator fault flag
    
        // Select ACLK as LFXTCLK
        CS->CTL1 &= ~(CS_CTL1_SELA_MASK) | CS_CTL1_SELA_0;
        CS->KEY = 0;                            // Lock CS module from unintended accesses
    }
    
    void enterLpm35(void)
    {
        // Set the Power Mode 3.5
        PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_LPMR__LPM35;
    
        // Setting the sleep deep bit
        SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk);
    
        __sleep();
        __no_operation();                       // For debugger
    }
    
    void RTC_C_IRQHandler(void)
    {
        volatile unsigned int i;
    
        if (RTC_C->CTL0 & RTC_C_CTL0_TEVIFG)
        {
            // If woken up at noon, set LED and stay loop there
            if((RTCHOUR == 0x12)&&(RTCMIN == 0x00)&&(RTCSEC == 0x00))
            {
                P1->OUT |= BIT0;                // Set P1.0 on
                while(1);
            }
            // If values do not match, blink LED fast
            else
            {
                while(1)                        // continuous loop
                {
                    P1->OUT ^= BIT0;            // XOR P1.0
                    for (i = 20000; i > 0; i--);// Delay
                }
            }
        }
    }
    

    Regards,

    James

    MSP Customer Applications

  • I'm having difficulties getting anywhere near the low current levels shown above. Here's what I did to try and re-create your setup:

    1. Used MSP432 Launchpad Dev Board Rev 1.0 (Black Board, Rev B Chip. I don't have a red Dev Board, but I can swap out the IC with a Rev C if that helps).

    2. Copied your above code into an empty project. I used the "driverlib_empty_project_sram" default empty project as my starting point.

    3. Changed the "msp.h" included header to  <ti/devices/msp432p4xx/driverlib/driverlib.h>, I didn't have or know where to find the msp.h header but figured the driverlib header works fine.

    4. Using CCS 7.1.0

    5. Programmed the board with just 3.3V jumper plugged in.

    6. Stopped debugger

    7. Unplugged/replugged in the dev board to my computer

    8. Launched EnergyTrace and started it. I am getting 3.3mA!!! Something is amiss here. I even tried switching the "JTAG" switch over to use an ext debugger, still no good. 

    Any ideas?

    **Edit**

    I downloaded the Zip File above (msp432p401x_rtc_lpm35_01.zip) and copied it into a completely empty project (File->New->CCS Project). This time the msp.h header was found without issues, so I used it. I was able to reduce the current to 0.6mA this way, but still a far cry from 0.9uA!

    **Another edit, sorry!**

    So I ran a few other tests and here's what I've got.. for all cases I am using the code snippet from James above, copied into the main.c file.

    1. Using the "driverlib_empty_project_sram" empty project, and correctly locating/including the msp.h header, I still get 2.6mA! 

    2. Using a completely empty project (File->new->CCS Project), I get 4.9uA.

    3. Using the "empty" project from the resource explorer, I get 4.9uA still. 

    So it seems like the empty_project_sram file does something extra that is drawing more current (like retaining more SRAM probably...). Do you know what exactly is different between these two "empty" projects? I've got a large project on a custom board that I believe I started off initially using the "sram" empty project, and it's pulling way too much power. Where do I go to change it to match the "empty" project? Also, I am still curious why I am getting 4.9uA and not 0.9uA like you, but it's not a huge issue for me at this time.

  • Hi Cody,

    First, I'd recommend that you get a Red MSP-EXP432P401R LaunchPad. The Black board with the Rev B chip was pre-production silicon (XMS), which could be the main reason why you're not achieving the current consumption values above. The Red board will have our production silicon (MSP) on it.

    Regards,

    James

    MSP Customer Applications

  • In addition to what James has said, be sure that the JTAG lines to the MSP432 are disconnected when performing the energyTrace measurements. The only connections between the debugger side of the launchpad and the target side should be 3.3V and GND.

    Regards,
    Chris
  • One other thing you may want to check if you are using the black board.  Make sure that the slide switch is moved to the position that disconnects it from the target MCU ( IIRC it is the external debug position).  This had me scratching my head for a little longer than I would care to admit as I was getting higher than expected numbers also.

**Attention** This is a public forum