Index: /trunk/FACT++/src/biasctrl.cc
===================================================================
--- /trunk/FACT++/src/biasctrl.cc	(revision 11930)
+++ /trunk/FACT++/src/biasctrl.cc	(revision 11931)
@@ -145,6 +145,6 @@
     bool CheckMessageLength(int received, int expected, const string &msg)
     {
-        if (received!=expected)
-            return false;
+        if (received==expected)
+            return true;
 
         ostringstream str;
@@ -166,4 +166,10 @@
         const uint16_t board  =  answer[2]&0xf;
 
+        /*
+        Out() << dec << setw(2) << board << '|' << wrap << " ";
+        if (id%8==7)
+            Out() << endl;
+            */
+
         if (fWrapCounter>=0)
         {
@@ -171,5 +177,5 @@
             {
                 ostringstream msg;
-                msg << "Corrupted answer: received wrap counter " << wrap << " is not last received counter (" << fWrapCounter << "+1)%8.";
+                msg << "Corrupted answer (id=" << id << "): received wrap counter " << wrap << " doesn't match last received counter " << fWrapCounter << ".";
                 Error(msg);
                 return false;
@@ -184,11 +190,19 @@
             msg << hex << setfill('0');
             msg << "Initial answer received:";
-            msg << " 0x" << setw(2) << answer[0];
-            msg << " 0x" << setw(2) << answer[1];
-            msg << " 0x" << setw(2) << answer[2];
+            msg << " 0x" << setw(2) << (int)answer[0];
+            msg << " 0x" << setw(2) << (int)answer[1];
+            msg << " 0x" << setw(2) << (int)answer[2];
             Message(msg);
 
-            if (status!=0 || ddd!=0 || error!=0 || board==0)
+            if (status!=0 || ddd!=0 || error!=0 || board!=0)
+            {
                 Warn("Initial answer doesn't seem to be a reset as naively expected.");
+
+                // FIXME:
+                //ostringstream msg;
+                //msg << hex << setfill('0');
+                //msg << "S=" << status << " D=" << ddd << " E=" << error << " B=" << board;
+                //Message(msg);
+            }
 
             fSendCounter = wrap;
@@ -299,6 +313,10 @@
 
         // Now print the received message if requested by the user
-        if (fIsVerbose)
-        {
+        if (fIsVerbose/* && command!=kUpdate*/)
+        {
+            Out() << endl << kBold << dec << "Data received (size=" << bytes_received << "):" << endl;
+            Out() << " Command=" << command << " fWrapCounter=" << fWrapCounter << " fSendCounter=" << fSendCounter << " fIsInitializing=" << fIsInitializing << " fIsRamping=" << fIsRamping << endl;
+            Out() << hex << setfill('0');
+
             vector<uint32_t> vout((bytes_received/3)*4);
 
@@ -306,12 +324,14 @@
             {
                 vout[i] =
-                    (uint32_t(fBuffer[i*3+0])<<16) |
+                    (uint32_t(fBuffer[i*3+2])<<16) |
                     (uint32_t(fBuffer[i*3+1])<< 8) |
-                    (uint32_t(fBuffer[i*3+2])<< 0);
+                    (uint32_t(fBuffer[i*3+0])<< 0);
+
+                Out() << setw(6) << vout[i] << " ";
+                if (i%8==7)
+                    Out() << endl;
             }
 
-            Out() << endl << kBold << "Data received (size=" << bytes_received << "):" << endl;
-            Out() << " fWrapCounter=" << fWrapCounter << " fSendCounter=" << fSendCounter << " fIsInitializing=" << fIsInitializing << " fIsRamping=" << fIsRamping << endl;
-            Out() << Converter::GetHex<uint32_t>(vout, 16) << endl;
+            //Out() << Converter::GetHex<uint32_t>(vout, 16) << endl;
         }
 
@@ -336,26 +356,28 @@
         }
 
+        // Now we are ready to send a new message
+//        fWaitingForAnswer = false;
+
+        if (command==kSynchronize)
+        {
+            Message("Stream successfully synchronized.");
+            fIsInitializing = false;
+
+            // Cancel sending of the next 0
+            fSyncTimer.cancel();
+
+            // Start continous reading of all channels
+            ScheduleUpdate(100);
+            return;
+        }
+
         if (send_counter%8 != fWrapCounter)
         {
             ostringstream msg;
-            msg << "Corrupted answer: received wrap counter " << fWrapCounter  << " is not send counter " << fSendCounter << "%8.";
+            msg << "Corrupted answer: received wrap counter " << fWrapCounter  << " is not send counter " << send_counter << "%8.";
             Error(msg);
             PostClose(false);
         }
 
-        // Now we are ready to send a new message
-//        fWaitingForAnswer = false;
-
-        if (command==kSynchronize)
-        {
-            Message("Stream successfully synchronized.");
-            fIsInitializing = false;
-
-            // Cancel sending of the next 0
-            fSyncTimer.cancel();
-
-            // Start continous reading of all channels
-            ScheduleUpdate(100);
-        }
 
         // Take action depending on what is going on
@@ -367,5 +389,4 @@
             UpdateV();
             UpdateA();
-            return;
         }
 
@@ -395,6 +416,8 @@
         if (error==ba::error::basic_errors::operation_aborted)
         {
-            Warn("Synchronization aborted...");
-            fIsRamping = false;
+            if (fIsInitializing)
+                Warn("Synchronization aborted...");
+            else
+                Info("Synchronization successfull.");
             return;
         }
@@ -417,5 +440,5 @@
 
         ostringstream msg;
-        msg << "Synchronization time expired (" << counter << ")" << endl;
+        msg << "Synchronization time expired (" << counter << ")";
         Info(msg);
 
@@ -440,5 +463,5 @@
     void ScheduleSync(int counter=0)
     {
-        fSyncTimer.expires_from_now(boost::posix_time::milliseconds(333));
+        fSyncTimer.expires_from_now(boost::posix_time::milliseconds(1000));
         fSyncTimer.async_wait(boost::bind(&ConnectionBias::HandleSyncTimer, this, counter, dummy::error));
     }
@@ -453,12 +476,12 @@
         fIsInitializing = true;
 
-        fVolt.assign(   0, kNumChannels);
-        fVoltRef.assign(0, kNumChannels);
-        fVoltCmd.assign(0, kNumChannels);
+        fVolt.assign(   kNumChannels, 0);
+        fVoltRef.assign(kNumChannels, 0);
+        fVoltCmd.assign(kNumChannels, 0);
 
         // Send a single 0 (and possible two consecutive 0's
         // to make sure we are in sync with the device)
         PostMessage("\0", 1);
-        AsyncRead(ba::buffer(fBuffer, 3), kSynchronize, ++fSendCounter);
+        AsyncRead(ba::buffer(fBuffer, 3), kSynchronize, 0);//++fSendCounter);
 //        fWaitingForAnswer = true;
 
@@ -489,5 +512,13 @@
 
         if (is_open())
-            ReadAllChannels(true);
+        {
+            if (fIsRamping)
+            {
+                Info("Schedule of update timer skipped.");
+                ScheduleUpdate(fUpdateTime);
+            }
+            else
+                ReadAllChannels(true);
+        }
     }
 
@@ -540,5 +571,5 @@
         {
             dac[ch] = RampOneStep(ch);
-            if (dac[ch]!=fVolt[ch])
+            if (dac[ch]!=fVolt[ch] && fPresent[ch/kNumChannelsPerBoard])
                 identical = false;
         }
@@ -583,4 +614,11 @@
         }
 
+        // Check whether the deadline has passed. We compare the deadline
+        // against the current time since a new asynchronous operation
+        // may have moved the deadline before this actor had a chance
+        // to run.
+        if (fRampTimer.expires_at() > ba::deadline_timer::traits_type::now())
+            return;
+
         fIsRamping = RampOneStep();
     }
@@ -588,4 +626,5 @@
     void ScheduleRampStep()
     {
+        Message("Schedule ramping");
         fRampTimer.expires_from_now(boost::posix_time::milliseconds(fRampTime));
         fRampTimer.async_wait(boost::bind(&ConnectionBias::HandleRampTimer, this, dummy::error));
@@ -598,5 +637,5 @@
         fUpdateTimer(ioservice),
         fBuffer(3*kNumChannels),
-        fIsVerbose(true),
+        fIsVerbose(false),
         fVoltCmd(kNumChannels),
         fVoltGapd(kNumChannels),
@@ -752,4 +791,8 @@
 
         fIsRamping = RampOneStep();
+
+        ostringstream msg;
+        msg << "Ramp=" << fIsRamping;
+        Message(msg);
     }
 
@@ -828,5 +871,5 @@
     bool ExpertGlobalSetVolt(float volt)
     {
-        return GlobalSetDac(volt*4096/90);
+        return ExpertGlobalSetDac(volt*4096/90);
     }
 
@@ -1214,9 +1257,9 @@
         T::AddEvent("REQUEST_STATUS", ConnectionBias::kConnected, ConnectionBias::kRamping)
             (Wrapper(bind(&ConnectionBias::ReadAllChannels, &fBias, false)))
-            ("");
+            ("Asynchronously request the status (current) of all channels.");
 
         T::AddEvent("RESET_OVER_CURRENT_STATUS", ConnectionBias::kConnected)
             (Wrapper(bind(&ConnectionBias::OverCurrentReset, &fBias)))
-            ("");
+            ("NOT YET TESTED");
 
 
@@ -1224,25 +1267,25 @@
         T::AddEvent("SET_GLOBAL_VOLTAGE", "F:1", ConnectionBias::kConnected, ConnectionBias::kRamping)
             (bind(&StateMachineBias::SetGlobalVolt, this, placeholders::_1))
-            ("");
+            ("Set all channels to a new reference voltage. Starts ramping if necessary. (This command is not realized with the GLOBAL SET command.)");
 
         T::AddEvent("SET_GLOBAL_DAC", "S:1", ConnectionBias::kConnected, ConnectionBias::kRamping)
             (bind(&StateMachineBias::SetGlobalDac, this, placeholders::_1))
-            ("");
+            ("Set all channels to a new DAC reference. Starts ramping if necessary. (This command is not realized with the GLOBAL SET command.)");
 
         T::AddEvent("SET_CHANNEL_VOLTAGE", "S:1;F:1", ConnectionBias::kConnected, ConnectionBias::kRamping)
             (bind(&StateMachineBias::SetChannelVolt, this, placeholders::_1))
-            ("");
+            ("Set a single channel a new reference voltage. Starts ramping if necessary.");
 
         T::AddEvent("SET_CHANNEL_DAC", "S:1;S:1", ConnectionBias::kConnected, ConnectionBias::kRamping)
             (bind(&StateMachineBias::SetChannelDac, this, placeholders::_1))
-            ("");
+            ("Set a single channel a new DAC reference value. Starts ramping if necessary.");
 
         T::AddEvent("SET_GAPD_REFERENCE_VOLTAGE", ConnectionBias::kConnected, ConnectionBias::kRamping)
             (Wrapper(bind(&ConnectionBias::SetGapdVoltage, &fBias)))
-            ("");
+            ("Set all channels to their G-APD reference voltage. Starts ramping if necessary.");
 
         T::AddEvent("SET_ZERO_VOLTAGE", ConnectionBias::kConnected, ConnectionBias::kRamping)
             (Wrapper(bind(&ConnectionBias::SetZero, &fBias)))
-            ("");
+            ("Set all channels to a zero reference voltage. Starts ramping if necessary.");
 
 
@@ -1258,5 +1301,5 @@
 
 
-        T::AddEvent("PRINT", ConnectionBias::kConnected, ConnectionBias::kRamping)
+        T::AddEvent("PRINT", ConnectionBias::kConnected, ConnectionBias::kExpertMode, ConnectionBias::kRamping)
             (Wrapper(bind(&ConnectionBias::Print, &fBias)))
             ("");
@@ -1265,26 +1308,28 @@
         T::AddEvent("EXPERT_MODE", "B:1")
             (bind(&StateMachineBias::SetExpertMode, this, placeholders::_1))
-            ("");
+            ("Enable usage of expert commands (note that for safty reasons the are exclusive with the standard commands)");
 
         T::AddEvent("EXPERT_RESET", ConnectionBias::kExpertMode)
             (Wrapper(bind(&ConnectionBias::ExpertReset, &fBias)))
-            ("");
+            ("Send the RESET command (note that this is possibly harmfull command)");
 
         T::AddEvent("EXPERT_SET_GLOBAL_VOLTAGE", "F:1", ConnectionBias::kExpertMode)
             (bind(&StateMachineBias::ExpertSetGlobalVolt, this, placeholders::_1))
-            ("");
+            ("Send the global set command. The given voltage is converted to DAC counts.");
 
         T::AddEvent("EXPERT_SET_GLOBAL_DAC", "S:1", ConnectionBias::kExpertMode)
             (bind(&StateMachineBias::ExpertSetGlobalDac, this, placeholders::_1))
-            ("");
+            ("Send the global set command.");
 
         T::AddEvent("EXPERT_SET_CHANNEL_VOLTAGE", "S:1;F:1", ConnectionBias::kExpertMode)
             (bind(&StateMachineBias::ExpertSetChannelVolt, this, placeholders::_1))
-            ("");
+            ("Send a single channel set command. The given voltage is converted to DAC commands.");
 
         T::AddEvent("EXPERT_SET_CHANNEL_DAC", "S:1;S:1", ConnectionBias::kExpertMode)
             (bind(&StateMachineBias::ExpertSetChannelDac, this, placeholders::_1))
-            ("");
-    }
+            ("Send a single channel set command.");
+    }
+
+    ~StateMachineBias() { T::Warn("Implement rampming at shutdown!"); }
 
     int EvalOptions(Configuration &conf)
@@ -1390,5 +1435,4 @@
         ("ramp-time",     var<uint16_t>(),  "")
         ("ramp-step",     var<uint16_t>(),  "")
-        ("ramp-volt",     var<float>(),     "")
         ;
 
