/*
  ******************************************************************************
  * @file    APP.c
  * @author  PJ
  * @version V1.0.0
  * @date    2021
  * @brief   RTC demo source code.
  ******************************************************************************
*/
#include "app.h"



void Delay_Sram(volatile uint32_t fu32_Delay)
{
    fu32_Delay *= 5000;
    
    while (fu32_Delay--);
}


void LowPower_STOP(void)
{
    /* 关闭中断 */
    __set_PRIMASK(1);
    /* 关闭Systick中断 */     
    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
    /* 清除Systick中断挂起标志 */    
    SCB->ICSR = BIT25;
    
    /* 设置PA0 上升沿唤醒 */
    SCU->PABADS &= ~(1 << 0);
    
    SCU->IPCKENR2 |= BIT4;
    EXTI->EENR  |= 1 << 0;
    EXTI->RTENR |= 1 << 0;
    
    /* 时钟源选择为RC64M */
    SCU->RCHCR |=  SCU_RCHCR_RCH_EN; 
    while(0 == (SCU->RCHCR & SCU_RCHCR_RCHRDY));  // wait RCH ready 

    SCU->CCR2=((SCU->CCR2) & (~(SCU_CCR2_SYSDIV0 | SCU_CCR2_SYSDIV1 | SCU_CCR2_PCLKDIV)));
    while((SCU->CCR2 & SCU_CCR2_DIVDONE) == 0x00);//wait for done
    
    SCU->CCR1 = 0;  // select RC64M as default 
    SCU->RCHCR &= ~(1 << 8);
    
    SCU->PLLCR &= ~0x01;
    SCU->PLLCR |= (1 << 21);
 
    /* All Clock Disable */
    SCU->CLKOCR &= ~(1ul << 31);    // Buzzer2 Disable
    SCU->CLKOCR &= ~(1ul << 23);    // Buzzer1 Disable
    
    /* 关闭PLL、XTH、XTL、32K时钟  */
    SCU->XTHCR &= ~(1 << 0);    // XTH Disable
    SCU->PLLCR &= ~(1 << 0);    // PLL Disable
    
    SCU->STOPCFG |= (1 << 0);    // RTC域写使能
    PMU->ANACR &= ~(1 << 0);     // XTL Disable
    PMU->ANACR &= ~(1 << 8);     // RC32K Disable

    /* RTCCLK Disable */
    PMU->CR1 &= ~(1 << 5);

    /* LVD Disable */
    SCU->LVDCFG &= ~(1 << 0);
    
    /* LDO17关闭，唤醒后需要打开 */
    SCU->LDOCR &= ~(1 << 9);
    SCU->LDOCR &= ~(1 << 14);
    
    /* Eflash Sleep */
    EFC->CTRL |= (1 << 12);
    Delay_Sram(1);
    
    /* 关闭不需要的Sram */
    //SCU->MEMCFG = ~2;

    /* STOP 模式下关闭LDO12、RC64M */    
    SCU->STOPCFG |= 1 << 8;//RCH选择16分频输出
    SCU->STOPCFG |= 1 << 3;//RCH即RC64M是否自动关闭
    
    /* 进入STOP模式前，需要将MLDO12电压自动降低(MLDO12LV)为1.0V，以减小随后关闭MLDO12带来的电压波动 */
    SCU->STOPCFG &= ~(3 << 4);
    SCU->STOPCFG |= (1 << 4);//MLDO12调整为1.0V
    
    SCU->STOPCFG |= 1 << 9;//进入LPLSTOP模式
    
    SCU->STOPCFG &= (~BIT11);  // PDDS=0   

    /* Set SLEEPDEEP bit of Cortex System Control Register */
    SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); 


    __SEV();   
    __WFE();
    __WFE();    /* Wait For Event */  
   

    CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
    
    SCU->STOPCFG &= ~(1 << 3);//RCH即RC64M不自动关闭
    SCU->STOPCFG &= ~(1 << 8);//RCH选择原始不分频输出
    
    SCU->STOPCFG &= ~(3 << 4);//MLDO12调整为1.2V    
    /* 唤醒后，打开LDO17V */
    SCU->LDOCR |= 1 << 9;
    SCU->LDOCR |= 1 << 14;
    
    EFC->CTRL &= ~(1<<12);
    
    Delay_Sram(50);
    
    /* 使能Systick中断 */
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; 
    /* 使能全部中断 */    
    __set_PRIMASK(0);
    
}
