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

VxWorks

开发平台:

C/C++

  1. /* m68302Timer.c - MC68302 timer library */
  2. /* Copyright 1984-1997 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01e,10mar97,map  added timestamp support [SPR# 7943]
  8. 01d,31oct96,wlf  doc: cleanup.
  9. 01c,04feb93,caf  fixed modification history, updated copyright notice.
  10. 01b,04feb93,caf  modified sysClkEnable() and sysAuxClkEnable() to use
  11.  divide-by-16 prescaler when necessary (SPR #1756).
  12. 01a,10aug92,caf  moved clock routines from ver 01h of ads302/sysLib.c, ansified.
  13. */
  14. /*
  15. DESCRIPTION
  16. This library contains routines to manipulate the timer functions on the
  17. Motorola MC68302.  This library handles system clock, auxiliary clock,
  18. and timestamp functions.
  19. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  20. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  21. sys[Aux]ClkRateSet() routines.
  22. To include timestamp facility, define a macro INCLUDE TIMESTAMP. Note that the
  23. system clock is used by the timestamp facility; and changing the system clock
  24. rate will affect the timestamp period. Current timestamp period can be read by
  25. calling sysTimestampPeriod().
  26. INCLUDE_FILES: timestampDev.h
  27. */
  28. /*includes */
  29. #include "config.h"
  30. #include "drv/timer/timestampDev.h"
  31. /* locals */
  32. LOCAL FUNCPTR sysClkRoutine = NULL; /* routine to call on clock interrupt */
  33. LOCAL int sysClkArg = NULL; /* its argument */
  34. LOCAL int sysClkRunning = FALSE;
  35. LOCAL int sysClkConnected = FALSE;
  36. LOCAL int sysClkTicksPerSecond = 60;
  37. LOCAL FUNCPTR sysAuxClkRoutine = NULL; /* routine to call on clock interrupt */
  38. LOCAL int sysAuxClkArg = NULL; /* its argument */
  39. LOCAL int sysAuxClkRunning = FALSE;
  40. LOCAL int auxClkConnected = FALSE;
  41. LOCAL int auxClkTicksPerSecond = 60;
  42. #ifdef INCLUDE_TIMESTAMP
  43. LOCAL BOOL sysTimestampRunning  = FALSE; /* timestamp running flag */
  44. #endif /* INCLUDE_TIMESTAMP */
  45. /*******************************************************************************
  46. *
  47. * sysClkInt - interrupt level processing for system clock
  48. *
  49. * This routine handles the system clock interrupt.  It is attached to the
  50. * clock interrupt vector by the routine sysClkConnect().
  51. */
  52. LOCAL void sysClkInt (void)
  53.     {
  54.     *IMP_TER1 = TER_REF_CNT; /* clear event register */
  55.     *IMP_ISR  = INT_TMR1; /* clear in-service bit */
  56.     if (sysClkRoutine != NULL)
  57.         (*sysClkRoutine) (sysClkArg);
  58.     }
  59. /*******************************************************************************
  60. *
  61. * sysAuxClkInt - interrupt level processing for auxiliary clock
  62. *
  63. * This routine handles the auxiliary clock interrupt.  It is attached to the
  64. * clock interrupt vector by the routine sysAuxClkConnect().
  65. */
  66. LOCAL void sysAuxClkInt (void)
  67.     {
  68.     *IMP_TER2 = TER_REF_CNT; /* clear event register */
  69.     *IMP_ISR  = INT_TMR2; /* clear in-service bit */
  70.     if (sysAuxClkRoutine != NULL)
  71.         (*sysAuxClkRoutine) (sysAuxClkArg);
  72.     }
  73. /*******************************************************************************
  74. *
  75. * sysClkConnect - connect a routine to the system clock interrupt
  76. *
  77. * This routine specifies the interrupt service routine to be called at each
  78. * clock interrupt.  Normally, it is called from usrRoot() in usrConfig.c to
  79. * connect usrClock() to the system clock interrupt.
  80. *
  81. * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
  82. *
  83. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  84. */
  85. STATUS sysClkConnect
  86.     (
  87.     FUNCPTR routine, /* routine to be called at each clock interrupt */
  88.     int     arg /* argument with which to call routine          */
  89.     )
  90.     {
  91.     sysHwInit2 (); /* XXX for now -- needs to be in usrConfig.c */
  92.     sysClkRoutine   = routine;
  93.     sysClkArg       = arg;
  94.     sysClkConnected = TRUE;
  95.     return (OK);
  96.     }
  97. /*******************************************************************************
  98. *
  99. * sysClkDisable - turn off system clock interrupts
  100. *
  101. * This routine disables system clock interrupts.
  102. *
  103. * RETURNS: N/A
  104. *
  105. * SEE ALSO: sysClkEnable()
  106. */
  107. void sysClkDisable (void)
  108.     {
  109.     if (sysClkRunning)
  110. {
  111. *IMP_TMR1     = TMR_STOP; /* turn off timer */
  112. *IMP_IMR     &= ~INT_TMR1; /* disable interrupt */
  113. sysClkRunning = FALSE; /* clock is no longer running */
  114. }
  115.     }
  116. /*******************************************************************************
  117. *
  118. * sysClkEnable - turn on system clock interrupts
  119. *
  120. * This routine enables system clock interrupts.
  121. *
  122. * RETURNS: N/A
  123. *
  124. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  125. */
  126. void sysClkEnable (void)
  127.     {
  128.     UINT32  tempDiv = SYS_CPU_FREQ / (sysClkTicksPerSecond << 8);
  129.     if ((!sysClkRunning) && (tempDiv <= USHRT_MAX * 16))
  130. {
  131. if (tempDiv <= USHRT_MAX)
  132.     {
  133.     *IMP_TRR1 = (UINT16) tempDiv;
  134.     *IMP_TMR1 = 0xff00 | TMR_ENABLE | TMR_CLK |     /* mpu clk/256   */
  135. TMR_RESTART | TMR_INT | TMR_CAP_DIS;/* no capture    */
  136.     }
  137. else
  138.     {
  139.     *IMP_TRR1 = (UINT16) (tempDiv / 16);
  140.     *IMP_TMR1 = 0xff00 | TMR_ENABLE | TMR_CLK16 |   /* mpu clk/4096  */
  141. TMR_RESTART | TMR_INT | TMR_CAP_DIS;/* no capture    */
  142.     }
  143. *IMP_TER1 = TER_REF_CNT;     /* clear event   */
  144. *IMP_IMR |= INT_TMR1;     /* enable intrpt */
  145. sysClkRunning = TRUE;
  146. }
  147.     }
  148. /*******************************************************************************
  149. *
  150. * sysClkRateGet - get the system clock rate
  151. *
  152. * This routine returns the system clock rate.
  153. *
  154. * RETURNS: The number of ticks per second of the system clock.
  155. *
  156. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  157. */
  158. int sysClkRateGet (void)
  159.     {
  160.     return (sysClkTicksPerSecond);
  161.     }
  162. /*******************************************************************************
  163. *
  164. * sysClkRateSet - set the system clock rate
  165. *
  166. * This routine sets the interrupt rate of the system clock.  It does not
  167. * enable system clock interrupts.  It is called by usrRoot() in
  168. * usrConfig.c.
  169. *
  170. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be
  171. * set.
  172. *
  173. * SEE ALSO: sysClkEnable(), sysClkRateGet()
  174. */
  175. STATUS sysClkRateSet
  176.     (
  177.     int ticksPerSecond     /* number of clock interrupts per second */
  178.     )
  179.     {
  180.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  181. return (ERROR);
  182.     sysClkTicksPerSecond = ticksPerSecond;
  183.     if (sysClkRunning)
  184. {
  185. sysClkDisable ();
  186. sysClkEnable ();
  187. }
  188.     return (OK);
  189.     }
  190. /*******************************************************************************
  191. *
  192. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  193. *
  194. * This routine specifies the interrupt service routine to be called at each
  195. * auxiliary clock interrupt.  It does not enable auxiliary clock
  196. * interrupts.
  197. *
  198. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  199. *
  200. * SEE ALSO: intConnect(), sysAuxClkEnable()
  201. */
  202. STATUS sysAuxClkConnect
  203.     (
  204.     FUNCPTR routine, /* routine called at each aux. clock interrupt */
  205.     int     arg /* argument to auxiliary clock interrupt routine */
  206.     )
  207.     {
  208.     sysAuxClkRoutine   = routine;
  209.     sysAuxClkArg       = arg;
  210.     auxClkConnected    = TRUE;
  211.     return (OK);
  212.     }
  213. /*******************************************************************************
  214. *
  215. * sysAuxClkDisable - turn off auxiliary clock interrupts
  216. *
  217. * This routine disables auxiliary clock interrupts.
  218. *
  219. * RETURNS: N/A
  220. *
  221. * SEE ALSO: sysAuxClkEnable()
  222. */
  223. void sysAuxClkDisable (void)
  224.     {
  225.     if (sysAuxClkRunning)
  226. {
  227. *IMP_TMR2 = TMR_STOP; /* turn off timer */
  228. *IMP_IMR &= ~INT_TMR2; /* disable interrupt */
  229. sysAuxClkRunning = FALSE;
  230. }
  231.     }
  232. /*******************************************************************************
  233. *
  234. * sysAuxClkEnable - turn on auxiliary clock interrupts
  235. *
  236. * This routine enables auxiliary clock interrupts.
  237. *
  238. * RETURNS: N/A
  239. *
  240. * SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
  241. */
  242. void sysAuxClkEnable (void)
  243.     {
  244.     UINT32  tempDiv = SYS_CPU_FREQ / (auxClkTicksPerSecond << 8);
  245.     if ((!sysAuxClkRunning) && (tempDiv <= USHRT_MAX * 16))
  246. {
  247. if (tempDiv <= USHRT_MAX)
  248.     {
  249.     *IMP_TRR2 = (UINT16) tempDiv;
  250.     *IMP_TMR2 = 0xff00 | TMR_ENABLE | TMR_CLK |     /* mpu clk/256   */
  251. TMR_RESTART | TMR_INT | TMR_CAP_DIS;/* no capture    */
  252.     }
  253. else
  254.     {
  255.     *IMP_TRR2 = (UINT16) (tempDiv / 16);
  256.     *IMP_TMR2 = 0xff00 | TMR_ENABLE | TMR_CLK16 |   /* mpu clk/4096  */
  257. TMR_RESTART | TMR_INT | TMR_CAP_DIS;/* no capture    */
  258.     }
  259. *IMP_TER1 = TER_REF_CNT;     /* clear event   */
  260. *IMP_IMR |= INT_TMR2;     /* enable intrpt */
  261. sysAuxClkRunning = TRUE;
  262. }
  263.     }
  264. /*******************************************************************************
  265. *
  266. * sysAuxClkRateGet - get the auxiliary clock rate
  267. *
  268. * This routine returns the interrupt rate of the auxiliary clock.
  269. *
  270. * RETURNS: The number of ticks per second of the auxiliary clock.
  271. *
  272. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  273. */
  274. int sysAuxClkRateGet (void)
  275.     {
  276.     return (auxClkTicksPerSecond);
  277.     }
  278. /*******************************************************************************
  279. *
  280. * sysAuxClkRateSet - set the auxiliary clock rate
  281. *
  282. * This routine sets the interrupt rate of the auxiliary clock.
  283. * It does not enable auxiliary clock interrupts.
  284. *
  285. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  286. *
  287. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  288. */
  289. STATUS sysAuxClkRateSet
  290.     (
  291.     int ticksPerSecond     /* number of clock interrupts per second */
  292.     )
  293.     {
  294.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  295. return (ERROR);
  296.     auxClkTicksPerSecond = ticksPerSecond;
  297.     if (sysAuxClkRunning)
  298. {
  299. sysAuxClkDisable ();
  300. sysAuxClkEnable ();
  301. }
  302.     return (OK);
  303.     }
  304. #ifdef INCLUDE_TIMESTAMP
  305. /*******************************************************************************
  306. *
  307. * sysTimestampConnect - connect a user routine to a timestamp timer interrupt
  308. *
  309. * This routine specifies the user interrupt routine to be called at each
  310. * timestamp timer interrupt.
  311. *
  312. * RETURNS: ERROR, always.
  313. */
  314. STATUS sysTimestampConnect
  315.     (
  316.     FUNCPTR routine,    /* routine called at each timestamp timer interrupt */
  317.     int arg             /* argument with which to call routine */
  318.     )
  319.     {
  320.     return (ERROR);
  321.     }
  322. /*******************************************************************************
  323. *
  324. * sysTimestampEnable - enable a timestamp timer interrupt
  325. *
  326. * This routine enables timestamp timer interrupts and resets the counter.
  327. *
  328. * RETURNS: OK, while sysClock is enabled.
  329. *
  330. * SEE ALSO: sysTimestampDisable()
  331. */
  332. STATUS sysTimestampEnable (void)
  333.    {
  334.    if (!sysClkRunning)
  335.        return (ERROR);
  336.    sysTimestampRunning = TRUE;
  337.    return (OK);
  338.    }
  339. /*******************************************************************************
  340. *
  341. * sysTimestampDisable - disable a timestamp timer interrupt
  342. *
  343. * This routine disables timestamp timer interrupts.
  344. *
  345. * RETURNS: OK, always.
  346. *
  347. * SEE ALSO: sysTimestampEnable()
  348. */
  349. STATUS sysTimestampDisable (void)
  350.     {
  351.     sysTimestampRunning = FALSE;
  352.     return (OK);
  353.     }
  354. /*******************************************************************************
  355. *
  356. * sysTimestampPeriod - get the period of a timestamp timer
  357. *
  358. * This routine gets the period of the timestamp timer, in ticks.  The
  359. * period, or terminal count, is the number of ticks to which the timestamp
  360. * timer counts before rolling over and restarting the counting process.
  361. *
  362. * RETURNS: The period of the timestamp timer in counter ticks.
  363. */
  364. UINT32 sysTimestampPeriod (void)
  365.     {
  366.     return (*IMP_TRR1);
  367.     }
  368. /*******************************************************************************
  369. *
  370. * sysTimestampFreq - get a timestamp timer clock frequency
  371. *
  372. * This routine gets the frequency of the timer clock, in ticks per
  373. * second.  The rate of the timestamp timer is set explicitly by the
  374. * hardware and typically cannot be altered.
  375. *
  376. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  377. */
  378. UINT32 sysTimestampFreq (void)
  379.    {
  380.    UINT32 prescale, clockDiv;
  381.    
  382.    prescale = (*IMP_TMR1 >> 8) + 1;
  383.    clockDiv = ((*IMP_TMR1 & (TMR_CLK | TMR_CLK16)) == TMR_CLK16) ? 16 : 1;
  384.    return (SYS_CPU_FREQ / (prescale * clockDiv));
  385.    }
  386. /*******************************************************************************
  387. *
  388. * sysTimestamp - get a timestamp timer tick count
  389. *
  390. * This routine returns the current value of the timestamp timer tick counter.
  391. * The tick count can be converted to seconds by dividing it by the return of
  392. * sysTimestampFreq().
  393. *
  394. * This routine should be called with interrupts locked.  If interrupts are
  395. * not locked, sysTimestampLock() should be used instead.
  396. *
  397. * RETURNS: The current timestamp timer tick count.
  398. *
  399. * SEE ALSO: sysTimestampFreq(), sysTimestampLock()
  400. */
  401. UINT32 sysTimestamp (void)
  402.     {
  403.     return ((UINT32) *IMP_TCN1);
  404.     }
  405. /*******************************************************************************
  406. *
  407. * sysTimestampLock - lock interrupts and get the timestamp timer tick count
  408. *
  409. * This routine locks interrupts when the tick counter must be stopped
  410. * in order to read it or when two independent counters must be read.
  411. * It then returns the current value of the timestamp timer tick
  412. * counter.
  413. *
  414. * The tick count can be converted to seconds by dividing it by the return of
  415. * sysTimestampFreq().
  416. *
  417. * If interrupts are already locked, sysTimestamp() should be
  418. * used instead.
  419. *
  420. * RETURNS: The current timestamp timer tick count.
  421. *
  422. * SEE ALSO: sysTimestampFreq(), sysTimestamp()
  423. */
  424. UINT32 sysTimestampLock (void)
  425.     {
  426.     /* same as sysTimestamp() */
  427.     return ((UINT32) *IMP_TCN1);
  428.     }
  429. #endif  /* INCLUDE_TIMESTAMP */