📄 s3c2410timer.c
字号:
/* s2410Timer.c - Atmel S2410 timer library */
/* Copyright 1999 ARM Limited */
/*
modification history
--------------------
01b,13jul99,jpd minor documentation updates.
01a,25jun99,jpd written.
*/
/*
DESCRIPTION
This library contains routines to manipulate the timer functions on a
S2410M40400 chip with a mostly board-independent interface. This driver
provides 3 main functions, system clock support, auxiliary clock
support, and timestamp timer support. The timestamp function is always
conditional upon the INCLUDE_TIMESTAMP macro.
The Atmel S2410M40400 microcontroller is a highly integrated
microcontroller, found on the Atmel S2410EB01 board. It contains three
counter/timers, clocked from possibly different sources to provide
software programmable interval timers via interrupt generation.
The three timers are 16-bit incrementers which have associated match
registers and comparators between them. In Waveform mode, in the mode
used by this driver, they increment continuously until the timer value
matches the value in register C, at which time they flag an interrupt,
reset to zero and then continue incrementing.
The timer registers are described below under the symbolic names used
herein.
At any time, the current timer values may be read from the counter value
registers.
REGISTERS:
BLOCK MODE: (read/write) controls the external clocks connected to each
channel of the block of timers.
CHANNEL CONTROL: (write only) allows enabling, disabling and triggering
of the timer channel.
CHANNEL MODE: (read/write) allows the selection of clocks to the timer
channel, the enabling of different types of triggering, and the actions
on comparison of the counter value with the different registers.
COUNTER VALUE: (read/write) contains the actual 16-bit value of the
counter for the timer channel.
REGISTER A and B: (16-bit comparison registers not used by this driver).
REGISTER C: (read/write) 16-bit comparison register containing the value
against which to match the incrementing counter value.
STATUS: (read only) contains status information for the timer channel,
e.g. on whether comparisons and triggers have occurred, overflows
etc.
INTERRUPT ENABLE: (write only)
INTERRUPT DISABLE: (write only) registers to enable and disable the
various interrupts that can be generated by each timer channel.
INTERRUPT MASK: (read only) contains information of which interrupts
are enabled.
The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
sys[Aux]ClkRateSet() routines. The following macros must also be defined:
SYS_TIMER_CLK /@ frequency of clock feeding SYS_CLK timer @/
AUX_TIMER_CLK /@ frequency of clock feeding AUX_CLK @/
SYS_TIMER_INT_LVL /@ interrupt level for sys Clk @/
AUX_TIMER_INT_LVL /@ interrupt level for aux Clk @/
The following may also be defined, if required:
S2410_TIMER_READ (reg, result) /@ read a timer register @/
S2410_TIMER_WRITE (reg, data) /@ write ... @/
S2410_TIMER_INT_ENABLE (level) /@ enable an interrupt @/
S2410_TIMER_INT_DISABLE (level) /@ disable an interrpt @/
BSP
Apart from defining such macros described above as are needed, the BSP
will need to connect the interrupt handlers (typically in sysHwInit2()).
e.g.
.CS
/@ connect sys clock interrupt and auxiliary clock interrupt @/
intConnect (INUM_TO_IVEC (INT_VEC...), sysClkInt, 0);
intConnect (INUM_TO_IVEC (INT_VEC...), sysAuxClkInt, 0);
.CE
INCLUDES:
S2410Timer.h
timestampDev.h
*/
/* includes */
#include "s3c2410Timer.h"
#include "drv/timer/timestampDev.h"
/* defines */
/* locals */
LOCAL FUNCPTR sysClkRoutine = NULL; /* routine to call on clock interrupt */
LOCAL int sysClkArg = 0; /*NULL its argument */
LOCAL int sysClkRunning = FALSE;
LOCAL int sysClkConnected = FALSE;
LOCAL int sysClkTicksPerSecond = 60;
#if 0
LOCAL FUNCPTR sysAuxClkRoutine = NULL;
LOCAL int sysAuxClkArg = 0;/*NULL;*/
LOCAL int sysAuxClkRunning = FALSE;
LOCAL int sysAuxClkTicksPerSecond = 100;
#endif
#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.
*/
void sysClkInt (void)
{
/*
static int i=0;
int j=0;
j=i % 120;
if(j==0)
Uart_Printf("%d the PendReg:%x \n",i,rINTPND);
i++;
*/
/* rTICNT=(volatile unsigned char )0;
rTICNT=(volatile unsigned char )((SYS_TIMER_CLK/sysClkTicksPerSecond-1)|(1<<7)); 此处不需要重新进行设置*/
/* If any routine is attached via sysClkConnect(), call it */
if (sysClkRoutine != NULL)
(* sysClkRoutine) (sysClkArg);
/* if(j==0)
Uart_Printf("clk int end \n");
*/
}
/*******************************************************************************
*
* 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)
{
rTICNT=0;
intDisable(INUM_TO_IVEC (INT_LVL_TICK));
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)
{
rTICNT=((volatile unsigned char )(SYS_TIMER_CLK/sysClkTicksPerSecond-1))|(1<<7);
intEnable(INUM_TO_IVEC(INT_LVL_TICK));
/* Uart_Printf("rINTMSK=%x\n",rINTMSK);
Uart_Printf("rTICNT=%x\n",rTICNT);
*/
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;
}
#ifdef INCLUDE_TIMESTAMP
/*******************************************************************************
*
* sysTimestampConnect - connect a user routine to a timestamp timer interrupt
*
* This routine specifies the user interrupt routine to be called at each
* timestamp timer interrupt.
*
* RETURNS: ERROR, always.
*/
STATUS sysTimestampConnect
(
FUNCPTR routine, /* routine called at each timestamp timer interrupt */
int arg /* argument with which to call routine */
)
{
return ERROR;
}
/*******************************************************************************
*
* sysTimestampEnable - enable a timestamp timer interrupt
*
* This routine enables timestamp timer interrupts and resets the counter.
*
* RETURNS: OK, always.
*
* SEE ALSO: sysTimestampDisable()
*/
STATUS sysTimestampEnable (void)
{
if (sysTimestampRunning)
{
return OK;
}
if (!sysClkRunning) /* timestamp timer is derived from the sysClk */
return ERROR;
sysTimestampRunning = TRUE;
return OK;
}
/*******************************************************************************
*
* sysTimestampDisable - disable a timestamp timer interrupt
*
* This routine disables timestamp timer interrupts.
*
* RETURNS: OK, always.
*
* SEE ALSO: sysTimestampEnable()
*/
STATUS sysTimestampDisable (void)
{
if (sysTimestampRunning)
sysTimestampRunning = FALSE;
return OK;
}
/*******************************************************************************
*
* sysTimestampPeriod - get the period of a timestamp timer
*
* This routine gets the period of the timestamp timer, in ticks. The
* period, or terminal count, is the number of ticks to which the timestamp
* timer counts before rolling over and restarting the counting process.
*
* RETURNS: The period of the timestamp timer in counter ticks.
*/
UINT32 sysTimestampPeriod (void)
{
/*
* The period of the timestamp depends on the clock rate of the system
* clock.
*/
return ((UINT32)(SYS_TIMER_CLK / sysClkTicksPerSecond));
}
/*******************************************************************************
*
* sysTimestampFreq - get a timestamp timer clock frequency
*
* This routine gets the frequency of the timer clock, in ticks per
* second. The rate of the timestamp timer is set explicitly by the
* hardware and typically cannot be altered.
*
* NOTE: Because the system clock serves as the timestamp timer,
* the system clock frequency is also the timestamp timer frequency.
*
* RETURNS: The timestamp timer clock frequency, in ticks per second.
*/
UINT32 sysTimestampFreq (void)
{
return ((UINT32)SYS_TIMER_CLK);
}
/*******************************************************************************
*
* sysTimestamp - get a timestamp timer tick count
*
* This routine returns the current value of the timestamp timer tick counter.
* The tick count can be converted to seconds by dividing it by the return of
* sysTimestampFreq().
*
* This routine should be called with interrupts locked. If interrupts are
* not locked, sysTimestampLock() should be used instead.
*
* RETURNS: The current timestamp timer tick count.
*
* SEE ALSO: sysTimestampFreq(), sysTimestampLock()
*/
UINT32 sysTimestamp (void)
{
UINT32 t;
return t;
}
/*******************************************************************************
*
* sysTimestampLock - lock interrupts and get the timestamp timer tick count
*
* This routine locks interrupts when the tick counter must be stopped
* in order to read it or when two independent counters must be read.
* It then returns the current value of the timestamp timer tick
* counter.
*
* The tick count can be converted to seconds by dividing it by the return of
* sysTimestampFreq().
*
* If interrupts are already locked, sysTimestamp() should be
* used instead.
*
* RETURNS: The current timestamp timer tick count.
*
* SEE ALSO: sysTimestampFreq(), sysTimestamp()
*/
UINT32 sysTimestampLock (void)
{
UINT32 t;
return t;
}
#endif /* INCLUDE_TIMESTAMP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -