Lely core libraries 2.3.4
pdo.c
Go to the documentation of this file.
1
24#include "co.h"
25
26#if !LELY_NO_CO_RPDO || !LELY_NO_CO_TPDO
27
28#include <lely/can/msg.h>
29#include <lely/co/dev.h>
30#include <lely/co/obj.h>
31#include <lely/co/pdo.h>
32#include <lely/co/sdo.h>
33#include <lely/util/endian.h>
34
35#include <assert.h>
36
37static co_unsigned32_t co_dev_cfg_pdo_comm(const co_dev_t *dev,
38 co_unsigned16_t idx, const struct co_pdo_comm_par *par);
39
40static co_unsigned32_t co_dev_cfg_pdo_map(const co_dev_t *dev,
41 co_unsigned16_t num, const struct co_pdo_map_par *par);
42
43#if !LELY_NO_CO_RPDO && !LELY_NO_CO_MPDO
44co_unsigned32_t co_mpdo_dn(const struct co_pdo_map_par *par, co_dev_t *dev,
45 struct co_sdo_req *req, const uint_least8_t *buf, size_t n);
46#endif
47
48#if !LELY_NO_CO_RPDO
49
50co_unsigned32_t
51co_dev_chk_rpdo(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
52{
53 assert(dev);
54
55 if (co_type_is_basic(idx) && !subidx) {
56 // If the object is a dummy entry, check if it is enabled.
57 if (!(co_dev_get_dummy(dev) & (1 << idx)))
58 return CO_SDO_AC_NO_OBJ;
59 } else {
60 co_obj_t *obj = co_dev_find_obj(dev, idx);
61 if (!obj)
62 return CO_SDO_AC_NO_OBJ;
63
64 co_sub_t *sub = co_obj_find_sub(obj, subidx);
65 if (!sub)
66 return CO_SDO_AC_NO_SUB;
67
68 unsigned int access = co_sub_get_access(sub);
69 if (!(access & CO_ACCESS_WRITE))
70 return CO_SDO_AC_NO_WRITE;
71
72 if (!co_sub_get_pdo_mapping(sub) || !(access & CO_ACCESS_RPDO))
73 return CO_SDO_AC_NO_PDO;
74 }
75
76 return 0;
77}
78
79co_unsigned32_t
80co_dev_cfg_rpdo(const co_dev_t *dev, co_unsigned16_t num,
81 const struct co_pdo_comm_par *comm,
82 const struct co_pdo_map_par *map)
83{
84 assert(comm);
85
86 co_unsigned32_t ac = 0;
87
88 struct co_pdo_comm_par par = *comm;
89 // Disable the RPDO service before configuring any parameters.
91 ac = co_dev_cfg_rpdo_comm(dev, num, &par);
92 if (ac)
93 return ac;
94
95 ac = co_dev_cfg_rpdo_map(dev, num, map);
96 if (ac)
97 return ac;
98
99 // Re-enable the RPDO service if necessary.
100 if (!(comm->cobid & CO_PDO_COBID_VALID))
101 ac = co_dev_cfg_rpdo_comm(dev, num, comm);
102 return ac;
103}
104
105co_unsigned32_t
106co_dev_cfg_rpdo_comm(const co_dev_t *dev, co_unsigned16_t num,
107 const struct co_pdo_comm_par *par)
108{
109 if (!num || num > CO_NUM_PDOS)
110 return CO_SDO_AC_NO_OBJ;
111
112 return co_dev_cfg_pdo_comm(dev, 0x1400 + num - 1, par);
113}
114
115co_unsigned32_t
116co_dev_cfg_rpdo_map(const co_dev_t *dev, co_unsigned16_t num,
117 const struct co_pdo_map_par *par)
118{
119 if (!num || num > CO_NUM_PDOS)
120 return CO_SDO_AC_NO_OBJ;
121
122 return co_dev_cfg_pdo_map(dev, 0x1600 + num - 1, par);
123}
124
125#endif // !LELY_NO_CO_RPDO
126
127#if !LELY_NO_CO_TPDO
128
129co_unsigned32_t
130co_dev_chk_tpdo(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
131{
132 assert(dev);
133
134 co_obj_t *obj = co_dev_find_obj(dev, idx);
135 if (!obj)
136 return CO_SDO_AC_NO_OBJ;
137
138 co_sub_t *sub = co_obj_find_sub(obj, subidx);
139 if (!sub)
140 return CO_SDO_AC_NO_SUB;
141
142 unsigned int access = co_sub_get_access(sub);
143 if (!(access & CO_ACCESS_READ))
144 return CO_SDO_AC_NO_READ;
145
146 if (!co_sub_get_pdo_mapping(sub) || !(access & CO_ACCESS_TPDO))
147 return CO_SDO_AC_NO_PDO;
148
149 return 0;
150}
151
152co_unsigned32_t
153co_dev_cfg_tpdo(const co_dev_t *dev, co_unsigned16_t num,
154 const struct co_pdo_comm_par *comm,
155 const struct co_pdo_map_par *map)
156{
157 assert(comm);
158
159 co_unsigned32_t ac = 0;
160
161 struct co_pdo_comm_par par = *comm;
162 // Disable the TPDO service before configuring any parameters.
164 ac = co_dev_cfg_tpdo_comm(dev, num, &par);
165 if (ac)
166 return ac;
167
168 ac = co_dev_cfg_tpdo_map(dev, num, map);
169 if (ac)
170 return ac;
171
172 // Re-enable the TPDO service if necessary.
173 if (!(comm->cobid & CO_PDO_COBID_VALID))
174 ac = co_dev_cfg_tpdo_comm(dev, num, comm);
175 return ac;
176}
177
178co_unsigned32_t
179co_dev_cfg_tpdo_comm(const co_dev_t *dev, co_unsigned16_t num,
180 const struct co_pdo_comm_par *par)
181{
182 if (!num || num > CO_NUM_PDOS)
183 return CO_SDO_AC_NO_OBJ;
184
185 return co_dev_cfg_pdo_comm(dev, 0x1800 + num - 1, par);
186}
187
188co_unsigned32_t
189co_dev_cfg_tpdo_map(const co_dev_t *dev, co_unsigned16_t num,
190 const struct co_pdo_map_par *par)
191{
192 if (!num || num > CO_NUM_PDOS)
193 return CO_SDO_AC_NO_OBJ;
194
195 return co_dev_cfg_pdo_map(dev, 0x1a00 + num - 1, par);
196}
197
198#endif // !LELY_NO_CO_TPDO
199
200#if !LELY_NO_CO_MPDO
201
202int
204 const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
205{
206 assert(dev);
207
208 // Loop over all sub-objects in the object scanner list (1FA0..1FCF).
209 co_obj_t *obj = NULL;
210 for (co_unsigned16_t i = 0x1fa0; !obj && i <= 0x1fcf; i++)
211 obj = co_dev_find_obj(dev, i);
212 for (; obj && co_obj_get_idx(obj) <= 0x1fcf; obj = co_obj_next(obj)) {
213 co_unsigned8_t n = co_obj_get_val_u8(obj, 0);
214 if (!n)
215 continue;
217 for (; sub && co_sub_get_subidx(sub) <= n;
218 sub = co_sub_next(sub)) {
219 co_unsigned32_t val = co_sub_get_val_u32(sub);
220 if (!val)
221 continue;
222 // Check if the object index matches.
223 if (((val >> 8) & 0xffff) != idx)
224 continue;
225 // Check if the object sub-index is part of the
226 // specified block.
227 co_unsigned8_t min = val & 0xff;
228 if (subidx < min)
229 continue;
230 co_unsigned8_t max = min;
231 co_unsigned8_t blk = (val >> 24) & 0xff;
232 if (blk)
233 max += MIN(blk - 1, 0xff - min);
234 if (subidx > max)
235 continue;
236
237 return 1;
238 }
239 }
240
241 return 0;
242}
243
244int
245co_dev_map_sam_mpdo(const co_dev_t *dev, co_unsigned8_t id, co_unsigned16_t idx,
246 co_unsigned8_t subidx, co_unsigned16_t *pidx,
247 co_unsigned8_t *psubidx)
248{
249 assert(dev);
250
251 // Loop over all sub-objects in the object dispatching list
252 // (1FD0..1FFF).
253 co_obj_t *obj = NULL;
254 for (co_unsigned16_t i = 0x1fd0; !obj && i <= 0x1fff; i++)
255 obj = co_dev_find_obj(dev, i);
256 for (; obj && co_obj_get_idx(obj) <= 0x1fff; obj = co_obj_next(obj)) {
257 co_unsigned8_t n = co_obj_get_val_u8(obj, 0);
258 if (!n)
259 continue;
261 for (; sub && co_sub_get_subidx(sub) <= n;
262 sub = co_sub_next(sub)) {
263 co_unsigned64_t val = co_sub_get_val_u64(sub);
264 if (!val)
265 continue;
266 // Check if the remote node-ID and object index match.
267 if ((val & 0xff) != id)
268 continue;
269 if (((val >> 16) & 0xffff) != idx)
270 continue;
271 // Check if the remote object sub-index is part of the
272 // specified block.
273 co_unsigned8_t min = (val >> 8) & 0xff;
274 if (subidx < min)
275 continue;
276 co_unsigned8_t max = min;
277 co_unsigned8_t blk = (val >> 54) & 0xff;
278 if (blk)
279 max += MIN(blk - 1, 0xff - min);
280 if (subidx > max)
281 continue;
282
283 if (pidx)
284 *pidx = (val >> 40) & 0xffff;
285 if (psubidx) {
286 *psubidx = (val >> 32) & 0xff;
287 *psubidx += subidx - min;
288 }
289 return 1;
290 }
291 }
292
293 return 0;
294}
295
296#endif // !LELY_NO_CO_MPDO
297
298co_unsigned32_t
299co_pdo_map(const struct co_pdo_map_par *par, const co_unsigned64_t *val,
300 co_unsigned8_t n, uint_least8_t *buf, size_t *pn)
301{
302 assert(par);
303 assert(val);
304
305 if (par->n > CO_PDO_NUM_MAPS || n != par->n)
306 return CO_SDO_AC_PDO_LEN;
307
308 size_t offset = 0;
309 for (size_t i = 0; i < par->n; i++) {
310 co_unsigned32_t map = par->map[i];
311 if (!map)
312 continue;
313
314 co_unsigned8_t len = map & 0xff;
315 if (offset + len > CAN_MAX_LEN * 8)
316 return CO_SDO_AC_PDO_LEN;
317
318 uint_least8_t tmp[sizeof(co_unsigned64_t)] = { 0 };
319 stle_u64(tmp, val[i]);
320 if (buf && pn && offset + len <= *pn * 8)
321 bcpyle(buf, offset, tmp, 0, len);
322
323 offset += len;
324 }
325
326 if (pn)
327 *pn = (offset + 7) / 8;
328
329 return 0;
330}
331
332co_unsigned32_t
333co_pdo_unmap(const struct co_pdo_map_par *par, const uint_least8_t *buf,
334 size_t n, co_unsigned64_t *val, co_unsigned8_t *pn)
335{
336 assert(par);
337 assert(buf);
338
339 if (par->n > CO_PDO_NUM_MAPS)
340 return CO_SDO_AC_PDO_LEN;
341
342 size_t offset = 0;
343 for (size_t i = 0; i < par->n; i++) {
344 co_unsigned32_t map = par->map[i];
345 if (!map)
346 continue;
347
348 co_unsigned8_t len = map & 0xff;
349 if (offset + len > n * 8)
350 return CO_SDO_AC_PDO_LEN;
351
352 uint_least8_t tmp[sizeof(co_unsigned64_t)] = { 0 };
353 bcpyle(tmp, 0, buf, offset, len);
354 if (val && pn && i < *pn)
355 val[i] = ldle_u64(tmp);
356
357 offset += len;
358 }
359
360 if (pn)
361 *pn = par->n;
362
363 return 0;
364}
365
366#if !LELY_NO_CO_RPDO
367co_unsigned32_t
368co_pdo_dn(const struct co_pdo_map_par *par, co_dev_t *dev,
369 struct co_sdo_req *req, const uint_least8_t *buf, size_t n,
370 int chk)
371{
372 assert(par);
373 assert(dev);
374 assert(req);
375 assert(buf);
376
377 if (par->n > CO_PDO_NUM_MAPS) {
378#if LELY_NO_CO_MPDO
379 return CO_SDO_AC_PDO_LEN;
380#else
381 return co_mpdo_dn(par, dev, req, buf, n);
382#endif // !LELY_NO_CO_MPDO
383 }
384
385 if (n > CAN_MAX_LEN)
386 return CO_SDO_AC_PDO_LEN;
387
388 size_t offset = 0;
389 for (size_t i = 0; i < par->n; i++) {
390 co_unsigned32_t map = par->map[i];
391 if (!map)
392 continue;
393
394 co_unsigned16_t idx = (map >> 16) & 0xffff;
395 co_unsigned8_t subidx = (map >> 8) & 0xff;
396 co_unsigned8_t len = map & 0xff;
397
398 // Check the PDO length.
399 if (offset + len > n * 8)
400 return CO_SDO_AC_PDO_LEN;
401
402 // Check, if necessary, whether the sub-object exists and can be
403 // mapped into an RPDO (or is a valid dummy entry).
404 co_unsigned32_t ac = 0;
405 if (chk && (ac = co_dev_chk_rpdo(dev, idx, subidx)))
406 return ac;
407
408 co_sub_t *sub = co_dev_find_sub(dev, idx, subidx);
409 if (sub) {
410 // Copy the value and download it into the sub-object.
411 uint_least8_t tmp[CAN_MAX_LEN] = { 0 };
412 bcpyle(tmp, 0, buf, offset, len);
413 co_sdo_req_clear(req);
414 req->size = (len + 7) / 8;
415 req->buf = tmp;
416 req->nbyte = req->size;
417 ac = co_sub_dn_ind(sub, req);
418 if (ac)
419 return ac;
420 }
421
422 offset += len;
423 }
424
425 return 0;
426}
427#endif // !LELY_NO_CO_RPDO
428
429#if !LELY_NO_CO_TPDO
430
431co_unsigned32_t
432co_pdo_up(const struct co_pdo_map_par *par, const co_dev_t *dev,
433 struct co_sdo_req *req, uint_least8_t *buf, size_t *pn, int chk)
434{
435 assert(par);
436 assert(dev);
437 assert(req);
438
439 if (par->n > CO_PDO_NUM_MAPS)
440 return CO_SDO_AC_PDO_LEN;
441
442 size_t offset = 0;
443 for (size_t i = 0; i < par->n; i++) {
444 co_unsigned32_t map = par->map[i];
445 if (!map)
446 continue;
447
448 co_unsigned16_t idx = (map >> 16) & 0xffff;
449 co_unsigned8_t subidx = (map >> 8) & 0xff;
450 co_unsigned8_t len = map & 0xff;
451
452 // Check the PDO length.
453 if (offset + len > CAN_MAX_LEN * 8)
454 return CO_SDO_AC_PDO_LEN;
455
456 // Check, if necessary, whether the sub-object exists and can be
457 // mapped into a TPDO.
458 co_unsigned32_t ac = 0;
459 if (chk && (ac = co_dev_chk_tpdo(dev, idx, subidx)))
460 return ac;
461
462 // Upload the value of the sub-object and copy the value.
463 co_sdo_req_clear(req);
464 ac = co_sub_up_ind(co_dev_find_sub(dev, idx, subidx), req);
465 if (ac)
466 return ac;
467 if (!co_sdo_req_first(req) || !co_sdo_req_last(req))
468 return CO_SDO_AC_PDO_LEN;
469 if (buf && pn && offset + len <= *pn * 8)
470 bcpyle(buf, offset, req->buf, 0, len);
471
472 offset += len;
473 }
474
475 if (pn)
476 *pn = (offset + 7) / 8;
477
478 return 0;
479}
480
481#if !LELY_NO_CO_MPDO
482co_unsigned32_t
483co_sam_mpdo_up(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx,
484 struct co_sdo_req *req, uint_least8_t buf[4])
485{
486 assert(dev);
487 assert(req);
488
489 // Check whether the sub-object can be mapped into a SAM-MPDO.
490 if (!co_dev_chk_sam_mpdo(dev, idx, subidx))
491 return CO_SDO_AC_NO_PDO;
492
493 // Check whether the sub-object exists and can be mapped into a TPDO.
494 co_unsigned32_t ac = co_dev_chk_tpdo(dev, idx, subidx);
495 if (ac)
496 return ac;
497
498 // Upload the value of the sub-object.
499 co_sdo_req_clear(req);
500 ac = co_sub_up_ind(co_dev_find_sub(dev, idx, subidx), req);
501 if (ac)
502 return ac;
503 // Check if the value is complete and fits in the PDO.
504 if (req->size > 4 || !co_sdo_req_first(req) || !co_sdo_req_last(req))
505 return CO_SDO_AC_PDO_LEN;
506 if (buf) {
507 // Copy the value and pad it with zeros, if necessary.
508 memcpy(buf, req->buf, req->size);
509 for (size_t i = req->size; i < 4; i++)
510 buf[i] = 0;
511 }
512
513 return 0;
514}
515#endif // !LELY_NO_CO_MPDO
516
517#endif // !LELY_NO_CO_TPDO
518
519static co_unsigned32_t
520co_dev_cfg_pdo_comm(const co_dev_t *dev, co_unsigned16_t idx,
521 const struct co_pdo_comm_par *par)
522{
523 assert(dev);
524 assert(par);
525
526 co_unsigned32_t ac = 0;
527
528 co_obj_t *obj = co_dev_find_obj(dev, idx);
529 if (!obj)
530 return CO_SDO_AC_NO_OBJ;
531
532 // Check if all sub-objects are available.
533 co_unsigned8_t n = co_obj_get_val_u8(obj, 0x00);
534 if (par->n > n)
535 return CO_SDO_AC_NO_SUB;
536
537 // Configure the COB-ID.
538 if (par->n >= 1) {
539 co_sub_t *sub = co_obj_find_sub(obj, 0x01);
540 if (!sub)
541 return CO_SDO_AC_NO_SUB;
543 }
544
545 // Configure the transmission type.
546 if (par->n >= 2 && !ac) {
547 co_sub_t *sub = co_obj_find_sub(obj, 0x02);
548 if (!sub)
549 return CO_SDO_AC_NO_SUB;
551 }
552
553 // Configure the inhibit time.
554 if (par->n >= 3 && !ac) {
555 co_sub_t *sub = co_obj_find_sub(obj, 0x03);
556 if (!sub)
557 return CO_SDO_AC_NO_SUB;
559 sub, CO_DEFTYPE_UNSIGNED16, &par->inhibit);
560 }
561
562 // Configure the event timer.
563 if (par->n >= 5 && !ac) {
564 co_sub_t *sub = co_obj_find_sub(obj, 0x05);
565 if (!sub)
566 return CO_SDO_AC_NO_SUB;
568 }
569
570 // Configure the SYNC start value.
571 if (par->n >= 6 && !ac) {
572 co_sub_t *sub = co_obj_find_sub(obj, 0x06);
573 if (!sub)
574 return CO_SDO_AC_NO_SUB;
576 }
577
578 return ac;
579}
580
581static co_unsigned32_t
582co_dev_cfg_pdo_map(const co_dev_t *dev, co_unsigned16_t idx,
583 const struct co_pdo_map_par *par)
584{
585 assert(dev);
586 assert(par);
587
588 co_unsigned32_t ac = 0;
589
590 co_obj_t *obj = co_dev_find_obj(dev, idx);
591 if (!obj)
592 return CO_SDO_AC_NO_OBJ;
593
594 co_sub_t *sub_00 = co_obj_find_sub(obj, 0x00);
595 if (!sub_00)
596 return CO_SDO_AC_NO_SUB;
597
598 // Disable mapping by setting subindex 0x00 to zero.
600 sub_00, CO_DEFTYPE_UNSIGNED8, &(co_unsigned8_t){ 0 });
601 if (ac)
602 return ac;
603
604 if (par->n <= CO_PDO_NUM_MAPS) {
605 // Copy the mapping parameters.
606 for (co_unsigned8_t i = 1; i <= par->n; i++) {
607 co_sub_t *sub = co_obj_find_sub(obj, i);
608 if (!sub)
609 return CO_SDO_AC_NO_SUB;
611 &par->map[i - 1]);
612 if (ac)
613 return ac;
614 }
615 }
616
617 // Enable mapping.
618 return co_sub_dn_ind_val(sub_00, CO_DEFTYPE_UNSIGNED8, &par->n);
619}
620
621#if !LELY_NO_CO_RPDO && !LELY_NO_CO_MPDO
622co_unsigned32_t
623co_mpdo_dn(const struct co_pdo_map_par *par, co_dev_t *dev,
624 struct co_sdo_req *req, const uint_least8_t *buf, size_t n)
625{
626 assert(par);
627 assert(dev);
628 assert(req);
629 assert(buf);
630
631 if ((par->n != CO_PDO_MAP_SAM_MPDO && par->n != CO_PDO_MAP_DAM_MPDO)
632 || n != CAN_MAX_LEN)
633 return CO_SDO_AC_PDO_LEN;
634
635 co_unsigned8_t id = buf[0];
636 co_unsigned16_t idx = ldle_u16(buf + 1);
637 co_unsigned8_t subidx = buf[3];
638 if (id & 0x80) {
639 // Ignore an unexpected DAM-MPDO.
640 if (par->n != CO_PDO_MAP_DAM_MPDO)
641 return 0;
642 // Check if the node-ID matches.
643 id &= 0x7f;
644 if (id && id != co_dev_get_id(dev))
645 return 0;
646 } else {
647 // Ignore an unexpected SAM-MPDO.
648 if (par->n != CO_PDO_MAP_SAM_MPDO)
649 return 0;
650 // Find the local object index and sub-index in the object
651 // dispatching list.
652 if (!co_dev_map_sam_mpdo(dev, id, idx, subidx, &idx, &subidx))
653 return 0;
654 }
655
656 // Check whether the sub-object exists and can be mapped into a PDO (or
657 // is a valid dummy entry).
658 co_unsigned32_t ac = co_dev_chk_rpdo(dev, idx, subidx);
659 if (ac)
660 return ac;
661
662 co_sub_t *sub = co_dev_find_sub(dev, idx, subidx);
663 if (sub) {
664 co_unsigned16_t type = co_sub_get_type(sub);
665 // Download the value to the sub-object.
666 co_sdo_req_clear(req);
667 // Discard any padding bytes.
668 req->size = co_type_is_basic(type)
669 ? MIN(co_type_sizeof(type), 4)
670 : 4;
671 req->buf = buf + 4;
672 req->nbyte = req->size;
673 ac = co_sub_dn_ind(sub, req);
674 if (ac)
675 return ac;
676 }
677
678 return 0;
679}
680#endif // !LELY_NO_CO_RPDO && !LELY_NO_CO_MPDO
681
682#endif // !LELY_NO_CO_RPDO || !LELY_NO_CO_TPDO
This header file is part of the CAN library; it contains the CAN frame declarations.
#define CAN_MAX_LEN
The maximum number of bytes in the payload of a CAN format frame.
Definition msg.h:72
This header file is part of the CANopen library; it contains the device description declarations.
co_obj_t * co_dev_find_obj(const co_dev_t *dev, co_unsigned16_t idx)
Finds an object in the object dictionary of a CANopen device.
Definition dev.c:279
co_unsigned8_t co_dev_get_id(const co_dev_t *dev)
Returns the node-ID of a CANopen device.
Definition dev.c:197
co_sub_t * co_dev_find_sub(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
Finds a sub-object in the object dictionary of a CANopen device.
Definition dev.c:290
co_unsigned32_t co_dev_get_dummy(const co_dev_t *dev)
Returns the data types supported by a CANopen device for mapping dummy entries in PDOs (one bit for e...
Definition dev.c:551
This header file is part of the utilities library; it contains the byte order (endianness) function d...
void stle_u64(uint_least8_t dst[8], uint_least64_t x)
Stores a 64-bit unsigned integer in little-endian byte order.
Definition endian.h:672
void bcpyle(uint_least8_t *dst, int dstbit, const uint_least8_t *src, int srcbit, size_t n)
Copies n bits from a source to a destination buffer.
Definition endian.c:123
uint_least16_t ldle_u16(const uint_least8_t src[2])
Loads a 16-bit unsigned integer in little-endian byte order.
Definition endian.h:516
uint_least64_t ldle_u64(const uint_least8_t src[8])
Loads a 64-bit unsigned integer in little-endian byte order.
Definition endian.h:690
This header file is part of the CANopen library; it contains the Service Data Object (SDO) declaratio...
int co_sdo_req_first(const struct co_sdo_req *req)
Returns 1 if the specified request includes the first segment, and 0 otherwise.
Definition sdo.h:343
#define CO_SDO_AC_NO_READ
SDO abort code: Attempt to read a write only object.
Definition sdo.h:87
#define CO_SDO_AC_NO_OBJ
SDO abort code: Object does not exist in the object dictionary.
Definition sdo.h:93
void co_sdo_req_clear(struct co_sdo_req *req)
Clears a CANopen SDO upload/download request, including its buffer.
Definition sdo.c:129
#define CO_SDO_AC_NO_SUB
SDO abort code: Sub-index does not exist.
Definition sdo.h:132
int co_sdo_req_last(const struct co_sdo_req *req)
Returns 1 if the specified request includes the last segment, and 0 otherwise.
Definition sdo.h:349
#define CO_SDO_AC_PDO_LEN
SDO abort code: The number and length of the objects to be mapped would exceed the PDO length.
Definition sdo.h:102
#define CO_SDO_AC_NO_PDO
SDO abort code: Object cannot be mapped to the PDO.
Definition sdo.h:96
#define CO_SDO_AC_NO_WRITE
SDO abort code: Attempt to write a read only object.
Definition sdo.h:90
#define MIN(a, b)
Returns the minimum of a and b.
Definition util.h:57
This header file is part of the CANopen library; it contains the object dictionary declarations.
co_sub_t * co_obj_first_sub(const co_obj_t *obj)
Finds the first sub-object (with the lowest sub-index) in a CANopen object.
Definition obj.c:249
#define CO_ACCESS_READ
The object can be read.
Definition obj.h:57
co_unsigned8_t co_sub_get_subidx(const co_sub_t *sub)
Returns the sub-index of a CANopen sub-object.
Definition obj.c:559
co_unsigned32_t co_sub_dn_ind(co_sub_t *sub, struct co_sdo_req *req)
Invokes the download indication function of a CANopen sub-object, registered with co_sub_set_dn_ind()...
Definition obj.c:958
co_unsigned16_t co_obj_get_idx(const co_obj_t *obj)
Returns the index of a CANopen object.
Definition obj.c:164
co_unsigned32_t co_sub_up_ind(const co_sub_t *sub, struct co_sdo_req *req)
Invokes the upload indication function of a CANopen sub-object, registered with co_sub_set_up_ind().
Definition obj.c:1066
co_unsigned32_t co_sub_dn_ind_val(co_sub_t *sub, co_unsigned16_t type, const void *val)
Invokes the download indication function of a CANopen sub-object, registered with co_sub_set_dn_ind()...
Definition obj.c:974
#define CO_ACCESS_RPDO
The object can be mapped to an RPDO.
Definition obj.h:66
int co_sub_get_pdo_mapping(const co_sub_t *sub)
Returns 1 if it is possible to map the specified CANopen sub-object into a PDO, and 0 if not.
Definition obj.c:802
co_sub_t * co_obj_find_sub(const co_obj_t *obj, co_unsigned8_t subidx)
Finds a sub-object in a CANopen object.
Definition obj.c:240
co_obj_t * co_obj_next(const co_obj_t *obj)
Finds the next object in the object dictionary of a CANopen device.
Definition obj.c:147
#define CO_ACCESS_TPDO
The object can be mapped to a TPDO.
Definition obj.h:63
co_sub_t * co_sub_next(const co_sub_t *sub)
Finds the next sub-object in a CANopen object.
Definition obj.c:542
#define CO_ACCESS_WRITE
The object can be written.
Definition obj.h:60
unsigned int co_sub_get_access(const co_sub_t *sub)
Returns the access type of a CANopen sub-object.
Definition obj.c:778
co_unsigned16_t co_sub_get_type(const co_sub_t *sub)
Returns the data type of a CANopen sub-object.
Definition obj.c:603
co_unsigned32_t co_pdo_unmap(const struct co_pdo_map_par *par, const uint_least8_t *buf, size_t n, co_unsigned64_t *val, co_unsigned8_t *pn)
Unmaps a PDO into its constituent values.
Definition pdo.c:333
co_unsigned32_t co_dev_chk_rpdo(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
Checks if the specified object is valid and can be mapped into a Receive-PDO.
Definition pdo.c:51
co_unsigned32_t co_pdo_up(const struct co_pdo_map_par *par, const co_dev_t *dev, struct co_sdo_req *req, uint_least8_t *buf, size_t *pn, int chk)
Reads mapped PDO values from the object dictionary through a local SDO upload request.
Definition pdo.c:432
co_unsigned32_t co_dev_cfg_rpdo_comm(const co_dev_t *dev, co_unsigned16_t num, const struct co_pdo_comm_par *par)
Configures the communication parameters of a Receive-PDO service by updating CANopen object 1400 - 15...
Definition pdo.c:106
co_unsigned32_t co_dev_cfg_tpdo_comm(const co_dev_t *dev, co_unsigned16_t num, const struct co_pdo_comm_par *par)
Configures the communication parameters of a Transmit-PDO service by updating CANopen object 1800 - 1...
Definition pdo.c:179
co_unsigned32_t co_sam_mpdo_up(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx, struct co_sdo_req *req, uint_least8_t buf[4])
Reads the value of the specified SAM-MPDO-mapped object from the local object dictionary through a lo...
Definition pdo.c:483
co_unsigned32_t co_dev_cfg_rpdo(const co_dev_t *dev, co_unsigned16_t num, const struct co_pdo_comm_par *comm, const struct co_pdo_map_par *map)
Configures the communication and parameters of a Receive-PDO service.
Definition pdo.c:80
co_unsigned32_t co_dev_cfg_tpdo(const co_dev_t *dev, co_unsigned16_t num, const struct co_pdo_comm_par *comm, const struct co_pdo_map_par *map)
Configures the communication and parameters of a Transmit-PDO service.
Definition pdo.c:153
co_unsigned32_t co_dev_chk_tpdo(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
Checks if the specified object is valid and can be mapped into a Transmit-PDO.
Definition pdo.c:130
co_unsigned32_t co_pdo_map(const struct co_pdo_map_par *par, const co_unsigned64_t *val, co_unsigned8_t n, uint_least8_t *buf, size_t *pn)
Maps values into a PDO.
Definition pdo.c:299
int co_dev_map_sam_mpdo(const co_dev_t *dev, co_unsigned8_t id, co_unsigned16_t idx, co_unsigned8_t subidx, co_unsigned16_t *pidx, co_unsigned8_t *psubidx)
Checks if the specified remote object is part of the object dispatching list (objects 1FD0....
Definition pdo.c:245
co_unsigned32_t co_pdo_dn(const struct co_pdo_map_par *par, co_dev_t *dev, struct co_sdo_req *req, const uint_least8_t *buf, size_t n, int chk)
Writes mapped PDO values to the object dictionary through a local SDO download request.
Definition pdo.c:368
co_unsigned32_t co_dev_cfg_tpdo_map(const co_dev_t *dev, co_unsigned16_t num, const struct co_pdo_map_par *par)
Configures the mapping parameters of a Transmit-PDO service by updating CANopen object 1A00 - 1BFF (T...
Definition pdo.c:189
int co_dev_chk_sam_mpdo(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
Checks if the specified object is part of the object scanner list (objects 1FA0..1FCF) and can be tra...
Definition pdo.c:203
co_unsigned32_t co_dev_cfg_rpdo_map(const co_dev_t *dev, co_unsigned16_t num, const struct co_pdo_map_par *par)
Configures the mapping parameters of a Receive-PDO service by updating CANopen object 1600 - 17FF (RP...
Definition pdo.c:116
This header file is part of the CANopen library; it contains the Process Data Object (PDO) declaratio...
#define CO_PDO_NUM_MAPS
The maximum number of mapped application objects in a single PDO.
Definition pdo.h:34
#define CO_PDO_COBID_VALID
The bit in the PDO COB-ID specifying whether the PDO exists and is valid.
Definition pdo.h:37
#define CO_NUM_PDOS
The maximum number of Receive/Transmit-PDOs.
Definition pdo.h:28
#define CO_PDO_MAP_DAM_MPDO
The value of sub-index 0 of the PDO mapping parameter record indicating a a destination address mode ...
Definition pdo.h:58
#define CO_PDO_MAP_SAM_MPDO
The value of sub-index 0 of the PDO mapping parameter record indicating a a source address mode multi...
Definition pdo.h:52
This is the internal header file of the CANopen library.
A CANopen device.
Definition dev.h:30
A CANopen object.
Definition obj.h:31
A CANopen sub-object.
Definition obj.h:53
A PDO communication parameter record.
Definition pdo.h:64
co_unsigned8_t sync
SYNC start value.
Definition pdo.h:77
co_unsigned16_t inhibit
Inhibit time.
Definition pdo.h:72
co_unsigned16_t event
Event timer.
Definition pdo.h:75
co_unsigned32_t cobid
COB-ID.
Definition pdo.h:68
co_unsigned8_t trans
Transmission type.
Definition pdo.h:70
co_unsigned8_t n
Highest sub-index supported.
Definition pdo.h:66
A PDO mapping parameter record.
Definition pdo.h:90
co_unsigned8_t n
Number of mapped objects in PDO.
Definition pdo.h:92
co_unsigned32_t map[CO_PDO_NUM_MAPS]
An array of objects to be mapped.
Definition pdo.h:94
A CANopen SDO upload/download request.
Definition sdo.h:181
size_t size
The total size (in bytes) of the value to be uploaded/downloaded.
Definition sdo.h:187
const void * buf
A pointer to the next bytes to be uploaded/downloaded.
Definition sdo.h:189
size_t nbyte
The number of bytes available at buf.
Definition sdo.h:191
#define CO_DEFTYPE_UNSIGNED16
The data type (and object index) of a 16-bit unsigned integer.
Definition type.h:47
#define CO_DEFTYPE_UNSIGNED8
The data type (and object index) of an 8-bit unsigned integer.
Definition type.h:44
size_t co_type_sizeof(co_unsigned16_t type)
Returns the native size (in bytes) of a value of the specified data type, or 1 if it is not a static ...
Definition type.c:52
#define CO_DEFTYPE_UNSIGNED32
The data type (and object index) of a 32-bit unsigned integer.
Definition type.h:50
int co_type_is_basic(co_unsigned16_t type)
Returns 1 if the specified (static) data type is a basic type, and 0 if not.
Definition type.c:28