hwt.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * (C)Copyright 1998,1999 SysKonnect,
  4.  * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
  5.  *
  6.  * See the file "skfddi.c" for further information.
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * The information in this file is provided "AS IS" without warranty.
  14.  *
  15.  ******************************************************************************/
  16. /*
  17.  * Timer Driver for FBI board (timer chip 82C54)
  18.  */
  19. /*
  20.  * Modifications:
  21.  *
  22.  * 28-Jun-1994 sw Edit v1.6.
  23.  * MCA: Added support for the SK-NET FDDI-FM2 adapter. The
  24.  *  following functions have been added(+) or modified(*):
  25.  *  hwt_start(*), hwt_stop(*), hwt_restart(*), hwt_read(*)
  26.  */
  27. #include "h/types.h"
  28. #include "h/fddi.h"
  29. #include "h/smc.h"
  30. #ifndef lint
  31. static const char ID_sccs[] = "@(#)hwt.c 1.13 97/04/23 (C) SK " ;
  32. #endif
  33. /*
  34.  * Prototypes of local functions.
  35.  */
  36. /* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
  37. /*static*/ void hwt_restart() ;
  38. /************************
  39.  *
  40.  * hwt_start
  41.  *
  42.  * Start hardware timer (clock ticks are 16us).
  43.  *
  44.  * void hwt_start(
  45.  * struct s_smc *smc,
  46.  * u_long time) ;
  47.  * In
  48.  * smc - A pointer to the SMT Context structure.
  49.  *
  50.  * time - The time in units of 16us to load the timer with.
  51.  * Out
  52.  * Nothing.
  53.  *
  54.  ************************/
  55. #define HWT_MAX (65000)
  56. void hwt_start(smc, time)
  57. struct s_smc *smc ;
  58. u_long time ;
  59. {
  60. u_short cnt ;
  61. if (time > HWT_MAX)
  62. time = HWT_MAX ;
  63. smc->hw.t_start = time ;
  64. smc->hw.t_stop = 0L ;
  65. cnt = (u_short)time ;
  66. /*
  67.  * if time < 16 us
  68.  * time = 16 us
  69.  */
  70. if (!cnt)
  71. cnt++ ;
  72. #ifndef PCI
  73. /*
  74.  * 6.25MHz -> CLK0 : T0 (cnt0 = 16us) -> OUT0
  75.  *    OUT0 -> CLK1 : T1 (cnt1) OUT1 -> ISRA(IS_TIMINT)
  76.  */
  77. OUT_82c54_TIMER(3,1<<6 | 3<<4 | 0<<1) ; /* counter 1, mode 0 */
  78. OUT_82c54_TIMER(1,cnt & 0xff) ; /* LSB */
  79. OUT_82c54_TIMER(1,(cnt>>8) & 0xff) ; /* MSB */
  80. /*
  81.  * start timer by switching counter 0 to mode 3
  82.  * T0 resolution 16 us (CLK0=0.16us)
  83.  */
  84. OUT_82c54_TIMER(3,0<<6 | 3<<4 | 3<<1) ; /* counter 0, mode 3 */
  85. OUT_82c54_TIMER(0,100) ; /* LSB */
  86. OUT_82c54_TIMER(0,0) ; /* MSB */
  87. #else /* PCI */
  88. outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ; /* Load timer value. */
  89. outpw(ADDR(B2_TI_CRTL), TIM_START) ; /* Start timer. */
  90. #endif /* PCI */
  91. smc->hw.timer_activ = TRUE ;
  92. }
  93. /************************
  94.  *
  95.  * hwt_stop
  96.  *
  97.  * Stop hardware timer.
  98.  *
  99.  * void hwt_stop(
  100.  * struct s_smc *smc) ;
  101.  * In
  102.  * smc - A pointer to the SMT Context structure.
  103.  * Out
  104.  * Nothing.
  105.  *
  106.  ************************/
  107. void hwt_stop(smc)
  108. struct s_smc *smc ;
  109. {
  110. #ifndef PCI
  111. /* stop counter 0 by switching to mode 0 */
  112. OUT_82c54_TIMER(3,0<<6 | 3<<4 | 0<<1) ; /* counter 0, mode 0 */
  113. OUT_82c54_TIMER(0,0) ; /* LSB */
  114. OUT_82c54_TIMER(0,0) ; /* MSB */
  115. #else /* PCI */
  116. outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
  117. outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
  118. #endif /* PCI */
  119. smc->hw.timer_activ = FALSE ;
  120. }
  121. /************************
  122.  *
  123.  * hwt_init
  124.  *
  125.  * Initialize hardware timer.
  126.  *
  127.  * void hwt_init(
  128.  * struct s_smc *smc) ;
  129.  * In
  130.  * smc - A pointer to the SMT Context structure.
  131.  * Out
  132.  * Nothing.
  133.  *
  134.  ************************/
  135. void hwt_init(smc)
  136. struct s_smc *smc ;
  137. {
  138. smc->hw.t_start = 0 ;
  139. smc->hw.t_stop = 0 ;
  140. smc->hw.timer_activ = FALSE ;
  141. hwt_restart(smc) ;
  142. }
  143. /************************
  144.  *
  145.  * hwt_restart
  146.  *
  147.  * Clear timer interrupt.
  148.  *
  149.  * void hwt_restart(
  150.  * struct s_smc *smc) ;
  151.  * In
  152.  * smc - A pointer to the SMT Context structure.
  153.  * Out
  154.  * Nothing.
  155.  *
  156.  ************************/
  157. void hwt_restart(smc)
  158. struct s_smc *smc ;
  159. {
  160. hwt_stop(smc) ;
  161. #ifndef PCI
  162. OUT_82c54_TIMER(3,1<<6 | 3<<4 | 0<<1) ; /* counter 1, mode 0 */
  163. OUT_82c54_TIMER(1,1 ) ; /* LSB */
  164. OUT_82c54_TIMER(1,0 ) ; /* MSB */
  165. #endif
  166. }
  167. /************************
  168.  *
  169.  * hwt_read
  170.  *
  171.  * Stop hardware timer and read time elapsed since last start.
  172.  *
  173.  * u_long hwt_read(smc) ;
  174.  * In
  175.  * smc - A pointer to the SMT Context structure.
  176.  * Out
  177.  * The elapsed time since last start in units of 16us.
  178.  *
  179.  ************************/
  180. u_long hwt_read(smc)
  181. struct s_smc *smc ;
  182. {
  183. u_short tr ;
  184. #ifndef PCI
  185. u_short is ;
  186. #else
  187. u_long is ;
  188. #endif
  189. if (smc->hw.timer_activ) {
  190. hwt_stop(smc) ;
  191. #ifndef PCI
  192. OUT_82c54_TIMER(3,1<<6) ; /* latch command */
  193. tr = IN_82c54_TIMER(1) & 0xff ;
  194. tr += (IN_82c54_TIMER(1) & 0xff)<<8 ;
  195. #else /* PCI */
  196. tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
  197. #endif /* PCI */
  198. is = GET_ISR() ;
  199. /* Check if timer expired (or wraparound). */
  200. if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {
  201. hwt_restart(smc) ;
  202. smc->hw.t_stop = smc->hw.t_start ;
  203. }
  204. else
  205. smc->hw.t_stop = smc->hw.t_start - tr ;
  206. }
  207. return (smc->hw.t_stop) ;
  208. }
  209. #ifdef PCI
  210. /************************
  211.  *
  212.  * hwt_quick_read
  213.  *
  214.  * Stop hardware timer and read timer value and start the timer again.
  215.  *
  216.  * u_long hwt_read(smc) ;
  217.  * In
  218.  * smc - A pointer to the SMT Context structure.
  219.  * Out
  220.  * current timer value in units of 80ns.
  221.  *
  222.  ************************/
  223. u_long hwt_quick_read(smc)
  224. struct s_smc *smc ;
  225. {
  226. u_long interval ;
  227. u_long time ;
  228. interval = inpd(ADDR(B2_TI_INI)) ;
  229. outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
  230. time = inpd(ADDR(B2_TI_VAL)) ;
  231. outpd(ADDR(B2_TI_INI),time) ;
  232. outpw(ADDR(B2_TI_CRTL), TIM_START) ;
  233. outpd(ADDR(B2_TI_INI),interval) ;
  234. return(time) ;
  235. }
  236. /************************
  237.  *
  238.  * hwt_wait_time(smc,start,duration)
  239.  *
  240.  * This function returnes after the amount of time is elapsed
  241.  * since the start time.
  242.  * 
  243.  * para start start time
  244.  * duration time to wait
  245.  *
  246.  * NOTE: The fuction will return immediatly, if the timer is not 
  247.  *  started
  248.  ************************/
  249. void hwt_wait_time(smc,start,duration)
  250. struct s_smc *smc ;
  251. u_long start ;
  252. long duration ;
  253. {
  254. long diff ;
  255. long interval ;
  256. int wrapped ;
  257. /*
  258.  * check if timer is running
  259.  */
  260. if (smc->hw.timer_activ == FALSE ||
  261. hwt_quick_read(smc) == hwt_quick_read(smc)) {
  262. return ;
  263. }
  264. interval = inpd(ADDR(B2_TI_INI)) ;
  265. if (interval > duration) {
  266. do {
  267. diff = (long)(start - hwt_quick_read(smc)) ;
  268. if (diff < 0) {
  269. diff += interval ;
  270. }
  271. } while (diff <= duration) ;
  272. }
  273. else {
  274. diff = interval ;
  275. wrapped = 0 ;
  276. do {
  277. if (!wrapped) {
  278. if (hwt_quick_read(smc) >= start) {
  279. diff += interval ;
  280. wrapped = 1 ;
  281. }
  282. }
  283. else {
  284. if (hwt_quick_read(smc) < start) {
  285. wrapped = 0 ;
  286. }
  287. }
  288. } while (diff <= duration) ;
  289. }
  290. }
  291. #endif