📄 i8254timer.c
字号:
/* i8254Timer.c - Intel 8254 timer library *//* Copyright 1984-1997 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01d,13mar97,kkk fixed warnings. 01c,19apr95,ism added WindView timestamp support01b,14mar94,caf fixed sysClkDisable() to clear counter 0 (SPR #2859).01b,14mar94,caf changed intDisable() to intLock() (SPR #2858).01a,28sep92,caf created by moving routines from version 02e of star/sysLib.c, ansified.*//*DESCRIPTIONThis library contains routines to manipulate the timer functions on theIntel 8254 chip with a board-independent interface. This library handlesboth the system clock and the auxiliary clock functions.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 for thesys[Aux]ClkRateSet() routines.If the board includes an external write buffer, define SYS_WB_FLUSH whenincluding this driver and implement sysWbFlush() in the BSP.INTERNALThis driver is not completely board-independent. It relies on severalmacros found in the star BSP. The way interrupts are controlled may alsoreflect the organization of MIPS R3000 targets such as the star.*//* defines */#define PERIOD(x) (((10 * TIMER2_HZ / (x)) + 5) / 10) /* rounded *//* locals */LOCAL FUNCPTR sysClkRoutine = NULL; /* routine to call on clock interrupt */LOCAL int sysClkArg = NULL; /* its argument */LOCAL int sysClkTicksPerSecond = 60; /* system clock rate */LOCAL BOOL sysClkConnected = FALSE;/* hooked up to interrupt yet? */LOCAL BOOL sysClkRunning = FALSE;/* system clock enabled? */LOCAL FUNCPTR sysAuxClkRoutine = NULL; /* routine to call on clock interrupt */LOCAL int sysAuxClkArg = NULL; /* its argument */LOCAL int auxClkTicksPerSecond = 60; /* auxiliary clock rate */LOCAL BOOL auxClkConnected = FALSE;/* hooked up to interrupt yet? */LOCAL BOOL auxClkRunning = FALSE;/* auxiliary clock enabled? */#ifdef INCLUDE_TIMESTAMPLOCAL BOOL sysTimestampRunning = FALSE; /* running flag */LOCAL int sysTimestampPeriodValue = NULL; /* Max counter value */UINT32 sysTimestamp (void);#endif /* INCLUDE_TIMESTAMP *//********************************************************************************* sysClkInt - interrupt level processing for timer 0.** This routine handles the interrupts associated with the Intel 8254 chip.* It is attached to the interrupt vector by sysClkConnect().*/LOCAL void sysClkInt (void) { FAST char staleValue; /* dummy read character */ if (sysClkRoutine != NULL) (* sysClkRoutine) (sysClkArg); /* call system clock routine */ staleValue = *(volatile char *) TIM0_ACK_ADDR; /* acknowledge int */ }/********************************************************************************* sysClkConnect - connect a routine to the system clock interrupt** This routine specifies the interrupt service routine to be called at each* clock interrupt. It does not enable system clock interrupts. 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 called at each system clock interrupt */ int arg /* argument with which to call with routine */ ) { sysHwInit2 (); /* XXX for now -- needs to be in usrConfig.c */ 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) { FAST volatile TIMER *pTimer = (volatile TIMER *) TIMER_BASE_ADRS; FAST ULONG statusReg; statusReg = intLock (); /* LOCK INTERRUPTS */ if (sysClkRunning) { /* stop timer 0, actually we get one more interrupt after this */ pTimer->cntrl_word = CW_SELECT (0) | CW_BOTHBYTE | CW_MODE (MD_SWTRIGSB); pTimer->counter0 = LSB (0); pTimer->counter0 = MSB (0);#ifdef SYS_WB_FLUSH sysWbFlush ();#endif /* SYS_WB_FLUSH */#ifdef INCLUDE_TIMESTAMP sysTimestampRunning = FALSE;#endif /* INCLUDE_TIMESTAMP */ sysClkRunning = FALSE; } intUnlock (statusReg); /* UNLOCK INTERRUPTS */ }/********************************************************************************* sysClkEnable - turn on system clock interrupts** This routine enables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()*/void sysClkEnable (void) { FAST volatile TIMER *pTimer = (volatile TIMER *) TIMER_BASE_ADRS; /* Initialize timer 0, primary clock */ if (!sysClkRunning) { /* setup device */ pTimer->cntrl_word = CW_SELECT (0) | CW_BOTHBYTE | CW_MODE (MD_RATEGEN); pTimer->counter0 = LSB (PERIOD (sysClkTicksPerSecond)); pTimer->counter0 = MSB (PERIOD (sysClkTicksPerSecond));#ifdef SYS_WB_FLUSH sysWbFlush ();#endif /* SYS_WB_FLUSH */ sysClkRunning = TRUE; intEnable (INT_LVL_TIMER0); /* turn on timer 0 ints just in case */ } }/********************************************************************************* sysClkRateGet - get the system clock rate** This routine returns the interrupt rate of the system clock.** 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. Normally, 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); }/********************************************************************************* 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(), sysClkEnable()*/STATUS sysAuxClkConnect ( FUNCPTR routine, /* routine called at each aux. clock interrupt */ int arg /* argument with which to call routine */ ) { sysAuxClkRoutine = routine; sysAuxClkArg = arg; auxClkConnected = TRUE; return (OK); }/********************************************************************************* sysAuxClkDisable - turn off auxiliary clock interrupts** This routine disables auxiliary clock interrupts.** RETURNS: N/A** SEE ALSO: sysAuxClkEnable()*/ void sysAuxClkDisable (void) { FAST volatile TIMER *pTimer = (volatile TIMER *) TIMER_BASE_ADRS; FAST ULONG statusReg; statusReg = intLock (); /* turn of timer 1 ints just in case */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -