1 /*
2 * Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef NRFX_RTC_H__
33 #define NRFX_RTC_H__
34
35 #include <nrfx.h>
36 #include <hal/nrf_rtc.h>
37
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41
42 /**
43 * @defgroup nrfx_rtc RTC driver
44 * @{
45 * @ingroup nrf_rtc
46 * @brief Real Timer Counter (RTC) peripheral driver.
47 */
48
49 /** @brief Macro for converting microseconds into ticks. */
50 #define NRFX_RTC_US_TO_TICKS(us,freq) (((us) * (freq)) / 1000000U)
51
52 /** @brief RTC driver interrupt types. */
53 typedef enum
54 {
55 NRFX_RTC_INT_COMPARE0 = 0, /**< Interrupt from COMPARE0 event. */
56 NRFX_RTC_INT_COMPARE1 = 1, /**< Interrupt from COMPARE1 event. */
57 NRFX_RTC_INT_COMPARE2 = 2, /**< Interrupt from COMPARE2 event. */
58 NRFX_RTC_INT_COMPARE3 = 3, /**< Interrupt from COMPARE3 event. */
59 NRFX_RTC_INT_TICK = 4, /**< Interrupt from TICK event. */
60 NRFX_RTC_INT_OVERFLOW = 5 /**< Interrupt from OVERFLOW event. */
61 } nrfx_rtc_int_type_t;
62
63 /** @brief RTC driver instance structure. */
64 typedef struct
65 {
66 NRF_RTC_Type * p_reg; /**< Pointer to instance register set. */
67 IRQn_Type irq; /**< Instance IRQ ID. */
68 uint8_t instance_id; /**< Index of the driver instance. For internal use only. */
69 uint8_t cc_channel_count; /**< Number of capture/compare channels. */
70 } nrfx_rtc_t;
71
72 /** @brief Macro for creating an RTC driver instance. */
73 #define NRFX_RTC_INSTANCE(id) \
74 { \
75 .p_reg = NRFX_CONCAT_2(NRF_RTC, id), \
76 .irq = NRFX_CONCAT_3(RTC, id, _IRQn), \
77 .instance_id = NRFX_CONCAT_3(NRFX_RTC, id, _INST_IDX), \
78 .cc_channel_count = NRF_RTC_CC_CHANNEL_COUNT(id), \
79 }
80
81 #ifndef __NRFX_DOXYGEN__
82 enum {
83 #if NRFX_CHECK(NRFX_RTC0_ENABLED)
84 NRFX_RTC0_INST_IDX,
85 #endif
86 #if NRFX_CHECK(NRFX_RTC1_ENABLED)
87 NRFX_RTC1_INST_IDX,
88 #endif
89 #if NRFX_CHECK(NRFX_RTC2_ENABLED)
90 NRFX_RTC2_INST_IDX,
91 #endif
92 NRFX_RTC_ENABLED_COUNT
93 };
94 #endif
95
96 /** @brief RTC driver instance configuration structure. */
97 typedef struct
98 {
99 uint16_t prescaler; /**< Prescaler. */
100 uint8_t interrupt_priority; /**< Interrupt priority. */
101 uint8_t tick_latency; /**< Maximum length of the interrupt handler in ticks (maximum 7.7 ms). */
102 bool reliable; /**< Reliable mode flag. */
103 } nrfx_rtc_config_t;
104
105 /**
106 * @brief RTC driver default configuration.
107 *
108 * This configuration sets up RTC with the following options:
109 * - frequency 32.768 kHz
110 * - maximum latency 2000 us
111 * - reliability checks disabled
112 */
113 #define NRFX_RTC_DEFAULT_CONFIG \
114 { \
115 .prescaler = RTC_FREQ_TO_PRESCALER(32768), \
116 .interrupt_priority = NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY, \
117 .tick_latency = NRFX_RTC_US_TO_TICKS(2000, 32768), \
118 .reliable = false, \
119 }
120
121 /** @brief RTC driver instance handler type. */
122 typedef void (*nrfx_rtc_handler_t)(nrfx_rtc_int_type_t int_type);
123
124 /**
125 * @brief Function for initializing the RTC driver instance.
126 *
127 * After initialization, the instance is in power off state.
128 *
129 * @param[in] p_instance Pointer to the driver instance structure.
130 * @param[in] p_config Pointer to the structure with the initial configuration.
131 * @param[in] handler Event handler provided by the user.
132 * Must not be NULL.
133 *
134 * @retval NRFX_SUCCESS Successfully initialized.
135 * @retval NRFX_ERROR_INVALID_STATE The instance is already initialized.
136 */
137 nrfx_err_t nrfx_rtc_init(nrfx_rtc_t const * p_instance,
138 nrfx_rtc_config_t const * p_config,
139 nrfx_rtc_handler_t handler);
140
141 /**
142 * @brief Function for uninitializing the RTC driver instance.
143 *
144 * After uninitialization, the instance is in idle state. The hardware should return to the state
145 * before initialization.
146 *
147 * @param[in] p_instance Pointer to the driver instance structure.
148 */
149 void nrfx_rtc_uninit(nrfx_rtc_t const * p_instance);
150
151 /**
152 * @brief Function for enabling the RTC driver instance.
153 *
154 * @param[in] p_instance Pointer to the driver instance structure.
155 */
156 void nrfx_rtc_enable(nrfx_rtc_t const * p_instance);
157
158 /**
159 * @brief Function for disabling the RTC driver instance.
160 *
161 * @param[in] p_instance Pointer to the driver instance structure.
162 */
163 void nrfx_rtc_disable(nrfx_rtc_t const * p_instance);
164
165 /**
166 * @brief Function for setting a compare channel.
167 *
168 * The function powers on the instance if the instance was in power off state.
169 *
170 * The driver is not entering a critical section when configuring RTC, which means that it can be
171 * preempted for a certain amount of time. When the driver was preempted and the value to be set
172 * is short in time, there is a risk that the driver sets a compare value that is
173 * behind. In this case, if the reliable mode is enabled for the specified instance,
174 * the risk is handled.
175 * However, to detect if the requested value is behind, this mode makes the following assumptions:
176 * - The maximum preemption time in ticks (8-bit value) is known and is less than 7.7 ms
177 * (for prescaler = 0, RTC frequency 32 kHz).
178 * - The requested absolute compare value is not bigger than (0x00FFFFFF)-tick_latency. It is
179 * the user's responsibility to ensure this.
180 *
181 * @param[in] p_instance Pointer to the driver instance structure.
182 * @param[in] channel One of the channels of the instance.
183 * @param[in] val Absolute value to be set in the compare register.
184 * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt.
185 *
186 * @retval NRFX_SUCCESS The procedure is successful.
187 * @retval NRFX_ERROR_TIMEOUT The compare is not set because the request value is behind the
188 * current counter value. This error can only be reported
189 * if the reliable mode is enabled.
190 */
191 nrfx_err_t nrfx_rtc_cc_set(nrfx_rtc_t const * p_instance,
192 uint32_t channel,
193 uint32_t val,
194 bool enable_irq);
195
196 /**
197 * @brief Function for disabling a channel.
198 *
199 * This function disables channel events and channel interrupts.
200 *
201 * @param[in] p_instance Pointer to the driver instance structure.
202 * @param[in] channel One of the channels of the instance.
203 *
204 * @retval NRFX_SUCCESS The procedure is successful.
205 * @retval NRFX_ERROR_TIMEOUT Interrupt is pending on the requested channel.
206 */
207 nrfx_err_t nrfx_rtc_cc_disable(nrfx_rtc_t const * p_instance, uint32_t channel);
208
209 /**
210 * @brief Function for enabling the TICK event.
211 *
212 * This function enables the tick event and optionally the interrupt.
213 *
214 * @param[in] p_instance Pointer to the driver instance structure.
215 * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt.
216 */
217 void nrfx_rtc_tick_enable(nrfx_rtc_t const * p_instance, bool enable_irq);
218
219 /**
220 * @brief Function for disabling the TICK event.
221 *
222 * This function disables the TICK event and interrupt.
223 *
224 * @param[in] p_instance Pointer to the driver instance structure.
225 */
226 void nrfx_rtc_tick_disable(nrfx_rtc_t const * p_instance);
227
228 /**
229 * @brief Function for enabling overflow.
230 *
231 * This function enables the overflow event and optionally the interrupt.
232 *
233 * @param[in] p_instance Pointer to the driver instance structure.
234 * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt.
235 */
236 void nrfx_rtc_overflow_enable(nrfx_rtc_t const * p_instance, bool enable_irq);
237
238 /**
239 * @brief Function for disabling overflow.
240 *
241 * This function disables the overflow event and interrupt.
242 *
243 * @param[in] p_instance Pointer to the driver instance structure.
244 */
245 void nrfx_rtc_overflow_disable(nrfx_rtc_t const * p_instance);
246
247 /**
248 * @brief Function for getting the maximum relative tick value that can be set in the compare channel.
249 *
250 * When a stack (for example SoftDevice) is used and it occupies high priority interrupts,
251 * the application code can be interrupted at any moment for a certain period of time.
252 * If the reliable mode is enabled, the provided maximum latency is taken into account
253 * and the return value is smaller than the RTC counter resolution.
254 * If the reliable mode is disabled, the return value equals the counter resolution.
255 *
256 * @param[in] p_instance Pointer to the driver instance structure.
257 *
258 * @return Maximum ticks value.
259 */
260 uint32_t nrfx_rtc_max_ticks_get(nrfx_rtc_t const * p_instance);
261
262 /**
263 * @brief Function for disabling all instance interrupts.
264 *
265 * @param[in] p_instance Pointer to the driver instance structure.
266 * @param[in] p_mask Pointer to the location where the mask is filled.
267 */
268 NRFX_STATIC_INLINE void nrfx_rtc_int_disable(nrfx_rtc_t const * p_instance,
269 uint32_t * p_mask);
270
271 /**
272 * @brief Function for enabling instance interrupts.
273 *
274 * @param[in] p_instance Pointer to the driver instance structure.
275 * @param[in] mask Mask of interrupts to enable.
276 */
277 NRFX_STATIC_INLINE void nrfx_rtc_int_enable(nrfx_rtc_t const * p_instance, uint32_t mask);
278
279 /**
280 * @brief Function for retrieving the current counter value.
281 *
282 * @param[in] p_instance Pointer to the driver instance structure.
283 *
284 * @return Counter value.
285 */
286 NRFX_STATIC_INLINE uint32_t nrfx_rtc_counter_get(nrfx_rtc_t const * p_instance);
287
288 /**
289 * @brief Function for clearing the counter value.
290 *
291 * @param[in] p_instance Pointer to the driver instance structure.
292 */
293 NRFX_STATIC_INLINE void nrfx_rtc_counter_clear(nrfx_rtc_t const * p_instance);
294
295 /**
296 * @brief Function for returning a requested task address for the RTC driver instance.
297 *
298 * The task address can be used by the PPI module.
299 *
300 * @param[in] p_instance Pointer to the instance.
301 * @param[in] task One of the peripheral tasks.
302 *
303 * @return Address of task register.
304 */
305 NRFX_STATIC_INLINE uint32_t nrfx_rtc_task_address_get(nrfx_rtc_t const * p_instance,
306 nrf_rtc_task_t task);
307
308 /**
309 * @brief Function for returning a requested event address for the RTC driver instance.
310 *
311 * The event address can be used by the PPI module.
312 *
313 * @param[in] p_instance Pointer to the driver instance structure.
314 * @param[in] event One of the peripheral events.
315 *
316 * @return Address of event register.
317 */
318 NRFX_STATIC_INLINE uint32_t nrfx_rtc_event_address_get(nrfx_rtc_t const * p_instance,
319 nrf_rtc_event_t event);
320
321 #ifndef NRFX_DECLARE_ONLY
nrfx_rtc_int_disable(nrfx_rtc_t const * p_instance,uint32_t * p_mask)322 NRFX_STATIC_INLINE void nrfx_rtc_int_disable(nrfx_rtc_t const * p_instance,
323 uint32_t * p_mask)
324 {
325 *p_mask = nrf_rtc_int_enable_check(p_instance->p_reg, ~0uL);
326 nrf_rtc_int_disable(p_instance->p_reg, NRF_RTC_INT_TICK_MASK |
327 NRF_RTC_INT_OVERFLOW_MASK |
328 NRF_RTC_INT_COMPARE0_MASK |
329 NRF_RTC_INT_COMPARE1_MASK |
330 NRF_RTC_INT_COMPARE2_MASK |
331 NRF_RTC_INT_COMPARE3_MASK);
332 }
333
nrfx_rtc_int_enable(nrfx_rtc_t const * p_instance,uint32_t mask)334 NRFX_STATIC_INLINE void nrfx_rtc_int_enable(nrfx_rtc_t const * p_instance, uint32_t mask)
335 {
336 nrf_rtc_int_enable(p_instance->p_reg, mask);
337 }
338
nrfx_rtc_counter_get(nrfx_rtc_t const * p_instance)339 NRFX_STATIC_INLINE uint32_t nrfx_rtc_counter_get(nrfx_rtc_t const * p_instance)
340 {
341 return nrf_rtc_counter_get(p_instance->p_reg);
342 }
343
nrfx_rtc_counter_clear(nrfx_rtc_t const * p_instance)344 NRFX_STATIC_INLINE void nrfx_rtc_counter_clear(nrfx_rtc_t const * p_instance)
345 {
346 nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_CLEAR);
347 }
348
nrfx_rtc_task_address_get(nrfx_rtc_t const * p_instance,nrf_rtc_task_t task)349 NRFX_STATIC_INLINE uint32_t nrfx_rtc_task_address_get(nrfx_rtc_t const * p_instance,
350 nrf_rtc_task_t task)
351 {
352 return nrf_rtc_task_address_get(p_instance->p_reg, task);
353 }
354
nrfx_rtc_event_address_get(nrfx_rtc_t const * p_instance,nrf_rtc_event_t event)355 NRFX_STATIC_INLINE uint32_t nrfx_rtc_event_address_get(nrfx_rtc_t const * p_instance,
356 nrf_rtc_event_t event)
357 {
358 return nrf_rtc_event_address_get(p_instance->p_reg, event);
359 }
360 #endif // NRFX_DECLARE_ONLY
361
362 /** @} */
363
364
365 void nrfx_rtc_0_irq_handler(void);
366 void nrfx_rtc_1_irq_handler(void);
367 void nrfx_rtc_2_irq_handler(void);
368
369
370 #ifdef __cplusplus
371 }
372 #endif
373
374 #endif // NRFX_RTC_H__
375