#include "acm32g103_hal_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 
    
    __HAL_RCC_PMU_CLK_ENABLE();
    
    PMU->STCLR = 0xFFFFFFFF;//Clear all wake-up flags

    PMU->CTRL0 &= ~(0xFFF << 16);
    PMU->CTRL0 |= (0x50 << 16);//STOP0/STOP1/STOP2唤醒时间设置
    //printfS("PMU->CTRL0 = 0x%08x\r\n",PMU->CTRL0); 
    if(mode != PMU_CTL0_LPMS_STOP2)
    {        
        /*时钟切换到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 &= ~(1 <<  0);     // XTH  Disable
        RCC->PLLCR &= ~(1 << 0);      //PLL Disable
        RCC->STDBYCTRL &= ~(1 << 8); //RC32K Disable
        RCC->STDBYCTRL &= ~(1 << 0); //XTL Disable
        
       /* All Clock Disable */
        RCC->CLKOCR &= ~(1ul << 31);    // Buzzer2 Disable
        RCC->CLKOCR &= ~(1ul << 23);    // Buzzer1 Disable

        RCC->APB1ENR = BIT27;//PMU
        RCC->APB2ENR = BIT4 ;//EXTI  
        
        PMU->CTRL1 &= ~0x01;//禁止LVD       
        /* STOP 模式下关闭RC64M */
        PMU->CTRL0 |= 1 << 4;//停止（STOP）模式下，RC64M 自动关闭 
    }
    
    EXTI->PDR = EXTI_ALL_LINE_MASK;//Clear all EXTI interrupt pending 
    
    if(mode == PMU_CTL0_LPMS_STOP0)
    {          
        PMU->CTRL0 |= (0x1 << 8);//MLDO12调整为1.0V
        PMU->CTRL0 |= 1 << 10;//MLDO是否进入低功耗模式    
        MODIFY_REG(PMU->CTRL0, PMU_CTL0_LPMS_Msk, PMU_CTL0_LPMS_STOP0);
    }
    else if(mode == PMU_CTL0_LPMS_STOP1)
    {
        /* STOP1 模式下关闭LDO12*/
        PMU->CTRL0 |= (0x1 << 8);//MLDO12调整为1.0V
        PMU->CTRL0 |= 1 << 10;//MLDO是否进入低功耗模式            
        MODIFY_REG(PMU->CTRL0, PMU_CTL0_LPMS_Msk, PMU_CTL0_LPMS_STOP1);
    }
    else if(mode == PMU_CTL0_LPMS_STOP2)
    {
        PMU->CTRL0 |= (0x1 << 8);//MLDO12调整为1.0V 
        //PMU->CTRL0 |= (0x7 << 12);//LPLD12调整为1.2V
        /*时钟切换到RC32K*/
        RCC->STDBYCTRL |= (1<<8);//RC32K时钟使能 
        RCC->CCR1 = 0x01; 
        while(0 == ((RCC->STDBYCTRL) & (1U << 9)));
        MODIFY_REG(PMU->CTRL0, PMU_CTL0_LPMS_Msk, PMU_CTL0_LPMS_STOP2);
    }        

        
    if(mode != PMU_CTL0_LPMS_STOP2)
    {
        /*Eflash 进入sleep模式 */
        EFC->CTRL |= 1<<12;
    }
    
    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_CTL0_LPMS_STOP2)
    {    
        /* 唤醒后，Eflash退出Sleep模式 */
        EFC->CTRL &= ~(1<<12);
        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 
}


