IgH EtherCAT Master  1.6.1
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  if (mbox_prot != EC_MBOX_TYPE_COE) {
543  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
544  mbox_prot);
545  fsm->state = ec_fsm_coe_error;
546  return;
547  }
548 
549  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
550  // check for CoE response again
551  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
552  fsm->retries = EC_FSM_RETRIES;
554  return;
555  }
556 
557  if (rec_size < 3) {
558  EC_SLAVE_ERR(slave, "Received corrupted SDO dictionary response"
559  " (size %zu).\n", rec_size);
560  fsm->state = ec_fsm_coe_error;
561  return;
562  }
563 
564  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
565  (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
566  EC_SLAVE_ERR(slave, "SDO information error response!\n");
567  if (rec_size < 10) {
568  EC_SLAVE_ERR(slave, "Incomplete SDO information"
569  " error response:\n");
570  ec_print_data(data, rec_size);
571  } else {
572  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
573  }
574  fsm->state = ec_fsm_coe_error;
575  return;
576  }
577 
578  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
579  (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
580  if (fsm->slave->master->debug_level) {
581  EC_SLAVE_DBG(slave, 1, "Invalid SDO list response!"
582  " Retrying...\n");
583  ec_print_data(data, rec_size);
584  }
585  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
586  fsm->retries = EC_FSM_RETRIES;
588  return;
589  }
590 
591  first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
592  index_list_offset = first_segment ? 8 : 6;
593 
594  if (rec_size < index_list_offset || rec_size % 2) {
595  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
596  ec_print_data(data, rec_size);
597  fsm->state = ec_fsm_coe_error;
598  return;
599  }
600 
601  sdo_count = (rec_size - index_list_offset) / 2;
602 
603  for (i = 0; i < sdo_count; i++) {
604  sdo_index = EC_READ_U16(data + index_list_offset + i * 2);
605  if (!sdo_index) {
606  EC_SLAVE_DBG(slave, 1, "SDO dictionary contains index 0x0000.\n");
607  continue;
608  }
609 
610  if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
611  EC_SLAVE_ERR(slave, "Failed to allocate memory for SDO!\n");
612  fsm->state = ec_fsm_coe_error;
613  return;
614  }
615 
616  ec_sdo_init(sdo, slave, sdo_index);
617  list_add_tail(&sdo->list, &slave->sdo_dictionary);
618  }
619 
620  fragments_left = EC_READ_U16(data + 4);
621  if (fragments_left) {
622  EC_SLAVE_DBG(slave, 1, "SDO list fragments left: %u\n",
623  fragments_left);
624  }
625 
626  if (EC_READ_U8(data + 2) & 0x80 || fragments_left) {
627  // more messages waiting. check again.
628  fsm->jiffies_start = fsm->datagram->jiffies_sent;
629  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
630  fsm->retries = EC_FSM_RETRIES;
632  return;
633  }
634 
635  if (list_empty(&slave->sdo_dictionary)) {
636  // no SDOs in dictionary. finished.
637  fsm->state = ec_fsm_coe_end; // success
638  return;
639  }
640 
641  // fetch SDO descriptions
642  fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);
643 
644  fsm->retries = EC_FSM_RETRIES;
645  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
646  fsm->state = ec_fsm_coe_error;
647  }
648 }
649 
650 /****************************************************************************/
651 
658  ec_fsm_coe_t *fsm,
659  ec_datagram_t *datagram
660  )
661 {
662  ec_slave_t *slave = fsm->slave;
663 
664  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
665  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
666  fsm->state = ec_fsm_coe_error;
667  }
668  return;
669  }
670 
671  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
672  fsm->state = ec_fsm_coe_error;
673  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
674  " description request datagram: ");
676  return;
677  }
678 
679  if (fsm->datagram->working_counter != 1) {
680  fsm->state = ec_fsm_coe_error;
681  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
682  " request failed: ");
684  return;
685  }
686 
687  fsm->jiffies_start = fsm->datagram->jiffies_sent;
688 
689  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
690  fsm->retries = EC_FSM_RETRIES;
692 }
693 
694 /****************************************************************************/
695 
701  ec_fsm_coe_t *fsm,
702  ec_datagram_t *datagram
703  )
704 {
705  ec_slave_t *slave = fsm->slave;
706 
707  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
708  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
709  return;
710  }
711 
712  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
713  fsm->state = ec_fsm_coe_error;
714  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
716  return;
717  }
718 
719  if (fsm->datagram->working_counter != 1) {
720  fsm->state = ec_fsm_coe_error;
721  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
722  " datagram failed: ");
724  return;
725  }
726 
727  if (!ec_slave_mbox_check(fsm->datagram)) {
728  unsigned long diff_ms =
729  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
730  1000 / HZ;
731  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
732  fsm->state = ec_fsm_coe_error;
733  EC_SLAVE_ERR(slave, "Timeout while waiting for"
734  " SDO 0x%04x object description response.\n",
735  fsm->sdo->index);
736  return;
737  }
738 
739  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
740  fsm->retries = EC_FSM_RETRIES;
741  return;
742  }
743 
744  // Fetch response
745  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
746  fsm->retries = EC_FSM_RETRIES;
748 }
749 
750 /****************************************************************************/
751 
757  ec_fsm_coe_t *fsm,
758  ec_datagram_t *datagram
759  )
760 {
761  ec_slave_t *slave = fsm->slave;
762  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
763  10);
764  if (IS_ERR(data)) {
765  return PTR_ERR(data);
766  }
767 
768  EC_WRITE_U16(data, 0x8 << 12); // SDO information
769  EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
770  EC_WRITE_U8 (data + 3, 0x00);
771  EC_WRITE_U16(data + 4, 0x0000);
772  EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
773  EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
774  EC_WRITE_U8 (data + 9, 0x01); // value info (access rights only)
775 
777  return 0;
778 }
779 
780 /****************************************************************************/
781 
788  ec_fsm_coe_t *fsm,
789  ec_datagram_t *datagram
790  )
791 {
792  ec_slave_t *slave = fsm->slave;
793  ec_sdo_t *sdo = fsm->sdo;
794  uint8_t *data, mbox_prot;
795  size_t rec_size, name_size;
796 
797  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
798  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
799  return;
800  }
801 
802  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
803  fsm->state = ec_fsm_coe_error;
804  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description"
805  " response datagram: ");
807  return;
808  }
809 
810  if (fsm->datagram->working_counter != 1) {
811  fsm->state = ec_fsm_coe_error;
812  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
813  " response failed: ");
815  return;
816  }
817 
818  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
819  if (IS_ERR(data)) {
820  fsm->state = ec_fsm_coe_error;
821  return;
822  }
823 
824  if (mbox_prot != EC_MBOX_TYPE_COE) {
825  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
826  mbox_prot);
827  fsm->state = ec_fsm_coe_error;
828  return;
829  }
830 
831  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
832  // check for CoE response again
833  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
834  fsm->retries = EC_FSM_RETRIES;
836  return;
837  }
838 
839  if (rec_size < 3) {
840  EC_SLAVE_ERR(slave, "Received corrupted SDO description response"
841  " (size %zu).\n", rec_size);
842  fsm->state = ec_fsm_coe_error;
843  return;
844  }
845 
846  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
847  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
848  EC_SLAVE_ERR(slave, "SDO information error response while"
849  " fetching SDO 0x%04X!\n", sdo->index);
850  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
851  fsm->state = ec_fsm_coe_error;
852  return;
853  }
854 
855  if (rec_size < 8) {
856  EC_SLAVE_ERR(slave, "Received corrupted SDO"
857  " description response (size %zu).\n", rec_size);
858  fsm->state = ec_fsm_coe_error;
859  return;
860  }
861 
862  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
863  (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response
864  EC_READ_U16(data + 6) != sdo->index) { // SDO index
865  if (fsm->slave->master->debug_level) {
866  EC_SLAVE_DBG(slave, 1, "Invalid object description response while"
867  " fetching SDO 0x%04X!\n", sdo->index);
868  ec_print_data(data, rec_size);
869  }
870  // check for CoE response again
871  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
872  fsm->retries = EC_FSM_RETRIES;
874  return;
875  }
876 
877  if (rec_size < 12) {
878  EC_SLAVE_ERR(slave, "Invalid data size!\n");
879  ec_print_data(data, rec_size);
880  fsm->state = ec_fsm_coe_error;
881  return;
882  }
883 
884  sdo->max_subindex = EC_READ_U8(data + 10);
885  sdo->object_code = EC_READ_U8(data + 11);
886 
887  name_size = rec_size - 12;
888  if (name_size) {
889  if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) {
890  EC_SLAVE_ERR(slave, "Failed to allocate SDO name!\n");
891  fsm->state = ec_fsm_coe_error;
892  return;
893  }
894 
895  memcpy(sdo->name, data + 12, name_size);
896  sdo->name[name_size] = 0;
897  }
898 
899  if (EC_READ_U8(data + 2) & 0x80) {
900  EC_SLAVE_ERR(slave, "Fragment follows (not implemented)!\n");
901  fsm->state = ec_fsm_coe_error;
902  return;
903  }
904 
905  // start fetching entries
906 
907  fsm->subindex = 0;
908  fsm->retries = EC_FSM_RETRIES;
909 
910  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
911  fsm->state = ec_fsm_coe_error;
912  }
913 }
914 
915 /****************************************************************************/
916 
923  ec_fsm_coe_t *fsm,
924  ec_datagram_t *datagram
925  )
926 {
927  ec_slave_t *slave = fsm->slave;
928 
929  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
930  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
931  fsm->state = ec_fsm_coe_error;
932  }
933  return;
934  }
935 
936  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
937  fsm->state = ec_fsm_coe_error;
938  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry"
939  " request datagram: ");
941  return;
942  }
943 
944  if (fsm->datagram->working_counter != 1) {
945  fsm->state = ec_fsm_coe_error;
946  EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: ");
948  return;
949  }
950 
951  fsm->jiffies_start = fsm->datagram->jiffies_sent;
952 
953  ec_slave_mbox_prepare_check(slave, datagram); // can not fail
954  fsm->retries = EC_FSM_RETRIES;
956 }
957 
958 /****************************************************************************/
959 
965  ec_fsm_coe_t *fsm,
966  ec_datagram_t *datagram
967  )
968 {
969  ec_slave_t *slave = fsm->slave;
970 
971  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
972  ec_slave_mbox_prepare_check(slave, datagram); // can not fail
973  return;
974  }
975 
976  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
977  fsm->state = ec_fsm_coe_error;
978  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
980  return;
981  }
982 
983  if (fsm->datagram->working_counter != 1) {
984  fsm->state = ec_fsm_coe_error;
985  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
986  " datagram failed: ");
988  return;
989  }
990 
991  if (!ec_slave_mbox_check(fsm->datagram)) {
992  unsigned long diff_ms =
993  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
994  1000 / HZ;
995  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
996  fsm->state = ec_fsm_coe_error;
997  EC_SLAVE_ERR(slave, "Timeout while waiting for"
998  " SDO entry 0x%04x:%x description response.\n",
999  fsm->sdo->index, fsm->subindex);
1000  return;
1001  }
1002 
1003  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1004  fsm->retries = EC_FSM_RETRIES;
1005  return;
1006  }
1007 
1008  // Fetch response
1009  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1010  fsm->retries = EC_FSM_RETRIES;
1012 }
1013 
1014 /****************************************************************************/
1015 
1022  ec_fsm_coe_t *fsm,
1023  ec_datagram_t *datagram
1024  )
1025 {
1026  ec_slave_t *slave = fsm->slave;
1027  ec_sdo_t *sdo = fsm->sdo;
1028  uint8_t *data, mbox_prot;
1029  size_t rec_size, data_size;
1030  ec_sdo_entry_t *entry;
1031  u16 word;
1032 
1033  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1034  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1035  return;
1036  }
1037 
1038  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1039  fsm->state = ec_fsm_coe_error;
1040  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
1041  " description response datagram: ");
1043  return;
1044  }
1045 
1046  if (fsm->datagram->working_counter != 1) {
1047  fsm->state = ec_fsm_coe_error;
1048  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
1049  " response failed: ");
1051  return;
1052  }
1053 
1054  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1055  if (IS_ERR(data)) {
1056  fsm->state = ec_fsm_coe_error;
1057  return;
1058  }
1059 
1060  if (mbox_prot != EC_MBOX_TYPE_COE) {
1061  EC_SLAVE_ERR(slave, "Received mailbox protocol"
1062  " 0x%02X as response.\n", mbox_prot);
1063  fsm->state = ec_fsm_coe_error;
1064  return;
1065  }
1066 
1067  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1068  // check for CoE response again
1069  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1070  fsm->retries = EC_FSM_RETRIES;
1072  return;
1073  }
1074 
1075  if (rec_size < 3) {
1076  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1077  " description response (size %zu).\n", rec_size);
1078  fsm->state = ec_fsm_coe_error;
1079  return;
1080  }
1081 
1082  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
1083  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
1084  EC_SLAVE_WARN(slave, "SDO information error response while"
1085  " fetching SDO entry 0x%04X:%02X!\n",
1086  sdo->index, fsm->subindex);
1087  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
1088 
1089  /* There may be gaps in the subindices, so try to continue with next
1090  * subindex. */
1091 
1092  } else {
1093 
1094  if (rec_size < 9) {
1095  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1096  " description response (size %zu).\n", rec_size);
1097  fsm->state = ec_fsm_coe_error;
1098  return;
1099  }
1100 
1101  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
1102  (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
1103  EC_READ_U16(data + 6) != sdo->index || // SDO index
1104  EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex
1105  if (fsm->slave->master->debug_level) {
1106  EC_SLAVE_DBG(slave, 1, "Invalid entry description response"
1107  " while fetching SDO entry 0x%04X:%02X!\n",
1108  sdo->index, fsm->subindex);
1109  ec_print_data(data, rec_size);
1110  }
1111  // check for CoE response again
1112  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1113  fsm->retries = EC_FSM_RETRIES;
1115  return;
1116  }
1117 
1118  if (rec_size < 16) {
1119  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
1120  ec_print_data(data, rec_size);
1121  fsm->state = ec_fsm_coe_error;
1122  return;
1123  }
1124 
1125  data_size = rec_size - 16;
1126 
1127  if (!(entry = (ec_sdo_entry_t *)
1128  kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) {
1129  EC_SLAVE_ERR(slave, "Failed to allocate entry!\n");
1130  fsm->state = ec_fsm_coe_error;
1131  return;
1132  }
1133 
1134  ec_sdo_entry_init(entry, sdo, fsm->subindex);
1135  entry->data_type = EC_READ_U16(data + 10);
1136  entry->bit_length = EC_READ_U16(data + 12);
1137 
1138  // read access rights
1139  word = EC_READ_U16(data + 14);
1140  entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001;
1142  (word >> 1) & 0x0001;
1143  entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001;
1144  entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001;
1146  (word >> 4) & 0x0001;
1147  entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001;
1148 
1149  if (data_size) {
1150  uint8_t *desc;
1151  if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) {
1152  EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n");
1153  fsm->state = ec_fsm_coe_error;
1154  return;
1155  }
1156  memcpy(desc, data + 16, data_size);
1157  desc[data_size] = 0;
1158  entry->description = desc;
1159  }
1160 
1161  list_add_tail(&entry->list, &sdo->entries);
1162  }
1163 
1164  if (fsm->subindex < sdo->max_subindex) {
1165 
1166  fsm->subindex++;
1167  fsm->retries = EC_FSM_RETRIES;
1168 
1169  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1170  fsm->state = ec_fsm_coe_error;
1171  }
1172 
1173  return;
1174  }
1175 
1176  // another SDO description to fetch?
1177  if (fsm->sdo->list.next != &slave->sdo_dictionary) {
1178 
1179  fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
1180  fsm->retries = EC_FSM_RETRIES;
1181 
1182  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
1183  fsm->state = ec_fsm_coe_error;
1184  }
1185 
1186  return;
1187  }
1188 
1189  fsm->state = ec_fsm_coe_end;
1190 }
1191 
1192 /*****************************************************************************
1193  * CoE state machine
1194  ****************************************************************************/
1195 
1201  ec_fsm_coe_t *fsm,
1202  ec_datagram_t *datagram
1203  )
1204 {
1205  u8 *data;
1206  ec_slave_t *slave = fsm->slave;
1207  ec_sdo_request_t *request = fsm->request;
1208  uint8_t data_set_size;
1209 
1210  if (request->data_size > 0 && request->data_size <= 4) {
1211  // use expedited transfer mode for lengths between 1 and 4 bytes
1212  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1214  if (IS_ERR(data)) {
1215  request->errno = PTR_ERR(data);
1216  return PTR_ERR(data);
1217  }
1218 
1219  fsm->remaining = 0;
1220 
1221  data_set_size = 4 - request->data_size;
1222 
1223  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1224  EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
1225  | data_set_size << 2
1226  | ((request->complete_access ? 1 : 0) << 4)
1227  | 0x1 << 5)); // Download request
1228  EC_WRITE_U16(data + 3, request->index);
1229  EC_WRITE_U8 (data + 5,
1230  request->complete_access ? 0x00 : request->subindex);
1231  memcpy(data + 6, request->data, request->data_size);
1232  memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);
1233 
1234  if (slave->master->debug_level) {
1235  EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
1237  }
1238  }
1239  else { // data_size < 1 or data_size > 4, use normal transfer type
1240  size_t data_size,
1241  max_data_size =
1243  required_data_size =
1245 
1246  if (max_data_size < required_data_size) {
1247  // segmenting needed
1248  data_size = max_data_size;
1249  } else {
1250  data_size = required_data_size;
1251  }
1252 
1253  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1254  data_size);
1255  if (IS_ERR(data)) {
1256  request->errno = PTR_ERR(data);
1257  return PTR_ERR(data);
1258  }
1259 
1260  fsm->offset = 0;
1261  fsm->remaining = request->data_size;
1262 
1263  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1264  EC_WRITE_U8(data + 2,
1265  0x1 // size indicator, normal
1266  | ((request->complete_access ? 1 : 0) << 4)
1267  | 0x1 << 5); // Download request
1268  EC_WRITE_U16(data + 3, request->index);
1269  EC_WRITE_U8 (data + 5,
1270  request->complete_access ? 0x00 : request->subindex);
1271  EC_WRITE_U32(data + 6, request->data_size);
1272 
1273  if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
1274  size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
1275  memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
1276  request->data, segment_size);
1277  fsm->offset += segment_size;
1278  fsm->remaining -= segment_size;
1279  }
1280 
1281  if (slave->master->debug_level) {
1282  EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
1283  ec_print_data(data, data_size);
1284  }
1285  }
1286 
1288  return 0;
1289 }
1290 
1291 /****************************************************************************/
1292 
1296  ec_fsm_coe_t *fsm,
1297  ec_datagram_t *datagram
1298  )
1299 {
1300  ec_slave_t *slave = fsm->slave;
1301  ec_sdo_request_t *request = fsm->request;
1302 
1303  if (fsm->slave->master->debug_level) {
1304  char subidxstr[10];
1305  if (request->complete_access) {
1306  subidxstr[0] = 0x00;
1307  } else {
1308  sprintf(subidxstr, ":%02X", request->subindex);
1309  }
1310  EC_SLAVE_DBG(slave, 1, "Downloading SDO 0x%04X%s.\n",
1311  request->index, subidxstr);
1312  ec_print_data(request->data, request->data_size);
1313  }
1314 
1315  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1316  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1317  request->errno = EPROTONOSUPPORT;
1318  fsm->state = ec_fsm_coe_error;
1319  return;
1320  }
1321 
1322  if (slave->configured_rx_mailbox_size <
1324  EC_SLAVE_ERR(slave, "Mailbox too small!\n");
1325  request->errno = ENOBUFS;
1326  fsm->state = ec_fsm_coe_error;
1327  return;
1328  }
1329 
1330 
1331  fsm->request->jiffies_sent = jiffies;
1332  fsm->retries = EC_FSM_RETRIES;
1333 
1334  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1335  fsm->state = ec_fsm_coe_error;
1336  }
1337 }
1338 
1339 /****************************************************************************/
1340 
1347  ec_fsm_coe_t *fsm,
1348  ec_datagram_t *datagram
1349  )
1350 {
1351  ec_slave_t *slave = fsm->slave;
1352  unsigned long diff_ms;
1353 
1354  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1355  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1356  fsm->state = ec_fsm_coe_error;
1357  }
1358  return;
1359  }
1360 
1361  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1362  fsm->request->errno = EIO;
1363  fsm->state = ec_fsm_coe_error;
1364  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1365  " request datagram: ");
1367  return;
1368  }
1369 
1370  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1371 
1372  if (fsm->datagram->working_counter != 1) {
1373  if (!fsm->datagram->working_counter) {
1374  if (diff_ms < fsm->request->response_timeout) {
1375 #if DEBUG_RETRIES
1376  EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
1377  " download request. Retrying after %lu ms...\n",
1378  diff_ms);
1379 #endif
1380  // no response; send request datagram again
1381  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1382  fsm->state = ec_fsm_coe_error;
1383  }
1384  return;
1385  }
1386  }
1387  fsm->request->errno = EIO;
1388  fsm->state = ec_fsm_coe_error;
1389  EC_SLAVE_ERR(slave, "Reception of CoE download request"
1390  " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
1391  fsm->request->index, fsm->request->subindex, diff_ms);
1393  return;
1394  }
1395 
1396 #if DEBUG_LONG
1397  if (diff_ms > 200) {
1398  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
1399  fsm->request->index, fsm->request->subindex, diff_ms);
1400  }
1401 #endif
1402 
1403  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1404 
1405  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1406  fsm->retries = EC_FSM_RETRIES;
1408 }
1409 
1410 /****************************************************************************/
1411 
1415  ec_fsm_coe_t *fsm,
1416  ec_datagram_t *datagram
1417  )
1418 {
1419  ec_slave_t *slave = fsm->slave;
1420 
1421  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1422  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1423  return;
1424  }
1425 
1426  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1427  fsm->request->errno = EIO;
1428  fsm->state = ec_fsm_coe_error;
1429  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
1430  " datagram: ");
1432  return;
1433  }
1434 
1435  if (fsm->datagram->working_counter != 1) {
1436  fsm->request->errno = EIO;
1437  fsm->state = ec_fsm_coe_error;
1438  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1439  " datagram failed: ");
1441  return;
1442  }
1443 
1444  if (!ec_slave_mbox_check(fsm->datagram)) {
1445  unsigned long diff_ms =
1446  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1447  1000 / HZ;
1448  if (diff_ms >= fsm->request->response_timeout) {
1449  fsm->request->errno = EIO;
1450  fsm->state = ec_fsm_coe_error;
1451  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
1452  " for SDO 0x%04x:%x download response.\n", diff_ms,
1453  fsm->request->index, fsm->request->subindex);
1454  return;
1455  }
1456 
1457  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1458  fsm->retries = EC_FSM_RETRIES;
1459  return;
1460  }
1461 
1462  // Fetch response
1463  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1464  fsm->retries = EC_FSM_RETRIES;
1466 }
1467 
1468 /****************************************************************************/
1469 
1473  ec_fsm_coe_t *fsm,
1474  ec_datagram_t *datagram
1475  )
1476 {
1477  ec_slave_t *slave = fsm->slave;
1478  ec_sdo_request_t *request = fsm->request;
1479  size_t max_segment_size =
1483  size_t data_size;
1484  uint8_t last_segment, seg_data_size, *data;
1485 
1486  if (fsm->remaining > max_segment_size) {
1487  fsm->segment_size = max_segment_size;
1488  last_segment = 0;
1489  } else {
1490  fsm->segment_size = fsm->remaining;
1491  last_segment = 1;
1492  }
1493 
1495  seg_data_size = 0x00;
1496  data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size;
1497  } else {
1498  seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size;
1501  }
1502 
1503  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1504  data_size);
1505  if (IS_ERR(data)) {
1506  request->errno = PTR_ERR(data);
1507  fsm->state = ec_fsm_coe_error;
1508  return;
1509  }
1510 
1511  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1512  EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
1513  | (seg_data_size << 1)
1514  | (fsm->toggle << 4)
1515  | (0x00 << 5)); // Download segment request
1516  memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
1517  request->data + fsm->offset, fsm->segment_size);
1519  memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size,
1521  }
1522 
1523  if (slave->master->debug_level) {
1524  EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
1525  ec_print_data(data, data_size);
1526  }
1527 
1529 }
1530 
1531 /****************************************************************************/
1532 
1539  ec_fsm_coe_t *fsm,
1540  ec_datagram_t *datagram
1541  )
1542 {
1543  ec_slave_t *slave = fsm->slave;
1544  uint8_t *data, mbox_prot;
1545  size_t rec_size;
1546  ec_sdo_request_t *request = fsm->request;
1547 
1548  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1549  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1550  return;
1551  }
1552 
1553  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1554  request->errno = EIO;
1555  fsm->state = ec_fsm_coe_error;
1556  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1557  " response datagram: ");
1559  return;
1560  }
1561 
1562  if (fsm->datagram->working_counter != 1) {
1563  request->errno = EIO;
1564  fsm->state = ec_fsm_coe_error;
1565  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1567  return;
1568  }
1569 
1570  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1571  if (IS_ERR(data)) {
1572  request->errno = PTR_ERR(data);
1573  fsm->state = ec_fsm_coe_error;
1574  return;
1575  }
1576 
1577  if (mbox_prot != EC_MBOX_TYPE_COE) {
1578  request->errno = EIO;
1579  fsm->state = ec_fsm_coe_error;
1580  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1581  mbox_prot);
1582  return;
1583  }
1584 
1585  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1586  // check for CoE response again
1587  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1588  fsm->retries = EC_FSM_RETRIES;
1590  return;
1591  }
1592 
1593  if (slave->master->debug_level) {
1594  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1595  ec_print_data(data, rec_size);
1596  }
1597 
1598  if (rec_size < 6) {
1599  request->errno = EIO;
1600  fsm->state = ec_fsm_coe_error;
1601  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1602  rec_size);
1603  ec_print_data(data, rec_size);
1604  return;
1605  }
1606 
1607  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1608  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1609  char subidxstr[10];
1610  request->errno = EIO;
1611  fsm->state = ec_fsm_coe_error;
1612  if (request->complete_access) {
1613  subidxstr[0] = 0x00;
1614  } else {
1615  sprintf(subidxstr, ":%02X", request->subindex);
1616  }
1617  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1618  request->index, subidxstr, request->data_size);
1619  if (rec_size < 10) {
1620  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1621  ec_print_data(data, rec_size);
1622  } else {
1623  fsm->request->abort_code = EC_READ_U32(data + 6);
1624  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1625  }
1626  return;
1627  }
1628 
1629  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
1630  EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
1631  EC_READ_U16(data + 3) != request->index || // index
1632  EC_READ_U8 (data + 5) != request->subindex) { // subindex
1633  if (slave->master->debug_level) {
1634  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1635  " Retrying...\n");
1636  ec_print_data(data, rec_size);
1637  }
1638  // check for CoE response again
1639  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1640  fsm->retries = EC_FSM_RETRIES;
1642  return;
1643  }
1644 
1645  if (fsm->remaining) { // more segments to download
1646  fsm->toggle = 0;
1648  } else {
1649  fsm->state = ec_fsm_coe_end; // success
1650  }
1651 }
1652 
1653 /****************************************************************************/
1654 
1660  ec_fsm_coe_t *fsm,
1661  ec_datagram_t *datagram
1662  )
1663 {
1664  ec_slave_t *slave = fsm->slave;
1665 
1666  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1667  return;
1668 
1669  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1670  fsm->request->errno = EIO;
1671  fsm->state = ec_fsm_coe_error;
1672  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1674  return;
1675  }
1676 
1677  if (fsm->datagram->working_counter != 1) {
1678  fsm->request->errno = EIO;
1679  fsm->state = ec_fsm_coe_error;
1680  EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
1681  " datagram failed: ");
1683  return;
1684  }
1685 
1686  if (!ec_slave_mbox_check(fsm->datagram)) {
1687  unsigned long diff_ms =
1688  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1689  1000 / HZ;
1690  if (diff_ms >= fsm->request->response_timeout) {
1691  fsm->request->errno = EIO;
1692  fsm->state = ec_fsm_coe_error;
1693  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
1694  " segment response.\n");
1695  return;
1696  }
1697 
1698  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1699  fsm->retries = EC_FSM_RETRIES;
1700  return;
1701  }
1702 
1703  // Fetch response
1704  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1705  fsm->retries = EC_FSM_RETRIES;
1707 }
1708 
1709 /****************************************************************************/
1710 
1717  ec_fsm_coe_t *fsm,
1718  ec_datagram_t *datagram
1719  )
1720 {
1721  ec_slave_t *slave = fsm->slave;
1722  uint8_t *data, mbox_prot;
1723  size_t rec_size;
1724  ec_sdo_request_t *request = fsm->request;
1725 
1726  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1727  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1728  return;
1729  }
1730 
1731  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1732  request->errno = EIO;
1733  fsm->state = ec_fsm_coe_error;
1734  EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
1735  " datagram: ");
1737  return;
1738  }
1739 
1740  if (fsm->datagram->working_counter != 1) {
1741  request->errno = EIO;
1742  fsm->state = ec_fsm_coe_error;
1743  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1745  return;
1746  }
1747 
1748  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1749  if (IS_ERR(data)) {
1750  request->errno = PTR_ERR(data);
1751  fsm->state = ec_fsm_coe_error;
1752  return;
1753  }
1754 
1755  if (mbox_prot != EC_MBOX_TYPE_COE) {
1756  request->errno = EIO;
1757  fsm->state = ec_fsm_coe_error;
1758  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1759  mbox_prot);
1760  return;
1761  }
1762 
1763  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1764  // check for CoE response again
1765  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1766  fsm->retries = EC_FSM_RETRIES;
1768  return;
1769  }
1770 
1771  if (slave->master->debug_level) {
1772  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1773  ec_print_data(data, rec_size);
1774  }
1775 
1776  if (rec_size < 6) {
1777  request->errno = EIO;
1778  fsm->state = ec_fsm_coe_error;
1779  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1780  rec_size);
1781  ec_print_data(data, rec_size);
1782  return;
1783  }
1784 
1785  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1786  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1787  char subidxstr[10];
1788  request->errno = EIO;
1789  fsm->state = ec_fsm_coe_error;
1790  if (request->complete_access) {
1791  subidxstr[0] = 0x00;
1792  } else {
1793  sprintf(subidxstr, ":%02X", request->subindex);
1794  }
1795  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1796  request->index, subidxstr, request->data_size);
1797  if (rec_size < 10) {
1798  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1799  ec_print_data(data, rec_size);
1800  } else {
1801  fsm->request->abort_code = EC_READ_U32(data + 6);
1802  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1803  }
1804  return;
1805  }
1806 
1807  if (EC_READ_U16(data) >> 12 != 0x3 ||
1808  ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response
1809  if (slave->master->debug_level) {
1810  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1811  " Retrying...\n");
1812  ec_print_data(data, rec_size);
1813  }
1814  // check for CoE response again
1815  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1816  fsm->retries = EC_FSM_RETRIES;
1818  return;
1819  }
1820 
1821  if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) {
1822  EC_SLAVE_ERR(slave, "Invalid toggle received during"
1823  " segmented download:\n");
1824  ec_print_data(data, rec_size);
1825  request->errno = EIO;
1826  fsm->state = ec_fsm_coe_error;
1827  return;
1828  }
1829 
1830  fsm->offset += fsm->segment_size;
1831  fsm->remaining -= fsm->segment_size;
1832 
1833  if (fsm->remaining) { // more segments to download
1834  fsm->toggle = !fsm->toggle;
1836  } else {
1837  fsm->state = ec_fsm_coe_end; // success
1838  }
1839 }
1840 
1841 /****************************************************************************/
1842 
1848  ec_fsm_coe_t *fsm,
1849  ec_datagram_t *datagram
1850  )
1851 {
1852  ec_slave_t *slave = fsm->slave;
1853  ec_sdo_request_t *request = fsm->request;
1854  ec_master_t *master = slave->master;
1855 
1856  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1857  10);
1858  if (IS_ERR(data)) {
1859  request->errno = PTR_ERR(data);
1860  return PTR_ERR(data);
1861  }
1862 
1863  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1864  EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
1865  EC_WRITE_U16(data + 3, request->index);
1866  EC_WRITE_U8 (data + 5, request->subindex);
1867  memset(data + 6, 0x00, 4);
1868 
1869  if (master->debug_level) {
1870  EC_SLAVE_DBG(slave, 1, "Upload request:\n");
1871  ec_print_data(data, 10);
1872  }
1873 
1875  return 0;
1876 }
1877 
1878 /****************************************************************************/
1879 
1885  ec_fsm_coe_t *fsm,
1886  ec_datagram_t *datagram
1887  )
1888 {
1889  ec_slave_t *slave = fsm->slave;
1890  ec_sdo_request_t *request = fsm->request;
1891 
1892  EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n",
1893  request->index, request->subindex);
1894 
1895  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1896  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1897  request->errno = EPROTONOSUPPORT;
1898  fsm->state = ec_fsm_coe_error;
1899  return;
1900  }
1901 
1902  fsm->retries = EC_FSM_RETRIES;
1903  fsm->request->jiffies_sent = jiffies;
1904 
1905  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1906  fsm->state = ec_fsm_coe_error;
1907  }
1908 }
1909 
1910 /****************************************************************************/
1917  ec_fsm_coe_t *fsm,
1918  ec_datagram_t *datagram
1919  )
1920 {
1921  ec_slave_t *slave = fsm->slave;
1922  unsigned long diff_ms;
1923 
1924  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1925  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1926  fsm->state = ec_fsm_coe_error;
1927  }
1928  return;
1929  }
1930 
1931  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1932  fsm->request->errno = EIO;
1933  fsm->state = ec_fsm_coe_error;
1934  EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
1936  return;
1937  }
1938 
1939  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1940 
1941  if (fsm->datagram->working_counter != 1) {
1942  if (!fsm->datagram->working_counter) {
1943  if (diff_ms < fsm->request->response_timeout) {
1944 #if DEBUG_RETRIES
1945  EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
1946  " SDO upload request. Retrying after %lu ms...\n",
1947  diff_ms);
1948 #endif
1949  // no response; send request datagram again
1950  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1951  fsm->state = ec_fsm_coe_error;
1952  }
1953  return;
1954  }
1955  }
1956  fsm->request->errno = EIO;
1957  fsm->state = ec_fsm_coe_error;
1958  EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
1959  " SDO 0x%04x:%x failed with timeout after %lu ms: ",
1960  fsm->request->index, fsm->request->subindex, diff_ms);
1962  return;
1963  }
1964 
1965 #if DEBUG_LONG
1966  if (diff_ms > 200) {
1967  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %lu ms.\n",
1968  fsm->request->index, fsm->request->subindex, diff_ms);
1969  }
1970 #endif
1971 
1972  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1973 
1974  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1975  fsm->retries = EC_FSM_RETRIES;
1976  fsm->state = ec_fsm_coe_up_check;
1977 }
1978 
1979 /****************************************************************************/
1980 
1986  ec_fsm_coe_t *fsm,
1987  ec_datagram_t *datagram
1988  )
1989 {
1990  ec_slave_t *slave = fsm->slave;
1991 
1992  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1993  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1994  return;
1995  }
1996 
1997  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1998  fsm->request->errno = EIO;
1999  fsm->state = ec_fsm_coe_error;
2000  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
2002  return;
2003  }
2004 
2005  if (fsm->datagram->working_counter != 1) {
2006  fsm->request->errno = EIO;
2007  fsm->state = ec_fsm_coe_error;
2008  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
2009  " datagram failed: ");
2011  return;
2012  }
2013 
2014  if (!ec_slave_mbox_check(fsm->datagram)) {
2015  unsigned long diff_ms =
2016  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2017  1000 / HZ;
2018  if (diff_ms >= fsm->request->response_timeout) {
2019  fsm->request->errno = EIO;
2020  fsm->state = ec_fsm_coe_error;
2021  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
2022  " SDO 0x%04x:%x upload response.\n", diff_ms,
2023  fsm->request->index, fsm->request->subindex);
2024  return;
2025  }
2026 
2027  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2028  fsm->retries = EC_FSM_RETRIES;
2029  return;
2030  }
2031 
2032  // Fetch response
2033  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2034  fsm->retries = EC_FSM_RETRIES;
2036 }
2037 
2038 /****************************************************************************/
2039 
2043  ec_fsm_coe_t *fsm,
2044  ec_datagram_t *datagram
2045  )
2046 {
2047  uint8_t *data =
2048  ec_slave_mbox_prepare_send(fsm->slave, datagram, EC_MBOX_TYPE_COE,
2049  10);
2050  if (IS_ERR(data)) {
2051  fsm->request->errno = PTR_ERR(data);
2052  fsm->state = ec_fsm_coe_error;
2053  return;
2054  }
2055 
2056  EC_WRITE_U16(data, 0x2 << 12); // SDO request
2057  EC_WRITE_U8 (data + 2, (fsm->toggle << 4 // toggle
2058  | 0x3 << 5)); // upload segment request
2059  memset(data + 3, 0x00, 7);
2060 
2061  if (fsm->slave->master->debug_level) {
2062  EC_SLAVE_DBG(fsm->slave, 1, "Upload segment request:\n");
2063  ec_print_data(data, 10);
2064  }
2065 }
2066 
2067 /****************************************************************************/
2068 
2075  ec_fsm_coe_t *fsm,
2076  ec_datagram_t *datagram
2077  )
2078 {
2079  ec_slave_t *slave = fsm->slave;
2080  ec_master_t *master = slave->master;
2081  uint16_t rec_index;
2082  uint8_t *data, mbox_prot, rec_subindex;
2083  size_t rec_size, data_size;
2084  ec_sdo_request_t *request = fsm->request;
2085  unsigned int expedited, size_specified;
2086  int ret;
2087 
2088  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2089  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2090  return;
2091  }
2092 
2093  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2094  request->errno = EIO;
2095  fsm->state = ec_fsm_coe_error;
2096  EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
2097  " datagram: ");
2099  return;
2100  }
2101 
2102  if (fsm->datagram->working_counter != 1) {
2103  request->errno = EIO;
2104  fsm->state = ec_fsm_coe_error;
2105  EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
2107  return;
2108  }
2109 
2110  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2111  if (IS_ERR(data)) {
2112  request->errno = PTR_ERR(data);
2113  fsm->state = ec_fsm_coe_error;
2114  return;
2115  }
2116 
2117  if (master->debug_level) {
2118  EC_SLAVE_DBG(slave, 1, "Upload response:\n");
2119  ec_print_data(data, rec_size);
2120  }
2121 
2122  if (mbox_prot != EC_MBOX_TYPE_COE) {
2123  request->errno = EIO;
2124  fsm->state = ec_fsm_coe_error;
2125  EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
2126  " as response.\n", mbox_prot);
2127  return;
2128  }
2129 
2130  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2131  // check for CoE response again
2132  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2133  fsm->retries = EC_FSM_RETRIES;
2134  fsm->state = ec_fsm_coe_up_check;
2135  return;
2136  }
2137 
2138  if (rec_size < 6) {
2139  request->errno = EIO;
2140  fsm->state = ec_fsm_coe_error;
2141  EC_SLAVE_ERR(slave, "Received currupted SDO upload response"
2142  " (%zu bytes)!\n", rec_size);
2143  ec_print_data(data, rec_size);
2144  return;
2145  }
2146 
2147  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2148  EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request
2149  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2150  request->index, request->subindex);
2151  if (rec_size >= 10) {
2152  request->abort_code = EC_READ_U32(data + 6);
2153  ec_canopen_abort_msg(slave, request->abort_code);
2154  } else {
2155  EC_SLAVE_ERR(slave, "No abort message.\n");
2156  }
2157  request->errno = EIO;
2158  fsm->state = ec_fsm_coe_error;
2159  return;
2160  }
2161 
2162  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2163  EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response
2164  EC_SLAVE_ERR(slave, "Received unknown response while"
2165  " uploading SDO 0x%04X:%02X.\n",
2166  request->index, request->subindex);
2167  ec_print_data(data, rec_size);
2168  request->errno = EIO;
2169  fsm->state = ec_fsm_coe_error;
2170  return;
2171  }
2172 
2173  rec_index = EC_READ_U16(data + 3);
2174  rec_subindex = EC_READ_U8(data + 5);
2175 
2176  if (rec_index != request->index || rec_subindex != request->subindex) {
2177  EC_SLAVE_ERR(slave, "Received upload response for wrong SDO"
2178  " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
2179  rec_index, rec_subindex, request->index, request->subindex);
2180  ec_print_data(data, rec_size);
2181 
2182  // check for CoE response again
2183  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2184  fsm->retries = EC_FSM_RETRIES;
2185  fsm->state = ec_fsm_coe_up_check;
2186  return;
2187  }
2188 
2189  // normal or expedited?
2190  expedited = EC_READ_U8(data + 2) & 0x02;
2191 
2192  if (expedited) {
2193  size_specified = EC_READ_U8(data + 2) & 0x01;
2194  if (size_specified) {
2195  fsm->complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
2196  } else {
2197  fsm->complete_size = 4;
2198  }
2199 
2200  if (rec_size < 6 + fsm->complete_size) {
2201  request->errno = EIO;
2202  fsm->state = ec_fsm_coe_error;
2203  EC_SLAVE_ERR(slave, "Received corrupted SDO expedited upload"
2204  " response (only %zu bytes)!\n", rec_size);
2205  ec_print_data(data, rec_size);
2206  return;
2207  }
2208 
2209  ret = ec_sdo_request_copy_data(request, data + 6, fsm->complete_size);
2210  if (ret) {
2211  request->errno = -ret;
2212  fsm->state = ec_fsm_coe_error;
2213  return;
2214  }
2215  } else { // normal
2216  if (rec_size < 10) {
2217  request->errno = EIO;
2218  fsm->state = ec_fsm_coe_error;
2219  EC_SLAVE_ERR(slave, "Received currupted SDO normal upload"
2220  " response (only %zu bytes)!\n", rec_size);
2221  ec_print_data(data, rec_size);
2222  return;
2223  }
2224 
2225  data_size = rec_size - 10;
2226  fsm->complete_size = EC_READ_U32(data + 6);
2227 
2228  ret = ec_sdo_request_alloc(request, fsm->complete_size);
2229  if (ret) {
2230  request->errno = -ret;
2231  fsm->state = ec_fsm_coe_error;
2232  return;
2233  }
2234 
2235  ret = ec_sdo_request_copy_data(request, data + 10, data_size);
2236  if (ret) {
2237  request->errno = -ret;
2238  fsm->state = ec_fsm_coe_error;
2239  return;
2240  }
2241 
2242  fsm->toggle = 0;
2243 
2244  if (data_size < fsm->complete_size) {
2245  EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
2246  " Segmenting...\n", data_size, fsm->complete_size);
2248  fsm->retries = EC_FSM_RETRIES;
2250  return;
2251  }
2252  }
2253 
2254  if (master->debug_level) {
2255  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2256  ec_print_data(request->data, request->data_size);
2257  }
2258 
2259  fsm->state = ec_fsm_coe_end; // success
2260 }
2261 
2262 /****************************************************************************/
2263 
2270  ec_fsm_coe_t *fsm,
2271  ec_datagram_t *datagram
2272  )
2273 {
2274  ec_slave_t *slave = fsm->slave;
2275 
2276  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2278  return;
2279  }
2280 
2281  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2282  fsm->request->errno = EIO;
2283  fsm->state = ec_fsm_coe_error;
2284  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2285  " request datagram: ");
2287  return;
2288  }
2289 
2290  if (fsm->datagram->working_counter != 1) {
2291  fsm->request->errno = EIO;
2292  fsm->state = ec_fsm_coe_error;
2293  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2294  " request failed: ");
2296  return;
2297  }
2298 
2299  fsm->jiffies_start = fsm->datagram->jiffies_sent;
2300 
2301  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2302  fsm->retries = EC_FSM_RETRIES;
2304 }
2305 
2306 /****************************************************************************/
2307 
2313  ec_fsm_coe_t *fsm,
2314  ec_datagram_t *datagram
2315  )
2316 {
2317  ec_slave_t *slave = fsm->slave;
2318 
2319  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2320  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2321  return;
2322  }
2323 
2324  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2325  fsm->request->errno = EIO;
2326  fsm->state = ec_fsm_coe_error;
2327  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
2328  " datagram: ");
2330  return;
2331  }
2332 
2333  if (fsm->datagram->working_counter != 1) {
2334  fsm->request->errno = EIO;
2335  fsm->state = ec_fsm_coe_error;
2336  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
2337  " failed: ");
2339  return;
2340  }
2341 
2342  if (!ec_slave_mbox_check(fsm->datagram)) {
2343  unsigned long diff_ms =
2344  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2345  1000 / HZ;
2346  if (diff_ms >= fsm->request->response_timeout) {
2347  fsm->request->errno = EIO;
2348  fsm->state = ec_fsm_coe_error;
2349  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
2350  " segment response.\n");
2351  return;
2352  }
2353 
2354  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2355  fsm->retries = EC_FSM_RETRIES;
2356  return;
2357  }
2358 
2359  // Fetch response
2360  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2361  fsm->retries = EC_FSM_RETRIES;
2363 }
2364 
2365 /****************************************************************************/
2366 
2373  ec_fsm_coe_t *fsm,
2374  ec_datagram_t *datagram
2375  )
2376 {
2377  ec_slave_t *slave = fsm->slave;
2378  ec_master_t *master = slave->master;
2379  uint8_t *data, mbox_prot;
2380  size_t rec_size, data_size;
2381  ec_sdo_request_t *request = fsm->request;
2382  unsigned int last_segment;
2383 
2384  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2385  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2386  return;
2387  }
2388 
2389  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2390  request->errno = EIO;
2391  fsm->state = ec_fsm_coe_error;
2392  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2393  " response datagram: ");
2395  return;
2396  }
2397 
2398  if (fsm->datagram->working_counter != 1) {
2399  request->errno = EIO;
2400  fsm->state = ec_fsm_coe_error;
2401  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2402  " response failed: ");
2404  return;
2405  }
2406 
2407  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2408  if (IS_ERR(data)) {
2409  request->errno = PTR_ERR(data);
2410  fsm->state = ec_fsm_coe_error;
2411  return;
2412  }
2413 
2414  if (master->debug_level) {
2415  EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
2416  ec_print_data(data, rec_size);
2417  }
2418 
2419  if (mbox_prot != EC_MBOX_TYPE_COE) {
2420  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
2421  mbox_prot);
2422  request->errno = EIO;
2423  fsm->state = ec_fsm_coe_error;
2424  return;
2425  }
2426 
2427  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2428  // check for CoE response again
2429  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2430  fsm->retries = EC_FSM_RETRIES;
2432  return;
2433  }
2434 
2435  if (rec_size < 10) {
2436  EC_SLAVE_ERR(slave, "Received currupted SDO upload"
2437  " segment response!\n");
2438  ec_print_data(data, rec_size);
2439  request->errno = EIO;
2440  fsm->state = ec_fsm_coe_error;
2441  return;
2442  }
2443 
2444  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2445  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
2446  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2447  request->index, request->subindex);
2448  request->abort_code = EC_READ_U32(data + 6);
2449  ec_canopen_abort_msg(slave, request->abort_code);
2450  request->errno = EIO;
2451  fsm->state = ec_fsm_coe_error;
2452  return;
2453  }
2454 
2455  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2456  EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
2457  if (fsm->slave->master->debug_level) {
2458  EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
2459  ec_print_data(data, rec_size);
2460  }
2461  // check for CoE response again
2462  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2463  fsm->retries = EC_FSM_RETRIES;
2465  return;
2466  }
2467 
2468  data_size = rec_size - 3; /* Header of segment upload is smaller than
2469  normal upload */
2470  if (rec_size == 10) {
2471  uint8_t seg_size = (EC_READ_U8(data + 2) & 0xE) >> 1;
2472  data_size -= seg_size;
2473  }
2474 
2475  if (request->data_size + data_size > fsm->complete_size) {
2476  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X failed: Fragment"
2477  " exceeding complete size!\n",
2478  request->index, request->subindex);
2479  request->errno = ENOBUFS;
2480  fsm->state = ec_fsm_coe_error;
2481  return;
2482  }
2483 
2484  memcpy(request->data + request->data_size, data + 3, data_size);
2485  request->data_size += data_size;
2486 
2487  last_segment = EC_READ_U8(data + 2) & 0x01;
2488  if (!last_segment) {
2489  fsm->toggle = !fsm->toggle;
2491  fsm->retries = EC_FSM_RETRIES;
2493  return;
2494  }
2495 
2496  if (request->data_size != fsm->complete_size) {
2497  EC_SLAVE_WARN(slave, "SDO upload 0x%04X:%02X: Assembled data"
2498  " size (%zu) does not match complete size (%u)!\n",
2499  request->index, request->subindex,
2500  request->data_size, fsm->complete_size);
2501  }
2502 
2503  if (master->debug_level) {
2504  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2505  ec_print_data(request->data, request->data_size);
2506  }
2507 
2508  fsm->state = ec_fsm_coe_end; // success
2509 }
2510 
2511 /****************************************************************************/
2512 
2518  ec_fsm_coe_t *fsm,
2519  ec_datagram_t *datagram
2520  )
2521 {
2522 }
2523 
2524 /****************************************************************************/
2525 
2531  ec_fsm_coe_t *fsm,
2532  ec_datagram_t *datagram
2533  )
2534 {
2535 }
2536 
2537 /****************************************************************************/
int ec_fsm_coe_prepare_down_start(ec_fsm_coe_t *, ec_datagram_t *)
Prepare a donwnload request.
Definition: fsm_coe.c:1200
#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:2372
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:1847
void ec_fsm_coe_up_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP START.
Definition: fsm_coe.c:1884
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:2530
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:2517
void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY CHECK.
Definition: fsm_coe.c:964
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:276
#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:1021
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:1414
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3137
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:1472
void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:2269
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:1659
#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:2312
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:922
const char * message
Message belonging to code.
Definition: globals.h:277
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:1916
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:275
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:657
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:3171
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:2042
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:275
void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC RESPONSE.
Definition: fsm_coe.c:787
#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:594
void ec_fsm_coe_up_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2074
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:3154
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:3061
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:756
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:700
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:1346
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:192
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:191
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:3045
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:557
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:190
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:1295
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:1716
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:3029
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:1538
#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:187
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:1985
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