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