1 /***************************************************************************//**
2  * @file
3  * @brief SLEEPTIMER API definition.
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Zlib
10  *
11  * The licensor of this software is Silicon Laboratories Inc.
12  *
13  * This software is provided 'as-is', without any express or implied
14  * warranty. In no event will the authors be held liable for any damages
15  * arising from the use of this software.
16  *
17  * Permission is granted to anyone to use this software for any purpose,
18  * including commercial applications, and to alter it and redistribute it
19  * freely, subject to the following restrictions:
20  *
21  * 1. The origin of this software must not be misrepresented; you must not
22  *    claim that you wrote the original software. If you use this software
23  *    in a product, an acknowledgment in the product documentation would be
24  *    appreciated but is not required.
25  * 2. Altered source versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.
27  * 3. This notice may not be removed or altered from any source distribution.
28  *
29  ******************************************************************************/
30 
31 /***************************************************************************//**
32  * @addtogroup sleeptimer Sleep Timer
33  * @{
34  ******************************************************************************/
35 
36 #ifndef SL_SLEEPTIMER_H
37 #define SL_SLEEPTIMER_H
38 
39 #include <stdint.h>
40 #include <stddef.h>
41 #include <stdbool.h>
42 #include "sl_status.h"
43 #include "sl_common.h"
44 #include "sl_code_classification.h"
45 
46 /// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
47 #define SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG (0x01)
48 #define SL_SLEEPTIMER_ANY_FLAG                                  (0xFF)
49 
50 #define SLEEPTIMER_ENUM(name) typedef uint8_t name; enum name##_enum
51 
52 /// @endcond
53 
54 /// Timestamp, wall clock time in seconds.
55 typedef uint32_t sl_sleeptimer_timestamp_t;
56 
57 // Timestamp, 64 bits wall clock in seconds.
58 typedef uint64_t sl_sleeptimer_timestamp_64_t;     ///< sl sleeptimer timestamp 64 t
59 
60 /// Time zone offset from UTC(second).
61 typedef int32_t sl_sleeptimer_time_zone_offset_t;
62 
63 // Forward declaration
64 typedef struct sl_sleeptimer_timer_handle sl_sleeptimer_timer_handle_t;
65 
66 /***************************************************************************//**
67  * Typedef for the user supplied callback function which is called when
68  * a timer expires.
69  *
70  * @param handle The timer handle.
71  *
72  * @param data An extra parameter for the user application.
73  ******************************************************************************/
74 typedef void (*sl_sleeptimer_timer_callback_t)(sl_sleeptimer_timer_handle_t *handle, void *data);
75 
76 /// @brief Timer structure for sleeptimer
77 struct sl_sleeptimer_timer_handle {
78   void *callback_data;                     ///< User data to pass to callback function.
79   uint8_t priority;                        ///< Priority of timer.
80   uint16_t option_flags;                   ///< Option flags.
81   sl_sleeptimer_timer_handle_t *next;      ///< Pointer to next element in list.
82   sl_sleeptimer_timer_callback_t callback; ///< Function to call when timer expires.
83   uint32_t timeout_periodic;               ///< Periodic timeout.
84   uint32_t delta;                          ///< Delay relative to previous element in list.
85   uint32_t timeout_expected_tc;            ///< Expected tick count of the next timeout (only used for periodic timer).
86   uint16_t conversion_error;               ///< The error when converting ms to ticks (thousandths of ticks)
87   uint16_t accumulated_error;              ///< Accumulated conversion error (thousandths of ticks)
88 };
89 
90 /// @brief Month enum.
SLEEPTIMER_ENUM(sl_sleeptimer_month_t)91 SLEEPTIMER_ENUM(sl_sleeptimer_month_t) {
92   MONTH_JANUARY = 0,
93   MONTH_FEBRUARY = 1,
94   MONTH_MARCH   = 2,
95   MONTH_APRIL = 3,
96   MONTH_MAY = 4,
97   MONTH_JUNE = 5,
98   MONTH_JULY = 6,
99   MONTH_AUGUST = 7,
100   MONTH_SEPTEMBER = 8,
101   MONTH_OCTOBER = 9,
102   MONTH_NOVEMBER = 10,
103   MONTH_DECEMBER = 11,
104 };
105 
106 /// @brief Week Day enum.
SLEEPTIMER_ENUM(sl_sleeptimer_weekDay_t)107 SLEEPTIMER_ENUM(sl_sleeptimer_weekDay_t) {
108   DAY_SUNDAY = 0,
109   DAY_MONDAY = 1,
110   DAY_TUESDAY = 2,
111   DAY_WEDNESDAY = 3,
112   DAY_THURSDAY = 4,
113   DAY_FRIDAY = 5,
114   DAY_SATURDAY = 6,
115 };
116 
117 /// @brief Time and Date structure.
118 typedef  struct  time_date {
119   uint8_t sec;                                ///< Second (0-59)
120   uint8_t min;                                ///< Minute of month (0-59)
121   uint8_t hour;                               ///< Hour (0-23)
122   uint8_t month_day;                          ///< Day of month (1-31)
123   sl_sleeptimer_month_t month;                ///< Month (0-11)
124   uint16_t year;                              ///< Year, based on a 1900 Epoch.
125   sl_sleeptimer_weekDay_t day_of_week;        ///< Day of week (0-6)
126   uint16_t day_of_year;                       ///< Day of year (1-366)
127   sl_sleeptimer_time_zone_offset_t time_zone; ///< Offset, in seconds, from UTC
128 } sl_sleeptimer_date_t;
129 
130 #ifdef __cplusplus
131 extern "C" {
132 #endif
133 
134 /***************************************************************************//**
135  * Initializes the Sleeptimer.
136  *
137  * @return SL_STATUS_OK if successful. Error code otherwise.
138  ******************************************************************************/
139 sl_status_t sl_sleeptimer_init(void);
140 
141 /***************************************************************************//**
142  * Starts a 32 bits timer.
143  *
144  * @param handle Pointer to handle to timer.
145  * @param timeout Timer timeout, in timer ticks.
146  * @param callback Callback function that will be called when
147  *        initial/periodic timeout expires.
148  * @param callback_data Pointer to user data that will be passed to callback.
149  * @param priority Priority of callback. Useful in case multiple timer expire
150  *        at the same time. 0 = highest priority.
151  * @param option_flags Bit array of option flags for the timer.
152  *        Valid bit-wise OR of one or more of the following:
153  *          - SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG
154  *        or 0 for not flags.
155  *
156  * @note This function cannot be called from an interrupt with a higher
157  *       priority than BASEPRI.
158  *
159  * @return SL_STATUS_OK if successful. Error code otherwise.
160  ******************************************************************************/
161 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
162 sl_status_t sl_sleeptimer_start_timer(sl_sleeptimer_timer_handle_t *handle,
163                                       uint32_t timeout,
164                                       sl_sleeptimer_timer_callback_t callback,
165                                       void *callback_data,
166                                       uint8_t priority,
167                                       uint16_t option_flags);
168 
169 /***************************************************************************//**
170  * Restarts a 32 bits timer.
171  *
172  * @param handle Pointer to handle to timer.
173  * @param timeout Timer timeout, in timer ticks.
174  * @param callback Callback function that will be called when
175  *        initial/periodic timeout expires.
176  * @param callback_data Pointer to user data that will be passed to callback.
177  * @param priority Priority of callback. Useful in case multiple timer expire
178  *        at the same time. 0 = highest priority.
179  * @param option_flags Bit array of option flags for the timer.
180  *        Valid bit-wise OR of one or more of the following:
181  *          - SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG
182  *        or 0 for not flags.
183  *
184  * @note This function cannot be called from an interrupt with a higher
185  *       priority than BASEPRI.
186  *
187  * @return SL_STATUS_OK if successful. Error code otherwise.
188  ******************************************************************************/
189 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
190 sl_status_t sl_sleeptimer_restart_timer(sl_sleeptimer_timer_handle_t *handle,
191                                         uint32_t timeout,
192                                         sl_sleeptimer_timer_callback_t callback,
193                                         void *callback_data,
194                                         uint8_t priority,
195                                         uint16_t option_flags);
196 
197 /***************************************************************************//**
198  * Starts a 32 bits periodic timer.
199  *
200  * @param handle Pointer to handle to timer.
201  * @param timeout Timer periodic timeout, in timer ticks.
202  * @param callback Callback function that will be called when
203  *        initial/periodic timeout expires.
204  * @param callback_data Pointer to user data that will be passed to callback.
205  * @param priority Priority of callback. Useful in case multiple timer expire
206  *        at the same time. 0 = highest priority.
207  * @param option_flags Bit array of option flags for the timer.
208  *        Valid bit-wise OR of one or more of the following:
209  *          - SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG
210  *        or 0 for not flags.
211  *
212  * @note This function cannot be called from an interrupt with a higher
213  *       priority than BASEPRI.
214  *
215  * @return SL_STATUS_OK if successful. Error code otherwise.
216  ******************************************************************************/
217 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
218 sl_status_t sl_sleeptimer_start_periodic_timer(sl_sleeptimer_timer_handle_t *handle,
219                                                uint32_t timeout,
220                                                sl_sleeptimer_timer_callback_t callback,
221                                                void *callback_data,
222                                                uint8_t priority,
223                                                uint16_t option_flags);
224 
225 /***************************************************************************//**
226  * Restarts a 32 bits periodic timer.
227  *
228  * @param handle Pointer to handle to timer.
229  * @param timeout Timer periodic timeout, in timer ticks.
230  * @param callback Callback function that will be called when
231  *        initial/periodic timeout expires.
232  * @param callback_data Pointer to user data that will be passed to callback.
233  * @param priority Priority of callback. Useful in case multiple timer expire
234  *        at the same time. 0 = highest priority.
235  * @param option_flags Bit array of option flags for the timer.
236  *        Valid bit-wise OR of one or more of the following:
237  *          - SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG
238  *        or 0 for not flags.
239  *
240  * @note This function cannot be called from an interrupt with a higher
241  *       priority than BASEPRI.
242  *
243  * @return SL_STATUS_OK if successful. Error code otherwise.
244  ******************************************************************************/
245 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
246 sl_status_t sl_sleeptimer_restart_periodic_timer(sl_sleeptimer_timer_handle_t *handle,
247                                                  uint32_t timeout,
248                                                  sl_sleeptimer_timer_callback_t callback,
249                                                  void *callback_data,
250                                                  uint8_t priority,
251                                                  uint16_t option_flags);
252 
253 /***************************************************************************//**
254  * Stops a timer.
255  *
256  * @param handle Pointer to handle to timer.
257  *
258  * @note This function cannot be called from an interrupt with a higher
259  *       priority than BASEPRI.
260  *
261  * @return SL_STATUS_OK if successful. Error code otherwise.
262  ******************************************************************************/
263 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
264 sl_status_t sl_sleeptimer_stop_timer(sl_sleeptimer_timer_handle_t *handle);
265 
266 /***************************************************************************//**
267  * Gets the status of a timer.
268  *
269  * @param handle Pointer to handle to timer.
270  * @param running Pointer to the status of the timer.
271  *
272  * @note A non periodic timer is considered not running during its callback.
273  *
274  * @return SL_STATUS_OK if successful. Error code otherwise.
275  ******************************************************************************/
276 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
277 sl_status_t sl_sleeptimer_is_timer_running(const sl_sleeptimer_timer_handle_t *handle,
278                                            bool *running);
279 
280 /***************************************************************************//**
281  * Gets remaining time until timer expires.
282  *
283  * @param handle Pointer to handle to timer.
284  * @param time Time left in timer ticks.
285  *
286  * @return SL_STATUS_OK if successful. Error code otherwise.
287  ******************************************************************************/
288 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
289 sl_status_t sl_sleeptimer_get_timer_time_remaining(const sl_sleeptimer_timer_handle_t *handle,
290                                                    uint32_t *time);
291 
292 /**************************************************************************//**
293  * Gets the time remaining until the first timer with the matching set of flags
294  * expires.
295  *
296  * @param option_flags Set of flags to match:
297  *          - SL_SLEEPTIMER_ANY_TIMER_FLAG
298  *          - SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG
299  *
300  * @param time_remaining Time left in timer ticks.
301  *
302  * @return SL_STATUS_OK if successful. Error code otherwise.
303  *****************************************************************************/
304 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
305 sl_status_t sl_sleeptimer_get_remaining_time_of_first_timer(uint16_t option_flags,
306                                                             uint32_t *time_remaining);
307 
308 /***************************************************************************//**
309  * Gets current 32 bits global tick count.
310  *
311  * @return Current tick count.
312  ******************************************************************************/
313 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
314 uint32_t sl_sleeptimer_get_tick_count(void);
315 
316 /***************************************************************************//**
317  * Gets current 64 bits global tick count.
318  *
319  * @return Current tick count.
320  ******************************************************************************/
321 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
322 uint64_t sl_sleeptimer_get_tick_count64(void);
323 
324 /***************************************************************************//**
325  * Get timer frequency.
326  *
327  * @return Timer frequency in hertz.
328  ******************************************************************************/
329 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
330 uint32_t sl_sleeptimer_get_timer_frequency(void);
331 
332 /***************************************************************************//**
333  * Converts a Unix timestamp into a date.
334  *
335  * @param time 32 bit Unix timestamp to convert.
336  * @param time_zone Offset from UTC in second.
337  * @param date Pointer to converted date.
338  *
339  * @note Time is in Standard Time.
340  *
341  * @note Function definition is accessible only when
342  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
343  *
344  * @return SL_STATUS_OK if successful. Error code otherwise.
345  ******************************************************************************/
346 sl_status_t sl_sleeptimer_convert_time_to_date(sl_sleeptimer_timestamp_t time,
347                                                sl_sleeptimer_time_zone_offset_t time_zone,
348                                                sl_sleeptimer_date_t *date);
349 
350 /***************************************************************************//**
351  * Converts a 64 bit Unix timestamp into a date.
352  *
353  * @param time 64 bit Unix timestamp to convert.
354  * @param time_zone Offset from UTC in second.
355  * @param date Pointer to converted date.
356  *
357  * @note Time is in Standard Time.
358  *
359  * @note Function definition is accessible only when
360  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
361  *
362  * @return SL_STATUS_OK if successful. Error code otherwise.
363  ******************************************************************************/
364 sl_status_t sl_sleeptimer_convert_time_to_date_64(sl_sleeptimer_timestamp_64_t time,
365                                                   sl_sleeptimer_time_zone_offset_t time_zone,
366                                                   sl_sleeptimer_date_t *date);
367 
368 /***************************************************************************//**
369  * Converts a date into a Unix timestamp.
370  *
371  * @param date Pointer to date to convert.
372  * @param time Pointer to converted 32 bit Unix timestamp.
373  *
374  * @return SL_STATUS_OK if successful. Error code otherwise.
375  *
376  * @note Dates are based on the Unix time representation.
377  *       Range of dates supported :
378  *          - January 1, 1970, 00:00:00 to January 19, 2038, 03:14:00
379  *
380  * @note Function definition is accessible only when
381  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
382  ******************************************************************************/
383 sl_status_t sl_sleeptimer_convert_date_to_time(sl_sleeptimer_date_t *date,
384                                                sl_sleeptimer_timestamp_t *time);
385 
386 /***************************************************************************//**
387  * Converts a date into a 64 bit timestamp.
388  *
389  * @param date Pointer to date to convert.
390  * @param time Pointer to converted 64 bit Unix timestamp.
391  *
392  * @return SL_STATUS_OK if successful. Error code otherwise.
393  *
394  * @note Dates are based on the 64 bit Unix time representation.
395  *       Range of dates supported :
396  *          - January 1, 1900, 00:00:00 to  December 31, 11899 23:59:59.
397  *
398  * @note Function definition is accessible only when
399  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
400  ******************************************************************************/
401 sl_status_t sl_sleeptimer_convert_date_to_time_64(sl_sleeptimer_date_t *date,
402                                                   sl_sleeptimer_timestamp_64_t *time);
403 
404 /***************************************************************************//**
405  * Convert date to string.
406  *
407  * @param str Output string.
408  * @param size Size of the input array.
409  * @param format The format specification character.
410  * @param date Pointer to date structure.
411  *
412  * @return 0 if error. Number of character in the output string.
413  *
414  * @note Refer strftime() from UNIX.
415  *       http://man7.org/linux/man-pages/man3/strftime.3.html
416  *
417  * @note Function definition is accessible only when
418  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
419  ******************************************************************************/
420 uint32_t sl_sleeptimer_convert_date_to_str(char *str,
421                                            size_t size,
422                                            const uint8_t *format,
423                                            sl_sleeptimer_date_t *date);
424 
425 /***************************************************************************//**
426  * Sets time zone offset.
427  *
428  * @param  offset  Time zone offset, in seconds.
429  *
430  * @note Function definition is accessible only when
431  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
432  *
433  ******************************************************************************/
434 void sl_sleeptimer_set_tz(sl_sleeptimer_time_zone_offset_t offset);
435 
436 /***************************************************************************//**
437  * Gets time zone offset.
438  *
439  * @return Time zone offset, in seconds.
440  ******************************************************************************/
441 sl_sleeptimer_time_zone_offset_t sl_sleeptimer_get_tz(void);
442 
443 /***************************************************************************//**
444  * Retrieves current 32 bit time.
445  *
446  * @note Function definition is accessible only when
447  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
448  *
449  * @return Current timestamps in Unix format.
450  ******************************************************************************/
451 sl_sleeptimer_timestamp_t sl_sleeptimer_get_time(void);
452 
453 /***************************************************************************//**
454  * Retrieves current 64 bit time.
455  *
456  * @note Function definition is accessible only when
457  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
458  *
459  * @return Current timestamps in Unix format.
460  ******************************************************************************/
461 sl_sleeptimer_timestamp_64_t sl_sleeptimer_get_time_64(void);
462 
463 /***************************************************************************//**
464  * Sets current time.
465  *
466  * @param time timestamp structure to set.
467  *
468  * @note Function definition is accessible only when
469  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
470  *
471  * @return SL_STATUS_OK if successful. Error code otherwise.
472  ******************************************************************************/
473 sl_status_t sl_sleeptimer_set_time(sl_sleeptimer_timestamp_t time);
474 
475 /***************************************************************************//**
476  * Sets current time.
477  *
478  * @param time timestamp structure to set.
479  *
480  * @note Function definition is accessible only when
481  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
482  *
483  * @return SL_STATUS_OK if successful. Error code otherwise.
484  ******************************************************************************/
485 sl_status_t sl_sleeptimer_set_time_64(sl_sleeptimer_timestamp_64_t time);
486 
487 /***************************************************************************//**
488  * Gets current date.
489  *
490  * @param date Pointer to a sl_sleeptimer_date_t structure.
491  *
492  * @note Time is in Standard Time.
493  *
494  * @note Function definition is accessible only when
495  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
496  *
497  * @return SL_STATUS_OK if successful. Error code otherwise.
498  ******************************************************************************/
499 sl_status_t sl_sleeptimer_get_datetime(sl_sleeptimer_date_t *date);
500 
501 /***************************************************************************//**
502  * Sets current time, in date format.
503  *
504  * @param date Pointer to current date.
505  *
506  * @note Function definition is accessible only when
507  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
508  *
509  * @return SL_STATUS_OK if successful. Error code otherwise.
510  ******************************************************************************/
511 sl_status_t sl_sleeptimer_set_datetime(sl_sleeptimer_date_t *date);
512 
513 /***************************************************************************//**
514  * Builds a date time structure based on the provided parameters,
515  * where the maximum supported date is 10:14:07 PM 01/18/2038.
516  *
517  * @param date Pointer to the structure to be populated.
518  * @param year Current year. May be provided based on a 0 Epoch or a 1900 Epoch.
519  * @param month Months since January. Expected value: 0-11.
520  * @param month_day Day of the month. Expected value: 1-31.
521  * @param hour Hours since midnight. Expected value: 0-23.
522  * @param min Minutes after the hour. Expected value: 0-59.
523  * @param sec Seconds after the minute. Expected value: 0-59.
524  * @param tzOffset Offset, in seconds, from UTC.
525  *
526  * @note Function definition is accessible only when
527  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
528  *
529  * @return SL_STATUS_OK if successful. Error code otherwise.
530  ******************************************************************************/
531 sl_status_t sl_sleeptimer_build_datetime(sl_sleeptimer_date_t *date,
532                                          uint16_t year,
533                                          sl_sleeptimer_month_t month,
534                                          uint8_t month_day,
535                                          uint8_t hour,
536                                          uint8_t min,
537                                          uint8_t sec,
538                                          sl_sleeptimer_time_zone_offset_t tzOffset);
539 
540 /***************************************************************************//**
541  * Builds a date time structure based on the provided parameters,
542  * where the maximum supported date is 11:59:59 PM 12/31/11899.
543  *
544  * @param date Pointer to the structure to be populated.
545  * @param year Current year based on 0 Epoch.
546  * @param month Months since January. Expected value: 0-11.
547  * @param month_day Day of the month. Expected value: 1-31.
548  * @param hour Hours since midnight. Expected value: 0-23.
549  * @param min Minutes after the hour. Expected value: 0-59.
550  * @param sec Seconds after the minute. Expected value: 0-59.
551  * @param tzOffset Offset, in seconds, from UTC.
552  *
553  * @note Resulting date structure's year will be based on 1900 epoch
554  *
555  * @note Function definition is accessible only when
556  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
557  *
558  * @return SL_STATUS_OK if successful. Error code otherwise.
559  ******************************************************************************/
560 sl_status_t sl_sleeptimer_build_datetime_64(sl_sleeptimer_date_t *date,
561                                             uint16_t year,
562                                             sl_sleeptimer_month_t month,
563                                             uint8_t month_day,
564                                             uint8_t hour,
565                                             uint8_t min,
566                                             uint8_t sec,
567                                             sl_sleeptimer_time_zone_offset_t tzOffset);
568 
569 /***************************************************************************//**
570  * Converts Unix timestamp into NTP timestamp.
571  *
572  * @param time Unix timestamp.
573  * @param ntp_time Pointer to NTP Timestamp.
574  *
575  * @note Unix timestamp range supported : 0x0 to 0x7C55 817F
576  *       ie. January 1, 1970, 00:00:00 to February 07, 2036, 06:28:15
577  *
578  * @note Function definition is accessible only when
579  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
580  *
581  * @return SL_STATUS_OK if successful. Error code otherwise.
582  ******************************************************************************/
583 sl_status_t sl_sleeptimer_convert_unix_time_to_ntp(sl_sleeptimer_timestamp_t time,
584                                                    uint32_t *ntp_time);
585 
586 /***************************************************************************//**
587  * Converts NTP timestamp into Unix timestamp.
588  *
589  * @param ntp_time NTP Timestamp.
590  * @param time Pointer to Unix timestamp.
591  *
592  * @note NTP timestamp range supported : 0x83AA 7E80 to 0xFFFF FFFF
593  *       ie. January 1, 1970, 00:00:00 to February 07, 2036, 06:28:15
594  *
595  * @note Function definition is accessible only when
596  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
597  *
598  * @return SL_STATUS_OK if successful. Error code otherwise.
599  ******************************************************************************/
600 sl_status_t sl_sleeptimer_convert_ntp_time_to_unix(uint32_t ntp_time,
601                                                    sl_sleeptimer_timestamp_t *time);
602 
603 /***************************************************************************//**
604  * Converts Unix timestamp into Zigbee timestamp.
605  *
606  * @param time Unix timestamp.
607  *
608  * @param zigbee_time Pointer to NTP Timestamp.
609  *
610  * @note Unix timestamp range supported : 0x386D 4380 to 0x7FFF FFFF
611  *       ie. January 1, 2000, 00:00:0 to January 19, 2038, 03:14:00
612  *
613  * @note Function definition is accessible only when
614  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
615  *
616  * @return SL_STATUS_OK if successful. Error code otherwise.
617  ******************************************************************************/
618 sl_status_t sl_sleeptimer_convert_unix_time_to_zigbee(sl_sleeptimer_timestamp_t time,
619                                                       uint32_t *zigbee_time);
620 
621 /***************************************************************************//**
622  * Converts Zigbee timestamp into Unix timestamp.
623  *
624  * @param zigbee_time NTP Timestamp.
625  * @param time Pointer to Unix timestamp.
626  *
627  * @note ZIGBEE timestamp range supported : 0x0 to 0x4792 BC7F
628  *        ie. January 1, 2000, 00:00:00 to January 19, 2038, 03:14:00
629  *
630  * @note Function definition is accessible only when
631  *       SL_SLEEPTIMER_WALLCLOCK_CONFIG is set to 1.
632  *
633  * @return SL_STATUS_OK if successful. Error code otherwise.
634  ******************************************************************************/
635 sl_status_t sl_sleeptimer_convert_zigbee_time_to_unix(uint32_t zigbee_time,
636                                                       sl_sleeptimer_timestamp_t *time);
637 
638 /***************************************************************************//**
639  * Calculates offset for time zone after UTC-0.
640  *
641  * @param hours Number of hours from UTC-0.
642  * @param minutes Number of minutes from UTC-0.
643  *
644  * @return The time zone offset in seconds.
645  ******************************************************************************/
sl_sleeptimer_set_tz_ahead_utc(uint8_t hours,uint8_t minutes)646 __STATIC_INLINE sl_sleeptimer_time_zone_offset_t sl_sleeptimer_set_tz_ahead_utc(uint8_t hours,
647                                                                                 uint8_t minutes)
648 {
649   return ((hours * 3600u) + (minutes * 60u));
650 }
651 
652 /***************************************************************************//**
653  * Calculates offset for time zone before UTC-0.
654  *
655  * @param hours Number of hours to UTC-0.
656  * @param minutes Number of minutes to UTC-0.
657  *
658  * @return The time zone offset in seconds.
659  ******************************************************************************/
sl_sleeptimer_set_tz_behind_utc(uint8_t hours,uint8_t minutes)660 __STATIC_INLINE sl_sleeptimer_time_zone_offset_t sl_sleeptimer_set_tz_behind_utc(uint8_t hours,
661                                                                                  uint8_t minutes)
662 {
663   return -(sl_sleeptimer_time_zone_offset_t)((hours * 3600u) + (minutes * 60u));
664 }
665 
666 /***************************************************************************//**
667  * Active delay.
668  *
669  * @param time_ms Delay duration in milliseconds.
670  ******************************************************************************/
671 void sl_sleeptimer_delay_millisecond(uint16_t time_ms);
672 
673 /***************************************************************************//**
674  * Converts milliseconds in ticks.
675  *
676  * @param time_ms Number of milliseconds.
677  *
678  * @return Corresponding ticks number.
679  *
680  * @note The result is "rounded" to the superior tick number.
681  *       This function is light and cannot fail so it should be privilegied to
682  *       perform a millisecond to tick conversion.
683  ******************************************************************************/
684 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
685 uint32_t sl_sleeptimer_ms_to_tick(uint16_t time_ms);
686 
687 /***************************************************************************//**
688  * Converts 32-bits milliseconds in ticks.
689  *
690  * @param time_ms Number of milliseconds.
691  * @param tick Pointer to the converted tick number.
692  *
693  * @return SL_STATUS_OK if successful. Error code otherwise.
694  *
695  * @note  The result is "rounded" to the superior tick number.
696  *        If possible the sl_sleeptimer_ms_to_tick() function should be used.
697  *
698  * @note  This function converts the delay expressed in milliseconds to timer
699  *        ticks (represented on 32 bits). This means that the value that can
700  *        be passed to the argument 'time_ms' is limited. The maximum
701  *        timeout value that can be passed to this function can be retrieved
702  *        by calling sl_sleeptimer_get_max_ms32_conversion().
703  *        If the value passed to 'time_ms' is too large,
704  *        SL_STATUS_INVALID_PARAMETER will be returned.
705  ******************************************************************************/
706 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
707 sl_status_t sl_sleeptimer_ms32_to_tick(uint32_t time_ms,
708                                        uint32_t *tick);
709 
710 /***************************************************************************//**
711  * Gets the maximum value that can be passed to the functions that have a
712  * 32-bits time or timeout argument expressed in milliseconds.
713  *
714  * @return Maximum time or timeout value in milliseconds.
715  ******************************************************************************/
716 uint32_t sl_sleeptimer_get_max_ms32_conversion(void);
717 
718 /***************************************************************************//**
719  * Converts ticks in milliseconds.
720  *
721  * @param tick Number of tick.
722  *
723  * @return Corresponding milliseconds number.
724  *
725  * @note The result is rounded to the inferior millisecond.
726  ******************************************************************************/
727 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
728 uint32_t sl_sleeptimer_tick_to_ms(uint32_t tick);
729 
730 /***************************************************************************//**
731  * Converts 64-bit ticks in milliseconds.
732  *
733  * @param tick Number of tick.
734  * @param ms Pointer to the converted milliseconds number.
735  *
736  * @return SL_STATUS_OK if successful. Error code otherwise.
737  *
738  * @note The result is rounded to the inferior millisecond.
739  ******************************************************************************/
740 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
741 sl_status_t sl_sleeptimer_tick64_to_ms(uint64_t tick,
742                                        uint64_t *ms);
743 
744 /***************************************************************************//**
745  * Allow sleep after ISR exit.
746  *
747  * @return true if sleep is allowed after ISR exit. False otherwise.
748  ******************************************************************************/
749 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
750 bool sl_sleeptimer_is_power_manager_early_restore_timer_latest_to_expire(void);
751 
752 /**************************************************************************//**
753  * Starts a 32 bits timer.
754  *
755  * @param handle Pointer to handle to timer.
756  * @param timeout_ms Timer timeout, in milliseconds.
757  * @param callback Callback function that will be called when
758  *        initial/periodic timeout expires.
759  * @param callback_data Pointer to user data that will be passed to callback.
760  * @param priority Priority of callback. Useful in case multiple timer expire
761  *        at the same time. 0 = highest priority.
762  * @param option_flags Bit array of option flags for the timer.
763  *        Valid bit-wise OR of one or more of the following:
764  *          - SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG
765  *        or 0 for not flags.
766  *
767  * @return SL_STATUS_OK if successful. Error code otherwise.
768  *
769  * @note  This function converts the delay expressed in milliseconds to timer
770  *        ticks (represented on 32 bits). This means that the value that can
771  *        be passed to the argument 'timeout_ms' is limited. The maximum
772  *        timeout value that can be passed to this function can be retrieved
773  *        by calling sl_sleeptimer_get_max_ms32_conversion().
774  *        If the value passed to 'timeout_ms' is too large,
775  *        SL_STATUS_INVALID_PARAMETER will be returned.
776  *
777  * @note This function cannot be called from an interrupt with a higher
778  *       priority than BASEPRI.
779  *****************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER,SL_CODE_CLASS_TIME_CRITICAL)780 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
781 __STATIC_INLINE sl_status_t sl_sleeptimer_start_timer_ms(sl_sleeptimer_timer_handle_t *handle,
782                                                          uint32_t timeout_ms,
783                                                          sl_sleeptimer_timer_callback_t callback,
784                                                          void *callback_data,
785                                                          uint8_t priority,
786                                                          uint16_t option_flags)
787 {
788   sl_status_t status;
789   uint32_t timeout_tick;
790 
791   status = sl_sleeptimer_ms32_to_tick(timeout_ms, &timeout_tick);
792   if (status != SL_STATUS_OK) {
793     return status;
794   }
795 
796   return sl_sleeptimer_start_timer(handle, timeout_tick, callback, callback_data, priority, option_flags);
797 }
798 
799 /**************************************************************************//**
800  * Restarts a 32 bits timer.
801  *
802  * @param handle Pointer to handle to timer.
803  * @param timeout_ms Timer timeout, in milliseconds.
804  * @param callback Callback function that will be called when
805  *        initial/periodic timeout expires.
806  * @param callback_data Pointer to user data that will be passed to callback.
807  * @param priority Priority of callback. Useful in case multiple timer expire
808  *        at the same time. 0 = highest priority.
809  * @param option_flags Bit array of option flags for the timer.
810  *        Valid bit-wise OR of one or more of the following:
811  *          - SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG
812  *        or 0 for not flags.
813  *
814  * @return SL_STATUS_OK if successful. Error code otherwise.
815  *
816  * @note  This function converts the delay expressed in milliseconds to timer
817  *        ticks (represented on 32 bits). This means that the value that can
818  *        be passed to the argument 'timeout_ms' is limited. The maximum
819  *        timeout value that can be passed to this function can be retrieved
820  *        by calling sl_sleeptimer_get_max_ms32_conversion().
821  *        If the value passed to 'timeout_ms' is too large,
822  *        SL_STATUS_INVALID_PARAMETER will be returned.
823  *
824  * @note This function cannot be called from an interrupt with a higher
825  *       priority than BASEPRI.
826  *****************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER,SL_CODE_CLASS_TIME_CRITICAL)827 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
828 __STATIC_INLINE sl_status_t sl_sleeptimer_restart_timer_ms(sl_sleeptimer_timer_handle_t *handle,
829                                                            uint32_t timeout_ms,
830                                                            sl_sleeptimer_timer_callback_t callback,
831                                                            void *callback_data,
832                                                            uint8_t priority,
833                                                            uint16_t option_flags)
834 {
835   sl_status_t status;
836   uint32_t timeout_tick;
837 
838   status = sl_sleeptimer_ms32_to_tick(timeout_ms, &timeout_tick);
839   if (status != SL_STATUS_OK) {
840     return status;
841   }
842 
843   return sl_sleeptimer_restart_timer(handle, timeout_tick, callback, callback_data, priority, option_flags);
844 }
845 
846 /***************************************************************************//**
847  * Starts a 32 bits periodic timer.
848  *
849  * @param handle Pointer to handle to timer.
850  * @param timeout_ms Timer periodic timeout, in milliseconds.
851  * @param callback Callback function that will be called when
852  *        initial/periodic timeout expires.
853  * @param callback_data Pointer to user data that will be passed to callback.
854  * @param priority Priority of callback. Useful in case multiple timer expire
855  *        at the same time. 0 = highest priority.
856  * @param option_flags Bit array of option flags for the timer.
857  *        Valid bit-wise OR of one or more of the following:
858  *          - SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG
859  *        or 0 for not flags.
860  *
861  * @return SL_STATUS_OK if successful. Error code otherwise.
862  *
863  * @note  This function converts the delay expressed in milliseconds to timer
864  *        ticks (represented on 32 bits). This means that the value that can
865  *        be passed to the argument 'timeout_ms' is limited. The maximum
866  *        timeout value that can be passed to this function can be retrieved
867  *        by calling sl_sleeptimer_get_max_ms32_conversion().
868  *        If the value passed to 'timeout_ms' is too large,
869  *        SL_STATUS_INVALID_PARAMETER will be returned.
870  *
871  * @note This function cannot be called from an interrupt with a higher
872  *       priority than BASEPRI.
873  ******************************************************************************/
874 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
875 sl_status_t sl_sleeptimer_start_periodic_timer_ms(sl_sleeptimer_timer_handle_t *handle,
876                                                   uint32_t timeout_ms,
877                                                   sl_sleeptimer_timer_callback_t callback,
878                                                   void *callback_data,
879                                                   uint8_t priority,
880                                                   uint16_t option_flags);
881 
882 /***************************************************************************//**
883  * Restarts a 32 bits periodic timer.
884  *
885  * @param handle Pointer to handle to timer.
886  * @param timeout_ms Timer periodic timeout, in milliseconds.
887  * @param callback Callback function that will be called when
888  *        initial/periodic timeout expires.
889  * @param callback_data Pointer to user data that will be passed to callback.
890  * @param priority Priority of callback. Useful in case multiple timer expire
891  *        at the same time. 0 = highest priority.
892  * @param option_flags Bit array of option flags for the timer.
893  *        Valid bit-wise OR of one or more of the following:
894  *          - SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG
895  *        or 0 for not flags.
896  *
897  * @return SL_STATUS_OK if successful. Error code otherwise.
898  *
899  * @note  This function converts the delay expressed in milliseconds to timer
900  *        ticks (represented on 32 bits). This means that the value that can
901  *        be passed to the argument 'timeout_ms' is limited. The maximum
902  *        timeout value that can be passed to this function can be retrieved
903  *        by calling sl_sleeptimer_get_max_ms32_conversion().
904  *        If the value passed to 'timeout_ms' is too large,
905  *        SL_STATUS_INVALID_PARAMETER will be returned.
906  *
907  * @note This function cannot be called from an interrupt with a higher
908  *       priority than BASEPRI.
909  ******************************************************************************/
910 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLEEPTIMER, SL_CODE_CLASS_TIME_CRITICAL)
911 sl_status_t sl_sleeptimer_restart_periodic_timer_ms(sl_sleeptimer_timer_handle_t *handle,
912                                                     uint32_t timeout_ms,
913                                                     sl_sleeptimer_timer_callback_t callback,
914                                                     void *callback_data,
915                                                     uint8_t priority,
916                                                     uint16_t option_flags);
917 
918 /***************************************************************************//**
919  * @brief
920  *   Gets the precision (in PPM) of the sleeptimer's clock.
921  *
922  * @return
923  *   Clock accuracy, in PPM.
924  ******************************************************************************/
925 uint16_t sl_sleeptimer_get_clock_accuracy(void);
926 
927 #ifdef __cplusplus
928 }
929 #endif
930 
931 /** @} (end addtogroup sleeptimer) */
932 
933 /* *INDENT-OFF* */
934 /* THE REST OF THE FILE IS DOCUMENTATION ONLY! */
935 /// @addtogroup sleeptimer Sleep Timer
936 /// @{
937 ///
938 ///   @details
939 ///   Sleep Timer can be used for creating timers which are tightly integrated with power management.
940 ///   The Power Manager requires precision timing to have all clocks ready on time, so that wakeup
941 ///   happens a little bit earlier to prepare the system to be ready at the right time.
942 ///   Sleep Timer uses one Hardware Timer and creates multiple software timer instances. It is important
943 ///   to note that when sleeptimer is used with WTIMER/TIMER, the MCU cannot go to EM2 energy mode
944 ///   because WTIMER/TIMER uses a high frequency clock source which is not retained in low energy mode.
945 ///
946 ///   The sleeptimer.c and sleeptimer.h source files for the SLEEPTIMER device driver library are in the
947 ///   service/sleeptimer folder.
948 ///
949 ///   @n @section sleeptimer_intro Introduction
950 ///
951 ///   The Sleeptimer driver provides software timers, delays, timekeeping and date functionalities using a low-frequency real-time clock peripheral.
952 ///
953 ///   All Silicon Labs microcontrollers equipped with the RTC or RTCC peripheral are currently supported. Only one instance of this driver can be initialized by the application.
954 ///
955 ///   @n @section sleeptimer_functionalities_overview Functionalities overview
956 ///
957 ///   @n @subsection software_timers Software Timers
958 ///
959 ///   This functionality allows the user to create periodic and one shot timers. A user callback can be associated with a timer and is called when the timer expires.
960 ///
961 ///   Timer structures must be allocated by the user. The function is called from within an interrupt handler with interrupts enabled.
962 ///
963 ///   As sleeptimer callback functions are executed in ISR, they should be kept simple and short.
964 ///   For periodic timers, the sleeptimer's callbacks need to be shorter than the timer's period to allow the application to exit the interrupt context.
965 ///
966 ///   @n @subsection timekeeping Timekeeping
967 ///
968 ///   A 64-bits tick counter is accessible through the @li uint64_t sl_sleeptimer_get_tick_count64(void) API. It keeps the tick count since the initialization of the driver
969 ///
970 ///   The `SL_SLEEPTIMER_WALLCLOCK_CONFIG` configuration enables a UNIX timestamp (seconds count since January 1, 1970, 00:00:00).
971 ///
972 ///   This timestamp can be retrieved/modified using the following API:
973 ///
974 ///   @li sl_sleeptimer_timestamp_t sl_sleeptimer_get_time(void);
975 ///   @li sl_status_t sl_sleeptimer_set_time(sl_sleeptimer_timestamp_t time);
976 ///
977 ///   Convenience conversion functions are provided to convert UNIX timestamp to/from NTP and Zigbee cluster format :
978 ///
979 ///   @li sl_status_t sl_sleeptimer_convert_unix_time_to_ntp(sl_sleeptimer_timestamp_t time, uint32_t *ntp_time);
980 ///   @li sl_status_t sl_sleeptimer_convert_ntp_time_to_unix(uint32_t ntp_time, sl_sleeptimer_timestamp_t *time);
981 ///   @li sl_status_t sl_sleeptimer_convert_unix_time_to_zigbee(sl_sleeptimer_timestamp_t time, uint32_t *zigbee_time);
982 ///   @li sl_status_t sl_sleeptimer_convert_zigbee_time_to_unix(uint32_t zigbee_time, sl_sleeptimer_timestamp_t *time);
983 ///
984 ///   @n @subsection date Date
985 ///
986 ///   The previously described internal timestamp can also be retrieved/modified in a date format sl_sleeptimer_date_t.
987 ///
988 ///   @n <b>API :</b> @n
989 ///
990 ///   @li sl_status_t sl_sleeptimer_get_datetime(sl_sleeptimer_date_t *date);
991 ///   @li sl_status_t sl_sleeptimer_set_datetime(sl_sleeptimer_date_t *date);
992 ///
993 ///   @n @subsection frequency_setup Frequency Setup and Tick Count
994 ///
995 ///   This driver works with a configurable time unit called tick.
996 ///
997 ///   The frequency of the ticks is based on the clock source and the internal frequency divider.
998 ///
999 ///   WTIMER/TIMER peripherals uses high frequency oscillator. To have a reasonable tick frequency, divider is set to maximum value (1024).
1000 ///
1001 ///   One of the following clock sources must be enabled before initializing the sleeptimer:
1002 ///
1003 ///   @li LFXO: external crystal oscillator. Typically running at 32.768 kHz.
1004 ///   @li LFRCO: internal oscillator running at 32.768 kHz
1005 ///   @li ULFRCO: Ultra low-frequency oscillator running at 1.000 kHz
1006 ///   @li HFXO: High Frequency Crystal Oscillator at 39 Mhz. HFXO is only needed when Sleeptimer runs on TIMER or WTIMER.
1007 ///
1008 ///   The frequency divider is selected with the `SL_SLEEPTIMER_FREQ_DIVIDER` configuration. Its value must be a power of two within the range of 1 to 32. The number of ticks per second (sleeptimer frequency) is dictated by the following formula:
1009 ///
1010 ///   Tick (seconds) = 1 / (clock_frequency / frequency_divider)
1011 ///
1012 ///   The highest resolution for a tick is 30.5 us. It is achieved with a 32.768 kHz clock and a divider of 1.
1013 ///
1014 ///   @n @section sleeptimer_getting_started Getting Started
1015 ///
1016 ///   @n @subsection  clock_selection Clock Selection
1017 ///
1018 ///   The sleeptimer relies on the hardware timer to operate. The hardware timer peripheral must be properly clocked from the application. Selecting the appropriate timer is crucial for design considerations. Each timer can potentially be used as a sleeptimer and is also available to the user. However, note that if a timer is used by the sleeptimer, it can't be used by the application and vice versa.
1019 ///
1020 ///   For WTIMER/TIMER peripherals, the user must select the appropriate oscillator if it is not the default wanted clock source.
1021 ///
1022 ///   When WTIMER/TIMER is selected, sleeptimer uses channel 0 and it is not possible to use other channels of the same instance for other purposes.
1023 ///
1024 ///   When SYSRTC is chosen, the Peripheral Reflex System (PRS) channel 1 and 2 will be used by sleeptimer and become unavailable. PRS_GetFreeChannel() can be used to retrieve an unallocated channel.
1025 ///
1026 ///   @n @subsection  Clock Selection in a Project without Micrium OS
1027 ///
1028 ///   When RTC, RTCC, or BURTC is selected, the clock source for the peripheral must be configured and enabled in the application before initializing the sleeptimer module or any communication stacks. Most of the time, it consists in enabling the desired oscillators and setting up the clock source for the peripheral, like in the following example:
1029 ///
1030 ///   @code{.c}
1031 ///   CMU_ClockSelectSet(cmuClock_LFE, cmuSelect_LFRCO);
1032 ///   CMU_ClockEnable(cmuClock_RTCC, true);
1033 ///   @endcode
1034 ///
1035 ///   @n @subsection  clock_branch_select Clock Branch Select
1036 ///
1037 ///   | Clock  | Enum                    | Description                       | Frequency |
1038 ///   |--------|-------------------------|-----------------------------------|-----------|
1039 ///   | LFXO   | <b>cmuSelect_LFXO</b>   | Low-frequency crystal oscillator  |32.768 Khz |
1040 ///   | LFRCO  | <b>cmuSelect_LFRCO</b>  | Low-frequency RC oscillator       |32.768 Khz |
1041 ///   | ULFRCO | <b>cmuSelect_ULFRCO</b> | Ultra low-frequency RC oscillator |1 Khz      |
1042 ///
1043 ///   @n @subsection  timer_clock_enable Timer Clock Enable
1044 ///
1045 ///   | Module             | Enum                  | Description                                        |
1046 ///   |--------------------|-----------------------|----------------------------------------------------|
1047 ///   | RTCC               | <b>cmuClock_RTCC</b>  | Real-time counter and calendar clock (LF E branch) |
1048 ///   | RTC                | <b>cmuClock_RTC</b>   | Real time counter clock (LF A branch)              |
1049 ///   | BURTC              | <b>cmuClock_BURTC</b> | BURTC clock (EM4 Group A branch)                   |
1050 ///
1051 ///   When the Radio internal RTC (PRORTC) is selected, it is not necessary to configure the clock source for the peripheral. However, it is important to enable the desired oscillator before initializing the sleeptimer module or any communication stacks. The best oscillator available (LFXO being the first choice) will be used by the sleeptimer at initalization. The following example shows how the desired oscilator should be enabled:
1052 ///
1053 ///   @code{.c}
1054 ///   CMU_OscillatorEnable(cmuSelect_LFXO, true, true);
1055 ///   @endcode
1056 ///
1057 ///   @n @subsection  clock_micrium_os Clock Selection in a Project with Micrium OS
1058 ///
1059 ///   When Micrium OS is used, a BSP (all instances) is provided that sets up some parts of the clock tree. The sleeptimer clock source will be enabled by this bsp. However, the desired oscillator remains configurable from the file <b>bsp_cfg.h</b>.
1060 ///
1061 ///   The configuration `BSP_LF_CLK_SEL` determines which oscillator will be used by the sleeptimer's hardware timer peripheral. It can take the following values:
1062 ///
1063 ///   | Config                   | Description                       | Frequency |
1064 ///   |--------------------------|-----------------------------------|-----------|
1065 ///   | <b>BSP_LF_CLK_LFXO</b>   | Low-frequency crystal oscillator  |32.768 Khz |
1066 ///   | <b>BSP_LF_CLK_LFRCO</b>  | Low-frequency RC oscillator       |32.768 Khz |
1067 ///   | <b>BSP_LF_CLK_ULFRCO</b> | Ultra low-frequency RC oscillator |1 Khz      |
1068 ///
1069 ///   @n @section sleeptimer_conf Configuration Options
1070 ///
1071 ///   `SL_SLEEPTIMER_PERIPHERAL` can be set to one of the following values:
1072 ///
1073 ///   | Config                            | Description                                                                                          |
1074 ///   | --------------------------------- |------------------------------------------------------------------------------------------------------|
1075 ///   | `SL_SLEEPTIMER_PERIPHERAL_DEFAULT`| Selects either RTC or RTCC, depending of what is available on the platform.                          |
1076 ///   | `SL_SLEEPTIMER_PERIPHERAL_RTCC`   | Selects RTCC                                                                                         |
1077 ///   | `SL_SLEEPTIMER_PERIPHERAL_RTC`    | Selects RTC                                                                                          |
1078 ///   | `SL_SLEEPTIMER_PERIPHERAL_PRORTC` | Selects Internal radio RTC. Available only on EFR32XG13, EFR32XG14, EFR32XG21 and EFR32XG22 families.|
1079 ///   | `SL_SLEEPTIMER_PERIPHERAL_BURTC`  | Selects BURTC. Not available on Series 0 devices.                                                    |
1080 ///
1081 ///   `SL_SLEEPTIMER_WALLCLOCK_CONFIG` must be set to 1 to enable timestamp and date functionnalities.
1082 ///
1083 ///   `SL_SLEEPTIMER_FREQ_DIVIDER` must be a power of 2 within the range 1 to 32. When `SL_SLEEPTIMER_PERIPHERAL` is set to `SL_SLEEPTIMER_PERIPHERAL_PRORTC`, `SL_SLEEPTIMER_FREQ_DIVIDER` must be set to 1.
1084 ///
1085 ///   `SL_SLEEPTIMER_PRORTC_HAL_OWNS_IRQ_HANDLER` is only meaningful when `SL_SLEEPTIMER_PERIPHERAL` is set to `SL_SLEEPTIMER_PERIPHERAL_PRORTC`. Set to 1 if no communication stack is used in your project. Otherwise, must be set to 0.
1086 ///
1087 ///   @n @section sleeptimer_api The API
1088 ///
1089 ///   This section contains brief descriptions of the API functions. For
1090 ///   more information about input and output parameters and return values,
1091 ///   click on the hyperlinked function names. Most functions return an error
1092 ///   code, `SL_STATUS_OK` is returned on success,
1093 ///   see sl_status.h for other error codes.
1094 ///
1095 ///   The application code must include the @em sl_sleeptimer.h header file.
1096 ///
1097 ///   All API functions can be called from within interrupt handlers.
1098 ///
1099 ///   @ref sl_sleeptimer_init() @n
1100 ///    These functions initialize the sleeptimer driver. Typically,
1101 ///     sl_sleeptimer_init() is called once in the startup code.
1102 ///
1103 ///   @ref sl_sleeptimer_start_timer() @n
1104 ///    Start a one shot 32 bits timer. When a timer expires, a user-supplied callback function
1105 ///    is called. A pointer to this function is passed to
1106 ///     sl_sleeptimer_start_timer(). See @ref sl_sleeptimer_timer_callback_t for
1107 ///    details of the callback prototype.
1108 ///
1109 ///   @ref sl_sleeptimer_restart_timer() @n
1110 ///    Restart a one shot 32 bits timer. When a timer expires, a user-supplied callback function
1111 ///    is called. A pointer to this function is passed to
1112 ///     sl_sleeptimer_start_timer(). See @ref sl_sleeptimer_timer_callback_t for
1113 ///    details of the callback prototype.
1114 ///
1115 ///   @ref sl_sleeptimer_start_periodic_timer() @n
1116 ///    Start a periodic 32 bits timer. When a timer expires, a user-supplied callback function
1117 ///    is called. A pointer to this function is passed to
1118 ///     sl_sleeptimer_start_timer(). See @ref sl_sleeptimer_timer_callback_t for
1119 ///    details of the callback prototype.
1120 ///
1121 ///   @ref sl_sleeptimer_restart_periodic_timer() @n
1122 ///    Restart a periodic 32 bits timer. When a timer expires, a user-supplied callback function
1123 ///    is called. A pointer to this function is passed to
1124 ///     sl_sleeptimer_start_timer(). See @ref sl_sleeptimer_timer_callback_t for
1125 ///    details of the callback prototype.
1126 ///
1127 ///   @ref sl_sleeptimer_stop_timer() @n
1128 ///    Stop a timer.
1129 ///
1130 ///   @ref sl_sleeptimer_get_timer_time_remaining() @n
1131 ///    Get the time remaining before the timer expires.
1132 ///
1133 ///   @ref sl_sleeptimer_delay_millisecond() @n
1134 ///    Delay for the given number of milliseconds. This is an "active wait" delay function.
1135 ///
1136 ///   @ref sl_sleeptimer_is_timer_running() @n
1137 ///    Check if a timer is running.
1138 ///
1139 ///   @ref sl_sleeptimer_get_time(), @ref sl_sleeptimer_set_time() @n
1140 ///    Get or set wallclock time.
1141 ///
1142 ///   @ref sl_sleeptimer_ms_to_tick(), @ref sl_sleeptimer_ms32_to_tick(),
1143 ///   @ref sl_sleeptimer_tick_to_ms(), @ref sl_sleeptimer_tick64_to_ms() @n
1144 ///    Convert between milliseconds and RTC/RTCC
1145 ///    counter ticks.
1146 ///
1147 ///   @n @anchor callback <b>The timer expiry callback function:</b> @n
1148 ///   The callback function, prototyped as @ref sl_sleeptimer_timer_callback_t(), is called from
1149 ///   within the RTC peripheral interrupt handler on timer expiration.
1150 ///    sl_sleeptimer_timer_callback_t(sl_sleeptimer_timer_handle_t *handle, void *data)
1151 ///
1152 ///   @n @section sleeptimer_example Example
1153 ///   @code{.c}
1154 ///#include "sl_sleeptimer.h"
1155 ///
1156 ///void my_timer_callback(sl_sleeptimer_timer_handle_t *handle, void *data)
1157 ///{
1158 ///  //Code executed when the timer expire.
1159 ///}
1160 ///
1161 ///int start_timer(void)
1162 ///{
1163 ///  sl_status_t status;
1164 ///  sl_sleeptimer_timer_handle_t my_timer;
1165 ///  uint32_t timer_timeout = 300;
1166 ///
1167 ///  // We assume the sleeptimer is initialized properly
1168 ///
1169 ///  status = sl_sleeptimer_start_timer(&my_timer,
1170 ///                                     timer_timeout,
1171 ///                                     my_timer_callback,
1172 ///                                     (void *)NULL,
1173 ///                                     0,
1174 ///                                     0);
1175 ///  if(status != SL_STATUS_OK) {
1176 ///    return -1;
1177 ///  }
1178 ///  return 1;
1179 ///}
1180 ///   @endcode
1181 ///
1182 /// @} (end addtogroup sleeptimer)
1183 
1184 #endif // SL_SLEEPTIMER_H
1185