Commit 5cd274ce authored by Mathieu Choplain's avatar Mathieu Choplain Committed by Anas Nashif
Browse files

drivers: intc: stm32: make stm32_exti_line_t opaque

This commit makes the contents of the stm32_exti_line_t data type opaque to
the EXTI GPIO interrupt controller API users. The GPIO driver is updated
to comply with this API change.

N.B.: while some assertions are removed as part of this commit, they were
broken since forever anyways, so nothing of value is lost.

Signed-off-by: default avatarMathieu Choplain <mathieu.choplain@st.com>
parent 0551825c
Loading
Loading
Loading
Loading
+12 −10
Changes for drivers/gpio/gpio_stm32.c: 12 added lines, 10 removed lines.
Original line number Diff line number Diff line
@@ -39,11 +39,11 @@ LOG_MODULE_REGISTER(stm32, CONFIG_GPIO_LOG_LEVEL);
/**
 * @brief EXTI interrupt callback
 */
static void gpio_stm32_isr(stm32_exti_line_t line, void *arg)
static void gpio_stm32_isr(gpio_port_pins_t pin, void *arg)
{
	struct gpio_stm32_data *data = arg;

	gpio_fire_callbacks(&data->cb, data->dev, BIT(line));
	gpio_fire_callbacks(&data->cb, data->dev, pin);
}

/**
@@ -505,24 +505,26 @@ static int gpio_stm32_pin_interrupt_configure(const struct device *dev,
{
	const struct gpio_stm32_config *cfg = dev->config;
	struct gpio_stm32_data *data = dev->data;
	const stm32_exti_line_t exti_line =
				stm32_exti_get_pin_exti_line(cfg->port, pin);
	uint32_t edge = 0;
	int err = 0;

#ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
	if (mode == GPIO_INT_MODE_DISABLE_ONLY) {
		stm32_exti_disable(pin);
		stm32_exti_disable(exti_line);
		goto exit;
	} else if (mode == GPIO_INT_MODE_ENABLE_ONLY) {
		stm32_exti_enable(pin);
		stm32_exti_enable(exti_line);
		goto exit;
	}
#endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */

	if (mode == GPIO_INT_MODE_DISABLED) {
		if (stm32_exti_get_line_src_port(pin) == cfg->port) {
			stm32_exti_disable(pin);
			stm32_exti_unset_callback(pin);
			stm32_exti_trigger(pin, STM32_EXTI_TRIG_NONE);
			stm32_exti_disable(exti_line);
			stm32_exti_unset_callback(exti_line);
			stm32_exti_trigger(exti_line, STM32_EXTI_TRIG_NONE);
		}
		/* else: No irq source configured for pin. Nothing to disable */
		goto exit;
@@ -534,7 +536,7 @@ static int gpio_stm32_pin_interrupt_configure(const struct device *dev,
		goto exit;
	}

	if (stm32_exti_set_callback(pin, gpio_stm32_isr, data) != 0) {
	if (stm32_exti_set_callback(exti_line, gpio_stm32_isr, data) != 0) {
		err = -EBUSY;
		goto exit;
	}
@@ -556,9 +558,9 @@ static int gpio_stm32_pin_interrupt_configure(const struct device *dev,

	stm32_exti_set_line_src_port(pin, cfg->port);

	stm32_exti_trigger(pin, edge);
	stm32_exti_trigger(exti_line, edge);

	stm32_exti_enable(pin);
	stm32_exti_enable(exti_line);

exit:
	return err;
+71 −46
Changes for drivers/interrupt_controller/intc_exti_stm32.c: 71 added lines, 46 removed lines.
Original line number Diff line number Diff line
@@ -77,19 +77,14 @@ static inline uint32_t stm32_exti_linenum_to_src_cfg_line(gpio_pin_t linenum)
 */
static inline int stm32_exti_is_pending(stm32_exti_line_t line)
{
	if (line < NUM_EXTI_LINES) {
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
		return (LL_EXTI_IsActiveRisingFlag_0_31(BIT(line)) ||
			LL_EXTI_IsActiveFallingFlag_0_31(BIT(line)));
	return (LL_EXTI_IsActiveRisingFlag_0_31(line) ||
		LL_EXTI_IsActiveFallingFlag_0_31(line));
#elif defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
		return LL_C2_EXTI_IsActiveFlag_0_31(BIT(line));
	return LL_C2_EXTI_IsActiveFlag_0_31(line);
#else
		return LL_EXTI_IsActiveFlag_0_31(BIT(line));
	return LL_EXTI_IsActiveFlag_0_31(line);
#endif
	} else {
		__ASSERT_NO_MSG(0);
		return 0;
	}
}

/**
@@ -99,18 +94,30 @@ static inline int stm32_exti_is_pending(stm32_exti_line_t line)
 */
static inline void stm32_exti_clear_pending(stm32_exti_line_t line)
{
	if (line < NUM_EXTI_LINES) {
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
		LL_EXTI_ClearRisingFlag_0_31(BIT(line));
		LL_EXTI_ClearFallingFlag_0_31(BIT(line));
	LL_EXTI_ClearRisingFlag_0_31(line);
	LL_EXTI_ClearFallingFlag_0_31(line);
#elif defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
		LL_C2_EXTI_ClearFlag_0_31(BIT(line));
	LL_C2_EXTI_ClearFlag_0_31(line);
#else
		LL_EXTI_ClearFlag_0_31(BIT(line));
	LL_EXTI_ClearFlag_0_31(line);
#endif
	} else {
		__ASSERT_NO_MSG(0);
}

/**
 * @returns the LL_EXTI_LINE_n define for EXTI line number @p linenum
 */
static inline stm32_exti_line_t linenum_to_ll_exti_line(gpio_pin_t linenum)
{
	return BIT(linenum);
}

/**
 * @returns EXTI line number for LL_EXTI_LINE_n define
 */
static inline gpio_pin_t ll_exti_line_to_linenum(stm32_exti_line_t line)
{
	return LOG2(line);
}

/**
@@ -126,21 +133,25 @@ static void stm32_exti_isr(const void *exti_range)
	struct stm32_exti_data *data = dev->data;
	const struct stm32_exti_range *range = exti_range;
	stm32_exti_line_t line;
	uint32_t line_num;

	/* see which bits are set */
	for (uint8_t i = 0; i <= range->len; i++) {
		line = range->start + i;
		line_num = range->start + i;
		line = linenum_to_ll_exti_line(line_num);

		/* check if interrupt is pending */
		if (stm32_exti_is_pending(line) != 0) {
			/* clear pending interrupt */
			stm32_exti_clear_pending(line);

			/* run callback only if one is registered */
			if (!data->cb[line].cb) {
			if (!data->cb[line_num].cb) {
				continue;
			}

			data->cb[line].cb(line, data->cb[line].data);
			/* `line` can be passed as-is because LL_EXTI_LINE_n is (1 << n) */
			data->cb[line_num].cb(line, data->cb[line_num].data);
		}
	}
}
@@ -227,21 +238,39 @@ DEVICE_DT_DEFINE(EXTI_NODE, &stm32_exti_init,
 * @brief EXTI GPIO interrupt controller API implementation
 */

/**
 * @internal
 * STM32 EXTI driver:
 * The type @ref stm32_exti_line_t is used to hold the LL_EXTI_LINE_xxx
 * defines of the LL EXTI API that corresponds to the provided pin.
 *
 * The port is not part of these definitions because port configuration
 * is done via different APIs, which use the LL_<PPP>_EXTI_LINE_xxx defines
 * returned by @ref stm32_exti_linenum_to_src_cfg_line instead.
 * @endinternal
 */
stm32_exti_line_t stm32_exti_get_pin_exti_line(uint32_t port, gpio_pin_t pin)
{
	ARG_UNUSED(port);
	return linenum_to_ll_exti_line(pin);
}

void stm32_exti_enable(stm32_exti_line_t line)
{
	int irqnum = 0;
	unsigned int irqnum;
	uint32_t line_num = ll_exti_line_to_linenum(line);

	__ASSERT_NO_MSG(line < NUM_EXTI_LINES);
	__ASSERT_NO_MSG(line_num < NUM_EXTI_LINES);

	/* Get matching exti irq provided line thanks to irq_table */
	irqnum = exti_irq_table[line];
	irqnum = exti_irq_table[line_num];
	__ASSERT_NO_MSG(irqnum != 0xFF);

	/* Enable requested line interrupt */
#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
	LL_C2_EXTI_EnableIT_0_31(BIT(line));
	LL_C2_EXTI_EnableIT_0_31(line);
#else
	LL_EXTI_EnableIT_0_31(BIT(line));
	LL_EXTI_EnableIT_0_31(line);
#endif

	/* Enable exti irq interrupt */
@@ -250,39 +279,33 @@ void stm32_exti_enable(stm32_exti_line_t line)

void stm32_exti_disable(stm32_exti_line_t line)
{
	if (line < NUM_EXTI_LINES) {
#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
		LL_C2_EXTI_DisableIT_0_31(BIT(line));
	LL_C2_EXTI_DisableIT_0_31(line);
#else
		LL_EXTI_DisableIT_0_31(BIT(line));
	LL_EXTI_DisableIT_0_31(line);
#endif
	} else {
		__ASSERT_NO_MSG(0);
	}
}

void stm32_exti_trigger(stm32_exti_line_t line, uint32_t trigger)
{
	__ASSERT_NO_MSG(line < NUM_EXTI_LINES);

	z_stm32_hsem_lock(CFG_HW_EXTI_SEMID, HSEM_LOCK_DEFAULT_RETRY);

	switch (trigger) {
	case STM32_EXTI_TRIG_NONE:
		LL_EXTI_DisableRisingTrig_0_31(BIT(line));
		LL_EXTI_DisableFallingTrig_0_31(BIT(line));
		LL_EXTI_DisableRisingTrig_0_31(line);
		LL_EXTI_DisableFallingTrig_0_31(line);
		break;
	case STM32_EXTI_TRIG_RISING:
		LL_EXTI_EnableRisingTrig_0_31(BIT(line));
		LL_EXTI_DisableFallingTrig_0_31(BIT(line));
		LL_EXTI_EnableRisingTrig_0_31(line);
		LL_EXTI_DisableFallingTrig_0_31(line);
		break;
	case STM32_EXTI_TRIG_FALLING:
		LL_EXTI_EnableFallingTrig_0_31(BIT(line));
		LL_EXTI_DisableRisingTrig_0_31(BIT(line));
		LL_EXTI_EnableFallingTrig_0_31(line);
		LL_EXTI_DisableRisingTrig_0_31(line);
		break;
	case STM32_EXTI_TRIG_BOTH:
		LL_EXTI_EnableRisingTrig_0_31(BIT(line));
		LL_EXTI_EnableFallingTrig_0_31(BIT(line));
		LL_EXTI_EnableRisingTrig_0_31(line);
		LL_EXTI_EnableFallingTrig_0_31(line);
		break;
	default:
		__ASSERT_NO_MSG(0);
@@ -295,18 +318,19 @@ int stm32_exti_set_callback(stm32_exti_line_t line, stm32_exti_callback_t cb, vo
{
	const struct device *const dev = DEVICE_DT_GET(EXTI_NODE);
	struct stm32_exti_data *data = dev->data;
	uint32_t line_num = ll_exti_line_to_linenum(line);

	if ((data->cb[line].cb == cb) && (data->cb[line].data == arg)) {
	if ((data->cb[line_num].cb == cb) && (data->cb[line_num].data == arg)) {
		return 0;
	}

	/* if callback already exists/maybe-running return busy */
	if (data->cb[line].cb != NULL) {
	if (data->cb[line_num].cb != NULL) {
		return -EBUSY;
	}

	data->cb[line].cb = cb;
	data->cb[line].data = arg;
	data->cb[line_num].cb = cb;
	data->cb[line_num].data = arg;

	return 0;
}
@@ -315,9 +339,10 @@ void stm32_exti_unset_callback(stm32_exti_line_t line)
{
	const struct device *const dev = DEVICE_DT_GET(EXTI_NODE);
	struct stm32_exti_data *data = dev->data;
	uint32_t line_num = ll_exti_line_to_linenum(line);

	data->cb[line].cb = NULL;
	data->cb[line].data = NULL;
	data->cb[line_num].cb = NULL;
	data->cb[line_num].data = NULL;
}

void stm32_exti_set_line_src_port(gpio_pin_t line, uint32_t port)
+9 −3
Changes for include/zephyr/drivers/interrupt_controller/exti_stm32.h: 9 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -25,10 +25,16 @@
#include <zephyr/drivers/gpio.h>

/**
 * @brief Type representing an EXTI line number
 * @brief Opaque type representing an EXTI line
 */
typedef uint32_t stm32_exti_line_t;

/**
 * @brief Get the EXTI interrupt line value corresponding
 *        to specified @p pin of GPIO port @p port
 */
stm32_exti_line_t stm32_exti_get_pin_exti_line(uint32_t port, gpio_pin_t pin);

/**
 * @brief Enable EXTI interrupts for specified line
 *
@@ -68,12 +74,12 @@ void stm32_exti_trigger(stm32_exti_line_t line, uint32_t trg);
/**
 * @brief EXTI interrupt callback function signature
 *
 * @param line	Triggered EXTI interrupt line
 * @param pin	GPIO pin on which interrupt occurred
 * @param user	@p data provided to @ref stm32_exti_set_callback
 *
 * @note This callback is invoked in ISR context.
 */
typedef void (*stm32_exti_callback_t)(stm32_exti_line_t line, void *user);
typedef void (*stm32_exti_callback_t)(gpio_port_pins_t pin, void *user);

/**
 * @brief Set callback invoked when an interrupt occurs on specified EXTI line