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

feat(core): event polling for power manager

[no changelog]
This commit is contained in:
tychovrahe 2025-05-03 16:12:46 +02:00 committed by kopecdav
parent e3be94d599
commit c89ca35bbc
21 changed files with 371 additions and 67 deletions

View File

@ -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);
}

View File

@ -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");

View File

@ -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"));

View File

@ -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;

View File

@ -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"),
}
}

View File

@ -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<Event> {
}
}
#[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
}

View File

@ -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).

View File

@ -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};

View File

@ -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,
}

View File

@ -38,6 +38,10 @@
#include <io/touch.h>
#endif
#ifdef USE_POWER_MANAGER
#include <sys/power_manager.h>
#endif
#include "bip39.h"
#include "rand.h"
#include "slip39.h"

View File

@ -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);

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifdef KERNEL_MODE
#include <trezor_rtl.h>
#include <sys/power_manager.h>
#include <sys/sysevent_source.h>
#include <sys/systick.h>
#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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
// This module implements system event evaluation & polling mechanism for power
// manager.
bool pm_poll_init(void);
void pm_poll_deinit(void);

View File

@ -25,6 +25,7 @@
#include <sys/systimer.h>
#include <trezor_rtl.h>
#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;

View File

@ -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;

View File

@ -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

View File

@ -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) {

View File

@ -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,

View File

@ -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")]

View File

@ -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")]

View File

@ -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")]