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.

EEPROM writng during power fail condition not working properly using PMM module

Other Parts Discussed in Thread: MSP430F5325

We are developing our product using TI microcontroller MSP430F5325,Our DVCC supply is 3.3 V  and we want to monitor the supply voltage during power fail condition. During power fail we want to write external EEPROM.

Our SMCLK is 8 MHz and required threshold voltage during power fail is 2.90 V so As per the datasheet and user guide of MSP430F5325 we have selected the SVS and SVM high-side reset release voltage level   7 (SVSMHRRL_7;) .

But during power fail we are not able to write the external EEPROM and in normal condition there is no issue to write and read the external EEPROM. During power fail sometime we got the interrupt and write is successful but sometime we didn’t get the interrupt and not able to write so Kindly suggest the solution .

pl refer the below relevant code section .  

 

 

void main(void)

{

WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer

///////////////////////Initialization///////////////////////////////////////////////////////

 

      PMMCTL0_H = PMMPW_H;

       __no_operation();

      SVSMHCTL =0x4400;

       SVSMHCTL = SVMHE + SVSMHRRL_0;

      SVSMHCTL &= ~SVSHE;

      SVSMLCTL &= ~(SVMLE+SVSLE);         // Disable Low side SVS/SVM

      PMMIFG &= ~SVMHIFG;

      PMMRIE=SVMHIE;

      // Lock PMM registers for  access

       PMMCTL0_H = 0x00;

      __no_operation();

     

  SetVCoreUp(1);

 

  SetVCoreUp(2);

 

  SetVCoreUp(3);

  PMMCTL0_H = PMMPW_H;

 

  __no_operation();

 

   SVSMHCTL = SVMHE + SVSMHRRL_7;

 

  SVSMHCTL &= ~SVSHE;

  SVSMLCTL &= ~(SVMLE+SVSLE);         // Disable Low side SVS/SVM

  PMMIFG &= ~SVMHIFG;

  PMMRIE=SVMHIE;

  // Lock PMM registers for write access

PMMCTL0_H = 0x00;

__no_operation();

 while(1)

   { 

         /////// C-  Code

         /////// C-  Code

         /////// C-  Code

         /////// C-  Code

         /////// C-  Code

         /////// C-  Code

 

 

   }// while(1) end

 

 

}//main end

 

 

////////////////////////////////////     SetVCoreUp  function ///////////////////////////

 

void SetVCoreUp (unsigned int level)

{

// Open PMM registers for write access

PMMCTL0_H = 0xA5;

// Make sure no flags are set for iterative sequences

while ((PMMIFG & SVSMHDLYIFG) == 0);

while ((PMMIFG & SVSMLDLYIFG) == 0);

// 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;

}

 

/////////////////////////////////////// Interrupt vector //////////////////////////////

 

#pragma vector=SYSNMI_VECTOR

__interrupt void SYSNMI_ISR(void)

{

   switch(__even_in_range(SYSSNIV,0x12))

   {

       case 0 : break;

       case 2 : break;

       case 4 :

                      Code for writing EEPROM;               

                             //  __no_operation();                      ß break point is here.

                                 //  __no_operation();

         break;

       case 6 :

       break;

       case 8:

           break;

     case 0x0A:

             break;

       case 0x0C:

            break;

       default:

           break;

 

   }

}

////////////////////////////////////////////////////////////////  PMM Setting in datasheet///////////////////////////////////

  • Generally, it is a bad idea in case of a power fail to increase the power consumption by writing to an external EEPROM. Especially since external access is much slower than an internal write operation, so chances are that power is gone long before you are done.

    The 'smart' approach is to save your data before power fails. Just in case it does. Or at least store it to internal flash (pre-erased segment, so there is no erase time and erase current) and copy it over to the external memory on next start.

    Alternatively, detect a power fail while there is still a sufficient backup.
    A possible approach here is to separate supply voltage and VCC by a diode, provide a huge capacitance on the MSP side and measure the supply side with an ADC or comparator. So when the supply fails, you know you have plenty of charge in the capacitor to complete the write.

    Anyway, did you check the tolerance of the SVS voltage thresholds and the required VCC for the current CPU operating speed? Maybe the SVS triggers when the supply is already too low for the CPU to operate?

  • Hi Jens-Michael Gross ,

    Thanks ,

    As  per your below suggestion, We tried to write flash in SYSNMI_isr for SVM on power fail but we are not able to write data in flash, whereas  if we execute the same code in main() function its work fine that we are able to read and write from/in flash (information memory) . Pl refer below code and Kindly suggest the solution. Sometime we get (SYSNMI for SVM ) interrupt on power fail but not on each power fail.

    The 'smart' approach is to save your data before power fails. Just in case it does. Or at least store it to internal flash (pre-erased segment, so there is no erase time and erase current) and copy it over to the external memory on next start.

     

     

     

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////

    void main(void)

    {

    WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer

    ///////////////////////Initialization////////////////////////

    PMMCTL0_H = PMMPW_H;

    __no_operation();

          SVSMHCTL =0x4400;

          SVSMHCTL &= ~SVSHE;

           SVSMHCTL = SVMHE +SVMHFP+ SVSMHRRL_0;     // FULL PERFORMANCE MODE

         

          SVSMLCTL &= ~(SVMLE+SVSLE);         // Disable Low side SVS/SVM

          PMMIFG &= ~SVMHIFG;

     

          PMMRIE&=~SVSHPE;                //SVS high side POR Disable

          PMMRIE=SVMHIE;

     

          // Lock PMM registers for  access

           PMMCTL0_H = 0x00;

          __no_operation();

         

      SetVCoreUp(1);

      __no_operation();

      SetVCoreUp(2);

      SetVCoreUp(3);

     

       __no_operation();

      PMMCTL0_H = PMMPW_H;

     

      __no_operation();

     

       SVSMHCTL = SVMHE +SVMHFP+SVSMHRRL_7;          // // FULL PERFORMANCE MODE ->SVMHFP

     

      SVSMHCTL &= ~SVSHE;

      SVSMLCTL &= ~(SVMLE+SVSLE);         // Disable Low side SVS/SVM

      PMMIFG &= ~SVMHIFG;

    EXT_WATCH_DOG_TOGGLE

      PMMRIE&=~SVSHPE;                //SVS high side POR Disable

      PMMRIE&=~(SVSMLDLYIFG+SVSMHDLYIFG+PMMRSTIFG+SVSHIFG+SVSLIFG);

      PMMRIE=SVMHIE;

     

      // Lock PMM registers for write access

    PMMCTL0_H = 0x00;

    Read_flash();                                        //read flash (information memory)

    while(1)

       { 

             /////// C-  Code

             /////// C-  Code

             /////// C-  Code

             /////// C-  Code

             /////// C-  Code

             /////// C-  Code

     

     

       }// while(1) end

    /////////////////////////////////////////////////////////////////////////////////////////////////////////

    ////////////////////////////////////////   SetVCoreUp  function ///////////////////////////

     

    void SetVCoreUp (unsigned int level)

    {

    // Open PMM registers for write access

    PMMCTL0_H = 0xA5;

    // Make sure no flags are set for iterative sequences

    while ((PMMIFG & SVSMHDLYIFG) == 0);

    while ((PMMIFG & SVSMLDLYIFG) == 0);

    // 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;

    }

     

    /////////////////////////////////////// Interrupt vector //////////////////////////////

     

    #pragma vector=SYSNMI_VECTOR

    __interrupt void SYSNMI_ISR(void)

    {

       switch(__even_in_range(SYSSNIV,0x12))

       {

           case 0 : break;

           case 2 : break;

           case 4 :

                                Code for writing flash;               

                                 //  __no_operation();                      ß break point is here.

                                     //  __no_operation();

             break;

             case 6 :

             break;

             case 8:

               break;

         case 0x0A:

                 break;

           case 0x0C:

                break;

           default:

               break;

     

       }

    }

     

**Attention** This is a public forum