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

📄 m8260timerdriver.c

📁 MPC 8260 时钟驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ghM8260Timer.c - Eastcomtd M8260 Timer Library *//* Copyright 2000 Eastcomtd  *//*modification history--------------------05-05-2000 /0 DP - adapted from drv/timer/m8260Timer.c*//*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 "drv/timer/ghM8260Timer.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		FREQ_BUS	/* 66.00 Mhz default */#endif /* DEC_CLOCK_FREQ */#ifndef SYS_CPU_FREQ    #define SYS_CPU_FREQ		FREQ_BUS	/* 66.00 Mhz default */#endif /* SYS_CPU_FREQ *//* locals */LOCAL int       sysClkTicksPerSecond    = 60;     /* default 60 ticks/second */LOCAL FUNCPTR   sysClkRoutine           = NULL;LOCAL int       sysClkArg               = NULL;LOCAL BOOL      sysClkConnectFirstTime  = TRUE;LOCAL int       decCountVal             = 10000000; /* default dec value */LOCAL BOOL      sysClkRunning           = FALSE;LOCAL int       sysDecClkFrequency      = DEC_CLOCK_FREQ/DEC_CLK_TO_INC;LOCAL FUNCPTR   sysAuxClkRoutine        = NULL;LOCAL int       sysAuxClkArg            = NULL;LOCAL BOOL      sysAuxClkRunning        = FALSE;LOCAL BOOL      sysAuxClkIntConnected   = FALSE;LOCAL int       sysAuxClkTicksPerSecond = 60;#ifdef          INCLUDE_TIMESTAMPLOCAL BOOL      sysTimestampRunning     = FALSE;   /* timestamp running flag */LOCAL FUNCPTR   sysTimestampRoutine     = NULL;LOCAL int       sysTimestampArg         = NULL;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 : None*/LOCAL void sysClkInt (void){    /*     * The PowerPC decrementer doesn't reload the value by itself. The reload     * need to be performed in this handler. The reload value should be      * adjusted each time because the time spent between the exception     * generation and the moment the register is reloaded changes.     * By reading the decrementer we obtain the time spent between the      * two events and can adjust the value to reload. This is done in assembly     * language in order to minimize time spent between reading and writing     * to the decrementer register in order to maximize system clock accuracy.     */    __asm__ ("    mfdec   	3	sysClkIntLoop:    add. 	3, %0, 3    ble		sysClkIntLoop		/* check if we missed tick(s) */    mtdec	3"             :                   /* no output operands  */             : "r" (decCountVal)         /* input operand, %0 = decCountVal */             : "3", "cc"/* side-effects: r3 clobbered, 'condition code' is clobbered */            );    /* 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: None** 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: None** SEE ALSO: sysClkEnable()*/void sysClkDisable (void){    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;    /*      * compute the value to load in the decrementer. The new value will be     * loaded into the decrementer after the current period     */    /* decCountVal = sysDecClkFrequency / ticksPerSecond; */    decCountVal = ((sysDecClkFrequency + ticksPerSecond/2) / ticksPerSecond) - 1;    return(OK);}/***************************************************************************** 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 int sysAuxClkInt (void){    char *immrVal;    /* get immr value */    immrVal = vxImmrGet();    *M8260_TER2(immrVal) = M8260_TER_REF | M8260_TER_CAP; /* clear all events */    if (sysAuxClkRoutine != NULL)    {        (*sysAuxClkRoutine) (sysAuxClkArg);    }    return(IT_PROCESSED);}/***************************************************************************** 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: None** SEE ALSO: sysAuxClkEnable()*/void sysAuxClkDisable (void){    char *immrVal;    if (sysAuxClkRunning)    {        /* get immr value */        immrVal = vxImmrGet();        intDisable(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: None** SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()*/void sysAuxClkEnable (void){    char *immrVal;    /* 

⌨️ 快捷键说明

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