win32/simple_test/simple_test.c
Go to the documentation of this file.
1 
12 #include <stdio.h>
13 #include <string.h>
14 //#include <Mmsystem.h>
15 
16 #include "osal.h"
17 #include "ethercattype.h"
18 #include "nicdrv.h"
19 #include "ethercatbase.h"
20 #include "ethercatmain.h"
21 #include "ethercatdc.h"
22 #include "ethercatcoe.h"
23 #include "ethercatfoe.h"
24 #include "ethercatconfig.h"
25 #include "ethercatprint.h"
26 
27 #define EC_TIMEOUTMON 500
28 
29 char IOmap[4096];
30 HANDLE thread1;
32 boolean needlf;
33 volatile int wkc;
34 volatile int rtcnt;
35 boolean inOP;
37 
38 /* most basic RT thread for process data, just does IO transfer */
39 void CALLBACK RTthread(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
40 {
41  IOmap[0]++;
42 
45  rtcnt++;
46  /* do RT control stuff here */
47 }
48 
50 {
51  int retval;
52  uint8 nsub, u8val;
53  uint16 nsub2, u16val;
54 
55  // map velocity
56  uint16 map_1c12[4] = {0x0003, 0x1601, 0x1602, 0x1604};
57  uint16 map_1c13[3] = {0x0002, 0x1a01, 0x1a03};
58 
59  retval = 0;
60 
61  // Set PDO mapping using Complete Access
62  // Strange, writing CA works, reading CA doesn't
63  // This is a protocol error of the slave.
64  retval += ec_SDOwrite(slave, 0x1c12, 0x00, TRUE, sizeof(map_1c12), &map_1c12, EC_TIMEOUTSAFE);
65  retval += ec_SDOwrite(slave, 0x1c13, 0x00, TRUE, sizeof(map_1c13), &map_1c13, EC_TIMEOUTSAFE);
66 
67  // bug in EL7031 old firmware, CompleteAccess for reading is not supported even if the slave says it is.
69 
70  // set some motor parameters, just as example
71  u16val = 1200; // max motor current in mA
72 // retval += ec_SDOwrite(slave, 0x8010, 0x01, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTSAFE);
73  u16val = 150; // motor coil resistance in 0.01ohm
74 // retval += ec_SDOwrite(slave, 0x8010, 0x04, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTSAFE);
75 
76  // set other nescessary parameters as needed
77  // .....
78 
79  while(EcatError) printf("%s", ec_elist2string());
80 
81  printf("EL7031 slave %d set, retval = %d\n", slave, retval);
82  return 1;
83 }
84 
86 {
87  int retval;
88  uint8 nsub, u8val;
89  uint16 nsub2, u16val;
90 
91  retval = 0;
92 
93  u8val = 0;
94  retval += ec_SDOwrite(slave, 0x1c12, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);
95  u16val = 0x1603;
96  retval += ec_SDOwrite(slave, 0x1c12, 0x01, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTRXM);
97  u8val = 1;
98  retval += ec_SDOwrite(slave, 0x1c12, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);
99 
100  u8val = 0;
101  retval += ec_SDOwrite(slave, 0x1c13, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);
102  u16val = 0x1a03;
103  retval += ec_SDOwrite(slave, 0x1c13, 0x01, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTRXM);
104  u8val = 1;
105  retval += ec_SDOwrite(slave, 0x1c13, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);
106 
107  u8val = 8;
108  retval += ec_SDOwrite(slave, 0x6060, 0x00, FALSE, sizeof(u8val), &u8val, EC_TIMEOUTRXM);
109 
110  // set some motor parameters, just as example
111  u16val = 1200; // max motor current in mA
112 // retval += ec_SDOwrite(slave, 0x8010, 0x01, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTSAFE);
113  u16val = 150; // motor coil resistance in 0.01ohm
114 // retval += ec_SDOwrite(slave, 0x8010, 0x04, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTSAFE);
115 
116  // set other nescessary parameters as needed
117  // .....
118 
119  while(EcatError) printf("%s", ec_elist2string());
120 
121  printf("AEP slave %d set, retval = %d\n", slave, retval);
122  return 1;
123 }
124 
125 void simpletest(char *ifname)
126 {
127  int i, j, oloop, iloop, wkc_count, chk, slc;
128  UINT mmResult;
129 
130  needlf = FALSE;
131  inOP = FALSE;
132 
133  printf("Starting simple test\n");
134 
135  /* initialise SOEM, bind socket to ifname */
136  if (ec_init(ifname))
137  {
138  printf("ec_init on %s succeeded.\n",ifname);
139  /* find and auto-config slaves */
140 
141 
142  if ( ec_config_init(FALSE) > 0 )
143  {
144  printf("%d slaves found and configured.\n",ec_slavecount);
145 
146  if((ec_slavecount > 1))
147  {
148  for(slc = 1; slc <= ec_slavecount; slc++)
149  {
150  // beckhoff EL7031, using ec_slave[].name is not very reliable
151  if((ec_slave[slc].eep_man == 0x00000002) && (ec_slave[slc].eep_id == 0x1b773052))
152  {
153  printf("Found %s at position %d\n", ec_slave[slc].name, slc);
154  // link slave specific setup to preop->safeop hook
156  }
157  // Copley Controls EAP, using ec_slave[].name is not very reliable
158  if((ec_slave[slc].eep_man == 0x000000ab) && (ec_slave[slc].eep_id == 0x00000380))
159  {
160  printf("Found %s at position %d\n", ec_slave[slc].name, slc);
161  // link slave specific setup to preop->safeop hook
162  ec_slave[slc].PO2SOconfig = &AEPsetup;
163  }
164  }
165  }
166 
167 
169 
170  ec_configdc();
171 
172  printf("Slaves mapped, state to SAFE_OP.\n");
173  /* wait for all slaves to reach SAFE_OP state */
175 
176  oloop = ec_slave[0].Obytes;
177  if ((oloop == 0) && (ec_slave[0].Obits > 0)) oloop = 1;
178  if (oloop > 8) oloop = 8;
179  iloop = ec_slave[0].Ibytes;
180  if ((iloop == 0) && (ec_slave[0].Ibits > 0)) iloop = 1;
181  if (iloop > 8) iloop = 8;
182 
183  printf("segments : %d : %d %d %d %d\n",ec_group[0].nsegments ,ec_group[0].IOsegment[0],ec_group[0].IOsegment[1],ec_group[0].IOsegment[2],ec_group[0].IOsegment[3]);
184 
185  printf("Request operational state for all slaves\n");
186  expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC;
187  printf("Calculated workcounter %d\n", expectedWKC);
189  /* send one valid process data to make outputs in slaves happy*/
192 
193  /* start RT thread as periodic MM timer */
194  mmResult = timeSetEvent(1, 0, RTthread, 0, TIME_PERIODIC);
195 
196  /* request OP state for all slaves */
197  ec_writestate(0);
198  chk = 40;
199  /* wait for all slaves to reach OP state */
200  do
201  {
203  }
204  while (chk-- && (ec_slave[0].state != EC_STATE_OPERATIONAL));
205  if (ec_slave[0].state == EC_STATE_OPERATIONAL )
206  {
207  printf("Operational state reached for all slaves.\n");
208  wkc_count = 0;
209  inOP = TRUE;
210 
211 
212  /* cyclic loop, reads data from RT thread */
213  for(i = 1; i <= 500; i++)
214  {
215  if(wkc >= expectedWKC)
216  {
217  printf("Processdata cycle %4d, WKC %d , O:", rtcnt, wkc);
218 
219  for(j = 0 ; j < oloop; j++)
220  {
221  printf(" %2.2x", *(ec_slave[0].outputs + j));
222  }
223 
224  printf(" I:");
225  for(j = 0 ; j < iloop; j++)
226  {
227  printf(" %2.2x", *(ec_slave[0].inputs + j));
228  }
229  printf(" T:%lld\r",ec_DCtime);
230  needlf = TRUE;
231  }
232  osal_usleep(50000);
233 
234  }
235  inOP = FALSE;
236  }
237  else
238  {
239  printf("Not all slaves reached operational state.\n");
240  ec_readstate();
241  for(i = 1; i<=ec_slavecount ; i++)
242  {
243  if(ec_slave[i].state != EC_STATE_OPERATIONAL)
244  {
245  printf("Slave %d State=0x%2.2x StatusCode=0x%4.4x : %s\n",
246  i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode));
247  }
248  }
249  }
250 
251  /* stop RT thread */
252  timeKillEvent(mmResult);
253 
254  printf("\nRequest init state for all slaves\n");
256  /* request INIT state for all slaves */
257  ec_writestate(0);
258  }
259  else
260  {
261  printf("No slaves found!\n");
262  }
263  printf("End simple test, close socket\n");
264  /* stop SOEM, close socket */
265  ec_close();
266  }
267  else
268  {
269  printf("No socket connection on %s\nExcecute as root\n",ifname);
270  }
271 }
272 
273 DWORD WINAPI ecatcheck( LPVOID lpParam )
274 {
275  int slave;
276 
277  while(1)
278  {
279  if( inOP && ((wkc < expectedWKC) || ec_group[currentgroup].docheckstate))
280  {
281  if (needlf)
282  {
283  needlf = FALSE;
284  printf("\n");
285  }
286  /* one ore more slaves are not responding */
288  ec_readstate();
289  for (slave = 1; slave <= ec_slavecount; slave++)
290  {
291  if ((ec_slave[slave].group == currentgroup) && (ec_slave[slave].state != EC_STATE_OPERATIONAL))
292  {
294  if (ec_slave[slave].state == (EC_STATE_SAFE_OP + EC_STATE_ERROR))
295  {
296  printf("ERROR : slave %d is in SAFE_OP + ERROR, attempting ack.\n", slave);
298  ec_writestate(slave);
299  }
300  else if(ec_slave[slave].state == EC_STATE_SAFE_OP)
301  {
302  printf("WARNING : slave %d is in SAFE_OP, change to OPERATIONAL.\n", slave);
304  ec_writestate(slave);
305  }
306  else if(ec_slave[slave].state > 0)
307  {
308  if (ec_reconfig_slave(slave, EC_TIMEOUTMON))
309  {
311  printf("MESSAGE : slave %d reconfigured\n",slave);
312  }
313  }
314  else if(!ec_slave[slave].islost)
315  {
316  /* re-check state */
318  if (!ec_slave[slave].state)
319  {
321  printf("ERROR : slave %d lost\n",slave);
322  }
323  }
324  }
325  if (ec_slave[slave].islost)
326  {
327  if(!ec_slave[slave].state)
328  {
329  if (ec_recover_slave(slave, EC_TIMEOUTMON))
330  {
332  printf("MESSAGE : slave %d recovered\n",slave);
333  }
334  }
335  else
336  {
338  printf("MESSAGE : slave %d found\n",slave);
339  }
340  }
341  }
342  if(!ec_group[currentgroup].docheckstate)
343  printf("OK : all slaves resumed OPERATIONAL.\n");
344  }
345  osal_usleep(10000);
346  }
347 
348  return 0;
349 }
350 
351 char ifbuf[1024];
352 
353 int main(int argc, char *argv[])
354 {
355  ec_adaptert * adapter = NULL;
356  printf("SOEM (Simple Open EtherCAT Master)\nSimple test\n");
357 
358  if (argc > 1)
359  {
360  /* create thread to handle slave error handling in OP */
361  thread1 = CreateThread( NULL, 0, ecatcheck, NULL, 0, NULL);
362 
363  strcpy(ifbuf, argv[1]);
364  /* start cyclic part */
365  simpletest(ifbuf);
366  }
367  else
368  {
369  printf("Usage: simple_test ifname1\n");
370  /* Print the list */
371  printf ("Available adapters\n");
372  adapter = ec_find_adapters ();
373  while (adapter != NULL)
374  {
375  printf ("Description : %s, Device to use for wpcap: %s\n", adapter->desc,adapter->name);
376  adapter = adapter->next;
377  }
378  }
379 
380  printf("End program\n");
381  return (0);
382 }
ec_groupt ec_group[EC_MAXGROUP]
Definition: ethercatmain.c:108
int ec_reconfig_slave(uint16 slave, int timeout)
char * ec_ALstatuscode2string(uint16 ALstatuscode)
void CALLBACK RTthread(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
#define EC_TIMEOUTMON
uint32 Obytes
Definition: ethercatmain.h:160
Headerfile for ethercatdc.c.
int ec_readstate(void)
int ec_send_processdata(void)
#define EC_TIMEOUTSTATE
Definition: ethercattype.h:102
PACKED_END ec_slavet ec_slave[EC_MAXSLAVE]
Definition: ethercatmain.c:104
int main(int argc, char *argv[])
char name[EC_MAXLEN_ADAPTERNAME]
Definition: ethercatmain.h:79
int(* PO2SOconfig)(uint16 slave)
Definition: ethercatmain.h:262
#define EC_TIMEOUTSAFE
Definition: ethercattype.h:94
char ifbuf[1024]
uint8_t uint8
Definition: osal.h:33
char IOmap[4096]
int ec_recover_slave(uint16 slave, int timeout)
ec_adaptert * next
Definition: ethercatmain.h:81
int ec_receive_processdata(int timeout)
uint16_t uint16
Definition: osal.h:34
int64 ec_DCtime
Definition: ethercatmain.c:132
char * ec_elist2string(void)
#define EC_TIMEOUTRXM
Definition: ethercattype.h:100
General typedefs and defines for EtherCAT.
Headerfile for ethercatcoe.c.
#define TRUE
Definition: osal.h:28
int ec_config_map(void *pIOmap)
volatile int wkc
char desc[EC_MAXLEN_ADAPTERNAME]
Definition: ethercatmain.h:80
boolean islost
Definition: ethercatmain.h:260
int ec_init(char *ifname)
void simpletest(char *ifname)
Headerfile for ethercatfoe.c.
boolean docheckstate
Definition: ethercatmain.h:299
int slave
Definition: aliastool.c:51
#define FALSE
Definition: osal.h:29
int EL7031setup(uint16 slave)
boolean EcatError
Definition: ethercatmain.c:130
#define EC_TIMEOUTRET
Definition: ethercattype.h:90
int ec_writestate(uint16 slave)
#define ECT_COEDET_SDOCA
Definition: ethercatmain.h:132
Headerfile for ethercatbase.c.
uint8 CoEdetails
Definition: ethercatmain.h:244
boolean ec_configdc(void)
Definition: ethercatdc.c:456
uint16 outputsWKC
Definition: ethercatmain.h:295
Headerfile for ethercatmain.c.
ec_adaptert * ec_find_adapters(void)
Definition: ethercatmain.c:165
uint32 Ibytes
Definition: ethercatmain.h:168
uint16 state
Definition: ethercatmain.h:140
int osal_usleep(uint32 usec)
Definition: linux/osal.c:28
void ec_close(void)
int AEPsetup(uint16 slave)
uint16 ec_statecheck(uint16 slave, uint16 reqstate, int timeout)
int ec_slavecount
Definition: ethercatmain.c:106
Headerfile for ethercatconfig.c.
int ec_SDOwrite(uint16 Slave, uint16 Index, uint8 SubIndex, boolean CA, int psize, void *p, int Timeout)
Definition: ethercatcoe.c:1353
int ec_config_init(uint8 usetable)
DWORD WINAPI ecatcheck(LPVOID lpParam)
volatile int rtcnt
Headerfile for ethercatprint.c.


soem
Author(s): Arthur Ketels and M.J.G. van den Molengraft
autogenerated on Sat Jun 8 2019 18:02:17