/**************************************************************\ Test program for new bias supply Oliver Grimm \**************************************************************/ #include #include #include #include #include #include #include #include "HV.h" #define MAX_NUM_TOKEN 10 // Global variables HVBoard **fHVBoard; const char *Param[MAX_NUM_TOKEN]; // For parser int NParam; int NumCrates; int FirstCrate; int LastCrate; bool Repeat = false; bool Verbose; // Function prototypes void cmd_crate(); void cmd_status(); void cmd_timeout(); void cmd_synch(); void cmd_send(); void cmd_rst(); void cmd_rd(); void cmd_gs(); void cmd_cs(); void cmd_exit(); void cmd_help(); void cmd_repeat(); void cmd_config(); void cmd_rate(); void cmd_test(); int ParseInput(char*, const char *Param[]); bool Match(const char *, const char *); bool ConvertToDouble(const char *, double *); bool ConvertToInt(const char *, int *); // Branch table for command evaluation static const struct CL_Struct { const char *Name; void (*CommandPointer)(); int MinNumParameter; const char *Parameters; const char *Help; bool Repeatable; } CommandList[] = {{"crate", &cmd_crate, 0, " [j] | " ,"Address crate i, crates i-j, all crates", false}, {"status", &cmd_status, 0, "[i]", "Show status information (for board i)", false}, {"config", &cmd_config, 0, "", "Show crate configuration", false}, {"timeout", &cmd_timeout, 1, "", "Set timeout to return from read", false}, {"synch", &cmd_synch, 0, "", "Synchronize board(s)", false}, {"send", &cmd_send, 1, " [byte2] ...", "Send bytes and wait for response", true}, {"rst", &cmd_rst, 0, "", "System reset", true}, {"rd", &cmd_rd, 2, " ", "Read status", true}, {"gs", &cmd_gs, 1, "", "Global voltage set", true}, {"cs", &cmd_cs, 3, " ", "Set channel to voltage", true}, {"rate", &cmd_rate, 1, "", "Make n 'rd 0 0' cycles and measure time", false}, {"repeat", &cmd_repeat, 1, "", "Command repetition (ENTER to stop)", false}, {"test", &cmd_test, 1, "", "Set all channels consecutively", false}, {"exit", &cmd_exit, 0, "", "Exit program", false}, {"help", &cmd_help, 0, "", "Print help", false}}; // ================ Main program ================ int main(int argc, char *argv[]) { char Prompt[MAX_COM_SIZE], *Command = NULL; struct termios Termios, Termios_orig; printf("\n*** vchvtest (built %s, %s; O. Grimm) ***\n\n",__DATE__,__TIME__); if (argc == 1) { printf("Note: Use FTDI serial numbers as arguments to connect\n"); } // Initialize status variables NumCrates = 0; FirstCrate = 0; LastCrate = -1; // Open HV devices fHVBoard = new HVBoard* [argc-1]; for (int i=1; ifDescriptor != -1) NumCrates++; else delete fHVBoard[NumCrates]; } LastCrate = NumCrates-1; // Set terminal to read single chars if (tcgetattr (1, &Termios_orig) == -1) { printf("Error with tcgetattr() (%s)\n", strerror(errno)); exit(EXIT_FAILURE); } Termios = Termios_orig; Termios.c_lflag &= ~(ICANON | ECHO); // Command loop while (true) { if (Command != NULL) free(Command); // Free command buffer // Assemble prompt if (NumCrates == 0) snprintf(Prompt, sizeof(Prompt), "HV> "); else if (FirstCrate == LastCrate) snprintf(Prompt, sizeof(Prompt), "HV|B%d> ",FirstCrate); else snprintf(Prompt,sizeof(Prompt),"HV|B%d-%d> ",FirstCrate,LastCrate); // Read command from console Command = readline(Prompt); if (Command==NULL) { printf("Error reading command line input\n"); continue; } if(strlen(Command)>0) add_history(Command); else continue; // Set terminal to return single chars if (tcsetattr (1, 0, &Termios) == -1) { printf("Error with tcsetattr() (%s)\n", strerror(errno)); exit(EXIT_FAILURE); } // Defualt is verbose response Verbose = true; // Process command for(int i=0; i=2 && ConvertToInt(Param[1], &Number) && Number>=0 && Number=FirstCrate && NumberSystemReset() == 1) { printf("Reset of board %d\n", fHVBoard[i]->BoardNumber); } else printf("Error: Could not reset board %d\n",fHVBoard[i]->BoardNumber); } } // Read channel void cmd_rd() { int Board=0, Channel=0; if (!ConvertToInt(Param[1], &Board) || !ConvertToInt(Param[2], &Channel)) return; for (int i=FirstCrate; i<=LastCrate; i++) { if (fHVBoard[i]->ReadChannel(Board, Channel) != 1) { printf("Error: Could not read from board %d\n", fHVBoard[i]->BoardNumber); } } } // Read channel void cmd_gs() { int Voltage; if (!ConvertToInt(Param[1], &Voltage)) return; for (int i=FirstCrate; i<=LastCrate; i++) { if (fHVBoard[i]->GlobalSet(Voltage) != 1) { printf("Error: Could not global set board %d\n", fHVBoard[i]->BoardNumber); } } } // Read channel void cmd_cs() { int Board=0, Channel=0, Voltage=0; if (!ConvertToInt(Param[1], &Board) || !ConvertToInt(Param[2], &Channel) || !ConvertToInt(Param[3], &Voltage)) return; for (int i=FirstCrate; i<=LastCrate; i++) { if (fHVBoard[i]->ChannelSet(Board, Channel, Voltage) != 1) { printf("Error: Could not channel set board %d\n", fHVBoard[i]->BoardNumber); } } } // Synchronize boards void cmd_synch() { for (int i=FirstCrate; i<=LastCrate; i++) { if (fHVBoard[i]->SynchBoard()) printf("Synchronized board %d\n", fHVBoard[i]->BoardNumber); else printf("Failed to synchronize board %d\n", fHVBoard[i]->BoardNumber); } } // Switch on all channels consecutively for cabling test void cmd_test() { Verbose = false; // Loop over crates for (int i=FirstCrate; i<=LastCrate; i++) { printf("Testing board %d (q to stop, any other key to continue)\n", fHVBoard[i]->BoardNumber); if (fHVBoard[i]->GlobalSet(0) != 1) { printf("Error: Could not global set board to zero\n"); return; } for (int k=0; kChannelSet(k, j, atoi(Param[1])) != 1) { printf(" Error setting voltage\n"); return; } if (getchar() == 'q') return; } } } // Send bytes and wait for response void cmd_send() { unsigned char wbuf[MAX_NUM_TOKEN]; int Number; for (int j=1; jCommunicate(wbuf, NParam-1); } } // Measure read speed void cmd_rate() { struct timeval Start, End; int N = atoi(Param[1]); if (N < 1) return; Verbose = false; gettimeofday(&Start, NULL); for (int i=0; i<=N; i++) fHVBoard[0]->ReadChannel(0, 0); gettimeofday(&End, NULL); double Diff = ((End.tv_sec-Start.tv_sec)*1e6 + End.tv_usec-Start.tv_usec) * 1e-6; printf("%d accesses in %f seconds: rate %.0f Hz, period %.2f ms\n", N, Diff, N/Diff, (Diff*1e3)/N); } // Switch repeat on/off void cmd_repeat() { if (Match(Param[1],"on")) Repeat = true; else Repeat = false; printf("Auto command repeat is %s\n", Repeat ? "on (Hit return while repeating to stop)" : "off"); } // Print status void cmd_status() { int Board; Verbose = false; if (NParam==2 && ConvertToInt(Param[1], &Board)) { for (int i=FirstCrate; i<=LastCrate; i++) { for (int j=0; jReadChannel(Board, j); if (fHVBoard[i]->Status.BoardNumber == -1) printf("Read error "); else printf(" %s %s %5d ", fHVBoard[i]->Status.Overcurrent ? "OC":"--", fHVBoard[i]->Status.Acknowledge ? "OK":"KO",fHVBoard[i]->Status.Current); } printf("\n"); } } else { printf(" Auto command repeat is %s\n", Repeat ? "on" : "off"); printf(" Total number of HV crates: %d\n", NumCrates); printf(" Active HV crates: %d\n\n", LastCrate - FirstCrate + 1); for (int i=FirstCrate; i<=LastCrate; i++) { printf(" Crate %d (%s) Wrap counter: %d Time-out: %.2f s\n", fHVBoard[i]->BoardNumber, fHVBoard[i]->BoardName, fHVBoard[i]->LastWrapCount, fHVBoard[i]->fTimeOut); } } } // Print crate configuration void cmd_config() { Verbose = false; for (int i=FirstCrate; i<=LastCrate; i++) { for (int j=0; jReadChannel(j, 0); if (fHVBoard[i]->Status.BoardNumber == -1) printf("Read error\n"); else printf(" %s\n", fHVBoard[i]->Status.Acknowledge ? "OK":"KO"); } } } // Set timeout to return from read void cmd_timeout() { double Timeout; if (!ConvertToDouble(Param[1], &Timeout)) return; for (int i=0; ifTimeOut = Timeout; } // Exit program (delete HV boards) void cmd_exit() { for (int i=0; i