Skip to content

Commit 5453e09

Browse files
drivers: intc_gpio_stm32: exti integration
integrate intc_exti_stm32 to intc_gpio_stm32 Co-authored-by: Mathieu CHOPLAIN <[email protected]> Signed-off-by: Alexander Kozhinov <[email protected]>
1 parent 7ea51c9 commit 5453e09

File tree

1 file changed

+29
-117
lines changed

1 file changed

+29
-117
lines changed

drivers/interrupt_controller/intc_gpio_stm32.c

+29-117
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Copyright (c) 2016 Open-RnD Sp. z o.o.
33
* Copyright (c) 2017 RnDity Sp. z o.o.
44
* Copyright (c) 2019-23 Linaro Limited
5+
* Copyright (c) 2025 Alexander Kozhinov <[email protected]>
56
*
67
* SPDX-License-Identifier: Apache-2.0
78
*/
@@ -22,10 +23,12 @@
2223
#include <zephyr/sys/util.h>
2324
#include <zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h> /* For STM32L0 series */
2425
#include <zephyr/drivers/interrupt_controller/gpio_intc_stm32.h>
26+
#include <zephyr/drivers/interrupt_controller/intc_exti_stm32.h>
2527
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
2628
#include <zephyr/irq.h>
2729

2830
#include "stm32_hsem.h"
31+
#include "intc_exti_stm32_priv.h"
2932

3033
/** @brief EXTI lines range mapped to a single interrupt line */
3134
struct stm32_exti_range {
@@ -35,7 +38,7 @@ struct stm32_exti_range {
3538
uint8_t len;
3639
};
3740

38-
#define NUM_EXTI_LINES DT_PROP(DT_NODELABEL(exti), num_lines)
41+
#define NUM_EXTI_LINES DT_PROP(DT_NODELABEL(exti), num_gpio_lines)
3942

4043
static IRQn_Type exti_irq_table[NUM_EXTI_LINES] = {[0 ... NUM_EXTI_LINES - 1] = 0xFF};
4144

@@ -46,11 +49,13 @@ struct __exti_cb {
4649
};
4750

4851
/* EXTI driver data */
49-
struct stm32_exti_data {
52+
struct stm32_intc_gpio_data {
5053
/* per-line callbacks */
5154
struct __exti_cb cb[NUM_EXTI_LINES];
5255
};
5356

57+
static struct stm32_intc_gpio_data intc_gpio_data;
58+
5459
/**
5560
* @returns the LL_<PPP>_EXTI_LINE_xxx define that corresponds to specified @p linenum
5661
* This value can be used with the LL EXTI source configuration functions.
@@ -70,48 +75,6 @@ static inline uint32_t stm32_exti_linenum_to_src_cfg_line(gpio_pin_t linenum)
7075
#endif
7176
}
7277

73-
/**
74-
* @brief Checks interrupt pending bit for specified EXTI line
75-
*
76-
* @param line EXTI line number
77-
*/
78-
static inline int stm32_exti_is_pending(stm32_gpio_irq_line_t line)
79-
{
80-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
81-
return (LL_EXTI_IsActiveRisingFlag_0_31(line) ||
82-
LL_EXTI_IsActiveFallingFlag_0_31(line));
83-
#elif defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
84-
return LL_C2_EXTI_IsActiveFlag_0_31(line);
85-
#else
86-
return LL_EXTI_IsActiveFlag_0_31(line);
87-
#endif
88-
}
89-
90-
/**
91-
* @brief Clears interrupt pending bit for specified EXTI line
92-
*
93-
* @param line EXTI line number
94-
*/
95-
static inline void stm32_exti_clear_pending(stm32_gpio_irq_line_t line)
96-
{
97-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti)
98-
LL_EXTI_ClearRisingFlag_0_31(line);
99-
LL_EXTI_ClearFallingFlag_0_31(line);
100-
#elif defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
101-
LL_C2_EXTI_ClearFlag_0_31(line);
102-
#else
103-
LL_EXTI_ClearFlag_0_31(line);
104-
#endif
105-
}
106-
107-
/**
108-
* @returns the LL_EXTI_LINE_n define for EXTI line number @p linenum
109-
*/
110-
static inline stm32_gpio_irq_line_t linenum_to_ll_exti_line(gpio_pin_t linenum)
111-
{
112-
return BIT(linenum);
113-
}
114-
11578
/**
11679
* @returns EXTI line number for LL_EXTI_LINE_n define
11780
*/
@@ -127,68 +90,34 @@ static inline gpio_pin_t ll_exti_line_to_linenum(stm32_gpio_irq_line_t line)
12790
*
12891
* @param exti_range Pointer to a exti_range structure
12992
*/
130-
static void stm32_exti_isr(const void *exti_range)
93+
static void stm32_intc_gpio_isr(const void *exti_range)
13194
{
132-
const struct device *dev = DEVICE_DT_GET(EXTI_NODE);
133-
struct stm32_exti_data *data = dev->data;
95+
struct stm32_intc_gpio_data *data = &intc_gpio_data;
13496
const struct stm32_exti_range *range = exti_range;
13597
stm32_gpio_irq_line_t line;
13698
uint32_t line_num;
13799

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

143104
/* check if interrupt is pending */
144-
if (stm32_exti_is_pending(line) != 0) {
105+
if (stm32_exti_is_pending(line_num) != 0) {
145106
/* clear pending interrupt */
146-
stm32_exti_clear_pending(line);
107+
stm32_exti_clear_pending(line_num);
147108

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

153114
/* `line` can be passed as-is because LL_EXTI_LINE_n is (1 << n) */
115+
line = exti_linenum_to_ll_exti_line(line_num);
154116
data->cb[line_num].cb(line, data->cb[line_num].data);
155117
}
156118
}
157119
}
158120

159-
/** Enables the peripheral clock required to access EXTI registers */
160-
static int stm32_exti_enable_registers(void)
161-
{
162-
/* Initialize to 0 for series where there is nothing to do. */
163-
int ret = 0;
164-
#if defined(CONFIG_SOC_SERIES_STM32F2X) || \
165-
defined(CONFIG_SOC_SERIES_STM32F3X) || \
166-
defined(CONFIG_SOC_SERIES_STM32F4X) || \
167-
defined(CONFIG_SOC_SERIES_STM32F7X) || \
168-
defined(CONFIG_SOC_SERIES_STM32H7X) || \
169-
defined(CONFIG_SOC_SERIES_STM32H7RSX) || \
170-
defined(CONFIG_SOC_SERIES_STM32L1X) || \
171-
defined(CONFIG_SOC_SERIES_STM32L4X) || \
172-
defined(CONFIG_SOC_SERIES_STM32G4X)
173-
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
174-
struct stm32_pclken pclken = {
175-
#if defined(CONFIG_SOC_SERIES_STM32H7X)
176-
.bus = STM32_CLOCK_BUS_APB4,
177-
.enr = LL_APB4_GRP1_PERIPH_SYSCFG
178-
#elif defined(CONFIG_SOC_SERIES_STM32H7RSX)
179-
.bus = STM32_CLOCK_BUS_APB4,
180-
.enr = LL_APB4_GRP1_PERIPH_SBS
181-
#else
182-
.bus = STM32_CLOCK_BUS_APB2,
183-
.enr = LL_APB2_GRP1_PERIPH_SYSCFG
184-
#endif /* CONFIG_SOC_SERIES_STM32H7X */
185-
};
186-
187-
ret = clock_control_on(clk, (clock_control_subsys_t) &pclken);
188-
#endif
189-
return ret;
190-
}
191-
192121
static void stm32_fill_irq_table(int8_t start, int8_t len, int32_t irqn)
193122
{
194123
for (int i = 0; i < len; i++) {
@@ -211,28 +140,21 @@ static void stm32_fill_irq_table(int8_t start, int8_t len, int32_t irqn)
211140
DT_IRQ_BY_IDX(node_id, idx, irq)); \
212141
IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), \
213142
DT_IRQ_BY_IDX(node_id, idx, priority), \
214-
stm32_exti_isr, &line_range_##idx, 0);
143+
stm32_intc_gpio_isr, &line_range_##idx, 0);
215144

216145
/**
217146
* @brief Initializes the EXTI GPIO interrupt controller driver
218147
*/
219-
static int stm32_exti_init(const struct device *dev)
148+
static int stm32_exti_gpio_intc_init(void)
220149
{
221-
ARG_UNUSED(dev);
222-
223150
DT_FOREACH_PROP_ELEM(DT_NODELABEL(exti),
224151
interrupt_names,
225152
STM32_EXTI_INIT_LINE_RANGE);
226153

227-
return stm32_exti_enable_registers();
154+
return 0;
228155
}
229156

230-
static struct stm32_exti_data exti_data;
231-
DEVICE_DT_DEFINE(EXTI_NODE, &stm32_exti_init,
232-
NULL,
233-
&exti_data, NULL,
234-
PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY,
235-
NULL);
157+
SYS_INIT(stm32_exti_gpio_intc_init, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY);
236158

237159
/**
238160
* @brief EXTI GPIO interrupt controller API implementation
@@ -252,7 +174,7 @@ DEVICE_DT_DEFINE(EXTI_NODE, &stm32_exti_init,
252174
stm32_gpio_irq_line_t stm32_gpio_intc_get_pin_irq_line(uint32_t port, gpio_pin_t pin)
253175
{
254176
ARG_UNUSED(port);
255-
return linenum_to_ll_exti_line(pin);
177+
return exti_linenum_to_ll_exti_line(pin);
256178
}
257179

258180
void stm32_gpio_intc_enable_line(stm32_gpio_irq_line_t line)
@@ -267,23 +189,15 @@ void stm32_gpio_intc_enable_line(stm32_gpio_irq_line_t line)
267189
__ASSERT_NO_MSG(irqnum != 0xFF);
268190

269191
/* Enable requested line interrupt */
270-
#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
271-
LL_C2_EXTI_EnableIT_0_31(line);
272-
#else
273-
LL_EXTI_EnableIT_0_31(line);
274-
#endif
192+
EXTI_ENABLE_IT(0_31, line);
275193

276194
/* Enable exti irq interrupt */
277195
irq_enable(irqnum);
278196
}
279197

280198
void stm32_gpio_intc_disable_line(stm32_gpio_irq_line_t line)
281199
{
282-
#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
283-
LL_C2_EXTI_DisableIT_0_31(line);
284-
#else
285-
LL_EXTI_DisableIT_0_31(line);
286-
#endif
200+
EXTI_DISABLE_IT(0_31, line);
287201
}
288202

289203
void stm32_gpio_intc_select_line_trigger(stm32_gpio_irq_line_t line, uint32_t trg)
@@ -292,20 +206,20 @@ void stm32_gpio_intc_select_line_trigger(stm32_gpio_irq_line_t line, uint32_t tr
292206

293207
switch (trg) {
294208
case STM32_GPIO_IRQ_TRIG_NONE:
295-
LL_EXTI_DisableRisingTrig_0_31(line);
296-
LL_EXTI_DisableFallingTrig_0_31(line);
209+
EXTI_DISABLE_RISING_TRIG(0_31, line);
210+
EXTI_DISABLE_FALLING_TRIG(0_31, line);
297211
break;
298212
case STM32_GPIO_IRQ_TRIG_RISING:
299-
LL_EXTI_EnableRisingTrig_0_31(line);
300-
LL_EXTI_DisableFallingTrig_0_31(line);
213+
EXTI_ENABLE_RISING_TRIG(0_31, line);
214+
EXTI_DISABLE_FALLING_TRIG(0_31, line);
301215
break;
302216
case STM32_GPIO_IRQ_TRIG_FALLING:
303-
LL_EXTI_EnableFallingTrig_0_31(line);
304-
LL_EXTI_DisableRisingTrig_0_31(line);
217+
EXTI_ENABLE_FALLING_TRIG(0_31, line);
218+
EXTI_DISABLE_RISING_TRIG(0_31, line);
305219
break;
306220
case STM32_GPIO_IRQ_TRIG_BOTH:
307-
LL_EXTI_EnableRisingTrig_0_31(line);
308-
LL_EXTI_EnableFallingTrig_0_31(line);
221+
EXTI_ENABLE_RISING_TRIG(0_31, line);
222+
EXTI_ENABLE_FALLING_TRIG(0_31, line);
309223
break;
310224
default:
311225
__ASSERT_NO_MSG(0);
@@ -316,8 +230,7 @@ void stm32_gpio_intc_select_line_trigger(stm32_gpio_irq_line_t line, uint32_t tr
316230

317231
int stm32_gpio_intc_set_irq_callback(stm32_gpio_irq_line_t line, stm32_gpio_irq_cb_t cb, void *user)
318232
{
319-
const struct device *const dev = DEVICE_DT_GET(EXTI_NODE);
320-
struct stm32_exti_data *data = dev->data;
233+
struct stm32_intc_gpio_data *data = &intc_gpio_data;
321234
uint32_t line_num = ll_exti_line_to_linenum(line);
322235

323236
if ((data->cb[line_num].cb == cb) && (data->cb[line_num].data == user)) {
@@ -337,8 +250,7 @@ int stm32_gpio_intc_set_irq_callback(stm32_gpio_irq_line_t line, stm32_gpio_irq_
337250

338251
void stm32_gpio_intc_remove_irq_callback(stm32_gpio_irq_line_t line)
339252
{
340-
const struct device *const dev = DEVICE_DT_GET(EXTI_NODE);
341-
struct stm32_exti_data *data = dev->data;
253+
struct stm32_intc_gpio_data *data = &intc_gpio_data;
342254
uint32_t line_num = ll_exti_line_to_linenum(line);
343255

344256
data->cb[line_num].cb = NULL;

0 commit comments

Comments
 (0)