1 /**
2 * @file xmc_rtc.c
3 * @date 2019-05-07
4 *
5 * @cond
6 *********************************************************************************************************************
7 * XMClib v2.1.24 - XMC Peripheral Driver Library
8 *
9 * Copyright (c) 2015-2019, Infineon Technologies AG
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the
13 * following conditions are met:
14 *
15 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
19 * disclaimer in the documentation and/or other materials provided with the distribution.
20 *
21 * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
22 * products derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes with
33 * Infineon Technologies AG dave@infineon.com).
34 *********************************************************************************************************************
35 *
36 * Change History
37 * --------------
38 *
39 * 2015-02-20:
40 * - Initial <br>
41 *
42 * 2015-06-20:
43 * - Removed GetDriverVersion API
44 *
45 * 2016-05-19:
46 * - Added XMC_RTC_SetTimeStdFormat() and XMC_RTC_SetAlarmStdFormat()
47 *
48 * 2018-06-21:
49 * - Fixed value of XMC_RTC_MAXSECONDS, XMC_RTC_MAXMINUTES, XMC_RTC_MAXHOURS macros
50 * - Fixed assertion on XMC_RTC_MAXDAYS
51 *
52 * 2019-05-07:
53 * - Fixed compilation warnings
54 *
55 * @endcond
56 *
57 */
58
59 /**
60 *
61 * @brief RTC driver for XMC microcontroller family.
62 *
63 */
64
65 /*********************************************************************************************************************
66 * HEADER FILES
67 *********************************************************************************************************************/
68
69 #include "xmc_scu.h"
70 #include "xmc_rtc.h"
71
72 /*********************************************************************************************************************
73 * MACROS
74 *********************************************************************************************************************/
75
76 #define XMC_RTC_MAXSECONDS (60U) /**< RTC time : Maximum seconds */
77 #define XMC_RTC_MAXMINUTES (60U) /**< RTC time : Maximum minutes */
78 #define XMC_RTC_MAXHOURS (24U) /**< RTC time : Maximum hours */
79 #define XMC_RTC_MAXDAYS (31U) /**< RTC time : Maximum days */
80 #define XMC_RTC_MAXDAYSOFWEEK (7U) /**< RTC time : Maximum days of week */
81 #define XMC_RTC_MAXMONTH (12U) /**< RTC time : Maximum month */
82 #define XMC_RTC_MAXYEAR (0xFFFFU) /**< RTC time : Maximum year */
83 #define XMC_RTC_MAXPRESCALER (0xFFFFU) /**< RTC time : Maximum prescaler */
84 #define XMC_RTC_YEAR_OFFSET (1900U) /**< RTC year offset : Year offset */
85
86 #if (UC_FAMILY == XMC4)
87 #define XMC_RTC_INIT_SEQUENCE (1U)
88 #endif
89 #if (UC_FAMILY == XMC1)
90 #define XMC_RTC_INIT_SEQUENCE (0U)
91 #endif
92
93 /*********************************************************************************************************************
94 * API IMPLEMENTATION
95 *********************************************************************************************************************/
96
97 /*
98 * Enables RTC peripheral to start counting time
99 */
XMC_RTC_Start(void)100 void XMC_RTC_Start(void)
101 {
102 while((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_CTR_Msk) != 0U)
103 {
104 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
105 }
106 RTC->CTR |= (uint32_t)RTC_CTR_ENB_Msk;
107 }
108
109 /*
110 * Disables RTC peripheral to start counting time
111 */
XMC_RTC_Stop(void)112 void XMC_RTC_Stop(void)
113 {
114 while((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_CTR_Msk) != 0U)
115 {
116 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
117 }
118 RTC->CTR &= ~(uint32_t)RTC_CTR_ENB_Msk;
119 }
120
121 /*
122 * Sets the RTC module prescaler value
123 */
XMC_RTC_SetPrescaler(uint16_t prescaler)124 void XMC_RTC_SetPrescaler(uint16_t prescaler)
125 {
126 XMC_ASSERT("XMC_RTC_SetPrescaler:Wrong prescaler value", (prescaler < XMC_RTC_MAXPRESCALER));
127
128 while((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_CTR_Msk) != 0U)
129 {
130 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
131 }
132 RTC->CTR = (RTC->CTR & ~(uint32_t)RTC_CTR_DIV_Msk) |
133 ((uint32_t)prescaler << (uint32_t)RTC_CTR_DIV_Pos);
134 }
135
136 /*
137 * Sets the RTC_TIM0, RTC_TIM1 registers with time values
138 */
XMC_RTC_SetTime(const XMC_RTC_TIME_t * const time)139 void XMC_RTC_SetTime(const XMC_RTC_TIME_t *const time)
140 {
141 XMC_ASSERT("XMC_RTC_SetTime:Wrong seconds value", ((uint32_t)time->seconds < XMC_RTC_MAXSECONDS));
142 XMC_ASSERT("XMC_RTC_SetTime:Wrong minutes value", ((uint32_t)time->minutes < XMC_RTC_MAXMINUTES));
143 XMC_ASSERT("XMC_RTC_SetTime:Wrong hours value", ((uint32_t)time->hours < XMC_RTC_MAXHOURS));
144 XMC_ASSERT("XMC_RTC_SetTime:Wrong week day value", ((uint32_t)time->daysofweek < XMC_RTC_MAXDAYSOFWEEK));
145 XMC_ASSERT("XMC_RTC_SetTime:Wrong month value", ((uint32_t)time->month < XMC_RTC_MAXMONTH));
146 XMC_ASSERT("XMC_RTC_SetTime:Wrong year value", ((uint32_t)time->year < XMC_RTC_MAXYEAR));
147
148 #if (XMC_RTC_INIT_SEQUENCE == 1U)
149 while ((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_TIM0_Msk) != 0U)
150 {
151 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
152 }
153 RTC->TIM0 = time->raw0;
154
155 while ((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_TIM1_Msk) != 0U)
156 {
157 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
158 }
159 RTC->TIM1 = time->raw1;
160 #endif
161 #if (XMC_RTC_INIT_SEQUENCE == 0U)
162 while ((XMC_SCU_GetMirrorStatus() & (SCU_GENERAL_MIRRSTS_RTC_TIM0_Msk | SCU_GENERAL_MIRRSTS_RTC_TIM1_Msk)) != 0U)
163 {
164 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
165 }
166 RTC->TIM0 = time->raw0;
167 RTC->TIM1 = time->raw1; ;
168 #endif
169 }
170
171 /*
172 * Gets the RTC module time value
173 */
XMC_RTC_GetTime(XMC_RTC_TIME_t * const time)174 void XMC_RTC_GetTime(XMC_RTC_TIME_t *const time)
175 {
176 time->raw0 = RTC->TIM0;
177 time->raw1 = RTC->TIM1;
178 }
179
180 /*
181 * Sets the RTC module time values in standard format
182 */
XMC_RTC_SetTimeStdFormat(const struct tm * const stdtime)183 void XMC_RTC_SetTimeStdFormat(const struct tm *const stdtime)
184 {
185
186 XMC_RTC_TIME_t time;
187
188 time.seconds = stdtime->tm_sec;
189 time.minutes = stdtime->tm_min;
190 time.hours = stdtime->tm_hour;
191 time.days = stdtime->tm_mday - 1;
192 time.month = stdtime->tm_mon;
193 time.year = stdtime->tm_year + XMC_RTC_YEAR_OFFSET;
194 time.daysofweek = stdtime->tm_wday;
195
196 XMC_RTC_SetTime(&time);
197 }
198
199 /*
200 * Gets the RTC module time values in standard format
201 */
XMC_RTC_GetTimeStdFormat(struct tm * const stdtime)202 void XMC_RTC_GetTimeStdFormat(struct tm *const stdtime)
203 {
204 XMC_RTC_TIME_t time;
205 time.raw0 = RTC->TIM0;
206 time.raw1 = RTC->TIM1;
207
208 stdtime->tm_sec = (int8_t)time.seconds;
209 stdtime->tm_min = (int8_t)time.minutes;
210 stdtime->tm_hour = (int8_t)time.hours;
211 stdtime->tm_mday = ((int8_t)time.days + (int8_t)1);
212 stdtime->tm_mon = (int8_t)time.month;
213 stdtime->tm_year = (int32_t)time.year - (int32_t)XMC_RTC_YEAR_OFFSET;
214 stdtime->tm_wday = (int8_t)time.daysofweek;
215 }
216
217 /*
218 * Sets the RTC module alarm time value
219 */
XMC_RTC_SetAlarm(const XMC_RTC_ALARM_t * const alarm)220 void XMC_RTC_SetAlarm(const XMC_RTC_ALARM_t *const alarm)
221 {
222 XMC_ASSERT("XMC_RTC_SetAlarm:Wrong seconds value", ((uint32_t)alarm->seconds < XMC_RTC_MAXSECONDS));
223 XMC_ASSERT("XMC_RTC_SetAlarm:Wrong minutes value", ((uint32_t)alarm->minutes < XMC_RTC_MAXMINUTES));
224 XMC_ASSERT("XMC_RTC_SetAlarm:Wrong hours value", ((uint32_t)alarm->hours < XMC_RTC_MAXHOURS));
225 XMC_ASSERT("XMC_RTC_SetAlarm:Wrong month value", ((uint32_t)alarm->month < XMC_RTC_MAXMONTH));
226 XMC_ASSERT("XMC_RTC_SetAlarm:Wrong year value", ((uint32_t)alarm->year < XMC_RTC_MAXYEAR));
227
228 #if (XMC_RTC_INIT_SEQUENCE == 1U)
229 while ((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_ATIM0_Msk) != 0U)
230 {
231 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
232 }
233 RTC->ATIM0 = alarm->raw0;
234
235 while ((XMC_SCU_GetMirrorStatus() & SCU_GENERAL_MIRRSTS_RTC_ATIM1_Msk) != 0U)
236 {
237 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
238 }
239 RTC->ATIM1 = alarm->raw1;
240 #endif
241 #if (XMC_RTC_INIT_SEQUENCE == 0U)
242 while ((XMC_SCU_GetMirrorStatus() & (SCU_GENERAL_MIRRSTS_RTC_ATIM0_Msk | SCU_GENERAL_MIRRSTS_RTC_ATIM1_Msk)) != 0U)
243 {
244 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
245 }
246 RTC->ATIM0 = alarm->raw0;
247 RTC->ATIM1 = alarm->raw1;
248 #endif
249 }
250
251 /*
252 * Gets the RTC module alarm time value
253 */
XMC_RTC_GetAlarm(XMC_RTC_ALARM_t * const alarm)254 void XMC_RTC_GetAlarm(XMC_RTC_ALARM_t *const alarm)
255 {
256 alarm->raw0 = RTC->ATIM0;
257 alarm->raw1 = RTC->ATIM1;
258 }
259
260
261 /*
262 * Sets the RTC module alarm time value in standard format
263 */
XMC_RTC_SetAlarmStdFormat(const struct tm * const stdtime)264 void XMC_RTC_SetAlarmStdFormat(const struct tm *const stdtime)
265 {
266 XMC_RTC_ALARM_t alarm;
267
268
269 alarm.seconds = stdtime->tm_sec;
270 alarm.minutes = stdtime->tm_min;
271 alarm.hours = stdtime->tm_hour;
272 alarm.days = stdtime->tm_mday - 1;
273 alarm.month = stdtime->tm_mon;
274 alarm.year = stdtime->tm_year + XMC_RTC_YEAR_OFFSET;
275
276 XMC_RTC_SetAlarm(&alarm);
277 }
278
279 /*
280 * Gets the RTC module alarm time value in standard format
281 */
XMC_RTC_GetAlarmStdFormat(struct tm * const stdtime)282 void XMC_RTC_GetAlarmStdFormat(struct tm *const stdtime)
283 {
284 XMC_RTC_ALARM_t alarm;
285
286 alarm.raw0 = RTC->ATIM0;
287 alarm.raw1 = RTC->ATIM1;
288
289 stdtime->tm_sec = (int8_t)alarm.seconds;
290 stdtime->tm_min = (int8_t)alarm.minutes;
291 stdtime->tm_hour = (int8_t)alarm.hours;
292 stdtime->tm_mday = ((int8_t)alarm.days + (int8_t)1);
293 stdtime->tm_mon = (int8_t)alarm.month;
294 stdtime->tm_year = (int32_t)alarm.year - (int32_t)XMC_RTC_YEAR_OFFSET;
295 }
296
297 /*
298 * Gets the RTC periodic and alarm event(s) status
299 */
XMC_RTC_GetEventStatus(void)300 uint32_t XMC_RTC_GetEventStatus(void)
301 {
302 return RTC->STSSR;
303 }
304