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

VxWorks

开发平台:

C/C++

  1. /* mipsR4kTimer.c - MIPS R4k on-chip timer library */
  2. /* Copyright 1997 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01b,09jul01,mem  Suppress warnings.
  8. 01a,03mar97,kkk  created.
  9. */
  10. /*
  11. DESCRIPTION
  12. This library provides timer routines for the on-chip R4k timer on 
  13. some R4XXX MIPS processors.  This library handles system clock and 
  14. timestamp functions.  This library does not provide auxillary clock functions.
  15. The macros SYS_CLK_RATE_MIN and SYS_CLK_RATE_MAX must be defined 
  16. to provide parameter checking for the sysClkRateSet() routines.
  17. To include the timestamp timer facility, the macro INCLUDE_TIMESTAMP must be
  18. defined. Note that changing the system clock rate will affect the timestamp
  19. timer period, which can be read by calling sysTimestampPeriod().
  20. This driver requires the external routines sysCompareSet(), sysCompareGet(),
  21. sysCountGet(), and sysCountSet() to be defined.  Also the value CPU_CLOCK_RATE
  22. must be defined in the BSP.
  23. The variable sysSoftCompare needs to be defined as global, because this
  24. variabl gets used by the sysCompareSet() routine in sysALib.s of the BSP.
  25. INCLUDE FILES: timestampDev.h
  26. SEE ALSO:
  27. .pG "Configuration"
  28. */
  29. /* includes */
  30. #include "config.h"
  31. #include "drv/timer/timestampDev.h"
  32. /* local defines */
  33. /* extern declarations */
  34. IMPORT STATUS intConnect();
  35. IMPORT int      sysCompareSet (); /* define in sysALib.s of BSP */
  36. IMPORT int      sysCompareGet (); /* define in sysALib.s of BSP */
  37. IMPORT int      sysCountGet (); /* define in sysALib.s of BSP */
  38. IMPORT int      sysCountSet (); /* define in sysALib.s of BSP */
  39. /* globals */
  40. ULONG sysSoftCompare = 0;               /* last target compare reg value */
  41. /* Locals */
  42. LOCAL int   sysClkTicksPerSecond    = 60;       /* default sys timer rate    */
  43. LOCAL int   sysClkArg               = 0;        /* clock int routine arg     */
  44. LOCAL BOOL  sysClkConnected         = FALSE;    /* sys clock connect flag    */
  45. LOCAL BOOL  sysClkRunning           = FALSE;    /* sys clock enabled flag    */
  46. LOCAL FUNCPTR   sysClkRoutine       = NULL;     /* clock interrupt routine   */
  47. LOCAL int   sysClkProcessorTicks;               /* R4000 clock ticks         */
  48. #ifdef  INCLUDE_TIMESTAMP
  49. LOCAL BOOL  sysTimestampRunning     = FALSE;   /* timestamp running flag */
  50. #endif  /* INCLUDE_TIMESTAMP */
  51. /*****************************************************************************
  52. *
  53. * sysClkEnable - turn on system clock interrupts
  54. *
  55. * This routine enables system clock interrupts.
  56. *
  57. * RETURNS: N/A
  58. *
  59. * SEE ALSO: sysClkDisable(), sysClkRateSet()
  60. */
  61. void sysClkEnable (void)
  62.     {
  63.     int key;
  64.     /* start the timer */
  65.     sysClkProcessorTicks = CPU_CLOCK_RATE/sysClkTicksPerSecond;
  66.     key = intLock ();
  67.     sysCompareSet (0);
  68.     sysCountSet (1);
  69.     sysCompareSet (sysClkProcessorTicks);
  70.     sysSoftCompare = sysClkProcessorTicks;
  71.     sysClkRunning = TRUE;
  72.     intUnlock (key);
  73.     }
  74. /*****************************************************************************
  75. *
  76. * sysClkRateGet - get the system clock rate
  77. *
  78. * This routine returns the interrupt rate of the system clock.
  79. *
  80. * RETURNS: The number of ticks per second of the system clock.
  81. *
  82. * SEE ALSO: sysClkRateSet()
  83. */
  84. int sysClkRateGet (void)
  85.     {
  86.     return (sysClkTicksPerSecond);
  87.     }
  88. /*****************************************************************************
  89. *
  90. * sysClkRateSet - set the system clock rate
  91. *
  92. * This routine sets the interrupt rate of the system clock.  It does not
  93. * enable system clock interrupts.  Normally, it is called by usrRoot() in
  94. * usrConfig.c.
  95. *
  96. * NOTE: The R4XXX internal timer is used to provide the system clock.
  97. *
  98. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be
  99. * set.
  100. *
  101. * SEE ALSO: sysClkDisable(), sysClkEnable(), sysClkRateGet()
  102. */
  103. STATUS sysClkRateSet
  104.     (
  105.     int ticksPerSecond  /* number of clock interrupts per second */
  106.     )
  107.     {
  108.     /* parameter checking */
  109.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  110.         return (ERROR);
  111.     sysClkTicksPerSecond = ticksPerSecond;
  112.     if (sysClkRunning)
  113.         {
  114.         sysClkDisable ();
  115.         sysClkEnable ();
  116.         }
  117.     return (OK);
  118.     }
  119. /*****************************************************************************
  120. *
  121. * sysClkInt - handle a system clock interrupt
  122. *
  123. * This routine handles a system clock interrupt.  It increments the value
  124. * on the front panel display and calls the routine installed by
  125. * sysClkConnect().
  126. *
  127. * RETURNS: N/A
  128. */
  129. LOCAL void sysClkInt (void)
  130.     {
  131.     int key;
  132.     ULONG delta;        /* time to when next interrupt should be */
  133.     /* see sysClkDisable(). Clear interrupt and return. */
  134.     if (!sysClkRunning)
  135.         {
  136.         sysCompareSet (sysSoftCompare);
  137.         return;
  138.         }
  139.     key = intLock();
  140.     /* use unsigned arithmetic to compensate for wrap-around */
  141.     /* delta is how long ago the interrupt occured. */
  142.     delta = sysCountGet() - sysSoftCompare;
  143.     if (delta < (sysClkProcessorTicks - 200))
  144.         {
  145.         /*
  146.          * case 1 (normal): we haven't missed the next interrupt.
  147.          *  The 200 above is an estimate of how far count will advance
  148.          *  between reading it above and setting the compare register
  149.          *  below (count should not pass the new compare value before
  150.          *  we've set the register).  sysClkProcessorTicks is on
  151.          *  the order of 500,000.
  152.          */
  153.         sysSoftCompare += sysClkProcessorTicks;
  154.         sysCompareSet (sysSoftCompare);
  155.         }
  156.     else if (delta < (16 * sysClkProcessorTicks))
  157.         {
  158.         /*
  159.          * case 2 (missed a couple): we've missed some interrupts,
  160.          *   don't set the compare register (so we'll take another
  161.          *   interrupt as soon as we return).
  162.          */
  163.         sysSoftCompare += sysClkProcessorTicks;
  164.         }
  165.     else
  166.         {
  167.         /*
  168.          * case 3 (missed a lot): set the next interrupt at
  169.          *   sysClkProcessorTicks past the current time.
  170.          */
  171.         sysSoftCompare = sysCountGet() + sysClkProcessorTicks;
  172.         sysCompareSet (sysSoftCompare);
  173.         }
  174.     intUnlock (key);
  175.     if (sysClkRoutine != NULL)
  176.         (*sysClkRoutine) (sysClkArg);
  177.     }
  178. /*****************************************************************************
  179. *
  180. * sysClkConnect - connect a routine to the system clock interrupt
  181. *
  182. * This routine specifies the interrupt handler to be called at each system
  183. * clock interrupt.  It does not enable system clock interrupts.  Normally,
  184. * it is called from usrRoot() in usrConfig.c to connect usrClock() to the
  185. * system clock interrupt.  Other standard interrupt handlers are also set up
  186. * at this time.
  187. *
  188. * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
  189. *
  190. * SEE ALSO: intConnect(), usrClock()
  191. */
  192. STATUS sysClkConnect
  193.     (
  194.     FUNCPTR routine,    /* routine called at each system clock interrupt */
  195.     int arg             /* argument with which to call routine           */
  196.     )
  197.     {
  198.     if (sysClkConnected == FALSE)
  199.         {
  200.         sysHwInit2 ();
  201.         sysClkConnected = TRUE;
  202.         }
  203.     sysClkRoutine   = routine;
  204.     sysClkArg       = arg;
  205.     return (OK);
  206.     }
  207. /*****************************************************************************
  208. *
  209. * sysClkDisable - turn off system clock interrupts
  210. *
  211. * This routine disables system clock interrupts.
  212. *
  213. * RETURNS: N/A
  214. *
  215. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  216. */
  217. void sysClkDisable (void)
  218.     {
  219.     int key;
  220.     /* we cannot disable interrupts so we do this instead... */
  221.     sysClkRunning = FALSE;
  222.     key = intLock ();
  223.     sysCompareSet (0);
  224.     sysCountSet (1);
  225.     sysClkProcessorTicks = 0xffffff00;
  226.     sysCompareSet (sysClkProcessorTicks);
  227.     sysSoftCompare = sysClkProcessorTicks;
  228.     intUnlock (key);
  229.     }
  230. #ifdef  INCLUDE_TIMESTAMP
  231. /*******************************************************************************
  232. *
  233. * sysTimestampConnect - connect a user routine to a timestamp timer interrupt
  234. *
  235. * This routine specifies the user interrupt routine to be called at each
  236. * timestamp timer interrupt.
  237. *
  238. * RETURNS: ERROR, always.
  239. */
  240. STATUS sysTimestampConnect
  241.     (
  242.     FUNCPTR routine,    /* routine called at each timestamp timer interrupt */
  243.     int arg             /* argument with which to call routine */
  244.     )
  245.     {
  246.     return (ERROR);
  247.     }
  248. /*******************************************************************************
  249. *
  250. * sysTimestampEnable - enable a timestamp timer interrupt
  251. *
  252. * This routine enables timestamp timer interrupts and resets the counter.
  253. *
  254. * RETURNS: OK, always.
  255. *
  256. * SEE ALSO: sysTimestampDisable()
  257. */
  258. STATUS sysTimestampEnable (void)
  259.    {
  260.    if (sysTimestampRunning)
  261.       {
  262.       return (OK);
  263.       }
  264.    if (!sysClkRunning)
  265.       return (ERROR);
  266.    sysTimestampRunning = TRUE;
  267.    return (OK);
  268.    }
  269. /*******************************************************************************
  270. *
  271. * sysTimestampDisable - disable a timestamp timer interrupt
  272. *
  273. * This routine disables timestamp timer interrupts.
  274. *
  275. * RETURNS: OK, always.
  276. *
  277. * SEE ALSO: sysTimestampEnable()
  278. */
  279. STATUS sysTimestampDisable (void)
  280.     {
  281.     if (sysTimestampRunning)
  282.         sysTimestampRunning = FALSE;
  283.     return (OK);
  284.     }
  285. /*******************************************************************************
  286. *
  287. * sysTimestampPeriod - get the period of a timestamp timer
  288. *
  289. * This routine gets the period of the timestamp timer, in ticks.  The
  290. * period, or terminal count, is the number of ticks to which the timestamp
  291. * timer counts before rolling over and restarting the counting process.
  292. *
  293. * RETURNS: The period of the timestamp timer in counter ticks.
  294. */
  295. UINT32 sysTimestampPeriod (void)
  296.     {
  297.     /*
  298.      * The period of the timestamp depends on the clock rate of the on-chip
  299.      * timer.
  300.      */
  301.     return (CPU_CLOCK_RATE/sysClkTicksPerSecond);
  302.     }
  303. /*******************************************************************************
  304. *
  305. * sysTimestampFreq - get a timestamp timer clock frequency
  306. *
  307. * This routine gets the frequency of the timer clock, in ticks per
  308. * second.  The rate of the timestamp timer is set explicitly by the
  309. * hardware and typically cannot be altered.
  310. *
  311. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  312. */
  313. UINT32 sysTimestampFreq (void)
  314.     {
  315.     return (CPU_CLOCK_RATE);
  316.     }
  317. /*******************************************************************************
  318. *
  319. * sysTimestamp - get a timestamp timer tick count
  320. *
  321. * This routine returns the current value of the timestamp timer tick counter.
  322. * The tick count can be converted to seconds by dividing it by the return of
  323. * sysTimestampFreq().
  324. *
  325. * This routine should be called with interrupts locked.  If interrupts are
  326. * not locked, sysTimestampLock() should be used instead.
  327. *
  328. * RETURNS: The current timestamp timer tick count.
  329. *
  330. * SEE ALSO: sysTimestampFreq(), sysTimestampLock()
  331. */
  332. UINT32 sysTimestamp (void)
  333.     {
  334.     return (sysCountGet() - (sysSoftCompare - sysClkProcessorTicks) + 1);
  335.     }
  336. /*******************************************************************************
  337. *
  338. * sysTimestampLock - lock interrupts and get the timestamp timer tick count
  339. *
  340. * This routine locks interrupts when the tick counter must be stopped
  341. * in order to read it or when two independent counters must be read.
  342. * It then returns the current value of the timestamp timer tick
  343. * counter.
  344. *
  345. * The tick count can be converted to seconds by dividing it by the return of
  346. * sysTimestampFreq().
  347. *
  348. * If interrupts are already locked, sysTimestamp() should be
  349. * used instead.
  350. *
  351. * RETURNS: The current timestamp timer tick count.
  352. *
  353. * SEE ALSO: sysTimestampFreq(), sysTimestamp()
  354. */
  355. UINT32 sysTimestampLock (void)
  356.     {
  357.     return(sysCountGet() - (sysSoftCompare - sysClkProcessorTicks)+ 1);
  358.     }
  359. #endif  /* INCLUDE_TIMESTAMP */