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
25 #include "TestMasterSlave.h"
27 /*****************************************************************************/
28 void TestMaster_heartbeatError(CO_Data* d, UNS8 heartbeatID)
30 eprintf("TestMaster_heartbeatError %d\n", heartbeatID);
33 /********************************************************
34 * ConfigureSlaveNode is responsible to
35 * - setup master RPDO 1 to receive TPDO 1 from id 2
36 * - setup master RPDO 2 to receive TPDO 2 from id 2
37 ********************************************************/
38 void TestMaster_initialisation(CO_Data* d)
40 UNS32 PDO1_COBID = 0x0182;
41 UNS32 PDO2_COBID = 0x0282;
42 UNS8 size = sizeof(UNS32);
46 eprintf("TestMaster_initialisation\n");
48 /*****************************************
49 * Define RPDOs to match slave ID=2 TPDOs*
50 *****************************************/
51 writeLocalDict( &TestMaster_Data, /*CO_Data* d*/
52 0x1400, /*UNS16 index*/
54 &PDO1_COBID, /*void * pSourceData,*/
55 &size, /* UNS8 * pExpectedSize*/
56 RW); /* UNS8 checkAccess */
58 writeLocalDict( &TestMaster_Data, /*CO_Data* d*/
59 0x1401, /*UNS16 index*/
61 &PDO2_COBID, /*void * pSourceData,*/
62 &size, /* UNS8 * pExpectedSize*/
63 RW); /* UNS8 checkAccess */
67 // Step counts number of times ConfigureSlaveNode is called
70 /*Froward declaration*/
71 static void ConfigureSlaveNode(CO_Data* d, UNS8 nodeId);
74 static void CheckSDOAndContinue(CO_Data* d, UNS8 nodeId)
77 if(getWriteResultNetworkDict (d, nodeId, &abortCode) != SDO_FINISHED)
78 eprintf("Master : Failed in initializing slave %2.2x, step %d, AbortCode :%4.4x \n", nodeId, init_step, abortCode);
80 /* Finalise last SDO transfer with this node */
81 closeSDOtransfer(&TestMaster_Data, nodeId, SDO_CLIENT);
83 ConfigureSlaveNode(d, nodeId);
86 /********************************************************
87 * ConfigureSlaveNode is responsible to
88 * - setup slave TPDO 1 transmit time
89 * - setup slave TPDO 2 transmit time
90 * - switch to operational mode
92 ********************************************************
93 * This an example of :
94 * Network Dictionary Access (SDO) with Callback
95 * Slave node state change request (NMT)
96 ********************************************************
97 * This is called first by TestMaster_preOperational
98 * then it called again each time a SDO exchange is
100 ********************************************************/
102 static void ConfigureSlaveNode(CO_Data* d, UNS8 nodeId)
104 /* Master configure heartbeat producer time at 1000 ms
105 * for slave node-id 0x02 by DCF concise */
107 UNS8 Transmission_Type = 0x01;
110 eprintf("Master : ConfigureSlaveNode %2.2x\n", nodeId);
113 case 1: /*First step : setup Slave's TPDO 1 to be transmitted on SYNC*/
114 eprintf("Master : set slave %2.2x TPDO 1 transmit type\n", nodeId);
115 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
116 nodeId, /*UNS8 nodeId*/
117 0x1800, /*UNS16 index*/
118 0x02, /*UNS8 subindex*/
121 &Transmission_Type,/*void *data*/
122 CheckSDOAndContinue); /*SDOCallback_t Callback*/
125 case 2: /*Second step*/
126 eprintf("Master : set slave %2.2x TPDO 2 transmit type\n", nodeId);
127 writeNetworkDictCallBack (d, /*CO_Data* d*/
128 nodeId, /*UNS8 nodeId*/
129 0x1801, /*UNS16 index*/
130 0x02, /*UNS16 index*/
133 &Transmission_Type,/*void *data*/
134 CheckSDOAndContinue); /*SDOCallback_t Callback*/
138 /****************************** START *******************************/
140 /* Put the master in operational mode */
141 setState(d, Operational);
143 /* Ask slave node to go in operational mode */
144 masterSendNMTstateChange (d, nodeId, NMT_Start_Node);
150 static void ConfigureLSSNode(CO_Data* d);
151 // Step counts number of times ConfigureLSSNode is called
152 UNS8 init_step_LSS=1;
154 static void CheckLSSAndContinue(CO_Data* d, UNS8 command)
158 printf("CheckLSS->");
159 if(getConfigResultNetworkNode (d, command, &dat1, &dat2) != LSS_FINISHED){
160 if(command==LSS_IDENT_REMOTE_NON_CONF){
161 eprintf("Master : There are not no-configured slaves in the net\n", command);
165 eprintf("Master : Failed in LSS comand %d. Trying again\n", command);
173 case LSS_CONF_NODE_ID:
175 case 0: printf("Node ID change succesful\n");break;
176 case 1: printf("Node ID change error:out of range\n");break;
177 case 0xFF:printf("Node ID change error:specific error\n");break;
181 case LSS_CONF_BIT_TIMING:
183 case 0: printf("Baud rate change succesful\n");break;
184 case 1: printf("Baud rate change error: change baud rate not supported\n");break;
185 case 0xFF:printf("Baud rate change error:specific error\n");break;
191 case 0: printf("Store configuration succesful\n");break;
192 case 1: printf("Store configuration error:not supported\n");break;
193 case 0xFF:printf("Store configuration error:specific error\n");break;
197 case LSS_SM_SELECTIVE_SERIAL:
198 printf("Slave in CONFIGURATION mode\n");
200 case LSS_IDENT_REMOTE_SERIAL_HIGH:
201 printf("node identified\n");
203 case LSS_IDENT_REMOTE_NON_CONF:
204 printf("non-configured remote slave in the net\n");
206 case LSS_INQ_VENDOR_ID:
207 printf("Slave VendorID %x\n", dat1);
209 case LSS_INQ_PRODUCT_CODE:
210 printf("Slave Product Code %x\n", dat1);
212 case LSS_INQ_REV_NUMBER:
213 printf("Slave Revision Number %x\n", dat1);
215 case LSS_INQ_SERIAL_NUMBER:
216 printf("Slave Serial Number %x\n", dat1);
218 case LSS_INQ_NODE_ID:
219 printf("Slave nodeid %x\n", dat1);
221 #ifdef CO_ENABLE_LSS_FS
222 case LSS_IDENT_FASTSCAN:
224 printf("Slave node identified with FastScan\n");
227 printf("There is not unconfigured node in the net\n");
241 /* First ask if there is a node with an invalid nodeID.
242 * If FastScan is activated it is used to put the node in the state â
\80\9cconfigurationâ
\80?.
243 * If FastScan is not activated, identification services are used to identify the node.
244 * Then switch mode service is used to put it in configuration state.
245 * Next all the inquire and configuration services are used.
246 * Finally, the node LSS state is restored to â
\80\9cwaitingâ
\80? and all the process is repeated
247 * again until there isn't any node with a invalid nodeID.
249 static void ConfigureLSSNode(CO_Data* d)
251 UNS32 Vendor_ID=0x12345678;
252 UNS32 Product_Code=0x90123456;
253 UNS32 Revision_Number=0x78901234;
254 UNS32 Serial_Number=0x56789012;
255 UNS32 Revision_Number_high=0x78901240;
256 UNS32 Revision_Number_low=0x78901230;
257 UNS32 Serial_Number_high=0x56789020;
258 UNS32 Serial_Number_low=0x56789010;
261 UNS8 Baud_BitTiming=3;
262 UNS16 Switch_delay=1;
263 UNS8 LSS_mode=LSS_WAITING_MODE;
265 eprintf("ConfigureLSSNode -> ",0);
267 switch(init_step_LSS){
268 case 1: /* LSS=>identify non-configured remote slave */
269 eprintf("LSS=>identify non-configured remote slave\n");
270 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_IDENT_REMOTE_NON_CONF,0,0,CheckLSSAndContinue);
272 #ifdef CO_ENABLE_LSS_FS
273 case 2: /* LSS=>FastScan */
274 eprintf("LSS=>FastScan\n");
275 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_IDENT_FASTSCAN,0,0,CheckLSSAndContinue);
278 case 2: /* LSS=>identify node */
279 eprintf("LSS=>identify node\n");
280 res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_VENDOR,&Vendor_ID,0);
281 res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_PRODUCT,&Product_Code,0);
282 res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_REV_LOW,&Revision_Number_low,0);
283 res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_REV_HIGH,&Revision_Number_high,0);
284 res=configNetworkNode(&TestMaster_Data,LSS_IDENT_REMOTE_SERIAL_LOW,&Serial_Number_low,0);
285 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_IDENT_REMOTE_SERIAL_HIGH,&Serial_Number_high,0,CheckLSSAndContinue);
287 case 3: /*LSS=>put in configuration mode*/
288 eprintf("LSS=>put in configuration mode\n");
289 res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_VENDOR,&Vendor_ID,0);
290 res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_PRODUCT,&Product_Code,0);
291 res=configNetworkNode(&TestMaster_Data,LSS_SM_SELECTIVE_REVISION,&Revision_Number,0);
292 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_SM_SELECTIVE_SERIAL,&Serial_Number,0,CheckLSSAndContinue);
295 case 4: /* LSS=>inquire nodeID */
296 eprintf("LSS=>inquire nodeID\n");
297 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_NODE_ID,0,0,CheckLSSAndContinue);
299 case 5: /* LSS=>inquire VendorID */
300 eprintf("LSS=>inquire VendorID\n");
301 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_VENDOR_ID,0,0,CheckLSSAndContinue);
303 case 6: /* LSS=>inquire Product code */
304 eprintf("LSS=>inquire Product code\n");
305 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_PRODUCT_CODE,0,0,CheckLSSAndContinue);
307 case 7: /* LSS=>inquire Revision Number */
308 eprintf("LSS=>inquire Revision Number\n");
309 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_REV_NUMBER,0,0,CheckLSSAndContinue);
311 case 8: /* LSS=>inquire Serial Number */
312 eprintf("LSS=>inquire Serial Number\n");
313 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_INQ_SERIAL_NUMBER,0,0,CheckLSSAndContinue);
315 case 9: /* LSS=>change the nodeID */
316 eprintf("LSS=>change the nodeId\n");
317 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_CONF_NODE_ID,&NodeID,0,CheckLSSAndContinue);
319 case 10: /* LSS=>change the Baud rate */
320 eprintf("LSS=>change the Baud rate\n");
321 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_CONF_BIT_TIMING,&Baud_Table,&Baud_BitTiming,CheckLSSAndContinue);
324 eprintf("LSS=>Activate Bit Timing\n");
325 res=configNetworkNode(&TestMaster_Data,LSS_CONF_ACT_BIT_TIMING,&Switch_delay,0);
329 /*LSS=>store configuration*/
330 /* It will fail the first time (time out) due to the switch delay */
331 /* It will fail the second time because it is not implemented in the slave */
332 eprintf("LSS=>store configuration\n");
333 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_CONF_STORE,0,0,CheckLSSAndContinue);
335 case 13: /* LSS=>put in operation mod */
336 eprintf("LSS=>put in operation mode\n");
337 res=configNetworkNode(&TestMaster_Data,LSS_SM_GLOBAL,&LSS_mode,0);
338 /* Search again for not-configured slaves*/
339 eprintf("LSS=>identify not-configured remote slave\n");
340 res=configNetworkNodeCallBack(&TestMaster_Data,LSS_IDENT_REMOTE_NON_CONF,0,0,CheckLSSAndContinue);
347 void TestMaster_preOperational(CO_Data* d)
349 eprintf("TestMaster_preOperational\n");
351 /* Ask slave node to go in stop mode */
352 masterSendNMTstateChange (&TestMaster_Data, 0, NMT_Stop_Node);
353 ConfigureLSSNode(&TestMaster_Data);
357 void TestMaster_operational(CO_Data* d)
359 eprintf("TestMaster_operational\n");
362 void TestMaster_stopped(CO_Data* d)
364 eprintf("TestMaster_stopped\n");
367 void TestMaster_post_sync(CO_Data* d)
369 eprintf("TestMaster_post_sync\n");
370 eprintf("Master: %d %d %d %d %d %d %d %d %d %x %x %d %d\n",
386 void TestMaster_post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg)
388 eprintf("Master received EMCY message. Node: %2.2x ErrorCode: %4.4x ErrorRegister: %2.2x\n", nodeID, errCode, errReg);
391 char query_result = 0;
392 char waiting_answer = 0;
394 static void CheckSDO(CO_Data* d, UNS8 nodeId)
397 if(getWriteResultNetworkDict (d, nodeId, &abortCode) != SDO_FINISHED)
398 eprintf("Master : Failed in changing Slave's transmit type AbortCode :%4.4x \n", abortCode);
400 /* Finalise last SDO transfer with this node */
401 closeSDOtransfer(&TestMaster_Data, nodeId, SDO_CLIENT);
405 static int MasterSyncCount = 0;
406 void TestMaster_post_TPDO(CO_Data* d)
408 eprintf("TestMaster_post_TPDO MasterSyncCount = %d \n", MasterSyncCount);
412 // if(MasterMap4 > 0x80){
413 // writeNetworkDict (
415 // TestSlave_Data->bDeviceNodeId,
428 switch(getReadResultNetworkDict (
436 /* Do something with result here !!*/
437 eprintf("Got SDO answer (0x2002, 0x00), %d %d\n",query_result,size);
438 case SDO_ABORTED_RCV:
439 case SDO_ABORTED_INTERNAL:
447 case SDO_DOWNLOAD_IN_PROGRESS:
448 case SDO_UPLOAD_IN_PROGRESS:
451 }else if(MasterSyncCount % 10 == 0){
461 if(MasterSyncCount % 17 == 0){
462 eprintf("Master : Ask RTR PDO (0x1402)\n");
463 sendPDOrequest(&TestMaster_Data, 0x1402 );
464 sendPDOrequest(&TestMaster_Data, 0x1403 );
466 if(MasterSyncCount % 50 == 0){
467 eprintf("Master : Change slave's transmit type to 0xFF\n");
468 UNS8 transmitiontype = 0xFF;
469 writeNetworkDictCallBack (&TestMaster_Data, /*CO_Data* d*/
471 0x1802, /*UNS16 index*/
472 0x02, /*UNS16 index*/
475 &transmitiontype,/*void *data*/
476 CheckSDO); /*SDOCallback_t Callback*/
478 if(MasterSyncCount % 50 == 25){
479 eprintf("Master : Change slave's transmit type to 0x00\n");
480 UNS8 transmitiontype = 0x00;
481 writeNetworkDictCallBack (&TestMaster_Data, /*CO_Data* d*/
483 0x1802, /*UNS16 index*/
484 0x02, /*UNS16 index*/
487 &transmitiontype,/*void *data*/
488 CheckSDO); /*SDOCallback_t Callback*/
493 void TestMaster_post_SlaveBootup(CO_Data* d, UNS8 nodeid)
495 eprintf("TestMaster_post_SlaveBootup %x\n", nodeid);
497 ConfigureSlaveNode(&TestMaster_Data, nodeid);