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 
83 
92 
102 
105 
106 /*****************************************************************************/
107 
115  {0x05030000, "Toggle bit not changed"},
116  {0x05040000, "SDO protocol timeout"},
117  {0x05040001, "Client/Server command specifier not valid or unknown"},
118  {0x05040005, "Out of memory"},
119  {0x06010000, "Unsupported access to an object"},
120  {0x06010001, "Attempt to read a write-only object"},
121  {0x06010002, "Attempt to write a read-only object"},
122  {0x06020000, "This object does not exist in the object directory"},
123  {0x06040041, "The object cannot be mapped into the PDO"},
124  {0x06040042, "The number and length of the objects to be mapped would"
125  " exceed the PDO length"},
126  {0x06040043, "General parameter incompatibility reason"},
127  {0x06040047, "Gerneral internal incompatibility in device"},
128  {0x06060000, "Access failure due to a hardware error"},
129  {0x06070010, "Data type does not match, length of service parameter does"
130  " not match"},
131  {0x06070012, "Data type does not match, length of service parameter too"
132  " high"},
133  {0x06070013, "Data type does not match, length of service parameter too"
134  " low"},
135  {0x06090011, "Subindex does not exist"},
136  {0x06090030, "Value range of parameter exceeded"},
137  {0x06090031, "Value of parameter written too high"},
138  {0x06090032, "Value of parameter written too low"},
139  {0x06090036, "Maximum value is less than minimum value"},
140  {0x08000000, "General error"},
141  {0x08000020, "Data cannot be transferred or stored to the application"},
142  {0x08000021, "Data cannot be transferred or stored to the application"
143  " because of local control"},
144  {0x08000022, "Data cannot be transferred or stored to the application"
145  " because of the present device state"},
146  {0x08000023, "Object dictionary dynamic generation fails or no object"
147  " dictionary is present"},
148  {}
149 };
150 
151 /*****************************************************************************/
152 
156  const ec_slave_t *slave,
157  uint32_t abort_code
158  )
159 {
160  const ec_code_msg_t *abort_msg;
161 
162  for (abort_msg = sdo_abort_messages; abort_msg->code; abort_msg++) {
163  if (abort_msg->code == abort_code) {
164  EC_SLAVE_ERR(slave, "SDO abort message 0x%08X: \"%s\".\n",
165  abort_msg->code, abort_msg->message);
166  return;
167  }
168  }
169 
170  EC_SLAVE_ERR(slave, "Unknown SDO abort code 0x%08X.\n", abort_code);
171 }
172 
173 /*****************************************************************************/
174 
178  ec_fsm_coe_t *fsm
179  )
180 {
181  fsm->state = NULL;
182  fsm->datagram = NULL;
183 }
184 
185 /*****************************************************************************/
186 
190  ec_fsm_coe_t *fsm
191  )
192 {
193 }
194 
195 /*****************************************************************************/
196 
200  ec_fsm_coe_t *fsm,
201  ec_slave_t *slave
202  )
203 {
204  fsm->slave = slave;
206 }
207 
208 /*****************************************************************************/
209 
213  ec_fsm_coe_t *fsm,
214  ec_slave_t *slave,
215  ec_sdo_request_t *request
216  )
217 {
218  fsm->slave = slave;
219  fsm->request = request;
220 
221  if (request->dir == EC_DIR_OUTPUT) {
223  }
224  else {
225  fsm->state = ec_fsm_coe_up_start;
226  }
227 }
228 
229 /*****************************************************************************/
230 
236  ec_fsm_coe_t *fsm,
237  ec_datagram_t *datagram
238  )
239 {
240  if (fsm->state == ec_fsm_coe_end || fsm->state == ec_fsm_coe_error)
241  return 0;
242 
243  fsm->state(fsm, datagram);
244 
245  if (fsm->state == ec_fsm_coe_end || fsm->state == ec_fsm_coe_error) {
246  fsm->datagram = NULL;
247  return 0;
248  }
249 
250  fsm->datagram = datagram;
251  return 1;
252 }
253 
254 /*****************************************************************************/
255 
260  const ec_fsm_coe_t *fsm
261  )
262 {
263  return fsm->state == ec_fsm_coe_end;
264 }
265 
266 /*****************************************************************************/
267 
275  ec_fsm_coe_t *fsm,
276  const uint8_t *data,
277  size_t size
278  )
279 {
280  if (size < 2 || ((EC_READ_U16(data) >> 12) & 0x0F) != 0x01)
281  return 0;
282 
283  if (size < 10) {
284  EC_SLAVE_WARN(fsm->slave, "Received incomplete CoE Emergency"
285  " request:\n");
286  ec_print_data(data, size);
287  return 1;
288  }
289 
290  {
291  ec_slave_config_t *sc = fsm->slave->config;
292  if (sc) {
293  ec_coe_emerg_ring_push(&sc->emerg_ring, data + 2);
294  }
295  }
296 
297  EC_SLAVE_WARN(fsm->slave, "CoE Emergency Request received:\n"
298  "Error code 0x%04X, Error register 0x%02X, data:\n",
299  EC_READ_U16(data + 2), EC_READ_U8(data + 4));
300  ec_print_data(data + 5, 5);
301  return 1;
302 }
303 
304 /******************************************************************************
305  * CoE dictionary state machine
306  *****************************************************************************/
307 
313  ec_fsm_coe_t *fsm,
314  ec_datagram_t *datagram
315  )
316 {
317  ec_slave_t *slave = fsm->slave;
318  uint8_t *data = ec_slave_mbox_prepare_send(slave, datagram,
319  EC_MBOX_TYPE_COE, 8);
320  if (IS_ERR(data)) {
321  return PTR_ERR(data);
322  }
323 
324  EC_WRITE_U16(data, 0x8 << 12); // SDO information
325  EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
326  EC_WRITE_U8 (data + 3, 0x00);
327  EC_WRITE_U16(data + 4, 0x0000);
328  EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
329 
331  return 0;
332 }
333 
334 /*****************************************************************************/
335 
339  ec_fsm_coe_t *fsm,
340  ec_datagram_t *datagram
341  )
342 {
343  ec_slave_t *slave = fsm->slave;
344 
345  if (!slave->sii_image) {
346  EC_SLAVE_ERR(slave, "Slave cannot process CoE dictionary request."
347  " SII data not available.\n");
348  fsm->state = ec_fsm_coe_error;
349  return;
350  }
351 
352  if (!(slave->sii_image->sii.mailbox_protocols & EC_MBOX_COE)) {
353  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
354  fsm->state = ec_fsm_coe_error;
355  return;
356  }
357 
359  EC_SLAVE_ERR(slave, "Slave does not support"
360  " SDO information service!\n");
361  fsm->state = ec_fsm_coe_error;
362  return;
363  }
364 
365  fsm->retries = EC_FSM_RETRIES;
366 
367  if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
368  fsm->state = ec_fsm_coe_error;
369  }
370 }
371 
372 /*****************************************************************************/
373 
378  ec_fsm_coe_t *fsm,
379  ec_datagram_t *datagram
380  )
381 {
382  ec_slave_t *slave = fsm->slave;
383 
384  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
385  if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
386  fsm->state = ec_fsm_coe_error;
387  }
388  return;
389  }
390 
391  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
392  fsm->state = ec_fsm_coe_error;
393  EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
394  " request datagram: ");
396  return;
397  }
398 
399  if (fsm->datagram->working_counter != 1) {
400  fsm->state = ec_fsm_coe_error;
401  EC_SLAVE_ERR(slave, "Reception of CoE dictionary request failed: ");
403  return;
404  }
405 
406  fsm->jiffies_start = fsm->datagram->jiffies_sent;
407 
408  // mailbox read check is skipped if a read request is already ongoing
409  if (ec_read_mbox_locked(slave)) {
411  // the datagram is not used and marked as invalid
412  datagram->state = EC_DATAGRAM_INVALID;
413  } else {
414  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
415  fsm->retries = EC_FSM_RETRIES;
417  }
418 }
419 
420 /*****************************************************************************/
421 
425  ec_fsm_coe_t *fsm,
426  ec_datagram_t *datagram
427  )
428 {
429  ec_slave_t *slave = fsm->slave;
430 
431  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
432  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
433  return;
434  }
435 
436  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
437  fsm->state = ec_fsm_coe_error;
439  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
441  return;
442  }
443 
444  if (fsm->datagram->working_counter != 1) {
445  fsm->state = ec_fsm_coe_error;
447  EC_SLAVE_ERR(slave,"Reception of CoE mailbox check"
448  " datagram failed: ");
450  return;
451  }
452 
453  if (!ec_slave_mbox_check(fsm->datagram)) {
454  unsigned long diff_ms = 0;
455 
456  // check that data is not already received by another read request
457  if (slave->mbox_coe_data.payload_size > 0) {
460  fsm->state(fsm, datagram);
461  return;
462  }
463 
464  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
465  1000 / HZ;
466 
467  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
468  fsm->state = ec_fsm_coe_error;
470  EC_SLAVE_ERR(slave, "Timeout while waiting for"
471  " SDO dictionary list response.\n");
472  return;
473  }
474 
475  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
476  fsm->retries = EC_FSM_RETRIES;
477  return;
478  }
479 
480  // Fetch response
481  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
482  fsm->retries = EC_FSM_RETRIES;
484 }
485 
486 /*****************************************************************************/
487 
493  ec_fsm_coe_t *fsm,
494  ec_datagram_t *datagram
495  )
496 {
497  ec_slave_t *slave = fsm->slave;
498  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
499  8);
500  if (IS_ERR(data)) {
501  return PTR_ERR(data);
502  }
503 
504  EC_WRITE_U16(data, 0x8 << 12); // SDO information
505  EC_WRITE_U8 (data + 2, 0x03); // Get object description request
506  EC_WRITE_U8 (data + 3, 0x00);
507  EC_WRITE_U16(data + 4, 0x0000);
508  EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
509 
511  return 0;
512 }
513 
514 /*****************************************************************************/
515 
522  ec_fsm_coe_t *fsm,
523  ec_datagram_t *datagram
524  )
525 {
526  ec_slave_t *slave = fsm->slave;
527 
528  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
529  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
530  return;
531  }
532 
533  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
534  fsm->state = ec_fsm_coe_error;
536  EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
537  " response datagram: ");
539  return;
540  }
541 
542  if (fsm->datagram->working_counter != 1) {
543  // only an error if data has not already been read by another read request
544  if (slave->mbox_coe_data.payload_size == 0) {
545  fsm->state = ec_fsm_coe_error;
547  EC_SLAVE_ERR(slave, "Reception of CoE dictionary response failed: ");
549  return;
550  }
551  }
554  fsm->state(fsm, datagram);
555 }
556 
557 
558 /*****************************************************************************/
559 
566  ec_fsm_coe_t *fsm,
567  ec_datagram_t *datagram
568  )
569 {
570  ec_slave_t *slave = fsm->slave;
571  uint8_t *data, mbox_prot;
572  size_t rec_size;
573  unsigned int sdo_count, i;
574  uint16_t sdo_index, fragments_left;
575  ec_sdo_t *sdo;
576  bool first_segment;
577  size_t index_list_offset;
578 
579  // process the data available or initiate a new mailbox read check
580  if (slave->mbox_coe_data.payload_size > 0) {
581  slave->mbox_coe_data.payload_size = 0;
582  } else {
583  // initiate a new mailbox read check if required data is not available
584  if (ec_read_mbox_locked(slave)) {
585  // await current read request and mark the datagram as invalid
586  datagram->state = EC_DATAGRAM_INVALID;
587  } else {
588  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
590  }
591  return;
592  }
593 
594  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
595  if (IS_ERR(data)) {
596  fsm->state = ec_fsm_coe_error;
597  return;
598  }
599 
600  if (mbox_prot != EC_MBOX_TYPE_COE) {
601  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
602  mbox_prot);
603  fsm->state = ec_fsm_coe_error;
604  return;
605  }
606 
607  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
608  // check for CoE response again
609  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
610  fsm->retries = EC_FSM_RETRIES;
612  return;
613  }
614 
615  if (rec_size < 3) {
616  EC_SLAVE_ERR(slave, "Received corrupted SDO dictionary response"
617  " (size %zu).\n", rec_size);
618  fsm->state = ec_fsm_coe_error;
619  return;
620  }
621 
622  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
623  (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
624  EC_SLAVE_ERR(slave, "SDO information error response!\n");
625  if (rec_size < 10) {
626  EC_SLAVE_ERR(slave, "Incomplete SDO information"
627  " error response:\n");
628  ec_print_data(data, rec_size);
629  } else {
630  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
631  }
632  fsm->state = ec_fsm_coe_error;
633  return;
634  }
635 
636  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
637  (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
638  if (fsm->slave->master->debug_level) {
639  EC_SLAVE_DBG(slave, 1, "Invalid SDO list response!"
640  " Retrying...\n");
641  ec_print_data(data, rec_size);
642  }
643  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
644  fsm->retries = EC_FSM_RETRIES;
646  return;
647  }
648 
649  first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
650  index_list_offset = first_segment ? 8 : 6;
651 
652  if (rec_size < index_list_offset || rec_size % 2) {
653  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
654  ec_print_data(data, rec_size);
655  fsm->state = ec_fsm_coe_error;
656  return;
657  }
658 
659  sdo_count = (rec_size - index_list_offset) / 2;
660 
661  for (i = 0; i < sdo_count; i++) {
662  sdo_index = EC_READ_U16(data + index_list_offset + i * 2);
663  if (!sdo_index) {
664  EC_SLAVE_DBG(slave, 1, "SDO dictionary contains index 0x0000.\n");
665  continue;
666  }
667 
668  if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
669  EC_SLAVE_ERR(slave, "Failed to allocate memory for SDO!\n");
670  fsm->state = ec_fsm_coe_error;
671  return;
672  }
673 
674  ec_sdo_init(sdo, slave, sdo_index);
675  list_add_tail(&sdo->list, &slave->sdo_dictionary);
676  }
677 
678  fragments_left = EC_READ_U16(data + 4);
679  if (fragments_left) {
680  EC_SLAVE_DBG(slave, 1, "SDO list fragments left: %u\n",
681  fragments_left);
682  }
683 
684  if (EC_READ_U8(data + 2) & 0x80 || fragments_left) {
685  // more messages waiting. check again.
686  fsm->jiffies_start = fsm->datagram->jiffies_sent;
687  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
688  fsm->retries = EC_FSM_RETRIES;
690  return;
691  }
692 
693  if (list_empty(&slave->sdo_dictionary)) {
694  // no SDOs in dictionary. finished.
695  fsm->state = ec_fsm_coe_end; // success
696  return;
697  }
698 
699  // fetch SDO descriptions
700  fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);
701 
702  fsm->retries = EC_FSM_RETRIES;
703  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
704  fsm->state = ec_fsm_coe_error;
705  }
706 }
707 
708 /*****************************************************************************/
709 
716  ec_fsm_coe_t *fsm,
717  ec_datagram_t *datagram
718  )
719 {
720  ec_slave_t *slave = fsm->slave;
721 
722  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
723  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
724  fsm->state = ec_fsm_coe_error;
725  }
726  return;
727  }
728 
729  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
730  fsm->state = ec_fsm_coe_error;
731  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
732  " description request datagram: ");
734  return;
735  }
736 
737  if (fsm->datagram->working_counter != 1) {
738  fsm->state = ec_fsm_coe_error;
739  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
740  " request failed: ");
742  return;
743  }
744 
745  fsm->jiffies_start = fsm->datagram->jiffies_sent;
746 
747  // mailbox read check is skipped if a read request is already ongoing
748  if (ec_read_mbox_locked(slave)) {
750  // the datagram is not used and marked as invalid
751  datagram->state = EC_DATAGRAM_INVALID;
752  } else {
753  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
754  fsm->retries = EC_FSM_RETRIES;
756  }
757 }
758 
759 /*****************************************************************************/
760 
766  ec_fsm_coe_t *fsm,
767  ec_datagram_t *datagram
768  )
769 {
770  ec_slave_t *slave = fsm->slave;
771 
772  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
773  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
774  return;
775  }
776 
777  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
778  fsm->state = ec_fsm_coe_error;
780  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
782  return;
783  }
784 
785  if (fsm->datagram->working_counter != 1) {
786  fsm->state = ec_fsm_coe_error;
788  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
789  " datagram failed: ");
791  return;
792  }
793 
794  if (!ec_slave_mbox_check(fsm->datagram)) {
795  unsigned long diff_ms = 0;
796 
797  // check that data is not already received by another read request
798  if (slave->mbox_coe_data.payload_size > 0) {
801  fsm->state(fsm, datagram);
802  return;
803  }
804 
805  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
806  1000 / HZ;
807 
808  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
809  fsm->state = ec_fsm_coe_error;
811  EC_SLAVE_ERR(slave, "Timeout while waiting for"
812  " SDO 0x%04x object description response.\n",
813  fsm->sdo->index);
814  return;
815  }
816 
817  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
818  fsm->retries = EC_FSM_RETRIES;
819  return;
820  }
821 
822  // Fetch response
823  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
824  fsm->retries = EC_FSM_RETRIES;
826 }
827 
828 /*****************************************************************************/
829 
835  ec_fsm_coe_t *fsm,
836  ec_datagram_t *datagram
837  )
838 {
839  ec_slave_t *slave = fsm->slave;
840  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
841  10);
842  if (IS_ERR(data)) {
843  return PTR_ERR(data);
844  }
845 
846  EC_WRITE_U16(data, 0x8 << 12); // SDO information
847  EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
848  EC_WRITE_U8 (data + 3, 0x00);
849  EC_WRITE_U16(data + 4, 0x0000);
850  EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
851  EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
852  EC_WRITE_U8 (data + 9, 0x01); // value info (access rights only)
853 
855  return 0;
856 }
857 
858 /*****************************************************************************/
859 
866  ec_fsm_coe_t *fsm,
867  ec_datagram_t *datagram
868  )
869 {
870  ec_slave_t *slave = fsm->slave;
871 
872  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
873  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
874  return;
875  }
876 
877  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
878  fsm->state = ec_fsm_coe_error;
880  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description"
881  " response datagram: ");
883  return;
884  }
885 
886  if (fsm->datagram->working_counter != 1) {
887  // only an error if data has not already been read by another read request
888  if (slave->mbox_coe_data.payload_size == 0) {
889  fsm->state = ec_fsm_coe_error;
891  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
892  " response failed: ");
894  return;
895  }
896  }
899  fsm->state(fsm, datagram);
900 }
901 
902 /*****************************************************************************/
903 
910  ec_fsm_coe_t *fsm,
911  ec_datagram_t *datagram
912  )
913 {
914  ec_slave_t *slave = fsm->slave;
915  ec_sdo_t *sdo = fsm->sdo;
916  uint8_t *data, mbox_prot;
917  size_t rec_size, name_size;
918 
919  // process the data available or initiate a new mailbox read check
920  if (slave->mbox_coe_data.payload_size > 0) {
921  slave->mbox_coe_data.payload_size = 0;
922  } else {
923  // initiate a new mailbox read check if required data is not available
924  if (ec_read_mbox_locked(slave)) {
925  // await current read request and mark the datagram as invalid
926  datagram->state = EC_DATAGRAM_INVALID;
927  } else {
928  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
930  }
931  return;
932  }
933 
934  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
935  if (IS_ERR(data)) {
936  fsm->state = ec_fsm_coe_error;
937  return;
938  }
939 
940  if (mbox_prot != EC_MBOX_TYPE_COE) {
941  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
942  mbox_prot);
943  fsm->state = ec_fsm_coe_error;
944  return;
945  }
946 
947  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
948  // check for CoE response again
949  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
950  fsm->retries = EC_FSM_RETRIES;
952  return;
953  }
954 
955  if (rec_size < 3) {
956  EC_SLAVE_ERR(slave, "Received corrupted SDO description response"
957  " (size %zu).\n", rec_size);
958  fsm->state = ec_fsm_coe_error;
959  return;
960  }
961 
962  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
963  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
964  EC_SLAVE_ERR(slave, "SDO information error response while"
965  " fetching SDO 0x%04X!\n", sdo->index);
966  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
967  fsm->state = ec_fsm_coe_error;
968  return;
969  }
970 
971  if (rec_size < 8) {
972  EC_SLAVE_ERR(slave, "Received corrupted SDO"
973  " description response (size %zu).\n", rec_size);
974  fsm->state = ec_fsm_coe_error;
975  return;
976  }
977 
978  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
979  (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response
980  EC_READ_U16(data + 6) != sdo->index) { // SDO index
981  if (fsm->slave->master->debug_level) {
982  EC_SLAVE_DBG(slave, 1, "Invalid object description response while"
983  " fetching SDO 0x%04X!\n", sdo->index);
984  ec_print_data(data, rec_size);
985  }
986  // check for CoE response again
987  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
988  fsm->retries = EC_FSM_RETRIES;
990  return;
991  }
992 
993  if (rec_size < 12) {
994  EC_SLAVE_ERR(slave, "Invalid data size!\n");
995  ec_print_data(data, rec_size);
996  fsm->state = ec_fsm_coe_error;
997  return;
998  }
999 
1000  sdo->max_subindex = EC_READ_U8(data + 10);
1001  sdo->object_code = EC_READ_U8(data + 11);
1002 
1003  name_size = rec_size - 12;
1004  if (name_size) {
1005  if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) {
1006  EC_SLAVE_ERR(slave, "Failed to allocate SDO name!\n");
1007  fsm->state = ec_fsm_coe_error;
1008  return;
1009  }
1010 
1011  memcpy(sdo->name, data + 12, name_size);
1012  sdo->name[name_size] = 0;
1013  }
1014 
1015  if (EC_READ_U8(data + 2) & 0x80) {
1016  EC_SLAVE_ERR(slave, "Fragment follows (not implemented)!\n");
1017  fsm->state = ec_fsm_coe_error;
1018  return;
1019  }
1020 
1021  // start fetching entries
1022 
1023  fsm->subindex = 0;
1024  fsm->retries = EC_FSM_RETRIES;
1025 
1026  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1027  fsm->state = ec_fsm_coe_error;
1028  }
1029 }
1030 
1031 /*****************************************************************************/
1032 
1039  ec_fsm_coe_t *fsm,
1040  ec_datagram_t *datagram
1041  )
1042 {
1043  ec_slave_t *slave = fsm->slave;
1044 
1045  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1046  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1047  fsm->state = ec_fsm_coe_error;
1048  }
1049  return;
1050  }
1051 
1052  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1053  fsm->state = ec_fsm_coe_error;
1054  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry"
1055  " request datagram: ");
1057  return;
1058  }
1059 
1060  if (fsm->datagram->working_counter != 1) {
1061  fsm->state = ec_fsm_coe_error;
1062  EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: ");
1064  return;
1065  }
1066 
1067  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1068 
1069  // mailbox read check is skipped if a read request is already ongoing
1070  if (ec_read_mbox_locked(slave)) {
1072  // the datagram is not used and marked as invalid
1073  datagram->state = EC_DATAGRAM_INVALID;
1074  } else {
1075  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1076  fsm->retries = EC_FSM_RETRIES;
1078  }
1079 }
1080 
1081 /*****************************************************************************/
1082 
1088  ec_fsm_coe_t *fsm,
1089  ec_datagram_t *datagram
1090  )
1091 {
1092  ec_slave_t *slave = fsm->slave;
1093 
1094  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1095  ec_slave_mbox_prepare_check(slave, datagram); // can not fail
1096  return;
1097  }
1098 
1099  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1100  fsm->state = ec_fsm_coe_error;
1101  ec_read_mbox_lock_clear(slave);
1102  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1104  return;
1105  }
1106 
1107  if (fsm->datagram->working_counter != 1) {
1108  fsm->state = ec_fsm_coe_error;
1109  ec_read_mbox_lock_clear(slave);
1110  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1111  " datagram failed: ");
1113  return;
1114  }
1115 
1116  if (!ec_slave_mbox_check(fsm->datagram)) {
1117  unsigned long diff_ms = 0;
1118 
1119  // check that data is not already received by another read request
1120  if (slave->mbox_coe_data.payload_size > 0) {
1121  ec_read_mbox_lock_clear(slave);
1123  fsm->state(fsm, datagram);
1124  return;
1125  }
1126 
1127  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1128  1000 / HZ;
1129 
1130  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
1131  fsm->state = ec_fsm_coe_error;
1132  ec_read_mbox_lock_clear(slave);
1133  EC_SLAVE_ERR(slave, "Timeout while waiting for"
1134  " SDO entry 0x%04x:%x description response.\n",
1135  fsm->sdo->index, fsm->subindex);
1136  return;
1137  }
1138 
1139  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1140  fsm->retries = EC_FSM_RETRIES;
1141  return;
1142  }
1143 
1144  // Fetch response
1145  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1146  fsm->retries = EC_FSM_RETRIES;
1148 }
1149 
1150 /*****************************************************************************/
1151 
1158  ec_fsm_coe_t *fsm,
1159  ec_datagram_t *datagram
1160  )
1161 {
1162  ec_slave_t *slave = fsm->slave;
1163 
1164  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1165  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1166  return;
1167  }
1168 
1169  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1170  fsm->state = ec_fsm_coe_error;
1171  ec_read_mbox_lock_clear(slave);
1172  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
1173  " description response datagram: ");
1175  return;
1176  }
1177 
1178  if (fsm->datagram->working_counter != 1) {
1179  // only an error if data has not already been read by another read request
1180  if (slave->mbox_coe_data.payload_size == 0) {
1181  fsm->state = ec_fsm_coe_error;
1182  ec_read_mbox_lock_clear(slave);
1183  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
1184  " response failed: ");
1186  return;
1187  }
1188  }
1189  ec_read_mbox_lock_clear(slave);
1191  fsm->state(fsm, datagram);
1192 }
1193 
1194 /*****************************************************************************/
1195 
1202  ec_fsm_coe_t *fsm,
1203  ec_datagram_t *datagram
1204  )
1205 {
1206  ec_slave_t *slave = fsm->slave;
1207  ec_sdo_t *sdo = fsm->sdo;
1208  uint8_t *data, mbox_prot;
1209  size_t rec_size, data_size;
1210  ec_sdo_entry_t *entry;
1211  u16 word;
1212 
1213  // process the data available or initiate a new mailbox read check
1214  if (slave->mbox_coe_data.payload_size > 0) {
1215  slave->mbox_coe_data.payload_size = 0;
1216  } else {
1217  // initiate a new mailbox read check if required data is not available
1218  if (ec_read_mbox_locked(slave)) {
1219  // await current read request and mark the datagram as invalid
1220  datagram->state = EC_DATAGRAM_INVALID;
1221  } else {
1222  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1224  }
1225  return;
1226  }
1227 
1228  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
1229  if (IS_ERR(data)) {
1230  fsm->state = ec_fsm_coe_error;
1231  return;
1232  }
1233 
1234  if (mbox_prot != EC_MBOX_TYPE_COE) {
1235  EC_SLAVE_ERR(slave, "Received mailbox protocol"
1236  " 0x%02X as response.\n", mbox_prot);
1237  fsm->state = ec_fsm_coe_error;
1238  return;
1239  }
1240 
1241  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1242  // check for CoE response again
1243  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1244  fsm->retries = EC_FSM_RETRIES;
1246  return;
1247  }
1248 
1249  if (rec_size < 3) {
1250  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1251  " description response (size %zu).\n", rec_size);
1252  fsm->state = ec_fsm_coe_error;
1253  return;
1254  }
1255 
1256  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
1257  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
1258  EC_SLAVE_WARN(slave, "SDO information error response while"
1259  " fetching SDO entry 0x%04X:%02X!\n",
1260  sdo->index, fsm->subindex);
1261  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
1262 
1263  /* There may be gaps in the subindices, so try to continue with next
1264  * subindex. */
1265 
1266  } else {
1267 
1268  if (rec_size < 9) {
1269  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1270  " description response (size %zu).\n", rec_size);
1271  fsm->state = ec_fsm_coe_error;
1272  return;
1273  }
1274 
1275  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
1276  (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
1277  EC_READ_U16(data + 6) != sdo->index || // SDO index
1278  EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex
1279  if (fsm->slave->master->debug_level) {
1280  EC_SLAVE_DBG(slave, 1, "Invalid entry description response"
1281  " while fetching SDO entry 0x%04X:%02X!\n",
1282  sdo->index, fsm->subindex);
1283  ec_print_data(data, rec_size);
1284  }
1285  // check for CoE response again
1286  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1287  fsm->retries = EC_FSM_RETRIES;
1289  return;
1290  }
1291 
1292  if (rec_size < 16) {
1293  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
1294  ec_print_data(data, rec_size);
1295  fsm->state = ec_fsm_coe_error;
1296  return;
1297  }
1298 
1299  data_size = rec_size - 16;
1300 
1301  if (!(entry = (ec_sdo_entry_t *)
1302  kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) {
1303  EC_SLAVE_ERR(slave, "Failed to allocate entry!\n");
1304  fsm->state = ec_fsm_coe_error;
1305  return;
1306  }
1307 
1308  ec_sdo_entry_init(entry, sdo, fsm->subindex);
1309  entry->data_type = EC_READ_U16(data + 10);
1310  entry->bit_length = EC_READ_U16(data + 12);
1311 
1312  // read access rights
1313  word = EC_READ_U16(data + 14);
1314  entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001;
1316  (word >> 1) & 0x0001;
1317  entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001;
1318  entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001;
1320  (word >> 4) & 0x0001;
1321  entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001;
1322 
1323  if (data_size) {
1324  uint8_t *desc;
1325  if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) {
1326  EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n");
1327  fsm->state = ec_fsm_coe_error;
1328  return;
1329  }
1330  memcpy(desc, data + 16, data_size);
1331  desc[data_size] = 0;
1332  entry->description = desc;
1333  }
1334 
1335  list_add_tail(&entry->list, &sdo->entries);
1336  }
1337 
1338  if (fsm->subindex < sdo->max_subindex) {
1339 
1340  fsm->subindex++;
1341  fsm->retries = EC_FSM_RETRIES;
1342 
1343  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1344  fsm->state = ec_fsm_coe_error;
1345  }
1346 
1347  return;
1348  }
1349 
1350  // another SDO description to fetch?
1351  if (fsm->sdo->list.next != &slave->sdo_dictionary) {
1352 
1353  fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
1354  fsm->retries = EC_FSM_RETRIES;
1355 
1356  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
1357  fsm->state = ec_fsm_coe_error;
1358  }
1359 
1360  return;
1361  }
1362 
1363  fsm->state = ec_fsm_coe_end;
1364 }
1365 
1366 /******************************************************************************
1367  * CoE state machine
1368  *****************************************************************************/
1369 
1375  ec_fsm_coe_t *fsm,
1376  ec_datagram_t *datagram
1377  )
1378 {
1379  u8 *data;
1380  ec_slave_t *slave = fsm->slave;
1381  ec_sdo_request_t *request = fsm->request;
1382  uint8_t data_set_size;
1383 
1384  if (request->data_size <= 4) { // use expedited transfer type
1385  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1387  if (IS_ERR(data)) {
1388  request->errno = PTR_ERR(data);
1389  return PTR_ERR(data);
1390  }
1391 
1392  fsm->remaining = 0;
1393 
1394  data_set_size = 4 - request->data_size;
1395 
1396  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1397  EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
1398  | data_set_size << 2
1399  | ((request->complete_access ? 1 : 0) << 4)
1400  | 0x1 << 5)); // Download request
1401  EC_WRITE_U16(data + 3, request->index);
1402  EC_WRITE_U8 (data + 5,
1403  request->complete_access ? 0x00 : request->subindex);
1404  memcpy(data + 6, request->data, request->data_size);
1405  memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);
1406 
1407  if (slave->master->debug_level) {
1408  EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
1410  }
1411  }
1412  else { // request->data_size > 4, use normal transfer type
1413  size_t data_size,
1414  max_data_size =
1416  required_data_size =
1418 
1419  if (max_data_size < required_data_size) {
1420  // segmenting needed
1421  data_size = max_data_size;
1422  } else {
1423  data_size = required_data_size;
1424  }
1425 
1426  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1427  data_size);
1428  if (IS_ERR(data)) {
1429  request->errno = PTR_ERR(data);
1430  return PTR_ERR(data);
1431  }
1432 
1433  fsm->offset = 0;
1434  fsm->remaining = request->data_size;
1435 
1436  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1437  EC_WRITE_U8(data + 2,
1438  0x1 // size indicator, normal
1439  | ((request->complete_access ? 1 : 0) << 4)
1440  | 0x1 << 5); // Download request
1441  EC_WRITE_U16(data + 3, request->index);
1442  EC_WRITE_U8 (data + 5,
1443  request->complete_access ? 0x00 : request->subindex);
1444  EC_WRITE_U32(data + 6, request->data_size);
1445 
1446  if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
1447  size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
1448  memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
1449  request->data, segment_size);
1450  fsm->offset += segment_size;
1451  fsm->remaining -= segment_size;
1452  }
1453 
1454  if (slave->master->debug_level) {
1455  EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
1456  ec_print_data(data, data_size);
1457  }
1458  }
1459 
1461  return 0;
1462 }
1463 
1464 /****************************************************************************/
1465 
1469  ec_fsm_coe_t *fsm,
1470  ec_datagram_t *datagram
1471  )
1472 {
1473  ec_slave_t *slave = fsm->slave;
1474  ec_sdo_request_t *request = fsm->request;
1475 
1476  if (fsm->slave->master->debug_level) {
1477  char subidxstr[10];
1478  if (request->complete_access) {
1479  subidxstr[0] = 0x00;
1480  } else {
1481  sprintf(subidxstr, ":%02X", request->subindex);
1482  }
1483  EC_SLAVE_DBG(slave, 1, "Downloading SDO 0x%04X%s.\n",
1484  request->index, subidxstr);
1485  ec_print_data(request->data, request->data_size);
1486  }
1487 
1488  if (!slave->sii_image) {
1489  EC_SLAVE_ERR(slave, "Slave cannot process CoE download request."
1490  " SII data not available.\n");
1491  request->errno = EAGAIN;
1492  fsm->state = ec_fsm_coe_error;
1493  return;
1494  }
1495 
1496  if (!(slave->sii_image->sii.mailbox_protocols & EC_MBOX_COE)) {
1497  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1498  request->errno = EPROTONOSUPPORT;
1499  fsm->state = ec_fsm_coe_error;
1500  return;
1501  }
1502 
1503  if (slave->configured_rx_mailbox_size <
1505  EC_SLAVE_ERR(slave, "Mailbox too small!\n");
1506  request->errno = EOVERFLOW;
1507  fsm->state = ec_fsm_coe_error;
1508  return;
1509  }
1510 
1511 
1512  fsm->request->jiffies_sent = jiffies;
1513  fsm->retries = EC_FSM_RETRIES;
1514 
1515  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1516  fsm->state = ec_fsm_coe_error;
1517  }
1518 }
1519 
1520 /*****************************************************************************/
1521 
1528  ec_fsm_coe_t *fsm,
1529  ec_datagram_t *datagram
1530  )
1531 {
1532  ec_slave_t *slave = fsm->slave;
1533  unsigned long diff_ms;
1534 
1535  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1536  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1537  fsm->state = ec_fsm_coe_error;
1538  }
1539  return;
1540  }
1541 
1542  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1543  fsm->request->errno = EIO;
1544  fsm->state = ec_fsm_coe_error;
1545  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1546  " request datagram: ");
1548  return;
1549  }
1550 
1551  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1552 
1553  if (fsm->datagram->working_counter != 1) {
1554  if (!fsm->datagram->working_counter) {
1555  if (diff_ms < fsm->request->response_timeout) {
1556 #if DEBUG_RETRIES
1557  EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
1558  " download request. Retrying after %lu ms...\n",
1559  diff_ms);
1560 #endif
1561  // no response; send request datagram again
1562  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1563  fsm->state = ec_fsm_coe_error;
1564  }
1565  return;
1566  }
1567  }
1568  fsm->request->errno = EIO;
1569  fsm->state = ec_fsm_coe_error;
1570  EC_SLAVE_ERR(slave, "Reception of CoE download request"
1571  " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
1572  fsm->request->index, fsm->request->subindex, diff_ms);
1574  return;
1575  }
1576 
1577 #if DEBUG_LONG
1578  if (diff_ms > 200) {
1579  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
1580  fsm->request->index, fsm->request->subindex, diff_ms);
1581  }
1582 #endif
1583 
1584  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1585 
1586  // mailbox read check is skipped if a read request is already ongoing
1587  if (ec_read_mbox_locked(slave)) {
1589  // the datagram is not used and marked as invalid
1590  datagram->state = EC_DATAGRAM_INVALID;
1591  } else {
1592  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1593  fsm->retries = EC_FSM_RETRIES;
1595  }
1596 }
1597 
1598 /*****************************************************************************/
1599 
1603  ec_fsm_coe_t *fsm,
1604  ec_datagram_t *datagram
1605  )
1606 {
1607  ec_slave_t *slave = fsm->slave;
1608 
1609  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1610  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1611  return;
1612  }
1613 
1614  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1615  fsm->request->errno = EIO;
1616  fsm->state = ec_fsm_coe_error;
1617  ec_read_mbox_lock_clear(slave);
1618  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
1619  " datagram: ");
1621  return;
1622  }
1623 
1624  if (fsm->datagram->working_counter != 1) {
1625  fsm->request->errno = EIO;
1626  fsm->state = ec_fsm_coe_error;
1627  ec_read_mbox_lock_clear(slave);
1628  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1629  " datagram failed: ");
1631  return;
1632  }
1633 
1634  if (!ec_slave_mbox_check(fsm->datagram)) {
1635  unsigned long diff_ms = 0;
1636 
1637  // check that data is not already received by another read request
1638  if (slave->mbox_coe_data.payload_size > 0) {
1639  ec_read_mbox_lock_clear(slave);
1641  fsm->state(fsm, datagram);
1642  return;
1643  }
1644 
1645  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1646  1000 / HZ;
1647 
1648  if (diff_ms >= fsm->request->response_timeout) {
1649  fsm->request->errno = EIO;
1650  fsm->state = ec_fsm_coe_error;
1651  ec_read_mbox_lock_clear(slave);
1652  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
1653  " for SDO 0x%04x:%x download response.\n", diff_ms,
1654  fsm->request->index, fsm->request->subindex);
1655  return;
1656  }
1657 
1658  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1659  fsm->retries = EC_FSM_RETRIES;
1660  return;
1661  }
1662 
1663  // Fetch response
1664  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1665  fsm->retries = EC_FSM_RETRIES;
1667 }
1668 
1669 /*****************************************************************************/
1670 
1674  ec_fsm_coe_t *fsm,
1675  ec_datagram_t *datagram
1676  )
1677 {
1678  ec_slave_t *slave = fsm->slave;
1679  ec_sdo_request_t *request = fsm->request;
1680  size_t max_segment_size =
1684  size_t data_size;
1685  uint8_t last_segment, seg_data_size, *data;
1686 
1687  if (fsm->remaining > max_segment_size) {
1688  fsm->segment_size = max_segment_size;
1689  last_segment = 0;
1690  } else {
1691  fsm->segment_size = fsm->remaining;
1692  last_segment = 1;
1693  }
1694 
1696  seg_data_size = 0x00;
1697  data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size;
1698  } else {
1699  seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size;
1700  data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE
1702  }
1703 
1704  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1705  data_size);
1706  if (IS_ERR(data)) {
1707  request->errno = PTR_ERR(data);
1708  fsm->state = ec_fsm_coe_error;
1709  return;
1710  }
1711 
1712  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1713  EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
1714  | (seg_data_size << 1)
1715  | (fsm->toggle << 4)
1716  | (0x00 << 5)); // Download segment request
1717  memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
1718  request->data + fsm->offset, fsm->segment_size);
1720  memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size,
1722  }
1723 
1724  if (slave->master->debug_level) {
1725  EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
1726  ec_print_data(data, data_size);
1727  }
1728 
1730 }
1731 
1732 /*****************************************************************************/
1733 
1740  ec_fsm_coe_t *fsm,
1741  ec_datagram_t *datagram
1742  )
1743 {
1744  ec_slave_t *slave = fsm->slave;
1745  ec_sdo_request_t *request = fsm->request;
1746 
1747  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1748  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1749  return;
1750  }
1751 
1752  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1753  request->errno = EIO;
1754  fsm->state = ec_fsm_coe_error;
1755  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1756  " response datagram: ");
1758  return;
1759  }
1760 
1761  if (fsm->datagram->working_counter != 1) {
1762  // only an error if data has not already been read by another read request
1763  if (slave->mbox_coe_data.payload_size == 0) {
1764  request->errno = EIO;
1765  fsm->state = ec_fsm_coe_error;
1766  ec_read_mbox_lock_clear(slave);
1767  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1769  return;
1770  }
1771  }
1772  ec_read_mbox_lock_clear(slave);
1774  fsm->state(fsm, datagram);
1775 }
1776 
1777 /*****************************************************************************/
1778 
1785  ec_fsm_coe_t *fsm,
1786  ec_datagram_t *datagram
1787  )
1788 {
1789  ec_slave_t *slave = fsm->slave;
1790  uint8_t *data, mbox_prot;
1791  size_t rec_size;
1792  ec_sdo_request_t *request = fsm->request;
1793 
1794  // process the data available or initiate a new mailbox read check
1795  if (slave->mbox_coe_data.payload_size > 0) {
1796  slave->mbox_coe_data.payload_size = 0;
1797  } else {
1798  // initiate a new mailbox read check if required data is not available
1799  if (ec_read_mbox_locked(slave)) {
1800  // await current read request and mark the datagram as invalid
1801  datagram->state = EC_DATAGRAM_INVALID;
1802  } else {
1803  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1805  }
1806  return;
1807  }
1808 
1809  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
1810 
1811  if (IS_ERR(data)) {
1812  request->errno = PTR_ERR(data);
1813  fsm->state = ec_fsm_coe_error;
1814  return;
1815  }
1816 
1817  if (mbox_prot != EC_MBOX_TYPE_COE) {
1818  request->errno = EIO;
1819  fsm->state = ec_fsm_coe_error;
1820  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1821  mbox_prot);
1822  return;
1823  }
1824 
1825  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1826  // check for CoE response again
1827  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1828  fsm->retries = EC_FSM_RETRIES;
1830  return;
1831  }
1832 
1833  if (slave->master->debug_level) {
1834  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1835  ec_print_data(data, rec_size);
1836  }
1837 
1838  if (rec_size < 6) {
1839  request->errno = EIO;
1840  fsm->state = ec_fsm_coe_error;
1841  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1842  rec_size);
1843  ec_print_data(data, rec_size);
1844  return;
1845  }
1846 
1847  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1848  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1849  char subidxstr[10];
1850  request->errno = EIO;
1851  fsm->state = ec_fsm_coe_error;
1852  if (request->complete_access) {
1853  subidxstr[0] = 0x00;
1854  } else {
1855  sprintf(subidxstr, ":%02X", request->subindex);
1856  }
1857  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1858  request->index, subidxstr, request->data_size);
1859  if (rec_size < 10) {
1860  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1861  ec_print_data(data, rec_size);
1862  } else {
1863  fsm->request->abort_code = EC_READ_U32(data + 6);
1864  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1865  }
1866  return;
1867  }
1868 
1869  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
1870  EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
1871  EC_READ_U16(data + 3) != request->index || // index
1872  EC_READ_U8 (data + 5) != request->subindex) { // subindex
1873  if (slave->master->debug_level) {
1874  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1875  " Retrying...\n");
1876  ec_print_data(data, rec_size);
1877  }
1878  // check for CoE response again
1879  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1880  fsm->retries = EC_FSM_RETRIES;
1882  return;
1883  }
1884 
1885  if (fsm->remaining) { // more segments to download
1886  fsm->toggle = 0;
1888  } else {
1889  fsm->state = ec_fsm_coe_end; // success
1890  }
1891 }
1892 
1893 /*****************************************************************************/
1894 
1900  ec_fsm_coe_t *fsm,
1901  ec_datagram_t *datagram
1902  )
1903 {
1904  ec_slave_t *slave = fsm->slave;
1905 
1906  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1907  return;
1908 
1909  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1910  fsm->request->errno = EIO;
1911  fsm->state = ec_fsm_coe_error;
1912  ec_read_mbox_lock_clear(slave);
1913  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1915  return;
1916  }
1917 
1918  if (fsm->datagram->working_counter != 1) {
1919  fsm->request->errno = EIO;
1920  fsm->state = ec_fsm_coe_error;
1921  ec_read_mbox_lock_clear(slave);
1922  EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
1923  " datagram failed: ");
1925  return;
1926  }
1927 
1928  if (!ec_slave_mbox_check(fsm->datagram)) {
1929  unsigned long diff_ms = 0;
1930 
1931  // check that data is not already received by another read request
1932  if (slave->mbox_coe_data.payload_size > 0) {
1933  ec_read_mbox_lock_clear(slave);
1935  fsm->state(fsm, datagram);
1936  return;
1937  }
1938 
1939  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1940  1000 / HZ;
1941 
1942  if (diff_ms >= fsm->request->response_timeout) {
1943  fsm->request->errno = EIO;
1944  fsm->state = ec_fsm_coe_error;
1945  ec_read_mbox_lock_clear(slave);
1946  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
1947  " segment response.\n");
1948  return;
1949  }
1950 
1951  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1952  fsm->retries = EC_FSM_RETRIES;
1953  return;
1954  }
1955 
1956  // Fetch response
1957  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1958  fsm->retries = EC_FSM_RETRIES;
1960 }
1961 
1962 /*****************************************************************************/
1963 
1970  ec_fsm_coe_t *fsm,
1971  ec_datagram_t *datagram
1972  )
1973 {
1974  ec_slave_t *slave = fsm->slave;
1975  ec_sdo_request_t *request = fsm->request;
1976 
1977  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1978  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1979  return;
1980  }
1981 
1982  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1983  request->errno = EIO;
1984  fsm->state = ec_fsm_coe_error;
1985  ec_read_mbox_lock_clear(slave);
1986  EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
1987  " datagram: ");
1989  return;
1990  }
1991 
1992  if (fsm->datagram->working_counter != 1) {
1993  // only an error if data has not already been read by another read request
1994  if (slave->mbox_coe_data.payload_size == 0) {
1995  request->errno = EIO;
1996  fsm->state = ec_fsm_coe_error;
1997  ec_read_mbox_lock_clear(slave);
1998  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
2000  return;
2001  }
2002  }
2003  ec_read_mbox_lock_clear(slave);
2005  fsm->state(fsm, datagram);
2006 }
2007 
2008 /*****************************************************************************/
2009 
2016  ec_fsm_coe_t *fsm,
2017  ec_datagram_t *datagram
2018  )
2019 {
2020  ec_slave_t *slave = fsm->slave;
2021  uint8_t *data, mbox_prot;
2022  size_t rec_size;
2023  ec_sdo_request_t *request = fsm->request;
2024 
2025  // process the data available or initiate a new mailbox read check
2026  if (slave->mbox_coe_data.payload_size > 0) {
2027  slave->mbox_coe_data.payload_size = 0;
2028  } else {
2029  // initiate a new mailbox read check if required data is not available
2030  if (ec_read_mbox_locked(slave)) {
2031  // await current read request and mark the datagram as invalid
2032  datagram->state = EC_DATAGRAM_INVALID;
2033  } else {
2034  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2036  }
2037  return;
2038  }
2039 
2040  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
2041  if (IS_ERR(data)) {
2042  request->errno = PTR_ERR(data);
2043  fsm->state = ec_fsm_coe_error;
2044  return;
2045  }
2046 
2047  if (mbox_prot != EC_MBOX_TYPE_COE) {
2048  request->errno = EIO;
2049  fsm->state = ec_fsm_coe_error;
2050  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
2051  mbox_prot);
2052  return;
2053  }
2054 
2055  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2056  // check for CoE response again
2057  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2058  fsm->retries = EC_FSM_RETRIES;
2060  return;
2061  }
2062 
2063  if (slave->master->debug_level) {
2064  EC_SLAVE_DBG(slave, 1, "Download response:\n");
2065  ec_print_data(data, rec_size);
2066  }
2067 
2068  if (rec_size < 6) {
2069  request->errno = EIO;
2070  fsm->state = ec_fsm_coe_error;
2071  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
2072  rec_size);
2073  ec_print_data(data, rec_size);
2074  return;
2075  }
2076 
2077  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2078  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
2079  char subidxstr[10];
2080  request->errno = EIO;
2081  fsm->state = ec_fsm_coe_error;
2082  if (request->complete_access) {
2083  subidxstr[0] = 0x00;
2084  } else {
2085  sprintf(subidxstr, ":%02X", request->subindex);
2086  }
2087  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
2088  request->index, subidxstr, request->data_size);
2089  if (rec_size < 10) {
2090  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
2091  ec_print_data(data, rec_size);
2092  } else {
2093  fsm->request->abort_code = EC_READ_U32(data + 6);
2094  ec_canopen_abort_msg(slave, fsm->request->abort_code);
2095  }
2096  return;
2097  }
2098 
2099  if (EC_READ_U16(data) >> 12 != 0x3 ||
2100  ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response
2101  if (slave->master->debug_level) {
2102  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
2103  " Retrying...\n");
2104  ec_print_data(data, rec_size);
2105  }
2106  // check for CoE response again
2107  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2108  fsm->retries = EC_FSM_RETRIES;
2110  return;
2111  }
2112 
2113  if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) {
2114  EC_SLAVE_ERR(slave, "Invalid toggle received during"
2115  " segmented download:\n");
2116  ec_print_data(data, rec_size);
2117  request->errno = EIO;
2118  fsm->state = ec_fsm_coe_error;
2119  return;
2120  }
2121 
2122  fsm->offset += fsm->segment_size;
2123  fsm->remaining -= fsm->segment_size;
2124 
2125  if (fsm->remaining) { // more segments to download
2126  fsm->toggle = !fsm->toggle;
2128  } else {
2129  fsm->state = ec_fsm_coe_end; // success
2130  }
2131 }
2132 
2133 /*****************************************************************************/
2134 
2140  ec_fsm_coe_t *fsm,
2141  ec_datagram_t *datagram
2142  )
2143 {
2144  ec_slave_t *slave = fsm->slave;
2145  ec_sdo_request_t *request = fsm->request;
2146  ec_master_t *master = slave->master;
2147 
2148  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
2149  10);
2150  if (IS_ERR(data)) {
2151  request->errno = PTR_ERR(data);
2152  return PTR_ERR(data);
2153  }
2154 
2155  EC_WRITE_U16(data, 0x2 << 12); // SDO request
2156  EC_WRITE_U8 (data + 2, 0x2 << 5 // initiate upload request
2157  | ((request->complete_access ? 1 : 0) << 4));
2158  EC_WRITE_U16(data + 3, request->index);
2159  EC_WRITE_U8 (data + 5, request->complete_access ? 0x00 : request->subindex);
2160  memset(data + 6, 0x00, 4);
2161 
2162  if (master->debug_level) {
2163  EC_SLAVE_DBG(slave, 1, "Upload request:\n");
2164  ec_print_data(data, 10);
2165  }
2166 
2168  return 0;
2169 }
2170 
2171 /*****************************************************************************/
2172 
2178  ec_fsm_coe_t *fsm,
2179  ec_datagram_t *datagram
2180  )
2181 {
2182  ec_slave_t *slave = fsm->slave;
2183  ec_sdo_request_t *request = fsm->request;
2184  char subidxstr[10];
2185 
2186  if (request->complete_access) {
2187  subidxstr[0] = 0x00;
2188  } else {
2189  sprintf(subidxstr, ":%02X", request->subindex);
2190  }
2191 
2192  EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X%s.\n",
2193  request->index, subidxstr);
2194 
2195  if (!slave->sii_image) {
2196  EC_SLAVE_ERR(slave, "Slave cannot process CoE upload request."
2197  " SII data not available.\n");
2198  request->errno = EAGAIN;
2199  fsm->state = ec_fsm_coe_error;
2200  return;
2201  }
2202 
2203  if (!(slave->sii_image->sii.mailbox_protocols & EC_MBOX_COE)) {
2204  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
2205  request->errno = EPROTONOSUPPORT;
2206  fsm->state = ec_fsm_coe_error;
2207  return;
2208  }
2209 
2210  fsm->retries = EC_FSM_RETRIES;
2211  fsm->request->jiffies_sent = jiffies;
2212 
2213  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
2214  fsm->state = ec_fsm_coe_error;
2215  }
2216 }
2217 
2218 /*****************************************************************************/
2225  ec_fsm_coe_t *fsm,
2226  ec_datagram_t *datagram
2227  )
2228 {
2229  ec_slave_t *slave = fsm->slave;
2230  unsigned long diff_ms;
2231  char subidxstr[10];
2232 
2233  if (fsm->request->complete_access) {
2234  subidxstr[0] = 0x00;
2235  } else {
2236  sprintf(subidxstr, ":%02X", fsm->request->subindex);
2237  }
2238 
2239  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2240  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
2241  fsm->state = ec_fsm_coe_error;
2242  }
2243  return;
2244  }
2245 
2246  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2247  fsm->request->errno = EIO;
2248  fsm->state = ec_fsm_coe_error;
2249  EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
2251  return;
2252  }
2253 
2254  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
2255 
2256  if (fsm->datagram->working_counter != 1) {
2257  if (!fsm->datagram->working_counter) {
2258  if (diff_ms < fsm->request->response_timeout) {
2259 #if DEBUG_RETRIES
2260  EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
2261  " SDO upload request. Retrying after %lu ms...\n",
2262  diff_ms);
2263 #endif
2264  // no response; send request datagram again
2265  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
2266  fsm->state = ec_fsm_coe_error;
2267  }
2268  return;
2269  }
2270  }
2271  fsm->request->errno = EIO;
2272  fsm->state = ec_fsm_coe_error;
2273  EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
2274  " SDO 0x%04x%s failed with timeout after %lu ms: ",
2275  fsm->request->index, subidxstr, diff_ms);
2277  return;
2278  }
2279 
2280 #if DEBUG_LONG
2281  if (diff_ms > 200) {
2282  EC_SLAVE_WARN(slave, "SDO 0x%04x%s upload took %lu ms.\n",
2283  fsm->request->index, subidxstr, diff_ms);
2284  }
2285 #endif
2286 
2287  fsm->jiffies_start = fsm->datagram->jiffies_sent;
2288  // mailbox read check is skipped if a read request is already ongoing
2289  if (ec_read_mbox_locked(slave)) {
2291  // the datagram is not used and marked as invalid
2292  datagram->state = EC_DATAGRAM_INVALID;
2293  } else {
2294  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2295  fsm->retries = EC_FSM_RETRIES;
2296  fsm->state = ec_fsm_coe_up_check;
2297  }
2298 }
2299 
2300 /*****************************************************************************/
2301 
2307  ec_fsm_coe_t *fsm,
2308  ec_datagram_t *datagram
2309  )
2310 {
2311  ec_slave_t *slave = fsm->slave;
2312 
2313  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2314  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2315  return;
2316  }
2317 
2318  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2319  fsm->request->errno = EIO;
2320  fsm->state = ec_fsm_coe_error;
2321  ec_read_mbox_lock_clear(slave);
2322  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
2324  return;
2325  }
2326 
2327  if (fsm->datagram->working_counter != 1) {
2328  fsm->request->errno = EIO;
2329  fsm->state = ec_fsm_coe_error;
2330  ec_read_mbox_lock_clear(slave);
2331  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
2332  " datagram failed: ");
2334  return;
2335  }
2336 
2337  if (!ec_slave_mbox_check(fsm->datagram)) {
2338  unsigned long diff_ms = 0;
2339 
2340  // check that data is not already received by another read request
2341  if (slave->mbox_coe_data.payload_size > 0) {
2342  ec_read_mbox_lock_clear(slave);
2344  fsm->state(fsm, datagram);
2345  return;
2346  }
2347 
2348  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2349  1000 / HZ;
2350 
2351  if (diff_ms >= fsm->request->response_timeout) {
2352  char subidxstr[10];
2353 
2354  if (fsm->request->complete_access) {
2355  subidxstr[0] = 0x00;
2356  } else {
2357  sprintf(subidxstr, ":%02X", fsm->request->subindex);
2358  }
2359 
2360  fsm->request->errno = EIO;
2361  fsm->state = ec_fsm_coe_error;
2362  ec_read_mbox_lock_clear(slave);
2363  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
2364  " SDO 0x%04x%s upload response.\n", diff_ms,
2365  fsm->request->index, subidxstr);
2366  return;
2367  }
2368 
2369  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2370  fsm->retries = EC_FSM_RETRIES;
2371  return;
2372  }
2373 
2374  // Fetch response
2375  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2376  fsm->retries = EC_FSM_RETRIES;
2378 }
2379 
2380 /*****************************************************************************/
2381 
2385  ec_fsm_coe_t *fsm,
2386  ec_datagram_t *datagram
2387  )
2388 {
2389  uint8_t *data =
2390  ec_slave_mbox_prepare_send(fsm->slave, datagram, EC_MBOX_TYPE_COE,
2391  10);
2392  if (IS_ERR(data)) {
2393  fsm->request->errno = PTR_ERR(data);
2394  fsm->state = ec_fsm_coe_error;
2395  return;
2396  }
2397 
2398  EC_WRITE_U16(data, 0x2 << 12); // SDO request
2399  EC_WRITE_U8 (data + 2, (fsm->toggle << 4 // toggle
2400  | 0x3 << 5)); // upload segment request
2401  memset(data + 3, 0x00, 7);
2402 
2403  if (fsm->slave->master->debug_level) {
2404  EC_SLAVE_DBG(fsm->slave, 1, "Upload segment request:\n");
2405  ec_print_data(data, 10);
2406  }
2407 }
2408 
2409 /*****************************************************************************/
2410 
2417  ec_fsm_coe_t *fsm,
2418  ec_datagram_t *datagram
2419  )
2420 {
2421  ec_slave_t *slave = fsm->slave;
2422  ec_sdo_request_t *request = fsm->request;
2423 
2424  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2425  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2426  return;
2427  }
2428 
2429  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2430  request->errno = EIO;
2431  fsm->state = ec_fsm_coe_error;
2432  ec_read_mbox_lock_clear(slave);
2433  EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
2434  " datagram: ");
2436  return;
2437  }
2438 
2439  if (fsm->datagram->working_counter != 1) {
2440  // only an error if data has not already been read by another read request
2441  if (slave->mbox_coe_data.payload_size == 0) {
2442  request->errno = EIO;
2443  fsm->state = ec_fsm_coe_error;
2444  ec_read_mbox_lock_clear(slave);
2445  EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
2447  return;
2448  }
2449  }
2450  ec_read_mbox_lock_clear(slave);
2452  fsm->state(fsm, datagram);
2453 }
2454 
2455 
2456 /*****************************************************************************/
2457 
2464  ec_fsm_coe_t *fsm,
2465  ec_datagram_t *datagram
2466  )
2467 {
2468  ec_slave_t *slave = fsm->slave;
2469  ec_master_t *master = slave->master;
2470  uint16_t rec_index;
2471  uint8_t *data, mbox_prot, rec_subindex;
2472  size_t rec_size, data_size;
2473  ec_sdo_request_t *request = fsm->request;
2474  unsigned int expedited, size_specified;
2475  int ret;
2476  char subidxstr[10];
2477 
2478  if (request->complete_access) {
2479  subidxstr[0] = 0x00;
2480  } else {
2481  sprintf(subidxstr, ":%02X", request->subindex);
2482  }
2483 
2484  // process the data available or initiate a new mailbox read check
2485  if (slave->mbox_coe_data.payload_size > 0) {
2486  slave->mbox_coe_data.payload_size = 0;
2487  } else {
2488  // initiate a new mailbox read check if required data is not available
2489  if (ec_read_mbox_locked(slave)) {
2490  // await current read request and mark the datagram as invalid
2491  datagram->state = EC_DATAGRAM_INVALID;
2492  } else {
2493  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2494  fsm->state = ec_fsm_coe_up_check;
2495  }
2496  return;
2497  }
2498 
2499  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
2500 
2501  if (IS_ERR(data)) {
2502  request->errno = PTR_ERR(data);
2503  fsm->state = ec_fsm_coe_error;
2504  return;
2505  }
2506 
2507  if (master->debug_level) {
2508  EC_SLAVE_DBG(slave, 1, "Upload response:\n");
2509  ec_print_data(data, rec_size);
2510  }
2511 
2512  if (mbox_prot != EC_MBOX_TYPE_COE) {
2513  request->errno = EIO;
2514  fsm->state = ec_fsm_coe_error;
2515  EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
2516  " as response.\n", mbox_prot);
2517  return;
2518  }
2519 
2520  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2521  // check for CoE response again
2522  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2523  fsm->retries = EC_FSM_RETRIES;
2524  fsm->state = ec_fsm_coe_up_check;
2525  return;
2526  }
2527 
2528  if (rec_size < 6) {
2529  request->errno = EIO;
2530  fsm->state = ec_fsm_coe_error;
2531  EC_SLAVE_ERR(slave, "Received currupted SDO upload response"
2532  " (%zu bytes)!\n", rec_size);
2533  ec_print_data(data, rec_size);
2534  return;
2535  }
2536 
2537  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2538  EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request
2539  EC_SLAVE_ERR(slave, "SDO upload 0x%04X%s aborted.\n",
2540  request->index, subidxstr);
2541  if (rec_size >= 10) {
2542  request->abort_code = EC_READ_U32(data + 6);
2543  ec_canopen_abort_msg(slave, request->abort_code);
2544  } else {
2545  EC_SLAVE_ERR(slave, "No abort message.\n");
2546  }
2547  request->errno = EIO;
2548  fsm->state = ec_fsm_coe_error;
2549  return;
2550  }
2551 
2552  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2553  EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response
2554  EC_SLAVE_ERR(slave, "Received unknown response while"
2555  " uploading SDO 0x%04X%s.\n",
2556  request->index, subidxstr);
2557  ec_print_data(data, rec_size);
2558  request->errno = EIO;
2559  fsm->state = ec_fsm_coe_error;
2560  return;
2561  }
2562 
2563  rec_index = EC_READ_U16(data + 3);
2564  rec_subindex = EC_READ_U8(data + 5);
2565 
2566  if (rec_index != request->index || rec_subindex != request->subindex) {
2567  EC_SLAVE_ERR(slave, "Received upload response for wrong SDO"
2568  " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
2569  rec_index, rec_subindex, request->index, request->subindex);
2570  ec_print_data(data, rec_size);
2571 
2572  // check for CoE response again
2573  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2574  fsm->retries = EC_FSM_RETRIES;
2575  fsm->state = ec_fsm_coe_up_check;
2576  return;
2577  }
2578 
2579  // normal or expedited?
2580  expedited = EC_READ_U8(data + 2) & 0x02;
2581 
2582  if (expedited) {
2583  size_specified = EC_READ_U8(data + 2) & 0x01;
2584  if (size_specified) {
2585  fsm->complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
2586  } else {
2587  fsm->complete_size = 4;
2588  }
2589 
2590  if (rec_size < 6 + fsm->complete_size) {
2591  request->errno = EIO;
2592  fsm->state = ec_fsm_coe_error;
2593  EC_SLAVE_ERR(slave, "Received corrupted SDO expedited upload"
2594  " response (only %zu bytes)!\n", rec_size);
2595  ec_print_data(data, rec_size);
2596  return;
2597  }
2598 
2599  ret = ec_sdo_request_copy_data(request, data + 6, fsm->complete_size);
2600  if (ret) {
2601  request->errno = -ret;
2602  fsm->state = ec_fsm_coe_error;
2603  return;
2604  }
2605  } else { // normal
2606  if (rec_size < 10) {
2607  request->errno = EIO;
2608  fsm->state = ec_fsm_coe_error;
2609  EC_SLAVE_ERR(slave, "Received currupted SDO normal upload"
2610  " response (only %zu bytes)!\n", rec_size);
2611  ec_print_data(data, rec_size);
2612  return;
2613  }
2614 
2615  data_size = rec_size - 10;
2616  fsm->complete_size = EC_READ_U32(data + 6);
2617 
2618  if (!fsm->complete_size) {
2619  request->errno = EIO;
2620  fsm->state = ec_fsm_coe_error;
2621  EC_SLAVE_ERR(slave, "No complete size supplied!\n");
2622  ec_print_data(data, rec_size);
2623  return;
2624  }
2625 
2626  ret = ec_sdo_request_alloc(request, fsm->complete_size);
2627  if (ret) {
2628  request->errno = -ret;
2629  fsm->state = ec_fsm_coe_error;
2630  return;
2631  }
2632 
2633  ret = ec_sdo_request_copy_data(request, data + 10, data_size);
2634  if (ret) {
2635  request->errno = -ret;
2636  fsm->state = ec_fsm_coe_error;
2637  return;
2638  }
2639 
2640  fsm->toggle = 0;
2641 
2642  if (data_size < fsm->complete_size) {
2643  EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
2644  " Segmenting...\n", data_size, fsm->complete_size);
2646  fsm->retries = EC_FSM_RETRIES;
2648  return;
2649  }
2650  }
2651 
2652  if (master->debug_level) {
2653  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2654  ec_print_data(request->data, request->data_size);
2655  }
2656 
2657  fsm->state = ec_fsm_coe_end; // success
2658 }
2659 
2660 /*****************************************************************************/
2661 
2668  ec_fsm_coe_t *fsm,
2669  ec_datagram_t *datagram
2670  )
2671 {
2672  ec_slave_t *slave = fsm->slave;
2673 
2674  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2676  return;
2677  }
2678 
2679  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2680  fsm->request->errno = EIO;
2681  fsm->state = ec_fsm_coe_error;
2682  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2683  " request datagram: ");
2685  return;
2686  }
2687 
2688  if (fsm->datagram->working_counter != 1) {
2689  fsm->request->errno = EIO;
2690  fsm->state = ec_fsm_coe_error;
2691  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2692  " request failed: ");
2694  return;
2695  }
2696 
2697  fsm->jiffies_start = fsm->datagram->jiffies_sent;
2698  // mailbox read check is skipped if a read request is already ongoing
2699  if (ec_read_mbox_locked(slave)) {
2701  // the datagram is not used and marked as invalid
2702  datagram->state = EC_DATAGRAM_INVALID;
2703  } else {
2704  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2705  fsm->retries = EC_FSM_RETRIES;
2707  }
2708 }
2709 
2710 /*****************************************************************************/
2711 
2717  ec_fsm_coe_t *fsm,
2718  ec_datagram_t *datagram
2719  )
2720 {
2721  ec_slave_t *slave = fsm->slave;
2722 
2723  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2724  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2725  return;
2726  }
2727 
2728  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2729  fsm->request->errno = EIO;
2730  fsm->state = ec_fsm_coe_error;
2731  ec_read_mbox_lock_clear(slave);
2732  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
2733  " datagram: ");
2735  return;
2736  }
2737 
2738  if (fsm->datagram->working_counter != 1) {
2739  fsm->request->errno = EIO;
2740  fsm->state = ec_fsm_coe_error;
2741  ec_read_mbox_lock_clear(slave);
2742  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
2743  " failed: ");
2745  return;
2746  }
2747 
2748  if (!ec_slave_mbox_check(fsm->datagram)) {
2749  unsigned long diff_ms = 0;
2750 
2751  // check that data is not already received by another read request
2752  if (slave->mbox_coe_data.payload_size > 0) {
2753  ec_read_mbox_lock_clear(slave);
2755  fsm->state(fsm, datagram);
2756  return;
2757  }
2758 
2759  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2760  1000 / HZ;
2761 
2762  if (diff_ms >= fsm->request->response_timeout) {
2763  fsm->request->errno = EIO;
2764  fsm->state = ec_fsm_coe_error;
2765  ec_read_mbox_lock_clear(slave);
2766  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
2767  " segment response.\n");
2768  return;
2769  }
2770 
2771  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2772  fsm->retries = EC_FSM_RETRIES;
2773  return;
2774  }
2775 
2776  // Fetch response
2777  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2778  fsm->retries = EC_FSM_RETRIES;
2780 }
2781 
2782 /*****************************************************************************/
2783 
2790  ec_fsm_coe_t *fsm,
2791  ec_datagram_t *datagram
2792  )
2793 {
2794  ec_slave_t *slave = fsm->slave;
2795  ec_sdo_request_t *request = fsm->request;
2796 
2797  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2798  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2799  return;
2800  }
2801 
2802  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2803  request->errno = EIO;
2804  fsm->state = ec_fsm_coe_error;
2805  ec_read_mbox_lock_clear(slave);
2806  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2807  " response datagram: ");
2809  return;
2810  }
2811 
2812  if (fsm->datagram->working_counter != 1) {
2813  // only an error if data has not already been read by another read request
2814  if (slave->mbox_coe_data.payload_size == 0) {
2815  request->errno = EIO;
2816  fsm->state = ec_fsm_coe_error;
2817  ec_read_mbox_lock_clear(slave);
2818  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2819  " response failed: ");
2821  return;
2822  }
2823  }
2824  ec_read_mbox_lock_clear(slave);
2826  fsm->state(fsm, datagram);
2827 }
2828 
2829 
2830 /*****************************************************************************/
2831 
2838  ec_fsm_coe_t *fsm,
2839  ec_datagram_t *datagram
2840  )
2841 {
2842  ec_slave_t *slave = fsm->slave;
2843  ec_master_t *master = slave->master;
2844  uint8_t *data, mbox_prot;
2845  size_t rec_size, data_size;
2846  ec_sdo_request_t *request = fsm->request;
2847  unsigned int last_segment;
2848 
2849  // process the data available or initiate a new mailbox read check
2850  if (slave->mbox_coe_data.payload_size > 0) {
2851  slave->mbox_coe_data.payload_size = 0;
2852  } else {
2853  // initiate a new mailbox read check if required data is not available
2854  if (ec_read_mbox_locked(slave)) {
2855  // await current read request and mark the datagram as invalid
2856  datagram->state = EC_DATAGRAM_INVALID;
2857  } else {
2858  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2860  }
2861  return;
2862  }
2863 
2864  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
2865 
2866  if (IS_ERR(data)) {
2867  request->errno = PTR_ERR(data);
2868  fsm->state = ec_fsm_coe_error;
2869  return;
2870  }
2871 
2872  if (master->debug_level) {
2873  EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
2874  ec_print_data(data, rec_size);
2875  }
2876 
2877  if (mbox_prot != EC_MBOX_TYPE_COE) {
2878  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
2879  mbox_prot);
2880  request->errno = EIO;
2881  fsm->state = ec_fsm_coe_error;
2882  return;
2883  }
2884 
2885  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2886  // check for CoE response again
2887  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2888  fsm->retries = EC_FSM_RETRIES;
2890  return;
2891  }
2892 
2893  if (rec_size < 10) {
2894  EC_SLAVE_ERR(slave, "Received currupted SDO upload"
2895  " segment response!\n");
2896  ec_print_data(data, rec_size);
2897  request->errno = EIO;
2898  fsm->state = ec_fsm_coe_error;
2899  return;
2900  }
2901 
2902  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2903  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
2904  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2905  request->index, request->subindex);
2906  request->abort_code = EC_READ_U32(data + 6);
2907  ec_canopen_abort_msg(slave, request->abort_code);
2908  request->errno = EIO;
2909  fsm->state = ec_fsm_coe_error;
2910  return;
2911  }
2912 
2913  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2914  EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
2915  if (fsm->slave->master->debug_level) {
2916  EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
2917  ec_print_data(data, rec_size);
2918  }
2919  // check for CoE response again
2920  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2921  fsm->retries = EC_FSM_RETRIES;
2923  return;
2924  }
2925 
2926  data_size = rec_size - 3; /* Header of segment upload is smaller than
2927  normal upload */
2928  if (rec_size == 10) {
2929  uint8_t seg_size = (EC_READ_U8(data + 2) & 0xE) >> 1;
2930  data_size -= seg_size;
2931  }
2932 
2933  if (request->data_size + data_size > fsm->complete_size) {
2934  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X failed: Fragment"
2935  " exceeding complete size!\n",
2936  request->index, request->subindex);
2937  request->errno = EOVERFLOW;
2938  fsm->state = ec_fsm_coe_error;
2939  return;
2940  }
2941 
2942  memcpy(request->data + request->data_size, data + 3, data_size);
2943  request->data_size += data_size;
2944 
2945  last_segment = EC_READ_U8(data + 2) & 0x01;
2946  if (!last_segment) {
2947  fsm->toggle = !fsm->toggle;
2949  fsm->retries = EC_FSM_RETRIES;
2951  return;
2952  }
2953 
2954  if (request->data_size != fsm->complete_size) {
2955  EC_SLAVE_WARN(slave, "SDO upload 0x%04X:%02X: Assembled data"
2956  " size (%zu) does not match complete size (%u)!\n",
2957  request->index, request->subindex,
2958  request->data_size, fsm->complete_size);
2959  }
2960 
2961  if (master->debug_level) {
2962  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2963  ec_print_data(request->data, request->data_size);
2964  }
2965 
2966  fsm->state = ec_fsm_coe_end; // success
2967 }
2968 
2969 /*****************************************************************************/
2970 
2976  ec_fsm_coe_t *fsm,
2977  ec_datagram_t *datagram
2978  )
2979 {
2980 }
2981 
2982 /*****************************************************************************/
2983 
2989  ec_fsm_coe_t *fsm,
2990  ec_datagram_t *datagram
2991  )
2992 {
2993 }
2994 
2995 /*****************************************************************************/
int ec_fsm_coe_prepare_down_start(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare a donwnload request.
Definition: fsm_coe.c:1374
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:59
void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2789
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:105
int ec_fsm_coe_prepare_up(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare an upload request.
Definition: fsm_coe.c:2139
void ec_fsm_coe_up_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP START.
Definition: fsm_coe.c:2177
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:108
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:2988
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:521
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:2975
void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY CHECK.
Definition: fsm_coe.c:1087
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:134
uint32_t code
Code.
Definition: globals.h:314
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:91
void ec_fsm_coe_dict_desc_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC RESPONSE DATA.
Definition: fsm_coe.c:909
void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY RESPONSE.
Definition: fsm_coe.c:1157
void ec_fsm_coe_up_seg_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE DATA.
Definition: fsm_coe.c:2837
EtherCAT datagram.
Definition: datagram.h:88
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:185
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:1602
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2642
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:1673
void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:2667
uint8_t * ec_slave_mbox_fetch(const ec_slave_t *slave, ec_mbox_data_t *response_data, uint8_t *type, size_t *size)
Processes received mailbox data.
Definition: mailbox.c:172
uint16_t working_counter
Working counter.
Definition: datagram.h:100
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:1899
#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:2716
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:259
#define EC_FSM_COE_DICT_TIMEOUT
Maximum time in ms to wait for responses when reading out the dictionary.
Definition: fsm_coe.c:46
#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:274
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:1038
const char * message
Message belonging to code.
Definition: globals.h:315
struct list_head sdo_dictionary
SDO dictionary list.
Definition: slave.h:269
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:2224
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
EtherCAT CoE state machines.
void ec_fsm_coe_up_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE DATA.
Definition: fsm_coe.c:2463
EtherCAT slave.
Definition: slave.h:214
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
ec_sii_image_t * sii_image
Current complete SII image.
Definition: slave.h:267
Code/Message pair.
Definition: globals.h:313
ec_datagram_state_t state
State.
Definition: datagram.h:101
CANopen over EtherCAT.
Definition: globals.h:184
void ec_fsm_coe_dict_desc_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC REQUEST.
Definition: fsm_coe.c:715
ec_slave_config_t * config
Current configuration.
Definition: slave.h:235
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2676
void ec_fsm_coe_down_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN RESPONSE DATA.
Definition: fsm_coe.c:1784
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:2384
uint8_t enable_sdo_info
SDO information service available.
Definition: globals.h:194
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:172
ec_sdo_request_t * request
SDO request.
Definition: fsm_coe.h:61
Access rights in OP.
Definition: globals.h:230
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:492
unsigned int debug_level
Master debug level.
Definition: master.h:310
void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC RESPONSE.
Definition: fsm_coe.c:865
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:77
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
Definition: datagram.c:627
void ec_fsm_coe_up_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2416
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_dict_entry_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY RESPONSE DATA.
Definition: fsm_coe.c:1201
void ec_fsm_coe_clear(ec_fsm_coe_t *fsm)
Destructor.
Definition: fsm_coe.c:189
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2659
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:2570
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:834
ec_master_t * master
Master owning the slave.
Definition: slave.h:216
int errno
Error number.
Definition: sdo_request.h:67
void ec_fsm_coe_down_seg_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN SEG RESPONSE DATA.
Definition: fsm_coe.c:2015
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:765
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:199
void ec_fsm_coe_dict_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT START.
Definition: fsm_coe.c:338
void ec_fsm_coe_down_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN REQUEST.
Definition: fsm_coe.c:1527
void ec_canopen_abort_msg(const ec_slave_t *slave, uint32_t abort_code)
Outputs an SDO abort message.
Definition: fsm_coe.c:155
int ec_read_mbox_locked(ec_slave_t *slave)
Return the current mailbox lock status and lock it if not locked.
Definition: slave.c:229
Access rights in SAFEOP.
Definition: globals.h:229
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:424
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:100
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:312
void ec_fsm_coe_init(ec_fsm_coe_t *fsm)
Constructor.
Definition: fsm_coe.c:177
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:355
void ec_read_mbox_lock_clear(ec_slave_t *slave)
Clears the mailbox lock.
Definition: slave.c:216
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:103
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2554
ec_coe_emerg_ring_t emerg_ring
CoE emergency ring buffer.
Definition: slave_config.h:152
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:587
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:235
void ec_fsm_coe_dict_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT REQUEST.
Definition: fsm_coe.c:377
void ec_fsm_coe_down_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN START.
Definition: fsm_coe.c:1468
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:1969
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:244
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:2538
EtherCAT slave configuration.
Definition: slave_config.h:118
void ec_fsm_coe_down_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN RESPONSE.
Definition: fsm_coe.c:1739
#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.
ec_sii_t sii
Extracted SII data.
Definition: slave.h:207
uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]
Write access.
Definition: sdo_entry.h:61
void ec_fsm_coe_dict_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT RESPONSE DATA.
Definition: fsm_coe.c:565
Unused and should not be queued (dequeued).
Definition: datagram.h:81
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:212
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:438
Received (dequeued).
Definition: datagram.h:78
Access rights in PREOP.
Definition: globals.h:228
EtherCAT master.
Definition: master.h:202
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:110
ec_mbox_data_t mbox_coe_data
Received mailbox data for CoE.
Definition: slave.h:291
ec_slave_t * slave
slave the FSM runs on
Definition: fsm_coe.h:53
size_t payload_size
Size of the mailbox response payload data.
Definition: datagram.h:125
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
Definition: mailbox.c:122
const ec_code_msg_t sdo_abort_messages[]
SDO abort messages.
Definition: fsm_coe.c:114
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:2306
unsigned int has_general
General category present.
Definition: slave.h:179
Finite state machines for the CANopen over EtherCAT protocol.
Definition: fsm_coe.h:52