📄 ppc860timer.c
字号:
sysAuxClkRunning = FALSE; /* clock is no longer running */
}
}
/*******************************************************************************
*
* sysAuxClkEnable - turn on auxiliary clock interrupts
*
* This routine enables auxiliary clock interrupts.
*
* RETURNS: N/A
*
* SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
*/
void sysAuxClkEnable (void)
{
UINT32 tempDiv = (SYS_CPU_FREQ / ((UINT32)sysAuxClkTicksPerSecond << 8)); /*lint!e778*/
if ((!sysAuxClkRunning) && (tempDiv <= USHRT_MAX * 16))
{
/* start, reset, but disable timer2 */
*TGCR(CPM_MEM_BASE) &= ~(TGCR_RST4| TGCR_STP4)/*(TGCR_RST2 | TGCR_STP2)*/;
*TCN4(CPM_MEM_BASE) = 0x0;
if (tempDiv <= USHRT_MAX)
{
*TRR4(CPM_MEM_BASE) = (UINT16) tempDiv;
*TMR4(CPM_MEM_BASE) = (TMR_ICLK_IN_GEN | TMR_ORI |
TMR_FRR | (TMR_PS_MSK & 0xff00));
}
else
{
*TRR4(CPM_MEM_BASE) = (UINT16) (tempDiv / 16);
*TMR4(CPM_MEM_BASE) = (TMR_ICLK_IN_GEN_DIV16 | TMR_ORI |
TMR_FRR | (TMR_PS_MSK & 0xff00));
}
*TER4(CPM_MEM_BASE) = 0xffff; /* clear event */
*CIMR(CPM_MEM_BASE) |= CISR_TIMER4/*CISR_TIMER2*/; /* unmask interupt */
if (! sysAuxClkIntConnected)
{
(void) intConnect (IV_TIMER4/*IV_TIMER2*/, (VOIDFUNCPTR) sysAuxClkInt, NULL);
sysAuxClkIntConnected = TRUE;
}
*TGCR(CPM_MEM_BASE) |= TGCR_RST4/*TGCR_RST2*/; /* enable timer2 */
sysAuxClkRunning = TRUE;
}
}
/*******************************************************************************
*
* sysAuxClkRateGet - get the auxiliary clock rate
*
* This routine returns the interrupt rate of the auxiliary clock.
*
* RETURNS: The number of ticks per second of the auxiliary clock.
*
* SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
*/
int sysAuxClkRateGet (void)
{
return (sysAuxClkTicksPerSecond);
}
/*******************************************************************************
*
* sysAuxClkRateSet - set the auxiliary clock rate
*
* This routine sets the interrupt rate of the auxiliary clock.
* It does not enable auxiliary clock interrupts.
*
* RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be
* set.
*
* 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
/*******************************************************************************
*
* sysTimestampInt - timestamp timer interrupt handler
*
* This rountine handles the timestamp timer interrupt. A user routine is
* called, if one was connected by sysTimestampConnect().
*
* RETURNS: N/A
*
* SEE ALSO: sysTimestampConnect()
*/
LOCAL void sysTimestampInt (void)
{
*TER4(CPM_MEM_BASE) |= TER_REF; /* clear TMR4 reference bit */
*CISR(CPM_MEM_BASE) = CISR_TIMER4; /* clear TMR4 interrupt
register bit */
if (sysTimestampRoutine != NULL) /* call user routine */
(*sysTimestampRoutine) (sysTimestampArg);
}
/*******************************************************************************
*
* sysTimestampConnect - connect a user routine to the timestamp timer interrupt
*
* This routine specifies the user interrupt routine to be called at each
* timestamp timer interrupt. It does not enable the timestamp timer itself.
*
* RETURNS: OK, or ERROR if sysTimestampInt() interrupt handler is not used.
*/
STATUS sysTimestampConnect
(
FUNCPTR routine, /* routine called at each timestamp timer interrupt */
int arg /* argument with which to call routine */
)
{
sysTimestampRoutine = routine;
sysTimestampArg = arg;
return (OK);
}
/*******************************************************************************
*
* sysTimestampEnable - initialize and enable the timestamp timer
*
* This routine connects interrupts, and enables the timer device
*
* RETURNS: TRUE always
*/
STATUS sysTimestampEnable (void)
{
if (sysTimestampRunning)
{
*TCN3(CPM_MEM_BASE) = (UINT32) 0; /* clear the counter */
return (OK);
}
if (! sysTimestampIntConnected)
{
(void) intConnect (IV_TIMER4, (VOIDFUNCPTR) sysTimestampInt, NULL);
sysTimestampIntConnected = FALSE;
}
sysTimestampRunning = TRUE;
/* cascade timer 3 and 4 in order to get a 32 bit timer */
*TGCR(CPM_MEM_BASE) |= TGCR_CAS4;
/* start, reset, but disable timers 3 and 4 */
*TGCR(CPM_MEM_BASE) &= ~(TGCR_RST4 | TGCR_RST3 | TGCR_STP4 | TGCR_STP3 );
/*
* When timers 3 and 4 are cascaded, TMR4 is the mode register, while
* TMR3 is ignored.
* Set prescaler to 0, to divide the clock (SYS_CPU_FREQ) by 1.
*/
*TMR4(CPM_MEM_BASE) = 0x0000 | TMR_ICLK_IN_GEN | TMR_ORI | TMR_FRR;
*TMR3(CPM_MEM_BASE) = TMR_ICLK_IN_CAS;
*((UINT32 *)TRR3(CPM_MEM_BASE)) = (UINT32) sysTimestampPeriod ();
*((UINT32 *)TCN3(CPM_MEM_BASE)) = (UINT32) 0;
*TER4(CPM_MEM_BASE) = (UINT16) 0xffff;
*CIMR(CPM_MEM_BASE) |= CISR_TIMER4;
*TGCR(CPM_MEM_BASE) |= TGCR_RST4 | TGCR_RST3; /* enable */
return (OK);
}
/*******************************************************************************
*
* sysTimestampDisable - turn off auxiliary clock interrupts
*
* This routine disables auxiliary clock interrupts.
*
* RETURNS: OK, always
*
* SEE ALSO: sysTimestampEnable()
*/
STATUS sysTimestampDisable (void)
{
if (sysTimestampRunning)
{
*CIMR(CPM_MEM_BASE) &= ~CISR_TIMER4; /* disable interrupt */
*CIMR(CPM_MEM_BASE) &= ~CISR_TIMER3; /* disable interrupt */
*TGCR(CPM_MEM_BASE) |= TGCR_STP4; /* stop timer */
*TGCR(CPM_MEM_BASE) |= TGCR_STP3; /* stop timer */
sysTimestampRunning = FALSE; /* clock is no longer running */
}
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 on-chip
* timer (ie the Decrementer reload value).
*/
return (0xffffffff); /* highest period -> freerunning */
}
/*******************************************************************************
*
* 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 PowerPC decrementer clock serves as the timestamp timer,
* the decrementer clock frequency is also the timestamp timer frequency.
*
* RETURNS: The timestamp timer clock frequency, in ticks per second.
*/
UINT32 sysTimestampFreq (void)
{
/* Get the prescaler value from TMR4. TMR3 is ignored in cascade mode. */
return (SYS_CPU_FREQ / ((*TMR4(CPM_MEM_BASE) >> 8) + 1));
}
/*******************************************************************************
*
* 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)
{
return (*((UINT32 *) TCN3(CPM_MEM_BASE)));
}
/*******************************************************************************
*
* 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)
{
return (*((UINT32 *) TCN3(CPM_MEM_BASE)));
}
#endif /* INCLUDE_TIMESTAMP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -