📄 s3c2410xtimer.c
字号:
/* s3c2410xTimer.c - s3c2410x timer library *//* Copyright 2004 HITSAT, Inc. *//*DESCRIPTIONThis driver provides 3 main functions: system clock support; timestamp timer support.If necessary, each function may be conditioned by a separate INCLUDE_ macro.The timestamp function is always conditional upon the INCLUDE_TIMESTAMP macro.The macros: SYS_CLK_RATE_MIN; SYS_CLK_RATE_MAX;Must be defined to provide parameter checking for the sys[Aux]ClkRateSet() routines.*//* includes */#include "vxWorks.h"#include "config.h"#include "drv/timer/timerDev.h"#include "drv/timer/timestampDev.h"/* defines */#undef SYS_CLK_RATE_MIN#undef SYS_CLK_RATE_MAX#define SYS_CLK_RATE_MIN 1#define SYS_CLK_RATE_MAX 12000#undef AUX_CLK_RATE_MAX#undef AUX_CLK_RATE_MIN#undef INCLUDE_AUX_CLK#define INCLUDE_AUX_CLK#define AUX_CLK_RATE_MIN 1#define AUX_CLK_RATE_MAX 12000/* The default is to assume memory mapped I/O */#ifndef s3c2410x_IO_READ #define s3c2410x_IO_READ(reg,result) ((result)=*(volatile UINT32 *)(reg))#endif#ifndef s3c2410x_IO_WRITE #define s3c2410x_IO_WRITE(reg, data) (*((volatile UINT32 *)(reg))=(data))#endif/* locals */LOCAL FUNCPTR sysClkRoutine = NULL; /* routine to call on clock tick */LOCAL int sysClkArg = (int)NULL; /* its argument */LOCAL BOOL sysClkRunning = FALSE;LOCAL int sysClkConnected = FALSE;LOCAL int sysClkTicksPerSecond = 10000;LOCAL FUNCPTR sysAuxClkRoutine = NULL;LOCAL int sysAuxClkArg = 0;LOCAL BOOL sysAuxClkRunning = FALSE;LOCAL int sysAuxClkConnected = FALSE;LOCAL int sysAuxClkTicksPerSecond = 10000;IMPORT STATUS s3c2410xIntLvlVecChk (int*, int*);IMPORT STATUS s3c2410xIntLvlEnable (int);IMPORT STATUS s3c2410xIntLvlDisable (int);/* * sysClkInt - interrupt level processing for system clock * * This routine handles an auxiliary clock interrupt. It acknowledges the * interrupt and calls the routine installed by sysClkConnect(). */void sysClkInt (void){ /* call system clock service routine */ if(sysClkRoutine != NULL) { (*sysClkRoutine)(sysClkArg); } /* clear the srcpend of sysclk, and enable this level. */ /* s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, 1<<SYS_TIMER_INT_LVL); s3c2410xIntLvlEnable(SYS_TIMER_INT_LVL);*/ return;}/* * 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 */ ){ if(sysClkConnected == FALSE) { s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCFG0), TCFG0_INIT_VALUE); s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCFG1), TCFG1_INIT_VALUE); sysHwInit2(); sysClkConnected = TRUE; } sysClkRoutine = NULL; sysClkArg = arg;#if ((CPU_FAMILY == ARM) && ARM_THUMB) /* set b0 so that sysClkConnect() can be used from shell */ sysClkRoutine = (FUNCPTR)((UINT32)routine | 1);#else sysClkRoutine = routine;#endif /* CPU_FAMILY == ARM */ return (OK);}/* * sysClkDisable - turn off system clock interrupts * * This routine disables system clock interrupts. * * RETURNS: N/A * * SEE ALSO: sysClkEnable() */void sysClkDisable (void){ UINT32 tempUINT32; if(sysClkRunning) { /* Disable system timer interrupts */ s3c2410xIntLvlDisable(SYS_TIMER_INT_LVL); /* Stop timer0 */ s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); tempUINT32 &= ~(BIT_SYS_TIMER_EN); s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); 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 tempUINT32; static BOOL connected = FALSE; if(!connected) { /* TODO - connect sysClkInt to appropriate interrupt */ sysClkInt(); connected = TRUE; } if(!sysClkRunning) { /* 12207 = PCLK/(255*16); */ s3c2410x_IO_WRITE((SYS_TIMER_BASE+OFFSET_TCNTB), ((s3c2410x_PCLK/(2*250))/sysClkTicksPerSecond)); s3c2410x_IO_WRITE((SYS_TIMER_BASE+OFFSET_TCMPB), ((s3c2410x_PCLK/(2*250))/(sysClkTicksPerSecond*2))); /* Set manual update bit and reload bit, clear enable bit. */ s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); tempUINT32 |= BIT_SYS_TIMER_MU; tempUINT32 &= ~(BIT_SYS_TIMER_EN|BIT_SYS_TIMER_RE); s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); /* Set enable bit and reload bit, clear manual update bit. */ s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); tempUINT32 &= ~(BIT_SYS_TIMER_MU); tempUINT32 |= (BIT_SYS_TIMER_EN|BIT_SYS_TIMER_RE); s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); /* Enable interrupt for system timer. */ s3c2410xIntLvlEnable(SYS_TIMER_INT_LVL); 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 */ ){ /* TODO - return ERROR if rate is not supported */ if((ticksPerSecond > SYS_CLK_RATE_MAX) ||(ticksPerSecond < SYS_CLK_RATE_MIN)) { return ERROR; } else { sysClkTicksPerSecond = ticksPerSecond; if(sysClkRunning) { sysClkDisable(); sysClkEnable(); } return (OK); }}/* * sysAuxClkInt - interrupt level processing for auxiliary clock * * This routine handles an auxiliary clock interrupt. It acknowledges the * interrupt and calls the routine installed by sysAuxClkConnect(). */void sysAuxClkInt (void){ /* call auxiliary clock service routine */ if(sysAuxClkRoutine != NULL) { (*sysAuxClkRoutine)(sysAuxClkArg); } /* clear the srcpend of auxclk, and enable this level. */ s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, 1<<AUX_TIMER_INT_LVL); s3c2410xIntLvlEnable(AUX_TIMER_INT_LVL); return;}/* * sysAuxClkConnect - connect a routine to the auxiliary 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 auxiliary clock interrupt. * * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt. * * SEE ALSO: intConnect(), usrClock(), sysClkEnable() */STATUS sysAuxClkConnect ( FUNCPTR routine, /* routine to be called at each clock interrupt */ int arg /* argument with which to call routine */ ){ if(sysAuxClkConnected == FALSE) { s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCFG0), TCFG0_INIT_VALUE); s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCFG1), TCFG1_INIT_VALUE); sysHwInit2(); sysAuxClkConnected = TRUE; } sysAuxClkRoutine = NULL; sysAuxClkArg = arg;#if ((CPU_FAMILY == ARM) && ARM_THUMB) /* set b0 so that sysClkConnect() can be used from shell */ sysAuxClkRoutine = (FUNCPTR)((UINT32)routine | 1);#else sysAuxClkRoutine = routine;#endif /* CPU_FAMILY == ARM */ return (OK);}/* * sysClkDisable - turn off system clock interrupts * * This routine disables system clock interrupts. * * RETURNS: N/A * * SEE ALSO: sysClkEnable() */void sysAuxClkDisable(void){ UINT32 tempUINT32; if(sysAuxClkRunning) { /* Disable system timer interrupts */ s3c2410xIntLvlDisable(AUX_TIMER_INT_LVL); /* Stop timer0 */ s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); tempUINT32 &= ~(BIT_AUX_TIMER_EN); s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); sysAuxClkRunning = FALSE; }}/* * sysClkEnable - turn on system clock interrupts * * This routine enables system clock interrupts. * * RETURNS: N/A * * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet() */void sysAuxClkEnable(void){ UINT32 tempUINT32; static BOOL connected = FALSE; if(!connected) { intConnect(INUM_TO_IVEC(AUX_TIMER_INT_VEC), sysAuxClkInt, 0); connected = TRUE; } if(!sysAuxClkRunning) { /* 12207 = PCLK/(255*16); */ s3c2410x_IO_WRITE((AUX_TIMER_BASE+OFFSET_TCNTB), ((s3c2410x_PCLK/(2*250))/sysAuxClkTicksPerSecond)); s3c2410x_IO_WRITE((AUX_TIMER_BASE+OFFSET_TCMPB), ((s3c2410x_PCLK/(2*250))/(sysAuxClkTicksPerSecond*2))); /* Set manual update bit and reload bit, clear enable bit. */ s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); tempUINT32 |= BIT_AUX_TIMER_MU; tempUINT32 &= ~(BIT_AUX_TIMER_EN|BIT_AUX_TIMER_RE); s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); /* Set enable bit and reload bit, clear manual update bit. */ s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); tempUINT32 &= ~(BIT_AUX_TIMER_MU); tempUINT32 |= (BIT_AUX_TIMER_EN|BIT_AUX_TIMER_RE); s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32); /* Enable interrupt for system timer. */ s3c2410xIntLvlEnable(AUX_TIMER_INT_LVL); sysAuxClkRunning = 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 sysAuxClkRateGet (void){ return sysAuxClkTicksPerSecond;}/* * 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 sysAuxClkRateSet ( int ticksPerSecond /* number of clock interrupts per second */ ){ /* TODO - return ERROR if rate is not supported */ if((ticksPerSecond > AUX_CLK_RATE_MAX) ||(ticksPerSecond < AUX_CLK_RATE_MIN)) { return ERROR; } else { sysAuxClkTicksPerSecond = ticksPerSecond; if(sysAuxClkRunning) { sysAuxClkDisable(); sysAuxClkEnable(); } return (OK); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -