Пример #1
0
OSStatus platform_gpio_enable_clock( const platform_gpio_t* gpio )
{
  uint8_t     port_number;
  OSStatus    err = kNoErr;

  require_action_quiet( gpio != NULL, exit, err = kParamErr);
  
  /* Enable peripheral clock for this port */
  port_number = platform_gpio_get_port_number( gpio->port );
  require_action_quiet( port_number != 0xFF, exit, err = kParamErr);

  RCC->AHB1ENR |= gpio_peripheral_clocks[port_number];  

exit:
  return err;

}
Пример #2
0
platform_result_t platform_gpio_init( const platform_gpio_t* gpio, platform_pin_config_t config )
{
    GPIO_InitTypeDef  gpio_init_structure;
    uint8_t           port_number;

    wiced_assert( "bad argument", ( gpio != NULL ) );

    platform_mcu_powersave_disable();

    port_number = platform_gpio_get_port_number( gpio->port );

    /* Enable peripheral clock for this port */
    RCC->AHB1ENR |= gpio_peripheral_clocks[port_number];

    gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz;
    gpio_init_structure.GPIO_Mode  = ( ( config == INPUT_PULL_UP ) || ( config == INPUT_PULL_DOWN ) || ( config == INPUT_HIGH_IMPEDANCE ) ) ? GPIO_Mode_IN : GPIO_Mode_OUT;
    gpio_init_structure.GPIO_OType = ( config == OUTPUT_PUSH_PULL ) ? GPIO_OType_PP : GPIO_OType_OD;

    if ( ( config == INPUT_PULL_UP ) || ( config == OUTPUT_OPEN_DRAIN_PULL_UP ) )
    {
        gpio_init_structure.GPIO_PuPd = GPIO_PuPd_UP;
    }
    else if ( config == INPUT_PULL_DOWN )
    {
        gpio_init_structure.GPIO_PuPd = GPIO_PuPd_DOWN;
    }
    else
    {
        gpio_init_structure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    }

    gpio_init_structure.GPIO_Pin = (uint32_t) ( 1 << gpio->pin_number );

    GPIO_Init( gpio->port, &gpio_init_structure );

    platform_mcu_powersave_enable();

    return PLATFORM_SUCCESS;
}
Пример #3
0
OSStatus platform_gpio_init( const platform_gpio_t* gpio, platform_pin_config_t config )
{
  GPIO_InitTypeDef  gpio_init_structure;
  uint8_t           port_number;
  OSStatus          err = kNoErr;

  platform_mcu_powersave_disable();
  require_action_quiet( gpio != NULL, exit, err = kParamErr);
  
  port_number = platform_gpio_get_port_number( gpio->port );

  /* Enable peripheral clock for this port */
  RCC->AHB1ENR |= gpio_peripheral_clocks[port_number];

  gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz;
  gpio_init_structure.GPIO_Mode  = ( ( config == INPUT_PULL_UP ) || ( config == INPUT_PULL_DOWN ) || ( config == INPUT_HIGH_IMPEDANCE ) ) ? GPIO_Mode_IN : GPIO_Mode_OUT;
  gpio_init_structure.GPIO_OType = ( config == OUTPUT_PUSH_PULL ) ? GPIO_OType_PP : GPIO_OType_OD;

  if ( ( config == INPUT_PULL_UP ) || ( config == OUTPUT_OPEN_DRAIN_PULL_UP ) )
  {
    gpio_init_structure.GPIO_PuPd = GPIO_PuPd_UP;
  }
  else if ( config == INPUT_PULL_DOWN )
  {
    gpio_init_structure.GPIO_PuPd = GPIO_PuPd_DOWN;
  }
  else
  {
    gpio_init_structure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  }

  gpio_init_structure.GPIO_Pin = (uint32_t) ( 1 << gpio->pin_number );

  GPIO_Init( gpio->port, &gpio_init_structure );
  
exit:
  platform_mcu_powersave_enable();
  return err;
}
Пример #4
0
platform_result_t platform_gpio_set_alternate_function( platform_gpio_port_t* gpio_port, uint8_t pin_number, GPIOOType_TypeDef output_type, GPIOPuPd_TypeDef pull_up_down_type, uint8_t alternation_function )
{
    GPIO_InitTypeDef  gpio_init_structure;
    uint8_t           port_number = platform_gpio_get_port_number( gpio_port );

    platform_mcu_powersave_disable();

    /* Enable peripheral clock for this port */
    RCC->AHB1ENR |= gpio_peripheral_clocks[port_number];

    gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz;
    gpio_init_structure.GPIO_Mode  = GPIO_Mode_AF;
    gpio_init_structure.GPIO_OType = output_type;
    gpio_init_structure.GPIO_PuPd  = pull_up_down_type;
    gpio_init_structure.GPIO_Pin   = (uint32_t) ( 1 << pin_number );

    GPIO_Init( gpio_port, &gpio_init_structure );
    GPIO_PinAFConfig( gpio_port, pin_number, alternation_function );

    platform_mcu_powersave_enable();

    return PLATFORM_SUCCESS;
}
Пример #5
0
platform_result_t platform_gpio_irq_enable( const platform_gpio_t* gpio, platform_gpio_irq_trigger_t trigger, platform_gpio_irq_callback_t handler, void* arg )
{
    uint32_t            interrupt_line;
    EXTITrigger_TypeDef exti_trigger;

    wiced_assert( "bad argument", ( gpio != NULL ) && ( handler != NULL ) );

    interrupt_line = (uint32_t) ( 1 << gpio->pin_number );

    switch ( trigger )
    {
        case IRQ_TRIGGER_RISING_EDGE:
        {
            exti_trigger = EXTI_Trigger_Rising;
            break;
        }
        case IRQ_TRIGGER_FALLING_EDGE:
        {
            exti_trigger = EXTI_Trigger_Falling;
            break;
        }
        case IRQ_TRIGGER_BOTH_EDGES:
        {
            exti_trigger = EXTI_Trigger_Rising_Falling;
            break;
        }
        default:
        {
            return PLATFORM_BADARG;
        }
    }

    platform_mcu_powersave_disable();

    if ( ( EXTI->IMR & interrupt_line ) == 0 )
    {
        EXTI_InitTypeDef exti_init_structure;
        IRQn_Type        interrupt_vector = 0;

        SYSCFG_EXTILineConfig( platform_gpio_get_port_number( gpio->port ), gpio->pin_number );

        exti_init_structure.EXTI_Trigger = exti_trigger;
        exti_init_structure.EXTI_Line    = interrupt_line;
        exti_init_structure.EXTI_Mode    = EXTI_Mode_Interrupt;
        exti_init_structure.EXTI_LineCmd = ENABLE;
        EXTI_Init( &exti_init_structure );

        if ( ( interrupt_line & 0x001F ) != 0 )
        {
            /* Line 0 to 4 */
            interrupt_vector = (IRQn_Type) ( EXTI0_IRQn + gpio->pin_number );
        }
        else if ( ( interrupt_line & 0x03E0 ) != 0 )
        {
            /* Line 5 to 9 */
            interrupt_vector = EXTI9_5_IRQn;
        }
        else if ( ( interrupt_line & 0xFC00 ) != 0 )
        {
            /* Line 10 to 15 */
            interrupt_vector = EXTI15_10_IRQn;
        }

        /* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY otherwise FreeRTOS will not be able to mask the interrupt */
        NVIC_EnableIRQ( interrupt_vector );

        gpio_irq_data[gpio->pin_number].owner_port = gpio->port;
        gpio_irq_data[gpio->pin_number].handler    = handler;
        gpio_irq_data[gpio->pin_number].arg        = arg;

        platform_mcu_powersave_enable();

        return PLATFORM_SUCCESS;
    }

    platform_mcu_powersave_enable();

    return PLATFORM_NO_EFFECT;
}
Пример #6
0
OSStatus platform_gpio_irq_enable( const platform_gpio_t* gpio, platform_gpio_irq_trigger_t trigger, platform_gpio_irq_callback_t handler, void* arg )
{
  uint32_t interrupt_line = (uint32_t) ( 1 << gpio->pin_number );
  EXTITrigger_TypeDef exti_trigger;
  OSStatus err = kNoErr;

  platform_mcu_powersave_disable();
  require_action_quiet( gpio != NULL, exit, err = kParamErr);

  switch ( trigger )
  {
    case IRQ_TRIGGER_RISING_EDGE:
    {
      exti_trigger = EXTI_Trigger_Rising;
      break;
    }
    case IRQ_TRIGGER_FALLING_EDGE:
    {
      exti_trigger = EXTI_Trigger_Falling;
      break;
    }
    case IRQ_TRIGGER_BOTH_EDGES:
    {
      exti_trigger = EXTI_Trigger_Rising_Falling;
      break;
    }
    default:
    {
      err =  kParamErr;
      goto exit;
    }
  }

  if ( ( EXTI->IMR & interrupt_line ) == 0 )
  {
    EXTI_InitTypeDef exti_init_structure;
    IRQn_Type        interrupt_vector = (IRQn_Type)0;

    if (gpio->pin_number == 10) {
      /* This is STM32 Bug, please check at:
      * https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FGPIO%20Interrupt%20Issue&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=581#{B7C01461-8CEC-4711-B331-64F4AECF4786}
      * ERRATA sheet in section 2.1.8.
      Configuration of PH10 and PI10 as external interrupts is erroneous
      
      Description
      
      PH10 or PI10 is selected as the source for the EXTI10 external interrupt by setting bits
      EXTI10[3:0] of SYSCFG_EXTICR3 register to 0x0111 or 0x1000, respectively. However,
      this erroneous operation enables PH2 and PI2 as external interrupt inputs.
      
      As a result, it is not possible to use PH10/PI10 as interrupt sources if PH2/PI2 are not
      selected as the interrupt source, as well. This means that bits EXTI10[3:0] of
      
      SYSCFG_EXTICR3 register and bits EXTI2[3:0] of SYSCFG_EXTICR1 should be
      programmed to the same value:
      ¡ñ 0x0111 to select PH10/PH2
      ¡ñ 0x1000 to select PI10/PI2
      
      */
      if (gpio->port == GPIOH)
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOH, EXTI_PinSource2); 
      else if (gpio->port == GPIOI)
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOI, EXTI_PinSource2);
    }
    else{
      SYSCFG_EXTILineConfig( platform_gpio_get_port_number( gpio->port ), gpio->pin_number );
    }
      
    exti_init_structure.EXTI_Trigger = exti_trigger;
    exti_init_structure.EXTI_Line    = interrupt_line;
    exti_init_structure.EXTI_Mode    = EXTI_Mode_Interrupt;
    exti_init_structure.EXTI_LineCmd = ENABLE;
    EXTI_Init( &exti_init_structure );

    if ( ( interrupt_line & 0x001F ) != 0 )
    {
      /* Line 0 to 4 */
      interrupt_vector = (IRQn_Type) ( EXTI0_IRQn + gpio->pin_number );
    }
    else if ( ( interrupt_line & 0x03E0 ) != 0 )
    {
      /* Line 5 to 9 */
      interrupt_vector = EXTI9_5_IRQn;
    }
    else if ( ( interrupt_line & 0xFC00 ) != 0 )
    {
      /* Line 10 to 15 */
      interrupt_vector = EXTI15_10_IRQn;
    }

    /* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY otherwise FreeRTOS will not be able to mask the interrupt */
    NVIC_EnableIRQ( interrupt_vector );

    gpio_irq_data[gpio->pin_number].owner_port = gpio->port;
    gpio_irq_data[gpio->pin_number].handler    = handler;
    gpio_irq_data[gpio->pin_number].arg        = arg;
  }

exit:
  platform_mcu_powersave_enable();
  return err;
}