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

VxWorks

开发平台:

C/C++

  1. /* ambaTimer.c - Advanced RISC Machines AMBA timer library */
  2. /* Copyright 1996-2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01l,18apr02,dat  null check in sysClkConnect, SPR 26729
  8. 01k,31oct01,rec  integrator AP changes
  9. 01j,04sep98,cdp  enable Thumb support for all ARM CPUs with ARM_THUMB==TRUE.
  10. 01i.10mar98,jpd  comments/layout tidying.
  11. 01h,23jan98,jpd  fixed bug in sysAuxClkConnect() (SPR #20349)
  12. 01g,11dec97,kkk  fixed typo in AMBA_TIMER_READ macro.
  13. 01f,02dec97,jpd  updated to latest coding standards.
  14. 01e,28oct97,cdp  set b0 in sysClkConnect/sysAuxClkConnect for Thumb.
  15. 01d,28oct97,tam  added TIMESTAMP support.
  16. 01c,08oct97,kkk  fixed bug in sysClkConnect().
  17. 01b,18aug97,jpd  Made more generic.
  18. 01a,09jul96,jpd  Written, based on i8253Timer.c, version 01i.
  19. */
  20. /*
  21. DESCRIPTION
  22. This library contains routines to manipulate the timer functions on an
  23. AMBA timer with a mostly board-independent interface. This driver
  24. provides 3 main functions, system clock support, auxiliary clock
  25. support, and timestamp timer support.  The timestamp function is always
  26. conditional upon the INCLUDE_TIMESTAMP macro.
  27. The AMBA Timer is a generic design of timer used within a number of
  28. systems including the ARM PID7T development system and the Digital
  29. Semiconductor 21285 chips as used in the EBSA-285 Evaluation Board.
  30. Different implementations of the design may vary slightly, such as
  31. providing more timers.
  32. Two timers are defined as the minimum (21285 provides 4). Each timer is
  33. a down counter (16 bits wide in PID7T, 24 on 21285), with selectable
  34. pre-scale.
  35. Two modes of operation are available, free-running and periodic timer.
  36. In periodic timer mode, the counter will generate an interrupt at a
  37. constant interval. In free-running mode, the timer will underflow after
  38. reaching its zero value and continue to count down from the maximum
  39. value.
  40. The timer is loaded by writing to the Load register, and then, if
  41. enabled, the timer will count down to zero. On reaching a count of
  42. zero, an interrupt will be generated. The interrupt may be cleared by
  43. writing to the Clear register.
  44. After reaching a zero count, if the timer is operating in free-running
  45. mode, then the timer will continue to decrement from its maximum value.
  46. If periodic timer mode is selected, then the timer will reload from the
  47. Load register and continue to decrement. In this mode, the timer will
  48. effectively generate a periodic interrupt. The mode is selected by a
  49. bit in the Control register and the timer is enabled by a bit in the
  50. Control register. At reset, the timer will be disabled, the interrupt
  51. will be cleared and the Load register will be undefined. The mode and
  52. pre-scale vale will also be undefined.
  53. At any time, the current timer value may be read from the Value register.
  54. The timer clock is generated by a pre-scale unit. The timer clock may
  55. be fed by the system clock or an external clock, then divided by 1, 16,
  56. or 256, which is generated by 0, 4 or 8 bits of pre-scale.
  57. REGISTERS:
  58. LOAD: (read/write) The load register contains the initial value of the timer
  59. and is also used as the reload value in periodic timer mode. When writing to
  60. this register, the unused high bits should be written as 0, and when reading,
  61. the unused bits will be undefined.
  62. VALUE: (read only) The Value location gives the current value of the timer.
  63. When reading this location, the unused bits are undefined.
  64. CLEAR: (write only) Writing to the Clear location clears an interrupt generated
  65. by the counter/timer.
  66. CTRL: (read/write) The Control register provides enable/disable, mode,
  67. pre-scale and clock source configurations for the timer.
  68. bits
  69. 0:1 unused
  70. 2:3 prescale: 00 = system clock divded by 1
  71.               01 = system clock divded by 16
  72.               10 = system clock divded by 256
  73.               11 = fed by external clock source (21285)
  74. 4:5 unused
  75. 6   mode:     0 => free-running
  76.       1 => periodic
  77. 7   enable:   0 => disable
  78.       1 => enable
  79. all unused bits must be written as zero and read as undefined.
  80. Only periodic mode is explicitly supported by this driver.
  81. Configuration of the control register is done via macros, so the BSP
  82. can choose suitable configuration values.
  83. Note that the system clock timer provides for the timestamp facility as
  84. well, therefore changing the system clock rate will affect the
  85. timestamp timer period, which can be read by calling
  86. sysTimestampPeriod().
  87. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  88. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  89. sys[Aux]ClkRateSet() routines.  The following macros must also be defined:
  90. SYS_TIMER_CLK /@ frequency of clock feeding SYS_CLK timer @/
  91. AUX_TIMER_CLK /@ frequency of clock feeding AUX_CLK @/
  92. AMBA_RELOAD_TICKS /@ any overhead in ticks when timer reloads @/
  93. SYS_TIMER_CLEAR /@ addresses of timer registers @/
  94. SYS_TIMER_CTRL /@ "" @/
  95. SYS_TIMER_LOAD /@ "" @/
  96. SYS_TIMER_VALUE /@ "" @/
  97. AUX_TIMER_CLEAR /@ "" @/
  98. AUX_TIMER_CTRL /@ "" @/
  99. AUX_TIMER_LOAD /@ "" @/
  100. AUX_TIMER_VALUE /@ "" @/
  101. SYS_TIMER_INT_LVL /@ interrupt level for sys Clk @/
  102. AUX_TIMER_INT_LVL /@ interrupt level for aux Clk @/
  103. AMBA_TIMER_SYS_TC_DISABLE /@ Control register values used when @/
  104. AMBA_TIMER_SYS_TC_ENABLE /@ enabling and disabling the two timers @/
  105. AMBA_TIMER_AUX_TC_DISABLE /@ "" @/
  106. AMBA_TIMER_AUX_TC_ENABLE /@ "" @/
  107. The following may also be defined, if required:
  108. AMBA_TIMER_READ (reg, result) /@ read an AMBA timer register @/
  109. AMBA_TIMER_WRITE (reg, data) /@ write ... @/
  110. AMBA_TIMER_INT_ENABLE (level) /@ enable an interrupt @/
  111. AMBA_TIMER_INT_DISABLE (level) /@ disable an interrpt @/
  112. BSP
  113. Apart from defining such macros described above as are needed, the BSP
  114. will need to connect the interrupt handlers (typically in sysHwInit2()).
  115. e.g.
  116. .CS
  117.     /@ connect sys clock interrupt and auxiliary clock interrupt @/
  118.     intConnect (INUM_TO_IVEC (INT_VEC...), sysClkInt, 0);
  119.     intConnect (INUM_TO_IVEC (INT_VEC...), sysAuxClkInt, 0);
  120. .CE
  121. INCLUDES:
  122. ambaTimer.h
  123. timestampDev.h
  124. SEE ALSO:
  125. .I "ARM Reference Peripheral Specification, ARM DDI 0062D,"
  126. .I "AMBA Timer Data Sheet, ARM DDI 0049B,"
  127. .I "ARM Target Development System User Guide, ARM DUI 0061A,"
  128. .I "Digital Semiconductor 21285 Core Logic for SA-110 Microprocessor Data
  129. Sheet."
  130. */
  131. /* includes */
  132. #include "drv/timer/ambaTimer.h"
  133. #include "drv/timer/timestampDev.h"
  134. /* defines */
  135. #ifndef AMBA_TIMER_READ
  136. #define AMBA_TIMER_READ(reg, result) 
  137. ((result) = *((volatile UINT32 *)(reg)))
  138. #endif /* AMBA_TIMER_READ */
  139. #ifndef AMBA_TIMER_WRITE
  140. #define AMBA_TIMER_WRITE(reg, data) 
  141. (*((volatile UINT32 *)(reg)) = (data))
  142. #endif /* AMBA_TIMER_WRITE */
  143. #ifndef AMBA_TIMER_INT_ENABLE
  144. #define AMBA_TIMER_INT_ENABLE(level) intEnable (level)
  145. #endif
  146. #ifndef AMBA_TIMER_INT_DISABLE
  147. #define AMBA_TIMER_INT_DISABLE(level) intDisable (level)
  148. #endif
  149. /* locals */
  150. LOCAL FUNCPTR sysClkRoutine = NULL; /* routine to call on clock interrupt */
  151. LOCAL int sysClkArg = 0;    /* its argument */
  152. LOCAL int sysClkRunning = FALSE;
  153. LOCAL int sysClkConnected = FALSE;
  154. LOCAL int sysClkTicksPerSecond = 60;
  155. LOCAL FUNCPTR sysAuxClkRoutine = NULL;
  156. LOCAL int sysAuxClkArg = 0;
  157. LOCAL int sysAuxClkRunning = FALSE;
  158. LOCAL int sysAuxClkTicksPerSecond = 100;
  159. #ifdef INCLUDE_TIMESTAMP
  160. LOCAL BOOL sysTimestampRunning   = FALSE;   /* timestamp running flag */
  161. #endif /* INCLUDE_TIMESTAMP */
  162. #if !defined (SYS_CLK_RATE_MIN) || !defined (SYS_CLK_RATE_MAX) || 
  163.     !defined (AUX_CLK_RATE_MIN) || !defined (AUX_CLK_RATE_MAX) || 
  164.     !defined (SYS_TIMER_CLK) || !defined (AUX_TIMER_CLK) || 
  165.     !defined (AMBA_RELOAD_TICKS) || !defined (SYS_TIMER_CLEAR) || 
  166.     !defined (SYS_TIMER_CTRL) || !defined (SYS_TIMER_LOAD) || 
  167.     !defined (SYS_TIMER_VALUE) || !defined (AUX_TIMER_CLEAR) || 
  168.     !defined (AUX_TIMER_CTRL) || !defined (AUX_TIMER_LOAD) || 
  169.     !defined (AUX_TIMER_VALUE) || !defined (SYS_TIMER_INT_LVL) || 
  170.     !defined (AUX_TIMER_INT_LVL) || !defined (AMBA_TIMER_SYS_TC_DISABLE) || 
  171.     !defined (AMBA_TIMER_SYS_TC_ENABLE) || 
  172.     !defined (AMBA_TIMER_AUX_TC_ENABLE) || !defined (AMBA_TIMER_AUX_TC_DISABLE)
  173. #error missing #defines in ambaTimer.c.
  174. #endif
  175. /*******************************************************************************
  176. *
  177. * sysClkInt - interrupt level processing for system clock
  178. *
  179. * This routine handles the system clock interrupt.  It is attached to the
  180. * clock interrupt vector by the routine sysClkConnect().
  181. *
  182. * RETURNS: N/A.
  183. */
  184. LOCAL void sysClkInt (void)
  185.     {
  186.     /* acknowledge interrupt: any write to Clear Register clears interrupt */
  187.     AMBA_TIMER_WRITE (SYS_TIMER_CLEAR (AMBA_TIMER_BASE), 0);
  188.     /* If any routine attached via sysClkConnect(), call it */
  189.     if (sysClkRoutine != NULL)
  190. (* sysClkRoutine) (sysClkArg);
  191.     }
  192. /*******************************************************************************
  193. *
  194. * sysClkConnect - connect a routine to the system clock interrupt
  195. *
  196. * This routine specifies the interrupt service routine to be called at each
  197. * clock interrupt.  It does not enable system clock interrupts.
  198. * Normally it is called from usrRoot() in usrConfig.c to connect
  199. * usrClock() to the system clock interrupt.
  200. *
  201. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  202. *
  203. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  204. */
  205. STATUS sysClkConnect
  206.     (
  207.     FUNCPTR routine, /* routine to be called at each clock interrupt */
  208.     int arg /* argument with which to call routine */
  209.     )
  210.     {
  211.     if (sysClkConnected == FALSE)
  212.      {
  213.      sysHwInit2 (); /* XXX for now -- needs to be in usrConfig.c */
  214.      sysClkConnected = TRUE;
  215.      }
  216.     sysClkRoutine = NULL; /* ensure routine not called with wrong arg */
  217.     sysClkArg   = arg;
  218.     if (routine == NULL)
  219. return OK;
  220. #if ((CPU_FAMILY == ARM) && ARM_THUMB)
  221.     /* set b0 so that sysClkConnect() can be used from shell */
  222.     sysClkRoutine = (FUNCPTR)((UINT32)routine | 1);
  223. #else
  224.     sysClkRoutine = routine;
  225. #endif /* CPU_FAMILY == ARM */
  226.     return OK;
  227.     }
  228. /*******************************************************************************
  229. *
  230. * sysClkDisable - turn off system clock interrupts
  231. *
  232. * This routine disables system clock interrupts.
  233. *
  234. * RETURNS: N/A
  235. *
  236. * SEE ALSO: sysClkEnable()
  237. */
  238. void sysClkDisable (void)
  239.     {
  240.     if (sysClkRunning)
  241. {
  242. /*
  243.  * Disable timer itself. Might as well leave it configured for
  244.  * Periodic mode, divided by 16.
  245.  */
  246. AMBA_TIMER_WRITE(
  247.    SYS_TIMER_CTRL (AMBA_TIMER_BASE), AMBA_TIMER_SYS_TC_DISABLE);
  248. /* Disable the timer interrupt in the Interrupt Controller */
  249. AMBA_TIMER_INT_DISABLE (SYS_TIMER_INT_LVL);
  250. sysClkRunning = FALSE;
  251. }
  252.     }
  253. /*******************************************************************************
  254. *
  255. * sysClkEnable - turn on system clock interrupts
  256. *
  257. * This routine enables system clock interrupts.
  258. *
  259. * RETURNS: N/A
  260. *
  261. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  262. */
  263. void sysClkEnable (void)
  264.     {
  265.     UINT32 tc;
  266.     if (!sysClkRunning)
  267. {
  268. /* Set up in periodic mode, divide clock input by 16, enable timer */
  269. AMBA_TIMER_WRITE(
  270.     SYS_TIMER_CTRL (AMBA_TIMER_BASE), AMBA_TIMER_SYS_TC_ENABLE);
  271. /*
  272.  * Calculate the timer value
  273.  * Note that it may take some ticks to reload the counter
  274.  * so counter value = (clock rate / sysClkTicksPerSecond) - num_ticks
  275.  */
  276. tc = (SYS_TIMER_CLK / sysClkTicksPerSecond) - AMBA_RELOAD_TICKS;
  277. /* Load Timer Reload value into Timer registers */
  278. AMBA_TIMER_WRITE (SYS_TIMER_LOAD (AMBA_TIMER_BASE), tc);
  279. /* enable clock interrupt in interrupt controller */
  280. AMBA_TIMER_INT_ENABLE (SYS_TIMER_INT_LVL);
  281. sysClkRunning = TRUE;
  282. }
  283.     }
  284. /*******************************************************************************
  285. *
  286. * sysClkRateGet - get the system clock rate
  287. *
  288. * This routine returns the interrupt rate of the system clock.
  289. *
  290. * RETURNS: The number of ticks per second of the system clock.
  291. *
  292. * SEE ALSO: sysClkRateSet(), sysClkEnable()
  293. */
  294. int sysClkRateGet (void)
  295.     {
  296.     return sysClkTicksPerSecond;
  297.     }
  298. /*******************************************************************************
  299. *
  300. * sysClkRateSet - set the system clock rate
  301. *
  302. * This routine sets the interrupt rate of the system clock.  It does not
  303. * enable system clock interrupts unilaterally, but if the system clock is
  304. * currently enabled, the clock is disabled and then re-enabled with the new
  305. * rate.  Normally it is called by usrRoot() in usrConfig.c.
  306. *
  307. * RETURNS:
  308. * OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  309. *
  310. * SEE ALSO: sysClkRateGet(), sysClkEnable()
  311. */
  312. STATUS sysClkRateSet
  313.     (
  314.     int ticksPerSecond     /* number of clock interrupts per second */
  315.     )
  316.     {
  317.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  318. return ERROR;
  319.     sysClkTicksPerSecond = ticksPerSecond;
  320.     if (sysClkRunning)
  321. {
  322. sysClkDisable ();
  323. sysClkEnable ();
  324. }
  325.     return OK;
  326.     }
  327. /*******************************************************************************
  328. *
  329. * sysAuxClkInt - handle an auxiliary clock interrupt
  330. *
  331. * This routine handles an auxiliary clock interrupt.  It acknowledges the
  332. * interrupt and calls the routine installed by sysAuxClkConnect().
  333. *
  334. * RETURNS: N/A
  335. */
  336. LOCAL void sysAuxClkInt (void)
  337.     {
  338.     /* Acknowledge interrupt: any write to Clear Register clears interrupt */
  339.     AMBA_TIMER_WRITE (AUX_TIMER_CLEAR (AMBA_TIMER_BASE), 0);
  340.     /* If any routine attached via sysAuxClkConnect(), call it */
  341.     if (sysAuxClkRoutine != NULL)
  342. (*sysAuxClkRoutine) (sysAuxClkArg);
  343.     }
  344. /*******************************************************************************
  345. *
  346. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  347. *
  348. * This routine specifies the interrupt service routine to be called at each
  349. * auxiliary clock interrupt.  It also connects the clock error interrupt
  350. * service routine.
  351. *
  352. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  353. *
  354. * SEE ALSO: intConnect(), sysAuxClkEnable()
  355. */
  356. STATUS sysAuxClkConnect
  357.     (
  358.     FUNCPTR routine,    /* routine called at each aux clock interrupt */
  359.     int arg             /* argument with which to call routine        */
  360.     )
  361.     {
  362.     sysAuxClkRoutine = NULL; /* ensure routine not called with wrong arg */
  363.     sysAuxClkArg = arg;
  364.     if (routine == NULL)
  365. return OK;
  366. #if ((CPU_FAMILY == ARM) && ARM_THUMB)
  367.     /* set b0 so that sysAuxClkConnect() can be used from shell */
  368.     sysAuxClkRoutine = (FUNCPTR)((UINT32)routine | 1);
  369. #else
  370.     sysAuxClkRoutine = routine;
  371. #endif /* CPU_FAMILY == ARM */
  372.     return OK;
  373.     }
  374. /*******************************************************************************
  375. *
  376. * sysAuxClkDisable - turn off auxiliary clock interrupts
  377. *
  378. * This routine disables auxiliary clock interrupts.
  379. *
  380. * RETURNS: N/A
  381. *
  382. * SEE ALSO: sysAuxClkEnable()
  383. */
  384. void sysAuxClkDisable (void)
  385.     {
  386.     if (sysAuxClkRunning)
  387.         {
  388. /*
  389.  * Disable timer itself. Might as well leave it configured for
  390.  * Periodic mode, divided by 16.
  391.  */
  392. AMBA_TIMER_WRITE(
  393.    AUX_TIMER_CTRL (AMBA_TIMER_BASE), AMBA_TIMER_AUX_TC_DISABLE);
  394. /* Disable the timer interrupt in the Interrupt Controller */
  395. AMBA_TIMER_INT_DISABLE (AUX_TIMER_INT_LVL);
  396. sysAuxClkRunning = FALSE;
  397.         }
  398.     }
  399. /*******************************************************************************
  400. *
  401. * sysAuxClkEnable - turn on auxiliary clock interrupts
  402. *
  403. * This routine enables auxiliary clock interrupts.
  404. *
  405. * RETURNS: N/A
  406. *
  407. * SEE ALSO: sysAuxClkDisable()
  408. */
  409. void sysAuxClkEnable (void)
  410.     {
  411.     UINT32 tc;
  412.     if (!sysAuxClkRunning)
  413. {
  414. /* Set up in periodic mode, divide clock input by 16, enable timer */
  415. AMBA_TIMER_WRITE(
  416.     AUX_TIMER_CTRL (AMBA_TIMER_BASE), AMBA_TIMER_AUX_TC_ENABLE);
  417. /*
  418.  * Calculate the timer value
  419.  * Note that it may take some ticks to reload the counter
  420.  * so counter value = (clock rate / sysAuxClkTicksPerSecond) - num_ticks
  421.  */
  422. tc = (AUX_TIMER_CLK / sysAuxClkTicksPerSecond) - AMBA_RELOAD_TICKS;
  423. /* Load Timer Reload value into Timer registers */
  424. AMBA_TIMER_WRITE (AUX_TIMER_LOAD (AMBA_TIMER_BASE), tc);
  425. /* enable clock interrupt in interrupt controller */
  426. AMBA_TIMER_INT_ENABLE (AUX_TIMER_INT_LVL);
  427. sysAuxClkRunning = TRUE;
  428. }
  429.     }
  430. /*******************************************************************************
  431. *
  432. * sysAuxClkRateGet - get the auxiliary clock rate
  433. *
  434. * This routine returns the interrupt rate of the auxiliary clock.
  435. *
  436. * RETURNS: The number of ticks per second of the auxiliary clock.
  437. *
  438. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  439. */
  440. int sysAuxClkRateGet (void)
  441.     {
  442.     return sysAuxClkTicksPerSecond;
  443.     }
  444. /*******************************************************************************
  445. *
  446. * sysAuxClkRateSet - set the auxiliary clock rate
  447. *
  448. * This routine sets the interrupt rate of the auxiliary clock.  It does
  449. * not enable auxiliary clock interrupts unilaterally, but if the
  450. * auxiliary clock is currently enabled, the clock is disabled and then
  451. * re-enabled with the new rate.
  452. *
  453. * RETURNS: OK or ERROR.
  454. *
  455. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  456. */
  457. STATUS sysAuxClkRateSet
  458.     (
  459.     int ticksPerSecond     /* number of clock interrupts per second */
  460.     )
  461.     {
  462.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  463. return ERROR;
  464.     sysAuxClkTicksPerSecond = ticksPerSecond;
  465.     if (sysAuxClkRunning)
  466. {
  467. sysAuxClkDisable ();
  468. sysAuxClkEnable ();
  469. }
  470.     return OK;
  471.     }
  472. #ifdef INCLUDE_TIMESTAMP
  473. /*******************************************************************************
  474. *
  475. * sysTimestampConnect - connect a user routine to a timestamp timer interrupt
  476. *
  477. * This routine specifies the user interrupt routine to be called at each
  478. * timestamp timer interrupt.
  479. *
  480. * RETURNS: ERROR, always.
  481. */
  482. STATUS sysTimestampConnect
  483.     (
  484.     FUNCPTR routine,    /* routine called at each timestamp timer interrupt */
  485.     int arg             /* argument with which to call routine */
  486.     )
  487.     {
  488.     return ERROR;
  489.     }
  490. /*******************************************************************************
  491. *
  492. * sysTimestampEnable - enable a timestamp timer interrupt
  493. *
  494. * This routine enables timestamp timer interrupts and resets the counter.
  495. *
  496. * RETURNS: OK, always.
  497. *
  498. * SEE ALSO: sysTimestampDisable()
  499. */
  500. STATUS sysTimestampEnable (void)
  501.    {
  502.    if (sysTimestampRunning)
  503.       {
  504.       return OK;
  505.       }
  506.    if (!sysClkRunning)          /* timestamp timer is derived from the sysClk */
  507.       return ERROR;
  508.    sysTimestampRunning = TRUE;
  509.    return OK;
  510.    }
  511. /*******************************************************************************
  512. *
  513. * sysTimestampDisable - disable a timestamp timer interrupt
  514. *
  515. * This routine disables timestamp timer interrupts.
  516. *
  517. * RETURNS: OK, always.
  518. *
  519. * SEE ALSO: sysTimestampEnable()
  520. */
  521. STATUS sysTimestampDisable (void)
  522.     {
  523.     if (sysTimestampRunning)
  524.         sysTimestampRunning = FALSE;
  525.     return OK;
  526.     }
  527. /*******************************************************************************
  528. *
  529. * sysTimestampPeriod - get the period of a timestamp timer
  530. *
  531. * This routine gets the period of the timestamp timer, in ticks.  The
  532. * period, or terminal count, is the number of ticks to which the timestamp
  533. * timer counts before rolling over and restarting the counting process.
  534. *
  535. * RETURNS: The period of the timestamp timer in counter ticks.
  536. */
  537. UINT32 sysTimestampPeriod (void)
  538.     {
  539.     /*
  540.      * The period of the timestamp depends on the clock rate of the system
  541.      * clock.
  542.      */
  543.     return ((UINT32)(SYS_TIMER_CLK / sysClkTicksPerSecond));
  544.     }
  545. /*******************************************************************************
  546. *
  547. * sysTimestampFreq - get a timestamp timer clock frequency
  548. *
  549. * This routine gets the frequency of the timer clock, in ticks per
  550. * second.  The rate of the timestamp timer is set explicitly by the
  551. * hardware and typically cannot be altered.
  552. *
  553. * NOTE: Because the system clock serves as the timestamp timer,
  554. * the system clock frequency is also the timestamp timer frequency.
  555. *
  556. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  557. */
  558. UINT32 sysTimestampFreq (void)
  559.     {
  560.     return ((UINT32)SYS_TIMER_CLK);
  561.     }
  562. /*******************************************************************************
  563. *
  564. * sysTimestamp - get a timestamp timer tick count
  565. *
  566. * This routine returns the current value of the timestamp timer tick counter.
  567. * The tick count can be converted to seconds by dividing it by the return of
  568. * sysTimestampFreq().
  569. *
  570. * This routine should be called with interrupts locked.  If interrupts are
  571. * not locked, sysTimestampLock() should be used instead.
  572. *
  573. * RETURNS: The current timestamp timer tick count.
  574. *
  575. * SEE ALSO: sysTimestampFreq(), sysTimestampLock()
  576. */
  577. UINT32 sysTimestamp (void)
  578.     {
  579.     UINT32 t;
  580.     AMBA_TIMER_READ (SYS_TIMER_VALUE (AMBA_TIMER_BASE), t);
  581. #if defined (AMBA_TIMER_VALUE_MASK)
  582.     t &= AMBA_TIMER_VALUE_MASK;
  583. #endif
  584.     return (sysTimestampPeriod() - t);
  585.     }
  586. /*******************************************************************************
  587. *
  588. * sysTimestampLock - lock interrupts and get the timestamp timer tick count
  589. *
  590. * This routine locks interrupts when the tick counter must be stopped
  591. * in order to read it or when two independent counters must be read.
  592. * It then returns the current value of the timestamp timer tick
  593. * counter.
  594. *
  595. * The tick count can be converted to seconds by dividing it by the return of
  596. * sysTimestampFreq().
  597. *
  598. * If interrupts are already locked, sysTimestamp() should be
  599. * used instead.
  600. *
  601. * RETURNS: The current timestamp timer tick count.
  602. *
  603. * SEE ALSO: sysTimestampFreq(), sysTimestamp()
  604. */
  605. UINT32 sysTimestampLock (void)
  606.     {
  607.     UINT32 t;
  608.     AMBA_TIMER_READ (SYS_TIMER_VALUE (AMBA_TIMER_BASE), t);
  609. #if defined (AMBA_TIMER_VALUE_MASK)
  610.     t &= AMBA_TIMER_VALUE_MASK;
  611. #endif
  612.     return (sysTimestampPeriod() - t);
  613.     }
  614. #endif  /* INCLUDE_TIMESTAMP */