1 /******************************************************************************
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
6 * See the file "skfddi.c" for further information.
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.
13 * The information in this file is provided "AS IS" without warranty.
15 ******************************************************************************/
26 static const char ID_sccs[] = "@(#)smttimer.c 2.4 97/08/04 (C) SK " ;
30 * external function declarations
32 extern u_long hwt_read() ;
33 extern void hwt_stop() ;
34 extern void hwt_start() ;
36 static void timer_done() ;
39 void smt_timer_init(smc)
43 smc->t.st_fast.tm_active = FALSE ;
44 smc->t.st_fast.tm_next = 0 ;
48 void smt_timer_stop(smc,timer)
50 struct smt_timer *timer ;
52 struct smt_timer **prev ;
53 struct smt_timer *tm ;
56 * remove timer from queue
58 timer->tm_active = FALSE ;
59 if (smc->t.st_queue == timer && !timer->tm_next) {
62 for (prev = &smc->t.st_queue ; (tm = *prev) ; prev = &tm->tm_next ) {
66 tm->tm_next->tm_delta += tm->tm_delta ;
73 void smt_timer_start(smc,timer,time,token)
75 struct smt_timer *timer ;
79 struct smt_timer **prev ;
80 struct smt_timer *tm ;
83 time /= 16 ; /* input is uS, clock ticks are 16uS */
86 smt_timer_stop(smc,timer) ;
88 timer->tm_token = token ;
89 timer->tm_active = TRUE ;
90 if (!smc->t.st_queue) {
91 smc->t.st_queue = timer ;
93 timer->tm_delta = time ;
103 * find position in queue
106 for (prev = &smc->t.st_queue ; (tm = *prev) ; prev = &tm->tm_next ) {
107 if (delta + tm->tm_delta > time) {
110 delta += tm->tm_delta ;
112 /* insert in queue */
114 timer->tm_next = tm ;
115 timer->tm_delta = time - delta ;
117 tm->tm_delta -= timer->tm_delta ;
119 * start new with first
121 hwt_start(smc,smc->t.st_queue->tm_delta) ;
124 void smt_force_irq(smc)
127 smt_timer_start(smc,&smc->t.st_fast,32L, EV_TOKEN(EVENT_SMT,SM_FAST));
130 void smt_timer_done(smc)
136 static void timer_done(smc,restart)
141 struct smt_timer *tm ;
142 struct smt_timer *next ;
143 struct smt_timer **last ;
146 delta = hwt_read(smc) ;
147 last = &smc->t.st_queue ;
148 tm = smc->t.st_queue ;
149 while (tm && !done) {
150 if (delta >= tm->tm_delta) {
151 tm->tm_active = FALSE ;
152 delta -= tm->tm_delta ;
153 last = &tm->tm_next ;
157 tm->tm_delta -= delta ;
163 next = smc->t.st_queue ;
164 smc->t.st_queue = tm ;
166 for ( tm = next ; tm ; tm = next) {
168 timer_event(smc,tm->tm_token) ;
171 if (restart && smc->t.st_queue)
172 hwt_start(smc,smc->t.st_queue->tm_delta) ;