CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Exploring PIC24 rtc_read()/rtc_write()

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
allenhuffman



Joined: 17 Jun 2019
Posts: 554
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

Exploring PIC24 rtc_read()/rtc_write()
PostPosted: Tue Nov 05, 2024 11:17 am     Reply with quote

Just something for future searches to find. I am experimenting with 24FJ256GA106 real time clock hardware.

Can someone clarify my understanding is correct? The help file is quite vague on rtc_read()/rtc_write() and the parameters of the rtc_time_t structure should be set to.

Code:
typedef struct {
   unsigned int8 tm_year;
   unsigned int8 tm_temp;  // Not used by built in functions, place holder only do not use
   unsigned int8 tm_mday;
   unsigned int8 tm_mon;
   unsigned int8 tm_hour;
   unsigned int8 tm_wday;
   unsigned int8 tm_sec;
   unsigned int8 tm_min;
   unsigned int8 tm_isdst; // Not used by built in functions
} rtc_time_t;


Based on looking at code examples, it looks like tm_year is Base-2000, so setting it to 0 means 2000, and 24 would mean 2024.

Other values seem to be base-1, so 1-12 for the tm_mon, 1-31 for the tm_mday, and the same four hour, min and sec.

Is this understanding correct? The reason I ask is I see things in the sample time.h/time.c files that do things to convert the RTC numbers back to C-time.

rtcperepheral.c does:

Code:
void GetTime(struct_tm *pRetTm)
{
   struct_tm cTime;
   rtc_time_t datetime;
   rtc_read(&datetime);
   
   // adjust date to be time.h compatible
   cTime.tm_year = datetime.tm_year + 100; // starting at 1900
   cTime.tm_mon = datetime.tm_mon - 1;     // 0-11
   cTime.tm_mday = datetime.tm_mday - 1;   // 0-30
   cTime.tm_wday = datetime.tm_wday - 1;   // 0-6
   
   cTime.tm_hour = datetime.tm_hour;
   cTime.tm_sec = datetime.tm_sec;
   cTime.tm_min = datetime.tm_min;
   
   memcpy(pRetTm, &cTime, sizeof(struct_tm));
}


This confuses me, since it implies the clock is base 1900, and adds 100 to the year.

Likewise, it shows mon, mdw and wday as being base-1, so it subtracts. But in the C standard it looks different:

https://cplusplus.com/reference/ctime/tm/

struct tm shows base-1 for tm_mday -- 1-31. The others it shows as base-0 (seconds, minutes, hours, months since January, days since Sunday, etc.)

If the intent of this code was to provide a struct_tm compatible structure, maybe that is just an error in the code. I believe if I used these time routines, it would be providing different results than cTime (even the code uses cTime for a variable name, which makes me think it is supposed to look like the C time structure).
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
jeremiah



Joined: 20 Jul 2010
Posts: 1354

View user's profile Send private message

PostPosted: Tue Nov 05, 2024 11:47 am     Reply with quote

The C standard doesn't have an rtc_time_t type, so I wouldn't compare them. In general, it would really come down to how the PIC implements the RTC registers as to what the time base is, so I would refer to the datasheet for your PIC to see what the RTC does for year month day, etc. As for the year, I don't recall if it is 1900 or 2000, but I would have guessed 1900 since most RTCs are 2 digit year and the PIC has been around since the 1900s, but it was only a guess.

I would do similar to what you are doing and just test it out and see what it gives and adjust my code accordingly.
allenhuffman



Joined: 17 Jun 2019
Posts: 554
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Tue Nov 05, 2024 12:38 pm     Reply with quote

Testing seems to verify the sample code incorrect unless the clock hardware is base-2 for some reason. The CCS code addresses using it with standard C (even providing an offset you apply to time_t to go between the "seconds since 1/1/2010" mode and standard C). Using that...

Quote:
31536000 seconds in a year.
86400 seconds in a day
31622400 seconds in a leap year.
1729810550 seconds since 1/1/1970
STD: 2024-11-05 18:21:55 is 1730830915 seconds since 1/1/1970
STD: 2024-11-05 18:21:55 is 468526915 seconds since 1/1/2010
CCS: 2024-11-05 18:21:55 is 1730830915 seconds since 1/1/1970
CCS: 2024-11-05 18:21:55 is 468526915 seconds since 1/1/2010


My test code:

https://onlinegdb.com/iTMTsbydwT

The datasheet for my PIC specifically mentions year values of 2000 to 2099, so that looks like 0 for 2000.

For month (MTH), it shows you can pass in 0-1 for the tens digit, and 0-9 for the ones. That would give 0-19 for the month, looking like it is base 0.

The same for day (DAY) using 0-3/0-9, allowing 0-39.

I do not see where it specifically says base 0 or base 1, so I "assume" it is base 0. But, since it shows values higher than we could use, maybe it also shows a 0 value that is lower than we can use and is really base 1.

I'll have to test that. ChatGPT tells me it is base-1, but ... yeah, never trust the 'bot ;-)
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
allenhuffman



Joined: 17 Jun 2019
Posts: 554
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Tue Nov 05, 2024 12:51 pm     Reply with quote

It is looking like Base-0 for the PIC24's RTC. I set the month to 0, and I see it rolls over to 1 after day 30:

Quote:
2000-00-30 23:59:59
2000-01-01 00:00:00
2000-01-01 00:00:01
2000-01-01 00:00:02
2000-01-01 00:00:03
2000-01-01 00:00:04
2000-01-01 00:00:05
2000-01-01 00:00:06

_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
allenhuffman



Joined: 17 Jun 2019
Posts: 554
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Tue Nov 05, 2024 12:58 pm     Reply with quote

I stand corrected.

Quote:
2000-01-31 23:59:57
2000-01-31 23:59:58
2000-01-31 23:59:59
2000-02-02 00:00:00
2000-02-02 00:00:01
2000-02-02 00:00:02


The RTC hardware seems to like base-1 for the day. This matches the C time.h struct tm where day of month is 1-31, but others are 0. A few more tests needed...
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
allenhuffman



Joined: 17 Jun 2019
Posts: 554
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Tue Nov 05, 2024 1:07 pm     Reply with quote

Base-1 it is.

Quote:
2000-12-31 23:59:55
2000-12-31 23:59:56
2000-12-31 23:59:57
2000-12-31 23:59:58
2000-12-31 23:59:59
2001-01-01 00:00:00
2001-01-01 00:00:01
2001-01-01 00:00:02
2001-01-01 00:00:03


Not sure if I need to do anything with tm_wday but for future reference, my test code:

Code:
    // Setup the real time clock.
    setup_rtc (RTC_ENABLE | RTC_OUTPUT_SECONDS, ZERO);

    // Set time to default if on a fresh power cycle.
    rtc_time_t datetime;

    if (RestartCause == RESTART_POWER_UP)
    {
        DEBUG_PRINTF ("Set ");

        // Initialize time to 1/1/2000 00:00:00.
        datetime.tm_year    = 0; // Base-2000
        datetime.tm_mon     = 12; // December(base 1)
        datetime.tm_mday    = 31; // 31st (base 1)

        datetime.tm_hour    = 23; // hh
        datetime.tm_min     = 59; // ss
        datetime.tm_sec     = 50; // mm

        datetime.tm_wday    = 0;

        datetime.tm_temp    = 0; // Not used.
        datetime.tm_isdst   = 0; // Not used.
       
        rtc_write (&datetime);
    }

    // Get current date and time.
    rtc_read (&datetime);

    DEBUG_PRINTF ("%04u-%02u-%02u %02u:%02u:%02u) ",
        datetime.tm_year + 2000, datetime.tm_mon, datetime.tm_mday,
        datetime.tm_hour, datetime.tm_min, datetime.tm_sec);

_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group