master/slave.c
changeset 792 3778920f61e4
parent 784 0a0994fdafb8
child 799 068a58b96965
equal deleted inserted replaced
791:3b81d074735c 792:3778920f61e4
    40 
    40 
    41 #include <linux/module.h>
    41 #include <linux/module.h>
    42 #include <linux/delay.h>
    42 #include <linux/delay.h>
    43 
    43 
    44 #include "globals.h"
    44 #include "globals.h"
    45 #include "slave.h"
       
    46 #include "datagram.h"
    45 #include "datagram.h"
    47 #include "master.h"
    46 #include "master.h"
       
    47 #include "slave_config.h"
       
    48 
       
    49 #include "slave.h"
    48 
    50 
    49 /*****************************************************************************/
    51 /*****************************************************************************/
    50 
    52 
    51 extern const ec_code_msg_t al_status_messages[];
    53 extern const ec_code_msg_t al_status_messages[];
    52 
    54 
   111     slave->ring_position = ring_position;
   113     slave->ring_position = ring_position;
   112     slave->station_address = station_address;
   114     slave->station_address = station_address;
   113 
   115 
   114     slave->master = master;
   116     slave->master = master;
   115 
   117 
       
   118     slave->config = NULL;
   116     slave->requested_state = EC_SLAVE_STATE_PREOP;
   119     slave->requested_state = EC_SLAVE_STATE_PREOP;
   117     slave->current_state = EC_SLAVE_STATE_UNKNOWN;
   120     slave->current_state = EC_SLAVE_STATE_UNKNOWN;
       
   121     slave->online_state = EC_SLAVE_ONLINE;
   118     slave->self_configured = 0;
   122     slave->self_configured = 0;
   119     slave->error_flag = 0;
   123     slave->error_flag = 0;
   120     slave->online_state = EC_SLAVE_ONLINE;
       
   121     slave->fmmu_count = 0;
       
   122     slave->pdos_registered = 0;
       
   123 
   124 
   124     slave->base_type = 0;
   125     slave->base_type = 0;
   125     slave->base_revision = 0;
   126     slave->base_revision = 0;
   126     slave->base_build = 0;
   127     slave->base_build = 0;
   127     slave->base_fmmu_count = 0;
   128     slave->base_fmmu_count = 0;
   149     slave->sii_string_count = 0;
   150     slave->sii_string_count = 0;
   150     slave->sii_syncs = NULL;
   151     slave->sii_syncs = NULL;
   151     slave->sii_sync_count = 0;
   152     slave->sii_sync_count = 0;
   152     INIT_LIST_HEAD(&slave->sii_pdos);
   153     INIT_LIST_HEAD(&slave->sii_pdos);
   153     INIT_LIST_HEAD(&slave->sdo_dictionary);
   154     INIT_LIST_HEAD(&slave->sdo_dictionary);
   154     INIT_LIST_HEAD(&slave->sdo_confs);
       
   155 
   155 
   156     slave->sdo_dictionary_fetched = 0;
   156     slave->sdo_dictionary_fetched = 0;
   157     slave->pdo_mapping_fetched = 0;
   157     slave->pdo_mapping_fetched = 0;
   158     slave->jiffies_preop = 0;
   158     slave->jiffies_preop = 0;
   159 
   159 
   211 
   211 
   212 void ec_slave_destroy(ec_slave_t *slave /**< EtherCAT slave */)
   212 void ec_slave_destroy(ec_slave_t *slave /**< EtherCAT slave */)
   213 {
   213 {
   214     ec_sdo_t *sdo, *next_sdo;
   214     ec_sdo_t *sdo, *next_sdo;
   215 
   215 
       
   216     if (slave->config)
       
   217         ec_slave_config_detach(slave->config);
       
   218 
   216     // free all SDOs
   219     // free all SDOs
   217     list_for_each_entry_safe(sdo, next_sdo, &slave->sdo_dictionary, list) {
   220     list_for_each_entry_safe(sdo, next_sdo, &slave->sdo_dictionary, list) {
   218         list_del(&sdo->list);
   221         list_del(&sdo->list);
   219         ec_sdo_destroy(sdo);
   222         ec_sdo_destroy(sdo);
   220     }
   223     }
   238 
   241 
   239 void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
   242 void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
   240 {
   243 {
   241     ec_slave_t *slave;
   244     ec_slave_t *slave;
   242     ec_pdo_t *pdo, *next_pdo;
   245     ec_pdo_t *pdo, *next_pdo;
   243     ec_sdo_data_t *sdodata, *next_sdodata;
       
   244     unsigned int i;
   246     unsigned int i;
   245 
   247 
   246     slave = container_of(kobj, ec_slave_t, kobj);
   248     slave = container_of(kobj, ec_slave_t, kobj);
   247 
   249 
   248     // free all strings
   250     // free all strings
   265         list_del(&pdo->list);
   267         list_del(&pdo->list);
   266         ec_pdo_clear(pdo);
   268         ec_pdo_clear(pdo);
   267         kfree(pdo);
   269         kfree(pdo);
   268     }
   270     }
   269 
   271 
   270     // free all SDO configurations
       
   271     list_for_each_entry_safe(sdodata, next_sdodata, &slave->sdo_confs, list) {
       
   272         list_del(&sdodata->list);
       
   273         kfree(sdodata->data);
       
   274         kfree(sdodata);
       
   275     }
       
   276 
       
   277     if (slave->eeprom_data) kfree(slave->eeprom_data);
   272     if (slave->eeprom_data) kfree(slave->eeprom_data);
   278 
   273 
   279     kfree(slave);
   274     kfree(slave);
   280 }
   275 }
   281 
   276 
   285  * SDO kobject clear method.
   280  * SDO kobject clear method.
   286  */
   281  */
   287 
   282 
   288 void ec_slave_sdos_clear(struct kobject *kobj /**< kobject for SDOs */)
   283 void ec_slave_sdos_clear(struct kobject *kobj /**< kobject for SDOs */)
   289 {
   284 {
   290 }
       
   291 
       
   292 /*****************************************************************************/
       
   293 
       
   294 /**
       
   295    Reset slave from operation mode.
       
   296 */
       
   297 
       
   298 void ec_slave_reset(ec_slave_t *slave /**< EtherCAT slave */)
       
   299 {
       
   300     ec_sdo_data_t *sdodata, *next_sdodata;
       
   301     unsigned int i;
       
   302 
       
   303     slave->fmmu_count = 0;
       
   304     slave->pdos_registered = 0;
       
   305 
       
   306     // free all SDO configurations
       
   307     list_for_each_entry_safe(sdodata, next_sdodata, &slave->sdo_confs, list) {
       
   308         list_del(&sdodata->list);
       
   309         kfree(sdodata->data);
       
   310         kfree(sdodata);
       
   311     }
       
   312 
       
   313     // remove estimated sync manager sizes
       
   314     for (i = 0; i < slave->sii_sync_count; i++) {
       
   315         slave->sii_syncs[i].est_length = 0;
       
   316     }
       
   317 }
   285 }
   318 
   286 
   319 /*****************************************************************************/
   287 /*****************************************************************************/
   320 
   288 
   321 /**
   289 /**
   349         ec_slave_online_state_t new_state /**< new online state */
   317         ec_slave_online_state_t new_state /**< new online state */
   350         )
   318         )
   351 {
   319 {
   352     if (new_state == EC_SLAVE_OFFLINE &&
   320     if (new_state == EC_SLAVE_OFFLINE &&
   353             slave->online_state == EC_SLAVE_ONLINE) {
   321             slave->online_state == EC_SLAVE_ONLINE) {
   354         if (slave->pdos_registered)
       
   355             slave->master->pdo_slaves_offline++;
       
   356         if (slave->master->debug_level)
   322         if (slave->master->debug_level)
   357             EC_DBG("Slave %u: offline.\n", slave->ring_position);
   323             EC_DBG("Slave %u: offline.\n", slave->ring_position);
   358     }
   324     }
   359     else if (new_state == EC_SLAVE_ONLINE &&
   325     else if (new_state == EC_SLAVE_ONLINE &&
   360             slave->online_state == EC_SLAVE_OFFLINE) {
   326             slave->online_state == EC_SLAVE_OFFLINE) {
   361         slave->error_flag = 0; // clear error flag
   327         slave->error_flag = 0; // clear error flag
   362         if (slave->pdos_registered)
       
   363             slave->master->pdo_slaves_offline--;
       
   364         if (slave->master->debug_level) {
   328         if (slave->master->debug_level) {
   365             char cur_state[EC_STATE_STRING_SIZE];
   329             char cur_state[EC_STATE_STRING_SIZE];
   366             ec_state_string(slave->current_state, cur_state);
   330             ec_state_string(slave->current_state, cur_state);
   367             EC_DBG("Slave %u: online (%s).\n",
   331             EC_DBG("Slave %u: online (%s).\n",
   368                    slave->ring_position, cur_state);
   332                    slave->ring_position, cur_state);
   532 
   496 
   533 int ec_slave_fetch_sii_pdos(
   497 int ec_slave_fetch_sii_pdos(
   534         ec_slave_t *slave, /**< EtherCAT slave */
   498         ec_slave_t *slave, /**< EtherCAT slave */
   535         const uint8_t *data, /**< category data */
   499         const uint8_t *data, /**< category data */
   536         size_t data_size, /**< number of bytes */
   500         size_t data_size, /**< number of bytes */
   537         ec_pdo_type_t pdo_type /**< PDO type */
   501         ec_direction_t dir /**< PDO direction. */
   538         )
   502         )
   539 {
   503 {
   540     ec_pdo_t *pdo;
   504     ec_pdo_t *pdo;
   541     ec_pdo_entry_t *entry;
   505     ec_pdo_entry_t *entry;
   542     unsigned int entry_count, i;
   506     unsigned int entry_count, i;
   546             EC_ERR("Failed to allocate PDO memory.\n");
   510             EC_ERR("Failed to allocate PDO memory.\n");
   547             return -1;
   511             return -1;
   548         }
   512         }
   549 
   513 
   550         ec_pdo_init(pdo);
   514         ec_pdo_init(pdo);
   551         pdo->type = pdo_type;
   515         pdo->dir = dir;
   552         pdo->index = EC_READ_U16(data);
   516         pdo->index = EC_READ_U16(data);
   553         entry_count = EC_READ_U8(data + 2);
   517         entry_count = EC_READ_U8(data + 2);
   554         pdo->sync_index = EC_READ_U8(data + 3);
   518         pdo->sync_index = EC_READ_U8(data + 3);
   555         pdo->name = ec_slave_sii_string(slave, EC_READ_U8(data + 5));
   519         if (ec_pdo_set_name(pdo,
       
   520                 ec_slave_sii_string(slave, EC_READ_U8(data + 5)))) {
       
   521             ec_pdo_clear(pdo);
       
   522             kfree(pdo);
       
   523             return -1;
       
   524         }
   556         list_add_tail(&pdo->list, &slave->sii_pdos);
   525         list_add_tail(&pdo->list, &slave->sii_pdos);
   557 
   526 
   558         data_size -= 8;
   527         data_size -= 8;
   559         data += 8;
   528         data += 8;
   560 
   529 
   562             if (!(entry = kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
   531             if (!(entry = kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
   563                 EC_ERR("Failed to allocate PDO entry memory.\n");
   532                 EC_ERR("Failed to allocate PDO entry memory.\n");
   564                 return -1;
   533                 return -1;
   565             }
   534             }
   566 
   535 
       
   536             ec_pdo_entry_init(entry);
   567             entry->index = EC_READ_U16(data);
   537             entry->index = EC_READ_U16(data);
   568             entry->subindex = EC_READ_U8(data + 2);
   538             entry->subindex = EC_READ_U8(data + 2);
   569             entry->name = ec_slave_sii_string(slave, EC_READ_U8(data + 3));
   539             if (ec_pdo_entry_set_name(entry,
       
   540                     ec_slave_sii_string(slave, EC_READ_U8(data + 3)))) {
       
   541                 ec_pdo_entry_clear(entry);
       
   542                 kfree(entry);
       
   543                 return -1;
       
   544             }
   570             entry->bit_length = EC_READ_U8(data + 5);
   545             entry->bit_length = EC_READ_U8(data + 5);
   571             list_add_tail(&entry->list, &pdo->entries);
   546             list_add_tail(&entry->list, &pdo->entries);
   572 
   547 
   573             data_size -= 8;
   548             data_size -= 8;
   574             data += 8;
   549             data += 8;
   575         }
   550         }
   576 
   551 
   577         // if sync manager index is positive, the PDO is mapped by default
   552         // if sync manager index is positive, the PDO is mapped by default
   578         if (pdo->sync_index >= 0) {
   553         if (pdo->sync_index >= 0) {
   579             ec_sync_t *sync;
   554             ec_sync_t *sync;
   580             ec_pdo_t *mapped_pdo;
       
   581 
   555 
   582             if (pdo->sync_index >= slave->sii_sync_count) {
   556             if (pdo->sync_index >= slave->sii_sync_count) {
   583                 EC_ERR("Invalid SM index %i for PDO 0x%04X in slave %u.",
   557                 EC_ERR("Invalid SM index %i for PDO 0x%04X in slave %u.",
   584                         pdo->sync_index, pdo->index, slave->ring_position);
   558                         pdo->sync_index, pdo->index, slave->ring_position);
   585                 return -1;
   559                 return -1;
   586             }
   560             }
   587             sync = &slave->sii_syncs[pdo->sync_index];
   561             sync = &slave->sii_syncs[pdo->sync_index];
   588 
   562 
   589             if (!(mapped_pdo = kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
   563             if (ec_pdo_mapping_add_pdo(&sync->mapping, pdo))
   590                 EC_ERR("Failed to allocate PDO memory.\n");
       
   591                 return -1;
   564                 return -1;
   592             }
   565 
   593 
       
   594             if (ec_pdo_copy(mapped_pdo, pdo)) {
       
   595                 EC_ERR("Failed to copy PDO.\n");
       
   596                 kfree(mapped_pdo);
       
   597                 return -1;
       
   598             }
       
   599 
       
   600             list_add_tail(&mapped_pdo->list, &sync->pdos);
       
   601             sync->mapping_source = EC_SYNC_MAPPING_SII;
   566             sync->mapping_source = EC_SYNC_MAPPING_SII;
   602         }
   567         }
   603     }
   568     }
   604 
   569 
   605     return 0;
   570     return 0;
   630     return slave->sii_strings[index];
   595     return slave->sii_strings[index];
   631 }
   596 }
   632 
   597 
   633 /*****************************************************************************/
   598 /*****************************************************************************/
   634 
   599 
   635 /**
   600 /** Outputs all information about a certain slave.
   636  * Prepares an FMMU configuration.
       
   637  * Configuration data for the FMMU is saved in the slave structure and is
       
   638  * written to the slave in ecrt_master_activate().
       
   639  * The FMMU configuration is done in a way, that the complete data range
       
   640  * of the corresponding sync manager is covered. Seperate FMMUs are configured
       
   641  * for each domain.
       
   642  * If the FMMU configuration is already prepared, the function returns with
       
   643  * success.
       
   644  * \return 0 in case of success, else < 0
       
   645  */
   601  */
   646 
       
   647 int ec_slave_prepare_fmmu(
       
   648         ec_slave_t *slave, /**< EtherCAT slave */
       
   649         const ec_domain_t *domain, /**< domain */
       
   650         const ec_sync_t *sync  /**< sync manager */
       
   651         )
       
   652 {
       
   653     unsigned int i;
       
   654     ec_fmmu_t *fmmu;
       
   655 
       
   656     // FMMU configuration already prepared?
       
   657     for (i = 0; i < slave->fmmu_count; i++) {
       
   658         fmmu = &slave->fmmus[i];
       
   659         if (fmmu->domain == domain && fmmu->sync == sync)
       
   660             return 0;
       
   661     }
       
   662 
       
   663     // reserve new FMMU...
       
   664 
       
   665     if (slave->fmmu_count >= slave->base_fmmu_count) {
       
   666         EC_ERR("Slave %u FMMU limit reached!\n", slave->ring_position);
       
   667         return -1;
       
   668     }
       
   669 
       
   670     fmmu = &slave->fmmus[slave->fmmu_count];
       
   671 
       
   672     ec_fmmu_init(fmmu, slave, slave->fmmu_count++);
       
   673     fmmu->domain = domain;
       
   674     fmmu->sync = sync;
       
   675     fmmu->logical_start_address = 0;
       
   676 
       
   677     slave->pdos_registered = 1;
       
   678     
       
   679     ec_slave_request_state(slave, EC_SLAVE_STATE_OP);
       
   680 
       
   681     return 0;
       
   682 }
       
   683 
       
   684 /*****************************************************************************/
       
   685 
       
   686 /**
       
   687    Outputs all information about a certain slave.
       
   688 */
       
   689 
       
   690 ssize_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
   602 ssize_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
   691         char *buffer /**< Output buffer */
   603         char *buffer /**< Output buffer */
   692         )
   604         )
   693 {
   605 {
   694     ec_sync_t *sync;
   606     ec_sync_t *sync;
   695     ec_pdo_t *pdo;
   607     ec_pdo_t *pdo;
   696     ec_pdo_entry_t *pdo_entry;
   608     ec_pdo_entry_t *pdo_entry;
   697     int first, i;
   609     int first, i;
   698     ec_sdo_data_t *sdodata;
       
   699     char str[20];
       
   700     char *large_buffer, *buf;
   610     char *large_buffer, *buf;
   701     unsigned int size;
   611     unsigned int size;
   702 
   612 
   703     if (!(large_buffer = (char *) kmalloc(PAGE_SIZE * 2, GFP_KERNEL))) {
   613     if (!(large_buffer = (char *) kmalloc(PAGE_SIZE * 2, GFP_KERNEL))) {
   704         return -ENOMEM;
   614         return -ENOMEM;
   711     buf += sprintf(buf, "State: ");
   621     buf += sprintf(buf, "State: ");
   712     buf += ec_state_string(slave->current_state, buf);
   622     buf += ec_state_string(slave->current_state, buf);
   713     buf += sprintf(buf, " (");
   623     buf += sprintf(buf, " (");
   714     buf += ec_state_string(slave->requested_state, buf);
   624     buf += ec_state_string(slave->requested_state, buf);
   715     buf += sprintf(buf, ")\n");
   625     buf += sprintf(buf, ")\n");
   716     buf += sprintf(buf, "Flags: %s, %s\n\n",
   626     buf += sprintf(buf, "Flags: %s\n\n", slave->error_flag ? "ERROR" : "ok");
   717             slave->online_state == EC_SLAVE_ONLINE ? "online" : "OFFLINE",
       
   718             slave->error_flag ? "ERROR" : "ok");
       
   719 
   627 
   720     buf += sprintf(buf, "Data link status:\n");
   628     buf += sprintf(buf, "Data link status:\n");
   721     for (i = 0; i < 4; i++) {
   629     for (i = 0; i < 4; i++) {
   722         buf += sprintf(buf, "  Port %u: Phy %u (",
   630         buf += sprintf(buf, "  Port %u: Phy %u (",
   723                 i, slave->sii_physical_layer[i]);
   631                 i, slave->sii_physical_layer[i]);
   819         for (i = 0; i < slave->sii_sync_count; i++) {
   727         for (i = 0; i < slave->sii_sync_count; i++) {
   820             sync = &slave->sii_syncs[i];
   728             sync = &slave->sii_syncs[i];
   821             buf += sprintf(buf,
   729             buf += sprintf(buf,
   822                     "  SM%u: addr 0x%04X, size %u, control 0x%02X, %s\n",
   730                     "  SM%u: addr 0x%04X, size %u, control 0x%02X, %s\n",
   823                     sync->index, sync->physical_start_address,
   731                     sync->index, sync->physical_start_address,
   824                     ec_sync_size(sync), sync->control_register,
   732                     sync->length, sync->control_register,
   825                     sync->enable ? "enable" : "disable");
   733                     sync->enable ? "enable" : "disable");
   826 
   734 
   827             if (list_empty(&sync->pdos)) {
   735             if (list_empty(&sync->mapping.pdos)) {
   828                 buf += sprintf(buf, "    No PDOs mapped.\n");
   736                 buf += sprintf(buf, "    No PDOs mapped.\n");
   829             } else if (sync->mapping_source != EC_SYNC_MAPPING_NONE) {
   737             } else if (sync->mapping_source != EC_SYNC_MAPPING_NONE) {
   830                 buf += sprintf(buf,
   738                 buf += sprintf(buf,
   831                         "    PDO mapping information from %s.\n",
   739                         "    PDO mapping information from %s.\n",
   832                         sync->mapping_source == EC_SYNC_MAPPING_SII
   740                         sync->mapping_source == EC_SYNC_MAPPING_SII
   833                         ? "SII" : "CoE");
   741                         ? "SII" : "CoE");
   834             }
   742             }
   835 
   743 
   836             list_for_each_entry(pdo, &sync->pdos, list) {
   744             list_for_each_entry(pdo, &sync->mapping.pdos, list) {
   837                 buf += sprintf(buf, "    %s 0x%04X \"%s\"\n",
   745                 buf += sprintf(buf, "    %s 0x%04X \"%s\"\n",
   838                         pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
   746                         pdo->dir == EC_DIR_OUTPUT ? "RxPdo" : "TxPdo",
   839                         pdo->index, pdo->name ? pdo->name : "???");
   747                         pdo->index, pdo->name ? pdo->name : "???");
   840 
   748 
   841                 list_for_each_entry(pdo_entry, &pdo->entries, list) {
   749                 list_for_each_entry(pdo_entry, &pdo->entries, list) {
   842                     buf += sprintf(buf,
   750                     buf += sprintf(buf,
   843                             "      0x%04X:%X \"%s\", %u bit\n",
   751                             "      0x%04X:%X \"%s\", %u bit\n",
   854     if (!list_empty((struct list_head *) &slave->sii_pdos)) {
   762     if (!list_empty((struct list_head *) &slave->sii_pdos)) {
   855         buf += sprintf(buf, "Available PDOs from SII:\n");
   763         buf += sprintf(buf, "Available PDOs from SII:\n");
   856 
   764 
   857         list_for_each_entry(pdo, &slave->sii_pdos, list) {
   765         list_for_each_entry(pdo, &slave->sii_pdos, list) {
   858             buf += sprintf(buf, "  %s 0x%04X \"%s\"",
   766             buf += sprintf(buf, "  %s 0x%04X \"%s\"",
   859                     pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
   767                     pdo->dir == EC_DIR_OUTPUT ? "RxPdo" : "TxPdo",
   860                     pdo->index, pdo->name ? pdo->name : "???");
   768                     pdo->index, pdo->name ? pdo->name : "???");
   861             if (pdo->sync_index >= 0)
   769             if (pdo->sync_index >= 0)
   862                 buf += sprintf(buf, ", default mapping: SM%u.\n",
   770                 buf += sprintf(buf, ", default mapping: SM%u.\n",
   863                         pdo->sync_index);
   771                         pdo->sync_index);
   864             else
   772             else
   868                 buf += sprintf(buf, "    0x%04X:%X \"%s\", %u bit\n",
   776                 buf += sprintf(buf, "    0x%04X:%X \"%s\", %u bit\n",
   869                         pdo_entry->index, pdo_entry->subindex,
   777                         pdo_entry->index, pdo_entry->subindex,
   870                         pdo_entry->name ? pdo_entry->name : "???",
   778                         pdo_entry->name ? pdo_entry->name : "???",
   871                         pdo_entry->bit_length);
   779                         pdo_entry->bit_length);
   872             }
   780             }
   873         }
       
   874         buf += sprintf(buf, "\n");
       
   875     }
       
   876 
       
   877     // type-cast to avoid warnings on some compilers
       
   878     if (!list_empty((struct list_head *) &slave->sdo_confs)) {
       
   879         buf += sprintf(buf, "SDO configurations:\n");
       
   880 
       
   881         list_for_each_entry(sdodata, &slave->sdo_confs, list) {
       
   882             switch (sdodata->size) {
       
   883                 case 1: sprintf(str, "%u", EC_READ_U8(sdodata->data)); break;
       
   884                 case 2: sprintf(str, "%u", EC_READ_U16(sdodata->data)); break;
       
   885                 case 4: sprintf(str, "%u", EC_READ_U32(sdodata->data)); break;
       
   886                 default: sprintf(str, "(invalid size)"); break;
       
   887             }
       
   888             buf += sprintf(buf, "  0x%04X:%-3i -> %s\n",
       
   889                     sdodata->index, sdodata->subindex, str);
       
   890         }
   781         }
   891         buf += sprintf(buf, "\n");
   782         buf += sprintf(buf, "\n");
   892     }
   783     }
   893 
   784 
   894     size = buf - large_buffer;
   785     size = buf - large_buffer;
  1249 
  1140 
  1250 /**
  1141 /**
  1251    \return 0 in case of success, else < 0
  1142    \return 0 in case of success, else < 0
  1252 */
  1143 */
  1253 
  1144 
  1254 int ec_slave_conf_sdo(ec_slave_t *slave, /**< EtherCAT slave */
       
  1255                       uint16_t sdo_index, /**< SDO index */
       
  1256                       uint8_t sdo_subindex, /**< SDO subindex */
       
  1257                       const uint8_t *data, /**< SDO data */
       
  1258                       size_t size /**< SDO size in bytes */
       
  1259                       )
       
  1260 {
       
  1261     ec_sdo_data_t *sdodata;
       
  1262 
       
  1263     if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
       
  1264         EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
       
  1265         return -1;
       
  1266     }
       
  1267 
       
  1268     if (!(sdodata = (ec_sdo_data_t *)
       
  1269           kmalloc(sizeof(ec_sdo_data_t), GFP_KERNEL))) {
       
  1270         EC_ERR("Failed to allocate memory for SDO configuration object!\n");
       
  1271         return -1;
       
  1272     }
       
  1273 
       
  1274     if (!(sdodata->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) {
       
  1275         EC_ERR("Failed to allocate memory for SDO configuration data!\n");
       
  1276         kfree(sdodata);
       
  1277         return -1;
       
  1278     }
       
  1279 
       
  1280     sdodata->index = sdo_index;
       
  1281     sdodata->subindex = sdo_subindex;
       
  1282     memcpy(sdodata->data, data, size);
       
  1283     sdodata->size = size;
       
  1284 
       
  1285     list_add_tail(&sdodata->list, &slave->sdo_confs);
       
  1286     return 0;
       
  1287 }
       
  1288 
       
  1289 /*****************************************************************************/
       
  1290 
       
  1291 /**
       
  1292    \return 0 in case of success, else < 0
       
  1293 */
       
  1294 
       
  1295 int ec_slave_validate(const ec_slave_t *slave, /**< EtherCAT slave */
  1145 int ec_slave_validate(const ec_slave_t *slave, /**< EtherCAT slave */
  1296                       uint32_t vendor_id, /**< vendor ID */
  1146                       uint32_t vendor_id, /**< vendor ID */
  1297                       uint32_t product_code /**< product code */
  1147                       uint32_t product_code /**< product code */
  1298                       )
  1148                       )
  1299 {
  1149 {
  1355     }
  1205     }
  1356 
  1206 
  1357     return NULL;
  1207     return NULL;
  1358 }
  1208 }
  1359 
  1209 
  1360 /******************************************************************************
  1210 /*****************************************************************************/
  1361  *  Realtime interface
       
  1362  *****************************************************************************/
       
  1363 
       
  1364 /**
       
  1365    \return 0 in case of success, else < 0
       
  1366    \ingroup RealtimeInterface
       
  1367 */
       
  1368 
       
  1369 int ecrt_slave_conf_sdo8(ec_slave_t *slave, /**< EtherCAT slave */
       
  1370                          uint16_t sdo_index, /**< SDO index */
       
  1371                          uint8_t sdo_subindex, /**< SDO subindex */
       
  1372                          uint8_t value /**< new SDO value */
       
  1373                          )
       
  1374 {
       
  1375     uint8_t data[1];
       
  1376     EC_WRITE_U8(data, value);
       
  1377     return ec_slave_conf_sdo(slave, sdo_index, sdo_subindex, data, 1);
       
  1378 }
       
  1379 
       
  1380 /*****************************************************************************/
       
  1381 
       
  1382 /**
       
  1383    \return 0 in case of success, else < 0
       
  1384    \ingroup RealtimeInterface
       
  1385 */
       
  1386 
       
  1387 int ecrt_slave_conf_sdo16(ec_slave_t *slave, /**< EtherCAT slave */
       
  1388                           uint16_t sdo_index, /**< SDO index */
       
  1389                           uint8_t sdo_subindex, /**< SDO subindex */
       
  1390                           uint16_t value /**< new SDO value */
       
  1391                           )
       
  1392 {
       
  1393     uint8_t data[2];
       
  1394     EC_WRITE_U16(data, value);
       
  1395     return ec_slave_conf_sdo(slave, sdo_index, sdo_subindex, data, 2);
       
  1396 }
       
  1397 
       
  1398 /*****************************************************************************/
       
  1399 
       
  1400 /**
       
  1401    \return 0 in case of success, else < 0
       
  1402    \ingroup RealtimeInterface
       
  1403 */
       
  1404 
       
  1405 int ecrt_slave_conf_sdo32(ec_slave_t *slave, /**< EtherCAT slave */
       
  1406                           uint16_t sdo_index, /**< SDO index */
       
  1407                           uint8_t sdo_subindex, /**< SDO subindex */
       
  1408                           uint32_t value /**< new SDO value */
       
  1409                           )
       
  1410 {
       
  1411     uint8_t data[4];
       
  1412     EC_WRITE_U32(data, value);
       
  1413     return ec_slave_conf_sdo(slave, sdo_index, sdo_subindex, data, 4);
       
  1414 }
       
  1415 
       
  1416 /*****************************************************************************/
       
  1417 
       
  1418 /**
       
  1419  * Clear slave's PDO mapping.
       
  1420  */
       
  1421 
       
  1422 void ecrt_slave_pdo_mapping_clear(
       
  1423         ec_slave_t *slave, /**< EtherCAT slave */
       
  1424         ec_direction_t dir /**< output/input */
       
  1425         )
       
  1426 {
       
  1427     ec_sync_t *sync;
       
  1428 
       
  1429     if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
       
  1430         EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
       
  1431         return;
       
  1432     }
       
  1433 
       
  1434     if (!(sync = ec_slave_get_pdo_sync(slave, dir)))
       
  1435         return;
       
  1436 
       
  1437     ec_sync_clear_pdos(sync);
       
  1438     sync->alt_mapping = 1;
       
  1439 }
       
  1440 
       
  1441 /*****************************************************************************/
       
  1442 
       
  1443 /**
       
  1444  * Add a PDO to the list of known mapped PDOs.
       
  1445  */
       
  1446 
       
  1447 int ecrt_slave_pdo_mapping_add(
       
  1448         ec_slave_t *slave, /**< EtherCAT slave */
       
  1449         ec_direction_t dir, /**< input/output */
       
  1450         uint16_t pdo_index /**< Index of mapped PDO */)
       
  1451 {
       
  1452     ec_pdo_t *pdo;
       
  1453     ec_sync_t *sync;
       
  1454     unsigned int not_found = 1;
       
  1455 
       
  1456     if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
       
  1457         EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
       
  1458         return -1;
       
  1459     }
       
  1460 
       
  1461     // does the slave provide the PDO? FIXME
       
  1462     list_for_each_entry(pdo, &slave->sii_pdos, list) {
       
  1463         if (pdo->index == pdo_index) {
       
  1464             not_found = 0;
       
  1465             break;
       
  1466         }
       
  1467     }
       
  1468 
       
  1469     if (not_found) {
       
  1470         EC_ERR("Slave %u does not provide PDO 0x%04X!\n",
       
  1471                 slave->ring_position, pdo_index);
       
  1472         return -1;
       
  1473     }
       
  1474 
       
  1475     // check direction
       
  1476     if ((pdo->type == EC_TX_PDO && dir == EC_DIR_OUTPUT) ||
       
  1477             (pdo->type == EC_RX_PDO && dir == EC_DIR_INPUT)) {
       
  1478         EC_ERR("Invalid direction for PDO 0x%04X.\n", pdo_index);
       
  1479         return -1;
       
  1480     }
       
  1481 
       
  1482 
       
  1483     if (!(sync = ec_slave_get_pdo_sync(slave, dir))) {
       
  1484         EC_ERR("Failed to obtain sync manager for PDO mapping of slave %u!\n",
       
  1485                 slave->ring_position);
       
  1486         return -1;
       
  1487     }
       
  1488 
       
  1489     if (ec_sync_add_pdo(sync, pdo))
       
  1490         return -1;
       
  1491 
       
  1492     sync->alt_mapping = 1;
       
  1493     return 0;
       
  1494 }
       
  1495 
       
  1496 /*****************************************************************************/
       
  1497 
       
  1498 /**
       
  1499  * Convenience function for ecrt_slave_pdo_mapping_clear() and
       
  1500  * ecrt_slave_pdo_mapping_add().
       
  1501  */
       
  1502 
       
  1503 int ecrt_slave_pdo_mapping(ec_slave_t *slave, /**< EtherCAT slave */
       
  1504         ec_direction_t dir, /**< input/output */
       
  1505         unsigned int num_args, /**< Number of following arguments */
       
  1506         ... /**< PDO indices to map */
       
  1507         )
       
  1508 {
       
  1509     va_list ap;
       
  1510 
       
  1511     ecrt_slave_pdo_mapping_clear(slave, dir);
       
  1512 
       
  1513     va_start(ap, num_args);
       
  1514 
       
  1515     for (; num_args; num_args--) {
       
  1516         if (ecrt_slave_pdo_mapping_add(
       
  1517                     slave, dir, (uint16_t) va_arg(ap, int))) {
       
  1518             return -1;
       
  1519         }
       
  1520     }
       
  1521 
       
  1522     va_end(ap);
       
  1523     return 0;
       
  1524 }
       
  1525 
       
  1526 
       
  1527 /*****************************************************************************/
       
  1528 
       
  1529 /** \cond */
       
  1530 
       
  1531 EXPORT_SYMBOL(ecrt_slave_conf_sdo8);
       
  1532 EXPORT_SYMBOL(ecrt_slave_conf_sdo16);
       
  1533 EXPORT_SYMBOL(ecrt_slave_conf_sdo32);
       
  1534 EXPORT_SYMBOL(ecrt_slave_pdo_mapping_clear);
       
  1535 EXPORT_SYMBOL(ecrt_slave_pdo_mapping_add);
       
  1536 EXPORT_SYMBOL(ecrt_slave_pdo_mapping);
       
  1537 
       
  1538 /** \endcond */
       
  1539 
       
  1540 /*****************************************************************************/