fsl_common.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2019 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_common.h"
10 #define SDK_MEM_MAGIC_NUMBER 12345U
11 
13 {
14  uint16_t identifier;
15  uint16_t offset;
17 
18 /* Component ID definition, used by tools. */
19 #ifndef FSL_COMPONENT_ID
20 #define FSL_COMPONENT_ID "platform.drivers.common"
21 #endif
22 
23 #ifndef __GIC_PRIO_BITS
24 #if defined(ENABLE_RAM_VECTOR_TABLE)
25 uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler)
26 {
27 /* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */
28 #if defined(__CC_ARM) || defined(__ARMCC_VERSION)
29  extern uint32_t Image$$VECTOR_ROM$$Base[];
30  extern uint32_t Image$$VECTOR_RAM$$Base[];
31  extern uint32_t Image$$RW_m_data$$Base[];
32 
33 #define __VECTOR_TABLE Image$$VECTOR_ROM$$Base
34 #define __VECTOR_RAM Image$$VECTOR_RAM$$Base
35 #define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base))
36 #elif defined(__ICCARM__)
37  extern uint32_t __RAM_VECTOR_TABLE_SIZE[];
38  extern uint32_t __VECTOR_TABLE[];
39  extern uint32_t __VECTOR_RAM[];
40 #elif defined(__GNUC__)
41  extern uint32_t __VECTOR_TABLE[];
42  extern uint32_t __VECTOR_RAM[];
43  extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[];
44  uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES);
45 #endif /* defined(__CC_ARM) || defined(__ARMCC_VERSION) */
46  uint32_t n;
47  uint32_t ret;
48  uint32_t irqMaskValue;
49 
50  irqMaskValue = DisableGlobalIRQ();
51  if (SCB->VTOR != (uint32_t)__VECTOR_RAM)
52  {
53  /* Copy the vector table from ROM to RAM */
54  for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++)
55  {
56  __VECTOR_RAM[n] = __VECTOR_TABLE[n];
57  }
58  /* Point the VTOR to the position of vector table */
59  SCB->VTOR = (uint32_t)__VECTOR_RAM;
60  }
61 
62  ret = __VECTOR_RAM[irq + 16];
63  /* make sure the __VECTOR_RAM is noncachable */
64  __VECTOR_RAM[irq + 16] = irqHandler;
65 
66  EnableGlobalIRQ(irqMaskValue);
68 
69  return ret;
70 }
71 #endif /* ENABLE_RAM_VECTOR_TABLE. */
72 #endif /* __GIC_PRIO_BITS. */
73 
74 #if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
75 #if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS)
76 
77 void EnableDeepSleepIRQ(IRQn_Type interrupt)
78 {
79  uint32_t intNumber = (uint32_t)interrupt;
80 
81  uint32_t index = 0;
82 
83  while (intNumber >= 32u)
84  {
85  index++;
86  intNumber -= 32u;
87  }
88 
89  SYSCON->STARTERSET[index] = 1u << intNumber;
90  EnableIRQ(interrupt); /* also enable interrupt at NVIC */
91 }
92 
93 void DisableDeepSleepIRQ(IRQn_Type interrupt)
94 {
95  uint32_t intNumber = (uint32_t)interrupt;
96 
97  DisableIRQ(interrupt); /* also disable interrupt at NVIC */
98  uint32_t index = 0;
99 
100  while (intNumber >= 32u)
101  {
102  index++;
103  intNumber -= 32u;
104  }
105 
106  SYSCON->STARTERCLR[index] = 1u << intNumber;
107 }
108 #endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */
109 #endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
110 
111 void *SDK_Malloc(size_t size, size_t alignbytes)
112 {
113  mem_align_cb_t *p_cb = NULL;
114  uint32_t alignedsize = SDK_SIZEALIGN(size, alignbytes) + alignbytes + sizeof(mem_align_cb_t);
115  union
116  {
117  void *pointer_value;
118  uint32_t unsigned_value;
119  } p_align_addr, p_addr;
120 
121  p_addr.pointer_value = malloc(alignedsize);
122 
123  if (p_addr.pointer_value == NULL)
124  {
125  return NULL;
126  }
127 
128  p_align_addr.unsigned_value = SDK_SIZEALIGN(p_addr.unsigned_value + sizeof(mem_align_cb_t), alignbytes);
129 
130  p_cb = (mem_align_cb_t *)(p_align_addr.unsigned_value - 4U);
132  p_cb->offset = (uint16_t)(p_align_addr.unsigned_value - p_addr.unsigned_value);
133 
134  return p_align_addr.pointer_value;
135 }
136 
137 void SDK_Free(void *ptr)
138 {
139  union
140  {
141  void *pointer_value;
142  uint32_t unsigned_value;
143  } p_free;
144  p_free.pointer_value = ptr;
145  mem_align_cb_t *p_cb = (mem_align_cb_t *)(p_free.unsigned_value - 4U);
146 
147  if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER)
148  {
149  return;
150  }
151 
152  p_free.unsigned_value = p_free.unsigned_value - p_cb->offset;
153 
154  free(p_free.pointer_value);
155 }
156 
162 #if defined(SDK_DELAY_USE_DWT) && defined(DWT)
163 void enableCpuCycleCounter(void)
164 {
165  /* Make sure the DWT trace fucntion is enabled. */
167  {
169  }
170 
171  /* CYCCNT not supported on this device. */
172  assert(DWT_CTRL_NOCYCCNT_Msk != (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk));
173 
174  /* Read CYCCNT directly if CYCCENT has already been enabled, otherwise enable CYCCENT first. */
176  {
177  DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
178  }
179 }
180 
181 uint32_t getCpuCycleCount(void)
182 {
183  return DWT->CYCCNT;
184 }
185 #elif defined __XCC__
186 extern uint32_t xthal_get_ccount(void);
187 void enableCpuCycleCounter(void)
188 {
189  /* do nothing */
190 }
191 
192 uint32_t getCpuCycleCount(void)
193 {
194  return xthal_get_ccount();
195 }
196 #endif
197 
198 #ifndef __XCC__
199 #if (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT))
200 #if defined(__CC_ARM) /* This macro is arm v5 specific */
201 /* clang-format off */
202 __ASM static void DelayLoop(uint32_t count)
203 {
204 loop
205  SUBS R0, R0, #1
206  CMP R0, #0
207  BNE loop
208  BX LR
209 }
210 /* clang-format on */
211 #elif defined(__ARMCC_VERSION) || defined(__ICCARM__) || defined(__GNUC__)
212 /* Cortex-M0 has a smaller instruction set, SUBS isn't supported in thumb-16 mode reported from __GNUC__ compiler,
213  * use SUB and CMP here for compatibility */
214 static void DelayLoop(uint32_t count)
215 {
216  __ASM volatile(" MOV R0, %0" : : "r"(count));
217  __ASM volatile(
218  "loop: \n"
219 #if defined(__GNUC__) && !defined(__ARMCC_VERSION)
220  " SUB R0, R0, #1 \n"
221 #else
222  " SUBS R0, R0, #1 \n"
223 #endif
224  " CMP R0, #0 \n"
225 
226  " BNE loop \n");
227 }
228 #endif /* defined(__CC_ARM) */
229 #endif /* (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT)) */
230 #endif /* __XCC__ */
231 
241 void SDK_DelayAtLeastUs(uint32_t delay_us, uint32_t coreClock_Hz)
242 {
243  assert(0U != delay_us);
244  uint64_t count = USEC_TO_COUNT(delay_us, coreClock_Hz);
245  assert(count <= UINT32_MAX);
246 
247 #if defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) /* Use DWT for better accuracy */
248 
249  enableCpuCycleCounter();
250  /* Calculate the count ticks. */
251  count += getCpuCycleCount();
252 
253  if (count > UINT32_MAX)
254  {
255  count -= UINT32_MAX;
256  /* Wait for cyccnt overflow. */
257  while (count < getCpuCycleCount())
258  {
259  }
260  }
261 
262  /* Wait for cyccnt reach count value. */
263  while (count > getCpuCycleCount())
264  {
265  }
266 #else
267  /* Divide value may be different in various environment to ensure delay is precise.
268  * Every loop count includes three instructions, due to Cortex-M7 sometimes executes
269  * two instructions in one period, through test here set divide 1.5. Other M cores use
270  * divide 4. By the way, divide 1.5 or 4 could let the count lose precision, but it does
271  * not matter because other instructions outside while loop is enough to fill the time.
272  */
273 #if (__CORTEX_M == 7)
274  count = count / 3U * 2U;
275 #else
276  count = count / 4U;
277 #endif
278  DelayLoop((uint32_t)count);
279 #endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) */
280 }
SCB
#define SCB
Definition: imxrt1050/imxrt1050-evkb/CMSIS/core_cm7.h:1778
fsl_common.h
mem_align_cb_t
struct _mem_align_control_block mem_align_cb_t
UINT32_MAX
#define UINT32_MAX
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:96
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
_mem_align_control_block::identifier
uint16_t identifier
Definition: fsl_common.c:14
_mem_align_control_block
Definition: fsl_common.c:12
SDK_DelayAtLeastUs
void SDK_DelayAtLeastUs(uint32_t delay_us, uint32_t coreClock_Hz)
Delay function bases on while loop, every loop includes three instructions.
Definition: fsl_common.c:241
SDK_SIZEALIGN
#define SDK_SIZEALIGN(var, alignbytes)
Definition: fsl_common.h:309
CoreDebug
#define CoreDebug
Definition: imxrt1050/imxrt1050-evkb/CMSIS/core_cm7.h:1784
SDK_Free
void SDK_Free(void *ptr)
Free memory.
Definition: fsl_common.c:137
DWT_CTRL_NOCYCCNT_Msk
#define DWT_CTRL_NOCYCCNT_Msk
Definition: imxrt1050/imxrt1050-evkb/CMSIS/core_cm7.h:1160
SDK_Malloc
void * SDK_Malloc(size_t size, size_t alignbytes)
Allocate memory with given alignment and aligned size.
Definition: fsl_common.c:111
USEC_TO_COUNT
#define USEC_TO_COUNT(us, clockFreqInHz)
Definition: fsl_common.h:228
DWT_CTRL_CYCCNTENA_Msk
#define DWT_CTRL_CYCCNTENA_Msk
Definition: imxrt1050/imxrt1050-evkb/CMSIS/core_cm7.h:1202
SDK_ISR_EXIT_BARRIER
#define SDK_ISR_EXIT_BARRIER
Definition: fsl_common.h:250
DisableIRQ
static status_t DisableIRQ(IRQn_Type interrupt)
Disable specific interrupt.
Definition: fsl_common.h:522
__VECTOR_TABLE
#define __VECTOR_TABLE
Definition: imxrt1050/imxrt1050-evkb/CMSIS/cmsis_armcc.h:126
DWT
#define DWT
Definition: imxrt1050/imxrt1050-evkb/CMSIS/core_cm7.h:1782
CoreDebug_DEMCR_TRCENA_Msk
#define CoreDebug_DEMCR_TRCENA_Msk
Definition: imxrt1050/imxrt1050-evkb/CMSIS/core_cm7.h:1693
IRQn_Type
IRQn_Type
STM32F4XX Interrupt Number Definition, according to the selected device in Library_configuration_sect...
Definition: stm32f407xx.h:66
count
size_t count
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_common/ma_test_common.c:31
DisableGlobalIRQ
static uint32_t DisableGlobalIRQ(void)
Disable the global IRQ.
Definition: fsl_common.h:552
EnableIRQ
static status_t EnableIRQ(IRQn_Type interrupt)
Enable specific interrupt.
Definition: fsl_common.h:484
SDK_MEM_MAGIC_NUMBER
#define SDK_MEM_MAGIC_NUMBER
Definition: fsl_common.c:10
_mem_align_control_block::offset
uint16_t offset
Definition: fsl_common.c:15
__ASM
#define __ASM
Definition: imxrt1050/imxrt1050-evkb/CMSIS/cmsis_armcc.h:57
EnableGlobalIRQ
static void EnableGlobalIRQ(uint32_t primask)
Enable the global IRQ.
Definition: fsl_common.h:583


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:13:56