2022-03-26 20:51:40 +08:00

392 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********************************** (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 <20><><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>DC/DC<44><43>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD>ڽ<EFBFBD>Լϵͳ<CFB5><CDB3><EFBFBD><EFBFBD>
*
* @param s - <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>DCDC<44><43>Դ
*
* @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 <20>ɿص<C9BF>Ԫģ<D4AA><C4A3><EFBFBD>ĵ<EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>
*
* @param s - <20>Ƿ<EFBFBD><C7B7>򿪵<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 <20><><EFBFBD><EFBFBD>ʱ<EFBFBD>ӿ<EFBFBD><D3BF><EFBFBD>λ
*
* @param s - <20>Ƿ<EFBFBD><C7B7>򿪶<EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
* @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><DFBB><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>
*
* @param s - <20>Ƿ<EFBFBD><C7B7>򿪴<EFBFBD><F2BFAAB4><EFBFBD><EFBFBD><EFBFBD>˯<EFBFBD>߻<EFBFBD><DFBB>ѹ<EFBFBD><D1B9><EFBFBD>
* @param perph - <20><>Ҫ<EFBFBD><D2AA><EFBFBD>õĻ<C3B5><C4BB><EFBFBD>Դ
* RB_SLP_USB_WAKE - USB Ϊ<><CEAA><EFBFBD><EFBFBD>Դ
* RB_SLP_RTC_WAKE - RTC Ϊ<><CEAA><EFBFBD><EFBFBD>Դ
* RB_SLP_GPIO_WAKE - GPIO Ϊ<><CEAA><EFBFBD><EFBFBD>Դ
* RB_SLP_BAT_WAKE - BAT Ϊ<><CEAA><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 <20><>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>
*
* @param s - <20>Ƿ<EFBFBD><C7B7>򿪴˹<F2BFAAB4><CBB9><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 <20>͹<EFBFBD><CDB9><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 <20>͹<EFBFBD><CDB9><EFBFBD>-Haltģʽ<C4A3><CABD><EFBFBD>˵͹<CBB5><CDB9><EFBFBD><EFBFBD>е<EFBFBD>HSI/5ʱ<35><CAB1><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD>Ѻ<EFBFBD><D1BA><EFBFBD>Ҫ<EFBFBD>û<EFBFBD><C3BB>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>ϵͳʱ<CDB3><CAB1>Դ
*
* @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 : <20>͹<EFBFBD><CDB9><EFBFBD>-Sleepģʽ<C4A3><CABD>
ע<><EFBFBD><E2B5B1>ƵΪ80Mʱ<4D><CAB1>˯<EFBFBD>߻<EFBFBD><DFBB><EFBFBD><EFBFBD>жϲ<D0B6><CFB2>ɵ<EFBFBD><C9B5><EFBFBD>flash<73>ڴ<EFBFBD><DAB4><EFBFBD><EBA3AC><EFBFBD>˳<EFBFBD><CBB3>˺<EFBFBD><CBBA><EFBFBD>ǰ<EFBFBD><C7B0>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>30us<75>ӳ١<D3B3>
* Input : rm:
RB_PWR_RAM2K - 2K retention SRAM <20><><EFBFBD><EFBFBD>
RB_PWR_RAM30K - 30K main SRAM <20><><EFBFBD><EFBFBD>
RB_PWR_EXTEND - USB <20><> BLE <20><>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򹩵<EFBFBD>
RB_PWR_XROM - FlashROM <20><><EFBFBD><EFBFBD>
NULL - <09><><EFBFBD>ϵ<EFBFBD>Ԫ<EFBFBD><D4AA><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 <20>͹<EFBFBD><CDB9><EFBFBD>-Shutdownģʽ<C4A3><CABD><EFBFBD>˵͹<CBB5><CDB9><EFBFBD><EFBFBD>е<EFBFBD>HSI/5ʱ<35><CAB1><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD>Ѻ<EFBFBD><D1BA><EFBFBD>Ҫ<EFBFBD>û<EFBFBD><C3BB>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>ϵͳʱ<CDB3><CAB1>Դ
* @note ע<><D7A2><EFBFBD><EFBFBD><EFBFBD>ô˺<C3B4><CBBA><EFBFBD><EFBFBD><EFBFBD>DCDC<44><43><EFBFBD><EFBFBD>ǿ<EFBFBD>ƹرգ<D8B1><D5A3><EFBFBD><EFBFBD>Ѻ<EFBFBD><D1BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><D6B6>ٴδ<D9B4><CEB4><EFBFBD>
*
* @param rm - <20><><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>ѡ<EFBFBD><D1A1>
* RB_PWR_RAM2K - 2K retention SRAM <20><><EFBFBD><EFBFBD>
* RB_PWR_RAM16K - 16K main SRAM <20><><EFBFBD><EFBFBD>
* NULL - <20><><EFBFBD>ϵ<EFBFBD>Ԫ<EFBFBD><D4AA><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;
}