mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-27 00:48:12 +00:00
feat(core): add rtc_get_timestamp function to RTC module.
[no changelog]
This commit is contained in:
parent
50481cb0b0
commit
847e5224ec
@ -29,6 +29,18 @@
|
|||||||
*/
|
*/
|
||||||
bool rtc_init(void);
|
bool rtc_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the current timestamp from the RTC
|
||||||
|
*
|
||||||
|
* Retrieves the current timestamp as a number of seconds since the device got
|
||||||
|
* powered up for the first time. The timestamp is calculated based on the
|
||||||
|
* current date and time stored in the RTC.
|
||||||
|
*
|
||||||
|
* @param timestamp Pointer to a variable where the timestamp will be stored.
|
||||||
|
* @return true if the timestamp was successfully retrieved, false otherwise
|
||||||
|
*/
|
||||||
|
bool rtc_get_timestamp(uint32_t* timestamp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Callback invoked when the RTC wakeup event occurs
|
* @brief Callback invoked when the RTC wakeup event occurs
|
||||||
*
|
*
|
||||||
|
@ -40,6 +40,9 @@ static rtc_driver_t g_rtc_driver = {
|
|||||||
.initialized = false,
|
.initialized = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static uint32_t rtc_calendar_to_timestamp(const RTC_DateTypeDef* date,
|
||||||
|
const RTC_TimeTypeDef* time);
|
||||||
|
|
||||||
bool rtc_init(void) {
|
bool rtc_init(void) {
|
||||||
rtc_driver_t* drv = &g_rtc_driver;
|
rtc_driver_t* drv = &g_rtc_driver;
|
||||||
|
|
||||||
@ -72,6 +75,33 @@ bool rtc_init(void) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool rtc_get_timestamp(uint32_t* timestamp) {
|
||||||
|
rtc_driver_t* drv = &g_rtc_driver;
|
||||||
|
|
||||||
|
if (!drv->initialized || timestamp == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTC_DateTypeDef date;
|
||||||
|
RTC_TimeTypeDef time;
|
||||||
|
|
||||||
|
// Get current time and date,
|
||||||
|
// Important: GetTime has to be called before the GetDate in order to unlock
|
||||||
|
// the values in higher-order callendar.
|
||||||
|
if (HAL_OK != HAL_RTC_GetTime(&drv->hrtc, &time, RTC_FORMAT_BCD)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current date
|
||||||
|
if (HAL_OK != HAL_RTC_GetDate(&drv->hrtc, &date, RTC_FORMAT_BCD)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*timestamp = rtc_calendar_to_timestamp(&date, &time);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool rtc_wakeup_timer_start(uint32_t seconds, rtc_wakeup_callback_t callback,
|
bool rtc_wakeup_timer_start(uint32_t seconds, rtc_wakeup_callback_t callback,
|
||||||
void* context) {
|
void* context) {
|
||||||
rtc_driver_t* drv = &g_rtc_driver;
|
rtc_driver_t* drv = &g_rtc_driver;
|
||||||
@ -139,4 +169,56 @@ void RTC_IRQHandler(void) {
|
|||||||
IRQ_LOG_EXIT();
|
IRQ_LOG_EXIT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const uint8_t days_in_month[] = {
|
||||||
|
31, // January
|
||||||
|
28, // February (not considering leap years here)
|
||||||
|
31, // March
|
||||||
|
30, // April
|
||||||
|
31, // May
|
||||||
|
30, // June
|
||||||
|
31, // July
|
||||||
|
31, // August
|
||||||
|
30, // September
|
||||||
|
31, // October
|
||||||
|
30, // November
|
||||||
|
31 // December
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t bcd2bin(uint8_t val) { return (val & 0x0F) + ((val >> 4) * 10); }
|
||||||
|
|
||||||
|
// Check for leap year
|
||||||
|
static int is_leap_year(int year) {
|
||||||
|
return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t rtc_calendar_to_timestamp(const RTC_DateTypeDef* date,
|
||||||
|
const RTC_TimeTypeDef* time) {
|
||||||
|
uint8_t year = bcd2bin(date->Year); // 0..99
|
||||||
|
uint8_t month = bcd2bin(date->Month); // 1..12
|
||||||
|
uint8_t day = bcd2bin(date->Date); // 1..31
|
||||||
|
uint8_t hour = bcd2bin(time->Hours);
|
||||||
|
uint8_t min = bcd2bin(time->Minutes);
|
||||||
|
uint8_t sec = bcd2bin(time->Seconds);
|
||||||
|
|
||||||
|
// STM RTC starts at 2000, so we need to offset the year evey time we
|
||||||
|
// calculate the leap years.
|
||||||
|
|
||||||
|
uint32_t days = 0;
|
||||||
|
for (int y = 0; y < year; ++y) {
|
||||||
|
days += 365;
|
||||||
|
if (is_leap_year(y + 2000)) days += 1;
|
||||||
|
}
|
||||||
|
for (int m = 1; m < month; ++m) {
|
||||||
|
days += days_in_month[m - 1];
|
||||||
|
if (m == 2 && is_leap_year(year + 2000)) days += 1;
|
||||||
|
}
|
||||||
|
days += day - 1;
|
||||||
|
|
||||||
|
uint32_t seconds = days * 86400 + hour * 3600 + min * 60 + sec;
|
||||||
|
|
||||||
|
// Unix epoch starts at 1970, STM32 RTC at 2000
|
||||||
|
// 946684800 = seconds from 1970-01-01 to 2000-01-01
|
||||||
|
return seconds + 946684800;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // KERNEL_MODE
|
#endif // KERNEL_MODE
|
||||||
|
Loading…
Reference in New Issue
Block a user