Line data Source code
1 : // This file (util_main.cc) was created by Ron Rechenmacher <ron@fnal.gov> on
2 : // May 13, 2015. "TERMS AND CONDITIONS" governing this file are in the README
3 : // or COPYING file. If you do not have such a file, one can be obtained by
4 : // contacting Ron or Fermi Lab in Batavia IL, 60510, phone: 630-840-3000.
5 : // $RCSfile: .emacs.gnu,v $
6 : // rev="$Revision: 1.23 $$Date: 2012/01/23 15:32:40 $";
7 :
8 : #include <unistd.h> // usleep
9 : #include <chrono>
10 : #include <cmath>
11 : #include <cstdio> // printf
12 : #include <cstdlib> // strtoul
13 : #include <iomanip>
14 : #include <iostream>
15 : #include <string>
16 :
17 : #include "TRACE/tracemf.h"
18 : #define TRACE_NAME "rocUtil"
19 :
20 : #include "DTC.h"
21 :
22 : #define DCS_TLVL(b) b ? TLVL_DEBUG + 6 : TLVL_INFO
23 :
24 : using namespace DTCLib;
25 :
26 0 : void printHelpMsg()
27 : {
28 : std::cout << "Usage: rocUtil [options] "
29 : "[read_register,simple_read,reset_roc,write_register,read_extregister,write_extregister,test_read,read_release,"
30 0 : "toggle_serdes,block_read,block_write,raw_block_read]"
31 0 : << std::endl;
32 0 : std::cout << "Options are:" << std::endl
33 0 : << " -h: This message." << std::endl
34 0 : << " -l: Link to send requests on (Default: 0)" << std::endl
35 0 : << " -n: Number of times to repeat test. (Default: 1)" << std::endl
36 0 : << " -d: Delay between tests, in us (Default: 0)." << std::endl
37 0 : << " -w: Data to write to address" << std::endl
38 0 : << " -a: Address to write" << std::endl
39 0 : << " -b: Block address (for write_rocext)" << std::endl
40 0 : << " -q: Quiet mode (Don't print requests)" << std::endl
41 0 : << " -Q: Really Quiet mode (Try not to print anything)" << std::endl
42 0 : << " -v: Expected DTC Design version string (Default: \"\")" << std::endl
43 0 : << " -c: Word count for Block Reads (Default: 0)" << std::endl
44 0 : << " -i: Do not set the incrementAddress bit for block operations" << std::endl
45 0 : << " --dtc: Use dtc <num> (Defaults to DTCLIB_DTC if set, 0 otherwise, see ls /dev/mu2e* for available DTCs)" << std::endl
46 0 : << " --stop-on-error: Abort operation if an error occurs" << std::endl
47 : << " --timeout-ms Try this long to read a DCS DMA from the DTC (Default: 10 ms)"
48 0 : << " --link-mask ROC links to enable on DTC (Default: 0x111111)";
49 0 : exit(0);
50 : }
51 :
52 0 : int main(int argc, char* argv[])
53 : {
54 0 : auto quiet = false;
55 0 : auto reallyQuiet = false;
56 0 : unsigned link = 0;
57 0 : unsigned delay = 0;
58 0 : unsigned number = 1;
59 0 : unsigned address = 0;
60 0 : unsigned data = 0;
61 0 : unsigned block = 0;
62 0 : unsigned tmo_ms = 10;
63 0 : unsigned link_mask = 0x111111;
64 0 : size_t count = 0;
65 0 : bool incrementAddress = true;
66 0 : std::string op = "";
67 0 : int dtc = -1;
68 0 : bool stopOnError = false;
69 :
70 0 : for (auto optind = 1; optind < argc; ++optind)
71 : {
72 0 : if (argv[optind][0] == '-')
73 : {
74 0 : switch (argv[optind][1])
75 : {
76 0 : case 'l':
77 0 : link = DTCLib::Utilities::getOptionValue(&optind, &argv);
78 0 : break;
79 0 : case 'd':
80 0 : delay = DTCLib::Utilities::getOptionValue(&optind, &argv);
81 0 : break;
82 0 : case 'n':
83 0 : number = DTCLib::Utilities::getOptionValue(&optind, &argv);
84 0 : break;
85 0 : case 'w':
86 0 : data = DTCLib::Utilities::getOptionValue(&optind, &argv);
87 0 : break;
88 0 : case 'a':
89 0 : address = DTCLib::Utilities::getOptionValue(&optind, &argv);
90 0 : break;
91 0 : case 'b':
92 0 : block = DTCLib::Utilities::getOptionValue(&optind, &argv);
93 0 : break;
94 0 : case 'c':
95 0 : count = DTCLib::Utilities::getOptionValue(&optind, &argv);
96 0 : break;
97 0 : case 'i':
98 0 : incrementAddress = !incrementAddress;
99 0 : break;
100 0 : case 'q':
101 0 : quiet = true;
102 0 : break;
103 0 : case 'Q':
104 0 : quiet = true;
105 0 : reallyQuiet = true;
106 0 : break;
107 0 : case '-': // Long option
108 : {
109 0 : auto option = DTCLib::Utilities::getLongOptionOption(&optind, &argv);
110 0 : if (option == "--dtc")
111 : {
112 0 : dtc = DTCLib::Utilities::getLongOptionValue(&optind, &argv);
113 : }
114 0 : else if (option == "--stop-on-error")
115 : {
116 0 : stopOnError = true;
117 : }
118 0 : else if (option == "--timeout-ms")
119 : {
120 0 : tmo_ms = DTCLib::Utilities::getLongOptionValue(&optind, &argv);
121 : }
122 0 : else if (option == "--link-mask")
123 : {
124 0 : link_mask = DTCLib::Utilities::getLongOptionValue(&optind, &argv);
125 : }
126 0 : else if (option == "--help")
127 : {
128 0 : printHelpMsg();
129 : }
130 0 : break;
131 0 : }
132 0 : default:
133 0 : TLOG(TLVL_ERROR) << "Unknown option: " << argv[optind] << std::endl;
134 0 : printHelpMsg();
135 0 : break;
136 0 : case 'h':
137 0 : printHelpMsg();
138 0 : break;
139 : }
140 : }
141 : else
142 : {
143 0 : op = std::string(argv[optind]);
144 : }
145 : }
146 :
147 0 : if (op == "simple_read")
148 : {
149 0 : TRACE_CNTL("modeS", 0);
150 : }
151 :
152 0 : TLOG(TLVL_DEBUG) << "Options are: " << std::boolalpha
153 0 : << "Operation: " << std::string(op)
154 0 : << ", Num: " << number
155 0 : << ", Link: " << link
156 0 : << ", Link Mask: " << std::hex << std::showbase << link_mask << std::dec
157 0 : << ", Delay: " << delay
158 0 : << ", Address: " << address
159 0 : << ", Data: " << data
160 0 : << ", Block: " << block
161 0 : << ", Quiet Mode: " << quiet
162 0 : << ", Really Quiet Mode: " << reallyQuiet
163 0 : << std::endl;
164 :
165 0 : auto dtc_link = static_cast<DTC_Link_ID>(link);
166 0 : link_mask |= 1 << (link * 4); // Always enable the link being tested
167 0 : auto thisDTC = new DTC(DTC_SimMode_NoCFO, dtc, link_mask); // rocMask is in hex, not binary
168 0 : auto device = thisDTC->GetDevice();
169 :
170 0 : if (op == "read_register")
171 : {
172 0 : for (unsigned ii = 0; ii < number; ++ii)
173 : {
174 0 : TLOG(DCS_TLVL(reallyQuiet)) << "Operation \"read_register\" " << ii << std::endl;
175 : try
176 : {
177 0 : auto rocdata = thisDTC->ReadROCRegister(dtc_link, address, tmo_ms);
178 0 : TLOG(DCS_TLVL(reallyQuiet)) << "ROC " << dtc_link << " returned " << rocdata << " for address " << address;
179 : }
180 0 : catch (std::runtime_error& err)
181 : {
182 0 : TLOG(TLVL_ERROR) << "Error reading from ROC on iteration " << ii << ": " << err.what();
183 0 : if (stopOnError) break;
184 0 : }
185 : }
186 : }
187 0 : else if (op == "simple_read")
188 : {
189 0 : TLOG(TLVL_DEBUG) << "Operation \"simple_read\"" << std::endl;
190 0 : for (unsigned ii = 0; ii < number; ++ii)
191 : {
192 0 : TLOG(DCS_TLVL(reallyQuiet)) << "Simple Read " << ii << std::endl;
193 : try
194 : {
195 0 : auto rocdata = thisDTC->ReadROCRegister(dtc_link, address, tmo_ms);
196 0 : std::cout << std::dec << ii << " " << std::hex << std::showbase << rocdata << std::endl;
197 0 : TLOG(DCS_TLVL(reallyQuiet)) << "ROC " << dtc_link << " returned " << rocdata << " for address " << address;
198 : }
199 0 : catch (std::runtime_error& err)
200 : {
201 0 : TLOG(TLVL_ERROR) << "Error reading from ROC on iteration " << ii << ": " << err.what();
202 0 : if (stopOnError) break;
203 0 : }
204 : }
205 : }
206 0 : else if (op == "reset_roc")
207 : {
208 0 : TLOG(TLVL_DEBUG) << "Operation \"reset_roc\"" << std::endl;
209 0 : thisDTC->WriteExtROCRegister(dtc_link, 12, 1, 0x11, false, tmo_ms);
210 0 : thisDTC->WriteExtROCRegister(dtc_link, 11, 1, 0x11, false, tmo_ms);
211 0 : thisDTC->WriteExtROCRegister(dtc_link, 10, 1, 0x11, false, tmo_ms);
212 0 : thisDTC->WriteExtROCRegister(dtc_link, 9, 1, 0x11, false, tmo_ms);
213 0 : thisDTC->WriteExtROCRegister(dtc_link, 8, 1, 0x11, false, tmo_ms);
214 : }
215 0 : else if (op == "write_register")
216 : {
217 0 : for (unsigned ii = 0; ii < number; ++ii)
218 : {
219 : try
220 : {
221 0 : TLOG(TLVL_DEBUG) << "Operation \"write_register\" " << ii << std::endl;
222 0 : thisDTC->WriteROCRegister(dtc_link, address, data, false, tmo_ms);
223 : }
224 0 : catch (std::runtime_error& err)
225 : {
226 0 : TLOG(TLVL_ERROR) << "Error writing to ROC on iteration " << ii << ": " << err.what();
227 0 : if (stopOnError) break;
228 0 : }
229 : }
230 : }
231 0 : else if (op == "read_extregister")
232 : {
233 0 : for (unsigned ii = 0; ii < number; ++ii)
234 : {
235 : try
236 : {
237 0 : TLOG(DCS_TLVL(reallyQuiet)) << "Operation \"read_extregister\" " << ii << std::endl;
238 0 : auto rocdata = thisDTC->ReadExtROCRegister(dtc_link, block, address, tmo_ms);
239 0 : TLOG(DCS_TLVL(reallyQuiet)) << "ROC " << dtc_link << " returned " << rocdata << " for address " << address << ", block " << block;
240 : }
241 0 : catch (std::runtime_error& err)
242 : {
243 0 : TLOG(TLVL_ERROR) << "Error reading from ROC on iteration " << ii << ": " << err.what();
244 0 : if (stopOnError) break;
245 0 : }
246 : }
247 : }
248 0 : else if (op == "write_extregister")
249 : {
250 0 : for (unsigned ii = 0; ii < number; ++ii)
251 : {
252 : try
253 : {
254 0 : TLOG(TLVL_DEBUG) << "Operation \"write_extregister\" " << ii << std::endl;
255 0 : thisDTC->WriteExtROCRegister(dtc_link, block, address, data, false, tmo_ms);
256 : }
257 0 : catch (std::runtime_error& err)
258 : {
259 0 : TLOG(TLVL_ERROR) << "Error writing to ROC on iteration " << ii << ": " << err.what();
260 0 : if (stopOnError) break;
261 0 : }
262 : }
263 : }
264 0 : else if (op == "test_read")
265 : {
266 0 : TLOG(TLVL_DEBUG) << "Operation \"test_read\"" << std::endl;
267 :
268 : // device->begin_dcs_transaction();
269 : // thisDTC->SendDCSRequestPacket(dtc_link, DTC_DCSOperationType_Read, address, quiet);
270 :
271 0 : for (unsigned ii = 0; ii < number; ++ii)
272 : {
273 0 : TLOG(DCS_TLVL(reallyQuiet)) << "Buffer Read " << ii << std::endl;
274 : mu2e_databuff_t* buffer;
275 0 : auto tmo_ms = 1500;
276 0 : device->begin_dcs_transaction();
277 0 : auto sts = device->read_data(DTC_DMA_Engine_DCS, reinterpret_cast<void**>(&buffer), tmo_ms);
278 :
279 0 : TLOG(TLVL_DEBUG) << "util - read for DCS - ii=" << ii << ", sts=" << sts << ", buffer=" << (void*)buffer;
280 0 : if (sts > 0)
281 : {
282 0 : auto bufSize = *reinterpret_cast<uint64_t*>(&buffer[0]);
283 0 : TLOG(TLVL_DEBUG) << "util - bufSize is " << bufSize;
284 :
285 0 : if (!reallyQuiet)
286 : {
287 0 : for (unsigned line = 0; line < static_cast<unsigned>(ceil((bufSize - 8) / 16)); ++line)
288 : {
289 0 : TLOG(TLVL_INFO) << "0x" << std::hex << std::setw(5) << std::setfill('0') << line << "0: ";
290 : // for (unsigned byte = 0; byte < 16; ++byte)
291 0 : for (unsigned byte = 0; byte < 8; ++byte)
292 : {
293 0 : if (line * 16 + 2 * byte < bufSize - 8u)
294 : {
295 0 : auto thisWord = reinterpret_cast<uint16_t*>(buffer)[4 + line * 8 + byte];
296 : // uint8_t thisWord = (((uint8_t*)buffer)[8 + (line * 16) + byte]);
297 0 : TLOG(TLVL_INFO) << std::setw(4) << static_cast<int>(thisWord) << " ";
298 : }
299 : }
300 0 : TLOG(TLVL_INFO) << std::endl;
301 : }
302 : }
303 : }
304 0 : device->read_release(DTC_DMA_Engine_DCS, 1);
305 0 : device->end_dcs_transaction();
306 :
307 0 : if (sts <= 0 && stopOnError)
308 : {
309 0 : TLOG(TLVL_ERROR) << "util - read for DCS: Error occurred, aborting!";
310 0 : break;
311 : }
312 :
313 0 : if (delay > 0) usleep(delay);
314 : }
315 : }
316 0 : else if (op == "toggle_serdes")
317 : {
318 0 : if (!thisDTC->ReadSERDESOscillatorClock())
319 : {
320 0 : TLOG(TLVL_INFO) << "Setting SERDES Oscillator Clock to 2.5 Gbps" << std::endl;
321 0 : thisDTC->SetSERDESOscillatorClock(DTC_SerdesClockSpeed_25Gbps);
322 : }
323 : else
324 : {
325 0 : TLOG(TLVL_INFO) << "Setting SERDES Oscillator Clock to 3.125 Gbps" << std::endl;
326 0 : thisDTC->SetSERDESOscillatorClock(DTC_SerdesClockSpeed_3125Gbps);
327 : }
328 : }
329 0 : else if (op == "read_release")
330 : {
331 0 : TLOG(TLVL_DEBUG) << "Operation \"read_release\"";
332 0 : for (unsigned ii = 0; ii < number; ++ii)
333 : {
334 : void* buffer;
335 0 : auto tmo_ms = 0;
336 0 : device->begin_dcs_transaction();
337 0 : auto stsRD = device->read_data(DTC_DMA_Engine_DCS, &buffer, tmo_ms);
338 0 : auto stsRL = device->read_release(DTC_DMA_Engine_DCS, 1);
339 0 : device->end_dcs_transaction();
340 0 : TLOG(TLVL_DEBUG + 7) << "dcs - release/read for DCS ii=" << ii << ", stsRD=" << stsRD << ", stsRL=" << stsRL << ", buffer=" << buffer;
341 0 : if (delay > 0) usleep(delay);
342 : }
343 : }
344 0 : else if (op == "block_read")
345 : {
346 0 : TLOG(TLVL_DEBUG) << "Operation \"block_read\"";
347 0 : for (unsigned ii = 0; ii < number; ++ii)
348 : {
349 0 : TLOG(DCS_TLVL(reallyQuiet)) << "Block Read " << ii << std::endl;
350 : try
351 : {
352 0 : std::vector<uint16_t> data(count);
353 0 : thisDTC->ReadROCBlock(data, dtc_link, address, count, incrementAddress, tmo_ms);
354 0 : DTCLib::Utilities::PrintBuffer(&data[0], data.size() * sizeof(uint16_t));
355 0 : }
356 0 : catch (std::runtime_error& err)
357 : {
358 0 : TLOG(TLVL_ERROR) << "Error reading from ROC on iteration " << ii << ": " << err.what();
359 0 : if (stopOnError) break;
360 0 : }
361 : }
362 : }
363 0 : else if (op == "block_write")
364 : {
365 0 : TLOG(TLVL_DEBUG) << "Operation \"block_write\"";
366 0 : for (unsigned ii = 0; ii < number; ++ii)
367 : {
368 0 : TLOG(DCS_TLVL(reallyQuiet)) << "Block Write " << ii << std::endl;
369 : try
370 : {
371 0 : std::vector<uint16_t> blockData;
372 0 : for (size_t ii = 0; ii < count; ++ii)
373 : {
374 0 : blockData.push_back(static_cast<uint16_t>(ii));
375 : }
376 0 : thisDTC->WriteROCBlock(dtc_link, address, blockData, false, incrementAddress, tmo_ms);
377 0 : }
378 0 : catch (std::runtime_error& err)
379 : {
380 0 : TLOG(TLVL_ERROR) << "Error writing to ROC on iteration " << ii << ": " << err.what();
381 0 : if (stopOnError) break;
382 0 : }
383 : }
384 : }
385 0 : else if (op == "raw_block_read")
386 : {
387 0 : TLOG(TLVL_DEBUG) << "Operation \"raw_block_read\"";
388 0 : for (unsigned ii = 0; ii < number; ++ii)
389 : {
390 0 : TLOG(DCS_TLVL(reallyQuiet)) << "Raw Block Read " << ii << std::endl;
391 : try
392 : {
393 0 : DTC_DCSRequestPacket req(dtc_link, DTC_DCSOperationType_BlockRead, false, incrementAddress, address, count);
394 :
395 0 : TLOG(TLVL_TRACE) << "rocUtil raw_block_read: before WriteDMADCSPacket - DTC_DCSRequestPacket";
396 :
397 0 : thisDTC->ReleaseAllBuffers(DTC_DMA_Engine_DCS);
398 :
399 0 : if (!thisDTC->ReadDCSReception()) thisDTC->EnableDCSReception();
400 :
401 : mu2e_databuff_t* buffer;
402 0 : auto tmo_ms = 1500;
403 :
404 0 : thisDTC->GetDevice()->begin_dcs_transaction();
405 0 : thisDTC->WriteDMAPacket(req);
406 0 : TLOG(TLVL_TRACE) << "rocUtil raw_block_read: after WriteDMADCSPacket - DTC_DCSRequestPacket";
407 0 : usleep(2500);
408 0 : auto sts = device->read_data(DTC_DMA_Engine_DCS, reinterpret_cast<void**>(&buffer), tmo_ms);
409 0 : device->read_release(DTC_DMA_Engine_DCS, 1);
410 0 : thisDTC->GetDevice()->end_dcs_transaction();
411 0 : TLOG(TLVL_TRACE) << "rocUtil raw_block_read: after DCS read_data - "
412 0 : << " sts=" << sts << ", buffer=" << (void*)buffer;
413 :
414 0 : if (sts > 0)
415 : {
416 0 : void* readPtr = &buffer[0];
417 0 : auto bufSize = static_cast<uint16_t>(*static_cast<uint64_t*>(readPtr));
418 0 : readPtr = static_cast<uint8_t*>(readPtr) + 8;
419 0 : TLOG((reallyQuiet ? TLVL_DEBUG + 5 : TLVL_INFO)) << "Buffer reports DMA size of " << std::dec << bufSize << " bytes. Device driver reports read of "
420 0 : << sts << " bytes," << std::endl;
421 :
422 0 : TLOG(TLVL_TRACE) << "util - bufSize is " << bufSize;
423 :
424 0 : if (!reallyQuiet)
425 : {
426 0 : DTCLib::Utilities::PrintBuffer(buffer, sts >= bufSize ? sts : bufSize);
427 : }
428 : }
429 0 : if (delay > 0) usleep(delay);
430 0 : }
431 0 : catch (std::runtime_error& err)
432 : {
433 0 : TLOG(TLVL_ERROR) << "Error reading from ROC on iteration " << ii << ": " << err.what();
434 0 : if (stopOnError) break;
435 0 : }
436 : }
437 : }
438 : else
439 : {
440 0 : TLOG(TLVL_ERROR) << "Unrecognized operation: " << op << std::endl;
441 0 : printHelpMsg();
442 : }
443 :
444 0 : delete thisDTC;
445 :
446 0 : if (op == "simple_read")
447 : {
448 0 : TRACE_CNTL("modeS", 1);
449 : }
450 0 : return 0;
451 0 : } // main
|