IgH EtherCAT Master  1.6.1
fsm_slave.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 
33 #include "fsm_slave.h"
34 
35 /****************************************************************************/
36 
47 #ifdef EC_EOE
50 #endif
51 
52 /****************************************************************************/
53 
57  ec_fsm_slave_t *fsm,
58  ec_slave_t *slave
59  )
60 {
61  fsm->slave = slave;
62  INIT_LIST_HEAD(&fsm->list); // mark as unlisted
63 
65  fsm->datagram = NULL;
66  fsm->sdo_request = NULL;
67  fsm->reg_request = NULL;
68  fsm->foe_request = NULL;
69  fsm->soe_request = NULL;
70 #ifdef EC_EOE
71  fsm->eoe_request = NULL;
72 #endif
73 
74  // Init sub-state-machines
75  ec_fsm_coe_init(&fsm->fsm_coe);
76  ec_fsm_foe_init(&fsm->fsm_foe);
77  ec_fsm_soe_init(&fsm->fsm_soe);
78 #ifdef EC_EOE
79  ec_fsm_eoe_init(&fsm->fsm_eoe);
80 #endif
81 }
82 
83 /****************************************************************************/
84 
88  ec_fsm_slave_t *fsm
89  )
90 {
91  // signal requests that are currently in operation
92 
93  if (fsm->sdo_request) {
94  fsm->sdo_request->state = EC_INT_REQUEST_FAILURE;
95  wake_up_all(&fsm->slave->master->request_queue);
96  }
97 
98  if (fsm->reg_request) {
99  fsm->reg_request->state = EC_INT_REQUEST_FAILURE;
100  wake_up_all(&fsm->slave->master->request_queue);
101  }
102 
103  if (fsm->foe_request) {
104  fsm->foe_request->state = EC_INT_REQUEST_FAILURE;
105  wake_up_all(&fsm->slave->master->request_queue);
106  }
107 
108  if (fsm->soe_request) {
109  fsm->soe_request->state = EC_INT_REQUEST_FAILURE;
110  wake_up_all(&fsm->slave->master->request_queue);
111  }
112 
113 #ifdef EC_EOE
114  if (fsm->eoe_request) {
115  fsm->soe_request->state = EC_INT_REQUEST_FAILURE;
116  wake_up_all(&fsm->slave->master->request_queue);
117  }
118 #endif
119 
120  // clear sub-state machines
121  ec_fsm_coe_clear(&fsm->fsm_coe);
122  ec_fsm_foe_clear(&fsm->fsm_foe);
123  ec_fsm_soe_clear(&fsm->fsm_soe);
124 #ifdef EC_EOE
125  ec_fsm_eoe_clear(&fsm->fsm_eoe);
126 #endif
127 }
128 
129 /****************************************************************************/
130 
136  ec_fsm_slave_t *fsm,
137  ec_datagram_t *datagram
138  )
139 {
140  int datagram_used;
141 
142  fsm->state(fsm, datagram);
143 
144  datagram_used = fsm->state != ec_fsm_slave_state_idle &&
146 
147  if (datagram_used) {
148  fsm->datagram = datagram;
149  } else {
150  fsm->datagram = NULL;
151  }
152 
153  return datagram_used;
154 }
155 
156 /****************************************************************************/
157 
161  ec_fsm_slave_t *fsm
162  )
163 {
164  if (fsm->state == ec_fsm_slave_state_idle) {
165  EC_SLAVE_DBG(fsm->slave, 1, "Ready for requests.\n");
167  }
168 }
169 
170 /****************************************************************************/
171 
177  const ec_fsm_slave_t *fsm
178  )
179 {
180  return fsm->state == ec_fsm_slave_state_ready;
181 }
182 
183 /*****************************************************************************
184  * Slave state machine
185  ****************************************************************************/
186 
190  ec_fsm_slave_t *fsm,
191  ec_datagram_t *datagram
192  )
193 {
194  // do nothing
195 }
196 
197 /****************************************************************************/
198 
202  ec_fsm_slave_t *fsm,
203  ec_datagram_t *datagram
204  )
205 {
206  // Check for pending external SDO requests
207  if (ec_fsm_slave_action_process_sdo(fsm, datagram)) {
208  return;
209  }
210 
211  // Check for pending external register requests
212  if (ec_fsm_slave_action_process_reg(fsm, datagram)) {
213  return;
214  }
215 
216  // Check for pending FoE requests
217  if (ec_fsm_slave_action_process_foe(fsm, datagram)) {
218  return;
219  }
220 
221  // Check for pending SoE requests
222  if (ec_fsm_slave_action_process_soe(fsm, datagram)) {
223  return;
224  }
225 
226 #ifdef EC_EOE
227  // Check for pending EoE IP parameter requests
228  if (ec_fsm_slave_action_process_eoe(fsm, datagram)) {
229  return;
230  }
231 #endif
232 }
233 
234 /****************************************************************************/
235 
241  ec_fsm_slave_t *fsm,
242  ec_datagram_t *datagram
243  )
244 {
245  ec_slave_t *slave = fsm->slave;
246  ec_sdo_request_t *request;
247 
248  if (list_empty(&slave->sdo_requests)) {
249  return 0;
250  }
251 
252  // take the first request to be processed
253  request = list_entry(slave->sdo_requests.next, ec_sdo_request_t, list);
254  list_del_init(&request->list); // dequeue
255 
256  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
257  EC_SLAVE_WARN(slave, "Aborting SDO request,"
258  " slave has error flag set.\n");
259  request->state = EC_INT_REQUEST_FAILURE;
260  wake_up_all(&slave->master->request_queue);
262  return 0;
263  }
264 
265  if (slave->current_state == EC_SLAVE_STATE_INIT) {
266  EC_SLAVE_WARN(slave, "Aborting SDO request, slave is in INIT.\n");
267  request->state = EC_INT_REQUEST_FAILURE;
268  wake_up_all(&slave->master->request_queue);
270  return 0;
271  }
272 
273  fsm->sdo_request = request;
274  request->state = EC_INT_REQUEST_BUSY;
275 
276  // Found pending SDO request. Execute it!
277  EC_SLAVE_DBG(slave, 1, "Processing SDO request...\n");
278 
279  // Start SDO transfer
281  ec_fsm_coe_transfer(&fsm->fsm_coe, slave, request);
282  ec_fsm_coe_exec(&fsm->fsm_coe, datagram); // execute immediately
283  return 1;
284 }
285 
286 /****************************************************************************/
287 
291  ec_fsm_slave_t *fsm,
292  ec_datagram_t *datagram
293  )
294 {
295  ec_slave_t *slave = fsm->slave;
296  ec_sdo_request_t *request = fsm->sdo_request;
297 
298  if (ec_fsm_coe_exec(&fsm->fsm_coe, datagram)) {
299  return;
300  }
301 
302  if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
303  EC_SLAVE_ERR(slave, "Failed to process SDO request.\n");
304  request->state = EC_INT_REQUEST_FAILURE;
305  wake_up_all(&slave->master->request_queue);
306  fsm->sdo_request = NULL;
308  return;
309  }
310 
311  EC_SLAVE_DBG(slave, 1, "Finished SDO request.\n");
312 
313  // SDO request finished
314  request->state = EC_INT_REQUEST_SUCCESS;
315  wake_up_all(&slave->master->request_queue);
316  fsm->sdo_request = NULL;
318 }
319 
320 /****************************************************************************/
321 
327  ec_fsm_slave_t *fsm,
328  ec_datagram_t *datagram
329  )
330 {
331  ec_slave_t *slave = fsm->slave;
332  ec_reg_request_t *reg;
333 
334  fsm->reg_request = NULL;
335 
336  if (slave->config) {
337  // search the first internal register request to be processed
338  list_for_each_entry(reg, &slave->config->reg_requests, list) {
339  if (reg->state == EC_INT_REQUEST_QUEUED) {
340  fsm->reg_request = reg;
341  break;
342  }
343  }
344  }
345 
346  if (!fsm->reg_request && !list_empty(&slave->reg_requests)) {
347  // take the first external request to be processed
348  fsm->reg_request =
349  list_entry(slave->reg_requests.next, ec_reg_request_t, list);
350  list_del_init(&fsm->reg_request->list); // dequeue
351  }
352 
353  if (!fsm->reg_request) { // no register request to process
354  return 0;
355  }
356 
357  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
358  EC_SLAVE_WARN(slave, "Aborting register request,"
359  " slave has error flag set.\n");
360  fsm->reg_request->state = EC_INT_REQUEST_FAILURE;
361  wake_up_all(&slave->master->request_queue);
362  fsm->reg_request = NULL;
364  return 0;
365  }
366 
367  // Found pending register request. Execute it!
368  EC_SLAVE_DBG(slave, 1, "Processing register request...\n");
369 
370  fsm->reg_request->state = EC_INT_REQUEST_BUSY;
371 
372  // Start register access
373  if (fsm->reg_request->dir == EC_DIR_INPUT) {
374  ec_datagram_fprd(datagram, slave->station_address,
376  ec_datagram_zero(datagram);
377  } else {
378  ec_datagram_fpwr(datagram, slave->station_address,
380  memcpy(datagram->data, fsm->reg_request->data,
381  fsm->reg_request->transfer_size);
382  }
383  datagram->device_index = slave->device_index;
385  return 1;
386 }
387 
388 /****************************************************************************/
389 
393  ec_fsm_slave_t *fsm,
394  ec_datagram_t *datagram
395  )
396 {
397  ec_slave_t *slave = fsm->slave;
398  ec_reg_request_t *reg = fsm->reg_request;
399 
400  if (!reg) {
401  // configuration was cleared in the meantime
403  fsm->reg_request = NULL;
404  return;
405  }
406 
407  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
408  EC_SLAVE_ERR(slave, "Failed to receive register"
409  " request datagram: ");
411  reg->state = EC_INT_REQUEST_FAILURE;
412  wake_up_all(&slave->master->request_queue);
413  fsm->reg_request = NULL;
415  return;
416  }
417 
418  if (fsm->datagram->working_counter == 1) {
419  if (reg->dir == EC_DIR_INPUT) { // read request
420  memcpy(reg->data, fsm->datagram->data, reg->transfer_size);
421  }
422 
423  reg->state = EC_INT_REQUEST_SUCCESS;
424  EC_SLAVE_DBG(slave, 1, "Register request successful.\n");
425  } else {
426  reg->state = EC_INT_REQUEST_FAILURE;
428  EC_SLAVE_ERR(slave, "Register request failed"
429  " (working counter is %u).\n",
430  fsm->datagram->working_counter);
431  }
432 
433  wake_up_all(&slave->master->request_queue);
434  fsm->reg_request = NULL;
436 }
437 
438 /****************************************************************************/
439 
445  ec_fsm_slave_t *fsm,
446  ec_datagram_t *datagram
447  )
448 {
449  ec_slave_t *slave = fsm->slave;
450  ec_foe_request_t *request;
451 
452  if (list_empty(&slave->foe_requests)) {
453  return 0;
454  }
455 
456  // take the first request to be processed
457  request = list_entry(slave->foe_requests.next, ec_foe_request_t, list);
458  list_del_init(&request->list); // dequeue
459 
460  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
461  EC_SLAVE_WARN(slave, "Aborting FoE request,"
462  " slave has error flag set.\n");
463  request->state = EC_INT_REQUEST_FAILURE;
464  wake_up_all(&slave->master->request_queue);
466  return 0;
467  }
468 
469  request->state = EC_INT_REQUEST_BUSY;
470  fsm->foe_request = request;
471 
472  EC_SLAVE_DBG(slave, 1, "Processing FoE request.\n");
473 
475  ec_fsm_foe_transfer(&fsm->fsm_foe, slave, request);
476  ec_fsm_foe_exec(&fsm->fsm_foe, datagram);
477  return 1;
478 }
479 
480 /****************************************************************************/
481 
485  ec_fsm_slave_t *fsm,
486  ec_datagram_t *datagram
487  )
488 {
489  ec_slave_t *slave = fsm->slave;
490  ec_foe_request_t *request = fsm->foe_request;
491 
492  if (ec_fsm_foe_exec(&fsm->fsm_foe, datagram)) {
493  return;
494  }
495 
496  if (!ec_fsm_foe_success(&fsm->fsm_foe)) {
497  EC_SLAVE_ERR(slave, "Failed to handle FoE request.\n");
498  request->state = EC_INT_REQUEST_FAILURE;
499  wake_up_all(&slave->master->request_queue);
500  fsm->foe_request = NULL;
502  return;
503  }
504 
505  // finished transferring FoE
506  EC_SLAVE_DBG(slave, 1, "Successfully transferred %zu bytes of FoE"
507  " data.\n", request->data_size);
508 
509  request->state = EC_INT_REQUEST_SUCCESS;
510  wake_up_all(&slave->master->request_queue);
511  fsm->foe_request = NULL;
513 }
514 
515 /****************************************************************************/
516 
522  ec_fsm_slave_t *fsm,
523  ec_datagram_t *datagram
524  )
525 {
526  ec_slave_t *slave = fsm->slave;
527  ec_soe_request_t *req;
528 
529  if (list_empty(&slave->soe_requests)) {
530  return 0;
531  }
532 
533  // take the first request to be processed
534  req = list_entry(slave->soe_requests.next, ec_soe_request_t, list);
535  list_del_init(&req->list); // dequeue
536 
537  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
538  EC_SLAVE_WARN(slave, "Aborting SoE request,"
539  " slave has error flag set.\n");
540  req->state = EC_INT_REQUEST_FAILURE;
541  wake_up_all(&slave->master->request_queue);
543  return 0;
544  }
545 
546  if (slave->current_state == EC_SLAVE_STATE_INIT) {
547  EC_SLAVE_WARN(slave, "Aborting SoE request, slave is in INIT.\n");
548  req->state = EC_INT_REQUEST_FAILURE;
549  wake_up_all(&slave->master->request_queue);
551  return 0;
552  }
553 
554  fsm->soe_request = req;
555  req->state = EC_INT_REQUEST_BUSY;
556 
557  // Found pending request. Execute it!
558  EC_SLAVE_DBG(slave, 1, "Processing SoE request...\n");
559 
560  // Start SoE transfer
562  ec_fsm_soe_transfer(&fsm->fsm_soe, slave, req);
563  ec_fsm_soe_exec(&fsm->fsm_soe, datagram); // execute immediately
564  return 1;
565 }
566 
567 /****************************************************************************/
568 
572  ec_fsm_slave_t *fsm,
573  ec_datagram_t *datagram
574  )
575 {
576  ec_slave_t *slave = fsm->slave;
577  ec_soe_request_t *request = fsm->soe_request;
578 
579  if (ec_fsm_soe_exec(&fsm->fsm_soe, datagram)) {
580  return;
581  }
582 
583  if (!ec_fsm_soe_success(&fsm->fsm_soe)) {
584  EC_SLAVE_ERR(slave, "Failed to process SoE request.\n");
585  request->state = EC_INT_REQUEST_FAILURE;
586  wake_up_all(&slave->master->request_queue);
587  fsm->soe_request = NULL;
589  return;
590  }
591 
592  EC_SLAVE_DBG(slave, 1, "Finished SoE request.\n");
593 
594  // SoE request finished
595  request->state = EC_INT_REQUEST_SUCCESS;
596  wake_up_all(&slave->master->request_queue);
597  fsm->soe_request = NULL;
599 }
600 
601 /****************************************************************************/
602 
603 #ifdef EC_EOE
604 
609  ec_fsm_slave_t *fsm,
610  ec_datagram_t *datagram
611  )
612 {
613  ec_slave_t *slave = fsm->slave;
614  ec_eoe_request_t *request;
615 
616  if (list_empty(&slave->eoe_requests)) {
617  return 0;
618  }
619 
620  // take the first request to be processed
621  request = list_entry(slave->eoe_requests.next, ec_eoe_request_t, list);
622  list_del_init(&request->list); // dequeue
623 
624  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
625  EC_SLAVE_WARN(slave, "Aborting EoE request,"
626  " slave has error flag set.\n");
627  request->state = EC_INT_REQUEST_FAILURE;
628  wake_up_all(&slave->master->request_queue);
630  return 0;
631  }
632 
633  if (slave->current_state == EC_SLAVE_STATE_INIT) {
634  EC_SLAVE_WARN(slave, "Aborting EoE request, slave is in INIT.\n");
635  request->state = EC_INT_REQUEST_FAILURE;
636  wake_up_all(&slave->master->request_queue);
638  return 0;
639  }
640 
641  fsm->eoe_request = request;
642  request->state = EC_INT_REQUEST_BUSY;
643 
644  // Found pending request. Execute it!
645  EC_SLAVE_DBG(slave, 1, "Processing EoE request...\n");
646 
647  // Start EoE command
649  ec_fsm_eoe_set_ip_param(&fsm->fsm_eoe, slave, request);
650  ec_fsm_eoe_exec(&fsm->fsm_eoe, datagram); // execute immediately
651  return 1;
652 }
653 
654 /****************************************************************************/
655 
659  ec_fsm_slave_t *fsm,
660  ec_datagram_t *datagram
661  )
662 {
663  ec_slave_t *slave = fsm->slave;
664  ec_eoe_request_t *req = fsm->eoe_request;
665 
666  if (ec_fsm_eoe_exec(&fsm->fsm_eoe, datagram)) {
667  return;
668  }
669 
670  if (ec_fsm_eoe_success(&fsm->fsm_eoe)) {
671  req->state = EC_INT_REQUEST_SUCCESS;
672  EC_SLAVE_DBG(slave, 1, "Finished EoE request.\n");
673  }
674  else {
675  req->state = EC_INT_REQUEST_FAILURE;
676  EC_SLAVE_ERR(slave, "Failed to process EoE request.\n");
677  }
678 
679  wake_up_all(&slave->master->request_queue);
680  fsm->eoe_request = NULL;
682 }
683 
684 /****************************************************************************/
685 #endif
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:121
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:48
void ec_fsm_slave_clear(ec_fsm_slave_t *fsm)
Destructor.
Definition: fsm_slave.c:87
int ec_fsm_foe_success(const ec_fsm_foe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_foe.c:151
void ec_fsm_slave_state_foe_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: FOE REQUEST.
Definition: fsm_slave.c:484
size_t transfer_size
Size of the data to transfer.
Definition: reg_request.h:47
ec_foe_request_t * foe_request
FoE request to process.
Definition: fsm_slave.h:60
void ec_fsm_foe_clear(ec_fsm_foe_t *fsm)
Destructor.
Definition: fsm_foe.c:107
void ec_fsm_slave_state_eoe_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: EOE_REQUEST.
Definition: fsm_slave.c:658
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:98
ec_reg_request_t * reg_request
Register request to process.
Definition: fsm_slave.h:59
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:176
CANopen SDO request.
Definition: sdo_request.h:40
ec_slave_state_t current_state
Current application state.
Definition: slave.h:184
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
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition: slave.h:82
EtherCAT datagram.
Definition: datagram.h:79
void ec_fsm_slave_state_soe_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: SOE_REQUEST.
Definition: fsm_slave.c:571
ec_fsm_soe_t fsm_soe
SoE state machine.
Definition: fsm_slave.h:69
Finite state machine of an EtherCAT slave.
Definition: fsm_slave.h:52
ec_datagram_t * datagram
Previous state datagram.
Definition: fsm_slave.h:57
struct list_head reg_requests
Register access requests.
Definition: slave.h:222
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_fsm_slave_action_process_foe(ec_fsm_slave_t *, ec_datagram_t *)
Check for pending FoE requests and process one.
Definition: fsm_slave.c:444
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:160
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
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:301
ec_sdo_request_t * sdo_request
SDO request to process.
Definition: fsm_slave.h:58
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:326
uint16_t station_address
Configured station address.
Definition: slave.h:176
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:521
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:104
Global definitions and macros.
EtherCAT master structure.
void ec_fsm_slave_state_sdo_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: SDO_REQUEST.
Definition: fsm_slave.c:290
EtherCAT slave.
Definition: slave.h:168
ec_eoe_request_t * eoe_request
SoE request to process.
Definition: fsm_slave.h:64
ec_slave_t * slave
slave the FSM runs on
Definition: fsm_slave.h:53
struct list_head sdo_requests
SDO access requests.
Definition: slave.h:221
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:170
void ec_fsm_foe_init(ec_fsm_foe_t *fsm)
Constructor.
Definition: fsm_foe.c:95
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:224
ec_datagram_state_t state
State.
Definition: datagram.h:94
ec_slave_config_t * config
Current configuration.
Definition: slave.h:182
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:140
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:68
void ec_fsm_slave_state_reg_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: Register request.
Definition: fsm_slave.c:392
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
struct list_head list
List item.
Definition: soe_request.h:41
ec_soe_request_t * soe_request
SoE request to process.
Definition: fsm_slave.h:62
void ec_fsm_coe_clear(ec_fsm_coe_t *fsm)
Destructor.
Definition: fsm_coe.c:187
ec_fsm_eoe_t fsm_eoe
EoE state machine.
Definition: fsm_slave.h:71
int ec_fsm_eoe_success(const ec_fsm_eoe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_eoe.c:156
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:135
ec_master_t * master
Master owning the slave.
Definition: slave.h:170
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
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
Values read by the master.
Definition: ecrt.h:507
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
Definition: datagram.h:84
void ec_fsm_slave_state_ready(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: READY.
Definition: fsm_slave.c:201
size_t data_size
Size of FoE data.
Definition: foe_request.h:46
void ec_fsm_coe_init(ec_fsm_coe_t *fsm)
Constructor.
Definition: fsm_coe.c:175
Ethernet-over-EtherCAT set IP parameter request.
Definition: eoe_request.h:41
void ec_fsm_eoe_clear(ec_fsm_eoe_t *fsm)
Destructor.
Definition: fsm_eoe.c:94
INIT state (no mailbox communication, no IO)
Definition: globals.h:124
FoE request.
Definition: foe_request.h:42
ec_internal_request_state_t state
Request state.
Definition: eoe_request.h:43
struct list_head foe_requests
FoE requests.
Definition: slave.h:223
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:240
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:117
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:557
Mailbox functionality.
struct list_head list
Used for execution list.
Definition: fsm_slave.h:54
uint8_t * data
Pointer to data memory.
Definition: reg_request.h:43
struct list_head list
List item.
Definition: sdo_request.h:41
void ec_fsm_slave_init(ec_fsm_slave_t *fsm, ec_slave_t *slave)
Constructor.
Definition: fsm_slave.c:56
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
EtherCAT slave request state machine.
ec_direction_t dir
Direction.
Definition: reg_request.h:44
ec_fsm_foe_t fsm_foe
FoE state machine.
Definition: fsm_slave.h:68
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:88
ec_fsm_coe_t fsm_coe
CoE state machine.
Definition: fsm_slave.h:67
EtherCAT slave configuration structure.
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:55
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
Received (dequeued).
Definition: datagram.h:70
void ec_fsm_slave_state_idle(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: IDLE.
Definition: fsm_slave.c:189
struct list_head list
List item.
Definition: reg_request.h:41
struct list_head eoe_requests
EoE set IP parameter requests.
Definition: slave.h:225
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:608
void(* state)(ec_fsm_slave_t *, ec_datagram_t *)
State function.
Definition: fsm_slave.h:56
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:52
struct list_head list
List item.
Definition: eoe_request.h:42
Sercos-over-EtherCAT request.
Definition: soe_request.h:40
struct list_head list
List item.
Definition: foe_request.h:43