/* * rtc.c * * Created on: Jan 16, 2023 * Author: Sword */ #include "rtc.h" #include #include /** Date and time set to: 1st of December 2014, 23 hour 59 min and 31 seconds */ #define SET_HOUR 13 /*< Set hour to the RTC */ #define SET_MINUTE 0 /*< Set minute to the RTC */ #define SET_SECOND 0 /*< Set second to the RTC */ #define SET_WEEKDAY 3 /*< Set weekday to the RTC */ #define SET_YEARDAY 16 /*< day in the year, range 0 to 365 */ #define SET_DAY 16 /*< Set day to the RTC */ #define SET_MONTH 1 /*< Set month to the RTC */ #define SET_YEAR 2023 /*< Set year to the RTC */ #define RTC_SUBSECOND_COUNTER_LOAD_VALUE 32767 static const char* TAG = "RTC"; #define LOG_LOCAL_LEVEL ESP_LOG_INFO #include "esp_log.h" static bool rtc_set = false; int app_rtc_init(void) { int retval = RTC_STATUS_OK; //RTC_InitType RTC_Init_struct; //RTC_StructInit(&RTC_Init_struct); //SysCtrl_PeripheralClockCmd(CLOCK_PERIPH_RTC, ENABLE); /* Try to enable the down-counter to use as a millisecond counter, but * does not seem to work without this __NOP delay. */ //RTC_Init_struct.RTC_TLR1 = RTC_SUBSECOND_COUNTER_LOAD_VALUE; //RTC_Init(&RTC_Init_struct); /** Delay between two write in RTC->TCR register has to be * at least 3 x 32k cycle + 2 CPU cycle. For that reason it * is neccessary to add the delay. */ // for (volatile uint32_t i = 0; i < 600; i++) { // __asm("NOP"); // } //RTC_DateTimeType RTC_DateTime; struct tm rtc_time; /* Set the present time and date */ /*RTC_DateTime.Second = SET_SECOND; RTC_DateTime.Minute = SET_MINUTE; RTC_DateTime.Hour = SET_HOUR; RTC_DateTime.WeekDay = SET_WEEKDAY; RTC_DateTime.MonthDay = SET_DAY; RTC_DateTime.Month = SET_MONTH; RTC_DateTime.Year = SET_YEAR; RTC_SetTimeDate(&RTC_DateTime);*/ rtc_time.tm_sec = SET_SECOND; rtc_time.tm_min = SET_MINUTE; rtc_time.tm_hour = SET_HOUR; rtc_time.tm_wday = SET_WEEKDAY; rtc_time.tm_mday = SET_DAY; rtc_time.tm_mon = SET_MONTH; rtc_time.tm_year = SET_YEAR; rtc_time.tm_yday = SET_YEARDAY; time_t t = mktime(&rtc_time); struct timeval now = { .tv_sec = t }; settimeofday(&now, NULL); /* Enable RTC */ // RTC_Cmd(ENABLE); /* Enable RTC clockwatch */ // RTC_ClockwatchCmd(ENABLE); rtc_set = false; return retval; } void rtc_get_timestamp(rtc_timestamp_t* ts) { if (ts) { //RTC_DateTimeType RTC_DateTime; //RTC_GetTimeDate(&RTC_DateTime); /* RTC subsecond counter is a count-down counter */ struct timeval tv; gettimeofday(&tv, NULL); struct tm *info = localtime( &tv.tv_sec ); ts->Millisecond = 7+1000*(info->tm_sec); //((RTC_SUBSECOND_COUNTER_LOAD_VALUE - RTC_GetTimerValue()) * 1000 + RTC_SUBSECOND_COUNTER_LOAD_VALUE) / ts->Second = info->tm_sec; ts->Minute = info->tm_min; ts->Hour = info->tm_hour; ts->WeekDay = info->tm_wday; ts->MonthDay = info->tm_mday; ts->Month = info->tm_mon; ts->Year = info->tm_year; } } void rtc_set_timestamp(rtc_timestamp_t* ts) { if (ts) { rtc_set_timestamp_tz(ts, 0); } } /* Set timestamp including a timezone offset in seconds. * The timezone offset may be positive or negative. It is applied * by subtraction, so a -ve offset (e.g. UTC-5) results in the * timezone offset being added to the local timestamp */ void rtc_set_timestamp_tz(rtc_timestamp_t* ts, int32_t tz_offset_sec) { if (ts) { struct tm buf; buf.tm_year = ts->Year - 1900; buf.tm_mon = ts->Month - 1; buf.tm_mday = ts->MonthDay; buf.tm_hour = ts->Hour; buf.tm_min = ts->Minute; buf.tm_sec = ts->Second; time_t t = mktime(&buf); /* Apply offset */ t -= tz_offset_sec; /* if (!rtc_is_set()) { rtc_set_epoch((uint32_t)t); } */ rtc_set_epoch((uint32_t)t); } } void rtc_set_epoch(uint32_t epoch) { /* * struct tm Member Type Meaning Range tm_sec int seconds after the minute 0 - 60 * tm_min int minutes after the hour 0 - 59 tm_hour int hours since midnight 0 - 23 tm_mday int day of the month 1 - 31 tm_mon int months since January 0 - 11 tm_year int years since 1900 tm_wday int days since Sunday 0 - 6 tm_yday int days since January 1 0 - 365 tm_isdst int Daylight Saving Time flag */ struct tm* buf; time_t t = epoch; buf = localtime(&t); ESP_LOGD(TAG,"rtc_set_epoch: %s\n", asctime(buf)); //RTC_DateTimeType RTC_DateTime; // ///* Set the present time and date */ //RTC_DateTime.Second = buf->tm_sec; //RTC_DateTime.Minute = buf->tm_min; //RTC_DateTime.Hour = buf->tm_hour; //RTC_DateTime.WeekDay = buf->tm_wday; //RTC_DateTime.MonthDay = buf->tm_mday; //RTC_DateTime.Month = buf->tm_mon + 1; //RTC_DateTime.Year = buf->tm_year + 1900; //RTC_SetTimeDate(&RTC_DateTime); time_t tmi = mktime(buf); struct timeval now = { .tv_sec = tmi }; settimeofday(&now, NULL); rtc_set = true; } uint32_t rtc_get_epoch(void) { struct timeval tv; gettimeofday(&tv, NULL); struct tm *info = localtime( &tv.tv_sec ); struct tm buf; buf.tm_year = info->tm_year - 1900; buf.tm_mon = info->tm_mon - 1; buf.tm_mday = info->tm_mday; buf.tm_hour = info->tm_hour; buf.tm_min = info->tm_min; buf.tm_sec = info->tm_sec; buf.tm_isdst = 0; time_t t = mktime(&buf); ESP_LOGD(TAG,"rtc_get_epoch: %s\n", ctime(&t)); return (uint32_t)t; } bool rtc_is_set(void) { return rtc_set; }