1 /*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef _HARDWARE_TIMER_H
8 #define _HARDWARE_TIMER_H
9
10 #include "pico.h"
11 #include "hardware/structs/timer.h"
12 #include "hardware/regs/intctrl.h"
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 /** \file hardware/timer.h
19 * \defgroup hardware_timer hardware_timer
20 *
21 * \brief Low-level hardware timer API
22 *
23 * This API provides medium level access to the timer HW.
24 * See also \ref pico_time which provides higher levels functionality using the hardware timer.
25 *
26 * The timer peripheral on RP-series microcontrollers supports the following features:
27 * - RP2040 single 64-bit counter, incrementing once per microsecond
28 * - RP2350 two 64-bit counters, ticks generated from the tick block
29 * - Latching two-stage read of counter, for race-free read over 32 bit bus
30 * - Four alarms: match on the lower 32 bits of counter, IRQ on match.
31 *
32 * \if rp2040_specific
33 * On RP2040, by default the timer uses a one microsecond reference that is generated in the Watchdog (see RP2040 Datasheet Section 4.8.2) which is derived
34 * from the clk_ref.
35 * \endif
36 *
37 * \if rp2350_specific
38 * On RP2350, by default the timer uses a one microsecond reference that is generated by the tick block (see RP2350 Datasheet Section 8.5)
39 * \endif
40 *
41 * The timer has 4 alarms, and can output a separate interrupt for each alarm. The alarms match on the lower 32 bits of the 64
42 * bit counter which means they can be fired a maximum of 2^32 microseconds into the future. This is equivalent to:
43 * - 2^32 ÷ 10^6: ~4295 seconds
44 * - 4295 ÷ 60: ~72 minutes
45 *
46 * The timer is expected to be used for short sleeps, if you want a longer alarm see the \ref hardware_rtc functions.
47 *
48 * \subsection timer_example Example
49 * \addtogroup hardware_timer
50 *
51 * \include hello_timer.c
52 *
53 * \see pico_time
54 */
55
56 // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_TIMER, Enable/disable assertions in the hardware_timer module, type=bool, default=0, group=hardware_timer
57 #ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_TIMER
58 #ifdef PARAM_ASSERTIONS_ENABLED_TIMER // backwards compatibility with SDK < 2.0.0
59 #define PARAM_ASSERTIONS_ENABLED_HARDWARE_TIMER PARAM_ASSERTIONS_ENABLED_TIMER
60 #else
61 #define PARAM_ASSERTIONS_ENABLED_HARDWARE_TIMER 0
62 #endif
63 #endif
64
65 /**
66 * \def TIMER_NUM(timer)
67 * \ingroup hardware_timer
68 * \hideinitializer
69 * \brief Returns the timer number for a timer instance
70 *
71 * Note this macro is intended to resolve at compile time, and does no parameter checking
72 */
73 #ifndef TIMER_NUM
74 #if NUM_GENERIC_TIMERS == 1
75 #define TIMER_NUM(timer) ({ (void) (timer); 0; })
76 #elif NUM_GENERIC_TIMERS == 2
77 #define TIMER_NUM(timer) ((timer) == timer1_hw)
78 #endif
79 #endif
80
81 /**
82 * \def TIMER_INSTANCE(timer_num)
83 * \ingroup hardware_timer
84 * \hideinitializer
85 * \brief Returns the timer instance with the given timer number
86 *
87 * Note this macro is intended to resolve at compile time, and does no parameter checking
88 */
89 #ifndef TIMER_INSTANCE
90 #if NUM_GENERIC_TIMERS == 1
91 #define TIMER_INSTANCE(num) timer_hw
92 #elif NUM_GENERIC_TIMERS == 2
93 #define TIMER_INSTANCE(num) ((num) ? timer1_hw : timer0_hw)
94 #endif
95 #endif
96
97 /**
98 * \def TIMER_ALARM_IRQ_NUM(timer,alarm_num)
99 * \ingroup hardware_timer
100 * \hideinitializer
101 * \brief Returns the \ref irq_num_t for the alarm interrupt from the given alarm on the given timer instance
102 *
103 * Note this macro is intended to resolve at compile time, and does no parameter checking
104 */
105 #ifndef TIMER_ALARM_IRQ_NUM
106 #if NUM_GENERIC_TIMERS == 1
107 static_assert(TIMER_IRQ_3 == TIMER_IRQ_0 + 3, "");
108 #define TIMER_ALARM_IRQ_NUM(timer, alarm_num) ({ ((void)(timer)); (TIMER_IRQ_0 + (alarm_num)); })
109 #else
110 static_assert(TIMER1_IRQ_3 == TIMER0_IRQ_0 + 7, "");
111 #define TIMER_ALARM_IRQ_NUM(timer, alarm_num) (TIMER0_IRQ_0 + TIMER_NUM(timer) * NUM_ALARMS + (alarm_num))
112 #endif
113 #endif
114
115 /**
116 * \def TIMER_ALARM_NUM_FROM_IRQ(irq_num)
117 * \ingroup hardware_timer
118 * \hideinitializer
119 * \brief Returns the alarm number from an \ref irq_num_t. See \ref TIMER_INSTANCE_NUM_FROM_IRQ to get the timer instance number
120 *
121 * Note this macro is intended to resolve at compile time, and does no parameter checking
122 */
123 #ifndef TIMER_ALARM_NUM_FROM_IRQ
124 #if NUM_GENERIC_TIMERS == 1
125 static_assert(TIMER_IRQ_3 == TIMER_IRQ_0 + 3, "");
126 #define TIMER_ALARM_NUM_FROM_IRQ(irq_num) (((irq_num) - TIMER_IRQ_0) & 3u)
127 #else
128 static_assert(TIMER1_IRQ_3 == TIMER0_IRQ_0 + 7, "");
129 #define TIMER_ALARM_NUM_FROM_IRQ(irq_num) (((irq_num) - TIMER0_IRQ_0) & 3u)
130 #endif
131 #endif
132
133 /**
134 * \def TIMER_NUM_FROM_IRQ(irq_num)
135 * \ingroup hardware_timer
136 * \hideinitializer
137 * \brief Returns the alarm number from an \ref irq_num_t. See \ref TIMER_INSTANCE_NUM_FROM_IRQ to get the alarm number
138 *
139 * Note this macro is intended to resolve at compile time, and does no parameter checking
140 */
141 #ifndef TIMER_NUM_FROM_IRQ
142 #if NUM_GENERIC_TIMERS == 1
143 static_assert(TIMER_IRQ_3 == TIMER_IRQ_0 + 3, "");
144 #define TIMER_NUM_FROM_IRQ(irq_num) (((irq_num) - TIMER_IRQ_0) >> 2)
145 #else
146 static_assert(TIMER1_IRQ_3 == TIMER0_IRQ_0 + 7, "");
147 #define TIMER_NUM_FROM_IRQ(irq_num) (((irq_num) - TIMER0_IRQ_0) >> 2)
148 #endif
149 #endif
150
151 // PICO_CONFIG: PICO_DEFAULT_TIMER, Timer instance number to use for RP2040-period hardware_timer APIs that assumed a single timer instance, min=0, max=1, default=0, group=hardware_timer
152
153 /**
154 * \ingroup hardware_timer
155 * \brief The default timer instance number of the timer instance used for APIs that don't take an explicit timer instance
156 * \if rp2040_specific
157 * On RP2040 this must be 0 as there is only one timer instance
158 * \endif
159 * \if rp2350_specific
160 * On RP2040 this may be set to 0 or 1
161 * \endif
162 */
163 #ifndef PICO_DEFAULT_TIMER
164 #define PICO_DEFAULT_TIMER 0
165 #endif
166
167 /**
168 * \def PICO_DEFAULT_TIMER_INSTANCE()
169 * \ingroup hardware_timer
170 * \hideinitializer
171 * \brief Returns the default timer instance on the platform based on the setting of PICO_DEFAULT_TIMER
172 *
173 * Note this macro is intended to resolve at compile time, and does no parameter checking
174 */
175 #ifndef PICO_DEFAULT_TIMER_INSTANCE
176 #if NUM_GENERIC_TIMERS == 1
177 #if PICO_DEFAULT_TIMER
178 #error Setting PICO_DEFAULT_TIMER to non zero is meaningless as there is only one TIMER instance on this platform
179 #endif
180 #define PICO_DEFAULT_TIMER_INSTANCE() timer_hw
181 #else
182 #define PICO_DEFAULT_TIMER_INSTANCE() (__CONCAT(__CONCAT(timer,PICO_DEFAULT_TIMER), _hw))
183 // also define timer_hw for backwards compatibility (just accesses the default instance)
184 #define timer_hw PICO_DEFAULT_TIMER_INSTANCE()
185 #endif
186 #endif
187
check_hardware_alarm_num_param(__unused uint alarm_num)188 static inline void check_hardware_alarm_num_param(__unused uint alarm_num) {
189 invalid_params_if(HARDWARE_TIMER, alarm_num >= NUM_ALARMS);
190 }
191
192 /*! \brief Return a 32 bit timestamp value in microseconds for a given timer instance
193 * \ingroup hardware_timer
194 *
195 * Returns the low 32 bits of the hardware timer.
196 * \note This value wraps roughly every 1 hour 11 minutes and 35 seconds.
197 *
198 * \param timer the timer instance
199 * \return the 32 bit timestamp
200 * \sa time_us_32
201 */
timer_time_us_32(timer_hw_t * timer)202 static inline uint32_t timer_time_us_32(timer_hw_t *timer) {
203 return timer->timerawl;
204 }
205
206 /*! \brief Return a 32 bit timestamp value in microseconds for the default timer instance
207 * \ingroup hardware_timer
208 *
209 * Returns the low 32 bits of the hardware timer.
210 * \note This value wraps roughly every 1 hour 11 minutes and 35 seconds.
211 *
212 * \return the 32 bit timestamp
213 * \sa timer_time_us_32
214 */
time_us_32(void)215 static inline uint32_t time_us_32(void) {
216 return timer_time_us_32(PICO_DEFAULT_TIMER_INSTANCE());
217 }
218
219 /*! \brief Return the current 64 bit timestamp value in microseconds for a given timer instance
220 * \ingroup hardware_timer
221 *
222 * Returns the full 64 bits of the hardware timer. The \ref pico_time and other functions rely on the fact that this
223 * value monotonically increases from power up. As such it is expected that this value counts upwards and never wraps
224 * (we apologize for introducing a potential year 5851444 bug).
225 *
226 * \param timer the timer instance
227 * \return the 64 bit timestamp
228 * \sa time_us_64
229 */
230 uint64_t timer_time_us_64(timer_hw_t *timer);
231
232 /*! \brief Return the current 64 bit timestamp value in microseconds for the default timer instance
233 * \ingroup hardware_timer
234 *
235 * Returns the full 64 bits of the hardware timer. The \ref pico_time and other functions rely on the fact that this
236 * value monotonically increases from power up. As such it is expected that this value counts upwards and never wraps
237 * (we apologize for introducing a potential year 5851444 bug).
238 *
239 * \return the 64 bit timestamp
240 * \sa timer_time_us_64
241 * */
242 uint64_t time_us_64(void);
243
244 /*! \brief Busy wait wasting cycles for the given (32 bit) number of microseconds using the given timer instance
245 * \ingroup hardware_timer
246 *
247 * \param timer the timer instance
248 * \param delay_us delay amount in microseconds
249 * \sa busy_wait_us_32
250 */
251 void timer_busy_wait_us_32(timer_hw_t *timer, uint32_t delay_us);
252
253 /*! \brief Busy wait wasting cycles for the given (32 bit) number of microseconds using the default timer instance
254 * \ingroup hardware_timer
255 *
256 * \param delay_us delay amount in microseconds
257 * \sa timer_busy_wait_us_32
258 */
259 void busy_wait_us_32(uint32_t delay_us);
260
261 /*! \brief Busy wait wasting cycles for the given (64 bit) number of microseconds using the given timer instance
262 * \ingroup hardware_timer
263 *
264 * \param timer the timer instance
265 * \param delay_us delay amount in microseconds
266 * \sa busy_wait_us
267 */
268 void timer_busy_wait_us(timer_hw_t *timer, uint64_t delay_us);
269
270 /*! \brief Busy wait wasting cycles for the given (64 bit) number of microseconds using the default timer instance
271 * \ingroup hardware_timer
272 *
273 * \param delay_us delay amount in microseconds
274 * \sa timer_busy_wait_us
275 */
276 void busy_wait_us(uint64_t delay_us);
277
278 /*! \brief Busy wait wasting cycles for the given number of milliseconds using the given timer instance
279 * \ingroup hardware_timer
280 *
281 * \param timer the timer instance
282 * \param delay_ms delay amount in milliseconds
283 * \sa busy_wait_ms
284 */
285 void timer_busy_wait_ms(timer_hw_t *timer, uint32_t delay_ms);
286
287 /*! \brief Busy wait wasting cycles for the given number of milliseconds using the default timer instance
288 * \ingroup hardware_timer
289 *
290 * \param delay_ms delay amount in milliseconds
291 * \sa timer_busy_wait_ms
292 */
293 void busy_wait_ms(uint32_t delay_ms);
294
295 /*! \brief Busy wait wasting cycles until after the specified timestamp using the given timer instance
296 * \ingroup hardware_timer
297 *
298 * \param timer the timer instance
299 * \param t Absolute time to wait until
300 * \sa busy_wait_until
301 */
302 void timer_busy_wait_until(timer_hw_t *timer, absolute_time_t t);
303
304 /*! \brief Busy wait wasting cycles until after the specified timestamp using the default timer instance
305 * \ingroup hardware_timer
306 *
307 * \param t Absolute time to wait until
308 * \sa timer_busy_wait_until
309 */
310 void busy_wait_until(absolute_time_t t);
311
312 /*! \brief Check if the specified timestamp has been reached on the given timer instance
313 * \ingroup hardware_timer
314 *
315 * \param timer the timer instance
316 * \param t Absolute time to compare against current time
317 * \return true if it is now after the specified timestamp
318 * \sa time_reached
319 */
timer_time_reached(timer_hw_t * timer,absolute_time_t t)320 static inline bool timer_time_reached(timer_hw_t *timer, absolute_time_t t) {
321 uint64_t target = to_us_since_boot(t);
322 uint32_t hi_target = (uint32_t)(target >> 32u);
323 uint32_t hi = timer->timerawh;
324 return (hi >= hi_target && (timer->timerawl >= (uint32_t) target || hi != hi_target));
325 }
326
327 /*! \brief Check if the specified timestamp has been reached on the default timer instance
328 * \ingroup hardware_timer
329 *
330 * \param t Absolute time to compare against current time
331 * \return true if it is now after the specified timestamp
332 * \sa timer_time_reached
333 */
time_reached(absolute_time_t t)334 static inline bool time_reached(absolute_time_t t) {
335 return timer_time_reached(PICO_DEFAULT_TIMER_INSTANCE(), t);
336 }
337
338 /*! Callback function type for hardware alarms
339 * \ingroup hardware_timer
340 *
341 * Modification on the porting to Zephyr:
342 * Add parameter argument to enable referencing user data
343 *
344 * \param alarm_num the hardware alarm number
345 * \sa hardware_alarm_set_callback()
346 */
347 typedef void (*hardware_alarm_callback_t)(uint alarm_num, void *data);
348
349 /*! \brief cooperatively claim the use of this hardware alarm_num on the given timer instance
350 * \ingroup hardware_timer
351 *
352 * This method hard asserts if the hardware alarm is currently claimed.
353 *
354 * \param timer the timer instance
355 * \param alarm_num the hardware alarm to claim
356 * \sa hardware_alarm_claim
357 * \sa hardware_claiming
358 */
359 void timer_hardware_alarm_claim(timer_hw_t *timer, uint alarm_num);
360
361 /*! \brief cooperatively claim the use of this hardware alarm_num on the default timer instance
362 * \ingroup hardware_timer
363 *
364 * This method hard asserts if the hardware alarm is currently claimed.
365 *
366 * \param alarm_num the hardware alarm to claim
367 * \sa timer_hardware_alarm_claim
368 * \sa hardware_claiming
369 */
370 void hardware_alarm_claim(uint alarm_num);
371
372 /*! \brief cooperatively claim the use of a hardware alarm_num on the given timer instance
373 * \ingroup hardware_timer
374 *
375 * This method attempts to claim an unused hardware alarm
376 *
377 * \param timer the timer instance
378 * \param required if true the function will panic if none are available
379 * \return alarm_num the hardware alarm claimed or -1 if required was false, and none are available
380 * \sa hardware_alarm_claim_unused
381 * \sa hardware_claiming
382 */
383 int timer_hardware_alarm_claim_unused(timer_hw_t *timer, bool required);
384
385 /*! \brief cooperatively claim the use of a hardware alarm_num on the default timer instance
386 * \ingroup hardware_timer
387 *
388 * This method attempts to claim an unused hardware alarm
389 *
390 * \param required if true the function will panic if none are available
391 * \return alarm_num the hardware alarm claimed or -1 if required was false, and none are available
392 * \sa timer_hardware_alarm_claim_unused
393 * \sa hardware_claiming
394 */
395 int hardware_alarm_claim_unused(bool required);
396
397 /*! \brief cooperatively release the claim on use of this hardware alarm_num on the given timer instance
398 * \ingroup hardware_timer
399 *
400 * \param timer the timer instance
401 * \param alarm_num the hardware alarm to unclaim
402 * \sa hardware_alarm_unclaim
403 * \sa hardware_claiming
404 */
405 void timer_hardware_alarm_unclaim(timer_hw_t *timer, uint alarm_num);
406
407 /*! \brief cooperatively release the claim on use of this hardware alarm_num on the default timer instance
408 * \ingroup hardware_timer
409 *
410 * \param alarm_num the hardware alarm to unclaim
411 * \sa timer_hardware_alarm_unclaim
412 * \sa hardware_claiming
413 */
414 void hardware_alarm_unclaim(uint alarm_num);
415
416 /*! \brief Determine if a hardware alarm has been claimed on the given timer instance
417 * \ingroup hardware_timer
418 *
419 * \param timer the timer instance
420 * \param alarm_num the hardware alarm number
421 * \return true if claimed, false otherwise
422 * \sa hardware_alarm_is_claimed
423 * \sa hardware_alarm_claim
424 */
425 bool timer_hardware_alarm_is_claimed(timer_hw_t *timer, uint alarm_num);
426
427 /*! \brief Determine if a hardware alarm has been claimed on the default timer instance
428 * \ingroup hardware_timer
429 *
430 * \param alarm_num the hardware alarm number
431 * \return true if claimed, false otherwise
432 * \sa timer_hardware_alarm_is_claimed
433 * \sa hardware_alarm_claim
434 */
435 bool hardware_alarm_is_claimed(uint alarm_num);
436
437 /*! \brief Enable/Disable a callback for a hardware alarm for a given timer instance on this core
438 * \ingroup hardware_timer
439 *
440 * This method enables/disables the alarm IRQ for the specified hardware alarm on the
441 * calling core, and set the specified callback to be associated with that alarm.
442 *
443 * This callback will be used for the timeout set via hardware_alarm_set_target
444 *
445 * \note This will install the handler on the current core if the IRQ handler isn't already set.
446 * Therefore the user has the opportunity to call this up from the core of their choice
447 *
448 * \param timer the timer instance
449 * \param alarm_num the hardware alarm number
450 * \param callback the callback to install, or NULL to unset
451 *
452 * \sa hardware_alarm_set_callback
453 * \sa timer_hardware_alarm_set_target()
454 */
455 void timer_hardware_alarm_set_callback(timer_hw_t *timer, uint alarm_num, hardware_alarm_callback_t callback);
456
457 /*! \brief Enable/Disable a callback for a hardware alarm on the default timer instance on this core
458 * \ingroup hardware_timer
459 *
460 * This method enables/disables the alarm IRQ for the specified hardware alarm on the
461 * calling core, and set the specified callback to be associated with that alarm.
462 *
463 * This callback will be used for the timeout set via hardware_alarm_set_target
464 *
465 * \note This will install the handler on the current core if the IRQ handler isn't already set.
466 * Therefore the user has the opportunity to call this up from the core of their choice
467 *
468 * \param alarm_num the hardware alarm number
469 * \param callback the callback to install, or NULL to unset
470 *
471 * \sa timer_hardware_alarm_set_callback
472 * \sa hardware_alarm_set_target()
473 */
474 void hardware_alarm_set_callback(uint alarm_num, hardware_alarm_callback_t callback);
475
476 /**
477 * \brief Set the current target for a specific hardware alarm on the given timer instance
478 * \ingroup hardware_timer
479 *
480 * This will replace any existing target
481 *
482 * \param timer the timer instance
483 * \param alarm_num the hardware alarm number
484 * \param t the target timestamp
485 * \return true if the target was "missed"; i.e. it was in the past, or occurred before a future hardware timeout could be set
486 * \sa hardware_alarm_set_target
487 */
488 bool timer_hardware_alarm_set_target(timer_hw_t *timer, uint alarm_num, absolute_time_t t);
489
490 /**
491 * \brief Set the current target for the specified hardware alarm on the default timer instance
492 * \ingroup hardware_timer
493 *
494 * This will replace any existing target
495 *
496 * \param alarm_num the hardware alarm number
497 * \param t the target timestamp
498 * \return true if the target was "missed"; i.e. it was in the past, or occurred before a future hardware timeout could be set
499 * \sa timer_hardware_alarm_set_target
500 */
501 bool hardware_alarm_set_target(uint alarm_num, absolute_time_t t);
502
503 /**
504 * \brief Cancel an existing target (if any) for a specific hardware_alarm on the given timer instance
505 * \ingroup hardware_timer
506 *
507 * \param timer the timer instance
508 * \param alarm_num the hardware alarm number
509 * \sa hardware_alarm_cancel
510 */
511 void timer_hardware_alarm_cancel(timer_hw_t *timer, uint alarm_num);
512
513 /**
514 * \brief Cancel an existing target (if any) for the specified hardware_alarm on the default timer instance
515 * \ingroup hardware_timer
516 *
517 * \param alarm_num the hardware alarm number
518 * \sa timer_hardware_alarm_cancel
519 */
520 void hardware_alarm_cancel(uint alarm_num);
521
522 /**
523 * \brief Force and IRQ for a specific hardware alarm on the given timer instance
524 * \ingroup hardware_timer
525 *
526 * This method will forcibly make sure the current alarm callback (if present) for the hardware
527 * alarm is called from an IRQ context after this call. If an actual callback is due at the same
528 * time then the callback may only be called once.
529 *
530 * Calling this method does not otherwise interfere with regular callback operations.
531 *
532 * \param timer the timer instance
533 * \param alarm_num the hardware alarm number
534 * \sa hardware_alarm_force_irq
535 */
536 void timer_hardware_alarm_force_irq(timer_hw_t *timer, uint alarm_num);
537
538 /**
539 * \brief Force and IRQ for a specific hardware alarm on the default timer instance
540 * \ingroup hardware_timer
541 *
542 * This method will forcibly make sure the current alarm callback (if present) for the hardware
543 * alarm is called from an IRQ context after this call. If an actual callback is due at the same
544 * time then the callback may only be called once.
545 *
546 * Calling this method does not otherwise interfere with regular callback operations.
547 *
548 * \param alarm_num the hardware alarm number
549 * \sa timer_hardware_alarm_force_irq
550 */
551 void hardware_alarm_force_irq(uint alarm_num);
552
553 /**
554 * \ingroup hardware_timer
555 * \brief Returns the \ref irq_num_t for the alarm interrupt from the given alarm on the given timer instance
556 * \param timer the timer instance
557 * \param alarm_num the alarm number
558 * \sa TIMER_ALARM_IRQ_NUM
559 */
timer_hardware_alarm_get_irq_num(timer_hw_t * timer,uint alarm_num)560 static inline uint timer_hardware_alarm_get_irq_num(timer_hw_t *timer, uint alarm_num) {
561 check_hardware_alarm_num_param(alarm_num);
562 return TIMER_ALARM_IRQ_NUM(timer, alarm_num);
563 }
564
565 /**
566 * \ingroup hardware_timer
567 * \brief Returns the \ref irq_num_t for the alarm interrupt from the given alarm on the default timer instance
568 * \param alarm_num the alarm number
569 */
hardware_alarm_get_irq_num(uint alarm_num)570 static inline uint hardware_alarm_get_irq_num(uint alarm_num) {
571 return timer_hardware_alarm_get_irq_num(PICO_DEFAULT_TIMER_INSTANCE(), alarm_num);
572 }
573
574 /**
575 * \ingroup hardware_timer
576 * \brief Returns the timer number for a timer instance
577 *
578 * \param timer the timer instance
579 * \return the timer number
580 * \sa TIMER_NUM
581 */
timer_get_index(timer_hw_t * timer)582 static inline uint timer_get_index(timer_hw_t *timer) {
583 return TIMER_NUM(timer);
584 }
585
586 /**
587 * \ingroup hardware_timer
588 * \brief Returns the timer instance with the given timer number
589 *
590 * \param timer_num the timer number
591 * \return the timer instance
592 */
timer_get_instance(uint timer_num)593 static inline timer_hw_t *timer_get_instance(uint timer_num) {
594 invalid_params_if(HARDWARE_TIMER, timer_num >= NUM_GENERIC_TIMERS);
595 return TIMER_INSTANCE(timer_num);
596 }
597
598 /**
599 * Modification on the porting to Zephyr:
600 * Publish as API.
601 * Add parameter argument to enable referencing user data
602 */
603 void hardware_alarm_irq_handler(void *dev);
604 #ifdef __cplusplus
605 }
606 #endif
607 #endif
608