3 #include <boost/bind.hpp> 20 namespace ba = boost::asio;
21 namespace bs = boost::system;
22 namespace dummy = ba::placeholders;
108 vector<char>
data(3);
119 data[0] = (cmd<<5) | (board<<1) | (((channel&16)>>4) & 1);
120 data[1] = (channel<<4) | (dac>>8);
131 return GetCmd(board, channel, cmd, dac);
136 if (received==expected)
140 str << msg <<
": Expected " << expected <<
" bytes in answer, but got " << received << endl;
146 bool EvalAnswer(
const uint8_t *answer, uint16_t
id,
int command)
150 const uint16_t status = (answer[0]>>7)&1;
151 const uint16_t wrap = (answer[0]>>4)&7;
152 const uint16_t ddd = ((uint16_t(answer[0])&0xf)<<8) | answer[1];
153 const uint16_t error = (answer[2]>>4)&0xf;
154 const uint16_t board = answer[2]&0xf;
171 if ((fWrapCounter+1)%8 != wrap)
174 msg <<
"Corrupted answer (id=" <<
id <<
"): received wrap counter " << wrap <<
" doesn't match last one " << fWrapCounter <<
" ";
175 msg <<
" (fSendCounter=" << fSendCounter <<
")";
186 msg << hex << setfill(
'0');
187 msg <<
"Initial answer received: 0x";
188 msg << setw(2) << (int)answer[2];
189 msg << setw(2) << (int)answer[1];
190 msg << setw(2) << (int)answer[0];
193 if (status!=0 || ddd!=0 || error!=0 || board!=0)
195 Warn(
"Initial answer doesn't seem to be a reset as naively expected.");
206 msg <<
"Setting fSendCounter to " << wrap;
214 Message(
"Reset button on crate pressed!");
221 if (status==0 && ddd==0 && error==0 && board==0)
223 Message(
"Reset successfully executed.");
227 Warn(
"Answer to 'reset' command contains unexpected data.");
233 if (status==0 && ddd==0 && error==0 && board==0)
236 fDacActual[
i] = fGlobalDacCmd;
243 Warn(
"Answer to 'global set' command contains unexpected data.");
250 const int cmd = command&3;
257 out <<
"Talked to board " <<
id/
kNumChannelsPerBoard <<
", but got answer from board " << board <<
" (fSendCounter=" << fSendCounter <<
")";
263 if (error==0x7 || error==0xf)
265 fPresent[board] =
false;
266 fCurrent[
id] = 0x8000;
273 fCurrent[
id] = status ? -(ddd==0?1:ddd) : ddd;
274 fPresent[board] =
true;
276 if (!fEmergencyShutdown)
280 Warn(
"OverCurrent detected.");
281 fEmergencyShutdown =
true;
284 if (fEmergencyLimit>0 && fCurrent[
id]>fEmergencyLimit && !fEmergencyShutdown)
286 Warn(
"Emergency limit exceeded.");
287 fEmergencyShutdown =
true;
290 if (fEmergencyShutdown)
292 Error(
"Emergency ramp down initiated.");
300 fDacActual[
id] = fDacCommand[
id];
313 if (now-fLastConnect>boost::posix_time::seconds(60))
317 msg <<
"Automatic reconnect in " << fReconnectDelay <<
"s after being connected for ";
318 msg << (now-fLastConnect).seconds() <<
"s";
321 CloseImp(fReconnectDelay);
322 fReconnectDelay *= 2;
325 void HandleReceivedData(
const vector<uint8_t> &buf,
size_t bytes_received,
int command,
int send_counter)
328 ofstream fout(
"received.txt", ios::app);
329 fout <<
Time() <<
": ";
330 for (
unsigned int i=0;
i<bytes_received;
i++)
331 fout << hex << setfill(
'0') << setw(2) << (uint16_t)buf[
i];
338 Out() << endl <<
kBold << dec <<
"Data received (size=" << bytes_received <<
"):" << endl;
339 Out() <<
" Command=" << command <<
" fWrapCounter=" << fWrapCounter <<
" fSendCounter=" << fSendCounter <<
" fIsInitializing=" << fIsInitializing <<
" fIsRamping=" << fIsRamping;
340 Out() << hex << setfill(
'0');
342 for (
size_t i=0;
i<bytes_received/3;
i++)
345 Out() <<
'\n' << setw(2) << bytes_received/24 <<
"| ";
347 Out() << setw(2) << uint16_t(buf[
i*3+2]);
348 Out() << setw(2) << uint16_t(buf[
i*3+1]);
349 Out() << setw(2) << uint16_t(buf[
i*3+0]) <<
" ";
354 const int cmd = command&0xf;
357 if ((cmd==
kSynchronize && !CheckMessageLength(bytes_received, 3,
"Synchronization")) ||
358 (cmd==
kCmdReset && !CheckMessageLength(bytes_received, 3,
"CmdReset")) ||
361 (cmd==
kExpertChannelSet && !CheckMessageLength(bytes_received, 3,
"CmdExpertChannelSet")))
368 for (
size_t i=0;
i<bytes_received/3;
i++)
370 if (!EvalAnswer(buf.data(),
i, command))
379 Message(
"Stream successfully synchronized.");
391 if (send_counter%8 != fWrapCounter)
394 msg <<
"Corrupted answer: received wrap counter " << fWrapCounter <<
" is not send counter " << send_counter <<
"%8.";
409 Message(
"Reset command successfully answered...");
417 fUpdateTimer.cancel();
420 ReadAllChannels(
true);
423 Message(
"...restarting automatic readout.");
436 ScheduleUpdate(fUpdateTime);
450 if (!fEmergencyShutdown)
452 Warn(
"OverCurrent detected - emergency ramp down initiated.");
455 fEmergencyShutdown =
true;
474 void HandleReceivedData(
const bs::error_code& err,
size_t bytes_received,
int command,
int send_counter)
477 if (bytes_received==0 || err)
479 if (err==ba::error::eof)
482 msg <<
"Connection closed by remote host (BIAS, fSendCounter=" << fSendCounter <<
")";
488 if (err && err!=ba::error::eof &&
489 err!=ba::error::basic_errors::not_connected &&
490 err!=ba::error::basic_errors::operation_aborted)
493 str <<
"Reading from " << URL() <<
": " << err.message() <<
" (" << err <<
")";
502 if (bytes_received%3)
504 Error(
"Number of received bytes not a multiple of 3, can't read data.");
530 switch (command&0xff)
538 HandleReceivedData(fBuffer, bytes_received, command, send_counter);
539 fWaitingForAnswer = -1;
543 HandleReceivedData(fBufferRamp, bytes_received, command, send_counter);
547 HandleReceivedData(fBufferUpdate, bytes_received, command, send_counter);
556 if (error==ba::error::basic_errors::operation_aborted)
558 if (fIsInitializing==1)
559 Warn(
"Synchronization aborted...");
567 str <<
"Synchronization timer: " << error.message() <<
" (" << error <<
")";
576 Warn(
"Synchronization in progress, but disconnected.");
581 msg <<
"Synchronization time expired (" << counter <<
")";
586 PostMessage(
"\0", 1);
590 Error(
"Synchronization attempt timed out.");
595 ScheduleSync(counter+1);
599 Info(
"Synchronisation successfull.");
604 fSyncTimer.expires_from_now(boost::posix_time::milliseconds(fSyncTime));
629 fLastConnect =
Time();
633 PostMessage(
"\0", 1);
645 if (error==ba::error::basic_errors::operation_aborted)
647 Warn(
"Update timer aborted...");
655 str <<
"Update timer: " << error.message() <<
" (" << error <<
")";
665 if (fUpdateTime==0 && fIsInitializing!=2)
669 ScheduleUpdate(fUpdateTime);
671 ReadAllChannels(
true);
678 fUpdateTimer.expires_from_now(boost::posix_time::milliseconds(millisec));
686 Out() << setw(2) << b <<
"|";
688 for (
int c=ch; c<ch+4; c++)
691 Out() <<
" " << setw(4) << int32_t(dac[
id])<<
"/"<<fDacActual[
id] <<
":" << setw(5) << ConvertDacToVolt(
id, fDacTarget[
id]);
698 Out() << dec << setprecision(2) << fixed << setfill(
' ');
703 Out() << setw(2) << b <<
"-" << endl;
707 PrintLineCmdDac(b, 0, dac);
708 PrintLineCmdDac(b, 4, dac);
709 PrintLineCmdDac(b, 8, dac);
710 PrintLineCmdDac(b, 12, dac);
711 PrintLineCmdDac(b, 16, dac);
712 PrintLineCmdDac(b, 20, dac);
713 PrintLineCmdDac(b, 24, dac);
714 PrintLineCmdDac(b, 28, dac);
722 PrintCommandDac(dac);
733 data.insert(data.end(), cmd.begin(), cmd.end());
735 fDacCommand[ch] = dac[ch];
741 AsyncRead(
ba::buffer(special ? fBuffer : fBufferRamp, kNumChannels*3),
750 if (fDacTarget[ch]>fDacActual[ch])
751 return fDacActual[ch]+fRampStep>fDacTarget[ch] ? fDacTarget[ch] : fDacActual[ch]+fRampStep;
753 if (fDacTarget[ch]<fDacActual[ch])
754 return fDacActual[ch]-fRampStep<fDacTarget[ch] ? fDacTarget[ch] : fDacActual[ch]-fRampStep;
756 return fDacActual[ch];
763 Warn(
"Ramping step time not yet set... ramping not started.");
768 Warn(
"Ramping step not yet set... ramping not started.");
774 bool identical =
true;
777 dac[ch] = RampOneStep(ch);
784 Info(
"Ramping: target values reached.");
788 if (fWaitingForAnswer<0)
795 msg <<
"RampOneStep while waiting for answer to last command (id=" << fWaitingForAnswer <<
")... ramp step delayed.";
805 if (error==ba::error::basic_errors::operation_aborted)
807 Warn(
"Ramping aborted...");
815 str <<
"Ramping timer: " << error.message() <<
" (" << error <<
")";
825 Warn(
"Ramping in progress, but disconnected.");
832 Error(
"Ramp handler called although no ramping in progress.");
840 if (fRampTimer.expires_at() > ba::deadline_timer::traits_type::now())
843 fIsRamping = RampOneStep();
848 fRampTimer.expires_from_now(boost::posix_time::milliseconds(fRampTime));
854 fSyncTimer(ioservice),
855 fRampTimer(ioservice),
856 fUpdateTimer(ioservice),
870 fWaitingForAnswer(-1),
873 fEmergencyShutdown(false),
896 msg <<
"CheckDac - Dac value of " << dac <<
" exceeds maximum of 4095.";
907 msg <<
"CheckChannel - Channel " << ch <<
" out of range [0;" <<
kNumChannels-1 <<
"].";
914 if (volt>fVoltageMaxAbs)
917 msg <<
"CheckChannelVoltage - Set voltage " << volt <<
"V of channel " << ch <<
" exceeds absolute limit of " << fVoltageMaxAbs <<
"V.";
922 if (fOperationVoltage[ch]<=0)
925 if (volt>fOperationVoltage[ch]+fVoltageMaxRel)
928 msg <<
"CheckChannelVoltage - Set voltage " << volt <<
"V of channel " << ch <<
" exceeds limit of " << fVoltageMaxRel <<
"V above operation voltage " << fOperationVoltage[ch] <<
"V + limit " << fVoltageMaxRel <<
"V.";
940 if (!CheckChannel(ch))
946 fDacTarget[ch] = dac;
950 fIsRamping = RampOneStep();
958 if (!CheckDac(dac[ch]))
965 fIsRamping = RampOneStep();
972 return RampAllChannelsDac(vector<uint16_t>(
kNumChannels, dac));
979 if (fCalibrationSlope[ch]<=0)
982 const double current = (volt-fCalibrationOffset[ch])/fCalibrationSlope[ch];
983 return current<0 ? 0 : nearbyint(current*4096000);
988 if (fCalibrationSlope[ch]<=0)
991 const double current = dac/4096000.;
992 return current*fCalibrationSlope[ch] + fCalibrationOffset[ch];
999 if (!CheckChannel(ch))
1002 if (!CheckChannelVoltage(ch, volt))
1005 const uint16_t dac = ConvertVoltToDac(ch, volt);
1006 return RampSingleChannelDac(ch, dac);
1014 if (!CheckChannelVoltage(ch, volt[ch]))
1017 dac[ch] = ConvertVoltToDac(ch, volt[ch]);
1020 return RampAllChannelsDac(dac);
1025 return RampAllChannelsVoltage(vector<float>(
kNumChannels, volt));
1101 if (fWaitingForAnswer>=0)
1104 msg <<
"OverCurrentReset - Answer on last command (id=" << fWaitingForAnswer <<
") not yet received.";
1111 Warn(
"OverCurrentReset - Ramping in progres.");
1115 vector<uint16_t> dac(fDacActual);
1121 SetAllChannels(dac,
true);
1126 if (!special && fWaitingForAnswer>=0)
1129 msg <<
"ReadAllChannels - Answer on last command (id=" << fWaitingForAnswer <<
") not yet received.";
1139 const vector<char> cmd = GetCmd(
kCmdRead, ch);
1140 data.insert(data.end(), cmd.begin(), cmd.end());
1146 AsyncRead(
ba::buffer(special ? fBufferUpdate : fBuffer, kNumChannels*3),
1153 bool SetReferences(
const vector<float> &volt,
const vector<float> &offset,
const vector<float> &slope)
1158 out <<
"SetReferences - Given vector has " << volt.size() <<
" elements - expected " <<
kNumChannels << endl;
1165 out <<
"SetReferences - Given vector has " << offset.size() <<
" elements - expected " <<
kNumChannels << endl;
1172 out <<
"SetReferences - Given vector has " << slope.size() <<
" elements - expected " <<
kNumChannels << endl;
1177 fOperationVoltage = volt;
1178 fCalibrationOffset = offset;
1179 fCalibrationSlope = slope;
1190 fRampTimer.cancel();
1193 Message(
"Ramping stopped.");
1200 Warn(
"RampStart - Ramping already in progress... ignored.");
1204 fIsRamping = RampOneStep();
1219 return fRampStep*90./4096;
1228 if (expert_mode && fWaitingForAnswer>=0)
1231 msg <<
"ExpertReset - Answer on last command (id=" << fWaitingForAnswer <<
") not yet received.";
1237 Warn(
"EXPERT MODE: Sending reset.");
1247 if (fWaitingForAnswer>=0)
1250 msg <<
"ExpertChannelSetDac - Answer on last command (id=" << fWaitingForAnswer <<
") not yet received.";
1258 fDacCommand[ch] = dac;
1261 msg <<
"EXPERT MODE: Sending 'ChannelSet' (set ch " << ch <<
" to DAC=" << dac <<
")";
1274 return ExpertChannelSetDac(ch, volt*4096/90.);
1279 if (fWaitingForAnswer>=0)
1282 msg <<
"ExpertGlobalSetDac - Answer on last command (id=" << fWaitingForAnswer <<
") not yet received.";
1290 if (fGlobalDacCmd>=0)
1292 Error(
"ExpertGlobalSetDac - Still waiting for previous answer to 'GlobalSet'");
1296 fGlobalDacCmd = dac;
1299 msg <<
"EXPERT MODE: Sending 'GlobalSet' (DAC=" << dac <<
")";
1311 return ExpertGlobalSetDac(volt*4096/90);
1328 Out() << endl <<
kBold << dec <<
'\n';
1329 Out() <<
"fWrapCounter = " << fWrapCounter <<
'\n';
1330 Out() <<
"fSendCounter = " << fSendCounter%8 <<
" (" << fSendCounter <<
")" <<
'\n';
1331 Out() <<
"fIsInitializing = " << fIsInitializing <<
'\n';
1332 Out() <<
"fIsRamping = " << fIsRamping <<
'\n';
1333 Out() <<
"Answer counter:" <<
'\n';
1334 Out() <<
" - Synchronization: " << fCounter[0] <<
'\n';
1335 Out() <<
" - Reset: " << fCounter[1] <<
'\n';
1336 Out() <<
" - Request update: " << fCounter[2] <<
'\n';
1337 Out() <<
" - Ramp step: " << fCounter[3] <<
'\n';
1338 Out() <<
" - Read: " << fCounter[4] <<
'\n';
1339 Out() <<
" - Reset channels: " << fCounter[5] <<
'\n';
1340 Out() <<
" - Global set: " << fCounter[7] <<
'\n';
1341 Out() <<
" - Channel set: " << fCounter[6] <<
'\n' << endl;
1346 Out() << setw(2) << b <<
"|";
1348 for (
int c=ch; c<ch+8; c++)
1352 Out() <<
" " << setw(7) << abs(fCurrent[
id])*5000/4096.;
1360 Out() << dec << setprecision(2) << fixed << setfill(
' ');
1365 Out() << setw(2) << b <<
"-" << endl;
1378 Out() << setw(2) << b <<
"|";
1380 for (
int c=ch; c<ch+4; c++)
1388 Out() << setw(5) << ConvertDacToVolt(
id, fDacActual[
id]) <<
'/';
1389 Out() << setw(5) << ConvertDacToVolt(
id, fDacTarget[
id]);
1396 Out() << dec << setprecision(2) << fixed << setfill(
' ');
1401 Out() << setw(2) << b <<
"-" << endl;
1418 Out() << setw(2) << b <<
"|";
1420 for (
int c=ch; c<ch+8; c++)
1423 Out() <<
" " << setw(5) << fOperationVoltage[
id];
1430 Out() << dec << setprecision(2) << fixed << setfill(
' ');
1435 Out() << setw(2) << b <<
"-" << endl;
1439 PrintLineGapd(b, 0);
1440 PrintLineGapd(b, 8);
1441 PrintLineGapd(b, 16);
1442 PrintLineGapd(b, 24);
1452 if (!IsConnected() || fIsInitializing)
1455 fUpdateTimer.cancel();
1458 ScheduleUpdate(fUpdateTime);
1473 fVoltageMaxAbs = max;
1483 fVoltageMaxRel = max;
1488 return fVoltageMaxAbs;
1493 return fVoltageMaxRel;
1504 if (fIsInitializing)
1530 fReconnectDelay = delay;
1535 fEmergencyLimit = limit;
1540 fEmergencyShutdown =
false;
1545 return fEmergencyShutdown;
1570 fDimCurrent.
Update(fCurrent);
1576 const bool rc = !memcmp(fDacActual.data(), fDacTarget.data(),
kNumChannels*2);
1587 volt[ch] = ConvertDacToVolt(ch, fDacActual[ch]);
1597 volt.insert(volt.end(), fOperationVoltage.begin(), fOperationVoltage.end());
1598 volt.insert(volt.end(), fCalibrationOffset.begin(), fCalibrationOffset.end());
1599 volt.insert(volt.end(), fCalibrationSlope.begin(), fCalibrationSlope.end());
1606 fDimCurrent(
"BIAS_CONTROL/CURRENT",
"S:416",
1607 "|I[dac]:Bias current (conversion: 5000uA/4096dac)"),
1608 fDimDac(
"BIAS_CONTROL/DAC",
"S:416;S:416",
1609 "|U[dac]:Current dac setting" 1610 "|Uref[dac]:Reference dac setting"),
1611 fDimVolt(
"BIAS_CONTROL/VOLTAGE",
"F:416",
1612 "|Uout[V]:Output voltage"),
1613 fDimGapd(
"BIAS_CONTROL/NOMINAL",
"F:416;F:416;F:416",
1614 "|Uop[V]:Nominal operation voltage at 25deg C" 1615 "|Uoff[V]:Bias crate channel calibration offsets" 1616 "|Rcal[Ohm]:Bias crate channel calibration slope")
1625 template <
class T,
class S>
1628 int Wrap(boost::function<
void()> f)
1631 return T::GetCurrentState();
1634 function<int(const EventImp &)>
Wrapper(
function<
void()> func)
1645 msg << name <<
" - Received event has " << has <<
" bytes, but expected " << size <<
".";
1662 if (!CheckEventSize(evt.
GetSize(),
"SetGlobalDac", 2))
1667 return T::GetCurrentState();
1673 if (!CheckEventSize(evt.
GetSize(),
"SetAllChannelsDac", 2*416))
1676 const uint16_t *ptr = evt.
Ptr<uint16_t>();
1678 fBias.RampAllChannelsDac(vector<uint16_t>(ptr, ptr+416));
1680 return T::GetCurrentState();
1686 if (!CheckEventSize(evt.
GetSize(),
"SetChannelDac", 4))
1689 fBias.RampSingleChannelDac(evt.
Get<uint16_t>(), evt.
Get<uint16_t>(2));
1691 return T::GetCurrentState();
1699 if (!CheckEventSize(evt.
GetSize(),
"SetChannelVolt", 6))
1702 fBias.RampSingleChannelVoltage(evt.
GetUShort(), evt.
Get<
float>(2));
1704 return T::GetCurrentState();
1710 if (!CheckEventSize(evt.
GetSize(),
"SetGlobalVolt", 4))
1713 fBias.RampAllVoltages(evt.
GetFloat());
1715 return T::GetCurrentState();
1724 const float *ptr = evt.
Ptr<
float>();
1725 fBias.RampAllChannelsVoltage(vector<float>(ptr, ptr+
kNumChannels));
1727 return T::GetCurrentState();
1770 if (!CheckEventSize(evt.
GetSize(),
"ExpertSetGlobalVolt", 4))
1773 fBias.ExpertGlobalSetVolt(evt.
GetFloat());
1775 return T::GetCurrentState();
1780 if (!CheckEventSize(evt.
GetSize(),
"ExpertSetGlobalDac", 2))
1783 fBias.ExpertGlobalSetDac(evt.
GetUShort());
1785 return T::GetCurrentState();
1790 if (!CheckEventSize(evt.
GetSize(),
"ExpertSetChannelVolt", 6))
1793 fBias.ExpertChannelSetVolt(evt.
GetUShort(), evt.
Get<
float>(2));
1795 return T::GetCurrentState();
1800 if (!CheckEventSize(evt.
GetSize(),
"ExpertSetChannelDac", 4))
1803 fBias.ExpertChannelSetDac(evt.
Get<uint16_t>(), evt.
Get<uint16_t>(2));
1805 return T::GetCurrentState();
1812 T::Warn(
"ExpertLoadMapFile - No file name given.");
1813 return T::GetCurrentState();
1818 T::Warn(
"ExpertLoadMapFile - Voltage must have been turned off.");
1819 return T::GetCurrentState();
1828 catch (
const runtime_error &e)
1830 T::Warn(
"Getting reference voltages failed: "+
string(e.what()));
1831 return T::GetCurrentState();
1836 T::Warn(
"Setting reference voltages failed.");
1837 return T::GetCurrentState();
1842 T::Info(
"Successfully loaded new mapping '"+evt.
GetString()+
"'");
1844 return T::GetCurrentState();
1851 if (!CheckEventSize(evt.
GetSize(),
"SetUpdateInterval", 4))
1854 fBias.SetUpdateInterval(evt.
Get<int32_t>()<0 ? 0 : evt.
Get<uint32_t>());
1856 return T::GetCurrentState();
1862 fBias.PostClose(-1);
1870 return T::GetCurrentState();
1876 fBias.PostClose(-1);
1880 ba::io_service::poll();
1886 fBias.SetReconnectDelay();
1889 return T::GetCurrentState();
1894 if (!CheckEventSize(evt.
GetSize(),
"SetVerbosity", 1))
1895 return T::kSM_FatalError;
1897 fBias.SetVerbose(evt.
GetBool());
1899 return T::GetCurrentState();
1904 if (!CheckEventSize(evt.
GetSize(),
"SetDummyMode", 1))
1905 return T::kSM_FatalError;
1907 fBias.SetDummyMode(evt.
GetBool());
1909 return T::GetCurrentState();
1914 if (!CheckEventSize(evt.
GetSize(),
"SetExpertMode", 1))
1915 return T::kSM_FatalError;
1920 T::Warn(
"Expert commands enabled -- please ensure that you EXACTLY know what you do. These commands can destroy the system.");
1922 return T::GetCurrentState();
1927 fBias.RampAllDacs(0);
1928 T::Info(
"Emergency shutdown initiated ["+reason+
"].");
1934 fBias.ResetEmergencyShutdown();
1935 return fBias.GetStatus();
1940 const int state = fBias.GetStatus();
1942 if (fBias.IsEmergencyShutdown())
1945 fBias.RampAllDacs(0);
1952 const bool shutdown =
1959 Shutdown(
"beginning of civil twilight");
1964 msg <<
"During next sun-rise nautical twilight will end at " << fSunRise;
1972 return T::GetCurrentState();
1983 fExpertMode(false), fSunRise(
Time().GetNextSunRise(-6))
1987 "Bias-power supply not connected via USB.");
1990 "Trying to establish USB connection to bias-power supply.");
1993 "USB connection to bias-power supply established, synchronizing USB stream.");
1996 "USB connection to bias-power supply established.");
1999 "Internal reference voltage does not match last sent voltage.");
2002 "All voltages are supposed to be switched off.");
2005 "At least one voltage is switched on and all are at reference.");
2008 "At least one channel is in over current state.");
2011 "Special (risky!) mode to directly send command to the bias-power supply.");
2014 "Voltage ramping in progress.");
2017 "Locked due to emergency shutdown, no commands accepted except UNLOCK.");
2020 T::AddEvent(
"SET_VERBOSE",
"B:1")
2022 (
"set verbosity state" 2023 "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
2025 T::AddEvent(
"ENABLE_DUMMY_MODE",
"B:1")
2027 (
"Enable dummy mode. In this mode SetAllChannels prints informations instead of sending anything to the bias crate." 2028 "|enable[bool]:disable or enable dummy mode");
2033 (
"disconnect from USB");
2036 (
"(Re)connect USB connection to Bias power supply, a new address can be given" 2037 "|tty[string]:new USB address");
2040 T::AddEvent(
"SET_UPDATE_INTERVAL",
"I:1")
2042 (
"Set the updat einterval how often the currents are requested" 2043 "|interval[ms]:Update interval in milliseconds");
2049 (
"Asynchronously request the status (current) of all channels.");
2053 (
"Set all channels in over current state to 0V and send a system reset to reset the over current flags.");
2058 (
"Set a new target value in DAC counts for a single channel. Starts ramping if necessary." 2059 "|channel[short]:Channel for which to set the target voltage [0-415]" 2060 "|voltage[dac]:Target voltage in DAC units for the given channel");
2063 (
"Set a new target value for all channels in DAC counts. Starts ramping if necessary. (This command is not realized with the GLOBAL SET command.)" 2064 "|voltage[dac]:Global target voltage in DAC counts.");
2067 (
"Set a new target value for all channels in DAC counts. Starts ramping if necessary." 2068 "|voltage[dac]:Global target voltage in DAC counts for all channels");
2073 (
"Set a new target voltage for a single channel. Starts ramping if necessary." 2074 "|channel[short]:Channel for which to set the target voltage [0-415]" 2075 "|voltage[V]:Target voltage in volts for the given channel (will be converted to DAC units)");
2078 (
"Set a new target voltage for all channels. Starts ramping if necessary. (This command is not realized with the GLOBAL SET command.)" 2079 "|voltage[V]:Global target voltage in volts (will be converted to DAC units)");
2082 (
"Set all channels to the given new reference voltage. Starts ramping if necessary." 2083 "|voltage[V]:New reference voltage for all channels");
2105 (
"Set all channels to a zero reference voltage. Starts ramping if necessary.");
2108 (
"Same as SET_ZERO_VOLTAGE; but goes to locked state afterwards.");
2112 (
"Unlock if in locked state.");
2120 (
"Stop an on-going ramping");
2124 (
"Start a ramping if no ramping is in progress and if reference values differ from current voltages");
2128 T::AddEvent(
"PRINT_INFO")
2130 (
"Print a table with all current read back with the last request operation");
2131 T::AddEvent(
"PRINT_CURRENTS")
2133 (
"Print a table with all current read back with the last request operation");
2134 T::AddEvent(
"PRINT_VOLTAGES")
2136 (
"Print a table with all voltages (current and reference voltages as currently in memory)");
2137 T::AddEvent(
"PRINT_GAPD_REFERENCE_VOLTAGES")
2139 (
"Print the G-APD reference values (breakdown voltage + overvoltage) obtained from file");
2142 T::AddEvent(
"EXPERT_MODE",
"B:1")
2144 (
"Enable usage of expert commands (note that for safty reasons the are exclusive with the standard commands)");
2148 (
"Send the RESET command (note that this is possibly harmfull command)");
2152 (
"Send the global set command. The given voltage is converted to DAC counts.");
2156 (
"Send the global set command.");
2160 (
"Send a single channel set command. The given voltage is converted to DAC commands.");
2164 (
"Send a single channel set command.");
2168 (
"Load a new mapping file.");
2178 fBias.SetVerbose(!conf.
Get<
bool>(
"quiet"));
2179 fBias.SetDummyMode(conf.
Get<
bool>(
"dummy-mode"));
2181 if (conf.
Has(
"dev"))
2183 fBias.SetEndpoint(conf.
Get<
string>(
"dev"));
2184 T::Message(
"Setting device to "+fBias.URL());
2187 const uint16_t step = conf.
Get<uint16_t>(
"ramp-step");
2188 const uint16_t
time = conf.
Get<uint16_t>(
"ramp-delay");
2192 T::Error(
"ramp-step exceeds allowed range.");
2196 fBias.SetRampStep(step);
2197 fBias.SetRampTime(time);
2198 fBias.SetUpdateInterval(conf.
Get<uint32_t>(
"update-interval"));
2199 fBias.SetEmergencyLimit(conf.
Get<uint16_t>(
"emergency-limit"));
2200 fBias.SetSyncDelay(conf.
Get<uint16_t>(
"sync-delay"));
2202 ostringstream str1, str2;
2203 str1 <<
"Ramping in effective steps of " << fBias.GetRampStepVolt() <<
"V";
2204 str2 <<
"Ramping with a delay per step of " << time <<
"ms";
2210 const float maxabsv = conf.
Get<
float>(
"volt-max-abs");
2211 const float maxrelv = conf.
Get<
float>(
"volt-max-rel");
2218 T::Warn(
"volt-max exceeds 75V.");
2220 T::Warn(
"volt-max below 70V.");
2227 fBias.SetVoltMaxAbs(maxabsv);
2228 fBias.SetVoltMaxRel(maxrelv);
2230 ostringstream str3, str4;
2231 str3 <<
"Effective maximum allowed absolute voltage: " << fBias.GetVoltMaxAbs() <<
"V";
2232 str4 <<
"Effective maximum difference w.r.t to G-APD reference: " << fBias.GetVoltMaxRel() <<
"V";
2240 if (!conf.
Has(
"bias-map-file") && !conf.
Has(
"bias-database"))
2242 T::Error(
"Neither bias-map-file not bias-database specified.");
2248 if (conf.
Has(
"bias-map-file"))
2249 map.
Read(conf.
Get<
string>(
"bias-map-file"));
2254 catch (
const runtime_error &e)
2256 T::Error(
"Getting reference voltages failed: "+
string(e.what()));
2262 T::Error(
"Setting reference voltages failed.");
2268 if (conf.
Has(
"dev"))
2279 template<
class T,
class S,
class R>
2282 return Main::execute<T, StateMachineBias<S, R>>(conf);
2287 po::options_description control(
"BIAS control options");
2288 control.add_options()
2289 (
"no-dim,d",
po_bool(),
"Disable dim services")
2290 (
"dev", var<string>(),
"Device address of USB port to bias-power supply")
2291 (
"quiet,q",
po_bool(
true),
"Disable printing contents of all received messages (except dynamic data) in clear text.")
2292 (
"dummy-mode",
po_bool(),
"Dummy mode - SetAllChannels prints info instead of sending new values.")
2293 (
"ramp-delay", var<uint16_t>(15),
"Delay between the answer of one ramping step and sending the next ramp command to all channels in milliseconds.")
2294 (
"ramp-step", var<uint16_t>(46),
"Maximum step in DAC counts during ramping (Volt = DAC*90/4096)")
2295 (
"update-interval", var<uint32_t>(3000),
"Interval between two current requests in milliseconds")
2296 (
"sync-delay", var<uint16_t>(500),
"Delay between sending the inital 0's after a newly established connection to synchronize the output stream in milliseconds")
2297 (
"volt-max-abs", var<float>(75),
"Absolte upper limit for the voltage (in Volts)")
2298 (
"volt-max-rel", var<float>(3.5),
"Relative upper limit for the voltage w.r.t. the G-APD reference voltage (in Volts)")
2299 (
"bias-map-file", var<string>(),
"File with nominal and offset voltages for each channel.")
2300 (
"bias-database", var<string>(),
"")
2301 (
"emergency-limit", var<uint16_t>(2200),
"A current limit in ADC counts which, if exceeded, will initiate an emergency shutdown (0=off)")
2319 "The biasctrl program controls the bias-power supply boards.\n" 2321 "Note: At default the program is started without a command line (user) " 2322 "interface. In this case Actions/Commands are available via Dim " 2324 "Use the -c option to start the program with a command line interface.\n" 2326 "In the running application:\n" 2327 "Use h or help to print a short help message about its usage.\n" 2329 "Usage: biasctrl [-c type] [OPTIONS]\n" 2330 " or: biasctrl [OPTIONS]\n";
2336 Main::PrintHelp<StateMachineBias<StateMachine,ConnectionBias>>();
2356 int main(
int argc,
const char* argv[])
2369 if (!conf.
Has(
"console"))
2371 if (conf.
Get<
bool>(
"no-dim"))
2372 return RunShell<LocalStream, StateMachine, ConnectionBias>(conf);
2374 return RunShell<LocalStream, StateMachineDim, ConnectionDimBias>(conf);
2377 if (conf.
Get<
bool>(
"no-dim"))
2379 if (conf.
Get<
int>(
"console")==0)
2380 return RunShell<LocalShell, StateMachine, ConnectionBias>(conf);
2382 return RunShell<LocalConsole, StateMachine, ConnectionBias>(conf);
2386 if (conf.
Get<
int>(
"console")==0)
2387 return RunShell<LocalShell, StateMachineDim, ConnectionDimBias>(conf);
2389 return RunShell<LocalConsole, StateMachineDim, ConnectionDimBias>(conf);
vector< uint64_t > fCounter
std::vector< float > Vslope() const
vector< float > fCalibrationOffset
vector< int16_t > fCurrent
void SetVoltMaxRel(float max)
DimDescribedService fDimCurrent
int Wrap(boost::function< void()> f)
void HandleSyncTimer(int counter, const bs::error_code &error)
void PrintCommandDac(const vector< uint16_t > &dac)
uint16_t GetVoltMaxRel() const
A general base-class describing events issues in a state machine.
void SetRampTime(uint16_t val)
const char * GetText() const
vector< uint8_t > fBuffer
int ExpertSetGlobalVolt(const EventImp &evt)
virtual void UpdateVgapd()
void SetupConfiguration(Configuration &conf)
vector< char > GetCmd(uint16_t board, uint16_t channel, Command_t cmd, uint16_t dac=0)
void setQuality(int quality)
The base implementation of a distributed messaging system.
void PrintReferenceVoltage()
Adds some functionality to boost::posix_time::ptime for our needs.
void SetPrintUsage(const std::function< void(void)> &func)
T Get(const std::string &var)
void SetAllChannels(const vector< uint16_t > &dac, bool special=false)
void ResetEmergencyShutdown()
State::states_t GetStatus()
vector< uint8_t > fBufferRamp
int EvalOptions(Configuration &conf)
Time GetNextSunRise(double horizon) const
int ExpertSetChannelDac(const EventImp &evt)
DimDescribedService fDimDac
void SetReconnectDelay(uint32_t delay=1)
int main(int argc, const char *argv[])
void PrintLineA(int b, int ch)
vector< float > fCalibrationSlope
ConnectionDimBias(ba::io_service &ioservice, MessageImp &imp)
bool RampSingleChannelVoltage(uint16_t ch, float volt)
vector< uint8_t > fBufferUpdate
std::string GetString() const
int SetExpertMode(const EventImp &evt)
bool CheckChannelVoltage(uint16_t ch, float volt)
bool ExpertChannelSetVolt(uint16_t ch, double volt)
uint16_t ConvertVoltToDac(uint16_t ch, double volt)
bool RampAllDacs(uint16_t dac)
bool IsEmergencyShutdown() const
int SetChannelVolt(const EventImp &evt)
void PrintLineGapd(int b, int ch)
void SetupConfiguration(Configuration &conf)
bool SetReferences(const vector< float > &volt, const vector< float > &offset, const vector< float > &slope)
bool RampAllChannelsVoltage(const vector< float > &volt)
void HandleReceivedData(const bs::error_code &err, size_t bytes_received, int command, int send_counter)
uint16_t GetUShort() const
DimDescribedService fDimVolt
bool Has(const std::string &var)
int ExpertLoadMapFile(const EventImp &evt)
void SetRampStep(uint16_t val)
void HandleRampTimer(const bs::error_code &error)
int SetDummyMode(const EventImp &evt)
int SetAllChannelsVolt(const EventImp &evt)
void setTime(const Time &t)
void HandleReceivedData(const vector< uint8_t > &buf, size_t bytes_received, int command, int send_counter)
void AddOptions(const po::options_description &opt, bool visible=true)
int RunShell(Configuration &conf)
int SetChannelDac(const EventImp &evt)
bool ExpertGlobalSetDac(uint16_t dac)
int SetGlobalDac(const EventImp &evt)
uint16_t GetVoltMaxAbs() const
int ExpertSetChannelVolt(const EventImp &evt)
vector< char > GetCmd(Command_t cmd, uint16_t id=0, uint16_t dac=0)
void SendCommandNB(const std::string &command)
void PrintLineV(int b, int ch)
Warning because the service this data corrsponds to might have been last updated longer ago than Local time
void HandleUpdateTimer(const bs::error_code &error)
void SetUpdateInterval(uint32_t val)
double ConvertDacToVolt(uint16_t ch, uint16_t dac)
int SetGlobalVolt(const EventImp &evt)
Commandline parsing, resource file parsing and database access.
std::vector< float > Voffset() const
virtual void UpdateV(const Time=Time())
void UpdateV(const Time now=Time())
function< int(const EventImp &)> Wrapper(function< void()> func)
DimDescribedService fDimGapd
std::vector< float > Vgapd() const
bool RampAllChannelsDac(const vector< uint16_t > &dac)
bool CheckDac(uint16_t dac)
bool RampSingleChannelDac(uint16_t ch, uint16_t dac)
void PrintLineCmdDac(int b, int ch, const vector< uint16_t > &dac)
bool CheckEventSize(size_t has, const char *name, size_t size)
bool Read(const std::string &fname)
void ScheduleUpdate(int millisec)
int Shutdown(const string &reason)
void SetDummyMode(bool b)
boost::asio::deadline_timer fUpdateTimer
void SetEmergencyLimit(int32_t limit=0)
StateMachineBias(ostream &out=cout)
void ScheduleSync(int counter=0)
bool RampAllVoltages(float volt)
bool CheckChannel(uint16_t ch)
po::typed_value< bool > * po_bool(bool def=false)
ConnectionBias(ba::io_service &ioservice, MessageImp &imp)
void ExpertReset(bool expert_mode=true)
int SetAllChannelsDac(const EventImp &evt)
int ExpertSetGlobalDac(const EventImp &evt)
int Reconnect(const EventImp &evt)
void ConnectionEstablished()
int SetUpdateInterval(const EventImp &evt)
boost::asio::deadline_timer fRampTimer
T Get(size_t offset=0) const
bool CheckMessageLength(int received, int expected, const string &msg)
uint16_t GetRampStepVolt() const
bool DoParse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
bool ExpertGlobalSetVolt(float volt)
vector< uint16_t > fDacTarget
bool EvalAnswer(const uint8_t *answer, uint16_t id, int command)
int SetVerbosity(const EventImp &evt)
const T * Ptr(size_t offset=0) const
uint16_t RampOneStep(uint16_t ch)
void ReadAllChannels(bool special=false)
vector< uint16_t > fDacActual
void SetVoltMaxAbs(float max)
boost::asio::deadline_timer fSyncTimer
void SetSyncDelay(uint16_t val)
bool ExpertChannelSetDac(uint16_t ch, uint16_t dac)
vector< float > fOperationVoltage
virtual size_t GetSize() const
vector< uint16_t > fDacCommand