Remote_Wifi_Switch/main/rtc.c
2025-02-21 15:26:53 +05:30

225 lines
5.8 KiB
C

/*
* rtc.c
*
* Created on: Jan 16, 2023
* Author: Sword
*/
#include "rtc.h"
#include <time.h>
#include <sys/time.h>
/** 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;
}