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:
parent
ea889e109e
commit
c17ce0e89e
@ -21,6 +21,7 @@ FEATURES_WANTED = [
|
||||
"power_manager",
|
||||
"power_save",
|
||||
"rgb_led",
|
||||
"rtc",
|
||||
"secure_domain",
|
||||
"tropic",
|
||||
"usb",
|
||||
|
@ -42,6 +42,7 @@ FEATURES_WANTED = [
|
||||
"power_manager",
|
||||
"power_save",
|
||||
"rgb_led",
|
||||
"rtc",
|
||||
"sd_card",
|
||||
"secmon_layout",
|
||||
"tropic",
|
||||
|
@ -26,6 +26,7 @@ FEATURES_WANTED = [
|
||||
"power_manager",
|
||||
"power_save",
|
||||
"rgb_led",
|
||||
"rtc",
|
||||
"sbu",
|
||||
"sd_card",
|
||||
"secure_domain",
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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) {}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
41
core/embed/sys/time/inc/sys/rtc.h
Normal file
41
core/embed/sys/time/inc/sys/rtc.h
Normal 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);
|
112
core/embed/sys/time/stm32u5/rtc.c
Normal file
112
core/embed/sys/time/stm32u5/rtc.c
Normal 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
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user