Reading of Pdo mapping via CoE during scan.
--- a/NEWS Tue Feb 26 13:20:32 2008 +0000
+++ b/NEWS Tue Feb 26 16:58:20 2008 +0000
@@ -41,7 +41,10 @@
be reached by specifying an explicit Pdo mapping and registering those
Pdo entries.
* Pdo configuration is now supported.
+* Current Pdo mapping/configuration is now read during bus scan, without
+ using the Sdo dictionary.
* Added 8139too driver for kernel 2.6.22, thanks to Erwin Burgstaller.
+* Added 8139too driver for kernel 2.6.23, thanks to Richard Hacker.
* Added e1000 driver for kernel 2.6.22.
* Added support for slaves that do not support the LRW datagram type. Separate
domains have to be used for inputs and output.
--- a/TODO Tue Feb 26 13:20:32 2008 +0000
+++ b/TODO Tue Feb 26 16:58:20 2008 +0000
@@ -8,7 +8,6 @@
Version 1.4.0:
-* Read PDO mapping via CoE during bus scan.
* Realtime interface changes:
- SDO access.
* Mailbox handler
@@ -18,9 +17,8 @@
* Remove ecdb.h and let lsec output PDO information 'cut-and-pastable' for
applications.
* SDO write access in sysfs.
+* Distributed clocks.
* Update documentation.
-* Distributed clocks.
-* Safety-over-EtherCAT
Future issues:
@@ -29,6 +27,8 @@
to replace lsec.
- Step 2: Move kernel threads to user space daemon with a TCP interface
replacing the cdev.
+* Mailbox gateway.
+* Slave-to-slave communication.
* Redundancy with 2 network adapters.
* Interface/buffers for asynchronous domain IO.
--- a/documentation/graphs/fsm_master.dot Tue Feb 26 13:20:32 2008 +0000
+++ b/documentation/graphs/fsm_master.dot Tue Feb 26 16:58:20 2008 +0000
@@ -26,16 +26,16 @@
action_configure -> configure_slave
+ action_process_states -> action_configure
+ action_process_states -> action_process_sdo
+ action_process_states -> sdodict
+ action_process_states -> action_process_eeprom
+ action_process_states -> end
+
action_next_slave_state -> read_states
action_next_slave_state -> validate_vendor
action_next_slave_state -> action_process_states
- action_process_states -> action_configure
- action_process_states -> action_process_sdo
- action_process_states -> action_process_eeprom
- action_process_states -> sdodict
- action_process_states -> end
-
//read_states -> error
read_states -> action_next_slave_state
read_states -> acknowledge
@@ -50,8 +50,8 @@
action_addresses -> rewrite_addresses
//validate_product -> error
+ validate_product -> action_addresses
validate_product -> validate_vendor
- validate_product -> action_addresses
//rewrite_addresses -> error
rewrite_addresses -> end
@@ -67,6 +67,7 @@
configure_slave -> end
//write_eeprom -> error
+ write_eeprom -> action_process_eeprom
write_eeprom -> end
//sdodict -> error
--- a/master/canopen.c Tue Feb 26 13:20:32 2008 +0000
+++ b/master/canopen.c Tue Feb 26 16:58:20 2008 +0000
@@ -416,7 +416,8 @@
off_t off = 0;
ec_sdo_request_t request;
- ec_sdo_request_init_read(&request, entry);
+ ec_sdo_request_init_read(&request, entry->sdo->slave,
+ entry->sdo->index, entry->subindex);
// schedule request.
down(&master->sdo_sem);
@@ -479,11 +480,16 @@
Sdo request constructor.
*/
-void ec_sdo_request_init_read(ec_sdo_request_t *req, /**< Sdo request */
- ec_sdo_entry_t *entry /**< Sdo entry */
- )
-{
- req->entry = entry;
+void ec_sdo_request_init_read(
+ ec_sdo_request_t *req, /**< Sdo request */
+ ec_slave_t *slave, /**< Slave owning the Sdo. */
+ uint16_t index, /**< Sdo index. */
+ uint8_t subindex /**< Sdo subindex. */
+ )
+{
+ req->slave = slave;
+ req->index = index;
+ req->subindex = subindex;
req->data = NULL;
req->size = 0;
req->state = EC_REQUEST_QUEUED;
--- a/master/canopen.h Tue Feb 26 13:20:32 2008 +0000
+++ b/master/canopen.h Tue Feb 26 16:58:20 2008 +0000
@@ -49,12 +49,9 @@
/*****************************************************************************/
-/**
- CANopen Sdo.
-*/
-
-struct ec_sdo
-{
+/** CANopen Sdo.
+ */
+struct ec_sdo {
struct kobject kobj; /**< kobject */
struct list_head list; /**< list item */
ec_slave_t *slave; /**< parent slave */
@@ -67,12 +64,9 @@
/*****************************************************************************/
-/**
- CANopen Sdo entry.
-*/
-
-typedef struct
-{
+/** CANopen Sdo entry.
+ */
+typedef struct {
struct kobject kobj; /**< kobject */
struct list_head list; /**< list item */
ec_sdo_t *sdo; /**< parent Sdo */
@@ -80,17 +74,13 @@
uint16_t data_type; /**< entry data type */
uint16_t bit_length; /**< entry length in bit */
char *description; /**< entry description */
-}
-ec_sdo_entry_t;
+} ec_sdo_entry_t;
/*****************************************************************************/
-/**
- CANopen Sdo configuration data.
-*/
-
-typedef struct
-{
+/** CANopen Sdo configuration data.
+ */
+typedef struct {
struct list_head list; /**< list item */
uint16_t index; /**< Sdo index */
uint8_t subindex; /**< Sdo subindex */
@@ -105,15 +95,15 @@
CANopen Sdo request.
*/
-typedef struct
-{
+typedef struct {
struct list_head list; /**< list item */
- ec_sdo_entry_t *entry; /**< Sdo entry */
+ ec_slave_t *slave; /**< Slave owning the Sdo. */
+ uint16_t index; /**< Sdo index. */
+ uint8_t subindex; /**< Sdo subindex. */
uint8_t *data; /**< pointer to Sdo data */
size_t size; /**< size of Sdo data */
ec_request_state_t state; /**< Sdo request state */
-}
-ec_sdo_request_t;
+} ec_sdo_request_t;
/*****************************************************************************/
@@ -124,7 +114,8 @@
int ec_sdo_entry_init(ec_sdo_entry_t *, uint8_t, ec_sdo_t *);
void ec_sdo_entry_destroy(ec_sdo_entry_t *);
-void ec_sdo_request_init_read(ec_sdo_request_t *, ec_sdo_entry_t *);
+void ec_sdo_request_init_read(ec_sdo_request_t *, ec_slave_t *, uint16_t,
+ uint8_t);
void ec_sdo_request_clear(ec_sdo_request_t *);
/*****************************************************************************/
--- a/master/fsm_coe.c Tue Feb 26 13:20:32 2008 +0000
+++ b/master/fsm_coe.c Tue Feb 26 16:58:20 2008 +0000
@@ -1175,12 +1175,11 @@
ec_slave_t *slave = fsm->slave;
ec_master_t *master = slave->master;
ec_sdo_request_t *request = fsm->request;
- ec_sdo_entry_t *entry = request->entry;
uint8_t *data;
if (master->debug_level)
EC_DBG("Uploading Sdo 0x%04X:%i from slave %i.\n",
- entry->sdo->index, entry->subindex, slave->ring_position);
+ request->index, request->subindex, slave->ring_position);
if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
@@ -1195,8 +1194,8 @@
EC_WRITE_U16(data, 0x2 << 12); // Sdo request
EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
- EC_WRITE_U16(data + 3, entry->sdo->index);
- EC_WRITE_U8 (data + 5, entry->subindex);
+ EC_WRITE_U16(data + 3, request->index);
+ EC_WRITE_U8 (data + 5, request->subindex);
memset(data + 6, 0x00, 4);
if (master->debug_level) {
@@ -1311,7 +1310,6 @@
uint8_t *data, mbox_prot;
size_t rec_size, data_size;
ec_sdo_request_t *request = fsm->request;
- ec_sdo_entry_t *entry = request->entry;
uint32_t complete_size;
unsigned int expedited, size_specified;
@@ -1361,7 +1359,7 @@
if (EC_READ_U16(data) >> 12 == 0x2 && // Sdo request
EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort Sdo transfer request
EC_ERR("Sdo upload 0x%04X:%X aborted on slave %i.\n",
- entry->sdo->index, entry->subindex, slave->ring_position);
+ request->index, request->subindex, slave->ring_position);
if (rec_size >= 10)
ec_canopen_abort_msg(EC_READ_U32(data + 6));
else
@@ -1390,9 +1388,10 @@
if (EC_READ_U16(data) >> 12 != 0x3 || // Sdo response
EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response
- EC_READ_U16(data + 3) != entry->sdo->index || // index
- EC_READ_U8 (data + 5) != entry->subindex) { // subindex
- EC_ERR("Sdo upload 0x%04X:%X failed:\n", entry->sdo->index, entry->subindex);
+ EC_READ_U16(data + 3) != request->index || // index
+ EC_READ_U8 (data + 5) != request->subindex) { // subindex
+ EC_ERR("Sdo upload 0x%04X:%X failed:\n",
+ request->index, request->subindex);
EC_ERR("Invalid Sdo upload response at slave %i!\n",
slave->ring_position);
ec_print_data(data, rec_size);
@@ -1438,9 +1437,10 @@
if (EC_READ_U16(data) >> 12 != 0x3 || // Sdo response
EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response
- EC_READ_U16(data + 3) != entry->sdo->index || // index
- EC_READ_U8 (data + 5) != entry->subindex) { // subindex
- EC_ERR("Sdo upload 0x%04X:%X failed:\n", entry->sdo->index, entry->subindex);
+ EC_READ_U16(data + 3) != request->index || // index
+ EC_READ_U8 (data + 5) != request->subindex) { // subindex
+ EC_ERR("Sdo upload 0x%04X:%X failed:\n",
+ request->index, request->subindex);
EC_ERR("Invalid Sdo upload response at slave %i!\n",
slave->ring_position);
ec_print_data(data, rec_size);
@@ -1602,7 +1602,6 @@
uint8_t *data, mbox_prot;
size_t rec_size, data_size;
ec_sdo_request_t *request = fsm->request;
- ec_sdo_entry_t *entry = request->entry;
uint32_t seg_size;
unsigned int last_segment;
@@ -1652,7 +1651,7 @@
if (EC_READ_U16(data) >> 12 == 0x2 && // Sdo request
EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort Sdo transfer request
EC_ERR("Sdo upload 0x%04X:%X aborted on slave %i.\n",
- entry->sdo->index, entry->subindex, slave->ring_position);
+ request->index, request->subindex, slave->ring_position);
ec_canopen_abort_msg(EC_READ_U32(data + 6));
fsm->state = ec_fsm_coe_error;
return;
@@ -1660,7 +1659,7 @@
if (EC_READ_U16(data) >> 12 != 0x3 || // Sdo response
EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
- EC_ERR("Sdo upload 0x%04X:%X failed:\n", entry->sdo->index, entry->subindex);
+ EC_ERR("Sdo upload 0x%04X:%X failed:\n", request->index, request->subindex);
EC_ERR("Invalid Sdo upload segment response at slave %i!\n",
slave->ring_position);
ec_print_data(data, rec_size);
--- a/master/fsm_coe_map.c Tue Feb 26 13:20:32 2008 +0000
+++ b/master/fsm_coe_map.c Tue Feb 26 16:58:20 2008 +0000
@@ -55,7 +55,7 @@
void ec_fsm_coe_map_state_end(ec_fsm_coe_map_t *);
void ec_fsm_coe_map_state_error(ec_fsm_coe_map_t *);
-void ec_fsm_coe_map_action_next_sync(ec_fsm_coe_map_t *);
+void ec_fsm_coe_map_action_next_dir(ec_fsm_coe_map_t *);
void ec_fsm_coe_map_action_next_pdo(ec_fsm_coe_map_t *);
void ec_fsm_coe_map_action_next_pdo_entry(ec_fsm_coe_map_t *);
@@ -140,49 +140,56 @@
ec_fsm_coe_map_t *fsm /**< finite state machine */
)
{
- // read mapping of first sync manager
- fsm->sync_index = 0;
- ec_fsm_coe_map_action_next_sync(fsm);
-}
-
-/*****************************************************************************/
-
-/**
- * Read mapping of next sync manager.
- */
-
-void ec_fsm_coe_map_action_next_sync(
+ // read mapping for first direction
+ fsm->dir = (ec_direction_t) -1; // next is EC_DIR_OUTPUT
+ ec_fsm_coe_map_action_next_dir(fsm);
+}
+
+/*****************************************************************************/
+
+/**
+ * Read mapping of next direction manager.
+ */
+
+void ec_fsm_coe_map_action_next_dir(
ec_fsm_coe_map_t *fsm /**< finite state machine */
)
{
ec_slave_t *slave = fsm->slave;
- ec_sdo_entry_t *entry;
-
- for (; fsm->sync_index < slave->sii_sync_count; fsm->sync_index++) {
- if (!(fsm->sync_sdo = ec_slave_get_sdo(slave, 0x1C10 + fsm->sync_index)))
+
+ fsm->dir++;
+
+ if (slave->master->debug_level)
+ EC_DBG("Processing dir %u of slave %u.\n",
+ fsm->dir, slave->ring_position);
+
+ for (; fsm->dir <= EC_DIR_INPUT; fsm->dir++) {
+
+ if (!(fsm->sync = ec_slave_get_pdo_sync(slave, fsm->dir))) {
+ if (slave->master->debug_level)
+ EC_DBG("No sync manager for direction %u!\n", fsm->dir);
continue;
+ }
+
+ fsm->sync_sdo_index = 0x1C10 + fsm->sync->index;
if (slave->master->debug_level)
EC_DBG("Reading Pdo mapping of sync manager %u of slave %u.\n",
- fsm->sync_index, slave->ring_position);
+ fsm->sync->index, slave->ring_position);
ec_pdo_mapping_clear_pdos(&fsm->mapping);
- if (!(entry = ec_sdo_get_entry(fsm->sync_sdo, 0))) {
- EC_ERR("Sdo 0x%04X has no subindex 0 on slave %u.\n",
- fsm->sync_sdo->index,
- fsm->slave->ring_position);
- fsm->state = ec_fsm_coe_map_state_error;
- return;
- }
-
- ec_sdo_request_init_read(&fsm->request, entry);
+ ec_sdo_request_init_read(&fsm->request, slave, fsm->sync_sdo_index, 0);
fsm->state = ec_fsm_coe_map_state_pdo_count;
ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
return;
}
+ if (slave->master->debug_level)
+ EC_DBG("Reading of Pdo mapping finished for slave %u.\n",
+ slave->ring_position);
+
fsm->state = ec_fsm_coe_map_state_end;
}
@@ -225,41 +232,27 @@
ec_fsm_coe_map_t *fsm /**< finite state machine */
)
{
- ec_sdo_entry_t *entry;
-
if (fsm->sync_subindex <= fsm->sync_subindices) {
- if (!(entry = ec_sdo_get_entry(fsm->sync_sdo,
- fsm->sync_subindex))) {
- EC_ERR("Sdo 0x%04X has no subindex %u on slave %u.\n",
- fsm->sync_sdo->index,
- fsm->sync_subindex,
- fsm->slave->ring_position);
- fsm->state = ec_fsm_coe_map_state_error;
- return;
- }
-
- ec_sdo_request_init_read(&fsm->request, entry);
+ ec_sdo_request_init_read(&fsm->request, fsm->slave,
+ fsm->sync_sdo_index, fsm->sync_subindex);
fsm->state = ec_fsm_coe_map_state_pdo;
ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
return;
}
- {
- ec_sync_t *sync = fsm->slave->sii_syncs + fsm->sync_index;
-
- if (ec_pdo_mapping_copy(&sync->mapping, &fsm->mapping)) {
- fsm->state = ec_fsm_coe_map_state_error;
- return;
- }
-
- sync->mapping_source = EC_SYNC_MAPPING_COE;
- ec_pdo_mapping_clear_pdos(&fsm->mapping);
-
- // next sync manager
- fsm->sync_index++;
- ec_fsm_coe_map_action_next_sync(fsm);
- }
+ // finished reading Pdo mapping/configuration
+
+ if (ec_pdo_mapping_copy(&fsm->sync->mapping, &fsm->mapping)) {
+ fsm->state = ec_fsm_coe_map_state_error;
+ return;
+ }
+
+ fsm->sync->mapping_source = EC_SYNC_MAPPING_COE;
+ ec_pdo_mapping_clear_pdos(&fsm->mapping);
+
+ // next direction
+ ec_fsm_coe_map_action_next_dir(fsm);
}
/*****************************************************************************/
@@ -281,58 +274,26 @@
return;
}
- {
- ec_sdo_entry_t *entry;
-
- if (!(fsm->pdo = (ec_pdo_t *)
- kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
- EC_ERR("Failed to allocate Pdo.\n");
- fsm->state = ec_fsm_coe_map_state_error;
- return;
- }
-
- ec_pdo_init(fsm->pdo);
- fsm->pdo->index = EC_READ_U16(fsm->request.data);
- fsm->pdo->dir =
- ec_sync_direction(fsm->slave->sii_syncs + fsm->sync_index);
-
- if (fsm->slave->master->debug_level)
- EC_DBG(" Pdo 0x%04X.\n", fsm->pdo->index);
-
- if (!(fsm->pdo_sdo = ec_slave_get_sdo(fsm->slave, fsm->pdo->index))) {
- EC_ERR("Slave %u has no Sdo 0x%04X.\n",
- fsm->slave->ring_position, fsm->pdo->index);
- ec_pdo_clear(fsm->pdo);
- kfree(fsm->pdo);
- fsm->state = ec_fsm_coe_map_state_error;
- return;
- }
-
- if (ec_pdo_set_name(fsm->pdo, fsm->pdo_sdo->name)) {
- ec_pdo_clear(fsm->pdo);
- kfree(fsm->pdo);
- fsm->state = ec_fsm_coe_map_state_error;
- return;
- }
-
- if (!(entry = ec_sdo_get_entry(fsm->pdo_sdo, 0))) {
- EC_ERR("Sdo 0x%04X has no subindex 0 on slave %u.\n",
- fsm->pdo_sdo->index,
- fsm->slave->ring_position);
- ec_pdo_clear(fsm->pdo);
- kfree(fsm->pdo);
- fsm->state = ec_fsm_coe_map_state_error;
- return;
- }
-
- list_add_tail(&fsm->pdo->list, &fsm->mapping.pdos);
-
- ec_sdo_request_init_read(&fsm->request, entry);
- fsm->state = ec_fsm_coe_map_state_pdo_entry_count;
- ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
- ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
- return;
- }
+ if (!(fsm->pdo = (ec_pdo_t *)
+ kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
+ EC_ERR("Failed to allocate Pdo.\n");
+ fsm->state = ec_fsm_coe_map_state_error;
+ return;
+ }
+
+ ec_pdo_init(fsm->pdo);
+ fsm->pdo->index = EC_READ_U16(fsm->request.data);
+ fsm->pdo->dir = ec_sync_direction(fsm->sync);
+
+ if (fsm->slave->master->debug_level)
+ EC_DBG(" Pdo 0x%04X.\n", fsm->pdo->index);
+
+ list_add_tail(&fsm->pdo->list, &fsm->mapping.pdos);
+
+ ec_sdo_request_init_read(&fsm->request, fsm->slave, fsm->pdo->index, 0);
+ fsm->state = ec_fsm_coe_map_state_pdo_entry_count;
+ ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
+ ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
}
/*****************************************************************************/
@@ -374,19 +335,9 @@
ec_fsm_coe_map_t *fsm /**< finite state machine */
)
{
- ec_sdo_entry_t *entry;
-
if (fsm->pdo_subindex <= fsm->pdo_subindices) {
- if (!(entry = ec_sdo_get_entry(fsm->pdo_sdo,
- fsm->pdo_subindex))) {
- EC_ERR("Sdo 0x%04X has no subindex %u on slave %u.\n",
- fsm->pdo_sdo->index, fsm->pdo_subindex,
- fsm->slave->ring_position);
- fsm->state = ec_fsm_coe_map_state_error;
- return;
- }
-
- ec_sdo_request_init_read(&fsm->request, entry);
+ ec_sdo_request_init_read(&fsm->request, fsm->slave,
+ fsm->pdo->index, fsm->pdo_subindex);
fsm->state = ec_fsm_coe_map_state_pdo_entry;
ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
@@ -419,8 +370,6 @@
{
uint32_t pdo_entry_info;
- ec_sdo_t *sdo;
- ec_sdo_entry_t *entry;
ec_pdo_entry_t *pdo_entry;
pdo_entry_info = EC_READ_U32(fsm->request.data);
@@ -438,49 +387,12 @@
pdo_entry->bit_length = pdo_entry_info & 0xFF;
if (!pdo_entry->index && !pdo_entry->subindex) {
- // we have a gap in the Pdo, next Pdo entry
- if (fsm->slave->master->debug_level) {
- EC_DBG(" Pdo entry gap: %u bit.\n",
- pdo_entry->bit_length);
- }
-
if (ec_pdo_entry_set_name(pdo_entry, "Gap")) {
ec_pdo_entry_clear(pdo_entry);
kfree(pdo_entry);
fsm->state = ec_fsm_coe_map_state_error;
return;
}
-
- list_add_tail(&pdo_entry->list, &fsm->pdo->entries);
- fsm->pdo_subindex++;
- ec_fsm_coe_map_action_next_pdo_entry(fsm);
- return;
- }
-
- if (!(sdo = ec_slave_get_sdo(fsm->slave, pdo_entry->index))) {
- EC_ERR("Slave %u has no Sdo 0x%04X.\n",
- fsm->slave->ring_position, pdo_entry->index);
- ec_pdo_entry_clear(pdo_entry);
- kfree(pdo_entry);
- fsm->state = ec_fsm_coe_map_state_error;
- return;
- }
-
- if (!(entry = ec_sdo_get_entry(sdo, pdo_entry->subindex))) {
- EC_ERR("Slave %u has no Sdo entry 0x%04X:%u.\n",
- fsm->slave->ring_position, pdo_entry->index,
- pdo_entry->subindex);
- ec_pdo_entry_clear(pdo_entry);
- kfree(pdo_entry);
- fsm->state = ec_fsm_coe_map_state_error;
- return;
- }
-
- if (ec_pdo_entry_set_name(pdo_entry, entry->description)) {
- ec_pdo_entry_clear(pdo_entry);
- kfree(pdo_entry);
- fsm->state = ec_fsm_coe_map_state_error;
- return;
}
if (fsm->slave->master->debug_level) {
@@ -489,9 +401,8 @@
pdo_entry->bit_length);
}
+ // next Pdo entry
list_add_tail(&pdo_entry->list, &fsm->pdo->entries);
-
- // next Pdo entry
fsm->pdo_subindex++;
ec_fsm_coe_map_action_next_pdo_entry(fsm);
}
--- a/master/fsm_coe_map.h Tue Feb 26 13:20:32 2008 +0000
+++ b/master/fsm_coe_map.h Tue Feb 26 16:58:20 2008 +0000
@@ -61,8 +61,9 @@
ec_slave_t *slave; /**< EtherCAT slave */
ec_sdo_request_t request; /**< Sdo request */
- unsigned int sync_index; /**< index of the current sync manager */
- ec_sdo_t *sync_sdo; /**< pointer to the sync managers mapping Sdo */
+ ec_direction_t dir; /**< index of the current sync manager */
+ ec_sync_t *sync; /**< Pdo sync manager. */
+ uint16_t sync_sdo_index; /**< Index of the mapping Sdo. */
uint8_t sync_subindices; /**< number of mapped Pdos */
uint16_t sync_subindex; /**< current subindex in mapping Sdo */
--- a/master/fsm_master.c Tue Feb 26 13:20:32 2008 +0000
+++ b/master/fsm_master.c Tue Feb 26 16:58:20 2008 +0000
@@ -60,7 +60,6 @@
void ec_fsm_master_state_scan_slaves(ec_fsm_master_t *);
void ec_fsm_master_state_write_eeprom(ec_fsm_master_t *);
void ec_fsm_master_state_sdodict(ec_fsm_master_t *);
-void ec_fsm_master_state_pdomap(ec_fsm_master_t *);
void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
void ec_fsm_master_state_end(ec_fsm_master_t *);
void ec_fsm_master_state_error(ec_fsm_master_t *);
@@ -88,7 +87,8 @@
// init sub-state-machines
ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram);
- ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram);
+ ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram,
+ &fsm->fsm_slave_config, &fsm->fsm_coe_map);
ec_fsm_sii_init(&fsm->fsm_sii, fsm->datagram);
ec_fsm_change_init(&fsm->fsm_change, fsm->datagram);
ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram);
@@ -387,7 +387,7 @@
request->state = EC_REQUEST_IN_PROGRESS;
up(&master->sdo_sem);
- slave = request->entry->sdo->slave;
+ slave = request->slave;
if (slave->current_state == EC_SLAVE_STATE_INIT ||
slave->online_state == EC_SLAVE_OFFLINE ||
slave->error_flag) {
@@ -526,29 +526,6 @@
return;
}
- // check, if slaves have their Pdo mapping to be read.
- list_for_each_entry(slave, &master->slaves, list) {
- if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)
- || slave->pdo_mapping_fetched
- || !slave->sdo_dictionary_fetched
- || slave->current_state == EC_SLAVE_STATE_INIT
- || slave->online_state == EC_SLAVE_OFFLINE) continue;
-
- if (master->debug_level) {
- EC_DBG("Fetching Pdo mapping from slave %i via CoE.\n",
- slave->ring_position);
- }
-
- slave->pdo_mapping_fetched = 1;
-
- // start fetching Pdo mapping
- fsm->idle = 0;
- fsm->state = ec_fsm_master_state_pdomap;
- ec_fsm_coe_map_start(&fsm->fsm_coe_map, slave);
- ec_fsm_coe_map_exec(&fsm->fsm_coe_map); // execute immediately
- return;
- }
-
// check for pending EEPROM write operations.
if (ec_fsm_master_action_process_eeprom(fsm))
return; // EEPROM write request found
@@ -1039,28 +1016,7 @@
/*****************************************************************************/
/**
- * Scan the Pdo mapping of a slave.
- */
-
-void ec_fsm_master_state_pdomap(
- ec_fsm_master_t *fsm /**< master state machine */
- )
-{
- if (ec_fsm_coe_map_exec(&fsm->fsm_coe_map)) return;
-
- if (!ec_fsm_coe_map_success(&fsm->fsm_coe_map)) {
- fsm->state = ec_fsm_master_state_error;
- return;
- }
-
- // fetching of Pdo mapping finished
- fsm->state = ec_fsm_master_state_end;
-}
-
-/*****************************************************************************/
-
-/**
- Master state: Sdo REQUEST.
+ Master state: SDO REQUEST.
*/
void ec_fsm_master_state_sdo_request(ec_fsm_master_t *fsm /**< master state machine */)
--- a/master/fsm_slave_scan.c Tue Feb 26 13:20:32 2008 +0000
+++ b/master/fsm_slave_scan.c Tue Feb 26 16:58:20 2008 +0000
@@ -54,19 +54,31 @@
void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_eeprom_size(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_eeprom_data(ec_fsm_slave_scan_t *);
+void ec_fsm_slave_scan_state_preop(ec_fsm_slave_scan_t *);
+void ec_fsm_slave_scan_state_pdos(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_end(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_error(ec_fsm_slave_scan_t *);
+void ec_fsm_slave_scan_enter_preop(ec_fsm_slave_scan_t *);
+void ec_fsm_slave_scan_enter_pdos(ec_fsm_slave_scan_t *);
+
/*****************************************************************************/
/** Constructor.
*/
-void ec_fsm_slave_scan_init(ec_fsm_slave_scan_t *fsm, /**< slave state machine */
- ec_datagram_t *datagram /**< datagram structure to use */
+void ec_fsm_slave_scan_init(
+ ec_fsm_slave_scan_t *fsm, /**< Slave scanning state machine. */
+ ec_datagram_t *datagram, /**< Datagram to use. */
+ ec_fsm_slave_config_t *fsm_slave_config, /**< Slave configuration
+ state machine to use. */
+ ec_fsm_coe_map_t *fsm_coe_map /**< Pdo mapping state machine to use.
+ */
)
{
fsm->datagram = datagram;
+ fsm->fsm_slave_config = fsm_slave_config;
+ fsm->fsm_coe_map = fsm_coe_map;
// init sub state machines
ec_fsm_sii_init(&fsm->fsm_sii, fsm->datagram);
@@ -556,7 +568,11 @@
}
}
- fsm->state = ec_fsm_slave_scan_state_end;
+ if (slave->sii_mailbox_protocols & EC_MBOX_COE) {
+ ec_fsm_slave_scan_enter_preop(fsm);
+ } else {
+ fsm->state = ec_fsm_slave_scan_state_end;
+ }
return;
end:
@@ -565,6 +581,82 @@
fsm->state = ec_fsm_slave_scan_state_error;
}
+/*****************************************************************************/
+
+void ec_fsm_slave_scan_enter_preop(
+ ec_fsm_slave_scan_t *fsm /**< slave state machine */
+ )
+{
+ ec_slave_t *slave = fsm->slave;
+
+ if ((slave->current_state & EC_SLAVE_STATE_MASK) < EC_SLAVE_STATE_PREOP) {
+ if (slave->master->debug_level)
+ EC_DBG("Slave %u is not in the state to do mailbox com, setting"
+ " to PREOP.\n", slave->ring_position);
+ fsm->state = ec_fsm_slave_scan_state_preop;
+ ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
+ ec_fsm_slave_config_start(fsm->fsm_slave_config, slave);
+ ec_fsm_slave_config_exec(fsm->fsm_slave_config);
+ } else {
+ ec_fsm_slave_scan_enter_pdos(fsm);
+ }
+}
+
+/*****************************************************************************/
+
+/** Slave scan state: PREOP.
+ */
+void ec_fsm_slave_scan_state_preop(
+ ec_fsm_slave_scan_t *fsm /**< slave state machine */
+ )
+{
+ if (ec_fsm_slave_config_exec(fsm->fsm_slave_config))
+ return;
+
+ if (!ec_fsm_slave_config_success(fsm->fsm_slave_config)) {
+ fsm->state = ec_fsm_slave_scan_state_error;
+ return;
+ }
+
+ ec_fsm_slave_scan_enter_pdos(fsm);
+}
+
+/*****************************************************************************/
+
+void ec_fsm_slave_scan_enter_pdos(
+ ec_fsm_slave_scan_t *fsm /**< slave state machine */
+ )
+{
+ ec_slave_t *slave = fsm->slave;
+
+ if (slave->master->debug_level)
+ EC_DBG("Scanning Pdo mapping/configuration of slave %u.\n",
+ slave->ring_position);
+ fsm->state = ec_fsm_slave_scan_state_pdos;
+ ec_fsm_coe_map_start(fsm->fsm_coe_map, slave);
+ ec_fsm_coe_map_exec(fsm->fsm_coe_map); // execute immediately
+}
+
+/*****************************************************************************/
+
+/** Slave scan state: PDOS.
+ */
+void ec_fsm_slave_scan_state_pdos(
+ ec_fsm_slave_scan_t *fsm /**< slave state machine */
+ )
+{
+ if (ec_fsm_coe_map_exec(fsm->fsm_coe_map))
+ return;
+
+ if (!ec_fsm_coe_map_success(fsm->fsm_coe_map)) {
+ fsm->state = ec_fsm_slave_scan_state_error;
+ return;
+ }
+
+ // fetching of Pdo mapping finished
+ fsm->state = ec_fsm_slave_scan_state_end;
+}
+
/******************************************************************************
* Common state functions
*****************************************************************************/
--- a/master/fsm_slave_scan.h Tue Feb 26 13:20:32 2008 +0000
+++ b/master/fsm_slave_scan.h Tue Feb 26 16:58:20 2008 +0000
@@ -49,6 +49,7 @@
#include "fsm_sii.h"
#include "fsm_change.h"
#include "fsm_coe.h"
+#include "fsm_coe_map.h"
#include "fsm_pdo_mapping.h"
#include "fsm_pdo_config.h"
@@ -63,6 +64,9 @@
{
ec_slave_t *slave; /**< Slave the FSM runs on. */
ec_datagram_t *datagram; /**< Datagram used in the state machine. */
+ ec_fsm_slave_config_t *fsm_slave_config; /**< Slave configuration state
+ machine to use. */
+ ec_fsm_coe_map_t *fsm_coe_map; /**< Pdo mapping state machine to use. */
unsigned int retries; /**< Retries on datagram timeout. */
void (*state)(ec_fsm_slave_scan_t *); /**< State function. */
@@ -73,7 +77,8 @@
/*****************************************************************************/
-void ec_fsm_slave_scan_init(ec_fsm_slave_scan_t *, ec_datagram_t *);
+void ec_fsm_slave_scan_init(ec_fsm_slave_scan_t *, ec_datagram_t *,
+ ec_fsm_slave_config_t *, ec_fsm_coe_map_t *);
void ec_fsm_slave_scan_clear(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_start(ec_fsm_slave_scan_t *, ec_slave_t *);
--- a/master/slave.c Tue Feb 26 13:20:32 2008 +0000
+++ b/master/slave.c Tue Feb 26 16:58:20 2008 +0000
@@ -154,7 +154,6 @@
INIT_LIST_HEAD(&slave->sdo_dictionary);
slave->sdo_dictionary_fetched = 0;
- slave->pdo_mapping_fetched = 0;
slave->jiffies_preop = 0;
for (i = 0; i < 4; i++) {
--- a/master/slave.h Tue Feb 26 13:20:32 2008 +0000
+++ b/master/slave.h Tue Feb 26 16:58:20 2008 +0000
@@ -53,6 +53,15 @@
/*****************************************************************************/
+/** Slave state mask.
+ *
+ * Apply this mask to a slave state byte to get the slave state without
+ * the error flag.
+ */
+#define EC_SLAVE_STATE_MASK 0x0F
+
+/*****************************************************************************/
+
/** State of an EtherCAT slave.
*/
typedef enum {
@@ -156,8 +165,6 @@
struct list_head sdo_dictionary; /**< Sdo dictionary list */
uint8_t sdo_dictionary_fetched; /**< dictionary has been fetched */
unsigned long jiffies_preop; /**< time, the slave went to PREOP */
-
- uint8_t pdo_mapping_fetched; /**< Pdo mapping has been fetched */
};
/*****************************************************************************/