📄 ppc860timer.c
字号:
/* ppc860Timer.c - PowerPC/860 timer library *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01d,22dec01,g_h Remove compilation warning01c,09oct01,dtr Removing unwanted NULLs(funcptrs) when int required. Also put in fix for SPR65678.01b,15sep01,dat Use new vxDecReload function01a,11nov97,map written from ppcDecTimer.c (v 01n), and m68360Timer.c (v 01f).*//*DESCRIPTIONThis library provides PowerPC/860 system clock, auxiliary clock, and timestampsupport.The PowerPC decrementer timer, is used to implement a system clock, and CPMTIMER2 for a 16-bit auxiliary clock. CPM timers TIMER3, and TIMER4are cascaded into a free-running 32-bit timer for timestamp support.The macro, DEC_CLOCK_FREQ, the frequency of the decrementer input clock, mustbe defined before using this module. The macro, DEC_CLK_TO_INC, the ratiobetween the number of decrementer input clock cycles and one counterincrement, may be redefined prior to including this file in sysLib.c.The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, andAUX_CLK_RATE_MAX must be defined to provide parameter checking forsysClkRateSet(), and sysAuxClkRateSet() routines.To include the timestamp timer facility, the macro INCLUDE_TIMESTAMP must bedefined. To enable dynamic bus clock rates, the BSP should set the macro,PPC_TMR_RATE_SET_ADJUST, to call an apropriate routine. This call, will bemade each time sysClkRateSet() is called. E.g. To use sysClkRateAdjust tocompute a correct value for sysDecClkFrequency. #define PPC_TMR_RATE_SET_ADJUST sysClkRateAdjust (&sysDecClkFrequency)The macro, PPC_TMR_RATE_SET_ADJUST, is by default not defined.INCLUDE FILES: timerDev.h, vxPpcLib.h SEE ALSO:.pG "Configuration"*//* includes */#include "arch/ppc/vxPpcLib.h"#include "drv/timer/timerDev.h"/* local defines */#ifndef DEC_CLK_TO_INC#define DEC_CLK_TO_INC 4 /* # bus clks per increment */#endif#ifndef DEC_CLOCK_FREQ#define DEC_CLOCK_FREQ 33333333 /* 33.33 Mhz default */#endif /* DEC_CLOCK_FREQ */#define CPM_MEM_BASE INTERNAL_MEM_MAP_ADDR/* extern declarations */IMPORT STATUS excIntConnect (VOIDFUNCPTR *, VOIDFUNCPTR);/* locals */LOCAL int sysClkTicksPerSecond = 60; /* default 60 ticks/second */LOCAL FUNCPTR sysClkRoutine = NULL;LOCAL int sysClkArg = 0;LOCAL BOOL sysClkConnectFirstTime = TRUE;LOCAL int decCountVal = 10000000; /* default dec value */LOCAL BOOL sysClkRunning = FALSE;LOCAL int sysDecClkFrequency = DEC_CLOCK_FREQ/DEC_CLK_TO_INC;LOCAL FUNCPTR sysAuxClkRoutine = NULL;LOCAL int sysAuxClkArg = 0;LOCAL BOOL sysAuxClkRunning = FALSE;LOCAL BOOL sysAuxClkIntConnected = FALSE;LOCAL int sysAuxClkTicksPerSecond = 60;#ifdef INCLUDE_TIMESTAMPLOCAL BOOL sysTimestampRunning = FALSE; /* timestamp running flag */LOCAL FUNCPTR sysTimestampRoutine = NULL;LOCAL int sysTimestampArg = 0;LOCAL BOOL sysTimestampIntConnected = FALSE;#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) {#ifdef USE_KEYED_REGS vxKeyedDecReload(decCountVal);#else vxDecReload (decCountVal); /* reload decrementer */#endif /*USE_KEYED_REGS*/ /* 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; 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); }/********************************************************************************* sysAuxClkInt - auxiliary clock interrupt handler** This routine handles the auxiliary clock interrupt. It calls a user routine* if one was specified by the routine sysAuxClkConnect().*/LOCAL void sysAuxClkInt (void) { *TER2(CPM_MEM_BASE) |= TER_REF; /* clear event register */ *CISR(CPM_MEM_BASE) = CISR_TIMER2; /* clear in-service bit */ if (sysAuxClkRoutine != NULL) (*sysAuxClkRoutine) (sysAuxClkArg); }/********************************************************************************* sysAuxClkConnect - connect a routine to the auxiliary clock interrupt** This routine specifies the interrupt service routine to be called at each* auxiliary clock interrupt. It does not enable auxiliary clock* interrupts.** RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.** SEE ALSO: intConnect(), sysAuxClkEnable()*/STATUS sysAuxClkConnect ( FUNCPTR routine, /* routine called at each aux. clock interrupt */ int arg /* argument to auxiliary clock interrupt routine */ ) { /* connect the ISR to the TIMER2 exception */ sysAuxClkRoutine = routine; sysAuxClkArg = arg; return (OK); }/********************************************************************************* sysAuxClkDisable - turn off auxiliary clock interrupts** This routine disables auxiliary clock interrupts.** RETURNS: N/A** SEE ALSO: sysAuxClkEnable()*/void sysAuxClkDisable (void) { if (sysAuxClkRunning) { *CIMR(CPM_MEM_BASE) &= ~CISR_TIMER2; /* disable interrupt */ *TGCR(CPM_MEM_BASE) |= TGCR_STP2; /* stop timer */ sysAuxClkRunning = FALSE; /* clock is no longer running */ } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -