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

VxWorks

开发平台:

C/C++

  1. /* templateTimer.c - template timer library */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. /*
  4. TODO - Remove the template modification history and begin a new history
  5. starting with version 01a and growing the history upward with
  6. each revision.
  7. modification history
  8. --------------------
  9. 01e,16oct01,dat  fixing warnings
  10. 01d,29oct97,dat  added protection for calling sysHwInit2 more than once.
  11. 01c,23sep97,dat  changed arg to TEMPLATE_REG_READ
  12. 01b,12mar97,dat  added basic timestamp support, some doc cleanup
  13. 01a,23dec96,ms   written by gutting i8253Timer.c.
  14. */
  15. /*
  16. TODO - This is an example timer.  It must be replaced with specific
  17. information and code for the actual device used as the timer.
  18. DESCRIPTION
  19. Describe the chip being used completely, even if it provides more features
  20. than just timers.
  21. Describe the device's capabilities as a timer, even if this driver doesn't
  22. or can't utilize all of them.  Describe the timer features that the driver
  23. does implement and any restrictions on their use.
  24. Describe all macros that can be used to customize this driver.  All
  25. accesses to chip registers should be done through a redefineable macro.
  26. In this example driver the macros TEMPLATE_READ and TEMPLATE_WRITE
  27. are sample macros to read/write data to a mock device.  If a device
  28. communicates through formatted control blocks in shared memory, the
  29. accesses to those control blocks should also be through a redefinable
  30. macro.
  31. This driver provides 3 main functions, system clock support, auxilliary
  32. clock support, and timestamp timer support.  If necessary, each function
  33. may be conditioned by a separate INCLUDE_ macro.  The timestamp function
  34. is always conditional upon the INCLUDE_TIMESTAMP macro.
  35. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  36. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  37. sys[Aux]ClkRateSet() routines.
  38. INCLUDES:
  39. timestampDev.h
  40. */
  41. /* includes */
  42. #include "vxWorks.h"
  43. #include "config.h"
  44. #include "drv/timer/timerDev.h"
  45. #include "drv/timer/timestampDev.h"
  46. /* defines */
  47. #define TIMESTAMP_HZ 1000000  /* timestamp counter freq */
  48. /* The default is to assume memory mapped I/O */
  49. #ifndef TEMPLATE_READ
  50. #define TEMPLATE_READ(reg, result) 
  51. (result = *reg)
  52. #endif /*TEMPLATE_READ*/
  53. #ifndef TEMPLATE_WRITE
  54. #define TEMPLATE_WRITE(reg, data) 
  55. (*reg = data)
  56. #endif /*TEMPLATE_WRITE*/
  57. /* locals */
  58. LOCAL FUNCPTR sysClkRoutine = NULL; /* routine to call on clock tick */
  59. LOCAL int sysClkArg = 0; /* its argument */
  60. LOCAL BOOL sysClkRunning = FALSE;
  61. LOCAL int sysClkTicksPerSecond = 60;
  62. LOCAL FUNCPTR sysAuxClkRoutine = NULL;
  63. LOCAL int sysAuxClkArg = 0;
  64. LOCAL BOOL sysAuxClkRunning = FALSE;
  65. LOCAL int sysAuxClkTicksPerSecond = 100;
  66. #ifdef INCLUDE_TIMESTAMP
  67. LOCAL BOOL sysTimestampRunning = FALSE; /* running flag */
  68. LOCAL int sysTimestampPeriodValue = 0;  /* Max counter value */
  69. LOCAL FUNCPTR sysTimestampRoutine = NULL;  /* routine to call on intr */
  70. LOCAL int sysTimestampArg = 0;     /* arg for routine */
  71.       void sysTimestampInt (void);  /* forward declaration */
  72. #endif  /* INCLUDE_TIMESTAMP */
  73. /*******************************************************************************
  74. *
  75. * sysClkInt - interrupt level processing for system clock
  76. *
  77. * This routine handles an auxiliary clock interrupt.  It acknowledges the
  78. * interrupt and calls the routine installed by sysClkConnect().
  79. */
  80. void sysClkInt (void)
  81.     {
  82.     /* TODO - acknowledge the interrupt if needed */
  83.     /* call system clock service routine */
  84.     if (sysClkRoutine != NULL)
  85. (* sysClkRoutine) (sysClkArg);
  86.     }
  87. /*******************************************************************************
  88. *
  89. * sysClkConnect - connect a routine to the system clock interrupt
  90. *
  91. * This routine specifies the interrupt service routine to be called at each
  92. * clock interrupt.  Normally, it is called from usrRoot() in usrConfig.c to 
  93. * connect usrClock() to the system clock interrupt.
  94. *
  95. * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
  96. *
  97. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  98. */
  99. STATUS sysClkConnect
  100.     (
  101.     FUNCPTR routine, /* routine to be called at each clock interrupt */
  102.     int arg /* argument with which to call routine */
  103.     )
  104.     {
  105.     static BOOL beenHere = FALSE;
  106.     if (!beenHere)
  107. {
  108. beenHere = TRUE;
  109. sysHwInit2 (); /* XXX for now -- needs to be in usrConfig.c */
  110. }
  111.     sysClkRoutine   = NULL;
  112.     sysClkArg     = arg;
  113.     sysClkRoutine   = routine;
  114.     return (OK);
  115.     }
  116. /*******************************************************************************
  117. *
  118. * sysClkDisable - turn off system clock interrupts
  119. *
  120. * This routine disables system clock interrupts.
  121. *
  122. * RETURNS: N/A
  123. *
  124. * SEE ALSO: sysClkEnable()
  125. */
  126. void sysClkDisable (void)
  127.     {
  128.     if (sysClkRunning)
  129. {
  130. /* TODO - disable system timer interrupts */
  131. sysClkRunning = FALSE;
  132. }
  133.     }
  134. /*******************************************************************************
  135. *
  136. * sysClkEnable - turn on system clock interrupts
  137. *
  138. * This routine enables system clock interrupts.
  139. *
  140. * RETURNS: N/A
  141. *
  142. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  143. */
  144. void sysClkEnable (void)
  145.     {
  146.     static BOOL connected = FALSE;
  147.     if (!connected)
  148. {
  149. /* TODO - connect sysClkInt to appropriate interrupt */
  150. connected = TRUE;
  151. }
  152.     if (!sysClkRunning)
  153. {
  154. /*
  155.  * TODO - start system timer interrupts at a
  156.  * at a frequency of sysClkTicksPerSecond
  157.  */
  158. sysClkRunning = TRUE;
  159. }
  160.     }
  161. /*******************************************************************************
  162. *
  163. * sysClkRateGet - get the system clock rate
  164. *
  165. * This routine returns the system clock rate.
  166. *
  167. * RETURNS: The number of ticks per second of the system clock.
  168. *
  169. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  170. */
  171. int sysClkRateGet (void)
  172.     {
  173.     return (sysClkTicksPerSecond);
  174.     }
  175. /*******************************************************************************
  176. *
  177. * sysClkRateSet - set the system clock rate
  178. *
  179. * This routine sets the interrupt rate of the system clock.
  180. * It is called by usrRoot() in usrConfig.c.
  181. *
  182. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  183. *
  184. * SEE ALSO: sysClkEnable(), sysClkRateGet()
  185. */
  186. STATUS sysClkRateSet
  187.     (
  188.     int ticksPerSecond     /* number of clock interrupts per second */
  189.     )
  190.     {
  191.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  192. return (ERROR);
  193.     /* TODO - return ERROR if rate is not supported */
  194.     sysClkTicksPerSecond = ticksPerSecond;
  195.     if (sysClkRunning)
  196. {
  197. sysClkDisable ();
  198. sysClkEnable ();
  199. }
  200.     return (OK);
  201.     }
  202. /*******************************************************************************
  203. *
  204. * sysAuxClkInt - handle an auxiliary clock interrupt
  205. *
  206. * This routine handles an auxiliary clock interrupt.  It acknowledges the
  207. * interrupt and calls the routine installed by sysAuxClkConnect().
  208. *
  209. * RETURNS: N/A
  210. */
  211. void sysAuxClkInt (void)
  212.     {
  213.     /* TODO - acknowledge the interrupt if needed */
  214.     /* call auxiliary clock service routine */
  215.     if (sysAuxClkRoutine != NULL)
  216. (*sysAuxClkRoutine) (sysAuxClkArg);
  217.     }
  218. /*******************************************************************************
  219. *
  220. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  221. *
  222. * This routine specifies the interrupt service routine to be called at each
  223. * auxiliary clock interrupt.  It does not enable auxiliary clock interrupts.
  224. *
  225. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  226. *
  227. * SEE ALSO: intConnect(), sysAuxClkEnable()
  228. */
  229. STATUS sysAuxClkConnect
  230.     (
  231.     FUNCPTR routine,    /* routine called at each aux clock interrupt */
  232.     int arg             /* argument to auxiliary clock interrupt routine */
  233.     )
  234.     {
  235.     sysAuxClkRoutine = NULL;
  236.     sysAuxClkArg = arg;
  237.     sysAuxClkRoutine = routine;
  238.     return (OK);
  239.     }
  240. /*******************************************************************************
  241. *
  242. * sysAuxClkDisable - turn off auxiliary clock interrupts
  243. *
  244. * This routine disables auxiliary clock interrupts.
  245. *
  246. * RETURNS: N/A
  247. *
  248. * SEE ALSO: sysAuxClkEnable()
  249. */
  250. void sysAuxClkDisable (void)
  251.     {
  252.     if (sysAuxClkRunning)
  253.         {
  254. /* TODO - disable auxiliary timer interrupts */
  255. sysAuxClkRunning = FALSE;
  256.         }
  257.     }
  258. /*******************************************************************************
  259. *
  260. * sysAuxClkEnable - turn on auxiliary clock interrupts
  261. *
  262. * This routine enables auxiliary clock interrupts.
  263. *
  264. * RETURNS: N/A
  265. *
  266. * SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
  267. */
  268. void sysAuxClkEnable (void)
  269.     {
  270.     static BOOL connected = FALSE;
  271.     if (!connected)
  272. {
  273. /* TODO - connect sysAuxClkInt to appropriate interrupt */
  274. connected = TRUE;
  275. }
  276.     if (!sysAuxClkRunning)
  277.         {
  278. /*
  279.  * TODO - start auxiliary timer interrupts at a
  280.  * at a frequency of sysAuxClkTicksPerSecond.
  281.  */
  282. sysAuxClkRunning = TRUE;
  283. }
  284.     }
  285. /*******************************************************************************
  286. *
  287. * sysAuxClkRateGet - get the auxiliary clock rate
  288. *
  289. * This routine returns the interrupt rate of the auxiliary clock.
  290. *
  291. * RETURNS: The number of ticks per second of the auxiliary clock.
  292. *
  293. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  294. */
  295. int sysAuxClkRateGet (void)
  296.     {
  297.     return (sysAuxClkTicksPerSecond);
  298.     }
  299. /*******************************************************************************
  300. *
  301. * sysAuxClkRateSet - set the auxiliary clock rate
  302. *
  303. * This routine sets the interrupt rate of the auxiliary clock.  It does not
  304. * enable auxiliary clock interrupts.
  305. *
  306. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  307. *
  308. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  309. */
  310. STATUS sysAuxClkRateSet
  311.     (
  312.     int ticksPerSecond  /* number of clock interrupts per second */
  313.     )
  314.     {
  315.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  316.         return (ERROR);
  317.     /* TODO - return ERROR if rate is not supported */
  318.     if (sysAuxClkRunning)
  319. {
  320. sysAuxClkDisable ();
  321. sysAuxClkEnable ();
  322. }
  323.     return (OK);
  324.     }
  325. #ifdef  INCLUDE_TIMESTAMP
  326. /*
  327.  * TODO - This is an example timestamp driver.  It must be modified to
  328.  * work with the specific hardware in use.  There is an application note
  329.  * on creating a timestamp driver that is very useful.
  330.  */
  331. /*******************************************************************************
  332. *
  333. * sysTimestampInt - timestamp timer interrupt handler
  334. *
  335. * This rountine handles the timestamp timer interrupt.  A user routine is
  336. * called, if one was connected by sysTimestampConnect().
  337. *
  338. * RETURNS: N/A
  339. *
  340. * SEE ALSO: sysTimestampConnect()
  341. */
  342. void sysTimestampInt (void)
  343.     {
  344.     if (sysTimestampRunning && sysTimestampRoutine != NULL)
  345. (*sysTimestampRoutine)(sysTimestampArg);
  346.     }
  347. /*******************************************************************************
  348. *
  349. * sysTimestampConnect - connect a user routine to the timestamp timer interrupt
  350. *
  351. * This routine specifies the user interrupt routine to be called at each
  352. * timestamp timer interrupt.  It does not enable the timestamp timer itself.
  353. *
  354. * RETURNS: OK, or ERROR if sysTimestampInt() interrupt handler is not used.
  355. */
  356. STATUS sysTimestampConnect
  357.     (
  358.     FUNCPTR routine,    /* routine called at each timestamp timer interrupt */
  359.     int arg     /* argument with which to call routine */
  360.     )
  361.     {
  362.     sysTimestampRoutine = NULL;
  363.     sysTimestampArg = arg;
  364.     sysTimestampRoutine = routine;
  365.     return OK;
  366.     }
  367. /*******************************************************************************
  368. *
  369. * sysTimestampEnable - initialize and enable the timestamp timer
  370. *
  371. * This routine connects the timestamp timer interrupt and initializes the
  372. * counter registers.  If the timestamp timer is already running, this routine
  373. * merely resets the timer counter.
  374. *
  375. * The rate of the timestamp timer should be set explicitly within the BSP,
  376. * in the sysHwInit() routine.  This routine does not intialize the timer
  377. * rate.
  378. *
  379. * RETURNS: OK, or ERROR if hardware cannot be enabled.
  380. */
  381. STATUS sysTimestampEnable (void)
  382.     {
  383.     static BOOL connected = FALSE;
  384.     if (!connected)
  385. {
  386. /* TODO - connect sysTimestampInt to the appropriate interrupt */
  387. connected = TRUE;
  388. }
  389.     if (!sysTimestampRunning)
  390. {
  391. /* TODO - setup the counter registers and start the counter */
  392. sysTimestampRunning = TRUE;
  393. }
  394.     return (OK);
  395.     }
  396. /*******************************************************************************
  397. *
  398. * sysTimestampDisable - disable the timestamp timer
  399. *
  400. * This routine disables the timestamp timer.  Interrupts are not disabled,
  401. * although the tick counter will not increment after the timestamp timer
  402. * is disabled, thus interrupts will no longer be generated.
  403. *
  404. * RETURNS: OK, or ERROR if timer cannot be disabled.
  405. */
  406. STATUS sysTimestampDisable (void)
  407.     {
  408.     if (sysTimestampRunning)
  409.         sysTimestampRunning = FALSE;
  410.     return (OK);
  411.     }
  412. /*******************************************************************************
  413. *
  414. * sysTimestampPeriod - get the timestamp timer period
  415. *
  416. * This routine returns the period of the timestamp timer in ticks.
  417. * The period, or terminal count, is the number of ticks to which the timestamp
  418. * timer will count before rolling over and restarting the counting process.
  419. *
  420. * RETURNS: The period of the timestamp timer in counter ticks.
  421. */
  422. UINT32 sysTimestampPeriod (void)
  423.     {
  424.     /* TODO - this is example code, it must be replaced. */
  425.     sysTimestampPeriodValue = TIMESTAMP_HZ / sysClkTicksPerSecond;
  426.     return (sysTimestampPeriodValue);
  427.     }
  428. /*******************************************************************************
  429. *
  430. * sysTimestampFreq - get the timestamp timer clock frequency
  431. *
  432. * This routine returns the frequency of the timer clock, in ticks per second.
  433. *
  434. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  435. */
  436. UINT32 sysTimestampFreq (void)
  437.     {
  438.     /* TODO - this is example code, it must be replaced. */
  439.     return (TIMESTAMP_HZ);
  440.     }
  441. /*******************************************************************************
  442. *
  443. * sysTimestamp - get the timestamp timer tick count
  444. *
  445. * This routine returns the current value of the timestamp timer tick counter.
  446. * The tick count can be converted to seconds by dividing by the return of
  447. * sysTimestampFreq().
  448. *
  449. * This routine should be called with interrupts locked.  If interrupts are
  450. * not already locked, sysTimestampLock() should be used instead.
  451. *
  452. * RETURNS: The current timestamp timer tick count.
  453. *
  454. * SEE ALSO: sysTimestampLock()
  455. */
  456. UINT32 sysTimestamp (void)
  457.     {
  458.     UINT32 count = 0;
  459.     /* TODO - read the timestamp timer value */
  460.     return (count);
  461.     }
  462. /*******************************************************************************
  463. *
  464. * sysTimestampLock - get the timestamp timer tick count
  465. *
  466. * This routine returns the current value of the timestamp timer tick counter.
  467. * The tick count can be converted to seconds by dividing by the return of
  468. * sysTimestampFreq().
  469. *
  470. * This routine locks interrupts for cases where it is necessary to stop the
  471. * tick counter in order to read it, or when two independent counters must
  472. * be read.  If interrupts are already locked, sysTimestamp() should be
  473. * used instead.
  474. *
  475. * RETURNS: The current timestamp timer tick count.
  476. *
  477. * SEE ALSO: sysTimestamp()
  478. */
  479. UINT32 sysTimestampLock (void)
  480.     {
  481.     UINT32 result;
  482.     int oldLevel;
  483.     /*
  484.      * TODO - If interrupt lockout is not needed, then don't do it. Just
  485.      * return the value from sysTimestamp().
  486.      */
  487.     oldLevel = intLock ();
  488.     result = sysTimestamp ();
  489.     intUnlock (oldLevel);
  490.     return (result);
  491.     }
  492. #endif  /* INCLUDE_TIMESTAMP */