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