arch/arm/stm32h5: Add PM stop and standby support.
Some checks are pending
Docker-Linux / push (push) Waiting to run
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions

Implement PM STANDBY. Loosely based on stm32h7 with
simpler registers.

Implement PM STOP. Using a similar parameter to stm32h7's
LPDS mode bool. There is no LPDS on stm32h5 but there is
the same lower-power voltage scaling value, so rename the parameter
for stm32h5 and use SVOS5 without LPDS present.

Add arm_pminitialize implementation with default
pm subsystem initialization.

Co-authored-by: Austin.Chen <Austin.Chen@wnc.com.tw>
Signed-off-by: Liam Howatt <liamhowatt@geotab.com>
This commit is contained in:
Liam Howatt 2026-08-18 10:30:26 -04:00 committed by Alan C. Assis
parent 34f25ed228
commit 0795d9a647
5 changed files with 360 additions and 0 deletions

View file

@ -116,6 +116,13 @@ ifeq ($(CONFIG_STM32_PWM),y)
CHIP_CSRCS += stm32_pwm.c
endif
ifeq ($(CONFIG_PM),y)
CHIP_CSRCS += stm32_pmstandby.c stm32_pmstop.c
ifneq ($(CONFIG_ARCH_CUSTOM_PMINIT),y)
CHIP_CSRCS += stm32_pminitialize.c
endif
endif
ifeq ($(CONFIG_STM32_IWDG),y)
CHIP_CSRCS += stm32_iwdg.c
endif

View file

@ -0,0 +1,91 @@
/****************************************************************************
* arch/arm/src/stm32h5/stm32_pm.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_STM32H5_STM32_PM_H
#define __ARCH_ARM_SRC_STM32H5_STM32_PM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include "chip.h"
#include "arm_internal.h"
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Name: stm32_pmstop
*
* Description:
* Enter STOP mode.
*
* Input Parameters:
* svos5 - true: To further reduce power consumption in Stop mode, put the
* internal voltage regulator in "stop mode voltage scaling"
* scale 5 which is the lowest-power stop mode.
* false: Use SVOS3 which is the default voltage scaling value.
*
* Returned Value:
* None
*
****************************************************************************/
void stm32_pmstop(bool svos5);
/****************************************************************************
* Name: stm32_pmstandby
*
* Description:
* Enter STANDBY mode.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void stm32_pmstandby(void);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_STM32H5_STM32_PM_H */

View file

@ -0,0 +1,64 @@
/****************************************************************************
* arch/arm/src/stm32h5/stm32_pminitialize.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/power/pm.h>
#include "arm_internal.h"
#include "stm32_pm.h"
#ifdef CONFIG_PM
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: arm_pminitialize
*
* Description:
* This function is called by MCU-specific logic at power-on reset in
* order to provide one-time initialization the power management subsystem.
* This function must be called *very* early in the initialization sequence
* *before* any other device drivers are initialized (since they may
* attempt to register with the power management subsystem).
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
void arm_pminitialize(void)
{
/* Initialize the NuttX power management subsystem proper */
pm_initialize();
}
#endif /* CONFIG_PM */

View file

@ -0,0 +1,88 @@
/****************************************************************************
* arch/arm/src/stm32h5/stm32_pmstandby.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include "arm_internal.h"
#include "nvic.h"
#include "stm32_rcc.h"
#include "stm32_pwr.h"
#include "stm32_pm.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_pmstandby
*
* Description:
* Enter STANDBY mode.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void stm32_pmstandby(void)
{
uint32_t regval;
/* Clear the wake-up flags before resetting. */
modifyreg32(STM32_PWR_PMCR, 0, PWR_PMCR_CSSF);
modifyreg32(STM32_PWR_WUSCR, 0, PWR_WUSCR_CWUF1 | PWR_WUSCR_CWUF2 |
PWR_WUSCR_CWUF3 | PWR_WUSCR_CWUF4 |
PWR_WUSCR_CWUF5 | PWR_WUSCR_CWUF6 |
PWR_WUSCR_CWUF7 | PWR_WUSCR_CWUF8);
/* Clear reset flags. */
modifyreg32(STM32_RCC_RSR, 0, RCC_RSR_RMVF);
/* Set the Low Power Mode to Standby in the Power Mode Control Register.
* Unlike H7 which has multiple power domains (D1, D2, D3), H5 uses a
* single bit in PMCR to select between Stop and Standby modes.
* Setting LPMS bit to 1 selects Standby mode.
*/
modifyreg32(STM32_PWR_PMCR, 0, PWR_PMCR_LPMS);
/* Set SLEEPDEEP bit of Cortex System Control Register */
regval = getreg32(NVIC_SYSCON);
regval |= NVIC_SYSCON_SLEEPDEEP;
putreg32(regval, NVIC_SYSCON);
/* Sleep until the wakeup reset occurs */
asm("wfi");
}

View file

@ -0,0 +1,110 @@
/****************************************************************************
* arch/arm/src/stm32h5/stm32_pmstop.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include "arm_internal.h"
#include "nvic.h"
#include "stm32_pwr.h"
#include "stm32_pm.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_pmstop
*
* Description:
* Enter STOP mode.
*
* Input Parameters:
* svos5 - true: To further reduce power consumption in Stop mode, put the
* internal voltage regulator in "stop mode voltage scaling"
* scale 5 which is the lowest-power stop mode.
* false: Use SVOS3 which is the default voltage scaling value.
*
* Returned Value:
* None
*
****************************************************************************/
void stm32_pmstop(bool svos5)
{
uint32_t regval;
/* Clear the Low Power Mode Selection (LPMS) bit in the power mode control
* register to specify Stop mode when entering DeepSleep.
*/
regval = getreg32(STM32_PWR_PMCR);
regval &= ~(PWR_PMCR_LPMS | PWR_PMCR_SVOS_MASK);
/* Set low-power voltage scaling. */
if (svos5)
{
regval |= PWR_PMCR_SVOS_SVOS5;
}
else
{
/* Set regulator to normal (S3) mode */
regval |= PWR_PMCR_SVOS_SVOS3;
}
putreg32(regval, STM32_PWR_PMCR);
/* Set SLEEPDEEP bit of Cortex System Control Register */
regval = getreg32(NVIC_SYSCON);
regval |= NVIC_SYSCON_SLEEPDEEP;
putreg32(regval, NVIC_SYSCON);
/* Sleep until the wakeup interrupt or event occurs */
#ifdef CONFIG_PM_WFE
/* Mode: SLEEP + Entry with WFE */
asm volatile ("wfe");
#else
/* Mode: SLEEP + Entry with WFI */
asm volatile ("wfi");
#endif
/* Clear deep sleep bits, so that MCU does not go into deep sleep in
* idle.
*/
/* Clear SLEEPDEEP bit of Cortex System Control Register */
regval = getreg32(NVIC_SYSCON);
regval &= ~NVIC_SYSCON_SLEEPDEEP;
putreg32(regval, NVIC_SYSCON);
}