Can_open_slavenode

Dependencies:   mbed

Committer:
sam_grove
Date:
Mon May 30 07:14:41 2011 +0000
Revision:
0:6219434a0cb5
Initial public release of slave node framework port

Who changed what in which revision?

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