--- a/master/domain.c Mon Mar 05 16:59:02 2007 +0000
+++ b/master/domain.c Tue Mar 06 09:06:01 2007 +0000
@@ -199,23 +199,17 @@
const ec_sii_sync_t *sync;
const ec_sii_pdo_t *other_pdo;
const ec_sii_pdo_entry_t *other_entry;
- unsigned int bit_offset, byte_offset, sync_found;
+ unsigned int bit_offset, byte_offset;
// Find sync manager for PDO
- sync_found = 0;
- list_for_each_entry(sync, &slave->sii_syncs, list) {
- if (sync->index == pdo->sync_index) {
- sync_found = 1;
- break;
- }
- }
-
- if (!sync_found) {
+ if (pdo->sync_index >= slave->sii_sync_count) {
EC_ERR("No sync manager for PDO 0x%04X:%i.",
pdo->index, entry->subindex);
return -1;
}
+ sync = &slave->sii_syncs[pdo->sync_index];
+
// Calculate offset (in sync manager) for process data pointer
bit_offset = 0;
byte_offset = 0;
@@ -272,10 +266,10 @@
{
ec_data_reg_t *data_reg;
ec_sii_sync_t *sync;
- unsigned int sync_found, sync_index;
+ unsigned int sync_index;
uint16_t sync_length;
- switch (dir) {
+ switch (dir) { // FIXME
case EC_DIR_OUTPUT: sync_index = 2; break;
case EC_DIR_INPUT: sync_index = 3; break;
default:
@@ -283,21 +277,13 @@
return -1;
}
- // Find sync manager
- sync_found = 0;
- list_for_each_entry(sync, &slave->sii_syncs, list) {
- if (sync->index == sync_index) {
- sync_found = 1;
- break;
- }
- }
-
- if (!sync_found) {
+ if (sync_index >= slave->sii_sync_count) {
EC_ERR("No sync manager found for PDO range.\n");
return -1;
}
-
- // Allocate memory for data registration object
+ sync = &slave->sii_syncs[sync_index];
+
+ // Allocate memory for data registration object
if (!(data_reg =
(ec_data_reg_t *) kmalloc(sizeof(ec_data_reg_t), GFP_KERNEL))) {
EC_ERR("Failed to allocate data registration.\n");
--- a/master/fsm_slave.c Mon Mar 05 16:59:02 2007 +0000
+++ b/master/fsm_slave.c Tue Mar 06 09:06:01 2007 +0000
@@ -319,7 +319,6 @@
slave->base_revision = EC_READ_U8 (datagram->data + 1);
slave->base_build = EC_READ_U16(datagram->data + 2);
slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4);
- slave->base_sync_count = EC_READ_U8 (datagram->data + 5);
if (slave->base_fmmu_count > EC_MAX_FMMUS)
slave->base_fmmu_count = EC_MAX_FMMUS;
@@ -661,8 +660,7 @@
ec_master_t *master = fsm->slave->master;
ec_slave_t *slave = fsm->slave;
ec_datagram_t *datagram = fsm->datagram;
- const ec_sii_sync_t *sync;
- ec_sii_sync_t mbox_sync;
+ unsigned int i;
// slave is now in INIT
if (slave->current_state == slave->requested_state) {
@@ -674,51 +672,25 @@
return;
}
- if (!slave->base_sync_count) { // no sync managers
+ if (!slave->sii_mailbox_protocols || slave->sii_sync_count < 2) {
+ // no mailbox sync managers to be configured
ec_fsm_slave_conf_enter_preop(fsm);
return;
}
if (master->debug_level) {
- EC_DBG("Configuring sync managers of slave %i.\n",
+ EC_DBG("Configuring mailbox sync managers of slave %i.\n",
slave->ring_position);
}
// configure sync managers
ec_datagram_npwr(datagram, slave->station_address, 0x0800,
- EC_SYNC_SIZE * slave->base_sync_count);
- memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
-
- if (list_empty(&slave->sii_syncs)) {
- if (slave->sii_rx_mailbox_offset && slave->sii_tx_mailbox_offset) {
- if (slave->master->debug_level)
- EC_DBG("Guessing sync manager settings for slave %i.\n",
- slave->ring_position);
- mbox_sync.index = 0;
- mbox_sync.physical_start_address = slave->sii_tx_mailbox_offset;
- mbox_sync.length = slave->sii_tx_mailbox_size;
- mbox_sync.control_register = 0x26;
- mbox_sync.enable = 0x01;
- mbox_sync.est_length = 0;
- ec_slave_sync_config(slave, &mbox_sync,
- datagram->data + EC_SYNC_SIZE * mbox_sync.index);
- mbox_sync.index = 1;
- mbox_sync.physical_start_address = slave->sii_rx_mailbox_offset;
- mbox_sync.length = slave->sii_rx_mailbox_size;
- mbox_sync.control_register = 0x22;
- mbox_sync.enable = 0x01;
- mbox_sync.est_length = 0;
- ec_slave_sync_config(slave, &mbox_sync,
- datagram->data + EC_SYNC_SIZE * mbox_sync.index);
- }
- }
- else if (slave->sii_mailbox_protocols) { // mailboxes present
- list_for_each_entry(sync, &slave->sii_syncs, list) {
- // only configure mailbox sync-managers
- if (sync->index != 0 && sync->index != 1) continue;
- ec_slave_sync_config(slave, sync,
- datagram->data + EC_SYNC_SIZE * sync->index);
- }
+ EC_SYNC_SIZE * slave->sii_sync_count);
+ memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->sii_sync_count);
+
+ for (i = 0; i < 2; i++) {
+ ec_slave_sync_config(slave, &slave->sii_syncs[i],
+ datagram->data + EC_SYNC_SIZE * i);
}
ec_master_queue_datagram(fsm->slave->master, datagram);
@@ -820,21 +792,21 @@
{
ec_slave_t *slave = fsm->slave;
ec_datagram_t *datagram = fsm->datagram;
- ec_sii_sync_t *sync;
-
- if (list_empty(&slave->sii_syncs)) {
+ unsigned int i;
+
+ if (!slave->sii_sync_count) {
ec_fsm_slave_conf_enter_fmmu(fsm);
return;
}
// configure sync managers for process data
ec_datagram_npwr(datagram, slave->station_address, 0x0800,
- EC_SYNC_SIZE * slave->base_sync_count);
- memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
-
- list_for_each_entry(sync, &slave->sii_syncs, list) {
- ec_slave_sync_config(slave, sync,
- datagram->data + EC_SYNC_SIZE * sync->index);
+ EC_SYNC_SIZE * slave->sii_sync_count);
+ memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->sii_sync_count);
+
+ for (i = 0; i < slave->sii_sync_count; i++) {
+ ec_slave_sync_config(slave, &slave->sii_syncs[i],
+ datagram->data + EC_SYNC_SIZE * i);
}
ec_master_queue_datagram(fsm->slave->master, datagram);
--- a/master/slave.c Mon Mar 05 16:59:02 2007 +0000
+++ b/master/slave.c Tue Mar 06 09:06:01 2007 +0000
@@ -127,7 +127,6 @@
slave->base_revision = 0;
slave->base_build = 0;
slave->base_fmmu_count = 0;
- slave->base_sync_count = 0;
slave->eeprom_data = NULL;
slave->eeprom_size = 0;
@@ -149,7 +148,8 @@
slave->sii_current_on_ebus = 0;
INIT_LIST_HEAD(&slave->sii_strings);
- INIT_LIST_HEAD(&slave->sii_syncs);
+ slave->sii_syncs = NULL;
+ slave->sii_sync_count = 0;
INIT_LIST_HEAD(&slave->sii_pdos);
INIT_LIST_HEAD(&slave->sdo_dictionary);
INIT_LIST_HEAD(&slave->sdo_confs);
@@ -240,7 +240,6 @@
{
ec_slave_t *slave;
ec_sii_string_t *string, *next_str;
- ec_sii_sync_t *sync, *next_sync;
ec_sii_pdo_t *pdo, *next_pdo;
ec_sii_pdo_entry_t *entry, *next_ent;
ec_sdo_data_t *sdodata, *next_sdodata;
@@ -254,10 +253,7 @@
}
// free all sync managers
- list_for_each_entry_safe(sync, next_sync, &slave->sii_syncs, list) {
- list_del(&sync->list);
- kfree(sync);
- }
+ if (slave->sii_syncs) kfree(slave->sii_syncs);
// free all PDOs
list_for_each_entry_safe(pdo, next_pdo, &slave->sii_pdos, list) {
@@ -309,7 +305,7 @@
void ec_slave_reset(ec_slave_t *slave /**< EtherCAT slave */)
{
ec_sdo_data_t *sdodata, *next_sdodata;
- ec_sii_sync_t *sync;
+ unsigned int i;
// remove FMMU configurations
slave->fmmu_count = 0;
@@ -323,8 +319,8 @@
}
// remove estimated sync manager sizes
- list_for_each_entry(sync, &slave->sii_syncs, list) {
- sync->est_length = 0;
+ for (i = 0; i < slave->sii_sync_count; i++) {
+ slave->sii_syncs[i].est_length = 0;
}
}
@@ -472,27 +468,28 @@
size_t word_count /**< number of words */
)
{
- unsigned int sync_count, i;
+ unsigned int i;
ec_sii_sync_t *sync;
- sync_count = word_count / 4; // sync manager struct is 4 words long
-
- for (i = 0; i < sync_count; i++, data += 8) {
- if (!(sync = (ec_sii_sync_t *)
- kmalloc(sizeof(ec_sii_sync_t), GFP_ATOMIC))) {
- EC_ERR("Failed to allocate Sync-Manager memory.\n");
- return -1;
- }
-
- sync->index = i;
+ // sync manager struct is 4 words long
+ slave->sii_sync_count = word_count / 4;
+
+ if (!(slave->sii_syncs = kmalloc(sizeof(ec_sii_sync_t) *
+ slave->sii_sync_count, GFP_ATOMIC))) {
+ EC_ERR("Failed to allocate Sync-Manager memory.\n");
+ return -1;
+ }
+
+ for (i = 0; i < slave->sii_sync_count; i++, data += 8) {
+ sync = &slave->sii_syncs[i];
+
+ sync->index = i;
sync->physical_start_address = EC_READ_U16(data);
sync->length = EC_READ_U16(data + 2);
sync->control_register = EC_READ_U8 (data + 4);
sync->enable = EC_READ_U8 (data + 6);
-
+
sync->est_length = 0;
-
- list_add_tail(&sync->list, &slave->sii_syncs);
}
return 0;
@@ -785,15 +782,16 @@
if (slave->sii_order)
off += sprintf(buffer + off, " Order number: %s\n", slave->sii_order);
- if (!list_empty(&slave->sii_syncs))
+ if (slave->sii_sync_count)
off += sprintf(buffer + off, "\nSync-Managers:\n");
- list_for_each_entry(sync, &slave->sii_syncs, list) {
+ for (i = 0; i < slave->sii_sync_count; i++) {
+ sync = &slave->sii_syncs[i];
off += sprintf(buffer + off, " %i: 0x%04X, length %i,"
- " control 0x%02X, %s\n",
- sync->index, sync->physical_start_address,
- sync->length, sync->control_register,
- sync->enable ? "enable" : "disable");
+ " control 0x%02X, %s\n",
+ sync->index, sync->physical_start_address,
+ sync->length, sync->control_register,
+ sync->enable ? "enable" : "disable");
}
if (!list_empty(&slave->sii_pdos))
--- a/master/slave.h Mon Mar 05 16:59:02 2007 +0000
+++ b/master/slave.h Tue Mar 06 09:06:01 2007 +0000
@@ -116,7 +116,6 @@
typedef struct
{
- struct list_head list; /**< list item */
unsigned int index; /**< sync manager index */
uint16_t physical_start_address; /**< physical start address */
uint16_t length; /**< data length in bytes */
@@ -219,7 +218,6 @@
uint8_t base_revision; /**< revision */
uint16_t base_build; /**< build number */
uint16_t base_fmmu_count; /**< number of supported FMMUs */
- uint16_t base_sync_count; /**< number of supported sync managers */
// data link status
uint8_t dl_link[4]; /**< link detected */
@@ -243,7 +241,8 @@
uint16_t sii_mailbox_protocols; /**< supported mailbox protocols */
uint8_t sii_physical_layer[4]; /**< port media */
struct list_head sii_strings; /**< EEPROM STRING categories */
- struct list_head sii_syncs; /**< EEPROM SYNC MANAGER categories */
+ ec_sii_sync_t *sii_syncs; /**< EEPROM SYNC MANAGER categories */
+ unsigned int sii_sync_count; /**< number of sync managers in EEPROM */
struct list_head sii_pdos; /**< EEPROM [RT]XPDO categories */
char *sii_group; /**< slave group acc. to EEPROM */
char *sii_image; /**< slave image name acc. to EEPROM */