1 /**
2  * \file
3  *
4  * \brief SAM RTC Driver (Calendar Mode)
5  *
6  * Copyright (C) 2012-2016 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 #ifndef RTC_CALENDAR_H_INCLUDED
47 #define RTC_CALENDAR_H_INCLUDED
48 
49 /**
50  * \defgroup asfdoc_sam0_rtc_calendar_group SAM RTC Calendar (RTC CAL) Driver
51  *
52  * This driver for Atmel&reg; | SMART ARM&reg;-based microcontrollers provides
53  * an interface for the configuration and management of the device's Real Time
54  * Clock functionality in Calendar operating mode, for the configuration and
55  * retrieval of the current time and date as maintained by the RTC module.
56   The following driver API modes are covered by this manual:
57  *
58  *  - Polled APIs
59  * \if RTC_CALENDAR_CALLBACK_MODE
60  *  - Callback APIs
61  * \endif
62  *
63  * The following peripheral is used by this module:
64  *  - RTC (Real Time Clock)
65  *
66  * The following devices can use this module:
67  *  - Atmel | SMART SAM D20/D21
68  *  - Atmel | SMART SAM R21
69  *  - Atmel | SMART SAM D09/D10/D11
70  *  - Atmel | SMART SAM L21/L22
71  *  - Atmel | SMART SAM DA1
72  *  - Atmel | SMART SAM C20/C21
73  *  - Atmel | SMART SAM HA1
74  *  - Atmel | SMART SAM R30
75  *
76  * The outline of this documentation is as follows:
77  *  - \ref asfdoc_sam0_rtc_calendar_prerequisites
78  *  - \ref asfdoc_sam0_rtc_calendar_module_overview
79  *  - \ref asfdoc_sam0_rtc_calendar_special_considerations
80  *  - \ref asfdoc_sam0_rtc_calendar_extra_info
81  *  - \ref asfdoc_sam0_rtc_calendar_examples
82  *  - \ref asfdoc_sam0_rtc_calendar_api_overview
83  *
84  *
85  * \section asfdoc_sam0_rtc_calendar_prerequisites Prerequisites
86  *
87  * There are no prerequisites for this module.
88  *
89  *
90  * \section asfdoc_sam0_rtc_calendar_module_overview Module Overview
91  *
92  * The RTC module in the SAM devices is a 32-bit counter, with a 10-bit
93  * programmable prescaler. Typically, the RTC clock is run continuously,
94  * including in the device's low-power sleep modes, to track the current time
95  * and date information. The RTC can be used as a source to wake up the system
96  * at a scheduled time or periodically using the alarm functions.
97  *
98  * In this driver, the RTC is operated in Calendar mode. This allows for an
99  * easy integration of a real time clock and calendar into a user application
100  * to track the passing of time and/or perform scheduled tasks.
101  *
102  * Whilst operating in Calendar mode, the RTC features:
103  *  - Time tracking in seconds, minutes, and hours
104  *  - 12 or 24 hour mode
105  *  - Date tracking in day, month, and year
106  *  - Automatic leap year correction
107  *
108  * \subsection asfdoc_sam0_rtc_calendar_features Driver Feature Macro Definition
109  * <table>
110  *  <tr>
111  *    <th>Driver Feature Macro</th>
112  *    <th>Supported devices</th>
113  *  </tr>
114  *  <tr>
115  *    <td>FEATURE_RTC_PERIODIC_INT</td>
116  *    <td>SAM L21/L22/C20/C21/R30</td>
117  *  </tr>
118  *  <tr>
119  *    <td>FEATURE_RTC_PRESCALER_OFF</td>
120  *    <td>SAM L21/L22/C20/C21/R30</td>
121  *  </tr>
122  *  <tr>
123  *    <td>FEATURE_RTC_CLOCK_SELECTION</td>
124  *    <td>SAM L21/L22/C20/C21/R30</td>
125  *  </tr>
126  *  <tr>
127  *    <td>FEATURE_RTC_GENERAL_PURPOSE_REG</td>
128  *    <td>SAM L21/L22/R30</td>
129  *  </tr>
130  *  <tr>
131  *    <td>FEATURE_RTC_CONTINUOUSLY_UPDATED</td>
132  *    <td>SAM D20, SAM D21, SAM R21, SAM D10, SAM D11, SAM DA1, SAM HA1</td>
133  *  </tr>
134  *  <tr>
135  *    <td>FEATURE_RTC_TAMPER_DETECTION</td>
136  *    <td>SAM L22</td>
137  *  </tr>
138  * </table>
139  * \note The specific features are only available in the driver when the
140  * selected device supports those features.
141  *
142  * \subsection asfdoc_sam0_rtc_calendar_module_overview_alarms Alarms and Overflow
143  * The RTC has up to four independent hardware alarms that can be configured by the user
144  * application. These alarms will be triggered on match with the current
145  * clock value, and can be set up to trigger an interrupt, event, or both. The
146  * RTC can also be configured to clear the clock value on alarm match, resetting
147  * the clock to the original start time.
148  *
149  * If the RTC is operated in clock-only mode (i.e. with calendar disabled), the
150  * RTC counter value will instead be cleared on overflow once the maximum count
151  * value has been reached:
152  *
153  * \f[ COUNT_{MAX} = 2^{32}-1 \f]
154  *
155  * When the RTC is operated with the calendar enabled and run using a nominal
156  * 1Hz input clock frequency, a register overflow will occur after 64 years.
157  *
158  * \subsection asfdoc_sam0_rtc_calendar_module_overview_periodic Periodic Events
159  * The RTC can generate events at periodic intervals, allowing for direct
160  * peripheral actions without CPU intervention. The periodic events can be
161  * generated on the upper eight bits of the RTC prescaler, and will be generated on
162  * the rising edge transition of the specified bit. The resulting periodic
163  * frequency can be calculated by the following formula:
164  *
165  * \f[ f_{PERIODIC}=\frac{f_{ASY}}{2^{n+3}} \f]
166  *
167  * Where \f$f_{ASY}\f$ refers to the \e asynchronous clock set up in the RTC
168  * module configuration. For the RTC to operate correctly in calendar mode, this
169  * frequency must be 1KHz, while the RTC's internal prescaler should be set to
170  * divide by 1024. The \b n parameter is the event source generator index of the
171  * RTC module. If the asynchronous clock is operated at the recommended 1KHz,
172  * the formula results in the values shown in
173  * \ref asfdoc_sam0_rtc_calendar_module_rtc_hz "the table below".
174  *
175  * \anchor asfdoc_sam0_rtc_calendar_module_rtc_hz
176  * <table>
177  *   <caption>RTC Event Frequencies for Each Prescaler Bit Using a 1KHz Clock</caption>
178  *   <tr>
179  *      <th>n</th> <th>Periodic event</th>
180  *   </tr>
181  *   <tr>
182  *      <td>7</td> <td>1Hz</td>
183  *   </tr>
184  *   <tr>
185  *      <td>6</td> <td>2Hz</td>
186  *   </tr>
187  *   <tr>
188  *      <td>5</td> <td>4Hz</td>
189  *   </tr>
190  *   <tr>
191  *      <td>4</td> <td>8Hz</td>
192  *   </tr>
193  *   <tr>
194  *      <td>3</td> <td>16Hz</td>
195  *   </tr>
196  *   <tr>
197  *      <td>2</td> <td>32Hz</td>
198  *   </tr>
199  *   <tr>
200  *      <td>1</td> <td>64Hz</td>
201  *   </tr>
202  *   <tr>
203  *      <td>0</td> <td>128Hz</td>
204  *   </tr>
205  * </table>
206  *
207  * \note The connection of events between modules requires the use of the
208  *       \ref asfdoc_sam0_events_group "SAM Event System Driver (EVENTS)"
209  *       to route output event of one module to the input event of another.
210  *       For more information on event routing, refer to the event driver
211  *       documentation.
212  *
213  * \subsection asfdoc_sam0_rtc_calendar_module_overview_correction Digital Frequency Correction
214  * The RTC module contains Digital Frequency Correction logic to compensate for
215  * inaccurate source clock frequencies which would otherwise result in skewed
216  * time measurements. The correction scheme requires that at least two bits
217  * in the RTC module prescaler are reserved by the correction logic. As a
218  * result of this implementation, frequency correction is only available when
219  * the RTC is running from a 1Hz reference clock.
220  *
221  * The correction procedure is implemented by subtracting or adding a single
222  * cycle from the RTC prescaler every 1024 RTC Generic Clock (GCLK) cycles. The adjustment is
223  * applied the specified number of time (maximum 127) over 976 of these periods. The
224  * corresponding correction in parts per million (PPM) will be given by:
225  *
226  * \f[ Correction(PPM) = \frac{VALUE}{999424}10^6 \f]
227  *
228  * The RTC clock will tick faster if provided with a positive correction value,
229  * and slower when given a negative correction value.
230  *
231  *
232  * \subsection asfdoc_sam0_rtc_calendar_module_overview_tamper_detect RTC Tamper Detect
233  * See \ref asfdoc_sam0_rtc_tamper_detect.
234  *
235  * \section asfdoc_sam0_rtc_calendar_special_considerations Special Considerations
236  *
237  * \subsection asfdoc_sam0_rtc_calendar_special_considerations_year Year Limit
238  * The RTC module has a year range of 63 years from the starting year configured
239  * when the module is initialized. Dates outside the start to end year range
240  * described below will need software adjustment:
241  *
242  * \f[ [YEAR_{START}, YEAR_{START}+64] \f]
243  *
244  * \subsection asfdoc_sam0_rtc_calendar_special_considerations_clock Clock Setup
245  * \subsubsection asfdoc_sam0_rtc_calendar_clock_samd_r SAM D20/D21/R21/D10/D11/DA1/HA1 Clock Setup.
246  * The RTC is typically clocked by a specialized GCLK generator that has a
247  * smaller prescaler than the others. By default the RTC clock is on, selected
248  * to use the internal 32KHz Resistor/Capacitor (RC)-oscillator with a prescaler
249  * of 32, giving a resulting clock frequency of 1024Hz to the RTC. When the
250  * internal RTC prescaler is set to 1024, this yields an end-frequency of 1Hz
251  * for correct time keeping operations.
252  *
253  * The implementer also has the option to set other end-frequencies.
254  * \ref asfdoc_sam0_rtc_calendar_rtc_out_freq "The table below" lists the
255  * available RTC frequencies for each possible GCLK and RTC input prescaler
256  * options.
257  *
258  * \anchor asfdoc_sam0_rtc_calendar_rtc_out_freq
259  * <table>
260  *   <caption>RTC Output Frequencies from Allowable Input Clocks</caption>
261  *   <tr>
262  *     <th>End-frequency</th>
263  *     <th>GCLK prescaler</th>
264  *     <th>RTC prescaler</th>
265  *   </tr>
266  *   <tr>
267  *     <td>32KHz</td>
268  *     <td>1</td>
269  *     <td>1</td>
270  *   </tr>
271  *   <tr>
272  *     <td>1KHz</td>
273  *     <td>32</td>
274  *     <td>1</td>
275  *   </tr>
276  *   <tr>
277  *     <td>1Hz</td>
278  *     <td>32</td>
279  *     <td>1024</td>
280  *   </tr>
281  * </table>
282  *
283  * The overall RTC module clocking scheme is shown in
284  * \ref asfdoc_sam0_rtc_calendar_rtc_clock_fig "the figure below".
285  *
286  * \anchor asfdoc_sam0_rtc_calendar_rtc_clock_fig
287  * \dot
288  * digraph clocking_scheme {
289  *     rankdir=LR;
290  *     GCLK [shape="record", label="<f0> GCLK | <f1> RTC_GCLK",
291  *         bgcolor="lightgray", style="filled"];
292  *     RTCPRE [shape="record" label="<f0> RTC | <f1> RTC PRESCALER"];
293  *     RTC [shape="record", label="<f0> RTC | <f1> RTC CLOCK"];
294  *
295  *     GCLK:f1 -> RTCPRE:f1;
296  *     RTCPRE:f1 -> RTC:f1;
297  * }
298  * \enddot
299  *
300  * \note For the calendar to operate correctly, an asynchronous clock of 1Hz
301  *       should be used.
302  *
303  * \subsubsection asfdoc_sam0_rtc_calendar_clock_saml SAM L21/C20/C21/R30 Clock Setup
304  * The RTC clock can be selected from OSC32K, XOSC32K, or OSCULP32K. A 32KHz
305  * or 1KHz oscillator clock frequency is required. This clock must be
306  * configured and enabled in the 32KHz oscillator controller before using the RTC.
307  *
308  * \ref asfdoc_sam0_rtc_calendar_rtc_clk lists the available RTC clock.
309  *
310  * \anchor asfdoc_sam0_rtc_calendar_rtc_clk
311  * <table>
312  *   <caption>RTC Clocks Source</caption>
313  *   <tr>
314  *     <th>RTC clock frequency</th>
315  *     <th>Clock source</th>
316  *     <th>Description</th>
317  *   </tr>
318  *   <tr>
319  *     <td>1.024kHz</td>
320  *     <td>ULP1K</td>
321  *     <td>1.024kHz from 32KHz internal ULP oscillator</td>
322  *   </tr>
323  *   <tr>
324  *     <td>32.768kHz</td>
325  *     <td>ULP32K</td>
326  *     <td>32.768kHz from 32KHz internal ULP oscillator</td>
327  *   </tr>
328  *   <tr>
329  *     <td>1.024kHz</td>
330  *     <td>OSC1K</td>
331  *     <td>1.024kHz from 32KHz internal oscillator</td>
332  *   </tr>
333  *   <tr>
334  *     <td>32.768kHz</td>
335  *     <td>OSC32K</td>
336  *     <td>32.768kHz from 3KkHz internal oscillator</td>
337  *   </tr>
338  *   <tr>
339  *     <td>1.024kHz</td>
340  *     <td>XOSC1K</td>
341  *     <td>1.024kHz from 32KHz internal oscillator</td>
342  *   </tr>
343  *   <tr>
344  *     <td>32.768kHz</td>
345  *     <td>XOSC32K</td>
346  *     <td>32.768kHz from 32KHz external crystal oscillator</td>
347  *   </tr>
348  * </table>
349  *
350  * \note For the calendar to operate correctly, an asynchronous clock of 1Hz
351  *       should be used.
352  *
353  * \section asfdoc_sam0_rtc_calendar_extra_info Extra Information
354  *
355  * For extra information, see \ref asfdoc_sam0_rtc_calendar_extra. This includes:
356  *  - \ref asfdoc_sam0_rtc_calendar_extra_acronyms
357  *  - \ref asfdoc_sam0_rtc_calendar_extra_dependencies
358  *  - \ref asfdoc_sam0_rtc_calendar_extra_errata
359  *  - \ref asfdoc_sam0_rtc_calendar_extra_history
360  *
361  *
362  * \section asfdoc_sam0_rtc_calendar_examples Examples
363  *
364  * For a list of examples related to this driver, see
365  * \ref asfdoc_sam0_rtc_calendar_exqsg.
366  *
367  *
368  * \section asfdoc_sam0_rtc_calendar_api_overview API Overview
369  * @{
370  */
371 
372 #include <conf_clocks.h>
373 
374 #if RTC_CALENDAR_ASYNC == true
375 #  include <system_interrupt.h>
376 #endif
377 
378 #ifdef __cplusplus
379 extern "C" {
380 #endif
381 
382 /**
383  * Define port features set according to different device family
384  * @{
385 */
386 #if (SAML21) || (SAML22) || (SAMC20) || (SAMC21) || (SAMR30) || defined(__DOXYGEN__)
387 /** RTC periodic interval interrupt. */
388 #  define FEATURE_RTC_PERIODIC_INT
389 /** RTC prescaler is off. */
390 #  define FEATURE_RTC_PRESCALER_OFF
391 /** RTC clock selection. */
392 #  define FEATURE_RTC_CLOCK_SELECTION
393 #  if !(SAMC20) && !(SAMC21)
394 /** General purpose registers. */
395 #  define FEATURE_RTC_GENERAL_PURPOSE_REG
396 #  endif
397 #else
398 /** RTC continuously updated. */
399 #  define FEATURE_RTC_CONTINUOUSLY_UPDATED
400 #endif
401 
402 #if (SAML22) || defined(__DOXYGEN__)
403 /** RTC tamper detection. */
404 #  define FEATURE_RTC_TAMPER_DETECTION
405 #endif
406 
407 /*@}*/
408 
409 #ifdef FEATURE_RTC_CLOCK_SELECTION
410 /**
411  * \brief Available clock source for RTC.
412  * RTC clock source.
413  */
414 enum rtc_clock_sel {
415 	/** 1.024kHz from 32KHz internal ULP oscillator */
416 	RTC_CLOCK_SELECTION_ULP1K = OSC32KCTRL_RTCCTRL_RTCSEL_ULP1K_Val,
417 	/** 32.768kHz from 32KHz internal ULP oscillator */
418 	RTC_CLOCK_SELECTION_ULP32K = OSC32KCTRL_RTCCTRL_RTCSEL_ULP32K_Val,
419 #if !(SAML22)
420 	/** 1.024kHz from 32KHz internal oscillator */
421 	RTC_CLOCK_SELECTION_OSC1K = OSC32KCTRL_RTCCTRL_RTCSEL_OSC1K_Val,
422 	/** 32.768kHz from 32KHz internal oscillator */
423 	RTC_CLOCK_SELECTION_OSC32K = OSC32KCTRL_RTCCTRL_RTCSEL_OSC32K_Val,
424 #endif
425 	/** 1.024kHz from 32KHz internal oscillator */
426 	RTC_CLOCK_SELECTION_XOSC1K = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC1K_Val,
427 	/** 32.768kHz from 32.768kHz external crystal oscillator */
428 	RTC_CLOCK_SELECTION_XOSC32K = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC32K_Val,
429 };
430 #endif
431 
432 #if !defined (RTC_NUM_OF_ALARMS) && defined(RTC_ALARM_NUM)
433 #define RTC_NUM_OF_ALARMS RTC_ALARM_NUM
434 #endif
435 
436 /**
437  * \brief Available alarm channels.
438  *
439  * Available alarm channels.
440  *
441  * \note Not all alarm channels are available on all devices.
442  */
443 enum rtc_calendar_alarm {
444 	/** Alarm channel 0 */
445 	RTC_CALENDAR_ALARM_0 = 0,
446 #if (RTC_NUM_OF_ALARMS > 1) || defined(__DOXYGEN__)
447 	/** Alarm channel 1 */
448 	RTC_CALENDAR_ALARM_1 = 1,
449 #endif
450 #if (RTC_NUM_OF_ALARMS > 2) || defined(__DOXYGEN__)
451 	/** Alarm channel 2 */
452 	RTC_CALENDAR_ALARM_2 = 2,
453 #endif
454 #if (RTC_NUM_OF_ALARMS > 3) || defined(__DOXYGEN__)
455 	/** Alarm channel 3 */
456 	RTC_CALENDAR_ALARM_3 = 3,
457 #endif
458 };
459 
460 #ifdef FEATURE_RTC_PERIODIC_INT
461 /**
462  * \brief Available periodic interval source.
463  */
464 enum rtc_calendar_periodic_interval{
465 	/** Periodic interval 0 */
466 	RTC_CALENDAR_PERIODIC_INTERVAL_0 = 0,
467 	/** Periodic interval 1 */
468 	RTC_CALENDAR_PERIODIC_INTERVAL_1 = 1,
469 	/** Periodic interval 2 */
470 	RTC_CALENDAR_PERIODIC_INTERVAL_2 = 2,
471 	/** Periodic interval 3 */
472 	RTC_CALENDAR_PERIODIC_INTERVAL_3 = 3,
473 	/** Periodic interval 4 */
474 	RTC_CALENDAR_PERIODIC_INTERVAL_4 = 4,
475 	/** Periodic interval 5 */
476 	RTC_CALENDAR_PERIODIC_INTERVAL_5 = 5,
477 	/** Periodic interval 6 */
478 	RTC_CALENDAR_PERIODIC_INTERVAL_6 = 6,
479 	/** Periodic interval 7 */
480 	RTC_CALENDAR_PERIODIC_INTERVAL_7 = 7,
481 };
482 #endif
483 
484 #if RTC_CALENDAR_ASYNC == true
485 #ifdef FEATURE_RTC_PERIODIC_INT
486 /**
487  * \brief Callback types.
488  *
489  * The available callback types for the RTC calendar module.
490  */
491 enum rtc_calendar_callback {
492 	/** Callback for Periodic Interval 0 Interrupt */
493 	RTC_CALENDAR_CALLBACK_PERIODIC_INTERVAL_0 = 0,
494 	/** Callback for Periodic Interval 1 Interrupt */
495 	RTC_CALENDAR_CALLBACK_PERIODIC_INTERVAL_1,
496 	/** Callback for Periodic Interval 2 Interrupt */
497 	RTC_CALENDAR_CALLBACK_PERIODIC_INTERVAL_2,
498 	/** Callback for Periodic Interval 3 Interrupt */
499 	RTC_CALENDAR_CALLBACK_PERIODIC_INTERVAL_3,
500 	/** Callback for Periodic Interval 4 Interrupt */
501 	RTC_CALENDAR_CALLBACK_PERIODIC_INTERVAL_4,
502 	/** Callback for Periodic Interval 5 Interrupt */
503 	RTC_CALENDAR_CALLBACK_PERIODIC_INTERVAL_5,
504 	/** Callback for Periodic Interval 6 Interrupt */
505 	RTC_CALENDAR_CALLBACK_PERIODIC_INTERVAL_6,
506 	/** Callback for Periodic Interval 7 Interrupt */
507 	RTC_CALENDAR_CALLBACK_PERIODIC_INTERVAL_7,
508 	/** Callback for alarm 0 */
509 	RTC_CALENDAR_CALLBACK_ALARM_0,
510 #  if (RTC_NUM_OF_ALARMS > 1) || defined(__DOXYGEN__)
511 	/** Callback for alarm 1 */
512 	RTC_CALENDAR_CALLBACK_ALARM_1,
513 #  endif
514 #  if (RTC_NUM_OF_ALARMS > 2) || defined(__DOXYGEN__)
515 	/** Callback for alarm 2 */
516 	RTC_CALENDAR_CALLBACK_ALARM_2,
517 #  endif
518 #  if (RTC_NUM_OF_ALARMS > 3) || defined(__DOXYGEN__)
519 	/** Callback for alarm 3 */
520 	RTC_CALENDAR_CALLBACK_ALARM_3,
521 #  endif
522 #ifdef FEATURE_RTC_TAMPER_DETECTION
523 	/** Callback for tamper */
524 	RTC_CALENDAR_CALLBACK_TAMPER,
525 #endif
526 	/** Callback for  overflow */
527 	RTC_CALENDAR_CALLBACK_OVERFLOW,
528 #  if !defined(__DOXYGEN__)
529 	/** Total number of callbacks */
530 	_RTC_CALENDAR_CALLBACK_N
531 #  endif
532 };
533 #else
534 /**
535  * \brief Callback types.
536  *
537  * The available callback types for the RTC calendar module.
538  */
539 enum rtc_calendar_callback {
540 	/** Callback for alarm 0 */
541 	RTC_CALENDAR_CALLBACK_ALARM_0 = 0,
542 #  if (RTC_NUM_OF_ALARMS > 1) || defined(__DOXYGEN__)
543 	/** Callback for alarm 1 */
544 	RTC_CALENDAR_CALLBACK_ALARM_1,
545 #  endif
546 #  if (RTC_NUM_OF_ALARMS > 2) || defined(__DOXYGEN__)
547 	/** Callback for alarm 2 */
548 	RTC_CALENDAR_CALLBACK_ALARM_2,
549 #  endif
550 #  if (RTC_NUM_OF_ALARMS > 3) || defined(__DOXYGEN__)
551 	/** Callback for alarm 3 */
552 	RTC_CALENDAR_CALLBACK_ALARM_3,
553 #  endif
554 #ifdef FEATURE_RTC_TAMPER_DETECTION
555 	/** Callback for tamper */
556 	RTC_CALENDAR_CALLBACK_TAMPER,
557 #endif
558 	/** Callback for  overflow */
559 	RTC_CALENDAR_CALLBACK_OVERFLOW,
560 #  if !defined(__DOXYGEN__)
561 	/** Total number of callbacks */
562 	_RTC_CALENDAR_CALLBACK_N
563 #  endif
564 };
565 #endif
566 
567 #  if !defined(__DOXYGEN__)
568 typedef void (*rtc_calendar_callback_t)(void);
569 #  endif
570 #endif
571 
572 #ifdef FEATURE_RTC_PRESCALER_OFF
573 /**
574  * \brief RTC input clock prescaler settings.
575  *
576  * The available input clock prescaler values for the RTC calendar module.
577  */
578 enum rtc_calendar_prescaler {
579 	/** RTC prescaler is off, and the input clock frequency is
580 	prescaled by a factor of 1 */
581 	RTC_CALENDAR_PRESCALER_OFF      = RTC_MODE2_CTRLA_PRESCALER_OFF,
582 	/** RTC input clock frequency is prescaled by a factor of 1 */
583 	RTC_CALENDAR_PRESCALER_DIV_1    = RTC_MODE2_CTRLA_PRESCALER_DIV1,
584 	/** RTC input clock frequency is prescaled by a factor of 2 */
585 	RTC_CALENDAR_PRESCALER_DIV_2    = RTC_MODE2_CTRLA_PRESCALER_DIV2,
586 	/** RTC input clock frequency is prescaled by a factor of 4 */
587 	RTC_CALENDAR_PRESCALER_DIV_4    = RTC_MODE2_CTRLA_PRESCALER_DIV4,
588 	/** RTC input clock frequency is prescaled by a factor of 8 */
589 	RTC_CALENDAR_PRESCALER_DIV_8    = RTC_MODE2_CTRLA_PRESCALER_DIV8,
590 	/** RTC input clock frequency is prescaled by a factor of 16 */
591 	RTC_CALENDAR_PRESCALER_DIV_16   = RTC_MODE2_CTRLA_PRESCALER_DIV16,
592 	/** RTC input clock frequency is prescaled by a factor of 32 */
593 	RTC_CALENDAR_PRESCALER_DIV_32   = RTC_MODE2_CTRLA_PRESCALER_DIV32,
594 	/** RTC input clock frequency is prescaled by a factor of 64 */
595 	RTC_CALENDAR_PRESCALER_DIV_64   = RTC_MODE2_CTRLA_PRESCALER_DIV64,
596 	/** RTC input clock frequency is prescaled by a factor of 128 */
597 	RTC_CALENDAR_PRESCALER_DIV_128  = RTC_MODE2_CTRLA_PRESCALER_DIV128,
598 	/** RTC input clock frequency is prescaled by a factor of 256 */
599 	RTC_CALENDAR_PRESCALER_DIV_256  = RTC_MODE2_CTRLA_PRESCALER_DIV256,
600 	/** RTC input clock frequency is prescaled by a factor of 512 */
601 	RTC_CALENDAR_PRESCALER_DIV_512  = RTC_MODE2_CTRLA_PRESCALER_DIV512,
602 	/** RTC input clock frequency is prescaled by a factor of 1024 */
603 	RTC_CALENDAR_PRESCALER_DIV_1024 = RTC_MODE2_CTRLA_PRESCALER_DIV1024,
604 };
605 
606 #else
607 /**
608  * \brief RTC input clock prescaler settings.
609  *
610  * The available input clock prescaler values for the RTC calendar module.
611  */
612 enum rtc_calendar_prescaler {
613 	/** RTC input clock frequency is prescaled by a factor of 1 */
614 	RTC_CALENDAR_PRESCALER_DIV_1    = RTC_MODE2_CTRL_PRESCALER_DIV1,
615 	/** RTC input clock frequency is prescaled by a factor of 2 */
616 	RTC_CALENDAR_PRESCALER_DIV_2    = RTC_MODE2_CTRL_PRESCALER_DIV2,
617 	/** RTC input clock frequency is prescaled by a factor of 4 */
618 	RTC_CALENDAR_PRESCALER_DIV_4    = RTC_MODE2_CTRL_PRESCALER_DIV4,
619 	/** RTC input clock frequency is prescaled by a factor of 8 */
620 	RTC_CALENDAR_PRESCALER_DIV_8    = RTC_MODE2_CTRL_PRESCALER_DIV8,
621 	/** RTC input clock frequency is prescaled by a factor of 16 */
622 	RTC_CALENDAR_PRESCALER_DIV_16   = RTC_MODE2_CTRL_PRESCALER_DIV16,
623 	/** RTC input clock frequency is prescaled by a factor of 32 */
624 	RTC_CALENDAR_PRESCALER_DIV_32   = RTC_MODE2_CTRL_PRESCALER_DIV32,
625 	/** RTC input clock frequency is prescaled by a factor of 64 */
626 	RTC_CALENDAR_PRESCALER_DIV_64   = RTC_MODE2_CTRL_PRESCALER_DIV64,
627 	/** RTC input clock frequency is prescaled by a factor of 128 */
628 	RTC_CALENDAR_PRESCALER_DIV_128  = RTC_MODE2_CTRL_PRESCALER_DIV128,
629 	/** RTC input clock frequency is prescaled by a factor of 256 */
630 	RTC_CALENDAR_PRESCALER_DIV_256  = RTC_MODE2_CTRL_PRESCALER_DIV256,
631 	/** RTC input clock frequency is prescaled by a factor of 512 */
632 	RTC_CALENDAR_PRESCALER_DIV_512  = RTC_MODE2_CTRL_PRESCALER_DIV512,
633 	/** RTC input clock frequency is prescaled by a factor of 1024 */
634 	RTC_CALENDAR_PRESCALER_DIV_1024 = RTC_MODE2_CTRL_PRESCALER_DIV1024,
635 };
636 #endif
637 
638 #if !defined(__DOXYGEN__)
639 /**
640  * \brief Device structure.
641  */
642 struct rtc_module {
643 	/** RTC hardware module */
644 	Rtc *hw;
645 	/** If clock mode 24h */
646 	bool clock_24h;
647 #ifdef FEATURE_RTC_CONTINUOUSLY_UPDATED
648 	/** If continuously update clock register */
649 	bool continuously_update;
650 #endif
651 	/** Initial year for counter value 0 */
652 	uint16_t year_init_value;
653 #  if RTC_CALENDAR_ASYNC == true
654 	/** Pointers to callback functions */
655 	volatile rtc_calendar_callback_t callbacks[_RTC_CALENDAR_CALLBACK_N];
656 	/** Mask for registered callbacks */
657 	volatile uint16_t registered_callback;
658 	/** Mask for enabled callbacks */
659 	volatile uint16_t enabled_callback;
660 #  endif
661 };
662 #endif
663 
664 /**
665  * \brief Available mask options for alarms.
666  *
667  * Available mask options for alarms.
668  */
669 enum rtc_calendar_alarm_mask {
670 	/** Alarm disabled */
671 	RTC_CALENDAR_ALARM_MASK_DISABLED = RTC_MODE2_MASK_SEL_OFF,
672 	/** Alarm match on second */
673 	RTC_CALENDAR_ALARM_MASK_SEC      = RTC_MODE2_MASK_SEL_SS,
674 	/** Alarm match on second and minute */
675 	RTC_CALENDAR_ALARM_MASK_MIN      = RTC_MODE2_MASK_SEL_MMSS,
676 	/** Alarm match on second, minute, and hour */
677 	RTC_CALENDAR_ALARM_MASK_HOUR     = RTC_MODE2_MASK_SEL_HHMMSS,
678 	/** Alarm match on second, minute, hour, and day */
679 	RTC_CALENDAR_ALARM_MASK_DAY      = RTC_MODE2_MASK_SEL_DDHHMMSS,
680 	/** Alarm match on second, minute, hour, day, and month */
681 	RTC_CALENDAR_ALARM_MASK_MONTH    = RTC_MODE2_MASK_SEL_MMDDHHMMSS,
682 	/** Alarm match on second, minute, hour, day, month, and year */
683 	RTC_CALENDAR_ALARM_MASK_YEAR     = RTC_MODE2_MASK_SEL_YYMMDDHHMMSS,
684 };
685 
686 /**
687  * \brief RTC Calendar event enable/disable structure.
688  *
689  * Event flags for the \ref rtc_calendar_enable_events() and
690  * \ref rtc_calendar_disable_events().
691  */
692 struct rtc_calendar_events {
693 	/** Generate an output event on each overflow of the RTC count */
694 	bool generate_event_on_overflow;
695 	/** Generate an output event on an alarm channel match against the RTC
696 	 *  count */
697 	bool generate_event_on_alarm[RTC_NUM_OF_ALARMS];
698 	/** Generate an output event periodically at a binary division of the RTC
699 	 *  counter frequency
700 	 */
701 	bool generate_event_on_periodic[8];
702 #ifdef FEATURE_RTC_TAMPER_DETECTION
703 	/** Generate an output event on every tamper input */
704 	bool generate_event_on_tamper;
705 	/** Tamper input event and capture the CLOCK value */
706 	bool on_event_to_tamper;
707 #endif
708 };
709 
710 /**
711  * \brief Time structure.
712  *
713  * Time structure containing the time given by or set to the RTC calendar.
714  * The structure uses seven values to give second, minute, hour, PM/AM, day,
715  * month, and year. It should be initialized via the
716  * \ref rtc_calendar_get_time_defaults() function before use.
717  */
718 struct rtc_calendar_time {
719 	/** Second value */
720 	uint8_t  second;
721 	/** Minute value */
722 	uint8_t  minute;
723 	/** Hour value */
724 	uint8_t  hour;
725 	/** PM/AM value, \c true for PM, or \c false for AM */
726 	bool     pm;
727 	/** Day value, where day 1 is the first day of the month */
728 	uint8_t  day;
729 	/** Month value, where month 1 is January */
730 	uint8_t  month;
731 	/** Year value */
732 	uint16_t year;
733 };
734 
735 /**
736  * \brief Alarm structure.
737  *
738  * Alarm structure containing time of the alarm and a mask to determine when
739  * the alarm will trigger.
740  */
741 struct rtc_calendar_alarm_time {
742 	/** Alarm time */
743 	struct rtc_calendar_time time;
744 	/** Alarm mask to determine on what precision the alarm will match */
745 	enum rtc_calendar_alarm_mask mask;
746 };
747 
748 /**
749  * \brief RTC configuration structure.
750  *
751  * Configuration structure for the RTC instance. This structure should
752  * be initialized using the \ref rtc_calendar_get_config_defaults() before any
753  * user configurations are set.
754  */
755 struct rtc_calendar_config {
756 	/** Input clock prescaler for the RTC module */
757 	enum rtc_calendar_prescaler prescaler;
758 	/** If \c true, clears the clock on alarm match */
759 	bool clear_on_match;
760 #ifdef FEATURE_RTC_CONTINUOUSLY_UPDATED
761 	/** If \c true, the digital counter registers will be continuously updated
762 	 *  so that internal synchronization is not needed when reading the current
763 	 *  count */
764 	bool continuously_update;
765 #endif
766 	/** If \c true, time is represented in 24 hour mode */
767 	bool clock_24h;
768 	/** Initial year for counter value 0 */
769 	uint16_t year_init_value;
770 #if (SAML21XXXB) || (SAML22) || (SAMC20) || (SAMC21) || (SAMR30)
771 	/** Enable count read synchronization. The CLOCK value requires
772 	 * synchronization when reading. Disabling the synchronization
773 	 * will prevent the CLOCK value from displaying the current value. */
774 	bool enable_read_sync;
775 #endif
776 	/** Alarm values */
777 	struct rtc_calendar_alarm_time alarm[RTC_NUM_OF_ALARMS];
778 };
779 
780 
781 /**
782  * \name Configuration and Initialization
783  * @{
784  */
785 
786 /**
787  * \brief Initialize a \c time structure.
788  *
789  * This will initialize a given time structure to the time 00:00:00 (hh:mm:ss)
790  * and date 2000-01-01 (YYYY-MM-DD).
791  *
792  * \param[out] time  Time structure to initialize
793  */
rtc_calendar_get_time_defaults(struct rtc_calendar_time * const time)794 static inline void rtc_calendar_get_time_defaults(
795 		struct rtc_calendar_time *const time)
796 {
797 	time->second = 0;
798 	time->minute = 0;
799 	time->hour   = 0;
800 	time->pm     = 0;
801 	time->day    = 1;
802 	time->month  = 1;
803 	time->year   = 2000;
804 }
805 
806 /**
807  * \brief Gets the RTC default settings.
808  *
809  * Initializes the configuration structure to the known default values. This
810  * function should be called at the start of any RTC initiation.
811  *
812  * The default configuration is as follows:
813  *  - Input clock divided by a factor of 1024
814  *  - Clear on alarm match off
815  *  - Continuously sync clock off
816  *  - 12 hour calendar
817  *  - Start year 2000 (Year 0 in the counter will be year 2000)
818  *  - Events off
819  *  - Alarms set to January 1. 2000, 00:00:00
820  *  - Alarm will match on second, minute, hour, day, month, and year
821  *  - Clock read synchronization is enabled for SAM L22
822  *
823  *  \param[out] config  Configuration structure to be initialized to default
824  *                      values
825  */
rtc_calendar_get_config_defaults(struct rtc_calendar_config * const config)826 static inline void rtc_calendar_get_config_defaults(
827 		struct rtc_calendar_config *const config)
828 {
829 	/* Sanity check argument */
830 	Assert(config);
831 
832 	/* Initialize and set time structure to default */
833 	struct rtc_calendar_time time;
834 	rtc_calendar_get_time_defaults(&time);
835 
836 	/* Set defaults into configuration structure */
837 	config->prescaler           = RTC_CALENDAR_PRESCALER_DIV_1024;
838 	config->clear_on_match      = false;
839 #ifdef FEATURE_RTC_CONTINUOUSLY_UPDATED
840 	config->continuously_update = false;
841 #endif
842 	config->clock_24h           = false;
843 	config->year_init_value     = 2000;
844 #if (SAML21XXXB) || (SAML22) || (SAMC20) || (SAMC21) || (SAMR30)
845 	config->enable_read_sync    = true;
846 #endif
847 	for (uint8_t i = 0; i < RTC_NUM_OF_ALARMS; i++) {
848 		config->alarm[i].time = time;
849 		config->alarm[i].mask = RTC_CALENDAR_ALARM_MASK_YEAR;
850 	}
851 }
852 
853 void rtc_calendar_reset(struct rtc_module *const module);
854 void rtc_calendar_enable(struct rtc_module *const module);
855 void rtc_calendar_disable(struct rtc_module *const module);
856 
857 #if (RTC_INST_NUM > 1) && !defined(__DOXYGEN__)
858 /**
859  * \internal Find the index of given RTC module instance.
860  *
861  * \param[in] hw  RTC module instance pointer
862  *
863  * \return Index of the given RTC module instance.
864  */
_rtc_get_inst_index(Rtc * const hw)865 uint8_t _rtc_get_inst_index(
866 		Rtc *const hw)
867 {
868 	/* List of available RTC modules */
869 	static Rtc *const rtc_modules[RTC_INST_NUM] = RTC_INSTS;
870 
871 	/* Find index for RTC instance */
872 	for (uint32_t i = 0; i < RTC_INST_NUM; i++) {
873 		if (hw == rtc_modules[i]) {
874 			return i;
875 		}
876 	}
877 
878 	/* Invalid data given */
879 	Assert(false);
880 	return 0;
881 }
882 #endif /* (RTC_INST_NUM > 1) && !defined(__DOXYGEN__) */
883 
884 void rtc_calendar_init(
885 		struct rtc_module *const module,
886 		Rtc *const hw,
887 		const struct rtc_calendar_config *const config);
888 
889 void rtc_calendar_swap_time_mode(struct rtc_module *const module);
890 
891 enum status_code rtc_calendar_frequency_correction(
892 		struct rtc_module *const module,
893 		const int8_t value);
894 
895 /** @} */
896 
897 
898 /** \name Time and Alarm Management
899  * @{
900  */
901 uint32_t rtc_calendar_time_to_register_value(
902 		struct rtc_module *const module,
903 		const struct rtc_calendar_time *const time);
904 void rtc_calendar_register_value_to_time(
905 		struct rtc_module *const module,
906 		const uint32_t register_value,
907 		struct rtc_calendar_time *const time);
908 
909 void rtc_calendar_set_time(
910 		struct rtc_module *const module,
911 		const struct rtc_calendar_time *const time);
912 
913 void rtc_calendar_get_time(
914 		struct rtc_module *const module,
915 		struct rtc_calendar_time *const time);
916 
917 enum status_code rtc_calendar_set_alarm(
918 		struct rtc_module *const module,
919 		const struct rtc_calendar_alarm_time *const alarm,
920 		const enum rtc_calendar_alarm alarm_index);
921 
922 enum status_code rtc_calendar_get_alarm(
923 		struct rtc_module *const module,
924 		struct rtc_calendar_alarm_time *const alarm,
925 		const enum rtc_calendar_alarm alarm_index);
926 
927 /** @} */
928 
929 
930 /** \name Status Flag Management
931  * @{
932  */
933 
934 /**
935  * \brief Check if an RTC overflow has occurred.
936  *
937  * Checks the overflow flag in the RTC. The flag is set when there
938  * is an overflow in the clock.
939  *
940  * \param[in,out] module  Pointer to the software instance struct
941  *
942  * \return Overflow state of the RTC module.
943  *
944  * \retval true   If the RTC count value has overflowed
945  * \retval false  If the RTC count value has not overflowed
946  */
rtc_calendar_is_overflow(struct rtc_module * const module)947 static inline bool rtc_calendar_is_overflow(struct rtc_module *const module)
948 {
949 	/* Sanity check arguments */
950 	Assert(module);
951 	Assert(module->hw);
952 
953 	Rtc *const rtc_module = module->hw;
954 
955 	/* Return status of flag */
956 	return (rtc_module->MODE2.INTFLAG.reg & RTC_MODE2_INTFLAG_OVF);
957 }
958 
959 /**
960  * \brief Clears the RTC overflow flag.
961  *
962  * \param[in,out] module  Pointer to the software instance struct
963  *
964  * Clears the RTC module counter overflow flag, so that new overflow conditions
965  * can be detected.
966  */
rtc_calendar_clear_overflow(struct rtc_module * const module)967 static inline void rtc_calendar_clear_overflow(struct rtc_module *const module)
968 {
969 	/* Sanity check arguments */
970 	Assert(module);
971 	Assert(module->hw);
972 
973 	Rtc *const rtc_module = module->hw;
974 
975 	/* Clear flag */
976 	rtc_module->MODE2.INTFLAG.reg = RTC_MODE2_INTFLAG_OVF;
977 }
978 
979 #ifdef FEATURE_RTC_PERIODIC_INT
980 /**
981  * \brief Check if an RTC periodic interval interrupt has occurred.
982  *
983  * Checks the periodic interval flag in the RTC.
984  *
985  * \param[in,out]  module  RTC hardware module
986  * \param[in]  n  RTC periodic interval interrupt
987  *
988  * \return Periodic interval interrupt state of the RTC module.
989  *
990  * \retval true   RTC periodic interval interrupt occur
991  * \retval false  RTC periodic interval interrupt doesn't occur
992  */
rtc_calendar_is_periodic_interval(struct rtc_module * const module,enum rtc_calendar_periodic_interval n)993 static inline bool rtc_calendar_is_periodic_interval(struct rtc_module *const module,
994 										enum rtc_calendar_periodic_interval n)
995 {
996 	/* Sanity check arguments */
997 	Assert(module);
998 	Assert(module->hw);
999 
1000 	Rtc *const rtc_module = module->hw;
1001 
1002 	/* Return status of flag */
1003 	return (rtc_module->MODE2.INTFLAG.reg & RTC_MODE2_INTFLAG_PER(1 << n));
1004 }
1005 
1006 /**
1007  * \brief Clears the RTC periodic interval flag.
1008  *
1009  * Clears the RTC module counter periodic interval flag, so that new periodic
1010  *  interval conditions can be detected.
1011  *
1012  * \param[in,out]  module  RTC hardware module
1013  * \param[in]  n  RTC periodic interval interrupt
1014  */
rtc_calendar_clear_periodic_interval(struct rtc_module * const module,enum rtc_calendar_periodic_interval n)1015 static inline void rtc_calendar_clear_periodic_interval(struct rtc_module *const module,
1016 											enum rtc_calendar_periodic_interval n)
1017 {
1018 	/* Sanity check arguments */
1019 	Assert(module);
1020 	Assert(module->hw);
1021 
1022 	Rtc *const rtc_module = module->hw;
1023 
1024 	/* Clear periodic interval flag */
1025 	rtc_module->MODE2.INTFLAG.reg = RTC_MODE2_INTFLAG_PER(1 << n);
1026 }
1027 #endif
1028 
1029 /**
1030  * \brief Check the RTC alarm flag.
1031  *
1032  * Check if the specified alarm flag is set. The flag is set when there
1033  * is a compare match between the alarm value and the clock.
1034  *
1035  * \param[in,out] module  Pointer to the software instance struct
1036  * \param[in] alarm_index  Index of the alarm to check
1037  *
1038  * \returns Match status of the specified alarm.
1039  *
1040  * \retval true   If the specified alarm has matched the current time
1041  * \retval false  If the specified alarm has not matched the current time
1042  */
rtc_calendar_is_alarm_match(struct rtc_module * const module,const enum rtc_calendar_alarm alarm_index)1043 static inline bool rtc_calendar_is_alarm_match(
1044 		struct rtc_module *const module,
1045 		const enum rtc_calendar_alarm alarm_index)
1046 {
1047 	/* Sanity check arguments */
1048 	Assert(module);
1049 	Assert(module->hw);
1050 
1051 	Rtc *const rtc_module = module->hw;
1052 
1053 	/* Sanity check */
1054 	if ((uint32_t)alarm_index > RTC_NUM_OF_ALARMS) {
1055 		Assert(false);
1056 		return false;
1057 	}
1058 
1059 	/* Return int flag status */
1060 	return (rtc_module->MODE2.INTFLAG.reg & RTC_MODE2_INTFLAG_ALARM(1 << alarm_index));
1061 }
1062 
1063 /**
1064  * \brief Clears the RTC alarm match flag.
1065  *
1066  * Clear the requested alarm match flag, so that future alarm matches can be
1067  * determined.
1068  *
1069  * \param[in,out] module  Pointer to the software instance struct
1070  * \param[in] alarm_index  The index of the alarm match to clear
1071  *
1072  * \return Status of the alarm match clear operation.
1073  *
1074  * \retval STATUS_OK               If flag was cleared correctly
1075  * \retval STATUS_ERR_INVALID_ARG  If invalid argument(s) were provided
1076  */
rtc_calendar_clear_alarm_match(struct rtc_module * const module,const enum rtc_calendar_alarm alarm_index)1077 static inline enum status_code rtc_calendar_clear_alarm_match(
1078 		struct rtc_module *const module,
1079 		const enum rtc_calendar_alarm alarm_index)
1080 {
1081 	/* Sanity check arguments */
1082 	Assert(module);
1083 	Assert(module->hw);
1084 
1085 	Rtc *const rtc_module = module->hw;
1086 
1087 	/* Sanity check */
1088 	if ((uint32_t)alarm_index > RTC_NUM_OF_ALARMS) {
1089 		Assert(false);
1090 		return STATUS_ERR_INVALID_ARG;
1091 	}
1092 
1093 	/* Clear flag */
1094 	rtc_module->MODE2.INTFLAG.reg = RTC_MODE2_INTFLAG_ALARM(1 << alarm_index);
1095 
1096 	return STATUS_OK;
1097 }
1098 
1099 /** @} */
1100 
1101 
1102 /**
1103  * \name Event Management
1104  * @{
1105  */
1106 
1107 /**
1108  * \brief Enables an RTC event output.
1109  *
1110  *  Enables one or more output events from the RTC module. See
1111  *  \ref rtc_calendar_events for a list of events this module supports.
1112  *
1113  *  \note Events cannot be altered while the module is enabled.
1114  *
1115  *  \param[in,out] module  Pointer to the software instance struct
1116  *  \param[in] events    Struct containing flags of events to enable
1117  */
rtc_calendar_enable_events(struct rtc_module * const module,struct rtc_calendar_events * const events)1118 static inline void rtc_calendar_enable_events(
1119 		struct rtc_module *const module,
1120 		struct rtc_calendar_events *const events)
1121 {
1122 	/* Sanity check arguments */
1123 	Assert(module);
1124 	Assert(module->hw);
1125 
1126 	Rtc *const rtc_module = module->hw;
1127 
1128 	uint32_t event_mask = 0;
1129 
1130 	/* Check if the user has requested an overflow event */
1131 	if (events->generate_event_on_overflow) {
1132 		event_mask |= RTC_MODE2_EVCTRL_OVFEO;
1133 	}
1134 
1135 	/* Check if the user has requested any alarm events */
1136 	for (uint8_t i = 0; i < RTC_NUM_OF_ALARMS; i++) {
1137 		if (events->generate_event_on_alarm[i]) {
1138 			event_mask |= RTC_MODE2_EVCTRL_ALARMEO(1 << i);
1139 		}
1140 	}
1141 
1142 	/* Check if the user has requested any periodic events */
1143 	for (uint8_t i = 0; i < 8; i++) {
1144 		if (events->generate_event_on_periodic[i]) {
1145 			event_mask |= RTC_MODE2_EVCTRL_PEREO(1 << i);
1146 		}
1147 	}
1148 
1149 #ifdef FEATURE_RTC_TAMPER_DETECTION
1150 	/* Check if the user has requested a tamper event output */
1151 	if (events->generate_event_on_tamper) {
1152 		event_mask |= RTC_MODE2_EVCTRL_TAMPEREO;
1153 	}
1154 
1155 	/* Check if the user has requested a tamper event input */
1156 	if (events->on_event_to_tamper) {
1157 		event_mask |= RTC_MODE2_EVCTRL_TAMPEVEI;
1158 	}
1159 #endif
1160 
1161 	/* Enable given event(s) */
1162 	rtc_module->MODE2.EVCTRL.reg |= event_mask;
1163 }
1164 
1165 /**
1166  * \brief Disables an RTC event output.
1167  *
1168  *  Disabled one or more output events from the RTC module. See
1169  *  \ref rtc_calendar_events for a list of events this module supports.
1170  *
1171  *  \note Events cannot be altered while the module is enabled.
1172  *
1173  *  \param[in,out] module  Pointer to the software instance struct
1174  *  \param[in] events    Struct containing flags of events to disable
1175  */
rtc_calendar_disable_events(struct rtc_module * const module,struct rtc_calendar_events * const events)1176 static inline void rtc_calendar_disable_events(
1177 		struct rtc_module *const module,
1178 		struct rtc_calendar_events *const events)
1179 {
1180 	/* Sanity check arguments */
1181 	Assert(module);
1182 	Assert(module->hw);
1183 
1184 	Rtc *const rtc_module = module->hw;
1185 
1186 	uint32_t event_mask = 0;
1187 
1188 	/* Check if the user has requested an overflow event */
1189 	if (events->generate_event_on_overflow) {
1190 		event_mask |= RTC_MODE2_EVCTRL_OVFEO;
1191 	}
1192 
1193 	/* Check if the user has requested any alarm events */
1194 	for (uint8_t i = 0; i < RTC_NUM_OF_ALARMS; i++) {
1195 		if (events->generate_event_on_alarm[i]) {
1196 			event_mask |= RTC_MODE2_EVCTRL_ALARMEO(1 << i);
1197 		}
1198 	}
1199 
1200 	/* Check if the user has requested any periodic events */
1201 	for (uint8_t i = 0; i < 8; i++) {
1202 		if (events->generate_event_on_periodic[i]) {
1203 			event_mask |= RTC_MODE2_EVCTRL_PEREO(1 << i);
1204 		}
1205 	}
1206 
1207 #ifdef FEATURE_RTC_TAMPER_DETECTION
1208 	/* Check if the user has requested a tamper event output */
1209 	if (events->generate_event_on_tamper) {
1210 		event_mask |= RTC_MODE2_EVCTRL_TAMPEREO;
1211 	}
1212 
1213 	/* Check if the user has requested a tamper event input */
1214 	if (events->on_event_to_tamper) {
1215 		event_mask |= RTC_MODE2_EVCTRL_TAMPEVEI;
1216 	}
1217 #endif
1218 
1219 	/* Disable given event(s) */
1220 	rtc_module->MODE2.EVCTRL.reg &= ~event_mask;
1221 }
1222 
1223 /** @} */
1224 
1225 #ifdef FEATURE_RTC_GENERAL_PURPOSE_REG
1226 /**
1227  * \name RTC General Purpose Registers
1228  * @{
1229  */
1230 
1231 /**
1232  * \brief Write a value into general purpose register.
1233  *
1234  * \param[in] module  Pointer to the software instance struct
1235  * \param[in] n  General purpose type
1236  * \param[in] index General purpose register index (0..3)
1237  *
1238  */
rtc_write_general_purpose_reg(struct rtc_module * const module,const uint8_t index,uint32_t value)1239 static inline void rtc_write_general_purpose_reg(
1240 	struct rtc_module *const module,
1241 	const  uint8_t index,
1242 	uint32_t value)
1243 {
1244 	/* Sanity check arguments */
1245 	Assert(module);
1246 	Assert(module->hw);
1247 	Assert(index <= 3);
1248 
1249 	Rtc *const rtc_module = module->hw;
1250 
1251 	rtc_module->MODE0.GP[index].reg = value;
1252 }
1253 
1254 /**
1255  * \brief Read the value from general purpose register.
1256  *
1257  * \param[in] module  Pointer to the software instance struct
1258  * \param[in] index General purpose register index (0..3)
1259  *
1260  * \return Value of general purpose register.
1261  */
rtc_read_general_purpose_reg(struct rtc_module * const module,const uint8_t index)1262 static inline uint32_t rtc_read_general_purpose_reg(
1263 	struct rtc_module *const module,
1264 	const  uint8_t index)
1265 {
1266 	/* Sanity check arguments */
1267 	Assert(module);
1268 	Assert(module->hw);
1269 	Assert(index <= 3);
1270 
1271 	Rtc *const rtc_module = module->hw;
1272 
1273 	return rtc_module->MODE0.GP[index].reg;
1274 }
1275 
1276 /** @} */
1277 #endif
1278 
1279 #ifdef FEATURE_RTC_TAMPER_DETECTION
1280 #include "rtc_tamper.h"
1281 /**
1282  * \brief Get the tamper stamp value.
1283  *
1284  * \param[in,out] module  Pointer to the software instance struct
1285  * \param[out] time  Pointer to value that filled with tamper stamp time
1286  */
1287 void rtc_tamper_get_stamp (struct rtc_module *const module,
1288 		struct rtc_calendar_time *const time);
1289 #endif
1290 
1291 /** @} */
1292 
1293 #ifdef __cplusplus
1294 }
1295 #endif
1296 
1297 
1298 /**
1299  * \page asfdoc_sam0_rtc_calendar_extra Extra Information for RTC (CAL) Driver
1300  *
1301  * \section asfdoc_sam0_rtc_calendar_extra_acronyms Acronyms
1302  * Below is a table listing the acronyms used in this module, along with their
1303  * intended meanings.
1304  *
1305  * <table>
1306  *	<tr>
1307  *		<th>Acronym</td>
1308  *		<th>Description</td>
1309  *	</tr>
1310  *	<tr>
1311  *		<td>RTC</td>
1312  *		<td>Real Time Counter</td>
1313  *	</tr>
1314  *	<tr>
1315  *		<td>PPM</td>
1316  *		<td>Part Per Million</td>
1317  *	</tr>
1318  *	<tr>
1319  *		<td>RC</td>
1320  *		<td>Resistor/Capacitor</td>
1321  *	</tr>
1322  * </table>
1323  *
1324  *
1325  * \section asfdoc_sam0_rtc_calendar_extra_dependencies Dependencies
1326  * This driver has the following dependencies:
1327  *
1328  *  - None
1329  *
1330  *
1331  * \section asfdoc_sam0_rtc_calendar_extra_errata Errata
1332  * There are no errata related to this driver.
1333  *
1334  *
1335  * \section asfdoc_sam0_rtc_calendar_extra_history Module History
1336  * An overview of the module history is presented in the table below, with
1337  * details on the enhancements and fixes made to the module since its first
1338  * release. The current version of this corresponds to the newest version in
1339  * the table.
1340  *
1341  * <table>
1342  *	<tr>
1343  *		<th>Changelog</th>
1344  *	</tr>
1345  *	<tr>
1346  *		<td>Added support for RTC tamper feature</td>
1347  *	</tr>
1348  *	<tr>
1349  *		<td>Added driver instance parameter to all API function calls, except
1350  *          get_config_defaults</td>
1351  *	</tr>
1352  *	<tr>
1353  *		<td>Updated initialization function to also enable the digital interface
1354  *          clock to the module if it is disabled</td>
1355  *	</tr>
1356  *	<tr>
1357  *		<td>Initial release</td>
1358  *	</tr>
1359  * </table>
1360  */
1361 
1362 /**
1363  * \page asfdoc_sam0_rtc_calendar_exqsg Examples for RTC CAL Driver
1364  *
1365  * This is a list of the available Quick Start guides (QSGs) and example
1366  * applications for \ref asfdoc_sam0_rtc_calendar_group. QSGs are simple
1367  * examples with step-by-step instructions to configure and use this driver in a
1368  * selection of use cases. Note that a QSG can be compiled as a standalone
1369  * application or be added to the user application.
1370  *
1371  *  - \subpage asfdoc_sam0_rtc_calendar_basic_use_case
1372  * \if RTC_CALENDAR_CALLBACK_MODE
1373  *  - \subpage asfdoc_sam0_rtc_calendar_callback_use_case
1374  * \endif
1375  *
1376  * \page asfdoc_sam0_rtc_calendar_document_revision_history Document Revision History
1377  *
1378  * <table>
1379  *	<tr>
1380  *		<th>Doc. Rev.</td>
1381  *		<th>Date</td>
1382  *		<th>Comments</td>
1383  *	</tr>
1384  *	<tr>
1385  *		<td>42126E</td>
1386  *		<td>12/2015</td>
1387  *		<td>Added support for SAM L21/L22, SAMR30, SAM C21, SAM D09, and SAM DA1</td>
1388  *	</tr>
1389  *	<tr>
1390  *		<td>42126D</td>
1391  *		<td>12/2014</td>
1392  *		<td>Added support for SAM R21 and SAM D10/D11</td>
1393  *	</tr>
1394  *	<tr>
1395  *		<td>42126C</td>
1396  *		<td>01/2014</td>
1397  *		<td>Added support for SAM D21</td>
1398  *	</tr>
1399  *	<tr>
1400  *		<td>42126B</td>
1401  *		<td>06/2013</td>
1402  *		<td>Added additional documentation on the event system. Corrected
1403  *          documentation typos</td>
1404  *	</tr>
1405  *	<tr>
1406  *		<td>42126A</td>
1407  *		<td>06/2013</td>
1408  *		<td>Initial document release</td>
1409  *	</tr>
1410  * </table>
1411  */
1412 
1413 #endif /* RTC_CALENDAR_H_INCLUDED */
1414 
1415