Index: trunk/FACT++/src/biasctrl.cc
===================================================================
--- trunk/FACT++/src/biasctrl.cc	(revision 11937)
+++ trunk/FACT++/src/biasctrl.cc	(revision 11938)
@@ -78,4 +78,5 @@
 
     uint16_t fUpdateTime;
+    uint16_t fSyncTime;
 
     bool fIsInitializing;
@@ -89,4 +90,6 @@
     vector<int16_t>  fCurrent;     // Current in ADC units (12bit = 5mA)
 
+    uint16_t fVoltMax;
+
     virtual void UpdateA()
     {
@@ -103,4 +106,9 @@
         {
             Error(cmd+" - DAC value out of range.");
+            return false;
+        }
+        if (dac>fVoltMax)
+        {
+            Error(cmd+" - DAC value exceeds fVoltMax.");
             return false;
         }
@@ -199,5 +207,4 @@
                 Warn("Initial answer doesn't seem to be a reset as naively expected.");
 
-                // FIXME:
                 //ostringstream msg;
                 //msg << hex << setfill('0');
@@ -463,5 +470,5 @@
     void ScheduleSync(int counter=0)
     {
-        fSyncTimer.expires_from_now(boost::posix_time::milliseconds(1000));
+        fSyncTimer.expires_from_now(boost::posix_time::milliseconds(fSyncTime));
         fSyncTimer.async_wait(boost::bind(&ConnectionBias::HandleSyncTimer, this, counter, dummy::error));
     }
@@ -511,14 +518,11 @@
         }
 
-        if (is_open())
-        {
-            if (fIsRamping)
-            {
-                Info("Schedule of update timer skipped.");
-                ScheduleUpdate(fUpdateTime);
-            }
-            else
-                ReadAllChannels(true);
-        }
+        if (!is_open())
+            return;
+
+        if (fIsRamping)
+            ScheduleUpdate(fUpdateTime);
+        else
+            ReadAllChannels(true);
     }
 
@@ -565,4 +569,15 @@
     bool RampOneStep()
     {
+        if (fRampTime<0)
+        {
+            Warn("Ramping step time not yet set... ramping not started.");
+            return false;
+        }
+        if (fRampStep<0)
+        {
+            Warn("Ramping step not yet set... ramping not started.");
+            return false;
+        }
+
         vector<uint16_t> dac(kNumChannels);
 
@@ -626,5 +641,4 @@
     void ScheduleRampStep()
     {
-        Message("Schedule ramping");
         fRampTimer.expires_from_now(boost::posix_time::milliseconds(fRampTime));
         fRampTimer.async_wait(boost::bind(&ConnectionBias::HandleRampTimer, this, dummy::error));
@@ -644,4 +658,5 @@
         fRampStep(-1),
         fRampTime(-1),
+        fSyncTime(333),
         fUpdateTime(3000),
         fIsRamping(false),
@@ -791,8 +806,4 @@
 
         fIsRamping = RampOneStep();
-
-        ostringstream msg;
-        msg << "Ramp=" << fIsRamping;
-        Message(msg);
     }
 
@@ -826,6 +837,4 @@
 
         fVoltCmd[ch] = dac;
-
-        // FIXME: How to ensure the correct evaluation of the answer?
 
         ostringstream msg;
@@ -983,4 +992,25 @@
 
     // -------------------------------------------------------------------
+
+    void SetUpdateInterval(uint16_t val)
+    {
+        fUpdateTime = val;
+    }
+
+    void SetSyncDelay(uint16_t val)
+    {
+        fSyncTime = val;
+    }
+
+    void SetVoltMax(float max)
+    {
+        fVoltMax = max*4096/90;
+        if (fVoltMax>4095)
+            fVoltMax = 4095;
+        if (max<0)
+            fVoltMax = 0;
+    }
+
+
 /*
     void AdaptVoltages()
@@ -1292,6 +1322,4 @@
         // deletion and creation of threads and more.
 
-        T::Warn("FIXME -- implement a state for 'at reference'");
-
         // State names
         T::AddStateName(ConnectionBias::kDisconnected, "Disconnected",
@@ -1436,12 +1464,27 @@
             return 1;
         }
-        if (time>10000) // 5V
-        {
-            T::Error("ramp-time exceeds allowed range.");
-            return 2;
-        }
 
         fBias.SetRampStep(step);
         fBias.SetRampTime(time);
+        fBias.SetUpdateInterval(conf.Get<uint16_t>("update-interval"));
+        fBias.SetSyncDelay(conf.Get<uint16_t>("sync-delay"));
+
+        const float maxv = conf.Get<float>("volt-max");
+        if (maxv>90)
+        {
+            T::Error("volt-max exceeds 90V.");
+            return 2;
+        }
+        if (maxv>75)
+            T::Warn("volt-max exceeds 75V.");
+        if (maxv<70)
+            T::Warn("volt-max below 70V.");
+        if (maxv<0)
+        {
+            T::Error("volt-max negative.");
+            return 3;
+        }
+
+        fBias.SetVoltMax(maxv);
 
         // --------------------------------------------------------------------------
@@ -1477,5 +1520,5 @@
             {
                 T::Error("Invalid board/channel read from FACTmapV5.txt.");
-                return 3;
+                return 4;
             }
 
@@ -1487,5 +1530,5 @@
         {
             T::Error("Reading reference voltages from FACTmapV5.txt failed.");
-            return 4;
+            return 5;
         }
 
@@ -1493,5 +1536,5 @@
         {
             T::Error("Setting reference voltages failed.");
-            return 5;
+            return 6;
         }
 
@@ -1518,14 +1561,15 @@
     po::options_description control("BIAS control options");
     control.add_options()
-        ("no-dim,d",      po_bool(),  "Disable dim services")
-        ("dev",           var<string>("FTE00FOH"),  "Device address of USB port to bias-power supply")
-        ("quiet,q",       po_bool(),        "Disable printing contents of all received messages (except dynamic data) in clear text.")
-        ("ramp-time",     var<uint16_t>(),  "")
-        ("ramp-step",     var<uint16_t>(),  "")
+        ("no-dim,d",        po_bool(),  "Disable dim services")
+        ("dev",             var<string>("FTE00FOH"),  "Device address of USB port to bias-power supply")
+        ("quiet,q",         po_bool(),        "Disable printing contents of all received messages (except dynamic data) in clear text.")
+        ("ramp-time",       var<uint16_t>(15),   "")
+        ("ramp-step",       var<uint16_t>(46),   "")
+        ("update-interval", var<uint16_t>(3000), "")
+        ("sync-delay",      var<uint16_t>(333),  "")
+        ("volt-max",        var<float>(75),      "")
         ;
-    // FIXME: Update interval
-    // FIXME: Synchronization interval
-    // FIXME: Make sure ramping / request and commands are not sent at the same time.
-    // FIXME: Add limit of 75V
+    // FIXME: Make sure ramping / request and commands are
+    //        not sent at the same time.
 
     conf.AddOptions(control);
