/**************************************************************************//**
 * @file     main.c
 * @version  V1.00
 * $Date: 19/11/06 16:00 $
 * @brief    PWM Sample Code. To test PWM counting modes such as One-Shot
 *           Mode and Periodic Mode, counting types such as Edge-Aligned PWM,
 *           Center-Aligned PWM and Precise Center-Aligned PWM, Center Loading
 *           Operation, Double Buffering, Operating Modes, Polarity Control,
 *           Trigger ADC Conversion, etc.
 * @note
 * Copyright (C) 2019 Panchip Technology Corp. All rights reserved.
 *
 ******************************************************************************/
#include "pan271x.h"
#include "pwm_common.h"

void Clock_Init(void)
{
	PMU->SYS_CLK_CTRL |= SYS_CLK_CTRL_OTP_READ_MODE_SEL_Msk;
	PMU->SYS_CLK_CTRL &= ~(SYS_CLK_CTRL_OTP_CLK_HIGH_CYCLE_Msk | SYS_CLK_CTRL_OTP_CLK_LOW_CYCLE_Msk);
	PMU->SYS_CLK_CTRL |= ((0x1 << SYS_CLK_CTRL_OTP_CLK_HIGH_CYCLE_Pos) | (0x0 << SYS_CLK_CTRL_OTP_CLK_LOW_CYCLE_Pos));
	PMU->SYS_CLK_CTRL |= SYS_CLK_CTRL_OTP_SW_UP_CYCLE_EN_Msk;

	PMU->ANA_ANALDO |= ANA_ANALDO_EN_LDO_FSYN_AON_Msk;
    //MCU
	CLK_XthStartupConfig();
	PMU->XTH_CTRL |= XTH_CTRL_FSYNXO_BUFEN_AON_Msk;
    PMU->XTH_CTRL |= XTH_CTRL_FSYNXO_EN_AON_Msk;
	CLK_WaitClockReady(CLK_SYS_SRCSEL_XTH);

	CLK_HCLKConfig(0);

	CLK_SYSCLKConfig(CLK_DPLL_REF_CLKSEL_XTH,CLK_DPLL_OUT_48M); 
	CLK_RefClkSrcConfig(CLK_SYS_SRCSEL_DPLL_1);

	CLK_AHBPeriphClockCmd(CLK_AHBPeriph_All,ENABLE);
	CLK_APB1PeriphClockCmd(CLK_APB1Periph_All,ENABLE);
}


void Sys_Init(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init I/O Multi-function  */
	SYS_SET_MFP(P0,6,UART0_RX);
	SYS_SET_MFP(P0,5,UART0_TX);
	GPIO_EnableDigitalPath(P0,BIT6);

	UART_Init(UART0, 115200);
    SYS_LockReg();
}


void PWM_PrintSampleInfo()
{
    SYS_TEST("\n");
    SYS_TEST("+--------------------------------------------------------------------------------------+ \n");
    SYS_TEST("|                      PAN271x PWM Sample Code.                                        | \n");
    SYS_TEST("+--------------------------------------------------------------------------------------+ \n");
    SYS_TEST("|    Press key to start specific testcase:                                             | \n");
    SYS_TEST("|                                                                                      | \n");
    SYS_TEST("|    Input '1'    Testcase 1: PWM Operating Modes.                                     | \n");
    SYS_TEST("|    Input '2'    Testcase 2: Polarity Control.                                        | \n");
    SYS_TEST("+--------------------------------------------------------------------------------------+ \n");
}

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 = 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);
		speed_div = 1;
		break;
    case 'B':
    case 'b':
		SYS->SYS_CTRL |= SYS_CTRL_CLK_OUT_SEL_Msk;
        SYS_SET_MFP(P1, 1, APB1_CLK);
        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;
			PMU->SYS_CLK_CTRL &= ~SYS_CLK_CTRL_SLOW_CLK_SEL_Msk;
            break;
        case 'B':
        case 'b':
            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;
            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);
		speed_div = 1000;
        break;
    default:
        break;
    }
}

/*------------------
    Main function
 ------------------*/
int main(void)
{
    char c;
    Clock_Init();
    Sys_Init();

    SYS_TEST("\nCPU @ %dHz\n", SystemCoreClock);

    PWM_ClkSrcSel();
    PWM_TestModuleInit();
    PWM_PrintSampleInfo();
    c = getchar();
    while( c )
    {
        SYS_TEST("\n");
        switch(c)
        {
            /* 1. PWM Operating Modes */
            case '1':
                PWM_TestFunctionEnter(0);
                break;
            /* 2. Polarity Control */
            case '2':
                PWM_TestFunctionEnter(1);
                break;
            default:
                SYS_WARN("Cannot find testcase %c!\n", c);
                break;
        }
        PWM_PrintSampleInfo();
        c = getchar();
    }
}
