⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppc403timer.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ppc403Timer.c - PowerPC 403 timer library *//* Copyright 1984-1997 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01o,19sep01,pch  SPR 20698, 69142, 69143:  TSR is write-to-clear,		 not read/modify/writeback01n,25sep97,ms2  corrected sysAuxClkTicksPerSecond (spr 9348)01m,16jul97,tam  add code to enable change of sysClk rate on the fly for GCX. 01l,07may97,tam  added use of IS_CPU_403GCX macro. 01k,17apr97,dat  rework on SYS_CLK_FREQ, fixed SPR 8372 - extra calls to		 excIntConnect.01j,09apr97,mkw  add support for 403GCX01i,24mar97,tam  replace excCrtConnect by excIntCrtConnect in sysWdtConnect().01h,08nov96,wlf  doc: cleanup.01g,07oct96,tam  fixed spr 7242: declared sysBusClkFrequency as a LOCAL.01f,02jul96,tam  added code to make system clock more accurate. Added		 timestamp support.01e,19mar96,tam  fixed sysAuxClkEnable() & sysWdtClkEnable().01d,12mar96,tam  changed excIntConnect to excIntConnectTimer for FIT & PIT.01c,11mar96,tam  added functions for the watchdog timer (WDT).01b,07mar96,tam  added functions for the auxiliary clock (FIT).01a,20feb96,tpr  written, inspired from ppcDecTimer.c version 01g.*//*DESCRIPTIONThis library provides PowerPC 403 Timer routines.  This library handlesthe system clock, the auxiliary clock and timestamp functions. Toinclude the timestamp timer facility, the macro INCLUDE_TIMESTAMP mustbe defined.The macro SYS_CLK_FREQ should be defined before usingthis module.  This macro is the rate at which clock ticks occur.  Fordouble clocked busses, this value should be half the actual clock speed.The macro PIT_CORRECTION is needed to adjust the reload value to accountfor the latency delay between generation of the interrupt and the timeto actually enter the service routine.  If not defined, an approximatevalue is calculated from the SYS_CLK_FREQ value.  The calculated valuefor a 25Mhz clock is a 9 microsecond correction.The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN,and AUX_CLK_RATE_MAX must be defined to provideparameter checking for sysClkRateSet().The BSP is responsible for connecting the interrupt handlers, sysClkInt(),and sysAuxClkInt(), to the appropriate vectors.INCLUDE FILES: ppc403Timer.hSEE ALSO:.pG "Configuration"*//* includes */#include "vxLib.h"#include "intLib.h"#include "drv/timer/ppc403Timer.h"#include "arch/ppc/ppc403.h"#include "drv/timer/timestampDev.h"/* local defines *//* System clock speed, default is 25 MHz */#ifndef	SYS_CLK_FREQ#   define SYS_CLK_FREQ		25000000#endif/* * The PIT_CORRECTION is expressed in nanoseconds.  It is used * to correct the reload value for the 403GA and 403GC cpus * which don't have an autoreload feature on the PIT clock.  It accounts * for the latency time between when the interrupt was generated and when * the interrupt handler was entered. */#ifndef PIT_CORRECTION#   define PIT_CORRECTION	(225000000 / (SYS_CLK_FREQ / 1000))#endif/* IS_CPU_403GCX returns TRUE if the CPU is a 403GCX, FALSE otherwise */#ifndef IS_CPU_403GCX#   define IS_CPU_403GCX      ((vxPvrGet() & (_PVR_CCF_MSK | _PVR_PCF_MSK)) \                              == (_PVR_CONF_403GCX << 8) ? 1:0)#endif/* Auxiliary clock default rate */#ifndef AUX_CLK_RATE_DEFAULT#   define AUX_CLK_RATE_DEFAULT 10#endif/* extern declarations *//* Locals */LOCAL FIT_PERIOD fitTable[] =                   /* available FIT periods */    {    {   (1 << 9),  0x00000000},    {   (1 << 13), 0x01000000},    {   (1 << 17), 0x02000000},    {   (1 << 21), 0x03000000},    };LOCAL WDT_PERIOD wdtTable[] =                   /* available WDT periods */    {    {   (1 << 17), 0x00000000},    {   (1 << 21), 0x40000000},    {   (1 << 25), 0x80000000},    {   (1 << 29), 0xC0000000},    };LOCAL int 	sysClkTicksPerSecond 	= 60;	/* default 60 ticks/second */LOCAL FUNCPTR	sysClkRoutine		= NULL;LOCAL int	sysClkArg		= NULL;LOCAL BOOL	sysClkConnectFirstTime	= TRUE;LOCAL BOOL	sysClkRunning 		= FALSE;LOCAL BOOL	sysClkReload		= TRUE;LOCAL BOOL	sysClkReloadOnce	= FALSE;LOCAL int 	sysAuxClkTicksPerSecond = AUX_CLK_RATE_DEFAULT;LOCAL FUNCPTR	sysAuxClkRoutine	= NULL;LOCAL int	sysAuxClkArg		= NULL;LOCAL BOOL	sysAuxClkRunning 	= FALSE;LOCAL int 	sysWdtTicksPerSecond	= 1;LOCAL FUNCPTR	sysWdtRoutine		= NULL;LOCAL int	sysWdtArg		= NULL;LOCAL BOOL	sysWdtRunning 		= FALSE;LOCAL UINT32	sysBusClkFrequency 	= TIMER_CLK_FREQ;LOCAL UINT32	pitCountVal;			/* PIT counter value */LOCAL UINT32 	fitPeriodMask = 0x01000000;	/* default FIT period: 2^21 */LOCAL UINT32	wdtPeriodMask = 0xC0000000;	/* default WDT period: 2^29 */LOCAL UINT32	pitCorrection;#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 403 architecture. It* is attached to the Programmable Interval Timer vector by the routine* sysClkConnect().** RETURNS : N/A*/LOCAL void sysClkInt (void)    {    vxPitIntAck ();            	/* acknowledge PIT interrupt */    /*     * Since the auto-reload feature of the PIT seems not to work properly     * for non-GCX it is necessary to reload the Programmable Interrupt Timer.     * The reload value should be adjusted each time because the time spent     * between the exception generation and the moment the register is reloaded     * changes.     * Since the PIT does not keep decrementing after it reaches 0 we cannot     * read it again and adjust pitCountVal. The current correction corresponds     * to the average time spend between the exception generation and the     * moment the register is reloaded. A better solution would be to use     * the time base to calculate that value dynamically but that requires     * adding code to the PPC interrupt stub routine.     */    if (sysClkReload)	vxPitSet(pitCountVal - pitCorrection);    if (sysClkReloadOnce)	{	vxPitSet(pitCountVal);		/* reload the PIT once after a call */	sysClkReloadOnce = FALSE;	/* to sysClkRateSet() for GCX cpu   */	}    /* execute the system clock routine */    if (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.  It also connects the* clock error interrupt service routine.** RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.** SEE ALSO: usrClock(), sysClkEnable()*/STATUS sysClkConnect    (    FUNCPTR 	routine,	/* routine to connect */    int 	arg		/* argument with which to call the routine */    )    {    if (sysClkConnectFirstTime)	{	sysHwInit2();	sysClkConnectFirstTime = FALSE;	}    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)	{	/* clear the pending PIT interrupt */	vxTsrSet (_PPC403_TSR_PIS);	/* load the PIT counter and the hidden register with interval value */	vxPitSet (pitCountVal);	/* Enable the PIT interrupt & enable autoreload for 403GCX */	if (IS_CPU_403GCX)	    {	    vxTcrSet (vxTcrGet() | _PPC403_TCR_PIE | _PPC403_TCR_ARE);	    sysClkReload = FALSE;	    }	else	    vxTcrSet (vxTcrGet() | _PPC403_TCR_PIE);	/* set the running flag */	sysClkRunning = TRUE;	}    }/******************************************************************************** sysClkDisable - turn off system clock interrupts** This routine disables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkEnable()*/void sysClkDisable (void)    {    if (sysClkRunning)	{	/* disable the PIT interrupt and auto-reload capability */	vxTcrSet (vxTcrGet() & ~ (_PPC403_TCR_PIE | _PPC403_TCR_ARE));	/* clear the PIT counter */	vxPitSet (0);	/* clear the pending PIT interrupt */	vxTsrSet (_PPC403_TSR_PIS);	/* reset the running flag */	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 does not* enable system clock interrupts.  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;    /*     * compute the value to load in the decrementor. The new value will be     * load in the decrementor after the end of the current period     */    if (vxIocrGet () & _PPC403_IOCR_TCSM)	sysBusClkFrequency = TIMER_CLK_FREQ;    else	sysBusClkFrequency = SYS_CLK_FREQ;    pitCountVal = sysBusClkFrequency / ticksPerSecond;    pitCorrection = (((sysBusClkFrequency / 1000000) *		    PIT_CORRECTION) / 1000);    if (IS_CPU_403GCX)	sysClkReloadOnce = TRUE;	/* reload the PIT with new value */    return (OK);    }/********************************************************************************* sysAuxClkInt - auxilary clock interrupt handler** This routine handles the auxilary clock interrupt on the PowerPC 403* architecture. It is attached to the Fix Interval Timer vector by the routine* sysAuxClkConnect().** RETURNS : N/A*/LOCAL void sysAuxClkInt (void)    {    vxFitIntAck ();             /* acknowledge FIT interrupt */    /* program TCR with the FIT period */    vxTcrSet ((vxTcrGet() & ~_PPC403_TCR_FP) | fitPeriodMask);    /* execute the system clock routine */    if (sysAuxClkRoutine != NULL)	(*(FUNCPTR) 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: excIntConnectTimer(), sysAuxClkEnable()*/STATUS sysAuxClkConnect    (    FUNCPTR routine,	/* routine called at each aux. clock interrupt */    int     arg		/* argument to auxiliary clock interrupt */    )    {    sysAuxClkRoutine	= routine;    sysAuxClkArg	= arg;    return (OK);    }/********************************************************************************* sysAuxClkEnable - turn on auxiliary clock interrupts** This routine enables auxiliary clock interrupts.** RETURNS: N/A** SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()*/void sysAuxClkEnable (void)    {    if (!sysAuxClkRunning)	{	/* clear the pending FIT interrupt */	vxTsrSet (_PPC403_TSR_FIS);	/* program TCR with the FIT period */	vxTcrSet ((vxTcrGet() & ~_PPC403_TCR_FP) | fitPeriodMask);	/* Enable the FIT interrupt */	vxTcrSet (vxTcrGet() | _PPC403_TCR_FIE);	/* set the running flag */	sysAuxClkRunning = TRUE;	}    }/********************************************************************************* sysAuxClkDisable - turn off auxiliary clock interrupts** This routine disables auxiliary clock interrupts.*** RETURNS: N/A** SEE ALSO: sysAuxClkEnable()*/void sysAuxClkDisable (void)    {    if (sysAuxClkRunning)	{	/* disable the FIT interrupt */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -