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

VxWorks

开发平台:

C/C++

  1. /* pccTimer.c - PCC Timer library */
  2. /* Copyright 1984-1996 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01i,22jul96,dat  merged with timestamp driver.
  8. 01h,06jun96,wlf  doc: cleanup.
  9. 01g,16apr94,dzb  changed the file name from pccTimer.c to pccTimerTS.c
  10. 01f,07apr94,dzb  optimized timestamp routines.
  11. 01e,10jan94,dzb  added conditional compilation for INCLUDE_TIMESTAMP macro.
  12. 01d,17sep93,dzb  added timestamp support.
  13. 01c,07jul92,ccc  changed genericTimer.h to timerDev.h.
  14. 01b,26jun92,ccc  changed include to genericTimer.h.
  15. 01a,10jun92,ccc  created by moving routines from sysLib.c of mv147, ansified.
  16. */
  17. /*
  18. DESCRIPTION
  19. This library contains routines to manipulate the timer functions on the
  20. PCC chip with a board-independent interface.  This library handles both
  21. the system clock and the auxiliary clock functions.
  22. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  23. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  24. sys[Aux]ClkRateSet() routines.
  25. To include the timestamp timer facility, the macro INCLUDE_TIMESTAMP must be
  26. defined.  When the timestamp timer is running, tick timer #2 is reset every
  27. system clock interrupt in an effort to control time skew.  Note that changing
  28. the system clock rate will affect the timestamp timer period, which can be
  29. read by calling sysTimestampPeriod().
  30. NOTE: the auxiliary clock and timestamp timer share the same physical timer
  31. (tick timer #2).  Only one of these facilities may used at a time.  The
  32. applicable disable routine (sysAuxClkDisable() or sysTimestampDisable())
  33. can be used to relinquish control of tick timer #2, and the other facility
  34. may then be enabled.  If either clock is active, attempting to activate
  35. the other clock will fail.
  36. */
  37. #include "drv/timer/timerDev.h"
  38. #include "drv/timer/timestampDev.h"
  39. /* Locals */
  40. #define TICK_FREQ         160000
  41. LOCAL int     sysClkTicksPerSecond  = 60;
  42. LOCAL BOOL    sysClkRunning         = FALSE;
  43. LOCAL FUNCPTR sysClkRoutine         = NULL;
  44. LOCAL int     sysClkArg             = NULL;
  45. LOCAL BOOL    sysClkConnected       = FALSE;
  46. LOCAL int     auxClkTicksPerSecond  = 60;
  47. LOCAL BOOL    sysAuxClkRunning      = FALSE;
  48. LOCAL FUNCPTR sysAuxClkRoutine      = NULL;
  49. LOCAL int     sysAuxClkArg          = NULL;
  50. LOCAL BOOL    auxClkConnected       = FALSE;
  51. LOCAL BOOL    sysTimestampRunning   = FALSE; /* running flag */
  52. /*******************************************************************************
  53. *
  54. * sysClkInt - handle system clock interrupts
  55. *
  56. * This routine handles system clock interrupts.
  57. */
  58. LOCAL void sysClkInt (void)
  59.     {
  60.     /* reset clock interrupt */
  61.     /* clear overflow counter, enable & start counter */
  62.     *TIC_1_CSR = TIC_1_CSR_CLR_OVF |
  63.                  TIC_1_CSR_ENABLE;
  64.     *TIC_1_INT_CTL = INT_LVL_TIC_1       |
  65.                      TIC_1_INT_CTL_CLEAR |
  66.                      TIC_1_INT_CTL_ENABLE; /* reset & enable int, set level */
  67. #ifdef INCLUDE_TIMESTAMP
  68.     if (sysTimestampRunning) /* sync up timestamp timer */
  69. sysTimestampEnable ();
  70. #endif /* INCLUDE_TIMESTAMP */
  71.     if (sysClkRoutine != NULL)
  72.         (*sysClkRoutine) (sysClkArg);
  73.     }
  74. /*******************************************************************************
  75. *
  76. * sysClkConnect - connect a routine to the system clock interrupt
  77. *
  78. * This routine specifies the interrupt service routine to be called at each
  79. * clock interrupt.  Normally, it is called from usrRoot() in usrConfig.c to
  80. * connect usrClock() to the system clock interrupt.
  81. *
  82. * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
  83. *
  84. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  85. */
  86. STATUS sysClkConnect
  87.     (
  88.     FUNCPTR routine,    /* routine called at each system clock interrupt */
  89.     int arg             /* argument with which to call routine           */
  90.     )
  91.     {
  92.     sysHwInit2 (); /* XXX for now -- needs to be in usrConfig.c */
  93.     sysClkConnected = TRUE;
  94.     sysClkRoutine   = routine;
  95.     sysClkArg       = arg;
  96.     return (OK);
  97.     }
  98. /*******************************************************************************
  99. *
  100. * sysClkDisable - turn off system clock interrupts
  101. *
  102. * This routine disables system clock interrupts.
  103. *
  104. * RETURNS: N/A
  105. *
  106. * SEE ALSO: sysClkEnable()
  107. */
  108. void sysClkDisable (void)
  109.     {
  110.     if (sysClkRunning)
  111.         {
  112.         /* disable interrupts */
  113.         *TIC_1_INT_CTL = TIC_1_INT_CTL_DISABLE;
  114.         sysClkRunning = FALSE;
  115.         }
  116.     }
  117. /*******************************************************************************
  118. *
  119. * sysClkEnable - turn on system clock interrupts
  120. *
  121. * This routine enables system clock interrupts.
  122. *
  123. * RETURNS: N/A
  124. *
  125. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  126. */
  127. void sysClkEnable (void)
  128.     {
  129.     if (!sysClkRunning)
  130.         {
  131.         /* preload the preload register */
  132.         *TIC_1_PRELOAD = (short) (65536 - (TICK_FREQ / sysClkTicksPerSecond));
  133.         /* enable the clock interrupt. */
  134.         *TIC_1_CSR = TIC_1_CSR_STOP;   /* load counter from preload register */
  135.         /* clear overflow counter, enable & start counter */
  136.         *TIC_1_CSR = TIC_1_CSR_CLR_OVF |
  137.                      TIC_1_CSR_ENABLE;
  138.         *TIC_1_INT_CTL = TIC_1_INT_CTL_CLEAR  |
  139.                          TIC_1_INT_CTL_ENABLE |
  140.                          INT_LVL_TIC_1;  /* reset&enable int, set level */
  141.         sysClkRunning = TRUE;
  142.         }
  143.     }
  144. /*******************************************************************************
  145. *
  146. * sysClkRateGet - get the system clock rate
  147. *
  148. * This routine returns the system clock rate.
  149. *
  150. * RETURNS: The number of ticks per second of the system clock.
  151. *
  152. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  153. */
  154. int sysClkRateGet (void)
  155.     {
  156.     return (sysClkTicksPerSecond);
  157.     }
  158. /********************************************************************************
  159. * sysClkRateSet - set the system clock rate
  160. *
  161. * This routine sets the interrupt rate of the system clock.
  162. * It is called by usrRoot() in usrConfig.c.
  163. *
  164. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be
  165. * set.
  166. *
  167. * SEE ALSO: sysClkEnable(), sysClkRateGet()
  168. */
  169. STATUS sysClkRateSet
  170.     (
  171.     int ticksPerSecond     /* number of clock interrupts per second */
  172.     )
  173.     {
  174.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  175.         return (ERROR);
  176.     sysClkTicksPerSecond = ticksPerSecond;
  177.     if (sysClkRunning)
  178.         {
  179.         sysClkDisable ();
  180.         sysClkEnable ();
  181.         }
  182.     return (OK);
  183.     }
  184. /*******************************************************************************
  185. *
  186. * sysAuxClkInt - handle auxiliary clock interrupts
  187. */
  188. LOCAL void sysAuxClkInt (void)
  189.     {
  190.     /* reset clock interrupt */
  191.     /* clear overflow counter, enable & start counter */
  192.     *TIC_2_CSR = TIC_2_CSR_CLR_OVF |
  193.                  TIC_2_CSR_ENABLE;
  194.     *TIC_2_INT_CTL = TIC_2_INT_CTL_CLEAR  |
  195.                      TIC_2_INT_CTL_ENABLE |
  196.                      INT_LVL_TIC_2;     /* reset & enable int, set level */
  197.     if (sysAuxClkRoutine != NULL)
  198.         (*sysAuxClkRoutine) (sysAuxClkArg);
  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
  206. * interrupts.
  207. *
  208. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  209. *
  210. * SEE ALSO: intConnect(), sysAuxClkEnable()
  211. */
  212. STATUS sysAuxClkConnect
  213.     (
  214.     FUNCPTR routine,    /* routine called at each aux clock interrupt    */
  215.     int arg             /* argument to auxiliary clock interrupt routine */
  216.     )
  217.     {
  218.     auxClkConnected  = TRUE;
  219.     sysAuxClkRoutine = routine;
  220.     sysAuxClkArg     = arg;
  221.     return (OK);
  222.     }
  223. /*******************************************************************************
  224. *
  225. * sysAuxClkDisable - turn off auxiliary clock interrupts
  226. *
  227. * This routine disables auxiliary clock interrupts.
  228. *
  229. * RETURNS: N/A
  230. *
  231. * SEE ALSO: sysAuxClkEnable()
  232. */
  233. void sysAuxClkDisable (void)
  234.     {
  235.     if ((sysAuxClkRunning) && (!sysTimestampRunning))
  236.         {
  237.         /* clear overflow counter & stop counter */
  238.         *TIC_2_CSR     = TIC_2_CSR_CLR_OVF |
  239.                          TIC_2_CSR_STOP;
  240.         /* reset & disable int, set level */
  241.         *TIC_2_INT_CTL = TIC_2_INT_CTL_CLEAR |
  242.                          TIC_2_INT_CTL_DISABLE;
  243.         sysAuxClkRunning = FALSE;
  244.         }
  245.     }
  246. /*******************************************************************************
  247. *
  248. * sysAuxClkEnable - turn on auxiliary clock interrupts
  249. *
  250. * This routine enables auxiliary clock interrupts.
  251. *
  252. * RETURNS: N/A
  253. *
  254. * SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
  255. */
  256. void sysAuxClkEnable (void)
  257.     {
  258.     if ((!sysAuxClkRunning) && (!sysTimestampRunning))
  259.         {
  260.         /* preload the preload register */
  261.         *TIC_2_PRELOAD = (short) (65536 - (TICK_FREQ / auxClkTicksPerSecond));
  262.         /* enable the clock interrupt */
  263.         *TIC_2_CSR     = TIC_2_CSR_STOP; /* load counter from preload reg */
  264.         /* clear overflow counter, enable & start counter */
  265.         *TIC_2_CSR     = TIC_2_CSR_CLR_OVF |
  266.                          TIC_2_CSR_ENABLE;
  267.         *TIC_2_INT_CTL = TIC_2_INT_CTL_CLEAR  |
  268.                          TIC_2_INT_CTL_ENABLE |
  269.                          INT_LVL_TIC_2;   /* reset&enable int, set level */
  270.         sysAuxClkRunning = TRUE;
  271.         }
  272.     }
  273. /*******************************************************************************
  274. *
  275. * sysAuxClkRateGet - get the auxiliary clock rate
  276. *
  277. * This routine returns the interrupt rate of the auxiliary clock.
  278. *
  279. * RETURNS: The number of ticks per second of the auxiliary clock.
  280. *
  281. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  282. */
  283. int sysAuxClkRateGet (void)
  284.     {
  285.     return (auxClkTicksPerSecond);
  286.     }
  287. /*******************************************************************************
  288. *
  289. * sysAuxClkRateSet - set the auxiliary clock rate
  290. *
  291. * This routine sets the interrupt rate of the auxiliary clock.
  292. * It does not enable auxiliary clock interrupts.
  293. *
  294. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  295. *
  296. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  297. */
  298. STATUS sysAuxClkRateSet
  299.     (
  300.     int ticksPerSecond     /* number of clock interrupts per second */
  301.     )
  302.     {
  303.     if (sysTimestampRunning)
  304. return (ERROR);
  305.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  306.         return (ERROR);
  307.     auxClkTicksPerSecond = ticksPerSecond;
  308.     if (sysAuxClkRunning)
  309.         {
  310.         sysAuxClkDisable ();
  311.         sysAuxClkEnable ();
  312.         }
  313.     return (OK);
  314.     }
  315. #ifdef INCLUDE_TIMESTAMP
  316. /*******************************************************************************
  317. *
  318. * sysTimestampConnect - connect a user routine to the timestamp timer interrupt
  319. *
  320. * This routine usually specifies the user interrupt routine to be called at
  321. * each timestamp timer interrupt.  In this case, however, the timestamp timer
  322. * interrupt is not used since the timer is reset by the system clock before
  323. * an interrupt can be generated.
  324. *
  325. * RETURNS: OK, or ERROR if sysTimestampInt() interrupt handler is not used.
  326. */
  327. STATUS sysTimestampConnect
  328.     (
  329.     FUNCPTR routine,    /* routine called at each timestamp timer interrupt */
  330.     int arg             /* argument with which to call routine */
  331.     )
  332.     {
  333.     return (ERROR);
  334.     }
  335. /*******************************************************************************
  336. *
  337. * sysTimestampEnable - initialize and enable the timestamp timer
  338. *
  339. * This routine disables the timestamp timer interrupt and initializes the
  340. * counter registers.  If the timestamp timer is already running, this routine
  341. * merely resets the timer counter.
  342. *
  343. * The rate of the timestamp timer should be set explicitly within the BSP,
  344. * in the sysHwInit() routine.  This routine does not intialize the timer
  345. * rate.
  346. *
  347. * RETURNS: OK, or ERROR if the timestamp timer cannot be enabled.
  348. */
  349. STATUS sysTimestampEnable (void)
  350.     {
  351.     if (sysTimestampRunning)
  352.         {
  353.         *TIC_2_CSR = TIC_2_CSR_STOP; /* clear the counter */
  354.         *TIC_2_CSR = TIC_2_CSR_ENABLE; /* enable the timer */
  355.         return (OK);
  356.         }
  357.     if ((sysAuxClkRunning) || (!sysClkRunning))
  358. return (ERROR);
  359.     sysTimestampRunning = TRUE;
  360.     /*
  361.      * Disable the timer interrupt.  The timestamp timer is reset by the
  362.      * system clock before rollover occurs.
  363.      */
  364.     *TIC_2_INT_CTL = TIC_2_INT_CTL_DISABLE;
  365.     *TIC_2_PRELOAD = 0x0; /* highest period -> freerunning */
  366.     *TIC_2_CSR = TIC_2_CSR_STOP; /* clear the counter */
  367.     *TIC_2_CSR = TIC_2_CSR_ENABLE; /* enable the timer */
  368.     return (OK);
  369.     }
  370. /*******************************************************************************
  371. *
  372. * sysTimestampDisable - disable the timestamp timer
  373. *
  374. * This routine disables the timestamp timer.  Interrupts are not disabled,
  375. * although the tick counter will not increment after the timestamp timer
  376. * is disabled, thus interrupts will no longer be generated.
  377. *
  378. * RETURNS: OK, or ERROR if the timestamp timer cannot be disabled.
  379. */
  380. STATUS sysTimestampDisable (void)
  381.     {
  382.     if (sysAuxClkRunning)
  383.         return (ERROR);
  384.     if (sysTimestampRunning)
  385. {
  386.         sysTimestampRunning = FALSE;
  387.         *TIC_2_CSR = TIC_2_CSR_DISABLE; /* disable the timer */
  388.         }
  389.     return (OK);
  390.     }
  391. /*******************************************************************************
  392. *
  393. * sysTimestampPeriod - get the timestamp timer period
  394. *
  395. * This routine returns the period of the timestamp timer in ticks.
  396. * The period, or terminal count, is the number of ticks to which the timestamp
  397. * timer will count before rolling over and restarting the counting process.
  398. *
  399. * RETURNS: The period of the timestamp timer in counter ticks.
  400. */
  401. UINT32 sysTimestampPeriod (void)
  402.     {
  403.     return (TICK_FREQ / sysClkTicksPerSecond);
  404.     }
  405. /*******************************************************************************
  406. *
  407. * sysTimestampFreq - get the timestamp timer clock frequency
  408. *
  409. * This routine returns the frequency of the timer clock, in ticks per second.
  410. * The rate of the timestamp timer should be set explicitly within the BSP,
  411. * in the sysHwInit() routine.
  412. *
  413. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  414. */
  415. UINT32 sysTimestampFreq (void)
  416.     {
  417.     UINT32 timerFreq;
  418.     timerFreq = TICK_FREQ;
  419.     return (timerFreq);
  420.     }
  421. /*******************************************************************************
  422. *
  423. * sysTimestamp - get the timestamp timer tick count
  424. *
  425. * This routine returns the current value of the timestamp timer tick counter.
  426. * The tick count can be converted to seconds by dividing by the return of
  427. * sysTimestampFreq().
  428. *
  429. * This routine should be called with interrupts locked.  If interrupts are
  430. * not already locked, sysTimestampLock() should be used instead.
  431. *
  432. * RETURNS: The current timestamp timer tick count.
  433. *
  434. * SEE ALSO: sysTimestampLock()
  435. */
  436. UINT32 sysTimestamp (void)
  437.     {
  438.     UINT32 tick = 0;
  439.     register short * pCounter;
  440.     if (sysTimestampRunning)
  441. {
  442. pCounter = TIC_2_COUNTER;
  443.         *TIC_2_CSR = TIC_2_CSR_DISABLE; /* disable the timer */
  444.         tick = *pCounter; /* read tick counter value */
  445.         *TIC_2_CSR = TIC_2_CSR_ENABLE; /* enable the timer */
  446. tick &= 0x0000ffff;
  447. }
  448.     return (tick);
  449.     }
  450. /*******************************************************************************
  451. *
  452. * sysTimestampLock - get the timestamp timer tick count
  453. *
  454. * This routine returns the current value of the timestamp timer tick counter.
  455. * The tick count can be converted to seconds by dividing by the return of
  456. * sysTimestampFreq().
  457. *
  458. * This routine locks interrupts for cases where it is necessary to stop the
  459. * tick counter in order to read it, or when two independent counters must
  460. * be read.  If interrupts are already locked, sysTimestamp() should be
  461. * used instead.
  462. *
  463. * RETURNS: The current timestamp timer tick count.
  464. *
  465. * SEE ALSO: sysTimestamp()
  466. */
  467. UINT32 sysTimestampLock (void)
  468.     {
  469.     UINT32 tick = 0;
  470.     register short * pCounter;
  471.     int lockKey;
  472.     if (sysTimestampRunning)
  473. {
  474. pCounter = TIC_2_COUNTER;
  475.         lockKey = intLock (); /* LOCK INTERRUPTS */
  476.         *TIC_2_CSR = TIC_2_CSR_DISABLE; /* disable the timer */
  477.         tick = *pCounter; /* read tick counter value */
  478.         *TIC_2_CSR = TIC_2_CSR_ENABLE; /* enable the timer */
  479.         intUnlock (lockKey); /* UNLOCK INTERRUPTS */
  480. tick &= 0x0000ffff;
  481. }
  482.     return (tick);
  483.     }
  484. #endif /* INCLUDE_TIMESTAMP */