#include "rtc.h" #include static bool time_valid = false; static rtc_t current_time = {2000,1,1,0,0,0}; static VirtualTimer rtc_timer; void rtc_set(const rtc_t *time) { chSysLock(); current_time = *time; time_valid = true; chSysUnlock(); } bool rtc_get(rtc_t *time) { if (!time_valid) return false; chSysLock(); *time = current_time; chSysUnlock(); return true; } static char get_days_in_month(const rtc_t *time) { switch (time->month) { case 4: case 6: case 9: case 11: return 30; case 2: if (time->year % 4 == 0 && (time->year % 100 != 0 || time->year % 400 == 0)) return 29; else return 28; default: return 31; } } static void rtc_increment(void *arg) __attribute__((optimize("O3"))); static void rtc_increment(void *arg) { chSysLockFromIsr(); if (time_valid) { current_time.second++; if (current_time.second == 60) { current_time.second = 0; current_time.minute++; if (current_time.minute == 60) { current_time.minute = 0; current_time.hour++; if (current_time.hour == 24) { current_time.hour = 0; current_time.day++; if (current_time.day > get_days_in_month(¤t_time)) { current_time.day = 1; current_time.month++; if (current_time.month > 12) { current_time.month = 1; current_time.year++; } } } } } } chVTSetI(&rtc_timer, S2ST(1), &rtc_increment, NULL); chSysUnlockFromIsr(); } void rtc_start() { chSysLock(); chVTSetI(&rtc_timer, S2ST(1), &rtc_increment, NULL); chSysUnlock(); }