diff --git a/arch/arm/src/stm32h5/Make.defs b/arch/arm/src/stm32h5/Make.defs index ca1b2e1dfe1..d401ea56d7d 100644 --- a/arch/arm/src/stm32h5/Make.defs +++ b/arch/arm/src/stm32h5/Make.defs @@ -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 diff --git a/arch/arm/src/stm32h5/stm32_pm.h b/arch/arm/src/stm32h5/stm32_pm.h new file mode 100644 index 00000000000..a2f47fc8bdd --- /dev/null +++ b/arch/arm/src/stm32h5/stm32_pm.h @@ -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 + +#include + +#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 */ diff --git a/arch/arm/src/stm32h5/stm32_pminitialize.c b/arch/arm/src/stm32h5/stm32_pminitialize.c new file mode 100644 index 00000000000..cbbaed06009 --- /dev/null +++ b/arch/arm/src/stm32h5/stm32_pminitialize.c @@ -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 +#include + +#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 */ diff --git a/arch/arm/src/stm32h5/stm32_pmstandby.c b/arch/arm/src/stm32h5/stm32_pmstandby.c new file mode 100644 index 00000000000..135f547c27d --- /dev/null +++ b/arch/arm/src/stm32h5/stm32_pmstandby.c @@ -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 + +#include + +#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"); +} diff --git a/arch/arm/src/stm32h5/stm32_pmstop.c b/arch/arm/src/stm32h5/stm32_pmstop.c new file mode 100644 index 00000000000..089113288eb --- /dev/null +++ b/arch/arm/src/stm32h5/stm32_pmstop.c @@ -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 + +#include + +#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); +}