mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cpu/{cortexm_common, stm32}: add support for backup RAM
This commit is contained in:
parent
5fdf8d2d88
commit
70d3d647d1
@ -137,6 +137,9 @@ void reset_handler_default(void)
|
||||
}
|
||||
|
||||
#ifdef CPU_HAS_BACKUP_RAM
|
||||
#if BACKUP_RAM_HAS_INIT
|
||||
backup_ram_init();
|
||||
#endif
|
||||
if (!cpu_woke_from_backup() ||
|
||||
CPU_BACKUP_RAM_NOT_RETAINED) {
|
||||
|
||||
|
@ -24,6 +24,16 @@ ifneq (,$(filter $(CPU_FAM),f0 f2 f3 f4 f7 l0 l1 l4 l5 u5 wb wl))
|
||||
endif
|
||||
endif
|
||||
|
||||
STM32_WITH_BKPRAM = stm32f205% stm32f207% stm32f215% stm32f217% \
|
||||
stm32f405% stm32f407% stm32f415% stm32f417% \
|
||||
stm32f427% stm32f429% stm32f437% stm32f439% \
|
||||
stm32f446% stm32f469% stm32f479% \
|
||||
stm32f7% \
|
||||
stm32u5%
|
||||
ifneq (,$(filter $(STM32_WITH_BKPRAM),$(CPU_MODEL)))
|
||||
FEATURES_PROVIDED += backup_ram
|
||||
endif
|
||||
|
||||
# The f2, f4 and f7 do not support the pagewise api
|
||||
ifneq (,$(filter $(CPU_FAM),f2 f4 f7))
|
||||
FEATURES_PROVIDED += periph_flashpage
|
||||
|
@ -372,3 +372,43 @@ void cpu_init(void)
|
||||
_wlx5xx_init_subghz_debug_pins();
|
||||
}
|
||||
}
|
||||
|
||||
void backup_ram_init(void)
|
||||
{
|
||||
/* see reference manual "Battery backup domain" */
|
||||
#if defined(RCC_APB1ENR_PWREN)
|
||||
periph_clk_en(APB1, RCC_APB1ENR_PWREN);
|
||||
#elif defined(RCC_APBENR1_PWREN)
|
||||
periph_clk_en(APB1, RCC_APBENR1_PWREN);
|
||||
#elif defined(RCC_APB1ENR1_PWREN)
|
||||
periph_clk_en(APB1, RCC_APB1ENR1_PWREN);
|
||||
#elif defined(RCC_AHB3ENR_PWREN)
|
||||
periph_clk_en(AHB3, RCC_AHB3ENR_PWREN);
|
||||
#endif
|
||||
stmclk_dbp_unlock();
|
||||
#if defined(RCC_AHB1ENR_BKPSRAMEN)
|
||||
periph_clk_en(AHB1, RCC_AHB1ENR_BKPSRAMEN);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BACKUP_RAM_MAGIC
|
||||
#define BACKUP_RAM_MAGIC {'R', 'I', 'O', 'T'}
|
||||
#endif
|
||||
|
||||
bool cpu_woke_from_backup(void)
|
||||
{
|
||||
#if IS_ACTIVE(CPU_HAS_BACKUP_RAM)
|
||||
static const char _signature[] BACKUP_RAM_DATA = BACKUP_RAM_MAGIC;
|
||||
/* switch off regulator to save power */
|
||||
#ifndef RIOTBOOT
|
||||
pm_backup_regulator_off();
|
||||
#endif
|
||||
for (unsigned i = 0; i < sizeof(_signature); i++) {
|
||||
if (_signature[i] != ((char[])BACKUP_RAM_MAGIC)[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
#endif /* CPU_HAS_BACKUP_RAM */
|
||||
return false;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@
|
||||
#elif CPU_FAM_STM32U5
|
||||
#include "stm32u5xx.h"
|
||||
#include "irqs/u5/irqs.h"
|
||||
#define NUM_HEAPS 2
|
||||
#define NUM_HEAPS 3
|
||||
#elif CPU_FAM_STM32WB
|
||||
#include "stm32wbxx.h"
|
||||
#include "irqs/wb/irqs.h"
|
||||
|
46
cpu/stm32/include/periph/cpu_backup_ram.h
Normal file
46
cpu/stm32/include/periph/cpu_backup_ram.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Otto-von-Guericke-Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_stm32
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Backup SRAM CPU specific definitions for the STM32 family
|
||||
*
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
*/
|
||||
|
||||
#ifndef PERIPH_CPU_BACKUP_RAM_H
|
||||
#define PERIPH_CPU_BACKUP_RAM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Backup RAM must be initialized with @ref backup_ram_init on reset
|
||||
*/
|
||||
#define BACKUP_RAM_HAS_INIT 1
|
||||
|
||||
/**
|
||||
* @brief Enable backup RAM access
|
||||
*/
|
||||
void backup_ram_init(void);
|
||||
|
||||
/**
|
||||
* @brief Returns true if the CPU woke up from deep sleep (backup/standby)
|
||||
*/
|
||||
bool cpu_woke_from_backup(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PERIPH_CPU_BACKUP_RAM_H */
|
||||
/** @} */
|
@ -50,6 +50,22 @@ extern "C" {
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Check whether the backup domain voltage regulator is on
|
||||
*/
|
||||
bool pm_backup_regulator_is_on(void);
|
||||
|
||||
/**
|
||||
* @brief Enable the backup domain voltage regulator to retain backup
|
||||
* register content during standby and VBAT mode
|
||||
*/
|
||||
void pm_backup_regulator_on(void);
|
||||
|
||||
/**
|
||||
* @brief Disable the backup domain voltage regulator
|
||||
*/
|
||||
void pm_backup_regulator_off(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "periph/wl/periph_cpu.h"
|
||||
#endif
|
||||
|
||||
#include "periph/cpu_backup_ram.h"
|
||||
#include "periph/cpu_common.h"
|
||||
#include "periph/cpu_dma.h"
|
||||
#include "periph/cpu_eth.h"
|
||||
|
@ -22,6 +22,8 @@
|
||||
#ifndef STMCLK_H
|
||||
#define STMCLK_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -84,6 +86,14 @@ void stmclk_dbp_unlock(void);
|
||||
*/
|
||||
void stmclk_dbp_lock(void);
|
||||
|
||||
/**
|
||||
* @brief Check whether write access to the backup domain is locked
|
||||
*
|
||||
* @retval true: locked
|
||||
* @retval false: unlocked
|
||||
*/
|
||||
bool stmclk_dbp_is_locked(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -9,6 +9,7 @@ config CPU_FAM_F2
|
||||
bool
|
||||
select CPU_STM32
|
||||
select CPU_CORE_CORTEX_M3
|
||||
select HAS_BACKUP_RAM
|
||||
select HAS_CPU_STM32F2
|
||||
select HAS_CORTEXM_MPU
|
||||
select HAS_PERIPH_FLASHPAGE
|
||||
|
@ -23,12 +23,14 @@ config CPU_LINE_STM32F401XE
|
||||
config CPU_LINE_STM32F405XX
|
||||
bool
|
||||
select CPU_FAM_F4
|
||||
select HAS_BACKUP_RAM
|
||||
select HAS_PERIPH_HWRNG
|
||||
select CLOCK_MAX_180MHZ
|
||||
|
||||
config CPU_LINE_STM32F407XX
|
||||
bool
|
||||
select CPU_FAM_F4
|
||||
select HAS_BACKUP_RAM
|
||||
select HAS_PERIPH_HWRNG
|
||||
select CLOCK_MAX_180MHZ
|
||||
|
||||
@ -83,12 +85,14 @@ config CPU_LINE_STM32F413XX
|
||||
config CPU_LINE_STM32F415XX
|
||||
bool
|
||||
select CPU_FAM_F4
|
||||
select HAS_BACKUP_RAM
|
||||
select HAS_PERIPH_HWRNG
|
||||
select CLOCK_MAX_180MHZ
|
||||
|
||||
config CPU_LINE_STM32F417XX
|
||||
bool
|
||||
select CPU_FAM_F4
|
||||
select HAS_BACKUP_RAM
|
||||
select CLOCK_MAX_180MHZ
|
||||
|
||||
config CPU_LINE_STM32F423XX
|
||||
@ -99,37 +103,44 @@ config CPU_LINE_STM32F423XX
|
||||
config CPU_LINE_STM32F427XX
|
||||
bool
|
||||
select CPU_FAM_F4
|
||||
select HAS_BACKUP_RAM
|
||||
select CLOCK_MAX_180MHZ
|
||||
|
||||
config CPU_LINE_STM32F429XX
|
||||
bool
|
||||
select CPU_FAM_F4
|
||||
select HAS_BACKUP_RAM
|
||||
select HAS_PERIPH_HWRNG
|
||||
select CLOCK_MAX_180MHZ
|
||||
|
||||
config CPU_LINE_STM32F437XX
|
||||
bool
|
||||
select CPU_FAM_F4
|
||||
select HAS_BACKUP_RAM
|
||||
select HAS_PERIPH_HWRNG
|
||||
select CLOCK_MAX_180MHZ
|
||||
|
||||
config CPU_LINE_STM32F439XX
|
||||
bool
|
||||
select CPU_FAM_F4
|
||||
select HAS_BACKUP_RAM
|
||||
select CLOCK_MAX_180MHZ
|
||||
|
||||
config CPU_LINE_STM32F446XX
|
||||
bool
|
||||
select CPU_FAM_F4
|
||||
select HAS_BACKUP_RAM
|
||||
select CLOCK_MAX_180MHZ
|
||||
|
||||
config CPU_LINE_STM32F469XX
|
||||
bool
|
||||
select CPU_FAM_F4
|
||||
select HAS_BACKUP_RAM
|
||||
select HAS_PERIPH_HWRNG
|
||||
select CLOCK_MAX_180MHZ
|
||||
|
||||
config CPU_LINE_STM32F479XX
|
||||
bool
|
||||
select CPU_FAM_F4
|
||||
select HAS_BACKUP_RAM
|
||||
select CLOCK_MAX_180MHZ
|
||||
|
@ -9,6 +9,7 @@ config CPU_FAM_F7
|
||||
bool
|
||||
select CPU_STM32
|
||||
select CPU_CORE_CORTEX_M7
|
||||
select HAS_BACKUP_RAM
|
||||
select HAS_CPU_STM32F7
|
||||
select HAS_CORTEXM_MPU
|
||||
select HAS_PERIPH_FLASHPAGE
|
||||
|
@ -9,6 +9,7 @@ config CPU_FAM_U5
|
||||
bool
|
||||
select CPU_STM32
|
||||
select CPU_CORE_CORTEX_M33
|
||||
select HAS_BACKUP_RAM
|
||||
select HAS_CPU_STM32U5
|
||||
select HAS_PERIPH_FLASHPAGE
|
||||
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||
|
@ -31,8 +31,8 @@ SECTIONS
|
||||
{
|
||||
.heap2 ALIGN(4) (NOLOAD) :
|
||||
{
|
||||
_sheap1 = . ;
|
||||
_eheap1 = ORIGIN(sram4) + LENGTH(sram4);
|
||||
_sheap2 = . ;
|
||||
_eheap2 = ORIGIN(sram4) + LENGTH(sram4);
|
||||
} > sram4
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "irq.h"
|
||||
#include "periph/pm.h"
|
||||
#include "periph/cpu_pm.h"
|
||||
#include "stmclk.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
@ -137,6 +138,7 @@ void pm_set(unsigned mode)
|
||||
PWR_WUP_REG |= PM_EWUP_CONFIG;
|
||||
/* Set SLEEPDEEP bit of system control block */
|
||||
deep = 1;
|
||||
pm_backup_regulator_on();
|
||||
break;
|
||||
#endif
|
||||
case STM32_PM_STOP:
|
||||
@ -159,3 +161,61 @@ void pm_set(unsigned mode)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Registers and related configuration bits to retain
|
||||
* the backup domain registers, using the backup regulator
|
||||
* @{
|
||||
*/
|
||||
#if defined(PWR_CSR1_BRE)
|
||||
#define PWR_BACKUP_REGULATOR_REG PWR->CSR1
|
||||
#define BKPREG_CONFIG (PWR_CSR1_BRE | PWR_CSR1_EIWUP)
|
||||
#define BKPREG_READY (PWR_CSR1_BRR)
|
||||
#elif defined(PWR_CSR_BRE)
|
||||
#define PWR_BACKUP_REGULATOR_REG PWR->CSR
|
||||
#define BKPREG_CONFIG (PWR_CSR_BRE)
|
||||
#define BKPREG_READY (PWR_CSR_BRR)
|
||||
#elif defined(PWR_CR2_BREN)
|
||||
#define PWR_BACKUP_REGULATOR_REG PWR->CR2
|
||||
#define BKPREG_CONFIG (PWR_CR2_BREN)
|
||||
#define BKPREG_READY (PWR_CR2_BRRDY)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
bool pm_backup_regulator_is_on(void)
|
||||
{
|
||||
#if defined(PWR_BACKUP_REGULATOR_REG)
|
||||
return (PWR_BACKUP_REGULATOR_REG & BKPREG_READY) == BKPREG_READY;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void pm_backup_regulator_on(void)
|
||||
{
|
||||
#if defined(PWR_BACKUP_REGULATOR_REG)
|
||||
bool locked = stmclk_dbp_is_locked();
|
||||
if (locked) {
|
||||
stmclk_dbp_unlock();
|
||||
}
|
||||
PWR_BACKUP_REGULATOR_REG |= BKPREG_CONFIG;
|
||||
while (!(PWR_BACKUP_REGULATOR_REG & BKPREG_READY));
|
||||
if (locked) {
|
||||
stmclk_dbp_lock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void pm_backup_regulator_off(void)
|
||||
{
|
||||
#if defined(PWR_BACKUP_REGULATOR_REG)
|
||||
bool locked = stmclk_dbp_is_locked();
|
||||
if (locked) {
|
||||
stmclk_dbp_unlock();
|
||||
}
|
||||
PWR_BACKUP_REGULATOR_REG &= ~BKPREG_CONFIG;
|
||||
if (locked) {
|
||||
stmclk_dbp_lock();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -90,6 +90,10 @@ ifeq ($(STM32_TYPE), F)
|
||||
else ifeq ($(STM32_MODEL3), 7)
|
||||
RAM_LEN = 128K
|
||||
endif
|
||||
ifneq (, $(filter $(STM32_MODEL), 205 207 215 217))
|
||||
BACKUP_RAM_ADDR = 0x40024000
|
||||
BACKUP_RAM_LEN = 0x4K
|
||||
endif
|
||||
else ifeq ($(STM32_FAMILY), 3)
|
||||
ifeq ($(STM32_MODEL), 301)
|
||||
RAM_LEN = 16K
|
||||
@ -167,6 +171,10 @@ ifeq ($(STM32_TYPE), F)
|
||||
ifneq (, $(filter $(STM32_MODEL3), 5 7 9))
|
||||
CCMRAM_LEN = 64K
|
||||
endif
|
||||
ifneq (, $(filter $(STM32_MODEL), 405 407 415 417 427 429 437 439 446 469 479))
|
||||
BACKUP_RAM_ADDR = 0x40024000
|
||||
BACKUP_RAM_LEN = 0x4K
|
||||
endif
|
||||
else ifeq ($(STM32_FAMILY),7)
|
||||
ifneq (, $(filter $(STM32_MODEL2), 2 3))
|
||||
RAM_LEN = 256K
|
||||
@ -175,6 +183,8 @@ ifeq ($(STM32_TYPE), F)
|
||||
else ifneq (, $(filter $(STM32_MODEL2), 6 7))
|
||||
RAM_LEN = 512K
|
||||
endif
|
||||
BACKUP_RAM_ADDR = 0x40024000
|
||||
BACKUP_RAM_LEN = 0x4K
|
||||
endif
|
||||
else ifeq ($(STM32_TYPE), G)
|
||||
ifeq ($(STM32_FAMILY), 0)
|
||||
@ -271,6 +281,8 @@ else ifeq ($(STM32_TYPE), U)
|
||||
ifneq (, $(filter $(STM32_MODEL2), 7 8))
|
||||
RAM_LEN = 768K
|
||||
SRAM4_LEN = 16K
|
||||
BACKUP_RAM_ADDR = 0x40036400
|
||||
BACKUP_RAM_LEN = 0x2K
|
||||
endif
|
||||
endif
|
||||
else ifeq ($(STM32_TYPE), W)
|
||||
|
@ -115,5 +115,14 @@ void stmclk_dbp_unlock(void)
|
||||
|
||||
void stmclk_dbp_lock(void)
|
||||
{
|
||||
PWR->REG_PWR_CR &= ~(BIT_CR_DBP);
|
||||
if (!IS_ACTIVE(CPU_HAS_BACKUP_RAM)) {
|
||||
/* The DBP must be unlocked all the time, if we modify
|
||||
backup RAM content by comfortable BACKUP_RAM variables */
|
||||
PWR->REG_PWR_CR &= ~(BIT_CR_DBP);
|
||||
}
|
||||
}
|
||||
|
||||
bool stmclk_dbp_is_locked(void)
|
||||
{
|
||||
return !(PWR->REG_PWR_CR & BIT_CR_DBP);
|
||||
}
|
||||
|
@ -246,6 +246,11 @@ void stmclk_init_sysclk(void)
|
||||
/* Wait Until the Voltage Regulator is ready */
|
||||
while (!(PWR->VOSR & PWR_VOSR_VOSRDY)) {}
|
||||
|
||||
/* Backup RAM retention in Standby and VBAT modes:
|
||||
This bit can be written only when the regulator is LDO,
|
||||
which must be configured before switching to SMPS */
|
||||
PWR->BDCR1 |= PWR_BDCR1_BREN;
|
||||
|
||||
/* Switch to SMPS regulator instead of LDO */
|
||||
PWR->CR3 |= PWR_CR3_REGSEL;
|
||||
while (!(PWR->SVMSR & PWR_SVMSR_REGS)) {}
|
||||
|
Loading…
Reference in New Issue
Block a user