s3c2410xTimer.c
上传用户:ske666
上传日期:2022-03-30
资源大小:371k
文件大小:10k
- /* s3c2410xTimer.c - s3c2410x timer library */
- /* Copyright 2004 HITSAT, Inc. */
- /*
- DESCRIPTION
- This 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);
- }
- }