あく 3 лет назад
Родитель
Сommit
e8de94ca00

+ 1 - 12
applications/dolphin/helpers/dolphin_state.c

@@ -72,19 +72,8 @@ bool dolphin_state_load(DolphinState* dolphin_state) {
 
 uint64_t dolphin_state_timestamp() {
     FuriHalRtcDateTime datetime;
-    struct tm current;
-
     furi_hal_rtc_get_datetime(&datetime);
-
-    current.tm_year = datetime.year - 1900;
-    current.tm_mday = datetime.day;
-    current.tm_mon = datetime.month - 1;
-
-    current.tm_hour = datetime.hour;
-    current.tm_min = datetime.minute;
-    current.tm_sec = datetime.second;
-
-    return mktime(&current);
+    return furi_hal_rtc_datetime_to_timestamp(&datetime);
 }
 
 bool dolphin_state_is_levelup(uint32_t icounter) {

+ 45 - 0
firmware/targets/f7/furi_hal/furi_hal_rtc.c

@@ -33,6 +33,20 @@ typedef struct {
 
 _Static_assert(sizeof(DeveloperReg) == 4, "DeveloperReg size mismatch");
 
+#define FURI_HAL_RTC_SECONDS_PER_MINUTE 60
+#define FURI_HAL_RTC_SECONDS_PER_HOUR (FURI_HAL_RTC_SECONDS_PER_MINUTE * 60)
+#define FURI_HAL_RTC_SECONDS_PER_DAY (FURI_HAL_RTC_SECONDS_PER_HOUR * 24)
+#define FURI_HAL_RTC_MONTHS_COUNT 12
+#define FURI_HAL_RTC_EPOCH_START_YEAR 1970
+#define FURI_HAL_RTC_IS_LEAP_YEAR(year) \
+    ((((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0))
+
+static const uint8_t furi_hal_rtc_days_per_month[][FURI_HAL_RTC_MONTHS_COUNT] = {
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
+
+static const uint16_t furi_hal_rtc_days_per_year[] = {365, 366};
+
 void furi_hal_rtc_init_early() {
     // LSE and RTC
     LL_PWR_EnableBkUpAccess();
@@ -259,3 +273,34 @@ void furi_hal_rtc_set_pin_fails(uint32_t value) {
 uint32_t furi_hal_rtc_get_pin_fails() {
     return furi_hal_rtc_get_register(FuriHalRtcRegisterPinFails);
 }
+
+uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime) {
+    uint32_t timestamp = 0;
+    uint8_t years = 0;
+    uint8_t leap_years = 0;
+
+    for(uint16_t y = FURI_HAL_RTC_EPOCH_START_YEAR; y < datetime->year; y++) {
+        if(FURI_HAL_RTC_IS_LEAP_YEAR(y)) {
+            leap_years++;
+        } else {
+            years++;
+        }
+    }
+
+    timestamp +=
+        ((years * furi_hal_rtc_days_per_year[0]) + (leap_years * furi_hal_rtc_days_per_year[1])) *
+        FURI_HAL_RTC_SECONDS_PER_DAY;
+
+    uint8_t year_index = (FURI_HAL_RTC_IS_LEAP_YEAR(datetime->year)) ? 1 : 0;
+
+    for(uint8_t m = 0; m < (datetime->month - 1); m++) {
+        timestamp += furi_hal_rtc_days_per_month[year_index][m] * FURI_HAL_RTC_SECONDS_PER_DAY;
+    }
+
+    timestamp += (datetime->day - 1) * FURI_HAL_RTC_SECONDS_PER_DAY;
+    timestamp += datetime->hour * FURI_HAL_RTC_SECONDS_PER_HOUR;
+    timestamp += datetime->minute * FURI_HAL_RTC_SECONDS_PER_MINUTE;
+    timestamp += datetime->second;
+
+    return timestamp;
+}

+ 2 - 0
firmware/targets/furi_hal_include/furi_hal_rtc.h

@@ -93,6 +93,8 @@ void furi_hal_rtc_set_pin_fails(uint32_t value);
 
 uint32_t furi_hal_rtc_get_pin_fails();
 
+uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime);
+
 #ifdef __cplusplus
 }
 #endif