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, 0x03, 8);
322  if (IS_ERR(data)) {
323  return PTR_ERR(data);
324  }
325 
326  EC_WRITE_U16(data, 0x8 << 12); // SDO information
327  EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
328  EC_WRITE_U8 (data + 3, 0x00);
329  EC_WRITE_U16(data + 4, 0x0000);
330  EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
331 
333  return 0;
334 }
335 
336 /*****************************************************************************/
337 
341  ec_fsm_coe_t *fsm,
342  ec_datagram_t *datagram
343  )
344 {
345  ec_slave_t *slave = fsm->slave;
346 
347  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
348  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
349  fsm->state = ec_fsm_coe_error;
350  return;
351  }
352 
353  if (slave->sii.has_general && !slave->sii.coe_details.enable_sdo_info) {
354  EC_SLAVE_ERR(slave, "Slave does not support"
355  " SDO information service!\n");
356  fsm->state = ec_fsm_coe_error;
357  return;
358  }
359 
360  fsm->retries = EC_FSM_RETRIES;
361 
362  if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
363  fsm->state = ec_fsm_coe_error;
364  }
365 }
366 
367 /*****************************************************************************/
368 
373  ec_fsm_coe_t *fsm,
374  ec_datagram_t *datagram
375  )
376 {
377  ec_slave_t *slave = fsm->slave;
378 
379  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
380  if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
381  fsm->state = ec_fsm_coe_error;
382  }
383  return;
384  }
385 
386  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
387  fsm->state = ec_fsm_coe_error;
388  EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
389  " request datagram: ");
391  return;
392  }
393 
394  if (fsm->datagram->working_counter != 1) {
395  fsm->state = ec_fsm_coe_error;
396  EC_SLAVE_ERR(slave, "Reception of CoE dictionary request failed: ");
398  return;
399  }
400 
401  fsm->jiffies_start = fsm->datagram->jiffies_sent;
402 
403  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
404  fsm->retries = EC_FSM_RETRIES;
406 }
407 
408 /*****************************************************************************/
409 
413  ec_fsm_coe_t *fsm,
414  ec_datagram_t *datagram
415  )
416 {
417  ec_slave_t *slave = fsm->slave;
418 
419  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
420  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
421  return;
422  }
423 
424  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
425  fsm->state = ec_fsm_coe_error;
426  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
428  return;
429  }
430 
431  if (fsm->datagram->working_counter != 1) {
432  fsm->state = ec_fsm_coe_error;
433  EC_SLAVE_ERR(slave,"Reception of CoE mailbox check"
434  " datagram failed: ");
436  return;
437  }
438 
439  if (!ec_slave_mbox_check(fsm->datagram)) {
440  unsigned long diff_ms =
441  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
442  1000 / HZ;
443  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
444  fsm->state = ec_fsm_coe_error;
445  EC_SLAVE_ERR(slave, "Timeout while waiting for"
446  " SDO dictionary list response.\n");
447  return;
448  }
449 
450  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
451  fsm->retries = EC_FSM_RETRIES;
452  return;
453  }
454 
455  // Fetch response
456  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
457  fsm->retries = EC_FSM_RETRIES;
459 }
460 
461 /*****************************************************************************/
462 
468  ec_fsm_coe_t *fsm,
469  ec_datagram_t *datagram
470  )
471 {
472  ec_slave_t *slave = fsm->slave;
473  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8);
474  if (IS_ERR(data)) {
475  return PTR_ERR(data);
476  }
477 
478  EC_WRITE_U16(data, 0x8 << 12); // SDO information
479  EC_WRITE_U8 (data + 2, 0x03); // Get object description request
480  EC_WRITE_U8 (data + 3, 0x00);
481  EC_WRITE_U16(data + 4, 0x0000);
482  EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
483 
485  return 0;
486 }
487 
488 /*****************************************************************************/
489 
496  ec_fsm_coe_t *fsm,
497  ec_datagram_t *datagram
498  )
499 {
500  ec_slave_t *slave = fsm->slave;
501  uint8_t *data, mbox_prot;
502  size_t rec_size;
503  unsigned int sdo_count, i;
504  uint16_t sdo_index, fragments_left;
505  ec_sdo_t *sdo;
506  bool first_segment;
507  size_t index_list_offset;
508 
509  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
510  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
511  return;
512  }
513 
514  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
515  fsm->state = ec_fsm_coe_error;
516  EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
517  " response datagram: ");
519  return;
520  }
521 
522  if (fsm->datagram->working_counter != 1) {
523  fsm->state = ec_fsm_coe_error;
524  EC_SLAVE_ERR(slave, "Reception of CoE dictionary response failed: ");
526  return;
527  }
528 
529  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
530  if (IS_ERR(data)) {
531  fsm->state = ec_fsm_coe_error;
532  return;
533  }
534 
535  if (mbox_prot != 0x03) { // CoE
536  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
537  mbox_prot);
538  fsm->state = ec_fsm_coe_error;
539  return;
540  }
541 
542  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
543  // check for CoE response again
544  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
545  fsm->retries = EC_FSM_RETRIES;
547  return;
548  }
549 
550  if (rec_size < 3) {
551  EC_SLAVE_ERR(slave, "Received corrupted SDO dictionary response"
552  " (size %zu).\n", rec_size);
553  fsm->state = ec_fsm_coe_error;
554  return;
555  }
556 
557  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
558  (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
559  EC_SLAVE_ERR(slave, "SDO information error response!\n");
560  if (rec_size < 10) {
561  EC_SLAVE_ERR(slave, "Incomplete SDO information"
562  " error response:\n");
563  ec_print_data(data, rec_size);
564  } else {
565  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
566  }
567  fsm->state = ec_fsm_coe_error;
568  return;
569  }
570 
571  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
572  (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
573  if (fsm->slave->master->debug_level) {
574  EC_SLAVE_DBG(slave, 1, "Invalid SDO list response!"
575  " Retrying...\n");
576  ec_print_data(data, rec_size);
577  }
578  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
579  fsm->retries = EC_FSM_RETRIES;
581  return;
582  }
583 
584  first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
585  index_list_offset = first_segment ? 8 : 6;
586 
587  if (rec_size < index_list_offset || rec_size % 2) {
588  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
589  ec_print_data(data, rec_size);
590  fsm->state = ec_fsm_coe_error;
591  return;
592  }
593 
594  sdo_count = (rec_size - index_list_offset) / 2;
595 
596  for (i = 0; i < sdo_count; i++) {
597  sdo_index = EC_READ_U16(data + index_list_offset + i * 2);
598  if (!sdo_index) {
599  EC_SLAVE_DBG(slave, 1, "SDO dictionary contains index 0x0000.\n");
600  continue;
601  }
602 
603  if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
604  EC_SLAVE_ERR(slave, "Failed to allocate memory for SDO!\n");
605  fsm->state = ec_fsm_coe_error;
606  return;
607  }
608 
609  ec_sdo_init(sdo, slave, sdo_index);
610  list_add_tail(&sdo->list, &slave->sdo_dictionary);
611  }
612 
613  fragments_left = EC_READ_U16(data + 4);
614  if (fragments_left) {
615  EC_SLAVE_DBG(slave, 1, "SDO list fragments left: %u\n",
616  fragments_left);
617  }
618 
619  if (EC_READ_U8(data + 2) & 0x80 || fragments_left) {
620  // more messages waiting. check again.
621  fsm->jiffies_start = fsm->datagram->jiffies_sent;
622  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
623  fsm->retries = EC_FSM_RETRIES;
625  return;
626  }
627 
628  if (list_empty(&slave->sdo_dictionary)) {
629  // no SDOs in dictionary. finished.
630  fsm->state = ec_fsm_coe_end; // success
631  return;
632  }
633 
634  // fetch SDO descriptions
635  fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);
636 
637  fsm->retries = EC_FSM_RETRIES;
638  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
639  fsm->state = ec_fsm_coe_error;
640  }
641 }
642 
643 /*****************************************************************************/
644 
651  ec_fsm_coe_t *fsm,
652  ec_datagram_t *datagram
653  )
654 {
655  ec_slave_t *slave = fsm->slave;
656 
657  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
658  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
659  fsm->state = ec_fsm_coe_error;
660  }
661  return;
662  }
663 
664  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
665  fsm->state = ec_fsm_coe_error;
666  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
667  " description request datagram: ");
669  return;
670  }
671 
672  if (fsm->datagram->working_counter != 1) {
673  fsm->state = ec_fsm_coe_error;
674  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
675  " request failed: ");
677  return;
678  }
679 
680  fsm->jiffies_start = fsm->datagram->jiffies_sent;
681 
682  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
683  fsm->retries = EC_FSM_RETRIES;
685 }
686 
687 /*****************************************************************************/
688 
694  ec_fsm_coe_t *fsm,
695  ec_datagram_t *datagram
696  )
697 {
698  ec_slave_t *slave = fsm->slave;
699 
700  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
701  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
702  return;
703  }
704 
705  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
706  fsm->state = ec_fsm_coe_error;
707  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
709  return;
710  }
711 
712  if (fsm->datagram->working_counter != 1) {
713  fsm->state = ec_fsm_coe_error;
714  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
715  " datagram failed: ");
717  return;
718  }
719 
720  if (!ec_slave_mbox_check(fsm->datagram)) {
721  unsigned long diff_ms =
722  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
723  1000 / HZ;
724  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
725  fsm->state = ec_fsm_coe_error;
726  EC_SLAVE_ERR(slave, "Timeout while waiting for"
727  " SDO 0x%04x object description response.\n",
728  fsm->sdo->index);
729  return;
730  }
731 
732  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
733  fsm->retries = EC_FSM_RETRIES;
734  return;
735  }
736 
737  // Fetch response
738  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
739  fsm->retries = EC_FSM_RETRIES;
741 }
742 
743 /*****************************************************************************/
744 
750  ec_fsm_coe_t *fsm,
751  ec_datagram_t *datagram
752  )
753 {
754  ec_slave_t *slave = fsm->slave;
755  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
756  if (IS_ERR(data)) {
757  return PTR_ERR(data);
758  }
759 
760  EC_WRITE_U16(data, 0x8 << 12); // SDO information
761  EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
762  EC_WRITE_U8 (data + 3, 0x00);
763  EC_WRITE_U16(data + 4, 0x0000);
764  EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
765  EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
766  EC_WRITE_U8 (data + 9, 0x01); // value info (access rights only)
767 
769  return 0;
770 }
771 
772 /*****************************************************************************/
773 
780  ec_fsm_coe_t *fsm,
781  ec_datagram_t *datagram
782  )
783 {
784  ec_slave_t *slave = fsm->slave;
785  ec_sdo_t *sdo = fsm->sdo;
786  uint8_t *data, mbox_prot;
787  size_t rec_size, name_size;
788 
789  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
790  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
791  return;
792  }
793 
794  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
795  fsm->state = ec_fsm_coe_error;
796  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description"
797  " response datagram: ");
799  return;
800  }
801 
802  if (fsm->datagram->working_counter != 1) {
803  fsm->state = ec_fsm_coe_error;
804  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
805  " response failed: ");
807  return;
808  }
809 
810  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
811  if (IS_ERR(data)) {
812  fsm->state = ec_fsm_coe_error;
813  return;
814  }
815 
816  if (mbox_prot != 0x03) { // CoE
817  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
818  mbox_prot);
819  fsm->state = ec_fsm_coe_error;
820  return;
821  }
822 
823  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
824  // check for CoE response again
825  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
826  fsm->retries = EC_FSM_RETRIES;
828  return;
829  }
830 
831  if (rec_size < 3) {
832  EC_SLAVE_ERR(slave, "Received corrupted SDO description response"
833  " (size %zu).\n", rec_size);
834  fsm->state = ec_fsm_coe_error;
835  return;
836  }
837 
838  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
839  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
840  EC_SLAVE_ERR(slave, "SDO information error response while"
841  " fetching SDO 0x%04X!\n", sdo->index);
842  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
843  fsm->state = ec_fsm_coe_error;
844  return;
845  }
846 
847  if (rec_size < 8) {
848  EC_SLAVE_ERR(slave, "Received corrupted SDO"
849  " description response (size %zu).\n", rec_size);
850  fsm->state = ec_fsm_coe_error;
851  return;
852  }
853 
854  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
855  (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response
856  EC_READ_U16(data + 6) != sdo->index) { // SDO index
857  if (fsm->slave->master->debug_level) {
858  EC_SLAVE_DBG(slave, 1, "Invalid object description response while"
859  " fetching SDO 0x%04X!\n", sdo->index);
860  ec_print_data(data, rec_size);
861  }
862  // check for CoE response again
863  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
864  fsm->retries = EC_FSM_RETRIES;
866  return;
867  }
868 
869  if (rec_size < 12) {
870  EC_SLAVE_ERR(slave, "Invalid data size!\n");
871  ec_print_data(data, rec_size);
872  fsm->state = ec_fsm_coe_error;
873  return;
874  }
875 
876  sdo->max_subindex = EC_READ_U8(data + 10);
877  sdo->object_code = EC_READ_U8(data + 11);
878 
879  name_size = rec_size - 12;
880  if (name_size) {
881  if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) {
882  EC_SLAVE_ERR(slave, "Failed to allocate SDO name!\n");
883  fsm->state = ec_fsm_coe_error;
884  return;
885  }
886 
887  memcpy(sdo->name, data + 12, name_size);
888  sdo->name[name_size] = 0;
889  }
890 
891  if (EC_READ_U8(data + 2) & 0x80) {
892  EC_SLAVE_ERR(slave, "Fragment follows (not implemented)!\n");
893  fsm->state = ec_fsm_coe_error;
894  return;
895  }
896 
897  // start fetching entries
898 
899  fsm->subindex = 0;
900  fsm->retries = EC_FSM_RETRIES;
901 
902  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
903  fsm->state = ec_fsm_coe_error;
904  }
905 }
906 
907 /*****************************************************************************/
908 
915  ec_fsm_coe_t *fsm,
916  ec_datagram_t *datagram
917  )
918 {
919  ec_slave_t *slave = fsm->slave;
920 
921  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
922  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
923  fsm->state = ec_fsm_coe_error;
924  }
925  return;
926  }
927 
928  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
929  fsm->state = ec_fsm_coe_error;
930  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry"
931  " request datagram: ");
933  return;
934  }
935 
936  if (fsm->datagram->working_counter != 1) {
937  fsm->state = ec_fsm_coe_error;
938  EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: ");
940  return;
941  }
942 
943  fsm->jiffies_start = fsm->datagram->jiffies_sent;
944 
945  ec_slave_mbox_prepare_check(slave, datagram); // can not fail
946  fsm->retries = EC_FSM_RETRIES;
948 }
949 
950 /*****************************************************************************/
951 
957  ec_fsm_coe_t *fsm,
958  ec_datagram_t *datagram
959  )
960 {
961  ec_slave_t *slave = fsm->slave;
962 
963  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
964  ec_slave_mbox_prepare_check(slave, datagram); // can not fail
965  return;
966  }
967 
968  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
969  fsm->state = ec_fsm_coe_error;
970  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
972  return;
973  }
974 
975  if (fsm->datagram->working_counter != 1) {
976  fsm->state = ec_fsm_coe_error;
977  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
978  " datagram failed: ");
980  return;
981  }
982 
983  if (!ec_slave_mbox_check(fsm->datagram)) {
984  unsigned long diff_ms =
985  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
986  1000 / HZ;
987  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
988  fsm->state = ec_fsm_coe_error;
989  EC_SLAVE_ERR(slave, "Timeout while waiting for"
990  " SDO entry 0x%04x:%x description response.\n",
991  fsm->sdo->index, fsm->subindex);
992  return;
993  }
994 
995  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
996  fsm->retries = EC_FSM_RETRIES;
997  return;
998  }
999 
1000  // Fetch response
1001  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1002  fsm->retries = EC_FSM_RETRIES;
1004 }
1005 
1006 /*****************************************************************************/
1007 
1014  ec_fsm_coe_t *fsm,
1015  ec_datagram_t *datagram
1016  )
1017 {
1018  ec_slave_t *slave = fsm->slave;
1019  ec_sdo_t *sdo = fsm->sdo;
1020  uint8_t *data, mbox_prot;
1021  size_t rec_size, data_size;
1022  ec_sdo_entry_t *entry;
1023  u16 word;
1024 
1025  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1026  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1027  return;
1028  }
1029 
1030  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1031  fsm->state = ec_fsm_coe_error;
1032  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
1033  " description response datagram: ");
1035  return;
1036  }
1037 
1038  if (fsm->datagram->working_counter != 1) {
1039  fsm->state = ec_fsm_coe_error;
1040  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
1041  " response failed: ");
1043  return;
1044  }
1045 
1046  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1047  if (IS_ERR(data)) {
1048  fsm->state = ec_fsm_coe_error;
1049  return;
1050  }
1051 
1052  if (mbox_prot != 0x03) { // CoE
1053  EC_SLAVE_ERR(slave, "Received mailbox protocol"
1054  " 0x%02X as response.\n", mbox_prot);
1055  fsm->state = ec_fsm_coe_error;
1056  return;
1057  }
1058 
1059  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1060  // check for CoE response again
1061  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1062  fsm->retries = EC_FSM_RETRIES;
1064  return;
1065  }
1066 
1067  if (rec_size < 3) {
1068  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1069  " description response (size %zu).\n", rec_size);
1070  fsm->state = ec_fsm_coe_error;
1071  return;
1072  }
1073 
1074  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
1075  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
1076  EC_SLAVE_WARN(slave, "SDO information error response while"
1077  " fetching SDO entry 0x%04X:%02X!\n",
1078  sdo->index, fsm->subindex);
1079  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
1080 
1081  /* There may be gaps in the subindices, so try to continue with next
1082  * subindex. */
1083 
1084  } else {
1085 
1086  if (rec_size < 9) {
1087  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1088  " description response (size %zu).\n", rec_size);
1089  fsm->state = ec_fsm_coe_error;
1090  return;
1091  }
1092 
1093  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
1094  (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
1095  EC_READ_U16(data + 6) != sdo->index || // SDO index
1096  EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex
1097  if (fsm->slave->master->debug_level) {
1098  EC_SLAVE_DBG(slave, 1, "Invalid entry description response"
1099  " while fetching SDO entry 0x%04X:%02X!\n",
1100  sdo->index, fsm->subindex);
1101  ec_print_data(data, rec_size);
1102  }
1103  // check for CoE response again
1104  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1105  fsm->retries = EC_FSM_RETRIES;
1107  return;
1108  }
1109 
1110  if (rec_size < 16) {
1111  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
1112  ec_print_data(data, rec_size);
1113  fsm->state = ec_fsm_coe_error;
1114  return;
1115  }
1116 
1117  data_size = rec_size - 16;
1118 
1119  if (!(entry = (ec_sdo_entry_t *)
1120  kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) {
1121  EC_SLAVE_ERR(slave, "Failed to allocate entry!\n");
1122  fsm->state = ec_fsm_coe_error;
1123  return;
1124  }
1125 
1126  ec_sdo_entry_init(entry, sdo, fsm->subindex);
1127  entry->data_type = EC_READ_U16(data + 10);
1128  entry->bit_length = EC_READ_U16(data + 12);
1129 
1130  // read access rights
1131  word = EC_READ_U16(data + 14);
1132  entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001;
1134  (word >> 1) & 0x0001;
1135  entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001;
1136  entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001;
1138  (word >> 4) & 0x0001;
1139  entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001;
1140 
1141  if (data_size) {
1142  uint8_t *desc;
1143  if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) {
1144  EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n");
1145  fsm->state = ec_fsm_coe_error;
1146  return;
1147  }
1148  memcpy(desc, data + 16, data_size);
1149  desc[data_size] = 0;
1150  entry->description = desc;
1151  }
1152 
1153  list_add_tail(&entry->list, &sdo->entries);
1154  }
1155 
1156  if (fsm->subindex < sdo->max_subindex) {
1157 
1158  fsm->subindex++;
1159  fsm->retries = EC_FSM_RETRIES;
1160 
1161  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1162  fsm->state = ec_fsm_coe_error;
1163  }
1164 
1165  return;
1166  }
1167 
1168  // another SDO description to fetch?
1169  if (fsm->sdo->list.next != &slave->sdo_dictionary) {
1170 
1171  fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
1172  fsm->retries = EC_FSM_RETRIES;
1173 
1174  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
1175  fsm->state = ec_fsm_coe_error;
1176  }
1177 
1178  return;
1179  }
1180 
1181  fsm->state = ec_fsm_coe_end;
1182 }
1183 
1184 /******************************************************************************
1185  * CoE state machine
1186  *****************************************************************************/
1187 
1193  ec_fsm_coe_t *fsm,
1194  ec_datagram_t *datagram
1195  )
1196 {
1197  u8 *data;
1198  ec_slave_t *slave = fsm->slave;
1199  ec_sdo_request_t *request = fsm->request;
1200  uint8_t data_set_size;
1201 
1202  if (request->data_size <= 4) { // use expedited transfer type
1203  data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
1205  if (IS_ERR(data)) {
1206  request->errno = PTR_ERR(data);
1207  return PTR_ERR(data);
1208  }
1209 
1210  fsm->remaining = 0;
1211 
1212  data_set_size = 4 - request->data_size;
1213 
1214  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1215  EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
1216  | data_set_size << 2
1217  | ((request->complete_access ? 1 : 0) << 4)
1218  | 0x1 << 5)); // Download request
1219  EC_WRITE_U16(data + 3, request->index);
1220  EC_WRITE_U8 (data + 5,
1221  request->complete_access ? 0x00 : request->subindex);
1222  memcpy(data + 6, request->data, request->data_size);
1223  memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);
1224 
1225  if (slave->master->debug_level) {
1226  EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
1228  }
1229  }
1230  else { // request->data_size > 4, use normal transfer type
1231  size_t data_size,
1232  max_data_size =
1234  required_data_size =
1236 
1237  if (max_data_size < required_data_size) {
1238  // segmenting needed
1239  data_size = max_data_size;
1240  } else {
1241  data_size = required_data_size;
1242  }
1243 
1244  data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
1245  data_size);
1246  if (IS_ERR(data)) {
1247  request->errno = PTR_ERR(data);
1248  return PTR_ERR(data);
1249  }
1250 
1251  fsm->offset = 0;
1252  fsm->remaining = request->data_size;
1253 
1254  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1255  EC_WRITE_U8(data + 2,
1256  0x1 // size indicator, normal
1257  | ((request->complete_access ? 1 : 0) << 4)
1258  | 0x1 << 5); // Download request
1259  EC_WRITE_U16(data + 3, request->index);
1260  EC_WRITE_U8 (data + 5,
1261  request->complete_access ? 0x00 : request->subindex);
1262  EC_WRITE_U32(data + 6, request->data_size);
1263 
1264  if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
1265  size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
1266  memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
1267  request->data, segment_size);
1268  fsm->offset += segment_size;
1269  fsm->remaining -= segment_size;
1270  }
1271 
1272  if (slave->master->debug_level) {
1273  EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
1274  ec_print_data(data, data_size);
1275  }
1276  }
1277 
1279  return 0;
1280 }
1281 
1282 /****************************************************************************/
1283 
1287  ec_fsm_coe_t *fsm,
1288  ec_datagram_t *datagram
1289  )
1290 {
1291  ec_slave_t *slave = fsm->slave;
1292  ec_sdo_request_t *request = fsm->request;
1293 
1294  if (fsm->slave->master->debug_level) {
1295  char subidxstr[10];
1296  if (request->complete_access) {
1297  subidxstr[0] = 0x00;
1298  } else {
1299  sprintf(subidxstr, ":%02X", request->subindex);
1300  }
1301  EC_SLAVE_DBG(slave, 1, "Downloading SDO 0x%04X%s.\n",
1302  request->index, subidxstr);
1303  ec_print_data(request->data, request->data_size);
1304  }
1305 
1306  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1307  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1308  request->errno = EPROTONOSUPPORT;
1309  fsm->state = ec_fsm_coe_error;
1310  return;
1311  }
1312 
1313  if (slave->configured_rx_mailbox_size <
1315  EC_SLAVE_ERR(slave, "Mailbox too small!\n");
1316  request->errno = EOVERFLOW;
1317  fsm->state = ec_fsm_coe_error;
1318  return;
1319  }
1320 
1321 
1322  fsm->request->jiffies_sent = jiffies;
1323  fsm->retries = EC_FSM_RETRIES;
1324 
1325  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1326  fsm->state = ec_fsm_coe_error;
1327  }
1328 }
1329 
1330 /*****************************************************************************/
1331 
1338  ec_fsm_coe_t *fsm,
1339  ec_datagram_t *datagram
1340  )
1341 {
1342  ec_slave_t *slave = fsm->slave;
1343  unsigned long diff_ms;
1344 
1345  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1346  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1347  fsm->state = ec_fsm_coe_error;
1348  }
1349  return;
1350  }
1351 
1352  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1353  fsm->request->errno = EIO;
1354  fsm->state = ec_fsm_coe_error;
1355  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1356  " request datagram: ");
1358  return;
1359  }
1360 
1361  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1362 
1363  if (fsm->datagram->working_counter != 1) {
1364  if (!fsm->datagram->working_counter) {
1365  if (diff_ms < fsm->request->response_timeout) {
1366 #if DEBUG_RETRIES
1367  EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
1368  " download request. Retrying after %lu ms...\n",
1369  diff_ms);
1370 #endif
1371  // no response; send request datagram again
1372  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1373  fsm->state = ec_fsm_coe_error;
1374  }
1375  return;
1376  }
1377  }
1378  fsm->request->errno = EIO;
1379  fsm->state = ec_fsm_coe_error;
1380  EC_SLAVE_ERR(slave, "Reception of CoE download request"
1381  " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
1382  fsm->request->index, fsm->request->subindex, diff_ms);
1384  return;
1385  }
1386 
1387 #if DEBUG_LONG
1388  if (diff_ms > 200) {
1389  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
1390  fsm->request->index, fsm->request->subindex, diff_ms);
1391  }
1392 #endif
1393 
1394  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1395 
1396  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1397  fsm->retries = EC_FSM_RETRIES;
1399 }
1400 
1401 /*****************************************************************************/
1402 
1406  ec_fsm_coe_t *fsm,
1407  ec_datagram_t *datagram
1408  )
1409 {
1410  ec_slave_t *slave = fsm->slave;
1411 
1412  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1413  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1414  return;
1415  }
1416 
1417  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1418  fsm->request->errno = EIO;
1419  fsm->state = ec_fsm_coe_error;
1420  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
1421  " datagram: ");
1423  return;
1424  }
1425 
1426  if (fsm->datagram->working_counter != 1) {
1427  fsm->request->errno = EIO;
1428  fsm->state = ec_fsm_coe_error;
1429  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1430  " datagram failed: ");
1432  return;
1433  }
1434 
1435  if (!ec_slave_mbox_check(fsm->datagram)) {
1436  unsigned long diff_ms =
1437  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1438  1000 / HZ;
1439  if (diff_ms >= fsm->request->response_timeout) {
1440  fsm->request->errno = EIO;
1441  fsm->state = ec_fsm_coe_error;
1442  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
1443  " for SDO 0x%04x:%x download response.\n", diff_ms,
1444  fsm->request->index, fsm->request->subindex);
1445  return;
1446  }
1447 
1448  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1449  fsm->retries = EC_FSM_RETRIES;
1450  return;
1451  }
1452 
1453  // Fetch response
1454  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1455  fsm->retries = EC_FSM_RETRIES;
1457 }
1458 
1459 /*****************************************************************************/
1460 
1464  ec_fsm_coe_t *fsm,
1465  ec_datagram_t *datagram
1466  )
1467 {
1468  ec_slave_t *slave = fsm->slave;
1469  ec_sdo_request_t *request = fsm->request;
1470  size_t max_segment_size =
1474  size_t data_size;
1475  uint8_t last_segment, seg_data_size, *data;
1476 
1477  if (fsm->remaining > max_segment_size) {
1478  fsm->segment_size = max_segment_size;
1479  last_segment = 0;
1480  } else {
1481  fsm->segment_size = fsm->remaining;
1482  last_segment = 1;
1483  }
1484 
1486  seg_data_size = 0x00;
1487  data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size;
1488  } else {
1489  seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size;
1490  data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE
1492  }
1493 
1494  data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
1495  data_size);
1496  if (IS_ERR(data)) {
1497  request->errno = PTR_ERR(data);
1498  fsm->state = ec_fsm_coe_error;
1499  return;
1500  }
1501 
1502  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1503  EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
1504  | (seg_data_size << 1)
1505  | (fsm->toggle << 4)
1506  | (0x00 << 5)); // Download segment request
1507  memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
1508  request->data + fsm->offset, fsm->segment_size);
1510  memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size,
1512  }
1513 
1514  if (slave->master->debug_level) {
1515  EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
1516  ec_print_data(data, data_size);
1517  }
1518 
1520 }
1521 
1522 /*****************************************************************************/
1523 
1530  ec_fsm_coe_t *fsm,
1531  ec_datagram_t *datagram
1532  )
1533 {
1534  ec_slave_t *slave = fsm->slave;
1535  uint8_t *data, mbox_prot;
1536  size_t rec_size;
1537  ec_sdo_request_t *request = fsm->request;
1538 
1539  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1540  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1541  return;
1542  }
1543 
1544  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1545  request->errno = EIO;
1546  fsm->state = ec_fsm_coe_error;
1547  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1548  " response datagram: ");
1550  return;
1551  }
1552 
1553  if (fsm->datagram->working_counter != 1) {
1554  request->errno = EIO;
1555  fsm->state = ec_fsm_coe_error;
1556  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1558  return;
1559  }
1560 
1561  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1562  if (IS_ERR(data)) {
1563  request->errno = PTR_ERR(data);
1564  fsm->state = ec_fsm_coe_error;
1565  return;
1566  }
1567 
1568  if (mbox_prot != 0x03) { // CoE
1569  request->errno = EIO;
1570  fsm->state = ec_fsm_coe_error;
1571  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1572  mbox_prot);
1573  return;
1574  }
1575 
1576  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1577  // check for CoE response again
1578  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1579  fsm->retries = EC_FSM_RETRIES;
1581  return;
1582  }
1583 
1584  if (slave->master->debug_level) {
1585  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1586  ec_print_data(data, rec_size);
1587  }
1588 
1589  if (rec_size < 6) {
1590  request->errno = EIO;
1591  fsm->state = ec_fsm_coe_error;
1592  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1593  rec_size);
1594  ec_print_data(data, rec_size);
1595  return;
1596  }
1597 
1598  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1599  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1600  char subidxstr[10];
1601  request->errno = EIO;
1602  fsm->state = ec_fsm_coe_error;
1603  if (request->complete_access) {
1604  subidxstr[0] = 0x00;
1605  } else {
1606  sprintf(subidxstr, ":%02X", request->subindex);
1607  }
1608  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1609  request->index, subidxstr, request->data_size);
1610  if (rec_size < 10) {
1611  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1612  ec_print_data(data, rec_size);
1613  } else {
1614  fsm->request->abort_code = EC_READ_U32(data + 6);
1615  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1616  }
1617  return;
1618  }
1619 
1620  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
1621  EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
1622  EC_READ_U16(data + 3) != request->index || // index
1623  EC_READ_U8 (data + 5) != request->subindex) { // subindex
1624  if (slave->master->debug_level) {
1625  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1626  " Retrying...\n");
1627  ec_print_data(data, rec_size);
1628  }
1629  // check for CoE response again
1630  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1631  fsm->retries = EC_FSM_RETRIES;
1633  return;
1634  }
1635 
1636  if (fsm->remaining) { // more segments to download
1637  fsm->toggle = 0;
1639  } else {
1640  fsm->state = ec_fsm_coe_end; // success
1641  }
1642 }
1643 
1644 /*****************************************************************************/
1645 
1651  ec_fsm_coe_t *fsm,
1652  ec_datagram_t *datagram
1653  )
1654 {
1655  ec_slave_t *slave = fsm->slave;
1656 
1657  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1658  return;
1659 
1660  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1661  fsm->request->errno = EIO;
1662  fsm->state = ec_fsm_coe_error;
1663  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1665  return;
1666  }
1667 
1668  if (fsm->datagram->working_counter != 1) {
1669  fsm->request->errno = EIO;
1670  fsm->state = ec_fsm_coe_error;
1671  EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
1672  " datagram failed: ");
1674  return;
1675  }
1676 
1677  if (!ec_slave_mbox_check(fsm->datagram)) {
1678  unsigned long diff_ms =
1679  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1680  1000 / HZ;
1681  if (diff_ms >= fsm->request->response_timeout) {
1682  fsm->request->errno = EIO;
1683  fsm->state = ec_fsm_coe_error;
1684  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
1685  " segment response.\n");
1686  return;
1687  }
1688 
1689  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1690  fsm->retries = EC_FSM_RETRIES;
1691  return;
1692  }
1693 
1694  // Fetch response
1695  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1696  fsm->retries = EC_FSM_RETRIES;
1698 }
1699 
1700 /*****************************************************************************/
1701 
1708  ec_fsm_coe_t *fsm,
1709  ec_datagram_t *datagram
1710  )
1711 {
1712  ec_slave_t *slave = fsm->slave;
1713  uint8_t *data, mbox_prot;
1714  size_t rec_size;
1715  ec_sdo_request_t *request = fsm->request;
1716 
1717  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1718  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1719  return;
1720  }
1721 
1722  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1723  request->errno = EIO;
1724  fsm->state = ec_fsm_coe_error;
1725  EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
1726  " datagram: ");
1728  return;
1729  }
1730 
1731  if (fsm->datagram->working_counter != 1) {
1732  request->errno = EIO;
1733  fsm->state = ec_fsm_coe_error;
1734  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1736  return;
1737  }
1738 
1739  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
1740  if (IS_ERR(data)) {
1741  request->errno = PTR_ERR(data);
1742  fsm->state = ec_fsm_coe_error;
1743  return;
1744  }
1745 
1746  if (mbox_prot != 0x03) { // CoE
1747  request->errno = EIO;
1748  fsm->state = ec_fsm_coe_error;
1749  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1750  mbox_prot);
1751  return;
1752  }
1753 
1754  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1755  // check for CoE response again
1756  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1757  fsm->retries = EC_FSM_RETRIES;
1759  return;
1760  }
1761 
1762  if (slave->master->debug_level) {
1763  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1764  ec_print_data(data, rec_size);
1765  }
1766 
1767  if (rec_size < 6) {
1768  request->errno = EIO;
1769  fsm->state = ec_fsm_coe_error;
1770  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1771  rec_size);
1772  ec_print_data(data, rec_size);
1773  return;
1774  }
1775 
1776  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1777  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1778  char subidxstr[10];
1779  request->errno = EIO;
1780  fsm->state = ec_fsm_coe_error;
1781  if (request->complete_access) {
1782  subidxstr[0] = 0x00;
1783  } else {
1784  sprintf(subidxstr, ":%02X", request->subindex);
1785  }
1786  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1787  request->index, subidxstr, request->data_size);
1788  if (rec_size < 10) {
1789  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1790  ec_print_data(data, rec_size);
1791  } else {
1792  fsm->request->abort_code = EC_READ_U32(data + 6);
1793  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1794  }
1795  return;
1796  }
1797 
1798  if (EC_READ_U16(data) >> 12 != 0x3 ||
1799  ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response
1800  if (slave->master->debug_level) {
1801  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1802  " Retrying...\n");
1803  ec_print_data(data, rec_size);
1804  }
1805  // check for CoE response again
1806  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1807  fsm->retries = EC_FSM_RETRIES;
1809  return;
1810  }
1811 
1812  if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) {
1813  EC_SLAVE_ERR(slave, "Invalid toggle received during"
1814  " segmented download:\n");
1815  ec_print_data(data, rec_size);
1816  request->errno = EIO;
1817  fsm->state = ec_fsm_coe_error;
1818  return;
1819  }
1820 
1821  fsm->offset += fsm->segment_size;
1822  fsm->remaining -= fsm->segment_size;
1823 
1824  if (fsm->remaining) { // more segments to download
1825  fsm->toggle = !fsm->toggle;
1827  } else {
1828  fsm->state = ec_fsm_coe_end; // success
1829  }
1830 }
1831 
1832 /*****************************************************************************/
1833 
1839  ec_fsm_coe_t *fsm,
1840  ec_datagram_t *datagram
1841  )
1842 {
1843  ec_slave_t *slave = fsm->slave;
1844  ec_sdo_request_t *request = fsm->request;
1845  ec_master_t *master = slave->master;
1846 
1847  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
1848  if (IS_ERR(data)) {
1849  request->errno = PTR_ERR(data);
1850  return PTR_ERR(data);
1851  }
1852 
1853  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1854  EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
1855  EC_WRITE_U16(data + 3, request->index);
1856  EC_WRITE_U8 (data + 5, request->subindex);
1857  memset(data + 6, 0x00, 4);
1858 
1859  if (master->debug_level) {
1860  EC_SLAVE_DBG(slave, 1, "Upload request:\n");
1861  ec_print_data(data, 10);
1862  }
1863 
1865  return 0;
1866 }
1867 
1868 /*****************************************************************************/
1869 
1875  ec_fsm_coe_t *fsm,
1876  ec_datagram_t *datagram
1877  )
1878 {
1879  ec_slave_t *slave = fsm->slave;
1880  ec_sdo_request_t *request = fsm->request;
1881 
1882  EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n",
1883  request->index, request->subindex);
1884 
1885  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1886  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1887  request->errno = EPROTONOSUPPORT;
1888  fsm->state = ec_fsm_coe_error;
1889  return;
1890  }
1891 
1892  fsm->retries = EC_FSM_RETRIES;
1893  fsm->request->jiffies_sent = jiffies;
1894 
1895  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1896  fsm->state = ec_fsm_coe_error;
1897  }
1898 }
1899 
1900 /*****************************************************************************/
1907  ec_fsm_coe_t *fsm,
1908  ec_datagram_t *datagram
1909  )
1910 {
1911  ec_slave_t *slave = fsm->slave;
1912  unsigned long diff_ms;
1913 
1914  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1915  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1916  fsm->state = ec_fsm_coe_error;
1917  }
1918  return;
1919  }
1920 
1921  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1922  fsm->request->errno = EIO;
1923  fsm->state = ec_fsm_coe_error;
1924  EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
1926  return;
1927  }
1928 
1929  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1930 
1931  if (fsm->datagram->working_counter != 1) {
1932  if (!fsm->datagram->working_counter) {
1933  if (diff_ms < fsm->request->response_timeout) {
1934 #if DEBUG_RETRIES
1935  EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
1936  " SDO upload request. Retrying after %lu ms...\n",
1937  diff_ms);
1938 #endif
1939  // no response; send request datagram again
1940  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
1941  fsm->state = ec_fsm_coe_error;
1942  }
1943  return;
1944  }
1945  }
1946  fsm->request->errno = EIO;
1947  fsm->state = ec_fsm_coe_error;
1948  EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
1949  " SDO 0x%04x:%x failed with timeout after %lu ms: ",
1950  fsm->request->index, fsm->request->subindex, diff_ms);
1952  return;
1953  }
1954 
1955 #if DEBUG_LONG
1956  if (diff_ms > 200) {
1957  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %lu ms.\n",
1958  fsm->request->index, fsm->request->subindex, diff_ms);
1959  }
1960 #endif
1961 
1962  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1963 
1964  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1965  fsm->retries = EC_FSM_RETRIES;
1966  fsm->state = ec_fsm_coe_up_check;
1967 }
1968 
1969 /*****************************************************************************/
1970 
1976  ec_fsm_coe_t *fsm,
1977  ec_datagram_t *datagram
1978  )
1979 {
1980  ec_slave_t *slave = fsm->slave;
1981 
1982  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1983  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1984  return;
1985  }
1986 
1987  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1988  fsm->request->errno = EIO;
1989  fsm->state = ec_fsm_coe_error;
1990  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1992  return;
1993  }
1994 
1995  if (fsm->datagram->working_counter != 1) {
1996  fsm->request->errno = EIO;
1997  fsm->state = ec_fsm_coe_error;
1998  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1999  " datagram failed: ");
2001  return;
2002  }
2003 
2004  if (!ec_slave_mbox_check(fsm->datagram)) {
2005  unsigned long diff_ms =
2006  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2007  1000 / HZ;
2008  if (diff_ms >= fsm->request->response_timeout) {
2009  fsm->request->errno = EIO;
2010  fsm->state = ec_fsm_coe_error;
2011  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
2012  " SDO 0x%04x:%x upload response.\n", diff_ms,
2013  fsm->request->index, fsm->request->subindex);
2014  return;
2015  }
2016 
2017  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2018  fsm->retries = EC_FSM_RETRIES;
2019  return;
2020  }
2021 
2022  // Fetch response
2023  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2024  fsm->retries = EC_FSM_RETRIES;
2026 }
2027 
2028 /*****************************************************************************/
2029 
2033  ec_fsm_coe_t *fsm,
2034  ec_datagram_t *datagram
2035  )
2036 {
2037  uint8_t *data =
2038  ec_slave_mbox_prepare_send(fsm->slave, datagram, 0x03, 10);
2039  if (IS_ERR(data)) {
2040  fsm->request->errno = PTR_ERR(data);
2041  fsm->state = ec_fsm_coe_error;
2042  return;
2043  }
2044 
2045  EC_WRITE_U16(data, 0x2 << 12); // SDO request
2046  EC_WRITE_U8 (data + 2, (fsm->toggle << 4 // toggle
2047  | 0x3 << 5)); // upload segment request
2048  memset(data + 3, 0x00, 7);
2049 
2050  if (fsm->slave->master->debug_level) {
2051  EC_SLAVE_DBG(fsm->slave, 1, "Upload segment request:\n");
2052  ec_print_data(data, 10);
2053  }
2054 }
2055 
2056 /*****************************************************************************/
2057 
2064  ec_fsm_coe_t *fsm,
2065  ec_datagram_t *datagram
2066  )
2067 {
2068  ec_slave_t *slave = fsm->slave;
2069  ec_master_t *master = slave->master;
2070  uint16_t rec_index;
2071  uint8_t *data, mbox_prot, rec_subindex;
2072  size_t rec_size, data_size;
2073  ec_sdo_request_t *request = fsm->request;
2074  unsigned int expedited, size_specified;
2075  int ret;
2076 
2077  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2078  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2079  return;
2080  }
2081 
2082  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2083  request->errno = EIO;
2084  fsm->state = ec_fsm_coe_error;
2085  EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
2086  " datagram: ");
2088  return;
2089  }
2090 
2091  if (fsm->datagram->working_counter != 1) {
2092  request->errno = EIO;
2093  fsm->state = ec_fsm_coe_error;
2094  EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
2096  return;
2097  }
2098 
2099  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2100  if (IS_ERR(data)) {
2101  request->errno = PTR_ERR(data);
2102  fsm->state = ec_fsm_coe_error;
2103  return;
2104  }
2105 
2106  if (master->debug_level) {
2107  EC_SLAVE_DBG(slave, 1, "Upload response:\n");
2108  ec_print_data(data, rec_size);
2109  }
2110 
2111  if (mbox_prot != 0x03) { // CoE
2112  request->errno = EIO;
2113  fsm->state = ec_fsm_coe_error;
2114  EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
2115  " as response.\n", mbox_prot);
2116  return;
2117  }
2118 
2119  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2120  // check for CoE response again
2121  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2122  fsm->retries = EC_FSM_RETRIES;
2123  fsm->state = ec_fsm_coe_up_check;
2124  return;
2125  }
2126 
2127  if (rec_size < 6) {
2128  request->errno = EIO;
2129  fsm->state = ec_fsm_coe_error;
2130  EC_SLAVE_ERR(slave, "Received currupted SDO upload response"
2131  " (%zu bytes)!\n", rec_size);
2132  ec_print_data(data, rec_size);
2133  return;
2134  }
2135 
2136  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2137  EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request
2138  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2139  request->index, request->subindex);
2140  if (rec_size >= 10) {
2141  request->abort_code = EC_READ_U32(data + 6);
2142  ec_canopen_abort_msg(slave, request->abort_code);
2143  } else {
2144  EC_SLAVE_ERR(slave, "No abort message.\n");
2145  }
2146  request->errno = EIO;
2147  fsm->state = ec_fsm_coe_error;
2148  return;
2149  }
2150 
2151  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2152  EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response
2153  EC_SLAVE_ERR(slave, "Received unknown response while"
2154  " uploading SDO 0x%04X:%02X.\n",
2155  request->index, request->subindex);
2156  ec_print_data(data, rec_size);
2157  request->errno = EIO;
2158  fsm->state = ec_fsm_coe_error;
2159  return;
2160  }
2161 
2162  rec_index = EC_READ_U16(data + 3);
2163  rec_subindex = EC_READ_U8(data + 5);
2164 
2165  if (rec_index != request->index || rec_subindex != request->subindex) {
2166  EC_SLAVE_ERR(slave, "Received upload response for wrong SDO"
2167  " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
2168  rec_index, rec_subindex, request->index, request->subindex);
2169  ec_print_data(data, rec_size);
2170 
2171  // check for CoE response again
2172  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2173  fsm->retries = EC_FSM_RETRIES;
2174  fsm->state = ec_fsm_coe_up_check;
2175  return;
2176  }
2177 
2178  // normal or expedited?
2179  expedited = EC_READ_U8(data + 2) & 0x02;
2180 
2181  if (expedited) {
2182  size_specified = EC_READ_U8(data + 2) & 0x01;
2183  if (size_specified) {
2184  fsm->complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
2185  } else {
2186  fsm->complete_size = 4;
2187  }
2188 
2189  if (rec_size < 6 + fsm->complete_size) {
2190  request->errno = EIO;
2191  fsm->state = ec_fsm_coe_error;
2192  EC_SLAVE_ERR(slave, "Received corrupted SDO expedited upload"
2193  " response (only %zu bytes)!\n", rec_size);
2194  ec_print_data(data, rec_size);
2195  return;
2196  }
2197 
2198  ret = ec_sdo_request_copy_data(request, data + 6, fsm->complete_size);
2199  if (ret) {
2200  request->errno = -ret;
2201  fsm->state = ec_fsm_coe_error;
2202  return;
2203  }
2204  } else { // normal
2205  if (rec_size < 10) {
2206  request->errno = EIO;
2207  fsm->state = ec_fsm_coe_error;
2208  EC_SLAVE_ERR(slave, "Received currupted SDO normal upload"
2209  " response (only %zu bytes)!\n", rec_size);
2210  ec_print_data(data, rec_size);
2211  return;
2212  }
2213 
2214  data_size = rec_size - 10;
2215  fsm->complete_size = EC_READ_U32(data + 6);
2216 
2217  if (!fsm->complete_size) {
2218  request->errno = EIO;
2219  fsm->state = ec_fsm_coe_error;
2220  EC_SLAVE_ERR(slave, "No complete size supplied!\n");
2221  ec_print_data(data, rec_size);
2222  return;
2223  }
2224 
2225  ret = ec_sdo_request_alloc(request, fsm->complete_size);
2226  if (ret) {
2227  request->errno = -ret;
2228  fsm->state = ec_fsm_coe_error;
2229  return;
2230  }
2231 
2232  ret = ec_sdo_request_copy_data(request, data + 10, data_size);
2233  if (ret) {
2234  request->errno = -ret;
2235  fsm->state = ec_fsm_coe_error;
2236  return;
2237  }
2238 
2239  fsm->toggle = 0;
2240 
2241  if (data_size < fsm->complete_size) {
2242  EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
2243  " Segmenting...\n", data_size, fsm->complete_size);
2245  fsm->retries = EC_FSM_RETRIES;
2247  return;
2248  }
2249  }
2250 
2251  if (master->debug_level) {
2252  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2253  ec_print_data(request->data, request->data_size);
2254  }
2255 
2256  fsm->state = ec_fsm_coe_end; // success
2257 }
2258 
2259 /*****************************************************************************/
2260 
2267  ec_fsm_coe_t *fsm,
2268  ec_datagram_t *datagram
2269  )
2270 {
2271  ec_slave_t *slave = fsm->slave;
2272 
2273  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2275  return;
2276  }
2277 
2278  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2279  fsm->request->errno = EIO;
2280  fsm->state = ec_fsm_coe_error;
2281  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2282  " request datagram: ");
2284  return;
2285  }
2286 
2287  if (fsm->datagram->working_counter != 1) {
2288  fsm->request->errno = EIO;
2289  fsm->state = ec_fsm_coe_error;
2290  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2291  " request failed: ");
2293  return;
2294  }
2295 
2296  fsm->jiffies_start = fsm->datagram->jiffies_sent;
2297 
2298  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2299  fsm->retries = EC_FSM_RETRIES;
2301 }
2302 
2303 /*****************************************************************************/
2304 
2310  ec_fsm_coe_t *fsm,
2311  ec_datagram_t *datagram
2312  )
2313 {
2314  ec_slave_t *slave = fsm->slave;
2315 
2316  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2317  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2318  return;
2319  }
2320 
2321  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2322  fsm->request->errno = EIO;
2323  fsm->state = ec_fsm_coe_error;
2324  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
2325  " datagram: ");
2327  return;
2328  }
2329 
2330  if (fsm->datagram->working_counter != 1) {
2331  fsm->request->errno = EIO;
2332  fsm->state = ec_fsm_coe_error;
2333  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
2334  " failed: ");
2336  return;
2337  }
2338 
2339  if (!ec_slave_mbox_check(fsm->datagram)) {
2340  unsigned long diff_ms =
2341  (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2342  1000 / HZ;
2343  if (diff_ms >= fsm->request->response_timeout) {
2344  fsm->request->errno = EIO;
2345  fsm->state = ec_fsm_coe_error;
2346  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
2347  " segment response.\n");
2348  return;
2349  }
2350 
2351  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2352  fsm->retries = EC_FSM_RETRIES;
2353  return;
2354  }
2355 
2356  // Fetch response
2357  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2358  fsm->retries = EC_FSM_RETRIES;
2360 }
2361 
2362 /*****************************************************************************/
2363 
2370  ec_fsm_coe_t *fsm,
2371  ec_datagram_t *datagram
2372  )
2373 {
2374  ec_slave_t *slave = fsm->slave;
2375  ec_master_t *master = slave->master;
2376  uint8_t *data, mbox_prot;
2377  size_t rec_size, data_size;
2378  ec_sdo_request_t *request = fsm->request;
2379  unsigned int last_segment;
2380 
2381  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2382  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2383  return;
2384  }
2385 
2386  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2387  request->errno = EIO;
2388  fsm->state = ec_fsm_coe_error;
2389  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2390  " response datagram: ");
2392  return;
2393  }
2394 
2395  if (fsm->datagram->working_counter != 1) {
2396  request->errno = EIO;
2397  fsm->state = ec_fsm_coe_error;
2398  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2399  " response failed: ");
2401  return;
2402  }
2403 
2404  data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
2405  if (IS_ERR(data)) {
2406  request->errno = PTR_ERR(data);
2407  fsm->state = ec_fsm_coe_error;
2408  return;
2409  }
2410 
2411  if (master->debug_level) {
2412  EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
2413  ec_print_data(data, rec_size);
2414  }
2415 
2416  if (mbox_prot != 0x03) { // CoE
2417  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
2418  mbox_prot);
2419  request->errno = EIO;
2420  fsm->state = ec_fsm_coe_error;
2421  return;
2422  }
2423 
2424  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2425  // check for CoE response again
2426  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2427  fsm->retries = EC_FSM_RETRIES;
2429  return;
2430  }
2431 
2432  if (rec_size < 10) {
2433  EC_SLAVE_ERR(slave, "Received currupted SDO upload"
2434  " segment response!\n");
2435  ec_print_data(data, rec_size);
2436  request->errno = EIO;
2437  fsm->state = ec_fsm_coe_error;
2438  return;
2439  }
2440 
2441  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2442  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
2443  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2444  request->index, request->subindex);
2445  request->abort_code = EC_READ_U32(data + 6);
2446  ec_canopen_abort_msg(slave, request->abort_code);
2447  request->errno = EIO;
2448  fsm->state = ec_fsm_coe_error;
2449  return;
2450  }
2451 
2452  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2453  EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
2454  if (fsm->slave->master->debug_level) {
2455  EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
2456  ec_print_data(data, rec_size);
2457  }
2458  // check for CoE response again
2459  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2460  fsm->retries = EC_FSM_RETRIES;
2462  return;
2463  }
2464 
2465  data_size = rec_size - 3; /* Header of segment upload is smaller than
2466  normal upload */
2467  if (rec_size == 10) {
2468  uint8_t seg_size = (EC_READ_U8(data + 2) & 0xE) >> 1;
2469  data_size -= seg_size;
2470  }
2471 
2472  if (request->data_size + data_size > fsm->complete_size) {
2473  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X failed: Fragment"
2474  " exceeding complete size!\n",
2475  request->index, request->subindex);
2476  request->errno = EOVERFLOW;
2477  fsm->state = ec_fsm_coe_error;
2478  return;
2479  }
2480 
2481  memcpy(request->data + request->data_size, data + 3, data_size);
2482  request->data_size += data_size;
2483 
2484  last_segment = EC_READ_U8(data + 2) & 0x01;
2485  if (!last_segment) {
2486  fsm->toggle = !fsm->toggle;
2488  fsm->retries = EC_FSM_RETRIES;
2490  return;
2491  }
2492 
2493  if (request->data_size != fsm->complete_size) {
2494  EC_SLAVE_WARN(slave, "SDO upload 0x%04X:%02X: Assembled data"
2495  " size (%zu) does not match complete size (%u)!\n",
2496  request->index, request->subindex,
2497  request->data_size, fsm->complete_size);
2498  }
2499 
2500  if (master->debug_level) {
2501  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2502  ec_print_data(request->data, request->data_size);
2503  }
2504 
2505  fsm->state = ec_fsm_coe_end; // success
2506 }
2507 
2508 /*****************************************************************************/
2509 
2515  ec_fsm_coe_t *fsm,
2516  ec_datagram_t *datagram
2517  )
2518 {
2519 }
2520 
2521 /*****************************************************************************/
2522 
2528  ec_fsm_coe_t *fsm,
2529  ec_datagram_t *datagram
2530  )
2531 {
2532 }
2533 
2534 /*****************************************************************************/
int ec_fsm_coe_prepare_down_start(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare a donwnload request.
Definition: fsm_coe.c:1192
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:59
void ec_fsm_coe_down_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN REQUEST.
Definition: fsm_coe.c:1337
void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY CHECK.
Definition: fsm_coe.c:956
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
void ec_fsm_coe_dict_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT START.
Definition: fsm_coe.c:340
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
Definition: datagram.h:104
void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:2266
void ec_fsm_coe_dict_entry_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY REQUEST.
Definition: fsm_coe.c:914
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:149
int ec_fsm_coe_prepare_up(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare an upload request.
Definition: fsm_coe.c:1838
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_down_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN RESPONSE.
Definition: fsm_coe.c:1529
size_t segment_size
Current segment size.
Definition: fsm_coe.h:66
CANopen SDO request.
Definition: sdo_request.h:48
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:279
Access rights in PREOP.
Definition: globals.h:193
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:90
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
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2187
uint32_t abort_code
SDO request abort code.
Definition: sdo_request.h:68
void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC RESPONSE.
Definition: fsm_coe.c:779
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:1463
void ec_fsm_coe_dict_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT RESPONSE.
Definition: fsm_coe.c:495
uint16_t working_counter
Working counter.
Definition: datagram.h:99
struct list_head list
List item.
Definition: sdo.h:50
#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
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
const char * message
Message belonging to code.
Definition: globals.h:280
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:1906
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:194
void ec_fsm_coe_dict_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT REQUEST.
Definition: fsm_coe.c:372
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:278
ec_datagram_state_t state
State.
Definition: datagram.h:100
void ec_fsm_coe_down_seg_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN SEG RESPONSE.
Definition: fsm_coe.c:1707
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:2221
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:2032
uint8_t enable_sdo_info
SDO information service available.
Definition: globals.h:159
void ec_fsm_coe_end(ec_fsm_coe_t *, ec_datagram_t *)
State: END.
Definition: fsm_coe.c:2527
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:467
unsigned int debug_level
Master debug level.
Definition: master.h:286
#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
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
void ec_fsm_coe_dict_desc_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC REQUEST.
Definition: fsm_coe.c:650
void ec_fsm_coe_down_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN START.
Definition: fsm_coe.c:1286
void ec_fsm_coe_up_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP START.
Definition: fsm_coe.c:1874
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:2204
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:2151
uint32_t complete_size
Used when segmenting.
Definition: fsm_coe.h:62
void ec_fsm_coe_down_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN CHECK.
Definition: fsm_coe.c:1405
void ec_fsm_coe_error(ec_fsm_coe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_coe.c:2514
void(* state)(ec_fsm_coe_t *, ec_datagram_t *)
CoE state function.
Definition: fsm_coe.h:56
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:749
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_dictionary(ec_fsm_coe_t *fsm, ec_slave_t *slave)
Starts reading a slaves' SDO dictionary.
Definition: fsm_coe.c:192
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_down_seg_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN SEG CHECK.
Definition: fsm_coe.c:1650
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:95
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:341
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
void ec_fsm_coe_dict_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT CHECK.
Definition: fsm_coe.c:412
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:2135
ec_coe_emerg_ring_t emerg_ring
CoE emergency ring buffer.
Definition: slave_config.h:149
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:565
Mailbox functionality.
void ec_coe_emerg_ring_push(ec_coe_emerg_ring_t *ring, const u8 *msg)
Add a new emergency message.
void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY RESPONSE.
Definition: fsm_coe.c:1013
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
Access rights in OP.
Definition: globals.h:195
Queued for sending.
Definition: datagram.h:76
Timed out (dequeued).
Definition: datagram.h:79
uint8_t max_subindex
Maximum subindex.
Definition: sdo.h:55
void ec_fsm_coe_up_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP CHECK.
Definition: fsm_coe.c:1975
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
void ec_fsm_coe_dict_desc_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC CHECK.
Definition: fsm_coe.c:693
void ec_fsm_coe_up_seg_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP CHECK.
Definition: fsm_coe.c:2309
void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2369
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2119
EtherCAT slave configuration.
Definition: slave_config.h:118
#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:419
Received (dequeued).
Definition: datagram.h:78
EtherCAT master.
Definition: master.h:194
void ec_fsm_coe_up_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2063
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
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