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

VxWorks

开发平台:

C/C++

  1. /* ixp425Timer.c - ixp425 processor timer library */
  2. /* Copyright 2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01a,05jun02,jb  initial version...
  8. */
  9. /*
  10. DESCRIPTION
  11. This library contains routines to manipulate the timer functions.
  12. _______
  13. hardware TIMER 0
  14. clock _______
  15.    |
  16. interface -----------------------------------------------------
  17. |   |      |
  18. |   |      |
  19. software     _______ ______ _____________
  20. clock(s)     sysClk auxClk timeStampClk
  21.      _______ ______ _____________
  22. interface functions:
  23. clkInt() - clock interrupt handler
  24. clkConnect() - connect a routine to the clock interrupt
  25. clkDisable() - turn off system clock interrupts
  26. clkEnable() - turn on system clock interrupts
  27. clkRateGet() - get the system clock rate oscillations per second
  28. clkPeriod() - get the period of the timer (tick counter rollover)
  29. clkFreq() - get a timer clock frequency
  30. clkTimestamp() - get a tick counter count
  31. Note: There are two different types of ticks referred to.  The frequency
  32. tick and the counter tick.  A frequency tick refers to the timer clock
  33. oscillations per second and the counter ticks refer to the number of times
  34. (ticks) a register decreases until roll over.
  35. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX must be defined to
  36. provide parameter checking for the sysClkRateSet() routine.
  37. */
  38. #include "ixp425.h"
  39. #include "ixp425Timer.h"
  40. #include "drv/timer/timerDev.h"
  41. #ifdef INCLUDE_TIMESTAMP
  42. #include "drv/timer/timestampDev.h"
  43. #endif
  44. /* 
  45.  * The APB timer block is not based on the CPU speed, but on
  46.  * the APB core clock of 66Mhz.
  47.  */
  48. #define TIMER_APB_CLOCK_MHZ ( IXP425_PERIPHERAL_BUS_CLOCK )
  49. /* hardware access methods */
  50. #ifndef IXP425_REG_TIMER_READ
  51. #define IXP425_REG_TIMER_READ(reg,result) 
  52. ((result) = *(volatile UINT32 *)(reg))
  53. #endif /*IXP425_REG_TIMER_READ*/
  54. #ifndef IXP425_REG_TIMER_WRITE
  55. #define IXP425_REG_TIMER_WRITE(reg,data) 
  56. (*((volatile UINT32 *)(reg)) = (data))
  57. #endif /*IXP425_REG_TIMER_WRITE*/
  58. /* Locals */
  59. LOCAL int     clockTicksPerSecond   = IXP425_OSST_TICKS_PER_SECOND;
  60. LOCAL UINT32  clockTimerRollOver    = IXP425_OSST_ROLLOVER;
  61. LOCAL BOOL    clockConnected     = FALSE;
  62. LOCAL BOOL    sysClkRunning     = FALSE;
  63. LOCAL FUNCPTR sysClkRoutine     = (FUNCPTR) NULL;
  64. LOCAL int     sysClkArg     = (int) NULL;
  65. LOCAL BOOL    sysClkConnected     = FALSE;
  66. /* We do not actually have an auxiliary clock available. */
  67. LOCAL BOOL    sysAuxClkRunning     = FALSE;
  68. LOCAL FUNCPTR sysAuxClkRoutine     = (FUNCPTR) NULL;
  69. LOCAL int     sysAuxClkArg     = (int) NULL;
  70. LOCAL BOOL    sysAuxClkConnected    = FALSE;
  71. #ifdef INCLUDE_TIMESTAMP
  72. LOCAL BOOL    sysTimestampRunning   = FALSE;
  73. #endif
  74. LOCAL void clkInt (void)
  75. {
  76.      /* Clear Pending Interrupt by writing '1' to it */
  77.      IXP425_REG_TIMER_WRITE(IXP425_OSST, IXP425_OSST_TIMER_1_PEND);
  78.      if ((sysClkRoutine != NULL) && sysClkRunning)
  79.  (*(FUNCPTR) sysClkRoutine) (sysClkArg);
  80.      /* The timer is free running and as such it has already reloaded
  81.       * and is counting down 
  82.       */
  83. }
  84. /***************************************************************************
  85. *
  86. * clkConnect - connect a routine to the clock interrupt
  87. *
  88. * This routine specifies the interrupt service routine to be called at each
  89. * clock interrupt.
  90. *
  91. * RETURN: OK
  92. *
  93. * SEE ALSO: intConnect(), usrClock(), clkEnable()
  94. */
  95. LOCAL STATUS clkConnect (void)
  96.     {
  97.     if(!clockConnected)
  98. {
  99.  sysHwInit2 ();
  100.  (void)intConnect ((void *)INT_VEC_TIMER1, clkInt, 0);
  101.  clockConnected = TRUE;
  102. }
  103.     return (OK);
  104.     }
  105. /***************************************************************************
  106. *
  107. * clkDisable - turn off system clock interrupts
  108. *
  109. * This routine disables clock interrupts.  In order for the hardware clock
  110. * to be disables all the software clocks must be disabled.
  111. *
  112. * RETURNS: N/A
  113. *
  114. * SEE ALSO: clkEnable()
  115. */
  116. LOCAL void clkDisable (void)
  117.     {
  118. intDisable(INT_VEC_TIMER1);
  119. /* Clear the OST register for this timer, This disabled the
  120.    timer */
  121. IXP425_REG_TIMER_WRITE( IXP425_OSRT1 , IXP425_OST_DISABLED );
  122.     
  123.     }
  124. /***************************************************************************
  125. *
  126. * clkEnable - turn on system clock interrupts
  127. *
  128. * This routine enables system clock interrupts.  Any software clock can
  129. * enable the hardware clock
  130. *
  131. * RETURNS: N/A
  132. *
  133. * SEE ALSO: sysClkDisable(), sysClkRateSet()
  134. */
  135. LOCAL void clkEnable (void)
  136.     {
  137. IXP425_REG_TIMER_WRITE( IXP425_OSRT1 , ((clockTimerRollOver & ~IXP425_OST_RELOAD_MASK) |  IXP425_OST_ENABLE )  );
  138. intEnable(INT_VEC_TIMER1);
  139.     }
  140. /***************************************************************************
  141. *
  142. * clkRateGet - get the system clock rate
  143. *
  144. * This routine returns the oscillations clock rate.
  145. *
  146. * RETURNS: The number of oscillations per second of the clock.
  147. *
  148. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  149. */
  150. LOCAL int clkRateGet (void)
  151.     {
  152.     return (clockTicksPerSecond);
  153.     }
  154. /**************************************************************************
  155. *
  156. * clkPeriod - get the period of the tick counter
  157. *
  158. * This routine gets the period of the timer, in ticks. The
  159. * period, or terminal count, is the number of ticks to which the tick
  160. * counter counts before rolling over and restarting the counting process.
  161. *
  162. * RETURNS: The period of the timer in counter ticks.
  163. */
  164. LOCAL UINT32 clkPeriod (void)
  165.     {
  166.     return (clockTimerRollOver);
  167.     }
  168. /**************************************************************************
  169. *
  170. * clkFreq - get a timer clock frequency
  171. *
  172. * This routine gets the frequency of the timer clock, in ticks per
  173. * second.  The rate of the timer is set explicitly by the
  174. * hardware and typically cannot be altered.
  175. *
  176. * RETURNS: The timer clock frequency, in counter ticks per second.
  177. */
  178. LOCAL UINT32 clkFreq (void)
  179.     {
  180.     return ( TIMER_APB_CLOCK_MHZ * 1000000);
  181.     }
  182. /**************************************************************************
  183. *
  184. * clkTimestamp - get a time stamp count
  185. *
  186. * This routine returns the current value of the timer tick counter.
  187. * The tick count can be converted to seconds by dividing it by the return of
  188. * clkFreq().
  189. *
  190. *
  191. * RETURNS: The current time stamp count.
  192. *
  193. * SEE ALSO: clkFreq()
  194. */
  195. LOCAL UINT32 clkTimestamp (void)
  196.     {
  197. UINT32 count;
  198. /* Read the free running up-timer from peripherial block */
  199. IXP425_REG_TIMER_READ(IXP425_OSTS,count);
  200. return(count);
  201.     }
  202.    
  203. /***************************************************************************
  204. *
  205. * sysClkConnect - connect a routine to the system clock interrupt
  206. *
  207. * This routine specifies the interrupt service routine to be called at each
  208. * clock interrupt.  Normally it is called from usrRoot() in usrConfig.c to
  209. * connect usrClock() to the system clock interrupt.
  210. *
  211. * RETURN: OK
  212. *
  213. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  214. */
  215. STATUS sysClkConnect
  216.     (
  217.     FUNCPTR routine, /* routine called at each system clock interrupt */
  218.     int     arg /* argument with which to call routine  */
  219.     )
  220.     {
  221.     sysClkConnected   = TRUE;
  222.     sysClkRoutine     = routine;
  223.     sysClkArg       = arg;
  224.     clkConnect();
  225.     return (OK);
  226.     }
  227. /***************************************************************************
  228. *
  229. * sysClkDisable - turn off system clock interrupts
  230. *
  231. * This routine disables system clock interrupts.
  232. *
  233. * RETURNS: N/A
  234. *
  235. * SEE ALSO: sysClkEnable()
  236. */
  237. void sysClkDisable (void)
  238.     {
  239.     if (sysClkRunning)
  240. {
  241. clkDisable();
  242. sysClkRunning  = FALSE;
  243. }
  244.     }
  245. /***************************************************************************
  246. *
  247. * sysClkEnable - turn on system clock interrupts
  248. *
  249. * This routine enables system clock interrupts.
  250. *
  251. * RETURNS: N/A
  252. *
  253. * SEE ALSO: sysClkDisable(), sysClkRateSet()
  254. */
  255. void sysClkEnable (void)
  256.     {
  257.     if (!sysClkRunning)
  258. {
  259. clkEnable();
  260. sysClkRunning  = TRUE;
  261. }
  262.     }
  263. /***************************************************************************
  264. *
  265. * sysClkRateGet - get the system clock rate
  266. *
  267. * This routine returns the system clock rate.
  268. *
  269. * RETURNS: The number of ticks per second of the system clock.
  270. *
  271. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  272. */
  273. int sysClkRateGet (void)
  274.     {
  275.     return(clkRateGet());
  276.     }
  277. /***************************************************************************
  278. *
  279. * sysClkRateSet - set the system clock rate
  280. *
  281. * This routine sets the interrupt rate of the system clock.  It is called by
  282. * usrRoot() in usrConfig.c.
  283. *
  284. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  285. *
  286. * SEE ALSO: sysClkEnable(), sysClkRateGet()
  287. */
  288. STATUS sysClkRateSet
  289.     (
  290.     int ticksPerSecond     /* number of clock interrupts per second */
  291.     )
  292.     {
  293.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  294.     return (ERROR);
  295.     clockTicksPerSecond = ticksPerSecond;
  296.     clockTimerRollOver = ((TIMER_APB_CLOCK_MHZ * 1000000) / clockTicksPerSecond);
  297.     if (sysClkRunning)
  298. {
  299. sysClkDisable ();
  300. sysClkEnable ();
  301. }
  302.     return (OK);
  303.     }
  304. /***************************************************************************
  305.  *  We do not actually have an auxiliary clock available.
  306.  ***************************************************************************/
  307. /***************************************************************************
  308. *
  309. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  310. *
  311. * This routine specifies the interrupt service routine to be called at each
  312. * auxiliary clock interrupt.  It does not enable auxiliary clock interrupts.
  313. *
  314. * RETURNS: OK
  315. *
  316. * SEE ALSO: intConnect(), sysAuxClkEnable()
  317. */
  318. STATUS sysAuxClkConnect
  319.     (
  320.     FUNCPTR routine, /* routine called at each aux. clock interrupt */
  321.     int     arg /* argument with which to call routine        */
  322.     )
  323.     {
  324.     sysAuxClkConnected = TRUE;
  325.     sysAuxClkRoutine   = routine;
  326.     sysAuxClkArg       = arg;
  327.     clkConnect();
  328.     return (OK);
  329.     }
  330. /***************************************************************************
  331. *
  332. * sysAuxClkDisconnect - clear the auxiliary clock routine
  333. *
  334. * This routine disables the auxiliary clock interrupt, stops the timer,
  335. * and disconnects the routine currently connected to the auxiliary clock
  336. * interrupt.
  337. *
  338. * RETURNS: N/A
  339. *
  340. * SEE ALSO: sysAuxClkConnect(), sysAuxClkEnable()
  341. */
  342. void sysAuxClkDisconnect (void)
  343.     {
  344.     /* disable the auxiliary clock interrupt */
  345.     sysAuxClkDisable ();
  346.     }
  347. /***************************************************************************
  348. *
  349. * sysAuxClkDisable - turn off auxiliary clock interrupts
  350. *
  351. * This routine disables auxiliary clock interrupts.
  352. *
  353. * RETURNS: N/A
  354. *
  355. * SEE ALSO: sysAuxClkEnable()
  356. */
  357. void sysAuxClkDisable (void)
  358.     {
  359.     if (sysAuxClkRunning)
  360. {
  361. sysAuxClkRunning = FALSE;
  362. }
  363.     }
  364. /***************************************************************************
  365. *
  366. * sysAuxClkEnable - turn on auxiliary clock interrupts
  367. *
  368. * This routine enables auxiliary clock interrupts.
  369. *
  370. * RETURNS: N/A
  371. *
  372. * SEE ALSO: sysAuxClkDisable()
  373. */
  374. void sysAuxClkEnable (void)
  375.     {
  376.     if (!sysAuxClkRunning)
  377. {
  378. sysAuxClkRunning  = TRUE;
  379. }
  380.     }
  381. /***************************************************************************
  382. *
  383. * sysAuxClkRateGet - get the auxiliary clock rate
  384. *
  385. * This routine returns the interrupt rate of the auxiliary clock.
  386. *
  387. * RETURNS: The number of ticks per second of the auxiliary clock.
  388. *
  389. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  390. */
  391. int sysAuxClkRateGet (void)
  392.     {
  393.     return(clkRateGet());
  394.     }
  395. /***************************************************************************
  396. *
  397. * sysAuxClkRateSet - set the auxiliary clock rate
  398. *
  399. * This routine sets the interrupt rate of the auxiliary clock. It does not
  400. * enable auxiliary clock interrupts.
  401. *
  402. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  403. *
  404. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  405. */
  406. STATUS sysAuxClkRateSet
  407.     (
  408.     int ticksPerSecond     /* number of clock interrupts per second */
  409.     )
  410.     {
  411.     return (OK);
  412.     }
  413. #ifdef INCLUDE_TIMESTAMP
  414. /**************************************************************************
  415.   NOTE: The current system has no suitable spare timers, thus requiring
  416. that timestamps be derived from vxWorks system clock timer.
  417.  **************************************************************************/
  418. /**************************************************************************
  419. *
  420. * sysTimestampConnect - connect a user routine to a timestamp timer interrupt
  421. *
  422. * This routine specifies the user interrupt routine to be called at each
  423. * timestamp timer interrupt.
  424. *
  425. * RETURNS: OK, or ERROR if sysTimestampInt() has not been used.
  426. *
  427. * SEE ALSO: sysTimestampEnable()
  428. */
  429. STATUS sysTimestampConnect
  430.     (
  431.     FUNCPTR routine, /* routine called at each timestamp timer interrupt */
  432.     int arg      /* argument with which to call routine */
  433.     )
  434.     {
  435.     return (ERROR);
  436.     }
  437. /**************************************************************************
  438. *
  439. * sysTimestampEnable - enable a timestamp timer interrupt
  440. *
  441. * This routine enables timestamp timer interrupts and resets the counter.
  442. *
  443. * RETURNS: OK, or ERROR if the timestamp timer cannot be enabled.
  444. *
  445. * SEE ALSO: sysTimestampDisable()
  446. */
  447. STATUS sysTimestampEnable(void)
  448.     {
  449.     if(!sysTimestampRunning)
  450. {
  451. sysTimestampRunning = TRUE;
  452. }
  453.     return (OK);
  454.     }
  455. /**************************************************************************
  456. *
  457. * sysTimestampDisable - disable a timestamp timer interrupt
  458. *
  459. * This routine disables the timestamp timer.  It does not directly disable
  460. * interrupts.  However, the tick counter does not increment once the
  461. * timestamp timer is disabled, thus, interrupts are no longer generated.
  462. * This routine merely resets the timer counter.
  463. *
  464. * RETURNS: OK, ERROR if the timestamp timer cannot be disabled.
  465. *
  466. * SEE ALSO: sysTimestampEnable()
  467. */
  468. STATUS sysTimestampDisable (void)
  469.     {
  470.     if (sysTimestampRunning)
  471. {
  472. sysTimestampRunning = FALSE;
  473. }
  474.     return (ERROR);
  475.     }
  476. /**************************************************************************
  477. *
  478. * sysTimestampPeriod - get the period of a timestamp timer
  479. *
  480. * This routine gets the period of the timestamp timer, in ticks.  The
  481. * period, or terminal count, is the number of ticks to which the timestamp
  482. * timer counts before rolling over and restarting the counting process.
  483. *
  484. * RETURNS: The period of the timestamp timer in counter ticks.
  485. */
  486. UINT32 sysTimestampPeriod (void)
  487.     {
  488.     /*
  489.      * Return the timestamp timer period here.
  490.      * The highest period (maximum terminal count) should be used so
  491.      * that rollover interrupts are kept to a minimum.
  492.      *
  493.      */
  494.     return (clkPeriod());
  495.     }
  496. /**************************************************************************
  497. *
  498. * sysTimestampFreq - get a timestamp timer clock frequency
  499. *
  500. * This routine gets the frequency of the timer clock, in ticks per
  501. * second.  The rate of the timestamp timer is set explicitly by the
  502. * hardware and typically cannot be altered.
  503. *
  504. * RETURNS: The timestamp timer clock frequency, in ticks per second.
  505. */
  506. UINT32 sysTimestampFreq (void)
  507.     {
  508.     /*
  509.      * Return the timestamp tick output frequency here.
  510.      * This value can be determined from the following equation:
  511.      *    timerFreq = clock input frequency / prescaler
  512.      *
  513.      * When possible, read the clock input frequency and prescaler values
  514.      * directly from chip registers.
  515.      */
  516.     return (clkFreq());
  517.     }
  518. /**************************************************************************
  519. *
  520. * sysTimestamp - get a timestamp timer tick count
  521. *
  522. * This routine returns the current value of the timestamp timer tick counter.
  523. * The tick count can be converted to seconds by dividing it by the return of
  524. * sysTimestampFreq().
  525. *
  526. * This routine should be called with interrupts locked.  If interrupts are
  527. * not locked, sysTimestampLock() should be used instead.
  528. *
  529. * RETURNS: The current timestamp timer tick count.
  530. *
  531. * SEE ALSO: sysTimestampFreq(), sysTimestampLock()
  532. */
  533. UINT32 sysTimestamp (void)
  534.     {
  535.     UINT32 ticks = 0;
  536.     if (sysTimestampRunning)
  537.     {
  538.     /* Read the timer counter register */
  539.     ticks = clkTimestamp();
  540.     }
  541.     /* return the timestamp timer tick count here */
  542.     return (ticks);
  543.     }
  544. /**************************************************************************
  545. *
  546. * sysTimestampLock - lock interrupts and get the timestamp timer tick count
  547. *
  548. * This routine locks interrupts when the tick counter must be stopped
  549. * in order to read it or when two independent counters must be read.
  550. * It then returns the current value of the timestamp timer tick
  551. * counter.
  552. *
  553. * The tick count can be converted to seconds by dividing it by the return of
  554. * sysTimestampFreq().
  555. *
  556. * If interrupts are already locked, sysTimestamp() should be
  557. * used instead.
  558. *
  559. * RETURNS: The current timestamp timer tick count.
  560. *
  561. * SEE ALSO: sysTimestampFreq(), sysTimestamp()
  562. */
  563. UINT32 sysTimestampLock (void)
  564.     {
  565.     int locKey;
  566.     UINT32 ticks = 0;
  567.     if (sysTimestampRunning)
  568.     {
  569.     /* Lock Interrupts */
  570.     locKey = intLock();
  571.     /* Read the timer counter register */
  572.     ticks = clkTimestamp();
  573.     /* UnLock Interrupts */
  574.     intUnlock (locKey);
  575.     }
  576.     /* return the timestamp timer tick count here */
  577.     return (ticks);
  578.     }
  579. void reset()
  580. {
  581. IXP425_REG_TIMER_WRITE(IXP425_OSWK, 0x482e);
  582. IXP425_REG_TIMER_WRITE(IXP425_OSWT, 0);
  583. IXP425_REG_TIMER_WRITE(IXP425_OSWE, 0x3);
  584. }
  585. #endif  /* INCLUDE_TIMESTAMP */