IgH EtherCAT Master  1.6.2
fsm_master.c
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * Copyright (C) 2006-2023 Florian Pose, Ingenieurgemeinschaft IgH
4  *
5  * This file is part of the IgH EtherCAT Master.
6  *
7  * The IgH EtherCAT Master is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License version 2, as
9  * published by the Free Software Foundation.
10  *
11  * The IgH EtherCAT Master is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14  * Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with the IgH EtherCAT Master; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  *
20  ****************************************************************************/
21 
26 /****************************************************************************/
27 
28 #include "globals.h"
29 #include "master.h"
30 #include "mailbox.h"
31 #include "slave_config.h"
32 #ifdef EC_EOE
33 #include "ethernet.h"
34 #endif
35 
36 #include "fsm_master.h"
37 #include "fsm_foe.h"
38 
39 /****************************************************************************/
40 
43 #define EC_SYSTEM_TIME_TOLERANCE_NS 1000000
44 
45 /****************************************************************************/
46 
47 // prototypes for private methods
54 u64 ec_fsm_master_dc_offset32(ec_fsm_master_t *, u64, u64, unsigned long);
55 u64 ec_fsm_master_dc_offset64(ec_fsm_master_t *, u64, u64, unsigned long);
56 
57 /****************************************************************************/
58 
74 
77 
78 /****************************************************************************/
79 
83  ec_fsm_master_t *fsm,
84  ec_master_t *master,
85  ec_datagram_t *datagram
86  )
87 {
88  fsm->master = master;
89  fsm->datagram = datagram;
90 
91  // inits the member variables state, idle, dev_idx, link_state,
92  // slaves_responding, slave_states and rescan_required
94 
95  fsm->retries = 0;
96  fsm->scan_jiffies = 0;
97  fsm->slave = NULL;
98  fsm->sii_request = NULL;
99  fsm->sii_index = 0;
100  fsm->sdo_request = NULL;
101  fsm->soe_request = NULL;
102 
103  // init sub-state-machines
104  ec_fsm_coe_init(&fsm->fsm_coe);
105  ec_fsm_soe_init(&fsm->fsm_soe);
106  ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe);
107 #ifdef EC_EOE
108  ec_fsm_eoe_init(&fsm->fsm_eoe);
109 #endif
112  &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_soe, &fsm->fsm_pdo,
113  &fsm->fsm_eoe);
115  &fsm->fsm_slave_config, &fsm->fsm_pdo);
116  ec_fsm_sii_init(&fsm->fsm_sii, fsm->datagram);
117 }
118 
119 /****************************************************************************/
120 
124  ec_fsm_master_t *fsm
125  )
126 {
127  // clear sub-state machines
128  ec_fsm_coe_clear(&fsm->fsm_coe);
129  ec_fsm_soe_clear(&fsm->fsm_soe);
130  ec_fsm_pdo_clear(&fsm->fsm_pdo);
131 #ifdef EC_EOE
132  ec_fsm_eoe_clear(&fsm->fsm_eoe);
133 #endif
137  ec_fsm_sii_clear(&fsm->fsm_sii);
138 }
139 
140 /****************************************************************************/
141 
145  ec_fsm_master_t *fsm
146  )
147 {
148  ec_device_index_t dev_idx;
149 
151  fsm->idle = 0;
152  fsm->dev_idx = EC_DEVICE_MAIN;
153 
154  for (dev_idx = EC_DEVICE_MAIN;
155  dev_idx < ec_master_num_devices(fsm->master); dev_idx++) {
156  fsm->link_state[dev_idx] = 0;
157  fsm->slaves_responding[dev_idx] = 0;
158  fsm->slave_states[dev_idx] = EC_SLAVE_STATE_UNKNOWN;
159  }
160 
161  fsm->rescan_required = 0;
162 }
163 
164 /****************************************************************************/
165 
174  ec_fsm_master_t *fsm
175  )
176 {
177  if (fsm->datagram->state == EC_DATAGRAM_SENT
178  || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
179  // datagram was not sent or received yet.
180  return 0;
181  }
182 
183  fsm->state(fsm);
184  return 1;
185 }
186 
187 /****************************************************************************/
188 
193  const ec_fsm_master_t *fsm
194  )
195 {
196  return fsm->idle;
197 }
198 
199 /****************************************************************************/
200 
204  ec_fsm_master_t *fsm
205  )
206 {
207  fsm->dev_idx = EC_DEVICE_MAIN;
209  fsm->state(fsm); // execute immediately
210 }
211 
212 /*****************************************************************************
213  * Master state machine
214  ****************************************************************************/
215 
221  ec_fsm_master_t *fsm
222  )
223 {
224  ec_master_t *master = fsm->master;
225 
226  fsm->idle = 1;
227 
228  // check for emergency requests
229  if (!list_empty(&master->emerg_reg_requests)) {
230  ec_reg_request_t *request;
231 
232  // get first request
233  request = list_entry(master->emerg_reg_requests.next,
234  ec_reg_request_t, list);
235  list_del_init(&request->list); // dequeue
236  request->state = EC_INT_REQUEST_BUSY;
237 
238  if (request->transfer_size > fsm->datagram->mem_size) {
239  EC_MASTER_ERR(master, "Emergency request data too large!\n");
240  request->state = EC_INT_REQUEST_FAILURE;
241  wake_up_all(&master->request_queue);
242  fsm->state(fsm); // continue
243  return;
244  }
245 
246  if (request->dir != EC_DIR_OUTPUT) {
247  EC_MASTER_ERR(master, "Emergency requests must be"
248  " write requests!\n");
249  request->state = EC_INT_REQUEST_FAILURE;
250  wake_up_all(&master->request_queue);
251  fsm->state(fsm); // continue
252  return;
253  }
254 
255  EC_MASTER_DBG(master, 1, "Writing emergency register request...\n");
256  ec_datagram_apwr(fsm->datagram, request->ring_position,
257  request->address, request->transfer_size);
258  memcpy(fsm->datagram->data, request->data, request->transfer_size);
260  request->state = EC_INT_REQUEST_SUCCESS;
261  wake_up_all(&master->request_queue);
262  return;
263  }
264 
265  ec_datagram_brd(fsm->datagram, 0x0130, 2);
267  fsm->datagram->device_index = fsm->dev_idx;
268  fsm->retries = EC_FSM_RETRIES;
270 }
271 
272 /****************************************************************************/
273 
279  ec_fsm_master_t *fsm
280  )
281 {
282  ec_datagram_t *datagram = fsm->datagram;
283  unsigned int i, size;
284  ec_slave_t *slave;
285  ec_master_t *master = fsm->master;
286 
287  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
288  return;
289  }
290 
291  // bus topology change?
292  if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
293  fsm->rescan_required = 1;
294  fsm->slaves_responding[fsm->dev_idx] = datagram->working_counter;
295  EC_MASTER_INFO(master, "%u slave(s) responding on %s device.\n",
296  fsm->slaves_responding[fsm->dev_idx],
297  ec_device_names[fsm->dev_idx != 0]);
298  }
299 
300  if (fsm->link_state[fsm->dev_idx] &&
301  !master->devices[fsm->dev_idx].link_state) {
302  ec_device_index_t dev_idx;
303 
304  EC_MASTER_DBG(master, 1, "Master state machine detected "
305  "link down on %s device. Clearing slave list.\n",
306  ec_device_names[fsm->dev_idx != 0]);
307 
308 #ifdef EC_EOE
309  ec_master_eoe_stop(master);
311 #endif
312  ec_master_clear_slaves(master);
313 
314  for (dev_idx = EC_DEVICE_MAIN;
315  dev_idx < ec_master_num_devices(master); dev_idx++) {
316  fsm->slave_states[dev_idx] = 0x00;
317  fsm->slaves_responding[dev_idx] = 0; /* Reset to trigger rescan on
318  next link up. */
319  }
320  }
321  fsm->link_state[fsm->dev_idx] = master->devices[fsm->dev_idx].link_state;
322 
323  if (datagram->state == EC_DATAGRAM_RECEIVED &&
324  fsm->slaves_responding[fsm->dev_idx]) {
325  uint8_t states = EC_READ_U8(datagram->data);
326  if (states != fsm->slave_states[fsm->dev_idx]) {
327  // slave states changed
328  char state_str[EC_STATE_STRING_SIZE];
329  fsm->slave_states[fsm->dev_idx] = states;
330  ec_state_string(states, state_str, 1);
331  EC_MASTER_INFO(master, "Slave states on %s device: %s.\n",
332  ec_device_names[fsm->dev_idx != 0], state_str);
333  }
334  } else {
335  fsm->slave_states[fsm->dev_idx] = 0x00;
336  }
337 
338  fsm->dev_idx++;
339  if (fsm->dev_idx < ec_master_num_devices(master)) {
340  // check number of responding slaves on next device
342  fsm->state(fsm); // execute immediately
343  return;
344  }
345 
346  if (fsm->rescan_required) {
347  down(&master->scan_sem);
348  if (!master->allow_scan) {
349  up(&master->scan_sem);
350  } else {
351  unsigned int count = 0, next_dev_slave, ring_position;
352  ec_device_index_t dev_idx;
353 
354  master->scan_busy = 1;
355  master->scan_index = 0;
356  up(&master->scan_sem);
357 
358  // clear all slaves and scan the bus
359  fsm->rescan_required = 0;
360  fsm->idle = 0;
361  fsm->scan_jiffies = jiffies;
362 
363 #ifdef EC_EOE
364  ec_master_eoe_stop(master);
366 #endif
367  ec_master_clear_slaves(master);
368 
369  for (dev_idx = EC_DEVICE_MAIN;
370  dev_idx < ec_master_num_devices(master); dev_idx++) {
371  count += fsm->slaves_responding[dev_idx];
372  }
373 
374  if (!count) {
375  // no slaves present -> finish state machine.
376  master->scan_busy = 0;
377  wake_up_interruptible(&master->scan_queue);
379  return;
380  }
381 
382  size = sizeof(ec_slave_t) * count;
383  if (!(master->slaves =
384  (ec_slave_t *) kmalloc(size, GFP_KERNEL))) {
385  EC_MASTER_ERR(master, "Failed to allocate %u bytes"
386  " of slave memory!\n", size);
387  master->scan_busy = 0;
388  wake_up_interruptible(&master->scan_queue);
390  return;
391  }
392 
393  // init slaves
394  dev_idx = EC_DEVICE_MAIN;
395  next_dev_slave = fsm->slaves_responding[dev_idx];
396  ring_position = 0;
397  for (i = 0; i < count; i++, ring_position++) {
398  slave = master->slaves + i;
399  while (i >= next_dev_slave) {
400  dev_idx++;
401  next_dev_slave += fsm->slaves_responding[dev_idx];
402  ring_position = 0;
403  }
404 
405  ec_slave_init(slave, master, dev_idx, ring_position, i + 1);
406 
407  // do not force reconfiguration in operation phase to avoid
408  // unnecesssary process data interruptions
409  if (master->phase != EC_OPERATION) {
410  slave->force_config = 1;
411  }
412  }
413  master->slave_count = count;
414  master->fsm_slave = master->slaves;
415 
416  /* start with first device with slaves responding; at least one
417  * has responding slaves, otherwise count would be zero. */
418  fsm->dev_idx = EC_DEVICE_MAIN;
419  while (!fsm->slaves_responding[fsm->dev_idx]) {
420  fsm->dev_idx++;
421  }
422 
424  return;
425  }
426  }
427 
428  if (master->slave_count) {
429 
430  // application applied configurations
431  if (master->config_changed) {
432  master->config_changed = 0;
433 
434  EC_MASTER_DBG(master, 1, "Configuration changed.\n");
435 
436  fsm->slave = master->slaves; // begin with first slave
438 
439  } else {
440  // fetch state from first slave
441  fsm->slave = master->slaves;
443  0x0130, 2);
444  ec_datagram_zero(datagram);
445  fsm->datagram->device_index = fsm->slave->device_index;
446  fsm->retries = EC_FSM_RETRIES;
448  }
449  } else {
451  }
452 }
453 
454 /****************************************************************************/
455 
461  ec_fsm_master_t *fsm
462  )
463 {
464  ec_master_t *master = fsm->master;
465  ec_sii_write_request_t *request;
466  ec_slave_config_t *config;
467  ec_flag_t *flag;
468  int assign_to_pdi;
469 
470  // search the first request to be processed
471  while (1) {
472  if (list_empty(&master->sii_requests))
473  break;
474 
475  // get first request
476  request = list_entry(master->sii_requests.next,
477  ec_sii_write_request_t, list);
478  list_del_init(&request->list); // dequeue
479  request->state = EC_INT_REQUEST_BUSY;
480 
481  assign_to_pdi = 0;
482  config = request->slave->config;
483  if (config) {
484  flag = ec_slave_config_find_flag(config, "AssignToPdi");
485  if (flag) {
486  assign_to_pdi = flag->value;
487  }
488  }
489 
490  if (assign_to_pdi) {
491  fsm->sii_request = request;
492  EC_SLAVE_DBG(request->slave, 1,
493  "Assigning SII back to EtherCAT.\n");
495  0x0500, 0x01);
496  EC_WRITE_U8(fsm->datagram->data, 0x00); // EtherCAT
497  fsm->retries = EC_FSM_RETRIES;
499  return 1;
500  }
501 
502  // found pending SII write operation. execute it!
503  EC_SLAVE_DBG(request->slave, 1, "Writing SII data...\n");
504  fsm->sii_request = request;
505  fsm->sii_index = 0;
506  ec_fsm_sii_write(&fsm->fsm_sii, request->slave, request->offset,
509  fsm->state(fsm); // execute immediately
510  return 1;
511  }
512 
513  return 0;
514 }
515 
516 /****************************************************************************/
517 
523  ec_fsm_master_t *fsm
524  )
525 {
526  ec_master_t *master = fsm->master;
527  ec_slave_t *slave;
528  ec_sdo_request_t *sdo_req;
529  ec_soe_request_t *soe_req;
530 
531  // search for internal requests to be processed
532  for (slave = master->slaves;
533  slave < master->slaves + master->slave_count;
534  slave++) {
535 
536  if (!slave->config) {
537  continue;
538  }
539 
540  list_for_each_entry(sdo_req, &slave->config->sdo_requests, list) {
541  if (sdo_req->state == EC_INT_REQUEST_QUEUED) {
542 
543  if (ec_sdo_request_timed_out(sdo_req)) {
544  sdo_req->state = EC_INT_REQUEST_FAILURE;
545  EC_SLAVE_DBG(slave, 1, "Internal SDO request"
546  " timed out.\n");
547  continue;
548  }
549 
550  if (slave->current_state == EC_SLAVE_STATE_INIT) {
551  sdo_req->state = EC_INT_REQUEST_FAILURE;
552  continue;
553  }
554 
555  sdo_req->state = EC_INT_REQUEST_BUSY;
556  EC_SLAVE_DBG(slave, 1, "Processing internal"
557  " SDO request...\n");
558  fsm->idle = 0;
559  fsm->sdo_request = sdo_req;
560  fsm->slave = slave;
562  ec_fsm_coe_transfer(&fsm->fsm_coe, slave, sdo_req);
563  ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram);
564  return 1;
565  }
566  }
567 
568  list_for_each_entry(soe_req, &slave->config->soe_requests, list) {
569  if (soe_req->state == EC_INT_REQUEST_QUEUED) {
570 
571  if (ec_soe_request_timed_out(soe_req)) {
572  soe_req->state = EC_INT_REQUEST_FAILURE;
573  EC_SLAVE_DBG(slave, 1, "Internal SoE request"
574  " timed out.\n");
575  continue;
576  }
577 
578  if (slave->current_state == EC_SLAVE_STATE_INIT) {
579  soe_req->state = EC_INT_REQUEST_FAILURE;
580  continue;
581  }
582 
583  soe_req->state = EC_INT_REQUEST_BUSY;
584  EC_SLAVE_DBG(slave, 1, "Processing internal"
585  " SoE request...\n");
586  fsm->idle = 0;
587  fsm->soe_request = soe_req;
588  fsm->slave = slave;
590  ec_fsm_soe_transfer(&fsm->fsm_soe, slave, soe_req);
591  ec_fsm_soe_exec(&fsm->fsm_soe, fsm->datagram);
592  return 1;
593  }
594  }
595  }
596  return 0;
597 }
598 
599 /****************************************************************************/
600 
606  ec_fsm_master_t *fsm
607  )
608 {
609  ec_master_t *master = fsm->master;
610  ec_slave_t *slave;
611 
612  // Check for pending internal SDO or SoE requests
614  return;
615  }
616 
617  // enable processing of requests
618  for (slave = master->slaves;
619  slave < master->slaves + master->slave_count;
620  slave++) {
621  ec_fsm_slave_set_ready(&slave->fsm);
622  }
623 
624  // check, if slaves have an SDO dictionary to read out.
625  for (slave = master->slaves;
626  slave < master->slaves + master->slave_count;
627  slave++) {
628  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)
629  || (slave->sii.has_general
630  && !slave->sii.coe_details.enable_sdo_info)
631  || slave->sdo_dictionary_fetched
634  || jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ
635  ) continue;
636 
637  EC_SLAVE_DBG(slave, 1, "Fetching SDO dictionary.\n");
638 
639  slave->sdo_dictionary_fetched = 1;
640 
641  // start fetching SDO dictionary
642  fsm->idle = 0;
643  fsm->slave = slave;
645  ec_fsm_coe_dictionary(&fsm->fsm_coe, slave);
646  ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram); // execute immediately
647  fsm->datagram->device_index = fsm->slave->device_index;
648  return;
649  }
650 
651  // check for pending SII write operations.
653  return; // SII write request found
654  }
655 
657 }
658 
659 /****************************************************************************/
660 
664  ec_fsm_master_t *fsm
665  )
666 {
667  ec_master_t *master = fsm->master;
668 
669  // is there another slave to query?
670  fsm->slave++;
671  if (fsm->slave < master->slaves + master->slave_count) {
672  // fetch state from next slave
673  fsm->idle = 1;
675  fsm->slave->station_address, 0x0130, 2);
677  fsm->datagram->device_index = fsm->slave->device_index;
678  fsm->retries = EC_FSM_RETRIES;
680  return;
681  }
682 
683  // all slaves processed
685 }
686 
687 /****************************************************************************/
688 
692  ec_fsm_master_t *fsm
693  )
694 {
695  ec_master_t *master = fsm->master;
696  ec_slave_t *slave = fsm->slave;
697 
698  if (master->config_changed) {
699  master->config_changed = 0;
700 
701  // abort iterating through slaves,
702  // first compensate DC system time offsets,
703  // then begin configuring at slave 0
704  EC_MASTER_DBG(master, 1, "Configuration changed"
705  " (aborting state check).\n");
706 
707  fsm->slave = master->slaves; // begin with first slave
709  return;
710  }
711 
712  // Does the slave have to be configured?
713  if ((slave->current_state != slave->requested_state
714  || slave->force_config) && !slave->error_flag) {
715 
716  // Start slave configuration
717  down(&master->config_sem);
718  master->config_busy = 1;
719  up(&master->config_sem);
720 
721  if (master->debug_level) {
722  char old_state[EC_STATE_STRING_SIZE],
723  new_state[EC_STATE_STRING_SIZE];
724  ec_state_string(slave->current_state, old_state, 0);
725  ec_state_string(slave->requested_state, new_state, 0);
726  EC_SLAVE_DBG(slave, 1, "Changing state from %s to %s%s.\n",
727  old_state, new_state,
728  slave->force_config ? " (forced)" : "");
729  }
730 
731  fsm->idle = 0;
734  fsm->state(fsm); // execute immediately
735  fsm->datagram->device_index = fsm->slave->device_index;
736  return;
737  }
738 
739  // process next slave
741 }
742 
743 /****************************************************************************/
744 
750  ec_fsm_master_t *fsm
751  )
752 {
753  ec_slave_t *slave = fsm->slave;
754  ec_datagram_t *datagram = fsm->datagram;
755 
756  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
757  return;
758  }
759 
760  if (datagram->state != EC_DATAGRAM_RECEIVED) {
761  EC_SLAVE_ERR(slave, "Failed to receive AL state datagram: ");
762  ec_datagram_print_state(datagram);
764  return;
765  }
766 
767  // did the slave not respond to its station address?
768  if (datagram->working_counter != 1) {
769  if (!slave->error_flag) {
770  slave->error_flag = 1;
771  EC_SLAVE_DBG(slave, 1, "Slave did not respond to state query.\n");
772  }
773  fsm->rescan_required = 1;
775  return;
776  }
777 
778  // A single slave responded
779  ec_slave_set_state(slave, EC_READ_U8(datagram->data));
780 
781  if (!slave->error_flag) {
782  // Check, if new slave state has to be acknowledged
783  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
784  fsm->idle = 0;
786  ec_fsm_change_ack(&fsm->fsm_change, slave);
787  fsm->state(fsm); // execute immediately
788  return;
789  }
790 
791  // No acknowlegde necessary; check for configuration
793  return;
794  }
795 
796  // slave has error flag set; process next one
798 }
799 
800 /****************************************************************************/
801 
805  ec_fsm_master_t *fsm
806  )
807 {
808  ec_slave_t *slave = fsm->slave;
809 
810  if (ec_fsm_change_exec(&fsm->fsm_change)) {
811  return;
812  }
813 
814  if (!ec_fsm_change_success(&fsm->fsm_change)) {
815  fsm->slave->error_flag = 1;
816  EC_SLAVE_ERR(slave, "Failed to acknowledge state change.\n");
817  }
818 
820 }
821 
822 /****************************************************************************/
823 
827  ec_fsm_master_t *fsm
828  )
829 {
830  // broadcast clear all station addresses
831  ec_datagram_bwr(fsm->datagram, 0x0010, 2);
832  EC_WRITE_U16(fsm->datagram->data, 0x0000);
833  fsm->datagram->device_index = fsm->dev_idx;
834  fsm->retries = EC_FSM_RETRIES;
836 }
837 
838 /****************************************************************************/
839 
843  ec_fsm_master_t *fsm
844  )
845 {
846  ec_master_t *master = fsm->master;
847  ec_datagram_t *datagram = fsm->datagram;
848 
849  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
850  return;
851  }
852 
853  if (datagram->state != EC_DATAGRAM_RECEIVED) {
854  EC_MASTER_ERR(master, "Failed to receive address"
855  " clearing datagram on %s link: ",
856  ec_device_names[fsm->dev_idx != 0]);
857  ec_datagram_print_state(datagram);
858  master->scan_busy = 0;
859  master->scan_index = master->slave_count;
860  wake_up_interruptible(&master->scan_queue);
862  return;
863  }
864 
865  if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
866  EC_MASTER_WARN(master, "Failed to clear station addresses on %s link:"
867  " Cleared %u of %u",
868  ec_device_names[fsm->dev_idx != 0], datagram->working_counter,
869  fsm->slaves_responding[fsm->dev_idx]);
870  }
871 
872  EC_MASTER_DBG(master, 1, "Sending broadcast-write"
873  " to measure transmission delays on %s link.\n",
874  ec_device_names[fsm->dev_idx != 0]);
875 
876  ec_datagram_bwr(datagram, 0x0900, 1);
877  ec_datagram_zero(datagram);
878  fsm->datagram->device_index = fsm->dev_idx;
879  fsm->retries = EC_FSM_RETRIES;
881 }
882 
883 /****************************************************************************/
884 
888  ec_fsm_master_t *fsm
889  )
890 {
891  ec_master_t *master = fsm->master;
892  ec_datagram_t *datagram = fsm->datagram;
893 
894  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
895  return;
896  }
897 
898  if (datagram->state != EC_DATAGRAM_RECEIVED) {
899  EC_MASTER_ERR(master, "Failed to receive delay measuring datagram"
900  " on %s link: ", ec_device_names[fsm->dev_idx != 0]);
901  ec_datagram_print_state(datagram);
902  master->scan_busy = 0;
903  master->scan_index = master->slave_count;
904  wake_up_interruptible(&master->scan_queue);
906  return;
907  }
908 
909  EC_MASTER_DBG(master, 1, "%u slaves responded to delay measuring"
910  " on %s link.\n",
911  datagram->working_counter, ec_device_names[fsm->dev_idx != 0]);
912 
913  do {
914  fsm->dev_idx++;
915  } while (fsm->dev_idx < ec_master_num_devices(master) &&
916  !fsm->slaves_responding[fsm->dev_idx]);
917  if (fsm->dev_idx < ec_master_num_devices(master)) {
919  return;
920  }
921 
922  EC_MASTER_INFO(master, "Scanning bus.\n");
923 
924  // begin scanning of slaves
925  fsm->slave = master->slaves;
926  master->scan_index = 0;
927  EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
928  fsm->slave->ring_position,
929  ec_device_names[fsm->slave->device_index != 0]);
932  ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately
933  fsm->datagram->device_index = fsm->slave->device_index;
934 }
935 
936 /****************************************************************************/
937 
943  ec_fsm_master_t *fsm
944  )
945 {
946  ec_master_t *master = fsm->master;
947 #ifdef EC_EOE
948  ec_slave_t *slave = fsm->slave;
949 #endif
950 
952  return;
953  }
954 
955 #ifdef EC_EOE
956  if (slave->sii.mailbox_protocols & EC_MBOX_EOE) {
957  // create EoE handler for this slave
958  ec_eoe_t *eoe;
959  if (!(eoe = kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
960  EC_SLAVE_ERR(slave, "Failed to allocate EoE handler memory!\n");
961  } else if (ec_eoe_init(eoe, slave)) {
962  EC_SLAVE_ERR(slave, "Failed to init EoE handler!\n");
963  kfree(eoe);
964  } else {
965  list_add_tail(&eoe->list, &master->eoe_handlers);
966  }
967  }
968 #endif
969 
970  // another slave to fetch?
971  fsm->slave++;
972  master->scan_index++;
973  if (fsm->slave < master->slaves + master->slave_count) {
974  EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
975  fsm->slave->ring_position,
976  ec_device_names[fsm->slave->device_index != 0]);
978  ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately
979  fsm->datagram->device_index = fsm->slave->device_index;
980  return;
981  }
982 
983  EC_MASTER_INFO(master, "Bus scanning completed in %lu ms.\n",
984  (jiffies - fsm->scan_jiffies) * 1000 / HZ);
985 
986  master->scan_busy = 0;
987  master->scan_index = master->slave_count;
988  wake_up_interruptible(&master->scan_queue);
989 
990  ec_master_calc_dc(master);
991 
992  // Attach slave configurations
994 
995 #ifdef EC_EOE
996  // check if EoE processing has to be started
997  ec_master_eoe_start(master);
998 #endif
999 
1000  if (master->slave_count) {
1001  master->config_changed = 0;
1002 
1003  fsm->slave = master->slaves; // begin with first slave
1005  } else {
1006  ec_fsm_master_restart(fsm);
1007  }
1008 }
1009 
1010 /****************************************************************************/
1011 
1017  ec_fsm_master_t *fsm
1018  )
1019 {
1020  ec_master_t *master = fsm->master;
1021 
1023  return;
1024  }
1025 
1026  fsm->slave->force_config = 0;
1027 
1028  // configuration finished
1029  master->config_busy = 0;
1030  wake_up_interruptible(&master->config_queue);
1031 
1033  // TODO: mark slave_config as failed.
1034  }
1035 
1036  fsm->idle = 1;
1038 }
1039 
1040 /****************************************************************************/
1041 
1045  ec_fsm_master_t *fsm
1046  )
1047 {
1048  ec_master_t *master = fsm->master;
1049 
1050  if (master->dc_ref_time) {
1051 
1052  while (fsm->slave < master->slaves + master->slave_count) {
1053  if (!fsm->slave->base_dc_supported
1054  || !fsm->slave->has_dc_system_time) {
1055  fsm->slave++;
1056  continue;
1057  }
1058 
1059  EC_SLAVE_DBG(fsm->slave, 1, "Checking system time offset.\n");
1060 
1061  // read DC system time (0x0910, 64 bit)
1062  // gap (64 bit)
1063  // and time offset (0x0920, 64 bit)
1065  0x0910, 24);
1066  fsm->datagram->device_index = fsm->slave->device_index;
1067  fsm->retries = EC_FSM_RETRIES;
1069  return;
1070  }
1071 
1072  } else {
1073  if (master->active) {
1074  EC_MASTER_WARN(master, "No application time received up to now,"
1075  " but master already active.\n");
1076  } else {
1077  EC_MASTER_DBG(master, 1, "No app_time received up to now.\n");
1078  }
1079  }
1080 
1081  // scanning and setting system times complete
1082  ec_master_request_op(master);
1083  ec_fsm_master_restart(fsm);
1084 }
1085 
1086 /****************************************************************************/
1087 
1093  ec_fsm_master_t *fsm,
1094  u64 system_time,
1095  u64 old_offset,
1096  unsigned long jiffies_since_read
1097  )
1098 {
1099  ec_slave_t *slave = fsm->slave;
1100  u32 correction, system_time32, old_offset32, new_offset;
1101  s32 time_diff;
1102 
1103  system_time32 = (u32) system_time;
1104  old_offset32 = (u32) old_offset;
1105 
1106  // correct read system time by elapsed time since read operation
1107  correction = jiffies_since_read * 1000 / HZ * 1000000;
1108  system_time32 += correction;
1109  time_diff = (u32) slave->master->app_time - system_time32;
1110 
1111  EC_SLAVE_DBG(slave, 1, "DC 32 bit system time offset calculation:"
1112  " system_time=%u (corrected with %u),"
1113  " app_time=%llu, diff=%i\n",
1114  system_time32, correction,
1115  slave->master->app_time, time_diff);
1116 
1117  if (EC_ABS(time_diff) > EC_SYSTEM_TIME_TOLERANCE_NS) {
1118  new_offset = time_diff + old_offset32;
1119  EC_SLAVE_DBG(slave, 1, "Setting time offset to %u (was %u)\n",
1120  new_offset, old_offset32);
1121  return (u64) new_offset;
1122  } else {
1123  EC_SLAVE_DBG(slave, 1, "Not touching time offset.\n");
1124  return old_offset;
1125  }
1126 }
1127 
1128 /****************************************************************************/
1129 
1135  ec_fsm_master_t *fsm,
1136  u64 system_time,
1137  u64 old_offset,
1138  unsigned long jiffies_since_read
1139  )
1140 {
1141  ec_slave_t *slave = fsm->slave;
1142  u64 new_offset, correction;
1143  s64 time_diff;
1144 
1145  // correct read system time by elapsed time since read operation
1146  correction = (u64) (jiffies_since_read * 1000 / HZ) * 1000000;
1147  system_time += correction;
1148  time_diff = fsm->slave->master->app_time - system_time;
1149 
1150  EC_SLAVE_DBG(slave, 1, "DC 64 bit system time offset calculation:"
1151  " system_time=%llu (corrected with %llu),"
1152  " app_time=%llu, diff=%lli\n",
1153  system_time, correction,
1154  slave->master->app_time, time_diff);
1155 
1156  if (EC_ABS(time_diff) > EC_SYSTEM_TIME_TOLERANCE_NS) {
1157  new_offset = time_diff + old_offset;
1158  EC_SLAVE_DBG(slave, 1, "Setting time offset to %llu (was %llu)\n",
1159  new_offset, old_offset);
1160  } else {
1161  new_offset = old_offset;
1162  EC_SLAVE_DBG(slave, 1, "Not touching time offset.\n");
1163  }
1164 
1165  return new_offset;
1166 }
1167 
1168 /****************************************************************************/
1169 
1173  ec_fsm_master_t *fsm
1174  )
1175 {
1176  ec_datagram_t *datagram = fsm->datagram;
1177  ec_slave_t *slave = fsm->slave;
1178  u64 system_time, old_offset, new_offset;
1179  unsigned long jiffies_since_read;
1180 
1181  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1182  return;
1183 
1184  if (datagram->state != EC_DATAGRAM_RECEIVED) {
1185  EC_SLAVE_ERR(slave, "Failed to receive DC times datagram: ");
1186  ec_datagram_print_state(datagram);
1187  fsm->slave++;
1189  return;
1190  }
1191 
1192  if (datagram->working_counter != 1) {
1193  EC_SLAVE_WARN(slave, "Failed to get DC times: ");
1194  ec_datagram_print_wc_error(datagram);
1195  fsm->slave++;
1197  return;
1198  }
1199 
1200  system_time = EC_READ_U64(datagram->data); // 0x0910
1201  old_offset = EC_READ_U64(datagram->data + 16); // 0x0920
1202  jiffies_since_read = jiffies - datagram->jiffies_sent;
1203 
1204  if (slave->base_dc_range == EC_DC_32) {
1205  new_offset = ec_fsm_master_dc_offset32(fsm,
1206  system_time, old_offset, jiffies_since_read);
1207  } else {
1208  new_offset = ec_fsm_master_dc_offset64(fsm,
1209  system_time, old_offset, jiffies_since_read);
1210  }
1211 
1212  // set DC system time offset and transmission delay
1213  ec_datagram_fpwr(datagram, slave->station_address, 0x0920, 12);
1214  EC_WRITE_U64(datagram->data, new_offset);
1215  EC_WRITE_U32(datagram->data + 8, slave->transmission_delay);
1216  fsm->datagram->device_index = slave->device_index;
1217  fsm->retries = EC_FSM_RETRIES;
1219 }
1220 
1221 /****************************************************************************/
1222 
1226  ec_fsm_master_t *fsm
1227  )
1228 {
1229  ec_datagram_t *datagram = fsm->datagram;
1230  ec_slave_t *slave = fsm->slave;
1231 
1232  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1233  return;
1234 
1235  if (datagram->state != EC_DATAGRAM_RECEIVED) {
1236  EC_SLAVE_ERR(slave,
1237  "Failed to receive DC system time offset datagram: ");
1238  ec_datagram_print_state(datagram);
1239  fsm->slave++;
1241  return;
1242  }
1243 
1244  if (datagram->working_counter != 1) {
1245  EC_SLAVE_ERR(slave, "Failed to set DC system time offset: ");
1246  ec_datagram_print_wc_error(datagram);
1247  fsm->slave++;
1249  return;
1250  }
1251 
1252  fsm->slave++;
1254 }
1255 
1256 /****************************************************************************/
1257 
1261  ec_fsm_master_t *fsm
1262  )
1263 {
1264  ec_datagram_t *datagram = fsm->datagram;
1265  ec_sii_write_request_t *request = fsm->sii_request;
1266  ec_slave_t *slave = request->slave;
1267 
1268  if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
1269  return;
1270 
1271  if (datagram->state != EC_DATAGRAM_RECEIVED) {
1272  EC_SLAVE_ERR(slave, "Failed to receive SII assignment datagram: ");
1273  ec_datagram_print_state(datagram);
1274  goto cont;
1275  }
1276 
1277  if (datagram->working_counter != 1) {
1278  EC_SLAVE_ERR(slave, "Failed to assign SII back to EtherCAT: ");
1279  ec_datagram_print_wc_error(datagram);
1280  goto cont;
1281  }
1282 
1283 cont:
1284  // found pending SII write operation. execute it!
1285  EC_SLAVE_DBG(slave, 1, "Writing SII data (after assignment)...\n");
1286  fsm->sii_index = 0;
1287  ec_fsm_sii_write(&fsm->fsm_sii, slave, request->offset,
1290  fsm->state(fsm); // execute immediately
1291 }
1292 
1293 /****************************************************************************/
1294 
1298  ec_fsm_master_t *fsm
1299  )
1300 {
1301  ec_master_t *master = fsm->master;
1302  ec_sii_write_request_t *request = fsm->sii_request;
1303  ec_slave_t *slave = request->slave;
1304 
1305  if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
1306 
1307  if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
1308  EC_SLAVE_ERR(slave, "Failed to write SII data.\n");
1309  request->state = EC_INT_REQUEST_FAILURE;
1310  wake_up_all(&master->request_queue);
1311  ec_fsm_master_restart(fsm);
1312  return;
1313  }
1314 
1315  fsm->sii_index++;
1316  if (fsm->sii_index < request->nwords) {
1317  ec_fsm_sii_write(&fsm->fsm_sii, slave,
1318  request->offset + fsm->sii_index,
1319  request->words + fsm->sii_index,
1321  ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
1322  return;
1323  }
1324 
1325  // finished writing SII
1326  EC_SLAVE_DBG(slave, 1, "Finished writing %zu words of SII data.\n",
1327  request->nwords);
1328 
1329  if (request->offset <= 4 && request->offset + request->nwords > 4) {
1330  // alias was written
1331  slave->sii.alias = EC_READ_U16(request->words + 4);
1332  // TODO: read alias from register 0x0012
1333  slave->effective_alias = slave->sii.alias;
1334  }
1335  // TODO: Evaluate other SII contents!
1336 
1337  request->state = EC_INT_REQUEST_SUCCESS;
1338  wake_up_all(&master->request_queue);
1339 
1340  // check for another SII write request
1342  return; // processing another request
1343 
1344  ec_fsm_master_restart(fsm);
1345 }
1346 
1347 /****************************************************************************/
1348 
1352  ec_fsm_master_t *fsm
1353  )
1354 {
1355  ec_slave_t *slave = fsm->slave;
1356  ec_master_t *master = fsm->master;
1357 
1358  if (ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram)) {
1359  return;
1360  }
1361 
1362  if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
1363  ec_fsm_master_restart(fsm);
1364  return;
1365  }
1366 
1367  // SDO dictionary fetching finished
1368 
1369  if (master->debug_level) {
1370  unsigned int sdo_count, entry_count;
1371  ec_slave_sdo_dict_info(slave, &sdo_count, &entry_count);
1372  EC_SLAVE_DBG(slave, 1, "Fetched %u SDOs and %u entries.\n",
1373  sdo_count, entry_count);
1374  }
1375 
1376  // attach pdo names from dictionary
1378 
1379  ec_fsm_master_restart(fsm);
1380 }
1381 
1382 /****************************************************************************/
1383 
1387  ec_fsm_master_t *fsm
1388  )
1389 {
1390  ec_sdo_request_t *request = fsm->sdo_request;
1391 
1392  if (!request) {
1393  // configuration was cleared in the meantime
1394  ec_fsm_master_restart(fsm);
1395  return;
1396  }
1397 
1398  if (ec_fsm_coe_exec(&fsm->fsm_coe, fsm->datagram)) {
1399  return;
1400  }
1401 
1402  if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
1403  EC_SLAVE_DBG(fsm->slave, 1,
1404  "Failed to process internal SDO request.\n");
1405  request->state = EC_INT_REQUEST_FAILURE;
1406  wake_up_all(&fsm->master->request_queue);
1407  ec_fsm_master_restart(fsm);
1408  return;
1409  }
1410 
1411  // SDO request finished
1412  request->state = EC_INT_REQUEST_SUCCESS;
1413  wake_up_all(&fsm->master->request_queue);
1414 
1415  EC_SLAVE_DBG(fsm->slave, 1, "Finished internal SDO request.\n");
1416 
1417  // check for another SDO/SoE request
1419  return; // processing another request
1420  }
1421 
1422  ec_fsm_master_restart(fsm);
1423 }
1424 
1425 /****************************************************************************/
1426 
1430  ec_fsm_master_t *fsm
1431  )
1432 {
1433  ec_soe_request_t *request = fsm->soe_request;
1434 
1435  if (!request) {
1436  // configuration was cleared in the meantime
1437  ec_fsm_master_restart(fsm);
1438  return;
1439  }
1440 
1441  if (ec_fsm_soe_exec(&fsm->fsm_soe, fsm->datagram)) {
1442  return;
1443  }
1444 
1445  if (!ec_fsm_soe_success(&fsm->fsm_soe)) {
1446  EC_SLAVE_DBG(fsm->slave, 1,
1447  "Failed to process internal SoE request.\n");
1448  request->state = EC_INT_REQUEST_FAILURE;
1449  wake_up_all(&fsm->master->request_queue);
1450  ec_fsm_master_restart(fsm);
1451  return;
1452  }
1453 
1454  // SoE request finished
1455  request->state = EC_INT_REQUEST_SUCCESS;
1456  wake_up_all(&fsm->master->request_queue);
1457 
1458  EC_SLAVE_DBG(fsm->slave, 1, "Finished internal SoE request.\n");
1459 
1460  // check for another CoE/SoE request
1462  return; // processing another request
1463  }
1464 
1465  ec_fsm_master_restart(fsm);
1466 }
1467 
1468 /****************************************************************************/
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Definition: globals.h:47
void ec_fsm_master_state_configure_slave(ec_fsm_master_t *)
Master state: CONFIGURE SLAVE.
Definition: fsm_master.c:1016
uint16_t ring_position
Ring position for emergency requests.
Definition: reg_request.h:49
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:48
uint16_t offset
SII word offset.
Definition: fsm_master.h:48
CANopen over EtherCAT.
Definition: globals.h:146
uint16_t ring_position
Ring position.
Definition: slave.h:175
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
Definition: datagram.h:98
ec_datagram_t * datagram
datagram used in the state machine
Definition: fsm_master.h:62
ec_sii_write_request_t * sii_request
SII write request.
Definition: fsm_master.h:80
ec_sii_t sii
Extracted SII data.
Definition: slave.h:215
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:86
struct semaphore config_sem
Semaphore protecting the config_busy variable and the allow_config flag.
Definition: master.h:248
void ec_master_calc_dc(ec_master_t *master)
Distributed-clocks calculations.
Definition: master.c:2200
size_t transfer_size
Size of the data to transfer.
Definition: reg_request.h:47
void ec_slave_attach_pdo_names(ec_slave_t *slave)
Attach PDO names.
Definition: slave.c:791
struct list_head sii_requests
SII write requests.
Definition: master.h:297
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:98
ec_fsm_pdo_t fsm_pdo
PDO configuration state machine.
Definition: fsm_master.h:87
Finite state machine of an EtherCAT master.
Definition: fsm_master.h:60
ec_internal_request_state_t state
State of the request.
Definition: fsm_master.h:51
unsigned int slaves_responding[EC_MAX_NUM_DEVICES]
Number of responding slaves for every device.
Definition: fsm_master.h:72
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:401
void ec_fsm_master_reset(ec_fsm_master_t *fsm)
Reset state machine.
Definition: fsm_master.c:144
struct ec_slave ec_slave_t
Definition: globals.h:310
void ec_master_request_op(ec_master_t *master)
Request OP state for configured slaves.
Definition: master.c:2217
CANopen SDO request.
Definition: sdo_request.h:40
ec_slave_state_t current_state
Current application state.
Definition: slave.h:184
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:321
u64 ec_fsm_master_dc_offset64(ec_fsm_master_t *, u64, u64, unsigned long)
Configure 64 bit time offset.
Definition: fsm_master.c:1134
size_t nwords
Number of words.
Definition: fsm_master.h:49
void(* state)(ec_fsm_master_t *)
master state function
Definition: fsm_master.h:65
ec_internal_request_state_t state
SDO request state.
Definition: sdo_request.h:55
uint16_t address
Register address.
Definition: reg_request.h:46
Register request.
Definition: reg_request.h:40
struct list_head eoe_handlers
Ethernet over EtherCAT handlers.
Definition: master.h:283
Operation phase.
Definition: master.h:128
unsigned int allow_scan
True, if slave scanning is allowed.
Definition: master.h:241
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:82
void ec_fsm_master_restart(ec_fsm_master_t *)
Restarts the master state machine.
Definition: fsm_master.c:203
unsigned int rescan_required
A bus rescan is required.
Definition: fsm_master.h:75
EtherCAT datagram.
Definition: datagram.h:79
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:152
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:108
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3137
unsigned int scan_index
Index of slave currently scanned.
Definition: master.h:240
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:228
ec_slave_state_t slave_states[EC_MAX_NUM_DEVICES]
AL states of responding slaves for every device.
Definition: fsm_master.h:76
struct list_head emerg_reg_requests
Emergency register access requests.
Definition: master.h:298
#define EC_SYSTEM_TIME_TOLERANCE_NS
Time difference [ns] to tolerate without setting a new system time offset.
Definition: fsm_master.c:43
ec_fsm_slave_t fsm
Slave state machine.
Definition: slave.h:227
void ec_slave_set_state(ec_slave_t *slave, ec_slave_state_t new_state)
Sets the application state of a slave.
Definition: slave.c:284
uint16_t working_counter
Working counter.
Definition: datagram.h:93
void ec_fsm_eoe_init(ec_fsm_eoe_t *fsm)
Constructor.
Definition: fsm_eoe.c:77
int ec_sdo_request_timed_out(const ec_sdo_request_t *req)
Checks, if the timeout was exceeded.
Definition: sdo_request.c:171
int ec_fsm_master_action_process_int_request(ec_fsm_master_t *)
Check for pending internal SDO/SoE requests and process one.
Definition: fsm_master.c:522
void ec_fsm_master_action_idle(ec_fsm_master_t *)
Master action: IDLE.
Definition: fsm_master.c:605
int ec_eoe_init(ec_eoe_t *eoe, ec_slave_t *slave)
EoE constructor.
Definition: ethernet.c:111
Acknowledge/Error bit (no actual state)
Definition: globals.h:134
int ec_fsm_coe_success(const ec_fsm_coe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_coe.c:267
uint8_t link_state
device link state
Definition: device.h:80
void ec_fsm_master_state_dc_write_offset(ec_fsm_master_t *)
Master state: DC WRITE OFFSET.
Definition: fsm_master.c:1225
Sent (still in the queue).
Definition: datagram.h:69
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:301
void ec_fsm_sii_init(ec_fsm_sii_t *fsm, ec_datagram_t *datagram)
Constructor.
Definition: fsm_sii.c:66
EtherCAT master state machine.
uint16_t station_address
Configured station address.
Definition: slave.h:176
const char * ec_device_names[2]
Device names.
Definition: module.c:465
struct list_head list
List head.
Definition: fsm_master.h:46
SII write request.
Definition: fsm_master.h:45
void ec_fsm_master_action_next_slave_state(ec_fsm_master_t *)
Master action: Get state of next slave.
Definition: fsm_master.c:663
#define EC_WAIT_SDO_DICT
Seconds to wait before fetching SDO dictionary after slave entered PREOP state.
Definition: globals.h:51
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
void ec_fsm_master_enter_clear_addresses(ec_fsm_master_t *)
Start clearing slave addresses.
Definition: fsm_master.c:826
EtherCAT master structure.
void ec_fsm_master_init(ec_fsm_master_t *fsm, ec_master_t *master, ec_datagram_t *datagram)
Constructor.
Definition: fsm_master.c:82
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:100
int ec_fsm_master_action_process_sii(ec_fsm_master_t *)
Check for pending SII write requests and process one.
Definition: fsm_master.c:460
ec_slave_t * fsm_slave
Slave that is queried next for FSM exec.
Definition: master.h:271
ec_slave_t * slave
EtherCAT slave.
Definition: fsm_master.h:47
u64 ec_fsm_master_dc_offset32(ec_fsm_master_t *, u64, u64, unsigned long)
Configure 32 bit time offset.
Definition: fsm_master.c:1092
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:618
EtherCAT slave.
Definition: slave.h:168
void ec_master_attach_slave_configs(ec_master_t *master)
Attaches the slave configurations to the slaves.
Definition: master.c:1785
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:202
void ec_fsm_master_state_read_state(ec_fsm_master_t *)
Master state: READ STATE.
Definition: fsm_master.c:749
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:170
void ec_fsm_master_state_sdo_request(ec_fsm_master_t *)
Master state: SDO REQUEST.
Definition: fsm_master.c:1386
void ec_fsm_master_state_scan_slave(ec_fsm_master_t *)
Master state: SCAN SLAVE.
Definition: fsm_master.c:942
void ec_fsm_soe_transfer(ec_fsm_soe_t *fsm, ec_slave_t *slave, ec_soe_request_t *request)
Starts to transfer an IDN to/from a slave.
Definition: fsm_soe.c:130
int ec_fsm_soe_success(const ec_fsm_soe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_soe.c:187
Ethernet over EtherCAT (EoE)
ec_datagram_state_t state
State.
Definition: datagram.h:94
ec_slave_config_t * config
Current configuration.
Definition: slave.h:182
ec_master_phase_t phase
Master phase.
Definition: master.h:212
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3171
ec_fsm_sii_t fsm_sii
SII state machine.
Definition: fsm_master.h:92
ec_slave_t * slaves
Array of slaves on the bus.
Definition: master.h:220
uint8_t enable_sdo_info
SDO information service available.
Definition: globals.h:156
Use configured addresses.
Definition: fsm_sii.h:42
ec_fsm_eoe_t fsm_eoe
EoE state machine.
Definition: fsm_master.h:88
Slave configutation feature flag.
Definition: flag.h:38
ec_fsm_slave_scan_t fsm_slave_scan
slave state machine
Definition: fsm_master.h:91
Ethernet over EtherCAT.
Definition: globals.h:145
uint8_t sdo_dictionary_fetched
Dictionary has been fetched.
Definition: slave.h:218
struct list_head sdo_requests
List of SDO requests.
Definition: slave_config.h:137
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:139
void ec_fsm_master_action_configure(ec_fsm_master_t *)
Master action: Configure.
Definition: fsm_master.c:691
ec_flag_t * ec_slave_config_find_flag(ec_slave_config_t *sc, const char *key)
Finds a flag.
Definition: slave_config.c:638
ec_sdo_request_t * sdo_request
SDO request to process.
Definition: fsm_master.h:82
unsigned int debug_level
Master debug level.
Definition: master.h:275
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:68
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
Definition: datagram.c:594
ec_slave_dc_range_t base_dc_range
DC range.
Definition: slave.h:203
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:160
int ec_fsm_change_exec(ec_fsm_change_t *fsm)
Executes the current state of the state machine.
Definition: fsm_change.c:157
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
Definition: slave.h:207
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:221
unsigned int scan_busy
Current scan state.
Definition: master.h:239
ec_device_index_t
Master devices.
Definition: globals.h:198
void ec_fsm_master_state_dc_measure_delays(ec_fsm_master_t *)
Master state: DC MEASURE DELAYS.
Definition: fsm_master.c:887
void ec_fsm_master_state_broadcast(ec_fsm_master_t *)
Master state: BROADCAST.
Definition: fsm_master.c:278
void ec_fsm_pdo_init(ec_fsm_pdo_t *fsm, ec_fsm_coe_t *fsm_coe)
Constructor.
Definition: fsm_pdo.c:74
ec_soe_request_t * soe_request
SoE request to process.
Definition: fsm_master.h:83
void ec_fsm_coe_clear(ec_fsm_coe_t *fsm)
Destructor.
Definition: fsm_coe.c:187
uint16_t alias
Configured station alias.
Definition: slave.h:126
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:3154
unsigned long scan_jiffies
beginning of slave scanning
Definition: fsm_master.h:69
#define EC_ABS(X)
Absolute value.
Definition: globals.h:251
Main device.
Definition: globals.h:199
void ec_fsm_master_state_assign_sii(ec_fsm_master_t *)
Master state: ASSIGN SII.
Definition: fsm_master.c:1260
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:86
unsigned int active
Master has been activated.
Definition: master.h:213
ec_master_t * master
Master owning the slave.
Definition: slave.h:170
struct list_head soe_requests
List of SoE requests.
Definition: slave_config.h:138
void ec_fsm_change_clear(ec_fsm_change_t *fsm)
Destructor.
Definition: fsm_change.c:69
int ec_datagram_brd(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BRD datagram.
Definition: datagram.c:365
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:290
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:204
wait_queue_head_t scan_queue
Queue for processes that wait for slave scanning.
Definition: master.h:244
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:74
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:265
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:197
void ec_fsm_master_state_soe_request(ec_fsm_master_t *)
Master state: SoE REQUEST.
Definition: fsm_master.c:1429
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
Definition: datagram.h:84
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, ec_fsm_eoe_t *fsm_eoe)
Constructor.
int ec_fsm_master_idle(const ec_fsm_master_t *fsm)
Definition: fsm_master.c:192
32 bit.
Definition: globals.h:173
void ec_master_clear_slaves(ec_master_t *master)
Clear all slaves.
Definition: master.c:478
void ec_fsm_change_init(ec_fsm_change_t *fsm, ec_datagram_t *datagram)
Constructor.
Definition: fsm_change.c:54
struct list_head list
list item
Definition: ethernet.h:76
void ec_fsm_coe_init(ec_fsm_coe_t *fsm)
Constructor.
Definition: fsm_coe.c:175
void ec_fsm_master_state_acknowledge(ec_fsm_master_t *)
Master state: ACKNOWLEDGE.
Definition: fsm_master.c:804
void ec_fsm_eoe_clear(ec_fsm_eoe_t *fsm)
Destructor.
Definition: fsm_eoe.c:94
void ec_fsm_sii_clear(ec_fsm_sii_t *fsm)
Destructor.
Definition: fsm_sii.c:80
INIT state (no mailbox communication, no IO)
Definition: globals.h:124
int idle
state machine is in idle phase
Definition: fsm_master.h:68
struct semaphore scan_sem
Semaphore protecting the scan_busy variable and the allow_scan flag.
Definition: master.h:242
void ec_fsm_master_state_start(ec_fsm_master_t *)
Master state: START.
Definition: fsm_master.c:220
uint16_t effective_alias
Effective alias address.
Definition: slave.h:177
void ec_master_clear_eoe_handlers(ec_master_t *master)
Clear and free all EoE handlers.
Definition: master.c:442
ec_fsm_slave_config_t fsm_slave_config
slave state machine
Definition: fsm_master.h:90
int ec_fsm_sii_exec(ec_fsm_sii_t *fsm)
Executes the SII state machine.
Definition: fsm_sii.c:129
int ec_fsm_sii_success(ec_fsm_sii_t *fsm)
Returns, if the master startup state machine terminated with success.
Definition: fsm_sii.c:144
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3045
void ec_master_eoe_start(ec_master_t *master)
Starts Ethernet over EtherCAT processing on demand.
Definition: master.c:1673
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:557
Mailbox functionality.
ec_master_t * master
master the FSM runs on
Definition: fsm_master.h:61
void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *)
Master state: SDO DICTIONARY.
Definition: fsm_master.c:1351
uint8_t * data
Pointer to data memory.
Definition: reg_request.h:43
#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:3188
void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *)
Master state: CLEAR ADDRESSES.
Definition: fsm_master.c:842
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:233
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:60
ec_direction_t dir
Direction.
Definition: reg_request.h:44
Queued for sending.
Definition: datagram.h:68
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:140
Timed out (dequeued).
Definition: datagram.h:71
wait_queue_head_t config_queue
Queue for processes that wait for slave configuration.
Definition: master.h:250
int32_t value
Flag value (meaning depends on key).
Definition: flag.h:41
unsigned int retries
retries on datagram timeout.
Definition: fsm_master.h:63
void ec_fsm_slave_config_clear(ec_fsm_slave_config_t *fsm)
Destructor.
u64 app_time
Time of the last ecrt_master_sync() call.
Definition: master.h:227
unsigned long jiffies_preop
Time, the slave went to PREOP.
Definition: slave.h:219
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:202
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.
void ec_fsm_master_state_write_sii(ec_fsm_master_t *)
Master state: WRITE SII.
Definition: fsm_master.c:1297
uint8_t * data
Datagram payload.
Definition: datagram.h:88
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3029
EtherCAT slave configuration.
Definition: slave_config.h:111
int ec_soe_request_timed_out(const ec_soe_request_t *req)
Checks, if the timeout was exceeded.
Definition: soe_request.c:258
int ec_fsm_master_exec(ec_fsm_master_t *fsm)
Executes the current state of the state machine.
Definition: fsm_master.c:173
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:90
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:171
int ec_fsm_soe_exec(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_soe.c:152
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:210
ec_slave_t * slave
current slave
Definition: fsm_master.h:79
Values written by the master.
Definition: ecrt.h:506
ec_fsm_change_t fsm_change
State change state machine.
Definition: fsm_master.h:89
Received (dequeued).
Definition: datagram.h:70
Ethernet over EtherCAT (EoE) handler.
Definition: ethernet.h:74
off_t sii_index
index to SII write request data
Definition: fsm_master.h:81
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
Definition: master.h:62
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:185
unsigned int config_changed
The configuration changed.
Definition: master.h:214
EtherCAT master.
Definition: master.h:187
struct list_head list
List item.
Definition: reg_request.h:41
ec_slave_state_t requested_state
Requested application state.
Definition: slave.h:183
ec_device_index_t dev_idx
Current device index (for scanning etc.).
Definition: fsm_master.h:66
#define EC_READ_U64(DATA)
Read a 64-bit unsigned value from EtherCAT data.
Definition: ecrt.h:3077
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:200
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:52
unsigned int config_busy
State of slave configuration.
Definition: master.h:247
const uint16_t * words
Pointer to the data words.
Definition: fsm_master.h:50
void ec_fsm_master_clear(ec_fsm_master_t *fsm)
Destructor.
Definition: fsm_master.c:123
EtherCAT FoE state machines.
Sercos-over-EtherCAT request.
Definition: soe_request.h:40
unknown state
Definition: globals.h:122
void ec_fsm_master_enter_write_system_times(ec_fsm_master_t *)
Start writing DC system times.
Definition: fsm_master.c:1044
void ec_master_eoe_stop(ec_master_t *master)
Stops the Ethernet over EtherCAT processing.
Definition: master.c:1707
uint8_t link_state[EC_MAX_NUM_DEVICES]
Last link state for every device.
Definition: fsm_master.h:70
ec_fsm_coe_t fsm_coe
CoE state machine.
Definition: fsm_master.h:85
void ec_fsm_master_state_dc_read_offset(ec_fsm_master_t *)
Master state: DC READ OFFSET.
Definition: fsm_master.c:1172
unsigned int force_config
Force (re-)configuration.
Definition: slave.h:186
int ec_fsm_change_success(ec_fsm_change_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_change.c:172
unsigned int has_general
General category present.
Definition: slave.h:146
int ec_datagram_bwr(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BWR datagram.
Definition: datagram.c:385