Changeset 11852 for trunk/FACT++
- Timestamp:
- 08/09/11 00:03:13 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/biasctrl.cc
r11775 r11852 25 25 class ConnectionBias : public ConnectionUSB 26 26 { 27 vector< char> fBuffer;27 vector<uint8_t> fBuffer; 28 28 29 29 bool fIsVerbose; … … 38 38 enum Command_t 39 39 { 40 kCmdReset = 0, 41 kCmdRead = 1, 42 kCmdWrite = 3 40 kCmdReset = 0, 41 kCmdRead = 1, 42 kCmdGlobalSet = 2, 43 kCmdChannelSet = 3, 44 kCmdPrint = 4 43 45 }; 44 45 46 46 47 // Resistance in Ohm for voltage correction … … 49 50 protected: 50 51 51 vector<uint16_t> fVolt; // Voltage in DAC units 52 vector<uint16_t> fVolt; // Voltage in DAC units (12bit = 90V) 52 53 vector<uint16_t> fRefVolt; 53 54 54 vector<uint16_t> fCurrent; // Current in ADC units 55 vector<uint16_t> fRefCurrent; 56 57 vector<bool> fOC; 55 vector<int16_t> fCurrent; // Current in ADC units (12bit = 5mA) 56 vector<int16_t> fRefCurrent; 57 58 58 vector<bool> fPresent; 59 59 60 bool fResetHit; 60 int fWrapCounter; 61 61 62 62 63 virtual void UpdateA() 63 64 { 64 if (!fIsVerbose)65 return;66 67 for (int c=0; c<kNumChannels; c++)68 {69 Out() << setw(2) << c << ":";70 for (int b=0; b<kNumBoards; b++)71 Out() << " " << setprecision(2) << fixed << setw(5) << fCurrent[b+c*kNumBoards];72 Out() << endl;73 }74 65 } 75 66 76 67 private: 77 void HandleReceivedData(const bs::error_code& err, size_t bytes_received, int /*type*/) 78 { 68 void HandleReceivedData(const bs::error_code& err, size_t bytes_received, int type) 69 { 70 if (type==kCmdPrint && bytes_received==0 && !err) 71 { 72 Print(); 73 return; 74 } 75 79 76 // Do not schedule a new read if the connection failed. 80 77 if (bytes_received==0 || err) … … 106 103 if (fIsVerbose) 107 104 { 108 Out() << endl << kBold << "Data received:" << endl; 109 Out() << Converter::GetHex<uint8_t>(fBuffer, 32) << endl; 110 } 111 112 int wrapcnt = -1; 113 114 // === Check/update all wrap counter === 115 for (unsigned int i=0; i<fBuffer.size(); i += 3) 116 { 117 const int old = wrapcnt; 118 wrapcnt = (fBuffer[i]>>4)&7; 119 120 if (wrapcnt==-1 || (old+1)%8 == wrapcnt) 121 continue; 122 123 Error("WrapCnt wrong"); 124 // Error receiving proper answer! 125 return; 126 } 127 128 // Success with received answer 129 130 if (fBuffer.size()!=kNumChannels*3) 131 return; 132 133 /* 134 data[0] = (cmd<<5) | (board<<1) | (((channel&16)>>4) & 1); 135 data[1] = (channel<<4) | (cmdval>>8); 136 data[2] = val&0xff; 137 */ 138 139 // ################## Read all channels status ################## 140 141 // Evaluate data returned from crate 142 for (int i=0; i<kNumChannels; i++) 143 { 144 fOC[i] = fBuffer[i*3]&0x80; 145 fCurrent[i] = fBuffer[i*3+1] | ((fBuffer[i*3]&0xf)<<8); 146 fPresent[i] = fBuffer[i*3+2]&0x70 ? false : true; 147 148 // FIXME FIXME FIXME 149 fResetHit = fBuffer[i*3+2] & 0x80; 150 151 if (i==2*kNumChannelsPerBoard+19) 152 fOC[i] = false; 153 } 154 155 UpdateA(); 156 } 157 158 void HandleTransmittedData(size_t n) 159 { 160 fBuffer.resize(n); 161 AsyncRead(ba::buffer(fBuffer)); 162 AsyncWait(fInTimeout, 50, &ConnectionUSB::HandleReadTimeout); 105 //Out() << endl << kBold << "Data received (size=" << bytes_received << "):" << endl; 106 //Out() << Converter::GetHex<uint8_t>(fBuffer, 32) << endl; 107 // FIXME: Check why more is printed than expected 108 } 109 110 const uint16_t command = type&0xf; 111 const uint16_t id = type>>4; 112 const uint16_t status = (fBuffer[0]>>7)&1; 113 const uint16_t wrap = (fBuffer[0]>>4)&7; 114 const uint16_t ddd = ((uint16_t(fBuffer[0])&0xf)<<8) | fBuffer[1]; 115 const uint16_t error = (fBuffer[2]>>4)&0xf; 116 const uint16_t board = fBuffer[2]&0xf; 117 118 if (fWrapCounter>=0 && (fWrapCounter+1)%8 != wrap) 119 { 120 Error("Corrupted answer (wrap counter not as it ought to be."); 121 return; 122 } 123 fWrapCounter = wrap; 124 125 if (error==0x8) // No device 126 { 127 ostringstream out; 128 out << "HV down requested!"; 129 Fatal(out); 130 131 GlobalSetDac(0); 132 133 // Resynchronize input and output 134 // SystemReset and status request 135 PostClose(true); 136 137 return; 138 } 139 140 if (command==kCmdReset) 141 { 142 if (status==0 && ddd==0 && error==0 && board==0) 143 { 144 Message("Reset successfully executed."); 145 return; 146 } 147 148 Warn("Answer to 'reset' command contains unexpected data."); 149 return; 150 } 151 152 if (command==kCmdGlobalSet) 153 { 154 if (status==0 && ddd==0 && error==0 && board==0) 155 { 156 Message("GlobalSet successfully executed."); 157 return; 158 } 159 160 Warn("Answer to 'global set' command contains unexpected data."); 161 return; 162 } 163 164 if (command==kCmdRead || command==kCmdChannelSet) 165 { 166 if (error==0x7 || error==0xf) 167 { 168 fPresent[board] = false; 169 fCurrent[id] = 0x8000; 170 return; 171 } 172 173 if (board!=id/kNumChannelsPerBoard) 174 { 175 ostringstream out; 176 out << "Talked to board " << id/kNumChannelsPerBoard << " but board " << board << " answered."; 177 Error(out); 178 return; 179 } 180 181 fCurrent[id] = status ? -ddd : ddd; 182 fPresent[board] = true; 183 184 UpdateA(); 185 186 return; 187 } 163 188 } 164 189 … … 166 191 void ConnectionEstablished() 167 192 { 193 fWrapCounter = -1; 194 fBuffer.resize(3); 195 196 SystemReset(); 197 ReadAllChannelsStatus(); 168 198 } 169 199 … … 181 211 PostClose(); 182 212 return; 183 184 213 } 185 214 … … 203 232 } 204 233 205 206 void SystemReset()207 {208 PostMessage(GetCmd(0, kCmdReset));209 }210 211 234 vector<char> GetCmd(uint16_t id, Command_t cmd, uint16_t dac=0) 212 235 { … … 239 262 void GlobalSetDac(uint16_t dac) 240 263 { 241 PostMessage(GetCmd(0, kCmdWrite, dac)); 242 /* 243 // On success 244 if (fBuffer.size() == 3) 245 { 246 for (int i=0; i<MAX_NUM_BOARDS; i++) 247 for (int j=0; j<NUM_CHANNELS; j++) 248 { 249 DAC[i][j] = SetPoint; 250 Volt[i][j] = Voltage; 251 RefVolt[i][j] = Voltage; 252 } 253 } 254 */ 255 } 256 264 PostMessage(GetCmd(0, kCmdGlobalSet, dac)); 265 AsyncRead(ba::buffer(fBuffer), kCmdGlobalSet); 266 } 267 268 /* 257 269 void SetChannels(const map<uint16_t, uint16_t> &vals) 258 270 { 259 271 if (vals.empty()) 260 272 return; 261 262 vector<char> data;263 273 264 274 // Build and execute commands … … 266 276 it!=vals.end(); it++) 267 277 { 268 //const uint16_t dac = it->second/90.0*0xfff;269 270 278 // If DAC value unchanged, do not send command 271 279 if (fVolt[it->first] == it->second) 272 280 continue; 273 281 274 const vector<char> cmd = GetCmd(it->first, kCmdWrite, it->second); 275 data.insert(data.end(), cmd.begin(), cmd.end()); 276 } 277 278 PostMessage(data); 279 280 /* 281 // On success 282 if (Data.size() == Buf.size()) 283 { 284 for (map<unsigned int, double>::const_iterator it = V.begin(); it != V.end(); ++it) { 285 DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = (unsigned int) (it->second/90.0*0x0fff); 286 Volt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second; 287 RefVolt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second; 288 } 289 */ 290 } 282 const vector<char> cmd = GetCmd(it->first, kCmdChannelSet, it->second); 283 PostMessage(cmd); 284 AsyncRead(ba::buffer(fBuffer), kCmdChannelSet|(it->first<<4)); 285 } 286 }*/ 291 287 292 288 /* … … 314 310 fCurrent(kNumChannels), 315 311 fRefCurrent(kNumChannels), 316 fOC(kNumChannels), 317 fPresent(kNumChannels) 312 fPresent(kNumBoards) 318 313 { 319 314 SetLogStream(&imp); … … 322 317 bool GlobalSet(double voltage) 323 318 { 324 if (voltage<0 || voltage>90) 319 const uint16_t dac = voltage*4096/90; 320 if (dac>0xfff) 325 321 return false; 326 322 327 GlobalSetDac( voltage/90.0*0xfff);323 GlobalSetDac(dac); 328 324 329 325 return true; 330 326 } 331 327 328 bool ChannelSet(uint16_t ch, double voltage) 329 { 330 const uint16_t dac = voltage*4096/90; 331 if (dac>0xfff) 332 return false; 333 334 if (ch>=kNumChannels) 335 return false; 336 337 PostMessage(GetCmd(ch, kCmdChannelSet, dac)); 338 AsyncRead(ba::buffer(fBuffer), kCmdChannelSet|(ch<<4)); 339 340 return true; 341 } 342 332 343 void ReadAllChannelsStatus() 333 344 { 334 vector<char> data; 335 data.reserve(kNumChannels*3); 345 Message("Requesting full system status."); 336 346 337 347 // Prepare command to read all channels 338 348 for (int i=0; i<kNumChannels; i++) 339 { 340 const vector<char> cmd = GetCmd(i, kCmdRead); 341 data.insert(data.end(), cmd.begin(), cmd.end()); 342 } 343 344 PostMessage(data); 349 { 350 const vector<char> cmd = GetCmd(i, kCmdRead); 351 PostMessage(cmd); 352 AsyncRead(ba::buffer(fBuffer), kCmdRead|(i<<4)); 353 } 354 355 //vector<char> buf; 356 //AsyncRead(ba::buffer(buf), kCmdPrint); 345 357 } 346 358 … … 348 360 void AdaptVoltages() 349 361 { 350 map<uint16_t, uint16_t> values;351 352 362 for (int i=0; i<kNumChannels; i++) 353 363 { 354 if (fRefVolt[i]==0 )364 if (fRefVolt[i]==0 || fCurrent[i]<0 || fRefCurrent[i]<0) 355 365 continue; 356 366 357 // Calculate difference and convert ADC units to Amps 358 const double diffcur = (fRefCurrent[i]-fCurrent[i])*1.22; 367 // Calculate difference and convert ADC units to Amp 368 // const double diffcur = (fRefCurrent[i]-fCurrent[i])*5000/4096 369 //const int32_t diffcur = int32_t(fRefCurrent[i]-fCurrent[i])*5000; 370 const int32_t diffvolt = (fRefCurrent[i]-fCurrent[i])*5; 359 371 360 372 // Calculate voltage difference 361 const double diffvolt = diffcur*RESISTOR/1e6; 373 // #define RESISTOR 1000 // Ohm 374 //const double diffvolt = diffcur*RESISTOR/1e6; 362 375 363 376 // Calculate new vlaue by onverting voltage difference to DAC units 364 const int32_t dac = fRefVolt[i] + diffvolt/90.0*0xfff; 365 366 if (dac<0 || dac>0xfff) 377 //const int32_t dac = fRefVolt[i] + diffvolt*4096/90.0; 378 int32_t dac = fRefVolt[i] + diffvolt/90; 379 380 if (dac<0) 381 dac = 0; 382 if (dac>0xfff) 383 dac = 0xfff; 384 385 if (fVolt[i] == dac) 367 386 continue; 368 387 369 values[i] = fRefVolt[i] + dac; 370 } 371 372 SetChannels(values); 373 374 /* 375 static int LastUpdate = 0; 376 if (time(NULL)-LastUpdate > 5) 377 { 378 LastUpdate = time(NULL); 379 UpdateDIM(); 380 }*/ 388 PostMessage(GetCmd(i, kCmdChannelSet, dac)); 389 AsyncRead(ba::buffer(fBuffer), kCmdChannelSet|(i<<4)); 390 } 391 } 392 393 void SystemReset() 394 { 395 Message("Sending system reset."); 396 PostMessage(GetCmd(0, kCmdReset)); 397 AsyncRead(ba::buffer(fBuffer), kCmdReset); 381 398 } 382 399 … … 389 406 { 390 407 fIsVerbose = b; 408 } 409 410 void PrintLine(int b, int ch) 411 { 412 Out() << setw(2) << b << "|"; 413 414 for (int c=ch; c<ch+8; c++) 415 { 416 const int id = c+kNumChannelsPerBoard*b; 417 Out() << " " << setw(7) << abs(fCurrent[id])*5000/4096.; 418 if (fCurrent[id]<0) 419 Out() << "!"; 420 else 421 Out() << " "; 422 } 423 Out() << endl; 424 425 } 426 void Print() 427 { 428 Out() << dec << setprecision(2) << fixed; 429 for (int b=0; b<kNumBoards; b++) 430 { 431 if (!fPresent[b]) 432 { 433 Out() << setw(2) << b << "-" << endl; 434 continue; 435 } 436 437 PrintLine(b, 0); 438 PrintLine(b, 8); 439 PrintLine(b, 16); 440 PrintLine(b, 24); 441 } 391 442 } 392 443 }; … … 469 520 if (!fBias.GlobalSet(evt.GetFloat())) 470 521 T::Error("Supplied voltage out of range (0-90)"); 522 523 return T::GetCurrentState(); 524 } 525 526 int SetChannel(const EventImp &evt) 527 { 528 if (!CheckEventSize(evt.GetSize(), "SetChannel", 6)) 529 return false; 530 531 if (!fBias.ChannelSet(evt.GetUShort(), evt.Get<float>(2))) 532 T::Error("Value out of range"); 471 533 472 534 return T::GetCurrentState(); … … 565 627 566 628 AddEvent("REQUEST_STATUS", kStateConnected) 567 (Wrap (bind(&ConnectionBias::ReadAllChannelsStatus, &fBias)))629 (Wrapper(bind(&ConnectionBias::ReadAllChannelsStatus, &fBias))) 568 630 (""); 569 631 570 AddEvent("SET_GLOBAL ", "F:1", kStateConnected)632 AddEvent("SET_GLOBAL_VOLTAGE", "F:1", kStateConnected) 571 633 (bind(&StateMachineBias::SetGlobal, this, _1)) 572 634 (""); 573 635 636 AddEvent("SET_CHANNEL_VOLTAGE", "S:1;F:1", kStateConnected) 637 (bind(&StateMachineBias::SetChannel, this, _1)) 638 (""); 639 574 640 AddEvent("RESET", kStateConnected) 575 (Wrap (bind(&ConnectionBias::SystemReset, &fBias)))641 (Wrapper(bind(&ConnectionBias::SystemReset, &fBias))) 576 642 (""); 577 643 578 644 AddEvent("SET_REFERENCE_CURRENT", kStateConnected) 579 (Wrap (bind(&ConnectionBias::SetReferenceCurrent, &fBias)))645 (Wrapper(bind(&ConnectionBias::SetReferenceCurrent, &fBias))) 580 646 (""); 581 647 582 648 AddEvent("ADAPT_VOLTAGES", kStateConnected) 583 (Wrap (bind(&ConnectionBias::AdaptVoltages, &fBias)))649 (Wrapper(bind(&ConnectionBias::AdaptVoltages, &fBias))) 584 650 (""); 585 } 586 587 void SetEndpoint(const string &url) 588 { 589 fBias.SetEndpoint(url); 651 652 AddEvent("PRINT", kStateConnected) 653 (Wrapper(bind(&ConnectionBias::Print, &fBias))) 654 (""); 590 655 } 591 656 592 657 int EvalOptions(Configuration &conf) 593 658 { 594 SetEndpoint(conf.Get<string>("addr"));595 596 659 fBias.SetVerbose(!conf.Get<bool>("quiet")); 660 661 fBias.SetEndpoint(conf.Get<string>("dev")); 662 T::Message("Setting device to "+fBias.URL()); 597 663 598 664 fBias.Connect(); … … 617 683 control.add_options() 618 684 ("no-dim,d", po_bool(), "Disable dim services") 619 (" addr,a", var<string>("ttysS0"), "Device address of USB port to bias-power supply")685 ("dev", var<string>("FTE00FOH"), "Device address of USB port to bias-power supply") 620 686 ("quiet,q", po_bool(), "Disable printing contents of all received messages (except dynamic data) in clear text.") 621 687 ;
Note:
See TracChangeset
for help on using the changeset viewer.