#include "stm32l_rtc.h" #include #include #include void set_rtc(const time_t *time) { // Allow RTC write RTC->WPR = 0xCA; RTC->WPR = 0x53; // Enter RTC init mode RTC->ISR |= RTC_ISR_INIT; chThdSleepMilliseconds(10); // Program clock frequency (32.768kHz crystal) // Reference manual says to write the prescalers in two operations.. RTC->PRER = 0x007F0000; RTC->PRER = 0x007F00FF; // Program the date and time RTC->DR = ( ((1) << 20) | // Year tens ((3) << 16) | // Year units (time->day_of_week << 13) | // Day of week ((0) << 12) | // Month tens ((1) << 8) | // Month units ((0) << 4) | // Day tens ((1) << 0) // Day units ); RTC->TR = ( ((time->hour / 10) << 20) | // Hour tens ((time->hour % 10) << 16) | // Hour units ((time->minute / 10) << 12) | // Minute tens ((time->minute % 10) << 8) | // Minute units ((time->second / 10) << 4) | // Second tens ((time->second % 10) << 0) // Second units ); // Start the RTC RTC->ISR &= ~RTC_ISR_INIT; chThdSleepMilliseconds(10); // Wait for RTC to start } bool get_rtc(time_t *time) { if (!(RTC->ISR & RTC_ISR_INITS)) return false; uint32_t tr = RTC->TR; uint32_t dr = RTC->DR; // Consistency guaranteed by hardware. time->day_of_week = (dr >> 13) & 0x7; time->hour = ((tr >> 20) & 0x3) * 10 + ((tr >> 16) & 0xF); time->minute = ((tr >> 12) & 0x7) * 10 + ((tr >> 8) & 0xF); time->second = ((tr >> 4) & 0x7) * 10 + ((tr >> 0) & 0xF); return true; }