Index: /trunk/FACT++/src/biasctrl.cc
===================================================================
--- /trunk/FACT++/src/biasctrl.cc	(revision 18123)
+++ /trunk/FACT++/src/biasctrl.cc	(revision 18124)
@@ -65,4 +65,7 @@
     Time fLastConnect;
 
+    int32_t  fEmergencyLimit;
+    bool     fEmergencyShutdown;
+
 protected:
 
@@ -270,4 +273,11 @@
             fCurrent[id]    = status ? -(ddd==0?1:ddd) : ddd;
             fPresent[board] = true;
+
+            if (fEmergencyLimit>0 && fCurrent[id]>fEmergencyLimit && !fEmergencyShutdown)
+            {
+                Info("Emergency shutdown initiated.");
+                RampAllDacs(0);
+                fEmergencyShutdown = true;
+            }
         }
 
@@ -840,4 +850,6 @@
         fWaitingForAnswer(-1),
         fCounter(8),
+        fEmergencyLimit(0),
+        fEmergencyShutdown(false),
         fCurrent(kNumChannels),
         fOperationVoltage(kNumChannels, 0),
@@ -1498,4 +1510,19 @@
         fReconnectDelay = delay;
     }
+
+    void SetEmergencyLimit(int32_t limit=0)
+    {
+        fEmergencyLimit = limit;
+    }
+
+    void ResetEmergencyShutdown()
+    {
+        fEmergencyShutdown = false;
+    }
+
+    bool IsEmergencyShutdown() const
+    {
+        return fEmergencyShutdown;
+    }
 };
 
@@ -1879,4 +1906,11 @@
         const int state = fBias.GetStatus();
 
+        if (fBias.IsEmergencyShutdown() && state>State::kInitializing && state<State::kExpertMode)
+        {
+            fBias.RampAllDacs(0);
+            fBias.ResetEmergencyShutdown();
+            return State::kLocked;
+        }
+
         const Time now;
         if (now>fSunRise)
@@ -1900,4 +1934,7 @@
         }
 
+        if (T::GetCurrentState()==State::kLocked)
+            return T::GetCurrentState();
+
         if (fExpertMode && state>=State::kConnected)
             return State::kExpertMode;
@@ -1943,5 +1980,5 @@
 
         T::AddStateName(State::kLocked, "Locked",
-                        "Locked, no commands accepted except UNLOCK.");
+                        "Locked due to emergency shutdown, no commands accepted except UNLOCK.");
 
         // Verbosity commands
@@ -2121,4 +2158,5 @@
         fBias.SetRampTime(time);
         fBias.SetUpdateInterval(conf.Get<uint32_t>("update-interval"));
+        fBias.SetEmergencyLimit(conf.Get<uint16_t>("emergency-limit"));
         fBias.SetSyncDelay(conf.Get<uint16_t>("sync-delay"));
 
@@ -2222,4 +2260,5 @@
         ("bias-map-file",   var<string>(),       "File with nominal and offset voltages for each channel.")
         ("bias-database",   var<string>(),       "")
+        ("emergency-limit", var<uint16_t>(2200), "A current limit in ADC counts which, if exceeded, will initiate an emergency shutdown (0=off)")
         ;
 
