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"
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 UNS8 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 */
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);
124 printf("nodeid slave=%x\n",nodeId);
127 { /*disable Slave's TPDO 1 */
128 UNS32 TPDO_COBId = 0x80000180 + nodeId;
130 eprintf("Master : disable slave %2.2x TPDO 1 \n", nodeId);
131 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
132 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
133 nodeId, /*UNS8 nodeId*/
134 0x1800, /*UNS16 index*/
135 0x01, /*UNS8 subindex*/
138 &TPDO_COBId,/*void *data*/
139 CheckSDOAndContinue); /*SDOCallback_t Callback*/
144 { /*setup Slave's TPDO 1 to be transmitted on SYNC*/
145 UNS8 Transmission_Type = 0x01;
147 eprintf("Master : set slave %2.2x TPDO 1 transmit type\n", nodeId);
148 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
149 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
150 nodeId, /*UNS8 nodeId*/
151 0x1800, /*UNS16 index*/
152 0x02, /*UNS8 subindex*/
155 &Transmission_Type,/*void *data*/
156 CheckSDOAndContinue); /*SDOCallback_t Callback*/
161 { /*re-enable Slave's TPDO 1 */
162 UNS32 TPDO_COBId = 0x00000180 + nodeId;
164 eprintf("Master : re-enable slave %2.2x TPDO 1\n", nodeId);
165 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
166 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
167 nodeId, /*UNS8 nodeId*/
168 0x1800, /*UNS16 index*/
169 0x01, /*UNS8 subindex*/
172 &TPDO_COBId,/*void *data*/
173 CheckSDOAndContinue); /*SDOCallback_t Callback*/
178 { /*disable Slave's TPDO 2 */
179 UNS32 TPDO_COBId = 0x80000200 + nodeId;
181 eprintf("Master : disable slave %2.2x RPDO 1\n", nodeId);
182 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
183 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
184 nodeId, /*UNS8 nodeId*/
185 0x1400, /*UNS16 index*/
186 0x01, /*UNS8 subindex*/
189 &TPDO_COBId,/*void *data*/
190 CheckSDOAndContinue); /*SDOCallback_t Callback*/
197 UNS8 Transmission_Type = 0x01;
199 eprintf("Master : set slave %2.2x RPDO 1 receive type\n", nodeId);
200 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
201 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
202 nodeId, /*UNS8 nodeId*/
203 0x1400, /*UNS16 index*/
204 0x02, /*UNS8 subindex*/
207 &Transmission_Type,/*void *data*/
208 CheckSDOAndContinue); /*SDOCallback_t Callback*/
213 { /*re-enable Slave's TPDO 1 */
214 UNS32 TPDO_COBId = 0x00000200 + nodeId;
216 eprintf("Master : re-enable %2.2x RPDO 1\n", nodeId);
217 res = writeNetworkDictCallBack (d, /*CO_Data* d*/
218 /**TestSlave_Data.bDeviceNodeId, UNS8 nodeId*/
219 nodeId, /*UNS8 nodeId*/
220 0x1400, /*UNS16 index*/
221 0x01, /*UNS8 subindex*/
224 &TPDO_COBId,/*void *data*/
225 CheckSDOAndContinue); /*SDOCallback_t Callback*/
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 2 */
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)
332 eprintf("MicroMod Digital Out: %2.2x\n",DO);
333 eprintf("MicroMod Analogue Out1: %d\n",AO1);
334 eprintf("MicroMod Analogue Out2: %d\n",AO2);
335 eprintf("MicroMod Analogue Out3: %d\n",AO3);
336 eprintf("MicroMod Analogue Out4: %d\n",AO4);
337 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);
338 eprintf("MicroMod Analogue In1: %d\n", AI1);
339 eprintf("MicroMod Analogue In2: %d\n", AI2);
340 eprintf("MicroMod Analogue In3: %d\n", AI3);
341 eprintf("MicroMod Analogue In4: %d\n", AI4);
342 eprintf("MicroMod Analogue In5: %d\n", AI5);
343 eprintf("MicroMod Analogue In6: %d\n", AI6);
344 eprintf("MicroMod Analogue In7: %d\n", AI7);
345 eprintf("MicroMod Analogue In8: %d\n", AI8);
348 void TestMaster_post_TPDO(CO_Data* d)
350 // eprintf("TestMaster_post_TPDO\n");
353 //s_BOARD SlaveBoard = {"0", "500K"};
354 s_BOARD MasterBoard = {"32", "125K"};
356 #if !defined(WIN32) || defined(__CYGWIN__)
357 void catch_signal(int sig)
359 signal(SIGTERM, catch_signal);
360 signal(SIGINT, catch_signal);
362 eprintf("Got Signal %d\n",sig);
368 printf("**************************************************************\n");
369 printf("* TestMasterMicroMod *\n");
371 printf("* A simple example for PC. *\n");
372 printf("* A CanOpen master that control a MicroMod module: *\n");
373 printf("* - setup module TPDO 1 transmit type *\n");
374 printf("* - setup module RPDO 1 transmit type *\n");
375 printf("* - setup module hearbeatbeat period *\n");
376 printf("* - disable others TPDOs *\n");
377 printf("* - set state to operational *\n");
378 printf("* - send periodic SYNC *\n");
379 printf("* - send periodic RPDO 1 to Micromod (digital output) *\n");
380 printf("* - listen Micromod's TPDO 1 (digital input) *\n");
381 printf("* - Mapping RPDO 1 bit per bit (digital input) *\n");
383 printf("* Usage: *\n");
384 printf("* ./TestMasterMicroMod [OPTIONS] *\n");
386 printf("* OPTIONS: *\n");
387 printf("* -l : Can library [\"libcanfestival_can_virtual.so\"] *\n");
389 printf("* Slave: *\n");
390 printf("* -i : Slave Node id format [0x01 , 0x7F] *\n");
392 printf("* Master: *\n");
393 printf("* -m : bus name [\"1\"] *\n");
394 printf("* -M : 1M,500K,250K,125K,100K,50K,20K,10K *\n");
396 printf("**************************************************************\n");
399 /*************************** INIT *****************************************/
400 void InitNodes(CO_Data* d, UNS32 id)
402 /****************************** INITIALISATION MASTER *******************************/
403 if(MasterBoard.baudrate){
404 /* Defining the node Id */
405 //setNodeId(&TestMaster_Data, 0x01);
408 setState(&TestMaster_Data, Initialisation);
412 /****************************************************************************/
413 /*************************** MAIN *****************************************/
414 /****************************************************************************/
415 int main(int argc,char **argv)
420 char* LibraryPath="libcanfestival_can_virtual.so";
422 while ((c = getopt(argc, argv, "-m:s:M:S:l:i:")) != EOF)
432 MasterBoard.busname = optarg;
440 MasterBoard.baudrate = optarg;
448 LibraryPath = optarg;
457 sscanf(snodeid,"%x",&slavenodeid);
465 #if !defined(WIN32) || defined(__CYGWIN__)
466 /* install signal handler for manual break */
467 signal(SIGTERM, catch_signal);
468 signal(SIGINT, catch_signal);
471 #ifndef NOT_USE_DYNAMIC_LOADING
472 LoadCanDriver(LibraryPath);
475 TestMaster_Data.heartbeatError = TestMaster_heartbeatError;
476 TestMaster_Data.initialisation = TestMaster_initialisation;
477 TestMaster_Data.preOperational = TestMaster_preOperational;
478 TestMaster_Data.operational = TestMaster_operational;
479 TestMaster_Data.stopped = TestMaster_stopped;
480 TestMaster_Data.post_sync = TestMaster_post_sync;
481 TestMaster_Data.post_TPDO = TestMaster_post_TPDO;
483 if(!canOpen(&MasterBoard,&TestMaster_Data)){
484 eprintf("Cannot open Master Board\n");
488 // Start timer thread
489 StartTimerLoop(&InitNodes);
493 eprintf("Finishing.\n");
495 // Reset the slave node for next use (will stop emitting heartbeat)
496 masterSendNMTstateChange (&TestMaster_Data, slavenodeid, NMT_Reset_Node);
499 setState(&TestMaster_Data, Stopped);
505 if(MasterBoard.baudrate) canClose(&TestMaster_Data);