
/******************************************************************************
*@file  : app.c
*@brief : application
******************************************************************************/

#include "app.h"   


/******************************************************************************
* @brief : RTC Wakeup Test in Low Power Stop Mode.
* @param : mode: Stop mode select:stop0 or stop1 or stop2 
* @return: none
******************************************************************************/
void LowPower_Stop_Mode_RTC_Test(uint8_t mode)
{
    RTC_ConfigTypeDef RTC_Handle;
    HAL_Delay(3000);
    HAL_PMU_Init();
    //STANDBY 电源域软复位
    RCC->STDBYCTRL &= ~RCC_STDBYCTRL_STDBYRST;
    /********************************************/
    /**************** RTC Config ****************/
    /********************************************/
    RTC_Handle.ClockSource       = RTC_CLOCK_RC32K;
    RTC_Handle.Compensation      = COMPENSATION_INCREASE;    // 开始时钟补偿，如不需补偿设置补偿值为0
    RTC_Handle.CompensationValue = 0x05;                     // 开始时钟补偿，如不需补偿设置补偿值为0

    HAL_RTC_Config(&RTC_Handle);  
   
    NVIC_ClearPendingIRQ(RTC_IRQn);
    NVIC_EnableIRQ(RTC_IRQn);
    SET_BIT(PMU->CTRL0,PMU_CTL0_RTC_WE);
    
    if(mode == PMU_CTL0_LPMS_STOP2)
    {
        NVIC_ClearPendingIRQ(STOP_RESET_IRQn);
        NVIC_SetPriority(STOP_RESET_IRQn, 5);
        NVIC_EnableIRQ(STOP_RESET_IRQn);
    }
    __HAL_RTC_ENABLE_32S_IT;
//    __HAL_RTC_ENABLE_SEC_IT;
    
    while (1) 
    {
        SysTick->CTRL = 0;   // disable systick        
        __set_PRIMASK(1);    // disable interrupt 
        SCB->ICSR = BIT25;   // clear systick pending bit 
        printfS("MCU Enter Stop%d Mode, Wait RTC IRQ To Wakeup MCU!\n",mode); 
        HAL_EXTI_ClearAllPending();
        SET_BIT(PMU->CTRL0,PMU_CTL0_RTC_WE);
        RTC->SR = 0xFFFFFFFF;
        
        if(mode == PMU_CTL0_LPMS_STOP2)
        {
            /*时钟切换到RC32K*/
            RCC->STDBYCTRL |= RCC_STDBYCTRL_RC32EN;//RC32K时钟使能 
            while(0 == ((RCC->STDBYCTRL) & RCC_STDBYCTRL_RC32KRDY));
            RCC->CCR1 = RCC_CCR1_SYSCLKSEL_0;             
        } 
            
        HAL_PMU_EnterStopMode(WAIT_FOR_INT, mode);
        
        if(mode == PMU_CTL0_LPMS_STOP2)
        {
            HAL_SimpleDelay(100);
                        
            SystemClock_Config();//切换至120MHZ
            HAL_Init(); 
        }
        if(mode != PMU_CTL0_LPMS_STOP2)
        {
            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 
        
        if(mode == PMU_CTL0_LPMS_STOP2)
        {
            BSP_UART_Init(); 
        }

        printfS("************\r\n"); 
        printfS("************\r\n"); 
        printfS("************\r\n");         
        printfS("Exit Stop%d\r\n", mode); 
        printfS("************\r\n"); 
        printfS("************\r\n"); 
        printfS("************\r\n");    

        HAL_Delay(3000);

    }
}





/******************************************************************************
* @brief : EXTI Wakeup Test in Low Power Stop Mode.
* @param : mode: Stop mode select:stop0 or stop1 or stop2 
* @return: none
******************************************************************************/
void LowPower_Stop_Mode_EXTI_Test(uint8_t mode)
{
    uint32_t i;
    GPIO_InitTypeDef GPIO_PINx_Handle;
    
    printfS("LowPower Stop%d Mode Test...... \r\n", mode);
    
    HAL_PMU_Init();	
    //STANDBY 电源域软复位
    RCC->STDBYCTRL &= ~RCC_STDBYCTRL_STDBYRST;
    __HAL_RCC_EXTI_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();


	/*---------------------------EXTI_Line13-----------------------------*/  	
	/* Initialization GPIO */
    GPIO_PINx_Handle.Pin       = GPIO_PIN_13;
    GPIO_PINx_Handle.Mode      = GPIO_MODE_INPUT;
    GPIO_PINx_Handle.Pull      = GPIO_NOPULL;
	GPIO_PINx_Handle.Drive     = GPIO_DRIVE_LEVEL3;
    HAL_GPIO_Init(GPIOC, &GPIO_PINx_Handle);
    
    /* Config EXTI */
    HAL_EXTI_SetConfigLine((GPIO_TypeDef *)GPIOC, EXTI_LINE_13, EXTI_MODE_IT_RISING);
    NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
    NVIC_SetPriority(EXTI15_10_IRQn, 5);
    NVIC_EnableIRQ(EXTI15_10_IRQn);
    
    if(mode == PMU_CTL0_LPMS_STOP2)
    {
        NVIC_ClearPendingIRQ(STOP_RESET_IRQn);
        NVIC_SetPriority(STOP_RESET_IRQn, 5);
        NVIC_EnableIRQ(STOP_RESET_IRQn);
    }
    
    HAL_Delay(3000);
    

    while (1) 
    {
        printfS("MCU Enter Lowpower, Press User EXIT Pin To Wakeup MCU!\n"); 
        
        extern void Enter_Stop_Ram(uint8_t mode);
        Enter_Stop_Ram(mode);                 
             
        HAL_SimpleDelay(100);
                    
        SystemClock_Config();//切换至120MHZ
        HAL_Init();  

        BSP_UART_Init(); 

        printfS("************\r\n"); 
        printfS("************\r\n"); 
        printfS("************\r\n");         
        printfS("Exit Stop%d\r\n", mode); 
        printfS("************\r\n"); 
        printfS("************\r\n"); 
        printfS("************\r\n");         
        HAL_Delay(3000);

    }
}

void APP_LowPower_Stop_Mode_Test(PMU_TestMode_TypeDef wakeup_src, uint8_t mode)
{
    /* 解决USBPHY的DP/DM输入无法关闭，存在漏电 */ 
    RCC->APB2ENR |= 1;  //SYSCFG 时钟使能
    SYSCFG->PHYCFG |= 3 << 6;   //USBPHY DP、DM Pull down 
    SYSCFG->PHYCFG |= 1 << 2;   //PLL enter PowerDown
    
    switch (wakeup_src)
    {
        /* stop模式下 IO唤醒 */
        case PMU_STOP_IO_WAKEUP:
        {
            LowPower_Stop_Mode_EXTI_Test(mode);           
        }
        break;
        /* stop模式下 RTC唤醒 */
        case PMU_STOP_RTC_WAKEUP:
        {
            LowPower_Stop_Mode_RTC_Test(mode);
        }
        break;
        default: break; 
    }
}


