|
34 | 34 | #include "supervisor/shared/translate.h" |
35 | 35 |
|
36 | 36 | // This is the time in seconds since 2000 that the RTC was started. |
37 | | -static uint32_t rtc_offset = 0; |
| 37 | +__attribute__((section(".uninitialized"))) static uint32_t rtc_offset[3]; |
| 38 | + |
| 39 | +// These values are placed before and after the current RTC count. They are |
| 40 | +// used to determine if the RTC count is valid. These randomly-generated values |
| 41 | +// will be set when the RTC value is set in order to mark the RTC as valid. If |
| 42 | +// the system crashes or reboots, these values will remain undisturbed and the |
| 43 | +// RTC offset will remain valid. |
| 44 | +// |
| 45 | +// If Circuit Python is updated or these symbols shift around, the prefix and |
| 46 | +// suffix will no longer match, and the time will no longer be valid. |
| 47 | +#define RTC_OFFSET_CHECK_PREFIX 0x25ea7e2a |
| 48 | +#define RTC_OFFSET_CHECK_SUFFIX 0x2b80b69e |
| 49 | + |
| 50 | +void common_hal_rtc_init(void) { |
| 51 | + // If the prefix and suffix are not valid, zero-initialize the RTC offset. |
| 52 | + if ((rtc_offset[0] != RTC_OFFSET_CHECK_PREFIX) || (rtc_offset[2] != RTC_OFFSET_CHECK_SUFFIX)) |
| 53 | + rtc_offset[1] = 0; |
| 54 | +} |
38 | 55 |
|
39 | 56 | void common_hal_rtc_get_time(timeutils_struct_time_t *tm) { |
40 | 57 | uint64_t ticks_s = port_get_raw_ticks(NULL) / 1024; |
41 | | - timeutils_seconds_since_2000_to_struct_time(rtc_offset + ticks_s, tm); |
| 58 | + timeutils_seconds_since_2000_to_struct_time(rtc_offset[1] + ticks_s, tm); |
42 | 59 | } |
43 | 60 |
|
44 | 61 | void common_hal_rtc_set_time(timeutils_struct_time_t *tm) { |
45 | 62 | uint64_t ticks_s = port_get_raw_ticks(NULL) / 1024; |
46 | 63 | uint32_t epoch_s = timeutils_seconds_since_2000( |
47 | 64 | tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec |
48 | 65 | ); |
49 | | - rtc_offset = epoch_s - ticks_s; |
| 66 | + rtc_offset[1] = epoch_s - ticks_s; |
| 67 | + |
| 68 | + // Set the prefix and suffix in order to indicate the time is valid. This |
| 69 | + // must be done after the offset is updated, in case there is a crash or |
| 70 | + // power failure. |
| 71 | + rtc_offset[0] = RTC_OFFSET_CHECK_PREFIX; |
| 72 | + rtc_offset[2] = RTC_OFFSET_CHECK_SUFFIX; |
50 | 73 | } |
51 | 74 |
|
52 | 75 | int common_hal_rtc_get_calibration(void) { |
|
0 commit comments