GCC Code Coverage Report


Directory: ./
File: firmware/hw_layer/rtc_helper.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 0.0% 0 0 3
Functions: 0.0% 0 0 1
Branches: -% 0 0 0
Decisions: -% 0 - 0

Line Branch Decision Exec Source
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
31 void PUBLIC_API_WEAK hal_lld_rtc_fixup(void) {
32 /* nop */
33 }
34
35 void initRtc() {
36 efiPrintf("initRtc()");
37 hal_lld_rtc_fixup();
38 printDateTime(); // this would test RTC, see #311
39 }
40
41 static const char * const monthAbbrs[] = {
42 "Jan", "Feb", "Mar",
43 "Apr", "May", "Jun",
44 "Jul", "Aug", "Sep",
45 "Oct", "Nov", "Dec"
46 };
47
48 void printRtcDateTime() {
49 efidatetime_t dateTime = getRtcDateTime();
50 // prints the date like: 19 sep 2022 21:19:55
51 efiPrintf("Current RTC time: %02u %s %04lu %02u:%02u:%02u",
52 dateTime.day, monthAbbrs[dateTime.month - 1], dateTime.year,
53 dateTime.hour, dateTime.minute, dateTime.second);
54 }
55
56 void setRtcDateTime(efidatetime_t const * const dateTime) {
57 RTCDateTime timespec = convertRtcDateTimeFromEfi(dateTime);
58 rtcSetTime(&RTCD1, &timespec);
59 }
60
61 static time_t rtc_encode(const RTCDateTime *timespec) {
62 struct tm tim;
63
64 // todo: looks like this pulls a lot of library code? 4K+?
65 // todo: reimplement lighter? https://github.com/rusefi/rusefi/issues/6876
66 rtcConvertDateTimeToStructTm(timespec, &tim, NULL);
67 return mktime(&tim);
68 }
69
70 uint32_t getEpochTime() {
71 RTCDateTime timespec;
72 rtcGetTime(&RTCD1, &timespec);
73 return rtc_encode(&timespec);
74 }
75
76 efidatetime_t getRtcDateTime() {
77 RTCDateTime timespec;
78 rtcGetTime(&RTCD1, &timespec);
79 return convertRtcDateTimeToEfi(&timespec);
80 }
81
82 efidatetime_t convertRtcDateTimeToEfi(RTCDateTime const * const timespec) {
83 uint32_t second = timespec->millisecond / 1000;
84 uint16_t minute = second / 60;
85 second -= minute * 60;
86 uint8_t hour = minute / 60;
87 minute -= hour * 60;
88
89 efidatetime_t const dateTime = {
90 .year = timespec->year + RTC_BASE_YEAR,
91 .month = (uint8_t)timespec->month,
92 .day = (uint8_t)timespec->day,
93 .hour = hour,
94 .minute = (uint8_t)minute,
95 .second = (uint8_t)second,
96 };
97 return dateTime;
98 }
99
100 RTCDateTime convertRtcDateTimeFromEfi(efidatetime_t const * const dateTime) {
101 RTCDateTime timespec;
102 timespec.year = dateTime->year - RTC_BASE_YEAR; // ChibiOS year origin is e.g. 1980
103 timespec.month = dateTime->month; // [1..12]
104 timespec.day = dateTime->day; // [1..31]
105 timespec.millisecond = (((dateTime->hour * 60) + dateTime->minute) * 60 + dateTime->second) * 1000; // ms since midnight
106 timespec.dayofweek = RTC_DAY_CATURDAY; // CATURDAY: 0 ... ?
107 timespec.dstflag = 0; // 0 ... ?
108 return timespec;
109 }
110
111 // TODO(nms): move to e.g. efitime ?
112
113 static void putTwoSymbolDecimal(int offset, char *destination, int value) {
114 static char buff[_MAX_FILLER];
115 efiAssertVoid(ObdCode::CUSTOM_ERR_6666, value >=0 && value <100, "value");
116 itoa10(buff, value);
117 if (value < 10) {
118 destination[offset] = '0';
119 destination[offset + 1] = buff[0];
120 } else {
121 destination[offset] = buff[0];
122 destination[offset + 1] = buff[1];
123 }
124 }
125 #endif // EFI_RTC
126
127
128 /**
129 * @return true if we seem to know current date, false if no valid RTC state
130 */
131 bool dateToStringShort(char *destination) {
132 #if EFI_RTC
133 strcpy(destination, "000000_000000\0");
134 efidatetime_t dateTime = getRtcDateTime();
135 if (dateTime.year < 2016 || dateTime.year > 2030) {
136 // 2016 to 2030 is the valid range
137 destination[0] = 0;
138 return false;
139 }
140
141 putTwoSymbolDecimal(0, destination, dateTime.year % 100); // year, format as just the last two digits
142 putTwoSymbolDecimal(2, destination, dateTime.month); // month 1-12
143 putTwoSymbolDecimal(4, destination, dateTime.day); // day of the month 1-31
144
145 putTwoSymbolDecimal(7, destination, dateTime.hour); // hours since midnight 0-23
146 putTwoSymbolDecimal(9, destination, dateTime.minute); // minutes
147 putTwoSymbolDecimal(11, destination, dateTime.second); // seconds
148
149 return true;
150 #else // EFI_RTC
151 destination[0] = 0;
152 return false;
153 #endif // EFI_RTC
154 }
155
156 /*
157 void dateToString(char *destination) {
158 #if EFI_RTC
159 // todo:
160 // 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,
161 // timp.tm_min, timp.tm_sec);
162 // this would require a temporary mem stream - see datalogging and other existing usages
163
164 strcpy(destination, "00/00 00:00:00\0");
165 efidatetime_t dateTime = getRtcDateTime();
166
167 putTwoSymbolDecimal(0, destination, dateTime.month);
168 putTwoSymbolDecimal(3, destination, dateTime.day);
169 putTwoSymbolDecimal(6, destination, dateTime.hour);
170 putTwoSymbolDecimal(9, destination, dateTime.minute);
171 putTwoSymbolDecimal(12, destination, dateTime.second);
172 #else // EFI_RTC
173 destination[0] = 0;
174 #endif // EFI_RTC
175 }
176 */
177