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.

MSP-EXP430F5529LP: Set it to sleep mode LPM4 but still get over 500uA current.

Part Number: MSP-EXP430F5529LP

Dear Sir,

I had this board connected to a simple keyboard, try to set it to enter LPM4 mode, disable all I/O and disable all SPI and I2C, confirm no current confirm by I/O, key wake up have been enabled and can wake up.  

During current test, all 9 jumpers from SBW_TST to GND were removed, JP8 removed, the board still take over 500uA.  

Please advice what procedures I missed.

Thanks in advanced. 

  • Hi Martin,

    Would you have a chance to run the example code MSP430F55xx_LPM4.c in CCS to see the power consumption?

    Please let me know if it still doesn't work.

    Regards,

    Sean

  • Dear Sean,

    Thanks for your reply.

    I put this portion of code to my sleep routine,  it still take around 50uA during sleep mode and cannot wake up anymore.

    And if take out this line of code "  UCSCTL4 = SELA_1; " , then it can wake up by key. 

    Thanks!

    WDTCTL = WDTPW | WDTHOLD; // Stop WDT

    // Setup UCS
    UCSCTL4 = SELA_1; // Ensure VLO is ACLK source

    // Port Configuration
    P1OUT = 0x00;P2OUT = 0x00;P3OUT = 0x00;P4OUT = 0x00;P5OUT = 0x00;P6OUT = 0x00;
    P7OUT = 0x00;P8OUT = 0x00;PJOUT = 0x00;
    P1DIR = 0xFF;P2DIR = 0xFF;P3DIR = 0xFF;P4DIR = 0xFF;P5DIR = 0xFF;P6DIR = 0xFF;
    P7DIR = 0xFF;P8DIR = 0xFF;PJDIR = 0xFF;

    // Disable VUSB LDO and SLDO
    USBKEYPID = 0x9628; // set USB KEYandPID to 0x9628
    // access to USB config registers enabled
    USBPWRCTL &= ~(SLDOEN+VUSBEN); // Disable the VUSB LDO and the SLDO
    USBKEYPID = 0x9600; // access to USB config registers disabled

    // Disable SVS
    PMMCTL0_H = PMMPW_H; // PMM Password
    SVSMHCTL &= ~(SVMHE+SVSHE); // Disable High side SVS
    SVSMLCTL &= ~(SVMLE+SVSLE); // Disable Low side SVS

    __bis_SR_register(LPM4_bits); // Enter LPM4

  • Hi Sean,

    If I run the demo code MSP430f55XX_LPM4.C,  it only takes 2.5uA.   But my program had 2 setup routines 

    increaseVCoreToLevel2();
    initClockTo25MHz();

    Otherwise, it run too slow.

    So when it has this 2 routines, it will draw around 500uA during LPM4 sleep mode. 

    Any idea how to solve it?

    Thanks!

    void initClockTo25MHz()
    {
    UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO
    UCSCTL4 |= SELA_2; // Set ACLK = REFO
    __bis_SR_register(SCG0); // Disable the FLL control loop
    
    UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
    UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation
    UCSCTL2 = FLLD_0 + 749; // 487; // Set DCO Multiplier 487 for 16MHz,
    // (N + 1) * FLLRef = Fdco
    // (487 + 1) * 32768 = 16MHz
    // Set FLL Div = fDCOCLK
    
    __bic_SR_register(SCG0); // Enable the FLL control loop
    
    // Worst-case settling time for the DCO when the DCO range bits have been
    // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
    // UG for optimization.
    // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
    __delay_cycles(750000);//
    // __delay_cycles(500000);//
    // Loop until XT1,XT2 & DCO fault flag is cleared
    do
    {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG; // Clear fault flags
    }while (SFRIFG1&OFIFG); // Test oscillator fault flag
    }
    
    uint16_t setVCoreUp(uint8_t level){
    uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
    
    //The code flow for increasing the Vcore has been altered to work around
    //the erratum FLASH37.
    //Please refer to the Errata sheet to know if a specific device is affected
    //DO NOT ALTER THIS FUNCTION
    
    //Open PMM registers for write access
    PMMCTL0_H = 0xA5;
    
    //Disable dedicated Interrupts
    //Backup all registers
    PMMRIE_backup = PMMRIE;
    PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE |
    SVSLPE | SVMHVLRIE | SVMHIE |
    SVSMHDLYIE | SVMLVLRIE | SVMLIE |
    SVSMLDLYIE
    );
    SVSMHCTL_backup = SVSMHCTL;
    SVSMLCTL_backup = SVSMLCTL;
    
    //Clear flags
    PMMIFG = 0;
    
    //Set SVM highside to new level and check if a VCore increase is possible
    SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMHDLYIFG;
    
    //Check if a VCore increase is possible
    if((PMMIFG & SVMHIFG) == SVMHIFG)
    {
    //-> Vcc is too low for a Vcore increase
    //recover the previous settings
    PMMIFG &= ~SVSMHDLYIFG;
    SVSMHCTL = SVSMHCTL_backup;
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear all Flags
    PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
    SVMLVLRIFG | SVMLIFG |
    SVSMLDLYIFG
    );
    
    //Restore PMM interrupt enable register
    PMMRIE = PMMRIE_backup;
    //Lock PMM registers for write access
    PMMCTL0_H = 0x00;
    //return: voltage not set
    return false;
    }
    
    //Set also SVS highside to new level
    //Vcc is high enough for a Vcore increase
    SVSMHCTL |= (SVSHRVL0 * level);
    
    //Wait until SVM highside is settled
    while((PMMIFG & SVSMHDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMHDLYIFG;
    
    //Set VCore to new level
    PMMCTL0_L = PMMCOREV0 * level;
    
    //Set SVM, SVS low side to new level
    SVSMLCTL = SVMLE | (SVSMLRRL0 * level) |
    SVSLE | (SVSLRVL0 * level);
    
    //Wait until SVM, SVS low side is settled
    while((PMMIFG & SVSMLDLYIFG) == 0)
    {
    ;
    }
    
    //Clear flag
    PMMIFG &= ~SVSMLDLYIFG;
    //SVS, SVM core and high side are now set to protect for the new core level
    
    //Restore Low side settings
    //Clear all other bits _except_ level settings
    SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 +
    SVSMLRRL1 + SVSMLRRL2
    );
    
    //Clear level settings in the backup register,keep all other bits
    SVSMLCTL_backup &=
    ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
    
    //Restore low-side SVS monitor settings
    SVSMLCTL |= SVSMLCTL_backup;
    
    //Restore High side settings
    //Clear all other bits except level settings
    SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 +
    SVSMHRRL0 + SVSMHRRL1 +
    SVSMHRRL2
    );
    
    //Clear level settings in the backup register,keep all other bits
    SVSMHCTL_backup &=
    ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
    
    //Restore backup
    SVSMHCTL |= SVSMHCTL_backup;
    
    //Wait until high side, low side settled
    while(((PMMIFG & SVSMLDLYIFG) == 0) &&
    ((PMMIFG & SVSMHDLYIFG) == 0))
    {
    ;
    }
    
    //Clear all Flags
    PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
    SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG
    );
    
    //Restore PMM interrupt enable register
    PMMRIE = PMMRIE_backup;
    
    //Lock PMM registers for write access
    PMMCTL0_H = 0x00;
    
    return true;
    }
    
    bool increaseVCoreToLevel2()
    {
    uint8_t level = 2;
    uint8_t actlevel;
    bool status = true;
    
    //Set Mask for Max. level
    level &= PMMCOREV_3;
    
    //Get actual VCore
    actlevel = PMMCTL0 & PMMCOREV_3;
    
    //step by step increase or decrease
    while((level != actlevel) && (status == true))
    {
    if(level > actlevel)
    {
    status = setVCoreUp(++actlevel);
    }
    }
    
    return (status);
    }

  • Hi Sean,

    Do you have any sample code which set the cMSP430F55xx to high speed ( i.e. 24Mhz ) and can enter sleep mode LPM4 with minimum low current but can wake up by key ( port 1.x ) ?

    I do need that in urgent.

    Thanks so much

  • Hi Martin,

    To include the code in a thread, please use the code format above by choosing "Insert", "Code" and then select the language, it helps us to read.

    From the two functions above I couldn't find what cause the device to consume that current, this current consumption should be from the peripheral that requesting the clock. Please read section 5.2.11 in User's Guide. So you may need to set a breakpoint before entering LPM4, see that exact peripheral requesting the clock and disable it, or set the UCSCTL8 register bits to disable all the clock requests (section 5.4.9 in User's Guide).

    Here is the example code to wake up by P1.4 MSP430F55xx_P1_03.c

    Regards,

    Sean

  • Dear Sean,

    I don't think it was caused by the I/O issue.   The reason is when I use the demo code MSP430F55xx_LPM4.c, it can enter LPM4 with <3uA.

    That mean my board does not have I/O current conflict. 

    But once I added the speed up routine during power up, wait for a second and enter the same sleep mode, current is over 1mA.

    So the same sleep mode entry does not work the same way it was. 

    I also try to add these before sleep mode, it still don't work well.

    UCSCTL3 = 0;
    UCSCTL4 = 0x44;
    UCSCTL0 = 0x0000; // 
    UCSCTL1 = 0x20; // 
    UCSCTL2 = 0x101F;

    Please try to add speed up routine and see from your side.

    Thanks so much!

    void initClockTofast()
    {
    BUCSCTL3 = UCSCTL3;
    BUCSCTL4 = UCSCTL4;
    UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO
    UCSCTL4 |= SELA_2; // Set ACLK = REFO
    __bis_SR_register(SCG0); // Disable the FLL control loop

    BUCSCTL2 = UCSCTL2;
    BUCSCTL1 = UCSCTL1;
    UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
    UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation
    UCSCTL2 = FLLD_0 + 487; // + 749; // 487; // Set DCO Multiplier 487 for 16MHz, 749 for 25Mhz.
    // (N + 1) * FLLRef = Fdco
    // (487 + 1) * 32768 = 16MHz
    // Set FLL Div = fDCOCLK

    __bic_SR_register(SCG0); // Enable the FLL control loop

    // Worst-case settling time for the DCO when the DCO range bits have been
    // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
    // UG for optimization.
    // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
    __delay_cycles(750000);//
    // __delay_cycles(500000);//
    // Loop until XT1,XT2 & DCO fault flag is cleared
    do
    {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG; // Clear fault flags
    }while (SFRIFG1&OFIFG); // Test oscillator fault flag
    }

  • Martin,

    Can you provide the entire code of the c file you run which get that 1mA? I'm having trouble adding this function, the program stuck at the loop in the bottom.(SFRIFG value stuck at 0x102). 

    I'll try to set the clock to 25Mhz and then enter LPM4. Let me get back to you by tomorrow.

    Regards,

    Sean

  • Hi Sean,

    Here is the code I modified from the original  MSP430F55xx_LPM4.c  code, just adding a speed up at power on, delay a bit and power down.  

    LPM4 mode cause over 1mA. 

    I had try added in these value before LPM4.  I used other code, try to read out the UCSCTLx before modified them and get back those values.  So I try to add them but does not really help. 

    UCSCTL3 = 0;
    UCSCTL4 = 0x44;
    UCSCTL0 = 0x0000; // 
    UCSCTL1 = 0x20; // 
    UCSCTL2 = 0x101F;

    Thanks,

    Martin

    #include <msp430.h> 
    #include <stdint.h>
    #include <stdbool.h>
    
    //******************************************************************************
    // Device Initialization *******************************************************
    //******************************************************************************
    
    
    
    uint16_t BUCSCTL2;
    uint16_t BUCSCTL1;
    uint16_t BUCSCTL3;
    uint16_t BUCSCTL4;
    
    void initClockTo25MHz()
    {
        BUCSCTL3 = UCSCTL3;
        BUCSCTL4 = UCSCTL4;
        UCSCTL3 |= SELREF_2;                      // Set DCO FLL reference = REFO
        UCSCTL4 |= SELA_2;                        // Set ACLK = REFO
        __bis_SR_register(SCG0);                  // Disable the FLL control loop
    
        BUCSCTL2 = UCSCTL2;
        BUCSCTL1 = UCSCTL1;
        UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
        UCSCTL1 = DCORSEL_5;                      // Select DCO range 16MHz operation
        UCSCTL2 = FLLD_0 + 487; // + 749; // 487;                   // Set DCO Multiplier 487 for 16MHz, 749 for 25Mhz.
                                                  // (N + 1) * FLLRef = Fdco
                                                  // (487 + 1) * 32768 = 16MHz
                                                  // Set FLL Div = fDCOCLK
    
        __bic_SR_register(SCG0);                  // Enable the FLL control loop
    
        // Worst-case settling time for the DCO when the DCO range bits have been
        // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
        // UG for optimization.
        // 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
        __delay_cycles(750000);//
       // __delay_cycles(500000);//
        // Loop until XT1,XT2 & DCO fault flag is cleared
        do
        {
            UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
            SFRIFG1 &= ~OFIFG;                          // Clear fault flags
        }while (SFRIFG1&OFIFG);                         // Test oscillator fault flag
    }
    
    int main(void)
    {
     //   increaseVCoreToLevel2();
    
        initClockTo25MHz();
    
        __delay_cycles(750000);//
        __delay_cycles(750000);//
        __delay_cycles(750000);//
        __delay_cycles(750000);//
        __delay_cycles(750000);//
        __delay_cycles(750000);//
        __delay_cycles(750000);//
        __delay_cycles(750000);//
        __delay_cycles(750000);//
    /**
        UCSCTL3 = 0;
        UCSCTL4 = 0x44;
        UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
        UCSCTL1 = 0x20;                      // Select DCO range 16MHz operation
        UCSCTL2 = 0x101F;
     // Setup UCS
    **/
        WDTCTL = WDTPW | WDTHOLD;                 // Stop WDT
      UCSCTL4 = SELA_1;                       // Ensure VLO is ACLK source
    
      // Port Configuration
      P1OUT = 0x00;P2OUT = 0x04;P3OUT = 0x00;P4OUT = 0x7f;P5OUT = 0x00;P6OUT = 0x00;
      P7OUT = 0x00;P8OUT = 0x00;PJOUT = 0x00;
      P1DIR = 0xFF;P2DIR = 0xFF;P3DIR = 0xFF;P4DIR = 0xFF;P5DIR = 0xFF;P6DIR = 0xFF;
      P7DIR = 0xFF;P8DIR = 0xFF;PJDIR = 0xFF;
    
      // Disable VUSB LDO and SLDO
      USBKEYPID   =     0x9628;           // set USB KEYandPID to 0x9628
                                          // access to USB config registers enabled
      USBPWRCTL &= ~(SLDOEN+VUSBEN);      // Disable the VUSB LDO and the SLDO
      USBKEYPID   =    0x9600;            // access to USB config registers disabled
    
      // Disable SVS
      PMMCTL0_H = PMMPW_H;                // PMM Password
      SVSMHCTL &= ~(SVMHE+SVSHE);         // Disable High side SVS
      SVSMLCTL &= ~(SVMLE+SVSLE);         // Disable Low side SVS
    
      __bis_SR_register(LPM4_bits);             // Enter LPM4
      __no_operation();
    
    }

  • Hi Sean,

    Without calling the setVCoreUp() routine, I cannot set the clock speed up to 25Mhz, I can only set it up to 22Mhz. 

    Now in my code, I can only setup clock to 22Mhz and in LPM4 mode, the lowest get it down to 61uA and able to have key wakeup and run it again.

     But if I add the line  

    UCSCTL4 = SELA_1; 

    It can down to 50uA but  cannot wake up by key.

    Thanks!

    Martin

  • Martin, 

    Here's what I tested with MSP-EXP430F5529LP.

    First running with MSP430F55xx_LPM4.c, current read as 1.1uA, the device was in LPM4.

    Then I added code to toggle P1.1 with 25MHz DCO, before entering LPM4:

    #include <msp430.h>
    
    void SetVcoreUp (unsigned int level);
    
    int main(void)
    {
      volatile unsigned int i;
    
      WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
      P1DIR |= BIT1;                            // P1.1 output
    
      P1DIR |= BIT0;                            // ACLK set out to pins
      P1SEL |= BIT0;
      P2DIR |= BIT2;                            // SMCLK set out to pins
      P2SEL |= BIT2;
      P7DIR |= BIT7;                            // MCLK set out to pins
      P7SEL |= BIT7;
    
      // Increase Vcore setting to level3 to support fsystem=25MHz
      // NOTE: Change core voltage one level at a time..
      SetVcoreUp (0x01);
      SetVcoreUp (0x02);
      SetVcoreUp (0x03);
    
      UCSCTL3 = SELREF_2;                       // Set DCO FLL reference = REFO
      UCSCTL4 |= SELA_2;                        // Set ACLK = REFO
    
      __bis_SR_register(SCG0);                  // Disable the FLL control loop
      UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
      UCSCTL1 = DCORSEL_7;                      // Select DCO range 50MHz operation
      UCSCTL2 = FLLD_0 + 762;                   // Set DCO Multiplier for 25MHz
                                                // (N + 1) * FLLRef = Fdco
                                                // (762 + 1) * 32768 = 25MHz
                                                // Set FLL Div = fDCOCLK/2
      __bic_SR_register(SCG0);                  // Enable the FLL control loop
    
      // Worst-case settling time for the DCO when the DCO range bits have been
      // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
      // UG for optimization.
      // 32 x 32 x 25 MHz / 32,768 Hz ~ 780k MCLK cycles for DCO to settle
      __delay_cycles(782000);
    
      // Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize
      do
      {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                                // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                      // Clear fault flags
      }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
    
    
    
        P1OUT ^= BIT1;                          // Toggle P1.1
        __delay_cycles(600000);                 // Delay
    
    
      WDTCTL = WDTPW | WDTHOLD;                 // Stop WDT
    
     // Setup UCS
      UCSCTL4 = SELA_1;                       // Ensure VLO is ACLK source
    
      // Port Configuration
      P1OUT = 0x00;P2OUT = 0x00;P3OUT = 0x00;P4OUT = 0x00;P5OUT = 0x00;P6OUT = 0x00;
      P7OUT = 0x00;P8OUT = 0x00;PJOUT = 0x00;
      P1DIR = 0xFF;P2DIR = 0xFF;P3DIR = 0xFF;P4DIR = 0xFF;P5DIR = 0xFF;P6DIR = 0xFF;
      P7DIR = 0xFF;P8DIR = 0xFF;PJDIR = 0xFF;
    
      // Disable VUSB LDO and SLDO
      USBKEYPID   =     0x9628;           // set USB KEYandPID to 0x9628
                                          // access to USB config registers enabled
      USBPWRCTL &= ~(SLDOEN+VUSBEN);      // Disable the VUSB LDO and the SLDO
      USBKEYPID   =    0x9600;            // access to USB config registers disabled
    
      // Disable SVS
      PMMCTL0_H = PMMPW_H;                // PMM Password
      SVSMHCTL &= ~(SVMHE+SVSHE);         // Disable High side SVS
      SVSMLCTL &= ~(SVMLE+SVSLE);         // Disable Low side SVS
    
      __bis_SR_register(LPM4_bits);             // Enter LPM4
      __no_operation();
    }
    
    
    void SetVcoreUp (unsigned int level)
    {
      // Open PMM registers for write
      PMMCTL0_H = PMMPW_H;
      // Set SVS/SVM high side new level
      SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;
      // Set SVM low side to new level
      SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
      // Wait till SVM is settled
      while ((PMMIFG & SVSMLDLYIFG) == 0);
      // Clear already set flags
      PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
      // Set VCore to new level
      PMMCTL0_L = PMMCOREV0 * level;
      // Wait till new level reached
      if ((PMMIFG & SVMLIFG))
        while ((PMMIFG & SVMLVLRIFG) == 0);
      // Set SVS/SVM low side to new level
      SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
      // Lock PMM registers for write access
      PMMCTL0_H = 0x00;
    }

    Current read as 1.3uA, no issue.

    Would you please try the code above.

    Regards,

    Sean

**Attention** This is a public forum