IgH EtherCAT Master  1.6.0
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 
72 
79 
87 
90 
91 /****************************************************************************/
92 
100  {0x05030000, "Toggle bit not changed"},
101  {0x05040000, "SDO protocol timeout"},
102  {0x05040001, "Client/Server command specifier not valid or unknown"},
103  {0x05040005, "Out of memory"},
104  {0x06010000, "Unsupported access to an object"},
105  {0x06010001, "Attempt to read a write-only object"},
106  {0x06010002, "Attempt to write a read-only object"},
107  {0x06020000, "This object does not exist in the object directory"},
108  {0x06040041, "The object cannot be mapped into the PDO"},
109  {0x06040042, "The number and length of the objects to be mapped would"
110  " exceed the PDO length"},
111  {0x06040043, "General parameter incompatibility reason"},
112  {0x06040047, "Gerneral internal incompatibility in device"},
113  {0x06060000, "Access failure due to a hardware error"},
114  {0x06070010, "Data type does not match, length of service parameter does"
115  " not match"},
116  {0x06070012, "Data type does not match, length of service parameter too"
117  " high"},
118  {0x06070013, "Data type does not match, length of service parameter too"
119  " low"},
120  {0x06090011, "Subindex does not exist"},
121  {0x06090030, "Value range of parameter exceeded"},
122  {0x06090031, "Value of parameter written too high"},
123  {0x06090032, "Value of parameter written too low"},
124  {0x06090036, "Maximum value is less than minimum value"},
125  {0x08000000, "General error"},
126  {0x08000020, "Data cannot be transferred or stored to the application"},
127  {0x08000021, "Data cannot be transferred or stored to the application"
128  " because of local control"},
129  {0x08000022, "Data cannot be transferred or stored to the application"
130  " because of the present device state"},
131  {0x08000023, "Object dictionary dynamic generation fails or no object"
132  " dictionary is present"},
133  {}
134 };
135 
136 /****************************************************************************/
137 
141  const ec_slave_t *slave,
142  uint32_t abort_code
143  )
144 {
145  const ec_code_msg_t *abort_msg;
146 
147  for (abort_msg = sdo_abort_messages; abort_msg->code; abort_msg++) {
148  if (abort_msg->code == abort_code) {
149  EC_SLAVE_ERR(slave, "SDO abort message 0x%08X: \"%s\".\n",
150  abort_msg->code, abort_msg->message);
151  return;
152  }
153  }
154 
155  EC_SLAVE_ERR(slave, "Unknown SDO abort code 0x%08X.\n", abort_code);
156 }
157 
158 /****************************************************************************/
159 
163  ec_fsm_coe_t *fsm
164  )
165 {
166  fsm->state = NULL;
167  fsm->datagram = NULL;
168 }
169 
170 /****************************************************************************/
171 
175  ec_fsm_coe_t *fsm
176  )
177 {
178 }
179 
180 /****************************************************************************/
181 
185  ec_fsm_coe_t *fsm,
186  ec_slave_t *slave
187  )
188 {
189  fsm->slave = slave;
191 }
192 
193 /****************************************************************************/
194 
198  ec_fsm_coe_t *fsm,
199  ec_slave_t *slave,
200  ec_sdo_request_t *request
201  )
202 {
203  fsm->slave = slave;
204  fsm->request = request;
205 
206  if (request->dir == EC_DIR_OUTPUT) {
208  }
209  else {
210  fsm->state = ec_fsm_coe_up_start;
211  }
212 }
213 
214 /****************************************************************************/
215 
221  ec_fsm_coe_t *fsm,
222  ec_datagram_t *datagram
223  )
224 {
225  int datagram_used = 0;
226 
227  if (fsm->datagram &&
228  (fsm->datagram->state == EC_DATAGRAM_INIT ||
229  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
230  fsm->datagram->state == EC_DATAGRAM_SENT)) {
231  // datagram not received yet
232  return datagram_used;
233  }
234 
235  fsm->state(fsm, datagram);
236 
237  datagram_used =
238  fsm->state != ec_fsm_coe_end && fsm->state != ec_fsm_coe_error;
239 
240  if (datagram_used) {
241  fsm->datagram = datagram;
242  } else {
243  fsm->datagram = NULL;
244  }
245 
246  return datagram_used;
247 }
248 
249 /****************************************************************************/
250 
255  const ec_fsm_coe_t *fsm
256  )
257 {
258  return fsm->state == ec_fsm_coe_end;
259 }
260 
261 /****************************************************************************/
262 
270  ec_fsm_coe_t *fsm,
271  const uint8_t *data,
272  size_t size
273  )
274 {
275  if (size < 2 || ((EC_READ_U16(data) >> 12) & 0x0F) != 0x01)
276  return 0;
277 
278  if (size < 10) {
279  EC_SLAVE_WARN(fsm->slave, "Received incomplete CoE Emergency"
280  " request:\n");
281  ec_print_data(data, size);
282  return 1;
283  }
284 
285  {
286  ec_slave_config_t *sc = fsm->slave->config;
287  if (sc) {
288  ec_coe_emerg_ring_push(&sc->emerg_ring, data + 2);
289  }
290  }
291 
292  EC_SLAVE_WARN(fsm->slave, "CoE Emergency Request received:\n"
293  "Error code 0x%04X, Error register 0x%02X, data:\n",
294  EC_READ_U16(data + 2), EC_READ_U8(data + 4));
295  ec_print_data(data + 5, 5);
296  return 1;
297 }
298 
299 /*****************************************************************************
300  * CoE dictionary state machine
301  ****************************************************************************/
302 
308  ec_fsm_coe_t *fsm,
309  ec_datagram_t *datagram
310  )
311 {
312  ec_slave_t *slave = fsm->slave;
313  uint8_t *data = ec_slave_mbox_prepare_send(slave, datagram,
314  EC_MBOX_TYPE_COE, 8);
315  if (IS_ERR(data)) {
316  return PTR_ERR(data);
317  }
318 
319  EC_WRITE_U16(data, 0x8 << 12); // SDO information
320  EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
321  EC_WRITE_U8 (data + 3, 0x00);
322  EC_WRITE_U16(data + 4, 0x0000);
323  EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
324 
326  return 0;
327 }
328 
329 /****************************************************************************/
330 
334  ec_fsm_coe_t *fsm,
335  ec_datagram_t *datagram
336  )
337 {
338  ec_slave_t *slave = fsm->slave;
339 
340  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
341  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
342  fsm->state = ec_fsm_coe_error;
343  return;
344  }
345 
346  if (slave->sii.has_general && !slave->sii.coe_details.enable_sdo_info) {
347  EC_SLAVE_ERR(slave, "Slave does not support"
348  " SDO information service!\n");
349  fsm->state = ec_fsm_coe_error;
350  return;
351  }
352 
353  fsm->retries = EC_FSM_RETRIES;
354 
355  if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
356  fsm->state = ec_fsm_coe_error;
357  }
358 }
359 
360 /****************************************************************************/
361 
366  ec_fsm_coe_t *fsm,
367  ec_datagram_t *datagram
368  )
369 {
370  ec_slave_t *slave = fsm->slave;
371 
372  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
373  if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
374  fsm->state = ec_fsm_coe_error;
375  }
376  return;
377  }
378 
379  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
380  fsm->state = ec_fsm_coe_error;
381  EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
382  " request datagram: ");
384  return;
385  }
386 
387  if (fsm->datagram->working_counter != 1) {
388  fsm->state = ec_fsm_coe_error;
389  EC_SLAVE_ERR(slave, "Reception of CoE dictionary request failed: ");
391  return;
392  }
393 
394  fsm->jiffies_start = fsm->datagram->jiffies_sent;
395 
396  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
397  fsm->retries = EC_FSM_RETRIES;
399 }
400 
401 /****************************************************************************/
402 
406  ec_fsm_coe_t *fsm,
407  ec_datagram_t *datagram
408  )
409 {
410  ec_slave_t *slave = fsm->slave;
411 
412  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
413  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
414  return;
415  }
416 
417  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
418  fsm->state = ec_fsm_coe_error;
419  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
421  return;
422  }
423 
424  if (fsm->datagram->working_counter != 1) {
425  fsm->state = ec_fsm_coe_error;
426  EC_SLAVE_ERR(slave,"Reception of CoE mailbox check"
427  " datagram failed: ");
429  return;
430  }
431 
432  if (!ec_slave_mbox_check(fsm->datagram)) {
433  unsigned long diff_ms =
434  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
435  1000 / HZ;
436  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
437  fsm->state = ec_fsm_coe_error;
438  EC_SLAVE_ERR(slave, "Timeout while waiting for"
439  " SDO dictionary list response.\n");
440  return;
441  }
442 
443  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
444  fsm->retries = EC_FSM_RETRIES;
445  return;
446  }
447 
448  // Fetch response
449  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
450  fsm->retries = EC_FSM_RETRIES;
452 }
453 
454 /****************************************************************************/
455 
461  ec_fsm_coe_t *fsm,
462  ec_datagram_t *datagram
463  )
464 {
465  ec_slave_t *slave = fsm->slave;
466  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
467  8);
468  if (IS_ERR(data)) {
469  return PTR_ERR(data);
470  }
471 
472  EC_WRITE_U16(data, 0x8 << 12); // SDO information
473  EC_WRITE_U8 (data + 2, 0x03); // Get object description request
474  EC_WRITE_U8 (data + 3, 0x00);
475  EC_WRITE_U16(data + 4, 0x0000);
476  EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
477 
479  return 0;
480 }
481 
482 /****************************************************************************/
483 
490  ec_fsm_coe_t *fsm,
491  ec_datagram_t *datagram
492  )
493 {
494  ec_slave_t *slave = fsm->slave;
495  uint8_t *data, mbox_prot;
496  size_t rec_size;
497  unsigned int sdo_count, i;
498  uint16_t sdo_index, fragments_left;
499  ec_sdo_t *sdo;
500  bool first_segment;
501  size_t index_list_offset;
502 
503  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
504  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
505  return;
506  }
507 
508  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
509  fsm->state = ec_fsm_coe_error;
510  EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
511  " response datagram: ");
513  return;
514  }
515 
516  if (fsm->datagram->working_counter != 1) {
517  fsm->state = ec_fsm_coe_error;
518  EC_SLAVE_ERR(slave, "Reception of CoE dictionary response failed: ");
520  return;
521  }
522 
523  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
524  if (IS_ERR(data)) {
525  fsm->state = ec_fsm_coe_error;
526  return;
527  }
528 
529  if (mbox_prot != EC_MBOX_TYPE_COE) {
530  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
531  mbox_prot);
532  fsm->state = ec_fsm_coe_error;
533  return;
534  }
535 
536  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
537  // check for CoE response again
538  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
539  fsm->retries = EC_FSM_RETRIES;
541  return;
542  }
543 
544  if (rec_size < 3) {
545  EC_SLAVE_ERR(slave, "Received corrupted SDO dictionary response"
546  " (size %zu).\n", rec_size);
547  fsm->state = ec_fsm_coe_error;
548  return;
549  }
550 
551  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
552  (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
553  EC_SLAVE_ERR(slave, "SDO information error response!\n");
554  if (rec_size < 10) {
555  EC_SLAVE_ERR(slave, "Incomplete SDO information"
556  " error response:\n");
557  ec_print_data(data, rec_size);
558  } else {
559  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
560  }
561  fsm->state = ec_fsm_coe_error;
562  return;
563  }
564 
565  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
566  (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
567  if (fsm->slave->master->debug_level) {
568  EC_SLAVE_DBG(slave, 1, "Invalid SDO list response!"
569  " Retrying...\n");
570  ec_print_data(data, rec_size);
571  }
572  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
573  fsm->retries = EC_FSM_RETRIES;
575  return;
576  }
577 
578  first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
579  index_list_offset = first_segment ? 8 : 6;
580 
581  if (rec_size < index_list_offset || rec_size % 2) {
582  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
583  ec_print_data(data, rec_size);
584  fsm->state = ec_fsm_coe_error;
585  return;
586  }
587 
588  sdo_count = (rec_size - index_list_offset) / 2;
589 
590  for (i = 0; i < sdo_count; i++) {
591  sdo_index = EC_READ_U16(data + index_list_offset + i * 2);
592  if (!sdo_index) {
593  EC_SLAVE_DBG(slave, 1, "SDO dictionary contains index 0x0000.\n");
594  continue;
595  }
596 
597  if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
598  EC_SLAVE_ERR(slave, "Failed to allocate memory for SDO!\n");
599  fsm->state = ec_fsm_coe_error;
600  return;
601  }
602 
603  ec_sdo_init(sdo, slave, sdo_index);
604  list_add_tail(&sdo->list, &slave->sdo_dictionary);
605  }
606 
607  fragments_left = EC_READ_U16(data + 4);
608  if (fragments_left) {
609  EC_SLAVE_DBG(slave, 1, "SDO list fragments left: %u\n",
610  fragments_left);
611  }
612 
613  if (EC_READ_U8(data + 2) & 0x80 || fragments_left) {
614  // more messages waiting. check again.
615  fsm->jiffies_start = fsm->datagram->jiffies_sent;
616  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
617  fsm->retries = EC_FSM_RETRIES;
619  return;
620  }
621 
622  if (list_empty(&slave->sdo_dictionary)) {
623  // no SDOs in dictionary. finished.
624  fsm->state = ec_fsm_coe_end; // success
625  return;
626  }
627 
628  // fetch SDO descriptions
629  fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);
630 
631  fsm->retries = EC_FSM_RETRIES;
632  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
633  fsm->state = ec_fsm_coe_error;
634  }
635 }
636 
637 /****************************************************************************/
638 
645  ec_fsm_coe_t *fsm,
646  ec_datagram_t *datagram
647  )
648 {
649  ec_slave_t *slave = fsm->slave;
650 
651  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
652  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
653  fsm->state = ec_fsm_coe_error;
654  }
655  return;
656  }
657 
658  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
659  fsm->state = ec_fsm_coe_error;
660  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
661  " description request datagram: ");
663  return;
664  }
665 
666  if (fsm->datagram->working_counter != 1) {
667  fsm->state = ec_fsm_coe_error;
668  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
669  " request failed: ");
671  return;
672  }
673 
674  fsm->jiffies_start = fsm->datagram->jiffies_sent;
675 
676  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
677  fsm->retries = EC_FSM_RETRIES;
679 }
680 
681 /****************************************************************************/
682 
688  ec_fsm_coe_t *fsm,
689  ec_datagram_t *datagram
690  )
691 {
692  ec_slave_t *slave = fsm->slave;
693 
694  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
695  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
696  return;
697  }
698 
699  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
700  fsm->state = ec_fsm_coe_error;
701  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
703  return;
704  }
705 
706  if (fsm->datagram->working_counter != 1) {
707  fsm->state = ec_fsm_coe_error;
708  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
709  " datagram failed: ");
711  return;
712  }
713 
714  if (!ec_slave_mbox_check(fsm->datagram)) {
715  unsigned long diff_ms =
716  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
717  1000 / HZ;
718  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
719  fsm->state = ec_fsm_coe_error;
720  EC_SLAVE_ERR(slave, "Timeout while waiting for"
721  " SDO 0x%04x object description response.\n",
722  fsm->sdo->index);
723  return;
724  }
725 
726  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
727  fsm->retries = EC_FSM_RETRIES;
728  return;
729  }
730 
731  // Fetch response
732  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
733  fsm->retries = EC_FSM_RETRIES;
735 }
736 
737 /****************************************************************************/
738 
744  ec_fsm_coe_t *fsm,
745  ec_datagram_t *datagram
746  )
747 {
748  ec_slave_t *slave = fsm->slave;
749  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
750  10);
751  if (IS_ERR(data)) {
752  return PTR_ERR(data);
753  }
754 
755  EC_WRITE_U16(data, 0x8 << 12); // SDO information
756  EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
757  EC_WRITE_U8 (data + 3, 0x00);
758  EC_WRITE_U16(data + 4, 0x0000);
759  EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
760  EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
761  EC_WRITE_U8 (data + 9, 0x01); // value info (access rights only)
762 
764  return 0;
765 }
766 
767 /****************************************************************************/
768 
775  ec_fsm_coe_t *fsm,
776  ec_datagram_t *datagram
777  )
778 {
779  ec_slave_t *slave = fsm->slave;
780  ec_sdo_t *sdo = fsm->sdo;
781  uint8_t *data, mbox_prot;
782  size_t rec_size, name_size;
783 
784  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
785  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
786  return;
787  }
788 
789  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
790  fsm->state = ec_fsm_coe_error;
791  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description"
792  " response datagram: ");
794  return;
795  }
796 
797  if (fsm->datagram->working_counter != 1) {
798  fsm->state = ec_fsm_coe_error;
799  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
800  " response failed: ");
802  return;
803  }
804 
805  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
806  if (IS_ERR(data)) {
807  fsm->state = ec_fsm_coe_error;
808  return;
809  }
810 
811  if (mbox_prot != EC_MBOX_TYPE_COE) {
812  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
813  mbox_prot);
814  fsm->state = ec_fsm_coe_error;
815  return;
816  }
817 
818  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
819  // check for CoE response again
820  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
821  fsm->retries = EC_FSM_RETRIES;
823  return;
824  }
825 
826  if (rec_size < 3) {
827  EC_SLAVE_ERR(slave, "Received corrupted SDO description response"
828  " (size %zu).\n", rec_size);
829  fsm->state = ec_fsm_coe_error;
830  return;
831  }
832 
833  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
834  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
835  EC_SLAVE_ERR(slave, "SDO information error response while"
836  " fetching SDO 0x%04X!\n", sdo->index);
837  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
838  fsm->state = ec_fsm_coe_error;
839  return;
840  }
841 
842  if (rec_size < 8) {
843  EC_SLAVE_ERR(slave, "Received corrupted SDO"
844  " description response (size %zu).\n", rec_size);
845  fsm->state = ec_fsm_coe_error;
846  return;
847  }
848 
849  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
850  (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response
851  EC_READ_U16(data + 6) != sdo->index) { // SDO index
852  if (fsm->slave->master->debug_level) {
853  EC_SLAVE_DBG(slave, 1, "Invalid object description response while"
854  " fetching SDO 0x%04X!\n", sdo->index);
855  ec_print_data(data, rec_size);
856  }
857  // check for CoE response again
858  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
859  fsm->retries = EC_FSM_RETRIES;
861  return;
862  }
863 
864  if (rec_size < 12) {
865  EC_SLAVE_ERR(slave, "Invalid data size!\n");
866  ec_print_data(data, rec_size);
867  fsm->state = ec_fsm_coe_error;
868  return;
869  }
870 
871  sdo->max_subindex = EC_READ_U8(data + 10);
872  sdo->object_code = EC_READ_U8(data + 11);
873 
874  name_size = rec_size - 12;
875  if (name_size) {
876  if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) {
877  EC_SLAVE_ERR(slave, "Failed to allocate SDO name!\n");
878  fsm->state = ec_fsm_coe_error;
879  return;
880  }
881 
882  memcpy(sdo->name, data + 12, name_size);
883  sdo->name[name_size] = 0;
884  }
885 
886  if (EC_READ_U8(data + 2) & 0x80) {
887  EC_SLAVE_ERR(slave, "Fragment follows (not implemented)!\n");
888  fsm->state = ec_fsm_coe_error;
889  return;
890  }
891 
892  // start fetching entries
893 
894  fsm->subindex = 0;
895  fsm->retries = EC_FSM_RETRIES;
896 
897  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
898  fsm->state = ec_fsm_coe_error;
899  }
900 }
901 
902 /****************************************************************************/
903 
910  ec_fsm_coe_t *fsm,
911  ec_datagram_t *datagram
912  )
913 {
914  ec_slave_t *slave = fsm->slave;
915 
916  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
917  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
918  fsm->state = ec_fsm_coe_error;
919  }
920  return;
921  }
922 
923  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
924  fsm->state = ec_fsm_coe_error;
925  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry"
926  " request datagram: ");
928  return;
929  }
930 
931  if (fsm->datagram->working_counter != 1) {
932  fsm->state = ec_fsm_coe_error;
933  EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: ");
935  return;
936  }
937 
938  fsm->jiffies_start = fsm->datagram->jiffies_sent;
939 
940  ec_slave_mbox_prepare_check(slave, datagram); // can not fail
941  fsm->retries = EC_FSM_RETRIES;
943 }
944 
945 /****************************************************************************/
946 
952  ec_fsm_coe_t *fsm,
953  ec_datagram_t *datagram
954  )
955 {
956  ec_slave_t *slave = fsm->slave;
957 
958  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
959  ec_slave_mbox_prepare_check(slave, datagram); // can not fail
960  return;
961  }
962 
963  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
964  fsm->state = ec_fsm_coe_error;
965  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
967  return;
968  }
969 
970  if (fsm->datagram->working_counter != 1) {
971  fsm->state = ec_fsm_coe_error;
972  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
973  " datagram failed: ");
975  return;
976  }
977 
978  if (!ec_slave_mbox_check(fsm->datagram)) {
979  unsigned long diff_ms =
980  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
981  1000 / HZ;
982  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
983  fsm->state = ec_fsm_coe_error;
984  EC_SLAVE_ERR(slave, "Timeout while waiting for"
985  " SDO entry 0x%04x:%x description response.\n",
986  fsm->sdo->index, fsm->subindex);
987  return;
988  }
989 
990  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
991  fsm->retries = EC_FSM_RETRIES;
992  return;
993  }
994 
995  // Fetch response
996  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
997  fsm->retries = EC_FSM_RETRIES;
999 }
1000 
1001 /****************************************************************************/
1002 
1009  ec_fsm_coe_t *fsm,
1010  ec_datagram_t *datagram
1011  )
1012 {
1013  ec_slave_t *slave = fsm->slave;
1014  ec_sdo_t *sdo = fsm->sdo;
1015  uint8_t *data, mbox_prot;
1016  size_t rec_size, data_size;
1017  ec_sdo_entry_t *entry;
1018  u16 word;
1019 
1020  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1021  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1022  return;
1023  }
1024 
1025  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1026  fsm->state = ec_fsm_coe_error;
1027  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
1028  " description response datagram: ");
1030  return;
1031  }
1032 
1033  if (fsm->datagram->working_counter != 1) {
1034  fsm->state = ec_fsm_coe_error;
1035  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
1036  " response failed: ");
1038  return;
1039  }
1040 
1041  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1042  if (IS_ERR(data)) {
1043  fsm->state = ec_fsm_coe_error;
1044  return;
1045  }
1046 
1047  if (mbox_prot != EC_MBOX_TYPE_COE) {
1048  EC_SLAVE_ERR(slave, "Received mailbox protocol"
1049  " 0x%02X as response.\n", mbox_prot);
1050  fsm->state = ec_fsm_coe_error;
1051  return;
1052  }
1053 
1054  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1055  // check for CoE response again
1056  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1057  fsm->retries = EC_FSM_RETRIES;
1059  return;
1060  }
1061 
1062  if (rec_size < 3) {
1063  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1064  " description response (size %zu).\n", rec_size);
1065  fsm->state = ec_fsm_coe_error;
1066  return;
1067  }
1068 
1069  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
1070  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
1071  EC_SLAVE_WARN(slave, "SDO information error response while"
1072  " fetching SDO entry 0x%04X:%02X!\n",
1073  sdo->index, fsm->subindex);
1074  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
1075 
1076  /* There may be gaps in the subindices, so try to continue with next
1077  * subindex. */
1078 
1079  } else {
1080 
1081  if (rec_size < 9) {
1082  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1083  " description response (size %zu).\n", rec_size);
1084  fsm->state = ec_fsm_coe_error;
1085  return;
1086  }
1087 
1088  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
1089  (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
1090  EC_READ_U16(data + 6) != sdo->index || // SDO index
1091  EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex
1092  if (fsm->slave->master->debug_level) {
1093  EC_SLAVE_DBG(slave, 1, "Invalid entry description response"
1094  " while fetching SDO entry 0x%04X:%02X!\n",
1095  sdo->index, fsm->subindex);
1096  ec_print_data(data, rec_size);
1097  }
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 < 16) {
1106  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
1107  ec_print_data(data, rec_size);
1108  fsm->state = ec_fsm_coe_error;
1109  return;
1110  }
1111 
1112  data_size = rec_size - 16;
1113 
1114  if (!(entry = (ec_sdo_entry_t *)
1115  kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) {
1116  EC_SLAVE_ERR(slave, "Failed to allocate entry!\n");
1117  fsm->state = ec_fsm_coe_error;
1118  return;
1119  }
1120 
1121  ec_sdo_entry_init(entry, sdo, fsm->subindex);
1122  entry->data_type = EC_READ_U16(data + 10);
1123  entry->bit_length = EC_READ_U16(data + 12);
1124 
1125  // read access rights
1126  word = EC_READ_U16(data + 14);
1127  entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001;
1129  (word >> 1) & 0x0001;
1130  entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001;
1131  entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001;
1133  (word >> 4) & 0x0001;
1134  entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001;
1135 
1136  if (data_size) {
1137  uint8_t *desc;
1138  if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) {
1139  EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n");
1140  fsm->state = ec_fsm_coe_error;
1141  return;
1142  }
1143  memcpy(desc, data + 16, data_size);
1144  desc[data_size] = 0;
1145  entry->description = desc;
1146  }
1147 
1148  list_add_tail(&entry->list, &sdo->entries);
1149  }
1150 
1151  if (fsm->subindex < sdo->max_subindex) {
1152 
1153  fsm->subindex++;
1154  fsm->retries = EC_FSM_RETRIES;
1155 
1156  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1157  fsm->state = ec_fsm_coe_error;
1158  }
1159 
1160  return;
1161  }
1162 
1163  // another SDO description to fetch?
1164  if (fsm->sdo->list.next != &slave->sdo_dictionary) {
1165 
1166  fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
1167  fsm->retries = EC_FSM_RETRIES;
1168 
1169  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
1170  fsm->state = ec_fsm_coe_error;
1171  }
1172 
1173  return;
1174  }
1175 
1176  fsm->state = ec_fsm_coe_end;
1177 }
1178 
1179 /*****************************************************************************
1180  * CoE state machine
1181  ****************************************************************************/
1182 
1188  ec_fsm_coe_t *fsm,
1189  ec_datagram_t *datagram
1190  )
1191 {
1192  u8 *data;
1193  ec_slave_t *slave = fsm->slave;
1194  ec_sdo_request_t *request = fsm->request;
1195  uint8_t data_set_size;
1196 
1197  if (request->data_size > 0 && request->data_size <= 4) {
1198  // use expedited transfer mode for lengths between 1 and 4 bytes
1199  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1201  if (IS_ERR(data)) {
1202  request->errno = PTR_ERR(data);
1203  return PTR_ERR(data);
1204  }
1205 
1206  fsm->remaining = 0;
1207 
1208  data_set_size = 4 - request->data_size;
1209 
1210  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1211  EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
1212  | data_set_size << 2
1213  | ((request->complete_access ? 1 : 0) << 4)
1214  | 0x1 << 5)); // Download request
1215  EC_WRITE_U16(data + 3, request->index);
1216  EC_WRITE_U8 (data + 5,
1217  request->complete_access ? 0x00 : request->subindex);
1218  memcpy(data + 6, request->data, request->data_size);
1219  memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);
1220 
1221  if (slave->master->debug_level) {
1222  EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
1224  }
1225  }
1226  else { // data_size < 1 or data_size > 4, use normal transfer type
1227  size_t data_size,
1228  max_data_size =
1230  required_data_size =
1232 
1233  if (max_data_size < required_data_size) {
1234  // segmenting needed
1235  data_size = max_data_size;
1236  } else {
1237  data_size = required_data_size;
1238  }
1239 
1240  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1241  data_size);
1242  if (IS_ERR(data)) {
1243  request->errno = PTR_ERR(data);
1244  return PTR_ERR(data);
1245  }
1246 
1247  fsm->offset = 0;
1248  fsm->remaining = request->data_size;
1249 
1250  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1251  EC_WRITE_U8(data + 2,
1252  0x1 // size indicator, normal
1253  | ((request->complete_access ? 1 : 0) << 4)
1254  | 0x1 << 5); // Download request
1255  EC_WRITE_U16(data + 3, request->index);
1256  EC_WRITE_U8 (data + 5,
1257  request->complete_access ? 0x00 : request->subindex);
1258  EC_WRITE_U32(data + 6, request->data_size);
1259 
1260  if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
1261  size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
1262  memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
1263  request->data, segment_size);
1264  fsm->offset += segment_size;
1265  fsm->remaining -= segment_size;
1266  }
1267 
1268  if (slave->master->debug_level) {
1269  EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
1270  ec_print_data(data, data_size);
1271  }
1272  }
1273 
1275  return 0;
1276 }
1277 
1278 /****************************************************************************/
1279 
1283  ec_fsm_coe_t *fsm,
1284  ec_datagram_t *datagram
1285  )
1286 {
1287  ec_slave_t *slave = fsm->slave;
1288  ec_sdo_request_t *request = fsm->request;
1289 
1290  if (fsm->slave->master->debug_level) {
1291  char subidxstr[10];
1292  if (request->complete_access) {
1293  subidxstr[0] = 0x00;
1294  } else {
1295  sprintf(subidxstr, ":%02X", request->subindex);
1296  }
1297  EC_SLAVE_DBG(slave, 1, "Downloading SDO 0x%04X%s.\n",
1298  request->index, subidxstr);
1299  ec_print_data(request->data, request->data_size);
1300  }
1301 
1302  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1303  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1304  request->errno = EPROTONOSUPPORT;
1305  fsm->state = ec_fsm_coe_error;
1306  return;
1307  }
1308 
1309  if (slave->configured_rx_mailbox_size <
1311  EC_SLAVE_ERR(slave, "Mailbox too small!\n");
1312  request->errno = ENOBUFS;
1313  fsm->state = ec_fsm_coe_error;
1314  return;
1315  }
1316 
1317 
1318  fsm->request->jiffies_sent = jiffies;
1319  fsm->retries = EC_FSM_RETRIES;
1320 
1321  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1322  fsm->state = ec_fsm_coe_error;
1323  }
1324 }
1325 
1326 /****************************************************************************/
1327 
1334  ec_fsm_coe_t *fsm,
1335  ec_datagram_t *datagram
1336  )
1337 {
1338  ec_slave_t *slave = fsm->slave;
1339  unsigned long diff_ms;
1340 
1341  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1342  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1343  fsm->state = ec_fsm_coe_error;
1344  }
1345  return;
1346  }
1347 
1348  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1349  fsm->request->errno = EIO;
1350  fsm->state = ec_fsm_coe_error;
1351  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1352  " request datagram: ");
1354  return;
1355  }
1356 
1357  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1358 
1359  if (fsm->datagram->working_counter != 1) {
1360  if (!fsm->datagram->working_counter) {
1361  if (diff_ms < fsm->request->response_timeout) {
1362 #if DEBUG_RETRIES
1363  EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
1364  " download request. Retrying after %lu ms...\n",
1365  diff_ms);
1366 #endif
1367  // no response; send request datagram again
1368  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1369  fsm->state = ec_fsm_coe_error;
1370  }
1371  return;
1372  }
1373  }
1374  fsm->request->errno = EIO;
1375  fsm->state = ec_fsm_coe_error;
1376  EC_SLAVE_ERR(slave, "Reception of CoE download request"
1377  " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
1378  fsm->request->index, fsm->request->subindex, diff_ms);
1380  return;
1381  }
1382 
1383 #if DEBUG_LONG
1384  if (diff_ms > 200) {
1385  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
1386  fsm->request->index, fsm->request->subindex, diff_ms);
1387  }
1388 #endif
1389 
1390  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1391 
1392  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1393  fsm->retries = EC_FSM_RETRIES;
1395 }
1396 
1397 /****************************************************************************/
1398 
1402  ec_fsm_coe_t *fsm,
1403  ec_datagram_t *datagram
1404  )
1405 {
1406  ec_slave_t *slave = fsm->slave;
1407 
1408  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1409  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1410  return;
1411  }
1412 
1413  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1414  fsm->request->errno = EIO;
1415  fsm->state = ec_fsm_coe_error;
1416  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
1417  " datagram: ");
1419  return;
1420  }
1421 
1422  if (fsm->datagram->working_counter != 1) {
1423  fsm->request->errno = EIO;
1424  fsm->state = ec_fsm_coe_error;
1425  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1426  " datagram failed: ");
1428  return;
1429  }
1430 
1431  if (!ec_slave_mbox_check(fsm->datagram)) {
1432  unsigned long diff_ms =
1433  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1434  1000 / HZ;
1435  if (diff_ms >= fsm->request->response_timeout) {
1436  fsm->request->errno = EIO;
1437  fsm->state = ec_fsm_coe_error;
1438  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
1439  " for SDO 0x%04x:%x download response.\n", diff_ms,
1440  fsm->request->index, fsm->request->subindex);
1441  return;
1442  }
1443 
1444  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1445  fsm->retries = EC_FSM_RETRIES;
1446  return;
1447  }
1448 
1449  // Fetch response
1450  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1451  fsm->retries = EC_FSM_RETRIES;
1453 }
1454 
1455 /****************************************************************************/
1456 
1460  ec_fsm_coe_t *fsm,
1461  ec_datagram_t *datagram
1462  )
1463 {
1464  ec_slave_t *slave = fsm->slave;
1465  ec_sdo_request_t *request = fsm->request;
1466  size_t max_segment_size =
1470  size_t data_size;
1471  uint8_t last_segment, seg_data_size, *data;
1472 
1473  if (fsm->remaining > max_segment_size) {
1474  fsm->segment_size = max_segment_size;
1475  last_segment = 0;
1476  } else {
1477  fsm->segment_size = fsm->remaining;
1478  last_segment = 1;
1479  }
1480 
1482  seg_data_size = 0x00;
1483  data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size;
1484  } else {
1485  seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size;
1488  }
1489 
1490  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1491  data_size);
1492  if (IS_ERR(data)) {
1493  request->errno = PTR_ERR(data);
1494  fsm->state = ec_fsm_coe_error;
1495  return;
1496  }
1497 
1498  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1499  EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
1500  | (seg_data_size << 1)
1501  | (fsm->toggle << 4)
1502  | (0x00 << 5)); // Download segment request
1503  memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
1504  request->data + fsm->offset, fsm->segment_size);
1506  memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size,
1508  }
1509 
1510  if (slave->master->debug_level) {
1511  EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
1512  ec_print_data(data, data_size);
1513  }
1514 
1516 }
1517 
1518 /****************************************************************************/
1519 
1526  ec_fsm_coe_t *fsm,
1527  ec_datagram_t *datagram
1528  )
1529 {
1530  ec_slave_t *slave = fsm->slave;
1531  uint8_t *data, mbox_prot;
1532  size_t rec_size;
1533  ec_sdo_request_t *request = fsm->request;
1534 
1535  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1536  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1537  return;
1538  }
1539 
1540  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1541  request->errno = EIO;
1542  fsm->state = ec_fsm_coe_error;
1543  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1544  " response datagram: ");
1546  return;
1547  }
1548 
1549  if (fsm->datagram->working_counter != 1) {
1550  request->errno = EIO;
1551  fsm->state = ec_fsm_coe_error;
1552  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1554  return;
1555  }
1556 
1557  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1558  if (IS_ERR(data)) {
1559  request->errno = PTR_ERR(data);
1560  fsm->state = ec_fsm_coe_error;
1561  return;
1562  }
1563 
1564  if (mbox_prot != EC_MBOX_TYPE_COE) {
1565  request->errno = EIO;
1566  fsm->state = ec_fsm_coe_error;
1567  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1568  mbox_prot);
1569  return;
1570  }
1571 
1572  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1573  // check for CoE response again
1574  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1575  fsm->retries = EC_FSM_RETRIES;
1577  return;
1578  }
1579 
1580  if (slave->master->debug_level) {
1581  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1582  ec_print_data(data, rec_size);
1583  }
1584 
1585  if (rec_size < 6) {
1586  request->errno = EIO;
1587  fsm->state = ec_fsm_coe_error;
1588  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1589  rec_size);
1590  ec_print_data(data, rec_size);
1591  return;
1592  }
1593 
1594  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1595  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1596  char subidxstr[10];
1597  request->errno = EIO;
1598  fsm->state = ec_fsm_coe_error;
1599  if (request->complete_access) {
1600  subidxstr[0] = 0x00;
1601  } else {
1602  sprintf(subidxstr, ":%02X", request->subindex);
1603  }
1604  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1605  request->index, subidxstr, request->data_size);
1606  if (rec_size < 10) {
1607  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1608  ec_print_data(data, rec_size);
1609  } else {
1610  fsm->request->abort_code = EC_READ_U32(data + 6);
1611  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1612  }
1613  return;
1614  }
1615 
1616  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
1617  EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
1618  EC_READ_U16(data + 3) != request->index || // index
1619  EC_READ_U8 (data + 5) != request->subindex) { // subindex
1620  if (slave->master->debug_level) {
1621  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1622  " Retrying...\n");
1623  ec_print_data(data, rec_size);
1624  }
1625  // check for CoE response again
1626  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1627  fsm->retries = EC_FSM_RETRIES;
1629  return;
1630  }
1631 
1632  if (fsm->remaining) { // more segments to download
1633  fsm->toggle = 0;
1635  } else {
1636  fsm->state = ec_fsm_coe_end; // success
1637  }
1638 }
1639 
1640 /****************************************************************************/
1641 
1647  ec_fsm_coe_t *fsm,
1648  ec_datagram_t *datagram
1649  )
1650 {
1651  ec_slave_t *slave = fsm->slave;
1652 
1653  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1654  return;
1655 
1656  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1657  fsm->request->errno = EIO;
1658  fsm->state = ec_fsm_coe_error;
1659  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1661  return;
1662  }
1663 
1664  if (fsm->datagram->working_counter != 1) {
1665  fsm->request->errno = EIO;
1666  fsm->state = ec_fsm_coe_error;
1667  EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
1668  " datagram failed: ");
1670  return;
1671  }
1672 
1673  if (!ec_slave_mbox_check(fsm->datagram)) {
1674  unsigned long diff_ms =
1675  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1676  1000 / HZ;
1677  if (diff_ms >= fsm->request->response_timeout) {
1678  fsm->request->errno = EIO;
1679  fsm->state = ec_fsm_coe_error;
1680  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
1681  " segment response.\n");
1682  return;
1683  }
1684 
1685  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1686  fsm->retries = EC_FSM_RETRIES;
1687  return;
1688  }
1689 
1690  // Fetch response
1691  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1692  fsm->retries = EC_FSM_RETRIES;
1694 }
1695 
1696 /****************************************************************************/
1697 
1704  ec_fsm_coe_t *fsm,
1705  ec_datagram_t *datagram
1706  )
1707 {
1708  ec_slave_t *slave = fsm->slave;
1709  uint8_t *data, mbox_prot;
1710  size_t rec_size;
1711  ec_sdo_request_t *request = fsm->request;
1712 
1713  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1714  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1715  return;
1716  }
1717 
1718  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1719  request->errno = EIO;
1720  fsm->state = ec_fsm_coe_error;
1721  EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
1722  " datagram: ");
1724  return;
1725  }
1726 
1727  if (fsm->datagram->working_counter != 1) {
1728  request->errno = EIO;
1729  fsm->state = ec_fsm_coe_error;
1730  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1732  return;
1733  }
1734 
1735  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1736  if (IS_ERR(data)) {
1737  request->errno = PTR_ERR(data);
1738  fsm->state = ec_fsm_coe_error;
1739  return;
1740  }
1741 
1742  if (mbox_prot != EC_MBOX_TYPE_COE) {
1743  request->errno = EIO;
1744  fsm->state = ec_fsm_coe_error;
1745  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1746  mbox_prot);
1747  return;
1748  }
1749 
1750  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1751  // check for CoE response again
1752  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1753  fsm->retries = EC_FSM_RETRIES;
1755  return;
1756  }
1757 
1758  if (slave->master->debug_level) {
1759  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1760  ec_print_data(data, rec_size);
1761  }
1762 
1763  if (rec_size < 6) {
1764  request->errno = EIO;
1765  fsm->state = ec_fsm_coe_error;
1766  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1767  rec_size);
1768  ec_print_data(data, rec_size);
1769  return;
1770  }
1771 
1772  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1773  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1774  char subidxstr[10];
1775  request->errno = EIO;
1776  fsm->state = ec_fsm_coe_error;
1777  if (request->complete_access) {
1778  subidxstr[0] = 0x00;
1779  } else {
1780  sprintf(subidxstr, ":%02X", request->subindex);
1781  }
1782  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1783  request->index, subidxstr, request->data_size);
1784  if (rec_size < 10) {
1785  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1786  ec_print_data(data, rec_size);
1787  } else {
1788  fsm->request->abort_code = EC_READ_U32(data + 6);
1789  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1790  }
1791  return;
1792  }
1793 
1794  if (EC_READ_U16(data) >> 12 != 0x3 ||
1795  ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response
1796  if (slave->master->debug_level) {
1797  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1798  " Retrying...\n");
1799  ec_print_data(data, rec_size);
1800  }
1801  // check for CoE response again
1802  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1803  fsm->retries = EC_FSM_RETRIES;
1805  return;
1806  }
1807 
1808  if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) {
1809  EC_SLAVE_ERR(slave, "Invalid toggle received during"
1810  " segmented download:\n");
1811  ec_print_data(data, rec_size);
1812  request->errno = EIO;
1813  fsm->state = ec_fsm_coe_error;
1814  return;
1815  }
1816 
1817  fsm->offset += fsm->segment_size;
1818  fsm->remaining -= fsm->segment_size;
1819 
1820  if (fsm->remaining) { // more segments to download
1821  fsm->toggle = !fsm->toggle;
1823  } else {
1824  fsm->state = ec_fsm_coe_end; // success
1825  }
1826 }
1827 
1828 /****************************************************************************/
1829 
1835  ec_fsm_coe_t *fsm,
1836  ec_datagram_t *datagram
1837  )
1838 {
1839  ec_slave_t *slave = fsm->slave;
1840  ec_sdo_request_t *request = fsm->request;
1841  ec_master_t *master = slave->master;
1842 
1843  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1844  10);
1845  if (IS_ERR(data)) {
1846  request->errno = PTR_ERR(data);
1847  return PTR_ERR(data);
1848  }
1849 
1850  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1851  EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
1852  EC_WRITE_U16(data + 3, request->index);
1853  EC_WRITE_U8 (data + 5, request->subindex);
1854  memset(data + 6, 0x00, 4);
1855 
1856  if (master->debug_level) {
1857  EC_SLAVE_DBG(slave, 1, "Upload request:\n");
1858  ec_print_data(data, 10);
1859  }
1860 
1862  return 0;
1863 }
1864 
1865 /****************************************************************************/
1866 
1872  ec_fsm_coe_t *fsm,
1873  ec_datagram_t *datagram
1874  )
1875 {
1876  ec_slave_t *slave = fsm->slave;
1877  ec_sdo_request_t *request = fsm->request;
1878 
1879  EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n",
1880  request->index, request->subindex);
1881 
1882  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1883  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1884  request->errno = EPROTONOSUPPORT;
1885  fsm->state = ec_fsm_coe_error;
1886  return;
1887  }
1888 
1889  fsm->retries = EC_FSM_RETRIES;
1890  fsm->request->jiffies_sent = jiffies;
1891 
1892  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1893  fsm->state = ec_fsm_coe_error;
1894  }
1895 }
1896 
1897 /****************************************************************************/
1904  ec_fsm_coe_t *fsm,
1905  ec_datagram_t *datagram
1906  )
1907 {
1908  ec_slave_t *slave = fsm->slave;
1909  unsigned long diff_ms;
1910 
1911  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1912  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1913  fsm->state = ec_fsm_coe_error;
1914  }
1915  return;
1916  }
1917 
1918  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1919  fsm->request->errno = EIO;
1920  fsm->state = ec_fsm_coe_error;
1921  EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
1923  return;
1924  }
1925 
1926  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1927 
1928  if (fsm->datagram->working_counter != 1) {
1929  if (!fsm->datagram->working_counter) {
1930  if (diff_ms < fsm->request->response_timeout) {
1931 #if DEBUG_RETRIES
1932  EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
1933  " SDO upload request. Retrying after %lu ms...\n",
1934  diff_ms);
1935 #endif
1936  // no response; send request datagram again
1937  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1938  fsm->state = ec_fsm_coe_error;
1939  }
1940  return;
1941  }
1942  }
1943  fsm->request->errno = EIO;
1944  fsm->state = ec_fsm_coe_error;
1945  EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
1946  " SDO 0x%04x:%x failed with timeout after %lu ms: ",
1947  fsm->request->index, fsm->request->subindex, diff_ms);
1949  return;
1950  }
1951 
1952 #if DEBUG_LONG
1953  if (diff_ms > 200) {
1954  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %lu ms.\n",
1955  fsm->request->index, fsm->request->subindex, diff_ms);
1956  }
1957 #endif
1958 
1959  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1960 
1961  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1962  fsm->retries = EC_FSM_RETRIES;
1963  fsm->state = ec_fsm_coe_up_check;
1964 }
1965 
1966 /****************************************************************************/
1967 
1973  ec_fsm_coe_t *fsm,
1974  ec_datagram_t *datagram
1975  )
1976 {
1977  ec_slave_t *slave = fsm->slave;
1978 
1979  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1980  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1981  return;
1982  }
1983 
1984  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1985  fsm->request->errno = EIO;
1986  fsm->state = ec_fsm_coe_error;
1987  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1989  return;
1990  }
1991 
1992  if (fsm->datagram->working_counter != 1) {
1993  fsm->request->errno = EIO;
1994  fsm->state = ec_fsm_coe_error;
1995  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1996  " datagram failed: ");
1998  return;
1999  }
2000 
2001  if (!ec_slave_mbox_check(fsm->datagram)) {
2002  unsigned long diff_ms =
2003  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2004  1000 / HZ;
2005  if (diff_ms >= fsm->request->response_timeout) {
2006  fsm->request->errno = EIO;
2007  fsm->state = ec_fsm_coe_error;
2008  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
2009  " SDO 0x%04x:%x upload response.\n", diff_ms,
2010  fsm->request->index, fsm->request->subindex);
2011  return;
2012  }
2013 
2014  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2015  fsm->retries = EC_FSM_RETRIES;
2016  return;
2017  }
2018 
2019  // Fetch response
2020  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2021  fsm->retries = EC_FSM_RETRIES;
2023 }
2024 
2025 /****************************************************************************/
2026 
2030  ec_fsm_coe_t *fsm,
2031  ec_datagram_t *datagram
2032  )
2033 {
2034  uint8_t *data =
2035  ec_slave_mbox_prepare_send(fsm->slave, datagram, EC_MBOX_TYPE_COE,
2036  10);
2037  if (IS_ERR(data)) {
2038  fsm->request->errno = PTR_ERR(data);
2039  fsm->state = ec_fsm_coe_error;
2040  return;
2041  }
2042 
2043  EC_WRITE_U16(data, 0x2 << 12); // SDO request
2044  EC_WRITE_U8 (data + 2, (fsm->toggle << 4 // toggle
2045  | 0x3 << 5)); // upload segment request
2046  memset(data + 3, 0x00, 7);
2047 
2048  if (fsm->slave->master->debug_level) {
2049  EC_SLAVE_DBG(fsm->slave, 1, "Upload segment request:\n");
2050  ec_print_data(data, 10);
2051  }
2052 }
2053 
2054 /****************************************************************************/
2055 
2062  ec_fsm_coe_t *fsm,
2063  ec_datagram_t *datagram
2064  )
2065 {
2066  ec_slave_t *slave = fsm->slave;
2067  ec_master_t *master = slave->master;
2068  uint16_t rec_index;
2069  uint8_t *data, mbox_prot, rec_subindex;
2070  size_t rec_size, data_size;
2071  ec_sdo_request_t *request = fsm->request;
2072  unsigned int expedited, size_specified;
2073  int ret;
2074 
2075  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2076  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2077  return;
2078  }
2079 
2080  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2081  request->errno = EIO;
2082  fsm->state = ec_fsm_coe_error;
2083  EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
2084  " datagram: ");
2086  return;
2087  }
2088 
2089  if (fsm->datagram->working_counter != 1) {
2090  request->errno = EIO;
2091  fsm->state = ec_fsm_coe_error;
2092  EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
2094  return;
2095  }
2096 
2097  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2098  if (IS_ERR(data)) {
2099  request->errno = PTR_ERR(data);
2100  fsm->state = ec_fsm_coe_error;
2101  return;
2102  }
2103 
2104  if (master->debug_level) {
2105  EC_SLAVE_DBG(slave, 1, "Upload response:\n");
2106  ec_print_data(data, rec_size);
2107  }
2108 
2109  if (mbox_prot != EC_MBOX_TYPE_COE) {
2110  request->errno = EIO;
2111  fsm->state = ec_fsm_coe_error;
2112  EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
2113  " as response.\n", mbox_prot);
2114  return;
2115  }
2116 
2117  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2118  // check for CoE response again
2119  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2120  fsm->retries = EC_FSM_RETRIES;
2121  fsm->state = ec_fsm_coe_up_check;
2122  return;
2123  }
2124 
2125  if (rec_size < 6) {
2126  request->errno = EIO;
2127  fsm->state = ec_fsm_coe_error;
2128  EC_SLAVE_ERR(slave, "Received currupted SDO upload response"
2129  " (%zu bytes)!\n", rec_size);
2130  ec_print_data(data, rec_size);
2131  return;
2132  }
2133 
2134  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2135  EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request
2136  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2137  request->index, request->subindex);
2138  if (rec_size >= 10) {
2139  request->abort_code = EC_READ_U32(data + 6);
2140  ec_canopen_abort_msg(slave, request->abort_code);
2141  } else {
2142  EC_SLAVE_ERR(slave, "No abort message.\n");
2143  }
2144  request->errno = EIO;
2145  fsm->state = ec_fsm_coe_error;
2146  return;
2147  }
2148 
2149  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2150  EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response
2151  EC_SLAVE_ERR(slave, "Received unknown response while"
2152  " uploading SDO 0x%04X:%02X.\n",
2153  request->index, request->subindex);
2154  ec_print_data(data, rec_size);
2155  request->errno = EIO;
2156  fsm->state = ec_fsm_coe_error;
2157  return;
2158  }
2159 
2160  rec_index = EC_READ_U16(data + 3);
2161  rec_subindex = EC_READ_U8(data + 5);
2162 
2163  if (rec_index != request->index || rec_subindex != request->subindex) {
2164  EC_SLAVE_ERR(slave, "Received upload response for wrong SDO"
2165  " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
2166  rec_index, rec_subindex, request->index, request->subindex);
2167  ec_print_data(data, rec_size);
2168 
2169  // check for CoE response again
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 
2176  // normal or expedited?
2177  expedited = EC_READ_U8(data + 2) & 0x02;
2178 
2179  if (expedited) {
2180  size_specified = EC_READ_U8(data + 2) & 0x01;
2181  if (size_specified) {
2182  fsm->complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
2183  } else {
2184  fsm->complete_size = 4;
2185  }
2186 
2187  if (rec_size < 6 + fsm->complete_size) {
2188  request->errno = EIO;
2189  fsm->state = ec_fsm_coe_error;
2190  EC_SLAVE_ERR(slave, "Received corrupted SDO expedited upload"
2191  " response (only %zu bytes)!\n", rec_size);
2192  ec_print_data(data, rec_size);
2193  return;
2194  }
2195 
2196  ret = ec_sdo_request_copy_data(request, data + 6, fsm->complete_size);
2197  if (ret) {
2198  request->errno = -ret;
2199  fsm->state = ec_fsm_coe_error;
2200  return;
2201  }
2202  } else { // normal
2203  if (rec_size < 10) {
2204  request->errno = EIO;
2205  fsm->state = ec_fsm_coe_error;
2206  EC_SLAVE_ERR(slave, "Received currupted SDO normal upload"
2207  " response (only %zu bytes)!\n", rec_size);
2208  ec_print_data(data, rec_size);
2209  return;
2210  }
2211 
2212  data_size = rec_size - 10;
2213  fsm->complete_size = EC_READ_U32(data + 6);
2214 
2215  ret = ec_sdo_request_alloc(request, fsm->complete_size);
2216  if (ret) {
2217  request->errno = -ret;
2218  fsm->state = ec_fsm_coe_error;
2219  return;
2220  }
2221 
2222  ret = ec_sdo_request_copy_data(request, data + 10, data_size);
2223  if (ret) {
2224  request->errno = -ret;
2225  fsm->state = ec_fsm_coe_error;
2226  return;
2227  }
2228 
2229  fsm->toggle = 0;
2230 
2231  if (data_size < fsm->complete_size) {
2232  EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
2233  " Segmenting...\n", data_size, fsm->complete_size);
2235  fsm->retries = EC_FSM_RETRIES;
2237  return;
2238  }
2239  }
2240 
2241  if (master->debug_level) {
2242  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2243  ec_print_data(request->data, request->data_size);
2244  }
2245 
2246  fsm->state = ec_fsm_coe_end; // success
2247 }
2248 
2249 /****************************************************************************/
2250 
2257  ec_fsm_coe_t *fsm,
2258  ec_datagram_t *datagram
2259  )
2260 {
2261  ec_slave_t *slave = fsm->slave;
2262 
2263  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2265  return;
2266  }
2267 
2268  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2269  fsm->request->errno = EIO;
2270  fsm->state = ec_fsm_coe_error;
2271  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2272  " request datagram: ");
2274  return;
2275  }
2276 
2277  if (fsm->datagram->working_counter != 1) {
2278  fsm->request->errno = EIO;
2279  fsm->state = ec_fsm_coe_error;
2280  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2281  " request failed: ");
2283  return;
2284  }
2285 
2286  fsm->jiffies_start = fsm->datagram->jiffies_sent;
2287 
2288  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2289  fsm->retries = EC_FSM_RETRIES;
2291 }
2292 
2293 /****************************************************************************/
2294 
2300  ec_fsm_coe_t *fsm,
2301  ec_datagram_t *datagram
2302  )
2303 {
2304  ec_slave_t *slave = fsm->slave;
2305 
2306  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2307  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2308  return;
2309  }
2310 
2311  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2312  fsm->request->errno = EIO;
2313  fsm->state = ec_fsm_coe_error;
2314  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
2315  " datagram: ");
2317  return;
2318  }
2319 
2320  if (fsm->datagram->working_counter != 1) {
2321  fsm->request->errno = EIO;
2322  fsm->state = ec_fsm_coe_error;
2323  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
2324  " failed: ");
2326  return;
2327  }
2328 
2329  if (!ec_slave_mbox_check(fsm->datagram)) {
2330  unsigned long diff_ms =
2331  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2332  1000 / HZ;
2333  if (diff_ms >= fsm->request->response_timeout) {
2334  fsm->request->errno = EIO;
2335  fsm->state = ec_fsm_coe_error;
2336  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
2337  " segment response.\n");
2338  return;
2339  }
2340 
2341  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2342  fsm->retries = EC_FSM_RETRIES;
2343  return;
2344  }
2345 
2346  // Fetch response
2347  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2348  fsm->retries = EC_FSM_RETRIES;
2350 }
2351 
2352 /****************************************************************************/
2353 
2360  ec_fsm_coe_t *fsm,
2361  ec_datagram_t *datagram
2362  )
2363 {
2364  ec_slave_t *slave = fsm->slave;
2365  ec_master_t *master = slave->master;
2366  uint8_t *data, mbox_prot;
2367  size_t rec_size, data_size;
2368  ec_sdo_request_t *request = fsm->request;
2369  unsigned int last_segment;
2370 
2371  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2372  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2373  return;
2374  }
2375 
2376  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2377  request->errno = EIO;
2378  fsm->state = ec_fsm_coe_error;
2379  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2380  " response datagram: ");
2382  return;
2383  }
2384 
2385  if (fsm->datagram->working_counter != 1) {
2386  request->errno = EIO;
2387  fsm->state = ec_fsm_coe_error;
2388  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2389  " response failed: ");
2391  return;
2392  }
2393 
2394  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2395  if (IS_ERR(data)) {
2396  request->errno = PTR_ERR(data);
2397  fsm->state = ec_fsm_coe_error;
2398  return;
2399  }
2400 
2401  if (master->debug_level) {
2402  EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
2403  ec_print_data(data, rec_size);
2404  }
2405 
2406  if (mbox_prot != EC_MBOX_TYPE_COE) {
2407  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
2408  mbox_prot);
2409  request->errno = EIO;
2410  fsm->state = ec_fsm_coe_error;
2411  return;
2412  }
2413 
2414  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2415  // check for CoE response again
2416  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2417  fsm->retries = EC_FSM_RETRIES;
2419  return;
2420  }
2421 
2422  if (rec_size < 10) {
2423  EC_SLAVE_ERR(slave, "Received currupted SDO upload"
2424  " segment response!\n");
2425  ec_print_data(data, rec_size);
2426  request->errno = EIO;
2427  fsm->state = ec_fsm_coe_error;
2428  return;
2429  }
2430 
2431  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2432  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
2433  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2434  request->index, request->subindex);
2435  request->abort_code = EC_READ_U32(data + 6);
2436  ec_canopen_abort_msg(slave, request->abort_code);
2437  request->errno = EIO;
2438  fsm->state = ec_fsm_coe_error;
2439  return;
2440  }
2441 
2442  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2443  EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
2444  if (fsm->slave->master->debug_level) {
2445  EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
2446  ec_print_data(data, rec_size);
2447  }
2448  // check for CoE response again
2449  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2450  fsm->retries = EC_FSM_RETRIES;
2452  return;
2453  }
2454 
2455  data_size = rec_size - 3; /* Header of segment upload is smaller than
2456  normal upload */
2457  if (rec_size == 10) {
2458  uint8_t seg_size = (EC_READ_U8(data + 2) & 0xE) >> 1;
2459  data_size -= seg_size;
2460  }
2461 
2462  if (request->data_size + data_size > fsm->complete_size) {
2463  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X failed: Fragment"
2464  " exceeding complete size!\n",
2465  request->index, request->subindex);
2466  request->errno = ENOBUFS;
2467  fsm->state = ec_fsm_coe_error;
2468  return;
2469  }
2470 
2471  memcpy(request->data + request->data_size, data + 3, data_size);
2472  request->data_size += data_size;
2473 
2474  last_segment = EC_READ_U8(data + 2) & 0x01;
2475  if (!last_segment) {
2476  fsm->toggle = !fsm->toggle;
2478  fsm->retries = EC_FSM_RETRIES;
2480  return;
2481  }
2482 
2483  if (request->data_size != fsm->complete_size) {
2484  EC_SLAVE_WARN(slave, "SDO upload 0x%04X:%02X: Assembled data"
2485  " size (%zu) does not match complete size (%u)!\n",
2486  request->index, request->subindex,
2487  request->data_size, fsm->complete_size);
2488  }
2489 
2490  if (master->debug_level) {
2491  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2492  ec_print_data(request->data, request->data_size);
2493  }
2494 
2495  fsm->state = ec_fsm_coe_end; // success
2496 }
2497 
2498 /****************************************************************************/
2499 
2505  ec_fsm_coe_t *fsm,
2506  ec_datagram_t *datagram
2507  )
2508 {
2509 }
2510 
2511 /****************************************************************************/
2512 
2518  ec_fsm_coe_t *fsm,
2519  ec_datagram_t *datagram
2520  )
2521 {
2522 }
2523 
2524 /****************************************************************************/
int ec_fsm_coe_prepare_down_start(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare a donwnload request.
Definition: fsm_coe.c:1187
#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:2359
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:96
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 *fsm, ec_datagram_t *datagram)
Prepare an upload request.
Definition: fsm_coe.c:1834
void ec_fsm_coe_up_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP START.
Definition: fsm_coe.c:1871
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:2517
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:489
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:2504
void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY CHECK.
Definition: fsm_coe.c:951
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:1008
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:1401
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2699
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 *fsm, ec_datagram_t *datagram)
Prepare a download segment request.
Definition: fsm_coe.c:1459
void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:2256
uint16_t working_counter
Working counter.
Definition: datagram.h:91
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:1646
#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:2299
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:254
#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
int ec_fsm_coe_check_emergency(ec_fsm_coe_t *fsm, const uint8_t *data, size_t size)
Check if the received data are a CoE emergency request.
Definition: fsm_coe.c:269
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:909
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:1903
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
Code/Message pair.
Definition: globals.h:275
ec_datagram_state_t state
State.
Definition: datagram.h:92
void ec_fsm_coe_dict_desc_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC REQUEST.
Definition: fsm_coe.c:644
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:2733
void ec_fsm_coe_up_prepare_segment_request(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare an SDO upload segment request.
Definition: fsm_coe.c:2029
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 *fsm, ec_datagram_t *datagram)
Prepare an object description request.
Definition: fsm_coe.c:460
unsigned int debug_level
Master debug level.
Definition: master.h:271
void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC RESPONSE.
Definition: fsm_coe.c:774
#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:2061
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:174
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2716
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:2627
uint32_t complete_size
Used when segmenting.
Definition: fsm_coe.h:54
int ec_fsm_coe_dict_prepare_entry(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare an entry description request.
Definition: fsm_coe.c:743
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:687
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:184
void ec_fsm_coe_dict_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT START.
Definition: fsm_coe.c:333
void ec_fsm_coe_down_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN REQUEST.
Definition: fsm_coe.c:1333
void ec_canopen_abort_msg(const ec_slave_t *slave, uint32_t abort_code)
Outputs an SDO abort message.
Definition: fsm_coe.c:140
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:405
#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 *fsm, ec_datagram_t *datagram)
Prepare a dictionary request.
Definition: fsm_coe.c:307
void ec_fsm_coe_init(ec_fsm_coe_t *fsm)
Constructor.
Definition: fsm_coe.c:162
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:342
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:2611
ec_coe_emerg_ring_t emerg_ring
CoE emergency ring buffer.
Definition: slave_config.h:144
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:220
void ec_fsm_coe_dict_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT REQUEST.
Definition: fsm_coe.c:365
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:1282
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:1703
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:2595
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:1525
#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:197
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:503
Received (dequeued).
Definition: datagram.h:70
EtherCAT master.
Definition: master.h:183
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:100
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:99
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:1972
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