Sam Grove / Mbed 2 deprecated canopen_masternode

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lifegrd.c Source File

lifegrd.c

Go to the documentation of this file.
00001 /*
00002   This file is part of CanFestival, a library implementing CanOpen
00003   Stack.
00004 
00005   Copyright (C): Edouard TISSERANT and Francis DUPIN
00006 
00007   See COPYING file for copyrights details.
00008 
00009   This library is free software; you can redistribute it and/or
00010   modify it under the terms of the GNU Lesser General Public
00011   License as published by the Free Software Foundation; either
00012   version 2.1 of the License, or (at your option) any later version.
00013 
00014   This library is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017   Lesser General Public License for more details.
00018 
00019   You should have received a copy of the GNU Lesser General Public
00020   License along with this library; if not, write to the Free Software
00021   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00022   USA
00023 */
00024 
00025 /*!
00026 ** @file   lifegrd.c
00027 ** @author Edouard TISSERANT
00028 ** @date   Mon Jun  4 17:19:24 2007
00029 **
00030 ** @brief
00031 **
00032 **
00033 */
00034 
00035 #include <data.h>
00036 #include "lifegrd.h"
00037 #include "canfestival.h"
00038 #include "dcf.h"
00039 #include "sysdep.h"
00040 
00041 
00042 void ConsumerHearbeatAlarm (CO_Data* d, UNS32 id);
00043 
00044 
00045 void ProducerHearbeatAlarm (CO_Data* d, UNS32 id);
00046 
00047 UNS32 OnHearbeatProducerUpdate(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex);
00048 
00049 /*!
00050 **
00051 **
00052 ** @param d
00053 ** @param nodeId
00054 **
00055 ** @return
00056 **/
00057 e_nodeState getNodeState (CO_Data* d, UNS8 nodeId)
00058 {
00059   e_nodeState networkNodeState = d->NMTable[nodeId];
00060   return networkNodeState;
00061 }
00062 
00063 /*! 
00064 ** The Consumer Timer Callback
00065 **
00066 ** @param d
00067 ** @param id
00068 **/
00069 void ConsumerHearbeatAlarm (CO_Data* d, UNS32 id)
00070 {
00071   UNS8 nodeId = (UNS8)(((d->ConsumerHeartbeatEntries[id]) & (UNS32)0x00FF0000) >> (UNS8)16);
00072   /*MSG_WAR(0x00, "ConsumerHearbeatAlarm", 0x00);*/
00073 
00074   /* timer have been notified and is now free (non periodic)*/
00075   /* -> avoid deleting re-assigned timer if message is received too late*/
00076   d->ConsumerHeartBeatTimers[id]=TIMER_NONE;
00077   
00078   /* set node state */
00079   d->NMTable[nodeId] = Disconnected;
00080   /*! call heartbeat error with NodeId */
00081   (*d->heartbeatError)(d, nodeId);
00082 }
00083 
00084 /*!
00085 **
00086 **
00087 ** @param d
00088 ** @param m
00089 **/
00090 void proceedNODE_GUARD(CO_Data* d, Message* m )
00091 {
00092   UNS8 nodeId = (UNS8) GET_NODE_ID((*m));
00093 
00094   if((m->rtr == 1) )
00095     /*!
00096     ** Notice that only the master can have sent this
00097     ** node guarding request
00098     */
00099     {
00100       /*!
00101       ** Receiving a NMT NodeGuarding (request of the state by the
00102       ** master)
00103       ** Only answer to the NMT NodeGuarding request, the master is
00104       ** not checked (not implemented)
00105       */
00106       if (nodeId == *d->bDeviceNodeId )
00107         {
00108           Message msg;
00109           UNS16 tmp = *d->bDeviceNodeId + 0x700;
00110           msg.cob_id = UNS16_LE(tmp);
00111           msg.len = (UNS8)0x01;
00112           msg.rtr = 0;
00113           msg.data[0] = d->nodeState;
00114           if (d->toggle)
00115             {
00116               msg.data[0] |= 0x80 ;
00117               d->toggle = 0 ;
00118             }
00119           else
00120             d->toggle = 1 ;
00121           /* send the nodeguard response. */
00122           MSG_WAR(0x3130, "Sending NMT Nodeguard to master, state: ", d->nodeState);
00123           canSend(d->canHandle,&msg );
00124         }
00125 
00126     }else{ /* Not a request CAN */
00127       /* The state is stored on 7 bit */
00128       e_nodeState newNodeState = (e_nodeState) ((*m).data[0] & 0x7F);
00129 
00130       MSG_WAR(0x3110, "Received NMT nodeId : ", nodeId);
00131       
00132       if (d->NMTable[nodeId] != newNodeState)
00133       {
00134         (*d->post_SlaveStateChange)(d, nodeId, newNodeState);
00135         /* the slave's state receievd is stored in the NMTable */
00136         d->NMTable[nodeId] = newNodeState;
00137       }
00138 
00139       /* Boot-Up frame reception */
00140       if ( d->NMTable[nodeId] == Initialisation)
00141         {
00142           /*
00143           ** The device send the boot-up message (Initialisation)
00144           ** to indicate the master that it is entered in
00145           ** pre_operational mode
00146           ** Because the  device enter automaticaly in pre_operational
00147           ** mode,
00148           ** the pre_operational mode is stored
00149           ** NMTable[bus_id][nodeId] = Pre_operational
00150           */
00151           MSG_WAR(0x3100, "The NMT is a bootup from node : ", nodeId);
00152           
00153           if(!send_consise_dcf(d,nodeId)){
00154              /* call post SlaveBootup with NodeId */
00155               (*d->post_SlaveBootup)(d, nodeId);
00156           }
00157         }
00158 
00159       if( d->NMTable[nodeId] != Unknown_state ) {
00160         UNS8 index, ConsummerHeartBeat_nodeId ;
00161         for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
00162           {
00163             ConsummerHeartBeat_nodeId = (UNS8)( ((d->ConsumerHeartbeatEntries[index]) & (UNS32)0x00FF0000) >> (UNS8)16 );
00164             if ( nodeId == ConsummerHeartBeat_nodeId )
00165               {
00166                 TIMEVAL time = ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ;
00167                 /* Renew alarm for next heartbeat. */
00168                 DelAlarm(d->ConsumerHeartBeatTimers[index]);
00169                 d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm , MS_TO_TIMEVAL(time), 0);
00170               }
00171           }
00172       }
00173     }
00174 }
00175 
00176 /*! The Consumer Timer Callback
00177 **
00178 **
00179 ** @param d
00180 ** @param id
00181 **/
00182 void ProducerHearbeatAlarm (CO_Data* d, UNS32 id)
00183 {
00184   if(*d->ProducerHeartBeatTime)
00185     {
00186       Message msg;
00187       /* Time expired, the heartbeat must be sent immediately
00188       ** generate the correct node-id: this is done by the offset 1792
00189       ** (decimal) and additionaly
00190       ** the node-id of this device.
00191       */
00192       UNS16 tmp = *d->bDeviceNodeId + 0x700;
00193       msg.cob_id = UNS16_LE(tmp);
00194       msg.len = (UNS8)0x01;
00195       msg.rtr = 0;
00196       msg.data[0] = d->nodeState; /* No toggle for heartbeat !*/
00197       /* send the heartbeat */
00198       MSG_WAR(0x3130, "Producing heartbeat: ", d->nodeState);
00199       canSend(d->canHandle,&msg );
00200 
00201     }else{
00202       d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);
00203     }
00204 }
00205 
00206 /*! This is called when Index 0x1017 is updated.
00207 **
00208 **
00209 ** @param d
00210 ** @param unsused_indextable
00211 ** @param unsused_bSubindex
00212 **
00213 ** @return
00214 **/
00215 UNS32 OnHeartbeatProducerUpdate (CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex)
00216 {
00217   heartbeatStop(d);
00218   heartbeatInit(d);
00219   return 0;
00220 }
00221 
00222 /*!
00223 **
00224 **
00225 ** @param d
00226 **/
00227 void heartbeatInit(CO_Data* d)
00228 {
00229 
00230   UNS8 index; /* Index to scan the table of heartbeat consumers */
00231   RegisterSetODentryCallBack(d, 0x1017, 0x00, &OnHeartbeatProducerUpdate );
00232 
00233   d->toggle = 0;
00234 
00235   for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
00236     {
00237       TIMEVAL time = (UNS16) ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ;
00238       /* MSG_WAR(0x3121, "should_time : ", should_time ) ; */
00239       if ( time )
00240         {
00241           d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm , MS_TO_TIMEVAL(time), 0);
00242         }
00243     }
00244 
00245   if ( *d->ProducerHeartBeatTime )
00246     {
00247       TIMEVAL time = *d->ProducerHeartBeatTime;
00248       d->ProducerHeartBeatTimer = SetAlarm(d, 0, &ProducerHearbeatAlarm , MS_TO_TIMEVAL(time), MS_TO_TIMEVAL(time));
00249     }
00250 }
00251 
00252 /*!
00253 **
00254 **
00255 ** @param d
00256 **/
00257 void heartbeatStop(CO_Data* d)
00258 {
00259   UNS8 index;
00260   for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
00261     {
00262       d->ConsumerHeartBeatTimers[index] = DelAlarm(d->ConsumerHeartBeatTimers[index]);
00263     }
00264 
00265   d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);
00266 }
00267 
00268 /*!
00269 **
00270 **
00271 ** @param heartbeatID
00272 **/
00273 void _heartbeatError (CO_Data* d, UNS8 heartbeatID){}
00274 void _post_SlaveBootup(CO_Data* d, UNS8 SlaveID){}
00275 void _post_SlaveStateChange(CO_Data* d, UNS8 nodeId, e_nodeState newNodeState){}
00276