hardware_timer

Low-level hardware timer API. More...

Macros

#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. More...
 
#define TIMER_ALARM_NUM_FROM_IRQ(irq_num)
 Returns the alarm number from an \irq_num_t. See TIMER_INSTANCE_NUM_FROM_IRQ to get the timer instance number. More...
 
#define TIMER_NUM_FROM_IRQ(irq_num)
 Returns the alarm number from an \irq_num_t. See TIMER_INSTANCE_NUM_FROM_IRQ to get the alarm number. More...
 
#define PICO_DEFAULT_TIMER   0
 The default timer instance number of the timer instance used for APIs that don't take an explicit timer instance On RP2040 this must be 0 as there is only one timer instance On RP2040 this may be set to 0 or 1 .
 
#define PICO_DEFAULT_TIMER_INSTANCE()
 Returns the default timer instance on the platform based on the setting of PICO_DEFAULT_TIMER. More...
 

Typedefs

typedef void(* hardware_alarm_callback_t) (uint alarm_num)
 

Functions

static uint32_t timer_time_us_32 (timer_hw_t *timer)
 Return a 32 bit timestamp value in microseconds for a given timer instance. More...
 
static uint32_t time_us_32 (void)
 Return a 32 bit timestamp value in microseconds for the default timer instance. More...
 
uint64_t timer_time_us_64 (timer_hw_t *timer)
 Return the current 64 bit timestamp value in microseconds for a given timer instance. More...
 
uint64_t time_us_64 (void)
 Return the current 64 bit timestamp value in microseconds for the default timer instance. More...
 
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. More...
 
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 instance. More...
 
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. More...
 
void busy_wait_us (uint64_t delay_us)
 Busy wait wasting cycles for the given (64 bit) number of microseconds using the default timer instance. More...
 
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. More...
 
void busy_wait_ms (uint32_t delay_ms)
 Busy wait wasting cycles for the given number of milliseconds using the default timer instance. More...
 
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. More...
 
void busy_wait_until (absolute_time_t t)
 Busy wait wasting cycles until after the specified timestamp using the default timer instance. More...
 
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. More...
 
static bool time_reached (absolute_time_t t)
 Check if the specified timestamp has been reached on the default timer instance. More...
 
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 More...
 
void hardware_alarm_claim (uint alarm_num)
 cooperatively claim the use of this hardware alarm_num on the default timer instance More...
 
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 More...
 
int hardware_alarm_claim_unused (bool required)
 cooperatively claim the use of a hardware alarm_num on the default timer instance More...
 
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 More...
 
void hardware_alarm_unclaim (uint alarm_num)
 cooperatively release the claim on use of this hardware alarm_num on the default timer instance More...
 
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. More...
 
bool hardware_alarm_is_claimed (uint alarm_num)
 Determine if a hardware alarm has been claimed on the default timer instance. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
void hardware_alarm_cancel (uint alarm_num)
 Cancel an existing target (if any) for the specified hardware_alarm on the default timer instance. More...
 
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. More...
 
void hardware_alarm_force_irq (uint alarm_num)
 Force and IRQ for a specific hardware alarm on the default timer instance. More...
 
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. More...
 
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. More...
 
static uint timer_get_index (timer_hw_t *timer)
 Returns the timer number for a timer instance. More...
 
static timer_hw_ttimer_get_instance (uint timer_num)
 Returns the timer instance with the given timer number. More...
 

Detailed Description

Low-level hardware timer API.

This API provides medium level access to the timer HW. See also pico_time which provides higher levels functionality using the hardware timer.

The timer peripheral on RP-series microcontrollers supports the following features:

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 from the clk_ref.

On RP2350, by default the timer uses a one microsecond reference that is generated by the tick block (see RP2350 Datasheet Section 8.5)

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 bit counter which means they can be fired a maximum of 2^32 microseconds into the future. This is equivalent to:

The timer is expected to be used for short sleeps, if you want a longer alarm see the hardware_rtc functions.

Example

#include <stdio.h>
#include "pico/stdlib.h"
volatile bool timer_fired = false;
int64_t alarm_callback(alarm_id_t id, void *user_data) {
printf("Timer %d fired!\n", (int) id);
timer_fired = true;
// Can return a value here in us to fire in the future
return 0;
}
bool repeating_timer_callback(struct repeating_timer *t) {
printf("Repeat at %lld\n", time_us_64());
return true;
}
int main() {
printf("Hello Timer!\n");
// Call alarm_callback in 2 seconds
add_alarm_in_ms(2000, alarm_callback, NULL, false);
// Wait for alarm callback to set timer_fired
while (!timer_fired) {
}
// Create a repeating timer that calls repeating_timer_callback.
// If the delay is > 0 then this is the delay between the previous callback ending and the next starting.
// If the delay is negative (see below) then the next call to the callback will be exactly 500ms after the
// start of the call to the last callback
struct repeating_timer timer;
add_repeating_timer_ms(500, repeating_timer_callback, NULL, &timer);
sleep_ms(3000);
bool cancelled = cancel_repeating_timer(&timer);
printf("cancelled... %d\n", cancelled);
sleep_ms(2000);
// Negative delay so means we will call repeating_timer_callback, and call it again
// 500ms later regardless of how long the callback took to execute
add_repeating_timer_ms(-500, repeating_timer_callback, NULL, &timer);
sleep_ms(3000);
cancelled = cancel_repeating_timer(&timer);
printf("cancelled... %d\n", cancelled);
sleep_ms(2000);
printf("Done\n");
return 0;
}
static alarm_id_t add_alarm_in_ms(uint32_t ms, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called after a delay specified in milliseconds.
Definition: time.h:671
int32_t alarm_id_t
The identifier for an alarm.
Definition: time.h:365
uint64_t time_us_64(void)
Return the current 64 bit timestamp value in microseconds for the default timer instance.
Definition: timer.c:125
static __force_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition: platform.h:67
bool stdio_init_all(void)
Initialize all of the present standard stdio types that are linked into the binary.
Definition: stdio.c:200
static bool add_repeating_timer_ms(int32_t delay_ms, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out)
Add a repeating timer that is called repeatedly at the specified interval in milliseconds.
Definition: time.h:824
bool cancel_repeating_timer(repeating_timer_t *timer)
Cancel a repeating timer.
Definition: time.c:481
void sleep_ms(uint32_t ms)
Wait for the given number of milliseconds before returning.
Definition: time.c:431
Information about a repeating timer.
Definition: time.h:735
See also
pico_time

Macro Definition Documentation

◆ 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.

Note this macro is intended to resolve at compile time, and does no parameter checking

◆ 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.

Note this macro is intended to resolve at compile time, and does no parameter checking

◆ TIMER_ALARM_NUM_FROM_IRQ

#define TIMER_ALARM_NUM_FROM_IRQ (   irq_num)

Returns the alarm number from an \irq_num_t. See TIMER_INSTANCE_NUM_FROM_IRQ to get the timer instance number.

Note this macro is intended to resolve at compile time, and does no parameter checking

◆ TIMER_NUM_FROM_IRQ

#define TIMER_NUM_FROM_IRQ (   irq_num)

Returns the alarm number from an \irq_num_t. See TIMER_INSTANCE_NUM_FROM_IRQ to get the alarm number.

Note this macro is intended to resolve at compile time, and does no parameter checking

Typedef Documentation

◆ hardware_alarm_callback_t

typedef void(* hardware_alarm_callback_t) (uint alarm_num)

Callback function type for hardware alarms

Parameters
alarm_numthe hardware alarm number
See also
hardware_alarm_set_callback()

Function Documentation

◆ 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.

Parameters
delay_msdelay amount in milliseconds
See also
timer_busy_wait_ms

◆ 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.

Parameters
tAbsolute time to wait until
See also
timer_busy_wait_until

◆ 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 instance.

Parameters
delay_usdelay amount in microseconds
See also
timer_busy_wait_us

◆ 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 instance.

Parameters
delay_usdelay amount in microseconds
See also
timer_busy_wait_us_32

◆ 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.

Parameters
alarm_numthe hardware alarm number
See also
timer_hardware_alarm_cancel

◆ hardware_alarm_claim()

void hardware_alarm_claim ( uint  alarm_num)

cooperatively claim the use of this hardware alarm_num on the default timer instance

This method hard asserts if the hardware alarm is currently claimed.

Parameters
alarm_numthe hardware alarm to claim
See also
timer_hardware_alarm_claim
hardware_claiming

◆ 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

This method attempts to claim an unused hardware alarm

Parameters
requiredif true the function will panic if none are available
Returns
alarm_num the hardware alarm claimed or -1 if required was false, and none are available
See also
timer_hardware_alarm_claim_unused
hardware_claiming

◆ 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.

This method will forcibly make sure the current alarm callback (if present) for the hardware alarm is called from an IRQ context after this call. If an actual callback is due at the same time then the callback may only be called once.

Calling this method does not otherwise interfere with regular callback operations.

Parameters
alarm_numthe hardware alarm number
See also
timer_hardware_alarm_force_irq

◆ hardware_alarm_get_irq_num()

static uint hardware_alarm_get_irq_num ( timer_hw_t timer,
uint  alarm_num 
)
inlinestatic

Returns the irq_num_t for the alarm interrupt from the given alarm on the default timer instance.

Parameters
timerthe timer instance
alarm_numthe alarm number

◆ 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.

Parameters
alarm_numthe hardware alarm number
Returns
true if claimed, false otherwise
See also
timer_hardware_alarm_is_claimed
hardware_alarm_claim

◆ 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.

This method enables/disables the alarm IRQ for the specified hardware alarm on the calling core, and set the specified callback to be associated with that alarm.

This callback will be used for the timeout set via hardware_alarm_set_target

Note
This will install the handler on the current core if the IRQ handler isn't already set. Therefore the user has the opportunity to call this up from the core of their choice
Parameters
alarm_numthe hardware alarm number
callbackthe callback to install, or NULL to unset
See also
timer_hardware_alarm_set_callback
hardware_alarm_set_target()

◆ 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.

This will replace any existing target

Parameters
alarm_numthe hardware alarm number
tthe target timestamp
Returns
true if the target was "missed"; i.e. it was in the past, or occurred before a future hardware timeout could be set
See also
timer_hardware_alarm_set_target

◆ 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

Parameters
alarm_numthe hardware alarm to unclaim
See also
timer_hardware_alarm_unclaim
hardware_claiming

◆ time_reached()

static bool time_reached ( absolute_time_t  t)
inlinestatic

Check if the specified timestamp has been reached on the default timer instance.

Parameters
tAbsolute time to compare against current time
Returns
true if it is now after the specified timestamp
See also
timer_time_reached

◆ time_us_32()

static uint32_t time_us_32 ( void  )
inlinestatic

Return a 32 bit timestamp value in microseconds for the default timer instance.

Returns the low 32 bits of the hardware timer.

Note
This value wraps roughly every 1 hour 11 minutes and 35 seconds.
Returns
the 32 bit timestamp
See also
timer_time_us_32

◆ time_us_64()

uint64_t time_us_64 ( void  )

Return the current 64 bit timestamp value in microseconds for the default timer instance.

Returns the full 64 bits of the hardware timer. The pico_time and other functions rely on the fact that this value monotonically increases from power up. As such it is expected that this value counts upwards and never wraps (we apologize for introducing a potential year 5851444 bug).

Returns
the 64 bit timestamp
See also
timer_time_us_64

◆ 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.

Parameters
timerthe timer instance
delay_msdelay amount in milliseconds
See also
busy_wait_ms

◆ 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.

Parameters
timerthe timer instance
tAbsolute time to wait until
See also
busy_wait_until

◆ 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.

Parameters
timerthe timer instance
delay_usdelay amount in microseconds
See also
busy_wait_us

◆ 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.

Parameters
timerthe timer instance
delay_usdelay amount in microseconds
See also
busy_wait_us_32

Busy wait wasting cycles for the given (32 bit) number of microseconds using the given timer instance.

◆ timer_get_index()

static uint timer_get_index ( timer_hw_t timer)
inlinestatic

Returns the timer number for a timer instance.

Parameters
timerthe timer instance
Returns
the timer number
See also
TIMER_NUM

◆ timer_get_instance()

static timer_hw_t * timer_get_instance ( uint  timer_num)
inlinestatic

Returns the timer instance with the given timer number.

Parameters
timer_numthe timer number
Returns
the timer instance

◆ 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.

Parameters
timerthe timer instance
alarm_numthe hardware alarm number
See also
hardware_alarm_cancel

◆ 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

This method hard asserts if the hardware alarm is currently claimed.

Parameters
timerthe timer instance
alarm_numthe hardware alarm to claim
See also
hardware_alarm_claim
hardware_claiming

◆ 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

This method attempts to claim an unused hardware alarm

Parameters
timerthe timer instance
requiredif true the function will panic if none are available
Returns
alarm_num the hardware alarm claimed or -1 if required was false, and none are available
See also
hardware_alarm_claim_unused
hardware_claiming

◆ 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.

This method will forcibly make sure the current alarm callback (if present) for the hardware alarm is called from an IRQ context after this call. If an actual callback is due at the same time then the callback may only be called once.

Calling this method does not otherwise interfere with regular callback operations.

Parameters
timerthe timer instance
alarm_numthe hardware alarm number
See also
hardware_alarm_force_irq

◆ timer_hardware_alarm_get_irq_num()

static uint timer_hardware_alarm_get_irq_num ( __unused timer_hw_t timer,
uint  alarm_num 
)
inlinestatic

Returns the irq_num_t for the alarm interrupt from the given alarm on the given timer instance.

Parameters
timerthe timer instance
alarm_numthe alarm number
See also
TIMER_ALARM_IRQ_NUM

◆ 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.

Parameters
timerthe timer instance
alarm_numthe hardware alarm number
Returns
true if claimed, false otherwise
See also
hardware_alarm_is_claimed
hardware_alarm_claim

◆ 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.

This method enables/disables the alarm IRQ for the specified hardware alarm on the calling core, and set the specified callback to be associated with that alarm.

This callback will be used for the timeout set via hardware_alarm_set_target

Note
This will install the handler on the current core if the IRQ handler isn't already set. Therefore the user has the opportunity to call this up from the core of their choice
Parameters
timerthe timer instance
alarm_numthe hardware alarm number
callbackthe callback to install, or NULL to unset
See also
hardware_alarm_set_callback
timer_hardware_alarm_set_target()

◆ 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.

This will replace any existing target

Parameters
timerthe timer instance
alarm_numthe hardware alarm number
tthe target timestamp
Returns
true if the target was "missed"; i.e. it was in the past, or occurred before a future hardware timeout could be set
See also
hardware_alarm_set_target

◆ 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

Parameters
timerthe timer instance
alarm_numthe hardware alarm to unclaim
See also
hardware_alarm_unclaim
hardware_claiming

◆ timer_time_reached()

static bool timer_time_reached ( timer_hw_t timer,
absolute_time_t  t 
)
inlinestatic

Check if the specified timestamp has been reached on the given timer instance.

Parameters
timerthe timer instance
tAbsolute time to compare against current time
Returns
true if it is now after the specified timestamp
See also
time_reached

◆ timer_time_us_32()

static uint32_t timer_time_us_32 ( timer_hw_t timer)
inlinestatic

Return a 32 bit timestamp value in microseconds for a given timer instance.

Returns the low 32 bits of the hardware timer.

Note
This value wraps roughly every 1 hour 11 minutes and 35 seconds.
Parameters
timerthe timer instance
Returns
the 32 bit timestamp
See also
time_us_32

◆ 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.

Returns the full 64 bits of the hardware timer. The pico_time and other functions rely on the fact that this value monotonically increases from power up. As such it is expected that this value counts upwards and never wraps (we apologize for introducing a potential year 5851444 bug).

Parameters
timerthe timer instance
Returns
the 64 bit timestamp
See also
time_us_64

Return the current 64 bit timestamp value in microseconds for a given timer instance.