SII sync managers as array instead of list, removed sync manager
guessing, ignoring base_sync_count.
This commit is contained in:
parent
d80e8883d2
commit
b75973f27f
|
|
@ -199,23 +199,17 @@ int ec_domain_reg_pdo_entry(ec_domain_t *domain, /**< EtherCAT domain */
|
|||
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 @@ int ec_domain_reg_pdo_range(ec_domain_t *domain, /**< EtherCAT domain */
|
|||
{
|
||||
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 @@ int ec_domain_reg_pdo_range(ec_domain_t *domain, /**< EtherCAT domain */
|
|||
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;
|
||||
}
|
||||
sync = &slave->sii_syncs[sync_index];
|
||||
|
||||
// Allocate memory for data registration object
|
||||
// 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");
|
||||
|
|
|
|||
|
|
@ -319,7 +319,6 @@ void ec_fsm_slave_scan_state_base(ec_fsm_slave_t *fsm /**< slave state machine *
|
|||
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 @@ void ec_fsm_slave_conf_enter_sync(ec_fsm_slave_t *fsm /**< slave state machine *
|
|||
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 @@ void ec_fsm_slave_conf_enter_sync(ec_fsm_slave_t *fsm /**< slave state machine *
|
|||
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);
|
||||
EC_SYNC_SIZE * slave->sii_sync_count);
|
||||
memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->sii_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);
|
||||
}
|
||||
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 @@ void ec_fsm_slave_conf_enter_sync2(ec_fsm_slave_t *fsm /**< slave state machine
|
|||
{
|
||||
ec_slave_t *slave = fsm->slave;
|
||||
ec_datagram_t *datagram = fsm->datagram;
|
||||
ec_sii_sync_t *sync;
|
||||
unsigned int i;
|
||||
|
||||
if (list_empty(&slave->sii_syncs)) {
|
||||
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);
|
||||
EC_SYNC_SIZE * slave->sii_sync_count);
|
||||
memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->sii_sync_count);
|
||||
|
||||
list_for_each_entry(sync, &slave->sii_syncs, list) {
|
||||
ec_slave_sync_config(slave, sync,
|
||||
datagram->data + EC_SYNC_SIZE * sync->index);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -127,7 +127,6 @@ int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */
|
|||
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 @@ int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */
|
|||
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 @@ void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
|
|||
{
|
||||
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 @@ void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
|
|||
}
|
||||
|
||||
// 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_sdos_clear(struct kobject *kobj /**< kobject for SDOs */)
|
|||
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 @@ void ec_slave_reset(ec_slave_t *slave /**< EtherCAT slave */)
|
|||
}
|
||||
|
||||
// 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 @@ int ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT slave */
|
|||
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
|
||||
// sync manager struct is 4 words long
|
||||
slave->sii_sync_count = word_count / 4;
|
||||
|
||||
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;
|
||||
}
|
||||
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->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 @@ size_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
|
|||
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))
|
||||
|
|
|
|||
|
|
@ -116,7 +116,6 @@ ec_sii_string_t;
|
|||
|
||||
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 @@ struct ec_slave
|
|||
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 @@ struct ec_slave
|
|||
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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue