2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Timer startup and device commands, reference code
7 This code uses VBlank interrupt as a source for both units. This can be
8 considered a reference code for building basic timer.device implementations,
9 using a periodic timer. However, in real life you'll want better timing source
10 than 50 Hz, so you'll likely replace this with your own code.
13 /****************************************************************************************/
15 #include <exec/types.h>
17 #include <exec/errors.h>
18 #include <exec/devices.h>
19 #include <exec/alerts.h>
20 #include <exec/initializers.h>
21 #include <devices/timer.h>
22 #include <hardware/intbits.h>
24 #include <proto/exec.h>
25 #include <proto/timer.h>
27 #include <aros/symbolsets.h>
28 #include <aros/debug.h>
30 #include LC_LIBDEFS_FILE
32 #include "timer_macros.h"
34 /* exec.library VBlank interrupt handler */
35 static AROS_INTH1(VBlankInt
, struct TimerBase
*, TimerBase
)
40 * First increment the current time. No need to Disable() here as
41 * there are no other interrupts that are allowed to interrupt us
42 * that can do anything with this.
44 ADDTIME(&TimerBase
->tb_CurrentTime
, &TimerBase
->tb_Platform
.tb_VBlankTime
);
45 ADDTIME(&TimerBase
->tb_Elapsed
, &TimerBase
->tb_Platform
.tb_VBlankTime
);
46 TimerBase
->tb_ticks_total
++;
49 * Now go to handle requests.
50 * We are called at rather low rate, so don't bother and process both units.
52 handleMicroHZ(TimerBase
, SysBase
);
53 handleVBlank(TimerBase
, SysBase
);
60 /****************************************************************************************/
62 static int GM_UNIQUENAME(Init
)(LIBBASETYPEPTR LIBBASE
)
66 /* If no frequency is set, assume 50Hz */
67 if (SysBase
->VBlankFrequency
== 0)
68 SysBase
->VBlankFrequency
= 50;
71 * Here we do no checks, we simply assume we have working VBlank interrupt,
72 * from whatever source it is.
75 LIBBASE
->tb_eclock_rate
= SysBase
->VBlankFrequency
;
76 D(bug("[timer] Timer IRQ is %d, frequency is %u Hz\n", INTB_VERTB
, LIBBASE
->tb_eclock_rate
));
78 /* Calculate timer period in us */
79 LIBBASE
->tb_Platform
.tb_VBlankTime
.tv_secs
= 0;
80 LIBBASE
->tb_Platform
.tb_VBlankTime
.tv_micro
= 1000000 / LIBBASE
->tb_eclock_rate
;
82 D(bug("Timer period: %ld secs, %ld micros\n",
83 LIBBASE
->tb_Platform
.tb_VBlankTime
.tv_secs
, LIBBASE
->tb_Platform
.tb_VBlankTime
.tv_micro
));
85 /* Start up the interrupt server */
86 is
= AllocMem(sizeof(struct Interrupt
), MEMF_PUBLIC
);
89 is
->is_Node
.ln_Pri
= 0;
90 is
->is_Node
.ln_Type
= NT_INTERRUPT
;
91 is
->is_Node
.ln_Name
= (STRPTR
)MOD_NAME_STRING
;
92 is
->is_Code
= (VOID_FUNC
)VBlankInt
;
93 is
->is_Data
= LIBBASE
;
95 AddIntServer(INTB_VERTB
, is
);
96 LIBBASE
->tb_TimerIRQHandle
= is
;
104 /****************************************************************************************/
106 ADD2INITLIB(GM_UNIQUENAME(Init
), 0)