⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at91timer.c

📁 ARM7开发板 AT91EB01 BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* at91Timer.c - Atmel AT91 timer library */

/* Copyright 1999 ARM Limited */

/*
modification history
--------------------
01b,13jul99,jpd  minor documentation updates.
01a,25jun99,jpd  written.
*/




/* includes */

#include "at91Timer.h"
#include "drv/timer/timestampDev.h"


/* defines */

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

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

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

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


/* locals */

LOCAL FUNCPTR sysClkRoutine	= NULL; /* routine to call on clock interrupt */
LOCAL int sysClkArg		= NULL; /* its argument */
LOCAL int sysClkRunning		= FALSE;
LOCAL int sysClkConnected	= FALSE;
LOCAL int sysClkTicksPerSecond	= 60;

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

#ifdef	INCLUDE_TIMESTAMP
LOCAL BOOL	sysTimestampRunning  	= FALSE;   /* timestamp running flag */
#endif /* INCLUDE_TIMESTAMP */

/*******************************************************************************
*
* 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().
*
* RETURNS: N/A.
*/

LOCAL void sysClkInt (void)
    {
    UINT32 dummy;

    /* acknowledge interrupt: a read of the Status Register clears interrupt */

    AT91_TIMER_READ (SYS_TIMER_STATUS, dummy);


    /* If any routine is attached via sysClkConnect(), call it */

    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.  It does not enable system clock interrupts.
* Normally it is called from usrRoot() in usrConfig.c to connect
* usrClock() to the system clock interrupt.
*
* RETURNS: 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)
    	{
    	sysHwInit2 ();	/* XXX for now -- needs to be in usrConfig.c */
    	sysClkConnected = TRUE;
    	}

    sysClkRoutine = NULL; /* ensure routine not called with wrong arg */
    sysClkArg	  = arg;

#if (ARM_THUMB)
    /* set b0 so that sysClkConnect() can be used from shell */

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

    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)
	{
	/* Disable timer in Channel Control Register */

	AT91_TIMER_WRITE (SYS_TIMER_CCR, AT91_TIMER_CCR_CLKDIS);


	/* Disable Register C Compare Interrupt in the timer */

	AT91_TIMER_WRITE (SYS_TIMER_IDR, AT91_TIMER_IER_CPCS);


	/* Disable the timer interrupt in the Interrupt Controller */

	AT91_TIMER_INT_DISABLE (SYS_TIMER_INT_LVL);
	
	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 tm;

    if (!sysClkRunning)
	{
	/*
	 * Calculate the timer match value:
	 * counter match value = (clock rate / sysClkTicksPerSecond)
	 */
	
	tm = (SYS_TIMER_CLK / sysClkTicksPerSecond);


	/* Load match value into Timer Register C */

	AT91_TIMER_WRITE (SYS_TIMER_REG_C, tm);

	/*
	 * Set up Channel Mode Register: waveform mode, divide MCKI by 128,
	 * Register C compare trigger (reset counter and start counter).
	 */

	AT91_TIMER_WRITE (SYS_TIMER_CMR, (AT91_TIMER_CMR_MCKI_128 | \
					  AT91_TIMER_CMR_CPCTRG | \
					  AT91_TIMER_CMR_WAVE));

    	/* Clear Interrupt Status */

	AT91_TIMER_READ (SYS_TIMER_STATUS, tm);

	/* Enable Register C Compare Interrupt in the timer */

	AT91_TIMER_WRITE (SYS_TIMER_IER, AT91_TIMER_IER_CPCS);

	/* Enable the timer */
	
	AT91_TIMER_WRITE (SYS_TIMER_CCR, AT91_TIMER_CCR_CLKEN);

	/* Trigger the timer */

	AT91_TIMER_WRITE (SYS_TIMER_CCR, AT91_TIMER_CCR_SWTRG);


	/* enable clock interrupt in interrupt controller */

	AT91_TIMER_INT_ENABLE (SYS_TIMER_INT_LVL);
	
	sysClkRunning = TRUE;
	}
    }

/*******************************************************************************
*
* sysClkRateGet - get the system clock rate
*
* This routine returns the interrupt rate of the system clock.
*
* RETURNS: The number of ticks per second of the system clock.
*
* SEE ALSO: sysClkRateSet(), sysClkEnable()
*/

int sysClkRateGet (void)
    {
    return sysClkTicksPerSecond;
    }

/*******************************************************************************
*
* sysClkRateSet - set the system clock rate
*
* This routine sets the interrupt rate of the system clock.  It does
* not enable system clock interrupts unilaterally, but if the system
* clock is currently enabled, the clock is disabled and then enabled with
* the new rate.  Normally 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: sysClkRateGet(), sysClkEnable()
*/

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
*
* This routine handles an auxiliary clock interrupt.  It acknowledges the
* interrupt and calls the routine installed by sysAuxClkConnect().
*
* RETURNS: N/A
*/

LOCAL void sysAuxClkInt (void)
    {
    UINT32 dummy;

    /* acknowledge interrupt: a read of the Status Register clears interrupt */

    AT91_TIMER_READ (AUX_TIMER_STATUS, dummy);

    /* If any routine is attached via sysAuxClkConnect(), call it */

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

/*******************************************************************************
*
* sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
*
* This routine specifies the interrupt service routine to be called at each
* auxiliary clock interrupt.  It also connects the clock error interrupt
* service routine.
*
* RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
*
* SEE ALSO: intConnect(), sysAuxClkEnable()
*/

STATUS sysAuxClkConnect
    (
    FUNCPTR routine,    /* routine called at each aux clock interrupt */
    int arg             /* argument with which to call routine        */
    )
    {
    sysAuxClkRoutine = NULL;	/* ensure routine not called with wrong arg */
    sysAuxClkArg	= arg;

#if (ARM_THUMB)
    /* set b0 so that sysAuxClkConnect() can be used from shell */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -