📄 iq80310timer.c
字号:
/* iq80310Timer.c - i80310 processor timer library *//* Copyright 2000 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01g,21jun02,scm add lock/unlock on reg access01f,23apr01,scm remove warnings01e,21mar01,scm test mod for LA3 mask for rev D1 boards...01d,24jan01,scm remove compiler warnings...01c,07dec00,scm correct timer mask...01b,06nov00,scm add tick read, mod to fit new HW corrections, etc...01a,06sep00,mar Created from ../target/src/drv/timer/ev960jxTimer.c.*//*DESCRIPTIONThis library contains routines to manipulate the timer functions. _______hardware TIMER 0clock _______ |interface ----------------------------------------------------- | | | | | |software _______ ______ _____________clock(s) sysClk auxClk timeStampClk _______ ______ _____________interface functions:clkInt() - clock interrupt handlerclkConnect() - connect a routine to the clock interruptclkDisable() - turn off system clock interruptsclkEnable() - turn on system clock interruptsclkRateGet() - get the system clock rate oscillations per secondclkPeriod() - get the period of the timer (tick counter rollover)clkFreq() - get a timer clock frequencyclkTimestamp() - get a tick counter countNote: There are two different types of ticks referred to. The frequencytick and the counter tick. The frequency tick refers to the timer clockoscillations per second and the couter ticks refer to the number of times(ticks) a register decreases until roll over.The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, and must be defined toprovide parameter checking for the sysClkRateSet() routine.Also NOTE: The current system has no suitable spare timers, thus requiringthat timestamps be derived from vxWorks system clock timer.We do not actually have an auxiliary clock available.*/#include "config.h"#include "drv/timer/timerDev.h"#ifdef INCLUDE_TIMESTAMP#include "drv/timer/timestampDev.h"#endif/* Fact is, the speed of this timer is not based on the CPU speed, but on * the pci bus clock speed. I'm making this a global variable here so it * can be configurable, even at runtime. At the time of this writing, the PCI * spec defines the max rate at 33 Mhz. */UINT32 _busClockMhz = 33;/* Locals */LOCAL int clockTicksPerSecond = 60;LOCAL UINT32 clockTimerRollOver = 1000000;LOCAL BOOL clockConnected = FALSE;LOCAL BOOL sysClkRunning = FALSE;LOCAL FUNCPTR sysClkRoutine = (FUNCPTR) NULL;LOCAL int sysClkArg = (int) NULL;LOCAL BOOL sysClkConnected = FALSE;#ifdef INCLUDE_AUX_CLK/* We do not actually have an auxiliary clock available. */LOCAL BOOL sysAuxClkRunning = FALSE;LOCAL FUNCPTR sysAuxClkRoutine = (FUNCPTR) NULL;LOCAL int sysAuxClkArg = (int) NULL;LOCAL BOOL sysAuxClkConnected = FALSE;#endif#ifdef INCLUDE_TIMESTAMPLOCAL BOOL sysTimestampRunning = FALSE;#endifextern int iq80310BoardRev (void);extern int iq80310CPLDRev (void);/**************************************************************************** clkInt - clock interrupt handler** This routine handles the clock interrupt. It is attached to the clock* interrupt vector by the routine clkConnect(). The appropriate routine* is called and the interrupts are acknowledged.*/LOCAL void clkInt (void) { if ((sysClkRoutine != NULL) && sysClkRunning) (*(FUNCPTR) sysClkRoutine) (sysClkArg); *EP310_TCR0 = IQ80310_TIMER_INT_ACK; /* acknowlege */ *EP310_TCR0 = IQ80310_TIMER_MASK_ENABLE; /* enable */ }/***************************************************************************** clkConnect - connect a routine to the clock interrupt** This routine specifies the interrupt service routine to be called at each* clock interrupt.** RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.** SEE ALSO: intConnect(), usrClock(), clkEnable()*/LOCAL STATUS clkConnect (void) { if(!clockConnected) { sysHwInit2 (); (void)intConnect ((void *)I80312INT_VEC_TIMER, clkInt, 0); clockConnected = TRUE; } return (OK); }/***************************************************************************** clkDisable - turn off system clock interrupts** This routine disables clock interrupts. In order for the hardware clock* to be disable all the software clocks must be disabled.** RETURNS: N/A** SEE ALSO: clkEnable()*/LOCAL void clkDisable (void) { int locKey; intDisable(I80312INT_VEC_TIMER); /* Lock Interrupts */ locKey = intLock(); *EP310_TCR0 = IQ80310_TIMER_MASK_DISABLE; /* UnLock Interrupts */ intUnlock (locKey); }/***************************************************************************** clkEnable - turn on system clock interrupts** This routine enables system clock interrupts. Any software clock can* enable the hardware clock** RETURNS: N/A** SEE ALSO: sysClkDisable(), sysClkRateSet()*/LOCAL void clkEnable (void) { int locKey; /* first ensure that there are only 22 bits of count data */ clockTimerRollOver &= 0x003fffff; /* Lock Interrupts */ locKey = intLock(); *EP310_TRR0 = (clockTimerRollOver & 0x000000FF); *EP310_TRR1 = ((clockTimerRollOver >> 8) & 0x000000FF); *EP310_TRR2 = ((clockTimerRollOver >> 16) & 0x0000003F); *EP310_TCR0 = IQ80310_TIMER_MASK_ENABLE; /* UnLock Interrupts */ intUnlock (locKey); intEnable(I80312INT_VEC_TIMER); }/***************************************************************************** clkRateGet - get the system clock rate** This routine returns the oscillations clock rate.** RETURNS: The number of oscillations per second of the clock.** SEE ALSO: sysClkEnable(), sysClkRateSet()*/LOCAL int clkRateGet (void) { return (clockTicksPerSecond); }/**************************************************************************** clkPeriod - get the period of the tick counter** This routine gets the period of the timer, in ticks. The* period, or terminal count, is the number of ticks to which the tick* counter counts before rolling over and restarting the counting process.** RETURNS: The period of the timer in counter ticks.*/LOCAL UINT32 clkPeriod (void) { return (clockTimerRollOver); }/**************************************************************************** clkFreq - get a timer clock frequency** This routine gets the frequency of the timer clock, in ticks per* second. The rate of the timer is set explicitly by the* hardware and typically cannot be altered.** RETURNS: The timer clock frequency, in counter ticks per second.*/LOCAL UINT32 clkFreq (void) { return (_busClockMhz * 1000000); }/**************************************************************************** clkTimestamp - get a timer tick count** This routine returns the current value of the timer tick counter.* The tick count can be converted to seconds by dividing it by the return of* clkFreq().** This routine should be called with interrupts locked.** RETURNS: The current timer tick count.** SEE ALSO: clkFreq()*/LOCAL UINT32 clkTimestamp (void) { UINT8 timer_cnt0, timer_cnt1, timer_cnt2, timer_cnt3; UINT8 timer_byte0, timer_byte1, timer_byte2, timer_byte3; UINT32 count; int locKey; /* Lock Interrupts */ locKey = intLock(); /* first read latches the count */ timer_cnt0 = ((*EP310_TRR0) & 0x5F); timer_cnt1 = ((*EP310_TRR1) & 0x5F); timer_cnt2 = ((*EP310_TRR2) & 0x5F); /* now build up the count value */ timer_byte0 = (((timer_cnt0 & 0x40) >> 1) | (timer_cnt0 & 0x1f)); timer_byte1 = (((timer_cnt1 & 0x40) >> 1) | (timer_cnt1 & 0x1f)); timer_byte2 = (((timer_cnt2 & 0x40) >> 1) | (timer_cnt2 & 0x1f)); if((iq80310BoardRev() == 0xF) && (iq80310CPLDRev() == 0x3)) { /* assume Rev D0 boards or earlier */ timer_cnt3 = ((*EP310_TRR3) & 0x33); /* only 4 bits in most sig. (bits #1,2,4,5) */ timer_byte3 = (((timer_cnt3 & 0x30) >> 2) | (timer_cnt3 & 0x03)); } else { /* assume Rev D1 boards or greater */ timer_cnt3 = ((*EP310_TRR3) & 0x0f); /* only 4 bits in most sig. (bits #1,2,3,4) */ timer_byte3 = timer_cnt3; } /* UnLock Interrupts */ intUnlock (locKey); count = ((timer_byte3 << 18) | (timer_byte2 << 12) | (timer_byte1 << 6) | timer_byte0); return (count); }/***************************************************************************** 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 called at each system clock interrupt */ int arg /* argument with which to call routine */ ) { sysClkConnected = TRUE; sysClkRoutine = routine; sysClkArg = arg; clkConnect(); return (OK); }/***************************************************************************** sysClkDisable - turn off system clock interrupts** This routine disables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkEnable()*/void sysClkDisable (void) { if (sysClkRunning) { clkDisable(); sysClkRunning = FALSE; } }/***************************************************************************** sysClkEnable - turn on system clock interrupts** This routine enables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkDisable(), sysClkRateSet()*/void sysClkEnable (void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -