Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2014 - 2022, Nordic Semiconductor ASA
3 : : * All rights reserved.
4 : : *
5 : : * SPDX-License-Identifier: BSD-3-Clause
6 : : *
7 : : * Redistribution and use in source and binary forms, with or without
8 : : * modification, are permitted provided that the following conditions are met:
9 : : *
10 : : * 1. Redistributions of source code must retain the above copyright notice, this
11 : : * list of conditions and the following disclaimer.
12 : : *
13 : : * 2. Redistributions in binary form must reproduce the above copyright
14 : : * notice, this list of conditions and the following disclaimer in the
15 : : * documentation and/or other materials provided with the distribution.
16 : : *
17 : : * 3. Neither the name of the copyright holder nor the names of its
18 : : * contributors may be used to endorse or promote products derived from this
19 : : * software without specific prior written permission.
20 : : *
21 : : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 : : * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 : : * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 : : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 : : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 : : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 : : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 : : * POSSIBILITY OF SUCH DAMAGE.
32 : : */
33 : :
34 : : #ifndef NRF_RTC_H
35 : : #define NRF_RTC_H
36 : :
37 : : #include <nrfx.h>
38 : :
39 : : #ifdef __cplusplus
40 : : extern "C" {
41 : : #endif
42 : :
43 : : /**
44 : : * @defgroup nrf_rtc_hal RTC HAL
45 : : * @{
46 : : * @ingroup nrf_rtc
47 : : * @brief Hardware access layer for managing the Real Time Counter (RTC) peripheral.
48 : : */
49 : :
50 : : /** @brief Macro for getting the number of compare channels available in a given RTC instance. */
51 : : #define NRF_RTC_CC_CHANNEL_COUNT(id) NRFX_CONCAT_3(RTC, id, _CC_NUM)
52 : :
53 : : /** @brief Maximum value of the RTC counter. */
54 : : #define NRF_RTC_COUNTER_MAX RTC_COUNTER_COUNTER_Msk
55 : :
56 : : /** @brief Input frequency of the RTC instance. */
57 : : #define RTC_INPUT_FREQ 32768
58 : :
59 : : /** @brief Macro for converting expected frequency to prescaler setting. */
60 : : #define RTC_FREQ_TO_PRESCALER(FREQ) (uint16_t)(((RTC_INPUT_FREQ) / (FREQ)) - 1)
61 : :
62 : : /** @brief Macro for trimming values to the RTC bit width. */
63 : : #define RTC_WRAP(val) ((val) & RTC_COUNTER_COUNTER_Msk)
64 : :
65 : : /** @brief Macro for creating the interrupt bitmask for the specified compare channel. */
66 : : #define RTC_CHANNEL_INT_MASK(ch) ((uint32_t)(NRF_RTC_INT_COMPARE0_MASK) << (ch))
67 : :
68 : : /** @brief Macro for obtaining the compare event for the specified channel. */
69 : : #define RTC_CHANNEL_EVENT_ADDR(ch) (nrf_rtc_event_t)((NRF_RTC_EVENT_COMPARE_0) + (ch) * sizeof(uint32_t))
70 : :
71 : :
72 : : /** @brief RTC tasks. */
73 : : typedef enum
74 : : {
75 : : NRF_RTC_TASK_START = offsetof(NRF_RTC_Type,TASKS_START), /**< Start. */
76 : : NRF_RTC_TASK_STOP = offsetof(NRF_RTC_Type,TASKS_STOP), /**< Stop. */
77 : : NRF_RTC_TASK_CLEAR = offsetof(NRF_RTC_Type,TASKS_CLEAR), /**< Clear. */
78 : : NRF_RTC_TASK_TRIGGER_OVERFLOW = offsetof(NRF_RTC_Type,TASKS_TRIGOVRFLW), /**< Trigger overflow. */
79 : : #if defined(RTC_TASKS_CAPTURE_TASKS_CAPTURE_Msk) || defined(__NRFX_DOXYGEN__)
80 : : NRF_RTC_TASK_CAPTURE_0 = offsetof(NRF_RTC_Type,TASKS_CAPTURE[0]), /**< Capture the counter value on channel 0. */
81 : : NRF_RTC_TASK_CAPTURE_1 = offsetof(NRF_RTC_Type,TASKS_CAPTURE[1]), /**< Capture the counter value on channel 1. */
82 : : NRF_RTC_TASK_CAPTURE_2 = offsetof(NRF_RTC_Type,TASKS_CAPTURE[2]), /**< Capture the counter value on channel 2. */
83 : : NRF_RTC_TASK_CAPTURE_3 = offsetof(NRF_RTC_Type,TASKS_CAPTURE[3]), /**< Capture the counter value on channel 3. */
84 : : #endif
85 : : } nrf_rtc_task_t;
86 : :
87 : : /** @brief RTC events. */
88 : : typedef enum
89 : : {
90 : : NRF_RTC_EVENT_TICK = offsetof(NRF_RTC_Type,EVENTS_TICK), /**< Tick event. */
91 : : NRF_RTC_EVENT_OVERFLOW = offsetof(NRF_RTC_Type,EVENTS_OVRFLW), /**< Overflow event. */
92 : : NRF_RTC_EVENT_COMPARE_0 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[0]), /**< Compare 0 event. */
93 : : NRF_RTC_EVENT_COMPARE_1 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[1]), /**< Compare 1 event. */
94 : : NRF_RTC_EVENT_COMPARE_2 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[2]), /**< Compare 2 event. */
95 : : NRF_RTC_EVENT_COMPARE_3 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[3]) /**< Compare 3 event. */
96 : : } nrf_rtc_event_t;
97 : :
98 : : /** @brief RTC interrupts. */
99 : : typedef enum
100 : : {
101 : : NRF_RTC_INT_TICK_MASK = RTC_INTENSET_TICK_Msk, /**< RTC interrupt from tick event. */
102 : : NRF_RTC_INT_OVERFLOW_MASK = RTC_INTENSET_OVRFLW_Msk, /**< RTC interrupt from overflow event. */
103 : : NRF_RTC_INT_COMPARE0_MASK = RTC_INTENSET_COMPARE0_Msk, /**< RTC interrupt from compare event on channel 0. */
104 : : NRF_RTC_INT_COMPARE1_MASK = RTC_INTENSET_COMPARE1_Msk, /**< RTC interrupt from compare event on channel 1. */
105 : : NRF_RTC_INT_COMPARE2_MASK = RTC_INTENSET_COMPARE2_Msk, /**< RTC interrupt from compare event on channel 2. */
106 : : NRF_RTC_INT_COMPARE3_MASK = RTC_INTENSET_COMPARE3_Msk /**< RTC interrupt from compare event on channel 3. */
107 : : } nrf_rtc_int_t;
108 : :
109 : :
110 : : /**
111 : : * @brief Function for setting a compare value for a channel.
112 : : *
113 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
114 : : * @param[in] ch Channel.
115 : : * @param[in] cc_val Compare value to be set.
116 : : */
117 : : NRF_STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_reg, uint32_t ch, uint32_t cc_val);
118 : :
119 : : /**
120 : : * @brief Function for returning the compare value for a channel.
121 : : *
122 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
123 : : * @param[in] ch Channel.
124 : : *
125 : : * @return COMPARE[ch] value.
126 : : */
127 : : NRF_STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type const * p_reg, uint32_t ch);
128 : :
129 : : /**
130 : : * @brief Function for enabling interrupts.
131 : : *
132 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
133 : : * @param[in] mask Interrupt mask to be enabled.
134 : : */
135 : : NRF_STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_reg, uint32_t mask);
136 : :
137 : : /**
138 : : * @brief Function for disabling interrupts.
139 : : *
140 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
141 : : * @param[in] mask Interrupt mask to be disabled.
142 : : */
143 : : NRF_STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_reg, uint32_t mask);
144 : :
145 : : /**
146 : : * @brief Function for checking if the specified interrupts are enabled.
147 : : *
148 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
149 : : * @param[in] mask Mask of interrupts to be checked.
150 : : *
151 : : * @return Mask of enabled interrupts.
152 : : */
153 : : NRF_STATIC_INLINE uint32_t nrf_rtc_int_enable_check(NRF_RTC_Type const * p_reg, uint32_t mask);
154 : :
155 : : #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
156 : : /**
157 : : * @brief Function for setting the subscribe configuration for a given
158 : : * RTC task.
159 : : *
160 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
161 : : * @param[in] task Task for which to set the configuration.
162 : : * @param[in] channel Channel through which to subscribe events.
163 : : */
164 : : NRF_STATIC_INLINE void nrf_rtc_subscribe_set(NRF_RTC_Type * p_reg,
165 : : nrf_rtc_task_t task,
166 : : uint8_t channel);
167 : :
168 : : /**
169 : : * @brief Function for clearing the subscribe configuration for a given
170 : : * RTC task.
171 : : *
172 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
173 : : * @param[in] task Task for which to clear the configuration.
174 : : */
175 : : NRF_STATIC_INLINE void nrf_rtc_subscribe_clear(NRF_RTC_Type * p_reg,
176 : : nrf_rtc_task_t task);
177 : :
178 : : /**
179 : : * @brief Function for setting the publish configuration for a given
180 : : * RTC event.
181 : : *
182 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
183 : : * @param[in] event Event for which to set the configuration.
184 : : * @param[in] channel Channel through which to publish the event.
185 : : */
186 : : NRF_STATIC_INLINE void nrf_rtc_publish_set(NRF_RTC_Type * p_reg,
187 : : nrf_rtc_event_t event,
188 : : uint8_t channel);
189 : :
190 : : /**
191 : : * @brief Function for clearing the publish configuration for a given
192 : : * RTC event.
193 : : *
194 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
195 : : * @param[in] event Event for which to clear the configuration.
196 : : */
197 : : NRF_STATIC_INLINE void nrf_rtc_publish_clear(NRF_RTC_Type * p_reg,
198 : : nrf_rtc_event_t event);
199 : : #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
200 : :
201 : : /**
202 : : * @brief Function for retrieving the state of the RTC event.
203 : : *
204 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
205 : : * @param[in] event Event to be checked.
206 : : *
207 : : * @retval true The event has been generated.
208 : : * @retval false The event has not been generated.
209 : : */
210 : : NRF_STATIC_INLINE bool nrf_rtc_event_check(NRF_RTC_Type const * p_reg, nrf_rtc_event_t event);
211 : :
212 : : /**
213 : : * @brief Function for clearing an event.
214 : : *
215 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
216 : : * @param[in] event Event to be cleared.
217 : : */
218 : : NRF_STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_reg, nrf_rtc_event_t event);
219 : :
220 : : /**
221 : : * @brief Function for returning a counter value.
222 : : *
223 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
224 : : *
225 : : * @return Counter value.
226 : : */
227 : : NRF_STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type const * p_reg);
228 : :
229 : : /**
230 : : * @brief Function for setting a prescaler value.
231 : : *
232 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
233 : : * @param[in] val Value to set the prescaler to.
234 : : */
235 : : NRF_STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_reg, uint32_t val);
236 : :
237 : : /**
238 : : * @brief Function for getting a prescaler value.
239 : : *
240 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
241 : : *
242 : : * @return Prescaler value.
243 : : */
244 : : NRF_STATIC_INLINE uint32_t nrf_rtc_prescaler_get(NRF_RTC_Type const * p_reg);
245 : :
246 : : /**
247 : : * @brief Function for returning the address of an event.
248 : : *
249 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
250 : : * @param[in] event Requested event.
251 : : *
252 : : * @return Address of the requested event register.
253 : : */
254 : : NRF_STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type const * p_reg,
255 : : nrf_rtc_event_t event);
256 : :
257 : : /**
258 : : * @brief Function for returning the address of a task.
259 : : *
260 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
261 : : * @param[in] task Requested task.
262 : : *
263 : : * @return Address of the requested task register.
264 : : */
265 : : NRF_STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type const * p_reg,
266 : : nrf_rtc_task_t task);
267 : :
268 : : /**
269 : : * @brief Function for starting a task.
270 : : *
271 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
272 : : * @param[in] task Requested task.
273 : : */
274 : : NRF_STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_reg, nrf_rtc_task_t task);
275 : :
276 : : /**
277 : : * @brief Function for enabling events.
278 : : *
279 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
280 : : * @param[in] mask Mask of event flags to be enabled.
281 : : */
282 : : NRF_STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_reg, uint32_t mask);
283 : :
284 : : /**
285 : : * @brief Function for disabling an event.
286 : : *
287 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
288 : : * @param[in] event Requested event.
289 : : */
290 : : NRF_STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_reg, uint32_t event);
291 : :
292 : : /**
293 : : * @brief Function for getting the COMPARE event associated with the specified compare channel.
294 : : *
295 : : * @param[in] index Compare channel index.
296 : : *
297 : : * @return Requested COMPARE event.
298 : : */
299 : : NRF_STATIC_INLINE nrf_rtc_event_t nrf_rtc_compare_event_get(uint8_t index);
300 : :
301 : : #ifndef NRF_DECLARE_ONLY
302 : :
303 : 2 : NRF_STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_reg, uint32_t ch, uint32_t cc_val)
304 : : {
305 : 2 : p_reg->CC[ch] = cc_val;
306 : 2 : }
307 : :
308 : 1 : NRF_STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type const * p_reg, uint32_t ch)
309 : : {
310 : 1 : return p_reg->CC[ch];
311 : : }
312 : :
313 : 3 : NRF_STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_reg, uint32_t mask)
314 : : {
315 : 3 : p_reg->INTENSET = mask;
316 : 3 : }
317 : :
318 : 1 : NRF_STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_reg, uint32_t mask)
319 : : {
320 : 1 : p_reg->INTENCLR = mask;
321 : 1 : }
322 : :
323 : 0 : NRF_STATIC_INLINE uint32_t nrf_rtc_int_enable_check(NRF_RTC_Type const * p_reg, uint32_t mask)
324 : : {
325 : 0 : return p_reg->INTENSET & mask;
326 : : }
327 : :
328 : : #if defined(DPPI_PRESENT)
329 : : NRF_STATIC_INLINE void nrf_rtc_subscribe_set(NRF_RTC_Type * p_reg,
330 : : nrf_rtc_task_t task,
331 : : uint8_t channel)
332 : : {
333 : : *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
334 : : ((uint32_t)channel | RTC_SUBSCRIBE_START_EN_Msk);
335 : : }
336 : :
337 : : NRF_STATIC_INLINE void nrf_rtc_subscribe_clear(NRF_RTC_Type * p_reg,
338 : : nrf_rtc_task_t task)
339 : : {
340 : : *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
341 : : }
342 : :
343 : : NRF_STATIC_INLINE void nrf_rtc_publish_set(NRF_RTC_Type * p_reg,
344 : : nrf_rtc_event_t event,
345 : : uint8_t channel)
346 : : {
347 : : *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
348 : : ((uint32_t)channel | RTC_PUBLISH_TICK_EN_Msk);
349 : : }
350 : :
351 : : NRF_STATIC_INLINE void nrf_rtc_publish_clear(NRF_RTC_Type * p_reg,
352 : : nrf_rtc_event_t event)
353 : : {
354 : : *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
355 : : }
356 : : #endif // defined(DPPI_PRESENT)
357 : :
358 : 0 : NRF_STATIC_INLINE bool nrf_rtc_event_check(NRF_RTC_Type const * p_reg, nrf_rtc_event_t event)
359 : : {
360 : 0 : return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
361 : : }
362 : :
363 : 1 : NRF_STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_reg, nrf_rtc_event_t event)
364 : : {
365 : 1 : *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0;
366 : 1 : nrf_event_readback((uint8_t *)p_reg + (uint32_t)event);
367 : 1 : }
368 : :
369 : 53 : NRF_STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type const * p_reg)
370 : : {
371 : 53 : return p_reg->COUNTER;
372 : : }
373 : :
374 : 1 : NRF_STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_reg, uint32_t val)
375 : : {
376 [ - + ]: 1 : NRFX_ASSERT(val <= (RTC_PRESCALER_PRESCALER_Msk >> RTC_PRESCALER_PRESCALER_Pos));
377 : 1 : p_reg->PRESCALER = val;
378 : 1 : }
379 : :
380 : : NRF_STATIC_INLINE uint32_t nrf_rtc_prescaler_get(NRF_RTC_Type const * p_reg)
381 : : {
382 : : return p_reg->PRESCALER;
383 : : }
384 : :
385 : 0 : NRF_STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type const * p_reg,
386 : : nrf_rtc_event_t event)
387 : : {
388 : 0 : return (uint32_t)p_reg + event;
389 : : }
390 : :
391 : 0 : NRF_STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type const * p_reg,
392 : : nrf_rtc_task_t task)
393 : : {
394 : 0 : return (uint32_t)p_reg + task;
395 : : }
396 : :
397 : 2 : NRF_STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_reg, nrf_rtc_task_t task)
398 : : {
399 : 2 : *(__IO uint32_t *)((uint32_t)p_reg + task) = 1;
400 : 2 : }
401 : :
402 : 1 : NRF_STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_reg, uint32_t mask)
403 : : {
404 : 1 : p_reg->EVTENSET = mask;
405 : 1 : }
406 : :
407 : 0 : NRF_STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_reg, uint32_t mask)
408 : : {
409 : 0 : p_reg->EVTENCLR = mask;
410 : 0 : }
411 : :
412 : 0 : NRF_STATIC_INLINE nrf_rtc_event_t nrf_rtc_compare_event_get(uint8_t index)
413 : : {
414 : 0 : return (nrf_rtc_event_t)NRFX_OFFSETOF(NRF_RTC_Type, EVENTS_COMPARE[index]);
415 : : }
416 : :
417 : : #endif // NRF_DECLARE_ONLY
418 : :
419 : : /** @} */
420 : :
421 : : #ifdef __cplusplus
422 : : }
423 : : #endif
424 : :
425 : : #endif /* NRF_RTC_H */
|