334 lines
10 KiB
C
334 lines
10 KiB
C
|
/**
|
||
|
******************************************************************************
|
||
|
* @brief PWR functions of the firmware library.
|
||
|
******************************************************************************
|
||
|
*/
|
||
|
|
||
|
/* Includes ------------------------------------------------------------------*/
|
||
|
#include "gd32f10x_pwr.h"
|
||
|
#include "gd32f10x_rcc.h"
|
||
|
|
||
|
/** @addtogroup GD32F10x_Firmware
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/** @defgroup PWR
|
||
|
* @brief PWR driver modules
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/** @defgroup PWR_Private_Defines
|
||
|
* @{
|
||
|
*/
|
||
|
/* Left shift SBF or WUF(PWR_STR) to SBFR or WUFR(PWR_CTLR) */
|
||
|
#define BIT_SHIFT 2
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/** @defgroup PWR_Private_Functions
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @brief Reset the PWR peripheral registers.
|
||
|
* @param None
|
||
|
* @retval None
|
||
|
*/
|
||
|
void PWR_DeInit(void)
|
||
|
{
|
||
|
RCC_APB1PeriphReset_Enable(RCC_APB1PERIPH_PWRRST, ENABLE);
|
||
|
RCC_APB1PeriphReset_Enable(RCC_APB1PERIPH_PWRRST, DISABLE);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Enable or disable write access to the registers in Backup domain.
|
||
|
* @note After reset, any write access to the registers in Backup domain is disabled.
|
||
|
* This bit has to be set to enable write access to these registers.
|
||
|
* @param NewValue: New value of write access state to the registers in Backup domain.
|
||
|
* This parameter can be: ENABLE or DISABLE.
|
||
|
* @retval None
|
||
|
*/
|
||
|
void PWR_BackupAccess_Enable(TypeState NewValue)
|
||
|
{
|
||
|
if (NewValue != DISABLE) {
|
||
|
/* Enable the Backup Domain Access */
|
||
|
PWR->CTLR |= PWR_CTLR_BKPWE;
|
||
|
} else {
|
||
|
/* Disable the Backup Domain Access */
|
||
|
PWR->CTLR &= ~((uint32_t)PWR_CTLR_BKPWE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Enable or disable the LVD(Low Voltage Detector), and configure the voltage
|
||
|
* threshold detected by the LVD.
|
||
|
* @note The LVDE bit controls whether LVD is enabled or not, while the LVDT[2:0]
|
||
|
* bits select the LVDT from 2.2V to 2.9V.
|
||
|
* @note The LVD is stopped in Standby mode.
|
||
|
* @param PWR_LVDT: the LVD threshold.
|
||
|
* This parameter can be one of the following values:
|
||
|
* @arg PWR_LVDT_0
|
||
|
* @arg PWR_LVDT_1
|
||
|
* @arg PWR_LVDT_2
|
||
|
* @arg PWR_LVDT_3
|
||
|
* @arg PWR_LVDT_4
|
||
|
* @arg PWR_LVDT_5
|
||
|
* @arg PWR_LVDT_6
|
||
|
* @arg PWR_LVDT_7
|
||
|
* @param NewValue: New value of the LVD state.
|
||
|
* This parameter can be: ENABLE or DISABLE.
|
||
|
* @retval None
|
||
|
*/
|
||
|
void PWR_LVDConfig(uint32_t PWR_LVDT, TypeState NewValue)
|
||
|
{
|
||
|
uint32_t temp = 0;
|
||
|
|
||
|
temp = PWR->CTLR;
|
||
|
|
||
|
/* Clear LVDT[7:5] bits */
|
||
|
temp &= ~((uint32_t)PWR_CTLR_LVDT);
|
||
|
|
||
|
/* Set LVDT[7:5] bits according to PWR_LVDT value */
|
||
|
temp |= PWR_LVDT;
|
||
|
|
||
|
/* Store the new value */
|
||
|
PWR->CTLR = temp;
|
||
|
|
||
|
/* Enable or disable the LVD */
|
||
|
if (NewValue != DISABLE) {
|
||
|
/* Enable the LVD */
|
||
|
PWR->CTLR |= PWR_CTLR_LVDE;
|
||
|
} else {
|
||
|
/* Disable the LVD */
|
||
|
PWR->CTLR &= ~((uint32_t)PWR_CTLR_LVDE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Enable or disable the WakeUp Pin(PA0 pin) function.
|
||
|
* @note If WUPE is set before entering the power saving mode,
|
||
|
* a rising edge on the WKUP Pin wakes up the system from the power
|
||
|
* saving mode. As the WKUP pin is active high, it will setup
|
||
|
* an input pull down mode when this bit is high.
|
||
|
* @param NewValue: New value of the WKUP Pin state.
|
||
|
* This parameter can be: ENABLE or DISABLE.
|
||
|
* @retval None
|
||
|
*/
|
||
|
void PWR_WKUP_Pin_Enable(TypeState NewValue)
|
||
|
{
|
||
|
if (NewValue != DISABLE) {
|
||
|
/* Enable the WKUP pin */
|
||
|
PWR->STR |= PWR_STR_WUPE;
|
||
|
} else {
|
||
|
/* Disable the WKUP pin */
|
||
|
PWR->STR &= ~PWR_STR_WUPE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*@verbatim
|
||
|
|
||
|
[..] The GD32F10x series of devices provide three types of power saving modes.
|
||
|
|
||
|
*** Sleep mode ***
|
||
|
==================
|
||
|
[..] The Sleep mode is based on the SLEEPING mode of the Cortex-M3. In Sleep
|
||
|
mode, only clock of Cortex-M3 is off.
|
||
|
(+) Entry:
|
||
|
(++) To enter the Sleep mode, it is only necessary to clear SLEEPDEEP bit
|
||
|
in the Cortex-M3 System Control Register, and execute a WFI or WFE
|
||
|
instruction.
|
||
|
(++) The Sleep mode is entered using the PWR_SLEEPMode_Entry() function.
|
||
|
(+) Wakeup:
|
||
|
(++) Any interrupt for WFI or Any event for WFE.
|
||
|
(+) Wakeup Latency:
|
||
|
(++) None
|
||
|
|
||
|
*** Deep-sleep mode ***
|
||
|
=================
|
||
|
[..] The Deep-sleep mode is based on the SLEEPDEEP mode of the Cortex-M3. In
|
||
|
Deep-sleep mode, all clocks in the 1.2V domain are off, and all of HSI,
|
||
|
HSE and PLL are disabled. The LDO can operate normally or in low
|
||
|
power mode depending on the LDOLP bit in the PWR_CTLR register.
|
||
|
(+) Entry:
|
||
|
(++) Before entering the Deep-sleep mode, it is necessary to set the
|
||
|
SLEEPDEEP bit in the Cortex-M3 System Control Register, and clear
|
||
|
the SDBM bit in the PWR_CTLR register.
|
||
|
(++) The Deep-sleep mode is entered using the PWR_DEEPSLEEPMode_Entry()
|
||
|
function.
|
||
|
(+) Wakeup:
|
||
|
(++) Any interrupt or event from EXTI Lines.
|
||
|
(+) Wakeup Latency:
|
||
|
(++) HSI wakeup time; LDO wakeup time if LDO is in low power mode.
|
||
|
|
||
|
*** Standby mode ***
|
||
|
====================
|
||
|
[..] The Standby mode is based on the SLEEPDEEP mode of the Cortex-M3. In Standby
|
||
|
mode, the whole 1.2V domain is power off, the LDO is shut down, and all of
|
||
|
HSI, HSE and PLL are disabled. Besides, the contents of SRAM and
|
||
|
registers(except Backup Registers) are lost in Standby mode.
|
||
|
(+) Entry:
|
||
|
(++) Before entering the Standby mode, it is necessary to set the
|
||
|
SLEEPDEEP bit in the Cortex-M3 System Control Register, and set
|
||
|
the SDBM bit in the PWR_CTLR register, and clear WUF bit in the
|
||
|
PWR_STR register. .
|
||
|
(++) The Standby mode is entered using the PWR_STDBYMode_Entry() function.
|
||
|
(+) Wakeup:
|
||
|
(++) NRST pin, WKUP pin rising edge, RTC alarm, IWDG reset.
|
||
|
(+) Wakeup Latency:
|
||
|
(++) Power on sequence
|
||
|
*@endverbatim
|
||
|
*/
|
||
|
/**
|
||
|
* @brief Enter Sleep mode.
|
||
|
* @note By default, this function selects the Sleep-now entry mechanism (SLEEPONEXIT = 0).
|
||
|
* @param PWR_SLEEPENTRY: WFI or WFE instruction.
|
||
|
* This parameter can be one of the following values:
|
||
|
* @arg PWR_SLEEPENTRY_WFI: enter Sleep mode with WFI instruction
|
||
|
* @arg PWR_SLEEPENTRY_WFE: enter Sleep mode with WFE instruction
|
||
|
* @retval None
|
||
|
*/
|
||
|
void PWR_SLEEPMode_Entry(uint8_t PWR_SLEEPENTRY)
|
||
|
{
|
||
|
/* Clear SLEEPDEEP bit of Cortex-M3 System Control Register */
|
||
|
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
|
||
|
|
||
|
/* Select WFI or WFE to enter Sleep mode */
|
||
|
if (PWR_SLEEPENTRY == PWR_SLEEPENTRY_WFI) {
|
||
|
__WFI();
|
||
|
} else {
|
||
|
__WFE();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Enter Deep-sleep mode.
|
||
|
* @note When exiting Deep-sleep mode, the HSI is selected as the system clock.
|
||
|
* @note An additional wakeup delay will be incurred if the LDO operates in
|
||
|
* low power mode.
|
||
|
* @param PWR_LDO: the LDO state in Deep-sleep mode.
|
||
|
* This parameter can be one of the following values:
|
||
|
* @arg PWR_LDO_ON: Deep-sleep mode with LDO ON
|
||
|
* @arg PWR_LDO_LOWPOWER: Deep-sleep mode with LDO in low power mode
|
||
|
* @param PWR_DEEPSLEEPENTRY: WFI or WFE instruction.
|
||
|
* This parameter can be one of the following values:
|
||
|
* @arg PWR_DEEPSLEEPENTRY_WFI: enter Deep-sleep mode with WFI instruction
|
||
|
* @arg PWR_DEEPSLEEPENTRY_WFE: enter Deep-sleep mode with WFE instruction
|
||
|
* @retval None
|
||
|
*/
|
||
|
void PWR_DEEPSLEEPMode_Entry(uint32_t PWR_LDO, uint8_t PWR_DEEPSLEEPENTRY)
|
||
|
{
|
||
|
uint32_t temp = 0;
|
||
|
|
||
|
/* Select the LDO state in Deep-sleep mode */
|
||
|
temp = PWR->CTLR;
|
||
|
|
||
|
/* Clear SDBM and LDOLP bits, and select Deep-sleep mode */
|
||
|
temp &= ~((uint32_t)(PWR_CTLR_SDBM | PWR_CTLR_LDOLP));
|
||
|
|
||
|
/* Set LDOLP bit according to PWR_LDO value, and select the LDO's state */
|
||
|
temp |= PWR_LDO;
|
||
|
|
||
|
/* Store the new value */
|
||
|
PWR->CTLR = temp;
|
||
|
|
||
|
/* Set SLEEPDEEP bit of Cortex-M3 System Control Register */
|
||
|
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||
|
|
||
|
/* Select WFI or WFE to enter Deep-sleep mode */
|
||
|
if (PWR_DEEPSLEEPENTRY == PWR_DEEPSLEEPENTRY_WFI) {
|
||
|
__WFI();
|
||
|
} else {
|
||
|
__SEV();
|
||
|
__WFE();
|
||
|
__WFE();
|
||
|
}
|
||
|
/* Reset SLEEPDEEP bit of Cortex-M3 System Control Register */
|
||
|
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Enter Standby mode.
|
||
|
* @note The Standby mode achieves the lowest power consumption, but spends
|
||
|
* longest time to wake up.
|
||
|
* @note When exiting from the Standby mode, a power-on reset occurs and the
|
||
|
* Cortex-M3 will execute instructions code from the 0x0000_0000 address.
|
||
|
* @param PWR_STDBYENTRY: WFI or WFE instruction.
|
||
|
* This parameter can be one of the following values:
|
||
|
* @arg PWR_STDBYENTRY_WFI: enter Standby mode with WFI instruction
|
||
|
* @arg PWR_STDBYENTRY_WFE: enter Standby mode with WFE instruction
|
||
|
* @retval None
|
||
|
*/
|
||
|
void PWR_STDBYMode_Entry(uint8_t PWR_STDBYENTRY)
|
||
|
{
|
||
|
/* Set SLEEPDEEP bit of Cortex-M3 System Control Register */
|
||
|
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||
|
|
||
|
/* Set SDBM bit, and select Standby mode */
|
||
|
PWR->CTLR |= PWR_CTLR_SDBM;
|
||
|
|
||
|
/* Reset Wakeup flag */
|
||
|
PWR->CTLR |= PWR_CTLR_WUFR;
|
||
|
|
||
|
/* Select WFI or WFE to enter Standby mode */
|
||
|
if (PWR_STDBYENTRY == PWR_STDBYENTRY_WFI) {
|
||
|
__WFI();
|
||
|
} else {
|
||
|
__WFE();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Get the bit flag of some PWR_STR registers.
|
||
|
* @param PWR_FLAG: the flag of PWR_STR registers.
|
||
|
* This parameter can be one of the following values:
|
||
|
* @arg PWR_FLAG_WKUP: WakeUp flag. This flag indicates that a wakeup
|
||
|
* event was received from the WKUP pin or from the RTC alarm,
|
||
|
* IWDG reset or NRST pin.
|
||
|
* @arg PWR_FLAG_STB: StandBy flag. This flag indicates that the
|
||
|
* system has been in Standby mode.
|
||
|
* @arg PWR_FLAG_LVDF: LVD State flag. This flag is valid only if LVD
|
||
|
* is enabled by the PWR_LVD_Config()function.
|
||
|
* @retval The new value of PWR_FLAG (SET or RESET).
|
||
|
*/
|
||
|
TypeState PWR_GetBitState(uint32_t PWR_FLAG)
|
||
|
{
|
||
|
/* Check and get the selected PWR flag */
|
||
|
if ((PWR->STR & PWR_FLAG) != (uint32_t)RESET) {
|
||
|
/* PWR_FLAG bit is SET */
|
||
|
return SET;
|
||
|
} else {
|
||
|
/* PWR_FLAG bit is RESET */
|
||
|
return RESET;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Clear the bit flag of some PWR_STR registers.
|
||
|
* @param PWR_FLAG: the flag of PWR_STR registers.
|
||
|
* This parameter can be one of the following values:
|
||
|
* @arg PWR_FLAG_WKUP: Wake_Up flag
|
||
|
* @arg PWR_FLAG_STB: StandBy flag
|
||
|
* @retval None
|
||
|
*/
|
||
|
void PWR_ClearBitState(uint32_t PWR_FLAG)
|
||
|
{
|
||
|
/* Clear the selected PWR flag */
|
||
|
PWR->CTLR |= PWR_FLAG << BIT_SHIFT;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|