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.

CCS/MSP430F6435: Alarm wakeup interrupt for LPM3

Part Number: MSP430F6435

Tool/software: Code Composer Studio

I am working on a small code which sets my controller (MSP430F6435), into sleep mode and get back in active mode by alarm interrupt. I referred to the sources but I am still missing on to something, the code never comes out of LPM3. I am attaching my code for referral

#include <stdio.h>
#include <msp430.h>

/*Sample code for testing the sleep mode(low power mode) of MSP430F6435 */

void Init_GPIO(void)
{
  // Port Configuration
  P1OUT = 0x00;P2OUT = 0x00;P3OUT = 0x00;P4OUT = 0x00;P5OUT = 0x00;P6OUT = 0x00;
  P7OUT = 0x00;P8OUT = 0x00;P9OUT = 0xFF;PJOUT = 0x00;
  P1DIR = 0xFF;P2DIR = 0xFF;P3DIR = 0xFF;P4DIR = 0xFF;P5DIR = 0xFF;P6DIR = 0xFF;
  P7DIR = 0xFF;P8DIR = 0xFF;P9DIR = 0xFF;PJDIR = 0xFF;
}

void init_RTC_B(void)       //NO PRESCALER USED
{

    UCSCTL6 &= ~(XT1OFF);                     // 32Khz capacitor used for MCLK, SMCLK, ACLK
    UCSCTL6 |= XCAP_3;                        // Internal load cap 12pF configuration
    while(BAKCTL & LOCKBAK)                   // Unlock XT1 pins for operation
       BAKCTL &= ~(LOCKBAK);
    do
    {
      UCSCTL7 &= ~(XT1LFOFFG + DCOFFG);
                                              // Clear XT1,DCO fault flags in case of possible faults that could set these registers high
      SFRIFG1 &= ~OFIFG;                      // Clear oscillator fault flags
    }while (SFRIFG1&OFIFG);                   // Till the oscillator fault flags are not cleared

    RTCCTL0 = RTCAIE;           //Alarm interrupt for wake up from low power mode
    RTCAMIN = 0x81;             //For 1 minute interupt

    RTCCTL1 = RTCHOLD;                        //Disables the calender mode

        RTCHOUR = 0x5;                        // Hour = 0x5
        RTCMIN = 0x6;                        // Minute = 0x15
        RTCSEC = 0x7;                        // Seconds = 0x25
}

void EnterLPM3(void)
{
  PMMCTL0_H = PMMPW_H;                      // Open PMM Registers for write
  PMMCTL0_L |= PMMREGOFF;                   // and set PMMREGOFF
  __bis_SR_register(LPM3_bits+ GIE);        // Enter LPM3.5 mode with interrupts//3.5 because minimum power consumption with backup RTC
  __no_operation();                         // enabled
}

#pragma vector=RTC_VECTOR
__interrupt void RTCISR (void)
{
  PMMCTL0_H = PMMPW_H;                      // open PMM
  PM5CTL0 &= ~LOCKLPM5;                     // Clear LOCKBAK and enable ports
  PMMCTL0_H = 0x00;                         // close PMM

  RTCCTL0 &= ~RTCAIE;
  __bic_SR_register_on_exit(LPM3_bits+ GIE);     // Exit LPM3
  __no_operation();
}

int main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    P5DIR |= BIT5;
    int i, sec;

    Init_GPIO();
    init_RTC_B();

    EnterLPM3();

    P5OUT |= 0X0020;
    while(1);
}

I am a newbie here and any help would be appreciable. Thank you.

Regards

-Onkar

  • Hello Onkar,

    Thank you for posting this question. Having looked at your code, I believe I know what is causing your HOLD in the LPM3 mode.

    First you need to enable the RTC Register to accept interrupts. Using the below code:

    RTCMODE = 1;

    You can add this code before the following code:

    RTCCTL0 = RTCAIE; //Alarm interrupt for wake up from low power mode
    RTCAMIN = 0x81; //For 1 minute interrupt

    Also from looking at your code I noticed that you used the below code:

    RTCCTL1 = RTCHOLD; //Disables the calendar mode

    To obtain your Hours, Minutes, and Seconds. You are then missing a vital part of your code. You then need to restart your RTC calendar mode after you sample the data. This is done by the following code.

    RTCCTL1 &= ~(RTCHOLD); // Start RTC calendar mode

    So in other words you need to add the above code after the following code:

    RTCHOUR = 0x5; // Hour = 0x5
    RTCMIN = 0x6; // Minute = 0x15
    RTCSEC = 0x7; // Seconds = 0x25

    If you go to the TI Resource Explorer and search the example code msp430f66xx_rtc_01.c you will find a good example of this.

    Let me know if this fixes your problem.

    Regards,
    Travis Black
    Apps Engineer
  • Thank you for your response Travis.

    I am currently using MSP430F6435 and moreover RTC_B, so i don't have an option for RTCMODE in it(reference slau208p). Secondly I intentionally disabled the calendar mode as this was a sample code for testing alarm interrupt and LPM. I don't think that should be the issue for the response of the interrupt.

    MOST IMPORTANT ----


    The above code works and the micro controller comes out of sleep mode if we wait for 1 hour, because i set my clock to 05:06:07 and gave an interrupt of 1 min the interrupt actually occurs at 06:01:00. I changed my initial time to 5:00:00 and I am getting expected results now.

    I still don't get how this part of code is functioning(with respect to function call, flow of control) so I'll be thankful if I get help/ reference for that

    #pragma vector=RTC_VECTOR
    __interrupt void RTCISR (void)
    {
      PMMCTL0_H = PMMPW_H;                      // open PMM
      PM5CTL0 &= ~LOCKLPM5;                     // Clear LOCKBAK and enable ports
      PMMCTL0_H = 0x00;                         // close PMM
    
      RTCCTL0 &= ~RTCAIE;
      __bic_SR_register_on_exit(LPM3_bits+ GIE);     // Exit LPM3
      __no_operation();
    }
    

    Regards

    -Onkar

  • Onkar,

    Good catch on the RTCMODE. So to answer your question, you are validly entering LPM3.5 (not LPM3). The interrupt is not immediately entered, the flag triggers a restart instead of an ISR. This is why the example msp430f66xx_LPM35_RTC.c checks the SYSRSTIV and has a WakeUpLPM35 configuration function. Only after enabling I/O and RTC_B interrupts should the interrupt that caused the wake-up be serviced (Section 23.3.6 of the User’s Guide). This ISR seems to be some sort of safeguard against improper operation since it only enables the I/O by clearing the LOCKIO bit, clears the IFG, and exits LPM3. I gather that the code could safely be removed without affecting operation but I’d like to know if you ever enter it during debugging?

    Regards,
    Travis Black
    Apps Engineer
  • Thank you Travis,

    I think that my code is entering LPM3, correct me if I am wrong, because I have ram retention(initialized some integers and printed them in debug mode before LPM and after wakeup and observed RAM retention). I am curious to know what make you think that the code uses LPM3.5.

    And when I removed the code the controller never comes out of sleep mode.

    Regards,

    Onkar

  • Onkar,

    Your code is confusing because you are sampling from the msp430f66xxLPM35_RTC.c, designed for LPM3.5 entry, but then you changed the code so that it only enters LPM3. There is no need to open the PMM registers and set the PMMREFOFF bit when using LPM3. Clearing the LOCKBAK bit should happen during initialization, not every time the ISR is triggered. The LPM3 bits are cleared so that the device enters Active Mode and continues operation past your EnterLPM3 function, where bit 5 of port 2 is set before entering the while loop.

    Regards,
    Ryan

**Attention** This is a public forum