/*
  Copyright (c) 2011 Arduino.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "variant.h"


#include "MG32x02z.h"
#include "system_MG32x02z.h"
#include "MG32x02z_DRV.h"
#include "MG32x02z_ChipInit.h"
#include "MG32x02z_URT_MID.h"
#include "MG32x02z_ADC_MID.h"

#include "timer.h"
#include "HardwareSerial.h"
#include "hw_config.h"


#include "pwm.h"

#ifdef __cplusplus
extern "C" {
#endif


//INPUT_PULLUP
//GPIO_Pin_0

#define  GPA_CFG(x, afs, m)        .AFS=PA##x##_AFS_##afs,   .PinNum=x,  .GioPin=GPIO_Pin_##x, .ulPort=GPIOA,  .IO_Mode=m
#define  GPB_CFG(x, afs, m)        .AFS=PB##x##_AFS_##afs,   .PinNum=x,  .GioPin=GPIO_Pin_##x, .ulPort=GPIOB,  .IO_Mode=m
#define  GPC_CFG(x, afs, m)        .AFS=PC##x##_AFS_##afs,   .PinNum=x,  .GioPin=GPIO_Pin_##x, .ulPort=GPIOC,  .IO_Mode=m
#define  GPD_CFG(x, afs, m)        .AFS=PD##x##_AFS_##afs,   .PinNum=x,  .GioPin=GPIO_Pin_##x, .ulPort=GPIOD,  .IO_Mode=m
#define  GPE_CFG(x, afs, m)        .AFS=PE##x##_AFS_##afs,   .PinNum=x,  .GioPin=GPIO_Pin_##x, .ulPort=GPIOE,  .IO_Mode=m


#define  GPNULL_CFG()              .AFS=0,   .PinNum=((uint16_t)-1),  .GioPin=((uint16_t)-1), .ulPort=NULL,  .IO_Mode=0


#define ANALOG_PULLUP    0xF1
#define ANALOG_NOPULLUP  0xF2

#define DEFAULT_PIN_STATE   INPUT_PULLUP  //ANALOG_NOPULLUP //ANALOG_PULLUP //INPUT //INPUT_PULLUP
const PinDescription  g_APinDescription[MAX_DIGITAL_IOS]=
{
    { .arduino_id=ARDUINO_PIN_D0, 
          GPC_CFG(9, GPC9, DEFAULT_PIN_STATE), 
                 .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART| PIN_ATTR_I2C|PIN_ATTR_CMP, 
                           .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT2_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D1, 
          GPC_CFG(8, GPC8, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART| PIN_ATTR_I2C|PIN_ATTR_ADC, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT2_IRQn,    .uconfigured=false },
  	                         	        
  { .arduino_id=ARDUINO_PIN_D2, 
          GPB_CFG(4, GPB4, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D3,  
          GPB_CFG(10, GPB10, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI| PIN_ATTR_I2C | PIN_ATTR_PWM, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },       

  { .arduino_id=ARDUINO_PIN_D4,  
          GPC_CFG(7, GPC7, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_ADC, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT2_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D5,  
          GPB_CFG(11, GPB11, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART| PIN_ATTR_I2C|PIN_ATTR_DMA | PIN_ATTR_PWM,
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D6,   
          GPC_CFG(0, GPC0, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART| PIN_ATTR_I2C| PIN_ATTR_PWM, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT2_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D7, 
          GPB_CFG(5, GPB5, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D8,   
          GPC_CFG(12, GPC12, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART| PIN_ATTR_PWM, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT2_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D9, 
          GPD_CFG(0, GPD0, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI| PIN_ATTR_PWM, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT3_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D10, 
          GPD_CFG(9, GPD9, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI| PIN_ATTR_PWM, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT3_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D11,
          GPD_CFG(2, GPD2, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI|PIN_ATTR_USB| PIN_ATTR_PWM, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT3_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D12, 
          GPD_CFG(7, GPD7, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT3_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D13,  
          GPD_CFG(8, GPD8, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT3_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D14, 
          GPA_CFG(0, GPA0, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART, 
  	                       .ADCChannel= ADC_CHANNEL_0,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D15,
          GPA_CFG(1, GPA1, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART, 
  	                       .ADCChannel= ADC_CHANNEL_1,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D16,
          GPA_CFG(2, GPA2, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART, 
  	                       .ADCChannel= ADC_CHANNEL_2,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D17,
          GPA_CFG(3, GPA3, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART, 
  	                       .ADCChannel= ADC_CHANNEL_3,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D18, 
          GPA_CFG(4, GPA4, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART, 
  	                       .ADCChannel= ADC_CHANNEL_4,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D19,
          GPA_CFG(5, GPA5, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART, 
  	                       .ADCChannel= ADC_CHANNEL_5,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D20,   
          GPB_CFG(3, GPB3, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI| PIN_ATTR_I2C|PIN_ATTR_ADC, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D21,   
          GPB_CFG(2, GPB2, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI| PIN_ATTR_I2C|PIN_ATTR_ADC|PIN_ATTR_DAC, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D22,  
          GPC_CFG(11, GPC11, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART| PIN_ATTR_I2C, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT2_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D23,  
          GPC_CFG(10, GPC10, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART| PIN_ATTR_I2C|PIN_ATTR_CMP, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT2_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D24,  
          GPB_CFG(7, GPB7, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D25,
          GPB_CFG(6, GPB6, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D26, 
          GPB_CFG(13, GPB13, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D27,  
          GPB_CFG(14, GPB14, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_DMA , 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D28,   
          GPB_CFG(15, GPB15, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_USB, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D29,
          GPB_CFG(12, GPB12, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL| PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_USB|PIN_ATTR_DMA , 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D30,   
          GPB_CFG(1, GPB1, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_CMP|PIN_ATTR_SPI| PIN_ATTR_I2C, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D31,  
          GPB_CFG(0, GPB0, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_CMP|PIN_ATTR_SPI| PIN_ATTR_I2C, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D32, 
          GPD_CFG(1, GPD1, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI,  
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT3_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D33,  
          GPD_CFG(3, GPD3, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI|PIN_ATTR_USB, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT3_IRQn,    .uconfigured=false },
  	               
  { .arduino_id=ARDUINO_PIN_D34,
          GPD_CFG(10, GPD10, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT3_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D35, 
          GPD_CFG(11, GPD11, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI|PIN_ATTR_DMA, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT3_IRQn,    .uconfigured=false },
               
  { .arduino_id=ARDUINO_PIN_D36, 
          GPA_CFG(6, GPA6, DEFAULT_PIN_STATE),
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI, 
  	                       .ADCChannel= ADC_CHANNEL_6,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D37,
          GPA_CFG(7, GPA7, DEFAULT_PIN_STATE),   
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI, 
  	                       .ADCChannel= ADC_CHANNEL_7,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },
  	       
  { .arduino_id=ARDUINO_PIN_D38, 
          GPA_CFG(8, GPA8, DEFAULT_PIN_STATE),  
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_CMP|PIN_ATTR_SPI | PIN_ATTR_I2C|PIN_ATTR_DMA,  
  	                       .ADCChannel= ADC_CHANNEL_8,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D39, 
          GPA_CFG(9, GPA9, DEFAULT_PIN_STATE),   
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_CMP|PIN_ATTR_SPI | PIN_ATTR_I2C|PIN_ATTR_DMA, 
  	                       .ADCChannel= ADC_CHANNEL_9,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },	       

  { .arduino_id=ARDUINO_PIN_D40,
          GPA_CFG(10, GPA10, DEFAULT_PIN_STATE),   
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_CMP|PIN_ATTR_SPI | PIN_ATTR_I2C, 
  	                       .ADCChannel= ADC_CHANNEL_10,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },
  	                      
  	     	                       
  { .arduino_id=ARDUINO_PIN_D41, 
          GPA_CFG(11, GPA11, DEFAULT_PIN_STATE),   
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_CMP|PIN_ATTR_SPI | PIN_ATTR_I2C, 
  	                       .ADCChannel= ADC_CHANNEL_11,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D42, 
          GPA_CFG(12, GPA12, DEFAULT_PIN_STATE),   
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_USB|PIN_ATTR_SPI | PIN_ATTR_PWM, 
  	                       .ADCChannel= ADC_CHANNEL_12,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D43,   
          GPA_CFG(13, GPA13, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_USB|PIN_ATTR_SPI | PIN_ATTR_PWM, 
  	                       .ADCChannel= ADC_CHANNEL_13,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D44, 
          GPA_CFG(14, GPA14, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI, 
  	                       .ADCChannel= ADC_CHANNEL_14,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D45,  
          GPA_CFG(15, GPA15, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_ADC|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI, 
  	                       .ADCChannel= ADC_CHANNEL_15,   .IO_irqnb=EXINT0_IRQn,    .uconfigured=false },          
  	                       
  	                       
  { .arduino_id=ARDUINO_PIN_D46,
          GPC_CFG(1, GPC1, DEFAULT_PIN_STATE),   
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART| PIN_ATTR_I2C|PIN_ATTR_ADC, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT2_IRQn,    .uconfigured=false },

/*
  { .arduino_id=ARDUINO_PIN_D47, 
          GPC_CFG(6, RSTN, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART,  
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT2_IRQn,    .uconfigured=false },

  { .arduino_id=ARDUINO_PIN_D48, 
          GPB_CFG(8, URT0_TX, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI|PIN_ATTR_CMP, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D49, 
          GPB_CFG(9, URT0_RX, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI|PIN_ATTR_CMP, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
*/

  { .arduino_id=ARDUINO_PIN_D47, 
          GPB_CFG(8, URT0_TX, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI|PIN_ATTR_CMP, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },
  	                       
  { .arduino_id=ARDUINO_PIN_D48, 
          GPB_CFG(9, URT0_RX, DEFAULT_PIN_STATE), 
  	             .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART|PIN_ATTR_SPI|PIN_ATTR_CMP, 
  	                       .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT1_IRQn,    .uconfigured=false },

};




#ifdef __cplusplus
}
#endif



void serialEvent() __attribute__((weak));
void serialEvent()
{
    ;
}

void serialEventRun(void)
{
    if(Serial.available() )
    {
        Serial.serialEvent();
    }

}



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

#ifdef __cplusplus
extern "C" {
#endif

void __libc_init_array(void);




//设置其它所有端口的默认状态
void Init_ClearIoPin( void )
{
    GPIO_InitTypeDef GPIOX;

    GPIOX.Mode = GPIO_MODE_DIGITAL_I; //GPIO_MODE_ANALOG_IO;  //GPIO_MODE_DIGITAL_I;
    GPIOX.Pull = GPIO_PULLUP;
    GPIOX.Pin            = GPIO_Pin_All;
    GPIOX.Speed          = GPIO_SPEED_LOW;
    GPIOX.OUTDrive       = GPIO_OUTDRIVE_LEVEL0;
    GPIOX.FilterDivider  = GPIO_FILTERDIVIDER_BYPASS;
    GPIOX.Inverse        = GPIO_INVERSE_DISABLE;
    GPIOX.Alternate      = 0;

    MID_GPIO_Init(  IOMA , &GPIOX);
    MID_GPIO_Init(  IOMB , &GPIOX);
    MID_GPIO_Init(  IOMC , &GPIOX);
    MID_GPIO_Init(  IOMD , &GPIOX);
    MID_GPIO_Init(  IOME , &GPIOX);

    __DRV_GPIO_WRITE(GPIOA , 0xFFFF);
    __DRV_GPIO_WRITE(GPIOB , 0xFFFF);
    __DRV_GPIO_WRITE(GPIOC , 0xFFFF);
    __DRV_GPIO_WRITE(GPIOD , 0xFFFF);
    __DRV_GPIO_WRITE(GPIOE , 0xFFFF);

    {
        
        Pin_Struct*  pPinx;	
        PinDescription  Rst_PinDescription = 
        { .arduino_id=0, 
              GPC_CFG(6, RSTN, INPUT_PULLUP), 
                     .mode=PIN_ATTR_DIGITAL|PIN_ATTR_TIMER |PIN_ATTR_EXTINT|PIN_ATTR_UART,  
                               .ADCChannel=NB_ADC_CHANNEL_MANAGED,   .IO_irqnb=EXINT2_IRQn,    .uconfigured=false };
                               

        GPIOX.Mode = GPIO_MODE_DIGITAL_I;  //GPIO_MODE_ANALOG_IO; //GPIO_MODE_DIGITAL_I;
        GPIOX.Pull = GPIO_PULLUP;
    
        GPIOX.Pin            = Rst_PinDescription.GioPin;
        GPIOX.Speed          = GPIO_SPEED_LOW;
        GPIOX.OUTDrive       = GPIO_OUTDRIVE_LEVEL0;
        GPIOX.FilterDivider  = GPIO_FILTERDIVIDER_BYPASS;
        GPIOX.Inverse        = GPIO_INVERSE_DISABLE;
        GPIOX.Alternate      = Rst_PinDescription.AFS;
        pPinx = __GetPinxx_byGPIOx( Rst_PinDescription.ulPort, Rst_PinDescription.PinNum );
        
        MID_GPIO_Pin_Init(  pPinx,  &GPIOX);
        __DRV_GPIO_SET_BIT( Rst_PinDescription.ulPort,  Rst_PinDescription.PinNum ); 
        //__DRV_GPIO_CLEAR_BIT( Rst_PinDescription.ulPort,  Rst_PinDescription.PinNum ); 
  	}
}

void init( void )
{
    Pin_Struct*  pPinx;		
    GPIO_InitTypeDef GPIOX;
    uint32_t i;

    hw_config_init();
    
#if 1
    GPIO_PortFilterClockSource_Select(IOMA, GPIO_FT_CLK_AHB);
    GPIO_PortFilterClockSource_Select(IOMB, GPIO_FT_CLK_AHB);
    GPIO_PortFilterClockSource_Select(IOMC, GPIO_FT_CLK_AHB);
    GPIO_PortFilterClockSource_Select(IOMD, GPIO_FT_CLK_AHB);
    GPIO_PortFilterClockSource_Select(IOME, GPIO_FT_CLK_AHB);
#endif

    __DRV_CSC_GPIOA_CLK_ENABLE();       // GPIOA clock enable
    __DRV_CSC_GPIOB_CLK_ENABLE();       // GPIOB clock enable
    __DRV_CSC_GPIOC_CLK_ENABLE();       // GPIOC clock enable
    __DRV_CSC_GPIOD_CLK_ENABLE();       // GPIOD clock enable
    __DRV_CSC_RTC_CLK_ENABLE();         // RTC clock enable
    __DRV_CSC_IWDT_CLK_ENABLE();        // IWDT clock enable


    Init_ClearIoPin();

    for(i=0; i<(sizeof(g_APinDescription)/sizeof(PinDescription)) ; i++)
    {
        if( ( g_APinDescription[i].mode==PIN_ATTR_NONE )
         || ( g_APinDescription[i].ulPort==NULL))
        {
            continue;

        }

        switch ( g_APinDescription[i].IO_Mode )
        {
            case INPUT:
                GPIOX.Mode = GPIO_MODE_DIGITAL_I;
                GPIOX.Pull = GPIO_NOPULLUP;
                break;

            case INPUT_PULLUP:
                GPIOX.Mode = GPIO_MODE_DIGITAL_I;
                GPIOX.Pull = GPIO_PULLUP;
                break;

            case INPUT_PULLDOWN:
                GPIOX.Mode = GPIO_MODE_DIGITAL_I;
                GPIOX.Pull = GPIO_NOPULLUP;
                break;

            case OUTPUT:
                GPIOX.Mode = GPIO_MODE_PUSHPULL_O;
                GPIOX.Pull = GPIO_PULLUP;
                break;

            case ANALOG_NOPULLUP:
                GPIOX.Mode = GPIO_MODE_ANALOG_IO;
                GPIOX.Pull = GPIO_NOPULLUP;
                break;

            case ANALOG_PULLUP:
            default:
                GPIOX.Mode = GPIO_MODE_ANALOG_IO;
                GPIOX.Pull = GPIO_PULLUP;
                break;
        }
        GPIOX.Pin            = g_APinDescription[i].GioPin;
        GPIOX.Speed          = GPIO_SPEED_LOW;
        GPIOX.OUTDrive       = GPIO_OUTDRIVE_LEVEL0;
        GPIOX.FilterDivider  = GPIO_FILTERDIVIDER_BYPASS;
        GPIOX.Inverse        = GPIO_INVERSE_DISABLE;
        GPIOX.Alternate      = g_APinDescription[i].AFS;
        pPinx = __GetPinxx_byGPIOx( g_APinDescription[i].ulPort, g_APinDescription[i].PinNum );
        
        MID_GPIO_Pin_Init(  pPinx,  &GPIOX); 
        
        //__DRV_GPIO_SET_BIT( g_APinDescription[i].ulPort,  g_APinDescription[i].PinNum );
        __DRV_GPIO_CLEAR_BIT( g_APinDescription[i].ulPort,  g_APinDescription[i].PinNum );
        //g_APinDescription[i].uconfigured = true;
    }
}

void initVariant()
{
    megawin_Uart_init();

    analogReadInit();
    analogOutputInit();


#if defined(HWSERIAL0)
    Serial.begin( &mURT0,
                  ARDUINO_PIN_UART0_RX,
                  ARDUINO_PIN_UART0_TX,
                  URT0_IRQn,  DEFAULT_INIT_BAUDRATE  );
#endif

    timer_cfg_init();
    
    Megawin_EXIC_Init();
}



#ifdef __cplusplus
}
#endif




#ifdef __cplusplus
extern "C" {
#endif


extern uint32_t SystemCoreClock;
uint32_t HAL_RCC_GetHCLKFreq()
{
    return SystemCoreClock;
}


unsigned int PINCOUNT_fn() 
{
    return (sizeof(g_APinDescription) / sizeof(PinDescription));
}




/* Private function prototypes -----------------------------------------------*/
int fputc(int ch, FILE *f __attribute__((unused)));
/*
 *******************************************************************************
 * @brief	 Replace printf fputc function.
 * @details     
 * @return      
 * @note       
 *******************************************************************************
 */
 /*
int fputc(int ch, FILE *f __attribute__((unused)))
{
    DEBUG_URTn->TDAT.B[0] = (uint8_t)ch;
    while((DEBUG_URTn->STA.W & URT_STA_TXF_mask_w)==0);
    
    return(ch);
}

*/


/*
 * \brief Set the analog PWM output frequency.
 *
 * \param ulPin
 * 3: Set the PWM frequency of pin D3. (The frequency of D6 pin will be modified synchronously)
 * 5: Set the PWM frequency of pin D5. (The frequency of D8 and D9 pins will be modified synchronously)
 * 6: Set the PWM frequency of pin D6. (The frequency of D6 pin will be modified synchronously)
 * 8: Set the PWM frequency of pin D8. (The frequency of D5 and D9 pins will be modified synchronously)
 * 9: Set the PWM frequency of pin D9. (The frequency of D5 and D8 pins will be modified synchronously)
 * 10: Set the PWM frequency of pin D10. (The frequency of D11 pin will be modified synchronously)
 * 11: Set the PWM frequency of pin D11. (The frequency of D10 pin will be modified synchronously)
 * Or use optional macros:
 * PWM_FRQ_D3_D6: Set the PWM frequency of pin D3 and pin D6 at the same time. (same as setting pin D3 or pin D6 separately)
 * PWM_FRQ_D5_D8_D9: Set the PWM frequency of pin D5, pin D8 and pin D9 at the same time. (Same effect as setting pin D5, pin D8 or pin D9 separately)
 * PWM_FRQ_D10_D11: Set the PWM frequency of pin D10 and pin D1 at the same time (same as setting pin D10 or pin D11 separately).
 * PWM_FRQ_ALL: Set the PWM frequency of all pins simultaneously.
 *
 * \param freq：the frequency 1~1000000(Hz)
 */
void analogWriteFrequency( uint32_t ulPin,  uint32_t freq)
{
    if( freq == 0 )
    {
        pwm_stop(ulPin);
    }

    if( freq > 1000000 )
    {
        freq = 1000000;
    }
    
    switch( ulPin )
    {
        case 3:
        case 6:
        case PWM_FRQ_D3_D6:
            pwm_setFrequency(  3,  freq );
            pwm_setFrequency(  6,  freq );
            break;
        case 5:
        case 8:
        case 9:
        case PWM_FRQ_D5_D8_D9:
            pwm_setFrequency(  5,  freq );
            pwm_setFrequency(  8,  freq );
            pwm_setFrequency(  9,  freq );
            break;
        case 10:
        case 11:
        case PWM_FRQ_D10_D11:
            pwm_setFrequency(  10,  freq );
            pwm_setFrequency(  11,  freq );
            break;

        case PWM_FRQ_ALL:
            pwm_setFrequency(  3,  freq );
            pwm_setFrequency(  6,  freq );
            pwm_setFrequency(  5,  freq );
            pwm_setFrequency(  8,  freq );
            pwm_setFrequency(  9,  freq );
            pwm_setFrequency(  10,  freq );
            pwm_setFrequency(  11,  freq );
            break;
            
        case 42:
        case 43:
            pwm_setFrequency(  42,  freq );
            pwm_setFrequency(  43,  freq );
            break;
        default:
            return;
    }
    
    //pwm_setFrequency(  ulPin,  freq );
    return;
}



#ifdef __cplusplus
}
#endif





