KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
timer.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 arch/dreamcast/include/timer.h
4 Copyright (c) 2000, 2001 Megan Potter
5 Copyright (c) 2023 Falco Girgis
6 Copyright (c) 2024 Paul Cercueil
7
8*/
9
10/** \file arch/timer.h
11 \brief Low-level timer functionality.
12 \ingroup timers
13
14 This file contains functions for interacting with the timer sources on the
15 SH4. Many of these functions may interfere with thread operation or other
16 such things, and should thus be used with caution. Basically, the only
17 functionality that you might use in practice in here in normal programs is
18 the gettime functions.
19
20 \sa arch/rtc.h
21 \sa dc/wdt.h
22
23 \author Megan Potter
24 \author Falco Girgis
25*/
26
27#ifndef __ARCH_TIMER_H
28#define __ARCH_TIMER_H
29
30
31#include <stdint.h>
32#include <kos/cdefs.h>
33__BEGIN_DECLS
34
35#include <arch/irq.h>
36
37#include <time.h>
38
39/** \defgroup timers Timer Unit
40 \brief SH4 CPU peripheral providing timers and counters
41 \ingroup timing
42
43 The Dreamcast's SH4 includes an on-chip Timer Unit (TMU) containing 3
44 independent 32-bit channels (TMU0-TMU2). Each channel provides a
45 down-counter with automatic reload and can be configured to use 1 of
46 7 divider circuits for its input clock. By default, KOS uses the fastest
47 input clock for each TMU channel, providing a maximum internal resolution
48 of 80ns ticks.
49
50 \warning
51 Under normal circumstances, all 3 TMU channels are reserved by KOS for
52 various OS-related purposes. If you need a free general-purpose interval
53 timer, consider using the Watchdog Timer.
54
55 \note
56 90% of the time, you will never have a need to directly interact with this
57 API, as it's mostly used as a kernel-level driver which backs other APIs.
58 For example, querying for ticks, fetching the current timestamp, or putting
59 a thread to sleep is typically done via the standard C, C++, or POSIX APIs.
60
61*/
62
63/** \defgroup tmus Channels
64 \brief TMU channel constants
65 \ingroup timers
66
67 The following are the constant `#define` identifiers for the 3 TMU channels.
68
69 \warning
70 All three of these channels are typically reserved and are by KOS for
71 OS-related tasks.
72
73 @{
74*/
75
76/** \brief SH4 Timer Channel 0.
77
78 \warning
79 This timer is used by the kernel's scheduler for thread operation, and thus
80 is off limits if you want that to work properly.
81*/
82#define TMU0 0
83
84/** \brief SH4 Timer Channel 1.
85
86 \warning
87 This timer channel is free to use.
88*/
89#define TMU1 1
90
91/** \brief SH4 Timer Channel 2.
92
93 \warning
94 This timer channel is used by the various gettime functions in this header.
95 It also backs the standard C, C++, and POSIX date/time and clock functions.
96*/
97#define TMU2 2
98
99/** @} */
100
101/** \cond Which timer does the thread system use? */
102#define TIMER_ID TMU0
103/** \endcond */
104
105/** \defgroup tmu_direct Direct-Access
106 \brief Low-level timer driver
107 \ingroup timers
108
109 This API provides a low-level driver abstraction around the TMU peripheral
110 and the control, counter, and reload registers of its 3 channels.
111
112 \note
113 You typically want to use the higher-level APIs associated with the
114 functionality implemented by each timer channel.
115*/
116
117/** \brief Pre-initialize a timer channel, but do not start it.
118 \ingroup tmu_direct
119
120 This function sets up a timer channel for use, but does not start it.
121
122 \param channel The timer channel to set up (\ref tmus).
123 \param speed The number of ticks per second.
124 \param interrupts Set to 1 to receive interrupts when the timer ticks.
125 \retval 0 On success.
126*/
127int timer_prime(int channel, uint32_t speed, int interrupts);
128
129/** \brief Start a timer channel.
130 \ingroup tmu_direct
131
132 This function starts a timer channel that has been initialized with
133 timer_prime(), starting raising interrupts if applicable.
134
135 \param channel The timer channel to start (\ref tmus).
136 \retval 0 On success.
137*/
138int timer_start(int channel);
139
140/** \brief Stop a timer channel.
141 \ingroup tmu_direct
142
143 This function stops a timer channel that was started with timer_start(),
144 and as a result stops interrupts coming in from the timer.
145
146 \param channel The timer channel to stop (\ref tmus).
147 \retval 0 On success.
148*/
149int timer_stop(int channel);
150
151/** \brief Checks whether a timer channel is running.
152 \ingroup tmu_direct
153
154 This function checks whether the given timer channel is actively counting.
155
156 \param channel The timer channel to check (\ref tmus).
157 \retval 0 The timer channel is stopped.
158 \retval 1 The timer channel is running.
159*/
160int timer_running(int channel);
161
162/** \brief Obtain the count of a timer channel.
163 \ingroup tmu_direct
164
165 This function simply returns the count of the timer channel.
166
167 \param channel The timer channel to inspect (\ref tmus).
168 \return The timer's count.
169*/
171
172/** \brief Clear the underflow bit of a timer channel.
173 \ingroup tmu_direct
174
175 This function clears the underflow bit of a timer channel if it was set.
176
177 \param channel The timer channel to clear (\ref tmus).
178 \retval 0 If the underflow bit was clear (prior to calling).
179 \retval 1 If the underflow bit was set (prior to calling).
180*/
181int timer_clear(int channel);
182
183/** \brief Enable high-priority timer interrupts.
184 \ingroup tmu_direct
185
186 This function enables interrupts on the specified timer.
187
188 \param channel The timer channel to enable interrupts on (\ref tmus).
189*/
190void timer_enable_ints(int channel);
191
192/** \brief Disable timer interrupts.
193 \ingroup tmu_direct
194
195 This function disables interrupts on the specified timer channel.
196
197 \param channel The timer channel to disable interrupts on
198 (\ref tmus).
199*/
200void timer_disable_ints(int channel);
201
202/** \brief Check whether interrupts are enabled on a timer channel.
203 \ingroup tmu_direct
204
205 This function checks whether or not interrupts are enabled on the specified
206 timer channel.
207
208 \param channel The timer channel to inspect (\ref tmus).
209 \retval 0 If interrupts are disabled on the timer.
210 \retval 1 If interrupts are enabled on the timer.
211*/
212int timer_ints_enabled(int channel);
213
214/** \defgroup tmu_uptime Uptime
215 \brief Maintaining time since system boot.
216 \ingroup timers
217
218 This API provides methods for querying the current system boot time or
219 uptime since KOS started at various resolutions. You can use this timing
220 for ticks, delta time, or frame deltas for games, profilers, or media
221 decoding.
222
223 \note
224 This API is used to back the C, C++, and POSIX standard date/time
225 APIs. You may wish to favor these for platform independence.
226
227 \warning
228 This API and its underlying functionality are using \ref TMU2, so any
229 direct manipulation of it will interfere with the API's proper functioning.
230
231 \note
232 The highest actual tick resolution of \ref TMU2 is 80ns.
233*/
234
235/** \brief Structure that holds timer values in seconds + ticks. */
236typedef struct timer_value {
237 uint32_t secs; /**< \brief Number of seconds */
238 uint32_t ticks; /**< \brief Number of ticks in the current second */
240
241/** \brief Get the current uptime of the system (in seconds and ticks).
242 \ingroup tmu_uptime
243
244 This function retrieves the number of seconds and ticks since KOS was
245 started.
246
247 \return The time since KOS started as a timer_val_t.
248*/
250
251/** \brief Get the current uptime of the system (in seconds and nanoseconds).
252 \ingroup tmu_uptime
253
254 This function retrieves the time since KOS was started, in a standard
255 timespec format.
256
257 \return The time since KOS started as a struct timespec.
258*/
259static inline struct timespec arch_timer_gettime(void) {
261
262 /* Convert from ticks to nanoseconds: each clock tick is 80ns. */
263 return (struct timespec){
264 .tv_sec = time.secs,
265 .tv_nsec = (long int)(time.ticks * 80),
266 };
267}
268
269/** \defgroup tmu_primary Primary Timer
270 \brief Primary timer used by the kernel.
271 \ingroup timers
272
273 This API provides a callback notification mechanism that can be hooked into
274 the primary timer (TMU0). It is used by the KOS kernel for threading and
275 scheduling.
276
277 \warning
278 This API and its underlying functionality are using \ref TMU0, so any
279 direct manipulation of it will interfere with the API's proper functioning.
280*/
281
282/** \brief Primary timer callback type.
283 \ingroup tmu_primary
284
285 This is the type of function which may be passed to
286 timer_primary_set_callback() as the function that gets invoked
287 upon interrupt.
288*/
290
291/** \brief Set the primary timer callback.
292 \ingroup tmu_primary
293
294 This function sets the primary timer callback to the specified function
295 pointer.
296
297 \warning
298 Generally, you should not do this, as the threading system relies
299 on the primary timer to work.
300
301 \param callback The new timer callback (set to NULL to disable).
302 \return The old timer callback.
303*/
305
306/** \brief Request a primary timer wakeup.
307 \ingroup tmu_primary
308
309 This function will wake the caller (by calling the primary timer callback)
310 in approximately the number of milliseconds specified. You can only have one
311 timer wakeup scheduled at a time. Any subsequently scheduled wakeups will
312 replace any existing one.
313
314 \param millis The number of milliseconds to schedule for.
315*/
317
318/** \cond */
319/* Init function */
320int timer_init(void);
321
322/* Shutdown */
323void timer_shutdown(void);
324/** \endcond */
325
326__END_DECLS
327
328#include <kos/timer.h>
329
330#endif /* __ARCH_TIMER_H */
Various common macros used throughout the codebase.
static uint32_t("Please see purupuru_effect_t for modern equivalent.") PURUPURU_EFFECT2_UINTENSITY(uint8_t x)
Definition purupuru.h:96
void timer_disable_ints(int channel)
Disable timer interrupts.
int timer_prime(int channel, uint32_t speed, int interrupts)
Pre-initialize a timer channel, but do not start it.
int timer_running(int channel)
Checks whether a timer channel is running.
uint32_t timer_count(int channel)
Obtain the count of a timer channel.
int timer_start(int channel)
Start a timer channel.
int timer_stop(int channel)
Stop a timer channel.
void timer_enable_ints(int channel)
Enable high-priority timer interrupts.
int timer_ints_enabled(int channel)
Check whether interrupts are enabled on a timer channel.
int timer_clear(int channel)
Clear the underflow bit of a timer channel.
timer_primary_callback_t timer_primary_set_callback(timer_primary_callback_t callback)
Set the primary timer callback.
void timer_primary_wakeup(uint32_t millis)
Request a primary timer wakeup.
void(* timer_primary_callback_t)(irq_context_t *)
Primary timer callback type.
Definition timer.h:289
timer_val_t __dreamcast_get_ticks(void)
Get the current uptime of the system (in seconds and ticks).
static struct timespec arch_timer_gettime(void)
Get the current uptime of the system (in seconds and nanoseconds).
Definition timer.h:259
Timer functionality.
Interrupt and exception handling.
Architecture-specific structure for holding the processor state.
Definition irq.h:91
Structure that holds timer values in seconds + ticks.
Definition timer.h:236
uint32_t ticks
Number of ticks in the current second.
Definition timer.h:238
uint32_t secs
Number of seconds.
Definition timer.h:237
KOS-implementation of select C11 and POSIX extensions.