/**************************************************************************//**
 * @file     main.c
 * @version  V1.00
 * $Revision: 1 $
 * $Date: 14/07/15 2:52p $
 * @brief    N572 PWM Generator and Capture Timer Driver Sample Code
 *
 * @note
 * Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
 *
 ******************************************************************************/
#include <stdio.h>
#include "N572.h"
#include "uip_kernel_api.h"
#include "demo.h"
#include "hardware_init.h"
#include "chip_uip_interrupt.h"

VOID PWM0_IRQHandler_Process(VOID  *arg, VOID *info)
{
    // Update PWMA channel 0 period and duty
    PWM_SetCNR(PWM, 200);
    PWM_SetCMR(PWM, PWM_CH0, 50);
	
    // Clear PWM period interrupt flag
    PWM_ClearIntFlag(PWM);
}

void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Unlock protected registers */
    SYS_UnlockReg();

    // Enable Internal RC
#if( __CHIP_SERIES__ == __N572F065_SERIES__ )	
    CLK_EnableXtalRC(CLK_PWRCTL_OSC24M_EN_Msk);
#endif
#if( __CHIP_SERIES__ == __N572F072_SERIES__ )	
    CLK_EnableXtalRC(CLK_PWRCTL_OSC48M_EN_Msk);
#endif
	
    // Enable External XTL32K
    CLK_EnableXtalRC(CLK_PWRCTL_XTL32K_EN_Msk);

	// Enable PLL1 & PLL2
	CLK_SetPLL1Mode(PLL_NORMAL_MODE);
	CLK_SetPLL2Mode(PLL_NORMAL_MODE);
	
	// Select PLL2 input source and frequence
#if( __CHIP_SERIES__ == __N572F065_SERIES__ )	
	CLK_SetPLL2(PLL2_SRC_PLL1_FOUT, NULL); // 32K -> PLL1(6M) -> PLL2(48M)
#endif
#if( __CHIP_SERIES__ == __N572F072_SERIES__ )	
	CLK_SetPLL2(PLL2_SRC_PLL1_FOUT, PLL2_48M);
#endif

	// Set RAM wait state
	SYS_SET_RAM_WAIT_STATE(SYS_IPRST0_RAMWS_ZERO_WAIT);
	
    // Set flash memory wait state
	SYS_SET_CPU_WAIT_STATE(SYS_IPRST0_CPUWS_1HCLK_WAIT);

	// Procedures to configure the HCLK from internal RC
#if( __CHIP_SERIES__ == __N572F065_SERIES__ )	
	//CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_XTL_32K,CLK_CLKDIV_HCLK(1));
	//CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL1_FOUT,CLK_CLKDIV_HCLK(1));
	CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL2_FOUT,CLK_CLKDIV_HCLK(1));
	//CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_RC_24M,CLK_CLKDIV_HCLK(1));
#endif
#if( __CHIP_SERIES__ == __N572F072_SERIES__ )	
	//CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_XTL_32K,CLK_CLKDIV_HCLK(1));
	//CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL1_FOUT,CLK_CLKDIV_HCLK(1));
	//CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL2_FOUT,CLK_CLKDIV_HCLK(1));
	CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_RC_48M,CLK_CLKDIV_HCLK(1));
	#endif

    /* Enable IP clock */
    CLK_EnableModuleClock(PWM_MODULE);

    /* Select PWM module clock source */
    CLK_SetModuleClock(PWM_MODULE, CLK_CLKSEL1_PWMSEL_HCLK, 0);

    /* Reset PWMA channel0~channel3 */
    SYS_ResetModule(PWM_RST);

    // Update System Core Clock
    // User can use SystemCoreClockUpdate() to calculate SystemCoreClock.
    SystemCoreClockUpdate();

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set GPB multi-function pins for PWM0 Channel0 */
	SYS->GPB_MFP  = (SYS->GPB_MFP & (~SYS_GPB_MFP_PB8MFP_Msk) ) | SYS_GPB_MFP_PB8MFP_PWM0;

    // Lock protected registers
    SYS_LockReg();

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
}

int pre_main_init (void)
{
    /* Lock protected registers */
    if(SYS->REGLCTL == 1) // In end of main function, program issued CPU reset and write-protection will be disabled.
        SYS_LockReg();

		/* Init System, IP clock and multi-function I/O
       In the end of SYS_Init() will issue SYS_LockReg()
       to lock protected register. If user want to write
       protected register, please issue SYS_UnlockReg()
       to unlock protected register if necessary */
    SYS_Init();

    /*
        PWM channel 0 waveform of this sample shown below:

         ______                      ______                      _____
      __| 50   |_______150__________| 50   |_______150__________| 50   PWM waveform

    */

		/* set PWM channel 0 output configuration */
    PWM_ConfigOutputChannel(PWM, 30000, 50, 50, 50, 50);

    /* Enable PWM Output path for PWM channel 0 */
    PWM_EnableOutput(PWM, 0);

    return 0;
}
