1
0
mirror of https://github.com/deadw00d/AROS.git synced 2025-12-10 00:14:36 +00:00
Files
AROS-v0/rom/timer/timer_init.c
Matthias Rustler a131b2b09f rom: detabbed
2021-05-02 14:00:32 +02:00

122 lines
3.4 KiB
C

/*
Copyright (C) 1995-2020, The AROS Development Team. All rights reserved.
Desc: Timer startup and device commands, reference code
This code uses VBlank interrupt as a source for both units. This can be
considered a reference code for building basic timer.device implementations,
using a periodic timer. However, in real life you'll want better timing source
than 50 Hz, so you'll likely replace this with your own code.
*/
/****************************************************************************************/
#include <aros/debug.h>
#include <exec/types.h>
#include <exec/io.h>
#include <exec/errors.h>
#include <exec/devices.h>
#include <exec/alerts.h>
#include <exec/initializers.h>
#include <devices/timer.h>
#include <hardware/intbits.h>
#include <proto/exec.h>
#include <proto/execlock.h>
#include <proto/timer.h>
#include <aros/symbolsets.h>
#include LC_LIBDEFS_FILE
#include "timer_macros.h"
/* exec.library VBlank interrupt handler */
static AROS_INTH1(VBlankInt, struct TimerBase *, TimerBase)
{
AROS_INTFUNC_INIT
D(bug("%s()\n", __func__);)
/*
* First increment the current time. No need to Disable() here as
* there are no other interrupts that are allowed to interrupt us
* that can do anything with this.
*/
ADDTIME(&TimerBase->tb_CurrentTime, &TimerBase->tb_Platform.tb_VBlankTime);
ADDTIME(&TimerBase->tb_Elapsed, &TimerBase->tb_Platform.tb_VBlankTime);
TimerBase->tb_ticks_total++;
/*
* Now go to handle requests.
* We are called at rather low rate, so don't bother and process both units.
*/
handleMicroHZ(TimerBase, SysBase);
handleVBlank(TimerBase, SysBase);
return 0;
AROS_INTFUNC_EXIT
}
/****************************************************************************************/
static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR LIBBASE)
{
struct Interrupt *is;
D(bug("%s()\n", __func__);)
#if defined(__AROSEXEC_SMP__)
struct ExecLockBase *ExecLockBase;
if ((ExecLockBase = OpenResource("execlock.resource")) != NULL)
{
LIBBASE->tb_ExecLockBase = ExecLockBase;
LIBBASE->tb_ListLock = AllocLock();
}
#endif
/* If no frequency is set, assume 50Hz */
if (SysBase->VBlankFrequency == 0)
SysBase->VBlankFrequency = 50;
/*
* Here we do no checks, we simply assume we have working VBlank interrupt,
* from whatever source it is.
*/
LIBBASE->tb_eclock_rate = SysBase->VBlankFrequency;
D(bug("[timer] Timer IRQ is %d, frequency is %u Hz\n", INTB_VERTB, LIBBASE->tb_eclock_rate));
/* Calculate timer period in us */
LIBBASE->tb_Platform.tb_VBlankTime.tv_secs = 0;
LIBBASE->tb_Platform.tb_VBlankTime.tv_micro = 1000000 / LIBBASE->tb_eclock_rate;
D(bug("Timer period: %ld secs, %ld micros\n",
LIBBASE->tb_Platform.tb_VBlankTime.tv_secs, LIBBASE->tb_Platform.tb_VBlankTime.tv_micro));
/* Start up the interrupt server */
is = AllocMem(sizeof(struct Interrupt), MEMF_PUBLIC);
if (is)
{
is->is_Node.ln_Pri = 0;
is->is_Node.ln_Type = NT_INTERRUPT;
is->is_Node.ln_Name = (STRPTR)MOD_NAME_STRING;
is->is_Code = (VOID_FUNC)VBlankInt;
is->is_Data = LIBBASE;
AddIntServer(INTB_VERTB, is);
LIBBASE->tb_TimerIRQHandle = is;
return TRUE;
}
return FALSE;
}
/****************************************************************************************/
ADD2INITLIB(GM_UNIQUENAME(Init), 0)