nico@207: nico@207: nico@207: CanFestival: /home/epimerde/documents/tc11/CanFestival-3/src/timer.c Source File nico@207: nico@207: nico@207: nico@207: nico@207:
nico@207:
nico@207:
nico@207:
nico@207:

/home/epimerde/documents/tc11/CanFestival-3/src/timer.c

Go to the documentation of this file.
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: 

Generated on Tue Jun 5 18:32:05 2007 for CanFestival by  nico@207: nico@207: doxygen 1.5.1
nico@207: nico@207: