1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-29 18:08:19 +00:00

feat(core): wake up from suspend mode after timeout

[no changelog]
This commit is contained in:
cepetr 2025-06-17 14:23:58 +02:00 committed by cepetr
parent ea889e109e
commit c17ce0e89e
16 changed files with 213 additions and 5 deletions

View File

@ -21,6 +21,7 @@ FEATURES_WANTED = [
"power_manager",
"power_save",
"rgb_led",
"rtc",
"secure_domain",
"tropic",
"usb",

View File

@ -42,6 +42,7 @@ FEATURES_WANTED = [
"power_manager",
"power_save",
"rgb_led",
"rtc",
"sd_card",
"secmon_layout",
"tropic",

View File

@ -26,6 +26,7 @@ FEATURES_WANTED = [
"power_manager",
"power_save",
"rgb_led",
"rtc",
"sbu",
"sd_card",
"secure_domain",

View File

@ -59,6 +59,9 @@
#ifdef USE_HASH_PROCESSOR
#include <sec/hash_processor.h>
#endif
#ifdef USE_RTC
#include <sys/rtc.h>
#endif
#ifdef USE_TAMPER
#include <sys/tamper.h>
#endif
@ -225,12 +228,17 @@ static void drivers_init(secbool manufacturing_mode,
#ifdef USE_HASH_PROCESSOR
hash_processor_init();
#endif
display_init(DISPLAY_RESET_CONTENT);
#ifdef USE_TAMPER
tamper_init();
#endif
#ifdef USE_RTC
rtc_init();
#endif
display_init(DISPLAY_RESET_CONTENT);
#ifdef USE_TOUCH
*touch_initialized = touch_init();
if (manufacturing_mode != sectrue) {

View File

@ -83,6 +83,10 @@
#include <io/rgb_led.h>
#endif
#ifdef USE_RTC
#include <sys/rtc.h>
#endif
#ifdef SYSTEM_VIEW
#include <sys/systemview.h>
#endif
@ -122,6 +126,10 @@ void drivers_init() {
#endif
#endif // SECURE_MODE
#ifdef USE_RTC
rtc_init();
#endif
#ifdef USE_CONSUMPTION_MASK
consumption_mask_init();
#endif

View File

@ -62,6 +62,10 @@
#include "cmd/prodtest_optiga.h"
#endif
#ifdef USE_RTC
#include <sys/rtc.h>
#endif
#ifdef USE_TROPIC
#include <sec/tropic.h>
#endif
@ -196,6 +200,9 @@ static bool g_rgbled_control_disabled = false;
void prodtest_disable_rgbled_control(void) { g_rgbled_control_disabled = true; }
static void drivers_init(void) {
#ifdef USE_RTC
rtc_init();
#endif
#ifdef USE_BACKUP_RAM
backup_ram_init();
#endif

View File

@ -28,7 +28,7 @@ typedef enum {
PM_WAKEUP_FLAG_BLE = 0x1 << 2, // Bluetooth connection event
PM_WAKEUP_FLAG_NFC = 0x1 << 3, // NFC event
PM_WAKEUP_FLAG_USB = 0x1 << 4, // USB event
PM_WAKEUP_FLAG_TIMER = 0x1 << 5, // Timer event
PM_WAKEUP_FLAG_RTC = 0x1 << 5, // RTC wake-up timer
} pm_wakeup_flags_t;
/* power manager status codes */

View File

@ -41,7 +41,7 @@ pm_status_t pm_control_hibernate() {
return PM_ERROR;
}
void pm_control_suspend() {
pm_wakeup_flags_t pm_control_suspend(void) {
// Clear all wakeup flags. From this point, any wakeup event that
// sets a wakeup flag causes this function to return.
pm_wakeup_flags_reset();
@ -94,6 +94,8 @@ void pm_control_suspend() {
// Reinitialize all drivers that were stopped earlier
power_save_resume_io(&wakeup_params);
return wakeup_flags;
}
static void pm_background_tasks_suspend(void) {}

View File

@ -25,6 +25,10 @@
#include <sys/systimer.h>
#include <trezor_rtl.h>
#ifdef USE_RTC
#include <sys/rtc.h>
#endif
#include "../power_manager_poll.h"
#include "../stwlc38/stwlc38.h"
#include "power_manager_internal.h"
@ -223,7 +227,16 @@ pm_status_t pm_suspend(void) {
irq_unlock(irq_key);
pm_control_suspend();
#ifdef USE_RTC
// TODO: Uncomment to wake up by RTC timer
// Automatically wakes up after 10 seconds with PM_WAKEUP_FLAG_RTC set
// rtc_wakeup_timer_start(10);
#endif
pm_wakeup_flags_t wakeup_flags = pm_control_suspend();
// TODO: Handle wake-up flags
UNUSED(wakeup_flags);
// Exit hibernation state if it was requested
irq_key = irq_lock();

View File

@ -141,4 +141,5 @@ void pm_battery_initial_soc_guess(void);
pm_status_t pm_control_hibernate(void);
// Power manager control function which puts device into suspend mode.
void pm_control_suspend(void);
// Returns the wakeup flags that caused the device to wake up.
pm_wakeup_flags_t pm_control_suspend(void);

View File

@ -0,0 +1,41 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/**
* @brief Initialize the RTC driver
*
* Before initialization, the RCC clock for the RTC must be configured to
* 32.768 kHz (using either LSE or LSI).
*
* @return true if initialization was successful, false otherwise
*/
bool rtc_init(void);
/**
* @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
* number of seconds. After waking up, the PM_WAKEUP_FLAG_RTC flag is set.
*
* @param seconds Number of seconds (1 to 65536) to wait before waking up.
* @return true if the wakeup was successfully scheduled, false otherwise
*/
bool rtc_wakeup_timer_start(uint32_t seconds);

View File

@ -0,0 +1,112 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef KERNEL_MODE
#include <trezor_bsp.h>
#include <trezor_rtl.h>
#include <sys/irq.h>
#include <sys/mpu.h>
#include <sys/power_manager.h>
#include <sys/rtc.h>
// RTC driver structure
typedef struct {
bool initialized;
RTC_HandleTypeDef hrtc;
} rtc_driver_t;
// RTC driver instance
static rtc_driver_t g_rtc_driver = {
.initialized = false,
};
bool rtc_init(void) {
rtc_driver_t* drv = &g_rtc_driver;
if (drv->initialized) {
return true;
}
memset(drv, 0, sizeof(rtc_driver_t));
drv->hrtc.Instance = RTC;
drv->hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
drv->hrtc.Init.AsynchPrediv = 128 - 1;
drv->hrtc.Init.SynchPrediv = 256 - 1;
drv->hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
drv->hrtc.Init.BinMode = RTC_BINARY_NONE;
if (HAL_OK != HAL_RTC_Init(&drv->hrtc)) {
return false;
}
// Allow waking up from STOP mode
RCC->APB3SMENR &= ~RCC_APB3SMENR_RTCAPBSMEN;
RCC->SRDAMR |= RCC_SRDAMR_RTCAPBAMEN;
NVIC_ClearPendingIRQ(RTC_IRQn);
NVIC_SetPriority(RTC_IRQn, IRQ_PRI_NORMAL);
NVIC_EnableIRQ(RTC_IRQn);
drv->initialized = true;
return true;
}
bool rtc_wakeup_timer_start(uint32_t seconds) {
rtc_driver_t* drv = &g_rtc_driver;
if (!drv->initialized) {
return false;
}
if (seconds < 1 || seconds > 0x10000) {
return false;
}
HAL_StatusTypeDef status;
status = HAL_RTCEx_SetWakeUpTimer_IT(&drv->hrtc, seconds - 1,
RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 0);
if (HAL_OK != status) {
return false;
}
return true;
}
void RTC_IRQHandler(void) {
IRQ_LOG_ENTER();
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT);
if (READ_BIT(RTC->MISR, RTC_MISR_WUTMF) != 0U) {
// Clear the wakeup timer interrupt flag
WRITE_REG(RTC->SCR, RTC_SCR_CWUTF);
// Deactivate the wakeup timer to prevent re-triggering
HAL_RTCEx_DeactivateWakeUpTimer(&g_rtc_driver.hrtc);
// Signal the wakeup event to the power manager
pm_wakeup_flags_set(PM_WAKEUP_FLAG_RTC);
}
mpu_restore(mpu_mode);
IRQ_LOG_EXIT();
}
#endif // KERNEL_MODE

View File

@ -97,6 +97,10 @@ def configure(
paths += ["embed/sys/backup_ram/inc"]
defines += [("USE_BACKUP_RAM", "1")]
if "rtc" in features_wanted:
sources += ["embed/sys/time/stm32u5/rtc.c"]
defines += [("USE_RTC", "1")]
if "haptic" in features_wanted:
sources += [
"embed/io/haptic/drv2625/drv2625.c",

View File

@ -98,6 +98,10 @@ def configure(
paths += ["embed/sys/backup_ram/inc"]
defines += [("USE_BACKUP_RAM", "1")]
if "rtc" in features_wanted:
sources += ["embed/sys/time/stm32u5/rtc.c"]
defines += [("USE_RTC", "1")]
if "haptic" in features_wanted:
sources += [
"embed/io/haptic/drv2625/drv2625.c",

View File

@ -97,6 +97,10 @@ def configure(
paths += ["embed/sys/backup_ram/inc"]
defines += [("USE_BACKUP_RAM", "1")]
if "rtc" in features_wanted:
sources += ["embed/sys/time/stm32u5/rtc.c"]
defines += [("USE_RTC", "1")]
if "haptic" in features_wanted:
sources += [
"embed/io/haptic/drv2625/drv2625.c",

View File

@ -73,6 +73,7 @@ def stm32u5_common_files(env, features_wanted, defines, sources, paths):
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_rcc.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_rcc_ex.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_rtc.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_rtc_ex.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_spi.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_sram.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_tim.c",