| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
app_pmc_states.c
Go to the documentation of this file.
1 /*
2 * @brief Power Management Controller example
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * All rights reserved.
7 *
8 * @par
9 * Software that is described herein is for illustrative purposes only
10 * which provides customers with programming information regarding the
11 * LPC products. This software is supplied "AS IS" without any warranties of
12 * any kind, and NXP Semiconductors and its licensor disclaim any and
13 * all warranties, express or implied, including all implied warranties of
14 * merchantability, fitness for a particular purpose and non-infringement of
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
16 * or liability for the use of the software, conveys no license or rights under any
17 * patent, copyright, mask work right, or any other intellectual property rights in
18 * or to any products. NXP Semiconductors reserves the right to make changes
19 * in the software without notification. NXP Semiconductors also makes no
20 * representation or warranty that such application will be suitable for the
21 * specified use without further testing or modification.
22 *
23 * @par
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, under NXP Semiconductors' and its
26 * licensor's relevant copyrights in the software, without fee, provided that it
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
28 * copyright, permission, and disclaimer notice must appear in all copies of
29 * this code.
30 */
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include "board.h"
35 #include "chip.h"
36
76 /*****************************************************************************
77 * Private types/enumerations/variables
78 ****************************************************************************/
79
80 #define RTC_ALARM_TIME 5
82 /* Structure for initial base clock states */
83 struct CLK_BASE_STATES {
84 CHIP_CGU_BASE_CLK_T clk; /* Base clock */
85 CHIP_CGU_CLKIN_T clkin; /* Base clock source, see UM for allowable souorces per base clock */
86 bool autoblock_enab;/* Set to true to enable autoblocking on frequency change */
87 bool powerdn; /* Set to true if the base clock is initially powered down */
88 };
89
90 static char menu[] =
91 "\r\n==========================================================================\r\n"
92 "NXP Semiconductors LPC18xx/43xx MCU Power Management Controller example \r\n"
93 "=============================================================================\r\n"
94 "Select the power state test to be executed \r\n"
95 " - Sleep state & Wake up test : Press '1' to select \r\n"
96 " - Deep Sleep state & Wake up test : Press '2' to select \r\n"
97 " - Power down state & Wake up test : Press '3' to select \r\n"
98 " - Deep power down state & Wake up test : Press '4' to select \r\n"
99 " - Exit the demo : Press 'X' or 'x' to select \r\n"
100 "=============================================================================\r\n";
101 static char menu1[] = "\r\nSelect the Wake up signal \r\n"
102 " - WAKEUP0 pin : Press 'W' or 'w' to select \r\n"
103 " - RTC Alarm : Press 'R' or 'r' to select \r\n";
104
105 static char menu2[] = "PMC demo example terimnated \r\n";
106 static char menu3[] = "\r\nPress 'C' or 'c' to start demo...\r\n";
107
108 /* Initial base clock states are mostly on */
109 static struct CLK_BASE_STATES InitClkStates[] = {
110 {CLK_BASE_SAFE, CLKIN_IRC, true, false},
111 {CLK_BASE_APB1, CLKIN_MAINPLL, true, false},
112 {CLK_BASE_APB3, CLKIN_MAINPLL, true, false},
113 {CLK_BASE_USB0, CLKIN_USBPLL, true, true},
114 #if defined(CHIP_LPC43XX)
115 {CLK_BASE_PERIPH, CLKIN_MAINPLL, true, false},
116 {CLK_BASE_SPI, CLKIN_MAINPLL, true, false},
117 {CLK_BASE_VADC, CLKIN_MAINPLL, true, true},
118 #endif
119 {CLK_BASE_PHY_TX, CLKIN_ENET_TX, true, false},
120 #if defined(USE_RMII)
121 {CLK_BASE_PHY_RX, CLKIN_ENET_TX, true, false},
122 #else
123 {CLK_BASE_PHY_RX, CLKIN_ENET_RX, true, false},
124 #endif
125 {CLK_BASE_SDIO, CLKIN_MAINPLL, true, false},
126 {CLK_BASE_SSP0, CLKIN_MAINPLL, true, false},
127 {CLK_BASE_SSP1, CLKIN_MAINPLL, true, false},
128 {CLK_BASE_UART0, CLKIN_MAINPLL, true, false},
129 {CLK_BASE_UART1, CLKIN_MAINPLL, true, false},
130 {CLK_BASE_UART2, CLKIN_MAINPLL, true, false},
131 {CLK_BASE_UART3, CLKIN_MAINPLL, true, false},
132 // {CLK_BASE_OUT, CLKINPUT_PD, true, false},
133 // {CLK_BASE_APLL, CLKINPUT_PD, true, false},
134 // {CLK_BASE_CGU_OUT0, CLKINPUT_PD, true, false},
135 // {CLK_BASE_CGU_OUT1, CLKINPUT_PD, true, false},
136 {CLK_BASE_LCD, CLKIN_IDIVC, true, false},
137 {CLK_BASE_USB1, CLKIN_IDIVD, true, true},
138 };
139
140 /*****************************************************************************
141 * Public types/enumerations/variables
142 ****************************************************************************/
143
144 /*****************************************************************************
145 * Private functions
146 ****************************************************************************/
147 static void PMC_Get_Wakeup_option(uint8_t *Wakeup_rtc)
148 {
149 FlagStatus exitflag;
150 uint8_t buffer = 0xFF;
151
152 DEBUGOUT(menu1);
153
154 exitflag = RESET;
155 while (exitflag == RESET) {
156
157 /* Get user input */
158 buffer = DEBUGIN();
159
160 if ((buffer == 'W') || (buffer == 'w')) {
161 DEBUGOUT("WAKEUP0 pin selected \r\n");
162 *Wakeup_rtc = 0;
163 exitflag = SET;
164 }
165
166 if ((buffer == 'R') || (buffer == 'r')) {
167 DEBUGOUT("RTC Alarm selected \r\n");
168 *Wakeup_rtc = 1;
169 exitflag = SET;
170 }
171 }
172 }
173
178 static void PMC_Pre_SleepPowerDown(void)
179 {
180 int i;
181
182 #ifndef BOARD_NGX_XPLORER_18304330
183 /* SDRAM in self refresh mode only for Keil & Hitex boards */
184 LPC_EMC->DYNAMICCONTROL |= (1 << 2);
185 while (!(LPC_EMC->STATUS & (1 << 2))) {}
186 #endif
187
188 /* Shutdown perpheral clocks with wake up enabled */
189 Chip_Clock_StartPowerDown();
190
191 /* Get state of individual base clocks & store them for restoring.
192 * Sets up the IRC as base clock source
193 */
194 for (i = 0; i < (sizeof(InitClkStates) / sizeof(InitClkStates[0])); i++) {
195 /* Get the Base clock settings */
196 Chip_Clock_GetBaseClockOpts(InitClkStates[i].clk, &InitClkStates[i].clkin,
197 &InitClkStates[i].autoblock_enab, &InitClkStates[i].powerdn);
198
199 /* Set IRC as clock input for all the base clocks */
200 Chip_Clock_SetBaseClock(InitClkStates[i].clk, CLKIN_IRC, InitClkStates[i].autoblock_enab,
201 InitClkStates[i].powerdn);
202 }
203
204 /* Set IRC as clock source for SPIFI */
205 Chip_Clock_SetBaseClock(CLK_BASE_SPIFI, CLKIN_IRC, true, false);
206
207 /* Set IRC as source clock for Core */
208 Chip_Clock_SetBaseClock(CLK_BASE_MX, CLKIN_IRC, true, false);
209
210 #ifdef BOARD_KEIL_MCB_18574357
211 /* Set Flash acceleration */
212 Chip_CREG_SetFlashAcceleration(CRYSTAL_MAIN_FREQ_IN);
213 #endif
214
215 /* Power down the main PLL */
216 Chip_Clock_DisableMainPLL();
217 Chip_Clock_DisablePLL(CGU_USB_PLL);
218 Chip_Clock_DisableCrystal();
219 }
220
224 static void PMC_Post_Wakeup(uint8_t buffer)
225 {
226 int i;
227
228 #ifdef BOARD_KEIL_MCB_18574357
229 /* Setup FLASH acceleration to target clock rate prior to clock switch */
230 Chip_CREG_SetFlashAcceleration(MAX_CLOCK_FREQ);
231 #endif
232
233 /* Reinitialise Clocks */
234 Chip_Clock_SetBaseClock(CLK_BASE_MX, CLKIN_CRYSTAL, true, false);
235
236 /* Setup PLL for 100MHz and switch main system clocking */
237 Chip_Clock_SetupMainPLLHz(CLKIN_CRYSTAL, CRYSTAL_MAIN_FREQ_IN, 100 * 1000000, 100 * 1000000);
238 Chip_Clock_SetBaseClock(CLK_BASE_MX, CLKIN_MAINPLL, true, false);
239
240 /* Setup PLL for maximum clock */
241 Chip_Clock_SetupMainPLLHz(CLKIN_CRYSTAL, CRYSTAL_MAIN_FREQ_IN, MAX_CLOCK_FREQ, MAX_CLOCK_FREQ);
242
243 /* Restore the base clock states */
244 for (i = 0; i < (sizeof(InitClkStates) / sizeof(InitClkStates[0])); i++) {
245 Chip_Clock_SetBaseClock(InitClkStates[i].clk, InitClkStates[i].clkin,
246 InitClkStates[i].autoblock_enab, InitClkStates[i].powerdn);
247 }
248
249 /* Reset and enable 32Khz oscillator */
250 LPC_CREG->CREG0 &= ~((1 << 3) | (1 << 2));
251 LPC_CREG->CREG0 |= (1 << 1) | (1 << 0);
252
253 /* Setup a divider E for main PLL clock switch SPIFI clock to that divider.
254 Divide rate is based on CPU speed and speed of SPI FLASH part. */
255 #if (MAX_CLOCK_FREQ > 180000000)
256 Chip_Clock_SetDivider(CLK_IDIV_E, CLKIN_MAINPLL, 5);
257 #else
258 Chip_Clock_SetDivider(CLK_IDIV_E, CLKIN_MAINPLL, 4);
259 #endif
260 Chip_Clock_SetBaseClock(CLK_BASE_SPIFI, CLKIN_IDIVE, true, false);
261
262 /* Attach main PLL clock to divider C with a divider of 2 */
263 Chip_Clock_SetDivider(CLK_IDIV_C, CLKIN_MAINPLL, 2);
264
265 /* Re-Initialize debug UART
266 * � 115200bps
267 * � 8 data bit
268 * � No parity
269 * � 1 stop bit
270 * � No flow control
271 */
272 DEBUGINIT();
273
274 #ifndef BOARD_NGX_XPLORER_18304330
275 /* SDRAM in NORMAL mode, only for Keil & Hitex boards */
276 LPC_EMC->DYNAMICCONTROL &= ~(1 << 2);
277 while (LPC_EMC->STATUS & (1 << 2)) {}
278 #endif
279 }
280
284 static void PMC_Evrt_Configure(CHIP_EVRT_SRC_T Evrt_Src)
285 {
286 /* Configure Interrupt signal from Evrt_Src pin to EVRT */
287 Chip_EVRT_ConfigIntSrcActiveType(Evrt_Src, EVRT_SRC_ACTIVE_RISING_EDGE);
288
289 /* Enable interrupt signal from Evrt_Src pin to EVRT */
290 Chip_EVRT_SetUpIntSrc(Evrt_Src, ENABLE);
291
292 /* Clear any pending interrupt */
293 Chip_EVRT_ClrPendIntSrc(Evrt_Src);
294
295 /* Disable EVRT interrupt in NVIC */
296 NVIC_DisableIRQ(EVENTROUTER_IRQn);
297
298 /* preemption = 1, sub-priority = 1 */
299 NVIC_SetPriority(EVENTROUTER_IRQn, ((0x01 << 3) | 0x01));
300
301 /* Enable Event Router interrupt in NVIC */
302 NVIC_EnableIRQ(EVENTROUTER_IRQn);
303 }
304
308 static void PMC_PwrState_Handler(uint8_t buffer, uint8_t Wake_RTC)
309 {
310 CHIP_EVRT_SRC_T Evrt_Src;
311 CHIP_PMC_PWR_STATE_T Pwr_state;
312 uint8_t confirm = 0xFF;
313
314 if (Wake_RTC) {
315 /* Configure EVRT_SRC_RTC as wake up signal */
316 Evrt_Src = EVRT_SRC_RTC;
317
318 /* Disable interrupt signal from Evrt_Src pin to EVRT */
319 Chip_EVRT_SetUpIntSrc(Evrt_Src, DISABLE);
320
321 /* Initialize and configure RTC */
322 Chip_RTC_Init(LPC_RTC);
323 Chip_RTC_ResetClockTickCounter(LPC_RTC);
324 Chip_RTC_SetTime(LPC_RTC, RTC_TIMETYPE_SECOND, 0);
325
326 /* Set alarm time = RTC_ALARM_TIME seconds.
327 * So after each RTC_ALARM_TIME seconds, RTC will generate and wake-up system
328 */
329 Chip_RTC_SetAlarmTime(LPC_RTC, RTC_TIMETYPE_SECOND, RTC_ALARM_TIME);
330 Chip_RTC_CntIncrIntConfig(LPC_RTC, RTC_AMR_CIIR_IMSEC, DISABLE);
331
332 /* Set the AMR for RTC_ALARM_TIME match alarm interrupt */
333 Chip_RTC_AlarmIntConfig(LPC_RTC, RTC_AMR_CIIR_IMSEC, ENABLE);
334 Chip_RTC_ClearIntPending(LPC_RTC, RTC_INT_ALARM);
335 }
336 else {
337 Evrt_Src = EVRT_SRC_WAKEUP0;
338 }
339
340 /* Configure wake up signal */
341 PMC_Evrt_Configure(Evrt_Src);
342
343 /* Get confirmation from user to continue
344 * Print wake up signal information to user
345 */
346 DEBUGOUT(menu3);
347 while ( (confirm != 'C') && (confirm != 'c')) {
348 confirm = DEBUGIN();
349 }
350
351 switch (buffer) {
352 case '1':
353 DEBUGOUT("Entering 'Sleep' state ...\r\n");
354 if (Wake_RTC) {
355 DEBUGOUT("Wait for %d seconds, RTC alarm will wake up from 'Sleep' mode \r\n", RTC_ALARM_TIME);
356 Chip_RTC_Enable(LPC_RTC, ENABLE);
357 }
358 else {
359 DEBUGOUT("Press WAKEUP0 button/Connect WAKEUP0 pin to 3.3V to exit 'Sleep' mode \r\n");
360 }
361 Chip_PMC_Sleep();
362 Chip_RTC_DeInit(LPC_RTC);
363 DEBUGOUT("Woken up \r\n");
364 break;
365
366 case '2':
367 DEBUGOUT("Entering 'Deep Sleep' state ...\r\n");
368 if (Wake_RTC) {
369 DEBUGOUT("Wait for %d seconds, RTC alarm will wake up from 'Deep Sleep' mode \r\n", RTC_ALARM_TIME);
370 Chip_RTC_Enable(LPC_RTC, ENABLE);
371 }
372 else {
373 DEBUGOUT("Press WAKEUP0 button/Connect WAKEUP0 pin to 3.3V to exit 'Deep Sleep' mode \r\n");
374 }
375 Pwr_state = PMC_DeepSleep;
376
377 /* Call Pre SleepPowerDown function */
378 PMC_Pre_SleepPowerDown();
379
380 /* Goto Deep Sleep mode */
381 Chip_PMC_Set_PwrState(Pwr_state);
382
383 /* Call Post Wake up Initialisation function */
384 PMC_Post_Wakeup(buffer);
385 DEBUGOUT("\r\nWoken up \r\n");
386 break;
387
388 case '3':
389 DEBUGOUT("Entering 'Power Down' state ...\r\n");
390 if (Wake_RTC) {
391 DEBUGOUT("Wait for %d seconds, RTC alarm will wake up from 'Power Down' mode \r\n", RTC_ALARM_TIME);
392 Chip_RTC_Enable(LPC_RTC, ENABLE);
393 }
394 else {
395 DEBUGOUT("Press WAKEUP0 button/Connect WAKEUP0 pin to 3.3V to exit 'Power Down' mode \r\n");
396 }
397 Pwr_state = PMC_PowerDown;
398
399 /* Call Pre SleepPowerDown function */
400 PMC_Pre_SleepPowerDown();
401
402 /* Goto Deep Sleep mode */
403 Chip_PMC_Set_PwrState(Pwr_state);
404
405 /* Call Post Wake up Initialisation function */
406 PMC_Post_Wakeup(buffer);
407
408 DEBUGOUT("\r\nWoken up \r\n");
409 break;
410
411 case '4':
412 DEBUGOUT("Entering 'Deep Power Down' state ...\r\n");
413 if (Wake_RTC) {
414 DEBUGOUT("Wait for %d seconds, RTC alarm will wake up from 'Deep Power Down' mode \r\n", RTC_ALARM_TIME);
415 Chip_RTC_Enable(LPC_RTC, ENABLE);
416 }
417 else {
418 DEBUGOUT("Press WAKEUP0 button/Connect WAKEUP0 pin to 3.3V to exit 'Deep Power Down' mode \r\n");
419 }
420 Pwr_state = PMC_DeepPowerDown;
421
422 /* Call Pre SleepPowerDown function */
423 PMC_Pre_SleepPowerDown();
424
425 /* Goto Deep Sleep mode */
426 Chip_PMC_Set_PwrState(Pwr_state);
427
428 /* Wake up from Deep power down state is as good as RESET */
429 while (1) {}
430 break;
431
432 default:
433 break;
434 }
435 }
436
437 /*****************************************************************************
438 * Public functions
439 ****************************************************************************/
440
445 void EVRT_IRQHandler(void)
446 {
447 if (Chip_EVRT_IsSourceInterrupting(EVRT_SRC_WAKEUP0)) {
448 Chip_EVRT_ClrPendIntSrc(EVRT_SRC_WAKEUP0);
449 NVIC_DisableIRQ(EVENTROUTER_IRQn);
450 }
451
452 if (Chip_EVRT_IsSourceInterrupting(EVRT_SRC_RTC)) {
453 if (Chip_RTC_GetIntPending(LPC_RTC, RTC_INT_ALARM)) {
454 Chip_RTC_ClearIntPending(LPC_RTC, RTC_INT_ALARM);
455 Chip_EVRT_ClrPendIntSrc(EVRT_SRC_RTC);
456 Chip_RTC_Enable(LPC_RTC, DISABLE);
457 NVIC_DisableIRQ(EVENTROUTER_IRQn);
458 }
459 }
460 }
461
466 int main(void)
467 {
468 FlagStatus exitflag;
469 uint8_t buffer = 0xFF;
470 uint8_t Wake_RTC = 0;
471
472 Board_Init();
473
474 /* Initialize the Event Router */
475 Chip_EVRT_Init();
476
477 /* Print user menu on UART console */
478 DEBUGOUT(menu);
479
480 exitflag = RESET;
481 /* Read user option from UART prompt */
482 while (exitflag == RESET) {
483
484 /* Get user input */
485 buffer = DEBUGIN();
486
487 switch (buffer) {
488 case '1': /* Sleep/Wake up Mode */
489 DEBUGOUT("'Sleep' state test selected \r\n");
490 PMC_Get_Wakeup_option(&Wake_RTC);
491 PMC_PwrState_Handler(buffer, Wake_RTC);
492 DEBUGOUT(menu);
493 break;
494
495 case '2': /* Deep sleep/Wakeup Mode */
496 DEBUGOUT("'Deep Sleep' state test selected \r\n");
497 PMC_Get_Wakeup_option(&Wake_RTC);
498 PMC_PwrState_Handler(buffer, Wake_RTC);
499 DEBUGOUT(menu);
500 break;
501
502 case '3': /* Power Down/Wakeup Mode */
503 DEBUGOUT("'Power Down' state test selected \r\n");
504 PMC_Get_Wakeup_option(&Wake_RTC);
505 PMC_PwrState_Handler(buffer, Wake_RTC);
506 DEBUGOUT(menu);
507 break;
508
509 case '4': /* Deep Power Down/Wakeup Mode */
510 DEBUGOUT("'Deep Power Down' state test selected \r\n");
511 PMC_Get_Wakeup_option(&Wake_RTC);
512 PMC_PwrState_Handler(buffer, Wake_RTC);
513 DEBUGOUT(menu);
514 break;
515
516 case 'X':
517 DEBUGOUT(menu2);
518 exitflag = SET;
519 break;
520
521 case 'x':
522 DEBUGOUT(menu2);
523 exitflag = SET;
524 break;
525 }
526 }
527
528 while (1) {}
529 }
530