
#include "hw.h"


static GpioIrqHandler *GpioIrq[16] = { NULL };


uint8_t gpio_test = 0;  //用于记录GPIO测试

//void GpioInit( void )
//{
//    GPIO_InitTypeDef GPIO_InitStruct;

//    /* GPIO Ports Clock Enable */
//    __HAL_RCC_GPIOA_CLK_ENABLE( );
//    __HAL_RCC_GPIOB_CLK_ENABLE( );
//    __HAL_RCC_GPIOC_CLK_ENABLE( );
//    __HAL_RCC_GPIOD_CLK_ENABLE( );
//    __HAL_RCC_GPIOE_CLK_ENABLE( );
//    __HAL_RCC_GPIOF_CLK_ENABLE( );
//    __HAL_RCC_GPIOG_CLK_ENABLE( );
//    __HAL_RCC_GPIOH_CLK_ENABLE( );

//    /*Configure GPIO pins : PC13 PC2 PC3 PC4 
//                           PC5 PC6 PC7 PC8 
//                           PC9 PC10 PC11 PC12 */
//    GPIO_InitStruct.Pin = GPIO_PIN_13 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 
//                          | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 
//                          | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOC, &GPIO_InitStruct );

//    /*Configure GPIO pins : LED_RX_Pin LED_TX_Pin */
//    GPIO_InitStruct.Pin = LED_RX_PIN | LED_TX_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( GPIOC, &GPIO_InitStruct );

//    /*Configure GPIO pins : nRESET_Pin RADIO_NSS_Pin */
//    GPIO_InitStruct.Pin = RADIO_nRESET_PIN | RADIO_NSS_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( GPIOA, &GPIO_InitStruct );

//    /*Configure GPIO pins : PA1 PA4 PA9 PA10 
//                           PA11 PA12 PA15 */
//    GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_9 | GPIO_PIN_10 
//                          | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_15;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOA, &GPIO_InitStruct );

//    /*Configure GPIO pin : ANT_SW_Pin */
//    GPIO_InitStruct.Pin = ANT_SW_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( ANT_SW_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pins : PB1 PB2 PB10 PB11 
//                           PB12 PB13 PB14 PB15 
//                           PB5 PB6 PB7 PB8 
//                           PB9 */
//    GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_10 | GPIO_PIN_11 
//                          | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15 
//                          | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 
//                          | GPIO_PIN_9;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOB, &GPIO_InitStruct );

//    /*Configure GPIO pin : PD2 */
//    GPIO_InitStruct.Pin = GPIO_PIN_2;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOD, &GPIO_InitStruct );

//    /*Configure GPIO pin : BUSY_Pin */
//    GPIO_InitStruct.Pin = RADIO_BUSY_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
//    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
//    HAL_GPIO_Init( RADIO_BUSY_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pin : DIOx_Pin */
//    GPIO_InitStruct.Pin = RADIO_DIOx_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
//    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
//    HAL_GPIO_Init( RADIO_DIOx_PORT, &GPIO_InitStruct);

//    /*Configure GPIO pin Output Level */
//    GpioWrite( GPIOC, LED_RX_PIN | LED_TX_PIN, GPIO_PIN_SET );

//    /*Configure GPIO pin Output Level */
//    GpioWrite( GPIOA, RADIO_nRESET_PIN | RADIO_NSS_PIN, GPIO_PIN_RESET );

//    /*Configure GPIO pin Output Level */
//    GpioWrite( ANT_SW_PORT, ANT_SW_PIN, GPIO_PIN_RESET );

//}


//void GpioDeInit( void )
//{
//    GPIO_InitTypeDef GPIO_InitStruct;

//    /*Configure GPIO pins : USART_TX_PIN */
//    GPIO_InitStruct.Pin = USART_TX_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( USART_TX_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pins : USART_RX_PIN */
//    GPIO_InitStruct.Pin = USART_RX_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( USART_RX_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pins : LED_RX_Pin */
//    GPIO_InitStruct.Pin = LED_RX_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( LED_RX_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pins : LED_TX_PIN */
//    GPIO_InitStruct.Pin = LED_TX_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( LED_TX_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pins : nRESET_Pin */
//    GPIO_InitStruct.Pin = RADIO_nRESET_PIN ;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( RADIO_nRESET_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pins : RADIO_NSS_Pin */
//    GPIO_InitStruct.Pin = RADIO_NSS_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//    GPIO_InitStruct.Pull = GPIO_PULLUP;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( RADIO_NSS_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pins : RADIO_MOSI_PIN */
//    GPIO_InitStruct.Pin = RADIO_MOSI_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( RADIO_MOSI_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pins : RADIO_MISO_PIN */
//    GPIO_InitStruct.Pin = RADIO_MISO_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( RADIO_MISO_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pins : RADIO_SCK_PIN */
//    GPIO_InitStruct.Pin = RADIO_SCK_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( RADIO_SCK_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pin : ANT_SW_Pin */
//    GPIO_InitStruct.Pin = ANT_SW_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//    HAL_GPIO_Init( ANT_SW_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pin : PD2 */
//    GPIO_InitStruct.Pin = GPIO_PIN_2;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOD, &GPIO_InitStruct );

//    /*Configure GPIO pin : BUSY_Pin */
//    GPIO_InitStruct.Pin = RADIO_BUSY_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( RADIO_BUSY_PORT, &GPIO_InitStruct );

//    /*Configure GPIO pin : DIOx_Pin */
//    GPIO_InitStruct.Pin = RADIO_DIOx_PIN;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( RADIO_DIOx_PORT, &GPIO_InitStruct);



//    /*Configure GPIO pins : PA1 PA4 PA9 PA10 
//                           PA11 PA12 PA15 */
//    GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_9 | GPIO_PIN_10 
//                          | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_15;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOA, &GPIO_InitStruct );

//    GPIO_InitStruct.Pin = GPIO_PIN_All;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOB, &GPIO_InitStruct );
//    
//    GPIO_InitStruct.Pin = GPIO_PIN_All;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOC, &GPIO_InitStruct );

//    GPIO_InitStruct.Pin = GPIO_PIN_All;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOD, &GPIO_InitStruct );
//    
//    GPIO_InitStruct.Pin = GPIO_PIN_All;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOE, &GPIO_InitStruct );
//    
//    GPIO_InitStruct.Pin = GPIO_PIN_All;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOF, &GPIO_InitStruct );
//    
//    GPIO_InitStruct.Pin = GPIO_PIN_All;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init( GPIOH, &GPIO_InitStruct );
//    
//    
//      /* Disable GPIOs clock */
//    __HAL_RCC_GPIOA_CLK_DISABLE( );
//    __HAL_RCC_GPIOB_CLK_DISABLE( );
//    __HAL_RCC_GPIOC_CLK_DISABLE( );
//    __HAL_RCC_GPIOD_CLK_DISABLE( );
//    __HAL_RCC_GPIOE_CLK_DISABLE( );
//    __HAL_RCC_GPIOF_CLK_DISABLE( );
//    __HAL_RCC_GPIOG_CLK_DISABLE( );
//    __HAL_RCC_GPIOH_CLK_DISABLE( );
//}


void GpioInit( void )
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA,ENABLE);
  
  GPIO_InitTypeDef GPIO_InitStruct;
  GPIO_InitStruct.GPIO_Pin = RADIO_nRESET_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;   			// 推挽输出
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(RADIO_nRESET_PORT, &GPIO_InitStruct); 
  
  
      // 配置NSS的引脚
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = RADIO_0_NSS_PIN;  // SCK, MISO, MOSI
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  // 复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(RADIO_0_NSS_PORT, &GPIO_InitStructure);
  
  
    GPIO_InitStructure.GPIO_Pin = RADIO_BUSY_PIN;  // SCK, MISO, MOSI
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(RADIO_BUSY_PORT, &GPIO_InitStructure);
    
    
    GPIO_InitStructure.GPIO_Pin = RADIO_DIOx_PIN;  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(RADIO_DIOx_PORT, &GPIO_InitStructure);
}


IRQn_Type MSP_GetIRQn( uint16_t GPIO_Pin )
{
  switch( GPIO_Pin )
  {
    case GPIO_Pin_0:  return EXTI0_IRQn;
    case GPIO_Pin_1:  return EXTI1_IRQn;
    case GPIO_Pin_2:  return EXTI2_IRQn;
    case GPIO_Pin_3:  return EXTI3_IRQn;
    case GPIO_Pin_4:  return EXTI4_IRQn;
    case GPIO_Pin_5:  
    case GPIO_Pin_6:
    case GPIO_Pin_7:
    case GPIO_Pin_8:
    case GPIO_Pin_9:  return EXTI9_5_IRQn;
    case GPIO_Pin_10:
    case GPIO_Pin_11:
    case GPIO_Pin_12:
    case GPIO_Pin_13:
    case GPIO_Pin_14:
    case GPIO_Pin_15: 
    default: return EXTI15_10_IRQn;
  }
}






/*!
 * @brief Records the interrupt handler for the GPIO  object
 *
 * @param  GPIOx: where x can be (A..E and H) 
 * @param  GPIO_Pin: specifies the port bit to be written.
 *                   This parameter can be one of GPIO_PIN_x where x can be (0..15).
 *                   All port bits are not necessarily available on all GPIOs.
 * @param [IN] prio       NVIC priority (0 is highest)
 * @param [IN] irqHandler  points to the  function to execute
 * @retval none
 */
void GpioSetIrq( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint32_t prio,  GpioIrqHandler *irqHandler )
{
    IRQn_Type IRQnb;
    uint32_t BitPos = GpioGetBitPos( GPIO_Pin ) ;

    if(irqHandler != NULL)
    {
      GpioIrq[BitPos] = irqHandler;
      
      //EXTI初始化
      EXTI_InitTypeDef EXTI_InitStructure;
      if(GPIO_Pin == RADIO_DIO1_PIN)
      {
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);	// AFIO外部中断引脚选择配置。
        EXTI_InitStructure.EXTI_Line = EXTI_Line1;						// 指定中断线
      }
      else if(GPIO_Pin == RADIO_DIO2_PIN)
      {
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);	// AFIO外部中断引脚选择配置。
        EXTI_InitStructure.EXTI_Line = EXTI_Line2;						// 指定中断线
      }
      else if(GPIO_Pin == RADIO_DIO3_PIN)
      {
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);	// AFIO外部中断引脚选择配置。
        EXTI_InitStructure.EXTI_Line = EXTI_Line3;						// 指定中断线
      }
      else
      {
        return;
      }
      EXTI_InitStructure.EXTI_LineCmd = ENABLE;						// 开启中断
      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;				// 指定模式为接收外部中断
      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;			// 下降沿触发
      EXTI_Init(&EXTI_InitStructure);
  
      IRQnb = MSP_GetIRQn( GPIO_Pin );
      NVIC_InitTypeDef NVIC_InitStructure;
      NVIC_InitStructure.NVIC_IRQChannel = IRQnb; // 中断源
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = prio; // 抢占优先级 
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断通道
      NVIC_Init(&NVIC_InitStructure);
    }      
}

void GpioSetIrq_all()
{
    IRQn_Type IRQnb;

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);	// AFIO外部中断引脚选择配置。
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource2);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);
    	//EXTI初始化
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = EXTI_Line2;						// 指定中断线
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;						// 开启中断
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;				// 指定模式为接收外部中断
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;			// 上升沿触发
    EXTI_Init(&EXTI_InitStructure);
    EXTI_InitStructure.EXTI_Line = EXTI_Line1;
    EXTI_Init(&EXTI_InitStructure);
    EXTI_InitStructure.EXTI_Line = EXTI_Line3;
    EXTI_Init(&EXTI_InitStructure);
  
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; // 中断源
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断通道
    NVIC_Init(&NVIC_InitStructure);    
    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; // 中断源
    NVIC_Init(&NVIC_InitStructure);
    NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; // 中断源
    NVIC_Init(&NVIC_InitStructure);
}

void EXTI1_IRQHandler(void)	
{
  //printf("dio1中断了\r\n");
  gpio_test |= 1; //第一位代表DIO1
  EXTI_ClearITPendingBit(EXTI_Line1);
  
}

void EXTI2_IRQHandler(void)	
{
  //printf("dio2中断了\r\n");
  gpio_test |= 2; //第二位代表DIO2
  EXTI_ClearITPendingBit(EXTI_Line2);
  
}

void EXTI3_IRQHandler(void)	
{
  //printf("dio3中断了\r\n");
  gpio_test |= 4; //第三位代表DIO3
  EXTI_ClearITPendingBit(EXTI_Line3);
  
}



/*!
 * @brief Execute the interrupt from the object
 *
 * @param  GPIO_Pin: specifies the port bit to be written.
 *                   This parameter can be one of GPIO_PIN_x where x can be (0..15).
 *                   All port bits are not necessarily available on all GPIOs.
 * @retval none
 */
void GpioLaunchIrqHandler( uint16_t GPIO_Pin )
{
    uint32_t BitPos = GpioGetBitPos( GPIO_Pin );

    if ( GpioIrq[BitPos]  != NULL )
    {
        GpioIrq[BitPos]( );
    }
}


/*!
 * @brief Get the position of the bit set in the GPIO_Pin
 * @param  GPIO_Pin: specifies the port bit to be written.
 *                   This parameter can be one of GPIO_PIN_x where x can be (0..15).
 *                   All port bits are not necessarily available on all GPIOs.
 * @retval the position of the bit
 */
uint8_t GpioGetBitPos( uint16_t GPIO_Pin )
{
    uint8_t PinPos=0;

    if ( ( GPIO_Pin & 0xFF00 ) != 0 ) { PinPos |= 0x8; }
    if ( ( GPIO_Pin & 0xF0F0 ) != 0 ) { PinPos |= 0x4; }
    if ( ( GPIO_Pin & 0xCCCC ) != 0 ) { PinPos |= 0x2; }
    if ( ( GPIO_Pin & 0xAAAA ) != 0 ) { PinPos |= 0x1; }

    return PinPos;
}


/*!
 * @brief Writes the given value to the GPIO output
 *
 * @param  GPIO_Pin: specifies the port bit to be written.
 *                   This parameter can be one of GPIO_PIN_x where x can be (0..15).
 *                   All port bits are not necessarily available on all GPIOs.
 * @param [IN] value New GPIO output value
 * @retval none
 */
void GpioWrite( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint32_t value )
{
    GPIO_WriteBit( GPIOx, GPIO_Pin , ( BitAction ) value );
}

/*!
 * @brief Reads the current GPIO input value
 *
 * @param  GPIOx: where x can be (A..E and H) 
 * @param  GPIO_Pin: specifies the port bit to be written.
 *                   This parameter can be one of GPIO_PIN_x where x can be (0..15).
 *                   All port bits are not necessarily available on all GPIOs.
 * @retval value   Current GPIO input value
 */
uint32_t GpioRead( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin )
{
    return GPIO_ReadInputDataBit( GPIOx, GPIO_Pin );
}
