Index: fact/BIASctrl/Crate.cc
===================================================================
--- fact/BIASctrl/Crate.cc	(revision 10095)
+++ fact/BIASctrl/Crate.cc	(revision 10096)
@@ -119,5 +119,8 @@
   // === Lock device ===
   flockfile(File);
-  
+
+  // Do not try to communicate if crate has too many errors
+  if (ErrorCount > MAX_ERR_COUNT) goto ExitCommunicate;
+
   // === Write data ===
   if ((N = write(fDescriptor, Buf.data(), Buf.size())) < (int) Buf.size()) {
@@ -125,5 +128,5 @@
     else m->Message(m->ERROR, "Could write only %d of %d bytes to board", N, Buf.size());
     ErrorCount++;
-	goto ExitCommunicate;
+	
   }
 
@@ -132,6 +135,5 @@
 	FD_ZERO(&SelectDescriptor);   FD_SET(fDescriptor, &SelectDescriptor);
 	if (select(fDescriptor+1, &SelectDescriptor, NULL, NULL, &WaitTime)==-1) {
-      m->Message(m->ERROR, "Error with select() (%s)", strerror(errno));
-	  goto ExitCommunicate;
+      m->Message(m->FATAL, "Error with select() (%s)", strerror(errno));
 	}
 
Index: fact/BIASctrl/Crate.h
===================================================================
--- fact/BIASctrl/Crate.h	(revision 10095)
+++ fact/BIASctrl/Crate.h	(revision 10096)
@@ -17,6 +17,6 @@
 #define NUM_CHANNELS 32		// Channels per bias board
 #define BAUDRATE B115200
-const float RESISTOR = 1000;		// Resistance in Ohm for voltage correction
-
+const float RESISTOR = 1000;	// Resistance in Ohm for voltage correction
+const int MAX_ERR_COUNT = 10;	// Maximum number of errors before reporting stopped
 class User;
 
Index: fact/BIASctrl/History.txt
===================================================================
--- fact/BIASctrl/History.txt	(revision 10095)
+++ fact/BIASctrl/History.txt	(revision 10096)
@@ -4,3 +4,4 @@
 17/11/2010	Added possibility for bulk transfers (ReadAll(), SetChannels())
 24/11/2010	Ramping for many channels possible with bulk transfers
-7/12/2010	Added dynamic mode.
+7/12/2010	Added dynamic mode
+6/1/2011	RampVoltages() had infinite loop if crate communication stopped
Index: fact/BIASctrl/User.cc
===================================================================
--- fact/BIASctrl/User.cc	(revision 10095)
+++ fact/BIASctrl/User.cc	(revision 10096)
@@ -54,9 +54,9 @@
 
     if (New->InitOK && New->Synch()) {
-       PrintMessage("Synchronized and reset board %s (#%d)\n", Boards[i].c_str(), Crates.size());
+       PrintMessage("Synchronized and reset crate %s (#%d)\n", Boards[i].c_str(), Crates.size());
        Crates.push_back(New);
     }
     else {
-      Message(WARN, "Failed to synchronize board %s", Boards[i].c_str());
+      Message(WARN, "Failed to synchronize crate %s", Boards[i].c_str());
 	  delete New;
     }
@@ -150,6 +150,8 @@
 void User::cmd_synch() {
 
-  if (Crates[0]->Synch()) PrintMessage("Synchronized board %d\n", 0);
-  else PrintMessage("Failed to synchronize board %d\n", 0);
+  for (unsigned int i=0; i<Crates.size(); i++) {
+	if (Crates[i]->Synch()) PrintMessage("Synchronized crate %d\n", i);
+	else PrintMessage("Failed to synchronize crate %d\n", i);
+  }
 }
 
@@ -219,5 +221,11 @@
   }
 
-  if (Errors > 0) Message(ERROR, "%d errors occurred from SetChannels()", Errors);
+  // Error message only if not yet too many errors
+  if (Errors > 0) {
+	for (unsigned int i=0; i<Crates.size(); i++) {
+	  if (Crates[i]->ErrorCount > MAX_ERR_COUNT) return;
+	}
+    Message(ERROR, "%d errors occurred from SetChannels()", Errors);
+  }
 }
 
@@ -325,6 +333,8 @@
   if (!ConvertToDouble(Parameter[1], &Voltage)) return;
 
-  if (Crates[0]->GlobalSet(Voltage) != 1) {
-    PrintMessage("Error: Could not global set board %d\n", 0);
+  for (unsigned int i=0; i<Crates.size(); i++) {
+	if (Crates[i]->GlobalSet(Voltage) != 1) {
+	  PrintMessage("Error: Could not global set crate %d\n", i);
+	}
   }    
 }
@@ -343,10 +353,12 @@
 
   // Execute current offset determination
-  if (!Crates[0]->CurrentCalib(Voltage)) {
-    PrintMessage("Error with current calibration of board %d\n", 0);
-	return;
-  }
-  
-  PrintMessage("Current calibration of board %d done\n", 0);  
+  for (unsigned int i=0; i<Crates.size(); i++) {
+	if (!Crates[i]->CurrentCalib(Voltage)) {
+      PrintMessage("Error with current calibration of crate %d\n", i);
+	  return;
+	}
+
+	PrintMessage("Current calibration of crate %d done\n", i);
+  }
 }
 
@@ -481,8 +493,8 @@
 
   map<unsigned int, double> Target;
-  unsigned int Errors = 0;
+  int Errors = 0;
 
   // Ramp until all channels at desired value
-  while (!Voltages.empty()) {
+  while (!Voltages.empty() && Errors < MAX_ERR_COUNT) {
     // Remove channels already at target (check for DAC, not for floating-point voltage)
 	for (map<unsigned int, double>::iterator it = Voltages.begin(); it != Voltages.end(); ++it) {
@@ -517,5 +529,5 @@
   while (!ExitRequest) {
 	for (unsigned int i=0; i<Crates.size(); i++) {
-      if (Crates[i]->ErrorCount > 10) {
+      if (Crates[i]->ErrorCount > MAX_ERR_COUNT) {
     	if (!Warned) {
           Warned = true;
