Line data Source code
1 : /**
2 : * @file rtc_helper.cpp
3 : * @brief Real Time Clock helper
4 : *
5 : * @date Feb 5, 2014
6 : * @author Andrey Belomutskiy, (c) 2012-2020
7 : */
8 :
9 : #include "pch.h"
10 :
11 : #include <string.h>
12 :
13 : #include "rtc_helper.h"
14 :
15 : #if EFI_RTC
16 : #include "rusefi_types.h"
17 : #endif // EFI_RTC
18 :
19 : #if EFI_PROD_CODE
20 : #include <sys/time.h>
21 :
22 : // Lua needs this function, but we don't necessarily have to implement it
23 : extern "C" int _gettimeofday(timeval* tv, void* tzvp) {
24 : (void)tv; (void)tzvp;
25 : return 0;
26 : }
27 : #endif // EFI_PROD_CODE
28 :
29 : #if EFI_RTC
30 : void initRtc() {
31 : efiPrintf("initRtc()");
32 : printDateTime(); // this would test RTC, see #311
33 : }
34 :
35 : static const char * const monthAbbrs[] = {
36 : "Jan", "Feb", "Mar",
37 : "Apr", "May", "Jun",
38 : "Jul", "Aug", "Sep",
39 : "Oct", "Nov", "Dec"
40 : };
41 :
42 : void printRtcDateTime() {
43 : efidatetime_t dateTime = getRtcDateTime();
44 : // prints the date like: 19 sep 2022 21:19:55
45 : efiPrintf("Current RTC time: %02u %s %04u %02u:%02u:%02u",
46 : dateTime.day, monthAbbrs[dateTime.month - 1], dateTime.year,
47 : dateTime.hour, dateTime.minute, dateTime.second);
48 : }
49 :
50 : void setRtcDateTime(efidatetime_t const * const dateTime) {
51 : RTCDateTime timespec = convertRtcDateTimeFromEfi(dateTime);
52 : rtcSetTime(&RTCD1, ×pec);
53 : }
54 :
55 : efidatetime_t getRtcDateTime() {
56 : RTCDateTime timespec;
57 : rtcGetTime(&RTCD1, ×pec);
58 : return convertRtcDateTimeToEfi(×pec);
59 : }
60 :
61 : efidatetime_t convertRtcDateTimeToEfi(RTCDateTime const * const timespec) {
62 : uint32_t second = timespec->millisecond / 1000;
63 : uint16_t minute = second / 60;
64 : second -= minute * 60;
65 : uint8_t hour = minute / 60;
66 : minute -= hour * 60;
67 :
68 : efidatetime_t const dateTime = {
69 : .year = timespec->year + RTC_BASE_YEAR,
70 : .month = (uint8_t)timespec->month,
71 : .day = (uint8_t)timespec->day,
72 : .hour = hour,
73 : .minute = (uint8_t)minute,
74 : .second = (uint8_t)second,
75 : };
76 : return dateTime;
77 : }
78 :
79 : RTCDateTime convertRtcDateTimeFromEfi(efidatetime_t const * const dateTime) {
80 : RTCDateTime timespec;
81 : timespec.year = dateTime->year - RTC_BASE_YEAR; // ChibiOS year origin is e.g. 1980
82 : timespec.month = dateTime->month; // [1..12]
83 : timespec.day = dateTime->day; // [1..31]
84 : timespec.millisecond = (((dateTime->hour * 60) + dateTime->minute) * 60 + dateTime->second) * 1000; // ms since midnight
85 : timespec.dayofweek = RTC_DAY_CATURDAY; // CATURDAY: 0 ... ?
86 : timespec.dstflag = 0; // 0 ... ?
87 : return timespec;
88 : }
89 :
90 : // TODO(nms): move to e.g. efitime ?
91 :
92 : static void put2(int offset, char *lcd_str, int value) {
93 : static char buff[_MAX_FILLER];
94 : efiAssertVoid(ObdCode::CUSTOM_ERR_6666, value >=0 && value <100, "value");
95 : itoa10(buff, value);
96 : if (value < 10) {
97 : lcd_str[offset] = '0';
98 : lcd_str[offset + 1] = buff[0];
99 : } else {
100 : lcd_str[offset] = buff[0];
101 : lcd_str[offset + 1] = buff[1];
102 : }
103 : }
104 : #endif // EFI_RTC
105 :
106 :
107 : /**
108 : * @return true if we seem to know current date, false if no valid RTC state
109 : */
110 0 : bool dateToStringShort(char *lcd_str) {
111 : #if EFI_RTC
112 : strcpy(lcd_str, "000000_000000\0");
113 : efidatetime_t dateTime = getRtcDateTime();
114 : if (dateTime.year < 2016 || dateTime.year > 2030) {
115 : // 2016 to 2030 is the valid range
116 : lcd_str[0] = 0;
117 : return false;
118 : }
119 :
120 : put2(0, lcd_str, dateTime.year % 100); // year, format as just the last two digits
121 : put2(2, lcd_str, dateTime.month); // month 1-12
122 : put2(4, lcd_str, dateTime.day); // day of the month 1-31
123 :
124 : put2(7, lcd_str, dateTime.hour); // hours since midnight 0-23
125 : put2(9, lcd_str, dateTime.minute); // minutes
126 : put2(11, lcd_str, dateTime.second); // seconds
127 :
128 : return true;
129 : #else // EFI_RTC
130 0 : lcd_str[0] = 0;
131 0 : return false;
132 : #endif // EFI_RTC
133 : }
134 :
135 0 : void dateToString(char *lcd_str) {
136 : #if EFI_RTC
137 : // todo:
138 : // 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,
139 : // timp.tm_min, timp.tm_sec);
140 : // this would require a temporary mem stream - see datalogging and other existing usages
141 :
142 : strcpy(lcd_str, "00/00 00:00:00\0");
143 : efidatetime_t dateTime = getRtcDateTime();
144 :
145 : put2(0, lcd_str, dateTime.month);
146 : put2(3, lcd_str, dateTime.day);
147 : put2(6, lcd_str, dateTime.hour);
148 : put2(9, lcd_str, dateTime.minute);
149 : put2(12, lcd_str, dateTime.second);
150 : #else // EFI_RTC
151 0 : lcd_str[0] = 0;
152 : #endif // EFI_RTC
153 0 : }
|