IgH EtherCAT Master  1.6.0-rc1
fsm_master.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * $Id$
4  *
5  * Copyright (C) 2006-2012 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 "slave_config.h"
40 #ifdef EC_EOE
41 #include "ethernet.h"
42 #endif
43 
44 #include "fsm_master.h"
45 #include "fsm_foe.h"
46 
47 /*****************************************************************************/
48 
51 #define EC_SYSTEM_TIME_TOLERANCE_NS 1000
52 
53 /*****************************************************************************/
54 
58 #ifdef EC_LOOP_CONTROL
59 void ec_fsm_master_state_read_dl_status(ec_fsm_master_t *);
60 void ec_fsm_master_state_open_port(ec_fsm_master_t *);
61 #endif
65 #ifdef EC_LOOP_CONTROL
66 void ec_fsm_master_state_loop_control(ec_fsm_master_t *);
67 #endif
73 
78 
81 
82 /*****************************************************************************/
83 
87  ec_fsm_master_t *fsm,
88  ec_master_t *master,
89  ec_datagram_t *datagram
90  )
91 {
92  fsm->master = master;
93  fsm->datagram = datagram;
94 
96 
97  // init sub-state-machines
98  ec_fsm_coe_init(&fsm->fsm_coe);
99  ec_fsm_soe_init(&fsm->fsm_soe);
100  ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe);
103  &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_soe, &fsm->fsm_pdo);
105  &fsm->fsm_slave_config, &fsm->fsm_pdo);
106  ec_fsm_sii_init(&fsm->fsm_sii, fsm->datagram);
107 }
108 
109 /*****************************************************************************/
110 
114  ec_fsm_master_t *fsm
115  )
116 {
117  // clear sub-state machines
118  ec_fsm_coe_clear(&fsm->fsm_coe);
119  ec_fsm_soe_clear(&fsm->fsm_soe);
120  ec_fsm_pdo_clear(&fsm->fsm_pdo);
124  ec_fsm_sii_clear(&fsm->fsm_sii);
125 }
126 
127 /*****************************************************************************/
128 
132  ec_fsm_master_t *fsm
133  )
134 {
135  ec_device_index_t dev_idx;
136 
138  fsm->idle = 0;
139  fsm->dev_idx = EC_DEVICE_MAIN;
140 
141  for (dev_idx = EC_DEVICE_MAIN;
142  dev_idx < ec_master_num_devices(fsm->master); dev_idx++) {
143  fsm->link_state[dev_idx] = 0;
144  fsm->slaves_responding[dev_idx] = 0;
145  fsm->slave_states[dev_idx] = EC_SLAVE_STATE_UNKNOWN;
146  }
147 
148  fsm->rescan_required = 0;
149 }
150 
151 /*****************************************************************************/
152 
161  ec_fsm_master_t *fsm
162  )
163 {
164  if (fsm->datagram->state == EC_DATAGRAM_SENT
165  || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
166  // datagram was not sent or received yet.
167  return 0;
168  }
169 
170  fsm->state(fsm);
171  return 1;
172 }
173 
174 /*****************************************************************************/
175 
180  const ec_fsm_master_t *fsm
181  )
182 {
183  return fsm->idle;
184 }
185 
186 /*****************************************************************************/
187 
191  ec_fsm_master_t *fsm
192  )
193 {
194  fsm->dev_idx = EC_DEVICE_MAIN;
196  fsm->state(fsm); // execute immediately
197 }
198 
199 /******************************************************************************
200  * Master state machine
201  *****************************************************************************/
202 
208  ec_fsm_master_t *fsm
209  )
210 {
211  ec_master_t *master = fsm->master;
212 
213  fsm->idle = 1;
214 
215  // check for emergency requests
216  if (!list_empty(&master->emerg_reg_requests)) {
217  ec_reg_request_t *request;
218 
219  // get first request
220  request = list_entry(master->emerg_reg_requests.next,
221  ec_reg_request_t, list);
222  list_del_init(&request->list); // dequeue
223  request->state = EC_INT_REQUEST_BUSY;
224 
225  if (request->transfer_size > fsm->datagram->mem_size) {
226  EC_MASTER_ERR(master, "Emergency request data too large!\n");
227  request->state = EC_INT_REQUEST_FAILURE;
228  wake_up_all(&master->request_queue);
229  fsm->state(fsm); // continue
230  return;
231  }
232 
233  if (request->dir != EC_DIR_OUTPUT) {
234  EC_MASTER_ERR(master, "Emergency requests must be"
235  " write requests!\n");
236  request->state = EC_INT_REQUEST_FAILURE;
237  wake_up_all(&master->request_queue);
238  fsm->state(fsm); // continue
239  return;
240  }
241 
242  EC_MASTER_DBG(master, 1, "Writing emergency register request...\n");
243  ec_datagram_apwr(fsm->datagram, request->ring_position,
244  request->address, request->transfer_size);
245  memcpy(fsm->datagram->data, request->data, request->transfer_size);
247  request->state = EC_INT_REQUEST_SUCCESS;
248  wake_up_all(&master->request_queue);
249  return;
250  }
251 
252  // check for detached config requests
254 
255  ec_datagram_brd(fsm->datagram, 0x0130, 2);
257  fsm->datagram->device_index = fsm->dev_idx;
258  fsm->retries = EC_FSM_RETRIES;
260 }
261 
262 /*****************************************************************************/
263 
269  ec_fsm_master_t *fsm
270  )
271 {
272  ec_datagram_t *datagram = fsm->datagram;
273  unsigned int i, size;
274  ec_slave_t *slave;
275  ec_master_t *master = fsm->master;
276 
277  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
278  return;
279  }
280 
281  // bus topology change?
282  if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
283  fsm->rescan_required = 1;
284  fsm->slaves_responding[fsm->dev_idx] = datagram->working_counter;
285  EC_MASTER_INFO(master, "%u slave(s) responding on %s device.\n",
286  fsm->slaves_responding[fsm->dev_idx],
287  ec_device_names[fsm->dev_idx != 0]);
288  }
289 
290  if (fsm->link_state[fsm->dev_idx] &&
291  !master->devices[fsm->dev_idx].link_state) {
292  ec_device_index_t dev_idx;
293 
294  EC_MASTER_DBG(master, 1, "Master state machine detected "
295  "link down on %s device. Clearing slave list.\n",
296  ec_device_names[fsm->dev_idx != 0]);
297 
298 #ifdef EC_EOE
299  ec_master_eoe_stop(master);
301 #endif
302  ec_master_clear_slaves(master);
303 
304  for (dev_idx = EC_DEVICE_MAIN;
305  dev_idx < ec_master_num_devices(master); dev_idx++) {
306  fsm->slave_states[dev_idx] = 0x00;
307  fsm->slaves_responding[dev_idx] = 0; /* Reset to trigger rescan on
308  next link up. */
309  }
310  }
311  fsm->link_state[fsm->dev_idx] = master->devices[fsm->dev_idx].link_state;
312 
313  if (datagram->state == EC_DATAGRAM_RECEIVED &&
314  fsm->slaves_responding[fsm->dev_idx]) {
315  uint8_t states = EC_READ_U8(datagram->data);
316  if (states != fsm->slave_states[fsm->dev_idx]) {
317  // slave states changed
318  char state_str[EC_STATE_STRING_SIZE];
319  fsm->slave_states[fsm->dev_idx] = states;
320  ec_state_string(states, state_str, 1);
321  EC_MASTER_INFO(master, "Slave states on %s device: %s.\n",
322  ec_device_names[fsm->dev_idx != 0], state_str);
323  }
324  } else {
325  fsm->slave_states[fsm->dev_idx] = 0x00;
326  }
327 
328  fsm->dev_idx++;
329  if (fsm->dev_idx < ec_master_num_devices(master)) {
330  // check number of responding slaves on next device
332  fsm->state(fsm); // execute immediately
333  return;
334  }
335 
336  if (fsm->rescan_required) {
337  ec_lock_down(&master->scan_sem);
338  if (!master->allow_scan) {
339  ec_lock_up(&master->scan_sem);
340  } else {
341  unsigned int count = 0, next_dev_slave, ring_position;
342  ec_device_index_t dev_idx;
343 
344  master->scan_busy = 1;
345  ec_lock_up(&master->scan_sem);
346 
347  // clear all slaves and scan the bus
348  fsm->rescan_required = 0;
349  fsm->idle = 0;
350  fsm->scan_jiffies = jiffies;
351 
352 #ifdef EC_EOE
353  ec_master_eoe_stop(master);
355 #endif
356  ec_master_clear_slaves(master);
357 
358  for (dev_idx = EC_DEVICE_MAIN;
359  dev_idx < ec_master_num_devices(master); dev_idx++) {
360  count += fsm->slaves_responding[dev_idx];
361  }
362 
363  if (!count) {
364  // no slaves present -> finish state machine.
365  master->scan_busy = 0;
366  wake_up_interruptible(&master->scan_queue);
368  return;
369  }
370 
371  size = sizeof(ec_slave_t) * count;
372  if (!(master->slaves =
373  (ec_slave_t *) kmalloc(size, GFP_KERNEL))) {
374  EC_MASTER_ERR(master, "Failed to allocate %u bytes"
375  " of slave memory!\n", size);
376  master->scan_busy = 0;
377  wake_up_interruptible(&master->scan_queue);
379  return;
380  }
381 
382  // init slaves
383  dev_idx = EC_DEVICE_MAIN;
384  next_dev_slave = fsm->slaves_responding[dev_idx];
385  ring_position = 0;
386  for (i = 0; i < count; i++, ring_position++) {
387  slave = master->slaves + i;
388  while (i >= next_dev_slave) {
389  dev_idx++;
390  next_dev_slave += fsm->slaves_responding[dev_idx];
391  ring_position = 0;
392  }
393 
394  ec_slave_init(slave, master, dev_idx, ring_position, i + 1);
395 
396  // do not force reconfiguration in operation phase to avoid
397  // unnecesssary process data interruptions
398  if (master->phase != EC_OPERATION) {
399  slave->force_config = 1;
400  }
401  }
402  master->slave_count = count;
403  master->fsm_slave = master->slaves;
404 
405  /* start with first device with slaves responding; at least one
406  * has responding slaves, otherwise count would be zero. */
407  fsm->dev_idx = EC_DEVICE_MAIN;
408  while (!fsm->slaves_responding[fsm->dev_idx]) {
409  fsm->dev_idx++;
410  }
411 
413  return;
414  }
415  }
416 
417  if (master->slave_count) {
418 
419  // application applied configurations
420  if (master->config_changed) {
421  master->config_changed = 0;
422  master->dc_offset_valid = 0;
423 
424  EC_MASTER_DBG(master, 1, "Configuration changed.\n");
425 
426  fsm->slave = master->slaves; // begin with first slave
428 
429  } else {
430  // fetch state from first slave
431  fsm->slave = master->slaves;
433  0x0130, 2);
434  ec_datagram_zero(datagram);
435  fsm->datagram->device_index = fsm->slave->device_index;
436  fsm->retries = EC_FSM_RETRIES;
438  }
439  } else {
441  }
442 }
443 
444 /*****************************************************************************/
445 
451  ec_fsm_master_t *fsm
452  )
453 {
454  ec_master_t *master = fsm->master;
455  ec_sii_write_request_t *request;
456  ec_slave_config_t *config;
457  ec_flag_t *flag;
458  int assign_to_pdi;
459 
460  // search the first request to be processed
461  while (1) {
462  if (list_empty(&master->sii_requests))
463  break;
464 
465  // get first request
466  request = list_entry(master->sii_requests.next,
467  ec_sii_write_request_t, list);
468  list_del_init(&request->list); // dequeue
469  request->state = EC_INT_REQUEST_BUSY;
470 
471  assign_to_pdi = 0;
472  config = request->slave->config;
473  if (config) {
474  flag = ec_slave_config_find_flag(config, "AssignToPdi");
475  if (flag) {
476  assign_to_pdi = flag->value;
477  }
478  }
479 
480  if (assign_to_pdi) {
481  fsm->sii_request = request;
482  EC_SLAVE_DBG(request->slave, 1,
483  "Assigning SII back to EtherCAT.\n");
485  0x0500, 0x01);
486  EC_WRITE_U8(fsm->datagram->data, 0x00); // EtherCAT
487  fsm->retries = EC_FSM_RETRIES;
489  return 1;
490  }
491 
492  // found pending SII write operation. execute it!
493  EC_SLAVE_DBG(request->slave, 1, "Writing SII data...\n");
494  fsm->sii_request = request;
495  fsm->sii_index = 0;
496  ec_fsm_sii_write(&fsm->fsm_sii, request->slave, request->offset,
499  fsm->state(fsm); // execute immediately
500  return 1;
501  }
502 
503  return 0;
504 }
505 
506 /*****************************************************************************/
507 
513  ec_fsm_master_t *fsm
514  )
515 {
516  ec_master_t *master = fsm->master;
517  ec_slave_t *slave;
518  ec_sdo_request_t *req;
519 
520  // search for internal requests to be processed
521  for (slave = master->slaves;
522  slave < master->slaves + master->slave_count;
523  slave++) {
524 
525  if (!slave->config) {
526  continue;
527  }
528 
529  if (!ec_fsm_slave_is_ready(&slave->fsm)) {
530  EC_SLAVE_DBG(slave, 2, "Busy - processing external request!\n");
531  continue;
532  }
533 
534  list_for_each_entry(req, &slave->config->sdo_requests, list) {
535  if (req->state == EC_INT_REQUEST_QUEUED) {
536 
537  if (ec_sdo_request_timed_out(req)) {
538  req->state = EC_INT_REQUEST_FAILURE;
539  EC_SLAVE_DBG(slave, 1, "Internal SDO request"
540  " timed out.\n");
541  continue;
542  }
543 
544  if (slave->current_state == EC_SLAVE_STATE_INIT) {
545  req->state = EC_INT_REQUEST_FAILURE;
546  continue;
547  }
548 
549  req->state = EC_INT_REQUEST_BUSY;
550  EC_SLAVE_DBG(slave, 1, "Processing internal"
551  " SDO request...\n");
552  fsm->idle = 0;
553  fsm->sdo_request = req;
554  fsm->slave = slave;
556  ec_fsm_coe_transfer(&fsm->fsm_coe, slave, req);
557  ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram);
558  return 1;
559  }
560  }
561  }
562  return 0;
563 }
564 
565 /*****************************************************************************/
566 
572  ec_fsm_master_t *fsm
573  )
574 {
575  ec_master_t *master = fsm->master;
576  ec_slave_t *slave;
577 
578  // Check for pending internal SDO requests
580  return;
581  }
582 
583  // check, if slaves have an SDO dictionary to read out.
584  for (slave = master->slaves;
585  slave < master->slaves + master->slave_count;
586  slave++) {
587 #ifndef EC_SKIP_SDO_DICT
588  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)
589  || (slave->sii.has_general
590  && !slave->sii.coe_details.enable_sdo_info)
591  || slave->sdo_dictionary_fetched
594  || jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ
595  ) {
596  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)
597  || (slave->sii.has_general
598  && !slave->sii.coe_details.enable_sdo_info)
599  ){
600 #endif
601  // SDO info not supported. Enable processing of requests
602  ec_fsm_slave_set_ready(&slave->fsm);
603 #ifndef EC_SKIP_SDO_DICT
604  }
605  continue;
606  }
607 
608  EC_SLAVE_DBG(slave, 1, "Fetching SDO dictionary.\n");
609 
610  slave->sdo_dictionary_fetched = 1;
611 
612  // start fetching SDO dictionary
613  fsm->idle = 0;
614  fsm->slave = slave;
616  ec_fsm_coe_dictionary(&fsm->fsm_coe, slave);
617  ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram); // execute immediately
618  fsm->datagram->device_index = fsm->slave->device_index;
619  return;
620 #endif
621  }
622 
623  // check for pending SII write operations.
625  return; // SII write request found
626  }
627 
629 }
630 
631 /*****************************************************************************/
632 
636  ec_fsm_master_t *fsm
637  )
638 {
639  ec_master_t *master = fsm->master;
640 
641  // is there another slave to query?
642  fsm->slave++;
643  if (fsm->slave < master->slaves + master->slave_count) {
644  // fetch state from next slave
645  fsm->idle = 1;
647  fsm->slave->station_address, 0x0130, 2);
649  fsm->datagram->device_index = fsm->slave->device_index;
650  fsm->retries = EC_FSM_RETRIES;
652  return;
653  }
654 
655  // all slaves processed
657 }
658 
659 /*****************************************************************************/
660 
661 #ifdef EC_LOOP_CONTROL
662 
665 void ec_fsm_master_action_read_dl_status(
666  ec_fsm_master_t *fsm
667  )
668 {
669  ec_datagram_fprd(fsm->datagram, fsm->slave->station_address, 0x0110, 2);
671  fsm->datagram->device_index = fsm->slave->device_index;
672  fsm->retries = EC_FSM_RETRIES;
673  fsm->state = ec_fsm_master_state_read_dl_status;
674 }
675 
676 /*****************************************************************************/
677 
680 void ec_fsm_master_action_open_port(
681  ec_fsm_master_t *fsm
682  )
683 {
684  EC_SLAVE_INFO(fsm->slave, "Opening ports.\n");
685 
686  ec_datagram_fpwr(fsm->datagram, fsm->slave->station_address, 0x0101, 1);
687  EC_WRITE_U8(fsm->datagram->data, 0x54); // port 0 auto, 1-3 auto-close
688  fsm->datagram->device_index = fsm->slave->device_index;
689  fsm->retries = EC_FSM_RETRIES;
690  fsm->state = ec_fsm_master_state_open_port;
691 }
692 
693 /*****************************************************************************/
694 
699 void ec_fsm_master_state_read_dl_status(
700  ec_fsm_master_t *fsm
701  )
702 {
703  ec_slave_t *slave = fsm->slave;
704  ec_datagram_t *datagram = fsm->datagram;
705  unsigned int i;
706 
707  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
708  return;
709  }
710 
711  if (datagram->state != EC_DATAGRAM_RECEIVED) {
712  EC_SLAVE_ERR(slave, "Failed to receive AL state datagram: ");
713  ec_datagram_print_state(datagram);
715  return;
716  }
717 
718  // did the slave not respond to its station address?
719  if (datagram->working_counter != 1) {
720  // try again next time
722  return;
723  }
724 
725  ec_slave_set_dl_status(slave, EC_READ_U16(datagram->data));
726 
727  // process port state machines
728  for (i = 0; i < EC_MAX_PORTS; i++) {
729  ec_slave_port_t *port = &slave->ports[i];
730 
731  switch (port->state) {
732  case EC_SLAVE_PORT_DOWN:
733  if (port->link.loop_closed) {
734  if (port->link.link_up) {
735  port->link_detection_jiffies = jiffies;
736  port->state = EC_SLAVE_PORT_WAIT;
737  }
738  }
739  else { // loop open
740  port->state = EC_SLAVE_PORT_UP;
741  }
742  break;
743  case EC_SLAVE_PORT_WAIT:
744  if (port->link.link_up) {
745  if (jiffies - port->link_detection_jiffies >
746  HZ * EC_PORT_WAIT_MS / 1000) {
747  port->state = EC_SLAVE_PORT_UP;
748  ec_fsm_master_action_open_port(fsm);
749  return;
750  }
751  }
752  else { // link down
753  port->state = EC_SLAVE_PORT_DOWN;
754  }
755  break;
756  default: // EC_SLAVE_PORT_UP
757  if (!port->link.link_up) {
758  port->state = EC_SLAVE_PORT_DOWN;
759  }
760  break;
761  }
762  }
763 
764  // process next slave
766 }
767 
768 /*****************************************************************************/
769 
774 void ec_fsm_master_state_open_port(
775  ec_fsm_master_t *fsm
776  )
777 {
778  ec_slave_t *slave = fsm->slave;
779  ec_datagram_t *datagram = fsm->datagram;
780 
781  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
782  return;
783  }
784 
785  if (datagram->state != EC_DATAGRAM_RECEIVED) {
786  EC_SLAVE_ERR(slave, "Failed to receive port open datagram: ");
787  ec_datagram_print_state(datagram);
789  return;
790  }
791 
792  // did the slave not respond to its station address?
793  if (datagram->working_counter != 1) {
794  EC_SLAVE_ERR(slave, "Did not respond to port open command!\n");
795  return;
796  }
797 
798  // process next slave
800 }
801 
802 #endif
803 
804 /*****************************************************************************/
805 
809  ec_fsm_master_t *fsm
810  )
811 {
812  ec_master_t *master = fsm->master;
813  ec_slave_t *slave = fsm->slave;
814 
815  if (master->config_changed) {
816  master->config_changed = 0;
817  master->dc_offset_valid = 0;
818 
819  // abort iterating through slaves,
820  // first compensate DC system time offsets,
821  // then begin configuring at slave 0
822  EC_MASTER_DBG(master, 1, "Configuration changed"
823  " (aborting state check).\n");
824 
825  fsm->slave = master->slaves; // begin with first slave
827  return;
828  }
829 
830  // Does the slave have to be configured?
831  if ((slave->current_state != slave->requested_state
832  || slave->force_config) && !slave->error_flag) {
833 
834  // Start slave configuration
835  ec_lock_down(&master->config_sem);
836  master->config_busy = 1;
837  ec_lock_up(&master->config_sem);
838 
839  if (master->debug_level) {
840  char old_state[EC_STATE_STRING_SIZE],
841  new_state[EC_STATE_STRING_SIZE];
842  ec_state_string(slave->current_state, old_state, 0);
843  ec_state_string(slave->requested_state, new_state, 0);
844  EC_SLAVE_DBG(slave, 1, "Changing state from %s to %s%s.\n",
845  old_state, new_state,
846  slave->force_config ? " (forced)" : "");
847  }
848 
849  fsm->idle = 0;
852  fsm->state(fsm); // execute immediately
853  fsm->datagram->device_index = fsm->slave->device_index;
854  return;
855  }
856 
857 #ifdef EC_LOOP_CONTROL
858  // read DL status
859  ec_fsm_master_action_read_dl_status(fsm);
860 #else
861  // process next slave
863 #endif
864 }
865 
866 /*****************************************************************************/
867 
873  ec_fsm_master_t *fsm
874  )
875 {
876  ec_slave_t *slave = fsm->slave;
877  ec_datagram_t *datagram = fsm->datagram;
878 
879  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
880  return;
881  }
882 
883  if (datagram->state != EC_DATAGRAM_RECEIVED) {
884  EC_SLAVE_ERR(slave, "Failed to receive AL state datagram: ");
885  ec_datagram_print_state(datagram);
887  return;
888  }
889 
890  // did the slave not respond to its station address?
891  if (datagram->working_counter != 1) {
892  if (!slave->error_flag) {
893  slave->error_flag = 1;
894  EC_SLAVE_DBG(slave, 1, "Slave did not respond to state query.\n");
895  }
896  fsm->rescan_required = 1;
898  return;
899  }
900 
901  // A single slave responded
902  ec_slave_set_al_status(slave, EC_READ_U8(datagram->data));
903 
904  if (!slave->error_flag) {
905  // Check, if new slave state has to be acknowledged
906  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
907  fsm->idle = 0;
909  ec_fsm_change_ack(&fsm->fsm_change, slave);
910  fsm->state(fsm); // execute immediately
911  return;
912  }
913 
914  // No acknowlegde necessary; check for configuration
916  return;
917  }
918 
919 #ifdef EC_LOOP_CONTROL
920  // read DL status
921  ec_fsm_master_action_read_dl_status(fsm);
922 #else
923  // process next slave
925 #endif
926 }
927 
928 /*****************************************************************************/
929 
933  ec_fsm_master_t *fsm
934  )
935 {
936  ec_slave_t *slave = fsm->slave;
937 
938  if (ec_fsm_change_exec(&fsm->fsm_change)) {
939  return;
940  }
941 
942  if (!ec_fsm_change_success(&fsm->fsm_change)) {
943  fsm->slave->error_flag = 1;
944  EC_SLAVE_ERR(slave, "Failed to acknowledge state change.\n");
945  }
946 
948 }
949 
950 /*****************************************************************************/
951 
955  ec_fsm_master_t *fsm
956  )
957 {
958  // broadcast clear all station addresses
959  ec_datagram_bwr(fsm->datagram, 0x0010, 2);
960  EC_WRITE_U16(fsm->datagram->data, 0x0000);
961  fsm->datagram->device_index = fsm->dev_idx;
962  fsm->retries = EC_FSM_RETRIES;
964 }
965 
966 /*****************************************************************************/
967 
971  ec_fsm_master_t *fsm
972  )
973 {
974  EC_MASTER_DBG(fsm->master, 1, "Sending broadcast-write"
975  " to measure transmission delays on %s link.\n",
976  ec_device_names[fsm->dev_idx != 0]);
977 
978  ec_datagram_bwr(fsm->datagram, 0x0900, 1);
980  fsm->datagram->device_index = fsm->dev_idx;
981  fsm->retries = EC_FSM_RETRIES;
983 }
984 
985 /*****************************************************************************/
986 
987 #ifdef EC_LOOP_CONTROL
988 
991 void ec_fsm_master_enter_loop_control(
992  ec_fsm_master_t *fsm
993  )
994 {
995  EC_MASTER_DBG(fsm->master, 1, "Broadcast-writing"
996  " loop control registers on %s link.\n",
997  ec_device_names[fsm->dev_idx != 0]);
998 
999  ec_datagram_bwr(fsm->datagram, 0x0101, 1);
1000  EC_WRITE_U8(fsm->datagram->data, 0x54); // port 0 auto, 1-3 auto-close
1001  fsm->datagram->device_index = fsm->dev_idx;
1002  fsm->retries = EC_FSM_RETRIES;
1003  fsm->state = ec_fsm_master_state_loop_control;
1004 }
1005 
1006 /*****************************************************************************/
1007 
1010 void ec_fsm_master_state_loop_control(
1011  ec_fsm_master_t *fsm
1012  )
1013 {
1014  ec_master_t *master = fsm->master;
1015  ec_datagram_t *datagram = fsm->datagram;
1016 
1017  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1018  return;
1019  }
1020 
1021  if (datagram->state != EC_DATAGRAM_RECEIVED) {
1022  EC_MASTER_ERR(master, "Failed to receive loop control"
1023  " datagram on %s link: ",
1024  ec_device_names[fsm->dev_idx != 0]);
1025  ec_datagram_print_state(datagram);
1026  }
1027 
1029 }
1030 
1031 #endif
1032 
1033 /*****************************************************************************/
1034 
1038  ec_fsm_master_t *fsm
1039  )
1040 {
1041  ec_master_t *master = fsm->master;
1042  ec_datagram_t *datagram = fsm->datagram;
1043 
1044  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1045  return;
1046  }
1047 
1048  if (datagram->state != EC_DATAGRAM_RECEIVED) {
1049  EC_MASTER_ERR(master, "Failed to receive address"
1050  " clearing datagram on %s link: ",
1051  ec_device_names[fsm->dev_idx != 0]);
1052  ec_datagram_print_state(datagram);
1053  master->scan_busy = 0;
1054  wake_up_interruptible(&master->scan_queue);
1055  ec_fsm_master_restart(fsm);
1056  return;
1057  }
1058 
1059  if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
1060  EC_MASTER_WARN(master, "Failed to clear station addresses on %s link:"
1061  " Cleared %u of %u",
1062  ec_device_names[fsm->dev_idx != 0], datagram->working_counter,
1063  fsm->slaves_responding[fsm->dev_idx]);
1064  }
1065 
1066 #ifdef EC_LOOP_CONTROL
1067  ec_fsm_master_enter_loop_control(fsm);
1068 #else
1070 #endif
1071 }
1072 
1073 /*****************************************************************************/
1074 
1078  ec_fsm_master_t *fsm
1079  )
1080 {
1081  ec_master_t *master = fsm->master;
1082  ec_datagram_t *datagram = fsm->datagram;
1083 
1084  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
1085  return;
1086  }
1087 
1088  if (datagram->state != EC_DATAGRAM_RECEIVED) {
1089  EC_MASTER_ERR(master, "Failed to receive delay measuring datagram"
1090  " on %s link: ", ec_device_names[fsm->dev_idx != 0]);
1091  ec_datagram_print_state(datagram);
1092  master->scan_busy = 0;
1093  wake_up_interruptible(&master->scan_queue);
1094  ec_fsm_master_restart(fsm);
1095  return;
1096  }
1097 
1098  EC_MASTER_DBG(master, 1, "%u slaves responded to delay measuring"
1099  " on %s link.\n",
1100  datagram->working_counter, ec_device_names[fsm->dev_idx != 0]);
1101 
1102  do {
1103  fsm->dev_idx++;
1104  } while (fsm->dev_idx < ec_master_num_devices(master) &&
1105  !fsm->slaves_responding[fsm->dev_idx]);
1106  if (fsm->dev_idx < ec_master_num_devices(master)) {
1108  return;
1109  }
1110 
1111  EC_MASTER_INFO(master, "Scanning bus.\n");
1112 
1113  // begin scanning of slaves
1114  fsm->slave = master->slaves;
1115  EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
1116  fsm->slave->ring_position,
1117  ec_device_names[fsm->slave->device_index != 0]);
1120  ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately
1121  fsm->datagram->device_index = fsm->slave->device_index;
1122 }
1123 
1124 /*****************************************************************************/
1125 
1131  ec_fsm_master_t *fsm
1132  )
1133 {
1134  ec_master_t *master = fsm->master;
1135 #ifdef EC_EOE
1136  ec_slave_t *slave = fsm->slave;
1137 #endif
1138 
1140  return;
1141  }
1142  // Assume that the slaves mailbox data is valid even if the slave scanning skipped
1143  // the clear mailbox state, e.g. if the slave refused to enter state INIT.
1144  fsm->slave->valid_mbox_data = 1;
1145 
1146 #ifdef EC_EOE
1147  if (slave->sii.mailbox_protocols & EC_MBOX_EOE) {
1148  // create EoE handler for this slave
1149  ec_eoe_t *eoe;
1150  if (!(eoe = kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
1151  EC_SLAVE_ERR(slave, "Failed to allocate EoE handler memory!\n");
1152  } else if (ec_eoe_init(eoe, slave)) {
1153  EC_SLAVE_ERR(slave, "Failed to init EoE handler!\n");
1154  kfree(eoe);
1155  } else {
1156  list_add_tail(&eoe->list, &master->eoe_handlers);
1157  }
1158  }
1159 #endif
1160 
1161  // another slave to fetch?
1162  fsm->slave++;
1163  if (fsm->slave < master->slaves + master->slave_count) {
1164  EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
1165  fsm->slave->ring_position,
1166  ec_device_names[fsm->slave->device_index != 0]);
1168  ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately
1169  fsm->datagram->device_index = fsm->slave->device_index;
1170  return;
1171  }
1172 
1173  EC_MASTER_INFO(master, "Bus scanning completed in %lu ms.\n",
1174  (jiffies - fsm->scan_jiffies) * 1000 / HZ);
1175 
1176  master->scan_busy = 0;
1177  wake_up_interruptible(&master->scan_queue);
1178 
1179  // Attach slave configurations
1181 
1182  // Set DC ref slave and calc topology and transmission delays
1183  // Note: must come after attach_slave_configs for application
1184  // selected dc_ref_config to return its slave
1185  ec_master_calc_dc(master);
1186 
1187 #ifdef EC_EOE
1188  // check if EoE processing has to be started
1189  ec_master_eoe_start(master);
1190 #endif
1191 
1192  if (master->slave_count) {
1193  master->config_changed = 0;
1194  master->dc_offset_valid = 0;
1195 
1196  fsm->slave = master->slaves; // begin with first slave
1198  } else {
1199  ec_fsm_master_restart(fsm);
1200  }
1201 }
1202 
1203 /*****************************************************************************/
1204 
1210  ec_fsm_master_t *fsm
1211  )
1212 {
1213  ec_master_t *master = fsm->master;
1214 
1216  return;
1217  }
1218 
1219  fsm->slave->force_config = 0;
1220 
1221  // configuration finished
1222  master->config_busy = 0;
1223  wake_up_interruptible(&master->config_queue);
1224 
1226  // TODO: mark slave_config as failed.
1227  }
1228 
1229  fsm->idle = 1;
1230 
1231 #ifdef EC_LOOP_CONTROL
1232  // read DL status
1233  ec_fsm_master_action_read_dl_status(fsm);
1234 #else
1235  // process next slave
1237 #endif
1238 }
1239 
1240 /*****************************************************************************/
1241 
1245  ec_fsm_master_t *fsm
1246  )
1247 {
1248  ec_master_t *master = fsm->master;
1249 
1250  if (master->active) {
1251 
1252  while (fsm->slave < master->slaves + master->slave_count) {
1253  if (!fsm->slave->base_dc_supported
1254  || !fsm->slave->has_dc_system_time) {
1255  fsm->slave++;
1256  continue;
1257  }
1258 
1259  EC_SLAVE_DBG(fsm->slave, 1, "Checking system time offset.\n");
1260 
1261  // read DC system time (0x0910, 64 bit)
1262  // gap (64 bit)
1263  // and time offset (0x0920, 64 bit)
1264  // and receive delay (0x0928, 32 bit)
1266  0x0910, 28);
1267  ec_datagram_zero(fsm->datagram);
1268  fsm->datagram->device_index = fsm->slave->device_index;
1269  fsm->retries = EC_FSM_RETRIES;
1271  return;
1272  }
1273  master->dc_offset_valid = 1;
1274 
1275  } else {
1276  EC_MASTER_DBG(master, 1, "No app_time received up to now.\n");
1277  }
1278 
1279  // scanning and setting system times complete
1280  ec_master_request_op(master);
1281  ec_fsm_master_restart(fsm);
1282 }
1283 
1284 /*****************************************************************************/
1285 
1291  ec_fsm_master_t *fsm,
1292  u64 system_time,
1293  u64 old_offset,
1294  u64 app_time_sent
1295  )
1296 {
1297  ec_slave_t *slave = fsm->slave;
1298  u32 system_time32, old_offset32, new_offset;
1299  s32 time_diff;
1300 
1301  system_time32 = (u32) system_time;
1302  old_offset32 = (u32) old_offset;
1303 
1304  time_diff = (u32) app_time_sent - system_time32;
1305 
1306  EC_SLAVE_DBG(slave, 1, "DC 32 bit system time offset calculation:"
1307  " system_time=%u, app_time=%llu, diff=%i\n",
1308  system_time32, app_time_sent, time_diff);
1309 
1310  if (EC_ABS(time_diff) > EC_SYSTEM_TIME_TOLERANCE_NS) {
1311  new_offset = time_diff + old_offset32;
1312  EC_SLAVE_DBG(slave, 1, "Setting time offset to %u (was %u)\n",
1313  new_offset, old_offset32);
1314  return (u64) new_offset;
1315  } else {
1316  EC_SLAVE_DBG(slave, 1, "Not touching time offset.\n");
1317  return old_offset;
1318  }
1319 }
1320 
1321 /*****************************************************************************/
1322 
1328  ec_fsm_master_t *fsm,
1329  u64 system_time,
1330  u64 old_offset,
1331  u64 app_time_sent
1332  )
1333 {
1334  ec_slave_t *slave = fsm->slave;
1335  u64 new_offset;
1336  s64 time_diff;
1337 
1338  time_diff = app_time_sent - system_time;
1339 
1340  EC_SLAVE_DBG(slave, 1, "DC 64 bit system time offset calculation:"
1341  " system_time=%llu, app_time=%llu, diff=%lli\n",
1342  system_time, app_time_sent, time_diff);
1343 
1344  if (EC_ABS(time_diff) > EC_SYSTEM_TIME_TOLERANCE_NS) {
1345  new_offset = time_diff + old_offset;
1346  EC_SLAVE_DBG(slave, 1, "Setting time offset to %llu (was %llu)\n",
1347  new_offset, old_offset);
1348  } else {
1349  new_offset = old_offset;
1350  EC_SLAVE_DBG(slave, 1, "Not touching time offset.\n");
1351  }
1352 
1353  return new_offset;
1354 }
1355 
1356 /*****************************************************************************/
1357 
1361  ec_fsm_master_t *fsm
1362  )
1363 {
1364  ec_datagram_t *datagram = fsm->datagram;
1365  ec_slave_t *slave = fsm->slave;
1366  ec_master_t *master = fsm->master;
1367  u64 system_time, old_offset, new_offset;
1368  u32 old_delay;
1369 
1370  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1371  return;
1372 
1373  if (datagram->state != EC_DATAGRAM_RECEIVED) {
1374  EC_SLAVE_ERR(slave, "Failed to receive DC times datagram: ");
1375  ec_datagram_print_state(datagram);
1376  fsm->slave++;
1378  return;
1379  }
1380 
1381  if (datagram->working_counter != 1) {
1382  EC_SLAVE_WARN(slave, "Failed to get DC times: ");
1383  ec_datagram_print_wc_error(datagram);
1384  fsm->slave++;
1386  return;
1387  }
1388 
1389  if (unlikely(!master->dc_ref_time)) {
1390  EC_MASTER_WARN(master, "No app_time received up to now,"
1391  " abort DC time offset calculation.\n");
1392  // scanning and setting system times complete
1393  ec_master_request_op(master);
1394  ec_fsm_master_restart(fsm);
1395  return;
1396  }
1397 
1398  system_time = EC_READ_U64(datagram->data); // 0x0910
1399  old_offset = EC_READ_U64(datagram->data + 16); // 0x0920
1400  old_delay = EC_READ_U32(datagram->data + 24); // 0x0928
1401 
1402  if (slave->base_dc_range == EC_DC_32) {
1403  new_offset = ec_fsm_master_dc_offset32(fsm,
1404  system_time, old_offset, datagram->app_time_sent);
1405  } else {
1406  new_offset = ec_fsm_master_dc_offset64(fsm,
1407  system_time, old_offset, datagram->app_time_sent);
1408  }
1409 
1410  if (new_offset != old_offset
1411  && slave->current_state >= EC_SLAVE_STATE_SAFEOP) {
1412  // Slave is already active; changing the system time offset could
1413  // cause problems. Leave the offset alone in this case and just
1414  // let the normal cyclic sync process gradually adjust it to the
1415  // correct time.
1416  EC_SLAVE_DBG(slave, 1, "Slave is running; ignoring DC offset change.\n");
1417  new_offset = old_offset;
1418  }
1419 
1420  if (new_offset == old_offset && slave->transmission_delay == old_delay) {
1421  // offsets have not changed; skip write to avoid possible trouble
1422  fsm->slave++;
1424  return;
1425  }
1426 
1427  // set DC system time offset and transmission delay
1428  ec_datagram_fpwr(datagram, slave->station_address, 0x0920, 12);
1429  EC_WRITE_U64(datagram->data, new_offset);
1430  EC_WRITE_U32(datagram->data + 8, slave->transmission_delay);
1431  fsm->datagram->device_index = slave->device_index;
1432  fsm->retries = EC_FSM_RETRIES;
1434 }
1435 
1436 /*****************************************************************************/
1437 
1441  ec_fsm_master_t *fsm
1442  )
1443 {
1444  ec_datagram_t *datagram = fsm->datagram;
1445  ec_slave_t *slave = fsm->slave;
1446 
1447  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1448  return;
1449 
1450  if (datagram->state != EC_DATAGRAM_RECEIVED) {
1451  EC_SLAVE_ERR(slave,
1452  "Failed to receive DC system time offset datagram: ");
1453  ec_datagram_print_state(datagram);
1454  fsm->slave++;
1456  return;
1457  }
1458 
1459  if (datagram->working_counter != 1) {
1460  EC_SLAVE_ERR(slave, "Failed to set DC system time offset: ");
1461  ec_datagram_print_wc_error(datagram);
1462  fsm->slave++;
1464  return;
1465  }
1466 
1467  // reset DC filter after changing offsets
1468  if (slave->current_state >= EC_SLAVE_STATE_SAFEOP) {
1469  EC_SLAVE_DBG(slave, 1, "Slave is running; not resetting DC filter.\n");
1470  fsm->slave++;
1472  } else {
1473  ec_datagram_fpwr(datagram, slave->station_address, 0x0930, 2);
1474  EC_WRITE_U16(datagram->data, 0x1000);
1475  fsm->datagram->device_index = slave->device_index;
1476  fsm->retries = EC_FSM_RETRIES;
1478  }
1479 }
1480 
1481 /*****************************************************************************/
1482 
1486  ec_fsm_master_t *fsm
1487  )
1488 {
1489  ec_datagram_t *datagram = fsm->datagram;
1490  ec_slave_t *slave = fsm->slave;
1491 
1492  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1493  return;
1494 
1495  if (datagram->state != EC_DATAGRAM_RECEIVED) {
1496  EC_SLAVE_ERR(slave,
1497  "Failed to receive DC reset filter datagram: ");
1498  ec_datagram_print_state(datagram);
1499  fsm->slave++;
1501  return;
1502  }
1503 
1504  if (datagram->working_counter != 1) {
1505  EC_SLAVE_ERR(slave, "Failed to reset DC filter: ");
1506  ec_datagram_print_wc_error(datagram);
1507  fsm->slave++;
1509  return;
1510  }
1511 
1512  fsm->slave++;
1514 }
1515 
1516 /*****************************************************************************/
1517 
1521  ec_fsm_master_t *fsm
1522  )
1523 {
1524  ec_datagram_t *datagram = fsm->datagram;
1525  ec_sii_write_request_t *request = fsm->sii_request;
1526  ec_slave_t *slave = request->slave;
1527 
1528  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1529  return;
1530 
1531  if (datagram->state != EC_DATAGRAM_RECEIVED) {
1532  EC_SLAVE_ERR(slave, "Failed to receive SII assignment datagram: ");
1533  ec_datagram_print_state(datagram);
1534  goto cont;
1535  }
1536 
1537  if (datagram->working_counter != 1) {
1538  EC_SLAVE_ERR(slave, "Failed to assign SII back to EtherCAT: ");
1539  ec_datagram_print_wc_error(datagram);
1540  goto cont;
1541  }
1542 
1543 cont:
1544  // found pending SII write operation. execute it!
1545  EC_SLAVE_DBG(slave, 1, "Writing SII data (after assignment)...\n");
1546  fsm->sii_index = 0;
1547  ec_fsm_sii_write(&fsm->fsm_sii, slave, request->offset,
1550  fsm->state(fsm); // execute immediately
1551 }
1552 
1553 /*****************************************************************************/
1554 
1558  ec_fsm_master_t *fsm
1559  )
1560 {
1561  ec_master_t *master = fsm->master;
1562  ec_sii_write_request_t *request = fsm->sii_request;
1563  ec_slave_t *slave = request->slave;
1564 
1565  if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
1566 
1567  if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
1568  EC_SLAVE_ERR(slave, "Failed to write SII data.\n");
1569  request->state = EC_INT_REQUEST_FAILURE;
1570  wake_up_all(&master->request_queue);
1571  ec_fsm_master_restart(fsm);
1572  return;
1573  }
1574 
1575  fsm->sii_index++;
1576  if (fsm->sii_index < request->nwords) {
1577  ec_fsm_sii_write(&fsm->fsm_sii, slave,
1578  request->offset + fsm->sii_index,
1579  request->words + fsm->sii_index,
1581  ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
1582  return;
1583  }
1584 
1585  // finished writing SII
1586  EC_SLAVE_DBG(slave, 1, "Finished writing %zu words of SII data.\n",
1587  request->nwords);
1588 
1589  if (request->offset <= 4 && request->offset + request->nwords > 4) {
1590  // alias was written
1591  slave->sii.alias = EC_READ_U16(request->words + 4);
1592  // TODO: read alias from register 0x0012
1593  slave->effective_alias = slave->sii.alias;
1594  }
1595  // TODO: Evaluate other SII contents!
1596 
1597  request->state = EC_INT_REQUEST_SUCCESS;
1598  wake_up_all(&master->request_queue);
1599 
1600  // check for another SII write request
1602  return; // processing another request
1603 
1604  ec_fsm_master_restart(fsm);
1605 }
1606 
1607 /*****************************************************************************/
1608 
1612  ec_fsm_master_t *fsm
1613  )
1614 {
1615  ec_slave_t *slave = fsm->slave;
1616  ec_master_t *master = fsm->master;
1617 
1618  if (ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram)) {
1619  return;
1620  }
1621 
1622  if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
1623  ec_fsm_master_restart(fsm);
1624  return;
1625  }
1626 
1627  // SDO dictionary fetching finished
1628 
1629  if (master->debug_level) {
1630  unsigned int sdo_count, entry_count;
1631  ec_slave_sdo_dict_info(slave, &sdo_count, &entry_count);
1632  EC_SLAVE_DBG(slave, 1, "Fetched %u SDOs and %u entries.\n",
1633  sdo_count, entry_count);
1634  }
1635 
1636  // enable processing of requests
1637  ec_fsm_slave_set_ready(&slave->fsm);
1638 
1639  // attach pdo names from dictionary
1641 
1642  ec_fsm_master_restart(fsm);
1643 }
1644 
1645 /*****************************************************************************/
1646 
1650  ec_fsm_master_t *fsm
1651  )
1652 {
1653  ec_sdo_request_t *request = fsm->sdo_request;
1654 
1655  if (!request) {
1656  // configuration was cleared in the meantime
1657  ec_fsm_master_restart(fsm);
1658  return;
1659  }
1660 
1661  if (ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram)) {
1662  return;
1663  }
1664 
1665  if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
1666  EC_SLAVE_DBG(fsm->slave, 1,
1667  "Failed to process internal SDO request.\n");
1668  request->state = EC_INT_REQUEST_FAILURE;
1669  wake_up_all(&fsm->master->request_queue);
1670  ec_fsm_master_restart(fsm);
1671  return;
1672  }
1673 
1674  // SDO request finished
1675  request->state = EC_INT_REQUEST_SUCCESS;
1676  wake_up_all(&fsm->master->request_queue);
1677 
1678  EC_SLAVE_DBG(fsm->slave, 1, "Finished internal SDO request.\n");
1679 
1680  // check for another SDO request
1682  return; // processing another request
1683  }
1684 
1685  ec_fsm_master_restart(fsm);
1686 }
1687 
1688 /*****************************************************************************/
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
uint16_t ring_position
Ring position for emergency requests.
Definition: reg_request.h:57
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:56
uint16_t offset
SII word offset.
Definition: fsm_master.h:56
uint16_t ring_position
Ring position.
Definition: slave.h:206
ec_datagram_t * datagram
datagram used in the state machine
Definition: fsm_master.h:70
ec_sii_write_request_t * sii_request
SII write request.
Definition: fsm_master.h:88
ec_sii_t sii
Extracted SII data.
Definition: slave.h:246
void ec_fsm_slave_config_start(ec_fsm_slave_config_t *fsm, ec_slave_t *slave)
Start slave configuration state machine.
ec_fsm_soe_t fsm_soe
SoE state machine.
Definition: fsm_master.h:93
void ec_master_calc_dc(ec_master_t *master)
Distributed-clocks calculations.
Definition: master.c:2388
size_t transfer_size
Size of the data to transfer.
Definition: reg_request.h:55
void ec_fsm_master_state_broadcast(ec_fsm_master_t *)
Master state: BROADCAST.
Definition: fsm_master.c:268
void ec_slave_attach_pdo_names(ec_slave_t *slave)
Attach PDO names.
Definition: slave.c:903
struct list_head sii_requests
SII write requests.
Definition: master.h:304
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:107
ec_fsm_pdo_t fsm_pdo
PDO configuration state machine.
Definition: fsm_master.h:94
void ec_fsm_master_state_configure_slave(ec_fsm_master_t *)
Master state: CONFIGURE SLAVE.
Definition: fsm_master.c:1209
void ec_fsm_master_state_scan_slave(ec_fsm_master_t *)
Master state: SCAN SLAVE.
Definition: fsm_master.c:1130
void ec_fsm_master_state_read_al_status(ec_fsm_master_t *)
Master state: READ AL STATUS.
Definition: fsm_master.c:872
Finite state machine of an EtherCAT master.
Definition: fsm_master.h:68
uint64_t app_time_sent
App time, when the datagram was sent.
Definition: datagram.h:106
ec_internal_request_state_t state
State of the request.
Definition: fsm_master.h:59
unsigned int slaves_responding[EC_MAX_NUM_DEVICES]
Number of responding slaves for every device.
Definition: fsm_master.h:80
void ec_fsm_slave_scan_init(ec_fsm_slave_scan_t *fsm, ec_datagram_t *datagram, ec_fsm_slave_config_t *fsm_slave_config, ec_fsm_pdo_t *fsm_pdo)
Constructor.
size_t ec_state_string(uint8_t, char *, uint8_t)
Prints slave states in clear text.
Definition: module.c:402
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
Definition: slave.h:210
void ec_fsm_master_reset(ec_fsm_master_t *fsm)
Reset state machine.
Definition: fsm_master.c:131
struct ec_slave ec_slave_t
Definition: globals.h:316
void ec_master_request_op(ec_master_t *master)
Request OP state for configured slaves.
Definition: master.c:2405
int ec_fsm_slave_is_ready(const ec_fsm_slave_t *fsm)
Returns, if the FSM is currently not busy and ready to execute.
Definition: fsm_slave.c:186
CANopen SDO request.
Definition: sdo_request.h:48
ec_slave_state_t current_state
Current application state.
Definition: slave.h:215
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:327
size_t nwords
Number of words.
Definition: fsm_master.h:57
void(* state)(ec_fsm_master_t *)
master state function
Definition: fsm_master.h:73
ec_internal_request_state_t state
SDO request state.
Definition: sdo_request.h:63
uint16_t address
Register address.
Definition: reg_request.h:54
Register request.
Definition: reg_request.h:48
struct list_head eoe_handlers
Ethernet over EtherCAT handlers.
Definition: master.h:292
Operation phase.
Definition: master.h:130
ec_slave_port_link_t link
Port link status.
Definition: slave.h:139
u64 ec_fsm_master_dc_offset32(ec_fsm_master_t *fsm, u64 system_time, u64 old_offset, u64 app_time_sent)
Configure 32 bit time offset.
Definition: fsm_master.c:1290
unsigned int allow_scan
True, if slave scanning is allowed.
Definition: master.h:250
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:91
void ec_fsm_master_restart(ec_fsm_master_t *fsm)
Restarts the master state machine.
Definition: fsm_master.c:190
unsigned int rescan_required
A bus rescan is required.
Definition: fsm_master.h:83
EtherCAT datagram.
Definition: datagram.h:88
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:183
void ec_fsm_sii_write(ec_fsm_sii_t *fsm, ec_slave_t *slave, uint16_t word_offset, const uint16_t *value, ec_fsm_sii_addressing_t mode)
Initializes the SII write state machine.
Definition: fsm_sii.c:116
void ec_master_expire_slave_config_requests(ec_master_t *master)
Abort active requests for slave configs without attached slaves.
Definition: master.c:1965
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2338
u64 ec_fsm_master_dc_offset64(ec_fsm_master_t *fsm, u64 system_time, u64 old_offset, u64 app_time_sent)
Configure 64 bit time offset.
Definition: fsm_master.c:1327
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:235
ec_slave_state_t slave_states[EC_MAX_NUM_DEVICES]
AL states of responding slaves for every device.
Definition: fsm_master.h:84
struct list_head emerg_reg_requests
Emergency register access requests.
Definition: master.h:305
#define EC_SYSTEM_TIME_TOLERANCE_NS
Time difference [ns] to tolerate without setting a new system time offset.
Definition: fsm_master.c:51
ec_fsm_slave_t fsm
Slave state machine.
Definition: slave.h:259
uint16_t working_counter
Working counter.
Definition: datagram.h:100
int ec_sdo_request_timed_out(const ec_sdo_request_t *req)
Checks, if the timeout was exceeded.
Definition: sdo_request.c:177
void ec_fsm_master_action_idle(ec_fsm_master_t *fsm)
Master action: IDLE.
Definition: fsm_master.c:571
int ec_eoe_init(ec_eoe_t *eoe, ec_slave_t *slave)
EoE constructor.
Definition: ethernet.c:134
Acknowledge/Error bit (no actual state)
Definition: globals.h:140
int ec_fsm_coe_success(const ec_fsm_coe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_coe.c:268
void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *)
Master state: SDO DICTIONARY.
Definition: fsm_master.c:1611
uint8_t link_state
device link state
Definition: device.h:88
void ec_fsm_master_state_dc_read_offset(ec_fsm_master_t *)
Master state: DC READ OFFSET.
Definition: fsm_master.c:1360
Sent (still in the queue).
Definition: datagram.h:77
void ec_slave_set_dl_status(ec_slave_t *slave, uint16_t new_state)
Sets the data-link state of a slave.
Definition: slave.c:356
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:308
void ec_fsm_sii_init(ec_fsm_sii_t *fsm, ec_datagram_t *datagram)
Constructor.
Definition: fsm_sii.c:74
EtherCAT master state machine.
uint16_t station_address
Configured station address.
Definition: slave.h:207
const char * ec_device_names[2]
Device names.
Definition: module.c:466
struct list_head list
List head.
Definition: fsm_master.h:54
SII write request.
Definition: fsm_master.h:53
void ec_fsm_master_action_next_slave_state(ec_fsm_master_t *fsm)
Master action: Get state of next slave.
Definition: fsm_master.c:635
#define EC_WAIT_SDO_DICT
Seconds to wait before fetching SDO dictionary after slave entered PREOP state.
Definition: globals.h:51
void ec_fsm_slave_config_init(ec_fsm_slave_config_t *fsm, ec_datagram_t *datagram, ec_fsm_change_t *fsm_change, ec_fsm_coe_t *fsm_coe, ec_fsm_soe_t *fsm_soe, ec_fsm_pdo_t *fsm_pdo)
Constructor.
int ec_fsm_slave_scan_exec(ec_fsm_slave_scan_t *fsm)
Executes the current state of the state machine.
Global definitions and macros.
void ec_fsm_pdo_clear(ec_fsm_pdo_t *fsm)
Destructor.
Definition: fsm_pdo.c:90
EtherCAT master structure.
SAFEOP (mailbox communication and input update)
Definition: globals.h:136
ec_lock_t config_sem
Semaphore protecting the config_busy variable and the allow_config flag.
Definition: master.h:257
void ec_fsm_master_init(ec_fsm_master_t *fsm, ec_master_t *master, ec_datagram_t *datagram)
Constructor.
Definition: fsm_master.c:86
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:106
void ec_fsm_master_state_sdo_request(ec_fsm_master_t *)
Master state: SDO REQUEST.
Definition: fsm_master.c:1649
int ec_fsm_master_action_process_sii(ec_fsm_master_t *fsm)
Check for pending SII write requests and process one.
Definition: fsm_master.c:450
ec_slave_t * fsm_slave
Slave that is queried next for FSM exec.
Definition: master.h:281
ec_slave_t * slave
EtherCAT slave.
Definition: fsm_master.h:55
void ec_slave_sdo_dict_info(const ec_slave_t *slave, unsigned int *sdo_count, unsigned int *entry_count)
Counts the total number of SDOs and entries in the dictionary.
Definition: slave.c:730
EtherCAT slave.
Definition: slave.h:199
int ec_fsm_master_action_process_sdo(ec_fsm_master_t *fsm)
Check for pending SDO requests and process one.
Definition: fsm_master.c:512
void ec_master_attach_slave_configs(ec_master_t *master)
Attaches the slave configurations to the slaves.
Definition: master.c:1950
int ec_datagram_apwr(ec_datagram_t *datagram, uint16_t ring_position, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT APWR datagram.
Definition: datagram.c:211
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:179
u8 dc_offset_valid
DC slaves have valid system time offsets.
Definition: master.h:236
Ethernet over EtherCAT (EoE)
ec_datagram_state_t state
State.
Definition: datagram.h:101
CANopen over EtherCAT.
Definition: globals.h:152
void ec_fsm_master_enter_write_system_times(ec_fsm_master_t *)
Start writing DC system times.
Definition: fsm_master.c:1244
ec_slave_config_t * config
Current configuration.
Definition: slave.h:213
ec_master_phase_t phase
Master phase.
Definition: master.h:218
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2372
ec_fsm_sii_t fsm_sii
SII state machine.
Definition: fsm_master.h:98
ec_slave_t * slaves
Array of slaves on the bus.
Definition: master.h:226
uint8_t enable_sdo_info
SDO information service available.
Definition: globals.h:162
Use configured addresses.
Definition: fsm_sii.h:50
Slave configutation feature flag.
Definition: flag.h:38
ec_fsm_slave_scan_t fsm_slave_scan
slave state machine
Definition: fsm_master.h:97
uint8_t sdo_dictionary_fetched
Dictionary has been fetched.
Definition: slave.h:249
struct list_head sdo_requests
List of SDO requests.
Definition: slave_config.h:147
void ec_fsm_master_action_configure(ec_fsm_master_t *fsm)
Master action: Configure.
Definition: fsm_master.c:808
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:170
ec_flag_t * ec_slave_config_find_flag(ec_slave_config_t *sc, const char *key)
Finds a flag.
Definition: slave_config.c:650
ec_sdo_request_t * sdo_request
SDO request to process.
Definition: fsm_master.h:90
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_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
Definition: datagram.c:606
ec_slave_dc_range_t base_dc_range
DC range.
Definition: slave.h:234
void ec_fsm_slave_set_ready(ec_fsm_slave_t *fsm)
Sets the current state of the state machine to READY.
Definition: fsm_slave.c:170
int ec_fsm_change_exec(ec_fsm_change_t *fsm)
Executes the current state of the state machine.
Definition: fsm_change.c:124
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
Definition: slave.h:238
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:227
unsigned int scan_busy
Current scan state.
Definition: master.h:249
ec_device_index_t
Master devices.
Definition: globals.h:204
void ec_fsm_pdo_init(ec_fsm_pdo_t *fsm, ec_fsm_coe_t *fsm_coe)
Constructor.
Definition: fsm_pdo.c:74
void ec_fsm_coe_clear(ec_fsm_coe_t *fsm)
Destructor.
Definition: fsm_coe.c:189
uint16_t alias
Configured station alias.
Definition: slave.h:157
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2355
unsigned long scan_jiffies
beginning of slave scanning
Definition: fsm_master.h:77
#define EC_ABS(X)
Absolute value.
Definition: globals.h:257
Main device.
Definition: globals.h:205
Ethernet over EtherCAT.
Definition: globals.h:151
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2266
void ec_fsm_master_enter_clear_addresses(ec_fsm_master_t *)
Start clearing slave addresses.
Definition: fsm_master.c:954
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:92
unsigned int active
Master has been activated.
Definition: master.h:219
void ec_fsm_master_state_assign_sii(ec_fsm_master_t *)
Master state: ASSIGN SII.
Definition: fsm_master.c:1520
void ec_fsm_change_clear(ec_fsm_change_t *fsm)
Destructor.
Definition: fsm_change.c:80
int ec_datagram_brd(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BRD datagram.
Definition: datagram.c:374
void ec_fsm_master_state_dc_measure_delays(ec_fsm_master_t *)
Master state: DC MEASURE DELAYS.
Definition: fsm_master.c:1077
int ec_datagram_fpwr(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPWR datagram.
Definition: datagram.c:299
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:235
void ec_fsm_master_state_dc_write_offset(ec_fsm_master_t *)
Master state: DC WRITE OFFSET.
Definition: fsm_master.c:1440
wait_queue_head_t scan_queue
Queue for processes that wait for slave scanning.
Definition: master.h:253
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:80
int ec_datagram_fprd(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPRD datagram.
Definition: datagram.c:274
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
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
Definition: datagram.h:91
int ec_fsm_master_idle(const ec_fsm_master_t *fsm)
Definition: fsm_master.c:179
32 bit.
Definition: globals.h:179
void ec_master_clear_slaves(ec_master_t *master)
Clear all slaves.
Definition: master.c:492
#define EC_SLAVE_INFO(slave, fmt, args...)
Convenience macro for printing slave-specific information to syslog.
Definition: slave.h:63
void ec_fsm_change_init(ec_fsm_change_t *fsm, ec_datagram_t *datagram)
Constructor.
Definition: fsm_change.c:65
struct list_head list
list item
Definition: ethernet.h:86
void ec_fsm_coe_init(ec_fsm_coe_t *fsm)
Constructor.
Definition: fsm_coe.c:177
uint8_t valid_mbox_data
Received mailbox data is valid.
Definition: slave.h:273
void ec_fsm_sii_clear(ec_fsm_sii_t *fsm)
Destructor.
Definition: fsm_sii.c:88
INIT state (no mailbox communication, no IO)
Definition: globals.h:130
int idle
state machine is in idle phase
Definition: fsm_master.h:76
void ec_fsm_master_state_dc_reset_filter(ec_fsm_master_t *)
Master state: DC RESET FILTER.
Definition: fsm_master.c:1485
uint16_t effective_alias
Effective alias address.
Definition: slave.h:208
void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *)
Master state: CLEAR ADDRESSES.
Definition: fsm_master.c:1037
void ec_master_clear_eoe_handlers(ec_master_t *master)
Clear and free all EoE handlers.
Definition: master.c:456
ec_fsm_slave_config_t fsm_slave_config
slave state machine
Definition: fsm_master.h:96
int ec_fsm_sii_exec(ec_fsm_sii_t *fsm)
Executes the SII state machine.
Definition: fsm_sii.c:137
int ec_fsm_sii_success(ec_fsm_sii_t *fsm)
Returns, if the master startup state machine terminated with success.
Definition: fsm_sii.c:152
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2250
void ec_master_eoe_start(ec_master_t *master)
Starts Ethernet over EtherCAT processing on demand.
Definition: master.c:1828
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_master_state_acknowledge(ec_fsm_master_t *)
Master state: ACKNOWLEDGE.
Definition: fsm_master.c:932
ec_master_t * master
master the FSM runs on
Definition: fsm_master.h:69
uint8_t * data
Pointer to data memory.
Definition: reg_request.h:51
#define EC_STATE_STRING_SIZE
Minimum size of a buffer used with ec_state_string().
Definition: globals.h:54
#define EC_WRITE_U64(DATA, VAL)
Write a 64-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2389
#define EC_MAX_PORTS
Maximum number of slave ports.
Definition: ecrt.h:227
int ec_fsm_slave_config_exec(ec_fsm_slave_config_t *fsm)
Executes the current state of the state machine.
int ec_fsm_coe_exec(ec_fsm_coe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_coe.c:235
void ec_slave_init(ec_slave_t *slave, ec_master_t *master, ec_device_index_t dev_idx, uint16_t ring_position, uint16_t station_address)
Slave constructor.
Definition: slave.c:62
ec_direction_t dir
Direction.
Definition: reg_request.h:52
Queued for sending.
Definition: datagram.h:76
void ec_fsm_change_ack(ec_fsm_change_t *fsm, ec_slave_t *slave)
Starts the change state machine to only acknowlegde a slave&#39;s state.
Definition: fsm_change.c:107
Timed out (dequeued).
Definition: datagram.h:79
wait_queue_head_t config_queue
Queue for processes that wait for slave configuration.
Definition: master.h:259
Slave port.
Definition: slave.h:137
int32_t value
Flag value (meaning depends on key).
Definition: flag.h:41
unsigned int retries
retries on datagram timeout.
Definition: fsm_master.h:71
void ec_fsm_slave_config_clear(ec_fsm_slave_config_t *fsm)
Destructor.
unsigned long jiffies_preop
Time, the slave went to PREOP.
Definition: slave.h:250
void ec_fsm_soe_init(ec_fsm_soe_t *fsm)
Constructor.
Definition: fsm_soe.c:107
uint8_t base_dc_supported
Distributed clocks are supported.
Definition: slave.h:233
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
Definition: fsm_soe.c:120
void ec_fsm_slave_scan_start(ec_fsm_slave_scan_t *fsm, ec_slave_t *slave)
Start slave scan state machine.
uint8_t * data
Datagram payload.
Definition: datagram.h:95
#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
int ec_fsm_master_exec(ec_fsm_master_t *fsm)
Executes the current state of the state machine.
Definition: fsm_master.c:160
int ec_fsm_slave_config_success(const ec_fsm_slave_config_t *fsm)
void ec_fsm_slave_scan_clear(ec_fsm_slave_scan_t *fsm)
Destructor.
EtherCAT slave configuration structure.
size_t mem_size
Datagram data memory size.
Definition: datagram.h:97
void ec_fsm_master_enter_dc_measure_delays(ec_fsm_master_t *fsm)
Start measuring DC delays.
Definition: fsm_master.c:970
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:202
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
ec_slave_t * slave
current slave
Definition: fsm_master.h:87
Values written by the master.
Definition: ecrt.h:437
void ec_fsm_master_state_start(ec_fsm_master_t *)
Master state: START.
Definition: fsm_master.c:207
ec_fsm_change_t fsm_change
State change state machine.
Definition: fsm_master.h:95
Received (dequeued).
Definition: datagram.h:78
Ethernet over EtherCAT (EoE) handler.
Definition: ethernet.h:84
void ec_fsm_master_state_write_sii(ec_fsm_master_t *)
Master state: WRITE SII.
Definition: fsm_master.c:1557
off_t sii_index
index to SII write request data
Definition: fsm_master.h:89
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
Definition: master.h:68
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:216
unsigned int config_changed
The configuration changed.
Definition: master.h:220
EtherCAT master.
Definition: master.h:189
struct list_head list
List item.
Definition: reg_request.h:49
ec_slave_state_t requested_state
Requested application state.
Definition: slave.h:214
ec_device_index_t dev_idx
Current device index (for scanning etc.).
Definition: fsm_master.h:74
#define EC_READ_U64(DATA)
Read a 64-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2282
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:206
ec_lock_t scan_sem
Semaphore protecting the scan_busy variable and the allow_scan flag.
Definition: master.h:251
unsigned int config_busy
State of slave configuration.
Definition: master.h:256
const uint16_t * words
Pointer to the data words.
Definition: fsm_master.h:58
void ec_fsm_master_clear(ec_fsm_master_t *fsm)
Destructor.
Definition: fsm_master.c:113
EtherCAT FoE state machines.
void ec_slave_set_al_status(ec_slave_t *slave, ec_slave_state_t new_state)
Sets the application state of a slave.
Definition: slave.c:396
unknown state
Definition: globals.h:128
void ec_master_eoe_stop(ec_master_t *master)
Stops the Ethernet over EtherCAT processing.
Definition: master.c:1863
uint8_t link_state[EC_MAX_NUM_DEVICES]
Last link state for every device.
Definition: fsm_master.h:78
ec_fsm_coe_t fsm_coe
CoE state machine.
Definition: fsm_master.h:92
unsigned int force_config
Force (re-)configuration.
Definition: slave.h:217
int ec_fsm_change_success(ec_fsm_change_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_change.c:139
unsigned int has_general
General category present.
Definition: slave.h:177
int ec_datagram_bwr(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BWR datagram.
Definition: datagram.c:394