📄 m8260timer.c
字号:
{
/* connect the ISR to the TIMER2 exception */
sysAuxClkRoutine = routine;
sysAuxClkArg = arg;
return (OK);
}
/*******************************************************************************
*
* sysAuxClkDisable - turn off auxiliary clock interrupts
*
* This routine disables auxiliary clock interrupts.
*
* RETURNS: N/A
*
* SEE ALSO: sysAuxClkEnable()
*/
void sysAuxClkDisable (void)
{
UINT32 immrVal = vxImmrGet();
if (sysAuxClkRunning)
{
*M8260_SIMR_L(immrVal) &= ~0x00000008; /* disable interrupt */
*M8260_TGCR1(immrVal) |= M8260_TGCR_STP2; /* stop timer */
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 immrVal = vxImmrGet();
UINT32 tempDiv = sysInputFreqGet() / (sysAuxClkTicksPerSecond << 8);
if ((!sysAuxClkRunning) && (tempDiv <= USHRT_MAX * 16))
{
/* start, reset, but disable timer2 */
*M8260_TGCR1(immrVal) &= ~(M8260_TGCR_RST2 | M8260_TGCR_STP2);
*M8260_TCN2(immrVal) = 0x0;
if (tempDiv <= USHRT_MAX)
{
*M8260_TRR2(immrVal) = (UINT16) tempDiv;
*M8260_TMR2(immrVal) = (M8260_TMR_ICLK_IN_GEN | M8260_TMR_ORI |
M8260_TMR_FRR | (M8260_TMR_PS_MSK & 0xff00));
}
else
{
*M8260_TRR2(immrVal) = (UINT16) (tempDiv / 16);
*M8260_TMR2(immrVal) = (M8260_TMR_ICLK_IN_GEN_DIV16 | M8260_TMR_ORI |
M8260_TMR_FRR | (M8260_TMR_PS_MSK & 0xff00));
}
*M8260_TER2(immrVal) = 0xffff; /* clear event */
*M8260_SIMR_L(immrVal) |= 0x00000008; /* unmask interupt */
if (! sysAuxClkIntConnected)
{
(void) intConnect (INUM_TO_IVEC(INUM_TIMER2), (VOIDFUNCPTR) sysAuxClkInt, NULL);
sysAuxClkIntConnected = TRUE;
}
*M8260_TGCR1(immrVal) |= M8260_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);
}
#endif /* INCLUDE_AUX_CLK */
#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)
{
UINT32 immrVal = vxImmrGet();
*M8260_TER4(immrVal) |= M8260_TER_REF; /* clear TMR4 reference bit */
*M8260_SIPNR_L(immrVal) = 0x00000004; /* 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)
{
UINT32 immrVal = vxImmrGet();
if (sysTimestampRunning)
{
*M8260_TCN3(immrVal) = (UINT32) 0; /* clear the counter */
return (OK);
}
if (! sysTimestampIntConnected)
{
(void) intConnect (INUM_TO_IVEC(INUM_TIMER4), (VOIDFUNCPTR) sysTimestampInt, NULL);
sysTimestampIntConnected = FALSE;
}
sysTimestampRunning = TRUE;
/* cascade timer 3 and 4 in order to get a 32 bit timer */
*M8260_TGCR2(immrVal) |= M8260_TGCR_CAS4;
/* start, reset, but disable timers 3 and 4 */
*M8260_TGCR2(immrVal) &= ~(M8260_TGCR_RST4 | M8260_TGCR_RST3 | M8260_TGCR_STP4 | M8260_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 (sysCoreFreqGet()) by 1.
*/
*M8260_TMR4(immrVal) = 0x0000 | M8260_TMR_ICLK_IN_GEN | M8260_TMR_ORI | M8260_TMR_FRR;
*M8260_TMR3(immrVal) = M8260_TMR_ICLK_IN_CAS;
*((UINT32 *)M8260_TRR3(immrVal)) = (UINT32) sysTimestampPeriod ();
*((UINT32 *)M8260_TCN3(immrVal)) = (UINT32) 0;
*M8260_TER4(immrVal) = (UINT16) 0xffff;
*M8260_SIMR_L(immrVal) |= 0x00000002;
*M8260_TGCR2(immrVal) |= M8260_TGCR_RST4 | M8260_TGCR_RST3; /* enable */
#ifdef INCLUDE_TIMESTAMP_LED
/*
* Indicate Timestamp support is enabled.
*/
sysLedOn(SYS_TIMESTAMP_LED);
#endif /* INCLUDE_TIMESTAMP_LED */
return (OK);
}
/*******************************************************************************
*
* sysTimestampDisable - turn off auxiliary clock interrupts
*
* This routine disables auxiliary clock interrupts.
*
* RETURNS: OK, always
*
* SEE ALSO: sysTimestampEnable()
*/
STATUS sysTimestampDisable (void)
{
UINT32 immrVal = vxImmrGet();
if (sysTimestampRunning)
{
*M8260_SIMR_L(immrVal) &= ~0x00000002; /* disable TIMER4 interrupt */
*M8260_SIMR_L(immrVal) &= ~0x00000004; /* disable TIMER3 interrupt */
*M8260_TGCR2(immrVal) |= M8260_TGCR_STP4; /* stop timer */
*M8260_TGCR2(immrVal) |= M8260_TGCR_STP3; /* stop timer */
sysTimestampRunning = FALSE; /* clock is no longer running */
}
#ifdef INCLUDE_TIMESTAMP_LED
/*
* Indicate Timestamp support is disabled.
*/
sysLedOff(SYS_TIMESTAMP_LED);
#endif /* INCLUDE_TIMESTAMP_LED */
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)
{
UINT32 immrVal = vxImmrGet();
/* Get the prescaler value from TMR4. TMR3 is ignored in cascade mode. */
return (sysInputFreqGet() / ((*M8260_TMR4(immrVal) >> 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)
{
UINT32 immrVal = vxImmrGet();
return (*((UINT32 *) M8260_TCN3(immrVal)));
}
/*******************************************************************************
*
* 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 immrVal = vxImmrGet();
return (*((UINT32 *) M8260_TCN3(immrVal)));
}
#endif /* INCLUDE_TIMESTAMP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -