source: tools/vchvtest/vchvtest.cc@ 200

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