18 You should have received a copy of the GNU Lesser General Public |
18 You should have received a copy of the GNU Lesser General Public |
19 License along with this library; if not, write to the Free Software |
19 License along with this library; if not, write to the Free Software |
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 */ |
21 */ |
22 |
22 |
23 //#define DEBUG_WAR_CONSOLE_ON |
23 /* #define DEBUG_WAR_CONSOLE_ON */ |
24 //#define DEBUG_ERR_CONSOLE_ON |
24 /* #define DEBUG_ERR_CONSOLE_ON */ |
25 |
25 |
26 #include <applicfg.h> |
26 #include <applicfg.h> |
27 #include "timer.h" |
27 #include "timer.h" |
28 |
28 |
29 // --------- The timer table --------- |
29 /* --------- The timer table --------- */ |
30 s_timer_entry timers[MAX_NB_TIMER] = {{TIMER_FREE, NULL, NULL, 0, 0, 0},}; |
30 s_timer_entry timers[MAX_NB_TIMER] = {{TIMER_FREE, NULL, NULL, 0, 0, 0},}; |
31 // |
31 |
32 TIMEVAL total_sleep_time = TIMEVAL_MAX; |
32 TIMEVAL total_sleep_time = TIMEVAL_MAX; |
33 TIMER_HANDLE last_timer_raw = -1; |
33 TIMER_HANDLE last_timer_raw = -1; |
34 |
34 |
35 #define minval(a,b) ((a<b)?a:b) |
35 #define minval(a,b) ((a<b)?a:b) |
36 |
36 |
37 // --------- Use this to declare a new alarm --------- |
37 /* --------- Use this to declare a new alarm --------- */ |
38 TIMER_HANDLE SetAlarm(CO_Data* d, UNS32 id, TimerCallback_t callback, TIMEVAL value, TIMEVAL period) |
38 TIMER_HANDLE SetAlarm(CO_Data* d, UNS32 id, TimerCallback_t callback, TIMEVAL value, TIMEVAL period) |
39 { |
39 { |
40 //printf("SetAlarm(UNS32 id=%d, TimerCallback_t callback=%x, TIMEVAL value=%d, TIMEVAL period=%d)\n", id, callback, value, period); |
40 /*printf("SetAlarm(UNS32 id=%d, TimerCallback_t callback=%x, TIMEVAL value=%d, TIMEVAL period=%d)\n", id, callback, value, period); */ |
41 TIMER_HANDLE i; |
41 TIMER_HANDLE i; |
42 TIMER_HANDLE row_number = TIMER_NONE; |
42 TIMER_HANDLE row_number = TIMER_NONE; |
43 |
43 |
44 // in order to decide new timer setting we have to run over all timer rows |
44 /* in order to decide new timer setting we have to run over all timer rows */ |
45 for(i=0; i <= last_timer_raw + 1 && i < MAX_NB_TIMER; i++) |
45 for(i=0; i <= last_timer_raw + 1 && i < MAX_NB_TIMER; i++) |
46 { |
46 { |
47 s_timer_entry *row = (timers+i); |
47 s_timer_entry *row = (timers+i); |
48 |
48 |
49 if (callback && // if something to store |
49 if (callback && /* if something to store */ |
50 row->state == TIMER_FREE) // and empty row |
50 row->state == TIMER_FREE) /* and empty row */ |
51 { // just store |
51 { /* just store */ |
52 row->callback = callback; |
52 row->callback = callback; |
53 row->d = d; |
53 row->d = d; |
54 row->id = id; |
54 row->id = id; |
55 row->val = value; |
55 row->val = value; |
56 row->interval = period; |
56 row->interval = period; |
58 row_number = i; |
58 row_number = i; |
59 break; |
59 break; |
60 } |
60 } |
61 } |
61 } |
62 |
62 |
63 if (row_number != TIMER_NONE) // if successfull |
63 if (row_number != TIMER_NONE) /* if successfull **/ |
64 { |
64 { |
|
65 TIMEVAL real_timer_value; |
|
66 TIMEVAL elapsed_time; |
|
67 |
65 if (row_number == last_timer_raw + 1) last_timer_raw++; |
68 if (row_number == last_timer_raw + 1) last_timer_raw++; |
66 |
69 |
67 // set next wakeup alarm if new entry is sooner than others, or if it is alone |
70 /* set next wakeup alarm if new entry is sooner than others, or if it is alone */ |
68 TIMEVAL real_timer_value = minval(value, TIMEVAL_MAX); |
71 real_timer_value = minval(value, TIMEVAL_MAX); |
69 TIMEVAL elapsed_time = getElapsedTime(); |
72 elapsed_time = getElapsedTime(); |
70 |
73 |
71 //printf("elapsed_time=%d real_timer_value=%d total_sleep_time=%d\n", elapsed_time, real_timer_value, total_sleep_time); |
74 /*printf("elapsed_time=%d real_timer_value=%d total_sleep_time=%d\n", elapsed_time, real_timer_value, total_sleep_time); */ |
72 if (total_sleep_time > elapsed_time && total_sleep_time - elapsed_time > real_timer_value) |
75 if (total_sleep_time > elapsed_time && total_sleep_time - elapsed_time > real_timer_value) |
73 { |
76 { |
74 total_sleep_time = elapsed_time + real_timer_value; |
77 total_sleep_time = elapsed_time + real_timer_value; |
75 setTimer(real_timer_value); |
78 setTimer(real_timer_value); |
76 } |
79 } |
77 //printf("SetAlarm() return %d\n", row_number); |
80 /*printf("SetAlarm() return %d\n", row_number); */ |
78 return row_number; |
81 return row_number; |
79 } |
82 } |
80 return TIMER_NONE; |
83 return TIMER_NONE; |
81 } |
84 } |
82 |
85 |
83 // --------- Use this to remove an alarm --------- |
86 /* --------- Use this to remove an alarm --------- */ |
84 TIMER_HANDLE DelAlarm(TIMER_HANDLE handle) |
87 TIMER_HANDLE DelAlarm(TIMER_HANDLE handle) |
85 { |
88 { |
86 // Quick and dirty. system timer will continue to be trigged, but no action will be preformed. |
89 /* Quick and dirty. system timer will continue to be trigged, but no action will be preformed. */ |
87 MSG_WAR(0x3320, "DelAlarm. handle = ", handle); |
90 MSG_WAR(0x3320, "DelAlarm. handle = ", handle); |
88 if(handle != TIMER_NONE) |
91 if(handle != TIMER_NONE) |
89 { |
92 { |
90 if(handle == last_timer_raw) |
93 if(handle == last_timer_raw) |
91 last_timer_raw--; |
94 last_timer_raw--; |
95 } |
98 } |
96 return TIMER_NONE; |
99 return TIMER_NONE; |
97 } |
100 } |
98 |
101 |
99 |
102 |
100 // --------- TimeDispatch is called on each timer expiration --------- |
103 /* --------- TimeDispatch is called on each timer expiration --------- */ |
101 void TimeDispatch() |
104 void TimeDispatch() |
102 { |
105 { |
103 TIMER_HANDLE i; |
106 TIMER_HANDLE i; |
104 TIMEVAL next_wakeup = TIMEVAL_MAX; // used to compute when should normaly occur next wakeup |
107 TIMEVAL next_wakeup = TIMEVAL_MAX; /* used to compute when should normaly occur next wakeup */ |
105 // First run : change timer state depending on time |
108 /* First run : change timer state depending on time */ |
106 // Get time since timer signal |
109 /* Get time since timer signal */ |
107 TIMEVAL overrun = getElapsedTime(); |
110 TIMEVAL overrun = getElapsedTime(); |
108 |
111 |
109 TIMEVAL real_total_sleep_time = total_sleep_time + overrun; |
112 TIMEVAL real_total_sleep_time = total_sleep_time + overrun; |
110 //printf("total_sleep_time %d + overrun %d\n", total_sleep_time , overrun); |
113 /*printf("total_sleep_time %d + overrun %d\n", total_sleep_time , overrun); */ |
111 |
114 |
112 for(i=0; i <= last_timer_raw; i++) |
115 for(i=0; i <= last_timer_raw; i++) |
113 { |
116 { |
114 s_timer_entry *row = (timers+i); |
117 s_timer_entry *row = (timers+i); |
115 |
118 |
116 if (row->state & TIMER_ARMED) // if row is active |
119 if (row->state & TIMER_ARMED) /* if row is active */ |
117 { |
120 { |
118 if (row->val <= real_total_sleep_time) // to be trigged |
121 if (row->val <= real_total_sleep_time) /* to be trigged */ |
119 { |
122 { |
120 //printf("row->val(%d) <= (%d)real_total_sleep_time\n", row->val, real_total_sleep_time); |
123 /*printf("row->val(%d) <= (%d)real_total_sleep_time\n", row->val, real_total_sleep_time); */ |
121 if (!row->interval) // if simply outdated |
124 if (!row->interval) /* if simply outdated */ |
122 { |
125 { |
123 row->state = TIMER_TRIG; // ask for trig |
126 row->state = TIMER_TRIG; /* ask for trig */ |
124 } |
127 } |
125 else // or period have expired |
128 else /* or period have expired */ |
126 { |
129 { |
127 // set val as interval, with overrun correction |
130 /* set val as interval, with overrun correction */ |
128 row->val = row->interval - (overrun % row->interval); |
131 row->val = row->interval - (overrun % row->interval); |
129 row->state = TIMER_TRIG_PERIOD; // ask for trig, periodic |
132 row->state = TIMER_TRIG_PERIOD; /* ask for trig, periodic */ |
130 // Check if this new timer value is the soonest |
133 /* Check if this new timer value is the soonest */ |
131 next_wakeup = minval(row->val,next_wakeup); |
134 next_wakeup = minval(row->val,next_wakeup); |
132 } |
135 } |
133 } |
136 } |
134 else |
137 else |
135 { |
138 { |
136 // Each armed timer value in decremented. |
139 /* Each armed timer value in decremented. */ |
137 row->val -= real_total_sleep_time; |
140 row->val -= real_total_sleep_time; |
138 |
141 |
139 // Check if this new timer value is the soonest |
142 /* Check if this new timer value is the soonest */ |
140 next_wakeup = minval(row->val,next_wakeup); |
143 next_wakeup = minval(row->val,next_wakeup); |
141 } |
144 } |
142 } |
145 } |
143 } |
146 } |
144 |
147 |
145 // Remember how much time we should sleep. |
148 /* Remember how much time we should sleep. */ |
146 total_sleep_time = next_wakeup; |
149 total_sleep_time = next_wakeup; |
147 |
150 |
148 // Set timer to soonest occurence |
151 /* Set timer to soonest occurence */ |
149 setTimer(next_wakeup); |
152 setTimer(next_wakeup); |
150 |
153 |
151 // Then trig them or not. |
154 /* Then trig them or not. */ |
152 for(i=0; i<=last_timer_raw; i++) |
155 for(i=0; i<=last_timer_raw; i++) |
153 { |
156 { |
154 s_timer_entry *row = (timers+i); |
157 s_timer_entry *row = (timers+i); |
155 |
158 |
156 if (row->state & TIMER_TRIG) |
159 if (row->state & TIMER_TRIG) |
157 { |
160 { |
158 row->state &= ~TIMER_TRIG; // reset trig state (will be free if not periodic) |
161 row->state &= ~TIMER_TRIG; /* reset trig state (will be free if not periodic) */ |
159 (*row->callback)(row->d, row->id); // trig ! |
162 (*row->callback)(row->d, row->id); /* trig ! */ |
160 } |
163 } |
161 } |
164 } |
162 } |
165 } |
163 |
166 |