392 lines
11 KiB
C
Raw Normal View History

2022-03-26 20:51:40 +08:00
/********************************** (C) COPYRIGHT *******************************
* File Name : CH58x_pwr.c
* Author : WCH
* Version : V1.2
* Date : 2021/11/17
* Description
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "CH58x_common.h"
/*********************************************************************
* @fn PWR_DCDCCfg
*
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>DC/DC<EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڽ<EFBFBD>Լϵͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param s - <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DCDC<EFBFBD><EFBFBD>Դ
*
* @return none
*/
void PWR_DCDCCfg(FunctionalState s)
{
if(s == DISABLE)
{
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R16_AUX_POWER_ADJ &= ~RB_DCDC_CHARGE;
R16_POWER_PLAN &= ~(RB_PWR_DCDC_EN | RB_PWR_DCDC_PRE); // <20><>· DC/DC
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG0;
}
else
{
__nop();
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R16_AUX_POWER_ADJ |= RB_DCDC_CHARGE;
R16_POWER_PLAN |= RB_PWR_DCDC_PRE;
DelayUs(10);
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R16_POWER_PLAN |= RB_PWR_DCDC_EN;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG0;
}
}
/*********************************************************************
* @fn PWR_UnitModCfg
*
* @brief <EFBFBD>ɿص<EFBFBD>Ԫģ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param s - <EFBFBD>Ƿ<EFBFBD><EFBFBD>򿪵<EFBFBD>Դ
* @param unit - please refer to unit of controllable power supply
*
* @return none
*/
void PWR_UnitModCfg(FunctionalState s, uint8_t unit)
{
if(s == DISABLE) //<2F>ر<EFBFBD>
{
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_HFCK_PWR_CTRL &= ~(unit & 0x1c);
R8_CK32K_CONFIG &= ~(unit & 0x03);
}
else //<2F><><EFBFBD><EFBFBD>
{
__nop();
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_HFCK_PWR_CTRL |= (unit & 0x1c);
R8_CK32K_CONFIG |= (unit & 0x03);
}
R8_SAFE_ACCESS_SIG = 0;
}
/*********************************************************************
* @fn PWR_PeriphClkCfg
*
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ӿ<EFBFBD><EFBFBD><EFBFBD>λ
*
* @param s - <EFBFBD>Ƿ<EFBFBD><EFBFBD>򿪶<EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
* @param perph - please refer to Peripher CLK control bit define
*
* @return none
*/
void PWR_PeriphClkCfg(FunctionalState s, uint16_t perph)
{
if(s == DISABLE)
{
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R32_SLEEP_CONTROL |= perph;
}
else
{
__nop();
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R32_SLEEP_CONTROL &= ~perph;
}
R8_SAFE_ACCESS_SIG = 0;
}
/*********************************************************************
* @fn PWR_PeriphWakeUpCfg
*
* @brief ˯<EFBFBD>߻<EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param s - <EFBFBD>Ƿ<EFBFBD><EFBFBD>򿪴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˯<EFBFBD>߻<EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD>
* @param perph - <EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>õĻ<EFBFBD><EFBFBD><EFBFBD>Դ
* RB_SLP_USB_WAKE - USB Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
* RB_SLP_RTC_WAKE - RTC Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
* RB_SLP_GPIO_WAKE - GPIO Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
* RB_SLP_BAT_WAKE - BAT Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
* @param mode - refer to WakeUP_ModeypeDef
*
* @return none
*/
void PWR_PeriphWakeUpCfg(FunctionalState s, uint8_t perph, WakeUP_ModeypeDef mode)
{
uint8_t m;
if(s == DISABLE)
{
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_SLP_WAKE_CTRL &= ~perph;
}
else
{
switch(mode)
{
case Short_Delay:
m = 0x01;
break;
case Long_Delay:
m = 0x00;
break;
default:
m = 0x01;
break;
}
__nop();
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_SLP_WAKE_CTRL |= RB_WAKE_EV_MODE | perph;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_SLP_POWER_CTRL &= ~(RB_WAKE_DLY_MOD);
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_SLP_POWER_CTRL |= m;
}
R8_SAFE_ACCESS_SIG = 0;
}
/*********************************************************************
* @fn PowerMonitor
*
* @brief <EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param s - <EFBFBD>Ƿ<EFBFBD><EFBFBD>򿪴˹<EFBFBD><EFBFBD><EFBFBD>
* @param vl - refer to VolM_LevelypeDef
*
* @return none
*/
void PowerMonitor(FunctionalState s, VolM_LevelypeDef vl)
{
if(s == DISABLE)
{
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_BAT_DET_CTRL = 0;
R8_SAFE_ACCESS_SIG = 0;
}
else
{
if(vl & 0x80)
{
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_BAT_DET_CFG = vl & 0x03;
R8_BAT_DET_CTRL = RB_BAT_MON_EN | ((vl >> 2) & 1);
}
else
{
__nop();
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_BAT_DET_CFG = vl & 0x03;
R8_BAT_DET_CTRL = RB_BAT_DET_EN;
}
R8_SAFE_ACCESS_SIG = 0;
mDelayuS(1);
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_BAT_DET_CTRL |= RB_BAT_LOW_IE | RB_BAT_LOWER_IE;
R8_SAFE_ACCESS_SIG = 0;
}
}
/*********************************************************************
* @fn LowPower_Idle
*
* @brief <EFBFBD>͹<EFBFBD><EFBFBD><EFBFBD>-Idleģʽ
*
* @param none
*
* @return none
*/
__HIGH_CODE
void LowPower_Idle(void)
{
FLASH_ROM_SW_RESET();
R8_FLASH_CTRL = 0x04; //flash<73>ر<EFBFBD>
PFIC->SCTLR &= ~(1 << 2); // sleep
__WFI();
__nop();
__nop();
}
/*********************************************************************
* @fn LowPower_Halt
*
* @brief <EFBFBD>͹<EFBFBD><EFBFBD><EFBFBD>-Haltģʽ<EFBFBD><EFBFBD><EFBFBD>˵͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>HSI/5ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѻ<EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>û<EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>ϵͳʱ<EFBFBD><EFBFBD>Դ
*
* @param none
*
* @return none
*/
__HIGH_CODE
void LowPower_Halt(void)
{
uint8_t x32Kpw, x32Mpw;
FLASH_ROM_SW_RESET();
R8_FLASH_CTRL = 0x04; //flash<73>ر<EFBFBD>
x32Kpw = R8_XT32K_TUNE;
x32Mpw = R8_XT32M_TUNE;
x32Mpw = (x32Mpw & 0xfc) | 0x03; // 150%<25><EFBFBD><EEB6A8><EFBFBD><EFBFBD>
if(R16_RTC_CNT_32K > 0x3fff)
{ // <20><><EFBFBD><EFBFBD>500ms
x32Kpw = (x32Kpw & 0xfc) | 0x01; // LSE<53><45><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EEB6A8><EFBFBD><EFBFBD>
}
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_BAT_DET_CTRL = 0; // <20>رյ<D8B1>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>
R8_XT32K_TUNE = x32Kpw;
R8_XT32M_TUNE = x32Mpw;
R8_PLL_CONFIG |= (1 << 5);
R8_SAFE_ACCESS_SIG = 0;
PFIC->SCTLR |= (1 << 2); //deep sleep
__WFI();
__nop();
__nop();
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_PLL_CONFIG &= ~(1 << 5);
R8_SAFE_ACCESS_SIG = 0;
}
/*******************************************************************************
* Function Name : LowPower_Sleep
* Description : <EFBFBD>͹<EFBFBD><EFBFBD><EFBFBD>-Sleepģʽ<EFBFBD><EFBFBD>
ע<EFBFBD><EFBFBD><EFBFBD>ƵΪ80<EFBFBD><EFBFBD>˯<EFBFBD>߻<EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϲ<EFBFBD><EFBFBD>ɵ<EFBFBD><EFBFBD><EFBFBD>flash<EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD>˺<EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>30us<EFBFBD>ӳ١<EFBFBD>
* Input : rm:
RB_PWR_RAM2K - 2K retention SRAM <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
RB_PWR_RAM30K - 30K main SRAM <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
RB_PWR_EXTEND - USB <EFBFBD><EFBFBD> BLE <EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򹩵<EFBFBD>
RB_PWR_XROM - FlashROM <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
NULL - <EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>
* Return : None
*******************************************************************************/
__HIGH_CODE
void LowPower_Sleep(uint8_t rm)
{
uint8_t x32Kpw, x32Mpw;
uint16_t DCDCState;
x32Kpw = R8_XT32K_TUNE;
x32Mpw = R8_XT32M_TUNE;
x32Mpw = (x32Mpw & 0xfc) | 0x03; // 150%<25><EFBFBD><EEB6A8><EFBFBD><EFBFBD>
if(R16_RTC_CNT_32K > 0x3fff)
{ // <20><><EFBFBD><EFBFBD>500ms
x32Kpw = (x32Kpw & 0xfc) | 0x01; // LSE<53><45><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EEB6A8><EFBFBD><EFBFBD>
}
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_BAT_DET_CTRL = 0; // <20>رյ<D8B1>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>
R8_XT32K_TUNE = x32Kpw;
R8_XT32M_TUNE = x32Mpw;
R8_SAFE_ACCESS_SIG = 0;
PFIC->SCTLR |= (1 << 2); //deep sleep
DCDCState = R16_POWER_PLAN & (RB_PWR_DCDC_EN | RB_PWR_DCDC_PRE);
DCDCState |= RB_PWR_PLAN_EN | RB_PWR_MUST_0010 | RB_PWR_CORE | rm;
__nop();
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_SLP_POWER_CTRL |= RB_RAM_RET_LV;
R8_PLL_CONFIG |= (1 << 5);
R16_POWER_PLAN = DCDCState;
__WFI();
__nop();
__nop();
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_PLL_CONFIG &= ~(1 << 5);
R8_SAFE_ACCESS_SIG = 0;
}
/*********************************************************************
* @fn LowPower_Shutdown
*
* @brief <EFBFBD>͹<EFBFBD><EFBFBD><EFBFBD>-Shutdownģʽ<EFBFBD><EFBFBD><EFBFBD>˵͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>HSI/5ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѻ<EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>û<EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>ϵͳʱ<EFBFBD><EFBFBD>Դ
* @note ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô˺<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DCDC<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>ƹرգ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD>ٴδ<EFBFBD><EFBFBD><EFBFBD>
*
* @param rm - <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD>
* RB_PWR_RAM2K - 2K retention SRAM <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* RB_PWR_RAM16K - 16K main SRAM <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* NULL - <EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>
*
* @return none
*/
__HIGH_CODE
void LowPower_Shutdown(uint8_t rm)
{
uint8_t x32Kpw, x32Mpw;
FLASH_ROM_SW_RESET();
x32Kpw = R8_XT32K_TUNE;
x32Mpw = R8_XT32M_TUNE;
x32Mpw = (x32Mpw & 0xfc) | 0x03; // 150%<25><EFBFBD><EEB6A8><EFBFBD><EFBFBD>
if(R16_RTC_CNT_32K > 0x3fff)
{ // <20><><EFBFBD><EFBFBD>500ms
x32Kpw = (x32Kpw & 0xfc) | 0x01; // LSE<53><45><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EEB6A8><EFBFBD><EFBFBD>
}
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_BAT_DET_CTRL = 0; // <20>رյ<D8B1>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>
R8_XT32K_TUNE = x32Kpw;
R8_XT32M_TUNE = x32Mpw;
R8_SAFE_ACCESS_SIG = 0;
SetSysClock(CLK_SOURCE_HSE_6_4MHz);
PFIC->SCTLR |= (1 << 2); //deep sleep
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_SLP_POWER_CTRL |= RB_RAM_RET_LV;
R16_POWER_PLAN = RB_PWR_PLAN_EN | RB_PWR_MUST_0010 | rm;
__WFI();
__nop();
__nop();
FLASH_ROM_SW_RESET();
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1;
R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2;
SAFEOPERATE;
R8_RST_WDOG_CTRL |= RB_SOFTWARE_RESET;
R8_SAFE_ACCESS_SIG = 0;
}