Psoc 6 RTC unixtime

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
JoMa_4610161
Level 2
Level 2
First like received First like given

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

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.

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.

View solution in original post

5 Replies
wcc3
Level 4
Level 4
10 likes received 10 replies posted 5 replies posted

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);

0 Likes
lock attach
Attachments are accessible only for community members.

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.

CaKu_4284131
Level 5
Level 5
50 replies posted 25 replies posted 10 likes received

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?

0 Likes

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?

0 Likes
Panometric
Level 5
Level 5
100 sign-ins 100 replies posted 10 solutions authored

I'm not seeing why you think this does not work. 

RTC_DateTimeToUnix() returns the same value as mktime() in the current libs. 




0 Likes