1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-25 00:48:19 +00:00

feat(core): introduce powerctl module

[no changelog]
This commit is contained in:
cepetr 2024-11-18 09:08:25 +01:00
parent 962afee7fe
commit 168f62c93e
6 changed files with 305 additions and 1 deletions

View File

@ -55,6 +55,10 @@
#include <sec/optiga_transport.h> #include <sec/optiga_transport.h>
#endif #endif
#ifdef USE_POWERCTL
#include <sys/powerctl.h>
#endif
#ifdef USE_PVD #ifdef USE_PVD
#include <sys/pvd.h> #include <sys/pvd.h>
#endif #endif
@ -100,6 +104,10 @@ static void optiga_log_hex(const char *prefix, const uint8_t *data,
#endif #endif
void drivers_init() { void drivers_init() {
#ifdef USE_POWERCTL
powerctl_init();
#endif
#ifdef USE_TAMPER #ifdef USE_TAMPER
tamper_init(); tamper_init();
#endif #endif

View File

@ -0,0 +1,58 @@
/*
* 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/>.
*/
#ifndef TREZORHAL_POWERCTL_H
#define TREZORHAL_POWERCTL_H
// Initializes power control module.
//
// Returns true if the initialization was successful.
bool powerctl_init(void);
// Deinitializes power control module.
void powerctl_deinit(void);
typedef enum {
POWER_SOURCE_BATT,
POWER_SOURCE_USB,
POWER_SOURCE_QI,
} power_source_t;
typedef struct {
// Current power source
power_source_t power_source;
// Set if charging is active
bool charging;
// Battery charge level in percents
// (or -1 if the battery level is unknown)
int charge_level;
// Set if the temperature is too low
bool low_temperature;
// Set if the temperature is too high
bool high_temperature;
} powerctl_status_t;
// Gets the current power status.
void powerctl_get_status(powerctl_status_t* status);
// Enters low-power mode
//
void powerctl_suspend(void);
#endif // TREZORHAL_POWERCTL_H

View File

@ -0,0 +1,40 @@
/*
* 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/>.
*/
#ifndef TREZORHAL_WAKEUP_FLAGS_H
#define TREZORHAL_WAKEUP_FLAGS_H
#include <stdint.h>
// Wakeup flags used to signal the reason of the wakeup
// from the STOP mode
#define WAKEUP_FLAG_BUTTON 0x01 // Button pressed
#define WAKEUP_FLAG_WPC 0x02 // Wireless power charging event
#define WAKEUP_FLAG_BLE 0x04 // Bluetooth connection event
#define WAKEUP_FLAG_NFC 0x08 // NFC event
#define WAKEUP_FLAG_TIMER 0x10 // Timer event
// Sets the wakeup flag
void wakeup_flag_set(uint16_t flags);
// Gets and clears the current wakeup flags
uint16_t wakeup_get_and_clear(void);
#endif // TREZORHAL_WAKEUP_FLAGS_H

View File

@ -0,0 +1,154 @@
/*
* 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/>.
*/
#include <trezor_bsp.h>
#include <trezor_rtl.h>
#include <io/display.h>
#include <io/usb.h>
#include <sys/powerctl.h>
#ifdef USE_TOUCH
#include <io/touch.h>
#endif
#ifdef USE_HAPTIC
#include <io/haptic.h>
#endif
#include "../npm1300/npm1300.h"
#include "../stwlc38/stwlc38.h"
#ifdef KERNEL_MODE
// Power control driver state
typedef struct {
// True if the driver is initialized
bool initialized;
} powerctl_driver_t;
// Power control driver instance
static powerctl_driver_t g_powerctl_driver = {.initialized = false};
bool powerctl_init(void) {
powerctl_driver_t* drv = &g_powerctl_driver;
if (drv->initialized) {
return true;
}
// Initialize PMIC
if (!npm1300_init()) {
goto cleanup;
}
// Initialize wireless charging
if (!stwlc38_init()) {
goto cleanup;
}
drv->initialized = true;
return true;
cleanup:
stwlc38_deinit();
npm1300_deinit();
return false;
}
void powerctl_deinit(void) {
powerctl_driver_t* drv = &g_powerctl_driver;
if (!drv->initialized) {
return;
}
stwlc38_deinit();
npm1300_deinit();
drv->initialized = false;
}
void powerctl_get_status(powerctl_status_t* status) {
powerctl_driver_t* drv = &g_powerctl_driver;
memset(status, 0, sizeof(powerctl_status_t));
if (!drv->initialized) {
return;
}
// TODO
}
void powerctl_suspend(void) {
usb_stop();
#ifdef USE_HAPTIC
haptic_deinit();
#endif
#ifdef USE_TOUCH
touch_deinit();
#endif
int backlight_level = display_get_backlight();
display_deinit(DISPLAY_RESET_CONTENT);
HAL_SuspendTick();
// Configure PC13 (on-board button) as a wake up pin
EXTI_HandleTypeDef EXTI_Handle = {0};
EXTI_ConfigTypeDef EXTI_Config = {0};
EXTI_Config.GPIOSel = EXTI_GPIOC;
EXTI_Config.Line = EXTI_LINE_13;
EXTI_Config.Mode = EXTI_MODE_EVENT;
EXTI_Config.Trigger = EXTI_TRIGGER_RISING;
HAL_EXTI_SetConfigLine(&EXTI_Handle, &EXTI_Config);
// HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_HIGH_1);
// Enter STOP2 mode
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFE);
// We get here when the wake-up button is pressed
// Recover system clock
SystemInit();
HAL_ResumeTick();
// Initialize drivers
display_init(DISPLAY_RESET_CONTENT);
display_set_backlight(backlight_level);
#ifdef USE_TOUCH
touch_init();
#endif
#ifdef USE_HAPTIC
haptic_init();
#endif
usb_start();
}
#endif // KERNEL_MODE

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/>.
*/
#include "wakeup_flags.h"
#include "irq.h"
#ifdef KERNEL_MODE
static uint16_t g_wakeup_flags = 0;
void wakeup_flag_set(uint16_t flags) {
irq_key_t irq_key = irq_lock();
g_wakeup_flags |= flags;
irq_unlock(irq_key);
}
uint16_t wakeup_get_and_clear(void) {
irq_key_t irq_key = irq_lock();
uint16_t flags = g_wakeup_flags;
g_wakeup_flags = 0;
irq_unlock(irq_key);
return flags;
}
#endif // KERNEL_MODE

View File

@ -119,8 +119,11 @@ def configure(
sources += [ sources += [
"embed/sys/powerctl/npm1300/npm1300.c", "embed/sys/powerctl/npm1300/npm1300.c",
"embed/sys/powerctl/stwlc38/stwlc38.c" "embed/sys/powerctl/stwlc38/stwlc38.c",
"embed/sys/powerctl/stm32u5/powerctl.c",
] ]
paths += ["embed/sys/powerctl/inc"]
defines += ["USE_POWERCTL=1"]
env.get("ENV")["LINKER_SCRIPT"] = linker_script env.get("ENV")["LINKER_SCRIPT"] = linker_script