IgH EtherCAT Master  1.6.13
fsm_coe.c
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
4  *
5  * This file is part of the IgH EtherCAT Master.
6  *
7  * The IgH EtherCAT Master is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License version 2, as
9  * published by the Free Software Foundation.
10  *
11  * The IgH EtherCAT Master is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14  * Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with the IgH EtherCAT Master; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  *
20  ****************************************************************************/
21 
26 /****************************************************************************/
27 
28 #include "globals.h"
29 #include "master.h"
30 #include "mailbox.h"
31 #include "fsm_coe.h"
32 #include "slave_config.h"
33 
34 /****************************************************************************/
35 
38 #define EC_FSM_COE_DICT_TIMEOUT 1000
39 
42 #define EC_COE_DOWN_REQ_HEADER_SIZE 10
43 
46 #define EC_COE_DOWN_SEG_REQ_HEADER_SIZE 3
47 
50 #define EC_COE_DOWN_SEG_MIN_DATA_SIZE 7
51 
54 #define DEBUG_RETRIES 0
55 
58 #define DEBUG_LONG 0
59 
60 /****************************************************************************/
61 
62 // prototypes for private methods
63 void ec_canopen_abort_msg(const ec_slave_t *, uint32_t);
64 int ec_fsm_coe_check_emergency(const ec_fsm_coe_t *, const uint8_t *, size_t);
72 
73 /****************************************************************************/
74 
85 
92 
100 
103 
104 /****************************************************************************/
105 
113  {0x05030000, "Toggle bit not changed"},
114  {0x05040000, "SDO protocol timeout"},
115  {0x05040001, "Client/Server command specifier not valid or unknown"},
116  {0x05040005, "Out of memory"},
117  {0x06010000, "Unsupported access to an object"},
118  {0x06010001, "Attempt to read a write-only object"},
119  {0x06010002, "Attempt to write a read-only object"},
120  {0x06020000, "This object does not exist in the object directory"},
121  {0x06040041, "The object cannot be mapped into the PDO"},
122  {0x06040042, "The number and length of the objects to be mapped would"
123  " exceed the PDO length"},
124  {0x06040043, "General parameter incompatibility reason"},
125  {0x06040047, "Gerneral internal incompatibility in device"},
126  {0x06060000, "Access failure due to a hardware error"},
127  {0x06070010, "Data type does not match, length of service parameter does"
128  " not match"},
129  {0x06070012, "Data type does not match, length of service parameter too"
130  " high"},
131  {0x06070013, "Data type does not match, length of service parameter too"
132  " low"},
133  {0x06090011, "Subindex does not exist"},
134  {0x06090030, "Value range of parameter exceeded"},
135  {0x06090031, "Value of parameter written too high"},
136  {0x06090032, "Value of parameter written too low"},
137  {0x06090036, "Maximum value is less than minimum value"},
138  {0x08000000, "General error"},
139  {0x08000020, "Data cannot be transferred or stored to the application"},
140  {0x08000021, "Data cannot be transferred or stored to the application"
141  " because of local control"},
142  {0x08000022, "Data cannot be transferred or stored to the application"
143  " because of the present device state"},
144  {0x08000023, "Object dictionary dynamic generation fails or no object"
145  " dictionary is present"},
146  {}
147 };
148 
149 /****************************************************************************/
150 
154  const ec_slave_t *slave,
155  uint32_t abort_code
156  )
157 {
158  const ec_code_msg_t *abort_msg;
159 
160  for (abort_msg = sdo_abort_messages; abort_msg->code; abort_msg++) {
161  if (abort_msg->code == abort_code) {
162  EC_SLAVE_ERR(slave, "SDO abort message 0x%08X: \"%s\".\n",
163  abort_msg->code, abort_msg->message);
164  return;
165  }
166  }
167 
168  EC_SLAVE_ERR(slave, "Unknown SDO abort code 0x%08X.\n", abort_code);
169 }
170 
171 /****************************************************************************/
172 
176  ec_fsm_coe_t *fsm
177  )
178 {
179  fsm->state = NULL;
180  fsm->datagram = NULL;
181 }
182 
183 /****************************************************************************/
184 
188  ec_fsm_coe_t *fsm
189  )
190 {
191 }
192 
193 /****************************************************************************/
194 
198  ec_fsm_coe_t *fsm,
199  ec_slave_t *slave
200  )
201 {
202  fsm->slave = slave;
204 }
205 
206 /****************************************************************************/
207 
211  ec_fsm_coe_t *fsm,
212  ec_slave_t *slave,
213  ec_sdo_request_t *request
214  )
215 {
216  fsm->slave = slave;
217  fsm->request = request;
218 
219  if (request->dir == EC_DIR_OUTPUT) {
221  }
222  else {
223  fsm->state = ec_fsm_coe_up_start;
224  }
225 }
226 
227 /****************************************************************************/
228 
234  ec_fsm_coe_t *fsm,
235  ec_datagram_t *datagram
236  )
237 {
238  int datagram_used = 0;
239 
240  if (fsm->datagram &&
241  (fsm->datagram->state == EC_DATAGRAM_INIT ||
242  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
243  fsm->datagram->state == EC_DATAGRAM_SENT)) {
244  // datagram not received yet
245  return datagram_used;
246  }
247 
248  fsm->state(fsm, datagram);
249 
250  datagram_used =
251  fsm->state != ec_fsm_coe_end && fsm->state != ec_fsm_coe_error;
252 
253  if (datagram_used) {
254  fsm->datagram = datagram;
255  } else {
256  fsm->datagram = NULL;
257  }
258 
259  return datagram_used;
260 }
261 
262 /****************************************************************************/
263 
268  const ec_fsm_coe_t *fsm
269  )
270 {
271  return fsm->state == ec_fsm_coe_end;
272 }
273 
274 /****************************************************************************/
275 
283  const ec_fsm_coe_t *fsm,
284  const uint8_t *data,
285  size_t size
286  )
287 {
288  if (size < 2 || ((EC_READ_U16(data) >> 12) & 0x0F) != 0x01)
289  return 0;
290 
291  if (size < 10) {
292  EC_SLAVE_WARN(fsm->slave, "Received incomplete CoE Emergency"
293  " request:\n");
294  ec_print_data(data, size);
295  return 1;
296  }
297 
298  {
299  ec_slave_config_t *sc = fsm->slave->config;
300  if (sc) {
301  ec_coe_emerg_ring_push(&sc->emerg_ring, data + 2);
302  }
303  }
304 
305  EC_SLAVE_WARN(fsm->slave, "CoE Emergency Request received:\n"
306  "Error code 0x%04X, Error register 0x%02X, data:\n",
307  EC_READ_U16(data + 2), EC_READ_U8(data + 4));
308  ec_print_data(data + 5, 5);
309  return 1;
310 }
311 
312 /*****************************************************************************
313  * CoE dictionary state machine
314  ****************************************************************************/
315 
321  ec_fsm_coe_t *fsm,
322  ec_datagram_t *datagram
323  )
324 {
325  ec_slave_t *slave = fsm->slave;
326  uint8_t *data = ec_slave_mbox_prepare_send(slave, datagram,
327  EC_MBOX_TYPE_COE, 8);
328  if (IS_ERR(data)) {
329  return PTR_ERR(data);
330  }
331 
332  EC_WRITE_U16(data, 0x8 << 12); // SDO information
333  EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
334  EC_WRITE_U8 (data + 3, 0x00);
335  EC_WRITE_U16(data + 4, 0x0000);
336  EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
337 
339  return 0;
340 }
341 
342 /****************************************************************************/
343 
347  ec_fsm_coe_t *fsm,
348  ec_datagram_t *datagram
349  )
350 {
351  ec_slave_t *slave = fsm->slave;
352 
353  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
354  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
355  fsm->state = ec_fsm_coe_error;
356  return;
357  }
358 
359  if (slave->sii.has_general && !slave->sii.coe_details.enable_sdo_info) {
360  EC_SLAVE_ERR(slave, "Slave does not support"
361  " SDO information service!\n");
362  fsm->state = ec_fsm_coe_error;
363  return;
364  }
365 
366  fsm->retries = EC_FSM_RETRIES;
367 
368  if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
369  fsm->state = ec_fsm_coe_error;
370  }
371 }
372 
373 /****************************************************************************/
374 
379  ec_fsm_coe_t *fsm,
380  ec_datagram_t *datagram
381  )
382 {
383  ec_slave_t *slave = fsm->slave;
384 
385  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
386  if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
387  fsm->state = ec_fsm_coe_error;
388  }
389  return;
390  }
391 
392  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
393  fsm->state = ec_fsm_coe_error;
394  EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
395  " request datagram: ");
397  return;
398  }
399 
400  if (fsm->datagram->working_counter != 1) {
401  fsm->state = ec_fsm_coe_error;
402  EC_SLAVE_ERR(slave, "Reception of CoE dictionary request failed: ");
404  return;
405  }
406 
407  fsm->jiffies_start = fsm->datagram->jiffies_sent;
408 
409  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
410  fsm->retries = EC_FSM_RETRIES;
412 }
413 
414 /****************************************************************************/
415 
419  ec_fsm_coe_t *fsm,
420  ec_datagram_t *datagram
421  )
422 {
423  ec_slave_t *slave = fsm->slave;
424 
425  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
426  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
427  return;
428  }
429 
430  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
431  fsm->state = ec_fsm_coe_error;
432  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
434  return;
435  }
436 
437  if (fsm->datagram->working_counter != 1) {
438  fsm->state = ec_fsm_coe_error;
439  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
440  " datagram failed: ");
442  return;
443  }
444 
445  if (!ec_slave_mbox_check(fsm->datagram)) {
446  unsigned long diff_ms =
447  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
448  1000 / HZ;
449  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
450  fsm->state = ec_fsm_coe_error;
451  EC_SLAVE_ERR(slave, "Timeout while waiting for"
452  " SDO dictionary list response.\n");
453  return;
454  }
455 
456  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
457  fsm->retries = EC_FSM_RETRIES;
458  return;
459  }
460 
461  // Fetch response
462  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
463  fsm->retries = EC_FSM_RETRIES;
465 }
466 
467 /****************************************************************************/
468 
474  ec_fsm_coe_t *fsm,
475  ec_datagram_t *datagram
476  )
477 {
478  ec_slave_t *slave = fsm->slave;
479  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
480  8);
481  if (IS_ERR(data)) {
482  return PTR_ERR(data);
483  }
484 
485  EC_WRITE_U16(data, 0x8 << 12); // SDO information
486  EC_WRITE_U8 (data + 2, 0x03); // Get object description request
487  EC_WRITE_U8 (data + 3, 0x00);
488  EC_WRITE_U16(data + 4, 0x0000);
489  EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
490 
492  return 0;
493 }
494 
495 /****************************************************************************/
496 
503  ec_fsm_coe_t *fsm,
504  ec_datagram_t *datagram
505  )
506 {
507  ec_slave_t *slave = fsm->slave;
508  uint8_t *data, mbox_prot;
509  size_t rec_size;
510  unsigned int sdo_count, i;
511  uint16_t sdo_index, fragments_left;
512  ec_sdo_t *sdo;
513  bool first_segment;
514  size_t index_list_offset;
515 
516  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
517  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
518  return;
519  }
520 
521  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
522  fsm->state = ec_fsm_coe_error;
523  EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
524  " response datagram: ");
526  return;
527  }
528 
529  if (fsm->datagram->working_counter != 1) {
530  fsm->state = ec_fsm_coe_error;
531  EC_SLAVE_ERR(slave, "Reception of CoE dictionary response failed: ");
533  return;
534  }
535 
536  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
537  if (IS_ERR(data)) {
538  fsm->state = ec_fsm_coe_error;
539  return;
540  }
541 
542 #ifndef EC_EOE
543  if (mbox_prot == EC_MBOX_TYPE_EOE) {
544  // discard EoE message and wait for the next reponse
545  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
546  fsm->retries = EC_FSM_RETRIES;
548  return;
549  }
550 #endif
551 
552  if (mbox_prot != EC_MBOX_TYPE_COE) {
553  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
554  mbox_prot);
555  fsm->state = ec_fsm_coe_error;
556  return;
557  }
558 
559  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
560  // check for CoE response again
561  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
562  fsm->retries = EC_FSM_RETRIES;
564  return;
565  }
566 
567  if (rec_size < 3) {
568  EC_SLAVE_ERR(slave, "Received corrupted SDO dictionary response"
569  " (size %zu).\n", rec_size);
570  fsm->state = ec_fsm_coe_error;
571  return;
572  }
573 
574  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
575  (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
576  EC_SLAVE_ERR(slave, "SDO information error response!\n");
577  if (rec_size < 10) {
578  EC_SLAVE_ERR(slave, "Incomplete SDO information"
579  " error response:\n");
580  ec_print_data(data, rec_size);
581  } else {
582  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
583  }
584  fsm->state = ec_fsm_coe_error;
585  return;
586  }
587 
588  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
589  (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
590  if (fsm->slave->master->debug_level) {
591  EC_SLAVE_DBG(slave, 1, "Invalid SDO list response!"
592  " Retrying...\n");
593  ec_print_data(data, rec_size);
594  }
595  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
596  fsm->retries = EC_FSM_RETRIES;
598  return;
599  }
600 
601  first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
602  index_list_offset = first_segment ? 8 : 6;
603 
604  if (rec_size < index_list_offset || rec_size % 2) {
605  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
606  ec_print_data(data, rec_size);
607  fsm->state = ec_fsm_coe_error;
608  return;
609  }
610 
611  sdo_count = (rec_size - index_list_offset) / 2;
612 
613  for (i = 0; i < sdo_count; i++) {
614  sdo_index = EC_READ_U16(data + index_list_offset + i * 2);
615  if (!sdo_index) {
616  EC_SLAVE_DBG(slave, 1, "SDO dictionary contains index 0x0000.\n");
617  continue;
618  }
619 
620  if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
621  EC_SLAVE_ERR(slave, "Failed to allocate memory for SDO!\n");
622  fsm->state = ec_fsm_coe_error;
623  return;
624  }
625 
626  ec_sdo_init(sdo, slave, sdo_index);
627  list_add_tail(&sdo->list, &slave->sdo_dictionary);
628  }
629 
630  fragments_left = EC_READ_U16(data + 4);
631  if (fragments_left) {
632  EC_SLAVE_DBG(slave, 1, "SDO list fragments left: %u\n",
633  fragments_left);
634  }
635 
636  if (EC_READ_U8(data + 2) & 0x80 || fragments_left) {
637  // more messages waiting. check again.
638  fsm->jiffies_start = fsm->datagram->jiffies_sent;
639  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
640  fsm->retries = EC_FSM_RETRIES;
642  return;
643  }
644 
645  if (list_empty(&slave->sdo_dictionary)) {
646  // no SDOs in dictionary. finished.
647  fsm->state = ec_fsm_coe_end; // success
648  return;
649  }
650 
651  // fetch SDO descriptions
652  fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);
653 
654  fsm->retries = EC_FSM_RETRIES;
655  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
656  fsm->state = ec_fsm_coe_error;
657  }
658 }
659 
660 /****************************************************************************/
661 
668  ec_fsm_coe_t *fsm,
669  ec_datagram_t *datagram
670  )
671 {
672  ec_slave_t *slave = fsm->slave;
673 
674  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
675  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
676  fsm->state = ec_fsm_coe_error;
677  }
678  return;
679  }
680 
681  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
682  fsm->state = ec_fsm_coe_error;
683  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
684  " description request datagram: ");
686  return;
687  }
688 
689  if (fsm->datagram->working_counter != 1) {
690  fsm->state = ec_fsm_coe_error;
691  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
692  " request failed: ");
694  return;
695  }
696 
697  fsm->jiffies_start = fsm->datagram->jiffies_sent;
698 
699  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
700  fsm->retries = EC_FSM_RETRIES;
702 }
703 
704 /****************************************************************************/
705 
711  ec_fsm_coe_t *fsm,
712  ec_datagram_t *datagram
713  )
714 {
715  ec_slave_t *slave = fsm->slave;
716 
717  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
718  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
719  return;
720  }
721 
722  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
723  fsm->state = ec_fsm_coe_error;
724  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
726  return;
727  }
728 
729  if (fsm->datagram->working_counter != 1) {
730  fsm->state = ec_fsm_coe_error;
731  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
732  " datagram failed: ");
734  return;
735  }
736 
737  if (!ec_slave_mbox_check(fsm->datagram)) {
738  unsigned long diff_ms =
739  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
740  1000 / HZ;
741  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
742  fsm->state = ec_fsm_coe_error;
743  EC_SLAVE_ERR(slave, "Timeout while waiting for"
744  " SDO 0x%04x object description response.\n",
745  fsm->sdo->index);
746  return;
747  }
748 
749  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
750  fsm->retries = EC_FSM_RETRIES;
751  return;
752  }
753 
754  // Fetch response
755  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
756  fsm->retries = EC_FSM_RETRIES;
758 }
759 
760 /****************************************************************************/
761 
767  ec_fsm_coe_t *fsm,
768  ec_datagram_t *datagram
769  )
770 {
771  ec_slave_t *slave = fsm->slave;
772  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
773  10);
774  if (IS_ERR(data)) {
775  return PTR_ERR(data);
776  }
777 
778  EC_WRITE_U16(data, 0x8 << 12); // SDO information
779  EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
780  EC_WRITE_U8 (data + 3, 0x00);
781  EC_WRITE_U16(data + 4, 0x0000);
782  EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
783  EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
784  EC_WRITE_U8 (data + 9, 0x01); // value info (access rights only)
785 
787  return 0;
788 }
789 
790 /****************************************************************************/
791 
798  ec_fsm_coe_t *fsm,
799  ec_datagram_t *datagram
800  )
801 {
802  ec_slave_t *slave = fsm->slave;
803  ec_sdo_t *sdo = fsm->sdo;
804  uint8_t *data, mbox_prot;
805  size_t rec_size, name_size;
806 
807  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
808  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
809  return;
810  }
811 
812  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
813  fsm->state = ec_fsm_coe_error;
814  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description"
815  " response datagram: ");
817  return;
818  }
819 
820  if (fsm->datagram->working_counter != 1) {
821  fsm->state = ec_fsm_coe_error;
822  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
823  " response failed: ");
825  return;
826  }
827 
828  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
829  if (IS_ERR(data)) {
830  fsm->state = ec_fsm_coe_error;
831  return;
832  }
833 
834 #ifndef EC_EOE
835  if (mbox_prot == EC_MBOX_TYPE_EOE) {
836  // discard EoE message and wait for the next reponse
837  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
838  fsm->retries = EC_FSM_RETRIES;
840  return;
841  }
842 #endif
843 
844  if (mbox_prot != EC_MBOX_TYPE_COE) {
845  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
846  mbox_prot);
847  fsm->state = ec_fsm_coe_error;
848  return;
849  }
850 
851  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
852  // check for CoE response again
853  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
854  fsm->retries = EC_FSM_RETRIES;
856  return;
857  }
858 
859  if (rec_size < 3) {
860  EC_SLAVE_ERR(slave, "Received corrupted SDO description response"
861  " (size %zu).\n", rec_size);
862  fsm->state = ec_fsm_coe_error;
863  return;
864  }
865 
866  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
867  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
868  EC_SLAVE_ERR(slave, "SDO information error response while"
869  " fetching SDO 0x%04X!\n", sdo->index);
870  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
871  fsm->state = ec_fsm_coe_error;
872  return;
873  }
874 
875  if (rec_size < 8) {
876  EC_SLAVE_ERR(slave, "Received corrupted SDO"
877  " description response (size %zu).\n", rec_size);
878  fsm->state = ec_fsm_coe_error;
879  return;
880  }
881 
882  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
883  (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response
884  EC_READ_U16(data + 6) != sdo->index) { // SDO index
885  if (fsm->slave->master->debug_level) {
886  EC_SLAVE_DBG(slave, 1, "Invalid object description response while"
887  " fetching SDO 0x%04X!\n", sdo->index);
888  ec_print_data(data, rec_size);
889  }
890  // check for CoE response again
891  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
892  fsm->retries = EC_FSM_RETRIES;
894  return;
895  }
896 
897  if (rec_size < 12) {
898  EC_SLAVE_ERR(slave, "Invalid data size!\n");
899  ec_print_data(data, rec_size);
900  fsm->state = ec_fsm_coe_error;
901  return;
902  }
903 
904  sdo->max_subindex = EC_READ_U8(data + 10);
905  sdo->object_code = EC_READ_U8(data + 11);
906 
907  name_size = rec_size - 12;
908  if (name_size) {
909  if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) {
910  EC_SLAVE_ERR(slave, "Failed to allocate SDO name!\n");
911  fsm->state = ec_fsm_coe_error;
912  return;
913  }
914 
915  memcpy(sdo->name, data + 12, name_size);
916  sdo->name[name_size] = 0;
917  }
918 
919  if (EC_READ_U8(data + 2) & 0x80) {
920  EC_SLAVE_ERR(slave, "Fragment follows (not implemented)!\n");
921  fsm->state = ec_fsm_coe_error;
922  return;
923  }
924 
925  // start fetching entries
926 
927  fsm->subindex = 0;
928  fsm->retries = EC_FSM_RETRIES;
929 
930  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
931  fsm->state = ec_fsm_coe_error;
932  }
933 }
934 
935 /****************************************************************************/
936 
943  ec_fsm_coe_t *fsm,
944  ec_datagram_t *datagram
945  )
946 {
947  ec_slave_t *slave = fsm->slave;
948 
949  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
950  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
951  fsm->state = ec_fsm_coe_error;
952  }
953  return;
954  }
955 
956  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
957  fsm->state = ec_fsm_coe_error;
958  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry"
959  " request datagram: ");
961  return;
962  }
963 
964  if (fsm->datagram->working_counter != 1) {
965  fsm->state = ec_fsm_coe_error;
966  EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: ");
968  return;
969  }
970 
971  fsm->jiffies_start = fsm->datagram->jiffies_sent;
972 
973  ec_slave_mbox_prepare_check(slave, datagram); // can not fail
974  fsm->retries = EC_FSM_RETRIES;
976 }
977 
978 /****************************************************************************/
979 
985  ec_fsm_coe_t *fsm,
986  ec_datagram_t *datagram
987  )
988 {
989  ec_slave_t *slave = fsm->slave;
990 
991  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
992  ec_slave_mbox_prepare_check(slave, datagram); // can not fail
993  return;
994  }
995 
996  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
997  fsm->state = ec_fsm_coe_error;
998  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1000  return;
1001  }
1002 
1003  if (fsm->datagram->working_counter != 1) {
1004  fsm->state = ec_fsm_coe_error;
1005  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1006  " datagram failed: ");
1008  return;
1009  }
1010 
1011  if (!ec_slave_mbox_check(fsm->datagram)) {
1012  unsigned long diff_ms =
1013  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1014  1000 / HZ;
1015  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
1016  fsm->state = ec_fsm_coe_error;
1017  EC_SLAVE_ERR(slave, "Timeout while waiting for"
1018  " SDO entry 0x%04x:%x description response.\n",
1019  fsm->sdo->index, fsm->subindex);
1020  return;
1021  }
1022 
1023  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1024  fsm->retries = EC_FSM_RETRIES;
1025  return;
1026  }
1027 
1028  // Fetch response
1029  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1030  fsm->retries = EC_FSM_RETRIES;
1032 }
1033 
1034 /****************************************************************************/
1035 
1042  ec_fsm_coe_t *fsm,
1043  ec_datagram_t *datagram
1044  )
1045 {
1046  ec_slave_t *slave = fsm->slave;
1047  ec_sdo_t *sdo = fsm->sdo;
1048  uint8_t *data, mbox_prot;
1049  size_t rec_size, data_size;
1050  ec_sdo_entry_t *entry;
1051  u16 word;
1052 
1053  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1054  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1055  return;
1056  }
1057 
1058  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1059  fsm->state = ec_fsm_coe_error;
1060  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
1061  " description response datagram: ");
1063  return;
1064  }
1065 
1066  if (fsm->datagram->working_counter != 1) {
1067  fsm->state = ec_fsm_coe_error;
1068  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
1069  " response failed: ");
1071  return;
1072  }
1073 
1074  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1075  if (IS_ERR(data)) {
1076  fsm->state = ec_fsm_coe_error;
1077  return;
1078  }
1079 
1080 #ifndef EC_EOE
1081  if (mbox_prot == EC_MBOX_TYPE_EOE) {
1082  // discard EoE message and wait for the next reponse
1083  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1084  fsm->retries = EC_FSM_RETRIES;
1086  return;
1087  }
1088 #endif
1089 
1090  if (mbox_prot != EC_MBOX_TYPE_COE) {
1091  EC_SLAVE_ERR(slave, "Received mailbox protocol"
1092  " 0x%02X as response.\n", mbox_prot);
1093  fsm->state = ec_fsm_coe_error;
1094  return;
1095  }
1096 
1097  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1098  // check for CoE response again
1099  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1100  fsm->retries = EC_FSM_RETRIES;
1102  return;
1103  }
1104 
1105  if (rec_size < 3) {
1106  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1107  " description response (size %zu).\n", rec_size);
1108  fsm->state = ec_fsm_coe_error;
1109  return;
1110  }
1111 
1112  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
1113  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
1114  EC_SLAVE_WARN(slave, "SDO information error response while"
1115  " fetching SDO entry 0x%04X:%02X!\n",
1116  sdo->index, fsm->subindex);
1117  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
1118 
1119  /* There may be gaps in the subindices, so try to continue with next
1120  * subindex. */
1121 
1122  } else {
1123  if (rec_size < 9) {
1124  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1125  " description response (size %zu).\n", rec_size);
1126  fsm->state = ec_fsm_coe_error;
1127  return;
1128  }
1129 
1130  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
1131  (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
1132  EC_READ_U16(data + 6) != sdo->index || // SDO index
1133  EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex
1134  if (fsm->slave->master->debug_level) {
1135  EC_SLAVE_DBG(slave, 1, "Invalid entry description response"
1136  " while fetching SDO entry 0x%04X:%02X!\n",
1137  sdo->index, fsm->subindex);
1138  ec_print_data(data, rec_size);
1139  }
1140  // check for CoE response again
1141  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1142  fsm->retries = EC_FSM_RETRIES;
1144  return;
1145  }
1146 
1147  if (rec_size < 16) {
1148  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
1149  ec_print_data(data, rec_size);
1150  fsm->state = ec_fsm_coe_error;
1151  return;
1152  }
1153 
1154  data_size = rec_size - 16;
1155 
1156  if (!(entry = (ec_sdo_entry_t *)
1157  kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) {
1158  EC_SLAVE_ERR(slave, "Failed to allocate entry!\n");
1159  fsm->state = ec_fsm_coe_error;
1160  return;
1161  }
1162 
1163  ec_sdo_entry_init(entry, sdo, fsm->subindex);
1164  entry->data_type = EC_READ_U16(data + 10);
1165  entry->bit_length = EC_READ_U16(data + 12);
1166 
1167  // read access rights
1168  word = EC_READ_U16(data + 14);
1169  entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001;
1171  (word >> 1) & 0x0001;
1172  entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001;
1173  entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001;
1175  (word >> 4) & 0x0001;
1176  entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001;
1177 
1178  if (data_size) {
1179  uint8_t *desc;
1180  if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) {
1181  EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n");
1182  fsm->state = ec_fsm_coe_error;
1183  return;
1184  }
1185  memcpy(desc, data + 16, data_size);
1186  desc[data_size] = 0;
1187  entry->description = desc;
1188  }
1189 
1190  list_add_tail(&entry->list, &sdo->entries);
1191  }
1192 
1193  if (fsm->subindex < sdo->max_subindex) {
1194  fsm->subindex++;
1195  fsm->retries = EC_FSM_RETRIES;
1196 
1197  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1198  fsm->state = ec_fsm_coe_error;
1199  }
1200 
1201  return;
1202  }
1203 
1204  // another SDO description to fetch?
1205  if (fsm->sdo->list.next != &slave->sdo_dictionary) {
1206  fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
1207  fsm->retries = EC_FSM_RETRIES;
1208 
1209  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
1210  fsm->state = ec_fsm_coe_error;
1211  }
1212 
1213  return;
1214  }
1215 
1216  fsm->state = ec_fsm_coe_end;
1217 }
1218 
1219 /*****************************************************************************
1220  * CoE state machine
1221  ****************************************************************************/
1222 
1228  ec_fsm_coe_t *fsm,
1229  ec_datagram_t *datagram
1230  )
1231 {
1232  u8 *data;
1233  ec_slave_t *slave = fsm->slave;
1234  ec_sdo_request_t *request = fsm->request;
1235  uint8_t data_set_size;
1236 
1237  if (request->data_size > 0 && request->data_size <= 4) {
1238  // use expedited transfer mode for lengths between 1 and 4 bytes
1239  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1241  if (IS_ERR(data)) {
1242  request->errno = PTR_ERR(data);
1243  return PTR_ERR(data);
1244  }
1245 
1246  fsm->remaining = 0;
1247 
1248  data_set_size = 4 - request->data_size;
1249 
1250  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1251  EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
1252  | data_set_size << 2
1253  | ((request->complete_access ? 1 : 0) << 4)
1254  | 0x1 << 5)); // Download request
1255  EC_WRITE_U16(data + 3, request->index);
1256  EC_WRITE_U8 (data + 5,
1257  request->complete_access ? 0x00 : request->subindex);
1258  memcpy(data + 6, request->data, request->data_size);
1259  memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);
1260 
1261  if (slave->master->debug_level) {
1262  EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
1264  }
1265  }
1266  else { // data_size < 1 or data_size > 4, use normal transfer type
1267  size_t data_size,
1268  max_data_size =
1270  required_data_size =
1272 
1273  if (max_data_size < required_data_size) {
1274  // segmenting needed
1275  data_size = max_data_size;
1276  } else {
1277  data_size = required_data_size;
1278  }
1279 
1280  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1281  data_size);
1282  if (IS_ERR(data)) {
1283  request->errno = PTR_ERR(data);
1284  return PTR_ERR(data);
1285  }
1286 
1287  fsm->offset = 0;
1288  fsm->remaining = request->data_size;
1289 
1290  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1291  EC_WRITE_U8(data + 2,
1292  0x1 // size indicator, normal
1293  | ((request->complete_access ? 1 : 0) << 4)
1294  | 0x1 << 5); // Download request
1295  EC_WRITE_U16(data + 3, request->index);
1296  EC_WRITE_U8 (data + 5,
1297  request->complete_access ? 0x00 : request->subindex);
1298  EC_WRITE_U32(data + 6, request->data_size);
1299 
1300  if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
1301  size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
1302  memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
1303  request->data, segment_size);
1304  fsm->offset += segment_size;
1305  fsm->remaining -= segment_size;
1306  }
1307 
1308  if (slave->master->debug_level) {
1309  EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
1310  ec_print_data(data, data_size);
1311  }
1312  }
1313 
1315  return 0;
1316 }
1317 
1318 /****************************************************************************/
1319 
1323  ec_fsm_coe_t *fsm,
1324  ec_datagram_t *datagram
1325  )
1326 {
1327  ec_slave_t *slave = fsm->slave;
1328  ec_sdo_request_t *request = fsm->request;
1329 
1330  if (fsm->slave->master->debug_level) {
1331  char subidxstr[10];
1332  if (request->complete_access) {
1333  subidxstr[0] = 0x00;
1334  } else {
1335  sprintf(subidxstr, ":%02X", request->subindex);
1336  }
1337  EC_SLAVE_DBG(slave, 1, "Downloading SDO 0x%04X%s.\n",
1338  request->index, subidxstr);
1339  ec_print_data(request->data, request->data_size);
1340  }
1341 
1342  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1343  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1344  request->errno = EPROTONOSUPPORT;
1345  fsm->state = ec_fsm_coe_error;
1346  return;
1347  }
1348 
1349  if (slave->configured_rx_mailbox_size <
1351  EC_SLAVE_ERR(slave, "Mailbox too small!\n");
1352  request->errno = ENOBUFS;
1353  fsm->state = ec_fsm_coe_error;
1354  return;
1355  }
1356 
1357 
1358  fsm->request->jiffies_sent = jiffies;
1359  fsm->retries = EC_FSM_RETRIES;
1360 
1361  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1362  fsm->state = ec_fsm_coe_error;
1363  }
1364 }
1365 
1366 /****************************************************************************/
1367 
1374  ec_fsm_coe_t *fsm,
1375  ec_datagram_t *datagram
1376  )
1377 {
1378  ec_slave_t *slave = fsm->slave;
1379  unsigned long diff_ms;
1380 
1381  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1382  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1383  fsm->state = ec_fsm_coe_error;
1384  }
1385  return;
1386  }
1387 
1388  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1389  fsm->request->errno = EIO;
1390  fsm->state = ec_fsm_coe_error;
1391  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1392  " request datagram: ");
1394  return;
1395  }
1396 
1397  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1398 
1399  if (fsm->datagram->working_counter != 1) {
1400  if (!fsm->datagram->working_counter) {
1401  if (diff_ms < fsm->request->response_timeout) {
1402 #if DEBUG_RETRIES
1403  EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
1404  " download request. Retrying after %lu ms...\n",
1405  diff_ms);
1406 #endif
1407  // no response; send request datagram again
1408  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1409  fsm->state = ec_fsm_coe_error;
1410  }
1411  return;
1412  }
1413  }
1414  fsm->request->errno = EIO;
1415  fsm->state = ec_fsm_coe_error;
1416  EC_SLAVE_ERR(slave, "Reception of CoE download request"
1417  " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
1418  fsm->request->index, fsm->request->subindex, diff_ms);
1420  return;
1421  }
1422 
1423 #if DEBUG_LONG
1424  if (diff_ms > 200) {
1425  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
1426  fsm->request->index, fsm->request->subindex, diff_ms);
1427  }
1428 #endif
1429 
1430  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1431 
1432  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1433  fsm->retries = EC_FSM_RETRIES;
1435 }
1436 
1437 /****************************************************************************/
1438 
1442  ec_fsm_coe_t *fsm,
1443  ec_datagram_t *datagram
1444  )
1445 {
1446  ec_slave_t *slave = fsm->slave;
1447 
1448  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1449  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1450  return;
1451  }
1452 
1453  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1454  fsm->request->errno = EIO;
1455  fsm->state = ec_fsm_coe_error;
1456  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
1457  " datagram: ");
1459  return;
1460  }
1461 
1462  if (fsm->datagram->working_counter != 1) {
1463  fsm->request->errno = EIO;
1464  fsm->state = ec_fsm_coe_error;
1465  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1466  " datagram failed: ");
1468  return;
1469  }
1470 
1471  if (!ec_slave_mbox_check(fsm->datagram)) {
1472  unsigned long diff_ms =
1473  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1474  1000 / HZ;
1475  if (diff_ms >= fsm->request->response_timeout) {
1476  fsm->request->errno = EIO;
1477  fsm->state = ec_fsm_coe_error;
1478  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
1479  " for SDO 0x%04x:%x download response.\n", diff_ms,
1480  fsm->request->index, fsm->request->subindex);
1481  return;
1482  }
1483 
1484  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1485  fsm->retries = EC_FSM_RETRIES;
1486  return;
1487  }
1488 
1489  // Fetch response
1490  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1491  fsm->retries = EC_FSM_RETRIES;
1493 }
1494 
1495 /****************************************************************************/
1496 
1500  ec_fsm_coe_t *fsm,
1501  ec_datagram_t *datagram
1502  )
1503 {
1504  ec_slave_t *slave = fsm->slave;
1505  ec_sdo_request_t *request = fsm->request;
1506  size_t max_segment_size =
1510  size_t data_size;
1511  uint8_t last_segment, seg_data_size, *data;
1512 
1513  if (fsm->remaining > max_segment_size) {
1514  fsm->segment_size = max_segment_size;
1515  last_segment = 0;
1516  } else {
1517  fsm->segment_size = fsm->remaining;
1518  last_segment = 1;
1519  }
1520 
1522  seg_data_size = 0x00;
1523  data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size;
1524  } else {
1525  seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size;
1528  }
1529 
1530  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1531  data_size);
1532  if (IS_ERR(data)) {
1533  request->errno = PTR_ERR(data);
1534  fsm->state = ec_fsm_coe_error;
1535  return;
1536  }
1537 
1538  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1539  EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
1540  | (seg_data_size << 1)
1541  | (fsm->toggle << 4)
1542  | (0x00 << 5)); // Download segment request
1543  memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
1544  request->data + fsm->offset, fsm->segment_size);
1546  memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size,
1548  }
1549 
1550  if (slave->master->debug_level) {
1551  EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
1552  ec_print_data(data, data_size);
1553  }
1554 
1556 }
1557 
1558 /****************************************************************************/
1559 
1566  ec_fsm_coe_t *fsm,
1567  ec_datagram_t *datagram
1568  )
1569 {
1570  ec_slave_t *slave = fsm->slave;
1571  uint8_t *data, mbox_prot;
1572  size_t rec_size;
1573  ec_sdo_request_t *request = fsm->request;
1574 
1575  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1576  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1577  return;
1578  }
1579 
1580  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1581  request->errno = EIO;
1582  fsm->state = ec_fsm_coe_error;
1583  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1584  " response datagram: ");
1586  return;
1587  }
1588 
1589  if (fsm->datagram->working_counter != 1) {
1590  request->errno = EIO;
1591  fsm->state = ec_fsm_coe_error;
1592  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1594  return;
1595  }
1596 
1597  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1598  if (IS_ERR(data)) {
1599  request->errno = PTR_ERR(data);
1600  fsm->state = ec_fsm_coe_error;
1601  return;
1602  }
1603 
1604 #ifndef EC_EOE
1605  if (mbox_prot == EC_MBOX_TYPE_EOE) {
1606  // discard EoE message and wait for the next reponse
1607  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1608  fsm->retries = EC_FSM_RETRIES;
1610  return;
1611  }
1612 #endif
1613 
1614  if (mbox_prot != EC_MBOX_TYPE_COE) {
1615  request->errno = EIO;
1616  fsm->state = ec_fsm_coe_error;
1617  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1618  mbox_prot);
1619  return;
1620  }
1621 
1622  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1623  // check for CoE response again
1624  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1625  fsm->retries = EC_FSM_RETRIES;
1627  return;
1628  }
1629 
1630  if (slave->master->debug_level) {
1631  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1632  ec_print_data(data, rec_size);
1633  }
1634 
1635  if (rec_size < 6) {
1636  request->errno = EIO;
1637  fsm->state = ec_fsm_coe_error;
1638  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1639  rec_size);
1640  ec_print_data(data, rec_size);
1641  return;
1642  }
1643 
1644  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1645  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1646  char subidxstr[10];
1647  request->errno = EIO;
1648  fsm->state = ec_fsm_coe_error;
1649  if (request->complete_access) {
1650  subidxstr[0] = 0x00;
1651  } else {
1652  sprintf(subidxstr, ":%02X", request->subindex);
1653  }
1654  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1655  request->index, subidxstr, request->data_size);
1656  if (rec_size < 10) {
1657  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1658  ec_print_data(data, rec_size);
1659  } else {
1660  fsm->request->abort_code = EC_READ_U32(data + 6);
1661  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1662  }
1663  return;
1664  }
1665 
1666  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
1667  EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
1668  EC_READ_U16(data + 3) != request->index || // index
1669  EC_READ_U8 (data + 5) != request->subindex) { // subindex
1670  if (slave->master->debug_level) {
1671  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1672  " Retrying...\n");
1673  ec_print_data(data, rec_size);
1674  }
1675  // check for CoE response again
1676  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1677  fsm->retries = EC_FSM_RETRIES;
1679  return;
1680  }
1681 
1682  if (fsm->remaining) { // more segments to download
1683  fsm->toggle = 0;
1685  } else {
1686  fsm->state = ec_fsm_coe_end; // success
1687  }
1688 }
1689 
1690 /****************************************************************************/
1691 
1697  ec_fsm_coe_t *fsm,
1698  ec_datagram_t *datagram
1699  )
1700 {
1701  ec_slave_t *slave = fsm->slave;
1702 
1703  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1704  return;
1705 
1706  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1707  fsm->request->errno = EIO;
1708  fsm->state = ec_fsm_coe_error;
1709  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1711  return;
1712  }
1713 
1714  if (fsm->datagram->working_counter != 1) {
1715  fsm->request->errno = EIO;
1716  fsm->state = ec_fsm_coe_error;
1717  EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
1718  " datagram failed: ");
1720  return;
1721  }
1722 
1723  if (!ec_slave_mbox_check(fsm->datagram)) {
1724  unsigned long diff_ms =
1725  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1726  1000 / HZ;
1727  if (diff_ms >= fsm->request->response_timeout) {
1728  fsm->request->errno = EIO;
1729  fsm->state = ec_fsm_coe_error;
1730  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
1731  " segment response.\n");
1732  return;
1733  }
1734 
1735  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1736  fsm->retries = EC_FSM_RETRIES;
1737  return;
1738  }
1739 
1740  // Fetch response
1741  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1742  fsm->retries = EC_FSM_RETRIES;
1744 }
1745 
1746 /****************************************************************************/
1747 
1754  ec_fsm_coe_t *fsm,
1755  ec_datagram_t *datagram
1756  )
1757 {
1758  ec_slave_t *slave = fsm->slave;
1759  uint8_t *data, mbox_prot;
1760  size_t rec_size;
1761  ec_sdo_request_t *request = fsm->request;
1762 
1763  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1764  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1765  return;
1766  }
1767 
1768  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1769  request->errno = EIO;
1770  fsm->state = ec_fsm_coe_error;
1771  EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
1772  " datagram: ");
1774  return;
1775  }
1776 
1777  if (fsm->datagram->working_counter != 1) {
1778  request->errno = EIO;
1779  fsm->state = ec_fsm_coe_error;
1780  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1782  return;
1783  }
1784 
1785  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1786  if (IS_ERR(data)) {
1787  request->errno = PTR_ERR(data);
1788  fsm->state = ec_fsm_coe_error;
1789  return;
1790  }
1791 
1792 #ifndef EC_EOE
1793  if (mbox_prot == EC_MBOX_TYPE_EOE) {
1794  // discard EoE message and wait for the next reponse
1795  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1796  fsm->retries = EC_FSM_RETRIES;
1798  return;
1799  }
1800 #endif
1801 
1802  if (mbox_prot != EC_MBOX_TYPE_COE) {
1803  request->errno = EIO;
1804  fsm->state = ec_fsm_coe_error;
1805  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1806  mbox_prot);
1807  return;
1808  }
1809 
1810  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1811  // check for CoE response again
1812  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1813  fsm->retries = EC_FSM_RETRIES;
1815  return;
1816  }
1817 
1818  if (slave->master->debug_level) {
1819  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1820  ec_print_data(data, rec_size);
1821  }
1822 
1823  if (rec_size < 6) {
1824  request->errno = EIO;
1825  fsm->state = ec_fsm_coe_error;
1826  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1827  rec_size);
1828  ec_print_data(data, rec_size);
1829  return;
1830  }
1831 
1832  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1833  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1834  char subidxstr[10];
1835  request->errno = EIO;
1836  fsm->state = ec_fsm_coe_error;
1837  if (request->complete_access) {
1838  subidxstr[0] = 0x00;
1839  } else {
1840  sprintf(subidxstr, ":%02X", request->subindex);
1841  }
1842  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1843  request->index, subidxstr, request->data_size);
1844  if (rec_size < 10) {
1845  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1846  ec_print_data(data, rec_size);
1847  } else {
1848  fsm->request->abort_code = EC_READ_U32(data + 6);
1849  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1850  }
1851  return;
1852  }
1853 
1854  if (EC_READ_U16(data) >> 12 != 0x3 ||
1855  ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response
1856  if (slave->master->debug_level) {
1857  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1858  " Retrying...\n");
1859  ec_print_data(data, rec_size);
1860  }
1861  // check for CoE response again
1862  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1863  fsm->retries = EC_FSM_RETRIES;
1865  return;
1866  }
1867 
1868  if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) {
1869  EC_SLAVE_ERR(slave, "Invalid toggle received during"
1870  " segmented download:\n");
1871  ec_print_data(data, rec_size);
1872  request->errno = EIO;
1873  fsm->state = ec_fsm_coe_error;
1874  return;
1875  }
1876 
1877  fsm->offset += fsm->segment_size;
1878  fsm->remaining -= fsm->segment_size;
1879 
1880  if (fsm->remaining) { // more segments to download
1881  fsm->toggle = !fsm->toggle;
1883  } else {
1884  fsm->state = ec_fsm_coe_end; // success
1885  }
1886 }
1887 
1888 /****************************************************************************/
1889 
1895  ec_fsm_coe_t *fsm,
1896  ec_datagram_t *datagram
1897  )
1898 {
1899  ec_slave_t *slave = fsm->slave;
1900  ec_sdo_request_t *request = fsm->request;
1901  ec_master_t *master = slave->master;
1902 
1903  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1904  10);
1905  if (IS_ERR(data)) {
1906  request->errno = PTR_ERR(data);
1907  return PTR_ERR(data);
1908  }
1909 
1910  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1911  EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
1912  EC_WRITE_U16(data + 3, request->index);
1913  EC_WRITE_U8 (data + 5, request->subindex);
1914  memset(data + 6, 0x00, 4);
1915 
1916  if (master->debug_level) {
1917  EC_SLAVE_DBG(slave, 1, "Upload request:\n");
1918  ec_print_data(data, 10);
1919  }
1920 
1922  return 0;
1923 }
1924 
1925 /****************************************************************************/
1926 
1932  ec_fsm_coe_t *fsm,
1933  ec_datagram_t *datagram
1934  )
1935 {
1936  ec_slave_t *slave = fsm->slave;
1937  ec_sdo_request_t *request = fsm->request;
1938 
1939  EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n",
1940  request->index, request->subindex);
1941 
1942  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1943  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1944  request->errno = EPROTONOSUPPORT;
1945  fsm->state = ec_fsm_coe_error;
1946  return;
1947  }
1948 
1949  fsm->retries = EC_FSM_RETRIES;
1950  fsm->request->jiffies_sent = jiffies;
1951 
1952  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1953  fsm->state = ec_fsm_coe_error;
1954  }
1955 }
1956 
1957 /****************************************************************************/
1964  ec_fsm_coe_t *fsm,
1965  ec_datagram_t *datagram
1966  )
1967 {
1968  ec_slave_t *slave = fsm->slave;
1969  unsigned long diff_ms;
1970 
1971  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1972  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1973  fsm->state = ec_fsm_coe_error;
1974  }
1975  return;
1976  }
1977 
1978  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1979  fsm->request->errno = EIO;
1980  fsm->state = ec_fsm_coe_error;
1981  EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
1983  return;
1984  }
1985 
1986  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1987 
1988  if (fsm->datagram->working_counter != 1) {
1989  if (!fsm->datagram->working_counter) {
1990  if (diff_ms < fsm->request->response_timeout) {
1991 #if DEBUG_RETRIES
1992  EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
1993  " SDO upload request. Retrying after %lu ms...\n",
1994  diff_ms);
1995 #endif
1996  // no response; send request datagram again
1997  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1998  fsm->state = ec_fsm_coe_error;
1999  }
2000  return;
2001  }
2002  }
2003  fsm->request->errno = EIO;
2004  fsm->state = ec_fsm_coe_error;
2005  EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
2006  " SDO 0x%04x:%x failed with timeout after %lu ms: ",
2007  fsm->request->index, fsm->request->subindex, diff_ms);
2009  return;
2010  }
2011 
2012 #if DEBUG_LONG
2013  if (diff_ms > 200) {
2014  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %lu ms.\n",
2015  fsm->request->index, fsm->request->subindex, diff_ms);
2016  }
2017 #endif
2018 
2019  fsm->jiffies_start = fsm->datagram->jiffies_sent;
2020 
2021  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2022  fsm->retries = EC_FSM_RETRIES;
2023  fsm->state = ec_fsm_coe_up_check;
2024 }
2025 
2026 /****************************************************************************/
2027 
2033  ec_fsm_coe_t *fsm,
2034  ec_datagram_t *datagram
2035  )
2036 {
2037  ec_slave_t *slave = fsm->slave;
2038 
2039  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2040  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2041  return;
2042  }
2043 
2044  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2045  fsm->request->errno = EIO;
2046  fsm->state = ec_fsm_coe_error;
2047  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
2049  return;
2050  }
2051 
2052  if (fsm->datagram->working_counter != 1) {
2053  fsm->request->errno = EIO;
2054  fsm->state = ec_fsm_coe_error;
2055  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
2056  " datagram failed: ");
2058  return;
2059  }
2060 
2061  if (!ec_slave_mbox_check(fsm->datagram)) {
2062  unsigned long diff_ms =
2063  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2064  1000 / HZ;
2065  if (diff_ms >= fsm->request->response_timeout) {
2066  fsm->request->errno = EIO;
2067  fsm->state = ec_fsm_coe_error;
2068  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
2069  " SDO 0x%04x:%x upload response.\n", diff_ms,
2070  fsm->request->index, fsm->request->subindex);
2071  return;
2072  }
2073 
2074  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2075  fsm->retries = EC_FSM_RETRIES;
2076  return;
2077  }
2078 
2079  // Fetch response
2080  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2081  fsm->retries = EC_FSM_RETRIES;
2083 }
2084 
2085 /****************************************************************************/
2086 
2090  ec_fsm_coe_t *fsm,
2091  ec_datagram_t *datagram
2092  )
2093 {
2094  uint8_t *data =
2095  ec_slave_mbox_prepare_send(fsm->slave, datagram, EC_MBOX_TYPE_COE,
2096  10);
2097  if (IS_ERR(data)) {
2098  fsm->request->errno = PTR_ERR(data);
2099  fsm->state = ec_fsm_coe_error;
2100  return;
2101  }
2102 
2103  EC_WRITE_U16(data, 0x2 << 12); // SDO request
2104  EC_WRITE_U8 (data + 2, (fsm->toggle << 4 // toggle
2105  | 0x3 << 5)); // upload segment request
2106  memset(data + 3, 0x00, 7);
2107 
2108  if (fsm->slave->master->debug_level) {
2109  EC_SLAVE_DBG(fsm->slave, 1, "Upload segment request:\n");
2110  ec_print_data(data, 10);
2111  }
2112 }
2113 
2114 /****************************************************************************/
2115 
2122  ec_fsm_coe_t *fsm,
2123  ec_datagram_t *datagram
2124  )
2125 {
2126  ec_slave_t *slave = fsm->slave;
2127  ec_master_t *master = slave->master;
2128  uint16_t rec_index;
2129  uint8_t *data, mbox_prot, rec_subindex;
2130  size_t rec_size, data_size;
2131  ec_sdo_request_t *request = fsm->request;
2132  unsigned int expedited, size_specified;
2133  int ret;
2134 
2135  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2136  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2137  return;
2138  }
2139 
2140  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2141  request->errno = EIO;
2142  fsm->state = ec_fsm_coe_error;
2143  EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
2144  " datagram: ");
2146  return;
2147  }
2148 
2149  if (fsm->datagram->working_counter != 1) {
2150  request->errno = EIO;
2151  fsm->state = ec_fsm_coe_error;
2152  EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
2154  return;
2155  }
2156 
2157  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2158  if (IS_ERR(data)) {
2159  request->errno = PTR_ERR(data);
2160  fsm->state = ec_fsm_coe_error;
2161  return;
2162  }
2163 
2164 #ifndef EC_EOE
2165  if (mbox_prot == EC_MBOX_TYPE_EOE) {
2166  // discard EoE message and wait for the next reponse
2167  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2168  fsm->retries = EC_FSM_RETRIES;
2169  fsm->state = ec_fsm_coe_up_check;
2170  return;
2171  }
2172 #endif
2173 
2174  if (mbox_prot != EC_MBOX_TYPE_COE) {
2175  request->errno = EIO;
2176  fsm->state = ec_fsm_coe_error;
2177  EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
2178  " as response.\n", mbox_prot);
2179  return;
2180  }
2181 
2182  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2183  // check for CoE response again
2184  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2185  fsm->retries = EC_FSM_RETRIES;
2186  fsm->state = ec_fsm_coe_up_check;
2187  return;
2188  }
2189 
2190  if (master->debug_level) {
2191  EC_SLAVE_DBG(slave, 1, "Upload response:\n");
2192  ec_print_data(data, rec_size);
2193  }
2194 
2195  if (rec_size < 6) {
2196  request->errno = EIO;
2197  fsm->state = ec_fsm_coe_error;
2198  EC_SLAVE_ERR(slave, "Received corrupted SDO upload response"
2199  " (%zu bytes)!\n", rec_size);
2200  ec_print_data(data, rec_size);
2201  return;
2202  }
2203 
2204  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2205  EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request
2206  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2207  request->index, request->subindex);
2208  if (rec_size >= 10) {
2209  request->abort_code = EC_READ_U32(data + 6);
2210  ec_canopen_abort_msg(slave, request->abort_code);
2211  } else {
2212  EC_SLAVE_ERR(slave, "No abort message.\n");
2213  }
2214  request->errno = EIO;
2215  fsm->state = ec_fsm_coe_error;
2216  return;
2217  }
2218 
2219  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2220  EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response
2221  EC_SLAVE_ERR(slave, "Received unknown response while"
2222  " uploading SDO 0x%04X:%02X.\n",
2223  request->index, request->subindex);
2224  ec_print_data(data, rec_size);
2225  request->errno = EIO;
2226  fsm->state = ec_fsm_coe_error;
2227  return;
2228  }
2229 
2230  rec_index = EC_READ_U16(data + 3);
2231  rec_subindex = EC_READ_U8(data + 5);
2232 
2233  if (rec_index != request->index || rec_subindex != request->subindex) {
2234  EC_SLAVE_ERR(slave, "Received upload response for wrong SDO"
2235  " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
2236  rec_index, rec_subindex, request->index, request->subindex);
2237  ec_print_data(data, rec_size);
2238 
2239  // check for CoE response again
2240  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2241  fsm->retries = EC_FSM_RETRIES;
2242  fsm->state = ec_fsm_coe_up_check;
2243  return;
2244  }
2245 
2246  // normal or expedited?
2247  expedited = EC_READ_U8(data + 2) & 0x02;
2248 
2249  if (expedited) {
2250  size_specified = EC_READ_U8(data + 2) & 0x01;
2251  if (size_specified) {
2252  fsm->complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
2253  } else {
2254  fsm->complete_size = 4;
2255  }
2256 
2257  if (rec_size < 6 + fsm->complete_size) {
2258  request->errno = EIO;
2259  fsm->state = ec_fsm_coe_error;
2260  EC_SLAVE_ERR(slave, "Received corrupted SDO expedited upload"
2261  " response (only %zu bytes)!\n", rec_size);
2262  ec_print_data(data, rec_size);
2263  return;
2264  }
2265 
2266  ret = ec_sdo_request_copy_data(request, data + 6, fsm->complete_size);
2267  if (ret) {
2268  request->errno = -ret;
2269  fsm->state = ec_fsm_coe_error;
2270  return;
2271  }
2272  } else { // normal
2273  if (rec_size < 10) {
2274  request->errno = EIO;
2275  fsm->state = ec_fsm_coe_error;
2276  EC_SLAVE_ERR(slave, "Received corrupted SDO normal upload"
2277  " response (only %zu bytes)!\n", rec_size);
2278  ec_print_data(data, rec_size);
2279  return;
2280  }
2281 
2282  data_size = rec_size - 10;
2283  fsm->complete_size = EC_READ_U32(data + 6);
2284 
2285  ret = ec_sdo_request_alloc(request, fsm->complete_size);
2286  if (ret) {
2287  request->errno = -ret;
2288  fsm->state = ec_fsm_coe_error;
2289  return;
2290  }
2291 
2292  ret = ec_sdo_request_copy_data(request, data + 10, data_size);
2293  if (ret) {
2294  request->errno = -ret;
2295  fsm->state = ec_fsm_coe_error;
2296  return;
2297  }
2298 
2299  fsm->toggle = 0;
2300 
2301  if (data_size < fsm->complete_size) {
2302  EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
2303  " Segmenting...\n", data_size, fsm->complete_size);
2305  fsm->retries = EC_FSM_RETRIES;
2307  return;
2308  }
2309  }
2310 
2311  if (master->debug_level) {
2312  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2313  ec_print_data(request->data, request->data_size);
2314  }
2315 
2316  fsm->state = ec_fsm_coe_end; // success
2317 }
2318 
2319 /****************************************************************************/
2320 
2327  ec_fsm_coe_t *fsm,
2328  ec_datagram_t *datagram
2329  )
2330 {
2331  ec_slave_t *slave = fsm->slave;
2332 
2333  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2335  return;
2336  }
2337 
2338  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2339  fsm->request->errno = EIO;
2340  fsm->state = ec_fsm_coe_error;
2341  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2342  " request datagram: ");
2344  return;
2345  }
2346 
2347  if (fsm->datagram->working_counter != 1) {
2348  fsm->request->errno = EIO;
2349  fsm->state = ec_fsm_coe_error;
2350  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2351  " request failed: ");
2353  return;
2354  }
2355 
2356  fsm->jiffies_start = fsm->datagram->jiffies_sent;
2357 
2358  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2359  fsm->retries = EC_FSM_RETRIES;
2361 }
2362 
2363 /****************************************************************************/
2364 
2370  ec_fsm_coe_t *fsm,
2371  ec_datagram_t *datagram
2372  )
2373 {
2374  ec_slave_t *slave = fsm->slave;
2375 
2376  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2377  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2378  return;
2379  }
2380 
2381  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2382  fsm->request->errno = EIO;
2383  fsm->state = ec_fsm_coe_error;
2384  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
2385  " datagram: ");
2387  return;
2388  }
2389 
2390  if (fsm->datagram->working_counter != 1) {
2391  fsm->request->errno = EIO;
2392  fsm->state = ec_fsm_coe_error;
2393  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
2394  " failed: ");
2396  return;
2397  }
2398 
2399  if (!ec_slave_mbox_check(fsm->datagram)) {
2400  unsigned long diff_ms =
2401  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2402  1000 / HZ;
2403  if (diff_ms >= fsm->request->response_timeout) {
2404  fsm->request->errno = EIO;
2405  fsm->state = ec_fsm_coe_error;
2406  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
2407  " segment response.\n");
2408  return;
2409  }
2410 
2411  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2412  fsm->retries = EC_FSM_RETRIES;
2413  return;
2414  }
2415 
2416  // Fetch response
2417  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2418  fsm->retries = EC_FSM_RETRIES;
2420 }
2421 
2422 /****************************************************************************/
2423 
2430  ec_fsm_coe_t *fsm,
2431  ec_datagram_t *datagram
2432  )
2433 {
2434  ec_slave_t *slave = fsm->slave;
2435  ec_master_t *master = slave->master;
2436  uint8_t *data, mbox_prot;
2437  size_t rec_size, data_size;
2438  ec_sdo_request_t *request = fsm->request;
2439  unsigned int last_segment;
2440 
2441  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2442  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2443  return;
2444  }
2445 
2446  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2447  request->errno = EIO;
2448  fsm->state = ec_fsm_coe_error;
2449  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2450  " response datagram: ");
2452  return;
2453  }
2454 
2455  if (fsm->datagram->working_counter != 1) {
2456  request->errno = EIO;
2457  fsm->state = ec_fsm_coe_error;
2458  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2459  " response failed: ");
2461  return;
2462  }
2463 
2464  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2465  if (IS_ERR(data)) {
2466  request->errno = PTR_ERR(data);
2467  fsm->state = ec_fsm_coe_error;
2468  return;
2469  }
2470 
2471 #ifndef EC_EOE
2472  if (mbox_prot == EC_MBOX_TYPE_EOE) {
2473  // discard EoE message and wait for the next reponse
2474  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2475  fsm->retries = EC_FSM_RETRIES;
2477  return;
2478  }
2479 #endif
2480 
2481  if (mbox_prot != EC_MBOX_TYPE_COE) {
2482  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
2483  mbox_prot);
2484  request->errno = EIO;
2485  fsm->state = ec_fsm_coe_error;
2486  return;
2487  }
2488 
2489  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2490  // check for CoE response again
2491  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2492  fsm->retries = EC_FSM_RETRIES;
2494  return;
2495  }
2496 
2497  if (master->debug_level) {
2498  EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
2499  ec_print_data(data, rec_size);
2500  }
2501 
2502 
2503  if (rec_size < 10) {
2504  EC_SLAVE_ERR(slave, "Received corrupted SDO upload"
2505  " segment response!\n");
2506  ec_print_data(data, rec_size);
2507  request->errno = EIO;
2508  fsm->state = ec_fsm_coe_error;
2509  return;
2510  }
2511 
2512  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2513  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
2514  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2515  request->index, request->subindex);
2516  request->abort_code = EC_READ_U32(data + 6);
2517  ec_canopen_abort_msg(slave, request->abort_code);
2518  request->errno = EIO;
2519  fsm->state = ec_fsm_coe_error;
2520  return;
2521  }
2522 
2523  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2524  EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
2525  if (fsm->slave->master->debug_level) {
2526  EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
2527  ec_print_data(data, rec_size);
2528  }
2529  // check for CoE response again
2530  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2531  fsm->retries = EC_FSM_RETRIES;
2533  return;
2534  }
2535 
2536  data_size = rec_size - 3; /* Header of segment upload is smaller than
2537  normal upload */
2538  if (rec_size == 10) {
2539  uint8_t seg_size = (EC_READ_U8(data + 2) & 0xE) >> 1;
2540  data_size -= seg_size;
2541  }
2542 
2543  if (request->data_size + data_size > fsm->complete_size) {
2544  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X failed: Fragment"
2545  " exceeding complete size!\n",
2546  request->index, request->subindex);
2547  request->errno = ENOBUFS;
2548  fsm->state = ec_fsm_coe_error;
2549  return;
2550  }
2551 
2552  memcpy(request->data + request->data_size, data + 3, data_size);
2553  request->data_size += data_size;
2554 
2555  last_segment = EC_READ_U8(data + 2) & 0x01;
2556  if (!last_segment) {
2557  fsm->toggle = !fsm->toggle;
2559  fsm->retries = EC_FSM_RETRIES;
2561  return;
2562  }
2563 
2564  if (request->data_size != fsm->complete_size) {
2565  EC_SLAVE_WARN(slave, "SDO upload 0x%04X:%02X: Assembled data"
2566  " size (%zu) does not match complete size (%u)!\n",
2567  request->index, request->subindex,
2568  request->data_size, fsm->complete_size);
2569  }
2570 
2571  if (master->debug_level) {
2572  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2573  ec_print_data(request->data, request->data_size);
2574  }
2575 
2576  fsm->state = ec_fsm_coe_end; // success
2577 }
2578 
2579 /****************************************************************************/
2580 
2586  ec_fsm_coe_t *fsm,
2587  ec_datagram_t *datagram
2588  )
2589 {
2590 }
2591 
2592 /****************************************************************************/
2593 
2599  ec_fsm_coe_t *fsm,
2600  ec_datagram_t *datagram
2601  )
2602 {
2603 }
2604 
2605 /****************************************************************************/
int ec_fsm_coe_prepare_down_start(ec_fsm_coe_t *, ec_datagram_t *)
Prepare a donwnload request.
Definition: fsm_coe.c:1227
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2429
CANopen over EtherCAT.
Definition: globals.h:146
uint8_t * ec_slave_mbox_prepare_send(const ec_slave_t *slave, ec_datagram_t *datagram, uint8_t type, size_t size)
Prepares a mailbox-send datagram.
Definition: mailbox.c:43
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
Definition: datagram.h:98
ec_sii_t sii
Extracted SII data.
Definition: slave.h:215
uint8_t * ec_slave_mbox_fetch(const ec_slave_t *slave, const ec_datagram_t *datagram, uint8_t *type, size_t *size)
Processes received mailbox data.
Definition: mailbox.c:157
int ec_fsm_coe_prepare_up(ec_fsm_coe_t *, ec_datagram_t *)
Prepare an upload request.
Definition: fsm_coe.c:1894
void ec_fsm_coe_up_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP START.
Definition: fsm_coe.c:1931
uint32_t offset
Data offset during segmented download.
Definition: fsm_coe.h:56
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:98
CANopen SDO entry.
Definition: sdo_entry.h:46
void ec_fsm_coe_end(ec_fsm_coe_t *, ec_datagram_t *)
State: END.
Definition: fsm_coe.c:2598
size_t segment_size
Current segment size.
Definition: fsm_coe.h:58
void ec_fsm_coe_dict_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT RESPONSE.
Definition: fsm_coe.c:502
CANopen SDO request.
Definition: sdo_request.h:40
void ec_fsm_coe_error(ec_fsm_coe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_coe.c:2585
void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY CHECK.
Definition: fsm_coe.c:984
uint16_t bit_length
Data size in bit.
Definition: sdo_entry.h:51
uint32_t response_timeout
Maximum time in ms, the transfer is retried, if the slave does not respond.
Definition: sdo_request.h:50
int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram to fetch mailbox data.
Definition: mailbox.c:119
uint32_t code
Code.
Definition: globals.h:275
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:82
void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY RESPONSE.
Definition: fsm_coe.c:1041
EtherCAT datagram.
Definition: datagram.h:79
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:152
uint16_t index
SDO index.
Definition: sdo_request.h:42
void ec_fsm_coe_down_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN CHECK.
Definition: fsm_coe.c:1441
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3192
uint32_t abort_code
SDO request abort code.
Definition: sdo_request.h:60
void(* state)(ec_fsm_coe_t *, ec_datagram_t *)
CoE state function.
Definition: fsm_coe.h:48
void ec_fsm_coe_down_prepare_segment_request(ec_fsm_coe_t *, ec_datagram_t *)
Prepare a download segment request.
Definition: fsm_coe.c:1499
void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:2326
uint16_t working_counter
Working counter.
Definition: datagram.h:93
struct list_head list
List item.
Definition: sdo.h:42
void ec_fsm_coe_down_seg_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN SEG CHECK.
Definition: fsm_coe.c:1696
#define EC_COE_DOWN_SEG_MIN_DATA_SIZE
Minimum size of download segment.
Definition: fsm_coe.c:50
CANopen SDO.
Definition: sdo.h:41
uint16_t index
SDO index.
Definition: sdo.h:44
void ec_fsm_coe_up_seg_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP CHECK.
Definition: fsm_coe.c:2369
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:44
int ec_fsm_coe_success(const ec_fsm_coe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_coe.c:267
#define EC_FSM_COE_DICT_TIMEOUT
Maximum time in ms to wait for responses when reading out the dictionary.
Definition: fsm_coe.c:38
Sent (still in the queue).
Definition: datagram.h:69
#define EC_COE_DOWN_SEG_REQ_HEADER_SIZE
CoE download segment request header size.
Definition: fsm_coe.c:46
struct list_head list
List item.
Definition: sdo_entry.h:47
void ec_fsm_coe_dict_entry_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY REQUEST.
Definition: fsm_coe.c:942
const char * message
Message belonging to code.
Definition: globals.h:276
struct list_head sdo_dictionary
SDO dictionary list.
Definition: slave.h:217
Global definitions and macros.
void ec_fsm_coe_up_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:1963
ec_direction_t dir
Direction.
Definition: sdo_request.h:52
EtherCAT master structure.
uint8_t object_code
Object code.
Definition: sdo.h:45
ec_sdo_t * sdo
current SDO
Definition: fsm_coe.h:51
Initial state of a new datagram.
Definition: datagram.h:67
EtherCAT CoE state machines.
EtherCAT slave.
Definition: slave.h:168
int ec_sdo_request_copy_data(ec_sdo_request_t *req, const uint8_t *source, size_t size)
Copies SDO data from an external source.
Definition: sdo_request.c:150
char * description
Description.
Definition: sdo_entry.h:54
int ec_fsm_coe_check_emergency(const ec_fsm_coe_t *, const uint8_t *, size_t)
Check if the received data are a CoE emergency request.
Definition: fsm_coe.c:282
Code/Message pair.
Definition: globals.h:274
ec_datagram_state_t state
State.
Definition: datagram.h:94
void ec_fsm_coe_dict_desc_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC REQUEST.
Definition: fsm_coe.c:667
ec_slave_config_t * config
Current configuration.
Definition: slave.h:182
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3226
void ec_fsm_coe_up_prepare_segment_request(ec_fsm_coe_t *, ec_datagram_t *)
Prepare an SDO upload segment request.
Definition: fsm_coe.c:2089
uint8_t enable_sdo_info
SDO information service available.
Definition: globals.h:156
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:139
ec_sdo_request_t * request
SDO request.
Definition: fsm_coe.h:53
int ec_fsm_coe_dict_prepare_desc(ec_fsm_coe_t *, ec_datagram_t *)
Prepare an object description request.
Definition: fsm_coe.c:473
unsigned int debug_level
Master debug level.
Definition: master.h:282
void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC RESPONSE.
Definition: fsm_coe.c:797
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:68
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
Definition: datagram.c:602
void ec_fsm_coe_up_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2121
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
Definition: sdo_request.h:57
uint8_t subindex
current subindex
Definition: fsm_coe.h:52
char * name
SDO name.
Definition: sdo.h:46
void ec_fsm_coe_clear(ec_fsm_coe_t *fsm)
Destructor.
Definition: fsm_coe.c:187
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3209
ec_datagram_t * datagram
Datagram used in last step.
Definition: fsm_coe.h:49
uint32_t remaining
Remaining bytes during segmented download.
Definition: fsm_coe.h:57
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3116
uint32_t complete_size
Used when segmenting.
Definition: fsm_coe.h:54
int ec_fsm_coe_dict_prepare_entry(ec_fsm_coe_t *, ec_datagram_t *)
Prepare an entry description request.
Definition: fsm_coe.c:766
ec_master_t * master
Master owning the slave.
Definition: slave.h:170
int errno
Error number.
Definition: sdo_request.h:59
unsigned long jiffies_start
CoE timestamp.
Definition: fsm_coe.h:50
void ec_fsm_coe_dict_desc_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC CHECK.
Definition: fsm_coe.c:710
void ec_fsm_coe_dictionary(ec_fsm_coe_t *fsm, ec_slave_t *slave)
Starts reading a slaves&#39; SDO dictionary.
Definition: fsm_coe.c:197
void ec_fsm_coe_dict_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT START.
Definition: fsm_coe.c:346
void ec_fsm_coe_down_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN REQUEST.
Definition: fsm_coe.c:1373
void ec_canopen_abort_msg(const ec_slave_t *, uint32_t)
Outputs an SDO abort message.
Definition: fsm_coe.c:153
uint16_t data_type
Data type.
Definition: sdo_entry.h:50
Access rights in OP.
Definition: globals.h:191
void ec_fsm_coe_dict_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT CHECK.
Definition: fsm_coe.c:418
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:83
void ec_sdo_init(ec_sdo_t *sdo, ec_slave_t *slave, uint16_t index)
Constructor.
Definition: sdo.c:39
Access rights in SAFEOP.
Definition: globals.h:190
int ec_fsm_coe_prepare_dict(ec_fsm_coe_t *, ec_datagram_t *)
Prepare a dictionary request.
Definition: fsm_coe.c:320
void ec_fsm_coe_init(ec_fsm_coe_t *fsm)
Constructor.
Definition: fsm_coe.c:175
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:344
uint8_t read_access[EC_SDO_ENTRY_ACCESS_COUNT]
Read access.
Definition: sdo_entry.h:52
uint8_t subindex
SDO subindex.
Definition: sdo_request.h:43
struct list_head entries
List of entries.
Definition: sdo.h:48
size_t data_size
Size of SDO data.
Definition: sdo_request.h:46
int ec_slave_mbox_prepare_check(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram for checking the mailbox state.
Definition: mailbox.c:88
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3100
ec_coe_emerg_ring_t emerg_ring
CoE emergency ring buffer.
Definition: slave_config.h:149
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:565
Mailbox functionality.
void ec_coe_emerg_ring_push(ec_coe_emerg_ring_t *ring, const u8 *msg)
Add a new emergency message.
int ec_fsm_coe_exec(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_coe.c:233
void ec_fsm_coe_dict_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT REQUEST.
Definition: fsm_coe.c:378
Access rights in PREOP.
Definition: globals.h:189
Queued for sending.
Definition: datagram.h:68
void ec_fsm_coe_down_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN START.
Definition: fsm_coe.c:1322
Timed out (dequeued).
Definition: datagram.h:71
uint8_t max_subindex
Maximum subindex.
Definition: sdo.h:47
void ec_fsm_coe_down_seg_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN SEG RESPONSE.
Definition: fsm_coe.c:1753
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:189
uint8_t toggle
toggle bit for segment commands
Definition: fsm_coe.h:55
void ec_sdo_entry_init(ec_sdo_entry_t *entry, ec_sdo_t *sdo, uint8_t subindex)
Constructor.
Definition: sdo_entry.c:37
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3084
EtherCAT slave configuration.
Definition: slave_config.h:111
void ec_fsm_coe_down_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN RESPONSE.
Definition: fsm_coe.c:1565
#define EC_COE_DOWN_REQ_HEADER_SIZE
CoE download request header size.
Definition: fsm_coe.c:42
unsigned int retries
retries upon datagram timeout
Definition: fsm_coe.h:46
EtherCAT slave configuration structure.
uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]
Write access.
Definition: sdo_entry.h:53
void ec_fsm_coe_transfer(ec_fsm_coe_t *fsm, ec_slave_t *slave, ec_sdo_request_t *request)
Starts to transfer an SDO to/from a slave.
Definition: fsm_coe.c:210
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: sdo_request.c:121
Values written by the master.
Definition: ecrt.h:506
Received (dequeued).
Definition: datagram.h:70
EtherCAT master.
Definition: master.h:194
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:102
ec_slave_t * slave
slave the FSM runs on
Definition: fsm_coe.h:45
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:107
const ec_code_msg_t sdo_abort_messages[]
SDO abort messages.
Definition: fsm_coe.c:112
uint8_t complete_access
SDO shall be transferred completely.
Definition: sdo_request.h:47
void ec_fsm_coe_up_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP CHECK.
Definition: fsm_coe.c:2032
unsigned int has_general
General category present.
Definition: slave.h:146
Finite state machines for the CANopen over EtherCAT protocol.
Definition: fsm_coe.h:44