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 " ;
29 static void timer_done(struct s_smc
*smc
, int restart
);
31 void smt_timer_init(struct s_smc
*smc
)
33 smc
->t
.st_queue
= NULL
;
34 smc
->t
.st_fast
.tm_active
= FALSE
;
35 smc
->t
.st_fast
.tm_next
= NULL
;
39 void smt_timer_stop(struct s_smc
*smc
, struct smt_timer
*timer
)
41 struct smt_timer
**prev
;
42 struct smt_timer
*tm
;
45 * remove timer from queue
47 timer
->tm_active
= FALSE
;
48 if (smc
->t
.st_queue
== timer
&& !timer
->tm_next
) {
51 for (prev
= &smc
->t
.st_queue
; (tm
= *prev
) ; prev
= &tm
->tm_next
) {
55 tm
->tm_next
->tm_delta
+= tm
->tm_delta
;
62 void smt_timer_start(struct s_smc
*smc
, struct smt_timer
*timer
, u_long time
,
65 struct smt_timer
**prev
;
66 struct smt_timer
*tm
;
69 time
/= 16 ; /* input is uS, clock ticks are 16uS */
72 smt_timer_stop(smc
,timer
) ;
74 timer
->tm_token
= token
;
75 timer
->tm_active
= TRUE
;
76 if (!smc
->t
.st_queue
) {
77 smc
->t
.st_queue
= timer
;
78 timer
->tm_next
= NULL
;
79 timer
->tm_delta
= time
;
89 * find position in queue
92 for (prev
= &smc
->t
.st_queue
; (tm
= *prev
) ; prev
= &tm
->tm_next
) {
93 if (delta
+ tm
->tm_delta
> time
) {
96 delta
+= tm
->tm_delta
;
100 timer
->tm_next
= tm
;
101 timer
->tm_delta
= time
- delta
;
103 tm
->tm_delta
-= timer
->tm_delta
;
105 * start new with first
107 hwt_start(smc
,smc
->t
.st_queue
->tm_delta
) ;
110 void smt_force_irq(struct s_smc
*smc
)
112 smt_timer_start(smc
,&smc
->t
.st_fast
,32L, EV_TOKEN(EVENT_SMT
,SM_FAST
));
115 void smt_timer_done(struct s_smc
*smc
)
120 static void timer_done(struct s_smc
*smc
, int restart
)
123 struct smt_timer
*tm
;
124 struct smt_timer
*next
;
125 struct smt_timer
**last
;
128 delta
= hwt_read(smc
) ;
129 last
= &smc
->t
.st_queue
;
130 tm
= smc
->t
.st_queue
;
131 while (tm
&& !done
) {
132 if (delta
>= tm
->tm_delta
) {
133 tm
->tm_active
= FALSE
;
134 delta
-= tm
->tm_delta
;
135 last
= &tm
->tm_next
;
139 tm
->tm_delta
-= delta
;
145 next
= smc
->t
.st_queue
;
146 smc
->t
.st_queue
= tm
;
148 for ( tm
= next
; tm
; tm
= next
) {
150 timer_event(smc
,tm
->tm_token
) ;
153 if (restart
&& smc
->t
.st_queue
)
154 hwt_start(smc
,smc
->t
.st_queue
->tm_delta
) ;