1 /*
2  * @brief RTC example with wakeup
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2013
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 
36 /*****************************************************************************
37  * Private types/enumerations/variables
38  ****************************************************************************/
39 
40 /* RTC interrupt flags */
41 static volatile bool rtcWake, rtcAlarm;
42 
43 /*****************************************************************************
44  * Public types/enumerations/variables
45  ****************************************************************************/
46 
47 /*****************************************************************************
48  * Private functions
49  ****************************************************************************/
50 
51 /*****************************************************************************
52  * Public functions
53  ****************************************************************************/
54 
55 /**
56  * @brief	RTC alarm interrupt Handler
57  * @return	None
58  */
RTC_ALARM_IRQHandler(void)59 void RTC_ALARM_IRQHandler(void)
60 {
61 	uint32_t rtcStatus;
62 
63 	Board_LED_Toggle(1);
64 
65 	/* Get RTC status register */
66 	rtcStatus = Chip_RTC_GetStatus(LPC_RTC);
67 
68 	/* Check RTC 1Khz match interrupt */
69 	if (rtcStatus & RTC_CTRL_ALARM1HZ) {
70 		/* Alarm */
71 		rtcAlarm = true;
72 	}
73 
74 	/* Clear only latched RTC alarm status */
75 	Chip_RTC_EnableOptions(LPC_RTC, rtcStatus & RTC_CTRL_ALARM1HZ);
76 }
77 
78 /**
79  * @brief	RTC wake interrupt Handler
80  * @return	None
81  */
RTC_WAKE_IRQHandler(void)82 void RTC_WAKE_IRQHandler(void)
83 {
84 	uint32_t rtcStatus;
85 
86 	Board_LED_Toggle(0);
87 
88 	/* Get RTC status register */
89 	rtcStatus = Chip_RTC_GetStatus(LPC_RTC);
90 
91 	/* Check RTC 1KHz match interrupt */
92 	if (rtcStatus & RTC_CTRL_WAKE1KHZ) {
93 		/* RTC high resultiuon wakeup interrupt */
94 		rtcWake = true;
95 	}
96 
97 	/* Clear only latched RTC wake status */
98 	Chip_RTC_EnableOptions(LPC_RTC, rtcStatus & RTC_CTRL_WAKE1KHZ);
99 }
100 
101 /**
102  * @brief	Main program body
103  * @return	int
104  */
main(void)105 int main(void)
106 {
107 	int stateCounter = 0;
108 	uint32_t ticks = 0;
109 
110 	/* Setup SystemCoreClock and any needed board code */
111 	SystemCoreClockUpdate();
112 	Board_Init();
113 
114 	/* Enable the RTC oscillator, oscillator rate can be determined by
115 	   calling Chip_Clock_GetRTCOscRate()	*/
116 	Chip_Clock_EnableRTCOsc();
117 
118 	/* Initialize RTC driver (enables RTC clocking) */
119 	Chip_RTC_Init(LPC_RTC);
120 
121 	/* Enable RTC as a peripheral wakeup event */
122 	Chip_SYSCTL_EnableERP1PeriphWakeup(SYSCTL_ERP1_WAKEUP_RTCALARMINT |
123 									   SYSCTL_ERP1_WAKEUP_RTCWAKEINT);
124 
125 	/* RTC reset */
126 	Chip_RTC_Reset(LPC_RTC);
127 
128 	/* Start RTC at a count of 0 when RTC is disabled. If the RTC is enabled, you
129 	   need to disable it before setting the initial RTC count. */
130 	Chip_RTC_Disable(LPC_RTC);
131 	Chip_RTC_SetCount(LPC_RTC, 0);
132 
133 	/* Set a long alarm time so the interrupt won't trigger */
134 	Chip_RTC_SetAlarm(LPC_RTC, 1000);
135 
136 	/* Enable RTC and high resolution timer - this can be done in a single
137 	   call with Chip_RTC_EnableOptions(LPC_RTC, (RTC_CTRL_RTC1KHZ_EN | RTC_CTRL_RTC_EN)); */
138 	Chip_RTC_Enable1KHZ(LPC_RTC);
139 	Chip_RTC_Enable(LPC_RTC);
140 
141 	/* Clear latched RTC interrupt statuses */
142 	Chip_RTC_ClearStatus(LPC_RTC, (RTC_CTRL_OFD | RTC_CTRL_ALARM1HZ | RTC_CTRL_WAKE1KHZ));
143 
144 	/* Enable RTC wake and alarm interrupts */
145 	NVIC_EnableIRQ(RTC_ALARM_IRQn);
146 	NVIC_EnableIRQ(RTC_WAKE_IRQn);
147 
148 	/* Enable RTC alarm interrupt */
149 	Chip_RTC_EnableWakeup(LPC_RTC, (RTC_CTRL_ALARMDPD_EN | RTC_CTRL_WAKEDPD_EN));
150 
151 	/* Sleep and do all the work in the RTC interrupt handler */
152 	while (1) {
153 		ticks = 0;
154 		DEBUGOUT("Tick number: %d, 1KHZ int:%d, alarm int:%d\r\n",
155 				 stateCounter, rtcWake, rtcAlarm);
156 		rtcWake = rtcAlarm = false;
157 
158 		/* 10 high resolution ticks that get slower each tick */
159 		if (stateCounter < 10) {
160 			/* Wakeup in 300, 400, 500, etc. milliSeconds */
161 			Chip_RTC_SetWake(LPC_RTC, (300 + (stateCounter * 100)));
162 
163 			stateCounter++;
164 		}
165 		else {
166 			DEBUGOUT("Setting alarm to wake up in 4s\r\n");
167 
168 			/* Set alarm to wakeup in 4 seconds */
169 			Chip_RTC_SetAlarm(LPC_RTC, Chip_RTC_GetCount(LPC_RTC) + 4);
170 
171 			stateCounter = 0;
172 		}
173 
174 		Chip_SYSCTL_SetWakeup(~(SYSCTL_SLPWAKE_IRCOUT_PD | SYSCTL_SLPWAKE_IRC_PD |
175 								SYSCTL_SLPWAKE_FLASH_PD | SYSCTL_SLPWAKE_SYSOSC_PD | SYSCTL_SLPWAKE_SYSPLL_PD));
176 		Chip_SYSCTL_EnableERP1PeriphWakeup(SYSCTL_ERP1_WAKEUP_RTCALARMINT | SYSCTL_ERP1_WAKEUP_RTCWAKEINT);
177 
178 		/* Delay to allow serial transmission to complete*/
179 		while(ticks++ < 10000) {}
180 
181 		/* Enter MCU Deep Sleep mode */
182 		Chip_PMU_DeepSleepState(LPC_PMU);
183 	}
184 
185 	return 0;
186 }
187