Part Number: MSP430FR2355
Although this appears to be a common problem, so far the solution has eluded me.
Here is the setup.
Micro running from an external 10MHZ crystal.
CSCTL6 has XT1Drive set for lowest power.
ACLK running from 10MHZ/256 (39062.5HZ)
MCLK and SMCLK running at 10MHZ.
One timer running off ACLK (used to wake micro)
One timer running off SMCLK for higher resolution timing (when we are not asleep - more on that as we go)
DAC and SAC OA on. OA is set for low power mode
ADC off
Internal references off (uses external Vref for ADC (when on) and for DAC).
CSCTL8 has MODOSCREQEN=0, SMCLKREQEN=0, MCLKREQEN=0, and ACKLREQEN=1.
CSCTL5, SMCLKOFF=0
To check LPM3 static current, the initialization is completed, global interrupts are left off. In main, the micro executes the LPM3 macro, and just sits there with ACLK running along with TIMER0.
So to summarize, here is what I believe that I have running in LPM3.
ACLK, 39062.5 HZ
TIMER0 clocked at ACLK rate with interrupts turned off.
DAC and OA on, (200uA typical in low power mode).
The power management circuits and internal regulator is still on (default settings).
The port lines are not driving any loads.
So I would expect the LPM3 current to be roughly 200uA plus whatever these other micro sections use (which I would expect to be pretty low). MCLK and SMCLK should be off.
However, my micro is drawing 325uA in LPM3, which is roughly 100+ micro amps more than expected.
My initialization code is attached.
Any ideas ?
#include <msp430fr2355.h>
/*
* functions.c
*
* Created on: Dec 29, 2021
* Author: Engineering
*/
void InitSys(void)
{
//**********************************
// Clear LOCKLPM5 bit to enable GPIO
//**********************************
PM5CTL0 &= ~LOCKLPM5; //
//************************************
// Configure I/O port lines
// P1 first
//
// P1.0, Analog Input (A0), P10V_FB
// P1.1, Analog Input (A1), SEC1
// P1.2, Analog Input (A2), SEC2
// P1.3, Digital Output, Unused
// P1.4, Digital Output, Unused
// P1.5, Digital Output, Unused
// P1.6, Digital Output, Unused
// P1.7, Digital Output, Unused
//***********************************
P1OUT = 0;
P1DIR = 0b11111000;
//***********************************
// Configure alternate functions for
// Port 1.
//
// P1.0 = A0 (Analog Input 0), 11
// P1.1 = A1 (Analog Input 1), 11
// P1.2 = A2 (Analog Input 2), 11
// P1.5 = OA1O (Analog Output 1), 11
//***********************************
P1SEL0 = 0b00100111;
P1SEL1 = 0b00100111;
//***********************************
// Configure Port2
//
// P2.0, Digital Output, Unused
// P2.1, Digital Output, Unused
// P2.2, Digital Output, Unused
// P2.3, Digital Output, Unused
// P2.4, Digital Output, Unused
// P2.5, Digital Output, Unused
// P2.6, XOUT, Do not care about DIR
// P2.7, XIN, Do not care about DIR
//************************************
P2OUT = 0;
P2DIR = 0b01111111;
//***********************************
// Configure P2.7 and P2.6 for
// XIN and XOUT
//***********************************
P2SEL1 = 0b11000000; // SEL1 for P2.7 and P2.6 are = 1, select XIN and XOUT respectively
P2SEL0 = 0b00000000; // SEL0 for P2.7 and P2.6 are = 0, select XIN and XOUT respectively
//*************************************
// Configure Port 3
//
// P3.0, Digital Output, Unused or MCLK
// P3.1, Digital Output, Unused
// P3.2, Digital Output, Unused
// P3.3, Digital Output, Unused
// P3.4, Digital Output, P10V_REG
// P3.5, Digital Output, P10V_MEAS
// P3.6, Digital Output, Unused
// P3.7, Digital Output, Unused
//*************************************
P3OUT = 0;
P3DIR = 0b11111111;
//***********************************
// Configure P3.0, MCLK Out
//***********************************
P3SEL1 = 0b00000000; // SEL1 for P3.0 MCLK
P3SEL0 = 0b00000001; // SEL0 for P3.0 MCLK
//*************************************
// Configure Port 4
//
// P4.0, Digital Output, Unused
// P4.1, Digital Output, Unused
// P4.2, Digital Output, Unused
// P4.3, Digital Output, Unused
// P4.4, Digital Output, Unused
// P4.5, Digital Output, Unused
// P4.6, Digital Output, Unused
// P4.7, Digital Output, Unused
//**************************************
P4OUT = 0;
P4DIR = 0b11111111;
//**************************************
// Configure Port 5
//
// P5.0, Digital Output, Unused
// P5.1, Digital Output, Unused
// P5.2, Digital Output, Unused
// P5.3, Digital Output, Unused
// P5.4, Digital Output, Unused
// P5.5 - P5.7 not available
//**************************************
P5OUT = 0;
P5DIR = 0b00011111;
//**************************************
// Configure Port 6
//
// P6.0, Digital Output, AH
// P6.1, Digital Output, AL
// P6.2, Digital Output, BH
// P6.3, Digital Output, BL
// P6.4, Digital Output, Unused
// P6.5, Digital Output, Unused
// P6.6, Digital Output, Unused
// P6.7, not available
//**************************************
P6OUT = 0;
P6DIR = 0b01111111;
//********************************
// Initialize clocks
// Use external xtal (10MHZ)
// MCLK = 10 MHZ (10MHZ / 1)
// ACLK = 39062.5 HZ (10MHZ / 256)
// SMCLK = 10 MHZ (MCLK / 1), 10MHZ
//*********************************
//******************************************
// CSCTL5
// Bits 15-13 Reserved
// Bit 12, VLOAUTOOFF = 0, VLO always on
// Bits 11-9 Reserved
// Bit 8, SMCLKOFF = 0, SMCLK On
// Bit 7-6 Reserved
// Bit 5:4, DIVS = 00, SMCLK = MCLK / 1
// Bit 3 Reserved
// Bits 2:1:0, DIVM = 000, MCLK = XT1CLK / 1
//******************************************
CSCTL5 = \
DIVS_0 | \
DIVM_0;
//***********************************************************
// Bits 15:14 Reserved
// Bit 13, XT1FAULTOFF = 0, Enable switch from ACLK to REFO
// Bit 12 Reserved
// Bits 11:10:9:8 = 0101, Divide by XT1 by 256 for ACLK
// Bit 7:6 = 00, Lowest crystal drive
// Bit 5, XTS = 1, high frequency mode
// Bit 4, XT1BYPASS = 0, XT1 sourced internally
// Bits 3:2, XT1HFFREQ = 10, 6 to 16MHZ XTAL
// Bit 1, XT1AGCOFF = 0, AGC ON
// Bit 0, XT1AUTOOFF = 1, XT1 OFF WHEN NOT USED
//************************************************************
CSCTL6 = \
DIVA__256 | \
XT1DRIVE_0 | \
XTS_1 | \
XT1HFFREQ_2 | \
XT1AUTOOFF_1_L;
//*************************************************************
// Bits 15:10 Reserved
// Bits 9:8, SELA = 00, ACLK Source XT1CLK with divider
// Bits 7-3 Reserved
// Bits 2:1:0 = 010, MCLK and SMCLK source = XT1CLK
//*************************************************************
CSCTL4 = \
SELA__XT1CLK | \
SELMS__XT1CLK;
//*************************************************************
// CSCTL8
// Bits 15:4 Reserved
// Bit 3, MODOSCREQEN, 0=MODOSC conditional requests disabled
// Bit 2, SMCLKRWQEN, 0=SMCLK conditional requests disabled
// Bit 1, MCLKREQEN, 0=MCLK conditional requests disabled
// Bit 0, ACLKEQEN, 1=ACLK conditional requests enabled
//*************************************************************
CSCTL8 = \
MODOSCREQEN_0 | \
SMCLKREQEN_0 | \
MCLKREQEN_0 | \
ACLKREQEN_1;
//**************************************************
// Configure ADC for following
//
// 12 bit operation
//
// ADCCLK source is SMCLK (10 MHZ)
// ADCDIV = 3
// ADCCLK = SMCLK / 3 = 3.33MHZ (max 4.4MHZ)
//
// Conversion time = (12 + 2) x 1/ADCCLK
// Conversion time does not include sample and hold
//
// Select VSS as -VREF
// Select VCC as +VREF
//****************************************************
//****************************************************
// Bits 15-10 Reserved
// Bits 9:8, ADCPDIV = 00, Pre-divide by 1
// Bits 7:6 Reserved
// Bits 5:4, ADCRES = 10, 12 bit conversion
// Bit 3, ADCDF = 0, unsigned binary result
// Bit 2, ADCSR = 1, ADC buffer set for 50ksps
// Bit 1, Reserved
// Bit 0, Reserved
//****************************************************
ADCCTL2 = \
ADCPDIV_0 | \
ADCRES_2 | \
ADCSR;
//****************************************************************
// Bits 15:12 reserved
// Bits 11:10, ADCSHS = 00, Sample and hold source is ADCSC bit
// Bit 9, ADCSHP = 1, SAMPCON signal is sourced from sampling timer
// Bit 8, ADCISSH = 0, sample input is not inverted
// Bits 7:6:5, ADCDIV = 010, Divide source clock by 3 for ADCCLK
// Bit 4:3, ADCSSEL = 10, SMCLK is ADCCLK source
// Bits 2:1, ADCCONSEQ = 00, single channel conversion
// Bit 0, ADCBUSY, Read only, 1=conversion active.
//****************************************************************
ADCCTL1 = \
ADCSHS_0 | \
ADCSHP_1 | \
ADCISSH_0 | \
ADCDIV_2 | \
ADCSSEL_3 | \
ADCCONSEQ_0;
//******************************
// Select AVCC and AVSS as VREF
// A0 selected as analog channel
//******************************
ADCMCTL0 = 0;
//************************************
// After selecting XT1 functions for
// port lines, clear the fault flag
//************************************
do
{
CSCTL7 &= ~(XT1OFFG | DCOFFG); // clear XT1 and DCO fault flags
SFRIFG1 &= ~OFIFG; // clear osc fault interrupt flag
}while (SFRIFG1 & OFIFG); // test osc fault flag
//*****************************************************************
// We will not turn the ADC on yet, since it consumes about
// 280uA when on. We will turn it on just before we need it.
//*****************************************************************
//*********************************
// Initialize TIMER0
//
// TIMER0 is used for low speed
// timing events, such as 10mS
// wake-up.
//
// Clock source ACLK (39062.5 HZ)
// ID Divider = /1
// IDEX Divider = /1
// Continuous mode
// 16 bit
//*********************************
//*****************************************
// Setup compare register for TIMER0, CCR0
// for first compare in 10mS from time
// Timer0 is enabled. Timer is not setup
// or started yet.
//*****************************************
TB0CCR0 = TIMB0_WAKEUP_CCR0;
//************************************************************
// TB0CTL0, TIMER0, Compare 0 Control
//
// Bits 15:14, CM = 00, No Capture
// Bits 13:12, CCIS = 00, CCI0A
// Bit 11, SCS = 0, Async Capture
// Bits 10:9, CLLD = 00, TB0CL0 loads on write
// Bit 8,, CAP = 0, Compare mode
// Bits 7:6:5, OUTMODE = 000, OUT bit value
// Bit 4, CCIE = 1, Compare 0 interrupt enabled
// Bit 3 CCI, Read Only, Input signal
// Bit 2, OUT = 0, Output low
// Bit 1, COV, Flag, 1=Capture Overflow occurred
// Bit 0, CCIFG, Flag, 1=Interrupt pending
//*************************************************************
TB0CCTL0 = \
CAP_0 | \
CCIS_0 | \
SCS__ASYNC | \
CLLD_0 | \
CAP_0 | \
OUTMOD_0 | \
CCIE_1 | \
OUT_0;
//***********************************************************
// TB0EX0, Timer0 Expansion Register
//
// Bits 15-3, Reserved
// Bits 2:1:0 = 000, Divide source clock input by 1
//***********************************************************
TB0EX0 = TBIDEX_0; // divide by 1
//***********************************************************
// TB0CTL, TIMER0 Control
//
// Bit 15, Reserved
// Bits 14:13, TBCLGRP = 00, Each TBxCLn latch is independent
// Bits 12:11, CNTL = 00, 16 bit mode
// Bit 10, Reserved
// Bits 9:8, TBSSEL = 01, ACLK Source
// Bits 7:6, ID = 00, Divide by 1
// Bits 5:4, MC = 10, Continuous mode
// Bit 3, Reserved
// Bit 2, TBCLR = 0, Set this bit to clear timer
// Bit 1, TBIE = 0, Interrupts disabled (THIS IS TIMER OVERFLOW)
// Bit 0, TBIFG, Interrupt flag
//
// TIMER STARTS NOW
//
//************************************************************
TB0CTL = \
TBCLGRP_0 | \
CNTL_0 | \
TBSSEL__ACLK | \
ID_0 | \
MC__CONTINUOUS | \
TBIE_0;
//*********************************
// Initialize TIMER1
//
// TIMER1 is used for high speed
// timing events such as 50uS
// core set and reset.
//
// Clock source SMCLK (10MHZ)
// ID Divider = /1
// Continuous mode
// 16 bit
//*********************************
//*****************************************
// Setup compare register for TIMER1, CCR0
// for first compare in 50uS from time
// Timer1 is enabled. Timer is not setup
// or started yet.
//*****************************************
TB1CCR0 = TIMB1_CORE_SET_CCR0;
//************************************************************
// TB1CCTL0, TIMER1, Compare 0 Control
//
// Bits 15:14, CM = 00, No Capture
// Bits 13:12, CCIS = 00, CCI0A
// Bit 11, SCS = 0, Async Capture
// Bits 10:9, CLLD = 00, TB0CL0 loads on write
// Bit 8,, CAP = 0, Compare mode
// Bits 7:6:5, OUTMODE = 000, OUT bit value
// Bit 4, CCIE = 1, Compare 0 interrupt enabled
// Bit 3 CCI, Read Only, Input signal
// Bit 2, OUT = 0, Output low
// Bit 1, COV, Flag, 1=Capture Overflow occurred
// Bit 0, CCIFG, Flag, 1=Interrupt pending
//*************************************************************
TB1CCTL0 = \
CAP_0 | \
CCIS_0 | \
SCS__ASYNC | \
CLLD_0 | \
CAP_0 | \
OUTMOD_0 | \
CCIE_0 | \
OUT_0;
//***********************************************************
// TB1EX0, Timer1 Expansion Register
//
// Bits 15-3, Reserved
// Bits 2:1:0 = 000, Divide source clock input by 1
//***********************************************************
TB1EX0 = TBIDEX_0; // divide by 1 ////
//***********************************************************
// TB1CTL, TIMER1 Control
//
// Bit 15, Reserved
// Bits 14:13, TBCLGRP = 00, Each TBxCLn latch is independent
// Bits 12:11, CNTL = 00, 16 bit mode
// Bit 10, Reserved
// Bits 9:8, TBSSEL = 10, SMCLK Source
// Bits 7:6, ID = 11, Divide by 8 (10MHZ/8 = 1.25MHZ)
// Bits 5:4, MC = 10, TIMER1 continuous mode
// Bit 3, Reserved
// Bit 2, TBCLR = 0, Set this bit to clear timer
// Bit 1, TBIE = 0, Interrupts disabled for now
// Bit 0, TBIFG, Interrupt flag
//
//
//************************************************************
TB1CTL = \
TBCLGRP_0 | \
CNTL_0 | \
TBSSEL__SMCLK | \
ID__8 | \
MC__CONTINUOUS | \
TBIE_0;
//**********************************************************************
// Configure SAC1
//
// SAC1OA, SAC OA Control Register
//
// Bits 15-11, Reserved
// Bit 10, SACEN = 1, SAC all modules enabled
// Bit 9, OAPM = 1, Low speed and power
// Bit 8, OAEN = 1, SAC OA is enabled, normal mode
// Bit 7, NMUXEN = 1, all negative sources connected to OA negative port
// Bit 6, Reserved
// Bits 5:4, NSEL = 01, PGA source selected
// Bit 3, PMUXEN = 1, all positive sources connected to OA positive port
// Bit 2, Reserved
// Bit 1:0, PSEL = 01, 12 bit DAC as input to OA
//***********************************************************************
SAC1OA = \
SACEN | \
OAPM | \
OAEN | \
NMUXEN | \
NSEL_1 | \
PMUXEN | \
PSEL_1;
//***********************************************************************
// SAC1PGA, SAC1 PGA Control Register
//
// Bits 15:7, Reserved
// Bits 6:5:4, GAIN = 000, Gain = 1
// Bits 3:2, Reserved
// Bits 1:0, MSEL = 01, Follower mode
//************************************************************************
SAC1PGA = \
MSEL0;
//***********************************************************************
// SAC1DAC, SAC DAC Control Register
//
// Bits 15:13, Reserved
// Bits 12, DACSREF = 0, Primary reference selected (DVCC for this part) *** TEST ***
// Bits 11:10, Reserved
// Bits 9:8, DACLSEL = 00, DAC latch loads when DACDAT written
// Bits 7:3, Reserved
// Bit 2, DACDMAE = 0, DMA request disabled
// Bit 1, DACIE = 0, Interrupts disabled
// Bit 0, DACEN = 1, SAC DAC enabled
//***********************************************************************
SAC1DAC = \
DACSREF_0 | \
DACLSEL_0 | \
DACDMAE_0 | \
DACIE_0 | \
DACEN_1;
//************************************************************************
// Initialize MPY32 module
// Module will be setup for 16x16 unsigned integer multiplication.
//
// MPY32CTL0
//
// Bits 15-10, Reserved
// Bit 9, MPYDLY32 = 1, Writes are delayed until 32bit result ready
// Bit 8, MPYDLYWRTEN = 1, Writes are delayed
// Bit 7, MPYOP2_32 = 0, Operand2 is 16 bits
// Bit 6, MPYOP1_32 = 0, Operand3 is 16 bits
// Bits 5:4, MPYMx = 00, MPY-Multiply
// Bit 3, MPYSAT = 0, Saturation mode disabled
// Bit 2, MPYFRAC = 0, Fractional mode disabled
// Bit 1, Reserved
// Bit 0, MPYC = 0, No carry for result
//*************************************************************************
MPY32CTL0 = \
MPYDLY32_1 | \
MPYDLYWRTEN_1 | \
MPYOP2_32_0 | \
MPYOP1_32_0 | \
MPYM_0 | \
MPYSAT_0 | \
MPYFRAC__DISABLE | \
MPYC_0;
//***************************************
// Initialization complete
// Enable global interrupts
//***************************************
// _enable_interrupts();
}