ethercatfoe.c
Go to the documentation of this file.
00001 /*
00002  * Simple Open EtherCAT Master Library 
00003  *
00004  * File    : ethercatfoe.c
00005  * Version : 1.2.5
00006  * Date    : 09-04-2011
00007  * Copyright (C) 2005-2011 Speciaal Machinefabriek Ketels v.o.f.
00008  * Copyright (C) 2005-2011 Arthur Ketels
00009  * Copyright (C) 2008-2009 TU/e Technische Universiteit Eindhoven 
00010  *
00011  * SOEM is free software; you can redistribute it and/or modify it under
00012  * the terms of the GNU General Public License version 2 as published by the Free
00013  * Software Foundation.
00014  *
00015  * SOEM is distributed in the hope that it will be useful, but WITHOUT ANY
00016  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00017  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00018  * for more details.
00019  *
00020  * As a special exception, if other files instantiate templates or use macros
00021  * or inline functions from this file, or you compile this file and link it
00022  * with other works to produce a work based on this file, this file does not
00023  * by itself cause the resulting work to be covered by the GNU General Public
00024  * License. However the source code for this file must still be made available
00025  * in accordance with section (3) of the GNU General Public License.
00026  *
00027  * This exception does not invalidate any other reasons why a work based on
00028  * this file might be covered by the GNU General Public License.
00029  *
00030  * The EtherCAT Technology, the trade name and logo “EtherCAT” are the intellectual
00031  * property of, and protected by Beckhoff Automation GmbH. You can use SOEM for
00032  * the sole purpose of creating, using and/or selling or otherwise distributing
00033  * an EtherCAT network master provided that an EtherCAT Master License is obtained
00034  * from Beckhoff Automation GmbH.
00035  *
00036  * In case you did not receive a copy of the EtherCAT Master License along with
00037  * SOEM write to Beckhoff Automation GmbH, Eiserstraße 5, D-33415 Verl, Germany
00038  * (www.beckhoff.com).
00039  *
00040  * 14-06-2010 : fixed bug in FOEread() by Torsten Bitterlich
00041  */
00042 
00050 #include <stdio.h>
00051 #include <string.h>
00052 #include <sys/time.h>
00053 #include <unistd.h>
00054 #include <youbot_driver/soem/ethercattype.h>
00055 #include <youbot_driver/soem/nicdrv.h>
00056 #include <youbot_driver/soem/ethercatbase.h>
00057 #include <youbot_driver/soem/ethercatmain.h>
00058 #include <youbot_driver/soem/ethercatfoe.h>
00059 
00060 #define EC_MAXFOEDATA 512
00061 
00065 typedef struct
00066   PACKED
00067   {
00068     ec_mbxheadert MbxHeader;
00069     uint8 OpCode;
00070     uint8 Reserved;
00071     union
00072     {
00073       uint32 Password;
00074       uint32 PacketNumber;
00075       uint32 ErrorCode;
00076     };
00077     union
00078     {
00079       char FileName[EC_MAXFOEDATA];
00080       uint8 Data[EC_MAXFOEDATA];
00081       char ErrorText[EC_MAXFOEDATA];
00082     };
00083   } ec_FOEt;
00084 
00095   int ec_FOEread(uint16 slave, char *filename, uint32 password, int *psize, void *p, int timeout)
00096   {
00097     ec_FOEt *FOEp, *aFOEp;
00098     int wkc;
00099     int32 dataread = 0;
00100     int32 buffersize, packetnumber, prevpacket = 0;
00101     uint16 fnsize, maxdata, segmentdata;
00102     ec_mbxbuft MbxIn, MbxOut;
00103     uint8 cnt;
00104     boolean worktodo;
00105 
00106     buffersize = *psize;
00107     ec_clearmbx(&MbxIn);
00108     /* Empty slave out mailbox if something is in. Timout set to 0 */
00109     wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, 0);
00110     ec_clearmbx(&MbxOut);
00111     aFOEp = (ec_FOEt *)&MbxIn;
00112     FOEp = (ec_FOEt *)&MbxOut;
00113     fnsize = strlen(filename);
00114     maxdata = ec_slave[slave].mbx_l - 12;
00115     if (fnsize > maxdata)
00116       fnsize = maxdata;
00117     FOEp->MbxHeader.length = htoes(0x0006 + fnsize);
00118     FOEp->MbxHeader.address = htoes(0x0000);
00119     FOEp->MbxHeader.priority = 0x00;
00120     /* get new mailbox count value, used as session handle */
00121     cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00122     ec_slave[slave].mbx_cnt = cnt;
00123     FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
00124     FOEp->OpCode = ECT_FOE_READ;
00125     FOEp->Password = htoel(password);
00126     /* copy filename in mailbox */
00127     memcpy(&FOEp->FileName[0], filename, fnsize);
00128     /* send FoE request to slave */
00129     wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00130     if (wkc > 0) /* succeeded to place mailbox in slave ? */
00131     {
00132       do
00133       {
00134         worktodo = FALSE;
00135         /* clean mailboxbuffer */
00136         ec_clearmbx(&MbxIn);
00137         /* read slave response */
00138         wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00139         if (wkc > 0) /* succeeded to read slave response ? */
00140         {
00141           /* slave response should be FoE */
00142           if ((aFOEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_FOE)
00143           {
00144             if (aFOEp->OpCode == ECT_FOE_DATA)
00145             {
00146               segmentdata = etohs(aFOEp->MbxHeader.length) - 0x0006;
00147               packetnumber = etohl(aFOEp->PacketNumber);
00148               if ((packetnumber == ++prevpacket) && (dataread + segmentdata <= buffersize))
00149               {
00150                 memcpy(p, &aFOEp->Data[0], segmentdata);
00151                 dataread += segmentdata;
00152                 p += segmentdata;
00153                 if (segmentdata == maxdata)
00154                   worktodo = TRUE;
00155                 FOEp->MbxHeader.length = htoes(0x0006);
00156                 FOEp->MbxHeader.address = htoes(0x0000);
00157                 FOEp->MbxHeader.priority = 0x00;
00158                 /* get new mailbox count value */
00159                 cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00160                 ec_slave[slave].mbx_cnt = cnt;
00161                 FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
00162                 FOEp->OpCode = ECT_FOE_ACK;
00163                 FOEp->PacketNumber = htoel(packetnumber);
00164                 /* send FoE ack to slave */
00165                 wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00166                 if (wkc <= 0)
00167                   worktodo = FALSE;
00168               }
00169               else
00170               {
00171                 /* FoE error */
00172                 wkc = -EC_ERR_TYPE_FOE_BUF2SMALL;
00173               }
00174             }
00175             else if (aFOEp->OpCode == ECT_FOE_ERROR)
00176             {
00177               /* FoE error */
00178               wkc = -EC_ERR_TYPE_FOE_ERROR;
00179             }
00180             else
00181             {
00182               /* unexpected mailbox received */
00183               wkc = -EC_ERR_TYPE_PACKET_ERROR;
00184             }
00185           }
00186           else
00187           {
00188             /* unexpected mailbox received */
00189             wkc = -EC_ERR_TYPE_PACKET_ERROR;
00190           }
00191           *psize = dataread;
00192         }
00193       } while (worktodo);
00194     }
00195 
00196     return wkc;
00197   }
00198 
00209   int ec_FOEwrite(uint16 slave, char *filename, uint32 password, int psize, void *p, int timeout)
00210   {
00211     ec_FOEt *FOEp, *aFOEp;
00212     int wkc;
00213     int32 packetnumber, sendpacket = 0;
00214     uint16 fnsize, maxdata;
00215     int segmentdata;
00216     ec_mbxbuft MbxIn, MbxOut;
00217     uint8 cnt;
00218     boolean worktodo;
00219     int tsize;
00220 
00221     ec_clearmbx(&MbxIn);
00222     /* Empty slave out mailbox if something is in. Timout set to 0 */
00223     wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, 0);
00224     ec_clearmbx(&MbxOut);
00225     aFOEp = (ec_FOEt *)&MbxIn;
00226     FOEp = (ec_FOEt *)&MbxOut;
00227     fnsize = strlen(filename);
00228     maxdata = ec_slave[slave].mbx_l - 12;
00229     if (fnsize > maxdata)
00230       fnsize = maxdata;
00231     FOEp->MbxHeader.length = htoes(0x0006 + fnsize);
00232     FOEp->MbxHeader.address = htoes(0x0000);
00233     FOEp->MbxHeader.priority = 0x00;
00234     /* get new mailbox count value, used as session handle */
00235     cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00236     ec_slave[slave].mbx_cnt = cnt;
00237     FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
00238     FOEp->OpCode = ECT_FOE_WRITE;
00239     FOEp->Password = htoel(password);
00240     /* copy filename in mailbox */
00241     memcpy(&FOEp->FileName[0], filename, fnsize);
00242     /* send FoE request to slave */
00243     wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00244     if (wkc > 0) /* succeeded to place mailbox in slave ? */
00245     {
00246       do
00247       {
00248         worktodo = FALSE;
00249         /* clean mailboxbuffer */
00250         ec_clearmbx(&MbxIn);
00251         /* read slave response */
00252         wkc = ec_mbxreceive(slave, (ec_mbxbuft *)&MbxIn, timeout);
00253         if (wkc > 0) /* succeeded to read slave response ? */
00254         {
00255           /* slave response should be FoE */
00256           if ((aFOEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_FOE)
00257           {
00258             if (aFOEp->OpCode == ECT_FOE_ACK)
00259             {
00260               packetnumber = etohl(aFOEp->PacketNumber);
00261               if (packetnumber == sendpacket)
00262               {
00263                 tsize = psize;
00264                 if (tsize > maxdata)
00265                 {
00266                   worktodo = TRUE;
00267                   tsize = maxdata;
00268                 }
00269                 segmentdata = tsize;
00270                 psize -= segmentdata;
00271                 FOEp->MbxHeader.length = htoes(0x0006 + segmentdata);
00272                 FOEp->MbxHeader.address = htoes(0x0000);
00273                 FOEp->MbxHeader.priority = 0x00;
00274                 /* get new mailbox count value */
00275                 cnt = ec_nextmbxcnt(ec_slave[slave].mbx_cnt);
00276                 ec_slave[slave].mbx_cnt = cnt;
00277                 FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
00278                 FOEp->OpCode = ECT_FOE_DATA;
00279                 FOEp->PacketNumber = htoel(++sendpacket);
00280                 memcpy(&FOEp->Data[0], p, segmentdata);
00281                 p += segmentdata;
00282                 /* send FoE data to slave */
00283                 wkc = ec_mbxsend(slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
00284                 if (wkc <= 0)
00285                   worktodo = FALSE;
00286               }
00287               else
00288               {
00289                 /* FoE error */
00290                 wkc = -EC_ERR_TYPE_FOE_PACKETNUMBER;
00291               }
00292             }
00293             else if (aFOEp->OpCode == ECT_FOE_ERROR)
00294             {
00295               /* FoE error */
00296               wkc = -EC_ERR_TYPE_FOE_ERROR;
00297             }
00298             else
00299             {
00300               /* unexpected mailbox received */
00301               wkc = -EC_ERR_TYPE_PACKET_ERROR;
00302             }
00303           }
00304           else
00305           {
00306             /* unexpected mailbox received */
00307             wkc = -EC_ERR_TYPE_PACKET_ERROR;
00308           }
00309         }
00310       } while (worktodo);
00311     }
00312 
00313     return wkc;
00314   }


youbot_driver
Author(s): Jan Paulus
autogenerated on Mon Oct 6 2014 09:08:01