1 /*
2 * Copyright (c) 2021 - 2025, 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 #include <nrfx.h>
35
36 #if NRFX_CHECK(NRFX_GRTC_ENABLED)
37
38 #include <nrfx_grtc.h>
39 #include <soc/nrfx_coredep.h>
40 #include <helpers/nrfx_flag32_allocator.h>
41
42 #define NRFX_LOG_MODULE GRTC
43 #include <nrfx_log.h>
44
45 #if NRFY_GRTC_HAS_EXTENDED
46 #define GRTC_ACTION_TO_STR(action) \
47 (action == NRFX_GRTC_ACTION_START ? "NRFX_GRTC_ACTION_START" : \
48 (action == NRFX_GRTC_ACTION_STOP ? "NRFX_GRTC_ACTION_STOP" : \
49 (action == NRFX_GRTC_ACTION_CLEAR ? "NRFX_GRTC_ACTION_CLEAR" : \
50 "UNKNOWN ACTION")))
51 #endif
52
53 #define GRTC_CHANNEL_TO_BITMASK(chan) NRFX_BIT(chan)
54 #define GRTC_CHANNEL_MASK_TO_INT_MASK(ch_mask) ((ch_mask) << GRTC_INTEN0_COMPARE0_Pos)
55
56 #if !defined(NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK)
57 #error "Channels mask for GRTC must be defined."
58 #endif
59
60 #if !defined(NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS)
61 #error "Number of channels for GRTC must be defined."
62 #endif
63
64 #if NRF_GRTC_HAS_RTCOUNTER
65 #define GRTC_NON_SYSCOMPARE_INT_MASK (NRF_GRTC_INT_RTCOMPARE_MASK | \
66 NRF_GRTC_INT_RTCOMPARESYNC_MASK | \
67 NRF_GRTC_INT_SYSCOUNTERVALID_MASK)
68 #define GRTC_ALL_INT_MASK (NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK | \
69 GRTC_NON_SYSCOMPARE_INT_MASK)
70 #define GRTC_RTCOUNTER_CC_HANDLER_IDX NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS
71 #define GRTC_RTCOUNTER_COMPARE_CHANNEL NRF_GRTC_SYSCOUNTER_CC_COUNT
72 #else
73 #define GRTC_ALL_INT_MASK (NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK)
74 #endif // NRF_GRTC_HAS_RTCOUNTER
75
76 #if !(defined(NRF_SECURE) && NRFX_IS_ENABLED(NRFY_GRTC_HAS_EXTENDED))
77 #define MAIN_GRTC_CC_CHANNEL NRF_GRTC_MAIN_CC_CHANNEL
78 #if NRFX_IS_ENABLED(NRFY_GRTC_HAS_EXTENDED)
79 /* Verify that the GRTC owner possesses the main capture/compare channel. */
80 NRFX_STATIC_ASSERT(NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK &
81 GRTC_CHANNEL_TO_BITMASK(MAIN_GRTC_CC_CHANNEL));
82 #else
83 /* Any other domain which is not an owner of GRTC shouldn't have an access to
84 the main capture/compare channel. */
85 NRFX_STATIC_ASSERT(!(NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK &
86 GRTC_CHANNEL_TO_BITMASK(MAIN_GRTC_CC_CHANNEL)));
87 #endif //NRFX_IS_ENABLED(NRFY_GRTC_HAS_EXTENDED)
88 #else
89 /* Change the main capture/compare channel to allow Secdom to start GRTC in extended mode. */
90 #define MAIN_GRTC_CC_CHANNEL (m_cb.channel_data[0].channel)
91 #endif // !(defined(NRF_SECURE) && NRFY_GRTC_HAS_EXTENDED)
92
93 /* The maximum SYSCOUNTERVALID settling time equals 1x32k cycles + 20x16MHz cycles. */
94 #define GRTC_SYSCOUNTERVALID_SETTLE_MAX_TIME_US 33
95
96 /* The timeout for the SYSCOUNTER's ready state after starting it. */
97 #define STARTUP_TIMEOUT ((SystemCoreClock / 1000000U) * GRTC_SYSCOUNTERVALID_SETTLE_MAX_TIME_US)
98
99 typedef struct
100 {
101 nrfx_drv_state_t state; /**< Driver state. */
102 nrfx_atomic_t available_channels; /**< Bitmask of available channels. */
103 uint32_t used_channels; /**< Bitmask of channels used by the driver. */
104 nrfx_grtc_channel_t channel_data[NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS + 1]; /**< Channel specific data. */
105 #if NRF_GRTC_HAS_RTCOUNTER
106 nrfx_grtc_rtcomparesync_handler_t rtcomparesync_handler; /**< User handler corresponding to rtcomparesync event.*/
107 void * rtcomparesync_context; /**< User context for rtcomparesync event handler. */
108 #endif
109 #if NRFY_GRTC_HAS_EXTENDED && NRFY_GRTC_HAS_SYSCOUNTERVALID
110 nrfx_grtc_syscountervalid_handler_t syscountervalid_handler; /**< User handler corresponding to syscountervalid event. */
111 void * syscountervalid_context; /**< User context for syscountervalid event handler. */
112 #endif
113 } nrfx_grtc_cb_t;
114
115 static nrfx_grtc_cb_t m_cb =
116 {
117 // At the initialization only channels assigned by configuration are available.
118 .available_channels = (nrfx_atomic_t)NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK
119 };
120
num_of_channels_get(uint32_t mask)121 static uint8_t num_of_channels_get(uint32_t mask)
122 {
123 uint8_t ch_count = 0;
124
125 while (mask)
126 {
127 // Calculating number of channels by counting ones inside given mask.
128 ch_count += mask & 0x1;
129 mask >>= 1;
130 }
131 return ch_count;
132 }
133
allocated_channels_mask_get(void)134 static uint32_t allocated_channels_mask_get(void)
135 {
136 return NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK & ~m_cb.available_channels;
137 }
138
used_channels_mask_get(void)139 static uint32_t used_channels_mask_get(void)
140 {
141 return NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK & m_cb.used_channels;
142 }
143
144 #if NRFY_GRTC_HAS_EXTENDED
is_syscounter_running(void)145 static bool is_syscounter_running(void)
146 {
147 return nrfy_grtc_sys_counter_check(NRF_GRTC);
148 }
149 #endif
150
is_channel_used(uint8_t channel)151 static bool is_channel_used(uint8_t channel)
152 {
153 return (GRTC_CHANNEL_TO_BITMASK(channel) & used_channels_mask_get());
154 }
155
is_channel_allocated(uint8_t channel)156 static bool is_channel_allocated(uint8_t channel)
157 {
158 return (GRTC_CHANNEL_TO_BITMASK(channel) & allocated_channels_mask_get());
159 }
160
channel_used_mark(uint8_t channel)161 static void channel_used_mark(uint8_t channel)
162 {
163 m_cb.used_channels |= GRTC_CHANNEL_TO_BITMASK(channel);
164 }
165
channel_used_unmark(uint8_t channel)166 static void channel_used_unmark(uint8_t channel)
167 {
168 m_cb.used_channels &= ~GRTC_CHANNEL_TO_BITMASK(channel);
169 }
170
is_channel_available(uint8_t channel)171 static bool is_channel_available(uint8_t channel)
172 {
173 return (GRTC_CHANNEL_TO_BITMASK(channel) & NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK);
174 }
175
syscounter_check(uint8_t channel)176 static nrfx_err_t syscounter_check(uint8_t channel)
177 {
178 if (!is_channel_available(channel))
179 {
180 return NRFX_ERROR_FORBIDDEN;
181 }
182 if (!is_channel_allocated(channel))
183 {
184 return NRFX_ERROR_INVALID_PARAM;
185 }
186 return NRFX_SUCCESS;
187 }
188
get_channel_for_ch_data_idx(uint8_t idx)189 static uint8_t get_channel_for_ch_data_idx(uint8_t idx)
190 {
191 uint32_t ch_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK;
192
193 for (uint8_t i = 0; i < idx; i++)
194 {
195 ch_mask &= ~(1UL << NRF_CTZ(ch_mask));
196 }
197 return (uint8_t)NRF_CTZ(ch_mask);
198 }
199
get_ch_data_index_for_channel(uint8_t channel)200 static uint8_t get_ch_data_index_for_channel(uint8_t channel)
201 {
202 uint32_t ch_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK;
203 uint8_t idx;
204
205 for (idx = 0; channel != NRF_CTZ(ch_mask); idx++)
206 {
207 ch_mask &= ~(1UL << NRF_CTZ(ch_mask));
208 }
209 return idx;
210 }
211
cc_channel_prepare(nrfx_grtc_channel_t * p_chan_data)212 static void cc_channel_prepare(nrfx_grtc_channel_t * p_chan_data)
213 {
214 NRFX_ASSERT(p_chan_data);
215 uint8_t ch_data_idx = get_ch_data_index_for_channel(p_chan_data->channel);
216
217 nrfy_grtc_sys_counter_compare_event_disable(NRF_GRTC, p_chan_data->channel);
218
219 m_cb.channel_data[ch_data_idx].handler = p_chan_data->handler;
220 m_cb.channel_data[ch_data_idx].p_context = p_chan_data->p_context;
221 m_cb.channel_data[ch_data_idx].channel = p_chan_data->channel;
222 channel_used_mark(p_chan_data->channel);
223 }
224
225 #if NRFY_GRTC_HAS_EXTENDED
sleep_configure(nrfx_grtc_sleep_config_t const * p_sleep_cfg)226 static void sleep_configure(nrfx_grtc_sleep_config_t const * p_sleep_cfg)
227 {
228 nrfy_grtc_sys_counter_auto_mode_set(NRF_GRTC, p_sleep_cfg->auto_mode);
229 nrfy_grtc_timeout_set(NRF_GRTC, p_sleep_cfg->timeout);
230 nrfy_grtc_waketime_set(NRF_GRTC, p_sleep_cfg->waketime);
231 }
232
sleep_configuration_get(nrfx_grtc_sleep_config_t * p_sleep_cfg)233 static void sleep_configuration_get(nrfx_grtc_sleep_config_t * p_sleep_cfg)
234 {
235 p_sleep_cfg->auto_mode = nrfy_grtc_sys_counter_auto_mode_check(NRF_GRTC);
236 p_sleep_cfg->timeout = nrfy_grtc_timeout_get(NRF_GRTC);
237 p_sleep_cfg->waketime = nrfy_grtc_waketime_get(NRF_GRTC);
238 }
239 #endif /* NRFY_GRTC_HAS_EXTENDED */
240
active_check(void)241 static inline bool active_check(void)
242 {
243 #if NRFY_GRTC_HAS_SYSCOUNTER_ARRAY
244 return nrfy_grtc_sys_counter_active_check(NRF_GRTC);
245 #else
246 return nrfy_grtc_sys_counter_active_state_request_check(NRF_GRTC);
247 #endif
248 }
249
active_set(bool active)250 static inline void active_set(bool active)
251 {
252 #if defined(NRF_GRTC_HAS_SYSCOUNTER_ARRAY) && (NRF_GRTC_HAS_SYSCOUNTER_ARRAY == 1)
253 nrfy_grtc_sys_counter_active_set(NRF_GRTC, active);
254 #else
255 nrfy_grtc_sys_counter_active_state_request_set(NRF_GRTC, active);
256 #endif
257 }
258
ready_check(void)259 static inline bool ready_check(void)
260 {
261 return nrfy_grtc_sys_counter_ready_check(NRF_GRTC);
262 }
263
nrfx_grtc_active_request_check(void)264 bool nrfx_grtc_active_request_check(void)
265 {
266 NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_INITIALIZED);
267
268 return active_check();
269 }
270
nrfx_grtc_active_request_set(bool active)271 void nrfx_grtc_active_request_set(bool active)
272 {
273 NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_INITIALIZED);
274
275 active_set(active);
276 }
277
nrfx_grtc_ready_check(void)278 bool nrfx_grtc_ready_check(void)
279 {
280 NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_INITIALIZED);
281
282 return ready_check();
283 }
284
nrfx_grtc_syscounter_get(uint64_t * p_counter)285 nrfx_err_t nrfx_grtc_syscounter_get(uint64_t * p_counter)
286 {
287 NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_INITIALIZED);
288 NRFX_ASSERT(p_counter);
289 *p_counter = 0;
290
291 nrfx_err_t err_code = NRFX_SUCCESS;
292 #if NRFY_GRTC_HAS_EXTENDED
293 if (!is_syscounter_running())
294 {
295 err_code = NRFX_ERROR_INTERNAL;
296 NRFX_LOG_WARNING("Function: %s, error code: %s.",
297 __func__,
298 NRFX_LOG_ERROR_STRING_GET(err_code));
299 return err_code;
300 }
301 #endif // NRFY_GRTC_HAS_EXTENDED
302 NRFX_CRITICAL_SECTION_ENTER();
303 *p_counter = nrfy_grtc_sys_counter_get(NRF_GRTC);
304 NRFX_CRITICAL_SECTION_EXIT();
305
306 return err_code;
307 }
308
nrfx_grtc_channel_alloc(uint8_t * p_channel)309 nrfx_err_t nrfx_grtc_channel_alloc(uint8_t * p_channel)
310 {
311 NRFX_ASSERT(p_channel);
312 nrfx_err_t err_code = nrfx_flag32_alloc(&m_cb.available_channels, p_channel);
313
314 if (err_code != NRFX_SUCCESS)
315 {
316 NRFX_LOG_WARNING("Function: %s, error code: %s.",
317 __func__,
318 NRFX_LOG_ERROR_STRING_GET(err_code));
319 }
320
321 NRFX_LOG_INFO("GRTC channel %u allocated.", *p_channel);
322 return err_code;
323 }
324
nrfx_grtc_channel_free(uint8_t channel)325 nrfx_err_t nrfx_grtc_channel_free(uint8_t channel)
326 {
327 NRFX_ASSERT(channel < NRF_GRTC_SYSCOUNTER_CC_COUNT);
328 nrfx_err_t err_code;
329
330 channel_used_unmark(channel);
331 if (!is_channel_available(channel))
332 {
333 err_code = NRFX_ERROR_FORBIDDEN;
334 NRFX_LOG_WARNING("Function: %s, error code: %s.",
335 __func__,
336 NRFX_LOG_ERROR_STRING_GET(err_code));
337 return err_code;
338 }
339
340 err_code = nrfx_flag32_free(&m_cb.available_channels, channel);
341 if (err_code != NRFX_SUCCESS)
342 {
343 NRFX_LOG_WARNING("Function: %s, error code: %s.",
344 __func__,
345 NRFX_LOG_ERROR_STRING_GET(err_code));
346 return err_code;
347 }
348
349 NRFX_LOG_INFO("GRTC channel %u freed.", channel);
350 return err_code;
351 }
352
nrfx_grtc_is_channel_used(uint8_t channel)353 bool nrfx_grtc_is_channel_used(uint8_t channel)
354 {
355 return is_channel_used(channel);
356 }
357
nrfx_grtc_init(uint8_t interrupt_priority)358 nrfx_err_t nrfx_grtc_init(uint8_t interrupt_priority)
359 {
360 nrfx_err_t err_code = NRFX_SUCCESS;
361
362 if (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED)
363 {
364 #if NRFX_API_VER_AT_LEAST(3, 2, 0)
365 err_code = NRFX_ERROR_ALREADY;
366 #else
367 err_code = NRFX_ERROR_INVALID_STATE;
368 #endif
369 NRFX_LOG_WARNING("Function: %s, error code: %s.",
370 __func__,
371 NRFX_LOG_ERROR_STRING_GET(err_code));
372 return err_code;
373 }
374
375 #if NRFY_GRTC_HAS_EXTENDED && NRFX_IS_ENABLED(NRFX_GRTC_CONFIG_AUTOSTART)
376 nrfx_grtc_sleep_config_t sleep_cfg = NRFX_GRTC_SLEEP_DEFAULT_CONFIG;
377 #if !NRFX_IS_ENABLED(NRFX_GRTC_CONFIG_AUTOEN)
378 sleep_cfg.auto_mode = false;
379 #endif
380
381 nrfy_grtc_sys_counter_set(NRF_GRTC, false);
382 sleep_configure(&sleep_cfg);
383 #endif
384
385 if ((num_of_channels_get(NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK) !=
386 NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS) || (NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS == 0))
387 {
388 err_code = NRFX_ERROR_INTERNAL;
389 NRFX_LOG_WARNING("Function: %s, error code: %s.",
390 __func__,
391 NRFX_LOG_ERROR_STRING_GET(err_code));
392 return err_code;
393 }
394
395 for (uint8_t i = 0; i < NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS; i++)
396 {
397 m_cb.channel_data[i].channel = get_channel_for_ch_data_idx(i);
398 }
399
400 nrfy_grtc_int_init(NRF_GRTC, GRTC_ALL_INT_MASK, interrupt_priority, false);
401
402 #if NRFY_GRTC_HAS_EXTENDED && NRFX_IS_ENABLED(NRFX_GRTC_CONFIG_AUTOSTART)
403 nrfy_grtc_prepare(NRF_GRTC, true);
404
405 #endif /* NRFY_GRTC_HAS_EXTENDED && NRFX_IS_ENABLED(NRFX_GRTC_CONFIG_AUTOSTART) */
406
407 m_cb.state = NRFX_DRV_STATE_INITIALIZED;
408 NRFX_LOG_INFO("GRTC initialized.");
409 return err_code;
410 }
411
412 #if NRFY_GRTC_HAS_EXTENDED
nrfx_grtc_sleep_configure(nrfx_grtc_sleep_config_t const * p_sleep_cfg)413 nrfx_err_t nrfx_grtc_sleep_configure(nrfx_grtc_sleep_config_t const * p_sleep_cfg)
414 {
415 NRFX_ASSERT(p_sleep_cfg);
416 bool is_active;
417
418 is_active = nrfy_grtc_sys_counter_check(NRF_GRTC);
419 if (is_active)
420 {
421 nrfy_grtc_sys_counter_set(NRF_GRTC, false);
422 }
423 sleep_configure(p_sleep_cfg);
424 if (is_active)
425 {
426 nrfy_grtc_sys_counter_set(NRF_GRTC, true);
427 }
428 return NRFX_SUCCESS;
429 }
430
nrfx_grtc_sleep_configuration_get(nrfx_grtc_sleep_config_t * p_sleep_cfg)431 nrfx_err_t nrfx_grtc_sleep_configuration_get(nrfx_grtc_sleep_config_t * p_sleep_cfg)
432 {
433 NRFX_ASSERT(p_sleep_cfg);
434 sleep_configuration_get(p_sleep_cfg);
435 return NRFX_SUCCESS;
436 }
437 #endif // NRFY_GRTC_HAS_EXTENDED
438
439 #if NRF_GRTC_HAS_RTCOUNTER
nrfx_grtc_rtcounter_cc_disable(void)440 nrfx_err_t nrfx_grtc_rtcounter_cc_disable(void)
441 {
442 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
443 nrfx_err_t err_code = NRFX_SUCCESS;
444 uint32_t int_mask = NRF_GRTC_INT_RTCOMPARE_MASK | NRF_GRTC_INT_RTCOMPARESYNC_MASK;
445
446 if (is_syscounter_running())
447 {
448 err_code = NRFX_ERROR_INTERNAL;
449 NRFX_LOG_WARNING("Function: %s, error code: %s.",
450 __func__,
451 NRFX_LOG_ERROR_STRING_GET(err_code));
452 return err_code;
453 }
454
455 if (nrfy_grtc_int_enable_check(NRF_GRTC, int_mask))
456 {
457 nrfy_grtc_int_disable(NRF_GRTC, int_mask);
458 if (nrfy_grtc_event_check(NRF_GRTC, NRF_GRTC_EVENT_RTCOMPARE) ||
459 nrfy_grtc_event_check(NRF_GRTC, NRF_GRTC_EVENT_RTCOMPARESYNC))
460 {
461 nrfy_grtc_event_clear(NRF_GRTC, NRF_GRTC_EVENT_RTCOMPARE);
462 nrfy_grtc_event_clear(NRF_GRTC, NRF_GRTC_EVENT_RTCOMPARESYNC);
463 err_code = NRFX_ERROR_TIMEOUT;
464 NRFX_LOG_WARNING("Function: %s, error code: %s.",
465 __func__,
466 NRFX_LOG_ERROR_STRING_GET(err_code));
467 return err_code;
468 }
469 }
470
471 NRFX_LOG_INFO("GRTC RTCOUNTER compare disabled.");
472 return err_code;
473 }
474
nrfx_grtc_rtcomparesync_int_enable(nrfx_grtc_rtcomparesync_handler_t handler,void * p_context)475 void nrfx_grtc_rtcomparesync_int_enable(nrfx_grtc_rtcomparesync_handler_t handler, void * p_context)
476 {
477 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
478
479 m_cb.rtcomparesync_handler = handler;
480 m_cb.rtcomparesync_context = p_context;
481 nrfy_grtc_event_clear(NRF_GRTC, NRF_GRTC_EVENT_RTCOMPARESYNC);
482 nrfy_grtc_int_enable(NRF_GRTC, NRFY_EVENT_TO_INT_BITMASK(NRF_GRTC_EVENT_RTCOMPARESYNC));
483 NRFX_LOG_INFO("GRTC RTCOMPARESYNC interrupt enabled.");
484 }
485
nrfx_grtc_rtcomparesync_int_disable(void)486 void nrfx_grtc_rtcomparesync_int_disable(void)
487 {
488 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
489
490 nrfy_grtc_int_disable(NRF_GRTC, NRF_GRTC_INT_RTCOMPARESYNC_MASK);
491 NRFX_LOG_INFO("GRTC RTCOMPARESYNC interrupt disabled.");
492 }
493
nrfx_grtc_rtcounter_cc_absolute_set(nrfx_grtc_rtcounter_handler_data_t * p_handler_data,uint64_t val,bool enable_irq,bool sync)494 nrfx_err_t nrfx_grtc_rtcounter_cc_absolute_set(nrfx_grtc_rtcounter_handler_data_t * p_handler_data,
495 uint64_t val,
496 bool enable_irq,
497 bool sync)
498 {
499 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
500 NRFX_ASSERT(p_handler_data);
501 nrfx_err_t err_code = NRFX_SUCCESS;
502
503 if (is_syscounter_running())
504 {
505 err_code = NRFX_ERROR_INTERNAL;
506 NRFX_LOG_WARNING("Function: %s, error code: %s.",
507 __func__,
508 NRFX_LOG_ERROR_STRING_GET(err_code));
509 return err_code;
510 }
511 nrfx_grtc_channel_t * p_chan_data = &m_cb.channel_data[GRTC_RTCOUNTER_CC_HANDLER_IDX];
512
513 p_chan_data->handler = p_handler_data->handler;
514 p_chan_data->p_context = p_handler_data->p_context;
515 p_chan_data->channel = GRTC_RTCOUNTER_COMPARE_CHANNEL;
516
517 NRFX_CRITICAL_SECTION_ENTER();
518 nrfy_grtc_rt_counter_cc_set(NRF_GRTC, val, sync);
519 NRFX_CRITICAL_SECTION_EXIT();
520
521 nrf_grtc_event_t event = NRF_GRTC_EVENT_RTCOMPARE;
522
523 nrfy_grtc_event_clear(NRF_GRTC, event);
524 if (enable_irq)
525 {
526 nrfy_grtc_int_enable(NRF_GRTC, NRFY_EVENT_TO_INT_BITMASK(event));
527 }
528
529 NRFX_LOG_INFO("GRTC RTCOUNTER compare set to %llu.", val);
530 return err_code;
531 }
532 #endif // NRF_GRTC_HAS_RTCOUNTER
533
534 #if NRFY_GRTC_HAS_EXTENDED
nrfx_grtc_syscounter_start(bool busy_wait,uint8_t * p_main_cc_channel)535 nrfx_err_t nrfx_grtc_syscounter_start(bool busy_wait, uint8_t * p_main_cc_channel)
536 {
537 NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_INITIALIZED);
538 NRFX_ASSERT(p_main_cc_channel);
539 NRFX_ASSERT(m_cb.channel_data[0].channel == MAIN_GRTC_CC_CHANNEL);
540 nrfx_err_t err_code = NRFX_SUCCESS;
541 nrfx_atomic_t init_mask = GRTC_CHANNEL_TO_BITMASK(MAIN_GRTC_CC_CHANNEL) &
542 m_cb.available_channels;
543
544 err_code = nrfx_flag32_alloc(&init_mask, &m_cb.channel_data[0].channel);
545 if (err_code != NRFX_SUCCESS)
546 {
547 NRFX_LOG_WARNING("Function: %s, error code: %s.",
548 __func__,
549 NRFX_LOG_ERROR_STRING_GET(err_code));
550 return err_code;
551 }
552
553 *p_main_cc_channel = MAIN_GRTC_CC_CHANNEL;
554 m_cb.available_channels &= ~GRTC_CHANNEL_TO_BITMASK(MAIN_GRTC_CC_CHANNEL);
555 channel_used_mark(MAIN_GRTC_CC_CHANNEL);
556 NRFX_LOG_INFO("GRTC channel %u allocated.", m_cb.channel_data[0].channel);
557
558 if (is_syscounter_running())
559 {
560 err_code = NRFX_ERROR_ALREADY;
561 NRFX_LOG_WARNING("Function: %s, error code: %s.",
562 __func__,
563 NRFX_LOG_ERROR_STRING_GET(err_code));
564 return err_code;
565 }
566 nrfy_grtc_sys_counter_start(NRF_GRTC, busy_wait);
567 #if NRFX_IS_ENABLED(NRFX_GRTC_CONFIG_AUTOEN)
568 uint32_t startup_timeout = STARTUP_TIMEOUT;
569
570 while ((startup_timeout > 0) && (!ready_check()))
571 {
572 startup_timeout--;
573 }
574 if (startup_timeout == 0)
575 {
576 return NRFX_ERROR_TIMEOUT;
577 }
578 #endif /* NRFX_IS_ENABLED(NRFX_GRTC_CONFIG_AUTOEN) */
579 NRFX_LOG_INFO("GRTC SYSCOUNTER started.");
580 return err_code;
581 }
582
nrfx_grtc_action_perform(nrfx_grtc_action_t action)583 nrfx_err_t nrfx_grtc_action_perform(nrfx_grtc_action_t action)
584 {
585 NRFX_ASSERT(m_cb.state == NRFX_DRV_STATE_INITIALIZED);
586 nrfx_err_t err_code = NRFX_SUCCESS;
587
588 if (is_syscounter_running())
589 {
590 err_code = NRFX_ERROR_INTERNAL;
591 NRFX_LOG_WARNING("Function: %s, error code: %s.",
592 __func__,
593 NRFX_LOG_ERROR_STRING_GET(err_code));
594
595 return err_code;
596 }
597
598 nrf_grtc_task_t task = (nrf_grtc_task_t)action;
599 nrfy_grtc_task_trigger(NRF_GRTC, task);
600
601 NRFX_LOG_INFO("GRTC %s action.", GRTC_ACTION_TO_STR(action));
602 return err_code;
603 }
604 #endif // NRFY_GRTC_HAS_EXTENDED
605
nrfx_grtc_uninit(void)606 void nrfx_grtc_uninit(void)
607 {
608 uint32_t ch_mask = allocated_channels_mask_get();
609
610 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
611
612 nrfy_grtc_int_disable(NRF_GRTC, GRTC_ALL_INT_MASK);
613
614 for (uint8_t chan = 0; ch_mask; chan++, ch_mask >>= 1)
615 {
616 if (is_channel_used(chan))
617 {
618 channel_used_unmark(chan);
619 if (is_channel_allocated(chan))
620 {
621 nrfy_grtc_sys_counter_compare_event_disable(NRF_GRTC, chan);
622 if (ch_mask & 0x1)
623 {
624 (void)nrfx_flag32_free(&m_cb.available_channels, chan);
625 }
626 }
627 }
628 }
629 nrfy_grtc_int_uninit(NRF_GRTC);
630
631 #if NRFY_GRTC_HAS_SYSCOUNTER_ARRAY
632 nrfy_grtc_sys_counter_active_set(NRF_GRTC, false);
633 #else
634 nrfy_grtc_sys_counter_active_state_request_set(NRF_GRTC, false);
635 #endif
636
637 #if NRFY_GRTC_HAS_EXTENDED && NRFX_IS_ENABLED(NRFX_GRTC_CONFIG_AUTOSTART)
638 nrfy_grtc_sys_counter_auto_mode_set(NRF_GRTC, false);
639 nrfy_grtc_sys_counter_set(NRF_GRTC, false);
640 nrf_grtc_task_trigger(NRF_GRTC, NRF_GRTC_TASK_STOP);
641 nrf_grtc_task_trigger(NRF_GRTC, NRF_GRTC_TASK_CLEAR);
642 #endif // NRFY_GRTC_HAS_EXTENDED && NRFX_IS_ENABLED(NRFX_GRTC_CONFIG_AUTOSTART)
643
644 m_cb.state = NRFX_DRV_STATE_UNINITIALIZED;
645 NRFX_LOG_INFO("GRTC uninitialized.");
646 }
647
nrfx_grtc_init_check(void)648 bool nrfx_grtc_init_check(void)
649 {
650 return (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
651 }
652
653 #if NRF_GRTC_HAS_RTCOUNTER
nrfx_grtc_rtcounter_cc_int_enable(bool sync)654 void nrfx_grtc_rtcounter_cc_int_enable(bool sync)
655 {
656 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
657 nrf_grtc_event_t event = sync ? NRF_GRTC_EVENT_RTCOMPARE : NRF_GRTC_EVENT_RTCOMPARESYNC;
658
659 nrfy_grtc_event_clear(NRF_GRTC, event);
660 nrfy_grtc_int_enable(NRF_GRTC, NRFY_EVENT_TO_INT_BITMASK(event));
661 NRFX_LOG_INFO("GRTC RTCOMPARE%s interrupt enabled.", sync ? "SYNC" : "");
662 }
663
nrfx_grtc_rtcounter_cc_int_disable(void)664 void nrfx_grtc_rtcounter_cc_int_disable(void)
665 {
666 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
667
668 nrfy_grtc_int_disable(NRF_GRTC, NRF_GRTC_INT_RTCOMPARE_MASK | NRF_GRTC_INT_RTCOMPARESYNC_MASK);
669 NRFX_LOG_INFO("GRTC RTCOMPARE/RTCOMPARESYNC interrupt disabled.");
670 }
671 #endif // NRF_GRTC_HAS_RTCOUNTER
672
673 #if NRFY_GRTC_HAS_EXTENDED && NRFY_GRTC_HAS_SYSCOUNTERVALID
nrfx_grtc_syscountervalid_int_enable(nrfx_grtc_syscountervalid_handler_t handler,void * p_context)674 void nrfx_grtc_syscountervalid_int_enable(nrfx_grtc_syscountervalid_handler_t handler,
675 void * p_context)
676 {
677 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
678
679 m_cb.syscountervalid_handler = handler;
680 m_cb.syscountervalid_context = p_context;
681 nrfy_grtc_int_enable(NRF_GRTC, NRFY_EVENT_TO_INT_BITMASK(NRF_GRTC_EVENT_SYSCOUNTERVALID));
682 NRFX_LOG_INFO("GRTC SYSCOUNTERVALID interrupt enabled.");
683 }
684
nrfx_grtc_syscountervalid_int_disable(void)685 void nrfx_grtc_syscountervalid_int_disable(void)
686 {
687 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
688
689 nrfy_grtc_int_disable(NRF_GRTC, NRF_GRTC_INT_SYSCOUNTERVALID_MASK);
690 NRFX_LOG_INFO("GRTC SYSCOUNTERVALID interrupt disabled.");
691 }
692 #endif // NRFY_GRTC_HAS_EXTENDED && NRFY_GRTC_HAS_SYSCOUNTERVALID
693
nrfx_grtc_syscounter_cc_disable(uint8_t channel)694 nrfx_err_t nrfx_grtc_syscounter_cc_disable(uint8_t channel)
695 {
696 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
697 uint32_t int_mask = NRF_GRTC_CHANNEL_INT_MASK(channel);
698 nrfx_err_t err_code = syscounter_check(channel);
699 if (err_code != NRFX_SUCCESS)
700 {
701 NRFX_LOG_WARNING("Function: %s, error code: %s.",
702 __func__,
703 NRFX_LOG_ERROR_STRING_GET(err_code));
704 return err_code;
705 }
706 if (!is_channel_used(channel))
707 {
708 err_code = NRFX_ERROR_INVALID_PARAM;
709 NRFX_LOG_WARNING("Function: %s, error code: %s.",
710 __func__,
711 NRFX_LOG_ERROR_STRING_GET(err_code));
712 return err_code;
713 }
714 channel_used_unmark(channel);
715
716 nrfy_grtc_sys_counter_compare_event_disable(NRF_GRTC, channel);
717
718 if (nrfy_grtc_int_enable_check(NRF_GRTC, int_mask))
719 {
720 nrfy_grtc_int_disable(NRF_GRTC, int_mask);
721 if (nrfy_grtc_sys_counter_compare_event_check(NRF_GRTC, channel))
722 {
723 nrfy_grtc_sys_counter_compare_event_clear(NRF_GRTC, channel);
724 err_code = NRFX_ERROR_TIMEOUT;
725 NRFX_LOG_WARNING("Function: %s, error code: %s.",
726 __func__,
727 NRFX_LOG_ERROR_STRING_GET(err_code));
728 return err_code;
729 }
730 }
731 NRFX_LOG_INFO("GRTC SYSCOUNTER compare for channel %u disabled.", (uint32_t)channel);
732 return err_code;
733 }
734
nrfx_grtc_syscounter_cc_absolute_set(nrfx_grtc_channel_t * p_chan_data,uint64_t val,bool enable_irq)735 nrfx_err_t nrfx_grtc_syscounter_cc_absolute_set(nrfx_grtc_channel_t * p_chan_data,
736 uint64_t val,
737 bool enable_irq)
738 {
739 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
740 NRFX_ASSERT(p_chan_data);
741 nrfx_err_t err_code = syscounter_check(p_chan_data->channel);
742 if (err_code != NRFX_SUCCESS)
743 {
744 NRFX_LOG_WARNING("Function: %s, error code: %s.",
745 __func__,
746 NRFX_LOG_ERROR_STRING_GET(err_code));
747 return err_code;
748 }
749
750 cc_channel_prepare(p_chan_data);
751 NRFX_CRITICAL_SECTION_ENTER();
752 nrfy_grtc_sys_counter_compare_event_clear(NRF_GRTC, p_chan_data->channel);
753 nrfy_grtc_sys_counter_cc_set(NRF_GRTC, p_chan_data->channel, val);
754 NRFX_CRITICAL_SECTION_EXIT();
755
756 if (enable_irq)
757 {
758 nrfy_grtc_int_enable(NRF_GRTC, GRTC_CHANNEL_TO_BITMASK(p_chan_data->channel));
759 }
760
761 NRFX_LOG_INFO("GRTC SYSCOUNTER absolute compare for channel %u set to %u.",
762 (uint32_t)p_chan_data->channel,
763 (uint32_t)nrfy_grtc_sys_counter_cc_get(NRF_GRTC, p_chan_data->channel));
764 return err_code;
765 }
766
nrfx_grtc_syscounter_cc_relative_set(nrfx_grtc_channel_t * p_chan_data,uint32_t val,bool enable_irq,nrfx_grtc_cc_relative_reference_t reference)767 nrfx_err_t nrfx_grtc_syscounter_cc_relative_set(nrfx_grtc_channel_t * p_chan_data,
768 uint32_t val,
769 bool enable_irq,
770 nrfx_grtc_cc_relative_reference_t reference)
771 {
772 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
773 NRFX_ASSERT(p_chan_data);
774 nrfx_err_t err_code = syscounter_check(p_chan_data->channel);
775 if (err_code != NRFX_SUCCESS)
776 {
777 NRFX_LOG_WARNING("Function: %s, error code: %s.",
778 __func__,
779 NRFX_LOG_ERROR_STRING_GET(err_code));
780 return err_code;
781 }
782
783 cc_channel_prepare(p_chan_data);
784 NRFX_CRITICAL_SECTION_ENTER();
785 nrfy_grtc_sys_counter_compare_event_clear(NRF_GRTC, p_chan_data->channel);
786 {
787 nrfy_grtc_sys_counter_cc_add_set(NRF_GRTC,
788 p_chan_data->channel,
789 val,
790 (nrf_grtc_cc_add_reference_t)reference);
791 }
792 NRFX_CRITICAL_SECTION_EXIT();
793
794 if (enable_irq)
795 {
796 nrfy_grtc_int_enable(NRF_GRTC, GRTC_CHANNEL_TO_BITMASK(p_chan_data->channel));
797 }
798
799 NRFX_LOG_INFO("GRTC SYSCOUNTER compare for channel %u set to %u.",
800 (uint32_t)p_chan_data->channel,
801 (uint32_t)val);
802 return err_code;
803 }
804
nrfx_grtc_syscounter_cc_int_disable(uint8_t channel)805 nrfx_err_t nrfx_grtc_syscounter_cc_int_disable(uint8_t channel)
806 {
807 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
808 nrfx_err_t err_code = syscounter_check(channel);
809 if (err_code != NRFX_SUCCESS)
810 {
811 NRFX_LOG_WARNING("Function: %s, error code: %s.",
812 __func__,
813 NRFX_LOG_ERROR_STRING_GET(err_code));
814 return err_code;
815 }
816 if (!is_channel_used(channel))
817 {
818 err_code = NRFX_ERROR_INVALID_PARAM;
819 NRFX_LOG_WARNING("Function: %s, error code: %s.",
820 __func__,
821 NRFX_LOG_ERROR_STRING_GET(err_code));
822 return err_code;
823 }
824
825 nrfy_grtc_int_disable(NRF_GRTC, NRF_GRTC_CHANNEL_INT_MASK(channel));
826 NRFX_LOG_INFO("GRTC SYSCOUNTER compare interrupt for channel %u disabled.", (uint32_t)channel);
827 return err_code;
828 }
829
nrfx_grtc_syscounter_cc_int_enable(uint8_t channel)830 nrfx_err_t nrfx_grtc_syscounter_cc_int_enable(uint8_t channel)
831 {
832 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
833 nrfx_err_t err_code = syscounter_check(channel);
834 if (err_code != NRFX_SUCCESS)
835 {
836 NRFX_LOG_WARNING("Function: %s, error code: %s.",
837 __func__,
838 NRFX_LOG_ERROR_STRING_GET(err_code));
839 return err_code;
840 }
841 channel_used_mark(channel);
842 nrfy_grtc_int_enable(NRF_GRTC, GRTC_CHANNEL_TO_BITMASK(channel));
843 NRFX_LOG_INFO("GRTC SYSCOUNTER compare interrupt for channel %u enabled.", (uint32_t)channel);
844 return err_code;
845 }
846
nrfx_grtc_syscounter_cc_int_enable_check(uint8_t channel)847 bool nrfx_grtc_syscounter_cc_int_enable_check(uint8_t channel)
848 {
849 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
850 NRFX_ASSERT(channel < NRF_GRTC_SYSCOUNTER_CC_COUNT);
851 return nrfy_grtc_int_enable_check(NRF_GRTC, GRTC_CHANNEL_TO_BITMASK(channel));
852 }
853
nrfx_grtc_syscounter_capture(uint8_t channel)854 nrfx_err_t nrfx_grtc_syscounter_capture(uint8_t channel)
855 {
856 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
857 nrfx_err_t err_code = syscounter_check(channel);
858 if (err_code != NRFX_SUCCESS)
859 {
860 NRFX_LOG_WARNING("Function: %s, error code: %s.",
861 __func__,
862 NRFX_LOG_ERROR_STRING_GET(err_code));
863 return err_code;
864 }
865 channel_used_mark(channel);
866 nrfy_grtc_task_trigger(NRF_GRTC, nrfy_grtc_sys_counter_capture_task_get(channel));
867
868 NRFX_LOG_INFO("GRTC SYSCOUNTER capture for channel %u triggered.", (uint32_t)channel);
869 return err_code;
870 }
871
nrfx_grtc_syscounter_cc_value_read(uint8_t channel,uint64_t * p_val)872 nrfx_err_t nrfx_grtc_syscounter_cc_value_read(uint8_t channel, uint64_t * p_val)
873 {
874 NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
875 NRFX_ASSERT(p_val);
876 nrfx_err_t err_code = syscounter_check(channel);
877 if (err_code != NRFX_SUCCESS)
878 {
879 NRFX_LOG_WARNING("Function: %s, error code: %s.",
880 __func__,
881 NRFX_LOG_ERROR_STRING_GET(err_code));
882 return err_code;
883 }
884 if (!is_channel_used(channel))
885 {
886 err_code = NRFX_ERROR_INVALID_PARAM;
887 NRFX_LOG_WARNING("Function: %s, error code: %s.",
888 __func__,
889 NRFX_LOG_ERROR_STRING_GET(err_code));
890 return err_code;
891 }
892
893 *p_val = nrfy_grtc_sys_counter_cc_get(NRF_GRTC, channel);
894
895 NRFX_LOG_INFO("GRTC SYSCOUNTER capture for channel %u read: %llu.", (uint32_t)channel, *p_val);
896 return err_code;
897 }
898
grtc_irq_handler(void)899 static void grtc_irq_handler(void)
900 {
901 uint32_t evt_to_process = GRTC_CHANNEL_MASK_TO_INT_MASK(allocated_channels_mask_get() &
902 used_channels_mask_get());
903 #if NRF_GRTC_HAS_RTCOUNTER
904 evt_to_process |= (GRTC_NON_SYSCOMPARE_INT_MASK & ~NRF_GRTC_INT_SYSCOUNTERVALID_MASK);
905 #endif
906 uint32_t event_mask = nrfy_grtc_events_process(NRF_GRTC, evt_to_process);
907 uint32_t active_int_mask = nrfy_grtc_int_enable_check(NRF_GRTC, event_mask);
908 nrf_grtc_event_t event;
909
910 for (uint32_t i = 0; i < NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS; i++)
911 {
912 uint8_t channel = m_cb.channel_data[i].channel;
913
914 event = nrfy_grtc_sys_counter_compare_event_get(channel);
915 if (active_int_mask & NRFY_EVENT_TO_INT_BITMASK(event))
916 {
917 NRFX_LOG_INFO("Event: NRF_GRTC_EVENT_COMPARE_%d.", channel);
918 if (m_cb.channel_data[i].handler)
919 {
920 m_cb.channel_data[i].handler((int32_t)channel,
921 nrfy_grtc_sys_counter_cc_get(NRF_GRTC, channel),
922 m_cb.channel_data[i].p_context);
923 }
924 }
925 }
926 #if NRF_GRTC_HAS_RTCOUNTER
927 if (active_int_mask & NRF_GRTC_INT_RTCOMPARE_MASK)
928 {
929 NRFX_LOG_INFO("Event: NRF_GRTC_EVENT_RTCOMPARE.");
930 nrfx_grtc_channel_t const * p_channel = &m_cb.channel_data[GRTC_RTCOUNTER_CC_HANDLER_IDX];
931 if (p_channel->handler)
932 {
933 p_channel->handler((int32_t)GRTC_RTCOUNTER_COMPARE_CHANNEL,
934 nrfy_grtc_rt_counter_cc_get(NRF_GRTC),
935 p_channel->p_context);
936 }
937 }
938
939 if (active_int_mask & NRF_GRTC_INT_RTCOMPARESYNC_MASK)
940 {
941 NRFX_LOG_INFO("Event: NRF_GRTC_EVENT_RTCOMPARESYNC.");
942 if (m_cb.rtcomparesync_handler)
943 {
944 m_cb.rtcomparesync_handler(m_cb.rtcomparesync_context);
945 }
946 }
947 #endif // NRF_GRTC_HAS_RTCOUNTER
948 #if NRFY_GRTC_HAS_EXTENDED && NRFY_GRTC_HAS_SYSCOUNTERVALID
949 /* The SYSCOUNTERVALID bit is automatically cleared when GRTC goes into sleep state and set
950 * when returning from this state. It can't be cleared inside the ISR procedure because we rely
951 * on it during SYSCOUNTER value reading procedure. */
952 if (nrfy_grtc_event_check(NRF_GRTC, NRF_GRTC_EVENT_SYSCOUNTERVALID) &&
953 nrfy_grtc_int_enable_check(NRF_GRTC, NRF_GRTC_INT_SYSCOUNTERVALID_MASK))
954 {
955 NRFX_LOG_INFO("Event: NRF_GRTC_EVENT_SYSCOUNTERVALID.");
956 if (m_cb.syscountervalid_handler)
957 {
958 m_cb.syscountervalid_handler(m_cb.syscountervalid_context);
959 }
960 }
961 #endif // NRFY_GRTC_HAS_EXTENDED && NRFY_GRTC_HAS_SYSCOUNTERVALID
962 }
963
nrfx_grtc_irq_handler(void)964 void nrfx_grtc_irq_handler(void)
965 {
966 grtc_irq_handler();
967 }
968
969 #endif // NRFX_CHECK(NRFX_GRTC_ENABLED)
970