]> git.sur5r.net Git - freertos/blob
2af1f0eeccaf2a095a4a9e819da87dfebdef8f60
[freertos] /
1 /*******************************************************************************\r
2  * (c) Copyright 2008-2013 Microsemi SoC Products Group.  All rights reserved.\r
3  * \r
4  * SmartFusion2 MSS RTC bare metal driver implementation.\r
5  *\r
6  * SVN $Revision: 5090 $\r
7  * SVN $Date: 2013-02-18 12:13:31 +0000 (Mon, 18 Feb 2013) $\r
8  */\r
9 #include "mss_rtc.h"\r
10 #include "../../CMSIS/mss_assert.h"\r
11 #include <string.h>\r
12 \r
13 #ifdef __cplusplus\r
14 extern "C" {\r
15 #endif \r
16 \r
17 /*-------------------------------------------------------------------------*//**\r
18  * CONTROL_REG register masks.\r
19  */\r
20 #define CONTROL_RUNNING_MASK        0x00000001u\r
21 \r
22 #define CONTROL_RTC_START_MASK      0x00000001u\r
23 #define CONTROL_RTC_STOP_MASK       0x00000002u\r
24 #define CONTROL_ALARM_ON_MASK       0x00000004u\r
25 #define CONTROL_ALARM_OFF_MASK      0x00000008u\r
26 #define CONTROL_RESET_MASK          0x00000010u\r
27 #define CONTROL_UPLOAD_MASK         0x00000020u\r
28 #define CONTROL_WAKEUP_CLR_MASK     0x00000100u\r
29 #define CONTROL_UPDATED_MASK        0x00000400u\r
30 \r
31 /*-------------------------------------------------------------------------*//**\r
32  * MODE_REG register masks.\r
33  */\r
34 #define MODE_CLK_MODE_MASK          0x00000001u\r
35 #define MODE_WAKEUP_EN_MASK         0x00000002u\r
36 #define MODE_WAKEUP_RESET_MASK      0x00000004u\r
37 #define MODE_WAKEUP_CONTINUE_MASK   0x00000008u\r
38 \r
39 /*-------------------------------------------------------------------------*//**\r
40  * Other masks.\r
41  */\r
42 #define MAX_BINARY_HIGHER_COUNT     0x7FFu\r
43 #define MASK_32_BIT                 0xFFFFFFFFu\r
44 #define MAX_PRESCALAR_COUNT         0x03FFFFFFu\r
45 #define CALENDAR_SHIFT              8u\r
46 \r
47 #define COMPARE_ALL_BITS            0xFFFFFFFFu\r
48 \r
49 #define SYSREG_RTC_WAKEUP_M3_EN_MASK    0x00000001u\r
50 \r
51 /*-------------------------------------------------------------------------*//**\r
52  * Index into look-up table.\r
53  */\r
54 #define SECONDS     0\r
55 #define MINUTES     1\r
56 #define HOURS       2\r
57 #define DAYS        3\r
58 #define MONTHS      4\r
59 #define YEARS       5\r
60 #define WEEKDAYS    6\r
61 #define WEEKS       7\r
62 \r
63 /*-------------------------------------------------------------------------*//**\r
64   Local functions.\r
65  */\r
66 static uint8_t\r
67 get_clock_mode\r
68 (\r
69     void\r
70 );\r
71 \r
72 static void set_rtc_mode(uint8_t requested_mode);\r
73 \r
74 static void add_alarm_cfg_values\r
75 (\r
76     uint8_t calendar_item,\r
77     uint32_t * p_calendar_value,\r
78     uint32_t * p_compare_mask\r
79     \r
80 );\r
81 \r
82 /*-------------------------------------------------------------------------*//**\r
83  * See "mss_rtc.h" for details of how to use this function.\r
84  */\r
85 void\r
86 MSS_RTC_init\r
87 (\r
88     uint8_t mode,\r
89     uint32_t prescaler\r
90 )\r
91 {\r
92     ASSERT(prescaler <= MAX_PRESCALAR_COUNT);\r
93 \r
94     if(prescaler <= MAX_PRESCALAR_COUNT)\r
95     {\r
96         /* Stop the RTC. */\r
97         MSS_RTC_stop();\r
98         \r
99         /* Disable alarm. */\r
100         RTC->CONTROL_REG = CONTROL_ALARM_OFF_MASK;\r
101         \r
102         /* Disable Interrupt */\r
103         MSS_RTC_disable_irq();\r
104         NVIC_ClearPendingIRQ(RTC_Wakeup_IRQn);\r
105 \r
106         /* Clear RTC wake up interrupt signal */\r
107         MSS_RTC_clear_irq();\r
108 \r
109         /* Enable the RTC to interrupt the Cortex-M3. */\r
110         SYSREG->RTC_WAKEUP_CR |= SYSREG_RTC_WAKEUP_M3_EN_MASK;\r
111         \r
112         /* Select mode of operation, including the wake configuration. */\r
113         if(MSS_RTC_CALENDAR_MODE == mode)\r
114         {\r
115             RTC->MODE_REG = MODE_CLK_MODE_MASK;\r
116         }\r
117         else\r
118         {\r
119             RTC->MODE_REG = 0u;\r
120         }\r
121         \r
122         /* Reset the alarm and compare registers to a known value. */\r
123         RTC->ALARM_LOWER_REG = 0u;\r
124         RTC->ALARM_UPPER_REG = 0u;\r
125         RTC->COMPARE_LOWER_REG = 0u;\r
126         RTC->COMPARE_UPPER_REG = 0u;\r
127 \r
128         /* Reset the calendar counters */\r
129         MSS_RTC_reset_counter();\r
130 \r
131         /* Set new Prescaler value */\r
132         RTC->PRESCALER_REG = prescaler;\r
133     }\r
134 }\r
135 \r
136 /*-------------------------------------------------------------------------*//**\r
137   See "mss_rtc.h" for details of how to use this function.\r
138  */\r
139 void\r
140 MSS_RTC_set_calendar_count\r
141 (\r
142     const mss_rtc_calendar_t *new_rtc_value\r
143 )\r
144 {\r
145     uint8_t error = 0u;\r
146     uint8_t clock_mode;\r
147     \r
148     const uint8_t g_rtc_max_count_lut[] =\r
149     {\r
150        /* Calendar mode */\r
151         59u,    /* Seconds */\r
152         59u,    /* Minutes */\r
153         23u,    /* Hours   */\r
154         31u,    /* Days    */\r
155         12u,    /* Months  */\r
156         254u,   /* Years   */\r
157         7u,     /* Weekdays*/\r
158         52u     /* Week    */\r
159     };\r
160 \r
161     const uint8_t g_rtc_min_count_lut[] =\r
162     {\r
163        /* Calendar mode */\r
164         0u, /* Seconds */\r
165         0u, /* Minutes */\r
166         0u, /* Hours   */\r
167         1u, /* Days    */\r
168         1u, /* Months  */\r
169         0u, /* Years   */\r
170         1u, /* Weekdays*/\r
171         1u  /* Week    */\r
172     };\r
173     \r
174     /* Assert if the values cross the limit */\r
175     ASSERT(new_rtc_value->second >= g_rtc_min_count_lut[SECONDS]);\r
176     ASSERT(new_rtc_value->second <= g_rtc_max_count_lut[SECONDS]);\r
177     ASSERT(new_rtc_value->minute >= g_rtc_min_count_lut[MINUTES]);\r
178     ASSERT(new_rtc_value->minute <= g_rtc_max_count_lut[MINUTES]);\r
179     ASSERT(new_rtc_value->hour >= g_rtc_min_count_lut[HOURS]);\r
180     ASSERT(new_rtc_value->hour <= g_rtc_max_count_lut[HOURS]);\r
181     ASSERT(new_rtc_value->day >= g_rtc_min_count_lut[DAYS]);\r
182     ASSERT(new_rtc_value->day <= g_rtc_max_count_lut[DAYS]);\r
183     ASSERT(new_rtc_value->month >= g_rtc_min_count_lut[MONTHS]);\r
184     ASSERT(new_rtc_value->month <= g_rtc_max_count_lut[MONTHS]);\r
185     ASSERT(new_rtc_value->year >= g_rtc_min_count_lut[YEARS]);\r
186     ASSERT(new_rtc_value->year <= g_rtc_max_count_lut[YEARS]);\r
187     ASSERT(new_rtc_value->weekday >= g_rtc_min_count_lut[WEEKDAYS]);\r
188     ASSERT(new_rtc_value->weekday <= g_rtc_max_count_lut[WEEKDAYS]);\r
189     ASSERT(new_rtc_value->week >= g_rtc_min_count_lut[WEEKS]);\r
190     ASSERT(new_rtc_value->week <= g_rtc_max_count_lut[WEEKS]);\r
191 \r
192     if(new_rtc_value->second < g_rtc_min_count_lut[SECONDS]) {error = 1u;}\r
193     if(new_rtc_value->second > g_rtc_max_count_lut[SECONDS]) {error = 1u;}\r
194     if(new_rtc_value->minute < g_rtc_min_count_lut[MINUTES]) {error = 1u;}\r
195     if(new_rtc_value->minute > g_rtc_max_count_lut[MINUTES]) {error = 1u;}\r
196     if(new_rtc_value->hour < g_rtc_min_count_lut[HOURS]) {error = 1u;}\r
197     if(new_rtc_value->hour > g_rtc_max_count_lut[HOURS]) {error = 1u;}\r
198     if(new_rtc_value->day < g_rtc_min_count_lut[DAYS]) {error = 1u;}\r
199     if(new_rtc_value->day > g_rtc_max_count_lut[DAYS]) {error = 1u;}\r
200     if(new_rtc_value->month < g_rtc_min_count_lut[MONTHS]) {error = 1u;}\r
201     if(new_rtc_value->month > g_rtc_max_count_lut[MONTHS]) {error = 1u;}\r
202     if(new_rtc_value->year < g_rtc_min_count_lut[YEARS]) {error = 1u;}\r
203     if(new_rtc_value->year > g_rtc_max_count_lut[YEARS]) {error = 1u;}\r
204     if(new_rtc_value->weekday < g_rtc_min_count_lut[WEEKDAYS]) {error = 1u;}\r
205     if(new_rtc_value->weekday > g_rtc_max_count_lut[WEEKDAYS]) {error = 1u;}\r
206     if(new_rtc_value->week < g_rtc_min_count_lut[WEEKS]) {error = 1u;}\r
207     if(new_rtc_value->week > g_rtc_max_count_lut[WEEKS]) {error = 1u;}\r
208 \r
209     /* \r
210      * This function can only be used when the RTC is configured to operate in\r
211      * calendar counter mode. \r
212      */\r
213     clock_mode = get_clock_mode();\r
214     ASSERT(MSS_RTC_CALENDAR_MODE == clock_mode);\r
215     \r
216     if((0u == error) && (MSS_RTC_CALENDAR_MODE == clock_mode))\r
217     {\r
218         uint32_t upload_in_progress;\r
219         \r
220         /*\r
221          * Write the RTC new value. \r
222          */\r
223         RTC->SECONDS_REG = new_rtc_value->second;\r
224         RTC->MINUTES_REG = new_rtc_value->minute;\r
225         RTC->HOURS_REG = new_rtc_value->hour;\r
226         RTC->DAY_REG = new_rtc_value->day;\r
227         RTC->MONTH_REG = new_rtc_value->month;\r
228         RTC->YEAR_REG = new_rtc_value->year;\r
229         RTC->WEEKDAY_REG = new_rtc_value->weekday;\r
230         RTC->WEEK_REG = new_rtc_value->week;\r
231 \r
232         /* Data is copied, now issue upload command */\r
233         RTC->CONTROL_REG = CONTROL_UPLOAD_MASK ;\r
234         \r
235         /* Wait for the upload to complete. */\r
236         do {\r
237             upload_in_progress = RTC->CONTROL_REG & CONTROL_UPLOAD_MASK;\r
238         } while(upload_in_progress);\r
239     }\r
240 }\r
241 \r
242 /*-------------------------------------------------------------------------*//**\r
243  * See "mss_rtc.h" for details of how to use this function.\r
244  */\r
245 void\r
246 MSS_RTC_set_binary_count\r
247 (\r
248     uint64_t new_rtc_value\r
249 )\r
250 {\r
251     uint8_t clock_mode;\r
252 \r
253     /* \r
254      * This function can only be used when the RTC is configured to operate in\r
255      * binary counter mode. \r
256      */\r
257     clock_mode = get_clock_mode();\r
258     ASSERT(MSS_RTC_BINARY_MODE == clock_mode);\r
259     \r
260     if(MSS_RTC_BINARY_MODE == clock_mode)\r
261     {\r
262         uint32_t rtc_upper_32_bit_value;\r
263         \r
264         rtc_upper_32_bit_value = (uint32_t)(new_rtc_value >> 32u) & MASK_32_BIT;\r
265 \r
266         /* Assert if the values cross the limit */\r
267         ASSERT(rtc_upper_32_bit_value <= MAX_BINARY_HIGHER_COUNT);\r
268 \r
269         if(rtc_upper_32_bit_value <= MAX_BINARY_HIGHER_COUNT)\r
270         {\r
271             uint32_t upload_in_progress;\r
272             \r
273             /*\r
274              * Write the RTC new value. \r
275              */\r
276             RTC->DATE_TIME_LOWER_REG = (uint32_t)new_rtc_value;\r
277             RTC->DATE_TIME_UPPER_REG =\r
278                     (uint32_t)(( new_rtc_value >> 32u) & MAX_BINARY_HIGHER_COUNT);\r
279 \r
280             /* Data is copied, now issue upload command */\r
281             RTC->CONTROL_REG = CONTROL_UPLOAD_MASK;\r
282             \r
283             /* Wait for the upload to complete. */\r
284             do {\r
285                 upload_in_progress = RTC->CONTROL_REG & CONTROL_UPLOAD_MASK;\r
286             } while(upload_in_progress);\r
287         }\r
288     }\r
289 }\r
290 \r
291 /*-------------------------------------------------------------------------*//**\r
292  * See "mss_rtc.h" for details of how to use this function.\r
293  */\r
294 void\r
295 MSS_RTC_get_calendar_count\r
296 (\r
297     mss_rtc_calendar_t *p_rtc_calendar\r
298 )\r
299 {\r
300     uint8_t clock_mode;\r
301     /* \r
302      * This function can only be used when the RTC is configured to operate in\r
303      * calendar counter mode. \r
304      */\r
305     clock_mode = get_clock_mode();\r
306     ASSERT(MSS_RTC_CALENDAR_MODE == clock_mode);\r
307     \r
308     if(MSS_RTC_CALENDAR_MODE == clock_mode)\r
309     {\r
310         p_rtc_calendar->second = (uint8_t)RTC->SECONDS_REG;\r
311         p_rtc_calendar->minute = (uint8_t)RTC->MINUTES_REG;\r
312         p_rtc_calendar->hour = (uint8_t)RTC->HOURS_REG;\r
313         p_rtc_calendar->day = (uint8_t)RTC->DAY_REG;\r
314         p_rtc_calendar->month = (uint8_t)RTC->MONTH_REG;\r
315         p_rtc_calendar->year = (uint8_t)RTC->YEAR_REG;\r
316         p_rtc_calendar->weekday = (uint8_t)RTC->WEEKDAY_REG;\r
317         p_rtc_calendar->week = (uint8_t)RTC->WEEK_REG;\r
318     }\r
319     else\r
320     {\r
321         /*\r
322          * Set returned calendar count to zero if the RTC is not configured for\r
323          * calendar counter mode. This should make incorrect release application\r
324          * code behave consistently and help application debugging.\r
325          */\r
326         memset(p_rtc_calendar, 0, sizeof(mss_rtc_calendar_t));\r
327     }\r
328 }\r
329 \r
330 /*-------------------------------------------------------------------------*//**\r
331  * See "mss_rtc.h" for details of how to use this function.\r
332  */\r
333 uint64_t\r
334 MSS_RTC_get_binary_count\r
335 (\r
336     void\r
337 )\r
338 {\r
339     uint64_t rtc_count;\r
340     uint8_t clock_mode;\r
341 \r
342     /* \r
343      * This function can only be used when the RTC is configured to operate in\r
344      * binary counter mode. \r
345      */\r
346     clock_mode = get_clock_mode();\r
347     ASSERT(MSS_RTC_BINARY_MODE == clock_mode);\r
348     \r
349     if(MSS_RTC_BINARY_MODE == clock_mode)\r
350     {\r
351         rtc_count = RTC->DATE_TIME_LOWER_REG;\r
352         rtc_count = rtc_count | ((uint64_t)RTC->DATE_TIME_UPPER_REG << 32u) ;\r
353     }\r
354     else\r
355     {\r
356         /*\r
357          * Set returned binary count to zero if the RTC is not configured for\r
358          * binary counter mode. This should make incorrect release application\r
359          * code behave consistently and help application debugging.\r
360          */\r
361         rtc_count = 0u;\r
362     }\r
363 \r
364     return rtc_count;\r
365 }\r
366 \r
367 /*-------------------------------------------------------------------------*//**\r
368  *\r
369  */\r
370 static void add_alarm_cfg_values\r
371 (\r
372     uint8_t calendar_item,\r
373     uint32_t * p_calendar_value,\r
374     uint32_t * p_compare_mask\r
375     \r
376 )\r
377 {\r
378     if(MSS_RTC_CALENDAR_DONT_CARE == calendar_item)\r
379     {\r
380         *p_calendar_value = (uint32_t)(*p_calendar_value << CALENDAR_SHIFT);\r
381         *p_compare_mask = (uint32_t)(*p_compare_mask << CALENDAR_SHIFT);\r
382     }\r
383     else\r
384     {\r
385         *p_calendar_value = (uint32_t)((*p_calendar_value << CALENDAR_SHIFT) | (uint32_t)calendar_item);\r
386         *p_compare_mask = (uint32_t)((*p_compare_mask << CALENDAR_SHIFT) | (uint32_t)0xFFu);\r
387     }\r
388 }\r
389 \r
390 /*-------------------------------------------------------------------------*//**\r
391  * See "mss_rtc.h" for details of how to use this function.\r
392  */\r
393 void MSS_RTC_set_calendar_count_alarm\r
394 (\r
395     const mss_rtc_calendar_t * alarm_value\r
396 )\r
397 {\r
398     uint32_t calendar_value;\r
399     uint32_t compare_mask;\r
400     uint8_t mode;\r
401     \r
402     mode = (uint8_t)(RTC->MODE_REG & MODE_CLK_MODE_MASK);\r
403     /*\r
404      * This function can only be used with the RTC set to operate in calendar\r
405      * mode.\r
406      */\r
407     ASSERT(MSS_RTC_CALENDAR_MODE == mode);\r
408     if(MSS_RTC_CALENDAR_MODE == mode)\r
409     {\r
410         uint8_t required_mode_reg;\r
411         \r
412         /* Disable the alarm before updating*/\r
413         RTC->CONTROL_REG = CONTROL_ALARM_OFF_MASK;\r
414 \r
415         /* Set alarm and compare lower registers. */\r
416         calendar_value = 0u;\r
417         compare_mask = 0u;\r
418         \r
419         add_alarm_cfg_values(alarm_value->day, &calendar_value, &compare_mask);\r
420         add_alarm_cfg_values(alarm_value->hour, &calendar_value, &compare_mask);\r
421         add_alarm_cfg_values(alarm_value->minute, &calendar_value, &compare_mask);\r
422         add_alarm_cfg_values(alarm_value->second, &calendar_value, &compare_mask);\r
423 \r
424         RTC->ALARM_LOWER_REG = calendar_value;\r
425         RTC->COMPARE_LOWER_REG = compare_mask;\r
426 \r
427         /* Set alarm and compare upper registers. */\r
428         calendar_value = 0u;\r
429         compare_mask = 0u;\r
430         \r
431         add_alarm_cfg_values(alarm_value->week, &calendar_value, &compare_mask);\r
432         add_alarm_cfg_values(alarm_value->weekday, &calendar_value, &compare_mask);\r
433         add_alarm_cfg_values(alarm_value->year, &calendar_value, &compare_mask);\r
434         add_alarm_cfg_values(alarm_value->month, &calendar_value, &compare_mask);\r
435 \r
436         RTC->ALARM_UPPER_REG = calendar_value;\r
437         RTC->COMPARE_UPPER_REG = compare_mask;\r
438         \r
439         /* Configure the RTC to enable the alarm. */\r
440         required_mode_reg = mode | MODE_WAKEUP_EN_MASK | MODE_WAKEUP_CONTINUE_MASK;\r
441         set_rtc_mode(required_mode_reg);\r
442         \r
443         /* Enable the alarm */\r
444         RTC->CONTROL_REG = CONTROL_ALARM_ON_MASK ;\r
445     }\r
446 }\r
447 \r
448 /*-------------------------------------------------------------------------*//**\r
449   We only write the RTC mode register if really required because the RTC needs\r
450   to be stopped for the mode register to be written. Stopping the RTC everytime\r
451   the wakeup alarm configuration is set might induce drift on the RTC time.\r
452   This function is intended to be used when setting alarms.\r
453  */\r
454 static void set_rtc_mode(uint8_t requested_mode)\r
455 {\r
456     if(RTC->MODE_REG != requested_mode)\r
457     {\r
458         uint32_t rtc_running;\r
459         rtc_running = RTC->CONTROL_REG & CONTROL_RUNNING_MASK;\r
460         if(rtc_running)\r
461         {\r
462             /* Stop the RTC in order to change the mode register content.*/\r
463             MSS_RTC_stop();\r
464             RTC->MODE_REG = requested_mode;\r
465             MSS_RTC_start();\r
466         }\r
467         else\r
468         {\r
469             RTC->MODE_REG = requested_mode;\r
470         }\r
471     }\r
472 }\r
473 \r
474 /*-------------------------------------------------------------------------*//**\r
475  * See "mss_rtc.h" for details of how to use this function.\r
476  */\r
477 void MSS_RTC_set_binary_count_alarm\r
478 (\r
479     uint64_t alarm_value,\r
480     mss_rtc_alarm_type_t alarm_type\r
481 )\r
482 {\r
483     uint8_t mode;\r
484     \r
485     mode = (uint8_t)(RTC->MODE_REG & MODE_CLK_MODE_MASK);\r
486     /*\r
487      * This function can only be used with the RTC set to operate in binary\r
488      * counter mode.\r
489      */\r
490     ASSERT(MSS_RTC_BINARY_MODE == mode);\r
491     if(MSS_RTC_BINARY_MODE == mode)\r
492     {\r
493         uint8_t required_mode_reg;\r
494         \r
495         /* Disable the alarm before updating*/\r
496         RTC->CONTROL_REG = CONTROL_ALARM_OFF_MASK;\r
497 \r
498         /* Set the alarm value. */\r
499         RTC->COMPARE_LOWER_REG = COMPARE_ALL_BITS;\r
500         RTC->COMPARE_UPPER_REG = COMPARE_ALL_BITS;\r
501         RTC->ALARM_LOWER_REG = (uint32_t)alarm_value;\r
502         RTC->ALARM_UPPER_REG = (uint32_t)(alarm_value >> 32u);\r
503 \r
504         /*\r
505          * Configure the RTC to enable the alarm.\r
506          */\r
507         required_mode_reg = mode | MODE_WAKEUP_EN_MASK | MODE_WAKEUP_CONTINUE_MASK;\r
508         if(MSS_RTC_PERIODIC_ALARM == alarm_type)\r
509         {\r
510             /*\r
511              * The RTC binary counter will be fully reset when the alarm occurs.\r
512              * The counter will continue counting while the wake-up interrupt is\r
513              * active.\r
514              */\r
515             required_mode_reg |= MODE_WAKEUP_RESET_MASK;\r
516         }\r
517         set_rtc_mode(required_mode_reg);\r
518         \r
519         /* Enable the alarm */\r
520         RTC->CONTROL_REG = CONTROL_ALARM_ON_MASK;\r
521     }\r
522 }\r
523 \r
524 /*-------------------------------------------------------------------------*//**\r
525  * See "mss_rtc.h" for details of how to use this function.\r
526  */\r
527 void\r
528 MSS_RTC_start\r
529 (\r
530     void\r
531 )\r
532 {\r
533     RTC->CONTROL_REG = CONTROL_RTC_START_MASK;\r
534 }\r
535 \r
536 /*-------------------------------------------------------------------------*//**\r
537  * See "mss_rtc.h" for details of how to use this function.\r
538  */\r
539 void\r
540 MSS_RTC_stop\r
541 (\r
542     void\r
543 )\r
544 {\r
545     uint32_t rtc_running;\r
546     \r
547     /*\r
548      * Send command to stop RTC.\r
549      */\r
550     RTC->CONTROL_REG = CONTROL_RTC_STOP_MASK;\r
551     \r
552     /* \r
553      * Wait for RTC internal synchronization to take place and RTC to actually\r
554      * stop.\r
555      */\r
556     do {\r
557         rtc_running =  RTC->CONTROL_REG & CONTROL_RUNNING_MASK;\r
558     } while(rtc_running);\r
559 }\r
560 \r
561 /*-------------------------------------------------------------------------*//**\r
562   See "mss_rtc.h" for details of how to use this function.\r
563  */\r
564 void\r
565 MSS_RTC_reset_counter\r
566 (\r
567     void\r
568 )\r
569 {\r
570     uint32_t upload_in_progress;\r
571     \r
572     RTC->CONTROL_REG = CONTROL_RESET_MASK;\r
573     \r
574     /* Wait for the upload to complete. */\r
575     do {\r
576         upload_in_progress = RTC->CONTROL_REG & CONTROL_UPLOAD_MASK;\r
577     } while(upload_in_progress);\r
578 }\r
579 \r
580 /*-------------------------------------------------------------------------*//**\r
581   See "mss_rtc.h" for details of how to use this function.\r
582  */\r
583 uint32_t MSS_RTC_get_update_flag(void)\r
584 {\r
585     uint32_t updated;\r
586     updated = RTC->CONTROL_REG & CONTROL_UPDATED_MASK;\r
587     return updated;\r
588 }\r
589 \r
590 /*-------------------------------------------------------------------------*//**\r
591   See "mss_rtc.h" for details of how to use this function.\r
592  */\r
593 void MSS_RTC_clear_update_flag(void)\r
594 {\r
595     /* Clear the "updated" control bit. */\r
596     RTC->CONTROL_REG = CONTROL_UPDATED_MASK;\r
597 }\r
598 \r
599 /*-------------------------------------------------------------------------*//**\r
600   See "mss_rtc.h" for details of how to use this function.\r
601  */\r
602 void MSS_RTC_enable_irq(void)\r
603 {\r
604     /*\r
605      * Only the NVIC level interrupt enable is performed within this function.\r
606      * The RTC level interrupt enable is performed within the alarm setting\r
607      * functions.\r
608      * This avoid the MODE register being modified whenever Cortex-M3 RTC\r
609      * interrupts are enabled/disabled. \r
610      */\r
611     NVIC_EnableIRQ(RTC_Wakeup_IRQn);\r
612 }\r
613 \r
614 /*-------------------------------------------------------------------------*//**\r
615   See "mss_rtc.h" for details of how to use this function.\r
616  */\r
617 void\r
618 MSS_RTC_disable_irq\r
619 (\r
620     void\r
621 )\r
622 {\r
623     /*\r
624      * Only the NVIC level interrupt disable is performed within this function.\r
625      * This avoid the MODE register being modified whenever Cortex-M3 RTC\r
626      * interrupts are enabled/disabled. \r
627      */\r
628     NVIC_DisableIRQ(RTC_Wakeup_IRQn);\r
629 }\r
630 \r
631 /*-------------------------------------------------------------------------*//**\r
632  * See "mss_rtc.h" for details of how to use this function.\r
633  */\r
634 void\r
635 MSS_RTC_clear_irq\r
636 (\r
637     void\r
638 )\r
639 {\r
640     /* Clear wake up interrupt signal */\r
641     RTC->CONTROL_REG = CONTROL_WAKEUP_CLR_MASK;\r
642 }\r
643 \r
644 /*-------------------------------------------------------------------------*//**\r
645   The get_clock_mode() function gets the clock mode of RTC hardware.\r
646   Possible clock modes are:\r
647     MSS_RTC_CALENDAR_MODE\r
648     MSS_RTC_BINARY_MODE\r
649  */\r
650 static uint8_t\r
651 get_clock_mode\r
652 (\r
653     void\r
654 )\r
655 {\r
656     uint8_t clock_mode;\r
657 \r
658     clock_mode = (uint8_t)(RTC->MODE_REG & MODE_CLK_MODE_MASK);\r
659 \r
660     return(clock_mode);\r
661 }\r
662 \r
663 #ifdef __cplusplus\r
664 }\r
665 #endif\r
666 \r