]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - src/lifegrd.c
First doxygen implementation
[CanFestival-3.git] / src / lifegrd.c
1 /*
2   This file is part of CanFestival, a library implementing CanOpen
3   Stack.
4
5   Copyright (C): Edouard TISSERANT and Francis DUPIN
6
7   See COPYING file for copyrights details.
8
9   This library is free software; you can redistribute it and/or
10   modify it under the terms of the GNU Lesser General Public
11   License as published by the Free Software Foundation; either
12   version 2.1 of the License, or (at your option) any later version.
13
14   This library is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   Lesser General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public
20   License along with this library; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
22   USA
23 */
24
25 /*!
26 ** @file   filegrd.c
27 ** @author Edouard TISSERANT
28 ** @date   Mon Jun  4 17:19:24 2007
29 **
30 ** @brief
31 **
32 **
33 */
34
35 #include <data.h>
36 #include "lifegrd.h"
37 #include "canfestival.h"
38
39 /*! Prototypes for internals functions
40 **
41 **
42 ** @param d
43 ** @param id
44 **/
45 void ConsumerHearbeatAlarm(CO_Data* d, UNS32 id);
46
47 /*!
48 **
49 **
50 ** @param d
51 ** @param id
52 **/
53 void ProducerHearbeatAlarm(CO_Data* d, UNS32 id);
54
55 /*!
56 **
57 **
58 ** @param d
59 ** @param unsused_indextable
60 ** @param unsused_bSubindex
61 **
62 ** @return
63 **/
64 UNS32 OnHearbeatProducerUpdate(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex);
65
66 /*!
67 **
68 **
69 ** @param d
70 ** @param nodeId
71 **
72 ** @return
73 **/
74 e_nodeState getNodeState (CO_Data* d, UNS8 nodeId)
75 {
76   e_nodeState networkNodeState = d->NMTable[nodeId];
77   return networkNodeState;
78 }
79
80 /*! The Consumer Timer Callback
81 **
82 **
83 ** @param d
84 ** @param id
85 **/
86 void ConsumerHearbeatAlarm(CO_Data* d, UNS32 id)
87 {
88   /*MSG_WAR(0x00, "ConsumerHearbeatAlarm", 0x00);*/
89
90   /*! call heartbeat error with NodeId */
91   (*d->heartbeatError)((UNS8)( ((d->ConsumerHeartbeatEntries[id]) & (UNS32)0x00FF0000) >> (UNS8)16 ));
92 }
93
94 /*!
95 **
96 **
97 ** @param d
98 ** @param m
99 **/
100 void proceedNODE_GUARD(CO_Data* d, Message* m )
101 {
102   UNS8 nodeId = (UNS8) GET_NODE_ID((*m));
103
104   if((m->rtr == 1) )
105     /*!
106     ** Notice that only the master can have sent this
107     ** node guarding request
108     */
109     {
110       /*!
111       ** Receiving a NMT NodeGuarding (request of the state by the
112       ** master)
113       ** Only answer to the NMT NodeGuarding request, the master is
114       ** not checked (not implemented)
115       */
116       if (nodeId == *d->bDeviceNodeId )
117         {
118           Message msg;
119           msg.cob_id.w = *d->bDeviceNodeId + 0x700;
120           msg.len = (UNS8)0x01;
121           msg.rtr = 0;
122           msg.data[0] = d->nodeState;
123           if (d->toggle)
124             {
125               msg.data[0] |= 0x80 ;
126               d->toggle = 0 ;
127             }
128           else
129             d->toggle = 1 ;
130           /*! send the nodeguard response. */
131           MSG_WAR(0x3130, "Sending NMT Nodeguard to master, state: ", d->nodeState);
132           canSend(d->canHandle,&msg );
133         }
134
135     }else{ /*! Not a request CAN */
136
137       MSG_WAR(0x3110, "Received NMT nodeId : ", nodeId);
138       /*! the slave's state receievd is stored in the NMTable */
139       /*! The state is stored on 7 bit */
140       d->NMTable[nodeId] = (e_nodeState) ((*m).data[0] & 0x7F) ;
141
142       /*! Boot-Up frame reception */
143       if ( d->NMTable[nodeId] == Initialisation)
144         {
145           /*!
146           ** The device send the boot-up message (Initialisation)
147           ** to indicate the master that it is entered in
148           ** pre_operational mode
149           ** Because the  device enter automaticaly in pre_operational
150           ** mode,
151           ** the pre_operational mode is stored
152           ** NMTable[bus_id][nodeId] = Pre_operational
153           */
154           MSG_WAR(0x3100, "The NMT is a bootup from node : ", nodeId);
155         }
156
157       if( d->NMTable[nodeId] != Unknown_state ) {
158         UNS8 index, ConsummerHeartBeat_nodeId ;
159         for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
160           {
161             ConsummerHeartBeat_nodeId = (UNS8)( ((d->ConsumerHeartbeatEntries[index]) & (UNS32)0x00FF0000) >> (UNS8)16 );
162             if ( nodeId == ConsummerHeartBeat_nodeId )
163               {
164                 TIMEVAL time = ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ;
165                 /* Renew alarm for next heartbeat. */
166                 DelAlarm(d->ConsumerHeartBeatTimers[index]);
167                 d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm, MS_TO_TIMEVAL(time), 0);
168               }
169           }
170       }
171     }
172 }
173
174 /*! The Consumer Timer Callback
175 **
176 **
177 ** @param d
178 ** @param id
179 **/
180 void ProducerHearbeatAlarm(CO_Data* d, UNS32 id)
181 {
182   if(*d->ProducerHeartBeatTime)
183     {
184       Message msg;
185       /*! Time expired, the heartbeat must be sent immediately
186       ** generate the correct node-id: this is done by the offset 1792
187       ** (decimal) and additionaly
188       ** the node-id of this device.
189       */
190
191       msg.cob_id.w = *d->bDeviceNodeId + 0x700;
192       msg.len = (UNS8)0x01;
193       msg.rtr = 0;
194       msg.data[0] = d->nodeState; /*! No toggle for heartbeat !*/
195       /*! send the heartbeat */
196       MSG_WAR(0x3130, "Producing heartbeat: ", d->nodeState);
197       canSend(d->canHandle,&msg );
198
199     }else{
200       d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);
201     }
202 }
203
204 /*! This is called when Index 0x1017 is updated.
205 **
206 **
207 ** @param d
208 ** @param unsused_indextable
209 ** @param unsused_bSubindex
210 **
211 ** @return
212 **/
213 UNS32 OnHeartbeatProducerUpdate(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex)
214 {
215   heartbeatStop(d);
216   heartbeatInit(d);
217   return 0;
218 }
219
220 /*!
221 **
222 **
223 ** @param d
224 **/
225 void heartbeatInit(CO_Data* d)
226 {
227
228   UNS8 index; /*! Index to scan the table of heartbeat consumers */
229   RegisterSetODentryCallBack(d, 0x1017, 0x00, &OnHeartbeatProducerUpdate);
230
231   d->toggle = 0;
232
233   for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
234     {
235       TIMEVAL time = (UNS16) ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ;
236       /*! MSG_WAR(0x3121, "should_time : ", should_time ) ; */
237       if ( time )
238         {
239           d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm, MS_TO_TIMEVAL(time), 0);
240         }
241     }
242
243   if ( *d->ProducerHeartBeatTime )
244     {
245       TIMEVAL time = *d->ProducerHeartBeatTime;
246       d->ProducerHeartBeatTimer = SetAlarm(d, 0, &ProducerHearbeatAlarm, MS_TO_TIMEVAL(time), MS_TO_TIMEVAL(time));
247     }
248 }
249
250 /*!
251 **
252 **
253 ** @param d
254 **/
255 void heartbeatStop(CO_Data* d)
256 {
257   UNS8 index;
258   for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
259     {
260       d->ConsumerHeartBeatTimers[index + 1] = DelAlarm(d->ConsumerHeartBeatTimers[index + 1]);;
261     }
262
263   d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);;
264 }
265
266 /*!
267 **
268 **
269 ** @param heartbeatID
270 **/
271 void _heartbeatError(UNS8 heartbeatID){}