From c89ca35bbcf216049833fd3f7d612fbe94e1f0d6 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Sat, 3 May 2025 16:12:46 +0200 Subject: [PATCH] feat(core): event polling for power manager [no changelog] --- .../prodtest/cmd/prodtest_power_manager.c | 22 +- core/embed/rust/build.rs | 6 + core/embed/rust/src/trezorhal/ffi.rs | 2 + core/embed/rust/src/trezorhal/mod.rs | 5 +- .../embed/rust/src/trezorhal/power_manager.rs | 46 ++++ core/embed/rust/src/trezorhal/sysevent.rs | 15 ++ core/embed/rust/src/ui/component/base.rs | 4 + core/embed/rust/src/ui/event/mod.rs | 5 + core/embed/rust/src/ui/event/power_manager.rs | 16 ++ core/embed/rust/trezorhal.h | 4 + .../sys/power_manager/inc/sys/power_manager.h | 32 +-- .../sys/power_manager/power_manager_poll.c | 198 ++++++++++++++++++ .../sys/power_manager/power_manager_poll.h | 27 +++ .../sys/power_manager/stm32u5/power_manager.c | 23 +- .../stm32u5/power_manager_internal.h | 6 - .../power_manager/stm32u5/power_monitoring.c | 7 +- .../sys/power_manager/stm32u5/power_states.c | 15 +- core/embed/sys/task/inc/sys/sysevent.h | 2 +- .../models/T3W1/trezor_t3w1_revA.py | 1 + .../models/T3W1/trezor_t3w1_revB.py | 1 + .../models/T3W1/trezor_t3w1_revC.py | 1 + 21 files changed, 371 insertions(+), 67 deletions(-) create mode 100644 core/embed/rust/src/trezorhal/power_manager.rs create mode 100644 core/embed/rust/src/ui/event/power_manager.rs create mode 100644 core/embed/sys/power_manager/power_manager_poll.c create mode 100644 core/embed/sys/power_manager/power_manager_poll.h diff --git a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c index 63c1633721..e4ab2f9991 100644 --- a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c +++ b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c @@ -266,47 +266,47 @@ void prodtest_pm_event_monitor(cli_t* cli) { cli_error(cli, CLI_ERROR, "Failed to get power manager events"); } - if (event_flag & PM_EVENT_USB_CONNECTED) { + if (event_flag.flags.usb_connected) { cli_trace(cli, "USB connected"); } - if (event_flag & PM_EVENT_USB_DISCONNECTED) { + if (event_flag.flags.usb_disconnected) { cli_trace(cli, "USB disconnected"); } - if (event_flag & PM_EVENT_WIRELESS_CONNECTED) { + if (event_flag.flags.wireless_connected) { cli_trace(cli, "WLC connected"); } - if (event_flag & PM_EVENT_WIRELESS_DISCONNECTED) { + if (event_flag.flags.wireless_disconnected) { cli_trace(cli, "WLC disconnected"); } - if (event_flag & PM_EVENT_ENTERED_MODE_ACTIVE) { + if (event_flag.flags.entered_mode_active) { cli_trace(cli, "Power manager entered active mode"); } - if (event_flag & PM_EVENT_ENTERED_MODE_POWER_SAVE) { + if (event_flag.flags.entered_mode_power_save) { cli_trace(cli, "Power manager entered power save mode"); } - if (event_flag & PM_EVENT_ENTERED_MODE_SHUTTING_DOWN) { + if (event_flag.flags.entered_mode_shutting_down) { cli_trace(cli, "Power manager entered shutting down mode"); } - if (event_flag & PM_EVENT_ENTERED_MODE_SUSPEND) { + if (event_flag.flags.entered_mode_suspend) { cli_trace(cli, "Power manager entered suspend mode"); } - if (event_flag & PM_EVENT_ENTERED_MODE_CHARGING) { + if (event_flag.flags.entered_mode_charging) { cli_trace(cli, "Power manager entered charging mode"); } - if (event_flag & PM_EVENT_ENTERED_MODE_HIBERNATE) { + if (event_flag.flags.entered_mode_hibernate) { cli_trace(cli, "Power manager entered hibernate mode"); } - if (event_flag & PM_EVENT_SOC_UPDATED) { + if (event_flag.flags.soc_updated) { status = pm_get_state(&state); cli_trace(cli, "Power manager SOC changed to %d %%", state.soc); } diff --git a/core/embed/rust/build.rs b/core/embed/rust/build.rs index 5cdde2e752..237d52abbc 100644 --- a/core/embed/rust/build.rs +++ b/core/embed/rust/build.rs @@ -45,6 +45,7 @@ const DEFAULT_BINDGEN_MACROS_COMMON: &[&str] = &[ "-I../sec/entropy/inc", "-I../sys/time/inc", "-I../sys/task/inc", + "-I../sys/power_manager/inc", "-I../util/flash/inc", "-I../util/translations/inc", "-I../models", @@ -54,6 +55,7 @@ const DEFAULT_BINDGEN_MACROS_COMMON: &[&str] = &[ "-DUSE_HAPTIC", "-DUSE_RGB_LED", "-DUSE_BLE", + "-DUSE_POWER_MANAGER", "-DUSE_HW_JPEG_DECODER", ]; @@ -443,6 +445,10 @@ fn generate_trezorhal_bindings() { .allowlist_type("syshandle_t") .allowlist_type("sysevents_t") .allowlist_function("sysevents_poll") + // power manager + .allowlist_type("pm_event_t") + .allowlist_function("pm_get_events") + .allowlist_function("pm_get_state") // c_layout .allowlist_type("c_layout_t"); diff --git a/core/embed/rust/src/trezorhal/ffi.rs b/core/embed/rust/src/trezorhal/ffi.rs index f8fcf3a49a..138657c6e7 100644 --- a/core/embed/rust/src/trezorhal/ffi.rs +++ b/core/embed/rust/src/trezorhal/ffi.rs @@ -3,5 +3,7 @@ #![allow(clippy::upper_case_acronyms)] #![allow(non_snake_case)] #![allow(dead_code)] +#![allow(clippy::transmute_int_to_bool)] +#![allow(clippy::too_many_arguments)] include!(concat!(env!("OUT_DIR"), "/trezorhal.rs")); diff --git a/core/embed/rust/src/trezorhal/mod.rs b/core/embed/rust/src/trezorhal/mod.rs index 5049416ed1..03c5a9bfe9 100644 --- a/core/embed/rust/src/trezorhal/mod.rs +++ b/core/embed/rust/src/trezorhal/mod.rs @@ -39,5 +39,8 @@ pub mod time; #[cfg(feature = "ui")] pub mod sysevent; -#[cfg(feature = "bootloader")] +#[cfg(feature = "power_manager")] +pub mod power_manager; + +#[cfg(any(feature = "bootloader", feature = "prodtest"))] pub mod layout_buf; diff --git a/core/embed/rust/src/trezorhal/power_manager.rs b/core/embed/rust/src/trezorhal/power_manager.rs new file mode 100644 index 0000000000..34855dc61f --- /dev/null +++ b/core/embed/rust/src/trezorhal/power_manager.rs @@ -0,0 +1,46 @@ +use super::ffi; + +use crate::ui::event::PMEvent; + +pub enum ChargingState { + Discharging, + Charging, + Idle, +} + +pub fn pm_parse_event(event: ffi::pm_event_t) -> PMEvent { + let mut pm_event = PMEvent::default(); + + unsafe { + pm_event.usb_connected = event.flags.usb_connected(); + pm_event.usb_disconnected = event.flags.usb_disconnected(); + pm_event.wireless_connected = event.flags.wireless_connected(); + pm_event.wireless_disconnected = event.flags.wireless_disconnected(); + pm_event.entered_mode_active = event.flags.entered_mode_active(); + pm_event.entered_mode_power_save = event.flags.entered_mode_power_save(); + pm_event.entered_mode_shutting_down = event.flags.entered_mode_shutting_down(); + pm_event.entered_mode_charging = event.flags.entered_mode_charging(); + pm_event.entered_mode_suspend = event.flags.entered_mode_suspend(); + pm_event.entered_mode_hibernate = event.flags.entered_mode_hibernate(); + pm_event.soc_updated = event.flags.soc_updated(); + pm_event.state_changed = event.flags.state_changed(); + } + pm_event +} + +pub fn soc() -> u8 { + let mut state: ffi::pm_state_t = unsafe { core::mem::zeroed() }; + unsafe { ffi::pm_get_state(&mut state as _) }; + state.soc +} + +pub fn charging_state() -> ChargingState { + let mut state: ffi::pm_state_t = unsafe { core::mem::zeroed() }; + unsafe { ffi::pm_get_state(&mut state as _) }; + match state.charging_status { + ffi::pm_charging_status_t_PM_BATTERY_DISCHARGING => ChargingState::Discharging, + ffi::pm_charging_status_t_PM_BATTERY_CHARGING => ChargingState::Charging, + ffi::pm_charging_status_t_PM_BATTERY_IDLE => ChargingState::Idle, + _ => panic!("Unknown charging status"), + } +} diff --git a/core/embed/rust/src/trezorhal/sysevent.rs b/core/embed/rust/src/trezorhal/sysevent.rs index b1938352fe..562610f916 100644 --- a/core/embed/rust/src/trezorhal/sysevent.rs +++ b/core/embed/rust/src/trezorhal/sysevent.rs @@ -16,6 +16,11 @@ use crate::trezorhal::touch::touch_get_event; #[cfg(feature = "touch")] use crate::ui::event::TouchEvent; +#[cfg(feature = "power_manager")] +use crate::trezorhal::power_manager::pm_parse_event; +#[cfg(feature = "power_manager")] +use crate::ui::event::PMEvent; + #[cfg(feature = "button")] use crate::trezorhal::button::button_parse_event; #[cfg(feature = "button")] @@ -123,6 +128,16 @@ pub fn parse_event(signalled: &sysevents_t) -> Option { } } + #[cfg(feature = "power_manager")] + if signalled.read_ready & (1 << ffi::syshandle_t_SYSHANDLE_POWER_MANAGER) != 0 { + let mut pm_event: ffi::pm_event_t = unsafe { mem::zeroed() }; + let event_available = unsafe { ffi::pm_get_events(&mut pm_event) }; + if event_available { + let pm_event = pm_parse_event(pm_event); + return Some(Event::PM(pm_event)); + } + } + None } diff --git a/core/embed/rust/src/ui/component/base.rs b/core/embed/rust/src/ui/component/base.rs index 602d18b92d..da13168ec5 100644 --- a/core/embed/rust/src/ui/component/base.rs +++ b/core/embed/rust/src/ui/component/base.rs @@ -16,6 +16,8 @@ use crate::{ use crate::ui::event::BLEEvent; #[cfg(feature = "button")] use crate::ui::event::ButtonEvent; +#[cfg(feature = "power_manager")] +use crate::ui::event::PMEvent; use crate::ui::event::USBEvent; #[cfg(feature = "touch")] use crate::ui::{ @@ -324,6 +326,8 @@ pub enum Event { Touch(TouchEvent), #[cfg(feature = "ble")] BLE(BLEEvent), + #[cfg(feature = "power_manager")] + PM(PMEvent), USB(USBEvent), /// Previously requested timer was triggered. This invalidates the timer /// token (another timer has to be requested). diff --git a/core/embed/rust/src/ui/event/mod.rs b/core/embed/rust/src/ui/event/mod.rs index 661efcadd0..d917163cf7 100644 --- a/core/embed/rust/src/ui/event/mod.rs +++ b/core/embed/rust/src/ui/event/mod.rs @@ -8,10 +8,15 @@ pub mod usb; #[cfg(feature = "ble")] mod ble; +#[cfg(feature = "power_manager")] +mod power_manager; + #[cfg(feature = "ble")] pub use ble::BLEEvent; #[cfg(feature = "button")] pub use button::{ButtonEvent, PhysicalButton}; +#[cfg(feature = "power_manager")] +pub use power_manager::PMEvent; #[cfg(feature = "touch")] pub use touch::{SwipeEvent, TouchEvent}; diff --git a/core/embed/rust/src/ui/event/power_manager.rs b/core/embed/rust/src/ui/event/power_manager.rs new file mode 100644 index 0000000000..ddd0bae6dc --- /dev/null +++ b/core/embed/rust/src/ui/event/power_manager.rs @@ -0,0 +1,16 @@ +#[derive(Default, Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] +pub struct PMEvent { + pub state_changed: bool, + pub usb_connected: bool, + pub usb_disconnected: bool, + pub wireless_connected: bool, + pub wireless_disconnected: bool, + pub entered_mode_active: bool, + pub entered_mode_power_save: bool, + pub entered_mode_shutting_down: bool, + pub entered_mode_charging: bool, + pub entered_mode_suspend: bool, + pub entered_mode_hibernate: bool, + pub soc_updated: bool, +} diff --git a/core/embed/rust/trezorhal.h b/core/embed/rust/trezorhal.h index 24a14c1dcf..375bedc040 100644 --- a/core/embed/rust/trezorhal.h +++ b/core/embed/rust/trezorhal.h @@ -38,6 +38,10 @@ #include #endif +#ifdef USE_POWER_MANAGER +#include +#endif + #include "bip39.h" #include "rand.h" #include "slip39.h" diff --git a/core/embed/sys/power_manager/inc/sys/power_manager.h b/core/embed/sys/power_manager/inc/sys/power_manager.h index e5e0129bc3..483788d776 100644 --- a/core/embed/sys/power_manager/inc/sys/power_manager.h +++ b/core/embed/sys/power_manager/inc/sys/power_manager.h @@ -54,20 +54,22 @@ typedef enum { } pm_internal_state_t; /* Power system events */ -typedef enum { - PM_EVENT_NONE = 0, - PM_EVENT_STATE_CHANGED = 1, - PM_EVENT_USB_CONNECTED = 1 << 1, - PM_EVENT_USB_DISCONNECTED = 1 << 2, - PM_EVENT_WIRELESS_CONNECTED = 1 << 3, - PM_EVENT_WIRELESS_DISCONNECTED = 1 << 4, - PM_EVENT_ENTERED_MODE_HIBERNATE = 1 << 5, - PM_EVENT_ENTERED_MODE_CHARGING = 1 << 6, - PM_EVENT_ENTERED_MODE_SUSPEND = 1 << 7, - PM_EVENT_ENTERED_MODE_SHUTTING_DOWN = 1 << 8, - PM_EVENT_ENTERED_MODE_POWER_SAVE = 1 << 9, - PM_EVENT_ENTERED_MODE_ACTIVE = 1 << 10, - PM_EVENT_SOC_UPDATED = 1 << 11, +typedef union { + uint32_t all; + struct { + bool state_changed : 1; + bool usb_connected : 1; + bool usb_disconnected : 1; + bool wireless_connected : 1; + bool wireless_disconnected : 1; + bool entered_mode_hibernate : 1; + bool entered_mode_charging : 1; + bool entered_mode_suspend : 1; + bool entered_mode_active : 1; + bool entered_mode_power_save : 1; + bool entered_mode_shutting_down : 1; + bool soc_updated : 1; + } flags; } pm_event_t; typedef struct { @@ -99,7 +101,7 @@ typedef struct { /* Public API functions */ pm_status_t pm_init(bool inherit_state); void pm_deinit(void); -pm_status_t pm_get_events(pm_event_t* event_flags); +bool pm_get_events(pm_event_t* event_flags); pm_status_t pm_get_state(pm_state_t* state); pm_status_t pm_suspend(void); pm_status_t pm_hibernate(void); diff --git a/core/embed/sys/power_manager/power_manager_poll.c b/core/embed/sys/power_manager/power_manager_poll.c new file mode 100644 index 0000000000..40977fa72c --- /dev/null +++ b/core/embed/sys/power_manager/power_manager_poll.c @@ -0,0 +1,198 @@ +/* + * 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 . + */ + +#ifdef KERNEL_MODE + +#include + +#include +#include +#include + +#include "power_manager_poll.h" + +typedef struct { + // Time (in ticks) when the tls was last updated + uint32_t update_ticks; + // Last state + pm_state_t pm_state; + // Pending events + pm_event_t event; + bool pending_event; + +} pm_fsm_t; + +// State machine for each task +static pm_fsm_t tls[SYSTASK_MAX_TASKS] = {0}; + +// Forward declarations +static const syshandle_vmt_t g_pm_handle_vmt; + +bool pm_poll_init(void) { + return syshandle_register(SYSHANDLE_POWER_MANAGER, &g_pm_handle_vmt, NULL); +} + +void pm_poll_deinit(void) { syshandle_unregister(SYSHANDLE_POWER_MANAGER); } + +void pm_fsm_clear(pm_fsm_t* fsm) { memset(fsm, 0, sizeof(pm_fsm_t)); } + +static void pm_clear_state_flags(pm_fsm_t* fsm) { + fsm->event.flags.entered_mode_active = false; + fsm->event.flags.entered_mode_power_save = false; + fsm->event.flags.entered_mode_shutting_down = false; + fsm->event.flags.entered_mode_charging = false; + fsm->event.flags.entered_mode_suspend = false; + fsm->event.flags.entered_mode_hibernate = false; +} + +bool pm_fsm_event_ready(pm_fsm_t* fsm, pm_state_t* new_state) { + bool event_detected = false; + + // Remember state changes + fsm->update_ticks = systick_ms(); + + // Return true if there are any state changes + if (new_state->soc != fsm->pm_state.soc) { + fsm->event.flags.soc_updated = true; + event_detected = true; + } + + if (new_state->usb_connected && !fsm->pm_state.usb_connected) { + fsm->event.flags.usb_connected = true; + fsm->event.flags.usb_disconnected = false; + } + + if (!new_state->usb_connected && fsm->pm_state.usb_connected) { + fsm->event.flags.usb_disconnected = true; + fsm->event.flags.usb_connected = false; + } + + if (new_state->wireless_connected && !fsm->pm_state.wireless_connected) { + fsm->event.flags.wireless_connected = true; + fsm->event.flags.wireless_disconnected = false; + } + + if (!new_state->wireless_connected && fsm->pm_state.wireless_connected) { + fsm->event.flags.wireless_disconnected = true; + fsm->event.flags.wireless_connected = false; + } + + if (new_state->power_state == PM_STATE_ACTIVE) { + if (fsm->pm_state.power_state != PM_STATE_ACTIVE) { + pm_clear_state_flags(fsm); + fsm->event.flags.entered_mode_active = true; + event_detected = true; + } + } else if (new_state->power_state == PM_STATE_POWER_SAVE) { + if (fsm->pm_state.power_state != PM_STATE_POWER_SAVE) { + pm_clear_state_flags(fsm); + fsm->event.flags.entered_mode_power_save = true; + event_detected = true; + } + } else if (new_state->power_state == PM_STATE_SHUTTING_DOWN) { + if (fsm->pm_state.power_state != PM_STATE_SHUTTING_DOWN) { + pm_clear_state_flags(fsm); + fsm->event.flags.entered_mode_shutting_down = true; + event_detected = true; + } + } else if (new_state->power_state == PM_STATE_CHARGING) { + if (fsm->pm_state.power_state != PM_STATE_CHARGING) { + pm_clear_state_flags(fsm); + fsm->event.flags.entered_mode_charging = true; + event_detected = true; + } + } else if (new_state->power_state == PM_STATE_SUSPEND) { + if (fsm->pm_state.power_state != PM_STATE_SUSPEND) { + pm_clear_state_flags(fsm); + fsm->event.flags.entered_mode_suspend = true; + event_detected = true; + } + } else if (new_state->power_state == PM_STATE_HIBERNATE) { + if (fsm->pm_state.power_state != PM_STATE_HIBERNATE) { + pm_clear_state_flags(fsm); + fsm->event.flags.entered_mode_hibernate = true; + event_detected = true; + } + } + + if (new_state->charging_status != fsm->pm_state.charging_status) { + fsm->event.flags.state_changed = true; + event_detected = true; + } + + if (event_detected) { + fsm->pending_event = true; + } + + memcpy(&fsm->pm_state, new_state, sizeof(pm_state_t)); + + return event_detected; +} + +bool pm_fsm_get_event(pm_fsm_t* fsm, pm_event_t* event) { + if (fsm->pending_event) { + memcpy(event, &fsm->event, sizeof(pm_event_t)); + memset(&fsm->event, 0, sizeof(pm_event_t)); + fsm->pending_event = false; + return true; + } + + return false; +} + +static void on_task_created(void* context, systask_id_t task_id) { + pm_fsm_t* fsm = &tls[task_id]; + pm_fsm_clear(fsm); +} + +static void on_event_poll(void* context, bool read_awaited, + bool write_awaited) { + UNUSED(write_awaited); + + if (read_awaited) { + pm_state_t state = {0}; + pm_get_state(&state); + syshandle_signal_read_ready(SYSHANDLE_POWER_MANAGER, &state); + } +} + +static bool on_check_read_ready(void* context, systask_id_t task_id, + void* param) { + pm_fsm_t* fsm = &tls[task_id]; + + pm_state_t* new_state = (pm_state_t*)param; + + return pm_fsm_event_ready(fsm, new_state); +} + +static const syshandle_vmt_t g_pm_handle_vmt = { + .task_created = on_task_created, + .task_killed = NULL, + .check_read_ready = on_check_read_ready, + .check_write_ready = NULL, + .poll = on_event_poll, +}; + +bool pm_get_events(pm_event_t* event_flags) { + pm_fsm_t* fsm = &tls[systask_id(systask_active())]; + + return pm_fsm_get_event(fsm, event_flags); +} + +#endif // KERNEL_MODE diff --git a/core/embed/sys/power_manager/power_manager_poll.h b/core/embed/sys/power_manager/power_manager_poll.h new file mode 100644 index 0000000000..29492701e1 --- /dev/null +++ b/core/embed/sys/power_manager/power_manager_poll.h @@ -0,0 +1,27 @@ +/* + * 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 . + */ + +#pragma once + +// This module implements system event evaluation & polling mechanism for power +// manager. + +bool pm_poll_init(void); + +void pm_poll_deinit(void); diff --git a/core/embed/sys/power_manager/stm32u5/power_manager.c b/core/embed/sys/power_manager/stm32u5/power_manager.c index 3a31f81027..7580d84647 100644 --- a/core/embed/sys/power_manager/stm32u5/power_manager.c +++ b/core/embed/sys/power_manager/stm32u5/power_manager.c @@ -25,6 +25,7 @@ #include #include +#include "../power_manager_poll.h" #include "../stwlc38/stwlc38.h" #include "power_manager_internal.h" @@ -55,6 +56,11 @@ pm_status_t pm_init(bool inherit_state) { return PM_ERROR; } + if (!pm_poll_init()) { + pm_deinit(); + return PM_ERROR; + } + // Initialize fuel gauge fuel_gauge_init(&drv->fuel_gauge, PM_FUEL_GAUGE_R, PM_FUEL_GAUGE_Q, PM_FUEL_GAUGE_R_AGGRESSIVE, PM_FUEL_GAUGE_Q_AGGRESSIVE, @@ -128,6 +134,8 @@ pm_status_t pm_init(bool inherit_state) { void pm_deinit(void) { pm_driver_t* drv = &g_pm; + pm_poll_deinit(); + if (drv->monitoring_timer) { systimer_delete(drv->monitoring_timer); drv->monitoring_timer = NULL; @@ -148,21 +156,6 @@ void pm_deinit(void) { drv->initialized = false; } -pm_status_t pm_get_events(pm_event_t* event_flags) { - pm_driver_t* drv = &g_pm; - - if (!drv->initialized) { - return PM_NOT_INITIALIZED; - } - - irq_key_t irq_key = irq_lock(); - *event_flags = drv->event_flags; - PM_CLEAR_ALL_EVENTS(drv->event_flags); - irq_unlock(irq_key); - - return PM_OK; -} - pm_status_t pm_get_state(pm_state_t* state) { pm_driver_t* drv = &g_pm; diff --git a/core/embed/sys/power_manager/stm32u5/power_manager_internal.h b/core/embed/sys/power_manager/stm32u5/power_manager_internal.h index b8212c577b..a446a305f5 100644 --- a/core/embed/sys/power_manager/stm32u5/power_manager_internal.h +++ b/core/embed/sys/power_manager/stm32u5/power_manager_internal.h @@ -46,11 +46,6 @@ #define PM_FUEL_GAUGE_Q_AGGRESSIVE 0.01f #define PM_FUEL_GAUGE_P_INIT 0.1f -// Event flag manipulation macros -#define PM_SET_EVENT(flags, event) ((flags) |= (event)) -#define PM_CLEAR_EVENT(flags, event) ((flags) &= ~(event)) -#define PM_CLEAR_ALL_EVENTS(flags) ((flags) = 0) - // Power manager battery sampling data structure typedef struct { float vbat; // Battery voltage [V] @@ -63,7 +58,6 @@ typedef struct { bool initialized; bool state_machine_stabilized; pm_internal_state_t state; - pm_event_t event_flags; // Fuel gauge fuel_gauge_state_t fuel_gauge; diff --git a/core/embed/sys/power_manager/stm32u5/power_monitoring.c b/core/embed/sys/power_manager/stm32u5/power_monitoring.c index b0d2bae836..01314ccfba 100644 --- a/core/embed/sys/power_manager/stm32u5/power_monitoring.c +++ b/core/embed/sys/power_manager/stm32u5/power_monitoring.c @@ -40,12 +40,10 @@ void pm_monitor_power_sources(void) { if (drv->pmic_data.usb_status != 0x0) { if (!drv->usb_connected) { drv->usb_connected = true; - PM_SET_EVENT(drv->event_flags, PM_EVENT_USB_CONNECTED); } } else { if (drv->usb_connected) { drv->usb_connected = false; - PM_SET_EVENT(drv->event_flags, PM_EVENT_USB_DISCONNECTED); } } @@ -53,12 +51,10 @@ void pm_monitor_power_sources(void) { if (drv->wireless_data.vout_ready) { if (!drv->wireless_connected) { drv->wireless_connected = true; - PM_SET_EVENT(drv->event_flags, PM_EVENT_WIRELESS_CONNECTED); } } else { if (drv->wireless_connected) { drv->wireless_connected = false; - PM_SET_EVENT(drv->event_flags, PM_EVENT_WIRELESS_DISCONNECTED); } } @@ -104,7 +100,6 @@ void pm_monitor_power_sources(void) { uint8_t soc_ceiled_temp = (int)(drv->fuel_gauge.soc_latched * 100 + 0.999f); if (soc_ceiled_temp != drv->soc_ceiled) { drv->soc_ceiled = soc_ceiled_temp; - PM_SET_EVENT(drv->event_flags, PM_EVENT_SOC_UPDATED); } // Check battery voltage for low threshold @@ -260,3 +255,5 @@ void pm_battery_initial_soc_guess(void) { fuel_gauge_initial_guess(&drv->fuel_gauge, vbat_g, ibat_g, ntc_temp_g); } + +#endif diff --git a/core/embed/sys/power_manager/stm32u5/power_states.c b/core/embed/sys/power_manager/stm32u5/power_states.c index 504bc8d418..658e5deb90 100644 --- a/core/embed/sys/power_manager/stm32u5/power_states.c +++ b/core/embed/sys/power_manager/stm32u5/power_states.c @@ -88,7 +88,6 @@ void pm_process_state_machine(void) { // Update state drv->state = new_state; - PM_SET_EVENT(drv->event_flags, PM_EVENT_STATE_CHANGED); // Enter new state if (state_handlers[new_state].enter != NULL) { @@ -236,39 +235,29 @@ pm_internal_state_t pm_handle_state_active(pm_driver_t* drv) { // State enter/exit actions void pm_enter_hibernate(pm_driver_t* drv) { - PM_SET_EVENT(drv->event_flags, PM_EVENT_ENTERED_MODE_HIBERNATE); - // Store power manager data with request to hibernate, power manager // will try to hibernate immediately after reboot. pm_store_data_to_backup_ram(); reboot_device(); } -void pm_enter_charging(pm_driver_t* drv) { - PM_SET_EVENT(drv->event_flags, PM_EVENT_ENTERED_MODE_CHARGING); -} +void pm_enter_charging(pm_driver_t* drv) {} -void pm_enter_suspend(pm_driver_t* drv) { - PM_SET_EVENT(drv->event_flags, PM_EVENT_ENTERED_MODE_SUSPEND); - pm_control_suspend(); -} +void pm_enter_suspend(pm_driver_t* drv) { pm_control_suspend(); } void pm_enter_shutting_down(pm_driver_t* drv) { // Set shutdown timer systimer_set(drv->shutdown_timer, PM_SHUTDOWN_TIMEOUT_MS); - PM_SET_EVENT(drv->event_flags, PM_EVENT_ENTERED_MODE_SHUTTING_DOWN); } void pm_enter_power_save(pm_driver_t* drv) { // Limit backlight backlight_set_max_level(130); - PM_SET_EVENT(drv->event_flags, PM_EVENT_ENTERED_MODE_POWER_SAVE); } void pm_enter_active(pm_driver_t* drv) { // Set unlimited backlight backlight_set_max_level(255); - PM_SET_EVENT(drv->event_flags, PM_EVENT_ENTERED_MODE_ACTIVE); } void pm_exit_shutting_down(pm_driver_t* drv) { diff --git a/core/embed/sys/task/inc/sys/sysevent.h b/core/embed/sys/task/inc/sys/sysevent.h index e99bc1415d..109e81bc92 100644 --- a/core/embed/sys/task/inc/sys/sysevent.h +++ b/core/embed/sys/task/inc/sys/sysevent.h @@ -27,7 +27,7 @@ typedef enum { SYSHANDLE_USB_IFACE_7 = SYSHANDLE_USB_IFACE_0 + 7, SYSHANDLE_BLE_IFACE_0, // SYSHANDLE_BLE_IFACE_N = SYSHANDLE_BLE_IFACE_0 + N - 1, - SYSHANDLE_POWERCTL, + SYSHANDLE_POWER_MANAGER, SYSHANDLE_BUTTON, SYSHANDLE_TOUCH, SYSHANDLE_USB, diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revA.py b/core/site_scons/models/T3W1/trezor_t3w1_revA.py index e3b090e505..b87944f8f5 100644 --- a/core/site_scons/models/T3W1/trezor_t3w1_revA.py +++ b/core/site_scons/models/T3W1/trezor_t3w1_revA.py @@ -251,6 +251,7 @@ def configure( "embed/sys/power_manager/fuel_gauge/battery_model.c", "embed/sys/power_manager/stwlc38/stwlc38.c", "embed/sys/power_manager/stwlc38/stwlc38_patching.c", + "embed/sys/power_manager/power_manager_poll.c", ] paths += ["embed/sys/power_manager/inc"] defines += [("USE_POWER_MANAGER", "1")] diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revB.py b/core/site_scons/models/T3W1/trezor_t3w1_revB.py index 9760f386bf..5bf3f07dc5 100644 --- a/core/site_scons/models/T3W1/trezor_t3w1_revB.py +++ b/core/site_scons/models/T3W1/trezor_t3w1_revB.py @@ -256,6 +256,7 @@ def configure( "embed/sys/power_manager/fuel_gauge/battery_model.c", "embed/sys/power_manager/stwlc38/stwlc38.c", "embed/sys/power_manager/stwlc38/stwlc38_patching.c", + "embed/sys/power_manager/power_manager_poll.c", ] paths += ["embed/sys/power_manager/inc"] defines += [("USE_POWER_MANAGER", "1")] diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revC.py b/core/site_scons/models/T3W1/trezor_t3w1_revC.py index 30ee832ccd..db3d5ded7d 100644 --- a/core/site_scons/models/T3W1/trezor_t3w1_revC.py +++ b/core/site_scons/models/T3W1/trezor_t3w1_revC.py @@ -256,6 +256,7 @@ def configure( "embed/sys/power_manager/fuel_gauge/battery_model.c", "embed/sys/power_manager/stwlc38/stwlc38.c", "embed/sys/power_manager/stwlc38/stwlc38_patching.c", + "embed/sys/power_manager/power_manager_poll.c", ] paths += ["embed/sys/power_manager/inc"] defines += [("USE_POWER_MANAGER", "1")]