s3c2410xTimer.c
上传用户:ske666
上传日期:2022-03-30
资源大小:371k
文件大小:10k
源码类别:

VxWorks

开发平台:

Objective-C

  1. /* s3c2410xTimer.c - s3c2410x timer library */
  2. /* Copyright 2004 HITSAT, Inc. */
  3. /*
  4. DESCRIPTION
  5. This driver provides 3 main functions:
  6. system clock support;
  7. timestamp timer support.
  8. If necessary, each function may be conditioned by a separate INCLUDE_ macro.
  9. The timestamp function is always conditional upon the INCLUDE_TIMESTAMP macro.
  10. The macros:
  11. SYS_CLK_RATE_MIN;
  12. SYS_CLK_RATE_MAX;
  13. Must be defined to provide parameter checking for the sys[Aux]ClkRateSet() routines.
  14. */
  15. /* includes */
  16. #include "vxWorks.h"
  17. #include "config.h"
  18. #include "drv/timer/timerDev.h"
  19. #include "drv/timer/timestampDev.h"
  20. /* defines */
  21. #undef SYS_CLK_RATE_MIN
  22. #undef SYS_CLK_RATE_MAX
  23. #define SYS_CLK_RATE_MIN 1
  24. #define SYS_CLK_RATE_MAX 12000
  25. #undef AUX_CLK_RATE_MAX
  26. #undef AUX_CLK_RATE_MIN
  27. #undef INCLUDE_AUX_CLK
  28. #define INCLUDE_AUX_CLK
  29. #define AUX_CLK_RATE_MIN 1
  30. #define AUX_CLK_RATE_MAX 12000
  31. /* The default is to assume memory mapped I/O */
  32. #ifndef s3c2410x_IO_READ
  33. #define s3c2410x_IO_READ(reg,result) ((result)=*(volatile UINT32 *)(reg))
  34. #endif
  35. #ifndef s3c2410x_IO_WRITE
  36. #define s3c2410x_IO_WRITE(reg, data) (*((volatile UINT32 *)(reg))=(data))
  37. #endif
  38. /* locals */
  39. LOCAL FUNCPTR sysClkRoutine = NULL; /* routine to call on clock tick */
  40. LOCAL int sysClkArg = (int)NULL; /* its argument */
  41. LOCAL BOOL sysClkRunning = FALSE;
  42. LOCAL int sysClkConnected      = FALSE;
  43. LOCAL int sysClkTicksPerSecond = 10000;
  44. LOCAL FUNCPTR sysAuxClkRoutine = NULL;
  45. LOCAL int sysAuxClkArg = 0;
  46. LOCAL BOOL sysAuxClkRunning = FALSE;
  47. LOCAL int sysAuxClkConnected      = FALSE;
  48. LOCAL int sysAuxClkTicksPerSecond = 10000;
  49. IMPORT STATUS s3c2410xIntLvlVecChk (int*, int*);
  50. IMPORT STATUS s3c2410xIntLvlEnable (int);
  51. IMPORT STATUS s3c2410xIntLvlDisable (int);
  52. /*
  53.  * sysClkInt - interrupt level processing for system clock
  54.  *
  55.  * This routine handles an auxiliary clock interrupt.  It acknowledges the
  56.  * interrupt and calls the routine installed by sysClkConnect().
  57.  */
  58. void sysClkInt (void)
  59. {
  60. /* call system clock service routine */
  61. if(sysClkRoutine != NULL) 
  62. {
  63. (*sysClkRoutine)(sysClkArg);
  64. }
  65. /* clear the srcpend of sysclk, and enable this level. */
  66. /* s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, 1<<SYS_TIMER_INT_LVL); 
  67. s3c2410xIntLvlEnable(SYS_TIMER_INT_LVL);*/
  68. return;
  69. }
  70. /*
  71.  * sysClkConnect - connect a routine to the system clock interrupt
  72.  *
  73.  * This routine specifies the interrupt service routine to be called at each
  74.  * clock interrupt.  Normally, it is called from usrRoot() in usrConfig.c to 
  75.  * connect usrClock() to the system clock interrupt.
  76.  *
  77.  * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
  78.  *
  79.  * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  80.  */
  81. STATUS sysClkConnect
  82. (
  83. FUNCPTR routine, /* routine to be called at each clock interrupt */
  84. int arg /* argument with which to call routine */
  85. )
  86. {
  87. if(sysClkConnected == FALSE)
  88. {
  89. s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCFG0), TCFG0_INIT_VALUE);
  90. s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCFG1), TCFG1_INIT_VALUE);
  91. sysHwInit2();
  92. sysClkConnected = TRUE;
  93. }
  94. sysClkRoutine = NULL;
  95. sysClkArg = arg;
  96. #if ((CPU_FAMILY == ARM) && ARM_THUMB)
  97. /* set b0 so that sysClkConnect() can be used from shell */
  98. sysClkRoutine = (FUNCPTR)((UINT32)routine | 1);
  99. #else
  100. sysClkRoutine = routine;
  101. #endif /* CPU_FAMILY == ARM */
  102. return (OK);
  103. }
  104. /*
  105.  * sysClkDisable - turn off system clock interrupts
  106.  *
  107.  * This routine disables system clock interrupts.
  108.  *
  109.  * RETURNS: N/A
  110.  *
  111.  * SEE ALSO: sysClkEnable()
  112.  */
  113. void sysClkDisable (void)
  114. {
  115. UINT32 tempUINT32;
  116. if(sysClkRunning)
  117. {
  118. /* Disable system timer interrupts */
  119. s3c2410xIntLvlDisable(SYS_TIMER_INT_LVL);
  120. /* Stop timer0 */
  121. s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  122. tempUINT32 &= ~(BIT_SYS_TIMER_EN);
  123. s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  124. sysClkRunning = FALSE;
  125. }
  126. }
  127. /*
  128.  * sysClkEnable - turn on system clock interrupts
  129.  *
  130.  * This routine enables system clock interrupts.
  131.  *
  132.  * RETURNS: N/A
  133.  *
  134.  * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  135.  */
  136. void sysClkEnable (void)
  137. {
  138. UINT32 tempUINT32;
  139. static BOOL connected = FALSE;
  140. if(!connected)
  141. {
  142. /* TODO - connect sysClkInt to appropriate interrupt */
  143. sysClkInt();
  144. connected = TRUE;
  145. }
  146. if(!sysClkRunning)
  147. {
  148. /* 12207 = PCLK/(255*16); */
  149. s3c2410x_IO_WRITE((SYS_TIMER_BASE+OFFSET_TCNTB), ((s3c2410x_PCLK/(2*250))/sysClkTicksPerSecond));
  150. s3c2410x_IO_WRITE((SYS_TIMER_BASE+OFFSET_TCMPB), ((s3c2410x_PCLK/(2*250))/(sysClkTicksPerSecond*2)));
  151. /* Set manual update bit and reload bit, clear enable bit. */
  152. s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  153. tempUINT32 |= BIT_SYS_TIMER_MU;
  154. tempUINT32 &= ~(BIT_SYS_TIMER_EN|BIT_SYS_TIMER_RE);
  155. s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  156. /* Set enable bit and reload bit, clear manual update bit. */
  157. s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  158. tempUINT32 &= ~(BIT_SYS_TIMER_MU);
  159. tempUINT32 |= (BIT_SYS_TIMER_EN|BIT_SYS_TIMER_RE);
  160. s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  161. /* Enable interrupt for system timer. */
  162. s3c2410xIntLvlEnable(SYS_TIMER_INT_LVL);
  163. sysClkRunning = TRUE;
  164. }
  165. }
  166. /*
  167.  * sysClkRateGet - get the system clock rate
  168.  *
  169.  * This routine returns the system clock rate.
  170.  *
  171.  * RETURNS: The number of ticks per second of the system clock.
  172.  *
  173.  * SEE ALSO: sysClkEnable(), sysClkRateSet()
  174.  */
  175. int sysClkRateGet (void)
  176. {
  177. return sysClkTicksPerSecond;
  178. }
  179. /*
  180.  * sysClkRateSet - set the system clock rate
  181.  *
  182.  * This routine sets the interrupt rate of the system clock.
  183.  * It is called by usrRoot() in usrConfig.c.
  184.  *
  185.  * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  186.  *
  187.  * SEE ALSO: sysClkEnable(), sysClkRateGet()
  188.  */
  189. STATUS sysClkRateSet
  190. (
  191. int ticksPerSecond     /* number of clock interrupts per second */
  192. )
  193. {
  194. /* TODO - return ERROR if rate is not supported */
  195. if((ticksPerSecond > SYS_CLK_RATE_MAX) ||(ticksPerSecond < SYS_CLK_RATE_MIN))
  196. {
  197. return ERROR;
  198. }
  199. else
  200. {
  201. sysClkTicksPerSecond = ticksPerSecond;
  202. if(sysClkRunning)
  203. {
  204. sysClkDisable();
  205. sysClkEnable();
  206. }
  207. return (OK);
  208. }
  209. }
  210. /*
  211.  * sysAuxClkInt - interrupt level processing for auxiliary clock
  212.  *
  213.  * This routine handles an auxiliary clock interrupt.  It acknowledges the
  214.  * interrupt and calls the routine installed by sysAuxClkConnect().
  215.  */
  216. void sysAuxClkInt (void)
  217. {
  218. /* call auxiliary clock service routine */
  219. if(sysAuxClkRoutine != NULL) 
  220. {
  221. (*sysAuxClkRoutine)(sysAuxClkArg);
  222. }
  223. /* clear the srcpend of auxclk, and enable this level. */
  224. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, 1<<AUX_TIMER_INT_LVL);
  225. s3c2410xIntLvlEnable(AUX_TIMER_INT_LVL);
  226. return;
  227. }
  228. /*
  229.  * sysAuxClkConnect - connect a routine to the auxiliary clock interrupt
  230.  *
  231.  * This routine specifies the interrupt service routine to be called at each
  232.  * clock interrupt.  Normally, it is called from usrRoot() in usrConfig.c to 
  233.  * connect usrClock() to the auxiliary clock interrupt.
  234.  *
  235.  * RETURN: OK, or ERROR if the routine cannot be connected to the interrupt.
  236.  *
  237.  * SEE ALSO: intConnect(), usrClock(), sysClkEnable()
  238.  */
  239. STATUS sysAuxClkConnect
  240. (
  241. FUNCPTR routine, /* routine to be called at each clock interrupt */
  242. int arg /* argument with which to call routine */
  243. )
  244. {
  245. if(sysAuxClkConnected == FALSE)
  246. {
  247. s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCFG0), TCFG0_INIT_VALUE);
  248. s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCFG1), TCFG1_INIT_VALUE);
  249. sysHwInit2();
  250. sysAuxClkConnected = TRUE;
  251. }
  252. sysAuxClkRoutine = NULL;
  253. sysAuxClkArg = arg;
  254. #if ((CPU_FAMILY == ARM) && ARM_THUMB)
  255. /* set b0 so that sysClkConnect() can be used from shell */
  256. sysAuxClkRoutine = (FUNCPTR)((UINT32)routine | 1);
  257. #else
  258. sysAuxClkRoutine = routine;
  259. #endif /* CPU_FAMILY == ARM */
  260. return (OK);
  261. }
  262. /*
  263.  * sysClkDisable - turn off system clock interrupts
  264.  *
  265.  * This routine disables system clock interrupts.
  266.  *
  267.  * RETURNS: N/A
  268.  *
  269.  * SEE ALSO: sysClkEnable()
  270.  */
  271. void sysAuxClkDisable(void)
  272. {
  273. UINT32 tempUINT32;
  274. if(sysAuxClkRunning)
  275. {
  276. /* Disable system timer interrupts */
  277. s3c2410xIntLvlDisable(AUX_TIMER_INT_LVL);
  278. /* Stop timer0 */
  279. s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  280. tempUINT32 &= ~(BIT_AUX_TIMER_EN);
  281. s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  282. sysAuxClkRunning = FALSE;
  283. }
  284. }
  285. /*
  286.  * sysClkEnable - turn on system clock interrupts
  287.  *
  288.  * This routine enables system clock interrupts.
  289.  *
  290.  * RETURNS: N/A
  291.  *
  292.  * SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()
  293.  */
  294. void sysAuxClkEnable(void)
  295. {
  296. UINT32 tempUINT32;
  297. static BOOL connected = FALSE;
  298. if(!connected)
  299. {
  300. intConnect(INUM_TO_IVEC(AUX_TIMER_INT_VEC), sysAuxClkInt, 0);
  301. connected = TRUE;
  302. }
  303. if(!sysAuxClkRunning)
  304. {
  305. /* 12207 = PCLK/(255*16); */
  306. s3c2410x_IO_WRITE((AUX_TIMER_BASE+OFFSET_TCNTB), ((s3c2410x_PCLK/(2*250))/sysAuxClkTicksPerSecond));
  307. s3c2410x_IO_WRITE((AUX_TIMER_BASE+OFFSET_TCMPB), ((s3c2410x_PCLK/(2*250))/(sysAuxClkTicksPerSecond*2)));
  308. /* Set manual update bit and reload bit, clear enable bit. */
  309. s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  310. tempUINT32 |= BIT_AUX_TIMER_MU;
  311. tempUINT32 &= ~(BIT_AUX_TIMER_EN|BIT_AUX_TIMER_RE);
  312. s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  313. /* Set enable bit and reload bit, clear manual update bit. */
  314. s3c2410x_IO_READ((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  315. tempUINT32 &= ~(BIT_AUX_TIMER_MU);
  316. tempUINT32 |= (BIT_AUX_TIMER_EN|BIT_AUX_TIMER_RE);
  317. s3c2410x_IO_WRITE((MASTER_TIMER_BASE+OFFSET_TCON), tempUINT32);
  318. /* Enable interrupt for system timer. */
  319. s3c2410xIntLvlEnable(AUX_TIMER_INT_LVL);
  320. sysAuxClkRunning = TRUE;
  321. }
  322. }
  323. /*
  324.  * sysClkRateGet - get the system clock rate
  325.  *
  326.  * This routine returns the system clock rate.
  327.  *
  328.  * RETURNS: The number of ticks per second of the system clock.
  329.  *
  330.  * SEE ALSO: sysClkEnable(), sysClkRateSet()
  331.  */
  332. int sysAuxClkRateGet (void)
  333. {
  334. return sysAuxClkTicksPerSecond;
  335. }
  336. /*
  337.  * sysClkRateSet - set the system clock rate
  338.  *
  339.  * This routine sets the interrupt rate of the system clock.
  340.  * It is called by usrRoot() in usrConfig.c.
  341.  *
  342.  * RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.
  343.  *
  344.  * SEE ALSO: sysClkEnable(), sysClkRateGet()
  345.  */
  346. STATUS sysAuxClkRateSet
  347. (
  348. int ticksPerSecond     /* number of clock interrupts per second */
  349. )
  350. {
  351. /* TODO - return ERROR if rate is not supported */
  352. if((ticksPerSecond > AUX_CLK_RATE_MAX) ||(ticksPerSecond < AUX_CLK_RATE_MIN))
  353. {
  354. return ERROR;
  355. }
  356. else
  357. {
  358. sysAuxClkTicksPerSecond = ticksPerSecond;
  359. if(sysAuxClkRunning)
  360. {
  361. sysAuxClkDisable();
  362. sysAuxClkEnable();
  363. }
  364. return (OK);
  365. }
  366. }