IgH EtherCAT Master  1.6.0-rc1
fsm_slave.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 
41 #include "fsm_slave.h"
42 
43 /*****************************************************************************/
44 
55 #ifdef EC_EOE
58 #endif
61 
62 /*****************************************************************************/
63 
67  ec_fsm_slave_t *fsm,
68  ec_slave_t *slave
69  )
70 {
71  fsm->slave = slave;
72  INIT_LIST_HEAD(&fsm->list); // mark as unlisted
73 
75  fsm->datagram = NULL;
76  fsm->sdo_request = NULL;
77  fsm->reg_request = NULL;
78  fsm->foe_request = NULL;
79  fsm->soe_request = NULL;
80 #ifdef EC_EOE
81  fsm->eoe_request = NULL;
82 #endif
83 
84  // Init sub-state-machines
85  ec_fsm_coe_init(&fsm->fsm_coe);
86  ec_fsm_foe_init(&fsm->fsm_foe);
87  ec_fsm_soe_init(&fsm->fsm_soe);
88 #ifdef EC_EOE
89  ec_fsm_eoe_init(&fsm->fsm_eoe);
90 #endif
91 }
92 
93 /*****************************************************************************/
94 
98  ec_fsm_slave_t *fsm
99  )
100 {
101  // signal requests that are currently in operation
102 
103  if (fsm->sdo_request) {
104  fsm->sdo_request->state = EC_INT_REQUEST_FAILURE;
105  wake_up_all(&fsm->slave->master->request_queue);
106  }
107 
108  if (fsm->reg_request) {
109  fsm->reg_request->state = EC_INT_REQUEST_FAILURE;
110  wake_up_all(&fsm->slave->master->request_queue);
111  }
112 
113  if (fsm->foe_request) {
114  fsm->foe_request->state = EC_INT_REQUEST_FAILURE;
115  wake_up_all(&fsm->slave->master->request_queue);
116  }
117 
118  if (fsm->soe_request) {
119  fsm->soe_request->state = EC_INT_REQUEST_FAILURE;
120  wake_up_all(&fsm->slave->master->request_queue);
121  }
122 
123 #ifdef EC_EOE
124  if (fsm->eoe_request) {
125  fsm->eoe_request->state = EC_INT_REQUEST_FAILURE;
126  wake_up_all(&fsm->slave->master->request_queue);
127  }
128 #endif
129 
130  // clear sub-state machines
131  ec_fsm_coe_clear(&fsm->fsm_coe);
132  ec_fsm_foe_clear(&fsm->fsm_foe);
133  ec_fsm_soe_clear(&fsm->fsm_soe);
134 #ifdef EC_EOE
135  ec_fsm_eoe_clear(&fsm->fsm_eoe);
136 #endif
137 }
138 
139 /*****************************************************************************/
140 
146  ec_fsm_slave_t *fsm,
147  ec_datagram_t *datagram
148  )
149 {
150  int datagram_used;
151 
152  fsm->state(fsm, datagram);
153 
154  datagram_used = fsm->state != ec_fsm_slave_state_idle &&
156 
157  if (datagram_used) {
158  fsm->datagram = datagram;
159  } else {
160  fsm->datagram = NULL;
161  }
162 
163  return datagram_used;
164 }
165 
166 /*****************************************************************************/
167 
171  ec_fsm_slave_t *fsm
172  )
173 {
174  if (fsm->state == ec_fsm_slave_state_idle) {
175  EC_SLAVE_DBG(fsm->slave, 1, "Ready for requests.\n");
177  }
178 }
179 
180 /*****************************************************************************/
181 
187  const ec_fsm_slave_t *fsm
188  )
189 {
190  return fsm->state == ec_fsm_slave_state_ready;
191 }
192 
193 /******************************************************************************
194  * Slave state machine
195  *****************************************************************************/
196 
200  ec_fsm_slave_t *fsm,
201  ec_datagram_t *datagram
202  )
203 {
204  // do nothing
205 }
206 
207 /*****************************************************************************/
208 
212  ec_fsm_slave_t *fsm,
213  ec_datagram_t *datagram
214  )
215 {
216  ec_slave_t *slave = fsm->slave;
217  ec_sdo_request_t *req;
218 
219  if (slave->config) {
220  list_for_each_entry(req, &slave->config->sdo_requests, list) {
221  if (req->state == EC_INT_REQUEST_QUEUED || req->state == EC_INT_REQUEST_BUSY) {
222  EC_SLAVE_DBG(slave, 2, "Busy - processing internal SDO request %04X:%02X!\n", req->index, req->subindex);
223  return;
224  }
225  }
226  }
227 
228  // Check for pending external SDO requests
229  if (ec_fsm_slave_action_process_sdo(fsm, datagram)) {
230  return;
231  }
232 
233  // Check for pending external register requests
234  if (ec_fsm_slave_action_process_reg(fsm, datagram)) {
235  return;
236  }
237 
238  // Check for pending FoE requests
239  if (ec_fsm_slave_action_process_foe(fsm, datagram)) {
240  return;
241  }
242 
243  // Check for pending SoE requests
244  if (ec_fsm_slave_action_process_soe(fsm, datagram)) {
245  return;
246  }
247 
248 #ifdef EC_EOE
249  // Check for pending EoE IP parameter requests
250  if (ec_fsm_slave_action_process_eoe(fsm, datagram)) {
251  return;
252  }
253 #endif
254 
255  // Check for pending dictionary requests
256  if (ec_fsm_slave_action_process_dict(fsm, datagram)) {
257  return;
258  }
259 }
260 
261 /*****************************************************************************/
262 
268  ec_fsm_slave_t *fsm,
269  ec_datagram_t *datagram
270  )
271 {
272  ec_slave_t *slave = fsm->slave;
273  ec_sdo_request_t *request;
274 
275  if (list_empty(&slave->sdo_requests)) {
276  return 0;
277  }
278 
279  // take the first request to be processed
280  request = list_entry(slave->sdo_requests.next, ec_sdo_request_t, list);
281  list_del_init(&request->list); // dequeue
282 
283  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
284  EC_SLAVE_WARN(slave, "Aborting SDO request,"
285  " slave has error flag set.\n");
286  request->state = EC_INT_REQUEST_FAILURE;
287  wake_up_all(&slave->master->request_queue);
289  return 0;
290  }
291 
292  if (slave->current_state == EC_SLAVE_STATE_INIT) {
293  EC_SLAVE_WARN(slave, "Aborting SDO request, slave is in INIT.\n");
294  request->state = EC_INT_REQUEST_FAILURE;
295  wake_up_all(&slave->master->request_queue);
297  return 0;
298  }
299 
300  fsm->sdo_request = request;
301  request->state = EC_INT_REQUEST_BUSY;
302 
303  // Found pending SDO request. Execute it!
304  EC_SLAVE_DBG(slave, 1, "Processing SDO request...\n");
305 
306  // Start SDO transfer
308  ec_fsm_coe_transfer(&fsm->fsm_coe, slave, request);
309  ec_fsm_coe_exec(&fsm->fsm_coe, datagram); // execute immediately
310  return 1;
311 }
312 
313 /*****************************************************************************/
314 
318  ec_fsm_slave_t *fsm,
319  ec_datagram_t *datagram
320  )
321 {
322  ec_slave_t *slave = fsm->slave;
323  ec_sdo_request_t *request = fsm->sdo_request;
324 
325  if (ec_fsm_coe_exec(&fsm->fsm_coe, datagram)) {
326  return;
327  }
328 
329  if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
330  EC_SLAVE_ERR(slave, "Failed to process SDO request.\n");
331  request->state = EC_INT_REQUEST_FAILURE;
332  wake_up_all(&slave->master->request_queue);
333  fsm->sdo_request = NULL;
335  return;
336  }
337 
338  EC_SLAVE_DBG(slave, 1, "Finished SDO request.\n");
339 
340  // SDO request finished
341  request->state = EC_INT_REQUEST_SUCCESS;
342  wake_up_all(&slave->master->request_queue);
343  fsm->sdo_request = NULL;
345 }
346 
347 /*****************************************************************************/
348 
354  ec_fsm_slave_t *fsm,
355  ec_datagram_t *datagram
356  )
357 {
358  ec_slave_t *slave = fsm->slave;
359  ec_reg_request_t *reg;
360 
361  fsm->reg_request = NULL;
362 
363  if (slave->config) {
364  // search the first internal register request to be processed
365  list_for_each_entry(reg, &slave->config->reg_requests, list) {
366  if (reg->state == EC_INT_REQUEST_QUEUED) {
367  fsm->reg_request = reg;
368  break;
369  }
370  }
371  }
372 
373  if (!fsm->reg_request && !list_empty(&slave->reg_requests)) {
374  // take the first external request to be processed
375  fsm->reg_request =
376  list_entry(slave->reg_requests.next, ec_reg_request_t, list);
377  list_del_init(&fsm->reg_request->list); // dequeue
378  }
379 
380  if (!fsm->reg_request) { // no register request to process
381  return 0;
382  }
383 
384  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
385  EC_SLAVE_WARN(slave, "Aborting register request,"
386  " slave has error flag set.\n");
387  fsm->reg_request->state = EC_INT_REQUEST_FAILURE;
388  wake_up_all(&slave->master->request_queue);
389  fsm->reg_request = NULL;
391  return 0;
392  }
393 
394  // Found pending register request. Execute it!
395  EC_SLAVE_DBG(slave, 1, "Processing register request...\n");
396 
397  fsm->reg_request->state = EC_INT_REQUEST_BUSY;
398 
399  // Start register access
400  if (fsm->reg_request->dir == EC_DIR_INPUT) {
401  ec_datagram_fprd(datagram, slave->station_address,
403  ec_datagram_zero(datagram);
404  } else {
405  ec_datagram_fpwr(datagram, slave->station_address,
407  memcpy(datagram->data, fsm->reg_request->data,
408  fsm->reg_request->transfer_size);
409  }
410  datagram->device_index = slave->device_index;
412  return 1;
413 }
414 
415 /*****************************************************************************/
416 
420  ec_fsm_slave_t *fsm,
421  ec_datagram_t *datagram
422  )
423 {
424  ec_slave_t *slave = fsm->slave;
425  ec_reg_request_t *reg = fsm->reg_request;
426 
427  if (!reg) {
428  // configuration was cleared in the meantime
430  fsm->reg_request = NULL;
431  return;
432  }
433 
434  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
435  EC_SLAVE_ERR(slave, "Failed to receive register"
436  " request datagram: ");
438  reg->state = EC_INT_REQUEST_FAILURE;
439  wake_up_all(&slave->master->request_queue);
440  fsm->reg_request = NULL;
442  return;
443  }
444 
445  if (fsm->datagram->working_counter == 1) {
446  if (reg->dir == EC_DIR_INPUT) { // read request
447  memcpy(reg->data, fsm->datagram->data, reg->transfer_size);
448  }
449 
450  reg->state = EC_INT_REQUEST_SUCCESS;
451  EC_SLAVE_DBG(slave, 1, "Register request successful.\n");
452  } else {
453  reg->state = EC_INT_REQUEST_FAILURE;
455  EC_SLAVE_ERR(slave, "Register request failed"
456  " (working counter is %u).\n",
457  fsm->datagram->working_counter);
458  }
459 
460  wake_up_all(&slave->master->request_queue);
461  fsm->reg_request = NULL;
463 }
464 
465 /*****************************************************************************/
466 
472  ec_fsm_slave_t *fsm,
473  ec_datagram_t *datagram
474  )
475 {
476  ec_slave_t *slave = fsm->slave;
477  ec_foe_request_t *request;
478 
479  if (list_empty(&slave->foe_requests)) {
480  return 0;
481  }
482 
483  // take the first request to be processed
484  request = list_entry(slave->foe_requests.next, ec_foe_request_t, list);
485  list_del_init(&request->list); // dequeue
486 
487  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
488  EC_SLAVE_WARN(slave, "Aborting FoE request,"
489  " slave has error flag set.\n");
490  request->state = EC_INT_REQUEST_FAILURE;
491  wake_up_all(&slave->master->request_queue);
493  return 0;
494  }
495 
496  request->state = EC_INT_REQUEST_BUSY;
497  fsm->foe_request = request;
498 
499  EC_SLAVE_DBG(slave, 1, "Processing FoE request.\n");
500 
502  ec_fsm_foe_transfer(&fsm->fsm_foe, slave, request);
503  ec_fsm_foe_exec(&fsm->fsm_foe, datagram);
504  return 1;
505 }
506 
507 /*****************************************************************************/
508 
512  ec_fsm_slave_t *fsm,
513  ec_datagram_t *datagram
514  )
515 {
516  ec_slave_t *slave = fsm->slave;
517  ec_foe_request_t *request = fsm->foe_request;
518 
519  if (ec_fsm_foe_exec(&fsm->fsm_foe, datagram)) {
520  return;
521  }
522 
523  if (!ec_fsm_foe_success(&fsm->fsm_foe)) {
524  EC_SLAVE_ERR(slave, "Failed to handle FoE request.\n");
525  request->state = EC_INT_REQUEST_FAILURE;
526  wake_up_all(&slave->master->request_queue);
527  fsm->foe_request = NULL;
529  return;
530  }
531 
532  // finished transferring FoE
533  EC_SLAVE_DBG(slave, 1, "Successfully transferred %zu bytes of FoE"
534  " data.\n", request->data_size);
535 
536  request->state = EC_INT_REQUEST_SUCCESS;
537  wake_up_all(&slave->master->request_queue);
538  fsm->foe_request = NULL;
540 }
541 
542 /*****************************************************************************/
543 
549  ec_fsm_slave_t *fsm,
550  ec_datagram_t *datagram
551  )
552 {
553  ec_slave_t *slave = fsm->slave;
554  ec_soe_request_t *req;
555 
556  if (list_empty(&slave->soe_requests)) {
557  return 0;
558  }
559 
560  // take the first request to be processed
561  req = list_entry(slave->soe_requests.next, ec_soe_request_t, list);
562  list_del_init(&req->list); // dequeue
563 
564  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
565  EC_SLAVE_WARN(slave, "Aborting SoE request,"
566  " slave has error flag set.\n");
567  req->state = EC_INT_REQUEST_FAILURE;
568  wake_up_all(&slave->master->request_queue);
570  return 0;
571  }
572 
573  if (slave->current_state == EC_SLAVE_STATE_INIT) {
574  EC_SLAVE_WARN(slave, "Aborting SoE request, slave is in INIT.\n");
575  req->state = EC_INT_REQUEST_FAILURE;
576  wake_up_all(&slave->master->request_queue);
578  return 0;
579  }
580 
581  fsm->soe_request = req;
582  req->state = EC_INT_REQUEST_BUSY;
583 
584  // Found pending request. Execute it!
585  EC_SLAVE_DBG(slave, 1, "Processing SoE request...\n");
586 
587  // Start SoE transfer
589  ec_fsm_soe_transfer(&fsm->fsm_soe, slave, req);
590  ec_fsm_soe_exec(&fsm->fsm_soe, datagram); // execute immediately
591  return 1;
592 }
593 
594 /*****************************************************************************/
595 
599  ec_fsm_slave_t *fsm,
600  ec_datagram_t *datagram
601  )
602 {
603  ec_slave_t *slave = fsm->slave;
604  ec_soe_request_t *request = fsm->soe_request;
605 
606  if (ec_fsm_soe_exec(&fsm->fsm_soe, datagram)) {
607  return;
608  }
609 
610  if (!ec_fsm_soe_success(&fsm->fsm_soe)) {
611  EC_SLAVE_ERR(slave, "Failed to process SoE request.\n");
612  request->state = EC_INT_REQUEST_FAILURE;
613  wake_up_all(&slave->master->request_queue);
614  fsm->soe_request = NULL;
616  return;
617  }
618 
619  EC_SLAVE_DBG(slave, 1, "Finished SoE request.\n");
620 
621  // SoE request finished
622  request->state = EC_INT_REQUEST_SUCCESS;
623  wake_up_all(&slave->master->request_queue);
624  fsm->soe_request = NULL;
626 }
627 
628 /*****************************************************************************/
629 
635  ec_fsm_slave_t *fsm,
636  ec_datagram_t *datagram
637  )
638 {
639  ec_slave_t *slave = fsm->slave;
640  ec_dict_request_t *request;
641 
642  if (list_empty(&slave->dict_requests)) {
643  return 0;
644  }
645 
646  // take the first request to be processed
647  request = list_entry(slave->dict_requests.next, ec_dict_request_t, list);
648  list_del_init(&request->list); // dequeue
649 
650  if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)
651  || (slave->sii.has_general
652  && !slave->sii.coe_details.enable_sdo_info))
653  {
654  EC_SLAVE_INFO(slave, "Aborting dictionary request,"
655  " slave does not support SDO Info.\n");
656  request->state = EC_INT_REQUEST_SUCCESS;
657  wake_up_all(&slave->master->request_queue);
658  fsm->dict_request = NULL;
660  return 1;
661  }
662 
663  if (slave->sdo_dictionary_fetched)
664  {
665  EC_SLAVE_DBG(slave, 1, "Aborting dictionary request,"
666  " dictionary already uploaded.\n");
667  request->state = EC_INT_REQUEST_SUCCESS;
668  wake_up_all(&slave->master->request_queue);
669  fsm->dict_request = NULL;
671  return 1;
672  }
673 
674  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
675  EC_SLAVE_WARN(slave, "Aborting dictionary request,"
676  " slave has error flag set.\n");
677  request->state = EC_INT_REQUEST_FAILURE;
678  wake_up_all(&slave->master->request_queue);
680  return 1;
681  }
682 
683  if (slave->current_state == EC_SLAVE_STATE_INIT) {
684  EC_SLAVE_WARN(slave, "Aborting dictioanry request, slave is in INIT.\n");
685  request->state = EC_INT_REQUEST_FAILURE;
686  wake_up_all(&slave->master->request_queue);
688  return 1;
689  }
690 
691  fsm->dict_request = request;
692  request->state = EC_INT_REQUEST_BUSY;
693 
694  // Found pending dictionary request. Execute it!
695  EC_SLAVE_DBG(slave, 1, "Processing dictionary request...\n");
696 
697  // Start dictionary transfer
699  ec_fsm_coe_dictionary(&fsm->fsm_coe, slave);
700  ec_fsm_coe_exec(&fsm->fsm_coe, datagram); // execute immediately
701  return 1;
702 }
703 
704 /*****************************************************************************/
705 
709  ec_fsm_slave_t *fsm,
710  ec_datagram_t *datagram
711  )
712 {
713  ec_slave_t *slave = fsm->slave;
714  ec_dict_request_t *request = fsm->dict_request;
715 
716  if (ec_fsm_coe_exec(&fsm->fsm_coe, datagram)) {
717  return;
718  }
719 
720  if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
721  EC_SLAVE_ERR(slave, "Failed to process dictionary request.\n");
722  request->state = EC_INT_REQUEST_FAILURE;
723  wake_up_all(&slave->master->request_queue);
724  fsm->dict_request = NULL;
726  return;
727  }
728 
729  EC_SLAVE_DBG(slave, 1, "Finished dictionary request.\n");
730 
731  // Dictionary request finished
732  slave->sdo_dictionary_fetched = 1;
733 
734  // attach pdo names from dictionary
736 
737  request->state = EC_INT_REQUEST_SUCCESS;
738  wake_up_all(&slave->master->request_queue);
739  fsm->dict_request = NULL;
741 }
742 
743 /*****************************************************************************/
744 #ifdef EC_EOE
745 
750  ec_fsm_slave_t *fsm,
751  ec_datagram_t *datagram
752  )
753 {
754  ec_slave_t *slave = fsm->slave;
755  ec_eoe_request_t *request;
756 
757  if (list_empty(&slave->eoe_requests)) {
758  return 0;
759  }
760 
761  // take the first request to be processed
762  request = list_entry(slave->eoe_requests.next, ec_eoe_request_t, list);
763  list_del_init(&request->list); // dequeue
764 
765  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
766  EC_SLAVE_WARN(slave, "Aborting EoE request,"
767  " slave has error flag set.\n");
768  request->state = EC_INT_REQUEST_FAILURE;
769  wake_up_all(&slave->master->request_queue);
771  return 0;
772  }
773 
774  if (slave->current_state == EC_SLAVE_STATE_INIT) {
775  EC_SLAVE_WARN(slave, "Aborting EoE request, slave is in INIT.\n");
776  request->state = EC_INT_REQUEST_FAILURE;
777  wake_up_all(&slave->master->request_queue);
779  return 0;
780  }
781 
782  fsm->eoe_request = request;
783  request->state = EC_INT_REQUEST_BUSY;
784 
785  // Found pending request. Execute it!
786  EC_SLAVE_DBG(slave, 1, "Processing EoE request...\n");
787 
788  // Start EoE command
790  ec_fsm_eoe_set_ip_param(&fsm->fsm_eoe, slave, request);
791  ec_fsm_eoe_exec(&fsm->fsm_eoe, datagram); // execute immediately
792  return 1;
793 }
794 
795 /*****************************************************************************/
796 
800  ec_fsm_slave_t *fsm,
801  ec_datagram_t *datagram
802  )
803 {
804  ec_slave_t *slave = fsm->slave;
805  ec_eoe_request_t *req = fsm->eoe_request;
806 
807  if (ec_fsm_eoe_exec(&fsm->fsm_eoe, datagram)) {
808  return;
809  }
810 
811  if (ec_fsm_eoe_success(&fsm->fsm_eoe)) {
812  req->state = EC_INT_REQUEST_SUCCESS;
813  EC_SLAVE_DBG(slave, 1, "Finished EoE request.\n");
814  }
815  else {
816  req->state = EC_INT_REQUEST_FAILURE;
817  EC_SLAVE_ERR(slave, "Failed to process EoE request.\n");
818  }
819 
820  wake_up_all(&slave->master->request_queue);
821  fsm->eoe_request = NULL;
823 }
824 #endif
825 
826 /*****************************************************************************/
int ec_fsm_eoe_exec(ec_fsm_eoe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_eoe.c:106
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:56
void ec_fsm_slave_clear(ec_fsm_slave_t *fsm)
Destructor.
Definition: fsm_slave.c:97
ec_sii_t sii
Extracted SII data.
Definition: slave.h:246
int ec_fsm_foe_success(const ec_fsm_foe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_foe.c:162
size_t transfer_size
Size of the data to transfer.
Definition: reg_request.h:55
ec_dict_request_t * dict_request
Dictionary request to process.
Definition: fsm_slave.h:73
void ec_slave_attach_pdo_names(ec_slave_t *slave)
Attach PDO names.
Definition: slave.c:903
ec_foe_request_t * foe_request
FoE request to process.
Definition: fsm_slave.h:67
void ec_fsm_foe_clear(ec_fsm_foe_t *fsm)
Destructor.
Definition: fsm_foe.c:118
struct list_head list
List item.
Definition: soe_request.h:49
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:107
ec_reg_request_t * reg_request
Register request to process.
Definition: fsm_slave.h:66
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
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
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:91
EtherCAT datagram.
Definition: datagram.h:88
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:183
uint16_t index
SDO index.
Definition: sdo_request.h:50
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:58
ec_fsm_soe_t fsm_soe
SoE state machine.
Definition: fsm_slave.h:77
Finite state machine of an EtherCAT slave.
Definition: fsm_slave.h:59
ec_datagram_t * datagram
Previous state datagram.
Definition: fsm_slave.h:64
struct list_head reg_requests
Register access requests.
Definition: slave.h:253
uint16_t working_counter
Working counter.
Definition: datagram.h:100
void ec_fsm_eoe_init(ec_fsm_eoe_t *fsm)
Constructor.
Definition: fsm_eoe.c:63
void ec_fsm_foe_transfer(ec_fsm_foe_t *fsm, ec_slave_t *slave, ec_foe_request_t *request)
Prepares an FoE transfer.
Definition: fsm_foe.c:171
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
int ec_fsm_slave_action_process_foe(ec_fsm_slave_t *, ec_datagram_t *)
Check for pending FoE requests and process one.
Definition: fsm_slave.c:471
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:308
ec_sdo_request_t * sdo_request
SDO request to process.
Definition: fsm_slave.h:65
uint16_t station_address
Configured station address.
Definition: slave.h:207
void ec_fsm_eoe_set_ip_param(ec_fsm_eoe_t *fsm, ec_slave_t *slave, ec_eoe_request_t *request)
Starts to set the EoE IP partameters of a slave.
Definition: fsm_eoe.c:89
Global definitions and macros.
EtherCAT master structure.
EtherCAT slave.
Definition: slave.h:199
ec_eoe_request_t * eoe_request
EoE request to process.
Definition: fsm_slave.h:71
ec_slave_t * slave
slave the FSM runs on
Definition: fsm_slave.h:60
struct list_head sdo_requests
SDO access requests.
Definition: slave.h:252
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:179
void ec_fsm_slave_state_soe_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: SOE_REQUEST.
Definition: fsm_slave.c:598
void ec_fsm_foe_init(ec_fsm_foe_t *fsm)
Constructor.
Definition: fsm_foe.c:106
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
struct list_head soe_requests
SoE requests.
Definition: slave.h:255
ec_datagram_state_t state
State.
Definition: datagram.h:101
CANopen over EtherCAT.
Definition: globals.h:152
ec_slave_config_t * config
Current configuration.
Definition: slave.h:213
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:149
int ec_fsm_slave_action_process_reg(ec_fsm_slave_t *, ec_datagram_t *)
Check for pending register requests and process one.
Definition: fsm_slave.c:353
uint8_t enable_sdo_info
SDO information service available.
Definition: globals.h:162
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
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:170
void ec_fsm_slave_state_eoe_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: EOE_REQUEST.
Definition: fsm_slave.c:799
void ec_fsm_slave_state_ready(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: READY.
Definition: fsm_slave.c:211
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:77
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
ec_soe_request_t * soe_request
SoE request to process.
Definition: fsm_slave.h:69
void ec_fsm_coe_clear(ec_fsm_coe_t *fsm)
Destructor.
Definition: fsm_coe.c:189
ec_fsm_eoe_t fsm_eoe
EoE state machine.
Definition: fsm_slave.h:79
int ec_fsm_eoe_success(const ec_fsm_eoe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_eoe.c:141
int ec_fsm_slave_exec(ec_fsm_slave_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_slave.c:145
ec_master_t * master
Master owning the slave.
Definition: slave.h:201
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
void ec_fsm_slave_state_sdo_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: SDO_REQUEST.
Definition: fsm_slave.c:317
void ec_fsm_slave_state_foe_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: FOE REQUEST.
Definition: fsm_slave.c:511
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' SDO dictionary.
Definition: fsm_coe.c:199
Values read by the master.
Definition: ecrt.h:438
int ec_fsm_slave_action_process_dict(ec_fsm_slave_t *, ec_datagram_t *)
Check for pending dictionary requests and process one.
Definition: fsm_slave.c:634
CANopen dictionary request.
Definition: dict_request.h:48
int ec_fsm_slave_action_process_eoe(ec_fsm_slave_t *, ec_datagram_t *)
Check for pending EoE IP parameter requests and process one.
Definition: fsm_slave.c:749
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
Definition: datagram.h:91
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
#define EC_SLAVE_INFO(slave, fmt, args...)
Convenience macro for printing slave-specific information to syslog.
Definition: slave.h:63
struct list_head list
List item.
Definition: dict_request.h:49
void ec_fsm_coe_init(ec_fsm_coe_t *fsm)
Constructor.
Definition: fsm_coe.c:177
Ethernet-over-EtherCAT set IP parameter request.
Definition: eoe_request.h:49
void ec_fsm_eoe_clear(ec_fsm_eoe_t *fsm)
Destructor.
Definition: fsm_eoe.c:79
INIT state (no mailbox communication, no IO)
Definition: globals.h:130
uint8_t subindex
SDO subindex.
Definition: sdo_request.h:51
FoE request.
Definition: foe_request.h:50
ec_internal_request_state_t state
Request state.
Definition: eoe_request.h:51
struct list_head foe_requests
FoE requests.
Definition: slave.h:254
int ec_fsm_foe_exec(ec_fsm_foe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_foe.c:128
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:566
Mailbox functionality.
struct list_head list
Used for execution list.
Definition: fsm_slave.h:61
uint8_t * data
Pointer to data memory.
Definition: reg_request.h:51
struct list_head list
List item.
Definition: sdo_request.h:49
void ec_fsm_slave_init(ec_fsm_slave_t *fsm, ec_slave_t *slave)
Constructor.
Definition: fsm_slave.c:66
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
EtherCAT slave request state machine.
ec_direction_t dir
Direction.
Definition: reg_request.h:52
void ec_fsm_slave_state_idle(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: IDLE.
Definition: fsm_slave.c:199
ec_fsm_foe_t fsm_foe
FoE state machine.
Definition: fsm_slave.h:76
void ec_fsm_soe_init(ec_fsm_soe_t *fsm)
Constructor.
Definition: fsm_soe.c:107
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
Definition: fsm_soe.c:120
uint8_t * data
Datagram payload.
Definition: datagram.h:95
struct list_head dict_requests
Dictionary read requests.
Definition: slave.h:257
ec_fsm_coe_t fsm_coe
CoE state machine.
Definition: fsm_slave.h:75
EtherCAT slave configuration structure.
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:63
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:202
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:212
int ec_fsm_slave_action_process_soe(ec_fsm_slave_t *, ec_datagram_t *)
Check for pending SoE requests and process one.
Definition: fsm_slave.c:548
Received (dequeued).
Definition: datagram.h:78
struct list_head list
List item.
Definition: reg_request.h:49
struct list_head eoe_requests
EoE set IP parameter requests.
Definition: slave.h:256
void(* state)(ec_fsm_slave_t *, ec_datagram_t *)
State function.
Definition: fsm_slave.h:63
struct list_head list
List item.
Definition: eoe_request.h:50
void ec_fsm_slave_state_reg_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: Register request.
Definition: fsm_slave.c:419
int ec_fsm_slave_action_process_sdo(ec_fsm_slave_t *, ec_datagram_t *)
Check for pending SDO requests and process one.
Definition: fsm_slave.c:267
struct list_head list
List item.
Definition: foe_request.h:51
unsigned int has_general
General category present.
Definition: slave.h:177
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
ec_internal_request_state_t state
SDO request state.
Definition: dict_request.h:50
void ec_fsm_slave_state_dict_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: DICT_REQUEST.
Definition: fsm_slave.c:708