www.pudn.com > S3c2410bsp.zip > s3c2410xTimer.c


/* s3c2410xTimer.c - Samsung S3C2410X timer library */



/* Copyright 1984-2001 Wind River Systems, Inc. */
#include "copyright_wrs.h"




/* includes */

#include "vxWorks.h"
#include "config.h"
#include "drv/timer/timerDev.h"
#include "drv/timer/timestampDev.h"
#include "s3c2410xTimer.h"


#ifndef S3C2410X_TIMER_REG_READ
#define S3C2410X_TIMER_REG_READ(reg, result) \
    ((result) = *(volatile UINT32 *)(reg))
#endif /*S3C2410X_TIMER_READ*/

#ifndef S3C2410X_TIMER_REG_WRITE
#define S3C2410X_TIMER_REG_WRITE(reg, data) \
    (*((volatile UINT32 *)(reg)) = (data))
#endif /*S3C2410X_TIMER_WRITE*/

#ifndef S3C2410X_TIMER_INT_ENABLE
#define S3C2410X_TIMER_INT_ENABLE(level) intEnable(level)
#endif

#ifndef S3C2410X_TIMER_INT_DISABLE
#define S3C2410X_TIMER_INT_DISABLE(level) intDisable(level)
#endif


/* locals */

LOCAL FUNCPTR sysClkRoutine    = NULL; 
LOCAL int sysClkArg            = (int)NULL; 
LOCAL int sysClkRunning        = FALSE;
LOCAL int sysClkConnected      = FALSE;
LOCAL int sysClkTicksPerSecond = 60;

LOCAL FUNCPTR sysAuxClkRoutine    = NULL;
LOCAL int sysAuxClkArg            = (int)NULL;
LOCAL int sysAuxClkRunning        = FALSE;
LOCAL int sysAuxClkTicksPerSecond = 100;
LOCAL int sysAuxClkTicks;



#ifdef INCLUDE_TIMESTAMP

LOCAL BOOL      sysTimestampRunning     = FALSE;         
LOCAL FUNCPTR   sysTimestampRoutine     = NULL;         
LOCAL int       sysTimestampArg         = 0;            
void      sysTimestampInt (void);                  

#endif  /* INCLUDE_TIMESTAMP */


/*******************************************************************************
*
* sysClkInt - interrupt level processing for system clock
*/

void sysClkInt (void)
    {


    if (sysClkRoutine != NULL)
        (* sysClkRoutine) (sysClkArg);
    }


/*******************************************************************************
*
* sysClkConnect - connect a routine 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,   
    int arg        
    )
    {


    if (sysClkConnected == FALSE)
        {
        S3C2410X_TIMER_REG_WRITE (S3C2410X_TCFG0, 0x00003f3f); 
        S3C2410X_TIMER_REG_WRITE (S3C2410X_TCFG1, 0x00000000);
        S3C2410X_TIMER_REG_WRITE (S3C2410X_TCON, 0x00000000);
        
        sysHwInit2 ();
        sysClkConnected = TRUE;
        }

    sysClkRoutine   = NULL;
    sysClkArg        = arg;

#if ((CPU_FAMILY == ARM) && ARM_THUMB)
    sysClkRoutine = (FUNCPTR)((UINT32)routine | 1);
#else
    sysClkRoutine = routine;
#endif /* CPU_FAMILY == ARM */

    return (OK);

}


/*******************************************************************************
*
* sysClkDisable - turn off system clock interrupts
*
*
* RETURNS: N/A
*
* SEE ALSO: sysClkEnable()
*/

void sysClkDisable (void)
    {

    
    if (sysClkRunning)
        {
		S3C2410X_TIMER_REG_WRITE (S3C2410X_TCON, 0x00000000);
		
    
        S3C2410X_TIMER_INT_DISABLE (SYS_TIMER_INT_LVL);

        sysClkRunning = FALSE;
        }
    }


/*******************************************************************************
*
* sysClkEnable - turn on system clock interrupts
*
*
* RETURNS: N/A
*
* SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
*/

void sysClkEnable (void)
    {

    if (!sysClkRunning)
        {

		S3C2410X_TIMER_REG_WRITE (S3C2410X_TCNTB0, (375*(1000/sysClkTicksPerSecond)));
        S3C2410X_TIMER_REG_WRITE (S3C2410X_TCON, 0x00000002);
		S3C2410X_TIMER_REG_WRITE (S3C2410X_TCON, 0x00000009);
        
        
        S3C2410X_TIMER_INT_ENABLE (SYS_TIMER_INT_LVL);
        sysClkRunning = TRUE;
        }
    }



/*******************************************************************************
*

*
* SEE ALSO: sysClkEnable(), sysClkRateSet()
*/

int sysClkRateGet (void)
    {
    return (sysClkTicksPerSecond);
    }




/*******************************************************************************
*
*
* 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);

    sysClkTicksPerSecond = ticksPerSecond;

    if (sysClkRunning)
        {
        sysClkDisable ();
        sysClkEnable ();
        }

    return (OK);
    }

/*******************************************************************************
*
* sysAuxClkInt - handle an auxiliary clock interrupt
*
* RETURNS: N/A
*/

void sysAuxClkInt (void)
    {
    /* call auxiliary clock service routine */

    if (sysAuxClkRoutine != NULL)
        (*sysAuxClkRoutine) (sysAuxClkArg);

    }

/*******************************************************************************
*
* sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
*
*
* SEE ALSO: intConnect(), sysAuxClkEnable()
*/

STATUS sysAuxClkConnect
    (
    FUNCPTR routine,    /* routine called at each aux clock interrupt */
    int arg             /* argument to auxiliary clock interrupt routine */
    )
    {
    sysAuxClkRoutine    = NULL;
    sysAuxClkArg        = arg;

#if ((CPU_FAMILY == ARM) && ARM_THUMB)
    sysAuxClkRoutine = (FUNCPTR)((UINT32)routine | 1);
#else
    sysAuxClkRoutine = routine;
#endif /* CPU_FAMILY == ARM */

    return (OK);
    }

/*******************************************************************************
*
* RETURNS: N/A
*
* SEE ALSO: sysAuxClkEnable()
*/

void sysAuxClkDisable (void)
    {
    
    if (sysAuxClkRunning)
        {

        S3C2410X_TIMER_INT_DISABLE (AUX_TIMER_INT_LVL);

        sysAuxClkRunning = FALSE;
        }
    }

/*******************************************************************************
*
*
* RETURNS: N/A
*
* SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
*/

void sysAuxClkEnable (void)
    {
    static BOOL connected = FALSE;

    if (!connected)
        {
        intConnect (INUM_TO_IVEC (INT_LVL_TIMER1), sysAuxClkInt, 0);
        connected = TRUE;
        }

    if (!sysAuxClkRunning)
        {

        sysAuxClkTicks = (AUX_TIMER_CLK / sysAuxClkTicksPerSecond);

        S3C2410X_TIMER_INT_ENABLE (AUX_TIMER_INT_LVL);

        sysAuxClkRunning = TRUE;
        }
    }

/*******************************************************************************
*
* SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
*/

int sysAuxClkRateGet (void)
    {
    return (sysAuxClkTicksPerSecond);
    }

/*******************************************************************************
*
*
* SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
*/

STATUS sysAuxClkRateSet
    (
    int ticksPerSecond  /* number of clock interrupts per second */
    )
    {
    if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
        return (ERROR);

    sysAuxClkTicksPerSecond = ticksPerSecond;

    if (sysAuxClkRunning)
        {
        sysAuxClkDisable ();
        sysAuxClkEnable ();
        }

    return (OK);
    }

#ifdef  INCLUDE_TIMESTAMP

/*******************************************************************************
*
* RETURNS: N/A
*
* SEE ALSO: sysTimestampConnect()
*/

void sysTimestampInt (void)
    {
    if (sysTimestampRunning && sysTimestampRoutine != NULL)
        (*sysTimestampRoutine)(sysTimestampArg);
    }

/*******************************************************************************
*
* RETURNS: OK, or ERROR if sysTimestampInt() interrupt handler is not used.
*/

STATUS sysTimestampConnect
    (
    FUNCPTR routine,    
    int arg     /* argument with which to call routine */
    )
    {
    return ERROR;    /* System clock tick specifies a rollover event */
    }

/*******************************************************************************
*
* sysTimestampEnable - initialize and enable the timestamp timer
*
*
* RETURNS: OK, or ERROR if hardware cannot be enabled.
*/

STATUS sysTimestampEnable (void)
    {

    if (!sysTimestampRunning)
        {
        sysTimestampRunning = TRUE;
        }

    sysClkEnable();    /* make sure that system clock is running */

    return (OK);
    }

/*******************************************************************************
*
* sysTimestampDisable - disable the timestamp timer
*
*
* RETURNS: OK, or ERROR if timer cannot be disabled.
*/

STATUS sysTimestampDisable (void)
    {
    if (sysTimestampRunning)
        sysTimestampRunning = FALSE;

    return (OK);
    }

/*******************************************************************************
*
* sysTimestampPeriod - get the timestamp timer period
*
* RETURNS: The period of the timestamp timer in counter ticks.
*/

UINT32 sysTimestampPeriod (void)
    {
    return (SYS_TIMER_CLK / sysClkTicksPerSecond);
    }

/*******************************************************************************
*
* sysTimestampFreq - get the timestamp timer clock frequency
* RETURNS: The timestamp timer clock frequency, in ticks per second.
*/

UINT32 sysTimestampFreq (void)
    {
    return (SYS_TIMER_CLK);
    }

/*******************************************************************************
*
* sysTimestamp - get the timestamp timer tick count
*
*
* RETURNS: The current timestamp timer tick count.
*
* SEE ALSO: sysTimestampLock()
*/

UINT32 sysTimestamp (void)
    {
    UINT32 count;

	S3C2410X_TIMER_REG_READ (S3C2410X_TCNTO0, count);
	
    return (sysTimestampPeriod() - count);
    }

/*******************************************************************************
*
* sysTimestampLock - get the timestamp timer tick count
*
* RETURNS: The current timestamp timer tick count.
*
* SEE ALSO: sysTimestamp()
*/

UINT32 sysTimestampLock (void)
    {
    UINT32 result;

    result = sysTimestamp ();

    return (result);
    }

#endif  /* INCLUDE_TIMESTAMP */