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

📄 i8253timer.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* i8253Timer.c - Intel 8253 timer library *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01z,18apr02,hdn  added docs for the PIC IRQ0 interrupt options (spr 76411)01y,14oct01,dat  merged with VxAE 1.101x,13apr01,hdn  cleared int-request-flag in sysAuxClkEnable() (spr 34212)		 replaced the magic numbers with macros in mc146818.h01w,05apr01,hdn  changed NULL to 0 in line 86 to shut off warning (spr 65562)01v,15dec00,dat  added #includes to define CLK_RATE01u,20nov00,mks  renamed INCLUDE_TIMESTAMP to INCLUDE_TIMESTAMP_PIT2, and		 cleaned up last checkin. (SPR 62085).01t,14nov00,rcs  changed references to SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX,                 AUX_CLK_RATE_MIN, and AUX_CLK_RATE_MAX to parameters SPR 6226601s,08nov00,mks  calling sysTimestampRoutine before sysClkRoutine in sysClkInt,                 modified sysTimestampConnect to allow external agents to hook                 callback function call which will be called at timer interrupt,                 and modified init sequence of i8253 CH2 in mode 3. (SPR 62085).01r,09apr00,stv  made sysClkInt, sysAuxClkInt functions global01q,29mar00,dat  removed sysHwInit2() (vxAE)01p,28jan00,jkf  corrected build warnings.01o,08may98,hdn  fixed typo.  sysTsc..() to pentiumTsc..().01n,20apr98,hdn  added documentation for INCLUDE_TIMESTAMP_TSC.01m,09apr98,hdn  added support for Pentium, PentiumPro.01l,22jul96,dat  merged timestamp driver into normal driver.01k,23may96,wlf  doc: cleanup.01j,12feb96,hdn  added support for a channel-1 as Aux timer with PIT1_FOR_AUX.01i,25apr94,hdn  changed sysAuxClkTicksPerSecond from 60 to 64.01h,09nov93,vin  added SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN,                 AUX_CLK_RATE_MAX macros, moved intConnect of auxiliary clock		 sysLib.c; made sysAuxClkRateSet return error if any value		 other than the one in the auxTable is set. Added sysClkDisable		 and sysClkEnable in sysClkRateSet.01g,27oct93,hdn  deleted memAddToPool stuff from sysClkConnect().01f,12oct93,hdn  added sysIntEnablePIC(), sysIntDisablePIC().01e,16aug93,hdn  added aux clock functions.01d,16jun93,hdn  updated to 5.1.01c,08apr93,jdi  doc cleanup.01d,07apr93,hdn  renamed compaq to pc.01c,26mar93,hdn  added the global descriptor table, memAddToPool.		 moved enabling A20 to romInit.s. added cacheClear for 486.01b,18nov92,hdn  supported nested interrupt.01a,15may92,hdn  written based on frc386 version.*//*DESCRIPTIONThis library contains routines to manipulate the timer functions on theIntel 8253 chip with a board-independent interface.  This library handlesboth the system clock and the auxiliary clock functions.The parameters SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, andAUX_CLK_RATE_MAX must be defined to provide parameter checking for thesys[Aux]ClkRateSet() routines.The macro PIT_CLOCK must also be defined to indicate the clock frequencyof the i8253.The macro INCLUDE_TIMESTAMP_TSC lets the timestamp driver use the on-chipTSC (Timestamp Counter) in P5 (Pentium), P6 (PentiumPro, II, III), andP7 (Pentium4) family processors.  P5, P6, and P7 family processors providea 64-bit timestamp counter that is incremented every processor clock cycle.The counter is incremented even when the processor is halted by the HLTinstruction or the external STPCLK# pin.  The timestamp counter is set to0 following a hardware reset of the processor.  The RDTSC instruction readsthe timestamp counter and is guaranteed to return a monotonicallyincreasing unique value whenever executed, except for 64-bit counterwraparound.  Intel guarantees, architecturally, that the timestamp counterfrequency and configuration will be such that it will not wraparound within10 years after being reset to 0.  The period for counter wrap is severalthousands of years in P5, P6, and P7 family processors.The system clock is the programmable interrupt timer (PIT) channel 0.  Thedefault auxiliary clock is the real-time clock (RTC).The PIC(8259A) IRQ0 is hard wired to the PIT(8253) channel 0 in a PCmotherboard.  The IRQ0 is the highest priority in the 8259A interruptcontroller.  Thus, the system clock interrupt handler blocks all lowerlevel interrupts.  This may cause a delay of the lower level interrupts insome situations even though the system clock interrupt handler finishesits job in the clock period.  This is quite natural from the hardware pointof view, but may not be ideal from the application software standpoint.To mitigate this situation, the PIC(8259A) driver provides severalconfigurations in the BSP.SEE ALSO: intrCtl/i8259Intr.c*/#include "vxWorks.h"#include "sysLib.h"#include "intLib.h"#include "taskLib.h"#include "arch/i86/pentiumLib.h"#include "drv/timer/i8253.h"#include "drv/timer/mc146818.h"#if defined(INCLUDE_TIMESTAMP_PIT2) || defined(INCLUDE_TIMESTAMP_TSC)/* Locals */ LOCAL BOOL sysTimestampRunning = FALSE;		/* running flag */LOCAL int  sysTimestampPeriodValue = 0;		/* Max counter value */union uc    {    USHORT count16;    UCHAR  count08[2];    };#endif	/* INCLUDE_TIMESTAMP_PIT2 || INCLUDE_TIMESTAMP_TSC */#ifdef	INCLUDE_TIMESTAMP_TSCLOCAL FUNCPTR	sysTimestampRoutine   = NULL;	/* user rollover routine */LOCAL int   	sysTimestampTickCount = 0;	/* system ticks counter */LOCAL UINT32	sysTimestampFreqValue = PENTIUMPRO_TSC_FREQ;	/* TSC freq */#endif	/* INCLUDE_TIMESTAMP_TSC *//* locals */LOCAL FUNCPTR sysClkRoutine	= NULL; /* routine to call on clock interrupt */LOCAL int sysClkArg		= 0; /* its argument */LOCAL int sysClkRunning		= FALSE;LOCAL int sysClkConnected	= FALSE;LOCAL int sysClkTicksPerSecond	= 60;LOCAL FUNCPTR sysAuxClkRoutine	= NULL;LOCAL int sysAuxClkArg		= 0;LOCAL int sysAuxClkRunning	= FALSE;#ifdef	PIT1_FOR_AUXLOCAL int sysAuxClkTicksPerSecond = 60;#elseLOCAL int sysAuxClkTicksPerSecond = 64;LOCAL CLK_RATE auxTable[] =    {    {   2, 0x0f},     {   4, 0x0e},     {   8, 0x0d},     {  16, 0x0c},     {  32, 0x0b},     {  64, 0x0a},     { 128, 0x09},     { 256, 0x08},     { 512, 0x07},     {1024, 0x06},     {2048, 0x05},     {4096, 0x04},     {8192, 0x03}     };#endif	/* PIT1_FOR_AUX *//* forward declarations */#if	defined (INCLUDE_TIMESTAMP_TSC)LOCAL void	sysTimestampFreqGet (void);#endif	/* defined (INCLUDE_TIMESTAMP_TSC) *//********************************************************************************* sysClkInt - interrupt level processing for system clock** This routine handles the system clock interrupt.  It is attached to the* clock interrupt vector by the routine sysClkConnect().*/void sysClkInt (void)    {    /* reset TSC */#if	defined (INCLUDE_TIMESTAMP_TSC)    if (sysTimestampRoutine != NULL)          (* sysTimestampRoutine) ();#endif	/* defined (INCLUDE_TIMESTAMP_TSC) */    /* acknowledge interrupt */    if (sysClkRoutine != NULL)	(* 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.** RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.** SEE ALSO: intConnect(), usrClock(), sysClkEnable()*/STATUS sysClkConnect    (    FUNCPTR routine,	/* routine to be called at each clock interrupt */    int arg		/* argument with which to call routine */    )    {#ifdef _WRS_VXWORKS_5_X    if (sysClkConnected == FALSE)	sysHwInit2 ();	/* VxAE does this in the prjConfig */#endif    sysClkRoutine   = routine;    sysClkArg	    = arg;    sysClkConnected = TRUE;    return (OK);    }/********************************************************************************* sysClkDisable - turn off system clock interrupts** This routine disables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkEnable()*/void sysClkDisable (void)    {    int oldLevel;    if (sysClkRunning)	{        oldLevel = intLock ();				/* LOCK INTERRUPT */	sysOutByte (PIT_CMD (PIT_BASE_ADR), 0x38);	sysOutByte (PIT_CNT0 (PIT_BASE_ADR), LSB(0));	sysOutByte (PIT_CNT0 (PIT_BASE_ADR), MSB(0));        intUnlock (oldLevel);				/* UNLOCK INTERRUPT */	sysIntDisablePIC (PIT0_INT_LVL);	#ifdef	INCLUDE_TIMESTAMP_PIT2        sysOutByte (0x61, sysInByte (0x61) & 0xfe);	/* disable counter 2 */#endif	/* INCLUDE_TIMESTAMP_PIT2 */	sysClkRunning = FALSE;	}    }/********************************************************************************* sysClkEnable - turn on system clock interrupts** This routine enables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()*/void sysClkEnable (void)    {    UINT tc0;    UINT tc2;    int oldLevel;    if (!sysClkRunning)	{		tc0 = PIT_CLOCK / sysClkTicksPerSecond;        tc2 = PIT_CLOCK / sysClkTicksPerSecond * 2;        oldLevel = intLock ();				/* LOCK INTERRUPT */	sysOutByte (PIT_CMD (PIT_BASE_ADR), 0x36);	sysOutByte (PIT_CNT0 (PIT_BASE_ADR), LSB(tc0));	sysOutByte (PIT_CNT0 (PIT_BASE_ADR), MSB(tc0));#ifdef	INCLUDE_TIMESTAMP_PIT2        sysOutByte (PIT_CMD (PIT_BASE_ADR), 0xb6);        sysOutByte (PIT_CNT2 (PIT_BASE_ADR), LSB(tc2));        sysOutByte (PIT_CNT2 (PIT_BASE_ADR), MSB(tc2));                sysOutByte (0x61, sysInByte (0x61) | 1);	/* enable counter 2 */#endif	/* INCLUDE_TIMESTAMP_PIT2 */        #ifdef	INCLUDE_TIMESTAMP_TSC	sysTimestampRoutine = (FUNCPTR)pentiumTscReset;#endif	/* INCLUDE_TIMESTAMP_TSC */                intUnlock (oldLevel);				/* UNLOCK INTERRUPT */	/* enable clock interrupt */	sysIntEnablePIC (PIT0_INT_LVL);		sysClkRunning = TRUE;#if	defined (INCLUDE_TIMESTAMP_TSC)	if (sysTimestampFreqValue == 0)			/* get TSC freq */	    {	    FUNCPTR oldFunc = sysTimestampRoutine;	    sysTimestampRoutine = (FUNCPTR)sysTimestampFreqGet;	    taskDelay (sysClkTicksPerSecond + 5);	/* wait 1 sec */	    sysTimestampRoutine = oldFunc;	    }#endif	/* defined (INCLUDE_TIMESTAMP_TSC) */	}    }/********************************************************************************* 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);    sysClkTicksPerSecond = ticksPerSecond;    if (sysClkRunning)	{	sysClkDisable ();	sysClkEnable ();	}    return (OK);    }#ifdef	PIT1_FOR_AUX/********************************************************************************* sysAuxClkInt - handle an auxiliary clock interrupt** This routine handles an auxiliary clock interrupt.  It acknowledges the* interrupt and calls the routine installed by sysAuxClkConnect().** RETURNS: N/A*/void sysAuxClkInt (void)    {    /* call auxiliary clock service routine */    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 */    )    {    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)        {	sysOutByte (PIT_CMD (PIT_BASE_ADR), 0x78);	sysOutByte (PIT_CNT1 (PIT_BASE_ADR), LSB(0));	sysOutByte (PIT_CNT1 (PIT_BASE_ADR), MSB(0));	sysIntDisablePIC (PIT1_INT_LVL);		sysAuxClkRunning = FALSE;        }    }/********************************************************************************* sysAuxClkEnable - turn on auxiliary clock interrupts** This routine enables auxiliary clock interrupts.** RETURNS: N/A** SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()*/void sysAuxClkEnable (void)    {    UINT tc;

⌨️ 快捷键说明

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