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

VxWorks

开发平台:

C/C++

  1. /* mb96840Timer.c - SPARClite Companion Chip Timer library */
  2.    
  3. /* Copyright 1984-1996 Wind River Systems, Inc. */
  4. #include "copyright_wrs.h"
  5. /*
  6. modification history
  7. --------------------
  8. 01g,14dec96,dat  fixed SPR 2702, documenting HZ and HZprescale.
  9. 01f,30may96,wlf  doc: cleanup.
  10. 01e,27apr94,jkw  Added macro INT_AUXCLOCK, IRC_REQUEST_AUXCLK. and
  11.                  IRC_REQUEST_SYSCLK for Auxiliary and System clock
  12.                  to make the sysClkEnable and sysAuxClkEnable 
  13.                  Interrupt level independent of the board
  14. 01d,04feb94,jkw  changed the Auxiliary clock level to 1  
  15. 01c,07jul93,vin  removed intConnect calls from sysClkConnect and 
  16.                  sysAuxClkConnect and placed them in sysHwInit2
  17. 01b,13nov92,jwt  clean up; auxClkTicksPerSecond from 60 to 310 per ccc.
  18. 01a,20aug92,ccc  created by moving routines from sysLib.c of mb930.
  19.  fixed sysAuxClkRateSet() to set aux ticks properly.
  20. */
  21. /*
  22. DESCRIPTION
  23. This library contains routines to manipulate the timer functions for
  24. the SPARClite with a board-independent interface.  This library
  25. handles both the system clock and the auxiliary clock functions.
  26. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  27. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  28. sys[Aux]ClkRateSet() routines.
  29. The global values HZ and HZprescale are  expected to contain the clock
  30. rate and the prescale divider value.
  31. */
  32. #include "drv/timer/timerDev.h"
  33. /* globals */
  34. IMPORT int HZ; /* clock rate */
  35. IMPORT int HZprescale; /* clock prescale value, normally 200 */
  36. /* Locals */ 
  37. LOCAL int     sysClkTicksPerSecond = 60; 
  38. LOCAL BOOL    sysClkRunning        = FALSE; 
  39. LOCAL FUNCPTR sysClkRoutine        = NULL; 
  40. LOCAL int     sysClkArg            = NULL; 
  41. LOCAL BOOL    sysClkConnected      = FALSE; 
  42. LOCAL int     auxClkTicksPerSecond = 310; 
  43. LOCAL BOOL    sysAuxClkRunning     = FALSE; 
  44. LOCAL FUNCPTR sysAuxClkRoutine     = NULL; 
  45. LOCAL int     sysAuxClkArg         = NULL;
  46. LOCAL BOOL    sysAuxClkConnected   = FALSE; 
  47. /**************************************************************************
  48. *
  49. * sysClkInt - clock interrupt handler
  50. *
  51. * This routine handles the clock interrupt.  It is attached to the clock
  52. * interrupt vector by the routine sysClkConnect().  The appropriate routine
  53. * is called and the interrupts are acknowledged.
  54. */
  55. LOCAL void sysClkInt (void)
  56.     {
  57.     if (sysClkRoutine != NULL)
  58.         (*(FUNCPTR) sysClkRoutine) (sysClkArg);
  59.     }
  60. /***************************************************************************
  61. *
  62. * sysAuxClkInt - clock interrupt handler
  63. *
  64. * This routine handles the clock interrupt.  It is attached to the clock
  65. * interrupt vector by the routine sysAuxClkConnect().  The appropriate
  66. * routine is called and the interrupts are acknowledged.
  67. */
  68. LOCAL void sysAuxClkInt (void)
  69.     {
  70.     if (sysAuxClkRoutine != NULL)
  71.         (*(FUNCPTR) sysAuxClkRoutine) (sysAuxClkArg);
  72.     }
  73. /***************************************************************************
  74. *
  75. * sysClkConnect - connect a routine to the system clock interrupt
  76. *
  77. * This routine specifies the interrupt service routine to be called at each
  78. * clock interrupt.  Normally, it is called from usrRoot() in usrConfig.c to 
  79. * connect usrClock() to the system clock interrupt.
  80. *
  81. * INTERNAL
  82. * Note that the system clock uses timer 1 interrupts.  This allows the
  83. * use of the pre-scale and a wider range of values.  Otherwise, the
  84. * slowest rate would be 310 ticks per second (the usual 60 or 100 ticks
  85. * per second would not work).
  86. *
  87. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  88. *
  89. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  90. */
  91. STATUS sysClkConnect
  92.     (
  93.     FUNCPTR routine,    /* routine called at each system clock interrupt */
  94.     int     arg         /* argument with which to call routine           */
  95.     )
  96.     {
  97.     sysHwInit2 ();
  98.     sysClkConnected   = TRUE;
  99.     sysClkRoutine     = routine;
  100.     sysClkArg         = arg;
  101.     return (OK);
  102.     }
  103.  
  104. /***************************************************************************
  105. *
  106. * sysClkDisable - turn off system clock interrupts
  107. *
  108. * This routine disables system clock interrupts.
  109. *
  110. * RETURNS: N/A
  111. *
  112. * SEE ALSO: sysClkEnable()
  113. */
  114.  
  115. void sysClkDisable (void)
  116.  
  117.     {
  118.     if (sysClkRunning)
  119.         {
  120.         sys940AsiSeth ((void *) (TIMER1_CONTROL_ADDR), SPARC_TIMER_SETUP);
  121.         sysClkRunning = FALSE;
  122.         }
  123.     }
  124. /***************************************************************************
  125. *
  126. * sysClkEnable - turn on system clock interrupts
  127. *
  128. * This routine enables system clock interrupts.  The system clock uses Timer 1
  129. * interrupts.
  130. *
  131. * RETURNS: N/A
  132. *
  133. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  134. */
  135. void sysClkEnable (void)
  136.     {
  137.     int clockrate;
  138.     if (!sysClkRunning)
  139.         {
  140. clockrate = (HZ / HZprescale) / sysClkTicksPerSecond;
  141.         sys940AsiSeth ((void *) (TIMER1_CONTROL_ADDR),
  142.                     SPARC_TIMER_SETUP | TIMER_CONT_PRESCALE); /* Enable */
  143.         sys940AsiSeth ((void *) (TIMER1_PRESCALE_ADDR),
  144.                    HZprescale);    /* Set prescale */
  145.         /* clear any pending IRQ before we start timer */
  146.         sys940AsiSeth ((void *) (IRC_REQ_CLEAR_ADDR), IRC_REQUEST_SYSCLK);
  147.         sys940AsiSeth ((void *) (TIMER1_RELOAD_ADDR),
  148.                    clockrate); /* Set reload->GO */
  149.         sysClkRunning = TRUE;
  150.         }
  151.     }
  152. /***************************************************************************
  153. *
  154. * sysClkRateGet - get the system clock rate
  155. *
  156. * This routine returns the system clock rate.
  157. *
  158. * RETURNS: The number of ticks per second of the system clock.
  159. *
  160. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  161. */
  162. int sysClkRateGet (void)
  163.     {
  164.     return (sysClkTicksPerSecond);
  165.     }
  166. /***************************************************************************
  167. *
  168. * sysClkRateSet - set the system clock rate
  169. *
  170. * This routine sets the interrupt rate of the system clock.  It does not
  171. * enable system clock interrupts.  It is called by usrRoot() in
  172. * usrConfig.c.
  173. *
  174. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  175. *
  176. * SEE ALSO: sysClkEnable(), sysClkRateGet()
  177. */
  178. STATUS sysClkRateSet
  179.     (
  180.     int ticksPerSecond      /* number of clock interrupts per second */
  181.     )
  182.     {
  183.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX)
  184. return (ERROR);
  185.     sysClkTicksPerSecond = ticksPerSecond;
  186.     if (sysClkRunning)
  187. {
  188. sysClkDisable ();
  189. sysClkEnable (); /* new count takes after mode set */
  190. }
  191.     return (OK);
  192.     }
  193. /***************************************************************************
  194. *
  195. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  196. *
  197. * This routine specifies the interrupt service routine to be called at each
  198. * auxiliary clock interrupt.  It does not enable auxiliary clock
  199. * interrupts.
  200. *
  201. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  202. *
  203. * SEE ALSO: intConnect(), sysAuxClkDisconnect(), sysAuxClkEnable()
  204. */
  205. STATUS sysAuxClkConnect
  206.     (
  207.     FUNCPTR routine,    /* routine called at each aux. clock interrupt   */
  208.     int     parm        /* argument to auxiliary clock interrupt routine */
  209.     )
  210.     {
  211.     sysAuxClkConnected = TRUE;
  212.     sysAuxClkRoutine   = routine;
  213.     sysAuxClkArg       = parm;
  214.     return (OK);
  215.     }
  216. /***************************************************************************
  217. *
  218. * sysAuxClkDisconnect - clear the auxiliary clock routine
  219. *
  220. * This routine disables the auxiliary clock interrupt, stops the timer,
  221. * and disconnects the routine currently connected to the auxiliary clock
  222. * interrupt.
  223. *
  224. * RETURNS: N/A
  225. *
  226. * SEE ALSO: sysAuxClkConnect(), sysAuxClkEnable()
  227. */
  228. void sysAuxClkDisconnect (void)
  229.     {
  230.     /* disable the auxiliary clock interrupt */
  231.     sysAuxClkDisable ();
  232.     /* connect dummy routine, just in case */
  233.     sysAuxClkConnect ((FUNCPTR) logMsg, (int) "auxiliary clock interruptn");
  234.     }
  235. /***************************************************************************
  236. *
  237. * sysAuxClkDisable - turn off auxiliary clock interrupts
  238. *
  239. * This routine disables auxiliary clock interrupts.
  240. *
  241. * RETURNS: N/A
  242. *
  243. * SEE ALSO: sysAuxClkEnable()
  244. */
  245. void sysAuxClkDisable (void)
  246.     {
  247.     if (sysAuxClkRunning)
  248.         {
  249.         /* STOP TIMER */
  250.         sys940AsiSeth ((void *) (TIMER2_CONTROL_ADDR),
  251.                    SPARC_TIMER_SETUP); /* Enable */
  252.         /* clear any pending interrupts after we unmask */
  253.         sysIntDisable (INT_AUXCLOCK);   /* mask interrupt */
  254.         sys940AsiSeth ((void *) (IRC_REQ_CLEAR_ADDR), IRC_REQUEST_AUXCLK);
  255.         sysAuxClkRunning = FALSE;
  256.         }
  257.     }
  258. /***************************************************************************
  259. *
  260. * sysAuxClkEnable - turn on auxiliary clock interrupts
  261. *
  262. * This routine enables auxiliary clock interrupts.
  263. *
  264. * RETURNS: N/A
  265. *
  266. * SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
  267. */
  268. void sysAuxClkEnable (void)
  269.     {
  270.     if (!sysAuxClkRunning)
  271.         {
  272.         sys940AsiSeth ((void *) (TIMER2_CONTROL_ADDR),
  273.                    SPARC_TIMER_SETUP); /* Enable */
  274.         /* clear any pending IRQ before we start timer */
  275.         sys940AsiSeth ((void *) (IRC_REQ_CLEAR_ADDR), IRC_REQUEST_AUXCLK);
  276.         sysIntEnable (INT_AUXCLOCK);              /* unmask interrupt */
  277.         sys940AsiSeth ((void *) (TIMER2_RELOAD_ADDR),
  278.                     HZ / auxClkTicksPerSecond); /* Set reload->GO */
  279.         sysAuxClkRunning = TRUE;
  280.         }
  281.     }
  282. /***************************************************************************
  283. *
  284. * sysAuxClkRateGet - get the auxiliary clock rate
  285. *
  286. * This routine returns the interrupt rate of the auxiliary clock.
  287. *
  288. * RETURNS: The number of ticks per second of the auxiliary clock.
  289. *
  290. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  291. */
  292. int sysAuxClkRateGet (void)
  293.     {
  294.     return (auxClkTicksPerSecond);
  295.     }
  296. /***************************************************************************
  297. *
  298. * sysAuxClkRateSet - set the auxiliary clock rate
  299. *
  300. * This routine sets the interrupt rate of the auxiliary clock.  It does not
  301. * enable auxiliary clock interrupts.
  302. *
  303. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  304. *
  305. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  306. */
  307. STATUS sysAuxClkRateSet
  308.     (
  309.     int ticksPerSecond      /* number of clock interrupts per second */
  310.     )
  311.     {
  312.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  313. return (ERROR);
  314.     auxClkTicksPerSecond = ticksPerSecond;
  315.     if (sysAuxClkRunning)
  316. {
  317. sysAuxClkDisable ();
  318. sysAuxClkEnable (); /* clock restarts upon new value */
  319. }
  320.     return (OK);
  321.     }