tool/CommandRegWrite.cpp
changeset 1389 5b392b22a2da
parent 1388 3c886ec376f5
child 1395 e9fe40c458cc
equal deleted inserted replaced
1388:3c886ec376f5 1389:5b392b22a2da
    36 #include "sii_crc.h"
    36 #include "sii_crc.h"
    37 
    37 
    38 /*****************************************************************************/
    38 /*****************************************************************************/
    39 
    39 
    40 CommandRegWrite::CommandRegWrite():
    40 CommandRegWrite::CommandRegWrite():
    41     Command("reg_write", "Write data to a slave's registers.")
    41     CommandReg("reg_write", "Write data to a slave's registers.")
    42 {
    42 {
    43 }
    43 }
    44 
    44 
    45 /*****************************************************************************/
    45 /*****************************************************************************/
    46 
    46 
    47 string CommandRegWrite::helpString() const
    47 string CommandRegWrite::helpString() const
    48 {
    48 {
    49     stringstream str;
    49     stringstream str;
    50 
    50 
    51     str << getName() << " [OPTIONS] <OFFSET> <FILENAME>" << endl
    51     str << getName() << " [OPTIONS] <OFFSET> <DATA>" << endl
    52         << endl 
    52         << endl 
    53         << getBriefDescription() << endl
    53         << getBriefDescription() << endl
    54         << endl
    54         << endl
    55         << "This command requires a single slave to be selected." << endl
    55         << "This command requires a single slave to be selected." << endl
    56     	<< endl
    56     	<< endl
    57         << "Arguments:" << endl
    57         << "Arguments:" << endl
    58         << "  OFFSET   must be the register address." << endl
    58         << "  OFFSET  is the register address to write to." << endl
    59         << "  FILENAME must be a path to a file with data to write." << endl
    59         << "  DATA    depends on whether a datatype was specified" << endl
    60         << "           If it is '-', data are read from stdin." << endl
    60 		<< "          with the --type option: If not, DATA must be" << endl
       
    61 		<< "          either a path to a file with data to write," << endl
       
    62 		<< "          or '-', which means, that data are read from" << endl
       
    63 		<< "          stdin. If a datatype was specified, VALUE is" << endl
       
    64 		<< "          interpreted respective to the given type." << endl
    61         << endl
    65         << endl
       
    66         << "These are the valid data types:" << endl
       
    67         << "  int8, int16, int32, int64, uint8, uint16, uint32," << endl
       
    68         << "  uint64, string." << endl
       
    69 		<< endl
    62         << "Command-specific options:" << endl
    70         << "Command-specific options:" << endl
    63         << "  --alias    -a <alias>" << endl
    71         << "  --alias    -a <alias>" << endl
    64         << "  --position -p <pos>    Slave selection. See the help of" << endl
    72         << "  --position -p <pos>    Slave selection. See the help of" << endl
    65         << "                         the 'slaves' command." << endl
    73         << "                         the 'slaves' command." << endl
       
    74         << "  --type     -t <type>   Data type (see above)." << endl
    66         << endl
    75         << endl
    67         << numericInfo();
    76         << numericInfo();
    68 
    77 
    69     return str.str();
    78     return str.str();
    70 }
    79 }
    90     if (strOffset.fail()) {
    99     if (strOffset.fail()) {
    91         err << "Invalid offset '" << args[0] << "'!";
   100         err << "Invalid offset '" << args[0] << "'!";
    92         throwInvalidUsageException(err);
   101         throwInvalidUsageException(err);
    93     }
   102     }
    94 
   103 
    95     if (args[1] == "-") {
   104 	if (getDataType().empty()) {
    96         loadRegData(&data, cin);
   105 		if (args[1] == "-") {
    97     } else {
   106 			loadRegData(&data, cin);
    98         file.open(args[1].c_str(), ifstream::in | ifstream::binary);
   107 		} else {
    99         if (file.fail()) {
   108 			file.open(args[1].c_str(), ifstream::in | ifstream::binary);
   100             err << "Failed to open '" << args[0] << "'!";
   109 			if (file.fail()) {
   101             throwCommandException(err);
   110 				err << "Failed to open '" << args[1] << "'!";
       
   111 				throwCommandException(err);
       
   112 			}
       
   113 			loadRegData(&data, file);
       
   114 			file.close();
       
   115 		}
       
   116 	} else {
       
   117 		stringstream strValue;
       
   118 		const DataType *dataType = findDataType(getDataType());
       
   119 
       
   120         if (!dataType) {
       
   121             err << "Invalid data type '" << getDataType() << "'!";
       
   122             throwInvalidUsageException(err);
   102         }
   123         }
   103         loadRegData(&data, file);
   124 
   104         file.close();
   125 		if (dataType->byteSize) {
   105     }
   126 			data.length = dataType->byteSize;
       
   127 			data.data = new uint8_t[data.length];
       
   128 		}
       
   129 
       
   130 		strValue << args[1];
       
   131 		strValue >> resetiosflags(ios::basefield); // guess base from prefix
       
   132 		strValue.exceptions(ios::failbit);
       
   133 
       
   134 		try {
       
   135 			if (dataType->name == "int8") {
       
   136 				int16_t val; // uint8_t is interpreted as char
       
   137 				strValue >> val;
       
   138 				if (val > 127 || val < -128)
       
   139 					throw ios::failure("Value out of range");
       
   140 				*data.data = (int8_t) val;
       
   141 			} else if (dataType->name == "int16") {
       
   142 				int16_t val;
       
   143 				strValue >> val;
       
   144 				*(int16_t *) data.data = cpu_to_le16(val);
       
   145 			} else if (dataType->name == "int32") {
       
   146 				int32_t val;
       
   147 				strValue >> val;
       
   148 				*(int32_t *) data.data = cpu_to_le32(val);
       
   149 			} else if (dataType->name == "uint8") {
       
   150 				uint16_t val; // uint8_t is interpreted as char
       
   151 				strValue >> val;
       
   152 				if (val > 0xff)
       
   153 					throw ios::failure("Value out of range");
       
   154 				*data.data = (uint8_t) val;
       
   155 			} else if (dataType->name == "uint16") {
       
   156 				uint16_t val;
       
   157 				strValue >> val;
       
   158 				*(uint16_t *) data.data = cpu_to_le16(val);
       
   159 			} else if (dataType->name == "uint32") {
       
   160 				uint32_t val;
       
   161 				strValue >> val;
       
   162 				*(uint32_t *) data.data = cpu_to_le32(val);
       
   163 			} else if (dataType->name == "string" ||
       
   164 					dataType->name == "octet_string") {
       
   165 				data.length = strValue.str().size();
       
   166 				if (!data.length) {
       
   167 					err << "Zero-size string now allowed!";
       
   168 					throwCommandException(err);
       
   169 				}
       
   170 				data.data = new uint8_t[data.length];
       
   171 				strValue >> (char *) data.data;
       
   172 			} else {
       
   173 				err << "Invalid data type " << dataType->name;
       
   174 				throwCommandException(err);
       
   175 			}
       
   176 		} catch (ios::failure &e) {
       
   177 			delete [] data.data;
       
   178 			err << "Invalid value argument '" << args[1]
       
   179 				<< "' for type '" << dataType->name << "'!";
       
   180 			throwInvalidUsageException(err);
       
   181 		}
       
   182 	}
   106 
   183 
   107     if ((uint32_t) data.offset + data.length > 0xffff) {
   184     if ((uint32_t) data.offset + data.length > 0xffff) {
   108         err << "Offset and length exceeding 64k!";
   185         err << "Offset and length exceeding 64k!";
   109         delete [] data.data;
   186         delete [] data.data;
   110         throwInvalidUsageException(err);
   187         throwInvalidUsageException(err);