Lely core libraries 2.3.4
lss.c
Go to the documentation of this file.
1
24#include "co.h"
25
26#if !LELY_NO_CO_LSS
27
28#include <lely/co/lss.h>
29#include <lely/co/nmt.h>
30#include <lely/co/obj.h>
31#include <lely/co/val.h>
32#include <lely/util/endian.h>
33#include <lely/util/errnum.h>
34#include <lely/util/time.h>
35
36#include <assert.h>
37#include <stdlib.h>
38
39struct __co_lss_state;
41typedef const struct __co_lss_state co_lss_state_t;
42
44struct __co_lss {
53#if !LELY_NO_CO_MASTER
55 int master;
57 co_unsigned16_t inhibit;
59 int next;
60#endif
63#if !LELY_NO_CO_MASTER
68#endif
70 co_unsigned8_t cs;
72 co_unsigned8_t lsspos;
73#if !LELY_NO_CO_MASTER
75 struct co_id lo;
77 struct co_id hi;
79 struct co_id mask;
81 co_unsigned8_t bitchk;
86 co_unsigned8_t lsssub;
88 co_unsigned8_t err;
90 co_unsigned8_t spec;
92 co_unsigned32_t lssid;
94 co_unsigned8_t nid;
96 struct co_id id;
97#endif
106#if !LELY_NO_CO_MASTER
110 void *cs_data;
114 void *err_data;
122 void *nid_data;
127#endif
128};
129
131static int co_lss_recv(const struct can_msg *msg, void *data);
132
133#if !LELY_NO_CO_MASTER
135static int co_lss_timer(const struct timespec *tp, void *data);
136#endif
137
142static void co_lss_enter(co_lss_t *lss, co_lss_state_t *next);
143
151static inline void co_lss_emit_recv(co_lss_t *lss, const struct can_msg *msg);
152
153#if !LELY_NO_CO_MASTER
161static inline void co_lss_emit_time(co_lss_t *lss, const struct timespec *tp);
162#endif
163
167 co_lss_state_t *(*on_enter)(co_lss_t *lss);
177 co_lss_state_t *(*on_recv)(co_lss_t *lss, const struct can_msg *msg);
178#if !LELY_NO_CO_MASTER
187 co_lss_state_t *(*on_time)(co_lss_t *lss, const struct timespec *tp);
188#endif
190 void (*on_leave)(co_lss_t *lss);
191};
192
193#define LELY_CO_DEFINE_STATE(name, ...) \
194 static co_lss_state_t *const name = &(co_lss_state_t){ __VA_ARGS__ };
195
197LELY_CO_DEFINE_STATE(co_lss_stopped_state, .on_recv = NULL)
198
199
201
203// clang-format off
204LELY_CO_DEFINE_STATE(co_lss_wait_state,
205 .on_enter = &co_lss_wait_on_enter
207// clang-format on
208
209
211
217 co_lss_t *lss, const struct can_msg *msg);
218
220// clang-format off
221LELY_CO_DEFINE_STATE(co_lss_wait_slave_state,
222 .on_enter = &co_lss_wait_slave_on_enter,
223 .on_recv = &co_lss_wait_slave_on_recv
225// clang-format on
226
232 co_lss_t *lss, const struct can_msg *msg);
233
235// clang-format off
236LELY_CO_DEFINE_STATE(co_lss_cfg_state,
237 .on_recv = &co_lss_cfg_on_recv
239// clang-format on
240
241#if !LELY_NO_CO_MASTER
242
245 co_lss_t *lss, const struct can_msg *msg);
246
249 co_lss_t *lss, const struct timespec *tp);
250
252// clang-format off
253LELY_CO_DEFINE_STATE(co_lss_cs_state,
254 .on_recv = &co_lss_cs_on_recv,
255 .on_time = &co_lss_cs_on_time
257// clang-format on
258
259
261
263static void co_lss_cs_fini_on_leave(co_lss_t *lss);
264
266// clang-format off
267LELY_CO_DEFINE_STATE(co_lss_cs_fini_state,
268 .on_enter = &co_lss_cs_fini_on_enter,
269 .on_leave = &co_lss_cs_fini_on_leave
271// clang-format on
272
275
278 co_lss_t *lss, const struct timespec *tp);
279
281// clang-format off
282LELY_CO_DEFINE_STATE(co_lss_switch_sel_state,
283 .on_enter = &co_lss_switch_sel_on_enter,
284 .on_time = &co_lss_switch_sel_on_time
286// clang-format on
287
290 co_lss_t *lss, const struct can_msg *msg);
291
294 co_lss_t *lss, const struct timespec *tp);
295
297static void co_lss_err_on_leave(co_lss_t *lss);
298
300// clang-format off
301LELY_CO_DEFINE_STATE(co_lss_err_state,
302 .on_recv = &co_lss_err_on_recv,
303 .on_time = &co_lss_err_on_time,
304 .on_leave = &co_lss_err_on_leave
306// clang-format on
307
310 co_lss_t *lss, const struct can_msg *msg);
311
314 co_lss_t *lss, const struct timespec *tp);
315
317static void co_lss_lssid_on_leave(co_lss_t *lss);
318
320// clang-format off
321LELY_CO_DEFINE_STATE(co_lss_lssid_state,
322 .on_recv = &co_lss_lssid_on_recv,
323 .on_time = &co_lss_lssid_on_time,
324 .on_leave = &co_lss_lssid_on_leave
326// clang-format on
327
330 co_lss_t *lss, const struct can_msg *msg);
331
334 co_lss_t *lss, const struct timespec *tp);
335
337static void co_lss_nid_on_leave(co_lss_t *lss);
338
340// clang-format off
341LELY_CO_DEFINE_STATE(co_lss_nid_state,
342 .on_recv = &co_lss_nid_on_recv,
343 .on_time = &co_lss_nid_on_time,
344 .on_leave = &co_lss_nid_on_leave
346// clang-format on
347
350
353 co_lss_t *lss, const struct timespec *tp);
354
356// clang-format off
357LELY_CO_DEFINE_STATE(co_lss_id_slave_state,
358 .on_enter = &co_lss_id_slave_on_enter,
359 .on_time = &co_lss_id_slave_on_time
361// clang-format on
362
365
371 co_lss_t *lss, const struct can_msg *msg);
372
375 co_lss_t *lss, const struct timespec *tp);
376
378// clang-format off
379LELY_CO_DEFINE_STATE(co_lss_slowscan_init_state,
384// clang-format on
385
388
391 co_lss_t *lss, const struct can_msg *msg);
392
395 co_lss_t *lss, const struct timespec *tp);
396
397static co_lss_state_t *co_lss_slowscan_scan_on_res(co_lss_t *lss, int timeout);
398
400// clang-format off
401LELY_CO_DEFINE_STATE(co_lss_slowscan_scan_state,
406// clang-format on
407
410 co_lss_t *lss, const struct can_msg *msg);
411
414 co_lss_t *lss, const struct timespec *tp);
415
417// clang-format off
418LELY_CO_DEFINE_STATE(co_lss_slowscan_wait_state,
422// clang-format on
423
426
432 co_lss_t *lss, const struct can_msg *msg);
433
439 co_lss_t *lss, const struct timespec *tp);
440
442// clang-format off
443LELY_CO_DEFINE_STATE(co_lss_slowscan_switch_state,
448// clang-format on
449
452
455
457// clang-format off
458LELY_CO_DEFINE_STATE(co_lss_slowscan_fini_state,
462// clang-format on
463
469 co_lss_t *lss, const struct can_msg *msg);
470
473 co_lss_t *lss, const struct timespec *tp);
474
476// clang-format off
477LELY_CO_DEFINE_STATE(co_lss_fastscan_init_state,
481// clang-format on
482
485
488 co_lss_t *lss, const struct can_msg *msg);
489
492 co_lss_t *lss, const struct timespec *tp);
493
494static co_lss_state_t *co_lss_fastscan_scan_on_res(co_lss_t *lss, int timeout);
495
497// clang-format off
498LELY_CO_DEFINE_STATE(co_lss_fastscan_scan_state,
503// clang-format on
504
507 co_lss_t *lss, const struct can_msg *msg);
508
511 co_lss_t *lss, const struct timespec *tp);
512
514// clang-format off
515LELY_CO_DEFINE_STATE(co_lss_fastscan_wait_state,
519// clang-format on
520
523
526
528// clang-format off
529LELY_CO_DEFINE_STATE(co_lss_fastscan_fini_state,
533// clang-format on
534
535#endif // !LELY_NO_CO_MASTER
536
537#undef LELY_CO_DEFINE_STATE
538
550 co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id);
551
560static void co_lss_id_slave(
561 co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id);
562
567static void co_lss_id_non_cfg_slave(const co_lss_t *lss);
568
583static co_lss_state_t *co_lss_fastscan(co_lss_t *lss, co_unsigned32_t id,
584 co_unsigned8_t bitchk, co_unsigned8_t lsssub,
585 co_unsigned8_t lssnext);
586
594static void co_lss_init_req(
595 const co_lss_t *lss, struct can_msg *msg, co_unsigned8_t cs);
596
597#if !LELY_NO_CO_MASTER
598
610static int co_lss_send_switch_sel_req(co_lss_t *lss, const struct co_id *id);
611
625static int co_lss_send_id_slave_req(
626 co_lss_t *lss, const struct co_id *lo, const struct co_id *hi);
627
639static int co_lss_send_fastscan_req(const co_lss_t *lss, co_unsigned32_t id,
640 co_unsigned8_t bitchk, co_unsigned8_t lsssub,
641 co_unsigned8_t lssnext);
642
649static void co_lss_init_ind(co_lss_t *lss, co_unsigned8_t cs);
650
659static inline co_unsigned32_t *co_id_sub(struct co_id *id, co_unsigned8_t sub);
660
661#endif // !LELY_NO_CO_MASTER
662
663void *
664__co_lss_alloc(void)
665{
666 void *ptr = malloc(sizeof(struct __co_lss));
667#if !LELY_NO_ERRNO
668 if (!ptr)
669 set_errc(errno2c(errno));
670#endif
671 return ptr;
672}
673
674void
675__co_lss_free(void *ptr)
676{
677 free(ptr);
678}
679
680struct __co_lss *
681__co_lss_init(struct __co_lss *lss, co_nmt_t *nmt)
682{
683 assert(lss);
684 assert(nmt);
685
686 int errc = 0;
687
688 lss->nmt = nmt;
689 lss->net = co_nmt_get_net(lss->nmt);
690 lss->dev = co_nmt_get_dev(lss->nmt);
691
693
694#if !LELY_NO_CO_MASTER
695 lss->master = 0;
697 lss->next = 0;
698#endif
699
700 lss->recv = can_recv_create();
701 if (!lss->recv) {
702 errc = get_errc();
703 goto error_create_recv;
704 }
706
707#if !LELY_NO_CO_MASTER
709
710 lss->timer = can_timer_create();
711 if (!lss->timer) {
712 errc = get_errc();
713 goto error_create_timer;
714 }
716#endif
717
718 lss->cs = 0;
719 lss->lsspos = 0;
720#if !LELY_NO_CO_MASTER
721 lss->lo = (struct co_id)CO_ID_INIT;
722 lss->hi = (struct co_id)CO_ID_INIT;
723 lss->mask = (struct co_id)CO_ID_INIT;
724 lss->bitchk = 0;
725 lss->lsssub = 0;
726 lss->err = 0;
727 lss->spec = 0;
728 lss->lssid = 0;
729 lss->nid = 0;
730 lss->id = (struct co_id)CO_ID_INIT;
731#endif
732
733 lss->rate_ind = NULL;
734 lss->rate_data = NULL;
735 lss->store_ind = NULL;
736 lss->store_data = NULL;
737#if !LELY_NO_CO_MASTER
738 lss->cs_ind = NULL;
739 lss->cs_data = NULL;
740 lss->err_ind = NULL;
741 lss->err_data = NULL;
742 lss->lssid_ind = NULL;
743 lss->lssid_data = NULL;
744 lss->nid_ind = NULL;
745 lss->nid_data = NULL;
746 lss->scan_ind = NULL;
747 lss->scan_data = NULL;
748#endif
749
750 if (co_lss_start(lss) == -1) {
751 errc = get_errc();
752 goto error_start;
753 }
754
755 return lss;
756
757 // co_lss_stop(lss);
758error_start:
759#if !LELY_NO_CO_MASTER
761error_create_timer:
762#endif
764error_create_recv:
765 set_errc(errc);
766 return NULL;
767}
768
769void
770__co_lss_fini(struct __co_lss *lss)
771{
772 assert(lss);
773
774 co_lss_stop(lss);
775
776#if !LELY_NO_CO_MASTER
778#endif
780}
781
782co_lss_t *
784{
785 trace("creating LSS");
786
787 int errc = 0;
788
789 co_lss_t *lss = __co_lss_alloc();
790 if (!lss) {
791 errc = get_errc();
792 goto error_alloc_lss;
793 }
794
795 if (!__co_lss_init(lss, nmt)) {
796 errc = get_errc();
797 goto error_init_lss;
798 }
799
800 return lss;
801
802error_init_lss:
803 __co_lss_free(lss);
804error_alloc_lss:
805 set_errc(errc);
806 return NULL;
807}
808
809void
811{
812 if (lss) {
813 trace("destroying LSS");
814 __co_lss_fini(lss);
815 __co_lss_free(lss);
816 }
817}
818
819int
821{
822 assert(lss);
823
824 if (!co_lss_is_stopped(lss))
825 return 0;
826
828
829 return 0;
830}
831
832void
834{
835 assert(lss);
836
837 if (co_lss_is_stopped(lss))
838 return;
839
840#if !LELY_NO_CO_MASTER
841 can_timer_stop(lss->timer);
842#endif
843 can_recv_stop(lss->recv);
844
846}
847
848int
850{
851 assert(lss);
852
853 return lss->state == co_lss_stopped_state;
854}
855
856co_nmt_t *
858{
859 assert(lss);
860
861 return lss->nmt;
862}
863
864void
865co_lss_get_rate_ind(const co_lss_t *lss, co_lss_rate_ind_t **pind, void **pdata)
866{
867 assert(lss);
868
869 if (pind)
870 *pind = lss->rate_ind;
871 if (pdata)
872 *pdata = lss->rate_data;
873}
874
875void
877{
878 assert(lss);
879
880 lss->rate_ind = ind;
881 lss->rate_data = data;
882}
883
884void
886 const co_lss_t *lss, co_lss_store_ind_t **pind, void **pdata)
887{
888 assert(lss);
889
890 if (pind)
891 *pind = lss->store_ind;
892 if (pdata)
893 *pdata = lss->store_data;
894}
895
896void
898{
899 assert(lss);
900
901 lss->store_ind = ind;
902 lss->store_data = data;
903}
904
905#if !LELY_NO_CO_MASTER
906
907co_unsigned16_t
909{
910 assert(lss);
911
912 return lss->inhibit;
913}
914
915void
916co_lss_set_inhibit(co_lss_t *lss, co_unsigned16_t inhibit)
917{
918 assert(lss);
919
920 lss->inhibit = inhibit;
921}
922
923int
925{
926 assert(lss);
927
928 return lss->timeout;
929}
930
931void
932co_lss_set_timeout(co_lss_t *lss, int timeout)
933{
934 assert(lss);
935
936 if (lss->timeout && timeout <= 0)
937 can_timer_stop(lss->timer);
938
939 lss->timeout = MAX(0, timeout);
940}
941
942#endif // !LELY_NO_CO_MASTER
943
944int
946{
947#if LELY_NO_CO_MASTER
948 (void)lss;
949
950 return 0;
951#else
952 assert(lss);
953
954 return lss->master;
955#endif
956}
957
958#if !LELY_NO_CO_MASTER
959
960int
962{
963 assert(lss);
964
965 return lss->state == co_lss_wait_state;
966}
967
968void
970{
971 assert(lss);
972
974}
975
976int
977co_lss_switch_req(co_lss_t *lss, co_unsigned8_t mode)
978{
979 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
981 return -1;
982 }
983
984 if (mode > 0x01) {
986 return -1;
987 }
988
989 trace("LSS: switch state global");
990
991 // Switch state global (see Fig. 31 in CiA 305 version 3.0.0).
992 struct can_msg req;
993 co_lss_init_req(lss, &req, 0x04);
994 req.data[1] = mode;
995 return can_net_send(lss->net, &req);
996}
997
998int
999co_lss_switch_sel_req(co_lss_t *lss, const struct co_id *id,
1000 co_lss_cs_ind_t *ind, void *data)
1001{
1002 assert(id);
1003
1004 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1006 return -1;
1007 }
1008
1009 trace("LSS: switch state selective");
1010
1011 lss->id = *id;
1012
1013 lss->cs_ind = ind;
1014 lss->cs_data = data;
1016
1017 return 0;
1018}
1019
1020int
1021co_lss_set_id_req(co_lss_t *lss, co_unsigned8_t id, co_lss_err_ind_t *ind,
1022 void *data)
1023{
1024 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1026 return -1;
1027 }
1028
1029 if (!id || (id > CO_NUM_NODES && id != 0xff)) {
1031 return -1;
1032 }
1033
1034 trace("LSS: configure node-ID");
1035
1036 // Configure node-ID (see Fig. 33 in CiA 305 version 3.0.0).
1037 struct can_msg req;
1038 co_lss_init_req(lss, &req, 0x11);
1039 req.data[1] = id;
1040 if (can_net_send(lss->net, &req) == -1)
1041 return -1;
1042
1043 // Wait for response.
1044 co_lss_init_ind(lss, req.data[0]);
1045 lss->err_ind = ind;
1046 lss->err_data = data;
1048
1049 return 0;
1050}
1051
1052int
1053co_lss_set_rate_req(co_lss_t *lss, co_unsigned16_t rate, co_lss_err_ind_t *ind,
1054 void *data)
1055{
1056 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1058 return -1;
1059 }
1060
1061 // Configure bit timing parameters (see Fig. 34 in CiA 305 version
1062 // 3.0.0).
1063 struct can_msg req;
1064 co_lss_init_req(lss, &req, 0x13);
1065 req.data[1] = 0;
1066 switch (rate) {
1067 case 1000: req.data[2] = 0; break;
1068 case 800: req.data[2] = 1; break;
1069 case 500: req.data[2] = 2; break;
1070 case 250: req.data[2] = 3; break;
1071 case 125: req.data[2] = 4; break;
1072 case 50: req.data[2] = 6; break;
1073 case 20: req.data[2] = 7; break;
1074 case 10: req.data[2] = 8; break;
1075 case 0: req.data[2] = 9; break;
1076 default: set_errnum(ERRNUM_INVAL); return 0;
1077 }
1078
1079 trace("LSS: configure bit timing parameters");
1080
1081 if (can_net_send(lss->net, &req) == -1)
1082 return -1;
1083
1084 // Wait for response.
1085 co_lss_init_ind(lss, req.data[0]);
1086 lss->err_ind = ind;
1087 lss->err_data = data;
1089
1090 return 0;
1091}
1092
1093int
1095{
1096 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1098 return -1;
1099 }
1100
1101 if (delay < CO_UNSIGNED16_MIN || delay > CO_UNSIGNED16_MAX) {
1103 return -1;
1104 }
1105
1106 trace("LSS: activate bit timing parameters");
1107
1108 // Activate bit timing parameters (see Fig. 35 in CiA 305 version
1109 // 3.0.0).
1110 struct can_msg req;
1111 co_lss_init_req(lss, &req, 0x15);
1112 stle_u16(req.data + 1, (co_unsigned16_t)delay);
1113 return can_net_send(lss->net, &req);
1114}
1115
1116int
1118{
1119 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1121 return -1;
1122 }
1123
1124 trace("LSS: store configuration");
1125
1126 // Store configuration (see Fig. 36 in CiA 305 version 3.0.0).
1127 struct can_msg req;
1128 co_lss_init_req(lss, &req, 0x17);
1129 if (can_net_send(lss->net, &req) == -1)
1130 return -1;
1131
1132 // Wait for response.
1133 co_lss_init_ind(lss, req.data[0]);
1134 lss->err_ind = ind;
1135 lss->err_data = data;
1137
1138 return 0;
1139}
1140
1141int
1143{
1144 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1146 return -1;
1147 }
1148
1149 trace("LSS: inquire identity vendor-ID");
1150
1151 // Inquire identity vendor-ID (see Fig. 37 in CiA 305 version 3.0.0).
1152 struct can_msg req;
1153 co_lss_init_req(lss, &req, 0x5a);
1154 if (can_net_send(lss->net, &req) == -1)
1155 return -1;
1156
1157 // Wait for response.
1158 co_lss_init_ind(lss, req.data[0]);
1159 lss->lssid_ind = ind;
1160 lss->lssid_data = data;
1162
1163 return 0;
1164}
1165
1166int
1168{
1169 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1171 return -1;
1172 }
1173
1174 trace("LSS: inquire identity product-code");
1175
1176 // Inquire identity product-code (see Fig. 38 in CiA 305 version 3.0.0).
1177 struct can_msg req;
1178 co_lss_init_req(lss, &req, 0x5b);
1179 if (can_net_send(lss->net, &req) == -1)
1180 return -1;
1181
1182 // Wait for response.
1183 co_lss_init_ind(lss, req.data[0]);
1184 lss->lssid_ind = ind;
1185 lss->lssid_data = data;
1187
1188 return 0;
1189}
1190
1191int
1193{
1194 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1196 return -1;
1197 }
1198
1199 trace("LSS: inquire identity revision-number");
1200
1201 // Inquire identity revision-number (see Fig. 39 in CiA 305 version
1202 // 3.0.0).
1203 struct can_msg req;
1204 co_lss_init_req(lss, &req, 0x5c);
1205 if (can_net_send(lss->net, &req) == -1)
1206 return -1;
1207
1208 // Wait for response.
1209 co_lss_init_ind(lss, req.data[0]);
1210 lss->lssid_ind = ind;
1211 lss->lssid_data = data;
1213
1214 return 0;
1215}
1216
1217int
1219{
1220 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1222 return -1;
1223 }
1224
1225 trace("LSS: inquire identity serial number");
1226
1227 // Inquire identity serial-number (see Fig. 40 in CiA 305 version
1228 // 3.0.0).
1229 struct can_msg req;
1230 co_lss_init_req(lss, &req, 0x5d);
1231 if (can_net_send(lss->net, &req) == -1)
1232 return -1;
1233
1234 // Wait for response.
1235 co_lss_init_ind(lss, req.data[0]);
1236 lss->lssid_ind = ind;
1237 lss->lssid_data = data;
1239
1240 return 0;
1241}
1242
1243int
1245{
1246 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1248 return -1;
1249 }
1250
1251 trace("LSS: inquire node-ID");
1252
1253 // Inquire node-ID (see Fig. 41 in CiA 305 version 3.0.0).
1254 struct can_msg req;
1255 co_lss_init_req(lss, &req, 0x5e);
1256 if (can_net_send(lss->net, &req) == -1)
1257 return -1;
1258
1259 // Wait for response.
1260 co_lss_init_ind(lss, req.data[0]);
1261 lss->nid_ind = ind;
1262 lss->nid_data = data;
1264
1265 return 0;
1266}
1267
1268int
1269co_lss_id_slave_req(co_lss_t *lss, const struct co_id *lo,
1270 const struct co_id *hi, co_lss_cs_ind_t *ind, void *data)
1271{
1272 assert(lo);
1273 assert(hi);
1274
1275 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1277 return -1;
1278 }
1279
1280 if (lo->vendor_id != hi->vendor_id
1281 || lo->product_code != hi->product_code
1282 || lo->revision > hi->revision
1283 || lo->serial_nr > hi->serial_nr) {
1285 return -1;
1286 }
1287
1288 trace("LSS: identify remote slave");
1289
1290 lss->lo = *lo;
1291 lss->lo.n = 4;
1292 lss->hi = *hi;
1293 lss->hi.n = 4;
1294
1295 lss->cs_ind = ind;
1296 lss->cs_data = data;
1298
1299 return 0;
1300}
1301
1302int
1304{
1305 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1307 return -1;
1308 }
1309
1310 trace("LSS: identify non-configured remote slave");
1311
1312 // LSS identify non-configured remote slave (see Fig. 44 in CiA 305
1313 // version 3.0.0).
1314 struct can_msg req;
1315 co_lss_init_req(lss, &req, 0x4c);
1316 if (can_net_send(lss->net, &req) == -1)
1317 return -1;
1318
1319 // Wait for response (see Fig. 45 in CiA 305 version 3.0.0).
1320 co_lss_init_ind(lss, 0x50);
1321 lss->cs_ind = ind;
1322 lss->cs_data = data;
1324
1325 return 0;
1326}
1327
1328int
1329co_lss_slowscan_req(co_lss_t *lss, const struct co_id *lo,
1330 const struct co_id *hi, co_lss_scan_ind_t *ind, void *data)
1331{
1332 assert(lo);
1333 assert(hi);
1334
1335 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1337 return -1;
1338 }
1339
1340 if (lo->vendor_id != hi->vendor_id
1341 || lo->product_code != hi->product_code
1342 || lo->revision > hi->revision
1343 || lo->serial_nr > hi->serial_nr) {
1345 return -1;
1346 }
1347
1348 trace("LSS: Slowscan");
1349
1350 lss->lo = *lo;
1351 lss->lo.n = 4;
1352 lss->hi = *hi;
1353 lss->hi.n = 4;
1354
1355 lss->id = (struct co_id)CO_ID_INIT;
1356
1357 lss->scan_ind = ind;
1358 lss->scan_data = data;
1360
1361 return 0;
1362}
1363
1364int
1365co_lss_fastscan_req(co_lss_t *lss, const struct co_id *id,
1366 const struct co_id *mask, co_lss_scan_ind_t *ind, void *data)
1367{
1368 if (!co_lss_is_master(lss) || !co_lss_is_idle(lss)) {
1370 return -1;
1371 }
1372
1373 trace("LSS: Fastscan");
1374
1375 lss->id = (struct co_id)CO_ID_INIT;
1376 lss->mask = (struct co_id)CO_ID_INIT;
1377 if (mask) {
1378 lss->mask = *mask;
1379 lss->mask.n = 4;
1380 if (id) {
1381 lss->id = *id;
1382 lss->id.n = 4;
1383 // Clear all unmasked bits in the LSS address.
1384 lss->id.vendor_id &= lss->mask.vendor_id;
1385 lss->id.product_code &= lss->mask.product_code;
1386 lss->id.revision &= lss->mask.revision;
1387 lss->id.serial_nr &= lss->mask.serial_nr;
1388 }
1389 }
1390 lss->bitchk = 0x80;
1391 lss->lsssub = 0;
1392
1393 // LSS Fastscan (see Fig. 46 in CiA 305 version 3.0.0).
1394 struct can_msg req;
1395 co_lss_init_req(lss, &req, 0x51);
1396 req.data[5] = lss->bitchk;
1397 if (can_net_send(lss->net, &req) == -1)
1398 return -1;
1399
1400 // Wait for response (see Fig. 43 in CiA 305 version 3.0.0).
1401 co_lss_init_ind(lss, 0x4f);
1402 lss->scan_ind = ind;
1403 lss->scan_data = data;
1405
1406 return 0;
1407}
1408
1409#endif // !LELY_NO_CO_MASTER
1410
1411static int
1412co_lss_recv(const struct can_msg *msg, void *data)
1413{
1414 assert(msg);
1415 co_lss_t *lss = data;
1416 assert(lss);
1417
1418 co_lss_emit_recv(lss, msg);
1419
1420 return 0;
1421}
1422
1423#if !LELY_NO_CO_MASTER
1424static int
1425co_lss_timer(const struct timespec *tp, void *data)
1426{
1427 assert(tp);
1428 co_lss_t *lss = data;
1429 assert(lss);
1430
1431 co_lss_emit_time(lss, tp);
1432
1433 return 0;
1434}
1435#endif
1436
1437static void
1439{
1440 assert(lss);
1441
1442 while (next) {
1443 co_lss_state_t *prev = lss->state;
1444 lss->state = next;
1445
1446 if (prev && prev->on_leave)
1447 prev->on_leave(lss);
1448
1449 next = next->on_enter ? next->on_enter(lss) : NULL;
1450 }
1451}
1452
1453static inline void
1454co_lss_emit_recv(co_lss_t *lss, const struct can_msg *msg)
1455{
1456 assert(lss);
1457 assert(lss->state);
1458 assert(lss->state->on_recv);
1459
1460 co_lss_enter(lss, lss->state->on_recv(lss, msg));
1461}
1462
1463#if !LELY_NO_CO_MASTER
1464static inline void
1465co_lss_emit_time(co_lss_t *lss, const struct timespec *tp)
1466{
1467 assert(lss);
1468 assert(lss->state);
1469 assert(lss->state->on_time);
1470
1471 co_lss_enter(lss, lss->state->on_time(lss, tp));
1472}
1473#endif
1474
1475static co_lss_state_t *
1477{
1478#if LELY_NO_CO_MASTER
1479 (void)lss;
1480#else
1481 assert(lss);
1482
1483 // Only an NMT master can be an LSS master.
1484 lss->master = co_nmt_is_master(lss->nmt);
1485 if (lss->master)
1486 return NULL;
1487#endif
1488
1490}
1491
1492static co_lss_state_t *
1494{
1495 assert(lss);
1496
1497 lss->cs = 0;
1498 lss->lsspos = 0;
1499
1500 // Start receiving LSS commands from the master.
1501 can_recv_start(lss->recv, lss->net, CO_LSS_CANID(1), 0);
1502
1503 return NULL;
1504}
1505
1506static co_lss_state_t *
1508{
1509 assert(lss);
1510 assert(msg);
1511
1512 if (!msg->len)
1513 return NULL;
1514
1515 co_unsigned8_t cs = msg->data[0];
1516 switch (cs) {
1517 // Switch state global (see Fig. 31 in CiA 305 version 3.0.0).
1518 case 0x04:
1519 if (msg->len < 2)
1520 return NULL;
1521 switch (msg->data[1]) {
1522 case 0x00:
1523 // Re-enter the waiting state.
1524 trace("LSS: switching to waiting state");
1525 return co_lss_wait_state;
1526 case 0x01:
1527 // Switch to the configuration state.
1528 trace("LSS: switching to configuration state");
1529 return co_lss_cfg_state;
1530 }
1531 break;
1532 // Switch state selective.
1533 case 0x40:
1534 case 0x41:
1535 case 0x42:
1536 case 0x43:
1537 if (msg->len < 5)
1538 return NULL;
1539 return co_lss_switch_sel(lss, cs, ldle_u32(msg->data + 1));
1540 // LSS identify remote slave.
1541 case 0x46:
1542 case 0x47:
1543 case 0x48:
1544 case 0x49:
1545 case 0x4a:
1546 case 0x4b:
1547 if (msg->len < 5)
1548 return NULL;
1549 co_lss_id_slave(lss, msg->data[0], ldle_u32(msg->data + 1));
1550 break;
1551 // LSS identify non-configured remote slave.
1552 case 0x4c: co_lss_id_non_cfg_slave(lss); break;
1553 // LSS Fastscan.
1554 case 0x51:
1555 if (msg->len < 8)
1556 return NULL;
1557 return co_lss_fastscan(lss, ldle_u32(msg->data + 1),
1558 msg->data[5], msg->data[6], msg->data[7]);
1559 }
1560
1561 return NULL;
1562}
1563
1564static co_lss_state_t *
1565co_lss_cfg_on_recv(co_lss_t *lss, const struct can_msg *msg)
1566{
1567 assert(lss);
1568 assert(msg);
1569
1570 int errc = get_errc();
1571 co_obj_t *obj_1018 = co_dev_find_obj(lss->dev, 0x1018);
1572 struct can_msg req;
1573
1574 if (!msg->len)
1575 return NULL;
1576
1577 co_unsigned8_t cs = msg->data[0];
1578 switch (cs) {
1579 // Switch state global (see Fig. 31 in CiA 305 version 3.0.0).
1580 case 0x04:
1581 if (msg->len < 2)
1582 return NULL;
1583 switch (msg->data[1]) {
1584 case 0x00:
1585 // Switch to the waiting state.
1586 trace("LSS: switching to waiting state");
1587 return co_lss_wait_state;
1588 case 0x01:
1589 // Re-enter the configuration state.
1590 trace("LSS: switching to configuration state");
1591 return co_lss_cfg_state;
1592 }
1593 break;
1594 // Configure node-ID (see Fig. 33 in CiA 305 version 3.0.0).
1595 case 0x11:
1596 if (msg->len < 2)
1597 return NULL;
1598 // Configure the pending node-ID.
1599 trace("LSS: configuring node-ID");
1600 co_lss_init_req(lss, &req, cs);
1601 if (co_nmt_set_id(lss->nmt, msg->data[1]) == -1) {
1602 // Discard the error code if the node-ID was invalid.
1603 set_errc(errc);
1604 req.data[1] = 1;
1605 }
1606 can_net_send(lss->net, &req);
1607 break;
1608 // Configure bit timing parameters (see Fig. 34 in CiA 305 version
1609 // 3.0.0).
1610 case 0x13:
1611 if (msg->len < 3)
1612 return NULL;
1613 // Configure the pending baudrate.
1614 trace("LSS: configuring bit timing parameters");
1615 co_lss_init_req(lss, &req, cs);
1616 if (!lss->rate_ind || msg->data[1]) {
1617 req.data[1] = 1;
1618 } else {
1619 unsigned int baud = co_dev_get_baud(lss->dev);
1620 switch (msg->data[2]) {
1621 case 0:
1622 if (!(req.data[1] = !(baud & CO_BAUD_1000)))
1623 co_dev_set_rate(lss->dev, 1000);
1624 break;
1625 case 1:
1626 if (!(req.data[1] = !(baud & CO_BAUD_800)))
1627 co_dev_set_rate(lss->dev, 800);
1628 break;
1629 case 2:
1630 if (!(req.data[1] = !(baud & CO_BAUD_500)))
1631 co_dev_set_rate(lss->dev, 500);
1632 break;
1633 case 3:
1634 if (!(req.data[1] = !(baud & CO_BAUD_250)))
1635 co_dev_set_rate(lss->dev, 250);
1636 break;
1637 case 4:
1638 if (!(req.data[1] = !(baud & CO_BAUD_125)))
1639 co_dev_set_rate(lss->dev, 125);
1640 break;
1641 case 6:
1642 if (!(req.data[1] = !(baud & CO_BAUD_50)))
1643 co_dev_set_rate(lss->dev, 50);
1644 break;
1645 case 7:
1646 if (!(req.data[1] = !(baud & CO_BAUD_20)))
1647 co_dev_set_rate(lss->dev, 20);
1648 break;
1649 case 8:
1650 if (!(req.data[1] = !(baud & CO_BAUD_10)))
1651 co_dev_set_rate(lss->dev, 10);
1652 break;
1653 case 9:
1654 if (!(req.data[1] = !(baud & CO_BAUD_AUTO)))
1655 co_dev_set_rate(lss->dev, 0);
1656 break;
1657 default: req.data[1] = 1; break;
1658 }
1659 }
1660 can_net_send(lss->net, &req);
1661 break;
1662 // Activate bit timing parameters (see Fig. 35 in CiA 305 version
1663 // 3.0.0).
1664 case 0x15:
1665 if (msg->len < 3 || !lss->rate_ind)
1666 return NULL;
1667 // Invoke the user-specified callback function to perform the
1668 // baudrate switch.
1669 trace("LSS: activating bit timing parameters");
1670 lss->rate_ind(lss, co_dev_get_rate(lss->dev),
1671 ldle_u16(msg->data + 1), lss->rate_data);
1672 break;
1673 // Store configuration (see Fig. 36 in CiA 305 version 3.0.0).
1674 case 0x17:
1675 trace("LSS: storing configuration");
1676 co_lss_init_req(lss, &req, cs);
1677 if (lss->store_ind) {
1678 // Store the pending node-ID and baudrate.
1679 // clang-format off
1680 if (lss->store_ind(lss, co_nmt_get_id(lss->nmt),
1681 co_dev_get_rate(lss->dev),
1682 lss->store_data) == -1) {
1683 // clang-format on
1684 // Discard the error code.
1685 set_errc(errc);
1686 req.data[1] = 2;
1687 }
1688 } else {
1689 req.data[1] = 1;
1690 }
1691 can_net_send(lss->net, &req);
1692 break;
1693 // LSS identify remote slave.
1694 case 0x46:
1695 case 0x47:
1696 case 0x48:
1697 case 0x49:
1698 case 0x4a:
1699 case 0x4b:
1700 if (msg->len < 5)
1701 return NULL;
1702 co_lss_id_slave(lss, cs, ldle_u32(msg->data + 1));
1703 break;
1704 // LSS identify non-configured remote slave.
1705 case 0x4c: co_lss_id_non_cfg_slave(lss); break;
1706 // Inquire identity vendor-ID (Fig. 37 in CiA 305 version 3.0.0).
1707 case 0x5a:
1708 trace("LSS: sending vendor-ID");
1709 co_lss_init_req(lss, &req, cs);
1710 stle_u32(req.data + 1, co_obj_get_val_u32(obj_1018, 0x01));
1711 can_net_send(lss->net, &req);
1712 break;
1713 // Inquire identity product-code (Fig. 38 in CiA 305 version 3.0.0).
1714 case 0x5b:
1715 trace("LSS: sending product-code");
1716 co_lss_init_req(lss, &req, cs);
1717 stle_u32(req.data + 1, co_obj_get_val_u32(obj_1018, 0x02));
1718 can_net_send(lss->net, &req);
1719 break;
1720 // Inquire identity revision-number (Fig. 39 in CiA 305 version 3.0.0).
1721 case 0x5c:
1722 trace("LSS: sending revision-number");
1723 co_lss_init_req(lss, &req, cs);
1724 stle_u32(req.data + 1, co_obj_get_val_u32(obj_1018, 0x03));
1725 can_net_send(lss->net, &req);
1726 break;
1727 // Inquire identity serial-number (Fig. 40 in CiA 305 version 3.0.0).
1728 case 0x5d:
1729 trace("LSS: sending serial-number");
1730 co_lss_init_req(lss, &req, cs);
1731 stle_u32(req.data + 1, co_obj_get_val_u32(obj_1018, 0x04));
1732 can_net_send(lss->net, &req);
1733 break;
1734 // Inquire node-ID (Fig. 41 in CiA 305 version 3.0.0).
1735 case 0x5e:
1736 trace("LSS: sending node-ID");
1737 co_lss_init_req(lss, &req, cs);
1738 // Respond with the active or pending node-ID, depending on
1739 // whether the device is in the NMT state Initializing.
1740 switch (co_nmt_get_st(lss->nmt)) {
1741 case CO_NMT_ST_BOOTUP:
1744 req.data[1] = co_nmt_get_id(lss->nmt);
1745 break;
1746 default: req.data[1] = co_dev_get_id(lss->dev); break;
1747 }
1748 can_net_send(lss->net, &req);
1749 break;
1750 }
1751
1752 return NULL;
1753}
1754
1755#if !LELY_NO_CO_MASTER
1756
1757static co_lss_state_t *
1758co_lss_cs_on_recv(co_lss_t *lss, const struct can_msg *msg)
1759{
1760 assert(lss);
1761 assert(msg);
1762
1763 if (msg->len < 1 || msg->data[0] != lss->cs)
1764 return NULL;
1765
1766 return co_lss_cs_fini_state;
1767}
1768
1769static co_lss_state_t *
1770co_lss_cs_on_time(co_lss_t *lss, const struct timespec *tp)
1771{
1772 assert(lss);
1773 (void)tp;
1774
1775 lss->cs = 0;
1776 return co_lss_cs_fini_state;
1777}
1778
1779static co_lss_state_t *
1781{
1782 (void)lss;
1783
1784 return co_lss_wait_state;
1785}
1786
1787static void
1789{
1790 assert(lss);
1791
1792 can_timer_stop(lss->timer);
1793 can_recv_stop(lss->recv);
1794
1795 if (lss->cs_ind)
1796 lss->cs_ind(lss, lss->cs, lss->cs_data);
1797}
1798
1799static co_lss_state_t *
1801{
1802 assert(lss);
1803
1804 lss->next = 0;
1805 lss->cs = 0;
1806 return co_lss_switch_sel_on_time(lss, NULL);
1807}
1808
1809static co_lss_state_t *
1810co_lss_switch_sel_on_time(co_lss_t *lss, const struct timespec *tp)
1811{
1812 assert(lss);
1813 (void)tp;
1814
1815 // Switch state selective (see Fig. 32 in CiA 305 version 3.0.0).
1816 if (co_lss_send_switch_sel_req(lss, &lss->id) == -1) {
1817 // Abort if sending the CAN frame failed.
1818 lss->cs = 0;
1819 return co_lss_cs_fini_state;
1820 }
1821
1822 // If the last frame was sent, wait for the response.
1823 if (lss->cs == 0x44)
1824 return co_lss_cs_state;
1825
1826 // Wait for the inhibit time to pass.
1827 return NULL;
1828}
1829
1830static co_lss_state_t *
1831co_lss_err_on_recv(co_lss_t *lss, const struct can_msg *msg)
1832{
1833 assert(lss);
1834 assert(msg);
1835
1836 if (msg->len < 3 || msg->data[0] != lss->cs)
1837 return NULL;
1838
1839 lss->err = msg->data[1];
1840 lss->spec = lss->err == 0xff ? msg->data[2] : 0;
1841 return co_lss_wait_state;
1842}
1843
1844static co_lss_state_t *
1845co_lss_err_on_time(co_lss_t *lss, const struct timespec *tp)
1846{
1847 assert(lss);
1848 (void)tp;
1849
1850 lss->cs = 0;
1851 return co_lss_wait_state;
1852}
1853
1854static void
1856{
1857 assert(lss);
1858
1859 can_timer_stop(lss->timer);
1860 can_recv_stop(lss->recv);
1861
1862 if (lss->err_ind)
1863 lss->err_ind(lss, lss->cs, lss->err, lss->spec, lss->err_data);
1864}
1865
1866static co_lss_state_t *
1867co_lss_lssid_on_recv(co_lss_t *lss, const struct can_msg *msg)
1868{
1869 assert(lss);
1870 assert(msg);
1871
1872 if (msg->len < 5 || msg->data[0] != lss->cs)
1873 return NULL;
1874
1875 lss->lssid = ldle_u32(msg->data + 1);
1876 return co_lss_wait_state;
1877}
1878
1879static co_lss_state_t *
1880co_lss_lssid_on_time(co_lss_t *lss, const struct timespec *tp)
1881{
1882 assert(lss);
1883 (void)tp;
1884
1885 lss->cs = 0;
1886 return co_lss_wait_state;
1887}
1888
1889static void
1891{
1892 assert(lss);
1893
1894 can_timer_stop(lss->timer);
1895 can_recv_stop(lss->recv);
1896
1897 if (lss->lssid_ind)
1898 lss->lssid_ind(lss, lss->cs, lss->lssid, lss->lssid_data);
1899}
1900
1901static co_lss_state_t *
1902co_lss_nid_on_recv(co_lss_t *lss, const struct can_msg *msg)
1903{
1904 assert(lss);
1905 assert(msg);
1906
1907 if (msg->len < 2 || msg->data[0] != lss->cs)
1908 return NULL;
1909
1910 lss->nid = msg->data[1];
1911 return co_lss_wait_state;
1912}
1913
1914static co_lss_state_t *
1915co_lss_nid_on_time(co_lss_t *lss, const struct timespec *tp)
1916{
1917 assert(lss);
1918 (void)tp;
1919
1920 lss->cs = 0;
1921 return co_lss_wait_state;
1922}
1923
1924static void
1926{
1927 assert(lss);
1928
1929 can_timer_stop(lss->timer);
1930 can_recv_stop(lss->recv);
1931
1932 if (lss->nid_ind)
1933 lss->nid_ind(lss, lss->cs, lss->nid, lss->nid_data);
1934}
1935
1936static co_lss_state_t *
1938{
1939 assert(lss);
1940
1941 lss->next = 0;
1942 lss->cs = 0;
1943 return co_lss_id_slave_on_time(lss, NULL);
1944}
1945
1946static co_lss_state_t *
1947co_lss_id_slave_on_time(co_lss_t *lss, const struct timespec *tp)
1948{
1949 assert(lss);
1950 (void)tp;
1951
1952 // LSS identify remote slave (see Fig. 42 in CiA 305 version 3.0.0).
1953 if (co_lss_send_id_slave_req(lss, &lss->lo, &lss->hi) == -1) {
1954 // Abort if sending the CAN frame failed.
1955 lss->cs = 0;
1956 return co_lss_cs_fini_state;
1957 }
1958
1959 // If the last frame was sent, wait for the response.
1960 if (lss->cs == 0x4f)
1961 return co_lss_cs_state;
1962
1963 // Wait for the inhibit time to pass.
1964 return NULL;
1965}
1966
1967static co_lss_state_t *
1969{
1970 assert(lss);
1971
1972 lss->next = 0;
1973 lss->cs = 0;
1974 return co_lss_slowscan_init_on_time(lss, NULL);
1975}
1976
1977static co_lss_state_t *
1979{
1980 assert(lss);
1981 assert(msg);
1982
1983 if (msg->len < 1 || msg->data[0] != lss->cs)
1984 return NULL;
1985
1987}
1988
1989static co_lss_state_t *
1990co_lss_slowscan_init_on_time(co_lss_t *lss, const struct timespec *tp)
1991{
1992 assert(lss);
1993 (void)tp;
1994
1995 // Abort if we did not receive a response on the first request.
1996 if (lss->cs == 0x4f) {
1997 lss->cs = 0;
1999 }
2000
2001 // LSS identify remote slave (see Fig. 42 in CiA 305 version 3.0.0).
2002 if (co_lss_send_id_slave_req(lss, &lss->lo, &lss->hi) == -1) {
2003 // Abort if sending the CAN frame failed.
2004 lss->cs = 0;
2006 }
2007
2008 // Wait for the inhibit time to pass.
2009 return NULL;
2010}
2011
2012static co_lss_state_t *
2014{
2015 assert(lss);
2016
2017 // Calculate the midpoint while avoiding integer overflow.
2018 struct co_id *id = &lss->id;
2019 *id = lss->lo;
2020 if (id->revision < lss->hi.revision) {
2021 id->revision += (lss->hi.revision - id->revision) / 2;
2022 id->serial_nr = lss->hi.serial_nr;
2023 } else {
2024 id->serial_nr += (lss->hi.serial_nr - id->serial_nr) / 2;
2025 }
2026
2027 lss->next = 0;
2028 lss->cs = 0;
2029 return co_lss_slowscan_scan_on_time(lss, NULL);
2030}
2031
2032static co_lss_state_t *
2034{
2035 assert(lss);
2036 assert(msg);
2037
2038 if (msg->len < 1 || msg->data[0] != lss->cs)
2039 return NULL;
2040
2041 // Wait until the timeout expires before handling the response.
2043}
2044
2045static co_lss_state_t *
2046co_lss_slowscan_scan_on_time(co_lss_t *lss, const struct timespec *tp)
2047{
2048 assert(lss);
2049 (void)tp;
2050
2051 if (lss->cs == 0x4f)
2052 return co_lss_slowscan_scan_on_res(lss, 1);
2053
2054 // LSS identify remote slave (see Fig. 42 in CiA 305 version 3.0.0).
2055 if (co_lss_send_id_slave_req(lss, &lss->lo, &lss->id) == -1) {
2056 // Abort if sending the CAN frame failed.
2057 lss->cs = 0;
2059 }
2060
2061 // Wait for the inhibit time to pass.
2062 return NULL;
2063}
2064
2065static co_lss_state_t *
2066co_lss_slowscan_scan_on_res(co_lss_t *lss, int timeout)
2067{
2068 assert(lss);
2069
2070 if (lss->lo.revision == lss->hi.revision
2071 && lss->lo.serial_nr == lss->hi.serial_nr) {
2072 // Abort if we timeout after sending the final LSS address.
2073 if (timeout) {
2074 lss->cs = 0;
2076 }
2077 // Switch the slave to the LSS configuration state.
2078 co_lss_init_ind(lss, 0x44);
2080 }
2081
2082 // Update the bounds on the LSS address.
2083 if (timeout) {
2084 if (lss->id.revision < lss->hi.revision)
2085 lss->lo.revision = lss->id.revision + 1;
2086 else
2087 lss->lo.serial_nr = lss->id.serial_nr + 1;
2088 } else {
2089 lss->hi = lss->id;
2090 }
2091
2092 // Start the next cycle.
2094}
2095
2096static co_lss_state_t *
2098{
2099 (void)lss;
2100 (void)msg;
2101
2102 // Ignore further responses from slaves.
2103 return NULL;
2104}
2105
2106static co_lss_state_t *
2107co_lss_slowscan_wait_on_time(co_lss_t *lss, const struct timespec *tp)
2108{
2109 (void)lss;
2110 (void)tp;
2111
2112 // All slaves should have responded by now.
2113 return co_lss_slowscan_scan_on_res(lss, 0);
2114}
2115
2116static co_lss_state_t *
2118{
2119 assert(lss);
2120
2121 lss->next = 0;
2122 lss->cs = 0;
2123 return co_lss_slowscan_switch_on_time(lss, NULL);
2124}
2125
2126static co_lss_state_t *
2128{
2129 assert(lss);
2130 assert(msg);
2131
2132 if (msg->len < 1 || msg->data[0] != lss->cs)
2133 return NULL;
2134
2136}
2137
2138static co_lss_state_t *
2139co_lss_slowscan_switch_on_time(co_lss_t *lss, const struct timespec *tp)
2140{
2141 assert(lss);
2142 (void)tp;
2143
2144 // Abort if we did not receive a response.
2145 if (lss->cs == 0x44) {
2146 lss->cs = 0;
2148 }
2149
2150 // Switch state selective (see Fig. 32 in CiA 305 version 3.0.0).
2151 if (co_lss_send_switch_sel_req(lss, &lss->id) == -1) {
2152 // Abort if sending the CAN frame failed.
2153 lss->cs = 0;
2155 }
2156
2157 // Wait for the inhibit time to pass.
2158 return NULL;
2159}
2160
2161static co_lss_state_t *
2163{
2164 (void)lss;
2165
2166 return co_lss_wait_state;
2167}
2168
2169static void
2171{
2172 assert(lss);
2173
2174 can_timer_stop(lss->timer);
2175 can_recv_stop(lss->recv);
2176
2177 if (lss->scan_ind)
2178 lss->scan_ind(lss, lss->cs, lss->cs ? &lss->id : NULL,
2179 lss->scan_data);
2180}
2181
2182static co_lss_state_t *
2184{
2185 assert(lss);
2186 assert(msg);
2187
2188 if (msg->len < 1 || msg->data[0] != lss->cs)
2189 return NULL;
2190
2191 lss->bitchk = 31;
2193}
2194
2195static co_lss_state_t *
2196co_lss_fastscan_init_on_time(co_lss_t *lss, const struct timespec *tp)
2197{
2198 assert(lss);
2199 (void)tp;
2200
2201 // Abort if we did not receive a response on the reset request.
2202 lss->cs = 0;
2204}
2205
2206static co_lss_state_t *
2208{
2209 assert(lss);
2210
2211 const co_unsigned32_t *pid = co_id_sub(&lss->id, lss->lsssub);
2212 assert(pid);
2213 const co_unsigned32_t *pmask = co_id_sub(&lss->mask, lss->lsssub);
2214 assert(pmask);
2215
2216 // Find the next unknown bit.
2217 for (; lss->bitchk && (*pmask & (UINT32_C(1) << lss->bitchk));
2218 lss->bitchk--)
2219 ;
2220
2221 co_unsigned8_t lssnext = lss->lsssub;
2222 // If we obtained the complete LSS number, send it again and prepare for
2223 // the next number.
2224 if (!lss->bitchk && (*pmask & 1)) {
2225 if (lssnext < 3) {
2226 lssnext++;
2227 } else {
2228 lssnext = 0;
2229 }
2230 }
2231
2232 // LSS Fastscan (see Fig. 46 in CiA 305 version 3.0.0).
2233 // clang-format off
2234 if (co_lss_send_fastscan_req(lss, *pid, lss->bitchk, lss->lsssub,
2235 lssnext) == -1) {
2236 // Abort if sending the CAN frame failed.
2237 // clang-format on
2238 lss->cs = 0;
2240 }
2241
2242 // Restart the timeout for the next response.
2243 can_timer_timeout(lss->timer, lss->net, lss->timeout);
2244 return NULL;
2245}
2246
2247static co_lss_state_t *
2249{
2250 assert(lss);
2251 assert(msg);
2252
2253 if (msg->len < 1 || msg->data[0] != lss->cs)
2254 return NULL;
2255
2256 // Wait until the timeout expires before handling the response.
2258}
2259
2260static co_lss_state_t *
2261co_lss_fastscan_scan_on_time(co_lss_t *lss, const struct timespec *tp)
2262{
2263 assert(lss);
2264 (void)tp;
2265
2266 return co_lss_fastscan_scan_on_res(lss, 1);
2267}
2268
2269static co_lss_state_t *
2270co_lss_fastscan_scan_on_res(co_lss_t *lss, int timeout)
2271{
2272 assert(lss);
2273 assert(lss->bitchk <= 31);
2274 assert(lss->lsssub < 4);
2275
2276 co_unsigned32_t *pid = co_id_sub(&lss->id, lss->lsssub);
2277 assert(pid);
2278 co_unsigned32_t *pmask = co_id_sub(&lss->mask, lss->lsssub);
2279 assert(pmask);
2280
2281 if (!lss->bitchk && (*pmask & 1)) {
2282 // Abort if we timeout after sending the complete LSS number.
2283 if (timeout) {
2284 lss->cs = 0;
2286 }
2287 // We're done if this was the last LSS number.
2288 if (++lss->lsssub == 4)
2290 lss->bitchk = 31;
2291 } else {
2292 // Update the LSS address. A timeout indicates the bit is 1.
2293 if (timeout)
2294 *pid |= UINT32_C(1) << lss->bitchk;
2295 *pmask |= UINT32_C(1) << lss->bitchk;
2296 }
2297
2298 // Start the next cycle.
2300}
2301
2302static co_lss_state_t *
2304{
2305 (void)lss;
2306 (void)msg;
2307
2308 // Ignore further responses from slaves.
2309 return NULL;
2310}
2311
2312static co_lss_state_t *
2313co_lss_fastscan_wait_on_time(co_lss_t *lss, const struct timespec *tp)
2314{
2315 (void)lss;
2316 (void)tp;
2317
2318 // All slaves should have responded by now.
2319 return co_lss_fastscan_scan_on_res(lss, 0);
2320}
2321
2322static co_lss_state_t *
2324{
2325 (void)lss;
2326
2327 return co_lss_wait_state;
2328}
2329
2330static void
2332{
2333 assert(lss);
2334
2335 can_timer_stop(lss->timer);
2336 can_recv_stop(lss->recv);
2337
2338 if (lss->scan_ind)
2339 lss->scan_ind(lss, lss->cs, lss->cs ? &lss->id : NULL,
2340 lss->scan_data);
2341}
2342
2343#endif // !LELY_NO_CO_MASTER
2344
2345static co_lss_state_t *
2346co_lss_switch_sel(co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id)
2347{
2348 assert(lss);
2349
2350 co_obj_t *obj_1018 = co_dev_find_obj(lss->dev, 0x1018);
2351 struct can_msg req;
2352
2353 switch (cs) {
2354 case 0x40:
2355 if (id != co_obj_get_val_u32(obj_1018, 0x01)) {
2356 lss->cs = 0;
2357 return NULL;
2358 }
2359 lss->cs = 0x41;
2360 return NULL;
2361 case 0x41:
2362 if (cs != lss->cs || id != co_obj_get_val_u32(obj_1018, 0x02)) {
2363 lss->cs = 0;
2364 return NULL;
2365 }
2366 lss->cs = 0x42;
2367 return NULL;
2368 case 0x42:
2369 if (cs != lss->cs || id != co_obj_get_val_u32(obj_1018, 0x03)) {
2370 lss->cs = 0;
2371 return NULL;
2372 }
2373 lss->cs = 0x43;
2374 return NULL;
2375 case 0x43:
2376 if (cs != lss->cs || id != co_obj_get_val_u32(obj_1018, 0x04)) {
2377 lss->cs = 0;
2378 return NULL;
2379 }
2380 lss->cs = 0;
2381 // Notify the master of the state switch.
2382 co_lss_init_req(lss, &req, 0x44);
2383 can_net_send(lss->net, &req);
2384 // Switch to the configuration state.
2385 trace("LSS: switching to configuration state");
2386 return co_lss_cfg_state;
2387 default: return NULL;
2388 }
2389}
2390
2391static void
2392co_lss_id_slave(co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id)
2393{
2394 assert(lss);
2395
2396 co_obj_t *obj_1018 = co_dev_find_obj(lss->dev, 0x1018);
2397 struct can_msg req;
2398
2399 switch (cs) {
2400 case 0x46:
2401 // Check the vendor-ID.
2402 if (id != co_obj_get_val_u32(obj_1018, 0x01)) {
2403 lss->cs = 0;
2404 return;
2405 }
2406 lss->cs = 0x47;
2407 break;
2408 case 0x47:
2409 // Check the product-code.
2410 if (cs != lss->cs || id != co_obj_get_val_u32(obj_1018, 0x02)) {
2411 lss->cs = 0;
2412 return;
2413 }
2414 lss->cs = 0x48;
2415 break;
2416 case 0x48:
2417 // Check the lower bound of the revision-number.
2418 if (cs != lss->cs || id > co_obj_get_val_u32(obj_1018, 0x03)) {
2419 lss->cs = 0;
2420 return;
2421 }
2422 lss->cs = 0x49;
2423 break;
2424 case 0x49:
2425 // Check the upper bound of the revision-number.
2426 if (cs != lss->cs || id < co_obj_get_val_u32(obj_1018, 0x03)) {
2427 lss->cs = 0;
2428 return;
2429 }
2430 lss->cs = 0x4a;
2431 break;
2432 case 0x4a:
2433 // Check the lower bound of the serial-number.
2434 if (cs != lss->cs || id > co_obj_get_val_u32(obj_1018, 0x04)) {
2435 lss->cs = 0;
2436 return;
2437 }
2438 lss->cs = 0x4b;
2439 break;
2440 case 0x4b:
2441 // Check the upper bound of the serial-number.
2442 if (cs != lss->cs || id < co_obj_get_val_u32(obj_1018, 0x04)) {
2443 lss->cs = 0;
2444 return;
2445 }
2446 lss->cs = 0;
2447 // Notify the master that it is a match.
2448 co_lss_init_req(lss, &req, 0x4f);
2449 can_net_send(lss->net, &req);
2450 break;
2451 }
2452}
2453
2454static void
2456{
2457 assert(lss);
2458
2459 // Check if both the active and the pending node-ID are invalid.
2460 if (co_dev_get_id(lss->dev) != 0xff || co_nmt_get_id(lss->nmt) != 0xff)
2461 return;
2462
2463 // Check if the device is in the NMT state Initialization.
2464 switch (co_nmt_get_st(lss->nmt)) {
2465 case CO_NMT_ST_BOOTUP:
2467 case CO_NMT_ST_RESET_COMM: break;
2468 default: return;
2469 }
2470
2471 struct can_msg req;
2472 co_lss_init_req(lss, &req, 0x50);
2473 can_net_send(lss->net, &req);
2474}
2475
2476static co_lss_state_t *
2477co_lss_fastscan(co_lss_t *lss, co_unsigned32_t id, co_unsigned8_t bitchk,
2478 co_unsigned8_t lsssub, co_unsigned8_t lssnext)
2479{
2480 assert(lss);
2481
2482 co_obj_t *obj_1018 = co_dev_find_obj(lss->dev, 0x1018);
2483 struct can_msg req;
2484 co_lss_state_t *next = NULL;
2485
2486 if (bitchk > 31 && bitchk != 0x80)
2487 return NULL;
2488
2489 if (bitchk == 0x80) {
2490 lss->lsspos = 0;
2491 } else {
2492 if (lss->lsspos > 3 || lss->lsspos != lsssub)
2493 return NULL;
2494 // Check if the unmasked bits of the specified IDNumber match.
2495 co_unsigned32_t pid[] = { co_obj_get_val_u32(obj_1018, 0x01),
2496 co_obj_get_val_u32(obj_1018, 0x02),
2497 co_obj_get_val_u32(obj_1018, 0x03),
2498 co_obj_get_val_u32(obj_1018, 0x04) };
2499 if ((id ^ pid[lss->lsspos]) & ~((UINT32_C(1) << bitchk) - 1))
2500 return NULL;
2501 lss->lsspos = lssnext;
2502 // If this was the final bit, switch to the configuration state.
2503 if (!bitchk && lss->lsspos < lsssub)
2504 next = co_lss_cfg_state;
2505 }
2506
2507 // Notify the master that it is a match.
2508 co_lss_init_req(lss, &req, 0x4f);
2509 can_net_send(lss->net, &req);
2510
2511 return next;
2512}
2513
2514static void
2515co_lss_init_req(const co_lss_t *lss, struct can_msg *msg, co_unsigned8_t cs)
2516{
2517 assert(lss);
2518 assert(msg);
2519
2520 *msg = (struct can_msg)CAN_MSG_INIT;
2521 msg->id = CO_LSS_CANID(co_lss_is_master(lss));
2522 msg->len = CAN_MAX_LEN;
2523 msg->data[0] = cs;
2524}
2525
2526#if !LELY_NO_CO_MASTER
2527
2528static int
2530{
2531 assert(id);
2532
2533 // Switch state selective (see Fig. 32 in CiA 305 version 3.0.0).
2534 struct can_msg req;
2535 switch (lss->next) {
2536 case 0:
2537 co_lss_init_req(lss, &req, 0x40);
2538 stle_u32(req.data + 1, id->vendor_id);
2539 break;
2540 case 1:
2541 co_lss_init_req(lss, &req, 0x41);
2542 stle_u32(req.data + 1, id->product_code);
2543 break;
2544 case 2:
2545 co_lss_init_req(lss, &req, 0x42);
2546 stle_u32(req.data + 1, id->revision);
2547 break;
2548 case 3:
2549 co_lss_init_req(lss, &req, 0x43);
2550 stle_u32(req.data + 1, id->serial_nr);
2551 break;
2552 default: return -1;
2553 }
2554 if (can_net_send(lss->net, &req) == -1)
2555 return -1;
2556
2557 if (++lss->next < 4) {
2558 can_recv_stop(lss->recv);
2559 // Wait until the inhibit time has elapsed.
2560 struct timespec start = { 0, 0 };
2561 can_net_get_time(lss->net, &start);
2562 timespec_add_usec(&start, 100 * lss->inhibit);
2563 can_timer_start(lss->timer, lss->net, &start, NULL);
2564 } else {
2565 // Wait for response (see Fig. 32 in CiA 305 version 3.0.0).
2566 co_lss_init_ind(lss, 0x44);
2567 }
2568
2569 return 0;
2570}
2571
2572static int
2574 co_lss_t *lss, const struct co_id *lo, const struct co_id *hi)
2575{
2576 assert(lo);
2577 assert(hi);
2578 assert(lo->vendor_id == hi->vendor_id);
2579 assert(lo->product_code == hi->product_code);
2580 assert(lo->revision <= hi->revision);
2581 assert(lo->serial_nr <= hi->serial_nr);
2582
2583 // LSS identify remote slave (see Fig. 42 in CiA 305 version 3.0.0).
2584 struct can_msg req;
2585 switch (lss->next) {
2586 case 0:
2587 co_lss_init_req(lss, &req, 0x46);
2588 stle_u32(req.data + 1, lo->vendor_id);
2589 break;
2590 case 1:
2591 co_lss_init_req(lss, &req, 0x47);
2592 stle_u32(req.data + 1, lo->product_code);
2593 break;
2594 case 2:
2595 co_lss_init_req(lss, &req, 0x48);
2596 stle_u32(req.data + 1, lo->revision);
2597 break;
2598 case 3:
2599 co_lss_init_req(lss, &req, 0x49);
2600 stle_u32(req.data + 1, hi->revision);
2601 break;
2602 case 4:
2603 co_lss_init_req(lss, &req, 0x4a);
2604 stle_u32(req.data + 1, lo->serial_nr);
2605 break;
2606 case 5:
2607 co_lss_init_req(lss, &req, 0x4b);
2608 stle_u32(req.data + 1, hi->serial_nr);
2609 break;
2610 default: return -1;
2611 }
2612 if (can_net_send(lss->net, &req) == -1)
2613 return -1;
2614
2615 if (++lss->next < 6) {
2616 can_recv_stop(lss->recv);
2617 // Wait until the inhibit time has elapsed.
2618 struct timespec start = { 0, 0 };
2619 can_net_get_time(lss->net, &start);
2620 timespec_add_usec(&start, 100 * lss->inhibit);
2621 can_timer_start(lss->timer, lss->net, &start, NULL);
2622 } else {
2623 // Wait for response (see Fig. 43 in CiA 305 version 3.0.0).
2624 co_lss_init_ind(lss, 0x4f);
2625 }
2626
2627 return 0;
2628}
2629
2630static int
2631co_lss_send_fastscan_req(const co_lss_t *lss, co_unsigned32_t id,
2632 co_unsigned8_t bitchk, co_unsigned8_t lsssub,
2633 co_unsigned8_t lssnext)
2634{
2635 // LSS Fastscan (see Fig. 46 in CiA 305 version 3.0.0).
2636 struct can_msg req;
2637 co_lss_init_req(lss, &req, 0x51);
2638 stle_u32(req.data + 1, id);
2639 req.data[5] = bitchk;
2640 req.data[6] = lsssub;
2641 req.data[7] = lssnext;
2642 return can_net_send(lss->net, &req);
2643}
2644
2645static void
2646co_lss_init_ind(co_lss_t *lss, co_unsigned8_t cs)
2647{
2648 assert(lss);
2649
2650 lss->cs = cs;
2651 lss->err = 0;
2652 lss->spec = 0;
2653 lss->lssid = 0;
2654 lss->nid = 0;
2655
2656 can_recv_start(lss->recv, lss->net, CO_LSS_CANID(0), 0);
2657 can_timer_timeout(lss->timer, lss->net, lss->timeout);
2658}
2659
2660static inline co_unsigned32_t *
2661co_id_sub(struct co_id *id, co_unsigned8_t sub)
2662{
2663 assert(id);
2664 assert(sub < 4);
2665
2666 switch (sub) {
2667 case 0: return &id->vendor_id;
2668 case 1: return &id->product_code;
2669 case 2: return &id->revision;
2670 case 3: return &id->serial_nr;
2671 default: return NULL;
2672 }
2673}
2674
2675#endif // !LELY_NO_CO_MASTER
2676
2677#endif // !LELY_NO_CO_LSS
#define CAN_MAX_LEN
The maximum number of bytes in the payload of a CAN format frame.
Definition: msg.h:72
#define CAN_MSG_INIT
The static initializer for can_msg.
Definition: msg.h:113
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
#define CO_BAUD_20
A bit rate of 20 kbit/s.
Definition: dev.h:77
#define CO_BAUD_AUTO
Automatic bit rate detection.
Definition: dev.h:83
#define CO_BAUD_125
A bit rate of 125 kbit/s.
Definition: dev.h:71
#define CO_NUM_NODES
The maximum number of nodes in a CANopen network.
Definition: dev.h:56
co_unsigned16_t co_dev_get_rate(const co_dev_t *dev)
Returns the (pending) baudrate of a CANopen device (in kbit/s).
Definition: dev.c:519
#define CO_ID_INIT
The static initializer for struct co_id.
Definition: dev.h:47
#define CO_BAUD_10
A bit rate of 10 kbit/s.
Definition: dev.h:80
#define CO_BAUD_250
A bit rate of 250 kbit/s.
Definition: dev.h:68
void co_dev_set_rate(co_dev_t *dev, co_unsigned16_t rate)
Sets the (pending) baudrate of a CANopen device.
Definition: dev.c:527
#define CO_BAUD_1000
A bit rate of 1 Mbit/s.
Definition: dev.h:59
#define CO_BAUD_500
A bit rate of 500 kbit/s.
Definition: dev.h:65
#define CO_BAUD_800
A bit rate of 800 kbit/s.
Definition: dev.h:62
unsigned int co_dev_get_baud(const co_dev_t *dev)
Returns the supported bit rates of a CANopen device (any combination of CO_BAUD_1000,...
Definition: dev.c:503
#define CO_BAUD_50
A bit rate of 50 kbit/s.
Definition: dev.h:74
This header file is part of the utilities library; it contains the byte order (endianness) function d...
uint_least32_t ldle_u32(const uint_least8_t src[4])
Loads a 32-bit unsigned integer in little-endian byte order.
Definition: endian.h:596
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
void stle_u16(uint_least8_t dst[2], uint_least16_t x)
Stores a 16-bit unsigned integer in little-endian byte order.
Definition: endian.h:504
void stle_u32(uint_least8_t dst[4], uint_least32_t x)
Stores a 32-bit unsigned integer in little-endian byte order.
Definition: endian.h:582
This header file is part of the utilities library; it contains the native and platform-independent er...
@ ERRNUM_PERM
Operation not permitted.
Definition: errnum.h:208
@ ERRNUM_INVAL
Invalid argument.
Definition: errnum.h:132
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
Definition: errnum.c:932
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:944
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
Definition: errnum.c:46
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:424
#define MAX(a, b)
Returns the maximum of a and b.
Definition: util.h:65
static co_lss_state_t * co_lss_cs_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the command received state.
Definition: lss.c:1758
static co_lss_state_t *const co_lss_slowscan_wait_state
The Slowscan waiting state.
Definition: lss.c:421
static co_lss_state_t * co_lss_slowscan_wait_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the Slowscan waiting state.
Definition: lss.c:2097
int co_lss_get_vendor_id_req(co_lss_t *lss, co_lss_lssid_ind_t *ind, void *data)
Requests the 'inquire identity vendor-ID' service.
Definition: lss.c:1142
void co_lss_destroy(co_lss_t *lss)
Destroys a CANopen LSS master/slave service.
Definition: lss.c:810
static co_lss_state_t * co_lss_switch_sel_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the 'switch state selective' state.
Definition: lss.c:1810
static void co_lss_cs_fini_on_leave(co_lss_t *lss)
The exit function of the command received finalization state.
Definition: lss.c:1788
static co_lss_state_t * co_lss_slowscan_init_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the Slowscan initialization state.
Definition: lss.c:1990
static int co_lss_send_fastscan_req(const co_lss_t *lss, co_unsigned32_t id, co_unsigned8_t bitchk, co_unsigned8_t lsssub, co_unsigned8_t lssnext)
Sends an LSS Fastscan request (see Fig.
Definition: lss.c:2631
static co_lss_state_t * co_lss_slowscan_scan_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the Slowscan scanning state.
Definition: lss.c:2046
static co_lss_state_t * co_lss_slowscan_switch_on_enter(co_lss_t *lss)
The entry function of the Slowscan 'switch state selective' state.
Definition: lss.c:2117
static co_lss_state_t * co_lss_nid_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the inquire node-ID state.
Definition: lss.c:1915
static void co_lss_fastscan_fini_on_leave(co_lss_t *lss)
The exit function of the Fastscan finalization state.
Definition: lss.c:2331
static co_lss_state_t *const co_lss_slowscan_scan_state
The Slowscan scanning state.
Definition: lss.c:405
static co_lss_state_t *const co_lss_fastscan_fini_state
The Fastscan finalization state.
Definition: lss.c:532
static co_lss_state_t *const co_lss_cs_state
The command received state.
Definition: lss.c:256
int co_lss_is_master(const co_lss_t *lss)
Returns 1 if the specified CANopen LSS service is a master, and 0 if not.
Definition: lss.c:945
static co_lss_state_t *const co_lss_slowscan_init_state
The Slowscan initialization state.
Definition: lss.c:383
int co_lss_set_id_req(co_lss_t *lss, co_unsigned8_t id, co_lss_err_ind_t *ind, void *data)
Requests the 'configure node-ID' service.
Definition: lss.c:1021
void co_lss_set_timeout(co_lss_t *lss, int timeout)
Sets the timeout of an LSS master service.
Definition: lss.c:932
static co_lss_state_t * co_lss_fastscan_fini_on_enter(co_lss_t *lss)
The entry function of the Fastscan finalization state.
Definition: lss.c:2323
static co_lss_state_t * co_lss_fastscan_scan_on_enter(co_lss_t *lss)
The entry function of the Fastscan scanning state.
Definition: lss.c:2207
static co_lss_state_t *const co_lss_wait_state
The 'waiting' state of an LSS master or slave.
Definition: lss.c:206
static void co_lss_id_slave(co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id)
Implements the LSS identify remote slave service for an LSS slave.
Definition: lss.c:2392
static void co_lss_err_on_leave(co_lss_t *lss)
The exit function of the error received state.
Definition: lss.c:1855
co_unsigned16_t co_lss_get_inhibit(const co_lss_t *lss)
Returns the inhibit time (in multiples of 100 microseconds) of an LSS master service.
Definition: lss.c:908
static void co_lss_init_req(const co_lss_t *lss, struct can_msg *msg, co_unsigned8_t cs)
Initializes an LSS request CAN frame.
Definition: lss.c:2515
int co_lss_slowscan_req(co_lss_t *lss, const struct co_id *lo, const struct co_id *hi, co_lss_scan_ind_t *ind, void *data)
Requests the 'LSS Slowscan' service.
Definition: lss.c:1329
int co_lss_switch_rate_req(co_lss_t *lss, int delay)
Requests the 'activate bit timing parameters' service.
Definition: lss.c:1094
static co_lss_state_t * co_lss_nid_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the inquire node-ID state.
Definition: lss.c:1902
static co_lss_state_t * co_lss_slowscan_switch_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the Slowscan 'switch state selective' state.
Definition: lss.c:2139
int co_lss_get_id_req(co_lss_t *lss, co_lss_nid_ind_t *ind, void *data)
Requests the 'inquire node-ID' service.
Definition: lss.c:1244
static co_lss_state_t * co_lss_fastscan_scan_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the Fastscan scanning state.
Definition: lss.c:2248
static void co_lss_init_ind(co_lss_t *lss, co_unsigned8_t cs)
Prepares an LSS master to receive an indication from a slave.
Definition: lss.c:2646
static co_lss_state_t * co_lss_id_slave_on_enter(co_lss_t *lss)
The entry function of the 'identify remote slave' state.
Definition: lss.c:1937
int co_lss_get_revision_req(co_lss_t *lss, co_lss_lssid_ind_t *ind, void *data)
Requests the 'inquire identity revision-number' service.
Definition: lss.c:1192
void co_lss_set_store_ind(co_lss_t *lss, co_lss_store_ind_t *ind, void *data)
Sets the indication function invoked when an LSS 'store configuration' request is received.
Definition: lss.c:897
int co_lss_switch_sel_req(co_lss_t *lss, const struct co_id *id, co_lss_cs_ind_t *ind, void *data)
Requests the 'switch state selective' service.
Definition: lss.c:999
static co_lss_state_t * co_lss_cs_fini_on_enter(co_lss_t *lss)
The entry function of the command received finalization state.
Definition: lss.c:1780
static co_lss_state_t * co_lss_slowscan_switch_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the Slowscan 'switch state selective' state.
Definition: lss.c:2127
void co_lss_get_rate_ind(const co_lss_t *lss, co_lss_rate_ind_t **pind, void **pdata)
Retrieves the indication function invoked when an LSS 'activate bit timing' request is received.
Definition: lss.c:865
int co_lss_switch_req(co_lss_t *lss, co_unsigned8_t mode)
Requests the 'switch state global' service.
Definition: lss.c:977
static void co_lss_emit_recv(co_lss_t *lss, const struct can_msg *msg)
Invokes the 'CAN frame received' transition function of the current state of an LSS service.
Definition: lss.c:1454
void co_lss_stop(co_lss_t *lss)
Stops an LSS service.
Definition: lss.c:833
int co_lss_set_rate_req(co_lss_t *lss, co_unsigned16_t rate, co_lss_err_ind_t *ind, void *data)
Requests the 'configure bit timing parameters' service.
Definition: lss.c:1053
static co_lss_state_t *const co_lss_cfg_state
The 'configuration' state of an LSS slave.
Definition: lss.c:238
int co_lss_is_idle(const co_lss_t *lss)
Returns 1 if the specified LSS master is idle, and 0 if a request is ongoing.
Definition: lss.c:961
static co_lss_state_t *const co_lss_fastscan_scan_state
The Fastscan scanning state.
Definition: lss.c:502
void co_lss_set_rate_ind(co_lss_t *lss, co_lss_rate_ind_t *ind, void *data)
Sets the indication function invoked when an LSS 'activate bit timing' request is received.
Definition: lss.c:876
static co_lss_state_t * co_lss_cfg_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the 'configuration' state of an LSS slave.
Definition: lss.c:1565
int co_lss_get_timeout(const co_lss_t *lss)
Returns the timeout (in milliseconds) of an LSS master service.
Definition: lss.c:924
co_lss_t * co_lss_create(co_nmt_t *nmt)
Creates a new CANopen LSS master/slave service.
Definition: lss.c:783
static co_lss_state_t * co_lss_fastscan_init_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the Fastscan initialization state.
Definition: lss.c:2196
co_nmt_t * co_lss_get_nmt(const co_lss_t *lss)
Returns a pointer to the NMT service of an LSS master/slave service.
Definition: lss.c:857
int co_lss_get_product_code_req(co_lss_t *lss, co_lss_lssid_ind_t *ind, void *data)
Requests the 'inquire identity product-code' service.
Definition: lss.c:1167
static co_lss_state_t *const co_lss_id_slave_state
The 'identify remote slave' state.
Definition: lss.c:360
static co_lss_state_t *const co_lss_slowscan_fini_state
The Slowscan finalization state.
Definition: lss.c:461
int co_lss_id_slave_req(co_lss_t *lss, const struct co_id *lo, const struct co_id *hi, co_lss_cs_ind_t *ind, void *data)
Requests the 'LSS identify remote slave' service.
Definition: lss.c:1269
static co_lss_state_t *const co_lss_nid_state
The inquire node-ID state.
Definition: lss.c:345
static void co_lss_slowscan_fini_on_leave(co_lss_t *lss)
The exit function of the Slowscan finalization state.
Definition: lss.c:2170
static co_lss_state_t * co_lss_fastscan_wait_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the Fastscan waiting state.
Definition: lss.c:2303
int co_lss_store_req(co_lss_t *lss, co_lss_err_ind_t *ind, void *data)
Requests the 'store configuration' service.
Definition: lss.c:1117
static co_lss_state_t * co_lss_fastscan_wait_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the Fastscan waiting state.
Definition: lss.c:2313
static co_lss_state_t * co_lss_slowscan_init_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the Slowscan initialization state.
Definition: lss.c:1978
static co_lss_state_t * co_lss_cs_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the command received state.
Definition: lss.c:1770
static co_lss_state_t * co_lss_id_slave_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the 'identify remote slave' state.
Definition: lss.c:1947
int co_lss_start(co_lss_t *lss)
Starts an LSS service.
Definition: lss.c:820
static co_lss_state_t * co_lss_lssid_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the inquire identity state.
Definition: lss.c:1867
int co_lss_id_non_cfg_slave_req(co_lss_t *lss, co_lss_cs_ind_t *ind, void *data)
Requests the 'LSS identify non-configured remote slave' service.
Definition: lss.c:1303
static co_lss_state_t *const co_lss_fastscan_wait_state
The Fastscan waiting state.
Definition: lss.c:518
static co_lss_state_t * co_lss_slowscan_fini_on_enter(co_lss_t *lss)
The entry function of the Slowscan finalization state.
Definition: lss.c:2162
static co_lss_state_t * co_lss_slowscan_scan_on_enter(co_lss_t *lss)
The entry function of the Slowscan scanning state.
Definition: lss.c:2013
static int co_lss_send_id_slave_req(co_lss_t *lss, const struct co_id *lo, const struct co_id *hi)
Sends a single frame of an LSS identify remote slave request (see Fig.
Definition: lss.c:2573
static int co_lss_timer(const struct timespec *tp, void *data)
The CAN timer callback function for an LSS service.
Definition: lss.c:1425
static co_lss_state_t * co_lss_wait_slave_on_enter(co_lss_t *lss)
The entry function of the 'waiting' state of an LSS slave.
Definition: lss.c:1493
static co_lss_state_t *const co_lss_cs_fini_state
The command received finalization state.
Definition: lss.c:270
static co_lss_state_t * co_lss_slowscan_init_on_enter(co_lss_t *lss)
The entry function of the Slowscan initialization state.
Definition: lss.c:1968
static co_lss_state_t *const co_lss_slowscan_switch_state
The Slowscan 'switch state selective' state.
Definition: lss.c:447
static co_lss_state_t * co_lss_slowscan_wait_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the Slowscan waiting state.
Definition: lss.c:2107
static co_lss_state_t * co_lss_fastscan(co_lss_t *lss, co_unsigned32_t id, co_unsigned8_t bitchk, co_unsigned8_t lsssub, co_unsigned8_t lssnext)
Implements the LSS fastscan service for an LSS slave.
Definition: lss.c:2477
int co_lss_fastscan_req(co_lss_t *lss, const struct co_id *id, const struct co_id *mask, co_lss_scan_ind_t *ind, void *data)
Requests the 'LSS Fastscan' service.
Definition: lss.c:1365
static void co_lss_enter(co_lss_t *lss, co_lss_state_t *next)
Enters the specified state of an LSS service and invokes the exit and entry functions.
Definition: lss.c:1438
static void co_lss_id_non_cfg_slave(const co_lss_t *lss)
Implements the LSS identify non-configured remote slave service for an LSS slave.
Definition: lss.c:2455
static co_lss_state_t * co_lss_wait_slave_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the 'waiting' state of an LSS slave.
Definition: lss.c:1507
static co_unsigned32_t * co_id_sub(struct co_id *id, co_unsigned8_t sub)
Returns a pointer to the specified number in an LSS address.
Definition: lss.c:2661
static co_lss_state_t *const co_lss_err_state
The error received state.
Definition: lss.c:305
static void co_lss_nid_on_leave(co_lss_t *lss)
The exit function of the inquire node-ID state.
Definition: lss.c:1925
static co_lss_state_t *const co_lss_switch_sel_state
The 'switch state selective' state.
Definition: lss.c:285
static co_lss_state_t *const co_lss_stopped_state
The 'stopped' state of an LSS master or slave.
Definition: lss.c:197
int co_lss_get_serial_nr_req(co_lss_t *lss, co_lss_lssid_ind_t *ind, void *data)
Requests the 'inquire identity serial-number' service.
Definition: lss.c:1218
static co_lss_state_t * co_lss_fastscan_init_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the Fastscan initialization state.
Definition: lss.c:2183
void co_lss_abort_req(co_lss_t *lss)
Aborts the current LSS master request.
Definition: lss.c:969
static co_lss_state_t * co_lss_switch_sel(co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id)
Implements the switch state selective service for an LSS slave.
Definition: lss.c:2346
static co_lss_state_t * co_lss_lssid_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the inquire identity state.
Definition: lss.c:1880
static int co_lss_recv(const struct can_msg *msg, void *data)
The CAN receive callback function for an LSS service.
Definition: lss.c:1412
static void co_lss_lssid_on_leave(co_lss_t *lss)
The exit function of the inquire identity state.
Definition: lss.c:1890
static co_lss_state_t * co_lss_wait_on_enter(co_lss_t *lss)
The entry function of the 'waiting' state an LSS master or slave.
Definition: lss.c:1476
static void co_lss_emit_time(co_lss_t *lss, const struct timespec *tp)
Invokes the 'timeout' transition function of the current state of an LSS service.
Definition: lss.c:1465
static co_lss_state_t *const co_lss_fastscan_init_state
The Fastscan initialization state.
Definition: lss.c:480
static co_lss_state_t * co_lss_fastscan_scan_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the Fastscan scanning state.
Definition: lss.c:2261
static co_lss_state_t *const co_lss_wait_slave_state
The 'waiting' state of an LSS slave.
Definition: lss.c:224
static co_lss_state_t * co_lss_switch_sel_on_enter(co_lss_t *lss)
The entry function of the 'switch state selective' state.
Definition: lss.c:1800
static co_lss_state_t *const co_lss_lssid_state
The inquire identity state.
Definition: lss.c:325
static co_lss_state_t * co_lss_err_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the error received state.
Definition: lss.c:1831
static co_lss_state_t * co_lss_slowscan_scan_on_recv(co_lss_t *lss, const struct can_msg *msg)
The 'CAN frame received' transition function of the Slowscan scanning state.
Definition: lss.c:2033
static co_lss_state_t * co_lss_err_on_time(co_lss_t *lss, const struct timespec *tp)
The 'timeout' transition function of the error received state.
Definition: lss.c:1845
void co_lss_get_store_ind(const co_lss_t *lss, co_lss_store_ind_t **pind, void **pdata)
Retrieves the indication function invoked when an LSS 'store configuration' request is received.
Definition: lss.c:885
static int co_lss_send_switch_sel_req(co_lss_t *lss, const struct co_id *id)
Sends a single frame of a switch state selective request (see Fig.
Definition: lss.c:2529
int co_lss_is_stopped(const co_lss_t *lss)
Retuns 1 if the specified LSS service is stopped, and 0 if not.
Definition: lss.c:849
void co_lss_set_inhibit(co_lss_t *lss, co_unsigned16_t inhibit)
Sets the inhibit time between successive LSS messages of an LSS master service.
Definition: lss.c:916
This header file is part of the CANopen library; it contains the Layer Setting Services (LSS) and pro...
void co_lss_lssid_ind_t(co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id, void *data)
The type of a CANopen LSS inquire identity indication function, invoked when an 'inquire identity ven...
Definition: lss.h:114
int co_lss_store_ind_t(co_lss_t *lss, co_unsigned8_t id, co_unsigned16_t rate, void *data)
The type of a CANopen LSS 'store configuration' indication function, invoked when the pending node-ID...
Definition: lss.h:72
#define CO_LSS_CANID(master)
The CAN identifier used for LSS by the master (1) or the slave (0).
Definition: lss.h:39
void co_lss_err_ind_t(co_lss_t *lss, co_unsigned8_t cs, co_unsigned8_t err, co_unsigned8_t spec, void *data)
The type of a CANopen LSS error received indication function, invoked when a 'configure node-ID',...
Definition: lss.h:99
void co_lss_nid_ind_t(co_lss_t *lss, co_unsigned8_t cs, co_unsigned8_t id, void *data)
The type of a CANopen LSS inquire node-ID indication function, invoked when an 'inquire node-ID' requ...
Definition: lss.h:126
void co_lss_scan_ind_t(co_lss_t *lss, co_unsigned8_t cs, const struct co_id *id, void *data)
The type of a CANopen LSS identify remote slave indication function, invoked when a 'Slowscan' or 'Fa...
Definition: lss.h:140
#define LELY_CO_LSS_INHIBIT
The default LSS inhibit time (in multiples of 100 microseconds).
Definition: lss.h:30
void co_lss_cs_ind_t(co_lss_t *lss, co_unsigned8_t cs, void *data)
The type of a CANopen LSS command received indication function, invoked when a 'switch state selectiv...
Definition: lss.h:85
void co_lss_rate_ind_t(co_lss_t *lss, co_unsigned16_t rate, int delay, void *data)
The type of a CANopen LSS 'activate bit timing' indication function, invoked when a baudrate switch i...
Definition: lss.h:56
#define LELY_CO_LSS_TIMEOUT
The default LSS timeout (in milliseconds).
Definition: lss.h:35
void can_timer_stop(can_timer_t *timer)
Stops a CAN timer and unregisters it with a network interface.
Definition: net.c:462
int can_net_send(can_net_t *net, const struct can_msg *msg)
Sends a CAN frame from a network interface.
Definition: net.c:300
void can_timer_start(can_timer_t *timer, can_net_t *net, const struct timespec *start, const struct timespec *interval)
Starts a CAN timer and registers it with a network interface.
Definition: net.c:431
can_timer_t * can_timer_create(void)
Creates a new CAN timer.
Definition: net.c:376
void can_net_get_time(const can_net_t *net, struct timespec *tp)
Retrieves the current time of a CAN network interface.
Definition: net.c:196
void can_timer_set_func(can_timer_t *timer, can_timer_func_t *func, void *data)
Sets the callback function invoked when a CAN timer is triggered.
Definition: net.c:422
void can_recv_stop(can_recv_t *recv)
Stops a CAN frame receiver from processing frames and unregisters it with the network interface.
Definition: net.c:609
void can_recv_set_func(can_recv_t *recv, can_recv_func_t *func, void *data)
Sets the callback function used to process CAN frames with a receiver.
Definition: net.c:578
void can_recv_destroy(can_recv_t *recv)
Destroys a CAN frame receiver.
Definition: net.c:558
void can_timer_timeout(can_timer_t *timer, can_net_t *net, int timeout)
Starts a CAN timer and registers it with a network interface.
Definition: net.c:478
void can_recv_start(can_recv_t *recv, can_net_t *net, uint_least32_t id, uint_least8_t flags)
Registers a CAN frame receiver with a network interface and starts processing frames.
Definition: net.c:587
can_recv_t * can_recv_create(void)
Creates a new CAN frame receiver.
Definition: net.c:533
void can_timer_destroy(can_timer_t *timer)
Destroys a CAN timer.
Definition: net.c:401
This header file is part of the CANopen library; it contains the network management (NMT) declaration...
#define CO_NMT_ST_BOOTUP
The NMT state 'boot-up'.
Definition: nmt.h:55
co_unsigned8_t co_nmt_get_id(const co_nmt_t *nmt)
Returns the pending node-ID.
Definition: nmt.c:1743
can_net_t * co_nmt_get_net(const co_nmt_t *nmt)
Returns a pointer to the CAN network of an NMT master/slave service.
Definition: nmt.c:1267
co_dev_t * co_nmt_get_dev(const co_nmt_t *nmt)
Returns a pointer to the CANopen device of an NMT master/slave service.
Definition: nmt.c:1275
co_unsigned8_t co_nmt_get_st(const co_nmt_t *nmt)
Returns the current state of a CANopen NMT service (one of CO_NMT_ST_BOOTUP, CO_NMT_ST_STOP,...
Definition: nmt.c:1766
#define CO_NMT_ST_RESET_NODE
The NMT sub-state 'reset application'.
Definition: nmt.h:64
#define CO_NMT_ST_RESET_COMM
The NMT sub-state 'reset communication'.
Definition: nmt.h:67
int co_nmt_set_id(co_nmt_t *nmt, co_unsigned8_t id)
Sets the pending node-ID.
Definition: nmt.c:1751
int co_nmt_is_master(const co_nmt_t *nmt)
Returns 1 if the specified CANopen NMT service is a master, and 0 if not.
Definition: nmt.c:1774
This header file is part of the CANopen library; it contains the object dictionary declarations.
This is the internal header file of the CANopen library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
A CAN network interface.
Definition: net.c:37
A CAN frame receiver.
Definition: net.c:86
A CAN timer.
Definition: net.c:63
A CANopen device.
Definition: dev.h:30
A CANopen LSS state.
Definition: lss.c:165
co_lss_state_t *(* on_recv)(co_lss_t *lss, const struct can_msg *msg)
A pointer to the transition function invoked when a CAN frame has been received.
Definition: lss.c:177
co_lss_state_t *(* on_time)(co_lss_t *lss, const struct timespec *tp)
A pointer to the transition function invoked when a timeout occurs.
Definition: lss.c:187
void(* on_leave)(co_lss_t *lss)
A pointer to the function invoked when the current state is left.
Definition: lss.c:190
co_lss_state_t *(* on_enter)(co_lss_t *lss)
A pointer to the function invoked when a new state is entered.
Definition: lss.c:167
A CANopen LSS master/slave service.
Definition: lss.c:44
void * err_data
A pointer to user-specified data for err_ind.
Definition: lss.c:114
co_unsigned8_t spec
The received implementation-specific error code.
Definition: lss.c:90
int next
The index of the next frame to be sent.
Definition: lss.c:59
co_unsigned8_t cs
The expected command specifier.
Definition: lss.c:70
struct co_id id
The LSS address obtained from the LSS Slowscan or Fastscan service.
Definition: lss.c:96
co_unsigned16_t inhibit
The inhibit time (in multiples of 100 microseconds).
Definition: lss.c:57
can_timer_t * timer
A pointer to the CAN timer.
Definition: lss.c:67
co_nmt_t * nmt
A pointer to an NMT master/slave service.
Definition: lss.c:46
co_unsigned8_t lsspos
The LSSPos value.
Definition: lss.c:72
co_lss_nid_ind_t * nid_ind
A pointer to the inquire node-ID indication function.
Definition: lss.c:120
co_lss_scan_ind_t * scan_ind
A pointer to the identify remote slave indication function.
Definition: lss.c:124
co_unsigned8_t err
The received error code.
Definition: lss.c:88
void * nid_data
A pointer to user-specified data for nid_ind.
Definition: lss.c:122
can_recv_t * recv
A pointer to the CAN frame receiver.
Definition: lss.c:62
void * cs_data
A pointer to user-specified data for cs_ind.
Definition: lss.c:110
co_lss_lssid_ind_t * lssid_ind
A pointer to the inquire identity indication function.
Definition: lss.c:116
co_lss_err_ind_t * err_ind
A pointer to the error indication function.
Definition: lss.c:112
co_unsigned8_t nid
The received node-ID.
Definition: lss.c:94
void * lssid_data
A pointer to user-specified data for lssid_ind.
Definition: lss.c:118
int master
A flag specifying whether the LSS service is a master or a slave.
Definition: lss.c:55
co_unsigned8_t lsssub
The index of the current LSS number being checked during the Fastscan service.
Definition: lss.c:86
void * rate_data
A pointer to user-specified data for rate_ind.
Definition: lss.c:101
struct co_id mask
The mask used during the Fastscan service.
Definition: lss.c:79
co_dev_t * dev
A pointer to a CANopen device.
Definition: lss.c:50
co_unsigned8_t bitchk
The least-significant bit being checked during the Fastscan service.
Definition: lss.c:81
struct co_id lo
The lower bound of the LSS address used during the Slowscan service.
Definition: lss.c:75
int timeout
The timeout (in milliseconds).
Definition: lss.c:65
void * scan_data
A pointer to user-specified data for scan_ind.
Definition: lss.c:126
void * store_data
A pointer to user-specified data for store_ind.
Definition: lss.c:105
co_unsigned32_t lssid
The received LSS number.
Definition: lss.c:92
co_lss_store_ind_t * store_ind
A pointer to the 'store configuration' indication function.
Definition: lss.c:103
co_lss_cs_ind_t * cs_ind
A pointer to the command indication function.
Definition: lss.c:108
co_lss_state_t * state
A pointer to the current state.
Definition: lss.c:52
co_lss_rate_ind_t * rate_ind
A pointer to the 'activate bit timing' indication function.
Definition: lss.c:99
struct co_id hi
The upper bound of the LSS address used during the Slowscan service.
Definition: lss.c:77
can_net_t * net
A pointer to a CAN network interface.
Definition: lss.c:48
A CANopen NMT master/slave service.
Definition: nmt.c:148
A CANopen object.
Definition: obj.h:31
A CAN or CAN FD format frame.
Definition: msg.h:87
uint_least8_t data[CAN_MSG_MAX_LEN]
The frame payload (in case of a data frame).
Definition: msg.h:102
uint_least32_t id
The identifier (11 or 29 bits, depending on the CAN_FLAG_IDE flag).
Definition: msg.h:89
uint_least8_t len
The number of bytes in data (or the requested number of bytes in case of a remote frame).
Definition: msg.h:100
An identity record.
Definition: dev.h:33
co_unsigned32_t product_code
Product code.
Definition: dev.h:39
co_unsigned32_t revision
Revision number.
Definition: dev.h:41
co_unsigned8_t n
Highest sub-index supported.
Definition: dev.h:35
co_unsigned32_t vendor_id
Vendor-ID.
Definition: dev.h:37
co_unsigned32_t serial_nr
Serial number.
Definition: dev.h:43
This header file is part of the utilities library; it contains the time function declarations.
void timespec_add_usec(struct timespec *tp, uint_least64_t usec)
Adds usec microseconds to the time at tp.
Definition: time.h:149
This header file is part of the CANopen library; it contains the CANopen value declarations.
#define CO_UNSIGNED16_MAX
The maximum value of a 16-bit unsigned integer.
Definition: val.h:90