📄 m5204timer.c
字号:
/* m5204Timer.c - Timer driver for Motorola MCF5204 *//* Copyright 1984-2000 Wind River Systems, Inc. *//*modification history--------------------01c,06jul00,dh changed IMR_Tn to IMR_TIMERn throughout.01b,10jul97,mem added timestamp driver support.01a,09dec96,mem written.*//*DESCRIPTIONThis is the timer for the MCF5204 ColdFire CPU. It provides system clock,auxillary clock and timestamp functionality.If INCLUDE_M5204_SYS_CLK is defined, the system clock is provided.The macro SYS_CLK_TIMER must be defined (as 1 or 2) to select whichon-chip timer to use for the system clock. The macros SYS_CLK_RATE_MINand SYS_CLK_RATE_MAX must be defined to provide parameter checking forsysClkRateSet().If INCLUDE_M5204_AUX_CLK is defined, the auxillary clock is provided.The macro AUX_CLK_TIMER must be defined (as 1 or 2) to select whichon-chip timer to use for the auxillary clock. The macros AUX_CLK_RATE_MINand AUX_CLK_RATE_MAX must be defined to provide parameter checking forauxClkRateSet().If INCLUDE_M5204_TIMESTAMP is defined, a timestamp driver based on thesystem clock is provided. If this option is selected,INCLUDE_M5204_SYS_CLK must also be defined.*/#include "drv/multi/m5204.h"/* defines */#ifdef INCLUDE_M5204_SYS_CLK#ifndef SYS_CLK_TIMER#error "INCLUDE_M5204_SYS_CLK requires SYS_CLK_TIMER be defined"#endif#if ((SYS_CLK_TIMER != 1) && (SYS_CLK_TIMER != 2))#error "Bad value for SYS_CLK_TIMER, must be 1 or 2"#endif#endif#ifdef INCLUDE_M5204_AUX_CLK#ifndef AUX_CLK_TIMER#error "INCLUDE_M5204_AUX_CLK requires AUX_CLK_TIMER be defined"#endif#if ((AUX_CLK_TIMER != 1) && (AUX_CLK_TIMER != 2))#error "Bad value for AUX_CLK_TIMER, must be 1 or 2"#endif#endif#if (defined(INCLUDE_M5204_SYS_CLK) && defined(INCLUDE_M5204_AUX_CLK) \ && (SYS_CLK_TIMER == AUX_CLK_TIMER))#error "SYS_CLK_TIMER and AUX_CLK_TIMER must be different"#endif#if defined(INCLUDE_M5204_TIMESTAMP) && !defined(INCLUDE_M5204_SYS_CLK)#error "INCLUDE_M5204_TIMESTAMP requires INCLUDE_M5204_SYS_CLK"#endif/* locals */#ifdef INCLUDE_M5204_SYS_CLKLOCAL FUNCPTR sysClkRoutine = NULL; /* routine to call on clock int */LOCAL int sysClkArg = NULL; /* its argument */LOCAL int sysClkRunning = FALSE;LOCAL int sysClkConnected = FALSE;LOCAL int sysClkTicksPerSecond = 60;LOCAL int sysClkPrescale = 0;LOCAL int sysClkCount = 0;#endif /* INCLUDE_M5204_SYS_CLK */#ifdef INCLUDE_M5204_AUX_CLKLOCAL FUNCPTR sysAuxClkRoutine = NULL; /* routine to call on clock int */LOCAL int sysAuxClkArg = NULL; /* its argument */LOCAL int sysAuxClkRunning = FALSE;LOCAL int sysAuxClkConnected = FALSE;LOCAL int sysAuxClkTicksPerSecond = 60;LOCAL int sysAuxClkPrescale = 0;LOCAL int sysAuxClkCount = 0;#endif /* INCLUDE_M5204_AUX_CLK */#ifdef INCLUDE_M5204_TIMESTAMP#include "drv/timer/timestampDev.h"LOCAL BOOL sysTimestampRunning = FALSE; #endif /* INCLUDE_M5204_TIMESTAMP */#ifdef INCLUDE_M5204_SYS_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().*/LOCAL void sysClkInt (void) { /* Clear interrupt condition */ *M5204_TIMER_TER(SIM_BASE, SYS_CLK_TIMER) = 0x02; 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. 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 to be called at each clock interrupt */ int arg /* argument with which to call 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) { if (sysClkRunning && sysClkConnected) {#if (SYS_CLK_TIMER == 1) *M5204_SIM_IMR(SIM_BASE) |= M5204_IMR_TIMER1;#else /* (SYS_CLK_TIMER == 1) */ *M5204_SIM_IMR(SIM_BASE) |= M5204_IMR_TIMER2;#endif /* (SYS_CLK_TIMER == 1) */ /* Clear CLK1-CLK0 to stop timer. */ *M5204_TIMER_TMR(SIM_BASE, SYS_CLK_TIMER) = 0x00; 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) { if (!sysClkRunning && sysClkConnected) { /* Disable timer */ *M5204_TIMER_TMR(SIM_BASE, SYS_CLK_TIMER) = 0x00; /* Reset timer count */ *M5204_TIMER_TCN(SIM_BASE, SYS_CLK_TIMER) = 0x00; sysClkPrescale = (MASTER_CLOCK / sysClkTicksPerSecond) >> 16; sysClkCount = ((MASTER_CLOCK / (sysClkPrescale + 1)) / sysClkTicksPerSecond); /* Set reference register */ *M5204_TIMER_TRR(SIM_BASE, SYS_CLK_TIMER) = sysClkCount; /* Start timer */ *M5204_TIMER_TMR(SIM_BASE, SYS_CLK_TIMER) = 0x1b | (sysClkPrescale<<8); #if (SYS_CLK_TIMER == 1) *M5204_SIM_IMR(SIM_BASE) &= ~M5204_IMR_TIMER1;#else /* (SYS_CLK_TIMER == 1) */ *M5204_SIM_IMR(SIM_BASE) &= ~M5204_IMR_TIMER2;#endif /* (SYS_CLK_TIMER == 1) */ sysClkRunning = TRUE; } }/******************************************************************************* 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 */ ) { UINT count, prescale; if (ticksPerSecond > SYS_CLK_RATE_MAX || ticksPerSecond < SYS_CLK_RATE_MIN) return (ERROR); prescale = (MASTER_CLOCK / ticksPerSecond) >> 16; if (prescale & ~0x00ff) return (ERROR); count = (MASTER_CLOCK / (prescale + 1)) / ticksPerSecond; if (count & 0xffff0000) return (ERROR); sysClkTicksPerSecond = ticksPerSecond; if (sysClkRunning) { sysClkDisable (); sysClkEnable (); } return (OK); }#endif /* INCLUDE_M5204_SYS_CLK */#ifdef INCLUDE_M5204_AUX_CLK/******************************************************************************* sysAuxClkInt - interrupt level processing for system clock** This routine handles the aux clock interrupt. It is attached to the* clock interrupt vector by the routine sysAuxClkConnect().*/LOCAL void sysAuxClkInt (void) { /* Clear interrupt condition */ *M5204_TIMER_TER(SIM_BASE, AUX_CLK_TIMER) = 0x02; if (sysAuxClkRoutine != NULL) (* sysAuxClkRoutine) (sysAuxClkArg); }/******************************************************************************* sysAuxClkConnect - connect a routine to the aux clock interrupt** This routine specifies the interrupt service routine to be called at each* aux clock interrupt.** RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.** SEE ALSO: intConnect(), usrClock(), sysAuxClkEnable()*/STATUS sysAuxClkConnect ( FUNCPTR routine, /* routine to be called at each clock interrupt */ int arg /* argument with which to call routine */ ) { sysAuxClkRoutine = routine;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -