IgH EtherCAT Master  1.7.0
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->eoe_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  // datagrams are taken from the shared external ring, so the device
143  // index has to be set according to the slave every time
144  datagram->device_index = fsm->slave->device_index;
145 
146  fsm->state(fsm, datagram);
147 
148  datagram_used = fsm->state != ec_fsm_slave_state_idle &&
150 
151  if (datagram_used) {
152  fsm->datagram = datagram;
153  } else {
154  fsm->datagram = NULL;
155  }
156 
157  return datagram_used;
158 }
159 
160 /****************************************************************************/
161 
165  ec_fsm_slave_t *fsm
166  )
167 {
168  if (fsm->state == ec_fsm_slave_state_idle) {
169  EC_SLAVE_DBG(fsm->slave, 1, "Ready for requests.\n");
171  }
172 }
173 
174 /****************************************************************************/
175 
181  const ec_fsm_slave_t *fsm
182  )
183 {
184  return fsm->state == ec_fsm_slave_state_ready;
185 }
186 
187 /*****************************************************************************
188  * Slave state machine
189  ****************************************************************************/
190 
194  ec_fsm_slave_t *fsm,
195  ec_datagram_t *datagram
196  )
197 {
198  // do nothing
199 }
200 
201 /****************************************************************************/
202 
206  ec_fsm_slave_t *fsm,
207  ec_datagram_t *datagram
208  )
209 {
210  // Check for pending external SDO requests
211  if (ec_fsm_slave_action_process_sdo(fsm, datagram)) {
212  return;
213  }
214 
215  // Check for pending external register requests
216  if (ec_fsm_slave_action_process_reg(fsm, datagram)) {
217  return;
218  }
219 
220  // Check for pending FoE requests
221  if (ec_fsm_slave_action_process_foe(fsm, datagram)) {
222  return;
223  }
224 
225  // Check for pending SoE requests
226  if (ec_fsm_slave_action_process_soe(fsm, datagram)) {
227  return;
228  }
229 
230 #ifdef EC_EOE
231  // Check for pending EoE IP parameter requests
232  if (ec_fsm_slave_action_process_eoe(fsm, datagram)) {
233  return;
234  }
235 #endif
236 }
237 
238 /****************************************************************************/
239 
245  ec_fsm_slave_t *fsm,
246  ec_datagram_t *datagram
247  )
248 {
249  ec_slave_t *slave = fsm->slave;
250  ec_sdo_request_t *request;
251 
252  if (list_empty(&slave->sdo_requests)) {
253  return 0;
254  }
255 
256  // take the first request to be processed
257  request = list_entry(slave->sdo_requests.next, ec_sdo_request_t, list);
258  list_del_init(&request->list); // dequeue
259 
260  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
261  EC_SLAVE_WARN(slave, "Aborting SDO request,"
262  " slave has error flag set.\n");
263  request->state = EC_INT_REQUEST_FAILURE;
264  wake_up_all(&slave->master->request_queue);
266  return 0;
267  }
268 
269  if (slave->current_state == EC_SLAVE_STATE_INIT) {
270  EC_SLAVE_WARN(slave, "Aborting SDO request, slave is in INIT.\n");
271  request->state = EC_INT_REQUEST_FAILURE;
272  wake_up_all(&slave->master->request_queue);
274  return 0;
275  }
276 
277  fsm->sdo_request = request;
278  request->state = EC_INT_REQUEST_BUSY;
279 
280  // Found pending SDO request. Execute it!
281  EC_SLAVE_DBG(slave, 1, "Processing SDO request...\n");
282 
283  // Start SDO transfer
285  ec_fsm_coe_transfer(&fsm->fsm_coe, slave, request);
286  ec_fsm_coe_exec(&fsm->fsm_coe, datagram); // execute immediately
287  return 1;
288 }
289 
290 /****************************************************************************/
291 
295  ec_fsm_slave_t *fsm,
296  ec_datagram_t *datagram
297  )
298 {
299  ec_slave_t *slave = fsm->slave;
300  ec_sdo_request_t *request = fsm->sdo_request;
301 
302  if (ec_fsm_coe_exec(&fsm->fsm_coe, datagram)) {
303  return;
304  }
305 
306  if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
307  EC_SLAVE_ERR(slave, "Failed to process SDO request.\n");
308  request->state = EC_INT_REQUEST_FAILURE;
309  wake_up_all(&slave->master->request_queue);
310  fsm->sdo_request = NULL;
312  return;
313  }
314 
315  EC_SLAVE_DBG(slave, 1, "Finished SDO request.\n");
316 
317  // SDO request finished
318  request->state = EC_INT_REQUEST_SUCCESS;
319  wake_up_all(&slave->master->request_queue);
320  fsm->sdo_request = NULL;
322 }
323 
324 /****************************************************************************/
325 
331  ec_fsm_slave_t *fsm,
332  ec_datagram_t *datagram
333  )
334 {
335  ec_slave_t *slave = fsm->slave;
336  ec_reg_request_t *reg;
337 
338  fsm->reg_request = NULL;
339 
340  if (slave->config) {
341  // search the first internal register request to be processed
342  list_for_each_entry(reg, &slave->config->reg_requests, list) {
343  if (reg->state == EC_INT_REQUEST_QUEUED) {
344  fsm->reg_request = reg;
345  break;
346  }
347  }
348  }
349 
350  if (!fsm->reg_request && !list_empty(&slave->reg_requests)) {
351  // take the first external request to be processed
352  fsm->reg_request =
353  list_entry(slave->reg_requests.next, ec_reg_request_t, list);
354  list_del_init(&fsm->reg_request->list); // dequeue
355  }
356 
357  if (!fsm->reg_request) { // no register request to process
358  return 0;
359  }
360 
361  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
362  EC_SLAVE_WARN(slave, "Aborting register request,"
363  " slave has error flag set.\n");
364  fsm->reg_request->state = EC_INT_REQUEST_FAILURE;
365  wake_up_all(&slave->master->request_queue);
366  fsm->reg_request = NULL;
368  return 0;
369  }
370 
371  // Found pending register request. Execute it!
372  EC_SLAVE_DBG(slave, 1, "Processing register request...\n");
373 
374  fsm->reg_request->state = EC_INT_REQUEST_BUSY;
375 
376  // Start register access
377  if (fsm->reg_request->dir == EC_DIR_INPUT) {
378  ec_datagram_fprd(datagram, slave->station_address,
380  ec_datagram_zero(datagram);
381  } else {
382  ec_datagram_fpwr(datagram, slave->station_address,
384  memcpy(datagram->data, fsm->reg_request->data,
385  fsm->reg_request->transfer_size);
386  }
388  return 1;
389 }
390 
391 /****************************************************************************/
392 
396  ec_fsm_slave_t *fsm,
397  ec_datagram_t *datagram
398  )
399 {
400  ec_slave_t *slave = fsm->slave;
401  ec_reg_request_t *reg = fsm->reg_request;
402 
403  if (!reg) {
404  // configuration was cleared in the meantime
406  fsm->reg_request = NULL;
407  return;
408  }
409 
410  if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
411  EC_SLAVE_ERR(slave, "Failed to receive register"
412  " request datagram: ");
414  reg->state = EC_INT_REQUEST_FAILURE;
415  wake_up_all(&slave->master->request_queue);
416  fsm->reg_request = NULL;
418  return;
419  }
420 
421  if (fsm->datagram->working_counter == 1) {
422  if (reg->dir == EC_DIR_INPUT) { // read request
423  memcpy(reg->data, fsm->datagram->data, reg->transfer_size);
424  }
425 
426  reg->state = EC_INT_REQUEST_SUCCESS;
427  EC_SLAVE_DBG(slave, 1, "Register request successful.\n");
428  } else {
429  reg->state = EC_INT_REQUEST_FAILURE;
431  EC_SLAVE_ERR(slave, "Register request failed"
432  " (working counter is %u).\n",
433  fsm->datagram->working_counter);
434  }
435 
436  wake_up_all(&slave->master->request_queue);
437  fsm->reg_request = NULL;
439 }
440 
441 /****************************************************************************/
442 
448  ec_fsm_slave_t *fsm,
449  ec_datagram_t *datagram
450  )
451 {
452  ec_slave_t *slave = fsm->slave;
453  ec_foe_request_t *request;
454 
455  if (list_empty(&slave->foe_requests)) {
456  return 0;
457  }
458 
459  // take the first request to be processed
460  request = list_entry(slave->foe_requests.next, ec_foe_request_t, list);
461  list_del_init(&request->list); // dequeue
462 
463  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
464  EC_SLAVE_WARN(slave, "Aborting FoE request,"
465  " slave has error flag set.\n");
466  request->state = EC_INT_REQUEST_FAILURE;
467  wake_up_all(&slave->master->request_queue);
469  return 0;
470  }
471 
472  request->state = EC_INT_REQUEST_BUSY;
473  fsm->foe_request = request;
474 
475  EC_SLAVE_DBG(slave, 1, "Processing FoE request.\n");
476 
478  ec_fsm_foe_transfer(&fsm->fsm_foe, slave, request);
479  ec_fsm_foe_exec(&fsm->fsm_foe, datagram);
480  return 1;
481 }
482 
483 /****************************************************************************/
484 
488  ec_fsm_slave_t *fsm,
489  ec_datagram_t *datagram
490  )
491 {
492  ec_slave_t *slave = fsm->slave;
493  ec_foe_request_t *request = fsm->foe_request;
494 
495  if (ec_fsm_foe_exec(&fsm->fsm_foe, datagram)) {
496  return;
497  }
498 
499  if (!ec_fsm_foe_success(&fsm->fsm_foe)) {
500  EC_SLAVE_ERR(slave, "Failed to handle FoE request.\n");
501  request->state = EC_INT_REQUEST_FAILURE;
502  wake_up_all(&slave->master->request_queue);
503  fsm->foe_request = NULL;
505  return;
506  }
507 
508  // finished transferring FoE
509  EC_SLAVE_DBG(slave, 1, "Successfully transferred %zu bytes of FoE"
510  " data.\n", request->data_size);
511 
512  request->state = EC_INT_REQUEST_SUCCESS;
513  wake_up_all(&slave->master->request_queue);
514  fsm->foe_request = NULL;
516 }
517 
518 /****************************************************************************/
519 
525  ec_fsm_slave_t *fsm,
526  ec_datagram_t *datagram
527  )
528 {
529  ec_slave_t *slave = fsm->slave;
530  ec_soe_request_t *req;
531 
532  if (list_empty(&slave->soe_requests)) {
533  return 0;
534  }
535 
536  // take the first request to be processed
537  req = list_entry(slave->soe_requests.next, ec_soe_request_t, list);
538  list_del_init(&req->list); // dequeue
539 
540  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
541  EC_SLAVE_WARN(slave, "Aborting SoE request,"
542  " slave has error flag set.\n");
543  req->state = EC_INT_REQUEST_FAILURE;
544  wake_up_all(&slave->master->request_queue);
546  return 0;
547  }
548 
549  if (slave->current_state == EC_SLAVE_STATE_INIT) {
550  EC_SLAVE_WARN(slave, "Aborting SoE request, slave is in INIT.\n");
551  req->state = EC_INT_REQUEST_FAILURE;
552  wake_up_all(&slave->master->request_queue);
554  return 0;
555  }
556 
557  fsm->soe_request = req;
558  req->state = EC_INT_REQUEST_BUSY;
559 
560  // Found pending request. Execute it!
561  EC_SLAVE_DBG(slave, 1, "Processing SoE request...\n");
562 
563  // Start SoE transfer
565  ec_fsm_soe_transfer(&fsm->fsm_soe, slave, req);
566  ec_fsm_soe_exec(&fsm->fsm_soe, datagram); // execute immediately
567  return 1;
568 }
569 
570 /****************************************************************************/
571 
575  ec_fsm_slave_t *fsm,
576  ec_datagram_t *datagram
577  )
578 {
579  ec_slave_t *slave = fsm->slave;
580  ec_soe_request_t *request = fsm->soe_request;
581 
582  if (ec_fsm_soe_exec(&fsm->fsm_soe, datagram)) {
583  return;
584  }
585 
586  if (!ec_fsm_soe_success(&fsm->fsm_soe)) {
587  EC_SLAVE_ERR(slave, "Failed to process SoE request.\n");
588  request->state = EC_INT_REQUEST_FAILURE;
589  wake_up_all(&slave->master->request_queue);
590  fsm->soe_request = NULL;
592  return;
593  }
594 
595  EC_SLAVE_DBG(slave, 1, "Finished SoE request.\n");
596 
597  // SoE request finished
598  request->state = EC_INT_REQUEST_SUCCESS;
599  wake_up_all(&slave->master->request_queue);
600  fsm->soe_request = NULL;
602 }
603 
604 /****************************************************************************/
605 
606 #ifdef EC_EOE
607 
612  ec_fsm_slave_t *fsm,
613  ec_datagram_t *datagram
614  )
615 {
616  ec_slave_t *slave = fsm->slave;
617  ec_eoe_request_t *request;
618 
619  if (list_empty(&slave->eoe_requests)) {
620  return 0;
621  }
622 
623  // take the first request to be processed
624  request = list_entry(slave->eoe_requests.next, ec_eoe_request_t, list);
625  list_del_init(&request->list); // dequeue
626 
627  if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
628  EC_SLAVE_WARN(slave, "Aborting EoE request,"
629  " slave has error flag set.\n");
630  request->state = EC_INT_REQUEST_FAILURE;
631  wake_up_all(&slave->master->request_queue);
633  return 0;
634  }
635 
636  if (slave->current_state == EC_SLAVE_STATE_INIT) {
637  EC_SLAVE_WARN(slave, "Aborting EoE request, slave is in INIT.\n");
638  request->state = EC_INT_REQUEST_FAILURE;
639  wake_up_all(&slave->master->request_queue);
641  return 0;
642  }
643 
644  fsm->eoe_request = request;
645  request->state = EC_INT_REQUEST_BUSY;
646 
647  // Found pending request. Execute it!
648  EC_SLAVE_DBG(slave, 1, "Processing EoE request...\n");
649 
650  // Start EoE command
652  ec_fsm_eoe_set_ip_param(&fsm->fsm_eoe, slave, request);
653  ec_fsm_eoe_exec(&fsm->fsm_eoe, datagram); // execute immediately
654  return 1;
655 }
656 
657 /****************************************************************************/
658 
662  ec_fsm_slave_t *fsm,
663  ec_datagram_t *datagram
664  )
665 {
666  ec_slave_t *slave = fsm->slave;
667  ec_eoe_request_t *req = fsm->eoe_request;
668 
669  if (ec_fsm_eoe_exec(&fsm->fsm_eoe, datagram)) {
670  return;
671  }
672 
673  if (ec_fsm_eoe_success(&fsm->fsm_eoe)) {
674  req->state = EC_INT_REQUEST_SUCCESS;
675  EC_SLAVE_DBG(slave, 1, "Finished EoE request.\n");
676  }
677  else {
678  req->state = EC_INT_REQUEST_FAILURE;
679  EC_SLAVE_ERR(slave, "Failed to process EoE request.\n");
680  }
681 
682  wake_up_all(&slave->master->request_queue);
683  fsm->eoe_request = NULL;
685 }
686 
687 /****************************************************************************/
688 #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:122
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:487
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:106
void ec_fsm_slave_state_eoe_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: EOE_REQUEST.
Definition: fsm_slave.c:661
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:100
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:180
CANopen SDO request.
Definition: sdo_request.h:40
ec_slave_state_t current_state
Current application state.
Definition: slave.h:186
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:84
EtherCAT datagram.
Definition: datagram.h:81
void ec_fsm_slave_state_soe_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: SOE_REQUEST.
Definition: fsm_slave.c:574
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:225
uint16_t working_counter
Working counter.
Definition: datagram.h:96
void ec_fsm_eoe_init(ec_fsm_eoe_t *fsm)
Constructor.
Definition: fsm_eoe.c:76
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:447
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:140
int ec_fsm_coe_success(const ec_fsm_coe_t *fsm)
Returns, if the state machine terminated with success.
Definition: fsm_coe.c:262
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:313
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:330
uint16_t station_address
Configured station address.
Definition: slave.h:178
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:524
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:105
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:294
EtherCAT slave.
Definition: slave.h:170
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:224
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:178
void ec_fsm_foe_init(ec_fsm_foe_t *fsm)
Constructor.
Definition: fsm_foe.c:93
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:227
ec_datagram_state_t state
State.
Definition: datagram.h:97
ec_slave_config_t * config
Current configuration.
Definition: slave.h:184
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:147
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:70
void ec_fsm_slave_state_reg_request(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: Register request.
Definition: fsm_slave.c:395
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:164
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:182
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:157
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:172
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:298
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:273
Values read by the master.
Definition: ecrt.h:525
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
Definition: datagram.h:87
void ec_fsm_slave_state_ready(ec_fsm_slave_t *, ec_datagram_t *)
Slave state: READY.
Definition: fsm_slave.c:205
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:169
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:130
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:226
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:244
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:565
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:229
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:105
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
Definition: fsm_soe.c:119
uint8_t * data
Datagram payload.
Definition: datagram.h:91
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:173
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:206
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:193
struct list_head list
List item.
Definition: reg_request.h:41
struct list_head eoe_requests
EoE set IP parameter requests.
Definition: slave.h:228
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:611
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