1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2020 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_intmux.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.intmux"
18 #endif
19
20 /*******************************************************************************
21 * Prototypes
22 ******************************************************************************/
23
24 /*!
25 * @brief Get instance number for INTMUX.
26 *
27 * @param base INTMUX peripheral base address.
28 */
29 static uint32_t INTMUX_GetInstance(INTMUX_Type *base);
30
31 #if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
32 /*!
33 * @brief Handle INTMUX all channels IRQ.
34 *
35 * The handler reads the INTMUX channel's active vector register. This returns the offset
36 * from the start of the vector table to the vector for the INTMUX channel's highest priority
37 * pending source interrupt. After a check for spurious interrupts (an offset of 0), the
38 * function address at the vector offset is read and jumped to.
39 *
40 * @param base INTMUX peripheral base address.
41 * @param channel INTMUX channel number.
42 */
43 static void INTMUX_CommonIRQHandler(INTMUX_Type *intmuxBase, uint32_t channel);
44 #endif
45
46 /*******************************************************************************
47 * Variables
48 ******************************************************************************/
49
50 /*! @brief Array to map INTMUX instance number to base pointer. */
51 static INTMUX_Type *const s_intmuxBases[] = INTMUX_BASE_PTRS;
52
53 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
54 /*! @brief Array to map INTMUX instance number to clock name. */
55 static const clock_ip_name_t s_intmuxClockName[] = INTMUX_CLOCKS;
56 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
57
58 #if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
59 /*! @brief Array to map INTMUX instance number to IRQ number. */
60 static const IRQn_Type s_intmuxIRQNumber[][FSL_FEATURE_INTMUX_CHANNEL_COUNT] = INTMUX_IRQS;
61 #endif /* FSL_FEATURE_INTMUX_DIRECTION_OUT */
62
63 /*******************************************************************************
64 * Code
65 ******************************************************************************/
66
INTMUX_GetInstance(INTMUX_Type * base)67 static uint32_t INTMUX_GetInstance(INTMUX_Type *base)
68 {
69 uint32_t instance;
70
71 /* Find the instance index from base address mappings. */
72 for (instance = 0; instance < ARRAY_SIZE(s_intmuxBases); instance++)
73 {
74 if (s_intmuxBases[instance] == base)
75 {
76 break;
77 }
78 }
79
80 assert(instance < ARRAY_SIZE(s_intmuxBases));
81
82 return instance;
83 }
84
85 #if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
INTMUX_CommonIRQHandler(INTMUX_Type * intmuxBase,uint32_t channel)86 static void INTMUX_CommonIRQHandler(INTMUX_Type *intmuxBase, uint32_t channel)
87 {
88 uint32_t pendingIrqOffset;
89
90 pendingIrqOffset = intmuxBase->CHANNEL[channel].CHn_VEC;
91 if (pendingIrqOffset != 0x00U)
92 {
93 uint32_t isr = *(uint32_t *)(SCB->VTOR + pendingIrqOffset);
94 ((void (*)(void))isr)();
95 }
96 SDK_ISR_EXIT_BARRIER;
97 }
98 #endif /* FSL_FEATURE_INTMUX_DIRECTION_OUT */
99
100 /*!
101 * brief Initializes the INTMUX module.
102 *
103 * This function enables the clock gate for the specified INTMUX. It then resets all channels, so that no
104 * interrupt sources are routed and the logic mode is set to default of #kINTMUX_ChannelLogicOR.
105 * Finally, the NVIC vectors for all the INTMUX output channels are enabled.
106 *
107 * param base INTMUX peripheral base address.
108 */
INTMUX_Init(INTMUX_Type * base)109 void INTMUX_Init(INTMUX_Type *base)
110 {
111 uint32_t channel;
112 uint32_t instance = INTMUX_GetInstance(base);
113
114 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
115 /* Enable clock gate. */
116 (void)CLOCK_EnableClock(s_intmuxClockName[instance]);
117 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
118 /* Reset all channels and enable NVIC vectors for all INTMUX channels. */
119 for (channel = 0; channel < (uint32_t)FSL_FEATURE_INTMUX_CHANNEL_COUNT; channel++)
120 {
121 INTMUX_ResetChannel(base, channel);
122 #if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
123 NVIC_EnableIRQ(s_intmuxIRQNumber[instance][channel]);
124 #endif /* FSL_FEATURE_INTMUX_DIRECTION_OUT */
125 }
126 }
127
128 /*!
129 * brief Deinitializes an INTMUX instance for operation.
130 *
131 * The clock gate for the specified INTMUX is disabled and the NVIC vectors for all channels are disabled.
132 *
133 * param base INTMUX peripheral base address.
134 */
INTMUX_Deinit(INTMUX_Type * base)135 void INTMUX_Deinit(INTMUX_Type *base)
136 {
137 uint32_t channel;
138 uint32_t instance = INTMUX_GetInstance(base);
139
140 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
141 /* Disable clock gate. */
142 (void)CLOCK_DisableClock(s_intmuxClockName[instance]);
143 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
144 /* Disable NVIC vectors for all of the INTMUX channels. */
145 for (channel = 0; channel < (uint32_t)FSL_FEATURE_INTMUX_CHANNEL_COUNT; channel++)
146 {
147 #if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
148 NVIC_DisableIRQ(s_intmuxIRQNumber[instance][channel]);
149 #endif /* FSL_FEATURE_INTMUX_DIRECTION_OUT */
150 }
151 }
152
153 #if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
154 #if defined(INTMUX0)
155 void INTMUX0_0_DriverIRQHandler(void);
INTMUX0_0_DriverIRQHandler(void)156 void INTMUX0_0_DriverIRQHandler(void)
157 {
158 INTMUX_CommonIRQHandler(INTMUX0, 0);
159 }
160
161 void INTMUX0_1_DriverIRQHandler(void);
INTMUX0_1_DriverIRQHandler(void)162 void INTMUX0_1_DriverIRQHandler(void)
163 {
164 INTMUX_CommonIRQHandler(INTMUX0, 1);
165 }
166
167 void INTMUX0_2_DriverIRQHandler(void);
INTMUX0_2_DriverIRQHandler(void)168 void INTMUX0_2_DriverIRQHandler(void)
169 {
170 INTMUX_CommonIRQHandler(INTMUX0, 2);
171 }
172
173 void INTMUX0_3_DriverIRQHandler(void);
INTMUX0_3_DriverIRQHandler(void)174 void INTMUX0_3_DriverIRQHandler(void)
175 {
176 INTMUX_CommonIRQHandler(INTMUX0, 3);
177 }
178
179 #if defined(FSL_FEATURE_INTMUX_CHANNEL_COUNT) && (FSL_FEATURE_INTMUX_CHANNEL_COUNT > 4U)
180 void INTMUX0_4_DriverIRQHandler(void);
INTMUX0_4_DriverIRQHandler(void)181 void INTMUX0_4_DriverIRQHandler(void)
182 {
183 INTMUX_CommonIRQHandler(INTMUX0, 4);
184 }
185
186 void INTMUX0_5_DriverIRQHandler(void);
INTMUX0_5_DriverIRQHandler(void)187 void INTMUX0_5_DriverIRQHandler(void)
188 {
189 INTMUX_CommonIRQHandler(INTMUX0, 5);
190 }
191
192 void INTMUX0_6_DriverIRQHandler(void);
INTMUX0_6_DriverIRQHandler(void)193 void INTMUX0_6_DriverIRQHandler(void)
194 {
195 INTMUX_CommonIRQHandler(INTMUX0, 6);
196 }
197
198 void INTMUX0_7_DriverIRQHandler(void);
INTMUX0_7_DriverIRQHandler(void)199 void INTMUX0_7_DriverIRQHandler(void)
200 {
201 INTMUX_CommonIRQHandler(INTMUX0, 7);
202 }
203 #endif /* FSL_FEATURE_INTMUX_CHANNEL_COUNT */
204
205 #endif
206
207 #if defined(INTMUX1)
208 void INTMUX1_0_DriverIRQHandler(void);
INTMUX1_0_DriverIRQHandler(void)209 void INTMUX1_0_DriverIRQHandler(void)
210 {
211 INTMUX_CommonIRQHandler(INTMUX1, 0);
212 }
213
214 void INTMUX1_1_DriverIRQHandler(void);
INTMUX1_1_DriverIRQHandler(void)215 void INTMUX1_1_DriverIRQHandler(void)
216 {
217 INTMUX_CommonIRQHandler(INTMUX1, 1);
218 }
219
220 void INTMUX1_2_DriverIRQHandler(void);
INTMUX1_2_DriverIRQHandler(void)221 void INTMUX1_2_DriverIRQHandler(void)
222 {
223 INTMUX_CommonIRQHandler(INTMUX1, 2);
224 }
225
226 void INTMUX1_3_DriverIRQHandler(void);
INTMUX1_3_DriverIRQHandler(void)227 void INTMUX1_3_DriverIRQHandler(void)
228 {
229 INTMUX_CommonIRQHandler(INTMUX1, 3);
230 }
231
232 #if defined(FSL_FEATURE_INTMUX_CHANNEL_COUNT) && (FSL_FEATURE_INTMUX_CHANNEL_COUNT > 4U)
233 void INTMUX1_4_DriverIRQHandler(void);
INTMUX1_4_DriverIRQHandler(void)234 void INTMUX1_4_DriverIRQHandler(void)
235 {
236 INTMUX_CommonIRQHandler(INTMUX1, 4);
237 }
238
239 void INTMUX1_5_DriverIRQHandler(void);
INTMUX1_5_DriverIRQHandler(void)240 void INTMUX1_5_DriverIRQHandler(void)
241 {
242 INTMUX_CommonIRQHandler(INTMUX1, 5);
243 }
244
245 void INTMUX1_6_DriverIRQHandler(void);
INTMUX1_6_DriverIRQHandler(void)246 void INTMUX1_6_DriverIRQHandler(void)
247 {
248 INTMUX_CommonIRQHandler(INTMUX1, 6);
249 }
250
251 void INTMUX1_7_DriverIRQHandler(void);
INTMUX1_7_DriverIRQHandler(void)252 void INTMUX1_7_DriverIRQHandler(void)
253 {
254 INTMUX_CommonIRQHandler(INTMUX1, 7);
255 }
256 #endif /* FSL_FEATURE_INTMUX_CHANNEL_COUNT */
257 #endif /* INTMUX1 */
258 #endif /* FSL_FEATURE_INTMUX_DIRECTION_OUT */
259