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.
Hi Team,
I'm using MSP430F5659 in my product, I'm getting updated date and time while main power is available(Coin cell battery also connected to VBat) there is no issue.
But whenever i turned off main power that time i'm not getting updated date and time. I'm getting before main power off time and date.
Below are the settings for RTC-B
void Initialize_RTC_B(void)
{
/ / Unlock battery backup system
while(BattBak_unlockBackupSubSystem(BAK_BATT_BASE));
// Initializes the LFXT1 crystal oscillator in low frequency mode
UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);
/* 1-0 RTCTEVx RW 0h Real-time clock time interrupt event
00b = Minute changed
01b = Hour changed
10b = Every day at midnight (00:00)
11b = Every day at noon (12:00) */
//Specify an interrupt to assert every minute
RTC_B_setCalendarEvent(RTC_B_BASE,
RTC_B_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_B_clearInterrupt(RTC_B_BASE,
RTCRDYIFG + RTCTEVIFG + RTCAIFG);
RTC_B_enableInterrupt(RTC_B_BASE,
RTCRDYIE + RTCTEVIE + RTCAIE);
//Start RTC Clock
RTC_B_startClock(RTC_B_BASE);
// interrupts enabled
__bis_SR_register(GIE);
__no_operation();
}
//******************************************************************************
//
//This is the RTC_B interrupt vector service routine.
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=RTC_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(RTC_VECTOR)))
#endif
void RTC_B_ISR(void)
{
// Unlock backup system
while(BattBak_unlockBackupSubSystem(BAK_BATT_BASE));
switch(__even_in_range(RTCIV,16))
{
case 0: break; //No interrupts
case 2: //RTCRDYIFG
break;
case 4: //RTCEVIFG
//Interrupts every minute
__no_operation();
//Read out New Time a Minute Later BREAKPOINT HERE
RTC_B_getCalendarTime(RTC_B_BASE);
break;
case 6: //RTCAIFG
//Interrupts 5:00pm on 5th day of week
__no_operation();
break;
case 8: break; //RT0PSIFG
case 10: break; //RT1PSIFG
case 12: break; //Reserved
case 14: break; //Reserved
case 16: break; //Reserved
default: break;
}
}
Did I miss something?
Hi Wei,
I found one example code on forums it was working fine with my custom hardware.
I used the same RTC initialization settings to my project i'm getting Faulty Oscillator and Frequency down bits set.
If i commented the configureHardware(); ( line number 170) in RTC_Issue file (please refer attached file). I'm able to retained the RTC date and time.
If i uncommented the line number 170(configureHardware();), Unable to get the updated date and time.
Note:-
1) Increased controller frequency upto 20MHz please refer SYSINIT_Init_Micro();
2) As per 20MHz SMCLK we are implemented remaining peripherals like timers, spi, i2c and uart
/* --COPYRIGHT--,BSD * Copyright (c) 2015, 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--*/ /********************************************************************** * * RTC_B_with_Backup.c * * This program demonstrates proper usage of RTC_B with Battery Backup on * F66xx family devices. The code distinguishes between a BOR event, and * a VBAT switching event, to determine if the RTC calendar registers * should contain accurate time information and initialize the RTC * accordingly. * * Time information is relayed to the Demo_Host F5529 Launchpad over UART * to be passed back to the PC and viewed by the user. This shows that * time is retained if VBAT is present, and is lost if VBAT becomes * drained. * **********************************************************************/ #include "driverlib.h" #include "UART1.h" #include "hardwareConfig.h" volatile Calendar newTime; Calendar currentTime; #define UCS_MCLK_DESIRED_FREQUENCY_IN_KHZ 20000 #define UCS_MCLK_FLLREF_RATIO 610 #define TB0_FREQ 20000000L // SMCLK #define TB0_CLOCK ((float)CTRL_OPERATING_FREQ / 7) // for 1mse #define TB0_RELOAD(T) (unsigned int)(((float)T/1000) * TB0_CLOCK) #define TIMER_B0_VALUE 1 // milliseconds #define TIMER_B0_RELOAD TB0_RELOAD(TIMER_B0_VALUE) #define TA0_FREQ 20000000L // SMCLK #define TA0_CLOCK ((float)CTRL_OPERATING_FREQ / 7) // via TA0EX0 = 6; #define TA0_RELOAD(T) (unsigned int)(((float)T/1000) * TA0_CLOCK) #define TIMER_A0_VALUE 5 // milliseconds #define TIMER_A0_RELOAD TA0_RELOAD(TIMER_A0_VALUE) #define TIMER_A1_RELOAD_1_5_CHAR_9600 13744 #define TIMER_A1_RELOAD_3_5_CHAR_9600 32080 #define TIMER_A1_RELOAD_750us_CHAR_19200 6000 #define TIMER_A1_RELOAD_1750us_CHAR_19200 14000 //P2.0 = TXD, P2.1 = RXD const uint8_t port_mapping[] = { //Port P2: PM_UCA0TXD, PM_UCA0RXD, PM_NONE, PM_NONE, PM_NONE, PM_NONE, PM_NONE, PM_NONE }; //strings to send to host to display switching/reset detection #define TIME_LOST_STRING_LENGTH 50 #define TIME_RETAINED_STRING_LENGTH 50 #define OSC_FAULT_STRING_LENGTH 50 const unsigned char timeLostString[TIME_LOST_STRING_LENGTH] = "SRK Reset event. Time was reset.\r\n"; const unsigned char timeRetainedString[TIME_RETAINED_STRING_LENGTH] = "SRKSwitching event. Time was retained.\r\n"; const unsigned char oscFaultString[OSC_FAULT_STRING_LENGTH] = "SRKOscillator Fault. Time was reset.\r\n"; unsigned char oscFault = 0; void resetTime(void); void clearOscFault(void); void configureHardware_module(void); void main(void) { unsigned char timeLost; WDT_A_hold(WDT_A_BASE); //stop the watchdog PMM_setVCore( PMM_CORE_LEVEL_3); //change this VCORE to test with different levels/settings //We have to re-init some crystal and RTC settings before clearing LOCKBAK so that crystal/RTC won't stop if we're coming out of VBat //init crystal UCSCTL6 = XT1DRIVE_3 | XCAP_3; //set up the crystal load capacitors for 12pF //init RTC RTCCTL01 |= RTCBCD; //use RTC in BCD mode RTCCTL01 &= ~RTCHOLD; //keep RTC running when we clear LOCKBAK //erase LOCKBAK bit for crystal + RTC settings to take effect //you must erase LOCKBACK or you won't be able to check RTC flag etc while(BAKCTL & LOCKBAK) { BAKCTL &= ~(LOCKBAK); } //check if backup supply was drained or not by checking BAKMEM0, RTCOFIFG, and RTCCALS //BAKMEM0 we are checking for backup memory retention //RTCOFIFG we are checking if an oscillator fault occurred while we were on the backup supply //RTCCALS will be retained through switching event but cleared on brownout, so also indicates if RTC calendar registers retained //NOTE: RTCCTL2 setting and checking should use whatever calibration values are required for the specific device/application. RTCCALS is used as an example in this case. if((BAKMEM0 == 0xDEAD) && !(RTCCTL01 & RTCOFIFG) && (RTCCTL2 & RTCCALS)) //backup not lost { timeLost = 0; //we retained the RTC data P5DIR |= BIT2; //RTC LED re-initialize to be output (GPIO are not retained) } else //either first startup or we lost backup RAM { timeLost = 1; P5OUT &= ~BIT2; P5DIR |= BIT2; //RTC LED //Clear faults clearOscFault(); //reinitialize the RTC time resetTime(); RTCCTL2 |= RTCCALS; //this bit is retained so can be used as a check for VBAT switching BAKMEM0 = 0xDEAD; //write in the signature } //Enable interrupt for RTC Ready Status, which asserts when the RTC //Calendar registers are ready to read. RTC_B_clearInterrupt(RTC_B_BASE, RTC_B_CLOCK_READ_READY_INTERRUPT | RTC_B_OSCILLATOR_FAULT_INTERRUPT); //clear flag before enabling interrupt RTC_B_enableInterrupt(RTC_B_BASE, RTC_B_CLOCK_READ_READY_INTERRUPT | RTC_B_OSCILLATOR_FAULT_INTERRUPT); //enable ready interrupt and fault interrupt RTC_B_startClock(RTC_B_BASE); //start clock //CONFIGURE PORTS- pass the port_mapping array, start @ P2MAP01, initialize //a single port, do not allow run-time reconfiguration of port mapping P8SEL = BIT2 | BIT3; //P2.0 = TXD, P2.1 = RXD //init UART for sending time data initUART(); //Enable UART module for operation USCI_A_UART_enable(USCI_A1_BASE); configureHardware(); //output whether a reset or a switching event occurred, time lost/retained if(timeLost) { transmitString((unsigned char*)timeLostString, TIME_LOST_STRING_LENGTH); } else { transmitString((unsigned char*)timeRetainedString, TIME_RETAINED_STRING_LENGTH); } while(1) { __bis_SR_register(LPM3_bits + GIE); __no_operation(); if(oscFault) { //check until fault clears clearOscFault(); oscFault = 0; //reset time // resetTime(); //print message about osc fault and time resetting transmitString((unsigned char*)oscFaultString, OSC_FAULT_STRING_LENGTH); //restart RTC //Enable interrupt for RTC Ready Status, which asserts when the RTC //Calendar registers are ready to read. RTC_B_clearInterrupt(RTC_B_BASE, RTC_B_CLOCK_READ_READY_INTERRUPT | RTC_B_OSCILLATOR_FAULT_INTERRUPT); //clear flag before enabling interrupt RTC_B_enableInterrupt(RTC_B_BASE, RTC_B_CLOCK_READ_READY_INTERRUPT | RTC_B_OSCILLATOR_FAULT_INTERRUPT); //enable ready interrupt and fault interrupt RTC_B_startClock(RTC_B_BASE); //start clock } else { //when we wake, output the new time on the UART currentTime = newTime; //we're buffering the data in case RTC interrupts again while still sending over UART transmitString(calendarToString(currentTime), CALENDAR_STRING_LENGTH); } } } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=RTC_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(RTC_VECTOR))) #endif void RTC_B_ISR(void) { while(BAKCTL & LOCKBAK) // Unlock backup system BAKCTL &= ~(LOCKBAK); switch (__even_in_range(RTCIV, 16)) { case 0: break; //No interrupts case 2: //RTCRDYIFG P5OUT ^= BIT2; //Toggle P1.0 every second newTime = RTC_B_getCalendarTime(RTC_B_BASE); __bic_SR_register_on_exit(LPM3_bits); __no_operation(); //put breakpoint here to check on time if desired break; case 4: break; //RTCEVIFG case 6: break; //RTCAIFG case 8: break; //RT0PSIFG case 10: break; //RT1PSIFG case 12: //RTCOFIFG oscFault = 1; RTC_B_disableInterrupt(RTC_B_BASE, RTC_B_OSCILLATOR_FAULT_INTERRUPT); //disable further fault interrupts __bic_SR_register_on_exit(LPM3_bits); //wake to handle fault __no_operation(); break; case 14: break; //Reserved case 16: break; //Reserved default: break; } } //reset the time to our starting time void resetTime(void) { //Setup Current Time for Calendar currentTime.Seconds = 0x00; currentTime.Minutes = 0x30; currentTime.Hours = 0x04; currentTime.DayOfWeek = 0x01; currentTime.DayOfMonth = 0x04; currentTime.Month = 0x05; currentTime.Year = 0x2015; RTC_B_initCalendar(RTC_B_BASE, ¤tTime, RTC_B_FORMAT_BCD); } //clear oscillator faults void clearOscFault(void) { //Clear OFIFG fault flag SFRIFG1 &= ~OFIFG; //wait for crystal to stabilize while (UCSCTL7 & XT1LFOFFG) { //Clear OSC flaut Flags fault flags UCSCTL7 &= ~(XT1LFOFFG); //Clear OFIFG fault flag SFRIFG1 &= ~OFIFG; } UCSCTL6 &= ~XT1OFF; RTC_B_clearInterrupt(RTC_B_BASE, RTC_B_OSCILLATOR_FAULT_INTERRUPT); } void configureHardware_module(void) { //Basic Clock Settings SYSINIT_Init_Micro(); InitializeSystemTimer(); //DELAY 1ms // Initialize timer pool timer_pool_init(); Initialize5msTimer_start(); //5mSEC TRIGGER //AllModuleGpioConfig(); //all modules gpio configurations } void SYSINIT_Init_Micro(void) { //Stop Watch Dog Timer............ WDT_A_hold(WDT_A_BASE); #if 1 /* PMM_setVCore(PMM_CORE_LEVEL_1); //DEFAULT 0 DLY_US(1000); PMM_setVCore(PMM_CORE_LEVEL_2); //DEFAULT 0 DLY_US(1000);*/ PMM_setVCore(PMM_CORE_LEVEL_3); //DEFAULT 0 DLY_US(1000); //Set DCO FLL reference = REFO UCS_initClockSignal( UCS_FLLREF, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1 ); //Set ACLK = REFO UCS_initClockSignal(UCS_ACLK, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1 ); //Set Ratio and Desired MCLK Frequency and initialize DCO UCS_initFLLSettle(UCS_MCLK_DESIRED_FREQUENCY_IN_KHZ, UCS_MCLK_FLLREF_RATIO ); //Verify if the Clock settings are as expected clockValue = UCS_getSMCLK(); clockValue = UCS_getMCLK(); clockValue = UCS_getACLK(); #endif #if 0 //use XT2 external crystal to create clock--- MUST AND SHOUD BE 7.2 AND 7.3 MUST BE HIGH P7SEL |= 0x0C; /********************************************************************************************************** SELREF RW 0h FLL reference select. These bits select the FLL reference clock source. 000b = XT1CLK 001b = Reserved for future use. Defaults to XT1CLK. 010b = REFOCLK 011b = Reserved for future use. Defaults to REFOCLK. 100b = Reserved for future use. Defaults to REFOCLK. 101b = XT2CLK when available, otherwise REFOCLK. //SELREF__XT2CLK //0X0050U 110b = Reserved for future use. XT2CLK when available, otherwise REFOCLK. 111b = Reserved for future use. XT2CLK when available, otherwise REFOCLK. ***********************************************************************************************************/ //ref for fll is xt2clk //SRK EDIT UCSCTL3 = (UCSCTL3 & ~(SELREF_7)) | (SELREF__XT2CLK ); UCSCTL2 &= ~(0x03FF); // Reset FN bits /******************************************************************************** fDCO(4,0) DCO frequency (4, 0)(1) DCORSELx = 4, DCOx = 0, MODx = 0 1.3 3.2 MHz fDCO(1,31) DCO frequency (1, 31)(1) DCORSELx = 1, DCOx = 31, MODx = 0 1.47 3.45 MHz //UCSCTL1 |= 0x1F00u; //3.45MHZ #define DCORSEL_0 (0x0000u) //2MHZ #define DCORSEL_1 (0x0010u) //4MHZ #define DCORSEL_2 (0x0020u) //2.6 #define DCORSEL_3 (0x0030u) //5MHZ #define DCORSEL_4 (0x0040u) //8HZ #define DCORSEL_5 (0x0050u) // LOW INTERRUPT MODE #define DCORSEL_6 (0x0060u) //8HZ #define DCORSEL_7 (0x0070u) //8HZ *****************************************************************************/ UCSCTL1 |= DCORSEL_4; //3.2MHZ #endif } void Initialize5msTimer_start(void) { //Start timer in continuous mode sourced by SMCLK Timer_A_initContinuousModeParam initContParam = {0}; initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_7; initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE; // ENABLE initContParam.timerClear = TIMER_A_DO_CLEAR; initContParam.startTimer = false; Timer_A_initContinuousMode(TIMER_A0_BASE, &initContParam); //Initiaze compare mode Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0); Timer_A_initCompareModeParam initCompParam = {0}; initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0; initCompParam.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE; initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE; initCompParam.compareValue = TIMER_A0_RELOAD; Timer_A_initCompareMode(TIMER_A0_BASE, &initCompParam); Timer_A_startCounter(TIMER_A0_BASE,TIMER_A_CONTINUOUS_MODE); // __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts __bis_SR_register(GIE); // Enter LPM0 w/ interrupt } /******************************************************************************* 5ms TIMER-----A0 *******************************************************************************/ void Initialize5msTimer_stop(void) { //Start timer in continuous mode sourced by SMCLK Timer_A_initContinuousModeParam initContParam = {0}; initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_7; initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE; // ENABLE initContParam.timerClear = TIMER_A_DO_CLEAR; initContParam.startTimer = false; Timer_A_initContinuousMode(TIMER_A0_BASE, &initContParam); //Initiaze compare mode Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0); Timer_A_initCompareModeParam initCompParam = {0}; initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0; initCompParam.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE; initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE; initCompParam.compareValue = TIMER_A0_RELOAD; Timer_A_initCompareMode(TIMER_A0_BASE, &initCompParam); //Timer_A_startCounter(TIMER_A0_BASE,TIMER_A_CONTINUOUS_MODE); Timer_A_startCounter(TIMER_A0_BASE,TIMER_A_STOP_MODE); // __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts __bis_SR_register(GIE); // Enter LPM0 w/ interrupt } /******************************************************************************* ** Function: void InitializeSystemTimer(void) ** ** Description: This is used to initialise 1 msec timer ** ** Parameters: None ** ** Returns: None ** ** Notes: None *******************************************************************************/ void InitializeSystemTimer(void) { // Set up Timer B0 // SMCLK = 8 MHz => 125 nsec , div by 7 = (125nsec * 7) = 875 nsec // MC_2 Timer B mode control: 2 - Continuous up // TBSSEL_2 Timer B clock source select: 2 - SMCLK // TbCLR Counter clear // 000b = Divide by 1 // 001b = Divide by 2 // 010b = Divide by 3 // 011b = Divide by 4 // 100b = Divide by 5 // 101b = Divide by 6 // 110b = Divide by 7 // 111b = Divide by 8 // These bits along with the ID bits select the divider for // the input clock. //4MHZ/6----->666KHZ TB0EX0 = 6; // CCR0 interrupt enabled TB0CCTL0 = CCIE; /****************************************************************************** TBxCCRn holds the data for the comparison to the timer value in the Timer_B Register, TBR.-----REFER #include "hardwareConfig.h" *******************************************************************************/ TB0CCR0 = TIMER_B0_RELOAD; // SMCLK, continuous mode, clear TAR TB0CTL = TBSSEL_2 | MC_2 | TBCLR; //ENABLE interrupts __bis_SR_register(GIE); }
As per my understanding, RTC can be updated during power off, using battery. With an example source code available in internet, i could able to test it. But when i integrate it to my application, its not working as expected. The extra work i have done in my code is more about Increased controller frequency upto 20MHz. Will it have any impact?
Hi,
I don't think it is related to the controller frequency.
If you are supply by battery to RTC, you can't access to the time and date information as described on the document.
**Attention** This is a public forum