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.

RTC Read/write error

Other Parts Discussed in Thread: EK-TM4C1294XL

  • Hello,

    I bought your TM4C1294,I call The RTC read-write interface you provide,The value written in is not the same as the value read out.Write the interface:HibernateCalendarSet(struct tm *psTime),Read the interface:HibernateCalendarGet(struct tm *psTime).I'm going to set 0. Theoretically it should be 1970, but it doesn't read it,How can I fix it?

Here are the renderings:

Here is my implementation of the read-write interface:

void RadarApiSetRTCTime(time_t iUtc)
{
static struct tm sTime;
static struct tm *pTime = &sTime;

ulocaltime(iUtc,pTime);
HibernateCalendarSet(pTime);

}

void RadarApiGetRTCTime(time_t *iUtc)
{
struct tm sTime;
HibernateCalendarGet(&sTime);
*iUtc= umktime(&sTime);
}

  • Hi,

      Can you please try the TivaWare hibernate example in C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\hibernate_calendar. 

      I just run this example and make a very minor modification to use your code to the hibernate_calendar.c file. Please find below what I changed. 

    void
    DateTimeDefaultSet(void)
    {
        static struct tm sTime;
        static struct tm *pTime = &sTime;
    
        ulocaltime((time_t)1614849342,pTime);
        HibernateCalendarSet(pTime);
        HibernateCalendarGet(&sTime);
    //    g_ui32MonthIdx = 7;
    //    g_ui32DayIdx = 29;
    //    g_ui32YearIdx = 13;
    //    g_ui32HourIdx = 8;
    //    g_ui32MinIdx = 30;
    
    }

                //
                // Set the date to the default values and commit it to the
                // hibernate module.
                //
                DateTimeDefaultSet();
    //            DateTimeSet();
            }

    I manually type in the current Epoch time (1614849342) for North America and I don't see an issue displaying the calendar time on the terminal window. Please see below. 

  • Hi ,

    • You can try it out, and it's going to be a problem when the values are small.

    I have tested it,There will be no problem between 2001 and 2021.but there will be problems with reading before 2000.And there is an identical difference with the actual value.

    I just use it  HibernateCalendarSet(pTime) and HibernateCalendarGet(&sTime);I think these two has bug.

       
        
  • Hi CTC,

      Sorry for delay. I actually spent hours trying to understand what is going on myself. I don't think the problem is the API. The issue you are facing is due to how the hibernate module handles YEAR in calendar mode. When you try to set the calendar to 1970 or in another word the epoch time equal 0, the problem is that the hibernate has no concept of epoch time equal to 0. The hibernate module does not use January 1, 1970 as time 0. Please see below datasheet description. 

      The hibernate module YEAR field is only 7 bit and it will only take from 0 to 127. 

    First of all, the epoch time will be stored in the struct tm structure. The TI C runtime library actually uses tm_year reference to 1900, not 1970. Therefore, 1900 January 1 is the time 0 for TI runtime library, not 1970. 

    struct tm 
    {
        int tm_sec;      /* seconds after the minute   - [0,59]  */
        int tm_min;      /* minutes after the hour     - [0,59]  */
        int tm_hour;     /* hours after the midnight   - [0,23]  */
        int tm_mday;     /* day of the month           - [1,31]  */
        int tm_mon;      /* months since January       - [0,11]  */
        int tm_year;     /* years since 1900                     */
        int tm_wday;     /* days since Sunday          - [0,6]   */
        int tm_yday;     /* days since Jan 1st         - [0,365] */
        int tm_isdst;    /* Daylight Savings Time flag           */
    #if defined(_AEABI_PORTABILITY_LEVEL) && _AEABI_PORTABILITY_LEVEL != 0
        int __extra_1, __extra_2;            /* ABI-required extra fields */
    #endif
    
    };

      When you call ulocaltime((time_t)0, pTime), the pTime->tm_year will be 70 because the ulocaltime() has the understanding of of epoch time as it tries to adjust for epoch time. So it knows epoch time 0 is equal to 1970. See the ulocaltime() code snippet below to extract the year. It tries to add 68 years. There are some leap years it will also add before adding 68. 

        //
        // Extract the year.
        //
        tm->tm_year = ((timer - temp) / 365) + 68;
        timer -= ((tm->tm_year - 68) * 365) + temp;

    However, when you call  HibernateCalendarSet(pTime),the API will first subtract 100 before writing the final value to the YEAR field. The psTime->tm_year - 100 will mean 70 - 100 = -30. See below snippet code for HibernateCalendarSet().

      The -30 is equal 0xFFFFFFE2. After you left shift by 16 (the YEAR field is at bit 22:16 of the register), the YEAR will contain 0x62. The reason it is 0x62 is because the YEAR field is only 7 bit. 0x62 is equal to 198 decimal.  

        if(ui32Reg == HIB_CAL0)
        {
            //
            // We must add 1 to the month, since the time structure lists
            // the month from 0 to 11 and the HIB lists it from 1 to 12.
            //
            ui32Date = ((psTime->tm_mday << HIB_CAL1_DOM_S) |
                        ((psTime->tm_mon + 1) << HIB_CAL1_MON_S) |
                        (psTime->tm_wday << HIB_CAL1_DOW_S) |
                        ((psTime->tm_year - 100) << HIB_CAL1_YEAR_S));

    With the above explanation, I hope it becomes more clear to you why you cannot set the epoch to 1970. You just can't set the calendar time to any year that is less than year 2000. If you enter a epoch time that is larger than year 2000 then it will work from year 2000 to year 2127 in theory. However, the datasheet says it will only work from year 2000 to 2099 which is plenty for any applications.