2
2
* Copyright (c) 2016 Open-RnD Sp. z o.o.
3
3
* Copyright (c) 2017 RnDity Sp. z o.o.
4
4
* Copyright (c) 2019-23 Linaro Limited
5
+ * Copyright (c) 2025 Alexander Kozhinov <[email protected] >
5
6
*
6
7
* SPDX-License-Identifier: Apache-2.0
7
8
*/
22
23
#include <zephyr/sys/util.h>
23
24
#include <zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h> /* For STM32L0 series */
24
25
#include <zephyr/drivers/interrupt_controller/gpio_intc_stm32.h>
26
+ #include <zephyr/drivers/interrupt_controller/intc_exti_stm32.h>
25
27
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
26
28
#include <zephyr/irq.h>
27
29
28
30
#include "stm32_hsem.h"
31
+ #include "intc_exti_stm32_priv.h"
29
32
30
33
/** @brief EXTI lines range mapped to a single interrupt line */
31
34
struct stm32_exti_range {
@@ -35,7 +38,7 @@ struct stm32_exti_range {
35
38
uint8_t len ;
36
39
};
37
40
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 )
39
42
40
43
static IRQn_Type exti_irq_table [NUM_EXTI_LINES ] = {[0 ... NUM_EXTI_LINES - 1 ] = 0xFF };
41
44
@@ -46,11 +49,13 @@ struct __exti_cb {
46
49
};
47
50
48
51
/* EXTI driver data */
49
- struct stm32_exti_data {
52
+ struct stm32_intc_gpio_data {
50
53
/* per-line callbacks */
51
54
struct __exti_cb cb [NUM_EXTI_LINES ];
52
55
};
53
56
57
+ static struct stm32_intc_gpio_data intc_gpio_data ;
58
+
54
59
/**
55
60
* @returns the LL_<PPP>_EXTI_LINE_xxx define that corresponds to specified @p linenum
56
61
* 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)
70
75
#endif
71
76
}
72
77
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
-
115
78
/**
116
79
* @returns EXTI line number for LL_EXTI_LINE_n define
117
80
*/
@@ -127,68 +90,34 @@ static inline gpio_pin_t ll_exti_line_to_linenum(stm32_gpio_irq_line_t line)
127
90
*
128
91
* @param exti_range Pointer to a exti_range structure
129
92
*/
130
- static void stm32_exti_isr (const void * exti_range )
93
+ static void stm32_intc_gpio_isr (const void * exti_range )
131
94
{
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 ;
134
96
const struct stm32_exti_range * range = exti_range ;
135
97
stm32_gpio_irq_line_t line ;
136
98
uint32_t line_num ;
137
99
138
100
/* see which bits are set */
139
101
for (uint8_t i = 0 ; i <= range -> len ; i ++ ) {
140
102
line_num = range -> start + i ;
141
- line = linenum_to_ll_exti_line (line_num );
142
103
143
104
/* check if interrupt is pending */
144
- if (stm32_exti_is_pending (line ) != 0 ) {
105
+ if (stm32_exti_is_pending (line_num ) != 0 ) {
145
106
/* clear pending interrupt */
146
- stm32_exti_clear_pending (line );
107
+ stm32_exti_clear_pending (line_num );
147
108
148
109
/* run callback only if one is registered */
149
110
if (!data -> cb [line_num ].cb ) {
150
111
continue ;
151
112
}
152
113
153
114
/* `line` can be passed as-is because LL_EXTI_LINE_n is (1 << n) */
115
+ line = exti_linenum_to_ll_exti_line (line_num );
154
116
data -> cb [line_num ].cb (line , data -> cb [line_num ].data );
155
117
}
156
118
}
157
119
}
158
120
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
-
192
121
static void stm32_fill_irq_table (int8_t start , int8_t len , int32_t irqn )
193
122
{
194
123
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)
211
140
DT_IRQ_BY_IDX(node_id, idx, irq)); \
212
141
IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), \
213
142
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);
215
144
216
145
/**
217
146
* @brief Initializes the EXTI GPIO interrupt controller driver
218
147
*/
219
- static int stm32_exti_init ( const struct device * dev )
148
+ static int stm32_exti_gpio_intc_init ( void )
220
149
{
221
- ARG_UNUSED (dev );
222
-
223
150
DT_FOREACH_PROP_ELEM (DT_NODELABEL (exti ),
224
151
interrupt_names ,
225
152
STM32_EXTI_INIT_LINE_RANGE );
226
153
227
- return stm32_exti_enable_registers () ;
154
+ return 0 ;
228
155
}
229
156
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 );
236
158
237
159
/**
238
160
* @brief EXTI GPIO interrupt controller API implementation
@@ -252,7 +174,7 @@ DEVICE_DT_DEFINE(EXTI_NODE, &stm32_exti_init,
252
174
stm32_gpio_irq_line_t stm32_gpio_intc_get_pin_irq_line (uint32_t port , gpio_pin_t pin )
253
175
{
254
176
ARG_UNUSED (port );
255
- return linenum_to_ll_exti_line (pin );
177
+ return exti_linenum_to_ll_exti_line (pin );
256
178
}
257
179
258
180
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)
267
189
__ASSERT_NO_MSG (irqnum != 0xFF );
268
190
269
191
/* 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 );
275
193
276
194
/* Enable exti irq interrupt */
277
195
irq_enable (irqnum );
278
196
}
279
197
280
198
void stm32_gpio_intc_disable_line (stm32_gpio_irq_line_t line )
281
199
{
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 );
287
201
}
288
202
289
203
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
292
206
293
207
switch (trg ) {
294
208
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 );
297
211
break ;
298
212
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 );
301
215
break ;
302
216
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 );
305
219
break ;
306
220
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 );
309
223
break ;
310
224
default :
311
225
__ASSERT_NO_MSG (0 );
@@ -316,8 +230,7 @@ void stm32_gpio_intc_select_line_trigger(stm32_gpio_irq_line_t line, uint32_t tr
316
230
317
231
int stm32_gpio_intc_set_irq_callback (stm32_gpio_irq_line_t line , stm32_gpio_irq_cb_t cb , void * user )
318
232
{
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 ;
321
234
uint32_t line_num = ll_exti_line_to_linenum (line );
322
235
323
236
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_
337
250
338
251
void stm32_gpio_intc_remove_irq_callback (stm32_gpio_irq_line_t line )
339
252
{
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 ;
342
254
uint32_t line_num = ll_exti_line_to_linenum (line );
343
255
344
256
data -> cb [line_num ].cb = NULL ;
0 commit comments