source: tools/vchvtest/vchvtest.cc@ 201

Last change on this file since 201 was 201, checked in by ogrimm, 14 years ago
New command 'test'
  • Property svn:executable set to *
File size: 11.7 KB
Line 
1/**************************************************************\
2
3 Test program for new bias supply
4
5 Oliver Grimm
6
7\**************************************************************/
8
9#include <stdio.h>
10#include <ctype.h>
11#include <sys/time.h>
12
13#include <readline/readline.h>
14#include <readline/history.h>
15
16#include "HV.h"
17
18#define MAX_NUM_TOKEN 10
19
20
21// Global variables
22HVBoard **fHVBoard;
23const char *Param[MAX_NUM_TOKEN]; // For parser
24int NParam;
25int NumCrates;
26int FirstCrate;
27int LastCrate;
28bool Repeat = false;
29bool Verbose = true;
30
31// Function prototypes
32void cmd_crate(); void cmd_status();
33void cmd_timeout(); void cmd_synch();
34void cmd_send(); void cmd_rst();
35void cmd_rd(); void cmd_gs();
36void cmd_cs(); void cmd_exit();
37void cmd_help(); void cmd_repeat();
38void cmd_config(); void cmd_rate();
39void cmd_test();
40
41int ParseInput(char*, const char *Param[]);
42bool Match(const char *, const char *);
43bool ConvertToDouble(const char *, double *);
44bool ConvertToInt(const char *, int *);
45
46// Branch table for command evaluation
47static const struct CL_Struct { const char *Name;
48 void (*CommandPointer)();
49 int MinNumParameter;
50 const char *Parameters;
51 const char *Help;
52 bool Repeatable;
53 } CommandList[] =
54 {{"crate", &cmd_crate, 0, "<i> [j] | <all>" ,"Address crate i, crates i-j, all crates", false},
55 {"status", &cmd_status, 0, "[i]", "Show status information (for board i)", false},
56 {"config", &cmd_config, 0, "", "Show crate configuration", false},
57 {"timeout", &cmd_timeout, 1, "<secs>", "Set timeout to return from read", false},
58 {"synch", &cmd_synch, 0, "", "Synchronize board(s)", false},
59 {"send", &cmd_send, 1, "<byte1> [byte2] ...", "Send bytes and wait for response", true},
60 {"rst", &cmd_rst, 0, "", "System reset", true},
61 {"rd", &cmd_rd, 2, "<Board> <Channel>", "Read status", true},
62 {"gs", &cmd_gs, 1, "<Voltage>", "Global voltage set", true},
63 {"cs", &cmd_cs, 3, "<Board> <Channel> <Voltage>", "Set channel to voltage", true},
64 {"rate", &cmd_rate, 1, "<n>", "Make n 'rd 0 0' cycles and measure time", false},
65 {"repeat", &cmd_repeat, 1, "<on|off>", "Command repetition (ENTER to stop)", false},
66 {"test", &cmd_test, 1, "<Voltage>", "Set all channels consecutively", false},
67 {"exit", &cmd_exit, 0, "", "Exit program", false},
68 {"help", &cmd_help, 0, "", "Print help", false}};
69
70
71// ================ Main program ================
72int main(int argc, char *argv[]) {
73
74 char Prompt[MAX_COM_SIZE], *Command = NULL;
75
76 printf("\n*** vchvtest (built %s, %s; O. Grimm) ***\n\n",__DATE__,__TIME__);
77 if (argc == 1) printf("Note: Use FTDI serial numbers as arguments to connect\n");
78
79 // Initialize status variables
80 NumCrates = 0;
81 FirstCrate = 0;
82 LastCrate = -1;
83
84 // Open HV devices
85 fHVBoard = new HVBoard* [argc-1];
86 for (int i=1; i<argc; i++) {
87 fHVBoard[NumCrates] = new HVBoard(i-1, argv[i]);
88 if(fHVBoard[NumCrates]->fDescriptor != -1) NumCrates++;
89 else delete fHVBoard[NumCrates];
90 }
91 LastCrate = NumCrates-1;
92
93 // Command loop
94 while (true) {
95 if (Command != NULL) free(Command); // Free command buffer
96
97 // Assemble prompt
98 if (NumCrates == 0) snprintf(Prompt, sizeof(Prompt), "HV> ");
99 else if (FirstCrate == LastCrate) snprintf(Prompt, sizeof(Prompt), "HV|B%d> ",FirstCrate);
100 else snprintf(Prompt,sizeof(Prompt),"HV|B%d-%d> ",FirstCrate,LastCrate);
101
102 // Read command from console
103 Command = readline(Prompt);
104 if (Command==NULL) {
105 printf("Error reading command line input\n");
106 continue;
107 }
108 if(strlen(Command)>0) add_history(Command);
109 else continue;
110
111 // Process command
112 for(int i=0; i<MAX_NUM_TOKEN; i++) Param[i] = ""; // All pointers point initially to empty string
113 NParam = ParseInput(Command, Param);
114
115 bool Found=false;
116 int N;
117 for(unsigned int CmdNumber=0; CmdNumber<sizeof(CommandList)/sizeof(CL_Struct); CmdNumber++)
118 if (Match(Param[0], CommandList[CmdNumber].Name)) {
119 if(NParam-1 < CommandList[CmdNumber].MinNumParameter) {
120 printf("Usage: %s %s\n", CommandList[CmdNumber].Name, CommandList[CmdNumber].Parameters);
121 }
122 else do {
123 (*CommandList[CmdNumber].CommandPointer)();
124 ioctl(STDIN_FILENO, FIONREAD, &N);
125 } while(CommandList[CmdNumber].Repeatable && Repeat && N==0);
126 Found = true;
127 break;
128 }
129 if (!Found) printf("Unknown command '%s'\n",Param[0]);
130 } // while{}
131}
132
133// Print help
134void cmd_help() {
135
136 char Buffer[MAX_COM_SIZE];
137 for(unsigned int i=0; i<sizeof(CommandList)/sizeof(CL_Struct); i++) {
138 snprintf(Buffer, sizeof(Buffer), "%s %s", CommandList[i].Name, CommandList[i].Parameters);
139 printf("%-32s%s\n", Buffer, CommandList[i].Help);
140 }
141 printf("\nAccepted prefixes for integers: 'b' binary, '0' octal, '0x' hexadecimal\n");
142}
143
144// Select board(s)
145void cmd_crate() {
146
147 int Number;
148
149 if (Match(Param[1],"all")) {
150 FirstCrate = 0;
151 LastCrate = NumCrates-1;
152 return;
153 }
154 if (NParam>=2 && ConvertToInt(Param[1], &Number) && Number>=0 && Number<NumCrates) {
155 FirstCrate = Number;
156 LastCrate = FirstCrate;
157 }
158 if (NParam==3 && ConvertToInt(Param[2], &Number) && Number>=FirstCrate && Number<NumCrates) {
159 LastCrate = Number;
160 }
161}
162
163// System reset
164void cmd_rst() {
165
166 for (int i=FirstCrate; i<=LastCrate; i++) {
167 if (fHVBoard[i]->SystemReset() == 1) {
168 printf("Reset of board %d\n", fHVBoard[i]->BoardNumber);
169 }
170 else printf("Error: Could not reset board %d\n",fHVBoard[i]->BoardNumber);
171 }
172}
173
174// Read channel
175void cmd_rd() {
176
177 int Board=0, Channel=0;
178
179 if (!ConvertToInt(Param[1], &Board) || !ConvertToInt(Param[2], &Channel)) return;
180
181 for (int i=FirstCrate; i<=LastCrate; i++) {
182 if (fHVBoard[i]->ReadChannel(Board, Channel) != 1) {
183 printf("Error: Could not read from board %d\n", fHVBoard[i]->BoardNumber);
184 }
185 }
186}
187
188// Read channel
189void cmd_gs() {
190
191 int Voltage;
192
193 if (!ConvertToInt(Param[1], &Voltage)) return;
194
195 for (int i=FirstCrate; i<=LastCrate; i++) {
196 if (fHVBoard[i]->GlobalSet(Voltage) != 1) {
197 printf("Error: Could not global set board %d\n", fHVBoard[i]->BoardNumber);
198 }
199 }
200}
201
202// Read channel
203void cmd_cs() {
204
205 int Board=0, Channel=0, Voltage=0;
206
207 if (!ConvertToInt(Param[1], &Board) || !ConvertToInt(Param[2], &Channel) || !ConvertToInt(Param[3], &Voltage)) return;
208
209 for (int i=FirstCrate; i<=LastCrate; i++) {
210 if (fHVBoard[i]->ChannelSet(Board, Channel, Voltage) != 1) {
211 printf("Error: Could not channel set board %d\n", fHVBoard[i]->BoardNumber);
212 }
213 }
214}
215
216// Synchronize boards
217void cmd_synch() {
218
219 for (int i=FirstCrate; i<=LastCrate; i++) {
220 if (fHVBoard[i]->SynchBoard()) printf("Synchronized board %d\n", fHVBoard[i]->BoardNumber);
221 else printf("Failed to synchronize board %d\n", fHVBoard[i]->BoardNumber);
222 }
223}
224
225// Switch on all channels consecutively for cabling test
226void cmd_test() {
227
228 for (int i=FirstCrate; i<=LastCrate; i++) {
229 printf("Testing board %d (Enter to continue, any key plus enter to stop)\n", fHVBoard[i]->BoardNumber);
230 if (fHVBoard[i]->GlobalSet(0) != 1) {
231 printf("Error: Could not global set board to zero\n");
232 return;
233 }
234
235 for (int k=0; k<MAX_NUM_BOARDS; k++) for (int j=0; j<NUM_CHANNELS; j++) {
236 printf("\rBoard %d, channel %d", k, j);
237 fflush(stdout);
238 Verbose = false;
239 if (fHVBoard[i]->ChannelSet(k, j, atoi(Param[1])) != 1) {
240 printf("Error setting voltage\n");
241 return;
242 }
243 Verbose = true;
244 if (getchar() != '\n') return;
245 }
246 }
247}
248
249// Send bytes and wait for response
250void cmd_send() {
251
252 unsigned char wbuf[MAX_NUM_TOKEN];
253 int Number;
254
255 for (int j=1; j<NParam; j++) {
256 ConvertToInt(Param[j], &Number);
257 wbuf[j-1] = (unsigned char) Number;
258 }
259
260 for (int i=FirstCrate; i<=LastCrate; i++) {
261 fHVBoard[i]->Communicate(wbuf, NParam-1);
262 }
263}
264
265// Measure read speed
266void cmd_rate() {
267
268 struct timeval Start, End;
269 int N = atoi(Param[1]);
270
271 if (N < 1) return;
272
273 gettimeofday(&Start, NULL);
274 Verbose = false;
275 for (int i=0; i<=N; i++) fHVBoard[0]->ReadChannel(0, 0);
276 Verbose = true;
277 gettimeofday(&End, NULL);
278
279 double Diff = ((End.tv_sec-Start.tv_sec)*1e6 + End.tv_usec-Start.tv_usec) * 1e-6;
280 printf("%d accesses in %f seconds: rate %.0f Hz, period %.2f ms\n", N, Diff, N/Diff, (Diff*1e3)/N);
281}
282
283// Switch repeat on/off
284void cmd_repeat() {
285
286 if (Match(Param[1],"on")) Repeat = true;
287 else Repeat = false;
288 printf("Auto command repeat is %s\n", Repeat ? "on (CTRL-c to switch off)" : "off");
289}
290
291// Print status
292void cmd_status() {
293
294 int Board;
295
296 if (NParam==2 && ConvertToInt(Param[1], &Board)) {
297 for (int i=FirstCrate; i<=LastCrate; i++) {
298 Verbose = false;
299 for (int j=0; j<NUM_CHANNELS; j++) {
300 if (j%4 == 0) printf("\nChannel %2d ", j);
301 fHVBoard[i]->ReadChannel(Board, j);
302 if (fHVBoard[i]->Status.BoardNumber == -1) printf("Read error ");
303 else printf(" %s %s %5d ", fHVBoard[i]->Status.Overcurrent ? "OC":"--", fHVBoard[i]->Status.Acknowledge ? "OK":"KO",fHVBoard[i]->Status.Current);
304 }
305 printf("\n");
306 Verbose = true;
307 }
308 } else {
309 printf(" Auto command repeat is %s\n", Repeat ? "on" : "off");
310 printf(" Total number of HV crates: %d\n", NumCrates);
311 printf(" Active HV crates: %d\n\n", LastCrate - FirstCrate + 1);
312
313 for (int i=FirstCrate; i<=LastCrate; i++) {
314 printf(" Crate %d (%s) Wrap counter: %d Time-out: %.2f s\n",
315 fHVBoard[i]->BoardNumber, fHVBoard[i]->BoardName,
316 fHVBoard[i]->LastWrapCount, fHVBoard[i]->fTimeOut);
317 }
318 }
319}
320
321// Print crate configuration
322void cmd_config() {
323
324 Verbose = false;
325
326 for (int i=FirstCrate; i<=LastCrate; i++) {
327 for (int j=0; j<MAX_NUM_BOARDS; j++) {
328 printf("Board %2d ", j);
329 fHVBoard[i]->ReadChannel(j, 0);
330 if (fHVBoard[i]->Status.BoardNumber == -1) printf("Read error\n");
331 else printf(" %s\n", fHVBoard[i]->Status.Acknowledge ? "OK":"KO");
332 }
333 }
334
335 Verbose = true;
336}
337
338// Set timeout to return from read
339void cmd_timeout() {
340
341 double Timeout;
342
343 if (!ConvertToDouble(Param[1], &Timeout)) return;
344 for (int i=0; i<NumCrates; i++) fHVBoard[i]->fTimeOut = Timeout;
345}
346
347// Exit program (delete HV boards)
348void cmd_exit() {
349
350 for (int i=0; i<NumCrates; i++) delete fHVBoard[i];
351 delete[] fHVBoard;
352
353 exit(EXIT_SUCCESS);
354}
355
356
357// Parse command line for white space and double-quote separated tokens
358int ParseInput(char* Command, const char *Param[]) {
359
360 int Count=0;
361
362 while(Count<MAX_NUM_TOKEN) {
363 while (isspace(*Command)) Command++; // Ignore initial white spaces
364 if(*Command=='\0') break;
365 if (*Command == '\"') {
366 Param[Count] = ++Command;
367 while(*Command!='\"' && *Command!='\0') Command++;
368 }
369 else {
370 Param[Count] = Command;
371 while(!isspace(*Command) && *Command!='\0') Command++;
372 }
373 if(*Command != '\0') *Command++ = '\0';
374 Count++;
375 }
376 return Count;
377}
378
379
380// Check if two strings match (min 1 character must match)
381bool Match(const char *str, const char *cmd) {
382
383 return strncasecmp(str,cmd,strlen(str)==0 ? 1:strlen(str)) ? false:true;
384}
385
386// Convert string to double
387// Returns false if conversion did not stop on whitespace or EOL character
388bool ConvertToDouble(const char *String, double *Result) {
389
390 char *EndPointer;
391
392 *Result = strtod(String, &EndPointer);
393 if(!isspace(*EndPointer) && *EndPointer!='\0') {
394 printf("Error: Wrong number format\n");
395 return false;
396 }
397 return true;
398}
399
400// Convert string to int
401// Returns false if conversion did not stop on whitespace or EOL character
402// Accepted prefixes: 'b' binary, '0' octal, '0x' hexadecimal
403bool ConvertToInt(const char *String, int *Result) {
404
405 char *EndPointer;
406 int Base = 0;
407
408 if (tolower(*String) == 'b') {
409 String++;
410 Base = 2;
411 }
412
413 *Result = (int) strtol(String, &EndPointer, Base);
414 if(!isspace(*EndPointer) && *EndPointer!='\0') {
415 printf("Error: Wrong number format\n");
416 return false;
417 }
418 return true;
419}
Note: See TracBrowser for help on using the repository browser.