master/slave.c
changeset 123 4d5dc58d48e2
parent 122 132c3ffc8dea
child 124 2a5d42513099
equal deleted inserted replaced
122:132c3ffc8dea 123:4d5dc58d48e2
     1 /******************************************************************************
     1 /******************************************************************************
     2  *
     2  *
     3  *  s l a v e . c
     3  *  s l a v e . c
     4  *
     4  *
     5  *  Methoden fŽür einen EtherCAT-Slave.
     5  *  Methoden für einen EtherCAT-Slave.
     6  *
     6  *
     7  *  $Id$
     7  *  $Id$
     8  *
     8  *
     9  *****************************************************************************/
     9  *****************************************************************************/
    10 
    10 
    18 
    18 
    19 /*****************************************************************************/
    19 /*****************************************************************************/
    20 
    20 
    21 int ec_slave_fetch_categories(ec_slave_t *);
    21 int ec_slave_fetch_categories(ec_slave_t *);
    22 int ec_slave_fetch_strings(ec_slave_t *, const uint8_t *);
    22 int ec_slave_fetch_strings(ec_slave_t *, const uint8_t *);
    23 void ec_slave_fetch_general(ec_slave_t *, const uint8_t *);
    23 int ec_slave_fetch_general(ec_slave_t *, const uint8_t *);
    24 void ec_slave_fetch_fmmu(ec_slave_t *, const uint8_t *);
    24 void ec_slave_fetch_fmmu(ec_slave_t *, const uint8_t *);
    25 void ec_slave_fetch_sync(ec_slave_t *, const uint8_t *);
    25 void ec_slave_fetch_sync(ec_slave_t *, const uint8_t *);
    26 void ec_slave_fetch_txpdo(ec_slave_t *, const uint8_t *);
    26 void ec_slave_fetch_txpdo(ec_slave_t *, const uint8_t *);
    27 void ec_slave_fetch_rxpdo(ec_slave_t *, const uint8_t *);
    27 void ec_slave_fetch_rxpdo(ec_slave_t *, const uint8_t *);
       
    28 int ec_slave_locate_string(ec_slave_t *, unsigned int, char **);
    28 
    29 
    29 /*****************************************************************************/
    30 /*****************************************************************************/
    30 
    31 
    31 /**
    32 /**
    32    EtherCAT-Slave-Konstruktor.
    33    EtherCAT-Slave-Konstruktor.
   159 int ec_slave_sii_read(ec_slave_t *slave,
   160 int ec_slave_sii_read(ec_slave_t *slave,
   160                       /**< EtherCAT-Slave */
   161                       /**< EtherCAT-Slave */
   161                       uint16_t offset,
   162                       uint16_t offset,
   162                       /**< Adresse des zu lesenden SII-Registers */
   163                       /**< Adresse des zu lesenden SII-Registers */
   163                       uint32_t *target
   164                       uint32_t *target
   164                       /**< Zeiger auf einen 4 Byte groŽßen Speicher zum Ablegen
   165                       /**< Zeiger auf einen 4 Byte groÂŽßen Speicher zum Ablegen
   165                          der Daten */
   166                          der Daten */
   166                       )
   167                       )
   167 {
   168 {
   168     ec_command_t command;
   169     ec_command_t command;
   169     uint8_t data[10];
   170     uint8_t data[10];
   314 
   315 
   315     while (1) {
   316     while (1) {
   316         // read category header
   317         // read category header
   317         if (ec_slave_sii_read(slave, word_offset, &value)) {
   318         if (ec_slave_sii_read(slave, word_offset, &value)) {
   318             EC_ERR("Unable to read category header and size.\n");
   319             EC_ERR("Unable to read category header and size.\n");
   319             kfree(cat_data);
   320             goto out_free;
   320             return -1;
       
   321         }
   321         }
   322 
   322 
   323         // Last category?
   323         // Last category?
   324         if ((value & 0xFFFF) == 0xFFFF) break;
   324         if ((value & 0xFFFF) == 0xFFFF) break;
   325 
   325 
   328 
   328 
   329         // Fetch category data
   329         // Fetch category data
   330         for (i = 0; i < word_count; i++) {
   330         for (i = 0; i < word_count; i++) {
   331             if (ec_slave_sii_read(slave, word_offset + 2 + i, &value)) {
   331             if (ec_slave_sii_read(slave, word_offset + 2 + i, &value)) {
   332                 EC_ERR("Unable to read category data word %i.\n", i);
   332                 EC_ERR("Unable to read category data word %i.\n", i);
   333                 kfree(cat_data);
   333                 goto out_free;
   334                 return -1;
       
   335             }
   334             }
   336 
   335 
   337             cat_data[i * 2]     = (value >> 0) & 0xFF;
   336             cat_data[i * 2]     = (value >> 0) & 0xFF;
   338             cat_data[i * 2 + 1] = (value >> 8) & 0xFF;
   337             cat_data[i * 2 + 1] = (value >> 8) & 0xFF;
   339 
   338 
   346         }
   345         }
   347 
   346 
   348         switch (header)
   347         switch (header)
   349         {
   348         {
   350             case 0x000A:
   349             case 0x000A:
   351                 if (ec_slave_fetch_strings(slave, cat_data)) {
   350                 if (ec_slave_fetch_strings(slave, cat_data))
   352                     kfree(cat_data);
   351                     goto out_free;
   353                     return -1;
       
   354                 }
       
   355                 break;
   352                 break;
   356             case 0x001E:
   353             case 0x001E:
   357             case 0x0001:
   354             case 0x0001:
   358                 ec_slave_fetch_general(slave, cat_data);
   355                 if (ec_slave_fetch_general(slave, cat_data))
       
   356                     goto out_free;
   359                 break;
   357                 break;
   360             case 0x0028:
   358             case 0x0028:
   361             case 0x0002:
   359             case 0x0002:
   362                 ec_slave_fetch_fmmu(slave, cat_data);
   360                 ec_slave_fetch_fmmu(slave, cat_data);
   363                 break;
   361                 break;
   381         word_offset += 2 + word_count;
   379         word_offset += 2 + word_count;
   382     }
   380     }
   383 
   381 
   384     kfree(cat_data);
   382     kfree(cat_data);
   385     return 0;
   383     return 0;
       
   384 
       
   385  out_free:
       
   386     kfree(cat_data);
       
   387     return -1;
   386 }
   388 }
   387 
   389 
   388 /*****************************************************************************/
   390 /*****************************************************************************/
   389 
   391 
   390 /**
   392 /**
   428 
   430 
   429 /**
   431 /**
   430    Holt die Daten einer General-Kategorie.
   432    Holt die Daten einer General-Kategorie.
   431 */
   433 */
   432 
   434 
   433 void ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT-Slave */
   435 int ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT-Slave */
   434                             const uint8_t *data /**< Kategorie-Daten */
   436                            const uint8_t *data /**< Kategorie-Daten */
   435                             )
   437                            )
   436 {
   438 {
       
   439     if (ec_slave_locate_string(slave, data[0], &slave->eeprom_group))
       
   440         return -1;
       
   441     if (ec_slave_locate_string(slave, data[1], &slave->eeprom_name))
       
   442         return -1;
       
   443     if (ec_slave_locate_string(slave, data[3], &slave->eeprom_desc))
       
   444         return -1;
       
   445 
       
   446     return 0;
   437 }
   447 }
   438 
   448 
   439 /*****************************************************************************/
   449 /*****************************************************************************/
   440 
   450 
   441 /**
   451 /**
   480 
   490 
   481 void ec_slave_fetch_rxpdo(ec_slave_t *slave, /**< EtherCAT-Slave */
   491 void ec_slave_fetch_rxpdo(ec_slave_t *slave, /**< EtherCAT-Slave */
   482                           const uint8_t *data /**< Kategorie-Daten */
   492                           const uint8_t *data /**< Kategorie-Daten */
   483                           )
   493                           )
   484 {
   494 {
       
   495 }
       
   496 
       
   497 /*****************************************************************************/
       
   498 
       
   499 /**
       
   500    Durchsucht die temporären Strings und dupliziert den gefundenen String.
       
   501 */
       
   502 
       
   503 int ec_slave_locate_string(ec_slave_t *slave, unsigned int index, char **ptr)
       
   504 {
       
   505     ec_slave_string_t *string;
       
   506 
       
   507     if (*ptr) {
       
   508         kfree(*ptr);
       
   509         *ptr = NULL;
       
   510     }
       
   511 
       
   512     if (!index) return 0;
       
   513 
       
   514     list_for_each_entry(string, &slave->eeprom_strings, list) {
       
   515         if (!(--index)) {
       
   516             if (!(*ptr = (char *) kmalloc(string->size + 1, GFP_KERNEL))) {
       
   517                 EC_ERR("Unable to allocate string memory.\n");
       
   518                 return -1;
       
   519             }
       
   520             memcpy(*ptr, string->data, string->size + 1);
       
   521             break;
       
   522         }
       
   523     }
       
   524 
       
   525     return 0;
   485 }
   526 }
   486 
   527 
   487 /*****************************************************************************/
   528 /*****************************************************************************/
   488 
   529 
   489 /**
   530 /**
   661    Gibt alle Informationen über einen EtherCAT-Slave aus.
   702    Gibt alle Informationen über einen EtherCAT-Slave aus.
   662 */
   703 */
   663 
   704 
   664 void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */)
   705 void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */)
   665 {
   706 {
   666     EC_INFO("--- EtherCAT slave information ---\n");
   707     EC_INFO("x-- EtherCAT slave information ---------------\n");
   667 
   708 
   668     if (slave->type) {
   709     if (slave->type) {
   669         EC_INFO("  Vendor \"%s\", Product \"%s\": %s\n",
   710         EC_INFO("| Vendor \"%s\", Product \"%s\": %s\n",
   670                 slave->type->vendor_name, slave->type->product_name,
   711                 slave->type->vendor_name, slave->type->product_name,
   671                 slave->type->description);
   712                 slave->type->description);
   672     }
   713     }
   673     else {
   714     else {
   674         EC_INFO("  *** This slave has no type information! ***\n");
   715         EC_INFO("| *** This slave has no type information! ***\n");
   675     }
   716     }
   676 
   717 
   677     EC_INFO("  Ring position: %i, Station address: 0x%04X\n",
   718     EC_INFO("| Ring position: %i, Station address: 0x%04X\n",
   678             slave->ring_position, slave->station_address);
   719             slave->ring_position, slave->station_address);
   679 
   720 
   680     EC_INFO("  Base information:\n");
   721     EC_INFO("| Base information:\n");
   681     EC_INFO("    Type %u, Revision %i, Build %i\n",
   722     EC_INFO("|   Type %u, Revision %i, Build %i\n",
   682             slave->base_type, slave->base_revision, slave->base_build);
   723             slave->base_type, slave->base_revision, slave->base_build);
   683     EC_INFO("    Supported FMMUs: %i, Sync managers: %i\n",
   724     EC_INFO("|   Supported FMMUs: %i, Sync managers: %i\n",
   684             slave->base_fmmu_count, slave->base_sync_count);
   725             slave->base_fmmu_count, slave->base_sync_count);
   685 
   726 
   686     EC_INFO("  EEPROM data:\n");
   727     EC_INFO("| EEPROM data:\n");
   687     EC_INFO("    Configured station alias: 0x%04X (%i)\n", slave->sii_alias,
   728     if (slave->sii_alias)
   688             slave->sii_alias);
   729         EC_INFO("|   Configured station alias: 0x%04X (%i)\n",
   689     EC_INFO("    Vendor-ID: 0x%08X, Product code: 0x%08X\n",
   730                 slave->sii_alias, slave->sii_alias);
       
   731     EC_INFO("|   Vendor-ID: 0x%08X, Product code: 0x%08X\n",
   690             slave->sii_vendor_id, slave->sii_product_code);
   732             slave->sii_vendor_id, slave->sii_product_code);
   691     EC_INFO("    Revision number: 0x%08X, Serial number: 0x%08X\n",
   733     EC_INFO("|   Revision number: 0x%08X, Serial number: 0x%08X\n",
   692             slave->sii_revision_number, slave->sii_serial_number);
   734             slave->sii_revision_number, slave->sii_serial_number);
   693     if (slave->eeprom_name)
   735     if (slave->eeprom_name)
   694         EC_INFO("    Name: %s\n", slave->eeprom_name);
   736         EC_INFO("|   Name: %s\n", slave->eeprom_name);
   695     if (slave->eeprom_group)
   737     if (slave->eeprom_group)
   696         EC_INFO("    Group: %s\n", slave->eeprom_group);
   738         EC_INFO("|   Group: %s\n", slave->eeprom_group);
   697     if (slave->eeprom_desc)
   739     if (slave->eeprom_desc)
   698         EC_INFO("    Description: %s\n", slave->eeprom_desc);
   740         EC_INFO("|   Description: %s\n", slave->eeprom_desc);
   699 }
   741     EC_INFO("x---------------------------------------------\n");
   700 
   742 }
   701 /*****************************************************************************/
   743 
   702 
   744 /*****************************************************************************/
   703 /**
   745 
   704    Gibt die ZŽählerstände der CRC-Fault-Counter aus und setzt diese zurück.
   746 /**
       
   747    Gibt die Zählerstände der CRC-Fault-Counter aus und setzt diese zurück.
   705 
   748 
   706    \return 0 bei Erfolg, sonst < 0
   749    \return 0 bei Erfolg, sonst < 0
   707 */
   750 */
   708 
   751 
   709 int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT-Slave */)
   752 int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT-Slave */)