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

VxWorks

开发平台:

C/C++

  1. /* sh7615Timer.c - template timer library */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01g,21feb02,h_k  fixed timestamp interrupt enable (SPR #73506).
  7.                  removed sysTimestampPeriodValue to avoid compile warning.
  8. 01f,02nov01,zl   corrected NULL usage.
  9. 01e,06oct00,zl   corrected vectors for AUX and timestamp drivers.
  10. 01d,16sep00,zl   timestamp to use maximum period.
  11. 01c,30aug00,zl   fixed INTC_IPRD modification.
  12. 01b,20aug00,csi  added AUX clock and timestamp.
  13. 01a,11aug00,zl   written.
  14. */
  15. /*
  16. DESCRIPTION
  17. This library contains routines to manipulate the timer functions on the
  18. SH7615 on-chip timer unit (TPU) with a board-independant interface.
  19. This library handles the system clock, auxiliary clock, and timestamp
  20. timer facilities.
  21. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  22. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  23. sys[Aux]ClkRateSet() routines.
  24. To include the timestamp timer facility, the macro INCLUDE_TIMESTAMP must be
  25. defined.  The macro TIMESTAMP_LEVEL must be defined to provide the timestamp
  26. timer's interrupt level.
  27. INCLUDES:
  28. timestampDev.h
  29. */
  30. /* includes */
  31. #include "vxWorks.h"
  32. #include "config.h"
  33. #include "drv/timer/timerDev.h"
  34. #include "drv/timer/timestampDev.h"
  35. /* select tick frequency */
  36. #define TICK_FREQ (SYS_PCLK_FREQ / 64)
  37. #define TCR_DIVIDE TCR_DIV64
  38. /* The default is to assume memory mapped I/O */
  39. #ifndef SH7615TPU_READ
  40. #define SH7615TPU_READ(reg, result) 
  41. ((result) = *(reg))
  42. #endif /* SH7615TPU_READ */
  43. #ifndef SH7615TPU_WRITE
  44. #define SH7615TPU_WRITE(reg, data) 
  45. (*(reg) = (data))
  46. #endif /* SH7615TPU_WRITE */
  47. #ifndef SH7615TPU_SET
  48. #define SH7615TPU_SET(reg, data) 
  49. (*(reg) |= (data))
  50. #endif /* SH7615TPU_SET */
  51. #ifndef SH7615TPU_CLEAR
  52. #define SH7615TPU_CLEAR(reg, data) 
  53. (*(reg) &= ~(data))
  54. #endif /* SH7615TPU_CLEAR */
  55. /* locals */
  56. LOCAL FUNCPTR sysClkRoutine = NULL; /* routine to call on clock tick */
  57. LOCAL int sysClkArg = 0; /* its argument */
  58. LOCAL int sysClkRunning = FALSE;
  59. LOCAL int sysClkTicksPerSecond = 60;
  60. LOCAL FUNCPTR sysAuxClkRoutine = NULL;
  61. LOCAL int sysAuxClkArg = 0;
  62. LOCAL int sysAuxClkRunning = FALSE;
  63. LOCAL int sysAuxClkTicksPerSecond = 100;
  64. #ifdef INCLUDE_TIMESTAMP
  65. LOCAL BOOL sysTimestampRunning = FALSE; /* running flag */
  66. LOCAL FUNCPTR sysTimestampRoutine = NULL;  /* routine to call on intr */
  67. LOCAL int sysTimestampArg = 0;     /* arg for routine */
  68.       void sysTimestampInt (void);  /* forward declaration */
  69. #endif  /* INCLUDE_TIMESTAMP */
  70. /*******************************************************************************
  71. *
  72. * sysClkInt - interrupt level processing for system clock
  73. *
  74. * This routine handles an auxiliary clock interrupt.  It acknowledges the
  75. * interrupt and calls the routine installed by sysClkConnect().
  76. */
  77. void sysClkInt (void)
  78.     {
  79.     UINT8 value;
  80.     if (SH7615TPU_READ (TPU_TSR0, value), (value & TSR_TGFA) == TSR_TGFA)
  81. {
  82. /* clear the interrupt */
  83. SH7615TPU_WRITE (TPU_TSR0, (value & ~TSR_TGFA));
  84. /* call system clock service routine */
  85. if (sysClkRoutine != NULL)
  86.     (* sysClkRoutine) (sysClkArg);
  87. }
  88.     }
  89. /*******************************************************************************
  90. *
  91. * sysClkConnect - connect a routine to the system clock interrupt
  92. *
  93. * This routine specifies the interrupt service routine to be called at each
  94. * clock interrupt.  Normally, it is called from usrRoot() in usrConfig.c to 
  95. * connect usrClock() to the system clock interrupt.
  96. *
  97. * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
  98. *
  99. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  100. */
  101. STATUS sysClkConnect
  102.     (
  103.     FUNCPTR routine, /* routine to be called at each clock interrupt */
  104.     int arg /* argument with which to call routine */
  105.     )
  106.     {
  107.     static BOOL beenHere = FALSE;
  108.     if (!beenHere)
  109. {
  110. beenHere = TRUE;
  111. sysHwInit2 (); /* XXX for now -- needs to be in usrConfig.c */
  112. }
  113.     sysClkRoutine   = NULL;
  114.     sysClkArg     = arg;
  115.     sysClkRoutine   = routine;
  116.     return (OK);
  117.     }
  118. /*******************************************************************************
  119. *
  120. * sysClkDisable - turn off system clock interrupts
  121. *
  122. * This routine disables system clock interrupts.
  123. *
  124. * RETURNS: N/A
  125. *
  126. * SEE ALSO: sysClkEnable()
  127. */
  128. void sysClkDisable (void)
  129.     {
  130.     if (sysClkRunning)
  131. {
  132. /* disable system timer interrupts */
  133. SH7615TPU_WRITE (TPU_TIER0, 0);
  134. sysClkRunning = FALSE;
  135. }
  136.     }
  137. /*******************************************************************************
  138. *
  139. * sysClkEnable - turn on system clock interrupts
  140. *
  141. * This routine enables system clock interrupts.
  142. *
  143. * RETURNS: N/A
  144. *
  145. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  146. */
  147. void sysClkEnable (void)
  148.     {
  149.     static BOOL connected = FALSE;
  150.     if (!connected)
  151. {
  152. UINT16 tmp;
  153. /* Disable interrupt and clear the status register */
  154. SH7615TPU_WRITE (TPU_TIER0, 0);
  155. SH7615TPU_READ  (TPU_TSR0, tmp);
  156. SH7615TPU_WRITE (TPU_TSR0, 0);
  157. /* connect handler */
  158. intConnect(IV_TPU_TGI0A, sysClkInt, 0);
  159. /* Set system clock interrupt priority */
  160.     
  161. SH7615TPU_READ  (INTC_IPRD, tmp);
  162. SH7615TPU_WRITE (INTC_IPRD, (tmp & 0x0fff) | (INT_LVL_SYSCLK << 12));
  163. sysClkRunning = FALSE;
  164. connected = TRUE;
  165. }
  166.     if (!sysClkRunning)
  167. {
  168. /* select counter at F/64 , clear with TGRA */
  169. SH7615TPU_WRITE (TPU_TCR0, TCR_DIVIDE | TCR_TGRA);
  170. /* set period */
  171. SH7615TPU_WRITE (TPU_TGR0A, (TICK_FREQ / sysClkTicksPerSecond));
  172. /* Reset counter */
  173. SH7615TPU_WRITE (TPU_TCNT0, 0);
  174. /* enable interrupt */
  175. SH7615TPU_WRITE (TPU_TIER0, TIER_TGIEA);
  176. /* start counter */
  177. SH7615TPU_SET (TPU_TSTR, TSTR_CST0);
  178. sysClkRunning = TRUE;
  179. }
  180.     }
  181. /*******************************************************************************
  182. *
  183. * sysClkRateGet - get the system clock rate
  184. *
  185. * This routine returns the system clock rate.
  186. *
  187. * RETURNS: The number of ticks per second of the system clock.
  188. *
  189. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  190. */
  191. int sysClkRateGet (void)
  192.     {
  193.     return (sysClkTicksPerSecond);
  194.     }
  195. /*******************************************************************************
  196. *
  197. * sysClkRateSet - set the system clock rate
  198. *
  199. * This routine sets the interrupt rate of the system clock.
  200. * It is called by usrRoot() in usrConfig.c.
  201. *
  202. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  203. *
  204. * SEE ALSO: sysClkEnable(), sysClkRateGet()
  205. */
  206. STATUS sysClkRateSet
  207.     (
  208.     int ticksPerSecond     /* number of clock interrupts per second */
  209.     )
  210.     {
  211.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  212. return (ERROR);
  213.     sysClkTicksPerSecond = ticksPerSecond;
  214.     if (sysClkRunning)
  215. {
  216. sysClkDisable ();
  217. sysClkEnable ();
  218. }
  219.     return (OK);
  220.     }
  221. /*******************************************************************************
  222. *
  223. * sysAuxClkInt - handle an auxiliary clock interrupt
  224. *
  225. * This routine handles an auxiliary clock interrupt.  It acknowledges the
  226. * interrupt and calls the routine installed by sysAuxClkConnect().
  227. *
  228. * RETURNS: N/A
  229. */
  230. void sysAuxClkInt (void)
  231.     {
  232.     UINT8 value;
  233.     /* acknowledge the interrupt if needed */
  234.     if (SH7615TPU_READ (TPU_TSR1, value), (value & TSR_TGFA) == TSR_TGFA)
  235.         {
  236.         /* clear the interrupt */
  237.         SH7615TPU_WRITE (TPU_TSR1, (value & ~TSR_TGFA));
  238.         /* call auxiliary clock service routine */
  239.         if (sysAuxClkRoutine != NULL)
  240.     (*sysAuxClkRoutine) (sysAuxClkArg);
  241.         }
  242.     }
  243. /*******************************************************************************
  244. *
  245. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  246. *
  247. * This routine specifies the interrupt service routine to be called at each
  248. * auxiliary clock interrupt.  It does not enable auxiliary clock interrupts.
  249. *
  250. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  251. *
  252. * SEE ALSO: intConnect(), sysAuxClkEnable()
  253. */
  254. STATUS sysAuxClkConnect
  255.     (
  256.     FUNCPTR routine,    /* routine called at each aux clock interrupt */
  257.     int arg             /* argument to auxiliary clock interrupt routine */
  258.     )
  259.     {
  260.     sysAuxClkRoutine = NULL;
  261.     sysAuxClkArg = arg;
  262.     sysAuxClkRoutine = routine;
  263.     return (OK);
  264.     }
  265. /*******************************************************************************
  266. *
  267. * sysAuxClkDisable - turn off auxiliary clock interrupts
  268. *
  269. * This routine disables auxiliary clock interrupts.
  270. *
  271. * RETURNS: N/A
  272. *
  273. * SEE ALSO: sysAuxClkEnable()
  274. */
  275. void sysAuxClkDisable (void)
  276.     {
  277.     if (sysAuxClkRunning)
  278.         {
  279.         /* disable system timer interrupts */
  280. SH7615TPU_WRITE (TPU_TIER1, 0);
  281. sysAuxClkRunning = FALSE;
  282.         }
  283.     }
  284. /*******************************************************************************
  285. *
  286. * sysAuxClkEnable - turn on auxiliary clock interrupts
  287. *
  288. * This routine enables auxiliary clock interrupts.
  289. *
  290. * RETURNS: N/A
  291. *
  292. * SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
  293. */
  294. void sysAuxClkEnable (void)
  295.     {
  296.     static BOOL connected = FALSE;
  297.     if (!connected)
  298. {
  299. UINT16 tmp;
  300. /* Disable interrupts until it's safe */
  301. SH7615TPU_WRITE (TPU_TIER1, 0);
  302. SH7615TPU_READ  (TPU_TSR1, tmp);
  303. SH7615TPU_WRITE (TPU_TSR1, 0);
  304. /* Connect handler */
  305. intConnect (IV_TPU_TGI1A, sysAuxClkInt, 0);
  306. /* Set AUX clock interrupt priority */
  307.     
  308. SH7615TPU_READ  (INTC_IPRD, tmp);
  309. SH7615TPU_WRITE (INTC_IPRD, (tmp & 0xf0ff) | (INT_LVL_AUXCLK << 8));
  310. connected = TRUE;
  311. sysAuxClkRunning = FALSE;
  312. }
  313.     if (!sysAuxClkRunning)
  314.         {
  315.         /* select counter at F/64 , clear with TGRA */
  316. SH7615TPU_WRITE (TPU_TCR1, TCR_DIVIDE | TCR_TGRA);
  317. /* set period */
  318. SH7615TPU_WRITE (TPU_TGR1A, (TICK_FREQ / sysAuxClkTicksPerSecond));
  319. /* Reset counter */
  320. SH7615TPU_WRITE (TPU_TCNT1, 0);
  321. /* enable interrupt */
  322. SH7615TPU_WRITE (TPU_TIER1, TIER_TGIEA);
  323. /* start counter */
  324. SH7615TPU_SET (TPU_TSTR, TSTR_CST1);
  325. sysAuxClkRunning = TRUE;
  326. }
  327.     }
  328. /*******************************************************************************
  329. *
  330. * sysAuxClkRateGet - get the auxiliary clock rate
  331. *
  332. * This routine returns the interrupt rate of the auxiliary clock.
  333. *
  334. * RETURNS: The number of ticks per second of the auxiliary clock.
  335. *
  336. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  337. */
  338. int sysAuxClkRateGet (void)
  339.     {
  340.     return (sysAuxClkTicksPerSecond);
  341.     }
  342. /*******************************************************************************
  343. *
  344. * sysAuxClkRateSet - set the auxiliary clock rate
  345. *
  346. * This routine sets the interrupt rate of the auxiliary clock.  It does not
  347. * enable auxiliary clock interrupts.
  348. *
  349. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  350. *
  351. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  352. */
  353. STATUS sysAuxClkRateSet
  354.     (
  355.     int ticksPerSecond  /* number of clock interrupts per second */
  356.     )
  357.     {
  358.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  359.         return (ERROR);
  360.     sysAuxClkTicksPerSecond = ticksPerSecond;
  361.     if (sysAuxClkRunning)
  362. {
  363. sysAuxClkDisable ();
  364. sysAuxClkEnable ();
  365. }
  366.     return (OK);
  367.     }
  368. #ifdef  INCLUDE_TIMESTAMP
  369. /*******************************************************************************
  370. *
  371. * sysTimestampInt - timestamp timer interrupt handler
  372. *
  373. * This rountine handles the timestamp timer interrupt.  A user routine is
  374. * called, if one was connected by sysTimestampConnect().
  375. *
  376. * RETURNS: N/A
  377. *
  378. * SEE ALSO: sysTimestampConnect()
  379. */
  380. void sysTimestampInt (void)
  381.     {
  382.     UINT8 value;
  383.     if (SH7615TPU_READ (TPU_TSR2, value), (value & TSR_TGFA) == TSR_TGFA)
  384. {
  385. /* clear the interrupt */
  386.         SH7615TPU_WRITE (TPU_TSR2, (value & ~TSR_TGFA));
  387.         /* call system clock service routine */
  388.         if (sysTimestampRunning && sysTimestampRoutine != NULL)
  389.     (*sysTimestampRoutine)(sysTimestampArg);
  390.         }
  391.     }
  392. /*******************************************************************************
  393. *
  394. * sysTimestampConnect - connect a user routine to the timestamp timer interrupt
  395. *
  396. * This routine specifies the user interrupt routine to be called at each
  397. * timestamp timer interrupt.  It does not enable the timestamp timer itself.
  398. *
  399. * RETURNS: OK, or ERROR if sysTimestampInt() interrupt handler is not used.
  400. */
  401. STATUS sysTimestampConnect
  402.     (
  403.     FUNCPTR routine, /* routine called at each timestamp timer interrupt */
  404.     int arg /* argument with which to call routine */
  405.     )
  406.     {
  407.     sysTimestampRoutine = NULL; /* set to NULL to avoid calling old */
  408. /* routine with new argument */
  409.     sysTimestampArg = arg;
  410.     sysTimestampRoutine = routine;
  411.     return OK;
  412.     }
  413. /*******************************************************************************
  414. *
  415. * sysTimestampEnable - initialize and enable the timestamp timer
  416. *
  417. * This routine connects the timestamp timer interrupt and initializes the
  418. * counter registers.  If the timestamp timer is already running, this routine
  419. * merely resets the timer counter.
  420. *
  421. * The rate of the timestamp timer should be set explicitly within the BSP,
  422. * in the sysHwInit() routine.  This routine does not intialize the timer
  423. * rate.
  424. *
  425. * RETURNS: OK, or ERROR if hardware cannot be enabled.
  426. */
  427. STATUS sysTimestampEnable (void)
  428.     {
  429.     static BOOL connected = FALSE;
  430.     if (!connected)
  431. {
  432. UINT16 tmp;
  433. /* Disable interrupts until it's safe */
  434. SH7615TPU_WRITE (TPU_TIER2, 0);
  435. SH7615TPU_READ  (TPU_TSR2, tmp);
  436. SH7615TPU_WRITE (TPU_TSR2, 0);
  437. /* connect sysTimestamp to the appropriate interrupt */
  438. if (intConnect(IV_TPU_TGI2A, sysTimestampInt, 0) != OK)
  439.     return (ERROR);
  440. /* Set timestamp interrupt priority */
  441.     
  442. SH7615TPU_READ  (INTC_IPRD, tmp);
  443. SH7615TPU_WRITE (INTC_IPRD, (tmp & 0xff0f) | (INT_LVL_TSTAMP << 4));
  444. connected = TRUE;
  445. }
  446.     if (!sysTimestampRunning)
  447. {
  448.         /* select counter at F/64 , clear with TGRA */
  449. SH7615TPU_WRITE (TPU_TCR2, TCR_DIVIDE | TCR_TGRA);
  450. /* set rate */
  451. SH7615TPU_WRITE (TPU_TGR2A, 0xffff);
  452. /* Reset counter */
  453. SH7615TPU_WRITE (TPU_TCNT2, 0);
  454.         /* enable interrupt */
  455.         SH7615TPU_WRITE (TPU_TIER2, TIER_TGIEA);
  456.         /* start counter */
  457. SH7615TPU_SET (TPU_TSTR, TSTR_CST2);
  458. sysTimestampRunning = TRUE;
  459. }
  460.     return (OK);
  461.     }
  462. /*******************************************************************************
  463. *
  464. * sysTimestampDisable - disable the timestamp timer
  465. *
  466. * This routine disables the timestamp timer.  
  467. *
  468. * RETURNS: OK, or ERROR if timer cannot be disabled.
  469. */
  470. STATUS sysTimestampDisable (void)
  471.     {
  472.     if (sysTimestampRunning)
  473.         {
  474. /* Stop timer */
  475. SH7615TPU_CLEAR (TPU_TSTR, TSTR_CST2);
  476.         /* disable system timer interrupts */
  477.         SH7615TPU_WRITE (TPU_TIER2, 0);
  478.         sysTimestampRunning = FALSE;
  479.         }
  480.     return (OK);
  481.     }
  482. /*******************************************************************************
  483. *
  484. * sysTimestampPeriod - get the timestamp timer period
  485. *
  486. * This routine returns the period of the timestamp timer in ticks.
  487. * The period, or terminal count, is the number of ticks to which the timestamp
  488. * timer will count before rolling over and restarting the counting process.
  489. *
  490. * RETURNS: The period of the timestamp timer in counter ticks.
  491. */
  492. UINT32 sysTimestampPeriod (void)
  493.     {
  494.     return (UINT32)(0xffff);        /* highest period -> freerunning */
  495.     }
  496. /*******************************************************************************
  497. *
  498. * sysTimestampFreq - get the timestamp timer clock frequency
  499. *
  500. * This routine returns the frequency of the timer clock, in ticks per second.
  501. *
  502. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  503. */
  504. UINT32 sysTimestampFreq (void)
  505.     {
  506.     return (UINT32)(TICK_FREQ);
  507.     }
  508. /*******************************************************************************
  509. *
  510. * sysTimestamp - get the timestamp timer tick count
  511. *
  512. * This routine returns the current value of the timestamp timer tick counter.
  513. * The tick count can be converted to seconds by dividing by the return of
  514. * sysTimestampFreq().
  515. *
  516. * This routine should be called with interrupts locked.  If interrupts are
  517. * not already locked, sysTimestampLock() should be used instead.
  518. *
  519. * RETURNS: The current timestamp timer tick count.
  520. *
  521. * SEE ALSO: sysTimestampLock()
  522. */
  523. UINT32 sysTimestamp (void)
  524.     {
  525.     UINT16 result;
  526.     SH7615TPU_READ (TPU_TCNT2, result);
  527.     return (UINT32) result;
  528.     }
  529. /*******************************************************************************
  530. *
  531. * sysTimestampLock - get the timestamp timer tick count
  532. *
  533. * This routine returns the current value of the timestamp timer tick counter.
  534. * The tick count can be converted to seconds by dividing by the return of
  535. * sysTimestampFreq().
  536. *
  537. * This routine locks interrupts for cases where it is necessary to stop the
  538. * tick counter in order to read it, or when two independent counters must
  539. * be read.  If interrupts are already locked, sysTimestamp() should be
  540. * used instead.
  541. *
  542. * RETURNS: The current timestamp timer tick count.
  543. *
  544. * SEE ALSO: sysTimestamp()
  545. */
  546. UINT32 sysTimestampLock (void)
  547.     {
  548.     UINT16 result;
  549.     SH7615TPU_READ (TPU_TCNT2, result);
  550.     return (UINT32) result;
  551.     }
  552. #endif  /* INCLUDE_TIMESTAMP */