summaryrefslogtreecommitdiff
path: root/libhw/rp2040_include/libhw/rp2040_hwalarm.h
blob: 3a7ae10f7dbdea85d1f5dea174e53941f2afac5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/* libhw/rp2040_hwalarm.h - Alarms for the RP2040
 *
 * Copyright (C) 2024  Luke T. Shumaker <lukeshu@lukeshu.com>
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

#ifndef _LIBHW_RP2040_HWALARM_H_
#define _LIBHW_RP2040_HWALARM_H_

#include <stdbool.h>         /* for bool */
#include <stdint.h>          /* for uint{n}_t */

#include <libmisc/private.h> /* for BEGIN_PRIVATE, END_PRIVATE */

/**
 * The RP2040 has one system "timer" (which we also use for
 * ./rp2040_bootclock.c) with 4 alarm interrupts.
 */
enum rp2040_hwalarm_instance {
	RP2040_HWALARM_0 = 0,
	RP2040_HWALARM_1 = 1,
	RP2040_HWALARM_2 = 2,
	RP2040_HWALARM_3 = 3,
	_RP2040_HWALARM_NUM,
};

struct rp2040_hwalarm_trigger;
struct rp2040_hwalarm_trigger {
	BEGIN_PRIVATE(LIBHW_RP2040_HWALARM_H)
	void                              *alarm;
	struct rp2040_hwalarm_trigger     *prev, *next;

	uint64_t                           fire_at_us;
	void                               (*cb)(void *);
	void                              *cb_arg;
	END_PRIVATE(LIBHW_RP2040_HWALARM_H)
};

/**
 * Returns true on error.
 *
 * fire_at_ns must be at most UINT32_MAX µs (72 minutes) in the future
 * (or an error will be returned).
 *
 * If fire_at_ns is in the past, then it will fire immediately.
 */
bool rp2040_hwalarm_trigger_init(struct rp2040_hwalarm_trigger *self,
                                 enum rp2040_hwalarm_instance alarm_num,
                                 uint64_t                     fire_at_ns,
                                 void                         (*cb)(void *),
                                 void                        *cb_arg);

void rp2040_hwalarm_trigger_cancel(struct rp2040_hwalarm_trigger *self);

#endif /* _LIBHW_RP2040_HWALARM_H_ */