master/slave.c
changeset 126 bbc963b9fead
parent 124 2a5d42513099
child 127 e67c80a76de4
equal deleted inserted replaced
125:b01bd5b830d7 126:bbc963b9fead
    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 int 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 int ec_slave_fetch_sync(ec_slave_t *, const uint8_t *, size_t);
    25 void ec_slave_fetch_sync(ec_slave_t *, const uint8_t *);
    25 int ec_slave_fetch_pdo(ec_slave_t *, const uint8_t *, size_t, ec_pdo_type_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 *);
       
    28 int ec_slave_locate_string(ec_slave_t *, unsigned int, char **);
    26 int ec_slave_locate_string(ec_slave_t *, unsigned int, char **);
    29 
    27 
    30 /*****************************************************************************/
    28 /*****************************************************************************/
    31 
    29 
    32 /**
    30 /**
    51     slave->sii_revision_number = 0;
    49     slave->sii_revision_number = 0;
    52     slave->sii_serial_number = 0;
    50     slave->sii_serial_number = 0;
    53     slave->type = NULL;
    51     slave->type = NULL;
    54     slave->registered = 0;
    52     slave->registered = 0;
    55     slave->fmmu_count = 0;
    53     slave->fmmu_count = 0;
    56 
       
    57     INIT_LIST_HEAD(&slave->eeprom_strings);
       
    58     slave->eeprom_name = NULL;
    54     slave->eeprom_name = NULL;
    59     slave->eeprom_group = NULL;
    55     slave->eeprom_group = NULL;
    60     slave->eeprom_desc = NULL;
    56     slave->eeprom_desc = NULL;
       
    57     INIT_LIST_HEAD(&slave->eeprom_strings);
       
    58     INIT_LIST_HEAD(&slave->eeprom_syncs);
       
    59     INIT_LIST_HEAD(&slave->eeprom_pdos);
    61 }
    60 }
    62 
    61 
    63 /*****************************************************************************/
    62 /*****************************************************************************/
    64 
    63 
    65 /**
    64 /**
    66    EtherCAT-Slave-Destruktor.
    65    EtherCAT-Slave-Destruktor.
    67 */
    66 */
    68 
    67 
    69 void ec_slave_clear(ec_slave_t *slave /**< EtherCAT-Slave */)
    68 void ec_slave_clear(ec_slave_t *slave /**< EtherCAT-Slave */)
    70 {
    69 {
    71     ec_slave_string_t *string, *next;
    70     ec_eeprom_string_t *string, *next_str;
       
    71     ec_eeprom_sync_t *sync, *next_sync;
       
    72     ec_eeprom_pdo_t *pdo, *next_pdo;
       
    73     ec_eeprom_pdo_entry_t *entry, *next_ent;
    72 
    74 
    73     // Alle Strings freigeben
    75     // Alle Strings freigeben
    74     list_for_each_entry_safe(string, next, &slave->eeprom_strings, list) {
    76     list_for_each_entry_safe(string, next_str, &slave->eeprom_strings, list) {
    75         list_del(&string->list);
    77         list_del(&string->list);
    76         kfree(string);
    78         kfree(string);
       
    79     }
       
    80 
       
    81     // Alle Sync-Manager freigeben
       
    82     list_for_each_entry_safe(sync, next_sync, &slave->eeprom_syncs, list) {
       
    83         list_del(&sync->list);
       
    84         kfree(sync);
       
    85     }
       
    86 
       
    87     // Alle PDOs freigeben
       
    88     list_for_each_entry_safe(pdo, next_pdo, &slave->eeprom_pdos, list) {
       
    89         list_del(&pdo->list);
       
    90         if (pdo->name) kfree(pdo->name);
       
    91 
       
    92         // Alle Entries innerhalb eines PDOs freigeben
       
    93         list_for_each_entry_safe(entry, next_ent, &pdo->entries, list) {
       
    94             list_del(&entry->list);
       
    95             if (entry->name) kfree(entry->name);
       
    96             kfree(entry);
       
    97         }
       
    98 
       
    99         kfree(pdo);
    77     }
   100     }
    78 
   101 
    79     if (slave->eeprom_name) kfree(slave->eeprom_name);
   102     if (slave->eeprom_name) kfree(slave->eeprom_name);
    80     if (slave->eeprom_group) kfree(slave->eeprom_group);
   103     if (slave->eeprom_group) kfree(slave->eeprom_group);
    81     if (slave->eeprom_desc) kfree(slave->eeprom_desc);
   104     if (slave->eeprom_desc) kfree(slave->eeprom_desc);
   297    \return 0, wenn alles ok, sonst < 0
   320    \return 0, wenn alles ok, sonst < 0
   298 */
   321 */
   299 
   322 
   300 int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT-Slave */)
   323 int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT-Slave */)
   301 {
   324 {
   302     uint16_t word_offset, header, word_count;
   325     uint16_t word_offset, cat_type, word_count;
   303     uint32_t value;
   326     uint32_t value;
   304     uint8_t *cat_data;
   327     uint8_t *cat_data;
   305     unsigned int i;
   328     unsigned int i;
   306 
   329 
   307     word_offset = 0x0040;
   330     word_offset = 0x0040;
   312         EC_ERR("Failed to allocate 64k bytes for category data.\n");
   335         EC_ERR("Failed to allocate 64k bytes for category data.\n");
   313         return -1;
   336         return -1;
   314     }
   337     }
   315 
   338 
   316     while (1) {
   339     while (1) {
   317         // read category header
   340         // read category type
   318         if (ec_slave_sii_read(slave, word_offset, &value)) {
   341         if (ec_slave_sii_read(slave, word_offset, &value)) {
   319             EC_ERR("Unable to read category header and size.\n");
   342             EC_ERR("Unable to read category header.\n");
   320             goto out_free;
   343             goto out_free;
   321         }
   344         }
   322 
   345 
   323         // Last category?
   346         // Last category?
   324         if ((value & 0xFFFF) == 0xFFFF) break;
   347         if ((value & 0xFFFF) == 0xFFFF) break;
   325 
   348 
   326         header = value & 0x7FFF;
   349         cat_type = value & 0x7FFF;
   327         word_count = (value >> 16) & 0xFFFF;
   350         word_count = (value >> 16) & 0xFFFF;
   328 
   351 
   329         // Fetch category data
   352         // Fetch category data
   330         for (i = 0; i < word_count; i++) {
   353         for (i = 0; i < word_count; i++) {
   331             if (ec_slave_sii_read(slave, word_offset + 2 + i, &value)) {
   354             if (ec_slave_sii_read(slave, word_offset + 2 + i, &value)) {
   342                 cat_data[i * 2]     = (value >> 16) & 0xFF;
   365                 cat_data[i * 2]     = (value >> 16) & 0xFF;
   343                 cat_data[i * 2 + 1] = (value >> 24) & 0xFF;
   366                 cat_data[i * 2 + 1] = (value >> 24) & 0xFF;
   344             }
   367             }
   345         }
   368         }
   346 
   369 
   347         switch (header)
   370         switch (cat_type)
   348         {
   371         {
   349             case 0x000A:
   372             case 0x000A:
   350                 if (ec_slave_fetch_strings(slave, cat_data))
   373                 if (ec_slave_fetch_strings(slave, cat_data))
   351                     goto out_free;
   374                     goto out_free;
   352                 break;
   375                 break;
   353             case 0x001E:
   376             case 0x001E:
   354             case 0x0001:
       
   355                 if (ec_slave_fetch_general(slave, cat_data))
   377                 if (ec_slave_fetch_general(slave, cat_data))
   356                     goto out_free;
   378                     goto out_free;
   357                 break;
   379                 break;
   358             case 0x0028:
   380             case 0x0028:
   359             case 0x0002:
       
   360                 ec_slave_fetch_fmmu(slave, cat_data);
       
   361                 break;
   381                 break;
   362             case 0x0029:
   382             case 0x0029:
   363             case 0x0003:
   383                 if (ec_slave_fetch_sync(slave, cat_data, word_count))
   364                 ec_slave_fetch_sync(slave, cat_data);
   384                     goto out_free;
   365                 break;
   385                 break;
   366             case 0x0032:
   386             case 0x0032:
   367             case 0x0004:
   387                 if (ec_slave_fetch_pdo(slave, cat_data, word_count, EC_TX_PDO))
   368                 ec_slave_fetch_txpdo(slave, cat_data);
   388                     goto out_free;
   369                 break;
   389                 break;
   370             case 0x0033:
   390             case 0x0033:
   371             case 0x0005:
   391                 if (ec_slave_fetch_pdo(slave, cat_data, word_count, EC_RX_PDO))
   372                 ec_slave_fetch_rxpdo(slave, cat_data);
   392                     goto out_free;
   373                 break;
   393                 break;
   374             default:
   394             default:
   375                 EC_WARN("Unknown category header 0x%04X in slave %i.\n",
   395                 EC_WARN("Unknown category type 0x%04X in slave %i.\n",
   376                         header, slave->ring_position);
   396                         cat_type, slave->ring_position);
   377         }
   397         }
   378 
   398 
   379         word_offset += 2 + word_count;
   399         word_offset += 2 + word_count;
   380     }
   400     }
   381 
   401 
   400                            )
   420                            )
   401 {
   421 {
   402     unsigned int string_count, i;
   422     unsigned int string_count, i;
   403     size_t size;
   423     size_t size;
   404     off_t offset;
   424     off_t offset;
   405     ec_slave_string_t *string;
   425     ec_eeprom_string_t *string;
   406 
   426 
   407     string_count = data[0];
   427     string_count = data[0];
   408     offset = 1;
   428     offset = 1;
   409     for (i = 0; i < string_count; i++) {
   429     for (i = 0; i < string_count; i++) {
   410         size = data[offset];
   430         size = data[offset];
   411         // Speicher für String-Objekt und Daten in einem Rutsch allozieren
   431         // Speicher für String-Objekt und Daten in einem Rutsch allozieren
   412         if (!(string = (ec_slave_string_t *) kmalloc(sizeof(ec_slave_string_t)
   432         if (!(string = (ec_eeprom_string_t *)
   413                                                      + size + 1,
   433               kmalloc(sizeof(ec_eeprom_string_t) + size + 1, GFP_KERNEL))) {
   414                                                      GFP_KERNEL))) {
       
   415             EC_ERR("Failed to allocate string memory.\n");
   434             EC_ERR("Failed to allocate string memory.\n");
   416             return -1;
   435             return -1;
   417         }
   436         }
   418         string->size = size;
   437         string->size = size;
   419         string->data = (char *) string + sizeof(ec_slave_string_t);
   438         string->data = (char *) string + sizeof(ec_eeprom_string_t);
   420         memcpy(string->data, data + offset + 1, size);
   439         memcpy(string->data, data + offset + 1, size);
   421         string->data[size] = 0x00;
   440         string->data[size] = 0x00;
   422         list_add_tail(&string->list, &slave->eeprom_strings);
   441         list_add_tail(&string->list, &slave->eeprom_strings);
   423         offset += 1 + size;
   442         offset += 1 + size;
   424     }
   443     }
   447 }
   466 }
   448 
   467 
   449 /*****************************************************************************/
   468 /*****************************************************************************/
   450 
   469 
   451 /**
   470 /**
   452    Holt die Daten einer FMMU-Kategorie.
       
   453 */
       
   454 
       
   455 void ec_slave_fetch_fmmu(ec_slave_t *slave, /**< EtherCAT-Slave */
       
   456                          const uint8_t *data /**< Kategorie-Daten */
       
   457                          )
       
   458 {
       
   459 }
       
   460 
       
   461 /*****************************************************************************/
       
   462 
       
   463 /**
       
   464    Holt die Daten einer Sync-Manager-Kategorie.
   471    Holt die Daten einer Sync-Manager-Kategorie.
   465 */
   472 */
   466 
   473 
   467 void ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT-Slave */
   474 int ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT-Slave */
   468                          const uint8_t *data /**< Kategorie-Daten */
   475                         const uint8_t *data, /**< Kategorie-Daten */
   469                          )
   476                         size_t word_count /**< Anzahl Words */
   470 {
   477                         )
       
   478 {
       
   479     unsigned int sync_count, i;
       
   480     ec_eeprom_sync_t *sync;
       
   481 
       
   482     sync_count = word_count / 4; // Sync-Manager-Strunktur ist 4 Worte lang
       
   483 
       
   484     for (i = 0; i < sync_count; i++, data += 8) {
       
   485         if (!(sync = (ec_eeprom_sync_t *) kmalloc(sizeof(ec_eeprom_sync_t),
       
   486                                                   GFP_KERNEL))) {
       
   487             EC_ERR("Failed to allocate Sync-Manager memory.\n");
       
   488             return -1;
       
   489         }
       
   490 
       
   491         sync->index = i;
       
   492         sync->physical_start_address = *((uint16_t *) (data + 0));
       
   493         sync->length                 = *((uint16_t *) (data + 2));
       
   494         sync->control_register       = data[4];
       
   495         sync->enable                 = data[6];
       
   496 
       
   497         list_add_tail(&sync->list, &slave->eeprom_syncs);
       
   498     }
       
   499 
       
   500     return 0;
   471 }
   501 }
   472 
   502 
   473 /*****************************************************************************/
   503 /*****************************************************************************/
   474 
   504 
   475 /**
   505 /**
   476    Holt die Daten einer TXPDO-Kategorie.
   506    Holt die Daten einer TXPDO-Kategorie.
   477 */
   507 */
   478 
   508 
   479 void ec_slave_fetch_txpdo(ec_slave_t *slave, /**< EtherCAT-Slave */
   509 int ec_slave_fetch_pdo(ec_slave_t *slave, /**< EtherCAT-Slave */
   480                           const uint8_t *data /**< Kategorie-Daten */
   510                        const uint8_t *data, /**< Kategorie-Daten */
   481                           )
   511                        size_t word_count, /**< Anzahl Worte */
   482 {
   512                        ec_pdo_type_t pdo_type /**< PDO-Typ */
   483 }
   513                        )
   484 
   514 {
   485 /*****************************************************************************/
   515     ec_eeprom_pdo_t *pdo;
   486 
   516     ec_eeprom_pdo_entry_t *entry;
   487 /**
   517     unsigned int entry_count, i;
   488    Holt die Daten einer RXPDO-Kategorie.
   518 
   489 */
   519     while (word_count >= 4) {
   490 
   520         if (!(pdo = (ec_eeprom_pdo_t *) kmalloc(sizeof(ec_eeprom_pdo_t),
   491 void ec_slave_fetch_rxpdo(ec_slave_t *slave, /**< EtherCAT-Slave */
   521                                                 GFP_KERNEL))) {
   492                           const uint8_t *data /**< Kategorie-Daten */
   522             EC_ERR("Failed to allocate PDO memory.\n");
   493                           )
   523             return -1;
   494 {
   524         }
       
   525 
       
   526         INIT_LIST_HEAD(&pdo->entries);
       
   527         pdo->type = pdo_type;
       
   528 
       
   529         pdo->index = *((uint16_t *) data);
       
   530         entry_count = data[2];
       
   531         pdo->sync_manager = data[3];
       
   532         pdo->name = NULL;
       
   533         ec_slave_locate_string(slave, data[5], &pdo->name);
       
   534 
       
   535         list_add_tail(&pdo->list, &slave->eeprom_pdos);
       
   536 
       
   537         word_count -= 4;
       
   538         data += 8;
       
   539 
       
   540         for (i = 0; i < entry_count; i++) {
       
   541             if (!(entry = (ec_eeprom_pdo_entry_t *)
       
   542                   kmalloc(sizeof(ec_eeprom_pdo_entry_t), GFP_KERNEL))) {
       
   543                 EC_ERR("Failed to allocate PDO entry memory.\n");
       
   544                 return -1;
       
   545             }
       
   546 
       
   547             entry->index = *((uint16_t *) data);
       
   548             entry->subindex = data[2];
       
   549             entry->name = NULL;
       
   550             ec_slave_locate_string(slave, data[3], &entry->name);
       
   551             entry->bit_length = data[5];
       
   552 
       
   553             list_add_tail(&entry->list, &pdo->entries);
       
   554 
       
   555             word_count -= 4;
       
   556             data += 8;
       
   557         }
       
   558     }
       
   559 
       
   560     return 0;
   495 }
   561 }
   496 
   562 
   497 /*****************************************************************************/
   563 /*****************************************************************************/
   498 
   564 
   499 /**
   565 /**
   500    Durchsucht die temporären Strings und dupliziert den gefundenen String.
   566    Durchsucht die temporären Strings und dupliziert den gefundenen String.
   501 */
   567 */
   502 
   568 
   503 int ec_slave_locate_string(ec_slave_t *slave, unsigned int index, char **ptr)
   569 int ec_slave_locate_string(ec_slave_t *slave, unsigned int index, char **ptr)
   504 {
   570 {
   505     ec_slave_string_t *string;
   571     ec_eeprom_string_t *string;
   506 
   572     char *err_string;
       
   573 
       
   574     // Erst alten Speicher freigeben
   507     if (*ptr) {
   575     if (*ptr) {
   508         kfree(*ptr);
   576         kfree(*ptr);
   509         *ptr = NULL;
   577         *ptr = NULL;
   510     }
   578     }
   511 
   579 
       
   580     // Index 0 bedeutet "nicht belegt"
   512     if (!index) return 0;
   581     if (!index) return 0;
   513 
   582 
       
   583     // EEPROM-String mit Index finden und kopieren
   514     list_for_each_entry(string, &slave->eeprom_strings, list) {
   584     list_for_each_entry(string, &slave->eeprom_strings, list) {
   515         if (!(--index)) {
   585         if (--index) continue;
   516             if (!(*ptr = (char *) kmalloc(string->size + 1, GFP_KERNEL))) {
   586 
   517                 EC_ERR("Unable to allocate string memory.\n");
   587         if (!(*ptr = (char *) kmalloc(string->size + 1, GFP_KERNEL))) {
   518                 return -1;
   588             EC_ERR("Unable to allocate string memory.\n");
   519             }
   589             return -1;
   520             memcpy(*ptr, string->data, string->size + 1);
   590         }
   521             break;
   591         memcpy(*ptr, string->data, string->size + 1);
   522         }
   592         return 0;
   523     }
   593     }
   524 
   594 
       
   595     EC_WARN("String %i not found in slave %i.\n", index, slave->ring_position);
       
   596 
       
   597     err_string = "(string not found)";
       
   598 
       
   599     if (!(*ptr = (char *) kmalloc(strlen(err_string) + 1, GFP_KERNEL))) {
       
   600         EC_ERR("Unable to allocate string memory.\n");
       
   601         return -1;
       
   602     }
       
   603 
       
   604     memcpy(*ptr, err_string, strlen(err_string) + 1);
   525     return 0;
   605     return 0;
   526 }
   606 }
   527 
   607 
   528 /*****************************************************************************/
   608 /*****************************************************************************/
   529 
   609 
   702    Gibt alle Informationen über einen EtherCAT-Slave aus.
   782    Gibt alle Informationen über einen EtherCAT-Slave aus.
   703 */
   783 */
   704 
   784 
   705 void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */)
   785 void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */)
   706 {
   786 {
       
   787     ec_eeprom_sync_t *sync;
       
   788     ec_eeprom_pdo_t *pdo;
       
   789     ec_eeprom_pdo_entry_t *entry;
       
   790 
   707     EC_INFO("x-- EtherCAT slave information ---------------\n");
   791     EC_INFO("x-- EtherCAT slave information ---------------\n");
   708 
   792 
   709     if (slave->type) {
   793     if (slave->type) {
   710         EC_INFO("| Vendor \"%s\", Product \"%s\": %s\n",
   794         EC_INFO("| Vendor \"%s\", Product \"%s\": %s\n",
   711                 slave->type->vendor_name, slave->type->product_name,
   795                 slave->type->vendor_name, slave->type->product_name,
   723             slave->base_type, slave->base_revision, slave->base_build);
   807             slave->base_type, slave->base_revision, slave->base_build);
   724     EC_INFO("|   Supported FMMUs: %i, Sync managers: %i\n",
   808     EC_INFO("|   Supported FMMUs: %i, Sync managers: %i\n",
   725             slave->base_fmmu_count, slave->base_sync_count);
   809             slave->base_fmmu_count, slave->base_sync_count);
   726 
   810 
   727     EC_INFO("| EEPROM data:\n");
   811     EC_INFO("| EEPROM data:\n");
       
   812 
   728     if (slave->sii_alias)
   813     if (slave->sii_alias)
   729         EC_INFO("|   Configured station alias: 0x%04X (%i)\n",
   814         EC_INFO("|   Configured station alias: 0x%04X (%i)\n",
   730                 slave->sii_alias, slave->sii_alias);
   815                 slave->sii_alias, slave->sii_alias);
       
   816 
   731     EC_INFO("|   Vendor-ID: 0x%08X, Product code: 0x%08X\n",
   817     EC_INFO("|   Vendor-ID: 0x%08X, Product code: 0x%08X\n",
   732             slave->sii_vendor_id, slave->sii_product_code);
   818             slave->sii_vendor_id, slave->sii_product_code);
   733     EC_INFO("|   Revision number: 0x%08X, Serial number: 0x%08X\n",
   819     EC_INFO("|   Revision number: 0x%08X, Serial number: 0x%08X\n",
   734             slave->sii_revision_number, slave->sii_serial_number);
   820             slave->sii_revision_number, slave->sii_serial_number);
       
   821 
   735     if (slave->eeprom_name)
   822     if (slave->eeprom_name)
   736         EC_INFO("|   Name: %s\n", slave->eeprom_name);
   823         EC_INFO("|   Name: %s\n", slave->eeprom_name);
   737     if (slave->eeprom_group)
   824     if (slave->eeprom_group)
   738         EC_INFO("|   Group: %s\n", slave->eeprom_group);
   825         EC_INFO("|   Group: %s\n", slave->eeprom_group);
   739     if (slave->eeprom_desc)
   826     if (slave->eeprom_desc)
   740         EC_INFO("|   Description: %s\n", slave->eeprom_desc);
   827         EC_INFO("|   Description: %s\n", slave->eeprom_desc);
       
   828 
       
   829     if (!list_empty(&slave->eeprom_syncs)) {
       
   830         EC_INFO("|   Sync-Managers:\n");
       
   831         list_for_each_entry(sync, &slave->eeprom_syncs, list) {
       
   832             EC_INFO("|     %i: 0x%04X, length %i, control 0x%02X, %s\n",
       
   833                     sync->index, sync->physical_start_address, sync->length,
       
   834                     sync->control_register,
       
   835                     sync->enable ? "enable" : "disable");
       
   836         }
       
   837     }
       
   838 
       
   839     list_for_each_entry(pdo, &slave->eeprom_pdos, list) {
       
   840         EC_INFO("|   %s \"%s\" (0x%04X), -> Sync-Manager %i\n",
       
   841                 pdo->type == EC_RX_PDO ? "RXPDO" : "TXPDO",
       
   842                 pdo->name ? pdo->name : "???",
       
   843                 pdo->index, pdo->sync_manager);
       
   844 
       
   845         list_for_each_entry(entry, &pdo->entries, list) {
       
   846             EC_INFO("|     \"%s\" 0x%04X:%X, %i Bit\n",
       
   847                     entry->name ? entry->name : "???",
       
   848                     entry->index, entry->subindex, entry->bit_length);
       
   849         }
       
   850     }
       
   851 
   741     EC_INFO("x---------------------------------------------\n");
   852     EC_INFO("x---------------------------------------------\n");
   742 }
   853 }
   743 
   854 
   744 /*****************************************************************************/
   855 /*****************************************************************************/
   745 
   856