master/canopen.c
branchstable-1.0
changeset 1621 4bbe090553f7
parent 1619 0d4119024f55
child 1623 05622513f627
equal deleted inserted replaced
1620:9d7453c16ade 1621:4bbe090553f7
    46 #include "mailbox.h"
    46 #include "mailbox.h"
    47 
    47 
    48 /*****************************************************************************/
    48 /*****************************************************************************/
    49 
    49 
    50 void ec_canopen_abort_msg(uint32_t);
    50 void ec_canopen_abort_msg(uint32_t);
    51 int ec_slave_fetch_sdo_descriptions(ec_slave_t *);
    51 int ec_slave_fetch_sdo_descriptions(ec_slave_t *, ec_command_t *);
    52 int ec_slave_fetch_sdo_entries(ec_slave_t *, ec_sdo_t *, uint8_t);
    52 int ec_slave_fetch_sdo_entries(ec_slave_t *, ec_command_t *,
       
    53                                ec_sdo_t *, uint8_t);
    53 
    54 
    54 /*****************************************************************************/
    55 /*****************************************************************************/
    55 
    56 
    56 const ec_code_msg_t sdo_abort_messages[];
    57 const ec_code_msg_t sdo_abort_messages[];
    57 
    58 
    66                           uint16_t sdo_index, /**< SDO index */
    67                           uint16_t sdo_index, /**< SDO index */
    67                           uint8_t sdo_subindex, /**< SDO subindex */
    68                           uint8_t sdo_subindex, /**< SDO subindex */
    68                           uint8_t *target /**< 4-byte memory */
    69                           uint8_t *target /**< 4-byte memory */
    69                           )
    70                           )
    70 {
    71 {
       
    72     ec_command_t command;
    71     size_t rec_size;
    73     size_t rec_size;
    72     uint8_t *data;
    74     uint8_t *data;
    73 
    75 
    74     if (!(data = ec_slave_mbox_prepare_send(slave, 0x03, 6))) return -1;
    76     ec_command_init(&command);
       
    77 
       
    78     if (!(data = ec_slave_mbox_prepare_send(slave, &command, 0x03, 6)))
       
    79         goto err;
    75 
    80 
    76     EC_WRITE_U16(data, 0x2 << 12); // SDO request
    81     EC_WRITE_U16(data, 0x2 << 12); // SDO request
    77     EC_WRITE_U8 (data + 2, (0x1 << 1 // expedited transfer
    82     EC_WRITE_U8 (data + 2, (0x1 << 1 // expedited transfer
    78                             | 0x2 << 5)); // initiate upload request
    83                             | 0x2 << 5)); // initiate upload request
    79     EC_WRITE_U16(data + 3, sdo_index);
    84     EC_WRITE_U16(data + 3, sdo_index);
    80     EC_WRITE_U8 (data + 5, sdo_subindex);
    85     EC_WRITE_U8 (data + 5, sdo_subindex);
    81 
    86 
    82     if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1;
    87     if (!(data = ec_slave_mbox_simple_io(slave, &command, &rec_size)))
       
    88         goto err;
    83 
    89 
    84     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
    90     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
    85         EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
    91         EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
    86         EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
    92         EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
    87                sdo_index, sdo_subindex, slave->ring_position);
    93                sdo_index, sdo_subindex, slave->ring_position);
    88         ec_canopen_abort_msg(EC_READ_U32(data + 6));
    94         ec_canopen_abort_msg(EC_READ_U32(data + 6));
    89         return -1;
    95         goto err;
    90     }
    96     }
    91 
    97 
    92     if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
    98     if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
    93         EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response
    99         EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response
    94         EC_READ_U16(data + 3) != sdo_index || // index
   100         EC_READ_U16(data + 3) != sdo_index || // index
    95         EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
   101         EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
    96         EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex);
   102         EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex);
    97         EC_ERR("Invalid SDO upload response at slave %i!\n",
   103         EC_ERR("Invalid SDO upload response at slave %i!\n",
    98                slave->ring_position);
   104                slave->ring_position);
    99         ec_print_data(data, rec_size);
   105         ec_print_data(data, rec_size);
   100         return -1;
   106         goto err;
   101     }
   107     }
   102 
   108 
   103     memcpy(target, data + 6, 4);
   109     memcpy(target, data + 6, 4);
   104     return 0;
   110 
       
   111     ec_command_clear(&command);
       
   112     return 0;
       
   113  err:
       
   114     ec_command_clear(&command);
       
   115     return -1;
   105 }
   116 }
   106 
   117 
   107 /*****************************************************************************/
   118 /*****************************************************************************/
   108 
   119 
   109 /**
   120 /**
   118                            size_t size /**< Data size in bytes (1 - 4) */
   129                            size_t size /**< Data size in bytes (1 - 4) */
   119                            )
   130                            )
   120 {
   131 {
   121     uint8_t *data;
   132     uint8_t *data;
   122     size_t rec_size;
   133     size_t rec_size;
       
   134     ec_command_t command;
       
   135 
       
   136     ec_command_init(&command);
   123 
   137 
   124     if (size == 0 || size > 4) {
   138     if (size == 0 || size > 4) {
   125         EC_ERR("Invalid data size!\n");
   139         EC_ERR("Invalid data size!\n");
   126         return -1;
   140         goto err;
   127     }
   141     }
   128 
   142 
   129     if (!(data = ec_slave_mbox_prepare_send(slave, 0x03, 0x0A))) return -1;
   143     if (!(data = ec_slave_mbox_prepare_send(slave, &command, 0x03, 0x0A)))
       
   144         goto err;
   130 
   145 
   131     EC_WRITE_U16(data, 0x2 << 12); // SDO request
   146     EC_WRITE_U16(data, 0x2 << 12); // SDO request
   132     EC_WRITE_U8 (data + 2, (0x1 // size specified
   147     EC_WRITE_U8 (data + 2, (0x1 // size specified
   133                             | 0x1 << 1 // expedited transfer
   148                             | 0x1 << 1 // expedited transfer
   134                             | (4 - size) << 2 // data set size
   149                             | (4 - size) << 2 // data set size
   136     EC_WRITE_U16(data + 3, sdo_index);
   151     EC_WRITE_U16(data + 3, sdo_index);
   137     EC_WRITE_U8 (data + 5, sdo_subindex);
   152     EC_WRITE_U8 (data + 5, sdo_subindex);
   138     memcpy(data + 6, sdo_data, size);
   153     memcpy(data + 6, sdo_data, size);
   139     if (size < 4) memset(data + 6 + size, 0x00, 4 - size);
   154     if (size < 4) memset(data + 6 + size, 0x00, 4 - size);
   140 
   155 
   141     if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1;
   156     if (!(data = ec_slave_mbox_simple_io(slave, &command, &rec_size)))
       
   157         goto err;
   142 
   158 
   143     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
   159     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
   144         EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
   160         EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
   145         EC_ERR("SDO download 0x%04X:%X (%i bytes) aborted on slave %i.\n",
   161         EC_ERR("SDO download 0x%04X:%X (%i bytes) aborted on slave %i.\n",
   146                sdo_index, sdo_subindex, size, slave->ring_position);
   162                sdo_index, sdo_subindex, size, slave->ring_position);
   158                slave->ring_position);
   174                slave->ring_position);
   159         ec_print_data(data, rec_size);
   175         ec_print_data(data, rec_size);
   160         return -1;
   176         return -1;
   161     }
   177     }
   162 
   178 
   163     return 0;
   179     ec_command_clear(&command);
       
   180     return 0;
       
   181  err:
       
   182     ec_command_clear(&command);
       
   183     return -1;
   164 }
   184 }
   165 
   185 
   166 /*****************************************************************************/
   186 /*****************************************************************************/
   167 
   187 
   168 /**
   188 /**
   180                         )
   200                         )
   181 {
   201 {
   182     uint8_t *data;
   202     uint8_t *data;
   183     size_t rec_size, data_size;
   203     size_t rec_size, data_size;
   184     uint32_t complete_size;
   204     uint32_t complete_size;
   185 
   205     ec_command_t command;
   186     if (!(data = ec_slave_mbox_prepare_send(slave, 0x03, 6))) return -1;
   206 
       
   207     ec_command_init(&command);
       
   208 
       
   209     if (!(data = ec_slave_mbox_prepare_send(slave, &command, 0x03, 6)))
       
   210         goto err;
   187 
   211 
   188     EC_WRITE_U16(data, 0x2 << 12); // SDO request
   212     EC_WRITE_U16(data, 0x2 << 12); // SDO request
   189     EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
   213     EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
   190     EC_WRITE_U16(data + 3, sdo_index);
   214     EC_WRITE_U16(data + 3, sdo_index);
   191     EC_WRITE_U8 (data + 5, sdo_subindex);
   215     EC_WRITE_U8 (data + 5, sdo_subindex);
   192 
   216 
   193     if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1;
   217     if (!(data = ec_slave_mbox_simple_io(slave, &command, &rec_size)))
       
   218         goto err;
   194 
   219 
   195     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
   220     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
   196         EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
   221         EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
   197         EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
   222         EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
   198                sdo_index, sdo_subindex, slave->ring_position);
   223                sdo_index, sdo_subindex, slave->ring_position);
   199         ec_canopen_abort_msg(EC_READ_U32(data + 6));
   224         ec_canopen_abort_msg(EC_READ_U32(data + 6));
   200         return -1;
   225         goto err;
   201     }
   226     }
   202 
   227 
   203     if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
   228     if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
   204         EC_READ_U8 (data + 2) >> 5 != 0x2 || // initiate upload response
   229         EC_READ_U8 (data + 2) >> 5 != 0x2 || // initiate upload response
   205         EC_READ_U16(data + 3) != sdo_index || // index
   230         EC_READ_U16(data + 3) != sdo_index || // index
   206         EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
   231         EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
   207         EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex);
   232         EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex);
   208         EC_ERR("Invalid SDO upload response at slave %i!\n",
   233         EC_ERR("Invalid SDO upload response at slave %i!\n",
   209                slave->ring_position);
   234                slave->ring_position);
   210         ec_print_data(data, rec_size);
   235         ec_print_data(data, rec_size);
   211         return -1;
   236         goto err;
   212     }
   237     }
   213 
   238 
   214     if (rec_size < 10) {
   239     if (rec_size < 10) {
   215         EC_ERR("Received currupted SDO upload response!\n");
   240         EC_ERR("Received currupted SDO upload response!\n");
   216         ec_print_data(data, rec_size);
   241         ec_print_data(data, rec_size);
   217         return -1;
   242         goto err;
   218     }
   243     }
   219 
   244 
   220     if ((complete_size = EC_READ_U32(data + 6)) > *size) {
   245     if ((complete_size = EC_READ_U32(data + 6)) > *size) {
   221         EC_ERR("SDO data does not fit into buffer (%i / %i)!\n",
   246         EC_ERR("SDO data does not fit into buffer (%i / %i)!\n",
   222                complete_size, *size);
   247                complete_size, *size);
   223         return -1;
   248         goto err;
   224     }
   249     }
   225 
   250 
   226     data_size = rec_size - 10;
   251     data_size = rec_size - 10;
   227 
   252 
   228     if (data_size != complete_size) {
   253     if (data_size != complete_size) {
   229         EC_ERR("SDO data incomplete - Fragmenting not implemented.\n");
   254         EC_ERR("SDO data incomplete - Fragmenting not implemented.\n");
   230         return -1;
   255         goto err;
   231     }
   256     }
   232 
   257 
   233     memcpy(target, data + 10, data_size);
   258     memcpy(target, data + 10, data_size);
   234     return 0;
   259 
       
   260     ec_command_clear(&command);
       
   261     return 0;
       
   262  err:
       
   263     ec_command_clear(&command);
       
   264     return -1;
   235 }
   265 }
   236 
   266 
   237 /*****************************************************************************/
   267 /*****************************************************************************/
   238 
   268 
   239 /**
   269 /**
   246     uint8_t *data;
   276     uint8_t *data;
   247     size_t rec_size;
   277     size_t rec_size;
   248     unsigned int i, sdo_count;
   278     unsigned int i, sdo_count;
   249     ec_sdo_t *sdo;
   279     ec_sdo_t *sdo;
   250     uint16_t sdo_index;
   280     uint16_t sdo_index;
   251 
   281     ec_command_t command;
   252     if (!(data = ec_slave_mbox_prepare_send(slave, 0x03, 8))) return -1;
   282 
       
   283     ec_command_init(&command);
       
   284 
       
   285     if (!(data = ec_slave_mbox_prepare_send(slave, &command, 0x03, 8)))
       
   286         goto err;
   253 
   287 
   254     EC_WRITE_U16(data, 0x8 << 12); // SDO information
   288     EC_WRITE_U16(data, 0x8 << 12); // SDO information
   255     EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
   289     EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
   256     EC_WRITE_U8 (data + 3, 0x00);
   290     EC_WRITE_U8 (data + 3, 0x00);
   257     EC_WRITE_U16(data + 4, 0x0000);
   291     EC_WRITE_U16(data + 4, 0x0000);
   258     EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
   292     EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
   259 
   293 
   260     if (unlikely(ec_master_simple_io(slave->master, &slave->mbox_command))) {
   294     if (unlikely(ec_master_simple_io(slave->master, &command))) {
   261         EC_ERR("Mailbox checking failed on slave %i!\n", slave->ring_position);
   295         EC_ERR("Mailbox checking failed on slave %i!\n", slave->ring_position);
   262         return -1;
   296         goto err;
   263     }
   297     }
   264 
   298 
   265     do {
   299     do {
   266         if (!(data = ec_slave_mbox_simple_receive(slave, 0x03, &rec_size)))
   300         if (!(data = ec_slave_mbox_simple_receive(slave, &command,
   267             return -1;
   301                                                   0x03, &rec_size)))
       
   302             goto err;
   268 
   303 
   269         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
   304         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
   270             (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
   305             (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
   271             EC_ERR("SDO information error response at slave %i!\n",
   306             EC_ERR("SDO information error response at slave %i!\n",
   272                    slave->ring_position);
   307                    slave->ring_position);
   273             ec_canopen_abort_msg(EC_READ_U32(data + 6));
   308             ec_canopen_abort_msg(EC_READ_U32(data + 6));
   274             return -1;
   309             goto err;
   275         }
   310         }
   276 
   311 
   277         if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
   312         if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
   278             (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
   313             (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
   279             EC_ERR("Invalid SDO list response at slave %i!\n",
   314             EC_ERR("Invalid SDO list response at slave %i!\n",
   280                    slave->ring_position);
   315                    slave->ring_position);
   281             ec_print_data(data, rec_size);
   316             ec_print_data(data, rec_size);
   282             return -1;
   317             goto err;
   283         }
   318         }
   284 
   319 
   285         if (rec_size < 8) {
   320         if (rec_size < 8) {
   286             EC_ERR("Invalid data size!\n");
   321             EC_ERR("Invalid data size!\n");
   287             ec_print_data(data, rec_size);
   322             ec_print_data(data, rec_size);
   288             return -1;
   323             goto err;
   289         }
   324         }
   290 
   325 
   291         sdo_count = (rec_size - 8) / 2;
   326         sdo_count = (rec_size - 8) / 2;
   292         for (i = 0; i < sdo_count; i++) {
   327         for (i = 0; i < sdo_count; i++) {
   293             sdo_index = EC_READ_U16(data + 8 + i * 2);
   328             sdo_index = EC_READ_U16(data + 8 + i * 2);
   294             if (!sdo_index) continue; // sometimes index is 0... ???
   329             if (!sdo_index) continue; // sometimes index is 0... ???
   295 
   330 
   296             if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
   331             if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
   297                 EC_ERR("Failed to allocate memory for SDO!\n");
   332                 EC_ERR("Failed to allocate memory for SDO!\n");
   298                 return -1;
   333                 goto err;
   299             }
   334             }
   300 
   335 
   301             // Initialize SDO object
   336             // Initialize SDO object
   302             sdo->index = sdo_index;
   337             sdo->index = sdo_index;
   303             //sdo->unkown = 0x0000;
   338             //sdo->unkown = 0x0000;
   309         }
   344         }
   310     }
   345     }
   311     while (EC_READ_U8(data + 2) & 0x80);
   346     while (EC_READ_U8(data + 2) & 0x80);
   312 
   347 
   313     // Fetch all SDO descriptions
   348     // Fetch all SDO descriptions
   314     if (ec_slave_fetch_sdo_descriptions(slave)) return -1;
   349     if (ec_slave_fetch_sdo_descriptions(slave, &command)) goto err;
   315 
   350 
   316     return 0;
   351     ec_command_clear(&command);
       
   352     return 0;
       
   353  err:
       
   354     ec_command_clear(&command);
       
   355     return -1;
   317 }
   356 }
   318 
   357 
   319 /*****************************************************************************/
   358 /*****************************************************************************/
   320 
   359 
   321 /**
   360 /**
   322    Fetches the SDO descriptions for the known SDOs.
   361    Fetches the SDO descriptions for the known SDOs.
   323    \return 0 in case of success, else < 0
   362    \return 0 in case of success, else < 0
   324 */
   363 */
   325 
   364 
   326 int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave /**< EtherCAT slave */)
   365 int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave, /**< EtherCAT slave */
       
   366                                     ec_command_t *command /**< command */
       
   367                                     )
   327 {
   368 {
   328     uint8_t *data;
   369     uint8_t *data;
   329     size_t rec_size, name_size;
   370     size_t rec_size, name_size;
   330     ec_sdo_t *sdo;
   371     ec_sdo_t *sdo;
   331 
   372 
   332     list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
   373     list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
   333         if (!(data = ec_slave_mbox_prepare_send(slave, 0x03, 8))) return -1;
   374         if (!(data = ec_slave_mbox_prepare_send(slave, command, 0x03, 8)))
       
   375             return -1;
   334         EC_WRITE_U16(data, 0x8 << 12); // SDO information
   376         EC_WRITE_U16(data, 0x8 << 12); // SDO information
   335         EC_WRITE_U8 (data + 2, 0x03); // Get object description request
   377         EC_WRITE_U8 (data + 2, 0x03); // Get object description request
   336         EC_WRITE_U8 (data + 3, 0x00);
   378         EC_WRITE_U8 (data + 3, 0x00);
   337         EC_WRITE_U16(data + 4, 0x0000);
   379         EC_WRITE_U16(data + 4, 0x0000);
   338         EC_WRITE_U16(data + 6, sdo->index); // SDO index
   380         EC_WRITE_U16(data + 6, sdo->index); // SDO index
   339 
   381 
   340         if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1;
   382         if (!(data = ec_slave_mbox_simple_io(slave, command, &rec_size)))
       
   383             return -1;
   341 
   384 
   342         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
   385         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
   343             (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
   386             (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
   344             EC_ERR("SDO information error response at slave %i while"
   387             EC_ERR("SDO information error response at slave %i while"
   345                    " fetching SDO 0x%04X!\n", slave->ring_position,
   388                    " fetching SDO 0x%04X!\n", slave->ring_position,
   362             EC_ERR("Invalid data size!\n");
   405             EC_ERR("Invalid data size!\n");
   363             ec_print_data(data, rec_size);
   406             ec_print_data(data, rec_size);
   364             return -1;
   407             return -1;
   365         }
   408         }
   366 
   409 
       
   410 #if 0
   367         EC_DBG("object desc response:\n");
   411         EC_DBG("object desc response:\n");
   368         ec_print_data(data, rec_size);
   412         ec_print_data(data, rec_size);
       
   413 #endif
   369 
   414 
   370         //sdo->unknown = EC_READ_U16(data + 8);
   415         //sdo->unknown = EC_READ_U16(data + 8);
   371         sdo->object_code = EC_READ_U8(data + 11);
   416         sdo->object_code = EC_READ_U8(data + 11);
   372 
   417 
   373         name_size = rec_size - 12;
   418         name_size = rec_size - 12;
   385             EC_ERR("Fragment follows (not implemented)!\n");
   430             EC_ERR("Fragment follows (not implemented)!\n");
   386             return -1;
   431             return -1;
   387         }
   432         }
   388 
   433 
   389         // Fetch all entries (subindices)
   434         // Fetch all entries (subindices)
   390         if (ec_slave_fetch_sdo_entries(slave, sdo, EC_READ_U8(data + 10)))
   435         if (ec_slave_fetch_sdo_entries(slave, command, sdo,
       
   436                                        EC_READ_U8(data + 10)))
   391             return -1;
   437             return -1;
   392     }
   438     }
   393 
   439 
   394     return 0;
   440     return 0;
   395 }
   441 }
   400    Fetches all entries (subindices) to an SDO.
   446    Fetches all entries (subindices) to an SDO.
   401    \return 0 in case of success, else < 0
   447    \return 0 in case of success, else < 0
   402 */
   448 */
   403 
   449 
   404 int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT slave */
   450 int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT slave */
       
   451                                ec_command_t *command, /**< command */
   405                                ec_sdo_t *sdo, /**< SDO */
   452                                ec_sdo_t *sdo, /**< SDO */
   406                                uint8_t subindices /**< number of subindices */
   453                                uint8_t subindices /**< number of subindices */
   407                                )
   454                                )
   408 {
   455 {
   409     uint8_t *data;
   456     uint8_t *data;
   410     size_t rec_size, data_size;
   457     size_t rec_size, data_size;
   411     uint8_t i;
   458     uint8_t i;
   412     ec_sdo_entry_t *entry;
   459     ec_sdo_entry_t *entry;
   413 
   460 
   414     for (i = 1; i <= subindices; i++) {
   461     for (i = 1; i <= subindices; i++) {
   415         if (!(data = ec_slave_mbox_prepare_send(slave, 0x03, 10)))
   462         if (!(data = ec_slave_mbox_prepare_send(slave, command, 0x03, 10)))
   416             return -1;
   463             return -1;
   417 
   464 
   418         EC_WRITE_U16(data, 0x8 << 12); // SDO information
   465         EC_WRITE_U16(data, 0x8 << 12); // SDO information
   419         EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
   466         EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
   420         EC_WRITE_U8 (data + 3, 0x00);
   467         EC_WRITE_U8 (data + 3, 0x00);
   421         EC_WRITE_U16(data + 4, 0x0000);
   468         EC_WRITE_U16(data + 4, 0x0000);
   422         EC_WRITE_U16(data + 6, sdo->index); // SDO index
   469         EC_WRITE_U16(data + 6, sdo->index); // SDO index
   423         EC_WRITE_U8 (data + 8, i); // SDO subindex
   470         EC_WRITE_U8 (data + 8, i); // SDO subindex
   424         EC_WRITE_U8 (data + 9, 0x00); // value info (no values)
   471         EC_WRITE_U8 (data + 9, 0x00); // value info (no values)
   425 
   472 
   426         if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1;
   473         if (!(data = ec_slave_mbox_simple_io(slave, command, &rec_size)))
       
   474             return -1;
   427 
   475 
   428         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
   476         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
   429             (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
   477             (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
   430             EC_ERR("SDO information error response at slave %i while"
   478             EC_ERR("SDO information error response at slave %i while"
   431                    " fetching SDO entry 0x%04X:%i!\n", slave->ring_position,
   479                    " fetching SDO entry 0x%04X:%i!\n", slave->ring_position,