1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_GRTC_TIMER_H
8 #define ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_GRTC_TIMER_H
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 #include <zephyr/sys_clock.h>
15 
16 /** @brief GRTC timer compare event handler.
17  *
18  * Called from GRTC ISR context when processing a compare event.
19  *
20  * @param id Compare channel ID.
21  *
22  * @param expire_time An actual absolute expiration time set for a compare
23  *		      channel. It can differ from the requested target time
24  *		      and the difference can be used to determine whether the
25  *		      time set was delayed.
26  *
27  * @param user_data Pointer to a user context data.
28  */
29 typedef void (*z_nrf_grtc_timer_compare_handler_t)(int32_t id, uint64_t expire_time,
30 						   void *user_data);
31 
32 /** @brief Allocate GRTC capture/compare channel.
33  *
34  * @retval >=0 Non-negative indicates allocated channel ID.
35  * @retval -ENOMEM if channel cannot be allocated.
36  */
37 int32_t z_nrf_grtc_timer_chan_alloc(void);
38 
39 /** @brief Free GRTC capture/compare channel.
40  *
41  * @param chan Previously allocated channel ID.
42  */
43 void z_nrf_grtc_timer_chan_free(int32_t chan);
44 
45 /** @brief Read current absolute time.
46  *
47  * @return Current absolute time.
48  */
49 uint64_t z_nrf_grtc_timer_read(void);
50 
51 /** @brief Check COMPARE event state.
52  *
53  * @param chan Channel ID.
54  *
55  * @retval true  The event has been generated.
56  * @retval false The event has not been generated.
57  */
58 bool z_nrf_grtc_timer_compare_evt_check(int32_t chan);
59 
60 /** @brief Get COMPARE event register address.
61  *
62  * Address can be used for DPPIC.
63  *
64  * @param chan Channel ID.
65  *
66  * @return Register address.
67  */
68 uint32_t z_nrf_grtc_timer_compare_evt_address_get(int32_t chan);
69 
70 /** @brief Get CAPTURE task register address.
71  *
72  * Address can be used for DPPIC.
73  *
74  * @param chan Channel ID.
75  *
76  * @return Register address.
77  */
78 uint32_t z_nrf_grtc_timer_capture_task_address_get(int32_t chan);
79 
80 /** @brief Safely disable compare event interrupt.
81  *
82  * Function returns key indicating whether interrupt was already disabled.
83  *
84  * @param chan Channel ID.
85  *
86  * @return key passed to z_nrf_grtc_timer_compare_int_unlock().
87  */
88 bool z_nrf_grtc_timer_compare_int_lock(int32_t chan);
89 
90 /** @brief Safely enable compare event interrupt.
91  *
92  * Event interrupt is conditionally enabled based on @p key.
93  *
94  * @param chan Channel ID.
95  *
96  * @param key Key returned by z_nrf_grtc_timer_compare_int_lock().
97  */
98 void z_nrf_grtc_timer_compare_int_unlock(int32_t chan, bool key);
99 
100 /** @brief Read compare register value.
101  *
102  * @param chan Channel ID.
103  *
104  * @param val Pointer to store the value.
105  *
106  * @retval 0 if the compare register was read successfully.
107  * @retval -EAGAIN if compare for given channel is not set.
108  * @retval -EPERM if either channel is unavailable or SYSCOUNTER is not running.
109  */
110 int z_nrf_grtc_timer_compare_read(int32_t chan, uint64_t *val);
111 
112 /** @brief  Set compare channel to given value.
113  *
114  * @param chan Channel ID.
115  *
116  * @param target_time Absolute target time in GRTC ticks.
117  *
118  * @param handler User function called in the context of the GRTC interrupt.
119  *
120  * @param user_data Data passed to the handler.
121  *
122  * @retval 0 if the compare channel was set successfully.
123  * @retval -EPERM if either channel is unavailable or SYSCOUNTER is not running.
124  */
125 int z_nrf_grtc_timer_set(int32_t chan, uint64_t target_time,
126 			 z_nrf_grtc_timer_compare_handler_t handler, void *user_data);
127 
128 /** @brief Abort a timer requested with z_nrf_grtc_timer_set().
129  *
130  * If an abort operation is performed too late it is still possible for an event
131  * to fire. The user can detect a spurious event by comparing absolute time
132  * provided in callback and a result of z_nrf_grtc_timer_read(). During this
133  * operation interrupt from that compare channel is disabled. Other interrupts
134  * are not locked during this operation.
135  *
136  * @param chan Channel ID between 1 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT.
137  */
138 void z_nrf_grtc_timer_abort(int32_t chan);
139 
140 /** @brief Convert system clock time to GRTC ticks.
141  *
142  * @p t can be absolute or relative.
143  *
144  * @retval >=0 Positive value represents @p t in GRTC tick value.
145  * @retval -EINVAL if @p t is out of range.
146  */
147 uint64_t z_nrf_grtc_timer_get_ticks(k_timeout_t t);
148 
149 /** @brief Prepare channel for timestamp capture.
150  *
151  * Use z_nrf_grtc_timer_capture_task_address_get() to determine the register
152  * address that is used to trigger capture.
153  *
154  * @note Capture and compare are mutually exclusive features - they cannot be
155  *       used simultaneously on the same GRTC channel.
156  *
157  * @param chan Channel ID.
158  *
159  * @retval 0 if the channel was successfully prepared.
160  * @retval -EPERM if either channel is unavailable or SYSCOUNTER is not running.
161  */
162 int z_nrf_grtc_timer_capture_prepare(int32_t chan);
163 
164 /** @brief Read timestamp value captured on the channel.
165  *
166  * The @p chan must be prepared using z_nrf_grtc_timer_capture_prepare().
167  *
168  * @param chan Channel ID.
169  *
170  * @param captured_time Pointer to store the value.
171  *
172  * @retval 0 if the timestamp was successfully caught and read.
173  * @retval -EBUSY if capturing has not been triggered.
174  * @retval -EPERM if either channel is unavailable or SYSCOUNTER is not running.
175  */
176 int z_nrf_grtc_timer_capture_read(int32_t chan, uint64_t *captured_time);
177 
178 /** @brief Prepare GRTC as a source of wake up event and set the wake up time.
179  *
180  * @note Calling this function should be immediately followed by low-power mode enter
181  *		(if it executed successfully).
182  *
183  * @param wake_time_us Relative wake up time in microseconds.
184  *
185  * @retval 0 if wake up time was successfully set.
186  * @retval -EPERM if the SYSCOUNTER is not running.
187  * @retval -ENOMEM if no available GRTC channels were found.
188  * @retval -EINVAL if @p wake_time_us is too low.
189  */
190 int z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us);
191 
192 /**
193  * @brief       Initialize the GRTC clock timer driver from an application-
194  *              defined function.
195  *
196  * @retval 0 on success.
197  * @retval -errno Negative error code on failure.
198  */
199 int nrf_grtc_timer_clock_driver_init(void);
200 
201 #ifdef __cplusplus
202 }
203 #endif
204 
205 #endif /* ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_GRTC_TIMER_H */
206