/**************************************************************************//**
 * @file     main.c
 * @version  V1.00
 * $Date: 19/09/09 11:28 $
 * @brief    GPIO Sample Code. Control GPIO pin direction, set high/low state,
 *           set GPIO interrupt, enable debounce, and set wake up pin.
 *
 * @note
 * Copyright (C) 2019 Panchip Technology Corp. All rights reserved.
 *
 ******************************************************************************/
#include "pan271x.h"
#include "gpio_common.h"


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

	GPIO_DB->DBCTL |= (0X3F << 16);
    /* 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 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 GPIO_PrintTestPins()
{
    SYS_TEST("|    Board Pin Connection Scheme:                                              | \n");
    SYS_TEST("|                                                                              | \n");
    SYS_TEST("|      [Group1]                [Group2]                                        | \n");
    for (size_t i = 0; i < GPIO_TEST_GRP_NUM; i++)
    SYS_TEST("|      P%02x       <---->        P%02x                                         | \n", GPIO_TEST_PINS[i][0],GPIO_TEST_PINS[i][1]);
    SYS_TEST("+------------------------------------------------------------------------------+ \n");
}

void GPIO_PrintSampleInfo()
{
    SYS_TEST("\n");
    SYS_TEST("+------------------------------------------------------------------------------+ \n");
    SYS_TEST("|                      PAN271X GPIO Sample Code.                               | \n");
    SYS_TEST("+------------------------------------------------------------------------------+ \n");
    SYS_TEST("|    Press key to start specific testcase:                                     | \n");
    SYS_TEST("|                                                                              | \n");
    SYS_TEST("|    Input '1'    Testcase 1: Push-pull Mode Test.                             | \n");
    SYS_TEST("|    Input '2'    Testcase 2: Open-drain Mode Test.                            | \n");
    SYS_TEST("|    Input '3'    Testcase 3: Quasi-bidirectional Mode Test.                   | \n");
    SYS_TEST("|    Input '4'    Testcase 4: Debounce Test.                                   | \n");
    SYS_TEST("|    Input '5'    Testcase 5: Interrupt Test.                                  | \n");
    SYS_TEST("+------------------------------------------------------------------------------+ \n");
    GPIO_PrintTestPins();
}


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

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

    GPIO_PrintSampleInfo();
	CLK->IPRST0 |= IPRST0_USBRST_Msk;

    c = getchar();
    while( c )
    {
        SYS_TEST("\n");
        switch(c)
        {
            /* 1. Push-pull Mode Test */
            case '1':
                GPIO_TestFunctionEnter(0);
                break;
            /* 2. Open-drain Mode Test */
            case '2':
                GPIO_TestFunctionEnter(1);
                break;
            /* 3. Quasi-bidirectional Mode Test */
            case '3':
                GPIO_TestFunctionEnter(2);
                break;
            /* 4. Debounce Test */
            case '4':
                GPIO_TestFunctionEnter(3);
                break;
            /* 5. Interrupt Test */
            case '5':
                GPIO_TestFunctionEnter(4);
                break;
            default:
                SYS_WARN("Cannot find testcase %c!\n", c);
                break;
        }
        GPIO_PrintSampleInfo();
        c = getchar();
    }
}

