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.

Understanding RTC B and the lockbak bit

Other Parts Discussed in Thread: MSP430F6636

Hello everybody,

I'd a bit confused with the RTC_B module, and I'd like some assistance to understand how it works.


This is what i got so far:
- Let's say we got the RTC_B running somehow when Power was available for the MSP430.

- Once power fades, the backup system comes into play, keeping the counters  + Oscillator LFXT1 running.
 The configuration registers are lost, but the RTC keeps working....

- Once power is present again : code starts, lockbak bit locks the registers of the RTC so the informations wont get overwritten ? because I read "The LOCKBAK bit should only be written as 0 after configuring the RTC control
registers."

Now TO test the RTC on my custom Board, I made this code:

#include "driverlib.h"

Calendar time;

int main(void)
{

	WDT_A_hold(WDT_A_BASE);
	// erase LOCKBAK bit
	time.DayOfMonth = 17;
	time.DayOfWeek = 06;
	time.Hours = 23;
	time.Minutes = 59;
	time.Seconds = 55;
	time.Year = 2015;
	GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN3 + GPIO_PIN4 + GPIO_PIN5);
	GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN3 + GPIO_PIN4 + GPIO_PIN5);
	GPIO_setAsInputPinWithPullDownResistor(GPIO_PORT_P1, GPIO_PIN6);
	__delay_cycles(1000000);
	if (GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN6))
	{
		GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN3 + GPIO_PIN5);
					GPIO_setOutputHighOnPin(GPIO_PORT_P5, GPIO_PIN4);
		RTC_B_initCalendar(RTC_B_BASE, &time, RTC_B_FORMAT_BINARY);
		BAK_BATT_unlockBackupSubSystem(BAK_BATT_BASE);
		__delay_cycles(1000000);
		GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN3 + GPIO_PIN4 + GPIO_PIN5);
	}
	BAK_BATT_unlockBackupSubSystem(BAK_BATT_BASE);
	RTC_B_startClock(RTC_B_BASE);

	while (1)
	{
		time = RTC_B_getCalendarTime(RTC_B_BASE);
		if (time.DayOfMonth > 17)
		{
			GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN4 + GPIO_PIN5);
			GPIO_setOutputHighOnPin(GPIO_PORT_P5, GPIO_PIN3);
		}
		else if (time.DayOfMonth == 0)
		{
			GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN3 + GPIO_PIN4);
			GPIO_setOutputHighOnPin(GPIO_PORT_P5, GPIO_PIN5);
		}
		else
		{
			GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN3 + GPIO_PIN5);
			GPIO_setOutputHighOnPin(GPIO_PORT_P5, GPIO_PIN4);
		}
	}
}

When the press button is pressed at start: reset clock to January 17th 5 seconds before midnight.
else, just keep clock running.
This works only if I
BAK_BATT_unlockBackupSubSystem(BAK_BATT_BASE); first
then
RTC_B_initCalendar(RTC_B_BASE, &time, RTC_B_FORMAT_BINARY);

which is contradictory to the information in the Family Guide ?

What makes me even more confused, even after reading a very similar thread, is the SVSH reset story...
IS teh purpose of that to check that there is sufficient DVCC before erasing LOKBAK bit otherwise keep sourcing RTC from bakup battery ?


Help would be much appreciated.

Thanks

Ness

  • Ness,

    What device are you developing for? Also, what version of driverlib are you using? We recently made some changes in the RTC APIs and want to make sure you haven't hit any of our bugs. If you are unsure of the version there should be a "version.h" file located in the MSP430F5xx_6xx/inc folder.

    Thanks,
    Zack

  • Hello Zack,

    What device are you developing for?
    MSP430F6636 sorry i forgot to mention it.

    I am using driverlib 1.90.00.65
    I am also encountering problems merging RTC_B within USB (CDC)...

    Let me check it deeper, maybe will add the code later if  I find the problem.

    Cheers

    Nessim

  • Hello again,

    I made further tests, and I managed to merge the RTC code within the C1 example:

    void main(void)
    {
    	WDT_A_hold(WDT_A_BASE); // Stop watchdog timer
    	// Minumum Vcore setting required for the USB API is PMM_CORE_LEVEL_2 .
    #ifndef DRIVERLIB_LEGACY_MODE
    	PMM_setVCore(PMM_CORE_LEVEL_3);
    #else
    	PMM_setVCore(PMM_BASE, PMM_CORE_LEVEL_3);
    #endif
    
    	initPorts();           // Config GPIOS for low-power (output low)
    	initClocks(8000000);   // Config clocks. MCLK=SMCLK=FLL=8MHz; ACLK=REFO=32kHz
    	initTimer();           // Prepare timer for LED toggling
    	USB_setup(TRUE, TRUE); // Init USB & events; if a host is present, connect
    	PMM_enableSvsH();
    	__enable_interrupt();  // Enable interrupts globally
    	RTC_B_startClock(RTC_B_BASE);
    	while (BAK_BATT_UNLOCKFAILURE == BAK_BATT_unlockBackupSubSystem(BAK_BATT_BASE))
    		;
    	while (1)
    	{
    		uint8_t i;
    
    		// Check the USB state and directly main loop accordingly
    		switch (USB_connectionState())
    		{
    			// This case is executed while your device is enumerated on the
    			// USB host
    			case ST_ENUM_ACTIVE:
    
    				// If true, some data is in the buffer; begin receiving a cmd
    				if (bCDCDataReceived_event)
    				{
    
    					// Holds the new addition to the string
    					char pieceOfString[MAX_STR_LENGTH] = "";
    
    					// Holds the outgoing string
    					char outString[MAX_STR_LENGTH] = "";
    
    					// Add bytes in USB buffer to the string
    					cdcReceiveDataInBuffer((uint8_t*) pieceOfString, MAX_STR_LENGTH,
    							CDC0_INTFNUM); // Get the next piece of the string
    
    					// Append new piece to the whole
    					strcat(wholeString, pieceOfString);
    
    					// Has the user pressed return yet?
    					if (retInString(wholeString))
    					{
    
    						if (!(strcmp(wholeString, "time?")))
    						{
    
    							if (BAKCTL & LOCKBAK)
    							{
    								GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN5);
    								GPIO_setOutputHighOnPin(GPIO_PORT_P5, GPIO_PIN5);
    							}
    							time = RTC_B_getCalendarTime(RTC_B_BASE);
    							switch (time.DayOfWeek)
    							{
    								case 0:
    									strcpy(outString, "So");
    									break;
    								case 1:
    									strcpy(outString, "Mo");
    									break;
    								case 2:
    									strcpy(outString, "Di");
    									break;
    								case 3:
    									strcpy(outString, "Mi");
    									break;
    								case 4:
    									strcpy(outString, "Do");
    									break;
    								case 5:
    									strcpy(outString, "Fr");
    									break;
    								case 6:
    									strcpy(outString, "Sa");
    									break;
    							}
    							sprintf(outString + 2, " %d.%d.%d %d:%d:%d\r", time.DayOfMonth,
    									time.Month, time.Year, time.Hours, time.Minutes,
    									time.Seconds);
    							// Send the response over USB
    							cdcSendDataInBackground((uint8_t*) outString, strlen(outString),
    									CDC0_INTFNUM, 0);
    						}
    						else if (strstr(wholeString, "conf: "))
    						{
    							char * ptr;
    							ptr = strchr(wholeString, ':') + 1;
    							time.Year = atoi(ptr);
    							ptr = strchr(ptr, '-') + 1;
    							time.Month = atoi(ptr);
    							ptr = strchr(ptr, '-') + 1;
    							time.DayOfMonth = atoi(ptr);
    							ptr = strchr(ptr, '-') + 1;
    							time.DayOfWeek = atoi(ptr);
    							ptr = strchr(ptr, '-') + 1;
    							time.Hours = atoi(ptr);
    							ptr = strchr(ptr, ':') + 1;
    							time.Minutes = atoi(ptr);
    							ptr = strchr(ptr, ':') + 1;
    							time.Seconds = atoi(ptr);
    							RTC_B_holdClock(RTC_B_BASE);
    							RTC_B_initCalendar(RTC_B_BASE, &time, RTC_B_FORMAT_BINARY);
    							RTC_B_startClock(RTC_B_BASE);
    						}
    						else
    						{
    
    							// Prepare the outgoing string
    							strcpy(outString, "No such command!\r");
    
    							// Send the response over USB
    							cdcSendDataInBackground((uint8_t*) outString, strlen(outString),
    									CDC0_INTFNUM, 0);
    						}
    
    						// Clear the string in preparation for the next one
    						for (i = 0; i < MAX_STR_LENGTH; i++)
    						{
    							wholeString[i] = 0x00;
    						}
    					}
    					bCDCDataReceived_event = FALSE;
    				}
    				break;
    
    				// These cases are executed while your device is disconnected from
    				// the host (meaning, not enumerated); enumerated but suspended
    				// by the host, or connected to a powered hub without a USB host
    				// present.
    			case ST_PHYS_DISCONNECTED:
    			case ST_ENUM_SUSPENDED:
    			case ST_PHYS_CONNECTED_NOENUM_SUSP:
    
    				//Turn off LED P1.0
    				GPIO_setOutputLowOnPin(LED_PORT, LED_PIN);
    				__bis_SR_register(LPM3_bits + GIE);
    				_NOP();
    				break;
    
    				// The default is executed for the momentary state
    				// ST_ENUM_IN_PROGRESS.  Usually, this state only last a few
    				// seconds.  Be sure not to enter LPM3 in this state; USB
    				// communication is taking place here, and therefore the mode must
    				// be LPM0 or active-CPU.
    			case ST_ENUM_IN_PROGRESS:
    			default:
    				;
    		}
    
    	}  // while(1)
    } // main()

    I found out that  LOKBAK bit gets set somehow after entering the main while loop.

    Any Ideas how this can be ?

    Cheers

    Ness

  • The LOCKBAK bit sewers the connection between the control registers and the controlled hardware.
    So the registers lose content while not powered (to save some nA), but it has no effect on the hardware that is still powered.
    When power returns, the MSP boots, the start ode is executed and will initialize most of the registers. But this won’t affect the (still running) RTC, until LOCKBAK is cleared. SO your app can check LOCKBAK, and if it is set, it can skip part of the init, so the required changes to the default are made, but without all the stuff that would reset e.g. the time. Then LOCKBAK is cleared and all the settings take effect (or rather not, since they should be the same that was already there).

    LOCKBAK should be reset by BAK_BATT_unlock… (at least that’s what I’d expect from the name) After this, I would expect LOCKBAK clear and only be set again on a supply failure.

    However, if the SVS isn’t programmed properly, it might be that the system switches to backup mode (setting LOCKBAK) while no reset is issued. And if the MSP doesn’t crash (because it was just a short dip in the supply, and VCORE was stable enough), then it will continue while LOCKBAK was set unnoticed.

    In other words: if LOCKBAK is set during operation, this most likely indicates that the SVS has detected a brownout (not to be confused with the basic brownout detection) but was not programmed to trigger a reset. So only a switch to the backup was done.

  • Hello Jens-Michael,

    Sounds very possible,
    yet after giving more attention to the topic, and re-reading the corresponding sections here is what I came out with:
    I started a debugging section, jumped till after the the PMM_setVCore(PMM_CORE_LEVEL_3); command line and checked the registers:

    PMMCTL0
    PMMCOREV 11                Supports up to 20 MHz operation but clock is just set to 8.

    SVSMHCTL
    SVMHE          1                SVM high side enable
    SVSHE          1                SVS high side enable
    SVSHRVL    11               Reset voltage level 2.10 - 2.23 V
    SVSMHRRL 11                Reset relase   2.20 - 2.33 V

    PMMRIE
    SVSHPE       1                 SVS high side POR enable


    these are the default settings.

    SVSMHCTL hold the recommended settings in the family guide.

    The DVCC is 3.3 V coming out of the LDO of the USB module of the msp430

    Now, when is the lockback bit set ? Wehn voltage falls below 2.10 - 2.23 V or 2.20 - 2.33 V ?

    Do i got this right?: once the voltage drops below 2.10 the device resets ?

    The value of the SVSMHCTL is 0x4703.
    Am i missing something here ?

    Thanks a lot for your attention and help

    NBA

  • Some updates,

    I updated/reduced the code to isolate the problem:


    /* --COPYRIGHT--,BSD
     * Copyright (c) 2014, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    /*  
     * ======== main.c ========
     * LED Control Demo:
     *
     * This example implements a simple command-line interface, where the command 
     * is ended by pressing ‘return’.  It accepts four "commands":
     * "LED ON"
     * "LED OFF"
     * "LED TOGGLE - SLOW"
     * "LED TOGGLE – FAST"
     +----------------------------------------------------------------------------+
     * Please refer to the Examples Guide for more details.
     * ---------------------------------------------------------------------------*/
    #include <string.h>
    
    #include "driverlib.h"
    
    #include "USB_config/descriptors.h"
    #include "USB_API/USB_Common/device.h"
    #include "USB_API/USB_Common/usb.h"                 // USB-specific functions
    #include "USB_API/USB_CDC_API/UsbCdc.h"
    #include "USB_app/usbConstructs.h"
    
    /*
     * NOTE: Modify hal.h to select a specific evaluation board and customize for
     * your own board.
     */
    #include "hal.h"
    #include <cstdlib>
    #include <cstdio>
    
    // Function declarations
    uint8_t retInString(char* string);
    void initTimer(void);
    
    // Global flags set by events
    volatile uint8_t bCDCDataReceived_event = FALSE; // Indicates data has been rx'ed
    // without an open rx operation
    
    #define MAX_STR_LENGTH 64
    char wholeString[MAX_STR_LENGTH] = ""; // Entire input str from last 'return'
    
    // Set/declare toggle delays
    uint16_t SlowToggle_Period = 20000 - 1;
    uint16_t FastToggle_Period = 1000 - 1;
    Calendar time;
    
    /*  
     * ======== main ========
     */
    void main(void)
    {
    	WDT_A_hold(WDT_A_BASE); // Stop watchdog timer
    	// Minumum Vcore setting required for the USB API is PMM_CORE_LEVEL_2 .
    #ifndef DRIVERLIB_LEGACY_MODE
    	PMM_setVCore(PMM_CORE_LEVEL_3);
    #else
    	PMM_setVCore(PMM_BASE, PMM_CORE_LEVEL_3);
    #endif
    	initPorts();           // Config GPIOS for low-power (output low)
    	initClocks(20000000);   // Config clocks. MCLK=SMCLK=FLL=8MHz; ACLK=REFO=32kHz
    	__delay_cycles(20000000);
    	initTimer();           // Prepare timer for LED toggling
    	USB_setup(TRUE, TRUE); // Init USB & events; if a host is present, connect
    	__enable_interrupt();  // Enable interrupts globally
    	RTC_B_startClock(RTC_B_BASE);
    	while (BAK_BATT_UNLOCKFAILURE == BAK_BATT_unlockBackupSubSystem(BAK_BATT_BASE))
    		;
    	while (1)
    	{
    		uint8_t i;
    
    		// Check the USB state and directly main loop accordingly
    		switch (USB_connectionState())
    		{
    			// This case is executed while your device is enumerated on the
    			// USB host
    			case ST_ENUM_ACTIVE:
    
    				// If true, some data is in the buffer; begin receiving a cmd
    				if (bCDCDataReceived_event)
    				{
    
    					// Holds the new addition to the string
    					char pieceOfString[MAX_STR_LENGTH] = "";
    
    					// Holds the outgoing string
    					char outString[MAX_STR_LENGTH] = "";
    
    					// Add bytes in USB buffer to the string
    					cdcReceiveDataInBuffer((uint8_t*) pieceOfString, MAX_STR_LENGTH,
    							CDC0_INTFNUM); // Get the next piece of the string
    
    					// Append new piece to the whole
    					strcat(wholeString, pieceOfString);
    
    					// Has the user pressed return yet?
    					if (retInString(wholeString))
    					{
    
    						if ( ! (strcmp(wholeString, "time?")))
    						{
    							time = RTC_B_getCalendarTime(RTC_B_BASE);
    							switch (time.DayOfWeek)
    							{
    								case 0:
    									strcpy(outString, "So");
    									break;
    								case 1:
    									strcpy(outString, "Mo");
    									break;
    								case 2:
    									strcpy(outString, "Di");
    									break;
    								case 3:
    									strcpy(outString, "Mi");
    									break;
    								case 4:
    									strcpy(outString, "Do");
    									break;
    								case 5:
    									strcpy(outString, "Fr");
    									break;
    								case 6:
    									strcpy(outString, "Sa");
    									break;
    							}
    							sprintf(outString + 2, " %d.%d.%d %d:%d:%d\r", time.DayOfMonth,
    									time.Month, time.Year, time.Hours, time.Minutes,
    									time.Seconds);
    							if (BAKCTL & LOCKBAK)
    							{
    								sprintf(strchr(outString, '\r') + 1, "LOCKBAK is ON\rPMMIFG : %d\r", PMMIFG);
    							}
    							else
    							{
    								sprintf(strchr(outString, '\r') + 1, "LOCKBAK is OFF\r");
    							}
    							// Send the response over USB
    							cdcSendDataInBackground((uint8_t*) outString, strlen(outString),
    									CDC0_INTFNUM, 0);
    						}
    						else if (strstr(wholeString, "conf: "))
    						{
    							char * ptr;
    							ptr = strchr(wholeString, ':') + 1;
    							time.Year = atoi(ptr);
    							ptr = strchr(ptr, '-') + 1;
    							time.Month = atoi(ptr);
    							ptr = strchr(ptr, '-') + 1;
    							time.DayOfMonth = atoi(ptr);
    							ptr = strchr(ptr, '-') + 1;
    							time.DayOfWeek = atoi(ptr);
    							ptr = strchr(ptr, '-') + 1;
    							time.Hours = atoi(ptr);
    							ptr = strchr(ptr, ':') + 1;
    							time.Minutes = atoi(ptr);
    							ptr = strchr(ptr, ':') + 1;
    							time.Seconds = atoi(ptr);
    							RTC_B_holdClock(RTC_B_BASE);
    							RTC_B_initCalendar(RTC_B_BASE, & time, RTC_B_FORMAT_BINARY);
    							RTC_B_startClock(RTC_B_BASE);
    						}
    						else
    						{
    
    							// Prepare the outgoing string
    							strcpy(outString, "No such command!\r");
    
    							// Send the response over USB
    							cdcSendDataInBackground((uint8_t*) outString, strlen(outString),
    									CDC0_INTFNUM, 0);
    						}
    
    						// Clear the string in preparation for the next one
    						for (i = 0; i < MAX_STR_LENGTH; i++)
    						{
    							wholeString[i] = 0x00;
    						}
    					}
    					bCDCDataReceived_event = FALSE;
    				}
    				break;
    
    				// These cases are executed while your device is disconnected from
    				// the host (meaning, not enumerated); enumerated but suspended
    				// by the host, or connected to a powered hub without a USB host
    				// present.
    			case ST_PHYS_DISCONNECTED:
    			case ST_ENUM_SUSPENDED:
    			case ST_PHYS_CONNECTED_NOENUM_SUSP:
    
    				//Turn off LED P1.0
    				GPIO_setOutputLowOnPin(LED_PORT, LED_PIN);
    				__bis_SR_register(LPM3_bits + GIE);
    				_NOP();
    				break;
    
    				// The default is executed for the momentary state
    				// ST_ENUM_IN_PROGRESS.  Usually, this state only last a few
    				// seconds.  Be sure not to enter LPM3 in this state; USB
    				// communication is taking place here, and therefore the mode must
    				// be LPM0 or active-CPU.
    			case ST_ENUM_IN_PROGRESS:
    			default:
    				;
    		}
    
    	}  // while(1)
    } // main()
    
    /*  
     * ======== UNMI_ISR ========
     */
    #if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__)
    #pragma vector = UNMI_VECTOR
    __interrupt void UNMI_ISR(void)
    #elif defined(__GNUC__) && (__MSP430__)
    void __attribute__ ((interrupt(UNMI_VECTOR))) UNMI_ISR (void)
    #else
    #error Compiler not found!
    #endif
    {
    	switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG))
    	{
    		case SYSUNIV_NONE:
    			__no_operation();
    			break;
    		case SYSUNIV_NMIIFG:
    			__no_operation();
    			break;
    		case SYSUNIV_OFIFG:
    #ifndef DRIVERLIB_LEGACY_MODE
    			UCS_clearFaultFlag(UCS_XT2OFFG);
    			UCS_clearFaultFlag(UCS_DCOFFG);
    			SFR_clearInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT);
    #else
    			UCS_clearFaultFlag(UCS_BASE, UCS_XT2OFFG);
    			UCS_clearFaultFlag(UCS_BASE, UCS_DCOFFG);
    			SFR_clearInterrupt(SFR_BASE, SFR_OSCILLATOR_FAULT_INTERRUPT);
    
    #endif
    			break;
    		case SYSUNIV_ACCVIFG:
    			__no_operation();
    			break;
    		case SYSUNIV_BUSIFG:
    			// If the CPU accesses USB memory while the USB module is
    			// suspended, a "bus error" can occur.  This generates an NMI.  If
    			// USB is automatically disconnecting in your software, set a
    			// breakpoint here and see if execution hits it.  See the
    			// Programmer's Guide for more information.
    			SYSBERRIV = 0; //clear bus error flag
    			USB_disable(); //Disable
    	}
    }
    
    /*  
     * ======== retInString ========
     */
    // This function returns true if there's an 0x0D character in the string; and if
    // so, it trims the 0x0D and anything that had followed it.
    uint8_t retInString(char* string)
    {
    	uint8_t retPos = 0, i, len;
    	char tempStr[MAX_STR_LENGTH] = "";
    
    	strncpy(tempStr, string, strlen(string));  // Make a copy of the string
    	len = strlen(tempStr);
    
    	// Find 0x0D; if not found, retPos ends up at len
    	while ((tempStr[retPos] != 0x0A) && (tempStr[retPos] != 0x0D)
    			&& (retPos++ < len))
    		;
    
    	// If 0x0D was actually found...
    	if ((retPos < len) && (tempStr[retPos] == 0x0D))
    	{
    		for (i = 0; i < MAX_STR_LENGTH; i++)
    		{ // Empty the buffer
    			string[i] = 0x00;
    		}
    
    		//...trim the input string to just before 0x0D
    		strncpy(string, tempStr, retPos);
    
    		//...and tell the calling function that we did so
    		return (TRUE);
    
    		// If 0x0D was actually found...
    	}
    	else if ((retPos < len) && (tempStr[retPos] == 0x0A))
    	{
    		// Empty the buffer
    		for (i = 0; i < MAX_STR_LENGTH; i++)
    		{
    			string[i] = 0x00;
    		}
    
    		//...trim the input string to just before 0x0D
    		strncpy(string, tempStr, retPos);
    
    		//...and tell the calling function that we did so
    		return (TRUE);
    	}
    	else if (tempStr[retPos] == 0x0D)
    	{
    		for (i = 0; i < MAX_STR_LENGTH; i++)
    		{  // Empty the buffer
    			string[i] = 0x00;
    		}
    		// ...trim the input string to just before 0x0D
    		strncpy(string, tempStr, retPos);
    		// ...and tell the calling function that we did so
    		return (TRUE);
    	}
    	else if (retPos < len)
    	{
    		for (i = 0; i < MAX_STR_LENGTH; i++)
    		{  // Empty the buffer
    			string[i] = 0x00;
    		}
    
    		//...trim the input string to just before 0x0D
    		strncpy(string, tempStr, retPos);
    
    		//...and tell the calling function that we did so
    		return (TRUE);
    	}
    
    	return (FALSE); // Otherwise, it wasn't found
    }
    
    /*
     * ======== initTimer ========
     */
    void initTimer(void)
    {
    	// Start timer
    	TIMER_A_clearTimerInterruptFlag(TIMER_A0_BASE);
    
    	TIMER_A_configureUpMode(TIMER_A0_BASE, TIMER_A_CLOCKSOURCE_ACLK,
    			TIMER_A_CLOCKSOURCE_DIVIDER_1, 0, TIMER_A_TAIE_INTERRUPT_DISABLE,
    			TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE, TIMER_A_DO_CLEAR);
    }
    
    /*
     * ======== TIMER1_A0_ISR ========
     */
    #if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__)
    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void TIMER0_A0_ISR(void)
    #elif defined(__GNUC__) && (__MSP430__)
    void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TIMER0_A0_ISR (void)
    #else
    #error Compiler not found!
    #endif
    {
    	GPIO_toggleOutputOnPin(LED_PORT, LED_PIN);
    }
    
    //Released_Version_4_10_02
    

    Now I get two distinct behaviors:

    When the debugger is attached,  the lockbak bit is not set again during execution and i get to fetch the time correctly.

    When i stop debugging and just plug the board to the computer, although, there is one second delay before clearing the LOCKBAK bit for the first time, this one is set again after that and I cannot get the time.

    Any ideas ?

  • Hi there,

    I finally got it, and I must say I am quite surprised:

    Jens_Michael was absolutely right:

    In other words: if LOCKBAK is set during operation, this most likely indicates that the SVS has detected a brownout (not to be confused with the basic brownout detection) but was not programmed to trigger a reset. So only a switch to the backup was done.

    Since I did not change the PMM registers except the PMM_setVCore(PMM_CORE_LEVEL_3); call,
    calling PMM_enableSvsHReset(); didnt changed the behavior.

    But as I looked to page 105 of the family guide (slau208), I noticed that I need either "High power mode" ( I don't know what that is) or the "SVSHMD" to make allow the SVSh output to propagate and trigger a POR.

    I had to do this by hand. Maybe a warning should be added to the driverlib, function so people will pay more attention to this.

  • Greetings... I have a board with a F5636 on it and I'm seeing the exact same problem:  With a debugger attached I clear LOCKBAK and it says cleared.  Just powering on my board with no debugger,  I'm seeing LOCKBAK set again after I clear it.

    The first thing I have to wonder is what causes this.  I'm guessing there is an issue with my hardware where Vcc gets high enough for the processor to start and then there is a dip before it stabilizes.  I'm investing this further.

    But the other thing I'm wondering is how your solution solves the problem.  It sounds like you're setting SVSHMD in the SVSHMCTL register? Table 2-18 in slau208 says this allows the SVSH interrupt flag to be set when in LPM2, 3 or 4.  What if you're not in a low power mode?  Even if you are, it sounds like you're causing a POR to occur when Vcc dips?  

    I'm kind of new to what you can and can't do with the SVS.  Any light you can shed on your solution would be appreciated.  Maybe even the code you added to fix your problem "by hand".

    Thanks...

  • Hi.

    I'm not really the master at this but I just happened to have found a solution, a bad one for sure, but it worked:

    Like i said look at the page 105 to the Logic gates, and figure out how the settings should be so
    so set SVSHIFG and the corresponding pro are triggered:

    I guess high power mode means no LPM, so this should work already, but somehow it didn't :-(
    Even when I couldn't find anything missing with the registers state when debugging....

    So I used the brute force method: having SVSHMD enabled makes sure that the Or gate yields 1 out.

    With SVSHE = 1 ( naturally) we are sure to have a 1 on the 3 pins AND gate and so on....

    And then, as if my interrupts could suddenly propagate the correct way....

    The other explanation would be, the LOCKBAK bit gets set for some other reason, or the reset does not propagate for some other reason....

    So far i understand only the SVSH is responsible for the lock bak behavior....

    I wich I could help better...

    Ness

  • Thanks for your reply... So the problem we're trying to solve is LOCKBAK settings again after its been cleared in the firmware.    I'm not sure I follow how what you describe accomplishes that.   It looks like you're settings things up so that SVSHIFG and POR get set.  I don't understand how that prevents LOCKBAK from setting again.  Doesn't the POR cause the MSP430 to completely restart?

    Thanks...

  • Hi,

    LOCKBAK bit gets set when VCC dips.

    If the msp430 restarts every time the VCC dips (which causes the LOCKBAK bit to be set),
    you won't have to clear the LOCKBAK bit twice in your code.

    Now there is 2 different questions:
    Is the SVSH the only one responsible for setting the LOCKBAK bit?
    How to make the MSP430 reset when VCC dips?

    I carried on trying to make the MSP430 reset when a dip in vcc occurs, that's what i explained.
    But im sure there is a better way to make it happen.

    Cheers

  • To prevent glitches during supply ramp-up, an R/C combo on RST is suggested. The slower Vcc is rising (or the more sensitive it is to current changes during ramp-up) the larger the R/C timer constant should be. On most 5x/6x family MSPs, there is an internal pull-up active by default on RST, so only the capacitor is required. OTOH, when using SBW, the capacitor size is limited to 2.2nF (I usually use 100nF and 4-wire JTAG)

**Attention** This is a public forum