1 /**
2 * @file xmc_rtc.c
3 * @date 2019-05-07
4 *
5 * @cond
6 *****************************************************************************
7 * XMClib v2.2.0 - XMC Peripheral Driver Library
8 *
9 * Copyright (c) 2015-2020, Infineon Technologies AG
10 * All rights reserved.
11 *
12 * Boost Software License - Version 1.0 - August 17th, 2003
13 *
14 * Permission is hereby granted, free of charge, to any person or organization
15 * obtaining a copy of the software and accompanying documentation covered by
16 * this license (the "Software") to use, reproduce, display, distribute,
17 * execute, and transmit the Software, and to prepare derivative works of the
18 * Software, and to permit third-parties to whom the Software is furnished to
19 * do so, all subject to the following:
20 *
21 * The copyright notices in the Software and this entire statement, including
22 * the above license grant, this restriction and the following disclaimer,
23 * must be included in all copies of the Software, in whole or in part, and
24 * all derivative works of the Software, unless such copies or derivative
25 * works are solely in the form of machine-executable object code generated by
26 * a source language processor.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
31 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
32 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
33 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
34 * DEALINGS IN THE SOFTWARE.
35 *
36 * To improve the quality of the software, users are encouraged to share
37 * modifications, enhancements or bug fixes with Infineon Technologies AG
38 * at XMCSupport@infineon.com.
39 *****************************************************************************
40 *
41 * Change History
42 * --------------
43 *
44 * 2015-02-20:
45 * - Initial <br>
46 *
47 * 2015-06-20:
48 * - Removed GetDriverVersion API
49 *
50 * 2016-05-19:
51 * - Added XMC_RTC_SetTimeStdFormat() and XMC_RTC_SetAlarmStdFormat()
52 *
53 * 2018-06-21:
54 * - Fixed value of XMC_RTC_MAXSECONDS, XMC_RTC_MAXMINUTES, XMC_RTC_MAXHOURS
macros
55 * - Fixed assertion on XMC_RTC_MAXDAYS
56 *
57 * 2019-05-07:
58 * - Fixed compilation warnings
59 *
60 * @endcond
61 *
62 */
63
64 /**
65 *
66 * @brief RTC driver for XMC microcontroller family.
67 *
68 */
69
70 /*************************************************************************************
********************************
71 * HEADER FILES
72
*************************************************************************************
********************************/
73
74 #include "xmc_scu.h"
75 #include "xmc_rtc.h"
76
77 /*************************************************************************************
********************************
78 * MACROS
79
*************************************************************************************
********************************/
80
81 #define XMC_RTC_MAXSECONDS (60U) /**< RTC time : Maximum seconds */
82 #define XMC_RTC_MAXMINUTES (60U) /**< RTC time : Maximum minutes */
83 #define XMC_RTC_MAXHOURS (24U) /**< RTC time : Maximum hours */
84 #define XMC_RTC_MAXDAYS (31U) /**< RTC time : Maximum days */
85 #define XMC_RTC_MAXDAYSOFWEEK (7U) /**< RTC time : Maximum days of week */
86 #define XMC_RTC_MAXMONTH (12U) /**< RTC time : Maximum month */
87 #define XMC_RTC_MAXYEAR (0xFFFFU) /**< RTC time : Maximum year */
88 #define XMC_RTC_MAXPRESCALER (0xFFFFU) /**< RTC time : Maximum prescaler */
89 #define XMC_RTC_YEAR_OFFSET (1900U) /**< RTC year offset : Year offset */
90
91 #if (UC_FAMILY == XMC4)
92 #define XMC_RTC_INIT_SEQUENCE (1U)
93 #endif
94 #if (UC_FAMILY == XMC1)
95 #define XMC_RTC_INIT_SEQUENCE (0U)
96 #endif
97
98 /*************************************************************************************
********************************
99 * API IMPLEMENTATION
100
*************************************************************************************
********************************/
101
102 /*
103 * Enables RTC peripheral to start counting time
104 */
105 void XMC_RTC_Start(void)
106 {
107 while ((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_CTR_Msk) != 0U)
108 {
109 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending
*/
110 }
111 RTC->CTR |= (uint32_t)RTC_CTR_ENB_Msk;
112 }
113
114 /*
115 * Disables RTC peripheral to start counting time
116 */
117 void XMC_RTC_Stop(void)
118 {
119 while ((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_CTR_Msk) != 0U)
120 {
121 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending
*/
122 }
123 RTC->CTR &= ~(uint32_t)RTC_CTR_ENB_Msk;
124 }
125
126 /*
127 * Sets the RTC module prescaler value
128 */
129 void XMC_RTC_SetPrescaler(uint16_t prescaler)
130 {
131 XMC_ASSERT("XMC_RTC_SetPrescaler:Wrong prescaler value", (prescaler <
XMC_RTC_MAXPRESCALER));
132
133 while ((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_CTR_Msk) != 0U)
134 {
135 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending
*/
136 }
137 RTC->CTR = (RTC->CTR & ~(uint32_t)RTC_CTR_DIV_Msk) |
138 ((uint32_t)prescaler << (uint32_t)RTC_CTR_DIV_Pos);
139 }
140
141 /*
142 * Sets the RTC_TIM0, RTC_TIM1 registers with time values
143 */
144 void XMC_RTC_SetTime(const XMC_RTC_TIME_t *const time)
145 {
146 XMC_ASSERT("XMC_RTC_SetTime:Wrong seconds value", ((uint32_t)time->seconds <
XMC_RTC_MAXSECONDS));
147 XMC_ASSERT("XMC_RTC_SetTime:Wrong minutes value", ((uint32_t)time->minutes <
XMC_RTC_MAXMINUTES));
148 XMC_ASSERT("XMC_RTC_SetTime:Wrong hours value", ((uint32_t)time->hours <
XMC_RTC_MAXHOURS));
149 XMC_ASSERT("XMC_RTC_SetTime:Wrong week day value", ((uint32_t)time->daysofweek <
XMC_RTC_MAXDAYSOFWEEK));
150 XMC_ASSERT("XMC_RTC_SetTime:Wrong month value", ((uint32_t)time->month <
XMC_RTC_MAXMONTH));
151 XMC_ASSERT("XMC_RTC_SetTime:Wrong year value", ((uint32_t)time->year <
XMC_RTC_MAXYEAR));
152
153 #if (XMC_RTC_INIT_SEQUENCE == 1U)
154 while ((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_TIM0_Msk) != 0U)
155 {
156 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending
*/
157 }
158 RTC->TIM0 = time->raw0;
159
160 while ((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_TIM1_Msk) != 0U)
161 {
162 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending
*/
163 }
164 RTC->TIM1 = time->raw1;
165 #endif
166 #if (XMC_RTC_INIT_SEQUENCE == 0U)
167 while ((XMC_SCU_GetMirrorStatus() & (SCU_GENERAL_MIRRSTS_RTC_TIM0_Msk |
SCU_GENERAL_MIRRSTS_RTC_TIM1_Msk)) != 0U)
168 {
169 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending
*/
170 }
171 RTC->TIM0 = time->raw0;
172 RTC->TIM1 = time->raw1; ;
173 #endif
174 }
175
176 /*
177 * Gets the RTC module time value
178 */
179 void XMC_RTC_GetTime(XMC_RTC_TIME_t *const time)
180 {
181 time->raw0 = RTC->TIM0;
182 time->raw1 = RTC->TIM1;
183 }
184
185 /*
186 * Sets the RTC module time values in standard format
187 */
188 void XMC_RTC_SetTimeStdFormat(const struct tm *const stdtime)
189 {
190
191 XMC_RTC_TIME_t time;
192
193 time.seconds = stdtime->tm_sec;
194 time.minutes = stdtime->tm_min;
195 time.hours = stdtime->tm_hour;
196 time.days = stdtime->tm_mday - 1;
197 time.month = stdtime->tm_mon;
198 time.year = stdtime->tm_year + XMC_RTC_YEAR_OFFSET;
199 time.daysofweek = stdtime->tm_wday;
200
201 XMC_RTC_SetTime(&time);
202 }
203
204 /*
205 * Gets the RTC module time values in standard format
206 */
207 void XMC_RTC_GetTimeStdFormat(struct tm *const stdtime)
208 {
209 XMC_RTC_TIME_t time;
210 time.raw0 = RTC->TIM0;
211 time.raw1 = RTC->TIM1;
212
213 stdtime->tm_sec = (int8_t)time.seconds;
214 stdtime->tm_min = (int8_t)time.minutes;
215 stdtime->tm_hour = (int8_t)time.hours;
216 stdtime->tm_mday = ((int8_t)time.days + (int8_t)1);
217 stdtime->tm_mon = (int8_t)time.month;
218 stdtime->tm_year = (int32_t)time.year - (int32_t)XMC_RTC_YEAR_OFFSET;
219 stdtime->tm_wday = (int8_t)time.daysofweek;
220 }
221
222 /*
223 * Sets the RTC module alarm time value
224 */
225 void XMC_RTC_SetAlarm(const XMC_RTC_ALARM_t *const alarm)
226 {
227 XMC_ASSERT("XMC_RTC_SetAlarm:Wrong seconds value", ((uint32_t)alarm->seconds <
XMC_RTC_MAXSECONDS));
228 XMC_ASSERT("XMC_RTC_SetAlarm:Wrong minutes value", ((uint32_t)alarm->minutes <
XMC_RTC_MAXMINUTES));
229 XMC_ASSERT("XMC_RTC_SetAlarm:Wrong hours value", ((uint32_t)alarm->hours <
XMC_RTC_MAXHOURS));
230 XMC_ASSERT("XMC_RTC_SetAlarm:Wrong month value", ((uint32_t)alarm->month <
XMC_RTC_MAXMONTH));
231 XMC_ASSERT("XMC_RTC_SetAlarm:Wrong year value", ((uint32_t)alarm->year <
XMC_RTC_MAXYEAR));
232
233 #if (XMC_RTC_INIT_SEQUENCE == 1U)
234 while ((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_ATIM0_Msk) != 0U)
235 {
236 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending
*/
237 }
238 RTC->ATIM0 = alarm->raw0;
239
240 while ((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_ATIM1_Msk) != 0U)
241 {
242 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending
*/
243 }
244 RTC->ATIM1 = alarm->raw1;
245 #endif
246 #if (XMC_RTC_INIT_SEQUENCE == 0U)
247 while ((XMC_SCU_GetMirrorStatus() & (SCU_GENERAL_MIRRSTS_RTC_ATIM0_Msk |
SCU_GENERAL_MIRRSTS_RTC_ATIM1_Msk)) != 0U)
248 {
249 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending
*/
250 }
251 RTC->ATIM0 = alarm->raw0;
252 RTC->ATIM1 = alarm->raw1;
253 #endif
254 }
255
256 /*
257 * Gets the RTC module alarm time value
258 */
259 void XMC_RTC_GetAlarm(XMC_RTC_ALARM_t *const alarm)
260 {
261 alarm->raw0 = RTC->ATIM0;
262 alarm->raw1 = RTC->ATIM1;
263 }
264
265
266 /*
267 * Sets the RTC module alarm time value in standard format
268 */
269 void XMC_RTC_SetAlarmStdFormat(const struct tm *const stdtime)
270 {
271 XMC_RTC_ALARM_t alarm;
272
273
274 alarm.seconds = stdtime->tm_sec;
275 alarm.minutes = stdtime->tm_min;
276 alarm.hours = stdtime->tm_hour;
277 alarm.days = stdtime->tm_mday - 1;
278 alarm.month = stdtime->tm_mon;
279 alarm.year = stdtime->tm_year + XMC_RTC_YEAR_OFFSET;
280
281 XMC_RTC_SetAlarm(&alarm);
282 }
283
284 /*
285 * Gets the RTC module alarm time value in standard format
286 */
287 void XMC_RTC_GetAlarmStdFormat(struct tm *const stdtime)
288 {
289 XMC_RTC_ALARM_t alarm;
290
291 alarm.raw0 = RTC->ATIM0;
292 alarm.raw1 = RTC->ATIM1;
293
294 stdtime->tm_sec = (int8_t)alarm.seconds;
295 stdtime->tm_min = (int8_t)alarm.minutes;
296 stdtime->tm_hour = (int8_t)alarm.hours;
297 stdtime->tm_mday = ((int8_t)alarm.days + (int8_t)1);
298 stdtime->tm_mon = (int8_t)alarm.month;
299 stdtime->tm_year = (int32_t)alarm.year - (int32_t)XMC_RTC_YEAR_OFFSET;
300 }
301
302 /*
303 * Gets the RTC periodic and alarm event(s) status
304 */
305 uint32_t XMC_RTC_GetEventStatus(void)
306 {
307 return RTC->STSSR;
308 }
309