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); |