BLE_DCF_TYQ_CH592F/HAL/SLEEP.c

318 lines
7.5 KiB
C
Raw Permalink 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 : SLEEP.c
* Author : WCH
* Version : V1.2
* Date : 2022/01/18
* Description : 睡眠配置及其初始化
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/******************************************************************************/
/* 头文件包含 */
#include "HAL.h"
#include "bsp_key.h"
#include "log.h"
#include "bsp_uart.h"
#include "bsp_beep_led_emv.h"
#undef LOG_ENABLE
#define LOG_ENABLE 1
#undef LOG_TAG
#define LOG_TAG "sleep"
static volatile bool block_sleep_flag = false;
static volatile bool block_boost_flag = false;
static uint32_t block_sleep = 0;
#define DEEP_SLEEP_VALUE 0
#define IDLE_SLEEP_VALUE 1
#define BLOCK_SLEEP_VALUE 0x80000000
__HIGH_CODE
void BSP_RequestSleep(void)
{
block_sleep_flag = false;
block_sleep = DEEP_SLEEP_VALUE;
}
__HIGH_CODE
void BSP_BlockSleep(void)
{
block_sleep_flag = true;
block_sleep = BLOCK_SLEEP_VALUE;
}
__HIGH_CODE
void BSP_RequestBoost(void)
{
// LDect_Init();
BOOST_EN;
block_boost_flag = false;
}
__HIGH_CODE
void BSP_NoNeedBoost(void)
{
block_boost_flag = true;
// LDect_Deinit();
BOOST_OFF_DEINIT;
}
__HIGH_CODE
void LowPower_Idle_ext(void)
{
FLASH_ROM_SW_RESET();
// R8_FLASH_CTRL = 0x04; //flash关闭
// PFIC->SCTLR &= ~(1 << 2); // sleep
__WFE();
__nop();
__nop();
}
__HIGH_CODE
void LowPower_Sleep_ext(uint16_t rm)
{
uint8_t x32Mpw;
uint16_t power_plan;
uint16_t clk_sys_cfg;
uint16_t hfck_pwr_ctrl;
clk_sys_cfg = R16_CLK_SYS_CFG;
hfck_pwr_ctrl = R8_HFCK_PWR_CTRL;
x32Mpw = R8_XT32M_TUNE;
x32Mpw = (x32Mpw & 0xfc) | 0x03; // 150%额定电流
sys_safe_access_enable();
R8_BAT_DET_CTRL = 0; // 关闭电压监控
R8_XT32M_TUNE = x32Mpw;
R16_POWER_PLAN &= ~RB_XT_PRE_EN;
sys_safe_access_disable();
PFIC->SCTLR |= (1 << 2); // deep sleep
power_plan = R16_POWER_PLAN & (RB_PWR_DCDC_EN | RB_PWR_DCDC_PRE);
power_plan |= RB_PWR_PLAN_EN | RB_PWR_CORE | rm | (2 << 11);
sys_safe_access_enable();
if (rm & RB_XT_PRE_EN)
{
R8_SLP_POWER_CTRL |= 0x41;
}
else
{
R8_SLP_POWER_CTRL |= 0x40;
}
R16_POWER_PLAN = power_plan;
R8_HFCK_PWR_CTRL |= RB_CLK_RC16M_PON; // 睡眠需要打开内部HSI之后睡
sys_safe_access_disable();
if ((R16_CLK_SYS_CFG & RB_CLK_SYS_MOD) == 0x40)
{
sys_safe_access_enable();
R16_CLK_SYS_CFG = (R16_CLK_SYS_CFG & (~RB_CLK_PLL_DIV)) | 24;
sys_safe_access_disable();
}
// sys_safe_access_enable();
// R8_PLL_CONFIG |= (1 << 5);
// sys_safe_access_disable();
__WFE();
__nop();
__nop();
PFIC->SCTLR &= ~(1 << 2);
sys_safe_access_enable();
R16_CLK_SYS_CFG = clk_sys_cfg;
R8_HFCK_PWR_CTRL = hfck_pwr_ctrl;
sys_safe_access_disable();
sys_safe_access_enable();
R16_POWER_PLAN &= ~(RB_XT_PRE_EN | RB_PWR_PLAN_EN);
sys_safe_access_disable();
// sys_safe_access_enable();
// R8_PLL_CONFIG &= ~(1 << 5);
// sys_safe_access_disable();
DelayUs(40);
}
pfnLowPowerGapProcessCB_t LowPowerGapProcess;
/*******************************************************************************
* @fn CH58x_LowPower
*
* @brief 启动睡眠
*
* @param time - 唤醒的时间点RTC绝对值
*
* @return state.
*/
__HIGH_CODE
uint32_t CH58x_LowPower(uint32_t time)
{
#if 1
// BSP_UART1_TxLowPower();
if (block_boost_flag == false)
{
// LDect_Init();
// BOOST_EN;
}
else
{
// LDect_Deinit();
// BOOST_OFF_DEINIT;
}
if (true == block_sleep_flag)
{
// logDebug("block_sleep");
return 0;
}
#endif
// LDect_Deinit();
#if (defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
volatile uint32_t i;
uint32_t time_tign, time_sleep, time_curr;
unsigned long irq_status;
// 提前唤醒
if (time <= WAKE_UP_RTC_MAX_TIME)
{
time_tign = time + (RTC_MAX_COUNT - WAKE_UP_RTC_MAX_TIME);
}
else
{
time_tign = time - WAKE_UP_RTC_MAX_TIME;
}
// SYS_DisableAllIrq(&irq_status);
PFIC_DisableAllIRQ();
time_curr = RTC_GetCycle32k();
// 检测睡眠时间
if (time_tign < time_curr)
{
time_sleep = time_tign + (RTC_MAX_COUNT - time_curr);
}
else
{
time_sleep = time_tign - time_curr;
}
// 若睡眠时间小于最小睡眠时间或大于最大睡眠时间,则不睡眠
if ((time_sleep < SLEEP_RTC_MIN_TIME) ||
(time_sleep > SLEEP_RTC_MAX_TIME))
{
// SYS_RecoverIrq(irq_status);
PFIC_EnableAllIRQ();
return 2;
}
RTC_SetTignTime(time_tign);
// SYS_RecoverIrq(irq_status);
PFIC_EnableAllIRQ();
#if (DEBUG == Debug_UART0) // 使用其他串口输出打印信息需要修改这行代码
while ((R8_UART0_LSR & RB_LSR_TX_ALL_EMP) == 0)
{
__nop();
}
#elif (DEBUG == Debug_UART1) // 使用其他串口输出打印信息需要修改这行代码
while ((R8_UART1_LSR & RB_LSR_TX_ALL_EMP) == 0)
{
__nop();
}
#endif
// BSP_KEY_EnterLowpower();
// LOW POWER-sleep模式
if (block_sleep)
{ // 这里是动态控制进入idle 睡眠,还是sleep 睡眠, 其中这里最高位置,定义为完全屏蔽睡眠,
if (block_sleep & 0x0000ffff)
{
LowPower_Idle_ext();
if (R8_RTC_FLAG_CTRL & RB_RTC_TRIG_FLAG)
{
R8_RTC_FLAG_CTRL = RB_RTC_TRIG_CLR;
}
}
return 3;
}
else
{
LowPower_Sleep_ext(RB_PWR_RAM96K | RB_PWR_EXTEND | RB_XT_PRE_EN);
HSECFG_Current(HSE_RCur_100); // 降为额定电流(低功耗函数中提升了HSE偏置电流)
}
if (R8_RTC_FLAG_CTRL & RB_RTC_TRIG_FLAG)
{
R8_RTC_FLAG_CTRL = RB_RTC_TRIG_CLR;
}
// if (!RTCTigFlag)
// {
// LowPower_Sleep(RB_PWR_RAM32K | RB_PWR_RAM96K | RB_PWR_EXTEND);
// R8_RTC_FLAG_CTRL = (RB_RTC_TMR_CLR | RB_RTC_TRIG_CLR);
// RTC_SetTignTime(time);
// sys_safe_access_enable();
// R8_HFCK_PWR_CTRL |= RB_CLK_XT32M_KEEP;
// sys_safe_access_disable();
// if (!RTCTigFlag)
// {
// LowPower_Halt();
// }
// R8_RTC_FLAG_CTRL = (RB_RTC_TMR_CLR | RB_RTC_TRIG_CLR);
// HSECFG_Current(HSE_RCur_100); // 降为额定电流(低功耗函数中提升了HSE偏置电流)
// return 0;
// }
#endif
return 0;
}
/*******************************************************************************
* @fn LowPowerGapProcess_Register
*
* @brief 注册低功耗唤醒间隙执行回调
*
* @param None.
*
* @return None.
*/
void LowPowerGapProcess_Register(pfnLowPowerGapProcessCB_t cb)
{
if ((uint32_t)cb & 0x20000000)
{
LowPowerGapProcess = cb;
}
}
/*******************************************************************************
* @fn HAL_SleepInit
*
* @brief 配置睡眠唤醒的方式 - RTC唤醒触发模式
*
* @param None.
*
* @return None.
*/
void HAL_SleepInit(void)
{
#if (defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
sys_safe_access_enable();
R8_SLP_WAKE_CTRL |= RB_SLP_RTC_WAKE; // RTC唤醒
sys_safe_access_disable();
sys_safe_access_enable();
R8_RTC_MODE_CTRL |= RB_RTC_TRIG_EN; // 触发模式
sys_safe_access_disable();
// PFIC_EnableIRQ(RTC_IRQn);
#endif
}