4 Replies Latest reply on Mar 23, 2020 10:06 AM by CaKu_4284131

    Psoc 6 RTC unixtime

    JoMa_4610161

      Hi,

       

      there is a way to get the unix time ( Seconds since January 1, 1970 ) from RTC?

       

      I have tried with mktime() but it doesn't work.

       

      Thanks,

      Giuseppe

        • 1. Re: Psoc 6 RTC unixtime
          WiCo_1641241

          The standard C library struct tm and the Cypress cy_stc_rtc_config_t don't quite map 1-to-1.  One needs to do a little fiddling.

           

          I presume that the PSoC RTC is running 24-hour format.  If not, the tweak ought to be apparent.

           

          Given your time here:

           

               cy_stc_rtc_config_t rtc_config;

           

          This ought to work:

           

               struct tm stdCTime;

               time_t utcTime;

           

               stdCTime.tm_year = rtc_config.year + 100;

               stdCTime.tm_mon = rtc_config.month - 1;

               stdCTime.tm_mday = rtc_config.date;

               stdCTime.tm_hour = rtc_config.hour;

               stdCTime.tm_min = rtc_config.min;

               stdCTime.tm_sec = rtc_config.sec;

               stdCTime.tm_isdst = -1;

           

               utcTime = mktime(&stdCTime);

          • 2. Re: Psoc 6 RTC unixtime
            JoMa_4610161

            Actually it doesn't work as expected with psoc 6.

             

            I have found a solution, so you can find attached the right library version useful to make a conversion to unix time.

             

            You can try this code with "RTC Basic" example available for PSOC6.

             

            You need to call my library with date_time struct acquired by cyhal_rtc_read function:

             

            rslt = cyhal_rtc_read(&my_rtc, &date_time);
            
            int unixTime = RTC_DateTimeToUnix(&date_time);
            

             

            To set a new date you need to execute this code ( just as example ):

             

            struct tm new_time = {0};
            
            new_time.tm_sec = 0;
            new_time.tm_min = 10;
            new_time.tm_hour = 11;
            new_time.tm_mday = 21;
            new_time.tm_mon = 12 - 1;
            new_time.tm_year = 2019 - TM_YEAR_BASE;
            new_time.tm_wday = get_day_of_week(21, 12, 2019);
            
            
            rslt = cyhal_rtc_write(&my_rtc, &new_time);
            

             

            I hope that this is useful to anyone.

             

            Thanks,

            Giuseppe.

            • 3. Re: Psoc 6 RTC unixtime
              CaKu_4284131

              I'm trying to do something similar:

               

                  time_t epochtime;

                  struct tm timeinfo;

                  cy_stc_rtc_config_t dateTime;

                

                  /*Get the current RTC time and date */

                  Cy_RTC_GetDateAndTime(&dateTime);

                

                  // The values of the members tm_wday and tm_yday are ignored

                

              //Member Type Meaning                Range

              //tm_sec int seconds after the minute 0-61*

                  timeinfo.tm_sec = dateTime.sec;  

              //tm_min int minutes after the hour    0-59

                  timeinfo.tm_min = dateTime.min;

              //tm_hour int hours since midnight    0-23

                  if (CY_RTC_12_HOURS == dateTime.hrFormat)

                      if (CY_RTC_AM == dateTime.amPm)

                          timeinfo.tm_hour = dateTime.hour - 1;        

                      else    

                        timeinfo.tm_hour = dateTime.hour - 1 + 12;

                  else

                      timeinfo.tm_hour = dateTime.hour;      

              //tm_mday int day of the month        1-31

                  timeinfo.tm_mday = dateTime.date;

              //tm_mon int months since January    0-11

                  timeinfo.tm_mon = dateTime.month - 1;

              //tm_year int years since 1900

                  timeinfo.tm_year = dateTime.year + 100;

              //tm_wday int days since Sunday    0-6

                  timeinfo.tm_wday = -1;

              //tm_yday int days since January 1 0-365

                  timeinfo.tm_wday = -1;

              //tm_isdst int Daylight Saving Time flag

              // The Daylight Saving Time flag (tm_isdst) is greater than zero

              //    if Daylight Saving Time is in effect,

              //    zero if Daylight Saving Time is not in effect,

              //    and less than zero if the information is not available.  

                  timeinfo.tm_isdst = -1;

                    

                  epochtime = mktime ( &timeinfo );

               

              This seems to work OK for me. However, I'm having a different problem. I'm calling this function frequently to timestamp records in a data log. Unfortunately, it seems that the call to get the current RTC date and time runs for relatively long periods of time with interrupts masked off:

               

              __STATIC_INLINE void Cy_RTC_SyncFromRtc(void)

              {

                  uint32_t interruptState;

                 

                  interruptState = Cy_SysLib_EnterCriticalSection();

                 

                  /* RTC Write is possible only in the condition that CY_RTC_BUSY bit = 0

                  *  or RTC Write bit is not set.

                  */

                  if ((CY_RTC_BUSY != Cy_RTC_GetSyncStatus()) && (!_FLD2BOOL(BACKUP_RTC_RW_WRITE, BACKUP_RTC_RW)))

                  {

                      /* Setting RTC Read bit */

                      BACKUP_RTC_RW = BACKUP_RTC_RW_READ_Msk;

               

               

                      /* Delay to guarantee RTC data reading */

                      Cy_SysLib_DelayUs(CY_RTC_DELAY_WHILE_READING_US);

               

               

                      /* Clearing RTC Read bit */

                      BACKUP_RTC_RW = 0U;

                  }

                  Cy_SysLib_ExitCriticalSection(interruptState);

              }

               

              (This is just my guess, given that when I started calling this, other parts of our system started missing interrupt deadlines.)

               

              So, I think I might need to do something like start a TCPWM counter and occasionally synch it with the RTC. Sounds complex. Has anyone been down this road before?

              • 4. Re: Psoc 6 RTC unixtime
                CaKu_4284131

                I wonder about that Cypress code in Generated_Source\PSoC6\pdl\drivers\peripheral\rtc\cy_rtc.h:

                __STATIC_INLINE void Cy_RTC_SyncFromRtc(void)

                {

                    uint32_t interruptState;

                  

                    interruptState = Cy_SysLib_EnterCriticalSection();

                //...

                        /* Delay to guarantee RTC data reading */

                        Cy_SysLib_DelayUs(CY_RTC_DELAY_WHILE_READING_US);

                // ...

                    Cy_SysLib_ExitCriticalSection(interruptState);

                }

                Does it make sense to call Cy_SysLib_DelayUs() (PSoC 6 Peripheral Driver Library: Functions) with interrupts disabled? Does Cy_SysLib_DelayUs() wait for an interrupt from SystemCoreClock or does it just spin in a hard loop for some number of cycles?