drivers: gpio: stm32: move EXTI line port configuration to proper driver
Move the functions that interact with EXTI configuration registers to select or get the GPIO port that triggers events on a given EXTI line to the EXTI driver. Signed-off-by: Mathieu Choplain <mathieu.choplain@st.com>
This commit is contained in:
parent
d34f5f27bf
commit
0551825ca3
3 changed files with 100 additions and 90 deletions
|
|
@ -15,7 +15,6 @@
|
|||
#include <stm32_ll_exti.h>
|
||||
#include <stm32_ll_gpio.h>
|
||||
#include <stm32_ll_pwr.h>
|
||||
#include <stm32_ll_system.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
|
|
@ -294,93 +293,6 @@ static int gpio_stm32_clock_request(const struct device *dev, bool on)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline uint32_t gpio_stm32_pin_to_exti_src_cfg_line(gpio_pin_t pin)
|
||||
{
|
||||
#if defined(CONFIG_SOC_SERIES_STM32L0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32F0X)
|
||||
return ((pin % 4 * 4) << 16) | (pin / 4);
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
|
||||
return ((pin & 0x3) << (16 + 3)) | (pin >> 2);
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7rs_exti)
|
||||
/* Gives the LL_SBS_EXTI_LINEn corresponding to the pin */
|
||||
return (((pin % 4 * 4) << LL_SBS_REGISTER_PINPOS_SHFT) | (pin / 4));
|
||||
#else
|
||||
return (0xF << ((pin % 4 * 4) + 16)) | (pin / 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set which GPIO port triggers events on specified EXTI line.
|
||||
*
|
||||
* @param line EXTI line number (= pin number)
|
||||
* @param port GPIO port number (STM32_PORTA, STM32_PORTB, ...)
|
||||
*/
|
||||
static void gpio_stm32_set_exti_line_src_port(gpio_pin_t line, uint32_t port)
|
||||
{
|
||||
uint32_t ll_line = gpio_stm32_pin_to_exti_src_cfg_line(line);
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_STM32L0X) && defined(LL_SYSCFG_EXTI_PORTH)
|
||||
/*
|
||||
* Ports F and G are not present on some STM32L0 parts, so
|
||||
* for these parts port H external interrupt should be enabled
|
||||
* by writing value 0x5 instead of 0x7.
|
||||
*/
|
||||
if (port == STM32_PORTH) {
|
||||
port = LL_SYSCFG_EXTI_PORTH;
|
||||
}
|
||||
#endif
|
||||
|
||||
z_stm32_hsem_lock(CFG_HW_EXTI_SEMID, HSEM_LOCK_DEFAULT_RETRY);
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_STM32F1X
|
||||
LL_GPIO_AF_SetEXTISource(port, ll_line);
|
||||
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
|
||||
LL_EXTI_SetEXTISource(port, ll_line);
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7rs_exti)
|
||||
LL_SBS_SetEXTISource(port, ll_line);
|
||||
#else
|
||||
LL_SYSCFG_SetEXTISource(port, ll_line);
|
||||
#endif
|
||||
z_stm32_hsem_unlock(CFG_HW_EXTI_SEMID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get port which is triggering events on specified EXTI line.
|
||||
*
|
||||
* @param line EXTI line number (= pin number)
|
||||
* @returns GPIO port number (STM32_PORTA, STM32_PORTB, ...)
|
||||
*/
|
||||
static uint32_t gpio_stm32_get_exti_line_src_port(gpio_pin_t line)
|
||||
{
|
||||
uint32_t ll_line = gpio_stm32_pin_to_exti_src_cfg_line(line);
|
||||
uint32_t port;
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_STM32F1X
|
||||
port = LL_GPIO_AF_GetEXTISource(ll_line);
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
|
||||
port = LL_EXTI_GetEXTISource(ll_line);
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7rs_exti)
|
||||
port = LL_SBS_GetEXTISource(ll_line);
|
||||
#else
|
||||
port = LL_SYSCFG_GetEXTISource(ll_line);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_STM32L0X) && defined(LL_SYSCFG_EXTI_PORTH)
|
||||
/*
|
||||
* Ports F and G are not present on some STM32L0 parts, so
|
||||
* for these parts port H external interrupt is enabled
|
||||
* by writing value 0x5 instead of 0x7.
|
||||
*/
|
||||
if (port == LL_SYSCFG_EXTI_PORTH) {
|
||||
port = STM32_PORTH;
|
||||
}
|
||||
#endif
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
static int gpio_stm32_port_get_raw(const struct device *dev, uint32_t *value)
|
||||
{
|
||||
const struct gpio_stm32_config *cfg = dev->config;
|
||||
|
|
@ -607,7 +519,7 @@ static int gpio_stm32_pin_interrupt_configure(const struct device *dev,
|
|||
#endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */
|
||||
|
||||
if (mode == GPIO_INT_MODE_DISABLED) {
|
||||
if (gpio_stm32_get_exti_line_src_port(pin) == cfg->port) {
|
||||
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);
|
||||
|
|
@ -642,7 +554,7 @@ static int gpio_stm32_pin_interrupt_configure(const struct device *dev,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
gpio_stm32_set_exti_line_src_port(pin, cfg->port);
|
||||
stm32_exti_set_line_src_port(pin, cfg->port);
|
||||
|
||||
stm32_exti_trigger(pin, edge);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,9 +15,12 @@
|
|||
#include <zephyr/device.h>
|
||||
#include <soc.h>
|
||||
#include <stm32_ll_bus.h>
|
||||
#include <stm32_ll_gpio.h> /* For STM32F1 series */
|
||||
#include <stm32_ll_exti.h>
|
||||
#include <stm32_ll_system.h>
|
||||
#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/clock_control/stm32_clock_control.h>
|
||||
#include <zephyr/irq.h>
|
||||
|
|
@ -48,6 +51,25 @@ struct stm32_exti_data {
|
|||
struct __exti_cb cb[NUM_EXTI_LINES];
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns the LL_<PPP>_EXTI_LINE_xxx define that corresponds to specified @p linenum
|
||||
* This value can be used with the LL EXTI source configuration functions.
|
||||
*/
|
||||
static inline uint32_t stm32_exti_linenum_to_src_cfg_line(gpio_pin_t linenum)
|
||||
{
|
||||
#if defined(CONFIG_SOC_SERIES_STM32L0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32F0X)
|
||||
return ((linenum % 4 * 4) << 16) | (linenum / 4);
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
|
||||
return ((linenum & 0x3) << (16 + 3)) | (linenum >> 2);
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7rs_exti)
|
||||
/* Gives the LL_SBS_EXTI_LINEn corresponding to the line number */
|
||||
return (((linenum % 4 * 4) << LL_SBS_REGISTER_PINPOS_SHFT) | (linenum / 4));
|
||||
#else
|
||||
return (0xF << ((linenum % 4 * 4) + 16)) | (linenum / 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks interrupt pending bit for specified EXTI line
|
||||
*
|
||||
|
|
@ -297,3 +319,62 @@ void stm32_exti_unset_callback(stm32_exti_line_t line)
|
|||
data->cb[line].cb = NULL;
|
||||
data->cb[line].data = NULL;
|
||||
}
|
||||
|
||||
void stm32_exti_set_line_src_port(gpio_pin_t line, uint32_t port)
|
||||
{
|
||||
uint32_t ll_line = stm32_exti_linenum_to_src_cfg_line(line);
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_STM32L0X) && defined(LL_SYSCFG_EXTI_PORTH)
|
||||
/*
|
||||
* Ports F and G are not present on some STM32L0 parts, so
|
||||
* for these parts port H external interrupt should be enabled
|
||||
* by writing value 0x5 instead of 0x7.
|
||||
*/
|
||||
if (port == STM32_PORTH) {
|
||||
port = LL_SYSCFG_EXTI_PORTH;
|
||||
}
|
||||
#endif
|
||||
|
||||
z_stm32_hsem_lock(CFG_HW_EXTI_SEMID, HSEM_LOCK_DEFAULT_RETRY);
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_STM32F1X
|
||||
LL_GPIO_AF_SetEXTISource(port, ll_line);
|
||||
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
|
||||
LL_EXTI_SetEXTISource(port, ll_line);
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7rs_exti)
|
||||
LL_SBS_SetEXTISource(port, ll_line);
|
||||
#else
|
||||
LL_SYSCFG_SetEXTISource(port, ll_line);
|
||||
#endif
|
||||
z_stm32_hsem_unlock(CFG_HW_EXTI_SEMID);
|
||||
}
|
||||
|
||||
uint32_t stm32_exti_get_line_src_port(gpio_pin_t line)
|
||||
{
|
||||
uint32_t ll_line = stm32_exti_linenum_to_src_cfg_line(line);
|
||||
uint32_t port;
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_STM32F1X
|
||||
port = LL_GPIO_AF_GetEXTISource(ll_line);
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
|
||||
port = LL_EXTI_GetEXTISource(ll_line);
|
||||
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7rs_exti)
|
||||
port = LL_SBS_GetEXTISource(ll_line);
|
||||
#else
|
||||
port = LL_SYSCFG_GetEXTISource(ll_line);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_STM32L0X) && defined(LL_SYSCFG_EXTI_PORTH)
|
||||
/*
|
||||
* Ports F and G are not present on some STM32L0 parts, so
|
||||
* for these parts port H external interrupt is enabled
|
||||
* by writing value 0x5 instead of 0x7.
|
||||
*/
|
||||
if (port == LL_SYSCFG_EXTI_PORTH) {
|
||||
port = STM32_PORTH;
|
||||
}
|
||||
#endif
|
||||
|
||||
return port;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_EXTI_STM32_H_
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
|
||||
/**
|
||||
* @brief Type representing an EXTI line number
|
||||
|
|
@ -91,4 +92,20 @@ int stm32_exti_set_callback(stm32_exti_line_t line, stm32_exti_callback_t cb, vo
|
|||
*/
|
||||
void stm32_exti_unset_callback(stm32_exti_line_t line);
|
||||
|
||||
/**
|
||||
* @brief Set which GPIO port triggers events on specified EXTI line.
|
||||
*
|
||||
* @param line EXTI line number (= pin number)
|
||||
* @param port GPIO port number (STM32_PORTA, STM32_PORTB, ...)
|
||||
*/
|
||||
void stm32_exti_set_line_src_port(gpio_pin_t line, uint32_t port);
|
||||
|
||||
/**
|
||||
* @brief Get port which is triggering events on specified EXTI line.
|
||||
*
|
||||
* @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);
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_EXTI_STM32_H_ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue