LPCOpen Platform for LPC18XX/43XX microcontrollers: C:/w/lpcopen_docs/software/lpc_core/lpc_chip/chip_common/rtc_ut.c Source File

| LPCOpen Platform for LPC18XX/43XX microcontrollers 18XX43XX LPCOpen Platform for the NXP LPC18XX/43XX family of Microcontrollers

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

rtc_ut.c
Go to the documentation of this file.
1 /*
2 * @brief RTC tick to (a more) Universal Time
3 * Adds conversion functions to use an RTC that only provides a
4 * seconds capability to provide "struct tm" support.
5 *
6 * @note
7 * Copyright(C) NXP Semiconductors, 2014
8 * All rights reserved.
9 *
10 * @par
11 * Software that is described herein is for illustrative purposes only
12 * which provides customers with programming information regarding the
13 * LPC products. This software is supplied "AS IS" without any warranties of
14 * any kind, and NXP Semiconductors and its licensor disclaim any and
15 * all warranties, express or implied, including all implied warranties of
16 * merchantability, fitness for a particular purpose and non-infringement of
17 * intellectual property rights. NXP Semiconductors assumes no responsibility
18 * or liability for the use of the software, conveys no license or rights under any
19 * patent, copyright, mask work right, or any other intellectual property rights in
20 * or to any products. NXP Semiconductors reserves the right to make changes
21 * in the software without notification. NXP Semiconductors also makes no
22 * representation or warranty that such application will be suitable for the
23 * specified use without further testing or modification.
24 *
25 * @par
26 * Permission to use, copy, modify, and distribute this software and its
27 * documentation is hereby granted, under NXP Semiconductors' and its
28 * licensor's relevant copyrights in the software, without fee, provided that it
29 * is used in conjunction with NXP Semiconductors microcontrollers. This
30 * copyright, permission, and disclaimer notice must appear in all copies of
31 * this code.
32 */
33
34 #include "rtc_ut.h"
35
36 /*****************************************************************************
37 * Private types/enumerations/variables
38 ****************************************************************************/
39
40 #define SECSPERMIN (60)
41 #define MINSPERHOUR (60)
42 #define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
43 #define HOURSPERDAY (24)
44 #define SECSPERDAY (SECSPERMIN * MINSPERHOUR * HOURSPERDAY)
45 #define DAYSPERWEEK (7)
46 #define MONETHSPERYEAR (12)
47 #define DAYSPERYEAR (365)
48 #define DAYSPERLEAPYEAR (366)
49
50 /* Days per month, LY is special */
51 static uint8_t daysPerMonth[2][MONETHSPERYEAR] = {
52 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, /* Normal year */
53 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, /* Leap year */
54 };
55
56 /*****************************************************************************
57 * Public types/enumerations/variables
58 ****************************************************************************/
59
60 /*****************************************************************************
61 * Private functions
62 ****************************************************************************/
63
64 /* Converts the number of days offset from the start year to real year
65 data accounting for leap years */
66 static void GetDMLY(int dayOff, struct tm *pTime)
67 {
68 bool YearFound = false;
69 int daysYear = dayOff;
70 int leapYear, curLeapYear, year = TM_YEAR_BASE, monthYear = 0;
71 bool MonthFound = false;
72
73 /* Leap year check for less than 1 year time */
74 if ((year % 4) == 0) {
75 curLeapYear = 1;
76 }
77 else {
78 curLeapYear = 0;
79 }
80
81 /* Determine offset of years from days offset */
82 while (YearFound == false) {
83 if ((year % 4) == 0) {
84 /* Leap year, 366 days */
85 daysYear = DAYSPERLEAPYEAR;
86 leapYear = 1;
87 }
88 else {
89 /* Leap year, 365 days */
90 daysYear = DAYSPERYEAR;
91 leapYear = 0;
92 }
93
94 if (dayOff > daysYear) {
95 dayOff -= daysYear;
96 year++;
97 }
98 else {
99 YearFound = true;
100 curLeapYear = leapYear; /* In a leap year */
101 }
102 }
103
104 /* Save relative year and day into year */
105 pTime->tm_year = year - TM_YEAR_BASE; /* Base year relative */
106 pTime->tm_yday = dayOff;/* 0 relative */
107
108 /* Determine offset of months from days offset */
109 while (MonthFound == false) {
110 if ((dayOff + 1) > daysPerMonth[curLeapYear][monthYear]) {
111 /* Next month */
112 dayOff -= daysPerMonth[curLeapYear][monthYear];
113 monthYear++;
114 }
115 else {
116 /* Month found */
117 MonthFound = true;
118 }
119 }
120
121 pTime->tm_mday = dayOff + 1;/* 1 relative */
122 pTime->tm_mon = monthYear; /* 0 relative */
123 }
124
125 /*****************************************************************************
126 * Public functions
127 ****************************************************************************/
128
129 /* Converts an RTC tick time to Universal time */
130 void ConvertRtcTime(uint32_t rtcTick, struct tm *pTime)
131 {
132 int daySeconds, dayNum;
133
134 /* Get day offset and seconds since start */
135 dayNum = (int) (rtcTick / SECSPERDAY);
136 daySeconds = (int) (rtcTick % SECSPERDAY);
137
138 /* Fill in secs, min, hours */
139 pTime->tm_sec = daySeconds % 60;
140 pTime->tm_hour = daySeconds / SECSPERHOUR;
141 pTime->tm_min = (daySeconds - (pTime->tm_hour * SECSPERHOUR)) / SECSPERMIN;
142
143 /* Weekday, 0 = Sunday, 6 = Saturday */
144 pTime->tm_wday = (dayNum + TM_DAYOFWEEK) % DAYSPERWEEK;
145
146 /* Get year, month, day of month, and day of year */
147 GetDMLY(dayNum, pTime);
148
149 /* Not supported in this driver */
150 pTime->tm_isdst = 0;
151 }
152
153 /* Converts a Universal time to RTC tick time */
154 void ConvertTimeRtc(struct tm *pTime, uint32_t *rtcTick)
155 {
156 int leapYear, year = pTime->tm_year + TM_YEAR_BASE;
157 uint32_t dayOff, monthOff, monthCur, rtcTicks = 0;
158
159 /* Leap year check for less than 1 year time */
160 if ((year % 4) == 0) {
161 leapYear = 1;
162 }
163 else {
164 leapYear = 0;
165 }
166
167 /* Add days for each year and leap year */
168 while (year > TM_YEAR_BASE) {
169 if ((year % 4) == 0) {
170 /* Leap year, 366 days */
171 rtcTicks += DAYSPERLEAPYEAR * SECSPERDAY;
172 leapYear = 1;
173 }
174 else {
175 /* Leap year, 365 days */
176 rtcTicks += DAYSPERYEAR * SECSPERDAY;
177 leapYear = 0;
178 }
179
180 year--;
181 }
182
183 /* Day and month are 0 relative offsets since day and month
184 start at 1 */
185 dayOff = (uint32_t) pTime->tm_mday - 1;
186 monthOff = (uint32_t) pTime->tm_mon;
187
188 /* Add in seconds for passed months */
189 for (monthCur = 0; monthCur < monthOff; monthCur++) {
190 rtcTicks += (uint32_t) (daysPerMonth[leapYear][monthCur] * SECSPERDAY);
191 }
192
193 /* Add in seconds for day offset into the current month */
194 rtcTicks += (dayOff * SECSPERDAY);
195
196 /* Add in seconds for hours, minutes, and seconds */
197 rtcTicks += (uint32_t) (pTime->tm_hour * SECSPERHOUR);
198 rtcTicks += (uint32_t) (pTime->tm_min * SECSPERMIN);
199 rtcTicks += (uint32_t) pTime->tm_sec;
200
201 *rtcTick = rtcTicks;
202 }