📄 m8260timer.c
字号:
* system clock by 16 or not. The 8 bit left shift accounts for * the prescaler which will always be set to 0xFF i.e. the clock * will further be divided by 256. * */ UINT32 tempDiv = SYS_CPU_FREQ / (sysAuxClkTicksPerSecond << 8); /* * Enable the auxiliary clock only if it is not already running * and if the required reference value will fit in the reference register * if the general system clock is divided by 16. */ if ((!sysAuxClkRunning) && (tempDiv < ((1 << (M8260_TRR_SIZE-1)) * 16))) { /* * start and hold in reset (i.e. disable) timer2 * Note that RST is active low while STP is active high */ *M8260_TGCR1(immrVal) &= ~M8260_TGCR_STP2; /* clear stop bit */ *M8260_TGCR1(immrVal) &= ~M8260_TGCR_RST2; /* clear reset bit */ *M8260_TCN2(immrVal) = 0x0; /* clear the timer counter */ /* * If the preliminary value for the Reference register is small * enough, we don't need to divide the general system clock by 16, * and the preliminary value for the Reference register is the * value used */ if (tempDiv < (1 << (M8260_TRR_SIZE-1))) { *M8260_TRR2(immrVal) = (UINT16) tempDiv; *M8260_TMR2(immrVal) = ( (M8260_TMR_ICLK_IN_GEN & M8260_TMR_ICLK_MSK) | /* int clk */ M8260_TMR_ORI | /* int on ref */ M8260_TMR_FRR | /* free run */ (M8260_TMR_PS_MSK & M8260_TMR_PS_MAX)); /* max prscl */ } 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 & M8260_TMR_PS_MAX)); } /* clear all timer events */ *M8260_TER2(immrVal) = M8260_TER_REF | M8260_TER_CAP; /* enable timer interrupt */ m8260IntEnable(INUM_TIMER2); if (! sysAuxClkIntConnected) { (void) intConnect (INUM_TO_IVEC(INUM_TIMER2), (VOIDFUNCPTR) sysAuxClkInt, 0); sysAuxClkIntConnected = TRUE; } /* Enable timer by removing reset, which is active low */ *M8260_TGCR1(immrVal) |= M8260_TGCR_RST2; /* set reset bit */ 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 event register */ 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, 0); sysTimestampIntConnected = TRUE; } sysTimestampRunning = TRUE; /* cascade timer 3 and 4 in order to get a 32 bit timer */ *M8260_TGCR2(immrVal) |= M8260_TGCR_CAS4; /* start and hold in reset (i.e. 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 * (SYS_CPU_FREQ) by 1. */ *M8260_TMR4(immrVal) = M8260_TMR_PS_MIN | M8260_TMR_ICLK_IN_GEN | M8260_TMR_ORI | M8260_TMR_FRR; *M8260_TMR3(immrVal) = M8260_TMR_ICLK_IN_CAS; /* * when cascaded, the combined TRR, TCR, and TCN must be referenced * with 32-bit bus cycles */ *((UINT32 *)M8260_TRR3(immrVal)) = (UINT32) sysTimestampPeriod (); *((UINT32 *)M8260_TCN3(immrVal)) = (UINT32) 0; /* clear all timer events */ *M8260_TER4(immrVal) = M8260_TER_REF | M8260_TER_CAP; /* enable timer interrupt */ m8260IntEnable(INUM_TIMER4); /* enable timer 3 and 4 */ *M8260_TGCR2(immrVal) |= (M8260_TGCR_RST3 | M8260_TGCR_RST4); 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) { m8260IntDisable(INUM_TIMER3); /* disable interrupt */ m8260IntDisable(INUM_TIMER4); /* disable interrupt */ *M8260_TGCR2(immrVal) |= M8260_TGCR_STP3; /* stop timer */ *M8260_TGCR2(immrVal) |= M8260_TGCR_STP4; /* 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.** 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. */ /* TMR4 was set in sysTimestampEnable -- comment added by fhchen */ return (SYS_CPU_FREQ / ((*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 + -