/*
*********************************************************************************************************
*                                     MICIRUM BOARD SUPPORT PACKAGE
*
*                             (c) Copyright 2012; Micrium, Inc.; Weston, FL
*
*               All rights reserved.  Protected by international copyright laws.
*               Knowledge of the source code may NOT be used to develop a similar product.
*               Please help us continue to provide the Embedded community with the finest
*               software available.  Your honesty is greatly appreciated.
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*
*                                        BOARD SUPPORT PACKAGE
*
*                                           megawin MG32
*                                              on the
*
*                                          MG32F02A132-EVAL
*                                          Evaluation Board
*
* Filename      : bsp.c
* Version       : V1.00
* Programmer(s) : FF
*                 MD
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                             INCLUDE FILES
*********************************************************************************************************
*/

#define   BSP_MODULE
#include  <bsp.h>

/*
*********************************************************************************************************
*                                            LOCAL DEFINES
*********************************************************************************************************
*/

////#define  BSP_GPIOC_LED1                        DEF_BIT_10       /* LED 1-3 controlled by GPIOC                          */
////#define  BSP_GPIOC_LED2                        DEF_BIT_11
////#define  BSP_GPIOC_LED3                        DEF_BIT_12
////#define  BSP_GPIOD_LED4                        DEF_BIT_02       /* LED 4 controlled by GPIOD                            */

#if defined(MG32F02A032)
    #define BSP_LED_CONFIG_PORT      IOMD
    
    #define BSP_LED_PORT             GPIOD
    #define BSP_LED_PINS_Mask        (PX_Pin_7 | PX_Pin_8 | PX_Pin_9 | PX_Pin_10)
    #define BSP_LED1_PIN_Mask        PX_Pin_7
    #define BSP_LED2_PIN_Mask        PX_Pin_8
    #define BSP_LED3_PIN_Mask        PX_Pin_9
    #define BSP_LED4_PIN_Mask        PX_Pin_10

    #define BSP_LED1_PIN             PD7
    #define BSP_LED2_PIN             PD8
    #define BSP_LED3_PIN             PD9
    #define BSP_LED4_PIN             PD10
#else
    #define BSP_LED_CONFIG_PORT      IOME
    
    #define BSP_LED_PORT             GPIOE
    #define BSP_LED_PINS_Mask        (PX_Pin_12 | PX_Pin_13 | PX_Pin_14 | PX_Pin_15)
    #define BSP_LED1_PIN_Mask        PX_Pin_12
    #define BSP_LED2_PIN_Mask        PX_Pin_13
    #define BSP_LED3_PIN_Mask        PX_Pin_14
    #define BSP_LED4_PIN_Mask        PX_Pin_15
    
    #define BSP_LED1_PIN             PE12
    #define BSP_LED2_PIN             PE13
    #define BSP_LED3_PIN             PE14
    #define BSP_LED4_PIN             PE15
#endif

#define BSP_LED_ON       1
#define BSP_LED_OFF      0

#define BSP_LED1_ON      BSP_LED1_PIN = BSP_LED_ON
#define BSP_LED2_ON      BSP_LED1_PIN = BSP_LED_ON
#define BSP_LED3_ON      BSP_LED1_PIN = BSP_LED_ON
#define BSP_LED4_ON      BSP_LED1_PIN = BSP_LED_ON
#define BSP_ALL_LED_ON   GPIO_SetPortBit(BSP_LED_PORT,BSP_LED_PINS_Mask)

#define BSP_LED1_OFF     BSP_LED1_PIN = BSP_LED_OFF
#define BSP_LED2_OFF     BSP_LED2_PIN = BSP_LED_OFF
#define BSP_LED3_OFF     BSP_LED3_PIN = BSP_LED_OFF
#define BSP_LED4_OFF     BSP_LED3_PIN = BSP_LED_OFF
#define BSP_LED_ALL_OFF  GPIO_ClearPortBit(BSP_LED_PORT,BSP_LED_PINS_Mask)

/*
*********************************************************************************************************
*                                           LOCAL CONSTANTS
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                          LOCAL DATA TYPES
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                            LOCAL TABLES
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                       LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                             REGISTERS
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                            REGISTER BITS
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                      LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/

static  void  BSP_LED_Init        (void);



/**
 *******************************************************************************
 * @brief       Resets the CSC clock configuration to the default reset state.
 * @note        The default reset state of the clock configuration is given below:
 *                - system clock source is CK_IHRCO or CK_ILRCO
 *                - PLL OFF
 *                - When CK_LS not use CK_XOSC or CK_EXT, disable both
 *                - CK_AHB, CK_APB prescaler set to 1
 *                - MCD ON
 *                - ICKO OFF
 *                - All interrupts disabled
 * @note        This function doesn't modify the configuration of the
 *                - Peripheral clocks  
 *                - CK_ILRCO, CK_LS and RTC clocks 
 * @details  
 * @param[in]   None
 * @return      None
 * @note
 * @par         Example
 * @code
    BSP_CSC_DeInit ();
 * @endcode
 *******************************************************************************
 */
void BSP_CSC_DeInit (void)
{
    // Unprotect CSC reigster
    CSC->KEY.H[0] = 0xA217;

#if defined(MG32F02A132) | defined(MG32F02A072) | defined(MA862) 
    // When CK_HS default setting CK_IHRCO
    if((CFG->OR05.W & CFG_OR05_HS_SEL_mask_w) == CFG_OR05_HS_SEL_ihrco_w)
    {   
        // When IHRCO disable
        if((CSC->CR0.W & CSC_CR0_IHRCO_EN_mask_w) == CSC_CR0_IHRCO_EN_disable_w)
        {
            // Clear IHRCOF
            CSC->STA.W = CSC_STA_IHRCOF_mask_w;
            // Enable IHRCO
            CSC->CR0.W |= CSC_CR0_IHRCO_EN_enable_w;
            // Waiting IHRCOF happened
            while((CSC->STA.W & CSC_STA_IHRCOF_mask_w)== CSC_STA_IHRCOF_normal_w);
            // Clear IHRCOF
            CSC->STA.W = CSC_STA_IHRCOF_mask_w;
        }
    }

#else
    // When CK_HS default setting CK_IHRCO
    if((CFG->OR05.W & CFG_OR05_HS_SEL_mask_w) == CFG_OR05_HS_SEL_ihrco_w)
    {
        // When IHRCO_STA not ready
        if((CSC->STA.W & CSC_STA_IHRCO_STA_mask_w) == CSC_STA_IHRCO_STA_unready_w)
        {
            // Clear IHRCOF
            CSC->STA.W = CSC_STA_IHRCOF_mask_w;
            // Enable IHRCO
            CSC->CR0.W |= CSC_CR0_IHRCO_EN_enable_w;
            // Waiting IHRCOF happened
            while((CSC->STA.W & CSC_STA_IHRCO_STA_mask_w)== CSC_STA_IHRCO_STA_unready_w);
            // Clear IHRCOF
            CSC->STA.W = CSC_STA_IHRCOF_mask_w;
        }
    }
#endif     
    
    
    
    // MCD ON
    CSC->CR0.W &= ~CSC_CR0_MCD_DIS_mask_w;
    // ICKO OFF
    CSC->CKO.W &= ~CSC_CKO_CKO_EN_mask_w;
    // All interrupts disabled
    CSC->INT.W = 0x00000000;
    // Peripheral clocks not modify
    // CK_AHB, CK_APB prescaler set to 1.
    CSC->DIV.W &= ~(CSC_DIV_APB_DIV_mask_w | CSC_DIV_AHB_DIV_mask_w);  
    
    
    // system clock source is CK_IHRCO or CK_ILRCO
#if defined(MG32F02A132) | defined(MG32F02A072) | defined(MA862) 
    // When CK_MAIN switch to CK_HS
    if((CSC->CR0.W & CSC_CR0_MAIN_SEL_mask_w) != CSC_CR0_MAIN_SEL_ck_hs_w)
    {    
        // CK_MIN = CK_HS
        CSC->CR0.W &= ~CSC_CR0_MAIN_SEL_mask_w;
        /* Delay 200us */
    }
    
    // When CK_HS default source CK_IHRCO
    if((CFG->OR05.W & CFG_OR05_HS_SEL_mask_w) == CFG_OR05_HS_SEL_ihrco_w)
    {
        // When CK_HS not CK_IHRCO
        if((CSC->CR0.W & CSC_CR0_HS_SEL_mask_w) != CSC_CR0_HS_SEL_ihrco_w)
        {   
            // CSC CK_HS = CK_IHRCO
            CSC->CR0.W &= ~CSC_CR0_HS_SEL_mask_w;
            /* Delay 200us */
        }
    }
    // When CK_HS default source CK_ILRCO
    else
    {
        // When CK_HS not CK_ILRCO
        if((CSC->CR0.W & CSC_CR0_HS_SEL_mask_w) != CSC_CR0_HS_SEL_ilrco_w)
        {
            // CSC CK_HS = CK_ILRCO
            CSC->CR0.W = (CSC->CR0.W & ~CSC_CR0_HS_SEL_mask_w) | CSC_CR0_HS_SEL_ilrco_w;
            /* Delay 200us */
        }
    }
    
#else
    // Wh// When CK_MAIN switch to CK_HS
    if((CSC->CR0.W & CSC_CR0_MAIN_SEL_mask_w) != CSC_CR0_MAIN_SEL_ck_hs_w)
    { 
        // CK_MIN = CK_HS
        CSC->CR0.W &= ~CSC_CR0_MAIN_SEL_mask_w;
        // Wait CK_MAIN to CK_HS
        while((CSC->STA.W & CSC_STA_MAIN_STA_mask_w) != CSC_STA_MAIN_STA_ck_hs_w);
    }
    
    // When CK_HS default source CK_IHRCO
    if((CFG->OR05.W & CFG_OR05_HS_SEL_mask_w) == CFG_OR05_HS_SEL_ihrco_w)
    {
        // When CK_HS not CK_IHRCO
        if((CSC->CR0.W & CSC_CR0_HS_SEL_mask_w) != CSC_CR0_HS_SEL_ihrco_w)
        {   
            // CSC CK_HS = CK_IHRCO
            CSC->CR0.W &= ~CSC_CR0_HS_SEL_mask_w;
            // Waitting CK_HS = CK_IHRCO
            while((CSC->STA.W & CSC_STA_HS_STA_mask_w) != CSC_STA_HS_STA_ihrco_w);
            
        }
    }
    // When CK_HS default source CK_ILRCO
    else
    {
        // When CK_HS not CK_ILRCO
        if((CSC->CR0.W & CSC_CR0_HS_SEL_mask_w) != CSC_CR0_HS_SEL_ilrco_w)
        {
            // CSC CK_HS = CK_IHRCO
            CSC->CR0.W = (CSC->CR0.W & ~CSC_CR0_HS_SEL_mask_w) | CSC_CR0_HS_SEL_ilrco_w;
            // Waitting CK_HS = CK_ILRCO
            while((CSC->STA.W & CSC_STA_HS_STA_mask_w) != CSC_STA_HS_STA_ilrco_w);
        }
    }
#endif
    // Disable PLL
    CSC->CR0.W &= ~CSC_CR0_PLL_EN_mask_w;
    CSC->DIV.W = CSC->DIV.W & ~(CSC_DIV_PLLI_DIV_mask_w | CSC_DIV_PLLO_DIV_mask_w);
    
    // CK_ILRCO, CK_LS, CK_UT and RTC clock not modify 
    if((CSC->CR0.W & CSC_CR0_LS_SEL_mask_w) == CSC_CR0_LS_SEL_ilrco_w)
    {
        // CK_XOSC OFF
        IOMC->CR13.W &= ~PX_CR_AFS_mask_w;
        IOMC->CR14.W &= ~PX_CR_AFS_mask_w;
    }

    // Protect CSC reigster
    CSC->KEY.H[0] = 0x0000;
}


/*
*********************************************************************************************************
*                                               BSP_Init()
*
* Description : Initialize the Board Support Package (BSP).
*
* Argument(s) : none.
*
* Return(s)   : none.
*
* Caller(s)   : Application.
*
* Note(s)     : (1) This function SHOULD be called before any other BSP function is called.
*
*               (2) CPU instruction / data tracing requires the use of the following pins :
*                   (a) (1) Aysynchronous     :  PB[3]
*                       (2) Synchronous 1-bit :  PE[3:2]
*                       (3) Synchronous 2-bit :  PE[4:2]
*                       (4) Synchronous 4-bit :  PE[6:2]
*
*                   (c) The application may wish to adjust the trace bus width depending on I/O
*                       requirements.
*********************************************************************************************************
*/

void  BSP_Init (void)
{
    CSC_PLL_TypeDef CSC_PLL_Init;

    BSP_IntInit();                                                  /*  */
    BSP_CSC_DeInit();

    UnProtectModuleReg(CSCprotect);                                 // Unprotect CSC module

    if(CSC->CR0.MBIT.HS_SEL != 0)                                   // When CK_HS != CK_IHCRO
    {
        if(CSC->CR0.MBIT.IHRCO_EN != 0)                             // When IHRCO disable
        {
            CSC_IHRCO_Select(IHRCO_12MHz);                          // CK_IHRCO = 12MHz
            CSC_IHRCO_Cmd(ENABLE);                                  // Enable IHRCO
        }
        
        while(CSC_GetSingleFlagStatus(CSC_IHRCOF) != DRV_Happened); // Wait IHRCO ready
        CSC_CK_HS_Select(HS_CK_IHRCO);                              // CK_HS source switch to CK_IHRCO
        CSC_ClearFlag(CSC_IHRCOF);                                  // Clear IHRCO ready flag
        __NOP();                                                    // Wait CK_HW switch complete
        __NOP();
        __NOP();
        __NOP();
    }

    CSC_CK_APB_Divider_Select(APB_DIV_1);                           // CK_AHB = CKAPB
    CSC_CK_AHB_Divider_Select(AHB_DIV_1);

    CSC_PLL_Init.InputDivider = PLLI_DIV_2;                         // Enable PLLO output 48KHz
  #if defined(MG32F02A132) || defined(MG32F02A072) || defined(MA862) || defined(MG32F02A032)
    CSC_PLL_Init.Multiplication = PLLIx16;
  #elif defined(MG32F02U128) || defined(MG32F02U064) || defined(MG32F02A128) || defined(MG32F02A064)
    CSC_PLL_Init.Multiplication = PLLI_CLKx16;
  #endif

    CSC_PLL_Init.OutputDivider = PLLO_DIV_2;

  #if defined(MG32F02A132) || defined(MG32F02A072) || defined(MA862) || defined(MG32F02A032)
    CSC_PLL_Config(&CSC_PLL_Init);
  #elif defined(MG32F02U128) || defined(MG32F02U064) || defined(MG32F02A128) || defined(MG32F02A064)
    CSC_PLL_Config(&CSC_PLL_Init);
  #endif

    CSC_PLL_Cmd(ENABLE);

    while(CSC_GetSingleFlagStatus(CSC_PLLF) == DRV_UnHappened);     // Wait PLL ready
    CSC_ClearFlag(CSC_PLLF);                                        // Clear PLL ready flag

    UnProtectModuleReg(MEMprotect);                                 // Set flash wait stete 1 (CK_AHB > 25MHz) 
    MEM_SetFlashWaitState(MEM_FWAIT_ONE);
    ProtectModuleReg(MEMprotect);

    CSC_CK_MAIN_Select(MAIN_CK_PLLO);                               // CK_MAIN source switch to CK_PLLO
    __NOP();
    __NOP();
    __NOP();
    __NOP();

    UnProtectModuleReg(CSCprotect);                                 // Protect CSC module

    BSP_LED_Init();                                                 /* Init LEDs. */  
}



void BSP_ClkFreq(CSC_ClockTypeDef* CSC_Clock)
{
//-----------------------------------------------------------------------------

    // IHRCO
    if((CSC->CR0.W & CSC_CR0_IHRCO_EN_mask_w) == 0)
        CSC_Clock->CK_IHRCO = 0;
    else if((CSC->CR0.W & CSC_CR0_IHRCO_SEL_mask_w) == 0)
            CSC_Clock->CK_IHRCO = 12000000UL;
        else
            CSC_Clock->CK_IHRCO = 11059200UL;

//-----------------------------------------------------------------------------

    // CK_HS
    // When CK_HS = IHRCO
    if((CSC->CR0.W & CSC_CR0_HS_SEL_mask_w) == CSC_CR0_HS_SEL_ihrco_w)
        CSC_Clock->CK_HS = CSC_Clock->CK_IHRCO;

    // When CK_HS = CK_XOSC
    else if((CSC->CR0.W & CSC_CR0_HS_SEL_mask_w) == CSC_CR0_HS_SEL_xosc_w)
        CSC_Clock->CK_HS = CONF_XOSC_EXTCK_FREQ;

    // When CK_HS = CK_XOSC
    else if((CSC->CR0.W & CSC_CR0_HS_SEL_mask_w) == CSC_CR0_HS_SEL_ilrco_w)
        CSC_Clock->CK_HS = 32000UL;

    // When CK_HS = CK_EXT
    else if((CSC->CR0.W & CSC_CR0_HS_SEL_mask_w) == CSC_CR0_HS_SEL_ck_ext_w)
        CSC_Clock->CK_HS = CONF_XOSC_EXTCK_FREQ;

//-----------------------------------------------------------------------------

    // CK_PLLO
    // When CSC PLL disable
    if((CSC->CR0.W & CSC_CR0_PLL_EN_mask_w) == 0)
        CSC_Clock->CK_PLLO = 0UL;
    else
    {
        CSC_Clock->CK_PLLO = CSC_Clock->CK_HS;
        
        // When CK_PLLI = CK_HS /1
//        if((CSC->DIV.W & CSC_DIV_PLLI_DIV_mask_w) == CSC_DIV_PLLI_DIV_div1_w) 
//            __NOP();
        // When CK_PLLI = CK_HS /2
        if((CSC->DIV.W & CSC_DIV_PLLI_DIV_mask_w) == CSC_DIV_PLLI_DIV_div2_w) 
            CSC_Clock->CK_PLLO = CSC_Clock->CK_PLLO / 2;
        // When CK_PLLI = CK_HS /4
        if((CSC->DIV.W & CSC_DIV_PLLI_DIV_mask_w) == CSC_DIV_PLLI_DIV_div4_w) 
            CSC_Clock->CK_PLLO = CSC_Clock->CK_PLLO / 4;
        // When CK_PLLI = CK_HS /6
        if((CSC->DIV.W & CSC_DIV_PLLI_DIV_mask_w) == CSC_DIV_PLLI_DIV_div6_w) 
            CSC_Clock->CK_PLLO = CSC_Clock->CK_PLLO / 6;
        
        // When CK_PLL = CK_PLLI * 16
        if((CSC->PLL.W & CSC_PLL_PLL_MUL_mask_w) == CSC_PLL_PLL_MUL_16_w) 
            CSC_Clock->CK_PLLO = CSC_Clock->CK_PLLO * 16;
        // When CK_PLL = CK_PLLI * 24
        if((CSC->PLL.W & CSC_PLL_PLL_MUL_mask_w) == CSC_PLL_PLL_MUL_24_w) 
            CSC_Clock->CK_PLLO = CSC_Clock->CK_PLLO * 24;
        
        // When CK_PLLO = CK_PLL /1
//        if((CSC->DIV.W & CSC_DIV_PLLO_DIV_mask_w) == CSC_DIV_PLLO_DIV_div1_w) 
//            __NOP();
        // When CK_PLLO = CK_PLL /2
        if((CSC->DIV.W & CSC_DIV_PLLO_DIV_mask_w) == CSC_DIV_PLLO_DIV_div2_w) 
            CSC_Clock->CK_PLLO = CSC_Clock->CK_PLLO / 2;
        // When CK_PLLO = CK_PLL /3
        if((CSC->DIV.W & CSC_DIV_PLLO_DIV_mask_w) == CSC_DIV_PLLO_DIV_div3_w) 
            CSC_Clock->CK_PLLO = CSC_Clock->CK_PLLO / 3;
        // When CK_PLLO = CK_PLL /4
        if((CSC->DIV.W & CSC_DIV_PLLO_DIV_mask_w) == CSC_DIV_PLLO_DIV_div4_w) 
            CSC_Clock->CK_PLLO = CSC_Clock->CK_PLLO / 4;
    }

//-----------------------------------------------------------------------------

    // CK_PLLO
    // When CK_MAIN = CK_HS
    if((CSC->CR0.W & CSC_CR0_MAIN_SEL_mask_w) == CSC_CR0_MAIN_SEL_ck_hs_w)
        CSC_Clock->CK_MAIN = CSC_Clock->CK_HS;

    // When CK_MAIN = CK_PLLI
    if((CSC->CR0.W & CSC_CR0_MAIN_SEL_mask_w) == CSC_CR0_MAIN_SEL_ck_plli_w)
    {
        // Get CK_HS frequency
        CSC_Clock->CK_MAIN = CSC_Clock->CK_HS;
        // When CK_PLLI = CK_HS /2
        if((CSC->DIV.W & CSC_DIV_PLLI_DIV_mask_w) == CSC_DIV_PLLI_DIV_div2_w) 
            CSC_Clock->CK_MAIN = CSC_Clock->CK_MAIN / 2;
        // When CK_PLLI = CK_HS /4
        if((CSC->DIV.W & CSC_DIV_PLLI_DIV_mask_w) == CSC_DIV_PLLI_DIV_div4_w) 
            CSC_Clock->CK_MAIN = CSC_Clock->CK_MAIN / 4;
        // When CK_PLLI = CK_HS /6
        if((CSC->DIV.W & CSC_DIV_PLLI_DIV_mask_w) == CSC_DIV_PLLI_DIV_div6_w) 
            CSC_Clock->CK_MAIN = CSC_Clock->CK_MAIN / 6;
    }

    // When CK_MAIN = CK_PLLO
    if((CSC->CR0.W & CSC_CR0_MAIN_SEL_mask_w) == CSC_CR0_MAIN_SEL_ck_pllo_w)
        // Return CK_PLLO frequency 
        CSC_Clock->CK_MAIN = CSC_Clock->CK_PLLO;  

//-----------------------------------------------------------------------------

    // CK_APB
    // Get CK_MAIN frequency and divider APB
    CSC_Clock->CK_APB = CSC_Clock->CK_MAIN >> CSC->DIV.MBIT.APB_DIV;

//-----------------------------------------------------------------------------

    // CK_AHB
    CSC_Clock->CK_AHB = CSC_Clock->CK_APB >> CSC->DIV.MBIT.AHB_DIV;

//-----------------------------------------------------------------------------
}



/*
*********************************************************************************************************
*                                            BSP_CPU_ClkFreq()
*
* Description : Read CPU registers to determine the CPU clock frequency of the chip.
*
* Argument(s) : none.
*
* Return(s)   : The CPU clock frequency, in Hz.
*
* Caller(s)   : Application.
*
* Note(s)     : none.
*********************************************************************************************************
*/

CPU_INT32U  BSP_CPU_ClkFreq (void)
{
    CSC_ClockTypeDef lCSC_Clock;

    BSP_ClkFreq(&lCSC_Clock);

    return ((CPU_INT32U)lCSC_Clock.CK_AHB);
}

/*
*********************************************************************************************************
*                                           BSP_LED_Init()
*
* Description : Initialize any or all the LEDs on the board.
*
* Argument(s) : led     The ID of the LED to control:
*
*                       0    inialize ALL  LEDs
*                       1    inialize user LED1
*                       2    inialize user LED2
*                       3    inialize user LED3
*                       4    inialize user LED4
*
* Return(s)   : none.
*
* Caller(s)   : Application.
*
* Note(s)     : none.
*********************************************************************************************************
*/
static void  BSP_LED_Init(void)
{
    PIN_InitTypeDef PINX_InitStruct;

    BSP_PeriphEn(BSP_PERIPH_ID_IOPEEN);

    PINX_InitStruct.PINX_Pin                = BSP_LED_PINS_Mask;

    PINX_InitStruct.PINX_Mode               = PINX_Mode_PushPull_O;
    PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Disable;
    PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;
    PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;
    PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;
    PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;
    PINX_InitStruct.PINX_Alternate_Function = 0;
    GPIO_PortMode_Config(BSP_LED_CONFIG_PORT,&PINX_InitStruct);
}



/*
*********************************************************************************************************
*                                             BSP_LED_On()
*
* Description : Turn ON any or all the LEDs on the board.
*
* Argument(s) : led     The ID of the LED to control:
*
*                       0    turns ON ALL  LEDs
*                       1    turns ON user LED1
*                       2    turns ON user LED2
*                       3    turns ON user LED3
*                       4    turns ON user LED4
*
* Return(s)   : none.
*
* Caller(s)   : Application.
*
* Note(s)     : none.
*********************************************************************************************************
*/

void BSP_LED_On(CPU_INT08U  led)
{
    switch(led)
    {
        case 0:
                BSP_ALL_LED_ON;
        case 1:
                BSP_LED1_ON;
                break;
        case 2:
                BSP_LED2_ON;
                break;
        case 3:
                BSP_LED3_ON;
                break;
        case 4:
                BSP_LED4_ON;
                break;
        default:
                break;
    }
}



/*
*********************************************************************************************************
*                                              BSP_LED_Off()
*
* Description : Turn OFF any or all the LEDs on the board.
*
* Argument(s) : led     The ID of the LED to control:
*
*                       0    turns OFF ALL the LEDs
*                       1    turns OFF user LED1
*                       2    turns OFF user LED2
*                       3    turns OFF user LED3
*                       4    turns OFF user LED4
*
* Return(s)   : none.
*
* Caller(s)   : Application.
*
* Note(s)     : none.
*********************************************************************************************************
*/
void  BSP_LED_Off(CPU_INT08U led)
{
    switch(led)
    {
        case 0:
                BSP_LED_ALL_OFF;
                break;
        case 1:
                BSP_LED1_OFF;
                break;
        case 2:
                BSP_LED2_OFF;
                break;
        case 3:
                BSP_LED3_OFF;
                break;
        case 4:
                BSP_LED4_OFF;
                break;
        default:
                break;
    }
}


/*
*********************************************************************************************************
*                                            BSP_LED_Toggle()
*
* Description : TOGGLE any or all the LEDs on the board.
*
* Argument(s) : led     The ID of the LED to control:
*
*                       0    TOGGLE ALL the LEDs
*                       1    TOGGLE user LED1
*                       2    TOGGLE user LED2
*                       3    TOGGLE user LED3
*                       4    TOGGLE user LED4
*
* Return(s)   : none.
*
* Caller(s)   : Application.
*
* Note(s)     : none.
*********************************************************************************************************
*/

void  BSP_LED_Toggle (CPU_INT08U  led)
{
    CPU_INT32U pins;
    
    switch(led)
    {
        case 0:
                pins = GPIO_ReadPort(BSP_LED_PORT);
                pins ^= BSP_LED_PINS_Mask;
        
                GPIO_SetClearPortBit( BSP_LED_PORT , (pins & BSP_LED_PINS_Mask) , ((~pins) & BSP_LED_PINS_Mask));
                break;
        case 1:
                pins = GPIO_ReadPort(BSP_LED_PORT);
                pins ^= BSP_LED1_PIN_Mask;
                
                GPIO_SetClearPortBit( BSP_LED_PORT , (pins & BSP_LED1_PIN_Mask) , ((~pins) & BSP_LED1_PIN_Mask));
                break;
        case 2:
                pins = GPIO_ReadPort(BSP_LED_PORT);
                pins ^= BSP_LED2_PIN_Mask;
                
                GPIO_SetClearPortBit( BSP_LED_PORT , (pins & BSP_LED2_PIN_Mask) , ((~pins) & BSP_LED2_PIN_Mask));
                break;
        case 3:
                pins = GPIO_ReadPort(BSP_LED_PORT);
                pins ^= BSP_LED3_PIN_Mask;
                
                GPIO_SetClearPortBit( BSP_LED_PORT , (pins & BSP_LED3_PIN_Mask) , ((~pins) & BSP_LED3_PIN_Mask));
                break;
        case 4:
                pins = GPIO_ReadPort(BSP_LED_PORT);
                pins ^= BSP_LED4_PIN_Mask;
                
                GPIO_SetClearPortBit( BSP_LED_PORT , (pins & BSP_LED4_PIN_Mask) , ((~pins) & BSP_LED4_PIN_Mask));
                break;
        default:
                break;
    }
}


/*$PAGE*/
/*
*********************************************************************************************************
*                                          CPU_TS_TmrInit()
*
* Description : Initialize & start CPU timestamp timer.
*
* Argument(s) : none.
*
* Return(s)   : none.
*
* Caller(s)   : CPU_TS_Init().
*
*               This function is an INTERNAL CPU module function & MUST be implemented by application/
*               BSP function(s) [see Note #1] but MUST NOT be called by application function(s).
*
* Note(s)     : (1) CPU_TS_TmrInit() is an application/BSP function that MUST be defined by the developer
*                   if either of the following CPU features is enabled :
*
*                   (a) CPU timestamps
*                   (b) CPU interrupts disabled time measurements
*
*                   See 'cpu_cfg.h  CPU TIMESTAMP CONFIGURATION  Note #1'
*                     & 'cpu_cfg.h  CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION  Note #1a'.
*
*               (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR'
*                       data type.
*
*                       (1) If timer has more bits, truncate timer values' higher-order bits greater
*                           than the configured 'CPU_TS_TMR' timestamp timer data type word size.
*
*                       (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR'
*                           timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be
*                           configured so that ALL bits in 'CPU_TS_TMR' data type are significant.
*
*                           In other words, if timer size is not a binary-multiple of 8-bit octets
*                           (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple
*                           octet word size SHOULD be configured (e.g. to 16-bits).  However, the
*                           minimum supported word size for CPU timestamp timers is 8-bits.
*
*                       See also 'cpu_cfg.h   CPU TIMESTAMP CONFIGURATION  Note #2'
*                              & 'cpu_core.h  CPU TIMESTAMP DATA TYPES     Note #1'.
*
*                   (b) Timer SHOULD be an 'up'  counter whose values increase with each time count.
*
*                   (c) When applicable, timer period SHOULD be less than the typical measured time
*                       but MUST be less than the maximum measured time; otherwise, timer resolution
*                       inadequate to measure desired times.
*
*                   See also 'CPU_TS_TmrRd()  Note #2'.
*********************************************************************************************************
*/

#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
void  CPU_TS_TmrInit (void)
{

}
#endif


/*$PAGE*/
/*
*********************************************************************************************************
*                                           CPU_TS_TmrRd()
*
* Description : Get current CPU timestamp timer count value.
*
* Argument(s) : none.
*
* Return(s)   : Timestamp timer count (see Notes #2a & #2b).
*
* Caller(s)   : CPU_TS_Init(),
*               CPU_TS_Get32(),
*               CPU_TS_Get64(),
*               CPU_IntDisMeasStart(),
*               CPU_IntDisMeasStop().
*
*               This function is an INTERNAL CPU module function & MUST be implemented by application/
*               BSP function(s) [see Note #1] but SHOULD NOT be called by application function(s).
*
* Note(s)     : (1) CPU_TS_TmrRd() is an application/BSP function that MUST be defined by the developer
*                   if either of the following CPU features is enabled :
*
*                   (a) CPU timestamps
*                   (b) CPU interrupts disabled time measurements
*
*                   See 'cpu_cfg.h  CPU TIMESTAMP CONFIGURATION  Note #1'
*                     & 'cpu_cfg.h  CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION  Note #1a'.
*
*               (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR'
*                       data type.
*
*                       (1) If timer has more bits, truncate timer values' higher-order bits greater
*                           than the configured 'CPU_TS_TMR' timestamp timer data type word size.
*
*                       (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR'
*                           timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be
*                           configured so that ALL bits in 'CPU_TS_TMR' data type are significant.
*
*                           In other words, if timer size is not a binary-multiple of 8-bit octets
*                           (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple
*                           octet word size SHOULD be configured (e.g. to 16-bits).  However, the
*                           minimum supported word size for CPU timestamp timers is 8-bits.
*
*                       See also 'cpu_cfg.h   CPU TIMESTAMP CONFIGURATION  Note #2'
*                              & 'cpu_core.h  CPU TIMESTAMP DATA TYPES     Note #1'.
*
*                   (b) Timer SHOULD be an 'up'  counter whose values increase with each time count.
*
*                       (1) If timer is a 'down' counter whose values decrease with each time count,
*                           then the returned timer value MUST be ones-complemented.
*
*                   (c) (1) When applicable, the amount of time measured by CPU timestamps is
*                           calculated by either of the following equations :
*
*                           (A) Time measured  =  Number timer counts  *  Timer period
*
*                                   where
*
*                                       Number timer counts     Number of timer counts measured
*                                       Timer period            Timer's period in some units of
*                                                                   (fractional) seconds
*                                       Time measured           Amount of time measured, in same
*                                                                   units of (fractional) seconds
*                                                                   as the Timer period
*
*                                                  Number timer counts
*                           (B) Time measured  =  ---------------------
*                                                    Timer frequency
*
*                                   where
*
*                                       Number timer counts     Number of timer counts measured
*                                       Timer frequency         Timer's frequency in some units
*                                                                   of counts per second
*                                       Time measured           Amount of time measured, in seconds
*
*                       (2) Timer period SHOULD be less than the typical measured time but MUST be less
*                           than the maximum measured time; otherwise, timer resolution inadequate to
*                           measure desired times.
*********************************************************************************************************
*/

#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
CPU_TS_TMR  CPU_TS_TmrRd (void)
{
    CPU_TS_TMR  ts_tmr_cnts;


    ts_tmr_cnts = 0u;

    return (ts_tmr_cnts);
}
#endif


/*$PAGE*/
/*
*********************************************************************************************************
*                                         CPU_TSxx_to_uSec()
*
* Description : Convert a 32-/64-bit CPU timestamp from timer counts to microseconds.
*
* Argument(s) : ts_cnts   CPU timestamp (in timestamp timer counts [see Note #2aA]).
*
* Return(s)   : Converted CPU timestamp (in microseconds           [see Note #2aD]).
*
* Caller(s)   : Application.
*
*               This function is an (optional) CPU module application programming interface (API)
*               function which MAY be implemented by application/BSP function(s) [see Note #1] &
*               MAY be called by application function(s).
*
* Note(s)     : (1) CPU_TS32_to_uSec()/CPU_TS64_to_uSec() are application/BSP functions that MAY be
*                   optionally defined by the developer when either of the following CPU features is
*                   enabled :
*
*                   (a) CPU timestamps
*                   (b) CPU interrupts disabled time measurements
*
*                   See 'cpu_cfg.h  CPU TIMESTAMP CONFIGURATION  Note #1'
*                     & 'cpu_cfg.h  CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION  Note #1a'.
*
*               (2) (a) The amount of time measured by CPU timestamps is calculated by either of
*                       the following equations :
*
*                                                                        10^6 microseconds
*                       (1) Time measured  =   Number timer counts   *  -------------------  *  Timer period
*                                                                            1 second
*
*                                              Number timer counts       10^6 microseconds
*                       (2) Time measured  =  ---------------------  *  -------------------
*                                                Timer frequency             1 second
*
*                               where
*
*                                   (A) Number timer counts     Number of timer counts measured
*                                   (B) Timer frequency         Timer's frequency in some units
*                                                                   of counts per second
*                                   (C) Timer period            Timer's period in some units of
*                                                                   (fractional)  seconds
*                                   (D) Time measured           Amount of time measured,
*                                                                   in microseconds
*
*                   (b) Timer period SHOULD be less than the typical measured time but MUST be less
*                       than the maximum measured time; otherwise, timer resolution inadequate to
*                       measure desired times.
*
*                   (c) Specific implementations may convert any number of CPU_TS32 or CPU_TS64 bits
*                       -- up to 32 or 64, respectively -- into microseconds.
*********************************************************************************************************
*/

#if (CPU_CFG_TS_32_EN == DEF_ENABLED)
CPU_INT64U  CPU_TS32_to_uSec (CPU_TS32  ts_cnts)                /* 32-bit conversion                                    */
{
    CPU_INT64U  ts_us;
    CPU_INT64U  fclk_freq;


    fclk_freq = BSP_CPU_ClkFreq();
    ts_us     = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC);

    return (ts_us);
}
#endif


#if (CPU_CFG_TS_64_EN == DEF_ENABLED)
CPU_INT64U  CPU_TS64_to_uSec (CPU_TS64  ts_cnts)                /* 64-bit conversion                                    */
{
    CPU_INT64U  ts_us;
    CPU_INT64U  fclk_freq;


    fclk_freq = BSP_CPU_ClkFreq();
    ts_us     = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC);

    return (ts_us);
}
#endif
