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.

Trouble Achieving Power Consumption Levels Specified in Datasheet

Other Parts Discussed in Thread: MSP430FR59941, MSP430FR5994, MSP430WARE

Dear Sirs:

     I had previously run the low power test and thought the consumption was less than 10 ua in LPM3.0.  But now when I go back to it the consumption is about .18 ma which is 10 times what would be acceptable!

     Maybe I misread earlier or whatever.   It is the same on two different MSP430FR5994 LaunchPad dev kits.  (the chip is actually MSP430FR59941 but that doesn’t seem to matter for this.)

     Anyway could you please examine the following example code to see what is the problem?  Would appreciate it very much.

 

Thanks,

John Moore

 

//******************************************************************************

// MSP430FRxx Demo - WDT, Low Power Mode, Interval Overflow ISR, DCO SMCLK

//

// Description: Go to LowPowerMode using software timed by the WDT ISR. The LED

// will turn off when sleeping, Port 1 interrupt will awake the mcu and turn on

// LED. The mcu will sleep at approximately 250 * 32ms based on default

// DCO/SMCLK clock source used in this example for the WDT.

// ACLK = n/a, MCLK = SMCLK = default

 

//                        After 6 sec the WDT interrupt sets to low power mode.

//                        Wakeup is done using low to high input on P1.3 which gives port 1 interrupt

//                          that goes back to normal mode.   Because this is a rising edge, it needs a pulldown in the

//                          form of a scope probe, etc.

//                          Just before going to sleep, it writes 10 values from 0 to 10 into fram memory at 0x4000.

//                          Used the wizard and the "persistant" keyword.

//

//                          If the debugger starts the program it will reinit the FRAM data to 0's and it will be lost (in "Persistent" mode).

//                          but not lost in "noinit" mode.  In "noinit" mode the debugger can read the nonvolatile fram data.

 

//                          The program

//                          is set up to read fram loc 1 and 2 on startup.  If these two locations are 1 and 0 it turns on the

//                          green led.  In this way you don't have to start with the debugger to check fram locations.

//

//

//                                        Uses 3.2ma and .165ma(sleep LPM 3.0)

//                            Must remove all the jumpers and meas current across 3.3V jumper

 

// MSP430G2xxx

// -----------------

// /|\| XIN|-

// | | |

// --|RST XOUT|-

// | |

// | P1.0|-->LED

//

// Aldo Briano

// Texas Instruments Inc.

// July 2010

//******************************************************************************

#include <msp430.h>

//#include "driverlib.h"

 

static int wdtCounter = 0;

 

//#pragma PERSISTENT(FRAM_arr)      //this worked

//unsigned int FRAM_arr[10]={0};

 

#pragma NOINIT(FRAM_arr)            //this works also

unsigned int FRAM_arr[10];

 

 

/************************************************************************

 *              Pre_init()

 ************************************************************************/

int _system_pre_init(void)

{

    // Stop Watchdog timer

    WDT_A_hold(__MSP430_BASEADDRESS_WDT_A__);     // Stop WDT

 

//    GPIO_setOutputHighOnPin(GPIO_PORT_P4, GPIO_PIN0);

//    GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN0);

 

    /*==================================*/

    /* Choose if segment initialization */

    /* should be done or not. */

    /* Return: 0 to omit initialization */

    /* 1 to run initialization */

    /*==================================*/

    return 1;

}

 

/*******************************************************************************************************************

 *                                  main

 *

 ******************************************************************************************************************/

void main(void)

{

 int A;

 

PM5CTL0 &= ~LOCKLPM5;      // Disable the GPIO power-on default high-impedance mode

 

// Init clocks and I/O:

// Startup clock system with max DCO setting ~8MHz

CSCTL0_H = CSKEY >> 8;                    // CSKey=A500.  Unlock clock registers

CSCTL1 = DCOFSEL_3 | DCORSEL;             // Set DCO to 8MHz.  6|40

CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;

CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers

CSCTL0_H = 0;                             // Lock CS registers

 

 

//set unused ports to pulldown:

P2SEL0 &= ~BIT0;          //select GPIO for P1.0

P2SEL1 &= ~BIT0;

P2DIR =0; // Set P2 to input direction

P2REN = 0;      //pulldowns (makes little difference)

//P2DIR =0xff; // Set P2 to output direction (makes little diff)

 

 

 

P3SEL0 &= ~BIT0;          //select GPIO for P1.0

P3SEL1 &= ~BIT0;

P3DIR =0; // Set P2 to input direction

P3REN = 0;      //pulldowns

 

P5SEL0 &= ~BIT0;          //this has push buttons

P5SEL1 &= ~BIT0;

P5DIR =0; // Set P2 to input direction

P5REN = 0;      //pulldowns

 

 

//Init P1.0 for LED1:

P1SEL0 &= ~BIT0;          //select GPIO for P1.0

P1SEL1 &= ~BIT0;

P1DIR |= BIT0; // Set P1.0 to output direction

P1OUT |= BIT0; // Turn on red LED1 at 1.0

 

//Init P1.1 for LED2:

P1SEL0 &= ~BIT0;          //select GPIO for P1.0

P1SEL1 &= ~BIT0;

P1DIR |= BIT1; // Set P1.0 to output direction

P1OUT |= BIT1;  // turn on grn led

 

if((FRAM_arr[1] ==1) && (FRAM_arr[2] ==2))

    P1OUT |= BIT1; // Turn on green LED at 1.1

else

    P1OUT &= ~BIT1; // turn off green LED at 1.1

 

 

//set up rising edge interrupt on P1.3:

P1SEL0 &= ~BIT3;          //select GPIO for P1.3

P1SEL1 &= ~BIT3;        //select1

//P1DIR = 0 ;             //set all to inputs

P1DIR &= ~BIT3;          //set dir to input (0)

P1REN |= (BIT3) ;       //pullup

P1IES &= ~BIT3;          //rising edge 0->1

P1IE |= BIT3 ;        //enable P1.3

 

P4SEL0 &= ~BIT4;          //select GPIO for P4

P4SEL1 &= ~BIT4;

P4DIR =0; // Set P2 to input direction

P4REN = 0;      //pulldowns

 

//set up falling edge interrupt on P5.5 (button2):

P5SEL0 &= ~BIT5;          //select GPIO for P5

P5SEL1 &= ~BIT5;

P5DIR &= ~BIT5;          //set dir to input

P5REN |= (BIT5) ;       //pullup on bit 5 only

P5IES |= BIT5;          //falling edge 1->0

P5IE |= BIT5;         //enable P5,5

 

 

WDTCTL = WDT_MDLY_32; // Set Watchdog Timer interval to ~32ms

SFRIE1 |= WDTIE; // Enable WDT interrupt

 

P1IE |= BIT3; // enable P1.3 interrupt

__enable_interrupt();

 

for(;;)

{

    A=A+1;

}

}

 

/***********************************************************************************

                     Watchdog Timer interrupt service routine

*************************************************************************************/

#pragma vector=WDT_VECTOR

__interrupt void watchdog_timer(void)

{

 int i;

 

    if(wdtCounter == 200)           //now 6 sec instead of 8 sec

    {

        P1OUT = 0x00; // P1.0 turn off

        wdtCounter = 0;

 

       //store FRAM data:

 

        for(i=0;i<10;i++)

            FRAM_arr[i]=i;

 

        _BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/interrupt

        //enterLPM35();               //enter LPM3.5 w/interrupt

    }

    else

    {

        wdtCounter++;

    }

 

}

/***************************************************************************************

             Port 1 interrupt service

***************************************************************************************/

#pragma vector=PORT1_VECTOR

__interrupt void Port_1(void)

{

    wdtCounter = 0; // reset watchdog timer counter

    P1OUT |= 0x01; // turn LED on

    P1IFG = 0x0;

    _BIC_SR(LPM3_EXIT); // wake up from low power mode

 

}

 

/***************************************************************************************

             Port 5 interrupt service routine for button S2?

***************************************************************************************/

#pragma vector=PORT5_VECTOR

__interrupt void Port_5(void)

{

    wdtCounter = 0; // reset watchdog timer counter

    P1OUT |= 0x01; // turn LED on

    P5IFG = 0x0;

    _BIC_SR(LPM3_EXIT); // wake up from low power mode

 

}

 

/***************************************************************************************

 * Enter Low Power Mode 3.5

 **************************************************************************************/

void enterLPM35()

{

    // Configure button S2 (P5.5) interrupt

//    GPIO_selectInterruptEdge(GPIO_PORT_P5, GPIO_PIN5, GPIO_HIGH_TO_LOW_TRANSITION);

//    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN5);

//    GPIO_clearInterrupt(GPIO_PORT_P5, GPIO_PIN5);

//    GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN5);

 

    // Request the disabling of the core voltage regulator when device enters

    // LPM3 (or LPM4) so that we can effectively enter LPM3.5 (or LPM4.5).

    //PMM_turnOffRegulator();

 

    PMMCTL0 &=~BIT4;                //turn off regulator

    //Enter LPM3 mode with interrupts enabled

    __bis_SR_register(LPM3_bits + GIE);

    //__bis_SR_register(LPM4_bits + GIE);

    __no_operation();

}

 

 

 

  • Hi John,

    It looks like you are setting the unused GPIO to input with internal pull-down. This can consume a significant amount of current. We suggest setting unused GPIO to output low. Additionally, because of the connections to the MSP430 on some of our launchpads it can be difficult to achieve the low power numbers found in our datasheet. For the most accurate current measurements we recommend using a target board which has very minimal connections to the GPIO of the MSP430.

    Finally, you can find examples of how to achieve the lowest possible power consumption in MSP430Ware. One example can be found via the TI Resource Explorer linked below:
    dev.ti.com/.../

    Best regards,
    Caleb Overbay
  • Hi John,

    First, have you set a breakpoint at the line where you set the LPM3 bits? That way we can make sure that the device is actually going into LPM3 and that the problem isn't with the WDT.

    Also, could you please describe how you are measuring the power? What setup are you using?

    Regards,
    Nathan
  • Thanks, Nathan:



    I'm using a launch pad MSP430FR5994 launch pad with nothing connected to it and the sd card pulled out loose. Don't see anything connected to it except the debug pins and uart output.

    All the jumpers to the debug section are removed except ground and a current DVM is inserted to measure the current flow across the 3V3 pins.

    The WDT does execute this instruction:

    _BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/interrup



    When a jumper is touched to P1.3 to give a rising edge interrupt, the current goes to 3+ma. After a few seconds the WDT apparantly executes the instr to

    put it into lpm3.0 when the current drops to .47ma. if I hit the red square and stop the debugger, the current drops to .31 ma. (debugging done with the two debug

    jumpers connected.)

    With the 2 debug jumpers pulled out, the current drops slightly to .30 ma.



    Thanks,
    John
  • The latest software of 1/31/18 1:46 which has the init cleaned up

    //******************************************************************************

    // MSP430G2xx Demo - WDT, Low Power Mode, Interval Overflow ISR, DCO SMCLK

    //

    // Description: Go to LowPowerMode using software timed by the WDT ISR. The LED

    // will turn off when sleeping, Port 1 interrupt will awake the mcu and turn on

    // LED. The mcu will sleep at approximately 250 * 32ms based on default

    // DCO/SMCLK clock source used in this example for the WDT.

    // ACLK = n/a, MCLK = SMCLK = default

    //                        After 6 sec the WDT interrupt sets to low power mode.

    //                        Wakeup is done using low to high input on P1.3 which gives port 1 interrupt

    //                          that goes back to normal mode.   Because this is a rising edge, it needs a pulldown in the

    //                          form of a scope probe, etc.

    //                          Just before going to sleep, it writes 10 values from 0 to 10 into fram memory at 0x4000.

    //                          Used the wizard and the "persistant" keyword.

    //

    //                          If the debugger starts the program it will reinit the FRAM data to 0's and it will be lost (in "Persistent" mode).

    //                          but not lost in "noinit" mode.  In "noinit" mode the debugger can read the nonvolatile fram data.

    //                          The program

    //                          is set up to read fram loc 1 and 2 on startup.  If these two locations are 1 and 0 it turns on the

    //                          green led.  In this way you don't have to start with the debugger to check fram locations.

    //

    //

    //                                        Uses 3.2ma and .165ma(sleep LPM 3.0)

    //                            Must remove all the jumpers and meas current across 3.3V jumper

    // MSP430G2xxx

    // -----------------

    // /|\| XIN|-

    // | | |

    // --|RST XOUT|-

    // | |

    // | P1.0|-->LED

    //

    // Aldo Briano

    // Texas Instruments Inc.

    // July 2010

    //******************************************************************************

    #include <msp430.h>

    //#include "driverlib.h"

    static int wdtCounter = 0;

    //#pragma PERSISTENT(FRAM_arr)      //this worked

    //unsigned int FRAM_arr[10]={0};

    #pragma NOINIT(FRAM_arr)            //this works also

    unsigned int FRAM_arr[10];

    /************************************************************************

    *              Pre_init()

    ************************************************************************/

    int _system_pre_init(void)

    {

       // Stop Watchdog timer

       WDT_A_hold(__MSP430_BASEADDRESS_WDT_A__);     // Stop WDT

    //    GPIO_setOutputHighOnPin(GPIO_PORT_P4, GPIO_PIN0);

    //    GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN0);

       /*==================================*/

       /* Choose if segment initialization */

       /* should be done or not. */

       /* Return: 0 to omit initialization */

       /* 1 to run initialization */

       /*==================================*/

       return 1;

    }

    /*******************************************************************************************************************

    *                                  main

    *

    ******************************************************************************************************************/

    void main(void)

    {

    int A;

    PM5CTL0 &= ~LOCKLPM5;      // Disable the GPIO power-on default high-impedance mode

    // Init clocks and I/O:

    // Startup clock system with max DCO setting ~8MHz

    CSCTL0_H = CSKEY >> 8;                    // CSKey=A500.  Unlock clock registers

    CSCTL1 = DCOFSEL_3 | DCORSEL;             // Set DCO to 8MHz.  6|40

    CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;

    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;     // Set all dividers

    CSCTL0_H = 0;                             // Lock CS registers

    //set unused ports to outputs low:

    P2SEL0 = 0;          //select GPIO for P2

    P2SEL1 =0;

    P2DIR =0xff; // Set P2 to output direction

    P2REN = 0;      //no pulls

    P2OUT=0;        //set outputs to 0

    P2OUT=0xff;     //set all high

    P2OUT=0;        //set back low

    P3SEL0 = 0;          //select all pins to GPIO for P1

    P3SEL1 = 0;

    P3DIR =0xff; // Set P3 to output direction

    P3REN = 0;      //no pulls

    P3OUT=0;            //set outputs low

    //P1.0 for LED1:

    //P1.1 for LED2:

    //set up rising edge interrupt on P1.3:

    P1SEL0 =0;          //select GPIO for all of P1

    P1SEL1 =0;        //select1

    P1DIR = 0xff ;             //set all to outputs

    P1DIR &= ~BIT3;          //set bit 3 dir to input (0)

    //P1REN |= (BIT3) ;       //pullup

    P1IES &= ~BIT3;          //rising edge 0->1

    P1IE |= BIT3 ;        //enable P1.3

    P1OUT |= BIT0; // Turn on red LED1 at 1.0

    P1OUT |= BIT1;  // turn on grn led, P1.1

    P1OUT =0 ;      //all off

    //check fram for data:

    if((FRAM_arr[1] ==1) && (FRAM_arr[2] ==2))          //Reset button only works with debugger off

       P1OUT |= BIT1; // Turn on green LED at 1.1

    else

       P1OUT &= ~BIT1; // turn off green LED at 1.1

    P4SEL0 =0;          //select GPIO for all of P4

    P4SEL1 =0;

    P4DIR =0xff; // Set P2 to output direction

    P4REN = 0;      //no pulls

    P4OUT =0;       //output lows

    //set up falling edge interrupt on P5.5 (button2):

    P5SEL0 =0;          //select GPIO for P5

    P5SEL1 =0;

    P5DIR = 0xff;       //set to all bits output

    P5DIR &= ~BIT5;          //set bit 5 dir to input

    P5OUT = BIT5;           //must be high for pullup

    //P5REN |= (BIT5) ;       //pullup on bit 5 only

    P5IES |= BIT5;          //falling edge 1->0

    P5IE |= BIT5;         //enable P5,5

    P5OUT =0x20;            //drive all low except bit5 for low power

    P6SEL0 =0;          //select GPIO for all of P4

    P6SEL1 =0;

    P6DIR =0xff; // Set P2 to output direction

    P6REN = 0;      //no pulls

    P6OUT =0;       //output lows

    P7SEL0 =0;          //select GPIO for all of P4

    P7SEL1 =0;

    P7DIR =0xff; // Set P2 to output direction

    P7REN = 0;      //no pulls

    P7OUT =0;       //output lows

    P8SEL0 =0;          //select GPIO for all of P4

    P8SEL1 =0;

    P8DIR =0xff; // Set P2 to output direction

    P8REN = 0;      //no pulls

    P8OUT =0;       //output lows

    WDTCTL = WDT_MDLY_32; // Set Watchdog Timer interval to ~32ms

    SFRIE1 |= WDTIE; // Enable WDT interrupt

    P1IE |= BIT3; // enable P1.3 interrupt

    __enable_interrupt();

    for(;;)

    {

       A=A+1;

    }

    }

    /***********************************************************************************

                        Watchdog Timer interrupt service routine

    *************************************************************************************/

    #pragma vector=WDT_VECTOR

    __interrupt void watchdog_timer(void)

    {

    int i;

       if(wdtCounter == 250)           //now 6 sec instead of 8 sec

       {

           P1OUT = 0x00; // P1.0 turn off

           wdtCounter = 0;

          //store FRAM data:

           for(i=0;i<10;i++)

               FRAM_arr[i]=i;

           _BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/interrupt

           //enterLPM35();               //enter LPM3.5 w/interrupt

       }

       else

       {

           wdtCounter++;

       }

    }

    /***************************************************************************************

                Port 1 interrupt service

    ***************************************************************************************/

    #pragma vector=PORT1_VECTOR

    __interrupt void Port_1(void)

    {

       wdtCounter = 0; // reset watchdog timer counter

       P1OUT |= 0x01; // turn LED on

       P1IFG = 0x0;

       _BIC_SR(LPM3_EXIT); // wake up from low power mode

    }

    /***************************************************************************************

                Port 5 interrupt service routine for button S2?

    ***************************************************************************************/

    #pragma vector=PORT5_VECTOR

    __interrupt void Port_5(void)

    {

       wdtCounter = 0; // reset watchdog timer counter

       P1OUT |= 0x01; // turn LED on

       P5IFG = 0x0;

       _BIC_SR(LPM3_EXIT); // wake up from low power mode

    }

    /***************************************************************************************

    * Enter Low Power Mode 3.5

    **************************************************************************************/

    void enterLPM35()

    {

       // Configure button S2 (P5.5) interrupt

    //    GPIO_selectInterruptEdge(GPIO_PORT_P5, GPIO_PIN5, GPIO_HIGH_TO_LOW_TRANSITION);

    //    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN5);

    //    GPIO_clearInterrupt(GPIO_PORT_P5, GPIO_PIN5);

    //    GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN5);

       // Request the disabling of the core voltage regulator when device enters

       // LPM3 (or LPM4) so that we can effectively enter LPM3.5 (or LPM4.5).

       //PMM_turnOffRegulator();

       PMMCTL0 &=~BIT4;                //turn off regulator

       //Enter LPM3 mode with interrupts enabled

       __bis_SR_register(LPM3_bits + GIE);

       //__bis_SR_register(LPM4_bits + GIE);

       __no_operation();

    }

  • Should have also said that the current is still .27ma.
  • Caleb and Ryan:

    Finally checked the example you cited. With an msp430fr5994 eval board, the current goes down to about .8ua using a fluke meter on 200ua scale. Now need to apply the information to my project.

    Thanks, you are both life savers!

    John
  • Goh's example was also a life saver.  After checking it, found that I'd forgotten the J port and there was an error in enabling the interrupt in the WDT irq.

    John

**Attention** This is a public forum