/******************************************************************************
*@file  : app.c
*@brief : application
******************************************************************************/
#include "app.h"



/******************************************************************************
* @brief : exti config.
* @param : None
* @return: None
******************************************************************************/
void Exit_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    EXTI_InitTypeDef EXTI_InitStruct;

    /* Initialization GPIO */
    System_Module_Enable(EN_GPIOAB);
    GPIO_InitStruct.Pin       = GPIO_PIN_13;  
    GPIO_InitStruct.Mode      = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull      = GPIO_PULLUP;
    GPIO_InitStruct.Alternate = GPIO_FUNCTION_0;
    GPIO_Init(GPIOC, &GPIO_InitStruct);
    
    PMU_PMUDomainPinFunction(PMU_PIN_PC13, PMU_PIN_FUNCTION_GPIO);
    PMU_PMUDomainPinMode(PMU_PIN_PC13, PMU_PIN_DIGITAL);
    PMU_PMUDomainPinPull(PMU_PIN_PC13, PMU_PIN_PULLUP);
    
    /* 配置EXTI */
    System_Module_Enable(EN_EXTI);
    /* Select EXTI_Line  */
    EXTI_InitStruct.EXTI_Line = EXTI_LINE_13;
    /* EXTI MODE   EXTI_MODE_INTERRUPT */
    EXTI_InitStruct.EXTI_Mode = EXTI_MODE_INTERRUPT;
    /* EXTI_Trigger   EXTI_TRIGGER_FALLING*/
    EXTI_InitStruct.EXTI_Trigger = EXTI_TRIGGER_FALLING;
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStruct); 

    /* Select EXTI SOURCE  */
    EXTI_LineConfig(EXTI_GPIOC, GPIO_PinSource13); 
    
    NVIC_ClearPendingIRQ(EXTI_IRQn);
    NVIC_SetPriority(EXTI_IRQn, 0x00);
    NVIC_EnableIRQ(EXTI_IRQn);
    

}

/******************************************************************************
* @brief : enter stop.
* @param : None
* @return: None
******************************************************************************/
void Enter_LowPower_STOP(void)
{
	volatile uint32_t i;
    uint32_t pabads, pcdads;
	/*----------------进stop模式前设置-------------*/
    /* 所有IO配置位模拟 */
    pabads = SCU->PABADS;
    pcdads = SCU->PCDADS;
    SCU->PABADS = 0xFFFFFFFF;
    SCU->PCDADS = 0xFFFFFFFF;

    /* 使能RTC PCLK */
    SCU->IPCKENR1 |= BIT13;

	/*时钟切换到RCH*/
	SCU->CCR1 = 0;
    /* 关闭XTH、XTL、RC4M、32K 时钟  */
    SCU->RCHCR&= ~(1 << 16);        // RC4M Disable
    SCU->XTHCR &= ~(1 <<  0);       // XTH Disable

    SCU->STOPCFG |=  (1 << 0);          // RTC域写使能
    PMU_XTLCmd(PMU_STATE_DISABLE);      // XTL Disable
    PMU_RC32KCmd(PMU_STATE_DISABLE);    // RC32K Disable
    PMU_RTCClkCmd(PMU_STATE_DISABLE);   // RTCCLK Disable 

	/*唤醒源配置*/
	Exit_Config();	
	
    /* LVD Disable */
    SCU->LVDCFG &= ~(1 << 0);

    /* STOP 模式下关闭LDO12、RC64M */
    /* 进入STOP模式前，需要将MLDO12电压自动降低(MLDO12LV)为1.0V，以减小随后关闭MLDO12带来的电压波动 */
    SCU->STOPCFG &= ~(0x03 << 4);
    SCU->STOPCFG |= (0x01 << 4);//MLDO12调整为1.0V
    SCU->STOPCFG |= 1 << 9;//STOP 下自动进入 LPSTP 模式
    SCU->STOPCFG |= 1 << 3;//停止（STOP）模式下，RC64M 自动关闭

    /* All Clock Disable */
    SCU->CLKOCR &= ~(1ul << 31);    // Buzzer2 Disable
    SCU->CLKOCR &= ~(1ul << 23);    // Buzzer1 Disable

    /*RAM Retention 模式*/	
	SCU->STOPCFG |=(1<<28);
	
	/*关闭SRAM未用空间*/
	//SCU->MEMCFG  |= (14<<16);    //1110 关闭未用的后24K
	
    /*Eflash 进入sleep模式 */
    EFC->CTRL |= 1<<12;
	
    
    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;   // disable systick        
    __set_PRIMASK(1);    // disable interrupt 
    SCB->ICSR = BIT25;   // clear systick pending bit 
    
    /* Set SLEEPDEEP bit of Cortex System Control Register */
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    
    SCU->STOPCFG &= ~(BIT11);  // PDDS=0 

    /* Request Wait For Interrupt */
    __WFI();

//    /* Request Wait For Event */
//    __SEV();   
//    __WFE();
//    __WFE(); 
 
    /* Reset SLEEPDEEP bit of Cortex System Control Register */
    SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); 
    

    
    SCU->STOPCFG &= ~(0x03 << 4);//MLDO12调整为1.2V
	 	 
	/* 唤醒后，Eflash退出Sleep模式 */
	EFC->CTRL &= ~(1<<12);
	for(i = 0; i < 100; i++); //Elash退出Sleep最少延时10uS

    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; /* Enable SysTick IRQ */               
    __set_PRIMASK(0);    // enable interrupt 

    SCU->PABADS = pabads;
    SCU->PCDADS = pcdads;
	
}
/******************************************************************************
* @brief : app test.
* @param : None
* @return: None
******************************************************************************/
void APP_Test(void)
{
    PMU_Init();
    while(1)
    {
        System_Delay_MS(1500);
        printfS("MCU enter stop mode, MCU will wakeup by PC13 falling edge!\n");            
        Enter_LowPower_STOP();
        printfS("MCU exit stop mode, wakeup by PC13 falling edge!\n");
    }
}








