Part Number: MSP432P401R
Tool/software: Code Composer Studio
Hi,
I am trying to enter low power mode 3 (LPM3) using the msp432 P401R launchpad (red) and have had little success.
I have changed the my clock to low frequency, turned off the supply voltage supervisor and monitor, turned on the force entry bit, and changed the watchdog timer to an interval timer to wake up from deep sleep.
I would like to make an application which goes into deep sleep mode for long periods of time and only turns on for short bursts. The code I have now is down to the barebones, to see if I can get an estimated battery life of over 2 months. The example in the resource center results in estimated battery life upwards of 2 months.
My current code only reaches 5-12 days.
What am I missing?
Thanks
* This test code is for testing entering into low power mode
* Entry into low power mode 3 will be performed
* Verification will be done using the Energy trace tool within code composer studio
*
* with WDT_A_CTL_IS_7 I got about 15 days
*/
#include "msp.h"
#define INT_WDT_BIT (1<<3)
void GPIO_Init(void);
void set_WDT(void);
void low_PWR(void);
void set_CLK(void);
void set_PSS(void);
void main(void)
{
WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer
set_WDT(); // change WDT to interval timer
GPIO_Init();
set_CLK(); // set clock to low freq, 32ish khz
set_PSS();
low_PWR(); // set low power mode for LPM3
__enable_interrupt(); // enable interrupts. should wake when WDT interval completes
__WFI(); // put system to sleep
while(1)
{
// will loop in here, do nothing.
// when WDT triggers, will wake up and then interrupt will put system back to sleep.
__WFI(); // put system to sleep
}
}
void GPIO_Init(void)
{
// enables pull-up/down resistor on all ports
/*
PA -> REN |= 0xFF;
PB -> REN |= 0xFF;
PC -> REN |= 0xFF;
PD -> REN |= 0xFF;
*/
// sets direction of ports to outputs
PA -> DIR |= 0xFF;
PB -> DIR |= 0xFF;
PC -> DIR |= 0xFF;
PD -> DIR |= 0xFF;
// sets all ports to use pull-down resistor
PA -> OUT &= 0x00;
PB -> OUT &= 0x00;
PC -> OUT &= 0x00;
PD -> OUT &= 0x00;
}
void set_CLK(void)
{
// enable
PJ->SEL0 |= 0x03; // PJ only found by accident. Pg 8 of tech ref
PJ->SEL1 &= ~0x03;
CS->KEY = CS_KEY_VAL; // enter key to allow for clk change. Cannot bitmask
CS->CTL1 = 0; // set everything to 0, which makes lfxtclk the source. Check this reg is 0 after writing to it.
CS->CTL2 = 0; // Lowest drive strength and current consumption LFXT oscillator
CS->CTL2 |= (1 << 8); // set enable low freq clk
CS->CLKEN &= (0<<0) | (0<<1) | (0<<2) | (0<<3); // shuts off clocks ACLK,MCLK,HSMCLK,SMCLK
// sometimes doesn't work. Need to stabalize
while(CS->IFG & (1 << 0)) // loop until the low freq clock is stable
{
CS->CLRIFG |= (1 << 0);
}
CS->KEY = 0; // stop making clock changes
}
void set_WDT(void)
{
// sets WDT to wakeup from sleep mode
// WDT_A_CTL_IS_1 1 day and change
// WDT_A_CTL_IS_2 4 min 16 sec
// WDT_A_CTL_IS_4 1 sec
// WDT_A_CTL_IS_7 1.95 ms
WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_IS_1 | WDT_A_CTL_TMSEL;
NVIC->ISER[0] |= INT_WDT_BIT;
}
void WDT_A_IRQHandler (void)
{
// what happens when the watchdog timer triggers
}
void low_PWR(void)
{
// sets upt low power mode 3 LPM3
//PCMCTL0 -> CTL0
/////// Core 0
SCB -> SCR |= (1 << 2); // sleep bit to premp
// PCM->CTL0 = PCM_CTL0_KEY_VAL | (1 << 8) | (1 << 0); not needed
PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR__AM_LF_VCORE0; // set to low power mode 3
PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_LPMR__LPM3; // set to low power mode 3
PCM->CTL1 = PCM_CTL1_KEY_VAL | (1 << 2); // force entry to LPM3
}
void set_PSS(void)
{
PSS ->KEY = PSS_KEY_KEY_VAL; // opens access to PSS
PSS ->CTL0 |= PSS_CTL0_SVSMHOFF; // Turns off SVSM
PSS ->KEY = 1; // closes access to PSS
}