ADuCM4x50 Device Drivers API Reference Manual  Release 4.0.0.0
system_ADuCM4050.c
1 
13 /* Copyright (c) 2012 ARM LIMITED
14 
15  All rights reserved.
16  Redistribution and use in source and binary forms, with or without
17  modification, are permitted provided that the following conditions are met:
18  - Redistributions of source code must retain the above copyright
19  notice, this list of conditions and the following disclaimer.
20  - Redistributions in binary form must reproduce the above copyright
21  notice, this list of conditions and the following disclaimer in the
22  documentation and/or other materials provided with the distribution.
23  - Neither the name of ARM nor the names of its contributors may be used
24  to endorse or promote products derived from this software without
25  specific prior written permission.
26  *
27  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
31  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  POSSIBILITY OF SUCH DAMAGE.
38 
39  Portions Copyright (c) 2018 Analog Devices, Inc.
40  ---------------------------------------------------------------------------*/
41 
46 #include <stdint.h>
47 #include "system_ADuCM4050.h"
48 #include <adi_callback.h>
49 #include <adi_processor.h>
50 #include <rtos_map/adi_rtos_map.h>
51 
52 #ifdef __ICCARM__
53 /*
54 * IAR MISRA C 2004 error suppressions.
55 *
56 * Pm073 (rule 14.7): a function should have a single point of exit.
57 * Pm143 (rule 14.7): a function should have a single point of exit at the end of the function.
58 * Multiple returns are used for error handling.
59 *
60 * Pm140 (rule 11.3): a cast should not be performed between a pointer type and an integral type
61 * The rule makes an exception for memory-mapped register accesses.
62 */
63 #pragma diag_suppress=Pm073,Pm143,Pm140
64 #endif /* __ICCARM__ */
65 
68 /*----------------------------------------------------------------------------
69  DEFINES
70  *----------------------------------------------------------------------------*/
71 
72 /* To enable the cache. Please note that linker description file need to
73  have appropriate memory mapping. */
74 /* #define ENABLE_CACHE */
75 
76 #ifdef ADI_DEBUG
77 
79 uint32_t lfClock = 0u;
80 #endif
81 
83 uint32_t hfClock = 0u;
84 
86 uint32_t gpioClock = 0u;
87 extern void* __Vectors[];
88 
89 /*----------------------------------------------------------------------------
90  Security options
91  *----------------------------------------------------------------------------*/
92 
93 #if defined (__CC_ARM)
94  __attribute__ ((at(0x00000180u)))
95  __attribute__ ((weak))
96 #elif defined (__GNUC__)
97  __attribute__ ((used,section(".security_options")))
98  __attribute__ ((weak))
99 #elif defined (__ICCARM__)
100  #pragma location=".security_options"
101  __root
102  __weak
103 #endif /* __ICCARM__ */
104 const ADI_ADUCM4X50_SECURITY_OPTIONS adi_aducm4x50_security_options
105  = {
106  { 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu },
107  0xA79C3203u,
108 #if defined (__ICCARM__)
109  0u,
110 #else
111  253u,
112 #endif /* __ICCARM__ */
113  0xFFFFFFFFu,
114  0xFFFFFFFFu,
115 };
116 
120 /*----------------------------------------------------------------------------
121  Clock Variable definitions
122  *----------------------------------------------------------------------------*/
123 
125 uint32_t SystemCoreClock = 0u;
126 
127 /*----------------------------------------------------------------------------
128  Clock functions
129  *----------------------------------------------------------------------------*/
130 
140 {
141  uint32_t val, nDivisor, nMulfactor, div2, mul2;
142 
143 #ifdef ADI_DEBUG
144  /* "lfclock" is only used during debug checks... */
145  /* LF clock is always 32k, whether osc or xtal */
146  lfClock = __LFCLK; /* for beep, wdt and lcd */
147  if (lfClock == 0u)
148  {
149  while (1) {}
150  }
151 #endif
152  /* Update Core Clock sources */
153  /* update the HF clock */
154  switch (pADI_CLKG0_CLK->CTL0 & BITM_CLKG_CLK_CTL0_CLKMUX ) {
155 
156  case HFMUX_INTERNAL_OSC_VAL:
157  hfClock = __HFOSC;
158  break;
159 
160  case HFMUX_EXTERNAL_XTAL_VAL:
161  hfClock = __HFXTAL;
162  break;
163 
164  case HFMUX_SYSTEM_SPLL_VAL:
165  /* Calculate System PLL output frequency */
166  if ((pADI_CLKG0_CLK->CTL0 & BITM_CLKG_CLK_CTL0_PLL_IPSEL) != 0u) {
167  /* PLL input from HFXTAL */
168  val = __HFXTAL;
169  } else {
170  /* PLL input from HFOSC */
171  val = __HFOSC;
172  }
173 
174  /* PLL NSEL multiplier */
175  nMulfactor = (pADI_CLKG0_CLK->CTL3 & BITM_CLKG_CLK_CTL3_SPLLNSEL) >> BITP_CLKG_CLK_CTL3_SPLLNSEL;
176  /* PLL MSEL divider */
177  nDivisor = (pADI_CLKG0_CLK->CTL3 & BITM_CLKG_CLK_CTL3_SPLLMSEL) >> BITP_CLKG_CLK_CTL3_SPLLMSEL;
178 
179  /* PLL NSEL multiplier */
180  mul2 = (pADI_CLKG0_CLK->CTL3 & BITM_CLKG_CLK_CTL3_SPLLMUL2) >> BITP_CLKG_CLK_CTL3_SPLLMUL2;
181  /* PLL MSEL divider */
182  div2 = (pADI_CLKG0_CLK->CTL3 & BITM_CLKG_CLK_CTL3_SPLLDIV2) >> BITP_CLKG_CLK_CTL3_SPLLDIV2;
183 
184  val = ((val << mul2) * nMulfactor / nDivisor) >> div2;
185 
186  hfClock = val;
187  break;
188 
189  case HFMUX_GPIO_VAL:
190  hfClock = gpioClock;
191  break;
192 
193  default:
194  return;
195  } /* end switch */
196 
197  SystemCoreClock = hfClock;
198  }
199 
200 #ifdef __ARMCC_VERSION
201 /* We want a warning if semi-hosting libraries are used. */
202 #pragma import(__use_no_semihosting_swi)
203 #endif
204 
205 #ifdef RELOCATE_IVT
206 
218 #define ADI_NUM_EXCEPTIONS 16
219 #define LENGTHOF_IVT (NVIC_INTS + ADI_NUM_EXCEPTIONS)
220 #define RELOCATION_ADDRESS (0x20000000)
221 
222 /* Relocatable vector table is only supported in IAR */
223 #if defined (__ICCARM__)
224 /* reserve no-init aligned IVT space at top of RAM */
225 SECTION_PLACE(KEEP_VAR(__no_init uint32_t __relocated_vector_table[LENGTHOF_IVT]), RELOCATION_ADDRESS);
226 #else
227 #warning "Relocated Interupt Vector Tables are not supported in this toolchain"
228 #endif
229 #endif
230 
238 void SystemInit (void)
239 {
240  uint32_t IntStatus;
241 
242 #if defined(ADI_FLCC_ENABLE_BUS_ERR) && (ADI_FLCC_ENABLE_BUS_ERR != 0)
243  /* Bus error on CRC error */
244  *pREG_FLCC0_IEN |= ENUM_FLCC_IEN_BUS_ERR_ERR;
245 #endif
246 
247  /* On reset, there is no SRAM retention. Any retention has to be explicitly
248  * set here. */
253  ADI_SRAM_BANK_6 |
254  ADI_SRAM_BANK_7 , true);
255 
256 
257 
258 /* To enable the instruction cache. */
259 #ifdef ENABLE_CACHE
261 #endif
262 
263 #if defined(ADI_SRAM_PARITY_ENABLE) && (ADI_SRAM_PARITY_ENABLE != 0)
264  /* Enable SRAM parity */
265  pADI_PMG0_TST->SRAM_CTL |= (BITM_PMG_TST_SRAM_CTL_PENBNK0 |
266  BITM_PMG_TST_SRAM_CTL_PENBNK1 |
267  BITM_PMG_TST_SRAM_CTL_PENBNK2 |
268  BITM_PMG_TST_SRAM_CTL_PENBNK3 |
269  BITM_PMG_TST_SRAM_CTL_PENBNK4 |
270  BITM_PMG_TST_SRAM_CTL_PENBNK5 |
271  BITM_PMG_TST_SRAM_CTL_PENBNK6 |
272  BITM_PMG_TST_SRAM_CTL_PENBNK7);
273 #endif
274 
275  /* Switch the Interrupt Vector Table Offset Register
276  * (VTOR) to point to the relocated IVT in SRAM.
277  */
278 
279  /* Because SystemInit must not use global variables, the following
280  * interrupt disabling code should not be replaced with critical region
281  * code which uses global variables.
282  */
283  IntStatus = __get_PRIMASK();
284  __disable_irq();
285 #ifdef RELOCATE_IVT
286  /* Copy the IVT (avoid use of memcpy here so it does not become locked into flash). */
287  size_t i;
288  for (i = 0u; i < LENGTHOF_IVT; i++)
289  {
290  __relocated_vector_table[i] = (uint32_t )__Vectors[i];
291  }
292  SCB->VTOR = (uint32_t) &__relocated_vector_table;
293 #else
294  /* Set the vector table address */
295  SCB->VTOR = (uint32_t) &__Vectors;
296 #endif /* RELOCATE_IVT */
297 
298  /* Set all three (USGFAULTENA, BUSFAULTENA, and MEMFAULTENA) fault enable bits
299  * in the System Control Block, System Handler Control and State Register
300  * otherwise these faults are handled as hard faults.
301  */
302  SCB->SHCSR = SCB_SHCSR_USGFAULTENA_Msk |
303  SCB_SHCSR_BUSFAULTENA_Msk |
304  SCB_SHCSR_MEMFAULTENA_Msk ;
305 
306 #ifdef DEBUG
307  /* Trap divide by zero and generate a fault in debug builds. */
308  SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk;
309 #endif
310 
311 #if (__FPU_PRESENT == 1u) && (__FPU_USED == 1u)
312  /* the FPU is disabled by default so enable FPU (NEON and VFP)
313  * set the System Control Block, Coprocessor Access Control Register bits:
314  * CP10 = grant CP10 coprocessor privileges and user mode access (full access)
315  * CP11 = grant CP11 coprocessor privileged and user mode access (full access)
316  * (CP10 and CP11 MUST be the same or "BEHAVIOR IS UNPREDICTABLE")
317  */
318  SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 for Full Access */
319 #endif
320 
321  /* Flush instruction and data pipelines to insure assertion of new settings. */
322  __ISB();
323  __DSB();
324 
325  __set_PRIMASK(IntStatus);
326 
327 #ifdef ADI_MAX_IRQ_PRIORITY
329 #endif
330 }
331 
332 
340 void adi_system_EnableCache(bool bEnable)
341 {
342  pADI_FLCC0_CACHE->KEY = CACHE_CONTROLLER_KEY;
343  if( bEnable == true )
344  {
345  pADI_FLCC0_CACHE->SETUP |= BITM_FLCC_CACHE_SETUP_ICEN;
346  }
347  else
348  {
349  pADI_FLCC0_CACHE->SETUP &= ~BITM_FLCC_CACHE_SETUP_ICEN;
350  }
351 }
352 
353 
374 {
375  uint32_t retainBits = 0u;
376 
377 #ifdef ADI_DEBUG
378  if((0u != (eBank & ADI_SRAM_BANK_0)) ||
379  (0u != (eBank & ADI_SRAM_BANK_2))) {
380  /* Banks 0 and 2 are not selectable */
381  return ADI_SYS_FAILURE;
382  }
383 
384  /* Are banks 3 or 4 selected? */
385  if(0u != (eBank & (ADI_SRAM_BANK_3 | ADI_SRAM_BANK_4))) {
386  /* If so, the only valid option is for both to be retained. */
388  return ADI_SYS_FAILURE;
389  }
390  }
391 
392  /* Are banks 6 or 7 selected? */
393  if(0u != (eBank & (ADI_SRAM_BANK_6 | ADI_SRAM_BANK_7))) {
394  /* If so, the only valid option is for both to be retained */
396  return ADI_SYS_FAILURE;
397  }
398  }
399 #endif
400  if((eBank & ADI_SRAM_BANK_1) != 0u) {
401  retainBits |= BITM_PMG_SRAMRET_RET1;
402  }
403  if((eBank & (ADI_SRAM_BANK_3 | ADI_SRAM_BANK_4)) != 0u) {
404  retainBits |= BITM_PMG_SRAMRET_RET2;
405  }
406  if((eBank & ADI_SRAM_BANK_5) != 0u) {
407  retainBits |= BITM_PMG_SRAMRET_RET3;
408  }
409  if((eBank & (ADI_SRAM_BANK_6 | ADI_SRAM_BANK_7)) != 0u) {
410  retainBits |= BITM_PMG_SRAMRET_RET4;
411  }
412 
413  /* Unlock the SRAMRET register using the PWRKEY.
414  * If there is any chance that this sequence can be interrupted then it
415  * should be protected by disabling interrupts. A write to any other
416  * register on the APB bus before writing to PMG_SRAMRET will return the
417  * protection to the lock state. */
418  pADI_PMG0->PWRKEY = PWRKEY_VALUE_KEY;
419  if(bEnable) {
420  pADI_PMG0->SRAMRET |= retainBits;
421  }
422  else {
423  pADI_PMG0->SRAMRET &= ~(retainBits);
424  }
425 
426  return ADI_SYS_SUCCESS;
427 }
428 
429 
444 {
445 #ifdef ADI_MAX_IRQ_PRIORITY
446  uint32_t prio = (uint32_t)ADI_MAX_IRQ_PRIORITY;
447 #else
448  uint32_t prio = (uint32_t)0u;
449 #endif
450 
451  /* NVIC supports up to 240 interrupt sources, but this part does not
452  * use the full range. */
453  for(uint8_t irq = 0u; irq < NVIC_INTS; irq++) {
454  NVIC_SetPriority((IRQn_Type)irq, prio);
455  }
456 }
457 
void SystemInit(void)
Sets up the microcontroller system. Initializes the System and updates the relocate vector table.
void SystemCoreClockUpdate(void)
Update the clock.
void adi_system_EnableCache(bool bEnable)
Enables or disables the cache.
uint32_t SystemCoreClock
#define ADI_SRAM_BANK_2
#define ADI_SRAM_BANK_5
#define ADI_SRAM_BANK_6
#define ADI_SRAM_BANK_4
void adi_system_SetGlobalIrqPriority(void)
This function sets the priority for all IRQ interrupts to the value defined by ADI_MAX_IRQ_PRIORITY (...
#define ADI_SRAM_BANK_0
#define ADI_SRAM_BANK_3
#define ADI_SRAM_BANK_7
ADI_SYS_RESULT
ADI_SYS_RESULT adi_system_EnableRetention(ADI_SRAM_BANK eBank, bool bEnable)
This enables/disable SRAM retention during the hibernation.
#define ADI_SRAM_BANK_1
uint32_t ADI_SRAM_BANK