📄 m8260timer.c
字号:
/* m8260Timer.c - Motorola MPC8260 Timer Library *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01h,01feb05,fhc fix sysTimestampIntConnected error in sysTimestampEnable01j,25oct01,g_h Move the initialization of sysDecClkFrequency to the function sysClkRateSet, remove #include "ads8260.h", part of SPR 71123.01i,24oct01,g_h Add #ifdef INCLUDE_AUX_CLK around AUX clock routines and variables to prevent compilation warnings, part of SPR 71123.01h,15sep01,dat Using new vxDecReload function01g,16sep99,ms_ m8260Timer.h comes from drv/timer01f,09sep99,ms_ change bsp name from vads8260 to ads826001e,15jul99,ms_ make compliant with our coding standards01d,02may99,ms_ add aux clock and timestamp facility01c,17apr99,ms_ final EAR cleanup01b,14apr99,ms_ use interrupt numbers instead of vectors01a,28jan99,ms_ adapted from ppc860Timer.c version 01a*//*DESCRIPTIONThis library provides MPC8260 system clock, auxiliary clock, and timestampsupport.The PowerPC decrementer timer is used to implement the system clock, the CPMTIMER2 is used for a 16-bit auxiliary clock, and CPM timers TIMER3 and TIMER4are cascaded into a free-running 32-bit timer for timestamp support.The macro DEC_CLOCK_FREQ, the frequency of the decrementer input clock, mustbe defined before using this module. The macro DEC_CLK_TO_INC, the ratiobetween the number of decrementer input clock cycles and one counterincrement, may be redefined prior to including this file in sysLib.c.The macros SYS_CLK_RATE_MIN and SYS_CLK_RATE_MAX must be defined to provide parameter checking for sysClkRateSet() the routine.The auxiliary clock period is modified by programming the Timer ReferenceRegister. The input is the general system clock, which can be optionallydivided by 16. The prescaler is always used to divide by 256. The TimerReference Register is 16 bits. This information dictates the minimum and maximum auxiliarly clock rates.The slowest rate is when the general system clock is divided by 16 and the value for the Reference register is the highest i.e. 65535. This gives us a minimum auxiliarly clock rate of .CS SYS_CPU_FREQ / (256 * 65535 * 16) = 40000000 / 268431360 = .15.CEWe define AUX_CLK_RATE_MIN as 1The highest rate is when the general system clock is not divided by16, and the reference register is set to its minimum value i.e. 1.This tells us the maximum auxiliary clock rate:.CS SYS_CPU_FREQ / 256 = 40000000 / 256 = 156250.CEWe define AUX_CLK_RATE_MAX as 8000INCLUDE FILES: timerDev.h, vxPpcLib.h SEE ALSO:.pG "Configuration"*//* includes */#include "arch/ppc/vxPpcLib.h"#include "drv/timer/timerDev.h"#include "m8260Timer.h"/* local defines */#ifndef DEC_CLK_TO_INC#define DEC_CLK_TO_INC 4 /* # bus clks per increment */#endif#ifndef DEC_CLOCK_FREQ#define DEC_CLOCK_FREQ OSCILLATOR_FREQ /* Set to system default */#endif /* DEC_CLOCK_FREQ */#ifndef SYS_CPU_FREQ#define SYS_CPU_FREQ OSCILLATOR_FREQ /* Set to system default */#endif /* SYS_CPU_FREQ *//* extern declarations */IMPORT STATUS excIntConnect (VOIDFUNCPTR *, VOIDFUNCPTR);/* locals */LOCAL int sysClkTicksPerSecond = 60; /* default 60 ticks/second */LOCAL FUNCPTR sysClkRoutine = NULL;LOCAL int sysClkArg = 0;LOCAL BOOL sysClkConnectFirstTime = TRUE;LOCAL int decCountVal = 10000000; /* default dec value */LOCAL BOOL sysClkRunning = FALSE;LOCAL int sysDecClkFrequency = 0;#ifdef INCLUDE_AUX_CLKLOCAL FUNCPTR sysAuxClkRoutine = NULL;LOCAL int sysAuxClkArg = 0;LOCAL BOOL sysAuxClkRunning = FALSE;LOCAL BOOL sysAuxClkIntConnected = FALSE;LOCAL int sysAuxClkTicksPerSecond = 60;#endif /* INCLUDE_AUX_CLK */#ifdef INCLUDE_TIMESTAMPLOCAL BOOL sysTimestampRunning = FALSE; /* timestamp running flag */LOCAL FUNCPTR sysTimestampRoutine = NULL;LOCAL int sysTimestampArg = 0;LOCAL BOOL sysTimestampIntConnected = FALSE;#endif /* INCLUDE_TIMESTAMP *//********************************************************************************* sysClkInt - clock interrupt handler** This routine handles the clock interrupt on the PowerPC architecture. It is* attached to the decrementer vector by the routine sysClkConnect().** RETURNS : N/A*/LOCAL void sysClkInt (void) { vxDecReload (decCountVal); /* reload the decrementer */ /* execute the system clock routine */ if (sysClkRunning && (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.** RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.** SEE ALSO: intConnect(), usrClock(), sysClkEnable()*/ STATUS sysClkConnect ( FUNCPTR routine, /* routine to connect */ int arg /* argument for the routine */ ) { if (sysClkConnectFirstTime) { sysHwInit2(); sysClkConnectFirstTime = FALSE; excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_DECR, (VOIDFUNCPTR) sysClkInt); } 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) { sysClkRunning = TRUE; vxDecSet (decCountVal); } }/******************************************************************************** sysClkDisable - turn off system clock interrupts** This routine disables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkEnable()*/void sysClkDisable (void) { if (sysClkRunning) 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 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; /* Calibrate the clock, if needed. */#ifdef PPC_TMR_RATE_SET_ADJUST PPC_TMR_RATE_SET_ADJUST;#endif sysDecClkFrequency = DEC_CLOCK_FREQ / DEC_CLK_TO_INC; /* * compute the value to load in the decrementer. The new value will be * loaded into the decrementer after the current period */ decCountVal = sysDecClkFrequency / ticksPerSecond; return (OK); }#ifdef INCLUDE_AUX_CLK/********************************************************************************* sysAuxClkInt - auxiliary clock interrupt handler** This routine handles the auxiliary clock interrupt. It calls a user routine* if one was specified by the routine sysAuxClkConnect().*/LOCAL void sysAuxClkInt (void) { UINT32 immrVal = vxImmrGet(); *M8260_TER2(immrVal) = M8260_TER_REF | M8260_TER_CAP; /* clear all events */ 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 */ ) { /* connect the ISR to the TIMER2 exception */ 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) { UINT32 immrVal = vxImmrGet(); if (sysAuxClkRunning) { m8260IntDisable(INUM_TIMER2); *M8260_TGCR1(immrVal) |= M8260_TGCR_STP2; /* stop timer */ sysAuxClkRunning = FALSE; /* clock is no longer running */ } }/********************************************************************************* sysAuxClkEnable - turn on auxiliary clock interrupts** This routine enables auxiliary clock interrupts.* The timer is used in "reference mode" i.e. a value is programmed into * the reference register and an interrupt occurs when the timer reaches* that value. ** RETURNS: N/A** SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()*/void sysAuxClkEnable (void) { UINT32 immrVal = vxImmrGet(); /* * Calculate the preliminary value for the Reference register. This * does not yet take into account whether we will divide the general
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -