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();
}