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

drivers: intc: stm32: rebrand EXTI API to be hardware-agnostic

This commit rebrands the STM32 EXTI API to a more hardware-agnostic
"GPIO interrupt controller" API, in anticipation of the introduction of
new series lacking the EXTI peripheral. The GPIO and EXTI drivers are
updated to match the rebranded API.

Signed-off-by: default avatarMathieu Choplain <mathieu.choplain@st.com>
parent 5cd274ce
Loading
Loading
Loading
Loading
+28 −17
Changes for drivers/gpio/gpio_stm32.c: 28 added lines, 17 removed lines.
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
#include <zephyr/sys/util.h>
#include <zephyr/drivers/interrupt_controller/exti_stm32.h>
#include <zephyr/drivers/interrupt_controller/gpio_intc_stm32.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/drivers/misc/stm32_wkup_pins/stm32_wkup_pins.h>
@@ -156,6 +156,21 @@ static inline uint32_t stm32_pinval_get(gpio_pin_t pin)
	return pinval;
}

static inline void gpio_stm32_disable_pin_irqs(uint32_t port, gpio_pin_t pin)
{
#if defined(CONFIG_EXTI_STM32)
	if (port != stm32_exti_get_line_src_port(pin)) {
		/* EXTI line not owned by this port - do nothing */
		return;
	}
#endif
	stm32_gpio_irq_line_t irq_line = stm32_gpio_intc_get_pin_irq_line(port, pin);

	stm32_gpio_intc_disable_line(irq_line);
	stm32_gpio_intc_remove_irq_callback(irq_line);
	stm32_gpio_intc_select_line_trigger(irq_line, STM32_GPIO_IRQ_TRIG_NONE);
}

/**
 * @brief Configure the hardware.
 */
@@ -505,28 +520,22 @@ 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);
	const stm32_gpio_irq_line_t irq_line = stm32_gpio_intc_get_pin_irq_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(exti_line);
		stm32_gpio_intc_disable_line(irq_line);
		goto exit;
	} else if (mode == GPIO_INT_MODE_ENABLE_ONLY) {
		stm32_exti_enable(exti_line);
		stm32_gpio_intc_enable_line(irq_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(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 */
		gpio_stm32_disable_pin_irqs(cfg->port, pin);
		goto exit;
	}

@@ -536,31 +545,33 @@ static int gpio_stm32_pin_interrupt_configure(const struct device *dev,
		goto exit;
	}

	if (stm32_exti_set_callback(exti_line, gpio_stm32_isr, data) != 0) {
	if (stm32_gpio_intc_set_irq_callback(irq_line, gpio_stm32_isr, data) != 0) {
		err = -EBUSY;
		goto exit;
	}

	switch (trig) {
	case GPIO_INT_TRIG_LOW:
		edge = STM32_EXTI_TRIG_FALLING;
		edge = STM32_GPIO_IRQ_TRIG_FALLING;
		break;
	case GPIO_INT_TRIG_HIGH:
		edge = STM32_EXTI_TRIG_RISING;
		edge = STM32_GPIO_IRQ_TRIG_RISING;
		break;
	case GPIO_INT_TRIG_BOTH:
		edge = STM32_EXTI_TRIG_BOTH;
		edge = STM32_GPIO_IRQ_TRIG_BOTH;
		break;
	default:
		err = -EINVAL;
		goto exit;
	}

#if defined(CONFIG_EXTI_STM32)
	stm32_exti_set_line_src_port(pin, cfg->port);
#endif

	stm32_exti_trigger(exti_line, edge);
	stm32_gpio_intc_select_line_trigger(irq_line, edge);

	stm32_exti_enable(exti_line);
	stm32_gpio_intc_enable_line(irq_line);

exit:
	return err;
+18 −18
Changes for drivers/interrupt_controller/intc_exti_stm32.c: 18 added lines, 18 removed lines.
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/util.h>
#include <zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h> /* For STM32L0 series */
#include <zephyr/drivers/interrupt_controller/exti_stm32.h>
#include <zephyr/drivers/interrupt_controller/gpio_intc_stm32.h>
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
#include <zephyr/irq.h>

@@ -41,7 +41,7 @@ static IRQn_Type exti_irq_table[NUM_EXTI_LINES] = {[0 ... NUM_EXTI_LINES - 1] =

/* User callback wrapper */
struct __exti_cb {
	stm32_exti_callback_t cb;
	stm32_gpio_irq_cb_t cb;
	void *data;
};

@@ -75,7 +75,7 @@ static inline uint32_t stm32_exti_linenum_to_src_cfg_line(gpio_pin_t linenum)
 *
 * @param line EXTI line number
 */
static inline int stm32_exti_is_pending(stm32_exti_line_t line)
static inline int stm32_exti_is_pending(stm32_gpio_irq_line_t line)
{
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
	return (LL_EXTI_IsActiveRisingFlag_0_31(line) ||
@@ -92,7 +92,7 @@ static inline int stm32_exti_is_pending(stm32_exti_line_t line)
 *
 * @param line EXTI line number
 */
static inline void stm32_exti_clear_pending(stm32_exti_line_t line)
static inline void stm32_exti_clear_pending(stm32_gpio_irq_line_t line)
{
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
	LL_EXTI_ClearRisingFlag_0_31(line);
@@ -107,7 +107,7 @@ static inline void stm32_exti_clear_pending(stm32_exti_line_t line)
/**
 * @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)
static inline stm32_gpio_irq_line_t linenum_to_ll_exti_line(gpio_pin_t linenum)
{
	return BIT(linenum);
}
@@ -115,7 +115,7 @@ static inline stm32_exti_line_t linenum_to_ll_exti_line(gpio_pin_t 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)
static inline gpio_pin_t ll_exti_line_to_linenum(stm32_gpio_irq_line_t line)
{
	return LOG2(line);
}
@@ -132,7 +132,7 @@ static void stm32_exti_isr(const void *exti_range)
	const struct device *dev = DEVICE_DT_GET(EXTI_NODE);
	struct stm32_exti_data *data = dev->data;
	const struct stm32_exti_range *range = exti_range;
	stm32_exti_line_t line;
	stm32_gpio_irq_line_t line;
	uint32_t line_num;

	/* see which bits are set */
@@ -241,7 +241,7 @@ DEVICE_DT_DEFINE(EXTI_NODE, &stm32_exti_init,
/**
 * @internal
 * STM32 EXTI driver:
 * The type @ref stm32_exti_line_t is used to hold the LL_EXTI_LINE_xxx
 * The type @ref stm32_gpio_irq_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
@@ -249,13 +249,13 @@ DEVICE_DT_DEFINE(EXTI_NODE, &stm32_exti_init,
 * 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)
stm32_gpio_irq_line_t stm32_gpio_intc_get_pin_irq_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)
void stm32_gpio_intc_enable_line(stm32_gpio_irq_line_t line)
{
	unsigned int irqnum;
	uint32_t line_num = ll_exti_line_to_linenum(line);
@@ -277,7 +277,7 @@ void stm32_exti_enable(stm32_exti_line_t line)
	irq_enable(irqnum);
}

void stm32_exti_disable(stm32_exti_line_t line)
void stm32_gpio_intc_disable_line(stm32_gpio_irq_line_t line)
{
#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
	LL_C2_EXTI_DisableIT_0_31(line);
@@ -286,24 +286,24 @@ void stm32_exti_disable(stm32_exti_line_t line)
#endif
}

void stm32_exti_trigger(stm32_exti_line_t line, uint32_t trigger)
void stm32_gpio_intc_select_line_trigger(stm32_gpio_irq_line_t line, uint32_t trigger)
{
	z_stm32_hsem_lock(CFG_HW_EXTI_SEMID, HSEM_LOCK_DEFAULT_RETRY);

	switch (trigger) {
	case STM32_EXTI_TRIG_NONE:
	case STM32_GPIO_IRQ_TRIG_NONE:
		LL_EXTI_DisableRisingTrig_0_31(line);
		LL_EXTI_DisableFallingTrig_0_31(line);
		break;
	case STM32_EXTI_TRIG_RISING:
	case STM32_GPIO_IRQ_TRIG_RISING:
		LL_EXTI_EnableRisingTrig_0_31(line);
		LL_EXTI_DisableFallingTrig_0_31(line);
		break;
	case STM32_EXTI_TRIG_FALLING:
	case STM32_GPIO_IRQ_TRIG_FALLING:
		LL_EXTI_EnableFallingTrig_0_31(line);
		LL_EXTI_DisableRisingTrig_0_31(line);
		break;
	case STM32_EXTI_TRIG_BOTH:
	case STM32_GPIO_IRQ_TRIG_BOTH:
		LL_EXTI_EnableRisingTrig_0_31(line);
		LL_EXTI_EnableFallingTrig_0_31(line);
		break;
@@ -314,7 +314,7 @@ void stm32_exti_trigger(stm32_exti_line_t line, uint32_t trigger)
	z_stm32_hsem_unlock(CFG_HW_EXTI_SEMID);
}

int stm32_exti_set_callback(stm32_exti_line_t line, stm32_exti_callback_t cb, void *arg)
int stm32_gpio_intc_set_irq_callback(stm32_gpio_irq_line_t line, stm32_gpio_irq_cb_t cb, void *arg)
{
	const struct device *const dev = DEVICE_DT_GET(EXTI_NODE);
	struct stm32_exti_data *data = dev->data;
@@ -335,7 +335,7 @@ int stm32_exti_set_callback(stm32_exti_line_t line, stm32_exti_callback_t cb, vo
	return 0;
}

void stm32_exti_unset_callback(stm32_exti_line_t line)
void stm32_gpio_intc_remove_irq_callback(stm32_gpio_irq_line_t line)
{
	const struct device *const dev = DEVICE_DT_GET(EXTI_NODE);
	struct stm32_exti_data *data = dev->data;
+40 −41
Changes for include/zephyr/drivers/interrupt_controller/gpio_intc_stm32.h: 40 added lines, 41 removed lines.
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016 Open-RnD Sp. z o.o.
 * Copyright (c) 2024 STMicroelectronics
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief Driver for External interrupt/event controller in STM32 MCUs
 *
 * Based on reference manuals:
 *   RM0008 Reference Manual: STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx
 *   and STM32F107xx advanced ARM(r)-based 32-bit MCUs
 * and
 *   RM0368 Reference manual STM32F401xB/C and STM32F401xD/E
 *   advanced ARM(r)-based 32-bit MCUs
 *
 * Chapter 10.2: External interrupt/event controller (EXTI)
 * @brief GPIO interrupt controller API for STM32 MCUs
 *
 * This API is used to interact with the GPIO interrupt controller
 * of STM32 microcontrollers.
 */

#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_EXTI_STM32_H_
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_EXTI_STM32_H_
#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_GPIO_INTC_STM32_H_
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_GPIO_INTC_STM32_H_

#include <zephyr/types.h>
#include <zephyr/drivers/gpio.h>

/**
 * @brief Opaque type representing an EXTI line
 * @brief Opaque type representing a GPIO interrupt line
 */
typedef uint32_t stm32_exti_line_t;
typedef uint32_t stm32_gpio_irq_line_t;

/**
 * @brief Get the EXTI interrupt line value corresponding
 * @brief Get the GPIO 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);
stm32_gpio_irq_line_t stm32_gpio_intc_get_pin_irq_line(uint32_t port, gpio_pin_t pin);

/**
 * @brief Enable EXTI interrupts for specified line
 * @brief Enable GPIO interrupts for specified line
 *
 * @param line	EXTI interrupt line
 * @param line	GPIO interrupt line
 */
void stm32_exti_enable(stm32_exti_line_t line);
void stm32_gpio_intc_enable_line(stm32_gpio_irq_line_t line);

/**
 * @brief Disable EXTI interrupts for specified line
 * @brief Disable GPIO interrupts for specified line
 *
 * @param line	EXTI interrupt line
 * @param line	GPIO interrupt line
 */
void stm32_exti_disable(stm32_exti_line_t line);
void stm32_gpio_intc_disable_line(stm32_gpio_irq_line_t line);

/**
 * @brief EXTI interrupt trigger flags
 * @brief GPIO interrupt trigger flags
 */
enum stm32_exti_trigger {
enum stm32_gpio_irq_trigger {
	/* No trigger */
	STM32_EXTI_TRIG_NONE  = 0x0,
	STM32_GPIO_IRQ_TRIG_NONE  = 0x0,
	/* Trigger on rising edge */
	STM32_EXTI_TRIG_RISING  = 0x1,
	STM32_GPIO_IRQ_TRIG_RISING  = 0x1,
	/* Trigger on falling edge */
	STM32_EXTI_TRIG_FALLING = 0x2,
	STM32_GPIO_IRQ_TRIG_FALLING = 0x2,
	/* Trigger on both rising and falling edge */
	STM32_EXTI_TRIG_BOTH = 0x3,
	STM32_GPIO_IRQ_TRIG_BOTH = 0x3,
};

/**
 * @brief Select trigger for interrupt on specified EXTI line
 * @brief Select trigger for interrupt on specified GPIO line
 *
 * @param line	EXTI interrupt line
 * @param trg	Interrupt trigger (see @ref stm32_exti_trigger)
 * @param line	GPIO interrupt line
 * @param trg	Interrupt trigger (see @ref stm32_gpio_irq_trigger)
 */
void stm32_exti_trigger(stm32_exti_line_t line, uint32_t trg);
void stm32_gpio_intc_select_line_trigger(stm32_gpio_irq_line_t line, uint32_t trg);

/**
 * @brief EXTI interrupt callback function signature
 * @brief GPIO interrupt callback function signature
 *
 * @param pin	GPIO pin on which interrupt occurred
 * @param user	@p data provided to @ref stm32_exti_set_callback
 * @param user	@p data provided to @ref stm32_gpio_intc_set_irq_callback
 *
 * @note This callback is invoked in ISR context.
 */
typedef void (*stm32_exti_callback_t)(gpio_port_pins_t pin, void *user);
typedef void (*stm32_gpio_irq_cb_t)(gpio_port_pins_t pin, void *user);

/**
 * @brief Set callback invoked when an interrupt occurs on specified EXTI line
 * @brief Set callback invoked when an interrupt occurs on specified GPIO line
 *
 * @param line	EXTI interrupt line
 * @param line	GPIO interrupt line
 * @param cb	Interrupt callback function
 * @param data	Custom data for usage by the callback
 * @returns 0 on success, -EBUSY if a callback is already set for @p line
 */
int stm32_exti_set_callback(stm32_exti_line_t line, stm32_exti_callback_t cb, void *data);
int stm32_gpio_intc_set_irq_callback(stm32_gpio_irq_line_t line,
					stm32_gpio_irq_cb_t cb, void *data);

/**
 * @brief Removes the interrupt callback of specified EXTI line
 *
 * @param line	EXTI interrupt line
 */
void stm32_exti_unset_callback(stm32_exti_line_t line);
void stm32_gpio_intc_remove_irq_callback(stm32_gpio_irq_line_t line);

/** Hardware-specific API extensions */

#if defined(CONFIG_EXTI_STM32)	/* EXTI-specific extensions */
/**
 * @brief Set which GPIO port triggers events on specified EXTI line.
 *
@@ -112,6 +110,7 @@ void stm32_exti_set_line_src_port(gpio_pin_t line, uint32_t port);
 * @param line	EXTI line number (= pin number)
 * @returns GPIO port number (STM32_PORTA, STM32_PORTB, ...)
 */
uint32_t stm32_exti_get_line_src_port(gpio_pin_t line);
uint32_t stm32_exti_get_line_src_port(gpio_pin_t pin);
#endif /* CONFIG_EXTI_STM32 */

#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_EXTI_STM32_H_ */
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_GPIO_INTC_STM32_H_ */