/******************************************************************************* * 函数名称: PWR_EnterSTOPMode * 功能描述: 进入STOP模式. * 输入参数: PWR_Regulator:STOP模式的校准状态。 * 这个参数可以是下面的值之一: * - PWR_Regulator_ON: 校准器开启的STOP模式 * - PWR_Regulator_LowPower: 在低功耗模式下带有校准器的STOP模式。 * - PWR_STOPEntry: 这个参数定义了STOP进入模式. * 这个参数可以是下面的值之一: * - PWR_STOPEntry_WFI: 进入有WFI指令的STOP模式 * - PWR_STOPEntry_WFE: 进入有WFE指令的STOP模式 * 输出参数: 无 * 返回参数: 无 *******************************************************************************/ void PWR_EnterSTOPMode(u32 PWR_Regulator, u8 PWR_STOPEntry) { u32 tmpreg = 0; /* Check the parameters [检查参数]*/ assert_param(IS_PWR_REGULATOR(PWR_Regulator)); assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); /* Select the regulator state in STOP mode [在停止模式选择校准状态]*/ tmpreg = PWR->CR; /* Clear PDDS and LPDS bits [清PDDS和LPDS位]*/ tmpreg &= CR_DS_Mask; /* Set LPDS bit according to PWR_Regulator value [依照PWR_Regulator值置位LPDS]*/ tmpreg |= PWR_Regulator; /* Store the new value [保存新的值]*/ PWR->CR = tmpreg; /* Set SLEEPDEEP bit of Cortex System Control Register [置位Cortex系统的控制寄存器SLEEPDEEP位]*/ *(vu32 *) SCB_SysCtrl |= SysCtrl_SLEEPDEEP_Set; /* Select STOP mode entry [选择停止模式进入]*/ if(PWR_STOPEntry == PWR_STOPEntry_WFI) { /* Request Wait For Interrupt [请求等待中断]*/ __WFI(); } else { /* Request Wait For Event [请求等待事件]*/ __WFE(); } }
/** * @brief Enter Stop 0 mode. * @note In Stop 0 mode, main and low voltage regulators are ON. * @note In Stop 0 mode, all I/O pins keep the same state as in Run mode. * @note All clocks in the VCORE domain are stopped; the PLL, the MSI, * the HSI and the HSE oscillators are disabled. Some peripherals with the wakeup capability * (I2Cx, USARTx and LPUART) can switch on the HSI to receive a frame, and switch off the HSI * after receiving the frame if it is not a wakeup frame. In this case, the HSI clock is propagated * only to the peripheral requesting it. * SRAM1, SRAM2 and register contents are preserved. * The BOR is available. * @note When exiting Stop 0 mode by issuing an interrupt or a wakeup event, * the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register * is set; the MSI oscillator is selected if STOPWUCK is cleared. * @note By keeping the internal regulator ON during Stop 0 mode, the consumption * is higher although the startup time is reduced. * @param STOPEntry specifies if Stop mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg @ref PWR_STOPENTRY_WFI Enter Stop mode with WFI instruction * @arg @ref PWR_STOPENTRY_WFE Enter Stop mode with WFE instruction * @retval None */ void HAL_PWREx_EnterSTOP0Mode(uint8_t STOPEntry) { /* Check the parameters */ assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); /* Stop 0 mode with Main Regulator */ MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STOP0); /* Set SLEEPDEEP bit of Cortex System Control Register */ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); /* Select Stop mode entry --------------------------------------------------*/ if(STOPEntry == PWR_STOPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } /* Reset SLEEPDEEP bit of Cortex System Control Register */ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); }
/** * @brief Enters STOP mode. * @param PWR_Regulator: specifies the regulator state in STOP mode. * This parameter can be one of the following values: * @arg PWR_Regulator_ON: STOP mode with regulator ON * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction * @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction * @retval None */ void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_PWR_REGULATOR(PWR_Regulator)); assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); /* Select the regulator state in STOP mode ---------------------------------*/ tmpreg = PWR->CR; /* Clear PDDS and LPDS bits */ tmpreg &= CR_DS_Mask; /* Set LPDS bit according to PWR_Regulator value */ tmpreg |= PWR_Regulator; /* Store the new value */ PWR->CR = tmpreg; /* Set SLEEPDEEP bit of Cortex System Control Register */ *(__IO uint32_t *) SCB_SysCtrl |= SysCtrl_SLEEPDEEP_Set; /* Select STOP mode entry --------------------------------------------------*/ if(PWR_STOPEntry == PWR_STOPEntry_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __WFE(); } }
/** * @brief Enters in Under-Drive STOP mode. * * @note This mode can be selected only when the Under-Drive is already active * * @note This mode is enabled only with STOP low power mode. * In this mode, the 1.2V domain is preserved in reduced leakage mode. This * mode is only available when the main regulator or the low power regulator * is in low voltage mode * * @note If the Under-drive mode was enabled, it is automatically disabled after * exiting Stop mode. * When the voltage regulator operates in Under-drive mode, an additional * startup delay is induced when waking up from Stop mode. * * @note In Stop mode, all I/O pins keep the same state as in Run mode. * * @note When exiting Stop mode by issuing an interrupt or a wakeup event, * the HSI RC oscillator is selected as system clock. * * @note When the voltage regulator operates in low power mode, an additional * startup delay is incurred when waking up from Stop mode. * By keeping the internal regulator ON during Stop mode, the consumption * is higher although the startup time is reduced. * * @param Regulator: specifies the regulator state in STOP mode. * This parameter can be one of the following values: * @arg PWR_MAINREGULATOR_UNDERDRIVE_ON: Main Regulator in under-drive mode * and Flash memory in power-down when the device is in Stop under-drive mode * @arg PWR_LOWPOWERREGULATOR_UNDERDRIVE_ON: Low Power Regulator in under-drive mode * and Flash memory in power-down when the device is in Stop under-drive mode * @param STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_SLEEPENTRY_WFI: enter STOP mode with WFI instruction * @arg PWR_SLEEPENTRY_WFE: enter STOP mode with WFE instruction * @retval None */ HAL_StatusTypeDef HAL_PWREx_EnterUnderDriveSTOPMode(uint32_t Regulator, uint8_t STOPEntry) { uint32_t tempreg = 0; uint32_t tickstart = 0; /* Check the parameters */ assert_param(IS_PWR_REGULATOR_UNDERDRIVE(Regulator)); assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); /* Enable Power ctrl clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* Enable the Under-drive Mode ---------------------------------------------*/ /* Clear Under-drive flag */ __HAL_PWR_CLEAR_ODRUDR_FLAG(); /* Enable the Under-drive */ __HAL_PWR_UNDERDRIVE_ENABLE(); /* Get tick */ tickstart = HAL_GetTick(); /* Wait for UnderDrive mode is ready */ while(__HAL_PWR_GET_FLAG(PWR_FLAG_UDRDY)) { if((HAL_GetTick() - tickstart ) > PWR_UDERDRIVE_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } /* Select the regulator state in STOP mode ---------------------------------*/ tempreg = PWR->CR1; /* Clear PDDS, LPDS, MRLUDS and LPLUDS bits */ tempreg &= (uint32_t)~(PWR_CR1_PDDS | PWR_CR1_LPDS | PWR_CR1_LPUDS | PWR_CR1_MRUDS); /* Set LPDS, MRLUDS and LPLUDS bits according to PWR_Regulator value */ tempreg |= Regulator; /* Store the new value */ PWR->CR1 = tempreg; /* Set SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Select STOP mode entry --------------------------------------------------*/ if(STOPEntry == PWR_SLEEPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __WFE(); } /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); return HAL_OK; }
/** * @brief Enters Stop mode. * @note In Stop mode, all I/O pins keep the same state as in Run mode. * @note When exiting Stop mode by using an interrupt or a wakeup event, * MSI RC oscillator is selected as system clock. * @note When the voltage regulator operates in low power mode, an additional * startup delay is incurred when waking up from Stop mode. * By keeping the internal regulator ON during Stop mode, the consumption * is higher although the startup time is reduced. * @param Regulator: Specifies the regulator state in Stop mode. * This parameter can be one of the following values: * @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON * @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON * @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction * @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction * @retval None */ void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) { /* Check the parameters */ assert_param(IS_PWR_REGULATOR(Regulator)); assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); /* Select the regulator state in Stop mode: Set PDDS and LPSDSR bit according to PWR_Regulator value */ MODIFY_REG(PWR->CR, (PWR_CR_PDDS | PWR_CR_LPSDSR), Regulator); /* Set SLEEPDEEP bit of Cortex System Control Register */ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); /* Select Stop mode entry --------------------------------------------------*/ if(STOPEntry == PWR_STOPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } /* Reset SLEEPDEEP bit of Cortex System Control Register */ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); }
/** * @brief Enters Stop mode. * @note In Stop mode, all I/O pins keep the same state as in Run mode. * @note When exiting Stop mode by using an interrupt or a wakeup event, * HSI RC oscillator is selected as system clock. * @note When the voltage regulator operates in low power mode, an additional * startup delay is incurred when waking up from Stop mode. * By keeping the internal regulator ON during Stop mode, the consumption * is higher although the startup time is reduced. * @param Regulator: Specifies the regulator state in Stop mode. * This parameter can be one of the following values: * @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON * @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON * @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction * @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction * @retval None */ void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) { /* Check the parameters */ assert_param(IS_PWR_REGULATOR(Regulator)); assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); /* Clear PDDS bit in PWR register to specify entering in STOP mode when CPU enter in Deepsleep */ CLEAR_BIT(PWR->CR, PWR_CR_PDDS); /* Select the voltage regulator mode by setting LPDS bit in PWR register according to Regulator parameter value */ MODIFY_REG(PWR->CR, PWR_CR_LPDS, Regulator); /* Set SLEEPDEEP bit of Cortex System Control Register */ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); /* Select Stop mode entry --------------------------------------------------*/ if(STOPEntry == PWR_STOPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); PWR_OverloadWfe(); /* WFE redefine locally */ PWR_OverloadWfe(); /* WFE redefine locally */ } /* Reset SLEEPDEEP bit of Cortex System Control Register */ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); }
/** * @brief Enter the system to STOP mode. * @note In System Stop mode, all I/O pins keep the same state as in Run mode. * @note When exiting System Stop mode by issuing an interrupt or a wakeup event, * the HSI RC oscillator is selected as default system wakeup clock. * @note In System STOP mode, when the voltage regulator operates in low power mode, * an additional startup delay is incurred when the system is waking up. * By keeping the internal regulator ON during Stop mode, the consumption * is higher although the startup time is reduced. * @param Regulator: Specifies the regulator state in Stop mode. * This parameter can be one of the following values: * @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON * @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON * @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction * @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction * @retval None */ void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_PWR_REGULATOR(Regulator)); assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); /* Select the regulator state in Stop mode */ tmpreg = PWR->CR1; /* Clear PDDS and LPDS bits */ tmpreg &= (uint32_t)~(PWR_CR1_LPDS); /* Set LPDS bit according to Regulator value */ tmpreg |= Regulator; /* Store the new value */ PWR->CR1 = tmpreg; /* Keep DSTOP mode when D1 domain enters Deepsleep */ CLEAR_BIT(PWR->CPUCR, PWR_CPUCR_PDDS_D1); /* Keep DSTOP mode when D2 domain enters Deepsleep */ CLEAR_BIT(PWR->CPUCR, PWR_CPUCR_PDDS_D2); /* Keep DSTOP mode when D3 domain enters Deepsleep */ CLEAR_BIT(PWR->CPUCR, PWR_CPUCR_PDDS_D3); /* Set SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Ensure that all instructions done before entering STOP mode */ __DSB(); __ISB(); /* Select Stop mode entry */ if(STOPEntry == PWR_STOPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); }
/** * @brief Enters STOP mode. * @param PWR_Regulator: specifies the regulator state in STOP mode. * This parameter can be one of the following values: * @arg PWR_Regulator_ON: STOP mode with regulator ON * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction * @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction * @retval None */ void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) { #ifdef OS_UCOS OS_CPU_SR cpu_sr; #endif uint32_t tmpreg = 0; #ifdef OS_UCOS OS_ENTER_CRITICAL(); #endif /* Check the parameters */ assert_param(IS_PWR_REGULATOR(PWR_Regulator)); assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); /* Select the regulator state in STOP mode ---------------------------------*/ tmpreg = PWR->CR; /* Clear PDDS and LPDS bits */ tmpreg &= CR_DS_MASK; /* Set LPDS bit according to PWR_Regulator value */ tmpreg |= PWR_Regulator; /* Store the new value */ PWR->CR = tmpreg; /* Set SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR |= SCB_SCR_SLEEPDEEP; /* Select STOP mode entry --------------------------------------------------*/ if(PWR_STOPEntry == PWR_STOPEntry_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __WFE(); } /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); #ifdef OS_UCOS OS_EXIT_CRITICAL(); #endif }
/** * @brief Enters STOP mode. * @note In Stop mode, all I/O pins keep the same state as in Run mode. * @note When exiting Stop mode by issuing an interrupt or a wakeup event, * the HSI RC oscillator is selected as system clock. * @note When the voltage regulator operates in low power mode, an additional * startup delay is incurred when waking up from Stop mode. * By keeping the internal regulator ON during Stop mode, the consumption * is higher although the startup time is reduced. * @param PWR_Regulator: specifies the regulator state in STOP mode. * This parameter can be one of the following values: * @arg PWR_Regulator_ON: STOP mode with regulator ON * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction * @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction @arg PWR_STOPEntry_SLEEPONEXIT: enter STOP mode with SLEEPONEXIT instruction * @retval None */ void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_PWR_REGULATOR(PWR_Regulator)); assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); /* Select the regulator state in STOP mode ---------------------------------*/ tmpreg = PWR->CR; /* Clear PDDS and LPDSR bits */ tmpreg &= CR_DS_MASK; /* Set LPDSR bit according to PWR_Regulator value */ tmpreg |= PWR_Regulator; /* Store the new value */ PWR->CR = tmpreg; /* Set SLEEPDEEP bit of Cortex-M0 System Control Register */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Select STOP mode entry --------------------------------------------------*/ if(PWR_STOPEntry == PWR_STOPEntry_WFI) { /* Request Wait For Interrupt */ __WFI(); /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); } else if (PWR_STOPEntry == PWR_STOPEntry_WFE) { /* Request Wait For Event */ __WFE(); /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); } else { /* Set SLEEP on exit bit of Cortex-M0 System Control Register */ SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; } }
/** * @brief Enters STOP mode. * @note In Stop mode, all I/O pins keep the same state as in Run mode. * @note When exiting Stop mode by issuing an interrupt or a wakeup event, * the HSI RC oscillator is selected as system clock. * @note When the voltage regulator operates in low power mode, an additional * startup delay is incurred when waking up from Stop mode. * By keeping the internal regulator ON during Stop mode, the consumption * is higher although the startup time is reduced. * @param Regulator: Specifies the regulator state in STOP mode. * This parameter can be one of the following values: * @arg PWR_MAINREGULATOR_ON: STOP mode with regulator ON * @arg PWR_LOWPOWERREGULATOR_ON: STOP mode with low power regulator ON * @param STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. * This parameter can be one of the following values: * @arg PWR_STOPENTRY_WFI:Enter STOP mode with WFI instruction * @arg PWR_STOPENTRY_WFE: Enter STOP mode with WFE instruction * @retval None */ void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_PWR_REGULATOR(Regulator)); assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); /* Select the regulator state in STOP mode ---------------------------------*/ tmpreg = PWR->CR; /* Clear PDDS and LPDS bits */ tmpreg &= (uint32_t)~(PWR_CR_PDDS | PWR_CR_LPDS); /* Set LPDS bit according to Regulator value */ tmpreg |= Regulator; /* Store the new value */ PWR->CR = tmpreg; /* Set SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Select STOP mode entry --------------------------------------------------*/ if(STOPEntry == PWR_STOPENTRY_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); }