v2.0.0
timer.h
Go to the documentation of this file.
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
15extern "C" {
16#endif
17
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
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
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
105#ifndef TIMER_ALARM_IRQ_NUM
106#if NUM_GENERIC_TIMERS == 1
107static_assert(TIMER_IRQ_3 == TIMER_IRQ_0 + 3, "");
108#define TIMER_ALARM_IRQ_NUM(timer, alarm_num) (TIMER_IRQ_0 + (alarm_num))
109#else
110static_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
123#ifndef TIMER_ALARM_NUM_FROM_IRQ
124#if NUM_GENERIC_TIMERS == 1
125static_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
128static_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
141#ifndef TIMER_NUM_FROM_IRQ
142#if NUM_GENERIC_TIMERS == 1
143static_assert(TIMER_IRQ_3 == TIMER_IRQ_0 + 3, "");
144#define TIMER_NUM_FROM_IRQ(irq_num) (((irq_num) - TIMER_IRQ_0) >> 2)
145#else
146static_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
163#ifndef PICO_DEFAULT_TIMER
164#define PICO_DEFAULT_TIMER 0
165#endif
166
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
188static inline void check_hardware_alarm_num_param(__unused uint alarm_num) {
189 invalid_params_if(HARDWARE_TIMER, alarm_num >= NUM_ALARMS);
190}
191
202 static inline uint32_t timer_time_us_32(timer_hw_t *timer) {
203 return timer->timerawl;
204}
205
215 static inline uint32_t time_us_32(void) {
216 return timer_time_us_32(PICO_DEFAULT_TIMER_INSTANCE());
217}
218
230uint64_t timer_time_us_64(timer_hw_t *timer);
231
242uint64_t time_us_64(void);
243
251void timer_busy_wait_us_32(timer_hw_t *timer, uint32_t delay_us);
252
259void busy_wait_us_32(uint32_t delay_us);
260
268void timer_busy_wait_us(timer_hw_t *timer, uint64_t delay_us);
269
276void busy_wait_us(uint64_t delay_us);
277
285void timer_busy_wait_ms(timer_hw_t *timer, uint32_t delay_ms);
286
293void busy_wait_ms(uint32_t delay_ms);
294
302void timer_busy_wait_until(timer_hw_t *timer, absolute_time_t t);
303
310void busy_wait_until(absolute_time_t t);
311
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
334 static inline bool time_reached(absolute_time_t t) {
335 return timer_time_reached(PICO_DEFAULT_TIMER_INSTANCE(), t);
336}
337
344 typedef void (*hardware_alarm_callback_t)(uint alarm_num);
345
356void timer_hardware_alarm_claim(timer_hw_t *timer, uint alarm_num);
357
367void hardware_alarm_claim(uint alarm_num);
368
380int timer_hardware_alarm_claim_unused(timer_hw_t *timer, bool required);
381
392int hardware_alarm_claim_unused(bool required);
393
402void timer_hardware_alarm_unclaim(timer_hw_t *timer, uint alarm_num);
403
411void hardware_alarm_unclaim(uint alarm_num);
412
422bool timer_hardware_alarm_is_claimed(timer_hw_t *timer, uint alarm_num);
423
432bool hardware_alarm_is_claimed(uint alarm_num);
433
452void timer_hardware_alarm_set_callback(timer_hw_t *timer, uint alarm_num, hardware_alarm_callback_t callback);
453
471void hardware_alarm_set_callback(uint alarm_num, hardware_alarm_callback_t callback);
472
485bool timer_hardware_alarm_set_target(timer_hw_t *timer, uint alarm_num, absolute_time_t t);
486
498bool hardware_alarm_set_target(uint alarm_num, absolute_time_t t);
499
508void timer_hardware_alarm_cancel(timer_hw_t *timer, uint alarm_num);
509
517void hardware_alarm_cancel(uint alarm_num);
518
533void timer_hardware_alarm_force_irq(timer_hw_t *timer, uint alarm_num);
534
548void hardware_alarm_force_irq(uint alarm_num);
549
557 static inline uint timer_hardware_alarm_get_irq_num(__unused timer_hw_t *timer, uint alarm_num) {
558 check_hardware_alarm_num_param(alarm_num);
559 return TIMER_ALARM_IRQ_NUM(timer, alarm_num);
560}
561
568 static inline uint hardware_alarm_get_irq_num(timer_hw_t *timer, uint alarm_num) {
569 return timer_hardware_alarm_get_irq_num(PICO_DEFAULT_TIMER_INSTANCE(), alarm_num);
570}
571
580 static inline uint timer_get_index(timer_hw_t *timer) {
581 return TIMER_NUM(timer);
582}
583
591 static inline timer_hw_t *timer_get_instance(uint timer_num) {
592 invalid_params_if(HARDWARE_TIMER, timer_num >= NUM_GENERIC_TIMERS);
593 return TIMER_INSTANCE(timer_num);
594}
595
596#ifdef __cplusplus
597}
598#endif
599#endif
TIMER0_IRQ_0
@ TIMER0_IRQ_0
Select TIMER0's IRQ 0 output.
Definition: intctrl.h:74
TIMER1_IRQ_3
@ TIMER1_IRQ_3
Select TIMER1's IRQ 3 output.
Definition: intctrl.h:81
TIMER_IRQ_0
@ TIMER_IRQ_0
Select TIMER's IRQ 0 output.
Definition: intctrl_rp2040.h:48
TIMER_IRQ_3
@ TIMER_IRQ_3
Select TIMER's IRQ 3 output.
Definition: intctrl_rp2040.h:51
hardware_alarm_unclaim
void hardware_alarm_unclaim(uint alarm_num)
cooperatively release the claim on use of this hardware alarm_num on the default timer instance
Definition: timer.c:35
busy_wait_ms
void busy_wait_ms(uint32_t delay_ms)
Busy wait wasting cycles for the given number of milliseconds using the default timer instance.
Definition: timer.c:137
timer_get_instance
static timer_hw_t * timer_get_instance(uint timer_num)
Returns the timer instance with the given timer number.
Definition: timer.h:591
time_reached
static bool time_reached(absolute_time_t t)
Check if the specified timestamp has been reached on the default timer instance.
Definition: timer.h:334
timer_hardware_alarm_set_callback
void timer_hardware_alarm_set_callback(timer_hw_t *timer, uint alarm_num, hardware_alarm_callback_t callback)
Enable/Disable a callback for a hardware alarm for a given timer instance on this core.
Definition: timer.c:183
timer_time_reached
static bool timer_time_reached(timer_hw_t *timer, absolute_time_t t)
Check if the specified timestamp has been reached on the given timer instance.
Definition: timer.h:320
timer_time_us_32
static uint32_t timer_time_us_32(timer_hw_t *timer)
Return a 32 bit timestamp value in microseconds for a given timer instance.
Definition: timer.h:202
timer_hardware_alarm_get_irq_num
static uint timer_hardware_alarm_get_irq_num(__unused timer_hw_t *timer, uint alarm_num)
Returns the irq_num_t for the alarm interrupt from the given alarm on the given timer instance.
Definition: timer.h:557
hardware_alarm_claim_unused
int hardware_alarm_claim_unused(bool required)
cooperatively claim the use of a hardware alarm_num on the default timer instance
Definition: timer.c:52
timer_hardware_alarm_is_claimed
bool timer_hardware_alarm_is_claimed(timer_hw_t *timer, uint alarm_num)
Determine if a hardware alarm has been claimed on the given timer instance.
Definition: timer.c:39
hardware_alarm_get_irq_num
static uint hardware_alarm_get_irq_num(timer_hw_t *timer, uint alarm_num)
Returns the irq_num_t for the alarm interrupt from the given alarm on the default timer instance.
Definition: timer.h:568
hardware_alarm_force_irq
void hardware_alarm_force_irq(uint alarm_num)
Force and IRQ for a specific hardware alarm on the default timer instance.
Definition: timer.c:292
hardware_alarm_claim
void hardware_alarm_claim(uint alarm_num)
cooperatively claim the use of this hardware alarm_num on the default timer instance
Definition: timer.c:26
hardware_alarm_cancel
void hardware_alarm_cancel(uint alarm_num)
Cancel an existing target (if any) for the specified hardware_alarm on the default timer instance.
Definition: timer.c:279
hardware_alarm_set_target
bool hardware_alarm_set_target(uint alarm_num, absolute_time_t t)
Set the current target for the specified hardware alarm on the default timer instance.
Definition: timer.c:265
timer_hardware_alarm_force_irq
void timer_hardware_alarm_force_irq(timer_hw_t *timer, uint alarm_num)
Force and IRQ for a specific hardware alarm on the given timer instance.
Definition: timer.c:283
hardware_alarm_is_claimed
bool hardware_alarm_is_claimed(uint alarm_num)
Determine if a hardware alarm has been claimed on the default timer instance.
Definition: timer.c:44
timer_get_index
static uint timer_get_index(timer_hw_t *timer)
Returns the timer number for a timer instance.
Definition: timer.h:580
TIMER_ALARM_IRQ_NUM
#define TIMER_ALARM_IRQ_NUM(timer, alarm_num)
Returns the irq_num_t for the alarm interrupt from the given alarm on the given timer instance.
Definition: timer.h:111
time_us_64
uint64_t time_us_64(void)
Return the current 64 bit timestamp value in microseconds for the default timer instance.
Definition: timer.c:125
timer_hardware_alarm_set_target
bool timer_hardware_alarm_set_target(timer_hw_t *timer, uint alarm_num, absolute_time_t t)
Set the current target for a specific hardware alarm on the given timer instance.
Definition: timer.c:215
timer_hardware_alarm_claim_unused
int timer_hardware_alarm_claim_unused(timer_hw_t *timer, bool required)
cooperatively claim the use of a hardware alarm_num on the given timer instance
Definition: timer.c:48
busy_wait_us_32
void busy_wait_us_32(uint32_t delay_us)
Busy wait wasting cycles for the given (32 bit) number of microseconds using the default timer instan...
Definition: timer.c:129
PICO_DEFAULT_TIMER_INSTANCE
#define PICO_DEFAULT_TIMER_INSTANCE()
Returns the default timer instance on the platform based on the setting of PICO_DEFAULT_TIMER.
Definition: timer.h:182
timer_time_us_64
uint64_t timer_time_us_64(timer_hw_t *timer)
Return the current 64 bit timestamp value in microseconds for a given timer instance.
Definition: timer.c:57
timer_busy_wait_until
void timer_busy_wait_until(timer_hw_t *timer, absolute_time_t t)
Busy wait wasting cycles until after the specified timestamp using the given timer instance.
Definition: timer.c:110
timer_busy_wait_us_32
void timer_busy_wait_us_32(timer_hw_t *timer, uint32_t delay_us)
Busy wait wasting cycles for the given (32 bit) number of microseconds using the given timer instance...
Definition: timer.c:77
timer_busy_wait_us
void timer_busy_wait_us(timer_hw_t *timer, uint64_t delay_us)
Busy wait wasting cycles for the given (64 bit) number of microseconds using the given timer instance...
Definition: timer.c:90
hardware_alarm_set_callback
void hardware_alarm_set_callback(uint alarm_num, hardware_alarm_callback_t callback)
Enable/Disable a callback for a hardware alarm on the default timer instance on this core.
Definition: timer.c:211
timer_hardware_alarm_claim
void timer_hardware_alarm_claim(timer_hw_t *timer, uint alarm_num)
cooperatively claim the use of this hardware alarm_num on the given timer instance
Definition: timer.c:21
busy_wait_until
void busy_wait_until(absolute_time_t t)
Busy wait wasting cycles until after the specified timestamp using the default timer instance.
Definition: timer.c:142
timer_hardware_alarm_cancel
void timer_hardware_alarm_cancel(timer_hw_t *timer, uint alarm_num)
Cancel an existing target (if any) for a specific hardware_alarm on the given timer instance.
Definition: timer.c:269
time_us_32
static uint32_t time_us_32(void)
Return a 32 bit timestamp value in microseconds for the default timer instance.
Definition: timer.h:215
busy_wait_us
void busy_wait_us(uint64_t delay_us)
Busy wait wasting cycles for the given (64 bit) number of microseconds using the default timer instan...
Definition: timer.c:133
timer_busy_wait_ms
void timer_busy_wait_ms(timer_hw_t *timer, uint32_t delay_ms)
Busy wait wasting cycles for the given number of milliseconds using the given timer instance.
Definition: timer.c:101
timer_hardware_alarm_unclaim
void timer_hardware_alarm_unclaim(timer_hw_t *timer, uint alarm_num)
cooperatively release the claim on use of this hardware alarm_num on the given timer instance
Definition: timer.c:30
hardware_alarm_callback_t
void(* hardware_alarm_callback_t)(uint alarm_num)
Definition: timer.h:344
to_us_since_boot
static uint64_t to_us_since_boot(absolute_time_t t)
convert an absolute_time_t into a number of microseconds since boot.
Definition: types.h:52
absolute_time_t
uint64_t absolute_time_t
An opaque 64 bit timestamp in microseconds.
Definition: types.h:43
pico.h
timer_hw_t
Definition: timer.h:26