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