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