📄 ppcdectimer.c
字号:
/***************************************************************************
*
* $RCSfile: ppcDecTimer.c $
*
* Copyright 2001 by Dy 4 Systems, Inc. All Rights Reserved.
*
* $Revision: 1.7 $
*
* $Name: AV4-ISP-R1.2-1 AV4-ISP-R1.2-0 HMTST2 HMTST1 DVT_AV4_4.101 AV4-VSP-R1.0-2 AV4-VSP-R1.0 CT-ISP-1.1 AV4 ISP 1.1 CT_R0.1_AV4/CAV4 champtools2.22 CAV4_CP1 CHAMPtools FW 3.0 champtools2.21_1215 champtools2.21 champ221_build1 champtools2.2 CHAMPtools_2.1.1_AV3 CHAMPtools_2.1_106 CHAMPtools_2.0_AV3 $ $State: Developmental $ $Locker: $
*
* $Source: L:/SWRND/champAV2/src/vx/src/drv/timer/rcs/ppcDecTimer.c $
*
* RCS Project Name:
*
* CSC:
*
* Target:
*
* Description:
*
* Usage:
*
* $Log: ppcDecTimer.c $
* Revision 1.7 2004/01/21 21:03:44Z dsessler
* Removed timestampDev.h and obsolete comments re. timestamp
* and auxtimer drivers.
* Revision 1.6 2002/05/08 16:00:09 coopertr
* Revision 1.5 2002/03/27 20:02:31 dsessler
*
****************************************************************************/
/* Copyright 1984-1997 Wind River Systems, Inc. */
#include "copyright_wrs.h"
/*
modification history
--------------------
01o,03mar98,jgn Re-enable interrupts during system clock tick processing
(SPR #10000)
01n,04nov96,tam renamed MEMORY_BUS_SPEED to DEC_CLOCK_FREQ, BUS_CLK_TO_INC
to DEC_CLK_TO_INC and DEFAULT_BUS_SPEED to DEFAULT_DEC_CLK_FREQ
(spr #7423).
01m,29oct96,wlf doc: cleanup.
01l,31jul96,dat added PPC_TMR_RATE_SET_ADJUST
01k,22jul96,tam cleanup. added timestamp support. Changed CPU_SPEED macro to
MEMORY_BUS_SPEED.
01j,17jun96,tpr optimized sysClkInt() assembly code.
01i,14may96,tam fixed drift in sysClkInt. Changed DEFAULT_CPU_SPEED to
33333333 (33.33 Mhz)
01h,11mar96,ms fixed roundoff in sysClkInt.
01g,12feb96,tpr reworked.
01f,23oct95,kvk cleanup.
01e,22may95,caf added conditional compile for PowerPC 601.
01d,02may95,caf cleanup.
01c,27apr95,caf removed vxDecEnable() and PPC60x_TIMER_INT_VECTOR,
changed name to ppcDecTimer.c.
01b,25jan95,vin cleanup.
01a,20jan95,kvk written.
*/
/*
DESCRIPTION
This library provides PowerPC decrementer timer routines.
The macro DEC_CLOCK_FREQ (frequency of the decrementer input clock) should be
defined before using this module. The macro DEC_CLK_TO_INC (ratio between the
number 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 provide
parameter checking for sysClkRateSet().
If dynamic bus clock speed calculation is needed, the BSP can define the
macro 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: ppcDecTimer.h
SEE ALSO:
.pG "Configuration"
*/
/* includes */
#include "arch/ppc/vxPpcLib.h"
#include "drv/timer/ppcDecTimer.h"
/* local defines */
#define DEFAULT_HZ 60
#define DEFAULT_FREQ (133333333/4)
#define DEFAULT_COUNT (DEFAULT_FREQ/DEFAULT_HZ)
#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);
/* Locals */
LOCAL int sysClkTicksPerSecond = DEFAULT_HZ; /* ticks per sec */
LOCAL FUNCPTR sysClkRoutine = NULL;
LOCAL int sysClkArg = 0;
LOCAL BOOL sysClkConnectFirstTime = TRUE;
LOCAL int decCountVal = DEFAULT_COUNT;
LOCAL BOOL sysClkRunning = FALSE;
LOCAL int sysDecClkFrequency = DEFAULT_FREQ;
/* Dino M. Change 11/17/2005 Macro Definition per Wind River */
#ifdef __DCC__
asm void ClkIntMacro (decountVal)
{
% lab sysClkIntLoop; reg decountVal;
!"r3", "r0"
mfdec 0
sysClkIntLoop:
add. 0, 3, 0
ble sysClkIntLoop
mtdec 0
}
#endif
/* End Of Dino M. Change */
/*******************************************************************************
*
* 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)
{
/* int decr;*/
/*
* The PowerPC decrementer doesn't reload the value by itself. The reload
* need to be performed in this handler. The reload value should be
* adjusted each time because the time spent between the exception
* generation and the moment the register is reloaded changes.
* By reading the decrementer we obtain the time spent between the
* two events and can adjust the value to reload. This is done in assembly
* language in order to minimize time spent between reading and writing
* to the decrementer register in order to maximize system clock accuracy.
*/
#ifdef __DCC__
ClkIntMacro (decCountVal);
#else
int decr;
__asm__ ("mfdec %0" : "=r" (decr));
while ( 0 > decr )
{
decr += decCountVal;
}
__asm__ ( "mtdec %0" : : "r" (decr) );
/*
__asm__ ("
mfdec 3
sysClkIntLoop:
add. 3, %0, 3
ble sysClkIntLoop
mtdec 3"
:
: "r" (decCountVal)
: "3", "cc"
);
*/
#endif
/* 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;
}
sysDecClkFrequency = bslBoardGetBusSpeed()/4;
/* 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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -