Index: /Feedback/Feedback.cc
===================================================================
--- /Feedback/Feedback.cc	(revision 269)
+++ /Feedback/Feedback.cc	(revision 269)
@@ -0,0 +1,495 @@
+/**************************************************************\
+
+  Bias feedback
+
+  Oliver Grimm, July 2010
+ 
+\**************************************************************/
+
+
+#include "Feedback.h"
+#include "PixelMap.h"
+
+#define PIXMAP_LOCATION "../config/PixelMap.txt"
+
+static const char* FBState_Description[] = {
+	"Feedback off",
+	"Feedback active",
+	"Feedback acquiring new targets",
+	"Feedback measuring response with first voltage",
+	"Feedback measuring response with second voltage"
+};
+
+static const struct CL_Struct { const char *Name;    
+								void (Feedback::*CommandPointer)();
+								const char *Parameters;
+								const char *Help;
+  } CommandList[] = 
+  {{"mode", &Feedback::cmd_mode, "[off|active|target]", "Set or get feedback mode"},
+   {"average", &Feedback::cmd_average, "[n]", "Set ot get number of averages for feedback"},
+   {"gain", &Feedback::cmd_gain, "[gain]", "Set ot get feedback gain"},
+   {"target", &Feedback::cmd_target, "[pixel id]", "Set or get target value"},
+   {"response", &Feedback::cmd_response, "[voltage]", "Start or get response measurement"},
+   {"clear", &Feedback::cmd_clear, "", "Clear feedback signals"},
+   {"data", &Feedback::cmd_data, "", "New feedback signals"},
+   {"help", &Feedback::cmd_help, "", "Print help"},
+   {"exit", &Feedback::cmd_exit, "", "Exit program"}};
+
+using namespace std;
+
+
+// ----- Constructor: Initialise feedback 
+Feedback::Feedback(): EvidenceServer(SERVER_NAME) {
+
+  PixMap = new PixelMap(PIXMAP_LOCATION, false);
+  TimeBarrier = 0;
+
+  // DIM console service used in PrintMessage()
+  ConsoleText = NULL;
+  ConsoleOut = new DimService(SERVER_NAME"/ConsoleOut", (char *) "");
+
+  // Get pixel ID table
+  fIDTable = Tokenize(GetConfig("IDTable"), " \t");
+  Multiplicity = new unsigned int [fIDTable.size()];
+  
+  multiset<string> A;
+  char *Buf;
+  
+  for (unsigned int i=0; i<fIDTable.size(); i++) {
+ 	if (asprintf(&Buf, "BiasID%d%d%d", PixMap->Pixel_to_HVboard(fIDTable[i]),
+	  	PixMap->Pixel_to_HVchain(fIDTable[i]), PixMap->Pixel_to_HVchannel(fIDTable[i])) == -1) Message(FATAL, "asprintf() failed");
+	A.insert(Buf);
+	free(Buf);
+  }
+  
+  for (unsigned int i=0; i<fIDTable.size(); i++) {
+ 	if (asprintf(&Buf, "BiasID%d%d%d", PixMap->Pixel_to_HVboard(fIDTable[i]),
+	  	PixMap->Pixel_to_HVchain(fIDTable[i]), PixMap->Pixel_to_HVchannel(fIDTable[i])) == -1) Message(FATAL, "asprintf() failed");
+	Multiplicity[i] = A.count(Buf);
+	free(Buf);
+  }
+
+  // Initialise with zero content ???
+  Average    = new float [fIDTable.size()];
+  Sigma      = new float [fIDTable.size()];
+  Response   = new float [fIDTable.size()];
+  Target     = new float [fIDTable.size()];
+  Buffer     = new float [fIDTable.size()];  
+
+  DIMAverage = new float [fIDTable.size()];
+  DIMSigma   = new float [fIDTable.size()];
+
+  // Get remaing configuration data
+  fDefaultNumAverage = atoi(GetConfig("DefaultNumAverage").c_str());
+  
+  vector<string> Token = Tokenize(GetConfig("DefaultResponse"), " \t");
+  for (unsigned int i=0; i< Token.size(); i++) {
+	if (i < fIDTable.size()) Response[i] = (float) atof(Token[i].c_str());
+  }
+
+  Token = Tokenize(GetConfig("DefaultTarget"), " \t");
+  for (unsigned int i=0; i<Token.size(); i++) {
+	if (i < fIDTable.size()) Target[i] = (float) atof(Token[i].c_str());
+  }
+  
+  // Provide DIM services
+  FeedbackAverage = new DimService (SERVER_NAME"/Average", "F", DIMAverage, fIDTable.size() * sizeof(float));
+  FeedbackSigma = new DimService (SERVER_NAME"/Sigma", "F", DIMSigma, fIDTable.size() * sizeof(float));
+  FeedbackResponse = new DimService (SERVER_NAME"/Response", "F", Response, fIDTable.size() * sizeof(float));
+  FeedbackTarget = new DimService (SERVER_NAME"/Target", "F", Target, fIDTable.size() * sizeof(float));
+  CountService = new DimService (SERVER_NAME"/Count", Count);
+  FeedbackState = new DimService (SERVER_NAME"/State", "I:1;C", NULL, 0);
+
+  // Initial state
+  Gain = atof(GetConfig("DefaultGain").c_str());
+  SetFBMode(Off);
+  NumAverages = fDefaultNumAverage;
+  LastServiceUpdate = 0;
+  
+  // Install DIM command (after all initialized)
+  Command = new DimCommand((char *) SERVER_NAME"/Command", (char *) "C", this);
+}
+
+
+// ----- Destructor
+Feedback::~Feedback() {
+
+  delete Command;
+  delete FeedbackState;
+  delete CountService;
+  delete FeedbackAverage;
+  delete FeedbackSigma;
+  delete FeedbackResponse;
+  delete FeedbackTarget;
+
+  delete[] Average;   	delete[] Response;
+  delete[] DIMAverage; 	delete[] DIMSigma;
+  delete[] Sigma;		delete[] Target;
+  delete[] Buffer;		delete[] Multiplicity;
+  delete PixMap;
+  
+  delete ConsoleOut;
+  free(ConsoleText);
+}
+
+
+// ----- Set/get mode of feedback
+void Feedback::cmd_mode() {
+
+  if (Match(Parameter[1], "off")) SetFBMode(Off);
+  else if (Match(Parameter[1], "active")) SetFBMode(Active);
+  else if (Match(Parameter[1], "targets")) SetFBMode(Targets);
+  else PrintMessage("%s.\n", FBState_Description[FBMode]);
+}
+
+
+// ----- Set/get current number of events
+void Feedback::cmd_average() {
+
+  if (Parameter.size() == 1) {
+	PrintMessage("Current feedback events: %u   (acting when %u events reached)\n", Count, NumAverages);
+  }
+  else if (atoi(Parameter[1].c_str())>=0) NumAverages = atoi(Parameter[1].c_str());
+  else PrintUsage();
+}
+
+
+// ----- Set/get feedback gain
+void Feedback::cmd_gain() {
+
+  if (Parameter.size() == 2) Gain = atof(Parameter[1].c_str());
+  PrintMessage("Feedback gain is %.2f\n", Gain);
+}
+
+
+// ----- Set/get target value
+void Feedback::cmd_target() {
+
+  if (Parameter.size() == 1) {
+	for (unsigned int i=0; i<fIDTable.size(); i++) {
+      PrintMessage("%s: %.2f  ", fIDTable[i].c_str(), Target[i]);
+      if (i%5 == 4) PrintMessage("\n\r");
+	}
+	PrintMessage("\n");
+	return;
+  }
+
+  if (Parameter.size() != 3) {
+	PrintUsage();
+	return;
+  }
+
+  if (Match(Parameter[1], "all")) {
+	for (unsigned int i=0; i<fIDTable.size(); i++) {
+	  Target[i] = atof(Parameter[2].c_str());
+	}
+	FeedbackTarget->updateService();
+	return;
+  }
+  
+  for (unsigned int i=0; i<fIDTable.size(); i++) {
+	if (Match(Parameter[1], fIDTable[i])) {
+	  Target[i] = atof(Parameter[2].c_str());
+	  FeedbackTarget->updateService();
+	  return;
+	}
+  }
+  
+  PrintMessage("Invalid board, chip or channel number.\n");
+}
+
+
+// ----- Start response measurement
+void Feedback::cmd_response() {
+
+  if (Parameter.size() == 1) {
+    for (unsigned int i=0; i<fIDTable.size(); i++) {
+      PrintMessage("%s: %.2f  ", fIDTable[i].c_str(), Response[i]);
+      if (i%5 == 4) PrintMessage("\n\r");
+	}
+	PrintMessage("\n");
+  }
+  else if (atof(Parameter[1].c_str()) != 0) MeasureResponse(atof(Parameter[1].c_str()));
+  else PrintUsage();
+}
+
+
+// ----- Clear accumulated averages
+void Feedback::cmd_clear() {
+
+  ClearAverages();
+}
+
+
+// ----- Accumulate feedback data and calculate voltage change if required number of events reached.
+void Feedback::cmd_data() {
+
+  float Correction;
+
+  // Refect data is feedback off or timestamp too early
+  if (FBMode == Off || getCommand()->getTimestamp() < TimeBarrier) return;
+  TimeBarrier = 0;
+
+  // Calculate average signal  
+  for (unsigned int i=0; i<Parameter.size()-1, i<fIDTable.size(); i++) {
+	Average[i] += atof(Parameter[i+1].c_str());
+	Sigma[i] += pow(atof(Parameter[i+1].c_str()), 2);
+  }
+  
+  // Update DIM count service regularly
+  if (time(NULL)-LastServiceUpdate > 2) {
+    LastServiceUpdate = time(NULL);
+	CountService->updateService();
+  }
+
+  // Check if acquired number of event requires action
+  if (++Count<NumAverages) return;
+
+  // Feedback action
+  std::stringstream Cmd;
+
+  for (unsigned int i=0; i<fIDTable.size(); i++) {
+    // Calculate average
+	Average[i] /= Count;
+	Sigma[i] = sqrt(Sigma[i]/Count - pow(Average[i],2))/sqrt(Count);
+	DIMAverage[i] = Average[i];
+	DIMSigma[i] = Sigma[i];
+	
+	switch (FBMode) {
+	  case Active:
+		// Determine correction from response maxtrix and change voltages
+	    Correction = -(Target[i] - Average[i])*Response[i]*Gain;
+    	// Limit voltage steps
+		if (fabs(Correction) > 0.1) Correction = fabs(Correction)/Correction*0.1;   // Limit changes to 100 mV
+		if (Correction==0 || Target[i]==0) break;
+		// Add voltage change command if not too noisy
+		if(fabs(Average[i]) > 2*Sigma[i]) {
+		  Cmd << fIDTable[i] << " " << std::showpos << Correction/Multiplicity[i] << " ";
+		}
+	    break;
+
+	  case Targets:  // Take average as new targets  
+	    Target[i] = Average[i];
+	    break;
+
+	  case ResponseFirst:  // First point of response measurement done  
+	    Buffer[i] = Average[i];
+		Cmd << fIDTable[i] << " " << std::showpos << DiffVoltage/Multiplicity[i] << " ";		  
+	    break;
+
+	  case ResponseSecond: // Determine response from signal variation
+	    if (Buffer[i] == Average[i]) {
+	      PrintMessage("Warning, response singular for pixel %s\n", fIDTable[i].c_str());
+	      Response[i] = 0;
+	    }
+	    else Response[i] = DiffVoltage/(Buffer[i] - Average[i]);
+
+		Cmd << fIDTable[i] << " " << std::showpos << -DiffVoltage/2/Multiplicity[i] << " ";		  		  
+	    break;
+
+	  default: break;  // to suppress warning abount not handled enumeration value
+        }			
+  } // for()
+
+  // Update DIM service
+  FeedbackAverage->updateService();
+  FeedbackSigma->updateService();
+
+  // Send command (non-blocking since in handler thread)
+  if (!Cmd.str().empty()) {
+	DimClient::sendCommandNB("Bias/Command", (char *) ("hv "+Cmd.str()).c_str());
+  }
+
+  switch (FBMode) {
+    case Targets:
+	  FeedbackTarget->updateService();
+      PrintMessage("New targets set, switching off\n");
+      SetFBMode(Off);
+      break;
+    case ResponseFirst:
+      SetFBMode(ResponseSecond);
+      PrintMessage("Increasing voltages by %f for response measurement, acquiring data\n", DiffVoltage);
+      break;
+    case ResponseSecond:
+	  FeedbackResponse->updateService();
+      PrintMessage("Response measurements finished, original voltages set, switching off\n");
+      SetFBMode(Off);
+      break;
+    default: break;  // to suppress warning abount not handled enumeration value
+  }
+  ClearAverages();
+  
+  return;
+}
+
+
+// ----- Print help
+void Feedback::cmd_help() {
+
+  char Buffer[BUF_LENGTH];
+
+  for(unsigned int i=0; i<sizeof(CommandList)/sizeof(CL_Struct); i++) {
+    snprintf(Buffer, sizeof(Buffer), "%s %s", CommandList[i].Name, CommandList[i].Parameters);
+    PrintMessage("%-28s%s\n", Buffer, CommandList[i].Help);
+  }     
+}
+
+
+// ----- Exit programm
+void Feedback::cmd_exit() {
+
+  ExitRequest = true;
+}
+
+
+// ----- Clear average values and event counter
+void Feedback::ClearAverages() {
+
+  for (unsigned int i=0; i<fIDTable.size(); i++) {
+	Average[i] = 0.0;
+	Sigma[i] = 0.0;
+  }
+  Count = 0;
+  CountService->updateService();
+}
+
+
+// ----- Set feedback mode and clear averages
+void Feedback::SetFBMode(FBState Mode) {
+
+  FBMode = Mode;
+  if (Mode != ResponseFirst) PrintMessage("%s\n", FBState_Description[FBMode]);
+  else PrintMessage("%s (voltage difference %.3f)\n", FBState_Description[FBMode], DiffVoltage);
+  ClearAverages();
+
+  // Update state service
+  State.State = FBMode;
+  strncpy(State.Text, FBState_Description[FBMode], sizeof(State.Text));
+  FeedbackState->updateService(&State, sizeof(State));
+
+  // Reject feedback signals received earlier than this time
+  TimeBarrier = time(NULL) + 2;
+}
+
+
+// ----- Measure response matrix
+void Feedback::MeasureResponse(float U) {
+
+  std::stringstream Cmd;
+
+  if (U == 0) {
+    PrintMessage("Error, voltage difference must be non-zero.\n");
+    return;
+  }
+
+  // Build command
+  for (unsigned int i=0; i<fIDTable.size(); i++) { 
+	Cmd << fIDTable[i] << " " << std::showpos << -U/2/Multiplicity[i] << " ";		  		  
+  }
+  
+  // Send command
+  if (!Cmd.str().empty()) {
+	DimClient::sendCommand("Bias/Command", ("hv "+Cmd.str()).c_str());
+  }
+
+  DiffVoltage = U;
+  SetFBMode(ResponseFirst);
+  PrintMessage("HV Feedback: Decreasing voltages by %f for response measurement, acquiring data.\n",DiffVoltage/2);
+}
+
+
+// ----- Print usage text for command
+void Feedback::PrintUsage() {
+
+  for (unsigned int i=0; i<sizeof(CommandList)/sizeof(CL_Struct); i++) {
+    if (Match(Parameter[0], CommandList[Count].Name)) {
+	  PrintMessage("Usage: %s %s\n", Parameter[0].c_str(), CommandList[Count].Parameters);
+	}
+  }
+}
+
+
+// ----- Print message to console only
+void Feedback::PrintMessage(const char *Format, ...) {
+
+  static char Error[] = "vasprintf() failed in PrintMessage()";
+  char *Text;
+
+  // Evaluate arguments
+  va_list ArgumentPointer;
+  va_start(ArgumentPointer, Format);
+  if (vasprintf(&Text, Format, ArgumentPointer) == -1) Text = Error;
+  va_end(ArgumentPointer);
+  
+  // Print to console
+  if(strlen(Text)>0 && Text[strlen(Text)-1]=='\n') printf("\r%sCmd> ", Text); // New prompt
+  else printf("%s", Text);
+  fflush(stdout);
+
+  // Send to DIM text service
+  ConsoleOut->updateService(Text); 
+
+  // Free old text
+  if (ConsoleText != Error) free(ConsoleText);
+  ConsoleText = Text; 
+}
+
+
+// ----- DIM command handler
+void Feedback::commandHandler() {
+
+  string Command = ToString("C", getCommand()->getData(), getCommand()->getSize());
+  
+  // Parse command into tokens
+  Parameter.clear();
+  Parameter = Tokenize(Command, " \t");
+  if (Parameter.empty()) return;
+
+  // Search for command
+  for (unsigned int Count=0; Count<sizeof(CommandList)/sizeof(CL_Struct); Count++) {
+    if (Match(Parameter[0], CommandList[Count].Name)) {
+	  (this->*CommandList[Count].CommandPointer)();
+	  return;
+	}
+  }
+  
+  // Command not found
+  PrintMessage("Unknown command '%s'\n", Command.c_str());
+}
+
+
+// -----  Check if two strings match (min 1 character must match)
+bool Feedback::Match(string str, string cmd) {
+  return strncasecmp(str.c_str(),cmd.c_str(),strlen(str.c_str())==0 ? 1:strlen(str.c_str())) ? false:true;
+}
+
+
+// ================
+//   Main program
+// ================
+
+int main() {
+
+  char *Command;
+
+  system("clear");
+  printf("\n*** Bias feedback (built %s, %s, revision %s) *** \n\n",__DATE__, __TIME__, REVISION);
+
+  // Readline library uses getc() (allows interruption by signal)
+  rl_getc_function = getc;
+
+  // Construct main instance (static ensures destructor is called with exit())
+  static Feedback M;
+
+  // Command loop
+  while (!M.ExitRequest) {
+    // Read Command
+    Command = readline("\rCmd> ");
+    if (Command == NULL) continue;
+    if(strlen(Command)>0) add_history(Command);
+
+    // Process command
+	DimClient::sendCommand(SERVER_NAME"/Command", Command);
+    free(Command);
+  }
+}
Index: /Feedback/Feedback.h
===================================================================
--- /Feedback/Feedback.h	(revision 269)
+++ /Feedback/Feedback.h	(revision 269)
@@ -0,0 +1,76 @@
+#ifndef FEEDBACK_H_SEEN
+#define FEEDBACK_H_SEEN
+
+#define SERVER_NAME "Feedback"       // Name to use in DIM
+#include "Evidence.h"
+
+#define BUF_LENGTH 1000
+
+#include <stdio.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+#include <math.h>
+#include <sstream>
+#include <vector>
+
+enum FBState {Off, Active, Targets, ResponseFirst, ResponseSecond};
+
+class Feedback: public EvidenceServer {
+
+	struct {
+      int State;
+	  char Text[BUF_LENGTH];
+	} State;
+
+    class PixelMap *PixMap;
+    FBState FBMode;
+    std::vector<std::string> fIDTable;
+	unsigned int *Multiplicity; 
+
+    float *Average;
+    float *Sigma;
+    float *Response;
+    float *Target;
+    float *Buffer;
+    float *DIMAverage;
+    float *DIMSigma;
+
+	DimService *FeedbackAverage;
+	DimService *FeedbackSigma;
+	DimService *FeedbackResponse;
+	DimService *FeedbackTarget;
+	DimService *CountService;
+	DimService *FeedbackState;
+	DimCommand *Command;
+	DimService *ConsoleOut;
+	char *ConsoleText;
+    int LastServiceUpdate;
+
+    int fDefaultNumAverage;
+	int NumAverages;					// Events before feedback acts
+	int Count;							// Current number of events
+    float Gain;
+    float DiffVoltage;					// for response measurement	
+	std::vector<std::string> Parameter;
+	int TimeBarrier;
+
+    void SetFBMode(FBState);
+    void MeasureResponse(float);
+    void ClearAverages();
+    void PrintMessage(const char*, ...);
+	bool Match(std::string, std::string);    
+    void PrintUsage();
+	void commandHandler();
+
+  public:
+    Feedback();
+    ~Feedback();
+
+    void cmd_mode();		void cmd_average();
+    void cmd_target();		void cmd_gain();
+    void cmd_response();	void cmd_config();
+    void cmd_data();		void cmd_clear();
+	void cmd_help();		void cmd_exit();
+};
+
+#endif
Index: /Feedback/History.txt
===================================================================
--- /Feedback/History.txt	(revision 269)
+++ /Feedback/History.txt	(revision 269)
@@ -0,0 +1,5 @@
+Modification history of Feedback program
+----------------------------------------
+
+27/7/2010   Feedback separated from drsdaq. Previous history listed in
+			drsdaq directory.
Index: /Feedback/Makefile
===================================================================
--- /Feedback/Makefile	(revision 269)
+++ /Feedback/Makefile	(revision 269)
@@ -0,0 +1,37 @@
+#
+#  Makefile for Feedback server
+#
+
+CC  	= g++   	# Compiler to use
+
+SOURCES = ../pixelmap/Pixel.cc ../pixelmap/PixelMap.cc Feedback.cc ../Evidence/Evidence.cc 
+OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))
+INCDIRS   = -I. -I../pixelmap -I../Evidence -I$(DIMDIR)/dim
+
+REVISION = $(shell svnversion -n)
+
+CPPFLAGS = -DREVISION='"$(REVISION)"' -O3 -Wall
+LIBS = -lstdc++ -lz -lpthread -lutil -lfl -lreadline -ltermcap $(DIMDIR)/linux/libdim.a
+
+Feedback: $(OBJECTS)
+	$(CC) $(CPPFLAGS) -o $@ $(OBJECTS) $(LIBS)
+
+clean:
+	@rm -f $(OBJECTS)
+	@rm -f *.d
+	@rm -f *~
+
+-include Dep.d
+	
+# Implicit rules
+
+%.o : %.c
+	$(CC) $(CPPFLAGS) $(INCDIRS) -c -o $@ $<
+%.o : %.cc
+	$(CC) $(CPPFLAGS) $(INCDIRS) -c -o $@ $<
+%.o : %.cpp
+	$(CC) $(CPPFLAGS) $(INCDIRS) -c -o $@ $< 
+%.d : 
+	@echo "Generating dependencies" $@
+	@$(CC) -MM $(SOURCES) $(INCDIRS) \
+	| sed 's/^\(.*\).o:/$@ \1.o:/' > $@
Index: /drsdaq/DAQReadout.cc
===================================================================
--- /drsdaq/DAQReadout.cc	(revision 268)
+++ /drsdaq/DAQReadout.cc	(revision 269)
@@ -47,10 +47,4 @@
    {"update", &DAQReadout::cmd_update, false, "<sec>", "Minimum delay between updates to DIM event service"},		  
    {"exit", &DAQReadout::cmd_exit, false, "", "Exit program"},
-   {"fmode", &DAQReadout::cmd_fmode, false, "[off|active|targ]", "Set or get feedback mode"},
-   {"faverage", &DAQReadout::cmd_faverage, false, "[n]", "Set ot get number of averages for feedback"},
-   {"fgain", &DAQReadout::cmd_fgain, false, "[gain]", "Set ot get feedback gain"},
-   {"ftarget", &DAQReadout::cmd_ftarget, false, "[brd chip chan]", "Set or get target value (also 'all' supported)"},
-   {"fresponse", &DAQReadout::cmd_fresponse, false, "[voltage]", "Start response measurement with given voltage difference"},
-   {"fconfig", &DAQReadout::cmd_fconfig, false, "", "Print feedback configuration"},
    {"help", &DAQReadout::cmd_help, false, "", "Print help"}};
 
@@ -96,4 +90,13 @@
   fDefaultFrequency = atof(GetConfig("DefaultFrequency").c_str());
 
+  fLedTrigBoard = atoi(GetConfig("TrigBoard").c_str());
+  fLedTrigChannel = atoi(GetConfig("TrigChannel").c_str());
+  fLedTrigChip = atoi(GetConfig("TrigChip").c_str());
+  fLedTrigSample = atoi(GetConfig("TrigSample").c_str());
+  fLedTrigThreshold = atoi(GetConfig("TrigThreshold").c_str());
+  fLedSignalSample = atoi(GetConfig("SignalSample").c_str());
+  fLedBaselineSample = atoi(GetConfig("BaselineSample").c_str());
+  fIntHalfWidth = atoi(GetConfig("IntHalfWidth").c_str());
+
   if (fFirstSample < 0 || fFirstSample > kNumberOfBins || fSamples > kNumberOfBins) {
     PrintMessage("Warning: Sample range in configuration beyond limits, setting to full range\n");
@@ -140,7 +143,4 @@
   EventService = new DimService (SERVER_NAME"/EventData", (char *) "C", DIMEventData, 0);
 						   
-  // Create instance of HV feedback (must be called after board detection)
-  HVFB	  = new HVFeedback(this);  
-
   // Install DIM command (after all initialized)
   Command = new DimCommand((char *) SERVER_NAME"/Command", (char *) "C", this);
@@ -157,5 +157,5 @@
   delete EventService;	delete[] DIMEventData;
   delete RHeader;		delete EHeader;
-  delete HVFB;			delete[] ACalibTemp;
+  delete[] ACalibTemp;
   delete[] ACalib;		delete[] TCalib;
   delete[] DRSFreq; 	delete[] BStruct;
@@ -220,5 +220,16 @@
 // Print DAQ configuration
 void DAQReadout::cmd_config() {
-  PrintConfig();
+
+  PrintMessage("RawDataPath: %s\n"
+		"DefaultFrequency: %.2f\tFirstSample: %d\tSamples: %u\n"
+		"MinDiskSpaceMB: %u\tMaxFileSizeMB: %d\n"
+		"CalibDataPath: %s\n\n"
+		"LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n"
+        "LedTrigSample: %d\tLedTrigThreshold: %.2f\n"
+        "LedSignalSample: %d\tLedBaselineSample: %d\tIntHalfWidth:%u\n",
+    fRawDataPath,fDefaultFrequency,fFirstSample,fSamples,fMinDiskSpaceMB,
+    fMaxFileSizeMB,fCalibDataPath,
+    fLedTrigBoard, fLedTrigChip, fLedTrigChannel, fLedTrigSample,
+    fLedTrigThreshold, fLedSignalSample, fLedBaselineSample, fIntHalfWidth);
 }
 
@@ -755,56 +766,4 @@
 }
 
-// Set/get mode of feedback
-void DAQReadout::cmd_fmode() {
-
-  if(Match(Param[1],"off")) HVFB->SetFBMode(FB_Off);
-  else if(Match(Param[1],"active")) HVFB->SetFBMode(FB_Active);
-  else if(Match(Param[1],"targets")) HVFB->SetFBMode(FB_Targets);
-  else HVFB->GetFBMode();
-}
-
-// Set/get current number of events
-void DAQReadout::cmd_faverage() {
-
-  if(NParam==1) PrintMessage("Current number of feedback events: %u   (acting when %u events are reached)\n",
-                       HVFB->GetCurrentCount(), HVFB->GetNumAverages());
-  else if(atoi(Param[1])>=0) HVFB->SetNumAverages(atoi(Param[1]));
-  else PrintUsage();
-}
-
-// Set/get feedback gain
-void DAQReadout::cmd_fgain() {
-
-  if(NParam==2) HVFB->SetGain(atof(Param[1]));
-  PrintMessage("Feedback gain is %.2f\n", HVFB->GetGain());
-}
-
-// Set/get target value
-void DAQReadout::cmd_ftarget() {
-
-  if(NParam==1) HVFB->GetTargets();
-  else if(NParam!=5) PrintUsage();
-  else for (int i=FirstBoard; i<=LastBoard; i++)
-         for (int j=0; j<GetBoard(i)->GetNumberOfChips(); j++)
-           for (int k=0; k<GetBoard(i)->GetNumberOfChannels(); k++)
-             if ((atoi(Param[1])==i || Match(Param[1],"all")) &&
-	         (atoi(Param[2])==j || Match(Param[2],"all")) &&
-	         (atoi(Param[3])==k || Match(Param[3],"all")))
-      	      HVFB->SetTarget(i,j,k,atof(Param[4]));
-}
-
-// Start response measurement
-void DAQReadout::cmd_fresponse() {
-
-  if(NParam==1) HVFB->GetResponse();
-  else if(atof(Param[1])) HVFB->MeasureResponse(atof(Param[1]));
-  else PrintUsage();
-}
-
-// Print feedback configuration
-void DAQReadout::cmd_fconfig() {
-
-  HVFB->PrintConfig();
-}
 
 // ----------------------------------------------
@@ -1156,14 +1115,4 @@
 }
 
-// Print configuration to target
-void DAQReadout::PrintConfig() {
-  PrintMessage("RawDataPath: %s\n"
-      	       "DefaultFrequency: %.2f\tFirstSample: %d\tSamples: %u\n"
-     	       "MinDiskSpaceMB: %u\tMaxFileSizeMB: %d\n"
-			   "CalibDataPath: %s\n",
-    fRawDataPath,fDefaultFrequency,fFirstSample,fSamples,fMinDiskSpaceMB,
-    fMaxFileSizeMB,fCalibDataPath);
-}
-
 // Print usage text for command
 void DAQReadout::PrintUsage() {
@@ -1249,7 +1198,9 @@
   int DIMSize;
 
+  // Initialize run
   NumEvents = 0;
   FileNumber = 0;
-  HVFB->ClearAverages();    
+  DimClient::sendCommandNB("Feedback/Command", "clear");
+    
   gettimeofday(&StartTime, NULL);
   PrintMessage("\rStarting run #%d (%s) with %u event(s)\n", RunNumber, daq_runtype_str[daq_runtype], NumEventsRequested);
@@ -1303,6 +1254,26 @@
       }
 
-      // Call feedback to process event
-      HVFB->ProcessEvent();
+	  // Check for LED trigger
+	  if (WaveForm[fLedTrigBoard][fLedTrigChip][fLedTrigChannel][fLedTrigSample] > fLedTrigThreshold) {
+		std::stringstream Cmd;
+		float Integral;
+
+		// Calculate feedback signal
+		for (int i=FirstBoard; i<=LastBoard; i++) {
+		  for (unsigned int j=0; j<RHeader->NChips; j++) {
+			for (unsigned int k=0; k<RHeader->NChannels; k++) {
+			  Integral = 0.0;
+			  for (int q=-fIntHalfWidth; q<=(int) fIntHalfWidth; q++) { 
+        		Integral += (WaveForm[i][j][k][fLedSignalSample+q] - WaveForm[i][j][k][fLedBaselineSample+q])*GetBoard(i)->GetPrecision();
+			  }
+        	  Integral /= 2*fIntHalfWidth+1;
+			  Cmd << Integral << " ";
+    		}
+		  }
+		}
+
+		// Send data to feedback
+		DimClient::sendCommandNB("Feedback/Command", (char *) ("data "+Cmd.str()).c_str());
+	  }
 
       // Call routine to update DIM service (update rate is limited)
Index: /drsdaq/DAQReadout.h
===================================================================
--- /drsdaq/DAQReadout.h	(revision 268)
+++ /drsdaq/DAQReadout.h	(revision 269)
@@ -9,4 +9,5 @@
 #include <ctype.h>
 #include <time.h>
+#include <math.h>
 #include <errno.h>
 #include <unistd.h>
@@ -19,5 +20,4 @@
 #include "RawDataCTX.h"
 #include "DRS.h"
-#include "HVFeedback.h"
 
 #define MAX_PATH 256		// also used for filename length
@@ -38,10 +38,8 @@
 	DimService *ConsoleOut;
 	char *ConsoleText;
+    int Rawfile;
 
     void PrintUsage();
 	void commandHandler();
-
-    int Rawfile;
-    class HVFeedback* HVFB;
 
     // Configuration data
@@ -53,4 +51,13 @@
     unsigned int fSamples;
     double fDefaultFrequency;
+
+    int fLedTrigBoard;
+    int fLedTrigChip;
+    int fLedTrigChannel;
+    int fLedTrigSample;
+    float fLedTrigThreshold;
+    int fLedSignalSample;
+    int fLedBaselineSample;
+    unsigned int fIntHalfWidth;
 
     state_enum   daq_state;
@@ -103,8 +110,4 @@
     void cmd_disk();	   void cmd_uptime();
       
-    void cmd_fmode(); 	   void cmd_faverage();
-    void cmd_ftarget();    void cmd_fgain();
-    void cmd_fresponse();  void cmd_fconfig();
-
     void Execute(char*);  
     void StartDRS();
@@ -121,5 +124,4 @@
     bool ReadCalibration();
     void ReadCalibratedDRSData();
-    void PrintConfig();
     void PrintMessage(const char*, ...);
     bool OpenRawFile();
Index: sdaq/HVFeedback.cc
===================================================================
--- /drsdaq/HVFeedback.cc	(revision 268)
+++ 	(revision )
@@ -1,390 +1,0 @@
-/********************************************************************\
-
-  HVFeedback.cc
-
-  Class handling the feedback of GAPD high voltage
-    
-  Oliver Grimm
-
-\********************************************************************/
-
-#include "HVFeedback.h"
-#include "PixelMap.h"
-
-#define PIXMAP_LOCATION "../config/PixelMap.txt"
-
-static const char* FBState_Description[] = {
-	"Feedback off",
-	"Feedback active",
-	"Feedback acquiring new targets",
-	"Feedback measuring response with first voltage",
-	"Feedback measuring response with second voltage"
-};
-
-using namespace std;
-
-//
-// Constructor: Initialise feedback 
-//
-HVFeedback::HVFeedback(DAQReadout* DAQClass){
-
-  m = DAQClass;
-  fNumberOfChannels = m->GetBoard(0)->GetNumberOfChannels();
-  fNumberOfChips = m->GetBoard(0)->GetNumberOfChips();  
-
-  PixMap = new PixelMap(PIXMAP_LOCATION, false);
-
-  // Initialise with zero content
-  Average    = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
-  Sigma      = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
-  Response   = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
-  Target     = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
-  Buffer     = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();  
-
-  DIMAverage = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
-  DIMSigma   = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
-
-  // Get configuration data
-  fLedTrigBoard = atoi(m->GetConfig("TrigBoard").c_str());
-  fLedTrigChannel = atoi(m->GetConfig("TrigChannel").c_str());
-  fLedTrigChip = atoi(m->GetConfig("TrigChip").c_str());
-  fLedTrigSample = atoi(m->GetConfig("TrigSample").c_str());
-  fLedTrigThreshold = atoi(m->GetConfig("TrigThreshold").c_str());
-  fLedSignalSample = atoi(m->GetConfig("SignalSample").c_str());
-  fLedBaselineSample = atoi(m->GetConfig("BaselineSample").c_str());
-  fIntHalfWidth = atoi(m->GetConfig("IntHalfWidth").c_str());
-  fDefaultNumAverage = atoi(m->GetConfig("DefaultNumAverage").c_str());
-
-  vector<string> Token = m->Tokenize(m->GetConfig("DefaultResponse"), " \t");
-  unsigned int N = 0;
-  for (int i=0; i<m->NumBoards; i++) {
-	for (int j=0; j<fNumberOfChips; j++) {
-	  for (int k=0; k<fNumberOfChannels; k++) {
-		if (N < Token.size()) Response[i][j][k] = (float) atof(Token[N++].c_str());
-	  }
-	}
-  }
-
-  Token = m->Tokenize(m->GetConfig("DefaultTarget"), " \t");
-  N = 0;
-  for (int i=0; i<m->NumBoards; i++) {
-	for (int j=0; j<fNumberOfChips; j++) {
-	  for (int k=0; k<fNumberOfChannels; k++) {
-		if (N < Token.size()) Target[i][j][k] = (float) atof(Token[N++].c_str());
-	  }
-	}
-  }
-  
-  // Provide DIM services
-  FeedbackAverage = new DimService ("Feedback/Average", "F", DIMAverage, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
-  FeedbackSigma = new DimService ("Feedback/Sigma", "F", DIMSigma, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
-  FeedbackResponse = new DimService ("Feedback/Response", "F", Response, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
-  FeedbackTarget = new DimService ("Feedback/Target", "F", Target, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
-  CountService = new DimService ("Feedback/Count", Count);
-  FeedbackState = new DimService ("Feedback/State", "I:1;C", NULL, 0);
-
-  // Initial state
-  Gain = atof(m->GetConfig("DefaultGain").c_str());
-  SetFBMode(FB_Off);
-  SetNumAverages(fDefaultNumAverage);
-  LastServiceUpdate = 0;
-}
-
-//
-// Destructor
-//
-HVFeedback::~HVFeedback() {
-
-  delete FeedbackState;
-  delete CountService;
-  delete FeedbackAverage;
-  delete FeedbackSigma;
-  delete FeedbackResponse;
-  delete FeedbackTarget;
-
-  delete[] Average;   	delete[] Response;
-  delete[] DIMAverage; 	delete[] DIMSigma;
-  delete[] Sigma;
-  delete[] Target;   	delete[] Buffer;
-  delete PixMap;
-}
-
-//
-// Check if LED trigger present, if yes accumulate feedback data and
-// calculate new high voltages if the required number of events is reached.
-//
-bool HVFeedback::ProcessEvent() {
-  int i,j,k,q;
-  float Correction, Integral;
-
-  // Check for LED trigger channel on given channel and if feedback running
-  if (FBMode==FB_Off || m->WaveForm[fLedTrigBoard][fLedTrigChip][fLedTrigChannel][fLedTrigSample] < fLedTrigThreshold) {
-    return false;
-  }
-  
-  // Calculate average signal of LED pulse as integral of signal
-  for (i=m->FirstBoard; i<=m->LastBoard; i++) {
-	for (j=0; j<fNumberOfChips; j++) {
-	  for (k=0; k<fNumberOfChannels; k++) {
-		for (Integral=0, q=-fIntHalfWidth; q<=(int) fIntHalfWidth; q++) { 
-          Integral += (m->WaveForm[i][j][k][fLedSignalSample+q] - m->WaveForm[i][j][k][fLedBaselineSample+q])*m->GetBoard(i)->GetPrecision();
-		}
-        Integral /= 2*fIntHalfWidth+1;
-		Average[i][j][k] += Integral;
-    	Sigma[i][j][k] += pow(Integral,2);
-      }
-	}
-  }
-  
-  // Update DIM count service regularly
-  if (time(NULL)-LastServiceUpdate > 2) {
-    LastServiceUpdate = time(NULL);
-	CountService->updateService();
-  }
-  // Check if acquired number of event requires action
-  if (++Count<NumAverages) return false;
-
-  // Feedback action
-  std::stringstream Cmd;
-  
-  for (i=m->FirstBoard; i<=m->LastBoard; i++) {
-  for (j=0; j<fNumberOfChips; j++) {
-  for (k=0; k<fNumberOfChannels; k++) {
-    // Calculate average
-	Average[i][j][k] /= Count;
-	Sigma[i][j][k] = sqrt(Sigma[i][j][k]/Count-pow(Average[i][j][k],2))/sqrt(Count);
-	DIMAverage[i][j][k] = Average[i][j][k];
-	DIMSigma[i][j][k] = Sigma[i][j][k];
-	
-	switch (FBMode) {
-	  case FB_Active:
-		// Determine correction from response maxtrix and change voltages
-	    Correction = -(Target[i][j][k] - Average[i][j][k])*Response[i][j][k]*Gain;
-    	// Limit voltage steps
-		if (fabs(Correction) > 0.1) Correction = fabs(Correction)/Correction*0.1;   // Limit changes to 100 mV
-		// Check if voltage change command possible
-		if(Correction==0 || Target[i][j][k]==0 || PixMap->DRS_to_Pixel(i,j,k).empty()) break;
-		// Add voltage change command if not too noisy
-		if(fabs(Average[i][j][k]) > 2*Sigma[i][j][k]) {
-		  Cmd << PixMap->DRS_to_Pixel(i,j,k)+" " << std::showpos << Correction << " ";
-		}
-	    break;
-
-	  case FB_Targets:  // Take average as new targets  
-	    Target[i][j][k] = Average[i][j][k];
-	    break;
-
-	  case FB_ResponseFirst:  // First point of response measurement done  
-	    Buffer[i][j][k] = Average[i][j][k];
-	    if(!PixMap->DRS_to_Pixel(i,j,k).empty()) {
-		  Cmd << PixMap->DRS_to_Pixel(i,j,k) << " " << std::showpos << DiffVoltage << " ";		  
-		}
-	    break;
-
-	  case FB_ResponseSecond: // Determine response from signal variation
-	    if(Buffer[i][j][k] == Average[i][j][k]) {
-	      m->PrintMessage("HV Feedback: Warning, response singular for board %d, chip %d, channel %d\n",i,j,k);
-	      Response[i][j][k] = 0;
-	    }
-	    else Response[i][j][k] = DiffVoltage/(Buffer[i][j][k]-Average[i][j][k]);
-	    if(!PixMap->DRS_to_Pixel(i,j,k).empty()) {
-		  Cmd << PixMap->DRS_to_Pixel(i,j,k) << " " << std::showpos << -DiffVoltage/2 << " ";		  		  
-		}
-	    break;
-
-	  default: break;  // to suppress warning abount not handled enumeration value
-        }			
-  } // for() channels
-  } // for() chips
-  } // for() boards
-
-  // Update DIM service
-  FeedbackAverage->updateService();
-  FeedbackSigma->updateService();
-
-  // Send command
-  if (!Cmd.str().empty()) {
-	DimClient::sendCommand("Bias/Command", ("hv "+Cmd.str()).c_str());
-  }
-
-  switch (FBMode) {
-    case FB_Targets:
-	  FeedbackTarget->updateService();
-      m->PrintMessage("HV Feedback: New targets set, switching off\n");
-      SetFBMode(FB_Off, true);
-      break;
-    case FB_ResponseFirst:
-      SetFBMode(FB_ResponseSecond, true);
-      m->PrintMessage("HV Feedback: Increasing voltages by %f for response measurement, acquiring data\n", DiffVoltage);
-      break;
-    case FB_ResponseSecond:
-	  FeedbackResponse->updateService();
-      m->PrintMessage("HV Feedback: Response measurements finished, original voltages set, switching off\n");
-      SetFBMode(FB_Off, true);
-      break;
-    default: break;  // to suppress warning abount not handled enumeration value
-  }
-  ClearAverages();
-  
-  return true;  
-}
-
-//
-// Clear average values and event counter
-//
-void HVFeedback::ClearAverages() {
-  for (int i=m->FirstBoard; i<=m->LastBoard; i++)
-    for (int j=0; j<fNumberOfChips; j++)
-      for (int k=0; k<fNumberOfChannels; k++) {
-        Average[i][j][k] = 0.0;
-		Sigma[i][j][k] = 0.0;
-      }
-  Count = 0;
-  CountService->updateService();
-}
-
-//
-// Number of events to accumulate before correction acts
-//
-void HVFeedback::SetNumAverages(unsigned int Averages) {
-  NumAverages = Averages;
-}
-
-//
-// Get requested number of events
-//
-unsigned int HVFeedback::GetNumAverages() {
-  return NumAverages;
-}
-
-//
-// Set feedback gain
-//
-void HVFeedback::SetGain(float FBGain) {
-  Gain = FBGain;
-}
-
-//
-// Get feedback gain
-//
-float HVFeedback::GetGain() {
-  return Gain;
-}
-
-//
-// Set feedback mode and clear averages
-//
-void HVFeedback::SetFBMode(FBState Mode, bool Internal) {
-  if((Mode==FB_ResponseFirst || Mode==FB_ResponseFirst) && !Internal)
-      m->PrintMessage("Start reponse measurement by calling MeasureResponse()\n");
-  else {
-    FBMode = Mode;
-	if (Mode != FB_ResponseFirst) m->PrintMessage("%s\n", FBState_Description[FBMode]);
-	else m->PrintMessage("%s (voltage difference %.3f)\n", FBState_Description[FBMode], DiffVoltage);
-    ClearAverages();
-	
-	// Update state service
-	State.State = FBMode;
-	strncpy(State.Text, FBState_Description[FBMode], sizeof(State.Text));
-	FeedbackState->updateService(&State, sizeof(State));
-  }
-}
-
-//
-// Get feedback mode
-//
-FBState HVFeedback::GetFBMode() {
-
-  m->PrintMessage("%s.\n", FBState_Description[FBMode]);
-  return FBMode;
-}
-
-//
-// Return current number of events
-//
-unsigned int HVFeedback::GetCurrentCount() {
-  return Count;
-}
-
-//
-// Set target values
-//
-void HVFeedback::SetTarget(int Board, int Chip, int Channel, float TargetVal) {
-
-  if(Board<m->NumBoards && Chip<fNumberOfChips && Channel<fNumberOfChannels) {
-    Target[Board][Chip][Channel] = TargetVal;
-	FeedbackTarget->updateService();
-  }
-  else printf("Invalid board, chip or channel number.\n");
-}
-
-//
-// Print target values
-//
-void HVFeedback::GetTargets() {
-  for (int i=m->FirstBoard; i<=m->LastBoard; i++)
-    for (int j=0; j<fNumberOfChips; j++) {
-      m->PrintMessage("Board %d, chip %d:",i,j);
-      for (int k=0; k<fNumberOfChannels; k++) m->PrintMessage(" %.2f",Target[i][j][k]);
-      m->PrintMessage("\n\r");
-    }
-}
-
-//
-// Measure response matrix
-//
-void HVFeedback::MeasureResponse(float U) {
-
-  std::stringstream Cmd;
-
-  if (U==0) {
-    m->PrintMessage("HV Feedback: Error, voltage difference must not non-zero.\n");
-    return;
-  }
-
-  for (int i=m->FirstBoard; i<=m->LastBoard; i++) { 
-  for (int j=0; j<fNumberOfChips; j++) { 
-  for (int k=0; k<fNumberOfChannels; k++) {
-	if(!PixMap->DRS_to_Pixel(i,j,k).empty()) {
-	  Cmd << PixMap->DRS_to_Pixel(i,j,k) << " " << std::showpos << -U/2 << " ";		  		  
-    }
-  }
-  }
-  }
-  
-  // Send command
-  if (!Cmd.str().empty()) {
-	DimClient::sendCommand("Bias/Command", ("hv "+Cmd.str()).c_str());
-  }
-
-  DiffVoltage = U;
-  SetFBMode(FB_ResponseFirst, true);
-  m->PrintMessage("HV Feedback: Decreasing voltages by %f for response measurement, acquiring data.\n",DiffVoltage/2);
-}
-
-//
-// Print response values
-//
-void HVFeedback::GetResponse() {
-  for (int i=m->FirstBoard; i<=m->LastBoard; i++) {
-    for (int j=0; j<fNumberOfChips; j++) {
-      m->PrintMessage("Board %d, chip %d:",i,j);
-      for (int k=0; k<fNumberOfChannels; k++) m->PrintMessage(" %.3f",Response[i][j][k]);
-      m->PrintMessage("\n\r");
-    }
-  }
-}
-
-//
-// Print feedback configuration
-//
-void HVFeedback::PrintConfig() {
-
-  m->PrintMessage("LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n"
-        "LedTrigSample: %d\tLedTrigThreshold: %.2f\n"
-        "LedSignalSample: %d\tLedBaselineSample: %d\tDefaultNumAverage: %d\n"
-        "IntHalfWidth:%u\n",
-    fLedTrigBoard, fLedTrigChip, fLedTrigChannel, fLedTrigSample,
-    fLedTrigThreshold, fLedSignalSample, fLedBaselineSample,
-    fDefaultNumAverage, fIntHalfWidth);
-}
Index: sdaq/HVFeedback.h
===================================================================
--- /drsdaq/HVFeedback.h	(revision 268)
+++ 	(revision )
@@ -1,83 +1,0 @@
-#ifndef HVFEEDBACK_H_SEEN
-#define HVFEEDBACK_H_SEEN
-
-#define BUF_LENGTH 1000
-
-#include <stdlib.h>
-#include <math.h>
-#include <sstream>
-#include <vector>
-
-#include "RawDataCTX.h"
-#include "DAQReadout.h"
-
-enum FBState {FB_Off, FB_Active, FB_Targets, FB_ResponseFirst, FB_ResponseSecond};
-
-class HVFeedback: public DimServer {
-
-    class DAQReadout *m;
-    class PixelMap *PixMap;
-    FBState FBMode;
-    
-    float (*Average)[kNumberOfChipsMax][kNumberOfChannelsMax];
-    float (*Sigma)[kNumberOfChipsMax][kNumberOfChannelsMax];
-    float (*Response)[kNumberOfChipsMax][kNumberOfChannelsMax];
-    float (*Target)[kNumberOfChipsMax][kNumberOfChannelsMax];
-    float (*Buffer)[kNumberOfChipsMax][kNumberOfChannelsMax];
-    float (*DIMAverage)[kNumberOfChipsMax][kNumberOfChannelsMax];
-    float (*DIMSigma)[kNumberOfChipsMax][kNumberOfChannelsMax];
-
-	DimService *FeedbackAverage;
-	DimService *FeedbackSigma;
-	DimService *FeedbackResponse;
-	DimService *FeedbackTarget;
-	DimService *CountService;
-	DimService *FeedbackState;
-
-	struct {
-      int State;
-	  char Text[BUF_LENGTH];
-	} State;
-
-	int NumAverages;	// Events to take before feedback acts
-	int Count;		// Number of currently integrated events
-    int LastServiceUpdate;
-
-    float Gain;     	    	// Feedback gain
-    float DiffVoltage;	    	// for response measurement	
-    char TextBuf[BUF_LENGTH];
-	
-    int fLedTrigBoard;
-    int fLedTrigChip;
-    int fLedTrigChannel;
-    int fLedTrigSample;
-    float fLedTrigThreshold;
-    int fLedSignalSample;
-    int fLedBaselineSample;
-    unsigned int fIntHalfWidth;
-    int fDefaultNumAverage;
-
-    int fNumberOfChannels;
-    int fNumberOfChips;
-    
-  public:
-    HVFeedback(class DAQReadout*);
-    ~HVFeedback();
-
-    bool ProcessEvent();
-    void SetTarget(int, int, int, float);
-    void GetTargets();
-    void SetGain(float);
-    float GetGain();
-    void SetNumAverages(unsigned int);
-    unsigned int GetNumAverages();
-    void SetFBMode(FBState, bool=false);
-    FBState GetFBMode();
-    unsigned int GetCurrentCount();
-    void MeasureResponse(float);
-    void GetResponse();
-    void ClearAverages();
-    void PrintConfig();
-};
-
-#endif
Index: /drsdaq/History.txt
===================================================================
--- /drsdaq/History.txt	(revision 268)
+++ /drsdaq/History.txt	(revision 269)
@@ -68,4 +68,8 @@
 18/5/2010	Rate of event service adjustable with command 'update'.
 21/5/2010	Fix so that 'exit' command also works as DimCommand.
-20/7/2010	Replaced mutex with Lock()/Unlock() from Evidence class, introduced DIM feedback state service,
-			streamlined PrintMessage(). 
+20/7/2010	Replaced mutex with Lock()/Unlock() from Evidence class, introduced DIM
+			feedback state service, streamlined PrintMessage().
+27/7/2010	Removed feedback from drsdaq. Feedback is now a separate DIM server and
+			invoked through a DIM command. Last revision with feedback integrated into
+			drsdaq is 264.
+			
Index: /drsdaq/Makefile
===================================================================
--- /drsdaq/Makefile	(revision 268)
+++ /drsdaq/Makefile	(revision 269)
@@ -10,5 +10,5 @@
 CC  	= g++   	# Compiler to use
 
-SOURCES = HVFeedback.cc DAQReadout.cc RawDataCTX.cc ../pixelmap/Pixel.cc ../pixelmap/PixelMap.cc DRS/DRS.cc DRS/mxml.c DRS/strlcpy.c drsdaq.cpp ../Evidence/Evidence.cc 
+SOURCES = DAQReadout.cc RawDataCTX.cc ../pixelmap/Pixel.cc ../pixelmap/PixelMap.cc DRS/DRS.cc DRS/mxml.c DRS/strlcpy.c drsdaq.cpp ../Evidence/Evidence.cc 
 OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))
 INCDIRS   = -I. -IDRS -I../pixelmap -I../Evidence -I$(DIMDIR)/dim
Index: /drsdaq/drsdaq.cpp
===================================================================
--- /drsdaq/drsdaq.cpp	(revision 268)
+++ /drsdaq/drsdaq.cpp	(revision 269)
@@ -19,5 +19,4 @@
 
 #include "DAQReadout.h"
-#include "HVFeedback.h"
 
 // Function prototypes
