ethercatfoe.c
Go to the documentation of this file.
1 /*
2  * Simple Open EtherCAT Master Library
3  *
4  * File : ethercatfoe.c
5  * Version : 1.3.0
6  * Date : 24-02-2013
7  * Copyright (C) 2005-2013 Speciaal Machinefabriek Ketels v.o.f.
8  * Copyright (C) 2005-2013 Arthur Ketels
9  * Copyright (C) 2008-2009 TU/e Technische Universiteit Eindhoven
10  *
11  * SOEM is free software; you can redistribute it and/or modify it under
12  * the terms of the GNU General Public License version 2 as published by the Free
13  * Software Foundation.
14  *
15  * SOEM is distributed in the hope that it will be useful, but WITHOUT ANY
16  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18  * for more details.
19  *
20  * As a special exception, if other files instantiate templates or use macros
21  * or inline functions from this file, or you compile this file and link it
22  * with other works to produce a work based on this file, this file does not
23  * by itself cause the resulting work to be covered by the GNU General Public
24  * License. However the source code for this file must still be made available
25  * in accordance with section (3) of the GNU General Public License.
26  *
27  * This exception does not invalidate any other reasons why a work based on
28  * this file might be covered by the GNU General Public License.
29  *
30  * The EtherCAT Technology, the trade name and logo “EtherCAT” are the intellectual
31  * property of, and protected by Beckhoff Automation GmbH. You can use SOEM for
32  * the sole purpose of creating, using and/or selling or otherwise distributing
33  * an EtherCAT network master provided that an EtherCAT Master License is obtained
34  * from Beckhoff Automation GmbH.
35  *
36  * In case you did not receive a copy of the EtherCAT Master License along with
37  * SOEM write to Beckhoff Automation GmbH, Eiserstraße 5, D-33415 Verl, Germany
38  * (www.beckhoff.com).
39  *
40  * 14-06-2010 : fixed bug in FOEread() by Torsten Bitterlich
41  */
42 
50 #include <stdio.h>
51 #include <string.h>
52 #include "osal.h"
53 #include "oshw.h"
54 #include "ethercattype.h"
55 #include "ethercatbase.h"
56 #include "ethercatmain.h"
57 #include "ethercatfoe.h"
58 
59 #define EC_MAXFOEDATA 512
60 
64 PACKED_BEGIN
65 typedef struct PACKED
66 {
70  union
71  {
75  };
76  union
77  {
81  };
82 } ec_FOEt;
83 PACKED_END
84 
91 int ecx_FOEdefinehook(ecx_contextt *context, void *hook)
92 {
93  context->FOEhook = hook;
94  return 1;
95 }
96 
108 int ecx_FOEread(ecx_contextt *context, uint16 slave, char *filename, uint32 password, int *psize, void *p, int timeout)
109 {
110  ec_FOEt *FOEp, *aFOEp;
111  int wkc;
112  int32 dataread = 0;
113  int32 buffersize, packetnumber, prevpacket = 0;
114  uint16 fnsize, maxdata, segmentdata;
115  ec_mbxbuft MbxIn, MbxOut;
116  uint8 cnt;
117  boolean worktodo;
118 
119  buffersize = *psize;
120  ec_clearmbx(&MbxIn);
121  /* Empty slave out mailbox if something is in. Timout set to 0 */
122  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
123  ec_clearmbx(&MbxOut);
124  aFOEp = (ec_FOEt *)&MbxIn;
125  FOEp = (ec_FOEt *)&MbxOut;
126  fnsize = strlen(filename);
127  maxdata = context->slavelist[slave].mbx_l - 12;
128  if (fnsize > maxdata)
129  {
130  fnsize = maxdata;
131  }
132  FOEp->MbxHeader.length = htoes(0x0006 + fnsize);
133  FOEp->MbxHeader.address = htoes(0x0000);
134  FOEp->MbxHeader.priority = 0x00;
135  /* get new mailbox count value, used as session handle */
136  cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
137  context->slavelist[slave].mbx_cnt = cnt;
138  FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
139  FOEp->OpCode = ECT_FOE_READ;
140  FOEp->Password = htoel(password);
141  /* copy filename in mailbox */
142  memcpy(&FOEp->FileName[0], filename, fnsize);
143  /* send FoE request to slave */
144  wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
145  if (wkc > 0) /* succeeded to place mailbox in slave ? */
146  {
147  do
148  {
149  worktodo = FALSE;
150  /* clean mailboxbuffer */
151  ec_clearmbx(&MbxIn);
152  /* read slave response */
153  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
154  if (wkc > 0) /* succeeded to read slave response ? */
155  {
156  /* slave response should be FoE */
157  if ((aFOEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_FOE)
158  {
159  if(aFOEp->OpCode == ECT_FOE_DATA)
160  {
161  segmentdata = etohs(aFOEp->MbxHeader.length) - 0x0006;
162  packetnumber = etohl(aFOEp->PacketNumber);
163  if ((packetnumber == ++prevpacket) && (dataread + segmentdata <= buffersize))
164  {
165  memcpy(p, &aFOEp->Data[0], segmentdata);
166  dataread += segmentdata;
167  p = (uint8 *)p + segmentdata;
168  if (segmentdata == maxdata)
169  {
170  worktodo = TRUE;
171  }
172  FOEp->MbxHeader.length = htoes(0x0006);
173  FOEp->MbxHeader.address = htoes(0x0000);
174  FOEp->MbxHeader.priority = 0x00;
175  /* get new mailbox count value */
176  cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
177  context->slavelist[slave].mbx_cnt = cnt;
178  FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
179  FOEp->OpCode = ECT_FOE_ACK;
180  FOEp->PacketNumber = htoel(packetnumber);
181  /* send FoE ack to slave */
182  wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
183  if (wkc <= 0)
184  {
185  worktodo = FALSE;
186  }
187  if (context->FOEhook)
188  {
189  context->FOEhook(slave, packetnumber, dataread);
190  }
191  }
192  else
193  {
194  /* FoE error */
196  }
197  }
198  else
199  {
200  if(aFOEp->OpCode == ECT_FOE_ERROR)
201  {
202  /* FoE error */
203  wkc = -EC_ERR_TYPE_FOE_ERROR;
204  }
205  else
206  {
207  /* unexpected mailbox received */
209  }
210  }
211  }
212  else
213  {
214  /* unexpected mailbox received */
216  }
217  *psize = dataread;
218  }
219  } while (worktodo);
220  }
221 
222  return wkc;
223 }
224 
236 int ecx_FOEwrite(ecx_contextt *context, uint16 slave, char *filename, uint32 password, int psize, void *p, int timeout)
237 {
238  ec_FOEt *FOEp, *aFOEp;
239  int wkc;
240  int32 packetnumber, sendpacket = 0;
241  uint16 fnsize, maxdata;
242  int segmentdata;
243  ec_mbxbuft MbxIn, MbxOut;
244  uint8 cnt;
245  boolean worktodo, dofinalzero;
246  int tsize;
247 
248  ec_clearmbx(&MbxIn);
249  /* Empty slave out mailbox if something is in. Timout set to 0 */
250  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
251  ec_clearmbx(&MbxOut);
252  aFOEp = (ec_FOEt *)&MbxIn;
253  FOEp = (ec_FOEt *)&MbxOut;
254  dofinalzero = FALSE;
255  fnsize = strlen(filename);
256  maxdata = context->slavelist[slave].mbx_l - 12;
257  if (fnsize > maxdata)
258  {
259  fnsize = maxdata;
260  }
261  FOEp->MbxHeader.length = htoes(0x0006 + fnsize);
262  FOEp->MbxHeader.address = htoes(0x0000);
263  FOEp->MbxHeader.priority = 0x00;
264  /* get new mailbox count value, used as session handle */
265  cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
266  context->slavelist[slave].mbx_cnt = cnt;
267  FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
268  FOEp->OpCode = ECT_FOE_WRITE;
269  FOEp->Password = htoel(password);
270  /* copy filename in mailbox */
271  memcpy(&FOEp->FileName[0], filename, fnsize);
272  /* send FoE request to slave */
273  wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
274  if (wkc > 0) /* succeeded to place mailbox in slave ? */
275  {
276  do
277  {
278  worktodo = FALSE;
279  /* clean mailboxbuffer */
280  ec_clearmbx(&MbxIn);
281  /* read slave response */
282  wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
283  if (wkc > 0) /* succeeded to read slave response ? */
284  {
285  /* slave response should be FoE */
286  if ((aFOEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_FOE)
287  {
288  switch (aFOEp->OpCode)
289  {
290  case ECT_FOE_ACK:
291  {
292  packetnumber = etohl(aFOEp->PacketNumber);
293  if (packetnumber == sendpacket)
294  {
295  if (context->FOEhook)
296  {
297  context->FOEhook(slave, packetnumber, psize);
298  }
299  tsize = psize;
300  if (tsize > maxdata)
301  {
302  tsize = maxdata;
303  }
304  if(tsize || dofinalzero)
305  {
306  worktodo = TRUE;
307  dofinalzero = FALSE;
308  segmentdata = tsize;
309  psize -= segmentdata;
310  /* if last packet was full size, add a zero size packet as final */
311  /* EOF is defined as packetsize < full packetsize */
312  if (!psize && (segmentdata == maxdata))
313  {
314  dofinalzero = TRUE;
315  }
316  FOEp->MbxHeader.length = htoes(0x0006 + segmentdata);
317  FOEp->MbxHeader.address = htoes(0x0000);
318  FOEp->MbxHeader.priority = 0x00;
319  /* get new mailbox count value */
320  cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
321  context->slavelist[slave].mbx_cnt = cnt;
322  FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
323  FOEp->OpCode = ECT_FOE_DATA;
324  sendpacket++;
325  FOEp->PacketNumber = htoel(sendpacket);
326  memcpy(&FOEp->Data[0], p, segmentdata);
327  p = (uint8 *)p + segmentdata;
328  /* send FoE data to slave */
329  wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
330  if (wkc <= 0)
331  {
332  worktodo = FALSE;
333  }
334  }
335  }
336  else
337  {
338  /* FoE error */
340  }
341  break;
342  }
343  case ECT_FOE_BUSY:
344  {
345  /* resend if data has been send before */
346  /* otherwise ignore */
347  if (sendpacket)
348  {
349  if (!psize)
350  {
351  dofinalzero = TRUE;
352  }
353  psize += segmentdata;
354  p = (uint8 *)p - segmentdata;
355  --sendpacket;
356  }
357  break;
358  }
359  case ECT_FOE_ERROR:
360  {
361  /* FoE error */
362  wkc = -EC_ERR_TYPE_FOE_ERROR;
363  break;
364  }
365  default:
366  {
367  /* unexpected mailbox received */
369  }
370  }
371  }
372  else
373  {
374  /* unexpected mailbox received */
376  }
377  }
378  } while (worktodo);
379  }
380 
381  return wkc;
382 }
383 
384 #ifdef EC_VER1
385 int ec_FOEdefinehook(void *hook)
386 {
387  return ecx_FOEdefinehook(&ecx_context, hook);
388 }
389 
390 int ec_FOEread(uint16 slave, char *filename, uint32 password, int *psize, void *p, int timeout)
391 {
392  return ecx_FOEread(&ecx_context, slave, filename, password, psize, p, timeout);
393 }
394 
395 int ec_FOEwrite(uint16 slave, char *filename, uint32 password, int psize, void *p, int timeout)
396 {
397  return ecx_FOEwrite(&ecx_context, slave, filename, password, psize, p, timeout);
398 }
399 #endif
char ErrorText[EC_MAXFOEDATA]
Definition: ethercatfoe.c:80
PACKED_END int ecx_FOEdefinehook(ecx_contextt *context, void *hook)
Definition: ethercatfoe.c:91
ec_slavet * slavelist
Definition: ethercatmain.h:418
#define htoel(A)
Definition: ethercattype.h:548
uint8_t uint8
Definition: osal.h:33
uint16 mbx_l
Definition: ethercatmain.h:188
void ec_clearmbx(ec_mbxbuft *Mbx)
Definition: ethercatmain.c:832
uint16_t uint16
Definition: osal.h:34
uint32 PacketNumber
Definition: ethercatfoe.c:73
char FileName[EC_MAXFOEDATA]
Definition: ethercatfoe.c:78
General typedefs and defines for EtherCAT.
#define etohs(A)
Definition: ethercattype.h:550
#define TRUE
Definition: osal.h:28
PACKED_BEGIN struct PACKED ec_mbxheadert
#define EC_TIMEOUTTXM
Definition: ethercattype.h:98
Headerfile for ethercatfoe.c.
ec_mbxheadert MbxHeader
Definition: ethercatcoe.c:61
#define FALSE
Definition: osal.h:29
int32_t int32
Definition: osal.h:32
uint8 OpCode
Definition: ethercatfoe.c:68
uint8 ec_nextmbxcnt(uint8 cnt)
Definition: ethercatmain.c:818
int(* FOEhook)(uint16 slave, int packetnumber, int datasize)
Definition: ethercatmain.h:456
PACKED_BEGIN struct PACKED ec_FOEt
uint8 mbx_cnt
Definition: ethercatmain.h:198
int ecx_mbxsend(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout)
Definition: ethercatmain.c:878
uint8 Reserved
Definition: ethercatcoe.c:82
uint32 Password
Definition: ethercatfoe.c:72
Headerfile for ethercatbase.c.
#define htoes(A)
Definition: ethercattype.h:547
uint32 ErrorCode
Definition: ethercatfoe.c:74
#define etohl(A)
Definition: ethercattype.h:551
Headerfile for ethercatmain.c.
uint32_t uint32
Definition: osal.h:35
int ecx_FOEwrite(ecx_contextt *context, uint16 slave, char *filename, uint32 password, int psize, void *p, int timeout)
Definition: ethercatfoe.c:236
#define EC_MAXFOEDATA
Definition: ethercatfoe.c:59
uint8 Data[EC_MAXFOEDATA]
Definition: ethercatfoe.c:79
int ecx_mbxreceive(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout)
Definition: ethercatmain.c:911
int ecx_FOEread(ecx_contextt *context, uint16 slave, char *filename, uint32 password, int *psize, void *p, int timeout)
Definition: ethercatfoe.c:108
uint8 ec_mbxbuft[EC_MAXMBX+1]
Definition: ethercatmain.h:341


youbot_driver
Author(s): Jan Paulus
autogenerated on Mon Jun 10 2019 15:46:24