Can_open_slavenode

Dependencies:   mbed

Committer:
sam_grove
Date:
Mon May 30 07:14:41 2011 +0000
Revision:
0:6219434a0cb5
Initial public release of slave node framework port

Who changed what in which revision?

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