|
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 /*****************************************************************************/ |