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
28 /* Prototypes for internals functions */
29 void switchCommunicationState(CO_Data* d,
30 s_state_communication *newCommunicationState);
32 /*****************************************************************************/
33 e_nodeState getState(CO_Data* d)
38 /*****************************************************************************/
39 void canDispatch(CO_Data* d, Message *m)
41 switch(m->cob_id.w >> 7)
44 if(d->CurrentCommunicationState.csSYNC)
47 /* case TIME_STAMP: */
56 if (d->CurrentCommunicationState.csPDO)
61 if (d->CurrentCommunicationState.csSDO)
65 if (d->CurrentCommunicationState.csHeartbeat)
66 proceedNODE_GUARD(d,m);
69 if (*(d->iam_a_slave))
71 proceedNMTstateChange(d,m);
76 #define StartOrStop(CommType, FuncStart, FuncStop) \
77 if(newCommunicationState->CommType && !d->CurrentCommunicationState.CommType){\
78 MSG_ERR(0x9999,#FuncStart, 9999);\
79 d->CurrentCommunicationState.CommType = 1;\
81 }else if(!newCommunicationState->CommType && d->CurrentCommunicationState.CommType){\
82 MSG_ERR(0x9999,#FuncStop, 9999);\
83 d->CurrentCommunicationState.CommType = 0;\
88 /*****************************************************************************/
89 void switchCommunicationState(CO_Data* d, s_state_communication *newCommunicationState)
91 StartOrStop(csSDO, None, resetSDO(d))
92 StartOrStop(csSYNC, startSYNC(d), stopSYNC(d))
93 StartOrStop(csHeartbeat, heartbeatInit(d), heartbeatStop(d))
94 /* StartOrStop(Emergency,,) */
95 StartOrStop(csPDO, None, None)
96 StartOrStop(csBoot_Up, None, slaveSendBootUp(d))
99 /*****************************************************************************/
100 UNS8 setState(CO_Data* d, e_nodeState newState)
102 while(newState != d->nodeState){
106 s_state_communication newCommunicationState = {1, 0, 0, 0, 0, 0};
107 /* This will force a second loop for the state switch */
108 d->nodeState = Initialisation;
109 newState = Pre_operational;
110 switchCommunicationState(d, &newCommunicationState);
111 /* call user app related state func. */
112 (*d->initialisation)();
116 case Pre_operational:
118 s_state_communication newCommunicationState = {0, 1, 1, 1, 1, 0};
119 d->nodeState = Pre_operational;
120 newState = Pre_operational;
121 switchCommunicationState(d, &newCommunicationState);
122 (*d->preOperational)();
127 if(d->nodeState == Initialisation) return 0xFF;
129 s_state_communication newCommunicationState = {0, 1, 1, 1, 1, 1};
130 d->nodeState = Operational;
131 newState = Operational;
132 switchCommunicationState(d, &newCommunicationState);
138 if(d->nodeState == Initialisation) return 0xFF;
140 s_state_communication newCommunicationState = {0, 0, 0, 0, 1, 0};
141 d->nodeState = Stopped;
143 switchCommunicationState(d, &newCommunicationState);
150 }/* end switch case */
156 /*****************************************************************************/
157 UNS8 getNodeId(CO_Data* d)
159 return *d->bDeviceNodeId;
162 /*****************************************************************************/
163 void setNodeId(CO_Data* d, UNS8 nodeId)
165 UNS16 offset = d->firstIndex->SDO_SVR;
167 /* cob_id_client = 0x600 + nodeId; */
168 *(UNS32*)d->objdict[offset].pSubindex[1].pObject = 0x600 + nodeId;
169 /* cob_id_server = 0x580 + nodeId; */
170 *(UNS32*)d->objdict[offset].pSubindex[2].pObject = 0x580 + nodeId;
171 /* node Id client. As we do not know the value, we put the node Id Server */
172 /* *(UNS8*)d->objdict[offset].pSubindex[3].pObject = nodeId; */
175 /* ** Initialize the server(s) SDO parameters */
176 /* Remember that only one SDO server is allowed, defined at index 0x1200 */
178 /* ** Initialize the client(s) SDO parameters */
179 /* Nothing to initialize (no default values required by the DS 401) */
180 /* ** Initialize the receive PDO communication parameters. Only for 0x1400 to 0x1403 */
183 UNS16 offset = d->firstIndex->PDO_RCV;
184 UNS16 lastIndex = d->lastIndex->PDO_RCV;
185 UNS32 cobID[] = {0x200, 0x300, 0x400, 0x500};
186 if( offset ) while( (offset <= lastIndex) && (i < 4)) {
187 if(*(UNS32*)d->objdict[offset].pSubindex[1].pObject == cobID[i] + *d->bDeviceNodeId)
188 *(UNS32*)d->objdict[offset].pSubindex[1].pObject = cobID[i] + nodeId;
193 /* ** Initialize the transmit PDO communication parameters. Only for 0x1800 to 0x1803 */
196 UNS16 offset = d->firstIndex->PDO_TRS;
197 UNS16 lastIndex = d->lastIndex->PDO_TRS;
198 UNS32 cobID[] = {0x180, 0x280, 0x380, 0x480};
200 if( offset ) while ((offset <= lastIndex) && (i < 4)) {
201 if(*(UNS32*)d->objdict[offset].pSubindex[1].pObject == cobID[i] + *d->bDeviceNodeId)
202 *(UNS32*)d->objdict[offset].pSubindex[1].pObject = cobID[i] + nodeId;
207 /* bDeviceNodeId is defined in the object dictionary. */
208 *d->bDeviceNodeId = nodeId;
211 void _initialisation(){}
212 void _preOperational(){}
213 void _operational(){}