/*********************************************************
*Copyright (C), 2017, Shanghai Eastsoft Microelectronics Co., Ltd.
 * @文件名:  sleep.c
 * @作  者:  AE Team
 * @版  本:  V1.00
 * @日  期:  2022/07/25
 * @描  述:  休眠函数
 * @note
 *          Change Logs:
 *          Date            Author          Notes
 *          25 July 2022    AE Team         change license to Apache-2.0
 *
 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 **********************************************************************************
 */


#include "sleep.h"
#include "gpio.h"
#include "wdt.h"

/***************************************************************
 函数名：void deep_sleep(void)
 描  述：进入深度睡眠
 输入值：无
 输出值：无
 返回值：无
***************************************************************/
void deep_sleep(void)
{
    /* 所有GPIO输入输出均关闭 */
    GPIO->PAINEB.Word = 0xFFFFFFFF;
    GPIO->PBINEB.Word = 0xFFFFFFFF;
    GPIO->PADIR.Word = 0xFFFFFFFF;
    GPIO->PBDIR.Word = 0xFFFFFFFF;
    /* 配置外部端口中断 */
    PINT1_Init(GPIO_Pin_A1);

    /* 配置SCU准备进入睡眠模式 */
    SCU_RegUnLock();
    SCU_MOSC_EN(0x0);                       /* 休眠时仅LRC工作，退出休眠自动恢复 */
    SCU_WAKEUPTIME(0x800);                  /* 系统唤醒时间控制 */
    SCU_MOSC_EN(0x00);                      /* 关闭HRC、XTAL以及CLKFLT */
    SCU_CLKFLT_EN(0x00);                    /* 关闭系统时钟滤波器 */
    SCU_VROSCEN(0x0);                       /* 关闭VR工作时钟 */
    SCU_STPRTNEN(0x01);                     /* 深度睡眠下SRAM低功耗 */
    SCU_LDOLP_VOSEL(0x01);                  /* 深度睡眠下，LDO输出1.4 */
    SCU_LP_STOP(0x01);                      /* 深度睡眠下LDO低功耗使能 */
    SCU_BG_STOP(0x01);                      /* 深度睡眠下BG低功耗使能 */
    SCU_FLS_STOP(0x01);                     /* 深度睡眠下FLASH STOP使能 */
    SCB_SystemLPConfig(SCB_LP_SleepDeep, Enable);       /* 深度睡眠 */
    SCB_SystemLPConfig(SCB_LP_SleepOnExit, Disable);    /* 从ISR中断处理程序返回到线程模式时不进入休眠 */
    SCB_SystemLPConfig(SCB_LP_SEVOPend, Enable);        /* 中断挂起作为唤醒事件 */
    SCU_RegLock();

    /* 配置看门狗及输出管脚 */
    WDTInit();
    OutPin_Init(GPIO_Pin_B1);
    OutPin_Init(GPIO_Pin_B0);

    /* 配置LVD为下降沿检测 */
    SCU_RegUnLock();
    SCU_LVDIFS_Fall();
    SCU_RegLock();

    /* 配置中断 */
    NVIC_Init(NVIC_LVD_IRQn, NVIC_Priority_1, Enable);
    NVIC_Init(NVIC_IWDT_IRQn, NVIC_Priority_1, Enable);

    while (1)
    {
        /* 清除所有挂起中断标志位 */
        __disable_irq();
        NVIC->ICPR[0] = NVIC->ICPR[0];

        __NOP();
        __NOP();
        __WFI(); /* 休眠 */
        __NOP();
        __NOP();

        /* 处理外部端口中断 */
        if (PINT_GetITFlag(GPIO_Pin_A1) == SET)
        {
            PINT_ClearITFlag(GPIO_Pin_A1);
            GPIO_ToggleBit(GPIO_Pin_B0);
        }

        /* 喂狗 */
        if (IWDT_GetFlagStatus() == SET)
        {
            IWDT_Clear();
            GPIO_ToggleBit(GPIO_Pin_B1);
        }

        /* 电压恢复则复位 */
        if (SCU_GetLVDFlagStatus(SCU_LVDFlag_IF) != RESET)
        {
            SCU_RegUnLock();
            SCU_LVDClearIFBit();
            SCU_RegLock();
            NVIC_SystemReset();
        }

        /* 其他任务 */
    }
}


/*************************END OF FILE**********************/
