Can_open_masternode

Dependencies:   mbed

Committer:
sam_grove
Date:
Wed Sep 26 05:48:14 2012 +0000
Revision:
7:537bae5a6fc6
Parent:
0:9dd7c6129683
Pushing the project into the new repo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sam_grove 0:9dd7c6129683 1 /*
sam_grove 0:9dd7c6129683 2 This file is part of CanFestival, a library implementing CanOpen Stack.
sam_grove 0:9dd7c6129683 3
sam_grove 0:9dd7c6129683 4 Copyright (C): Edouard TISSERANT and Francis DUPIN
sam_grove 0:9dd7c6129683 5
sam_grove 0:9dd7c6129683 6 See COPYING file for copyrights details.
sam_grove 0:9dd7c6129683 7
sam_grove 0:9dd7c6129683 8 This library is free software; you can redistribute it and/or
sam_grove 0:9dd7c6129683 9 modify it under the terms of the GNU Lesser General Public
sam_grove 0:9dd7c6129683 10 License as published by the Free Software Foundation; either
sam_grove 0:9dd7c6129683 11 version 2.1 of the License, or (at your option) any later version.
sam_grove 0:9dd7c6129683 12
sam_grove 0:9dd7c6129683 13 This library is distributed in the hope that it will be useful,
sam_grove 0:9dd7c6129683 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
sam_grove 0:9dd7c6129683 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
sam_grove 0:9dd7c6129683 16 Lesser General Public License for more details.
sam_grove 0:9dd7c6129683 17
sam_grove 0:9dd7c6129683 18 You should have received a copy of the GNU Lesser General Public
sam_grove 0:9dd7c6129683 19 License along with this library; if not, write to the Free Software
sam_grove 0:9dd7c6129683 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
sam_grove 0:9dd7c6129683 21 */
sam_grove 0:9dd7c6129683 22 /*!
sam_grove 0:9dd7c6129683 23 ** @file timer.c
sam_grove 0:9dd7c6129683 24 ** @author Edouard TISSERANT and Francis DUPIN
sam_grove 0:9dd7c6129683 25 ** @date Tue Jun 5 09:32:32 2007
sam_grove 0:9dd7c6129683 26 **
sam_grove 0:9dd7c6129683 27 ** @brief
sam_grove 0:9dd7c6129683 28 **
sam_grove 0:9dd7c6129683 29 **
sam_grove 0:9dd7c6129683 30 */
sam_grove 0:9dd7c6129683 31
sam_grove 0:9dd7c6129683 32 /* #define DEBUG_WAR_CONSOLE_ON */
sam_grove 0:9dd7c6129683 33 /* #define DEBUG_ERR_CONSOLE_ON */
sam_grove 0:9dd7c6129683 34
sam_grove 0:9dd7c6129683 35 #include <applicfg.h>
sam_grove 0:9dd7c6129683 36 #include "canopen_timer.h"
sam_grove 0:9dd7c6129683 37
sam_grove 0:9dd7c6129683 38 /* --------- The timer table --------- */
sam_grove 0:9dd7c6129683 39 s_timer_entry timers[MAX_NB_TIMER] = {{TIMER_FREE, NULL, NULL, 0, 0, 0},};
sam_grove 0:9dd7c6129683 40
sam_grove 0:9dd7c6129683 41 TIMEVAL total_sleep_time = TIMEVAL_MAX;
sam_grove 0:9dd7c6129683 42 TIMER_HANDLE last_timer_raw = -1;
sam_grove 0:9dd7c6129683 43
sam_grove 0:9dd7c6129683 44 #define min_val(a,b) ((a<b)?a:b)
sam_grove 0:9dd7c6129683 45
sam_grove 0:9dd7c6129683 46 /*!
sam_grove 0:9dd7c6129683 47 ** ------- Use this to declare a new alarm ------
sam_grove 0:9dd7c6129683 48 **
sam_grove 0:9dd7c6129683 49 ** @param d
sam_grove 0:9dd7c6129683 50 ** @param id
sam_grove 0:9dd7c6129683 51 ** @param callback
sam_grove 0:9dd7c6129683 52 ** @param value
sam_grove 0:9dd7c6129683 53 ** @param period
sam_grove 0:9dd7c6129683 54 **
sam_grove 0:9dd7c6129683 55 ** @return
sam_grove 0:9dd7c6129683 56 **/
sam_grove 0:9dd7c6129683 57 TIMER_HANDLE SetAlarm(CO_Data* d, UNS32 id, TimerCallback_t callback, TIMEVAL value, TIMEVAL period)
sam_grove 0:9dd7c6129683 58 {
sam_grove 0:9dd7c6129683 59 TIMER_HANDLE row_number;
sam_grove 0:9dd7c6129683 60 s_timer_entry *row;
sam_grove 0:9dd7c6129683 61
sam_grove 0:9dd7c6129683 62 /* in order to decide new timer setting we have to run over all timer rows */
sam_grove 0:9dd7c6129683 63 for(row_number=0, row=timers; row_number <= last_timer_raw + 1 && row_number < MAX_NB_TIMER; row_number++, row++)
sam_grove 0:9dd7c6129683 64 {
sam_grove 0:9dd7c6129683 65 if (callback && /* if something to store */
sam_grove 0:9dd7c6129683 66 row->state == TIMER_FREE) /* and empty row */
sam_grove 0:9dd7c6129683 67 { /* just store */
sam_grove 0:9dd7c6129683 68 TIMEVAL real_timer_value;
sam_grove 0:9dd7c6129683 69 TIMEVAL elapsed_time;
sam_grove 0:9dd7c6129683 70
sam_grove 0:9dd7c6129683 71 if (row_number == last_timer_raw + 1) last_timer_raw++;
sam_grove 0:9dd7c6129683 72
sam_grove 0:9dd7c6129683 73 elapsed_time = getElapsedTime();
sam_grove 0:9dd7c6129683 74 /* set next wakeup alarm if new entry is sooner than others, or if it is alone */
sam_grove 0:9dd7c6129683 75 real_timer_value = value;
sam_grove 0:9dd7c6129683 76 real_timer_value = min_val(real_timer_value, TIMEVAL_MAX);
sam_grove 0:9dd7c6129683 77
sam_grove 0:9dd7c6129683 78 if (total_sleep_time > elapsed_time && total_sleep_time - elapsed_time > real_timer_value)
sam_grove 0:9dd7c6129683 79 {
sam_grove 0:9dd7c6129683 80 total_sleep_time = elapsed_time + real_timer_value;
sam_grove 0:9dd7c6129683 81 setTimer(real_timer_value);
sam_grove 0:9dd7c6129683 82 }
sam_grove 0:9dd7c6129683 83 row->callback = callback;
sam_grove 0:9dd7c6129683 84 row->d = d;
sam_grove 0:9dd7c6129683 85 row->id = id;
sam_grove 0:9dd7c6129683 86 row->val = value + elapsed_time;
sam_grove 0:9dd7c6129683 87 row->interval = period;
sam_grove 0:9dd7c6129683 88 row->state = TIMER_ARMED;
sam_grove 0:9dd7c6129683 89 return row_number;
sam_grove 0:9dd7c6129683 90 }
sam_grove 0:9dd7c6129683 91 }
sam_grove 0:9dd7c6129683 92
sam_grove 0:9dd7c6129683 93 return TIMER_NONE;
sam_grove 0:9dd7c6129683 94 }
sam_grove 0:9dd7c6129683 95
sam_grove 0:9dd7c6129683 96 /*!
sam_grove 0:9dd7c6129683 97 ** ----- Use this to remove an alarm ----
sam_grove 0:9dd7c6129683 98 **
sam_grove 0:9dd7c6129683 99 ** @param handle
sam_grove 0:9dd7c6129683 100 **
sam_grove 0:9dd7c6129683 101 ** @return
sam_grove 0:9dd7c6129683 102 **/
sam_grove 0:9dd7c6129683 103 TIMER_HANDLE DelAlarm(TIMER_HANDLE handle)
sam_grove 0:9dd7c6129683 104 {
sam_grove 0:9dd7c6129683 105 /* Quick and dirty. system timer will continue to be trigged, but no action will be preformed. */
sam_grove 0:9dd7c6129683 106 MSG_WAR(0x3320, "DelAlarm. handle = ", handle);
sam_grove 0:9dd7c6129683 107 if(handle != TIMER_NONE)
sam_grove 0:9dd7c6129683 108 {
sam_grove 0:9dd7c6129683 109 if(handle == last_timer_raw)
sam_grove 0:9dd7c6129683 110 last_timer_raw--;
sam_grove 0:9dd7c6129683 111 timers[handle].state = TIMER_FREE;
sam_grove 0:9dd7c6129683 112 }
sam_grove 0:9dd7c6129683 113 return TIMER_NONE;
sam_grove 0:9dd7c6129683 114 }
sam_grove 0:9dd7c6129683 115
sam_grove 0:9dd7c6129683 116 /*!
sam_grove 0:9dd7c6129683 117 ** ------ TimeDispatch is called on each timer expiration ----
sam_grove 0:9dd7c6129683 118 **
sam_grove 0:9dd7c6129683 119 **/
sam_grove 0:9dd7c6129683 120 int tdcount=0;
sam_grove 0:9dd7c6129683 121 void TimeDispatch(void)
sam_grove 0:9dd7c6129683 122 {
sam_grove 0:9dd7c6129683 123 TIMER_HANDLE i;
sam_grove 0:9dd7c6129683 124 TIMEVAL next_wakeup = TIMEVAL_MAX; /* used to compute when should normaly occur next wakeup */
sam_grove 0:9dd7c6129683 125 /* First run : change timer state depending on time */
sam_grove 0:9dd7c6129683 126 /* Get time since timer signal */
sam_grove 0:9dd7c6129683 127 UNS32 overrun = (UNS32)getElapsedTime();
sam_grove 0:9dd7c6129683 128
sam_grove 0:9dd7c6129683 129 TIMEVAL real_total_sleep_time = total_sleep_time + overrun;
sam_grove 0:9dd7c6129683 130
sam_grove 0:9dd7c6129683 131 s_timer_entry *row;
sam_grove 0:9dd7c6129683 132
sam_grove 0:9dd7c6129683 133 for(i=0, row = timers; i <= last_timer_raw; i++, row++)
sam_grove 0:9dd7c6129683 134 {
sam_grove 0:9dd7c6129683 135 if (row->state & TIMER_ARMED) /* if row is active */
sam_grove 0:9dd7c6129683 136 {
sam_grove 0:9dd7c6129683 137 if (row->val <= real_total_sleep_time) /* to be trigged */
sam_grove 0:9dd7c6129683 138 {
sam_grove 0:9dd7c6129683 139 if (!row->interval) /* if simply outdated */
sam_grove 0:9dd7c6129683 140 {
sam_grove 0:9dd7c6129683 141 row->state = TIMER_TRIG; /* ask for trig */
sam_grove 0:9dd7c6129683 142 }
sam_grove 0:9dd7c6129683 143 else /* or period have expired */
sam_grove 0:9dd7c6129683 144 {
sam_grove 0:9dd7c6129683 145 /* set val as interval, with 32 bit overrun correction, */
sam_grove 0:9dd7c6129683 146 /* modulo for 64 bit not available on all platforms */
sam_grove 0:9dd7c6129683 147 row->val = row->interval - (overrun % (UNS32)row->interval);
sam_grove 0:9dd7c6129683 148 row->state = TIMER_TRIG_PERIOD; /* ask for trig, periodic */
sam_grove 0:9dd7c6129683 149 /* Check if this new timer value is the soonest */
sam_grove 0:9dd7c6129683 150 if(row->val < next_wakeup)
sam_grove 0:9dd7c6129683 151 next_wakeup = row->val;
sam_grove 0:9dd7c6129683 152 }
sam_grove 0:9dd7c6129683 153 }
sam_grove 0:9dd7c6129683 154 else
sam_grove 0:9dd7c6129683 155 {
sam_grove 0:9dd7c6129683 156 /* Each armed timer value in decremented. */
sam_grove 0:9dd7c6129683 157 row->val -= real_total_sleep_time;
sam_grove 0:9dd7c6129683 158
sam_grove 0:9dd7c6129683 159 /* Check if this new timer value is the soonest */
sam_grove 0:9dd7c6129683 160 if(row->val < next_wakeup)
sam_grove 0:9dd7c6129683 161 next_wakeup = row->val;
sam_grove 0:9dd7c6129683 162 }
sam_grove 0:9dd7c6129683 163 }
sam_grove 0:9dd7c6129683 164 }
sam_grove 0:9dd7c6129683 165
sam_grove 0:9dd7c6129683 166 /* Remember how much time we should sleep. */
sam_grove 0:9dd7c6129683 167 total_sleep_time = next_wakeup;
sam_grove 0:9dd7c6129683 168
sam_grove 0:9dd7c6129683 169 /* Set timer to soonest occurence */
sam_grove 0:9dd7c6129683 170 setTimer(next_wakeup);
sam_grove 0:9dd7c6129683 171
sam_grove 0:9dd7c6129683 172 /* Then trig them or not. */
sam_grove 0:9dd7c6129683 173 for(i=0, row = timers; i<=last_timer_raw; i++, row++)
sam_grove 0:9dd7c6129683 174 {
sam_grove 0:9dd7c6129683 175 if (row->state & TIMER_TRIG)
sam_grove 0:9dd7c6129683 176 {
sam_grove 0:9dd7c6129683 177 row->state &= ~TIMER_TRIG; /* reset trig state (will be free if not periodic) */
sam_grove 0:9dd7c6129683 178 if(row->callback)
sam_grove 0:9dd7c6129683 179 (*row->callback)(row->d, row->id); /* trig ! */
sam_grove 0:9dd7c6129683 180 }
sam_grove 0:9dd7c6129683 181 }
sam_grove 0:9dd7c6129683 182 }