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