Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: FRDM-KL46Z_LCD_Test FRDM-KL46Z_LCD_Test FRDM-KL46Z_Plantilla FRDM-KL46Z_Plantilla ... more
targets/cmsis/TARGET_NXP/TARGET_LPC43XX/system_LPC43xx.c@0:6bc4ac881c8e, 2016-07-28 (annotated)
- Committer:
- ebrus
- Date:
- Thu Jul 28 15:56:34 2016 +0000
- Revision:
- 0:6bc4ac881c8e
1;
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| ebrus | 0:6bc4ac881c8e | 1 | /* |
| ebrus | 0:6bc4ac881c8e | 2 | * @brief LPC43xx System Initialization |
| ebrus | 0:6bc4ac881c8e | 3 | * |
| ebrus | 0:6bc4ac881c8e | 4 | * @note |
| ebrus | 0:6bc4ac881c8e | 5 | * Copyright(C) NXP Semiconductors, 2012 |
| ebrus | 0:6bc4ac881c8e | 6 | * All rights reserved. |
| ebrus | 0:6bc4ac881c8e | 7 | * |
| ebrus | 0:6bc4ac881c8e | 8 | * @par |
| ebrus | 0:6bc4ac881c8e | 9 | * Software that is described herein is for illustrative purposes only |
| ebrus | 0:6bc4ac881c8e | 10 | * which provides customers with programming information regarding the |
| ebrus | 0:6bc4ac881c8e | 11 | * LPC products. This software is supplied "AS IS" without any warranties of |
| ebrus | 0:6bc4ac881c8e | 12 | * any kind, and NXP Semiconductors and its licensor disclaim any and |
| ebrus | 0:6bc4ac881c8e | 13 | * all warranties, express or implied, including all implied warranties of |
| ebrus | 0:6bc4ac881c8e | 14 | * merchantability, fitness for a particular purpose and non-infringement of |
| ebrus | 0:6bc4ac881c8e | 15 | * intellectual property rights. NXP Semiconductors assumes no responsibility |
| ebrus | 0:6bc4ac881c8e | 16 | * or liability for the use of the software, conveys no license or rights under any |
| ebrus | 0:6bc4ac881c8e | 17 | * patent, copyright, mask work right, or any other intellectual property rights in |
| ebrus | 0:6bc4ac881c8e | 18 | * or to any products. NXP Semiconductors reserves the right to make changes |
| ebrus | 0:6bc4ac881c8e | 19 | * in the software without notification. NXP Semiconductors also makes no |
| ebrus | 0:6bc4ac881c8e | 20 | * representation or warranty that such application will be suitable for the |
| ebrus | 0:6bc4ac881c8e | 21 | * specified use without further testing or modification. |
| ebrus | 0:6bc4ac881c8e | 22 | * |
| ebrus | 0:6bc4ac881c8e | 23 | * @par |
| ebrus | 0:6bc4ac881c8e | 24 | * Permission to use, copy, modify, and distribute this software and its |
| ebrus | 0:6bc4ac881c8e | 25 | * documentation is hereby granted, under NXP Semiconductors' and its |
| ebrus | 0:6bc4ac881c8e | 26 | * licensor's relevant copyrights in the software, without fee, provided that it |
| ebrus | 0:6bc4ac881c8e | 27 | * is used in conjunction with NXP Semiconductors microcontrollers. This |
| ebrus | 0:6bc4ac881c8e | 28 | * copyright, permission, and disclaimer notice must appear in all copies of |
| ebrus | 0:6bc4ac881c8e | 29 | * this code. |
| ebrus | 0:6bc4ac881c8e | 30 | * |
| ebrus | 0:6bc4ac881c8e | 31 | * Modified by Micromint USA <support@micromint.com> |
| ebrus | 0:6bc4ac881c8e | 32 | */ |
| ebrus | 0:6bc4ac881c8e | 33 | #include "LPC43xx.h" |
| ebrus | 0:6bc4ac881c8e | 34 | |
| ebrus | 0:6bc4ac881c8e | 35 | #define COUNT_OF(a) (sizeof(a)/sizeof(a[0])) |
| ebrus | 0:6bc4ac881c8e | 36 | |
| ebrus | 0:6bc4ac881c8e | 37 | /* Clock variables */ |
| ebrus | 0:6bc4ac881c8e | 38 | #if (CLOCK_SETUP) |
| ebrus | 0:6bc4ac881c8e | 39 | uint32_t SystemCoreClock = MAX_CLOCK_FREQ; |
| ebrus | 0:6bc4ac881c8e | 40 | #else |
| ebrus | 0:6bc4ac881c8e | 41 | uint32_t SystemCoreClock = CRYSTAL_MAIN_FREQ_IN; |
| ebrus | 0:6bc4ac881c8e | 42 | #endif |
| ebrus | 0:6bc4ac881c8e | 43 | |
| ebrus | 0:6bc4ac881c8e | 44 | #if !defined(CORE_M0) |
| ebrus | 0:6bc4ac881c8e | 45 | /* SCU pin definitions for pin muxing */ |
| ebrus | 0:6bc4ac881c8e | 46 | typedef struct { |
| ebrus | 0:6bc4ac881c8e | 47 | __IO uint32_t *reg; /* SCU register address */ |
| ebrus | 0:6bc4ac881c8e | 48 | uint16_t mode; /* SCU pin mode and function */ |
| ebrus | 0:6bc4ac881c8e | 49 | } PINMUX_GRP_T; |
| ebrus | 0:6bc4ac881c8e | 50 | |
| ebrus | 0:6bc4ac881c8e | 51 | /* Pins to initialize before clocks are configured */ |
| ebrus | 0:6bc4ac881c8e | 52 | static const PINMUX_GRP_T pre_clock_mux[] = { |
| ebrus | 0:6bc4ac881c8e | 53 | /* SPIFI pins */ |
| ebrus | 0:6bc4ac881c8e | 54 | {SCU_REG(0x3, 3), (SCU_PINIO_FAST | 0x3)}, /* P3_3 SPIFI CLK */ |
| ebrus | 0:6bc4ac881c8e | 55 | {SCU_REG(0x3, 4), (SCU_PINIO_FAST | 0x3)}, /* P3_4 SPIFI D3 */ |
| ebrus | 0:6bc4ac881c8e | 56 | {SCU_REG(0x3, 5), (SCU_PINIO_FAST | 0x3)}, /* P3_5 SPIFI D2 */ |
| ebrus | 0:6bc4ac881c8e | 57 | {SCU_REG(0x3, 6), (SCU_PINIO_FAST | 0x3)}, /* P3_6 SPIFI D1 */ |
| ebrus | 0:6bc4ac881c8e | 58 | {SCU_REG(0x3, 7), (SCU_PINIO_FAST | 0x3)}, /* P3_7 SPIFI D0 */ |
| ebrus | 0:6bc4ac881c8e | 59 | {SCU_REG(0x3, 8), (SCU_PINIO_FAST | 0x3)} /* P3_8 SPIFI CS/SSEL */ |
| ebrus | 0:6bc4ac881c8e | 60 | }; |
| ebrus | 0:6bc4ac881c8e | 61 | |
| ebrus | 0:6bc4ac881c8e | 62 | /* Pins to initialize after clocks are configured */ |
| ebrus | 0:6bc4ac881c8e | 63 | static const PINMUX_GRP_T post_clock_mux[] = { |
| ebrus | 0:6bc4ac881c8e | 64 | /* Boot pins */ |
| ebrus | 0:6bc4ac881c8e | 65 | {SCU_REG(0x1, 1), (SCU_PINIO_FAST | 0x0)}, /* P1_1 BOOT0 */ |
| ebrus | 0:6bc4ac881c8e | 66 | {SCU_REG(0x1, 2), (SCU_PINIO_FAST | 0x0)}, /* P1_2 BOOT1 */ |
| ebrus | 0:6bc4ac881c8e | 67 | {SCU_REG(0x2, 8), (SCU_PINIO_FAST | 0x0)}, /* P2_8 BOOT2 */ |
| ebrus | 0:6bc4ac881c8e | 68 | {SCU_REG(0x2, 9), (SCU_PINIO_FAST | 0x0)}, /* P2_9 BOOT3 */ |
| ebrus | 0:6bc4ac881c8e | 69 | /* Micromint Bambino 200/210 */ |
| ebrus | 0:6bc4ac881c8e | 70 | {SCU_REG(0x6, 11), (SCU_PINIO_FAST | 0x0)}, /* P6_11 LED1 */ |
| ebrus | 0:6bc4ac881c8e | 71 | {SCU_REG(0x2, 5), (SCU_PINIO_FAST | 0x0)}, /* P2_5 LED2 */ |
| ebrus | 0:6bc4ac881c8e | 72 | {SCU_REG(0x2, 7), (SCU_PINIO_FAST | 0x0)}, /* P2_7 BTN1 */ |
| ebrus | 0:6bc4ac881c8e | 73 | /* Micromint Bambino 210 */ |
| ebrus | 0:6bc4ac881c8e | 74 | {SCU_REG(0x6, 1), (SCU_PINIO_FAST | 0x0)}, /* P6_1 LED3 */ |
| ebrus | 0:6bc4ac881c8e | 75 | {SCU_REG(0x6, 2), (SCU_PINIO_FAST | 0x0)}, /* P6_2 LED4 */ |
| ebrus | 0:6bc4ac881c8e | 76 | }; |
| ebrus | 0:6bc4ac881c8e | 77 | |
| ebrus | 0:6bc4ac881c8e | 78 | #if (CLOCK_SETUP) |
| ebrus | 0:6bc4ac881c8e | 79 | /* Structure for initial base clock states */ |
| ebrus | 0:6bc4ac881c8e | 80 | struct CLK_BASE_STATES { |
| ebrus | 0:6bc4ac881c8e | 81 | CGU_BASE_CLK_T clk; /* Base clock */ |
| ebrus | 0:6bc4ac881c8e | 82 | CGU_CLKIN_T clkin; /* Base clock source */ |
| ebrus | 0:6bc4ac881c8e | 83 | uint8_t powerdn; /* Set to 1 if base clock is initially powered down */ |
| ebrus | 0:6bc4ac881c8e | 84 | }; |
| ebrus | 0:6bc4ac881c8e | 85 | |
| ebrus | 0:6bc4ac881c8e | 86 | /* Initial base clock states are mostly on */ |
| ebrus | 0:6bc4ac881c8e | 87 | static const struct CLK_BASE_STATES clock_states[] = { |
| ebrus | 0:6bc4ac881c8e | 88 | {CLK_BASE_SAFE, CLKIN_IRC, 0}, |
| ebrus | 0:6bc4ac881c8e | 89 | {CLK_BASE_APB1, CLKIN_MAINPLL, 0}, |
| ebrus | 0:6bc4ac881c8e | 90 | {CLK_BASE_APB3, CLKIN_MAINPLL, 0}, |
| ebrus | 0:6bc4ac881c8e | 91 | {CLK_BASE_USB0, CLKIN_USBPLL, 1}, |
| ebrus | 0:6bc4ac881c8e | 92 | {CLK_BASE_PERIPH, CLKIN_MAINPLL, 0}, |
| ebrus | 0:6bc4ac881c8e | 93 | {CLK_BASE_SPI, CLKIN_MAINPLL, 0}, |
| ebrus | 0:6bc4ac881c8e | 94 | {CLK_BASE_PHY_TX, CLKIN_ENET_TX, 0}, |
| ebrus | 0:6bc4ac881c8e | 95 | #if defined(USE_RMII) |
| ebrus | 0:6bc4ac881c8e | 96 | {CLK_BASE_PHY_RX, CLKIN_ENET_TX, 0}, |
| ebrus | 0:6bc4ac881c8e | 97 | #else |
| ebrus | 0:6bc4ac881c8e | 98 | {CLK_BASE_PHY_RX, CLKIN_ENET_RX, 0}, |
| ebrus | 0:6bc4ac881c8e | 99 | #endif |
| ebrus | 0:6bc4ac881c8e | 100 | {CLK_BASE_SDIO, CLKIN_MAINPLL, 0}, |
| ebrus | 0:6bc4ac881c8e | 101 | {CLK_BASE_SSP0, CLKIN_IDIVC, 0}, |
| ebrus | 0:6bc4ac881c8e | 102 | {CLK_BASE_SSP1, CLKIN_IDIVC, 0}, |
| ebrus | 0:6bc4ac881c8e | 103 | {CLK_BASE_UART0, CLKIN_MAINPLL, 0}, |
| ebrus | 0:6bc4ac881c8e | 104 | {CLK_BASE_UART1, CLKIN_MAINPLL, 0}, |
| ebrus | 0:6bc4ac881c8e | 105 | {CLK_BASE_UART2, CLKIN_MAINPLL, 0}, |
| ebrus | 0:6bc4ac881c8e | 106 | {CLK_BASE_UART3, CLKIN_MAINPLL, 0}, |
| ebrus | 0:6bc4ac881c8e | 107 | {CLK_BASE_OUT, CLKINPUT_PD, 0}, |
| ebrus | 0:6bc4ac881c8e | 108 | {CLK_BASE_APLL, CLKINPUT_PD, 0}, |
| ebrus | 0:6bc4ac881c8e | 109 | {CLK_BASE_CGU_OUT0, CLKINPUT_PD, 0}, |
| ebrus | 0:6bc4ac881c8e | 110 | {CLK_BASE_CGU_OUT1, CLKINPUT_PD, 0}, |
| ebrus | 0:6bc4ac881c8e | 111 | |
| ebrus | 0:6bc4ac881c8e | 112 | /* Clocks derived from dividers */ |
| ebrus | 0:6bc4ac881c8e | 113 | {CLK_BASE_LCD, CLKIN_IDIVC, 0}, |
| ebrus | 0:6bc4ac881c8e | 114 | {CLK_BASE_USB1, CLKIN_IDIVD, 1} |
| ebrus | 0:6bc4ac881c8e | 115 | }; |
| ebrus | 0:6bc4ac881c8e | 116 | #endif /* defined(CLOCK_SETUP) */ |
| ebrus | 0:6bc4ac881c8e | 117 | |
| ebrus | 0:6bc4ac881c8e | 118 | /* Local functions */ |
| ebrus | 0:6bc4ac881c8e | 119 | static uint32_t SystemGetMainPLLHz(void); |
| ebrus | 0:6bc4ac881c8e | 120 | static void SystemSetupClock(void); |
| ebrus | 0:6bc4ac881c8e | 121 | static void SystemSetupPins(const PINMUX_GRP_T *mux, uint32_t n); |
| ebrus | 0:6bc4ac881c8e | 122 | static void SystemSetupMemory(void); |
| ebrus | 0:6bc4ac881c8e | 123 | static void WaitUs(uint32_t us); |
| ebrus | 0:6bc4ac881c8e | 124 | |
| ebrus | 0:6bc4ac881c8e | 125 | #endif /* !defined(CORE_M0) */ |
| ebrus | 0:6bc4ac881c8e | 126 | |
| ebrus | 0:6bc4ac881c8e | 127 | /* |
| ebrus | 0:6bc4ac881c8e | 128 | * SystemInit() - Initialize the system |
| ebrus | 0:6bc4ac881c8e | 129 | */ |
| ebrus | 0:6bc4ac881c8e | 130 | void SystemInit(void) |
| ebrus | 0:6bc4ac881c8e | 131 | { |
| ebrus | 0:6bc4ac881c8e | 132 | #if !defined(CORE_M0) |
| ebrus | 0:6bc4ac881c8e | 133 | |
| ebrus | 0:6bc4ac881c8e | 134 | /* Initialize vector table in flash */ |
| ebrus | 0:6bc4ac881c8e | 135 | #if defined(__ARMCC_VERSION) |
| ebrus | 0:6bc4ac881c8e | 136 | extern void *__Vectors; |
| ebrus | 0:6bc4ac881c8e | 137 | |
| ebrus | 0:6bc4ac881c8e | 138 | SCB->VTOR = (unsigned int) &__Vectors; |
| ebrus | 0:6bc4ac881c8e | 139 | #elif defined(__IAR_SYSTEMS_ICC__) |
| ebrus | 0:6bc4ac881c8e | 140 | extern void *__vector_table; |
| ebrus | 0:6bc4ac881c8e | 141 | |
| ebrus | 0:6bc4ac881c8e | 142 | SCB->VTOR = (unsigned int) &__vector_table; |
| ebrus | 0:6bc4ac881c8e | 143 | #elif defined(TOOLCHAIN_GCC_ARM) |
| ebrus | 0:6bc4ac881c8e | 144 | extern void *__isr_vector; |
| ebrus | 0:6bc4ac881c8e | 145 | |
| ebrus | 0:6bc4ac881c8e | 146 | SCB->VTOR = (unsigned int) &__isr_vector; |
| ebrus | 0:6bc4ac881c8e | 147 | #else /* defined(__GNUC__) and others */ |
| ebrus | 0:6bc4ac881c8e | 148 | extern void *g_pfnVectors; |
| ebrus | 0:6bc4ac881c8e | 149 | |
| ebrus | 0:6bc4ac881c8e | 150 | SCB->VTOR = (unsigned int) &g_pfnVectors; |
| ebrus | 0:6bc4ac881c8e | 151 | #endif |
| ebrus | 0:6bc4ac881c8e | 152 | |
| ebrus | 0:6bc4ac881c8e | 153 | #if !defined(TOOLCHAIN_GCC) |
| ebrus | 0:6bc4ac881c8e | 154 | #if defined(__FPU_PRESENT) && __FPU_PRESENT == 1 |
| ebrus | 0:6bc4ac881c8e | 155 | /* Initialize floating point */ |
| ebrus | 0:6bc4ac881c8e | 156 | fpuInit(); |
| ebrus | 0:6bc4ac881c8e | 157 | #endif |
| ebrus | 0:6bc4ac881c8e | 158 | #endif |
| ebrus | 0:6bc4ac881c8e | 159 | |
| ebrus | 0:6bc4ac881c8e | 160 | SystemSetupPins(pre_clock_mux, COUNT_OF(pre_clock_mux)); /* Configure pins */ |
| ebrus | 0:6bc4ac881c8e | 161 | SystemSetupClock(); /* Configure processor and peripheral clocks */ |
| ebrus | 0:6bc4ac881c8e | 162 | SystemSetupPins(post_clock_mux, COUNT_OF(post_clock_mux)); /* Configure pins */ |
| ebrus | 0:6bc4ac881c8e | 163 | SystemSetupMemory(); /* Configure external memory */ |
| ebrus | 0:6bc4ac881c8e | 164 | #endif /* !defined(CORE_M0) */ |
| ebrus | 0:6bc4ac881c8e | 165 | |
| ebrus | 0:6bc4ac881c8e | 166 | SystemCoreClockUpdate(); /* Update SystemCoreClock variable */ |
| ebrus | 0:6bc4ac881c8e | 167 | } |
| ebrus | 0:6bc4ac881c8e | 168 | |
| ebrus | 0:6bc4ac881c8e | 169 | /* |
| ebrus | 0:6bc4ac881c8e | 170 | * SystemCoreClockUpdate() - Update SystemCoreClock variable |
| ebrus | 0:6bc4ac881c8e | 171 | */ |
| ebrus | 0:6bc4ac881c8e | 172 | void SystemCoreClockUpdate(void) |
| ebrus | 0:6bc4ac881c8e | 173 | { |
| ebrus | 0:6bc4ac881c8e | 174 | uint32_t reg, div, rate; |
| ebrus | 0:6bc4ac881c8e | 175 | |
| ebrus | 0:6bc4ac881c8e | 176 | /* Get main PLL rate */ |
| ebrus | 0:6bc4ac881c8e | 177 | rate = SystemGetMainPLLHz(); |
| ebrus | 0:6bc4ac881c8e | 178 | |
| ebrus | 0:6bc4ac881c8e | 179 | /* Get clock divider */ |
| ebrus | 0:6bc4ac881c8e | 180 | reg = LPC_CCU1->CLKCCU[CLK_MX_MXCORE].CFG; |
| ebrus | 0:6bc4ac881c8e | 181 | if (((reg >> 5) & 0x7) == 0) { |
| ebrus | 0:6bc4ac881c8e | 182 | div = 1; |
| ebrus | 0:6bc4ac881c8e | 183 | } |
| ebrus | 0:6bc4ac881c8e | 184 | else { |
| ebrus | 0:6bc4ac881c8e | 185 | div = 2; |
| ebrus | 0:6bc4ac881c8e | 186 | } |
| ebrus | 0:6bc4ac881c8e | 187 | rate = rate / div; |
| ebrus | 0:6bc4ac881c8e | 188 | |
| ebrus | 0:6bc4ac881c8e | 189 | SystemCoreClock = rate; |
| ebrus | 0:6bc4ac881c8e | 190 | } |
| ebrus | 0:6bc4ac881c8e | 191 | |
| ebrus | 0:6bc4ac881c8e | 192 | /* Returns the frequency of the main PLL */ |
| ebrus | 0:6bc4ac881c8e | 193 | uint32_t SystemGetMainPLLHz(void) |
| ebrus | 0:6bc4ac881c8e | 194 | { |
| ebrus | 0:6bc4ac881c8e | 195 | uint32_t PLLReg = LPC_CGU->PLL1_CTRL; |
| ebrus | 0:6bc4ac881c8e | 196 | uint32_t freq = CRYSTAL_MAIN_FREQ_IN; |
| ebrus | 0:6bc4ac881c8e | 197 | uint32_t msel, nsel, psel, direct, fbsel; |
| ebrus | 0:6bc4ac881c8e | 198 | uint32_t m, n, p; |
| ebrus | 0:6bc4ac881c8e | 199 | const uint8_t ptab[] = {1, 2, 4, 8}; |
| ebrus | 0:6bc4ac881c8e | 200 | |
| ebrus | 0:6bc4ac881c8e | 201 | msel = (PLLReg >> 16) & 0xFF; |
| ebrus | 0:6bc4ac881c8e | 202 | nsel = (PLLReg >> 12) & 0x3; |
| ebrus | 0:6bc4ac881c8e | 203 | psel = (PLLReg >> 8) & 0x3; |
| ebrus | 0:6bc4ac881c8e | 204 | direct = (PLLReg >> 7) & 0x1; |
| ebrus | 0:6bc4ac881c8e | 205 | fbsel = (PLLReg >> 6) & 0x1; |
| ebrus | 0:6bc4ac881c8e | 206 | |
| ebrus | 0:6bc4ac881c8e | 207 | m = msel + 1; |
| ebrus | 0:6bc4ac881c8e | 208 | n = nsel + 1; |
| ebrus | 0:6bc4ac881c8e | 209 | p = ptab[psel]; |
| ebrus | 0:6bc4ac881c8e | 210 | |
| ebrus | 0:6bc4ac881c8e | 211 | if (direct || fbsel) { |
| ebrus | 0:6bc4ac881c8e | 212 | return m * (freq / n); |
| ebrus | 0:6bc4ac881c8e | 213 | } |
| ebrus | 0:6bc4ac881c8e | 214 | |
| ebrus | 0:6bc4ac881c8e | 215 | return (m / (2 * p)) * (freq / n); |
| ebrus | 0:6bc4ac881c8e | 216 | } |
| ebrus | 0:6bc4ac881c8e | 217 | |
| ebrus | 0:6bc4ac881c8e | 218 | #if !defined(CORE_M0) |
| ebrus | 0:6bc4ac881c8e | 219 | /* |
| ebrus | 0:6bc4ac881c8e | 220 | * SystemSetupClock() - Set processor and peripheral clocks |
| ebrus | 0:6bc4ac881c8e | 221 | * |
| ebrus | 0:6bc4ac881c8e | 222 | * Clock Frequency Source |
| ebrus | 0:6bc4ac881c8e | 223 | * CLK_BASE_MX 204 MHz CLKIN_MAINPLL (CLKIN_PLL1) |
| ebrus | 0:6bc4ac881c8e | 224 | * CLK_BASE_SPIFI 102 MHz CLKIN_IDIVE |
| ebrus | 0:6bc4ac881c8e | 225 | * CLK_BASE_USB0 480 MHz CLKIN_USBPLL (Disabled) (CLKIN_PLL0USB) |
| ebrus | 0:6bc4ac881c8e | 226 | * CLK_BASE_USB1 60 MHz CLKIN_IDIVE (Disabled) |
| ebrus | 0:6bc4ac881c8e | 227 | * 120 MHz CLKIN_IDIVD (Disabled) |
| ebrus | 0:6bc4ac881c8e | 228 | * |
| ebrus | 0:6bc4ac881c8e | 229 | * 12 MHz CLKIN_IDIVB |
| ebrus | 0:6bc4ac881c8e | 230 | * 12 MHz CLKIN_IDIVC |
| ebrus | 0:6bc4ac881c8e | 231 | * |
| ebrus | 0:6bc4ac881c8e | 232 | */ |
| ebrus | 0:6bc4ac881c8e | 233 | void SystemSetupClock(void) |
| ebrus | 0:6bc4ac881c8e | 234 | { |
| ebrus | 0:6bc4ac881c8e | 235 | #if (CLOCK_SETUP) |
| ebrus | 0:6bc4ac881c8e | 236 | uint32_t i; |
| ebrus | 0:6bc4ac881c8e | 237 | |
| ebrus | 0:6bc4ac881c8e | 238 | /* Switch main clock to Internal RC (IRC) while setting up PLL1 */ |
| ebrus | 0:6bc4ac881c8e | 239 | LPC_CGU->BASE_CLK[CLK_BASE_MX] = (1 << 11) | (CLKIN_IRC << 24); |
| ebrus | 0:6bc4ac881c8e | 240 | /* Set prescaler/divider on SSP1 assuming 204 MHz clock */ |
| ebrus | 0:6bc4ac881c8e | 241 | LPC_SSP1->CR1 &= ~(1 << 1); |
| ebrus | 0:6bc4ac881c8e | 242 | LPC_SSP1->CPSR = 0x0002; |
| ebrus | 0:6bc4ac881c8e | 243 | LPC_SSP1->CR0 = 0x00006507; |
| ebrus | 0:6bc4ac881c8e | 244 | LPC_SSP1->CR1 |= (1 << 1); |
| ebrus | 0:6bc4ac881c8e | 245 | |
| ebrus | 0:6bc4ac881c8e | 246 | /* Enable the oscillator and wait 100 us */ |
| ebrus | 0:6bc4ac881c8e | 247 | LPC_CGU->XTAL_OSC_CTRL = 0; |
| ebrus | 0:6bc4ac881c8e | 248 | WaitUs(100); |
| ebrus | 0:6bc4ac881c8e | 249 | |
| ebrus | 0:6bc4ac881c8e | 250 | #if (SPIFI_INIT) |
| ebrus | 0:6bc4ac881c8e | 251 | /* Setup SPIFI control register and no-opcode mode */ |
| ebrus | 0:6bc4ac881c8e | 252 | LPC_SPIFI->CTRL = (0x100 << 0) | (1 << 16) | (1 << 29) | (1 << 30); |
| ebrus | 0:6bc4ac881c8e | 253 | LPC_SPIFI->IDATA = 0xA5; |
| ebrus | 0:6bc4ac881c8e | 254 | /* Switch IDIVE clock to IRC and connect to SPIFI clock */ |
| ebrus | 0:6bc4ac881c8e | 255 | LPC_CGU->IDIV_CTRL[CLK_IDIV_E] = ((1 << 11) | (CLKIN_IRC << 24)); |
| ebrus | 0:6bc4ac881c8e | 256 | LPC_CGU->BASE_CLK[CLK_BASE_SPIFI] = ((1 << 11) | (CLKIN_IDIVE << 24)); |
| ebrus | 0:6bc4ac881c8e | 257 | #endif /* SPIFI_INIT */ |
| ebrus | 0:6bc4ac881c8e | 258 | |
| ebrus | 0:6bc4ac881c8e | 259 | /* Configure PLL1 (MAINPLL) for main clock */ |
| ebrus | 0:6bc4ac881c8e | 260 | LPC_CGU->PLL1_CTRL |= 1; /* Power down PLL1 */ |
| ebrus | 0:6bc4ac881c8e | 261 | |
| ebrus | 0:6bc4ac881c8e | 262 | /* Change PLL1 to 108 Mhz (msel=9, 12 MHz*9=108 MHz) */ |
| ebrus | 0:6bc4ac881c8e | 263 | LPC_CGU->PLL1_CTRL = (1 << 7) | (0 << 8) | (1 << 11) | (0 << 12) | (8 << 16) |
| ebrus | 0:6bc4ac881c8e | 264 | | (CLKIN_MAINPLL << 24); |
| ebrus | 0:6bc4ac881c8e | 265 | while (!(LPC_CGU->PLL1_STAT & 1)); /* Wait for PLL1 to lock */ |
| ebrus | 0:6bc4ac881c8e | 266 | WaitUs(100); |
| ebrus | 0:6bc4ac881c8e | 267 | |
| ebrus | 0:6bc4ac881c8e | 268 | /* Change PLL1 to 204 Mhz (msel=17, 12 MHz*17=204 MHz) */ |
| ebrus | 0:6bc4ac881c8e | 269 | LPC_CGU->PLL1_CTRL = (1 << 7) | (0 << 8) | (1 << 11) | (0 << 12) | (16 << 16) |
| ebrus | 0:6bc4ac881c8e | 270 | | (CLKIN_MAINPLL << 24); |
| ebrus | 0:6bc4ac881c8e | 271 | while (!(LPC_CGU->PLL1_STAT & 1)); /* Wait for PLL1 to lock */ |
| ebrus | 0:6bc4ac881c8e | 272 | |
| ebrus | 0:6bc4ac881c8e | 273 | /* Connect main clock to PLL1 */ |
| ebrus | 0:6bc4ac881c8e | 274 | LPC_CGU->BASE_CLK[CLK_BASE_MX] = (1 << 11) | (CLKIN_MAINPLL << 24); |
| ebrus | 0:6bc4ac881c8e | 275 | |
| ebrus | 0:6bc4ac881c8e | 276 | /* Set USB PLL dividers for 480 MHz (for USB0) */ |
| ebrus | 0:6bc4ac881c8e | 277 | LPC_CGU->PLL[CGU_USB_PLL].PLL_MDIV = 0x06167FFA; |
| ebrus | 0:6bc4ac881c8e | 278 | LPC_CGU->PLL[CGU_USB_PLL].PLL_NP_DIV = 0x00302062; |
| ebrus | 0:6bc4ac881c8e | 279 | LPC_CGU->PLL[CGU_USB_PLL].PLL_CTRL = 0x0000081D | (CLKIN_CRYSTAL << 24); |
| ebrus | 0:6bc4ac881c8e | 280 | |
| ebrus | 0:6bc4ac881c8e | 281 | /* Set IDIVE clock to PLL1/2 = 102 MHz */ |
| ebrus | 0:6bc4ac881c8e | 282 | LPC_CGU->IDIV_CTRL[CLK_IDIV_E] = (1 << 2) | (1 << 11) | (CLKIN_MAINPLL << 24); /* PLL1/2 */ |
| ebrus | 0:6bc4ac881c8e | 283 | |
| ebrus | 0:6bc4ac881c8e | 284 | /* Set IDIVD clock to ((USBPLL/4) / 2) = 60 MHz (for USB1) */ |
| ebrus | 0:6bc4ac881c8e | 285 | LPC_CGU->IDIV_CTRL[CLK_IDIV_A] = (3 << 2) | (1 << 11) | (CLKIN_USBPLL << 24); /* USBPLL/4 */ |
| ebrus | 0:6bc4ac881c8e | 286 | LPC_CGU->IDIV_CTRL[CLK_IDIV_D] = (1 << 2) | (1 << 11) | (CLKIN_IDIVA << 24); /* IDIVA/2 */ |
| ebrus | 0:6bc4ac881c8e | 287 | |
| ebrus | 0:6bc4ac881c8e | 288 | /* Configure remaining integer dividers */ |
| ebrus | 0:6bc4ac881c8e | 289 | LPC_CGU->IDIV_CTRL[CLK_IDIV_B] = (0 << 2) | (1 << 11) | (CLKIN_IRC << 24); /* IRC */ |
| ebrus | 0:6bc4ac881c8e | 290 | LPC_CGU->IDIV_CTRL[CLK_IDIV_C] = (1 << 2) | (1 << 11) | (CLKIN_MAINPLL << 24); /* PLL1/2 */ |
| ebrus | 0:6bc4ac881c8e | 291 | |
| ebrus | 0:6bc4ac881c8e | 292 | /* Connect base clocks */ |
| ebrus | 0:6bc4ac881c8e | 293 | for (i = 0; i < COUNT_OF(clock_states); i++) { |
| ebrus | 0:6bc4ac881c8e | 294 | LPC_CGU->BASE_CLK[clock_states[i].clk] = |
| ebrus | 0:6bc4ac881c8e | 295 | ( clock_states[i].powerdn << 0) |
| ebrus | 0:6bc4ac881c8e | 296 | | (1 << 11) | (clock_states[i].clkin << 24); |
| ebrus | 0:6bc4ac881c8e | 297 | } |
| ebrus | 0:6bc4ac881c8e | 298 | #endif /* CLOCK_SETUP */ |
| ebrus | 0:6bc4ac881c8e | 299 | /* Reset peripherals */ |
| ebrus | 0:6bc4ac881c8e | 300 | LPC_RGU->RESET_CTRL0 = 0x105F0000; |
| ebrus | 0:6bc4ac881c8e | 301 | LPC_RGU->RESET_CTRL1 = 0x01DFF7FF; |
| ebrus | 0:6bc4ac881c8e | 302 | } |
| ebrus | 0:6bc4ac881c8e | 303 | |
| ebrus | 0:6bc4ac881c8e | 304 | /* |
| ebrus | 0:6bc4ac881c8e | 305 | * SystemSetupPins() - Configure MCU pins |
| ebrus | 0:6bc4ac881c8e | 306 | */ |
| ebrus | 0:6bc4ac881c8e | 307 | void SystemSetupPins(const PINMUX_GRP_T *mux, uint32_t n) |
| ebrus | 0:6bc4ac881c8e | 308 | { |
| ebrus | 0:6bc4ac881c8e | 309 | uint32_t i; |
| ebrus | 0:6bc4ac881c8e | 310 | |
| ebrus | 0:6bc4ac881c8e | 311 | for (i = 0; i < n; i++) { |
| ebrus | 0:6bc4ac881c8e | 312 | *(mux[i].reg) = mux[i].mode; |
| ebrus | 0:6bc4ac881c8e | 313 | } |
| ebrus | 0:6bc4ac881c8e | 314 | } |
| ebrus | 0:6bc4ac881c8e | 315 | |
| ebrus | 0:6bc4ac881c8e | 316 | /* |
| ebrus | 0:6bc4ac881c8e | 317 | * SystemSetupMemory() - Configure external memory |
| ebrus | 0:6bc4ac881c8e | 318 | */ |
| ebrus | 0:6bc4ac881c8e | 319 | void SystemSetupMemory(void) |
| ebrus | 0:6bc4ac881c8e | 320 | { |
| ebrus | 0:6bc4ac881c8e | 321 | #if (MEMORY_SETUP) |
| ebrus | 0:6bc4ac881c8e | 322 | /* None required for boards without external memory */ |
| ebrus | 0:6bc4ac881c8e | 323 | #endif /* MEMORY_SETUP */ |
| ebrus | 0:6bc4ac881c8e | 324 | } |
| ebrus | 0:6bc4ac881c8e | 325 | |
| ebrus | 0:6bc4ac881c8e | 326 | #if defined(__FPU_PRESENT) && __FPU_PRESENT == 1 |
| ebrus | 0:6bc4ac881c8e | 327 | /* |
| ebrus | 0:6bc4ac881c8e | 328 | * fpuInit() - Early initialization of the FPU |
| ebrus | 0:6bc4ac881c8e | 329 | */ |
| ebrus | 0:6bc4ac881c8e | 330 | void fpuInit(void) |
| ebrus | 0:6bc4ac881c8e | 331 | { |
| ebrus | 0:6bc4ac881c8e | 332 | /* |
| ebrus | 0:6bc4ac881c8e | 333 | * from ARM TRM manual: |
| ebrus | 0:6bc4ac881c8e | 334 | * ; CPACR is located at address 0xE000ED88 |
| ebrus | 0:6bc4ac881c8e | 335 | * LDR.W R0, =0xE000ED88 |
| ebrus | 0:6bc4ac881c8e | 336 | * ; Read CPACR |
| ebrus | 0:6bc4ac881c8e | 337 | * LDR R1, [R0] |
| ebrus | 0:6bc4ac881c8e | 338 | * ; Set bits 20-23 to enable CP10 and CP11 coprocessors |
| ebrus | 0:6bc4ac881c8e | 339 | * ORR R1, R1, #(0xF << 20) |
| ebrus | 0:6bc4ac881c8e | 340 | * ; Write back the modified value to the CPACR |
| ebrus | 0:6bc4ac881c8e | 341 | * STR R1, [R0] |
| ebrus | 0:6bc4ac881c8e | 342 | */ |
| ebrus | 0:6bc4ac881c8e | 343 | |
| ebrus | 0:6bc4ac881c8e | 344 | volatile uint32_t *regCpacr = (uint32_t *) LPC_CPACR; |
| ebrus | 0:6bc4ac881c8e | 345 | volatile uint32_t *regMvfr0 = (uint32_t *) SCB_MVFR0; |
| ebrus | 0:6bc4ac881c8e | 346 | volatile uint32_t *regMvfr1 = (uint32_t *) SCB_MVFR1; |
| ebrus | 0:6bc4ac881c8e | 347 | volatile uint32_t Cpacr; |
| ebrus | 0:6bc4ac881c8e | 348 | volatile uint32_t Mvfr0; |
| ebrus | 0:6bc4ac881c8e | 349 | volatile uint32_t Mvfr1; |
| ebrus | 0:6bc4ac881c8e | 350 | char vfpPresent = 0; |
| ebrus | 0:6bc4ac881c8e | 351 | |
| ebrus | 0:6bc4ac881c8e | 352 | Mvfr0 = *regMvfr0; |
| ebrus | 0:6bc4ac881c8e | 353 | Mvfr1 = *regMvfr1; |
| ebrus | 0:6bc4ac881c8e | 354 | |
| ebrus | 0:6bc4ac881c8e | 355 | vfpPresent = ((SCB_MVFR0_RESET == Mvfr0) && (SCB_MVFR1_RESET == Mvfr1)); |
| ebrus | 0:6bc4ac881c8e | 356 | |
| ebrus | 0:6bc4ac881c8e | 357 | if (vfpPresent) { |
| ebrus | 0:6bc4ac881c8e | 358 | Cpacr = *regCpacr; |
| ebrus | 0:6bc4ac881c8e | 359 | Cpacr |= (0xF << 20); |
| ebrus | 0:6bc4ac881c8e | 360 | *regCpacr = Cpacr; /* enable CP10 and CP11 for full access */ |
| ebrus | 0:6bc4ac881c8e | 361 | } |
| ebrus | 0:6bc4ac881c8e | 362 | } |
| ebrus | 0:6bc4ac881c8e | 363 | #endif /* defined(__FPU_PRESENT) && __FPU_PRESENT == 1 */ |
| ebrus | 0:6bc4ac881c8e | 364 | |
| ebrus | 0:6bc4ac881c8e | 365 | /* Approximate delay function */ |
| ebrus | 0:6bc4ac881c8e | 366 | #define CPU_NANOSEC(x) (((uint64_t) (x) * SystemCoreClock) / 1000000000) |
| ebrus | 0:6bc4ac881c8e | 367 | |
| ebrus | 0:6bc4ac881c8e | 368 | static void WaitUs(uint32_t us) |
| ebrus | 0:6bc4ac881c8e | 369 | { |
| ebrus | 0:6bc4ac881c8e | 370 | uint32_t cyc = us * CPU_NANOSEC(1000) / 4; |
| ebrus | 0:6bc4ac881c8e | 371 | while (cyc--) |
| ebrus | 0:6bc4ac881c8e | 372 | ; |
| ebrus | 0:6bc4ac881c8e | 373 | } |
| ebrus | 0:6bc4ac881c8e | 374 | |
| ebrus | 0:6bc4ac881c8e | 375 | #endif /* !defined(CORE_M0) */ |