rusefi-1/firmware/hw_layer/rtc_helper.cpp

176 lines
4.1 KiB
C++
Raw Normal View History

2015-07-10 06:01:56 -07:00
/**
* @file rtc_helper.cpp
* @brief Real Time Clock helper
*
* @date Feb 5, 2014
2020-01-13 18:57:43 -08:00
* @author Andrey Belomutskiy, (c) 2012-2020
2015-07-10 06:01:56 -07:00
*/
#include "pch.h"
2015-07-10 06:01:56 -07:00
#include <string.h>
#include <time.h>
#include "os_access.h"
2015-07-10 06:01:56 -07:00
#include "rtc_helper.h"
#include <sys/time.h>
2015-07-10 06:01:56 -07:00
2019-04-12 17:52:51 -07:00
#if EFI_RTC
2017-03-21 11:58:14 -07:00
static RTCDateTime timespec;
2015-07-10 06:01:56 -07:00
2017-08-25 15:37:59 -07:00
extern bool rtcWorks;
2015-07-10 06:01:56 -07:00
#endif /* EFI_RTC */
void date_set_tm(struct tm *timp) {
(void)timp;
2019-04-12 17:52:51 -07:00
#if EFI_RTC
2017-03-21 11:58:14 -07:00
rtcConvertStructTmToDateTime(timp, 0, &timespec);
rtcSetTime(&RTCD1, &timespec);
2015-07-10 06:01:56 -07:00
#endif /* EFI_RTC */
}
void date_get_tm(struct tm *timp) {
(void)timp;
2019-04-12 17:52:51 -07:00
#if EFI_RTC
2017-03-21 11:58:14 -07:00
rtcGetTime(&RTCD1, &timespec);
rtcConvertDateTimeToStructTm(&timespec, timp, NULL);
2015-07-10 06:01:56 -07:00
#endif /* EFI_RTC */
}
#if EFI_PROD_CODE
// Lua needs this function, but we don't necessarily have to implement it
extern "C" int _gettimeofday(timeval* tv, void* tzvp) {
(void)tv; (void)tzvp;
return 0;
}
#endif
2019-04-12 17:52:51 -07:00
#if EFI_RTC
static time_t GetTimeUnixSec() {
2017-03-21 11:58:14 -07:00
struct tm tim;
rtcGetTime(&RTCD1, &timespec);
rtcConvertDateTimeToStructTm(&timespec, &tim, NULL);
return mktime(&tim);
}
static void SetTimeUnixSec(time_t unix_time) {
struct tm tim;
2017-04-01 22:02:58 -07:00
#if defined __GNUC__
struct tm *canary;
2017-03-21 11:58:14 -07:00
/* If the conversion is successful the function returns a pointer
to the object the result was written into.*/
canary = localtime_r(&unix_time, &tim);
osalDbgCheck(&tim == canary);
2017-04-01 22:02:58 -07:00
#else
2017-04-01 22:15:03 -07:00
struct tm *t = localtime(&unix_time);
memcpy(&tim, t, sizeof(struct tm));
2017-04-01 22:02:58 -07:00
#endif
2017-03-21 11:58:14 -07:00
rtcConvertStructTmToDateTime(&tim, 0, &timespec);
rtcSetTime(&RTCD1, &timespec);
}
2016-08-08 21:03:08 -07:00
static void put2(int offset, char *lcd_str, int value) {
2016-08-09 21:04:24 -07:00
static char buff[_MAX_FILLER];
2018-07-25 20:03:04 -07:00
efiAssertVoid(CUSTOM_ERR_6666, value >=0 && value <100, "value");
2016-08-08 21:03:08 -07:00
itoa10(buff, value);
if (value < 10) {
lcd_str[offset] = '0';
lcd_str[offset + 1] = buff[0];
} else {
lcd_str[offset] = buff[0];
lcd_str[offset + 1] = buff[1];
}
}
2017-08-22 21:46:34 -07:00
/**
* @return true if we seem to know current date, false if no valid RTC state
*/
2016-08-08 21:03:08 -07:00
bool dateToStringShort(char *lcd_str) {
2020-05-17 14:02:22 -07:00
strcpy(lcd_str, "000000_000000\0");
2016-08-08 21:03:08 -07:00
struct tm timp;
2017-03-21 11:58:14 -07:00
date_get_tm(&timp);
2016-08-08 21:03:08 -07:00
if (timp.tm_year < 116 || timp.tm_year > 130) {
// 2016 to 2030 is the valid range
lcd_str[0] = 0;
return false;
}
2020-05-17 14:02:22 -07:00
put2(0, lcd_str, timp.tm_year % 100); // Years since 1900 - format as just the last two digits
put2(2, lcd_str, timp.tm_mon + 1); // months since January 0-11
put2(4, lcd_str, timp.tm_mday); // day of the month 1-31
put2(7, lcd_str, timp.tm_hour); // hours since midnight 0-23
put2(9, lcd_str, timp.tm_min); // Minutes
put2(11, lcd_str, timp.tm_sec); // seconds
2016-08-08 21:03:08 -07:00
return true;
}
2015-07-10 06:01:56 -07:00
void dateToString(char *lcd_str) {
// todo:
// re-implement this along the lines of chvprintf("%04u-%02u-%02u %02u:%02u:%02u\r\n", timp.tm_year + 1900, timp.tm_mon + 1, timp.tm_mday, timp.tm_hour,
// timp.tm_min, timp.tm_sec);
// this would require a temporary mem stream - see datalogging and other existing usages
strcpy(lcd_str, "00/00 00:00:00\0");
struct tm timp;
2017-03-21 11:58:14 -07:00
date_get_tm(&timp); // get RTC date/time
2015-07-10 06:01:56 -07:00
2016-08-08 21:03:08 -07:00
put2(0, lcd_str, timp.tm_mon + 1);
put2(3, lcd_str, timp.tm_mday);
put2(6, lcd_str, timp.tm_hour);
put2(9, lcd_str, timp.tm_min);
put2(12, lcd_str, timp.tm_sec);
2015-07-10 06:01:56 -07:00
}
void printDateTime(void) {
static time_t unix_time;
struct tm timp;
2017-03-21 11:58:14 -07:00
unix_time = GetTimeUnixSec();
2015-07-10 06:01:56 -07:00
if (unix_time == -1) {
efiPrintf("incorrect time in RTC cell");
2015-07-10 06:01:56 -07:00
} else {
efiPrintf("%D - unix time", unix_time);
2017-03-21 11:58:14 -07:00
date_get_tm(&timp);
2015-07-10 06:01:56 -07:00
efiPrintf("Current RTC localtime is: %04u-%02u-%02u %02u:%02u:%02u w=%d", timp.tm_year + 1900, timp.tm_mon + 1, timp.tm_mday, timp.tm_hour,
2017-08-25 15:37:59 -07:00
timp.tm_min, timp.tm_sec, rtcWorks);
2015-07-10 06:01:56 -07:00
}
}
void setDateTime(const char *strDate) {
if (strlen(strDate) > 0) {
2016-08-09 18:03:16 -07:00
time_t unix_time = atoi(strDate);
2015-07-10 06:01:56 -07:00
if (unix_time > 0) {
2017-03-21 11:58:14 -07:00
SetTimeUnixSec(unix_time);
2015-07-10 06:01:56 -07:00
printDateTime();
return;
}
}
efiPrintf("date_set Date parameter %s is wrong", strDate);
2015-07-10 06:01:56 -07:00
}
#else /* EFI_RTC */
bool dateToStringShort(char *lcd_str) {
lcd_str[0] = 0;
return false;
}
void dateToString(char *lcd_str) {
lcd_str[0] = 0;
}
#endif
2015-07-10 06:01:56 -07:00
void initRtc(void) {
2019-04-12 17:52:51 -07:00
#if EFI_RTC
2017-03-21 11:58:14 -07:00
GetTimeUnixSec(); // this would test RTC, see 'rtcWorks' variable, see #311
efiPrintf("initRtc()");
2016-09-15 19:02:00 -07:00
#endif /* EFI_RTC */
2015-07-10 06:01:56 -07:00
}