Changeset 11906 for fact/BIASctrl
- Timestamp:
- 08/15/11 17:01:20 (13 years ago)
- Location:
- fact/BIASctrl
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/BIASctrl/BIASctrl.cc
r11205 r11906 14 14 #include <readline/history.h> 15 15 16 const char READLINE_HIST_FILE[] = "/tmp/.history.BIASctrl"; 16 using namespace std; 17 18 const string READLINE_HIST_FILE = string(getenv("HOME"))+"/.history_BIASctrl"; 17 19 18 20 // Main program … … 24 26 // Uses getc() for readline library (allows interruption by signal) and load history buffer 25 27 rl_getc_function = getc; 26 read_history(READLINE_HIST_FILE );28 read_history(READLINE_HIST_FILE.c_str()); 27 29 28 30 // Set signal SIGTERM to interrupt blocking system calls … … 38 40 // Handle command-line input 39 41 while (!M.ExitRequest) { 40 Command = readline(" \rBias> ");42 Command = readline("Bias> "); 41 43 42 44 // NULL returned if interrupted by signal … … 55 57 56 58 // Save history buffer 57 int Ret = write_history(READLINE_HIST_FILE );58 if (Ret != 0 ) printf("Error writing history file to '%s' (%s)\n", READLINE_HIST_FILE , strerror(Ret));59 int Ret = write_history(READLINE_HIST_FILE.c_str()); 60 if (Ret != 0 ) printf("Error writing history file to '%s' (%s)\n", READLINE_HIST_FILE.c_str(), strerror(Ret)); 59 61 } -
fact/BIASctrl/Crate.cc
r11773 r11906 20 20 // Initialize 21 21 InitOK = false; 22 Disabled = false; 22 23 File = NULL; 23 24 m = PIO; … … 26 27 CrateNumber = Number; 27 28 WrapCount = -1; 28 29 for (int i=0; i<MAX_NUM_BOARDS; i++) { 30 for (int j=0; j<NUM_CHANNELS; j++) { 31 OC[i][j] = false; 32 Present[i][j] = false; 33 Current[i][j] = 0; 34 } 29 LastReset = 0; 30 31 for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) { 32 OC[i] = false; 33 Present[i] = false; 34 Current[i] = 0; 35 35 } 36 36 ResetHit = false; … … 45 45 NameService = new DimService ((SERVER_NAME"/NAME/ID"+ID.str()).c_str(), Name); 46 46 BiasVolt = new DimService ((char *) (SERVER_NAME"/VOLT/ID"+ID.str()).c_str(), (char *) "D", Volt, MAX_NUM_BOARDS*NUM_CHANNELS*sizeof(double)); 47 BiasDAC = new DimService ((char *) (SERVER_NAME"/DAC/ID"+ID.str()).c_str(), (char *) "I", DAC, MAX_NUM_BOARDS*NUM_CHANNELS*sizeof(int));48 47 BiasCurrent = new DimService ((char *) (SERVER_NAME"/MICROAMP/ID"+ID.str()).c_str(), (char *) "F", Current, MAX_NUM_BOARDS*NUM_CHANNELS*sizeof(float)); 49 48 … … 52 51 // Open device 53 52 if ((fDescriptor = open(("/dev/"+CrateName).c_str(), O_RDWR|O_NOCTTY|O_NDELAY)) == -1) { 54 if (errno != 2) m->PrintMessage("Error: Could not open device %d/%s (%s)\n", CrateNumber, Name, strerror(errno));53 if (errno != 2) m->PrintMessage("Error: Could not open device %d/%s (%s)\n", CrateNumber, Name, strerror(errno)); 55 54 return; 56 55 } … … 69 68 70 69 // Set baudrate and raw mode 71 if (cfsetspeed(&tio, B AUDRATE) == -1) {70 if (cfsetspeed(&tio, B115200) == -1) { 72 71 m->PrintMessage("Error: Could not set baud rate of device %s (%s)\n", Name, strerror(errno)); 73 72 return; … … 79 78 } 80 79 80 // Synchronize crate 81 if (!Synch()) return; 82 83 // Set voltages and zero and reset crate 84 if (!GlobalSet(0) || !SystemReset()) return; 85 81 86 InitOK = true; 82 87 } … … 88 93 89 94 if(fDescriptor != -1) { 90 GlobalSet(0); 91 92 SystemReset(); 95 if (!GlobalSet(0)) m->Message(m->ERROR, "Could not global set crate %d to zero voltage", Name); 96 93 97 if (File == NULL) { 94 98 if (close(fDescriptor) == -1) m->PrintMessage("Error closing device %s (%s)\n", Name, strerror(errno)); … … 99 103 delete NameService; 100 104 delete BiasVolt; 101 delete BiasDAC;102 105 delete BiasCurrent; 103 106 delete[] Name; … … 105 108 106 109 107 // Communicate: Write and read from HV Board until time-out has been reached108 // 109 // Returns: 0 error, 1 success, -1 time-out exceeded110 // 111 // Communicate with crate (return empty vector in case of time-out or not a multiple of 3 bytes was returned) 112 // 110 113 vector<unsigned char> Crate::Communicate(string Buf) { 111 114 112 115 int N; 113 116 fd_set SelectDescriptor; 114 struct timeval WaitTime = {(long) m->fTimeOut, (long) ((m->fTimeOut-(long) m->fTimeOut)*1e6)}; 117 float TimeOut = atof(m->GetConfig("TimeOut").c_str()); 118 struct timeval WaitTime = {(long) TimeOut, (long) ((TimeOut-(long) TimeOut)*1e6)}; 115 119 char Buffer[10000]; 116 120 vector<unsigned char> Data; 121 122 // Crate disabled because of too many errors? 123 if (Disabled) return Data; 117 124 118 125 // === Lock device === 119 126 flockfile(File); 120 127 121 // Do not try to communicate if crate has too many errors122 if (ErrorCount > MAX_ERR_COUNT) goto ExitCommunicate;123 124 128 // === Write data === 125 129 if ((N = write(fDescriptor, Buf.data(), Buf.size())) < (int) Buf.size()) { 126 if (N == -1) m->Message(m->ERROR, "Could not write data to crate (%s)", strerror(errno));127 else m->Message(m->ERROR, "Could write only %d of %d bytes to board", N, Buf.size());130 if (N == -1) m->Message(m->ERROR, "Could not write data to crate %s (%s)", Name, strerror(errno)); 131 else m->Message(m->ERROR, "Could write only %d of %d bytes to crate %s", N, Buf.size(), Name); 128 132 ErrorCount++; 129 133 goto ExitCommunicate; 130 134 } 131 135 … … 145 149 // Read data 146 150 if ((N = read(fDescriptor, Buffer, sizeof(Buffer))) == -1) { 147 m->Message(m->ERROR, "Read error (%s)", strerror(errno));151 m->Message(m->ERROR, "Read error from crate %s (%s)", Name, strerror(errno)); 148 152 ErrorCount++; 149 153 goto ExitCommunicate; … … 160 164 } 161 165 162 // === Check/update all wrap counter===166 // === Check/update wrap counter in all received data packages of three bytes === 163 167 for (unsigned int i=0; i<Data.size(); i+=3) { 164 168 if (WrapCount != -1) { … … 168 172 WrapCount = (Data[i]>>4) & 7; 169 173 } 174 175 // Check wrap counter 176 if (!WrapOK) { 177 m->Message(m->WARN, "Wrap counter mismatch of crate %s", Name); 178 ErrorCount++; 179 } 170 180 171 181 // === UnLock file descriptor === … … 173 183 funlockfile(File); 174 184 175 if ( Data.empty()) Data.push_back(0);185 if (ErrorCount > MAX_ERR_COUNT) Disabled = true; 176 186 177 187 return Data; … … 181 191 // System reset of bias crate 182 192 // 183 int Crate::SystemReset() { 184 185 vector<unsigned char> Data = Communicate(string(3, 0)); 186 187 if (Data.size() == 3) { 188 ResetHit = false; 189 ErrorCount = 0; 190 return 1; 191 } 192 return 0; 193 bool Crate::SystemReset() { 194 195 // Check if minimum requested period elapsed since last reset 196 if (time(NULL) - LastReset < max(atoi(m->GetConfig("MinResetPeriod").c_str()),1)) return false; 197 LastReset = time(NULL); 198 199 // Send reset and check if 3 bytes returned 200 if (Communicate(string(3, 0)).size() != 3) return false; 201 202 ResetHit = false; 203 Disabled = false; 204 ErrorCount = 0; 205 return true; 193 206 } 194 207 … … 196 209 // Read all channels status 197 210 // 198 intCrate::ReadAll() {211 bool Crate::ReadAll() { 199 212 200 213 string Buf; 201 214 202 215 // Prepare command to read all channels 203 for ( int i=0; i<MAX_NUM_BOARDS; i++) for (intj=0; j<NUM_CHANNELS; j++) {216 for (unsigned int i=0; i<MAX_NUM_BOARDS; i++) for (int unsigned j=0; j<NUM_CHANNELS; j++) { 204 217 Buf.push_back(1<<5 | i<<1 | (j&16)>>4); 205 218 Buf.push_back(j<<4); … … 210 223 vector<unsigned char> Data = Communicate(Buf); 211 224 212 if (Data.size() != Buf.size()) return 0;225 if (Data.size() != Buf.size()) return false; 213 226 214 227 // Evaluate data returned from crate 215 228 int Count = 0; 216 for ( int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {217 Current[i] [j]= (Data[Count+1] + (Data[Count] & 0x0f)*256) * 1.22;218 OC[i] [j]= Data[Count] & 128;219 Present[i] [j]= (Data[Count+2] & 0x70) == 0 ? true : false;229 for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) { 230 Current[i] = (Data[Count+1] + (Data[Count] & 0x0f)*256) * 1.22; 231 OC[i] = Data[Count] & 128; 232 Present[i] = (Data[Count+2] & 0x70) == 0 ? true : false; 220 233 if (!ResetHit) ResetHit = (Data[Count+2] & 0x80) == 0 ? false : true; 221 234 Count += 3; 222 235 } 223 return 1;236 return true; 224 237 } 225 238 226 239 227 240 // ***** Global set ***** 228 int Crate::GlobalSet(double Voltage) { 229 241 bool Crate::GlobalSet(double Voltage) { 242 243 // Limit voltage 244 Voltage = min(Voltage, atof(m->GetConfig("VoltageLimit").c_str())); 245 246 // Calculate DAC value 230 247 unsigned int SetPoint = (unsigned int) (Voltage/90.0*0x0fff); 231 248 232 249 // Execute command 233 250 string Buf; … … 235 252 vector<unsigned char> Data = Communicate(Buf); 236 253 237 if (Data.size() == 3) { 238 for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) { 239 DAC[i][j] = SetPoint; 240 Volt[i][j] = Voltage; 241 RefVolt[i][j] = Voltage; 242 } 243 return 1; 244 } 245 return 0; 254 if (Data.size() != 3) return false; 255 256 for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) { 257 Volt[i] = Voltage; 258 RefVolt[i] = Voltage; 259 } 260 return true; 246 261 } 247 262 248 263 249 264 // ***** Set channel voltages ***** 250 intCrate::SetChannels(map<unsigned int, double> V) {265 bool Crate::SetChannels(map<unsigned int, double> V) { 251 266 252 267 string Buf; 253 268 254 if (V.empty()) return 1;269 if (V.empty()) return true; 255 270 256 271 // Build and execute commands 257 for (map<unsigned int, double>::const_iterator it = V.begin(); it != V.end(); ++it) { 272 for (map<unsigned int, double>::iterator it = V.begin(); it != V.end(); ++it) { 273 // Limit maximum voltage 274 it->second = min(it->second, atof(m->GetConfig("VoltageLimit").c_str())); 275 258 276 // If DAC value unchanged, do not send command 259 if ( DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS]== it->second/90.0*0x0fff) continue;277 if (GetDAC(it->first) == it->second/90.0*0x0fff) continue; 260 278 261 279 // Add command to buffer … … 267 285 268 286 // Store new voltage values of successful 269 if (Data.size() == Buf.size()) { 270 for (map<unsigned int, double>::const_iterator it = V.begin(); it != V.end(); ++it) { 271 DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = (unsigned int) (it->second/90.0*0x0fff); 272 Volt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second; 273 RefVolt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second; 274 } 275 return 1; 276 } 277 return 0; 287 if (Data.size() != Buf.size()) return false; 288 289 for (map<unsigned int, double>::const_iterator it = V.begin(); it != V.end(); ++it) { 290 Volt[it->first] = it->second; 291 RefVolt[it->first] = it->second; 292 } 293 294 return true; 278 295 } 279 296 … … 296 313 void Crate::ClearVoltageArrays() { 297 314 298 for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) { 299 DAC[i][j] = 0; 300 Volt[i][j] = 0; 301 RefVolt[i][j] = 0; 315 for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) { 316 Volt[i] = 0; 317 RefVolt[i] = 0; 302 318 } 303 319 … … 310 326 311 327 if (Channel >= MAX_NUM_BOARDS*NUM_CHANNELS) return 0; 312 else return Volt[Channel /NUM_CHANNELS][Channel%NUM_CHANNELS];328 else return Volt[Channel]; 313 329 } 314 330 … … 318 334 319 335 if (Channel >= MAX_NUM_BOARDS*NUM_CHANNELS) return 0; 320 else return DAC[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS];336 else return (unsigned int) (Volt[Channel]/90.0*0x0fff); 321 337 } 322 338 … … 326 342 327 343 if (Channel >= MAX_NUM_BOARDS*NUM_CHANNELS) return 0; 328 else return Current[Channel /NUM_CHANNELS][Channel%NUM_CHANNELS];344 else return Current[Channel]; 329 345 } 330 346 … … 334 350 335 351 BiasVolt->updateService(); 336 BiasDAC->updateService();337 352 } 338 353 … … 341 356 void Crate::SetRefCurrent() { 342 357 343 for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) { 344 RefCurrent[i][j] = Current[i][j]; 345 } 358 for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) RefCurrent[i] = Current[i]; 346 359 } 347 360 … … 354 367 map<unsigned int, double> Voltages; 355 368 356 for ( int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {357 if (RefVolt[i] [j]== 0) continue;358 Voltages[i *NUM_CHANNELS+j] = RefVolt[i][j] + (RefCurrent[i][j]-Current[i][j])*RESISTOR/1e6;369 for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) { 370 if (RefVolt[i] == 0) continue; 371 Voltages[i] = RefVolt[i] + (RefCurrent[i]-Current[i])*RESISTOR/1e6; 359 372 } 360 373 SetChannels(Voltages); -
fact/BIASctrl/Crate.h
r11361 r11906 14 14 #include "dis.hxx" 15 15 16 #define MAX_NUM_BOARDS 13 // Maximum number of boards per crate 17 #define NUM_CHANNELS 32 // Channels per bias board 18 #define BAUDRATE B115200 19 const float RESISTOR = 1000; // Resistance in Ohm for voltage correction 16 const unsigned int MAX_NUM_BOARDS = 13; // Maximum number of boards per crate 17 const unsigned int NUM_CHANNELS = 32; // Channels per bias board 18 const float RESISTOR = 1000; // Resistance in Ohm for voltage correction 20 19 const int MAX_ERR_COUNT = 10; // Maximum number of errors before reporting stopped 21 20 class User; … … 29 28 DimService *NameService; 30 29 DimService *BiasVolt; 31 DimService *BiasDAC;32 30 DimService *BiasCurrent; 33 31 32 double Volt[MAX_NUM_BOARDS*NUM_CHANNELS]; // Voltage 33 float Current[MAX_NUM_BOARDS*NUM_CHANNELS]; 34 time_t LastReset; 34 35 35 int DAC[MAX_NUM_BOARDS][NUM_CHANNELS]; // Voltage in DAC units36 double Volt[MAX_NUM_BOARDS][NUM_CHANNELS]; // Voltage in Volt37 float Current[MAX_NUM_BOARDS][NUM_CHANNELS];38 36 std::vector<unsigned char> Communicate(std::string); 39 37 void ClearVoltageArrays(); … … 45 43 char *Name; 46 44 47 bool OC[MAX_NUM_BOARDS ][NUM_CHANNELS];48 bool Present[MAX_NUM_BOARDS ][NUM_CHANNELS];45 bool OC[MAX_NUM_BOARDS*NUM_CHANNELS]; 46 bool Present[MAX_NUM_BOARDS*NUM_CHANNELS]; 49 47 bool ResetHit; 50 48 bool WrapOK; 51 49 int WrapCount; 52 50 int ErrorCount; 51 bool Disabled; 53 52 54 float RefCurrent[MAX_NUM_BOARDS ][NUM_CHANNELS];55 double RefVolt[MAX_NUM_BOARDS ][NUM_CHANNELS];53 float RefCurrent[MAX_NUM_BOARDS*NUM_CHANNELS]; 54 double RefVolt[MAX_NUM_BOARDS*NUM_CHANNELS]; 56 55 57 56 bool InitOK; 58 57 59 intSetChannels(std::map<unsigned int, double>);60 intReadAll();61 intSystemReset();62 intGlobalSet(double);58 bool SetChannels(std::map<unsigned int, double>); 59 bool ReadAll(); 60 bool SystemReset(); 61 bool GlobalSet(double); 63 62 bool Synch(); 64 63 double GetVoltage(unsigned int); -
fact/BIASctrl/History.txt
r11781 r11906 16 16 4/8/2011 'pixel' and 'channel' commands accept 'info' parameter. 17 17 5/8/2011 Default voltages now given per bias channel, not per pixel 18 15/8/2011 Added global voltage limit and minimum time between system resets. -
fact/BIASctrl/User.cc
r11781 r11906 26 26 {"load", &User::cmd_load, 1, true, "<file>", "Load and set bias settings from file"}, 27 27 {"save", &User::cmd_save, 1, true, "<file>", "Save current bias settings to file"}, 28 {"rate", &User::cmd_rate, 1, false, "<rate>", "Set refresh rate in Hz"},29 {"timeout", &User::cmd_timeout, 1, false, "<time>", "Set timeout to return from read in seconds"},30 28 {"help", &User::cmd_help, 0, false, "", "Print help"}, 31 29 {"exit", &User::cmd_exit, 0, false, "", "Exit program"}, … … 43 41 ConsoleOut = new DimService(SERVER_NAME"/ConsoleOut", (char *) ""); 44 42 45 // Get configuration data43 // Get/initialize configuration data 46 44 vector<string> Boards = Tokenize(GetConfig("Boards", "dummy"), " \t"); 47 fTimeOut = atof(GetConfig("TimeOut").c_str());48 fStatusRefreshRate = atof(GetConfig("StatusRefreshRate").c_str());49 fMaxDiff = atof(GetConfig("HVMaxDiffNew").c_str());50 51 if (fStatusRefreshRate < MIN_RATE || fStatusRefreshRate > MAX_RATE) fStatusRefreshRate = 1;45 GetConfig("TimeOut"); 46 GetConfig("VoltageLimit"); 47 GetConfig("MinResetPeriod"); 48 GetConfig("RampSpeed"); 49 GetConfig("UpdatePeriod"); 52 50 53 51 vector<string> Text = Tokenize(GetConfig("DefaultVoltage", ""), " \t"); … … 62 60 class Crate *New = new class Crate(Boards[i], Crates.size(), this); 63 61 64 if (New->InitOK && New->Synch()) {62 if (New->InitOK) { 65 63 PrintMessage("Synchronized and reset crate %s (#%d)\n", Boards[i].c_str(), Crates.size()); 66 64 Crates.push_back(New); … … 94 92 int Ret; 95 93 96 // Wait for thread to quit 97 if ((Ret = pthread_cancel(Thread)) != 0) Message(ERROR, "pthread_cancel() failed (%s)", strerror(Ret)); 94 // Wait for thread to quit (ignore error if thread did already exit) 95 if ((Ret = pthread_cancel(Thread)) != 0) { 96 if (Ret != ESRCH) Message(ERROR, "pthread_cancel() failed (%s)", strerror(Ret)); 97 } 98 98 if ((Ret = pthread_join(Thread, NULL)) != 0) Message(ERROR, "pthread_join() failed (%s)", strerror(Ret)); 99 99 … … 266 266 if (Match(Parameter[n+1], "info")) { 267 267 PrintMessage("Crate %2d, channel %3d ", Crate, Channel); 268 if (!Crates[Crate]->Present[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS]) { 269 PrintMessage("(channel not present in crate)"); 270 } 268 if (!Crates[Crate]->Present[Channel]) PrintMessage("(channel not present in crate)"); 271 269 PrintMessage("\n Channel is on board %d, board channel %d\n", Channel/32, Channel%32); 272 270 … … 280 278 PrintMessage("\n Voltage setpoint: %.2f V (DAC %u) Current: %.2f uA ", Crates[Crate]->GetVoltage(Channel), Crates[Crate]->GetDAC(Channel), Crates[Crate]->GetCurrent(Channel)); 281 279 282 if (Crates[Crate]->OC[Channel /NUM_CHANNELS][Channel%NUM_CHANNELS]) PrintMessage("(overcurrent)\n");280 if (Crates[Crate]->OC[Channel]) PrintMessage("(overcurrent)\n"); 283 281 else PrintMessage("\n"); 284 282 … … 327 325 328 326 char Buffer[MAX_COM_SIZE]; 329 int Errors = 0, Channel; 327 int Errors = 0; 328 unsigned int Channel; 330 329 double Value; 331 330 FILE *File; … … 368 367 if (fclose(File) != 0) PrintMessage("Error: Could not close file '%s'\n", Parameter[1].c_str()); 369 368 } 370 371 // 372 // Set refresh rate 373 // 374 void User::cmd_rate() { 375 376 double Rate; 377 378 if (!ConvertToDouble(Parameter[1], &Rate)) { 379 PrintMessage("Error: Wrong number format\n"); 380 return; 381 } 382 383 // Check limits 384 if (Rate<MIN_RATE || Rate>MAX_RATE) { 385 PrintMessage("Refresh rate out of range (min: %.2f Hz, max: %.2f Hz)\n", MIN_RATE, MAX_RATE); 386 return; 387 } 388 389 fStatusRefreshRate = Rate; 390 PrintMessage("Refresh rate set to %.2f Hz\n", fStatusRefreshRate); 391 } 392 369 393 370 // 394 371 // Reset crates … … 396 373 void User::cmd_reset() { 397 374 398 if (Crates[ActiveCrate]->SystemReset() == 1) PrintMessage("System reset of crate %d\n", ActiveCrate);375 if (Crates[ActiveCrate]->SystemReset()) PrintMessage("System reset of crate %d\n", ActiveCrate); 399 376 else PrintMessage("Error: Could not reset crate %d\n", ActiveCrate); 400 377 } … … 412 389 } 413 390 414 if ( Crates[ActiveCrate]->GlobalSet(Voltage) != 1) {391 if (!Crates[ActiveCrate]->GlobalSet(Voltage)) { 415 392 PrintMessage("Error: Could not global set crate %d\n", ActiveCrate); 416 393 } … … 435 412 fprintf(File, "%s\n\n", Crates[i]->Name); 436 413 437 for ( int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) fprintf(File,"%.3f ",Crates[i]->GetVoltage(j));414 for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) fprintf(File,"%.3f ",Crates[i]->GetVoltage(j)); 438 415 fprintf(File, "\n"); 439 416 } … … 463 440 void User::cmd_status() { 464 441 465 PrintMessage(" Number of crates: %d\n", Crates.size()); 466 PrintMessage(" Active crate: %d\n", ActiveCrate); 467 PrintMessage(" Refresh rate: %.2f Hz\n", fStatusRefreshRate); 468 PrintMessage(" Time out: %.2f s\n\n", fTimeOut); 469 PrintMessage(" MaxDiff : %u\n", fMaxDiff); 470 442 PrintMessage(" Number of crates: %d\n", Crates.size()); 443 PrintMessage(" Active crate: %d\n", ActiveCrate); 444 PrintMessage(" Update delay: %d sec\n", min(atoi(GetConfig("UpdatePeriod").c_str()), 1)); 445 PrintMessage(" Time out: %.2f sec\n", atof(GetConfig("TimeOut").c_str())); 446 PrintMessage(" Max ramp speed %.2f V/10 ms\n", atof(GetConfig("RampSpeed").c_str())); 447 PrintMessage(" Voltage limit: %.2f V\n", atof(GetConfig("VoltageLimit").c_str())); 448 PrintMessage(" Minium reset delay: %u sec\n", atoi(GetConfig("MinResetPeriod").c_str())); 449 471 450 for (unsigned int i=0; i<Crates.size(); i++) { 472 PrintMessage(" CRATE %d (%s)\n Wrap counter: %s (%d) Reset: %s Error count: %d\n ", 451 452 PrintMessage(" CRATE %d (%s)\n Wrap counter: %s (%d) Reset: %s Error count: %d %s\n ", 473 453 i, Crates[i]->Name, Crates[i]->WrapOK ? "ok":"error", Crates[i]->WrapCount, 474 Crates[i]->ResetHit ? "yes" : "no", Crates[i]->ErrorCount); 454 Crates[i]->ResetHit ? "yes" : "no", Crates[i]->ErrorCount, Crates[i]->Disabled ? "(DISABLED)":""); 455 456 // Read all channels 457 if (!Crates[i]->ReadAll()) { 458 PrintMessage("Could not update status from crate %d\n", i); 459 continue; 460 } 475 461 476 462 if (Parameter.size() == 1) PrintMessage("Channel voltages (in V)"); … … 478 464 else PrintMessage("Channel currents (in uA)"); 479 465 480 for ( int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) {466 for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) { 481 467 if (j%12 == 0) PrintMessage("\n%3.1d: ", j); 482 if (!Crates[i]->Present[j /NUM_CHANNELS][j%NUM_CHANNELS]) PrintMessage(" - ");468 if (!Crates[i]->Present[j]) PrintMessage(" - "); 483 469 else if (Parameter.size() == 1) PrintMessage("%#5.2f ",Crates[i]->GetVoltage(j)); 484 470 else if (Match(Parameter[1], "dac")) PrintMessage("%5d ", Crates[i]->GetDAC(j)); 485 else PrintMessage("%#5.2f %s ", Crates[i]->GetCurrent(j), Crates[i]->OC[j /NUM_CHANNELS][j%NUM_CHANNELS] ? "OC":"");471 else PrintMessage("%#5.2f %s ", Crates[i]->GetCurrent(j), Crates[i]->OC[j] ? "OC":""); 486 472 } 487 473 PrintMessage("\n"); … … 489 475 } 490 476 491 //492 // Set timeout to return from read493 //494 void User::cmd_timeout() {495 496 double Timeout;497 498 if (!ConvertToDouble(Parameter[1], &Timeout)) {499 PrintMessage("Error: Wrong number format\n");500 return;501 }502 503 fTimeOut = Timeout;504 PrintMessage("Timeout set to %.2f s\n", fTimeOut);505 }506 507 477 // 508 478 // Exit program (Signal makes readline return and sets ExitRequest) … … 535 505 if (vasprintf(&Text, Format, ArgumentPointer) == -1) Text = Error; 536 506 va_end(ArgumentPointer); 507 508 if (strlen(Text) == 0) return; 537 509 538 510 // Print to console 539 printf("%s", Text); // New prompt511 printf("%s", Text); 540 512 fflush(stdout); 541 if ( strlen(Text)>0 && Text[strlen(Text)-1]=='\n') rl_on_new_line(); // New prompt513 if (Text[strlen(Text)-1] == '\n') rl_on_new_line(); // New prompt 542 514 543 515 // Send to DIM text service … … 550 522 551 523 552 // Ramp to new voltage with maximum step size given in fMaxDiff524 // Ramp to new voltage with given maximum step 553 525 // No ramping when decreasing voltage 554 526 unsigned int User::RampVoltages(int Crate, map<unsigned int, double> Voltages) { … … 556 528 map<unsigned int, double> Target; 557 529 int Errors = 0; 530 double MaxDiff = atof(GetConfig("RampSpeed").c_str()); 558 531 559 532 // Ramp until all channels at desired value … … 567 540 Target = Voltages; 568 541 for (map<unsigned int, double>::iterator it = Target.begin(); it != Target.end(); ++it) { 569 if (Crates[Crate]->GetVoltage(it->first) + fMaxDiff < it->second) {570 it->second = Crates[Crate]->GetVoltage(it->first) + fMaxDiff;542 if (Crates[Crate]->GetVoltage(it->first) + MaxDiff < it->second) { 543 it->second = Crates[Crate]->GetVoltage(it->first) + MaxDiff; 571 544 } 572 545 } 573 546 574 547 // Set channels to next target and wait 10 ms 575 if ( Crates[Crate]->SetChannels(Target) != 1) Errors++;548 if (!Crates[Crate]->SetChannels(Target)) Errors++; 576 549 usleep(10000); 577 550 } … … 586 559 void User::Monitor() { 587 560 588 static bool Warned = false;589 561 int Ret; 590 unsigned int Count=0;591 562 592 563 while (!ExitRequest) { … … 596 567 Message(FATAL, "pthread_setcancelstate() failed (%s)", strerror(Ret)); 597 568 } 598 if (usleep((unsigned long) floor(1000000./fStatusRefreshRate)) == -1) { 599 Message(FATAL, "usleep() failed (%s)", strerror(errno)); 600 } 569 sleep(min(atoi(GetConfig("UpdatePeriod").c_str()), 1)); 601 570 if ((Ret=pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL)) != 0) { 602 571 Message(FATAL, "pthread_setcancelstate() failed (%s)", strerror(Ret)); … … 605 574 // Check all crates 606 575 for (unsigned int i=0; i<Crates.size(); i++) { 607 if (Crates[i]->ErrorCount > MAX_ERR_COUNT) { 608 if (!Warned) { 609 Warned = true; 610 Message(WARN, "Crate %d has many read/write errors, further error reporting disabled", i); 611 } 612 continue; 576 // Crate disabled because of too many errors? 577 if (Crates[i]->Disabled) continue; 578 579 // Read all channels 580 if (!Crates[i]->ReadAll()) { 581 Message(ERROR, "Monitor thread could not read status from crate %d", i); 582 continue; 613 583 } 614 584 585 // Check if crate push button was hit 615 586 if (Crates[i]->ResetHit) { 616 587 Message(INFO, "Manual reset of crate %d, setting voltages to zero and issuing system reset", i); 617 Crates[i]->GlobalSet(0);618 Crates[i]->SystemReset();588 if (!Crates[i]->GlobalSet(0)) Message(ERROR, "Global set to zero voltage of crate %d failed", i); 589 if (!Crates[i]->SystemReset()) Message(ERROR, "System reset of crate %d failed", i); 619 590 } 620 591 621 if (!Crates[i]->WrapOK) { 622 Message(ERROR, "Wrap counter mismatch of crate %d", i); 623 } 624 625 if (Crates[i]->ReadAll() != 1) { 626 Message(ERROR, "Monitor could not read status from crate %d", i); 627 continue; 628 } 629 592 // Check for overcurrent and set voltage to zero if occurred 630 593 map<unsigned int, double> Voltages; 631 594 632 for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) { 633 if (Crates[i]->OC[j/NUM_CHANNELS][j%NUM_CHANNELS]) { 634 if (Count++ < 5) Message(WARN, "Overcurrent on crate %d, board %d, channel %d, setting voltage to zero", i, j/NUM_CHANNELS, j%NUM_CHANNELS); 635 if (Count == 5) Message(ERROR, "Five overcurrent warnings, no more!"); 595 for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) { 596 if (Crates[i]->OC[j]) { 597 Message(WARN, "Overcurrent on crate %d, board %d, channel %d, setting voltage to zero", i, j/NUM_CHANNELS, j%NUM_CHANNELS); 636 598 Voltages[j] = 0; 637 599 } 638 600 } 639 if (!Voltages.empty()) { 640 Crates[i]->SetChannels(Voltages); 641 Crates[i]->SystemReset(); 642 } 601 if (!Crates[i]->SetChannels(Voltages)) Message(ERROR, "Error when setting voltages of crate %d", i); 643 602 644 603 if (Mode == mode_dynamic) Crates[i]->AdaptVoltages(); -
fact/BIASctrl/User.h
r11772 r11906 18 18 19 19 #define MAX_COM_SIZE 5000 20 21 #define MIN_RATE 0.0122 #define MAX_RATE 50.023 20 24 21 class User: public EvidenceServer { … … 50 47 51 48 public: 52 double fTimeOut;53 float fStatusRefreshRate;54 double fMaxDiff;55 49 unsigned int ActiveCrate; 56 50 … … 66 60 void cmd_status(); void cmd_gs(); 67 61 void cmd_load(); void cmd_save(); 68 void cmd_exit(); void cmd_rate(); 69 void cmd_timeout(); void cmd_reset(); 62 void cmd_exit(); void cmd_reset(); 70 63 void cmd_help(); void cmd_mode(); 71 64 void cmd_crate(); void cmd_shell();
Note:
See TracChangeset
for help on using the changeset viewer.