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.
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