1 /***************************************************************************//**
2  * @file
3  * @brief Real Time Counter (RTC) peripheral API
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2018 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 #ifndef EM_RTC_H
32 #define EM_RTC_H
33 
34 #include "em_device.h"
35 #if defined(RTC_COUNT) && (RTC_COUNT > 0)
36 
37 #include <stdbool.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /***************************************************************************//**
44  * @addtogroup rtc
45  * @{
46  ******************************************************************************/
47 
48 /*******************************************************************************
49  *******************************   DEFINES   ***********************************
50  ******************************************************************************/
51 
52 /** The RTC peripheral on series 0 devices support 2 compare channels while
53  *  the RTC peripheral on series 1 devices support 6 compare channels. */
54 #if defined(_SILICON_LABS_32B_SERIES_0)
55 #define NUM_RTC_CHANNELS   2U
56 #else
57 #define NUM_RTC_CHANNELS   6U
58 #endif
59 
60 /*******************************************************************************
61  *******************************   STRUCTS   ***********************************
62  ******************************************************************************/
63 
64 /** RTC initialization structure. */
65 typedef struct {
66   bool enable;   /**< Start counting when initialization is completed. */
67   bool debugRun; /**< Counter shall keep running during debug halt. */
68   bool comp0Top; /**< Use compare register 0 as max count value. */
69 } RTC_Init_TypeDef;
70 
71 /** Suggested default configuration for RTC initialization structure. */
72 #define RTC_INIT_DEFAULT                                      \
73   {                                                           \
74     true,  /* Start counting when initialization is done. */  \
75     false, /* Disable updating during debug halt. */          \
76     true   /* Restart counting from 0 when reaching COMP0. */ \
77   }
78 
79 /*******************************************************************************
80  *****************************   PROTOTYPES   **********************************
81  ******************************************************************************/
82 
83 uint32_t RTC_CompareGet(unsigned int comp);
84 void RTC_CompareSet(unsigned int comp, uint32_t value);
85 
86 /***************************************************************************//**
87  * @brief
88  *   Get RTC counter value.
89  *
90  * @return
91  *   Current RTC counter value.
92  ******************************************************************************/
RTC_CounterGet(void)93 __STATIC_INLINE uint32_t RTC_CounterGet(void)
94 {
95   return RTC->CNT;
96 }
97 
98 #if !defined(_EFM32_GECKO_FAMILY)
99 /***************************************************************************//**
100  * @brief
101  *   Set the RTC counter value.
102  *
103  * @param[in] value
104  *   The new RTC counter value.
105  ******************************************************************************/
RTC_CounterSet(uint32_t value)106 __STATIC_INLINE void RTC_CounterSet(uint32_t value)
107 {
108   RTC->CNT = value;
109 }
110 #endif
111 
112 void RTC_CounterReset(void);
113 void RTC_Enable(bool enable);
114 #if defined(_RTC_FREEZE_MASK)
115 void RTC_FreezeEnable(bool enable);
116 #endif
117 void RTC_Init(const RTC_Init_TypeDef *init);
118 
119 /***************************************************************************//**
120  * @brief
121  *   Clear one or more pending RTC interrupts.
122  *
123  * @param[in] flags
124  *   RTC interrupt sources to clear. Use a set of interrupt flags OR-ed
125  *   together to clear multiple interrupt sources for the RTC module
126  *   (RTC_IFS_nnn).
127  ******************************************************************************/
RTC_IntClear(uint32_t flags)128 __STATIC_INLINE void RTC_IntClear(uint32_t flags)
129 {
130   RTC->IFC = flags;
131 }
132 
133 /***************************************************************************//**
134  * @brief
135  *   Disable one or more RTC interrupts.
136  *
137  * @param[in] flags
138  *   RTC interrupt sources to disable. Use a set of interrupt flags OR-ed
139  *   together to disable multiple interrupt sources for the RTC module
140  *   (RTC_IFS_nnn).
141  ******************************************************************************/
RTC_IntDisable(uint32_t flags)142 __STATIC_INLINE void RTC_IntDisable(uint32_t flags)
143 {
144   RTC->IEN &= ~flags;
145 }
146 
147 /***************************************************************************//**
148  * @brief
149  *   Enable one or more RTC interrupts.
150  *
151  * @note
152  *   Depending on the use, a pending interrupt may already be set prior to
153  *   enabling the interrupt. To ignore a pending interrupt, consider using
154  *   RTC_IntClear() prior to enabling the interrupt.
155  *
156  * @param[in] flags
157  *   RTC interrupt sources to enable. Use a set of interrupt flags OR-ed
158  *   together to set multiple interrupt sources for the RTC module
159  *   (RTC_IFS_nnn).
160  ******************************************************************************/
RTC_IntEnable(uint32_t flags)161 __STATIC_INLINE void RTC_IntEnable(uint32_t flags)
162 {
163   RTC->IEN |= flags;
164 }
165 
166 /***************************************************************************//**
167  * @brief
168  *   Get pending RTC interrupt flags.
169  *
170  * @note
171  *   Event bits are not cleared by using this function.
172  *
173  * @return
174  *   Pending RTC interrupt sources. Returns a set of interrupt flags OR-ed
175  *   together for multiple interrupt sources in the RTC module (RTC_IFS_nnn).
176  ******************************************************************************/
RTC_IntGet(void)177 __STATIC_INLINE uint32_t RTC_IntGet(void)
178 {
179   return RTC->IF;
180 }
181 
182 /***************************************************************************//**
183  * @brief
184  *   Get enabled and pending RTC interrupt flags.
185  *   Useful for handling more interrupt sources in the same interrupt handler.
186  *
187  * @note
188  *   Interrupt flags are not cleared by using this function.
189  *
190  * @return
191  *   Pending and enabled RTC interrupt sources.
192  *   The return value is the bitwise AND of
193  *   - the enabled interrupt sources in RTC_IEN and
194  *   - the pending interrupt flags RTC_IF.
195  ******************************************************************************/
RTC_IntGetEnabled(void)196 __STATIC_INLINE uint32_t RTC_IntGetEnabled(void)
197 {
198   uint32_t ien;
199 
200   ien = RTC->IEN;
201   return RTC->IF & ien;
202 }
203 
204 /***************************************************************************//**
205  * @brief
206  *   Set one or more pending RTC interrupts from SW.
207  *
208  * @param[in] flags
209  *   RTC interrupt sources to set to pending. Use a set of interrupt flags
210  *   OR-ed together to set multiple interrupt sources for the RTC module
211  *   (RTC_IFS_nnn).
212  ******************************************************************************/
RTC_IntSet(uint32_t flags)213 __STATIC_INLINE void RTC_IntSet(uint32_t flags)
214 {
215   RTC->IFS = flags;
216 }
217 
218 void RTC_Reset(void);
219 
220 /** @} (end addtogroup rtc) */
221 
222 #ifdef __cplusplus
223 }
224 #endif
225 
226 #endif /* defined(RTC_COUNT) && (RTC_COUNT > 0) */
227 #endif /* EM_RTC_H */
228