46 /*****************************************************************************/ |
46 /*****************************************************************************/ |
47 |
47 |
48 /** \cond */ |
48 /** \cond */ |
49 |
49 |
50 #define EC_FUNC_HEADER \ |
50 #define EC_FUNC_HEADER \ |
51 if (unlikely(ec_datagram_prealloc(datagram, data_size))) \ |
51 ret = ec_datagram_prealloc(datagram, data_size); \ |
52 return -1; \ |
52 if (unlikely(ret)) \ |
|
53 return ret; \ |
53 datagram->index = 0; \ |
54 datagram->index = 0; \ |
54 datagram->working_counter = 0; \ |
55 datagram->working_counter = 0; \ |
55 datagram->state = EC_DATAGRAM_INIT; |
56 datagram->state = EC_DATAGRAM_INIT; |
56 |
57 |
57 #define EC_FUNC_FOOTER \ |
58 #define EC_FUNC_FOOTER \ |
169 |
170 |
170 /*****************************************************************************/ |
171 /*****************************************************************************/ |
171 |
172 |
172 /** Initializes an EtherCAT APRD datagram. |
173 /** Initializes an EtherCAT APRD datagram. |
173 * |
174 * |
174 * \return 0 in case of success, else < 0 |
175 * \return Return value of ec_datagram_prealloc(). |
175 */ |
176 */ |
176 int ec_datagram_aprd( |
177 int ec_datagram_aprd( |
177 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
178 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
178 uint16_t ring_position, /**< Auto-increment address. */ |
179 uint16_t ring_position, /**< Auto-increment address. */ |
179 uint16_t mem_address, /**< Physical memory address. */ |
180 uint16_t mem_address, /**< Physical memory address. */ |
180 size_t data_size /**< Number of bytes to read. */ |
181 size_t data_size /**< Number of bytes to read. */ |
181 ) |
182 ) |
182 { |
183 { |
|
184 int ret; |
183 EC_FUNC_HEADER; |
185 EC_FUNC_HEADER; |
184 datagram->type = EC_DATAGRAM_APRD; |
186 datagram->type = EC_DATAGRAM_APRD; |
185 EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1)); |
187 EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1)); |
186 EC_WRITE_U16(datagram->address + 2, mem_address); |
188 EC_WRITE_U16(datagram->address + 2, mem_address); |
187 EC_FUNC_FOOTER; |
189 EC_FUNC_FOOTER; |
189 |
191 |
190 /*****************************************************************************/ |
192 /*****************************************************************************/ |
191 |
193 |
192 /** Initializes an EtherCAT APWR datagram. |
194 /** Initializes an EtherCAT APWR datagram. |
193 * |
195 * |
194 * \return 0 in case of success, else < 0 |
196 * \return Return value of ec_datagram_prealloc(). |
195 */ |
197 */ |
196 int ec_datagram_apwr( |
198 int ec_datagram_apwr( |
197 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
199 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
198 uint16_t ring_position, /**< Auto-increment address. */ |
200 uint16_t ring_position, /**< Auto-increment address. */ |
199 uint16_t mem_address, /**< Physical memory address. */ |
201 uint16_t mem_address, /**< Physical memory address. */ |
200 size_t data_size /**< Number of bytes to write. */ |
202 size_t data_size /**< Number of bytes to write. */ |
201 ) |
203 ) |
202 { |
204 { |
|
205 int ret; |
203 EC_FUNC_HEADER; |
206 EC_FUNC_HEADER; |
204 datagram->type = EC_DATAGRAM_APWR; |
207 datagram->type = EC_DATAGRAM_APWR; |
205 EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1)); |
208 EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1)); |
206 EC_WRITE_U16(datagram->address + 2, mem_address); |
209 EC_WRITE_U16(datagram->address + 2, mem_address); |
207 EC_FUNC_FOOTER; |
210 EC_FUNC_FOOTER; |
209 |
212 |
210 /*****************************************************************************/ |
213 /*****************************************************************************/ |
211 |
214 |
212 /** Initializes an EtherCAT APRW datagram. |
215 /** Initializes an EtherCAT APRW datagram. |
213 * |
216 * |
214 * \return 0 in case of success, else < 0 |
217 * \return Return value of ec_datagram_prealloc(). |
215 */ |
218 */ |
216 int ec_datagram_aprw( |
219 int ec_datagram_aprw( |
217 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
220 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
218 uint16_t ring_position, /**< Auto-increment address. */ |
221 uint16_t ring_position, /**< Auto-increment address. */ |
219 uint16_t mem_address, /**< Physical memory address. */ |
222 uint16_t mem_address, /**< Physical memory address. */ |
220 size_t data_size /**< Number of bytes to write. */ |
223 size_t data_size /**< Number of bytes to write. */ |
221 ) |
224 ) |
222 { |
225 { |
|
226 int ret; |
223 EC_FUNC_HEADER; |
227 EC_FUNC_HEADER; |
224 datagram->type = EC_DATAGRAM_APRW; |
228 datagram->type = EC_DATAGRAM_APRW; |
225 EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1)); |
229 EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1)); |
226 EC_WRITE_U16(datagram->address + 2, mem_address); |
230 EC_WRITE_U16(datagram->address + 2, mem_address); |
227 EC_FUNC_FOOTER; |
231 EC_FUNC_FOOTER; |
229 |
233 |
230 /*****************************************************************************/ |
234 /*****************************************************************************/ |
231 |
235 |
232 /** Initializes an EtherCAT ARMW datagram. |
236 /** Initializes an EtherCAT ARMW datagram. |
233 * |
237 * |
234 * \return 0 in case of success, else < 0 |
238 * \return Return value of ec_datagram_prealloc(). |
235 */ |
239 */ |
236 int ec_datagram_armw( |
240 int ec_datagram_armw( |
237 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
241 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
238 uint16_t ring_position, /**< Auto-increment address. */ |
242 uint16_t ring_position, /**< Auto-increment address. */ |
239 uint16_t mem_address, /**< Physical memory address. */ |
243 uint16_t mem_address, /**< Physical memory address. */ |
240 size_t data_size /**< Number of bytes to read. */ |
244 size_t data_size /**< Number of bytes to read. */ |
241 ) |
245 ) |
242 { |
246 { |
|
247 int ret; |
243 EC_FUNC_HEADER; |
248 EC_FUNC_HEADER; |
244 datagram->type = EC_DATAGRAM_ARMW; |
249 datagram->type = EC_DATAGRAM_ARMW; |
245 EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1)); |
250 EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1)); |
246 EC_WRITE_U16(datagram->address + 2, mem_address); |
251 EC_WRITE_U16(datagram->address + 2, mem_address); |
247 EC_FUNC_FOOTER; |
252 EC_FUNC_FOOTER; |
249 |
254 |
250 /*****************************************************************************/ |
255 /*****************************************************************************/ |
251 |
256 |
252 /** Initializes an EtherCAT FPRD datagram. |
257 /** Initializes an EtherCAT FPRD datagram. |
253 * |
258 * |
254 * \return 0 in case of success, else < 0 |
259 * \return Return value of ec_datagram_prealloc(). |
255 */ |
260 */ |
256 int ec_datagram_fprd( |
261 int ec_datagram_fprd( |
257 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
262 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
258 uint16_t configured_address, /**< Configured station address. */ |
263 uint16_t configured_address, /**< Configured station address. */ |
259 uint16_t mem_address, /**< Physical memory address. */ |
264 uint16_t mem_address, /**< Physical memory address. */ |
260 size_t data_size /**< Number of bytes to read. */ |
265 size_t data_size /**< Number of bytes to read. */ |
261 ) |
266 ) |
262 { |
267 { |
|
268 int ret; |
|
269 |
263 if (unlikely(configured_address == 0x0000)) |
270 if (unlikely(configured_address == 0x0000)) |
264 EC_WARN("Using configured station address 0x0000!\n"); |
271 EC_WARN("Using configured station address 0x0000!\n"); |
265 |
272 |
266 EC_FUNC_HEADER; |
273 EC_FUNC_HEADER; |
267 datagram->type = EC_DATAGRAM_FPRD; |
274 datagram->type = EC_DATAGRAM_FPRD; |
272 |
279 |
273 /*****************************************************************************/ |
280 /*****************************************************************************/ |
274 |
281 |
275 /** Initializes an EtherCAT FPWR datagram. |
282 /** Initializes an EtherCAT FPWR datagram. |
276 * |
283 * |
277 * \return 0 in case of success, else < 0 |
284 * \return Return value of ec_datagram_prealloc(). |
278 */ |
285 */ |
279 int ec_datagram_fpwr( |
286 int ec_datagram_fpwr( |
280 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
287 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
281 uint16_t configured_address, /**< Configured station address. */ |
288 uint16_t configured_address, /**< Configured station address. */ |
282 uint16_t mem_address, /**< Physical memory address. */ |
289 uint16_t mem_address, /**< Physical memory address. */ |
283 size_t data_size /**< Number of bytes to write. */ |
290 size_t data_size /**< Number of bytes to write. */ |
284 ) |
291 ) |
285 { |
292 { |
|
293 int ret; |
|
294 |
286 if (unlikely(configured_address == 0x0000)) |
295 if (unlikely(configured_address == 0x0000)) |
287 EC_WARN("Using configured station address 0x0000!\n"); |
296 EC_WARN("Using configured station address 0x0000!\n"); |
288 |
297 |
289 EC_FUNC_HEADER; |
298 EC_FUNC_HEADER; |
290 datagram->type = EC_DATAGRAM_FPWR; |
299 datagram->type = EC_DATAGRAM_FPWR; |
295 |
304 |
296 /*****************************************************************************/ |
305 /*****************************************************************************/ |
297 |
306 |
298 /** Initializes an EtherCAT FPRW datagram. |
307 /** Initializes an EtherCAT FPRW datagram. |
299 * |
308 * |
300 * \return 0 in case of success, else < 0 |
309 * \return Return value of ec_datagram_prealloc(). |
301 */ |
310 */ |
302 int ec_datagram_fprw( |
311 int ec_datagram_fprw( |
303 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
312 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
304 uint16_t configured_address, /**< Configured station address. */ |
313 uint16_t configured_address, /**< Configured station address. */ |
305 uint16_t mem_address, /**< Physical memory address. */ |
314 uint16_t mem_address, /**< Physical memory address. */ |
306 size_t data_size /**< Number of bytes to write. */ |
315 size_t data_size /**< Number of bytes to write. */ |
307 ) |
316 ) |
308 { |
317 { |
|
318 int ret; |
|
319 |
309 if (unlikely(configured_address == 0x0000)) |
320 if (unlikely(configured_address == 0x0000)) |
310 EC_WARN("Using configured station address 0x0000!\n"); |
321 EC_WARN("Using configured station address 0x0000!\n"); |
311 |
322 |
312 EC_FUNC_HEADER; |
323 EC_FUNC_HEADER; |
313 datagram->type = EC_DATAGRAM_FPRW; |
324 datagram->type = EC_DATAGRAM_FPRW; |
318 |
329 |
319 /*****************************************************************************/ |
330 /*****************************************************************************/ |
320 |
331 |
321 /** Initializes an EtherCAT FRMW datagram. |
332 /** Initializes an EtherCAT FRMW datagram. |
322 * |
333 * |
323 * \return 0 in case of success, else < 0 |
334 * \return Return value of ec_datagram_prealloc(). |
324 */ |
335 */ |
325 int ec_datagram_frmw( |
336 int ec_datagram_frmw( |
326 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
337 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
327 uint16_t configured_address, /**< Configured station address. */ |
338 uint16_t configured_address, /**< Configured station address. */ |
328 uint16_t mem_address, /**< Physical memory address. */ |
339 uint16_t mem_address, /**< Physical memory address. */ |
329 size_t data_size /**< Number of bytes to write. */ |
340 size_t data_size /**< Number of bytes to write. */ |
330 ) |
341 ) |
331 { |
342 { |
|
343 int ret; |
|
344 |
332 if (unlikely(configured_address == 0x0000)) |
345 if (unlikely(configured_address == 0x0000)) |
333 EC_WARN("Using configured station address 0x0000!\n"); |
346 EC_WARN("Using configured station address 0x0000!\n"); |
334 |
347 |
335 EC_FUNC_HEADER; |
348 EC_FUNC_HEADER; |
336 datagram->type = EC_DATAGRAM_FRMW; |
349 datagram->type = EC_DATAGRAM_FRMW; |
341 |
354 |
342 /*****************************************************************************/ |
355 /*****************************************************************************/ |
343 |
356 |
344 /** Initializes an EtherCAT BRD datagram. |
357 /** Initializes an EtherCAT BRD datagram. |
345 * |
358 * |
346 * \return 0 in case of success, else < 0 |
359 * \return Return value of ec_datagram_prealloc(). |
347 */ |
360 */ |
348 int ec_datagram_brd( |
361 int ec_datagram_brd( |
349 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
362 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
350 uint16_t mem_address, /**< Physical memory address. */ |
363 uint16_t mem_address, /**< Physical memory address. */ |
351 size_t data_size /**< Number of bytes to read. */ |
364 size_t data_size /**< Number of bytes to read. */ |
352 ) |
365 ) |
353 { |
366 { |
|
367 int ret; |
354 EC_FUNC_HEADER; |
368 EC_FUNC_HEADER; |
355 datagram->type = EC_DATAGRAM_BRD; |
369 datagram->type = EC_DATAGRAM_BRD; |
356 EC_WRITE_U16(datagram->address, 0x0000); |
370 EC_WRITE_U16(datagram->address, 0x0000); |
357 EC_WRITE_U16(datagram->address + 2, mem_address); |
371 EC_WRITE_U16(datagram->address + 2, mem_address); |
358 EC_FUNC_FOOTER; |
372 EC_FUNC_FOOTER; |
360 |
374 |
361 /*****************************************************************************/ |
375 /*****************************************************************************/ |
362 |
376 |
363 /** Initializes an EtherCAT BWR datagram. |
377 /** Initializes an EtherCAT BWR datagram. |
364 * |
378 * |
365 * \return 0 in case of success, else < 0 |
379 * \return Return value of ec_datagram_prealloc(). |
366 */ |
380 */ |
367 int ec_datagram_bwr( |
381 int ec_datagram_bwr( |
368 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
382 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
369 uint16_t mem_address, /**< Physical memory address. */ |
383 uint16_t mem_address, /**< Physical memory address. */ |
370 size_t data_size /**< Number of bytes to write. */ |
384 size_t data_size /**< Number of bytes to write. */ |
371 ) |
385 ) |
372 { |
386 { |
|
387 int ret; |
373 EC_FUNC_HEADER; |
388 EC_FUNC_HEADER; |
374 datagram->type = EC_DATAGRAM_BWR; |
389 datagram->type = EC_DATAGRAM_BWR; |
375 EC_WRITE_U16(datagram->address, 0x0000); |
390 EC_WRITE_U16(datagram->address, 0x0000); |
376 EC_WRITE_U16(datagram->address + 2, mem_address); |
391 EC_WRITE_U16(datagram->address + 2, mem_address); |
377 EC_FUNC_FOOTER; |
392 EC_FUNC_FOOTER; |
379 |
394 |
380 /*****************************************************************************/ |
395 /*****************************************************************************/ |
381 |
396 |
382 /** Initializes an EtherCAT BRW datagram. |
397 /** Initializes an EtherCAT BRW datagram. |
383 * |
398 * |
384 * \return 0 in case of success, else < 0 |
399 * \return Return value of ec_datagram_prealloc(). |
385 */ |
400 */ |
386 int ec_datagram_brw( |
401 int ec_datagram_brw( |
387 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
402 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
388 uint16_t mem_address, /**< Physical memory address. */ |
403 uint16_t mem_address, /**< Physical memory address. */ |
389 size_t data_size /**< Number of bytes to write. */ |
404 size_t data_size /**< Number of bytes to write. */ |
390 ) |
405 ) |
391 { |
406 { |
|
407 int ret; |
392 EC_FUNC_HEADER; |
408 EC_FUNC_HEADER; |
393 datagram->type = EC_DATAGRAM_BRW; |
409 datagram->type = EC_DATAGRAM_BRW; |
394 EC_WRITE_U16(datagram->address, 0x0000); |
410 EC_WRITE_U16(datagram->address, 0x0000); |
395 EC_WRITE_U16(datagram->address + 2, mem_address); |
411 EC_WRITE_U16(datagram->address + 2, mem_address); |
396 EC_FUNC_FOOTER; |
412 EC_FUNC_FOOTER; |
401 /** Initializes an EtherCAT LRD datagram. |
417 /** Initializes an EtherCAT LRD datagram. |
402 * |
418 * |
403 * \attention It is assumed, that the external memory is at least \a data_size |
419 * \attention It is assumed, that the external memory is at least \a data_size |
404 * bytes large. |
420 * bytes large. |
405 * |
421 * |
406 * \return 0 in case of success, else < 0 |
422 * \return Return value of ec_datagram_prealloc(). |
407 */ |
423 */ |
408 int ec_datagram_lrd( |
424 int ec_datagram_lrd( |
409 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
425 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
410 uint32_t offset, /**< Logical address. */ |
426 uint32_t offset, /**< Logical address. */ |
411 size_t data_size, /**< Number of bytes to read/write. */ |
427 size_t data_size, /**< Number of bytes to read/write. */ |
412 uint8_t *external_memory /**< Pointer to the memory to use. */ |
428 uint8_t *external_memory /**< Pointer to the memory to use. */ |
413 ) |
429 ) |
414 { |
430 { |
|
431 int ret; |
415 datagram->data = external_memory; |
432 datagram->data = external_memory; |
416 datagram->data_origin = EC_ORIG_EXTERNAL; |
433 datagram->data_origin = EC_ORIG_EXTERNAL; |
417 EC_FUNC_HEADER; |
434 EC_FUNC_HEADER; |
418 datagram->type = EC_DATAGRAM_LRD; |
435 datagram->type = EC_DATAGRAM_LRD; |
419 EC_WRITE_U32(datagram->address, offset); |
436 EC_WRITE_U32(datagram->address, offset); |
425 /** Initializes an EtherCAT LWR datagram. |
442 /** Initializes an EtherCAT LWR datagram. |
426 * |
443 * |
427 * \attention It is assumed, that the external memory is at least \a data_size |
444 * \attention It is assumed, that the external memory is at least \a data_size |
428 * bytes large. |
445 * bytes large. |
429 * |
446 * |
430 * \return 0 in case of success, else < 0 |
447 * \return Return value of ec_datagram_prealloc(). |
431 */ |
448 */ |
432 int ec_datagram_lwr( |
449 int ec_datagram_lwr( |
433 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
450 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
434 uint32_t offset, /**< Logical address. */ |
451 uint32_t offset, /**< Logical address. */ |
435 size_t data_size, /**< Number of bytes to read/write. */ |
452 size_t data_size, /**< Number of bytes to read/write. */ |
436 uint8_t *external_memory /**< Pointer to the memory to use. */ |
453 uint8_t *external_memory /**< Pointer to the memory to use. */ |
437 ) |
454 ) |
438 { |
455 { |
|
456 int ret; |
439 datagram->data = external_memory; |
457 datagram->data = external_memory; |
440 datagram->data_origin = EC_ORIG_EXTERNAL; |
458 datagram->data_origin = EC_ORIG_EXTERNAL; |
441 EC_FUNC_HEADER; |
459 EC_FUNC_HEADER; |
442 datagram->type = EC_DATAGRAM_LWR; |
460 datagram->type = EC_DATAGRAM_LWR; |
443 EC_WRITE_U32(datagram->address, offset); |
461 EC_WRITE_U32(datagram->address, offset); |
449 /** Initializes an EtherCAT LRW datagram. |
467 /** Initializes an EtherCAT LRW datagram. |
450 * |
468 * |
451 * \attention It is assumed, that the external memory is at least \a data_size |
469 * \attention It is assumed, that the external memory is at least \a data_size |
452 * bytes large. |
470 * bytes large. |
453 * |
471 * |
454 * \return 0 in case of success, else < 0 |
472 * \return Return value of ec_datagram_prealloc(). |
455 */ |
473 */ |
456 int ec_datagram_lrw( |
474 int ec_datagram_lrw( |
457 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
475 ec_datagram_t *datagram, /**< EtherCAT datagram. */ |
458 uint32_t offset, /**< Logical address. */ |
476 uint32_t offset, /**< Logical address. */ |
459 size_t data_size, /**< Number of bytes to read/write. */ |
477 size_t data_size, /**< Number of bytes to read/write. */ |
460 uint8_t *external_memory /**< Pointer to the memory to use. */ |
478 uint8_t *external_memory /**< Pointer to the memory to use. */ |
461 ) |
479 ) |
462 { |
480 { |
|
481 int ret; |
463 datagram->data = external_memory; |
482 datagram->data = external_memory; |
464 datagram->data_origin = EC_ORIG_EXTERNAL; |
483 datagram->data_origin = EC_ORIG_EXTERNAL; |
465 EC_FUNC_HEADER; |
484 EC_FUNC_HEADER; |
466 datagram->type = EC_DATAGRAM_LRW; |
485 datagram->type = EC_DATAGRAM_LRW; |
467 EC_WRITE_U32(datagram->address, offset); |
486 EC_WRITE_U32(datagram->address, offset); |