1 /***************************************************************************** |
1 /***************************************************************************** |
2 * |
2 * |
3 * $Id$ |
3 * $Id$ |
4 * |
4 * |
5 * Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH |
5 * Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH |
6 * |
6 * |
7 * This file is part of the IgH EtherCAT Master. |
7 * This file is part of the IgH EtherCAT Master. |
8 * |
8 * |
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or |
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU General Public License version 2, as |
10 * modify it under the terms of the GNU General Public License version 2, as |
55 << getBriefDescription() << endl |
55 << getBriefDescription() << endl |
56 << endl |
56 << endl |
57 << "This command requires a single slave to be selected." << endl |
57 << "This command requires a single slave to be selected." << endl |
58 << endl |
58 << endl |
59 << "Arguments:" << endl |
59 << "Arguments:" << endl |
60 << " OFFSET is the register address to write to." << endl |
60 << " ADDRESS is the register address to write to." << endl |
61 << " DATA depends on whether a datatype was specified" << endl |
61 << " DATA depends on whether a datatype was specified" << endl |
62 << " with the --type option: If not, DATA must be" << endl |
62 << " with the --type option: If not, DATA must be" << endl |
63 << " either a path to a file with data to write," << endl |
63 << " either a path to a file with data to write," << endl |
64 << " or '-', which means, that data are read from" << endl |
64 << " or '-', which means, that data are read from" << endl |
65 << " stdin. If a datatype was specified, VALUE is" << endl |
65 << " stdin. If a datatype was specified, VALUE is" << endl |
81 /****************************************************************************/ |
81 /****************************************************************************/ |
82 |
82 |
83 void CommandRegWrite::execute(const StringVector &args) |
83 void CommandRegWrite::execute(const StringVector &args) |
84 { |
84 { |
85 stringstream strOffset, err; |
85 stringstream strOffset, err; |
86 ec_ioctl_slave_reg_t data; |
86 ec_ioctl_slave_reg_t io; |
87 ifstream file; |
87 ifstream file; |
88 SlaveList slaves; |
88 SlaveList slaves; |
89 |
89 |
90 if (args.size() != 2) { |
90 if (args.size() != 2) { |
91 err << "'" << getName() << "' takes exactly two arguments!"; |
91 err << "'" << getName() << "' takes exactly two arguments!"; |
93 } |
93 } |
94 |
94 |
95 strOffset << args[0]; |
95 strOffset << args[0]; |
96 strOffset |
96 strOffset |
97 >> resetiosflags(ios::basefield) // guess base from prefix |
97 >> resetiosflags(ios::basefield) // guess base from prefix |
98 >> data.offset; |
98 >> io.address; |
99 if (strOffset.fail()) { |
99 if (strOffset.fail()) { |
100 err << "Invalid offset '" << args[0] << "'!"; |
100 err << "Invalid address '" << args[0] << "'!"; |
101 throwInvalidUsageException(err); |
101 throwInvalidUsageException(err); |
102 } |
102 } |
103 |
103 |
104 if (getDataType().empty()) { |
104 if (getDataType().empty()) { |
105 if (args[1] == "-") { |
105 if (args[1] == "-") { |
106 loadRegData(&data, cin); |
106 loadRegData(&io, cin); |
107 } else { |
107 } else { |
108 file.open(args[1].c_str(), ifstream::in | ifstream::binary); |
108 file.open(args[1].c_str(), ifstream::in | ifstream::binary); |
109 if (file.fail()) { |
109 if (file.fail()) { |
110 err << "Failed to open '" << args[1] << "'!"; |
110 err << "Failed to open '" << args[1] << "'!"; |
111 throwCommandException(err); |
111 throwCommandException(err); |
112 } |
112 } |
113 loadRegData(&data, file); |
113 loadRegData(&io, file); |
114 file.close(); |
114 file.close(); |
115 } |
115 } |
116 } else { |
116 } else { |
117 stringstream strValue; |
117 stringstream strValue; |
118 const DataType *dataType = findDataType(getDataType()); |
118 const DataType *dataType = findDataType(getDataType()); |
121 err << "Invalid data type '" << getDataType() << "'!"; |
121 err << "Invalid data type '" << getDataType() << "'!"; |
122 throwInvalidUsageException(err); |
122 throwInvalidUsageException(err); |
123 } |
123 } |
124 |
124 |
125 if (dataType->byteSize) { |
125 if (dataType->byteSize) { |
126 data.length = dataType->byteSize; |
126 io.size = dataType->byteSize; |
127 } else { |
127 } else { |
128 data.length = 1024; // FIXME |
128 io.size = 1024; // FIXME |
129 } |
129 } |
130 |
130 |
131 data.data = new uint8_t[data.length]; |
131 io.data = new uint8_t[io.size]; |
132 |
132 |
133 try { |
133 try { |
134 data.length = interpretAsType( |
134 io.size = interpretAsType( |
135 dataType, args[1], data.data, data.length); |
135 dataType, args[1], io.data, io.size); |
136 } catch (SizeException &e) { |
136 } catch (SizeException &e) { |
137 delete [] data.data; |
137 delete [] io.data; |
138 throwCommandException(e.what()); |
138 throwCommandException(e.what()); |
139 } catch (ios::failure &e) { |
139 } catch (ios::failure &e) { |
140 delete [] data.data; |
140 delete [] io.data; |
141 err << "Invalid value argument '" << args[1] |
141 err << "Invalid value argument '" << args[1] |
142 << "' for type '" << dataType->name << "'!"; |
142 << "' for type '" << dataType->name << "'!"; |
143 throwInvalidUsageException(err); |
143 throwInvalidUsageException(err); |
144 } |
144 } |
145 } |
145 } |
146 |
146 |
147 if ((uint32_t) data.offset + data.length > 0xffff) { |
147 if ((uint32_t) io.address + io.size > 0xffff) { |
148 err << "Offset and length exceeding 64k!"; |
148 err << "Address and size exceeding 64k!"; |
149 delete [] data.data; |
149 delete [] io.data; |
150 throwInvalidUsageException(err); |
150 throwInvalidUsageException(err); |
151 } |
151 } |
152 |
152 |
153 MasterDevice m(getSingleMasterIndex()); |
153 MasterDevice m(getSingleMasterIndex()); |
154 try { |
154 try { |
155 m.open(MasterDevice::ReadWrite); |
155 m.open(MasterDevice::ReadWrite); |
156 } catch (MasterDeviceException &e) { |
156 } catch (MasterDeviceException &e) { |
157 delete [] data.data; |
157 delete [] io.data; |
158 throw e; |
158 throw e; |
159 } |
159 } |
160 |
160 |
161 slaves = selectedSlaves(m); |
161 slaves = selectedSlaves(m); |
162 if (slaves.size() != 1) { |
162 if (slaves.size() != 1) { |
163 delete [] data.data; |
163 delete [] io.data; |
164 throwSingleSlaveRequired(slaves.size()); |
164 throwSingleSlaveRequired(slaves.size()); |
165 } |
165 } |
166 data.slave_position = slaves.front().position; |
166 io.slave_position = slaves.front().position; |
167 |
167 |
168 // send data to master |
168 // send data to master |
169 try { |
169 try { |
170 m.writeReg(&data); |
170 m.writeReg(&io); |
171 } catch (MasterDeviceException &e) { |
171 } catch (MasterDeviceException &e) { |
172 delete [] data.data; |
172 delete [] io.data; |
173 throw e; |
173 throw e; |
174 } |
174 } |
175 |
175 |
176 if (getVerbosity() == Verbose) { |
176 if (getVerbosity() == Verbose) { |
177 cerr << "Register writing finished." << endl; |
177 cerr << "Register writing finished." << endl; |
178 } |
178 } |
179 |
179 |
180 delete [] data.data; |
180 delete [] io.data; |
181 } |
181 } |
182 |
182 |
183 /*****************************************************************************/ |
183 /*****************************************************************************/ |
184 |
184 |
185 void CommandRegWrite::loadRegData( |
185 void CommandRegWrite::loadRegData( |
186 ec_ioctl_slave_reg_t *data, |
186 ec_ioctl_slave_reg_t *io, |
187 const istream &in |
187 const istream &in |
188 ) |
188 ) |
189 { |
189 { |
190 stringstream err; |
190 stringstream err; |
191 ostringstream tmp; |
191 ostringstream tmp; |
199 |
199 |
200 if (contents.size() > 0xffff) { |
200 if (contents.size() > 0xffff) { |
201 err << "Invalid data size " << contents.size() << "!"; |
201 err << "Invalid data size " << contents.size() << "!"; |
202 throwInvalidUsageException(err); |
202 throwInvalidUsageException(err); |
203 } |
203 } |
204 data->length = contents.size(); |
204 io->size = contents.size(); |
205 |
205 |
206 // allocate buffer and read file into buffer |
206 // allocate buffer and read file into buffer |
207 data->data = new uint8_t[data->length]; |
207 io->data = new uint8_t[io->size]; |
208 contents.copy((char *) data->data, contents.size()); |
208 contents.copy((char *) io->data, contents.size()); |
209 } |
209 } |
210 |
210 |
211 /*****************************************************************************/ |
211 /*****************************************************************************/ |