]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_MPU_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS / Demo / CORTEX_MPU_M33F_NXP_LPC55S69_MCUXpresso / NXP_Code / drivers / fsl_flexcomm.c
1 /*\r
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.\r
3  * Copyright 2016-2019 NXP\r
4  * All rights reserved.\r
5  *\r
6  * SPDX-License-Identifier: BSD-3-Clause\r
7  */\r
8 \r
9 #include "fsl_common.h"\r
10 #include "fsl_flexcomm.h"\r
11 \r
12 /*******************************************************************************\r
13  * Definitions\r
14  ******************************************************************************/\r
15 \r
16 /* Component ID definition, used by tools. */\r
17 #ifndef FSL_COMPONENT_ID\r
18 #define FSL_COMPONENT_ID "platform.drivers.flexcomm"\r
19 #endif\r
20 \r
21 /*!\r
22  * @brief Used for conversion between `void*` and `uint32_t`.\r
23  */\r
24 typedef union pvoid_to_u32\r
25 {\r
26     void *pvoid;\r
27     uint32_t u32;\r
28 } pvoid_to_u32_t;\r
29 \r
30 /*******************************************************************************\r
31  * Prototypes\r
32  ******************************************************************************/\r
33 /*! @brief Set the FLEXCOMM mode . */\r
34 static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock);\r
35 \r
36 /*! @brief check whether flexcomm supports peripheral type */\r
37 static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph);\r
38 \r
39 /*******************************************************************************\r
40  * Variables\r
41  ******************************************************************************/\r
42 \r
43 /*! @brief Pointers to real IRQ handlers installed by drivers for each instance. */\r
44 static flexcomm_irq_handler_t s_flexcommIrqHandler[FSL_FEATURE_SOC_FLEXCOMM_COUNT];\r
45 \r
46 /*! @brief Pointers to handles for each instance to provide context to interrupt routines */\r
47 static void *s_flexcommHandle[FSL_FEATURE_SOC_FLEXCOMM_COUNT];\r
48 \r
49 /*! @brief Array to map FLEXCOMM instance number to IRQ number. */\r
50 IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS;\r
51 \r
52 /*! @brief Array to map FLEXCOMM instance number to base address. */\r
53 static const uint32_t s_flexcommBaseAddrs[FSL_FEATURE_SOC_FLEXCOMM_COUNT] = FLEXCOMM_BASE_ADDRS;\r
54 \r
55 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)\r
56 /*! @brief IDs of clock for each FLEXCOMM module */\r
57 static const clock_ip_name_t s_flexcommClocks[] = FLEXCOMM_CLOCKS;\r
58 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */\r
59 \r
60 #if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)\r
61 /*! @brief Pointers to FLEXCOMM resets for each instance. */\r
62 static const reset_ip_name_t s_flexcommResets[] = FLEXCOMM_RSTS;\r
63 #endif\r
64 \r
65 /*******************************************************************************\r
66  * Code\r
67  ******************************************************************************/\r
68 \r
69 /* check whether flexcomm supports peripheral type */\r
70 static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph)\r
71 {\r
72     if (periph == FLEXCOMM_PERIPH_NONE)\r
73     {\r
74         return true;\r
75     }\r
76     else if (periph <= FLEXCOMM_PERIPH_I2S_TX)\r
77     {\r
78         return (base->PSELID & (1UL << ((uint32_t)periph + 3U))) > 0UL ? true : false;\r
79     }\r
80     else if (periph == FLEXCOMM_PERIPH_I2S_RX)\r
81     {\r
82         return (base->PSELID & (1U << 7U)) > (uint32_t)0U ? true : false;\r
83     }\r
84     else\r
85     {\r
86         return false;\r
87     }\r
88 }\r
89 \r
90 /* Get the index corresponding to the FLEXCOMM */\r
91 /*! brief Returns instance number for FLEXCOMM module with given base address. */\r
92 uint32_t FLEXCOMM_GetInstance(void *base)\r
93 {\r
94     uint32_t i;\r
95     pvoid_to_u32_t BaseAddr;\r
96     BaseAddr.pvoid = base;\r
97 \r
98     for (i = 0U; i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++)\r
99     {\r
100         if (BaseAddr.u32 == s_flexcommBaseAddrs[i])\r
101         {\r
102             break;\r
103         }\r
104     }\r
105 \r
106     assert(i < FSL_FEATURE_SOC_FLEXCOMM_COUNT);\r
107     return i;\r
108 }\r
109 \r
110 /* Changes FLEXCOMM mode */\r
111 static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock)\r
112 {\r
113     /* Check whether peripheral type is present */\r
114     if (!FLEXCOMM_PeripheralIsPresent(base, periph))\r
115     {\r
116         return kStatus_OutOfRange;\r
117     }\r
118 \r
119     /* Flexcomm is locked to different peripheral type than expected  */\r
120     if (((base->PSELID & FLEXCOMM_PSELID_LOCK_MASK) != 0U) &&\r
121         ((base->PSELID & FLEXCOMM_PSELID_PERSEL_MASK) != (uint32_t)periph))\r
122     {\r
123         return kStatus_Fail;\r
124     }\r
125 \r
126     /* Check if we are asked to lock */\r
127     if (lock != 0)\r
128     {\r
129         base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK;\r
130     }\r
131     else\r
132     {\r
133         base->PSELID = (uint32_t)periph;\r
134     }\r
135 \r
136     return kStatus_Success;\r
137 }\r
138 \r
139 /*! brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */\r
140 status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph)\r
141 {\r
142     uint32_t idx = FLEXCOMM_GetInstance(base);\r
143 \r
144 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)\r
145     /* Enable the peripheral clock */\r
146     CLOCK_EnableClock(s_flexcommClocks[idx]);\r
147 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */\r
148 \r
149 #if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)\r
150     /* Reset the FLEXCOMM module */\r
151     RESET_PeripheralReset(s_flexcommResets[idx]);\r
152 #endif\r
153 \r
154     /* Set the FLEXCOMM to given peripheral */\r
155     return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0);\r
156 }\r
157 \r
158 /*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM\r
159  * mode */\r
160 void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *handle)\r
161 {\r
162     uint32_t instance;\r
163 \r
164     /* Look up instance number */\r
165     instance = FLEXCOMM_GetInstance(base);\r
166 \r
167     /* Clear handler first to avoid execution of the handler with wrong handle */\r
168     s_flexcommIrqHandler[instance] = NULL;\r
169     s_flexcommHandle[instance]     = handle;\r
170     s_flexcommIrqHandler[instance] = handler;\r
171 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
172   exception return operation might vector to incorrect interrupt */\r
173 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
174     __DSB();\r
175 #endif\r
176 }\r
177 \r
178 /* IRQ handler functions overloading weak symbols in the startup */\r
179 #if defined(FLEXCOMM0)\r
180 void FLEXCOMM0_DriverIRQHandler(void)\r
181 {\r
182     assert(s_flexcommIrqHandler[0]);\r
183     s_flexcommIrqHandler[0]((uint32_t *)s_flexcommBaseAddrs[0], s_flexcommHandle[0]);\r
184 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
185   exception return operation might vector to incorrect interrupt */\r
186 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
187     __DSB();\r
188 #endif\r
189 }\r
190 #endif\r
191 \r
192 #if defined(FLEXCOMM1)\r
193 void FLEXCOMM1_DriverIRQHandler(void)\r
194 {\r
195     assert(s_flexcommIrqHandler[1]);\r
196     s_flexcommIrqHandler[1]((uint32_t *)s_flexcommBaseAddrs[1], s_flexcommHandle[1]);\r
197 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
198   exception return operation might vector to incorrect interrupt */\r
199 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
200     __DSB();\r
201 #endif\r
202 }\r
203 #endif\r
204 \r
205 #if defined(FLEXCOMM2)\r
206 void FLEXCOMM2_DriverIRQHandler(void)\r
207 {\r
208     assert(s_flexcommIrqHandler[2]);\r
209     s_flexcommIrqHandler[2]((uint32_t *)s_flexcommBaseAddrs[2], s_flexcommHandle[2]);\r
210 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
211   exception return operation might vector to incorrect interrupt */\r
212 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
213     __DSB();\r
214 #endif\r
215 }\r
216 #endif\r
217 \r
218 #if defined(FLEXCOMM3)\r
219 void FLEXCOMM3_DriverIRQHandler(void)\r
220 {\r
221     assert(s_flexcommIrqHandler[3]);\r
222     s_flexcommIrqHandler[3]((uint32_t *)s_flexcommBaseAddrs[3], s_flexcommHandle[3]);\r
223 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
224   exception return operation might vector to incorrect interrupt */\r
225 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
226     __DSB();\r
227 #endif\r
228 }\r
229 #endif\r
230 \r
231 #if defined(FLEXCOMM4)\r
232 void FLEXCOMM4_DriverIRQHandler(void)\r
233 {\r
234     assert(s_flexcommIrqHandler[4]);\r
235     s_flexcommIrqHandler[4]((uint32_t *)s_flexcommBaseAddrs[4], s_flexcommHandle[4]);\r
236 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
237   exception return operation might vector to incorrect interrupt */\r
238 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
239     __DSB();\r
240 #endif\r
241 }\r
242 \r
243 #endif\r
244 \r
245 #if defined(FLEXCOMM5)\r
246 void FLEXCOMM5_DriverIRQHandler(void)\r
247 {\r
248     assert(s_flexcommIrqHandler[5]);\r
249     s_flexcommIrqHandler[5]((uint32_t *)s_flexcommBaseAddrs[5], s_flexcommHandle[5]);\r
250 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
251   exception return operation might vector to incorrect interrupt */\r
252 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
253     __DSB();\r
254 #endif\r
255 }\r
256 #endif\r
257 \r
258 #if defined(FLEXCOMM6)\r
259 void FLEXCOMM6_DriverIRQHandler(void)\r
260 {\r
261     assert(s_flexcommIrqHandler[6]);\r
262     s_flexcommIrqHandler[6]((uint32_t *)s_flexcommBaseAddrs[6], s_flexcommHandle[6]);\r
263 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
264   exception return operation might vector to incorrect interrupt */\r
265 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
266     __DSB();\r
267 #endif\r
268 }\r
269 #endif\r
270 \r
271 #if defined(FLEXCOMM7)\r
272 void FLEXCOMM7_DriverIRQHandler(void)\r
273 {\r
274     assert(s_flexcommIrqHandler[7]);\r
275     s_flexcommIrqHandler[7]((uint32_t *)s_flexcommBaseAddrs[7], s_flexcommHandle[7]);\r
276 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
277   exception return operation might vector to incorrect interrupt */\r
278 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
279     __DSB();\r
280 #endif\r
281 }\r
282 #endif\r
283 \r
284 #if defined(FLEXCOMM8)\r
285 void FLEXCOMM8_DriverIRQHandler(void)\r
286 {\r
287     assert(s_flexcommIrqHandler[8]);\r
288     s_flexcommIrqHandler[8]((uint32_t *)s_flexcommBaseAddrs[8], s_flexcommHandle[8]);\r
289 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
290   exception return operation might vector to incorrect interrupt */\r
291 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
292     __DSB();\r
293 #endif\r
294 }\r
295 #endif\r
296 \r
297 #if defined(FLEXCOMM9)\r
298 void FLEXCOMM9_DriverIRQHandler(void)\r
299 {\r
300     assert(s_flexcommIrqHandler[9]);\r
301     s_flexcommIrqHandler[9]((uint32_t *)s_flexcommBaseAddrs[9], s_flexcommHandle[9]);\r
302 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
303   exception return operation might vector to incorrect interrupt */\r
304 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
305     __DSB();\r
306 #endif\r
307 }\r
308 #endif\r
309 \r
310 #if defined(FLEXCOMM10)\r
311 void FLEXCOMM10_DriverIRQHandler(void)\r
312 {\r
313     assert(s_flexcommIrqHandler[10]);\r
314     s_flexcommIrqHandler[10]((uint32_t *)s_flexcommBaseAddrs[10], s_flexcommHandle[10]);\r
315 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
316   exception return operation might vector to incorrect interrupt */\r
317 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
318     __DSB();\r
319 #endif\r
320 }\r
321 #endif\r
322 \r
323 #if defined(FLEXCOMM11)\r
324 void FLEXCOMM11_DriverIRQHandler(void)\r
325 {\r
326     assert(s_flexcommIrqHandler[11]);\r
327     s_flexcommIrqHandler[11]((uint32_t *)s_flexcommBaseAddrs[11], s_flexcommHandle[11]);\r
328 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
329   exception return operation might vector to incorrect interrupt */\r
330 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
331     __DSB();\r
332 #endif\r
333 }\r
334 #endif\r
335 \r
336 #if defined(FLEXCOMM12)\r
337 void FLEXCOMM12_DriverIRQHandler(void)\r
338 {\r
339     assert(s_flexcommIrqHandler[12]);\r
340     s_flexcommIrqHandler[12]((uint32_t *)s_flexcommBaseAddrs[12], s_flexcommHandle[12]);\r
341 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
342   exception return operation might vector to incorrect interrupt */\r
343 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
344     __DSB();\r
345 #endif\r
346 }\r
347 #endif\r
348 \r
349 #if defined(FLEXCOMM13)\r
350 void FLEXCOMM13_DriverIRQHandler(void)\r
351 {\r
352     assert(s_flexcommIrqHandler[13]);\r
353     s_flexcommIrqHandler[13]((uint32_t *)s_flexcommBaseAddrs[13], s_flexcommHandle[13]);\r
354 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
355   exception return operation might vector to incorrect interrupt */\r
356 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
357     __DSB();\r
358 #endif\r
359 }\r
360 #endif\r
361 \r
362 #if defined(FLEXCOMM14)\r
363 void FLEXCOMM14_DriverIRQHandler(void)\r
364 {\r
365     uint32_t instance;\r
366 \r
367     /* Look up instance number */\r
368     instance = FLEXCOMM_GetInstance(FLEXCOMM14);\r
369     assert(s_flexcommIrqHandler[instance]);\r
370     s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);\r
371 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
372   exception return operation might vector to incorrect interrupt */\r
373 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
374     __DSB();\r
375 #endif\r
376 }\r
377 #endif\r
378 \r
379 #if defined(FLEXCOMM15)\r
380 void FLEXCOMM15_DriverIRQHandler(void)\r
381 {\r
382     uint32_t instance;\r
383 \r
384     /* Look up instance number */\r
385     instance = FLEXCOMM_GetInstance(FLEXCOMM15);\r
386     assert(s_flexcommIrqHandler[instance]);\r
387     s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);\r
388 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
389   exception return operation might vector to incorrect interrupt */\r
390 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
391     __DSB();\r
392 #endif\r
393 }\r
394 #endif\r
395 \r
396 #if defined(FLEXCOMM16)\r
397 void FLEXCOMM16_DriverIRQHandler(void)\r
398 {\r
399     uint32_t instance;\r
400 \r
401     /* Look up instance number */\r
402     instance = FLEXCOMM_GetInstance(FLEXCOMM16);\r
403     assert(s_flexcommIrqHandler[instance]);\r
404     s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);\r
405 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
406   exception return operation might vector to incorrect interrupt */\r
407 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
408     __DSB();\r
409 #endif\r
410 }\r
411 #endif\r