00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <ctype.h>
00012 #include <errno.h>
00013 #include <signal.h>
00014 #include <sys/time.h>
00015 #include <time.h>
00016 #include <unistd.h>
00017 #include <stdio.h>
00018 #include <string.h>
00019
00020
00021 #include <math.h>
00022
00023 #include <cmath>
00024 #include <cstdlib>
00025
00026 #include <algorithm>
00027 #include <iostream>
00028 #include <string>
00029 #include <vector>
00030 #include <map>
00031 #include <fstream>
00032 #include <memory>
00033
00034 #include <readline/readline.h>
00035 #include <readline/history.h>
00036
00037 #include "boost/format.hpp"
00038
00039 #include "roc/defines_roc.h"
00040 #include "base/defines_gpio.h"
00041 #include "nxyter/defines_nxyter.h"
00042 #include "roc/defines_udp.h"
00043 #include "roc/defines_optic.h"
00044
00045 #include "base/Board.h"
00046 #include "sp605/Board.h"
00047 #include "roc/Board.h"
00048 #include "base/Gpio.h"
00049 #include "roc/I2cDevice.h"
00050 #include "roc/UdpBoard.h"
00051 #include "nxyter/RocNx.h"
00052 #include "nxyter/FebBase.h"
00053 #include "nxyter/Feb1nxGenB.h"
00054 #include "nxyter/Feb1nxGenC.h"
00055 #include "nxyter/Feb1nxGenD.h"
00056 #include "nxyter/Feb2nxGas.h"
00057 #include "nxyter/Feb4nxBT.h"
00058 #include "nxyter/NxI2c.h"
00059 #include "nxyter/NxContext.h"
00060 #include "nxyter/FebUtil.h"
00061 #include "nxyter/QuickDaq.h"
00062 #include "nxyter/DistFunc.h"
00063 #include "nxyter/DistFuncArray.h"
00064 #include "nxyter/NxDataSummary.h"
00065 #include "feet/RocFeet.h"
00066
00067 base::Board* gBaseBoard = 0;
00068 roc::Board* gRocBoard = 0;
00069 sp605::Board* gSP605Board = 0;
00070 base::Gpio* gGpio = 0;
00071 nxyter::RocNx* gRocNx = 0;
00072 nxyter::FebBase* gFeb = 0;
00073 nxyter::QuickDaq* gQdaq = 0;
00074 nxyter::FebUtil* gUtil = 0;
00075
00076 std::string gBoardName;
00077
00078 int gIntCount = 0;
00079
00080 std::vector<std::string> argspos;
00081 std::vector<std::string> argsopt;
00082
00083 enum ArgNeedConstants {
00084 kNeedBoard = (1<<0),
00085 kNeedRocBoard = (1<<1),
00086 kNeedFeb = (1<<2),
00087 kNeedDaq = (1<<3),
00088 };
00089
00090
00091
00092
00093 int cmd_autoped();
00094 int cmd_autosettrh();
00095 int cmd_autotrim();
00096 int cmd_autovbiass();
00097 int cmd_board();
00098 int cmd_discover();
00099 int cmd_dlm();
00100 int cmd_feb();
00101 int cmd_firepulser();
00102 int cmd_getadcdirect();
00103 int cmd_geti2c();
00104 int cmd_puti2c();
00105 int cmd_getnx();
00106 int cmd_getroc();
00107 int cmd_help();
00108 int cmd_ident();
00109 int cmd_idsigch();
00110 int cmd_initfeb();
00111 int cmd_printadc();
00112 int cmd_printdata();
00113 int cmd_printdatadbg();
00114 int cmd_printfeb();
00115 int cmd_printgpio();
00116 int cmd_printid();
00117 int cmd_printmon();
00118 int cmd_printnx();
00119 int cmd_printroc();
00120 int cmd_printrocmap();
00121 int cmd_printstatus();
00122 int cmd_putroc();
00123 int cmd_quit();
00124 int cmd_resetnxi2cbus();
00125 int cmd_resetnxi2creg();
00126 int cmd_resetrocnxts();
00127 int cmd_restartbrd();
00128 int cmd_saverocconf();
00129 int cmd_scanadclat();
00130 int cmd_scanmonadc();
00131 int cmd_scanvbiasf();
00132 int cmd_scanvbiass();
00133 int cmd_setadc();
00134 int cmd_setadcclock();
00135 int cmd_setadcdef();
00136 int cmd_setadcpatt();
00137 int cmd_setaux();
00138 int cmd_setdebug();
00139 int cmd_setfebdef();
00140 int cmd_seti2c();
00141 int cmd_setlhwater();
00142 int cmd_setnx();
00143 int cmd_setnxaddr();
00144 int cmd_setnxdef();
00145 int cmd_setnxmask();
00146 int cmd_setnxmode();
00147 int cmd_setnxoff();
00148 int cmd_setnxpower();
00149 int cmd_setnxtrim();
00150 int cmd_setbrddef();
00151 int cmd_setrocdef();
00152 int cmd_setsyncm();
00153 int cmd_setsyncs();
00154 int cmd_settrace();
00155 int cmd_testadccntl();
00156 int cmd_testadcdata();
00157 int cmd_testfebcntl();
00158 int cmd_testnxcntl();
00159 int cmd_testnxdata();
00160 int cmd_testnxregs();
00161 int cmd_testrocaux();
00162 int cmd_testrocsync();
00163
00164
00165 typedef struct
00166 {
00167 const char* name;
00168 int (*func)();
00169 const char* shelp;
00170 const char* lhelp;
00171 } cmditem_t;
00172
00173
00174
00175 std::vector<cmditem_t*> cmdlist;
00176
00177
00178 cmditem_t cmdlist_base[] = {
00179 { name: "help|h",
00180 func: cmd_help,
00181 shelp:"[-g -v|command] : help on rocutil and its commands",
00182 lhelp:" -g gives general help on using rocutil\n"
00183 " -v gives full help test for all commands\n"
00184 " -a gives list of command abbreviations\n"
00185 " command gives help text for the given command"
00186 },
00187 { name: "board|b",
00188 func: cmd_board,
00189 shelp:"brdname : connect to board",
00190 lhelp:" brdname address of the board to connect\n"
00191 " Note: connection mode (DAQ, Control, or Observer) could be specified as\n"
00192 " optional argument like cbmtest03?Control. Default is DAQ mode\n"
00193 " Example of valid addresses: \n"
00194 " board=cbmtest08 - udp connection to ROC board with address cbmtest08\n"
00195 " board=140.181.115.234?Control - udp connection to ROC board with specified IP in control mode\n"
00196 " board=abb1 - optic connection to ROC board, connected via second SFP\n"
00197 " board=optic://abb13/sp605 - optic connection to SP605 board, connected via second SFP on ABB and forth SFP on DCB"
00198 },
00199 { name: "quit|q",
00200 func: cmd_quit,
00201 shelp:"exit program",
00202 lhelp:""
00203 },
00204 { name: 0,
00205 func: 0,
00206 shelp:0,
00207 lhelp:0
00208 }
00209 };
00210
00212 cmditem_t cmdlist_board[] = {
00213 { name: "getroc|get",
00214 func: cmd_getroc,
00215 shelp:"aname : direct get() from board control space !! EXPERT ONLY !!",
00216 lhelp:" aname symbolic name of the board control space resource"
00217 },
00218 { name: "putroc|put",
00219 func: cmd_putroc,
00220 shelp:"aname,val : direct put() to board control space !! EXPERT ONLY !!",
00221 lhelp:" aname symbolic name of the board control space resource\n"
00222 " val value to be written"
00223 },
00224 { name: "ident|id",
00225 func: cmd_ident,
00226 shelp:" : print connection data and current time",
00227 lhelp:""
00228 },
00229 { name: "printrocmap|printmap",
00230 func: cmd_printrocmap,
00231 shelp:"[-n] : print board control space address map !! FOR EXPERTS !!",
00232 lhelp:" -n sort by name (default is sort by address)"
00233 },
00234 { name: "restartbrd",
00235 func: cmd_restartbrd,
00236 shelp:"restart board !! THINK BEFORE !!",
00237 lhelp:" Note: this command will disconnect the board/feb !!!\n"
00238 " restart rocutil and used 'setbrddef' to initialize board"
00239 },
00240 { name: "setbrddef",
00241 func: cmd_setbrddef,
00242 shelp:" : set board registers to default values",
00243 lhelp:""
00244 },
00245 { name: "geti2c",
00246 func: cmd_geti2c,
00247 shelp:"[-l -w] addr,reg : read from I2C selected device",
00248 lhelp:" -l scope loop (repeat until ^C)\n"
00249 " -w 16 bit access (default is 8 bit)\n"
00250 " addr I2C slave address (0:127)\n"
00251 " reg device register number (0:255)"
00252 },
00253 { name: "puti2c",
00254 func: cmd_puti2c,
00255 shelp:"addr,reg,value : write I2C register",
00256 lhelp:" addr I2C slave address (0:127)\n"
00257 " reg device register number (0:255)"
00258 " value register value (0:255)"
00259 },
00260 { name: "printdata|pd",
00261 func: cmd_printdata,
00262 shelp:"[-m -r -h -t -s -d -n -ia][nmsg,time,npuls,pper,pdly] : print data",
00263 lhelp:" -m print messages (default if no -s -d given)\n"
00264 " -r print messages in raw format (def is human readable)\n"
00265 " -h print hex dump of message\n"
00266 " -t print wall clock timestamp in front of message\n"
00267 " -s print statistics\n"
00268 " -d print nx distribution parameters\n"
00269 " -n no ROC initialization, use ROC config as is\n"
00270 " -ia init nx/roc timestamp system after DAQ start\n"
00271 " nmsg number of messages to print (def=100, see Note below)\n"
00272 " time maximal time to look for data (def=10., see Note below)\n"
00273 " npuls if >0 fire pulser, send np pulses (0:32767, def=0)\n"
00274 " pper pulser period in units of 4ns (2:2^24, def=100000)\n"
00275 " pwth pulser period in units of 4ns (-2^24:2^24, def=32)\n"
00276 " pdly pulser delay in units of 4ns (1:65535, def=1000)\n"
00277 " Note: if neither nmsg nor time is specified, the defaults of\n"
00278 " nmsg=100 and time=10. are used. If only one of the two\n"
00279 " is specified, the other is unlimited\n"
00280 " Note 2: One could use pd for printout of messages from lmd file.\n"
00281 " One can do \"rocutil b=file.lmd pd\". In this case all \n"
00282 " messages will be printout if other not specified."
00283 },
00284 { name: 0,
00285 func: 0,
00286 shelp:0,
00287 lhelp:0
00288 }
00289 };
00290
00291
00293 cmditem_t cmdlist_sp605[] = {
00294 { name: "set605def",
00295 func: cmd_setrocdef,
00296 shelp:" : set SP605 registers to default values",
00297 lhelp:" Note: use after board boot"
00298 },
00299 { name: 0,
00300 func: 0,
00301 shelp:0,
00302 lhelp:0
00303 }
00304 };
00305
00307 cmditem_t cmdlist_nxyter[] = {
00308 { name: "feb|f",
00309 func: cmd_feb,
00310 shelp:"[port,type] : configure feb",
00311 lhelp:" port port number, default is first available\n"
00312 " type feb type either Feb1nxGen[BCD], Feb2nxGas,\n"
00313 " Feb4nxBT, if omitted the discoverFebs() autodetect\n"
00314 " heuristics is used\n"
00315 " Note: Feb1nxGenB MUST be configured manually, the autodetect\n"
00316 " will recognize them as errorously as Feb1nxGenC !!"
00317 },
00318 { name: "getnx|gx",
00319 func: cmd_getnx,
00320 shelp:"nx,reg : read nXYTER register reg",
00321 lhelp:" nx nXYTER index ('*' for all or specific index)\n"
00322 " reg nXYTER register number"
00323 },
00324 { name: "initfeb|if",
00325 func: cmd_initfeb,
00326 shelp:" : set nx on/off flags to ROC",
00327 lhelp:""
00328 },
00329 { name: "printadc|pa",
00330 func: cmd_printadc,
00331 shelp:"prints device registers the MainAdc of a FEB",
00332 lhelp:""
00333 },
00334 { name: "printfeb|pf",
00335 func: cmd_printfeb,
00336 shelp:"[-m -c -t -a] : prints all device registers of a FEB",
00337 lhelp:" -m print only nXYTER mask part\n"
00338 " -c print only nXYTER core part (default unless -m -c -t -a)\n"
00339 " -t print only nXYTER trim part\n"
00340 " -a print all parts\n"
00341 },
00342 { name: "printnx|px",
00343 func: cmd_printnx,
00344 shelp:"[-m -c -t -a][nx] : print device registers one nXYTER of a FEB",
00345 lhelp:" -m print only mask part\n"
00346 " -c print only core part (default unless -m -c -t -a given)\n"
00347 " -t print only trim part\n"
00348 " -a print all parts\n"
00349 " nx nXYTER index ('*' for all or specific index)"
00350 },
00351 { name: "resetnxi2cbus",
00352 func: cmd_resetnxi2cbus,
00353 shelp:"reset I2C bus state machine in all nXYTER",
00354 lhelp:""
00355 },
00356 { name: "resetnxi2creg",
00357 func: cmd_resetnxi2creg,
00358 shelp:"reset all I2C registers to power-up defauls in all nXYTER",
00359 lhelp:""
00360 },
00361 { name: "setadc",
00362 func: cmd_setadc,
00363 shelp:"reg,val : set ADC register reg to val",
00364 lhelp:" reg ADC register number\n"
00365 " val new value\n"
00366 },
00367 { name: "setnx|sx",
00368 func: cmd_setnx,
00369 shelp:"nx,reg,val : set for nXYTER nx the register reg to val",
00370 lhelp:" nx nXYTER index ('*' for all or specific index)\n"
00371 " reg nXYTER register number\n"
00372 " val new value\n"
00373 },
00374 { name: "setnxaddr",
00375 func: cmd_setnxaddr,
00376 shelp:"nx,addr : set I2C slave address for nXYTER",
00377 lhelp:" nx nXYTER index\n"
00378 " addr nXYTER I2C slave address"
00379 },
00380 { name: "setnxdef|sxd",
00381 func: cmd_setnxdef,
00382 shelp:"[nx,pos] : set nXYTER registers to default values",
00383 lhelp:" nx nXYTER index ('*' for all or specific index, def=*)\n"
00384 " pos if 1 than nXYTER is setup for positive signals\n"
00385 },
00386 { name: "setnxmask|sxm",
00387 func: cmd_setnxmask,
00388 shelp:"nx,[val,ibeg,iend,istep] : set channel-off mask to val in range",
00389 lhelp:" nx nXYTER index ('*' for all or specific index)\n"
00390 " val channel-off bit, 1 means off (0:1, def=0)\n"
00391 " ibeg first channel number (0:127, def=0)\n"
00392 " iend last channel number (0:127, def=127)\n"
00393 " istep cha. num. increment, touch ibeg+n*istep (1:64, def=1)"
00394 },
00395 { name: "setnxmode|sxmo",
00396 func: cmd_setnxmode,
00397 shelp:"nx,[tpul,ttri,csel] : set test pulser and test trigger modes",
00398 lhelp:" nx nXYTER index ('*' for all or specific index)\n"
00399 " tpul test pulser mode flag (0:1, def=0)\n"
00400 " ttri test trigger mode flag (0:1, def=0)\n"
00401 " csel calibration group select (0:3, def=3)\n"
00402 " Note: the csel default is 3 to have test channel 128 active"
00403 },
00404 { name: "setfebdef|sfd",
00405 func: cmd_setfebdef,
00406 shelp:"[pos0,pos1] : set ADC and nXYTER registers to default values",
00407 lhelp:" pos0 if 1 setup 1st half of nXYTER for positive signals\n"
00408 " pos1 if 1 setup 2nd half of nXYTER for positive signals"
00409 },
00410 { name: "firepulser|fp",
00411 func: cmd_firepulser,
00412 shelp:"[-a -s][per,wth,num,dly] : fire test pulse train",
00413 lhelp:" -a setup AUX2, enable ext&alt, or if -s disable ext\n"
00414 " -s stop pulse train\n"
00415 " per period in units of 4ns (2:2^24, def=100000)\n"
00416 " wth width in units of 4ns (-2^24:+2^24, def=350)\n"
00417 " num number of pulses (0:32768, def=0)\n"
00418 " dly delay after reset in units of 4ns (0:65535, def=0)\n"
00419 " Note: number=0 causes permanent pulse activity\n"
00420 " to terminate this do 'firepulser -s'\n"
00421 " Note: 'firepulser' will cause continuous 2.5 kHz pulsing"
00422 },
00423 { name: 0,
00424 func: 0,
00425 shelp:0,
00426 lhelp:0
00427 }
00428 };
00429
00430 cmditem_t cmdlist_gpio[] = {
00431 { name: "setaux|sa",
00432 func: cmd_setaux,
00433 shelp:"ch,[re,fe,thr,ext,alt] : setup aux channel",
00434 lhelp:" ch channel number (0:3)\n"
00435 " re rising edge enable flag (0:1, def=0)\n"
00436 " fe falling edge enable flag (0:1, def=0)\n"
00437 " thr throttled option (0:1, def=1)\n"
00438 " ext enable TP_in(2) Thr_In(3) (0:1, def=0)\n"
00439 " alt use alt. input TP_busy(1),TP_gen(2),Thr_out(3) (0:1,def=0)"
00440 },
00441 { name: "setsyncm|ssm",
00442 func: cmd_setsyncm,
00443 shelp:"scale[,baud]: set sync message sender",
00444 lhelp:" scale rate scale-down (0:21)\n"
00445 " baud baud rate in MHz (def=62.5)"
00446 },
00447 { name: "setsyncs|sss",
00448 func: cmd_setsyncs,
00449 shelp:"ch,en[,thr,baud,loop] : setup sync message receiver channel",
00450 lhelp:" ch channel number (0:1)\n"
00451 " en enable flag (0:1)\n"
00452 " thr throttled option (0:1, def=0)\n"
00453 " baud baud rate in MHz (def=62.5)\n"
00454 " loop enable syncm->syncs internal loop back (0:1, def=0)"
00455 },
00456 { name: "printgpio|pg",
00457 func: cmd_printgpio,
00458 shelp:"lists gpio options",
00459 lhelp:""
00460 },
00461 { name: 0,
00462 func: 0,
00463 shelp:0,
00464 lhelp:0
00465 }
00466 };
00467
00468
00469
00470 cmditem_t cmdlist_roc[] = {
00471 { name: "autoped",
00472 func: cmd_autoped,
00473 shelp:"[tmeas,tped] : auto-pedestal sequencer [EXPERIMENTAL!!]",
00474 lhelp:" tmeas length of measurement time interval (def=30.)\n"
00475 " tped length of pedestal time intervalta (def=0.1)\n"
00476 },
00477 { name: "autosettrh|ath",
00478 func: cmd_autosettrh,
00479 shelp:"time, min, nch, nnx",
00480 lhelp:" time sets the time of DAq for setup (real time is 8x higher)\n"
00481 " min crutial minimal value of working channels\n"
00482 " nch maximum rate of noise per channel\n"
00483 " nnx maximum rate of per chip\n"
00484 },
00485 { name: "autotrim|att",
00486 func: cmd_autotrim,
00487 shelp:"[-k -t -q] nx,rate[,time,vth_min,vth_max,target] : trim n-XYTER thresholds",
00488 lhelp:" -k keep vth at target efficiency after execution\n"
00489 " -m only measure the signal rate, without changing vth or trim register\n"
00490 " -t use actual vth, do not adjust it. Only adjust trim\n"
00491 " -q quiet mode\n"
00492 " rate expected pulse rate {Hz}\n"
00493 " time duration of one measurement {s} (def=4.)\n"
00494 " target detection efficiency to adjust the thresholds to (def=0.5)\n"
00495 " vth_min low limit of n-XYTER threshold (def=20)\n"
00496 " vth_max high limit of n-XYTER threshold (def=255)\n"
00497 " Hint: One can test autotrim with n-XYTER internal pulser:\n"
00498 " rocutil> sxmo * tpul=1\n"
00499 " rocutil> fp -a\n"
00500 " rocutil> setnxmask=0,val=1\n"
00501 " rocutil> setnxmask=0,val=0,ibeg=3,istep=4\n"
00502 " rocutil> autotrim * rate=2500\n"
00503 },
00504 { name: "autovbiass",
00505 func: cmd_autovbiass,
00506 shelp:"[-v] nx,[base,npuls] : VBiasS autotrim",
00507 lhelp:" -v show data for each channel\n"
00508 " nx nXYTER index ('*' for all or specific index)\n"
00509 " base target value for median baseline(0:4095, def=2000)\n"
00510 " npuls number of pulses to accumulate (1:10000, def=200)"
00511 },
00512 { name: "discover",
00513 func: cmd_discover,
00514 shelp:"[-v] : discover (probe for) nXYTER and FEBs",
00515 lhelp:" -v gives a verbose listing of all return codes\n"
00516 " Note: probes all even I2C addresses on both ports for nXYTER\n"
00517 " and uses discoverFebs() heuristics to identify FEBs"
00518 },
00519 { name: "dlm",
00520 func: cmd_dlm,
00521 shelp:"[num] : issue DLM message, default 1",
00522 lhelp:" num number of DLM message\n"
00523 " num=1 used for time synchronisation\n"
00524 },
00525 { name: "getadcdirect",
00526 func: cmd_getadcdirect,
00527 shelp:"[-d] : peak at adc data directly",
00528 lhelp:" -d use decimal output, default is hex"
00529 },
00530 { name: "idsigch|isc",
00531 func: cmd_idsigch,
00532 shelp:" [-m -q] nx [amp, vth, rate, time] : identify channels with signal !! UNDER DEVELOPMENT !!",
00533 lhelp:" -m mask channels with no signal\n"
00534 " -q quite mode, print only error messages\n"
00535
00536 " -t do not reqire any separation between signal and noise,\n"
00537 " simply apply the threshold, suppresses -v\n"
00538 " amp minimal amplitude (def=50)\n"
00539 " vth work with the specified vth, set to initial value\n"
00540 " when finish. 0 -- don't change vth. (def=0)\n"
00541 " rate require a minimal signal rate. (def=1./time)\n"
00542 " time measurement time in seconds (def=4.)"
00543 },
00544 { name: "printdatadbg|pdd",
00545 func: cmd_printdatadbg,
00546 shelp:"[-c -ib -ia][nmsg,time] : print data from debug port !! EXPERT !!",
00547 lhelp:" -c clear FIFO's before accessing data\n"
00548 " -ib init nx/roc timestamp system before FIFO clear\n"
00549 " -ia init nx/roc timestamp system after FIFO clear\n"
00550 " nmsg number of messages to print (def=100)\n"
00551 " time maximal time to look for data (def=1.)"
00552 },
00553 { name: "printid|pi",
00554 func: cmd_printid,
00555 shelp:"Prints all system id's and versions specifications",
00556 lhelp:""
00557 },
00558 { name: "printmon|pm",
00559 func: cmd_printmon,
00560 shelp:"print monitoring ADC readings",
00561 lhelp:""
00562 },
00563 { name: "printroc|pr",
00564 func: cmd_printroc,
00565 shelp:"lists ROC register settings",
00566 lhelp:""
00567 },
00568 { name: "printstatus|ps",
00569 func: cmd_printstatus,
00570 shelp:"brief status summary of ROC and FEBs",
00571 lhelp:""
00572 },
00573 { name: "restartroc",
00574 func: cmd_restartbrd,
00575 shelp:"restart ROC (FPGA reconfigure and PPC reboot) !! THINK BEFORE !!",
00576 lhelp:" Note: this command will disconnect the board/feb !!!\n"
00577 " restart rocutil and used 'setrocdef' to initialize ROC"
00578 },
00579 { name: "saverocconf",
00580 func: cmd_saverocconf,
00581 shelp:"will write the current ROC setting to the SDcard",
00582 lhelp:" Note: This will change the startup default of the ROC"
00583 },
00584 { name: "scanadclat",
00585 func: cmd_scanadclat,
00586 shelp:"[-v -d] nx[,ch,lbeg,lend,dbeg,dend,npuls,ch2] : ADC latency scan",
00587 lhelp:" -v show data for each scan point\n"
00588 " -d full delay scan, default is full latency scan\n"
00589 " nx nXYTER index\n"
00590 " ch channel to be used (0:127, def=0)\n"
00591 " lbeg start value for ADC latency (0:127, def=61)\n"
00592 " lend end value for ADC latency (0:127, def=68)\n"
00593 " dbeg start value for ADC clock delay (0:31, def=0)\n"
00594 " dend end value for ADC clock delay (0:31, def=31)\n"
00595 " npuls number of pulses to accumulate (1:10000, def=100)\n"
00596 " ch2 second channel to be activated (0:127, def=<none>)\n"
00597 " Note: For a latency scan (no -d) 8 delay settings are\n"
00598 " inspected in the range dbeg:dend, step size is adjusted.\n"
00599 " For a delay scan (-d) 8 latency settings are inspected\n"
00600 " in the range lbeg:lend, step size is adjusted to 1,2,4\n"
00601 " or lend is reduced\n"
00602 },
00603 { name: "scanmonadc",
00604 func: cmd_scanmonadc,
00605 shelp:"nx,reg[,vbeg,vend,vstep] : parameter scan for monitor ADCs",
00606 lhelp:" nx nXYTER index ('*' for all or specific index)\n"
00607 " reg nXYTER register number to be varied\n"
00608 " vbeg start value for scan (0:255, def=0)\n"
00609 " vend end value for scan (0:255, def=255)\n"
00610 " vstep step size of scan (1:255, def=1)\n"
00611 },
00612 { name: "scanvbiasf",
00613 func: cmd_scanvbiasf,
00614 shelp:"[-v] nx[,vbeg,vend,vstep,npuls] : VBiasF scan",
00615 lhelp:" -v show data for each channel\n"
00616 " nx nXYTER index ('*' for all or specific index)\n"
00617 " vbeg start value for VBiasF scan (0:255, def=0)\n"
00618 " vend end value for VBiasF scan (0:255, def=255)\n"
00619 " vstep step size of scan (1:255, def=1)\n"
00620 " npuls number of pulses to accumulate (1:10000, def=100)"
00621 },
00622 { name: "scanvbiass",
00623 func: cmd_scanvbiass,
00624 shelp:"[-v] nx[,vbeg,vend,vstep,npuls] : VBiasS scan",
00625 lhelp:" -v show data for each channel\n"
00626 " nx nXYTER index ('*' for all or specific index)\n"
00627 " vbeg start value for VBiasS scan (0:255, def=0)\n"
00628 " vend end value for VBiasS scan (0:255, def=255)\n"
00629 " vstep step size of scan (1:255, def=1)\n"
00630 " npuls number of pulses to accumulate (1:10000, def=100)"
00631 },
00632 { name: "setadcclock",
00633 func: cmd_setadcclock,
00634 shelp:"dly : set main clock delay",
00635 lhelp:" dly delay in 2ns units (0:31)"
00636 },
00637 { name: "setadcdef|sad",
00638 func: cmd_setadcdef,
00639 shelp:"set ADC registers to default values",
00640 lhelp:""
00641 },
00642 { name: "setadcpatt",
00643 func: cmd_setadcpatt,
00644 shelp:"[tm0,tm1,tm2,tm3,upatt] : set main adc test pattern mode",
00645 lhelp:" tm* adc channel i (0,1,2,3) test pattern mode\n"
00646 " upatt user data pattern (12 bit used, default='keep old')\n"
00647 " Note: modes are: 0=none(ADC data); 1=0x800; 2=0xfff;\n"
00648 " 3=0x000; 4=0xaaa,0x555; 5=PNlong; 6=PNshort;\n"
00649 " 7=0xfff,0x000; 8=upatt; 9=0xaaa; 10=0x03f;\n"
00650 " 11=0x800; 12=0xa33;"
00651 },
00652 { name: "setdebug",
00653 func: cmd_setdebug,
00654 shelp:"lvl : set debug level",
00655 lhelp:" lvl 0 only errors, >0 also debug infos"
00656 },
00657 { name: "seti2c",
00658 func: cmd_seti2c,
00659 shelp:"[-l -v] addr,reg,val : write into I2C selected device",
00660 lhelp:" -l scope loop (repeat until ^C)\n"
00661 " -v do readback verification\n"
00662 " addr I2C slave address (0:127)\n"
00663 " reg device register number (0:255)\n"
00664 " val value to be written (0:255)"
00665 },
00666 { name: "setlhwater|lhw",
00667 func: cmd_setlhwater,
00668 shelp:"low,high : low/high water",
00669 lhelp:" low low limit of PowerPC buffer in KB, min 8K\n"
00670 " high high limit of PowerPC buffer in KB, max 128M\n"
00671 },
00672 { name: "setnxoff",
00673 func: cmd_setnxoff,
00674 shelp:"nx,val : set 'offline' flag for nXYTER",
00675 lhelp:" nx nXYTER index\n"
00676 " val nXYTER offline flag, 1 means off (0:1)"
00677 },
00678 { name: "setnxpower|sxp",
00679 func: cmd_setnxpower,
00680 shelp:"nx,[val,ibeg,iend,istep] : set the power-down bit to val in range",
00681 lhelp:" nx nXYTER index ('*' for all or specific index)\n"
00682 " val power down bit, 1 means off (0:1, def=0)\n"
00683 " ibeg first channel number (0:128, def=0)\n"
00684 " iend last channel number (0:128, def=127)\n"
00685 " istep cha. num. increment, touch ibeg+n*istep (1:64, def=1)\n"
00686 " Note: channel range is 0:128, channel 128 is the test channel\n"
00687 " Note: the default for iend is 127, sparing the test channel"
00688 },
00689 { name: "setnxtrim|sxt",
00690 func: cmd_setnxtrim,
00691 shelp:"nx,[val,ibeg,iend,istep] : set the trim to val in range",
00692 lhelp:" nx nXYTER index ('*' for all or specific index)\n"
00693 " val trim value (0:31, def=16)\n"
00694 " ibeg first channel number (0:128, def=0)\n"
00695 " iend last channel number (0:128, def=127)\n"
00696 " istep cha. num. increment, touch ibeg+n*istep (1:64, def=1)\n"
00697 " Note: channel range is 0:128, channel 128 is the test channel\n"
00698 " Note: the default for iend is 127, sparing the test channel"
00699 },
00700 { name: "setrocdef|srd",
00701 func: cmd_setrocdef,
00702 shelp:" : set ROC registers to default values",
00703 lhelp:" Note: use after ROC boot, replaces old SDcard config file"
00704 },
00705 { name: "settrace|st",
00706 func: cmd_settrace,
00707 shelp:"[lvl] : set get/put/opergen trace level",
00708 lhelp:" lvl 0 none; 1 only comm err; 2 only err; 3 all (def=1)"
00709 },
00710 { name: "testadccntl",
00711 func: cmd_testadccntl,
00712 shelp:"[time] : test ADC control interface (SPI) for some time",
00713 lhelp:" time length of test in sec (def=10.)"
00714 },
00715 { name: "testadcdata",
00716 func: cmd_testadcdata,
00717 shelp:"[time] : test ADC data interface for some time",
00718 lhelp:" time length of test in sec (def=10.)"
00719 },
00720 { name: "testfebcntl",
00721 func: cmd_testfebcntl,
00722 shelp:"[time] : test ADC(not yet!) and all nXYTER control interfaces",
00723 lhelp:" time length of test in sec (def=10.)\n"
00724 " Note: does a random pattern test on many regsisters of all\n"
00725 " nXYTERs of the FEB and some ADC registers. See also\n"
00726 " 'testnxcntl' and 'testadccntl'"
00727 },
00728 { name: "testnxcntl",
00729 func: cmd_testnxcntl,
00730 shelp:"nx[,time] : test nXYTER control interface (I2C) for some time",
00731 lhelp:" nx nXYTER index ('*' for all or specific index)\n"
00732 " time length of test in sec (def=10.)\n"
00733 " Note: calls the NxI2c::probe() method continuously.\n"
00734 " To check all nXYTERs of a FEB together use 'testfebcntl'\n"
00735 " To check a I2C address use 'seti2c -l' or 'geti2c -l'"
00736 },
00737 { name: "testnxdata",
00738 func: cmd_testnxdata,
00739 shelp:"[-p -r -s][time] : test whether FEB responds to test triggers",
00740 lhelp:" -p print messages\n"
00741 " -r use raw format (default is human readable)\n"
00742 " -s print statistics\n"
00743 " time length of test in sec (def=10.)\n"
00744 " Note: will put FEB into default settings !!!"
00745 },
00746 { name: "testnxregs",
00747 func: cmd_testnxregs,
00748 shelp:"nx : test nXYTER registers",
00749 lhelp:" nx nXYTER index ('*' for all or specific index)\n"
00750 " Note: Writes and read-checks patterns in all registers"
00751 },
00752 { name: "testrocaux",
00753 func: cmd_testrocaux,
00754 shelp:"[-v -n] [ch,scale,time] : test ROC aux for some time",
00755 lhelp:" -v verbose, show first aux's, trends, stats\n"
00756 " -n no ROC initialization, use ROC config as is\n"
00757 " ch aux channel (0:3, def=2)\n"
00758 " scale aux scale (0:11, def=0)\n"
00759 " time length of test in sec (def=10.)\n"
00760 " Note: expects to receive periodic aux pulses from SysGlue\n"
00761 " with given frequency scale"
00762 },
00763 { name: "testrocsync",
00764 func: cmd_testrocsync,
00765 shelp:"[-v -n] [ch,scale,time] : test ROC sync for some time",
00766 lhelp:" -v verbose, show first sync's, trends, stats\n"
00767 " -n no ROC initialization, use ROC config as is\n"
00768 " ch sync channel (0:1, def=0)\n"
00769 " scale sync scale down (0:21, def=5)\n"
00770 " time length of test in sec (def=10.)\n"
00771 " Note: expects to receive periodic sync markers with the given\n"
00772 " scale down, either via loop-back or external"
00773 },
00774 { name: "resetrocnxts",
00775 func: cmd_resetrocnxts,
00776 shelp:"resetrocnxts : reset timing of nx time stamp",
00777 lhelp:" Note: should probably not used for optic"
00778 },
00779 { name: 0,
00780 func: 0,
00781 shelp:0,
00782 lhelp:0
00783 }
00784 };
00785
00786 void add_cmdlist(cmditem_t* lst)
00787 {
00788 for (cmditem_t* item = lst; item->name; item++)
00789 cmdlist.push_back(item);
00790 }
00791
00792
00793 void reset_cmdlist()
00794 {
00795 cmdlist.clear();
00796
00797 add_cmdlist(cmdlist_base);
00798 }
00799
00800
00801
00802
00803
00805
00809 int check_feb(bool needfeb=true)
00810 {
00811 if (needfeb && gFeb==0) {
00812 std::cerr << "rocutil-E: command requires connected FEB, use 'feb'" << std::endl;
00813 return 1;
00814 }
00815 return 0;
00816 }
00817
00818
00820
00825 int check_daq(bool needdaq)
00826 {
00827 if (needdaq && (gQdaq==0)) {
00828 std::cerr << "rocutil-E: command requires active DAQ, use 'board=addr?DAQ'"<< std::endl;
00829 return 1;
00830 }
00831 return 0;
00832 }
00833
00834
00836
00849 int args_check(int needs)
00850 {
00851 if (argspos.size() || argsopt.size()) {
00852 std::cerr << "rocutil-E: leftover arguments '";
00853 int cnt=0;
00854 for (int i=0; i<argspos.size(); i++) {
00855 if (cnt != 0) std::cerr << ",";
00856 std::cerr << argspos[i];
00857 cnt++;
00858 }
00859 for (int i=0; i<argsopt.size(); i++) {
00860 if (cnt != 0) std::cerr << ",";
00861 std::cerr << argsopt[i];
00862 cnt++;
00863 }
00864 std::cerr << "'" << std::endl;
00865 return 1;
00866 }
00867
00868 if (needs & kNeedFeb) needs |= kNeedBoard;
00869 if (needs & kNeedDaq) needs |= kNeedBoard;
00870
00871 if (((needs & kNeedBoard) != 0) && (gBaseBoard==0)) {
00872 std::cerr << "rocutil-E: command requires connected board, use 'board'" << std::endl;
00873 return 1;
00874 }
00875
00876 if (((needs & kNeedRocBoard)!=0) && (gRocBoard==0)) {
00877 std::cerr << "rocutil-E: command requires connected ROC, use 'board'" << std::endl;
00878 return 1;
00879 }
00880
00881 if (check_feb((needs & kNeedFeb)!=0)) return 1;
00882 if (check_daq((needs & kNeedDaq)!=0)) return 1;
00883
00884 return 0;
00885 }
00886
00887
00889
00894 void trim_whitespace(std::string& str)
00895 {
00896
00897 size_t pos_nwhitebeg = str.find_first_not_of(" \t");
00898 str.erase(0, pos_nwhitebeg);
00899
00900
00901 size_t pos_nwhiteend = str.find_last_not_of(" \t");
00902 str.erase(pos_nwhiteend+1);
00903 }
00904
00905
00906
00907 bool cmd_full_short(const char* cmd, std::string& cmdfull, std::string& cmdshort)
00908 {
00909 bool hasshort = false;
00910 cmdfull = cmd;
00911 cmdshort.erase();
00912 size_t pos_delcmd = cmdfull.find("|");
00913 if (pos_delcmd != std::string::npos) {
00914 cmdshort = cmdfull;
00915 cmdfull.erase(pos_delcmd);
00916 cmdshort.erase(0, pos_delcmd+1);
00917 hasshort = true;
00918 }
00919 return hasshort;
00920 }
00921
00922
00923
00924 std::string get_timestamp(const char* fields="dtm")
00925 {
00926 char buf[100];
00927 std::string str;
00928 struct timeval tv;
00929 struct tm tm_now;
00930 gettimeofday(&tv, 0);
00931 localtime_r(&tv.tv_sec, &tm_now);
00932
00933 if (strchr(fields, 'd')) {
00934 strftime(buf, sizeof(buf), "%F", &tm_now);
00935 str += buf;
00936 }
00937 if (strchr(fields, 't')) {
00938 if (strchr(fields, 'd')) str += " ";
00939 strftime(buf, sizeof(buf), "%T", &tm_now);
00940 str += buf;
00941 }
00942 if (strchr(fields, 'm')) {
00943 snprintf(buf, sizeof(buf), ".%03d", int(tv.tv_usec/1000));
00944 str += buf;
00945 }
00946 return str;
00947 }
00948
00949
00950
00951 int print_opererr(const char* text, int rc)
00952 {
00953 static boost::format fmt(": rc = %|4|,%|2| -> ");
00954 if (rc) {
00955 std::cout << "rocutil-E: " << text << " : "
00956 << base::Board::operErrToString(rc) << std::endl;
00957 }
00958 return rc;
00959 }
00960
00961
00962
00963 void print_loop_stats(const char* text, int ecnt)
00964 {
00965 std::cout << "rocutil-I: " << text << " ";
00966 std::cout << ( (ecnt)?"FAILED":"PASSED" );
00967 std::cout << " after " << std::dec << gUtil->getLoopCount()
00968 << " test loops";
00969 double dtime = gUtil->now() - gUtil->getStartLoopTime();
00970 if (dtime > 0) {
00971 static boost::format fmt(" in %4.2f sec");
00972 std::cout << fmt % dtime;
00973 }
00974 if (ecnt) std::cout << " with " << ecnt << " errors";
00975 std::cout << std::endl;
00976 }
00977
00978
00979
00980 void print_daq_stats(const char* text, uint64_t cnt, int ecnt)
00981 {
00982 std::cout << "rocutil-I: " << text << " ";
00983 std::cout << ( (ecnt)?"FAILED":"PASSED" );
00984 std::cout << " after " << std::dec << cnt
00985 << " messages";
00986 double dtime = gQdaq->getStopTime() - gQdaq->getStartTime();
00987 if (dtime > 0) {
00988 static boost::format fmt(" in %4.2f sec");
00989 std::cout << fmt % dtime;
00990 }
00991 if (ecnt) std::cout << " with " << ecnt << " errors";
00992 std::cout << std::endl;
00993 }
00994
00995
00996
00998
00999 int get_arg(std::string& arg, const char* aname, bool& defaulting)
01000 {
01001 defaulting = false;
01002 if (argspos.size()) {
01003 arg = argspos.front();
01004 argspos.erase(argspos.begin());
01005 return 0;
01006
01007 } else if (aname && aname[0]) {
01008 for (int i=0; i<argsopt.size(); i++) {
01009 size_t pos = argsopt[i].find(aname);
01010 if (pos == 0) {
01011 arg = argsopt[i];
01012 arg.erase(0, strlen(aname));
01013 argsopt.erase(argsopt.begin()+i);
01014 return 0;
01015 }
01016 }
01017 defaulting = true;
01018 return 0;
01019 }
01020 std::cerr << "rocutil-E: Argument missing" << std::endl;
01021 return 1;
01022 }
01023
01024
01025
01027
01028 int get_arg(std::string& arg, const char* aname=0)
01029 {
01030 bool defaulting;
01031 return get_arg(arg, aname, defaulting);
01032 }
01033
01034
01036
01037 int get_arg(int32_t& arg, const char* aname=0,
01038 int32_t min=(1<<31), int32_t max=~(1<<31))
01039 {
01040 std::string str;
01041 bool defaulting;
01042 if (get_arg(str, aname, defaulting)) return 1;
01043 if (defaulting) return 0;
01044 trim_whitespace(str);
01045
01046 if (str.size()!=0) {
01047 const char* cstr = str.c_str();
01048 char* eptr;
01049 int base=0;
01050
01051 if (cstr[0]=='b' || cstr[0]=='B') {
01052 cstr += 1;
01053 base = 2;
01054 }
01055
01056 errno = 0;
01057 int res = strtol(cstr, &eptr, base);
01058 if (errno || (eptr && eptr[0]!=0)) {
01059 std::cerr << "rocutil-E: conversion error in '" << str << "'" << std::endl;
01060 return 1;
01061 } else {
01062 arg = res;
01063 }
01064
01065 } else {
01066 arg = 0;
01067 }
01068
01069 if (arg < min || arg > max) {
01070 std::cerr << "rocutil-E: value " << arg << " is out of range "
01071 << min << ",...," << max << std::endl;
01072 return 1;
01073 }
01074
01075 return 0;
01076 }
01077
01078
01080
01081 int get_arg(double& arg, const char* aname=0)
01082 {
01083 std::string str;
01084 bool defaulting;
01085 if (get_arg(str, aname, defaulting)) return 1;
01086 if (defaulting) return 0;
01087 trim_whitespace(str);
01088
01089 if (str.size()!=0) {
01090 const char* cstr = str.c_str();
01091 char* eptr;
01092
01093 errno = 0;
01094 double res = strtod(cstr, &eptr);
01095 if (errno || (eptr && eptr[0]!=0)) {
01096 std::cerr << "rocutil-E: conversion error in '" << str << "'" << std::endl;
01097 return 1;
01098 } else {
01099 arg = res;
01100 }
01101
01102 } else {
01103 arg = 0.;
01104 }
01105
01106 return 0;
01107 }
01108
01109
01111
01112 int get_arg(bool& arg, const char* aname=0)
01113 {
01114 int32_t inp = -1;
01115 if (get_arg(inp, aname, 0, 1)) return 1;
01116 if (inp != -1) arg = (inp != 0);
01117 return 0;
01118 }
01119
01120
01122
01123 int get_nxind(int32_t& nx, const char* aname=0)
01124 {
01125 if (get_arg(nx, aname)) return 1;
01126 if (check_feb()) return 1;
01127
01128 if (nx<0 || nx>=gFeb->numNx()) {
01129 std::cout << "nXYTER index '" << nx << "' out of range, use 0,..,"
01130 << gFeb->numNx()-1 << std::endl;
01131 return 1;
01132 }
01133 return 0;
01134 }
01135
01136
01138
01139 int get_nxrange(int32_t& nxbeg, int32_t& nxend, const char* aname=0)
01140 {
01141 std::string str;
01142 bool defaulting;
01143
01144 if (check_feb()) return 1;
01145 if (get_arg(str, aname, defaulting)) return 1;
01146 if (defaulting || str == "*") {
01147 nxbeg = 0;
01148 nxend = gFeb->numNx()-1;
01149 return 0;
01150 }
01151
01152 trim_whitespace(str);
01153
01154 int32_t nx = 0;
01155 if (str.size()!=0) {
01156 const char* cstr = str.c_str();
01157 char* eptr;
01158 errno = 0;
01159 nx = strtol(cstr, &eptr, 0);
01160 if (errno || (eptr && eptr[0]!=0)) {
01161 std::cerr << "rocutil-E: conversion error in '" << str << "'" << std::endl;
01162 return 1;
01163 }
01164 }
01165
01166 if (nx<0 || nx>=gFeb->numNx()) {
01167 std::cout << "nXYTER index '" << nx << "' out of range, use 0,..,"
01168 << gFeb->numNx()-1 << std::endl;
01169 return 1;
01170 }
01171 nxbeg = nx;
01172 nxend = nx;
01173 return 0;
01174 }
01175
01176
01178
01179 bool get_opt(const std::string& opt)
01180 {
01181 for (std::vector<std::string>::iterator it=argsopt.begin(); it!=argsopt.end(); it++) {
01182 if (*it == opt) {
01183 argsopt.erase(it);
01184 return true;
01185 }
01186 }
01187 return false;
01188 }
01189
01190
01192
01193 bool check_nxoffline(int nxind, int nxbeg, int nxend)
01194 {
01195 if (nxbeg == nxend) return false;
01196 return gFeb->getNxOffline(nxind);
01197 }
01198
01199
01200
01201
01202 int cmd_help()
01203 {
01204 bool verbose = get_opt("-v");
01205 bool genhelp = get_opt("-g");
01206 bool listabr = get_opt("-a");
01207 std::string cmd;
01208
01209 get_arg(cmd, "command=");
01210
01211 if (cmd.size()) verbose = true;
01212 bool cmdok = false;
01213
01214 if (genhelp) {
01215 std::cout
01216 << "rocutil is a general purpose utility for all kinds of operations\n"
01217 << "on ROCs and FEBs. It can handle one ROC and one FEB at a time.\n"
01218 << "Commands can be specified on the shell command line or at a prompt.\n"
01219 << "\n"
01220 << "Command syntax is simple, a command name followed by a comma or\n"
01221 << "white space separated list of arguments.\n"
01222 << "The delimiter between command name and arguments can be '=' or\n"
01223 << "white space. The '=' is more convenient at the shell command line\n"
01224 << "white space after a command prompt.\n"
01225 << "A shell command line might look like\n"
01226 << " rocutil board=cbmtest42 feb=0,Feb1nx setfebdef\n"
01227 << "\n"
01228 << "If no command is given on the command line or the last is '-'\n"
01229 << "rocutil will enter command prompt mode with a 'rocutil>' prompt.\n"
01230 << "The prompt mode supports command editing and history recall,\n"
01231 << "the command history is stored across program invocations in the\n"
01232 << "file ./.rocutil_history in the current working directory.\n"
01233 << "\n"
01234 << "Integer numerical arguments can be entered in four radix:\n"
01235 << " decimal like 123\n"
01236 << " hexadecimal like 0x123\n"
01237 << " octal like 0123 !Note: leading zero means octal!\n"
01238 << " binary like b1011 is 11 (dec) 0xB (hex) 013 (oct)\n"
01239 << "\n"
01240 << "Optional arguments can be given in the form 'name=value'. They are\n"
01241 << "put in [...] in the help text and always have a default value. The\n"
01242 << "two command lines:\n"
01243 << " setnxmode 0 ttri=1 csel=2\n"
01244 << " setnxmode 0,0,1,2\n"
01245 << "are equivalent. Command options have the UNIX style '-v' form and\n"
01246 << "can be placed anywhere in the argument list. The two commands\n"
01247 << " seti2c=-l,-v,0,8,0xaa\n"
01248 << " seti2c -l -v 0 8 b10101010\n"
01249 << "are again equivalent.\n"
01250 << "\n"
01251 << "It is convenient to leave setup configuration commands at the shell\n"
01252 << "command and do the rest at the prompt, like:\n"
01253 << " rocutil board=cbmtest42 feb=0,Feb1nx -\n"
01254 << " rocutil> setfebdef\n"
01255 << " rocutil> setnxmask 0 1 4\n"
01256 << " rocutil> setnxmode 0 tpul=1 csel=2\n"
01257 << " rocutil> printfeb\n"
01258 << "\n"
01259 << "Command files can be executed with a command like\n"
01260 << " @filename\n"
01261 << "\n"
01262 << "Command lines can have comments in two forms:\n"
01263 << " 1. everything after '//' is discarted\n"
01264 << " 2. a line starting with '/*' is copied to stdout\n"
01265 << "\n"
01266 << "Finally, some commands have abreviated names, see 'help -s' for a"
01267 << "list of abbreviations. The full help text 'help <cmd>' will also"
01268 << "indicate when an abbreviation is defined."
01269 << "\n"
01270 << std::flush;
01271 return 0;
01272 }
01273
01274 if (listabr) {
01275 std::map<std::string, std::string> map_short2full;
01276 typedef std::map<std::string,std::string>::iterator map_iter_t;
01277
01278 for (unsigned i=0; i<cmdlist.size(); i++) {
01279 std::string cmdfull;
01280 std::string cmdshort;
01281 cmd_full_short(cmdlist[i]->name, cmdfull, cmdshort);
01282 if (cmdshort.size()==0) continue;
01283
01284 map_iter_t it = map_short2full.find(cmdshort);
01285
01286 if (it != map_short2full.end()) {
01287 std::cout << "rocutil-E: duplicate command abbreviation: "
01288 << cmdshort << " -> '" << (*it).second
01289 << "' and '" << cmdfull << "'"
01290 << std::endl;
01291 } else {
01292 map_short2full[cmdshort] = cmdfull;
01293 }
01294 }
01295
01296 for (map_iter_t it = map_short2full.begin();
01297 it != map_short2full.end(); it++) {
01298 static boost::format fmt("%|-4| -> %s");
01299 std::cout << fmt % (*it).first % (*it).second << std::endl;
01300 }
01301
01302 return 0;
01303 }
01304
01305 for (unsigned i=0; i<cmdlist.size(); i++) {
01306 std::string cmdfull;
01307 std::string cmdshort;
01308 cmd_full_short(cmdlist[i]->name, cmdfull, cmdshort);
01309
01310 static boost::format fmt("%|-12| %s");
01311 if (cmd.size() == 0 || cmd == cmdfull || cmd == cmdshort) {
01312 cmdok = true;
01313 std::cout << fmt % cmdfull % cmdlist[i]->shelp << std::endl;
01314 if (verbose && cmdlist[i]->lhelp[0]) {
01315 size_t pos_cur = 0;
01316 while(pos_cur != std::string::npos) {
01317 std::string lhelp(cmdlist[i]->lhelp);
01318 std::cout << " ";
01319 size_t pos_eol = lhelp.find("\n", pos_cur);
01320 if (pos_eol != std::string::npos) {
01321 std::cout << lhelp.substr(pos_cur, pos_eol-pos_cur);
01322 pos_cur = pos_eol+1;
01323 if (pos_cur >= lhelp.size()) pos_cur = std::string::npos;
01324 } else {
01325 std::cout << lhelp.substr(pos_cur);
01326 pos_cur = std::string::npos;
01327 }
01328 std::cout << std::endl;
01329 }
01330 if (cmdshort.size()) {
01331 std::cout << " "
01332 << cmdfull << " can be abreviated as "
01333 << cmdshort << std::endl;
01334 }
01335 }
01336 }
01337 }
01338
01339 if (cmd.size() == 0) {
01340 std::cout
01341 << "\n"
01342 << "For command syntax and general help use 'help -g'\n"
01343 << "For detailed help on a command cmd use 'help cmd'\n"
01344 << "For a full long listing of all command 'help -v'\n"
01345 << "For list of command abbreviations see 'help -a'\n"
01346 << std::flush;
01347 }
01348
01349 if (cmd.size() && (!cmdok)) {
01350 std::cout << "rocutil-E: Command '" << cmd << "' not found." << std::endl;
01351 std::cout << "rocutil-I: Use 'help', 'help -g', 'help -s' or 'help -v'." << std::endl;
01352 }
01353
01354 return 0;
01355 }
01356
01357
01358
01359 int cmd_quit()
01360 {
01361 return -1;
01362 }
01363
01364
01365
01366 int cmd_board()
01367 {
01368 if (gBaseBoard) {
01369 std::cerr << "rocutil-E: Already connected to a board, command ignored" << std::endl;
01370 return 0;
01371 }
01372
01373 std::string brdname;
01374 if (get_arg(brdname)) return 1;
01375 if (args_check(0)) return 1;
01376
01377 gBaseBoard = base::Board::Connect(brdname.c_str(), base::roleDAQ);
01378
01379 if (gBaseBoard==0) {
01380 std::cerr << "rocutil-E: Fail connect to the board " << brdname << std::endl;
01381 return 1;
01382 }
01383
01384 gBoardName = brdname;
01385
01386 reset_cmdlist();
01387 add_cmdlist(cmdlist_board);
01388
01389 gRocBoard = dynamic_cast<roc::Board*> (gBaseBoard);
01390 gSP605Board = dynamic_cast<sp605::Board*>(gBaseBoard);
01391
01392 if (gBaseBoard!=0) {
01393 gUtil = new nxyter::FebUtil(0);
01394 }
01395
01396 uint32_t fee_kind = gBaseBoard->getFrontendKind();
01397
01398 bool isnxyter = (fee_kind == base::kind_nXYTER) || (fee_kind == base::kind_newNX);
01399 bool isfeet = (fee_kind == base::kind_FEET) || (fee_kind == base::kind_oldFEET);
01400
01401 if (gBaseBoard->getRole() == base::roleDAQ) {
01402 gQdaq = new nxyter::QuickDaq(gBaseBoard);
01403 }
01404
01405 if (isnxyter)
01406 add_cmdlist(cmdlist_nxyter);
01407
01408 if (gRocBoard!=0) {
01409
01410
01411 add_cmdlist(cmdlist_gpio);
01412 add_cmdlist(cmdlist_roc);
01413
01414 roc::I2cDevice::addAddrMap(gRocBoard);
01415 base::Gpio::addAddrMap(gRocBoard);
01416 gGpio = new base::Gpio(gRocBoard);
01417
01418 if (isnxyter) {
01419 gRocNx = new nxyter::RocNx(gRocBoard);
01420 nxyter::RocNx::addAddrMap(gRocBoard, fee_kind);
01421 nxyter::MainAdc::addAddrMap(gRocBoard);
01422 }
01423
01424 if (isfeet)
01425 feet::RocFeet::addAddrMap(gRocBoard, fee_kind);
01426
01427
01428 if (!gRocBoard->isFile()) {
01429 uint32_t hw_vers;
01430 uint32_t lts_delay(1);
01431 int rc;
01432 rc = gRocBoard->get(ROC_HWV, hw_vers);
01433 print_opererr("Board::get(HARDWARE_VERSION)", rc);
01434
01435 if (fee_kind == base::kind_nXYTER) {
01436 rc = gRocBoard->get(ROC_NX_DELAY_LTS, lts_delay);
01437 print_opererr("Board::get(DELAY_LTS)", rc);
01438 }
01439
01440 if (hw_vers < 0x01070213)
01441 std::cout << "rocutil-W: Detected outdated firmware version. This version of\n"
01442 << " rocutil expects HARDWARE_VERSION 01070213 or higher" << std::endl;
01443
01444 if (lts_delay == 0)
01445 std::cout << "rocutil-W: Detected uninitialized ROC registers. Use 'setrocdef'." << std::endl;
01446 }
01447 } else
01448
01449 if (gSP605Board!=0) {
01450 add_cmdlist(cmdlist_gpio);
01451 add_cmdlist(cmdlist_sp605);
01452
01453 roc::I2cDevice::addAddrMap(gBaseBoard);
01454 base::Gpio::addAddrMap(gBaseBoard);
01455
01456 gGpio = new base::Gpio(gBaseBoard);
01457
01458 if (isnxyter) {
01459 gRocNx = new nxyter::RocNx(gBaseBoard);
01460 nxyter::RocNx::addAddrMap(gBaseBoard, fee_kind);
01461 nxyter::MainAdc::addAddrMap(gBaseBoard);
01462 }
01463 }
01464
01465 return 0;
01466 }
01467
01468
01469
01470 int cmd_setdebug()
01471 {
01472 int32_t lvl;
01473 if (get_arg(lvl)) return 1;
01474 if (args_check(kNeedRocBoard)) return 1;
01475
01476 gRocBoard->setVerbosity(lvl);
01477 return 0;
01478 }
01479
01480
01481
01482 int cmd_settrace()
01483 {
01484 int32_t lvl=1;
01485 if (get_arg(lvl, "lvl=")) return 1;
01486 if (args_check(kNeedBoard)) return 1;
01487
01488 gBaseBoard->setOperTrace(lvl);
01489 return 0;
01490 }
01491
01492
01493
01494 int cmd_ident()
01495 {
01496 if (gBaseBoard)
01497 std::cout << "--- Connected to " << gBoardName;
01498 else
01499 std::cout << "--- Not yet connected";
01500
01501 std::cout << " at " << get_timestamp("dtm") << std::endl;
01502 return 0;
01503 }
01504
01505
01506
01507 int cmd_initfeb()
01508 {
01509 if (gFeb==0) {
01510 std::cout << " Feb not created" << std::endl;
01511 } else {
01512 gFeb->initRoc();
01513 std::cout << "set nxyter on/off flags to ROC" << std::endl;
01514 }
01515
01516 return 0;
01517 }
01518
01519
01520
01521
01522 int cmd_discover()
01523 {
01524 bool opt_verb = get_opt("-v");
01525 if (args_check(kNeedRocBoard)) return 1;
01526 nxyter::FebUtil::probe(gRocBoard, opt_verb);
01527 return 0;
01528 }
01529
01530
01531
01532 int cmd_dlm()
01533 {
01534 int num = 1;
01535 if (get_arg(num, "num=")) return 1;
01536 if (gRocBoard==0) return 1;
01537
01538 gRocBoard->invokeDLM(num);
01539
01540 std::cout << "Invoke DLM = " << num << std::endl;
01541
01542 return 0;
01543 }
01544
01545
01546
01547 int cmd_feb()
01548 {
01549 int32_t port = -1;
01550 std::string type("auto");
01551 if (get_arg(port, "port=")) return 1;
01552 if (get_arg(type, "type=")) return 1;
01553 if (args_check(kNeedBoard)) return 1;
01554
01555 delete gFeb; gFeb = 0;
01556 delete gQdaq; gQdaq = 0;
01557 delete gUtil; gUtil = 0;
01558
01559 int ftyp=-1;
01560
01561 if (type != "auto") {
01562 if (type == "Feb1nxGenB") ftyp = nxyter::FebBase::kFeb1nxGenB;
01563 else if (type == "Feb1nxGenC") ftyp = nxyter::FebBase::kFeb1nxGenC;
01564 else if (type == "Feb1nxGenD") ftyp = nxyter::FebBase::kFeb1nxGenD;
01565 else if (type == "Feb2nxGas") ftyp = nxyter::FebBase::kFeb2nxGas;
01566 else if (type == "Feb4nxBT") ftyp = nxyter::FebBase::kFeb4nxBT;
01567 else {
01568 std::cout << "Unknown type, use Feb1nxGen[BCD], Feb2nxGas, Feb4nxBT" << std::endl;
01569 return 1;
01570 }
01571 }
01572
01573 if (port==-1 || type=="auto") {
01574 int ftyp0, ftyp1;
01575 nxyter::FebBase::discoverFebs(gRocBoard, ftyp0, ftyp1, true);
01576 if (port==-1) {
01577 if (ftyp0 != 0) {
01578 port = 0;
01579 ftyp = ftyp0;
01580 } else if (ftyp1 != 0) {
01581 port = 1;
01582 ftyp = ftyp1;
01583 } else {
01584 std::cout << "No FEB detected, use 'discover'" << std::endl;
01585 return 1;
01586 }
01587 }
01588 if (ftyp == -1) {
01589 ftyp = (port==0) ? ftyp0 : ftyp1;
01590 if (ftyp==0) {
01591 std::cout << "No FEB detected on port " << port << ", use 'discover'" << std::endl;
01592 return 1;
01593 }
01594 }
01595 std::cout << "rocutil-I: connect on port " << port
01596 << " " << nxyter::FebBase::typeToString(ftyp) << std::endl;
01597 }
01598
01599 gFeb = nxyter::FebBase::newFeb(gBaseBoard, port, ftyp);
01600
01601 if (!gFeb)
01602 std::cout << "Internal error, no FEB attached" << std::endl;
01603
01604 if (gBaseBoard && (gBaseBoard->getRole() == base::roleDAQ))
01605 gQdaq = new nxyter::QuickDaq(gFeb);
01606
01607 gUtil = new nxyter::FebUtil(gFeb, gQdaq);
01608
01609 return 0;
01610 }
01611
01612
01613
01614 int cmd_setnxaddr()
01615 {
01616 int32_t nxind;
01617 int32_t addr;
01618 if (get_nxind(nxind)) return 1;
01619 if (get_arg(addr, 0, 0, 255)) return 1;
01620 if (args_check(kNeedFeb)) return 1;
01621
01622 gFeb->nx(nxind).i2c().setSlaveAddr(uint8_t(addr));
01623 return 0;
01624 }
01625
01626
01627
01628 int cmd_setnxoff()
01629 {
01630 int32_t nxind;
01631 bool val;
01632 if (get_nxind(nxind)) return 1;
01633 if (get_arg(val)) return 1;
01634 if (args_check(kNeedFeb)) return 1;
01635
01636 gFeb->setNxOffline(nxind, val);
01637 return 0;
01638 }
01639
01640
01641
01642 int cmd_printroc()
01643 {
01644 uint32_t alist[] = {ROC_TYPE,
01645 ROC_HWV,
01646 ROC_ROCID,
01647 base::GPIO_CONFIG,
01648 base::GPIO_SYNCM_SCALEDOWN,
01649 base::GPIO_SYNCM_BAUD1,
01650 base::GPIO_SYNCM_BAUD2,
01651 base::GPIO_SYNCS0_BAUD1,
01652 base::GPIO_SYNCS0_BAUD2,
01653 ROC_NX_HWV,
01654 ROC_NX_NXACTIVE,
01655 ROC_NX_FEB4NX,
01656 ROC_NX_PARITY_CHECK,
01657 ROC_NX_ADC_PORT_SELECT1,
01658 ROC_NX_ADC_PORT_SELECT2,
01659 ROC_NX_ADC_PORT_SELECT3,
01660 ROC_NX_ADC_PORT_SELECT4,
01661 ROC_NX_SR_INIT,
01662 ROC_NX_BUFG_SELECT,
01663 ROC_NX_SR_INIT2,
01664 ROC_NX_BUFG_SELECT2,
01665 ROC_NX_ADC_LATENCY1,
01666 ROC_NX_ADC_LATENCY2,
01667 ROC_NX_ADC_LATENCY3,
01668 ROC_NX_ADC_LATENCY4,
01669 ROC_NX_DELAY_LTS,
01670 ROC_NX_DELAY_NX0,
01671 ROC_NX_DELAY_NX1,
01672 ROC_NX_DELAY_NX2,
01673 ROC_NX_DELAY_NX3,
01674 ROC_NX_DEBUG_MODE,
01675 ROC_ETH_HWV,
01676 ROC_ETH_SWV,
01677 ROC_ETH_IP_ADDRESS,
01678 ROC_ETH_MAC_ADDRESS_UPPER,
01679 ROC_ETH_MAC_ADDRESS_LOWER,
01680 ROC_ETH_BUFFER_FLUSH_TIMER,
01681 ROC_ETH_LOWWATER,
01682 ROC_ETH_HIGHWATER,
01683 ROC_ETH_NUMBUFALLOC,
01684 ROC_ETH_LOST_ETHER_FRAMES,
01685 ROC_ETH_TEMAC_REG0
01686 };
01687
01688 if (args_check(kNeedRocBoard)) return 1;
01689
01690 for (int i=0; i<sizeof(alist)/sizeof(alist[0]); i++) {
01691
01692
01693 if ((alist[i]==ROC_ETH_SWV) &&
01694 (gRocBoard->getTransportKind() != roc::kind_UDP)) break;
01695
01696
01697 if ((alist[i]==ROC_NX_HWV) &&
01698 (gRocBoard->getRocFrontendKind() != base::kind_nXYTER)) break;
01699
01700 const char* sname = gRocBoard->findRegNameByAddress(alist[i]);
01701
01702 if (sname==0) {
01703 std::cout << alist[i] << " not available on ROC" << std::endl;
01704 continue;
01705 }
01706
01707 static boost::format fmt_pref("get(%-24s [0x%08x]) -> ");
01708 std::cout << fmt_pref % sname % alist[i];
01709
01710 uint32_t value;
01711 int rc = gRocBoard->get(alist[i], value);
01712 if (rc==0) {
01713 static boost::format fmt_data("0x%08x %10d");
01714 std::cout << fmt_data % value % value << std::endl;
01715 } else {
01716 std::cout << base::Board::operErrToString(rc) << std::endl;
01717 }
01718 }
01719
01720 return 0;
01721 }
01722
01723
01724
01725 int cmd_printid()
01726 {
01727 if (args_check(kNeedRocBoard)) return 1;
01728
01729 int rc;
01730 uint32_t value;
01731
01732 rc = gRocBoard->get(ROC_TYPE, value);
01733 if (rc==0) std::cout << "ROC type: "
01734 << gRocBoard->versionToString(value) << std::endl;
01735 rc = gRocBoard->get(ROC_HWV, value);
01736 if (rc==0) std::cout << "ROC hardware version: "
01737 << gRocBoard->versionToString(value) << std::endl;
01738 if (gRocBoard->getTransportKind() == roc::kind_UDP) {
01739 rc = gRocBoard->get(ROC_ETH_HWV, value);
01740 if (rc==0) std::cout << "Eth hardware version: "
01741 << gRocBoard->versionToString(value) << std::endl;
01742 rc = gRocBoard->get(ROC_ETH_SWV, value);
01743 if (rc==0) std::cout << "Eth software version: "
01744 << gRocBoard->versionToString(value) << std::endl;
01745 }
01746 if (gRocBoard->getTransportKind() == roc::kind_ABB) {
01747 rc = gRocBoard->get(ROC_OPTICS_HWV, value);
01748 if (rc==0) std::cout << "Opt hardware version: "
01749 << gRocBoard->versionToString(value) << std::endl;
01750 }
01751 rc = gRocBoard->get(ROC_NX_HWV, value);
01752 if (rc==0) std::cout << "Nx hardware version: "
01753 << gRocBoard->versionToString(value) << std::endl;
01754
01755 return 0;
01756 }
01757
01758
01759
01760 int cmd_printfeb()
01761 {
01762 bool opt_m = get_opt("-m");
01763 bool opt_c = get_opt("-c");
01764 bool opt_t = get_opt("-t");
01765 bool opt_a = get_opt("-a");
01766 if (args_check(kNeedFeb)) return 1;
01767
01768 if (!(opt_m | opt_c | opt_t | opt_a)) opt_c = true;
01769 int domask = 0;
01770 if (opt_m | opt_a) domask |= nxyter::kDoMask;
01771 if (opt_c | opt_a) domask |= nxyter::kDoCore;
01772 if (opt_t | opt_a) domask |= nxyter::kDoTrim;
01773
01774 gFeb->printRegisters(std::cout, domask);
01775 return 0;
01776 }
01777
01778
01779
01780 int cmd_printadc()
01781 {
01782 if (args_check(kNeedFeb)) return 1;
01783 gFeb->adc().printRegisters(std::cout);
01784 return 0;
01785 }
01786
01787
01788
01789 int cmd_printnx()
01790 {
01791 bool opt_m = get_opt("-m");
01792 bool opt_c = get_opt("-c");
01793 bool opt_t = get_opt("-t");
01794 bool opt_a = get_opt("-a");
01795 int nxbeg=0;
01796 int nxend=0;
01797 if (get_nxrange(nxbeg, nxend, "nx=")) return 1;
01798 if (args_check(kNeedFeb)) return 1;
01799
01800 if (!(opt_m | opt_c | opt_t | opt_a)) opt_c = true;
01801 int domask = 0;
01802 if (opt_m | opt_a) domask |= nxyter::kDoMask;
01803 if (opt_c | opt_a) domask |= nxyter::kDoCore;
01804 if (opt_t | opt_a) domask |= nxyter::kDoTrim;
01805
01806 for (int i=nxbeg; i<=nxend; i++) {
01807 gFeb->printNxHeadLine(std::cout, i);
01808 if (!gFeb->getNxOffline(i)) gFeb->nx(i).i2c().printRegisters(std::cout, domask);
01809 }
01810 return 0;
01811 }
01812
01813
01814
01815 int cmd_printmon()
01816 {
01817 if (args_check(kNeedFeb)) return 1;
01818
01819 if (!gFeb->monAdcSupport()) {
01820 std::cout << "no monitoring ADC support for this FEB type" << std::endl;
01821 return 0;
01822 }
01823
01824 uint16_t val[4];
01825 for (int ch=0; ch<4; ch++) {
01826 int rc = gFeb->getMonAdc(ch, val[ch]);
01827 print_opererr("FebBase::getMonAdc", rc);
01828 }
01829
01830 for (int ch=0; ch<4; ch++) {
01831 static boost::format fmt("%|4|");
01832 std::cout << " " << fmt % uint32_t(val[ch]);
01833 }
01834 std::cout << std::endl;
01835
01836 return 0;
01837 }
01838
01839
01840
01841 int cmd_setbrddef()
01842 {
01843 if (args_check(kNeedBoard)) return 1;
01844
01845 int rc = gBaseBoard->setToDefault();
01846 print_opererr("Board::setToDefault", rc);
01847
01848 return 0;
01849 }
01850
01851
01852
01853 int cmd_setrocdef()
01854 {
01855 if (args_check(kNeedBoard)) return 1;
01856
01857 int rc = gBaseBoard->setToDefault();
01858 print_opererr("Board::setToDefault", rc);
01859
01860 if (gRocNx) {
01861 rc = gRocNx->setToDefault();
01862 print_opererr("RocNx::setToDefault", rc);
01863 }
01864
01865 return 0;
01866 }
01867
01868
01869
01870 int cmd_setsyncm()
01871 {
01872 int32_t scale;
01873 double baud = 62.5;
01874 if (get_arg(scale, 0, 0, 21)) return 1;
01875 if (get_arg(baud, "baud=")) return 1;
01876 if (args_check(kNeedBoard)) return 1;
01877 if (gGpio == 0) { std::cerr << "No Gpio instance" << std::endl; return 1; }
01878
01879 int ratediv = int(std::floor((500./baud)+0.5));
01880 if (ratediv > 511 || std::abs(baud - 500./double(ratediv)) > 0.01) {
01881 std::cout << "rocutil-E: baud rate not supported" << std::endl;
01882 return 1;
01883 }
01884
01885 int rc;
01886 rc = gGpio->setSyncScale(scale);
01887 print_opererr("Gpio::setSyncScale", rc);
01888 rc = gGpio->setSyncBaud(1, ratediv);
01889 print_opererr("Gpio::setSyncBaud", rc);
01890
01891 return 0;
01892 }
01893
01894
01895
01896 int cmd_setsyncs()
01897 {
01898 int32_t ch;
01899 bool enable;
01900 bool throttled = false;
01901 double baud = 62.5;
01902 int32_t loop = 0;
01903 if (get_arg(ch, 0, 0, 1)) return 1;
01904 if (get_arg(enable)) return 1;
01905 if (get_arg(throttled, "thr=")) return 1;
01906 if (get_arg(baud, "baud=")) return 1;
01907 if (get_arg(loop, "loop=", 0, 1)) return 1;
01908 if (args_check(kNeedBoard)) return 1;
01909 if (gGpio == 0) { std::cerr << "No Gpio instance" << std::endl; return 1; }
01910
01911 int ratediv = int(std::floor((500./baud)+0.5));
01912 if (ratediv > 511 || std::abs(baud - 500./double(ratediv)) > 0.01) {
01913 std::cout << "rocutil-E: baud rate not supported" << std::endl;
01914 return 1;
01915 }
01916
01917 int rc;
01918 rc = gGpio->setConfig(2+ch, enable, enable, throttled, loop, false);
01919 print_opererr("Gpio::setConfig", rc);
01920 rc = gGpio->setSyncBaud(2+ch, ratediv);
01921 print_opererr("Gpio::setSyncBaud", rc);
01922
01923 return 0;
01924 }
01925
01926
01927
01928 int cmd_setaux()
01929 {
01930 int32_t ch;
01931 bool riseedge = false;
01932 bool falledge = false;
01933 bool throttled = true;
01934 bool extrafunc = false;
01935 bool altin = false;
01936 if (get_arg(ch, 0, 0, 3)) return 1;
01937 if (get_arg(riseedge, "re=")) return 1;
01938 if (get_arg(falledge, "fe=")) return 1;
01939 if (get_arg(throttled, "thr=")) return 1;
01940 if (get_arg(extrafunc, "ext=")) return 1;
01941 if (get_arg(altin, "alt=")) return 1;
01942 if (args_check(kNeedBoard)) return 1;
01943 if (gGpio == 0) { std::cerr << "No Gpio instance" << std::endl; return 1; }
01944
01945 int rc = gGpio->setConfig(4+ch, riseedge, falledge, throttled,
01946 extrafunc,altin);
01947 print_opererr("Gpio::setConfig", rc);
01948 return 0;
01949 }
01950
01951
01952 int cmd_setlhwater()
01953 {
01954 int32_t low(0), high(0);
01955
01956 roc::UdpBoard* udp = dynamic_cast<roc::UdpBoard*> (gRocBoard);
01957 if (udp==0) return 1;
01958
01959 if (get_arg(low, "low=")) return 1;
01960 if (get_arg(high, "high=")) return 1;
01961
01962 if ((low<8) || (high>128*1024) || (low>=high-8)) return 1;
01963
01964 if (!udp->setRocLowHighWater(low, high)) return 1;
01965
01966 return 0;
01967 }
01968
01969
01970
01971
01972 int cmd_printgpio()
01973 {
01974 if (args_check(kNeedBoard)) return 1;
01975 if (gGpio == 0) { std::cerr << "No Gpio instance" << std::endl; return 1; }
01976
01977 const char* names[8] = {"",
01978 "sync-m ",
01979 "sync-0 ",
01980 "sync-1 ",
01981 "aux-0 ",
01982 "aux-1 ",
01983 "aux-2 ",
01984 "aux-3 "
01985 };
01986 const char* namext[8] = {"",
01987 "",
01988 "loop-back",
01989 "loop-back",
01990 " <unused>",
01991 " <unused>",
01992 "TP-source",
01993 "THR-input"
01994 };
01995 const char* namalt[8] = {"",
01996 "",
01997 "",
01998 "",
01999 " <unused>",
02000 " TP-busy",
02001 " TP-gen",
02002 " THR-loop"
02003 };
02004
02005 uint32_t mask;
02006 int rc = gGpio->getConfig(mask);
02007 print_opererr("Gpio::getConfig", rc);
02008 if (rc) return 0;
02009
02010 bool riseedge;
02011 bool falledge;
02012 bool throttled;
02013 bool extrafunc;
02014 bool altin;
02015
02016 for (int i=1; i<4; i++) {
02017 uint32_t bauds;
02018 uint32_t baud1;
02019 uint32_t baud2;
02020 rc = gGpio->getSyncBaud(i, bauds, baud1, baud2);
02021 print_opererr("Gpio::getSyncBaud", rc);
02022
02023 double baud = 500. / (double(baud1+baud2));
02024
02025 std::cout << names[i] << " : baud(";
02026 static boost::format fmt_3d("%3d");
02027 std::cout << fmt_3d % bauds;
02028 std::cout << "," << fmt_3d % baud1;
02029 std::cout << "," << fmt_3d % baud2;
02030 static boost::format fmt_4p1f("%4.1f");
02031 std::cout << ")= " << fmt_4p1f % baud;
02032 std::cout << " MHz";
02033
02034 if (i==1) {
02035 uint32_t scale;
02036 rc = gGpio->getSyncScale(scale);
02037 print_opererr("Gpio::getSyncScale", rc);
02038 std::cout << " scale=" << fmt_3d % scale;
02039 std::cout << " 1:" << std::dec << (1<<scale);
02040 } else {
02041 gGpio->unpackConfig(mask, i, riseedge, falledge, throttled,
02042 extrafunc, altin);
02043 std::cout << " enable=" << riseedge
02044 << " throttled=" << throttled
02045 << " " << namext[i] << "=" << extrafunc;
02046 }
02047 std::cout << std::endl;
02048 }
02049
02050 for (int i=4; i<=7; i++) {
02051 gGpio->unpackConfig(mask, i, riseedge, falledge, throttled,
02052 extrafunc, altin);
02053 std::cout << names[i] << " : rise=" << riseedge
02054 << " fall=" << falledge
02055 << " throttled=" << throttled
02056 << " " << namext[i] << "=" << extrafunc
02057 << " " << namalt[i] << "=" << altin;
02058 std::cout << std::endl;
02059 }
02060
02061 return 0;
02062 }
02063
02064
02065
02066 int cmd_printstatus()
02067 {
02068 if (args_check(kNeedRocBoard)) return 1;
02069 if (gGpio == 0) { std::cerr << "No Gpio instance" << std::endl; return 1; }
02070
02071
02072 int rc;
02073 uint32_t mask;
02074 rc = gGpio->getConfig(mask);
02075 print_opererr("Gpio::getConfig", rc);
02076 if (rc) return 0;
02077
02078 bool riseedge;
02079 bool falledge;
02080 bool throttled;
02081 bool extrafunc;
02082 bool altin;
02083
02084 for (int i=0; i<=1; i++) {
02085 gGpio->unpackConfig(mask, i+2, riseedge, falledge, throttled,
02086 extrafunc, altin);
02087 if (riseedge | falledge) {
02088 std::cout << "SYN " << std::dec << i << ":"
02089 << " enabled";
02090 if (extrafunc) {
02091 std::cout << " in loop-back mode";
02092 uint32_t scale;
02093 rc = gGpio->getSyncScale(scale);
02094 print_opererr("Gpio::getSyncScale", rc);
02095 std::cout << "; syncm scale = " << scale;
02096 }
02097 std::cout << std::endl;
02098 }
02099 }
02100
02101 for (int i=0; i<=3; i++) {
02102 gGpio->unpackConfig(mask, i+4, riseedge, falledge, throttled,
02103 extrafunc, altin);
02104 if (riseedge | falledge | extrafunc) {
02105 std::cout << "AUX " << std::dec << i << ":"
02106 << " re=" << riseedge
02107 << " fe=" << falledge
02108 << " thr=" << throttled
02109 << " ext=" << extrafunc
02110 << " alt=" << altin
02111 << " ";
02112 if (i==3) {
02113 if (extrafunc) {
02114 std::cout << "THR active";
02115 if (altin) std::cout << " as auto throttle";
02116 }
02117 }
02118 std::cout << std::endl;
02119 }
02120 }
02121
02122 if (gFeb) {
02123 static boost::format fmt_3d("%3d");
02124 static boost::format fmt_02x("%02x");
02125 for (int nx=0; nx<gFeb->numNx(); nx++) {
02126 std::cout << "NX " << gFeb->getPortNumber()
02127 << "," << nx
02128 << "," << gFeb->nx(nx).getNxNumber()
02129 << ":";
02130
02131 if (gFeb->getNxOffline(nx)) {
02132 std::cout << " is offline" << std::endl;
02133 continue;
02134 }
02135
02136 nxyter::NxContext cntx;
02137 rc = gFeb->nx(nx).i2c().getContext(cntx, nxyter::kDoCore);
02138 if (rc) {
02139 std::cout << "!! ERROR: NX NOT REACHABLE:"
02140 << base::Board::operErrToString(rc)
02141 << " <===" << std::endl;
02142 continue;
02143 }
02144
02145 uint8_t vth = cntx.getRegister(nxyter::kNxRegVth);
02146 uint8_t vbiasf = cntx.getRegister(nxyter::kNxRegVbiasF);
02147 uint8_t vbiass = cntx.getRegister(nxyter::kNxRegVbiasS);
02148
02149 std::cout << " Vth=" << fmt_3d % int(vth);
02150 std::cout << " VbiasF=" << fmt_3d % int(vbiasf);
02151 std::cout << " VbiasS=" << fmt_3d % int(vbiass);
02152
02153 int n128 = 0;
02154 for (int i=nxyter::kNxRegVcg; i<=nxyter::kNxRegiTWC; i++) {
02155 if (cntx.getRegister(i) == 128) n128 += 1;
02156 }
02157 if (n128 >= (nxyter::kNxRegiTWC-nxyter::kNxRegVcg)-2) {
02158 std::cout << "!! ERROR: NX in RESET STATE <===";
02159 } else {
02160 uint8_t conf0 = cntx.getRegister(nxyter::kNxRegConfig0);
02161 uint8_t conf1 = cntx.getRegister(nxyter::kNxRegConfig1);
02162
02163 std::cout << " conf=" << fmt_02x % uint32_t(conf0);
02164 std::cout << "," << fmt_02x % uint32_t(conf1);
02165 std::cout << " tpul=" << ((conf0&nxyter::kNxC0TestPulsEnable) ? "1" : "0");
02166 std::cout << " ttri=" << ((conf0&nxyter::kNxC0TestTrigEnable) ? "1" : "0");
02167 std::cout << " pos=" << ((conf0&nxyter::kNxC1FrontEndPolarity) ? "1" : "0");
02168 }
02169
02170 std::cout << std::endl;
02171 }
02172 }
02173
02174 return 0;
02175 }
02176
02177
02178
02179 int cmd_firepulser()
02180 {
02181 bool opt_s = get_opt("-s");
02182 bool opt_a = get_opt("-a");
02183 int32_t period(100000);
02184 int32_t width(350);
02185 int32_t number(0);
02186 int32_t delay(0);
02187 if (get_arg(period, "per=", 2, 0x00ffffff)) return 1;
02188 if (get_arg(width, "wth=", -0x00ffffff, 0x00ffffff)) return 1;
02189 if (get_arg(number, "num=", 0, 0x00008fff)) return 1;
02190 if (get_arg(delay, "dly=", 0, 0x0000ffff)) return 1;
02191 if (args_check(kNeedBoard)) return 1;
02192
02193 if (gRocNx==0) {
02194 std::cout << "RocNx instance is required" << std::endl;
02195 return 1;
02196 }
02197
02198 if (gGpio==0) {
02199 std::cout << "Gpio instance is required" << std::endl;
02200 return 1;
02201 }
02202
02203 int rc;
02204
02205 if (opt_a) {
02206 uint32_t mask;
02207 rc = gGpio->getConfig(mask);
02208 print_opererr("Gpio::getConfig", rc);
02209 bool riseedge, falledge, throttled, extrafunc, altin;
02210 base::Gpio::unpackConfig(mask, 6,
02211 riseedge, falledge, throttled, extrafunc, altin);
02212
02213 if (opt_s) {
02214 extrafunc = false;
02215 } else {
02216 extrafunc = true;
02217 altin = true;
02218 }
02219
02220 base::Gpio::packConfig(mask, 6, riseedge, falledge, throttled, extrafunc, altin);
02221 rc = gGpio->setConfig(mask);
02222 print_opererr("Gpio::setConfig", rc);
02223 }
02224
02225 if (delay == 0) {
02226 if (opt_s) {
02227 period = 0;
02228 width = 0;
02229 number = 0;
02230 }
02231 rc = gRocNx->fireTestPulse(period, width, number);
02232 } else {
02233 rc = gRocNx->fireTestPulse(delay, period, width, number);
02234 }
02235 print_opererr("RocNx::fireTestPulse", rc);
02236 return 0;
02237 }
02238
02239
02240
02241 int cmd_setfebdef()
02242 {
02243 bool ispos0(false), ispos1(false);
02244 if (get_arg(ispos0, "pos0=")) return 1;
02245 if (get_arg(ispos1, "pos1=")) return 1;
02246 if (args_check(kNeedFeb)) return 1;
02247 int rc = gFeb->setToDefault(ispos0, ispos1);
02248 print_opererr("FebBase::setToDefault", rc);
02249 printf("Note: Vbfb default value is changed now from 6 to 30!\n");
02250 return 0;
02251 }
02252
02253
02254
02255 int cmd_setnxdef()
02256 {
02257 int32_t nxbeg(0), nxend(0);
02258 bool ispos(false);
02259 if (get_nxrange(nxbeg, nxend, "nx=")) return 1;
02260 if (get_arg(ispos, "pos=")) return 1;
02261 if (args_check(kNeedFeb)) return 1;
02262 for (int i=nxbeg; i<=nxend; i++) {
02263 if (check_nxoffline(i, nxbeg, nxend)) continue;
02264 int rc = gFeb->nx(i).i2c().setToDefault(ispos);
02265 print_opererr("NxI2c::setToDefault", rc);
02266 }
02267 return 0;
02268 }
02269
02270
02271
02272 int cmd_setnx()
02273 {
02274 int32_t nxbeg=0;
02275 int32_t nxend=0;
02276 int32_t reg;
02277 int32_t val;
02278 if (get_nxrange(nxbeg, nxend)) return 1;
02279 if (get_arg(reg, 0, 0, 255)) return 1;
02280 if (get_arg(val, 0, 0, 255)) return 1;
02281 if (args_check(kNeedFeb)) return 1;
02282
02283 if (reg == nxyter::kNxRegTrimDAQPower) {
02284 std::cout << "rocutil-E: use 'setnxtrim' and 'setnxpower' for Reg 42" << std::endl;
02285 return 1;
02286 }
02287
02288 if ((reg == nxyter::kNxRegdelayTestPuls) ||
02289 (reg == nxyter::kNxRegdelayTestTrig) ||
02290 (reg == nxyter::kNxRegdelayClock1) ||
02291 (reg == nxyter::kNxRegdelayClock2) ||
02292 (reg == nxyter::kNxRegdelayClock3)) {
02293 int32_t del = val;
02294 val = nxyter::NxI2c::delayToSetting(del);
02295 std::cout << "rocutil-I: map delay " << del
02296 << " to register value " << val << std::endl;
02297 }
02298
02299 for (int i=nxbeg; i<=nxend; i++) {
02300 if (check_nxoffline(i, nxbeg, nxend)) continue;
02301 int rc = gFeb->nx(i).i2c().setRegister(uint8_t(reg), uint8_t(val), true);
02302 print_opererr("NxI2c::setRegister", rc);
02303 }
02304
02305 return 0;
02306 }
02307
02308
02309
02310 int cmd_getnx()
02311 {
02312 int32_t nxbeg=0;
02313 int32_t nxend=0;
02314 int32_t reg;
02315 if (get_nxrange(nxbeg, nxend)) return 1;
02316 if (get_arg(reg, 0, 0, 255)) return 1;
02317 if (args_check(kNeedFeb)) return 1;
02318
02319 if (reg == nxyter::kNxRegTrimDAQPower) {
02320 std::cout << "rocutil-E: use 'printnx' to see Reg 42" << std::endl;
02321 return 1;
02322 }
02323
02324 for (int i=nxbeg; i<=nxend; i++) {
02325 if (check_nxoffline(i, nxbeg, nxend)) {
02326 std::cout << "nxind=" << i << " is is set OFFLINE" << std::endl;
02327 continue;
02328 }
02329
02330 uint8_t val;
02331 int rc = gFeb->nx(i).i2c().getRegister(uint8_t(reg), val);
02332 if (print_opererr("NxI2c::getRegister", rc)) return 0;
02333
02334 static boost::format fmt("nxind=%|1| (%|1|,%|3|) "
02335 "Reg(%|2|) %|-14|: 0x%|02x| %|3|");
02336
02337 const char* name = nxyter::NxI2c::registerName(reg);
02338 if (name[0] == 0) name = "..not in nX..";
02339
02340 std::cout << fmt % i % gFeb->getPortNumber() %
02341 uint32_t(gFeb->nx(i).i2c().getSlaveAddr()) % reg %
02342 name % uint32_t(val)% uint32_t(val);
02343
02344 std::cout << " : ";
02345 for (int i=7; i>=0; i--) std::cout << ((val & (1<<i)) ? " 1" : " 0");
02346
02347 if (reg == nxyter::kNxRegdelayTestPuls ||
02348 reg == nxyter::kNxRegdelayTestTrig ||
02349 reg == nxyter::kNxRegdelayClock1 ||
02350 reg == nxyter::kNxRegdelayClock2 ||
02351 reg == nxyter::kNxRegdelayClock3) {
02352 static boost::format fmt_del(" : delay=%|3|");
02353 std::cout << fmt_del % uint16_t(nxyter::NxI2c::settingToDelay(val));
02354 }
02355 std::cout << std::endl;
02356 }
02357
02358 return 0;
02359 }
02360
02361
02362
02363 int cmd_setnxmode()
02364 {
02365 int32_t nxbeg=0;
02366 int32_t nxend=0;
02367 bool testpuls=false;
02368 bool testtrig=false;
02369 int32_t calselect=3;
02370 if (get_nxrange(nxbeg, nxend)) return 1;
02371 if (get_arg(testpuls, "tpul=")) return 1;
02372 if (get_arg(testtrig, "ttri=")) return 1;
02373 if (get_arg(calselect, "csel=", 0, 3)) return 1;
02374 if (args_check(kNeedFeb)) return 1;
02375
02376 for (int i=nxbeg; i<=nxend; i++) {
02377 if (check_nxoffline(i, nxbeg, nxend)) continue;
02378 int rc;
02379 rc = gFeb->nx(i).i2c().setTestModes(testpuls, testtrig, calselect);
02380 print_opererr("NxI2c::setTestModes", rc);
02381 }
02382 return 0;
02383 }
02384
02385
02386
02387 int cmd_setnxmask()
02388 {
02389 int32_t nxbeg=0;
02390 int32_t nxend=0;
02391 bool val=false;
02392 int32_t ibeg=0;
02393 int32_t iend=127;
02394 int32_t istep=1;
02395 if (get_nxrange(nxbeg, nxend)) return 1;
02396 if (get_arg(val, "val=")) return 1;
02397 if (get_arg(ibeg, "ibeg=", 0, 127)) return 1;
02398 if (get_arg(iend, "iend=", 0, 127)) return 1;
02399 if (get_arg(istep, "istep=", 1, 64)) return 1;
02400 if (args_check(kNeedFeb)) return 1;
02401
02402 for (int i=nxbeg; i<=nxend; i++) {
02403 if (check_nxoffline(i, nxbeg, nxend)) continue;
02404 int rc;
02405 nxyter::NxContext cntx;
02406 rc = gFeb->nx(i).i2c().getContext(cntx, nxyter::kDoMask);
02407 print_opererr("NxI2c::getContext", rc);
02408
02409 cntx.setChannelMaskBit(ibeg, iend, val, istep);
02410
02411 rc = gFeb->nx(i).i2c().setContext(cntx, nxyter::kDoMask);
02412 print_opererr("NxI2c::setContext", rc);
02413 }
02414 return 0;
02415 }
02416
02417
02418
02419 int cmd_setnxtrim()
02420 {
02421 int32_t nxbeg=0;
02422 int32_t nxend=0;
02423 int32_t val=16;
02424 int32_t ibeg=0;
02425 int32_t iend=127;
02426 int32_t istep=1;
02427 if (get_nxrange(nxbeg, nxend)) return 1;
02428 if (get_arg(val, "val=", 0, 31)) return 1;
02429 if (get_arg(ibeg, "ibeg=", 0, 128)) return 1;
02430 if (get_arg(iend, "iend=", 0, 128)) return 1;
02431 if (get_arg(istep, "istep=", 1, 64)) return 1;
02432 if (args_check(kNeedFeb)) return 1;
02433
02434 for (int i=nxbeg; i<=nxend; i++) {
02435 if (check_nxoffline(i, nxbeg, nxend)) continue;
02436 int rc;
02437 nxyter::NxContext cntx;
02438 rc = gFeb->nx(i).i2c().getContext(cntx, nxyter::kDoTrim);
02439 print_opererr("NxI2c::getContext", rc);
02440
02441 cntx.setThresholdTrim(ibeg, iend, uint8_t(val), istep);
02442
02443 rc = gFeb->nx(i).i2c().setContext(cntx, nxyter::kDoTrim);
02444 print_opererr("NxI2c::setContext", rc);
02445 }
02446 return 0;
02447 }
02448
02449
02450
02451 int cmd_setnxpower()
02452 {
02453 int32_t nxbeg=0;
02454 int32_t nxend=0;
02455 bool val=false;
02456 int32_t ibeg=0;
02457 int32_t iend=127;
02458 int32_t istep=1;
02459 if (get_nxrange(nxbeg, nxend)) return 1;
02460 if (get_arg(val, "val=")) return 1;
02461 if (get_arg(ibeg, "ibeg=", 0, 128)) return 1;
02462 if (get_arg(iend, "iend=", 0, 128)) return 1;
02463 if (get_arg(istep, "istep=", 1, 64)) return 1;
02464 if (args_check(kNeedFeb)) return 1;
02465
02466 for (int i=nxbeg; i<=nxend; i++) {
02467 if (check_nxoffline(i, nxbeg, nxend)) continue;
02468 int rc;
02469 nxyter::NxContext cntx;
02470 rc = gFeb->nx(i).i2c().getContext(cntx, nxyter::kDoTrim);
02471 print_opererr("NxI2c::getContext", rc);
02472
02473 cntx.setPowerOffMaskBit(ibeg, iend, val, istep);
02474
02475 rc = gFeb->nx(i).i2c().setContext(cntx, nxyter::kDoTrim);
02476 print_opererr("NxI2c::setContext", rc);
02477 }
02478
02479 return 0;
02480 }
02481
02482
02483
02484 int cmd_resetnxi2cbus()
02485 {
02486 if (args_check(kNeedFeb)) return 1;
02487 gFeb->resetNxI2cBus();
02488 return 0;
02489 }
02490
02491
02492
02493 int cmd_resetnxi2creg()
02494 {
02495 if (args_check(kNeedFeb)) return 1;
02496 gFeb->resetNxI2cRegister();
02497 return 0;
02498 }
02499
02500
02501
02502 int cmd_seti2c()
02503 {
02504 bool loop = get_opt("-l");
02505 bool veri = get_opt("-v");
02506 int32_t addr;
02507 int32_t reg;
02508 int32_t val;
02509 int32_t ecnt = 0;
02510
02511 if (get_arg(addr, 0, 0, 127)) return 1;
02512 if (get_arg(reg, 0, 0, 255)) return 1;
02513 if (get_arg(val, 0, 0, 255)) return 1;
02514 if (args_check(kNeedFeb)) return 1;
02515
02516 roc::I2cDevice i2c(gRocBoard, gFeb->getPortNumber(), addr);
02517 gUtil->startLoop(0.);
02518 while(gUtil->testLoop()) {
02519 int rc = i2c.setRegister(reg, val, veri);
02520 if (rc) {
02521 std::cout << std::dec << ecnt << " : " << base::Board::operErrToString(rc) << std::endl;
02522 ecnt++;
02523 }
02524 if (!loop) break;
02525 }
02526
02527 if (loop) print_loop_stats("seti2c", ecnt);
02528
02529 return 0;
02530 }
02531
02532
02533
02534 int cmd_geti2c()
02535 {
02536 bool loop = get_opt("-l");
02537 bool wide = get_opt("-w");
02538 int32_t addr;
02539 int32_t reg;
02540 uint8_t val8;
02541 uint16_t val;
02542 uint16_t valold = 0;
02543 uint64_t count = 0;
02544 int ecnt = 0;
02545
02546 if (get_arg(addr, 0, 0, 127)) return 1;
02547 if (get_arg(reg, 0, 0, 255)) return 1;
02548 if (args_check(kNeedBoard)) return 1;
02549 if (gRocBoard)
02550 if (args_check(kNeedFeb)) return 1;
02551
02552 if (gUtil==0) {
02553 printf("No utility instance available - break\n");
02554 return 1;
02555 }
02556
02557 roc::I2cDevice i2c(gBaseBoard, gFeb ? gFeb->getPortNumber() : 0, addr);
02558
02559 gUtil->startLoop(0.);
02560
02561 while(gUtil->testLoop()) {
02562 int rc;
02563
02564 if (wide) {
02565 rc = i2c.getRegister16(reg, val);
02566 } else {
02567 rc = i2c.getRegister(reg, val8);
02568 val = uint16_t(val8);
02569 }
02570 if (rc) std::cout << base::Board::operErrToString(rc) << std::endl;
02571 if (count==0) {
02572 static boost::format fmt("addr=%|3|,reg=%|3| -> read %|5| 0x%04x");
02573 std::cout << fmt % addr % reg % uint32_t(val) % uint32_t(val);
02574 if (wide) {
02575 static boost::format fmt(" (%|2|,%|4|)");
02576 std::cout << fmt % uint32_t((val>>12)&0xf) % uint32_t(val&0xfff);
02577 }
02578 std::cout << std::endl;
02579 valold = val;
02580 } else if (val != valold) {
02581 ecnt++;
02582 static boost::format fmt(" loop %|8| -> read %|5| 0x%04x");
02583 std::cout << fmt % count % uint32_t(val) % uint32_t(val) << std::endl;
02584 valold = val;
02585 }
02586 count++;
02587 if (!loop) break;
02588 }
02589
02590 if (loop) print_loop_stats("geti2c", ecnt);
02591
02592 return 0;
02593 }
02594
02595
02596
02597 int cmd_puti2c()
02598 {
02599 int32_t addr;
02600 int32_t reg;
02601 int32_t val;
02602
02603 if (get_arg(addr, 0, 0, 127)) return 1;
02604 if (get_arg(reg, 0, 0, 255)) return 1;
02605 if (get_arg(val, 0, 0, 255)) return 1;
02606 if (args_check(kNeedBoard)) return 1;
02607 if (gRocBoard)
02608 if (args_check(kNeedFeb)) return 1;
02609
02610 if (gUtil==0) {
02611 printf("No utility instance available - break\n");
02612 return 1;
02613 }
02614
02615 roc::I2cDevice i2c(gBaseBoard, gFeb ? gFeb->getPortNumber() : 0, addr);
02616
02617 int rc = i2c.setRegister(reg, val);
02618 if (rc) std::cout << base::Board::operErrToString(rc) << std::endl;
02619 static boost::format fmt("addr=%|3|,reg=%|3| -> write %|5| 0x%04x");
02620 std::cout << fmt % addr % reg % uint32_t(val) % uint32_t(val) << std::endl;
02621
02622 return 0;
02623 }
02624
02625
02626
02627
02628 int cmd_setadcdef()
02629 {
02630 if (args_check(kNeedFeb)) return 1;
02631 int rc = gFeb->adc().setToDefault();
02632 print_opererr("MainAdc::setToDefault", rc);
02633 return 0;
02634 }
02635
02636
02637
02638 int cmd_setadc()
02639 {
02640 int32_t reg;
02641 int32_t val;
02642 if (get_arg(reg, 0, 0, 255)) return 1;
02643 if (get_arg(val, 0, 0, 255)) return 1;
02644 if (args_check(kNeedFeb)) return 1;
02645 int rc = gFeb->adc().setRegister(uint8_t(reg), uint8_t(val), true);
02646 print_opererr("MainAdc::setRegister", rc);
02647 return 0;
02648 }
02649
02650
02651
02652 int cmd_setadcpatt()
02653 {
02654 int32_t tm0(0), tm1(0), tm2(0), tm3(0), upatt(-1);
02655 if (get_arg(tm0, "tm0=", 0, 12)) return 1;
02656 if (get_arg(tm1, "tm1=", 0, 12)) return 1;
02657 if (get_arg(tm2, "tm2=", 0, 12)) return 1;
02658 if (get_arg(tm3, "tm3=", 0, 12)) return 1;
02659 if (get_arg(upatt, "upatt=")) return 1;
02660 if (args_check(kNeedFeb)) return 1;
02661 int rc;
02662 rc = gFeb->adc().setTestMode(0, uint8_t(tm0));
02663 if (rc==0) rc = gFeb->adc().setTestMode(1, uint8_t(tm1));
02664 if (rc==0) rc = gFeb->adc().setTestMode(2, uint8_t(tm2));
02665 if (rc==0) rc = gFeb->adc().setTestMode(3, uint8_t(tm3));
02666 if (rc==0 && upatt != -1) gFeb->adc().setUserPattern(uint16_t(upatt));
02667 print_opererr("MainAdc::setTestMode/setUserPattern", rc);
02668 return 0;
02669 }
02670
02671
02672
02673 int cmd_setadcclock()
02674 {
02675 int32_t dly;
02676 if (get_arg(dly, 0, 0, 31)) return 1;
02677 if (args_check(kNeedFeb)) return 1;
02678 gFeb->adc().setClockDelay(dly);
02679 return 0;
02680 }
02681
02682
02683
02684 int cmd_getadcdirect()
02685 {
02686 bool opt_d = get_opt("-d");
02687 if (args_check(kNeedFeb)) return 1;
02688
02689 for (int ch=0; ch<4; ch++) {
02690 std::cout << " " << std::dec << ch << " : ";
02691 int imax = (opt_d) ? 14 : 18;
02692 int rcsum = 0;
02693 for (int i=0; i<imax; i++) {
02694 uint32_t val;
02695 int rc = gFeb->adc().getAdcDirect(ch, val);
02696 if (rc) rcsum = rc;
02697 if (opt_d) {
02698 static boost::format fmt(" %|4|");
02699 std::cout << fmt % val;
02700 } else {
02701 static boost::format fmt(" %03x");
02702 std::cout << fmt % val;
02703 }
02704 }
02705 std::cout << std::endl;
02706 print_opererr("MainAdc::getAdcDirect", rcsum);
02707 }
02708 return 0;
02709 }
02710
02711
02712 void print_40f_41f(float val)
02713 {
02714 static boost::format fmt_40f("%4.0f");
02715 static boost::format fmt_41f("%4.1f");
02716 if (val < 99.9) {
02717 std::cout << " " << fmt_41f % val;
02718 } else {
02719 std::cout << " " << fmt_40f % val;
02720 }
02721 }
02722
02723
02724 void print_dfa_ent_med_w50(int vb, int ncha, nxyter::DistFunc& df_ent,
02725 nxyter::DistFunc& df_med, nxyter::DistFunc& df_w50,
02726 bool mode_ent, bool phead)
02727 {
02728 if (phead) {
02729 if (mode_ent) {
02730 std::cout << " #hits : ADC median :ADC Width 25-75" << std::endl;
02731 std::cout << "val #ch : min 3% 10% med 90% 97% max : 10% med 90% : med w50 w80" << std::endl;
02732 } else {
02733 std::cout << " #hits : ADC median value :ADC Width 25-75" << std::endl;
02734 std::cout << "val #ch : 5% med 95% : min 3% 10% med 90% 97% max : med w50 w80" << std::endl;
02735 }
02736 }
02737
02738 static boost::format fmt_3d("%3d");
02739 static boost::format fmt_40f("%4.0f");
02740 static boost::format fmt_41f("%4.1f");
02741 float p4of128 = 4./128.;
02742
02743 std::cout << fmt_3d % vb;
02744 std::cout << " " << fmt_3d % ncha;
02745 if (mode_ent) {
02746 std::cout << " : " << fmt_40f % df_ent.getMin();
02747 std::cout << " " << fmt_40f % df_ent(p4of128);
02748 std::cout << " " << fmt_40f % df_ent(.10);
02749 std::cout << " " << fmt_40f % df_ent.getMedian();
02750 std::cout << " " << fmt_40f % df_ent(.90);
02751 std::cout << " " << fmt_40f % df_ent(1.-p4of128);
02752 std::cout << " " << fmt_40f % df_ent.getMax();
02753 std::cout << " : " << fmt_40f % df_med(0.10);
02754 std::cout << " " << fmt_40f % df_med.getMedian();
02755 std::cout << " " << fmt_40f % df_med(0.90);
02756 } else {
02757 std::cout << " : " << fmt_40f % df_ent(0.05);
02758 std::cout << " " << fmt_40f % df_ent.getMedian();
02759 std::cout << " " << fmt_40f % df_ent(0.95);
02760 std::cout << " : " << fmt_40f % df_med.getMin();
02761 std::cout << " " << fmt_40f % df_med(p4of128);
02762 std::cout << " " << fmt_40f % df_med(.10);
02763 std::cout << " " << fmt_40f % df_med.getMedian();
02764 std::cout << " " << fmt_40f % df_med(.90);
02765 std::cout << " " << fmt_40f % df_med(1.-p4of128);
02766 std::cout << " " << fmt_40f % df_med.getMax();
02767 }
02768 std::cout << " :";
02769 print_40f_41f(df_w50.getMedian());
02770 print_40f_41f(df_w50.getWidth(.25));
02771 print_40f_41f(df_w50.getWidth(.40));
02772 std::cout << std::endl;
02773 }
02774
02775
02776 void get_vbiass_data(int nxind, int vb, float& med, int npuls,
02777 bool opt_v, bool phead)
02778 {
02779 int ncha = 0;
02780 nxyter::DistFunc df_ent(128);
02781 nxyter::DistFunc df_med(128);
02782 nxyter::DistFunc df_w50(128);
02783
02784 int rc;
02785 rc = gFeb->nx(nxind).i2c().setRegister(nxyter::kNxRegVbiasS, vb, true);
02786 print_opererr("setRegister(kNxRegVbiasS,...)", rc);
02787 nxyter::NxDataSummary nds;
02788 gUtil->acquireTestTriggerData(nxind, npuls, nds);
02789 if (opt_v) {
02790 nds.print(std::cout, gFeb->nx(nxind).getNxNumber());
02791 gQdaq->stats().print(std::cout);
02792 }
02793
02794 for (int ch=0; ch<128; ch++) {
02795 if (nds.numEntries(ch)==0) continue;
02796 ncha += 1;
02797 df_ent.addEntry(nds.numEntries(ch));
02798 df_med.addEntry(nds.getMedian(ch));
02799 df_w50.addEntry(nds.getWidth50(ch));
02800 }
02801
02802 print_dfa_ent_med_w50(vb, ncha, df_ent, df_med, df_w50, false, phead);
02803
02804 med = df_med.getMedian();
02805
02806 }
02807
02808
02809
02810 int cmd_scanmonadc()
02811 {
02812 int32_t nxbeg=0;
02813 int32_t nxend=0;
02814 int32_t reg;
02815 int32_t vbeg=0;
02816 int32_t vend=255;
02817 int32_t vstep=1;
02818 int32_t npuls=100;
02819 if (get_nxrange(nxbeg, nxend)) return 1;
02820 if (get_arg(reg, 0, 0, 255)) return 1;
02821 if (get_arg(vbeg, "vbeg=", 0, 255)) return 1;
02822 if (get_arg(vend, "vend=", 0, 255)) return 1;
02823 if (get_arg(vstep, "vstep=", 1, 255)) return 1;
02824 if (args_check(kNeedFeb)) return 1;
02825
02826 int rc;
02827 nxyter::NxContext save_cntx;
02828
02829 gUtil->startLoop(0.);
02830 for (int nxind=nxbeg; nxind<=nxend; nxind++) {
02831 if (!gUtil->testLoop()) break;
02832 gFeb->printNxHeadLine(std::cout, nxind);
02833 if (check_nxoffline(nxind, nxbeg, nxend)) continue;
02834
02835 rc = gFeb->nx(nxind).i2c().getContext(save_cntx, nxyter::kDoCore);
02836 print_opererr("NxI2c::getContext {save}", rc);
02837
02838 std::cout << "val : adc0 adc1 adc2 adc3" << std::endl;
02839
02840 for (int vb=vbeg; vb<=vend; vb+=vstep) {
02841 if (!gUtil->testLoop()) break;
02842 rc = gFeb->nx(nxind).i2c().setRegister(uint8_t(reg), uint8_t(vb), true);
02843 print_opererr("NxI2c::setRegister", rc);
02844 uint16_t val[4];
02845 for (int ch=0; ch<4; ch++) {
02846 rc = gFeb->getMonAdc(ch, val[ch]);
02847 print_opererr("FebBase::getMonAdc", rc);
02848 }
02849 static boost::format fmt_3("%|3|");
02850 static boost::format fmt_4("%|4|");
02851 std::cout << fmt_3 % vb << " :";
02852 for (int ch=0; ch<4; ch++) std::cout << " " << fmt_4 % val[ch];
02853 std::cout << std::endl;
02854 }
02855
02856 rc = gFeb->nx(nxind).i2c().setContext(save_cntx, nxyter::kDoCore);
02857 print_opererr("NxI2c::setContext {restore}", rc);
02858
02859 }
02860
02861 return 0;
02862 }
02863
02864
02865
02866 int cmd_scanvbiass()
02867 {
02868 bool opt_v = get_opt("-v");
02869 int32_t nxbeg=0;
02870 int32_t nxend=0;
02871 int32_t vbeg=0;
02872 int32_t vend=255;
02873 int32_t vstep=1;
02874 int32_t npuls=100;
02875 if (get_nxrange(nxbeg, nxend)) return 1;
02876 if (get_arg(vbeg, "vbeg=", 0, 255)) return 1;
02877 if (get_arg(vend, "vend=", 0, 255)) return 1;
02878 if (get_arg(vstep, "vstep=", 1, 255)) return 1;
02879 if (get_arg(npuls, "npuls=", 1, 10000)) return 1;
02880 if (args_check(kNeedFeb|kNeedDaq)) return 1;
02881
02882 int rc;
02883 nxyter::NxContext save_cntx;
02884
02885 gUtil->startLoop(0.);
02886 for (int nxind=nxbeg; nxind<=nxend; nxind++) {
02887 if (!gUtil->testLoop()) break;
02888 gFeb->printNxHeadLine(std::cout, nxind);
02889 if (check_nxoffline(nxind, nxbeg, nxend)) continue;
02890
02891 rc = gFeb->nx(nxind).i2c().getContext(save_cntx, nxyter::kDoCore);
02892 print_opererr("NxI2c::getContext {save}", rc);
02893
02894 rc = gFeb->nx(nxind).i2c().setTestModes(false, true, 0);
02895 print_opererr("NxI2c::setTestModes", rc);
02896
02897
02898 for (int vb=vbeg; vb<=vend; vb+=vstep) {
02899 if (!gUtil->testLoop()) break;
02900 float med;
02901 get_vbiass_data(nxind, vb, med, npuls, opt_v, vb==vbeg);
02902 }
02903
02904 rc = gFeb->nx(nxind).i2c().setContext(save_cntx, nxyter::kDoCore);
02905 print_opererr("NxI2c::setContext {restore}", rc);
02906
02907 }
02908
02909 return 0;
02910 }
02911
02912
02913
02914 int cmd_autovbiass()
02915 {
02916 bool opt_v = get_opt("-v");
02917 int32_t nxbeg=0;
02918 int32_t nxend=0;
02919 int32_t base=2000;
02920 int32_t npuls=200;
02921 if (get_nxrange(nxbeg, nxend)) return 1;
02922 if (get_arg(base, "base=", 0, 4095)) return 1;
02923 if (get_arg(npuls, "npuls=", 1, 10000)) return 1;
02924 if (args_check(kNeedFeb|kNeedDaq)) return 1;
02925
02926 int rc;
02927 nxyter::NxContext save_cntx;
02928
02929 gUtil->startLoop(0.);
02930 for (int nxind=nxbeg; nxind<=nxend; nxind++) {
02931 if (!gUtil->testLoop()) break;
02932 gFeb->printNxHeadLine(std::cout, nxind);
02933 if (check_nxoffline(nxind, nxbeg, nxend)) continue;
02934
02935 rc = gFeb->nx(nxind).i2c().getContext(save_cntx, nxyter::kDoCore);
02936 print_opererr("NxI2c::getContext {save}", rc);
02937
02938 rc = gFeb->nx(nxind).i2c().setTestModes(false, true, 0);
02939 print_opererr("NxI2c::setTestModes", rc);
02940
02941 int vb_beg = 0;
02942 int vb_end = 255;
02943 int vb_mid = 0;
02944 float med_beg;
02945 float med_end;
02946 float med_mid;
02947 bool nxabort = false;
02948
02949 get_vbiass_data(nxind, vb_beg, med_beg, npuls, opt_v, true);
02950 get_vbiass_data(nxind, vb_end, med_end, npuls, opt_v, false);
02951
02952 if (float(base) < std::min(med_beg, med_end) ||
02953 float(base) > std::max(med_beg, med_end)) {
02954 std::cout << "!! ABORT autovbiass: baseline target of " << std::dec << base
02955 << " is outside the range possible\n"
02956 << " with VBiasS between 0 and 255, see two lines above" << std::endl;
02957 nxabort = true;
02958 }
02959
02960 bool posgain = (med_end > med_beg);
02961
02962 while (!nxabort && vb_end-vb_beg >=2) {
02963 if (!gUtil->testLoop()) break;
02964 vb_mid = (vb_end+vb_beg)/2;
02965 get_vbiass_data(nxind, vb_mid, med_mid, npuls, opt_v, false);
02966
02967
02968 float tol = 300.;
02969 if (med_mid < std::min(med_beg, med_end)-tol ||
02970 med_mid > std::max(med_beg, med_end)+tol) {
02971 nxabort = true;
02972 std::cout << "!! ABORT autovbiass: ADC median for vb="
02973 << std::dec << vb_mid << " outside the previous bounds\n"
02974 << " determined for vb_beg=" << vb_beg
02975 << " and vb_end=" << vb_end << ", values see above." << std::endl;
02976 break;
02977 }
02978
02979 bool keepend;
02980 bool unsteady = false;
02981 if (posgain) {
02982 keepend = base >= med_mid;
02983 } else {
02984 keepend = base <= med_mid;
02985 }
02986
02987 if (keepend) {
02988 vb_beg = vb_mid;
02989 med_beg = med_mid;
02990 } else {
02991 vb_end = vb_mid;
02992 med_end = med_mid;
02993 }
02994 }
02995
02996
02997 float dif_beg = std::abs(med_beg - base);
02998 float dif_mid = std::abs(med_mid - base);
02999 float dif_end = std::abs(med_end - base);
03000 int vb_fin = 0;
03001 float med_fin = 0.;
03002
03003 if (!nxabort) {
03004 if (dif_beg < dif_mid) {
03005 vb_fin = vb_beg;
03006 med_fin = med_beg;
03007 } else if (dif_end < dif_mid) {
03008 vb_fin = vb_end;
03009 med_fin = med_end;
03010 } else {
03011 vb_fin = vb_mid;
03012 med_fin = med_mid;
03013 }
03014 static boost::format fmt("==> VBiasS=%3d median ADC=%4.0f (target=%4d)");
03015 std::cout << fmt % vb_fin % med_fin % base << std::endl;
03016 }
03017
03018 rc = gFeb->nx(nxind).i2c().setContext(save_cntx, nxyter::kDoCore);
03019 print_opererr("NxI2c::setContext {restore}", rc);
03020
03021 if (!nxabort && gUtil->testLoop()) {
03022 rc = gFeb->nx(nxind).i2c().setRegister(nxyter::kNxRegVbiasS,
03023 vb_fin, true);
03024 print_opererr("setRegister(kNxRegVbiasS,...)", rc);
03025 }
03026
03027 }
03028
03029 return 0;
03030 }
03031
03032
03033
03034 int cmd_scanvbiasf()
03035 {
03036 bool opt_v = get_opt("-v");
03037 int32_t nxbeg=0;
03038 int32_t nxend=0;
03039 int32_t vbeg=0;
03040 int32_t vend=255;
03041 int32_t vstep=1;
03042 int32_t npuls=100;
03043 if (get_nxrange(nxbeg, nxend)) return 1;
03044 if (get_arg(vbeg, "vbeg=", 0, 255)) return 1;
03045 if (get_arg(vend, "vend=", 0, 255)) return 1;
03046 if (get_arg(vstep, "vstep=", 1, 255)) return 1;
03047 if (get_arg(npuls, "npuls=", 1, 10000)) return 1;
03048 if (args_check(kNeedFeb|kNeedDaq)) return 1;
03049
03050 int rc;
03051 nxyter::NxContext save_cntx;
03052
03053 gUtil->startLoop(0.);
03054 for (int nxind=nxbeg; nxind<=nxend; nxind++) {
03055 if (!gUtil->testLoop()) break;
03056 gFeb->printNxHeadLine(std::cout, nxind);
03057 if (check_nxoffline(nxind, nxbeg, nxend)) continue;
03058
03059 rc = gFeb->nx(nxind).i2c().getContext(save_cntx,
03060 nxyter::kDoCore|nxyter::kDoMask);
03061 print_opererr("NxI2c::getContext {save}", rc);
03062
03063 rc = gFeb->nx(nxind).i2c().setTestModes(true, false, 0);
03064 print_opererr("NxI2c::setTestModes", rc);
03065
03066 for (int vb=vbeg; vb<=vend; vb+=vstep) {
03067 if (!gUtil->testLoop()) break;
03068 rc = gFeb->nx(nxind).i2c().setRegister(nxyter::kNxRegVbiasF, vb, true);
03069 print_opererr("setRegister(kNxRegVbiasF,...)", rc);
03070
03071 nxyter::NxDataSummary nds;
03072 gUtil->acquireTestPulserData(nxind, save_cntx, npuls, nds);
03073 if (opt_v) {
03074 nds.print(std::cout, gFeb->nx(nxind).getNxNumber());
03075 gQdaq->stats().print(std::cout);
03076 }
03077
03078 int ncha = 0;
03079 nxyter::DistFunc df_ent(128);
03080 nxyter::DistFunc df_med(128);
03081 nxyter::DistFunc df_w50(128);
03082
03083 for (int ch=0; ch<128; ch++) {
03084 if (nds.numEntries(ch)==0) continue;
03085 ncha += 1;
03086 df_ent.addEntry(nds.numEntries(ch));
03087 df_med.addEntry(nds.getMedian(ch));
03088 df_w50.addEntry(nds.getWidth50(ch));
03089 }
03090
03091 print_dfa_ent_med_w50(vb, ncha, df_ent, df_med, df_w50, true, vb==vbeg);
03092
03093 }
03094
03095 rc = gFeb->nx(nxind).i2c().setContext(save_cntx,
03096 nxyter::kDoCore|nxyter::kDoMask);
03097 print_opererr("NxI2c::setContext {restore}", rc);
03098
03099 }
03100
03101 return 0;
03102 }
03103
03104
03105
03106 int cmd_scanadclat()
03107 {
03108 bool opt_v = get_opt("-v");
03109 bool opt_d = get_opt("-d");
03110 int32_t nxind=0;
03111 int32_t ch=0;
03112 int32_t ch2=-1;
03113 int32_t lbeg=61;
03114 int32_t lend=68;
03115 int32_t dbeg=0;
03116 int32_t dend=31;
03117 int32_t npuls=100;
03118 if (get_nxind(nxind)) return 1;
03119 if (get_arg(ch, "ch=", 0, 127)) return 1;
03120 if (get_arg(lbeg, "lbeg=", 0, 127)) return 1;
03121 if (get_arg(lend, "lend=", 0, 127)) return 1;
03122 if (get_arg(dbeg, "dbeg=", 0, 31)) return 1;
03123 if (get_arg(dend, "dend=", 0, 31)) return 1;
03124 if (get_arg(npuls, "npuls=", 1, 10000)) return 1;
03125 if (get_arg(ch2, "ch2=", 0, 127)) return 1;
03126 if (args_check(kNeedFeb|kNeedDaq)) return 1;
03127
03128 int32_t dstep=1;
03129 int32_t lstep=1;
03130
03131 if (opt_d) {
03132 int nlat = lend-lbeg+1;
03133 if (nlat > 16) {
03134 lstep = 4;
03135 if (lend > lbeg + (nlat-1)*lstep) lend = lbeg + (nlat-1)*lstep;
03136 } else if (nlat > 8) {
03137 lstep = 2;
03138 }
03139
03140 } else {
03141 int ndly = dend-dbeg+1;
03142 if (ndly > 16) {
03143 dstep = 4;
03144 } else if (ndly > 8) {
03145 dstep = 2;
03146 }
03147 }
03148
03149 int rc;
03150 int nxnum = gFeb->nx(nxind).getNxNumber();
03151 nxyter::NxContext save_cntx;
03152
03153 rc = gFeb->nx(nxind).i2c().getContext(save_cntx,
03154 nxyter::kDoCore|nxyter::kDoMask);
03155 print_opererr("NxI2c::getContext {save}", rc);
03156 if (rc) return 0;
03157
03158 nxyter::NxContext cntx;
03159 cntx.setToDefault(false);
03160 cntx.setChannelMaskBit(0, 127, true);
03161 cntx.setChannelMaskBit(ch, ch, false);
03162 if (ch2 >= 0) {
03163 cntx.setChannelMaskBit(ch2, ch2, false);
03164 }
03165 cntx.setRegister(nxyter::kNxRegVbiasS, 0);
03166 uint8_t config0 = cntx.getRegister(nxyter::kNxRegConfig0);
03167 cntx.setRegister(nxyter::kNxRegConfig0,
03168 config0 | nxyter::kNxC0TestTrigEnable);
03169
03170 rc = gFeb->nx(nxind).i2c().setContext(cntx, nxyter::kDoCore|nxyter::kDoMask);
03171 print_opererr("NxI2c::setContext {setup}", rc);
03172
03173 gUtil->startLoop(0.);
03174
03175 uint32_t clkinit[32];
03176 uint32_t clkbufg[32];
03177
03178 float ent[128][32];
03179 float med[128][32];
03180 float w80[128][32];
03181
03182 for (int dly=0; dly<32; dly++) {
03183 clkinit[dly] = 0;
03184 clkbufg[dly] = 0;
03185 for (int lat=0; lat<128; lat++) {
03186 ent[lat][dly] = 0.;
03187 med[lat][dly] = 0.;
03188 w80[lat][dly] = 0.;
03189 }
03190 }
03191
03192 uint32_t save_clkinit;
03193 uint32_t save_clkbufg;
03194 uint32_t save_adclat;
03195 rc = gFeb->adc().getClockDelaySrInit(save_clkinit);
03196 print_opererr("MainAdc::getClockDelaySrInit {save}", rc);
03197 rc = gFeb->adc().getClockDelayBufg(save_clkbufg);
03198 print_opererr("MainAdc::getClockDelayBufg {save}", rc);
03199 rc = gFeb->adc().getChannelLatency(nxnum, save_adclat);
03200 print_opererr("MainAdc::getChannelLatency {save}", rc);
03201
03202 static boost::format fmt_04x("%04x");
03203 static boost::format fmt_1d("%1d");
03204 static boost::format fmt_2d("%2d");
03205 static boost::format fmt_3d("%3d");
03206 static boost::format fmt_40f("%4.0f");
03207
03208 if (opt_v) std::cout << "dly lat nhit med w50 w80 min max" << std::endl;
03209
03210 for (int dly=dbeg; dly<=dend; dly+=dstep) {
03211 if (!gUtil->testLoop()) break;
03212
03213 gFeb->adc().setClockDelay(dly);
03214 rc = gFeb->adc().getClockDelaySrInit(clkinit[dly]);
03215 print_opererr("MainAdc::getClockDelaySrInit", rc);
03216 rc = gFeb->adc().getClockDelayBufg(clkbufg[dly]);
03217 print_opererr("MainAdc::getClockDelayBufg", rc);
03218
03219 for (int lat=lbeg; lat<=lend; lat+=lstep) {
03220 if (!gUtil->testLoop()) break;
03221
03222 rc = gFeb->adc().setChannelLatency(nxnum, lat);
03223 print_opererr("MainAdc::setChannelLatency", rc);
03224
03225 nxyter::NxDataSummary nds;
03226 gUtil->acquireTestTriggerData(nxind, npuls, nds);
03227 ent[lat][dly] = nds.numEntries(ch);
03228 med[lat][dly] = nds.getMedian(ch);
03229 w80[lat][dly] = nds.getWidth80(ch);
03230 if (opt_v) {
03231 std::cout << " " << fmt_2d % dly;
03232 std::cout << " " << fmt_3d % lat;
03233 std::cout << " " << fmt_40f % nds.numEntries(ch);
03234 std::cout << ((nds.full(ch)) ? '+' : ' ');
03235 std::cout << " " << fmt_40f % nds.getMedian(ch);
03236 std::cout << " " << fmt_40f % nds.getWidth50(ch);
03237 std::cout << " " << fmt_40f % nds.getWidth80(ch);
03238 std::cout << " " << fmt_40f % nds.getMin(ch);
03239 std::cout << " " << fmt_40f % nds.getMax(ch);
03240 std::cout << std::endl;
03241 }
03242 }
03243 }
03244
03245 rc = gFeb->adc().setClockDelaySrInit(save_clkinit);
03246 print_opererr("MainAdc::setClockDelaySrInit {restore}", rc);
03247 rc = gFeb->adc().setClockDelayBufg(save_clkbufg);
03248 print_opererr("MainAdc::setClockDelayBufg {restore}", rc);
03249 rc = gFeb->adc().setChannelLatency(nxnum, save_adclat);
03250 print_opererr("MainAdc::setChannelLatency {restore}", rc);
03251
03252 if (opt_d) {
03253
03254
03255 int inddmed = -1;
03256 if (lstep==4 && dstep==1) {
03257 float maxdmed = 0.;
03258 for (int dly=dbeg; dly<=dend; dly+=dstep) {
03259 float absdmed = 0.;
03260 for (int lat=lbeg; lat<=lend; lat+=2*lstep) {
03261 absdmed += std::abs(med[lat][dly] - med[lat][(dly+1)%32]);
03262 if (lat+lstep <= lend) {
03263 absdmed += std::abs(med[lat+4][(dly+16)%32] -
03264 med[lat+4][(dly+17)%32]);
03265 }
03266 }
03267 if (absdmed > maxdmed) {
03268 inddmed = dly;
03269 maxdmed = absdmed;
03270 }
03271 }
03272 }
03273
03274 std::cout << "dly init s ";
03275 for (int lat=lbeg; lat<=lend; lat+=lstep) std::cout << " lat=" << fmt_3d % lat;
03276 std::cout << std::endl;
03277
03278 for (int dly=dbeg; dly<=dend; dly+=dstep) {
03279 std::cout << " " << fmt_2d % dly;
03280 std::cout << " " << fmt_04x % clkinit[dly];
03281 std::cout << " " << fmt_1d % clkbufg[dly];
03282 std::cout << ": ";
03283 for (int lat=lbeg; lat<=lend; lat+=lstep) {
03284 std::cout << " " << fmt_40f % med[lat][dly];
03285 const char* del = "/";
03286 if (inddmed >= 0) {
03287 if (((lat-lbeg)%8==0) && dly==inddmed) del = "\\";
03288 if (((lat-lbeg)%8==4) && (dly+16)%32==inddmed) del = "\\";
03289 }
03290 std::cout << del;
03291 int width = int(w80[lat][dly]);
03292 if (width > 99) width = 99;
03293 std::cout << fmt_2d % width;
03294 }
03295 std::cout << std::endl;
03296 }
03297
03298 } else {
03299 std::cout << "lat :";
03300 for (int dly=dbeg; dly<=dend; dly+=dstep) std::cout << " dly=" << fmt_2d % dly;
03301 std::cout << std::endl;
03302
03303 for (int lat=lbeg; lat<=lend; lat+=lstep) {
03304 std::cout << fmt_3d % lat << " :";
03305 for (int dly=dbeg; dly<=dend; dly+=dstep) {
03306 std::cout << " " << fmt_40f % med[lat][dly];
03307 std::cout << "/";
03308 int width = int(w80[lat][dly]);
03309 if (width > 99) width = 99;
03310 std::cout << fmt_2d % width;
03311 }
03312 std::cout << std::endl;
03313 }
03314
03315 }
03316
03317 rc = gFeb->nx(nxind).i2c().setContext(save_cntx,
03318 nxyter::kDoCore|nxyter::kDoMask);
03319 print_opererr("NxI2c::setContext {restore}", rc);
03320
03321 return 0;
03322 }
03323
03324
03325
03326 int cmd_testrocsync()
03327 {
03328 bool opt_n = get_opt("-n");
03329 bool opt_v = get_opt("-v");
03330 int32_t ch=0;
03331 int32_t scale=5;
03332 double time=10.;
03333 if (get_arg(ch, "ch=", 0, 1)) return 1;
03334 if (get_arg(scale, "scale=", 0, 21)) return 1;
03335 if (get_arg(time, "time=")) return 1;
03336 if (args_check(kNeedDaq)) return 1;
03337
03338 uint64_t nsync = 0;
03339 uint32_t syncdata_last = 0;
03340 uint32_t syncdata_inc = (1<<scale);
03341 double synctime_last = -1.;
03342 double synctime_inc = double(1<<(scale+14))/1.e9;
03343 int ecnt = 0;
03344
03345 uint32_t syncmask = ~(-(1<<scale));
03346
03347 double dif_avr = 0.;
03348 double sync_per_sec = 1.e9/(16384.*(1<<scale));
03349 double dif_avr_weight = 1./sync_per_sec;
03350
03351 static boost::format fmt_06x("%06x");
03352 static boost::format fmt_4d("%4d");
03353 static boost::format fmt_5d("%5d");
03354 static boost::format fmt_159f("%15.9f");
03355 static boost::format fmt_63f("%6.3f");
03356 static boost::format fmt_p102e("%+10.2e");
03357
03358 gQdaq->startRun(0, time, opt_n);
03359
03360 while(gQdaq->testRun()) {
03361 roc::Message& msg = gQdaq->msg();
03362 if (msg.isSyncMsg()) {
03363 if (msg.getSyncChNum() != ch) continue;
03364
03365 uint32_t syncdata = msg.getSyncData();
03366 uint32_t syncdata_exp = (syncdata_last + syncdata_inc) & 0xffffff;
03367 double synctime = gQdaq->getMsgTime();
03368 double synctime_exp = synctime_last + synctime_inc;
03369 double synctime_dif = synctime - synctime_exp;
03370
03371 nsync += 1;
03372
03373 if (opt_v && nsync <= 30) {
03374 std::cout << get_timestamp("tm");
03375 std::cout << " @" << fmt_159f % synctime;
03376 std::cout << ": SYNC ";
03377 std::cout << " Ts: " << fmt_5d % msg.getSyncTs();
03378 std::cout << " Data: 0x" << fmt_06x % syncdata;
03379 if (synctime_last >= 0.) {
03380 std::cout << " delta: " << fmt_4d % int(round(1.e9*synctime_dif));
03381 std::cout << " ns";
03382 }
03383 std::cout << std::endl;
03384 }
03385
03386 if ((syncdata & syncmask) != 0) {
03387 std::cout << get_timestamp("tm");
03388 std::cout << " @" << fmt_159f % synctime;
03389 std::cout << ": BAD LSB ERROR";
03390 std::cout << " data: 0x" << fmt_06x % syncdata;
03391 std::cout << " expected: 0x" << fmt_06x % syncdata_exp;
03392 std::cout << std::endl;
03393 ecnt += 1;
03394
03395 } else {
03396
03397 if (synctime_last>=0.) {
03398 if (syncdata != syncdata_exp) {
03399 int nmiss = syncdata - syncdata_exp;
03400 if (nmiss < 0) nmiss += 1<<24;
03401 nmiss = nmiss >> scale;
03402 std::cout << get_timestamp("tm");
03403 std::cout << " @" << fmt_159f % synctime;
03404 std::cout << ": SYNC MISS";
03405 std::cout << " now: 0x" << fmt_06x % syncdata;
03406 std::cout << " last: 0x" << fmt_06x % syncdata_last;
03407 std::cout << " nmiss: " << std::dec << nmiss;
03408 std::cout << std::endl;
03409 ecnt += 1;
03410 }
03411 dif_avr = (1.-dif_avr_weight)*dif_avr + dif_avr_weight*synctime_dif;
03412 }
03413
03414 if (opt_v && ((nsync<<scale) & 0xffff) == 0) {
03415 std::cout << get_timestamp("tm");
03416 std::cout << " @" << fmt_159f % synctime;
03417 std::cout << " : shift: ";
03418 std::cout << fmt_63f % (1.e9*dif_avr);
03419 std::cout << " ns/sync";
03420 std::cout << " drift: " << fmt_p102e % (dif_avr/synctime_inc);
03421 std::cout << std::endl;
03422 }
03423
03424 syncdata_last = syncdata;
03425 synctime_last = synctime;
03426 }
03427
03428 } else if (msg.isSysMsg() & msg.getSysMesType() == roc::SYSMSG_SYNC_PARITY) {
03429
03430
03431 double msgtime = gQdaq->getMsgTime();
03432 std::cout << get_timestamp("tm");
03433 std::cout << " @" << fmt_159f % msgtime;
03434 std::cout << ": SYNC PARITY ERROR";
03435 std::cout << " data: 0x" << fmt_06x % msg.getSysMesData();
03436 std::cout << std::endl;
03437 ecnt += 1;
03438 }
03439
03440 }
03441
03442 if (opt_v || gQdaq->stats().errorCount()>0 ) {
03443 double dtime = gQdaq->getStopTime() - gQdaq->getStartTime();
03444 gQdaq->stats().print(std::cout, dtime);
03445 }
03446
03447 print_daq_stats("testrocsync", nsync, ecnt);
03448
03449 return 0;
03450 }
03451
03452
03453
03454 int cmd_testrocaux()
03455 {
03456 bool opt_n = get_opt("-n");
03457 bool opt_v = get_opt("-v");
03458 int32_t ch=2;
03459 int32_t scale=0;
03460 double time=10.;
03461 if (get_arg(ch, "ch=", 0, 3)) return 1;
03462 if (get_arg(scale, "scale=", 0, 11)) return 1;
03463 if (get_arg(time, "time=")) return 1;
03464 if (args_check(kNeedDaq)) return 1;
03465
03466 uint64_t naux_re = 0;
03467 uint64_t naux_fe = 0;
03468 double auxtime_re_last = -1.;
03469 double auxtime_re_inc = 31.25e-9*65536./(1<<scale);
03470 int pw_last = -1;
03471 int ecnt = 0;
03472
03473 static boost::format fmt_5d("%5d");
03474 static boost::format fmt_6d("%6d");
03475 static boost::format fmt_159f("%15.9f");
03476 static boost::format fmt_30f("%3.0f");
03477 static boost::format fmt_70f("%7.0f");
03478
03479 gQdaq->startRun(0, time, opt_n);
03480
03481 while(gQdaq->testRun()) {
03482 roc::Message& msg = gQdaq->msg();
03483 if (msg.isAuxMsg()) {
03484 if (msg.getAuxChNum() != ch) continue;
03485
03486 double auxtime = gQdaq->getMsgTime();
03487 double dtime = auxtime-auxtime_re_last;
03488 int nclock = int(round(dtime/31.25e-9));
03489
03490 if (opt_v && (naux_re <= 20 || naux_fe <= 20)) {
03491 std::cout << get_timestamp("tm");
03492 std::cout << " @" << fmt_159f % auxtime;
03493 std::cout << ": AUX ";
03494 std::cout << " Ts: " << fmt_5d % msg.getAuxTs();
03495 if (auxtime_re_last >= 0.) {
03496 if (!msg.getAuxFalling()) {
03497 std::cout << " rise, peri: ";
03498 } else {
03499 std::cout << " fall, wdth: ";
03500 }
03501 std::cout << fmt_70f % (dtime*1.e9);
03502 std::cout << " ns";
03503 std::cout << fmt_6d % nclock;
03504 std::cout << " clk";
03505 }
03506 std::cout << std::endl;
03507 }
03508
03509 if (!msg.getAuxFalling()) {
03510 naux_re += 1;
03511 if (auxtime_re_last >=0.) {
03512 double dterr = dtime-auxtime_re_inc;
03513 double relerrlimit = 5.e-5;
03514 double dttol = auxtime_re_inc*relerrlimit;
03515 if (dttol < 10.e-9) dttol = 10.e-9;
03516 if (std::abs(dterr) > dttol) {
03517 std::cout << get_timestamp("tm");
03518 std::cout << " @" << fmt_159f % auxtime;
03519 std::cout << ": AUX ERROR PERI: ";
03520 std::cout << fmt_70f % (dtime*1.e9);
03521 std::cout << " ns exp: " << fmt_70f % (auxtime_re_inc*1.e9);
03522 std::cout << "+-" << fmt_30f % (dttol*1.e9);
03523 std::cout << " ns" << std::endl;
03524 ecnt += 1;
03525 }
03526 }
03527 auxtime_re_last = auxtime;
03528
03529 } else {
03530 naux_fe += 1;
03531 if (auxtime_re_last >= 0.) {
03532 if (pw_last >= 0) {
03533 int pw_exp = (pw_last & 0xf) + 1;
03534 if (nclock != pw_exp) {
03535 std::cout << get_timestamp("tm");
03536 std::cout << " @" << fmt_159f % auxtime;
03537 std::cout << ": AUX ERROR WDTH: ";
03538 std::cout << fmt_70f % (dtime*1.e9);
03539 std::cout << " ns exp: " << fmt_70f % (pw_exp*31.25);
03540 std::cout << "+- 14 ns" << std::endl;
03541 ecnt += 1;
03542 }
03543 }
03544 pw_last = nclock;
03545 }
03546 }
03547
03548 }
03549
03550 }
03551
03552 if (opt_v || gQdaq->stats().errorCount()>0 ) {
03553 double dtime = gQdaq->getStopTime() - gQdaq->getStartTime();
03554 gQdaq->stats().print(std::cout, dtime);
03555 }
03556
03557 print_daq_stats("testrocaux", naux_re, ecnt);
03558
03559 return 0;
03560 }
03561
03562
03563
03564 int cmd_testnxcntl()
03565 {
03566 int32_t nxbeg=0;
03567 int32_t nxend=0;
03568 double time=10.;
03569 if (get_nxrange(nxbeg, nxend)) return 1;
03570 if (get_arg(time, "time=")) return 1;
03571 if (args_check(kNeedFeb)) return 1;
03572
03573 for (int i=nxbeg; i<=nxend; i++) {
03574 if (check_nxoffline(i, nxbeg, nxend)) continue;
03575 if (nxend!=nxbeg) std::cout << "Test nx:" << i << std::endl;
03576 int ecnt = gUtil->testNxControlPath(i, time);
03577 print_loop_stats("testnxcntl", ecnt);
03578 if (gUtil->getLoopState()==nxyter::FebUtil::kLoopInterrupted) break;
03579 }
03580 return 0;
03581 }
03582
03583
03584
03585 int cmd_testnxregs()
03586 {
03587 int32_t nxbeg=0;
03588 int32_t nxend=0;
03589 if (get_nxrange(nxbeg, nxend)) return 1;
03590 if (args_check(kNeedFeb)) return 1;
03591
03592 for (int i=nxbeg; i<=nxend; i++) {
03593 if (check_nxoffline(i, nxbeg, nxend)) continue;
03594 if (nxend!=nxbeg) std::cout << "Test nx:" << i << std::endl;
03595 int ecnt = gUtil->testNxRegisters(i);
03596 print_loop_stats("testnxregs", ecnt);
03597 if (gUtil->getLoopState()==nxyter::FebUtil::kLoopInterrupted) break;
03598 }
03599 return 0;
03600 }
03601
03602
03603 int cmd_testadccntl()
03604 {
03605 double time=10.;
03606 if (get_arg(time, "time=")) return 1;
03607 if (args_check(kNeedFeb)) return 1;
03608
03609 int ecnt = gUtil->testMainAdcControlPath(time);
03610 print_loop_stats("testadccntl", ecnt);
03611 return 0;
03612 }
03613
03614
03615 int cmd_testadcdata()
03616 {
03617 double time=10.;
03618 if (get_arg(time, "time=")) return 1;
03619 if (args_check(kNeedFeb)) return 1;
03620
03621 int ecnt = gUtil->testMainAdcDataPath(time);
03622 print_loop_stats("testadcdata", ecnt);
03623 return 0;
03624 }
03625
03626
03627 int cmd_testfebcntl()
03628 {
03629 double time=10.;
03630 if (get_arg(time, "time=")) return 1;
03631 if (args_check(kNeedFeb)) return 1;
03632
03633 int ecnt = gUtil->testFebControlPathCombo(time);
03634 print_loop_stats("testfebcntl", ecnt);
03635 return 0;
03636 }
03637
03638
03639 int cmd_printdata()
03640 {
03641 bool opt_m = get_opt("-m");
03642 bool opt_r = get_opt("-r");
03643 bool opt_h = get_opt("-h");
03644 bool opt_t = get_opt("-t");
03645 bool opt_s = get_opt("-s");
03646 bool opt_d = get_opt("-d");
03647 bool opt_n = get_opt("-n");
03648 bool opt_ia = get_opt("-ia");
03649 int32_t nmsg=-1;
03650 double time=-1.;
03651 int32_t npuls=0;
03652 int32_t pper=100000;
03653 int32_t pwth=32;
03654 int32_t pdly=1000;
03655 if (get_arg(nmsg, "nmsg=", 0)) return 1;
03656 if (get_arg(time, "time=")) return 1;
03657 if (get_arg(npuls, "npuls=", 0, 32767)) return 1;
03658 if (get_arg(pper, "pper=", 2, 0x00ffffff)) return 1;
03659 if (get_arg(pwth, "pwth=", -0x00ffffff, 0x00ffffff)) return 1;
03660 if (get_arg(pdly, "pdly=", 1, 0x0000ffff)) return 1;
03661 if (args_check(kNeedDaq)) return 1;
03662
03663 if (nmsg < 0 && time < 0.) {
03664 if (gBaseBoard->isFile()) {
03665 nmsg = 0;
03666 time = 0.;
03667 } else {
03668 nmsg = 100;
03669 time = 10.;
03670 }
03671 }
03672 if (nmsg < 0) nmsg = 0;
03673 if (time < 0) time = 0.;
03674
03675 if (!(opt_s | opt_d)) opt_m = true;
03676
03677 int rc;
03678
03679 if (gRocNx && (npuls > 0)) {
03680 if (opt_ia) {
03681 rc = gRocNx->fireTestPulse(0,0,0);
03682 print_opererr("RocNx::fireTestPulse", rc);
03683 } else {
03684 rc = gRocNx->fireTestPulse(pdly, pper, pwth, npuls);
03685 print_opererr("RocNx::fireTestPulse", rc);
03686 }
03687 }
03688
03689 gQdaq->startRun(nmsg, time, opt_n);
03690
03691 if (opt_ia && gRocNx) {
03692 if (npuls > 0) {
03693 rc = gRocNx->fireTestPulse(pdly, pper, pwth, npuls);
03694 print_opererr("RocNx::fireTestPulse", rc);
03695 }
03696 rc = gRocNx->resetRocNxTs();
03697 print_opererr("RocNx::resetRocNxTs", rc);
03698 }
03699
03700 typedef std::auto_ptr<nxyter::DistFuncArray> ptr_dfa;
03701 ptr_dfa dfa[4];
03702 if (opt_d) {
03703 for (int i=0; i<4; i++)
03704 dfa[i] = ptr_dfa(new nxyter::DistFuncArray(128, 512));
03705 }
03706
03707
03708
03709 const static int nentmax = 100000;
03710
03711 while(gQdaq->testRun()) {
03712 roc::Message& msg = gQdaq->msg();
03713 if (opt_m) {
03714 if (opt_t) std::cout << get_timestamp("tm") << ": ";
03715 unsigned kind = roc::msg_print_Human;
03716 if (opt_r) kind = roc::msg_print_Prefix | roc::msg_print_Data;
03717 if (opt_h) kind |= roc::msg_print_Hex;
03718 msg.printData(std::cout, kind, gQdaq->getMsgEpoch());
03719 }
03720
03721 if (opt_d) {
03722 if (msg.isHitMsg()) {
03723 int nxnum = msg.getNxNumber();
03724 int nxcha = msg.getNxChNum();
03725 int nxadc = msg.getNxAdcValue();
03726 if ((*dfa[nxnum])[nxcha].numEntries() < nentmax) {
03727 (*dfa[nxnum]).addEntry(nxcha, float(nxadc));
03728 }
03729 }
03730 }
03731 }
03732
03733 if (gRocNx && (npuls > 0)) {
03734 rc = gRocNx->fireTestPulse(0,0,0);
03735 print_opererr("RocNx::fireTestPulse", rc);
03736 }
03737
03738 if (opt_d) {
03739 for (int nxnum=0; nxnum<4; nxnum++) {
03740 if ((*dfa[nxnum]).numEntries() == 0) continue;
03741 nxyter::NxDataSummary nds;
03742 nds.analyse((*dfa[nxnum]));
03743 nds.print(std::cout, nxnum);
03744 }
03745 }
03746
03747 double dtime = gQdaq->getStopTime() - gQdaq->getStartTime();
03748 gQdaq->stats().print(std::cout, dtime);
03749
03750 return 0;
03751 }
03752
03753
03754
03755
03756
03757 int autoped_issue_system_message(uint32_t type)
03758 {
03759 int rc = gRocBoard->operPPP(
03760 ROC_NX_FIFO_RESET, 1,
03761 ROC_NX_FIFO_RESET, 0,
03762 ROC_ADDSYSMSG, type );
03763 print_opererr("operPPP(ROC_ADDSYSMSG,...)", rc);
03764 return rc;
03765 }
03766
03767
03768
03769
03770 int autoped_setnxmode(bool testtrig)
03771 {
03772 int32_t nxbeg = 0;
03773 int32_t nxend = gFeb->numNx()-1;
03774 int rc = 0;
03775
03776 for (int i=nxbeg; i<=nxend; i++) {
03777 if (check_nxoffline(i, nxbeg, nxend)) continue;
03778 rc = gFeb->nx(i).i2c().setTestModes(false, testtrig, 0);
03779 print_opererr("NxI2c::setTestModes", rc);
03780 }
03781
03782 return rc;
03783 }
03784
03785
03786 int cmd_autoped()
03787 {
03788 double tmeas=30.;
03789 double tped=0.1;
03790 if (get_arg(tmeas, "tmeas=")) return 1;
03791 if (get_arg(tped, "tped=")) return 1;
03792 if (args_check(kNeedFeb)) return 1;
03793
03794 if (tmeas < 0.1 || tped < 0.05) {
03795 std::cout << "rocutil-E: tmeas or tped out of range" << std::endl;
03796 return 1;
03797 }
03798
03799 int rc;
03800
03801
03802 uint32_t gpio_mask_save;
03803 rc = gGpio->getConfig(gpio_mask_save);
03804 print_opererr("Gpio::getConfig", rc);
03805 bool riseedge, falledge, throttled, extrafunc, altin;
03806 base::Gpio::unpackConfig(gpio_mask_save, 6,
03807 riseedge, falledge, throttled, extrafunc, altin);
03808
03809 extrafunc = true;
03810 altin = true;
03811 uint32_t gpio_mask_on = gpio_mask_save;
03812 base::Gpio::packConfig(gpio_mask_on, 6,
03813 riseedge, falledge, throttled, extrafunc, altin);
03814
03815 extrafunc = false;
03816 altin = false;
03817 uint32_t gpio_mask_off = gpio_mask_save;
03818 base::Gpio::packConfig(gpio_mask_off, 6,
03819 riseedge, falledge, throttled, extrafunc, altin);
03820
03821
03822
03823 int32_t period=250000;
03824 rc = gRocNx->fireTestPulse(period, 128, 0);
03825 print_opererr("RocNx::fireTestPulse", rc);
03826
03827 int imeas = (int) ((tmeas + 0.0999) / 0.1);
03828
03829 struct timespec ts_tmeas;
03830 uint64_t itmeas = (uint64_t) (1.e9*tmeas);
03831 ts_tmeas.tv_sec = itmeas / (1000*1000*1000);
03832 ts_tmeas.tv_nsec = itmeas % (1000*1000*1000);
03833
03834 struct timespec ts_tped;
03835 uint64_t itped = (uint64_t) (1.e9*tped);
03836 ts_tped.tv_sec = itped / (1000*1000*1000);
03837 ts_tped.tv_nsec = itped % (1000*1000*1000);
03838
03839 gUtil->startLoop(0.);
03840 while (true) {
03841
03842 autoped_issue_system_message(roc::SYSMSG_USER_RECONFIGURE);
03843 autoped_setnxmode(true);
03844 rc = gGpio->setConfig(gpio_mask_on);
03845 print_opererr("Gpio::setConfig{ped_on}", rc);
03846 autoped_issue_system_message(roc::SYSMSG_USER_CALIBR_ON);
03847
03848
03849 std::cout << get_timestamp() << " +++1a before tped wait" << std::endl;
03850 nanosleep(&ts_tped, 0);
03851 std::cout << get_timestamp() << " +++1b after tped wait" << std::endl;
03852
03853
03854 autoped_issue_system_message(roc::SYSMSG_USER_RECONFIGURE);
03855 rc = gGpio->setConfig(gpio_mask_off);
03856 print_opererr("Gpio::setConfig{ped_off}", rc);
03857 autoped_setnxmode(false);
03858 autoped_issue_system_message(roc::SYSMSG_USER_CALIBR_OFF);
03859
03860
03861 if (!gUtil->testLoop()) break;
03862 std::cout << get_timestamp() << " +++1c before tmeas wait" << std::endl;
03863 nanosleep(&ts_tmeas, 0);
03864 std::cout << get_timestamp() << " +++1d after tmeas wait" << std::endl;
03865 if (!gUtil->testLoop()) break;
03866 }
03867
03868 rc = gGpio->setConfig(gpio_mask_save);
03869 print_opererr("Gpio::setConfig{restore}", rc);
03870
03871
03872 rc = gRocNx->fireTestPulse(0, 0, 0);
03873 print_opererr("RocNx::fireTestPulse", rc);
03874
03875 return 0;
03876 }
03877
03878
03879 int cmd_testnxdata()
03880 {
03881 std::cout << "currently deactivated" << std::endl;
03882
03883 #ifdef never
03884 bool opt_p = get_opt("-p");
03885 bool opt_r = get_opt("-r");
03886 bool opt_s = get_opt("-s");
03887 double time=10.;
03888 if (get_arg(time, "time=")) return 1;
03889 if (args_check(kNeedFeb|kNeedDaq)) return 1;
03890
03891 int rc;
03892 rc = gFeb->setToDefault();
03893 if (print_opererr("FebBase::setToDefault", rc)) return 0;
03894
03895 for (int i=0; i<16; i++) {
03896 rc = gFeb->setNxRegisterAll(i,0xff);
03897 if (print_opererr("FebBase::setNxRegisterAll", rc)) return 0;
03898 }
03899
03900 rc = gFeb->setNxRegisterAll(1,0xf0);
03901 if (print_opererr("FebBase::setNxRegisterAll", rc)) return 0;
03902
03903 rc = gFeb->setNxTestModes(false, true, 0);
03904 if (print_opererr("FebBase::setNxTestModes", rc)) return 0;
03905
03906 nxyter::QuickDaq qd(gRocBoard, gFeb);
03907
03908 qd.startRun(0, time);
03909
03910 rc = gRocNx->fireTestPulse(100000, 50000, 0);
03911 print_opererr("RocNx::fireTestPulse", rc);
03912
03913 gUtil->startLoop(time+2.);
03914
03915 double npulslast = -1.;
03916 int nhit = 4;
03917 double tsbase = -1.;
03918
03919 int numnx = gFeb->numNx();
03920
03921
03922 nxyter::Data data;
03923 while(gUtil->testLoop()) {
03924 int rc = qd.getData(data);
03925 if (rc) break;
03926 if (msg.isNopMsg()) continue;
03927 if (opt_p) msg.printData(std::cout, opt_r ? 3 : 8, qd.getEpoch());
03928 if (msg.isHitMsg()) {
03929 int nxnum = msg.getNxNumber();
03930 int nxchn = msg.getNxChNum();
03931 double ts = msg.getMsgFullTime(qd.getEpoch())*1.e-9;
03932 if (tsbase < 0.) tsbase = ts;
03933
03934 double npuls = floor((2500. * (ts - tsbase)) + 0.5);
03935 double tsoffset = ts - (tsbase + npuls/2500.);
03936
03937 if (opt_p) {
03938 static boost::format fmt("Nx:%|1| Chn:%|3| puls: %|6.0f| offset:%|3.0f|");
03939 std::cout << fmt % nxnum % nxchn % npuls % (1.e9*tsoffset) << std::endl;
03940 }
03941
03942 if (npuls != npulslast) {
03943 if (tsoffset < -4.e-9 || tsoffset > +4.e-9) {
03944 std::cout << "outlayer hit, offset " << int(1.e9*tsoffset)
03945 << "ns" << std::endl;
03946 msg.printData(std::cout, opt_r ? 3 : 8, qd.getEpoch());
03947 }
03948 if (nhit != 4*numnx) {
03949 std::cout << "last pulse has != 4*numnx hits, nhit = " << nhit << std::endl;
03950 }
03951 if (npuls != npulslast + 1.) {
03952 std::cout << "pulses missing, now " << int(npuls)
03953 << " last was " << int(npulslast) << std::endl;
03954 }
03955 nhit = 0;
03956 npulslast = npuls;
03957 }
03958
03959 nhit += 1;
03960
03961 }
03962 }
03963
03964 if (opt_s) qd.getStats().print(std::cout);
03965
03966
03967 rc = gRocNx->fireTestPulse(0, 0, 0);
03968 print_opererr("RocNx::fireTestPulse", rc);
03969 #endif
03970
03971 return 0;
03972 }
03973
03974
03975
03976 int cmd_saverocconf()
03977 {
03978 if (args_check(kNeedRocBoard)) return 1;
03979
03980 roc::UdpBoard* udp = dynamic_cast<roc::UdpBoard*> (gRocBoard);
03981 if (udp) {
03982 udp->saveConfig();
03983 } else {
03984 std::cout << "rocutil-E: only supported for 'ROC-over-Ethernet'" << std::endl;
03985 }
03986
03987 return 0;
03988 }
03989
03990
03991
03992 int cmd_restartbrd()
03993 {
03994 if (args_check(kNeedBoard)) return 1;
03995
03996 std::cout << "rocutil-I: Board self-destruct initiated, have a nice day :)" << std::endl;
03997 gBaseBoard->restartBoard();
03998 std::cout << "rocutil-I: restart rocutil when board back on-line" << std::endl;
03999 std::cout << "rocutil-I: use 'setbrddef' command to initialize board" << std::endl;
04000
04001 return -2;
04002 }
04003
04004
04005
04006 int cmd_printrocmap()
04007 {
04008 bool byname = get_opt("-n");
04009 if (args_check(kNeedBoard)) return 1;
04010 gBaseBoard->printRegAddressMap(std::cout, byname);
04011 return 0;
04012 }
04013
04014
04015
04016
04017 int cmd_putroc()
04018 {
04019 std::string sname;
04020 int32_t val;
04021 if (get_arg(sname, 0)) return 1;
04022 if (get_arg(val, 0)) return 1;
04023 if (args_check(kNeedBoard)) return 1;
04024
04025 uint32_t addr = gBaseBoard->findRegAddressByName(sname.c_str());
04026
04027 if (addr==base::Board::kAddrError) {
04028 const char* cstr = sname.c_str();
04029 char* eptr(0);
04030 int base(0);
04031
04032 if (cstr[0]=='b' || cstr[0]=='B') { cstr += 1; base = 2; }
04033 addr = strtol(cstr, &eptr, base);
04034 if (errno || (eptr && (*eptr!=0))) {
04035 std::cout << "Board address '" << sname << "' not known" << std::endl;
04036 return 0;
04037 }
04038 }
04039
04040 uint32_t value = uint32_t(val);
04041 int rc = gBaseBoard->put(addr, value);
04042 print_opererr("Board::put", rc);
04043 if (rc==0) {
04044 static boost::format fmt("put(%s [0x%08x]) -> 0x%08x %10d");
04045 std::cout << fmt % sname % addr % value % value << std::endl;
04046 }
04047 return 0;
04048 }
04049
04050
04051
04052 int cmd_getroc()
04053 {
04054 std::string sname;
04055 if (get_arg(sname, 0)) return 1;
04056 if (args_check(kNeedBoard)) return 1;
04057
04058 uint32_t addr = gBaseBoard->findRegAddressByName(sname.c_str());
04059 if (addr==base::Board::kAddrError) {
04060 const char* cstr = sname.c_str();
04061 char* eptr(0);
04062 int base(0);
04063
04064 if (cstr[0]=='b' || cstr[0]=='B') { cstr += 1; base = 2; }
04065 addr = strtol(cstr, &eptr, base);
04066 if (errno || (eptr && (*eptr!=0))) {
04067 std::cout << "Board address '" << sname << "' not known" << std::endl;
04068 return 0;
04069 }
04070 }
04071
04072 uint32_t value;
04073 int rc = gBaseBoard->get(addr, value);
04074 if (rc==0) {
04075 static boost::format fmt("get(%s [0x%08x]) -> 0x%08x %10d");
04076 std::cout << fmt % sname % addr % value % value << std::endl;
04077 }
04078 print_opererr("Board::get", rc);
04079 return 0;
04080 }
04081
04082
04083
04084 int cmd_resetrocnxts()
04085 {
04086 if (gRocNx==0) return 1;
04087 int rc = gRocNx->resetRocNxTs();
04088 print_opererr("RocNx::resetRocNxTs", rc);
04089 return 0;
04090 }
04091
04092
04093
04094
04095 int cmd_printdatadbg()
04096 {
04097 bool opt_c = get_opt("-c");
04098 bool opt_ib = get_opt("-ib");
04099 bool opt_ia = get_opt("-ia");
04100 int32_t nmsg=100;
04101 double time=1.;
04102 if (get_arg(nmsg, "nmsg=", 1)) return 1;
04103 if (get_arg(time, "time=")) return 1;
04104 if (args_check(kNeedDaq)) return 1;
04105
04106 std::vector<nxyter::DataDebug> datvec;
04107
04108 int rc = gRocNx->setDebugMode(1);
04109 print_opererr("RocNx::setDebugMode", rc);
04110
04111 gUtil->startLoop(time);
04112 int nempty = 0;
04113
04114 if (opt_ib) {
04115 rc = gRocNx->resetRocNxTs();
04116 print_opererr("RocNx::resetRocNxTs", rc);
04117 }
04118
04119 if (opt_c) gRocBoard->clearRocFifo();
04120
04121 if (opt_ia) {
04122 rc = gRocNx->resetRocNxTs();
04123 print_opererr("RocNx::resetRocNxTs", rc);
04124 }
04125
04126 std::cout << "getDataDebug(): ";
04127 while(gUtil->testLoop() && datvec.size() < nmsg) {
04128 rc = gRocNx->getDataDebug(datvec, nmsg-datvec.size());
04129 if (rc < 0) {
04130 std::cout << "getDataDebug(): bail-out with rc=" << rc << std::endl;
04131 break;
04132 }
04133 if (rc >0) {
04134 if (nempty > 0) std::cout << "(" << nempty << ") ";
04135 std::cout << rc << " ";
04136 nempty = 0;
04137 } else {
04138 nempty += 1;
04139 }
04140 }
04141 std::cout << std::endl;
04142
04143 rc = gRocNx->setDebugMode(0);
04144 print_opererr("RocNx::setDebugMode", rc);
04145
04146 for (int i=0; i<datvec.size(); i++) {
04147 datvec[i].print(std::cout);
04148 }
04149
04150 return 0;
04151 }
04152
04153
04154 void acquire_data( int nxind, std::vector<std::vector<float> > & data, float time )
04155 {
04156 if( data.size() != 128 ) {
04157 printf("Error in acquire_data: data must be vector[128][4096] of floats\n");
04158 return;
04159 }
04160 for( int iChannel = 0; iChannel < 128; iChannel++ ) {
04161 if( data.at(iChannel).size() != 4096 ) {
04162 printf("Error in acquire_data: data must be vector[128][4096] of floats\n");
04163 return;
04164 }
04165 data.at(iChannel).assign( 4096, 0. );
04166 }
04167
04168 gQdaq->startRun( 0, time, true );
04169
04170 while( gQdaq->testRun() ) {
04171 roc::Message & msg = gQdaq->msg();
04172
04173 if( msg.isHitMsg() ) {
04174 int num = msg.getNxNumber();
04175 if (num != nxind) {
04176 printf("Error in acquire_data: hit from nXYTER %d received, while not expected\n", num);
04177 }
04178 uint8_t ch = msg.getNxChNum();
04179 uint16_t adcVal = msg.getNxAdcValue();
04180 data.at(ch).at(adcVal)++;
04181 }
04182 }
04183 if (gQdaq->stats().errorCount()) {
04184 gQdaq->stats().print(std::cout, 0., nxyter::QuickDaqStats::kPrintError);
04185 }
04186 }
04187
04188
04189 void acquire_data(int nxind, std::vector<int> & nhits, float time)
04190 {
04191 if( nhits.size() != 128 ) {
04192 printf("Error in count_pulses: npulses is expected to be 128 in size\n");
04193 return;
04194 }
04195 nhits.assign( 128, 0 );
04196
04197 gQdaq->startRun( 0, time, true );
04198
04199 while( gQdaq->testRun() ) {
04200 roc::Message & msg = gQdaq->msg();
04201
04202 if( msg.isHitMsg() ) {
04203 int num = msg.getNxNumber();
04204 if (num != nxind) {
04205 printf("Error in acquire_data: hit from nXYTER %d received, while not expected\n", num);
04206 }
04207 int ch = msg.getNxChNum();
04208 nhits.at(ch)++;
04209 }
04210 }
04211 if (gQdaq->stats().errorCount()) {
04212 gQdaq->stats().print(std::cout, 0., nxyter::QuickDaqStats::kPrintError);
04213 }
04214 }
04215
04216
04217 void autotrim_print_rates(const std::vector<int> & npulses, double time )
04218 {
04219 printf(" -- -- -- -- -- -- -- -- -- -- -- Rates per channel -- -- -- -- -- -- -- -- -- -- --\n");
04220 for( int i=0; i < 16; i++ ) {
04221 printf(" %3d..%-3d:", i*8, i*8 + 7);
04222 for( int j=0; j < 8; j++ ) {
04223 printf( "%9.1f", static_cast<float>( npulses.at(i*8 + j) ) / time );
04224 }
04225 printf("\n");
04226 }
04227 printf(" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --\n");
04228 }
04229
04230 void autotrim_print_trim(const nxyter::NxContext & cntx_trim)
04231 {
04232 printf(" -- -- -- -- -- -- -- -- -- -- -- -- Trim values -- -- -- -- -- -- -- -- -- -- -- --\n");
04233 for( int i = 0; i < 16; i++ ) {
04234 printf(" %3d..%-3d:", i*8, i*8 + 7);
04235 for( int j = 0; j < 8; j++ ) {
04236 int ch = i * 8 + j;
04237 printf("%9d", cntx_trim.getThresholdTrim(ch));
04238 }
04239 printf("\n");
04240 }
04241 printf(" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --\n");
04242 }
04243
04244 void autotrim_print_trim_dbg(const nxyter::NxContext & cntx_trim, const std::vector<int> & trim_min, const std::vector<int> & trim_max )
04245 {
04246 printf(" -- -- -- -- -- -- -- -- -- -- -- -- Trim values -- -- -- -- -- -- -- -- -- -- -- --\n");
04247 for( int i = 0; i < 16; i++ ) {
04248 printf(" %3d..%-3d:", i*8, i*8 + 7);
04249 for( int j = 0; j < 8; j++ ) {
04250 int ch = i * 8 + j;
04251 printf("%2d(%2d-%2d)", cntx_trim.getThresholdTrim(ch), trim_min.at(ch), trim_max.at(ch));
04252 }
04253 printf("\n");
04254 }
04255 printf(" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --\n");
04256 }
04257
04258 float get_npuls_avg( const std::vector< int > & npuls, int nchactive )
04259 {
04260 int npuls_tot = 0;
04261 for( int ch = 0; ch < npuls.size(); ch++ ) {
04262 npuls_tot += npuls[ch];
04263 }
04264 return static_cast<float>( npuls_tot ) / nchactive;
04265 }
04266
04267
04268
04269
04270
04271 int cmd_autotrim()
04272 {
04273 const int knch = 128;
04274 int gainsign_vth = 1;
04275 int gainsign_trim = -1;
04276 bool posgain_vth = true;
04277 bool posgain_trim = false;
04278
04279
04280 bool opt_k = get_opt("-k");
04281 bool opt_m = get_opt("-m");
04282 bool opt_q = get_opt("-q");
04283 bool opt_t = get_opt("-t");
04284
04285
04286 int32_t nxbeg=0;
04287 int32_t nxend=0;
04288 if (get_nxrange(nxbeg, nxend)) return 1;
04289
04290 double rate;
04291 if (get_arg(rate)) return 1;
04292
04293 double time = 4;
04294 if (get_arg(time,"time=")) return 1;
04295 if( time < 0. ) {
04296 printf("ERROR in cmd_autotrim: time must be larger than 0.\n");
04297 return 1;
04298 }
04299
04300 int32_t vth_range_min = 20;
04301 if (get_arg(vth_range_min, "vth_min=", 0, 255)) return 1;
04302
04303 int32_t vth_range_max = 255;
04304 if (get_arg(vth_range_max, "vth_max=", 1, 255)) return 1;
04305 if( vth_range_max < vth_range_min ) {
04306 printf("ERROR in cmd_autotrim: vth_max must be larger than vth_min\n");
04307 return 1;
04308 }
04309
04310 double target = 0.5;
04311 if (get_arg(target, "target=")) return 1;
04312 if( target < 0. || target > 1.) {
04313 printf("ERROR in cmd_autotrim: target must be within ( 0. ; 1. ) range \n");
04314 return 1;
04315 }
04316
04317 if (args_check(kNeedFeb|kNeedDaq)) return 1;
04318
04319
04320
04321
04322
04323
04324
04325
04326
04327 for( int nxind = nxbeg; nxind <= nxend; nxind++ ) {
04328
04329
04330 int rc;
04331 uint8_t vth_init;
04332 rc = gFeb->nx(nxind).i2c().getRegister(nxyter::kNxRegVth, vth_init);
04333 print_opererr("getRegister(kNxRegVth,...)", rc);
04334
04335
04336 nxyter::NxContext mask_cntx;
04337 rc = gFeb->nx(nxind).i2c().getContext(mask_cntx, nxyter::kDoMask);
04338
04339
04340 int nchactive = 0;
04341 for( int ch = 0; ch < knch; ch++ ) {
04342 nchactive += ( ! mask_cntx.getChannelMaskBit(ch) );
04343 }
04344
04345
04346 nxyter::NxContext cntx_trim;
04347 rc = gFeb->nx(nxind).i2c().getContext(cntx_trim, nxyter::kDoTrim);
04348 print_opererr("GetContext(cntx_trim,...)", rc);
04349
04350 std::vector< int > npuls( knch );
04351 float npuls_exp = rate * time;
04352 if( opt_m ) {
04353 if( ! opt_q ) printf("Measuring efficiency at vth=%d, and with trim values:\n", vth_init);
04354 if( ! opt_q ) autotrim_print_trim(cntx_trim);
04355 acquire_data( nxind, npuls, time );
04356 if( ! opt_q ) autotrim_print_rates( npuls, time );
04357 if( ! opt_q ) printf( "Average efficiency: %f\n", get_npuls_avg( npuls, nchactive ) / npuls_exp );
04358 return 0;
04359 }
04360
04361
04362 if( ! opt_q ) printf("Setting trim to 16 in all channels...\n");
04363 nxyter::NxContext cntx_trim_reset;
04364 cntx_trim_reset.setThresholdTrim(0, knch - 1, 16, 1);
04365 rc = gFeb->nx(nxind).i2c().setContext(cntx_trim_reset, nxyter::kDoTrim);
04366 print_opererr("SetContext(cntx_trim_reset,...)", rc);
04367
04368 if( ! opt_t ) {
04369
04370 if( ! opt_q ) printf("Start adjusting vth to average detection efficiency of %f\n", target);
04371
04372 uint8_t vth_step = 0;
04373 int vth_step_prev_signed = 0;
04374 uint8_t vth_curr = vth_init;
04375 uint8_t vth_prev = 0;
04376
04377 {
04378 bool first = true;
04379 float eff_curr = 0;
04380 float eff_prev = 0;
04381 float diff_curr = 0;
04382 float diff_prev = 0;
04383 int vth_step_sign = 0;
04384 while( true ) {
04385
04386
04387 if( ! first ) {
04388 eff_prev = eff_curr;
04389 diff_prev = diff_curr;
04390 }
04391
04392 vth_step_prev_signed = vth_step * vth_step_sign;
04393
04394
04395 if( ! opt_q ) printf("Measuring efficiency at vth=%d...\n", vth_curr);
04396 acquire_data( nxind, npuls, time );
04397 if( ! opt_q ) autotrim_print_rates( npuls, time );
04398 eff_curr = get_npuls_avg( npuls, nchactive ) / npuls_exp;
04399 if( ! opt_q ) printf( "Average efficiency: %f\n", eff_curr );
04400 diff_curr = std::abs( target - eff_curr );
04401
04402
04403 if( ! first ) {
04404 if( ( eff_prev > eff_curr) != ( (vth_step_sign > 0) == posgain_vth ) ) {
04405 printf("WARNING: detection efficiency changes in the same direction as physical threshold -- system is not stable. Try to increase the measurement time?\n");
04406 }
04407 }
04408
04409
04410 if( ( eff_curr > target) == posgain_vth ) {
04411 vth_step_sign = 1; }
04412 else {
04413 vth_step_sign = -1;
04414 }
04415
04416
04417 if( first ) {
04418 if( vth_step_sign > 0 ) {
04419 vth_step = vth_range_max - vth_curr;
04420 }
04421 else {
04422 vth_step = vth_curr - vth_range_min;
04423 }
04424 }
04425 vth_step = vth_step / 2 + vth_step % 2;
04426
04427
04428 int vth_prelim = vth_curr + vth_step * vth_step_sign;
04429 if( vth_prelim > vth_range_max || vth_prelim < vth_range_min ) {
04430 printf("ERROR: target efficiency can not be reached with vth within the specified range\n");
04431 return 1;
04432 }
04433
04434
04435 if( ! first ) {
04436 if( vth_step == 1 && vth_step_sign == - vth_step_prev_signed ) {
04437 if( diff_prev < diff_curr ) {
04438 vth_curr = vth_prev;
04439 rc = gFeb->nx(nxind).i2c().setRegister(nxyter::kNxRegVth, vth_curr, true);
04440 print_opererr("setRegister(kNxRegVth,...)", rc);
04441 }
04442 break;
04443 }
04444 }
04445
04446
04447 vth_prev = vth_curr;
04448 vth_curr = vth_curr + vth_step * vth_step_sign;
04449 rc = gFeb->nx(nxind).i2c().setRegister(nxyter::kNxRegVth, vth_curr, true);
04450 print_opererr("setRegister(kNxRegVth,...)", rc);
04451
04452 first = false;
04453 }
04454 if( ! opt_q ) printf("Finished with vth=%d\n", vth_curr);
04455 }
04456 }
04457
04458
04459 if( ! opt_q ) printf("Start trimming the thresholds\n");
04460
04461 std::vector<int> trim_step(128, 16);
04462 std::vector<int> trim_step_sign(128, 0);
04463 std::vector<int> trim_step_prev_signed(128, 0);
04464 std::vector<float> eff_curr(128, 0);
04465 std::vector<float> eff_prev(128, 0);
04466 std::vector<float> diff_curr(128, 0);
04467 std::vector<float> diff_prev(128, 0);
04468
04469 bool first = true;
04470
04471 nxyter::NxContext cntx_trim_prev( cntx_trim );
04472
04473 while( 1 ) {
04474
04475
04476 for( int ch = 0; ch < knch; ch++ ) {
04477 if( ! mask_cntx.getChannelMaskBit(ch) ) {
04478 eff_prev.at(ch) = eff_curr.at(ch);
04479 eff_curr.at(ch) = npuls.at(ch) / npuls_exp;
04480 diff_prev.at(ch) = diff_curr.at(ch);
04481 diff_curr.at(ch) = std::abs( target - eff_curr.at(ch) );
04482 }
04483 }
04484
04485
04486 for( int ch = 0; ch < knch; ch++ ) {
04487 if( ! mask_cntx.getChannelMaskBit(ch) ) {
04488 trim_step_prev_signed.at(ch) = trim_step.at(ch) * trim_step_sign.at(ch);
04489 }
04490 }
04491
04492
04493 for( int ch = 0; ch < knch; ch++ ) {
04494 if( ! mask_cntx.getChannelMaskBit(ch) ) {
04495 if( trim_step_prev_signed.at(ch) != 0 ) {
04496 if( ( eff_curr.at(ch) < eff_prev.at(ch) ) != ( ( trim_step_prev_signed.at(ch) > 0 ) == posgain_trim ) ) {
04497 printf("WARNING: In channel %d detection efficiency changes in the same direction as physical threshold -- system is not stable. Try to increase the measurement time?\n", ch);
04498 }
04499 }
04500 }
04501 }
04502
04503
04504 for( int ch = 0; ch < knch; ch++ ) {
04505 if( ! mask_cntx.getChannelMaskBit(ch) ) {
04506 if( ( eff_curr.at(ch) > target ) == posgain_trim ) {
04507 trim_step_sign.at(ch) = 1;
04508 }
04509 else {
04510 trim_step_sign.at(ch) = -1;
04511 }
04512
04513 }
04514 }
04515
04516
04517 for( int ch = 0; ch < knch; ch++ ) {
04518 if( ! mask_cntx.getChannelMaskBit(ch) ) {
04519 trim_step.at(ch) = trim_step.at(ch) / 2 + trim_step.at(ch) % 2;
04520 int prelim_new_trim = cntx_trim.getThresholdTrim(ch) + trim_step_sign.at(ch) * trim_step.at(ch);
04521 if( prelim_new_trim > 31 ) {
04522 trim_step.at(ch) -= prelim_new_trim - 31;
04523 }
04524 if( prelim_new_trim < 0 ) {
04525 trim_step.at(ch) -= 0 - prelim_new_trim;
04526 }
04527 }
04528 }
04529
04530
04531 if( ! first ) {
04532 bool all_ch_converge = true;
04533 nxyter::NxContext cntx_trim_converge(cntx_trim);
04534 for( int ch = 0; ch < knch; ch++ ) {
04535 if( ! mask_cntx.getChannelMaskBit(ch) ) {
04536 if( trim_step.at(ch) == 0 || ( trim_step.at(ch) == 1 && trim_step_sign.at(ch) == - trim_step_prev_signed.at(ch) ) ) {
04537 if( diff_prev.at(ch) < diff_curr.at(ch) ) {
04538 cntx_trim_converge.setThresholdTrim( ch, static_cast<uint8_t>( cntx_trim.getThresholdTrim(ch) - trim_step_prev_signed.at(ch) ) );
04539 }
04540 }
04541 else {
04542 all_ch_converge = false;
04543 }
04544
04545 }
04546 }
04547 if( all_ch_converge ) {
04548 for( int ch = 0; ch < knch; ch++ ) {
04549 if( ! mask_cntx.getChannelMaskBit(ch) ) {
04550 cntx_trim.setThresholdTrim( ch, cntx_trim_converge.getThresholdTrim(ch) );
04551 }
04552 }
04553 rc = gFeb->nx(nxind).i2c().setContext(cntx_trim, nxyter::kDoTrim);
04554 print_opererr("SetContext(cntx_trim,...)", rc);
04555 break;
04556 }
04557 }
04558
04559
04560 for( int ch = 0; ch < knch; ch++ ) {
04561 if( ! mask_cntx.getChannelMaskBit(ch) ) {
04562 cntx_trim_prev.setThresholdTrim( ch, cntx_trim.getThresholdTrim(ch) );
04563 cntx_trim.setThresholdTrim(ch, cntx_trim.getThresholdTrim(ch) + trim_step.at(ch) * trim_step_sign.at(ch) );
04564 }
04565 }
04566
04567
04568
04569 rc = gFeb->nx(nxind).i2c().setContext(cntx_trim, nxyter::kDoTrim);
04570 print_opererr("SetContext(cntx_trim_reset,...)", rc);
04571 if( ! opt_q ) printf("Measuring with trim values:\n");
04572 if( ! opt_q ) autotrim_print_trim(cntx_trim);
04573
04574 acquire_data( nxind, npuls, time );
04575 if( ! opt_q ) printf("Resulting rates:\n");
04576 if( ! opt_q ) autotrim_print_rates( npuls, time );
04577
04578 first = false;
04579 }
04580
04581 printf("Finished with trim values:\n");
04582 autotrim_print_trim(cntx_trim);
04583
04584 return 0;
04585
04586
04587 if( ! opt_k ) {
04588 rc = gFeb->nx(nxind).i2c().setRegister(nxyter::kNxRegVth, vth_init, true);
04589 print_opererr("setRegister(kNxRegVth,...)", rc);
04590 }
04591
04592 }
04593 return 0;
04594
04595 }
04596
04597 float get_mean( std::vector< float > const & vect )
04598 {
04599 double sum = 0;
04600 double ncnt = 0;
04601 for( int ch = 0; ch < vect.size(); ch++ ) {
04602 sum += ch * vect.at(ch);
04603 ncnt += vect.at(ch);
04604 }
04605 return sum / ncnt;
04606 }
04607
04608 int cmd_idsigch()
04609 {
04610 int32_t nxbeg=0;
04611 int32_t nxend=0;
04612 int32_t npuls=2000;
04613 if (get_nxrange(nxbeg, nxend)) return 1;
04614 float time=4.;
04615 float amp_min = 100.;
04616 if (args_check(kNeedFeb|kNeedDaq)) return 1;
04617
04618 int rc;
04619 nxyter::NxContext save_cntx;
04620
04621 gUtil->startLoop(0.);
04622 for (int nxind=nxbeg; nxind<=nxend; nxind++) {
04623 if (!gUtil->testLoop()) break;
04624 gFeb->printNxHeadLine(std::cout, nxind);
04625 if (check_nxoffline(nxind, nxbeg, nxend)) continue;
04626
04627 rc = gFeb->nx(nxind).i2c().getContext(save_cntx, nxyter::kDoCore);
04628 print_opererr("NxI2c::getContext {save}", rc);
04629
04630 rc = gFeb->nx(nxind).i2c().setTestModes(false, true, 0);
04631 print_opererr("NxI2c::setTestModes", rc);
04632
04633 int vb_beg = 0;
04634 int vb_end = 255;
04635 int vb_mid;
04636 float med_beg;
04637 float med_end;
04638 float med_mid;
04639 bool nxabort = false;
04640
04641 nxyter::DistFuncArray dfa_bl(128, npuls);
04642 dfa_bl.setMaxEntries(2*npuls);
04643 int rc = gUtil->acquireTestTriggerData(nxind, npuls, dfa_bl);
04644 nxyter::NxDataSummary nds_bl;
04645 nds_bl.analyse(dfa_bl);
04646
04647 rc = gFeb->nx(nxind).i2c().setTestModes(false, false, 0);
04648 print_opererr("NxI2c::setTestModes", rc);
04649
04650 std::vector< std::vector<float> > data;
04651 data.resize(128);
04652 for( int ch = 0; ch < 128; ch++ ) {
04653 data.at( ch ).resize( 4096 );
04654 }
04655 acquire_data(nxind, data, time );
04656
04657 for( int ch = 0; ch < 128; ch++) {
04658 float bl = nds_bl.getMedian(ch);
04659 float mean = get_mean( data.at(ch) );
04660
04661 float amp = bl - mean;
04662 if( amp > amp_min ) {
04663 printf("In idsigch: detected signal in channel %d, amp = %f\n", ch, amp );
04664 }
04665 }
04666 }
04667
04668 return 0;
04669 }
04670
04671
04672
04673
04674 int process_command(const std::string& line, int level)
04675 {
04676 gIntCount = 0;
04677
04678 std::string cmdline(line);
04679
04680 size_t pos_delcomment = 0;
04681
04682
04683 while (pos_delcomment < cmdline.length()) {
04684 pos_delcomment = cmdline.find("//", pos_delcomment);
04685
04686 if (pos_delcomment == std::string::npos) break;
04687
04688
04689 if ((pos_delcomment>0) && (cmdline[pos_delcomment-1]==':')) { pos_delcomment+=2; continue; }
04690
04691 cmdline.erase(pos_delcomment);
04692
04693 break;
04694 }
04695
04696
04697 trim_whitespace(cmdline);
04698 if (cmdline.size() == 0) return 0;
04699
04700
04701 if (cmdline.find("/*") == 0) {
04702 std::cout << cmdline << std::endl;
04703 return 0;
04704 }
04705
04706
04707
04708 if (cmdline.find("@") == 0) {
04709 cmdline.erase(0,1);
04710 std::ifstream cmdfile;
04711 cmdfile.open(cmdline.c_str(), std::ifstream::in);
04712 if (cmdfile.fail()) {
04713 std::cerr << "rocutil-E: Failed to open file '" << cmdline << "'" << std::endl;
04714 return 1;
04715 }
04716
04717
04718 for (int i=0; i<std::max(int(0),level+1); i++) std::cout << ">";
04719 std::cout << " (open) @" << cmdline << std::endl;
04720
04721 while (cmdfile.good()) {
04722 std::string line;
04723 std::getline(cmdfile, line);
04724 if (line.size()) {
04725 int rc = process_command(line, std::max(int(0),level) + 1);
04726 if (rc > 0) std::cerr << "rocutil-E: Aborting command file '"
04727 << cmdline << "'" << std::endl;
04728 if (rc) return rc;
04729 }
04730 }
04731
04732 for (int i=0; i<level+1; i++) std::cout << ">";
04733 std::cout << " (close) @" << cmdline << std::endl;
04734
04735 return 0;
04736 }
04737
04738 if (level > 0) {
04739 for (int i=0; i<level; i++) std::cout << ">";
04740 std::cout << " " << cmdline << std::endl;
04741 }
04742
04743
04744 for (size_t i=0; i<cmdline.size(); i++) {
04745 if (cmdline[i] == '\t') cmdline[i] = ' ';
04746 }
04747
04748
04749 size_t pos_deleq = cmdline.find("=");
04750 size_t pos_delsp = cmdline.find(" ");
04751 if (pos_deleq != std::string::npos && pos_deleq < pos_delsp) {
04752 cmdline[pos_deleq] = ' ';
04753 }
04754
04755
04756 pos_delsp = cmdline.find(" ");
04757 std::string cmd;
04758 std::string args;
04759
04760 if (pos_delsp != std::string::npos) {
04761 cmd = cmdline.substr(0,pos_delsp);
04762 args = cmdline.substr(pos_delsp+1);
04763 } else {
04764 cmd = cmdline;
04765 }
04766
04767
04768
04769 argspos.clear();
04770 argsopt.clear();
04771
04772 trim_whitespace(args);
04773
04774 while(args.size()) {
04775 std::string curarg;
04776 size_t pos_del = args.find_first_of(" ,");
04777 if (pos_del != std::string::npos) {
04778 curarg = args.substr(0,pos_del);
04779 args.erase(0,pos_del+1);
04780 trim_whitespace(args);
04781 } else {
04782 curarg = args;
04783 args.clear();
04784 }
04785
04786 bool isopt = false;
04787 if ((curarg.size()>=2) && (curarg[0]=='-') && isalpha(curarg[1])) {
04788 isopt = true;
04789 } else if (curarg.find("=") != std::string::npos) {
04790 isopt = true;
04791 }
04792
04793 if (isopt) {
04794 argsopt.push_back(curarg);
04795 } else {
04796 argspos.push_back(curarg);
04797 }
04798 }
04799
04800 for (unsigned i=0; i<cmdlist.size(); i++) {
04801 std::string cmdfull;
04802 std::string cmdshort;
04803 cmd_full_short(cmdlist[i]->name, cmdfull, cmdshort);
04804 if (cmd.compare(cmdfull)==0 || cmd.compare(cmdshort)==0) {
04805 int rc = cmdlist[i]->func();
04806 if (rc > 0) {
04807 std::cerr << "rocutil-E: Error in command '" << cmdline << "'" << std::endl;
04808 }
04809 return rc;
04810 }
04811 }
04812
04813 std::cerr << "rocutil-E: Command '" << cmd << "' not defined, use 'help'" << std::endl;
04814 return 1;
04815
04816 }
04817
04818
04819
04820 void hdl_int(int sig, siginfo_t *info, void *cnxt)
04821 {
04822 switch (gIntCount) {
04823 case 1:
04824 std::cerr << '\007' << std::flush;
04825 break;
04826 case 2:
04827 std::cerr << std::endl
04828 << "rocutil-W: not responding on ^C, next will terminate" << std::endl;
04829 break;
04830 case 3:
04831 std::cerr << "rocutil-E: ^C abort, have a nice day..." << std::endl;
04832 exit(1);
04833 break;
04834 }
04835 gIntCount += 1;
04836 if (gUtil) gUtil->interruptLoop();
04837 if (gQdaq) gQdaq->interruptRun();
04838 }
04839
04840
04841
04842 static const char* history_file = "./.rocutil_history";
04843 static const int history_max = 250;
04844
04845 int main(int argc, char* argv[])
04846 {
04847 struct sigaction act;
04848 memset (&act, '\0', sizeof(act));
04849 act.sa_sigaction = &hdl_int;
04850 act.sa_flags = SA_SIGINFO;
04851 if (sigaction(SIGINT, &act, 0) < 0) {
04852 perror ("sigaction");
04853 }
04854
04855 reset_cmdlist();
04856
04857 bool prompt = (argc<=1);
04858
04859 for (int i=1; i<argc; i++) {
04860 if (i==argc-1 && strcmp(argv[i],"-")==0) {
04861 prompt = true;
04862 } else {
04863 int rc = process_command(argv[i], -1);
04864 if (rc > 0) std::cerr << "rocutil-F: Aborting rocutil...." << std::endl;
04865 if (rc) { base::Board::Close(gRocBoard); return (rc<=0) ? 0 : rc; }
04866 }
04867 }
04868
04869 if (!prompt) {
04870
04871 base::Board::Close(gRocBoard);
04872 return 0;
04873 }
04874
04875 std::string lastline;
04876
04877 char* buf = 0;
04878 int rc;
04879 rc = read_history(history_file);
04880
04881 while ( (buf=readline("rocutil> ")) ) {
04882 std::string line(buf);
04883 trim_whitespace(line);
04884 if (line.size() && line != lastline) add_history(buf);
04885 lastline = line;
04886 free(buf);
04887 int rc = process_command(line, 0);
04888 if (rc < 0) break;
04889 }
04890
04891
04892
04893
04894
04895 if (buf==0) std::cout << std::endl;
04896
04897
04898
04899
04900
04901 if (gRocBoard && rc>-2) {
04902 base::Board::Close(gRocBoard);
04903 gRocBoard = 0;
04904 }
04905
04906 rc = append_history (history_max, history_file);
04907 if (rc) {
04908 rc = write_history(history_file);
04909 } else {
04910 rc = history_truncate_file(history_file, history_max);
04911 }
04912
04913 return 0;
04914 }
04915
04916 int cmd_autosettrh()
04917 {
04918
04919
04920
04921
04922
04923
04924
04925
04926 int time = 5;
04927 int rc;
04928 int nentmax;
04929 int nxmax;
04930 int maskmax;
04931 int starttrh, up, low, diff;
04932 int step;
04933 int sig;
04934 int minchan, counter;
04935 int previous = 0, previous2 = 0;
04936 nentmax = 500;
04937 nxmax = 10000;
04938 minchan = 100;
04939 starttrh = 255;
04940 up = 255;
04941 low = 0;
04942 step = 20;
04943
04944 if (get_arg(time, "time=")) return 1;
04945 if (get_arg(minchan, "min=")) return 1;
04946 if (get_arg(nentmax, "nnc=")) return 1;
04947 if (get_arg(nxmax, "nnx=")) return 1;
04948
04949
04950 std::cout << "Used values:" << std::endl;
04951 std::cout << " time: " << time << std::endl;
04952 std::cout << " minimum working channels: " << minchan << std::endl;
04953 std::cout << " maximum noise rate per channel: " << nentmax << std::endl;
04954 std::cout << " maximum noise rate per chip: "<< nxmax << std::endl;
04955
04956 diff = up - low;
04957
04958 nxyter::NxContext cntx;
04959
04960 int32_t nonx = 0;
04961 if( gFeb ) {
04962 nonx = gFeb->numNx();
04963 }
04964 else {
04965 printf("Log to the FEB!\n");
04966 }
04967
04968 std::cout << "Number of nXYTERs at FEB: " << nonx << std::endl;
04969
04970
04971 typedef std::auto_ptr<nxyter::DistFuncArray> ptr_dfa;
04972 ptr_dfa dfa[4];
04973
04974 for (int i=0; i<gFeb->numNx(); i++) {
04975 dfa[i] = ptr_dfa(new nxyter::DistFuncArray(128, 512));
04976 }
04977 rc = gRocNx->fireTestPulse(0,0,0);
04978
04979
04980
04981
04982 for (int i=0; i<gFeb->numNx(); i++) {
04983 rc = gFeb->nx(i).i2c().setRegister(uint8_t(18), uint8_t(up), true);
04984 }
04985
04986
04987 bool mainstop = false;
04988 int totalentries[4];
04989 int totalrate[4];
04990 int channelentries[512];
04991 int channelrate[512];
04992 int channelcontrol[4];
04993 bool control[4];
04994 bool masking[4];
04995 bool trhcontrol[2];
04996 int trhvalue[2];
04997 int val[4];
04998 bool channelid[4][128];
04999
05000
05001 int noisy = 0;
05002 int maskedch = 0;
05003 int tobemasked = 0;
05004
05005 for (int i=0;i<gFeb->numNx();i++) {
05006
05007 std::cout << "Setup is running for nXYTER: " << i << std::endl;
05008
05009 mainstop = false;
05010 trhvalue[0]=up;
05011 trhvalue[1]=low;
05012 trhcontrol[0]=false;
05013 trhcontrol[1]=false;
05014
05015
05016 while (!mainstop) {
05017
05018 for (int k=0; k<2; k++){
05019 masking[i]=false;
05020
05021 for (int l=0; l<4; l++) {
05022 totalentries[l] = 0;
05023 totalrate[l] = 0;
05024 channelcontrol[l] = 0;
05025 control[l] = false;
05026 masking[l] = false;
05027 for (int j=0; j<128; j++) {
05028 channelid[l][j] = false;
05029 channelrate[(l*128)+j] = 0;
05030 channelentries[(l*128)+j] = 0;
05031 }
05032 }
05033
05034
05035 delete gQdaq;
05036 gQdaq = 0;
05037 gQdaq = new nxyter::QuickDaq(gFeb);
05038 int rc = gFeb->nx(i).i2c().setRegister(uint8_t(18), uint8_t(trhvalue[k]), true);
05039 cntx.setChannelMaskBit(0, 127, 0, 1);
05040 rc = gFeb->nx(i).i2c().setContext(cntx, nxyter::kDoMask);
05041 dfa[i] = ptr_dfa(new nxyter::DistFuncArray(128, 512));
05042
05043 gQdaq->startRun(0, time);
05044
05045
05046
05047 while(gQdaq->testRun()) {
05048 roc::Message& msg = gQdaq->msg();
05049 if (msg.isHitMsg()) {
05050 int nxnum = msg.getNxNumber();
05051 int nxcha = msg.getNxChNum();
05052 int nxadc = msg.getNxAdcValue();
05053 if (nxnum == i) {
05054 (*dfa[i]).addEntry(nxcha, float(nxadc));
05055 }
05056 }
05057 }
05058
05059 for (int j=0; j< 128; j++) {
05060 totalentries[i] = totalentries[i] + (*dfa[i])[j].numEntries();
05061
05062 channelrate[(i*128)+j] = (*dfa[i])[j].numEntries()/time;
05063 }
05064 totalrate[i] = totalentries[i]/time;
05065
05066
05067
05068
05069 for (int j=0; j<128; j++) {
05070 if (channelrate[(i*128)+j] <= (nentmax-1)){
05071 channelcontrol[i]++;
05072 }
05073 }
05074 if ((channelcontrol[i] <= (minchan-1))) {
05075
05076 trhcontrol[k] = false;
05077 }
05078
05079 if ((channelcontrol[i] >= minchan) && (totalrate[i] >= nxmax)) {
05080
05081 masking[i] = true;
05082 trhcontrol[k] = false;
05083
05084 }
05085
05086 if ((channelcontrol[i] >= minchan) && (totalrate[i] <= nxmax)) {
05087
05088 trhcontrol[k] = true;
05089 }
05090
05091 tobemasked=0;
05092
05093 if (masking[i]) {
05094
05095 while (totalrate[i] >= (nxmax+1)) {
05096 tobemasked++;
05097
05098 noisy = 0;
05099 for (int j=0; j<128; j++) {
05100 if (!channelid[i][j]) {
05101
05102 if (channelrate[(i*128)+j]>=noisy) {
05103
05104 noisy = channelrate[(i*128)+j];
05105 maskedch = j;
05106 }
05107
05108 }
05109
05110 }
05111 channelid[i][maskedch] = true;
05112 totalrate[i] = totalrate[i] - channelrate[(i*128)+maskedch];
05113
05114
05115
05116 }
05117 for (int j=0; j<128; j++) {
05118 if (!channelid[i][j]) {
05119 if (channelrate[(i*128)+j]>=nentmax) {
05120 tobemasked++;
05121 channelid[i][j] = true;
05122 totalrate[i] = totalrate[i] - channelrate[(i*128)+maskedch];
05123 }
05124 }
05125 }
05126
05127
05128
05129 if (tobemasked >= (128-minchan)) {
05130 totalrate[i]=0;
05131 trhcontrol[k] = false;
05132
05133 }
05134
05135 if (tobemasked <= (128-minchan)) {
05136 trhcontrol[k] = true;
05137
05138 }
05139 }
05140
05141 masking[i] = false;
05142
05143
05144 if (previous == trhvalue[1]) {
05145 k++;
05146 }
05147 if (previous2 == trhvalue[1]) {
05148 k++;
05149 }
05150
05151 }
05152
05153
05154 previous = trhvalue[1];
05155 previous2 = trhvalue[0];
05156
05157 if ((diff/2) == 0) {
05158 mainstop = true;
05159 }
05160
05161 if (trhcontrol[0]) {
05162 trhvalue[0] = trhvalue[0] - (diff/2);
05163 diff = trhvalue[0]-trhvalue[1];
05164 }
05165
05166 if (!trhcontrol[0]) {
05167 trhvalue[1] = trhvalue[0];
05168 trhvalue[0] = trhvalue[0] + (diff/2);
05169 trhcontrol[1] = trhcontrol[0];
05170 diff = trhvalue[0]-trhvalue[1];
05171 }
05172
05173
05174
05175 }
05176
05177
05178 for (int l=0; l<4; l++) {
05179 totalentries[l] = 0;
05180 totalrate[l] = 0;
05181 channelcontrol[l] = 0;
05182 control[l] = false;
05183 masking[l] = false;
05184 for (int j=0; j<128; j++) {
05185 channelid[l][j] = false;
05186 channelrate[(l*128)+j] = 0;
05187 channelentries[(l*128)+j] = 0;
05188 }
05189 }
05190
05191 int settrhvalue = 0;
05192
05193 if (trhvalue[0] && trhvalue[1]) {
05194 settrhvalue = trhvalue[1]+1;
05195 }
05196
05197 if (trhvalue[0] && !trhvalue[1]){
05198 settrhvalue = trhvalue[0];
05199 }
05200
05201 delete gQdaq;
05202 gQdaq = 0;
05203 gQdaq = new nxyter::QuickDaq(gFeb);
05204 int rc = gFeb->nx(i).i2c().setRegister(uint8_t(18), uint8_t(settrhvalue), true);
05205 cntx.setChannelMaskBit(0, 127, 0, 1);
05206 rc = gFeb->nx(i).i2c().setContext(cntx, nxyter::kDoMask);
05207 dfa[i] = ptr_dfa(new nxyter::DistFuncArray(128, 512));
05208
05209 gQdaq->startRun(0, time);
05210
05211
05212 while(gQdaq->testRun()) {
05213 roc::Message& msg = gQdaq->msg();
05214 if (msg.isHitMsg()) {
05215 int nxnum = msg.getNxNumber();
05216 int nxcha = msg.getNxChNum();
05217 int nxadc = msg.getNxAdcValue();
05218 if (nxnum == i) {
05219 (*dfa[i]).addEntry(nxcha, float(nxadc));
05220 }
05221 }
05222 }
05223
05224
05225 for (int j=0; j< 128; j++) {
05226 totalentries[i] = totalentries[i] + (*dfa[i])[j].numEntries();
05227 channelrate[(i*128)+j] = (*dfa[i])[j].numEntries()/time;
05228
05229 }
05230 totalrate[i] = totalentries[i]/time;
05231
05232
05233
05234 while (totalrate[i] >= (nxmax+1)) {
05235 tobemasked++;
05236
05237 noisy = 0;
05238 for (int j=0; j<128; j++) {
05239 if (!channelid[i][j]) {
05240
05241 if (channelrate[(i*128)+j]>=noisy) {
05242
05243 noisy = channelrate[(i*128)+j];
05244 maskedch = j;
05245 }
05246
05247 }
05248
05249 }
05250 channelid[i][maskedch] = true;
05251 totalrate[i] = totalrate[i] - channelrate[(i*128)+maskedch];
05252 }
05253
05254 for (int j=0; j<128; j++) {
05255 if (!channelid[i][j]) {
05256 if (channelrate[(i*128)+j]>=nentmax) {
05257 tobemasked++;
05258 channelid[i][j] = true;
05259 totalrate[i] = totalrate[i] - channelrate[(i*128)+j];
05260 }
05261 }
05262 }
05263
05264
05265
05266
05267 for (int j=0; j<128; j++) {
05268 if (channelid[i][j]) {
05269 cntx.setChannelMaskBit(j, j, 1, 1);
05270 rc = gFeb->nx(i).i2c().setContext(cntx, nxyter::kDoMask);
05271 }
05272 }
05273
05274 for (int i=0; i<gFeb->numNx(); i++) {
05275
05276
05277
05278
05279
05280
05281
05282
05283
05284
05285
05286
05287
05288
05289 std::cout << "\n Masked channels are:" << std::endl;
05290 std::cout << " nXYTER " << i << " channels: " ;
05291 for (int j=0; j<128; j++) {
05292
05293 if (channelid[i][j]){
05294
05295 std::cout << " " << j << ", " ;
05296
05297 }
05298 }
05299 std::cout << "\n" << std::endl;
05300
05301 std::cout << "Total noise rate in chip is " << totalrate[i] << std::endl;
05302 std::cout << "Set threshold in " << i << " nXYTER is " << settrhvalue << std::endl;
05303
05304 }
05305
05306
05307 std::cout << "Setup has finished this difficult work. You are welcome ...\n" << std::endl;
05308
05309 }
05310
05311
05312 mainstop = false;
05313 return 0;
05314
05315 }
05316
05317
05318
05319
05320