IgH EtherCAT Master  1.6.9
fsm_pdo_entry.c
Go to the documentation of this file.
1/*****************************************************************************
2 *
3 * Copyright (C) 2006-2008 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
25
26/****************************************************************************/
27
28#include "globals.h"
29#include "master.h"
30#include "mailbox.h"
31#include "slave_config.h"
32
33#include "fsm_pdo_entry.h"
34
35/****************************************************************************/
36
37// prototypes for private methods
41 const struct list_head *);
42
43/****************************************************************************/
44
48
50
58
60
63
64/****************************************************************************/
65
70 ec_fsm_coe_t *fsm_coe
71 )
72{
73 fsm->fsm_coe = fsm_coe;
75}
76
77/****************************************************************************/
78
87
88/****************************************************************************/
89
93 const ec_fsm_pdo_entry_t *fsm
94 )
95{
96 printk(KERN_CONT "Currently mapped PDO entries: ");
98 printk(KERN_CONT ". Entries to map: ");
100 printk(KERN_CONT "\n");
101}
102
103/****************************************************************************/
104
108 ec_fsm_pdo_entry_t *fsm,
109 ec_slave_t *slave,
110 ec_pdo_t *pdo
111 )
112{
113 fsm->slave = slave;
114 fsm->target_pdo = pdo;
115
117
119}
120
121/****************************************************************************/
122
126 ec_fsm_pdo_entry_t *fsm,
127 ec_slave_t *slave,
128 const ec_pdo_t *pdo,
129 const ec_pdo_t *cur_pdo
130 )
131{
132 fsm->slave = slave;
133 fsm->source_pdo = pdo;
134 fsm->cur_pdo = cur_pdo;
135
136 if (fsm->slave->master->debug_level) {
137 EC_SLAVE_DBG(slave, 1, "Changing mapping of PDO 0x%04X.\n",
138 pdo->index);
139 EC_SLAVE_DBG(slave, 1, ""); ec_fsm_pdo_entry_print(fsm);
140 }
141
143}
144
145/****************************************************************************/
146
152 const ec_fsm_pdo_entry_t *fsm
153 )
154{
155 return fsm->state != ec_fsm_pdo_entry_state_end
157}
158
159/****************************************************************************/
160
166 ec_fsm_pdo_entry_t *fsm,
167 ec_datagram_t *datagram
168 )
169{
170 fsm->state(fsm, datagram);
171
172 return ec_fsm_pdo_entry_running(fsm);
173}
174
175/****************************************************************************/
176
182 const ec_fsm_pdo_entry_t *fsm
183 )
184{
185 return fsm->state == ec_fsm_pdo_entry_state_end;
186}
187
188/*****************************************************************************
189 * Reading state functions.
190 ****************************************************************************/
191
195 ec_fsm_pdo_entry_t *fsm,
196 ec_datagram_t *datagram
197 )
198{
201
203 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
204 ec_fsm_coe_exec(fsm->fsm_coe, datagram); // execute immediately
205}
206
207/****************************************************************************/
208
212 ec_fsm_pdo_entry_t *fsm,
213 ec_datagram_t *datagram
214 )
215{
216 if (ec_fsm_coe_exec(fsm->fsm_coe, datagram)) {
217 return;
218 }
219
220 if (!ec_fsm_coe_success(fsm->fsm_coe)) {
221 EC_SLAVE_ERR(fsm->slave,
222 "Failed to read number of mapped PDO entries.\n");
224 return;
225 }
226
227 if (fsm->request.data_size != sizeof(uint8_t)) {
228 EC_SLAVE_ERR(fsm->slave, "Invalid data size %zu at uploading"
229 " SDO 0x%04X:%02X.\n",
230 fsm->request.data_size, fsm->request.index,
231 fsm->request.subindex);
233 return;
234 }
235
236 fsm->entry_count = EC_READ_U8(fsm->request.data);
237
238 EC_SLAVE_DBG(fsm->slave, 1, "%u PDO entries mapped.\n", fsm->entry_count);
239
240 // read first PDO entry
241 fsm->entry_pos = 1;
243}
244
245/****************************************************************************/
246
250 ec_fsm_pdo_entry_t *fsm,
251 ec_datagram_t *datagram
252 )
253{
254 if (fsm->entry_pos <= fsm->entry_count) {
256 fsm->entry_pos);
259 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
260 ec_fsm_coe_exec(fsm->fsm_coe, datagram); // execute immediately
261 return;
262 }
263
264 // finished reading entries.
266}
267
268/****************************************************************************/
269
273 ec_fsm_pdo_entry_t *fsm,
274 ec_datagram_t *datagram
275 )
276{
277 if (ec_fsm_coe_exec(fsm->fsm_coe, datagram)) {
278 return;
279 }
280
281 if (!ec_fsm_coe_success(fsm->fsm_coe)) {
282 EC_SLAVE_ERR(fsm->slave, "Failed to read mapped PDO entry.\n");
284 return;
285 }
286
287 if (fsm->request.data_size != sizeof(uint32_t)) {
288 EC_SLAVE_ERR(fsm->slave, "Invalid data size %zu at"
289 " uploading SDO 0x%04X:%02X.\n",
290 fsm->request.data_size, fsm->request.index,
291 fsm->request.subindex);
293 } else {
294 uint32_t pdo_entry_info;
295 ec_pdo_entry_t *pdo_entry;
296
297 pdo_entry_info = EC_READ_U32(fsm->request.data);
298
299 if (!(pdo_entry = (ec_pdo_entry_t *)
300 kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
301 EC_SLAVE_ERR(fsm->slave, "Failed to allocate PDO entry.\n");
303 return;
304 }
305
306 ec_pdo_entry_init(pdo_entry);
307 pdo_entry->index = pdo_entry_info >> 16;
308 pdo_entry->subindex = (pdo_entry_info >> 8) & 0xFF;
309 pdo_entry->bit_length = pdo_entry_info & 0xFF;
310
311 if (!pdo_entry->index && !pdo_entry->subindex) {
312 if (ec_pdo_entry_set_name(pdo_entry, "Gap")) {
313 ec_pdo_entry_clear(pdo_entry);
314 kfree(pdo_entry);
316 return;
317 }
318 }
319
320 EC_SLAVE_DBG(fsm->slave, 1,
321 "PDO entry 0x%04X:%02X, %u bit, \"%s\".\n",
322 pdo_entry->index, pdo_entry->subindex,
323 pdo_entry->bit_length,
324 pdo_entry->name ? pdo_entry->name : "???");
325
326 list_add_tail(&pdo_entry->list, &fsm->target_pdo->entries);
327
328 // next PDO entry
329 fsm->entry_pos++;
331 }
332}
333
334/*****************************************************************************
335 * Configuration state functions.
336 ****************************************************************************/
337
341 ec_fsm_pdo_entry_t *fsm,
342 ec_datagram_t *datagram
343 )
344{
345 if (ec_sdo_request_alloc(&fsm->request, 4)) {
347 return;
348 }
349
350 // set mapped PDO entry count to zero
351 EC_WRITE_U8(fsm->request.data, 0);
352 fsm->request.data_size = 1;
355
356 EC_SLAVE_DBG(fsm->slave, 1, "Setting entry count to zero.\n");
357
359 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
360 ec_fsm_coe_exec(fsm->fsm_coe, datagram); // execute immediately
361}
362
363/****************************************************************************/
364
370 const ec_fsm_pdo_entry_t *fsm,
371 const struct list_head *list
372 )
373{
374 list = list->next;
375 if (list == &fsm->source_pdo->entries)
376 return NULL; // no next entry
377 return list_entry(list, ec_pdo_entry_t, list);
378}
379
380/****************************************************************************/
381
385 ec_fsm_pdo_entry_t *fsm,
386 ec_datagram_t *datagram
387 )
388{
389 if (ec_fsm_coe_exec(fsm->fsm_coe, datagram)) {
390 return;
391 }
392
393 if (!ec_fsm_coe_success(fsm->fsm_coe)) {
394 EC_SLAVE_WARN(fsm->slave, "Failed to clear PDO mapping.\n");
397 return;
398 }
399
400 // find first entry
402 fsm, &fsm->source_pdo->entries))) {
403
404 EC_SLAVE_DBG(fsm->slave, 1, "No entries to map.\n");
405
406 fsm->state = ec_fsm_pdo_entry_state_end; // finished
407 return;
408 }
409
410 // add first entry
411 fsm->entry_pos = 1;
413}
414
415/****************************************************************************/
416
420 ec_fsm_pdo_entry_t *fsm,
421 ec_datagram_t *datagram
422 )
423{
424 uint32_t value;
425
426 EC_SLAVE_DBG(fsm->slave, 1, "Mapping PDO entry 0x%04X:%02X (%u bit)"
427 " at position %u.\n",
428 fsm->entry->index, fsm->entry->subindex,
429 fsm->entry->bit_length, fsm->entry_pos);
430
431 value = fsm->entry->index << 16
432 | fsm->entry->subindex << 8 | fsm->entry->bit_length;
433 EC_WRITE_U32(fsm->request.data, value);
434 fsm->request.data_size = 4;
436 fsm->entry_pos);
438
440 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
441 ec_fsm_coe_exec(fsm->fsm_coe, datagram); // execute immediately
442}
443
444/****************************************************************************/
445
449 ec_fsm_pdo_entry_t *fsm,
450 ec_datagram_t *datagram
451 )
452{
453 if (ec_fsm_coe_exec(fsm->fsm_coe, datagram)) {
454 return;
455 }
456
457 if (!ec_fsm_coe_success(fsm->fsm_coe)) {
458 EC_SLAVE_WARN(fsm->slave, "Failed to map PDO entry"
459 " 0x%04X:%02X (%u bit) to position %u.\n",
460 fsm->entry->index, fsm->entry->subindex,
461 fsm->entry->bit_length, fsm->entry_pos);
464 return;
465 }
466
467 // find next entry
469 fsm, &fsm->entry->list))) {
470
471 // No more entries to add. Write entry count.
472 EC_WRITE_U8(fsm->request.data, fsm->entry_pos);
473 fsm->request.data_size = 1;
476
477 EC_SLAVE_DBG(fsm->slave, 1, "Setting number of PDO entries to %u.\n",
478 fsm->entry_pos);
479
481 ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request);
482 ec_fsm_coe_exec(fsm->fsm_coe, datagram); // execute immediately
483 return;
484 }
485
486 // add next entry
487 fsm->entry_pos++;
489}
490
491/****************************************************************************/
492
496 ec_fsm_pdo_entry_t *fsm,
497 ec_datagram_t *datagram
498 )
499{
500 if (ec_fsm_coe_exec(fsm->fsm_coe, datagram)) {
501 return;
502 }
503
504 if (!ec_fsm_coe_success(fsm->fsm_coe)) {
505 EC_SLAVE_WARN(fsm->slave, "Failed to set number of entries.\n");
508 return;
509 }
510
511 EC_SLAVE_DBG(fsm->slave, 1, "Successfully configured"
512 " mapping for PDO 0x%04X.\n", fsm->source_pdo->index);
513
514 fsm->state = ec_fsm_pdo_entry_state_end; // finished
515}
516
517/*****************************************************************************
518 * Common state functions
519 ****************************************************************************/
520
524 ec_fsm_pdo_entry_t *fsm,
525 ec_datagram_t *datagram
526 )
527{
528}
529
530/****************************************************************************/
531
535 ec_fsm_pdo_entry_t *fsm,
536 ec_datagram_t *datagram
537 )
538{
539}
540
541/****************************************************************************/
int ec_fsm_coe_success(const ec_fsm_coe_t *fsm)
Returns, if the state machine terminated with success.
Definition fsm_coe.c:267
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
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
struct ec_fsm_coe ec_fsm_coe_t
Definition fsm_coe.h:40
ec_pdo_entry_t * ec_fsm_pdo_entry_conf_next_entry(const ec_fsm_pdo_entry_t *, const struct list_head *)
Process next PDO entry.
void ec_fsm_pdo_entry_read_state_count(ec_fsm_pdo_entry_t *, ec_datagram_t *)
Read number of mapped PDO entries.
void ec_fsm_pdo_entry_init(ec_fsm_pdo_entry_t *fsm, ec_fsm_coe_t *fsm_coe)
Constructor.
void ec_fsm_pdo_entry_read_action_next(ec_fsm_pdo_entry_t *, ec_datagram_t *)
Read next PDO entry.
void ec_fsm_pdo_entry_conf_action_map(ec_fsm_pdo_entry_t *, ec_datagram_t *)
Starts to add a PDO entry.
int ec_fsm_pdo_entry_exec(ec_fsm_pdo_entry_t *fsm, ec_datagram_t *datagram)
Executes the current state.
void ec_fsm_pdo_entry_read_state_entry(ec_fsm_pdo_entry_t *, ec_datagram_t *)
Read PDO entry information.
void ec_fsm_pdo_entry_start_reading(ec_fsm_pdo_entry_t *fsm, ec_slave_t *slave, ec_pdo_t *pdo)
Start reading a PDO's entries.
void ec_fsm_pdo_entry_state_error(ec_fsm_pdo_entry_t *, ec_datagram_t *)
State: ERROR.
void ec_fsm_pdo_entry_conf_state_map_entry(ec_fsm_pdo_entry_t *, ec_datagram_t *)
Add a PDO entry.
void ec_fsm_pdo_entry_state_end(ec_fsm_pdo_entry_t *, ec_datagram_t *)
State: END.
void ec_fsm_pdo_entry_start_configuration(ec_fsm_pdo_entry_t *fsm, ec_slave_t *slave, const ec_pdo_t *pdo, const ec_pdo_t *cur_pdo)
Start PDO mapping state machine.
void ec_fsm_pdo_entry_conf_state_set_entry_count(ec_fsm_pdo_entry_t *, ec_datagram_t *)
Set the number of entries.
void ec_fsm_pdo_entry_clear(ec_fsm_pdo_entry_t *fsm)
Destructor.
void ec_fsm_pdo_entry_print(const ec_fsm_pdo_entry_t *)
Print the current and desired PDO mapping.
void ec_fsm_pdo_entry_read_state_start(ec_fsm_pdo_entry_t *, ec_datagram_t *)
Request reading the number of mapped PDO entries.
int ec_fsm_pdo_entry_success(const ec_fsm_pdo_entry_t *fsm)
Get execution result.
void ec_fsm_pdo_entry_conf_state_zero_entry_count(ec_fsm_pdo_entry_t *, ec_datagram_t *)
Set the number of mapped entries to zero.
int ec_fsm_pdo_entry_running(const ec_fsm_pdo_entry_t *)
Get running state.
void ec_fsm_pdo_entry_conf_state_start(ec_fsm_pdo_entry_t *, ec_datagram_t *)
Start PDO mapping.
EtherCAT PDO entry configuration state machine structures.
struct ec_fsm_pdo_entry ec_fsm_pdo_entry_t
Global definitions and macros.
struct ec_slave ec_slave_t
Definition globals.h:310
int ecrt_sdo_request_read(ec_sdo_request_t *req)
Schedule an SDO read operation.
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition ecrt.h:3040
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition ecrt.h:3074
int ecrt_sdo_request_write(ec_sdo_request_t *req)
Schedule an SDO write operation.
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition ecrt.h:2932
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition ecrt.h:2964
int ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index, uint8_t subindex)
Set the SDO index and subindex.
Mailbox functionality.
EtherCAT master structure.
void ec_pdo_clear_entries(ec_pdo_t *pdo)
Clear PDO entry list.
Definition pdo.c:98
void ec_pdo_print_entries(const ec_pdo_t *pdo)
Outputs the PDOs in the list.
Definition pdo.c:291
void ec_pdo_entry_clear(ec_pdo_entry_t *entry)
PDO entry destructor.
Definition pdo_entry.c:68
int ec_pdo_entry_set_name(ec_pdo_entry_t *entry, const char *name)
Set PDO entry name.
Definition pdo_entry.c:81
void ec_pdo_entry_init(ec_pdo_entry_t *entry)
PDO entry constructor.
Definition pdo_entry.c:37
void ec_sdo_request_init(ec_sdo_request_t *req)
SDO request constructor.
Definition sdo_request.c:48
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
void ec_sdo_request_clear(ec_sdo_request_t *req)
SDO request destructor.
Definition sdo_request.c:70
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition slave.h:98
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition slave.h:68
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
Definition slave.h:82
EtherCAT slave configuration structure.
EtherCAT datagram.
Definition datagram.h:79
ec_slave_t * slave
Slave the FSM runs on.
void(* state)(ec_fsm_pdo_entry_t *, ec_datagram_t *)
state function
ec_pdo_t * target_pdo
PDO to read the mapping for.
const ec_pdo_entry_t * entry
Current entry.
ec_fsm_coe_t * fsm_coe
CoE state machine to use.
const ec_pdo_t * source_pdo
PDO with desired mapping.
unsigned int entry_pos
Position in PDO mapping.
unsigned int entry_count
Number of entries.
const ec_pdo_t * cur_pdo
PDO with current mapping (display only).
ec_sdo_request_t request
SDO request.
unsigned int debug_level
Master debug level.
Definition master.h:275
PDO entry description.
Definition pdo_entry.h:40
struct list_head list
list item
Definition pdo_entry.h:41
uint8_t bit_length
entry length in bit
Definition pdo_entry.h:45
uint8_t subindex
PDO entry subindex.
Definition pdo_entry.h:43
char * name
entry name
Definition pdo_entry.h:44
uint16_t index
PDO entry index.
Definition pdo_entry.h:42
PDO description.
Definition pdo.h:41
struct list_head entries
List of PDO entries.
Definition pdo.h:46
uint16_t index
PDO index.
Definition pdo.h:43
size_t data_size
Size of SDO data.
Definition sdo_request.h:46
uint8_t * data
Pointer to SDO data.
Definition sdo_request.h:44
uint16_t index
SDO index.
Definition sdo_request.h:42
uint8_t subindex
SDO subindex.
Definition sdo_request.h:43
ec_master_t * master
Master owning the slave.
Definition slave.h:170