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

VxWorks

开发平台:

C/C++

  1. /* mccTimer.c - MCC Timer library */
  2. /* Copyright 1984-1996 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01e,22jul96,dat  merged in timestamp functions, from mccTimerTS.c.
  7. 01d,16apr94,dzb  changed the file name from mccTimer.c to mccTimerTS.c
  8. 01c,10jan94,dzb  added conditional compilation for INCLUDE_TIMESTAMP macro
  9.  (SPR #2773).
  10. 01b,17sep93,dzb  added timestamp timer support.
  11. 01a,07jan93,ccc  created.
  12. */
  13. /*
  14. DESCRIPTION
  15. This library contains routines to manipulate the timer functions on the
  16. MCchip with a board-independent interface.  This library handles
  17. the system clock, auxiliary clock, and timestamp timer facilities.
  18. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  19. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  20. sys[Aux]ClkRateSet() routines.
  21. To include the timestamp timer facility, the macro INCLUDE_TIMESTAMP must be
  22. defined.  The macro TIMESTAMP_LEVEL must be defined to provide the timestamp
  23. timer's interrupt level.
  24. */
  25. #include "drv/timer/timerDev.h"
  26. #include "drv/timer/timestampDev.h"
  27. /* Locals */
  28. LOCAL int     sysClkTicksPerSecond = 60;
  29. LOCAL BOOL    sysClkRunning        = FALSE;
  30. LOCAL FUNCPTR sysClkRoutine        = NULL;
  31. LOCAL int     sysClkArg            = NULL;
  32. LOCAL BOOL    sysClkConnected      = FALSE;
  33. LOCAL int     auxClkTicksPerSecond = 100;
  34. LOCAL BOOL    sysAuxClkRunning     = FALSE;
  35. LOCAL FUNCPTR sysAuxClkRoutine     = NULL;
  36. LOCAL int     sysAuxClkArg         = NULL;
  37. LOCAL BOOL    auxClkConnected      = FALSE;
  38. #ifdef INCLUDE_TIMESTAMP
  39. LOCAL BOOL    sysTimestampRunning  = FALSE; /* running flag */
  40. LOCAL FUNCPTR sysTimestampRoutine  = NULL; /* user rollover routine */
  41. LOCAL int     sysTimestampArg    = NULL; /* arg to user routine */
  42. #ifndef TIMESTAMP_LEVEL
  43. #   define TIMESTAMP_LEVEL 1
  44. #endif /*!TIMESTAMP_LEVEL*/
  45. #endif /* INCLUDE_TIMESTAMP */
  46. /*******************************************************************************
  47. *
  48. * sysClkInt - handle system clock interrupts
  49. *
  50. * This routine handles system clock interrupts.
  51. */
  52. LOCAL void sysClkInt (void)
  53.     {
  54.     /* reset clock interrupt */
  55.     *MCC_T1_IRQ_CR |=  T1_IRQ_CR_ICLR;
  56.     if (sysClkRoutine != NULL)
  57.         (*sysClkRoutine) (sysClkArg);
  58.     }
  59. /*******************************************************************************
  60. *
  61. * sysClkConnect - connect a routine to the system clock interrupt
  62. *
  63. * This routine specifies the interrupt service routine to be called at each
  64. * clock interrupt.  It does not enable system clock interrupts.  Normally,
  65. * it is called from usrRoot() in usrConfig.c to connect usrClock() to the
  66. * system clock interrupt.
  67. *
  68. * RETURN: OK, always.
  69. *
  70. * SEE ALSO: usrClock(), sysClkEnable()
  71. */
  72. STATUS sysClkConnect
  73.     (
  74.     FUNCPTR routine,    /* routine called at each system clock interrupt */
  75.     int arg             /* argument with which to call routine           */
  76.     )
  77.     {
  78.     sysHwInit2 (); /* XXX for now -- needs to be in usrConfig.c */
  79.     sysClkConnected = TRUE;
  80.     sysClkRoutine   = routine;
  81.     sysClkArg       = arg;
  82.     return (OK);
  83.     }
  84. /*******************************************************************************
  85. *
  86. * sysClkDisable - turn off system clock interrupts
  87. *
  88. * This routine disables system clock interrupts.
  89. *
  90. * RETURNS: N/A
  91. *
  92. * SEE ALSO: sysClkEnable()
  93. */
  94. void sysClkDisable (void)
  95.     {
  96.     if (sysClkRunning)
  97.         {
  98.         /* disable interrupts */
  99.         *MCC_T1_IRQ_CR = 0;
  100.         *MCC_TIMER1_CR = 0;    /* and disable counter */
  101.         sysClkRunning = FALSE;
  102.         }
  103.     }
  104. /*******************************************************************************
  105. *
  106. * sysClkEnable - turn on system clock interrupts
  107. *
  108. * This routine enables system clock interrupts.
  109. *
  110. * RETURNS: N/A
  111. *
  112. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  113. */
  114. void sysClkEnable (void)
  115.     {
  116.     if (!sysClkRunning)
  117.         {
  118.         /* load compare register with the number of micro seconds */
  119.         *MCC_TIMER1_CMP = 1000000 / sysClkTicksPerSecond;
  120.         /* enable the clock interrupt. */
  121.         *MCC_TIMER1_CNT = 0;           /* clear counter */
  122.         /* enable interrupt, clear any pending, and set IRQ level */
  123.         *MCC_T1_IRQ_CR = T1_IRQ_CR_IEN         |
  124.                          T1_IRQ_CR_ICLR        |
  125.                          SYS_CLK_LEVEL;
  126.         /* now enable timer */
  127.         *MCC_TIMER1_CR = TIMER1_CR_CEN         |
  128.                          TIMER1_CR_COC;
  129.         sysClkRunning = TRUE;
  130.         }
  131.     }
  132. /*******************************************************************************
  133. *
  134. * sysClkRateGet - get the system clock rate
  135. *
  136. * This routine returns the interrupt rate of the system clock.
  137. *
  138. * RETURNS: The number of ticks per second of the system clock.
  139. *
  140. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  141. */
  142. int sysClkRateGet (void)
  143.     {
  144.     return (sysClkTicksPerSecond);
  145.     }
  146. /*******************************************************************************
  147. *
  148. * sysClkRateSet - set the system clock rate
  149. *
  150. * This routine sets the interrupt rate of the system clock.  It does not
  151. * enable system clock interrupts.  Normally, it is called by usrRoot() in
  152. * usrConfig.c.
  153. *
  154. * RETURNS: OK, or ERROR if the tick rate is invalid.
  155. *
  156. * SEE ALSO: sysClkEnable(), sysClkRateGet()
  157. */
  158. STATUS sysClkRateSet
  159.     (
  160.     int ticksPerSecond     /* number of clock interrupts per second */
  161.     )
  162.     {
  163.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  164.         return (ERROR);
  165.     sysClkTicksPerSecond = ticksPerSecond;
  166.     if (sysClkRunning)
  167.         {
  168.         sysClkDisable ();
  169.         sysClkEnable ();
  170.         }
  171.     return (OK);
  172.     }
  173. /*******************************************************************************
  174. *
  175. * sysAuxClkInt - handle auxiliary clock interrupts
  176. *
  177. * This is the interrupt service routine for auxilliary clock interrupts.
  178. *
  179. * NOMANUAL
  180. */
  181. LOCAL void sysAuxClkInt (void)
  182.     {
  183.     /* reset clock interrupt */
  184.     *MCC_T2_IRQ_CR |=  T2_IRQ_CR_ICLR;
  185.     if (sysAuxClkRoutine != NULL)
  186.         (*sysAuxClkRoutine) (sysAuxClkArg);
  187.     }
  188. /*******************************************************************************
  189. *
  190. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  191. *
  192. * This routine specifies the interrupt service routine to be called at each
  193. * auxiliary clock interrupt.  It does not enable auxiliary clock interrupts.
  194. *
  195. * RETURNS: OK, always.
  196. *
  197. * SEE ALSO: sysAuxClkEnable()
  198. */
  199. STATUS sysAuxClkConnect
  200.     (
  201.     FUNCPTR routine,    /* routine called at each aux clock interrupt    */
  202.     int arg             /* argument to auxiliary clock interrupt routine */
  203.     )
  204.     {
  205.     auxClkConnected  = TRUE;
  206.     sysAuxClkRoutine = routine;
  207.     sysAuxClkArg     = arg;
  208.     return (OK);
  209.     }
  210. /*******************************************************************************
  211. *
  212. * sysAuxClkDisable - turn off auxiliary clock interrupts
  213. *
  214. * This routine disables auxiliary clock interrupts.
  215. *
  216. * RETURNS: N/A
  217. *
  218. * SEE ALSO: sysAuxClkEnable()
  219. */
  220. void sysAuxClkDisable (void)
  221.     {
  222.     if (sysAuxClkRunning)
  223.         {
  224.         /* disable interrupts */
  225.         *MCC_T2_IRQ_CR = 0;
  226.         *MCC_TIMER2_CR = 0;
  227.         sysAuxClkRunning = FALSE;
  228.         }
  229.     }
  230. /*******************************************************************************
  231. *
  232. * sysAuxClkEnable - turn on auxiliary clock interrupts
  233. *
  234. * This routine enables auxiliary clock interrupts.
  235. *
  236. * RETURNS: N/A
  237. *
  238. * SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
  239. */
  240. void sysAuxClkEnable (void)
  241.     {
  242.     if (!sysAuxClkRunning)
  243.         {
  244.         /* load compare register with the number of micro seconds per tick */
  245.         *MCC_TIMER2_CMP = 1000000 / auxClkTicksPerSecond;
  246.         /* enable the clock interrupt */
  247.         *MCC_TIMER2_CNT = 0;   /* clear counter */
  248.         /* enable interrupt, clear any pending, and set IRQ level */
  249.         *MCC_T2_IRQ_CR = T2_IRQ_CR_IEN         |
  250.                          T2_IRQ_CR_ICLR        |
  251.                          AUX_CLK_LEVEL;
  252.         /* now enable timer */
  253.         *MCC_TIMER2_CR = TIMER2_CR_CEN         |
  254.                          TIMER2_CR_COC;
  255.         sysAuxClkRunning = TRUE;
  256.         }
  257.     }
  258. /*******************************************************************************
  259. *
  260. * sysAuxClkRateGet - get the auxiliary clock rate
  261. *
  262. * This routine returns the interrupt rate of the auxiliary clock.
  263. *
  264. * RETURNS: The number of ticks per second of the auxiliary clock.
  265. *
  266. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  267. */
  268. int sysAuxClkRateGet (void)
  269.     {
  270.     return (auxClkTicksPerSecond);
  271.     }
  272. /*******************************************************************************
  273. *
  274. * sysAuxClkRateSet - set the auxiliary clock rate
  275. *
  276. * This routine sets the interrupt rate of the auxiliary clock.
  277. * It does not enable auxiliary clock interrupts.
  278. *
  279. * RETURNS: OK, or ERROR if the tick rate is invalid.
  280. *
  281. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  282. */
  283. STATUS sysAuxClkRateSet
  284.     (
  285.     int ticksPerSecond     /* number of clock interrupts per second */
  286.     )
  287.     {
  288.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  289.         return (ERROR);
  290.     auxClkTicksPerSecond = ticksPerSecond;
  291.     if (sysAuxClkRunning)
  292.         {
  293.         sysAuxClkDisable ();
  294.         sysAuxClkEnable ();
  295.         }
  296.     return (OK);
  297.     }
  298. #ifdef INCLUDE_TIMESTAMP
  299. /*******************************************************************************
  300. *
  301. * sysTimestampInt - timestamp timer interrupt handler
  302. *
  303. * This rountine handles the timestamp timer interrupt.  A user routine is
  304. * called, if one was connected by sysTimestampConnect().
  305. *
  306. * RETURNS: N/A
  307. *
  308. * SEE ALSO: sysTimestampConnect()
  309. */
  310. LOCAL void sysTimestampInt (void)
  311.     {
  312.     *MCC_T3_IRQ_CR |= T3_IRQ_CR_ICLR; /* acknowledge timer interrupt */
  313.     if (sysTimestampRoutine != NULL) /* call user routine */
  314.         (*sysTimestampRoutine) (sysTimestampArg);
  315.     }
  316. /*******************************************************************************
  317. *
  318. * sysTimestampConnect - connect a user routine to the timestamp timer interrupt
  319. *
  320. * This routine specifies the user interrupt routine to be called at each
  321. * timestamp timer interrupt.  It does not enable the timestamp timer itself.
  322. *
  323. * RETURNS: OK, or ERROR if sysTimestampInt() interrupt handler is not used.
  324. */
  325. STATUS sysTimestampConnect
  326.     (
  327.     FUNCPTR routine, /* routine called at each timestamp timer interrupt */
  328.     int arg /* argument with which to call routine */
  329.     )
  330.     {
  331.     sysTimestampRoutine = routine;
  332.     sysTimestampArg = arg;
  333.     return (OK);
  334.     }
  335. /*******************************************************************************
  336. *
  337. * sysTimestampEnable - initialize and enable the timestamp timer
  338. *
  339. * This routine connects 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.     static BOOL beenHere = FALSE;
  352.     if (sysTimestampRunning)
  353. {
  354. *MCC_TIMER3_CNT = 0; /* clear the counter */
  355. return (OK);
  356. }
  357.     if (!beenHere)
  358. {
  359. intConnect (INUM_TO_IVEC (MCC_INT_VEC_BASE + MCC_INT_TT3),
  360.    sysTimestampInt, NULL);
  361. beenHere = TRUE;
  362. }
  363.     sysTimestampRunning = TRUE;
  364.     /* reset & enable the timestamp timer interrupt */
  365.     *MCC_T3_IRQ_CR = T3_IRQ_CR_IEN | T3_IRQ_CR_ICLR | TIMESTAMP_LEVEL;
  366.     *MCC_TIMER3_CMP = sysTimestampPeriod (); /* set the timer period */
  367.     *MCC_TIMER3_CNT = 0; /* clear the counter */
  368.     *MCC_TIMER3_CR = TIMER3_CR_CEN; /* enable the timer */
  369.     return (OK);
  370.     }
  371. /*******************************************************************************
  372. *
  373. * sysTimestampDisable - disable the timestamp timer
  374. *
  375. * This routine disables the timestamp timer.  Interrupts are not disabled,
  376. * although the tick counter will not increment after the timestamp timer
  377. * is disabled, thus interrupts will no longer be generated.
  378. *
  379. * RETURNS: OK, or ERROR if the timestamp timer cannot be disabled.
  380. */
  381. STATUS sysTimestampDisable (void)
  382.     {
  383.     if (sysTimestampRunning)
  384. {
  385.         *MCC_TIMER3_CR = TIMER3_CR_DIS; /* disable the timer */
  386.         sysTimestampRunning = FALSE;
  387. }
  388.     return (OK);
  389.     }
  390. /*******************************************************************************
  391. *
  392. * sysTimestampPeriod - get the timestamp timer period
  393. *
  394. * This routine returns the period of the timestamp timer in ticks.
  395. * The period, or terminal count, is the number of ticks to which the timestamp
  396. * timer will count before rolling over and restarting the counting process.
  397. *
  398. * RETURNS: The period of the timestamp timer in counter ticks.
  399. */
  400. UINT32 sysTimestampPeriod (void)
  401.     {
  402.     return (0xffffffff); /* highest period -> freerunning */
  403.     }
  404. /*******************************************************************************
  405. *
  406. * sysTimestampFreq - get the timestamp timer clock frequency
  407. *
  408. * This routine returns the frequency of the timer clock, in ticks per second.
  409. * The rate of the timestamp timer should be set explicitly within the BSP,
  410. * in the sysHwInit() routine.
  411. *
  412. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  413. */
  414. UINT32 sysTimestampFreq (void)
  415.     {
  416.     UINT32 timerFreq;
  417.     UINT32 Bclk;
  418.     if (*MCC_VERSION_REG & VERSION_REG_SPEED) /* check clock speed */
  419.         Bclk = 33000000;
  420.     else
  421. Bclk = 25000000;
  422.     timerFreq = Bclk/(256 - (*MCC_PRESCALE_CLK_ADJ & 0xff));
  423.     return (timerFreq);
  424.     }
  425. /*******************************************************************************
  426. *
  427. * sysTimestamp - get the timestamp timer tick count
  428. *
  429. * This routine returns the current value of the timestamp timer tick counter.
  430. * The tick count can be converted to seconds by dividing by the return of
  431. * sysTimestampFreq().
  432. *
  433. * This routine should be called with interrupts locked.  If interrupts are
  434. * not already locked, sysTimestampLock() should be used instead.
  435. *
  436. * RETURNS: The current timestamp timer tick count.
  437. *
  438. * SEE ALSO: sysTimestampLock()
  439. */
  440. UINT32 sysTimestamp (void)
  441.     {
  442.     return (*MCC_TIMER3_CNT);
  443.     }
  444. /*******************************************************************************
  445. *
  446. * sysTimestampLock - get the timestamp timer tick count
  447. *
  448. * This routine returns the current value of the timestamp timer tick counter.
  449. * The tick count can be converted to seconds by dividing by the return of
  450. * sysTimestampFreq().
  451. *
  452. * This routine locks interrupts for cases where it is necessary to stop the
  453. * tick counter in order to read it, or when two independent counters must
  454. * be read.  If interrupts are already locked, sysTimestamp() should be
  455. * used instead.
  456. *
  457. * RETURNS: The current timestamp timer tick count.
  458. *
  459. * SEE ALSO: sysTimestamp()
  460. */
  461. UINT32 sysTimestampLock (void)
  462.     {
  463.     return (*MCC_TIMER3_CNT);
  464.     }
  465. #endif /* INCLUDE_TIMESTAMP */