2 This file is part of CanFestival, a library implementing CanOpen Stack.
4 Copyright (C): Edouard TISSERANT and Francis DUPIN
6 See COPYING file for copyrights details.
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 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,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 ** @author Edouard TISSERANT and Francis DUPIN
25 ** @date Tue Jun 5 09:32:32 2007
37 /** Prototypes for internals functions */
42 ** @param newCommunicationState
44 void switchCommunicationState(CO_Data* d,
45 s_state_communication *newCommunicationState);
54 e_nodeState getState(CO_Data* d)
65 void canDispatch(CO_Data* d, Message *m)
67 switch(m->cob_id.w >> 7)
70 if(d->CurrentCommunicationState.csSYNC)
73 /** case TIME_STAMP: */
82 if (d->CurrentCommunicationState.csPDO)
87 if (d->CurrentCommunicationState.csSDO)
91 if (d->CurrentCommunicationState.csHeartbeat)
92 proceedNODE_GUARD(d,m);
95 if (*(d->iam_a_slave))
97 proceedNMTstateChange(d,m);
102 #define StartOrStop(CommType, FuncStart, FuncStop) \
103 if(newCommunicationState->CommType && !d->CurrentCommunicationState.CommType){\
104 MSG_WAR(0x9999,#FuncStart, 9999);\
105 d->CurrentCommunicationState.CommType = 1;\
107 }else if(!newCommunicationState->CommType && d->CurrentCommunicationState.CommType){\
108 MSG_WAR(0x9999,#FuncStop, 9999);\
109 d->CurrentCommunicationState.CommType = 0;\
118 ** @param newCommunicationState
120 void switchCommunicationState(CO_Data* d, s_state_communication *newCommunicationState)
122 StartOrStop(csSDO, None, resetSDO(d))
123 StartOrStop(csSYNC, startSYNC(d), stopSYNC(d))
124 StartOrStop(csHeartbeat, heartbeatInit(d), heartbeatStop(d))
125 /* StartOrStop(Emergency,,) */
126 StartOrStop(csPDO, None, None)
127 StartOrStop(csBoot_Up, None, slaveSendBootUp(d))
138 UNS8 setState(CO_Data* d, e_nodeState newState)
140 UNS16 wIndex = 0x1F22;
141 const indextable *ptrTable;
142 ODCallback_t *Callback;
144 while(newState != d->nodeState){
148 s_state_communication newCommunicationState = {1, 0, 0, 0, 0, 0};
149 /** This will force a second loop for the state switch */
150 d->nodeState = Initialisation;
151 newState = Pre_operational;
152 switchCommunicationState(d, &newCommunicationState);
153 /** call user app related state func. */
154 (*d->initialisation)();
159 case Pre_operational:
162 s_state_communication newCommunicationState = {0, 1, 1, 1, 1, 0};
163 d->nodeState = Pre_operational;
164 newState = Pre_operational;
165 switchCommunicationState(d, &newCommunicationState);
166 if (!(*(d->iam_a_slave)))
168 ptrTable =(*d->scanIndexOD)(wIndex, &errorCode, &Callback);
170 if (errorCode != OD_SUCCESSFUL)
172 (*d->preOperational)();
177 res = decompo_dcf(d,0x01);
182 (*d->preOperational)();
188 if(d->nodeState == Initialisation) return 0xFF;
190 s_state_communication newCommunicationState = {0, 1, 1, 1, 1, 1};
191 d->nodeState = Operational;
192 newState = Operational;
193 switchCommunicationState(d, &newCommunicationState);
199 if(d->nodeState == Initialisation) return 0xFF;
201 s_state_communication newCommunicationState = {0, 0, 0, 0, 1, 0};
202 d->nodeState = Stopped;
204 switchCommunicationState(d, &newCommunicationState);
211 }/** end switch case */
224 UNS8 getNodeId(CO_Data* d)
226 return *d->bDeviceNodeId;
235 void setNodeId(CO_Data* d, UNS8 nodeId)
237 UNS16 offset = d->firstIndex->SDO_SVR;
239 /** cob_id_client = 0x600 + nodeId; */
240 *(UNS32*)d->objdict[offset].pSubindex[1].pObject = 0x600 + nodeId;
241 /** cob_id_server = 0x580 + nodeId; */
242 *(UNS32*)d->objdict[offset].pSubindex[2].pObject = 0x580 + nodeId;
243 /** node Id client. As we do not know the value, we put the node Id Server */
244 /** *(UNS8*)d->objdict[offset].pSubindex[3].pObject = nodeId; */
248 Initialize the server(s) SDO parameters
249 Remember that only one SDO server is allowed, defined at index 0x1200
251 Initialize the client(s) SDO parameters
252 Nothing to initialize (no default values required by the DS 401)
253 Initialize the receive PDO communication parameters. Only for 0x1400 to 0x1403
257 UNS16 offset = d->firstIndex->PDO_RCV;
258 UNS16 lastIndex = d->lastIndex->PDO_RCV;
259 UNS32 cobID[] = {0x200, 0x300, 0x400, 0x500};
260 if( offset ) while( (offset <= lastIndex) && (i < 4)) {
261 //if(*(UNS32*)d->objdict[offset].pSubindex[1].pObject == cobID[i] + *d->bDeviceNodeId)
262 *(UNS32*)d->objdict[offset].pSubindex[1].pObject = cobID[i] + nodeId;
267 /* ** Initialize the transmit PDO communication parameters. Only for 0x1800 to 0x1803 */
270 UNS16 offset = d->firstIndex->PDO_TRS;
271 UNS16 lastIndex = d->lastIndex->PDO_TRS;
272 UNS32 cobID[] = {0x180, 0x280, 0x380, 0x480};
274 if( offset ) while ((offset <= lastIndex) && (i < 4)) {
275 //if(*(UNS32*)d->objdict[offset].pSubindex[1].pObject == cobID[i] + *d->bDeviceNodeId)
276 *(UNS32*)d->objdict[offset].pSubindex[1].pObject = cobID[i] + nodeId;
281 /** bDeviceNodeId is defined in the object dictionary. */
282 *d->bDeviceNodeId = nodeId;
285 void _initialisation(){}
286 void _preOperational(){}
287 void _operational(){}