Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: EasyCAT_LAB_simple EasyCAT_LAB_very_simple EasyCAT_LAB
ethercatbase.c
00001 /* 00002 * Licensed under the GNU General Public License version 2 with exceptions. See 00003 * LICENSE file in the project root for full license information 00004 */ 00005 00006 /** \file 00007 * \brief 00008 * Base EtherCAT functions. 00009 * 00010 * Setting up a datagram in an ethernet frame. 00011 * EtherCAT datagram primitives, broadcast, auto increment, configured and 00012 * logical addressed data transfers. All base transfers are blocking, so 00013 * wait for the frame to be returned to the master or timeout. If this is 00014 * not acceptable build your own datagrams and use the functions from nicdrv.c. 00015 */ 00016 00017 #include <stdio.h> 00018 #include <string.h> 00019 #include "oshw.h" 00020 #include "osal.h" 00021 #include "ethercattype.h" 00022 #include "ethercatbase.h" 00023 00024 /** Write data to EtherCAT datagram. 00025 * 00026 * @param[out] datagramdata = data part of datagram 00027 * @param[in] com = command 00028 * @param[in] length = length of databuffer 00029 * @param[in] data = databuffer to be copied into datagram 00030 */ 00031 static void ecx_writedatagramdata(void *datagramdata, ec_cmdtype com, uint16 length, const void * data) 00032 { 00033 if (length > 0) 00034 { 00035 switch (com) 00036 { 00037 case EC_CMD_NOP: 00038 /* Fall-through */ 00039 case EC_CMD_APRD: 00040 /* Fall-through */ 00041 case EC_CMD_FPRD: 00042 /* Fall-through */ 00043 case EC_CMD_BRD: 00044 /* Fall-through */ 00045 case EC_CMD_LRD: 00046 /* no data to write. initialise data so frame is in a known state */ 00047 memset(datagramdata, 0, length); 00048 break; 00049 default: 00050 memcpy(datagramdata, data, length); 00051 break; 00052 } 00053 } 00054 } 00055 00056 /** Generate and set EtherCAT datagram in a standard ethernet frame. 00057 * 00058 * @param[in] port = port context struct 00059 * @param[out] frame = framebuffer 00060 * @param[in] com = command 00061 * @param[in] idx = index used for TX and RX buffers 00062 * @param[in] ADP = Address Position 00063 * @param[in] ADO = Address Offset 00064 * @param[in] length = length of datagram excluding EtherCAT header 00065 * @param[in] data = databuffer to be copied in datagram 00066 * @return always 0 00067 */ 00068 int ecx_setupdatagram(ecx_portt *port, void *frame, uint8 com, uint8 idx, uint16 ADP, uint16 ADO, uint16 length, void *data) 00069 { 00070 ec_comt *datagramP; 00071 uint8 *frameP; 00072 00073 frameP = frame; 00074 /* Ethernet header is preset and fixed in frame buffers 00075 EtherCAT header needs to be added after that */ 00076 datagramP = (ec_comt*)&frameP[ETH_HEADERSIZE]; 00077 datagramP->elength = htoes(EC_ECATTYPE + EC_HEADERSIZE + length); 00078 datagramP->command = com; 00079 datagramP->index = idx; 00080 datagramP->ADP = htoes(ADP); 00081 datagramP->ADO = htoes(ADO); 00082 datagramP->dlength = htoes(length); 00083 ecx_writedatagramdata(&frameP[ETH_HEADERSIZE + EC_HEADERSIZE], com, length, data); 00084 /* set WKC to zero */ 00085 frameP[ETH_HEADERSIZE + EC_HEADERSIZE + length] = 0x00; 00086 frameP[ETH_HEADERSIZE + EC_HEADERSIZE + length + 1] = 0x00; 00087 /* set size of frame in buffer array */ 00088 port->txbuflength[idx] = ETH_HEADERSIZE + EC_HEADERSIZE + EC_WKCSIZE + length; 00089 00090 return 0; 00091 } 00092 00093 /** Add EtherCAT datagram to a standard ethernet frame with existing datagram(s). 00094 * 00095 * @param[in] port = port context struct 00096 * @param[out] frame = framebuffer 00097 * @param[in] com = command 00098 * @param[in] idx = index used for TX and RX buffers 00099 * @param[in] more = TRUE if still more datagrams to follow 00100 * @param[in] ADP = Address Position 00101 * @param[in] ADO = Address Offset 00102 * @param[in] length = length of datagram excluding EtherCAT header 00103 * @param[in] data = databuffer to be copied in datagram 00104 * @return Offset to data in rx frame, usefull to retrieve data after RX. 00105 */ 00106 int ecx_adddatagram(ecx_portt *port, void *frame, uint8 com, uint8 idx, boolean more, uint16 ADP, uint16 ADO, uint16 length, void *data) 00107 { 00108 ec_comt *datagramP; 00109 uint8 *frameP; 00110 uint16 prevlength; 00111 00112 frameP = frame; 00113 /* copy previous frame size */ 00114 prevlength = port->txbuflength[idx]; 00115 datagramP = (ec_comt*)&frameP[ETH_HEADERSIZE]; 00116 /* add new datagram to ethernet frame size */ 00117 datagramP->elength = htoes( etohs(datagramP->elength) + EC_HEADERSIZE + length ); 00118 /* add "datagram follows" flag to previous subframe dlength */ 00119 datagramP->dlength = htoes( etohs(datagramP->dlength) | EC_DATAGRAMFOLLOWS ); 00120 /* set new EtherCAT header position */ 00121 datagramP = (ec_comt*)&frameP[prevlength - EC_ELENGTHSIZE]; 00122 datagramP->command = com; 00123 datagramP->index = idx; 00124 datagramP->ADP = htoes(ADP); 00125 datagramP->ADO = htoes(ADO); 00126 if (more) 00127 { 00128 /* this is not the last datagram to add */ 00129 datagramP->dlength = htoes(length | EC_DATAGRAMFOLLOWS); 00130 } 00131 else 00132 { 00133 /* this is the last datagram in the frame */ 00134 datagramP->dlength = htoes(length); 00135 } 00136 ecx_writedatagramdata(&frameP[prevlength + EC_HEADERSIZE - EC_ELENGTHSIZE], com, length, data); 00137 /* set WKC to zero */ 00138 frameP[prevlength + EC_HEADERSIZE - EC_ELENGTHSIZE + length] = 0x00; 00139 frameP[prevlength + EC_HEADERSIZE - EC_ELENGTHSIZE + length + 1] = 0x00; 00140 /* set size of frame in buffer array */ 00141 port->txbuflength[idx] = prevlength + EC_HEADERSIZE - EC_ELENGTHSIZE + EC_WKCSIZE + length; 00142 00143 /* return offset to data in rx frame 00144 14 bytes smaller than tx frame due to stripping of ethernet header */ 00145 return prevlength + EC_HEADERSIZE - EC_ELENGTHSIZE - ETH_HEADERSIZE; 00146 } 00147 00148 /** BRW "broadcast write" primitive. Blocking. 00149 * 00150 * @param[in] port = port context struct 00151 * @param[in] ADP = Address Position, normally 0 00152 * @param[in] ADO = Address Offset, slave memory address 00153 * @param[in] length = length of databuffer 00154 * @param[in] data = databuffer to be written to slaves 00155 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00156 * @return Workcounter or EC_NOFRAME 00157 */ 00158 int ecx_BWR (ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00159 { 00160 uint8 idx; 00161 int wkc; 00162 00163 /* get fresh index */ 00164 idx = ecx_getindex (port); 00165 /* setup datagram */ 00166 ecx_setupdatagram (port, &(port->txbuf[idx]), EC_CMD_BWR, idx, ADP, ADO, length, data); 00167 /* send data and wait for answer */ 00168 wkc = ecx_srconfirm (port, idx, timeout); 00169 /* clear buffer status */ 00170 ecx_setbufstat (port, idx, EC_BUF_EMPTY); 00171 00172 return wkc; 00173 } 00174 00175 /** BRD "broadcast read" primitive. Blocking. 00176 * 00177 * @param[in] port = port context struct 00178 * @param[in] ADP = Address Position, normally 0 00179 * @param[in] ADO = Address Offset, slave memory address 00180 * @param[in] length = length of databuffer 00181 * @param[out] data = databuffer to put slave data in 00182 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00183 * @return Workcounter or EC_NOFRAME 00184 */ 00185 int ecx_BRD(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00186 { 00187 uint8 idx; 00188 int wkc; 00189 00190 /* get fresh index */ 00191 idx = ecx_getindex(port); 00192 /* setup datagram */ 00193 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_BRD, idx, ADP, ADO, length, data); 00194 /* send data and wait for answer */ 00195 wkc = ecx_srconfirm (port, idx, timeout); 00196 if (wkc > 0) 00197 { 00198 /* copy datagram to data buffer */ 00199 memcpy(data, &(port->rxbuf[idx][EC_HEADERSIZE]), length); 00200 } 00201 /* clear buffer status */ 00202 ecx_setbufstat(port, idx, EC_BUF_EMPTY); 00203 00204 return wkc; 00205 } 00206 00207 /** APRD "auto increment address read" primitive. Blocking. 00208 * 00209 * @param[in] port = port context struct 00210 * @param[in] ADP = Address Position, each slave ++, slave that has 0 executes 00211 * @param[in] ADO = Address Offset, slave memory address 00212 * @param[in] length = length of databuffer 00213 * @param[out] data = databuffer to put slave data in 00214 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00215 * @return Workcounter or EC_NOFRAME 00216 */ 00217 int ecx_APRD(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00218 { 00219 int wkc; 00220 uint8 idx; 00221 00222 idx = ecx_getindex(port); 00223 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_APRD, idx, ADP, ADO, length, data); 00224 wkc = ecx_srconfirm(port, idx, timeout); 00225 if (wkc > 0) 00226 { 00227 memcpy(data, &(port->rxbuf[idx][EC_HEADERSIZE]), length); 00228 } 00229 ecx_setbufstat(port, idx, EC_BUF_EMPTY); 00230 00231 return wkc; 00232 } 00233 00234 /** APRMW "auto increment address read, multiple write" primitive. Blocking. 00235 * 00236 * @param[in] port = port context struct 00237 * @param[in] ADP = Address Position, each slave ++, slave that has 0 reads, 00238 * following slaves write. 00239 * @param[in] ADO = Address Offset, slave memory address 00240 * @param[in] length = length of databuffer 00241 * @param[out] data = databuffer to put slave data in 00242 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00243 * @return Workcounter or EC_NOFRAME 00244 */ 00245 int ecx_ARMW(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00246 { 00247 int wkc; 00248 uint8 idx; 00249 00250 idx = ecx_getindex(port); 00251 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_ARMW, idx, ADP, ADO, length, data); 00252 wkc = ecx_srconfirm(port, idx, timeout); 00253 if (wkc > 0) 00254 { 00255 memcpy(data, &(port->rxbuf[idx][EC_HEADERSIZE]), length); 00256 } 00257 ecx_setbufstat(port, idx, EC_BUF_EMPTY); 00258 00259 return wkc; 00260 } 00261 00262 /** FPRMW "configured address read, multiple write" primitive. Blocking. 00263 * 00264 * @param[in] port = port context struct 00265 * @param[in] ADP = Address Position, slave that has address reads, 00266 * following slaves write. 00267 * @param[in] ADO = Address Offset, slave memory address 00268 * @param[in] length = length of databuffer 00269 * @param[out] data = databuffer to put slave data in 00270 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00271 * @return Workcounter or EC_NOFRAME 00272 */ 00273 int ecx_FRMW(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00274 { 00275 int wkc; 00276 uint8 idx; 00277 00278 idx = ecx_getindex(port); 00279 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_FRMW, idx, ADP, ADO, length, data); 00280 wkc = ecx_srconfirm(port, idx, timeout); 00281 if (wkc > 0) 00282 { 00283 memcpy(data, &(port->rxbuf[idx][EC_HEADERSIZE]), length); 00284 } 00285 ecx_setbufstat(port, idx, EC_BUF_EMPTY); 00286 00287 return wkc; 00288 } 00289 00290 /** APRDw "auto increment address read" word return primitive. Blocking. 00291 * 00292 * @param[in] port = port context struct 00293 * @param[in] ADP = Address Position, each slave ++, slave that has 0 reads. 00294 * @param[in] ADO = Address Offset, slave memory address 00295 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00296 * @return word data from slave 00297 */ 00298 uint16 ecx_APRDw(ecx_portt *port, uint16 ADP, uint16 ADO, int timeout) 00299 { 00300 uint16 w; 00301 00302 w = 0; 00303 ecx_APRD(port, ADP, ADO, sizeof(w), &w, timeout); 00304 00305 return w; 00306 } 00307 00308 /** FPRD "configured address read" primitive. Blocking. 00309 * 00310 * @param[in] port = port context struct 00311 * @param[in] ADP = Address Position, slave that has address reads. 00312 * @param[in] ADO = Address Offset, slave memory address 00313 * @param[in] length = length of databuffer 00314 * @param[out] data = databuffer to put slave data in 00315 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00316 * @return Workcounter or EC_NOFRAME 00317 */ 00318 int ecx_FPRD(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00319 { 00320 int wkc; 00321 uint8 idx; 00322 00323 idx = ecx_getindex(port); 00324 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_FPRD, idx, ADP, ADO, length, data); 00325 wkc = ecx_srconfirm(port, idx, timeout); 00326 if (wkc > 0) 00327 { 00328 memcpy(data, &(port->rxbuf[idx][EC_HEADERSIZE]), length); 00329 } 00330 ecx_setbufstat(port, idx, EC_BUF_EMPTY); 00331 00332 return wkc; 00333 } 00334 00335 /** FPRDw "configured address read" word return primitive. Blocking. 00336 * 00337 * @param[in] port = port context struct 00338 * @param[in] ADP = Address Position, slave that has address reads. 00339 * @param[in] ADO = Address Offset, slave memory address 00340 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00341 * @return word data from slave 00342 */ 00343 uint16 ecx_FPRDw(ecx_portt *port, uint16 ADP, uint16 ADO, int timeout) 00344 { 00345 uint16 w; 00346 00347 w = 0; 00348 ecx_FPRD(port, ADP, ADO, sizeof(w), &w, timeout); 00349 return w; 00350 } 00351 00352 /** APWR "auto increment address write" primitive. Blocking. 00353 * 00354 * @param[in] port = port context struct 00355 * @param[in] ADP = Address Position, each slave ++, slave that has 0 writes. 00356 * @param[in] ADO = Address Offset, slave memory address 00357 * @param[in] length = length of databuffer 00358 * @param[in] data = databuffer to write to slave. 00359 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00360 * @return Workcounter or EC_NOFRAME 00361 */ 00362 int ecx_APWR(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00363 { 00364 uint8 idx; 00365 int wkc; 00366 00367 idx = ecx_getindex(port); 00368 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_APWR, idx, ADP, ADO, length, data); 00369 wkc = ecx_srconfirm(port, idx, timeout); 00370 ecx_setbufstat(port, idx, EC_BUF_EMPTY); 00371 00372 return wkc; 00373 } 00374 00375 /** APWRw "auto increment address write" word primitive. Blocking. 00376 * 00377 * @param[in] port = port context struct 00378 * @param[in] ADP = Address Position, each slave ++, slave that has 0 writes. 00379 * @param[in] ADO = Address Offset, slave memory address 00380 * @param[in] data = word data to write to slave. 00381 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00382 * @return Workcounter or EC_NOFRAME 00383 */ 00384 int ecx_APWRw(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 data, int timeout) 00385 { 00386 return ecx_APWR(port, ADP, ADO, sizeof(data), &data, timeout); 00387 } 00388 00389 /** FPWR "configured address write" primitive. Blocking. 00390 * 00391 * @param[in] port = port context struct 00392 * @param[in] ADP = Address Position, slave that has address writes. 00393 * @param[in] ADO = Address Offset, slave memory address 00394 * @param[in] length = length of databuffer 00395 * @param[in] data = databuffer to write to slave. 00396 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00397 * @return Workcounter or EC_NOFRAME 00398 */ 00399 int ecx_FPWR(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00400 { 00401 int wkc; 00402 uint8 idx; 00403 00404 idx = ecx_getindex(port); 00405 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_FPWR, idx, ADP, ADO, length, data); 00406 wkc = ecx_srconfirm(port, idx, timeout); 00407 ecx_setbufstat(port, idx, EC_BUF_EMPTY); 00408 00409 return wkc; 00410 } 00411 00412 /** FPWR "configured address write" primitive. Blocking. 00413 * 00414 * @param[in] port = port context struct 00415 * @param[in] ADP = Address Position, slave that has address writes. 00416 * @param[in] ADO = Address Offset, slave memory address 00417 * @param[in] data = word to write to slave. 00418 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00419 * @return Workcounter or EC_NOFRAME 00420 */ 00421 int ecx_FPWRw(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 data, int timeout) 00422 { 00423 return ecx_FPWR(port, ADP, ADO, sizeof(data), &data, timeout); 00424 } 00425 00426 /** LRW "logical memory read / write" primitive. Blocking. 00427 * 00428 * @param[in] port = port context struct 00429 * @param[in] LogAdr = Logical memory address 00430 * @param[in] length = length of databuffer 00431 * @param[in,out] data = databuffer to write to and read from slave. 00432 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00433 * @return Workcounter or EC_NOFRAME 00434 */ 00435 int ecx_LRW(ecx_portt *port, uint32 LogAdr, uint16 length, void *data, int timeout) 00436 { 00437 uint8 idx; 00438 int wkc; 00439 00440 idx = ecx_getindex(port); 00441 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_LRW, idx, LO_WORD(LogAdr), HI_WORD(LogAdr), length, data); 00442 wkc = ecx_srconfirm(port, idx, timeout); 00443 if ((wkc > 0) && (port->rxbuf[idx][EC_CMDOFFSET] == EC_CMD_LRW)) 00444 { 00445 memcpy(data, &(port->rxbuf[idx][EC_HEADERSIZE]), length); 00446 } 00447 ecx_setbufstat(port, idx, EC_BUF_EMPTY); 00448 00449 return wkc; 00450 } 00451 00452 /** LRD "logical memory read" primitive. Blocking. 00453 * 00454 * @param[in] port = port context struct 00455 * @param[in] LogAdr = Logical memory address 00456 * @param[in] length = length of bytes to read from slave. 00457 * @param[out] data = databuffer to read from slave. 00458 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00459 * @return Workcounter or EC_NOFRAME 00460 */ 00461 int ecx_LRD(ecx_portt *port, uint32 LogAdr, uint16 length, void *data, int timeout) 00462 { 00463 uint8 idx; 00464 int wkc; 00465 00466 idx = ecx_getindex(port); 00467 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_LRD, idx, LO_WORD(LogAdr), HI_WORD(LogAdr), length, data); 00468 wkc = ecx_srconfirm(port, idx, timeout); 00469 if ((wkc > 0) && (port->rxbuf[idx][EC_CMDOFFSET]==EC_CMD_LRD)) 00470 { 00471 memcpy(data, &(port->rxbuf[idx][EC_HEADERSIZE]), length); 00472 } 00473 ecx_setbufstat(port, idx, EC_BUF_EMPTY); 00474 00475 return wkc; 00476 } 00477 00478 /** LWR "logical memory write" primitive. Blocking. 00479 * 00480 * @param[in] port = port context struct 00481 * @param[in] LogAdr = Logical memory address 00482 * @param[in] length = length of databuffer 00483 * @param[in] data = databuffer to write to slave. 00484 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00485 * @return Workcounter or EC_NOFRAME 00486 */ 00487 int ecx_LWR(ecx_portt *port, uint32 LogAdr, uint16 length, void *data, int timeout) 00488 { 00489 uint8 idx; 00490 int wkc; 00491 00492 idx = ecx_getindex(port); 00493 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_LWR, idx, LO_WORD(LogAdr), HI_WORD(LogAdr), length, data); 00494 wkc = ecx_srconfirm(port, idx, timeout); 00495 ecx_setbufstat(port, idx, EC_BUF_EMPTY); 00496 00497 return wkc; 00498 } 00499 00500 /** LRW "logical memory read / write" primitive plus Clock Distribution. Blocking. 00501 * Frame consists of two datagrams, one LRW and one FPRMW. 00502 * 00503 * @param[in] port = port context struct 00504 * @param[in] LogAdr = Logical memory address 00505 * @param[in] length = length of databuffer 00506 * @param[in,out] data = databuffer to write to and read from slave. 00507 * @param[in] DCrs = Distributed Clock reference slave address. 00508 * @param[out] DCtime = DC time read from reference slave. 00509 * @param[in] timeout = timeout in us, standard is EC_TIMEOUTRET 00510 * @return Workcounter or EC_NOFRAME 00511 */ 00512 int ecx_LRWDC(ecx_portt *port, uint32 LogAdr, uint16 length, void *data, uint16 DCrs, int64 *DCtime, int timeout) 00513 { 00514 uint16 DCtO; 00515 uint8 idx; 00516 int wkc; 00517 uint64 DCtE; 00518 00519 idx = ecx_getindex(port); 00520 /* LRW in first datagram */ 00521 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_LRW, idx, LO_WORD(LogAdr), HI_WORD(LogAdr), length, data); 00522 /* FPRMW in second datagram */ 00523 DCtE = htoell(*DCtime); 00524 DCtO = ecx_adddatagram(port, &(port->txbuf[idx]), EC_CMD_FRMW, idx, FALSE, DCrs, ECT_REG_DCSYSTIME, sizeof(DCtime), &DCtE); 00525 wkc = ecx_srconfirm(port, idx, timeout); 00526 if ((wkc > 0) && (port->rxbuf[idx][EC_CMDOFFSET] == EC_CMD_LRW)) 00527 { 00528 memcpy(data, &(port->rxbuf[idx][EC_HEADERSIZE]), length); 00529 memcpy(&wkc, &(port->rxbuf[idx][EC_HEADERSIZE + length]), EC_WKCSIZE); 00530 memcpy(&DCtE, &(port->rxbuf[idx][DCtO]), sizeof(*DCtime)); 00531 *DCtime = etohll(DCtE); 00532 } 00533 ecx_setbufstat(port, idx, EC_BUF_EMPTY); 00534 00535 return wkc; 00536 } 00537 00538 #ifdef EC_VER1 00539 int ec_setupdatagram(void *frame, uint8 com, uint8 idx, uint16 ADP, uint16 ADO, uint16 length, void *data) 00540 { 00541 return ecx_setupdatagram (&ecx_port, frame, com, idx, ADP, ADO, length, data); 00542 } 00543 00544 int ec_adddatagram (void *frame, uint8 com, uint8 idx, boolean more, uint16 ADP, uint16 ADO, uint16 length, void *data) 00545 { 00546 return ecx_adddatagram (&ecx_port, frame, com, idx, more, ADP, ADO, length, data); 00547 } 00548 00549 int ec_BWR(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00550 { 00551 return ecx_BWR (&ecx_port, ADP, ADO, length, data, timeout); 00552 } 00553 00554 int ec_BRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00555 { 00556 return ecx_BRD(&ecx_port, ADP, ADO, length, data, timeout); 00557 } 00558 00559 int ec_APRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00560 { 00561 return ecx_APRD(&ecx_port, ADP, ADO, length, data, timeout); 00562 } 00563 00564 int ec_ARMW(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00565 { 00566 return ecx_ARMW(&ecx_port, ADP, ADO, length, data, timeout); 00567 } 00568 00569 int ec_FRMW(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00570 { 00571 return ecx_FRMW(&ecx_port, ADP, ADO, length, data, timeout); 00572 } 00573 00574 uint16 ec_APRDw(uint16 ADP, uint16 ADO, int timeout) 00575 { 00576 uint16 w; 00577 00578 w = 0; 00579 ec_APRD(ADP, ADO, sizeof(w), &w, timeout); 00580 00581 return w; 00582 } 00583 00584 int ec_FPRD(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00585 { 00586 return ecx_FPRD(&ecx_port, ADP, ADO, length, data, timeout); 00587 } 00588 00589 uint16 ec_FPRDw(uint16 ADP, uint16 ADO, int timeout) 00590 { 00591 uint16 w; 00592 00593 w = 0; 00594 ec_FPRD(ADP, ADO, sizeof(w), &w, timeout); 00595 return w; 00596 } 00597 00598 int ec_APWR(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00599 { 00600 return ecx_APWR(&ecx_port, ADP, ADO, length, data, timeout); 00601 } 00602 00603 int ec_APWRw(uint16 ADP, uint16 ADO, uint16 data, int timeout) 00604 { 00605 return ec_APWR(ADP, ADO, sizeof(data), &data, timeout); 00606 } 00607 00608 int ec_FPWR(uint16 ADP, uint16 ADO, uint16 length, void *data, int timeout) 00609 { 00610 return ecx_FPWR(&ecx_port, ADP, ADO, length, data, timeout); 00611 } 00612 00613 int ec_FPWRw(uint16 ADP, uint16 ADO, uint16 data, int timeout) 00614 { 00615 return ec_FPWR(ADP, ADO, sizeof(data), &data, timeout); 00616 } 00617 00618 int ec_LRW(uint32 LogAdr, uint16 length, void *data, int timeout) 00619 { 00620 return ecx_LRW(&ecx_port, LogAdr, length, data, timeout); 00621 } 00622 00623 int ec_LRD(uint32 LogAdr, uint16 length, void *data, int timeout) 00624 { 00625 return ecx_LRD(&ecx_port, LogAdr, length, data, timeout); 00626 } 00627 00628 int ec_LWR(uint32 LogAdr, uint16 length, void *data, int timeout) 00629 { 00630 return ecx_LWR(&ecx_port, LogAdr, length, data, timeout); 00631 } 00632 00633 int ec_LRWDC(uint32 LogAdr, uint16 length, void *data, uint16 DCrs, int64 *DCtime, int timeout) 00634 { 00635 return ecx_LRWDC(&ecx_port, LogAdr, length, data, DCrs, DCtime, timeout); 00636 } 00637 #endif
Generated on Tue Jul 12 2022 18:21:13 by
