master/slave.c
changeset 118 dc71ce4cc641
parent 114 e4b4b5a85e75
child 119 b2de89096010
equal deleted inserted replaced
117:b9976a5281e0 118:dc71ce4cc641
    13 
    13 
    14 #include "globals.h"
    14 #include "globals.h"
    15 #include "slave.h"
    15 #include "slave.h"
    16 #include "command.h"
    16 #include "command.h"
    17 #include "master.h"
    17 #include "master.h"
       
    18 
       
    19 /*****************************************************************************/
       
    20 
       
    21 int ec_slave_fetch_categories(ec_slave_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 *);
       
    24 void ec_slave_fetch_fmmu(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 *);
       
    27 void ec_slave_fetch_rxpdo(ec_slave_t *, const uint8_t *);
    18 
    28 
    19 /*****************************************************************************/
    29 /*****************************************************************************/
    20 
    30 
    21 /**
    31 /**
    22    EtherCAT-Slave-Konstruktor.
    32    EtherCAT-Slave-Konstruktor.
    40     slave->sii_revision_number = 0;
    50     slave->sii_revision_number = 0;
    41     slave->sii_serial_number = 0;
    51     slave->sii_serial_number = 0;
    42     slave->type = NULL;
    52     slave->type = NULL;
    43     slave->registered = 0;
    53     slave->registered = 0;
    44     slave->fmmu_count = 0;
    54     slave->fmmu_count = 0;
       
    55 
       
    56     INIT_LIST_HEAD(&slave->cat_strings);
    45 }
    57 }
    46 
    58 
    47 /*****************************************************************************/
    59 /*****************************************************************************/
    48 
    60 
    49 /**
    61 /**
    50    EtherCAT-Slave-Destruktor.
    62    EtherCAT-Slave-Destruktor.
    51 */
    63 */
    52 
    64 
    53 void ec_slave_clear(ec_slave_t *slave /**< EtherCAT-Slave */)
    65 void ec_slave_clear(ec_slave_t *slave /**< EtherCAT-Slave */)
    54 {
    66 {
    55     // Nichts freizugeben
    67     ec_slave_string_t *string, *next;
       
    68 
       
    69     // Alle Strings freigeben
       
    70     list_for_each_entry_safe(string, next, &slave->cat_strings, list) {
       
    71         list_del(&string->list);
       
    72         kfree(string);
       
    73     }
    56 }
    74 }
    57 
    75 
    58 /*****************************************************************************/
    76 /*****************************************************************************/
    59 
    77 
    60 /**
    78 /**
   109     }
   127     }
   110 
   128 
   111     if (unlikely(ec_slave_sii_read(slave, 0x000E,
   129     if (unlikely(ec_slave_sii_read(slave, 0x000E,
   112                                    &slave->sii_serial_number))) {
   130                                    &slave->sii_serial_number))) {
   113         EC_ERR("Could not read SII serial number!\n");
   131         EC_ERR("Could not read SII serial number!\n");
       
   132         return -1;
       
   133     }
       
   134 
       
   135     if (unlikely(ec_slave_fetch_categories(slave))) {
       
   136         EC_ERR("Could not fetch category data!\n");
   114         return -1;
   137         return -1;
   115     }
   138     }
   116 
   139 
   117     return 0;
   140     return 0;
   118 }
   141 }
   175             *target = EC_READ_U32(command.data + 6);
   198             *target = EC_READ_U32(command.data + 6);
   176             return 0;
   199             return 0;
   177         }
   200         }
   178 
   201 
   179         if (unlikely((end - start) >= timeout)) {
   202         if (unlikely((end - start) >= timeout)) {
   180             EC_ERR("SSI-read. Slave %i timed out!\n", slave->ring_position);
   203             EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position);
   181             return -1;
   204             return -1;
   182         }
   205         }
   183     }
   206     }
   184 }
   207 }
   185 
   208 
   250                 return 0;
   273                 return 0;
   251             }
   274             }
   252         }
   275         }
   253 
   276 
   254         if (unlikely((end - start) >= timeout)) {
   277         if (unlikely((end - start) >= timeout)) {
   255             EC_ERR("SSI-write: Slave %i timed out!\n", slave->ring_position);
   278             EC_ERR("SII-write: Slave %i timed out!\n", slave->ring_position);
   256             return -1;
   279             return -1;
   257         }
   280         }
   258     }
   281     }
       
   282 }
       
   283 
       
   284 /*****************************************************************************/
       
   285 
       
   286 /**
       
   287    Holt Daten aus dem EEPROM.
       
   288 
       
   289    \return 0, wenn alles ok, sonst < 0
       
   290 */
       
   291 
       
   292 int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT-Slave */)
       
   293 {
       
   294     uint16_t word_offset, header, word_count;
       
   295     uint32_t value;
       
   296     uint8_t *cat_data;
       
   297     unsigned int i;
       
   298 
       
   299     word_offset = 0x0040;
       
   300 
       
   301     //EC_DBG("Slave %i...\n", slave->ring_position);
       
   302 
       
   303     if (!(cat_data = (uint8_t *) kmalloc(0x10000, GFP_KERNEL))) {
       
   304         EC_ERR("Failed to allocate 64k bytes for category data.\n");
       
   305         return -1;
       
   306     }
       
   307 
       
   308     while (1) {
       
   309         // read category header
       
   310         if (ec_slave_sii_read(slave, word_offset, &value)) {
       
   311             EC_ERR("Unable to read category header and size.\n");
       
   312             kfree(cat_data);
       
   313             return -1;
       
   314         }
       
   315 
       
   316         // Last category?
       
   317         if ((value & 0xFFFF) == 0xFFFF) break;
       
   318 
       
   319         header = value & 0x7FFF;
       
   320         word_count = (value >> 16) & 0xFFFF;
       
   321 
       
   322         // Fetch category data
       
   323         for (i = 0; i < word_count; i++) {
       
   324             if (ec_slave_sii_read(slave, word_offset + 2 + i, &value)) {
       
   325                 EC_ERR("Unable to read category data word %i.\n", i);
       
   326                 kfree(cat_data);
       
   327                 return -1;
       
   328             }
       
   329 
       
   330             cat_data[i * 2]     = (value >> 0) & 0xFF;
       
   331             cat_data[i * 2 + 1] = (value >> 8) & 0xFF;
       
   332 
       
   333             // read second word "on the fly"
       
   334             if (i + 1 < word_count) {
       
   335                 i++;
       
   336                 cat_data[i * 2]     = (value >> 16) & 0xFF;
       
   337                 cat_data[i * 2 + 1] = (value >> 24) & 0xFF;
       
   338             }
       
   339         }
       
   340 
       
   341         switch (header)
       
   342         {
       
   343             case 0x000A:
       
   344                 if (ec_slave_fetch_strings(slave, cat_data)) {
       
   345                     kfree(cat_data);
       
   346                     return -1;
       
   347                 }
       
   348                 break;
       
   349             case 0x001E:
       
   350             case 0x0001:
       
   351                 ec_slave_fetch_general(slave, cat_data);
       
   352                 break;
       
   353             case 0x0028:
       
   354             case 0x0002:
       
   355                 ec_slave_fetch_fmmu(slave, cat_data);
       
   356                 break;
       
   357             case 0x0029:
       
   358             case 0x0003:
       
   359                 ec_slave_fetch_sync(slave, cat_data);
       
   360                 break;
       
   361             case 0x0032:
       
   362             case 0x0004:
       
   363                 ec_slave_fetch_txpdo(slave, cat_data);
       
   364                 break;
       
   365             case 0x0033:
       
   366             case 0x0005:
       
   367                 ec_slave_fetch_rxpdo(slave, cat_data);
       
   368                 break;
       
   369             default:
       
   370                 EC_WARN("Unknown category header 0x%04X in slave %i.\n",
       
   371                         header, slave->ring_position);
       
   372         }
       
   373 
       
   374         word_offset += 2 + word_count;
       
   375     }
       
   376 
       
   377     kfree(cat_data);
       
   378     return 0;
       
   379 }
       
   380 
       
   381 /*****************************************************************************/
       
   382 
       
   383 /**
       
   384    Holt die Daten einer String-Kategorie.
       
   385 
       
   386    \return 0 wenn alles ok, sonst < 0
       
   387 */
       
   388 
       
   389 int ec_slave_fetch_strings(ec_slave_t *slave, /**< EtherCAT-Slave */
       
   390                            const uint8_t *data /**< Kategoriedaten */
       
   391                            )
       
   392 {
       
   393     unsigned int string_count, i;
       
   394     size_t size;
       
   395     off_t offset;
       
   396     ec_slave_string_t *string;
       
   397 
       
   398     string_count = data[0];
       
   399     offset = 1;
       
   400     for (i = 0; i < string_count; i++) {
       
   401         size = data[offset];
       
   402         // Speicher für String-Objekt und Daten in einem Rutsch allozieren
       
   403         if (!(string = (ec_slave_string_t *) kmalloc(sizeof(ec_slave_string_t)
       
   404                                                      + size + 1,
       
   405                                                      GFP_KERNEL))) {
       
   406             EC_ERR("Failed to allocate string memory.\n");
       
   407             return -1;
       
   408         }
       
   409         string->data = (char *) (string + sizeof(ec_slave_string_t));
       
   410         memcpy(string->data, data + offset + 1, size);
       
   411         string->data[size] = 0x00;
       
   412         list_add_tail(&string->list, &slave->cat_strings);
       
   413         offset += 1 + size;
       
   414     }
       
   415 
       
   416     return 0;
       
   417 }
       
   418 
       
   419 /*****************************************************************************/
       
   420 
       
   421 /**
       
   422    Holt die Daten einer General-Kategorie.
       
   423 */
       
   424 
       
   425 void ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT-Slave */
       
   426                             const uint8_t *data /**< Kategorie-Daten */
       
   427                             )
       
   428 {
       
   429 }
       
   430 
       
   431 /*****************************************************************************/
       
   432 
       
   433 /**
       
   434    Holt die Daten einer FMMU-Kategorie.
       
   435 */
       
   436 
       
   437 void ec_slave_fetch_fmmu(ec_slave_t *slave, /**< EtherCAT-Slave */
       
   438                          const uint8_t *data /**< Kategorie-Daten */
       
   439                          )
       
   440 {
       
   441 }
       
   442 
       
   443 /*****************************************************************************/
       
   444 
       
   445 /**
       
   446    Holt die Daten einer Sync-Manager-Kategorie.
       
   447 */
       
   448 
       
   449 void ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT-Slave */
       
   450                          const uint8_t *data /**< Kategorie-Daten */
       
   451                          )
       
   452 {
       
   453 }
       
   454 
       
   455 /*****************************************************************************/
       
   456 
       
   457 /**
       
   458    Holt die Daten einer TXPDO-Kategorie.
       
   459 */
       
   460 
       
   461 void ec_slave_fetch_txpdo(ec_slave_t *slave, /**< EtherCAT-Slave */
       
   462                           const uint8_t *data /**< Kategorie-Daten */
       
   463                           )
       
   464 {
       
   465 }
       
   466 
       
   467 /*****************************************************************************/
       
   468 
       
   469 /**
       
   470    Holt die Daten einer RXPDO-Kategorie.
       
   471 */
       
   472 
       
   473 void ec_slave_fetch_rxpdo(ec_slave_t *slave, /**< EtherCAT-Slave */
       
   474                           const uint8_t *data /**< Kategorie-Daten */
       
   475                           )
       
   476 {
   259 }
   477 }
   260 
   478 
   261 /*****************************************************************************/
   479 /*****************************************************************************/
   262 
   480 
   263 /**
   481 /**
   435    Gibt alle Informationen über einen EtherCAT-Slave aus.
   653    Gibt alle Informationen über einen EtherCAT-Slave aus.
   436 */
   654 */
   437 
   655 
   438 void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */)
   656 void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */)
   439 {
   657 {
       
   658     ec_slave_string_t *string;
       
   659 
   440     EC_INFO("--- EtherCAT slave information ---\n");
   660     EC_INFO("--- EtherCAT slave information ---\n");
   441 
   661 
   442     if (slave->type) {
   662     if (slave->type) {
   443         EC_INFO("  Vendor \"%s\", Product \"%s\": %s\n",
   663         EC_INFO("  Vendor \"%s\", Product \"%s\": %s\n",
   444                 slave->type->vendor_name, slave->type->product_name,
   664                 slave->type->vendor_name, slave->type->product_name,
   462             slave->sii_alias);
   682             slave->sii_alias);
   463     EC_INFO("    Vendor-ID: 0x%08X, Product code: 0x%08X\n",
   683     EC_INFO("    Vendor-ID: 0x%08X, Product code: 0x%08X\n",
   464             slave->sii_vendor_id, slave->sii_product_code);
   684             slave->sii_vendor_id, slave->sii_product_code);
   465     EC_INFO("    Revision number: 0x%08X, Serial number: 0x%08X\n",
   685     EC_INFO("    Revision number: 0x%08X, Serial number: 0x%08X\n",
   466             slave->sii_revision_number, slave->sii_serial_number);
   686             slave->sii_revision_number, slave->sii_serial_number);
       
   687 
       
   688     EC_INFO("    EEPROM strings:\n");
       
   689     list_for_each_entry(string, &slave->cat_strings, list) {
       
   690         EC_INFO("      * \"%s\"\n", string->data);
       
   691     }
   467 }
   692 }
   468 
   693 
   469 /*****************************************************************************/
   694 /*****************************************************************************/
   470 
   695 
   471 /**
   696 /**