canopen.c

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  *  $Id: canopen.c 490 2006-08-02 12:25:25Z fp $
00004  *
00005  *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
00006  *
00007  *  This file is part of the IgH EtherCAT Master.
00008  *
00009  *  The IgH EtherCAT Master is free software; you can redistribute it
00010  *  and/or modify it under the terms of the GNU General Public License
00011  *  as published by the Free Software Foundation; either version 2 of the
00012  *  License, or (at your option) any later version.
00013  *
00014  *  The IgH EtherCAT Master is distributed in the hope that it will be
00015  *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with the IgH EtherCAT Master; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  *  The right to use EtherCAT Technology is granted and comes free of
00024  *  charge under condition of compatibility of product made by
00025  *  Licensee. People intending to distribute/sell products based on the
00026  *  code, have to sign an agreement to guarantee that products using
00027  *  software based on IgH EtherCAT master stay compatible with the actual
00028  *  EtherCAT specification (which are released themselves as an open
00029  *  standard) as the (only) precondition to have the right to use EtherCAT
00030  *  Technology, IP and trade marks.
00031  *
00032  *****************************************************************************/
00033 
00039 /*****************************************************************************/
00040 
00041 #include <linux/delay.h>
00042 #include <linux/slab.h>
00043 #include <linux/module.h>
00044 
00045 #include "master.h"
00046 #include "mailbox.h"
00047 
00048 /*****************************************************************************/
00049 
00050 void ec_canopen_abort_msg(uint32_t);
00051 int ec_slave_fetch_sdo_descriptions(ec_slave_t *, ec_datagram_t *);
00052 int ec_slave_fetch_sdo_entries(ec_slave_t *, ec_datagram_t *,
00053                                ec_sdo_t *, uint8_t);
00054 
00055 /*****************************************************************************/
00056 
00062 int ec_slave_sdo_read_exp(ec_slave_t *slave, 
00063                           uint16_t sdo_index, 
00064                           uint8_t sdo_subindex, 
00065                           uint8_t *target 
00066                           )
00067 {
00068     ec_datagram_t datagram;
00069     size_t rec_size;
00070     uint8_t *data;
00071 
00072     ec_datagram_init(&datagram);
00073 
00074     if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 6)))
00075         goto err;
00076 
00077     EC_WRITE_U16(data, 0x2 << 12); // SDO request
00078     EC_WRITE_U8 (data + 2, (0x1 << 1 // expedited transfer
00079                             | 0x2 << 5)); // initiate upload request
00080     EC_WRITE_U16(data + 3, sdo_index);
00081     EC_WRITE_U8 (data + 5, sdo_subindex);
00082 
00083     if (!(data = ec_slave_mbox_simple_io(slave, &datagram, &rec_size)))
00084         goto err;
00085 
00086     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
00087         EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
00088         EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
00089                sdo_index, sdo_subindex, slave->ring_position);
00090         ec_canopen_abort_msg(EC_READ_U32(data + 6));
00091         goto err;
00092     }
00093 
00094     if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
00095         EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response
00096         EC_READ_U16(data + 3) != sdo_index || // index
00097         EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
00098         EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex);
00099         EC_ERR("Invalid SDO upload response at slave %i!\n",
00100                slave->ring_position);
00101         ec_print_data(data, rec_size);
00102         goto err;
00103     }
00104 
00105     memcpy(target, data + 6, 4);
00106 
00107     ec_datagram_clear(&datagram);
00108     return 0;
00109  err:
00110     ec_datagram_clear(&datagram);
00111     return -1;
00112 }
00113 
00114 /*****************************************************************************/
00115 
00121 int ec_slave_sdo_write_exp(ec_slave_t *slave, 
00122                            uint16_t sdo_index, 
00123                            uint8_t sdo_subindex, 
00124                            const uint8_t *sdo_data, 
00125                            size_t size 
00126                            )
00127 {
00128     uint8_t *data;
00129     size_t rec_size;
00130     ec_datagram_t datagram;
00131 
00132     ec_datagram_init(&datagram);
00133 
00134     if (size == 0 || size > 4) {
00135         EC_ERR("Invalid data size!\n");
00136         goto err;
00137     }
00138 
00139     if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 0x0A)))
00140         goto err;
00141 
00142     EC_WRITE_U16(data, 0x2 << 12); // SDO request
00143     EC_WRITE_U8 (data + 2, (0x1 // size specified
00144                             | 0x1 << 1 // expedited transfer
00145                             | (4 - size) << 2 // data set size
00146                             | 0x1 << 5)); // initiate download request
00147     EC_WRITE_U16(data + 3, sdo_index);
00148     EC_WRITE_U8 (data + 5, sdo_subindex);
00149     memcpy(data + 6, sdo_data, size);
00150     if (size < 4) memset(data + 6 + size, 0x00, 4 - size);
00151 
00152     if (!(data = ec_slave_mbox_simple_io(slave, &datagram, &rec_size)))
00153         goto err;
00154 
00155     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
00156         EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
00157         EC_ERR("SDO download 0x%04X:%X (%i bytes) aborted on slave %i.\n",
00158                sdo_index, sdo_subindex, size, slave->ring_position);
00159         ec_canopen_abort_msg(EC_READ_U32(data + 6));
00160         return -1;
00161     }
00162 
00163     if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
00164         EC_READ_U8 (data + 2) >> 5 != 0x3 || // download response
00165         EC_READ_U16(data + 3) != sdo_index || // index
00166         EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
00167         EC_ERR("SDO download 0x%04X:%X (%i bytes) failed:\n",
00168                sdo_index, sdo_subindex, size);
00169         EC_ERR("Invalid SDO download response at slave %i!\n",
00170                slave->ring_position);
00171         ec_print_data(data, rec_size);
00172         return -1;
00173     }
00174 
00175     ec_datagram_clear(&datagram);
00176     return 0;
00177  err:
00178     ec_datagram_clear(&datagram);
00179     return -1;
00180 }
00181 
00182 /*****************************************************************************/
00183 
00191 int ecrt_slave_sdo_read(ec_slave_t *slave, 
00192                         uint16_t sdo_index, 
00193                         uint8_t sdo_subindex, 
00194                         uint8_t *target, 
00195                         size_t *size 
00196                         )
00197 {
00198     uint8_t *data;
00199     size_t rec_size, data_size;
00200     uint32_t complete_size;
00201     ec_datagram_t datagram;
00202 
00203     ec_datagram_init(&datagram);
00204 
00205     if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 6)))
00206         goto err;
00207 
00208     EC_WRITE_U16(data, 0x2 << 12); // SDO request
00209     EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
00210     EC_WRITE_U16(data + 3, sdo_index);
00211     EC_WRITE_U8 (data + 5, sdo_subindex);
00212 
00213     if (!(data = ec_slave_mbox_simple_io(slave, &datagram, &rec_size)))
00214         goto err;
00215 
00216     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
00217         EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
00218         EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
00219                sdo_index, sdo_subindex, slave->ring_position);
00220         ec_canopen_abort_msg(EC_READ_U32(data + 6));
00221         goto err;
00222     }
00223 
00224     if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
00225         EC_READ_U8 (data + 2) >> 5 != 0x2 || // initiate upload response
00226         EC_READ_U16(data + 3) != sdo_index || // index
00227         EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
00228         EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex);
00229         EC_ERR("Invalid SDO upload response at slave %i!\n",
00230                slave->ring_position);
00231         ec_print_data(data, rec_size);
00232         goto err;
00233     }
00234 
00235     if (rec_size < 10) {
00236         EC_ERR("Received currupted SDO upload response!\n");
00237         ec_print_data(data, rec_size);
00238         goto err;
00239     }
00240 
00241     if ((complete_size = EC_READ_U32(data + 6)) > *size) {
00242         EC_ERR("SDO data does not fit into buffer (%i / %i)!\n",
00243                complete_size, *size);
00244         goto err;
00245     }
00246 
00247     data_size = rec_size - 10;
00248 
00249     if (data_size != complete_size) {
00250         EC_ERR("SDO data incomplete - Fragmenting not implemented.\n");
00251         goto err;
00252     }
00253 
00254     memcpy(target, data + 10, data_size);
00255 
00256     ec_datagram_clear(&datagram);
00257     return 0;
00258  err:
00259     ec_datagram_clear(&datagram);
00260     return -1;
00261 }
00262 
00263 /*****************************************************************************/
00264 
00270 int ec_slave_fetch_sdo_list(ec_slave_t *slave )
00271 {
00272     uint8_t *data;
00273     size_t rec_size;
00274     unsigned int i, sdo_count;
00275     ec_sdo_t *sdo;
00276     uint16_t sdo_index;
00277     ec_datagram_t datagram;
00278 
00279     ec_datagram_init(&datagram);
00280 
00281     if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 8)))
00282         goto err;
00283 
00284     EC_WRITE_U16(data, 0x8 << 12); // SDO information
00285     EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
00286     EC_WRITE_U8 (data + 3, 0x00);
00287     EC_WRITE_U16(data + 4, 0x0000);
00288     EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
00289 
00290     if (unlikely(ec_master_simple_io(slave->master, &datagram))) {
00291         EC_ERR("Mailbox checking failed on slave %i!\n", slave->ring_position);
00292         goto err;
00293     }
00294 
00295     do {
00296         if (!(data = ec_slave_mbox_simple_receive(slave, &datagram,
00297                                                   0x03, &rec_size)))
00298             goto err;
00299 
00300         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
00301             (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
00302             EC_ERR("SDO information error response at slave %i!\n",
00303                    slave->ring_position);
00304             ec_canopen_abort_msg(EC_READ_U32(data + 6));
00305             goto err;
00306         }
00307 
00308         if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
00309             (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
00310             EC_ERR("Invalid SDO list response at slave %i!\n",
00311                    slave->ring_position);
00312             ec_print_data(data, rec_size);
00313             goto err;
00314         }
00315 
00316         if (rec_size < 8) {
00317             EC_ERR("Invalid data size!\n");
00318             ec_print_data(data, rec_size);
00319             goto err;
00320         }
00321 
00322         sdo_count = (rec_size - 8) / 2;
00323         for (i = 0; i < sdo_count; i++) {
00324             sdo_index = EC_READ_U16(data + 8 + i * 2);
00325             if (!sdo_index) continue; // sometimes index is 0... ???
00326 
00327             if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
00328                 EC_ERR("Failed to allocate memory for SDO!\n");
00329                 goto err;
00330             }
00331 
00332             // Initialize SDO object
00333             sdo->index = sdo_index;
00334             //sdo->unkown = 0x0000;
00335             sdo->object_code = 0x00;
00336             sdo->name = NULL;
00337             INIT_LIST_HEAD(&sdo->entries);
00338 
00339             list_add_tail(&sdo->list, &slave->sdo_dictionary);
00340         }
00341     }
00342     while (EC_READ_U8(data + 2) & 0x80);
00343 
00344     // Fetch all SDO descriptions
00345     if (ec_slave_fetch_sdo_descriptions(slave, &datagram)) goto err;
00346 
00347     ec_datagram_clear(&datagram);
00348     return 0;
00349  err:
00350     ec_datagram_clear(&datagram);
00351     return -1;
00352 }
00353 
00354 /*****************************************************************************/
00355 
00361 int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave, 
00362                                     ec_datagram_t *datagram 
00363                                     )
00364 {
00365     uint8_t *data;
00366     size_t rec_size, name_size;
00367     ec_sdo_t *sdo;
00368 
00369     list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
00370         if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8)))
00371             return -1;
00372         EC_WRITE_U16(data, 0x8 << 12); // SDO information
00373         EC_WRITE_U8 (data + 2, 0x03); // Get object description request
00374         EC_WRITE_U8 (data + 3, 0x00);
00375         EC_WRITE_U16(data + 4, 0x0000);
00376         EC_WRITE_U16(data + 6, sdo->index); // SDO index
00377 
00378         if (!(data = ec_slave_mbox_simple_io(slave, datagram, &rec_size)))
00379             return -1;
00380 
00381         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
00382             (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
00383             EC_ERR("SDO information error response at slave %i while"
00384                    " fetching SDO 0x%04X!\n", slave->ring_position,
00385                    sdo->index);
00386             ec_canopen_abort_msg(EC_READ_U32(data + 6));
00387             return -1;
00388         }
00389 
00390         if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
00391             (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response
00392             EC_READ_U16(data + 6) != sdo->index) { // SDO index
00393             EC_ERR("Invalid object description response at slave %i while"
00394                    " fetching SDO 0x%04X!\n", slave->ring_position,
00395                    sdo->index);
00396             ec_print_data(data, rec_size);
00397             return -1;
00398         }
00399 
00400         if (rec_size < 12) {
00401             EC_ERR("Invalid data size!\n");
00402             ec_print_data(data, rec_size);
00403             return -1;
00404         }
00405 
00406 #if 0
00407         EC_DBG("object desc response:\n");
00408         ec_print_data(data, rec_size);
00409 #endif
00410 
00411         //sdo->unknown = EC_READ_U16(data + 8);
00412         sdo->object_code = EC_READ_U8(data + 11);
00413 
00414         name_size = rec_size - 12;
00415         if (name_size) {
00416             if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) {
00417                 EC_ERR("Failed to allocate SDO name!\n");
00418                 return -1;
00419             }
00420 
00421             memcpy(sdo->name, data + 12, name_size);
00422             sdo->name[name_size] = 0;
00423         }
00424 
00425         if (EC_READ_U8(data + 2) & 0x80) {
00426             EC_ERR("Fragment follows (not implemented)!\n");
00427             return -1;
00428         }
00429 
00430         // Fetch all entries (subindices)
00431         if (ec_slave_fetch_sdo_entries(slave, datagram, sdo,
00432                                        EC_READ_U8(data + 10)))
00433             return -1;
00434     }
00435 
00436     return 0;
00437 }
00438 
00439 /*****************************************************************************/
00440 
00446 int ec_slave_fetch_sdo_entries(ec_slave_t *slave, 
00447                                ec_datagram_t *datagram, 
00448                                ec_sdo_t *sdo, 
00449                                uint8_t subindices 
00450                                )
00451 {
00452     uint8_t *data;
00453     size_t rec_size, data_size;
00454     uint8_t i;
00455     ec_sdo_entry_t *entry;
00456 
00457     for (i = 1; i <= subindices; i++) {
00458         if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10)))
00459             return -1;
00460 
00461         EC_WRITE_U16(data, 0x8 << 12); // SDO information
00462         EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
00463         EC_WRITE_U8 (data + 3, 0x00);
00464         EC_WRITE_U16(data + 4, 0x0000);
00465         EC_WRITE_U16(data + 6, sdo->index); // SDO index
00466         EC_WRITE_U8 (data + 8, i); // SDO subindex
00467         EC_WRITE_U8 (data + 9, 0x00); // value info (no values)
00468 
00469         if (!(data = ec_slave_mbox_simple_io(slave, datagram, &rec_size)))
00470             return -1;
00471 
00472         if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
00473             (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
00474             EC_ERR("SDO information error response at slave %i while"
00475                    " fetching SDO entry 0x%04X:%i!\n", slave->ring_position,
00476                    sdo->index, i);
00477             ec_canopen_abort_msg(EC_READ_U32(data + 6));
00478             return -1;
00479         }
00480 
00481         if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
00482             (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
00483             EC_READ_U16(data + 6) != sdo->index || // SDO index
00484             EC_READ_U8(data + 8) != i) { // SDO subindex
00485             EC_ERR("Invalid entry description response at slave %i while"
00486                    " fetching SDO entry 0x%04X:%i!\n", slave->ring_position,
00487                    sdo->index, i);
00488             ec_print_data(data, rec_size);
00489             return -1;
00490         }
00491 
00492         if (rec_size < 16) {
00493             EC_ERR("Invalid data size!\n");
00494             ec_print_data(data, rec_size);
00495             return -1;
00496         }
00497 
00498         if (!EC_READ_U16(data + 12)) // bit length = 0
00499             continue;
00500 
00501         data_size = rec_size - 16;
00502 
00503         if (!(entry = (ec_sdo_entry_t *)
00504               kmalloc(sizeof(ec_sdo_entry_t) + data_size + 1, GFP_KERNEL))) {
00505             EC_ERR("Failed to allocate entry!\n");
00506             return -1;
00507         }
00508 
00509         entry->subindex = i;
00510         entry->data_type = EC_READ_U16(data + 10);
00511         entry->bit_length = EC_READ_U16(data + 12);
00512 
00513         // memory for name string appended to entry
00514         entry->name = (uint8_t *) entry + sizeof(ec_sdo_entry_t);
00515 
00516         memcpy(entry->name, data + 16, data_size);
00517         entry->name[data_size] = 0;
00518 
00519         list_add_tail(&entry->list, &sdo->entries);
00520     }
00521 
00522     return 0;
00523 }
00524 
00525 /*****************************************************************************/
00526 
00534 const ec_code_msg_t sdo_abort_messages[] = {
00535     {0x05030000, "Toggle bit not changed"},
00536     {0x05040000, "SDO protocol timeout"},
00537     {0x05040001, "Client/Server command specifier not valid or unknown"},
00538     {0x05040005, "Out of memory"},
00539     {0x06010000, "Unsupported access to an object"},
00540     {0x06010001, "Attempt to read a write-only object"},
00541     {0x06010002, "Attempt to write a read-only object"},
00542     {0x06020000, "This object does not exist in the object directory"},
00543     {0x06040041, "The object cannot be mapped into the PDO"},
00544     {0x06040042, "The number and length of the objects to be mapped would"
00545      " exceed the PDO length"},
00546     {0x06040043, "General parameter incompatibility reason"},
00547     {0x06040047, "Gerneral internal incompatibility in device"},
00548     {0x06060000, "Access failure due to a hardware error"},
00549     {0x06070010, "Data type does not match, length of service parameter does"
00550      " not match"},
00551     {0x06070012, "Data type does not match, length of service parameter too"
00552      " high"},
00553     {0x06070013, "Data type does not match, length of service parameter too"
00554      " low"},
00555     {0x06090011, "Subindex does not exist"},
00556     {0x06090030, "Value range of parameter exceeded"},
00557     {0x06090031, "Value of parameter written too high"},
00558     {0x06090032, "Value of parameter written too low"},
00559     {0x06090036, "Maximum value is less than minimum value"},
00560     {0x08000000, "General error"},
00561     {0x08000020, "Data cannot be transferred or stored to the application"},
00562     {0x08000021, "Data cannot be transferred or stored to the application"
00563      " because of local control"},
00564     {0x08000022, "Data cannot be transferred or stored to the application"
00565      " because of the present device state"},
00566     {0x08000023, "Object dictionary dynamic generation fails or no object"
00567      " dictionary is present"},
00568     {}
00569 };
00570 
00571 /*****************************************************************************/
00572 
00577 void ec_canopen_abort_msg(uint32_t abort_code)
00578 {
00579     const ec_code_msg_t *abort_msg;
00580 
00581     for (abort_msg = sdo_abort_messages; abort_msg->code; abort_msg++) {
00582         if (abort_msg->code == abort_code) {
00583             EC_ERR("SDO abort message 0x%08X: \"%s\".\n",
00584                    abort_msg->code, abort_msg->message);
00585             return;
00586         }
00587     }
00588 
00589     EC_ERR("Unknown SDO abort code 0x%08X.\n", abort_code);
00590 }
00591 
00592 /******************************************************************************
00593  *  Realtime interface
00594  *****************************************************************************/
00595 
00603 int ecrt_slave_sdo_read_exp8(ec_slave_t *slave, 
00604                              uint16_t sdo_index, 
00605                              uint8_t sdo_subindex, 
00606                              uint8_t *target 
00607                              )
00608 {
00609     uint8_t data[4];
00610     if (ec_slave_sdo_read_exp(slave, sdo_index, sdo_subindex, data)) return -1;
00611     *target = EC_READ_U8(data);
00612     return 0;
00613 }
00614 
00615 /*****************************************************************************/
00616 
00624 int ecrt_slave_sdo_read_exp16(ec_slave_t *slave, 
00625                               uint16_t sdo_index, 
00626                               uint8_t sdo_subindex, 
00627                               uint16_t *target 
00628                               )
00629 {
00630     uint8_t data[4];
00631     if (ec_slave_sdo_read_exp(slave, sdo_index, sdo_subindex, data)) return -1;
00632     *target = EC_READ_U16(data);
00633     return 0;
00634 }
00635 
00636 /*****************************************************************************/
00637 
00645 int ecrt_slave_sdo_read_exp32(ec_slave_t *slave, 
00646                               uint16_t sdo_index, 
00647                               uint8_t sdo_subindex, 
00648                               uint32_t *target 
00649                               )
00650 {
00651     uint8_t data[4];
00652     if (ec_slave_sdo_read_exp(slave, sdo_index, sdo_subindex, data)) return -1;
00653     *target = EC_READ_U32(data);
00654     return 0;
00655 }
00656 
00657 /*****************************************************************************/
00658 
00665 int ecrt_slave_sdo_write_exp8(ec_slave_t *slave, 
00666                               uint16_t sdo_index, 
00667                               uint8_t sdo_subindex, 
00668                               uint8_t value 
00669                               )
00670 {
00671     return ec_slave_sdo_write_exp(slave, sdo_index, sdo_subindex, &value, 1);
00672 }
00673 
00674 /*****************************************************************************/
00675 
00682 int ecrt_slave_sdo_write_exp16(ec_slave_t *slave, 
00683                                uint16_t sdo_index, 
00684                                uint8_t sdo_subindex, 
00685                                uint16_t value 
00686                                )
00687 {
00688     uint8_t data[2];
00689     EC_WRITE_U16(data, value);
00690     return ec_slave_sdo_write_exp(slave, sdo_index, sdo_subindex, data, 2);
00691 }
00692 
00693 /*****************************************************************************/
00694 
00701 int ecrt_slave_sdo_write_exp32(ec_slave_t *slave, 
00702                                uint16_t sdo_index, 
00703                                uint8_t sdo_subindex, 
00704                                uint32_t value 
00705                                )
00706 {
00707     uint8_t data[4];
00708     EC_WRITE_U32(data, value);
00709     return ec_slave_sdo_write_exp(slave, sdo_index, sdo_subindex, data, 4);
00710 }
00711 
00712 /*****************************************************************************/
00713 
00716 EXPORT_SYMBOL(ecrt_slave_sdo_read_exp8);
00717 EXPORT_SYMBOL(ecrt_slave_sdo_read_exp16);
00718 EXPORT_SYMBOL(ecrt_slave_sdo_read_exp32);
00719 EXPORT_SYMBOL(ecrt_slave_sdo_write_exp8);
00720 EXPORT_SYMBOL(ecrt_slave_sdo_write_exp16);
00721 EXPORT_SYMBOL(ecrt_slave_sdo_write_exp32);
00722 EXPORT_SYMBOL(ecrt_slave_sdo_read);
00723 
00726 /*****************************************************************************/

Generated on Wed Aug 2 18:41:43 2006 for IgH EtherCAT master by  doxygen 1.4.6