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 
39 struct __co_lss_state;
41 typedef const struct __co_lss_state co_lss_state_t;
42 
44 struct __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
65  int timeout;
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
101  void *rate_data;
105  void *store_data;
106 #if !LELY_NO_CO_MASTER
110  void *cs_data;
114  void *err_data;
118  void *lssid_data;
122  void *nid_data;
126  void *scan_data;
127 #endif
128 };
129 
131 static int co_lss_recv(const struct can_msg *msg, void *data);
132 
133 #if !LELY_NO_CO_MASTER
135 static int co_lss_timer(const struct timespec *tp, void *data);
136 #endif
137 
142 static void co_lss_enter(co_lss_t *lss, co_lss_state_t *next);
143 
151 static inline void co_lss_emit_recv(co_lss_t *lss, const struct can_msg *msg);
152 
153 #if !LELY_NO_CO_MASTER
161 static 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 
197 LELY_CO_DEFINE_STATE(co_lss_stopped_state, .on_recv = NULL)
198 
201 
203 // clang-format off
204 LELY_CO_DEFINE_STATE(co_lss_wait_state,
205  .on_enter = &co_lss_wait_on_enter
206 )
207 // clang-format on
208 
211 
217  co_lss_t *lss, const struct can_msg *msg);
218 
220 // clang-format off
221 LELY_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
224 )
225 // clang-format on
226 
232  co_lss_t *lss, const struct can_msg *msg);
233 
235 // clang-format off
236 LELY_CO_DEFINE_STATE(co_lss_cfg_state,
237  .on_recv = &co_lss_cfg_on_recv
238 )
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
253 LELY_CO_DEFINE_STATE(co_lss_cs_state,
254  .on_recv = &co_lss_cs_on_recv,
255  .on_time = &co_lss_cs_on_time
256 )
257 // clang-format on
258 
261 
263 static void co_lss_cs_fini_on_leave(co_lss_t *lss);
264 
266 // clang-format off
267 LELY_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
270 )
271 // clang-format on
272 
275 
278  co_lss_t *lss, const struct timespec *tp);
279 
281 // clang-format off
282 LELY_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
285 )
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 
297 static void co_lss_err_on_leave(co_lss_t *lss);
298 
300 // clang-format off
301 LELY_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
305 )
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 
317 static void co_lss_lssid_on_leave(co_lss_t *lss);
318 
320 // clang-format off
321 LELY_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
325 )
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 
337 static void co_lss_nid_on_leave(co_lss_t *lss);
338 
340 // clang-format off
341 LELY_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
345 )
346 // clang-format on
347 
350 
353  co_lss_t *lss, const struct timespec *tp);
354 
356 // clang-format off
357 LELY_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
360 )
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
379 LELY_CO_DEFINE_STATE(co_lss_slowscan_init_state,
380  .on_enter = &co_lss_slowscan_init_on_enter,
381  .on_recv = &co_lss_slowscan_init_on_recv,
382  .on_time = &co_lss_slowscan_init_on_time
383 )
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 
397 static co_lss_state_t *co_lss_slowscan_scan_on_res(co_lss_t *lss, int timeout);
398 
400 // clang-format off
401 LELY_CO_DEFINE_STATE(co_lss_slowscan_scan_state,
402  .on_enter = &co_lss_slowscan_scan_on_enter,
403  .on_recv = &co_lss_slowscan_scan_on_recv,
404  .on_time = &co_lss_slowscan_scan_on_time
405 )
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
418 LELY_CO_DEFINE_STATE(co_lss_slowscan_wait_state,
419  .on_recv = &co_lss_slowscan_wait_on_recv,
420  .on_time = &co_lss_slowscan_wait_on_time
421 )
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
443 LELY_CO_DEFINE_STATE(co_lss_slowscan_switch_state,
444  .on_enter = &co_lss_slowscan_switch_on_enter,
445  .on_recv = &co_lss_slowscan_switch_on_recv,
447 )
448 // clang-format on
449 
452 
454 static void co_lss_slowscan_fini_on_leave(co_lss_t *lss);
455 
457 // clang-format off
458 LELY_CO_DEFINE_STATE(co_lss_slowscan_fini_state,
459  .on_enter = &co_lss_slowscan_fini_on_enter,
460  .on_leave = &co_lss_slowscan_fini_on_leave
461 )
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
477 LELY_CO_DEFINE_STATE(co_lss_fastscan_init_state,
478  .on_recv = &co_lss_fastscan_init_on_recv,
479  .on_time = &co_lss_fastscan_init_on_time
480 )
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 
494 static co_lss_state_t *co_lss_fastscan_scan_on_res(co_lss_t *lss, int timeout);
495 
497 // clang-format off
498 LELY_CO_DEFINE_STATE(co_lss_fastscan_scan_state,
499  .on_enter = &co_lss_fastscan_scan_on_enter,
500  .on_recv = &co_lss_fastscan_scan_on_recv,
501  .on_time = &co_lss_fastscan_scan_on_time
502 )
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
515 LELY_CO_DEFINE_STATE(co_lss_fastscan_wait_state,
516  .on_recv = &co_lss_fastscan_wait_on_recv,
517  .on_time = &co_lss_fastscan_wait_on_time
518 )
519 // clang-format on
520 
523 
525 static void co_lss_fastscan_fini_on_leave(co_lss_t *lss);
526 
528 // clang-format off
529 LELY_CO_DEFINE_STATE(co_lss_fastscan_fini_state,
530  .on_enter = &co_lss_fastscan_fini_on_enter,
531  .on_leave = &co_lss_fastscan_fini_on_leave
532 )
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 
560 static void co_lss_id_slave(
561  co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id);
562 
567 static void co_lss_id_non_cfg_slave(const co_lss_t *lss);
568 
583 static 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 
594 static 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 
610 static int co_lss_send_switch_sel_req(co_lss_t *lss, const struct co_id *id);
611 
625 static int co_lss_send_id_slave_req(
626  co_lss_t *lss, const struct co_id *lo, const struct co_id *hi);
627 
639 static 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 
649 static void co_lss_init_ind(co_lss_t *lss, co_unsigned8_t cs);
650 
659 static inline co_unsigned32_t *co_id_sub(struct co_id *id, co_unsigned8_t sub);
660 
661 #endif // !LELY_NO_CO_MASTER
662 
663 void *
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 
674 void
675 __co_lss_free(void *ptr)
676 {
677  free(ptr);
678 }
679 
680 struct __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  }
705  can_recv_set_func(lss->recv, &co_lss_recv, lss);
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);
758 error_start:
759 #if !LELY_NO_CO_MASTER
760  can_timer_destroy(lss->timer);
761 error_create_timer:
762 #endif
763  can_recv_destroy(lss->recv);
764 error_create_recv:
765  set_errc(errc);
766  return NULL;
767 }
768 
769 void
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
777  can_timer_destroy(lss->timer);
778 #endif
779  can_recv_destroy(lss->recv);
780 }
781 
782 co_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 
802 error_init_lss:
803  __co_lss_free(lss);
804 error_alloc_lss:
805  set_errc(errc);
806  return NULL;
807 }
808 
809 void
811 {
812  if (lss) {
813  trace("destroying LSS");
814  __co_lss_fini(lss);
815  __co_lss_free(lss);
816  }
817 }
818 
819 int
821 {
822  assert(lss);
823 
824  if (!co_lss_is_stopped(lss))
825  return 0;
826 
828 
829  return 0;
830 }
831 
832 void
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 
848 int
850 {
851  assert(lss);
852 
853  return lss->state == co_lss_stopped_state;
854 }
855 
856 co_nmt_t *
858 {
859  assert(lss);
860 
861  return lss->nmt;
862 }
863 
864 void
865 co_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 
875 void
877 {
878  assert(lss);
879 
880  lss->rate_ind = ind;
881  lss->rate_data = data;
882 }
883 
884 void
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 
896 void
898 {
899  assert(lss);
900 
901  lss->store_ind = ind;
902  lss->store_data = data;
903 }
904 
905 #if !LELY_NO_CO_MASTER
906 
907 co_unsigned16_t
909 {
910  assert(lss);
911 
912  return lss->inhibit;
913 }
914 
915 void
916 co_lss_set_inhibit(co_lss_t *lss, co_unsigned16_t inhibit)
917 {
918  assert(lss);
919 
920  lss->inhibit = inhibit;
921 }
922 
923 int
925 {
926  assert(lss);
927 
928  return lss->timeout;
929 }
930 
931 void
932 co_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 
944 int
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 
960 int
962 {
963  assert(lss);
964 
965  return lss->state == co_lss_wait_state;
966 }
967 
968 void
970 {
971  assert(lss);
972 
974 }
975 
976 int
977 co_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 
998 int
999 co_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 
1020 int
1021 co_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 
1052 int
1053 co_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 
1093 int
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 
1116 int
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 
1141 int
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 
1166 int
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 
1191 int
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 
1217 int
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 
1243 int
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 
1268 int
1269 co_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 
1302 int
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 
1328 int
1329 co_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 
1364 int
1365 co_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 
1411 static int
1412 co_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
1424 static int
1425 co_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 
1437 static 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 
1453 static inline void
1454 co_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
1464 static inline void
1465 co_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 
1475 static 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 
1489  return co_lss_wait_slave_state;
1490 }
1491 
1492 static 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 
1506 static 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 
1564 static co_lss_state_t *
1565 co_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:
1742  case CO_NMT_ST_RESET_NODE:
1743  case CO_NMT_ST_RESET_COMM:
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 
1757 static co_lss_state_t *
1758 co_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 
1769 static co_lss_state_t *
1770 co_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 
1779 static co_lss_state_t *
1781 {
1782  (void)lss;
1783 
1784  return co_lss_wait_state;
1785 }
1786 
1787 static 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 
1799 static 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 
1809 static co_lss_state_t *
1810 co_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 
1830 static co_lss_state_t *
1831 co_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 
1844 static co_lss_state_t *
1845 co_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 
1854 static 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 
1866 static co_lss_state_t *
1867 co_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 
1879 static co_lss_state_t *
1880 co_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 
1889 static 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 
1901 static co_lss_state_t *
1902 co_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 
1914 static co_lss_state_t *
1915 co_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 
1924 static 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 
1936 static 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 
1946 static co_lss_state_t *
1947 co_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 
1967 static 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 
1977 static 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 
1989 static co_lss_state_t *
1990 co_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 
2012 static 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 
2032 static 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 
2045 static co_lss_state_t *
2046 co_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 
2065 static co_lss_state_t *
2066 co_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 
2096 static co_lss_state_t *
2098 {
2099  (void)lss;
2100  (void)msg;
2101 
2102  // Ignore further responses from slaves.
2103  return NULL;
2104 }
2105 
2106 static co_lss_state_t *
2107 co_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 
2116 static 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 
2126 static 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 
2138 static co_lss_state_t *
2139 co_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 
2161 static co_lss_state_t *
2163 {
2164  (void)lss;
2165 
2166  return co_lss_wait_state;
2167 }
2168 
2169 static 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 
2182 static 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 
2195 static co_lss_state_t *
2196 co_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 
2206 static 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 
2247 static 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 
2260 static co_lss_state_t *
2261 co_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 
2269 static co_lss_state_t *
2270 co_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 
2302 static co_lss_state_t *
2304 {
2305  (void)lss;
2306  (void)msg;
2307 
2308  // Ignore further responses from slaves.
2309  return NULL;
2310 }
2311 
2312 static co_lss_state_t *
2313 co_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 
2322 static co_lss_state_t *
2324 {
2325  (void)lss;
2326 
2327  return co_lss_wait_state;
2328 }
2329 
2330 static 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 
2345 static co_lss_state_t *
2346 co_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 
2391 static void
2392 co_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 
2454 static 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:
2466  case CO_NMT_ST_RESET_NODE:
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 
2476 static co_lss_state_t *
2477 co_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 
2514 static void
2515 co_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 
2528 static 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 
2572 static 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 
2630 static int
2631 co_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 
2645 static void
2646 co_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 
2660 static inline co_unsigned32_t *
2661 co_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_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
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
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
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
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
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_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
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_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
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
can_recv_t * can_recv_create(void)
Creates a new CAN frame receiver.
Definition: net.c:533
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
can_timer_t * can_timer_create(void)
Creates a new CAN timer.
Definition: net.c:376
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
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...
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
#define CO_NMT_ST_BOOTUP
The NMT state 'boot-up'.
Definition: nmt.h:55
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_id(const co_nmt_t *nmt)
Returns the pending node-ID.
Definition: nmt.c:1743
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_enter)(co_lss_t *lss)
A pointer to the function invoked when a new state is entered.
Definition: lss.c:167
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
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