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

VxWorks

开发平台:

C/C++

  1. /* m68562Timer.c - Motorola MC68562 DUSCC timer library */
  2. /* Copyright 1984-1996 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01c,21jun96,wlf  doc: cleanup.
  8. 01b,10jul92,caf  preload timers in sys[Aux]ClkEnable() (SPR 937).
  9. 01a,08jul92,caf  created, based on version 01c of pccTimer.c.
  10. */
  11. /*
  12. DESCRIPTION
  13. This library contains routines to manipulate the timer functions on the
  14. DUSCC chip with a board-independent interface.  This library handles both
  15. the system clock and the auxiliary clock functions.
  16. The macros SYS_CLK_RATE_MIN, SYS_CLK_RATE_MAX, AUX_CLK_RATE_MIN, and
  17. AUX_CLK_RATE_MAX must be defined to provide parameter checking for the
  18. sys[Aux]ClkRateSet() routines.
  19. The macro DUSCC_BASE_ADRS must be defined when including this driver.
  20. */
  21. /* includes */
  22. #include "drv/timer/timerDev.h"
  23. /* defines */
  24. /*
  25.  * If hardware varies from the typical 3.6864 MHz frequency supplied
  26.  * to the DUSCC chip, define DUSCC_FREQ when including this driver.
  27.  */
  28. #ifndef DUSCC_FREQ
  29. #define DUSCC_FREQ     3686400
  30. #endif /* DUSCC_FREQ */
  31. /*
  32.  * This macro expresses the lowest clock rate that can be attained by a
  33.  * 16 bit timer without using a prescaler (0x0ffff is the max timer value).
  34.  */
  35. #define DUSCC_MIN_DIV_1     (DUSCC_FREQ / 0x0ffff + 1)
  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 = 60; 
  43. LOCAL BOOL    sysAuxClkRunning     = FALSE; 
  44. LOCAL FUNCPTR sysAuxClkRoutine     = NULL; 
  45. LOCAL int     sysAuxClkArg         = NULL;
  46. LOCAL BOOL    auxClkConnected      = FALSE; 
  47. /*******************************************************************************
  48. *
  49. * sysClkInt - handle system clock interrupts
  50. *
  51. * This routine handles system clock interrupts.
  52. */
  53. LOCAL void sysClkInt (void)
  54.     {
  55.     /* acknowledge interrupt */
  56.     *DUSCC_ICTSRA = DUSCC_ICTSR_CT_ZERO_COUNT;
  57.     if (sysClkRoutine != NULL)
  58.         (*sysClkRoutine) (sysClkArg);
  59.     }
  60. /*******************************************************************************
  61. *
  62. * sysClkConnect - connect a routine to the system clock interrupt
  63. *
  64. * This routine specifies the interrupt service routine to be called at each
  65. * clock interrupt.  Normally, it is called from usrRoot() in usrConfig.c to 
  66. * connect usrClock() to the system clock interrupt.
  67. *
  68. * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
  69. *
  70. * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  71. */
  72.  
  73. STATUS sysClkConnect
  74.     (
  75.     FUNCPTR routine,    /* routine called at each system clock interrupt */
  76.     int arg             /* argument with which to call routine           */
  77.     )
  78.     {
  79.     sysHwInit2 (); /* XXX for now -- needs to be in usrConfig.c */
  80.  
  81.     sysClkConnected = TRUE;
  82.  
  83.     sysClkRoutine   = routine;
  84.     sysClkArg       = arg;
  85.  
  86.     return (OK);
  87.     }
  88. /*******************************************************************************
  89. *
  90. * sysClkDisable - turn off system clock interrupts
  91. *
  92. * This routine disables system clock interrupts.
  93. *
  94. * RETURNS: N/A
  95. *
  96. * SEE ALSO: sysClkEnable()
  97. */
  98.  
  99. void sysClkDisable (void)
  100.  
  101.     {
  102.     if (sysClkRunning)
  103.         {
  104.         /* disable interrupts */
  105.  
  106.         *DUSCC_CCRA = DUSCC_CCR_CT_STOP;        /* stop timer */
  107.         sysClkRunning = FALSE;
  108.         }
  109.     }
  110. /****************************************************************************** 
  111. *
  112. * sysClkEnable - turn on system clock interrupts
  113. *
  114. * This routine enables system clock interrupts.
  115. *
  116. * RETURNS: N/A
  117. *
  118. * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  119. */
  120.  
  121. void sysClkEnable (void)
  122.  
  123.     {
  124.     if (!sysClkRunning)
  125.         {
  126. FAST int tc;
  127. FAST int prescale;
  128.         /* calculate the divide ratio, and write it to the timer chip */
  129. prescale = (sysClkTicksPerSecond < DUSCC_MIN_DIV_1) ? 64 : 1;
  130. tc = DUSCC_FREQ / prescale / sysClkTicksPerSecond;
  131.         *DUSCC_CTPRHA = MSB (tc);
  132.         *DUSCC_CTPRLA = LSB (tc);
  133.         /* enable and start clock interrupts */
  134.         if (prescale == 1)
  135.             {
  136.     /* prescale is 1 */
  137.             *DUSCC_CTCRA = DUSCC_CTCR_ZERO_DET_INTR_ENABLE |
  138.                            DUSCC_CTCR_CLK_X1_CLK |
  139.                            DUSCC_CTCR_PRESCALER_DIV_1;
  140.             }
  141.         else
  142.             {
  143.     /* prescale is 64 */
  144.             *DUSCC_CTCRA = DUSCC_CTCR_ZERO_DET_INTR_ENABLE |
  145.                            DUSCC_CTCR_CLK_X1_CLK |
  146.                            DUSCC_CTCR_PRESCALER_DIV_64;
  147.             }
  148.         *DUSCC_CCRA  = DUSCC_CCR_CT_PRE_CTPRHL; /* preload */
  149.         *DUSCC_CCRA  = DUSCC_CCR_CT_START; /* start   */
  150.  
  151.         sysClkRunning = TRUE;
  152.         }
  153.     }
  154. /*******************************************************************************
  155. *
  156. * sysClkRateGet - get the system clock rate
  157. *
  158. * This routine returns the system clock rate.
  159. *
  160. * RETURNS: The number of ticks per second of the system clock.
  161. *
  162. * SEE ALSO: sysClkEnable(), sysClkRateSet()
  163. */
  164.  
  165. int sysClkRateGet (void)
  166.  
  167.     {
  168.     return (sysClkTicksPerSecond);
  169.     }
  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.  
  199.     return (OK);
  200.     }
  201.  
  202. /*******************************************************************************
  203. *
  204. * sysAuxClkInt - handle auxiliary clock interrupts
  205. */
  206.  
  207. LOCAL void sysAuxClkInt (void)
  208.  
  209.     {
  210.     /* acknowledge interrupt */
  211.     *DUSCC_ICTSRB = DUSCC_ICTSR_CT_ZERO_COUNT;
  212.     if (sysAuxClkRoutine != NULL)
  213.         (*sysAuxClkRoutine) (sysAuxClkArg);
  214.     }
  215.        
  216. /*******************************************************************************
  217. *
  218. * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  219. *
  220. * This routine specifies the interrupt service routine to be called at each
  221. * auxiliary clock interrupt.  It does not enable auxiliary clock
  222. * interrupts.
  223. *
  224. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  225. *
  226. * SEE ALSO: intConnect(), sysAuxClkEnable()
  227. */
  228.  
  229. STATUS sysAuxClkConnect
  230.     (
  231.     FUNCPTR routine,    /* routine called at each aux clock interrupt    */
  232.     int arg             /* argument to auxiliary clock interrupt routine */
  233.     )
  234.     {
  235.     auxClkConnected  = TRUE;
  236.  
  237.     sysAuxClkRoutine = routine;
  238.     sysAuxClkArg     = arg;
  239.  
  240.     return (OK);
  241.     }
  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.     {
  257.     if (sysAuxClkRunning)
  258.         {
  259.         *DUSCC_CCRB = DUSCC_CCR_CT_STOP;        /* stop timer */
  260.  
  261.         sysAuxClkRunning = FALSE;
  262.         }
  263.     }
  264. /*******************************************************************************
  265. *
  266. * sysAuxClkEnable - turn on auxiliary clock interrupts
  267. *
  268. * This routine enables auxiliary clock interrupts.
  269. *
  270. * RETURNS: N/A
  271. *
  272. * SEE ALSO: sysAuxClkConnect(), sysAuxClkDisable(), sysAuxClkRateSet()
  273. */
  274.  
  275. void sysAuxClkEnable (void)
  276.  
  277.     {
  278.     if (!sysAuxClkRunning)
  279.         {
  280. FAST int tc;
  281. FAST int prescale;
  282.         /* calculate the divide ratio, and write it to the timer chip */
  283. prescale = (auxClkTicksPerSecond < DUSCC_MIN_DIV_1) ? 64 : 1;
  284. tc = DUSCC_FREQ / prescale / auxClkTicksPerSecond;
  285.         *DUSCC_CTPRHB = MSB (tc);
  286.         *DUSCC_CTPRLB = LSB (tc);
  287.         /* enable and start clock interrupts */
  288.         if (prescale == 1)
  289.             {
  290.     /* prescale is 1 */
  291.     *DUSCC_CTCRB = DUSCC_CTCR_ZERO_DET_INTR_ENABLE |
  292.    DUSCC_CTCR_CLK_X1_CLK |
  293.    DUSCC_CTCR_PRESCALER_DIV_1;
  294.             }
  295.         else
  296.             {
  297.     /* prescale is 64 */
  298.             *DUSCC_CTCRB = DUSCC_CTCR_ZERO_DET_INTR_ENABLE |
  299.                            DUSCC_CTCR_CLK_X1_CLK |
  300.                            DUSCC_CTCR_PRESCALER_DIV_64;
  301.             }
  302.         *DUSCC_CCRB  = DUSCC_CCR_CT_PRE_CTPRHL; /* preload */
  303.         *DUSCC_CCRB  = DUSCC_CCR_CT_START; /* start   */
  304.  
  305.         sysAuxClkRunning = TRUE;
  306.         }
  307.     }
  308. /*******************************************************************************
  309. *
  310. * sysAuxClkRateGet - get the auxiliary clock rate
  311. *
  312. * This routine returns the interrupt rate of the auxiliary clock.
  313. *
  314. * RETURNS: The number of ticks per second of the auxiliary clock.
  315. *
  316. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateSet()
  317. */
  318.  
  319. int sysAuxClkRateGet (void)
  320.  
  321.     {
  322.     return (auxClkTicksPerSecond);
  323.     }
  324. /*******************************************************************************
  325. *
  326. * sysAuxClkRateSet - set the auxiliary clock rate
  327. *
  328. * This routine sets the interrupt rate of the auxiliary clock.
  329. * It does not enable auxiliary clock interrupts.
  330. *
  331. * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  332. *
  333. * SEE ALSO: sysAuxClkEnable(), sysAuxClkRateGet()
  334. */
  335.  
  336. STATUS sysAuxClkRateSet
  337.     (
  338.     int ticksPerSecond     /* number of clock interrupts per second */
  339.     )
  340.     {
  341.     if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
  342.         return (ERROR);
  343.  
  344.     auxClkTicksPerSecond = ticksPerSecond;
  345.  
  346.     if (sysAuxClkRunning)
  347.         {
  348.         sysAuxClkDisable ();
  349.         sysAuxClkEnable ();
  350.         }
  351.  
  352.     return (OK);
  353.     }