ethercatbase.c
Go to the documentation of this file.
00001 /*
00002  * Simple Open EtherCAT Master Library 
00003  *
00004  * File    : ethercatbase.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 
00052 #include <stdio.h>
00053 #include <string.h>
00054 #include <youbot_driver/soem/ethercattype.h>
00055 #include <youbot_driver/soem/nicdrv.h>
00056 #include <youbot_driver/soem/ethercatbase.h>
00057 
00069 int ec_setupdatagram(void *frame, uint8 com, uint8 idx, uint16 ADP, uint16 ADO, uint16 length, void *data)
00070 {
00071   ec_comt *datagramP;
00072   uint8 *frameP;
00073 
00074   frameP = frame;
00075   /* Ethernet header is preset and fixed in frame buffers
00076    EtherCAT header needs to be added after that */
00077   datagramP = (ec_comt*)&frameP[ETH_HEADERSIZE];
00078   datagramP->elength = htoes(EC_ECATTYPE + EC_HEADERSIZE + length);
00079   datagramP->command = com;
00080   datagramP->index = idx;
00081   datagramP->ADP = htoes(ADP);
00082   datagramP->ADO = htoes(ADO);
00083   datagramP->dlength = htoes(length);
00084   if (length > 0)
00085   {
00086     memcpy(&frameP[ETH_HEADERSIZE+ EC_HEADERSIZE], data, length);
00087   }
00088     /* set WKC to zero */
00089   frameP[ETH_HEADERSIZE+ EC_HEADERSIZE + length] = 0x00;
00090   frameP[ETH_HEADERSIZE+ EC_HEADERSIZE + length + 1] = 0x00;
00091   /* set size of frame in buffer array */
00092   ec_txbuflength[idx] = ETH_HEADERSIZE+ EC_HEADERSIZE + EC_WKCSIZE + length;
00093 
00094   return 0;
00095 }
00096 
00109 int ec_adddatagram(void *frame, uint8 com, uint8 idx, boolean more, uint16 ADP, uint16 ADO, uint16 length, void *data)
00110 {
00111   ec_comt *datagramP;
00112   uint8 *frameP;
00113   uint16 prevlength;
00114 
00115   frameP = frame;
00116   /* copy previous frame size */
00117   prevlength = ec_txbuflength[idx];
00118   datagramP = (ec_comt*)&frameP[ETH_HEADERSIZE];
00119   /* add new datagram to ethernet frame size */
00120   datagramP->elength = htoes( etohs(datagramP->elength) + EC_HEADERSIZE + length );
00121   /* add "datagram follows" flag to previous subframe dlength */
00122   datagramP->dlength = htoes( etohs(datagramP->dlength) | EC_DATAGRAMFOLLOWS );
00123   /* set new EtherCAT header position */
00124   datagramP = (ec_comt*)&frameP[prevlength - EC_ELENGTHSIZE];
00125   datagramP->command = com;
00126   datagramP->index = idx;
00127   datagramP->ADP = htoes(ADP);
00128   datagramP->ADO = htoes(ADO);
00129   if (more)
00130   {
00131     /* this is not the last datagram to add */
00132     datagramP->dlength = htoes(length | EC_DATAGRAMFOLLOWS);
00133   }
00134   else
00135   {
00136     /* this is the last datagram in the frame */
00137     datagramP->dlength = htoes(length);
00138   }
00139   if (length > 0)
00140   {
00141     memcpy(&frameP[prevlength + EC_HEADERSIZE- EC_ELENGTHSIZE], data, length);
00142   }
00143     /* set WKC to zero */
00144   frameP[prevlength + EC_HEADERSIZE- EC_ELENGTHSIZE + length] = 0x00;
00145   frameP[prevlength + EC_HEADERSIZE- EC_ELENGTHSIZE + length + 1] = 0x00;
00146   /* set size of frame in buffer array */
00147   ec_txbuflength[idx] = prevlength + EC_HEADERSIZE- EC_ELENGTHSIZE + EC_WKCSIZE + length;
00148 
00149   /* return offset to data in rx frame
00150    14 bytes smaller than tx frame due to stripping of ethernet header */
00151   return prevlength + EC_HEADERSIZE- EC_ELENGTHSIZE - ETH_HEADERSIZE;
00152 }
00153 
00163 int ec_BWR(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
00164 {
00165   uint8 idx;
00166   int wkc;
00167 
00168   /* get fresh index */
00169   idx = ec_getindex();
00170   /* setup datagram */
00171   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_BWR, idx, ADP, ADO, length, data);
00172   /* send data and wait for answer */
00173   wkc = ec_srconfirm(idx, timeout);
00174   /* clear buffer status */
00175   ec_setbufstat(idx, EC_BUF_EMPTY);
00176 
00177   return wkc;
00178 }
00179 
00189 int ec_BRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
00190 {
00191   uint8 idx;
00192   int wkc;
00193 
00194   /* get fresh index */
00195   idx = ec_getindex();
00196   /* setup datagram */
00197   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_BRD, idx, ADP, ADO, length, data);
00198   /* send data and wait for answer */
00199   wkc = ec_srconfirm(idx, timeout);
00200   if (wkc > 0)
00201   {
00202     /* copy datagram to data buffer */
00203     memcpy(data, &ec_rxbuf[idx][EC_HEADERSIZE], length);
00204   }
00205     /* clear buffer status */
00206   ec_setbufstat(idx, EC_BUF_EMPTY);
00207 
00208   return wkc;
00209 }
00210 
00220 int ec_APRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
00221 {
00222   int wkc;
00223   uint8 idx;
00224 
00225   idx = ec_getindex();
00226   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_APRD, idx, ADP, ADO, length, data);
00227   wkc = ec_srconfirm(idx, timeout);
00228   if (wkc > 0)
00229   {
00230     memcpy(data, &ec_rxbuf[idx][EC_HEADERSIZE], length);
00231   }
00232   ec_setbufstat(idx, EC_BUF_EMPTY);
00233 
00234   return wkc;
00235 }
00236 
00247 int ec_ARMW(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
00248 {
00249   int wkc;
00250   uint8 idx;
00251 
00252   idx = ec_getindex();
00253   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_ARMW, idx, ADP, ADO, length, data);
00254   wkc = ec_srconfirm(idx, timeout);
00255   if (wkc > 0)
00256   {
00257     memcpy(data, &ec_rxbuf[idx][EC_HEADERSIZE], length);
00258   }
00259   ec_setbufstat(idx, EC_BUF_EMPTY);
00260 
00261   return wkc;
00262 }
00263 
00274 int ec_FRMW(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
00275 {
00276   int wkc;
00277   uint8 idx;
00278 
00279   idx = ec_getindex();
00280   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_FRMW, idx, ADP, ADO, length, data);
00281   wkc = ec_srconfirm(idx, timeout);
00282   if (wkc > 0)
00283   {
00284     memcpy(data, &ec_rxbuf[idx][EC_HEADERSIZE], length);
00285   }
00286   ec_setbufstat(idx, EC_BUF_EMPTY);
00287 
00288   return wkc;
00289 }
00290 
00298 uint16 ec_APRDw(uint16 ADP, uint16 ADO, int timeout)
00299 {
00300   uint16 w;
00301 
00302   w = 0;
00303   ec_APRD(ADP, ADO, sizeof(w), &w, timeout);
00304 
00305   return w;
00306 }
00307 
00317 int ec_FPRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
00318 {
00319   int wkc;
00320   uint8 idx;
00321 
00322   idx = ec_getindex();
00323   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_FPRD, idx, ADP, ADO, length, data);
00324   wkc = ec_srconfirm(idx, timeout);
00325   if (wkc > 0)
00326   {
00327     memcpy(data, &ec_rxbuf[idx][EC_HEADERSIZE], length);
00328   }
00329   ec_setbufstat(idx, EC_BUF_EMPTY);
00330 
00331   return wkc;
00332 }
00333 
00341 uint16 ec_FPRDw(uint16 ADP, uint16 ADO, int16 timeout)
00342 {
00343   uint16 w;
00344 
00345   w = 0;
00346   ec_FPRD(ADP, ADO, sizeof(w), &w, timeout);
00347   return w;
00348 }
00349 
00358 int ec_APWRw(uint16 ADP, uint16 ADO, uint16 data, int timeout)
00359 {
00360   return ec_APWR(ADP, ADO, sizeof(data), &data, timeout);
00361 }
00362 
00372 int ec_APWR(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
00373 {
00374   uint8 idx;
00375   int wkc;
00376 
00377   idx = ec_getindex();
00378   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_APWR, idx, ADP, ADO, length, data);
00379   wkc = ec_srconfirm(idx, timeout);
00380   ec_setbufstat(idx, EC_BUF_EMPTY);
00381 
00382   return wkc;
00383 }
00384 
00393 int ec_FPWRw(uint16 ADP, uint16 ADO, uint16 data, int timeout)
00394 {
00395   return ec_FPWR(ADP, ADO, sizeof(data), &data, timeout);
00396 }
00397 
00407 int ec_FPWR(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout)
00408 {
00409   int wkc;
00410   uint8 idx;
00411 
00412   idx = ec_getindex();
00413   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_FPWR, idx, ADP, ADO, length, data);
00414   wkc = ec_srconfirm(idx, timeout);
00415   ec_setbufstat(idx, EC_BUF_EMPTY);
00416 
00417   return wkc;
00418 }
00419 
00428 int ec_LRW(uint32 LogAdr, uint16 length, void *data, int timeout)
00429 {
00430   uint8 idx;
00431   int wkc;
00432 
00433   idx = ec_getindex();
00434   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_LRW, idx, LO_WORD(LogAdr), HI_WORD(LogAdr), length, data);
00435   wkc = ec_srconfirm(idx, timeout);
00436   if ((wkc > 0) && (ec_rxbuf[idx][EC_CMDOFFSET] == EC_CMD_LRW))
00437   {
00438     memcpy(data, &ec_rxbuf[idx][EC_HEADERSIZE], length);
00439   }
00440   ec_setbufstat(idx, EC_BUF_EMPTY);
00441 
00442   return wkc;
00443 }
00444 
00453 int ec_LRD(uint32 LogAdr, uint16 length, void *data, int timeout)
00454 {
00455   uint8 idx;
00456   int wkc;
00457 
00458   idx = ec_getindex();
00459   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_LRD, idx, LO_WORD(LogAdr), HI_WORD(LogAdr), length, data);
00460   wkc = ec_srconfirm(idx, timeout);
00461   if ((wkc > 0) && (ec_rxbuf[idx][EC_CMDOFFSET]==EC_CMD_LRD))
00462   {
00463     memcpy(data, &ec_rxbuf[idx][EC_HEADERSIZE], length);
00464   }
00465   ec_setbufstat(idx, EC_BUF_EMPTY);
00466 
00467   return wkc;
00468 }
00469 
00478 int ec_LWR(uint32 LogAdr, uint16 length, void *data, int timeout)
00479 {
00480   uint8 idx;
00481   int wkc;
00482 
00483   idx = ec_getindex();
00484   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_LWR, idx, LO_WORD(LogAdr), HI_WORD(LogAdr), length, data);
00485   wkc = ec_srconfirm(idx, timeout);
00486   ec_setbufstat(idx, EC_BUF_EMPTY);
00487 
00488   return wkc;
00489 }
00490 
00502 int ec_LRWDC(uint32 LogAdr, uint16 length, void *data, uint16 DCrs, int64 *DCtime, int timeout)
00503 {
00504   uint16 DCtO;
00505   uint8 idx;
00506   int wkc;
00507   uint64 DCtE;
00508 
00509   idx = ec_getindex();
00510   /* LRW in first datagram */
00511   ec_setupdatagram(&ec_txbuf[idx], EC_CMD_LRW, idx, LO_WORD(LogAdr), HI_WORD(LogAdr), length, data);
00512   /* FPRMW in second datagram */
00513   DCtE = htoell(*DCtime);
00514   DCtO = ec_adddatagram(&ec_txbuf[idx], EC_CMD_FRMW, idx, FALSE, DCrs, ECT_REG_DCSYSTIME, sizeof(DCtime), &DCtE);
00515   wkc = ec_srconfirm(idx, timeout);
00516   if ((wkc > 0) && (ec_rxbuf[idx][EC_CMDOFFSET] == EC_CMD_LRW))
00517   {
00518     memcpy(data, &ec_rxbuf[idx][EC_HEADERSIZE], length);
00519     memcpy(&wkc, &ec_rxbuf[idx][EC_HEADERSIZE + length], EC_WKCSIZE);
00520     memcpy(&DCtE, &ec_rxbuf[idx][DCtO], sizeof(*DCtime));
00521     *DCtime = etohll(DCtE);
00522   }
00523   ec_setbufstat(idx, EC_BUF_EMPTY);
00524 
00525   return wkc;
00526 }


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