[PATCH] Proposal for new GPIO API and example implementation for STM32F4 BSP
Duc Doan
dtbpkmte at gmail.com
Sat Jun 25 11:43:53 UTC 2022
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
);
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