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.

MSP430F6638 Battery Backup RTC_B

Other Parts Discussed in Thread: MSP430F6638, MSP430F6736

Battery backup system retained RTC_B register when primary power fail.

Does the RTC_B still running? Is Date and Time still updating in this case?

  • I have same question. I can't do debugging because of seperating power system.

    Please explain the concept of using RTC_B and battery backup! 

    I want to get the example source.

    Thanks.

  • Fanmook Leem said:
    Please explain the concept of using RTC_B and battery backup! 

    It's explaine din the RTC_B chapter and the Battery Backup System chapter in the 5x family users guide.

  • Thank you your reply

    I also am referting to the user guide for developing. 

    Currently under development, the system operates in the active mode.

    If the system's power is cut off, the RTC is alive only.

    But I do not know when and how to go into LPM4.5.

    And when the power is turned on, waht should I do?

  • Fanmook Leem said:
    But I do not know when and how to go into LPM4.5.

    When? Well, when you like. How? See Chapter 2.2.7 (PMM Operation: LPM3.5/4.5) in the users guide.

    Fanmook Leem said:
    And when the power is turned on, waht should I do?

    You should check whether this was a normal power-on or a return from LPMx.5. THis is indicated by the PMMLPM5IFG bit in PMMIFG or by reading the reset vector word (SYSRSTIV). If it is a wakeup form LPMx.5, then all port operations do not affect the physical port pins (to give you time to reconfigure them as all register contents are lost) until you clear the LOCKLPM5 bit in PM5CTL0. (I dimly remember some errata here, so check your MSPs errata sheet)

  • Thank you!

    II tried test as your comment.

    Source is attached below.

    By turning the power off and on again, lpm_flag should be 1.However, it is always 0.

    Please know what my mistake?

     

    5224.Rtc_test.c
    #include "inc/hw_memmap.h"
    #include "rtc.h"
    #include "sfr_sys.h"
    #include "wdt.h"
    #include "gpio.h"
    #include "ucs.h"
    #include "pmm.h"
    
    void EnterLPM45(void);
    void WakeUpLPM45(void);
    void SetBAKMEM(void);
    
    volatile Calendar newTime;
    Calendar currentTime;
    
    void main (void)
    {
    	int	lpm_flag = 0;
    	
    	WDT_hold(__MSP430_BASEADDRESS_WDT_A__);
    
    	while(BAKCTL & LOCKBAK)                   // Unlock XT1 pins for operation
    		BAKCTL &= ~(LOCKBAK);  
    	
    	if(SYSRSTIV == 0x08) {
    		PMMCTL0_H = PMMPW_H;                      // open PMM
    		PM5CTL0 &= ~LOCKIO;                       // Clear LOCKBAK and enable ports
    		PMMCTL0_H = 0x00;                         // close PMM
    
    		//Initialize LFXT1
    		UCS_LFXT1Start(__MSP430_BASEADDRESS_UCS__,
    			UCS_XT1_DRIVE3,
    			UCS_XCAP_3
    			);
    
    		//Monitor high side is turned on
    		PMM_enableSvmH(__MSP430_BASEADDRESS_PMM__);
    
    		PMMCTL0_H = PMMPW_H;                      // open PMM
    		SVSMHCTL |= SVSHMD + 5;                       // Clear LOCKBAK and enable ports
    		PMMCTL0_H = 0x00;                         // close PMM
    
    		PMM_enableSvmHInterrupt(__MSP430_BASEADDRESS_PMM__);
    		
    		lpm_flag = 1;
    	}
    	else {
    		//Initialize LFXT1
    		UCS_LFXT1Start(__MSP430_BASEADDRESS_UCS__,
    			UCS_XT1_DRIVE3,
    			UCS_XCAP_3
    			);
    		
    		//Setup Current Time for Calendar
    		currentTime.Seconds    = 0x00;
    		currentTime.Minutes    = 0x26;
    		currentTime.Hours      = 0x13;
    		currentTime.DayOfWeek  = 0x03;
    		currentTime.DayOfMonth = 0x20;
    		currentTime.Month      = 0x07;
    		currentTime.Year       = 0x2011;
    		
    		//Initialize Calendar Mode of RTC
    		/*
    		* Base Address of the RTC_A
    		* Pass in current time, intialized above
    		* Use BCD as Calendar Register Format
    		*/
    		RTC_calendarInit(__MSP430_BASEADDRESS_RTC_B__,
    			currentTime,
    			RTC_FORMAT_BCD);
    		
    		//Setup Calendar Alarm for 5:00pm on the 5th day of the week.
    		//Note: Does not specify day of the week.
    		//RTC_setCalendarAlarm(__MSP430_BASEADDRESS_RTC_B__,
    		//    0x00,
    		//    0x17,
    		//    RTC_ALARMCONDITION_OFF,
    		//    0x05);
    		
    		//Specify an interrupt to assert every minute
    		//RTC_setCalendarEvent(__MSP430_BASEADDRESS_RTC_B__,
    		//    RTC_CALENDAREVENT_MINUTECHANGE);
    		
    		//Enable interrupt for RTC Ready Status, which asserts when the RTC
    		//Calendar registers are ready to read.
    		//Also, enable interrupts for the Calendar alarm and Calendar event.
    		//RTC_enableInterrupt(__MSP430_BASEADDRESS_RTC_B__,
    		//    RTCRDYIE + RTCTEVIE + RTCAIE );
    		RTC_enableInterrupt(__MSP430_BASEADDRESS_RTC_B__, RTCRDYIE + RTCOFIE );
    		//RTC_definePrescaleEvent( __MSP430_BASEADDRESS_RTC_B__, RTC_PRESCALE_1, RTC_PSEVENTDIVIDER_128 );
    		//RTC_enableInterrupt(__MSP430_BASEADDRESS_RTC_B__, RTC_PRESCALE_TIMER1_INTERRUPT );
    		
    		//Start RTC Clock
    		RTC_startClock(__MSP430_BASEADDRESS_RTC_B__);
    		
    		//Monitor high side is turned on
    		PMM_enableSvmH(__MSP430_BASEADDRESS_PMM__);
    
    		PMMCTL0_H = PMMPW_H;                      // open PMM
    		SVSMHCTL |= SVSHMD + 5;                       // Clear LOCKBAK and enable ports
    		PMMCTL0_H = 0x00;                         // close PMM
    
    		PMM_enableSvmHInterrupt(__MSP430_BASEADDRESS_PMM__);
    		
    		EnterLPM45();
    	}
    
    	//Set P1.0 to output direction
    	GPIO_setAsOutputPin(__MSP430_BASEADDRESS_PORT7_R__,
    		GPIO_PORT_P7,
    		GPIO_PIN4+GPIO_PIN5
    		);
    	
    	
    	GPIO_setAsPeripheralModuleFunctionInputPin(__MSP430_BASEADDRESS_PORT7_R__,
    		GPIO_PORT_P7,
    		GPIO_PIN0 + GPIO_PIN1
    		);
    	
    	//Enter LPM3 mode with interrupts enabled
    	while(1) {
    		if( lpm_flag ) {
    			GPIO_toggleOutputOnPin(__MSP430_BASEADDRESS_PORT7_R__,
    				GPIO_PORT_P7,
    				GPIO_PIN5);
    			
    			__delay_cycles(100000);
    		}
    	}
    }
    
    #pragma vector=RTC_VECTOR
    __interrupt void RTC_ISR (void)
    {
    	while(BAKCTL & LOCKIO)                    // Unlock backup system
    	BAKCTL &= ~(LOCKIO); 
    	
    	switch (__even_in_range(RTCIV,16)){
    	case 0: break;  //No interrupts
    	case 2:         //RTCRDYIFG
    		//Toggle P1.0 every second
    		GPIO_toggleOutputOnPin(__MSP430_BASEADDRESS_PORT7_R__,
    			GPIO_PORT_P7,
    			GPIO_PIN4);
    		
    		PM5CTL0 &= ~LOCKLPM5;
    		LPM4_EXIT;
    		break;
    	case 4:         //RTCEVIFG
    		//Interrupts every minute
    		__no_operation();
    		
    		//Read out New Time a Minute Later BREAKPOINT HERE
    		newTime = RTC_getCalendarTime(__MSP430_BASEADDRESS_RTC_B__);
    		break;
    	case 6:         //RTCAIFG
    		//Interrupts 5:00pm on 5th day of week
    		__no_operation();
    		break;
    	case 8: break;  //RT0PSIFG
    	case 10: //RT1PSIFG
    		//Toggle P1.0 every second
    		GPIO_toggleOutputOnPin(__MSP430_BASEADDRESS_PORT7_R__,
    			GPIO_PORT_P7,
    			GPIO_PIN4);
    		
    		//RTCPS1CTL &= ~RT1PSIFG;
    		
    		PM5CTL0 &= ~LOCKLPM5;
    		//LPM4_EXIT;
    		break;
    	case 12:	// RTCOFIFG 
    		__no_operation();
    		break; //
    	case 14: break; //Reserved
    	case 16: break; //Reserved
    	default: break;
    	}
    	
    	//RTCIV = 0;
    }
    
    #pragma vector=SYSNMI_VECTOR
    __interrupt void SysNMI_ISR (void)
    {
    	switch( SYSSNIV ) {
    	case	2 :	// SVMLIFG
    		__no_operation();
    		break;
    	case	4 :	// SVMHIFG
    		EnterLPM45();
    		__no_operation();
    		break;
    	case	6 :	// SVSMLDLYIFG
    		__no_operation();
    		break;
    	case	8 :	// SVSMHDLYIFG
    		__no_operation();
    		break;
    	case	10 :	// VMAIFG
    		__no_operation();
    		break;
    	case	12 :	// JMBINIFG
    		__no_operation();
    		break;
    	}
    }
    
    void EnterLPM45(void)
    {
      __enable_interrupt();
      PMMCTL0_H = PMMPW_H;                      // Open PMM Registers for write and set
      PMMCTL0_L |= PMMREGOFF;                   // PMMREGOFF
      __bis_SR_register(LPM4_bits);             // Enter LPM4.5 mode with interrupts
      __no_operation();                         // enabled
    }
    
    void WakeUpLPM45(void)
    {
      PMMCTL0_H = PMMPW_H;                      // open PMM
      PM5CTL0 &= ~LOCKIO;                       // Clear LOCKBAK and enable ports
      PMMCTL0_H = 0x00;                         // close PMM
    
      // Restore Port settings
      P1OUT = 0x00;P2OUT = 0x00;P3OUT = 0x00;P4OUT = 0x00;P5OUT = 0x00;P6OUT = 0x00;
      P7OUT = 0x00;P8OUT = 0x00;P9OUT = 0x00;PJOUT = 0x00;
      P1DIR = 0xFF;P2DIR = 0xFF;P3DIR = 0xFF;P4DIR = 0xFF;P5DIR = 0xFF;P6DIR = 0xFF;
      P7DIR = 0xFF;P8DIR = 0xFF;P9DIR = 0xFF;PJDIR = 0xFF; 
      
      // Restore Clock so that BAKMEM will be read
      UCSCTL6 &= ~(XT1OFF);                     // XT1 On
      UCSCTL6 |= XCAP_3;                        // Internal load cap
      while(BAKCTL & LOCKBAK)                   // Unlock XT1 pins for operation
         BAKCTL &= ~(LOCKBAK);  
      do
      {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                                // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                      // Clear fault flags
      }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag   
    }
    
    void SetBAKMEM(void)
    {
      // Setup Clock
      UCSCTL6 &= ~(XT1OFF);                     // XT1 On
      UCSCTL6 |= XCAP_3;                        // Internal load cap
      while(BAKCTL & LOCKBAK)                   // Unlock XT1 pins for operation
         BAKCTL &= ~(LOCKBAK);  
      do
      {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                                // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                      // Clear fault flags
      }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
    
      // Set backup RAM values
      BAKMEM0 = 0x0000;
      BAKMEM1 = 0x1111;
      BAKMEM2 = 0x2222;
      BAKMEM3 = 0x3333;
      
      // Turn off Clock for LPM4.5 operation
      UCSCTL6 |= XT1OFF;                        // XT1 Off
    }
    

  • One thing that might happen is that your code you execute when SYSRSTIV == 0x08 is causing another reset, maybe by the SVM you program. Then SYSRSTIV is of course not 0x08 anymore.

    Keep in mind that in LPM4.5 everything is gone, except the port interrupt logic. I'm not even sure whether the SVM interrupt works in LPM4.5. I only know of the port interrupts.
    For RTC working, LPM3.5 is to be used Then the RTC alarm should work also for wakeup..

    So before unlocking the ports, you'll have to init the port registers or they will fallback to power-on defaults as soon as you release the lock. Thsi is if you have e.g. some port pins as outputs and they must not switch to input just because the MSP is waking from LPM4.5

    I don't see you using WakeUpLPM45, which was apparently written to do exactly this.

    In addition, I'm not sure whether 0x08 is the first result returned by SYSRSTIV. Yu should loop reading this register until you either get 0x08 or 0x00 result. In addition, PMMLPM5IFG is available in PMM register.

    Your combination of using the backup, the RTC and LPMx.5 is combining three aspects of the MSP430 which are each a challenge of its own.
    Maybe you should break down your work into mastering each one on its own before trying to do all three together.

  • Like you say, I think it is important to master.

    I newly applied to the RTC_B and the battery backup in msp430f6638.

    I usually see  examples of msp430f66xx.

    'msp430f66xx_bakmem.c' is a good one about battery backup in the examples.

    But this examle normally works by port event during power on.

    I want to get a example that work when power on and off, if possible.

    Thank you.

  • Hi

    just in case someone landed here again, i have a working and tested solution described in the following wiki:

    http://processors.wiki.ti.com/index.php/MSP430_-_Running_RTC_with_Battery_Backup_Module

  • Does this implementation work well with RTC_C module in the device MSP430F6736 ?

  • The MSP430F6736 has an auxiliary supply system (AUX), not the battery backup module (BAK). There are other differences between RTC_B and RTC_C. So I doubt the solution for the problem above will help you.
    Note that AUXVCC3 powers the RTC and the crystal. If it isn’t powered, both won’t operate.

  • Hi Jens,

    As you mentioned I have already powered the crystal and RTC using the AUXVCC3. The problem is when the main supply is off, sometimes my RTC is working and sometimes it is not. When it is not working i can see it is holding the old calendar values.

    My suspicion is does a power down can set the RTCHOLD bit  by anyway so that RTC is not counting and keeps the old value ?

  • When main supply is on, it is always working? Maybe there’s an external influence form VCC to AUXVCC3. Is AUXVCC3 charged while main power is on? So there is a voltage drop when VCC goes off.
    Check the crystal datasheet for the required load capacitance. If it is not met, then the crystal may run unstable.

    A power-down cannot set RTCHOLD. However, RTCHOLD is set by a POR. Are you sure the MSP isn’t doing a reset when main power returns? The calendar registers are not affected by a reset, so if they do not lose their content due to a complete power failure (including backup), they will stay unchanged, but RTCHHOLD and the other control bits are reset to defaults.

    A misconfigured SVS could be the cause.
    On some MSPs, a fast rise of VCC may also trigger a POR, but I don’t see this erratum in the 6736 datasheet.

**Attention** This is a public forum