/*******************************************************************************
 * @note      Copyright (C) 2019 Shanghai Panchip Microelectronics Co., Ltd.
 *            All rights reserved.
 * @file      user_lp.c
 * @brief     Low Power test
 * @history - V1.0, 2019-3-21, zhangzhao, first implementation.
*******************************************************************************/
#include "pan271x.h"
#include "lp_common.h"

static void PWM_AutoReloadModeProc(void)
{
    CLK_APB1PeriphClockCmd(CLK_APB1Periph_PWM0_EN | CLK_APB1Periph_PWM0_CH23, ENABLE);
    // Config Pinmux
    SYS_SET_MFP(P1, 3, PWM_CH3);
	
    // Reset Prescaler before Config Output Channel
    PWM_ResetPrescaler(PWM, 3);

    // Config Target Output Channel
    PWM_ConfigOutputChannel(PWM, 3, 100, 30);

    // Enable output of TGT_PWM channel
    PWM_EnableOutput(PWM, BIT(3));

    // Start
    PWM_Start(PWM, BIT(3));
}

void PWM_ClkSrcSel(void)
{
	char input;
	SYS_TEST("pwm clk source select\n");
	SYS_TEST("a:  clk source select apb\n");
	SYS_TEST("b:  clk source select rcl/xtl\n");
	input = 'B';//getchar();
	switch(input){
		case 'A':
		case 'a':
			CLK->APB1_CLK_CTRL0 &= ~(APB1_CLK_CTRL0_PWM0_01CKSEL_Msk | APB1_CLK_CTRL0_PWM0_23CKSEL_Msk
									| APB1_CLK_CTRL0_PWM0_45CKSEL_Msk);
			break;
		case 'B':
		case 'b':
			SYS_TEST("low speed clk select\n");
			SYS_TEST("a:  clk source select rcl\n");
			SYS_TEST("b:  clk source select xtl\n");
			input = getchar();
			switch(input){
				case 'A':
				case 'a':
					PMU->RCL_CTRL |= RCL_CTRL_CLK_RCL_EN_AON_Msk;
					while(!(PMU->RCL_CTRL & RCL_CTRL_CLK_RCL32K_RDY_OUT_AON_Msk));
					PMU->SYS_CLK_CTRL &= ~SYS_CLK_CTRL_SLOW_CLK_SEL_Msk;
					break;
				case 'B':
				case 'b':
					#ifndef FPGA_MODE
					PMU->XTL_CTRL |= XTL_CTRL_CLK_XTL_EN_AON_Msk;
					while(!(PMU->XTL_CTRL & XTL_CTRL_CLK_XTL_RDY_OUT_AON_Msk));
					PMU->SYS_CLK_CTRL &= ~SYS_CLK_CTRL_SLOW_CLK_SEL_Msk;
					#else
					SYS_TEST("xtl is no supported at fpga mode \n");
					#endif
					break;
				default:break;
			}
			CLK->APB1_CLK_CTRL0 |= (APB1_CLK_CTRL0_PWM0_01CKSEL_Msk | APB1_CLK_CTRL0_PWM0_23CKSEL_Msk
									| APB1_CLK_CTRL0_PWM0_45CKSEL_Msk);
			break;
		default:break;
	}	
}

uint32_t LP_DeepSleepPwmOutTest(void)
{
	uint32_t tmp_reg;
	uint32_t wkupMode = LP_WKUP_MODE_SEL_EXT_GPIO;

	PWM_ClkSrcSel();
	
	uint32_t lpldo1 = 0x4;
	uint32_t lpldoh = 0x2;
	tmp_reg = PMU->ANA_LPLDO;
	tmp_reg &= ~ANA_LPLDO_PMU_LPLDOH_VSEL_AON_Msk;
	tmp_reg = (tmp_reg & ~(0xf << 20)) | (lpldoh << 20);
	PMU->ANA_LPLDO = tmp_reg;
	tmp_reg = PMU->ANA_RESERVED;
	tmp_reg &= ~ANA_RESERVED_PMU_LPLDOL_VSEL_AON_Msk;
	tmp_reg = (tmp_reg & ~(0xf<<1)) | (lpldo1 << 1);
	PMU->ANA_RESERVED = tmp_reg;

	GPIO_DisableDigitalPath(P0,0x03);
	GPIO_DisablePullupPath(P0,0x03);


	SYS_TEST("\r\nwake up by rcl 32k \r\n");
	SYS_delay_10nop(0x1000);
	LP_SetSleepTimerConfig(PMU, SLPTMR_CTRL_SLPTMR_EN_Msk | SLPTMR_CTRL_SLPTMR_INT_EN_Msk
							| SLPTMR_CTRL_SLPTMR_CMP0_EN_Msk | SLPTMR_CTRL_SLPTMR_WK_EN_Msk,
							ENABLE);
	LP_SetUsrSleepTimer(32000 * 5, 0);
	wkupMode = LP_WKUP_MODE_SEL_32K;

	PWM_AutoReloadModeProc();

	GPIO_DisableDigitalPath(P0,BIT6);
	LP_SetOtpCeDelayTime(PMU, 0XA);
	LP_SetOtpPowerDelayTime(PMU, 0X2);
	LP_SetDeepSleepConfig(PMU,wkupMode,LP_DEEPSLEEP_MODE2);
	
	SYS_TEST("deep sleep mode run continue \r\n");
	GPIO_EnableDigitalPath(P0,BIT6);
	PWM_ForceStop(PWM, BIT3);
    return 0;
}

