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

VxWorks

开发平台:

C/C++

  1. /* m68901Timer.c - MC68901 Multi-Function Peripheral (MFP) timer driver */
  2. /* Copyright 1984-1993 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01b,30jan93,dzb  separated sys,aux clocks from particular timers.
  8.  added support for user-defined prescale values.
  9.  icreased auxClkTicksPerSecond to fit prescale=4 (worst case).
  10. 01a,04jan93,caf  derived from version 02a of config/mv133/sysLib.c.
  11. */
  12. /*
  13. DESCRIPTION
  14. This library contains routines to manipulate the timer functions on the
  15. MFP chip with a board-independent interface.  This library handles both
  16. the system clock and the auxiliary clock functions.
  17. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  18. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  19. sys[Aux]ClkRateSet() routines.  Additionally, the system and auxiliary
  20. clocks must each be assigned to one of the four MFP timers.  The 
  21. tyCoDv.sys and tyCoDv.aux structures must be intialized to point to
  22. the appropriate registers and constants.
  23. */
  24. /* locals */
  25. LOCAL FUNCPTR sysClkRoutine = NULL; /* routine to call on clock interrupt */
  26. LOCAL int sysClkArg = NULL; /* its argument */
  27. LOCAL int sysClkRunning = FALSE;
  28. LOCAL int sysClkConnected = FALSE;
  29. LOCAL int sysClkTicksPerSecond = 60;
  30. LOCAL FUNCPTR sysAuxClkRoutine = NULL; /* routine to call on clock interrupt */
  31. LOCAL int sysAuxClkArg = NULL; /* its argument */
  32. LOCAL int sysAuxClkRunning = FALSE;
  33. LOCAL int auxClkConnected = FALSE;
  34. LOCAL int auxClkTicksPerSecond = 2400; /* min freq if prescale=4,hz=2.4Mhz */
  35. /* forward declarations */
  36. LOCAL void sysClkInt ();
  37. LOCAL void sysAuxClkInt ();
  38. /*******************************************************************************
  39. *
  40. * sysClkInt - interrupt level processing for system clock
  41. *
  42. * This routine handles the system clock interrupt.  It is attached to the
  43. * clock interrupt vector by the routine sysClkConnect().
  44. *
  45. * RETURNS: N/A
  46. */
  47. LOCAL void sysClkInt (void)
  48.     {
  49.     if (sysClkRoutine != NULL)
  50.         (*sysClkRoutine) (sysClkArg);
  51.     }
  52. /*******************************************************************************
  53. *
  54. * sysClkConnect - connect a routine to the system clock interrupt
  55. *
  56. * This routine specifies the interrupt service routine to be called at each
  57. * clock interrupt.  It does not enable system clock interrupts.  Normally,
  58. * it is called from usrRoot() in usrConfig.c to connect usrClock() to the
  59. * system clock interrupt.
  60. *
  61. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  62. *
  63. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  64. */
  65. STATUS sysClkConnect
  66.     (
  67.     FUNCPTR routine, /* routine called at each clock interrupt */
  68.     int     arg /* argument with which to call routine    */
  69.     )
  70.     {
  71.     sysHwInit2 (); /* XXX for now -- needs to be in usrConfig.c */
  72.     sysClkRoutine   = routine;
  73.     sysClkArg       = arg;
  74.     sysClkConnected = TRUE;
  75.     return (OK);
  76.     }
  77. /*******************************************************************************
  78. *
  79. * sysClkDisable - turn off system clock interrupts
  80. *
  81. * This routine disables system clock interrupts.
  82. *
  83. * RETURNS: N/A
  84. *
  85. * SEE ALSO: sysClkEnable()
  86. */
  87. void sysClkDisable (void)
  88.     {
  89.     if (sysClkRunning)
  90. {
  91. *tyCoDv.sys.ier &= ~tyCoDv.sys.iMask; /* disable interrupt */
  92. sysClkRunning = FALSE;
  93. }
  94.     }
  95. /*******************************************************************************
  96. *
  97. * sysClkEnable - turn on system clock interrupts
  98. *
  99. * This routine enables system clock interrupts.
  100. *
  101. * RETURNS: N/A
  102. *
  103. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  104. */
  105. void sysClkEnable (void)
  106.     {
  107.     if (!sysClkRunning)
  108. {
  109. *tyCoDv.sys.cr &= ~tyCoDv.sys.cMask; /* clear previous mode value */
  110. if (tyCoDv.sys.prescale == 100)
  111.     *tyCoDv.sys.cr |= (MFP_TCR_DELAY_100 & tyCoDv.sys.cMask);
  112.         else
  113.     {
  114.     *tyCoDv.sys.cr |= (MFP_TCR_DELAY_200 & tyCoDv.sys.cMask);
  115.     tyCoDv.sys.prescale = 200;
  116.     }
  117. /* write the timer value (with prescale) */
  118. *tyCoDv.sys.dr = tyCoDv.baudFreq / (tyCoDv.sys.prescale *
  119.    sysClkTicksPerSecond);
  120. *tyCoDv.sys.imr |= tyCoDv.sys.iMask; /* set mask */
  121. *tyCoDv.sys.ier |= tyCoDv.sys.iMask; /* enable interrupt */
  122. sysClkRunning = TRUE;
  123. }
  124.     }
  125. /*******************************************************************************
  126. *
  127. * sysClkRateGet - get the system clock rate
  128. *
  129. * This routine returns the interrupt rate of the system clock.
  130. *
  131. * RETURNS: The number of ticks per second of the system clock.
  132. *
  133. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  134. */
  135. int sysClkRateGet (void)
  136.     {
  137.     return (sysClkTicksPerSecond);
  138.     }
  139. /*******************************************************************************
  140. *
  141. * sysClkRateSet - set the system clock rate
  142. *
  143. * This routine sets the interrupt rate of the system clock.  It does not
  144. * enable system clock interrupts.  Normally, it is called by usrRoot() in
  145. * usrConfig.c.
  146. *
  147. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  148. *
  149. * SEE ALSO: sysClkEnable(), sysClkRateGet()
  150. */
  151. STATUS sysClkRateSet
  152.     (
  153.     int ticksPerSecond     /* number of clock interrupts per second */
  154.     )
  155.     {
  156.     if (ticksPerSecond < SYS_CLK_RATE_MIN || ticksPerSecond > SYS_CLK_RATE_MAX
  157. || ticksPerSecond < (tyCoDv.baudFreq/(256*tyCoDv.sys.prescale))
  158. || ticksPerSecond > (tyCoDv.baudFreq/tyCoDv.sys.prescale))
  159. return (ERROR);
  160.     sysClkTicksPerSecond = ticksPerSecond;
  161.     if (sysClkRunning)
  162. {
  163. sysClkDisable ();
  164. sysClkEnable ();
  165. }
  166.     return (OK);
  167.     }
  168. /*******************************************************************************
  169. *
  170. * sysAuxClkInt - interrupt level processing for auxiliary clock
  171. *
  172. * This routine handles the auxiliary clock interrupt.  It is attached to the
  173. * clock interrupt vector by the routine sysAuxClkConnect().
  174. */
  175. LOCAL void sysAuxClkInt (void)
  176.     {
  177.     if (sysAuxClkRoutine != NULL)
  178.         (*sysAuxClkRoutine) (sysAuxClkArg);
  179.     }
  180. /*******************************************************************************
  181. *
  182. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  183. *
  184. * This routine specifies the interrupt service routine to be called at each
  185. * auxiliary clock interrupt.  It does not enable auxiliary clock
  186. * interrupts.
  187. *
  188. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  189. *
  190. * SEE ALSO: intConnect(), sysAuxClkEnable()
  191. */
  192. STATUS sysAuxClkConnect
  193.     (
  194.     FUNCPTR  routine, /* routine called at each aux. clock interrupt */
  195.     int      arg /* argument with which to call routine         */
  196.     )
  197.     {
  198.     sysAuxClkRoutine   = routine;
  199.     sysAuxClkArg       = arg;
  200.     auxClkConnected    = TRUE;
  201.     return (OK);
  202.     }
  203. /*******************************************************************************
  204. *
  205. * sysAuxClkDisable - turn off auxiliary clock interrupts
  206. *
  207. * This routine disables auxiliary clock interrupts.
  208. *
  209. * RETURNS: N/A
  210. *
  211. * SEE ALSO: sysAuxClkEnable()
  212. */
  213. void sysAuxClkDisable (void)
  214.     {
  215.     if (sysAuxClkRunning)
  216. {
  217. *tyCoDv.aux.ier &= ~tyCoDv.aux.iMask; /* disable interrupt */
  218. sysAuxClkRunning = FALSE;
  219. }
  220.     }
  221. /*******************************************************************************
  222. *
  223. * sysAuxClkEnable - turn on auxiliary clock interrupts
  224. *
  225. * This routine enables auxiliary clock interrupts.
  226. *
  227. * RETURNS: N/A
  228. *
  229. * SEE ALSO: sysAuxClkConnect(),sysAuxClkDisable(), sysAuxClkRateSet()
  230. */
  231. void sysAuxClkEnable (void)
  232.     {
  233.     if (!sysAuxClkRunning)
  234. {
  235. *tyCoDv.aux.cr &= ~tyCoDv.aux.cMask; /* clear previous mode value */
  236. switch (tyCoDv.aux.prescale)
  237.     {
  238.     case 4:
  239. *tyCoDv.aux.cr |= (MFP_TCR_DELAY_4 & tyCoDv.aux.cMask);
  240. break;
  241.     case 10:
  242. *tyCoDv.aux.cr |= (MFP_TCR_DELAY_10 & tyCoDv.aux.cMask);
  243. break;
  244.     case 16:
  245. *tyCoDv.aux.cr |= (MFP_TCR_DELAY_16 & tyCoDv.aux.cMask);
  246. break;
  247.     case 50:
  248. *tyCoDv.aux.cr |= (MFP_TCR_DELAY_50 & tyCoDv.aux.cMask);
  249. break;
  250.     case 64:
  251. *tyCoDv.aux.cr |= (MFP_TCR_DELAY_64 & tyCoDv.aux.cMask);
  252. break;
  253.     case 100:
  254. *tyCoDv.aux.cr |= (MFP_TCR_DELAY_100 & tyCoDv.aux.cMask);
  255. break;
  256.     default:
  257.         *tyCoDv.aux.cr |= (MFP_TCR_DELAY_200 & tyCoDv.aux.cMask);
  258.         tyCoDv.aux.prescale = 200;
  259.     }
  260. /* write the timer value (with prescale) */
  261. *tyCoDv.aux.dr = tyCoDv.baudFreq / (tyCoDv.aux.prescale *
  262.    auxClkTicksPerSecond);
  263. *tyCoDv.aux.imr |= tyCoDv.aux.iMask; /* set mask */
  264. *tyCoDv.aux.ier |= tyCoDv.aux.iMask; /* enable interrupt */
  265. sysAuxClkRunning = TRUE;
  266. }
  267.     }
  268. /*******************************************************************************
  269. *
  270. * sysAuxClkRateGet - get the auxiliary clock rate
  271. *
  272. * This routine returns the interrupt rate of the auxiliary clock.
  273. *
  274. * RETURNS: The number of ticks per second of the auxiliary clock.
  275. *
  276. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  277. */
  278. int sysAuxClkRateGet (void)
  279.     {
  280.     return (auxClkTicksPerSecond);
  281.     }
  282. /*******************************************************************************
  283. *
  284. * sysAuxClkRateSet - set the auxiliary clock rate
  285. *
  286. * This routine sets the interrupt rate of the auxiliary clock.
  287. * It does not enable auxiliary clock interrupts.
  288. *
  289. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  290. *
  291. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  292. */
  293. STATUS sysAuxClkRateSet
  294.     (
  295.     int ticksPerSecond     /* number of clock interrupts per second */
  296.     )
  297.     {
  298.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX
  299. || ticksPerSecond < (tyCoDv.baudFreq/(256*tyCoDv.aux.prescale))
  300. || ticksPerSecond > (tyCoDv.baudFreq/tyCoDv.aux.prescale))
  301. return (ERROR);
  302.     auxClkTicksPerSecond = ticksPerSecond;
  303.     if (sysAuxClkRunning)
  304. {
  305. sysAuxClkDisable ();
  306. sysAuxClkEnable ();
  307. }
  308.     return (OK);
  309.     }