1 /*
2 * Copyright (c) 2015 - 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 #ifndef NRFX_TIMER_H__
35 #define NRFX_TIMER_H__
36
37 #include <nrfx.h>
38 #include <haly/nrfy_timer.h>
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 /**
45 * @defgroup nrfx_timer Timer driver
46 * @{
47 * @ingroup nrf_timer
48 * @brief TIMER peripheral driver.
49 */
50
51 /**
52 * @brief Timer driver instance data structure.
53 */
54 typedef struct
55 {
56 NRF_TIMER_Type * p_reg; ///< Pointer to the structure with TIMER peripheral instance registers.
57 uint8_t instance_id; ///< Index of the driver instance. For internal use only.
58 uint8_t cc_channel_count; ///< Number of capture/compare channels.
59 } nrfx_timer_t;
60
61 /** @brief Macro for creating a timer driver instance. */
62 #define NRFX_TIMER_INSTANCE(id) \
63 { \
64 .p_reg = NRFX_CONCAT(NRF_, TIMER, id), \
65 .instance_id = NRFX_CONCAT(NRFX_TIMER, id, _INST_IDX), \
66 .cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(id), \
67 }
68
69 #ifndef __NRFX_DOXYGEN__
70 enum {
71 /* List all enabled driver instances (in the format NRFX_\<instance_name\>_INST_IDX). */
72 NRFX_INSTANCE_ENUM_LIST(TIMER)
73 NRFX_TIMER_ENABLED_COUNT
74 };
75 #endif
76
77 /** @brief The configuration structure of the timer driver instance. */
78 typedef struct
79 {
80 uint32_t frequency; ///< Frequency value.
81 nrf_timer_mode_t mode; ///< Mode of operation.
82 nrf_timer_bit_width_t bit_width; ///< Bit width.
83 uint8_t interrupt_priority; ///< Interrupt priority.
84 void * p_context; ///< Context passed to interrupt handler.
85 } nrfx_timer_config_t;
86
87 /**
88 * @brief TIMER driver default configuration.
89 *
90 * This configuration sets up TIMER with the following options:
91 * - works as timer
92 * - width: 16 bit
93 *
94 * @param[in] _frequency Timer frequency in Hz.
95 */
96 #define NRFX_TIMER_DEFAULT_CONFIG(_frequency) \
97 { \
98 .frequency = _frequency, \
99 .mode = NRF_TIMER_MODE_TIMER, \
100 .bit_width = NRF_TIMER_BIT_WIDTH_16, \
101 .interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY, \
102 .p_context = NULL \
103 }
104
105 /**
106 * @brief Macro for checking whether specified frequency can be achived for given timer instance.
107 *
108 * @note Macro is using compile time assertion.
109 *
110 * @param[in] id Index of the specified timer instance.
111 * @param[in] frequency Desired frequency value in Hz.
112 */
113 #define NRFX_TIMER_FREQUENCY_STATIC_CHECK(id, frequency) \
114 NRF_TIMER_FREQUENCY_STATIC_CHECK(NRF_TIMER_INST_GET(id), frequency)
115
116 /**
117 * @brief Macro for getting base frequency value in Hz for a given timer instance.
118 *
119 * @param[in] p_instance Pointer to the driver instance structure.
120 */
121 #define NRFX_TIMER_BASE_FREQUENCY_GET(p_instance) \
122 NRF_TIMER_BASE_FREQUENCY_GET((p_instance)->p_reg)
123
124 /**
125 * @brief Timer driver event handler type.
126 *
127 * @param[in] event_type Timer event.
128 * @param[in] p_context General purpose parameter set during initialization of
129 * the timer. This parameter can be used to pass
130 * additional information to the handler function, for
131 * example, the timer ID.
132 */
133 typedef void (* nrfx_timer_event_handler_t)(nrf_timer_event_t event_type, void * p_context);
134
135 /**
136 * @brief Function for initializing the timer.
137 *
138 * @param[in] p_instance Pointer to the driver instance structure.
139 * @param[in] p_config Pointer to the structure with the initial configuration.
140 * @param[in] timer_event_handler Event handler provided by the user. Can be NULL.
141 *
142 * @retval NRFX_SUCCESS Initialization was successful.
143 * @retval NRFX_ERROR_INVALID_PARAM Specified frequency is not supported by the TIMER instance.
144 * @retval NRFX_ERROR_ALREADY The driver is already initialized.
145 * @retval NRFX_ERROR_INVALID_STATE The driver is already initialized.
146 * Deprecated - use @ref NRFX_ERROR_ALREADY instead.
147 */
148 nrfx_err_t nrfx_timer_init(nrfx_timer_t const * p_instance,
149 nrfx_timer_config_t const * p_config,
150 nrfx_timer_event_handler_t timer_event_handler);
151
152 /**
153 * @brief Function for reconfiguring the timer.
154 *
155 * @param[in] p_instance Pointer to the driver instance structure.
156 * @param[in] p_config Pointer to the structure with the configuration.
157 *
158 * @retval NRFX_SUCCESS Reconfiguration was successful.
159 * @retval NRFX_ERROR_INVALID_PARAM Specified frequency is not supported by the TIMER instance.
160 * @retval NRFX_ERROR_INVALID_STATE The driver is uninitialized.
161 * @retval NRFX_ERROR_BUSY The driver is enabled and cannot be reconfigured.
162 */
163 nrfx_err_t nrfx_timer_reconfigure(nrfx_timer_t const * p_instance,
164 nrfx_timer_config_t const * p_config);
165
166 /**
167 * @brief Function for uninitializing the timer.
168 *
169 * @param[in] p_instance Pointer to the driver instance structure.
170 */
171 void nrfx_timer_uninit(nrfx_timer_t const * p_instance);
172
173 /**
174 * @brief Function for checking if the TIMER driver instance is initialized.
175 *
176 * @param[in] p_instance Pointer to the driver instance structure.
177 *
178 * @retval true Instance is already initialized.
179 * @retval false Instance is not initialized.
180 */
181 bool nrfx_timer_init_check(nrfx_timer_t const * p_instance);
182
183 /**
184 * @brief Function for turning on the timer.
185 *
186 * @param[in] p_instance Pointer to the driver instance structure.
187 */
188 void nrfx_timer_enable(nrfx_timer_t const * p_instance);
189
190 /**
191 * @brief Function for turning off the timer.
192 *
193 * The timer will allow to enter the lowest possible SYSTEM_ON state
194 * only after this function is called.
195 *
196 * @param[in] p_instance Pointer to the driver instance structure.
197 */
198 void nrfx_timer_disable(nrfx_timer_t const * p_instance);
199
200 /**
201 * @brief Function for checking the timer state.
202 *
203 * @param[in] p_instance Pointer to the driver instance structure.
204 *
205 * @retval true Timer is enabled.
206 * @retval false Timer is not enabled.
207 */
208 bool nrfx_timer_is_enabled(nrfx_timer_t const * p_instance);
209
210 /**
211 * @brief Function for pausing the timer.
212 *
213 * @param[in] p_instance Pointer to the driver instance structure.
214 */
215 void nrfx_timer_pause(nrfx_timer_t const * p_instance);
216
217 /**
218 * @brief Function for resuming the timer.
219 *
220 * @param[in] p_instance Pointer to the driver instance structure.
221 */
222 void nrfx_timer_resume(nrfx_timer_t const * p_instance);
223
224 /**
225 * @brief Function for clearing the timer.
226 *
227 * @param[in] p_instance Pointer to the driver instance structure.
228 */
229 void nrfx_timer_clear(nrfx_timer_t const * p_instance);
230
231 /**
232 * @brief Function for incrementing the timer.
233 *
234 * @param[in] p_instance Pointer to the driver instance structure.
235 */
236 void nrfx_timer_increment(nrfx_timer_t const * p_instance);
237
238 /**
239 * @brief Function for returning the address of the specified timer task.
240 *
241 * @param[in] p_instance Pointer to the driver instance structure.
242 * @param[in] timer_task Timer task.
243 *
244 * @return Task address.
245 */
246 NRFX_STATIC_INLINE uint32_t nrfx_timer_task_address_get(nrfx_timer_t const * p_instance,
247 nrf_timer_task_t timer_task);
248
249 /**
250 * @brief Function for returning the address of the specified timer capture task.
251 *
252 * @param[in] p_instance Pointer to the driver instance structure.
253 * @param[in] channel Capture channel number.
254 *
255 * @return Task address.
256 */
257 NRFX_STATIC_INLINE uint32_t nrfx_timer_capture_task_address_get(nrfx_timer_t const * p_instance,
258 uint32_t channel);
259
260 /**
261 * @brief Function for returning the address of the specified timer event.
262 *
263 * @param[in] p_instance Pointer to the driver instance structure.
264 * @param[in] timer_event Timer event.
265 *
266 * @return Event address.
267 */
268 NRFX_STATIC_INLINE uint32_t nrfx_timer_event_address_get(nrfx_timer_t const * p_instance,
269 nrf_timer_event_t timer_event);
270
271 /**
272 * @brief Function for returning the address of the specified timer compare event.
273 *
274 * @param[in] p_instance Pointer to the driver instance structure.
275 * @param[in] channel Compare channel number.
276 *
277 * @return Event address.
278 */
279 NRFX_STATIC_INLINE uint32_t nrfx_timer_compare_event_address_get(nrfx_timer_t const * p_instance,
280 uint32_t channel);
281
282 /**
283 * @brief Function for capturing the timer value.
284 *
285 * @param[in] p_instance Pointer to the driver instance structure.
286 * @param[in] cc_channel Capture channel number.
287 *
288 * @return Captured value.
289 */
290 uint32_t nrfx_timer_capture(nrfx_timer_t const * p_instance, nrf_timer_cc_channel_t cc_channel);
291
292 /**
293 * @brief Function for returning the capture value from the specified channel.
294 *
295 * Use this function to read channel values when PPI is used for capturing.
296 *
297 * @param[in] p_instance Pointer to the driver instance structure.
298 * @param[in] cc_channel Capture channel number.
299 *
300 * @return Captured value.
301 */
302 NRFX_STATIC_INLINE uint32_t nrfx_timer_capture_get(nrfx_timer_t const * p_instance,
303 nrf_timer_cc_channel_t cc_channel);
304
305 /**
306 * @brief Function for setting the timer channel in compare mode.
307 *
308 * @param[in] p_instance Pointer to the driver instance structure.
309 * @param[in] cc_channel Compare channel number.
310 * @param[in] cc_value Compare value.
311 * @param[in] enable_int Enable or disable the interrupt for the compare channel.
312 */
313 void nrfx_timer_compare(nrfx_timer_t const * p_instance,
314 nrf_timer_cc_channel_t cc_channel,
315 uint32_t cc_value,
316 bool enable_int);
317
318 /**
319 * @brief Function for setting the timer channel in the extended compare mode.
320 *
321 * @param[in] p_instance Pointer to the driver instance structure.
322 * @param[in] cc_channel Compare channel number.
323 * @param[in] cc_value Compare value.
324 * @param[in] timer_short_mask Shortcut between the compare event on the channel
325 * and the timer task (STOP or CLEAR).
326 * @param[in] enable_int Enable or disable the interrupt for the compare channel.
327 */
328 void nrfx_timer_extended_compare(nrfx_timer_t const * p_instance,
329 nrf_timer_cc_channel_t cc_channel,
330 uint32_t cc_value,
331 nrf_timer_short_mask_t timer_short_mask,
332 bool enable_int);
333
334 /**
335 * @brief Function for converting time in microseconds to timer ticks.
336 *
337 * @param[in] p_instance Pointer to the driver instance structure.
338 * @param[in] time_us Time in microseconds.
339 *
340 * @return Number of ticks.
341 */
342 uint32_t nrfx_timer_us_to_ticks(nrfx_timer_t const * p_instance, uint32_t time_us);
343
344 /**
345 * @brief Function for converting time in milliseconds to timer ticks.
346 *
347 * @param[in] p_instance Pointer to the driver instance structure.
348 * @param[in] time_ms Time in milliseconds.
349 *
350 * @return Number of ticks.
351 */
352 uint32_t nrfx_timer_ms_to_ticks(nrfx_timer_t const * p_instance, uint32_t time_ms);
353
354 /**
355 * @brief Function for enabling timer compare interrupt.
356 *
357 * @param[in] p_instance Pointer to the driver instance structure.
358 * @param[in] channel Compare channel.
359 */
360 void nrfx_timer_compare_int_enable(nrfx_timer_t const * p_instance, uint32_t channel);
361
362 /**
363 * @brief Function for disabling timer compare interrupt.
364 *
365 * @param[in] p_instance Pointer to the driver instance structure.
366 * @param[in] channel Compare channel.
367 */
368 void nrfx_timer_compare_int_disable(nrfx_timer_t const * p_instance, uint32_t channel);
369
370 #ifndef NRFX_DECLARE_ONLY
nrfx_timer_task_address_get(nrfx_timer_t const * p_instance,nrf_timer_task_t timer_task)371 NRFX_STATIC_INLINE uint32_t nrfx_timer_task_address_get(nrfx_timer_t const * p_instance,
372 nrf_timer_task_t timer_task)
373 {
374 return nrfy_timer_task_address_get(p_instance->p_reg, timer_task);
375 }
376
nrfx_timer_capture_task_address_get(nrfx_timer_t const * p_instance,uint32_t channel)377 NRFX_STATIC_INLINE uint32_t nrfx_timer_capture_task_address_get(nrfx_timer_t const * p_instance,
378 uint32_t channel)
379 {
380 NRFX_ASSERT(channel < p_instance->cc_channel_count);
381 return nrfy_timer_task_address_get(p_instance->p_reg,
382 nrfy_timer_capture_task_get((uint8_t)channel));
383 }
384
nrfx_timer_event_address_get(nrfx_timer_t const * p_instance,nrf_timer_event_t timer_event)385 NRFX_STATIC_INLINE uint32_t nrfx_timer_event_address_get(nrfx_timer_t const * p_instance,
386 nrf_timer_event_t timer_event)
387 {
388 return nrfy_timer_event_address_get(p_instance->p_reg, timer_event);
389 }
390
nrfx_timer_compare_event_address_get(nrfx_timer_t const * p_instance,uint32_t channel)391 NRFX_STATIC_INLINE uint32_t nrfx_timer_compare_event_address_get(nrfx_timer_t const * p_instance,
392 uint32_t channel)
393 {
394 NRFX_ASSERT(channel < p_instance->cc_channel_count);
395 return nrfy_timer_event_address_get(p_instance->p_reg,
396 nrfy_timer_compare_event_get((uint8_t)channel));
397 }
398
nrfx_timer_capture_get(nrfx_timer_t const * p_instance,nrf_timer_cc_channel_t cc_channel)399 NRFX_STATIC_INLINE uint32_t nrfx_timer_capture_get(nrfx_timer_t const * p_instance,
400 nrf_timer_cc_channel_t cc_channel)
401 {
402 return nrfy_timer_cc_get(p_instance->p_reg, cc_channel);
403 }
404
405 #endif // NRFX_DECLARE_ONLY
406
407 /**
408 * @brief Macro returning TIMER interrupt handler.
409 *
410 * param[in] idx TIMER index.
411 *
412 * @return Interrupt handler.
413 */
414 #define NRFX_TIMER_INST_HANDLER_GET(idx) NRFX_CONCAT_3(nrfx_timer_, idx, _irq_handler)
415
416 /** @} */
417
418 /*
419 * Declare interrupt handlers for all enabled driver instances in the following format:
420 * nrfx_\<periph_name\>_\<idx\>_irq_handler (for example, nrfx_timer_0_irq_handler).
421 *
422 * A specific interrupt handler for the driver instance can be retrieved by using
423 * the NRFX_TIMER_INST_HANDLER_GET macro.
424 *
425 * Here is a sample of using the NRFX_TIMER_INST_HANDLER_GET macro to map an interrupt handler
426 * in a Zephyr application:
427 *
428 * IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_TIMER_INST_GET(\<instance_index\>)), \<priority\>,
429 * NRFX_TIMER_INST_HANDLER_GET(\<instance_index\>), 0, 0);
430 */
431 NRFX_INSTANCE_IRQ_HANDLERS_DECLARE(TIMER, timer)
432
433 #ifdef __cplusplus
434 }
435 #endif
436
437 #endif // NRFX_TIMER_H__
438
439