

/**
 ******************************************************************************
 *
 * @file        BSP.C
 * @brief       BLE_MG126 BSP c Code. 
 *
 * @par         Project
 *              MG32
 * @version     V1.04
 * @date        2021/06/23
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2020 MegaWin Technology Co., Ltd.
 *              All rights reserved.
 *
 ******************************************************************************* 
 * @par Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 *******************************************************************************
 *******************************************************************************
 */
 

#include "BSP.h"
#include "mg_api.h"
#include "MG32_CSC_Init.h"

void BLE_EXIC_Init(void);
void EXINT1_IRQHandler(void);
void BLE_URT0_Init(void);
void IWDT_Init(void);
void BLE_SPI_Init(void);
void BLE_LED_Init(void);
void LED_Flash(void);
void BSP_Init(void);
char IsIrqEnabled(void); //porting api
void IrqMcuGotoSleepAndWakeup(void);
unsigned int GetSysTickCount(void); //porting api
void SysTick_Handler(void);

/**
 *******************************************************************************
 * @brief       EXIC module initial for BLE
 * @details
 * @return      None
 * @note        Used pin
 *                  PB10 AFS GPB10 (EXIC Interrupt)
 * @par         Example
 * @code
    EXIC_Init();
 * @endcode
 *******************************************************************************
 */
void BLE_EXIC_Init(void)
{
    PIN_InitTypeDef  PINX_InitStruct;
    EXIC_TRGSTypeDef EXIC_TRGS;
    
    UnProtectModuleReg(CSCprotect);                                         // Unprotect CSC module register
    CSC_PeriphOnModeClock_Config(CSC_ON_PortB,ENABLE);                      // Emable port B moudle clock
    ProtectModuleReg(CSCprotect);                                           // Protect CSC module register
    
    //====GPIO Initial==== 
//    PINX_InitStruct.PINX_Pin                = PX_Pin;                       // Select Pin of the port to initial (PX_Pin_All is all pin of the port.)
    PINX_InitStruct.PINX_Mode               = PINX_Mode_Digital_I;          // Select GPIO mode 
                                                                            //     1.QB: Quasi-Bidirection mode only for PC ) 
    PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;      // Select wether enable internal pull-up R or not.
    PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;               // Select wehter enable high speed mode
                                                                            //     1.(PINX_Speed_High mode only for PC0~3 , PD0~3 )    
    PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;         // Select output drive strength 
                                                                            //     1.(Level 0 & level 3 only for PE0~PE3)
    PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;    // Select input filter divider.
    PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;         // Select input signal whether inverse or not.
                                                                            //     1.PINX_Inverse_Disable = L level or falling edge.
                                                                            //     2.PINX_Inverse_Enable  = H level or Rising edge.
    PINX_InitStruct.PINX_Alternate_Function = 0;                            // Select GPIO mode
//    GPIO_PortMode_Config(IOMB, &PINX_InitStruct);                            // (Pin0 & Pin1) of PorA configuration // Initial PortA
    GPIO_PinMode_Config(EXIC_CFG_PIN,&PINX_InitStruct);
    
    //====EXIC Initial====                                   
    EXIC_TRGS.EXIC_Pin = EXIC_TRGS_PINX;    //1. You can select any pin of the port.
    EXIC_TRGS.EXIC_TRGS_Mode = Edge;                                        // External interrupt pin edge/level trigger event select.
    EXIC_PxTriggerMode_Select(EXIC_PB,&EXIC_TRGS);                          // EXIC trigger mode configuration.
    
    EXIC_PxTriggerAndMask_Select(EXIC_PB , EXIC_PX_AND_MASK_PINX);          // EXIC_PA  AF trigger event select.
                                                                            //     1. Select PA_AF trigger pin(PA0, PA1).
                                                                            //     2. PA_AF is set if trigger event of select pin have to happen at same time(PA0 & PA1).  
    EXIC_PxTriggerOrMask_Select(EXIC_PB  , EXIC_PX_OR_MASK_PINX);           // EXIC_PA  OF trigger event select.
                                                                            //     1. Select PA_OF trigger pin(PA2, PA3).
                                                                            //     2. PA_OF is set if anyone trigger event of select pin happen(PA2 | PA3).   
    EXIC_ClearPxTriggerEventFlag(EXIC_PB, EXIC_PX_PINX );                   // Clear All pin of the port event flag.    
    
    EXIC_PxTriggerITEA_Cmd(EXIC_PB_IT , ENABLE);                            // Enable EXIC interrupt
    NVIC_EnableIRQ(EXINT1_IRQn);                                            // Enable EXIC interrupt of NVIC
}


/**
 *******************************************************************************
 * @brief       EXINT1 IRQ Handler
 * @details
 * @return      None
 * @note        ble has used, modify code must be careful
 * @par         Example
 * @code

 * @endcode
 *******************************************************************************
 */
void EXINT1_IRQHandler(void)
{
   EXIC_ClearPxTriggerEventFlag(EXIC_PB, EXIC_PX_PINX );            // Clear 
   EXIC_ClearPxTriggerITFlag(EXIC_PB_ITF,EXIC_PX_OF | EXIC_PX_AF);
   ble_run(0);
}


/**
 *******************************************************************************
 * @brief       UART0 module initial for BLE
 * @details
 * @return      None
 * @note        Used pins
 *                  PB8  AFS URT0_TX
 *                  PB9  AFS URT0_RX
 * @par         Example
 * @code
    BLE_URT0_Init();
 * @endcode
 *******************************************************************************
 */
void BLE_URT0_Init(void)
{
    URT_BRG_TypeDef  URT_BRG;
    URT_Data_TypeDef DataDef;
    PIN_InitTypeDef PINX_InitStruct;

    UnProtectModuleReg(CSCprotect);                                         // Unprottect CSC Module Register
    CSC_PeriphProcessClockSource_Config(CSC_UART0_CKS, CK_APB);             // UART0 process clock select CK_APB
    CSC_PeriphOnModeClock_Config(CSC_ON_UART0,ENABLE);                      // UART0 module clock enable
    CSC_PeriphOnModeClock_Config(CSC_ON_PortB,ENABLE);                      // Port B module clock enable
    ProtectModuleReg(CSCprotect);                                           // Prottect CSC Module Register

    //==Set GPIO init
    //PB8 PPO TX ,PB9 ODO RX
    PINX_InitStruct.PINX_Mode                = PINX_Mode_PushPull_O;        // Pin select Push Pull mode
    PINX_InitStruct.PINX_PUResistant         = PINX_PUResistant_Enable;     // Enable pull up resistor
    PINX_InitStruct.PINX_Speed               = PINX_Speed_Low;              // Pin output low speed mode
    PINX_InitStruct.PINX_OUTDrive            = PINX_OUTDrive_Level0;        // Pin output driver full strength.
    PINX_InitStruct.PINX_FilterDivider       = PINX_FilterDivider_Bypass;   // Pin input deglitch filter clock divider bypass
    PINX_InitStruct.PINX_Inverse             = PINX_Inverse_Disable;        // Pin input data not inverse
    PINX_InitStruct.PINX_Alternate_Function  = 3;                           // Pin AFS = URT0_TX
    GPIO_PinMode_Config(PINB(8),&PINX_InitStruct);                          // TXD(MOSI) at PB8

    PINX_InitStruct.PINX_Mode                = PINX_Mode_OpenDrain_O;       // Pin select Open Drain mode
    PINX_InitStruct.PINX_Alternate_Function  = 3;                           // Pin AFS = URT0_RX
    GPIO_PinMode_Config(PINB(9),&PINX_InitStruct);                          // RXD(MISO) at PB9  

    //=====Set Clock=====//
    //---Set BaudRate---//
    URT_BRG.URT_InternalClockSource = URT_BDClock_PROC;         //
    URT_BRG.URT_BaudRateMode = URT_BDMode_Separated;            //
    URT_BRG.URT_PrescalerCounterReload = 0;                     // Set PSR
    URT_BRG.URT_BaudRateCounterReload = 12;                     // Set RLR
    URT_BaudRateGenerator_Config(URT0, &URT_BRG);               // BR115200 = f(CK_URTx)/(PSR+1)/(RLR+1)/(OS_NUM+1)
    URT_BaudRateGenerator_Cmd(URT0, ENABLE);                    // Enable BaudRateGenerator
    //---TX/RX Clock---//
    URT_TXClockSource_Select(URT0, URT_TXClock_Internal);       // URT_TX use BaudRateGenerator
    URT_RXClockSource_Select(URT0, URT_RXClock_Internal);       // URT_RX use BaudRateGenerator
    URT_TXOverSamplingSampleNumber_Select(URT0, 7);	            // Set TX OS_NUM
    URT_RXOverSamplingSampleNumber_Select(URT0, 7);	            // Set RX OS_NUM
    URT_RXOverSamplingMode_Select(URT0, URT_RXSMP_3TIME);
    URT_TX_Cmd(URT0, ENABLE);                                   // Enable TX
    URT_RX_Cmd(URT0, ENABLE);                                   // Enable RX
    

    //=====Set Mode=====//
    //---Set Data character config---//
    DataDef.URT_TX_DataLength  = URT_DataLength_8;              //
    DataDef.URT_RX_DataLength  = URT_DataLength_8;              //
    DataDef.URT_TX_DataOrder   = URT_DataTyped_LSB;             // UART SPI Data Mode
    DataDef.URT_RX_DataOrder   = URT_DataTyped_LSB;             // UART SPI Data Mode
    DataDef.URT_TX_Parity      = URT_Parity_No;                 //
    DataDef.URT_RX_Parity      = URT_Parity_No;                 //
    DataDef.URT_TX_StopBits    = URT_StopBits_1_0;              //
    DataDef.URT_RX_StopBits    = URT_StopBits_1_0;              //
    DataDef.URT_TX_DataInverse = DISABLE;                       //
    DataDef.URT_RX_DataInverse = DISABLE;                       //
    URT_DataCharacter_Config(URT0, &DataDef);                   //
    //---Set Mode Select---//
    URT_Mode_Select(URT0, URT_URT_mode);                        // 
    //---Set DataLine Select---//
    URT_DataLine_Select(URT0, URT_DataLine_2);                  // 
    
    //=====Set Data Control=====//
    URT_RXShadowBufferThreshold_Select(URT0, URT_RXTH_1BYTE);   //
    URT_IdlehandleMode_Select(URT0, URT_IDLEMode_No);           //
    URT_TXGuardTime_Select(URT0, 0);                            //
    
    //=====Enable URT Interrupt=====//
    URT_IT_Config(URT0, URT_IT_RX | URT_IT_TC, ENABLE);         // Enable UART0 URT_IT_RX and URT_IT_TC interrupt
    URT_ITEA_Cmd(URT0, ENABLE);                                 // Enable UART0 interrupt all enable 
    NVIC_EnableIRQ(URT0_IRQn);                                  // Enable UART0 interrupt of NVIC
    
    //=====Enable URT=====//
    URT_Cmd(URT0, ENABLE);                                      // Enable UART0 module
}


/**
 *******************************************************************************
 * @brief       IWDT module initial
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    IWDT_Init();
 * @endcode
 *******************************************************************************
 */
void IWDT_Init(void)
{
    /*=== 1. Configure IWDT clock ===*/
    UnProtectModuleReg(IWDTprotect);                                // Unprotect IWDT module
    IWDT_Divider_Select(IWDT_DIV_128);                              // DIV output = CK_IWDT /128

    /*=== 2. Configure RST module ===*/                         
    UnProtectModuleReg(RSTprotect);                                 // Unprotect RST moduel register
    RST_WRstSource_Config(RST_IWDT_WE, ENABLE);                     // Enable IWDT event trigger warm reset
    ProtectModuleReg(RSTprotect);                                   // Protect RST moduel register

    IWDT_IT_Config(IWDT_INT_TF, ENABLE);                            // Enable IWDT timeout interupt 
    NVIC_EnableIRQ(SYS_IRQn);
    SYS_ITEA_Cmd(ENABLE);                                           // Enable SYS interupt in NVIC
    IWDT_ClearFlag(IWDT_TF);                                        // Clear IWDT timeout flag

    /*=== 3. Enable IWDT module ===*/
    IWDT_Cmd(ENABLE);                                               // Enable IWDT module
    ProtectModuleReg(IWDTprotect);                                  // Protect IWDT module
    
    /*=== 4. Check flag action ===*/
    while(IWDT_GetSingleFlagStatus(IWDT_EW1F) == DRV_UnHappened);   // Wait IWDT early wakeup-1 happened
    IWDT_ClearFlag(IWDT_EW1F);                                      // Clear EW1F flag 
    
    while(IWDT_GetSingleFlagStatus(IWDT_EW0F) == DRV_UnHappened);   // Wait IWDT early wakeup-0 happened
    IWDT_ClearFlag(IWDT_EW0F);                                      // Clear EW0F flag

    IWDT_RefreshCounter();                                          // Clear IWDT timer
}


/**
 *******************************************************************************
 * @brief       SPI0 module initial for BLE
 * @details
 * @return      None
 * @note        Used pins
 *                  PB0  AFS GPB0 (Software NSS)
 *                  PB1  AFS SPI0_MISO
 *                  PB2  AFS SPI0_CLK
 *                  PB3  AFS SPI0_MOSI
 * @par         Example
 * @code
    BLE_SPI_Init();
 * @endcode
 *******************************************************************************
 */
void BLE_SPI_Init(void)
{
    PIN_InitTypeDef PINX_InitStruct;

    
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wunreachable-code"
    /*=== 1. Config SPI0 IO ===*/
    if(&BLE_MODULE->STA.W == &SPI0->STA.W)
    {
        // For SPI0 pins setting
        PINX_InitStruct.PINX_Mode               = PINX_Mode_PushPull_O;     // Pin select pusu pull mode
        PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;  // Enable pull up resistor
        PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;           // Pin output low speed mode
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;     // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;     // Pin input data not inverse
        PINX_InitStruct.PINX_Alternate_Function = 2;                        // Pin AFS = 2
        GPIO_PinMode_Config(PINB(2),&PINX_InitStruct);                      // CLK setup at PB2
        
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level2;     // Pin output drive strength 1/4
        GPIO_PinMode_Config(PINB(3),&PINX_InitStruct);                      // MOSI setup at PB3
        
        PINX_InitStruct.PINX_Alternate_Function = 0;                        // Pin AFS = 0
        GPIO_PinMode_Config(PINB(0),&PINX_InitStruct);                      // NSS setup at PB0
        
        PINX_InitStruct.PINX_Mode               = PINX_Mode_Digital_I;      // Setting digital  mode
        PINX_InitStruct.PINX_Alternate_Function = 2;                        // Pin AFS = 2
        GPIO_PinMode_Config(PINB(1),&PINX_InitStruct);  
    }
    else
    {
#if defined(MG32_1ST)
        // For URT1 pins setting
        PINX_InitStruct.PINX_Mode               = PINX_Mode_PushPull_O;     // Pin select pusu pull mode
        PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;  // Enable pull up resistor
        PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;           // Pin output low speed mode
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;     // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;     // Pin input data not inverse
        PINX_InitStruct.PINX_Alternate_Function = 3;                        // Pin AFS = 9
        GPIO_PinMode_Config(PIND(2),&PINX_InitStruct);                      // CLK setup at PD2
        
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level2;     // Pin output drive strength 1/4
        GPIO_PinMode_Config(PIND(4),&PINX_InitStruct);                      // MOSI setup at PD4
        
        PINX_InitStruct.PINX_Alternate_Function = 0;                        // Pin AFS = 0
        GPIO_PinMode_Config(PIND(6),&PINX_InitStruct);                      // NSS setup at PD6
        
        PINX_InitStruct.PINX_Mode               = PINX_Mode_Digital_I;      // Setting digital  mode
        PINX_InitStruct.PINX_Alternate_Function = 3;                        // Pin AFS = 2
        GPIO_PinMode_Config(PIND(5),&PINX_InitStruct);                      // MISO setup at D5
#endif

#if defined(MG32_2ND)
        // For URT1 pins setting
        PINX_InitStruct.PINX_Mode               = PINX_Mode_PushPull_O;     // Pin select pusu pull mode
        PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;  // Enable pull up resistor
        PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;           // Pin output low speed mode
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;     // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;     // Pin input data not inverse
        PINX_InitStruct.PINX_Alternate_Function = 4;                        // Pin AFS = 9
        GPIO_PinMode_Config(PINC(3),&PINX_InitStruct);                      // CLK setup at PC3
        
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level2;     // Pin output drive strength 1/4
        GPIO_PinMode_Config(PINC(8),&PINX_InitStruct);                      // MOSI setup at PC8
        
        PINX_InitStruct.PINX_Alternate_Function = 0;                        // Pin AFS = 0
        GPIO_PinMode_Config(PINC(13),&PINX_InitStruct);                      // NSS setup at PC13
        
        PINX_InitStruct.PINX_Mode               = PINX_Mode_Digital_I;      // Setting digital  mode
        PINX_InitStruct.PINX_Alternate_Function = 4;                        // Pin AFS = 2
        GPIO_PinMode_Config(PINC(9),&PINX_InitStruct);                      // MISO setup at PC9
#endif

#if defined(MG32_3RD)
        // For URT1 pins setting
        PINX_InitStruct.PINX_Mode               = PINX_Mode_PushPull_O;     // Pin select pusu pull mode
        PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;  // Enable pull up resistor
        PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;           // Pin output low speed mode
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;     // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;     // Pin input data not inverse

        PINX_InitStruct.PINX_Alternate_Function = 4;                        // Pin AFS = 4
        GPIO_PinMode_Config(PINC(3),&PINX_InitStruct);                      // CLK at PC3
        
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level2;     // Pin output drive strength 1/4
        GPIO_PinMode_Config(PINC(8),&PINX_InitStruct);                      // MOSI at PC8
        
        PINX_InitStruct.PINX_Alternate_Function = 0;                        // Pin AFS = 0
        GPIO_PinMode_Config(PINC(7),&PINX_InitStruct);                      // NSS at PC7
        
        PINX_InitStruct.PINX_Mode               = PINX_Mode_Digital_I;      // Setting digital  mode
        PINX_InitStruct.PINX_Alternate_Function = 4;                        // Pin AFS = 2
        GPIO_PinMode_Config(PINC(9),&PINX_InitStruct);                      // MISO at PC9
#endif
    }
    #pragma clang diagnostic pop
#else
    
    /*=== 1. Config SPI0 IO ===*/
    if(&BLE_MODULE->STA.W == &SPI0->STA.W)
    {
        // For SPI0 pins setting
        PINX_InitStruct.PINX_Mode               = PINX_Mode_PushPull_O;     // Pin select pusu pull mode
        PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;  // Enable pull up resistor
        PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;           // Pin output low speed mode
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;     // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;     // Pin input data not inverse
        PINX_InitStruct.PINX_Alternate_Function = 2;                        // Pin AFS = 2
        GPIO_PinMode_Config(PINB(2),&PINX_InitStruct);                      // CLK setup at PB2
        
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level2;     // Pin output drive strength 1/4
        GPIO_PinMode_Config(PINB(3),&PINX_InitStruct);                      // MOSI setup at PB3
        
        PINX_InitStruct.PINX_Alternate_Function = 0;                        // Pin AFS = 0
        GPIO_PinMode_Config(PINB(0),&PINX_InitStruct);                      // NSS setup at PB0
        
        PINX_InitStruct.PINX_Mode               = PINX_Mode_Digital_I;      // Setting digital  mode
        PINX_InitStruct.PINX_Alternate_Function = 2;                        // Pin AFS = 2
        GPIO_PinMode_Config(PINB(1),&PINX_InitStruct);  
    }
    else
    {
#if defined(MG32_1ST)
        // For URT1 pins setting
        PINX_InitStruct.PINX_Mode               = PINX_Mode_PushPull_O;     // Pin select pusu pull mode
        PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;  // Enable pull up resistor
        PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;           // Pin output low speed mode
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;     // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;     // Pin input data not inverse
        PINX_InitStruct.PINX_Alternate_Function = 3;                        // Pin AFS = 9
        GPIO_PinMode_Config(PIND(2),&PINX_InitStruct);                      // CLK setup at PD2
        
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level2;     // Pin output drive strength 1/4
        GPIO_PinMode_Config(PIND(4),&PINX_InitStruct);                      // MOSI setup at PD4
        
        PINX_InitStruct.PINX_Alternate_Function = 0;                        // Pin AFS = 0
        GPIO_PinMode_Config(PIND(6),&PINX_InitStruct);                      // NSS setup at PD6
        
        PINX_InitStruct.PINX_Mode               = PINX_Mode_Digital_I;      // Setting digital  mode
        PINX_InitStruct.PINX_Alternate_Function = 3;                        // Pin AFS = 2
        GPIO_PinMode_Config(PIND(5),&PINX_InitStruct);                      // MISO setup at D5
#endif

#if defined(MG32_2ND)
        // For URT1 pins setting
        PINX_InitStruct.PINX_Mode               = PINX_Mode_PushPull_O;     // Pin select pusu pull mode
        PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;  // Enable pull up resistor
        PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;           // Pin output low speed mode
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;     // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;     // Pin input data not inverse
        PINX_InitStruct.PINX_Alternate_Function = 4;                        // Pin AFS = 9
        GPIO_PinMode_Config(PINC(3),&PINX_InitStruct);                      // CLK setup at PC3
        
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level2;     // Pin output drive strength 1/4
        GPIO_PinMode_Config(PINC(8),&PINX_InitStruct);                      // MOSI setup at PC8
        
        PINX_InitStruct.PINX_Alternate_Function = 0;                        // Pin AFS = 0
        GPIO_PinMode_Config(PINC(13),&PINX_InitStruct);                      // NSS setup at PC13
        
        PINX_InitStruct.PINX_Mode               = PINX_Mode_Digital_I;      // Setting digital  mode
        PINX_InitStruct.PINX_Alternate_Function = 4;                        // Pin AFS = 2
        GPIO_PinMode_Config(PINC(9),&PINX_InitStruct);                      // MISO setup at PC9
#endif

#if defined(MG32_3RD)
        // For URT1 pins setting
        PINX_InitStruct.PINX_Mode               = PINX_Mode_PushPull_O;     // Pin select pusu pull mode
        PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;  // Enable pull up resistor
        PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;           // Pin output low speed mode
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;     // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;     // Pin input data not inverse

        PINX_InitStruct.PINX_Alternate_Function = 4;                        // Pin AFS = 4
        GPIO_PinMode_Config(PINC(3),&PINX_InitStruct);                      // CLK at PC3
        
        PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level2;     // Pin output drive strength 1/4
        GPIO_PinMode_Config(PINC(8),&PINX_InitStruct);                      // MOSI at PC8
        
        PINX_InitStruct.PINX_Alternate_Function = 0;                        // Pin AFS = 0
        GPIO_PinMode_Config(PINC(7),&PINX_InitStruct);                      // NSS at PC7
        
        PINX_InitStruct.PINX_Mode               = PINX_Mode_Digital_I;      // Setting digital  mode
        PINX_InitStruct.PINX_Alternate_Function = 4;                        // Pin AFS = 2
        GPIO_PinMode_Config(PINC(9),&PINX_InitStruct);                      // MISO at PC9
#endif
    }
#endif
    /*=== 2. Configure SPI ===*/
    SPIx_Init(CONF_CK_APB_FREQ, 0);
}


/**
 *******************************************************************************
 * @brief       LED module initial for BLE
 * @details
 * @return      None
 * @note        Used pins
 *                  PD8 for MG32F02A032
 *                  PE13 for MG32F02A132/072 MA862
 * @par         Example
 * @code
    BLE_LED_Init();
 * @endcode
 *******************************************************************************
 */
void BLE_LED_Init(void)
{
    PIN_InitTypeDef        PINX_InitStruct;
    
    PINX_InitStruct.PINX_Mode               = PINX_Mode_PushPull_O;     // Pin select pusu pull mode
    PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;  // Enable pull up resistor
    PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;           // Pin output low speed mode
    PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;     // Pin output driver full strength.
    PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
    PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;     // Pin input data not inverse
    PINX_InitStruct.PINX_Alternate_Function = 0;                        // Pin AFS = 0 (GPIO)

    GPIO_PinMode_Config(LED1_PINSET,&PINX_InitStruct);
    LED1_PIN = LED_OFF; 
}


/**
 *******************************************************************************
 * @brief       LED module initial
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    LED_Flash();
 * @endcode
 *******************************************************************************
 */
void LED_Flash(void)
{
    LED1_PIN ^= 0x1;
}


/**
 *******************************************************************************
 * @brief       BSP initial
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    BSP_Init();
 * @endcode
 *******************************************************************************
 */
void BSP_Init(void)
{
    BLE_SPI_Init();
    BLE_URT0_Init();
    BLE_EXIC_Init();
    BLE_LED_Init();
    InitTick(12000000,0);
    IWDT_Init();
}


/**
 *******************************************************************************
 * @brief       IS IRQ Enable
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    IsIrqEnabled();
 * @endcode
 *******************************************************************************
 */
char IsIrqEnabled(void) //porting api
{
    return !(EXIC_PIN);
}


/**
 *******************************************************************************
 * @brief       IRQ MCU go to sleep and wakeup
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    IrqMcuGotoSleepAndWakeup();
 * @endcode
 *******************************************************************************
 */
void IrqMcuGotoSleepAndWakeup(void)
{
    if(ble_run_interrupt_McuCanSleep())
    {
        //mcu lowpower
    }
}


#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
        volatile unsigned int SysTick_Count = 0;
    #pragma clang diagnostic pop
#else
    volatile unsigned int SysTick_Count = 0;
#endif

/**
 *******************************************************************************
 * @brief       Get sys tick count
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    GetSysTickCount();
 * @endcode
 *******************************************************************************
 */
unsigned int GetSysTickCount(void) //porting api
{
    return SysTick_Count;
}


/**
 *******************************************************************************
 * @brief       Sys Tick Handler
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    SysTick_Handler();
 * @endcode
 *******************************************************************************
 */
void SysTick_Handler(void)
{
    SysTick_Count ++;
    ble_nMsRoutine();
}

