IgH EtherCAT Master  1.6.0-rc1
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  if (fsm->datagram &&
243  (fsm->datagram->state == EC_DATAGRAM_INIT ||
244  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
245  fsm->datagram->state == EC_DATAGRAM_SENT)) {
246  // datagram not received yet
247  if (datagram != fsm->datagram)
248  datagram->state = EC_DATAGRAM_INVALID;
249  return 1;
250  }
251 
252  fsm->state(fsm, datagram);
253 
254  if (fsm->state == ec_fsm_coe_end || fsm->state == ec_fsm_coe_error) {
255  fsm->datagram = NULL;
256  return 0;
257  }
258 
259  fsm->datagram = datagram;
260  return 1;
261 }
262 
263 /*****************************************************************************/
264 
269  const ec_fsm_coe_t *fsm
270  )
271 {
272  return fsm->state == ec_fsm_coe_end;
273 }
274 
275 /*****************************************************************************/
276 
284  ec_fsm_coe_t *fsm,
285  const uint8_t *data,
286  size_t size
287  )
288 {
289  if (size < 2 || ((EC_READ_U16(data) >> 12) & 0x0F) != 0x01)
290  return 0;
291 
292  if (size < 10) {
293  EC_SLAVE_WARN(fsm->slave, "Received incomplete CoE Emergency"
294  " request:\n");
295  ec_print_data(data, size);
296  return 1;
297  }
298 
299  {
300  ec_slave_config_t *sc = fsm->slave->config;
301  if (sc) {
302  ec_coe_emerg_ring_push(&sc->emerg_ring, data + 2);
303  }
304  }
305 
306  EC_SLAVE_WARN(fsm->slave, "CoE Emergency Request received:\n"
307  "Error code 0x%04X, Error register 0x%02X, data:\n",
308  EC_READ_U16(data + 2), EC_READ_U8(data + 4));
309  ec_print_data(data + 5, 5);
310  return 1;
311 }
312 
313 /******************************************************************************
314  * CoE dictionary state machine
315  *****************************************************************************/
316 
322  ec_fsm_coe_t *fsm,
323  ec_datagram_t *datagram
324  )
325 {
326  ec_slave_t *slave = fsm->slave;
327  uint8_t *data = ec_slave_mbox_prepare_send(slave, datagram,
328  EC_MBOX_TYPE_COE, 8);
329  if (IS_ERR(data)) {
330  return PTR_ERR(data);
331  }
332 
333  EC_WRITE_U16(data, 0x8 << 12); // SDO information
334  EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
335  EC_WRITE_U8 (data + 3, 0x00);
336  EC_WRITE_U16(data + 4, 0x0000);
337  EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
338 
340  return 0;
341 }
342 
343 /*****************************************************************************/
344 
348  ec_fsm_coe_t *fsm,
349  ec_datagram_t *datagram
350  )
351 {
352  ec_slave_t *slave = fsm->slave;
353 
354  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
355  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
356  fsm->state = ec_fsm_coe_error;
357  return;
358  }
359 
360  if (slave->sii.has_general && !slave->sii.coe_details.enable_sdo_info) {
361  EC_SLAVE_ERR(slave, "Slave does not support"
362  " SDO information service!\n");
363  fsm->state = ec_fsm_coe_error;
364  return;
365  }
366 
367  fsm->retries = EC_FSM_RETRIES;
368 
369  if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
370  fsm->state = ec_fsm_coe_error;
371  }
372 }
373 
374 /*****************************************************************************/
375 
380  ec_fsm_coe_t *fsm,
381  ec_datagram_t *datagram
382  )
383 {
384  ec_slave_t *slave = fsm->slave;
385 
386  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
387  if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
388  fsm->state = ec_fsm_coe_error;
389  }
390  return;
391  }
392 
393  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
394  fsm->state = ec_fsm_coe_error;
395  EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
396  " request datagram: ");
398  return;
399  }
400 
401  if (fsm->datagram->working_counter != 1) {
402  fsm->state = ec_fsm_coe_error;
403  EC_SLAVE_ERR(slave, "Reception of CoE dictionary request failed: ");
405  return;
406  }
407 
408  fsm->jiffies_start = fsm->datagram->jiffies_sent;
409 
410  // mailbox read check is skipped if a read request is already ongoing
411  if (ec_read_mbox_locked(slave)) {
413  // the datagram is not used and marked as invalid
414  datagram->state = EC_DATAGRAM_INVALID;
415  } else {
416  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
417  fsm->retries = EC_FSM_RETRIES;
419  }
420 }
421 
422 /*****************************************************************************/
423 
427  ec_fsm_coe_t *fsm,
428  ec_datagram_t *datagram
429  )
430 {
431  ec_slave_t *slave = fsm->slave;
432 
433  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
434  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
435  return;
436  }
437 
438  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
439  fsm->state = ec_fsm_coe_error;
441  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
443  return;
444  }
445 
446  if (fsm->datagram->working_counter != 1) {
447  fsm->state = ec_fsm_coe_error;
449  EC_SLAVE_ERR(slave,"Reception of CoE mailbox check"
450  " datagram failed: ");
452  return;
453  }
454 
455  if (!ec_slave_mbox_check(fsm->datagram)) {
456  unsigned long diff_ms = 0;
457 
458  // check that data is not already received by another read request
459  if (slave->mbox_coe_data.payload_size > 0) {
462  fsm->state(fsm, datagram);
463  return;
464  }
465 
466  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
467  1000 / HZ;
468 
469  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
470  fsm->state = ec_fsm_coe_error;
472  EC_SLAVE_ERR(slave, "Timeout while waiting for"
473  " SDO dictionary list response.\n");
474  return;
475  }
476 
477  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
478  fsm->retries = EC_FSM_RETRIES;
479  return;
480  }
481 
482  // Fetch response
483  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
484  fsm->retries = EC_FSM_RETRIES;
486 }
487 
488 /*****************************************************************************/
489 
495  ec_fsm_coe_t *fsm,
496  ec_datagram_t *datagram
497  )
498 {
499  ec_slave_t *slave = fsm->slave;
500  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
501  8);
502  if (IS_ERR(data)) {
503  return PTR_ERR(data);
504  }
505 
506  EC_WRITE_U16(data, 0x8 << 12); // SDO information
507  EC_WRITE_U8 (data + 2, 0x03); // Get object description request
508  EC_WRITE_U8 (data + 3, 0x00);
509  EC_WRITE_U16(data + 4, 0x0000);
510  EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
511 
513  return 0;
514 }
515 
516 /*****************************************************************************/
517 
524  ec_fsm_coe_t *fsm,
525  ec_datagram_t *datagram
526  )
527 {
528  ec_slave_t *slave = fsm->slave;
529 
530  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
531  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
532  return;
533  }
534 
535  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
536  fsm->state = ec_fsm_coe_error;
538  EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
539  " response datagram: ");
541  return;
542  }
543 
544  if (fsm->datagram->working_counter != 1) {
545  // only an error if data has not already been read by another read request
546  if (slave->mbox_coe_data.payload_size == 0) {
547  fsm->state = ec_fsm_coe_error;
549  EC_SLAVE_ERR(slave, "Reception of CoE dictionary response failed: ");
551  return;
552  }
553  }
556  fsm->state(fsm, datagram);
557 }
558 
559 
560 /*****************************************************************************/
561 
568  ec_fsm_coe_t *fsm,
569  ec_datagram_t *datagram
570  )
571 {
572  ec_slave_t *slave = fsm->slave;
573  uint8_t *data, mbox_prot;
574  size_t rec_size;
575  unsigned int sdo_count, i;
576  uint16_t sdo_index, fragments_left;
577  ec_sdo_t *sdo;
578  bool first_segment;
579  size_t index_list_offset;
580 
581  // process the data available or initiate a new mailbox read check
582  if (slave->mbox_coe_data.payload_size > 0) {
583  slave->mbox_coe_data.payload_size = 0;
584  } else {
585  // initiate a new mailbox read check if required data is not available
586  if (ec_read_mbox_locked(slave)) {
587  // await current read request and mark the datagram as invalid
588  datagram->state = EC_DATAGRAM_INVALID;
589  } else {
590  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
592  }
593  return;
594  }
595 
596  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
597  if (IS_ERR(data)) {
598  fsm->state = ec_fsm_coe_error;
599  return;
600  }
601 
602  if (mbox_prot != EC_MBOX_TYPE_COE) {
603  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
604  mbox_prot);
605  fsm->state = ec_fsm_coe_error;
606  return;
607  }
608 
609  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
610  // check for CoE response again
611  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
612  fsm->retries = EC_FSM_RETRIES;
614  return;
615  }
616 
617  if (rec_size < 3) {
618  EC_SLAVE_ERR(slave, "Received corrupted SDO dictionary response"
619  " (size %zu).\n", rec_size);
620  fsm->state = ec_fsm_coe_error;
621  return;
622  }
623 
624  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
625  (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
626  EC_SLAVE_ERR(slave, "SDO information error response!\n");
627  if (rec_size < 10) {
628  EC_SLAVE_ERR(slave, "Incomplete SDO information"
629  " error response:\n");
630  ec_print_data(data, rec_size);
631  } else {
632  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
633  }
634  fsm->state = ec_fsm_coe_error;
635  return;
636  }
637 
638  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
639  (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
640  if (fsm->slave->master->debug_level) {
641  EC_SLAVE_DBG(slave, 1, "Invalid SDO list response!"
642  " Retrying...\n");
643  ec_print_data(data, rec_size);
644  }
645  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
646  fsm->retries = EC_FSM_RETRIES;
648  return;
649  }
650 
651  first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
652  index_list_offset = first_segment ? 8 : 6;
653 
654  if (rec_size < index_list_offset || rec_size % 2) {
655  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
656  ec_print_data(data, rec_size);
657  fsm->state = ec_fsm_coe_error;
658  return;
659  }
660 
661  sdo_count = (rec_size - index_list_offset) / 2;
662 
663  for (i = 0; i < sdo_count; i++) {
664  sdo_index = EC_READ_U16(data + index_list_offset + i * 2);
665  if (!sdo_index) {
666  EC_SLAVE_DBG(slave, 1, "SDO dictionary contains index 0x0000.\n");
667  continue;
668  }
669 
670  if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
671  EC_SLAVE_ERR(slave, "Failed to allocate memory for SDO!\n");
672  fsm->state = ec_fsm_coe_error;
673  return;
674  }
675 
676  ec_sdo_init(sdo, slave, sdo_index);
677  list_add_tail(&sdo->list, &slave->sdo_dictionary);
678  }
679 
680  fragments_left = EC_READ_U16(data + 4);
681  if (fragments_left) {
682  EC_SLAVE_DBG(slave, 1, "SDO list fragments left: %u\n",
683  fragments_left);
684  }
685 
686  if (EC_READ_U8(data + 2) & 0x80 || fragments_left) {
687  // more messages waiting. check again.
688  fsm->jiffies_start = fsm->datagram->jiffies_sent;
689  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
690  fsm->retries = EC_FSM_RETRIES;
692  return;
693  }
694 
695  if (list_empty(&slave->sdo_dictionary)) {
696  // no SDOs in dictionary. finished.
697  fsm->state = ec_fsm_coe_end; // success
698  return;
699  }
700 
701  // fetch SDO descriptions
702  fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);
703 
704  fsm->retries = EC_FSM_RETRIES;
705  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
706  fsm->state = ec_fsm_coe_error;
707  }
708 }
709 
710 /*****************************************************************************/
711 
718  ec_fsm_coe_t *fsm,
719  ec_datagram_t *datagram
720  )
721 {
722  ec_slave_t *slave = fsm->slave;
723 
724  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
725  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
726  fsm->state = ec_fsm_coe_error;
727  }
728  return;
729  }
730 
731  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
732  fsm->state = ec_fsm_coe_error;
733  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
734  " description request datagram: ");
736  return;
737  }
738 
739  if (fsm->datagram->working_counter != 1) {
740  fsm->state = ec_fsm_coe_error;
741  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
742  " request failed: ");
744  return;
745  }
746 
747  fsm->jiffies_start = fsm->datagram->jiffies_sent;
748 
749  // mailbox read check is skipped if a read request is already ongoing
750  if (ec_read_mbox_locked(slave)) {
752  // the datagram is not used and marked as invalid
753  datagram->state = EC_DATAGRAM_INVALID;
754  } else {
755  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
756  fsm->retries = EC_FSM_RETRIES;
758  }
759 }
760 
761 /*****************************************************************************/
762 
768  ec_fsm_coe_t *fsm,
769  ec_datagram_t *datagram
770  )
771 {
772  ec_slave_t *slave = fsm->slave;
773 
774  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
775  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
776  return;
777  }
778 
779  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
780  fsm->state = ec_fsm_coe_error;
782  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
784  return;
785  }
786 
787  if (fsm->datagram->working_counter != 1) {
788  fsm->state = ec_fsm_coe_error;
790  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
791  " datagram failed: ");
793  return;
794  }
795 
796  if (!ec_slave_mbox_check(fsm->datagram)) {
797  unsigned long diff_ms = 0;
798 
799  // check that data is not already received by another read request
800  if (slave->mbox_coe_data.payload_size > 0) {
803  fsm->state(fsm, datagram);
804  return;
805  }
806 
807  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
808  1000 / HZ;
809 
810  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
811  fsm->state = ec_fsm_coe_error;
813  EC_SLAVE_ERR(slave, "Timeout while waiting for"
814  " SDO 0x%04x object description response.\n",
815  fsm->sdo->index);
816  return;
817  }
818 
819  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
820  fsm->retries = EC_FSM_RETRIES;
821  return;
822  }
823 
824  // Fetch response
825  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
826  fsm->retries = EC_FSM_RETRIES;
828 }
829 
830 /*****************************************************************************/
831 
837  ec_fsm_coe_t *fsm,
838  ec_datagram_t *datagram
839  )
840 {
841  ec_slave_t *slave = fsm->slave;
842  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
843  10);
844  if (IS_ERR(data)) {
845  return PTR_ERR(data);
846  }
847 
848  EC_WRITE_U16(data, 0x8 << 12); // SDO information
849  EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
850  EC_WRITE_U8 (data + 3, 0x00);
851  EC_WRITE_U16(data + 4, 0x0000);
852  EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
853  EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
854  EC_WRITE_U8 (data + 9, 0x01); // value info (access rights only)
855 
857  return 0;
858 }
859 
860 /*****************************************************************************/
861 
868  ec_fsm_coe_t *fsm,
869  ec_datagram_t *datagram
870  )
871 {
872  ec_slave_t *slave = fsm->slave;
873 
874  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
875  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
876  return;
877  }
878 
879  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
880  fsm->state = ec_fsm_coe_error;
882  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description"
883  " response datagram: ");
885  return;
886  }
887 
888  if (fsm->datagram->working_counter != 1) {
889  // only an error if data has not already been read by another read request
890  if (slave->mbox_coe_data.payload_size == 0) {
891  fsm->state = ec_fsm_coe_error;
893  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
894  " response failed: ");
896  return;
897  }
898  }
901  fsm->state(fsm, datagram);
902 }
903 
904 /*****************************************************************************/
905 
912  ec_fsm_coe_t *fsm,
913  ec_datagram_t *datagram
914  )
915 {
916  ec_slave_t *slave = fsm->slave;
917  ec_sdo_t *sdo = fsm->sdo;
918  uint8_t *data, mbox_prot;
919  size_t rec_size, name_size;
920 
921  // process the data available or initiate a new mailbox read check
922  if (slave->mbox_coe_data.payload_size > 0) {
923  slave->mbox_coe_data.payload_size = 0;
924  } else {
925  // initiate a new mailbox read check if required data is not available
926  if (ec_read_mbox_locked(slave)) {
927  // await current read request and mark the datagram as invalid
928  datagram->state = EC_DATAGRAM_INVALID;
929  } else {
930  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
932  }
933  return;
934  }
935 
936  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
937  if (IS_ERR(data)) {
938  fsm->state = ec_fsm_coe_error;
939  return;
940  }
941 
942  if (mbox_prot != EC_MBOX_TYPE_COE) {
943  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
944  mbox_prot);
945  fsm->state = ec_fsm_coe_error;
946  return;
947  }
948 
949  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
950  // check for CoE response again
951  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
952  fsm->retries = EC_FSM_RETRIES;
954  return;
955  }
956 
957  if (rec_size < 3) {
958  EC_SLAVE_ERR(slave, "Received corrupted SDO description response"
959  " (size %zu).\n", rec_size);
960  fsm->state = ec_fsm_coe_error;
961  return;
962  }
963 
964  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
965  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
966  EC_SLAVE_ERR(slave, "SDO information error response while"
967  " fetching SDO 0x%04X!\n", sdo->index);
968  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
969  fsm->state = ec_fsm_coe_error;
970  return;
971  }
972 
973  if (rec_size < 8) {
974  EC_SLAVE_ERR(slave, "Received corrupted SDO"
975  " description response (size %zu).\n", rec_size);
976  fsm->state = ec_fsm_coe_error;
977  return;
978  }
979 
980  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
981  (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response
982  EC_READ_U16(data + 6) != sdo->index) { // SDO index
983  if (fsm->slave->master->debug_level) {
984  EC_SLAVE_DBG(slave, 1, "Invalid object description response while"
985  " fetching SDO 0x%04X!\n", sdo->index);
986  ec_print_data(data, rec_size);
987  }
988  // check for CoE response again
989  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
990  fsm->retries = EC_FSM_RETRIES;
992  return;
993  }
994 
995  if (rec_size < 12) {
996  EC_SLAVE_ERR(slave, "Invalid data size!\n");
997  ec_print_data(data, rec_size);
998  fsm->state = ec_fsm_coe_error;
999  return;
1000  }
1001 
1002  sdo->max_subindex = EC_READ_U8(data + 10);
1003  sdo->object_code = EC_READ_U8(data + 11);
1004 
1005  name_size = rec_size - 12;
1006  if (name_size) {
1007  if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) {
1008  EC_SLAVE_ERR(slave, "Failed to allocate SDO name!\n");
1009  fsm->state = ec_fsm_coe_error;
1010  return;
1011  }
1012 
1013  memcpy(sdo->name, data + 12, name_size);
1014  sdo->name[name_size] = 0;
1015  }
1016 
1017  if (EC_READ_U8(data + 2) & 0x80) {
1018  EC_SLAVE_ERR(slave, "Fragment follows (not implemented)!\n");
1019  fsm->state = ec_fsm_coe_error;
1020  return;
1021  }
1022 
1023  // start fetching entries
1024 
1025  fsm->subindex = 0;
1026  fsm->retries = EC_FSM_RETRIES;
1027 
1028  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1029  fsm->state = ec_fsm_coe_error;
1030  }
1031 }
1032 
1033 /*****************************************************************************/
1034 
1041  ec_fsm_coe_t *fsm,
1042  ec_datagram_t *datagram
1043  )
1044 {
1045  ec_slave_t *slave = fsm->slave;
1046 
1047  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1048  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1049  fsm->state = ec_fsm_coe_error;
1050  }
1051  return;
1052  }
1053 
1054  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1055  fsm->state = ec_fsm_coe_error;
1056  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry"
1057  " request datagram: ");
1059  return;
1060  }
1061 
1062  if (fsm->datagram->working_counter != 1) {
1063  fsm->state = ec_fsm_coe_error;
1064  EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: ");
1066  return;
1067  }
1068 
1069  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1070 
1071  // mailbox read check is skipped if a read request is already ongoing
1072  if (ec_read_mbox_locked(slave)) {
1074  // the datagram is not used and marked as invalid
1075  datagram->state = EC_DATAGRAM_INVALID;
1076  } else {
1077  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1078  fsm->retries = EC_FSM_RETRIES;
1080  }
1081 }
1082 
1083 /*****************************************************************************/
1084 
1090  ec_fsm_coe_t *fsm,
1091  ec_datagram_t *datagram
1092  )
1093 {
1094  ec_slave_t *slave = fsm->slave;
1095 
1096  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1097  ec_slave_mbox_prepare_check(slave, datagram); // can not fail
1098  return;
1099  }
1100 
1101  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1102  fsm->state = ec_fsm_coe_error;
1103  ec_read_mbox_lock_clear(slave);
1104  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1106  return;
1107  }
1108 
1109  if (fsm->datagram->working_counter != 1) {
1110  fsm->state = ec_fsm_coe_error;
1111  ec_read_mbox_lock_clear(slave);
1112  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1113  " datagram failed: ");
1115  return;
1116  }
1117 
1118  if (!ec_slave_mbox_check(fsm->datagram)) {
1119  unsigned long diff_ms = 0;
1120 
1121  // check that data is not already received by another read request
1122  if (slave->mbox_coe_data.payload_size > 0) {
1123  ec_read_mbox_lock_clear(slave);
1125  fsm->state(fsm, datagram);
1126  return;
1127  }
1128 
1129  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1130  1000 / HZ;
1131 
1132  if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
1133  fsm->state = ec_fsm_coe_error;
1134  ec_read_mbox_lock_clear(slave);
1135  EC_SLAVE_ERR(slave, "Timeout while waiting for"
1136  " SDO entry 0x%04x:%x description response.\n",
1137  fsm->sdo->index, fsm->subindex);
1138  return;
1139  }
1140 
1141  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1142  fsm->retries = EC_FSM_RETRIES;
1143  return;
1144  }
1145 
1146  // Fetch response
1147  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1148  fsm->retries = EC_FSM_RETRIES;
1150 }
1151 
1152 /*****************************************************************************/
1153 
1160  ec_fsm_coe_t *fsm,
1161  ec_datagram_t *datagram
1162  )
1163 {
1164  ec_slave_t *slave = fsm->slave;
1165 
1166  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1167  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1168  return;
1169  }
1170 
1171  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1172  fsm->state = ec_fsm_coe_error;
1173  ec_read_mbox_lock_clear(slave);
1174  EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
1175  " description response datagram: ");
1177  return;
1178  }
1179 
1180  if (fsm->datagram->working_counter != 1) {
1181  // only an error if data has not already been read by another read request
1182  if (slave->mbox_coe_data.payload_size == 0) {
1183  fsm->state = ec_fsm_coe_error;
1184  ec_read_mbox_lock_clear(slave);
1185  EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
1186  " response failed: ");
1188  return;
1189  }
1190  }
1191  ec_read_mbox_lock_clear(slave);
1193  fsm->state(fsm, datagram);
1194 }
1195 
1196 /*****************************************************************************/
1197 
1204  ec_fsm_coe_t *fsm,
1205  ec_datagram_t *datagram
1206  )
1207 {
1208  ec_slave_t *slave = fsm->slave;
1209  ec_sdo_t *sdo = fsm->sdo;
1210  uint8_t *data, mbox_prot;
1211  size_t rec_size, data_size;
1212  ec_sdo_entry_t *entry;
1213  u16 word;
1214 
1215  // process the data available or initiate a new mailbox read check
1216  if (slave->mbox_coe_data.payload_size > 0) {
1217  slave->mbox_coe_data.payload_size = 0;
1218  } else {
1219  // initiate a new mailbox read check if required data is not available
1220  if (ec_read_mbox_locked(slave)) {
1221  // await current read request and mark the datagram as invalid
1222  datagram->state = EC_DATAGRAM_INVALID;
1223  } else {
1224  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1226  }
1227  return;
1228  }
1229 
1230  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
1231  if (IS_ERR(data)) {
1232  fsm->state = ec_fsm_coe_error;
1233  return;
1234  }
1235 
1236  if (mbox_prot != EC_MBOX_TYPE_COE) {
1237  EC_SLAVE_ERR(slave, "Received mailbox protocol"
1238  " 0x%02X as response.\n", mbox_prot);
1239  fsm->state = ec_fsm_coe_error;
1240  return;
1241  }
1242 
1243  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1244  // check for CoE response again
1245  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1246  fsm->retries = EC_FSM_RETRIES;
1248  return;
1249  }
1250 
1251  if (rec_size < 3) {
1252  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1253  " description response (size %zu).\n", rec_size);
1254  fsm->state = ec_fsm_coe_error;
1255  return;
1256  }
1257 
1258  if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
1259  (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
1260  EC_SLAVE_WARN(slave, "SDO information error response while"
1261  " fetching SDO entry 0x%04X:%02X!\n",
1262  sdo->index, fsm->subindex);
1263  ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
1264 
1265  /* There may be gaps in the subindices, so try to continue with next
1266  * subindex. */
1267 
1268  } else {
1269 
1270  if (rec_size < 9) {
1271  EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
1272  " description response (size %zu).\n", rec_size);
1273  fsm->state = ec_fsm_coe_error;
1274  return;
1275  }
1276 
1277  if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
1278  (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
1279  EC_READ_U16(data + 6) != sdo->index || // SDO index
1280  EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex
1281  if (fsm->slave->master->debug_level) {
1282  EC_SLAVE_DBG(slave, 1, "Invalid entry description response"
1283  " while fetching SDO entry 0x%04X:%02X!\n",
1284  sdo->index, fsm->subindex);
1285  ec_print_data(data, rec_size);
1286  }
1287  // check for CoE response again
1288  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1289  fsm->retries = EC_FSM_RETRIES;
1291  return;
1292  }
1293 
1294  if (rec_size < 16) {
1295  EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
1296  ec_print_data(data, rec_size);
1297  fsm->state = ec_fsm_coe_error;
1298  return;
1299  }
1300 
1301  data_size = rec_size - 16;
1302 
1303  if (!(entry = (ec_sdo_entry_t *)
1304  kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) {
1305  EC_SLAVE_ERR(slave, "Failed to allocate entry!\n");
1306  fsm->state = ec_fsm_coe_error;
1307  return;
1308  }
1309 
1310  ec_sdo_entry_init(entry, sdo, fsm->subindex);
1311  entry->data_type = EC_READ_U16(data + 10);
1312  entry->bit_length = EC_READ_U16(data + 12);
1313 
1314  // read access rights
1315  word = EC_READ_U16(data + 14);
1316  entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001;
1318  (word >> 1) & 0x0001;
1319  entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001;
1320  entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001;
1322  (word >> 4) & 0x0001;
1323  entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001;
1324 
1325  if (data_size) {
1326  uint8_t *desc;
1327  if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) {
1328  EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n");
1329  fsm->state = ec_fsm_coe_error;
1330  return;
1331  }
1332  memcpy(desc, data + 16, data_size);
1333  desc[data_size] = 0;
1334  entry->description = desc;
1335  }
1336 
1337  list_add_tail(&entry->list, &sdo->entries);
1338  }
1339 
1340  if (fsm->subindex < sdo->max_subindex) {
1341 
1342  fsm->subindex++;
1343  fsm->retries = EC_FSM_RETRIES;
1344 
1345  if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
1346  fsm->state = ec_fsm_coe_error;
1347  }
1348 
1349  return;
1350  }
1351 
1352  // another SDO description to fetch?
1353  if (fsm->sdo->list.next != &slave->sdo_dictionary) {
1354 
1355  fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
1356  fsm->retries = EC_FSM_RETRIES;
1357 
1358  if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
1359  fsm->state = ec_fsm_coe_error;
1360  }
1361 
1362  return;
1363  }
1364 
1365  fsm->state = ec_fsm_coe_end;
1366 }
1367 
1368 /******************************************************************************
1369  * CoE state machine
1370  *****************************************************************************/
1371 
1377  ec_fsm_coe_t *fsm,
1378  ec_datagram_t *datagram
1379  )
1380 {
1381  u8 *data;
1382  ec_slave_t *slave = fsm->slave;
1383  ec_sdo_request_t *request = fsm->request;
1384  uint8_t data_set_size;
1385 
1386  if (request->data_size > 0 && request->data_size <= 4) {
1387  // use expedited transfer mode for lengths between 1 and 4 bytes
1388  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1390  if (IS_ERR(data)) {
1391  request->errno = PTR_ERR(data);
1392  return PTR_ERR(data);
1393  }
1394 
1395  fsm->remaining = 0;
1396 
1397  data_set_size = 4 - request->data_size;
1398 
1399  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1400  EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
1401  | data_set_size << 2
1402  | ((request->complete_access ? 1 : 0) << 4)
1403  | 0x1 << 5)); // Download request
1404  EC_WRITE_U16(data + 3, request->index);
1405  EC_WRITE_U8 (data + 5,
1406  request->complete_access ? 0x00 : request->subindex);
1407  memcpy(data + 6, request->data, request->data_size);
1408  memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);
1409 
1410  if (slave->master->debug_level) {
1411  EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
1413  }
1414  }
1415  else { // data_size < 1 or data_size > 4, use normal transfer type
1416  size_t data_size,
1417  max_data_size =
1419  required_data_size =
1421 
1422  if (max_data_size < required_data_size) {
1423  // segmenting needed
1424  data_size = max_data_size;
1425  } else {
1426  data_size = required_data_size;
1427  }
1428 
1429  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1430  data_size);
1431  if (IS_ERR(data)) {
1432  request->errno = PTR_ERR(data);
1433  return PTR_ERR(data);
1434  }
1435 
1436  fsm->offset = 0;
1437  fsm->remaining = request->data_size;
1438 
1439  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1440  EC_WRITE_U8(data + 2,
1441  0x1 // size indicator, normal
1442  | ((request->complete_access ? 1 : 0) << 4)
1443  | 0x1 << 5); // Download request
1444  EC_WRITE_U16(data + 3, request->index);
1445  EC_WRITE_U8 (data + 5,
1446  request->complete_access ? 0x00 : request->subindex);
1447  EC_WRITE_U32(data + 6, request->data_size);
1448 
1449  if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
1450  size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
1451  memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
1452  request->data, segment_size);
1453  fsm->offset += segment_size;
1454  fsm->remaining -= segment_size;
1455  }
1456 
1457  if (slave->master->debug_level) {
1458  EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
1459  ec_print_data(data, data_size);
1460  }
1461  }
1462 
1464  return 0;
1465 }
1466 
1467 /****************************************************************************/
1468 
1472  ec_fsm_coe_t *fsm,
1473  ec_datagram_t *datagram
1474  )
1475 {
1476  ec_slave_t *slave = fsm->slave;
1477  ec_sdo_request_t *request = fsm->request;
1478 
1479  if (fsm->slave->master->debug_level) {
1480  char subidxstr[10];
1481  if (request->complete_access) {
1482  subidxstr[0] = 0x00;
1483  } else {
1484  sprintf(subidxstr, ":%02X", request->subindex);
1485  }
1486  EC_SLAVE_DBG(slave, 1, "Downloading SDO 0x%04X%s.\n",
1487  request->index, subidxstr);
1488  ec_print_data(request->data, request->data_size);
1489  }
1490 
1491  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
1492  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
1493  request->errno = EPROTONOSUPPORT;
1494  fsm->state = ec_fsm_coe_error;
1495  return;
1496  }
1497 
1498  if (slave->configured_rx_mailbox_size <
1500  EC_SLAVE_ERR(slave, "Mailbox too small!\n");
1501  request->errno = EOVERFLOW;
1502  fsm->state = ec_fsm_coe_error;
1503  return;
1504  }
1505 
1506 
1507  fsm->request->jiffies_sent = jiffies;
1508  fsm->retries = EC_FSM_RETRIES;
1509 
1510  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1511  fsm->state = ec_fsm_coe_error;
1512  }
1513 }
1514 
1515 /*****************************************************************************/
1516 
1523  ec_fsm_coe_t *fsm,
1524  ec_datagram_t *datagram
1525  )
1526 {
1527  ec_slave_t *slave = fsm->slave;
1528  unsigned long diff_ms;
1529 
1530  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1531  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1532  fsm->state = ec_fsm_coe_error;
1533  }
1534  return;
1535  }
1536 
1537  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1538  fsm->request->errno = EIO;
1539  fsm->state = ec_fsm_coe_error;
1540  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1541  " request datagram: ");
1543  return;
1544  }
1545 
1546  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
1547 
1548  if (fsm->datagram->working_counter != 1) {
1549  if (!fsm->datagram->working_counter) {
1550  if (diff_ms < fsm->request->response_timeout) {
1551 #if DEBUG_RETRIES
1552  EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
1553  " download request. Retrying after %lu ms...\n",
1554  diff_ms);
1555 #endif
1556  // no response; send request datagram again
1557  if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
1558  fsm->state = ec_fsm_coe_error;
1559  }
1560  return;
1561  }
1562  }
1563  fsm->request->errno = EIO;
1564  fsm->state = ec_fsm_coe_error;
1565  EC_SLAVE_ERR(slave, "Reception of CoE download request"
1566  " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
1567  fsm->request->index, fsm->request->subindex, diff_ms);
1569  return;
1570  }
1571 
1572 #if DEBUG_LONG
1573  if (diff_ms > 200) {
1574  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
1575  fsm->request->index, fsm->request->subindex, diff_ms);
1576  }
1577 #endif
1578 
1579  fsm->jiffies_start = fsm->datagram->jiffies_sent;
1580 
1581  // mailbox read check is skipped if a read request is already ongoing
1582  if (ec_read_mbox_locked(slave)) {
1584  // the datagram is not used and marked as invalid
1585  datagram->state = EC_DATAGRAM_INVALID;
1586  } else {
1587  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1588  fsm->retries = EC_FSM_RETRIES;
1590  }
1591 }
1592 
1593 /*****************************************************************************/
1594 
1598  ec_fsm_coe_t *fsm,
1599  ec_datagram_t *datagram
1600  )
1601 {
1602  ec_slave_t *slave = fsm->slave;
1603 
1604  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1605  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1606  return;
1607  }
1608 
1609  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1610  fsm->request->errno = EIO;
1611  fsm->state = ec_fsm_coe_error;
1612  ec_read_mbox_lock_clear(slave);
1613  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
1614  " datagram: ");
1616  return;
1617  }
1618 
1619  if (fsm->datagram->working_counter != 1) {
1620  fsm->request->errno = EIO;
1621  fsm->state = ec_fsm_coe_error;
1622  ec_read_mbox_lock_clear(slave);
1623  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
1624  " datagram failed: ");
1626  return;
1627  }
1628 
1629  if (!ec_slave_mbox_check(fsm->datagram)) {
1630  unsigned long diff_ms = 0;
1631 
1632  // check that data is not already received by another read request
1633  if (slave->mbox_coe_data.payload_size > 0) {
1634  ec_read_mbox_lock_clear(slave);
1636  fsm->state(fsm, datagram);
1637  return;
1638  }
1639 
1640  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1641  1000 / HZ;
1642 
1643  if (diff_ms >= fsm->request->response_timeout) {
1644  fsm->request->errno = EIO;
1645  fsm->state = ec_fsm_coe_error;
1646  ec_read_mbox_lock_clear(slave);
1647  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
1648  " for SDO 0x%04x:%x download response.\n", diff_ms,
1649  fsm->request->index, fsm->request->subindex);
1650  return;
1651  }
1652 
1653  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1654  fsm->retries = EC_FSM_RETRIES;
1655  return;
1656  }
1657 
1658  // Fetch response
1659  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1660  fsm->retries = EC_FSM_RETRIES;
1662 }
1663 
1664 /*****************************************************************************/
1665 
1669  ec_fsm_coe_t *fsm,
1670  ec_datagram_t *datagram
1671  )
1672 {
1673  ec_slave_t *slave = fsm->slave;
1674  ec_sdo_request_t *request = fsm->request;
1675  size_t max_segment_size =
1679  size_t data_size;
1680  uint8_t last_segment, seg_data_size, *data;
1681 
1682  if (fsm->remaining > max_segment_size) {
1683  fsm->segment_size = max_segment_size;
1684  last_segment = 0;
1685  } else {
1686  fsm->segment_size = fsm->remaining;
1687  last_segment = 1;
1688  }
1689 
1691  seg_data_size = 0x00;
1692  data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size;
1693  } else {
1694  seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size;
1695  data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE
1697  }
1698 
1699  data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
1700  data_size);
1701  if (IS_ERR(data)) {
1702  request->errno = PTR_ERR(data);
1703  fsm->state = ec_fsm_coe_error;
1704  return;
1705  }
1706 
1707  EC_WRITE_U16(data, 0x2 << 12); // SDO request
1708  EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
1709  | (seg_data_size << 1)
1710  | (fsm->toggle << 4)
1711  | (0x00 << 5)); // Download segment request
1712  memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
1713  request->data + fsm->offset, fsm->segment_size);
1715  memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size,
1717  }
1718 
1719  if (slave->master->debug_level) {
1720  EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
1721  ec_print_data(data, data_size);
1722  }
1723 
1725 }
1726 
1727 /*****************************************************************************/
1728 
1735  ec_fsm_coe_t *fsm,
1736  ec_datagram_t *datagram
1737  )
1738 {
1739  ec_slave_t *slave = fsm->slave;
1740  ec_sdo_request_t *request = fsm->request;
1741 
1742  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1743  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1744  return;
1745  }
1746 
1747  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1748  request->errno = EIO;
1749  fsm->state = ec_fsm_coe_error;
1750  EC_SLAVE_ERR(slave, "Failed to receive CoE download"
1751  " response datagram: ");
1753  return;
1754  }
1755 
1756  if (fsm->datagram->working_counter != 1) {
1757  // only an error if data has not already been read by another read request
1758  if (slave->mbox_coe_data.payload_size == 0) {
1759  request->errno = EIO;
1760  fsm->state = ec_fsm_coe_error;
1761  ec_read_mbox_lock_clear(slave);
1762  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1764  return;
1765  }
1766  }
1767  ec_read_mbox_lock_clear(slave);
1769  fsm->state(fsm, datagram);
1770 }
1771 
1772 /*****************************************************************************/
1773 
1780  ec_fsm_coe_t *fsm,
1781  ec_datagram_t *datagram
1782  )
1783 {
1784  ec_slave_t *slave = fsm->slave;
1785  uint8_t *data, mbox_prot;
1786  size_t rec_size;
1787  ec_sdo_request_t *request = fsm->request;
1788 
1789  // process the data available or initiate a new mailbox read check
1790  if (slave->mbox_coe_data.payload_size > 0) {
1791  slave->mbox_coe_data.payload_size = 0;
1792  } else {
1793  // initiate a new mailbox read check if required data is not available
1794  if (ec_read_mbox_locked(slave)) {
1795  // await current read request and mark the datagram as invalid
1796  datagram->state = EC_DATAGRAM_INVALID;
1797  } else {
1798  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1800  }
1801  return;
1802  }
1803 
1804  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
1805 
1806  if (IS_ERR(data)) {
1807  request->errno = PTR_ERR(data);
1808  fsm->state = ec_fsm_coe_error;
1809  return;
1810  }
1811 
1812  if (mbox_prot != EC_MBOX_TYPE_COE) {
1813  request->errno = EIO;
1814  fsm->state = ec_fsm_coe_error;
1815  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
1816  mbox_prot);
1817  return;
1818  }
1819 
1820  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
1821  // check for CoE response again
1822  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1823  fsm->retries = EC_FSM_RETRIES;
1825  return;
1826  }
1827 
1828  if (slave->master->debug_level) {
1829  EC_SLAVE_DBG(slave, 1, "Download response:\n");
1830  ec_print_data(data, rec_size);
1831  }
1832 
1833  if (rec_size < 6) {
1834  request->errno = EIO;
1835  fsm->state = ec_fsm_coe_error;
1836  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
1837  rec_size);
1838  ec_print_data(data, rec_size);
1839  return;
1840  }
1841 
1842  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
1843  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
1844  char subidxstr[10];
1845  request->errno = EIO;
1846  fsm->state = ec_fsm_coe_error;
1847  if (request->complete_access) {
1848  subidxstr[0] = 0x00;
1849  } else {
1850  sprintf(subidxstr, ":%02X", request->subindex);
1851  }
1852  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
1853  request->index, subidxstr, request->data_size);
1854  if (rec_size < 10) {
1855  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
1856  ec_print_data(data, rec_size);
1857  } else {
1858  fsm->request->abort_code = EC_READ_U32(data + 6);
1859  ec_canopen_abort_msg(slave, fsm->request->abort_code);
1860  }
1861  return;
1862  }
1863 
1864  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
1865  EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
1866  EC_READ_U16(data + 3) != request->index || // index
1867  EC_READ_U8 (data + 5) != request->subindex) { // subindex
1868  if (slave->master->debug_level) {
1869  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
1870  " Retrying...\n");
1871  ec_print_data(data, rec_size);
1872  }
1873  // check for CoE response again
1874  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1875  fsm->retries = EC_FSM_RETRIES;
1877  return;
1878  }
1879 
1880  if (fsm->remaining) { // more segments to download
1881  fsm->toggle = 0;
1883  } else {
1884  fsm->state = ec_fsm_coe_end; // success
1885  }
1886 }
1887 
1888 /*****************************************************************************/
1889 
1895  ec_fsm_coe_t *fsm,
1896  ec_datagram_t *datagram
1897  )
1898 {
1899  ec_slave_t *slave = fsm->slave;
1900 
1901  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1902  return;
1903 
1904  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1905  fsm->request->errno = EIO;
1906  fsm->state = ec_fsm_coe_error;
1907  ec_read_mbox_lock_clear(slave);
1908  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
1910  return;
1911  }
1912 
1913  if (fsm->datagram->working_counter != 1) {
1914  fsm->request->errno = EIO;
1915  fsm->state = ec_fsm_coe_error;
1916  ec_read_mbox_lock_clear(slave);
1917  EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
1918  " datagram failed: ");
1920  return;
1921  }
1922 
1923  if (!ec_slave_mbox_check(fsm->datagram)) {
1924  unsigned long diff_ms = 0;
1925 
1926  // check that data is not already received by another read request
1927  if (slave->mbox_coe_data.payload_size > 0) {
1928  ec_read_mbox_lock_clear(slave);
1930  fsm->state(fsm, datagram);
1931  return;
1932  }
1933 
1934  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
1935  1000 / HZ;
1936 
1937  if (diff_ms >= fsm->request->response_timeout) {
1938  fsm->request->errno = EIO;
1939  fsm->state = ec_fsm_coe_error;
1940  ec_read_mbox_lock_clear(slave);
1941  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
1942  " segment response.\n");
1943  return;
1944  }
1945 
1946  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
1947  fsm->retries = EC_FSM_RETRIES;
1948  return;
1949  }
1950 
1951  // Fetch response
1952  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1953  fsm->retries = EC_FSM_RETRIES;
1955 }
1956 
1957 /*****************************************************************************/
1958 
1965  ec_fsm_coe_t *fsm,
1966  ec_datagram_t *datagram
1967  )
1968 {
1969  ec_slave_t *slave = fsm->slave;
1970  ec_sdo_request_t *request = fsm->request;
1971 
1972  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1973  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
1974  return;
1975  }
1976 
1977  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
1978  request->errno = EIO;
1979  fsm->state = ec_fsm_coe_error;
1980  ec_read_mbox_lock_clear(slave);
1981  EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
1982  " datagram: ");
1984  return;
1985  }
1986 
1987  if (fsm->datagram->working_counter != 1) {
1988  // only an error if data has not already been read by another read request
1989  if (slave->mbox_coe_data.payload_size == 0) {
1990  request->errno = EIO;
1991  fsm->state = ec_fsm_coe_error;
1992  ec_read_mbox_lock_clear(slave);
1993  EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
1995  return;
1996  }
1997  }
1998  ec_read_mbox_lock_clear(slave);
2000  fsm->state(fsm, datagram);
2001 }
2002 
2003 /*****************************************************************************/
2004 
2011  ec_fsm_coe_t *fsm,
2012  ec_datagram_t *datagram
2013  )
2014 {
2015  ec_slave_t *slave = fsm->slave;
2016  uint8_t *data, mbox_prot;
2017  size_t rec_size;
2018  ec_sdo_request_t *request = fsm->request;
2019 
2020  // process the data available or initiate a new mailbox read check
2021  if (slave->mbox_coe_data.payload_size > 0) {
2022  slave->mbox_coe_data.payload_size = 0;
2023  } else {
2024  // initiate a new mailbox read check if required data is not available
2025  if (ec_read_mbox_locked(slave)) {
2026  // await current read request and mark the datagram as invalid
2027  datagram->state = EC_DATAGRAM_INVALID;
2028  } else {
2029  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2031  }
2032  return;
2033  }
2034 
2035  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
2036  if (IS_ERR(data)) {
2037  request->errno = PTR_ERR(data);
2038  fsm->state = ec_fsm_coe_error;
2039  return;
2040  }
2041 
2042  if (mbox_prot != EC_MBOX_TYPE_COE) {
2043  request->errno = EIO;
2044  fsm->state = ec_fsm_coe_error;
2045  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
2046  mbox_prot);
2047  return;
2048  }
2049 
2050  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2051  // check for CoE response again
2052  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2053  fsm->retries = EC_FSM_RETRIES;
2055  return;
2056  }
2057 
2058  if (slave->master->debug_level) {
2059  EC_SLAVE_DBG(slave, 1, "Download response:\n");
2060  ec_print_data(data, rec_size);
2061  }
2062 
2063  if (rec_size < 6) {
2064  request->errno = EIO;
2065  fsm->state = ec_fsm_coe_error;
2066  EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
2067  rec_size);
2068  ec_print_data(data, rec_size);
2069  return;
2070  }
2071 
2072  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2073  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
2074  char subidxstr[10];
2075  request->errno = EIO;
2076  fsm->state = ec_fsm_coe_error;
2077  if (request->complete_access) {
2078  subidxstr[0] = 0x00;
2079  } else {
2080  sprintf(subidxstr, ":%02X", request->subindex);
2081  }
2082  EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
2083  request->index, subidxstr, request->data_size);
2084  if (rec_size < 10) {
2085  EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
2086  ec_print_data(data, rec_size);
2087  } else {
2088  fsm->request->abort_code = EC_READ_U32(data + 6);
2089  ec_canopen_abort_msg(slave, fsm->request->abort_code);
2090  }
2091  return;
2092  }
2093 
2094  if (EC_READ_U16(data) >> 12 != 0x3 ||
2095  ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response
2096  if (slave->master->debug_level) {
2097  EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
2098  " Retrying...\n");
2099  ec_print_data(data, rec_size);
2100  }
2101  // check for CoE response again
2102  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2103  fsm->retries = EC_FSM_RETRIES;
2105  return;
2106  }
2107 
2108  if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) {
2109  EC_SLAVE_ERR(slave, "Invalid toggle received during"
2110  " segmented download:\n");
2111  ec_print_data(data, rec_size);
2112  request->errno = EIO;
2113  fsm->state = ec_fsm_coe_error;
2114  return;
2115  }
2116 
2117  fsm->offset += fsm->segment_size;
2118  fsm->remaining -= fsm->segment_size;
2119 
2120  if (fsm->remaining) { // more segments to download
2121  fsm->toggle = !fsm->toggle;
2123  } else {
2124  fsm->state = ec_fsm_coe_end; // success
2125  }
2126 }
2127 
2128 /*****************************************************************************/
2129 
2135  ec_fsm_coe_t *fsm,
2136  ec_datagram_t *datagram
2137  )
2138 {
2139  ec_slave_t *slave = fsm->slave;
2140  ec_sdo_request_t *request = fsm->request;
2141  ec_master_t *master = slave->master;
2142 
2143  u8 *data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_COE,
2144  10);
2145  if (IS_ERR(data)) {
2146  request->errno = PTR_ERR(data);
2147  return PTR_ERR(data);
2148  }
2149 
2150  EC_WRITE_U16(data, 0x2 << 12); // SDO request
2151  EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
2152  EC_WRITE_U16(data + 3, request->index);
2153  EC_WRITE_U8 (data + 5, request->subindex);
2154  memset(data + 6, 0x00, 4);
2155 
2156  if (master->debug_level) {
2157  EC_SLAVE_DBG(slave, 1, "Upload request:\n");
2158  ec_print_data(data, 10);
2159  }
2160 
2162  return 0;
2163 }
2164 
2165 /*****************************************************************************/
2166 
2172  ec_fsm_coe_t *fsm,
2173  ec_datagram_t *datagram
2174  )
2175 {
2176  ec_slave_t *slave = fsm->slave;
2177  ec_sdo_request_t *request = fsm->request;
2178 
2179  EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n",
2180  request->index, request->subindex);
2181 
2182  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
2183  EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
2184  request->errno = EPROTONOSUPPORT;
2185  fsm->state = ec_fsm_coe_error;
2186  return;
2187  }
2188 
2189  fsm->retries = EC_FSM_RETRIES;
2190  fsm->request->jiffies_sent = jiffies;
2191 
2192  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
2193  fsm->state = ec_fsm_coe_error;
2194  }
2195 }
2196 
2197 /*****************************************************************************/
2204  ec_fsm_coe_t *fsm,
2205  ec_datagram_t *datagram
2206  )
2207 {
2208  ec_slave_t *slave = fsm->slave;
2209  unsigned long diff_ms;
2210 
2211  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2212  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
2213  fsm->state = ec_fsm_coe_error;
2214  }
2215  return;
2216  }
2217 
2218  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2219  fsm->request->errno = EIO;
2220  fsm->state = ec_fsm_coe_error;
2221  EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
2223  return;
2224  }
2225 
2226  diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
2227 
2228  if (fsm->datagram->working_counter != 1) {
2229  if (!fsm->datagram->working_counter) {
2230  if (diff_ms < fsm->request->response_timeout) {
2231 #if DEBUG_RETRIES
2232  EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
2233  " SDO upload request. Retrying after %lu ms...\n",
2234  diff_ms);
2235 #endif
2236  // no response; send request datagram again
2237  if (ec_fsm_coe_prepare_up(fsm, datagram)) {
2238  fsm->state = ec_fsm_coe_error;
2239  }
2240  return;
2241  }
2242  }
2243  fsm->request->errno = EIO;
2244  fsm->state = ec_fsm_coe_error;
2245  EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
2246  " SDO 0x%04x:%x failed with timeout after %lu ms: ",
2247  fsm->request->index, fsm->request->subindex, diff_ms);
2249  return;
2250  }
2251 
2252 #if DEBUG_LONG
2253  if (diff_ms > 200) {
2254  EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %lu ms.\n",
2255  fsm->request->index, fsm->request->subindex, diff_ms);
2256  }
2257 #endif
2258 
2259  fsm->jiffies_start = fsm->datagram->jiffies_sent;
2260  // mailbox read check is skipped if a read request is already ongoing
2261  if (ec_read_mbox_locked(slave)) {
2263  // the datagram is not used and marked as invalid
2264  datagram->state = EC_DATAGRAM_INVALID;
2265  } else {
2266  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2267  fsm->retries = EC_FSM_RETRIES;
2268  fsm->state = ec_fsm_coe_up_check;
2269  }
2270 }
2271 
2272 /*****************************************************************************/
2273 
2279  ec_fsm_coe_t *fsm,
2280  ec_datagram_t *datagram
2281  )
2282 {
2283  ec_slave_t *slave = fsm->slave;
2284 
2285  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2286  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2287  return;
2288  }
2289 
2290  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2291  fsm->request->errno = EIO;
2292  fsm->state = ec_fsm_coe_error;
2293  ec_read_mbox_lock_clear(slave);
2294  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
2296  return;
2297  }
2298 
2299  if (fsm->datagram->working_counter != 1) {
2300  fsm->request->errno = EIO;
2301  fsm->state = ec_fsm_coe_error;
2302  ec_read_mbox_lock_clear(slave);
2303  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
2304  " datagram failed: ");
2306  return;
2307  }
2308 
2309  if (!ec_slave_mbox_check(fsm->datagram)) {
2310  unsigned long diff_ms = 0;
2311 
2312  // check that data is not already received by another read request
2313  if (slave->mbox_coe_data.payload_size > 0) {
2314  ec_read_mbox_lock_clear(slave);
2316  fsm->state(fsm, datagram);
2317  return;
2318  }
2319 
2320  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2321  1000 / HZ;
2322 
2323  if (diff_ms >= fsm->request->response_timeout) {
2324  fsm->request->errno = EIO;
2325  fsm->state = ec_fsm_coe_error;
2326  ec_read_mbox_lock_clear(slave);
2327  EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
2328  " SDO 0x%04x:%x upload response.\n", diff_ms,
2329  fsm->request->index, fsm->request->subindex);
2330  return;
2331  }
2332 
2333  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2334  fsm->retries = EC_FSM_RETRIES;
2335  return;
2336  }
2337 
2338  // Fetch response
2339  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2340  fsm->retries = EC_FSM_RETRIES;
2342 }
2343 
2344 /*****************************************************************************/
2345 
2349  ec_fsm_coe_t *fsm,
2350  ec_datagram_t *datagram
2351  )
2352 {
2353  uint8_t *data =
2354  ec_slave_mbox_prepare_send(fsm->slave, datagram, EC_MBOX_TYPE_COE,
2355  10);
2356  if (IS_ERR(data)) {
2357  fsm->request->errno = PTR_ERR(data);
2358  fsm->state = ec_fsm_coe_error;
2359  return;
2360  }
2361 
2362  EC_WRITE_U16(data, 0x2 << 12); // SDO request
2363  EC_WRITE_U8 (data + 2, (fsm->toggle << 4 // toggle
2364  | 0x3 << 5)); // upload segment request
2365  memset(data + 3, 0x00, 7);
2366 
2367  if (fsm->slave->master->debug_level) {
2368  EC_SLAVE_DBG(fsm->slave, 1, "Upload segment request:\n");
2369  ec_print_data(data, 10);
2370  }
2371 }
2372 
2373 /*****************************************************************************/
2374 
2381  ec_fsm_coe_t *fsm,
2382  ec_datagram_t *datagram
2383  )
2384 {
2385  ec_slave_t *slave = fsm->slave;
2386  ec_sdo_request_t *request = fsm->request;
2387 
2388  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2389  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2390  return;
2391  }
2392 
2393  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2394  request->errno = EIO;
2395  fsm->state = ec_fsm_coe_error;
2396  ec_read_mbox_lock_clear(slave);
2397  EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
2398  " datagram: ");
2400  return;
2401  }
2402 
2403  if (fsm->datagram->working_counter != 1) {
2404  // only an error if data has not already been read by another read request
2405  if (slave->mbox_coe_data.payload_size == 0) {
2406  request->errno = EIO;
2407  fsm->state = ec_fsm_coe_error;
2408  ec_read_mbox_lock_clear(slave);
2409  EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
2411  return;
2412  }
2413  }
2414  ec_read_mbox_lock_clear(slave);
2416  fsm->state(fsm, datagram);
2417 }
2418 
2419 
2420 /*****************************************************************************/
2421 
2428  ec_fsm_coe_t *fsm,
2429  ec_datagram_t *datagram
2430  )
2431 {
2432  ec_slave_t *slave = fsm->slave;
2433  ec_master_t *master = slave->master;
2434  uint16_t rec_index;
2435  uint8_t *data, mbox_prot, rec_subindex;
2436  size_t rec_size, data_size;
2437  ec_sdo_request_t *request = fsm->request;
2438  unsigned int expedited, size_specified;
2439  int ret;
2440 
2441  // process the data available or initiate a new mailbox read check
2442  if (slave->mbox_coe_data.payload_size > 0) {
2443  slave->mbox_coe_data.payload_size = 0;
2444  } else {
2445  // initiate a new mailbox read check if required data is not available
2446  if (ec_read_mbox_locked(slave)) {
2447  // await current read request and mark the datagram as invalid
2448  datagram->state = EC_DATAGRAM_INVALID;
2449  } else {
2450  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2451  fsm->state = ec_fsm_coe_up_check;
2452  }
2453  return;
2454  }
2455 
2456  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
2457 
2458  if (IS_ERR(data)) {
2459  request->errno = PTR_ERR(data);
2460  fsm->state = ec_fsm_coe_error;
2461  return;
2462  }
2463 
2464  if (master->debug_level) {
2465  EC_SLAVE_DBG(slave, 1, "Upload response:\n");
2466  ec_print_data(data, rec_size);
2467  }
2468 
2469  if (mbox_prot != EC_MBOX_TYPE_COE) {
2470  request->errno = EIO;
2471  fsm->state = ec_fsm_coe_error;
2472  EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
2473  " as response.\n", mbox_prot);
2474  return;
2475  }
2476 
2477  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2478  // check for CoE response again
2479  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2480  fsm->retries = EC_FSM_RETRIES;
2481  fsm->state = ec_fsm_coe_up_check;
2482  return;
2483  }
2484 
2485  if (rec_size < 6) {
2486  request->errno = EIO;
2487  fsm->state = ec_fsm_coe_error;
2488  EC_SLAVE_ERR(slave, "Received currupted SDO upload response"
2489  " (%zu bytes)!\n", rec_size);
2490  ec_print_data(data, rec_size);
2491  return;
2492  }
2493 
2494  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2495  EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request
2496  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2497  request->index, request->subindex);
2498  if (rec_size >= 10) {
2499  request->abort_code = EC_READ_U32(data + 6);
2500  ec_canopen_abort_msg(slave, request->abort_code);
2501  } else {
2502  EC_SLAVE_ERR(slave, "No abort message.\n");
2503  }
2504  request->errno = EIO;
2505  fsm->state = ec_fsm_coe_error;
2506  return;
2507  }
2508 
2509  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2510  EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response
2511  EC_SLAVE_ERR(slave, "Received unknown response while"
2512  " uploading SDO 0x%04X:%02X.\n",
2513  request->index, request->subindex);
2514  ec_print_data(data, rec_size);
2515  request->errno = EIO;
2516  fsm->state = ec_fsm_coe_error;
2517  return;
2518  }
2519 
2520  rec_index = EC_READ_U16(data + 3);
2521  rec_subindex = EC_READ_U8(data + 5);
2522 
2523  if (rec_index != request->index || rec_subindex != request->subindex) {
2524  EC_SLAVE_ERR(slave, "Received upload response for wrong SDO"
2525  " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
2526  rec_index, rec_subindex, request->index, request->subindex);
2527  ec_print_data(data, rec_size);
2528 
2529  // check for CoE response again
2530  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2531  fsm->retries = EC_FSM_RETRIES;
2532  fsm->state = ec_fsm_coe_up_check;
2533  return;
2534  }
2535 
2536  // normal or expedited?
2537  expedited = EC_READ_U8(data + 2) & 0x02;
2538 
2539  if (expedited) {
2540  size_specified = EC_READ_U8(data + 2) & 0x01;
2541  if (size_specified) {
2542  fsm->complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
2543  } else {
2544  fsm->complete_size = 4;
2545  }
2546 
2547  if (rec_size < 6 + fsm->complete_size) {
2548  request->errno = EIO;
2549  fsm->state = ec_fsm_coe_error;
2550  EC_SLAVE_ERR(slave, "Received corrupted SDO expedited upload"
2551  " response (only %zu bytes)!\n", rec_size);
2552  ec_print_data(data, rec_size);
2553  return;
2554  }
2555 
2556  ret = ec_sdo_request_copy_data(request, data + 6, fsm->complete_size);
2557  if (ret) {
2558  request->errno = -ret;
2559  fsm->state = ec_fsm_coe_error;
2560  return;
2561  }
2562  } else { // normal
2563  if (rec_size < 10) {
2564  request->errno = EIO;
2565  fsm->state = ec_fsm_coe_error;
2566  EC_SLAVE_ERR(slave, "Received currupted SDO normal upload"
2567  " response (only %zu bytes)!\n", rec_size);
2568  ec_print_data(data, rec_size);
2569  return;
2570  }
2571 
2572  data_size = rec_size - 10;
2573  fsm->complete_size = EC_READ_U32(data + 6);
2574 
2575  ret = ec_sdo_request_alloc(request, fsm->complete_size);
2576  if (ret) {
2577  request->errno = -ret;
2578  fsm->state = ec_fsm_coe_error;
2579  return;
2580  }
2581 
2582  ret = ec_sdo_request_copy_data(request, data + 10, data_size);
2583  if (ret) {
2584  request->errno = -ret;
2585  fsm->state = ec_fsm_coe_error;
2586  return;
2587  }
2588 
2589  fsm->toggle = 0;
2590 
2591  if (data_size < fsm->complete_size) {
2592  EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
2593  " Segmenting...\n", data_size, fsm->complete_size);
2595  fsm->retries = EC_FSM_RETRIES;
2597  return;
2598  }
2599  }
2600 
2601  if (master->debug_level) {
2602  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2603  ec_print_data(request->data, request->data_size);
2604  }
2605 
2606  fsm->state = ec_fsm_coe_end; // success
2607 }
2608 
2609 /*****************************************************************************/
2610 
2617  ec_fsm_coe_t *fsm,
2618  ec_datagram_t *datagram
2619  )
2620 {
2621  ec_slave_t *slave = fsm->slave;
2622 
2623  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2625  return;
2626  }
2627 
2628  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2629  fsm->request->errno = EIO;
2630  fsm->state = ec_fsm_coe_error;
2631  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2632  " request datagram: ");
2634  return;
2635  }
2636 
2637  if (fsm->datagram->working_counter != 1) {
2638  fsm->request->errno = EIO;
2639  fsm->state = ec_fsm_coe_error;
2640  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2641  " request failed: ");
2643  return;
2644  }
2645 
2646  fsm->jiffies_start = fsm->datagram->jiffies_sent;
2647  // mailbox read check is skipped if a read request is already ongoing
2648  if (ec_read_mbox_locked(slave)) {
2650  // the datagram is not used and marked as invalid
2651  datagram->state = EC_DATAGRAM_INVALID;
2652  } else {
2653  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2654  fsm->retries = EC_FSM_RETRIES;
2656  }
2657 }
2658 
2659 /*****************************************************************************/
2660 
2666  ec_fsm_coe_t *fsm,
2667  ec_datagram_t *datagram
2668  )
2669 {
2670  ec_slave_t *slave = fsm->slave;
2671 
2672  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2673  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2674  return;
2675  }
2676 
2677  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2678  fsm->request->errno = EIO;
2679  fsm->state = ec_fsm_coe_error;
2680  ec_read_mbox_lock_clear(slave);
2681  EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
2682  " datagram: ");
2684  return;
2685  }
2686 
2687  if (fsm->datagram->working_counter != 1) {
2688  fsm->request->errno = EIO;
2689  fsm->state = ec_fsm_coe_error;
2690  ec_read_mbox_lock_clear(slave);
2691  EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
2692  " failed: ");
2694  return;
2695  }
2696 
2697  if (!ec_slave_mbox_check(fsm->datagram)) {
2698  unsigned long diff_ms = 0;
2699 
2700  // check that data is not already received by another read request
2701  if (slave->mbox_coe_data.payload_size > 0) {
2702  ec_read_mbox_lock_clear(slave);
2704  fsm->state(fsm, datagram);
2705  return;
2706  }
2707 
2708  diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) *
2709  1000 / HZ;
2710 
2711  if (diff_ms >= fsm->request->response_timeout) {
2712  fsm->request->errno = EIO;
2713  fsm->state = ec_fsm_coe_error;
2714  ec_read_mbox_lock_clear(slave);
2715  EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
2716  " segment response.\n");
2717  return;
2718  }
2719 
2720  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2721  fsm->retries = EC_FSM_RETRIES;
2722  return;
2723  }
2724 
2725  // Fetch response
2726  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2727  fsm->retries = EC_FSM_RETRIES;
2729 }
2730 
2731 /*****************************************************************************/
2732 
2739  ec_fsm_coe_t *fsm,
2740  ec_datagram_t *datagram
2741  )
2742 {
2743  ec_slave_t *slave = fsm->slave;
2744  ec_sdo_request_t *request = fsm->request;
2745 
2746  if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
2747  ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
2748  return;
2749  }
2750 
2751  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
2752  request->errno = EIO;
2753  fsm->state = ec_fsm_coe_error;
2754  ec_read_mbox_lock_clear(slave);
2755  EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
2756  " response datagram: ");
2758  return;
2759  }
2760 
2761  if (fsm->datagram->working_counter != 1) {
2762  // only an error if data has not already been read by another read request
2763  if (slave->mbox_coe_data.payload_size == 0) {
2764  request->errno = EIO;
2765  fsm->state = ec_fsm_coe_error;
2766  ec_read_mbox_lock_clear(slave);
2767  EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
2768  " response failed: ");
2770  return;
2771  }
2772  }
2773  ec_read_mbox_lock_clear(slave);
2775  fsm->state(fsm, datagram);
2776 }
2777 
2778 
2779 /*****************************************************************************/
2780 
2787  ec_fsm_coe_t *fsm,
2788  ec_datagram_t *datagram
2789  )
2790 {
2791  ec_slave_t *slave = fsm->slave;
2792  ec_master_t *master = slave->master;
2793  uint8_t *data, mbox_prot;
2794  size_t rec_size, data_size;
2795  ec_sdo_request_t *request = fsm->request;
2796  unsigned int last_segment;
2797 
2798  // process the data available or initiate a new mailbox read check
2799  if (slave->mbox_coe_data.payload_size > 0) {
2800  slave->mbox_coe_data.payload_size = 0;
2801  } else {
2802  // initiate a new mailbox read check if required data is not available
2803  if (ec_read_mbox_locked(slave)) {
2804  // await current read request and mark the datagram as invalid
2805  datagram->state = EC_DATAGRAM_INVALID;
2806  } else {
2807  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2809  }
2810  return;
2811  }
2812 
2813  data = ec_slave_mbox_fetch(slave, &slave->mbox_coe_data, &mbox_prot, &rec_size);
2814 
2815  if (IS_ERR(data)) {
2816  request->errno = PTR_ERR(data);
2817  fsm->state = ec_fsm_coe_error;
2818  return;
2819  }
2820 
2821  if (master->debug_level) {
2822  EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
2823  ec_print_data(data, rec_size);
2824  }
2825 
2826  if (mbox_prot != EC_MBOX_TYPE_COE) {
2827  EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
2828  mbox_prot);
2829  request->errno = EIO;
2830  fsm->state = ec_fsm_coe_error;
2831  return;
2832  }
2833 
2834  if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
2835  // check for CoE response again
2836  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2837  fsm->retries = EC_FSM_RETRIES;
2839  return;
2840  }
2841 
2842  if (rec_size < 10) {
2843  EC_SLAVE_ERR(slave, "Received currupted SDO upload"
2844  " segment response!\n");
2845  ec_print_data(data, rec_size);
2846  request->errno = EIO;
2847  fsm->state = ec_fsm_coe_error;
2848  return;
2849  }
2850 
2851  if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
2852  EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
2853  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
2854  request->index, request->subindex);
2855  request->abort_code = EC_READ_U32(data + 6);
2856  ec_canopen_abort_msg(slave, request->abort_code);
2857  request->errno = EIO;
2858  fsm->state = ec_fsm_coe_error;
2859  return;
2860  }
2861 
2862  if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
2863  EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
2864  if (fsm->slave->master->debug_level) {
2865  EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
2866  ec_print_data(data, rec_size);
2867  }
2868  // check for CoE response again
2869  ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
2870  fsm->retries = EC_FSM_RETRIES;
2872  return;
2873  }
2874 
2875  data_size = rec_size - 3; /* Header of segment upload is smaller than
2876  normal upload */
2877  if (rec_size == 10) {
2878  uint8_t seg_size = (EC_READ_U8(data + 2) & 0xE) >> 1;
2879  data_size -= seg_size;
2880  }
2881 
2882  if (request->data_size + data_size > fsm->complete_size) {
2883  EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X failed: Fragment"
2884  " exceeding complete size!\n",
2885  request->index, request->subindex);
2886  request->errno = EOVERFLOW;
2887  fsm->state = ec_fsm_coe_error;
2888  return;
2889  }
2890 
2891  memcpy(request->data + request->data_size, data + 3, data_size);
2892  request->data_size += data_size;
2893 
2894  last_segment = EC_READ_U8(data + 2) & 0x01;
2895  if (!last_segment) {
2896  fsm->toggle = !fsm->toggle;
2898  fsm->retries = EC_FSM_RETRIES;
2900  return;
2901  }
2902 
2903  if (request->data_size != fsm->complete_size) {
2904  EC_SLAVE_WARN(slave, "SDO upload 0x%04X:%02X: Assembled data"
2905  " size (%zu) does not match complete size (%u)!\n",
2906  request->index, request->subindex,
2907  request->data_size, fsm->complete_size);
2908  }
2909 
2910  if (master->debug_level) {
2911  EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
2912  ec_print_data(request->data, request->data_size);
2913  }
2914 
2915  fsm->state = ec_fsm_coe_end; // success
2916 }
2917 
2918 /*****************************************************************************/
2919 
2925  ec_fsm_coe_t *fsm,
2926  ec_datagram_t *datagram
2927  )
2928 {
2929 }
2930 
2931 /*****************************************************************************/
2932 
2938  ec_fsm_coe_t *fsm,
2939  ec_datagram_t *datagram
2940  )
2941 {
2942 }
2943 
2944 /*****************************************************************************/
int ec_fsm_coe_prepare_down_start(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare a donwnload request.
Definition: fsm_coe.c:1376
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
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
void ec_fsm_coe_up_seg_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE DATA.
Definition: fsm_coe.c:2786
ec_sii_t sii
Extracted SII data.
Definition: slave.h:246
void ec_fsm_coe_down_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN REQUEST.
Definition: fsm_coe.c:1522
int ec_fsm_coe_prepare_up(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare an upload request.
Definition: fsm_coe.c:2134
uint32_t offset
Data offset during segmented download.
Definition: fsm_coe.h:64
void ec_fsm_coe_down_seg_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN SEG CHECK.
Definition: fsm_coe.c:1894
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:107
CANopen SDO entry.
Definition: sdo_entry.h:54
void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:2616
size_t segment_size
Current segment size.
Definition: fsm_coe.h:66
CANopen SDO request.
Definition: sdo_request.h:48
uint16_t bit_length
Data size in bit.
Definition: sdo_entry.h:59
uint32_t response_timeout
Maximum time in ms, the transfer is retried, if the slave does not respond.
Definition: sdo_request.h:58
int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram to fetch mailbox data.
Definition: mailbox.c:128
uint32_t code
Code.
Definition: globals.h:282
#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_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT RESPONSE.
Definition: fsm_coe.c:523
EtherCAT datagram.
Definition: datagram.h:88
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:183
uint16_t index
SDO index.
Definition: sdo_request.h:50
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2338
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:1668
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:166
void ec_fsm_coe_dict_desc_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC REQUEST.
Definition: fsm_coe.c:717
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_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN RESPONSE.
Definition: fsm_coe.c:1734
#define EC_COE_DOWN_SEG_MIN_DATA_SIZE
Minimum size of download segment.
Definition: fsm_coe.c:58
CANopen SDO.
Definition: sdo.h:49
uint16_t index
SDO index.
Definition: sdo.h:52
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:52
int ec_fsm_coe_success(const ec_fsm_coe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_coe.c:268
#define EC_FSM_COE_DICT_TIMEOUT
Maximum time in ms to wait for responses when reading out the dictionary.
Definition: fsm_coe.c:46
Sent (still in the queue).
Definition: datagram.h:77
#define EC_COE_DOWN_SEG_REQ_HEADER_SIZE
CoE download segment request header size.
Definition: fsm_coe.c:54
int ec_fsm_coe_check_emergency(ec_fsm_coe_t *fsm, const uint8_t *data, size_t size)
Check if the received data are a CoE emergency request.
Definition: fsm_coe.c:283
struct list_head list
List item.
Definition: sdo_entry.h:55
void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY CHECK.
Definition: fsm_coe.c:1089
const char * message
Message belonging to code.
Definition: globals.h:283
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:911
void ec_fsm_coe_up_seg_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP CHECK.
Definition: fsm_coe.c:2665
struct list_head sdo_dictionary
SDO dictionary list.
Definition: slave.h:248
void ec_fsm_coe_dict_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT START.
Definition: fsm_coe.c:347
Global definitions and macros.
ec_direction_t dir
Direction.
Definition: sdo_request.h:60
EtherCAT master structure.
uint8_t object_code
Object code.
Definition: sdo.h:53
ec_sdo_t * sdo
current SDO
Definition: fsm_coe.h:59
Initial state of a new datagram.
Definition: datagram.h:75
EtherCAT CoE state machines.
EtherCAT slave.
Definition: slave.h:199
void ec_fsm_coe_dict_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT REQUEST.
Definition: fsm_coe.c:379
int ec_sdo_request_copy_data(ec_sdo_request_t *req, const uint8_t *source, size_t size)
Copies SDO data from an external source.
Definition: sdo_request.c:156
char * description
Description.
Definition: sdo_entry.h:62
Code/Message pair.
Definition: globals.h:281
void ec_fsm_coe_down_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN RESPONSE DATA.
Definition: fsm_coe.c:1779
ec_datagram_state_t state
State.
Definition: datagram.h:101
CANopen over EtherCAT.
Definition: globals.h:152
ec_slave_config_t * config
Current configuration.
Definition: slave.h:213
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2372
void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY RESPONSE.
Definition: fsm_coe.c:1159
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:2348
uint8_t enable_sdo_info
SDO information service available.
Definition: globals.h:162
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:170
ec_sdo_request_t * request
SDO request.
Definition: fsm_coe.h:61
Access rights in OP.
Definition: globals.h:198
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:494
void ec_fsm_coe_down_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN START.
Definition: fsm_coe.c:1471
unsigned int debug_level
Master debug level.
Definition: master.h:285
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:77
void ec_fsm_coe_up_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE DATA.
Definition: fsm_coe.c:2427
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
Definition: datagram.c:606
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
Definition: sdo_request.h:65
uint8_t subindex
current subindex
Definition: fsm_coe.h:60
char * name
SDO name.
Definition: sdo.h:54
void ec_fsm_coe_clear(ec_fsm_coe_t *fsm)
Destructor.
Definition: fsm_coe.c:189
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2355
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:2266
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:836
ec_master_t * master
Master owning the slave.
Definition: slave.h:201
int errno
Error number.
Definition: sdo_request.h:67
unsigned long jiffies_start
CoE timestamp.
Definition: fsm_coe.h:58
void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC RESPONSE.
Definition: fsm_coe.c:867
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_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:203
Access rights in SAFEOP.
Definition: globals.h:197
uint16_t data_type
Data type.
Definition: sdo_entry.h:58
void ec_fsm_coe_up_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP REQUEST.
Definition: fsm_coe.c:2203
void ec_fsm_coe_down_seg_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN SEG RESPONSE.
Definition: fsm_coe.c:1964
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:89
void ec_sdo_init(ec_sdo_t *sdo, ec_slave_t *slave, uint16_t index)
Constructor.
Definition: sdo.c:47
void ec_fsm_coe_up_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2380
void ec_fsm_coe_dict_entry_request(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT ENTRY REQUEST.
Definition: fsm_coe.c:1040
void ec_fsm_coe_error(ec_fsm_coe_t *, ec_datagram_t *)
State: ERROR.
Definition: fsm_coe.c:2924
int ec_fsm_coe_prepare_dict(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Prepare a dictionary request.
Definition: fsm_coe.c:321
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:345
void ec_read_mbox_lock_clear(ec_slave_t *slave)
Clears the mailbox lock.
Definition: slave.c:190
uint8_t read_access[EC_SDO_ENTRY_ACCESS_COUNT]
Read access.
Definition: sdo_entry.h:60
void ec_fsm_coe_dict_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT CHECK.
Definition: fsm_coe.c:426
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:97
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2250
ec_coe_emerg_ring_t emerg_ring
CoE emergency ring buffer.
Definition: slave_config.h:153
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:566
Mailbox functionality.
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:1203
void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP RESPONSE.
Definition: fsm_coe.c:2738
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
Queued for sending.
Definition: datagram.h:76
Timed out (dequeued).
Definition: datagram.h:79
uint8_t max_subindex
Maximum subindex.
Definition: sdo.h:55
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
Definition: slave.h:220
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:2234
EtherCAT slave configuration.
Definition: slave_config.h:119
void ec_fsm_coe_dict_desc_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT DESC CHECK.
Definition: fsm_coe.c:767
#define EC_COE_DOWN_REQ_HEADER_SIZE
CoE download request header size.
Definition: fsm_coe.c:50
unsigned int retries
retries upon datagram timeout
Definition: fsm_coe.h:54
EtherCAT slave configuration structure.
uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]
Write access.
Definition: sdo_entry.h:61
void ec_fsm_coe_down_seg_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN SEG RESPONSE DATA.
Definition: fsm_coe.c:2010
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:437
Received (dequeued).
Definition: datagram.h:78
Access rights in PREOP.
Definition: globals.h:196
EtherCAT master.
Definition: master.h:189
void ec_fsm_coe_end(ec_fsm_coe_t *, ec_datagram_t *)
State: END.
Definition: fsm_coe.c:2937
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:268
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:116
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_dict_response_data(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DICT RESPONSE DATA.
Definition: fsm_coe.c:567
unsigned int has_general
General category present.
Definition: slave.h:177
void ec_fsm_coe_down_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: DOWN CHECK.
Definition: fsm_coe.c:1597
Finite state machines for the CANopen over EtherCAT protocol.
Definition: fsm_coe.h:52
void ec_fsm_coe_up_start(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP START.
Definition: fsm_coe.c:2171
void ec_fsm_coe_up_check(ec_fsm_coe_t *, ec_datagram_t *)
CoE state: UP CHECK.
Definition: fsm_coe.c:2278