master/slave.c
branchstable-1.3
changeset 1746 72e7507b3f1b
parent 1744 7bc131b92039
child 1749 696dd9f22777
equal deleted inserted replaced
1745:07fd94c5119d 1746:72e7507b3f1b
   152     INIT_LIST_HEAD(&slave->sii_pdos);
   152     INIT_LIST_HEAD(&slave->sii_pdos);
   153     INIT_LIST_HEAD(&slave->sdo_dictionary);
   153     INIT_LIST_HEAD(&slave->sdo_dictionary);
   154     INIT_LIST_HEAD(&slave->sdo_confs);
   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->jiffies_preop = 0;
   158     slave->jiffies_preop = 0;
   158 
   159 
   159     for (i = 0; i < 4; i++) {
   160     for (i = 0; i < 4; i++) {
   160         slave->dl_link[i] = 0;
   161         slave->dl_link[i] = 0;
   161         slave->dl_loop[i] = 0;
   162         slave->dl_loop[i] = 0;
   279 }
   280 }
   280 
   281 
   281 /*****************************************************************************/
   282 /*****************************************************************************/
   282 
   283 
   283 /**
   284 /**
   284 */
   285  * SDO kobject clear method.
       
   286  */
   285 
   287 
   286 void ec_slave_sdos_clear(struct kobject *kobj /**< kobject for SDOs */)
   288 void ec_slave_sdos_clear(struct kobject *kobj /**< kobject for SDOs */)
   287 {
   289 {
   288 }
   290 }
   289 
   291 
   371 }
   373 }
   372 
   374 
   373 /*****************************************************************************/
   375 /*****************************************************************************/
   374 
   376 
   375 /**
   377 /**
       
   378  * Request a slave state and resets the error flag.
   376  */
   379  */
   377 
   380 
   378 void ec_slave_request_state(ec_slave_t *slave, /**< EtherCAT slave */
   381 void ec_slave_request_state(ec_slave_t *slave, /**< EtherCAT slave */
   379                             ec_slave_state_t state /**< new state */
   382                             ec_slave_state_t state /**< new state */
   380                             )
   383                             )
   385 
   388 
   386 /*****************************************************************************/
   389 /*****************************************************************************/
   387 
   390 
   388 /**
   391 /**
   389    Fetches data from a STRING category.
   392    Fetches data from a STRING category.
       
   393    \todo range checking
   390    \return 0 in case of success, else < 0
   394    \return 0 in case of success, else < 0
   391 */
   395 */
   392 
   396 
   393 int ec_slave_fetch_sii_strings(
   397 int ec_slave_fetch_sii_strings(
   394         ec_slave_t *slave, /**< EtherCAT slave */
   398         ec_slave_t *slave, /**< EtherCAT slave */
   395         const uint8_t *data /**< category data */
   399         const uint8_t *data, /**< category data */
       
   400         size_t data_size /**< number of bytes */
   396         )
   401         )
   397 {
   402 {
   398     int i;
   403     int i;
   399     size_t size;
   404     size_t size;
   400     off_t offset;
   405     off_t offset;
   441 /**
   446 /**
   442    Fetches data from a GENERAL category.
   447    Fetches data from a GENERAL category.
   443    \return 0 in case of success, else < 0
   448    \return 0 in case of success, else < 0
   444 */
   449 */
   445 
   450 
   446 void ec_slave_fetch_sii_general(
   451 int ec_slave_fetch_sii_general(
   447         ec_slave_t *slave, /**< EtherCAT slave */
   452         ec_slave_t *slave, /**< EtherCAT slave */
   448         const uint8_t *data /**< category data */
   453         const uint8_t *data, /**< category data */
       
   454         size_t data_size /**< size in bytes */
   449         )
   455         )
   450 {
   456 {
   451     unsigned int i;
   457     unsigned int i;
       
   458 
       
   459     if (data_size != 32) {
       
   460         EC_ERR("Wrong size of general category (%u/32) in slave %u.\n",
       
   461                 data_size, slave->ring_position);
       
   462         return -1;
       
   463     }
   452 
   464 
   453     slave->sii_group = ec_slave_sii_string(slave, data[0]);
   465     slave->sii_group = ec_slave_sii_string(slave, data[0]);
   454     slave->sii_image = ec_slave_sii_string(slave, data[1]);
   466     slave->sii_image = ec_slave_sii_string(slave, data[1]);
   455     slave->sii_order = ec_slave_sii_string(slave, data[2]);
   467     slave->sii_order = ec_slave_sii_string(slave, data[2]);
   456     slave->sii_name = ec_slave_sii_string(slave, data[3]);
   468     slave->sii_name = ec_slave_sii_string(slave, data[3]);
   458     for (i = 0; i < 4; i++)
   470     for (i = 0; i < 4; i++)
   459         slave->sii_physical_layer[i] =
   471         slave->sii_physical_layer[i] =
   460             (data[4] & (0x03 << (i * 2))) >> (i * 2);
   472             (data[4] & (0x03 << (i * 2))) >> (i * 2);
   461 
   473 
   462     slave->sii_current_on_ebus = EC_READ_S16(data + 0x0C);
   474     slave->sii_current_on_ebus = EC_READ_S16(data + 0x0C);
       
   475 
       
   476     return 0;
   463 }
   477 }
   464 
   478 
   465 /*****************************************************************************/
   479 /*****************************************************************************/
   466 
   480 
   467 /**
   481 /**
   470 */
   484 */
   471 
   485 
   472 int ec_slave_fetch_sii_syncs(
   486 int ec_slave_fetch_sii_syncs(
   473         ec_slave_t *slave, /**< EtherCAT slave */
   487         ec_slave_t *slave, /**< EtherCAT slave */
   474         const uint8_t *data, /**< category data */
   488         const uint8_t *data, /**< category data */
   475         size_t word_count /**< number of words */
   489         size_t data_size /**< number of bytes */
   476         )
   490         )
   477 {
   491 {
   478     unsigned int i;
   492     unsigned int i;
   479     ec_sync_t *sync;
   493     ec_sync_t *sync;
   480 
   494     size_t memsize;
   481     // sync manager struct is 4 words long
   495 
   482     slave->sii_sync_count = word_count / 4;
   496     // one sync manager struct is 4 words long
   483 
   497     if (data_size % 8) {
   484     if (!(slave->sii_syncs =
   498         EC_ERR("Invalid SII sync manager size %u in slave %u.\n",
   485                 kmalloc(sizeof(ec_sync_t) * slave->sii_sync_count,
   499                 data_size, slave->ring_position);
   486                     GFP_KERNEL))) {
   500         return -1;
   487         EC_ERR("Failed to allocate memory for sync managers.\n");
   501     }
       
   502 
       
   503     slave->sii_sync_count = data_size / 8;
       
   504 
       
   505     memsize = sizeof(ec_sync_t) * slave->sii_sync_count;
       
   506     if (!(slave->sii_syncs = kmalloc(memsize, GFP_KERNEL))) {
       
   507         EC_ERR("Failed to allocate %u bytes for sync managers.\n",
       
   508                 memsize);
   488         slave->sii_sync_count = 0;
   509         slave->sii_sync_count = 0;
   489         return -1;
   510         return -1;
   490     }
   511     }
   491     
   512     
   492     for (i = 0; i < slave->sii_sync_count; i++, data += 8) {
   513     for (i = 0; i < slave->sii_sync_count; i++, data += 8) {
   510 */
   531 */
   511 
   532 
   512 int ec_slave_fetch_sii_pdos(
   533 int ec_slave_fetch_sii_pdos(
   513         ec_slave_t *slave, /**< EtherCAT slave */
   534         ec_slave_t *slave, /**< EtherCAT slave */
   514         const uint8_t *data, /**< category data */
   535         const uint8_t *data, /**< category data */
   515         size_t word_count, /**< number of words */
   536         size_t data_size, /**< number of bytes */
   516         ec_pdo_type_t pdo_type /**< PDO type */
   537         ec_pdo_type_t pdo_type /**< PDO type */
   517         )
   538         )
   518 {
   539 {
   519     ec_pdo_t *pdo;
   540     ec_pdo_t *pdo;
   520     ec_pdo_entry_t *entry;
   541     ec_pdo_entry_t *entry;
   521     unsigned int entry_count, i;
   542     unsigned int entry_count, i;
   522 
   543 
   523     while (word_count >= 4) {
   544     while (data_size >= 8) {
   524         if (!(pdo = kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
   545         if (!(pdo = kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
   525             EC_ERR("Failed to allocate PDO memory.\n");
   546             EC_ERR("Failed to allocate PDO memory.\n");
   526             return -1;
   547             return -1;
   527         }
   548         }
   528 
   549 
   532         entry_count = EC_READ_U8(data + 2);
   553         entry_count = EC_READ_U8(data + 2);
   533         pdo->sync_index = EC_READ_U8(data + 3);
   554         pdo->sync_index = EC_READ_U8(data + 3);
   534         pdo->name = ec_slave_sii_string(slave, EC_READ_U8(data + 5));
   555         pdo->name = ec_slave_sii_string(slave, EC_READ_U8(data + 5));
   535         list_add_tail(&pdo->list, &slave->sii_pdos);
   556         list_add_tail(&pdo->list, &slave->sii_pdos);
   536 
   557 
   537         word_count -= 4;
   558         data_size -= 8;
   538         data += 8;
   559         data += 8;
   539 
   560 
   540         for (i = 0; i < entry_count; i++) {
   561         for (i = 0; i < entry_count; i++) {
   541             if (!(entry = kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
   562             if (!(entry = kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
   542                 EC_ERR("Failed to allocate PDO entry memory.\n");
   563                 EC_ERR("Failed to allocate PDO entry memory.\n");
   547             entry->subindex = EC_READ_U8(data + 2);
   568             entry->subindex = EC_READ_U8(data + 2);
   548             entry->name = ec_slave_sii_string(slave, EC_READ_U8(data + 3));
   569             entry->name = ec_slave_sii_string(slave, EC_READ_U8(data + 3));
   549             entry->bit_length = EC_READ_U8(data + 5);
   570             entry->bit_length = EC_READ_U8(data + 5);
   550             list_add_tail(&entry->list, &pdo->entries);
   571             list_add_tail(&entry->list, &pdo->entries);
   551 
   572 
   552             word_count -= 4;
   573             data_size -= 8;
   553             data += 8;
   574             data += 8;
   554         }
   575         }
   555 
   576 
   556         // if sync manager index is positive, the PDO is mapped by default
   577         // if sync manager index is positive, the PDO is mapped by default
   557         if (pdo->sync_index >= 0) {
   578         if (pdo->sync_index >= 0) {
   792         if (list_empty(&sync->pdos))
   813         if (list_empty(&sync->pdos))
   793             off += sprintf(buffer + off, "    No PDOs mapped.\n");
   814             off += sprintf(buffer + off, "    No PDOs mapped.\n");
   794 
   815 
   795         list_for_each_entry(pdo, &sync->pdos, list) {
   816         list_for_each_entry(pdo, &sync->pdos, list) {
   796             off += sprintf(buffer + off, "    %s 0x%04X \"%s\"\n",
   817             off += sprintf(buffer + off, "    %s 0x%04X \"%s\"\n",
   797                     pdo->type == EC_RX_PDO ? "RXPDO" : "TXPDO",
   818                     pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
   798                     pdo->index, pdo->name ? pdo->name : "???");
   819                     pdo->index, pdo->name ? pdo->name : "???");
   799 
   820 
   800             list_for_each_entry(pdo_entry, &pdo->entries, list) {
   821             list_for_each_entry(pdo_entry, &pdo->entries, list) {
   801                 off += sprintf(buffer + off,
   822                 off += sprintf(buffer + off,
   802                         "      0x%04X:%X \"%s\", %i bit\n",
   823                         "      0x%04X:%X \"%s\", %i bit\n",
   805                         pdo_entry->bit_length);
   826                         pdo_entry->bit_length);
   806             }
   827             }
   807         }
   828         }
   808     }
   829     }
   809 
   830 
   810     if (!list_empty(&slave->sii_pdos))
   831     // type-cast to avoid warnings on some compilers
       
   832     if (!list_empty((struct list_head *) &slave->sii_pdos))
   811         off += sprintf(buffer + off, "\nAvailable PDOs:\n");
   833         off += sprintf(buffer + off, "\nAvailable PDOs:\n");
   812 
   834 
   813     list_for_each_entry(pdo, &slave->sii_pdos, list) {
   835     list_for_each_entry(pdo, &slave->sii_pdos, list) {
   814         off += sprintf(buffer + off, "  %s 0x%04X \"%s\"",
   836         off += sprintf(buffer + off, "  %s 0x%04X \"%s\"",
   815                        pdo->type == EC_RX_PDO ? "RXPDO" : "TXPDO",
   837                        pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
   816                        pdo->index, pdo->name ? pdo->name : "???");
   838                        pdo->index, pdo->name ? pdo->name : "???");
   817         if (pdo->sync_index >= 0)
   839         if (pdo->sync_index >= 0)
   818             off += sprintf(buffer + off, ", default mapping: SM%u.\n",
   840             off += sprintf(buffer + off, ", default mapping: SM%u.\n",
   819                     pdo->sync_index);
   841                     pdo->sync_index);
   820         else
   842         else
   826                            pdo_entry->name ? pdo_entry->name : "???",
   848                            pdo_entry->name ? pdo_entry->name : "???",
   827                            pdo_entry->bit_length);
   849                            pdo_entry->bit_length);
   828         }
   850         }
   829     }
   851     }
   830 
   852 
   831     if (!list_empty(&slave->sdo_confs))
   853     // type-cast to avoid warnings on some compilers
       
   854     if (!list_empty((struct list_head *) &slave->sdo_confs))
   832         off += sprintf(buffer + off, "\nSDO configurations:\n");
   855         off += sprintf(buffer + off, "\nSDO configurations:\n");
   833 
   856 
   834     list_for_each_entry(sdodata, &slave->sdo_confs, list) {
   857     list_for_each_entry(sdodata, &slave->sdo_confs, list) {
   835         switch (sdodata->size) {
   858         switch (sdodata->size) {
   836             case 1: sprintf(str, "%i", EC_READ_U8(sdodata->data)); break;
   859             case 1: sprintf(str, "%i", EC_READ_U8(sdodata->data)); break;
   852 /**
   875 /**
   853  * Schedules an EEPROM write request.
   876  * Schedules an EEPROM write request.
   854  * \return 0 case of success, otherwise error code.
   877  * \return 0 case of success, otherwise error code.
   855  */
   878  */
   856 
   879 
   857 int ec_slave_schedule_eeprom_writing(ec_eeprom_write_request_t *request)
   880 int ec_slave_schedule_eeprom_writing(
       
   881         ec_eeprom_write_request_t *request /**< EEPROM write request */
       
   882         )
   858 {
   883 {
   859     ec_master_t *master = request->slave->master;
   884     ec_master_t *master = request->slave->master;
   860 
   885 
   861     request->state = EC_REQUEST_QUEUED;
   886     request->state = EC_REQUEST_QUEUED;
   862 
   887 
   887 }
   912 }
   888 
   913 
   889 /*****************************************************************************/
   914 /*****************************************************************************/
   890 
   915 
   891 /**
   916 /**
       
   917  * Calculates the EEPROM checksum field.
       
   918  *
       
   919  * The checksum is generated with the polynom x^8+x^2+x+1 (0x07) and an
       
   920  * initial value of 0xff (see IEC 61158-6-12 ch. 5.4).
       
   921  *
       
   922  * The below code was originally generated with PYCRC
       
   923  * http://www.tty1.net/pycrc
       
   924  *
       
   925  * ./pycrc.py --width=8 --poly=0x07 --reflect-in=0 --xor-in=0xff
       
   926  *   --reflect-out=0 --xor-out=0 --generate c --algorithm=bit-by-bit
       
   927  *
       
   928  * \return CRC8
       
   929  */
       
   930 
       
   931 uint8_t ec_slave_eeprom_crc(
       
   932         const uint8_t *data, /**< pointer to data */
       
   933         size_t length /**< number of bytes in \a data */
       
   934         )
       
   935 {
       
   936     unsigned int i;
       
   937     uint8_t bit, byte, crc = 0x48;
       
   938 
       
   939     while (length--) {
       
   940         byte = *data++;
       
   941         for (i = 0; i < 8; i++) {
       
   942             bit = crc & 0x80;
       
   943             crc = (crc << 1) | ((byte >> (7 - i)) & 0x01);
       
   944             if (bit) crc ^= 0x07;
       
   945         }
       
   946     }
       
   947 
       
   948     for (i = 0; i < 8; i++) {
       
   949         bit = crc & 0x80;
       
   950         crc <<= 1;
       
   951         if (bit) crc ^= 0x07;
       
   952     }
       
   953 
       
   954     return crc;
       
   955 }
       
   956 
       
   957 /*****************************************************************************/
       
   958 
       
   959 /**
   892  * Writes complete EEPROM contents to a slave.
   960  * Writes complete EEPROM contents to a slave.
   893  * \return data size written in case of success, otherwise error code.
   961  * \return data size written in case of success, otherwise error code.
   894  */
   962  */
   895 
   963 
   896 ssize_t ec_slave_write_eeprom(ec_slave_t *slave, /**< EtherCAT slave */
   964 ssize_t ec_slave_write_eeprom(ec_slave_t *slave, /**< EtherCAT slave */
   900 {
   968 {
   901     ec_eeprom_write_request_t request;
   969     ec_eeprom_write_request_t request;
   902     const uint16_t *cat_header;
   970     const uint16_t *cat_header;
   903     uint16_t cat_type, cat_size;
   971     uint16_t cat_type, cat_size;
   904     int ret;
   972     int ret;
       
   973     uint8_t crc;
   905 
   974 
   906     if (slave->master->mode != EC_MASTER_MODE_IDLE) { // FIXME
   975     if (slave->master->mode != EC_MASTER_MODE_IDLE) { // FIXME
   907         EC_ERR("Writing EEPROMs only allowed in idle mode!\n");
   976         EC_ERR("Writing EEPROMs only allowed in idle mode!\n");
   908         return -EBUSY;
   977         return -EBUSY;
   909     }
   978     }
   914     }
   983     }
   915 
   984 
   916     // init EEPROM write request
   985     // init EEPROM write request
   917     INIT_LIST_HEAD(&request.list);
   986     INIT_LIST_HEAD(&request.list);
   918     request.slave = slave;
   987     request.slave = slave;
   919     request.words = (const uint16_t *) data;
   988     request.data = data;
   920     request.offset = 0;
   989     request.word_offset = 0;
   921     request.size = size / 2;
   990     request.word_size = size / 2;
   922 
   991 
   923     if (request.size < 0x0041) {
   992     if (request.word_size < 0x0041) {
   924         EC_ERR("EEPROM data too short! Dropping.\n");
   993         EC_ERR("EEPROM data too short! Dropping.\n");
   925         return -EINVAL;
   994         return -EINVAL;
   926     }
   995     }
   927 
   996 
   928     cat_header = request.words + EC_FIRST_EEPROM_CATEGORY_OFFSET;
   997     // calculate checksum
       
   998     crc = ec_slave_eeprom_crc(data, 14); // CRC over words 0 to 6
       
   999     if (crc != data[14]) {
       
  1000         EC_WARN("EEPROM CRC incorrect. Must be 0x%02x.\n", crc);
       
  1001     }
       
  1002 
       
  1003     cat_header = (const uint16_t *) request.data
       
  1004 		+ EC_FIRST_EEPROM_CATEGORY_OFFSET;
   929     cat_type = EC_READ_U16(cat_header);
  1005     cat_type = EC_READ_U16(cat_header);
   930     while (cat_type != 0xFFFF) { // cycle through categories
  1006     while (cat_type != 0xFFFF) { // cycle through categories
   931         if (cat_header + 1 > request.words + request.size) {
  1007         if (cat_header + 1 >
       
  1008 				(const uint16_t *) request.data + request.word_size) {
   932             EC_ERR("EEPROM data corrupted! Dropping.\n");
  1009             EC_ERR("EEPROM data corrupted! Dropping.\n");
   933             return -EINVAL;
  1010             return -EINVAL;
   934         }
  1011         }
   935         cat_size = EC_READ_U16(cat_header + 1);
  1012         cat_size = EC_READ_U16(cat_header + 1);
   936         if (cat_header + cat_size + 2 > request.words + request.size) {
  1013         if (cat_header + cat_size + 2 >
       
  1014 				(const uint16_t *) request.data + request.word_size) {
   937             EC_ERR("EEPROM data corrupted! Dropping.\n");
  1015             EC_ERR("EEPROM data corrupted! Dropping.\n");
   938             return -EINVAL;
  1016             return -EINVAL;
   939         }
  1017         }
   940         cat_header += cat_size + 2;
  1018         cat_header += cat_size + 2;
   941         cat_type = EC_READ_U16(cat_header);
  1019         cat_type = EC_READ_U16(cat_header);
   960         size_t size /**< size of data in bytes */
  1038         size_t size /**< size of data in bytes */
   961         )
  1039         )
   962 {
  1040 {
   963     ec_eeprom_write_request_t request;
  1041     ec_eeprom_write_request_t request;
   964     char *remainder;
  1042     char *remainder;
   965     uint16_t alias, word;
  1043     uint16_t alias;
   966     int ret;
  1044     int ret;
       
  1045     uint8_t eeprom_data[16], crc;
   967 
  1046 
   968     if (slave->master->mode != EC_MASTER_MODE_IDLE) { // FIXME
  1047     if (slave->master->mode != EC_MASTER_MODE_IDLE) { // FIXME
   969         EC_ERR("Writing EEPROMs only allowed in idle mode!\n");
  1048         EC_ERR("Writing to EEPROM is only allowed in idle mode!\n");
   970         return -EBUSY;
  1049         return -EBUSY;
   971     }
  1050     }
   972 
  1051 
   973     alias = simple_strtoul(data, &remainder, 0);
  1052     alias = simple_strtoul(data, &remainder, 0);
   974     if (remainder == (char *) data || (*remainder && *remainder != '\n')) {
  1053     if (remainder == (char *) data || (*remainder && *remainder != '\n')) {
   975         EC_ERR("Invalid alias value! Dropping.\n");
  1054         EC_ERR("Invalid alias value! Dropping.\n");
   976         return -EINVAL;
  1055         return -EINVAL;
   977     }
  1056     }
       
  1057 
       
  1058     if (!slave->eeprom_data || slave->eeprom_size < 16) {
       
  1059         EC_ERR("Failed to read EEPROM contents from slave %u.\n",
       
  1060                 slave->ring_position);
       
  1061         return -EINVAL;
       
  1062     }
       
  1063 
       
  1064     // copy first 7 words of recent EEPROM contents
       
  1065     memcpy(eeprom_data, slave->eeprom_data, 14);
   978     
  1066     
   979     // correct endianess
  1067     // write new alias address in word 4
   980     EC_WRITE_U16(&word, alias);
  1068     EC_WRITE_U16(eeprom_data + 8, alias);
       
  1069 
       
  1070     // calculate new checksum over words 0 to 6
       
  1071     crc = ec_slave_eeprom_crc(eeprom_data, 14);
       
  1072     EC_WRITE_U16(eeprom_data + 14, crc);
   981 
  1073 
   982     // init EEPROM write request
  1074     // init EEPROM write request
   983     INIT_LIST_HEAD(&request.list);
  1075     INIT_LIST_HEAD(&request.list);
   984     request.slave = slave;
  1076     request.slave = slave;
   985     request.words = &word;
  1077     request.data = eeprom_data;
   986     request.offset = 0x0004;
  1078     request.word_offset = 0x0000;
   987     request.size = 1;
  1079     request.word_size = 8;
   988 
  1080 
   989     if ((ret = ec_slave_schedule_eeprom_writing(&request)))
  1081     if ((ret = ec_slave_schedule_eeprom_writing(&request)))
   990         return ret; // error code
  1082         return ret; // error code
   991 
  1083 
   992     slave->sii_alias = alias; // FIXME: do this in state machine
  1084     slave->sii_alias = alias; // FIXME: do this in state machine
  1092 }
  1184 }
  1093 
  1185 
  1094 /*****************************************************************************/
  1186 /*****************************************************************************/
  1095 
  1187 
  1096 /**
  1188 /**
       
  1189  * Get the sync manager for either Rx- or Tx-PDOs.
       
  1190  * \return pointer to sync manager, or NULL.
  1097  */
  1191  */
  1098 
  1192 
  1099 ec_sync_t *ec_slave_get_pdo_sync(
  1193 ec_sync_t *ec_slave_get_pdo_sync(
  1100         ec_slave_t *slave, /**< EtherCAT slave */
  1194         ec_slave_t *slave, /**< EtherCAT slave */
  1101         ec_direction_t dir /**< input or output */
  1195         ec_direction_t dir /**< input or output */
  1205 
  1299 
  1206     *sdo_count = sdos;
  1300     *sdo_count = sdos;
  1207     *entry_count = entries;
  1301     *entry_count = entries;
  1208 }
  1302 }
  1209 
  1303 
       
  1304 /*****************************************************************************/
       
  1305 
       
  1306 /**
       
  1307  * Get an SDO from the dictionary.
       
  1308  * \returns The desired SDO, of NULL.
       
  1309  */
       
  1310 
       
  1311 ec_sdo_t *ec_slave_get_sdo(
       
  1312         ec_slave_t *slave /**< EtherCAT slave */,
       
  1313         uint16_t index /**< SDO index */
       
  1314         )
       
  1315 {
       
  1316     ec_sdo_t *sdo;
       
  1317 
       
  1318     list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
       
  1319         if (sdo->index != index) continue;
       
  1320         return sdo;
       
  1321     }
       
  1322 
       
  1323     return NULL;
       
  1324 }
       
  1325 
  1210 /******************************************************************************
  1326 /******************************************************************************
  1211  *  Realtime interface
  1327  *  Realtime interface
  1212  *****************************************************************************/
  1328  *****************************************************************************/
  1213 
  1329 
  1214 /**
  1330 /**
  1263     return ec_slave_conf_sdo(slave, sdo_index, sdo_subindex, data, 4);
  1379     return ec_slave_conf_sdo(slave, sdo_index, sdo_subindex, data, 4);
  1264 }
  1380 }
  1265 
  1381 
  1266 /*****************************************************************************/
  1382 /*****************************************************************************/
  1267 
  1383 
       
  1384 /**
       
  1385  * Clear slave's PDO mapping.
       
  1386  */
       
  1387 
  1268 void ecrt_slave_pdo_mapping_clear(
  1388 void ecrt_slave_pdo_mapping_clear(
  1269         ec_slave_t *slave, /**< EtherCAT slave */
  1389         ec_slave_t *slave, /**< EtherCAT slave */
  1270         ec_direction_t dir /**< output/input */
  1390         ec_direction_t dir /**< output/input */
  1271         )
  1391         )
  1272 {
  1392 {
  1279 
  1399 
  1280     if (!(sync = ec_slave_get_pdo_sync(slave, dir)))
  1400     if (!(sync = ec_slave_get_pdo_sync(slave, dir)))
  1281         return;
  1401         return;
  1282 
  1402 
  1283     ec_sync_clear_pdos(sync);
  1403     ec_sync_clear_pdos(sync);
  1284 }
  1404     sync->alt_mapping = 1;
  1285 
  1405 }
  1286 /*****************************************************************************/
  1406 
       
  1407 /*****************************************************************************/
       
  1408 
       
  1409 /**
       
  1410  * Add a PDO to the list of known mapped PDOs.
       
  1411  */
  1287 
  1412 
  1288 int ecrt_slave_pdo_mapping_add(
  1413 int ecrt_slave_pdo_mapping_add(
  1289         ec_slave_t *slave, /**< EtherCAT slave */
  1414         ec_slave_t *slave, /**< EtherCAT slave */
  1290         ec_direction_t dir, /**< input/output */
  1415         ec_direction_t dir, /**< input/output */
  1291         uint16_t pdo_index /**< Index of PDO mapping list */)
  1416         uint16_t pdo_index /**< Index of mapped PDO */)
  1292 {
  1417 {
  1293     ec_pdo_t *pdo;
  1418     ec_pdo_t *pdo;
  1294     ec_sync_t *sync;
  1419     ec_sync_t *sync;
  1295     unsigned int not_found = 1;
  1420     unsigned int not_found = 1;
  1296 
  1421 
  1297     if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
  1422     if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) {
  1298         EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
  1423         EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
  1299         return -1;
  1424         return -1;
  1300     }
  1425     }
  1301 
  1426 
  1302     // does the slave provide the PDO list?
  1427     // does the slave provide the PDO?
  1303     list_for_each_entry(pdo, &slave->sii_pdos, list) {
  1428     list_for_each_entry(pdo, &slave->sii_pdos, list) {
  1304         if (pdo->index == pdo_index) {
  1429         if (pdo->index == pdo_index) {
  1305             not_found = 0;
  1430             not_found = 0;
  1306             break;
  1431             break;
  1307         }
  1432         }
  1325         EC_ERR("Failed to obtain sync manager for PDO mapping of slave %u!\n",
  1450         EC_ERR("Failed to obtain sync manager for PDO mapping of slave %u!\n",
  1326                 slave->ring_position);
  1451                 slave->ring_position);
  1327         return -1;
  1452         return -1;
  1328     }
  1453     }
  1329 
  1454 
  1330     return ec_sync_add_pdo(sync, pdo);
  1455     if (ec_sync_add_pdo(sync, pdo))
  1331 }
  1456         return -1;
  1332 
  1457 
  1333 /*****************************************************************************/
  1458     sync->alt_mapping = 1;
       
  1459     return 0;
       
  1460 }
       
  1461 
       
  1462 /*****************************************************************************/
       
  1463 
       
  1464 /**
       
  1465  * Convenience function for ecrt_slave_pdo_mapping_clear() and
       
  1466  * ecrt_slave_pdo_mapping_add().
       
  1467  */
  1334 
  1468 
  1335 int ecrt_slave_pdo_mapping(ec_slave_t *slave, /**< EtherCAT slave */
  1469 int ecrt_slave_pdo_mapping(ec_slave_t *slave, /**< EtherCAT slave */
  1336         ec_direction_t dir, /**< input/output */
  1470         ec_direction_t dir, /**< input/output */
  1337         unsigned int num_args, /**< Number of following arguments */
  1471         unsigned int num_args, /**< Number of following arguments */
  1338         ... /**< PDO indices to map */
  1472         ... /**< PDO indices to map */