Lely core libraries  1.9.2
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 
35 #include <assert.h>
36 #include <stdlib.h>
37 
38 struct __co_lss_state;
40 typedef const struct __co_lss_state co_lss_state_t;
41 
43 struct __co_lss {
52 #ifndef LELY_NO_CO_MASTER
53  int master;
55 #endif
58 #ifndef LELY_NO_CO_MASTER
59  int timeout;
63 #endif
64  co_unsigned8_t cs;
67  co_unsigned8_t lsspos;
68 #ifndef LELY_NO_CO_MASTER
69  struct co_id lo;
72  struct co_id hi;
74  struct co_id mask;
76  co_unsigned8_t bitchk;
81  co_unsigned8_t lsssub;
83  co_unsigned8_t err;
85  co_unsigned8_t spec;
87  co_unsigned32_t lssid;
89  co_unsigned8_t nid;
91  struct co_id id;
92 #endif
96  void *rate_data;
100  void *store_data;
101 #ifndef LELY_NO_CO_MASTER
105  void *cs_data;
109  void *err_data;
113  void *lssid_data;
117  void *nid_data;
121  void *scan_data;
122 #endif
123 };
124 
126 static int co_lss_recv(const struct can_msg *msg, void *data);
127 
128 #ifndef LELY_NO_CO_MASTER
129 static int co_lss_timer(const struct timespec *tp, void *data);
131 #endif
132 
137 static void co_lss_enter(co_lss_t *lss, co_lss_state_t *next);
138 
146 static inline void co_lss_emit_recv(co_lss_t *lss, const struct can_msg *msg);
147 
148 #ifndef LELY_NO_CO_MASTER
149 
156 static inline void co_lss_emit_time(co_lss_t *lss, const struct timespec *tp);
157 #endif
158 
162  co_lss_state_t *(*on_enter)(co_lss_t *lss);
172  co_lss_state_t *(*on_recv)(co_lss_t *lss, const struct can_msg *msg);
173 #ifndef LELY_NO_CO_MASTER
174 
182  co_lss_state_t *(*on_time)(co_lss_t *lss, const struct timespec *tp);
183 #endif
184  void (*on_leave)(co_lss_t *lss);
186 };
187 
188 #define LELY_CO_DEFINE_STATE(name, ...) \
189  static co_lss_state_t *const name = &(co_lss_state_t){ __VA_ARGS__ };
190 
193 
195 // clang-format off
196 LELY_CO_DEFINE_STATE(co_lss_wait_state,
197  .on_enter = &co_lss_wait_on_enter
198 )
199 // clang-format on
200 
203 
209  co_lss_t *lss, const struct can_msg *msg);
210 
212 // clang-format off
213 LELY_CO_DEFINE_STATE(co_lss_wait_slave_state,
214  .on_enter = &co_lss_wait_slave_on_enter,
215  .on_recv = &co_lss_wait_slave_on_recv
216 )
217 // clang-format on
218 
224  co_lss_t *lss, const struct can_msg *msg);
225 
227 // clang-format off
228 LELY_CO_DEFINE_STATE(co_lss_cfg_state,
229  .on_recv = &co_lss_cfg_on_recv
230 )
231 // clang-format on
232 
233 #ifndef LELY_NO_CO_MASTER
234 
237  co_lss_t *lss, const struct can_msg *msg);
238 
241  co_lss_t *lss, const struct timespec *tp);
242 
244 static void co_lss_cs_on_leave(co_lss_t *lss);
245 
247 // clang-format off
248 LELY_CO_DEFINE_STATE(co_lss_cs_state,
249  .on_recv = &co_lss_cs_on_recv,
250  .on_time = &co_lss_cs_on_time,
251  .on_leave = &co_lss_cs_on_leave
252 )
253 // clang-format on
254 
257  co_lss_t *lss, const struct can_msg *msg);
258 
261  co_lss_t *lss, const struct timespec *tp);
262 
264 static void co_lss_err_on_leave(co_lss_t *lss);
265 
267 // clang-format off
268 LELY_CO_DEFINE_STATE(co_lss_err_state,
269  .on_recv = &co_lss_err_on_recv,
270  .on_time = &co_lss_err_on_time,
271  .on_leave = &co_lss_err_on_leave
272 )
273 // clang-format on
274 
277  co_lss_t *lss, const struct can_msg *msg);
278 
281  co_lss_t *lss, const struct timespec *tp);
282 
284 static void co_lss_lssid_on_leave(co_lss_t *lss);
285 
287 // clang-format off
288 LELY_CO_DEFINE_STATE(co_lss_lssid_state,
289  .on_recv = &co_lss_lssid_on_recv,
290  .on_time = &co_lss_lssid_on_time,
291  .on_leave = &co_lss_lssid_on_leave
292 )
293 // clang-format on
294 
297  co_lss_t *lss, const struct can_msg *msg);
298 
301  co_lss_t *lss, const struct timespec *tp);
302 
304 static void co_lss_nid_on_leave(co_lss_t *lss);
305 
307 // clang-format off
308 LELY_CO_DEFINE_STATE(co_lss_nid_state,
309  .on_recv = &co_lss_nid_on_recv,
310  .on_time = &co_lss_nid_on_time,
311  .on_leave = &co_lss_nid_on_leave
312 )
313 // clang-format on
314 
320  co_lss_t *lss, const struct can_msg *msg);
321 
324  co_lss_t *lss, const struct timespec *tp);
325 
327 // clang-format off
328 LELY_CO_DEFINE_STATE(co_lss_slowscan_init_state,
329  .on_recv = &co_lss_slowscan_init_on_recv,
330  .on_time = &co_lss_slowscan_init_on_time
331 )
332 // clang-format on
333 
336 
339  co_lss_t *lss, const struct can_msg *msg);
340 
343  co_lss_t *lss, const struct timespec *tp);
344 
345 static co_lss_state_t *co_lss_slowscan_scan_on_res(co_lss_t *lss, int timeout);
346 
348 // clang-format off
349 LELY_CO_DEFINE_STATE(co_lss_slowscan_scan_state,
350  .on_enter = &co_lss_slowscan_scan_on_enter,
351  .on_recv = &co_lss_slowscan_scan_on_recv,
352  .on_time = &co_lss_slowscan_scan_on_time
353 )
354 // clang-format on
355 
358  co_lss_t *lss, const struct can_msg *msg);
359 
362  co_lss_t *lss, const struct timespec *tp);
363 
365 // clang-format off
366 LELY_CO_DEFINE_STATE(co_lss_slowscan_wait_state,
367  .on_recv = &co_lss_slowscan_wait_on_recv,
368  .on_time = &co_lss_slowscan_wait_on_time
369 )
370 // clang-format on
371 
374 
380  co_lss_t *lss, const struct can_msg *msg);
381 
387  co_lss_t *lss, const struct timespec *tp);
388 
390 // clang-format off
391 LELY_CO_DEFINE_STATE(co_lss_slowscan_switch_state,
392  .on_enter = &co_lss_slowscan_switch_on_enter,
393  .on_recv = &co_lss_slowscan_switch_on_recv,
395 )
396 // clang-format on
397 
400 
402 static void co_lss_slowscan_fini_on_leave(co_lss_t *lss);
403 
405 // clang-format off
406 LELY_CO_DEFINE_STATE(co_lss_slowscan_fini_state,
407  .on_enter = &co_lss_slowscan_fini_on_enter,
408  .on_leave = &co_lss_slowscan_fini_on_leave
409 )
410 // clang-format on
411 
417  co_lss_t *lss, const struct can_msg *msg);
418 
421  co_lss_t *lss, const struct timespec *tp);
422 
424 // clang-format off
425 LELY_CO_DEFINE_STATE(co_lss_fastscan_init_state,
426  .on_recv = &co_lss_fastscan_init_on_recv,
427  .on_time = &co_lss_fastscan_init_on_time
428 )
429 // clang-format on
430 
433 
436  co_lss_t *lss, const struct can_msg *msg);
437 
440  co_lss_t *lss, const struct timespec *tp);
441 
442 static co_lss_state_t *co_lss_fastscan_scan_on_res(co_lss_t *lss, int timeout);
443 
445 // clang-format off
446 LELY_CO_DEFINE_STATE(co_lss_fastscan_scan_state,
447  .on_enter = &co_lss_fastscan_scan_on_enter,
448  .on_recv = &co_lss_fastscan_scan_on_recv,
449  .on_time = &co_lss_fastscan_scan_on_time
450 )
451 // clang-format on
452 
455  co_lss_t *lss, const struct can_msg *msg);
456 
459  co_lss_t *lss, const struct timespec *tp);
460 
462 // clang-format off
463 LELY_CO_DEFINE_STATE(co_lss_fastscan_wait_state,
464  .on_recv = &co_lss_fastscan_wait_on_recv,
465  .on_time = &co_lss_fastscan_wait_on_time
466 )
467 // clang-format on
468 
471 
473 static void co_lss_fastscan_fini_on_leave(co_lss_t *lss);
474 
476 // clang-format off
477 LELY_CO_DEFINE_STATE(co_lss_fastscan_fini_state,
478  .on_enter = &co_lss_fastscan_fini_on_enter,
479  .on_leave = &co_lss_fastscan_fini_on_leave
480 )
481 // clang-format on
482 
483 #endif // !LELY_NO_CO_MASTER
484 
485 #undef LELY_CO_DEFINE_STATE
486 
498  co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id);
499 
508 static void co_lss_id_slave(
509  co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id);
510 
515 static void co_lss_id_non_cfg_slave(const co_lss_t *lss);
516 
531 static co_lss_state_t *co_lss_fastscan(co_lss_t *lss, co_unsigned32_t id,
532  co_unsigned8_t bitchk, co_unsigned8_t lsssub,
533  co_unsigned8_t lssnext);
534 
542 static void co_lss_init_req(
543  const co_lss_t *lss, struct can_msg *msg, co_unsigned8_t cs);
544 
545 #ifndef LELY_NO_CO_MASTER
546 
556 static int co_lss_send_switch_sel_req(
557  const co_lss_t *lss, const struct co_id *id);
558 
570 static int co_lss_send_id_slave_req(const co_lss_t *lss, const struct co_id *lo,
571  const struct co_id *hi);
572 
584 static int co_lss_send_fastscan_req(const co_lss_t *lss, co_unsigned32_t id,
585  co_unsigned8_t bitchk, co_unsigned8_t lsssub,
586  co_unsigned8_t lssnext);
587 
594 static void co_lss_init_ind(co_lss_t *lss, co_unsigned8_t cs);
595 
596 #endif
597 
598 void *
599 __co_lss_alloc(void)
600 {
601  void *ptr = malloc(sizeof(struct __co_lss));
602  if (__unlikely(!ptr))
603  set_errc(errno2c(errno));
604  return ptr;
605 }
606 
607 void
608 __co_lss_free(void *ptr)
609 {
610  free(ptr);
611 }
612 
613 struct __co_lss *
614 __co_lss_init(struct __co_lss *lss, co_nmt_t *nmt)
615 {
616  assert(lss);
617  assert(nmt);
618 
619  int errc = 0;
620 
621  lss->nmt = nmt;
622  lss->net = co_nmt_get_net(lss->nmt);
623  lss->dev = co_nmt_get_dev(lss->nmt);
624 
625  lss->state = NULL;
626 
627 #ifndef LELY_NO_CO_MASTER
628  lss->master = 0;
629 #endif
630 
631  lss->recv = can_recv_create();
632  if (__unlikely(!lss->recv)) {
633  errc = get_errc();
634  goto error_create_recv;
635  }
636  can_recv_set_func(lss->recv, &co_lss_recv, lss);
637 
638 #ifndef LELY_NO_CO_MASTER
640 
641  lss->timer = can_timer_create();
642  if (__unlikely(!lss->timer)) {
643  errc = get_errc();
644  goto error_create_timer;
645  }
647 #endif
648 
649  lss->cs = 0;
650  lss->lsspos = 0;
651 #ifndef LELY_NO_CO_MASTER
652  lss->lo = (struct co_id)CO_ID_INIT;
653  lss->hi = (struct co_id)CO_ID_INIT;
654  lss->mask = (struct co_id)CO_ID_INIT;
655  lss->bitchk = 0;
656  lss->lsssub = 0;
657  lss->err = 0;
658  lss->spec = 0;
659  lss->lssid = 0;
660  lss->nid = 0;
661  lss->id = (struct co_id)CO_ID_INIT;
662 #endif
663 
664  lss->rate_ind = NULL;
665  lss->rate_data = NULL;
666  lss->store_ind = NULL;
667  lss->store_data = NULL;
668 #ifndef LELY_NO_CO_MASTER
669  lss->cs_ind = NULL;
670  lss->cs_data = NULL;
671  lss->err_ind = NULL;
672  lss->err_data = NULL;
673  lss->lssid_ind = NULL;
674  lss->lssid_data = NULL;
675  lss->nid_ind = NULL;
676  lss->nid_data = NULL;
677  lss->scan_ind = NULL;
678  lss->scan_data = NULL;
679 #endif
680 
682  return lss;
683 
684 #ifndef LELY_NO_CO_MASTER
685  can_timer_destroy(lss->timer);
686 error_create_timer:
687 #endif
688  can_recv_destroy(lss->recv);
689 error_create_recv:
690  set_errc(errc);
691  return NULL;
692 }
693 
694 void
695 __co_lss_fini(struct __co_lss *lss)
696 {
697  assert(lss);
698 
699 #ifndef LELY_NO_CO_MASTER
700  can_timer_destroy(lss->timer);
701 #endif
702  can_recv_destroy(lss->recv);
703 }
704 
705 co_lss_t *
707 {
708  trace("creating LSS");
709 
710  int errc = 0;
711 
712  co_lss_t *lss = __co_lss_alloc();
713  if (__unlikely(!lss)) {
714  errc = get_errc();
715  goto error_alloc_lss;
716  }
717 
718  if (__unlikely(!__co_lss_init(lss, nmt))) {
719  errc = get_errc();
720  goto error_init_lss;
721  }
722 
723  return lss;
724 
725 error_init_lss:
726  __co_lss_free(lss);
727 error_alloc_lss:
728  set_errc(errc);
729  return NULL;
730 }
731 
732 void
734 {
735  if (lss) {
736  trace("destroying LSS");
737  __co_lss_fini(lss);
738  __co_lss_free(lss);
739  }
740 }
741 
742 co_nmt_t *
744 {
745  assert(lss);
746 
747  return lss->nmt;
748 }
749 
750 void
751 co_lss_get_rate_ind(const co_lss_t *lss, co_lss_rate_ind_t **pind, void **pdata)
752 {
753  assert(lss);
754 
755  if (pind)
756  *pind = lss->rate_ind;
757  if (pdata)
758  *pdata = lss->rate_data;
759 }
760 
761 void
763 {
764  assert(lss);
765 
766  lss->rate_ind = ind;
767  lss->rate_data = data;
768 }
769 
770 void
772  const co_lss_t *lss, co_lss_store_ind_t **pind, void **pdata)
773 {
774  assert(lss);
775 
776  if (pind)
777  *pind = lss->store_ind;
778  if (pdata)
779  *pdata = lss->store_data;
780 }
781 
782 void
784 {
785  assert(lss);
786 
787  lss->store_ind = ind;
788  lss->store_data = data;
789 }
790 
791 #ifndef LELY_NO_CO_MASTER
792 
793 int
795 {
796  assert(lss);
797 
798  return lss->timeout;
799 }
800 
801 void
802 co_lss_set_timeout(co_lss_t *lss, int timeout)
803 {
804  assert(lss);
805 
806  if (lss->timeout && timeout <= 0)
807  can_timer_stop(lss->timer);
808 
809  lss->timeout = MAX(0, timeout);
810 }
811 
812 #endif
813 
814 int
816 {
817 #ifdef LELY_NO_CO_MASTER
818  (void)lss;
819 
820  return 0;
821 #else
822  assert(lss);
823 
824  return lss->master;
825 #endif
826 }
827 
828 #ifndef LELY_NO_CO_MASTER
829 
830 int
832 {
833  assert(lss);
834 
835  return lss->state == co_lss_wait_state;
836 }
837 
838 void
840 {
841  assert(lss);
842 
844 }
845 
846 int
847 co_lss_switch_req(co_lss_t *lss, co_unsigned8_t mode)
848 {
849  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
851  return -1;
852  }
853 
854  if (__unlikely(mode > 0x01)) {
856  return -1;
857  }
858 
859  trace("LSS: switch state global");
860 
861  // Switch state global (see Fig. 31 in CiA 305 version 3.0.0).
862  struct can_msg req;
863  co_lss_init_req(lss, &req, 0x04);
864  req.data[1] = mode;
865  return can_net_send(lss->net, &req);
866 }
867 
868 int
869 co_lss_switch_sel_req(co_lss_t *lss, const struct co_id *id,
870  co_lss_cs_ind_t *ind, void *data)
871 {
872  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
874  return -1;
875  }
876 
877  trace("LSS: switch state selective");
878 
879  // Switch state selective (see Fig. 32 in CiA 305 version 3.0.0).
880  if (__unlikely(co_lss_send_switch_sel_req(lss, id) == -1))
881  return -1;
882 
883  // Wait for response.
884  co_lss_init_ind(lss, 0x44);
885  lss->cs_ind = ind;
886  lss->cs_data = data;
888 
889  return 0;
890 }
891 
892 int
893 co_lss_set_id_req(co_lss_t *lss, co_unsigned8_t id, co_lss_err_ind_t *ind,
894  void *data)
895 {
896  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
898  return -1;
899  }
900 
901  if (__unlikely(!id || (id > CO_NUM_NODES && id != 0xff))) {
903  return -1;
904  }
905 
906  trace("LSS: configure node-ID");
907 
908  // Configure node-ID (see Fig. 33 in CiA 305 version 3.0.0).
909  struct can_msg req;
910  co_lss_init_req(lss, &req, 0x11);
911  req.data[1] = id;
912  if (__unlikely(can_net_send(lss->net, &req) == -1))
913  return -1;
914 
915  // Wait for response.
916  co_lss_init_ind(lss, req.data[0]);
917  lss->err_ind = ind;
918  lss->err_data = data;
920 
921  return 0;
922 }
923 
924 int
925 co_lss_set_rate_req(co_lss_t *lss, co_unsigned16_t rate, co_lss_err_ind_t *ind,
926  void *data)
927 {
928  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
930  return -1;
931  }
932 
933  // Configure bit timing parameters (see Fig. 34 in CiA 305 version
934  // 3.0.0).
935  struct can_msg req;
936  co_lss_init_req(lss, &req, 0x13);
937  req.data[1] = 0;
938  switch (rate) {
939  case 1000: req.data[2] = 0; break;
940  case 800: req.data[2] = 1; break;
941  case 500: req.data[2] = 2; break;
942  case 250: req.data[2] = 3; break;
943  case 125: req.data[2] = 4; break;
944  case 50: req.data[2] = 6; break;
945  case 20: req.data[2] = 7; break;
946  case 10: req.data[2] = 8; break;
947  case 0: req.data[2] = 9; break;
948  default: set_errnum(ERRNUM_INVAL); return 0;
949  }
950 
951  trace("LSS: configure bit timing parameters");
952 
953  if (__unlikely(can_net_send(lss->net, &req) == -1))
954  return -1;
955 
956  // Wait for response.
957  co_lss_init_ind(lss, req.data[0]);
958  lss->err_ind = ind;
959  lss->err_data = data;
961 
962  return 0;
963 }
964 
965 int
967 {
968  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
970  return -1;
971  }
972 
973  // clang-format off
974  if (__unlikely(delay < CO_UNSIGNED16_MIN
975  || delay > CO_UNSIGNED16_MAX)) {
976  // clang-format on
978  return -1;
979  }
980 
981  trace("LSS: activate bit timing parameters");
982 
983  // Activate bit timing parameters (see Fig. 35 in CiA 305 version
984  // 3.0.0).
985  struct can_msg req;
986  co_lss_init_req(lss, &req, 0x15);
987  stle_u16(req.data + 1, (co_unsigned16_t)delay);
988  return can_net_send(lss->net, &req);
989 }
990 
991 int
993 {
994  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
996  return -1;
997  }
998 
999  trace("LSS: store configuration");
1000 
1001  // Store configuration (see Fig. 36 in CiA 305 version 3.0.0).
1002  struct can_msg req;
1003  co_lss_init_req(lss, &req, 0x17);
1004  if (__unlikely(can_net_send(lss->net, &req) == -1))
1005  return -1;
1006 
1007  // Wait for response.
1008  co_lss_init_ind(lss, req.data[0]);
1009  lss->err_ind = ind;
1010  lss->err_data = data;
1012 
1013  return 0;
1014 }
1015 
1016 int
1018 {
1019  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
1021  return -1;
1022  }
1023 
1024  trace("LSS: inquire identity vendor-ID");
1025 
1026  // Inquire identity vendor-ID (see Fig. 37 in CiA 305 version 3.0.0).
1027  struct can_msg req;
1028  co_lss_init_req(lss, &req, 0x5a);
1029  if (__unlikely(can_net_send(lss->net, &req) == -1))
1030  return -1;
1031 
1032  // Wait for response.
1033  co_lss_init_ind(lss, req.data[0]);
1034  lss->lssid_ind = ind;
1035  lss->lssid_data = data;
1037 
1038  return 0;
1039 }
1040 
1041 int
1043 {
1044  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
1046  return -1;
1047  }
1048 
1049  trace("LSS: inquire identity product-code");
1050 
1051  // Inquire identity product-code (see Fig. 38 in CiA 305 version 3.0.0).
1052  struct can_msg req;
1053  co_lss_init_req(lss, &req, 0x5b);
1054  if (__unlikely(can_net_send(lss->net, &req) == -1))
1055  return -1;
1056 
1057  // Wait for response.
1058  co_lss_init_ind(lss, req.data[0]);
1059  lss->lssid_ind = ind;
1060  lss->lssid_data = data;
1062 
1063  return 0;
1064 }
1065 
1066 int
1068 {
1069  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
1071  return -1;
1072  }
1073 
1074  trace("LSS: inquire identity revision-number");
1075 
1076  // Inquire identity revision-number (see Fig. 39 in CiA 305 version
1077  // 3.0.0).
1078  struct can_msg req;
1079  co_lss_init_req(lss, &req, 0x5c);
1080  if (__unlikely(can_net_send(lss->net, &req) == -1))
1081  return -1;
1082 
1083  // Wait for response.
1084  co_lss_init_ind(lss, req.data[0]);
1085  lss->lssid_ind = ind;
1086  lss->lssid_data = data;
1088 
1089  return 0;
1090 }
1091 
1092 int
1094 {
1095  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
1097  return -1;
1098  }
1099 
1100  trace("LSS: inquire identity serial number");
1101 
1102  // Inquire identity serial-number (see Fig. 40 in CiA 305 version
1103  // 3.0.0).
1104  struct can_msg req;
1105  co_lss_init_req(lss, &req, 0x5d);
1106  if (__unlikely(can_net_send(lss->net, &req) == -1))
1107  return -1;
1108 
1109  // Wait for response.
1110  co_lss_init_ind(lss, req.data[0]);
1111  lss->lssid_ind = ind;
1112  lss->lssid_data = data;
1114 
1115  return 0;
1116 }
1117 
1118 int
1120 {
1121  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
1123  return -1;
1124  }
1125 
1126  trace("LSS: inquire node-ID");
1127 
1128  // Inquire node-ID (see Fig. 41 in CiA 305 version 3.0.0).
1129  struct can_msg req;
1130  co_lss_init_req(lss, &req, 0x5e);
1131  if (__unlikely(can_net_send(lss->net, &req) == -1))
1132  return -1;
1133 
1134  // Wait for response.
1135  co_lss_init_ind(lss, req.data[0]);
1136  lss->nid_ind = ind;
1137  lss->nid_data = data;
1139 
1140  return 0;
1141 }
1142 
1143 int
1144 co_lss_id_slave_req(co_lss_t *lss, const struct co_id *lo,
1145  const struct co_id *hi, co_lss_cs_ind_t *ind, void *data)
1146 {
1147  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
1149  return -1;
1150  }
1151 
1152  trace("LSS: identify remote slave");
1153 
1154  // LSS identify remote slave (see Fig. 42 in CiA 305 version 3.0.0).
1155  if (__unlikely(co_lss_send_id_slave_req(lss, lo, hi) == -1))
1156  return -1;
1157 
1158  // Wait for response (see Fig. 43 in CiA 305 version 3.0.0).
1159  co_lss_init_ind(lss, 0x4f);
1160  lss->cs_ind = ind;
1161  lss->cs_data = data;
1163 
1164  return 0;
1165 }
1166 
1167 int
1169 {
1170  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
1172  return -1;
1173  }
1174 
1175  trace("LSS: identify non-configured remote slave");
1176 
1177  // LSS identify non-configured remote slave (see Fig. 44 in CiA 305
1178  // version 3.0.0).
1179  struct can_msg req;
1180  co_lss_init_req(lss, &req, 0x4c);
1181  if (__unlikely(can_net_send(lss->net, &req) == -1))
1182  return -1;
1183 
1184  // Wait for response (see Fig. 45 in CiA 305 version 3.0.0).
1185  co_lss_init_ind(lss, 0x50);
1186  lss->cs_ind = ind;
1187  lss->cs_data = data;
1189 
1190  return 0;
1191 }
1192 
1193 int
1194 co_lss_slowscan_req(co_lss_t *lss, const struct co_id *lo,
1195  const struct co_id *hi, co_lss_scan_ind_t *ind, void *data)
1196 {
1197  assert(lo);
1198  assert(hi);
1199 
1200  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
1202  return -1;
1203  }
1204 
1205  trace("LSS: Slowscan");
1206 
1207  lss->lo = *lo;
1208  lss->lo.n = 4;
1209  lss->hi = *hi;
1210  lss->hi.n = 4;
1211 
1212  // LSS identify remote slave (see Fig. 42 in CiA 305 version 3.0.0).
1213  if (__unlikely(co_lss_send_id_slave_req(lss, &lss->lo, &lss->hi) == -1))
1214  return -1;
1215 
1216  lss->id = (struct co_id)CO_ID_INIT;
1217 
1218  // Wait for response (see Fig. 43 in CiA 305 version 3.0.0).
1219  co_lss_init_ind(lss, 0x4f);
1220  lss->scan_ind = ind;
1221  lss->scan_data = data;
1223 
1224  return 0;
1225 }
1226 
1227 int
1228 co_lss_fastscan_req(co_lss_t *lss, const struct co_id *id,
1229  const struct co_id *mask, co_lss_scan_ind_t *ind, void *data)
1230 {
1231  if (__unlikely(!co_lss_is_master(lss) || !co_lss_is_idle(lss))) {
1233  return -1;
1234  }
1235 
1236  trace("LSS: Fastscan");
1237 
1238  lss->id = (struct co_id)CO_ID_INIT;
1239  lss->mask = (struct co_id)CO_ID_INIT;
1240  if (mask) {
1241  lss->mask = *mask;
1242  lss->mask.n = 4;
1243  if (id) {
1244  lss->id = *id;
1245  lss->id.n = 4;
1246  // Clear all unmasked bits in the LSS address.
1247  lss->id.vendor_id &= lss->mask.vendor_id;
1248  lss->id.product_code &= lss->mask.product_code;
1249  lss->id.revision &= lss->mask.revision;
1250  lss->id.serial_nr &= lss->mask.serial_nr;
1251  }
1252  }
1253  lss->bitchk = 0x80;
1254  lss->lsssub = 0;
1255 
1256  // LSS Fastscan (see Fig. 46 in CiA 305 version 3.0.0).
1257  struct can_msg req;
1258  co_lss_init_req(lss, &req, 0x51);
1259  req.data[5] = lss->bitchk;
1260  if (__unlikely(can_net_send(lss->net, &req) == -1))
1261  return -1;
1262 
1263  // Wait for response (see Fig. 43 in CiA 305 version 3.0.0).
1264  co_lss_init_ind(lss, 0x4f);
1265  lss->scan_ind = ind;
1266  lss->scan_data = data;
1268 
1269  return 0;
1270 }
1271 
1272 #endif // !LELY_NO_CO_MASTER
1273 
1274 static int
1275 co_lss_recv(const struct can_msg *msg, void *data)
1276 {
1277  assert(msg);
1278  co_lss_t *lss = data;
1279  assert(lss);
1280 
1281  co_lss_emit_recv(lss, msg);
1282 
1283  return 0;
1284 }
1285 
1286 #ifndef LELY_NO_CO_MASTER
1287 static int
1288 co_lss_timer(const struct timespec *tp, void *data)
1289 {
1290  assert(tp);
1291  co_lss_t *lss = data;
1292  assert(lss);
1293 
1294  co_lss_emit_time(lss, tp);
1295 
1296  return 0;
1297 }
1298 #endif
1299 
1300 static void
1302 {
1303  assert(lss);
1304 
1305  while (next) {
1306  co_lss_state_t *prev = lss->state;
1307  lss->state = next;
1308 
1309  if (prev && prev->on_leave)
1310  prev->on_leave(lss);
1311 
1312  next = next->on_enter ? next->on_enter(lss) : NULL;
1313  }
1314 }
1315 
1316 static inline void
1317 co_lss_emit_recv(co_lss_t *lss, const struct can_msg *msg)
1318 {
1319  assert(lss);
1320  assert(lss->state);
1321  assert(lss->state->on_recv);
1322 
1323  co_lss_enter(lss, lss->state->on_recv(lss, msg));
1324 }
1325 
1326 #ifndef LELY_NO_CO_MASTER
1327 static inline void
1328 co_lss_emit_time(co_lss_t *lss, const struct timespec *tp)
1329 {
1330  assert(lss);
1331  assert(lss->state);
1332  assert(lss->state->on_time);
1333 
1334  co_lss_enter(lss, lss->state->on_time(lss, tp));
1335 }
1336 #endif
1337 
1338 static co_lss_state_t *
1340 {
1341  assert(lss);
1342 
1343 #ifndef LELY_NO_CO_MASTER
1344  // Only an NMT master can be an LSS master.
1345  lss->master = co_nmt_is_master(lss->nmt);
1346  if (lss->master)
1347  return NULL;
1348 #endif
1349 
1350  return co_lss_wait_slave_state;
1351 }
1352 
1353 static co_lss_state_t *
1355 {
1356  assert(lss);
1357 
1358  lss->cs = 0;
1359  lss->lsspos = 0;
1360 
1361  // Start receiving LSS commands from the master.
1362  can_recv_start(lss->recv, lss->net, CO_LSS_CANID(1), 0);
1363 
1364  return NULL;
1365 }
1366 
1367 static co_lss_state_t *
1369 {
1370  assert(lss);
1371  assert(msg);
1372 
1373  if (__unlikely(!msg->len))
1374  return NULL;
1375 
1376  uint8_t cs = msg->data[0];
1377  switch (cs) {
1378  // Switch state global (see Fig. 31 in CiA 305 version 3.0.0).
1379  case 0x04:
1380  if (__unlikely(msg->len < 2))
1381  return NULL;
1382  switch (msg->data[1]) {
1383  case 0x00:
1384  // Re-enter the waiting state.
1385  trace("LSS: switching to waiting state");
1386  return co_lss_wait_state;
1387  case 0x01:
1388  // Switch to the configuration state.
1389  trace("LSS: switching to configuration state");
1390  return co_lss_cfg_state;
1391  }
1392  break;
1393  // Switch state selective.
1394  case 0x40:
1395  case 0x41:
1396  case 0x42:
1397  case 0x43:
1398  if (msg->len < 5)
1399  return NULL;
1400  return co_lss_switch_sel(lss, cs, ldle_u32(msg->data + 1));
1401  // LSS identify remote slave.
1402  case 0x46:
1403  case 0x47:
1404  case 0x48:
1405  case 0x49:
1406  case 0x4a:
1407  case 0x4b:
1408  if (msg->len < 5)
1409  return NULL;
1410  co_lss_id_slave(lss, msg->data[0], ldle_u32(msg->data + 1));
1411  break;
1412  // LSS identify non-configured remote slave.
1413  case 0x4c: co_lss_id_non_cfg_slave(lss); break;
1414  // LSS Fastscan.
1415  case 0x51:
1416  if (msg->len < 8)
1417  return NULL;
1418  return co_lss_fastscan(lss, ldle_u32(msg->data + 1),
1419  msg->data[5], msg->data[6], msg->data[7]);
1420  }
1421 
1422  return NULL;
1423 }
1424 
1425 static co_lss_state_t *
1426 co_lss_cfg_on_recv(co_lss_t *lss, const struct can_msg *msg)
1427 {
1428  assert(lss);
1429  assert(msg);
1430 
1431  int errc = get_errc();
1432  co_obj_t *obj_1018 = co_dev_find_obj(lss->dev, 0x1018);
1433  struct can_msg req;
1434 
1435  if (__unlikely(!msg->len))
1436  return NULL;
1437 
1438  co_unsigned8_t cs = msg->data[0];
1439  switch (cs) {
1440  // Switch state global (see Fig. 31 in CiA 305 version 3.0.0).
1441  case 0x04:
1442  if (__unlikely(msg->len < 2))
1443  return NULL;
1444  switch (msg->data[1]) {
1445  case 0x00:
1446  // Switch to the waiting state.
1447  trace("LSS: switching to waiting state");
1448  return co_lss_wait_state;
1449  case 0x01:
1450  // Re-enter the configuration state.
1451  trace("LSS: switching to configuration state");
1452  return co_lss_cfg_state;
1453  }
1454  break;
1455  // Configure node-ID (see Fig. 33 in CiA 305 version 3.0.0).
1456  case 0x11:
1457  if (msg->len < 2)
1458  return NULL;
1459  // Configure the pending node-ID.
1460  trace("LSS: configuring node-ID");
1461  co_lss_init_req(lss, &req, cs);
1462  if (co_nmt_set_id(lss->nmt, msg->data[1]) == -1) {
1463  // Discard the error code if the node-ID was invalid.
1464  set_errc(errc);
1465  req.data[1] = 1;
1466  }
1467  can_net_send(lss->net, &req);
1468  break;
1469  // Configure bit timing parameters (see Fig. 34 in CiA 305 version
1470  // 3.0.0).
1471  case 0x13:
1472  if (msg->len < 3)
1473  return NULL;
1474  // Configure the pending baudrate.
1475  trace("LSS: configuring bit timing parameters");
1476  co_lss_init_req(lss, &req, cs);
1477  if (__unlikely(!lss->rate_ind || msg->data[1])) {
1478  req.data[1] = 1;
1479  } else {
1480  unsigned int baud = co_dev_get_baud(lss->dev);
1481  switch (msg->data[2]) {
1482  case 0:
1483  if (!(req.data[1] = !(baud & CO_BAUD_1000)))
1484  co_dev_set_rate(lss->dev, 1000);
1485  break;
1486  case 1:
1487  if (!(req.data[1] = !(baud & CO_BAUD_800)))
1488  co_dev_set_rate(lss->dev, 800);
1489  break;
1490  case 2:
1491  if (!(req.data[1] = !(baud & CO_BAUD_500)))
1492  co_dev_set_rate(lss->dev, 500);
1493  break;
1494  case 3:
1495  if (!(req.data[1] = !(baud & CO_BAUD_250)))
1496  co_dev_set_rate(lss->dev, 250);
1497  break;
1498  case 4:
1499  if (!(req.data[1] = !(baud & CO_BAUD_125)))
1500  co_dev_set_rate(lss->dev, 135);
1501  break;
1502  case 6:
1503  if (!(req.data[1] = !(baud & CO_BAUD_50)))
1504  co_dev_set_rate(lss->dev, 50);
1505  break;
1506  case 7:
1507  if (!(req.data[1] = !(baud & CO_BAUD_20)))
1508  co_dev_set_rate(lss->dev, 20);
1509  break;
1510  case 8:
1511  if (!(req.data[1] = !(baud & CO_BAUD_10)))
1512  co_dev_set_rate(lss->dev, 10);
1513  break;
1514  case 9:
1515  if (!(req.data[1] = !(baud & CO_BAUD_AUTO)))
1516  co_dev_set_rate(lss->dev, 0);
1517  break;
1518  default: req.data[1] = 1; break;
1519  }
1520  }
1521  can_net_send(lss->net, &req);
1522  break;
1523  // Activate bit timing parameters (see Fig. 35 in CiA 305 version
1524  // 3.0.0).
1525  case 0x15:
1526  if (msg->len < 3 || !lss->rate_ind)
1527  return NULL;
1528  // Invoke the user-specified callback function to perform the
1529  // baudrate switch.
1530  trace("LSS: activating bit timing parameters");
1531  lss->rate_ind(lss, co_dev_get_rate(lss->dev),
1532  ldle_u16(msg->data + 1), lss->rate_data);
1533  break;
1534  // Store configuration (see Fig. 36 in CiA 305 version 3.0.0).
1535  case 0x17:
1536  trace("LSS: storing configuration");
1537  co_lss_init_req(lss, &req, cs);
1538  if (lss->store_ind) {
1539  // Store the pending node-ID and baudrate.
1540  // clang-format off
1541  if (__unlikely(lss->store_ind(lss,
1542  co_nmt_get_id(lss->nmt),
1543  co_dev_get_rate(lss->dev),
1544  lss->store_data) == -1)) {
1545  // clang-format on
1546  // Discard the error code.
1547  set_errc(errc);
1548  req.data[1] = 2;
1549  }
1550  } else {
1551  req.data[1] = 1;
1552  }
1553  can_net_send(lss->net, &req);
1554  break;
1555  // LSS identify remote slave.
1556  case 0x46:
1557  case 0x47:
1558  case 0x48:
1559  case 0x49:
1560  case 0x4a:
1561  case 0x4b:
1562  if (msg->len < 5)
1563  return NULL;
1564  co_lss_id_slave(lss, cs, ldle_u32(msg->data + 1));
1565  break;
1566  // LSS identify non-configured remote slave.
1567  case 0x4c: co_lss_id_non_cfg_slave(lss); break;
1568  // Inquire identity vendor-ID (Fig. 37 in CiA 305 version 3.0.0).
1569  case 0x5a:
1570  trace("LSS: sending vendor-ID");
1571  co_lss_init_req(lss, &req, cs);
1572  stle_u32(req.data + 1, co_obj_get_val_u32(obj_1018, 0x01));
1573  can_net_send(lss->net, &req);
1574  break;
1575  // Inquire identity product-code (Fig. 38 in CiA 305 version 3.0.0).
1576  case 0x5b:
1577  trace("LSS: sending product-code");
1578  co_lss_init_req(lss, &req, cs);
1579  stle_u32(req.data + 1, co_obj_get_val_u32(obj_1018, 0x02));
1580  can_net_send(lss->net, &req);
1581  break;
1582  // Inquire identity revision-number (Fig. 39 in CiA 305 version 3.0.0).
1583  case 0x5c:
1584  trace("LSS: sending revision-number");
1585  co_lss_init_req(lss, &req, cs);
1586  stle_u32(req.data + 1, co_obj_get_val_u32(obj_1018, 0x03));
1587  can_net_send(lss->net, &req);
1588  break;
1589  // Inquire identity serial-number (Fig. 40 in CiA 305 version 3.0.0).
1590  case 0x5d:
1591  trace("LSS: sending serial-number");
1592  co_lss_init_req(lss, &req, cs);
1593  stle_u32(req.data + 1, co_obj_get_val_u32(obj_1018, 0x04));
1594  can_net_send(lss->net, &req);
1595  break;
1596  // Inquire node-ID (Fig. 41 in CiA 305 version 3.0.0).
1597  case 0x5e:
1598  trace("LSS: sending node-ID");
1599  co_lss_init_req(lss, &req, cs);
1600  // Respond with the active or pending node-ID, depending on
1601  // whether the device is in the NMT state Initializing.
1602  switch (co_nmt_get_st(lss->nmt)) {
1603  case CO_NMT_ST_BOOTUP:
1604  case CO_NMT_ST_RESET_NODE:
1605  case CO_NMT_ST_RESET_COMM:
1606  req.data[1] = co_nmt_get_id(lss->nmt);
1607  break;
1608  default: req.data[1] = co_dev_get_id(lss->dev); break;
1609  }
1610  can_net_send(lss->net, &req);
1611  break;
1612  }
1613 
1614  return NULL;
1615 }
1616 
1617 #ifndef LELY_NO_CO_MASTER
1618 
1619 static co_lss_state_t *
1620 co_lss_cs_on_recv(co_lss_t *lss, const struct can_msg *msg)
1621 {
1622  assert(lss);
1623  assert(msg);
1624 
1625  if (msg->len < 1 || msg->data[0] != lss->cs)
1626  return NULL;
1627 
1628  return co_lss_wait_state;
1629 }
1630 
1631 static co_lss_state_t *
1632 co_lss_cs_on_time(co_lss_t *lss, const struct timespec *tp)
1633 {
1634  assert(lss);
1635  (void)tp;
1636 
1637  lss->cs = 0;
1638  return co_lss_wait_state;
1639 }
1640 
1641 static void
1643 {
1644  assert(lss);
1645 
1646  can_timer_stop(lss->timer);
1647  can_recv_stop(lss->recv);
1648 
1649  if (lss->cs_ind)
1650  lss->cs_ind(lss, lss->cs, lss->cs_data);
1651 }
1652 
1653 static co_lss_state_t *
1654 co_lss_err_on_recv(co_lss_t *lss, const struct can_msg *msg)
1655 {
1656  assert(lss);
1657  assert(msg);
1658 
1659  if (msg->len < 3 || msg->data[0] != lss->cs)
1660  return NULL;
1661 
1662  lss->err = msg->data[1];
1663  lss->spec = lss->err == 0xff ? msg->data[2] : 0;
1664  return co_lss_wait_state;
1665 }
1666 
1667 static co_lss_state_t *
1668 co_lss_err_on_time(co_lss_t *lss, const struct timespec *tp)
1669 {
1670  assert(lss);
1671  (void)tp;
1672 
1673  lss->cs = 0;
1674  return co_lss_wait_state;
1675 }
1676 
1677 static void
1679 {
1680  assert(lss);
1681 
1682  can_timer_stop(lss->timer);
1683  can_recv_stop(lss->recv);
1684 
1685  if (lss->err_ind)
1686  lss->err_ind(lss, lss->cs, lss->err, lss->spec, lss->err_data);
1687 }
1688 
1689 static co_lss_state_t *
1690 co_lss_lssid_on_recv(co_lss_t *lss, const struct can_msg *msg)
1691 {
1692  assert(lss);
1693  assert(msg);
1694 
1695  if (msg->len < 5 || msg->data[0] != lss->cs)
1696  return NULL;
1697 
1698  lss->lssid = ldle_u32(msg->data + 1);
1699  return co_lss_wait_state;
1700 }
1701 
1702 static co_lss_state_t *
1703 co_lss_lssid_on_time(co_lss_t *lss, const struct timespec *tp)
1704 {
1705  assert(lss);
1706  (void)tp;
1707 
1708  lss->cs = 0;
1709  return co_lss_wait_state;
1710 }
1711 
1712 static void
1714 {
1715  assert(lss);
1716 
1717  can_timer_stop(lss->timer);
1718  can_recv_stop(lss->recv);
1719 
1720  if (lss->lssid_ind)
1721  lss->lssid_ind(lss, lss->cs, lss->lssid, lss->lssid_data);
1722 }
1723 
1724 static co_lss_state_t *
1725 co_lss_nid_on_recv(co_lss_t *lss, const struct can_msg *msg)
1726 {
1727  assert(lss);
1728  assert(msg);
1729 
1730  if (msg->len < 2 || msg->data[0] != lss->cs)
1731  return NULL;
1732 
1733  lss->nid = msg->data[1];
1734  return co_lss_wait_state;
1735 }
1736 
1737 static co_lss_state_t *
1738 co_lss_nid_on_time(co_lss_t *lss, const struct timespec *tp)
1739 {
1740  assert(lss);
1741  (void)tp;
1742 
1743  lss->cs = 0;
1744  return co_lss_wait_state;
1745 }
1746 
1747 static void
1749 {
1750  assert(lss);
1751 
1752  can_timer_stop(lss->timer);
1753  can_recv_stop(lss->recv);
1754 
1755  if (lss->nid_ind)
1756  lss->nid_ind(lss, lss->cs, lss->nid, lss->nid_data);
1757 }
1758 
1759 static co_lss_state_t *
1761 {
1762  assert(lss);
1763  assert(msg);
1764 
1765  if (msg->len < 1 || msg->data[0] != lss->cs)
1766  return NULL;
1767 
1769 }
1770 
1771 static co_lss_state_t *
1772 co_lss_slowscan_init_on_time(co_lss_t *lss, const struct timespec *tp)
1773 {
1774  assert(lss);
1775  (void)tp;
1776 
1777  // Abort if we did not receive a response on the first request.
1778  lss->cs = 0;
1780 }
1781 
1782 static co_lss_state_t *
1784 {
1785  assert(lss);
1786 
1787  struct co_id *id = &lss->id;
1788 
1789  // Calculate the midpoint while avoiding integer overflow.
1790  *id = lss->lo;
1791  if (id->revision < lss->hi.revision) {
1792  id->revision += (lss->hi.revision - id->revision) / 2;
1793  id->serial_nr = lss->hi.serial_nr;
1794  } else {
1795  id->serial_nr += (lss->hi.serial_nr - id->serial_nr) / 2;
1796  }
1797 
1798  // LSS identify remote slave (see Fig. 42 in CiA 305 version 3.0.0).
1799  if (__unlikely(co_lss_send_id_slave_req(lss, &lss->lo, id) == -1)) {
1800  // Abort if sending the CAN frame failed.
1801  lss->cs = 0;
1803  }
1804 
1805  // Restart the timeout for the next response.
1806  can_timer_timeout(lss->timer, lss->net, lss->timeout);
1807  return NULL;
1808 }
1809 
1810 static co_lss_state_t *
1812 {
1813  assert(lss);
1814  assert(msg);
1815 
1816  if (msg->len < 1 || msg->data[0] != lss->cs)
1817  return NULL;
1818 
1819  // Wait until the timeout expires before handling the response.
1821 }
1822 
1823 static co_lss_state_t *
1824 co_lss_slowscan_scan_on_time(co_lss_t *lss, const struct timespec *tp)
1825 {
1826  assert(lss);
1827  (void)tp;
1828 
1829  return co_lss_slowscan_scan_on_res(lss, 1);
1830 }
1831 
1832 static co_lss_state_t *
1833 co_lss_slowscan_scan_on_res(co_lss_t *lss, int timeout)
1834 {
1835  assert(lss);
1836 
1837  if (lss->lo.revision == lss->hi.revision
1838  && lss->lo.serial_nr == lss->hi.serial_nr) {
1839  // Abort if we timeout after sending the final LSS address.
1840  if (timeout) {
1841  lss->cs = 0;
1843  }
1844  // Switch the slave to the LSS configuration state.
1845  co_lss_init_ind(lss, 0x44);
1847  }
1848 
1849  // Update the bounds on the LSS address.
1850  if (timeout) {
1851  if (lss->id.revision < lss->hi.revision)
1852  lss->lo.revision = lss->id.revision + 1;
1853  else
1854  lss->lo.serial_nr = lss->id.serial_nr + 1;
1855  } else {
1856  lss->hi = lss->id;
1857  }
1858 
1859  // Start the next cycle.
1861 }
1862 
1863 static co_lss_state_t *
1865 {
1866  (void)lss;
1867  (void)msg;
1868 
1869  // Ignore further responses from slaves.
1870  return NULL;
1871 }
1872 
1873 static co_lss_state_t *
1874 co_lss_slowscan_wait_on_time(co_lss_t *lss, const struct timespec *tp)
1875 {
1876  (void)lss;
1877  (void)tp;
1878 
1879  // All slaves should have responded by now.
1880  return co_lss_slowscan_scan_on_res(lss, 0);
1881 }
1882 
1883 static co_lss_state_t *
1885 {
1886  assert(lss);
1887 
1888  // Switch state selective (see Fig. 32 in CiA 305 version 3.0.0).
1889  if (__unlikely(co_lss_send_switch_sel_req(lss, &lss->id) == -1)) {
1890  // Abort if sending the CAN frame failed.
1891  lss->cs = 0;
1893  }
1894 
1895  // Restart the timeout for the response.
1896  can_timer_timeout(lss->timer, lss->net, lss->timeout);
1897  return NULL;
1898 }
1899 
1900 static co_lss_state_t *
1902 {
1903  assert(lss);
1904  assert(msg);
1905 
1906  if (msg->len < 1 || msg->data[0] != lss->cs)
1907  return NULL;
1908 
1910 }
1911 
1912 static co_lss_state_t *
1913 co_lss_slowscan_switch_on_time(co_lss_t *lss, const struct timespec *tp)
1914 {
1915  assert(lss);
1916  (void)tp;
1917 
1918  // Abort if no response was received.
1919  lss->cs = 0;
1921 }
1922 
1923 static co_lss_state_t *
1925 {
1926  (void)lss;
1927 
1928  return co_lss_wait_state;
1929 }
1930 
1931 static void
1933 {
1934  assert(lss);
1935 
1936  can_timer_stop(lss->timer);
1937  can_recv_stop(lss->recv);
1938 
1939  if (lss->scan_ind)
1940  lss->scan_ind(lss, lss->cs, lss->cs ? &lss->id : NULL,
1941  lss->scan_data);
1942 }
1943 
1944 static co_lss_state_t *
1946 {
1947  assert(lss);
1948  assert(msg);
1949 
1950  if (msg->len < 1 || msg->data[0] != lss->cs)
1951  return NULL;
1952 
1953  lss->bitchk = 31;
1955 }
1956 
1957 static co_lss_state_t *
1958 co_lss_fastscan_init_on_time(co_lss_t *lss, const struct timespec *tp)
1959 {
1960  assert(lss);
1961  (void)tp;
1962 
1963  // Abort if we did not receive a response on the reset request.
1964  lss->cs = 0;
1966 }
1967 
1968 static co_lss_state_t *
1970 {
1971  assert(lss);
1972 
1973  const co_unsigned32_t *pid = &lss->id.vendor_id;
1974  const co_unsigned32_t *pmask = &lss->mask.vendor_id;
1975 
1976  // Find the next unknown bit.
1977  for (; lss->bitchk
1978  && (pmask[lss->lsssub] & (UINT32_C(1) << lss->bitchk));
1979  lss->bitchk--)
1980  ;
1981 
1982  co_unsigned8_t lssnext = lss->lsssub;
1983  // If we obtained the complete LSS number, send it again and prepare for
1984  // the next number.
1985  if (!lss->bitchk && (pmask[lss->lsssub] & 1)) {
1986  if (lssnext < 3) {
1987  lssnext++;
1988  } else {
1989  lssnext = 0;
1990  }
1991  }
1992 
1993  // LSS Fastscan (see Fig. 46 in CiA 305 version 3.0.0).
1994  // clang-format off
1995  if (__unlikely(co_lss_send_fastscan_req(lss, pid[lss->lsssub],
1996  lss->bitchk, lss->lsssub, lssnext) == -1)) {
1997  // Abort if sending the CAN frame failed.
1998  // clang-format on
1999  lss->cs = 0;
2001  }
2002 
2003  // Restart the timeout for the next response.
2004  can_timer_timeout(lss->timer, lss->net, lss->timeout);
2005  return NULL;
2006 }
2007 
2008 static co_lss_state_t *
2010 {
2011  assert(lss);
2012  assert(msg);
2013 
2014  if (msg->len < 1 || msg->data[0] != lss->cs)
2015  return NULL;
2016 
2017  // Wait until the timeout expires before handling the response.
2019 }
2020 
2021 static co_lss_state_t *
2022 co_lss_fastscan_scan_on_time(co_lss_t *lss, const struct timespec *tp)
2023 {
2024  assert(lss);
2025  (void)tp;
2026 
2027  return co_lss_fastscan_scan_on_res(lss, 1);
2028 }
2029 
2030 static co_lss_state_t *
2031 co_lss_fastscan_scan_on_res(co_lss_t *lss, int timeout)
2032 {
2033  assert(lss);
2034  assert(lss->bitchk <= 31);
2035  assert(lss->lsssub < 4);
2036 
2037  co_unsigned32_t *pid = &lss->id.vendor_id;
2038  co_unsigned32_t *pmask = &lss->mask.vendor_id;
2039 
2040  if (!lss->bitchk && (pmask[lss->lsssub] & 1)) {
2041  // Abort if we timeout after sending the complete LSS number.
2042  if (__unlikely(timeout)) {
2043  lss->cs = 0;
2045  }
2046  // We're done if this was the last LSS number.
2047  if (++lss->lsssub == 4)
2049  lss->bitchk = 31;
2050  } else {
2051  // Update the LSS address. A timeout indicates the bit is 1.
2052  if (timeout)
2053  pid[lss->lsssub] |= UINT32_C(1) << lss->bitchk;
2054  pmask[lss->lsssub] |= UINT32_C(1) << lss->bitchk;
2055  }
2056 
2057  // Start the next cycle.
2059 }
2060 
2061 static co_lss_state_t *
2063 {
2064  (void)lss;
2065  (void)msg;
2066 
2067  // Ignore further responses from slaves.
2068  return NULL;
2069 }
2070 
2071 static co_lss_state_t *
2072 co_lss_fastscan_wait_on_time(co_lss_t *lss, const struct timespec *tp)
2073 {
2074  (void)lss;
2075  (void)tp;
2076 
2077  // All slaves should have responded by now.
2078  return co_lss_fastscan_scan_on_res(lss, 0);
2079 }
2080 
2081 static co_lss_state_t *
2083 {
2084  (void)lss;
2085 
2086  return co_lss_wait_state;
2087 }
2088 
2089 static void
2091 {
2092  assert(lss);
2093 
2094  can_timer_stop(lss->timer);
2095  can_recv_stop(lss->recv);
2096 
2097  if (lss->scan_ind)
2098  lss->scan_ind(lss, lss->cs, lss->cs ? &lss->id : NULL,
2099  lss->scan_data);
2100 }
2101 
2102 #endif // !LELY_NO_CO_MASTER
2103 
2104 static co_lss_state_t *
2105 co_lss_switch_sel(co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id)
2106 {
2107  assert(lss);
2108 
2109  co_obj_t *obj_1018 = co_dev_find_obj(lss->dev, 0x1018);
2110  struct can_msg req;
2111 
2112  switch (cs) {
2113  case 0x40:
2114  if (id != co_obj_get_val_u32(obj_1018, 0x01)) {
2115  lss->cs = 0;
2116  return NULL;
2117  }
2118  lss->cs = 0x41;
2119  return NULL;
2120  case 0x41:
2121  if (cs != lss->cs || id != co_obj_get_val_u32(obj_1018, 0x02)) {
2122  lss->cs = 0;
2123  return NULL;
2124  }
2125  lss->cs = 0x42;
2126  return NULL;
2127  case 0x42:
2128  if (cs != lss->cs || id != co_obj_get_val_u32(obj_1018, 0x03)) {
2129  lss->cs = 0;
2130  return NULL;
2131  }
2132  lss->cs = 0x43;
2133  return NULL;
2134  case 0x43:
2135  if (cs != lss->cs || id != co_obj_get_val_u32(obj_1018, 0x04)) {
2136  lss->cs = 0;
2137  return NULL;
2138  }
2139  lss->cs = 0;
2140  // Notify the master of the state switch.
2141  co_lss_init_req(lss, &req, 0x44);
2142  can_net_send(lss->net, &req);
2143  // Switch to the configuration state.
2144  trace("LSS: switching to configuration state");
2145  return co_lss_cfg_state;
2146  default: return NULL;
2147  }
2148 }
2149 
2150 static void
2151 co_lss_id_slave(co_lss_t *lss, co_unsigned8_t cs, co_unsigned32_t id)
2152 {
2153  assert(lss);
2154 
2155  co_obj_t *obj_1018 = co_dev_find_obj(lss->dev, 0x1018);
2156  struct can_msg req;
2157 
2158  switch (cs) {
2159  case 0x46:
2160  // Check the vendor-ID.
2161  if (id != co_obj_get_val_u32(obj_1018, 0x01)) {
2162  lss->cs = 0;
2163  return;
2164  }
2165  lss->cs = 0x47;
2166  break;
2167  case 0x47:
2168  // Check the product-code.
2169  if (cs != lss->cs || id != co_obj_get_val_u32(obj_1018, 0x02)) {
2170  lss->cs = 0;
2171  return;
2172  }
2173  lss->cs = 0x48;
2174  break;
2175  case 0x48:
2176  // Check the lower bound of the revision-number.
2177  if (cs != lss->cs || id > co_obj_get_val_u32(obj_1018, 0x03)) {
2178  lss->cs = 0;
2179  return;
2180  }
2181  lss->cs = 0x49;
2182  break;
2183  case 0x49:
2184  // Check the upper bound of the revision-number.
2185  if (cs != lss->cs || id < co_obj_get_val_u32(obj_1018, 0x03)) {
2186  lss->cs = 0;
2187  return;
2188  }
2189  lss->cs = 0x4a;
2190  break;
2191  case 0x4a:
2192  // Check the lower bound of the serial-number.
2193  if (cs != lss->cs || id > co_obj_get_val_u32(obj_1018, 0x04)) {
2194  lss->cs = 0;
2195  return;
2196  }
2197  lss->cs = 0x4b;
2198  break;
2199  case 0x4b:
2200  // Check the upper bound of the serial-number.
2201  if (cs != lss->cs || id < co_obj_get_val_u32(obj_1018, 0x04)) {
2202  lss->cs = 0;
2203  return;
2204  }
2205  lss->cs = 0;
2206  // Notify the master that it is a match.
2207  co_lss_init_req(lss, &req, 0x4f);
2208  can_net_send(lss->net, &req);
2209  break;
2210  }
2211 }
2212 
2213 static void
2215 {
2216  assert(lss);
2217 
2218  // Check if both the active and the pending node-ID are invalid.
2219  if (co_dev_get_id(lss->dev) != 0xff || co_nmt_get_id(lss->nmt) != 0xff)
2220  return;
2221 
2222  // Check if the device is in the NMT state Initialization.
2223  switch (co_nmt_get_st(lss->nmt)) {
2224  case CO_NMT_ST_BOOTUP:
2225  case CO_NMT_ST_RESET_NODE:
2226  case CO_NMT_ST_RESET_COMM: break;
2227  default: return;
2228  }
2229 
2230  struct can_msg req;
2231  co_lss_init_req(lss, &req, 0x50);
2232  can_net_send(lss->net, &req);
2233 }
2234 
2235 static co_lss_state_t *
2236 co_lss_fastscan(co_lss_t *lss, co_unsigned32_t id, co_unsigned8_t bitchk,
2237  co_unsigned8_t lsssub, co_unsigned8_t lssnext)
2238 {
2239  assert(lss);
2240 
2241  co_obj_t *obj_1018 = co_dev_find_obj(lss->dev, 0x1018);
2242  struct can_msg req;
2243  co_lss_state_t *next = NULL;
2244 
2245  if (__unlikely(bitchk > 31 && bitchk != 0x80))
2246  return NULL;
2247 
2248  if (bitchk == 0x80) {
2249  lss->lsspos = 0;
2250  } else {
2251  if (lss->lsspos > 3 || lss->lsspos != lsssub)
2252  return NULL;
2253  // Check if the unmasked bits of the specified IDNumber match.
2254  co_unsigned32_t pid[] = { co_obj_get_val_u32(obj_1018, 0x01),
2255  co_obj_get_val_u32(obj_1018, 0x02),
2256  co_obj_get_val_u32(obj_1018, 0x03),
2257  co_obj_get_val_u32(obj_1018, 0x04) };
2258  if ((id ^ pid[lss->lsspos]) & ~((UINT32_C(1) << bitchk) - 1))
2259  return NULL;
2260  lss->lsspos = lssnext;
2261  // If this was the final bit, switch to the configuration state.
2262  if (!bitchk && lss->lsspos < lsssub)
2263  next = co_lss_cfg_state;
2264  }
2265 
2266  // Notify the master that it is a match.
2267  co_lss_init_req(lss, &req, 0x4f);
2268  can_net_send(lss->net, &req);
2269 
2270  return next;
2271 }
2272 
2273 static void
2274 co_lss_init_req(const co_lss_t *lss, struct can_msg *msg, co_unsigned8_t cs)
2275 {
2276  assert(lss);
2277  assert(msg);
2278 
2279  *msg = (struct can_msg)CAN_MSG_INIT;
2280  msg->id = CO_LSS_CANID(co_lss_is_master(lss));
2281  msg->len = CAN_MAX_LEN;
2282  msg->data[0] = cs;
2283 }
2284 
2285 #ifndef LELY_NO_CO_MASTER
2286 
2287 static int
2288 co_lss_send_switch_sel_req(const co_lss_t *lss, const struct co_id *id)
2289 {
2290  assert(id);
2291 
2292  // Switch state selective (see Fig. 32 in CiA 305 version 3.0.0).
2293  struct can_msg req;
2294  co_lss_init_req(lss, &req, 0x40);
2295  stle_u32(req.data + 1, id->vendor_id);
2296  if (__unlikely(can_net_send(lss->net, &req) == -1))
2297  return -1;
2298  co_lss_init_req(lss, &req, 0x41);
2299  stle_u32(req.data + 1, id->product_code);
2300  if (__unlikely(can_net_send(lss->net, &req) == -1))
2301  return -1;
2302  co_lss_init_req(lss, &req, 0x42);
2303  stle_u32(req.data + 1, id->revision);
2304  if (__unlikely(can_net_send(lss->net, &req) == -1))
2305  return -1;
2306  co_lss_init_req(lss, &req, 0x43);
2307  stle_u32(req.data + 1, id->serial_nr);
2308  if (__unlikely(can_net_send(lss->net, &req) == -1))
2309  return -1;
2310 
2311  return 0;
2312 }
2313 
2314 static int
2315 co_lss_send_id_slave_req(const co_lss_t *lss, const struct co_id *lo,
2316  const struct co_id *hi)
2317 {
2318  assert(lo);
2319  assert(hi);
2320 
2321  // clang-format off
2322  if (__unlikely(lo->vendor_id != hi->vendor_id
2323  || lo->product_code != hi->product_code)
2324  || lo->revision > hi->revision
2325  || lo->serial_nr > hi->serial_nr) {
2326  // clang-format on
2328  return -1;
2329  }
2330 
2331  // LSS identify remote slave (see Fig. 42 in CiA 305 version 3.0.0).
2332  struct can_msg req;
2333  co_lss_init_req(lss, &req, 0x46);
2334  stle_u32(req.data + 1, lo->vendor_id);
2335  if (__unlikely(can_net_send(lss->net, &req) == -1))
2336  return -1;
2337  co_lss_init_req(lss, &req, 0x47);
2338  stle_u32(req.data + 1, lo->product_code);
2339  if (__unlikely(can_net_send(lss->net, &req) == -1))
2340  return -1;
2341  co_lss_init_req(lss, &req, 0x48);
2342  stle_u32(req.data + 1, lo->revision);
2343  if (__unlikely(can_net_send(lss->net, &req) == -1))
2344  return -1;
2345  co_lss_init_req(lss, &req, 0x49);
2346  stle_u32(req.data + 1, hi->revision);
2347  if (__unlikely(can_net_send(lss->net, &req) == -1))
2348  return -1;
2349  co_lss_init_req(lss, &req, 0x4a);
2350  stle_u32(req.data + 1, lo->serial_nr);
2351  if (__unlikely(can_net_send(lss->net, &req) == -1))
2352  return -1;
2353  co_lss_init_req(lss, &req, 0x4b);
2354  stle_u32(req.data + 1, hi->serial_nr);
2355  if (__unlikely(can_net_send(lss->net, &req) == -1))
2356  return -1;
2357 
2358  return 0;
2359 }
2360 
2361 static int
2362 co_lss_send_fastscan_req(const co_lss_t *lss, co_unsigned32_t id,
2363  co_unsigned8_t bitchk, co_unsigned8_t lsssub,
2364  co_unsigned8_t lssnext)
2365 {
2366  // LSS Fastscan (see Fig. 46 in CiA 305 version 3.0.0).
2367  struct can_msg req;
2368  co_lss_init_req(lss, &req, 0x51);
2369  stle_u32(req.data + 1, id);
2370  req.data[5] = bitchk;
2371  req.data[6] = lsssub;
2372  req.data[7] = lssnext;
2373  return can_net_send(lss->net, &req);
2374 }
2375 
2376 static void
2377 co_lss_init_ind(co_lss_t *lss, co_unsigned8_t cs)
2378 {
2379  assert(lss);
2380 
2381  lss->cs = cs;
2382  lss->err = 0;
2383  lss->spec = 0;
2384  lss->lssid = 0;
2385  lss->nid = 0;
2386 
2387  can_recv_start(lss->recv, lss->net, CO_LSS_CANID(0), 0);
2388  can_timer_timeout(lss->timer, lss->net, lss->timeout);
2389 }
2390 
2391 #endif // !LELY_NO_CO_MASTER
2392 
2393 #endif // !LELY_NO_CO_LSS
static co_lss_state_t *const co_lss_cs_state
The command received state.
Definition: lss.c:252
static co_lss_state_t *const co_lss_slowscan_scan_state
The Slowscan scanning state.
Definition: lss.c:353
static co_lss_state_t *const co_lss_err_state
The error received state.
Definition: lss.c:272
int co_nmt_set_id(co_nmt_t *nmt, co_unsigned8_t id)
Sets the pending node-ID.
Definition: nmt.c:1400
#define CO_NMT_ST_RESET_NODE
The NMT sub-state &#39;reset application&#39;.
Definition: nmt.h:64
co_unsigned8_t lsspos
The LSSPos value.
Definition: lss.c:67
A CAN or CAN FD format frame.
Definition: msg.h:88
void stle_u32(void *ptr, uint_least32_t x)
Stores a 32-bit unsigned integer in little-endian byte order.
Definition: endian.h:534
static co_lss_state_t *const co_lss_slowscan_wait_state
The Slowscan waiting state.
Definition: lss.c:369
static co_lss_state_t * co_lss_nid_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the inquire node-ID state.
Definition: lss.c:1725
#define CO_BAUD_20
A bit rate of 20 kbit/s.
Definition: dev.h:77
struct co_id hi
The upper bound of the LSS address used during the Slowscan service.
Definition: lss.c:72
co_unsigned8_t co_nmt_get_id(const co_nmt_t *nmt)
Returns the pending node-ID.
Definition: nmt.c:1392
static co_lss_state_t * co_lss_cfg_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the &#39;configuration&#39; state of an LSS slave...
Definition: lss.c:1426
A CANopen LSS master/slave service.
Definition: lss.c:43
static co_lss_state_t * co_lss_slowscan_switch_on_enter(co_lss_t *lss)
The entry function of the Slowscan &#39;switch state selective&#39; state.
Definition: lss.c:1884
uint_least32_t id
The identifier (11 or 29 bits, depending on the CAN_FLAG_IDE flag).
Definition: msg.h:90
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 &#39;LSS Fastscan&#39; service.
Definition: lss.c:1228
static co_lss_state_t * co_lss_fastscan_scan_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the Fastscan scanning state.
Definition: lss.c:2009
struct co_id mask
The mask used during the Fastscan service.
Definition: lss.c:74
A CAN network interface.
Definition: net.c:37
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:1301
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:1924
#define CO_BAUD_10
A bit rate of 10 kbit/s.
Definition: dev.h:80
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:101
co_unsigned8_t n
Highest sub-index supported.
Definition: dev.h:35
void co_lss_rate_ind_t(co_lss_t *lss, co_unsigned16_t rate, int delay, void *data)
The type of a CANopen LSS &#39;activate bit timing&#39; indication function, invoked when a baudrate switch i...
Definition: lss.h:51
void * lssid_data
A pointer to user-specified data for lssid_ind.
Definition: lss.c:113
static co_lss_state_t * co_lss_slowscan_init_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the Slowscan initialization state.
Definition: lss.c:1760
static co_lss_state_t *const co_lss_nid_state
The inquire node-ID state.
Definition: lss.c:312
#define CO_BAUD_500
A bit rate of 500 kbit/s.
Definition: dev.h:65
#define CO_UNSIGNED16_MAX
The maximum value of a 16-bit unsigned integer.
Definition: val.h:64
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
static int co_lss_send_switch_sel_req(const co_lss_t *lss, const struct co_id *id)
Sends a switch state selective request (see Fig.
Definition: lss.c:2288
static int co_lss_recv(const struct can_msg *msg, void *data)
The CAN receive callback function for an LSS service.
Definition: lss.c:1275
static co_lss_state_t * co_lss_slowscan_init_on_time(co_lss_t *lss, const struct timespec *tp)
The &#39;timeout&#39; transition function of the Slowscan initialization state.
Definition: lss.c:1772
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:2377
static void co_lss_nid_on_leave(co_lss_t *lss)
The exit function of the inquire node-ID state.
Definition: lss.c:1748
static void co_lss_emit_recv(co_lss_t *lss, const struct can_msg *msg)
Invokes the &#39;CAN frame received&#39; transition function of the current state of an LSS service...
Definition: lss.c:1317
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 &#39;inquire node-ID&#39; requ...
Definition: lss.h:121
static void co_lss_slowscan_fini_on_leave(co_lss_t *lss)
The exit function of the Slowscan finalization state.
Definition: lss.c:1932
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 &#39;LSS identify remote slave&#39; service.
Definition: lss.c:1144
#define CAN_MSG_INIT
The static initializer for can_msg.
Definition: msg.h:114
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:375
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:172
void * store_data
A pointer to user-specified data for store_ind.
Definition: lss.c:100
#define LELY_CO_LSS_TIMEOUT
The default LSS timeout (in milliseconds).
Definition: lss.h:30
int co_lss_switch_req(co_lss_t *lss, co_unsigned8_t mode)
Requests the &#39;switch state global&#39; service.
Definition: lss.c:847
static co_lss_state_t * co_lss_slowscan_switch_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the Slowscan &#39;switch state selective&#39; state...
Definition: lss.c:1901
void * nid_data
A pointer to user-specified data for nid_ind.
Definition: lss.c:117
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:1783
int co_lss_store_req(co_lss_t *lss, co_lss_err_ind_t *ind, void *data)
Requests the &#39;store configuration&#39; service.
Definition: lss.c:992
static co_lss_state_t *const co_lss_slowscan_fini_state
The Slowscan finalization state.
Definition: lss.c:409
uint_least16_t ldle_u16(const void *ptr)
Loads a 16-bit unsigned integer in little-endian byte order.
Definition: endian.h:487
static co_lss_state_t * co_lss_slowscan_wait_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the Slowscan waiting state.
Definition: lss.c:1864
A CANopen LSS state.
Definition: lss.c:160
co_lss_t * co_lss_create(co_nmt_t *nmt)
Creates a new CANopen LSS master/slave service.
Definition: lss.c:706
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 &#39;Slowscan&#39; or &#39;Fa...
Definition: lss.h:135
static void co_lss_err_on_leave(co_lss_t *lss)
The exit function of the error received state.
Definition: lss.c:1678
co_unsigned8_t co_dev_get_id(const co_dev_t *dev)
Returns the node-ID of a CANopen device.
Definition: dev.c:198
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:2236
#define CO_UNSIGNED16_MIN
The minimum value of a 16-bit unsigned integer.
Definition: val.h:61
#define CO_BAUD_50
A bit rate of 50 kbit/s.
Definition: dev.h:74
This header file is part of the CANopen library; it contains the CANopen value declarations.
co_unsigned32_t lssid
The received LSS number.
Definition: lss.c:87
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:957
int co_lss_get_id_req(co_lss_t *lss, co_lss_nid_ind_t *ind, void *data)
Requests the &#39;inquire node-ID&#39; service.
Definition: lss.c:1119
int co_lss_get_timeout(const co_lss_t *lss)
Returns the timeout (in milliseconds) of an LSS master service.
Definition: lss.c:794
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
can_recv_t * can_recv_create(void)
Creates a new CAN frame receiver.
Definition: net.c:537
int co_lss_set_id_req(co_lss_t *lss, co_unsigned8_t id, co_lss_err_ind_t *ind, void *data)
Requests the &#39;configure node-ID&#39; service.
Definition: lss.c:893
static co_lss_state_t * co_lss_fastscan_scan_on_time(co_lss_t *lss, const struct timespec *tp)
The &#39;timeout&#39; transition function of the Fastscan scanning state.
Definition: lss.c:2022
static co_lss_state_t * co_lss_cs_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the command received state.
Definition: lss.c:1620
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 &#39;switch state selective&#39; service.
Definition: lss.c:869
static co_lss_state_t *const co_lss_lssid_state
The inquire identity state.
Definition: lss.c:292
static co_lss_state_t * co_lss_slowscan_scan_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the Slowscan scanning state.
Definition: lss.c:1811
void co_lss_set_timeout(co_lss_t *lss, int timeout)
Sets the timeout of an LSS master service.
Definition: lss.c:802
uint_least8_t data[CAN_MSG_MAX_LEN]
The frame payload (in case of a data frame).
Definition: msg.h:103
co_unsigned32_t product_code
Product code.
Definition: dev.h:39
static co_lss_state_t * co_lss_slowscan_switch_on_time(co_lss_t *lss, const struct timespec *tp)
The &#39;timeout&#39; transition function of the Slowscan &#39;switch state selective&#39; state. ...
Definition: lss.c:1913
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:2082
This header file is part of the utilities library; it contains the native and platform-independent er...
co_unsigned32_t vendor_id
Vendor-ID.
Definition: dev.h:37
int co_lss_get_product_code_req(co_lss_t *lss, co_lss_lssid_ind_t *ind, void *data)
Requests the &#39;inquire identity product-code&#39; service.
Definition: lss.c:1042
int co_lss_get_revision_req(co_lss_t *lss, co_lss_lssid_ind_t *ind, void *data)
Requests the &#39;inquire identity revision-number&#39; service.
Definition: lss.c:1067
void can_timer_stop(can_timer_t *timer)
Stops a CAN timer and unregisters it with a network interface.
Definition: net.c:468
void(* on_leave)(co_lss_t *lss)
A pointer to the function invoked when the current state is left.
Definition: lss.c:185
static co_lss_state_t * co_lss_lssid_on_time(co_lss_t *lss, const struct timespec *tp)
The &#39;timeout&#39; transition function of the inquire identity state.
Definition: lss.c:1703
void co_lss_abort_req(co_lss_t *lss)
Aborts the current LSS master request.
Definition: lss.c:839
static void co_lss_lssid_on_leave(co_lss_t *lss)
The exit function of the inquire identity state.
Definition: lss.c:1713
#define CO_BAUD_125
A bit rate of 125 kbit/s.
Definition: dev.h:71
void can_recv_destroy(can_recv_t *recv)
Destroys a CAN frame receiver.
Definition: net.c:562
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:815
This header file is part of the utilities library; it contains the byte order (endianness) function d...
int timeout
The timeout (in milliseconds).
Definition: lss.c:60
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 &#39;activate bit timing&#39; request is received...
Definition: lss.c:762
co_unsigned8_t lsssub
The index of the current LSS number being checked during the Fastscan service.
Definition: lss.c:81
This is the internal header file of the CANopen library.
static co_lss_state_t * co_lss_fastscan_init_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the Fastscan initialization state.
Definition: lss.c:1945
co_unsigned8_t bitchk
The least-significant bit being checked during the Fastscan service.
Definition: lss.c:76
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:182
#define CO_ID_INIT
The static initializer for struct co_id.
Definition: dev.h:47
can_recv_t * recv
A pointer to the CAN frame receiver.
Definition: lss.c:57
#define CO_NMT_ST_BOOTUP
The NMT state &#39;boot-up&#39;.
Definition: nmt.h:55
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function...
Definition: errnum.c:947
A CAN timer.
Definition: net.c:63
co_lss_cs_ind_t * cs_ind
A pointer to the command indication function.
Definition: lss.c:103
#define MAX(a, b)
Returns the maximum of a and b.
Definition: util.h:65
void * err_data
A pointer to user-specified data for err_ind.
Definition: lss.c:109
static co_lss_state_t * co_lss_fastscan_init_on_time(co_lss_t *lss, const struct timespec *tp)
The &#39;timeout&#39; transition function of the Fastscan initialization state.
Definition: lss.c:1958
void can_timer_destroy(can_timer_t *timer)
Destroys a CAN timer.
Definition: net.c:407
co_lss_rate_ind_t * rate_ind
A pointer to the &#39;activate bit timing&#39; indication function.
Definition: lss.c:94
A CANopen NMT master/slave service.
Definition: nmt.c:104
can_net_t * net
A pointer to a CAN network interface.
Definition: lss.c:47
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 &#39;store configuration&#39; indication function, invoked when the pending node-ID...
Definition: lss.h:67
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:831
co_unsigned8_t cs
The expected command specifier.
Definition: lss.c:65
#define CO_NUM_NODES
The maximum number of nodes in a CANopen network.
Definition: dev.h:56
#define CO_NMT_ST_RESET_COMM
The NMT sub-state &#39;reset communication&#39;.
Definition: nmt.h:67
void co_dev_set_rate(co_dev_t *dev, co_unsigned16_t rate)
Sets the (pending) baudrate of a CANopen device.
Definition: dev.c:489
Invalid argument.
Definition: errnum.h:129
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 &#39;store configuration&#39; request is received...
Definition: lss.c:771
void stle_u16(void *ptr, uint_least16_t x)
Stores a 16-bit unsigned integer in little-endian byte order.
Definition: endian.h:480
static int co_lss_send_id_slave_req(const co_lss_t *lss, const struct co_id *lo, const struct co_id *hi)
Sends an LSS identify remote slave request (see Fig.
Definition: lss.c:2315
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:2105
co_lss_state_t * state
A pointer to the current state.
Definition: lss.c:51
#define CO_BAUD_250
A bit rate of 250 kbit/s.
Definition: dev.h:68
co_lss_scan_ind_t * scan_ind
A pointer to the identify remote slave indication function.
Definition: lss.c:119
static co_lss_state_t * co_lss_fastscan_wait_on_time(co_lss_t *lss, const struct timespec *tp)
The &#39;timeout&#39; transition function of the Fastscan waiting state.
Definition: lss.c:2072
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:743
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 &#39;inquire identity ven...
Definition: lss.h:109
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
Definition: errnum.c:43
static co_lss_state_t * co_lss_cs_on_time(co_lss_t *lss, const struct timespec *tp)
The &#39;timeout&#39; transition function of the command received state.
Definition: lss.c:1632
#define __unlikely(x)
Indicates to the compiler that the expression is most-likely false.
Definition: features.h:286
void co_lss_destroy(co_lss_t *lss)
Destroys a CANopen LSS master/slave service.
Definition: lss.c:733
static co_lss_state_t * co_lss_err_on_time(co_lss_t *lss, const struct timespec *tp)
The &#39;timeout&#39; transition function of the error received state.
Definition: lss.c:1668
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:162
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:1036
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, CO_BAUD_800, CO_BAUD_500, CO_BAUD_250, CO_BAUD_125, CO_BAUD_50, CO_BAUD_20, CO_BAUD_10 and CO_BAUD_AUTO).
Definition: dev.c:465
static co_lss_state_t * co_lss_wait_on_enter(co_lss_t *lss)
The entry function of the &#39;waiting&#39; state an LSS master or slave.
Definition: lss.c:1339
co_unsigned32_t revision
Revision number.
Definition: dev.h:41
static void co_lss_fastscan_fini_on_leave(co_lss_t *lss)
The exit function of the Fastscan finalization state.
Definition: lss.c:2090
static co_lss_state_t *const co_lss_slowscan_init_state
The Slowscan initialization state.
Definition: lss.c:331
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 &#39;configure node-ID&#39;...
Definition: lss.h:94
A CANopen device.
Definition: dev.c:38
static co_lss_state_t * co_lss_err_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the error received state.
Definition: lss.c:1654
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 &#39;store configuration&#39; request is received...
Definition: lss.c:783
#define CO_BAUD_AUTO
Automatic bit rate detection.
Definition: dev.h:83
void * rate_data
A pointer to user-specified data for rate_ind.
Definition: lss.c:96
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:2214
can_timer_t * timer
A pointer to the CAN timer.
Definition: lss.c:62
int co_lss_get_vendor_id_req(co_lss_t *lss, co_lss_lssid_ind_t *ind, void *data)
Requests the &#39;inquire identity vendor-ID&#39; service.
Definition: lss.c:1017
static co_lss_state_t * co_lss_nid_on_time(co_lss_t *lss, const struct timespec *tp)
The &#39;timeout&#39; transition function of the inquire node-ID state.
Definition: lss.c:1738
static co_lss_state_t * co_lss_slowscan_scan_on_time(co_lss_t *lss, const struct timespec *tp)
The &#39;timeout&#39; transition function of the Slowscan scanning state.
Definition: lss.c:1824
static int co_lss_timer(const struct timespec *tp, void *data)
The CAN timer callback function for an LSS service.
Definition: lss.c:1288
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:2274
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_err_ind_t * err_ind
A pointer to the error indication function.
Definition: lss.c:107
co_dev_t * dev
A pointer to a CANopen device.
Definition: lss.c:49
static co_lss_state_t *const co_lss_wait_state
The &#39;waiting&#39; state of an LSS master or slave.
Definition: lss.c:198
can_timer_t * can_timer_create(void)
Creates a new CAN timer.
Definition: net.c:382
struct co_id id
The LSS address obtained from the LSS Slowscan or Fastscan service.
Definition: lss.c:91
co_unsigned32_t serial_nr
Serial number.
Definition: dev.h:43
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_lss_store_ind_t * store_ind
A pointer to the &#39;store configuration&#39; indication function.
Definition: lss.c:98
static co_lss_state_t * co_lss_lssid_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the inquire identity state.
Definition: lss.c:1690
co_nmt_t * nmt
A pointer to an NMT master/slave service.
Definition: lss.c:45
void * cs_data
A pointer to user-specified data for cs_ind.
Definition: lss.c:105
static void co_lss_emit_time(co_lss_t *lss, const struct timespec *tp)
Invokes the &#39;timeout&#39; transition function of the current state of an LSS service. ...
Definition: lss.c:1328
This header file is part of the CANopen library; it contains the Layer Setting Services (LSS) and pro...
co_unsigned8_t spec
The received implementation-specific error code.
Definition: lss.c:85
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
static co_lss_state_t *const co_lss_fastscan_wait_state
The Fastscan waiting state.
Definition: lss.c:466
int co_lss_switch_rate_req(co_lss_t *lss, int delay)
Requests the &#39;activate bit timing parameters&#39; service.
Definition: lss.c:966
int co_lss_id_non_cfg_slave_req(co_lss_t *lss, co_lss_cs_ind_t *ind, void *data)
Requests the &#39;LSS identify non-configured remote slave&#39; service.
Definition: lss.c:1168
static co_lss_state_t *const co_lss_fastscan_init_state
The Fastscan initialization state.
Definition: lss.c:428
static co_lss_state_t * co_lss_wait_slave_on_enter(co_lss_t *lss)
The entry function of the &#39;waiting&#39; state of an LSS slave.
Definition: lss.c:1354
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 &#39;switch state selectiv...
Definition: lss.h:80
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:481
#define CO_LSS_CANID(master)
The CAN identifier used for LSS by the master (1) or the slave (0).
Definition: lss.h:34
static co_lss_state_t *const co_lss_wait_slave_state
The &#39;waiting&#39; state of an LSS slave.
Definition: lss.c:216
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:2151
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:1969
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:1423
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, CO_NMT_ST_START, CO_NMT_ST_RESET_NODE, CO_NMT_ST_RESET_COMM or CO_NMT_ST_PREOP).
Definition: nmt.c:1415
This header file is part of the CANopen library; it contains the network management (NMT) declaration...
#define CO_BAUD_800
A bit rate of 800 kbit/s.
Definition: dev.h:62
int co_lss_get_serial_nr_req(co_lss_t *lss, co_lss_lssid_ind_t *ind, void *data)
Requests the &#39;inquire identity serial-number&#39; service.
Definition: lss.c:1093
static co_lss_state_t *const co_lss_fastscan_fini_state
The Fastscan finalization state.
Definition: lss.c:480
Operation not permitted.
Definition: errnum.h:205
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
#define CO_BAUD_1000
A bit rate of 1 Mbit/s.
Definition: dev.h:59
static co_lss_state_t *const co_lss_cfg_state
The &#39;configuration&#39; state of an LSS slave.
Definition: lss.c:230
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
A CAN frame receiver.
Definition: net.c:99
void * scan_data
A pointer to user-specified data for scan_ind.
Definition: lss.c:121
static co_lss_state_t * co_lss_slowscan_wait_on_time(co_lss_t *lss, const struct timespec *tp)
The &#39;timeout&#39; transition function of the Slowscan waiting state.
Definition: lss.c:1874
#define CAN_MAX_LEN
The maximum number of bytes in the payload of a CAN format frame.
Definition: msg.h:73
static co_lss_state_t * co_lss_fastscan_wait_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the Fastscan waiting state.
Definition: lss.c:2062
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:1044
static co_lss_state_t *const co_lss_slowscan_switch_state
The Slowscan &#39;switch state selective&#39; state.
Definition: lss.c:395
int master
A flag specifying whether the LSS service is a master or a slave.
Definition: lss.c:54
co_unsigned8_t err
The received error code.
Definition: lss.c:83
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:2362
static co_lss_state_t * co_lss_wait_slave_on_recv(co_lss_t *lss, const struct can_msg *msg)
The &#39;CAN frame received&#39; transition function of the &#39;waiting&#39; state of an LSS slave.
Definition: lss.c:1368
struct co_id lo
The lower bound of the LSS address used during the Slowscan service.
Definition: lss.c:70
A CANopen object.
Definition: obj.h:32
This header file is part of the CANopen library; it contains the object dictionary declarations...
int co_lss_set_rate_req(co_lss_t *lss, co_unsigned16_t rate, co_lss_err_ind_t *ind, void *data)
Requests the &#39;configure bit timing parameters&#39; service.
Definition: lss.c:925
static co_lss_state_t *const co_lss_fastscan_scan_state
The Fastscan scanning state.
Definition: lss.c:450
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
An identity record.
Definition: dev.h:33
static void co_lss_cs_on_leave(co_lss_t *lss)
The exit function of the command received state.
Definition: lss.c:1642
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 &#39;activate bit timing&#39; request is received...
Definition: lss.c:751
uint_least32_t ldle_u32(const void *ptr)
Loads a 32-bit unsigned integer in little-endian byte order.
Definition: endian.h:541
co_unsigned8_t nid
The received node-ID.
Definition: lss.c:89
co_lss_nid_ind_t * nid_ind
A pointer to the inquire node-ID indication function.
Definition: lss.c:115
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 &#39;LSS Slowscan&#39; service.
Definition: lss.c:1194
co_lss_lssid_ind_t * lssid_ind
A pointer to the inquire identity indication function.
Definition: lss.c:111