diff --git a/master/fsm.c b/master/fsm.c index cd104d3ed1cdfd424cd43c23790f13fcaaf92dd0..45c9562a55196d90db96781cff1768c825a35a87 100644 --- a/master/fsm.c +++ b/master/fsm.c @@ -1163,7 +1163,7 @@ void ec_fsm_slave_sync(ec_fsm_t *fsm /**< finite state machine */) EC_ERR("Invalid sync manager configuration found!"); return; } - ec_eeprom_sync_config(eeprom_sync, + ec_eeprom_sync_config(eeprom_sync, slave, datagram->data + EC_SYNC_SIZE * eeprom_sync->index); } @@ -1176,14 +1176,14 @@ void ec_fsm_slave_sync(ec_fsm_t *fsm /**< finite state machine */) mbox_sync.length = slave->sii_rx_mailbox_size; mbox_sync.control_register = 0x26; mbox_sync.enable = 1; - ec_eeprom_sync_config(&mbox_sync, datagram->data); + ec_eeprom_sync_config(&mbox_sync, slave, datagram->data); mbox_sync.physical_start_address = slave->sii_tx_mailbox_offset; mbox_sync.length = slave->sii_tx_mailbox_size; mbox_sync.control_register = 0x22; mbox_sync.enable = 1; - ec_eeprom_sync_config(&mbox_sync, + ec_eeprom_sync_config(&mbox_sync, slave, datagram->data + EC_SYNC_SIZE); } diff --git a/master/master.c b/master/master.c index dfa399dc87d03fea70137b9f801e32d603ff6765..67d840819ae0b8d404a6704796849b5225478ce0 100644 --- a/master/master.c +++ b/master/master.c @@ -772,11 +772,16 @@ void ec_sync_config(const ec_sync_t *sync, /**< sync manager */ */ void ec_eeprom_sync_config(const ec_eeprom_sync_t *sync, /**< sync manager */ + const ec_slave_t *slave, /**< EtherCAT slave */ uint8_t *data /**> configuration memory */ ) { + size_t sync_size; + + sync_size = ec_slave_calc_eeprom_sync_size(slave, sync); + EC_WRITE_U16(data, sync->physical_start_address); - EC_WRITE_U16(data + 2, sync->length); + EC_WRITE_U16(data + 2, sync_size); EC_WRITE_U8 (data + 4, sync->control_register); EC_WRITE_U8 (data + 5, 0x00); // status byte (read only) EC_WRITE_U16(data + 6, sync->enable ? 0x0001 : 0x0000); // enable @@ -1130,7 +1135,8 @@ int ecrt_master_activate(ec_master_t *master /**< EtherCAT master */) if (ec_datagram_npwr(datagram, slave->station_address, 0x0800, EC_SYNC_SIZE * slave->base_sync_count)) return -1; - memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count); + memset(datagram->data, 0x00, + EC_SYNC_SIZE * slave->base_sync_count); if (unlikely(ec_master_simple_io(master, datagram))) { EC_ERR("Resetting sync managers failed on slave %i!\n", slave->ring_position); @@ -1139,11 +1145,27 @@ int ecrt_master_activate(ec_master_t *master /**< EtherCAT master */) } // configure sync managers - if (type) { // known slave type, take type's SM information + + // does the slave provide sync manager information? + if (!list_empty(&slave->eeprom_syncs)) { + list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) { + if (ec_datagram_npwr(datagram, slave->station_address, + 0x800 + eeprom_sync->index * + EC_SYNC_SIZE, + EC_SYNC_SIZE)) return -1; + ec_eeprom_sync_config(eeprom_sync, slave, datagram->data); + if (unlikely(ec_master_simple_io(master, datagram))) { + EC_ERR("Setting sync manager %i failed on slave %i!\n", + eeprom_sync->index, slave->ring_position); + return -1; + } + } + } + else if (type) { // known slave type, take type's SM information for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++) { sync = type->sync_managers[j]; if (ec_datagram_npwr(datagram, slave->station_address, - 0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE)) + 0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE)) return -1; ec_sync_config(sync, slave, datagram->data); if (unlikely(ec_master_simple_io(master, datagram))) { @@ -1153,54 +1175,34 @@ int ecrt_master_activate(ec_master_t *master /**< EtherCAT master */) } } } - else if (slave->sii_mailbox_protocols) { // unknown type, but mailbox - // does the device supply SM configurations in its EEPROM? - if (!list_empty(&slave->eeprom_syncs)) { - list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) { - EC_INFO("Sync manager %i...\n", eeprom_sync->index); - if (ec_datagram_npwr(datagram, slave->station_address, - 0x800 + eeprom_sync->index * - EC_SYNC_SIZE, - EC_SYNC_SIZE)) return -1; - ec_eeprom_sync_config(eeprom_sync, datagram->data); - if (unlikely(ec_master_simple_io(master, datagram))) { - EC_ERR("Setting sync manager %i failed on slave %i!\n", - eeprom_sync->index, slave->ring_position); - return -1; - } - } + else { // no sync manager information; guess mailbox settings + mbox_sync.physical_start_address = + slave->sii_rx_mailbox_offset; + mbox_sync.length = slave->sii_rx_mailbox_size; + mbox_sync.control_register = 0x26; + mbox_sync.enable = 1; + if (ec_datagram_npwr(datagram, slave->station_address, + 0x800,EC_SYNC_SIZE)) return -1; + ec_eeprom_sync_config(&mbox_sync, slave, datagram->data); + if (unlikely(ec_master_simple_io(master, datagram))) { + EC_ERR("Setting sync manager 0 failed on slave %i!\n", + slave->ring_position); + return -1; } - else { // no sync manager information; guess mailbox settings - mbox_sync.physical_start_address = - slave->sii_rx_mailbox_offset; - mbox_sync.length = slave->sii_rx_mailbox_size; - mbox_sync.control_register = 0x26; - mbox_sync.enable = 1; - if (ec_datagram_npwr(datagram, slave->station_address, - 0x800,EC_SYNC_SIZE)) return -1; - ec_eeprom_sync_config(&mbox_sync, datagram->data); - if (unlikely(ec_master_simple_io(master, datagram))) { - EC_ERR("Setting sync manager 0 failed on slave %i!\n", - slave->ring_position); - return -1; - } - - mbox_sync.physical_start_address = - slave->sii_tx_mailbox_offset; - mbox_sync.length = slave->sii_tx_mailbox_size; - mbox_sync.control_register = 0x22; - mbox_sync.enable = 1; - if (ec_datagram_npwr(datagram, slave->station_address, - 0x808, EC_SYNC_SIZE)) return -1; - ec_eeprom_sync_config(&mbox_sync, datagram->data); - if (unlikely(ec_master_simple_io(master, datagram))) { + + mbox_sync.physical_start_address = + slave->sii_tx_mailbox_offset; + mbox_sync.length = slave->sii_tx_mailbox_size; + mbox_sync.control_register = 0x22; + mbox_sync.enable = 1; + if (ec_datagram_npwr(datagram, slave->station_address, + 0x808, EC_SYNC_SIZE)) return -1; + ec_eeprom_sync_config(&mbox_sync, slave, datagram->data); + if (unlikely(ec_master_simple_io(master, datagram))) { EC_ERR("Setting sync manager 1 failed on slave %i!\n", slave->ring_position); return -1; - } - } - EC_INFO("Mailbox configured for unknown slave %i\n", - slave->ring_position); + } } // change state to PREOP diff --git a/master/master.h b/master/master.h index 73f6b1c1b46ef0428be6dbbb22e1535e9fced83d..1be89918aacac2602b5f36aadd13bc188d761a4d 100644 --- a/master/master.h +++ b/master/master.h @@ -152,7 +152,8 @@ int ec_master_bus_scan(ec_master_t *); // misc. void ec_master_clear_slaves(ec_master_t *); void ec_sync_config(const ec_sync_t *, const ec_slave_t *, uint8_t *); -void ec_eeprom_sync_config(const ec_eeprom_sync_t *, uint8_t *); +void ec_eeprom_sync_config(const ec_eeprom_sync_t *, const ec_slave_t *, + uint8_t *); void ec_fmmu_config(const ec_fmmu_t *, const ec_slave_t *, uint8_t *); void ec_master_output_stats(ec_master_t *); diff --git a/master/slave.c b/master/slave.c index 32e5903e3e8615549bfa592100dda6b95d6807e1..5e8f627798e87112b9f1f93afa30cdf34f782714 100644 --- a/master/slave.c +++ b/master/slave.c @@ -1494,6 +1494,37 @@ size_t ec_slave_calc_sync_size(const ec_slave_t *slave, /**< EtherCAT slave */ return size; } +/*****************************************************************************/ + +/** + Calculates the size of a sync manager by evaluating PDO sizes. + \return sync manager size +*/ + +uint16_t ec_slave_calc_eeprom_sync_size(const ec_slave_t *slave, + /**< EtherCAT slave */ + const ec_eeprom_sync_t *sync + /**< sync manager */ + ) +{ + ec_eeprom_pdo_t *pdo; + ec_eeprom_pdo_entry_t *pdo_entry; + uint16_t size; + + if (sync->length) return sync->length; + + size = 0; + list_for_each_entry(pdo, &slave->eeprom_pdos, list) { + if (pdo->sync_manager != sync->index) continue; + + list_for_each_entry(pdo_entry, &pdo->entries, list) { + size += pdo_entry->bit_length / 8; + } + } + + return size; +} + /****************************************************************************** * Realtime interface *****************************************************************************/ diff --git a/master/slave.h b/master/slave.h index e2fa8c7e5e7db06982703a7f5cba8bcb00d5d913..96510455739f1feabd9183d0d42f27a8ab39c96d 100644 --- a/master/slave.h +++ b/master/slave.h @@ -326,6 +326,9 @@ int ec_slave_locate_string(ec_slave_t *, unsigned int, char **); // misc. size_t ec_slave_calc_sync_size(const ec_slave_t *, const ec_sync_t *); +uint16_t ec_slave_calc_eeprom_sync_size(const ec_slave_t *, + const ec_eeprom_sync_t *); + void ec_slave_print(const ec_slave_t *, unsigned int); int ec_slave_check_crc(ec_slave_t *);