]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - examples/TestMasterSlave/TestMasterSlave.c
Changes in the API:
[CanFestival-3.git] / examples / TestMasterSlave / TestMasterSlave.c
1 /*
2 This file is part of CanFestival, a library implementing CanOpen Stack. 
3
4 Copyright (C): Edouard TISSERANT and Francis DUPIN
5
6 See COPYING file for copyrights details.
7
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.
12
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.
17
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
21 */
22
23 #if defined(WIN32) && !defined(__CYGWIN__)
24 #include <windows.h>
25 #include "getopt.h"
26 void pause(void)
27 {
28         system("PAUSE");
29 }
30 #else
31 #include <stdio.h>
32 #include <string.h>
33 //#include <sys/time.h>
34 //#include <unistd.h>
35 #include <stdlib.h>
36 #include <signal.h>
37 #endif
38
39 #include <applicfg.h>
40 #include <can_driver.h>
41 #include <timers_driver.h>
42
43 #include "Master.h"
44 #include "Slave.h"
45 #include "TestMasterSlave.h"
46
47 #define MyCase(fc) case fc: eprintf(#fc);break;
48 void print_message(Message *m)
49 {
50         int i;
51         switch(m->cob_id.w >> 7)
52         {
53                 MyCase(SYNC)
54                 MyCase(TIME_STAMP)
55                 MyCase(PDO1tx)
56                 MyCase(PDO1rx)
57                 MyCase(PDO2tx)
58                 MyCase(PDO2rx)
59                 MyCase(PDO3tx)
60                 MyCase(PDO3rx)
61                 MyCase(PDO4tx)
62                 MyCase(PDO4rx)
63                 MyCase(SDOtx)
64                 MyCase(SDOrx)
65                 MyCase(NODE_GUARD)
66                 MyCase(NMT)
67         }
68         eprintf(" rtr:%d", m->rtr);
69         eprintf(" len:%d", m->len);
70         for (i = 0 ; i < m->len ; i++)
71                 eprintf(" %02x", m->data[i]);
72         eprintf("\n");
73 }
74
75 UNS32 OnMasterMap1Update(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex)
76 {
77         eprintf("OnSlaveMap1Update:%d\n", SlaveMap1);
78         return 0;
79 }
80
81 s_BOARD SlaveBoard = {"0", "500K"};
82 s_BOARD MasterBoard = {"1", "500K"};
83
84 #if !defined(WIN32) || defined(__CYGWIN__)
85 void catch_signal(int sig)
86 {
87   signal(SIGTERM, catch_signal);
88   signal(SIGINT, catch_signal);
89   eprintf("Got Signal %d\n",sig);
90 }
91 #endif
92
93 void help()
94 {
95   printf("**************************************************************\n");
96   printf("*  TestMasterSlave                                           *\n");
97   printf("*                                                            *\n");
98   printf("*  A simple example for PC. It does implement 2 CanOpen      *\n");
99   printf("*  nodes in the same process. A master and a slave. Both     *\n");
100   printf("*  communicate together, exchanging periodically NMT, SYNC,  *\n");
101   printf("*  SDO and PDO.                                              *\n");
102   printf("*                                                            *\n");
103   printf("*   Usage:                                                   *\n");
104   printf("*   ./TestMasterSlave  [OPTIONS]                             *\n");
105   printf("*                                                            *\n");
106   printf("*   OPTIONS:                                                 *\n");
107   printf("*     -l : Can library [\"libcanfestival_can_virtual.so\"]     *\n");
108   printf("*                                                            *\n");
109   printf("*    Slave:                                                  *\n");
110   printf("*     -s : bus name [\"0\"]                                    *\n");
111   printf("*     -S : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable)  *\n");
112   printf("*                                                            *\n");
113   printf("*    Master:                                                 *\n");
114   printf("*     -m : bus name [\"1\"]                                    *\n");
115   printf("*     -M : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable)  *\n");
116   printf("*                                                            *\n");
117   printf("**************************************************************\n");
118 }
119
120 /***************************  INIT  *****************************************/
121 void InitNodes(CO_Data* d, UNS32 id)
122 {
123         /****************************** INITIALISATION SLAVE *******************************/
124         if(SlaveBoard.baudrate) {
125                 /* Defining the node Id */
126                 setNodeId(&TestSlave_Data, 0x02);
127                 /* init */
128                 setState(&TestSlave_Data, Initialisation);
129         }
130
131         /****************************** INITIALISATION MASTER *******************************/
132         if(MasterBoard.baudrate){
133                 RegisterSetODentryCallBack(&TestMaster_Data, 0x2000, 0, &OnMasterMap1Update);
134
135                 /* Defining the node Id */
136                 setNodeId(&TestMaster_Data, 0x01);
137
138                 /* init */
139                 setState(&TestMaster_Data, Initialisation);
140
141                 /****************************** START *******************************/
142                 /* Put the master in operational mode */
143                 setState(&TestMaster_Data, Operational);
144   
145                 /* Ask slave node to go in operational mode */
146                 masterSendNMTstateChange (&TestMaster_Data, 0x02, NMT_Start_Node);
147         }
148 }
149
150 /****************************************************************************/
151 /***************************  MAIN  *****************************************/
152 /****************************************************************************/
153 int main(int argc,char **argv)
154 {
155
156   char c;
157   extern char *optarg;
158   char* LibraryPath="libcanfestival_can_virtual.so";
159
160   while ((c = getopt(argc, argv, "-m:s:M:S:l:")) != EOF)
161   {
162     switch(c)
163     {
164       case 's' :
165         if (optarg[0] == 0)
166         {
167           help();
168           exit(1);
169         }
170         SlaveBoard.busname = optarg;
171         break;
172       case 'm' :
173         if (optarg[0] == 0)
174         {
175           help();
176           exit(1);
177         }
178         MasterBoard.busname = optarg;
179         break;
180       case 'S' :
181         if (optarg[0] == 0)
182         {
183           help();
184           exit(1);
185         }
186         SlaveBoard.baudrate = optarg;
187         break;
188       case 'M' :
189         if (optarg[0] == 0)
190         {
191           help();
192           exit(1);
193         }
194         MasterBoard.baudrate = optarg;
195         break;
196       case 'l' :
197         if (optarg[0] == 0)
198         {
199           help();
200           exit(1);
201         }
202         LibraryPath = optarg;
203         break;
204       default:
205         help();
206         exit(1);
207     }
208   }
209
210 #if !defined(WIN32) || defined(__CYGWIN__)
211   /* install signal handler for manual break */
212         signal(SIGTERM, catch_signal);
213         signal(SIGINT, catch_signal);
214 #endif
215
216 #ifndef NOT_USE_DYNAMIC_LOADING
217         LoadCanDriver(LibraryPath);
218 #endif          
219         // Open CAN devices
220         if(SlaveBoard.baudrate){
221                 
222                 TestSlave_Data.heartbeatError = TestSlave_heartbeatError;
223                 TestSlave_Data.SDOtimeoutError = TestSlave_SDOtimeoutError;
224                 TestSlave_Data.initialisation = TestSlave_initialisation;
225                 TestSlave_Data.preOperational = TestSlave_preOperational;
226                 TestSlave_Data.operational = TestSlave_operational;
227                 TestSlave_Data.stopped = TestSlave_stopped;
228                 TestSlave_Data.post_sync = TestSlave_post_sync;
229                 TestSlave_Data.post_TPDO = TestSlave_post_TPDO;
230
231                 if(!canOpen(&SlaveBoard,&TestSlave_Data)){
232                         eprintf("Cannot open Slave Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate);
233                         goto fail_slave;
234                 }
235         }
236
237         if(MasterBoard.baudrate){
238                 
239                 TestMaster_Data.heartbeatError = TestMaster_heartbeatError;
240                 TestMaster_Data.SDOtimeoutError = TestMaster_SDOtimeoutError;
241                 TestMaster_Data.initialisation = TestMaster_initialisation;
242                 TestMaster_Data.preOperational = TestMaster_preOperational;
243                 TestMaster_Data.operational = TestMaster_operational;
244                 TestMaster_Data.stopped = TestMaster_stopped;
245                 TestMaster_Data.post_sync = TestMaster_post_sync;
246                 TestMaster_Data.post_TPDO = TestMaster_post_TPDO;
247                 
248                 if(!canOpen(&MasterBoard,&TestMaster_Data)){
249                         eprintf("Cannot open Master Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate);
250                         goto fail_master;
251                 }
252         }
253         
254         // Start timer thread
255         StartTimerLoop(&InitNodes);
256
257         // wait Ctrl-C
258         pause();
259         eprintf("Finishing.\n");
260         
261         // Stop timer thread
262         StopTimerLoop();
263         
264         // Close CAN devices (and can threads)
265         if(SlaveBoard.baudrate) canClose(&TestSlave_Data);
266 fail_master:
267         if(MasterBoard.baudrate) canClose(&TestMaster_Data);    
268 fail_slave:
269         
270
271   return 0;
272 }