#include "acm32g103_spl_conf.h"

/*****************************************************************
@功能	进入Stop低功耗模式，关闭Eflash,并在Ram中运行
@参数	无
@返回	无
******************************************************************/
void Enter_Stop_Ram(uint8_t mode)
{
	volatile uint32_t i;
    
    SysTick->CTRL = 0;   // disable systick        
    __set_PRIMASK(1);    // disable interrupt 
    SCB->ICSR = BIT25;   // clear systick pending bit 
    
    __RCC_PMU_CLK_ENABLE();
    
    PMU->STCLR = 0xFFFFFFFF;//Clear all wake-up flags
    RCC->RSR |= RCC_RSR_RSTFLAGCLR;//Clear all reset flags

    PMU->CTRL0 &= (~PMU_CTL0_STOP_WPT_Msk);
    PMU->CTRL0 |= (0x50 << PMU_CTL0_STOP_WPT_Pos);//STOP0/STOP1/STOP2唤醒时间设置
    //printfS("PMU->CTRL0 = 0x%08x\r\n",PMU->CTRL0); 
    if(mode != PMU_STOP_2)
    {        
        /*时钟切换到RCH*/
        RCC->RC64MCR &= ~RCC_RC64MCR_RC64MDIV;
        RCC->RC64MCR |= RCC_RC64MCR_RC64MEN;
        while (!(RCC->RC64MCR & RCC_RC64MCR_RC64MRDY));

        RCC->CCR1 &= ~RCC_CCR1_SYSCLKSEL;	/* sysclk = RC64M  */
                
        /* 关闭XTH、XTL、32K 时钟  */
        RCC->XTHCR &= (~RCC_XTHCR_XTHEN);     // XTH  Disable
        RCC->PLLCR &= (~RCC_PLLCR_PLLEN);      //PLL Disable
        RCC->STDBYCTRL &= (~RCC_STDBYCTRL_RC32EN); //RC32K Disable
        RCC->STDBYCTRL &= (~RCC_STDBYCTRL_XTLEN); //XTL Disable
        
       /* All Clock Disable */
        RCC->CLKOCR &= (~RCC_CLKOCR_BUZZER2EN);    // Buzzer2 Disable
        RCC->CLKOCR &= (~RCC_CLKOCR_BUZZER1EN);    // Buzzer1 Disable

        RCC->APB1ENR = RCC_APB1ENR_PMUCKEN;//PMU
        RCC->APB2ENR = RCC_APB2ENR_EXTICKEN ;//EXTI 
        
        PMU->CTRL1 &= (~PMU_CTL1_LVDEN);//禁止LVD       
        /* STOP 模式下关闭RC64M */
        PMU->CTRL0 |= PMU_CTL0_RC64MPDEN;//停止（STOP）模式下，RC64M 自动关闭 
    }
    
    EXTI->PDR = EXTI_ALL_LINE_MASK;//Clear all EXTI interrupt pending 
    
    PMU->CTRL0 &= (~PMU_CTL0_MLDO12_LV_Msk);
    PMU->CTRL0 |= PMU_CTL0_MLDO12_LV_0;//MLDO12调整为1.0V 
    if(mode == PMU_STOP_0)
    {          
        PMU->CTRL0 |= PMU_CTL0_MLDO12_LOWP;//MLDO是否进入低功耗模式       
    }
    else if(mode == PMU_STOP_2)
    {
        /*时钟切换到RC32K*/
        RCC->STDBYCTRL |= RCC_STDBYCTRL_RC32EN;//RC32K时钟使能 
        while(0 == ((RCC->STDBYCTRL) & RCC_STDBYCTRL_RC32KRDY));
        RCC->CCR1 = RCC_CCR1_SYSCLKSEL_0;       
    }  
    
    MODIFY_REG(PMU->CTRL0, PMU_CTL0_LPMS_Msk, mode);
        
    if(mode != PMU_STOP_2)
    {
        /*Eflash 进入sleep模式 */
        EFC->CTRL |= EFC_CTRL_SLEEP;
    }
    
    SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));   // Set SLEEPDEEP bit of Cortex System Control Register 
      

	/*---------------进入stop模式-----------*/
	/* Wait For Interrupt */   
    __WFI();
	
	/*---------------唤醒后设置-------------*/
	CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); 
	
    if(mode != PMU_STOP_2)
    {    
        /* 唤醒后，Eflash退出Sleep模式 */
        EFC->CTRL &= (~EFC_CTRL_SLEEP);
        for(i = 0; i < 10 *5000; i++); //Elash退出Sleep最少延时10uS
    }
    //开启Systick
    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ 
    //开启所有中断               
    __set_PRIMASK(0);    // enable interrupt 
}


