[PATCH] Proposal for new GPIO API and example implementation for STM32F4 BSP
oss at c-mauderer.de
oss at c-mauderer.de
Sun Jun 26 07:50:07 UTC 2022
Hello Duc,
Am 25.06.22 um 13:43 schrieb Duc Doan:
> Hello Christian,
>
> On Fri, 2022-06-24 at 17:32 +0200, oss at 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
>
More information about the devel
mailing list