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.

CCS/MSP430FR6989: RTC for Timestamp

Part Number: MSP430FR6989


Tool/software: Code Composer Studio

Hi

I am trying to use RTC to setup timestamp with which I want send with each data string I send over GPRS every 10 seconds. I have gone through the TI example (msp430fr69xx_rtc_02.c) and also search Internet extensively. I want to do the following.

1. Calibrate RTC

2. Read time from network and synchronize RTC (something like NTP)

3. Read timestamp from RTC and add Timezone offset (I live in India so I have to add 5.30 hrs to UTC)

4. Create an interrupt to send data every 10 seconds with timestamp 

Please help me with the code.

Regards

Vijay

  • Hello Vijay,

    We will look into this and get back to you.

    Thanks,

    Yiding

  • Hello Vijay,

    I recommend to follow msp430fr69xx_rtc_02.c example project in TI Resource Explorer. Link: http://dev.ti.com/tirex/explore/node?node=AHrEUMIycvYtJqOTx3x90Q__IOGqZri__LATEST&search=MSP430FR6989

    And for using interrupt to send data, this depends on what communication protocol you plan to use.

    There are examples of using I2C, UART and SPI to send data in TI Resource Explorer.

    Thanks,

    Yiding 

  • I like to use NTP or SNTP to update the RTC clock. Please point me to any example with does this

  • I want to pull time from my server in int (dd, yy, mm, dow, h, m, s) and I want to update the RTC Calendar with integer values. When I try to update the clock i am not getting the right values into it. It tried both BCD mode and Hex mode.

    Below is the extract of my code.

    #include <msp430fr6989.h>
    #include "myprintf.h"
    
    #define changeHexToInt(hex)     ( ( ((hex)>>4) *10 ) + ((hex)%16) )
    
    int mm = 10;
    int dd = 18;
    int yy = 2019;
    int h = 13;
    int m = 17;
    int s = 44;
    
    int main (void)
    {
        WDTCTL = WDTPW | WDTHOLD;
    
        // Init UART_A1 Pins
        P3SEL0 |= BIT4 | BIT5;                  // Pins P3.4(TX) P3.5(RX)
        P3SEL1 &= ~(BIT4 | BIT5);               // USCI_A1 UART operation using Backchannel
    
        // Init LFXT Pins
        PJSEL0 = BIT4 | BIT5;                   // PJ.4(LFXIN), PJ.5(LFXOUT)
    
        PM5CTL0 &= ~LOCKLPM5;
    
        // Configure LFXT 32kHz crystal
        CSCTL0_H = CSKEY >> 8;                  // Unlock CS registers
        CSCTL4 &= ~LFXTOFF;                     // Enable LFXT
        do
        {
          CSCTL5 &= ~LFXTOFFG;                  // Clear LFXT fault flag
          SFRIFG1 &= ~OFIFG;
        } while (SFRIFG1 & OFIFG);              // Test oscillator fault flag
        CSCTL0_H = 0;                           // Lock CS registers
    
        Sync_Time();
    
        RTCCTL0_H = RTCKEY_H;                   // Unlock RTC
    //    RTCCTL0_L = RTCTEVIE | RTCRDYIE;        // enable RTC read ready interrupt
                                                // enable RTC time event interrupt
    
        RTCCTL1 = RTCHOLD | RTCMODE | RTCBCD;   // RTC enable, BCD mode, RTC hold
    
        RTCYEAR = yy;                       // Year = 0x2010
        RTCMON = mm;                           // Month = 0x04 = April
        RTCDAY = dd;                          // Day = 0x06 = 6th
        RTCDOW = dow;                          // Day of week = 0x04 = Thursday
        RTCHOUR = h;                         // Hour = 0x15
        RTCMIN = m;                          // Minute = 0x47
        RTCSEC = s;                          // Seconds = 0x50
    
        RTCCTL1 &= ~(RTCHOLD);
    
        while(1)
        {
            myprintf("RTC: %02d%02d-%02d-%02d %02d:%02d:%02d\r\n",
                     (long int)changeHexToInt(RTCYEAR >> 8),
                     (long int)changeHexToInt(RTCYEAR & 0x00FF),
                     (long int)changeHexToInt(RTCMON),
                     (long int)changeHexToInt(RTCDAY),
                     (long int)changeHexToInt(RTCHOUR),
                     (long int)changeHexToInt(RTCMIN),
                     (long int)changeHexToInt(RTCSEC)
                     );
            __delay_cycles(5000000);
        }
    }

    In the terminal it prints

    0843-10-12 13:11:32

    Where as it should print

    2019-10-18 13:17:44

    Please help.

    Regards

    Vijay

  • Hello Vijay,

    I did not see anything particularly in your code cause the wrong output.

    Were you able to make it work? 

    Thanks,

    Yiding

  • int m = 17;

    >0843-10-12 13:11:32

    (int)17 is 0x11 which is "11" in BCD, so it's doing what you told it to do. You need to change your "int"-s to BCD before storing them.

    If it helps, I think you can store the "int" in HEX mode, then change the RTC to BCD mode, and it will read out in BCD.

    There are also the BIN2BCD and BCD2BIN registers to do this for you.

  • I have tried changeIntoToHex from one of the examples and used it in BCD mode. It is working for all except for the year 2019.

    #define changeIntToHex(dec)     ( ( ((dec)/10) <<4 ) + ((dec)%10) )

    Please help me with the year

  • It would probably look something like [untested]:

    > highBCD=changeIntToHex(year_in_BIN/100);

    > lowBCD=changeIntToHex(year_in_BIN%100);

    >year_in_BCD = (highBCD << 8) | (lowBCD << 0);

    though I would be tempted to say instead:

    > BIN2BCD = year_in_BIN;  // uint12 goes in,

    > year_in_BCD = BIN2BCD; // BCD comes out

  • Thank you Bruce. I am getting the time in UTC from server. So the 2019 is in int. I also tried to convert 20 and 19 into RTCYEAR_H and RTCYEAR_L using changeIntToHex. Both did not work. I will try your suggestion. Thanks again.

  • Dear Yiding

    The changeIntToHex is working fine. I only have issue with the year. I am receiving the year 2019 in Int using time.h. The following is not working.

    RTCYEAR = changeIntToHex(2019);

    I also tried

    RTCYEAR_H = changeIntToHex(20);

    RTCYEAR_L = changeIntToHex(19);

    Both are not working either in BCDMODE or HEXMODE. However, others like mins, hours etc are working as below

    RTCSEC = changeIntToHex(newtime->tm_sec);
    RTCMIN = changeIntToHex(newtime->tm_min); 
    RTCHOUR = changeIntToHex(newtime->tm_hour); 
    RTCDAY = changeIntToHex(newtime->tm_mday); 
    RTCDOW = changeIntToHex(newtime->tm_wday);
    RTCMON = changeIntToHex(newtime->tm_mon+1);

    I need to do the same with year it fails

    RTCYEAR = changeIntToHex(newtime->tm_year);

  • > RTCYEAR = changeIntToHex(2019);

    This doesn't work since changeIntToHex is only designed to work on bytes (<100).

    ----------

    > RTCYEAR_H = changeIntToHex(20);

    > RTCYEAR_L = changeIntToHex(19);

    This doesn't work since you can't write RTCYEAR by bytes [Ref UG (SLAU367O) Table 29-2, footnote p. 732]. (I actually tried it; I couldn't figure out what it does, but it clearly isn't what you want.)

    ---------

    Each of my suggested sequences above does what you want (when I do it). Did you try either of them?

    ---------

    [Edit: Did you remember to unlock the RTC registers with "RTCCTL0_H = 0xA5;"?]

  • I tried your suggestion like below

    RTCYEAR = (changeIntToHex(newtime->tm_year/100)<<8) | (changeHexToInt(newtime->tm_year%100)<<0);

    I got below

    Clock: 025-11-03 18:22:22

    When you mentioned year_in_BIN should I convert the int to binary?

  • 1) (int)25 is 0x19, which suggests you're not using changeHexToInt to change it back to integer ("binary") before printing it.

    2) What value is actually in tm_year? If it's a time_t, I would expect it to contain 119 (2019-1900), but it appears to contain 19 (2019-2000). What is the origin of this structure?

    ----------

    In my example, year_in_BIN is expected to be =(int)2019, e.g.

    > int year_in_BIN = yy;  // yy = 2019 from the original example

    ----------

    Unsolicited: Do you really need to use BCD at all? Your time_t values are binary ("int"), you want to print them in binary ("%d"), and the RTC registers can be set/read in binary ("HEX"). Dealing with BCD seems like a lot of trouble for no benefit. (I suspect the only reason that BCD mode exists in the RTC_C is that historically many RTCs ran only in BCD mode. BCD was actually easier to print in the days before printf.)

  • IT WORKED! THANK YOU SO MUCH!

    i am using time_t values. There was a typo in the line. The code had changeHexToInt instead of changeIntToHex. I have used the following and now I am getting the year right.

    RTCSEC = changeIntToHex(newtime->tm_sec); // Seconds = 0x50
    RTCMIN = changeIntToHex(newtime->tm_min); // Minute = 0x47
    RTCHOUR = changeIntToHex(newtime->tm_hour); // Hour = 0x15
    RTCDAY = changeIntToHex(newtime->tm_mday); // Day = 0x06 = 6th
    RTCDOW = changeIntToHex(newtime->tm_wday); // Day of week = 0x04 = Thursday
    RTCMON = changeIntToHex(newtime->tm_mon+1); // Month = 0x04 = April
    RTCYEAR = (changeIntToHex(newtime->tm_year-99)<<8) | (changeIntToHex(newtime->tm_year-100)<<0);

    RTCYEAR = (changeIntToHex(newtime->tm_year-99)<<8) | (changeIntToHex(newtime->tm_year-100)<<0);

    Clock: 2019-11-04 10:30:41 IST

    Like you suggested I tried using the HEXMODE with the same code returns

    Clock: 019-01-04 10:17:18 IST

    It should be

    Clock: 2019-10-04 10:57:18

    What I did not understand is that even though RTC is in BCD MODE, I am still sending it in hex and it is working fine. If I change to HEX mode and send the same it does not work. Please enlighten me on this. Thank you for your time and support. I really appreciate it.

  • changeIntToHex() returns a BCD representation of the given int ("binary") value. The name seemed a bit odd to me, but I'm not the judge.

**Attention** This is a public forum