IgH EtherCAT Master  1.6.8
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 
1124  if (rec_size < 9) {
1125  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1126  " description response (size %zu).\n", rec_size);
1127  fsm->state = ec_fsm_coe_error;
1128  return;
1129  }
1130 
1131  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
1132  (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
1133  EC_READ_U16(data + 6) != sdo->index || // SDO index
1134  EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex
1135  if (fsm->slave->master->debug_level) {
1136  EC_SLAVE_DBG(slave, 1, "Invalid entry description response"
1137  " while fetching SDO entry 0x%04X:%02X!\n",
1138  sdo->index, fsm->subindex);
1139  ec_print_data(data, rec_size);
1140  }
1141  // check for CoE response again
1142  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1143  fsm->retries = EC_FSM_RETRIES;
1145  return;
1146  }
1147 
1148  if (rec_size < 16) {
1149  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
1150  ec_print_data(data, rec_size);
1151  fsm->state = ec_fsm_coe_error;
1152  return;
1153  }
1154 
1155  data_size = rec_size - 16;
1156 
1157  if (!(entry = (ec_sdo_entry_t *)
1158  kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) {
1159  EC_SLAVE_ERR(slave, "Failed to allocate entry!\n");
1160  fsm->state = ec_fsm_coe_error;
1161  return;
1162  }
1163 
1164  ec_sdo_entry_init(entry, sdo, fsm->subindex);
1165  entry->data_type = EC_READ_U16(data + 10);
1166  entry->bit_length = EC_READ_U16(data + 12);
1167 
1168  // read access rights
1169  word = EC_READ_U16(data + 14);
1170  entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001;
1172  (word >> 1) & 0x0001;
1173  entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001;
1174  entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001;
1176  (word >> 4) & 0x0001;
1177  entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001;
1178 
1179  if (data_size) {
1180  uint8_t *desc;
1181  if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) {
1182  EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n");
1183  fsm->state = ec_fsm_coe_error;
1184  return;
1185  }
1186  memcpy(desc, data + 16, data_size);
1187  desc[data_size] = 0;
1188  entry->description = desc;
1189  }
1190 
1191  list_add_tail(&entry->list, &sdo->entries);
1192  }
1193 
1194  if (fsm->subindex < sdo->max_subindex) {
1195 
1196  fsm->subindex++;
1197  fsm->retries = EC_FSM_RETRIES;
1198 
1199  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1200  fsm->state = ec_fsm_coe_error;
1201  }
1202 
1203  return;
1204  }
1205 
1206  // another SDO description to fetch?
1207  if (fsm->sdo->list.next != &slave->sdo_dictionary) {
1208 
1209  fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
1210  fsm->retries = EC_FSM_RETRIES;
1211 
1212  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
1213  fsm->state = ec_fsm_coe_error;
1214  }
1215 
1216  return;
1217  }
1218 
1219  fsm->state = ec_fsm_coe_end;
1220 }
1221 
1222 /*****************************************************************************
1223  * CoE state machine
1224  ****************************************************************************/
1225 
1231  ec_fsm_coe_t *fsm,
1232  ec_datagram_t *datagram
1233  )
1234 {
1235  u8 *data;
1236  ec_slave_t *slave = fsm->slave;
1237  ec_sdo_request_t *request = fsm->request;
1238  uint8_t data_set_size;
1239 
1240  if (request->data_size > 0 && request->data_size <= 4) {
1241  // use expedited transfer mode for lengths between 1 and 4 bytes
1242  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1244  if (IS_ERR(data)) {
1245  request->errno = PTR_ERR(data);
1246  return PTR_ERR(data);
1247  }
1248 
1249  fsm->remaining = 0;
1250 
1251  data_set_size = 4 - request->data_size;
1252 
1253  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1254  EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
1255  | data_set_size << 2
1256  | ((request->complete_access ? 1 : 0) << 4)
1257  | 0x1 << 5)); // Download request
1258  EC_WRITE_U16(data + 3, request->index);
1259  EC_WRITE_U8 (data + 5,
1260  request->complete_access ? 0x00 : request->subindex);
1261  memcpy(data + 6, request->data, request->data_size);
1262  memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);
1263 
1264  if (slave->master->debug_level) {
1265  EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
1267  }
1268  }
1269  else { // data_size < 1 or data_size > 4, use normal transfer type
1270  size_t data_size,
1271  max_data_size =
1273  required_data_size =
1275 
1276  if (max_data_size < required_data_size) {
1277  // segmenting needed
1278  data_size = max_data_size;
1279  } else {
1280  data_size = required_data_size;
1281  }
1282 
1283  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1284  data_size);
1285  if (IS_ERR(data)) {
1286  request->errno = PTR_ERR(data);
1287  return PTR_ERR(data);
1288  }
1289 
1290  fsm->offset = 0;
1291  fsm->remaining = request->data_size;
1292 
1293  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1294  EC_WRITE_U8(data + 2,
1295  0x1 // size indicator, normal
1296  | ((request->complete_access ? 1 : 0) << 4)
1297  | 0x1 << 5); // Download request
1298  EC_WRITE_U16(data + 3, request->index);
1299  EC_WRITE_U8 (data + 5,
1300  request->complete_access ? 0x00 : request->subindex);
1301  EC_WRITE_U32(data + 6, request->data_size);
1302 
1303  if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
1304  size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
1305  memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
1306  request->data, segment_size);
1307  fsm->offset += segment_size;
1308  fsm->remaining -= segment_size;
1309  }
1310 
1311  if (slave->master->debug_level) {
1312  EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
1313  ec_print_data(data, data_size);
1314  }
1315  }
1316 
1318  return 0;
1319 }
1320 
1321 /****************************************************************************/
1322 
1326  ec_fsm_coe_t *fsm,
1327  ec_datagram_t *datagram
1328  )
1329 {
1330  ec_slave_t *slave = fsm->slave;
1331  ec_sdo_request_t *request = fsm->request;
1332 
1333  if (fsm->slave->master->debug_level) {
1334  char subidxstr[10];
1335  if (request->complete_access) {
1336  subidxstr[0] = 0x00;
1337  } else {
1338  sprintf(subidxstr, ":%02X", request->subindex);
1339  }
1340  EC_SLAVE_DBG(slave, 1, "Downloading SDO 0x%04X%s.\n",
1341  request->index, subidxstr);
1342  ec_print_data(request->data, request->data_size);
1343  }
1344 
1345  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1346  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1347  request->errno = EPROTONOSUPPORT;
1348  fsm->state = ec_fsm_coe_error;
1349  return;
1350  }
1351 
1352  if (slave->configured_rx_mailbox_size <
1354  EC_SLAVE_ERR(slave, "Mailbox too small!\n");
1355  request->errno = ENOBUFS;
1356  fsm->state = ec_fsm_coe_error;
1357  return;
1358  }
1359 
1360 
1361  fsm->request->jiffies_sent = jiffies;
1362  fsm->retries = EC_FSM_RETRIES;
1363 
1364  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1365  fsm->state = ec_fsm_coe_error;
1366  }
1367 }
1368 
1369 /****************************************************************************/
1370 
1377  ec_fsm_coe_t *fsm,
1378  ec_datagram_t *datagram
1379  )
1380 {
1381  ec_slave_t *slave = fsm->slave;
1382  unsigned long diff_ms;
1383 
1384  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1385  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1386  fsm->state = ec_fsm_coe_error;
1387  }
1388  return;
1389  }
1390 
1391  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1392  fsm->request->errno = EIO;
1393  fsm->state = ec_fsm_coe_error;
1394  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1395  " request datagram: ");
1397  return;
1398  }
1399 
1400  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1401 
1402  if (fsm->datagram->working_counter != 1) {
1403  if (!fsm->datagram->working_counter) {
1404  if (diff_ms < fsm->request->response_timeout) {
1405 #if DEBUG_RETRIES
1406  EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
1407  " download request. Retrying after %lu ms...\n",
1408  diff_ms);
1409 #endif
1410  // no response; send request datagram again
1411  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1412  fsm->state = ec_fsm_coe_error;
1413  }
1414  return;
1415  }
1416  }
1417  fsm->request->errno = EIO;
1418  fsm->state = ec_fsm_coe_error;
1419  EC_SLAVE_ERR(slave, "Reception of CoE download request"
1420  " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
1421  fsm->request->index, fsm->request->subindex, diff_ms);
1423  return;
1424  }
1425 
1426 #if DEBUG_LONG
1427  if (diff_ms > 200) {
1428  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
1429  fsm->request->index, fsm->request->subindex, diff_ms);
1430  }
1431 #endif
1432 
1433  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1434 
1435  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1436  fsm->retries = EC_FSM_RETRIES;
1438 }
1439 
1440 /****************************************************************************/
1441 
1445  ec_fsm_coe_t *fsm,
1446  ec_datagram_t *datagram
1447  )
1448 {
1449  ec_slave_t *slave = fsm->slave;
1450 
1451  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1452  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1453  return;
1454  }
1455 
1456  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1457  fsm->request->errno = EIO;
1458  fsm->state = ec_fsm_coe_error;
1459  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
1460  " datagram: ");
1462  return;
1463  }
1464 
1465  if (fsm->datagram->working_counter != 1) {
1466  fsm->request->errno = EIO;
1467  fsm->state = ec_fsm_coe_error;
1468  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1469  " datagram failed: ");
1471  return;
1472  }
1473 
1474  if (!ec_slave_mbox_check(fsm->datagram)) {
1475  unsigned long diff_ms =
1476  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1477  1000 / HZ;
1478  if (diff_ms >= fsm->request->response_timeout) {
1479  fsm->request->errno = EIO;
1480  fsm->state = ec_fsm_coe_error;
1481  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
1482  " for SDO 0x%04x:%x download response.\n", diff_ms,
1483  fsm->request->index, fsm->request->subindex);
1484  return;
1485  }
1486 
1487  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1488  fsm->retries = EC_FSM_RETRIES;
1489  return;
1490  }
1491 
1492  // Fetch response
1493  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1494  fsm->retries = EC_FSM_RETRIES;
1496 }
1497 
1498 /****************************************************************************/
1499 
1503  ec_fsm_coe_t *fsm,
1504  ec_datagram_t *datagram
1505  )
1506 {
1507  ec_slave_t *slave = fsm->slave;
1508  ec_sdo_request_t *request = fsm->request;
1509  size_t max_segment_size =
1513  size_t data_size;
1514  uint8_t last_segment, seg_data_size, *data;
1515 
1516  if (fsm->remaining > max_segment_size) {
1517  fsm->segment_size = max_segment_size;
1518  last_segment = 0;
1519  } else {
1520  fsm->segment_size = fsm->remaining;
1521  last_segment = 1;
1522  }
1523 
1525  seg_data_size = 0x00;
1526  data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size;
1527  } else {
1528  seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size;
1531  }
1532 
1533  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1534  data_size);
1535  if (IS_ERR(data)) {
1536  request->errno = PTR_ERR(data);
1537  fsm->state = ec_fsm_coe_error;
1538  return;
1539  }
1540 
1541  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1542  EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
1543  | (seg_data_size << 1)
1544  | (fsm->toggle << 4)
1545  | (0x00 << 5)); // Download segment request
1546  memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
1547  request->data + fsm->offset, fsm->segment_size);
1549  memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size,
1551  }
1552 
1553  if (slave->master->debug_level) {
1554  EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
1555  ec_print_data(data, data_size);
1556  }
1557 
1559 }
1560 
1561 /****************************************************************************/
1562 
1569  ec_fsm_coe_t *fsm,
1570  ec_datagram_t *datagram
1571  )
1572 {
1573  ec_slave_t *slave = fsm->slave;
1574  uint8_t *data, mbox_prot;
1575  size_t rec_size;
1576  ec_sdo_request_t *request = fsm->request;
1577 
1578  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1579  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1580  return;
1581  }
1582 
1583  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1584  request->errno = EIO;
1585  fsm->state = ec_fsm_coe_error;
1586  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1587  " response datagram: ");
1589  return;
1590  }
1591 
1592  if (fsm->datagram->working_counter != 1) {
1593  request->errno = EIO;
1594  fsm->state = ec_fsm_coe_error;
1595  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1597  return;
1598  }
1599 
1600  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1601  if (IS_ERR(data)) {
1602  request->errno = PTR_ERR(data);
1603  fsm->state = ec_fsm_coe_error;
1604  return;
1605  }
1606 
1607 #ifndef EC_EOE
1608  if (mbox_prot == EC_MBOX_TYPE_EOE) {
1609  // discard EoE message and wait for the next reponse
1610  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1611  fsm->retries = EC_FSM_RETRIES;
1613  return;
1614  }
1615 #endif
1616 
1617  if (mbox_prot != EC_MBOX_TYPE_COE) {
1618  request->errno = EIO;
1619  fsm->state = ec_fsm_coe_error;
1620  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1621  mbox_prot);
1622  return;
1623  }
1624 
1625  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1626  // check for CoE response again
1627  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1628  fsm->retries = EC_FSM_RETRIES;
1630  return;
1631  }
1632 
1633  if (slave->master->debug_level) {
1634  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1635  ec_print_data(data, rec_size);
1636  }
1637 
1638  if (rec_size < 6) {
1639  request->errno = EIO;
1640  fsm->state = ec_fsm_coe_error;
1641  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1642  rec_size);
1643  ec_print_data(data, rec_size);
1644  return;
1645  }
1646 
1647  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1648  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1649  char subidxstr[10];
1650  request->errno = EIO;
1651  fsm->state = ec_fsm_coe_error;
1652  if (request->complete_access) {
1653  subidxstr[0] = 0x00;
1654  } else {
1655  sprintf(subidxstr, ":%02X", request->subindex);
1656  }
1657  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1658  request->index, subidxstr, request->data_size);
1659  if (rec_size < 10) {
1660  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1661  ec_print_data(data, rec_size);
1662  } else {
1663  fsm->request->abort_code = EC_READ_U32(data + 6);
1664  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1665  }
1666  return;
1667  }
1668 
1669  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
1670  EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
1671  EC_READ_U16(data + 3) != request->index || // index
1672  EC_READ_U8 (data + 5) != request->subindex) { // subindex
1673  if (slave->master->debug_level) {
1674  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1675  " Retrying...\n");
1676  ec_print_data(data, rec_size);
1677  }
1678  // check for CoE response again
1679  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1680  fsm->retries = EC_FSM_RETRIES;
1682  return;
1683  }
1684 
1685  if (fsm->remaining) { // more segments to download
1686  fsm->toggle = 0;
1688  } else {
1689  fsm->state = ec_fsm_coe_end; // success
1690  }
1691 }
1692 
1693 /****************************************************************************/
1694 
1700  ec_fsm_coe_t *fsm,
1701  ec_datagram_t *datagram
1702  )
1703 {
1704  ec_slave_t *slave = fsm->slave;
1705 
1706  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1707  return;
1708 
1709  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1710  fsm->request->errno = EIO;
1711  fsm->state = ec_fsm_coe_error;
1712  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1714  return;
1715  }
1716 
1717  if (fsm->datagram->working_counter != 1) {
1718  fsm->request->errno = EIO;
1719  fsm->state = ec_fsm_coe_error;
1720  EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
1721  " datagram failed: ");
1723  return;
1724  }
1725 
1726  if (!ec_slave_mbox_check(fsm->datagram)) {
1727  unsigned long diff_ms =
1728  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1729  1000 / HZ;
1730  if (diff_ms >= fsm->request->response_timeout) {
1731  fsm->request->errno = EIO;
1732  fsm->state = ec_fsm_coe_error;
1733  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
1734  " segment response.\n");
1735  return;
1736  }
1737 
1738  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1739  fsm->retries = EC_FSM_RETRIES;
1740  return;
1741  }
1742 
1743  // Fetch response
1744  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1745  fsm->retries = EC_FSM_RETRIES;
1747 }
1748 
1749 /****************************************************************************/
1750 
1757  ec_fsm_coe_t *fsm,
1758  ec_datagram_t *datagram
1759  )
1760 {
1761  ec_slave_t *slave = fsm->slave;
1762  uint8_t *data, mbox_prot;
1763  size_t rec_size;
1764  ec_sdo_request_t *request = fsm->request;
1765 
1766  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1767  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1768  return;
1769  }
1770 
1771  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1772  request->errno = EIO;
1773  fsm->state = ec_fsm_coe_error;
1774  EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
1775  " datagram: ");
1777  return;
1778  }
1779 
1780  if (fsm->datagram->working_counter != 1) {
1781  request->errno = EIO;
1782  fsm->state = ec_fsm_coe_error;
1783  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1785  return;
1786  }
1787 
1788  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1789  if (IS_ERR(data)) {
1790  request->errno = PTR_ERR(data);
1791  fsm->state = ec_fsm_coe_error;
1792  return;
1793  }
1794 
1795 #ifndef EC_EOE
1796  if (mbox_prot == EC_MBOX_TYPE_EOE) {
1797  // discard EoE message and wait for the next reponse
1798  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1799  fsm->retries = EC_FSM_RETRIES;
1801  return;
1802  }
1803 #endif
1804 
1805  if (mbox_prot != EC_MBOX_TYPE_COE) {
1806  request->errno = EIO;
1807  fsm->state = ec_fsm_coe_error;
1808  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1809  mbox_prot);
1810  return;
1811  }
1812 
1813  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
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 (slave->master->debug_level) {
1822  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1823  ec_print_data(data, rec_size);
1824  }
1825 
1826  if (rec_size < 6) {
1827  request->errno = EIO;
1828  fsm->state = ec_fsm_coe_error;
1829  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1830  rec_size);
1831  ec_print_data(data, rec_size);
1832  return;
1833  }
1834 
1835  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1836  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1837  char subidxstr[10];
1838  request->errno = EIO;
1839  fsm->state = ec_fsm_coe_error;
1840  if (request->complete_access) {
1841  subidxstr[0] = 0x00;
1842  } else {
1843  sprintf(subidxstr, ":%02X", request->subindex);
1844  }
1845  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1846  request->index, subidxstr, request->data_size);
1847  if (rec_size < 10) {
1848  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1849  ec_print_data(data, rec_size);
1850  } else {
1851  fsm->request->abort_code = EC_READ_U32(data + 6);
1852  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1853  }
1854  return;
1855  }
1856 
1857  if (EC_READ_U16(data) >> 12 != 0x3 ||
1858  ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response
1859  if (slave->master->debug_level) {
1860  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1861  " Retrying...\n");
1862  ec_print_data(data, rec_size);
1863  }
1864  // check for CoE response again
1865  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1866  fsm->retries = EC_FSM_RETRIES;
1868  return;
1869  }
1870 
1871  if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) {
1872  EC_SLAVE_ERR(slave, "Invalid toggle received during"
1873  " segmented download:\n");
1874  ec_print_data(data, rec_size);
1875  request->errno = EIO;
1876  fsm->state = ec_fsm_coe_error;
1877  return;
1878  }
1879 
1880  fsm->offset += fsm->segment_size;
1881  fsm->remaining -= fsm->segment_size;
1882 
1883  if (fsm->remaining) { // more segments to download
1884  fsm->toggle = !fsm->toggle;
1886  } else {
1887  fsm->state = ec_fsm_coe_end; // success
1888  }
1889 }
1890 
1891 /****************************************************************************/
1892 
1898  ec_fsm_coe_t *fsm,
1899  ec_datagram_t *datagram
1900  )
1901 {
1902  ec_slave_t *slave = fsm->slave;
1903  ec_sdo_request_t *request = fsm->request;
1904  ec_master_t *master = slave->master;
1905 
1906  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1907  10);
1908  if (IS_ERR(data)) {
1909  request->errno = PTR_ERR(data);
1910  return PTR_ERR(data);
1911  }
1912 
1913  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1914  EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
1915  EC_WRITE_U16(data + 3, request->index);
1916  EC_WRITE_U8 (data + 5, request->subindex);
1917  memset(data + 6, 0x00, 4);
1918 
1919  if (master->debug_level) {
1920  EC_SLAVE_DBG(slave, 1, "Upload request:\n");
1921  ec_print_data(data, 10);
1922  }
1923 
1925  return 0;
1926 }
1927 
1928 /****************************************************************************/
1929 
1935  ec_fsm_coe_t *fsm,
1936  ec_datagram_t *datagram
1937  )
1938 {
1939  ec_slave_t *slave = fsm->slave;
1940  ec_sdo_request_t *request = fsm->request;
1941 
1942  EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n",
1943  request->index, request->subindex);
1944 
1945  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1946  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1947  request->errno = EPROTONOSUPPORT;
1948  fsm->state = ec_fsm_coe_error;
1949  return;
1950  }
1951 
1952  fsm->retries = EC_FSM_RETRIES;
1953  fsm->request->jiffies_sent = jiffies;
1954 
1955  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1956  fsm->state = ec_fsm_coe_error;
1957  }
1958 }
1959 
1960 /****************************************************************************/
1967  ec_fsm_coe_t *fsm,
1968  ec_datagram_t *datagram
1969  )
1970 {
1971  ec_slave_t *slave = fsm->slave;
1972  unsigned long diff_ms;
1973 
1974  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1975  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1976  fsm->state = ec_fsm_coe_error;
1977  }
1978  return;
1979  }
1980 
1981  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1982  fsm->request->errno = EIO;
1983  fsm->state = ec_fsm_coe_error;
1984  EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
1986  return;
1987  }
1988 
1989  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1990 
1991  if (fsm->datagram->working_counter != 1) {
1992  if (!fsm->datagram->working_counter) {
1993  if (diff_ms < fsm->request->response_timeout) {
1994 #if DEBUG_RETRIES
1995  EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
1996  " SDO upload request. Retrying after %lu ms...\n",
1997  diff_ms);
1998 #endif
1999  // no response; send request datagram again
2000  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
2001  fsm->state = ec_fsm_coe_error;
2002  }
2003  return;
2004  }
2005  }
2006  fsm->request->errno = EIO;
2007  fsm->state = ec_fsm_coe_error;
2008  EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
2009  " SDO 0x%04x:%x failed with timeout after %lu ms: ",
2010  fsm->request->index, fsm->request->subindex, diff_ms);
2012  return;
2013  }
2014 
2015 #if DEBUG_LONG
2016  if (diff_ms > 200) {
2017  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %lu ms.\n",
2018  fsm->request->index, fsm->request->subindex, diff_ms);
2019  }
2020 #endif
2021 
2022  fsm->jiffies_start = fsm->datagram->jiffies_sent;
2023 
2024  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2025  fsm->retries = EC_FSM_RETRIES;
2026  fsm->state = ec_fsm_coe_up_check;
2027 }
2028 
2029 /****************************************************************************/
2030 
2036  ec_fsm_coe_t *fsm,
2037  ec_datagram_t *datagram
2038  )
2039 {
2040  ec_slave_t *slave = fsm->slave;
2041 
2042  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2043  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2044  return;
2045  }
2046 
2047  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2048  fsm->request->errno = EIO;
2049  fsm->state = ec_fsm_coe_error;
2050  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
2052  return;
2053  }
2054 
2055  if (fsm->datagram->working_counter != 1) {
2056  fsm->request->errno = EIO;
2057  fsm->state = ec_fsm_coe_error;
2058  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
2059  " datagram failed: ");
2061  return;
2062  }
2063 
2064  if (!ec_slave_mbox_check(fsm->datagram)) {
2065  unsigned long diff_ms =
2066  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2067  1000 / HZ;
2068  if (diff_ms >= fsm->request->response_timeout) {
2069  fsm->request->errno = EIO;
2070  fsm->state = ec_fsm_coe_error;
2071  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
2072  " SDO 0x%04x:%x upload response.\n", diff_ms,
2073  fsm->request->index, fsm->request->subindex);
2074  return;
2075  }
2076 
2077  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2078  fsm->retries = EC_FSM_RETRIES;
2079  return;
2080  }
2081 
2082  // Fetch response
2083  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2084  fsm->retries = EC_FSM_RETRIES;
2086 }
2087 
2088 /****************************************************************************/
2089 
2093  ec_fsm_coe_t *fsm,
2094  ec_datagram_t *datagram
2095  )
2096 {
2097  uint8_t *data =
2098  ec_slave_mbox_prepare_send(fsm->slave, datagram, EC_MBOX_TYPE_COE,
2099  10);
2100  if (IS_ERR(data)) {
2101  fsm->request->errno = PTR_ERR(data);
2102  fsm->state = ec_fsm_coe_error;
2103  return;
2104  }
2105 
2106  EC_WRITE_U16(data, 0x2 << 12); // SDO request
2107  EC_WRITE_U8 (data + 2, (fsm->toggle << 4 // toggle
2108  | 0x3 << 5)); // upload segment request
2109  memset(data + 3, 0x00, 7);
2110 
2111  if (fsm->slave->master->debug_level) {
2112  EC_SLAVE_DBG(fsm->slave, 1, "Upload segment request:\n");
2113  ec_print_data(data, 10);
2114  }
2115 }
2116 
2117 /****************************************************************************/
2118 
2125  ec_fsm_coe_t *fsm,
2126  ec_datagram_t *datagram
2127  )
2128 {
2129  ec_slave_t *slave = fsm->slave;
2130  ec_master_t *master = slave->master;
2131  uint16_t rec_index;
2132  uint8_t *data, mbox_prot, rec_subindex;
2133  size_t rec_size, data_size;
2134  ec_sdo_request_t *request = fsm->request;
2135  unsigned int expedited, size_specified;
2136  int ret;
2137 
2138  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2139  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2140  return;
2141  }
2142 
2143  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2144  request->errno = EIO;
2145  fsm->state = ec_fsm_coe_error;
2146  EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
2147  " datagram: ");
2149  return;
2150  }
2151 
2152  if (fsm->datagram->working_counter != 1) {
2153  request->errno = EIO;
2154  fsm->state = ec_fsm_coe_error;
2155  EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
2157  return;
2158  }
2159 
2160  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2161  if (IS_ERR(data)) {
2162  request->errno = PTR_ERR(data);
2163  fsm->state = ec_fsm_coe_error;
2164  return;
2165  }
2166 
2167 #ifndef EC_EOE
2168  if (mbox_prot == EC_MBOX_TYPE_EOE) {
2169  // discard EoE message and wait for the next reponse
2170  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2171  fsm->retries = EC_FSM_RETRIES;
2172  fsm->state = ec_fsm_coe_up_check;
2173  return;
2174  }
2175 #endif
2176 
2177  if (mbox_prot != EC_MBOX_TYPE_COE) {
2178  request->errno = EIO;
2179  fsm->state = ec_fsm_coe_error;
2180  EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
2181  " as response.\n", mbox_prot);
2182  return;
2183  }
2184 
2185  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2186  // check for CoE response again
2187  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2188  fsm->retries = EC_FSM_RETRIES;
2189  fsm->state = ec_fsm_coe_up_check;
2190  return;
2191  }
2192 
2193  if (master->debug_level) {
2194  EC_SLAVE_DBG(slave, 1, "Upload response:\n");
2195  ec_print_data(data, rec_size);
2196  }
2197 
2198  if (rec_size < 6) {
2199  request->errno = EIO;
2200  fsm->state = ec_fsm_coe_error;
2201  EC_SLAVE_ERR(slave, "Received currupted SDO upload response"
2202  " (%zu bytes)!\n", rec_size);
2203  ec_print_data(data, rec_size);
2204  return;
2205  }
2206 
2207  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2208  EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request
2209  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2210  request->index, request->subindex);
2211  if (rec_size >= 10) {
2212  request->abort_code = EC_READ_U32(data + 6);
2213  ec_canopen_abort_msg(slave, request->abort_code);
2214  } else {
2215  EC_SLAVE_ERR(slave, "No abort message.\n");
2216  }
2217  request->errno = EIO;
2218  fsm->state = ec_fsm_coe_error;
2219  return;
2220  }
2221 
2222  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2223  EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response
2224  EC_SLAVE_ERR(slave, "Received unknown response while"
2225  " uploading SDO 0x%04X:%02X.\n",
2226  request->index, request->subindex);
2227  ec_print_data(data, rec_size);
2228  request->errno = EIO;
2229  fsm->state = ec_fsm_coe_error;
2230  return;
2231  }
2232 
2233  rec_index = EC_READ_U16(data + 3);
2234  rec_subindex = EC_READ_U8(data + 5);
2235 
2236  if (rec_index != request->index || rec_subindex != request->subindex) {
2237  EC_SLAVE_ERR(slave, "Received upload response for wrong SDO"
2238  " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
2239  rec_index, rec_subindex, request->index, request->subindex);
2240  ec_print_data(data, rec_size);
2241 
2242  // check for CoE response again
2243  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2244  fsm->retries = EC_FSM_RETRIES;
2245  fsm->state = ec_fsm_coe_up_check;
2246  return;
2247  }
2248 
2249  // normal or expedited?
2250  expedited = EC_READ_U8(data + 2) & 0x02;
2251 
2252  if (expedited) {
2253  size_specified = EC_READ_U8(data + 2) & 0x01;
2254  if (size_specified) {
2255  fsm->complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
2256  } else {
2257  fsm->complete_size = 4;
2258  }
2259 
2260  if (rec_size < 6 + fsm->complete_size) {
2261  request->errno = EIO;
2262  fsm->state = ec_fsm_coe_error;
2263  EC_SLAVE_ERR(slave, "Received corrupted SDO expedited upload"
2264  " response (only %zu bytes)!\n", rec_size);
2265  ec_print_data(data, rec_size);
2266  return;
2267  }
2268 
2269  ret = ec_sdo_request_copy_data(request, data + 6, fsm->complete_size);
2270  if (ret) {
2271  request->errno = -ret;
2272  fsm->state = ec_fsm_coe_error;
2273  return;
2274  }
2275  } else { // normal
2276  if (rec_size < 10) {
2277  request->errno = EIO;
2278  fsm->state = ec_fsm_coe_error;
2279  EC_SLAVE_ERR(slave, "Received currupted SDO normal upload"
2280  " response (only %zu bytes)!\n", rec_size);
2281  ec_print_data(data, rec_size);
2282  return;
2283  }
2284 
2285  data_size = rec_size - 10;
2286  fsm->complete_size = EC_READ_U32(data + 6);
2287 
2288  ret = ec_sdo_request_alloc(request, fsm->complete_size);
2289  if (ret) {
2290  request->errno = -ret;
2291  fsm->state = ec_fsm_coe_error;
2292  return;
2293  }
2294 
2295  ret = ec_sdo_request_copy_data(request, data + 10, data_size);
2296  if (ret) {
2297  request->errno = -ret;
2298  fsm->state = ec_fsm_coe_error;
2299  return;
2300  }
2301 
2302  fsm->toggle = 0;
2303 
2304  if (data_size < fsm->complete_size) {
2305  EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
2306  " Segmenting...\n", data_size, fsm->complete_size);
2308  fsm->retries = EC_FSM_RETRIES;
2310  return;
2311  }
2312  }
2313 
2314  if (master->debug_level) {
2315  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2316  ec_print_data(request->data, request->data_size);
2317  }
2318 
2319  fsm->state = ec_fsm_coe_end; // success
2320 }
2321 
2322 /****************************************************************************/
2323 
2330  ec_fsm_coe_t *fsm,
2331  ec_datagram_t *datagram
2332  )
2333 {
2334  ec_slave_t *slave = fsm->slave;
2335 
2336  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2338  return;
2339  }
2340 
2341  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2342  fsm->request->errno = EIO;
2343  fsm->state = ec_fsm_coe_error;
2344  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2345  " request datagram: ");
2347  return;
2348  }
2349 
2350  if (fsm->datagram->working_counter != 1) {
2351  fsm->request->errno = EIO;
2352  fsm->state = ec_fsm_coe_error;
2353  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2354  " request failed: ");
2356  return;
2357  }
2358 
2359  fsm->jiffies_start = fsm->datagram->jiffies_sent;
2360 
2361  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2362  fsm->retries = EC_FSM_RETRIES;
2364 }
2365 
2366 /****************************************************************************/
2367 
2373  ec_fsm_coe_t *fsm,
2374  ec_datagram_t *datagram
2375  )
2376 {
2377  ec_slave_t *slave = fsm->slave;
2378 
2379  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2380  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2381  return;
2382  }
2383 
2384  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2385  fsm->request->errno = EIO;
2386  fsm->state = ec_fsm_coe_error;
2387  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
2388  " datagram: ");
2390  return;
2391  }
2392 
2393  if (fsm->datagram->working_counter != 1) {
2394  fsm->request->errno = EIO;
2395  fsm->state = ec_fsm_coe_error;
2396  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
2397  " failed: ");
2399  return;
2400  }
2401 
2402  if (!ec_slave_mbox_check(fsm->datagram)) {
2403  unsigned long diff_ms =
2404  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2405  1000 / HZ;
2406  if (diff_ms >= fsm->request->response_timeout) {
2407  fsm->request->errno = EIO;
2408  fsm->state = ec_fsm_coe_error;
2409  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
2410  " segment response.\n");
2411  return;
2412  }
2413 
2414  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2415  fsm->retries = EC_FSM_RETRIES;
2416  return;
2417  }
2418 
2419  // Fetch response
2420  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2421  fsm->retries = EC_FSM_RETRIES;
2423 }
2424 
2425 /****************************************************************************/
2426 
2433  ec_fsm_coe_t *fsm,
2434  ec_datagram_t *datagram
2435  )
2436 {
2437  ec_slave_t *slave = fsm->slave;
2438  ec_master_t *master = slave->master;
2439  uint8_t *data, mbox_prot;
2440  size_t rec_size, data_size;
2441  ec_sdo_request_t *request = fsm->request;
2442  unsigned int last_segment;
2443 
2444  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2445  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2446  return;
2447  }
2448 
2449  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2450  request->errno = EIO;
2451  fsm->state = ec_fsm_coe_error;
2452  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2453  " response datagram: ");
2455  return;
2456  }
2457 
2458  if (fsm->datagram->working_counter != 1) {
2459  request->errno = EIO;
2460  fsm->state = ec_fsm_coe_error;
2461  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2462  " response failed: ");
2464  return;
2465  }
2466 
2467  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2468  if (IS_ERR(data)) {
2469  request->errno = PTR_ERR(data);
2470  fsm->state = ec_fsm_coe_error;
2471  return;
2472  }
2473 
2474 #ifndef EC_EOE
2475  if (mbox_prot == EC_MBOX_TYPE_EOE) {
2476  // discard EoE message and wait for the next reponse
2477  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2478  fsm->retries = EC_FSM_RETRIES;
2480  return;
2481  }
2482 #endif
2483 
2484  if (mbox_prot != EC_MBOX_TYPE_COE) {
2485  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
2486  mbox_prot);
2487  request->errno = EIO;
2488  fsm->state = ec_fsm_coe_error;
2489  return;
2490  }
2491 
2492  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2493  // check for CoE response again
2494  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2495  fsm->retries = EC_FSM_RETRIES;
2497  return;
2498  }
2499 
2500  if (master->debug_level) {
2501  EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
2502  ec_print_data(data, rec_size);
2503  }
2504 
2505 
2506  if (rec_size < 10) {
2507  EC_SLAVE_ERR(slave, "Received currupted SDO upload"
2508  " segment response!\n");
2509  ec_print_data(data, rec_size);
2510  request->errno = EIO;
2511  fsm->state = ec_fsm_coe_error;
2512  return;
2513  }
2514 
2515  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2516  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
2517  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2518  request->index, request->subindex);
2519  request->abort_code = EC_READ_U32(data + 6);
2520  ec_canopen_abort_msg(slave, request->abort_code);
2521  request->errno = EIO;
2522  fsm->state = ec_fsm_coe_error;
2523  return;
2524  }
2525 
2526  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2527  EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
2528  if (fsm->slave->master->debug_level) {
2529  EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
2530  ec_print_data(data, rec_size);
2531  }
2532  // check for CoE response again
2533  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2534  fsm->retries = EC_FSM_RETRIES;
2536  return;
2537  }
2538 
2539  data_size = rec_size - 3; /* Header of segment upload is smaller than
2540  normal upload */
2541  if (rec_size == 10) {
2542  uint8_t seg_size = (EC_READ_U8(data + 2) & 0xE) >> 1;
2543  data_size -= seg_size;
2544  }
2545 
2546  if (request->data_size + data_size > fsm->complete_size) {
2547  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X failed: Fragment"
2548  " exceeding complete size!\n",
2549  request->index, request->subindex);
2550  request->errno = ENOBUFS;
2551  fsm->state = ec_fsm_coe_error;
2552  return;
2553  }
2554 
2555  memcpy(request->data + request->data_size, data + 3, data_size);
2556  request->data_size += data_size;
2557 
2558  last_segment = EC_READ_U8(data + 2) & 0x01;
2559  if (!last_segment) {
2560  fsm->toggle = !fsm->toggle;
2562  fsm->retries = EC_FSM_RETRIES;
2564  return;
2565  }
2566 
2567  if (request->data_size != fsm->complete_size) {
2568  EC_SLAVE_WARN(slave, "SDO upload 0x%04X:%02X: Assembled data"
2569  " size (%zu) does not match complete size (%u)!\n",
2570  request->index, request->subindex,
2571  request->data_size, fsm->complete_size);
2572  }
2573 
2574  if (master->debug_level) {
2575  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2576  ec_print_data(request->data, request->data_size);
2577  }
2578 
2579  fsm->state = ec_fsm_coe_end; // success
2580 }
2581 
2582 /****************************************************************************/
2583 
2589  ec_fsm_coe_t *fsm,
2590  ec_datagram_t *datagram
2591  )
2592 {
2593 }
2594 
2595 /****************************************************************************/
2596 
2602  ec_fsm_coe_t *fsm,
2603  ec_datagram_t *datagram
2604  )
2605 {
2606 }
2607 
2608 /****************************************************************************/
int ec_fsm_coe_prepare_down_start(ec_fsm_coe_t *, ec_datagram_t *)
Prepare a donwnload request.
Definition: fsm_coe.c:1230
#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:2432
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:1897
void ec_fsm_coe_up_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP START.
Definition: fsm_coe.c:1934
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:2601
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:2588
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: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: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:1444
#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:1502
void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:2329
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:1699
#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:2372
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: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:1966
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: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: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:2092
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: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:594
void ec_fsm_coe_up_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2124
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: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:1376
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:1325
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:1756
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:1568
#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:2035
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