- Timestamp:
- 11/24/10 12:11:50 (14 years ago)
- Location:
- fact/BIASctrl
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/BIASctrl/Crate.cc
r10052 r10059 4 4 5 5 \********************************************************************/ 6 #include <utility> 6 7 7 8 #include "Crate.h" … … 29 30 for (int j=0; j<NUM_CHANNELS; j++) { 30 31 OC[i][j] = false; 32 Present[i][j] = false; 31 33 Current[i][j] = 0; 32 34 } … … 102 104 // 103 105 // Returns: 0 error, 1 success, -1 time-out exceeded 104 vector<char> Crate::Communicate( unsigned char* wbuf, int Bytes) {106 vector<char> Crate::Communicate(string Buf) { 105 107 106 108 int N; … … 114 116 115 117 // === Write data === 116 if ((N = write(fDescriptor, wbuf, Bytes)) < Bytes) {118 if ((N = write(fDescriptor, Buf.data(), Buf.size())) < (int) Buf.size()) { 117 119 if (N == -1) m->Message(m->ERROR, "Could not write data to crate (%s)", strerror(errno)); 118 else m->Message(m->ERROR, "Could write only %d of %d bytes to board", N, B ytes);120 else m->Message(m->ERROR, "Could write only %d of %d bytes to board", N, Buf.size()); 119 121 ErrorCount++; 120 122 goto ExitCommunicate; … … 144 146 // Add data to buffer 145 147 for (int i=0; i<N; i++) Data.push_back(Buffer[i]); 146 } while(Data.size() < (unsigned int) Bytes);148 } while(Data.size() < Buf.size()); 147 149 148 150 // === Check if multiple of three bytes were returned === … … 175 177 int Crate::SystemReset() { 176 178 177 unsigned char wbuf[] = {0,0,0}; 178 vector<char> Data = Communicate(wbuf, 3); 179 179 vector<char> Data = Communicate(string(3, 0)); 180 180 181 if (Data.size() == 3) { 181 ClearVoltageArrays();182 182 ErrorCount = 0; 183 183 return 1; … … 187 187 188 188 // 189 // Read channel status190 //191 int Crate::ReadChannel(unsigned int Board, unsigned int Channel) {192 193 // Check limits194 if (Board > MAX_NUM_BOARDS) {195 m->PrintMessage("Error: Board number out of range\n");196 return 0;197 }198 if (Channel > NUM_CHANNELS) {199 m->PrintMessage("Error: Channel number out of range\n");200 return 0;201 }202 203 // Execute command204 unsigned char wbuf[] = {1<<5 | Board<<1 | (Channel&16)>>4, Channel<<4, 0};205 vector<char> Data = Communicate(wbuf, 3);206 207 if (Data.size() == 3) {208 Current[Board][Channel] = Data[1] + (Data[0]&15)*256;209 OC[Board][Channel] = Data[0] & 128;210 ResetHit = Data[2] & 128;211 if (Board==2 && Channel==19) OC[Board][Channel] = false;212 return 1;213 }214 return Data[0];215 }216 217 218 //219 189 // Read all channels status 220 190 // 221 191 int Crate::ReadAll() { 222 192 223 unsigned char wbuf[3*MAX_NUM_BOARDS*NUM_CHANNELS]; 224 int Count = 0; 193 string Buf; 225 194 226 195 // Prepare command to read all channels 227 196 for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) { 228 wbuf[Count++] = 1<<5 | i<<1 | (j&16)>>4;229 wbuf[Count++] = j<<4;230 wbuf[Count++] = 0;197 Buf.push_back(1<<5 | i<<1 | (j&16)>>4); 198 Buf.push_back(j<<4); 199 Buf.push_back(0); 231 200 } 232 201 233 202 // Execute command 234 vector<char> Data = Communicate( wbuf, 3*MAX_NUM_BOARDS*NUM_CHANNELS);203 vector<char> Data = Communicate(Buf); 235 204 236 if (Data.size() != 3*MAX_NUM_BOARDS*NUM_CHANNELS) return Data[0];237 238 // Evaluate returned data239 Count = 0;205 if (Data.size() != Buf.size()) return Data[0]; 206 207 // Evaluate data returned from crate 208 int Count = 0; 240 209 for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) { 241 210 Current[i][j] = Data[Count+1] + (Data[Count]&15)*256; 242 211 OC[i][j] = Data[Count] & 128; 212 Present[i][j] = Data[Count+2] & 0x70 ? false : true; 243 213 ResetHit = Data[Count+2] & 128; 244 214 Count += 3; … … 259 229 260 230 // Execute command 261 unsigned char wbuf[] = {1<<6 , SetPoint>>8, SetPoint}; 262 vector<char> Data = Communicate(wbuf, 3); 231 string Buf; 232 Buf = (((Buf + char(1<<6)) + char(SetPoint>>8)) + char(SetPoint)); 233 vector<char> Data = Communicate(Buf); 263 234 264 235 if (Data.size() == 3) { … … 273 244 274 245 275 // ***** Channel set ***** 276 int Crate::ChannelSet(int Board, int Channel, unsigned int SetPoint) { 277 278 // Check limits 279 if (SetPoint > 0x0FFF) { 280 m->PrintMessage("Error: Voltage DAC value above 0x0FFF\n"); 281 return 0; 282 } 283 if (Board > MAX_NUM_BOARDS) { 284 m->PrintMessage("Error: Board number out of range\n"); 285 return 0; 286 } 287 if (Channel > NUM_CHANNELS) { 288 m->PrintMessage("Error: Channel number out of range\n"); 289 return 0; 290 } 291 292 // Execute command 293 unsigned char wbuf[] = {3<<5 | Board<<1 | (Channel&16)>>4, Channel<<4 | SetPoint>>8, SetPoint}; 294 vector<char> Data = Communicate(wbuf, 3); 295 296 if (Data.size() == 3) { 297 DAC[Board][Channel] = SetPoint; 298 Volt[Board][Channel] = (double) SetPoint / 0xfff * 90; 246 // ***** Set channel voltages ***** 247 int Crate::SetChannels(map<unsigned int, unsigned int> V) { 248 249 string Buf; 250 251 if (V.empty()) return 1; 252 253 // Build and execute commands 254 for (map<unsigned int, unsigned int>::const_iterator it = V.begin(); it != V.end(); ++it) { 255 Buf += char(3<<5) | char(it->first/NUM_CHANNELS<<1 & 0x0f) | char((it->first%NUM_CHANNELS&16)>>4 & 1); 256 Buf += char(it->first%NUM_CHANNELS<<4) | ((it->second>>8) & 0x0f); 257 Buf += char(it->second); 258 } 259 vector<char> Data = Communicate(Buf); 260 261 // Store new voltage values of successful 262 if (Data.size() == Buf.size()) { 263 for (map<unsigned int, unsigned int>::const_iterator it = V.begin(); it != V.end(); ++it) { 264 DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second; 265 Volt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = 90.0*it->second/0x0fff; 266 } 299 267 return 1; 300 268 } 301 return Data[0]; 302 } 303 304 305 // ***** Channel set ***** 306 int Crate::SetAll() { 307 308 unsigned char wbuf[3*MAX_NUM_BOARDS*NUM_CHANNELS]; 309 double Volt = 10; 310 int Count=0; 311 for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) { 312 wbuf[Count++] = 3<<5 | i<<1 | (j&16)>>4; 313 wbuf[Count++] = j<<4 | ((int) (Volt/90*0x0fff))>>8; 314 wbuf[Count++] = (int) (Volt/90*0x0fff); 315 Volt += 0.2; 316 } 317 318 // Execute command 319 vector<char> Data = Communicate(wbuf, 3*MAX_NUM_BOARDS*NUM_CHANNELS); 320 321 if (Data.size() == 3*MAX_NUM_BOARDS*NUM_CHANNELS) { 322 //DAC[Board][Channel] = SetPoint; 323 //Volt[Board][Channel] = (double) SetPoint / 0xfff * 90; 324 return 1; 325 } 326 return Data[0]; 269 return Data[0]; 327 270 } 328 271 … … 331 274 bool Crate::Synch() { 332 275 333 unsigned char wbuf = 0;334 276 int Trial = 0; 335 277 vector<char> Data; 336 278 337 279 while(++Trial <= 3) { 338 Data = Communicate( &wbuf, 1);280 Data = Communicate(string(1, 0)); 339 281 if (Data.size() == 3) return true; 340 282 if (Data[0] == 0) break; -
fact/BIASctrl/Crate.h
r10052 r10059 10 10 #include <string> 11 11 #include <vector> 12 #include <map> 12 13 13 14 #include "dis.hxx" … … 27 28 DimService *NameService; 28 29 29 std::vector<char> Communicate( unsigned char*, int);30 std::vector<char> Communicate(std::string); 30 31 void ClearVoltageArrays(); 31 32 … … 39 40 int Current[MAX_NUM_BOARDS][NUM_CHANNELS]; 40 41 bool OC[MAX_NUM_BOARDS][NUM_CHANNELS]; 42 bool Present[MAX_NUM_BOARDS][NUM_CHANNELS]; 41 43 bool ResetHit; 42 44 bool WrapOK; … … 44 46 int ErrorCount; 45 47 46 int DAC[MAX_NUM_BOARDS][NUM_CHANNELS]; // Voltage in DAC units48 unsigned int DAC[MAX_NUM_BOARDS][NUM_CHANNELS]; // Voltage in DAC units 47 49 double Volt[MAX_NUM_BOARDS][NUM_CHANNELS]; // Voltage in Volt 48 50 int CurrentOffset[MAX_NUM_BOARDS][NUM_CHANNELS]; // Offset for current measurement … … 50 52 bool InitOK; 51 53 52 int Set All();54 int SetChannels(std::map<unsigned int, unsigned int>); 53 55 int ReadAll(); 54 56 int SystemReset(); 55 int ReadChannel(unsigned int, unsigned int);56 57 int GlobalSet(unsigned int); 57 int ChannelSet(int, int, unsigned int);58 58 bool Synch(); 59 59 bool CurrentCalib(double); -
fact/BIASctrl/History.txt
r10052 r10059 2 2 program 'hvcontrol' (revision 9852). 3 3 20/8/2010 Removed the possibility to set DAC values. 4 17/11/2010 Added possibility for bulk transfers (ReadAll(), SetAll()) 4 17/11/2010 Added possibility for bulk transfers (ReadAll(), SetChannels()) 5 24/11/2010 Ramping for many channels possible with bulk transfers -
fact/BIASctrl/User.cc
r10052 r10059 161 161 double Double; 162 162 struct Range Crt, Chan; 163 163 vector< map<unsigned int, unsigned int> > Voltages (Crates.size()); 164 164 165 // Loop over all parameters 165 for (unsigned int n=1; n < Parameter.size()-1; n+ +) {166 for (unsigned int n=1; n < Parameter.size()-1; n+=2) { 166 167 167 168 // Extract channel identification … … 197 198 continue; 198 199 } 199 200 200 201 // Loop over given crates and channels 201 202 for (int i=Crt.Min; i<=Crt.Max; i++) for (int j=Chan.Min; j<=Chan.Max; j++) { … … 211 212 else DACValue = (unsigned int) (Double/90*0x0fff); 212 213 213 // Set new voltage 214 if (!RampVoltage(DACValue, i, B, C)) Errors++; 215 214 Voltages[i][j] = DACValue; 216 215 } // Channels 217 216 } // Loop over command argument 218 217 219 // Update DIM service 220 for (unsigned int i=0; i<Crates.size(); i++) Crates[i]->BiasVolt->updateService(); 221 222 if (Errors > 0) PrintMessage("Errors on %d channel(s) occurred\n", Errors); 218 // Ramp voltages and update DIM services 219 for (unsigned int i=0; i<Voltages.size(); i++) { 220 Errors += RampVoltages(i, Voltages[i]); 221 Crates[i]->BiasVolt->updateService(); 222 } 223 224 if (Errors > 0) Message(ERROR, "%d errors occurred from SetChannels()", Errors); 223 225 } 224 226 … … 232 234 unsigned int DACValue, NBoards = 0; 233 235 FILE *File; 236 map<unsigned int, unsigned int> Voltages; 234 237 235 238 // Open file … … 245 248 PrintMessage("Found bias settings for board %s (#%d)\n\r", Crates[Crate]->Name, Crate); 246 249 250 Voltages.clear(); 247 251 Board = 0; Channel = 0; 248 252 while (fscanf(File, "%u", &DACValue)==1 && Board<MAX_NUM_BOARDS) { 253 Voltages[Board*NUM_CHANNELS+Channel] = DACValue; 254 249 255 // Ramp channel to new voltage 250 if (!RampVoltage(DACValue, Crate, Board, Channel)) {256 /*if (!RampVoltage(DACValue, Crate, Board, Channel)) { 251 257 Errors++; 252 258 PrintMessage("Error: Could not ramp board %d, channel %d\n", Board, Channel); … … 255 261 PrintMessage("Ramped board %d, channel %d to %u (%.2f V) \r", 256 262 Board, Channel, DACValue, (double) DACValue/0x0fff*90); 257 } 263 }*/ 258 264 259 265 if(++Channel == NUM_CHANNELS) { … … 262 268 } 263 269 } 270 271 // Ramp channels 272 Errors += RampVoltages(Crate, Voltages); 264 273 265 274 // Update DIM service … … 278 287 else if (Errors == 0) PrintMessage("Success: Read bias settings for all connected crates\n"); 279 288 280 if (Errors != 0) PrintMessage("Warning: Errors on %d channel(s) occurred\n", Errors);289 if (Errors != 0) PrintMessage("Warning: %d error(s) occurred\n", Errors); 281 290 282 291 if (fclose(File) != 0) PrintMessage("Error: Could not close file '%s'\n", Parameter[1].c_str()); … … 409 418 for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) { 410 419 if (j%12 == 0) PrintMessage("\n%3.1d: ", j); 411 if (Parameter.size() == 1) PrintMessage("%#5.2f ",Crates[i]->Volt[j/NUM_CHANNELS][j%NUM_CHANNELS]); 420 if (!Crates[i]->Present[j/NUM_CHANNELS][j%NUM_CHANNELS]) PrintMessage(" - "); 421 else if (Parameter.size() == 1) PrintMessage("%#5.2f ",Crates[i]->Volt[j/NUM_CHANNELS][j%NUM_CHANNELS]); 412 422 else if (Match(Parameter[1], "dac")) PrintMessage("%5d ", Crates[i]->DAC[j/NUM_CHANNELS][j%NUM_CHANNELS]); 413 423 else PrintMessage("%#5.2f %s ", (Crates[i]->Current[j/NUM_CHANNELS][j%NUM_CHANNELS]-Crates[i]->CurrentOffset[j/NUM_CHANNELS][j%NUM_CHANNELS])*1.2, Crates[i]->OC[j/NUM_CHANNELS][j%NUM_CHANNELS] ? "OC":""); … … 474 484 // Ramp to new voltage with maximum step size given in fMaxDiff 475 485 // No ramping when decreasing voltage 476 bool User::RampVoltage(unsigned int Target, int Crate, int Board, int Channel) { 477 478 while (Crates[Crate]->DAC[Board][Channel] != (int) Target) { 479 int Diff = Target - Crates[Crate]->DAC[Board][Channel]; 480 if (Diff > (int) fMaxDiff) Diff = fMaxDiff; 481 482 if (Crates[Crate]->ChannelSet(Board, Channel, Crates[Crate]->DAC[Board][Channel]+Diff) != 1) { 483 Message(ERROR, "Could not set bias of crate %d, board %d, channel %d. Skipping channel\n", Crate, Board, Channel); 484 return false; 485 } 486 } 487 488 return true; 486 unsigned int User::RampVoltages(int Crate, map<unsigned int, unsigned int> Voltages) { 487 488 map<unsigned int, unsigned int> Target; 489 unsigned int Errors = 0; 490 491 // Ramp until all channels at desired value 492 while (!Voltages.empty()) { 493 // Remove channels already at target 494 for (map<unsigned int, unsigned int>::iterator it = Voltages.begin(); it != Voltages.end(); ++it) { 495 if (Crates[Crate]->DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] == it->second) Voltages.erase(it); 496 } 497 498 // Limit voltage changes to fMaxDiff 499 Target = Voltages; 500 for (map<unsigned int, unsigned int>::iterator it = Target.begin(); it != Target.end(); ++it) { 501 if (Crates[Crate]->DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] + fMaxDiff/2 < it->second) { 502 it->second = Crates[Crate]->DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] + fMaxDiff/2; 503 } 504 } 505 506 // Set channels to next target and wait 10 ms 507 if (Crates[Crate]->SetChannels(Target) != 1) Errors++; 508 usleep(10000); 509 } 510 511 return Errors; 489 512 } 490 513 … … 522 545 } 523 546 547 map<unsigned int, unsigned int> Voltages; 548 524 549 for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) { 525 550 if (Crates[i]->OC[j/NUM_CHANNELS][j%NUM_CHANNELS]) { 526 551 Message(WARN, "Overcurrent on crate %d, board %d, channel %d, setting voltage to zero", i, j/NUM_CHANNELS, j%NUM_CHANNELS); 527 Crates[i]->ChannelSet(j/NUM_CHANNELS, j%NUM_CHANNELS, 0);528 Crates[i]->SystemReset();552 Voltages[j] = 0; 553 //Crates[i]->ChannelSet(j/NUM_CHANNELS, j%NUM_CHANNELS, 0); 529 554 } 530 555 } 556 if (!Voltages.empty()) { 557 Crates[i]->SetChannels(Voltages); 558 Crates[i]->SystemReset(); 559 } 531 560 } // for 532 561 -
fact/BIASctrl/User.h
r10052 r10059 54 54 55 55 void PrintMessage(const char *, ...); 56 bool RampVoltage(unsigned int, int, int, int);56 unsigned int RampVoltages(int, std::map<unsigned int, unsigned int>); 57 57 void Monitor(); 58 58 static void LaunchMonitor(User *);
Note:
See TracChangeset
for help on using the changeset viewer.