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

📄 sa1100timer.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* sa1100Timer.c - Digital Semiconductor SA-1100 timer library *//* Copyright 1997-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01j,14oct01,dat  added #includes to stand alone01i,22feb01,jpd  made auxClk support dependent on INCLUDE_AUX_CLK (SPR #64165).01h,16nov00,sbs  corrected docs for vxWorks AE.01g,17apr00,jpd  made sysClkInt, sysAuxClkInt functions global.01f,29mar00,dat  removed sysHwInit2()01e,05jan00,jpd  fixed warnings from new definition of NULL. Comments changes.01d,23apr98,cdp  updated comment about reload correction value.01c,22apr98,cdp  lock ints around reload of match register (preemptive ints);		 add reload correction.01b,19mar98,cdp  removed unused variable in sysTimestampInt; fix typo in docn.01a,10dec97,cdp  created from 01f of ambaTimer.c.*//*DESCRIPTIONThis library contains routines to manipulate the OS timer functions ofthe SA-1100 with a mostly board-independent interface. This driverprovides 3 main functions, system clock support, auxiliary clocksupport, and timestamp timer support.  The timestamp function is alwaysconditional upon the INCLUDE_TIMESTAMP component.The SA-1100 provides a free-running 32-bit counter, which counts upfrom zero, and four 32-bit match registers each of which can cause aninterrupt when its value matches the value of the counter.The SA-1100 also provides a watchdog timer which is not used by VxWorks.The SA-1100 timer registers are described below under the symbolicnames used herein.SA1100_TIMER_CSR_OSCR (read/write): this is the "OS Timer CountRegister" (OSCR) described in the SA-1100 Data Sheet.  This register,which can be read or written at any time, increments at 3.6864 MHz.SA1100_TIMER_CSR_OSMR[0..3] (read/write): these are the "OS Timer MatchRegisters" (OSMR[0..3]) described in the SA-1100 Data Sheet.  Theseregisters, which can be read or written at any time, are compared withthe counter every tick.  For each match register whose contents matchthe counter, the corresponding event bit in the status register isset.  Match registers 0, 1 and 2 are used for the system, auxiliary andtimestamp clocks respectively.SA1100_TIMER_CSR_OSSR (read/write): this is the "OS Timer StatusRegister" (OSSR) described in the SA-1100 Data Sheet.  When thisregister is read, each data bit that is set (1) indicates a matchregister that matches the counter register; unused bits read as 0.When this register is written, each data bit that is set (1) clears thecorresponding timer match event;  bits that are clear (0) have noeffect.SA1100_TIMER_CSR_OIER (read/write): this is the "OS Timer InterruptEnable Register" (OIER) described in the SA-1100 Data Sheet.  When thisregister is written, each data bit that is set (1) enables theinterrupt when the corresponding match register matches the counter;data bits that are clear (0) do not clear the corresponding interruptif the interrupt is already asserted.  When this register is read, eachdata bit that is set (1) indicates that the corresponding timer matchinterrupt is enabled; each data bit that is clear (0) indicates thatthe corresponding timer match interrupt is disabled.Note that the timestamp facility is provided by OSMR[2] and so isindependent of the system clock.This driver assumes that the chip is memory-mapped and does directmemory access to the registers which are assumed to be 32 bits wide.If a different access method is needed, the BSP can redefine the parametersSA1100_TIMER_REG_READ(addr,result) and SA1100_TIMER_REG_WRITE(addr,data).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 following parameters must also be defined:.CS SYS_TIMER_CLK			/@ frequency of clock feeding SYS_CLK timer @/ AUX_TIMER_CLK			/@ frequency of clock feeding AUX_CLK @/ TIMESTAMP_TIMER_CLK		/@ frequency of clock feeding TIMESTAMP_CLK @/ SYS_TIMER_INT_LVL		/@ interrupt level for sys Clk @/ AUX_TIMER_INT_LVL		/@ interrupt level for aux Clk @/ TIMESTAMP_TIMER_INT_LVL	/@ interrupt level for timestamp Clk @/ SA1100_TIMER_CSR_OSCR		/@ addresses of timer registers @/ SA1100_TIMER_CSR_OSMR_0	/@ "" @/ SA1100_TIMER_CSR_OSMR_1	/@ "" @/ SA1100_TIMER_CSR_OSMR_2	/@ "" @/ SA1100_TIMER_CSR_OSSR		/@ "" @/ SA1100_TIMER_CSR_OIER		/@ "" @/.CEThe following may also be defined, if required:.CS SA1100_TIMER_REG_READ(reg, data)	/@ read a timer register @/ SA1100_TIMER_REG_WRITE(reg, data)	/@ write ... @/ SA1100_TIMER_INT_ENABLE(level)		/@ enable an interrupt @/ SA1100_TIMER_INT_DISABLE(level)	/@ disable an interrpt @/.CEBSPApart from defining such parameters described above as are needed, the BSPmust connect the interrupt handlers (typically in sysHwInit2()).e.g..CS    /@ connect sys clock interrupt and auxiliary clock interrupt @/    intConnect (INUM_TO_IVEC (INT_VEC...), sysClkInt, 0);    @ifdef INCLUDE_AUX_CLK    intConnect (INUM_TO_IVEC (INT_VEC...), sysAuxClkInt, 0);    @endif.CEINCLUDES:sa1100Timer.htimestampDev.hSEE ALSO:.I "Digital StrongARM SA-1100 Portable Communications Microcontroller, DataSheet,"*//* includes */#include "vxWorks.h"#include "sysLib.h"#include "intLib.h"#include "drv/timer/sa1100Timer.h"#include "drv/timer/timestampDev.h"/* defines */#ifndef SA1100_TIMER_REG_READ#define SA1100_TIMER_REG_READ(reg, result) \	((result) = *(volatile UINT32 *)(reg))#endif /* SA1100_TIMER_REG_READ */#ifndef SA1100_TIMER_REG_WRITE#define SA1100_TIMER_REG_WRITE(reg, data) \	(*((volatile UINT32 *)(reg)) = (data))#endif /* SA1100_TIMER_REG_WRITE */#ifndef SA1100_TIMER_INT_ENABLE#define SA1100_TIMER_INT_ENABLE(level) intEnable(level)#endif#ifndef SA1100_TIMER_INT_DISABLE#define SA1100_TIMER_INT_DISABLE(level) intDisable(level)#endif/* * A correction to account for average reload delays. This is necessary * because the timer hardware does not reload itself and so any delays * caused by interrupt latency etc. will stretch the gap between ticks. * The value chosen ensures that the timer is accurate enough to pass the * BSP Validation Suite on a 200MHz Brutus board.  If required, the * reload code could be changed to read both counter and match registers * and work out a suitable match register reload value based on the * difference between the two. */#ifndef SA1100_TIMER_RELOAD_CORRECTION#define SA1100_TIMER_RELOAD_CORRECTION 6#endif/* 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 UINT32 sysClkTicks;		/* ticks of counter per interrupt */#ifdef INCLUDE_AUX_CLKLOCAL FUNCPTR sysAuxClkRoutine	= NULL;LOCAL int sysAuxClkArg		= 0;LOCAL int sysAuxClkRunning	= FALSE;LOCAL int sysAuxClkTicksPerSecond = 100;LOCAL UINT32 sysAuxClkTicks;		/* ticks of counter per interrupt */#endif /* INCLUDE_AUX_CLK */#ifdef	INCLUDE_TIMESTAMPLOCAL BOOL	sysTimestampRunning 	= FALSE; /* timestamp running flag */LOCAL FUNCPTR	sysTimestampRoutine	= NULL;	 /* routine to call on intr */LOCAL int	sysTimestampArg		= 0;	 /* arg for routine */#endif /* INCLUDE_TIMESTAMP */#if !defined(SYS_CLK_RATE_MIN)		|| \    !defined(SYS_CLK_RATE_MAX)		|| \    !defined(SYS_TIMER_CLK)		|| \    !defined(TIMESTAMP_TIMER_CLK)	|| \    !defined(SYS_TIMER_INT_LVL)		|| \    !defined(TIMESTAMP_TIMER_INT_LVL)	|| \    !defined(SA1100_TIMER_CSR_OSCR)	|| \    !defined(SA1100_TIMER_CSR_OSMR_0)	|| \    !defined(SA1100_TIMER_CSR_OSMR_1)	|| \    !defined(SA1100_TIMER_CSR_OSMR_2)	|| \    !defined(SA1100_TIMER_CSR_OSSR)	|| \    !defined(SA1100_TIMER_CSR_OIER)#   error missing SA-1100 timer definitions#endif#ifdef INCLUDE_AUX_CLK#if !defined(AUX_CLK_RATE_MIN)		|| \    !defined(AUX_CLK_RATE_MAX)		|| \    !defined(AUX_TIMER_CLK)		|| \    !defined(AUX_TIMER_INT_LVL)#   error missing SA-1100 Aux timer definitions#endif#endif /* INCLUDE_AUX_CLK *//********************************************************************************* 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().** RETURNS: N/A.*/void sysClkInt (void)    {    UINT32 tc;    int key;    /* clear interrupt */    SA1100_TIMER_REG_WRITE (SA1100_TIMER_CSR_OSSR, 1);    /*     * Load the match register with a new value calculated by     * adding the ticks per interrupt to the current value of the     * counter register.  Note that this may wraparound to a value     * less than the current counter value but that's OK.     */    key = intLock ();    SA1100_TIMER_REG_READ (SA1100_TIMER_CSR_OSCR, tc);    tc += sysClkTicks;    SA1100_TIMER_REG_WRITE (SA1100_TIMER_CSR_OSMR_0, tc);    /* read the match register to work around the bug in pre 2.1 silicon */    SA1100_TIMER_REG_READ (SA1100_TIMER_CSR_OSMR_0, tc);    intUnlock (key);    /* If any routine attached via sysClkConnect(), call it */    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.  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 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 prjConfig */    	}#endif    sysClkConnected = TRUE;    sysClkRoutine = NULL; /* ensure routine not called with wrong arg */    sysClkArg	  = arg;    sysClkRoutine = routine;    return OK;    }/********************************************************************************* sysClkDisable - turn off system clock interrupts** This routine disables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkEnable()*/void sysClkDisable (void)    {    UINT32 oier;    int key;    if (sysClkRunning)	{	/* disable timer interrupt in the timer */	key = intLock ();	SA1100_TIMER_REG_READ (SA1100_TIMER_CSR_OIER, oier);	SA1100_TIMER_REG_WRITE (SA1100_TIMER_CSR_OIER, oier & ~(1 << 0));	intUnlock (key);	/* clear any pending interrupt */	SA1100_TIMER_REG_WRITE (SA1100_TIMER_CSR_OSSR, 1 << 0);	/* disable timer interrupt in the interrupt controller */	SA1100_TIMER_INT_DISABLE (SYS_TIMER_INT_LVL);	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)    {    UINT32 tc, oier;    int key;    if (!sysClkRunning)	{	/*	 * Calculate the number of ticks of the timer clock that this	 * period requires.  Do this once, here, so that the timer interrupt	 * routine does not need to perform a division.	 */	sysClkTicks = (SYS_TIMER_CLK / sysClkTicksPerSecond) -						SA1100_TIMER_RELOAD_CORRECTION;	/* clear any pending interrupt */	SA1100_TIMER_REG_WRITE (SA1100_TIMER_CSR_OSSR, 1 << 0);	/*	 * Load the match register with a new value calculated by	 * adding the ticks per interrupt to the current value of the	 * counter register.  Note that this may wraparound to a value	 * less than the current counter value but that's OK.	 */	key = intLock ();	SA1100_TIMER_REG_READ (SA1100_TIMER_CSR_OSCR, tc);	tc += sysClkTicks;	SA1100_TIMER_REG_WRITE (SA1100_TIMER_CSR_OSMR_0, tc);	/* read the match register to work around the bug in per 2.1 silicon */	SA1100_TIMER_REG_READ (SA1100_TIMER_CSR_OSMR_0, tc);	/* enable interrupt in timer */	SA1100_TIMER_REG_READ (SA1100_TIMER_CSR_OIER, oier);	SA1100_TIMER_REG_WRITE (SA1100_TIMER_CSR_OIER, oier | (1 << 0));	intUnlock (key);	/* enable clock interrupt in interrupt controller */	SA1100_TIMER_INT_ENABLE (SYS_TIMER_INT_LVL);	sysClkRunning = TRUE;	}    }/********************************************************************************* 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: sysClkRateSet(), sysClkEnable()*/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 unilaterally, but if the system clock is* currently enabled, the clock is disabled and then re-enabled with the new* rate.  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: sysClkRateGet(), sysClkEnable()*/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 INCLUDE_AUX_CLK/********************************************************************************* 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)    {    UINT32 tc;

⌨️ 快捷键说明

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