|
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