Sam Grove / Mbed 2 deprecated canopen_slavenode

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