master/slave.c
changeset 325 7833cf70c4f2
parent 320 71d559ec66d7
child 329 d004349777fc
equal deleted inserted replaced
324:9aa51cbdbfae 325:7833cf70c4f2
    50 
    50 
    51 extern const ec_code_msg_t al_status_messages[];
    51 extern const ec_code_msg_t al_status_messages[];
    52 
    52 
    53 /*****************************************************************************/
    53 /*****************************************************************************/
    54 
    54 
    55 int ec_slave_fetch_categories(ec_slave_t *);
       
    56 ssize_t ec_show_slave_attribute(struct kobject *, struct attribute *, char *);
    55 ssize_t ec_show_slave_attribute(struct kobject *, struct attribute *, char *);
    57 ssize_t ec_store_slave_attribute(struct kobject *, struct attribute *,
    56 ssize_t ec_store_slave_attribute(struct kobject *, struct attribute *,
    58                                  const char *, size_t);
    57                                  const char *, size_t);
    59 
    58 
    60 /*****************************************************************************/
    59 /*****************************************************************************/
    61 
    60 
    62 /** \cond */
    61 /** \cond */
    63 
    62 
    64 EC_SYSFS_READ_ATTR(ring_position);
    63 EC_SYSFS_READ_ATTR(info);
    65 EC_SYSFS_READ_ATTR(advanced_position);
       
    66 EC_SYSFS_READ_ATTR(vendor_name); // deprecated
       
    67 EC_SYSFS_READ_ATTR(product_name); // deprecated
       
    68 EC_SYSFS_READ_ATTR(product_desc); // deprecated
       
    69 EC_SYSFS_READ_ATTR(name);
       
    70 EC_SYSFS_READ_ATTR(type); // deprecated
       
    71 EC_SYSFS_READ_WRITE_ATTR(state);
    64 EC_SYSFS_READ_WRITE_ATTR(state);
    72 EC_SYSFS_READ_WRITE_ATTR(eeprom);
    65 EC_SYSFS_READ_WRITE_ATTR(eeprom);
    73 
    66 
    74 static struct attribute *def_attrs[] = {
    67 static struct attribute *def_attrs[] = {
    75     &attr_ring_position,
    68     &attr_info,
    76     &attr_advanced_position,
       
    77     &attr_vendor_name,
       
    78     &attr_product_name,
       
    79     &attr_product_desc,
       
    80     &attr_name,
       
    81     &attr_type,
       
    82     &attr_state,
    69     &attr_state,
    83     &attr_eeprom,
    70     &attr_eeprom,
    84     NULL,
    71     NULL,
    85 };
    72 };
    86 
    73 
   125         kobject_put(&slave->kobj);
   112         kobject_put(&slave->kobj);
   126         return -1;
   113         return -1;
   127     }
   114     }
   128 
   115 
   129     slave->master = master;
   116     slave->master = master;
       
   117 
       
   118     slave->requested_state = EC_SLAVE_STATE_UNKNOWN;
       
   119     slave->current_state = EC_SLAVE_STATE_UNKNOWN;
       
   120     slave->error_flag = 0;
       
   121     slave->online = 1;
       
   122     slave->fmmu_count = 0;
       
   123     slave->registered = 0;
       
   124 
   130     slave->coupler_index = 0;
   125     slave->coupler_index = 0;
   131     slave->coupler_subindex = 0xFFFF;
   126     slave->coupler_subindex = 0xFFFF;
       
   127 
   132     slave->base_type = 0;
   128     slave->base_type = 0;
   133     slave->base_revision = 0;
   129     slave->base_revision = 0;
   134     slave->base_build = 0;
   130     slave->base_build = 0;
   135     slave->base_fmmu_count = 0;
   131     slave->base_fmmu_count = 0;
   136     slave->base_sync_count = 0;
   132     slave->base_sync_count = 0;
       
   133 
       
   134     slave->eeprom_data = NULL;
       
   135     slave->eeprom_size = 0;
       
   136     slave->new_eeprom_data = NULL;
       
   137     slave->new_eeprom_size = 0;
       
   138 
   137     slave->sii_alias = 0;
   139     slave->sii_alias = 0;
   138     slave->sii_vendor_id = 0;
   140     slave->sii_vendor_id = 0;
   139     slave->sii_product_code = 0;
   141     slave->sii_product_code = 0;
   140     slave->sii_revision_number = 0;
   142     slave->sii_revision_number = 0;
   141     slave->sii_serial_number = 0;
   143     slave->sii_serial_number = 0;
   142     slave->sii_rx_mailbox_offset = 0;
   144     slave->sii_rx_mailbox_offset = 0;
   143     slave->sii_rx_mailbox_size = 0;
   145     slave->sii_rx_mailbox_size = 0;
   144     slave->sii_tx_mailbox_offset = 0;
   146     slave->sii_tx_mailbox_offset = 0;
   145     slave->sii_tx_mailbox_size = 0;
   147     slave->sii_tx_mailbox_size = 0;
   146     slave->sii_mailbox_protocols = 0;
   148     slave->sii_mailbox_protocols = 0;
   147     slave->type = NULL;
   149     slave->sii_group = NULL;
   148     slave->registered = 0;
   150     slave->sii_image = NULL;
   149     slave->fmmu_count = 0;
   151     slave->sii_order = NULL;
   150     slave->eeprom_data = NULL;
   152     slave->sii_name = NULL;
   151     slave->eeprom_size = 0;
   153 
   152     slave->eeprom_group = NULL;
   154     INIT_LIST_HEAD(&slave->sii_strings);
   153     slave->eeprom_image = NULL;
   155     INIT_LIST_HEAD(&slave->sii_syncs);
   154     slave->eeprom_order = NULL;
   156     INIT_LIST_HEAD(&slave->sii_pdos);
   155     slave->eeprom_name = NULL;
       
   156     slave->requested_state = EC_SLAVE_STATE_UNKNOWN;
       
   157     slave->current_state = EC_SLAVE_STATE_UNKNOWN;
       
   158     slave->error_flag = 0;
       
   159     slave->online = 1;
       
   160     slave->new_eeprom_data = NULL;
       
   161     slave->new_eeprom_size = 0;
       
   162 
       
   163     INIT_LIST_HEAD(&slave->eeprom_strings);
       
   164     INIT_LIST_HEAD(&slave->eeprom_syncs);
       
   165     INIT_LIST_HEAD(&slave->eeprom_pdos);
       
   166     INIT_LIST_HEAD(&slave->sdo_dictionary);
   157     INIT_LIST_HEAD(&slave->sdo_dictionary);
   167     INIT_LIST_HEAD(&slave->varsize_fields);
   158     INIT_LIST_HEAD(&slave->varsize_fields);
   168 
   159 
   169     for (i = 0; i < 4; i++) {
   160     for (i = 0; i < 4; i++) {
   170         slave->dl_link[i] = 0;
   161         slave->dl_link[i] = 0;
   183 */
   174 */
   184 
   175 
   185 void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
   176 void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
   186 {
   177 {
   187     ec_slave_t *slave;
   178     ec_slave_t *slave;
   188     ec_eeprom_string_t *string, *next_str;
   179     ec_sii_string_t *string, *next_str;
   189     ec_eeprom_sync_t *sync, *next_sync;
   180     ec_sii_sync_t *sync, *next_sync;
   190     ec_eeprom_pdo_t *pdo, *next_pdo;
   181     ec_sii_pdo_t *pdo, *next_pdo;
   191     ec_eeprom_pdo_entry_t *entry, *next_ent;
   182     ec_sii_pdo_entry_t *entry, *next_ent;
   192     ec_sdo_t *sdo, *next_sdo;
   183     ec_sdo_t *sdo, *next_sdo;
   193     ec_sdo_entry_t *en, *next_en;
   184     ec_sdo_entry_t *en, *next_en;
   194     ec_varsize_t *var, *next_var;
   185     ec_varsize_t *var, *next_var;
   195 
   186 
   196     slave = container_of(kobj, ec_slave_t, kobj);
   187     slave = container_of(kobj, ec_slave_t, kobj);
   197 
   188 
   198     // free all string objects
   189     // free all string objects
   199     list_for_each_entry_safe(string, next_str, &slave->eeprom_strings, list) {
   190     list_for_each_entry_safe(string, next_str, &slave->sii_strings, list) {
   200         list_del(&string->list);
   191         list_del(&string->list);
   201         kfree(string);
   192         kfree(string);
   202     }
   193     }
   203 
   194 
   204     // free all sync managers
   195     // free all sync managers
   205     list_for_each_entry_safe(sync, next_sync, &slave->eeprom_syncs, list) {
   196     list_for_each_entry_safe(sync, next_sync, &slave->sii_syncs, list) {
   206         list_del(&sync->list);
   197         list_del(&sync->list);
   207         kfree(sync);
   198         kfree(sync);
   208     }
   199     }
   209 
   200 
   210     // free all PDOs
   201     // free all PDOs
   211     list_for_each_entry_safe(pdo, next_pdo, &slave->eeprom_pdos, list) {
   202     list_for_each_entry_safe(pdo, next_pdo, &slave->sii_pdos, list) {
   212         list_del(&pdo->list);
   203         list_del(&pdo->list);
   213         if (pdo->name) kfree(pdo->name);
   204         if (pdo->name) kfree(pdo->name);
   214 
   205 
   215         // free all PDO entries
   206         // free all PDO entries
   216         list_for_each_entry_safe(entry, next_ent, &pdo->entries, list) {
   207         list_for_each_entry_safe(entry, next_ent, &pdo->entries, list) {
   220         }
   211         }
   221 
   212 
   222         kfree(pdo);
   213         kfree(pdo);
   223     }
   214     }
   224 
   215 
   225     if (slave->eeprom_group) kfree(slave->eeprom_group);
   216     if (slave->sii_group) kfree(slave->sii_group);
   226     if (slave->eeprom_image) kfree(slave->eeprom_image);
   217     if (slave->sii_image) kfree(slave->sii_image);
   227     if (slave->eeprom_order) kfree(slave->eeprom_order);
   218     if (slave->sii_order) kfree(slave->sii_order);
   228     if (slave->eeprom_name) kfree(slave->eeprom_name);
   219     if (slave->sii_name) kfree(slave->sii_name);
   229 
   220 
   230     // free all SDOs
   221     // free all SDOs
   231     list_for_each_entry_safe(sdo, next_sdo, &slave->sdo_dictionary, list) {
   222     list_for_each_entry_safe(sdo, next_sdo, &slave->sdo_dictionary, list) {
   232         list_del(&sdo->list);
   223         list_del(&sdo->list);
   233         if (sdo->name) kfree(sdo->name);
   224         if (sdo->name) kfree(sdo->name);
   251 }
   242 }
   252 
   243 
   253 /*****************************************************************************/
   244 /*****************************************************************************/
   254 
   245 
   255 /**
   246 /**
   256    Reads all necessary information from a slave.
       
   257    \return 0 in case of success, else < 0
       
   258 */
       
   259 
       
   260 int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT slave */)
       
   261 {
       
   262     ec_datagram_t *datagram;
       
   263     unsigned int i;
       
   264     uint16_t dl_status;
       
   265 
       
   266     datagram = &slave->master->simple_datagram;
       
   267 
       
   268     // read base data
       
   269     if (ec_datagram_nprd(datagram, slave->station_address, 0x0000, 6))
       
   270         return -1;
       
   271     if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   272         EC_ERR("Reading base data from slave %i failed!\n",
       
   273                slave->ring_position);
       
   274         return -1;
       
   275     }
       
   276 
       
   277     slave->base_type =       EC_READ_U8 (datagram->data);
       
   278     slave->base_revision =   EC_READ_U8 (datagram->data + 1);
       
   279     slave->base_build =      EC_READ_U16(datagram->data + 2);
       
   280     slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4);
       
   281     slave->base_sync_count = EC_READ_U8 (datagram->data + 5);
       
   282 
       
   283     if (slave->base_fmmu_count > EC_MAX_FMMUS)
       
   284         slave->base_fmmu_count = EC_MAX_FMMUS;
       
   285 
       
   286     // read data link status
       
   287     if (ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2))
       
   288         return -1;
       
   289     if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   290         EC_ERR("Reading DL status from slave %i failed!\n",
       
   291                slave->ring_position);
       
   292         return -1;
       
   293     }
       
   294 
       
   295     dl_status = EC_READ_U16(datagram->data);
       
   296     for (i = 0; i < 4; i++) {
       
   297         slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
       
   298         slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
       
   299         slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
       
   300     }
       
   301 
       
   302     // read EEPROM data
       
   303     if (ec_slave_sii_read16(slave, 0x0004, &slave->sii_alias))
       
   304         return -1;
       
   305     if (ec_slave_sii_read32(slave, 0x0008, &slave->sii_vendor_id))
       
   306         return -1;
       
   307     if (ec_slave_sii_read32(slave, 0x000A, &slave->sii_product_code))
       
   308         return -1;
       
   309     if (ec_slave_sii_read32(slave, 0x000C, &slave->sii_revision_number))
       
   310         return -1;
       
   311     if (ec_slave_sii_read32(slave, 0x000E, &slave->sii_serial_number))
       
   312         return -1;
       
   313     if (ec_slave_sii_read16(slave, 0x0018, &slave->sii_rx_mailbox_offset))
       
   314         return -1;
       
   315     if (ec_slave_sii_read16(slave, 0x0019, &slave->sii_rx_mailbox_size))
       
   316         return -1;
       
   317     if (ec_slave_sii_read16(slave, 0x001A, &slave->sii_tx_mailbox_offset))
       
   318         return -1;
       
   319     if (ec_slave_sii_read16(slave, 0x001B, &slave->sii_tx_mailbox_size))
       
   320         return -1;
       
   321     if (ec_slave_sii_read16(slave, 0x001C, &slave->sii_mailbox_protocols))
       
   322         return -1;
       
   323 
       
   324     if (unlikely(ec_slave_fetch_categories(slave))) {
       
   325         EC_ERR("Failed to fetch category data!\n");
       
   326         return -1;
       
   327     }
       
   328 
       
   329     return 0;
       
   330 }
       
   331 
       
   332 /*****************************************************************************/
       
   333 
       
   334 /**
       
   335    Reads 16 bit from the slave information interface (SII).
       
   336    \return 0 in case of success, else < 0
       
   337 */
       
   338 
       
   339 int ec_slave_sii_read16(ec_slave_t *slave,
       
   340                         /**< EtherCAT slave */
       
   341                         uint16_t offset,
       
   342                         /**< address of the SII register to read */
       
   343                         uint16_t *target
       
   344                         /**< target memory */
       
   345                         )
       
   346 {
       
   347     ec_datagram_t *datagram;
       
   348     cycles_t start, end, timeout;
       
   349 
       
   350     datagram = &slave->master->simple_datagram;
       
   351 
       
   352     // initiate read operation
       
   353     if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 6))
       
   354         return -1;
       
   355     EC_WRITE_U8 (datagram->data,     0x00); // read-only access
       
   356     EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation
       
   357     EC_WRITE_U32(datagram->data + 2, offset);
       
   358     if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   359         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
       
   360         return -1;
       
   361     }
       
   362 
       
   363     start = get_cycles();
       
   364     timeout = (cycles_t) 100 * cpu_khz; // 100ms
       
   365 
       
   366     while (1)
       
   367     {
       
   368         udelay(10);
       
   369 
       
   370         if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10))
       
   371             return -1;
       
   372         if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   373             EC_ERR("Getting SII-read status failed on slave %i!\n",
       
   374                    slave->ring_position);
       
   375             return -1;
       
   376         }
       
   377 
       
   378         end = get_cycles();
       
   379 
       
   380         // check for "busy bit"
       
   381         if (likely((EC_READ_U8(datagram->data + 1) & 0x81) == 0)) {
       
   382             *target = EC_READ_U16(datagram->data + 6);
       
   383             return 0;
       
   384         }
       
   385 
       
   386         if (unlikely((end - start) >= timeout)) {
       
   387             EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position);
       
   388             return -1;
       
   389         }
       
   390     }
       
   391 }
       
   392 
       
   393 /*****************************************************************************/
       
   394 
       
   395 /**
       
   396    Reads 32 bit from the slave information interface (SII).
       
   397    \return 0 in case of success, else < 0
       
   398 */
       
   399 
       
   400 int ec_slave_sii_read32(ec_slave_t *slave,
       
   401                         /**< EtherCAT slave */
       
   402                         uint16_t offset,
       
   403                         /**< address of the SII register to read */
       
   404                         uint32_t *target
       
   405                         /**< target memory */
       
   406                         )
       
   407 {
       
   408     ec_datagram_t *datagram;
       
   409     cycles_t start, end, timeout;
       
   410 
       
   411     datagram = &slave->master->simple_datagram;
       
   412 
       
   413     // initiate read operation
       
   414     if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 6))
       
   415         return -1;
       
   416     EC_WRITE_U8 (datagram->data,     0x00); // read-only access
       
   417     EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation
       
   418     EC_WRITE_U32(datagram->data + 2, offset);
       
   419     if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   420         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
       
   421         return -1;
       
   422     }
       
   423 
       
   424     start = get_cycles();
       
   425     timeout = (cycles_t) 100 * cpu_khz; // 100ms
       
   426 
       
   427     while (1)
       
   428     {
       
   429         udelay(10);
       
   430 
       
   431         if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10))
       
   432             return -1;
       
   433         if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   434             EC_ERR("Getting SII-read status failed on slave %i!\n",
       
   435                    slave->ring_position);
       
   436             return -1;
       
   437         }
       
   438 
       
   439         end = get_cycles();
       
   440 
       
   441         // check "busy bit"
       
   442         if (likely((EC_READ_U8(datagram->data + 1) & 0x81) == 0)) {
       
   443             *target = EC_READ_U32(datagram->data + 6);
       
   444             return 0;
       
   445         }
       
   446 
       
   447         if (unlikely((end - start) >= timeout)) {
       
   448             EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position);
       
   449             return -1;
       
   450         }
       
   451     }
       
   452 }
       
   453 
       
   454 /*****************************************************************************/
       
   455 
       
   456 /**
       
   457    Writes 16 bit of data to the slave information interface (SII).
       
   458    \return 0 in case of success, else < 0
       
   459 */
       
   460 
       
   461 int ec_slave_sii_write16(ec_slave_t *slave,
       
   462                          /**< EtherCAT slave */
       
   463                          uint16_t offset,
       
   464                          /**< address of the SII register to write */
       
   465                          uint16_t value
       
   466                          /**< new value */
       
   467                          )
       
   468 {
       
   469     ec_datagram_t *datagram;
       
   470     cycles_t start, end, timeout;
       
   471 
       
   472     datagram = &slave->master->simple_datagram;
       
   473 
       
   474     EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n",
       
   475             slave->ring_position, offset, value);
       
   476 
       
   477     // initiate write operation
       
   478     if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 8))
       
   479         return -1;
       
   480     EC_WRITE_U8 (datagram->data,     0x01); // enable write access
       
   481     EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation
       
   482     EC_WRITE_U32(datagram->data + 2, offset);
       
   483     EC_WRITE_U16(datagram->data + 6, value);
       
   484     if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   485         EC_ERR("SII-write failed on slave %i!\n", slave->ring_position);
       
   486         return -1;
       
   487     }
       
   488 
       
   489     start = get_cycles();
       
   490     timeout = (cycles_t) 100 * cpu_khz; // 100ms
       
   491 
       
   492     while (1)
       
   493     {
       
   494         udelay(10);
       
   495 
       
   496         if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 2))
       
   497             return -1;
       
   498         if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   499             EC_ERR("Getting SII-write status failed on slave %i!\n",
       
   500                    slave->ring_position);
       
   501             return -1;
       
   502         }
       
   503 
       
   504         end = get_cycles();
       
   505 
       
   506         // check "busy bit"
       
   507         if (likely((EC_READ_U8(datagram->data + 1) & 0x82) == 0)) {
       
   508             if (EC_READ_U8(datagram->data + 1) & 0x40) {
       
   509                 EC_ERR("SII-write failed!\n");
       
   510                 return -1;
       
   511             }
       
   512             else {
       
   513                 EC_INFO("SII-write succeeded!\n");
       
   514                 return 0;
       
   515             }
       
   516         }
       
   517 
       
   518         if (unlikely((end - start) >= timeout)) {
       
   519             EC_ERR("SII-write: Slave %i timed out!\n", slave->ring_position);
       
   520             return -1;
       
   521         }
       
   522     }
       
   523 }
       
   524 
       
   525 /*****************************************************************************/
       
   526 
       
   527 /**
       
   528    Fetches data from slave's EEPROM.
       
   529    \return 0 in case of success, else < 0
       
   530    \todo memory allocation
       
   531 */
       
   532 
       
   533 int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT slave */)
       
   534 {
       
   535     uint16_t word_offset, cat_type, word_count;
       
   536     uint32_t value;
       
   537     uint8_t *cat_data;
       
   538     unsigned int i;
       
   539 
       
   540     word_offset = 0x0040;
       
   541 
       
   542     if (!(cat_data = (uint8_t *) kmalloc(0x10000, GFP_ATOMIC))) {
       
   543         EC_ERR("Failed to allocate 64k bytes for category data.\n");
       
   544         return -1;
       
   545     }
       
   546 
       
   547     while (1) {
       
   548         // read category type
       
   549         if (ec_slave_sii_read32(slave, word_offset, &value)) {
       
   550             EC_ERR("Unable to read category header.\n");
       
   551             goto out_free;
       
   552         }
       
   553 
       
   554         // last category?
       
   555         if ((value & 0xFFFF) == 0xFFFF) break;
       
   556 
       
   557         cat_type = value & 0x7FFF;
       
   558         word_count = (value >> 16) & 0xFFFF;
       
   559 
       
   560         // fetch category data
       
   561         for (i = 0; i < word_count; i++) {
       
   562             if (ec_slave_sii_read32(slave, word_offset + 2 + i, &value)) {
       
   563                 EC_ERR("Unable to read category data word %i.\n", i);
       
   564                 goto out_free;
       
   565             }
       
   566 
       
   567             cat_data[i * 2]     = (value >> 0) & 0xFF;
       
   568             cat_data[i * 2 + 1] = (value >> 8) & 0xFF;
       
   569 
       
   570             // read second word "on the fly"
       
   571             if (i + 1 < word_count) {
       
   572                 i++;
       
   573                 cat_data[i * 2]     = (value >> 16) & 0xFF;
       
   574                 cat_data[i * 2 + 1] = (value >> 24) & 0xFF;
       
   575             }
       
   576         }
       
   577 
       
   578         switch (cat_type)
       
   579         {
       
   580             case 0x000A:
       
   581                 if (ec_slave_fetch_strings(slave, cat_data))
       
   582                     goto out_free;
       
   583                 break;
       
   584             case 0x001E:
       
   585                 if (ec_slave_fetch_general(slave, cat_data))
       
   586                     goto out_free;
       
   587                 break;
       
   588             case 0x0028:
       
   589                 break;
       
   590             case 0x0029:
       
   591                 if (ec_slave_fetch_sync(slave, cat_data, word_count))
       
   592                     goto out_free;
       
   593                 break;
       
   594             case 0x0032:
       
   595                 if (ec_slave_fetch_pdo(slave, cat_data, word_count, EC_TX_PDO))
       
   596                     goto out_free;
       
   597                 break;
       
   598             case 0x0033:
       
   599                 if (ec_slave_fetch_pdo(slave, cat_data, word_count, EC_RX_PDO))
       
   600                     goto out_free;
       
   601                 break;
       
   602             default:
       
   603                 EC_WARN("Unknown category type 0x%04X in slave %i.\n",
       
   604                         cat_type, slave->ring_position);
       
   605         }
       
   606 
       
   607         word_offset += 2 + word_count;
       
   608     }
       
   609 
       
   610     kfree(cat_data);
       
   611     return 0;
       
   612 
       
   613  out_free:
       
   614     kfree(cat_data);
       
   615     return -1;
       
   616 }
       
   617 
       
   618 /*****************************************************************************/
       
   619 
       
   620 /**
       
   621    Fetches data from a STRING category.
   247    Fetches data from a STRING category.
   622    \return 0 in case of success, else < 0
   248    \return 0 in case of success, else < 0
   623 */
   249 */
   624 
   250 
   625 int ec_slave_fetch_strings(ec_slave_t *slave, /**< EtherCAT slave */
   251 int ec_slave_fetch_strings(ec_slave_t *slave, /**< EtherCAT slave */
   627                            )
   253                            )
   628 {
   254 {
   629     unsigned int string_count, i;
   255     unsigned int string_count, i;
   630     size_t size;
   256     size_t size;
   631     off_t offset;
   257     off_t offset;
   632     ec_eeprom_string_t *string;
   258     ec_sii_string_t *string;
   633 
   259 
   634     string_count = data[0];
   260     string_count = data[0];
   635     offset = 1;
   261     offset = 1;
   636     for (i = 0; i < string_count; i++) {
   262     for (i = 0; i < string_count; i++) {
   637         size = data[offset];
   263         size = data[offset];
   638         // allocate memory for string structure and data at a single blow
   264         // allocate memory for string structure and data at a single blow
   639         if (!(string = (ec_eeprom_string_t *)
   265         if (!(string = (ec_sii_string_t *)
   640               kmalloc(sizeof(ec_eeprom_string_t) + size + 1, GFP_ATOMIC))) {
   266               kmalloc(sizeof(ec_sii_string_t) + size + 1, GFP_ATOMIC))) {
   641             EC_ERR("Failed to allocate string memory.\n");
   267             EC_ERR("Failed to allocate string memory.\n");
   642             return -1;
   268             return -1;
   643         }
   269         }
   644         string->size = size;
   270         string->size = size;
   645         // string memory appended to string structure
   271         // string memory appended to string structure
   646         string->data = (char *) string + sizeof(ec_eeprom_string_t);
   272         string->data = (char *) string + sizeof(ec_sii_string_t);
   647         memcpy(string->data, data + offset + 1, size);
   273         memcpy(string->data, data + offset + 1, size);
   648         string->data[size] = 0x00;
   274         string->data[size] = 0x00;
   649         list_add_tail(&string->list, &slave->eeprom_strings);
   275         list_add_tail(&string->list, &slave->sii_strings);
   650         offset += 1 + size;
   276         offset += 1 + size;
   651     }
   277     }
   652 
   278 
   653     return 0;
   279     return 0;
   654 }
   280 }
   658 /**
   284 /**
   659    Fetches data from a GENERAL category.
   285    Fetches data from a GENERAL category.
   660    \return 0 in case of success, else < 0
   286    \return 0 in case of success, else < 0
   661 */
   287 */
   662 
   288 
   663 int ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT slave */
   289 void ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT slave */
   664                            const uint8_t *data /**< category data */
   290                             const uint8_t *data /**< category data */
   665                            )
   291                             )
   666 {
   292 {
   667     unsigned int i;
   293     unsigned int i;
   668 
   294 
   669     if (ec_slave_locate_string(slave, data[0], &slave->eeprom_group))
   295     ec_slave_locate_string(slave, data[0], &slave->sii_group);
   670         return -1;
   296     ec_slave_locate_string(slave, data[1], &slave->sii_image);
   671     if (ec_slave_locate_string(slave, data[1], &slave->eeprom_image))
   297     ec_slave_locate_string(slave, data[2], &slave->sii_order);
   672         return -1;
   298     ec_slave_locate_string(slave, data[3], &slave->sii_name);
   673     if (ec_slave_locate_string(slave, data[2], &slave->eeprom_order))
       
   674         return -1;
       
   675     if (ec_slave_locate_string(slave, data[3], &slave->eeprom_name))
       
   676         return -1;
       
   677 
   299 
   678     for (i = 0; i < 4; i++)
   300     for (i = 0; i < 4; i++)
   679         slave->sii_physical_layer[i] =
   301         slave->sii_physical_layer[i] =
   680             (data[4] & (0x03 << (i * 2))) >> (i * 2);
   302             (data[4] & (0x03 << (i * 2))) >> (i * 2);
   681 
       
   682     return 0;
       
   683 }
   303 }
   684 
   304 
   685 /*****************************************************************************/
   305 /*****************************************************************************/
   686 
   306 
   687 /**
   307 /**
   693                         const uint8_t *data, /**< category data */
   313                         const uint8_t *data, /**< category data */
   694                         size_t word_count /**< number of words */
   314                         size_t word_count /**< number of words */
   695                         )
   315                         )
   696 {
   316 {
   697     unsigned int sync_count, i;
   317     unsigned int sync_count, i;
   698     ec_eeprom_sync_t *sync;
   318     ec_sii_sync_t *sync;
   699 
   319 
   700     sync_count = word_count / 4; // sync manager struct is 4 words long
   320     sync_count = word_count / 4; // sync manager struct is 4 words long
   701 
   321 
   702     for (i = 0; i < sync_count; i++, data += 8) {
   322     for (i = 0; i < sync_count; i++, data += 8) {
   703         if (!(sync = (ec_eeprom_sync_t *)
   323         if (!(sync = (ec_sii_sync_t *)
   704               kmalloc(sizeof(ec_eeprom_sync_t), GFP_ATOMIC))) {
   324               kmalloc(sizeof(ec_sii_sync_t), GFP_ATOMIC))) {
   705             EC_ERR("Failed to allocate Sync-Manager memory.\n");
   325             EC_ERR("Failed to allocate Sync-Manager memory.\n");
   706             return -1;
   326             return -1;
   707         }
   327         }
   708 
   328 
   709         sync->index = i;
   329         sync->index = i;
   710         sync->physical_start_address = *((uint16_t *) (data + 0));
   330         sync->physical_start_address = EC_READ_U16(data);
   711         sync->length                 = *((uint16_t *) (data + 2));
   331         sync->length                 = EC_READ_U16(data + 2);
   712         sync->control_register       = data[4];
   332         sync->control_register       = EC_READ_U8 (data + 4);
   713         sync->enable                 = data[6];
   333         sync->enable                 = EC_READ_U8 (data + 6);
   714 
   334 
   715         list_add_tail(&sync->list, &slave->eeprom_syncs);
   335         list_add_tail(&sync->list, &slave->sii_syncs);
   716     }
   336     }
   717 
   337 
   718     return 0;
   338     return 0;
   719 }
   339 }
   720 
   340 
   726 */
   346 */
   727 
   347 
   728 int ec_slave_fetch_pdo(ec_slave_t *slave, /**< EtherCAT slave */
   348 int ec_slave_fetch_pdo(ec_slave_t *slave, /**< EtherCAT slave */
   729                        const uint8_t *data, /**< category data */
   349                        const uint8_t *data, /**< category data */
   730                        size_t word_count, /**< number of words */
   350                        size_t word_count, /**< number of words */
   731                        ec_pdo_type_t pdo_type /**< PDO type */
   351                        ec_sii_pdo_type_t pdo_type /**< PDO type */
   732                        )
   352                        )
   733 {
   353 {
   734     ec_eeprom_pdo_t *pdo;
   354     ec_sii_pdo_t *pdo;
   735     ec_eeprom_pdo_entry_t *entry;
   355     ec_sii_pdo_entry_t *entry;
   736     unsigned int entry_count, i;
   356     unsigned int entry_count, i;
   737 
   357 
   738     while (word_count >= 4) {
   358     while (word_count >= 4) {
   739         if (!(pdo = (ec_eeprom_pdo_t *)
   359         if (!(pdo = (ec_sii_pdo_t *)
   740               kmalloc(sizeof(ec_eeprom_pdo_t), GFP_ATOMIC))) {
   360               kmalloc(sizeof(ec_sii_pdo_t), GFP_ATOMIC))) {
   741             EC_ERR("Failed to allocate PDO memory.\n");
   361             EC_ERR("Failed to allocate PDO memory.\n");
   742             return -1;
   362             return -1;
   743         }
   363         }
   744 
   364 
   745         INIT_LIST_HEAD(&pdo->entries);
   365         INIT_LIST_HEAD(&pdo->entries);
   746         pdo->type = pdo_type;
   366         pdo->type = pdo_type;
   747 
   367 
   748         pdo->index = *((uint16_t *) data);
   368         pdo->index = EC_READ_U16(data);
   749         entry_count = data[2];
   369         entry_count = EC_READ_U8(data + 2);
   750         pdo->sync_manager = data[3];
   370         pdo->sync_index = EC_READ_U8(data + 3);
   751         pdo->name = NULL;
   371         pdo->name = NULL;
   752         ec_slave_locate_string(slave, data[5], &pdo->name);
   372         ec_slave_locate_string(slave, EC_READ_U8(data + 5), &pdo->name);
   753 
   373 
   754         list_add_tail(&pdo->list, &slave->eeprom_pdos);
   374         list_add_tail(&pdo->list, &slave->sii_pdos);
   755 
   375 
   756         word_count -= 4;
   376         word_count -= 4;
   757         data += 8;
   377         data += 8;
   758 
   378 
   759         for (i = 0; i < entry_count; i++) {
   379         for (i = 0; i < entry_count; i++) {
   760             if (!(entry = (ec_eeprom_pdo_entry_t *)
   380             if (!(entry = (ec_sii_pdo_entry_t *)
   761                   kmalloc(sizeof(ec_eeprom_pdo_entry_t), GFP_ATOMIC))) {
   381                   kmalloc(sizeof(ec_sii_pdo_entry_t), GFP_ATOMIC))) {
   762                 EC_ERR("Failed to allocate PDO entry memory.\n");
   382                 EC_ERR("Failed to allocate PDO entry memory.\n");
   763                 return -1;
   383                 return -1;
   764             }
   384             }
   765 
   385 
   766             entry->index = *((uint16_t *) data);
   386             entry->index = EC_READ_U16(data);
   767             entry->subindex = data[2];
   387             entry->subindex = EC_READ_U8(data + 2);
   768             entry->name = NULL;
   388             entry->name = NULL;
   769             ec_slave_locate_string(slave, data[3], &entry->name);
   389             ec_slave_locate_string(slave, EC_READ_U8(data + 3), &entry->name);
   770             entry->bit_length = data[5];
   390             entry->bit_length = EC_READ_U8(data + 5);
   771 
   391 
   772             list_add_tail(&entry->list, &pdo->entries);
   392             list_add_tail(&entry->list, &pdo->entries);
   773 
   393 
   774             word_count -= 4;
   394             word_count -= 4;
   775             data += 8;
   395             data += 8;
   790 int ec_slave_locate_string(ec_slave_t *slave, /**< EtherCAT slave */
   410 int ec_slave_locate_string(ec_slave_t *slave, /**< EtherCAT slave */
   791                            unsigned int index, /**< string index */
   411                            unsigned int index, /**< string index */
   792                            char **ptr /**< Address of the string pointer */
   412                            char **ptr /**< Address of the string pointer */
   793                            )
   413                            )
   794 {
   414 {
   795     ec_eeprom_string_t *string;
   415     ec_sii_string_t *string;
   796     char *err_string;
   416     char *err_string;
   797 
   417 
   798     // Erst alten Speicher freigeben
   418     // Erst alten Speicher freigeben
   799     if (*ptr) {
   419     if (*ptr) {
   800         kfree(*ptr);
   420         kfree(*ptr);
   803 
   423 
   804     // Index 0 bedeutet "nicht belegt"
   424     // Index 0 bedeutet "nicht belegt"
   805     if (!index) return 0;
   425     if (!index) return 0;
   806 
   426 
   807     // EEPROM-String mit Index finden und kopieren
   427     // EEPROM-String mit Index finden und kopieren
   808     list_for_each_entry(string, &slave->eeprom_strings, list) {
   428     list_for_each_entry(string, &slave->sii_strings, list) {
   809         if (--index) continue;
   429         if (--index) continue;
   810 
   430 
   811         if (!(*ptr = (char *) kmalloc(string->size + 1, GFP_ATOMIC))) {
   431         if (!(*ptr = (char *) kmalloc(string->size + 1, GFP_ATOMIC))) {
   812             EC_ERR("Unable to allocate string memory.\n");
   432             EC_ERR("Unable to allocate string memory.\n");
   813             return -1;
   433             return -1;
   819     EC_WARN("String %i not found in slave %i.\n", index, slave->ring_position);
   439     EC_WARN("String %i not found in slave %i.\n", index, slave->ring_position);
   820 
   440 
   821     err_string = "(string not found)";
   441     err_string = "(string not found)";
   822 
   442 
   823     if (!(*ptr = (char *) kmalloc(strlen(err_string) + 1, GFP_ATOMIC))) {
   443     if (!(*ptr = (char *) kmalloc(strlen(err_string) + 1, GFP_ATOMIC))) {
   824         EC_ERR("Unable to allocate string memory.\n");
   444         EC_WARN("Unable to allocate string memory.\n");
   825         return -1;
   445         return -1;
   826     }
   446     }
   827 
   447 
   828     memcpy(*ptr, err_string, strlen(err_string) + 1);
   448     memcpy(*ptr, err_string, strlen(err_string) + 1);
   829     return 0;
   449     return 0;
   830 }
       
   831 
       
   832 /*****************************************************************************/
       
   833 
       
   834 /**
       
   835    Acknowledges an error after a state transition.
       
   836 */
       
   837 
       
   838 void ec_slave_state_ack(ec_slave_t *slave, /**< EtherCAT slave */
       
   839                         uint8_t state /**< previous state */
       
   840                         )
       
   841 {
       
   842     ec_datagram_t *datagram;
       
   843     cycles_t start, end, timeout;
       
   844 
       
   845     datagram = &slave->master->simple_datagram;
       
   846 
       
   847     if (ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2)) return;
       
   848     EC_WRITE_U16(datagram->data, state | EC_ACK);
       
   849     if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   850         EC_WARN("Acknowledge sending failed on slave %i!\n",
       
   851                 slave->ring_position);
       
   852         return;
       
   853     }
       
   854 
       
   855     start = get_cycles();
       
   856     timeout = (cycles_t) 100 * cpu_khz; // 100ms
       
   857 
       
   858     while (1) {
       
   859         udelay(100); // wait a little bit...
       
   860 
       
   861         if (ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2))
       
   862             return;
       
   863         if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   864             slave->current_state = EC_SLAVE_STATE_UNKNOWN;
       
   865             EC_WARN("Acknowledge checking failed on slave %i!\n",
       
   866                     slave->ring_position);
       
   867             return;
       
   868         }
       
   869 
       
   870         end = get_cycles();
       
   871 
       
   872         if (EC_READ_U8(datagram->data) == state) {
       
   873             slave->current_state = state;
       
   874             EC_INFO("Acknowleged state 0x%02X on slave %i.\n", state,
       
   875                     slave->ring_position);
       
   876             return;
       
   877         }
       
   878 
       
   879         if (end - start >= timeout) {
       
   880             slave->current_state = EC_SLAVE_STATE_UNKNOWN;
       
   881             EC_WARN("Failed to acknowledge state 0x%02X on slave %i"
       
   882                     " - Timeout!\n", state, slave->ring_position);
       
   883             return;
       
   884         }
       
   885     }
       
   886 }
       
   887 
       
   888 /*****************************************************************************/
       
   889 
       
   890 /**
       
   891    Reads the AL status code of a slave and displays it.
       
   892    If the AL status code is not supported, or if no error occurred (both
       
   893    resulting in code = 0), nothing is displayed.
       
   894 */
       
   895 
       
   896 void ec_slave_read_al_status_code(ec_slave_t *slave /**< EtherCAT slave */)
       
   897 {
       
   898     ec_datagram_t *datagram;
       
   899     uint16_t code;
       
   900     const ec_code_msg_t *al_msg;
       
   901 
       
   902     datagram = &slave->master->simple_datagram;
       
   903 
       
   904     if (ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2)) return;
       
   905     if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   906         EC_WARN("Failed to read AL status code on slave %i!\n",
       
   907                 slave->ring_position);
       
   908         return;
       
   909     }
       
   910 
       
   911     if (!(code = EC_READ_U16(datagram->data))) return;
       
   912 
       
   913     for (al_msg = al_status_messages; al_msg->code; al_msg++) {
       
   914         if (al_msg->code == code) {
       
   915             EC_ERR("AL status message 0x%04X: \"%s\".\n",
       
   916                    al_msg->code, al_msg->message);
       
   917             return;
       
   918         }
       
   919     }
       
   920 
       
   921     EC_ERR("Unknown AL status code 0x%04X.\n", code);
       
   922 }
       
   923 
       
   924 /*****************************************************************************/
       
   925 
       
   926 /**
       
   927    Does a state transition.
       
   928    \return 0 in case of success, else < 0
       
   929 */
       
   930 
       
   931 int ec_slave_state_change(ec_slave_t *slave, /**< EtherCAT slave */
       
   932                           uint8_t state /**< new state */
       
   933                           )
       
   934 {
       
   935     ec_datagram_t *datagram;
       
   936     cycles_t start, end, timeout;
       
   937 
       
   938     datagram = &slave->master->simple_datagram;
       
   939 
       
   940     slave->requested_state = state;
       
   941 
       
   942     if (ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2))
       
   943         return -1;
       
   944     EC_WRITE_U16(datagram->data, state);
       
   945     if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   946         EC_ERR("Failed to set state 0x%02X on slave %i!\n",
       
   947                state, slave->ring_position);
       
   948         return -1;
       
   949     }
       
   950 
       
   951     start = get_cycles();
       
   952     timeout = (cycles_t) 10 * cpu_khz; // 10ms
       
   953 
       
   954     while (1)
       
   955     {
       
   956         udelay(100); // wait a little bit
       
   957 
       
   958         if (ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2))
       
   959             return -1;
       
   960         if (unlikely(ec_master_simple_io(slave->master, datagram))) {
       
   961             slave->current_state = EC_SLAVE_STATE_UNKNOWN;
       
   962             EC_ERR("Failed to check state 0x%02X on slave %i!\n",
       
   963                    state, slave->ring_position);
       
   964             return -1;
       
   965         }
       
   966 
       
   967         end = get_cycles();
       
   968 
       
   969         if (unlikely(EC_READ_U8(datagram->data) & 0x10)) {
       
   970             // state change error
       
   971             EC_ERR("Failed to set state 0x%02X - Slave %i refused state change"
       
   972                    " (code 0x%02X)!\n", state, slave->ring_position,
       
   973                    EC_READ_U8(datagram->data));
       
   974             slave->current_state = EC_READ_U8(datagram->data);
       
   975             state = slave->current_state & 0x0F;
       
   976             ec_slave_read_al_status_code(slave);
       
   977             ec_slave_state_ack(slave, state);
       
   978             return -1;
       
   979         }
       
   980 
       
   981         if (likely(EC_READ_U8(datagram->data) == (state & 0x0F))) {
       
   982             slave->current_state = state;
       
   983             return 0; // state change successful
       
   984         }
       
   985 
       
   986         if (unlikely((end - start) >= timeout)) {
       
   987             slave->current_state = EC_SLAVE_STATE_UNKNOWN;
       
   988             EC_ERR("Failed to check state 0x%02X of slave %i - Timeout!\n",
       
   989                    state, slave->ring_position);
       
   990             return -1;
       
   991         }
       
   992     }
       
   993 }
   450 }
   994 
   451 
   995 /*****************************************************************************/
   452 /*****************************************************************************/
   996 
   453 
   997 /**
   454 /**
   998    Prepares an FMMU configuration.
   455    Prepares an FMMU configuration.
   999    Configuration data for the FMMU is saved in the slave structure and is
   456    Configuration data for the FMMU is saved in the slave structure and is
  1000    written to the slave in ecrt_master_activate().
   457    written to the slave in ecrt_master_activate().
  1001    The FMMU configuration is done in a way, that the complete data range
   458    The FMMU configuration is done in a way, that the complete data range
  1002    of the corresponding sync manager is covered. Seperate FMMUs arce configured
   459    of the corresponding sync manager is covered. Seperate FMMUs are configured
  1003    for each domain.
   460    for each domain.
  1004    If the FMMU configuration is already prepared, the function returns with
   461    If the FMMU configuration is already prepared, the function returns with
  1005    success.
   462    success.
  1006    \return 0 in case of success, else < 0
   463    \return 0 in case of success, else < 0
  1007 */
   464 */
  1008 
   465 
  1009 int ec_slave_prepare_fmmu(ec_slave_t *slave, /**< EtherCAT slave */
   466 int ec_slave_prepare_fmmu(ec_slave_t *slave, /**< EtherCAT slave */
  1010                           const ec_domain_t *domain, /**< domain */
   467                           const ec_domain_t *domain, /**< domain */
  1011                           const ec_sync_t *sync  /**< sync manager */
   468                           const ec_sii_sync_t *sync  /**< sync manager */
  1012                           )
   469                           )
  1013 {
   470 {
  1014     unsigned int i;
   471     unsigned int i;
  1015 
   472 
  1016     // FMMU configuration already prepared?
   473     // FMMU configuration already prepared?
  1036 
   493 
  1037 /*****************************************************************************/
   494 /*****************************************************************************/
  1038 
   495 
  1039 /**
   496 /**
  1040    Outputs all information about a certain slave.
   497    Outputs all information about a certain slave.
  1041    Verbosity:
   498 */
  1042    - 0: Only slave types and addresses
   499 
  1043    - 1: with EEPROM information
   500 size_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
  1044    - >1: with SDO dictionaries
   501                      char *buffer /**< Output buffer */
  1045 */
   502                      )
  1046 
   503 {
  1047 void ec_slave_print(const ec_slave_t *slave, /**< EtherCAT slave */
   504     off_t off = 0;
  1048                     unsigned int verbosity /**< verbosity level */
   505     ec_sii_sync_t *sync;
  1049                     )
   506     ec_sii_pdo_t *pdo;
  1050 {
   507     ec_sii_pdo_entry_t *pdo_entry;
  1051     ec_eeprom_sync_t *sync;
       
  1052     ec_eeprom_pdo_t *pdo;
       
  1053     ec_eeprom_pdo_entry_t *pdo_entry;
       
  1054     ec_sdo_t *sdo;
       
  1055     ec_sdo_entry_t *sdo_entry;
       
  1056     int first, i;
   508     int first, i;
  1057 
   509 
  1058     if (slave->type) {
   510     off += sprintf(buffer + off, "\nName: ");
  1059         EC_INFO("%i) %s %s: %s\n", slave->ring_position,
   511 
  1060                 slave->type->vendor_name, slave->type->product_name,
   512     if (slave->sii_name)
  1061                 slave->type->description);
   513         off += sprintf(buffer + off, "%s", slave->sii_name);
  1062     }
   514 
  1063     else {
   515     off += sprintf(buffer + off, "\n\nVendor ID: 0x%08X\n",
  1064         EC_INFO("%i) UNKNOWN SLAVE: vendor 0x%08X, product 0x%08X\n",
   516                    slave->sii_vendor_id);
  1065                 slave->ring_position, slave->sii_vendor_id,
   517     off += sprintf(buffer + off, "Product code: 0x%08X\n\n",
  1066                 slave->sii_product_code);
   518                    slave->sii_product_code);
  1067     }
   519 
  1068 
   520     off += sprintf(buffer + off, "Ring position: %i\n", slave->ring_position);
  1069     if (!verbosity) return;
   521     off += sprintf(buffer + off, "Advanced position: %i:%i\n\n",
  1070 
   522                    slave->coupler_index, slave->coupler_subindex);
  1071     EC_INFO("  Station address: 0x%04X\n", slave->station_address);
   523 
  1072 
   524     off += sprintf(buffer + off, "State: ");
  1073     EC_INFO("  Data link status:\n");
   525     off += ec_state_string(slave->current_state, buffer + off);
       
   526     off += sprintf(buffer + off, "\n\n");
       
   527 
       
   528     off += sprintf(buffer + off, "Data link status:\n");
  1074     for (i = 0; i < 4; i++) {
   529     for (i = 0; i < 4; i++) {
  1075         EC_INFO("    Port %i (", i);
   530         off += sprintf(buffer + off, "  Port %i (", i);
  1076         switch (slave->sii_physical_layer[i]) {
   531         switch (slave->sii_physical_layer[i]) {
  1077             case 0x00:
   532             case 0x00:
  1078                 printk("EBUS");
   533                 off += sprintf(buffer + off, "EBUS");
  1079                 break;
   534                 break;
  1080             case 0x01:
   535             case 0x01:
  1081                 printk("100BASE-TX");
   536                 off += sprintf(buffer + off, "100BASE-TX");
  1082                 break;
   537                 break;
  1083             case 0x02:
   538             case 0x02:
  1084                 printk("100BASE-FX");
   539                 off += sprintf(buffer + off, "100BASE-FX");
  1085                 break;
   540                 break;
  1086             default:
   541             default:
  1087                 printk("unknown");
   542                 off += sprintf(buffer + off, "unknown (%i)",
  1088         }
   543                                slave->sii_physical_layer[i]);
  1089         printk(")\n");
   544         }
  1090         EC_INFO("      link %s, loop %s, %s\n",
   545         off += sprintf(buffer + off, ") Link %s, Loop %s, %s\n",
  1091                 slave->dl_link[i] ? "up" : "down",
   546                        slave->dl_link[i] ? "up" : "down",
  1092                 slave->dl_loop[i] ? "closed" : "open",
   547                        slave->dl_loop[i] ? "closed" : "open",
  1093                 slave->dl_signal[i] ? "signal detected" : "no signal");
   548                        slave->dl_signal[i] ? "Signal detected" : "No signal");
  1094     }
   549     }
  1095 
       
  1096     EC_INFO("  Base information:\n");
       
  1097     EC_INFO("    Type %u, revision %i, build %i\n",
       
  1098             slave->base_type, slave->base_revision, slave->base_build);
       
  1099     EC_INFO("    Supported FMMUs: %i, sync managers: %i\n",
       
  1100             slave->base_fmmu_count, slave->base_sync_count);
       
  1101 
   550 
  1102     if (slave->sii_mailbox_protocols) {
   551     if (slave->sii_mailbox_protocols) {
  1103         EC_INFO("  Mailbox communication:\n");
   552         off += sprintf(buffer + off, "\nMailboxes:\n");
  1104         EC_INFO("    RX mailbox: 0x%04X/%i, TX mailbox: 0x%04X/%i\n",
   553         off += sprintf(buffer + off, "  RX mailbox: 0x%04X/%i,"
  1105                 slave->sii_rx_mailbox_offset, slave->sii_rx_mailbox_size,
   554                        " TX mailbox: 0x%04X/%i\n",
  1106                 slave->sii_tx_mailbox_offset, slave->sii_tx_mailbox_size);
   555                        slave->sii_rx_mailbox_offset,
  1107         EC_INFO("    Supported protocols: ");
   556                        slave->sii_rx_mailbox_size,
       
   557                        slave->sii_tx_mailbox_offset,
       
   558                        slave->sii_tx_mailbox_size);
       
   559         off += sprintf(buffer + off, "  Supported protocols: ");
  1108 
   560 
  1109         first = 1;
   561         first = 1;
  1110         if (slave->sii_mailbox_protocols & EC_MBOX_AOE) {
   562         if (slave->sii_mailbox_protocols & EC_MBOX_AOE) {
  1111             printk("AoE");
   563             off += sprintf(buffer + off, "AoE");
  1112             first = 0;
   564             first = 0;
  1113         }
   565         }
  1114         if (slave->sii_mailbox_protocols & EC_MBOX_EOE) {
   566         if (slave->sii_mailbox_protocols & EC_MBOX_EOE) {
  1115             if (!first) printk(", ");
   567             if (!first) off += sprintf(buffer + off, ", ");
  1116             printk("EoE");
   568             off += sprintf(buffer + off, "EoE");
  1117             first = 0;
   569             first = 0;
  1118         }
   570         }
  1119         if (slave->sii_mailbox_protocols & EC_MBOX_COE) {
   571         if (slave->sii_mailbox_protocols & EC_MBOX_COE) {
  1120             if (!first) printk(", ");
   572             if (!first) off += sprintf(buffer + off, ", ");
  1121             printk("CoE");
   573             off += sprintf(buffer + off, "CoE");
  1122             first = 0;
   574             first = 0;
  1123         }
   575         }
  1124         if (slave->sii_mailbox_protocols & EC_MBOX_FOE) {
   576         if (slave->sii_mailbox_protocols & EC_MBOX_FOE) {
  1125             if (!first) printk(", ");
   577             if (!first) off += sprintf(buffer + off, ", ");
  1126             printk("FoE");
   578             off += sprintf(buffer + off, "FoE");
  1127             first = 0;
   579             first = 0;
  1128         }
   580         }
  1129         if (slave->sii_mailbox_protocols & EC_MBOX_SOE) {
   581         if (slave->sii_mailbox_protocols & EC_MBOX_SOE) {
  1130             if (!first) printk(", ");
   582             if (!first) off += sprintf(buffer + off, ", ");
  1131             printk("SoE");
   583             off += sprintf(buffer + off, "SoE");
  1132             first = 0;
   584             first = 0;
  1133         }
   585         }
  1134         if (slave->sii_mailbox_protocols & EC_MBOX_VOE) {
   586         if (slave->sii_mailbox_protocols & EC_MBOX_VOE) {
  1135             if (!first) printk(", ");
   587             if (!first) off += sprintf(buffer + off, ", ");
  1136             printk("VoE");
   588             off += sprintf(buffer + off, "VoE");
  1137         }
   589         }
  1138         printk("\n");
   590         off += sprintf(buffer + off, "\n");
  1139     }
   591     }
  1140 
   592 
  1141     EC_INFO("  EEPROM data:\n");
   593     if (slave->sii_alias || slave->sii_group
  1142 
   594         || slave->sii_image || slave->sii_order)
  1143     EC_INFO("    EEPROM content size: %i Bytes\n", slave->eeprom_size);
   595         off += sprintf(buffer + off, "\nSII data:\n");
  1144 
   596 
  1145     if (slave->sii_alias)
   597     if (slave->sii_alias)
  1146         EC_INFO("    Configured station alias: 0x%04X (%i)\n",
   598         off += sprintf(buffer + off, "  Configured station alias:"
  1147                 slave->sii_alias, slave->sii_alias);
   599                        " 0x%04X (%i)\n", slave->sii_alias, slave->sii_alias);
  1148 
   600     if (slave->sii_group)
  1149     EC_INFO("    Vendor-ID: 0x%08X, Product code: 0x%08X\n",
   601         off += sprintf(buffer + off, "  Group: %s\n", slave->sii_group);
  1150             slave->sii_vendor_id, slave->sii_product_code);
   602     if (slave->sii_image)
  1151     EC_INFO("    Revision number: 0x%08X, Serial number: 0x%08X\n",
   603         off += sprintf(buffer + off, "  Image: %s\n", slave->sii_image);
  1152             slave->sii_revision_number, slave->sii_serial_number);
   604     if (slave->sii_order)
  1153 
   605         off += sprintf(buffer + off, "  Order#: %s\n", slave->sii_order);
  1154     if (slave->eeprom_group)
   606 
  1155         EC_INFO("    Group: %s\n", slave->eeprom_group);
   607     if (!list_empty(&slave->sii_syncs))
  1156     if (slave->eeprom_image)
   608         off += sprintf(buffer + off, "\nSync-Managers:\n");
  1157         EC_INFO("    Image: %s\n", slave->eeprom_image);
   609 
  1158     if (slave->eeprom_order)
   610     list_for_each_entry(sync, &slave->sii_syncs, list) {
  1159         EC_INFO("    Order#: %s\n", slave->eeprom_order);
   611         off += sprintf(buffer + off, "  %i: 0x%04X, length %i,"
  1160     if (slave->eeprom_name)
   612                        " control 0x%02X, %s\n",
  1161         EC_INFO("    Name: %s\n", slave->eeprom_name);
   613                        sync->index, sync->physical_start_address,
  1162 
   614                        sync->length, sync->control_register,
  1163     if (!list_empty(&slave->eeprom_syncs)) {
   615                        sync->enable ? "enable" : "disable");
  1164         EC_INFO("    Sync-Managers:\n");
   616     }
  1165         list_for_each_entry(sync, &slave->eeprom_syncs, list) {
   617 
  1166             EC_INFO("      %i: 0x%04X, length %i, control 0x%02X, %s\n",
   618     if (!list_empty(&slave->sii_pdos))
  1167                     sync->index, sync->physical_start_address,
   619         off += sprintf(buffer + off, "\nPDOs:\n");
  1168                     sync->length, sync->control_register,
   620 
  1169                     sync->enable ? "enable" : "disable");
   621     list_for_each_entry(pdo, &slave->sii_pdos, list) {
  1170         }
   622         off += sprintf(buffer + off,
  1171     }
   623                        "  %s \"%s\" (0x%04X), -> Sync-Manager %i\n",
  1172 
   624                        pdo->type == EC_RX_PDO ? "RXPDO" : "TXPDO",
  1173     list_for_each_entry(pdo, &slave->eeprom_pdos, list) {
   625                        pdo->name ? pdo->name : "???",
  1174         EC_INFO("    %s \"%s\" (0x%04X), -> Sync-Manager %i\n",
   626                        pdo->index, pdo->sync_index);
  1175                 pdo->type == EC_RX_PDO ? "RXPDO" : "TXPDO",
       
  1176                 pdo->name ? pdo->name : "???",
       
  1177                 pdo->index, pdo->sync_manager);
       
  1178 
   627 
  1179         list_for_each_entry(pdo_entry, &pdo->entries, list) {
   628         list_for_each_entry(pdo_entry, &pdo->entries, list) {
  1180             EC_INFO("      \"%s\" 0x%04X:%X, %i Bit\n",
   629             off += sprintf(buffer + off, "    \"%s\" 0x%04X:%X, %i Bit\n",
  1181                     pdo_entry->name ? pdo_entry->name : "???",
   630                            pdo_entry->name ? pdo_entry->name : "???",
  1182                     pdo_entry->index, pdo_entry->subindex,
   631                            pdo_entry->index, pdo_entry->subindex,
  1183                     pdo_entry->bit_length);
   632                            pdo_entry->bit_length);
  1184         }
   633         }
  1185     }
   634     }
  1186 
   635 
  1187     if (verbosity < 2) return;
   636     off += sprintf(buffer + off, "\n");
  1188 
   637 
  1189     if (!list_empty(&slave->sdo_dictionary)) {
   638     return off;
  1190         EC_INFO("    SDO-Dictionary:\n");
   639 }
  1191         list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
   640 
  1192             EC_INFO("      0x%04X \"%s\"\n", sdo->index,
   641 /*****************************************************************************/
  1193                     sdo->name ? sdo->name : "");
   642 
  1194             EC_INFO("        Object code: 0x%02X\n", sdo->object_code);
   643 #if 0
  1195             list_for_each_entry(sdo_entry, &sdo->entries, list) {
       
  1196                 EC_INFO("        0x%04X:%i \"%s\", type 0x%04X, %i bits\n",
       
  1197                         sdo->index, sdo_entry->subindex,
       
  1198                         sdo_entry->name ? sdo_entry->name : "",
       
  1199                         sdo_entry->data_type, sdo_entry->bit_length);
       
  1200             }
       
  1201         }
       
  1202     }
       
  1203 }
       
  1204 
       
  1205 /*****************************************************************************/
       
  1206 
   644 
  1207 /**
   645 /**
  1208    Outputs the values of the CRC faoult counters and resets them.
   646    Outputs the values of the CRC faoult counters and resets them.
  1209    \return 0 in case of success, else < 0
   647    \return 0 in case of success, else < 0
  1210 */
   648 */
  1257     }
   695     }
  1258 
   696 
  1259     return 0;
   697     return 0;
  1260 }
   698 }
  1261 
   699 
       
   700 #endif
       
   701 
  1262 /*****************************************************************************/
   702 /*****************************************************************************/
  1263 
   703 
  1264 /**
   704 /**
  1265    Schedules an EEPROM write operation.
   705    Schedules an EEPROM write operation.
  1266    \return 0 in case of success, else < 0
   706    \return 0 in case of success, else < 0
  1348                                 char *buffer /**< memory to store data */
   788                                 char *buffer /**< memory to store data */
  1349                                 )
   789                                 )
  1350 {
   790 {
  1351     ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj);
   791     ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj);
  1352 
   792 
  1353     if (attr == &attr_ring_position) {
   793     if (attr == &attr_info) {
  1354         return sprintf(buffer, "%i\n", slave->ring_position);
   794         return ec_slave_info(slave, buffer);
  1355     }
       
  1356     else if (attr == &attr_advanced_position) {
       
  1357         return sprintf(buffer, "%i:%i\n", slave->coupler_index,
       
  1358                        slave->coupler_subindex);
       
  1359     }
       
  1360     else if (attr == &attr_vendor_name) {
       
  1361         if (slave->type)
       
  1362             return sprintf(buffer, "%s\n", slave->type->vendor_name);
       
  1363     }
       
  1364     else if (attr == &attr_product_name) {
       
  1365         if (slave->type)
       
  1366             return sprintf(buffer, "%s\n", slave->type->product_name);
       
  1367     }
       
  1368     else if (attr == &attr_product_desc) {
       
  1369         if (slave->type)
       
  1370             return sprintf(buffer, "%s\n", slave->type->description);
       
  1371     }
       
  1372     else if (attr == &attr_name) {
       
  1373         if (slave->eeprom_name)
       
  1374             return sprintf(buffer, "%s\n", slave->eeprom_name);
       
  1375     }
       
  1376     else if (attr == &attr_type) {
       
  1377         if (slave->type) {
       
  1378             if (slave->type->special == EC_TYPE_BUS_COUPLER)
       
  1379                 return sprintf(buffer, "coupler\n");
       
  1380 	    else if (slave->type->special == EC_TYPE_INFRA)
       
  1381                 return sprintf(buffer, "infrastructure\n");
       
  1382             else
       
  1383                 return sprintf(buffer, "normal\n");
       
  1384         }
       
  1385     }
   795     }
  1386     else if (attr == &attr_state) {
   796     else if (attr == &attr_state) {
  1387         switch (slave->current_state) {
   797         switch (slave->current_state) {
  1388             case EC_SLAVE_STATE_INIT:
   798             case EC_SLAVE_STATE_INIT:
  1389                 return sprintf(buffer, "INIT\n");
   799                 return sprintf(buffer, "INIT\n");
  1457 }
   867 }
  1458 
   868 
  1459 /*****************************************************************************/
   869 /*****************************************************************************/
  1460 
   870 
  1461 /**
   871 /**
  1462    \return size of sync manager contents
       
  1463 */
       
  1464 
       
  1465 size_t ec_slave_calc_sync_size(const ec_slave_t *slave, /**< EtherCAT slave */
       
  1466                                const ec_sync_t *sync /**< sync manager */
       
  1467                                )
       
  1468 {
       
  1469     unsigned int i, found;
       
  1470     const ec_field_t *field;
       
  1471     const ec_varsize_t *var;
       
  1472     size_t size;
       
  1473 
       
  1474     // if size is specified, return size
       
  1475     if (sync->size) return sync->size;
       
  1476 
       
  1477     // sync manager has variable size (size == 0).
       
  1478 
       
  1479     size = 0;
       
  1480     for (i = 0; (field = sync->fields[i]); i++) {
       
  1481         found = 0;
       
  1482         list_for_each_entry(var, &slave->varsize_fields, list) {
       
  1483             if (var->field != field) continue;
       
  1484             size += var->size;
       
  1485             found = 1;
       
  1486         }
       
  1487 
       
  1488         if (!found) {
       
  1489             EC_WARN("Variable data field \"%s\" of slave %i has no size"
       
  1490                     " information!\n", field->name, slave->ring_position);
       
  1491         }
       
  1492     }
       
  1493     return size;
       
  1494 }
       
  1495 
       
  1496 /*****************************************************************************/
       
  1497 
       
  1498 /**
       
  1499    Calculates the size of a sync manager by evaluating PDO sizes.
   872    Calculates the size of a sync manager by evaluating PDO sizes.
  1500    \return sync manager size
   873    \return sync manager size
  1501 */
   874 */
  1502 
   875 
  1503 uint16_t ec_slave_calc_eeprom_sync_size(const ec_slave_t *slave,
   876 uint16_t ec_slave_calc_sync_size(const ec_slave_t *slave,
  1504                                         /**< EtherCAT slave */
   877                                  /**< EtherCAT slave */
  1505                                         const ec_eeprom_sync_t *sync
   878                                  const ec_sii_sync_t *sync
  1506                                         /**< sync manager */
   879                                  /**< sync manager */
  1507                                         )
   880                                  )
  1508 {
   881 {
  1509     ec_eeprom_pdo_t *pdo;
   882     ec_sii_pdo_t *pdo;
  1510     ec_eeprom_pdo_entry_t *pdo_entry;
   883     ec_sii_pdo_entry_t *pdo_entry;
  1511     unsigned int bit_size;
   884     unsigned int bit_size;
  1512 
   885 
  1513     if (sync->length) return sync->length;
   886     if (sync->length) return sync->length;
  1514 
   887 
  1515     bit_size = 0;
   888     bit_size = 0;
  1516     list_for_each_entry(pdo, &slave->eeprom_pdos, list) {
   889     list_for_each_entry(pdo, &slave->sii_pdos, list) {
  1517         if (pdo->sync_manager != sync->index) continue;
   890         if (pdo->sync_index != sync->index) continue;
  1518 
   891 
  1519         list_for_each_entry(pdo_entry, &pdo->entries, list) {
   892         list_for_each_entry(pdo_entry, &pdo->entries, list) {
  1520             bit_size += pdo_entry->bit_length;
   893             bit_size += pdo_entry->bit_length;
  1521         }
   894         }
  1522     }
   895     }
  1525         return bit_size / 8 + 1;
   898         return bit_size / 8 + 1;
  1526     else
   899     else
  1527         return bit_size / 8;
   900         return bit_size / 8;
  1528 }
   901 }
  1529 
   902 
       
   903 /*****************************************************************************/
       
   904 
       
   905 /**
       
   906    \return non-zero if slave is a bus coupler
       
   907 */
       
   908 
       
   909 int ec_slave_is_coupler(const ec_slave_t *slave)
       
   910 {
       
   911     // TODO: Better bus coupler criterion
       
   912     return slave->sii_vendor_id == 0x00000002
       
   913         && slave->sii_product_code == 0x044C2C52;
       
   914 }
       
   915 
  1530 /******************************************************************************
   916 /******************************************************************************
  1531  *  Realtime interface
   917  *  Realtime interface
  1532  *****************************************************************************/
   918  *****************************************************************************/
  1533 
   919 
  1534 /**
   920 /**
  1535    Writes the "configured station alias" to the slave's EEPROM.
       
  1536    \return 0 in case of success, else < 0
   921    \return 0 in case of success, else < 0
  1537    \ingroup RealtimeInterface
   922    \ingroup RealtimeInterface
  1538 */
   923 */
  1539 
   924 
  1540 int ecrt_slave_write_alias(ec_slave_t *slave, /**< EtherCAT slave */
   925 int ecrt_slave_pdo_size(ec_slave_t *slave, /**< EtherCAT slave */
  1541                            uint16_t alias /**< new alias */
   926                         uint16_t pdo_index, /**< PDO index */
  1542                            )
   927                         uint8_t pdo_subindex, /**< PDO subindex */
  1543 {
   928                         size_t size /**< new PDO size */
  1544     return ec_slave_sii_write16(slave, 0x0004, alias);
   929                         )
  1545 }
   930 {
  1546 
   931     EC_WARN("ecrt_slave_pdo_size() currently not available.\n");
  1547 /*****************************************************************************/
   932     return -1;
  1548 
   933 
  1549 /**
   934 #if 0
  1550    \return 0 in case of success, else < 0
       
  1551    \ingroup RealtimeInterface
       
  1552 */
       
  1553 
       
  1554 int ecrt_slave_field_size(ec_slave_t *slave, /**< EtherCAT slave */
       
  1555                           const char *field_name, /**< data field name */
       
  1556                           unsigned int field_index, /**< data field index */
       
  1557                           size_t size /**< new data field size */
       
  1558                           )
       
  1559 {
       
  1560     unsigned int i, j, field_counter;
   935     unsigned int i, j, field_counter;
  1561     const ec_sync_t *sync;
   936     const ec_sii_sync_t *sync;
  1562     const ec_field_t *field;
   937     const ec_pdo_t *pdo;
  1563     ec_varsize_t *var;
   938     ec_varsize_t *var;
  1564 
   939 
  1565     if (!slave->type) {
   940     if (!slave->type) {
  1566         EC_ERR("Slave %i has no type information!\n", slave->ring_position);
   941         EC_ERR("Slave %i has no type information!\n", slave->ring_position);
  1567         return -1;
   942         return -1;
  1605 
   980 
  1606     EC_ERR("Slave %i (\"%s %s\") has no field \"%s\"[%i]!\n",
   981     EC_ERR("Slave %i (\"%s %s\") has no field \"%s\"[%i]!\n",
  1607            slave->ring_position, slave->type->vendor_name,
   982            slave->ring_position, slave->type->vendor_name,
  1608            slave->type->product_name, field_name, field_index);
   983            slave->type->product_name, field_name, field_index);
  1609     return -1;
   984     return -1;
       
   985 #endif
  1610 }
   986 }
  1611 
   987 
  1612 /*****************************************************************************/
   988 /*****************************************************************************/
  1613 
   989 
  1614 /**< \cond */
   990 /**< \cond */
  1615 
   991 
  1616 EXPORT_SYMBOL(ecrt_slave_write_alias);
   992 EXPORT_SYMBOL(ecrt_slave_pdo_size);
  1617 EXPORT_SYMBOL(ecrt_slave_field_size);
       
  1618 
   993 
  1619 /**< \endcond */
   994 /**< \endcond */
  1620 
   995 
  1621 /*****************************************************************************/
   996 /*****************************************************************************/