master/slave.c
changeset 195 674071846ee3
parent 190 4e32bcc6b361
child 197 b9a6e2c22745
child 1618 5cff10efb927
equal deleted inserted replaced
194:c21e7c12dd50 195:674071846ee3
     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  *  EtherCAT slave methods.
     6  *
     6  *
     7  *  $Id$
     7  *  $Id$
     8  *
     8  *
     9  *****************************************************************************/
     9  *****************************************************************************/
    10 
    10 
    61 const ec_code_msg_t al_status_messages[];
    61 const ec_code_msg_t al_status_messages[];
    62 
    62 
    63 /*****************************************************************************/
    63 /*****************************************************************************/
    64 
    64 
    65 /**
    65 /**
    66    EtherCAT-Slave-Konstruktor.
    66    Slave constructor.
    67 */
    67    \return 0 in case of success, else < 0
    68 
    68 */
    69 int ec_slave_init(ec_slave_t *slave, /**< EtherCAT-Slave */
    69 
    70                   ec_master_t *master, /**< EtherCAT-Master */
    70 int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */
    71                   uint16_t ring_position, /**< Ringposition */
    71                   ec_master_t *master, /**< EtherCAT master */
    72                   uint16_t station_address /**< Programmierte Adresse */
    72                   uint16_t ring_position, /**< ring position */
       
    73                   uint16_t station_address /**< station address to configure */
    73                   )
    74                   )
    74 {
    75 {
    75     unsigned int i;
    76     unsigned int i;
    76 
    77 
    77     slave->ring_position = ring_position;
    78     slave->ring_position = ring_position;
    78     slave->station_address = station_address;
    79     slave->station_address = station_address;
    79 
    80 
    80     // Init kobject and add it to the hierarchy
    81     // init kobject and add it to the hierarchy
    81     memset(&slave->kobj, 0x00, sizeof(struct kobject));
    82     memset(&slave->kobj, 0x00, sizeof(struct kobject));
    82     kobject_init(&slave->kobj);
    83     kobject_init(&slave->kobj);
    83     slave->kobj.ktype = &ktype_ec_slave;
    84     slave->kobj.ktype = &ktype_ec_slave;
    84     slave->kobj.parent = &master->kobj;
    85     slave->kobj.parent = &master->kobj;
    85     if (kobject_set_name(&slave->kobj, "slave%03i", slave->ring_position)) {
    86     if (kobject_set_name(&slave->kobj, "slave%03i", slave->ring_position)) {
   131 }
   132 }
   132 
   133 
   133 /*****************************************************************************/
   134 /*****************************************************************************/
   134 
   135 
   135 /**
   136 /**
   136    EtherCAT-Slave-Destruktor.
   137    Slave destructor.
   137 */
   138 */
   138 
   139 
   139 void ec_slave_clear(struct kobject *kobj /**< KObject des Slaves */)
   140 void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
   140 {
   141 {
   141     ec_slave_t *slave;
   142     ec_slave_t *slave;
   142     ec_eeprom_string_t *string, *next_str;
   143     ec_eeprom_string_t *string, *next_str;
   143     ec_eeprom_sync_t *sync, *next_sync;
   144     ec_eeprom_sync_t *sync, *next_sync;
   144     ec_eeprom_pdo_t *pdo, *next_pdo;
   145     ec_eeprom_pdo_t *pdo, *next_pdo;
   146     ec_sdo_t *sdo, *next_sdo;
   147     ec_sdo_t *sdo, *next_sdo;
   147     ec_sdo_entry_t *en, *next_en;
   148     ec_sdo_entry_t *en, *next_en;
   148 
   149 
   149     slave = container_of(kobj, ec_slave_t, kobj);
   150     slave = container_of(kobj, ec_slave_t, kobj);
   150 
   151 
   151     // Alle Strings freigeben
   152     // free all string objects
   152     list_for_each_entry_safe(string, next_str, &slave->eeprom_strings, list) {
   153     list_for_each_entry_safe(string, next_str, &slave->eeprom_strings, list) {
   153         list_del(&string->list);
   154         list_del(&string->list);
   154         kfree(string);
   155         kfree(string);
   155     }
   156     }
   156 
   157 
   157     // Alle Sync-Manager freigeben
   158     // free all sync managers
   158     list_for_each_entry_safe(sync, next_sync, &slave->eeprom_syncs, list) {
   159     list_for_each_entry_safe(sync, next_sync, &slave->eeprom_syncs, list) {
   159         list_del(&sync->list);
   160         list_del(&sync->list);
   160         kfree(sync);
   161         kfree(sync);
   161     }
   162     }
   162 
   163 
   163     // Alle PDOs freigeben
   164     // free all PDOs
   164     list_for_each_entry_safe(pdo, next_pdo, &slave->eeprom_pdos, list) {
   165     list_for_each_entry_safe(pdo, next_pdo, &slave->eeprom_pdos, list) {
   165         list_del(&pdo->list);
   166         list_del(&pdo->list);
   166         if (pdo->name) kfree(pdo->name);
   167         if (pdo->name) kfree(pdo->name);
   167 
   168 
   168         // Alle Entries innerhalb eines PDOs freigeben
   169         // free all PDO entries
   169         list_for_each_entry_safe(entry, next_ent, &pdo->entries, list) {
   170         list_for_each_entry_safe(entry, next_ent, &pdo->entries, list) {
   170             list_del(&entry->list);
   171             list_del(&entry->list);
   171             if (entry->name) kfree(entry->name);
   172             if (entry->name) kfree(entry->name);
   172             kfree(entry);
   173             kfree(entry);
   173         }
   174         }
   177 
   178 
   178     if (slave->eeprom_name) kfree(slave->eeprom_name);
   179     if (slave->eeprom_name) kfree(slave->eeprom_name);
   179     if (slave->eeprom_group) kfree(slave->eeprom_group);
   180     if (slave->eeprom_group) kfree(slave->eeprom_group);
   180     if (slave->eeprom_desc) kfree(slave->eeprom_desc);
   181     if (slave->eeprom_desc) kfree(slave->eeprom_desc);
   181 
   182 
   182     // Alle SDOs freigeben
   183     // free all SDOs
   183     list_for_each_entry_safe(sdo, next_sdo, &slave->sdo_dictionary, list) {
   184     list_for_each_entry_safe(sdo, next_sdo, &slave->sdo_dictionary, list) {
   184         list_del(&sdo->list);
   185         list_del(&sdo->list);
   185         if (sdo->name) kfree(sdo->name);
   186         if (sdo->name) kfree(sdo->name);
   186 
   187 
   187         // Alle Entries freigeben
   188         // free all SDO entries
   188         list_for_each_entry_safe(en, next_en, &sdo->entries, list) {
   189         list_for_each_entry_safe(en, next_en, &sdo->entries, list) {
   189             list_del(&en->list);
   190             list_del(&en->list);
   190             kfree(en);
   191             kfree(en);
   191         }
   192         }
   192         kfree(sdo);
   193         kfree(sdo);
   196 }
   197 }
   197 
   198 
   198 /*****************************************************************************/
   199 /*****************************************************************************/
   199 
   200 
   200 /**
   201 /**
   201    Liest alle benötigten Informationen aus einem Slave.
   202    Reads all necessary information from a slave.
   202 
   203    \return 0 in case of success, else < 0
   203    \return 0 wenn alles ok, < 0 bei Fehler.
   204 */
   204 */
   205 
   205 
   206 int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT slave */)
   206 int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT-Slave */)
       
   207 {
   207 {
   208     ec_command_t *command;
   208     ec_command_t *command;
   209     unsigned int i;
   209     unsigned int i;
   210     uint16_t dl_status;
   210     uint16_t dl_status;
   211 
   211 
   212     command = &slave->master->simple_command;
   212     command = &slave->master->simple_command;
   213 
   213 
   214     // Read base data
   214     // read base data
   215     if (ec_command_nprd(command, slave->station_address, 0x0000, 6)) return -1;
   215     if (ec_command_nprd(command, slave->station_address, 0x0000, 6)) return -1;
   216     if (unlikely(ec_master_simple_io(slave->master, command))) {
   216     if (unlikely(ec_master_simple_io(slave->master, command))) {
   217         EC_ERR("Reading base data from slave %i failed!\n",
   217         EC_ERR("Reading base data from slave %i failed!\n",
   218                slave->ring_position);
   218                slave->ring_position);
   219         return -1;
   219         return -1;
   226     slave->base_sync_count = EC_READ_U8 (command->data + 5);
   226     slave->base_sync_count = EC_READ_U8 (command->data + 5);
   227 
   227 
   228     if (slave->base_fmmu_count > EC_MAX_FMMUS)
   228     if (slave->base_fmmu_count > EC_MAX_FMMUS)
   229         slave->base_fmmu_count = EC_MAX_FMMUS;
   229         slave->base_fmmu_count = EC_MAX_FMMUS;
   230 
   230 
   231     // Read DL status
   231     // read data link status
   232     if (ec_command_nprd(command, slave->station_address, 0x0110, 2)) return -1;
   232     if (ec_command_nprd(command, slave->station_address, 0x0110, 2)) return -1;
   233     if (unlikely(ec_master_simple_io(slave->master, command))) {
   233     if (unlikely(ec_master_simple_io(slave->master, command))) {
   234         EC_ERR("Reading DL status from slave %i failed!\n",
   234         EC_ERR("Reading DL status from slave %i failed!\n",
   235                slave->ring_position);
   235                slave->ring_position);
   236         return -1;
   236         return -1;
   241         slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
   241         slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
   242         slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
   242         slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
   243         slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
   243         slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
   244     }
   244     }
   245 
   245 
   246     // Read EEPROM data
   246     // read EEPROM data
   247     if (ec_slave_sii_read16(slave, 0x0004, &slave->sii_alias))
   247     if (ec_slave_sii_read16(slave, 0x0004, &slave->sii_alias))
   248         return -1;
   248         return -1;
   249     if (ec_slave_sii_read32(slave, 0x0008, &slave->sii_vendor_id))
   249     if (ec_slave_sii_read32(slave, 0x0008, &slave->sii_vendor_id))
   250         return -1;
   250         return -1;
   251     if (ec_slave_sii_read32(slave, 0x000A, &slave->sii_product_code))
   251     if (ec_slave_sii_read32(slave, 0x000A, &slave->sii_product_code))
   274 }
   274 }
   275 
   275 
   276 /*****************************************************************************/
   276 /*****************************************************************************/
   277 
   277 
   278 /**
   278 /**
   279    Liest 16 Bit aus dem Slave-Information-Interface
   279    Reads 16 bit from the slave information interface (SII).
   280    eines EtherCAT-Slaves.
   280    \return 0 in case of success, else < 0
   281 
       
   282    \return 0 bei Erfolg, sonst < 0
       
   283 */
   281 */
   284 
   282 
   285 int ec_slave_sii_read16(ec_slave_t *slave,
   283 int ec_slave_sii_read16(ec_slave_t *slave,
   286                         /**< EtherCAT-Slave */
   284                         /**< EtherCAT slave */
   287                         uint16_t offset,
   285                         uint16_t offset,
   288                         /**< Adresse des zu lesenden SII-Registers */
   286                         /**< address of the SII register to read */
   289                         uint16_t *target
   287                         uint16_t *target
   290                         /**< Speicher für Wert (16-Bit) */
   288                         /**< target memory */
   291                         )
   289                         )
   292 {
   290 {
   293     ec_command_t *command;
   291     ec_command_t *command;
   294     cycles_t start, end, timeout;
   292     cycles_t start, end, timeout;
   295 
   293 
   296     command = &slave->master->simple_command;
   294     command = &slave->master->simple_command;
   297 
   295 
   298     // Initiate read operation
   296     // initiate read operation
   299     if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1;
   297     if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1;
   300     EC_WRITE_U8 (command->data,     0x00); // read-only access
   298     EC_WRITE_U8 (command->data,     0x00); // read-only access
   301     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
   299     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
   302     EC_WRITE_U32(command->data + 2, offset);
   300     EC_WRITE_U32(command->data + 2, offset);
   303     if (unlikely(ec_master_simple_io(slave->master, command))) {
   301     if (unlikely(ec_master_simple_io(slave->master, command))) {
   304         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   302         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   305         return -1;
   303         return -1;
   306     }
   304     }
   307 
   305 
   308     // Der Slave legt die Informationen des Slave-Information-Interface
       
   309     // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange
       
   310     // den Status auslesen, bis das Bit weg ist.
       
   311 
       
   312     start = get_cycles();
   306     start = get_cycles();
   313     timeout = (cycles_t) 100 * cpu_khz; // 100ms
   307     timeout = (cycles_t) 100 * cpu_khz; // 100ms
   314 
   308 
   315     while (1)
   309     while (1)
   316     {
   310     {
   324             return -1;
   318             return -1;
   325         }
   319         }
   326 
   320 
   327         end = get_cycles();
   321         end = get_cycles();
   328 
   322 
       
   323         // check for "busy bit"
   329         if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) {
   324         if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) {
   330             *target = EC_READ_U16(command->data + 6);
   325             *target = EC_READ_U16(command->data + 6);
   331             return 0;
   326             return 0;
   332         }
   327         }
   333 
   328 
   339 }
   334 }
   340 
   335 
   341 /*****************************************************************************/
   336 /*****************************************************************************/
   342 
   337 
   343 /**
   338 /**
   344    Liest 32 Bit aus dem Slave-Information-Interface
   339    Reads 32 bit from the slave information interface (SII).
   345    eines EtherCAT-Slaves.
   340    \return 0 in case of success, else < 0
   346 
       
   347    \return 0 bei Erfolg, sonst < 0
       
   348 */
   341 */
   349 
   342 
   350 int ec_slave_sii_read32(ec_slave_t *slave,
   343 int ec_slave_sii_read32(ec_slave_t *slave,
   351                         /**< EtherCAT-Slave */
   344                         /**< EtherCAT slave */
   352                         uint16_t offset,
   345                         uint16_t offset,
   353                         /**< Adresse des zu lesenden SII-Registers */
   346                         /**< address of the SII register to read */
   354                         uint32_t *target
   347                         uint32_t *target
   355                         /**< Speicher für Wert (32-Bit) */
   348                         /**< target memory */
   356                         )
   349                         )
   357 {
   350 {
   358     ec_command_t *command;
   351     ec_command_t *command;
   359     cycles_t start, end, timeout;
   352     cycles_t start, end, timeout;
   360 
   353 
   361     command = &slave->master->simple_command;
   354     command = &slave->master->simple_command;
   362 
   355 
   363     // Initiate read operation
   356     // initiate read operation
   364     if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1;
   357     if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1;
   365     EC_WRITE_U8 (command->data,     0x00); // read-only access
   358     EC_WRITE_U8 (command->data,     0x00); // read-only access
   366     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
   359     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
   367     EC_WRITE_U32(command->data + 2, offset);
   360     EC_WRITE_U32(command->data + 2, offset);
   368     if (unlikely(ec_master_simple_io(slave->master, command))) {
   361     if (unlikely(ec_master_simple_io(slave->master, command))) {
   369         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   362         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   370         return -1;
   363         return -1;
   371     }
   364     }
   372 
   365 
   373     // Der Slave legt die Informationen des Slave-Information-Interface
       
   374     // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange
       
   375     // den Status auslesen, bis das Bit weg ist.
       
   376 
       
   377     start = get_cycles();
   366     start = get_cycles();
   378     timeout = (cycles_t) 100 * cpu_khz; // 100ms
   367     timeout = (cycles_t) 100 * cpu_khz; // 100ms
   379 
   368 
   380     while (1)
   369     while (1)
   381     {
   370     {
   389             return -1;
   378             return -1;
   390         }
   379         }
   391 
   380 
   392         end = get_cycles();
   381         end = get_cycles();
   393 
   382 
       
   383         // check "busy bit"
   394         if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) {
   384         if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) {
   395             *target = EC_READ_U32(command->data + 6);
   385             *target = EC_READ_U32(command->data + 6);
   396             return 0;
   386             return 0;
   397         }
   387         }
   398 
   388 
   404 }
   394 }
   405 
   395 
   406 /*****************************************************************************/
   396 /*****************************************************************************/
   407 
   397 
   408 /**
   398 /**
   409    Schreibt 16 Bit Daten in das Slave-Information-Interface
   399    Writes 16 bit of data to the slave information interface (SII).
   410    eines EtherCAT-Slaves.
   400    \return 0 in case of success, else < 0
   411 
       
   412    \return 0 bei Erfolg, sonst < 0
       
   413 */
   401 */
   414 
   402 
   415 int ec_slave_sii_write16(ec_slave_t *slave,
   403 int ec_slave_sii_write16(ec_slave_t *slave,
   416                          /**< EtherCAT-Slave */
   404                          /**< EtherCAT slave */
   417                          uint16_t offset,
   405                          uint16_t offset,
   418                          /**< Adresse des zu lesenden SII-Registers */
   406                          /**< address of the SII register to write */
   419                          uint16_t value
   407                          uint16_t value
   420                          /**< Zu schreibender Wert */
   408                          /**< new value */
   421                          )
   409                          )
   422 {
   410 {
   423     ec_command_t *command;
   411     ec_command_t *command;
   424     cycles_t start, end, timeout;
   412     cycles_t start, end, timeout;
   425 
   413 
   426     command = &slave->master->simple_command;
   414     command = &slave->master->simple_command;
   427 
   415 
   428     EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n",
   416     EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n",
   429             slave->ring_position, offset, value);
   417             slave->ring_position, offset, value);
   430 
   418 
   431     // Initiate write operation
   419     // initiate write operation
   432     if (ec_command_npwr(command, slave->station_address, 0x502, 8)) return -1;
   420     if (ec_command_npwr(command, slave->station_address, 0x502, 8)) return -1;
   433     EC_WRITE_U8 (command->data,     0x01); // enable write access
   421     EC_WRITE_U8 (command->data,     0x01); // enable write access
   434     EC_WRITE_U8 (command->data + 1, 0x02); // request write operation
   422     EC_WRITE_U8 (command->data + 1, 0x02); // request write operation
   435     EC_WRITE_U32(command->data + 2, offset);
   423     EC_WRITE_U32(command->data + 2, offset);
   436     EC_WRITE_U16(command->data + 6, value);
   424     EC_WRITE_U16(command->data + 6, value);
   437     if (unlikely(ec_master_simple_io(slave->master, command))) {
   425     if (unlikely(ec_master_simple_io(slave->master, command))) {
   438         EC_ERR("SII-write failed on slave %i!\n", slave->ring_position);
   426         EC_ERR("SII-write failed on slave %i!\n", slave->ring_position);
   439         return -1;
   427         return -1;
   440     }
   428     }
   441 
   429 
   442     // Der Slave legt die Informationen des Slave-Information-Interface
       
   443     // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange
       
   444     // den Status auslesen, bis das Bit weg ist.
       
   445 
       
   446     start = get_cycles();
   430     start = get_cycles();
   447     timeout = (cycles_t) 100 * cpu_khz; // 100ms
   431     timeout = (cycles_t) 100 * cpu_khz; // 100ms
   448 
   432 
   449     while (1)
   433     while (1)
   450     {
   434     {
   458             return -1;
   442             return -1;
   459         }
   443         }
   460 
   444 
   461         end = get_cycles();
   445         end = get_cycles();
   462 
   446 
       
   447         // check "busy bit"
   463         if (likely((EC_READ_U8(command->data + 1) & 0x82) == 0)) {
   448         if (likely((EC_READ_U8(command->data + 1) & 0x82) == 0)) {
   464             if (EC_READ_U8(command->data + 1) & 0x40) {
   449             if (EC_READ_U8(command->data + 1) & 0x40) {
   465                 EC_ERR("SII-write failed!\n");
   450                 EC_ERR("SII-write failed!\n");
   466                 return -1;
   451                 return -1;
   467             }
   452             }
   479 }
   464 }
   480 
   465 
   481 /*****************************************************************************/
   466 /*****************************************************************************/
   482 
   467 
   483 /**
   468 /**
   484    Holt Daten aus dem EEPROM.
   469    Fetches data from slave's EEPROM.
   485 
   470    \return 0 in case of success, else < 0
   486    \return 0, wenn alles ok, sonst < 0
   471 */
   487 */
   472 
   488 
   473 int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT slave */)
   489 int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT-Slave */)
       
   490 {
   474 {
   491     uint16_t word_offset, cat_type, word_count;
   475     uint16_t word_offset, cat_type, word_count;
   492     uint32_t value;
   476     uint32_t value;
   493     uint8_t *cat_data;
   477     uint8_t *cat_data;
   494     unsigned int i;
   478     unsigned int i;
   505         if (ec_slave_sii_read32(slave, word_offset, &value)) {
   489         if (ec_slave_sii_read32(slave, word_offset, &value)) {
   506             EC_ERR("Unable to read category header.\n");
   490             EC_ERR("Unable to read category header.\n");
   507             goto out_free;
   491             goto out_free;
   508         }
   492         }
   509 
   493 
   510         // Last category?
   494         // last category?
   511         if ((value & 0xFFFF) == 0xFFFF) break;
   495         if ((value & 0xFFFF) == 0xFFFF) break;
   512 
   496 
   513         cat_type = value & 0x7FFF;
   497         cat_type = value & 0x7FFF;
   514         word_count = (value >> 16) & 0xFFFF;
   498         word_count = (value >> 16) & 0xFFFF;
   515 
   499 
   516         // Fetch category data
   500         // fetch category data
   517         for (i = 0; i < word_count; i++) {
   501         for (i = 0; i < word_count; i++) {
   518             if (ec_slave_sii_read32(slave, word_offset + 2 + i, &value)) {
   502             if (ec_slave_sii_read32(slave, word_offset + 2 + i, &value)) {
   519                 EC_ERR("Unable to read category data word %i.\n", i);
   503                 EC_ERR("Unable to read category data word %i.\n", i);
   520                 goto out_free;
   504                 goto out_free;
   521             }
   505             }
   572 }
   556 }
   573 
   557 
   574 /*****************************************************************************/
   558 /*****************************************************************************/
   575 
   559 
   576 /**
   560 /**
   577    Holt die Daten einer String-Kategorie.
   561    Fetches data from a STRING category.
   578 
   562    \return 0 in case of success, else < 0
   579    \return 0 wenn alles ok, sonst < 0
   563 */
   580 */
   564 
   581 
   565 int ec_slave_fetch_strings(ec_slave_t *slave, /**< EtherCAT slave */
   582 int ec_slave_fetch_strings(ec_slave_t *slave, /**< EtherCAT-Slave */
   566                            const uint8_t *data /**< category data */
   583                            const uint8_t *data /**< Kategoriedaten */
       
   584                            )
   567                            )
   585 {
   568 {
   586     unsigned int string_count, i;
   569     unsigned int string_count, i;
   587     size_t size;
   570     size_t size;
   588     off_t offset;
   571     off_t offset;
   590 
   573 
   591     string_count = data[0];
   574     string_count = data[0];
   592     offset = 1;
   575     offset = 1;
   593     for (i = 0; i < string_count; i++) {
   576     for (i = 0; i < string_count; i++) {
   594         size = data[offset];
   577         size = data[offset];
   595         // Speicher für String-Objekt und Daten in einem Rutsch allozieren
   578         // allocate memory for string structure and data at a single blow
   596         if (!(string = (ec_eeprom_string_t *)
   579         if (!(string = (ec_eeprom_string_t *)
   597               kmalloc(sizeof(ec_eeprom_string_t) + size + 1, GFP_KERNEL))) {
   580               kmalloc(sizeof(ec_eeprom_string_t) + size + 1, GFP_KERNEL))) {
   598             EC_ERR("Failed to allocate string memory.\n");
   581             EC_ERR("Failed to allocate string memory.\n");
   599             return -1;
   582             return -1;
   600         }
   583         }
   611 }
   594 }
   612 
   595 
   613 /*****************************************************************************/
   596 /*****************************************************************************/
   614 
   597 
   615 /**
   598 /**
   616    Holt die Daten einer General-Kategorie.
   599    Fetches data from a GENERAL category.
   617 */
   600    \return 0 in case of success, else < 0
   618 
   601 */
   619 int ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT-Slave */
   602 
   620                            const uint8_t *data /**< Kategorie-Daten */
   603 int ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT slave */
       
   604                            const uint8_t *data /**< category data */
   621                            )
   605                            )
   622 {
   606 {
   623     unsigned int i;
   607     unsigned int i;
   624 
   608 
   625     if (ec_slave_locate_string(slave, data[0], &slave->eeprom_group))
   609     if (ec_slave_locate_string(slave, data[0], &slave->eeprom_group))
   628         return -1;
   612         return -1;
   629     if (ec_slave_locate_string(slave, data[3], &slave->eeprom_desc))
   613     if (ec_slave_locate_string(slave, data[3], &slave->eeprom_desc))
   630         return -1;
   614         return -1;
   631 
   615 
   632     for (i = 0; i < 4; i++)
   616     for (i = 0; i < 4; i++)
   633         slave->sii_physical_layer[i] = (data[4] & (0x03 << (i * 2))) >> (i * 2);
   617         slave->sii_physical_layer[i] =
       
   618             (data[4] & (0x03 << (i * 2))) >> (i * 2);
   634 
   619 
   635     return 0;
   620     return 0;
   636 }
   621 }
   637 
   622 
   638 /*****************************************************************************/
   623 /*****************************************************************************/
   639 
   624 
   640 /**
   625 /**
   641    Holt die Daten einer Sync-Manager-Kategorie.
   626    Fetches data from a SYNC MANAGER category.
   642 */
   627    \return 0 in case of success, else < 0
   643 
   628 */
   644 int ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT-Slave */
   629 
   645                         const uint8_t *data, /**< Kategorie-Daten */
   630 int ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT slave */
   646                         size_t word_count /**< Anzahl Words */
   631                         const uint8_t *data, /**< category data */
       
   632                         size_t word_count /**< number of words */
   647                         )
   633                         )
   648 {
   634 {
   649     unsigned int sync_count, i;
   635     unsigned int sync_count, i;
   650     ec_eeprom_sync_t *sync;
   636     ec_eeprom_sync_t *sync;
   651 
   637 
   652     sync_count = word_count / 4; // Sync-Manager-Strunktur ist 4 Worte lang
   638     sync_count = word_count / 4; // sync manager struct is 4 words long
   653 
   639 
   654     for (i = 0; i < sync_count; i++, data += 8) {
   640     for (i = 0; i < sync_count; i++, data += 8) {
   655         if (!(sync = (ec_eeprom_sync_t *)
   641         if (!(sync = (ec_eeprom_sync_t *)
   656               kmalloc(sizeof(ec_eeprom_sync_t), GFP_KERNEL))) {
   642               kmalloc(sizeof(ec_eeprom_sync_t), GFP_KERNEL))) {
   657             EC_ERR("Failed to allocate Sync-Manager memory.\n");
   643             EC_ERR("Failed to allocate Sync-Manager memory.\n");
   671 }
   657 }
   672 
   658 
   673 /*****************************************************************************/
   659 /*****************************************************************************/
   674 
   660 
   675 /**
   661 /**
   676    Holt die Daten einer TXPDO-Kategorie.
   662    Fetches data from a [RT]XPDO category.
   677 */
   663    \return 0 in case of success, else < 0
   678 
   664 */
   679 int ec_slave_fetch_pdo(ec_slave_t *slave, /**< EtherCAT-Slave */
   665 
   680                        const uint8_t *data, /**< Kategorie-Daten */
   666 int ec_slave_fetch_pdo(ec_slave_t *slave, /**< EtherCAT slave */
   681                        size_t word_count, /**< Anzahl Worte */
   667                        const uint8_t *data, /**< category data */
   682                        ec_pdo_type_t pdo_type /**< PDO-Typ */
   668                        size_t word_count, /**< number of words */
       
   669                        ec_pdo_type_t pdo_type /**< PDO type */
   683                        )
   670                        )
   684 {
   671 {
   685     ec_eeprom_pdo_t *pdo;
   672     ec_eeprom_pdo_t *pdo;
   686     ec_eeprom_pdo_entry_t *entry;
   673     ec_eeprom_pdo_entry_t *entry;
   687     unsigned int entry_count, i;
   674     unsigned int entry_count, i;
   731 }
   718 }
   732 
   719 
   733 /*****************************************************************************/
   720 /*****************************************************************************/
   734 
   721 
   735 /**
   722 /**
   736    Durchsucht die temporären Strings und dupliziert den gefundenen String.
   723    Searches the string list for an index and allocates a new string.
       
   724    \return 0 in case of success, else < 0
   737 */
   725 */
   738 
   726 
   739 int ec_slave_locate_string(ec_slave_t *slave, unsigned int index, char **ptr)
   727 int ec_slave_locate_string(ec_slave_t *slave, unsigned int index, char **ptr)
   740 {
   728 {
   741     ec_eeprom_string_t *string;
   729     ec_eeprom_string_t *string;
   776 }
   764 }
   777 
   765 
   778 /*****************************************************************************/
   766 /*****************************************************************************/
   779 
   767 
   780 /**
   768 /**
   781    Bestätigt einen Fehler beim Zustandswechsel.
   769    Acknowledges an error after a state transition.
   782 */
   770 */
   783 
   771 
   784 void ec_slave_state_ack(ec_slave_t *slave,
   772 void ec_slave_state_ack(ec_slave_t *slave, /**< EtherCAT slave */
   785                         /**< Slave, dessen Zustand geändert werden soll */
   773                         uint8_t state /**< previous state */
   786                         uint8_t state
       
   787                         /**< Alter Zustand */
       
   788                         )
   774                         )
   789 {
   775 {
   790     ec_command_t *command;
   776     ec_command_t *command;
   791     cycles_t start, end, timeout;
   777     cycles_t start, end, timeout;
   792 
   778 
   803     start = get_cycles();
   789     start = get_cycles();
   804     timeout = (cycles_t) 10 * cpu_khz; // 10ms
   790     timeout = (cycles_t) 10 * cpu_khz; // 10ms
   805 
   791 
   806     while (1)
   792     while (1)
   807     {
   793     {
   808         udelay(100); // Dem Slave etwas Zeit lassen...
   794         udelay(100); // wait a little bit...
   809 
   795 
   810         if (ec_command_nprd(command, slave->station_address, 0x0130, 2))
   796         if (ec_command_nprd(command, slave->station_address, 0x0130, 2))
   811             return;
   797             return;
   812         if (unlikely(ec_master_simple_io(slave->master, command))) {
   798         if (unlikely(ec_master_simple_io(slave->master, command))) {
   813             EC_WARN("Acknowledge checking failed on slave %i!\n",
   799             EC_WARN("Acknowledge checking failed on slave %i!\n",
   833 
   819 
   834 /*****************************************************************************/
   820 /*****************************************************************************/
   835 
   821 
   836 /**
   822 /**
   837    Reads the AL status code of a slave and displays it.
   823    Reads the AL status code of a slave and displays it.
   838 
       
   839    If the AL status code is not supported, or if no error occurred (both
   824    If the AL status code is not supported, or if no error occurred (both
   840    resulting in code=0), nothing is displayed.
   825    resulting in code=0), nothing is displayed.
   841 */
   826 */
   842 
   827 
   843 void ec_slave_read_al_status_code(ec_slave_t *slave /**< EtherCAT-Slave */)
   828 void ec_slave_read_al_status_code(ec_slave_t *slave /**< EtherCAT slave */)
   844 {
   829 {
   845     ec_command_t *command;
   830     ec_command_t *command;
   846     uint16_t code;
   831     uint16_t code;
   847     const ec_code_msg_t *al_msg;
   832     const ec_code_msg_t *al_msg;
   848 
   833 
   869 }
   854 }
   870 
   855 
   871 /*****************************************************************************/
   856 /*****************************************************************************/
   872 
   857 
   873 /**
   858 /**
   874    Ändert den Zustand eines Slaves.
   859    Does a state transition.
   875 
   860    \return 0 in case of success, else < 0
   876    \return 0 bei Erfolg, sonst < 0
   861 */
   877 */
   862 
   878 
   863 int ec_slave_state_change(ec_slave_t *slave, /**< EtherCAT slave */
   879 int ec_slave_state_change(ec_slave_t *slave,
   864                           uint8_t state /**< new state */
   880                           /**< Slave, dessen Zustand geändert werden soll */
       
   881                           uint8_t state
       
   882                           /**< Neuer Zustand */
       
   883                           )
   865                           )
   884 {
   866 {
   885     ec_command_t *command;
   867     ec_command_t *command;
   886     cycles_t start, end, timeout;
   868     cycles_t start, end, timeout;
   887 
   869 
   898     start = get_cycles();
   880     start = get_cycles();
   899     timeout = (cycles_t) 10 * cpu_khz; // 10ms
   881     timeout = (cycles_t) 10 * cpu_khz; // 10ms
   900 
   882 
   901     while (1)
   883     while (1)
   902     {
   884     {
   903         udelay(100); // Dem Slave etwas Zeit lassen...
   885         udelay(100); // wait a little bit
   904 
   886 
   905         if (ec_command_nprd(command, slave->station_address, 0x0130, 2))
   887         if (ec_command_nprd(command, slave->station_address, 0x0130, 2))
   906             return -1;
   888             return -1;
   907         if (unlikely(ec_master_simple_io(slave->master, command))) {
   889         if (unlikely(ec_master_simple_io(slave->master, command))) {
   908             EC_ERR("Failed to check state 0x%02X on slave %i!\n",
   890             EC_ERR("Failed to check state 0x%02X on slave %i!\n",
   910             return -1;
   892             return -1;
   911         }
   893         }
   912 
   894 
   913         end = get_cycles();
   895         end = get_cycles();
   914 
   896 
   915         if (unlikely(EC_READ_U8(command->data) & 0x10)) { // State change error
   897         if (unlikely(EC_READ_U8(command->data) & 0x10)) { // state change error
   916             EC_ERR("Failed to set state 0x%02X - Slave %i refused state change"
   898             EC_ERR("Failed to set state 0x%02X - Slave %i refused state change"
   917                    " (code 0x%02X)!\n", state, slave->ring_position,
   899                    " (code 0x%02X)!\n", state, slave->ring_position,
   918                    EC_READ_U8(command->data));
   900                    EC_READ_U8(command->data));
   919             state = EC_READ_U8(command->data) & 0x0F;
   901             state = EC_READ_U8(command->data) & 0x0F;
   920             ec_slave_read_al_status_code(slave);
   902             ec_slave_read_al_status_code(slave);
   921             ec_slave_state_ack(slave, state);
   903             ec_slave_state_ack(slave, state);
   922             return -1;
   904             return -1;
   923         }
   905         }
   924 
   906 
   925         if (likely(EC_READ_U8(command->data) == (state & 0x0F))) {
   907         if (likely(EC_READ_U8(command->data) == (state & 0x0F)))
   926             // State change successful
   908             return 0; // state change successful
   927             return 0;
       
   928         }
       
   929 
   909 
   930         if (unlikely((end - start) >= timeout)) {
   910         if (unlikely((end - start) >= timeout)) {
   931             EC_ERR("Failed to check state 0x%02X of slave %i - Timeout!\n",
   911             EC_ERR("Failed to check state 0x%02X of slave %i - Timeout!\n",
   932                    state, slave->ring_position);
   912                    state, slave->ring_position);
   933             return -1;
   913             return -1;
   936 }
   916 }
   937 
   917 
   938 /*****************************************************************************/
   918 /*****************************************************************************/
   939 
   919 
   940 /**
   920 /**
   941    Merkt eine FMMU-Konfiguration vor.
   921    Prepares an FMMU configuration.
   942 
   922    Configuration data for the FMMU is saved in the slave structure and is
   943    Die FMMU wird so konfiguriert, dass sie den gesamten Datenbereich des
   923    written to the slave in ecrt_master_activate().
   944    entsprechenden Sync-Managers abdeckt. Für jede Domäne werden separate
   924    The FMMU configuration is done in a way, that the complete data range
   945    FMMUs konfiguriert.
   925    of the corresponding sync manager is covered. Seperate FMMUs arce configured
   946 
   926    for each domain.
   947    Wenn die entsprechende FMMU bereits konfiguriert ist, wird dies als
   927    If the FMMU configuration is already prepared, the function returns with
   948    Erfolg zurückgegeben.
   928    success.
   949 
   929    \return 0 in case of success, else < 0
   950    \return 0 bei Erfolg, sonst < 0
   930 */
   951 */
   931 
   952 
   932 int ec_slave_prepare_fmmu(ec_slave_t *slave, /**< EtherCAT slave */
   953 int ec_slave_prepare_fmmu(ec_slave_t *slave, /**< EtherCAT-Slave */
   933                           const ec_domain_t *domain, /**< domain */
   954                           const ec_domain_t *domain, /**< Domäne */
   934                           const ec_sync_t *sync  /**< sync manager */
   955                           const ec_sync_t *sync  /**< Sync-Manager */
       
   956                           )
   935                           )
   957 {
   936 {
   958     unsigned int i;
   937     unsigned int i;
   959 
   938 
   960     // FMMU schon vorgemerkt?
   939     // FMMU configuration already prepared?
   961     for (i = 0; i < slave->fmmu_count; i++)
   940     for (i = 0; i < slave->fmmu_count; i++)
   962         if (slave->fmmus[i].domain == domain && slave->fmmus[i].sync == sync)
   941         if (slave->fmmus[i].domain == domain && slave->fmmus[i].sync == sync)
   963             return 0;
   942             return 0;
   964 
   943 
   965     // Neue FMMU reservieren...
   944     // reserve new FMMU...
   966 
   945 
   967     if (slave->fmmu_count >= slave->base_fmmu_count) {
   946     if (slave->fmmu_count >= slave->base_fmmu_count) {
   968         EC_ERR("Slave %i FMMU limit reached!\n", slave->ring_position);
   947         EC_ERR("Slave %i FMMU limit reached!\n", slave->ring_position);
   969         return -1;
   948         return -1;
   970     }
   949     }
   979 }
   958 }
   980 
   959 
   981 /*****************************************************************************/
   960 /*****************************************************************************/
   982 
   961 
   983 /**
   962 /**
   984    Gibt alle Informationen über einen EtherCAT-Slave aus.
   963    Outputs all information about a certain slave.
   985 
       
   986    Verbosity:
   964    Verbosity:
   987      0 - Nur Slavetypen und Adressen
   965    - 0: Only slave types and addresses
   988      1 - mit EEPROM-Informationen
   966    - 1: with EEPROM information
   989     >1 - mit SDO-Dictionaries
   967    - >1: with SDO dictionaries
   990 */
   968 */
   991 
   969 
   992 void ec_slave_print(const ec_slave_t *slave, /**< EtherCAT-Slave */
   970 void ec_slave_print(const ec_slave_t *slave, /**< EtherCAT slave */
   993                     unsigned int verbosity /**< Geschwätzigkeit */
   971                     unsigned int verbosity /**< verbosity level */
   994                     )
   972                     )
   995 {
   973 {
   996     ec_eeprom_sync_t *sync;
   974     ec_eeprom_sync_t *sync;
   997     ec_eeprom_pdo_t *pdo;
   975     ec_eeprom_pdo_t *pdo;
   998     ec_eeprom_pdo_entry_t *pdo_entry;
   976     ec_eeprom_pdo_entry_t *pdo_entry;
  1144 }
  1122 }
  1145 
  1123 
  1146 /*****************************************************************************/
  1124 /*****************************************************************************/
  1147 
  1125 
  1148 /**
  1126 /**
  1149    Gibt die Zählerstände der CRC-Fault-Counter aus und setzt diese zurück.
  1127    Outputs the values of the CRC faoult counters and resets them.
  1150 
  1128    \return 0 in case of success, else < 0
  1151    \return 0 bei Erfolg, sonst < 0
  1129 */
  1152 */
  1130 
  1153 
  1131 int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT slave */)
  1154 int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT-Slave */)
       
  1155 {
  1132 {
  1156     ec_command_t *command;
  1133     ec_command_t *command;
  1157 
  1134 
  1158     command = &slave->master->simple_command;
  1135     command = &slave->master->simple_command;
  1159 
  1136 
  1162         EC_WARN("Reading CRC fault counters failed on slave %i!\n",
  1139         EC_WARN("Reading CRC fault counters failed on slave %i!\n",
  1163                 slave->ring_position);
  1140                 slave->ring_position);
  1164         return -1;
  1141         return -1;
  1165     }
  1142     }
  1166 
  1143 
  1167     // No CRC faults.
  1144     if (!EC_READ_U32(command->data)) return 0; // no CRC faults
  1168     if (!EC_READ_U32(command->data)) return 0;
       
  1169 
  1145 
  1170     if (EC_READ_U8(command->data))
  1146     if (EC_READ_U8(command->data))
  1171         EC_WARN("%3i RX-error%s on slave %i, channel A.\n",
  1147         EC_WARN("%3i RX-error%s on slave %i, channel A.\n",
  1172                 EC_READ_U8(command->data),
  1148                 EC_READ_U8(command->data),
  1173                 EC_READ_U8(command->data) == 1 ? "" : "s",
  1149                 EC_READ_U8(command->data) == 1 ? "" : "s",
  1186         EC_WARN("%3i invalid frame%s on slave %i, channel B.\n",
  1162         EC_WARN("%3i invalid frame%s on slave %i, channel B.\n",
  1187                 EC_READ_U8(command->data + 3),
  1163                 EC_READ_U8(command->data + 3),
  1188                 EC_READ_U8(command->data + 3) == 1 ? "" : "s",
  1164                 EC_READ_U8(command->data + 3) == 1 ? "" : "s",
  1189                 slave->ring_position);
  1165                 slave->ring_position);
  1190 
  1166 
  1191     // Reset CRC counters
  1167     // reset CRC counters
  1192     if (ec_command_npwr(command, slave->station_address, 0x0300, 4)) return -1;
  1168     if (ec_command_npwr(command, slave->station_address, 0x0300, 4)) return -1;
  1193     EC_WRITE_U32(command->data, 0x00000000);
  1169     EC_WRITE_U32(command->data, 0x00000000);
  1194     if (unlikely(ec_master_simple_io(slave->master, command))) {
  1170     if (unlikely(ec_master_simple_io(slave->master, command))) {
  1195         EC_WARN("Resetting CRC fault counters failed on slave %i!\n",
  1171         EC_WARN("Resetting CRC fault counters failed on slave %i!\n",
  1196                 slave->ring_position);
  1172                 slave->ring_position);
  1201 }
  1177 }
  1202 
  1178 
  1203 /*****************************************************************************/
  1179 /*****************************************************************************/
  1204 
  1180 
  1205 /**
  1181 /**
  1206    Schreibt den "Configured station alias".
  1182    Writes the "configured station alias" to the slave's EEPROM.
  1207    \return 0, wenn alles ok, sonst < 0
  1183    \return 0 in case of success, else < 0
  1208 */
  1184 */
  1209 
  1185 
  1210 int ecrt_slave_write_alias(ec_slave_t *slave, /** EtherCAT-Slave */
  1186 int ecrt_slave_write_alias(ec_slave_t *slave, /** EtherCAT slave */
  1211                            uint16_t alias /** Neuer Alias */
  1187                            uint16_t alias /** new alias */
  1212                            )
  1188                            )
  1213 {
  1189 {
  1214     return ec_slave_sii_write16(slave, 0x0004, alias);
  1190     return ec_slave_sii_write16(slave, 0x0004, alias);
  1215 }
  1191 }
  1216 
  1192 
  1217 /*****************************************************************************/
  1193 /*****************************************************************************/
  1218 
  1194 
  1219 /**
  1195 /**
  1220    Formatiert Attribut-Daten für lesenden Zugriff im SysFS
  1196    Formats attribute data for SysFS read access.
  1221 
  1197    \return number of bytes to read
  1222    \return Anzahl Bytes im Speicher
  1198 */
  1223 */
  1199 
  1224 
  1200 ssize_t ec_show_slave_attribute(struct kobject *kobj, /**< slave's kobject */
  1225 ssize_t ec_show_slave_attribute(struct kobject *kobj, /**< KObject */
  1201                                 struct attribute *attr, /**< attribute */
  1226                                 struct attribute *attr, /**< Attribut */
  1202                                 char *buffer /**< memory to store data */
  1227                                 char *buffer /**< Speicher für die Daten */
       
  1228                                 )
  1203                                 )
  1229 {
  1204 {
  1230     ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj);
  1205     ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj);
  1231 
  1206 
  1232     if (attr == &attr_ring_position) {
  1207     if (attr == &attr_ring_position) {
  1285 /*****************************************************************************/
  1260 /*****************************************************************************/
  1286 
  1261 
  1287 EXPORT_SYMBOL(ecrt_slave_write_alias);
  1262 EXPORT_SYMBOL(ecrt_slave_write_alias);
  1288 
  1263 
  1289 /*****************************************************************************/
  1264 /*****************************************************************************/
  1290 
       
  1291 /* Emacs-Konfiguration
       
  1292 ;;; Local Variables: ***
       
  1293 ;;; c-basic-offset:4 ***
       
  1294 ;;; End: ***
       
  1295 */
       
  1296