Can_open_masternode

Dependencies:   mbed

Committer:
sam_grove
Date:
Mon May 30 07:36:47 2011 +0000
Revision:
0:9dd7c6129683
Initial public release of master node example

Who changed what in which revision?

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