nico@207: nico@207:
nico@207:00001 /* nico@207: 00002 This file is part of CanFestival, a library implementing CanOpen Stack. nico@207: 00003 nico@207: 00004 Copyright (C): Edouard TISSERANT and Francis DUPIN nico@207: 00005 nico@207: 00006 See COPYING file for copyrights details. nico@207: 00007 nico@207: 00008 This library is free software; you can redistribute it and/or nico@207: 00009 modify it under the terms of the GNU Lesser General Public nico@207: 00010 License as published by the Free Software Foundation; either nico@207: 00011 version 2.1 of the License, or (at your option) any later version. nico@207: 00012 nico@207: 00013 This library is distributed in the hope that it will be useful, nico@207: 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of nico@207: 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU nico@207: 00016 Lesser General Public License for more details. nico@207: 00017 nico@207: 00018 You should have received a copy of the GNU Lesser General Public nico@207: 00019 License along with this library; if not, write to the Free Software nico@207: 00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA nico@207: 00021 */ nico@210: 00032 /* #define DEBUG_WAR_CONSOLE_ON */ nico@210: 00033 /* #define DEBUG_ERR_CONSOLE_ON */ nico@207: 00034 nico@210: 00035 #include <applicfg.h> nico@210: 00036 #include "timer.h" nico@210: 00037 nico@210: 00038 /* --------- The timer table --------- */ nico@210: 00039 s_timer_entry timers[MAX_NB_TIMER] = {{TIMER_FREE, NULL, NULL, 0, 0, 0},}; nico@210: 00040 nico@210: 00041 TIMEVAL total_sleep_time = TIMEVAL_MAX; nico@210: 00042 TIMER_HANDLE last_timer_raw = -1; nico@207: 00043 nico@210: 00044 #define min_val(a,b) ((a<b)?a:b) nico@210: 00045 nico@210: 00057 TIMER_HANDLE SetAlarm(CO_Data* d, UNS32 id, TimerCallback_t callback, TIMEVAL value, TIMEVAL period) nico@210: 00058 { nico@210: 00059 /*printf("SetAlarm(UNS32 id=%d, TimerCallback_t callback=%x, TIMEVAL value=%d, TIMEVAL period=%d)\n", id, callback, value, period); */ nico@210: 00060 TIMER_HANDLE i; nico@210: 00061 TIMER_HANDLE row_number = TIMER_NONE; nico@210: 00062 nico@210: 00064 for(i=0; i <= last_timer_raw + 1 && i < MAX_NB_TIMER; i++) nico@210: 00065 { nico@210: 00066 s_timer_entry *row = (timers+i); nico@210: 00067 nico@210: 00068 if (callback && nico@210: 00069 row->state == TIMER_FREE) nico@210: 00070 { nico@210: 00071 row->callback = callback; nico@210: 00072 row->d = d; nico@210: 00073 row->id = id; nico@210: 00074 row->val = value; nico@210: 00075 row->interval = period; nico@210: 00076 row->state = TIMER_ARMED; nico@210: 00077 row_number = i; nico@210: 00078 break; nico@207: 00079 } nico@210: 00080 } nico@210: 00081 nico@210: 00082 if (row_number != TIMER_NONE) nico@210: 00083 { nico@210: 00084 TIMEVAL real_timer_value; nico@210: 00085 TIMEVAL elapsed_time; nico@210: 00086 nico@210: 00087 if (row_number == last_timer_raw + 1) last_timer_raw++; nico@210: 00088 nico@210: 00090 real_timer_value = min_val(value, TIMEVAL_MAX); nico@210: 00091 elapsed_time = getElapsedTime(); nico@210: 00092 nico@210: 00094 if (total_sleep_time > elapsed_time && total_sleep_time - elapsed_time > real_timer_value) nico@210: 00095 { nico@210: 00096 total_sleep_time = elapsed_time + real_timer_value; nico@210: 00097 setTimer(real_timer_value); nico@210: 00098 } nico@210: 00100 return row_number; nico@210: 00101 } nico@210: 00102 return TIMER_NONE; nico@210: 00103 } nico@210: 00104 nico@210: 00112 TIMER_HANDLE DelAlarm(TIMER_HANDLE handle) nico@210: 00113 { nico@210: 00115 MSG_WAR(0x3320, "DelAlarm. handle = ", handle); nico@210: 00116 if(handle != TIMER_NONE) nico@210: 00117 { nico@210: 00118 if(handle == last_timer_raw) nico@210: 00119 last_timer_raw--; nico@210: 00120 timers[handle].state = TIMER_FREE; nico@210: 00121 } nico@210: 00122 else { nico@210: 00123 } nico@210: 00124 return TIMER_NONE; nico@210: 00125 } nico@210: 00126 nico@210: 00131 void TimeDispatch() nico@210: 00132 { nico@210: 00133 TIMER_HANDLE i; nico@210: 00134 TIMEVAL next_wakeup = TIMEVAL_MAX; nico@210: 00137 TIMEVAL overrun = getElapsedTime(); nico@210: 00138 nico@210: 00139 TIMEVAL real_total_sleep_time = total_sleep_time + overrun; nico@210: 00140 /*printf("total_sleep_time %d + overrun %d\n", total_sleep_time , overrun); */ nico@207: 00141 nico@210: 00142 for(i=0; i <= last_timer_raw; i++) nico@210: 00143 { nico@210: 00144 s_timer_entry *row = (timers+i); nico@210: 00145 nico@210: 00146 if (row->state & TIMER_ARMED) nico@210: 00147 { nico@210: 00148 if (row->val <= real_total_sleep_time) nico@210: 00149 { nico@210: 00150 /*printf("row->val(%d) <= (%d)real_total_sleep_time\n", row->val, real_total_sleep_time); */ nico@210: 00151 if (!row->interval) nico@210: 00152 { nico@210: 00153 row->state = TIMER_TRIG; nico@210: 00154 } nico@210: 00155 else nico@210: 00156 { nico@210: 00158 row->val = row->interval - (overrun % row->interval); nico@210: 00159 row->state = TIMER_TRIG_PERIOD; /* ask for trig, periodic */ nico@210: 00161 next_wakeup = min_val(row->val,next_wakeup); nico@210: 00162 } nico@210: 00163 } nico@210: 00164 else nico@210: 00165 { nico@210: 00167 row->val -= real_total_sleep_time; nico@210: 00168 nico@210: 00170 next_wakeup = min_val(row->val,next_wakeup); nico@210: 00171 } nico@210: 00172 } nico@210: 00173 } nico@210: 00174 nico@210: 00176 total_sleep_time = next_wakeup; nico@210: 00177 nico@210: 00179 setTimer(next_wakeup); nico@210: 00180 nico@210: 00182 for(i=0; i<=last_timer_raw; i++) nico@210: 00183 { nico@210: 00184 s_timer_entry *row = (timers+i); nico@210: 00185 nico@210: 00186 if (row->state & TIMER_TRIG) nico@210: 00187 { nico@210: 00188 row->state &= ~TIMER_TRIG; nico@210: 00189 if(row->callback) nico@210: 00190 (*row->callback)(row->d, row->id); nico@210: 00191 } nico@210: 00192 } nico@210: 00193 } nico@210: 00194 nico@210: