/home/epimerde/documents/tc11/CanFestival-3/src/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  USA
00021 */
00022 
00023 #include <data.h>
00024 #include "lifegrd.h"
00025 #include "canfestival.h"
00026 
00027 /* Prototypes for internals functions */
00028 void ConsumerHearbeatAlarm(CO_Data* d, UNS32 id);
00029 void ProducerHearbeatAlarm(CO_Data* d, UNS32 id);
00030 UNS32 OnHearbeatProducerUpdate(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex);
00031 
00032 /*****************************************************************************/
00033 e_nodeState getNodeState (CO_Data* d, UNS8 nodeId)
00034 {
00035         e_nodeState networkNodeState = d->NMTable[nodeId];
00036         return networkNodeState;
00037 }
00038 
00039 /*****************************************************************************/
00040 /* The Consumer Timer Callback */
00041 void ConsumerHearbeatAlarm(CO_Data* d, UNS32 id)
00042 {
00043         /*MSG_WAR(0x00, "ConsumerHearbeatAlarm", 0x00);*/
00044         
00045         /* call heartbeat error with NodeId */
00046         (*d->heartbeatError)((UNS8)( ((d->ConsumerHeartbeatEntries[id]) & (UNS32)0x00FF0000) >> (UNS8)16 ));
00047 }
00048 
00049 /*****************************************************************************/
00050 void proceedNODE_GUARD(CO_Data* d, Message* m )
00051 {
00052   UNS8 nodeId = (UNS8) GET_NODE_ID((*m));
00053   
00054   if((m->rtr == 1) ) /* Notice that only the master can have sent this node guarding request */
00055   { /* Receiving a NMT NodeGuarding (request of the state by the master) */
00056     /*  only answer to the NMT NodeGuarding request, the master is not checked (not implemented) */
00057     if (nodeId == *d->bDeviceNodeId )
00058     {
00059       Message msg;
00060       msg.cob_id.w = *d->bDeviceNodeId + 0x700;
00061       msg.len = (UNS8)0x01;
00062       msg.rtr = 0;
00063       msg.data[0] = d->nodeState; 
00064       if (d->toggle)
00065       {
00066         msg.data[0] |= 0x80 ;
00067         d->toggle = 0 ;
00068       }
00069       else
00070         d->toggle = 1 ; 
00071       /* send the nodeguard response. */
00072       MSG_WAR(0x3130, "Sending NMT Nodeguard to master, state: ", d->nodeState);
00073       canSend(d->canHandle,&msg );
00074     }  
00075 
00076   }else{ /* Not a request CAN */
00077 
00078     MSG_WAR(0x3110, "Received NMT nodeId : ", nodeId);
00079     /* the slave's state receievd is stored in the NMTable */
00080       /* The state is stored on 7 bit */
00081     d->NMTable[nodeId] = (e_nodeState) ((*m).data[0] & 0x7F) ;
00082     
00083     /* Boot-Up frame reception */
00084     if ( d->NMTable[nodeId] == Initialisation)
00085       {
00086         /* The device send the boot-up message (Initialisation) */
00087         /* to indicate the master that it is entered in pre_operational mode */
00088         /* Because the  device enter automaticaly in pre_operational mode, */
00089         /* the pre_operational mode is stored */
00090 /*        NMTable[bus_id][nodeId] = Pre_operational; */
00091         MSG_WAR(0x3100, "The NMT is a bootup from node : ", nodeId);
00092       }
00093       
00094     if( d->NMTable[nodeId] != Unknown_state ) {
00095         UNS8 index, ConsummerHeartBeat_nodeId ;
00096         for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
00097         {
00098             ConsummerHeartBeat_nodeId = (UNS8)( ((d->ConsumerHeartbeatEntries[index]) & (UNS32)0x00FF0000) >> (UNS8)16 );
00099             if ( nodeId == ConsummerHeartBeat_nodeId )
00100             {
00101                 TIMEVAL time = ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ;
00102                 /* Renew alarm for next heartbeat. */
00103                 DelAlarm(d->ConsumerHeartBeatTimers[index]);
00104                 d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm, MS_TO_TIMEVAL(time), 0);
00105             }
00106         }
00107     }
00108   }
00109 }
00110 
00111 /*****************************************************************************/
00112 /* The Consumer Timer Callback */
00113 void ProducerHearbeatAlarm(CO_Data* d, UNS32 id)
00114 {
00115         if(*d->ProducerHeartBeatTime)
00116         {
00117                 Message msg;
00118                 /* Time expired, the heartbeat must be sent immediately
00119                  * generate the correct node-id: this is done by the offset 1792
00120                  * (decimal) and additionaly
00121                  * the node-id of this device.
00122                  */
00123                 
00124                 msg.cob_id.w = *d->bDeviceNodeId + 0x700;
00125                 msg.len = (UNS8)0x01;
00126                 msg.rtr = 0;
00127                 msg.data[0] = d->nodeState; /* No toggle for heartbeat !*/
00128                 /* send the heartbeat */
00129                 MSG_WAR(0x3130, "Producing heartbeat: ", d->nodeState);
00130                 canSend(d->canHandle,&msg );
00131         
00132         }else{
00133                 d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);
00134         }
00135 }
00136 
00137 /*****************************************************************************/
00138 /* This is called when Index 0x1017 is updated.*/
00139 UNS32 OnHeartbeatProducerUpdate(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex)
00140 {
00141         heartbeatStop(d);
00142         heartbeatInit(d);
00143         return 0;
00144 }
00145 /*****************************************************************************/
00146 
00147 void heartbeatInit(CO_Data* d)
00148 {
00149                 
00150     UNS8 index; /* Index to scan the table of heartbeat consumers */
00151         RegisterSetODentryCallBack(d, 0x1017, 0x00, &OnHeartbeatProducerUpdate);
00152     
00153     d->toggle = 0;
00154         
00155     for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
00156     {
00157         TIMEVAL time = (UNS16) ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ;
00158         /* MSG_WAR(0x3121, "should_time : ", should_time ) ; */
00159         if ( time )
00160         {
00161                 d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm, MS_TO_TIMEVAL(time), 0);
00162         }
00163     }
00164 
00165     if ( *d->ProducerHeartBeatTime )
00166     {
00167         TIMEVAL time = *d->ProducerHeartBeatTime;
00168         d->ProducerHeartBeatTimer = SetAlarm(d, 0, &ProducerHearbeatAlarm, MS_TO_TIMEVAL(time), MS_TO_TIMEVAL(time));
00169     }
00170 }
00171 
00172 /*****************************************************************************/
00173 void heartbeatStop(CO_Data* d)
00174 {
00175     UNS8 index;
00176     for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
00177     {
00178         d->ConsumerHeartBeatTimers[index + 1] = DelAlarm(d->ConsumerHeartBeatTimers[index + 1]);;
00179     }
00180 
00181     d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);;
00182 }
00183 
00184 void _heartbeatError(UNS8 heartbeatID){}

Generated on Mon Jun 4 17:09:26 2007 for CanFestival by  doxygen 1.5.1