1142
|
1 |
/*****************************************************************************
|
|
2 |
*
|
|
3 |
* $Id$
|
|
4 |
*
|
|
5 |
****************************************************************************/
|
|
6 |
|
|
7 |
#include <list>
|
|
8 |
#include <iostream>
|
|
9 |
#include <iomanip>
|
|
10 |
#include <sstream>
|
|
11 |
using namespace std;
|
|
12 |
|
|
13 |
#include "CommandConfig.h"
|
|
14 |
#include "byteorder.h"
|
|
15 |
|
|
16 |
/*****************************************************************************/
|
|
17 |
|
|
18 |
CommandConfig::CommandConfig():
|
|
19 |
Command("config", "Show slave configurations.")
|
|
20 |
{
|
|
21 |
}
|
|
22 |
|
|
23 |
/*****************************************************************************/
|
|
24 |
|
|
25 |
string CommandConfig::helpString() const
|
|
26 |
{
|
|
27 |
stringstream str;
|
|
28 |
|
|
29 |
str << "[OPTIONS]" << endl
|
|
30 |
<< endl
|
|
31 |
<< "Output information about the slave configurations" << endl
|
|
32 |
<< "supplied by the application." << endl
|
|
33 |
<< endl
|
|
34 |
<< "Without the --verbose option, slave configurations are" << endl
|
|
35 |
<< "output one-per-line. Example:" << endl
|
|
36 |
<< endl
|
|
37 |
<< "1001:0 0x0000003b/0x02010000 - -" << endl
|
|
38 |
<< "| | | |" << endl
|
|
39 |
<< "| | | \\- Slave is operational."
|
|
40 |
<< endl
|
|
41 |
<< "| | \\- Slave has been found." << endl
|
|
42 |
<< "| \\- Hexadecimal vendor ID and product code, separated"
|
|
43 |
<< endl
|
|
44 |
<< "| by a slash." << endl
|
|
45 |
<< "\\- Decimal alias and position, separated by a colon." << endl
|
|
46 |
<< endl
|
|
47 |
<< "With the --verbose option given, the configured Pdos and" << endl
|
|
48 |
<< "Sdos are additionally printed." << endl
|
|
49 |
<< endl
|
|
50 |
<< "Command-specific options:" << endl
|
|
51 |
<< " --verbose -v Show detailed configurations." << endl;
|
|
52 |
|
|
53 |
return str.str();
|
|
54 |
}
|
|
55 |
|
|
56 |
/*****************************************************************************/
|
|
57 |
|
|
58 |
/*****************************************************************************/
|
|
59 |
|
|
60 |
bool operator<(const ec_ioctl_config_t &a, const ec_ioctl_config_t &b)
|
|
61 |
{
|
|
62 |
return a.alias < b.alias
|
|
63 |
|| (a.alias == b.alias && a.position < b.position);
|
|
64 |
}
|
|
65 |
|
|
66 |
/*****************************************************************************/
|
|
67 |
|
|
68 |
/** Lists the bus configuration.
|
|
69 |
*/
|
|
70 |
void CommandConfig::execute(MasterDevice &m, const StringVector &args)
|
|
71 |
{
|
|
72 |
ec_ioctl_master_t master;
|
|
73 |
unsigned int i;
|
|
74 |
ec_ioctl_config_t config;
|
|
75 |
ConfigList configList;
|
|
76 |
|
|
77 |
m.open(MasterDevice::Read);
|
|
78 |
m.getMaster(&master);
|
|
79 |
|
|
80 |
for (i = 0; i < master.config_count; i++) {
|
|
81 |
m.getConfig(&config, i);
|
|
82 |
configList.push_back(config);
|
|
83 |
}
|
|
84 |
|
|
85 |
configList.sort();
|
|
86 |
|
|
87 |
if (getVerbosity() == Verbose) {
|
|
88 |
showDetailedConfigs(m, configList);
|
|
89 |
} else {
|
|
90 |
listConfigs(configList);
|
|
91 |
}
|
|
92 |
}
|
|
93 |
|
|
94 |
/*****************************************************************************/
|
|
95 |
|
|
96 |
/** Lists the complete bus configuration.
|
|
97 |
*/
|
|
98 |
void CommandConfig::showDetailedConfigs(
|
|
99 |
MasterDevice &m,
|
|
100 |
const ConfigList &configList
|
|
101 |
)
|
|
102 |
{
|
|
103 |
ConfigList::const_iterator configIter;
|
|
104 |
unsigned int j, k, l;
|
|
105 |
ec_ioctl_config_pdo_t pdo;
|
|
106 |
ec_ioctl_config_pdo_entry_t entry;
|
|
107 |
ec_ioctl_config_sdo_t sdo;
|
|
108 |
|
|
109 |
for (configIter = configList.begin();
|
|
110 |
configIter != configList.end();
|
|
111 |
configIter++) {
|
|
112 |
|
|
113 |
cout << "Alias: "
|
|
114 |
<< dec << configIter->alias << endl
|
|
115 |
<< "Position: " << configIter->position << endl
|
|
116 |
<< "Vendor Id: 0x"
|
|
117 |
<< hex << setfill('0')
|
|
118 |
<< setw(8) << configIter->vendor_id << endl
|
|
119 |
<< "Product code: 0x"
|
|
120 |
<< setw(8) << configIter->product_code << endl
|
|
121 |
<< "Attached: " << (configIter->attached ? "yes" : "no") << endl
|
|
122 |
<< "Operational: " << (configIter->operational ? "yes" : "no") << endl;
|
|
123 |
|
|
124 |
for (j = 0; j < EC_MAX_SYNC_MANAGERS; j++) {
|
|
125 |
if (configIter->syncs[j].pdo_count) {
|
|
126 |
cout << "SM" << dec << j << " ("
|
|
127 |
<< (configIter->syncs[j].dir == EC_DIR_INPUT
|
|
128 |
? "Input" : "Output") << ")" << endl;
|
|
129 |
for (k = 0; k < configIter->syncs[j].pdo_count; k++) {
|
|
130 |
m.getConfigPdo(&pdo, configIter->config_index, j, k);
|
|
131 |
|
|
132 |
cout << " Pdo 0x" << hex
|
|
133 |
<< setw(4) << pdo.index
|
|
134 |
<< " \"" << pdo.name << "\"" << endl;
|
|
135 |
|
|
136 |
for (l = 0; l < pdo.entry_count; l++) {
|
|
137 |
m.getConfigPdoEntry(&entry,
|
|
138 |
configIter->config_index, j, k, l);
|
|
139 |
|
|
140 |
cout << " Pdo entry 0x" << hex
|
|
141 |
<< setw(4) << entry.index << ":"
|
|
142 |
<< setw(2) << (unsigned int) entry.subindex
|
|
143 |
<< ", " << dec << (unsigned int) entry.bit_length
|
|
144 |
<< " bit, \"" << entry.name << "\"" << endl;
|
|
145 |
}
|
|
146 |
}
|
|
147 |
}
|
|
148 |
}
|
|
149 |
|
|
150 |
cout << "Sdo configuration:" << endl;
|
|
151 |
if (configIter->sdo_count) {
|
|
152 |
for (j = 0; j < configIter->sdo_count; j++) {
|
|
153 |
m.getConfigSdo(&sdo, configIter->config_index, j);
|
|
154 |
|
|
155 |
cout << " 0x"
|
|
156 |
<< hex << setfill('0')
|
|
157 |
<< setw(4) << sdo.index << ":"
|
|
158 |
<< setw(2) << (unsigned int) sdo.subindex
|
|
159 |
<< ", " << dec << sdo.size << " byte: " << hex;
|
|
160 |
|
|
161 |
switch (sdo.size) {
|
|
162 |
case 1:
|
|
163 |
cout << "0x" << setw(2)
|
|
164 |
<< (unsigned int) *(uint8_t *) &sdo.data;
|
|
165 |
break;
|
|
166 |
case 2:
|
|
167 |
cout << "0x" << setw(4)
|
|
168 |
<< le16tocpu(*(uint16_t *) &sdo.data);
|
|
169 |
break;
|
|
170 |
case 4:
|
|
171 |
cout << "0x" << setw(8)
|
|
172 |
<< le32tocpu(*(uint32_t *) &sdo.data);
|
|
173 |
break;
|
|
174 |
default:
|
|
175 |
cout << "???";
|
|
176 |
}
|
|
177 |
|
|
178 |
cout << endl;
|
|
179 |
}
|
|
180 |
} else {
|
|
181 |
cout << " None." << endl;
|
|
182 |
}
|
|
183 |
|
|
184 |
cout << endl;
|
|
185 |
}
|
|
186 |
}
|
|
187 |
|
|
188 |
/*****************************************************************************/
|
|
189 |
|
|
190 |
/** Lists the bus configuration.
|
|
191 |
*/
|
|
192 |
void CommandConfig::listConfigs(const ConfigList &configList)
|
|
193 |
{
|
|
194 |
ConfigList::const_iterator configIter;
|
|
195 |
stringstream str;
|
|
196 |
Info info;
|
|
197 |
typedef list<Info> InfoList;
|
|
198 |
InfoList list;
|
|
199 |
InfoList::const_iterator iter;
|
|
200 |
unsigned int maxAliasWidth = 0, maxPosWidth = 0,
|
|
201 |
maxAttWidth = 0, maxOpWidth = 0;
|
|
202 |
|
|
203 |
for (configIter = configList.begin();
|
|
204 |
configIter != configList.end();
|
|
205 |
configIter++) {
|
|
206 |
|
|
207 |
str << dec << configIter->alias;
|
|
208 |
info.alias = str.str();
|
|
209 |
str.clear();
|
|
210 |
str.str("");
|
|
211 |
|
|
212 |
str << configIter->position;
|
|
213 |
info.pos = str.str();
|
|
214 |
str.clear();
|
|
215 |
str.str("");
|
|
216 |
|
|
217 |
str << hex << setfill('0')
|
|
218 |
<< "0x" << setw(8) << configIter->vendor_id
|
|
219 |
<< "/0x" << setw(8) << configIter->product_code;
|
|
220 |
info.ident = str.str();
|
|
221 |
str.clear();
|
|
222 |
str.str("");
|
|
223 |
|
|
224 |
str << (configIter->attached ? "attached" : "-");
|
|
225 |
info.att = str.str();
|
|
226 |
str.clear();
|
|
227 |
str.str("");
|
|
228 |
|
|
229 |
str << (configIter->operational ? "operational" : "-");
|
|
230 |
info.op = str.str();
|
|
231 |
str.clear();
|
|
232 |
str.str("");
|
|
233 |
|
|
234 |
list.push_back(info);
|
|
235 |
|
|
236 |
if (info.alias.length() > maxAliasWidth)
|
|
237 |
maxAliasWidth = info.alias.length();
|
|
238 |
if (info.pos.length() > maxPosWidth)
|
|
239 |
maxPosWidth = info.pos.length();
|
|
240 |
if (info.att.length() > maxAttWidth)
|
|
241 |
maxAttWidth = info.att.length();
|
|
242 |
if (info.op.length() > maxOpWidth)
|
|
243 |
maxOpWidth = info.op.length();
|
|
244 |
}
|
|
245 |
|
|
246 |
for (iter = list.begin(); iter != list.end(); iter++) {
|
|
247 |
cout << setfill(' ') << right
|
|
248 |
<< setw(maxAliasWidth) << iter->alias
|
|
249 |
<< ":" << left
|
|
250 |
<< setw(maxPosWidth) << iter->pos
|
|
251 |
<< " "
|
|
252 |
<< iter->ident
|
|
253 |
<< " "
|
|
254 |
<< setw(maxAttWidth) << iter->att << " "
|
|
255 |
<< setw(maxOpWidth) << iter->op << " "
|
|
256 |
<< endl;
|
|
257 |
}
|
|
258 |
}
|
|
259 |
|
|
260 |
/*****************************************************************************/
|