master/slave.c
changeset 784 0a0994fdafb8
parent 772 6c29e74d6763
child 792 3778920f61e4
equal deleted inserted replaced
783:0e16f97cf752 784:0a0994fdafb8
   330         if (slave->master->debug_level) {
   330         if (slave->master->debug_level) {
   331             char old_state[EC_STATE_STRING_SIZE],
   331             char old_state[EC_STATE_STRING_SIZE],
   332                 cur_state[EC_STATE_STRING_SIZE];
   332                 cur_state[EC_STATE_STRING_SIZE];
   333             ec_state_string(slave->current_state, old_state);
   333             ec_state_string(slave->current_state, old_state);
   334             ec_state_string(new_state, cur_state);
   334             ec_state_string(new_state, cur_state);
   335             EC_DBG("Slave %i: %s -> %s.\n",
   335             EC_DBG("Slave %u: %s -> %s.\n",
   336                    slave->ring_position, old_state, cur_state);
   336                    slave->ring_position, old_state, cur_state);
   337         }
   337         }
   338         slave->current_state = new_state;
   338         slave->current_state = new_state;
   339     }
   339     }
   340 }
   340 }
   352     if (new_state == EC_SLAVE_OFFLINE &&
   352     if (new_state == EC_SLAVE_OFFLINE &&
   353             slave->online_state == EC_SLAVE_ONLINE) {
   353             slave->online_state == EC_SLAVE_ONLINE) {
   354         if (slave->pdos_registered)
   354         if (slave->pdos_registered)
   355             slave->master->pdo_slaves_offline++;
   355             slave->master->pdo_slaves_offline++;
   356         if (slave->master->debug_level)
   356         if (slave->master->debug_level)
   357             EC_DBG("Slave %i: offline.\n", slave->ring_position);
   357             EC_DBG("Slave %u: offline.\n", slave->ring_position);
   358     }
   358     }
   359     else if (new_state == EC_SLAVE_ONLINE &&
   359     else if (new_state == EC_SLAVE_ONLINE &&
   360             slave->online_state == EC_SLAVE_OFFLINE) {
   360             slave->online_state == EC_SLAVE_OFFLINE) {
   361         slave->error_flag = 0; // clear error flag
   361         slave->error_flag = 0; // clear error flag
   362         if (slave->pdos_registered)
   362         if (slave->pdos_registered)
   363             slave->master->pdo_slaves_offline--;
   363             slave->master->pdo_slaves_offline--;
   364         if (slave->master->debug_level) {
   364         if (slave->master->debug_level) {
   365             char cur_state[EC_STATE_STRING_SIZE];
   365             char cur_state[EC_STATE_STRING_SIZE];
   366             ec_state_string(slave->current_state, cur_state);
   366             ec_state_string(slave->current_state, cur_state);
   367             EC_DBG("Slave %i: online (%s).\n",
   367             EC_DBG("Slave %u: online (%s).\n",
   368                    slave->ring_position, cur_state);
   368                    slave->ring_position, cur_state);
   369         }
   369         }
   370     }
   370     }
   371 
   371 
   372     slave->online_state = new_state;
   372     slave->online_state = new_state;
   606 }
   606 }
   607 
   607 
   608 /*****************************************************************************/
   608 /*****************************************************************************/
   609 
   609 
   610 /**
   610 /**
   611    Searches the string list for an index and allocates a new string.
   611    Searches the string list for an index.
   612    \return 0 in case of success, else < 0
   612    \return 0 in case of success, else < 0
   613    \todo documentation
       
   614 */
   613 */
   615 
   614 
   616 char *ec_slave_sii_string(
   615 char *ec_slave_sii_string(
   617         ec_slave_t *slave, /**< EtherCAT slave */
   616         ec_slave_t *slave, /**< EtherCAT slave */
   618         unsigned int index /**< string index */
   617         unsigned int index /**< string index */
   621     if (!index--) 
   620     if (!index--) 
   622         return NULL;
   621         return NULL;
   623 
   622 
   624     if (index >= slave->sii_string_count) {
   623     if (index >= slave->sii_string_count) {
   625         if (slave->master->debug_level)
   624         if (slave->master->debug_level)
   626             EC_WARN("String %i not found in slave %i.\n",
   625             EC_WARN("String %u not found in slave %u.\n",
   627                     index, slave->ring_position);
   626                     index, slave->ring_position);
   628         return NULL;
   627         return NULL;
   629     }
   628     }
   630 
   629 
   631     return slave->sii_strings[index];
   630     return slave->sii_strings[index];
   662     }
   661     }
   663 
   662 
   664     // reserve new FMMU...
   663     // reserve new FMMU...
   665 
   664 
   666     if (slave->fmmu_count >= slave->base_fmmu_count) {
   665     if (slave->fmmu_count >= slave->base_fmmu_count) {
   667         EC_ERR("Slave %i FMMU limit reached!\n", slave->ring_position);
   666         EC_ERR("Slave %u FMMU limit reached!\n", slave->ring_position);
   668         return -1;
   667         return -1;
   669     }
   668     }
   670 
   669 
   671     fmmu = &slave->fmmus[slave->fmmu_count];
   670     fmmu = &slave->fmmus[slave->fmmu_count];
   672 
   671 
   705         return -ENOMEM;
   704         return -ENOMEM;
   706     }
   705     }
   707 
   706 
   708     buf = large_buffer;
   707     buf = large_buffer;
   709 
   708 
   710     buf += sprintf(buf, "Ring position: %i\n",
   709     buf += sprintf(buf, "Ring position: %u\n",
   711                    slave->ring_position);
   710                    slave->ring_position);
   712     buf += sprintf(buf, "State: ");
   711     buf += sprintf(buf, "State: ");
   713     buf += ec_state_string(slave->current_state, buf);
   712     buf += ec_state_string(slave->current_state, buf);
   714     buf += sprintf(buf, " (");
   713     buf += sprintf(buf, " (");
   715     buf += ec_state_string(slave->requested_state, buf);
   714     buf += ec_state_string(slave->requested_state, buf);
   742     }
   741     }
   743     buf += sprintf(buf, "\n");
   742     buf += sprintf(buf, "\n");
   744 
   743 
   745     if (slave->sii_alias)
   744     if (slave->sii_alias)
   746         buf += sprintf(buf, "Configured station alias:"
   745         buf += sprintf(buf, "Configured station alias:"
   747                        " 0x%04X (%i)\n\n", slave->sii_alias, slave->sii_alias);
   746                        " 0x%04X (%u)\n\n", slave->sii_alias, slave->sii_alias);
   748 
   747 
   749     buf += sprintf(buf, "Identity:\n");
   748     buf += sprintf(buf, "Identity:\n");
   750     buf += sprintf(buf, "  Vendor ID: 0x%08X (%u)\n",
   749     buf += sprintf(buf, "  Vendor ID: 0x%08X (%u)\n",
   751                    slave->sii_vendor_id, slave->sii_vendor_id);
   750                    slave->sii_vendor_id, slave->sii_vendor_id);
   752     buf += sprintf(buf, "  Product code: 0x%08X (%u)\n",
   751     buf += sprintf(buf, "  Product code: 0x%08X (%u)\n",
   818         buf += sprintf(buf, "Sync managers / PDO mapping:\n");
   817         buf += sprintf(buf, "Sync managers / PDO mapping:\n");
   819 
   818 
   820         for (i = 0; i < slave->sii_sync_count; i++) {
   819         for (i = 0; i < slave->sii_sync_count; i++) {
   821             sync = &slave->sii_syncs[i];
   820             sync = &slave->sii_syncs[i];
   822             buf += sprintf(buf,
   821             buf += sprintf(buf,
   823                     "  SM%u: addr 0x%04X, size %i, control 0x%02X, %s\n",
   822                     "  SM%u: addr 0x%04X, size %u, control 0x%02X, %s\n",
   824                     sync->index, sync->physical_start_address,
   823                     sync->index, sync->physical_start_address,
   825                     ec_sync_size(sync), sync->control_register,
   824                     ec_sync_size(sync), sync->control_register,
   826                     sync->enable ? "enable" : "disable");
   825                     sync->enable ? "enable" : "disable");
   827 
   826 
   828             if (list_empty(&sync->pdos)) {
   827             if (list_empty(&sync->pdos)) {
   839                         pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
   838                         pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
   840                         pdo->index, pdo->name ? pdo->name : "???");
   839                         pdo->index, pdo->name ? pdo->name : "???");
   841 
   840 
   842                 list_for_each_entry(pdo_entry, &pdo->entries, list) {
   841                 list_for_each_entry(pdo_entry, &pdo->entries, list) {
   843                     buf += sprintf(buf,
   842                     buf += sprintf(buf,
   844                             "      0x%04X:%X \"%s\", %i bit\n",
   843                             "      0x%04X:%X \"%s\", %u bit\n",
   845                             pdo_entry->index, pdo_entry->subindex,
   844                             pdo_entry->index, pdo_entry->subindex,
   846                             pdo_entry->name ? pdo_entry->name : "???",
   845                             pdo_entry->name ? pdo_entry->name : "???",
   847                             pdo_entry->bit_length);
   846                             pdo_entry->bit_length);
   848                 }
   847                 }
   849             }
   848             }
   864                         pdo->sync_index);
   863                         pdo->sync_index);
   865             else
   864             else
   866                 buf += sprintf(buf, ", no default mapping.\n");
   865                 buf += sprintf(buf, ", no default mapping.\n");
   867 
   866 
   868             list_for_each_entry(pdo_entry, &pdo->entries, list) {
   867             list_for_each_entry(pdo_entry, &pdo->entries, list) {
   869                 buf += sprintf(buf, "    0x%04X:%X \"%s\", %i bit\n",
   868                 buf += sprintf(buf, "    0x%04X:%X \"%s\", %u bit\n",
   870                         pdo_entry->index, pdo_entry->subindex,
   869                         pdo_entry->index, pdo_entry->subindex,
   871                         pdo_entry->name ? pdo_entry->name : "???",
   870                         pdo_entry->name ? pdo_entry->name : "???",
   872                         pdo_entry->bit_length);
   871                         pdo_entry->bit_length);
   873             }
   872             }
   874         }
   873         }
   879     if (!list_empty((struct list_head *) &slave->sdo_confs)) {
   878     if (!list_empty((struct list_head *) &slave->sdo_confs)) {
   880         buf += sprintf(buf, "SDO configurations:\n");
   879         buf += sprintf(buf, "SDO configurations:\n");
   881 
   880 
   882         list_for_each_entry(sdodata, &slave->sdo_confs, list) {
   881         list_for_each_entry(sdodata, &slave->sdo_confs, list) {
   883             switch (sdodata->size) {
   882             switch (sdodata->size) {
   884                 case 1: sprintf(str, "%i", EC_READ_U8(sdodata->data)); break;
   883                 case 1: sprintf(str, "%u", EC_READ_U8(sdodata->data)); break;
   885                 case 2: sprintf(str, "%i", EC_READ_U16(sdodata->data)); break;
   884                 case 2: sprintf(str, "%u", EC_READ_U16(sdodata->data)); break;
   886                 case 4: sprintf(str, "%i", EC_READ_U32(sdodata->data)); break;
   885                 case 4: sprintf(str, "%u", EC_READ_U32(sdodata->data)); break;
   887                 default: sprintf(str, "(invalid size)"); break;
   886                 default: sprintf(str, "(invalid size)"); break;
   888             }
   887             }
   889             buf += sprintf(buf, "  0x%04X:%-3i -> %s\n",
   888             buf += sprintf(buf, "  0x%04X:%-3i -> %s\n",
   890                     sdodata->index, sdodata->subindex, str);
   889                     sdodata->index, sdodata->subindex, str);
   891         }
   890         }
  1154         }
  1153         }
  1155     }
  1154     }
  1156     else if (attr == &attr_eeprom) {
  1155     else if (attr == &attr_eeprom) {
  1157         if (slave->eeprom_data) {
  1156         if (slave->eeprom_data) {
  1158             if (slave->eeprom_size > PAGE_SIZE) {
  1157             if (slave->eeprom_size > PAGE_SIZE) {
  1159                 EC_ERR("EEPROM contents of slave %i exceed 1 page (%i/%i).\n",
  1158                 EC_ERR("EEPROM contents of slave %u exceed 1 page (%u/%u).\n",
  1160                        slave->ring_position, slave->eeprom_size,
  1159                        slave->ring_position, slave->eeprom_size,
  1161                        (int) PAGE_SIZE);
  1160                        (int) PAGE_SIZE);
  1162             }
  1161             }
  1163             else {
  1162             else {
  1164                 memcpy(buffer, slave->eeprom_data, slave->eeprom_size);
  1163                 memcpy(buffer, slave->eeprom_data, slave->eeprom_size);
  1202             EC_ERR("Invalid slave state \"%s\"!\n", buffer);
  1201             EC_ERR("Invalid slave state \"%s\"!\n", buffer);
  1203             return -EINVAL;
  1202             return -EINVAL;
  1204         }
  1203         }
  1205 
  1204 
  1206         ec_state_string(slave->requested_state, state);
  1205         ec_state_string(slave->requested_state, state);
  1207         EC_INFO("Accepted new state %s for slave %i.\n",
  1206         EC_INFO("Accepted new state %s for slave %u.\n",
  1208                 state, slave->ring_position);
  1207                 state, slave->ring_position);
  1209         return size;
  1208         return size;
  1210     }
  1209     }
  1211     else if (attr == &attr_eeprom) {
  1210     else if (attr == &attr_eeprom) {
  1212         return ec_slave_write_eeprom(slave, buffer, size);
  1211         return ec_slave_write_eeprom(slave, buffer, size);
  1260                       )
  1259                       )
  1261 {
  1260 {
  1262     ec_sdo_data_t *sdodata;
  1261     ec_sdo_data_t *sdodata;
  1263 
  1262 
  1264     if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
  1263     if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
  1265         EC_ERR("Slave %i does not support CoE!\n", slave->ring_position);
  1264         EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
  1266         return -1;
  1265         return -1;
  1267     }
  1266     }
  1268 
  1267 
  1269     if (!(sdodata = (ec_sdo_data_t *)
  1268     if (!(sdodata = (ec_sdo_data_t *)
  1270           kmalloc(sizeof(ec_sdo_data_t), GFP_KERNEL))) {
  1269           kmalloc(sizeof(ec_sdo_data_t), GFP_KERNEL))) {
  1298                       uint32_t product_code /**< product code */
  1297                       uint32_t product_code /**< product code */
  1299                       )
  1298                       )
  1300 {
  1299 {
  1301     if (vendor_id != slave->sii_vendor_id ||
  1300     if (vendor_id != slave->sii_vendor_id ||
  1302         product_code != slave->sii_product_code) {
  1301         product_code != slave->sii_product_code) {
  1303         EC_ERR("Invalid slave type at position %i:\n", slave->ring_position);
  1302         EC_ERR("Invalid slave type at position %u:\n", slave->ring_position);
  1304         EC_ERR("  Requested: 0x%08X 0x%08X\n", vendor_id, product_code);
  1303         EC_ERR("  Requested: 0x%08X 0x%08X\n", vendor_id, product_code);
  1305         EC_ERR("      Found: 0x%08X 0x%08X\n",
  1304         EC_ERR("      Found: 0x%08X 0x%08X\n",
  1306                 slave->sii_vendor_id, slave->sii_product_code);
  1305                 slave->sii_vendor_id, slave->sii_product_code);
  1307         return -1;
  1306         return -1;
  1308     }
  1307     }
  1426         )
  1425         )
  1427 {
  1426 {
  1428     ec_sync_t *sync;
  1427     ec_sync_t *sync;
  1429 
  1428 
  1430     if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
  1429     if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
  1431         EC_ERR("Slave %i does not support CoE!\n", slave->ring_position);
  1430         EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
  1432         return;
  1431         return;
  1433     }
  1432     }
  1434 
  1433 
  1435     if (!(sync = ec_slave_get_pdo_sync(slave, dir)))
  1434     if (!(sync = ec_slave_get_pdo_sync(slave, dir)))
  1436         return;
  1435         return;
  1457     if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
  1456     if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
  1458         EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
  1457         EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
  1459         return -1;
  1458         return -1;
  1460     }
  1459     }
  1461 
  1460 
  1462     // does the slave provide the PDO?
  1461     // does the slave provide the PDO? FIXME
  1463     list_for_each_entry(pdo, &slave->sii_pdos, list) {
  1462     list_for_each_entry(pdo, &slave->sii_pdos, list) {
  1464         if (pdo->index == pdo_index) {
  1463         if (pdo->index == pdo_index) {
  1465             not_found = 0;
  1464             not_found = 0;
  1466             break;
  1465             break;
  1467         }
  1466         }