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.

MSP430F67791A: i want to use LPM 3.5 mode in MSP430F67791A

Part Number: MSP430F67791A
Other Parts Discussed in Thread: MSP430F6779, MSP430WARE

Hi,

Good Day. I have a customer who is dealing with coding with MSP430F67791A, please see his query below. Thank you very much.

i tried to study and edit MSP430F6779_AUX_11.c given in tidc620a

please check the function "EnterLPM35()". from reading datasheet, after setting PMMREGOFF bit, the core voltage must measure 0V. right?? but my issue is i can still measure 1.5V at Vcore, after i power off the main supply so i assume that the controller is not entering LPM3.5 mode

#include <msp430.h>

//Lookup table for displaying LCD characters

const unsigned int LCD_Char_Map_Top[] =
{
BIT3|BIT2|BIT1|BIT0|BIT7|BIT6, // '0' or 'O'
BIT2|BIT1, // '1' or 'I'
BIT3|BIT2|BIT0|BIT7|BIT5, // '2' or 'Z'
BIT3|BIT2|BIT1|BIT0|BIT5, // '3'
BIT2|BIT1|BIT6|BIT5, // '4' or 'y'
BIT3|BIT1|BIT0|BIT6|BIT5, // '5' or 'S'
BIT3|BIT1|BIT0|BIT7|BIT6|BIT5, // '6' or 'b'
BIT3|BIT2|BIT1, // '7'
BIT3|BIT2|BIT1|BIT0|BIT7|BIT6|BIT5, // '8' or 'B'
BIT3|BIT2|BIT1|BIT0|BIT6|BIT5, // '9' or 'g'
};

const unsigned int LCD_Char_Map[] =
{
BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7, // '0' or 'O'
BIT5 | BIT6, // '1' or 'I'
BIT0 | BIT1 | BIT3 | BIT4 | BIT6 | BIT7, // '2' or 'Z'
BIT0 | BIT1 | BIT4 | BIT5 | BIT6 | BIT7, // '3'
BIT0 | BIT1 | BIT2 | BIT5 | BIT6, // '4' or 'y'
BIT0 | BIT1 | BIT2 | BIT4 | BIT5 | BIT7, // '5' or 'S'
BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT7, // '6' or 'b'
BIT5 | BIT6 | BIT7, // '7'
BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7, // '8' or 'B'
BIT0 | BIT1 | BIT2 | BIT4 | BIT5 | BIT6 | BIT7, // '9' or 'g'
};

void Board_LPM(void);
void EnterLPM35(void);

#include <msp430.h>

int LPM0_enter=0, LPM35_enter=0;
int i=0, reset_source=0, reset_source1=0;
int srcLo, srcHi;

void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT

reset_source=SYSRSTIV;

UCSCTL6 = (UCSCTL6 | XT1DRIVE_3); /* Highest drive setting for XT1 startup */
while (SFRIFG1 & OFIFG)
{
UCSCTL7 &= ~(DCOFFG | XT1LFOFFG | XT2OFFG); /* Clear OSC fault flags */
SFRIFG1 &= ~OFIFG; /* Clear OFIFG fault flag */
}
UCSCTL6 = (UCSCTL6 & ~(XT1DRIVE_3)); /* Reduce drive to something weaker */

if(reset_source1 == 0x08) //Case when just exited LPM3.5 mode, which caused RESET. ( but control never come inside this if(). )
{ // When woken up from LPM3.5, reinit
PMMCTL0_H = PMMPW_H; // open PMM
// PM5CTL0 &= ~LOCKIO; // Clear LOCKBAK and enable ports
PMMCTL0_H = 0x00; // close PMM
}

P1DIR &= ~(BIT0); // Set P1.0 as input
P1IE |= BIT0; // P1.0 interrupt enabled
P1IES &= ~BIT0; // P1.0 high/low edge
P1IFG &= ~BIT0;

PMMCTL0_H = PMMPW_H;
SVSMHCTL &= ~SVSMHRRL_7;
SVSMHCTL |= SVSMHRRL_4;
AUXCTL0 = AUXKEY;
AUX2CHCTL = AUXCHKEY | AUXCHC_1 | AUXCHV_1 | AUXCHEN;
AUX3CHCTL = AUXCHKEY | AUXCHC_1 | AUXCHV_1 | AUXCHEN;
AUXCTL2 |= AUX0LVL_6 + AUX2LVL_5;
AUXCTL1 |= AUX2PRIO;
AUXIE |= (AUX0SWIE | AUX2SWIE | AUX2DRPIE );
AUXCTL0_L &= ~LOCKAUX;
PMMCTL0_H = 0;

//Setup LCD
for (i = 0; i < 20; i++)
{
LCDMEM[i] = 0;
LCDBMEM[i]=0; //Clear Blinking segment memory
}

LCDCCTL0 = LCDDIV_31 | LCDPRE_1 | LCD4MUX | LCDON;
LCDCVCTL = LCDCPEN | VLCD_2_60;
LCDCPCTL0 = 0xFFFF;
LCDCPCTL1 = 0xFFFF;
LCDCPCTL2 = 0xFFC3;
LCDCCPCTL = 0xFFFF;

RTCCTL0 = RTCKEY;
RTCCTL0_L |= RTCRDYIE; // Enable RTC time event,
RTCCTL1 |= RTCBCD | RTCHOLD; // RTC enable BCD mode, RTC hold
RTCCTL1 &= ~(RTCHOLD); // Start RTC
RTCCTL0_H = 0;



__bis_SR_register(GIE); //Enable interrupt

//Print "rs:xx" where xx is the source of the last reset.
LCDM17=BIT5 | BIT7 | BIT4;
LCDM16=BIT0| BIT1 | BIT3 | BIT5 | BIT6;
LCDM15= LCD_Char_Map_Top[reset_source>>4];
LCDM14= LCD_Char_Map_Top[reset_source&0xF];


//Handle the case where a reset occurs and running from AUXVCC2.
if(AUXCTL0 & AUX0SW)
{
LPM0_enter=0;
LPM35_enter=0;
}
else if(AUXCTL0 & AUX2SW)
{
Board_LPM();
LPM0_enter=0;
LPM35_enter=1;
AUXCTL1 |= AUX0MD;
AUXCTL1 &= ~( AUX0OK);
}

while(1)
{
if(LPM35_enter==1)
{
EnterLPM35(); // Enter LPM3.5. The RTCRDY interrupt will not be trigered.
//Unlike RTCOFIE, RTCEVIE, RTCAIE interrupts, this interrupt cannot wake up RTC from LPM3.5
// However, the RTC still counts in LPM3.5 though you can't see it.
}
}
}


void EnterLPM35(void)
{
PMMCTL0_H = PMMPW_H; // Open PMM Registers for write
PMMCTL0_L |= PMMREGOFF; // and set PMMREGOFF (this bit is not working, i believe since i can measure 1.52v at Vcore afret powering off main supply)
__bis_SR_register(LPM4_bits+ GIE); // Enter LPM3.5 mode with interrupts
__no_operation(); // enabled
}


#pragma vector=AUX_VECTOR
__interrupt void aux_interrupt(void)
{
switch (__even_in_range(AUXIV, 16))
{
case AUXIV_NONE:
break;
case AUXIV_AUXSWNMIFG: /* Global (non-)maskable supply switched interrupt flag */
break;
case AUXIV_AUX0SWIFG: /* Switched to DVCC interrupt flag */
__bic_SR_register_on_exit(LPM4_bits); // Exit LPM0 mode if in it
__no_operation();
PMMCTL0_H = PMMPW_H; // open PMM
PMMCTL0_L = 0x08; // trigger Software power-on reset
PMMCTL0_H = 0x00;
LPM35_enter=0;
break;
case AUXIV_AUX1SWIFG: /* Switched to AUXVCC1 interrupt flag */
break;
case AUXIV_AUX2SWIFG: /* Switched to AUXVCC2 interrupt flag */
Board_LPM();
LPM35_enter=1; //When switch to AUXVCC2, go to LPM3.5 mode
break;
case AUXIV_AUX1DRPIFG: /* AUXVCC1 below threshold interrupt flag */
break;
case AUXIV_AUX2DRPIFG: /* AUXVCC2 below threshold interrupt flag */
break;
case AUXIV_AUXMONIFG: /* Supply monitor interrupt flag */
break;
}
}


#pragma vector=RTC_VECTOR // RTC Interrupt Service Routine
__interrupt void rtc_isr(void)
{
switch (__even_in_range(RTCIV, 16))
{
case RTCIV_NONE: // No interrupts
break;
case RTCIV_RTCOFIFG: // RTCOFIFG
break;
case RTCIV_RTCRDYIFG: // RTCRDYIFG


LCDM8=LCDM4=0x04; //Display two ":" in the time
LCDM3 = LCD_Char_Map[RTCHOUR & 0xF];//Display actual time
LCDM1 = LCD_Char_Map[RTCHOUR >> 4];
LCDM7 = LCD_Char_Map[RTCMIN & 0xF] ;
LCDM5 = LCD_Char_Map[RTCMIN >> 4];
LCDM11 = LCD_Char_Map[RTCSEC & 0xF];
LCDM9 = LCD_Char_Map[RTCSEC >> 4];
break;
case RTCIV_RTCTEVIFG: // RTCEVIFG
__no_operation();
break;
case RTCIV_RTCAIFG: // RTCAIFG
__no_operation();
break;
case RTCIV_RT0PSIFG: // RT0PSIFG
break;
case RTCIV_RT1PSIFG: // RT1PSIFG
break;
case 16: break; // Reserved
default: break;
}
}


void Board_LPM(void)
{
// Port Configuration

P1OUT = 0x00;P2OUT = 0x00;P3OUT = 0x00;P4OUT = 0x00;P5OUT = 0x00;P6OUT = 0x00;
P7OUT = 0x00;P8OUT = 0x00;P9OUT = 0x00; P10OUT = 0x00; P11OUT = 0x00;PJOUT = 0x00;
P1DIR = 0xFE;P2DIR = 0xFF;P3DIR = 0xFF;P4DIR = 0xFF;P5DIR = 0xFF;P6DIR = 0xFF;
P7DIR = 0xFF;P8DIR = 0xFF;P9DIR = 0xFF; P10DIR = 0xFF; P11DIR = 0xFF; PJDIR = 0xFF;

LCDCCTL0 &= ~LCDON; //Disable clocks

//This port interrupt would wake the chip out of LPM3.5.
// P1DIR &= ~(BIT0); // Set P1.0 as input
P1IE = BIT0; // P1.0 interrupt enabled
P1IES = 0; // P1.0 high/low edge
P1IFG = 0;
}

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
P1IFG =0; // P1.0 IFG cleared

}

this is an edited version of "MSP430F6779_AUX_11.c' given in 'tidc620a'

i came to assumption that the micro is not entering LPM3.5 from 2 observations. one is the Vcore not going 0Vafter power down. next is i commented 'Board_LPM();' in aux interrupt, and now the display is live and the RTCIV_RTCRDYIFGis being triggered

Best Regards,

Ray Vincent

**Attention** This is a public forum