mirror of https://github.com/ARMmbed/mbed-os.git
STM32WB align deepsleep functions with CubeFW
parent
f0370222d8
commit
ebae0e56d4
|
@ -0,0 +1,264 @@
|
|||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
***************************************************************************************
|
||||
* File Name : stm32_lpm_if.c
|
||||
* Description : Low layer function to enter/exit low power modes (stop, sleep).
|
||||
***************************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32wbxx_ll_hsem.h"
|
||||
#include "stm32wbxx_ll_cortex.h"
|
||||
#include "app_conf.h"
|
||||
/* USER CODE BEGIN include */
|
||||
|
||||
/* USER CODE END include */
|
||||
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void Switch_On_HSI( void );
|
||||
/* USER CODE BEGIN Private_Function_Prototypes */
|
||||
|
||||
/* USER CODE END Private_Function_Prototypes */
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Private_Typedef */
|
||||
|
||||
/* USER CODE END Private_Typedef */
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Private_Define */
|
||||
|
||||
/* USER CODE END Private_Define */
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Private_Macro */
|
||||
|
||||
/* USER CODE END Private_Macro */
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Private_Variables */
|
||||
|
||||
/* USER CODE END Private_Variables */
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Enters Low Power Off Mode
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_EnterOffMode( void )
|
||||
{
|
||||
/* USER CODE BEGIN PWR_EnterOffMode */
|
||||
/************************************************************************************
|
||||
* ENTER OFF MODE
|
||||
***********************************************************************************/
|
||||
/*
|
||||
* There is no risk to clear all the WUF here because in the current implementation, this API is called
|
||||
* in critical section. If an interrupt occurs while in that critical section before that point,
|
||||
* the flag is set and will be cleared here but the system will not enter Off Mode
|
||||
* because an interrupt is pending in the NVIC. The ISR will be executed when moving out
|
||||
* of this critical section
|
||||
*/
|
||||
LL_PWR_ClearFlag_WU( );
|
||||
|
||||
LL_PWR_SetPowerMode( LL_PWR_MODE_STANDBY );
|
||||
|
||||
LL_LPM_EnableDeepSleep( ); /**< Set SLEEPDEEP bit of Cortex System Control Register */
|
||||
|
||||
/**
|
||||
* This option is used to ensure that store operations are completed
|
||||
*/
|
||||
#if defined ( __CC_ARM)
|
||||
__force_stores( );
|
||||
#endif
|
||||
|
||||
__WFI( );
|
||||
/* USER CODE END PWR_EnterOffMode */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exits Low Power Off Mode
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_ExitOffMode( void )
|
||||
{
|
||||
/* USER CODE BEGIN PWR_ExitOffMode */
|
||||
|
||||
/* USER CODE END PWR_ExitOffMode */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enters Low Power Stop Mode
|
||||
* @note ARM exists the function when waking up
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_EnterStopMode( void )
|
||||
{
|
||||
/* USER CODE BEGIN PWR_EnterStopMode */
|
||||
/**
|
||||
* This function is called from CRITICAL SECTION
|
||||
*/
|
||||
while( LL_HSEM_1StepLock( HSEM, CFG_HW_RCC_SEMID ) );
|
||||
|
||||
if ( ! LL_HSEM_1StepLock( HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID ) )
|
||||
{
|
||||
if( LL_PWR_IsActiveFlag_C2DS( ) )
|
||||
{
|
||||
/* Release ENTRY_STOP_MODE semaphore */
|
||||
LL_HSEM_ReleaseLock( HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0 );
|
||||
|
||||
/**
|
||||
* The switch on HSI before entering Stop Mode is required on Cut2.0
|
||||
* It is useless from Cut2.1
|
||||
*/
|
||||
Switch_On_HSI( );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* The switch on HSI before entering Stop Mode is required on Cut2.0
|
||||
* It is useless from Cut2.1
|
||||
*/
|
||||
Switch_On_HSI( );
|
||||
}
|
||||
|
||||
/* Release RCC semaphore */
|
||||
LL_HSEM_ReleaseLock( HSEM, CFG_HW_RCC_SEMID, 0 );
|
||||
|
||||
/************************************************************************************
|
||||
* ENTER STOP MODE
|
||||
***********************************************************************************/
|
||||
LL_PWR_SetPowerMode( LL_PWR_MODE_STOP2 );
|
||||
|
||||
LL_LPM_EnableDeepSleep( ); /**< Set SLEEPDEEP bit of Cortex System Control Register */
|
||||
|
||||
/**
|
||||
* This option is used to ensure that store operations are completed
|
||||
*/
|
||||
#if defined ( __CC_ARM)
|
||||
__force_stores( );
|
||||
#endif
|
||||
|
||||
__WFI();
|
||||
/* USER CODE END PWR_EnterStopMode */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exits Low Power Stop Mode
|
||||
* @note Enable the pll at 32MHz
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_ExitStopMode( void )
|
||||
{
|
||||
/* USER CODE BEGIN PWR_ExitStopMode */
|
||||
/**
|
||||
* This function is called from CRITICAL SECTION
|
||||
*/
|
||||
|
||||
/* Release ENTRY_STOP_MODE semaphore */
|
||||
LL_HSEM_ReleaseLock( HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0 );
|
||||
|
||||
while( LL_HSEM_1StepLock( HSEM, CFG_HW_RCC_SEMID ) );
|
||||
|
||||
if(LL_RCC_GetSysClkSource( ) == LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
|
||||
{
|
||||
LL_RCC_HSE_Enable( );
|
||||
while(!LL_RCC_HSE_IsReady( ));
|
||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
|
||||
while (LL_RCC_GetSysClkSource( ) != LL_RCC_SYS_CLKSOURCE_STATUS_HSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* As long as the current application is fine with HSE as system clock source,
|
||||
* there is nothing to do here
|
||||
*/
|
||||
}
|
||||
|
||||
/* Release RCC semaphore */
|
||||
LL_HSEM_ReleaseLock( HSEM, CFG_HW_RCC_SEMID, 0 );
|
||||
/* USER CODE END PWR_ExitStopMode */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enters Low Power Sleep Mode
|
||||
* @note ARM exits the function when waking up
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_EnterSleepMode( void )
|
||||
{
|
||||
/* USER CODE BEGIN PWR_EnterSleepMode */
|
||||
|
||||
HAL_SuspendTick();
|
||||
|
||||
/************************************************************************************
|
||||
* ENTER SLEEP MODE
|
||||
***********************************************************************************/
|
||||
LL_LPM_EnableSleep( ); /**< Clear SLEEPDEEP bit of Cortex System Control Register */
|
||||
|
||||
/**
|
||||
* This option is used to ensure that store operations are completed
|
||||
*/
|
||||
#if defined ( __CC_ARM)
|
||||
__force_stores();
|
||||
#endif
|
||||
|
||||
__WFI( );
|
||||
/* USER CODE END PWR_EnterSleepMode */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exits Low Power Sleep Mode
|
||||
* @note ARM exits the function when waking up
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_ExitSleepMode( void )
|
||||
{
|
||||
/* USER CODE BEGIN PWR_ExitSleepMode */
|
||||
|
||||
HAL_ResumeTick();
|
||||
|
||||
/* USER CODE END PWR_ExitSleepMode */
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* LOCAL FUNCTIONS
|
||||
*
|
||||
*************************************************************/
|
||||
/**
|
||||
* @brief Switch the system clock on HSI
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
static void Switch_On_HSI( void )
|
||||
{
|
||||
LL_RCC_HSI_Enable( );
|
||||
while(!LL_RCC_HSI_IsReady( ));
|
||||
LL_RCC_SetSysClkSource( LL_RCC_SYS_CLKSOURCE_HSI );
|
||||
LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSI);
|
||||
while (LL_RCC_GetSysClkSource( ) != LL_RCC_SYS_CLKSOURCE_STATUS_HSI);
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN Private_Functions */
|
||||
|
||||
/* USER CODE END Private_Functions */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32_lpm_if.h
|
||||
* @brief Header for stm32_lpm_if.c module (device specific LP management)
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32_LPM_IF_H
|
||||
#define __STM32_LPM_IF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Enters Low Power Off Mode
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_EnterOffMode( void );
|
||||
/**
|
||||
* @brief Exits Low Power Off Mode
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_ExitOffMode( void );
|
||||
|
||||
/**
|
||||
* @brief Enters Low Power Stop Mode
|
||||
* @note ARM exists the function when waking up
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_EnterStopMode( void );
|
||||
/**
|
||||
* @brief Exits Low Power Stop Mode
|
||||
* @note Enable the pll at 32MHz
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_ExitStopMode( void );
|
||||
|
||||
/**
|
||||
* @brief Enters Low Power Sleep Mode
|
||||
* @note ARM exits the function when waking up
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_EnterSleepMode( void );
|
||||
|
||||
/**
|
||||
* @brief Exits Low Power Sleep Mode
|
||||
* @note ARM exits the function when waking up
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_ExitSleepMode( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__STM32_LPM_IF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -17,116 +17,22 @@
|
|||
|
||||
#if DEVICE_SLEEP
|
||||
|
||||
#include "sleep_api.h"
|
||||
#include "us_ticker_api.h"
|
||||
#include "us_ticker_data.h"
|
||||
#include "mbed_critical.h"
|
||||
#include "mbed_error.h"
|
||||
#include "stm32wbxx_ll_hsem.h"
|
||||
#include "stm32wbxx_ll_cortex.h"
|
||||
#include "hw_conf.h" /* Common BLE file where BLE shared resources are defined */
|
||||
|
||||
extern void save_timer_ctx(void);
|
||||
extern void restore_timer_ctx(void);
|
||||
extern int serial_is_tx_ongoing(void);
|
||||
extern void PWR_EnterStopMode(void);
|
||||
extern void PWR_ExitStopMode(void);
|
||||
|
||||
|
||||
extern int mbed_sdk_inited;
|
||||
|
||||
static void Switch_On_HSI(void)
|
||||
{
|
||||
LL_RCC_HSI_Enable();
|
||||
while (!LL_RCC_HSI_IsReady());
|
||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
|
||||
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void LPM_EnterStopMode(void)
|
||||
{
|
||||
/**
|
||||
* This function is called from CRITICAL SECTION
|
||||
*/
|
||||
|
||||
while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID));
|
||||
|
||||
/**
|
||||
* Select HSI as system clock source after Wake Up from Stop mode
|
||||
*/
|
||||
LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI);
|
||||
|
||||
if (! LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID)) {
|
||||
if (LL_PWR_IsActiveFlag_C2DS()) {
|
||||
/* Release ENTRY_STOP_MODE semaphore */
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);
|
||||
|
||||
Switch_On_HSI();
|
||||
}
|
||||
} else {
|
||||
Switch_On_HSI();
|
||||
}
|
||||
|
||||
/* Release RCC semaphore */
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void LPM_ExitStopMode(void)
|
||||
{
|
||||
/**
|
||||
* This function is called from CRITICAL SECTION
|
||||
*/
|
||||
|
||||
/* Release ENTRY_STOP_MODE semaphore */
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);
|
||||
|
||||
if ((LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_HSI) || (LL_PWR_IsActiveFlag_C1STOP() != 0)) {
|
||||
LL_PWR_ClearFlag_C1STOP_C1STB();
|
||||
|
||||
while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID));
|
||||
|
||||
if (LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
|
||||
LL_RCC_HSE_Enable();
|
||||
while (!LL_RCC_HSE_IsReady());
|
||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
|
||||
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE);
|
||||
} else {
|
||||
/**
|
||||
* As long as the current application is fine with HSE as system clock source,
|
||||
* there is nothing to do here
|
||||
*/
|
||||
}
|
||||
|
||||
/* Release RCC semaphore */
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_LPM_StopMode(void)
|
||||
{
|
||||
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2);
|
||||
|
||||
LL_LPM_EnableDeepSleep(); /**< Set SLEEPDEEP bit of Cortex System Control Register */
|
||||
|
||||
/**
|
||||
* This option is used to ensure that store operations are completed
|
||||
*/
|
||||
#if defined ( __CC_ARM)
|
||||
__force_stores();
|
||||
#endif
|
||||
|
||||
__WFI();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* STM32WB has very specific needs to handling STOP mode.
|
||||
* The target has a cortex-M4 and cortex-M0 and needs to
|
||||
* handle shared ressources btw both cores.
|
||||
* Each core can sleep independantly, but the first one that
|
||||
* wkaes-up needs to restore the clock tree.
|
||||
* wakes-up needs to restore the clock tree.
|
||||
*/
|
||||
void hal_deepsleep(void)
|
||||
{
|
||||
|
@ -149,12 +55,8 @@ void hal_deepsleep(void)
|
|||
* us_ticker timestamp until the us_ticker context is restored. */
|
||||
mbed_sdk_inited = 0;
|
||||
|
||||
/**
|
||||
* Enter the STOP mode
|
||||
*/
|
||||
LPM_EnterStopMode();
|
||||
HW_LPM_StopMode();
|
||||
LPM_ExitStopMode();
|
||||
PWR_EnterStopMode();
|
||||
PWR_ExitStopMode();
|
||||
|
||||
restore_timer_ctx();
|
||||
|
||||
|
@ -166,5 +68,4 @@ void hal_deepsleep(void)
|
|||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue