ev960jxTimer.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:16k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* ev960jxTimer.c - i960 processor timer library */
  2. /* Copyright 1984-1997 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01f,21may97,db   moved intConnect from sysTimestampConnect to 
  8.  sysTimestampEnable.(SPR #8400)
  9. 01e,03jan97,wlf  doc: more cleanup.
  10. 01d,17jul96,tmk  fixed casting of TIMER_ROLL_OVER - made arithmetic work.
  11. 01c,23may96,wlf  doc: cleanup.
  12. 01b,05jan96,myz  removed intConnect in xxxClkEnable routine.
  13. 01a,20mar95,kvk  Created.
  14. */
  15. /*
  16. DESCRIPTION
  17. This library contains routines to manipulate the timer functions on the
  18. ep960jx and hx with a board-independent interface.  This library handles both
  19. the system clock and the auxiliary clock functions.
  20. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  21. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  22. sys[Aux]ClkRateSet() routines.
  23. */
  24. /* Move the following into /ev960jxTimer.h when created */
  25. /* Timer Reload Register 0 */
  26. #define EP960_TRR0 ((unsigned long *) TRR0_ADDR)
  27. /* Timer Count Register 0 */
  28. #define EP960_TCR0 ((unsigned long *) TCR0_ADDR)
  29. /* Timer Mode Register 0 */
  30. #define EP960_TMR0 ((unsigned long *) TMR0_ADDR)
  31. /* Timer Reload Register 1 */
  32. #define EP960_TRR1 ((unsigned long *) TRR1_ADDR)
  33. /* Timer Count Register 1 */
  34. #define EP960_TCR1 ((unsigned long *) TCR1_ADDR)
  35. /* Timer Mode Register 1 */
  36. #define EP960_TMR1 ((unsigned long *) TMR1_ADDR)
  37. /* IMSK Register */
  38. #define EP960_IMSK ((unsigned long *) IMSK_ADDR)
  39. #define CPU_SPEED_MHZ            33
  40. #define TIMER_ROLL_OVER  ((unsigned long) 0xffffffff)
  41. #include "drv/timer/timerDev.h"
  42. /* Locals */ 
  43. LOCAL int     sysClkTicksPerSecond = 60; 
  44. LOCAL BOOL    sysClkRunning        = FALSE; 
  45. LOCAL FUNCPTR sysClkRoutine        = NULL;
  46. LOCAL int     sysClkArg            = NULL;
  47. LOCAL BOOL    sysClkConnected      = FALSE; 
  48. LOCAL int     auxClkTicksPerSecond = 60; 
  49. LOCAL BOOL    sysAuxClkRunning     = FALSE; 
  50. LOCAL FUNCPTR sysAuxClkRoutine     = NULL;
  51. LOCAL int     sysAuxClkArg         = NULL;
  52. LOCAL BOOL    sysAuxClkConnected   = FALSE; 
  53. /**************************************************************************
  54. *
  55. * sysClkInt - clock interrupt handler
  56. *
  57. * This routine handles the clock interrupt.  It is attached to the clock
  58. * interrupt vector by the routine sysClkConnect().  The appropriate routine
  59. * is called and the interrupts are acknowledged.
  60. */
  61. LOCAL void sysClkInt (void)
  62.     {
  63.     if (sysClkRoutine != NULL)
  64.         (*(FUNCPTR) sysClkRoutine) (sysClkArg);
  65.     /* processor clears the IPEND bit upon entry into the ISR */
  66.     }
  67. /***************************************************************************
  68. *
  69. * sysAuxClkInt - clock interrupt handler
  70. *
  71. * This routine handles the clock interrupt.  It is attached to the clock
  72. * interrupt vector by the routine sysAuxClkConnect().  The appropriate
  73. * routine is called and the interrupts are acknowledged.
  74. */
  75. LOCAL void sysAuxClkInt (void)
  76.     {
  77.     if (sysAuxClkRoutine != NULL)
  78.         (*(FUNCPTR) sysAuxClkRoutine) (sysAuxClkArg);
  79.     }
  80. /***************************************************************************
  81. *
  82. * sysClkConnect - connect a routine to the system clock interrupt
  83. *
  84. * This routine specifies the interrupt service routine to be called at each
  85. * clock interrupt.  Normally it is called from usrRoot() in usrConfig.c to 
  86. * connect usrClock() to the system clock interrupt.
  87. *
  88. * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
  89. *
  90. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  91. */
  92. STATUS sysClkConnect
  93.     (
  94.     FUNCPTR routine,    /* routine called at each system clock interrupt */
  95.     int     arg         /* argument with which to call routine           */
  96.     )
  97.     {
  98.     (void)intConnect ((void *)VECTOR_TMR0, sysClkInt, 0);
  99.     sysClkConnected   = TRUE;
  100.     sysClkRoutine     = routine;
  101.     sysClkArg         = arg;
  102.     sysHwInit2 ();
  103.     return (OK);
  104.     }
  105.  
  106. /***************************************************************************
  107. *
  108. * sysClkDisable - turn off system clock interrupts
  109. *
  110. * This routine disables system clock interrupts.
  111. *
  112. * RETURNS: N/A
  113. *
  114. * SEE ALSO: sysClkEnable()
  115. */
  116.  
  117. void sysClkDisable (void)
  118.     {
  119.     if (sysClkRunning)
  120.         {
  121. /* Mask the timer interrupt bits in the IMSK register */
  122. *EP960_IMSK &= 0x20ff;
  123. /* Set the Timer mode Register */
  124. *EP960_TMR0 = 0;
  125. /* Clear the timer interrupts in IPND register, if any */
  126. vxIPNDClear(0x1000);
  127.         sysClkRunning    = FALSE;
  128.         }
  129.     }
  130. /***************************************************************************
  131. *
  132. * sysClkEnable - turn on system clock interrupts
  133. *
  134. * This routine enables system clock interrupts.
  135. *
  136. * RETURNS: N/A
  137. *
  138. * SEE ALSO: sysClkDisable(), sysClkRateSet()
  139. */
  140. void sysClkEnable (void)
  141.     {
  142.     if (!sysClkRunning)
  143.         {
  144. /* Set the Timer Count register to 0 */
  145. *EP960_TCR0 = (CPU_SPEED_MHZ * 1000000 / sysClkTicksPerSecond);
  146. /* Load the Timer Reload register */
  147. *EP960_TRR0 = (CPU_SPEED_MHZ * 1000000 / sysClkTicksPerSecond);
  148. /* Set the Timer mode Register */
  149. *EP960_TMR0 = 7; /* enable timer, auto reload */
  150. /* Enable the timer interrupt bits in the IMSK register */
  151. *EP960_IMSK |= 0x1000;
  152.         sysClkRunning    = TRUE;
  153.         }
  154.     }
  155.     
  156. /***************************************************************************
  157. *
  158. * sysClkRateGet - get the system clock rate
  159. *
  160. * This routine returns the system clock rate.
  161. *
  162. * RETURNS: The number of ticks per second of the system clock.
  163. *
  164. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  165. */
  166. int sysClkRateGet (void)
  167.     {
  168.     return (sysClkTicksPerSecond);
  169.     }
  170.     
  171. /***************************************************************************
  172. *
  173. * sysClkRateSet - set the system clock rate
  174. *
  175. * This routine sets the interrupt rate of the system clock.  It is called by 
  176. * usrRoot() in usrConfig.c.
  177. *
  178. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  179. *
  180. * SEE ALSO: sysClkEnable(), sysClkRateGet()
  181. */
  182. STATUS sysClkRateSet
  183.     (
  184.     int ticksPerSecond      /* number of clock interrupts per second */
  185.     )
  186.     {
  187.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  188.     return (ERROR);
  189.     
  190.     sysClkTicksPerSecond = ticksPerSecond;
  191.     
  192.     if (sysClkRunning)
  193. {
  194. sysClkDisable ();
  195. sysClkEnable ();
  196. }
  197.     
  198.     return (OK);
  199.     }
  200. /***************************************************************************
  201. *
  202. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  203. *
  204. * This routine specifies the interrupt service routine to be called at each
  205. * auxiliary clock interrupt.  It does not enable auxiliary clock interrupts.
  206. *
  207. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  208. *
  209. * SEE ALSO: intConnect(), sysAuxClkEnable()
  210. */
  211. STATUS sysAuxClkConnect
  212.     (
  213.     FUNCPTR routine,    /* routine called at each aux. clock interrupt */
  214.     int     arg         /* argument with which to call routine         */
  215.     )
  216.     {
  217. #ifdef INCLUDE_TIMESTAMP
  218.     return (ERROR);
  219. #endif
  220.     (void) intConnect ((void *)VECTOR_TMR1, sysAuxClkInt, 0);
  221.     sysAuxClkConnected = TRUE;
  222.     sysAuxClkRoutine   = routine;
  223.     sysAuxClkArg       = arg;
  224.     
  225.     return (OK);
  226.     }
  227. /***************************************************************************
  228. *
  229. * sysAuxClkDisconnect - clear the auxiliary clock routine
  230. *
  231. * This routine disables the auxiliary clock interrupt, stops the timer,
  232. * and disconnects the routine currently connected to the auxiliary clock
  233. * interrupt.
  234. *
  235. * RETURNS: N/A
  236. *
  237. * SEE ALSO: sysAuxClkConnect(), sysAuxClkEnable()
  238. */
  239. void sysAuxClkDisconnect (void)
  240.     {
  241.     /* disable the auxiliary clock interrupt */
  242.     sysAuxClkDisable ();
  243.     }
  244. /***************************************************************************
  245. *
  246. * sysAuxClkDisable - turn off auxiliary clock interrupts
  247. *
  248. * This routine disables auxiliary clock interrupts.
  249. *
  250. * RETURNS: N/A
  251. *
  252. * SEE ALSO: sysAuxClkEnable()
  253. */
  254. void sysAuxClkDisable (void)
  255.     {
  256.     if (sysAuxClkRunning)
  257.         {
  258. /* Mask the timer interrupt bits in the IMSK register */
  259. *EP960_IMSK &= 0x10ff;
  260. /* Set the Timer mode Register */
  261. *EP960_TMR1 = 0;
  262. /* Clear the timer interrupts in IPND register, if any */
  263. vxIPNDClear(0x2000);
  264.         sysAuxClkRunning = FALSE;
  265.         }
  266.     }
  267. /***************************************************************************
  268. *
  269. * sysAuxClkEnable - turn on auxiliary clock interrupts
  270. *
  271. * This routine enables auxiliary clock interrupts.
  272. *
  273. * RETURNS: N/A
  274. *
  275. * SEE ALSO: sysAuxClkDisable()
  276. */
  277. void sysAuxClkEnable (void)
  278.     {
  279.     if (!sysAuxClkRunning)
  280.         {
  281. /* Set the Timer Count register to 0 */
  282. *EP960_TCR1 = (CPU_SPEED_MHZ * 1000000 / auxClkTicksPerSecond);
  283. /* Load the Timer Reload register */
  284. *EP960_TRR1 = (CPU_SPEED_MHZ * 1000000 / auxClkTicksPerSecond);
  285. /* Set the Timer mode Register */
  286. *EP960_TMR1 = 7;
  287. /* Enable the timer interrupt bits in the IMSK register */
  288. *EP960_IMSK |= 0x2000;
  289.         sysAuxClkRunning  = TRUE;
  290.         }
  291.     }
  292. /***************************************************************************
  293. *
  294. * sysAuxClkRateGet - get the auxiliary clock rate
  295. *
  296. * This routine returns the interrupt rate of the auxiliary clock.
  297. *
  298. * RETURNS: The number of ticks per second of the auxiliary clock.
  299. *
  300. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  301. */
  302. int sysAuxClkRateGet (void)
  303.     {
  304.     return (auxClkTicksPerSecond);
  305.     }
  306. /***************************************************************************
  307. *
  308. * sysAuxClkRateSet - set the auxiliary clock rate
  309. *
  310. * This routine sets the interrupt rate of the auxiliary clock.  It does not
  311. * enable auxiliary clock interrupts.
  312. *
  313. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  314. *
  315. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  316. */
  317. STATUS sysAuxClkRateSet
  318.     (
  319.     int ticksPerSecond      /* number of clock interrupts per second */
  320.     )
  321.     {
  322.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  323. return (ERROR);
  324.     auxClkTicksPerSecond = ticksPerSecond;
  325.     if (sysAuxClkRunning)
  326. {
  327. sysAuxClkDisable ();
  328. sysAuxClkEnable ();
  329. }
  330.     return (OK);
  331.     }
  332. #ifdef INCLUDE_TIMESTAMP
  333. #include "drv/timer/timestampDev.h"
  334. /* Locals */ 
  335. LOCAL int     sysTimestampTicksPerSecond = 60; 
  336. LOCAL BOOL    sysTimestampConnected      = FALSE; 
  337. LOCAL BOOL    sysTimestampRunning        = FALSE; 
  338. LOCAL FUNCPTR sysTimestampRoutine        = NULL; 
  339. LOCAL int     sysTimestampArg            = NULL;
  340. /**************************************************************************
  341. *
  342. * sysTimestampInt - timestamp timer interrupt handler
  343. *
  344. * This routine handles the timestamp timer interrupt.   A user routine is
  345. * called, if one was connected by sysTimestampConnect().
  346. *
  347. * RETURNS: N/A
  348. *
  349. * SEE ALSO: sysTimestampConnect()
  350. */
  351. LOCAL void sysTimestampInt (void)
  352.     {
  353.     if (sysTimestampRoutine != NULL)     /* call user-connected routine */
  354.         (*sysTimestampRoutine) (sysTimestampArg);
  355.     }
  356. /**************************************************************************
  357. *
  358. * sysTimestampConnect - connect a user routine to a timestamp timer interrupt
  359. *
  360. * This routine specifies the user interrupt routine to be called at each
  361. * timestamp timer interrupt.  
  362. *
  363. * RETURNS: OK, or ERROR if sysTimestampInt() has not been used.
  364. *
  365. * SEE ALSO: sysTimestampEnable()
  366. */
  367. STATUS sysTimestampConnect
  368.     (
  369.     FUNCPTR routine, /* routine called at each timestamp timer interrupt */
  370.     int arg          /* argument with which to call routine */
  371.     )
  372.     {
  373.     sysTimestampConnected = TRUE; 
  374.     sysTimestampRoutine = routine;
  375.     sysTimestampArg = arg;
  376.     return (OK);
  377.     }
  378. /**************************************************************************
  379. *
  380. * sysTimestampEnable - enable a timestamp timer interrupt
  381. *
  382. * This routine enables timestamp timer interrupts and resets the counter.
  383. *
  384. * RETURNS: OK, or ERROR if the timestamp timer cannot be enabled.
  385. *
  386. * SEE ALSO: sysTimestampDisable()
  387. */
  388. STATUS sysTimestampEnable(void)
  389.     {
  390.     if (!sysTimestampRunning)
  391. {
  392.         (void)intConnect ((void *)VECTOR_TMR1, sysTimestampInt, 0);
  393. /* Set the Timer Count register to 0 */
  394. *EP960_TCR1 = TIMER_ROLL_OVER;
  395. /* Load the Timer Reload register */
  396. *EP960_TRR1 = TIMER_ROLL_OVER;
  397. /* Set the Timer mode Register */
  398. *EP960_TMR1 = 0x37; /* timer clock = cpu clock / 8 */
  399. /* Enable the timer interrupt bits in the IMSK register */
  400. *EP960_IMSK |= 0x2000;
  401.         sysTimestampRunning = TRUE;
  402. }
  403.     /* Aux clock and Timestamp timer both are on the same vector */
  404.     
  405.     return (OK);
  406.     }
  407. /**************************************************************************
  408. *
  409. * sysTimestampDisable - disable a timestamp timer interrupt
  410. *
  411. * This routine disables the timestamp timer.  It does not directly disable
  412. * interrupts.  However, the tick counter does not increment once the 
  413. * timestamp timer is disabled, thus, interrupts are no longer generated.
  414. * This routine merely resets the timer counter.
  415. *
  416. * RETURNS: OK, always.
  417. *
  418. * SEE ALSO: sysTimestampEnable()
  419. */
  420. STATUS sysTimestampDisable (void)
  421.     {
  422.     if (sysTimestampRunning)
  423. {
  424. /* Mask the timer interrupt bits in the IMSK register */
  425. *EP960_IMSK &= 0x10ff;
  426. /* Set the Timer mode Register */
  427. *EP960_TMR1 = 0;
  428. /* Clear the timer interrupts in IPND register, if any */
  429. vxIPNDClear(0x2000);
  430. sysTimestampRunning = FALSE;
  431. }
  432.     return (OK);
  433.     }
  434. /**************************************************************************
  435. *
  436. * sysTimestampPeriod - get the period of a timestamp timer 
  437. *
  438. * This routine gets the period of the timestamp timer, in ticks.  The
  439. * period, or terminal count, is the number of ticks to which the timestamp
  440. * timer counts before rolling over and restarting the counting process.
  441. *
  442. * RETURNS: The period of the timestamp timer in counter ticks.
  443. */
  444. UINT32 sysTimestampPeriod (void)
  445.     {
  446.     /* 
  447.      * Return the timestamp timer period here.
  448.      * The highest period (maximum terminal count) should be used so
  449.      * that rollover interrupts are kept to a minimum.
  450.      *
  451.      */
  452.     return (TIMER_ROLL_OVER);
  453.     }
  454. /**************************************************************************
  455. *
  456. * sysTimestampFreq - get a timestamp timer clock frequency
  457. *
  458. * This routine gets the frequency of the timer clock, in ticks per 
  459. * second.  The rate of the timestamp timer is set explicitly by the 
  460. * hardware and typically cannot be altered.
  461. *
  462. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  463. */
  464. UINT32 sysTimestampFreq (void)
  465.     {
  466.     /*
  467.      * Return the timestamp tick output frequency here.
  468.      * This value can be determined from the following equation:
  469.      *     timerFreq = clock input frequency / prescaler
  470.      *
  471.      * When possible, read the clock input frequency and prescaler values
  472.      * directly from chip registers.
  473.      */
  474.     return ((1000000 * CPU_SPEED_MHZ) / 8);
  475.     }
  476. /**************************************************************************
  477. *
  478. * sysTimestamp - get a timestamp timer tick count
  479. *
  480. * This routine returns the current value of the timestamp timer tick counter.
  481. * The tick count can be converted to seconds by dividing it by the return of
  482. * sysTimestampFreq().
  483. *
  484. * This routine should be called with interrupts locked.  If interrupts are
  485. * not locked, sysTimestampLock() should be used instead.
  486. *
  487. * RETURNS: The current timestamp timer tick count.
  488. *
  489. * SEE ALSO: sysTimestampFreq(), sysTimestampLock()
  490. */
  491. UINT32 sysTimestamp (void)
  492.     {
  493.     unsigned long countValue;
  494.     /* Read the timer counter register */
  495.     countValue = ((TIMER_ROLL_OVER - *EP960_TCR1));
  496.     /* return the timestamp timer tick count here */
  497.     return (countValue);
  498.     }
  499. /**************************************************************************
  500. *
  501. * sysTimestampLock - lock interrupts and get the timestamp timer tick count
  502. *
  503. * This routine locks interrupts when the tick counter must be stopped 
  504. * in order to read it or when two independent counters must be read.  
  505. * It then returns the current value of the timestamp timer tick
  506. * counter.
  507. * The tick count can be converted to seconds by dividing it by the return of
  508. * sysTimestampFreq().
  509. *
  510. * If interrupts are already locked, sysTimestamp() should be
  511. * used instead.
  512. *
  513. * RETURNS: The current timestamp timer tick count.
  514. *
  515. * SEE ALSO: sysTimestampFreq(), sysTimestamp()
  516. */
  517. UINT32 sysTimestampLock (void)
  518.     {
  519.     unsigned long countValue;
  520.     /* Read the timer counter register */
  521.     countValue = (TIMER_ROLL_OVER - *EP960_TCR1);
  522.     /* return the timestamp timer tick count here */
  523.     return (countValue);
  524.     }
  525. #endif   /* INCLUDE_TIMESTAMP */