1 /**********************************************************************
\r
2 * $Id$ lpc18xx_cgu.c 2011-06-02
\r
4 * @file lpc18xx_cgu.c
\r
5 * @brief Contains all functions support for Clock Generation and Control
\r
6 * firmware library on LPC18xx
\r
8 * @date 02. June. 2011
\r
9 * @author NXP MCU SW Application Team
\r
11 * Copyright(C) 2011, NXP Semiconductor
\r
12 * All rights reserved.
\r
14 ***********************************************************************
\r
15 * Software that is described herein is for illustrative purposes only
\r
16 * which provides customers with programming information regarding the
\r
17 * products. This software is supplied "AS IS" without any warranties.
\r
18 * NXP Semiconductors assumes no responsibility or liability for the
\r
19 * use of the software, conveys no license or title under any patent,
\r
20 * copyright, or mask work right to the product. NXP Semiconductors
\r
21 * reserves the right to make changes in the software without
\r
22 * notification. NXP Semiconductors also make no representation or
\r
23 * warranty that such application will be suitable for the specified
\r
24 * use without further testing or modification.
\r
25 **********************************************************************/
\r
27 /* Peripheral group ----------------------------------------------------------- */
\r
32 /* Includes ------------------------------------------------------------------- */
\r
33 #include "lpc_types.h"
\r
34 #include "lpc18xx_scu.h"
\r
35 #include "lpc18xx_cgu.h"
\r
37 /** This define used to fix mistake when run with IAR compiler */
\r
39 #define CGU_BRANCH_STATUS_ENABLE_MASK 0x80000001
\r
41 #define CGU_BRANCH_STATUS_ENABLE_MASK 0x01
\r
46 * UPDATE Clock from PLL0
\r
47 * SetDIV uncheck value
\r
48 * GetBaseStatus BASE_SAFE
\r
50 /* Local definition */
\r
51 #define CGU_ADDRESS32(x,y) (*(uint32_t*)((uint32_t)x+y))
\r
53 /* Local Variable */
\r
54 const int16_t CGU_Entity_ControlReg_Offset[CGU_ENTITY_NUM] = {
\r
55 -1, //CGU_CLKSRC_32KHZ_OSC,
\r
56 -1, //CGU_CLKSRC_IRC,
\r
57 -1, //CGU_CLKSRC_ENET_RX_CLK,
\r
58 -1, //CGU_CLKSRC_ENET_TX_CLK,
\r
59 -1, //CGU_CLKSRC_GP_CLKIN,
\r
60 -1, //CGU_CLKSRC_TCK,
\r
61 0x18, //CGU_CLKSRC_XTAL_OSC,
\r
62 0x20, //CGU_CLKSRC_PLL0,
\r
63 0x30, //CGU_CLKSRC_PLL0_AUDIO **REV A**
\r
64 0x44, //CGU_CLKSRC_PLL1,
\r
65 -1, //CGU_CLKSRC_RESERVE,
\r
66 -1, //CGU_CLKSRC_RESERVE,
\r
67 0x48, //CGU_CLKSRC_IDIVA,,
\r
68 0x4C, //CGU_CLKSRC_IDIVB,
\r
69 0x50, //CGU_CLKSRC_IDIVC,
\r
70 0x54, //CGU_CLKSRC_IDIVD,
\r
71 0x58, //CGU_CLKSRC_IDIVE,
\r
73 0x5C, //CGU_BASE_SAFE,
\r
74 0x60, //CGU_BASE_USB0,
\r
75 -1, //CGU_BASE_RESERVE,
\r
76 0x68, //CGU_BASE_USB1,
\r
77 0x6C, //CGU_BASE_M3,
\r
78 0x70, //CGU_BASE_SPIFI,
\r
79 -1, //CGU_BASE_RESERVE,
\r
80 0x78, //CGU_BASE_PHY_RX,
\r
81 0x7C, //CGU_BASE_PHY_TX,
\r
82 0x80, //CGU_BASE_APB1,
\r
83 0x84, //CGU_BASE_APB3,
\r
84 0x88, //CGU_BASE_LCD,
\r
85 0X8C, //CGU_BASE_ENET_CSR, **REV A**
\r
86 0x90, //CGU_BASE_SDIO,
\r
87 0x94, //CGU_BASE_SSP0,
\r
88 0x98, //CGU_BASE_SSP1,
\r
89 0x9C, //CGU_BASE_UART0,
\r
90 0xA0, //CGU_BASE_UART1,
\r
91 0xA4, //CGU_BASE_UART2,
\r
92 0xA8, //CGU_BASE_UART3,
\r
93 0xAC, //CGU_BASE_CLKOUT
\r
98 0xC0, //CGU_BASE_APLL
\r
99 0xC4, //CGU_BASE_OUT0
\r
100 0xC8 //CGU_BASE_OUT1
\r
103 const uint8_t CGU_ConnectAlloc_Tbl[CGU_CLKSRC_NUM][CGU_ENTITY_NUM] = {
\r
104 // 3 I E E G T X P P P x x D D D D D S U x U M S x P P A A L E S S S U U U U C x x x x A O O
\r
105 // 2 R R T P C T L L L I I I I I A S S 3 P H H P P C N D S S R R R R O P U U
\r
106 // C X X I K A 0 A 1 A B C D E F B B F RxTx1 3 D T I 0 1 0 1 2 3 L T T
\r
107 {0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_32KHZ_OSC = 0,*/
\r
108 {0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_IRC,*/
\r
109 {0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_ENET_RX_CLK,*/
\r
110 {0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_ENET_TX_CLK,*/
\r
111 {0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_GP_CLKIN,*/
\r
112 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0},/*CGU_CLKSRC_TCK,*/
\r
113 {0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_XTAL_OSC,*/
\r
114 {0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1},/*CGU_CLKSRC_PLL0,*/
\r
115 {0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_PLL0_AUDIO,*/
\r
116 {0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_PLL1,*/
\r
117 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
\r
118 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
\r
119 {0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_IDIVA = CGU_CLKSRC_PLL1 + 3,*/
\r
120 {0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_IDIVB,*/
\r
121 {0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_IDIVC,*/
\r
122 {0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_IDIVD,*/
\r
123 {0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1}/*CGU_CLKSRC_IDIVE,*/
\r
126 const CGU_PERIPHERAL_S CGU_PERIPHERAL_Info[CGU_PERIPHERAL_NUM] = {
\r
127 /* Register Clock | Peripheral Clock
\r
128 | BASE | BRANCH | BASE | BRANCH */
\r
129 {CGU_BASE_APB3, 0x1118, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_ADC0,
\r
130 {CGU_BASE_APB3, 0x1120, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_ADC1,
\r
131 {CGU_BASE_M3, 0x1460, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_AES,
\r
132 //// CGU_PERIPHERAL_ALARMTIMER_CGU_RGU_RTC_WIC,
\r
133 {CGU_BASE_APB1, 0x1200, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_APB1_BUS,
\r
134 {CGU_BASE_APB3, 0x1100, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_APB3_BUS,
\r
135 {CGU_BASE_APB3, 0x1128, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_CAN0,
\r
136 {CGU_BASE_M3, 0x1538, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_CREG,
\r
137 {CGU_BASE_APB3, 0x1110, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_DAC,
\r
138 {CGU_BASE_M3, 0x1440, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_DMA,
\r
139 {CGU_BASE_M3, 0x1430, CGU_BASE_M3, 0x1478, 0},//CGU_PERIPHERAL_EMC,
\r
140 {CGU_BASE_M3, 0x1420, CGU_BASE_PHY_RX, 0x0000, CGU_PERIPHERAL_ETHERNET_TX},//CGU_PERIPHERAL_ETHERNET,
\r
141 {CGU_ENTITY_NONE,0x0000, CGU_BASE_PHY_TX, 0x0000, 0},//CGU_PERIPHERAL_ETHERNET_TX
\r
142 {CGU_BASE_M3, 0x1410, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_GPIO,
\r
143 {CGU_BASE_APB1, 0x1210, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_I2C0,
\r
144 {CGU_BASE_APB3, 0x1108, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_I2C1,
\r
145 {CGU_BASE_APB1, 0x1218, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_I2S,
\r
146 {CGU_BASE_M3, 0x1418, CGU_BASE_LCD, 0x0000, 0},//CGU_PERIPHERAL_LCD,
\r
147 {CGU_BASE_M3, 0x1448, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_M3CORE,
\r
148 {CGU_BASE_M3, 0x1400, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_M3_BUS,
\r
149 {CGU_BASE_APB1, 0x1208, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_MOTOCON,
\r
150 {CGU_BASE_M3, 0x1630, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_QEI,
\r
151 {CGU_BASE_M3, 0x1600, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_RITIMER,
\r
152 {CGU_BASE_M3, 0x1468, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_SCT,
\r
153 {CGU_BASE_M3, 0x1530, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_SCU,
\r
154 {CGU_BASE_M3, 0x1438, CGU_BASE_SDIO, 0x2800, 0},//CGU_PERIPHERAL_SDIO,
\r
155 {CGU_BASE_M3, 0x1408, CGU_BASE_SPIFI, 0x1300, 0},//CGU_PERIPHERAL_SPIFI,
\r
156 {CGU_BASE_M3, 0x1518, CGU_BASE_SSP0, 0x2700, 0},//CGU_PERIPHERAL_SSP0,
\r
157 {CGU_BASE_M3, 0x1628, CGU_BASE_SSP1, 0x2600, 0},//CGU_PERIPHERAL_SSP1,
\r
158 {CGU_BASE_M3, 0x1520, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER0,
\r
159 {CGU_BASE_M3, 0x1528, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER1,
\r
160 {CGU_BASE_M3, 0x1618, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER2,
\r
161 {CGU_BASE_M3, 0x1620, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER3,
\r
162 {CGU_BASE_M3, 0x1508, CGU_BASE_UART0, 0x2500, 0},//CGU_PERIPHERAL_UART0,
\r
163 {CGU_BASE_M3, 0x1510, CGU_BASE_UART1, 0x2400, 0},//CGU_PERIPHERAL_UART1,
\r
164 {CGU_BASE_M3, 0x1608, CGU_BASE_UART2, 0x2300, 0},//CGU_PERIPHERAL_UART2,
\r
165 {CGU_BASE_M3, 0x1610, CGU_BASE_UART3, 0x2200, 0},//CGU_PERIPHERAL_UART3,
\r
166 {CGU_BASE_M3, 0x1428, CGU_BASE_USB0, 0x1800, 0},//CGU_PERIPHERAL_USB0,
\r
167 {CGU_BASE_M3, 0x1470, CGU_BASE_USB1, 0x1900, 0},//CGU_PERIPHERAL_USB1,
\r
168 {CGU_BASE_M3, 0x1500, CGU_BASE_SAFE, 0x0000, 0},//CGU_PERIPHERAL_WWDT,
\r
171 uint32_t CGU_ClockSourceFrequency[CGU_CLKSRC_NUM] = {0,12000000,0,0,0,0, 0, 480000000,0,0,0,0,0,0,0,0,0};
\r
173 #define CGU_CGU_ADDR ((uint32_t)LPC_CGU)
\r
174 #define CGU_REG_BASE_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_Entity_ControlReg_Offset[CGU_PERIPHERAL_Info[x].RegBaseEntity]))
\r
175 #define CGU_REG_BRANCH_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].RegBranchOffset))
\r
176 #define CGU_REG_BRANCH_STATUS(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].RegBranchOffset+4))
\r
178 #define CGU_PER_BASE_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_Entity_ControlReg_Offset[CGU_PERIPHERAL_Info[x].PerBaseEntity]))
\r
179 #define CGU_PER_BRANCH_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].PerBranchOffset))
\r
180 #define CGU_PER_BRANCH_STATUS(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].PerBranchOffset+4))
\r
183 /*********************************************************************//**
\r
184 * @brief Initialize default clock for LPC1800 Eval board
\r
186 * @return Initialize status, could be:
\r
187 * - CGU_ERROR_SUCCESS: successful
\r
189 **********************************************************************/
\r
190 uint32_t CGU_Init(void){
\r
191 CGU_SetXTALOSC(12000000);
\r
192 CGU_EnableEntity(CGU_CLKSRC_XTAL_OSC, ENABLE);
\r
193 CGU_EntityConnect(CGU_CLKSRC_XTAL_OSC, CGU_CLKSRC_PLL1);
\r
194 // Disable PLL1 CPU hang???
\r
195 //CGU_EnableEntity(CGU_CLKSRC_PLL1, DISABLE);
\r
197 CGU_EnableEntity(CGU_CLKSRC_PLL1, ENABLE);
\r
198 CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_M3);
\r
203 /*********************************************************************//**
\r
204 * @brief Configure power for individual peripheral
\r
205 * @param[in] PPType peripheral type, should be:
\r
206 * - CGU_PERIPHERAL_ADC0 :ADC0
\r
207 * - CGU_PERIPHERAL_ADC1 :ADC1
\r
208 * - CGU_PERIPHERAL_AES :AES
\r
209 * - CGU_PERIPHERAL_APB1_BUS :APB1 bus
\r
210 * - CGU_PERIPHERAL_APB3_BUS :APB3 bus
\r
211 * - CGU_PERIPHERAL_CAN :CAN
\r
212 * - CGU_PERIPHERAL_CREG :CREG
\r
213 * - CGU_PERIPHERAL_DAC :DAC
\r
214 * - CGU_PERIPHERAL_DMA :DMA
\r
215 * - CGU_PERIPHERAL_EMC :EMC
\r
216 * - CGU_PERIPHERAL_ETHERNET :ETHERNET
\r
217 * - CGU_PERIPHERAL_GPIO :GPIO
\r
218 * - CGU_PERIPHERAL_I2C0 :I2C0
\r
219 * - CGU_PERIPHERAL_I2C1 :I2C1
\r
220 * - CGU_PERIPHERAL_I2S :I2S
\r
221 * - CGU_PERIPHERAL_LCD :LCD
\r
222 * - CGU_PERIPHERAL_M3CORE :M3 core
\r
223 * - CGU_PERIPHERAL_M3_BUS :M3 bus
\r
224 * - CGU_PERIPHERAL_MOTOCON :Motor control
\r
225 * - CGU_PERIPHERAL_QEI :QEI
\r
226 * - CGU_PERIPHERAL_RITIMER :RIT timer
\r
227 * - CGU_PERIPHERAL_SCT :SCT
\r
228 * - CGU_PERIPHERAL_SCU :SCU
\r
229 * - CGU_PERIPHERAL_SDIO :SDIO
\r
230 * - CGU_PERIPHERAL_SPIFI :SPIFI
\r
231 * - CGU_PERIPHERAL_SSP0 :SSP0
\r
232 * - CGU_PERIPHERAL_SSP1 :SSP1
\r
233 * - CGU_PERIPHERAL_TIMER0 :TIMER0
\r
234 * - CGU_PERIPHERAL_TIMER1 :TIMER1
\r
235 * - CGU_PERIPHERAL_TIMER2 :TIMER2
\r
236 * - CGU_PERIPHERAL_TIMER3 :TIMER3
\r
237 * - CGU_PERIPHERAL_UART0 :UART0
\r
238 * - CGU_PERIPHERAL_UART1 :UART1
\r
239 * - CGU_PERIPHERAL_UART2 :UART2
\r
240 * - CGU_PERIPHERAL_UART3 :UART3
\r
241 * - CGU_PERIPHERAL_USB0 :USB0
\r
242 * - CGU_PERIPHERAL_USB1 :USB1
\r
243 * - CGU_PERIPHERAL_WWDT :WWDT
\r
244 * @param[in] en status, should be:
\r
245 * - ENABLE: Enable power
\r
246 * - DISABLE: Disable power
\r
247 * @return Configure status, could be:
\r
248 * - CGU_ERROR_SUCCESS: successful
\r
250 **********************************************************************/
\r
251 uint32_t CGU_ConfigPWR (CGU_PERIPHERAL_T PPType, FunctionalState en){
\r
252 if(PPType >= CGU_PERIPHERAL_WWDT && PPType <= CGU_PERIPHERAL_ADC0)
\r
253 return CGU_ERROR_INVALID_PARAM;
\r
254 if(en == DISABLE){/* Going to disable clock */
\r
255 /*Get Reg branch status */
\r
256 if(CGU_PERIPHERAL_Info[PPType].RegBranchOffset!= 0 &&
\r
257 CGU_REG_BRANCH_STATUS(PPType) & 1){
\r
258 CGU_REG_BRANCH_CTRL(PPType) &= ~1; /* Disable branch clock */
\r
259 while(CGU_REG_BRANCH_STATUS(PPType) & 1);
\r
261 /* GetBase Status*/
\r
262 if((CGU_PERIPHERAL_Info[PPType].RegBaseEntity!=CGU_ENTITY_NONE) &&
\r
263 CGU_GetBaseStatus((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].RegBaseEntity) == 0){
\r
265 CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].RegBaseEntity,0);
\r
268 /* Same for Peripheral */
\r
269 if((CGU_PERIPHERAL_Info[PPType].PerBranchOffset!= 0) && (CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK)){
\r
270 CGU_PER_BRANCH_CTRL(PPType) &= ~1; /* Disable branch clock */
\r
271 while(CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK);
\r
273 /* GetBase Status*/
\r
274 if((CGU_PERIPHERAL_Info[PPType].PerBaseEntity!=CGU_ENTITY_NONE) &&
\r
275 CGU_GetBaseStatus((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].PerBaseEntity) == 0){
\r
277 CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].PerBaseEntity,0);
\r
281 /* GetBase Status*/
\r
282 if((CGU_PERIPHERAL_Info[PPType].RegBaseEntity!=CGU_ENTITY_NONE) && CGU_REG_BASE_CTRL(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK){
\r
284 CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].RegBaseEntity, 1);
\r
286 /*Get Reg branch status */
\r
287 if((CGU_PERIPHERAL_Info[PPType].RegBranchOffset!= 0) && !(CGU_REG_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK)){
\r
288 CGU_REG_BRANCH_CTRL(PPType) |= 1; /* Enable branch clock */
\r
289 while(!(CGU_REG_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK));
\r
292 /* Same for Peripheral */
\r
293 /* GetBase Status*/
\r
294 if((CGU_PERIPHERAL_Info[PPType].PerBaseEntity != CGU_ENTITY_NONE) &&
\r
295 (CGU_PER_BASE_CTRL(PPType) & 1)){
\r
297 CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].PerBaseEntity, 1);
\r
299 /*Get Reg branch status */
\r
300 if((CGU_PERIPHERAL_Info[PPType].PerBranchOffset!= 0) && !(CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK)){
\r
301 CGU_PER_BRANCH_CTRL(PPType) |= 1; /* Enable branch clock */
\r
302 while(!(CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK));
\r
307 if(CGU_PERIPHERAL_Info[PPType].next){
\r
308 return CGU_ConfigPWR((CGU_PERIPHERAL_T)CGU_PERIPHERAL_Info[PPType].next, en);
\r
310 return CGU_ERROR_SUCCESS;
\r
314 /*********************************************************************//**
\r
315 * @brief Get peripheral clock frequency
\r
316 * @param[in] Clock Peripheral type, should be:
\r
317 * - CGU_PERIPHERAL_ADC0 :ADC0
\r
318 * - CGU_PERIPHERAL_ADC1 :ADC1
\r
319 * - CGU_PERIPHERAL_AES :AES
\r
320 * - CGU_PERIPHERAL_APB1_BUS :APB1 bus
\r
321 * - CGU_PERIPHERAL_APB3_BUS :APB3 bus
\r
322 * - CGU_PERIPHERAL_CAN :CAN
\r
323 * - CGU_PERIPHERAL_CREG :CREG
\r
324 * - CGU_PERIPHERAL_DAC :DAC
\r
325 * - CGU_PERIPHERAL_DMA :DMA
\r
326 * - CGU_PERIPHERAL_EMC :EMC
\r
327 * - CGU_PERIPHERAL_ETHERNET :ETHERNET
\r
328 * - CGU_PERIPHERAL_GPIO :GPIO
\r
329 * - CGU_PERIPHERAL_I2C0 :I2C0
\r
330 * - CGU_PERIPHERAL_I2C1 :I2C1
\r
331 * - CGU_PERIPHERAL_I2S :I2S
\r
332 * - CGU_PERIPHERAL_LCD :LCD
\r
333 * - CGU_PERIPHERAL_M3CORE :M3 core
\r
334 * - CGU_PERIPHERAL_M3_BUS :M3 bus
\r
335 * - CGU_PERIPHERAL_MOTOCON :Motor control
\r
336 * - CGU_PERIPHERAL_QEI :QEI
\r
337 * - CGU_PERIPHERAL_RITIMER :RIT timer
\r
338 * - CGU_PERIPHERAL_SCT :SCT
\r
339 * - CGU_PERIPHERAL_SCU :SCU
\r
340 * - CGU_PERIPHERAL_SDIO :SDIO
\r
341 * - CGU_PERIPHERAL_SPIFI :SPIFI
\r
342 * - CGU_PERIPHERAL_SSP0 :SSP0
\r
343 * - CGU_PERIPHERAL_SSP1 :SSP1
\r
344 * - CGU_PERIPHERAL_TIMER0 :TIMER0
\r
345 * - CGU_PERIPHERAL_TIMER1 :TIMER1
\r
346 * - CGU_PERIPHERAL_TIMER2 :TIMER2
\r
347 * - CGU_PERIPHERAL_TIMER3 :TIMER3
\r
348 * - CGU_PERIPHERAL_UART0 :UART0
\r
349 * - CGU_PERIPHERAL_UART1 :UART1
\r
350 * - CGU_PERIPHERAL_UART2 :UART2
\r
351 * - CGU_PERIPHERAL_UART3 :UART3
\r
352 * - CGU_PERIPHERAL_USB0 :USB0
\r
353 * - CGU_PERIPHERAL_USB1 :USB1
\r
354 * - CGU_PERIPHERAL_WWDT :WWDT
\r
355 * @return Return frequently value
\r
356 **********************************************************************/
\r
357 uint32_t CGU_GetPCLKFrequency (CGU_PERIPHERAL_T Clock){
\r
359 if(Clock >= CGU_PERIPHERAL_WWDT && Clock <= CGU_PERIPHERAL_ADC0)
\r
360 return CGU_ERROR_INVALID_PARAM;
\r
362 if(CGU_PERIPHERAL_Info[Clock].PerBaseEntity != CGU_ENTITY_NONE){
\r
363 /* Get Base Clock Source */
\r
364 ClkSrc = (CGU_PER_BASE_CTRL(Clock) & CGU_CTRL_SRC_MASK) >> 24;
\r
365 /* GetBase Status*/
\r
366 if(CGU_PER_BASE_CTRL(Clock) & 1)
\r
368 /* check Branch if it is enabled */
\r
369 if((CGU_PERIPHERAL_Info[Clock].PerBranchOffset!= 0) && !(CGU_PER_BRANCH_STATUS(Clock) & CGU_BRANCH_STATUS_ENABLE_MASK)) return 0;
\r
371 if(CGU_REG_BASE_CTRL(Clock) & 1) return 0;
\r
372 ClkSrc = (CGU_REG_BASE_CTRL(Clock) & CGU_CTRL_SRC_MASK) >> 24;
\r
373 /* check Branch if it is enabled */
\r
374 if((CGU_PERIPHERAL_Info[Clock].RegBranchOffset!= 0) && !(CGU_REG_BRANCH_STATUS(Clock) & CGU_BRANCH_STATUS_ENABLE_MASK)) return 0;
\r
376 return CGU_ClockSourceFrequency[ClkSrc];
\r
380 /*********************************************************************//**
\r
381 * @brief Update clock
\r
384 **********************************************************************/
\r
385 void CGU_UpdateClock(void){
\r
391 if(ISBITSET(LPC_CREG->CREG0,1) && ISBITCLR(LPC_CREG->CREG0,3))
\r
392 CGU_ClockSourceFrequency[CGU_CLKSRC_32KHZ_OSC] = 32768;
\r
394 CGU_ClockSourceFrequency[CGU_CLKSRC_32KHZ_OSC] = 0;
\r
397 if(ISBITCLR(LPC_CGU->PLL1_CTRL,1) /* Enabled */
\r
398 && (LPC_CGU->PLL1_STAT&1)){ /* Locked? */
\r
399 ClkSrc = (LPC_CGU->PLL1_CTRL & CGU_CTRL_SRC_MASK)>>24;
\r
400 CGU_ClockSourceFrequency[CGU_CLKSRC_PLL1] = CGU_ClockSourceFrequency[ClkSrc] *
\r
401 (((LPC_CGU->PLL1_CTRL>>16)&0xFF)+1);
\r
403 CGU_ClockSourceFrequency[CGU_CLKSRC_PLL1] = 0;
\r
406 for(div = CGU_CLKSRC_IDIVA; div <= CGU_CLKSRC_IDIVE; div++){
\r
407 RegOffset = CGU_Entity_ControlReg_Offset[div];
\r
408 if(ISBITCLR(CGU_ADDRESS32(LPC_CGU,RegOffset),1)){
\r
409 ClkSrc = (CGU_ADDRESS32(LPC_CGU,RegOffset) & CGU_CTRL_SRC_MASK) >> 24;
\r
410 divisor = (CGU_ADDRESS32(LPC_CGU,RegOffset)>>2) & 0xFF;
\r
412 CGU_ClockSourceFrequency[div] = CGU_ClockSourceFrequency[ClkSrc] / divisor;
\r
414 CGU_ClockSourceFrequency[div] = 0;
\r
418 /*********************************************************************//**
\r
419 * @brief Set XTAL oscillator value
\r
420 * @param[in] ClockFrequency XTAL Frequency value
\r
421 * @return Setting status, could be:
\r
422 * - CGU_ERROR_SUCCESS: successful
\r
423 * - CGU_ERROR_FREQ_OUTOF_RANGE: XTAL value set is out of range
\r
424 **********************************************************************/
\r
425 uint32_t CGU_SetXTALOSC(uint32_t ClockFrequency){
\r
426 if(ClockFrequency < 15000000){
\r
427 LPC_CGU->XTAL_OSC_CTRL &= ~(1<<2);
\r
428 }else if(ClockFrequency < 25000000){
\r
429 LPC_CGU->XTAL_OSC_CTRL |= (1<<2);
\r
431 return CGU_ERROR_FREQ_OUTOF_RANGE;
\r
433 CGU_ClockSourceFrequency[CGU_CLKSRC_XTAL_OSC] = ClockFrequency;
\r
434 return CGU_ERROR_SUCCESS;
\r
438 /*********************************************************************//**
\r
439 * @brief Set clock divider
\r
440 * @param[in] SelectDivider Clock source, should be:
\r
441 * - CGU_CLKSRC_IDIVA :Integer divider register A
\r
442 * - CGU_CLKSRC_IDIVB :Integer divider register B
\r
443 * - CGU_CLKSRC_IDIVC :Integer divider register C
\r
444 * - CGU_CLKSRC_IDIVD :Integer divider register D
\r
445 * - CGU_CLKSRC_IDIVE :Integer divider register E
\r
446 * @param[in] divisor Divisor value, should be: 0..255
\r
447 * @return Setting status, could be:
\r
448 * - CGU_ERROR_SUCCESS: successful
\r
449 * - CGU_ERROR_INVALID_ENTITY: Invalid entity
\r
450 **********************************************************************/
\r
451 /* divisor number must >=1*/
\r
452 uint32_t CGU_SetDIV(CGU_ENTITY_T SelectDivider, uint32_t divisor){
\r
455 if(SelectDivider>=CGU_CLKSRC_IDIVA && SelectDivider<=CGU_CLKSRC_IDIVE){
\r
456 RegOffset = CGU_Entity_ControlReg_Offset[SelectDivider];
\r
457 if(RegOffset == -1) return CGU_ERROR_INVALID_ENTITY;
\r
458 tempReg = CGU_ADDRESS32(LPC_CGU,RegOffset);
\r
459 tempReg &= ~(0xFF<<2);
\r
460 tempReg |= ((divisor-1)&0xFF)<<2;
\r
461 CGU_ADDRESS32(LPC_CGU,RegOffset) = tempReg;
\r
462 return CGU_ERROR_SUCCESS;
\r
464 return CGU_ERROR_INVALID_ENTITY;
\r
467 /*********************************************************************//**
\r
468 * @brief Enable clock entity
\r
469 * @param[in] ClockEntity Clock entity, should be:
\r
470 * - CGU_CLKSRC_32KHZ_OSC :32Khz oscillator
\r
471 * - CGU_CLKSRC_IRC :IRC clock
\r
472 * - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock
\r
473 * - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock
\r
474 * - CGU_CLKSRC_GP_CLKIN :General purpose input clock
\r
475 * - CGU_CLKSRC_XTAL_OSC :Crystal oscillator
\r
476 * - CGU_CLKSRC_PLL0 :PLL0 clock
\r
477 * - CGU_CLKSRC_PLL1 :PLL1 clock
\r
478 * - CGU_CLKSRC_IDIVA :Integer divider register A
\r
479 * - CGU_CLKSRC_IDIVB :Integer divider register B
\r
480 * - CGU_CLKSRC_IDIVC :Integer divider register C
\r
481 * - CGU_CLKSRC_IDIVD :Integer divider register D
\r
482 * - CGU_CLKSRC_IDIVE :Integer divider register E
\r
483 * - CGU_BASE_SAFE :Base safe clock (always on)for WDT
\r
484 * - CGU_BASE_USB0 :Base clock for USB0
\r
485 * - CGU_BASE_USB1 :Base clock for USB1
\r
486 * - CGU_BASE_M3 :System base clock for ARM Cortex-M3 core
\r
487 * and APB peripheral blocks #0 and #2
\r
488 * - CGU_BASE_SPIFI :Base clock for SPIFI
\r
489 * - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx
\r
490 * - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx
\r
491 * - CGU_BASE_APB1 :Base clock for APB peripheral block #1
\r
492 * - CGU_BASE_APB3 :Base clock for APB peripheral block #3
\r
493 * - CGU_BASE_LCD :Base clock for LCD
\r
494 * - CGU_BASE_SDIO :Base clock for SDIO card reader
\r
495 * - CGU_BASE_SSP0 :Base clock for SSP0
\r
496 * - CGU_BASE_SSP1 :Base clock for SSP1
\r
497 * - CGU_BASE_UART0 :Base clock for UART0
\r
498 * - CGU_BASE_UART1 :Base clock for UART1
\r
499 * - CGU_BASE_UART2 :Base clock for UART2
\r
500 * - CGU_BASE_UART3 :Base clock for UART3
\r
501 * - CGU_BASE_CLKOUT :Base clock for CLKOUT pin
\r
502 * @param[in] en status, should be:
\r
503 * - ENABLE: Enable power
\r
504 * - DISABLE: Disable power
\r
505 * @return Setting status, could be:
\r
506 * - CGU_ERROR_SUCCESS: successful
\r
507 * - CGU_ERROR_INVALID_ENTITY: Invalid entity
\r
508 **********************************************************************/
\r
509 uint32_t CGU_EnableEntity(CGU_ENTITY_T ClockEntity, uint32_t en){
\r
512 if(ClockEntity == CGU_CLKSRC_32KHZ_OSC){
\r
514 LPC_CREG->CREG0 &= ~((1<<3)|(1<<2));
\r
515 LPC_CREG->CREG0 |= (1<<1)|(1<<0);
\r
517 LPC_CREG->CREG0 &= ~((1<<1)|(1<<0));
\r
518 LPC_CREG->CREG0 |= (1<<3);
\r
520 for(i = 0;i<1000000;i++);
\r
522 }else if(ClockEntity == CGU_CLKSRC_ENET_RX_CLK){
\r
523 scu_pinmux(0xC ,0 , MD_PLN, FUNC3);
\r
525 }else if(ClockEntity == CGU_CLKSRC_ENET_TX_CLK){
\r
526 scu_pinmux(0x1 ,19 , MD_PLN, FUNC0);
\r
528 }else if(ClockEntity == CGU_CLKSRC_GP_CLKIN){
\r
530 }else if(ClockEntity == CGU_CLKSRC_TCK){
\r
532 }else if(ClockEntity == CGU_CLKSRC_XTAL_OSC){
\r
534 LPC_CGU->XTAL_OSC_CTRL |= CGU_CTRL_EN_MASK;
\r
536 LPC_CGU->XTAL_OSC_CTRL &= ~CGU_CTRL_EN_MASK;
\r
537 /*Delay for stable clock*/
\r
538 for(i = 0;i<1000000;i++);
\r
541 RegOffset = CGU_Entity_ControlReg_Offset[ClockEntity];
\r
542 if(RegOffset == -1) return CGU_ERROR_INVALID_ENTITY;
\r
544 CGU_ADDRESS32(CGU_CGU_ADDR,RegOffset) |= CGU_CTRL_EN_MASK;
\r
546 CGU_ADDRESS32(CGU_CGU_ADDR,RegOffset) &= ~CGU_CTRL_EN_MASK;
\r
547 /*if PLL is selected check if it is locked */
\r
548 if(ClockEntity == CGU_CLKSRC_PLL0){
\r
549 while((LPC_CGU->PLL0USB_STAT&1) == 0x0);
\r
551 if(ClockEntity == CGU_CLKSRC_PLL1){
\r
552 while((LPC_CGU->PLL1_STAT&1) == 0x0);
\r
553 /*post check lock status */
\r
554 if(!(LPC_CGU->PLL1_STAT&1))
\r
559 return CGU_ERROR_SUCCESS;
\r
562 /*********************************************************************//**
\r
563 * @brief Connect entity clock source
\r
564 * @param[in] ClockSource Clock source, should be:
\r
565 * - CGU_CLKSRC_32KHZ_OSC :32Khz oscillator
\r
566 * - CGU_CLKSRC_IRC :IRC clock
\r
567 * - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock
\r
568 * - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock
\r
569 * - CGU_CLKSRC_GP_CLKIN :General purpose input clock
\r
570 * - CGU_CLKSRC_XTAL_OSC :Crystal oscillator
\r
571 * - CGU_CLKSRC_PLL0 :PLL0 clock
\r
572 * - CGU_CLKSRC_PLL1 :PLL1 clock
\r
573 * - CGU_CLKSRC_IDIVA :Integer divider register A
\r
574 * - CGU_CLKSRC_IDIVB :Integer divider register B
\r
575 * - CGU_CLKSRC_IDIVC :Integer divider register C
\r
576 * - CGU_CLKSRC_IDIVD :Integer divider register D
\r
577 * - CGU_CLKSRC_IDIVE :Integer divider register E
\r
578 * @param[in] ClockEntity Clock entity, should be:
\r
579 * - CGU_CLKSRC_PLL0 :PLL0 clock
\r
580 * - CGU_CLKSRC_PLL1 :PLL1 clock
\r
581 * - CGU_CLKSRC_IDIVA :Integer divider register A
\r
582 * - CGU_CLKSRC_IDIVB :Integer divider register B
\r
583 * - CGU_CLKSRC_IDIVC :Integer divider register C
\r
584 * - CGU_CLKSRC_IDIVD :Integer divider register D
\r
585 * - CGU_CLKSRC_IDIVE :Integer divider register E
\r
586 * - CGU_BASE_SAFE :Base safe clock (always on)for WDT
\r
587 * - CGU_BASE_USB0 :Base clock for USB0
\r
588 * - CGU_BASE_USB1 :Base clock for USB1
\r
589 * - CGU_BASE_M3 :System base clock for ARM Cortex-M3 core
\r
590 * and APB peripheral blocks #0 and #2
\r
591 * - CGU_BASE_SPIFI :Base clock for SPIFI
\r
592 * - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx
\r
593 * - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx
\r
594 * - CGU_BASE_APB1 :Base clock for APB peripheral block #1
\r
595 * - CGU_BASE_APB3 :Base clock for APB peripheral block #3
\r
596 * - CGU_BASE_LCD :Base clock for LCD
\r
597 * - CGU_BASE_SDIO :Base clock for SDIO card reader
\r
598 * - CGU_BASE_SSP0 :Base clock for SSP0
\r
599 * - CGU_BASE_SSP1 :Base clock for SSP1
\r
600 * - CGU_BASE_UART0 :Base clock for UART0
\r
601 * - CGU_BASE_UART1 :Base clock for UART1
\r
602 * - CGU_BASE_UART2 :Base clock for UART2
\r
603 * - CGU_BASE_UART3 :Base clock for UART3
\r
604 * - CGU_BASE_CLKOUT :Base clock for CLKOUT pin
\r
605 * @return Setting status, could be:
\r
606 * - CGU_ERROR_SUCCESS: successful
\r
607 * - CGU_ERROR_CONNECT_TOGETHER: Error when 2 clock source connect together
\r
608 * - CGU_ERROR_INVALID_CLOCK_SOURCE: Invalid clock source error
\r
609 * - CGU_ERROR_INVALID_ENTITY: Invalid entity error
\r
610 **********************************************************************/
\r
611 /* Connect one entity into clock source */
\r
612 uint32_t CGU_EntityConnect(CGU_ENTITY_T ClockSource, CGU_ENTITY_T ClockEntity){
\r
616 if(ClockSource > CGU_CLKSRC_IDIVE)
\r
617 return CGU_ERROR_INVALID_CLOCK_SOURCE;
\r
619 if(ClockEntity >= CGU_CLKSRC_PLL0 && ClockEntity <= CGU_BASE_CLKOUT){
\r
620 if(CGU_ConnectAlloc_Tbl[ClockSource][ClockEntity]){
\r
621 RegOffset = CGU_Entity_ControlReg_Offset[ClockSource];
\r
622 if(RegOffset != -1){
\r
623 if(ClockEntity<=CGU_CLKSRC_IDIVE &&
\r
624 ClockEntity>=CGU_CLKSRC_PLL0)
\r
626 //RegOffset = (CGU_ADDRESS32(LPC_CGU,RegOffset)>>24)&0xF;
\r
627 if(((CGU_ADDRESS32(LPC_CGU,RegOffset)>>24)& 0xF) == ClockEntity)
\r
628 return CGU_ERROR_CONNECT_TOGETHER;
\r
631 RegOffset = CGU_Entity_ControlReg_Offset[ClockEntity];
\r
632 if(RegOffset == -1) return CGU_ERROR_INVALID_ENTITY;
\r
633 tempReg = CGU_ADDRESS32(LPC_CGU,RegOffset);
\r
634 tempReg &= ~CGU_CTRL_SRC_MASK;
\r
635 tempReg |= ClockSource<<24 | CGU_CTRL_AUTOBLOCK_MASK;
\r
636 CGU_ADDRESS32(LPC_CGU,RegOffset) = tempReg;
\r
637 return CGU_ERROR_SUCCESS;
\r
639 return CGU_ERROR_INVALID_CLOCK_SOURCE;
\r
641 return CGU_ERROR_INVALID_ENTITY;
\r
645 /*********************************************************************//**
\r
646 * @brief Get current USB PLL clock from XTAL
\r
648 * @return Returned clock value
\r
649 **********************************************************************/
\r
650 uint32_t CGU_SetPLL0(void){
\r
651 // Setup PLL550 to generate 480MHz from 12 MHz crystal
\r
652 LPC_CGU->PLL0USB_CTRL |= 1; // Power down PLL
\r
654 LPC_CGU->PLL0USB_NP_DIV = (98<<0) | (514<<12);
\r
655 // SELP SELI SELR MDEC
\r
656 LPC_CGU->PLL0USB_MDIV = (0xB<<17)|(0x10<<22)|(0<<28)|(0x7FFA<<0);
\r
657 LPC_CGU->PLL0USB_CTRL =(CGU_CLKSRC_XTAL_OSC<<24) | (0x3<<2) | (1<<4);
\r
658 return CGU_ERROR_SUCCESS;
\r
662 /*********************************************************************//**
\r
663 * @brief Setting PLL1
\r
664 * @param[in] mult Multiple value
\r
665 * @return Setting status, could be:
\r
666 * - CGU_ERROR_SUCCESS: successful
\r
667 * - CGU_ERROR_INVALID_PARAM: Invalid parameter error
\r
668 **********************************************************************/
\r
669 uint32_t CGU_SetPLL1(uint32_t mult){
\r
670 uint32_t msel=0, nsel=0, psel=0, pval=1;
\r
672 uint32_t ClkSrc = (LPC_CGU->PLL1_CTRL & CGU_CTRL_SRC_MASK)>>24;
\r
673 freq = CGU_ClockSourceFrequency[ClkSrc];
\r
677 LPC_CGU->PLL1_CTRL &= ~(CGU_PLL1_FBSEL_MASK |
\r
678 CGU_PLL1_BYPASS_MASK |
\r
679 CGU_PLL1_DIRECT_MASK |
\r
680 (0x03<<8) | (0xFF<<16) | (0x03<<12));
\r
682 if(freq<156000000){
\r
683 //psel is encoded such that 0=1, 1=2, 2=4, 3=8
\r
684 while(2*(pval)*freq < 156000000) {
\r
688 // if(2*(pval)*freq > 320000000) {
\r
689 // //THIS IS OUT OF RANGE!!!
\r
690 // //HOW DO WE ASSERT IN SAMPLE CODE?
\r
691 // //__breakpoint(0);
\r
692 // return CGU_ERROR_INVALID_PARAM;
\r
694 LPC_CGU->PLL1_CTRL |= (msel<<16) | (nsel<<12) | (psel<<8) | CGU_PLL1_FBSEL_MASK;
\r
695 }else if(freq<320000000){
\r
696 LPC_CGU->PLL1_CTRL |= (msel<<16) | (nsel<<12) | (psel<<8) |CGU_PLL1_DIRECT_MASK | CGU_PLL1_FBSEL_MASK;
\r
698 return CGU_ERROR_INVALID_PARAM;
\r
700 return CGU_ERROR_SUCCESS;
\r
704 /*********************************************************************//**
\r
705 * @brief Get current base status
\r
706 * @param[in] Base Base type, should be:
\r
707 * - CGU_BASE_USB0 :Base clock for USB0
\r
708 * - CGU_BASE_USB1 :Base clock for USB1
\r
709 * - CGU_BASE_M3 :System base clock for ARM Cortex-M3 core
\r
710 * and APB peripheral blocks #0 and #2
\r
711 * - CGU_BASE_SPIFI :Base clock for SPIFI
\r
712 * - CGU_BASE_APB1 :Base clock for APB peripheral block #1
\r
713 * - CGU_BASE_APB3 :Base clock for APB peripheral block #3
\r
714 * - CGU_BASE_SDIO :Base clock for SDIO card reader
\r
715 * - CGU_BASE_SSP0 :Base clock for SSP0
\r
716 * - CGU_BASE_SSP1 :Base clock for SSP1
\r
717 * - CGU_BASE_UART0 :Base clock for UART0
\r
718 * - CGU_BASE_UART1 :Base clock for UART1
\r
719 * - CGU_BASE_UART2 :Base clock for UART2
\r
720 * - CGU_BASE_UART3 :Base clock for UART3
\r
721 * @return Always return 0
\r
722 **********************************************************************/
\r
723 uint32_t CGU_GetBaseStatus(CGU_ENTITY_T Base){
\r
726 case CGU_BASE_APB3:
\r
727 return LPC_CCU1->BASE_STAT & 1;
\r
729 case CGU_BASE_APB1:
\r
730 return (LPC_CCU1->BASE_STAT>>1) & 1;
\r
732 case CGU_BASE_SPIFI:
\r
733 return (LPC_CCU1->BASE_STAT>>2) & 1;
\r
736 return (LPC_CCU1->BASE_STAT>>3) & 1;
\r
738 case CGU_BASE_USB0:
\r
739 return (LPC_CCU1->BASE_STAT>>7) & 1;
\r
741 case CGU_BASE_USB1:
\r
742 return (LPC_CCU1->BASE_STAT>>8) & 1;
\r
745 case CGU_BASE_UART3:
\r
746 return (LPC_CCU2->BASE_STAT>>1) & 1;
\r
748 case CGU_BASE_UART2:
\r
749 return (LPC_CCU2->BASE_STAT>>2) & 1;
\r
751 case CGU_BASE_UART1:
\r
752 return (LPC_CCU2->BASE_STAT>>3) & 1;
\r
754 case CGU_BASE_UART0:
\r
755 return (LPC_CCU2->BASE_STAT>>4) & 1;
\r
757 case CGU_BASE_SSP1:
\r
758 return (LPC_CCU2->BASE_STAT>>5) & 1;
\r
760 case CGU_BASE_SSP0:
\r
761 return (LPC_CCU2->BASE_STAT>>6) & 1;
\r
763 case CGU_BASE_SDIO:
\r
764 return (LPC_CCU2->BASE_STAT>>7) & 1;
\r
766 /*BASE SAFE is used by WWDT and RGU*/
\r
767 case CGU_BASE_SAFE:
\r
776 /*********************************************************************//**
\r
777 * @brief Compare one source clock to IRC clock
\r
778 * @param[in] Clock Clock entity that will be compared to IRC, should be:
\r
779 * - CGU_CLKSRC_32KHZ_OSC :32Khz crystal oscillator
\r
780 * - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock
\r
781 * - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock
\r
782 * - CGU_CLKSRC_GP_CLKIN :General purpose input clock
\r
783 * - CGU_CLKSRC_XTAL_OSC :Crystal oscillator
\r
784 * - CGU_CLKSRC_PLL0 :PLL0 clock
\r
785 * - CGU_CLKSRC_PLL1 :PLL1 clock
\r
786 * - CGU_CLKSRC_IDIVA :Integer divider register A
\r
787 * - CGU_CLKSRC_IDIVB :Integer divider register B
\r
788 * - CGU_CLKSRC_IDIVC :Integer divider register C
\r
789 * - CGU_CLKSRC_IDIVD :Integer divider register D
\r
790 * - CGU_CLKSRC_IDIVE :Integer divider register E
\r
791 * - CGU_BASE_SAFE :Base safe clock (always on)for WDT
\r
792 * - CGU_BASE_USB0 :Base clock for USB0
\r
793 * - CGU_BASE_USB1 :Base clock for USB1
\r
794 * - CGU_BASE_M3 :System base clock for ARM Cortex-M3 core
\r
795 * and APB peripheral blocks #0 and #2
\r
796 * - CGU_BASE_SPIFI :Base clock for SPIFI
\r
797 * - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx
\r
798 * - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx
\r
799 * - CGU_BASE_APB1 :Base clock for APB peripheral block #1
\r
800 * - CGU_BASE_APB3 :Base clock for APB peripheral block #3
\r
801 * - CGU_BASE_LCD :Base clock for LCD
\r
802 * - CGU_BASE_SDIO :Base clock for SDIO card reader
\r
803 * - CGU_BASE_SSP0 :Base clock for SSP0
\r
804 * - CGU_BASE_SSP1 :Base clock for SSP1
\r
805 * - CGU_BASE_UART0 :Base clock for UART0
\r
806 * - CGU_BASE_UART1 :Base clock for UART1
\r
807 * - CGU_BASE_UART2 :Base clock for UART2
\r
808 * - CGU_BASE_UART3 :Base clock for UART3
\r
809 * - CGU_BASE_CLKOUT :Base clock for CLKOUT pin
\r
810 * @param[in] m Multiple value pointer
\r
811 * @param[in] d Divider value pointer
\r
812 * @return Compare status, could be:
\r
815 * @note Formula used to compare:
\r
816 * FClock = F_IRC* m / d
\r
817 **********************************************************************/
\r
818 int CGU_FrequencyMonitor(CGU_ENTITY_T Clock, uint32_t *m, uint32_t *d){
\r
822 /* Maximum allow RCOUNT number */
\r
824 /* Check Source Clock Freq is larger or smaller */
\r
825 LPC_CGU->FREQ_MON = (Clock<<24) | 1<<23 | c;
\r
826 while(LPC_CGU->FREQ_MON & (1 <<23));
\r
827 for(i=0;i<10000;i++);
\r
828 temp = (LPC_CGU->FREQ_MON >>9) & 0x3FFF;
\r
830 if(temp == 0) /* too low F < 12000000/511*/
\r
832 if(temp > 511){ /* larger */
\r
834 c = 511 - (LPC_CGU->FREQ_MON&0x1FF);
\r
838 LPC_CGU->FREQ_MON = (Clock<<24) | 1<<23 | c;
\r
839 while(LPC_CGU->FREQ_MON & (1 <<23));
\r
840 for(i=0;i<10000;i++);
\r
841 n = (LPC_CGU->FREQ_MON >>9) & 0x3FFF;
\r
850 /*********************************************************************//**
\r
851 * @brief Compare one source clock to another source clock
\r
852 * @param[in] Clock Clock entity that will be compared to second source, should be:
\r
853 * - CGU_CLKSRC_32KHZ_OSC :32Khz crystal oscillator
\r
854 * - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock
\r
855 * - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock
\r
856 * - CGU_CLKSRC_GP_CLKIN :General purpose input clock
\r
857 * - CGU_CLKSRC_XTAL_OSC :Crystal oscillator
\r
858 * - CGU_CLKSRC_PLL0 :PLL0 clock
\r
859 * - CGU_CLKSRC_PLL1 :PLL1 clock
\r
860 * - CGU_CLKSRC_IDIVA :Integer divider register A
\r
861 * - CGU_CLKSRC_IDIVB :Integer divider register B
\r
862 * - CGU_CLKSRC_IDIVC :Integer divider register C
\r
863 * - CGU_CLKSRC_IDIVD :Integer divider register D
\r
864 * - CGU_CLKSRC_IDIVE :Integer divider register E
\r
865 * - CGU_BASE_SAFE :Base safe clock (always on)for WDT
\r
866 * - CGU_BASE_USB0 :Base clock for USB0
\r
867 * - CGU_BASE_USB1 :Base clock for USB1
\r
868 * - CGU_BASE_M3 :System base clock for ARM Cortex-M3 core
\r
869 * and APB peripheral blocks #0 and #2
\r
870 * - CGU_BASE_SPIFI :Base clock for SPIFI
\r
871 * - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx
\r
872 * - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx
\r
873 * - CGU_BASE_APB1 :Base clock for APB peripheral block #1
\r
874 * - CGU_BASE_APB3 :Base clock for APB peripheral block #3
\r
875 * - CGU_BASE_LCD :Base clock for LCD
\r
876 * - CGU_BASE_SDIO :Base clock for SDIO card reader
\r
877 * - CGU_BASE_SSP0 :Base clock for SSP0
\r
878 * - CGU_BASE_SSP1 :Base clock for SSP1
\r
879 * - CGU_BASE_UART0 :Base clock for UART0
\r
880 * - CGU_BASE_UART1 :Base clock for UART1
\r
881 * - CGU_BASE_UART2 :Base clock for UART2
\r
882 * - CGU_BASE_UART3 :Base clock for UART3
\r
883 * - CGU_BASE_CLKOUT :Base clock for CLKOUT pin
\r
884 * @param[in] CompareToClock Clock source that to be compared to first source, should be different
\r
886 * @param[in] m Multiple value pointer
\r
887 * @param[in] d Divider value pointer
\r
888 * @return Compare status, could be:
\r
891 * @note Formula used to compare:
\r
892 * FClock = m*FCompareToClock/d
\r
893 **********************************************************************/
\r
894 uint32_t CGU_RealFrequencyCompare(CGU_ENTITY_T Clock, CGU_ENTITY_T CompareToClock, uint32_t *m, uint32_t *d){
\r
895 uint32_t m1,m2,d1,d2;
\r
896 /* Check Parameter */
\r
897 if((Clock>CGU_CLKSRC_IDIVE) || (CompareToClock>CGU_CLKSRC_IDIVE))
\r
898 return CGU_ERROR_INVALID_PARAM;
\r
899 /* Check for Clock Enable - Not yet implement
\r
900 * The Comparator will hang if Clock has not been set*/
\r
901 CGU_FrequencyMonitor(Clock, &m1, &d1);
\r
902 CGU_FrequencyMonitor(CompareToClock, &m2, &d2);
\r
916 /* --------------------------------- End Of File ------------------------------ */
\r