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
23 #if defined(WIN32) && !defined(__CYGWIN__)
38 #include "canfestival.h"
39 #include "TestMasterMicroMod.h"
40 #include "TestMaster.h"
41 unsigned int slavenodeid = 0x40;
44 /*****************************************************************************/
45 void TestMaster_heartbeatError(CO_Data* d, UNS8 heartbeatID)
47 eprintf("TestMaster_heartbeatError %d\n", heartbeatID);
50 /********************************************************
51 * ConfigureSlaveNode is responsible to
52 * - setup master RPDO 1 to receive TPDO 1 from id 0x40
53 * - setup master TPDO 1 to send RPDO 1 to id 0x40
54 ********************************************************/
55 void TestMaster_initialisation(CO_Data* d)
57 UNS32 PDO1_COBID = 0x0180 + slavenodeid;
58 UNS32 PDO2_COBID = 0x0200 + slavenodeid;
59 UNS32 size = sizeof(UNS32);
61 eprintf("TestMaster_initialisation\n");
63 /*****************************************
64 * Define RPDOs to match slave ID=0x40 TPDOs*
65 *****************************************/
66 writeLocalDict( &TestMaster_Data, /*CO_Data* d*/
67 0x1400, /*UNS16 index*/
69 &PDO1_COBID, /*void * pSourceData,*/
70 &size, /* UNS8 * pExpectedSize*/
71 RW); /* UNS8 checkAccess */
74 /*****************************************
75 * Define TPDOs to match slave ID=0x40 RPDOs*
76 *****************************************/
77 writeLocalDict( &TestMaster_Data, /*CO_Data* d*/
78 0x1800, /*UNS16 index*/
80 &PDO2_COBID, /*void * pSourceData,*/
81 &size, /* UNS8 * pExpectedSize*/
82 RW); /* UNS8 checkAccess */
85 static int init_step = 0;
87 /*Froward declaration*/
88 static void ConfigureSlaveNode(CO_Data* d, UNS8 nodeId);
91 static void CheckSDOAndContinue(CO_Data* d, UNS8 nodeId)
95 if(getWriteResultNetworkDict (d, nodeId, &abortCode) != SDO_FINISHED)
96 eprintf("Master : Failed in initializing slave %2.2x, step %d, AbortCode :%4.4x \n", nodeId, init_step, abortCode);
98 /* Finalise last SDO transfer with this node */
99 closeSDOtransfer(&TestMaster_Data, nodeId, SDO_CLIENT);
101 ConfigureSlaveNode(d, nodeId);
104 /********************************************************
105 * ConfigureSlaveNode is responsible to
106 * - setup slave TPDO 1 transmit time
107 * - setup slave TPDO 2 transmit time
108 * - setup slave Heartbeat Producer time
109 * - switch to operational mode
110 * - send NMT to slave
111 ********************************************************
112 * This an example of :
113 * Network Dictionary Access (SDO) with Callback
114 * Slave node state change request (NMT)
115 ********************************************************
116 * This is called first by TestMaster_preOperational
117 * then it called again each time a SDO exchange is
119 ********************************************************/
120 static void ConfigureSlaveNode(CO_Data* d, UNS8 nodeId)
123 eprintf("Master : ConfigureSlaveNode %2.2x\n", nodeId);
126 { /*disable Slave's TPDO 1 */
127 UNS32 TPDO_COBId = 0x80000180 + nodeId;
129 eprintf("Master : disable slave %2.2x TPDO 1 \n", nodeId);
130 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
131 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
132 nodeId, /*UNS8 nodeId*/
133 0x1800, /*UNS16 index*/
134 0x01, /*UNS8 subindex*/
137 &TPDO_COBId,/*void *data*/
138 CheckSDOAndContinue); /*SDOCallback_t Callback*/
143 { /*setup Slave's TPDO 1 to be transmitted on SYNC*/
144 UNS8 Transmission_Type = 0x01;
146 eprintf("Master : set slave %2.2x TPDO 1 transmit type\n", nodeId);
147 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
148 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
149 nodeId, /*UNS8 nodeId*/
150 0x1800, /*UNS16 index*/
151 0x02, /*UNS8 subindex*/
154 &Transmission_Type,/*void *data*/
155 CheckSDOAndContinue); /*SDOCallback_t Callback*/
160 { /*re-enable Slave's TPDO 1 */
161 UNS32 TPDO_COBId = 0x00000180 + nodeId;
163 eprintf("Master : re-enable slave %2.2x TPDO 1\n", nodeId);
164 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
165 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
166 nodeId, /*UNS8 nodeId*/
167 0x1800, /*UNS16 index*/
168 0x01, /*UNS8 subindex*/
171 &TPDO_COBId,/*void *data*/
172 CheckSDOAndContinue); /*SDOCallback_t Callback*/
177 { /*disable Slave's RPDO 1 */
178 UNS32 TPDO_COBId = 0x80000200 + nodeId;
180 eprintf("Master : disable slave %2.2x RPDO 1\n", nodeId);
181 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
182 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
183 nodeId, /*UNS8 nodeId*/
184 0x1400, /*UNS16 index*/
185 0x01, /*UNS8 subindex*/
188 &TPDO_COBId,/*void *data*/
189 CheckSDOAndContinue); /*SDOCallback_t Callback*/
196 UNS8 Transmission_Type = 0x01;
198 eprintf("Master : set slave %2.2x RPDO 1 receive type\n", nodeId);
199 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
200 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
201 nodeId, /*UNS8 nodeId*/
202 0x1400, /*UNS16 index*/
203 0x02, /*UNS8 subindex*/
206 &Transmission_Type,/*void *data*/
207 CheckSDOAndContinue); /*SDOCallback_t Callback*/
212 { /*re-enable Slave's RPDO 1 */
213 UNS32 TPDO_COBId = 0x00000200 + nodeId;
215 eprintf("Master : re-enable %2.2x RPDO 1\n", nodeId);
216 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
217 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
218 nodeId, /*UNS8 nodeId*/
219 0x1400, /*UNS16 index*/
220 0x01, /*UNS8 subindex*/
223 &TPDO_COBId,/*void *data*/
224 CheckSDOAndContinue); /*SDOCallback_t Callback*/
230 /*set the heartbeat Producer Time*/
231 UNS16 Heartbeat_Producer_Time = 0x03E8;
232 eprintf("Master : set slave %2.2x heartbeat producer time \n", nodeId);
233 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
234 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
235 nodeId, /*UNS8 nodeId*/
236 0x1017, /*UNS16 index*/
237 0x00, /*UNS8 subindex*/
240 &Heartbeat_Producer_Time,/*void *data*/
241 CheckSDOAndContinue); /*SDOCallback_t Callback*/
246 { /*disable Slave's TPDO 2 */
247 UNS32 TPDO_COBId = 0x80000280 + nodeId;
249 eprintf("Master : disable slave %2.2x TPDO 2 \n", nodeId);
250 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
251 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
252 nodeId, /*UNS8 nodeId*/
253 0x1801, /*UNS16 index*/
254 0x01, /*UNS8 subindex*/
257 &TPDO_COBId,/*void *data*/
258 CheckSDOAndContinue); /*SDOCallback_t Callback*/
263 { /*disable Slave's TPDO 3 */
264 UNS32 TPDO_COBId = 0x80000380 + nodeId;
266 eprintf("Master : disable slave %2.2x TPDO 3 \n", nodeId);
267 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
268 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
269 nodeId, /*UNS8 nodeId*/
270 0x1802, /*UNS16 index*/
271 0x01, /*UNS8 subindex*/
274 &TPDO_COBId,/*void *data*/
275 CheckSDOAndContinue); /*SDOCallback_t Callback*/
280 { /*disable Slave's TPDO 4 */
281 UNS32 TPDO_COBId = 0x80000480 + nodeId;
283 eprintf("Master : disable slave %2.2x TPDO 4 \n", nodeId);
284 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
285 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
286 nodeId, /*UNS8 nodeId*/
287 0x1803, /*UNS16 index*/
288 0x01, /*UNS8 subindex*/
291 &TPDO_COBId,/*void *data*/
292 CheckSDOAndContinue); /*SDOCallback_t Callback*/
297 /* Put the master in operational mode */
298 setState(d, Operational);
300 /* Ask slave node to go in operational mode */
301 masterSendNMTstateChange (d, nodeId, NMT_Start_Node);
306 void TestMaster_preOperational(CO_Data* d)
309 eprintf("TestMaster_preOperational\n");
310 ConfigureSlaveNode(&TestMaster_Data, slavenodeid);
314 void TestMaster_operational(CO_Data* d)
316 eprintf("TestMaster_operational\n");
319 void TestMaster_stopped(CO_Data* d)
321 eprintf("TestMaster_stopped\n");
324 void TestMaster_post_sync(CO_Data* d)
327 eprintf("MicroMod Digital Out: %2.2x\n",DO);
328 eprintf("MicroMod Digital In (by bit): DI1: %2.2x DI2: %2.2x DI3: %2.2x DI4: %2.2x DI5: %2.2x DI6: %2.2x DI7: %2.2x DI8: %2.2x\n",DI1,DI2,DI3,DI4,DI5,DI6,DI7,DI8);
331 void TestMaster_post_TPDO(CO_Data* d)
333 // eprintf("TestMaster_post_TPDO\n");
336 //s_BOARD SlaveBoard = {"0", "500K"};
337 s_BOARD MasterBoard = {"0", "125K"};
339 #if !defined(WIN32) || defined(__CYGWIN__)
340 void catch_signal(int sig)
342 signal(SIGTERM, catch_signal);
343 signal(SIGINT, catch_signal);
345 eprintf("Got Signal %d\n",sig);
351 printf("**************************************************************\n");
352 printf("* TestMasterMicroMod *\n");
354 printf("* A simple example for PC. *\n");
355 printf("* A CanOpen master that control a MicroMod module: *\n");
356 printf("* - setup module TPDO 1 transmit type *\n");
357 printf("* - setup module RPDO 1 transmit type *\n");
358 printf("* - setup module hearbeatbeat period *\n");
359 printf("* - disable others TPDOs *\n");
360 printf("* - set state to operational *\n");
361 printf("* - send periodic SYNC *\n");
362 printf("* - send periodic RPDO 1 to Micromod (digital output) *\n");
363 printf("* - listen Micromod's TPDO 1 (digital input) *\n");
364 printf("* - Mapping RPDO 1 bit per bit (digital input) *\n");
366 printf("* Usage: *\n");
367 printf("* ./TestMasterMicroMod [OPTIONS] *\n");
369 printf("* OPTIONS: *\n");
370 printf("* -l : Can library [\"libcanfestival_can_virtual.so\"] *\n");
372 printf("* Slave: *\n");
373 printf("* -i : Slave Node id format [0x01 , 0x7F] *\n");
375 printf("* Master: *\n");
376 printf("* -m : bus name [\"1\"] *\n");
377 printf("* -M : 1M,500K,250K,125K,100K,50K,20K,10K *\n");
379 printf("**************************************************************\n");
382 /*************************** INIT *****************************************/
383 void InitNodes(CO_Data* d, UNS32 id)
385 /****************************** INITIALISATION MASTER *******************************/
386 if(MasterBoard.baudrate){
387 /* Defining the node Id */
388 setNodeId(&TestMaster_Data, 0x01);
391 setState(&TestMaster_Data, Initialisation);
395 /*************************** EXIT *****************************************/
396 void Exit(CO_Data* d, UNS32 id)
398 if(strcmp(MasterBoard.baudrate, "none")){
399 masterSendNMTstateChange(&TestMaster_Data, 0x02, NMT_Reset_Node);
402 setState(&TestMaster_Data, Stopped);
405 /****************************************************************************/
406 /*************************** MAIN *****************************************/
407 /****************************************************************************/
408 int main(int argc,char **argv)
413 char* LibraryPath="libcanfestival_can_virtual.so";
415 while ((c = getopt(argc, argv, "-m:s:M:S:l:i:")) != EOF)
425 MasterBoard.busname = optarg;
433 MasterBoard.baudrate = optarg;
441 LibraryPath = optarg;
450 sscanf(snodeid,"%x",&slavenodeid);
458 #if !defined(WIN32) || defined(__CYGWIN__)
459 /* install signal handler for manual break */
460 signal(SIGTERM, catch_signal);
461 signal(SIGINT, catch_signal);
465 #ifndef NOT_USE_DYNAMIC_LOADING
466 LoadCanDriver(LibraryPath);
469 TestMaster_Data.heartbeatError = TestMaster_heartbeatError;
470 TestMaster_Data.initialisation = TestMaster_initialisation;
471 TestMaster_Data.preOperational = TestMaster_preOperational;
472 TestMaster_Data.operational = TestMaster_operational;
473 TestMaster_Data.stopped = TestMaster_stopped;
474 TestMaster_Data.post_sync = TestMaster_post_sync;
475 TestMaster_Data.post_TPDO = TestMaster_post_TPDO;
477 if(!canOpen(&MasterBoard,&TestMaster_Data)){
478 eprintf("Cannot open Master Board\n");
482 // Start timer thread
483 StartTimerLoop(&InitNodes);
487 eprintf("Finishing.\n");
490 StopTimerLoop(&Exit);
493 if(MasterBoard.baudrate) canClose(&TestMaster_Data);