📄 coldfiretimer.c
字号:
/* coldfireTimer.c - Timer driver for Motorola ColdFire processors *//* Copyright 1984-1998 Wind River Systems, Inc. *//*modification history--------------------01c,29jan02,dee fixed typecasting to clean up compiler warnings int<->uint merge in T2.1.0 changes SET_IMR_BIT, CLEAR_IMR_BIT01b,09jul98,gls Adapted to WRS coding conventions01a,19apr98,mem written, based on m5204Timer and m5206Timer.*//*DESCRIPTIONThis is the timer for the ColdFire CPUs. It provides system clock,auxillary clock and timestamp functionality.If INCLUDE_COLDFIRE_SYS_CLK is defined, the system clock is provided.The macros SYS_CLK_RATE_MIN and SYS_CLK_RATE_MAX must be defined toprovide parameter checking for sysClkRateSet().If INCLUDE_COLDFIRE_AUX_CLK is defined, the auxillary clock is provided.The macros AUX_CLK_RATE_MINand AUX_CLK_RATE_MAX must be defined to provide parameter checking forauxClkRateSet().If INCLUDE_COLDFIRE_TIMESTAMP is defined, a timestamp driver based on thesystem clock is provided. If this option is selected,INCLUDE_COLDFIRE_SYS_CLK must also be defined.*/#include "drv/timer/coldfireTimer.h"/* defines */#ifndef SET_IMR_BIT /* allows BSP to define this macro */#define SET_IMR_BIT(pTimer) \ do \ { \ if ((pTimer)->imrSize == 1) \ *(volatile UINT8 *) (pTimer)->imr |= (pTimer)->imrMask; \ else if ((pTimer)->imrSize == 2) \ *(volatile UINT16 *) (pTimer)->imr |= (pTimer)->imrMask; \ else \ *(volatile UINT32 *) (pTimer)->imr |= (pTimer)->imrMask; \ } while (0)#endif /* SET_IMR_BIT */#ifndef CLEAR_IMR_BIT /* allows BSP to define this macro */#define CLEAR_IMR_BIT(pTimer) \ do \ { \ if ((pTimer)->imrSize == 1) \ *(volatile UINT8 *) (pTimer)->imr &= ~(pTimer)->imrMask; \ else if ((pTimer)->imrSize == 2) \ *(volatile UINT16 *) (pTimer)->imr &= ~(pTimer)->imrMask; \ else \ *(volatile UINT32 *) (pTimer)->imr &= ~(pTimer)->imrMask; \ } while (0)#endif /* CLEAR_IMR_BIT *//* locals */#ifdef INCLUDE_COLDFIRE_SYS_CLKLOCAL COLDFIRE_TIMER sysClkTimer;LOCAL 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_COLDFIRE_SYS_CLK */#ifdef INCLUDE_COLDFIRE_AUX_CLKLOCAL COLDFIRE_TIMER auxClkTimer;LOCAL 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_COLDFIRE_AUX_CLK */#ifdef INCLUDE_COLDFIRE_TIMESTAMP#include "drv/timer/timestampDev.h"LOCAL BOOL sysTimestampRunning = FALSE; #endif /* INCLUDE_COLDFIRE_TIMESTAMP */#ifdef INCLUDE_COLDFIRE_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 */ *sysClkTimer.ter = COLDFIRE_TER_REF; 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 */ ) { /* XXX for now -- needs to be in usrConfig.c */ if (!sysClkConnected) sysHwInit2 (); 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) { SET_IMR_BIT(&sysClkTimer); /* Clear CLK1-CLK0 to stop timer. */ *sysClkTimer.tmr = 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 */ *sysClkTimer.tmr = 0x00; /* Reset timer count */ *sysClkTimer.tcn = 0x00; sysClkPrescale = (MASTER_CLOCK / sysClkTicksPerSecond) >> 16; sysClkCount = ((MASTER_CLOCK / (sysClkPrescale + 1)) / sysClkTicksPerSecond); /* Set reference register */ *sysClkTimer.trr = (UINT16)sysClkCount; /* Start timer */ *sysClkTimer.tmr = (UINT16)(COLDFIRE_TMR_ORI | COLDFIRE_TMR_FRR | COLDFIRE_TMR_CLK_BUS | COLDFIRE_TMR_EN | (sysClkPrescale << 8)); CLEAR_IMR_BIT(&sysClkTimer); 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_COLDFIRE_SYS_CLK */#ifdef INCLUDE_COLDFIRE_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 */ *auxClkTimer.ter = COLDFIRE_TER_REF; 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 (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -