Index: /trunk/FACT++/src/biasctrl.cc
===================================================================
--- /trunk/FACT++/src/biasctrl.cc	(revision 11952)
+++ /trunk/FACT++/src/biasctrl.cc	(revision 11953)
@@ -764,5 +764,5 @@
         return ChannelSetDac(ch, volt*4096/90.);
     }
-
+/*
     bool GlobalSetDac(uint16_t dac)
     {
@@ -789,19 +789,25 @@
         return GlobalSetDac(volt*4096/90);
     }
-
-    bool GlobalAddDac(int16_t dac)
-    {
+*/
+    bool AddDac(const vector<int16_t> &dac)
+    {
+        if (dac.size()!=kNumChannels)
+        {
+            Error("AddDac - Wrong size of array.");
+            return false;
+        }
+
         for (size_t ch=0; ch<kNumChannels; ch++)
         {
-            if (fVoltRef[ch]+dac>kMaxDac)
+            if (fVoltRef[ch]+dac[ch]>kMaxDac)
             {
-                Error("GlobalAddDac - New voltage reference out of range.");
+                Error("AddDac - New voltage reference out of range.");
                 return false;
             }
 
-            if (fVoltRef[ch]+dac<0)
+            if (fVoltRef[ch]+dac[ch]<0)
                 fVoltRef[ch] = 0;
             else
-                fVoltRef[ch]+= dac;
+                fVoltRef[ch] += dac[ch];
         }
 
@@ -812,14 +818,80 @@
     }
 
+    bool AddVolt(const vector<float> &offset)
+    {
+        vector<int16_t> dac(offset.size());
+
+        for (size_t ch=0; ch<offset.size(); ch++)
+        {
+            if (offset[ch]<-90 || offset[ch]>90)
+            {
+                Error("AddVolt - Offset out of range [-90V,90V].");
+                return false;
+            }
+            dac[ch] = offset[ch]*4096/90;
+        }
+
+        return AddDac(dac);
+    }
+
+    bool GlobalAddDac(int16_t offset)
+    {
+        return AddDac(vector<int16_t>(kNumChannels, offset));
+    }
+
     bool GlobalAddVolt(float offset)
     {
-        if (offset<-90 || offset>90)
-        {
-            Error("GlobalAddVolt - Offset out of range [-90V,90V].");
-            return false;
-        }
-
-        return GlobalAddDac(offset*4096/90);
-    }
+        return AddVolt(vector<float>(kNumChannels, offset));
+    }
+
+    bool SetDac(const vector<int16_t> &dac)
+    {
+        if (dac.size()!=kNumChannels)
+        {
+            Error("SetDac - Wrong size of array.");
+            return false;
+        }
+
+        for (size_t ch=0; ch<kNumChannels; ch++)
+        {
+            if (!CheckChDac("SetDac", dac[ch]))
+                return false;
+
+            fVoltRef[ch] = dac[ch];
+        }
+
+        if (!fIsRamping)
+            fIsRamping = RampOneStep();
+
+        return true;
+    }
+
+    bool SetVolt(const vector<float> &volt)
+    {
+        vector<int16_t> dac(volt.size());
+
+        for (size_t ch=0; ch<volt.size(); ch++)
+        {
+            if (volt[ch]<0 || volt[ch]>90)
+            {
+                Error("SetVolt - Voltage out of range [0V,90V].");
+                return false;
+            }
+            dac[ch] = volt[ch]*4096/90;
+        }
+
+        return SetDac(dac);
+    }
+
+    bool GlobalSetDac(int16_t dac)
+    {
+        return SetDac(vector<int16_t>(kNumChannels, dac));
+    }
+
+    bool GlobalSetVolt(float volt)
+    {
+        return SetVolt(vector<float>(kNumChannels, volt));
+    }
+
 
     // --------------------------------------------------------------------
@@ -1337,4 +1409,50 @@
     // --------------------------------------------------------------------
 
+    int AddReferenceDac(const EventImp &evt)
+    {
+        if (!CheckEventSize(evt.GetSize(), "AddReferenceDac", 2*kNumChannels))
+            return false;
+
+        const int16_t *ptr = evt.Ptr<int16_t>();
+        fBias.AddDac(vector<int16_t>(ptr, ptr+416));
+
+        return T::GetCurrentState();
+    }
+
+    int AddReferenceVolt(const EventImp &evt)
+    {
+        if (!CheckEventSize(evt.GetSize(), "AddReferenceVolt", 4*kNumChannels))
+            return false;
+
+        const float_t *ptr = evt.Ptr<float>();
+        fBias.AddVolt(vector<float>(ptr, ptr+416));
+
+        return T::GetCurrentState();
+    }
+
+    int SetReferenceDac(const EventImp &evt)
+    {
+        if (!CheckEventSize(evt.GetSize(), "SetReferenceDac", 2*kNumChannels))
+            return false;
+
+        const int16_t *ptr = evt.Ptr<int16_t>();
+        fBias.SetDac(vector<int16_t>(ptr, ptr+416));
+
+        return T::GetCurrentState();
+    }
+
+    int SetReferenceVolt(const EventImp &evt)
+    {
+        if (!CheckEventSize(evt.GetSize(), "SetReferenceVolt", 4*kNumChannels))
+            return false;
+
+        const float_t *ptr = evt.Ptr<float>();
+        fBias.SetVolt(vector<float>(ptr, ptr+416));
+
+        return T::GetCurrentState();
+    }
+
+    // --------------------------------------------------------------------
+
     int ExpertSetGlobalVolt(const EventImp &evt)
     {
@@ -1555,4 +1673,21 @@
             (Wrapper(bind(&ConnectionBias::SetZero, &fBias)))
             ("Set all channels to a zero reference voltage. Starts ramping if necessary.");
+
+        T::AddEvent("SET_REFERENCE_VOLTAGES", "F:416", kConnected, kAtReference, kOverCurrent)
+            (bind(&StateMachineBias::SetReferenceVolt, this, placeholders::_1))
+            ("");
+
+        T::AddEvent("SET_REFERENCE_DACS", "S:416", kConnected, kAtReference, kOverCurrent)
+            (bind(&StateMachineBias::SetReferenceDac, this, placeholders::_1))
+            ("");
+
+        T::AddEvent("ADD_REFERENCE_VOLTAGES", "F:416", kConnected, kAtReference, kOverCurrent)
+            (bind(&StateMachineBias::AddReferenceVolt, this, placeholders::_1))
+            ("");
+
+        T::AddEvent("ADD_REFERENCE_DACS", "S:416", kConnected, kAtReference, kOverCurrent)
+            (bind(&StateMachineBias::AddReferenceDac, this, placeholders::_1))
+            ("");
+
 
 
