📄 ppc555timer.c
字号:
/* templateTimer.c - template timer library *//* Copyright 1984-2001 Wind River Systems, Inc. *//*modification history--------------------01d,15sep01,dat removed inline assembly, used vxDecReload()01c,08sep99,cmc test01b,15apr99,cmc Fixed a bug in sysAuxClkRateSet01a,15apr99,cmc ppc555Timer.c created *//*DESCRIPTIONThis library provides PowerPC/555 system clock, auxiliary clock, and timestampsupport.The PPC555 Decrementer Timer is used to implement the system clock and timestamp.The PPC555 PIT (Periodic Interrupt Timer) is used to implement the auxiliary clock.The macro DEC_CLOCK_FREQ (frequency of the decrementer input clock) should bedefined before using this module. The macro DEC_CLK_TO_INC (ratio between thenumber of decrementer input clock cycles and one counter increment) can be redefined prior to #including this file into sysLib.c.The macros SYS_CLK_RATE_MIN and SYS_CLK_RATE_MAX must be defined to provideparameter checking for sysClkRateSet().To include the timestamp timer facility, the macro INCLUDE_TIMESTAMP must bedefined. Note that changing the system clock rate will affect the timestamptimer period, which can be read by calling sysTimestampPeriod().If dynamic bus clock speed calculation is needed, the BSP can define themacro PPC_TMR_RATE_SET_ADJUST to be a call to the needed routine.This macro, if defined, will be executed during each call to sysClkRateSet().PPC_TMR_RATE_SET_ADJUST is usually not defined. e.g. Assuming sysClkRateAdjust can compute a correct value for sysDecClkFrequency. #define PPC_TMR_RATE_SET_ADJUST \ sysClkRateAdjust (&sysDecClkFrequency)INCLUDE FILES: ppc555Timer.h SEE ALSO:.pG "Configuration"*//* includes */#include "vxWorks.h"#include "config.h"#include "arch/ppc/vxPpcLib.h"#include "drv/timer/timerDev.h"#include "drv/timer/timestampDev.h"/* local defines */#ifndef DEC_CLK_TO_INC#define DEC_CLK_TO_INC 1 /* # bus clks per increment */#endif#define DEFAULT_DEC_CLK_FREQ 33333333 /* 33.33 Mhz default */#define DEC_SHIFT 0#ifndef CPU_INT_UNLOCK# define CPU_INT_UNLOCK(x) (intUnlock(x))#endif#ifndef CPU_INT_LOCK# define CPU_INT_LOCK(x) (*x = intLock())#endif/* extern declarations */IMPORT STATUS excIntConnect (VOIDFUNCPTR *, VOIDFUNCPTR);IMPORT UINT32 vxImemBaseGet();/* Locals */LOCAL int sysClkTicksPerSecond = 60; /* default 60 ticks/second */LOCAL FUNCPTR sysClkRoutine = NULL;LOCAL int sysClkArg = NULL;LOCAL BOOL sysClkConnectFirstTime = TRUE;LOCAL int decCountVal = 10000000; /* default dec value */LOCAL BOOL sysClkRunning = FALSE;LOCAL int sysDecClkFrequency = DEFAULT_DEC_CLK_FREQ/DEC_CLK_TO_INC;LOCAL FUNCPTR sysAuxClkRoutine = NULL;LOCAL int sysAuxClkArg = NULL;LOCAL BOOL sysAuxClkRunning = FALSE;LOCAL BOOL sysAuxClkIntConnected = FALSE;LOCAL int sysAuxClkTicksPerSecond = 60;#ifdef INCLUDE_TIMESTAMPLOCAL BOOL sysTimestampRunning = FALSE; /* timestamp running flag */#endif /* INCLUDE_TIMESTAMP *//********************************************************************************* sysClkInt - clock interrupt handler** This routine handles the clock interrupt on the PowerPC architecture. It is* attached to the decrementer vector by the routine sysClkConnect().** RETURNS : N/A*/LOCAL void sysClkInt (void) { vxDecReload (decCountVal); /* reload decrementer */ /* Unlock interrupts during decrementer processing */ CPU_INT_UNLOCK (_PPC_MSR_EE); /* execute the system clock routine */ if (sysClkRunning && (sysClkRoutine != NULL)) (*(FUNCPTR) sysClkRoutine) (sysClkArg); }/********************************************************************************* sysClkConnect - connect a routine to the system clock interrupt** This routine specifies the interrupt service routine to be called at each* clock interrupt. Normally, it is called from usrRoot() in usrConfig.c to* connect usrClock() to the system clock interrupt.** RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.** SEE ALSO: intConnect(), usrClock(), sysClkEnable()*/ STATUS sysClkConnect ( FUNCPTR routine, /* routine to connect */ int arg /* argument for the routine */ ) { if (sysClkConnectFirstTime) { sysHwInit2(); sysClkConnectFirstTime = FALSE; }#ifdef DEC_CLOCK_FREQ sysDecClkFrequency = DEC_CLOCK_FREQ / DEC_CLK_TO_INC;#endif /* DEC_CLOCK_FREQ */ /* connect the routine to the decrementer exception */ excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_DECR, (VOIDFUNCPTR) sysClkInt); sysClkRoutine = routine; sysClkArg = arg; return (OK); }/******************************************************************************** sysClkEnable - turn on system clock interrupts** This routine enables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()*/void sysClkEnable (void) { if (!sysClkRunning) { sysClkRunning = TRUE; vxDecSet (decCountVal); } }/******************************************************************************** sysClkDisable - turn off system clock interrupts** This routine disables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkEnable()*/void sysClkDisable (void) { if (sysClkRunning) sysClkRunning = FALSE; }/******************************************************************************** sysClkRateGet - get the system clock rate** This routine returns the system clock rate.** RETURNS: The number of ticks per second of the system clock.** SEE ALSO: sysClkEnable(), sysClkRateSet()*/int sysClkRateGet (void) { return (sysClkTicksPerSecond); }/******************************************************************************** sysClkRateSet - set the system clock rate** This routine sets the interrupt rate of the system clock. It is called* by usrRoot() in usrConfig.c.** RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.** SEE ALSO: sysClkEnable(), sysClkRateGet()*/ STATUS sysClkRateSet ( int ticksPerSecond /* number of clock interrupts per second */ ) { if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX) return (ERROR); /* save the clock speed */ sysClkTicksPerSecond = ticksPerSecond; /* Calibrate the clock, if needed. */#ifdef PPC_TMR_RATE_SET_ADJUST PPC_TMR_RATE_SET_ADJUST;#endif /* * compute the value to load in the decrementer. The new value will be * load in the decrementer after the end of the current period */ decCountVal = sysDecClkFrequency / ticksPerSecond; return (OK); }#ifdef INCLUDE_TIMESTAMP/********************************************************************************* sysTimestampConnect - connect a user routine to a timestamp timer interrupt** This routine specifies the user interrupt routine to be called at each* timestamp timer interrupt. ** NOTE: This routine has no effect, since the CPU decrementer has no* timestamp timer interrupt.** RETURNS: ERROR, always.*/STATUS sysTimestampConnect ( FUNCPTR routine, /* routine called at each timestamp timer interrupt */ int arg /* argument with which to call routine */ ) { return (ERROR); }/********************************************************************************* sysTimestampEnable - enable a timestamp timer interrupt** This routine enables timestamp timer interrupts and resets the counter.** NOTE: This routine has no effect, since the CPU decrementer has no* timestamp timer interrupt.** RETURNS: OK, always.** SEE ALSO: sysTimestampDisable()*/STATUS sysTimestampEnable (void) { if (sysTimestampRunning) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -