time_adapter.h
1/*
2 * Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _PICO_TIME_ADAPTER_H
8#define _PICO_TIME_ADAPTER_H
9
10#include "hardware/irq.h"
11#include "hardware/timer.h"
12#include "pico/assert.h"
13
14#define TA_NUM_TIMERS NUM_GENERIC_TIMERS
15#define TA_NUM_TIMER_ALARMS NUM_ALARMS
16
17#define timer_hw_from_timer(t) ((timer_hw_t *)(t))
18
19static inline void ta_force_irq(alarm_pool_timer_t *timer, uint alarm_num) {
20 hw_set_bits(&timer_hw_from_timer(timer)->intf, 1u << alarm_num);
21}
22
23static inline void ta_clear_force_irq(alarm_pool_timer_t *timer, uint alarm_num) {
24 hw_clear_bits(&timer_hw_from_timer(timer)->intf, 1u << alarm_num);
25}
26
27static inline void ta_clear_irq(alarm_pool_timer_t *timer, uint alarm_num) {
28 timer_hw_from_timer(timer)->intr = 1u << alarm_num;
29}
30
31static inline alarm_pool_timer_t *ta_from_current_irq(uint *alarm_num) {
32 uint irq_num = __get_current_exception() - VTABLE_FIRST_IRQ;
33 alarm_pool_timer_t *timer = timer_get_instance(TIMER_NUM_FROM_IRQ(irq_num));
34 *alarm_num = TIMER_ALARM_NUM_FROM_IRQ(irq_num);
35 return timer;
36}
37
38static inline void ta_set_timeout(alarm_pool_timer_t *timer, uint alarm_num, int64_t target) {
39 timer_hw_from_timer(timer)->alarm[alarm_num] = (uint32_t) target;
40}
41
42static inline uint64_t ta_time_us_64(alarm_pool_timer_t *timer) {
43 return timer_time_us_64(timer_hw_from_timer(timer));
44}
45
46static inline void ta_enable_irq_handler(alarm_pool_timer_t *timer, uint alarm_num, irq_handler_t irq_handler) {
47 // disarm the timer
48 uint irq_num = timer_hardware_alarm_get_irq_num(timer, alarm_num);
49 timer_hw_from_timer(timer)->armed = 1u << alarm_num;
50 irq_set_exclusive_handler(irq_num, irq_handler);
51 irq_set_enabled(irq_num, true);
52 hw_set_bits(&timer_hw_from_timer(timer)->inte, 1u << alarm_num);
53}
54
55static inline void ta_disable_irq_handler(alarm_pool_timer_t *timer, uint alarm_num, irq_handler_t irq_handler) {
56 uint irq_num = timer_hardware_alarm_get_irq_num(timer, alarm_num);
57 hw_clear_bits(&timer_hw_from_timer(timer)->inte, 1u << alarm_num);
58 irq_set_enabled(irq_num, true);
59 irq_remove_handler(irq_num, irq_handler);
60 hardware_alarm_unclaim(alarm_num);
61}
62
63static inline void ta_hardware_alarm_claim(alarm_pool_timer_t *timer, uint hardware_alaram_num) {
64 timer_hardware_alarm_claim(timer_hw_from_timer(timer), hardware_alaram_num);
65}
66
67static inline int ta_hardware_alarm_claim_unused(alarm_pool_timer_t *timer, bool required) {
68 return timer_hardware_alarm_claim_unused(timer, required);
69}
70
71static inline alarm_pool_timer_t *ta_timer_instance(uint timer_num) {
72 return timer_get_instance(timer_num);
73}
74
75static inline uint ta_timer_num(alarm_pool_timer_t *timer) {
76 return timer_get_index(timer_hw_from_timer(timer));
77}
78
79static inline alarm_pool_timer_t *ta_default_timer_instance(void) {
81}
82#endif
static __force_inline void hw_set_bits(io_rw_32 *addr, uint32_t mask)
Atomically set the specified bits to 1 in a HW register.
Definition: address_mapped.h:135
static __force_inline void hw_clear_bits(io_rw_32 *addr, uint32_t mask)
Atomically clear the specified bits to 0 in a HW register.
Definition: address_mapped.h:145
void irq_set_enabled(uint num, bool enabled)
Enable or disable a specific interrupt on the executing core.
Definition: irq.c:61
void(* irq_handler_t)(void)
Interrupt handler function type.
Definition: irq.h:195
void irq_remove_handler(uint num, irq_handler_t handler)
Remove a specific interrupt handler for the given irq number on the executing core.
Definition: irq.c:470
void irq_set_exclusive_handler(uint num, irq_handler_t handler)
Set an exclusive interrupt handler for an interrupt on the executing core.
Definition: irq.c:219
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
static timer_hw_t * timer_get_instance(uint timer_num)
Returns the timer instance with the given timer number.
Definition: timer.h:591
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
static uint timer_get_index(timer_hw_t *timer)
Returns the timer number for a timer instance.
Definition: timer.h:580
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
#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
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
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
#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.
Definition: timer.h:147
#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 instanc...
Definition: timer.h:129
static __force_inline uint __get_current_exception(void)
Get the current exception level on this core.
Definition: platform.h:158