tool/cmd_sdo_download.cpp
changeset 1134 3356141fa2f8
parent 1133 860d1c3d08fc
child 1135 807ec6498502
equal deleted inserted replaced
1133:860d1c3d08fc 1134:3356141fa2f8
     1 /*****************************************************************************
       
     2  *
       
     3  * $Id$
       
     4  *
       
     5  ****************************************************************************/
       
     6 
       
     7 #include <iostream>
       
     8 #include <iomanip>
       
     9 using namespace std;
       
    10 
       
    11 #include "globals.h"
       
    12 #include "coe_datatypes.h"
       
    13 
       
    14 /****************************************************************************/
       
    15 
       
    16 // FIXME
       
    17 const char *help_sdo_download =
       
    18     "[OPTIONS]\n"
       
    19     "\n"
       
    20     "\n"
       
    21     "Command-specific options:\n";
       
    22 
       
    23 /****************************************************************************/
       
    24 
       
    25 void command_sdo_download(void)
       
    26 {
       
    27     stringstream strIndex, strSubIndex, strValue, err;
       
    28     ec_ioctl_slave_sdo_download_t data;
       
    29     unsigned int number;
       
    30     const CoEDataType *dataType = NULL;
       
    31 
       
    32     if (slavePosition < 0) {
       
    33         err << "'sdo_download' requires a slave! Please specify --slave.";
       
    34         throw MasterDeviceException(err.str());
       
    35     }
       
    36     data.slave_position = slavePosition;
       
    37 
       
    38     if (commandArgs.size() != 3) {
       
    39         err << "'sdo_download' takes 3 arguments!";
       
    40         throw MasterDeviceException(err.str());
       
    41     }
       
    42 
       
    43     strIndex << commandArgs[0];
       
    44     strIndex
       
    45         >> resetiosflags(ios::basefield) // guess base from prefix
       
    46         >> data.sdo_index;
       
    47     if (strIndex.fail()) {
       
    48         err << "Invalid Sdo index '" << commandArgs[0] << "'!";
       
    49         throw MasterDeviceException(err.str());
       
    50     }
       
    51 
       
    52     strSubIndex << commandArgs[1];
       
    53     strSubIndex
       
    54         >> resetiosflags(ios::basefield) // guess base from prefix
       
    55         >> number;
       
    56     if (strSubIndex.fail() || number > 0xff) {
       
    57         err << "Invalid Sdo subindex '" << commandArgs[1] << "'!";
       
    58         throw MasterDeviceException(err.str());
       
    59     }
       
    60     data.sdo_entry_subindex = number;
       
    61 
       
    62     if (dataTypeStr != "") { // data type specified
       
    63         if (!(dataType = findDataType(dataTypeStr))) {
       
    64             err << "Invalid data type '" << dataTypeStr << "'!";
       
    65             throw MasterDeviceException(err.str());
       
    66         }
       
    67     } else { // no data type specified: fetch from dictionary
       
    68         ec_ioctl_slave_sdo_entry_t entry;
       
    69 
       
    70         masterDev.open(MasterDevice::ReadWrite);
       
    71 
       
    72         try {
       
    73             masterDev.getSdoEntry(&entry, slavePosition,
       
    74                     data.sdo_index, data.sdo_entry_subindex);
       
    75         } catch (MasterDeviceException &e) {
       
    76             err << "Failed to determine Sdo entry data type. "
       
    77                 << "Please specify --type.";
       
    78             throw ExecutionFailureException(err);
       
    79         }
       
    80         if (!(dataType = findDataType(entry.data_type))) {
       
    81             err << "Pdo entry has unknown data type 0x"
       
    82                 << hex << setfill('0') << setw(4) << entry.data_type << "!"
       
    83                 << " Please specify --type.";
       
    84             throw ExecutionFailureException(err);
       
    85         }
       
    86     }
       
    87 
       
    88     if (dataType->byteSize) {
       
    89         data.data_size = dataType->byteSize;
       
    90     } else {
       
    91         data.data_size = DefaultBufferSize;
       
    92     }
       
    93 
       
    94     data.data = new uint8_t[data.data_size + 1];
       
    95 
       
    96     strValue << commandArgs[2];
       
    97     strValue >> resetiosflags(ios::basefield); // guess base from prefix
       
    98     strValue.exceptions(ios::failbit);
       
    99 
       
   100     try {
       
   101         switch (dataType->coeCode) {
       
   102             case 0x0002: // int8
       
   103                 {
       
   104                     int16_t val; // uint8_t is interpreted as char
       
   105                     strValue >> val;
       
   106                     if (val > 127 || val < -128)
       
   107                         throw ios::failure("Value out of range");
       
   108                     *data.data = val;
       
   109                     break;
       
   110                 }
       
   111             case 0x0003: // int16
       
   112                 {
       
   113                     int16_t val;
       
   114                     strValue >> val;
       
   115                     *(int16_t *) data.data = cputole16(val);
       
   116                     break;
       
   117                 }
       
   118             case 0x0004: // int32
       
   119                 {
       
   120                     int32_t val;
       
   121                     strValue >> val;
       
   122                     *(int32_t *) data.data = cputole32(val);
       
   123                     break;
       
   124                 }
       
   125             case 0x0005: // uint8
       
   126                 {
       
   127                     uint16_t val; // uint8_t is interpreted as char
       
   128                     strValue >> val;
       
   129                     if (val > 0xff)
       
   130                         throw ios::failure("Value out of range");
       
   131                     *data.data = val;
       
   132                     break;
       
   133                 }
       
   134             case 0x0006: // uint16
       
   135                 {
       
   136                     uint16_t val;
       
   137                     strValue >> val;
       
   138                     *(uint16_t *) data.data = cputole16(val);
       
   139                     break;
       
   140                 }
       
   141             case 0x0007: // uint32
       
   142                 {
       
   143                     uint32_t val;
       
   144                     strValue >> val;
       
   145                     *(uint32_t *) data.data = cputole32(val);
       
   146                     break;
       
   147                 }
       
   148             case 0x0009: // string
       
   149                 if (strValue.str().size() >= data.data_size) {
       
   150                     err << "String too large";
       
   151                     throw MasterDeviceException(err.str());
       
   152                 }
       
   153                 data.data_size = strValue.str().size();
       
   154                 strValue >> (char *) data.data;
       
   155                 break;
       
   156 
       
   157             default:
       
   158                 delete [] data.data;
       
   159                 err << "Unknown data type 0x" << hex << dataType->coeCode;
       
   160                 throw MasterDeviceException(err.str());
       
   161         }
       
   162     } catch (ios::failure &e) {
       
   163         delete [] data.data;
       
   164         err << "Invalid value argument '" << commandArgs[2]
       
   165             << "' for type '" << dataType->name << "'!";
       
   166         throw MasterDeviceException(err.str());
       
   167     }
       
   168 
       
   169     masterDev.open(MasterDevice::ReadWrite);
       
   170 
       
   171 	try {
       
   172 		masterDev.sdoDownload(&data);
       
   173 	} catch(MasterDeviceException &e) {
       
   174         delete [] data.data;
       
   175         throw e;
       
   176     }
       
   177 
       
   178     delete [] data.data;
       
   179 }
       
   180 
       
   181 /*****************************************************************************/