#include "pan271x.h"
#include "pan_lp.h"
#include "pan_clk.h"


/**
* @brief  This function set sleep time
* @param[in]  pmu: where pmu is pmu module
* @param[in]  u32ClkCnt: where u32ClkCnt is 32k clock cnt num
* @param[in]  idx: where idx is 0,1, 2
* @return   none
*/
void LP_SetSleepTime(PMU_T *pmu,uint32_t u32ClkCnt,uint8_t idx)
{
	((__IO uint32_t *)(&(pmu)->SLPTMR_CMP0))[idx] = u32ClkCnt;
}

/**
* @brief  This function set lowpower mode
* @param[in]  pmu: where pmu is pmu module
* @param[in]  mode: where mode is sleep mode select
*                        LP_MODE_SEL_SLEEP_MODE
*                        LP_MODE_SEL_DEEPSLEEP_MODE
*                        LP_MODE_SEL_STANDBY_M1_MODE
*                        LP_MODE_SEL_STANDBY_M0_MODE
*
* @return   none
*/

void LP_SetSleepMode(PMU_T *pmu,uint8_t mode)
{
	uint32_t tmp_reg = pmu->LP_CTRL0;

	tmp_reg &= ~(LP_CTRL0_SLEEP_MODE_Msk);
	tmp_reg |= (mode << LP_CTRL0_SLEEP_MODE_Pos);
	pmu->LP_CTRL0 = tmp_reg;
}


void LP_SetSleepModeConfig(PMU_T *pmu, uint16_t ahbClkDiv)
{	
	LP_EnableInt(pmu,ENABLE);
	LP_SetSleepMode(pmu, LP_MODE_SEL_SLEEP_MODE);
	
	CLK->AHB_CLK_CTRL = (CLK->AHB_CLK_CTRL & ~AHB_CLK_CTRL_SLP_AHB_CLK_DIV_Msk) | (ahbClkDiv << AHB_CLK_CTRL_SLP_AHB_CLK_DIV_Pos);
	PMU->LP_CTRL0 |= LP_CTRL0_OTP_LP_CTRL_Msk;
	SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
	__WFI();

}

void LP_SetDeepSleepConfig(PMU_T *pmu,
							uint32_t wkMode,
							uint8_t dp_mode)
{
	LP_EnableInt(pmu,ENABLE);
	if (dp_mode == LP_DEEPSLEEP_MODE1){
		pmu->ANA_LPLDO |= ANA_LPLDO_PMU_LPLDOL_EN_AON_Msk;
		LP_SetAnalogConfig(pmu, LP_CTRL0_SW0_LP_CTRL_Msk | LP_CTRL0_PMU_ISOLATE_EN_Msk, ENABLE);
		LP_SetAnalogConfig(pmu, LP_CTRL0_SW1_LP_CTRL_Msk, DISABLE);
	} else if (dp_mode == LP_DEEPSLEEP_MODE2){
		pmu->ANA_LPLDO &= ~ANA_LPLDO_PMU_LPLDOL_EN_AON_Msk;
		LP_SetAnalogConfig(pmu, LP_CTRL0_SW1_LP_CTRL_Msk | LP_CTRL0_SW0_LP_CTRL_Msk, ENABLE);
		LP_SetAnalogConfig(pmu, LP_CTRL0_PMU_ISOLATE_EN_Msk, DISABLE);
	}
	
	LP_SetSleepMode(pmu, LP_MODE_SEL_DEEPSLEEP_MODE);
	LP_SetAnalogConfig(pmu, LP_CTRL0_SLOW_CLK_LP_CTRL_Msk, ENABLE);
	LP_SetOtpConfig(pmu, OTP_MODE_PSD_CE_REEN_DIS);
	SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
	__WFI();
}



void LP_SetStandbyMode1Config(PMU_T *pmu,
							uint32_t wkMode,
							uint8_t stdy_mode)
{
	LP_EnableInt(pmu,ENABLE);
	if (stdy_mode == LP_STANDBY_M1_MODE1){
		pmu->ANA_LPLDO |= ANA_LPLDO_PMU_LPLDOL_EN_AON_Msk;
		LP_SetAnalogConfig(pmu, LP_CTRL0_PMU_ISOLATE_EN_Msk, ENABLE);
		LP_SetAnalogConfig(pmu, LP_CTRL0_SW0_LP_CTRL_Msk | LP_CTRL0_SW1_LP_CTRL_Msk, DISABLE);
	} else if (stdy_mode == LP_STANDBY_M1_MODE2){
		pmu->ANA_LPLDO &= ~ANA_LPLDO_PMU_LPLDOL_EN_AON_Msk;
		LP_SetAnalogConfig(pmu, LP_CTRL0_PMU_ISOLATE_EN_Msk | LP_CTRL0_SW1_LP_CTRL_Msk, ENABLE);
		LP_SetAnalogConfig(pmu, LP_CTRL0_SW0_LP_CTRL_Msk, DISABLE);
	}
	
	LP_SetSleepMode(pmu, LP_MODE_SEL_STANDBY_M1_MODE);
	if((LP_WKUP_MODE_SEL_EXT_GPIO != wkMode)&&(LP_WKUP_MODE_SEL_GPIO != wkMode)){
		LP_SetAnalogConfig(pmu, LP_CTRL0_SLOW_CLK_LP_CTRL_Msk, ENABLE);
	} else {
		LP_SetAnalogConfig(pmu, LP_CTRL0_SLOW_CLK_LP_CTRL_Msk, DISABLE);
    }
	
	LP_SetOtpConfig(pmu, OTP_MODE_PSD_CE_REEN_DIS);
	SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
	__WFI();
}

void LP_SetStandbyMode0Config(uint32_t wkMode)
{
	LP_EnableInt(PMU,ENABLE);
	PMU->ANA_LPLDO &= ~ANA_LPLDO_PMU_LPLDOL_EN_AON_Msk;
	LP_SetAnalogConfig(PMU, LP_CTRL0_PMU_ISOLATE_EN_Msk, ENABLE);
	LP_SetAnalogConfig(PMU, LP_CTRL0_SW0_LP_CTRL_Msk | LP_CTRL0_SW1_LP_CTRL_Msk, DISABLE);

	LP_SetSleepMode(PMU, LP_MODE_SEL_STANDBY_M0_MODE);
	if((LP_WKUP_MODE_SEL_BOD == wkMode)||(LP_WKUP_MODE_SEL_BOD == wkMode)){
		LP_SetAnalogConfig(PMU, LP_CTRL0_SLOW_CLK_LP_CTRL_Msk, ENABLE);
	} else {
		LP_SetAnalogConfig(PMU, LP_CTRL0_SLOW_CLK_LP_CTRL_Msk, DISABLE);
    }
	
	LP_SetOtpConfig(PMU, OTP_MODE_PSD_CE_REEN_DIS);
	SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
	__WFI();
}
