]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M0+_LPC51U68_GCC_IAR_KEIL/drivers/fsl_flexcomm.c
Increase test coverage for queue sets.
[freertos] / FreeRTOS / Demo / CORTEX_M0+_LPC51U68_GCC_IAR_KEIL / drivers / fsl_flexcomm.c
1 /*\r
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.\r
3  * Copyright 2016-2017 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  * Prototypes\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
26 \r
27 /*! @brief check whether flexcomm supports peripheral type */\r
28 static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph);\r
29 \r
30 /*******************************************************************************\r
31  * Variables\r
32  ******************************************************************************/\r
33 \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
36 \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
39 \r
40 /*! @brief Array to map FLEXCOMM instance number to IRQ number. */\r
41 IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS;\r
42 \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
45 \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
50 \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
54 #endif\r
55 \r
56 /*******************************************************************************\r
57  * Code\r
58  ******************************************************************************/\r
59 \r
60 /* check whether flexcomm supports peripheral type */\r
61 static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph)\r
62 {\r
63     if (periph == FLEXCOMM_PERIPH_NONE)\r
64     {\r
65         return true;\r
66     }\r
67     else if (periph <= FLEXCOMM_PERIPH_I2S_TX)\r
68     {\r
69         return (base->PSELID & (uint32_t)(1 << ((uint32_t)periph + 3))) > (uint32_t)0 ? true : false;\r
70     }\r
71     else if (periph == FLEXCOMM_PERIPH_I2S_RX)\r
72     {\r
73         return (base->PSELID & (1 << 7)) > (uint32_t)0 ? true : false;\r
74     }\r
75     else\r
76     {\r
77         return false;\r
78     }\r
79 }\r
80 \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
84 {\r
85     int i;\r
86 \r
87     for (i = 0; i < FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++)\r
88     {\r
89         if ((uint32_t)base == s_flexcommBaseAddrs[i])\r
90         {\r
91             return i;\r
92         }\r
93     }\r
94 \r
95     assert(false);\r
96     return 0;\r
97 }\r
98 \r
99 /* Changes FLEXCOMM mode */\r
100 static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock)\r
101 {\r
102     /* Check whether peripheral type is present */\r
103     if (!FLEXCOMM_PeripheralIsPresent(base, periph))\r
104     {\r
105         return kStatus_OutOfRange;\r
106     }\r
107 \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
110     {\r
111         return kStatus_Fail;\r
112     }\r
113 \r
114     /* Check if we are asked to lock */\r
115     if (lock)\r
116     {\r
117         base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK;\r
118     }\r
119     else\r
120     {\r
121         base->PSELID = (uint32_t)periph;\r
122     }\r
123 \r
124     return kStatus_Success;\r
125 }\r
126 \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
129 {\r
130     int idx = FLEXCOMM_GetInstance(base);\r
131 \r
132     if (idx < 0)\r
133     {\r
134         return kStatus_InvalidArgument;\r
135     }\r
136 \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
141 \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
145 #endif\r
146 \r
147     /* Set the FLEXCOMM to given peripheral */\r
148     return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0);\r
149 }\r
150 \r
151 /*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM\r
152  * mode */\r
153 void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *handle)\r
154 {\r
155     uint32_t instance;\r
156 \r
157     /* Look up instance number */\r
158     instance = FLEXCOMM_GetInstance(base);\r
159 \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
167     __DSB();\r
168 #endif\r
169 }\r
170 \r
171 /* IRQ handler functions overloading weak symbols in the startup */\r
172 #if defined(FLEXCOMM0)\r
173 void FLEXCOMM0_DriverIRQHandler(void)\r
174 {\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
180     __DSB();\r
181 #endif\r
182 }\r
183 #endif\r
184 \r
185 #if defined(FLEXCOMM1)\r
186 void FLEXCOMM1_DriverIRQHandler(void)\r
187 {\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
193     __DSB();\r
194 #endif\r
195 }\r
196 #endif\r
197 \r
198 #if defined(FLEXCOMM2)\r
199 void FLEXCOMM2_DriverIRQHandler(void)\r
200 {\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
206     __DSB();\r
207 #endif\r
208 }\r
209 #endif\r
210 \r
211 #if defined(FLEXCOMM3)\r
212 void FLEXCOMM3_DriverIRQHandler(void)\r
213 {\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
219     __DSB();\r
220 #endif\r
221 }\r
222 #endif\r
223 \r
224 #if defined(FLEXCOMM4)\r
225 void FLEXCOMM4_DriverIRQHandler(void)\r
226 {\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
232     __DSB();\r
233 #endif\r
234 }\r
235 \r
236 #endif\r
237 \r
238 #if defined(FLEXCOMM5)\r
239 void FLEXCOMM5_DriverIRQHandler(void)\r
240 {\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
246     __DSB();\r
247 #endif\r
248 }\r
249 #endif\r
250 \r
251 #if defined(FLEXCOMM6)\r
252 void FLEXCOMM6_DriverIRQHandler(void)\r
253 {\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
259     __DSB();\r
260 #endif\r
261 }\r
262 #endif\r
263 \r
264 #if defined(FLEXCOMM7)\r
265 void FLEXCOMM7_DriverIRQHandler(void)\r
266 {\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
272     __DSB();\r
273 #endif\r
274 }\r
275 #endif\r
276 \r
277 #if defined(FLEXCOMM8)\r
278 void FLEXCOMM8_DriverIRQHandler(void)\r
279 {\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
285     __DSB();\r
286 #endif\r
287 }\r
288 #endif\r
289 \r
290 #if defined(FLEXCOMM9)\r
291 void FLEXCOMM9_DriverIRQHandler(void)\r
292 {\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
298     __DSB();\r
299 #endif\r
300 }\r
301 #endif\r
302 \r
303 #if defined(FLEXCOMM10)\r
304 void FLEXCOMM10_DriverIRQHandler(void)\r
305 {\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
311     __DSB();\r
312 #endif\r
313 }\r
314 #endif\r
315 \r
316 #if defined(FLEXCOMM11)\r
317 void FLEXCOMM11_DriverIRQHandler(void)\r
318 {\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
324     __DSB();\r
325 #endif\r
326 }\r
327 #endif\r
328 \r
329 #if defined(FLEXCOMM12)\r
330 void FLEXCOMM12_DriverIRQHandler(void)\r
331 {\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
337     __DSB();\r
338 #endif\r
339 }\r
340 #endif\r
341 \r
342 #if defined(FLEXCOMM13)\r
343 void FLEXCOMM13_DriverIRQHandler(void)\r
344 {\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
350     __DSB();\r
351 #endif\r
352 }\r
353 #endif\r
354 \r
355 #if defined(FLEXCOMM14)\r
356 void FLEXCOMM14_DriverIRQHandler(void)\r
357 {\r
358     uint32_t instance;\r
359 \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
367     __DSB();\r
368 #endif\r
369 }\r
370 #endif\r
371 \r
372 #if defined(FLEXCOMM15)\r
373 void FLEXCOMM15_DriverIRQHandler(void)\r
374 {\r
375     uint32_t instance;\r
376 \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
384     __DSB();\r
385 #endif\r
386 }\r
387 #endif\r
388 \r
389 #if defined(FLEXCOMM16)\r
390 void FLEXCOMM16_DriverIRQHandler(void)\r
391 {\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
397     __DSB();\r
398 #endif\r
399 }\r
400 #endif\r