diff --git a/application.c b/application.c index 20222e3..ebc8dc0 100644 --- a/application.c +++ b/application.c @@ -46,6 +46,9 @@ static volatile bool wakeup_flag = false; /**< flag set when wakeup timer trigge static volatile bool second_flag = false; /**< flag set when a second passed */ /** @} */ +/** number of seconds since boot */ +static uint32_t boot_time = 0; + size_t putc(char c) { size_t length = 0; // number of characters printed @@ -81,14 +84,36 @@ static void command_version(void* argument) printf("device serial: %08x%08x%08x\n", DESIG_UNIQUE_ID2, DESIG_UNIQUE_ID1, DESIG_UNIQUE_ID0); // show complete serial (different than the one used for USB) } +/** convert RTC date/time to number of seconds + * @return number of seconds since 2000-01-01 00:00:00 + * @warning for simplicity I consider every month to have 31 days + */ +static uint32_t rtc_to_seconds(void) +{ + rtc_wait_for_synchro(); // wait until date/time is synchronised + const uint8_t year = ((RTC_DR >> RTC_DR_YT_SHIFT) & RTC_DR_YT_MASK) * 10 + ((RTC_DR >> RTC_DR_YU_SHIFT) & RTC_DR_YU_MASK); // get year + uint8_t month = ((RTC_DR >> RTC_DR_MT_SHIFT) & RTC_DR_MT_MASK) * 10 + ((RTC_DR >> RTC_DR_MU_SHIFT) & RTC_DR_MU_MASK); // get month + if (month > 0) { // month has been initialized, but starts with 1 + month--; // fix for calculation + } + uint8_t day = ((RTC_DR >> RTC_DR_DT_SHIFT) & RTC_DR_DT_MASK) * 10 + ((RTC_DR >> RTC_DR_DU_SHIFT) & RTC_DR_DU_MASK); // get day + if (day > 0) { // day has been initialized, but starts with 1 + day--; // fix for calculation + } + const uint8_t hour = ((RTC_TR >> RTC_TR_HT_SHIFT) & RTC_TR_HT_MASK) * 10 + ((RTC_TR >> RTC_TR_HU_SHIFT) & RTC_TR_HU_MASK); // get hours + const uint8_t minute = ((RTC_TR >> RTC_TR_MNT_SHIFT) & RTC_TR_MNT_MASK) * 10 + ((RTC_TR >> RTC_TR_MNU_SHIFT) & RTC_TR_MNU_MASK); // get minutes + const uint8_t second = ((RTC_TR >> RTC_TR_ST_SHIFT) & RTC_TR_ST_MASK) * 10 + ((RTC_TR >> RTC_TR_SU_SHIFT) & RTC_TR_SU_MASK); // get seconds + const uint32_t seconds = ((((((((year * 12) + month) * 31) + day) * 24) + hour) * 24) + minute) * 60 + second; // convert to number of seconds + return seconds; +} + /** show uptime * @param[in] argument no argument required */ static void command_uptime(void* argument) { (void)argument; // we won't use the argument - // TODO calculate time difference - const uint32_t uptime = 0; // get time from internal RTC + const uint32_t uptime = rtc_to_seconds() - boot_time; // get time from internal RTC printf("uptime: %u.%02u:%02u:%02u\n", uptime / (24 * 60 * 60), (uptime / (60 * 60)) % 24, (uptime / 60) % 60, uptime % 60); } @@ -410,6 +435,7 @@ void main(void) rtc_lock(); // protect RTC register against writing pwr_enable_backup_domain_write_protect(); // re-enable protection now that we configured the RTC clock } + boot_time = rtc_to_seconds(); // remember the start time puts("OK\n"); // setup wakeup timer for periodic checks