]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_MPU_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/drivers/fsl_common.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS / Demo / CORTEX_MPU_M33F_NXP_LPC55S69_MCUXpresso / NXP_Code / drivers / fsl_common.c
1 /*\r
2  * Copyright (c) 2015-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 #define SDK_MEM_MAGIC_NUMBER 12345U\r
11 \r
12 typedef struct _mem_align_control_block\r
13 {\r
14     uint16_t identifier; /*!< Identifier for the memory control block. */\r
15     uint16_t offset;     /*!< offset from aligned address to real address */\r
16 } mem_align_cb_t;\r
17 \r
18 /* Component ID definition, used by tools. */\r
19 #ifndef FSL_COMPONENT_ID\r
20 #define FSL_COMPONENT_ID "platform.drivers.common"\r
21 #endif\r
22 \r
23 #ifndef __GIC_PRIO_BITS\r
24 #if defined(ENABLE_RAM_VECTOR_TABLE)\r
25 uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler)\r
26 {\r
27 /* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */\r
28 #if defined(__CC_ARM) || defined(__ARMCC_VERSION)\r
29     extern uint32_t Image$$VECTOR_ROM$$Base[];\r
30     extern uint32_t Image$$VECTOR_RAM$$Base[];\r
31     extern uint32_t Image$$RW_m_data$$Base[];\r
32 \r
33 #define __VECTOR_TABLE Image$$VECTOR_ROM$$Base\r
34 #define __VECTOR_RAM Image$$VECTOR_RAM$$Base\r
35 #define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base))\r
36 #elif defined(__ICCARM__)\r
37     extern uint32_t __RAM_VECTOR_TABLE_SIZE[];\r
38     extern uint32_t __VECTOR_TABLE[];\r
39     extern uint32_t __VECTOR_RAM[];\r
40 #elif defined(__GNUC__)\r
41     extern uint32_t __VECTOR_TABLE[];\r
42     extern uint32_t __VECTOR_RAM[];\r
43     extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[];\r
44     uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES);\r
45 #endif /* defined(__CC_ARM) || defined(__ARMCC_VERSION) */\r
46     uint32_t n;\r
47     uint32_t ret;\r
48     uint32_t irqMaskValue;\r
49 \r
50     irqMaskValue = DisableGlobalIRQ();\r
51     if (SCB->VTOR != (uint32_t)__VECTOR_RAM)\r
52     {\r
53         /* Copy the vector table from ROM to RAM */\r
54         for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++)\r
55         {\r
56             __VECTOR_RAM[n] = __VECTOR_TABLE[n];\r
57         }\r
58         /* Point the VTOR to the position of vector table */\r
59         SCB->VTOR = (uint32_t)__VECTOR_RAM;\r
60     }\r
61 \r
62     ret = __VECTOR_RAM[irq + 16];\r
63     /* make sure the __VECTOR_RAM is noncachable */\r
64     __VECTOR_RAM[irq + 16] = irqHandler;\r
65 \r
66     EnableGlobalIRQ(irqMaskValue);\r
67 \r
68 /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping\r
69   exception return operation might vector to incorrect interrupt */\r
70 #if defined __CORTEX_M && (__CORTEX_M == 4U)\r
71     __DSB();\r
72 #endif\r
73 \r
74     return ret;\r
75 }\r
76 #endif /* ENABLE_RAM_VECTOR_TABLE. */\r
77 #endif /* __GIC_PRIO_BITS. */\r
78 \r
79 #if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))\r
80 #if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS)\r
81 \r
82 void EnableDeepSleepIRQ(IRQn_Type interrupt)\r
83 {\r
84     uint32_t intNumber = (uint32_t)interrupt;\r
85 \r
86     uint32_t index = 0;\r
87 \r
88     while (intNumber >= 32u)\r
89     {\r
90         index++;\r
91         intNumber -= 32u;\r
92     }\r
93 \r
94     SYSCON->STARTERSET[index] = 1u << intNumber;\r
95     EnableIRQ(interrupt); /* also enable interrupt at NVIC */\r
96 }\r
97 \r
98 void DisableDeepSleepIRQ(IRQn_Type interrupt)\r
99 {\r
100     uint32_t intNumber = (uint32_t)interrupt;\r
101 \r
102     DisableIRQ(interrupt); /* also disable interrupt at NVIC */\r
103     uint32_t index = 0;\r
104 \r
105     while (intNumber >= 32u)\r
106     {\r
107         index++;\r
108         intNumber -= 32u;\r
109     }\r
110 \r
111     SYSCON->STARTERCLR[index] = 1u << intNumber;\r
112 }\r
113 #endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */\r
114 #endif /* FSL_FEATURE_SOC_SYSCON_COUNT */\r
115 \r
116 void *SDK_Malloc(size_t size, size_t alignbytes)\r
117 {\r
118     mem_align_cb_t *p_cb = NULL;\r
119     uint32_t alignedsize = SDK_SIZEALIGN(size, alignbytes) + alignbytes + sizeof(mem_align_cb_t);\r
120     union\r
121     {\r
122         void *pointer_value;\r
123         uint32_t unsigned_value;\r
124     } p_align_addr, p_addr;\r
125 \r
126     p_addr.pointer_value = malloc(alignedsize);\r
127 \r
128     if (p_addr.pointer_value == NULL)\r
129     {\r
130         return NULL;\r
131     }\r
132 \r
133     p_align_addr.unsigned_value = SDK_SIZEALIGN(p_addr.unsigned_value + sizeof(mem_align_cb_t), alignbytes);\r
134 \r
135     p_cb             = (mem_align_cb_t *)(p_align_addr.unsigned_value - 4U);\r
136     p_cb->identifier = SDK_MEM_MAGIC_NUMBER;\r
137     p_cb->offset     = (uint16_t)(p_align_addr.unsigned_value - p_addr.unsigned_value);\r
138 \r
139     return p_align_addr.pointer_value;\r
140 }\r
141 \r
142 void SDK_Free(void *ptr)\r
143 {\r
144     union\r
145     {\r
146         void *pointer_value;\r
147         uint32_t unsigned_value;\r
148     } p_free;\r
149     p_free.pointer_value = ptr;\r
150     mem_align_cb_t *p_cb = (mem_align_cb_t *)(p_free.unsigned_value - 4U);\r
151 \r
152     if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER)\r
153     {\r
154         return;\r
155     }\r
156 \r
157     p_free.unsigned_value = p_free.unsigned_value - p_cb->offset;\r
158 \r
159     free(p_free.pointer_value);\r
160 }\r
161 \r
162 /*!\r
163  * @brief Delay function bases on while loop, every loop includes three instructions.\r
164  *\r
165  * @param count  Counts of loop needed for dalay.\r
166  */\r
167 #ifndef __XCC__\r
168 #if defined(__CC_ARM) /* This macro is arm v5 specific */\r
169 /* clang-format off */\r
170 __ASM static void DelayLoop(uint32_t count)\r
171 {\r
172 loop\r
173     SUBS R0, R0, #1\r
174     CMP  R0, #0\r
175     BNE  loop\r
176     BX   LR\r
177 }\r
178 /* clang-format on */\r
179 #elif defined(__ARMCC_VERSION) || defined(__ICCARM__) || defined(__GNUC__)\r
180 /* Cortex-M0 has a smaller instruction set, SUBS isn't supported in thumb-16 mode reported from __GNUC__ compiler,\r
181  * use SUB and CMP here for compatibility */\r
182 static void DelayLoop(uint32_t count)\r
183 {\r
184     __ASM volatile("    MOV    R0, %0" : : "r"(count));\r
185     __ASM volatile(\r
186         "loop:                          \n"\r
187 #if defined(__GNUC__) && !defined(__ARMCC_VERSION)\r
188         "    SUB    R0, R0, #1          \n"\r
189 #else\r
190         "    SUBS   R0, R0, #1          \n"\r
191 #endif\r
192         "    CMP    R0, #0              \n"\r
193 \r
194         "    BNE    loop                \n");\r
195 }\r
196 #endif /* defined(__CC_ARM) */\r
197 \r
198 /*!\r
199  * @brief Delay at least for some time.\r
200  *  Please note that, this API uses while loop for delay, different run-time environments make the time not precise,\r
201  *  if precise delay count was needed, please implement a new delay function with hardware timer.\r
202  *\r
203  * @param delay_us  Delay time in unit of microsecond.\r
204  * @param coreClock_Hz  Core clock frequency with Hz.\r
205  */\r
206 void SDK_DelayAtLeastUs(uint32_t delay_us, uint32_t coreClock_Hz)\r
207 {\r
208     assert(0U != delay_us);\r
209     uint64_t count = USEC_TO_COUNT(delay_us, coreClock_Hz);\r
210     assert(count <= UINT32_MAX);\r
211 \r
212     /* Divide value may be different in various environment to ensure delay is precise.\r
213      * Every loop count includes three instructions, due to Cortex-M7 sometimes executes\r
214      * two instructions in one period, through test here set divide 2. Other M cores use\r
215      * divide 4. By the way, divide 2 or 4 could let odd count lost precision, but it does\r
216      * not matter because other instructions outside while loop is enough to fill the time.\r
217      */\r
218 #if (__CORTEX_M == 7)\r
219     count = count / 2U;\r
220 #else\r
221     count = count / 4U;\r
222 #endif\r
223     DelayLoop((uint32_t)count);\r
224 }\r
225 #endif\r