diff --git a/core/embed/models/T3W1/memory.ld b/core/embed/models/T3W1/memory.ld
index a5c9e5170c..98b0bff897 100644
--- a/core/embed/models/T3W1/memory.ld
+++ b/core/embed/models/T3W1/memory.ld
@@ -49,6 +49,8 @@ SAES_RAM_START = 0x300cfe00;
SAES_RAM_SIZE = 0x200;
FB2_RAM_START = 0x300d0000;
FB2_RAM_SIZE = 0xc0000;
+BACKUP_RAM_START = 0x50036400;
+BACKUP_RAM_SIZE = 0x800;
AUX1_RAM_START = 0x30190000;
AUX1_RAM_SIZE = 0xe0000;
CODE_ALIGNMENT = 0x400;
diff --git a/core/embed/models/T3W1/model_T3W1.h b/core/embed/models/T3W1/model_T3W1.h
index 83bf16f7a6..e0fdc1a852 100644
--- a/core/embed/models/T3W1/model_T3W1.h
+++ b/core/embed/models/T3W1/model_T3W1.h
@@ -101,6 +101,9 @@
#define AUX1_RAM_START 0x30190000
#define AUX1_RAM_SIZE (896 * 1024)
+#define BACKUP_RAM_START 0x50036400
+#define BACKUP_RAM_SIZE 2048
+
// misc
#define CODE_ALIGNMENT 0x400
#define COREAPP_ALIGNMENT 0x2000
diff --git a/core/embed/sys/backup_ram/backup_ram.c b/core/embed/sys/backup_ram/backup_ram.c
new file mode 100644
index 0000000000..9b976ec41c
--- /dev/null
+++ b/core/embed/sys/backup_ram/backup_ram.c
@@ -0,0 +1,110 @@
+/*
+ * 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 .
+ */
+
+// #include
+#include
+#include
+
+#include
+
+// Place backup RAM data structure in the linker backup SRAM section
+__attribute__((section(".backup_ram"))) backup_ram_data_t backup_ram;
+
+typedef struct {
+ bool initialized;
+ RAMCFG_HandleTypeDef hramcfg;
+} backup_ram_driver_t;
+
+static backup_ram_driver_t backup_ram_driver = {
+ .initialized = false,
+};
+
+backup_ram_status_t backup_ram_init(void) {
+ backup_ram_driver_t *drv = &backup_ram_driver;
+
+ if (drv->initialized) {
+ return BACKUP_RAM_OK;
+ }
+
+ // Enable backup SRAM clock
+ __HAL_RCC_RAMCFG_FORCE_RESET();
+ __HAL_RCC_RAMCFG_RELEASE_RESET();
+ __HAL_RCC_RAMCFG_CLK_ENABLE();
+ __HAL_RCC_BKPSRAM_CLK_ENABLE();
+
+ memset((void *)drv, 0, sizeof(backup_ram_driver_t));
+ drv->hramcfg.Instance = RAMCFG_BKPRAM;
+ HAL_StatusTypeDef status = HAL_RAMCFG_Init(&drv->hramcfg);
+
+ if (status != HAL_OK) {
+ __HAL_RCC_BKPSRAM_CLK_DISABLE();
+ return BACKUP_RAM_ERROR;
+ }
+
+ drv->initialized = true;
+
+ return BACKUP_RAM_OK;
+}
+
+backup_ram_status_t backup_ram_deinit(void) {
+ backup_ram_driver_t *drv = &backup_ram_driver;
+
+ HAL_RAMCFG_DeInit(&drv->hramcfg);
+
+ // Disable backup SRAM clock
+ __HAL_RCC_BKPSRAM_CLK_DISABLE();
+ __HAL_RCC_RAMCFG_CLK_DISABLE();
+ backup_ram_driver.initialized = false;
+
+ return BACKUP_RAM_OK;
+}
+
+backup_ram_status_t backup_ram_erase(void) {
+ backup_ram_driver_t *drv = &backup_ram_driver;
+
+ HAL_StatusTypeDef status = HAL_RAMCFG_Erase(&drv->hramcfg);
+ if (status != HAL_OK) {
+ return BACKUP_RAM_ERROR;
+ }
+
+ return BACKUP_RAM_OK;
+}
+
+backup_ram_status_t backup_ram_erase_unused(void) {
+ memset(backup_ram.bytes + sizeof(backup_ram.data), 0,
+ sizeof(backup_ram.bytes) - sizeof(backup_ram.data));
+
+ return BACKUP_RAM_OK;
+}
+
+backup_ram_status_t backup_ram_store_fuel_gauge_state(
+ const fuel_gauge_backup_storage_t *fg_state) {
+ memcpy((void *)&backup_ram.data.fg, fg_state,
+ sizeof(fuel_gauge_backup_storage_t));
+
+ return BACKUP_RAM_OK;
+}
+
+backup_ram_status_t backup_ram_read_fuel_gauge_state(
+ fuel_gauge_backup_storage_t *fg_state) {
+ memcpy(fg_state, (const void *)&backup_ram.data.fg,
+ sizeof(fuel_gauge_backup_storage_t));
+
+ return BACKUP_RAM_OK;
+}
diff --git a/core/embed/sys/backup_ram/inc/sys/backup_ram.h b/core/embed/sys/backup_ram/inc/sys/backup_ram.h
new file mode 100644
index 0000000000..772fd76c5a
--- /dev/null
+++ b/core/embed/sys/backup_ram/inc/sys/backup_ram.h
@@ -0,0 +1,65 @@
+/*
+ * 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
+
+#include
+#include
+
+typedef enum {
+ BACKUP_RAM_OK = 0,
+ BACKUP_RAM_ERROR,
+} backup_ram_status_t;
+
+// Fuel gauge backup storage definition
+typedef struct {
+ float soc; // Captured state of charge <0, 1>
+ // Captures RTC time at which SOC was captured
+ uint32_t last_capture_timestamp;
+} fuel_gauge_backup_storage_t;
+
+typedef union {
+ uint8_t bytes[BACKUP_RAM_SIZE];
+ struct {
+ volatile fuel_gauge_backup_storage_t fg;
+ // < Room for other data structures >
+ } data;
+} backup_ram_data_t;
+
+// Initialize backup RAM driver
+backup_ram_status_t backup_ram_init(void);
+
+// Deinitialize backup RAM driver
+backup_ram_status_t backup_ram_deinit(void);
+
+// Erase backup ram
+backup_ram_status_t backup_ram_erase(void);
+
+// Erase unused space in backup ram
+// This function clears the remaining part of the backup ram not alocated by
+// data struct.
+backup_ram_status_t backup_ram_erase_unused(void);
+
+// Store fuel gauge state in backup ram
+backup_ram_status_t backup_ram_store_fuel_gauge_state(
+ const fuel_gauge_backup_storage_t* fg_state);
+
+// Read fuel gauge state from backup ram
+backup_ram_status_t backup_ram_read_fuel_gauge_state(
+ fuel_gauge_backup_storage_t* fg_state);
diff --git a/core/embed/sys/bsp/stm32u5/stm32u5xx_hal_conf.h b/core/embed/sys/bsp/stm32u5/stm32u5xx_hal_conf.h
index 0b489baf77..f213c6446e 100644
--- a/core/embed/sys/bsp/stm32u5/stm32u5xx_hal_conf.h
+++ b/core/embed/sys/bsp/stm32u5/stm32u5xx_hal_conf.h
@@ -84,7 +84,7 @@ extern "C" {
#define HAL_SRAM_MODULE_ENABLED
#define HAL_TIM_MODULE_ENABLED
/*#define HAL_TSC_MODULE_ENABLED */
-/*#define HAL_RAMCFG_MODULE_ENABLED */
+#define HAL_RAMCFG_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/*#define HAL_USART_MODULE_ENABLED */
/*#define HAL_WWDG_MODULE_ENABLED */
diff --git a/core/embed/sys/linker/stm32u5g/prodtest.ld b/core/embed/sys/linker/stm32u5g/prodtest.ld
index efc2f4ab56..4eba5c45be 100644
--- a/core/embed/sys/linker/stm32u5g/prodtest.ld
+++ b/core/embed/sys/linker/stm32u5g/prodtest.ld
@@ -11,6 +11,7 @@ MEMORY {
SAES_RAM (wal) : ORIGIN = SAES_RAM_START, LENGTH = SAES_RAM_SIZE
FB1_RAM (wal) : ORIGIN = FB1_RAM_START, LENGTH = FB1_RAM_SIZE
FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE
+ BACKUP_RAM (wal) : ORIGIN = BACKUP_RAM_START, LENGTH = BACKUP_RAM_SIZE
}
_stack_section_start = ADDR(.stack);
@@ -35,6 +36,9 @@ _accessible_ram_1_end = MCU_SRAM4 + MCU_SRAM4_SIZE;
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
+_backup_ram_start = ORIGIN(BACKUP_RAM);
+_backup_ram_end = ORIGIN(BACKUP_RAM) + LENGTH(BACKUP_RAM);
+
_codelen = SIZEOF(.padding) + SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential);
_flash_start = ORIGIN(FLASH);
@@ -113,6 +117,11 @@ SECTIONS {
. = ALIGN(4);
} >AUX1_RAM
+ .backup_ram (NOLOAD) : {
+ . = ALIGN(4);
+ *(.backup_ram)
+ . = ALIGN(4);
+ } > BACKUP_RAM
.boot_args : ALIGN(8) {
*(.boot_command*);
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revC.py b/core/site_scons/models/T3W1/trezor_t3w1_revC.py
index 32f18f1c71..558e5b4170 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revC.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revC.py
@@ -77,6 +77,10 @@ def configure(
paths += ["embed/io/i2c_bus/inc"]
defines += [("USE_I2C", "1")]
+ sources += ["embed/sys/backup_ram/backup_ram.c"]
+ paths += ["embed/sys/backup_ram/inc"]
+ defines += [("USE_BACKUP_RAM", "1")]
+
if "haptic" in features_wanted:
sources += [
"embed/io/haptic/drv2625/drv2625.c",
diff --git a/core/site_scons/models/stm32u5_common.py b/core/site_scons/models/stm32u5_common.py
index 020576c3f4..8650ae8c82 100644
--- a/core/site_scons/models/stm32u5_common.py
+++ b/core/site_scons/models/stm32u5_common.py
@@ -68,6 +68,7 @@ def stm32u5_common_files(env, defines, sources, paths):
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_pcd_ex.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_pwr.c",
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_pwr_ex.c",
+ "vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_ramcfg.c",
"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",