mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-15 19:18:11 +00:00
feat(core): add rtc wake-up callback
[no changelog]
This commit is contained in:
parent
4672745a5b
commit
995caca9c7
@ -209,6 +209,22 @@ pm_status_t pm_get_state(pm_state_t* state) {
|
|||||||
return PM_OK;
|
return PM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This callback is called from inside the system_suspend() function
|
||||||
|
// when the rtc wake-up timer expires. The callback can perform
|
||||||
|
// measurements and update the fuel gauge state.
|
||||||
|
// - The callback can schedule the next wake-up by calling
|
||||||
|
// rtc_wakeup_timer_start().
|
||||||
|
// - If the callback return with wakeup_flags set, system_suspend() returns.
|
||||||
|
void pm_rtc_wakeup_callback(void* context) {
|
||||||
|
// TODO: update fuel gauge state
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
rtc_wakeup_timer_start(0, pm_rtc_wakeup_callback, NULL);
|
||||||
|
} else {
|
||||||
|
wakeup_flags_set(WAKEUP_FLAG_RTC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pm_status_t pm_suspend(wakeup_flags_t* wakeup_reason) {
|
pm_status_t pm_suspend(wakeup_flags_t* wakeup_reason) {
|
||||||
pm_driver_t* drv = &g_pm;
|
pm_driver_t* drv = &g_pm;
|
||||||
|
|
||||||
@ -234,13 +250,14 @@ pm_status_t pm_suspend(wakeup_flags_t* wakeup_reason) {
|
|||||||
irq_unlock(irq_key);
|
irq_unlock(irq_key);
|
||||||
|
|
||||||
#ifdef USE_RTC
|
#ifdef USE_RTC
|
||||||
// TODO: Uncomment to wake up by RTC timer
|
// Automatically wakes up after specified time and call pm_rtc_wakeup_callback
|
||||||
// Automatically wakes up after 10 seconds with PM_WAKEUP_FLAG_RTC set
|
rtc_wakeup_timer_start(10, pm_rtc_wakeup_callback, NULL);
|
||||||
// rtc_wakeup_timer_start(10);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wakeup_flags_t wakeup_flags = system_suspend();
|
wakeup_flags_t wakeup_flags = system_suspend();
|
||||||
|
|
||||||
|
rtc_wakeup_timer_stop();
|
||||||
|
|
||||||
// TODO: Handle wake-up flags
|
// TODO: Handle wake-up flags
|
||||||
// UNUSED(wakeup_flags);
|
// UNUSED(wakeup_flags);
|
||||||
|
|
||||||
|
@ -29,13 +29,29 @@
|
|||||||
*/
|
*/
|
||||||
bool rtc_init(void);
|
bool rtc_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback invoked when the RTC wakeup event occurs
|
||||||
|
*
|
||||||
|
* @param context Context pointer passed to rtc_wakeup_timer_start
|
||||||
|
*/
|
||||||
|
typedef void (*rtc_wakeup_callback_t)(void* context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Schedule a wakeup event after a specified number of seconds
|
* @brief Schedule a wakeup event after a specified number of seconds
|
||||||
*
|
*
|
||||||
* Configures the RTC to wake up the system from STOP mode after the specified
|
* Configures the RTC to wake up the system from STOP mode after the specified
|
||||||
* number of seconds. After waking up, the PM_WAKEUP_FLAG_RTC flag is set.
|
* number of seconds. After waking up, callback is called if not NULL otherwise
|
||||||
|
* the WAKEUP_FLAG_RTC flag is set.
|
||||||
*
|
*
|
||||||
* @param seconds Number of seconds (1 to 65536) to wait before waking up.
|
* @param seconds Number of seconds (1 to 65536) to wait before waking up.
|
||||||
|
* @param callback Callback function to be called when the wakeup event occurs.
|
||||||
|
* @param context Context pointer to be passed to the callback function.
|
||||||
* @return true if the wakeup was successfully scheduled, false otherwise
|
* @return true if the wakeup was successfully scheduled, false otherwise
|
||||||
*/
|
*/
|
||||||
bool rtc_wakeup_timer_start(uint32_t seconds);
|
bool rtc_wakeup_timer_start(uint32_t seconds, rtc_wakeup_callback_t callback,
|
||||||
|
void* context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop the RTC wakeup timer
|
||||||
|
*/
|
||||||
|
void rtc_wakeup_timer_stop(void);
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
bool initialized;
|
bool initialized;
|
||||||
RTC_HandleTypeDef hrtc;
|
RTC_HandleTypeDef hrtc;
|
||||||
|
rtc_wakeup_callback_t callback;
|
||||||
|
void* callback_context;
|
||||||
} rtc_driver_t;
|
} rtc_driver_t;
|
||||||
|
|
||||||
// RTC driver instance
|
// RTC driver instance
|
||||||
@ -70,7 +72,8 @@ bool rtc_init(void) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_wakeup_timer_start(uint32_t seconds) {
|
bool rtc_wakeup_timer_start(uint32_t seconds, rtc_wakeup_callback_t callback,
|
||||||
|
void* context) {
|
||||||
rtc_driver_t* drv = &g_rtc_driver;
|
rtc_driver_t* drv = &g_rtc_driver;
|
||||||
|
|
||||||
if (!drv->initialized) {
|
if (!drv->initialized) {
|
||||||
@ -81,6 +84,11 @@ bool rtc_wakeup_timer_start(uint32_t seconds) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
irq_key_t irq_key = irq_lock();
|
||||||
|
drv->callback = callback;
|
||||||
|
drv->callback_context = context;
|
||||||
|
irq_unlock(irq_key);
|
||||||
|
|
||||||
HAL_StatusTypeDef status;
|
HAL_StatusTypeDef status;
|
||||||
|
|
||||||
status = HAL_RTCEx_SetWakeUpTimer_IT(&drv->hrtc, seconds - 1,
|
status = HAL_RTCEx_SetWakeUpTimer_IT(&drv->hrtc, seconds - 1,
|
||||||
@ -92,18 +100,40 @@ bool rtc_wakeup_timer_start(uint32_t seconds) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rtc_wakeup_timer_stop(void) {
|
||||||
|
rtc_driver_t* drv = &g_rtc_driver;
|
||||||
|
|
||||||
|
if (!drv->initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HAL_RTCEx_DeactivateWakeUpTimer(&drv->hrtc);
|
||||||
|
drv->callback = NULL;
|
||||||
|
drv->callback_context = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void RTC_IRQHandler(void) {
|
void RTC_IRQHandler(void) {
|
||||||
|
rtc_driver_t* drv = &g_rtc_driver;
|
||||||
|
|
||||||
IRQ_LOG_ENTER();
|
IRQ_LOG_ENTER();
|
||||||
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT);
|
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT);
|
||||||
|
|
||||||
if (READ_BIT(RTC->MISR, RTC_MISR_WUTMF) != 0U) {
|
if (READ_BIT(RTC->MISR, RTC_MISR_WUTMF) != 0U) {
|
||||||
// Clear the wakeup timer interrupt flag
|
// Clear the wakeup timer interrupt flag
|
||||||
WRITE_REG(RTC->SCR, RTC_SCR_CWUTF);
|
WRITE_REG(RTC->SCR, RTC_SCR_CWUTF);
|
||||||
|
|
||||||
|
rtc_wakeup_callback_t callback = drv->callback;
|
||||||
|
void* callback_context = drv->callback_context;
|
||||||
|
|
||||||
// Deactivate the wakeup timer to prevent re-triggering
|
// Deactivate the wakeup timer to prevent re-triggering
|
||||||
HAL_RTCEx_DeactivateWakeUpTimer(&g_rtc_driver.hrtc);
|
rtc_wakeup_timer_stop();
|
||||||
// Signal the wakeup event to the power manager
|
|
||||||
|
if (callback != NULL) {
|
||||||
|
callback(callback_context);
|
||||||
|
} else {
|
||||||
wakeup_flags_set(WAKEUP_FLAG_RTC);
|
wakeup_flags_set(WAKEUP_FLAG_RTC);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mpu_restore(mpu_mode);
|
mpu_restore(mpu_mode);
|
||||||
IRQ_LOG_EXIT();
|
IRQ_LOG_EXIT();
|
||||||
|
Loading…
Reference in New Issue
Block a user