2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
\r
3 * Copyright 2016-2017 NXP
\r
4 * All rights reserved.
\r
6 * SPDX-License-Identifier: BSD-3-Clause
\r
9 #include "fsl_common.h"
\r
10 #include "fsl_flexcomm.h"
\r
12 /*******************************************************************************
\r
14 ******************************************************************************/
\r
16 /* Component ID definition, used by tools. */
\r
17 #ifndef FSL_COMPONENT_ID
\r
18 #define FSL_COMPONENT_ID "platform.drivers.flexcomm"
\r
21 /*******************************************************************************
\r
23 ******************************************************************************/
\r
24 /*! @brief Set the FLEXCOMM mode . */
\r
25 static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock);
\r
27 /*! @brief check whether flexcomm supports peripheral type */
\r
28 static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph);
\r
30 /*******************************************************************************
\r
32 ******************************************************************************/
\r
34 /*! @brief Pointers to real IRQ handlers installed by drivers for each instance. */
\r
35 static flexcomm_irq_handler_t s_flexcommIrqHandler[FSL_FEATURE_SOC_FLEXCOMM_COUNT];
\r
37 /*! @brief Pointers to handles for each instance to provide context to interrupt routines */
\r
38 static void *s_flexcommHandle[FSL_FEATURE_SOC_FLEXCOMM_COUNT];
\r
40 /*! @brief Array to map FLEXCOMM instance number to IRQ number. */
\r
41 IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS;
\r
43 /*! @brief Array to map FLEXCOMM instance number to base address. */
\r
44 static const uint32_t s_flexcommBaseAddrs[FSL_FEATURE_SOC_FLEXCOMM_COUNT] = FLEXCOMM_BASE_ADDRS;
\r
46 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
\r
47 /*! @brief IDs of clock for each FLEXCOMM module */
\r
48 static const clock_ip_name_t s_flexcommClocks[] = FLEXCOMM_CLOCKS;
\r
49 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
\r
51 #if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
\r
52 /*! @brief Pointers to FLEXCOMM resets for each instance. */
\r
53 static const reset_ip_name_t s_flexcommResets[] = FLEXCOMM_RSTS;
\r
56 /*******************************************************************************
\r
58 ******************************************************************************/
\r
60 /* check whether flexcomm supports peripheral type */
\r
61 static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph)
\r
63 if (periph == FLEXCOMM_PERIPH_NONE)
\r
67 else if (periph <= FLEXCOMM_PERIPH_I2S_TX)
\r
69 return (base->PSELID & (uint32_t)(1 << ((uint32_t)periph + 3))) > (uint32_t)0 ? true : false;
\r
71 else if (periph == FLEXCOMM_PERIPH_I2S_RX)
\r
73 return (base->PSELID & (1 << 7)) > (uint32_t)0 ? true : false;
\r
81 /* Get the index corresponding to the FLEXCOMM */
\r
82 /*! brief Returns instance number for FLEXCOMM module with given base address. */
\r
83 uint32_t FLEXCOMM_GetInstance(void *base)
\r
87 for (i = 0; i < FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++)
\r
89 if ((uint32_t)base == s_flexcommBaseAddrs[i])
\r
99 /* Changes FLEXCOMM mode */
\r
100 static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock)
\r
102 /* Check whether peripheral type is present */
\r
103 if (!FLEXCOMM_PeripheralIsPresent(base, periph))
\r
105 return kStatus_OutOfRange;
\r
108 /* Flexcomm is locked to different peripheral type than expected */
\r
109 if ((base->PSELID & FLEXCOMM_PSELID_LOCK_MASK) && ((base->PSELID & FLEXCOMM_PSELID_PERSEL_MASK) != periph))
\r
111 return kStatus_Fail;
\r
114 /* Check if we are asked to lock */
\r
117 base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK;
\r
121 base->PSELID = (uint32_t)periph;
\r
124 return kStatus_Success;
\r
127 /*! brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
\r
128 status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph)
\r
130 int idx = FLEXCOMM_GetInstance(base);
\r
134 return kStatus_InvalidArgument;
\r
137 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
\r
138 /* Enable the peripheral clock */
\r
139 CLOCK_EnableClock(s_flexcommClocks[idx]);
\r
140 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
\r
142 #if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
\r
143 /* Reset the FLEXCOMM module */
\r
144 RESET_PeripheralReset(s_flexcommResets[idx]);
\r
147 /* Set the FLEXCOMM to given peripheral */
\r
148 return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0);
\r
151 /*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
\r
153 void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *handle)
\r
157 /* Look up instance number */
\r
158 instance = FLEXCOMM_GetInstance(base);
\r
160 /* Clear handler first to avoid execution of the handler with wrong handle */
\r
161 s_flexcommIrqHandler[instance] = NULL;
\r
162 s_flexcommHandle[instance] = handle;
\r
163 s_flexcommIrqHandler[instance] = handler;
\r
164 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
165 exception return operation might vector to incorrect interrupt */
\r
166 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
171 /* IRQ handler functions overloading weak symbols in the startup */
\r
172 #if defined(FLEXCOMM0)
\r
173 void FLEXCOMM0_DriverIRQHandler(void)
\r
175 assert(s_flexcommIrqHandler[0]);
\r
176 s_flexcommIrqHandler[0]((void *)s_flexcommBaseAddrs[0], s_flexcommHandle[0]);
\r
177 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
178 exception return operation might vector to incorrect interrupt */
\r
179 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
185 #if defined(FLEXCOMM1)
\r
186 void FLEXCOMM1_DriverIRQHandler(void)
\r
188 assert(s_flexcommIrqHandler[1]);
\r
189 s_flexcommIrqHandler[1]((void *)s_flexcommBaseAddrs[1], s_flexcommHandle[1]);
\r
190 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
191 exception return operation might vector to incorrect interrupt */
\r
192 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
198 #if defined(FLEXCOMM2)
\r
199 void FLEXCOMM2_DriverIRQHandler(void)
\r
201 assert(s_flexcommIrqHandler[2]);
\r
202 s_flexcommIrqHandler[2]((void *)s_flexcommBaseAddrs[2], s_flexcommHandle[2]);
\r
203 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
204 exception return operation might vector to incorrect interrupt */
\r
205 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
211 #if defined(FLEXCOMM3)
\r
212 void FLEXCOMM3_DriverIRQHandler(void)
\r
214 assert(s_flexcommIrqHandler[3]);
\r
215 s_flexcommIrqHandler[3]((void *)s_flexcommBaseAddrs[3], s_flexcommHandle[3]);
\r
216 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
217 exception return operation might vector to incorrect interrupt */
\r
218 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
224 #if defined(FLEXCOMM4)
\r
225 void FLEXCOMM4_DriverIRQHandler(void)
\r
227 assert(s_flexcommIrqHandler[4]);
\r
228 s_flexcommIrqHandler[4]((void *)s_flexcommBaseAddrs[4], s_flexcommHandle[4]);
\r
229 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
230 exception return operation might vector to incorrect interrupt */
\r
231 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
238 #if defined(FLEXCOMM5)
\r
239 void FLEXCOMM5_DriverIRQHandler(void)
\r
241 assert(s_flexcommIrqHandler[5]);
\r
242 s_flexcommIrqHandler[5]((void *)s_flexcommBaseAddrs[5], s_flexcommHandle[5]);
\r
243 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
244 exception return operation might vector to incorrect interrupt */
\r
245 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
251 #if defined(FLEXCOMM6)
\r
252 void FLEXCOMM6_DriverIRQHandler(void)
\r
254 assert(s_flexcommIrqHandler[6]);
\r
255 s_flexcommIrqHandler[6]((void *)s_flexcommBaseAddrs[6], s_flexcommHandle[6]);
\r
256 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
257 exception return operation might vector to incorrect interrupt */
\r
258 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
264 #if defined(FLEXCOMM7)
\r
265 void FLEXCOMM7_DriverIRQHandler(void)
\r
267 assert(s_flexcommIrqHandler[7]);
\r
268 s_flexcommIrqHandler[7]((void *)s_flexcommBaseAddrs[7], s_flexcommHandle[7]);
\r
269 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
270 exception return operation might vector to incorrect interrupt */
\r
271 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
277 #if defined(FLEXCOMM8)
\r
278 void FLEXCOMM8_DriverIRQHandler(void)
\r
280 assert(s_flexcommIrqHandler[8]);
\r
281 s_flexcommIrqHandler[8]((void *)s_flexcommBaseAddrs[8], s_flexcommHandle[8]);
\r
282 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
283 exception return operation might vector to incorrect interrupt */
\r
284 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
290 #if defined(FLEXCOMM9)
\r
291 void FLEXCOMM9_DriverIRQHandler(void)
\r
293 assert(s_flexcommIrqHandler[9]);
\r
294 s_flexcommIrqHandler[9]((void *)s_flexcommBaseAddrs[9], s_flexcommHandle[9]);
\r
295 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
296 exception return operation might vector to incorrect interrupt */
\r
297 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
303 #if defined(FLEXCOMM10)
\r
304 void FLEXCOMM10_DriverIRQHandler(void)
\r
306 assert(s_flexcommIrqHandler[10]);
\r
307 s_flexcommIrqHandler[10]((void *)s_flexcommBaseAddrs[10], s_flexcommHandle[10]);
\r
308 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
309 exception return operation might vector to incorrect interrupt */
\r
310 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
316 #if defined(FLEXCOMM11)
\r
317 void FLEXCOMM11_DriverIRQHandler(void)
\r
319 assert(s_flexcommIrqHandler[11]);
\r
320 s_flexcommIrqHandler[11]((void *)s_flexcommBaseAddrs[11], s_flexcommHandle[11]);
\r
321 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
322 exception return operation might vector to incorrect interrupt */
\r
323 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
329 #if defined(FLEXCOMM12)
\r
330 void FLEXCOMM12_DriverIRQHandler(void)
\r
332 assert(s_flexcommIrqHandler[12]);
\r
333 s_flexcommIrqHandler[12]((void *)s_flexcommBaseAddrs[12], s_flexcommHandle[12]);
\r
334 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
335 exception return operation might vector to incorrect interrupt */
\r
336 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
342 #if defined(FLEXCOMM13)
\r
343 void FLEXCOMM13_DriverIRQHandler(void)
\r
345 assert(s_flexcommIrqHandler[13]);
\r
346 s_flexcommIrqHandler[13]((void *)s_flexcommBaseAddrs[13], s_flexcommHandle[13]);
\r
347 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
348 exception return operation might vector to incorrect interrupt */
\r
349 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
355 #if defined(FLEXCOMM14)
\r
356 void FLEXCOMM14_DriverIRQHandler(void)
\r
360 /* Look up instance number */
\r
361 instance = FLEXCOMM_GetInstance(FLEXCOMM14);
\r
362 assert(s_flexcommIrqHandler[instance]);
\r
363 s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
\r
364 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
365 exception return operation might vector to incorrect interrupt */
\r
366 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
372 #if defined(FLEXCOMM15)
\r
373 void FLEXCOMM15_DriverIRQHandler(void)
\r
377 /* Look up instance number */
\r
378 instance = FLEXCOMM_GetInstance(FLEXCOMM14);
\r
379 assert(s_flexcommIrqHandler[instance]);
\r
380 s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
\r
381 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
382 exception return operation might vector to incorrect interrupt */
\r
383 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r
389 #if defined(FLEXCOMM16)
\r
390 void FLEXCOMM16_DriverIRQHandler(void)
\r
392 assert(s_flexcommIrqHandler[16]);
\r
393 s_flexcommIrqHandler[16]((void *)s_flexcommBaseAddrs[16], s_flexcommHandle[16]);
\r
394 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
\r
395 exception return operation might vector to incorrect interrupt */
\r
396 #if defined __CORTEX_M && (__CORTEX_M == 4U)
\r