1 /*
2 * Copyright (c) 2025 Alexander Kozhinov <ak.alexander.kozhinov@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_EXTI_STM32_PRIV_H_
8 #define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_EXTI_STM32_PRIV_H_
9
10 #include <zephyr/device.h>
11 #include <zephyr/sys/util.h>
12 #include <zephyr/sys/util_macro.h>
13 #include <zephyr/drivers/interrupt_controller/intc_exti_stm32.h>
14
15 #include <stm32_ll_bus.h>
16 #include <stm32_ll_exti.h>
17 #include <stm32_ll_system.h>
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 /**
24 * NOTE: This implementation currently does not support configurations where a
25 * single CPU has access to multiple EXTI instances. Supporting multiple EXTI
26 * instances per CPU (such as possible on STM32MP2 series with both M33 and M0+
27 * cores) will require changes to this macro and potentially other parts of the
28 * driver.
29 */
30 #define EXTI_NODE DT_INST(0, st_stm32_exti)
31
32 /**
33 * STM32MP1 has up to 96 EXTI lines (RM0475, Table 112. STM32MP13xx EXTI Events),
34 * but some ranges contain only direct lines, so the LL functions that are
35 * only valid for configurable lines are not provided for these ranges.
36 * However, we are relying on all these functions being present as part of our
37 * utility macros. Define dummy stubs for these functions to allow the main driver
38 * to work properly on this special series.
39 *
40 * NOTE: These stubs are only for compatibility and will assert if called for
41 * unsupported lines. Always ensure the correct line range is used.
42 */
43
44 #define STM32_EXTI_TOTAL_LINES_NUM DT_PROP(EXTI_NODE, num_lines)
45
46 /**
47 * @brief Define CPU number suffix for STM32 series.
48 */
49 #if (defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)) || \
50 (defined(CONFIG_SOC_SERIES_STM32MP2X) && defined(CONFIG_CPU_CORTEX_M33))
51 #define CPU_NR _C2
52 #elif defined(CONFIG_SOC_SERIES_STM32MP2X) && defined(CONFIG_CPU_CORTEX_M0)
53 #define CPU_NR _C3
54 #else
55 /* NOTE: usually one CPU (e.g. C1) only is omitted and leaved empty */
56 #define CPU_NR
57 #endif
58
59 /**
60 * @brief Define EXTI_LL_INST for STM32MP2X series, since it may have multiple instances
61 * For all other than STM32MP2X series the EXTI instance is defined within LL driver
62 * itself s.t. EXTI_LL_INST will be empty.
63 */
64 #if defined(CONFIG_SOC_SERIES_STM32MP2X)
65 #define EXTI_LL_INST ((EXTI_TypeDef *)DT_REG_ADDR(EXTI_NODE)),
66 #else /* CONFIG_SOC_SERIES_STM32MP2X */
67 #define EXTI_LL_INST
68 #endif /* CONFIG_SOC_SERIES_STM32MP2X */
69
70
71 #define EXTI_LINE_NOT_SUPP_ASSERT(line) \
72 { \
73 LOG_ERR("Unsupported line number %u", line); \
74 __ASSERT_NO_MSG(0); \
75 }
76
77 #define EXTI_LINE_NOP(line) \
78 { \
79 ARG_UNUSED(line); \
80 }
81
82 #if defined(CONFIG_SOC_SERIES_STM32MP1X) || defined(CONFIG_SOC_SERIES_STM32MP13X)
83
84 /*
85 * NOTE: There is currently no other option than to define LL_ prefixed functions
86 * that are missing in the original drivers as stubs for unsupported EXTI lines.
87 * This is required for compatibility across all STM32 series, until a more
88 * flexible solution is available.
89 */
90 #define LL_EXTI_IsActiveRisingFlag_32_63(line) 0
91 #define LL_EXTI_IsActiveFallingFlag_32_63(line) 0
92
93 #define LL_EXTI_ClearRisingFlag_32_63(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
94 #define LL_EXTI_ClearFallingFlag_32_63(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
95 #define LL_EXTI_GenerateSWI_32_63(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
96
97 #define LL_EXTI_EnableRisingTrig_32_63(line) EXTI_LINE_NOP(line)
98 #define LL_EXTI_EnableFallingTrig_32_63(line) EXTI_LINE_NOP(line)
99 #define LL_EXTI_DisableRisingTrig_32_63(line) EXTI_LINE_NOP(line)
100 #define LL_EXTI_DisableFallingTrig_32_63(line) EXTI_LINE_NOP(line)
101 #define LL_EXTI_EnableEvent_32_63(line) EXTI_LINE_NOP(line)
102 #define LL_EXTI_DisableEvent_32_63(line) EXTI_LINE_NOP(line)
103
104 #if defined(CONFIG_SOC_SERIES_STM32MP13X)
105
106 #define LL_EXTI_IsActiveRisingFlag_64_95(line) 0
107 #define LL_EXTI_IsActiveFallingFlag_64_95(line) 0
108
109 #define LL_EXTI_ClearRisingFlag_64_95(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
110 #define LL_EXTI_ClearFallingFlag_64_95(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
111 #define LL_EXTI_GenerateSWI_64_95(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
112 #define LL_EXTI_EnableRisingTrig_64_95(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
113 #define LL_EXTI_DisableRisingTrig_64_95(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
114 #define LL_EXTI_EnableFallingTrig_64_95(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
115 #define LL_EXTI_DisableFallingTrig_64_95(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
116 #define LL_EXTI_EnableEvent_64_95(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
117 #define LL_EXTI_DisableEvent_64_95(line) EXTI_LINE_NOT_SUPP_ASSERT(line)
118
119 #endif /* !CONFIG_SOC_SERIES_STM32MP13X */
120
121 #endif /* CONFIG_SOC_SERIES_STM32MP1X || CONFIG_SOC_SERIES_STM32MP13X */
122
123
124 /* Define general macros line-range independent */
125 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti) || defined(CONFIG_SOC_SERIES_STM32MP2X)
126
127 #if defined(CONFIG_SOC_SERIES_STM32MP2X)
128
129 #define EXTI_IS_ACTIVE_RISING_FLAG(line_range, line) \
130 CONCAT(LL, _EXTI_IsActiveRisingFlag_##line_range)(EXTI_LL_INST line)
131 #define EXTI_IS_ACTIVE_FALLING_FLAG(line_range, line) \
132 CONCAT(LL, _EXTI_IsActiveFallingFlag_##line_range)(EXTI_LL_INST line)
133
134 #define EXTI_CLEAR_RISING_FLAG(line_range, line) \
135 CONCAT(LL, _EXTI_ClearRisingFlag_##line_range)(EXTI_LL_INST line)
136 #define EXTI_CLEAR_FALLING_FLAG(line_range, line) \
137 CONCAT(LL, _EXTI_ClearFallingFlag_##line_range)(EXTI_LL_INST line)
138
139 #else /* !CONFIG_SOC_SERIES_STM32MP2X */
140
141 #define EXTI_IS_ACTIVE_RISING_FLAG(line_range, line) \
142 CONCAT(LL, CPU_NR, _EXTI_IsActiveRisingFlag_##line_range)(EXTI_LL_INST line)
143 #define EXTI_IS_ACTIVE_FALLING_FLAG(line_range, line) \
144 CONCAT(LL, CPU_NR, _EXTI_IsActiveFallingFlag_##line_range)(EXTI_LL_INST line)
145
146 #define EXTI_CLEAR_RISING_FLAG(line_range, line) \
147 CONCAT(LL, CPU_NR, _EXTI_ClearRisingFlag_##line_range)(EXTI_LL_INST line)
148 #define EXTI_CLEAR_FALLING_FLAG(line_range, line) \
149 CONCAT(LL, CPU_NR, _EXTI_ClearFallingFlag_##line_range)(EXTI_LL_INST line)
150
151 #endif /* CONFIG_SOC_SERIES_STM32MP2X */
152
153 #define EXTI_CLEAR_FLAG(line_range, line) \
154 { \
155 EXTI_CLEAR_RISING_FLAG(line_range, (line)); \
156 EXTI_CLEAR_FALLING_FLAG(line_range, (line)); \
157 }
158 #define EXTI_IS_ACTIVE_FLAG(line_range, line) \
159 (EXTI_IS_ACTIVE_RISING_FLAG(line_range, (line)) || \
160 EXTI_IS_ACTIVE_FALLING_FLAG(line_range, (line)))
161
162 #else /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti) */
163
164 #define EXTI_CLEAR_FLAG(line_range, line) \
165 CONCAT(LL, CPU_NR, _EXTI_ClearFlag_##line_range)(line)
166 #define EXTI_IS_ACTIVE_FLAG(line_range, line) \
167 CONCAT(LL, CPU_NR, _EXTI_IsActiveFlag_##line_range)(line)
168
169 #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32g0_exti) */
170
171
172 /* Define general macros line-range independent */
173 #define EXTI_ENABLE_IT(line_range, line) \
174 CONCAT(LL, CPU_NR, _EXTI_EnableIT_##line_range)(EXTI_LL_INST line)
175 #define EXTI_DISABLE_IT(line_range, line) \
176 CONCAT(LL, CPU_NR, _EXTI_DisableIT_##line_range)(EXTI_LL_INST line)
177 #define EXTI_ENABLE_EVENT(line_range, line) \
178 CONCAT(LL, CPU_NR, _EXTI_EnableEvent_##line_range)(EXTI_LL_INST line)
179 #define EXTI_DISABLE_EVENT(line_range, line) \
180 CONCAT(LL, CPU_NR, _EXTI_DisableEvent_##line_range)(EXTI_LL_INST line)
181 #define EXTI_ENABLE_RISING_TRIG(line_range, line) \
182 CONCAT(LL, _EXTI_EnableRisingTrig_##line_range)(EXTI_LL_INST line)
183 #define EXTI_ENABLE_FALLING_TRIG(line_range, line) \
184 CONCAT(LL, _EXTI_EnableFallingTrig_##line_range)(EXTI_LL_INST line)
185 #define EXTI_DISABLE_FALLING_TRIG(line_range, line) \
186 CONCAT(LL, _EXTI_DisableFallingTrig_##line_range)(EXTI_LL_INST line)
187 #define EXTI_DISABLE_RISING_TRIG(line_range, line) \
188 CONCAT(LL, _EXTI_DisableRisingTrig_##line_range)(EXTI_LL_INST line)
189 #define EXTI_GENERATE_SWI(line_range, line) \
190 CONCAT(LL, _EXTI_GenerateSWI_##line_range)(EXTI_LL_INST line)
191
192 /**
193 * @returns LL_EXTI_LINE_n define corresponding to EXTI line number
194 */
exti_linenum_to_ll_exti_line(uint32_t line_num)195 static inline uint32_t exti_linenum_to_ll_exti_line(uint32_t line_num)
196 {
197 return BIT(line_num % 32);
198 }
199
200 #ifdef __cplusplus
201 }
202 #endif
203
204 #endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_EXTI_STM32_PRIV_H_ */
205