Hello Duc,

Am 25.06.22 um 13:43 schrieb Duc Doan:
Hello Christian,

On Fri, 2022-06-24 at 17:32 +0200, o...@c-mauderer.de wrote:
Be careful with everything that depends on the BSP. Again: Please
think
about an i2c GPIO expander. That chip can be used on different BSPs.
It
can be even an independent driver that can be used by a user on
demand
on any BSP that supports i2c.

I ended up using a void* so that users can pass anything into it and
the driver/BSP will cast and parse it. Is that a good solution?

Also, here is my updated API:

File: gpio2.h  /********* API header **********/

typedef struct rtems_gpio_handlers rtems_gpio_handlers_t;
typedef struct rtems_gpio_ctrl rtems_gpio_ctrl_t;
typedef struct rtems_gpio_config rtems_gpio_config_t;
typedef struct rtems_gpio_interrupt_config
rtems_gpio_interrupt_config_t;

struct rtems_gpio_handlers {
     rtems_status_code (*initialize)(rtems_gpio_ctrl_t *);

     rtems_status_code (*deinitialize)(rtems_gpio_ctrl_t *);

     rtems_status_code (*configure)(rtems_gpio_ctrl_t *, void *,
rtems_gpio_config_t *);

     rtems_status_code (*configure_interrupt)(rtems_gpio_ctrl_t *, void
*, rtems_gpio_interrupt_config_t *);

     rtems_status_code (*enable_interrupt)(rtems_gpio_ctrl_t *, void *,
rtems_gpio_interrupt_config_t *);

     rtems_status_code (*disable_interrupt)(rtems_gpio_ctrl_t *, void *,
rtems_gpio_interrupt_config_t *);

     rtems_status_code (*set_pin_mode)(rtems_gpio_ctrl_t *, void *,
rtems_gpio_pin_mode);

     rtems_status_code (*set_pull)(rtems_gpio_ctrl_t *, void *,
rtems_gpio_pull);

     rtems_status_code (*read)(rtems_gpio_ctrl_t *, void *,
rtems_gpio_pin_state *);

     rtems_status_code (*write)(rtems_gpio_ctrl_t *, void *,
rtems_gpio_pin_state);

     rtems_status_code (*toggle)(rtems_gpio_ctrl_t *, void *);

};

struct rtems_gpio_ctrl {
     const rtems_gpio_handlers_t *handlers;
};

struct rtems_gpio_config {
     rtems_gpio_pin_mode mode;   /* Pin mode */
     rtems_gpio_pull pull;       /* Pull resistor configuration */
};

struct rtems_gpio_interrupt_config {
     rtems_gpio_interrupt interrupt_mode;        /* Interrupt trigger
mode */
     uint32_t interrupt_number;                  /* Interrupt number */
     uint32_t priority;                          /* Interrupt priority
*/
     void *bsp;                                  /* Pointer to BSP-
specific config */
     void (*handler) (void *arg);                /* Pointer to the IRQ
handler */
     void *arg;                                  /* Pointer to the
arguments of IRQ handler */
};

extern void rtems_gpio_register(
     rtems_gpio_ctrl_t *base,
     const rtems_gpio_handlers_t *handlers
);

extern rtems_status_code rtems_gpio_initialize(
     rtems_gpio_ctrl_t *base
);

extern rtems_status_code rtems_gpio_deinitialize(
     rtems_gpio_ctrl_t *base
);

extern rtems_status_code rtems_gpio_configure(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_config_t *config
);

extern rtems_status_code rtems_gpio_set_pin_mode(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_mode mode
);

extern rtems_status_code rtems_gpio_set_pull(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pull pull
);

Is setting the pull really independent of the mode? Most controller that I know have a pull-Up only on Inputs. Sometimes on an Open-Drain output. Sometimes in another controller (but you might ignore that option). Somethimes you can also set a different strength like 10k pull-up or 100k pull-up.

Best regards

Christian


extern rtems_status_code rtems_gpio_configure_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
);

extern rtems_status_code rtems_gpio_enable_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
);

extern rtems_status_code rtems_gpio_disable_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
);

extern rtems_status_code rtems_gpio_write(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_state value
);

extern rtems_status_code rtems_gpio_read(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_state *value
);

extern rtems_status_code rtems_gpio_ctrl_toggle(
     rtems_gpio_ctrl_t *base,
     void *pin
);
/************************************************/

File: gpio.c (API source)

#include <bsp/gpio2.h>

void rtems_gpio_register(
     rtems_gpio_ctrl_t *base,
     const rtems_gpio_handlers_t *handlers
)
{
     base->handlers = handlers;
}

rtems_status_code rtems_gpio_initialize(
     rtems_gpio_ctrl_t *base
)
{
     return base->handlers->initialize(base);
}

rtems_status_code rtems_gpio_deinitialize(
     rtems_gpio_ctrl_t *base
)
{
     return base->handlers->deinitialize(base);
}

rtems_status_code rtems_gpio_configure(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_config_t *config
)
{
     return base->handlers->configure(base, pin, config);
}

rtems_status_code rtems_gpio_set_pin_mode(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_mode mode
)
{
     return base->handlers->set_pin_mode(base, pin, mode);
}

rtems_status_code rtems_gpio_set_pull(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pull pull
)
{
     return base->handlers->set_pull(base, pin, pull);
}

rtems_status_code rtems_gpio_configure_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
)
{
     return base->handlers->configure_interrupt(base, pin, int_conf);
}

rtems_status_code rtems_gpio_enable_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
)
{
     return base->handlers->enable_interrupt(base, pin, int_conf);
}

rtems_status_code rtems_gpio_disable_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
)
{
     return base->handlers->disable_interrupt(base, pin, int_conf);
}

rtems_status_code rtems_gpio_write(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_state value
)
{
     return base->handlers->write(base, pin, value);
}

rtems_status_code rtems_gpio_read(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_state *value
)
{
     return base->handlers->read(base, pin, value);
}

rtems_status_code rtems_gpio_ctrl_toggle(
     rtems_gpio_ctrl_t *base,
     void *pin
)
{
     return base->handlers->toggle(base, pin);
}
/**************************************************/

File: stm32f4_gpio.h (Header for STM32F4 GPIO)

typedef struct {
     rtems_gpio_ctrl_t base;
     GPIO_TypeDef *port;
     bool is_registered;
} stm32f4_gpio_ctrl_t;

/**
   * @brief STM32F4-specific interrupt configuration structure.
   */
typedef struct {
     rtems_gpio_interrupt_config_t base;
     uint32_t subpriority;  /* Subpriority level of the IRQ */
     bool is_event_mode;     /* Set to true if using Event mode */
} stm32f4_gpio_interrupt_config_t;

typedef struct {
     rtems_gpio_config_t base;   /* Base GPIO config object */

     uint32_t speed;             /* Speed of the pin. Must be specified
*/

     uint32_t alternate_mode;    /* Open drain or Push-pull mode
                                    Use if the pin is in Alternate mode
*/
     uint32_t alternate_fn;      /* The alternate function of the pin
                                    Use if the pin is in Alternate mode
*/
} stm32f4_gpio_config_t;

rtems_status_code stm32f4_gpio_get_ctrl(GPIO_TypeDef *port,
rtems_gpio_ctrl_t **out);

/************************************************/

File: bsps/arm/stm32f4/gpio/gpio.c (STM32F4 GPIO source)

#include <bsp.h>
#include <rtems.h>
#include <bsp/stm32f4_gpio.h>

static rtems_status_code stm32f4_gpio_initialize(
     rtems_gpio_ctrl_t *base
);

static rtems_status_code stm32f4_gpio_deinitialize(
     rtems_gpio_ctrl_t *base
);

static rtems_status_code stm32f4_gpio_configure(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_config_t *config
);

static rtems_status_code stm32f4_gpio_configure_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
);

static rtems_status_code stm32f4_gpio_enable_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
);

static rtems_status_code stm32f4_gpio_disable_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
);

static rtems_status_code stm32f4_gpio_set_pin_mode(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_mode mode
);

static rtems_status_code stm32f4_gpio_set_pull(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pull pull
);

static rtems_status_code stm32f4_gpio_read(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_state *value
);
static rtems_status_code stm32f4_gpio_write(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_state value
);

static rtems_status_code stm32f4_gpio_toggle(
     rtems_gpio_ctrl_t *base,
     void *pin
);

static const rtems_gpio_handlers_t stm32f4_gpio_handlers = {
     .initialize = stm32f4_gpio_initialize,
     .deinitialize = stm32f4_gpio_deinitialize,
     .configure = stm32f4_gpio_configure,
     .configure_interrupt = stm32f4_gpio_configure_interrupt,
     .enable_interrupt = stm32f4_gpio_enable_interrupt,
     .disable_interrupt = stm32f4_gpio_disable_interrupt,
     .set_pin_mode = stm32f4_gpio_set_pin_mode,
     .set_pull = stm32f4_gpio_set_pull,
     .read = stm32f4_gpio_read,
     .write = stm32f4_gpio_write,
     .toggle = stm32f4_gpio_toggle
};

stm32f4_gpio_ctrl_t gpioa_ctrl = { .port = GPIOA };
stm32f4_gpio_ctrl_t gpiob_ctrl = { .port = GPIOB };
stm32f4_gpio_ctrl_t gpioc_ctrl = { .port = GPIOC };
stm32f4_gpio_ctrl_t gpiod_ctrl = { .port = GPIOD };
stm32f4_gpio_ctrl_t gpioe_ctrl = { .port = GPIOE };
stm32f4_gpio_ctrl_t gpiof_ctrl = { .port = GPIOF };
stm32f4_gpio_ctrl_t gpiog_ctrl = { .port = GPIOG };
stm32f4_gpio_ctrl_t gpioh_ctrl = { .port = GPIOG };
stm32f4_gpio_ctrl_t gpioi_ctrl = { .port = GPIOI };
#ifdef STM32F429X
stm32f4_gpio_ctrl_t gpioj_ctrl = { .port = GPIOJ };
stm32f4_gpio_ctrl_t gpiok_ctrl = { .port = GPIOK };
#endif /* STM32F429X */

rtems_status_code stm32f4_gpio_get_ctrl(GPIO_TypeDef *port,
rtems_gpio_ctrl_t **out) {
     switch ((uintptr_t) port) {
         case (uintptr_t) GPIOA:
             *out = (rtems_gpio_ctrl_t *) &gpioa_ctrl;
             break;
         case (uintptr_t) GPIOB:
             *out = (rtems_gpio_ctrl_t *) &gpiob_ctrl;
             break;
         case (uintptr_t) GPIOC:
             *out = (rtems_gpio_ctrl_t *) &gpioc_ctrl;
             break;
         case (uintptr_t) GPIOD:
             *out = (rtems_gpio_ctrl_t *) &gpiod_ctrl;
             break;
         case (uintptr_t) GPIOE:
             *out = (rtems_gpio_ctrl_t *) &gpioe_ctrl;
             break;
         case (uintptr_t) GPIOF:
             *out = (rtems_gpio_ctrl_t *) &gpiof_ctrl;
             break;
         case (uintptr_t) GPIOG:
             *out = (rtems_gpio_ctrl_t *) &gpiog_ctrl;
             break;
         case (uintptr_t) GPIOH:
             *out = (rtems_gpio_ctrl_t *) &gpiog_ctrl;
             break;
         case (uintptr_t) GPIOI:
             *out = (rtems_gpio_ctrl_t *) &gpioi_ctrl;
             break;
#ifdef STM32F429X
         case (uintptr_t) GPIOJ:
             *out = (rtems_gpio_ctrl_t *) &gpioj_ctrl;
             break;
         case (uintptr_t) GPIOK:
             *out = (rtems_gpio_ctrl_t *) &gpiok_ctrl;
             break;
#endif /* STM32F429X */
         default:
             return RTEMS_UNSATISFIED;
     }
     if (((stm32f4_gpio_ctrl_t *) (*out))->is_registered == false) {
         rtems_gpio_register(*out, &stm32f4_gpio_handlers);
         ((stm32f4_gpio_ctrl_t *) (*out))->is_registered = true;
     }
     return RTEMS_SUCCESSFUL;
}

static stm32f4_gpio_ctrl_t *get_ctrl_from_base(
     rtems_gpio_ctrl_t *base
)
{
     return RTEMS_CONTAINER_OF(base, stm32f4_gpio_ctrl_t, base);
}

static stm32f4_gpio_config_t *get_config_from_base(
     rtems_gpio_config_t *config
)
{
     return RTEMS_CONTAINER_OF(config, stm32f4_gpio_config_t, base);
}

static stm32f4_gpio_interrupt_config_t *get_interrupt_config_from_base(
     rtems_gpio_interrupt_config_t *int_conf
)
{
     return RTEMS_CONTAINER_OF(int_conf,
stm32f4_gpio_interrupt_config_t, base);
}

static rtems_status_code stm32f4_gpio_initialize(rtems_gpio_ctrl_t
*base) {
     stm32f4_gpio_ctrl_t *ctrl = get_ctrl_from_base(base);
switch ((uintptr_t) ctrl->port) {
         case (uintptr_t) GPIOA:
             __HAL_RCC_GPIOA_CLK_ENABLE();
             break;
         case (uintptr_t) GPIOB:
             __HAL_RCC_GPIOB_CLK_ENABLE();
             break;
         case (uintptr_t) GPIOC:
             __HAL_RCC_GPIOC_CLK_ENABLE();
             break;
         case (uintptr_t) GPIOD:
             __HAL_RCC_GPIOD_CLK_ENABLE();
             break;
         case (uintptr_t) GPIOE:
             __HAL_RCC_GPIOE_CLK_ENABLE();
             break;
         case (uintptr_t) GPIOF:
             __HAL_RCC_GPIOF_CLK_ENABLE();
             break;
         case (uintptr_t) GPIOG:
             __HAL_RCC_GPIOG_CLK_ENABLE();
             break;
         case (uintptr_t) GPIOH:
             __HAL_RCC_GPIOH_CLK_ENABLE();
             break;
         case (uintptr_t) GPIOI:
             __HAL_RCC_GPIOI_CLK_ENABLE();
             break;
#ifdef STM32F429X
         case (uintptr_t) GPIOJ:
             __HAL_RCC_GPIOJ_CLK_ENABLE();
             break;
         case (uintptr_t) GPIOK:
             __HAL_RCC_GPIOK_CLK_ENABLE();
             break;
#endif /* STM32F429X */
         default:
             return RTEMS_UNSATISFIED;
     }
     return RTEMS_SUCCESSFUL;
}

static rtems_status_code stm32f4_gpio_deinitialize(rtems_gpio_ctrl_t
*base) {
     stm32f4_gpio_ctrl_t *ctrl = get_ctrl_from_base(base);
switch ((uintptr_t) ctrl->port) {
         case (uintptr_t) GPIOA:
             __HAL_RCC_GPIOA_CLK_DISABLE();
             break;
         case (uintptr_t) GPIOB:
             __HAL_RCC_GPIOB_CLK_DISABLE();
             break;
         case (uintptr_t) GPIOC:
             __HAL_RCC_GPIOC_CLK_DISABLE();
             break;
         case (uintptr_t) GPIOD:
             __HAL_RCC_GPIOD_CLK_DISABLE();
             break;
         case (uintptr_t) GPIOE:
             __HAL_RCC_GPIOE_CLK_DISABLE();
             break;
         case (uintptr_t) GPIOF:
             __HAL_RCC_GPIOF_CLK_DISABLE();
             break;
         case (uintptr_t) GPIOG:
             __HAL_RCC_GPIOG_CLK_DISABLE();
             break;
         case (uintptr_t) GPIOH:
             __HAL_RCC_GPIOH_CLK_DISABLE();
             break;
         case (uintptr_t) GPIOI:
             __HAL_RCC_GPIOI_CLK_DISABLE();
             break;
#ifdef STM32F429X
         case (uintptr_t) GPIOJ:
             __HAL_RCC_GPIOJ_CLK_DISABLE();
             break;
         case (uintptr_t) GPIOK:
             __HAL_RCC_GPIOK_CLK_DISABLE();
             break;
#endif /* STM32F429X */
         default:
             return RTEMS_UNSATISFIED;
     }
     return RTEMS_SUCCESSFUL;
}

/**
   * @note Warning: only one pin can be passed as argument
   * @note If using interrupt mode, use
rtems_gpio_configure_interrupt().
   * @note If using alternate mode, use rtems_gpio_configure().
   */
rtems_status_code stm32f4_gpio_set_pin_mode(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_mode mode
)
{
     stm32f4_gpio_ctrl_t *ctrl = get_ctrl_from_base(base);
     uint32_t pin_mask = *(uint32_t *)pin;

     uint32_t stm32f4_mode, stm32f4_output_type;
     switch (mode) {
     case RTEMS_GPIO_PINMODE_OUTPUT_PP:
         stm32f4_mode = LL_GPIO_MODE_OUTPUT;
         stm32f4_output_type = LL_GPIO_OUTPUT_PUSHPULL;
         break;
     case RTEMS_GPIO_PINMODE_OUTPUT_OD:
         stm32f4_mode = LL_GPIO_MODE_OUTPUT;
         stm32f4_output_type = LL_GPIO_OUTPUT_OPENDRAIN;
         break;
     case RTEMS_GPIO_PINMODE_INPUT:
         stm32f4_mode = LL_GPIO_MODE_INPUT;
         break;
     case RTEMS_GPIO_PINMODE_ANALOG:
         stm32f4_mode = LL_GPIO_MODE_ANALOG;
         break;
     case RTEMS_GPIO_PINMODE_BSP_SPECIFIC:
         /* use rtems_gpio_configure() instead */
         stm32f4_mode = LL_GPIO_MODE_ALTERNATE;
         break;
     default:
         /* illegal argument */
         return RTEMS_UNSATISFIED;
     }
     LL_GPIO_SetPinMode((GPIO_TypeDef *) ctrl->port, pin_mask,
stm32f4_mode);
     if (stm32f4_mode == LL_GPIO_MODE_OUTPUT) {
         LL_GPIO_SetPinOutputType((GPIO_TypeDef *) ctrl->port, pin_mask,
stm32f4_output_type);
     }

     return RTEMS_SUCCESSFUL;
}

/**
   * @note Warning: only one pin can be passed as argument
   */
rtems_status_code stm32f4_gpio_set_pull(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pull pull
)
{
     stm32f4_gpio_ctrl_t *ctrl = get_ctrl_from_base(base);
     uint32_t pin_mask = *(uint32_t *)pin;
     uint32_t stm32f4_pull;

     switch (pull) {
     case RTEMS_GPIO_NOPULL:
         stm32f4_pull = LL_GPIO_PULL_NO;
         break;
     case RTEMS_GPIO_PULLUP:
         stm32f4_pull = LL_GPIO_PULL_UP;
         break;
     case RTEMS_GPIO_PULLDOWN:
         stm32f4_pull = LL_GPIO_PULL_DOWN;
         break;
     default:
         /* Illegal argument */
         return RTEMS_UNSATISFIED;
     }
     LL_GPIO_SetPinPull((GPIO_TypeDef *) ctrl->port, pin_mask,
stm32f4_pull);
     return RTEMS_SUCCESSFUL;
}

rtems_status_code stm32f4_gpio_configure(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_config_t *config
)
{
     stm32f4_gpio_ctrl_t *ctrl = get_ctrl_from_base(base);
     stm32f4_gpio_config_t *stm32_conf = get_config_from_base(config);
     uint32_t pin_mask = *(uint32_t *)pin;
     GPIO_InitTypeDef init_struct;

     // Pin number
     init_struct.Pin = pin_mask;
// Pin mode
     switch (config->mode) {
     case RTEMS_GPIO_PINMODE_OUTPUT_PP:
         init_struct.Mode = GPIO_MODE_OUTPUT_PP;
         break;
     case RTEMS_GPIO_PINMODE_OUTPUT_OD:
         init_struct.Mode = GPIO_MODE_OUTPUT_OD;
         break;
     case RTEMS_GPIO_PINMODE_INPUT:
         init_struct.Mode = GPIO_MODE_INPUT;
         break;
     case RTEMS_GPIO_PINMODE_ANALOG:
         init_struct.Mode = GPIO_MODE_ANALOG;
         break;
     case RTEMS_GPIO_PINMODE_BSP_SPECIFIC:
         /* Alternate mode */
         init_struct.Mode = stm32_conf->alternate_mode;
         break;
     default:
         /* illegal argument */
         return RTEMS_UNSATISFIED;
     }

     // Pin pull resistor
     switch (config->pull) {
         case RTEMS_GPIO_NOPULL:
             init_struct.Pull = GPIO_NOPULL;
             break;
         case RTEMS_GPIO_PULLUP:
             init_struct.Pull = GPIO_PULLUP;
             break;
         case RTEMS_GPIO_PULLDOWN:
             init_struct.Pull = GPIO_PULLDOWN;
             break;
         default:
             return RTEMS_UNSATISFIED;
     }
// Pin speed
     init_struct.Speed = stm32_conf->speed;

     // Pin alternate functionality
     if (config->mode == RTEMS_GPIO_PINMODE_BSP_SPECIFIC) {
         init_struct.Alternate = stm32_conf->alternate_fn;
     }

     // Call HAL to configure the GPIO pin
     HAL_GPIO_Init(ctrl->port, &init_struct);

     return RTEMS_SUCCESSFUL;
}

/**
   * TODO
   *
   * @note This function defaults to not using pull resistor.
   *       Use rtems_gpio_set_pull() afterwards to change.
   */
rtems_status_code stm32f4_gpio_configure_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
)
{
     stm32f4_gpio_ctrl_t *ctrl = get_ctrl_from_base(base);
     stm32f4_gpio_interrupt_config_t *stm32_int_conf =
get_interrupt_config_from_base(int_conf);
     uint32_t pin_mask = *(uint32_t *)pin;
     GPIO_InitTypeDef hal_conf;

     switch (int_conf->interrupt_mode) {
     case RTEMS_GPIO_INT_MODE_NONE:
         return RTEMS_SUCCESSFUL;
     case RTEMS_GPIO_INT_MODE_FALLING:
         if (stm32_int_conf->is_event_mode) {
             hal_conf.Mode = GPIO_MODE_EVT_FALLING;
         } else {
             hal_conf.Mode = GPIO_MODE_IT_FALLING;
         }
         break;
     case RTEMS_GPIO_INT_MODE_RISING:
         if (stm32_int_conf->is_event_mode) {
             hal_conf.Mode = GPIO_MODE_EVT_RISING;
         } else {
             hal_conf.Mode = GPIO_MODE_IT_RISING;
         }
         break;
     case RTEMS_GPIO_INT_MODE_BOTH_EDGES:
         if (stm32_int_conf->is_event_mode) {
             hal_conf.Mode = GPIO_MODE_EVT_RISING_FALLING;
         } else {
             hal_conf.Mode = GPIO_MODE_IT_RISING_FALLING;
         }
         break;
     default:
         /* Invalid argument */
         return RTEMS_UNSATISFIED;
     }
     hal_conf.Pull = GPIO_NOPULL;
     hal_conf.Pin = pin_mask;
     HAL_GPIO_Init(ctrl->port, &hal_conf);

     HAL_NVIC_SetPriority((IRQn_Type) int_conf->interrupt_number,
int_conf->priority, stm32_int_conf->subpriority);

     return RTEMS_SUCCESSFUL;
}

static rtems_status_code stm32f4_gpio_enable_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
)
{
     HAL_NVIC_EnableIRQ((IRQn_Type) int_conf->interrupt_number);
     return RTEMS_SUCCESSFUL;
}

static rtems_status_code stm32f4_gpio_disable_interrupt(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_interrupt_config_t *int_conf
)
{
     HAL_NVIC_DisableIRQ((IRQn_Type) int_conf->interrupt_number);
     return RTEMS_SUCCESSFUL;
}

rtems_status_code stm32f4_gpio_write(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_state value
)
{
     stm32f4_gpio_ctrl_t *ctrl = get_ctrl_from_base(base);
     uint32_t pin_mask = *(uint32_t *)pin;

     HAL_GPIO_WritePin(ctrl->port, pin_mask, value);
     return RTEMS_SUCCESSFUL;
}

rtems_status_code stm32f4_gpio_read(
     rtems_gpio_ctrl_t *base,
     void *pin,
     rtems_gpio_pin_state *value
)
{
     stm32f4_gpio_ctrl_t *ctrl = get_ctrl_from_base(base);
     uint32_t pin_mask = *(uint32_t *)pin;

     *value = HAL_GPIO_ReadPin(ctrl->port, pin_mask);
     return RTEMS_SUCCESSFUL;
}

rtems_status_code stm32f4_gpio_toggle(
     rtems_gpio_ctrl_t *base,
     void *pin
)
{
     stm32f4_gpio_ctrl_t *ctrl = get_ctrl_from_base(base);
     uint32_t pin_mask = *(uint32_t *)pin;

     HAL_GPIO_TogglePin(ctrl->port, pin_mask);
     return RTEMS_SUCCESSFUL;
}
/**********************************************************/

I am still testing and modifying the external interrupt part.

Please let me know what you think the code. Thank you.

Best,

Duc Doan

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to