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

VxWorks

开发平台:

C/C++

  1. /* dga001Timer.c - DGA-001 Timer library */
  2. /* Copyright 1994-1998 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01o,23apr98,hk   added tkt's counter glitch filter to sysTimestamp{Lock}.
  8. 01n,09dec97,hk   changed TICK_FREQ to DGA_TICK_FREQ. added sys{Aux}ClkDisable()
  9.                  in sys{Aux}ClkConnect(). reviewed timestamp driver code.
  10. 01m,12jul97,hk   changed inclusion of multi/dga001.h to timer/dga001Timer.h.
  11. 01l,06may97,hk   added TSTAMP_USE_DGA001_TT1. added default TIMESTAMP_LEVEL.
  12. 01k,04may97,hk   merged in timestamp driver.
  13. 01f,18apr97,st   moved initialization of Timerstamp-Timer in
  14.                  sysTimestampConnect() to sysTimestampEnable().
  15. 01i,06mar97,st   added support for timestamp function for windview
  16. 01h,10nov95,hk   followed dga001.h-01j macro name changes.
  17. 01g,09nov95,hk   added more type casting. followed dga001.h 01i.
  18. 01f,08nov95,hk   changed dga001.h directory to drv/multi/.
  19. 01e,08jun95,hk   changed sysClkInt/sysAuxClkInt for CSR20 header mod.
  20. 01d,06jun95,hk   renamed timer select macros.
  21. 01c,28feb95,hk   changed sysClkConnect() and sysAuxClkConnect() to conform the
  22.  corrected IV_ defines in ivSh.h-01e. copyright 1995.
  23. 01b,09nov94,sa   fixed.
  24. 01a,08nov94,sa   derived from 01f of sh7604Timer.c.
  25. */
  26. /*
  27. DESCRIPTION
  28. This library contains routines to manipulate the timer functions on the
  29. DGA-001 chip with a board-independant interface.  This library handles both
  30. the system clock, auxiliary clock, and timestamp timer facilities.
  31. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  32. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  33. sys[Aux]ClkRateSet() routines.
  34. To include the timestamp timer facility, the macro INCLUDE_TIMESTAMP must be
  35. defined.  The macro TIMESTAMP_LEVEL must be defined to provide the timestamp
  36. timer's interrupt level.
  37. */
  38. #include "drv/timer/timerDev.h"
  39. #include "drv/timer/timestampDev.h"
  40. #include "drv/timer/dga001Timer.h"
  41. #include "config.h"
  42. /* Locals */ 
  43. #define DGA_TICK_FREQ 1000000 /* 1MHz */
  44. #ifdef SYSCLK_USE_DGA001_TT0
  45. LOCAL int     sysClkTicksPerSecond = 60; 
  46. LOCAL BOOL    sysClkRunning        = FALSE; 
  47. LOCAL FUNCPTR sysClkRoutine        = NULL; 
  48. LOCAL int     sysClkArg            = NULL; 
  49. LOCAL BOOL    sysClkConnected      = FALSE; 
  50. #endif
  51. #ifdef AUXCLK_USE_DGA001_TT1
  52. LOCAL int     auxClkTicksPerSecond = 60; 
  53. LOCAL BOOL    sysAuxClkRunning     = FALSE; 
  54. LOCAL FUNCPTR sysAuxClkRoutine     = NULL; 
  55. LOCAL int     sysAuxClkArg         = NULL;
  56. LOCAL BOOL    auxClkConnected      = FALSE; 
  57. #endif
  58. #if defined(INCLUDE_TIMESTAMP) && defined(TSTAMP_USE_DGA001_TT1)
  59. LOCAL BOOL    sysTimestampRunning  = FALSE; /* running flag */
  60. LOCAL FUNCPTR sysTimestampRoutine  = NULL; /* user rollover routine */
  61. LOCAL int     sysTimestampArg      = NULL; /* arg to user routine */
  62. #ifndef TIMESTAMP_LEVEL
  63. #error TIMESTAMP_LEVEL is not defined
  64. #endif /* ! TIMESTAMP_LEVEL */
  65. #endif /* INCLUDE_TIMESTAMP && TSTAMP_USE_DGA001_TT1 */
  66. #ifdef SYSCLK_USE_DGA001_TT0
  67. /*******************************************************************************
  68. *
  69. * sysClkInt - handle system clock interrupts
  70. *
  71. * This routine handles system clock interrupts.
  72. */
  73. LOCAL void sysClkInt (void)
  74.     {
  75.     if ( !(*DGA_CSR20 & CSR20_TT0IRQ))
  76. return;
  77.     if (sysClkRoutine != NULL)
  78. (*sysClkRoutine) (sysClkArg);
  79.     *DGA_CSR23 = (UINT32)CSR23_TT0ICL; /* clear interrupt */
  80.     }
  81. /*******************************************************************************
  82. *
  83. * sysClkConnect - connect a routine to the system clock interrupt
  84. *
  85. * This routine specifies the interrupt service routine to be called at each
  86. * clock interrupt.  Normally, it is called from usrRoot() in usrConfig.c to
  87. * connect usrClock() to the system clock interrupt.
  88. *
  89. * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
  90. *
  91. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  92. */
  93.  
  94. STATUS sysClkConnect
  95.     (
  96.     FUNCPTR routine,    /* routine called at each system clock interrupt */
  97.     int arg             /* argument with which to call routine           */
  98.     )
  99.     {
  100.     sysHwInit2 ();      /* XXX for now -- needs to be in usrConfig.c */
  101.     sysClkDisable ();
  102.     if (intConnect (INT_VEC_TT0, sysClkInt, NULL) != OK)
  103. return (ERROR);
  104.     sysClkConnected = TRUE;
  105.     sysClkRoutine   = routine;
  106.     sysClkArg       = arg;
  107.     return (OK);
  108.     }
  109. /*******************************************************************************
  110. *
  111. * sysClkDisable - turn off system clock interrupts
  112. *
  113. * This routine disables system clock interrupts.
  114. *
  115. * RETURNS: N/A
  116. *
  117. * SEE ALSO: sysClkEnable()
  118. */
  119.  
  120. void sysClkDisable (void)
  121.     {
  122.     if (sysClkRunning)
  123. {
  124. *DGA_CSR21 &= (UINT32) ~CSR21_TT0IEN; /* disable interrupt */
  125. *DGA_CSR12 &= (UINT32) ~CSR12_TT0CEN; /* stop timer */
  126. sysClkRunning = FALSE;
  127. }
  128.     }
  129. /****************************************************************************** 
  130. *
  131. * sysClkEnable - turn on system clock interrupts
  132. *
  133. * This routine enables system clock interrupts.
  134. *
  135. * RETURNS: N/A
  136. *
  137. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  138. */
  139.  
  140. void sysClkEnable (void)
  141.     {
  142.     if (!sysClkRunning)
  143. {
  144. *DGA_CSR12  = (UINT32) NULL; /* stop timer */
  145. *DGA_CSR13  = (UINT32) NULL; /* clear count */
  146. *DGA_CSR23  = (UINT32) CSR23_TT0ICL; /* clear interrupt */
  147. *DGA_CSR21 |= (UINT32) CSR21_TT0IEN; /* enable interrupt */
  148. /* load compare register with the number of micro seconds and 
  149.          * start the counter.
  150.  */
  151. *DGA_CSR12 = (UINT32)((DGA_TICK_FREQ / sysClkTicksPerSecond - 1) | 
  152. CSR12_TT0CEN);
  153. sysClkRunning = TRUE;
  154. }
  155.     }
  156. /*******************************************************************************
  157. *
  158. * sysClkRateGet - get the system clock rate
  159. *
  160. * This routine returns the system clock rate.
  161. *
  162. * RETURNS: The number of ticks per second of the system clock.
  163. *
  164. * SEE ALSO: sysClkEnable, sysClkRateSet()
  165. */
  166.  
  167. int sysClkRateGet (void)
  168.     {
  169.     return (sysClkTicksPerSecond);
  170.     }
  171. /********************************************************************************
  172. * sysClkRateSet - set the system clock rate
  173. *
  174. * This routine sets the interrupt rate of the system clock.
  175. * It is called by usrRoot() in usrConfig.c.
  176. *
  177. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be
  178. * set.
  179. *
  180. * SEE ALSO: sysClkEnable, sysClkRateGet()
  181. */
  182.  
  183. STATUS sysClkRateSet
  184.     (
  185.     int ticksPerSecond     /* number of clock interrupts per second */
  186.     )
  187.     {
  188.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  189. return (ERROR);
  190.  
  191.     sysClkTicksPerSecond = ticksPerSecond;
  192.  
  193.     if (sysClkRunning)
  194. {
  195. sysClkDisable ();
  196. sysClkEnable ();
  197. }
  198.     return (OK);
  199.     }
  200. #endif /* SYSCLK_USE_DGA001_TT0 */
  201. #ifdef AUXCLK_USE_DGA001_TT1
  202. /*******************************************************************************
  203. *
  204. * sysAuxClkInt - handle auxiliary clock interrupts
  205. */
  206.  
  207. LOCAL void sysAuxClkInt (void)
  208.     {
  209.     if ( !(*DGA_CSR20 & CSR20_TT1IRQ))
  210. return;
  211.     if (sysAuxClkRoutine != NULL)
  212. (*sysAuxClkRoutine) (sysAuxClkArg);
  213.     *DGA_CSR23 = (UINT32)CSR23_TT1ICL; /* reset clock interrupt */
  214.     }
  215. /*******************************************************************************
  216. *
  217. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  218. *
  219. * This routine specifies the interrupt service routine to be called at each
  220. * auxiliary clock interrupt.  It does not enable auxiliary clock
  221. * interrupts.
  222. *
  223. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  224. *
  225. * SEE ALSO: intConnect(), sysAuxClkEnable()
  226. */
  227.  
  228. STATUS sysAuxClkConnect
  229.     (
  230.     FUNCPTR routine,    /* routine called at each aux clock interrupt    */
  231.     int arg             /* argument to auxiliary clock interrupt routine */
  232.     )
  233.     {
  234.     sysAuxClkDisable ();
  235.     if (intConnect (INT_VEC_TT1, sysAuxClkInt, NULL) != OK)
  236. return (ERROR);
  237.     auxClkConnected  = TRUE;
  238.     sysAuxClkRoutine = routine;
  239.     sysAuxClkArg     = arg;
  240.  
  241.     return (OK);
  242.     }
  243. /*******************************************************************************
  244. *
  245. * sysAuxClkDisable - turn off auxiliary clock interrupts
  246. *
  247. * This routine disables auxiliary clock interrupts.
  248. *
  249. * RETURNS: N/A
  250. *
  251. * SEE ALSO: sysAuxClkEnable()
  252. */
  253.  
  254. void sysAuxClkDisable (void)
  255.     {
  256.     if (sysAuxClkRunning)
  257. {
  258. *DGA_CSR21 &= (UINT32) ~CSR21_TT1IEN; /* disable interrupt */
  259. *DGA_CSR14 &= (UINT32) ~CSR14_TT1CEN; /* stop timer */
  260. sysAuxClkRunning = FALSE;
  261. }
  262.     }
  263. /*******************************************************************************
  264. *
  265. * sysAuxClkEnable - turn on auxiliary clock interrupts
  266. *
  267. * This routine enables auxiliary clock interrupts.
  268. *
  269. * RETURNS: N/A
  270. *
  271. * SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
  272. */
  273.  
  274. void sysAuxClkEnable (void)
  275.     {
  276.     if (!sysAuxClkRunning)
  277. {
  278. *DGA_CSR14  = (UINT32) NULL; /* stop timer */
  279. *DGA_CSR15  = (UINT32) NULL; /* clear count */
  280. *DGA_CSR23  = (UINT32) CSR23_TT1ICL; /* clear interrupt */
  281. *DGA_CSR21 |= (UINT32) CSR21_TT1IEN; /* enable interrupt */
  282. /* load compare register with the number of micro seconds and 
  283.  * start the counter.
  284.  */
  285. *DGA_CSR14 = (UINT32)((DGA_TICK_FREQ / auxClkTicksPerSecond - 1) | 
  286. CSR14_TT1CEN);
  287. sysAuxClkRunning = TRUE;
  288. }
  289.     }
  290. /*******************************************************************************
  291. *
  292. * sysAuxClkRateGet - get the auxiliary clock rate
  293. *
  294. * This routine returns the interrupt rate of the auxiliary clock.
  295. *
  296. * RETURNS: The number of ticks per second of the auxiliary clock.
  297. *
  298. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  299. */
  300.  
  301. int sysAuxClkRateGet (void)
  302.     {
  303.     return (auxClkTicksPerSecond);
  304.     }
  305. /*******************************************************************************
  306. *
  307. * sysAuxClkRateSet - set the auxiliary clock rate
  308. *
  309. * This routine sets the interrupt rate of the auxiliary clock.
  310. * It does not enable auxiliary clock interrupts.
  311. *
  312. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  313. *
  314. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  315. */
  316.  
  317. STATUS sysAuxClkRateSet
  318.     (
  319.     int ticksPerSecond     /* number of clock interrupts per second */
  320.     )
  321.     {
  322.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  323. return (ERROR);
  324.  
  325.     auxClkTicksPerSecond = ticksPerSecond;
  326.  
  327.     if (sysAuxClkRunning)
  328. {
  329. sysAuxClkDisable ();
  330. sysAuxClkEnable ();
  331. }
  332.     return (OK);
  333.     } 
  334. #endif /* AUXCLK_USE_DGA001_TT1 */
  335. #if defined(INCLUDE_TIMESTAMP) && defined(TSTAMP_USE_DGA001_TT1)
  336. /*******************************************************************************
  337. *
  338. * sysTimestampInt - timestamp timer interrupt handler
  339. *
  340. * This rountine handles the timestamp timer interrupt.  A user routine is
  341. * called, if one was connected by sysTimestampConnect().
  342. *
  343. * RETURNS: N/A   
  344. *
  345. * SEE ALSO: sysTimestampConnect()
  346. */
  347. LOCAL void sysTimestampInt (void)
  348.     {
  349.     if (*DGA_CSR20 & CSR20_TT1IRQ)
  350. {
  351. *DGA_CSR23 = (UINT32)CSR23_TT1ICL; /* clear interrupt */
  352. if (sysTimestampRoutine != NULL)
  353.     (*sysTimestampRoutine) (sysTimestampArg); /* call user routine */
  354. }
  355.     }
  356. /*******************************************************************************
  357. *
  358. * sysTimestampConnect - connect a user routine to the timestamp timer interrupt
  359. *
  360. * This routine specifies the user interrupt routine to be called at each
  361. * timestamp timer interrupt.  It does not enable the timestamp timer itself.
  362. *
  363. * RETURNS: OK, or ERROR if sysTimestampInt() interrupt handler is not used.
  364. */
  365.  
  366. STATUS sysTimestampConnect
  367.     (
  368.     FUNCPTR routine, /* routine called at each timestamp timer interrupt */
  369.     int arg /* argument with which to call routine */
  370.     )
  371.     {
  372.     sysTimestampRoutine = routine;
  373.     sysTimestampArg     = arg;
  374.  
  375.     return (OK);
  376.     }
  377. /*******************************************************************************
  378. *
  379. * sysTimestampEnable - initialize and enable the timestamp timer
  380. *
  381. * This routine connects the timestamp timer interrupt and initializes the
  382. * counter registers.  If the timestamp timer is already running, this routine
  383. * merely resets the timer counter.
  384. *
  385. * The rate of the timestamp timer should be set explicitly within the BSP,
  386. * in the sysHwInit() routine.  This routine does not intialize the timer
  387. * rate.  
  388. *
  389. * RETURNS: OK, or ERROR if the timestamp timer cannot be enabled.
  390. */
  391.  
  392. STATUS sysTimestampEnable (void)
  393.     {
  394.     if (sysTimestampRunning)
  395. {
  396. *DGA_CSR14 &= (UINT32) ~CSR14_TT1CEN; /* stop timer */
  397. *DGA_CSR15  = (UINT32) NULL;  /* clear count */
  398. *DGA_CSR14 |= (UINT32) CSR14_TT1CEN; /* start timer */
  399. return (OK);
  400. }
  401.     
  402.     *DGA_CSR14  = (UINT32) NULL; /* stop timer */
  403.     *DGA_CSR15  = (UINT32) NULL; /* clear count */
  404.     *DGA_CSR23  = (UINT32) CSR23_TT1ICL; /* clear interrupt */
  405.     if (intConnect (INT_VEC_TT1, sysTimestampInt, NULL) != OK)
  406. return (ERROR);
  407.     *DGA_CSR25 = (UINT32)((*DGA_CSR25 & 0xff0fffff)
  408.        | (((TIMESTAMP_LEVEL >> 1) & 0x7) << 20));
  409. /* set interrupt level */
  410.     *DGA_CSR21 |= (UINT32) CSR21_TT1IEN; /* enable interrupt */
  411.     /* load compare register with the number of micro seconds and
  412.      * start the counter.
  413.      */
  414.     *DGA_CSR14 = (UINT32)(sysTimestampPeriod() | CSR14_TT1CEN);
  415.     sysTimestampRunning = TRUE;
  416.     return (OK);
  417.     }
  418. /********************************************************************************
  419. * sysTimestampDisable - disable the timestamp timer
  420. *
  421. * This routine disables the timestamp timer.  Interrupts are not disabled,
  422. * although the tick counter will not increment after the timestamp timer
  423. * is disabled, thus interrupts will no longer be generated.
  424. *
  425. * RETURNS: OK, or ERROR if the timestamp timer cannot be disabled.
  426. */
  427.  
  428. STATUS sysTimestampDisable (void)
  429.     {
  430.     if (sysTimestampRunning)
  431. {
  432. *DGA_CSR21 &= (UINT32) ~CSR21_TT1IEN; /* disable interrupt */
  433. *DGA_CSR14 &= (UINT32) ~CSR14_TT1CEN; /* stop timer */
  434. *DGA_CSR23 = (UINT32) CSR23_TT1ICL; /* clear pending interrupt */
  435. sysTimestampRunning = FALSE;
  436. }
  437.     return (OK);
  438.     }
  439. /*******************************************************************************
  440. *
  441. * sysTimestampPeriod - get the timestamp timer period
  442. *
  443. * This routine returns the period of the timestamp timer in ticks.
  444. * The period, or terminal count, is the number of ticks to which the timestamp
  445. * timer will count before rolling over and restarting the counting process.
  446. *
  447. * RETURNS: The period of the timestamp timer in counter ticks.
  448. */
  449.  
  450. UINT32 sysTimestampPeriod (void)
  451.     {
  452.     return ((UINT32)0x00ffffff); /* highest period -> freerunning */
  453.     }
  454. /*******************************************************************************
  455. *
  456. * sysTimestampFreq - get the timestamp timer clock frequency
  457. *
  458. * This routine returns the frequency of the timer clock, in ticks per second.
  459. * The rate of the timestamp timer should be set explicitly within the BSP,
  460. * in the sysHwInit() routine.
  461. *
  462. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  463. */
  464.  
  465. UINT32 sysTimestampFreq (void)
  466.     {
  467.     return ((UINT32)DGA_TICK_FREQ);
  468.     }
  469. /*******************************************************************************
  470. *
  471. * sysTimestamp - get the timestamp timer tick count
  472. *
  473. * This routine returns the current value of the timestamp timer tick counter.
  474. * The tick count can be converted to seconds by dividing by the return of
  475. * sysTimestampFreq().
  476. *
  477. * This routine should be called with interrupts locked.  If interrupts are
  478. * not already locked, sysTimestampLock() should be used instead.
  479. *
  480. * NOTE DGA-001:
  481. * The following code workarounds the DGA-001 up-counter glitch as shown below:
  482. *
  483. * .CS
  484. *     1111                                .
  485. *     1110                                :.
  486. *     1101                                ::
  487. *     1100                                ::.
  488. *     1011                             -->: :<-- (few nano seconds)
  489. *     1010                                : :
  490. *     1001                                : :            _______________
  491. *     1000                                : :____________
  492. *     0111                 _______________:
  493. *     0110  _______________
  494. *
  495. *          0              +1             +2             +3 [micro sec]
  496. * .CE
  497. *
  498. * RETURNS: The current timestamp timer tick count.
  499. *
  500. * SEE ALSO: sysTimestampLock()
  501. */
  502.  
  503. UINT32 sysTimestamp (void)
  504.     {
  505.     UINT32 cnt1 = *DGA_CSR15 & 0x00ffffff;
  506.     UINT32 cnt2 = *DGA_CSR15 & 0x00ffffff;
  507.     if (cnt1 <= cnt2) return (cnt1);
  508.     return (cnt2);
  509.     }
  510. /*******************************************************************************
  511. *
  512. * sysTimestampLock - get the timestamp timer tick count
  513. *
  514. * This routine returns the current value of the timestamp timer tick counter.
  515. * The tick count can be converted to seconds by dividing by the return of
  516. * sysTimestampFreq().
  517. *
  518. * This routine locks interrupts for cases where it is necessary to stop the
  519. * tick counter in order to read it, or when two independent counters must
  520. * be read.  If interrupts are already locked, sysTimestamp() should be
  521. * used instead.
  522. *
  523. * RETURNS: The current timestamp timer tick count.
  524. *
  525. * SEE ALSO: sysTimestamp()
  526. */
  527.  
  528. UINT32 sysTimestampLock (void)
  529.     {
  530.     int lockKey = intLock ();
  531.     UINT32 cnt1 = *DGA_CSR15 & 0x00ffffff;
  532.     UINT32 cnt2 = *DGA_CSR15 & 0x00ffffff;
  533.     intUnlock (lockKey);
  534.     if (cnt1 <= cnt2) return (cnt1);
  535.     return (cnt2);
  536.     }
  537. #endif /* INCLUDE_TIMESTAMP */