diff --git a/MAC/APL/PIC/TBBDriver/src/ClearCmd.cc b/MAC/APL/PIC/TBBDriver/src/ClearCmd.cc
index f348d262e1da723a5faeb0fa806d032a3ba7a51d..8f62dd6c43dcb7d4c6e1c16fa0e3e172d7ffa374 100644
--- a/MAC/APL/PIC/TBBDriver/src/ClearCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/ClearCmd.cc
@@ -22,6 +22,7 @@
 
 #include <lofar_config.h>
 #include <Common/LofarLogger.h>
+#include <unistd.h>
 
 #include "ClearCmd.h"
 
@@ -93,27 +94,18 @@ void ClearCmd::sendTpEvent()
 // ----------------------------------------------------------------------------
 void ClearCmd::saveTpAckEvent(GCFEvent& event)
 {
-	// in case of a time-out, set error mask
-	if (event.signal == F_TIMER) {
-		;
-	}	else {
-		itsTPackE = new TPClearAckEvent(event);
-		
-		if ((itsTPackE->status >= 0xF0) && (itsTPackE->status <= 0xF6)) 
-			itsTBBackE->status_mask[getBoardNr()] |= (1 << (16 + (itsTPackE->status & 0x0F)));	
-		
-		// reset channel-information for selected board	
-		if (itsTPackE->status == 0) {
-			for (int channelnr = (getBoardNr() * 16); channelnr < ((getBoardNr() * 16) + 16); channelnr++) {
-				TS->setChSelected(channelnr, false);
-				TS->setChState(channelnr, 'F');
-				TS->setChStartAddr(channelnr, 0);
-				TS->setChPageSize(channelnr, 0);				
-			}
-		}
-		LOG_DEBUG_STR(formatString("Received ClearAck from boardnr[%d]", getBoardNr()));
-		delete itsTPackE;
+	itsTPackE = new TPClearAckEvent(event);
+	
+	if ((itsTPackE->status >= 0xF0) && (itsTPackE->status <= 0xF6)) 
+		itsTBBackE->status_mask[getBoardNr()] |= (1 << (16 + (itsTPackE->status & 0x0F)));	
+	
+	// reset channel-information for selected board	
+	if (itsTPackE->status == 0) {
+		TS->clearRcuSettings(getBoardNr());	
 	}
+	LOG_DEBUG_STR(formatString("Received ClearAck from boardnr[%d]", getBoardNr()));
+	delete itsTPackE;
+	
 	nextBoardNr();
 }
 
@@ -124,6 +116,6 @@ void ClearCmd::sendTbbAckEvent(GCFPortInterface* clientport)
 		if (itsTBBackE->status_mask[boardnr] == 0)
 			itsTBBackE->status_mask[boardnr] = TBB_SUCCESS;
 	}
-	
+	sleep(3);
 	clientport->send(*itsTBBackE);
 }
diff --git a/MAC/APL/PIC/TBBDriver/src/DriverSettings.cc b/MAC/APL/PIC/TBBDriver/src/DriverSettings.cc
index b25fcb0bcda0bbce2a23daa02d38f7da0139cfb6..58f46e019a4595b464597f7cc2644ed83ed4aaf8 100644
--- a/MAC/APL/PIC/TBBDriver/src/DriverSettings.cc
+++ b/MAC/APL/PIC/TBBDriver/src/DriverSettings.cc
@@ -198,6 +198,7 @@ void TbbSettings::setMaxBoards (int32 maxboards)
 	itsBoardInfo = new BoardInfo[itsMaxBoards];
 	
 	for (int nr = 0;nr < itsMaxBoards; nr++) {
+		itsBoardInfo[nr].setupState = boardReset;
 		itsBoardInfo[nr].memorySize = 0;
 		itsBoardInfo[nr].srcIp = "";
 		itsBoardInfo[nr].dstIp = "";
@@ -206,8 +207,8 @@ void TbbSettings::setMaxBoards (int32 maxboards)
 	}
 }
 
-//---- setActiveBoards ---------------------------
-void TbbSettings::setActiveBoards (uint32 activeboardsmask)
+//---- setActiveBoardsMask -----------------------
+void TbbSettings::setActiveBoardsMask (uint32 activeboardsmask)
 {
 	// clear rcu setting for boards not active anymore
 	uint32 mask;
@@ -220,6 +221,19 @@ void TbbSettings::setActiveBoards (uint32 activeboardsmask)
 	itsActiveBoardsMask = activeboardsmask;
 }
 
+//---- setActiveBoard ---------------------------
+void TbbSettings::setActiveBoard (int32 boardnr)
+{
+	itsActiveBoardsMask |= (1 << boardnr);
+}
+
+//---- resetActiveBoards ---------------------------
+void TbbSettings::resetActiveBoard (int32 boardnr)
+{
+	clearRcuSettings(boardnr);
+	itsActiveBoardsMask &= ~(1 << boardnr);
+}
+	
 //---- set Communication retries ----------------
 void TbbSettings::setMaxRetries(int32 retries)
 {
diff --git a/MAC/APL/PIC/TBBDriver/src/DriverSettings.h b/MAC/APL/PIC/TBBDriver/src/DriverSettings.h
index 741fc04a42c618990b9adec1a4054c0482de0cb0..0ae1dba66822f2186431dbdb7dc8bf8128be16b5 100644
--- a/MAC/APL/PIC/TBBDriver/src/DriverSettings.h
+++ b/MAC/APL/PIC/TBBDriver/src/DriverSettings.h
@@ -35,6 +35,8 @@
 namespace LOFAR {
   namespace TBB {
 
+enum SetupStateT {boardReset,boardCleared,boardFreed,boardReady};
+
 // info for all channels
 struct ChannelInfo
 {
@@ -61,11 +63,12 @@ struct ChannelInfo
 struct BoardInfo
 {
 	GCFPortInterface* port;
+	SetupStateT setupState; 
 	uint32	memorySize;
 	string	srcIp;
 	string	dstIp;
 	string	srcMac;
-	string	dstMac; 	
+	string	dstMac;
 };
 
 // forward declaration
@@ -120,6 +123,12 @@ public:
 	string getDstIp(int32 boardnr);
 	string getSrcMac(int32 boardnr);
 	string getDstMac(int32 boardnr);
+	SetupStateT getBoardState(int32 boardnr);
+	void setBoardState(int32 boardnr, SetupStateT setupstate);
+	void setActiveBoardsMask (uint32 activeboardsmask);
+	void setActiveBoard (int32 boardnr);
+	void resetActiveBoard (int32 boardnr);
+	
 
 	void setChSelected(int32 channelnr, bool selected);
 	void setChStatus(int32 channelnr, uint32 status);
@@ -135,6 +144,8 @@ public:
 	void setChTriggerDummy(int32 channelnr, uint32 dummy);
 	void setChFilterCoefficient(int32 channelnr, int32 coef_nr, uint32 coef);
 	
+	void clearRcuSettings(int32 boardnr);
+	
 	void convertRcu2Ch(int32 rcunr, int32 *boardnr, int32 *channelnr);
 	void convertCh2Rcu(int32 channelnr, int32 *rcunr);
 	bool isBoardActive(int32 boardnr);
@@ -150,11 +161,9 @@ protected:	// note TBBDriver must be able to set them
 	void getTbbSettings();
 	void setConversionTable(int32 rcu, int32 channel); 
 	void setMaxBoards (int32 maxboards);
-	void setActiveBoards (uint32 activeboardsmask);
 	void setMaxRetries(int32 retries);
 	void setTimeOut(double timeout);
 	void setBoardPorts(int board, GCFPortInterface* board_ports);
-	void clearRcuSettings(int32 boardnr);
 	
 private:
 	// Copying is not allowed
@@ -210,6 +219,9 @@ inline	double TbbSettings::timeout()	{ return (itsTimeOut);   }
 //inline	GCFPortInterface& TbbSettings::boardPort(int32 boardnr)	{ return (itsBoardPorts[boardnr]); }
 inline	GCFPortInterface& TbbSettings::boardPort(int32 boardnr)	{ return (*itsBoardInfo[boardnr].port); }
 
+inline	void TbbSettings::setBoardState(int32 boardnr, SetupStateT setupstate) { itsBoardInfo[boardnr].setupState = setupstate; }
+inline	SetupStateT TbbSettings::getBoardState(int32 boardnr) { return (itsBoardInfo[boardnr].setupState); }
+
 //---- inline functions for channel information ------------
 inline	bool TbbSettings::isChSelected(int32 channelnr) { return (itsChannelInfo[channelnr].Selected); }
 inline	uint32 TbbSettings::getChStatus(int32 channelnr) { return (itsChannelInfo[channelnr].Status); }
diff --git a/MAC/APL/PIC/TBBDriver/src/MsgHandler.cc b/MAC/APL/PIC/TBBDriver/src/MsgHandler.cc
index 80a7ddc012683e44723cd026e97122fead7e0d2a..59680e7ab8fdaa0f93e4cd34da61b80619584572 100644
--- a/MAC/APL/PIC/TBBDriver/src/MsgHandler.cc
+++ b/MAC/APL/PIC/TBBDriver/src/MsgHandler.cc
@@ -47,18 +47,16 @@ MsgHandler::~MsgHandler()
 //-----------------------------------------------------------------------------
 void MsgHandler::addClient(GCFPortInterface& port)
 {
-	itsClientMsgList.insert(&port);
-
-	//itsClientMsgList.push_back(&port);
-	//itsClientMsgList.sort();
-	//itsClientMsgList.unique();		
+	itsClientMsgList.push_back(&port);	// add client to list
+	
+	itsClientMsgList.sort();	// and remove double inputs
+	itsClientMsgList.unique();
 }
 
 //-----------------------------------------------------------------------------
 void MsgHandler::removeClient(GCFPortInterface& port)
 {
-	itsClientMsgList.erase(&port);
-	//itsClientMsgList.remove(&port);		
+	itsClientMsgList.remove(&port);	// remove client from list
 }
 
 //-----------------------------------------------------------------------------
@@ -66,7 +64,7 @@ void MsgHandler::sendTrigger(GCFEvent& event, int boardnr)
 {
 	TPTriggerEvent	*TPE;
 	TPE	= new TPTriggerEvent(event);
-	int channel = TPE->trigger.channel + (boardnr * TS->maxBoards());	
+	int channel = TPE->trigger.channel + (boardnr * TS->nrChannelsOnBoard());	
 	TS->convertCh2Rcu(channel, &itsTriggerE->rcu);
 	itsTriggerE->sequence_nr			=	TPE->trigger.sequence_nr;
 	itsTriggerE->time							=	TPE->trigger.time;
@@ -105,7 +103,7 @@ void MsgHandler::sendBoardChange(uint32 activeboards)
 void MsgHandler::sendMessage(GCFEvent& event)
 {
   if (!itsClientMsgList.empty()) {
-    for (set<GCFPortInterface*>::iterator it = itsClientMsgList.begin();
+    for (list<GCFPortInterface*>::iterator it = itsClientMsgList.begin();
          it != itsClientMsgList.end();
          it++)
     {
diff --git a/MAC/APL/PIC/TBBDriver/src/MsgHandler.h b/MAC/APL/PIC/TBBDriver/src/MsgHandler.h
index 0643f1793f18ce89d0681ebc0435368e03b51797..f62fd07db8464581fefa56466236b38909bab63b 100644
--- a/MAC/APL/PIC/TBBDriver/src/MsgHandler.h
+++ b/MAC/APL/PIC/TBBDriver/src/MsgHandler.h
@@ -65,7 +65,7 @@ namespace LOFAR {
 			private:
 				TbbSettings *TS;
 				
-				std::set<GCFPortInterface*> itsClientMsgList;  // list of clients witch receive messages
+				std::list<GCFPortInterface*> itsClientMsgList;  // list of clients witch receive messages
 				
 				TBBTriggerEvent			*itsTriggerE;
 				TBBErrorEvent				*itsErrorE;
diff --git a/MAC/APL/PIC/TBBDriver/src/ReadrCmd.cc b/MAC/APL/PIC/TBBDriver/src/ReadrCmd.cc
index 4b9c98b289f40825a50cd0cc2380117b36ea5390..ae1254917612291e7d9f802d5e7df6ea2ca5b664 100644
--- a/MAC/APL/PIC/TBBDriver/src/ReadrCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/ReadrCmd.cc
@@ -99,7 +99,7 @@ void ReadrCmd::saveTpAckEvent(GCFEvent& event)
 		itsTPackE = new TPReadrAckEvent(event);
 		
 		itsBoardStatus	= itsTPackE->status;
-		for (int32 an = 0; an < 512;an++) {
+		for (int32 an = 0; an < 256;an++) {
 			itsTBBackE->data[an]	= itsTPackE->data[an];
 		}
 		
diff --git a/MAC/APL/PIC/TBBDriver/src/RecordCmd.cc b/MAC/APL/PIC/TBBDriver/src/RecordCmd.cc
index 1930c8927280b693e13ed6cb376e7c8788919b77..6a6b0dbc40c62b40de7fd9d144cb742737b868e8 100644
--- a/MAC/APL/PIC/TBBDriver/src/RecordCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/RecordCmd.cc
@@ -80,8 +80,8 @@ void RecordCmd::saveTbbEvent(GCFEvent& event)
 			if ((TS->getChState(channel) == 'A') || (TS->getChState(channel) == 'S')) {
 				itsChannelMask[board] |= (1 << board_channel);
 				TS->setChSelected(channel,true);
-				
-			} else {
+			}
+			if (TS->getChState(channel) == 'F') {
 				TS->setChStatus(channel,(uint16)(TBB_RCU_NOT_ALLOCATED >> 16));
 			}
 		}
diff --git a/MAC/APL/PIC/TBBDriver/src/ResetCmd.cc b/MAC/APL/PIC/TBBDriver/src/ResetCmd.cc
index ce01155a95227f855c22fb0c1539bc7b514c02a5..65e99f75644a25052c7c9b920b8988006befc10f 100644
--- a/MAC/APL/PIC/TBBDriver/src/ResetCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/ResetCmd.cc
@@ -22,6 +22,7 @@
 
 #include <lofar_config.h>
 #include <Common/LofarLogger.h>
+#include <unistd.h>
 
 #include "ResetCmd.h"
 
@@ -64,47 +65,37 @@ bool ResetCmd::isValid(GCFEvent& event)
 // ----------------------------------------------------------------------------
 void ResetCmd::saveTbbEvent(GCFEvent& event)
 {
+	uint32	boardmask = 0;
+	
 	itsTBBE	= new TBBResetEvent(event);
 	itsTPE->opcode			= TPRESET;
 	itsTPE->status			=	0;
 		
 	for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) {
 		if (itsTBBE->boardmask & (1 << boardnr)) {
-			if (TS->boardPort(boardnr).isConnected())
+			boardmask |= (1 << boardnr);
+			if (TS->boardPort(boardnr).isConnected()) {
 				TS->boardPort(boardnr).send(*itsTPE);
-			
-			// reset channel information for selected board	
-			for (int channelnr = (boardnr * 16); channelnr < ((boardnr * 16) + 16); channelnr++) {
-				TS->setChSelected(channelnr, false);
-				TS->setChState(channelnr, 'F');
-				TS->setChStartAddr(channelnr, 0);
-				TS->setChPageSize(channelnr, 0);				
 			}
 		} 
 	}
-	delete itsTBBE;	
+	TS->setActiveBoardsMask(boardmask);
 	setDone(true);
+	delete itsTBBE;	
 }
 
 // ----------------------------------------------------------------------------
 void ResetCmd::sendTpEvent()
 {
-	// sending reset is done in saveTbbEvent()
-	// because sendTpEvent() is only posible for active boards
+	// empty
 }
 
 // ----------------------------------------------------------------------------
 void ResetCmd::saveTpAckEvent(GCFEvent& event)
 {
-	// in case of a time-out, set error mask
-	if (event.signal == F_TIMER) {
-		;
-	}
-	else {
-		itsTPackE = new TPResetAckEvent(event);
-		
-		delete itsTPackE;
-	}
+	//itsTPackE = new TPResetAckEvent(event);
+	//delete itsTPackE;
+	setDone(true);
 }
 
 // ----------------------------------------------------------------------------
@@ -114,6 +105,6 @@ void ResetCmd::sendTbbAckEvent(GCFPortInterface* clientport)
 		if (itsTBBackE->status_mask[boardnr] == 0)
 			itsTBBackE->status_mask[boardnr] = TBB_SUCCESS;
 	}
-	
+	sleep(3);
 	clientport->send(*itsTBBackE);
 }
diff --git a/MAC/APL/PIC/TBBDriver/src/StopCmd.cc b/MAC/APL/PIC/TBBDriver/src/StopCmd.cc
index 6519b16a049597d17a6ffd7b55689ea0a533db41..787f63236a1a367c42a41342c40d642770e5e9eb 100644
--- a/MAC/APL/PIC/TBBDriver/src/StopCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/StopCmd.cc
@@ -88,9 +88,8 @@ void StopCmd::saveTbbEvent(GCFEvent& event)
 	
 	uint32 boardmask = 0;		
 	for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) {
-		if (itsChannelMask[boardnr] != 0) boardmask |= (1 << boardnr); 
-			
 		if (!TS->isBoardActive(boardnr)) { 
+			if (itsChannelMask[boardnr] != 0) boardmask |= (1 << boardnr);
 			itsTBBackE->status_mask[boardnr] |= TBB_NO_BOARD;
 		}
 		
diff --git a/MAC/APL/PIC/TBBDriver/src/TBBDriver.cc b/MAC/APL/PIC/TBBDriver/src/TBBDriver.cc
index 2ec9d9d58e818333c5da9bb8c91d5b7b45a06bee..9c391d5e7e6284f74a627e9edbc296ad7d31a632 100644
--- a/MAC/APL/PIC/TBBDriver/src/TBBDriver.cc
+++ b/MAC/APL/PIC/TBBDriver/src/TBBDriver.cc
@@ -24,8 +24,11 @@
 #include <lofar_config.h>
 #include <Common/LofarLogger.h>
 #include <Common/LofarLocators.h>
+#include <APL/RTCCommon/daemonize.h>
 #include <APS/ParameterSet.h>
 #include <GCF/GCF_ServiceInfo.h>
+
+#include <getopt.h>
 //#include <string>
 
 #include "TBBDriver.h"
@@ -68,17 +71,17 @@ using namespace GCFCommon;
 using namespace ACC::APS;
 using namespace TBB;
 
-static int32    g_instancenr = -1;
+static bool   itsDaemonize  = false;
+static int32	itsInstancenr = -1;
 
 static const long ALIVECHECKTIME = 60;
 
-/*
+
 //
 // parseOptions
 //
 void parseOptions(int argc, char** argv)
 {
-
 	static struct option long_options[] = {
 		{ "instance",   required_argument, 0, 'I' },
 		{ "daemon",     no_argument,       0, 'd' },
@@ -86,32 +89,30 @@ void parseOptions(int argc, char** argv)
 	};
 
 	optind = 0; // reset option parsing
-	for(;;)
-	{
+	for(;;) {
 		int option_index = 0;
 		int c = getopt_long(argc, argv, "dI:", long_options, &option_index);
 
-		if (c == -1)
-		{
+		if (c == -1) {
 			break;
 		}
 
-		switch (c)
-		{
-			case 'I':   // --instance
-				g_instancenr = atoi(optarg);
-				break;
-			case 'd':   // --daemon
-				g_daemonize = true;
-				break;
-			default:
-				LOG_FATAL (formatString("Unknown option %c", c));
+		switch (c) {
+			case 'I': {   // --instance
+				itsInstancenr = atoi(optarg);
+			}	break;
+			
+			case 'd': {   // --daemon
+				itsDaemonize = true;
+			}	break;
+			
+			default: {
+				LOG_FATAL_STR("Unknown option " << c);
 				ASSERT(false);
+			}
 		}
 	}
-
 }
-*/
 
 //-----------------------------------------------------------------------------		
 TBBDriver::TBBDriver(string name)
@@ -125,25 +126,28 @@ TBBDriver::TBBDriver(string name)
   
 	cmd = 0;
 	itsActiveBoards = 0;
+	itsNewBoards = 0;
 	itsAliveCheck = false;
 	itsActiveBoardsChange = false;
 	itsResetCount = 0;
   
   // tell broker we are here
-  LOG_DEBUG("Registering protocols");
+  LOG_DEBUG_STR("Registering protocols");
   registerProtocol(TBB_PROTOCOL, TBB_PROTOCOL_signalnames);
   registerProtocol(TP_PROTOCOL, TP_PROTOCOL_signalnames);
 
   // open client port
-  LOG_DEBUG("Opening listener for clients");
-  string  acceptorID;
-  if (g_instancenr>=0) {
-	 acceptorID = formatString("(%d)", g_instancenr);
+  LOG_DEBUG_STR("Opening listener for clients");
+	
+	string  acceptorID;
+  if (itsInstancenr >= 0) {
+	 acceptorID = formatString("(%d)", itsInstancenr);
   }
+	
   itsAcceptor.init(*this, MAC_SVCMASK_TBBDRIVER + acceptorID, GCFPortInterface::MSPP, TBB_PROTOCOL);
 
   // open port with TBB board
-  LOG_DEBUG("Connecting to TBB boards");
+  LOG_DEBUG_STR("Connecting to TBB boards");
 	itsBoard = new GCFETHRawPort[TS->maxBoards()];
   ASSERT(itsBoard);
 	
@@ -166,6 +170,7 @@ TBBDriver::TBBDriver(string name)
 	}
 	
 	itsAliveTimer = new GCFTimerPort(*this, "AliveTimer");
+	itsSetupTimer = new GCFTimerPort(*this, "SetupTimer");
 	
 	 // create cmd & msg handler
 	LOG_DEBUG_STR("initializing handlers");
@@ -190,6 +195,7 @@ TBBDriver::~TBBDriver()
 {
 	delete [] itsBoard;
 	delete itsAliveTimer;
+	delete itsSetupTimer;
 	delete cmdhandler;
 	delete msghandler;
 	delete [] itsResetCount;
@@ -208,13 +214,16 @@ GCFEvent::TResult TBBDriver::init_state(GCFEvent& event, GCFPortInterface& port)
 			if (itsAcceptor.isConnected())
 				itsAcceptor.close();
 		} break;
+		
+		case F_EXIT: {
+		} break;
         
 		case F_ENTRY:	{
 			openBoards();
 		}	break;
 		
 		case F_CONNECTED: {
-      LOG_INFO_STR(formatString("CONNECTED: port '%s'", port.getName().c_str()));
+      LOG_DEBUG_STR("CONNECTED: port " << port.getName());
 			
 			if (isEnabled() && !itsAcceptor.isConnected()) {
  				itsAcceptor.open();
@@ -222,7 +231,6 @@ GCFEvent::TResult TBBDriver::init_state(GCFEvent& event, GCFPortInterface& port)
 			if (itsAcceptor.isConnected()) {
 				TRAN(TBBDriver::idle_state);
       }
-      
     } break;
 		
 		case F_TIMER: {
@@ -237,7 +245,148 @@ GCFEvent::TResult TBBDriver::init_state(GCFEvent& event, GCFPortInterface& port)
 	}
 	return(status);
 }
+
+
+//-----------------------------------------------------------------------------
+GCFEvent::TResult TBBDriver::setup_state(GCFEvent& event, GCFPortInterface& port)
+{
+	GCFEvent::TResult status = GCFEvent::HANDLED;
+	static int boardnr;
+	static int retries;
+	
+	switch(event.signal) {
+		case F_INIT: {
+			boardnr = 0;
+			retries = 0;
+		} break;
+		
+		case F_EXIT: {
+		} break;
+        
+		case F_ENTRY:	{
+			itsSetupTimer->setTimer((long)0);
+		}	break;
+		
+		case F_CONNECTED: {
+    } break;
+		
+		case F_TIMER: {
+    	if (&port == itsSetupTimer) {
+	    	if (itsNewBoards & (1 << boardnr)) {
+		    	switch (TS->getBoardState(boardnr)) {
+		    		case boardReset: {
+		    			TPClearEvent clear;
+		 					clear.opcode = TPCLEAR;
+		 					clear.status = 0;
+							itsBoard[boardnr].send(clear);
+							itsBoard[boardnr].setTimer(TS->timeout());	
+							LOG_DEBUG_STR("CLEAR is send to port '" << itsBoard[boardnr].getName() << "'");
+		    		} break;
+		    		
+		    		case boardCleared: {
+		    			TPFreeEvent free;
+		 					free.opcode = TPFREE;
+		 					free.status = 0;
+		 					free.channel = 0xFFFFFFFF;  // send channel = -1 to free all inputs
+							itsBoard[boardnr].send(free);
+							itsBoard[boardnr].setTimer(TS->timeout());	
+							LOG_DEBUG_STR("FREE -1 is send to port '" << itsBoard[boardnr].getName() << "'");
+		    		} break;
+		    		
+		    		case boardFreed: {
+		    			TS->setBoardState(boardnr,boardReady);
+		    			itsNewBoards &= ~(1 << boardnr);
+		    			LOG_DEBUG_STR("'" << itsBoard[boardnr].getName() << "' is Ready");
+		    			itsNewBoards = 0;
+		    			boardnr++;
+		    			retries = 0;
+		    			itsBoard[boardnr].setTimer((long)0);
+		    		} break;
+		    		
+		    		case boardReady: {
+		    		
+		    		} break;
+		    		
+		    		default: break;
+		    	}
+	    	} else {
+	    		boardnr++;
+	    		itsSetupTimer->setTimer((long)0);
+	    	}
+    	} else {
+    		retries++;
+    		if (retries == TS->maxRetries()) {
+    			TS->setBoardState(boardnr,boardReset);
+    			itsNewBoards &= ~(1 << boardnr);
+    			TS->resetActiveBoard(boardnr);    			 
+    			boardnr++;
+    		}
+    		itsSetupTimer->setTimer((long)0);
+    	}
+    	if (boardnr == TS->maxBoards()) { 
+	    		TRAN(TBBDriver::idle_state);
+	    }
+    } break;
+		
+		case F_DATAIN: {
+			status = RawEvent::dispatch(*this, port);	
+		}	break;
+		
+		case TP_CLEAR_ACK: {
+			itsBoard[boardnr].cancelAllTimers();
+			TS->setBoardState(boardnr,boardCleared);
+			itsSetupTimer->setTimer((long)3);		
+    } break;
+		
+		case TP_FREE_ACK: {
+			itsBoard[boardnr].cancelAllTimers();
+    	TS->setBoardState(boardnr,boardFreed);
+			itsSetupTimer->setTimer((long)0);		
+    } break;
+		
+		case TP_ALLOC:	
+		case TP_FREE:
+		case TP_RECORD: 
+		case TP_STOP:
+		case TP_TRIG_RELEASE:
+		case TP_TRIG_GENERATE:
+		case TP_TRIG_SETUP:
+		case TP_TRIG_COEF:
+		case TP_TRIG_INFO:				
+		case TP_READ:
+		case TP_UDP:
+		case TP_PAGEPERIOD:	
+		case TP_VERSION:
+		case TP_STATUS:
+		case TP_CLEAR:
+		case TP_SIZE:	
+		case TP_RESET:
+		case TP_CONFIG:
+		case TP_ERASEF:
+		case TP_READF:
+		case TP_WRITEF:
+		case TP_READW:
+		case TP_WRITEW:
+		case TP_READR:
+		case TP_WRITER:
+		case TP_READX: {
+			// put event on the queue
+			TbbEvent tbbevent;
+			tbbevent.length = event.length;
+			tbbevent.event = new uint8[tbbevent.length];
+			memcpy(tbbevent.event, &event, tbbevent.length);			
+			//tbbevent.signal = event.signal;
+			tbbevent.port = &port;
+			itsTbbQueue->push_back(tbbevent);	
+		} break;
+							 
+		default: {
+			status = GCFEvent::NOT_HANDLED;
+		}	break;
+	}
 	
+	return(status);
+}	
 
 //-----------------------------------------------------------------------------
 // idle(event, port)
@@ -247,15 +396,29 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
 	LOG_DEBUG_STR("idle:" << evtstr(event) << "@" << port.getName());
 	
 	GCFEvent::TResult status = GCFEvent::HANDLED;
-  undertaker();
-  
+    
 	switch(event.signal) {
 		case F_INIT: {
 		} break;
+    
+    case F_EXIT: {
+		} break;
         
 		case F_ENTRY:	{
 			LOG_DEBUG_STR("Entering Idle State");
-			// look if there is an Tbb command in queue
+			// if no tbb boards start check-alive
+			if (itsActiveBoards == 0) {
+				itsAliveTimer->setTimer((long)0);
+				break;
+			} 
+						
+			// if new boards detected set them up
+			if (itsNewBoards != 0) {
+				TRAN(TBBDriver::setup_state);
+				break;
+			}
+			
+			// look if there is an Tbb command in queue	
 			if (!itsTbbQueue->empty()) {
 				LOG_DEBUG_STR("The queue is NOT empty");
 				
@@ -267,27 +430,22 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
 				itsTbbQueue->pop_front();
 				TRAN(TBBDriver::busy_state);
 			}
-			// if no tbb boards start check-alive
-			if (itsActiveBoards == 0) {
-				itsAliveTimer->setTimer((long)0);
-			} 
 		}	break;
         
 		case F_CONNECTED:	{
-			LOG_DEBUG_STR(formatString("CONNECTED: port '%s'", port.getName().c_str()));
+			LOG_DEBUG_STR("CONNECTED: port '" << port.getName() << "'");
 		}	break;
 		
 		case F_DISCONNECTED: {
-			
-			LOG_DEBUG_STR(formatString("DISCONNECTED: port '%s'", port.getName().c_str()));
+			LOG_DEBUG_STR("DISCONNECTED: port ''" << port.getName() << "'");
       port.close();
       		
 			if (&port == &itsAcceptor) {
-        LOG_FATAL("Failed to start listening for client connections.");
+        LOG_FATAL_STR("Failed to start listening for client connections.");
         exit(EXIT_FAILURE);
       } else {
 				itsClientList.remove(&port);
-        itsDeadClients.push_back(&port);
+				msghandler->removeClient(port);
       }
 		} break;
 		
@@ -297,7 +455,7 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
       itsAcceptor.accept(*client);
       itsClientList.push_back(client);
 
-      LOG_DEBUG_STR(formatString("NEW CLIENT CONNECTED: %d clients connected", itsClientList.size()));
+			LOG_DEBUG_STR("NEW CLIENT CONNECTED: " << itsClientList.size() << " clients connected");
 		} break;
 		
 		case F_DATAIN: {
@@ -308,11 +466,15 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
 			if (&port == itsAliveTimer) {
 				CheckAlive(event, port);
 			}
-			
+			// if new boards detected set them up
+			if (itsAliveCheck == false && itsNewBoards != 0) {
+				LOG_DEBUG_STR("new boards: " << itsNewBoards);
+				TRAN(TBBDriver::setup_state);
+			}
 		} break;
 		
 		case TP_ALIVE_ACK: {
-			LOG_DEBUG("TP_ALIVE_ACK received");
+			LOG_DEBUG_STR("TP_ALIVE_ACK received");
 			CheckAlive(event, port);
 		} break;
 				
@@ -381,7 +543,7 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
 			}
 		}	break;
 	}
-	LOG_DEBUG_STR("leaving??");
+	
 	return(status);
 }
 
@@ -392,18 +554,40 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port)
 {
 	GCFEvent::TResult status = GCFEvent::HANDLED;    
 	
-	LOG_DEBUG_STR(formatString("busy_state signal = [%d]",event.signal));
+	LOG_DEBUG_STR("busy_state signal = [" << event.signal << "]");
 	switch(event.signal) {
 		case F_INIT: {
 		} break;
 		
+		case F_EXIT: {
+		} break;
+		
 		case F_ENTRY: {
 		}	break;
 		
 		case F_ACCEPT_REQ: {
+			GCFTCPPort* client = new GCFTCPPort();
+			client->init(*this, "client", GCFPortInterface::SPP, TBB_PROTOCOL);
+      itsAcceptor.accept(*client);
 		}	break;
 		
 		case F_CONNECTED:	{
+			LOG_DEBUG_STR("CONNECTED: port '" << port.getName() << "'");
+		}	break;
+		
+		case F_DISCONNECTED: {
+			LOG_DEBUG_STR("DISCONNECTED: port '" << port.getName() << "'");
+      port.close();
+      		
+			if (&port == &itsAcceptor) {
+        LOG_FATAL_STR("Failed to start listening for client connections.");
+        exit(EXIT_FAILURE);
+      } else {
+				itsClientList.remove(&port);
+				msghandler->removeClient(port);
+      }
+			itsAcceptor.setTimer((long)1);
+			TRAN(TBBDriver::idle_state);	
 		}	break;
 		
 		case F_TIMER: {
@@ -413,17 +597,9 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port)
 				} else {
 					itsAliveTimer->setTimer(ALIVECHECKTIME);
 				}
+			} else {
+				status = cmdhandler->dispatch(event,port); // dispatch time-out event	
 			}
-
-			status = cmdhandler->dispatch(event,port); // dispatch time-out event	
-		} break;
-		
-		case F_DISCONNECTED: {
-			itsAcceptor.setTimer((long)1);
-			TRAN(TBBDriver::idle_state);	
-		}	break;
-		
-		case F_EXIT: {
 		} break;
 		
 		case F_DATAIN: {
@@ -500,26 +676,51 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port)
 				TRAN(TBBDriver::idle_state);
 			}
 		}	break;	
-										
+		
+		case TP_ALLOC:	
+		case TP_FREE:
+		case TP_RECORD: 
+		case TP_STOP:
+		case TP_TRIG_RELEASE:
+		case TP_TRIG_GENERATE:
+		case TP_TRIG_SETUP:
+		case TP_TRIG_COEF:
+		case TP_TRIG_INFO:				
+		case TP_READ:
+		case TP_UDP:
+		case TP_PAGEPERIOD:	
+		case TP_VERSION:
+		case TP_STATUS:
+		case TP_CLEAR:
+		case TP_SIZE:	
+		case TP_RESET:
+		case TP_CONFIG:
+		case TP_ERASEF:
+		case TP_READF:
+		case TP_WRITEF:
+		case TP_READW:
+		case TP_WRITEW:
+		case TP_READR:
+		case TP_WRITER:
+		case TP_READX: {
+			// put event on the queue
+			TbbEvent tbbevent;
+			tbbevent.length = event.length;
+			tbbevent.event = new uint8[tbbevent.length];
+			memcpy(tbbevent.event, &event, tbbevent.length);			
+			//tbbevent.signal = event.signal;
+			tbbevent.port = &port;
+			itsTbbQueue->push_back(tbbevent);	
+		} break;								
+		
 		default: {
-			LOG_DEBUG("DEFAULT");
-			if (cmdhandler->tpCmdDone() == true){
-				// set ALIVE timer, and check for resets
-				//if (!itsAliveCheck) {
-				//	itsAliveTimer->setTimer((long)2);
-				//	itsAliveCheck = false;
-				//}
-				TRAN(TBBDriver::idle_state);
-			} else {
+			LOG_DEBUG_STR("DEFAULT");
 			
-				// put event on the queue
-				TbbEvent tbbevent;
-				tbbevent.length = event.length;
-				tbbevent.event = new uint8[tbbevent.length];
-				memcpy(tbbevent.event, &event, tbbevent.length);			
-				//tbbevent.signal = event.signal;
-				tbbevent.port = &port;
-				itsTbbQueue->push_back(tbbevent);
+			if (itsClientList.empty()) {
+				if (cmd) delete cmd;
+				itsAliveTimer->setTimer((long)1);
+				itsAliveCheck = false;
+				TRAN(TBBDriver::idle_state);
 			}
 			status = GCFEvent::NOT_HANDLED;
 		}	break;
@@ -527,18 +728,6 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port)
 	return(status);
 }
 
-//-----------------------------------------------------------------------------
-void TBBDriver::undertaker()
-{
-  for (list<GCFPortInterface*>::iterator it = itsDeadClients.begin();
-       it != itsDeadClients.end();
-       it++)
-  {
-    delete (*it);
-  }
-  itsDeadClients.clear();
-}
-
 //-----------------------------------------------------------------------------
 // openBoards()
 //
@@ -570,7 +759,7 @@ bool TBBDriver::isEnabled()
 }
 
 //-----------------------------------------------------------------------------
-bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
+bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& /*port*/)
 {
 	//bool done = false;
 	static int32 boardnr;
@@ -595,20 +784,8 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 		if (event.signal == TP_ALIVE_ACK){
 			// new board, send free and clear cmd 
 			if ((itsActiveBoards & (1 << boardnr)) == 0) {  // is it a new board ??
- 				// free all inputs on all boards
- 				TPFreeEvent free;
- 				free.opcode = TPFREE;
- 				free.status = 0;
- 				free.channel = 0xFFFFFFFF;  // send channel = -1 to free all inputs
-				itsBoard[boardnr].send(free);	
-				LOG_DEBUG_STR(formatString("FREE -1 is send to port '%s'", itsBoard[boardnr].getName().c_str()));
-				
-				// clear all boards(FPGA register are set to 0 and firmware is maintained)
- 				TPClearEvent clear;
- 				clear.opcode = TPCLEAR;
- 				clear.status = 0;
-				itsBoard[boardnr].send(clear);	
- 				LOG_DEBUG(formatString("CLEAR is send to port '%s'", itsBoard[boardnr].getName().c_str()));
+ 				itsNewBoards |= (1 << boardnr);
+ 				TS->setBoardState(boardnr,boardReset);
 			}
 			
 			activeboards |= (1 << boardnr);
@@ -616,7 +793,7 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 			if (ack.resetflag == 0){
 				itsResetCount[boardnr]++;
 				TS->clearRcuSettings(boardnr);
-				LOG_INFO_STR(formatString("=BOARD-RESET=, TBB board %d has been reset %d times",boardnr,itsResetCount[boardnr]));
+				LOG_INFO_STR("=BOARD-RESET=, TBB board " << boardnr << " has been reset " << itsResetCount[boardnr] << " times");
 			}
 		}
 		boardnr++;
@@ -629,24 +806,22 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 	if (checkmask == 0) {
 		if (activeboards != itsActiveBoards) {
 			itsActiveBoards = activeboards;
-			TS->setActiveBoards(itsActiveBoards);
+			TS->setActiveBoardsMask(itsActiveBoards);
+			
 			itsActiveBoardsChange = true;
 		
-			string boardstr;
-			for (int i = 0; i < 12; i++) {
-				boardstr += " ";
+			char boardstr[40];
+			char instr[5];
+			strcpy(boardstr,"");
+			for (int i = 0; i < TS->maxBoards(); i++) {
 				if (activeboards & (1 << i)) {
-					if (i >= 9) {
-						boardstr += "1";
-						boardstr += i+38;
-					} else {			
-						boardstr += i+48;
-					}
+					sprintf(instr," %d",i);
+					strcat(boardstr,instr);
 				} else {
-					boardstr += ".";
+					strcat(boardstr," .");
 				}
 			}
-			LOG_INFO_STR("Available TBB boards changed:" + boardstr);	
+			LOG_INFO_STR("Available TBB boards changed:" << boardstr);	
 		}
 		LOG_DEBUG_STR("Active TBB boards check");
 		if (itsActiveBoards == 0) {
@@ -853,30 +1028,29 @@ int main(int argc, char** argv)
 {
   LOFAR::GCF::TM::GCFTask::init(argc, argv);    // initializes log system
   
-	/*
-	LOG_INFO(formatString("Starting up %s", argv[0]));
+	LOG_INFO_STR("Starting up " << argv[0]);
   
   // adopt commandline switches
-  LOG_DEBUG("Parsing options");
+  LOG_DEBUG_STR("Parsing options");
   parseOptions (argc, argv);
   
   // daemonize if required 
-  if (g_daemonize) {
-	 if (0 != daemonize(false)) {
+  if (itsDaemonize) {
+		LOG_DEBUG_STR("background this process");
+		if (daemonize(false) == 0) {
 		cerr << "Failed to background this process: " << strerror(errno) << endl;
 		exit(EXIT_FAILURE);
 	 }
   }
-	*/
-  LOG_DEBUG ("Reading configuration files");
+	
+  LOG_DEBUG_STR("Reading configuration files");
   try {
   	LOFAR::ConfigLocator cl;
-		//LOFAR::ACC::APS::globalParameterSet()->adoptFile(cl.locate("RemoteStation.conf"));
 		LOFAR::ACC::APS::globalParameterSet()->adoptFile(cl.locate("TBBDriver.conf"));
 	}
 	catch (LOFAR::Exception e) {
 		LOG_ERROR_STR("Failed to load configuration files: " << e.text());
-		//exit(EXIT_FAILURE);
+		exit(EXIT_FAILURE);
 	}
   
 	LOFAR::TBB::TBBDriver tbb("TBBDriver");
diff --git a/MAC/APL/PIC/TBBDriver/src/TBBDriver.conf.in b/MAC/APL/PIC/TBBDriver/src/TBBDriver.conf.in
index 7d286e5fa37e446eedb6566474f93e3515e81a47..ef7361008df3270d86b56ce39c967c20e4bbb0ef 100644
--- a/MAC/APL/PIC/TBBDriver/src/TBBDriver.conf.in
+++ b/MAC/APL/PIC/TBBDriver/src/TBBDriver.conf.in
@@ -11,8 +11,8 @@ TBBDriver.IF_NAME=eth1
 #
 # Communication settings for TBB boards
 #
-TBBDriver.TP_RETRIES=2
-TBBDriver.TP_TIMEOUT=1.0
+TBBDriver.TP_RETRIES=5
+TBBDriver.TP_TIMEOUT=0.5
 
 #
 # Specify the MAC addresses of all TBB boards
diff --git a/MAC/APL/PIC/TBBDriver/src/TBBDriver.h b/MAC/APL/PIC/TBBDriver/src/TBBDriver.h
index 68a69d9ed194c4ed70cc3799ddb1528daebbc00a..5f6356270cd7bc619214a0efa7d2123ee80b4404 100644
--- a/MAC/APL/PIC/TBBDriver/src/TBBDriver.h
+++ b/MAC/APL/PIC/TBBDriver/src/TBBDriver.h
@@ -70,6 +70,10 @@ namespace LOFAR{
 			// and transition to the busy state is made.
       GCFEvent::TResult init_state(GCFEvent& event, GCFPortInterface &port);
       
+      // The setup state. 
+			// This state is used to setup the boards after a new connection or 
+      // board reset, if completed an transition to the idle state is made.
+      GCFEvent::TResult setup_state(GCFEvent& event, GCFPortInterface &port);
       
       // The idle state. 
 			// This state is used to wait for events from the client
@@ -83,7 +87,7 @@ namespace LOFAR{
 			// All TPEvent will be transmittted imediallie
       GCFEvent::TResult busy_state(GCFEvent& event, GCFPortInterface &port);
 			
-			void undertaker();
+			//void undertaker();
 		
     private:
       // Copying is not allowed ??
@@ -105,6 +109,7 @@ namespace LOFAR{
 			bool							itsAliveCheck;
 			bool							itsSizeCheck;
 			uint32						itsActiveBoards;
+			uint32						itsNewBoards;
 			bool							itsActiveBoardsChange;
 			int32 						*itsResetCount;
 			
@@ -120,9 +125,8 @@ namespace LOFAR{
 			GCFTCPPort      itsAcceptor;     // listen for clients on this port
 			GCFETHRawPort*	itsBoard;        // array of ports, one for each TBB board
 			GCFTimerPort*		itsAliveTimer;
-			  
+			GCFTimerPort*		itsSetupTimer;
 			std::list<GCFPortInterface*> itsClientList;  // list of clients
-			std::list<GCFPortInterface*> itsDeadClients; // list of clients to cleanup
     };
 	} // end TBB namespace
 } // end LOFAR namespace
diff --git a/MAC/APL/PIC/TBBDriver/src/TrigCoefCmd.cc b/MAC/APL/PIC/TBBDriver/src/TrigCoefCmd.cc
index 7a0bff9e90c4cde66bb161cc57282271cc105e3d..9d9bee4f7741fa954a11715ddd1463c4981bee8d 100644
--- a/MAC/APL/PIC/TBBDriver/src/TrigCoefCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/TrigCoefCmd.cc
@@ -85,6 +85,11 @@ void TrigCoefCmd::saveTbbEvent(GCFEvent& event)
 	boardmask = TS->activeBoardsMask();
 	setBoardMask(boardmask);
 	
+	for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) {
+		if (TS->isBoardActive(boardnr) == false)
+			itsTBBackE->status_mask[boardnr] |= TBB_NO_BOARD;
+	}
+	
 	// select firt channel to handle
 	nextChannelNr();
 	
diff --git a/MAC/APL/PIC/TBBDriver/src/TrigGenCmd.cc b/MAC/APL/PIC/TBBDriver/src/TrigGenCmd.cc
index bb073a8909fe23ba3c1eb5bfd5486fced21d559d..af5d7a6478a36beb7f56c232d6d287e6a06c8d7c 100644
--- a/MAC/APL/PIC/TBBDriver/src/TrigGenCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/TrigGenCmd.cc
@@ -91,6 +91,12 @@ void TrigGenCmd::saveTbbEvent(GCFEvent& event)
 		if (itsChannelMask[boardnr] != 0)  boardmask |= (1 << boardnr);
 	}
 	setBoardMask(boardmask);
+	
+	for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) {
+		if (TS->isBoardActive(boardnr) == false)
+			itsTBBackE->status_mask[boardnr] |= TBB_NO_BOARD;
+	}
+	
 	LOG_DEBUG_STR(formatString("boardmask = 0x%08X",boardmask));
 	
 	// select firt channel to handle
diff --git a/MAC/APL/PIC/TBBDriver/src/TrigReleaseCmd.cc b/MAC/APL/PIC/TBBDriver/src/TrigReleaseCmd.cc
index 26fc58d1a8ff50f6a3dcf105cb7ddbf45158c0cd..9c40ffe28a81aebf3d4a9cfb9598cc5f799de042 100644
--- a/MAC/APL/PIC/TBBDriver/src/TrigReleaseCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/TrigReleaseCmd.cc
@@ -29,7 +29,7 @@
 using namespace LOFAR;
 using namespace TBB_Protocol;
 using namespace TP_Protocol;
-using	namespace TBB;
+using namespace TBB;
 
 //--Constructors for a TrigReleaseCmd object.----------------------------------------
 TrigReleaseCmd::TrigReleaseCmd():
@@ -43,7 +43,8 @@ TrigReleaseCmd::TrigReleaseCmd():
 	
 	for(int boardnr = 0;boardnr < TS->maxBoards();boardnr++) { 
 		itsTBBackE->status_mask[boardnr]	= 0;
-		itsChannelMask[boardnr] = 0;
+		itsChannelStopMask[boardnr] = 0;
+		itsChannelStartMask[boardnr] = 0;
 	}
 	setWaitAck(true);
 }
@@ -58,7 +59,7 @@ TrigReleaseCmd::~TrigReleaseCmd()
 // ----------------------------------------------------------------------------
 bool TrigReleaseCmd::isValid(GCFEvent& event)
 {
-	if ((event.signal == TBB_TRIG_RELEASE)||(event.signal == TP_TRIG_RELEASE_ACK)) {
+	if ((event.signal == TBB_TRIG_RELEASE) || (event.signal == TP_TRIG_RELEASE_ACK)) {
 		return(true);
 	}
 	return(false);
@@ -73,22 +74,24 @@ void TrigReleaseCmd::saveTbbEvent(GCFEvent& event)
 	int32 board;
 	int32 channel;
 	for (int rcunr = 0; rcunr < TS->maxChannels(); rcunr++) {
-		if(itsTBBE->rcu_mask.test(rcunr)) {
+		if(itsTBBE->rcu_stop_mask.test(rcunr)) {
 			TS->convertRcu2Ch(rcunr,&board,&channel);	
-			itsChannelMask[board] |= (1 << channel);
+			itsChannelStopMask[board] |= (1 << channel);
+			TS->setChSelected((channel + (board * TS->nrChannelsOnBoard())),true);
+		}
+		if(itsTBBE->rcu_start_mask.test(rcunr)) {
+			TS->convertRcu2Ch(rcunr,&board,&channel);	
+			itsChannelStartMask[board] |= (1 << channel);
 			TS->setChSelected((channel + (board * TS->nrChannelsOnBoard())),true);
 		}
 	} 
 	
 	uint32 boardmask = 0;	
 	for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) {
-		if (itsChannelMask[boardnr] != 0) boardmask |= (1 << boardnr); 
-		
 		if (TS->isBoardActive(boardnr)) {
-			for (int ch = 0; ch < 16; ch++) {
-				TS->setChSelected((ch + (boardnr * 16)),true);
-				LOG_DEBUG_STR(formatString("Ch[%d] is selected",ch + (boardnr * 16)));
-			} 		
+			if ((itsChannelStopMask[boardnr] != 0) || (itsChannelStartMask[boardnr] != 0)) {
+				boardmask |= (1 << boardnr);
+			}
 		} else {
 			itsTBBackE->status_mask[boardnr] |= TBB_NO_BOARD;
 		}
@@ -101,6 +104,8 @@ void TrigReleaseCmd::saveTbbEvent(GCFEvent& event)
 	setBoardMask(boardmask);
 	
 	nextSelectedChannelNr();
+	
+	if (itsChannelStopMask[getBoardNr()] != 0) itsStage = 0;
 		
 	// initialize TP send frame
 	itsTPE->opcode	= TPTRIGRELEASE;
@@ -116,9 +121,8 @@ void TrigReleaseCmd::sendTpEvent()
 	if (itsTBBackE->status_mask[getBoardNr()] == 0) {
 		switch (itsStage) {
 			case 0: {
-				
 				// look if all channels are selected
-				if (itsChannelMask[getBoardNr()] == 0xFFFF) {
+				if (itsChannelStopMask[getBoardNr()] == 0xFFFF) {
 					// all channels are selected
 					// set mp = -1, now all 16 channels will be set to 0 (reset)
 					itsTPE->mp = 0xFFFFFFFF; 
@@ -129,12 +133,12 @@ void TrigReleaseCmd::sendTpEvent()
 					
 					uint32	reset_mask = 0; // default, reset all 4 channels
 					int32		first_channel = (getBoardNr() * 16) + (mpnr * 4);
-					uint32	mp_mask = (itsChannelMask[getBoardNr()] >> (mpnr * 4)) & 0xF; // only 4 bits
+					uint32	mp_mask = (itsChannelStopMask[getBoardNr()] >> (mpnr * 4)) & 0xF; // only 4 bits
 					LOG_DEBUG_STR(formatString("mp_mask[0x%08X]",mp_mask));
 					// mask channels that NOT require a reset
 					for (int ch = 0; ch < 4; ch++) {
 						if (	TS->isChTriggerReleased(first_channel + ch)
-							 		&& ((mp_mask & (1 << ch)) == 0)) {
+									&& ((mp_mask & (1 << ch)) == 0)) {
 							reset_mask |= (1 << ch);
 						}			
 					}
@@ -145,7 +149,7 @@ void TrigReleaseCmd::sendTpEvent()
 			
 			case 1: {
 				// look if all channels are selected
-				if (itsChannelMask[getBoardNr()] == 0xFFFF) {
+				if (itsChannelStartMask[getBoardNr()] == 0xFFFF) {
 					// all channels are selected
 					// set mp = -1, all channels on all mp's will be set to 1 (released)
 					itsTPE->mp = 0xFFFFFFFF; 
@@ -156,7 +160,7 @@ void TrigReleaseCmd::sendTpEvent()
 					
 					uint32	release_mask = 0x0; // default, don't select channels 
 					int32		first_channel = (getBoardNr() * 16) + (mpnr * 4);
-					uint32	mp_mask = (itsChannelMask[getBoardNr()] >> (mpnr * 4)) & 0xF; // only 4 bits
+					uint32	mp_mask = (itsChannelStartMask[getBoardNr()] >> (mpnr * 4)) & 0xF; // only 4 bits
 					
 					for (int ch = 0; ch < 4; ch++) {
 						if (	TS->isChTriggerReleased(first_channel + ch) 
@@ -167,10 +171,12 @@ void TrigReleaseCmd::sendTpEvent()
 					itsTPE->channel_mask = release_mask;	
 				}
 			} break;
-			default: break;
+
+			default: { 
+			} break;
 		}
-		TS->boardPort(getBoardNr()).send(*itsTPE);
 	}
+	TS->boardPort(getBoardNr()).send(*itsTPE);
 	TS->boardPort(getBoardNr()).setTimer(TS->timeout());
 }
 
@@ -198,7 +204,18 @@ void TrigReleaseCmd::saveTpAckEvent(GCFEvent& event)
 				}
 				LOG_DEBUG_STR(formatString("Received TrigReleaseAck from boardnr[%d]", getBoardNr()));
 				delete itsTPackE;
-				itsStage = 1; 
+				if (itsChannelStartMask[getBoardNr()] != 0) {
+					itsStage = 1;
+				} else {
+					if (itsTPE->mp == 0xFFFFFFFF) {
+					// all channels done, go to next board
+						setChannelNr((getBoardNr() * 16) + 15);
+					} else {
+					// one mp done, go to next mp
+						setChannelNr((getBoardNr() * 16) + (TS->getChMpNr(getChannelNr()) * 4) + 3);
+					}
+					nextSelectedChannelNr();
+				}
 			} break;
 			
 			case 1: {
@@ -225,7 +242,7 @@ void TrigReleaseCmd::saveTpAckEvent(GCFEvent& event)
 					setChannelNr((getBoardNr() * 16) + (TS->getChMpNr(getChannelNr()) * 4) + 3);
 				}
 				delete itsTPackE;
-				itsStage = 0;
+				if (itsChannelStopMask[getBoardNr()] != 0) { itsStage = 0; }
 				nextSelectedChannelNr();
 			} break;
 			default: break;
diff --git a/MAC/APL/PIC/TBBDriver/src/TrigReleaseCmd.h b/MAC/APL/PIC/TBBDriver/src/TrigReleaseCmd.h
index b57a9e2e1eaf62cf12204d8662e4c1fa4b87f02f..6d6a2121f5d110a8bdb8e8ede9cc09f128f332eb 100644
--- a/MAC/APL/PIC/TBBDriver/src/TrigReleaseCmd.h
+++ b/MAC/APL/PIC/TBBDriver/src/TrigReleaseCmd.h
@@ -61,7 +61,8 @@ namespace LOFAR {
 				TbbSettings *TS;
 				
 				int32		itsStage;
-				uint32	itsChannelMask[MAX_N_TBBBOARDS];
+				uint32	itsChannelStopMask[MAX_N_TBBBOARDS];
+				uint32	itsChannelStartMask[MAX_N_TBBBOARDS];
 				
 				TPTrigReleaseEvent			*itsTPE;
 				TPTrigReleaseAckEvent		*itsTPackE;
diff --git a/MAC/APL/PIC/TBBDriver/src/TrigSetupCmd.cc b/MAC/APL/PIC/TBBDriver/src/TrigSetupCmd.cc
index 5433b6b98f718cb0303b83e5f77c5625fec0dc76..ce2e8b6376e76892fdeb2797acf8ce4729c7064d 100644
--- a/MAC/APL/PIC/TBBDriver/src/TrigSetupCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/TrigSetupCmd.cc
@@ -87,6 +87,11 @@ void TrigSetupCmd::saveTbbEvent(GCFEvent& event)
 	boardmask = TS->activeBoardsMask();
 	setBoardMask(boardmask);
 	
+	for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) {
+		if (TS->isBoardActive(boardnr) == false)
+			itsTBBackE->status_mask[boardnr] |= TBB_NO_BOARD;
+	}
+	
 	// select firt channel to handle
 	nextChannelNr();
 	
diff --git a/MAC/APL/PIC/TBBDriver/src/WritefCmd.cc b/MAC/APL/PIC/TBBDriver/src/WritefCmd.cc
index 811f392aa3d5e009015bf8180eabc8cc381068a7..bfa9bd6295a6307d40363750c20ec03b87e2d27d 100644
--- a/MAC/APL/PIC/TBBDriver/src/WritefCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/WritefCmd.cc
@@ -175,8 +175,19 @@ void WritefCmd::sendTpEvent()
 				char info[256];
 				memset(info,0,256);
 				
-				char *tp_name = strstr(itsFileNameTp,"tp");
-				char *mp_name = strstr(itsFileNameMp,"mp");
+				char *tp_name = strrchr(itsFileNameTp,'/');
+				if (tp_name == 0) {
+					tp_name = itsFileNameTp;
+				} else {
+					tp_name += 1;
+				} 
+				
+				char *mp_name = strrchr(itsFileNameMp,'/');
+				if (mp_name == 0) {
+					mp_name = itsFileNameMp;
+				} else {
+					mp_name += 1;
+				}
 				
 				sprintf(info," %s %s",tp_name,mp_name);
 				LOG_DEBUG_STR(formatString("ImageInfo: %s",info));
diff --git a/MAC/APL/PIC/TBBDriver/src/tbbctl.cc b/MAC/APL/PIC/TBBDriver/src/tbbctl.cc
index 42fc54fc181710b7080d8037e113dd278666a7e9..e206901c52ec8ae555d11beca98a5119b12a9a68 100644
--- a/MAC/APL/PIC/TBBDriver/src/tbbctl.cc
+++ b/MAC/APL/PIC/TBBDriver/src/tbbctl.cc
@@ -40,6 +40,9 @@
 #include <ctype.h>
 #include <Common/lofar_set.h>
 #include <time.h>
+#include <unistd.h>
+
+//#include <APL/RTCCommon/gnuplot_i.h>
 
 #include <netinet/in.h>    
 #include <net/ethernet.h>  
@@ -56,7 +59,9 @@ using namespace TbbCtl;
 //---- ALLOC  ----------------------------------------------------------------
 AllocCmd::AllocCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ================================================== allocate memory ====\n");	
+	cout << endl;
+	cout << "== TBB ================================================== allocate memory ====" << endl;	
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -64,7 +69,7 @@ void AllocCmd::send()
 {
 	TBBAllocEvent event;
 	
-	if (getSelected()) event.rcu_mask = getRcuMask(); // if select cmd is used
+	if (isSelectionDone()) event.rcu_mask = getRcuMask(); // if select cmd is used
 	
 	itsPort.send(event);
 	itsPort.setTimer((long)1);
@@ -74,8 +79,8 @@ void AllocCmd::send()
 GCFEvent::TResult AllocCmd::ack(GCFEvent& e)
 {
 	TBBAllocAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;
 	int32 bnr = 0;
 	int32 oldbnr = -1;
 	for (int cnr=0; cnr < getMaxSelections(); cnr++) {
@@ -83,18 +88,18 @@ GCFEvent::TResult AllocCmd::ack(GCFEvent& e)
 		
 		if (bnr != oldbnr) {
 			if ((ack.status_mask[bnr] & TBB_SUCCESS) || (ack.status_mask[bnr] & TBB_RCU_COMM_ERROR)) {
-				logMessage(cout,formatString(" %2d memory allocated for selected rcu's", bnr));
+				cout << formatString(" %2d memory allocated for selected rcu's", bnr) << endl;
 			}	else {
-				logMessage(cout,formatString(" %2d %s", bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				cout << formatString(" %2d %s", bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 			}
 		}
 		
 		if (isSelected(cnr) && !(ack.status_mask[bnr] & TBB_NO_BOARD) ) {
 			if (ack.rcu_mask.test(cnr)) {
 				if (ack.status_mask[bnr] & TBB_SUCCESS) {
-					logMessage(cout,formatString("     ERROR, Rcu-%d NOT in correct state\n",cnr));
+					cout << formatString("     ERROR, Rcu-%d NOT in correct state",cnr) << endl;
 				} else {
-					logMessage(cout,formatString("     ERROR, Rcu-%d  %s\n",cnr,getDriverErrorStr(ack.status_mask[bnr] & 0xFFFF0000).c_str()));
+					cout << formatString("     ERROR, Rcu-%d  %s",cnr,getDriverErrorStr(ack.status_mask[bnr] & 0xFFFF0000).c_str()) << endl;
 				}
 			}
 		}
@@ -109,7 +114,9 @@ GCFEvent::TResult AllocCmd::ack(GCFEvent& e)
 //---- CHANNELINFO --------------------------------------------------------------
 ChannelInfoCmd::ChannelInfoCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ===================================================== rcu info =======\n");
+	cout << endl;
+	cout << "== TBB ===================================================== rcu info =======" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -132,19 +139,20 @@ GCFEvent::TResult ChannelInfoCmd::ack(GCFEvent& e)
 			if (ack.rcu_state[rcu] != 'F') {
 				if (isSelected(rcu) ) {
 					if (bnr != oldbnr) {
-						logMessage(cout,"Rcu  Board  Input  State  Start-address  Size[pages]");
-						logMessage(cout,"---  -----  -----  -----  -------------  -----------");
+						cout << "Rcu  Board  Input  State  Start-address  Size[pages]" << endl;
+						cout << "---  -----  -----  -----  -------------  -----------" << endl;
 					}
-					logMessage(cout,formatString(" %2d    %2d     %2d      %c     0x%08X  %11u %s",
+					cout << formatString(" %2d    %2d     %2d      %c     0x%08X  %11u %s",
 							rcu, ack.rcu_on_board[rcu], ack.rcu_on_input[rcu],
 							(char)ack.rcu_state[rcu],	ack.rcu_start_addr[rcu], ack.rcu_pages[rcu],
-							getBoardErrorStr(ack.rcu_status[rcu]).c_str()));
+							getBoardErrorStr(ack.rcu_status[rcu]).c_str()) << endl;
 				}
 			}
 			oldbnr = bnr;
 	}
-	logMessage(cout,"\n *State:  F = Free, A = Allocated, R = Recording, S = Stopped, E = Error");
-	logMessage(cout," *Only NOT Free rcu's are listed ");
+	cout << endl;
+	cout << " *State:  F = Free, A = Allocated, R = Recording, S = Stopped, E = Error" << endl;
+	cout << " *Only NOT Free rcu's are listed " << endl;
 	
 	setCmdDone(true);
 
@@ -154,7 +162,9 @@ GCFEvent::TResult ChannelInfoCmd::ack(GCFEvent& e)
 //---- FREE ----------------------------------------------------------------
 FreeCmd::FreeCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB =================== discard buffer allocation and disable rcu's ====\n");
+	cout << endl;
+	cout << "== TBB =================== discard buffer allocation and disable rcu's ====" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -162,7 +172,7 @@ void FreeCmd::send()
 {
 	TBBFreeEvent event;
 	
-	if (getSelected()) event.rcu_mask = getRcuMask(); // if select cmd is used
+	if (isSelectionDone()) event.rcu_mask = getRcuMask(); // if select cmd is used
 	
 	itsPort.send(event);
 	itsPort.setTimer((long)1);
@@ -172,8 +182,8 @@ void FreeCmd::send()
 GCFEvent::TResult FreeCmd::ack(GCFEvent& e)
 {
 	TBBFreeAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;
 	int32 bnr = 0;
 	int32 oldbnr = -1;
 	for (int cnr=0; cnr < getMaxSelections(); cnr++) {
@@ -181,17 +191,17 @@ GCFEvent::TResult FreeCmd::ack(GCFEvent& e)
 		
 		if (bnr != oldbnr) {
 			if (ack.status_mask[bnr] & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  buffer dischard and channel disabled for selected rcu's", bnr));
+				cout << formatString(" %2d  buffer dischard and channel disabled for selected rcu's", bnr) << endl;
 			} else {
-				logMessage(cout,formatString(" %2d  %s", bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				cout << formatString(" %2d  %s", bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 			}
 		}
 		if (isSelected(cnr) && !(ack.status_mask[bnr] & TBB_NO_BOARD) ) {
 			if (ack.rcu_mask.test(cnr)) {
 				if (ack.status_mask[bnr] & TBB_SUCCESS) {
-					logMessage(cout,formatString("     ERROR, Rcu-%d NOT in correct state\n",cnr));
+					cout << formatString("     ERROR, Rcu-%d NOT in correct state",cnr) << endl;
 				} else {
-					logMessage(cout,formatString("     ERROR, Rcu-%d  %s\n",cnr,getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+					cout << formatString("     ERROR, Rcu-%d  %s",cnr,getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 				}
 			}
 		}
@@ -206,7 +216,9 @@ GCFEvent::TResult FreeCmd::ack(GCFEvent& e)
 //---- RECORD ----------------------------------------------------------------
 RecordCmd::RecordCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ============================= start recording on selected rcu's ====\n");
+	cout << endl;
+	cout << "== TBB ============================= start recording on selected rcu's ====" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -214,7 +226,7 @@ void RecordCmd::send()
 {
 	TBBRecordEvent event;
 	
-	if (getSelected()) event.rcu_mask = getRcuMask(); // if select cmd is used
+	if (isSelectionDone()) event.rcu_mask = getRcuMask(); // if select cmd is used
 	
 	itsPort.send(event);
 	itsPort.setTimer((long)1);
@@ -224,8 +236,8 @@ void RecordCmd::send()
 GCFEvent::TResult RecordCmd::ack(GCFEvent& e)
 {
 	TBBRecordAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;
 	int32 bnr = 0;
 	int32 oldbnr = -1;
 	for (int cnr=0; cnr < getMaxSelections(); cnr++) {
@@ -233,18 +245,19 @@ GCFEvent::TResult RecordCmd::ack(GCFEvent& e)
 		
 		if (bnr != oldbnr) {
 			if (ack.status_mask[bnr] & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  recording started for selected rcu's", bnr));
+				cout << formatString(" %2d  recording started for selected rcu's", bnr) << endl;
 			} else {
-				logMessage(cout,formatString(" %2d  %s", bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				cout << formatString(" %2d  %s", bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 			}
 		}
 		
 		if (isSelected(cnr) && !(ack.status_mask[bnr] & TBB_NO_BOARD) ) {
 			if (ack.rcu_mask.test(cnr)) {
 				if (ack.status_mask[bnr] & TBB_SUCCESS) {
-					//logMessage(cout,formatString("      ERROR, Rcu-%d NOT in correct state\n",cnr));
+					//cout << formatString("      ERROR, Rcu-%d NOT in correct state",cnr) << endl;
+					//cout  << endl;
 				} else {
-					logMessage(cout,formatString("      ERROR, Rcu-%d  %s\n",cnr,getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+					cout << formatString("      ERROR, Rcu-%d  %s",cnr,getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 				}
 			}
 		}
@@ -260,17 +273,17 @@ GCFEvent::TResult RecordCmd::ack(GCFEvent& e)
 //---- STOP -------------------------------------------------------------------
 StopCmd::StopCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ============================== stop recording on selected rcu's ====\n");	
+	cout << endl;
+	cout << "== TBB ============================== stop recording on selected rcu's ====" << endl;	
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
 void StopCmd::send()
 {
 	TBBStopEvent event;
+	if (isSelectionDone()) event.rcu_mask = getRcuMask(); // if select cmd is used
 	
-	if (getSelected()) {
-		event.rcu_mask = getRcuMask(); // if select cmd is use
-	}
 	itsPort.send(event);
 	itsPort.setTimer((long)1);
 }
@@ -279,8 +292,8 @@ void StopCmd::send()
 GCFEvent::TResult StopCmd::ack(GCFEvent& e)
 {
 	TBBStopAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;
 	int32 bnr = 0;
 	int32 oldbnr = -1;
 	for (int cnr=0; cnr < getMaxSelections(); cnr++) {
@@ -288,18 +301,16 @@ GCFEvent::TResult StopCmd::ack(GCFEvent& e)
 		
 		if (bnr != oldbnr) {
 			if (ack.status_mask[bnr] & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  recording stopped for selected rcu's", bnr));
+				cout << formatString(" %2d  recording stopped for selected rcu's", bnr) << endl;
 			} else {
-				logMessage(cout,formatString(" %2d  %s", bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				cout << formatString(" %2d  %s", bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 			}
 		}
 		
 		if (isSelected(cnr) && !(ack.status_mask[bnr] & TBB_NO_BOARD) ) {
 			if (ack.rcu_mask.test(cnr)) {
-				if (ack.status_mask[bnr] & TBB_SUCCESS) {
-					//logMessage(cout,formatString("      ERROR, Rcu-%d NOT in correct state\n",cnr));
-				} else {
-				  logMessage(cout,formatString("      ERROR, Rcu-%d  %s\n",cnr,getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				if (!(ack.status_mask[bnr] & TBB_SUCCESS)) {
+					cout << formatString("      ERROR, Rcu-%d  %s",cnr,getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 				}
 			}
 		}
@@ -315,15 +326,18 @@ GCFEvent::TResult StopCmd::ack(GCFEvent& e)
 //---- TRIGRELEASE ------------------------------------------------------------
 TrigReleaseCmd::TrigReleaseCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ============================ release trigger for selected rcu's ====\n");
+	cout << endl;
+	cout << "== TBB ============================ release trigger for selected rcu's ====" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
 void TrigReleaseCmd::send()
 {
 	TBBTrigReleaseEvent event;
-	if (getSelected()) {
-		event.rcu_mask = getRcuMask();
+	if (isSelectionDone()) {
+		event.rcu_stop_mask = getRcuMask();
+		event.rcu_start_mask = getRcuMask();
 	}
 	itsPort.send(event);
 	itsPort.setTimer((long)1);
@@ -333,17 +347,23 @@ void TrigReleaseCmd::send()
 GCFEvent::TResult TrigReleaseCmd::ack(GCFEvent& e)
 {
 	TBBTrigReleaseAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");  
-	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
-		if (isSelected(bnr) ) {
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;  
+	int32 bnr = 0;
+	int32 oldbnr = -1;  
+	for (int cnr=0; cnr < getMaxSelections(); cnr++) {
+		bnr = static_cast<int32>(cnr / 16);
+		
+		if (bnr != oldbnr) {
 			if (ack.status_mask[bnr] & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  trigger detection released for selected rcu's",bnr ));
+				cout << formatString(" %2d  trigger detection released for selected rcu's",bnr ) << endl;
 			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				cout << formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 			}
 		}
+		oldbnr = bnr;
 	}
+	
 	setCmdDone(true);
 	return(GCFEvent::HANDLED);
 }
@@ -351,16 +371,20 @@ GCFEvent::TResult TrigReleaseCmd::ack(GCFEvent& e)
 //---- TRIGGENERATE -----------------------------------------------------------
 TrigGenerateCmd::TrigGenerateCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ============================ generate trigger on selected rcu's ====\n");
-	logMessage(cout,"RCU  seq_nr     time       sample     sum        samples    peak");
-	logMessage(cout,"---  ---------  ---------  ---------  ---------  ---------  ---------");  
+	cout << endl;
+	cout << "== TBB ============================ generate trigger on selected rcu's ====" << endl;
+	cout << endl;
+	cout << "RCU   seq_nr      time        sample       sum          samples     peak" << endl;
+	cout << "---   ---------   ---------   ----------   ----------   ---------   ---------" << endl;  
 }
 
 //-----------------------------------------------------------------------------
 void TrigGenerateCmd::send()
 {
+	setCmdSendNext(false);
+	
 	TBBTrigGenerateEvent event;
-	if (getSelected()) {
+	if (isSelectionDone()) {
 		event.rcu_mask = getRcuMask();
 	}	
 	itsPort.send(event);
@@ -375,8 +399,15 @@ GCFEvent::TResult TrigGenerateCmd::ack(GCFEvent& e)
 	}
 	if (e.signal == TBB_TRIGGER) {
 		TBBTriggerEvent trig(e);
-		logMessage(cout,formatString(" %2d  %8u   %8u   %8u   %8u   %8u   %9u",
-			trig.rcu, trig.sequence_nr, trig.time, trig.sample_nr, trig.trigger_sum, trig.trigger_samples, trig.peak_value));
+		cout << formatString(" %2d   %9u   %9u   %10u   %10u   %9u   %9u",
+												 trig.rcu,
+												 trig.sequence_nr,
+												 trig.time,
+												 trig.sample_nr,
+												 trig.trigger_sum,
+												 trig.trigger_samples,
+												 trig.peak_value
+												) << endl;
 	}
 	//setCmdDone(true);
 	return(GCFEvent::HANDLED);
@@ -386,15 +417,17 @@ GCFEvent::TResult TrigGenerateCmd::ack(GCFEvent& e)
 TrigSetupCmd::TrigSetupCmd(GCFPortInterface& port) : Command(port),
 	itsLevel(0), itsMode(0), itsFilter(0), itsWindow(0), itsDummy(0)
 {
-	logMessage(cout,"\n== TBB ============================ trigger system setup for selected rcu's ====\n");
+	cout << endl;
+	cout << "== TBB ============================ trigger system setup for selected rcu's ====" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
 void TrigSetupCmd::send()
 {
 	TBBTrigSetupEvent event;
-	if (getSelected()) {
-		for (int cnr=0; cnr < MAX_N_RCUS; cnr++) {	
+	if (isSelectionDone()) {
+		for (int cnr=0; cnr < getMaxSelections(); cnr++) {	
 			event.setup[cnr].level = itsLevel;
 			event.setup[cnr].td_mode = itsMode;
 			event.setup[cnr].filter_select = itsFilter;
@@ -409,19 +442,26 @@ void TrigSetupCmd::send()
 //-----------------------------------------------------------------------------
 GCFEvent::TResult TrigSetupCmd::ack(GCFEvent& e)
 {
-	TBBTrigSetupAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");  
-	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
-		if (isSelected(bnr) ) {
-			if (ack.status_mask[bnr] & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  setup trigger system for all rcu's",bnr ));
-			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+	if (e.signal == TBB_TRIG_SETUP_ACK) {
+		TBBTrigSetupAckEvent ack(e);
+		cout << "TBB  Info" << endl;
+		cout << "---  -------------------------------------------------------" << endl;
+		int32 bnr = 0;
+		int32 oldbnr = -1;  
+		for (int cnr=0; cnr < getMaxSelections(); cnr++) {
+			bnr = static_cast<int32>(cnr / 16);
+			
+			if (bnr != oldbnr) {
+				if (ack.status_mask[bnr] & TBB_SUCCESS) {
+					cout << formatString(" %2d  setup trigger system for all rcu's",bnr ) << endl;
+				}	else {	
+					cout << formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
+				}
 			}
+			oldbnr = bnr;
 		}
+		setCmdDone(true);
 	}
-	setCmdDone(true);
 	return(GCFEvent::HANDLED);
 }
 
@@ -429,14 +469,16 @@ GCFEvent::TResult TrigSetupCmd::ack(GCFEvent& e)
 TrigCoefficientCmd::TrigCoefficientCmd(GCFPortInterface& port) : Command(port),
 	itsC0(0), itsC1(0), itsC2(0), itsC3(0)
 {
-	logMessage(cout,"\n== TBB ============================ setup trigger coeffients for selected rcu's ====\n");
+	cout << endl;
+	cout << "== TBB ============================ setup trigger coeffients for selected rcu's ====" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
 void TrigCoefficientCmd::send()
 {
 	TBBTrigCoefEvent event;
-	if (getSelected()) {
+	if (isSelectionDone()) {
 		for (int cnr=0; cnr < getMaxSelections(); cnr++) {
 			event.coefficients[cnr].c0 = itsC0;
 			event.coefficients[cnr].c1 = itsC1;
@@ -452,16 +494,21 @@ void TrigCoefficientCmd::send()
 GCFEvent::TResult TrigCoefficientCmd::ack(GCFEvent& e)
 {
 	TBBTrigCoefAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");  
-	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
-		if (isSelected(bnr) ) {
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;  
+	int32 bnr = 0;
+	int32 oldbnr = -1;  
+	for (int cnr=0; cnr < getMaxSelections(); cnr++) {
+		bnr = static_cast<int32>(cnr / 16);
+		
+		if (bnr != oldbnr) {
 			if (ack.status_mask[bnr] & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  setup trigger coeffients for selected rcu's",bnr ));
+				cout << formatString(" %2d  setup trigger system for all rcu's",bnr ) << endl;
 			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				cout << formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 			}
 		}
+		oldbnr = bnr;
 	}
 	setCmdDone(true);
 	return(GCFEvent::HANDLED);
@@ -470,14 +517,16 @@ GCFEvent::TResult TrigCoefficientCmd::ack(GCFEvent& e)
 //---- TRIGINFO ---------------------------------------------------------------
 TrigInfoCmd::TrigInfoCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ============================ trigger info for selected rcu's ====\n");
+	cout << endl;
+	cout << "== TBB ============================ trigger info for selected rcu's ====" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
 void TrigInfoCmd::send()
 {
 	TBBTrigInfoEvent event;
-	if (getSelected()) {
+	if (isSelectionDone()) {
 		event.rcu = getRcu();
 	}
 	itsPort.send(event);
@@ -488,32 +537,124 @@ void TrigInfoCmd::send()
 GCFEvent::TResult TrigInfoCmd::ack(GCFEvent& e)
 {
 	TBBTrigInfoAckEvent ack(e);
-	logMessage(cout,"RCU  Info");
-	logMessage(cout,"---  -------------------------------------------------------");  
-	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
-		if (isSelected(bnr) ) {
-			if (ack.status_mask & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  sequence   : %u",bnr,ack.sequence_nr));
-				logMessage(cout,formatString("      time       : %u",ack.time));
-				logMessage(cout,formatString("      sample     : %u",ack.sample_nr));
-				logMessage(cout,formatString("      sum        : %u",ack.trigger_sum));
-				logMessage(cout,formatString("      samples    : %u",ack.trigger_samples));
-				logMessage(cout,formatString("      peak value : %u",ack.peak_value));
-				logMessage(cout,formatString("      flags      : %08X",ack.trigger_flags));
-			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask).c_str()));
-			}
-		}
+	cout << "RCU  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;  
+	if (ack.status_mask & TBB_SUCCESS) {
+		cout << formatString(" %2d  sequence   : %u",getRcu(),ack.sequence_nr) << endl;
+		cout << formatString("      time       : %u",ack.time) << endl;
+		cout << formatString("      sample     : %u",ack.sample_nr) << endl;
+		cout << formatString("      sum        : %u",ack.trigger_sum) << endl;
+		cout << formatString("      samples    : %u",ack.trigger_samples) << endl;
+		cout << formatString("      peak value : %u",ack.peak_value) << endl;
+		cout << formatString("      flags      : %08X",ack.trigger_flags) << endl;
+	}	else {	
+		cout << formatString(" %2d  %s",getRcu(), getDriverErrorStr(ack.status_mask).c_str()) << endl;
 	}
 	setCmdDone(true);
 	return(GCFEvent::HANDLED);
 }
 
+//---- LISTEN ---------------------------------------------------------------
+ListenCmd::ListenCmd(GCFPortInterface& port) : Command(port),
+	itsCmdStage(0)
+{
+	cout << endl;
+	cout << "== TBB ============================ listen for triggers on selected rcu's ====" << endl;
+	cout << endl;
+	 
+}
+
+//-----------------------------------------------------------------------------
+void ListenCmd::send()
+{
+	switch (itsCmdStage) {
+		case 0: {
+			cout << "-stop all trigger systems" << endl;
+			TBBTrigReleaseEvent release;
+			release.rcu_stop_mask.set();
+			release.rcu_start_mask.reset();
+			itsPort.send(release);
+		} break;
+		
+		case 1: {
+			cout << "-stopped recording on all allocated rcu's" << endl;
+			TBBStopEvent stop;
+			stop.rcu_mask = getRcuMask();
+			itsPort.send(stop);	
+		} break;
+
+		case 2: {
+			cout << "-restarted recording on all allocated rcu's" << endl;
+			TBBRecordEvent record;
+			record.rcu_mask = getRcuMask(); // if select cmd is used
+			itsPort.send(record);	
+		} break;
+
+		case 3: {
+			cout << "-released all trigger systems, and waiting  (STOP WAITING WITH CTRL-C)" << endl;
+			setCmdSendNext(false);
+			TBBTrigReleaseEvent release;
+			release.rcu_stop_mask.reset();
+			release.rcu_start_mask = getRcuMask();
+			itsPort.send(release);
+			cout << endl;
+			cout << "RCU   seq_nr      time        sample       sum          samples     peak" << endl;
+			cout << "---   ---------   ---------   ----------   ----------   ---------   ---------" << endl; 
+		} break;
+
+		default: {
+		} break;
+	}
+	itsPort.setTimer((long)1);
+}
+
+//-----------------------------------------------------------------------------
+GCFEvent::TResult ListenCmd::ack(GCFEvent& e)
+{
+	if (e.signal == TBB_STOP_ACK) {
+		TBBTrigReleaseAckEvent ack(e);
+		itsCmdStage = 2;
+	}
+	if (e.signal == TBB_RECORD_ACK) {
+		TBBTrigReleaseAckEvent ack(e);
+		itsCmdStage = 3;
+	}
+	if (e.signal == TBB_TRIG_RELEASE_ACK) {
+		TBBTrigReleaseAckEvent ack(e);
+		if (itsCmdStage == 0) itsCmdStage = 1;
+		if (itsCmdStage == 3) itsCmdStage = 4;	
+	}
+
+	if (e.signal == TBB_TRIGGER) {
+		
+			TBBTriggerEvent trig(e);
+			
+			TBBStopEvent event;
+			event.rcu_mask = (1 << trig.rcu);
+			itsPort.send(event);
+			
+			cout << formatString(" %2d   %9u   %9u   %10u   %10u   %9u   %9u  (stopped)",
+													 trig.rcu,
+													 trig.sequence_nr,
+													 trig.time,
+													 trig.sample_nr,
+													 trig.trigger_sum,
+													 trig.trigger_samples,
+													 trig.peak_value
+													) << endl;
+		
+	}	
+	//setCmdDone(true);
+	return(GCFEvent::HANDLED);
+}
+
 //---- READ -------------------------------------------------------------------
 ReadCmd::ReadCmd(GCFPortInterface& port) : Command(port),
 	itsSecondsTime(0),itsSampleTime(0),itsPrePages(0),itsPostPages(0)
 {
-	logMessage(cout,"\n== TBB ==============  transfer data to CEP for all selected rcu ====\n");	
+	cout << endl;
+	cout << "== TBB ==============  transfer data to CEP for all selected rcu ====" << endl;	
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -533,14 +674,14 @@ void ReadCmd::send()
 GCFEvent::TResult ReadCmd::ack(GCFEvent& e)
 {
 	TBBReadAckEvent ack(e);
-	logMessage(cout,"RCU  Info");
-	logMessage(cout,"---  -------------------------------------------------------");  
+	cout << "RCU  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;  
 	for (int cnr=0; cnr < getMaxSelections(); cnr++) {
 		if (isSelected(cnr) ) {
 			if (ack.status_mask & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  tranfering data to CEP",cnr ));
+				cout << formatString(" %2d  tranfering data to CEP",cnr ) << endl;
 			}	else {			
-				logMessage(cout,formatString(" %2d  %s",cnr, getDriverErrorStr(ack.status_mask).c_str()));
+				cout << formatString(" %2d  %s",cnr, getDriverErrorStr(ack.status_mask).c_str()) << endl;
 			}
 		}
 	}
@@ -554,7 +695,9 @@ GCFEvent::TResult ReadCmd::ack(GCFEvent& e)
 ModeCmd::ModeCmd(GCFPortInterface& port) : Command(port)
 	,itsRecMode(0)
 {
-	logMessage(cout,"\n== TBB ===================================== set mode command ===============\n");
+	cout << endl;
+	cout << "== TBB ===================================== set mode command ===============" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -571,12 +714,12 @@ void ModeCmd::send()
 GCFEvent::TResult ModeCmd::ack(GCFEvent& e)
 {
 	TBBModeAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");  
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;  
 	if (ack.status_mask & TBB_SUCCESS) {
-		logMessage(cout,formatString(" %2d  mode set and UDP/IP configured", getBoard()));
+		cout << formatString(" %2d  mode set and UDP/IP configured", getBoard()) << endl;
 	}	else {			
-		logMessage(cout,formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()));
+		cout << formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()) << endl;
 	}
 	
 	setCmdDone(true);
@@ -587,7 +730,9 @@ GCFEvent::TResult ModeCmd::ack(GCFEvent& e)
 //---- VERSION ----------------------------------------------------------------
 VersionCmd::VersionCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ====================================== ID and version information ====\n");
+	cout << endl;
+	cout << "== TBB ====================================== ID and version information ====" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -604,13 +749,14 @@ GCFEvent::TResult VersionCmd::ack(GCFEvent& e)
 {
   TBBVersionAckEvent ack(e);
 	
-	logMessage(cout,formatString("TBBDriver software version %3.2f\n",(ack.driverversion / 100.)));
-	logMessage(cout,"TBB  ID  Software   Board    TP0      MP0      MP1      MP2      MP3");
-	logMessage(cout,"---  --  --------  -------  -------  -------  -------  -------  -------");
+	cout << formatString("TBBDriver software version %3.2f",(ack.driverversion / 100.)) << endl;
+	cout << endl;
+	cout << "TBB  ID  Software   Board    TP0      MP0      MP1      MP2      MP3" << endl;
+	cout << "---  --  --------  -------  -------  -------  -------  -------  -------" << endl;
 	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
 		if (isSelected(bnr) ) {
 			if (ack.status_mask[bnr] & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2u  %2u   V%5.1f    V%4.1f    V%4.1f    V%4.1f    V%4.1f    V%4.1f    V%4.1f",
+				cout << formatString(" %2u  %2u   V%5.1f    V%4.1f    V%4.1f    V%4.1f    V%4.1f    V%4.1f    V%4.1f",
 	          bnr,
 	          ack.boardid[bnr],
 						(ack.swversion[bnr] / 10.),
@@ -619,9 +765,9 @@ GCFEvent::TResult VersionCmd::ack(GCFEvent& e)
 						(ack.mp0version[bnr] / 10.),
 						(ack.mp1version[bnr] / 10.),
 						(ack.mp2version[bnr] / 10.),
-						(ack.mp3version[bnr] / 10.)));
+						(ack.mp3version[bnr] / 10.)) << endl;
 			}	else {
-					logMessage(cout,formatString(" %2u  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));	
+					cout << formatString(" %2u  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;	
       }
   	}
 	}
@@ -634,7 +780,9 @@ GCFEvent::TResult VersionCmd::ack(GCFEvent& e)
 //---- SIZE -------------------------------------------------------------------
 SizeCmd::SizeCmd(GCFPortInterface& port) : Command(port)
 {
-  logMessage(cout,"\n== TBB ==================================== installed memory information ====\n");	
+  cout << endl;
+  cout << "== TBB ==================================== installed memory information ====" << endl;	
+  cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -650,19 +798,20 @@ void SizeCmd::send()
 GCFEvent::TResult SizeCmd::ack(GCFEvent& e)
 {
   TBBSizeAckEvent ack(e);
-	logMessage(cout,"TBB  pages     Total memory ");
-	logMessage(cout,"---  --------  ------------"); 
+	cout << "TBB  pages     Total memory " << endl;
+	cout << "---  --------  ------------" << endl; 
 	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
 		if (isSelected(bnr) ) {
 			if (ack.status_mask[bnr] & TBB_SUCCESS) {
 				double gbyte = ((double)ack.npages[bnr] * 2048.) / (1024. * 1024. * 1024.); 
-				logMessage(cout,formatString(" %2d  %8d  %6.3f GByte",bnr,ack.npages[bnr],gbyte));
+				cout << formatString(" %2d  %8d  %6.3f GByte",bnr,ack.npages[bnr],gbyte) << endl;
 			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				cout << formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
       }
   	}
 	}
-	logMessage(cout,"\n1 page = 2048 Bytes");
+	cout << endl;
+	cout << "1 page = 2048 Bytes" << endl;
 	
   setCmdDone(true);
 
@@ -672,7 +821,9 @@ GCFEvent::TResult SizeCmd::ack(GCFEvent& e)
 //---- STATUS -----------------------------------------------------------------
 StatusCmd::StatusCmd(GCFPortInterface& port) : Command(port)
 {
-  logMessage(cout,"\n== TBB ============================= voltage and temperature information ====\n");	
+  cout << endl;
+  cout << "== TBB ============================= voltage and temperature information ====" << endl;	
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -689,13 +840,13 @@ GCFEvent::TResult StatusCmd::ack(GCFEvent& e)
 {
   TBBStatusAckEvent ack(e);
     
-	logMessage(cout,"TBB  Voltage 1.2  Voltage 2.5  Voltage 3.3  Temp PCB  Temp TP   Temp MP0  Temp MP1  Temp MP2  Temp MP3");
-	logMessage(cout,"---  -----------  -----------  -----------  --------  --------  --------  --------  --------  --------");
+	cout << "TBB  Voltage 1.2  Voltage 2.5  Voltage 3.3  Temp PCB  Temp TP   Temp MP0  Temp MP1  Temp MP2  Temp MP3" << endl;
+	cout << "---  -----------  -----------  -----------  --------  --------  --------  --------  --------  --------" << endl;
 	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
 		if (isSelected(bnr) ) {
 			if (ack.status_mask[bnr] & TBB_SUCCESS) {
 				
-				logMessage(cout,formatString(" %2d     %4.2f V       %4.2f V       %4.2f V    %3u 'C    %3u 'C    %3u 'C    %3u 'C    %3u 'C    %3u 'C",
+				cout << formatString(" %2d     %4.2f V       %4.2f V       %4.2f V    %3u 'C    %3u 'C    %3u 'C    %3u 'C    %3u 'C    %3u 'C",
 						bnr,
 						((double)ack.V12[bnr] * (2.5 / 192.)),	// MAX6652 pin-2:  2.5 / 192	= 0.0130 / count
 						((double)ack.V25[bnr] * (3.3 / 192.)),	// MAX6652 pin-3:  3.3 / 192	= 0.0172 / count
@@ -705,9 +856,9 @@ GCFEvent::TResult StatusCmd::ack(GCFEvent& e)
 						ack.Tmp0[bnr],
 						ack.Tmp1[bnr],
 						ack.Tmp2[bnr],
-						ack.Tmp3[bnr] ));
+						ack.Tmp3[bnr] ) << endl;
 			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				cout << formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
       }
   	}
 	}
@@ -720,7 +871,10 @@ GCFEvent::TResult StatusCmd::ack(GCFEvent& e)
 //---- CLEAR -------------------------------------------------------------------
 ClearCmd::ClearCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB =============================================== clear in progress ====\n");
+	cout << endl;
+	cout << "== TBB =============================================== clear in progress ====" << endl;
+	cout << " wait 5 seconds" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -729,21 +883,21 @@ void ClearCmd::send()
 	TBBClearEvent event;
 	event.boardmask = getBoardMask();
 	itsPort.send(event);
-	itsPort.setTimer((long)1);
+	itsPort.setTimer((long)5);
 }
 
 //-----------------------------------------------------------------------------
 GCFEvent::TResult ClearCmd::ack(GCFEvent& e)
 {
 	TBBClearAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");    
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;    
 	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
 		if (isSelected(bnr) ) {
 			if (ack.status_mask[bnr] & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  board is cleared",bnr ));
+				cout << formatString(" %2d  board is cleared",bnr ) << endl;
 			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				cout << formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 			}
 		}
 	}
@@ -756,7 +910,10 @@ GCFEvent::TResult ClearCmd::ack(GCFEvent& e)
 //---- RESET -------------------------------------------------------------------
 ResetCmd::ResetCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB =============================================== reset in progress ====\n");
+	cout << endl;
+	cout << "== TBB =============================================== reset in progress ====" << endl;
+	cout << " wait 5 seconds" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -772,14 +929,14 @@ void ResetCmd::send()
 GCFEvent::TResult ResetCmd::ack(GCFEvent& e)
 {
 	TBBResetAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");    
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;    
 	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
 		if (isSelected(bnr) ) {
 			if (ack.status_mask[bnr] & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  board is reset",bnr ));
+				cout << formatString(" %2d  board is reset",bnr ) << endl;
 			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				cout << formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 			}
 		}
 	}
@@ -792,7 +949,10 @@ GCFEvent::TResult ResetCmd::ack(GCFEvent& e)
 //---- CONFIG -------------------------------------------------------------------
 ConfigCmd::ConfigCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ========================================= reconfigure TP and MP's ====\n");
+	cout << endl;
+	cout << "== TBB ========================================= reconfigure TP and MP's ====" << endl;
+	cout << " wait 5 seconds" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -809,14 +969,14 @@ void ConfigCmd::send()
 GCFEvent::TResult ConfigCmd::ack(GCFEvent& e)
 {
 	TBBConfigAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");    
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;    
 	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
 		if (isSelected(bnr) ) {
 			if (ack.status_mask[bnr] & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  reconfigured TP and MP's",bnr ));
+				cout << formatString(" %2d  reconfigured TP and MP's",bnr ) << endl;
 			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()));
+				cout << formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask[bnr]).c_str()) << endl;
 			}
 		}
 	}
@@ -830,9 +990,11 @@ GCFEvent::TResult ConfigCmd::ack(GCFEvent& e)
 ErasefCmd::ErasefCmd(GCFPortInterface& port) : Command(port)
 	,itsPage(0)
 {
-	logMessage(cout,"\n== TBB ===================================================== erase flash ====\n");
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");  
+	cout << endl;
+	cout << "== TBB ===================================================== erase flash ====" << endl;
+	cout << endl;
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;  
 
 }
 
@@ -842,8 +1004,9 @@ void ErasefCmd::send()
 	TBBEraseImageEvent event;
 	event.board = getBoard();
 	event.image = itsPage;
-	logMessage(cout,formatString(" %2d  erasing flash memory of image %d\n", getBoard(), itsPage));
-	logMessage(cout,"     erasing will take about 8 seconds");	
+	cout << formatString(" %2d  erasing flash memory of image %d", getBoard(), itsPage) << endl;
+	cout << endl;
+	cout << "     erasing will take about 8 seconds" << endl;	
 	itsPort.send(event);
 	itsPort.setTimer((long)16);
 }
@@ -854,9 +1017,9 @@ GCFEvent::TResult ErasefCmd::ack(GCFEvent& e)
 	TBBEraseImageAckEvent ack(e);
 	  
 	if (ack.status_mask & TBB_SUCCESS) {
-		logMessage(cout,formatString(" %2d  image is erased",getBoard()));
+		cout << formatString(" %2d  image is erased",getBoard()) << endl;
 	}	else {	
-		logMessage(cout,formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()));
+		cout << formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()) << endl;
 	}
 	
 	setCmdDone(true);
@@ -870,9 +1033,11 @@ ReadfCmd::ReadfCmd(GCFPortInterface& port) : Command(port)
 {
 	//memset(itsFileName,'\0',sizeof(itsFileName));
 	//memset(itsPageData,0,sizeof(itsPageData));
-	logMessage(cout,"\n== TBB ====================================================== read flash ====\n");
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");  
+	cout << endl;
+	cout << "== TBB ====================================================== read flash ====" << endl;
+	cout << endl;
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;  
 }
 
 //-----------------------------------------------------------------------------
@@ -881,8 +1046,9 @@ void ReadfCmd::send()
 	TBBReadImageEvent event;
 	event.board = getBoard();
 	event.image = itsPage;
-	logMessage(cout,formatString(" %2d  reading flash memory of image %d\n", getBoard(), itsPage));
-	logMessage(cout,"     reading will take about 12 seconds");	
+	cout << formatString(" %2d  reading flash memory of image %d", getBoard(), itsPage) << endl;
+	cout << endl;
+	cout << "     reading will take about 12 seconds" << endl;	
 	itsPort.send(event);
 	itsPort.setTimer((long)24);
 }
@@ -893,9 +1059,9 @@ GCFEvent::TResult ReadfCmd::ack(GCFEvent& e)
 	TBBReadImageAckEvent ack(e);
 
 		if (ack.status_mask & TBB_SUCCESS) {
-			logMessage(cout,formatString(" %2d  image is read",getBoard()));
+			cout << formatString(" %2d  image is read",getBoard()) << endl;
 		}	else {	
-			logMessage(cout,formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()));
+			cout << formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()) << endl;
 		}
 
 		
@@ -911,9 +1077,11 @@ WritefCmd::WritefCmd(GCFPortInterface& port) : Command(port)
 {
 	memset(itsFileNameTp,'\0',sizeof(itsFileNameTp));
 	memset(itsFileNameMp,'\0',sizeof(itsFileNameMp));
-	logMessage(cout,"\n== TBB ===================================================== write flash ====\n");
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");  
+	cout << endl;
+	cout << "== TBB ===================================================== write flash ====" << endl;
+	cout << endl;
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;  
 }
 
 //-----------------------------------------------------------------------------
@@ -925,8 +1093,9 @@ void WritefCmd::send()
 	event.version = static_cast<int32>(round(itsVersion * 10.));
 	memcpy(event.filename_tp,itsFileNameTp,sizeof(itsFileNameTp));
 	memcpy(event.filename_mp,itsFileNameMp,sizeof(itsFileNameMp));
-	logMessage(cout,formatString(" %2d  writing flash memory of image %d\n", getBoard(), itsPage));
-	logMessage(cout,"     writing will take about 25 seconds");	
+	cout << formatString(" %2d  writing flash memory of image %d", getBoard(), itsPage) << endl;
+	cout << endl;
+	cout << "     writing will take about 25 seconds" << endl;	
 	itsPort.send(event);
 	itsPort.setTimer((long)60);
 }
@@ -936,9 +1105,9 @@ GCFEvent::TResult WritefCmd::ack(GCFEvent& e)
 {
 	TBBWriteImageAckEvent ack(e);
 	if (ack.status_mask & TBB_SUCCESS) {
-		logMessage(cout,formatString(" %2d  image is written",getBoard()));
+		cout << formatString(" %2d  image is written",getBoard()) << endl;
 	}	else {	
-		logMessage(cout,formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()));
+		cout << formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()) << endl;
 	}
 	
 	setCmdDone(true);
@@ -949,7 +1118,9 @@ GCFEvent::TResult WritefCmd::ack(GCFEvent& e)
 //---- IMAGE INFO -------------------------------------------------------------
 ImageInfoCmd::ImageInfoCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ===================================================== image info ====\n");
+	cout << endl;
+	cout << "== TBB ===================================================== image info ====" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -965,14 +1136,15 @@ void ImageInfoCmd::send()
 GCFEvent::TResult ImageInfoCmd::ack(GCFEvent& e)
 {
 	TBBImageInfoAckEvent ack(e);
-	logMessage(cout,formatString("Reading image information from TBB %d\n", getBoard()));
-	logMessage(cout,"IMAGE  SW      Flash date_time      TP file name    MP file name");
-	logMessage(cout,"-----  ------  -------------------  --------------  --------------");  
+	cout << formatString("Reading image information from TBB %d", getBoard()) << endl;
+	cout << endl;
+	cout << "IMAGE  SW      Flash date_time      TP file name    MP file name" << endl;
+	cout << "-----  ------  -------------------  --------------  --------------" << endl;  
 	if (ack.status_mask & TBB_SUCCESS) {
 		for (int image = 0; image < 32; image++) {	
 			if (ack.write_date[image] == 0xFFFFFFFF) {
-				//logMessage(cout,formatString("  %2d   no information",image));
-				logMessage(cout,formatString("  %2d   free",image));
+				//cout << formatString("  %2d   no information",image) << endl;
+				cout << formatString("  %2d   free",image) << endl;
 			} else {
 				time_t write_time;
 				struct tm t;
@@ -981,17 +1153,17 @@ GCFEvent::TResult ImageInfoCmd::ack(GCFEvent& e)
 				write_time = static_cast<time_t>(ack.write_date[image]);
 				t = *gmtime(&write_time);
 				version = static_cast<double>(ack.image_version[image] / 10.);
-				logMessage(cout,formatString("  %2d   V%5.1lf  %d-%d-%d_%d:%02d:%02d  %-14.14s  %-14.14s",
+				cout << formatString("  %2d   V%5.1lf  %02d-%02d-%4d %2d:%02d:%02d  %-14.14s  %-14.14s",
 									 	image,
 										version, 
 									 	t.tm_mday,t.tm_mon+1,t.tm_year+1900,
 										t.tm_hour,t.tm_min,t.tm_sec,
 										ack.tp_file_name[image],
-										ack.mp_file_name[image]));
+										ack.mp_file_name[image]) << endl;;
 			}
 		}
 	}	else {	
-		logMessage(cout,formatString("TBB %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()));
+		cout << formatString("TBB %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()) << endl;
 	}
 	
 	setCmdDone(true);
@@ -1004,9 +1176,11 @@ GCFEvent::TResult ImageInfoCmd::ack(GCFEvent& e)
 //---- READW -------------------------------------------------------------------
 ReadwCmd::ReadwCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ======================================================= read DDR2 ====\n");
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");  
+	cout << endl;
+	cout << "== TBB ======================================================= read DDR2 ====" << endl;
+	cout << endl;
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;  
 }
 
 //-----------------------------------------------------------------------------
@@ -1027,11 +1201,11 @@ GCFEvent::TResult ReadwCmd::ack(GCFEvent& e)
 	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
 		if (isSelected(bnr) ) {
 			if (ack.status_mask & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  MP[%u] Addr[0x%08X]  [0x%08X] [0x%08X]"
-						,bnr, itsMp, itsAddr, ack.wordlo, ack.wordhi ));
+				cout << formatString(" %2d  MP[%u] Addr[0x%08X]  [0x%08X] [0x%08X]"
+						,bnr, itsMp, itsAddr, ack.wordlo, ack.wordhi ) << endl;
 			}	else {	
-				logMessage(cout,formatString(" %2d  %s"
-						,bnr, getDriverErrorStr(ack.status_mask).c_str()));
+				cout << formatString(" %2d  %s"
+						,bnr, getDriverErrorStr(ack.status_mask).c_str()) << endl;
 				itsAddr = itsStopAddr - 1;
 			}
 		}
@@ -1050,7 +1224,9 @@ GCFEvent::TResult ReadwCmd::ack(GCFEvent& e)
 //---- WRITEW -------------------------------------------------------------------
 WritewCmd::WritewCmd(GCFPortInterface& port) : Command(port)
 {
-	logMessage(cout,"\n== TBB ====================================================== write DDR2 ====\n");
+	cout << endl;
+	cout << "== TBB ====================================================== write DDR2 ====" << endl;
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
@@ -1070,14 +1246,14 @@ void WritewCmd::send()
 GCFEvent::TResult WritewCmd::ack(GCFEvent& e)
 {
 	TBBWritewAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");    
+	cout << "TBB  Info" << endl;
+	cout << "---  -------------------------------------------------------" << endl;    
 	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
 		if (isSelected(bnr) ) {
 			if (ack.status_mask & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  DDR2 write TBB_SUCCESS",bnr ));
+				cout << formatString(" %2d  DDR2 write TBB_SUCCESS",bnr ) << endl;
 			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask).c_str()));
+				cout << formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask).c_str()) << endl;
 			}
 		}
 	}
@@ -1090,26 +1266,32 @@ GCFEvent::TResult WritewCmd::ack(GCFEvent& e)
 
 //---- TESTDDR ----------------------------------------------------------------
 TestDdrCmd::TestDdrCmd(GCFPortInterface& port) : Command(port),
-	itsCmdStage(0),itsMp(0), itsAddr(0), itsAddrLine(0), itsTestPatern(1), itsWordLo(0), itsWordHi(0)
+	itsCmdStage(0),itsMp(0), itsAddr(0), itsAddrLine(0), itsTestPatern(1), itsWordLo(0), itsWordHi(0),
+	itsAddrLineErrors(0), itsDataLineErrors(0)
 {
-	logMessage(cout,"\n==== TBB-board, test ddr =================================================\n");	
+	cout << endl;
+	cout << "==== TBB-board, test ddr =================================================" << endl;	
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
 void TestDdrCmd::send()
 {
 	if ((itsCmdStage == 0)&&(itsMp == 0)&&(itsAddrLine == 0)) {
-		logMessage(cout,formatString("Testing DDR memory address lines of board %d\n",getBoard()));
-		logMessage(cout,"Mp  Addr   Write  Read                                 ");
-		logMessage(cout,"Nr  Line   DDR    DDR     Info                         ");
-		logMessage(cout,"--  -----  -----  -----   -----------------------------");
+		cout << formatString("Testing DDR memory address lines of board %d",getBoard()) << endl;
+		cout << endl;
+		cout << "Mp  Addr   Write  Read                                 " << endl;
+		cout << "Nr  Line   DDR    DDR     Info                         " << endl;
+		cout << "--  -----  -----  -----   -----------------------------" << endl;
 	}
 	
 	if ((itsCmdStage == 2)&&(itsMp == 0)&&(itsTestPatern == 1)) {
-		logMessage(cout,formatString("\nTesting DDR memory data lines of board %d\n",getBoard()));
-		logMessage(cout,"Mp  Write     Read      Write      Read                              ");
-		logMessage(cout,"Nr  WordLow   WordLow   WordHigh   WordHigh  Info                         ");
-		logMessage(cout,"--  --------  --------  --------   --------  ------------------------");
+		cout << endl;
+		cout << formatString("Testing DDR memory data lines of board %d",getBoard()) << endl;
+		cout << endl;
+		cout << "Mp  Write     Read      Write      Read                              " << endl;
+		cout << "Nr  WordLow   WordLow   WordHigh   WordHigh  Info                    " << endl;
+		cout << "--  --------  --------  --------   --------  ------------------------" << endl;
 	}
 	switch (itsCmdStage) {
 			
@@ -1162,7 +1344,7 @@ GCFEvent::TResult TestDdrCmd::ack(GCFEvent& e)
 		case 0: {
 			TBBWritewAckEvent ack(e);
 			if (!(ack.status_mask & TBB_SUCCESS)) {
-				logMessage(cout,formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()));
+				cout << formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()) << endl;
 			}
 			itsAddr = (1 << itsAddrLine);
 			itsAddrLine++;
@@ -1177,14 +1359,15 @@ GCFEvent::TResult TestDdrCmd::ack(GCFEvent& e)
 			TBBReadwAckEvent ack(e);
 			if (ack.status_mask & TBB_SUCCESS) {
 				if (ack.wordlo == itsAddrLine) {
-					logMessage(cout,formatString("%2d  %5d  %5d  %5d   SAME",
-						itsMp, itsAddrLine, itsAddrLine, ack.wordlo));
+					cout << formatString("%2d  %5d  %5d  %5d   SAME",
+						itsMp, itsAddrLine, itsAddrLine, ack.wordlo) << endl;
 				} else {
-					logMessage(cout,formatString("%2d  %5d  %5d  %5d   FAULT",
-						itsMp, itsAddrLine, itsAddrLine, ack.wordlo ));
+					cout << formatString("%2d  %5d  %5d  %5d   FAULT",
+						itsMp, itsAddrLine, itsAddrLine, ack.wordlo ) << endl;
+					itsAddrLineErrors++;
 				}
 			} else {
-				logMessage(cout,formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()));
+				cout << formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()) << endl;
 			}
 			itsAddr = (1 << itsAddrLine);
 			itsAddrLine++;
@@ -1205,7 +1388,7 @@ GCFEvent::TResult TestDdrCmd::ack(GCFEvent& e)
 		case 2: {
 			TBBWritewAckEvent ack(e);
 			if (!(ack.status_mask & TBB_SUCCESS)) {
-				logMessage(cout,formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()));
+				cout << formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()) << endl;
 			}
 			itsAddr++;
 			itsTestPatern <<= 1;
@@ -1222,14 +1405,15 @@ GCFEvent::TResult TestDdrCmd::ack(GCFEvent& e)
 			TBBReadwAckEvent ack(e);
 			if (ack.status_mask & TBB_SUCCESS) {
 				if ((ack.wordlo == itsTestPatern)&&(ack.wordhi == ~itsTestPatern)) {
-					logMessage(cout,formatString("%2d  %08X  %08X  %08X  %08X   SAME",
-						itsMp, itsTestPatern, ack.wordlo, ~itsTestPatern, ack.wordhi));
+					cout << formatString("%2d  %08X  %08X  %08X  %08X   SAME",
+						itsMp, itsTestPatern, ack.wordlo, ~itsTestPatern, ack.wordhi) << endl;
 				} else {
-					logMessage(cout,formatString("%2d  %08X  %08X  %08X  %08X   FAULT",
-						itsMp, itsTestPatern, ack.wordlo, ~itsTestPatern, ack.wordhi));
+					cout << formatString("%2d  %08X  %08X  %08X  %08X   FAULT",
+						itsMp, itsTestPatern, ack.wordlo, ~itsTestPatern, ack.wordhi) << endl;
+					itsDataLineErrors++;
 				}
 			} else {
-				logMessage(cout,formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()));
+				cout << formatString(" %2d  %s",getBoard(), getDriverErrorStr(ack.status_mask).c_str()) << endl;
 			}
 			itsAddr++;
 			itsTestPatern <<= 1;
@@ -1241,6 +1425,17 @@ GCFEvent::TResult TestDdrCmd::ack(GCFEvent& e)
 				itsCmdStage = 2;
 				itsMp++;
 				if (itsMp == 4) {
+					cout << formatString("  == summary ==") << endl;
+					if (itsAddrLineErrors != 0) {
+						cout << formatString("  %d  Addressline ERRORS",itsAddrLineErrors) << endl;
+					} else {
+						cout << formatString("  All Addresslines OK") << endl;
+					}
+					if (itsDataLineErrors != 0) {
+						cout << formatString("  %d  Dataline ERRORS",itsDataLineErrors) << endl;
+					} else {
+						cout << formatString("  All Datalines OK") << endl;
+					}
 					setCmdDone(true);
 				}
 			}
@@ -1253,16 +1448,22 @@ GCFEvent::TResult TestDdrCmd::ack(GCFEvent& e)
 }
 
 //---- READR -------------------------------------------------------------------
-ReadrCmd::ReadrCmd(GCFPortInterface& port) : Command(port)
+ReadrCmd::ReadrCmd(GCFPortInterface& port) : Command(port),
+	itsMp(0), itsPid(0), itsRegId(0)
 {
-	logMessage(cout,"\n==== TBB-board, read register ================================================\n");	
+	cout << endl;
+	cout << "==== TBB-board, read register ================================================" << endl;
 }
 
 //-----------------------------------------------------------------------------
 void ReadrCmd::send()
 {
 	TBBReadrEvent event;
-	event.board = (uint32)getBoard();
+	event.board = (int32)getBoard();
+	event.mp = itsMp;
+	event.pid = itsPid;
+	event.regid = itsRegId;
+	
 	itsPort.send(event);
 	itsPort.setTimer((long)1);
 }
@@ -1271,16 +1472,23 @@ void ReadrCmd::send()
 GCFEvent::TResult ReadrCmd::ack(GCFEvent& e)
 {
 	TBBReadrAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");    
-	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
-		if (isSelected(bnr) ) {
-			if (ack.status_mask & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  read register",bnr ));
-			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask).c_str()));
+	
+	cout <<   "Board : " <<  getBoard() << endl;
+	if (ack.status_mask & TBB_SUCCESS) {
+		cout << "MP    : " << itsMp << endl;
+		cout << "PID   : " << itsPid << endl;
+		cout << "REGID : " << itsRegId << endl;
+		cout << "Received data : "; 
+		        
+		for (int i = 0; i < (REG_SIZE[itsPid][itsRegId]); i++) {
+			if (i % 4 == 0) {
+				if (i != 0) cout << endl << "                ";
+				cout << formatString("0x%02x: ",(i * 4));
 			}
+			cout << formatString("%08x ",ack.data[i]);
 		}
+	} else {
+		cout << "ERROR : " << getDriverErrorStr(ack.status_mask).c_str();	
 	}
 	
 	setCmdDone(true);
@@ -1289,16 +1497,28 @@ GCFEvent::TResult ReadrCmd::ack(GCFEvent& e)
 }
 
 //---- WRITER -------------------------------------------------------------------
-WriterCmd::WriterCmd(GCFPortInterface& port) : Command(port)
+WriterCmd::WriterCmd(GCFPortInterface& port) : Command(port),
+	itsMp(0), itsPid(0), itsRegId(0)
 {
-	logMessage(cout,"\n==== TBB-board, write register ===============================================\n");	
+	for (int i = 0; i < 16; i++) {
+		itsData[i] = 0;
+	}
+	cout << endl;
+	cout << "==== TBB-board, write register ===============================================" << endl;	
+	cout << endl;
 }
 
 //-----------------------------------------------------------------------------
 void WriterCmd::send()
 {
 	TBBWriterEvent event;
-	event.board = (uint32)getBoard();
+	event.board = (int32)getBoard();
+	event.mp = itsMp;
+	event.pid = itsPid;
+	event.regid = itsRegId;
+	for (int i = 0; i < (REG_SIZE[itsPid][itsRegId]); i++) {
+		event.data[i] = itsData[i];
+	}
 	itsPort.send(event);
 	itsPort.setTimer((long)1);
 }
@@ -1307,19 +1527,23 @@ void WriterCmd::send()
 GCFEvent::TResult WriterCmd::ack(GCFEvent& e)
 {
 	TBBWriterAckEvent ack(e);
-	logMessage(cout,"TBB  Info");
-	logMessage(cout,"---  -------------------------------------------------------");    
-	for (int bnr=0; bnr < getMaxSelections(); bnr++) {
-		if (isSelected(bnr) ) {
-			if (ack.status_mask & TBB_SUCCESS) {
-				logMessage(cout,formatString(" %2d  write register",
-						bnr ));
-			}	else {	
-				logMessage(cout,formatString(" %2d  %s",bnr, getDriverErrorStr(ack.status_mask).c_str()));
+	
+	cout <<   "Board : " <<  getBoard() << endl;
+	if (ack.status_mask & TBB_SUCCESS) {
+		cout << "MP    : " << itsMp << endl;
+		cout << "PID   : " << itsPid << endl;
+		cout << "REGID : " << itsRegId << endl;
+		cout << "Transmitted data : "; 
+		for (int i = 0; i < (REG_SIZE[itsPid][itsRegId]); i++) {
+			if (i % 4 == 0) {
+				if (i != 0) cout << endl << "                ";
+				cout << formatString("0x%02x: ",(i * 4));
 			}
+			cout << formatString("%08x ",itsData[i]);
 		}
+	}	else {	
+		cout << getDriverErrorStr(ack.status_mask).c_str();
 	}
-	
 	setCmdDone(true);
 
 	return(GCFEvent::HANDLED);
@@ -1332,7 +1556,9 @@ ReadPageCmd::ReadPageCmd(GCFPortInterface& port) : Command(port),
 	itsFreqBands(0),itsTotalSamples(0),itsTotalBands(0), itsBandNr(0), itsSliceNr(0)
 {
 	for (int i = 0; i < 512; i++) itsData[i] = 0;
-	logMessage(cout,"\n==== TBB-board, readx register ================================================\n");
+	cout << endl;
+	cout << "==== TBB-board, readx register ================================================" << endl;
+	cout << endl;
 }
 //-----------------------------------------------------------------------------
 void ReadPageCmd::send()
@@ -1432,7 +1658,7 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 
 	int16 val[1400];
 	
-	double 				bar_size = 40;
+	double 				bar_size = 50;
 	static double	bar_interval = 1;
 	static double	bar_buff = 0;
 		
@@ -1446,12 +1672,12 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 			itsSize = ack.rcu_pages[itsRcu];
 			itsBoard = ack.rcu_on_board[itsRcu];
 			//itsMp = static_cast<int32>(ack.rcu_on_input[itsRcu] / 4);
-			logMessage(cout,formatString("Rcu-%d Board[%d] Mp[%d]",itsRcu,itsBoard,itsMp));
+			//cout << formatString("Rcu-%d Board[%d] Mp[%d]",itsRcu,itsBoard,itsMp) << endl;
 			
 			itsStartPage += itsStartAddr;
 			
 			if (itsState == 'F') {
-				logMessage(cout,"Rcu not allocated");
+				cout << "Rcu not allocated" << endl;
 				itsCmdStage = 10;
 			}
 		} break;
@@ -1459,15 +1685,15 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 		case 1: {
   		TBBSizeAckEvent ack(e);
   		if (!(ack.status_mask[itsBoard] & TBB_SUCCESS)) {
-				logMessage(cout,formatString("%s",getDriverErrorStr(ack.status_mask[itsBoard]).c_str()));
+				cout << formatString("%s",getDriverErrorStr(ack.status_mask[itsBoard]).c_str()) << endl;
 				itsCmdStage = 10;
 			} else {
 				itsTotalSize = ack.npages[itsBoard] / 4;
 				
 				if ((itsStartPage < itsStartAddr) || ((itsStartPage + itsPages) > (itsStartAddr + itsSize))) {
-					logMessage(cout,formatString("Requested Page belongs not to rcu-%d", itsRcu));			 
+					cout << formatString("Requested Page belongs not to rcu %d", itsRcu) << endl;			 
 				} else {
-					logMessage(cout,formatString("StartPage = %u ",itsStartPage));			 
+					//cout << formatString("StartPage = %u ",itsStartPage) << endl;			 
 				}
 			}
 		} break;
@@ -1475,7 +1701,7 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 		case 2: {
 			TBBWriterAckEvent ack(e);
 			if (!(ack.status_mask & TBB_SUCCESS)) {
-				logMessage(cout,formatString("%s",getDriverErrorStr(ack.status_mask).c_str()));
+				cout << formatString("%s",getDriverErrorStr(ack.status_mask).c_str()) << endl;
 				itsCmdStage = 10;
 			}
 		} break;
@@ -1483,7 +1709,7 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 		case 3: {
 			TBBWriterAckEvent ack(e);
 			if (!(ack.status_mask & TBB_SUCCESS)) {
-				logMessage(cout,formatString("%s",getDriverErrorStr(ack.status_mask).c_str()));
+				cout << formatString("%s",getDriverErrorStr(ack.status_mask).c_str()) << endl;
 				itsCmdStage = 10;
 			}
 		} break;
@@ -1491,7 +1717,7 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 		case 4: {
 			TBBReadxAckEvent ack(e);
 			if (!(ack.status_mask & TBB_SUCCESS)) {
-				logMessage(cout,formatString("%s", getDriverErrorStr(ack.status_mask).c_str()));
+				cout << formatString("%s", getDriverErrorStr(ack.status_mask).c_str()) << endl;
 				itsCmdStage = 10;
 		  }
 		  
@@ -1504,7 +1730,7 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 		case 5: {
 			TBBReadxAckEvent ack(e);
 			if (!(ack.status_mask & TBB_SUCCESS)) {
-				logMessage(cout,formatString("%s", getDriverErrorStr(ack.status_mask).c_str()));
+				cout << formatString("%s", getDriverErrorStr(ack.status_mask).c_str()) << endl;
 				itsCmdStage = 10;
 		  }
 			for (int32 dn = 0; dn < 256; dn++) { 
@@ -1547,13 +1773,13 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 			if (itsTime < 0) {
 				cout << "Time            : invalid" << endl;
 			} else {
-				cout << "Time of 1e sample/slice  : " << timestring << " (" << (uint32)itsTime << ")" << endl ;
+				cout << "Time of 1e sample/slice    : " << timestring << " (" << (uint32)itsTime << ")" << endl ;
 			}
 			if (itsTotalBands > 0) {
-				cout << "Slice number of 1e slice : " << itsSliceNr << endl;
-				cout << "Band number of 1e sample : " << itsBandNr << endl;
-				cout << "Number of bands          : " << itsTotalBands << endl;
-				cout << "Data file format         : binary complex(int16 Re, int16 Im)" << endl;
+				cout << "Slice number of 1e slice   : " << itsSliceNr << endl;
+				cout << "Band number of 1e sample   : " << itsBandNr << endl;
+				cout << "Number of bands            : " << itsTotalBands << endl;
+				cout << "Data file format           : binary complex(int16 Re, int16 Im)" << endl;
 			}	else {
 				cout << "Sample number of 1e sample : " << itsSampleNr << endl;
 				cout << "Data file format           : binary  int16" << endl;
@@ -1561,13 +1787,13 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 			
 			// print size of progressbar on screen
 			bar_interval = itsPages / bar_size;
-			
-			cout << "|";
+			cout << endl;
+			cout <<   "Progress |";
 			for (int i = 0; i < bar_size; i++) {
 				cout << "-";
 			}
 			cout << "|" << endl ;
-			cout << "|";
+			cout <<   "         |";
 						
 			
 			snprintf(basefilename, PATH_MAX, "%s_%s_%02d%02d",(itsTotalBands == 0)?"rw":"sb",timestring,itsStationId,itsRcuId);
@@ -1576,7 +1802,7 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 		
 		// print receive progress on screen
 		if (bar_interval < 1.) {
-			int count = ceil(bar_buff / bar_interval);
+			int count = static_cast<int>(ceil(bar_buff / bar_interval));
 			for (int i = 0; i < count; i++) {
 				cout << "x" << flush;
 			}
@@ -1656,12 +1882,19 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 		}	else {
 			// last page received, print last info on screen
 			cout << "|" << endl;
-			cout << "Total received frames : " << itsPage << endl;
+			cout << endl;
+			cout << "Total received pages  : " << itsPage;
+			if (itsPage > 1) {
+				cout << " (page " << itsStartPage << " .. " << (itsStartPage + itsPage - 1) << ")" << endl;
+			} else {
+				cout << " (page " << itsStartPage << ")" << endl;
+			}
 			cout << "Total received samples: " << itsTotalSamples << endl;
 
 			if (val_cnt > 0) {
 				cout << "Filename        : " << basefilename << ".nfo" << endl;
-				cout << "                : " << basefilename << ".dat" << endl;;
+				cout << "                : " << basefilename << ".dat" << endl;
+				cout << endl;
 				cout << "Each frame exists of:" << endl;
 				cout << "  HEADER(88 bytes) + PAYLOAD(see header for size) + PAYLOAD_CRC(4 bytes)" << endl;
 			} else {
@@ -1711,47 +1944,69 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 
 
 //---- HELP --------------------------------------------------------------------
-void TBBCtl::help()
-{
-	logMessage(cout,"\n==== tbbctl command usage =========================================================================================\n");
-	
-	logMessage(cout,"#  --command                : all boards or active rcu's are selected, and will be displayed");
-	logMessage(cout,"#  --command --select=<set> : only information for all selected boards or rcu's is displayed\n"
-									"#    Example: --select=0,1,4  or  --select=0:6  or  --select=0,1,2,8:11\n");
-	logMessage(cout,"tbbctl --alloc [--select=<set>]                                    # allocate memmory locations for selected rcu's");
-	logMessage(cout,"tbbctl --free [--select=<set>]                                     # free memmory locations for selected rcu's");
-	logMessage(cout,"tbbctl --record [--select=<set>]                                   # start recording on selected rcu's");
-	logMessage(cout,"tbbctl --stop [--select=<set>]                                     # stop recording on all selected rcu's");
-	logMessage(cout,"tbbctl --rcuinfo [--select=<set>]                                  # list rcu info for all allocated rcu's\n");
-	
-	logMessage(cout,"tbbctl --release [--select=<set>]                                  # release trigger system for all selected rcu's");
-	logMessage(cout,"tbbctl --generate [--select=<set>]                                 # generate a trigger for all selected rcu's");	
-	logMessage(cout,"tbbctl --setup=level,mode,filter,window,dummy [--select=<set>]     # setup trigger system for all selected rcu's");
-	logMessage(cout,"tbbctl --coef=c0,c1,c2,c3 [--select=<set>]                         # set trigger coeffients for all selected rcu's");
-	logMessage(cout,"tbbctl --triginfo=rcu                                              # get trigger info for selected rcu\n");
-	
-	logMessage(cout,"tbbctl --read=rcunr,secondstime,sampletime,prepages,postpages      # transfer recorded data from rcunr to CEP, use --mode first");
-	logMessage(cout,"tbbctl --mode=board,[transient | subbands]                         # set mode to configure UDP/IP header for CEP"); 
-	logMessage(cout,"tbbctl --version [--select=<set>]                                  # get version information from selected boards");
-	logMessage(cout,"tbbctl --status [--select=<set>]                                   # get status information from selected boards");	
-	logMessage(cout,"tbbctl --size [--select=<set>]                                     # get installed memory size from selected boards\n");
-	
-	logMessage(cout,"tbbctl --eraseimage=board,image                                    # erase image from flash");
-	logMessage(cout,"tbbctl --readimage=board,image                                     # read image from flash to file");
-	logMessage(cout,"tbbctl --writeimage=boardnr,imagenr,version,tpfilename,mpfilename  # write tp and mp file to imagenr on boardnr");
-	logMessage(cout,"                                                                   # version is the sw version of the image stored");
-	logMessage(cout,"tbbctl --imageinfo=board                                           # read info from all images on board\n");
-	
-	logMessage(cout,"tbbctl --readddr=board,mp,addr,size                                # DDR2 read, (size x 2) words starting on addr");
-	logMessage(cout,"tbbctl --writeddr=board,mp,addr,wordL,wordH                        # DDR2 write, 2 words to starting on addr");
-	logMessage(cout,"tbbctl --testddr=board                                             # DDR2 memory test, adress and data lines");
-	logMessage(cout,"tbbctl --readpage=rcunr,startpage,npages                           # DDR2 read npages from rcunr, starting on startpage");
-	logMessage(cout,"tbbctl --clear [--select=<set>]                                    # clear selected board");
-	logMessage(cout,"tbbctl --reset [--select=<set>]                                    # reset to factory images on selected boards");
-	logMessage(cout,"tbbctl --config=imagenr [--select=<set>]                           # reconfigure TP and MP's with imagenr [0..31] on ");
-	logMessage(cout,"                                                                   # selected boards");
-	logMessage(cout,"tbbctl --help                                                      # this help screen\n");
-	logMessage(cout,"===================================================================================================================");
+void TBBCtl::commandHelp(int level)
+{
+	cout << endl;
+	cout << endl;
+	cout << "> > > > tbbctl COMMAND USAGE > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >" << endl;
+	cout << endl;
+	cout << " #  --command                : all boards or active rcu's are selected, and will be displayed" << endl;
+	cout << " #  --command --select=<set> : only information for all selected boards or rcu's is displayed"  << endl;
+	cout << " #    Example: --select=0,1,4  or  --select=0:6  or  --select=0,1,2,8:11" << endl;
+	cout << endl;
+	cout << "______| CHANNEL |_________________________________________________________________________________________________________" << endl;
+	cout << " tbbctl --rcuinfo [--select=<set>]                                  # list rcu info, only allocated rcu's are listed" << endl;
+	cout << " tbbctl --alloc [--select=<set>]                                    # allocate memmory locations for selected rcu's" << endl;
+	cout << " tbbctl --free [--select=<set>]                                     # free memmory locations for selected rcu's" << endl;
+	cout << " tbbctl --record [--select=<set>]                                   # start recording on selected rcu's" << endl;
+	cout << " tbbctl --stop [--select=<set>]                                     # stop recording on selected rcu's" << endl;
+	cout << " tbbctl --mode=board,[transient | subbands]                         # set mode to configure UDP/IP header for CEP tranport" << endl;
+	cout << " tbbctl --read=rcunr,secondstime,sampletime,prepages,postpages      # transfer recorded data from rcunr to CEP, " << endl;
+	cout << "                                                                    # use first --mode to setup UDP/IP header" << endl;   
+	cout << "______| TRIGGER |_________________________________________________________________________________________________________" << endl;
+	cout << " tbbctl --release [--select=<set>]                                  # release trigger system for selected rcu's" << endl;
+	cout << " tbbctl --generate [--select=<set>]                                 # generate a trigger for selected rcu's" << endl;	
+	cout << " tbbctl --setup=level,start,stop,filter,window,x [--select=<set>]   # setup trigger system for selected rcu's, x = dummy" << endl;
+	cout << " tbbctl --coef=c0,c1,c2,c3 [--select=<set>]                         # set trigger coeffients for elected rcu's" << endl;
+	cout << " tbbctl --triginfo=rcu                                              # get trigger info for selected rcu" << endl;
+	cout << " tbbctl --listen                                                    # put in listen mode, all triggers will be listed" << endl;
+	cout << endl;
+	cout << "______| INFO |____________________________________________________________________________________________________________" << endl;
+	cout << " tbbctl --version [--select=<set>]                                  # get version information from selected boards" << endl;
+	cout << " tbbctl --status [--select=<set>]                                   # get status information from selected boards" << endl;	
+	cout << " tbbctl --size [--select=<set>]                                     # get installed memory size from selected boards" << endl;
+	cout << endl;
+	cout << "______| DDR |_____________________________________________________________________________________________________________" << endl;
+	cout << " tbbctl --readpage=rcunr,startpage,npages                           # ddr read npages from rcunr, starting on startpage" << endl;
+	if (level == 3) {
+		cout << " tbbctl --testddr=board                                             # ddr memory test, adress and data lines" << endl;
+		cout << " tbbctl --readddr=board,mp,addr,size                                # ddr read, (size x 2) words starting on addr" << endl;
+		cout << " tbbctl --writeddr=board,mp,addr,wordL,wordH                        # ddr write, 2 words to starting on addr" << endl;
+		cout << endl;
+		cout << "______| MP-REGISTER |_____________________________________________________________________________________________________" << endl;
+		cout << " tbbctl --readreg=board,mp,pid,regid                                # register read" << endl;
+		cout << " tbbctl --writereg=board,mp,pid,regid                               # register write" << endl;
+		cout << endl;
+		cout << "______| FLASH |___________________________________________________________________________________________________________" << endl;
+		cout << " tbbctl --eraseimage=board,image                                    # erase image from flash" << endl;
+		cout << " tbbctl --readimage=board,image                                     # read image from flash to file" << endl;
+		cout << " tbbctl --writeimage=boardnr,imagenr,version,tpfilename,mpfilename  # write tp and mp file to imagenr on boardnr" << endl;
+		cout << "                                                                    # version is the sw version of the image stored" << endl;
+	} 
+	if (level == 1) {
+		cout << endl;
+		cout << "______| FLASH |___________________________________________________________________________________________________________" << endl;
+	}
+	cout << " tbbctl --imageinfo=board                                           # read info from all images on board" << endl;
+	cout << " tbbctl --config=imagenr [--select=<set>]                           # reconfigure TP and MP's with imagenr [0..31] on " << endl;
+	cout << "                                                                    # selected boards" << endl;
+	cout << "__________________________________________________________________________________________________________________________" << endl;
+	cout << " tbbctl --clear [--select=<set>]                                    # clear selected board" << endl;
+	cout << " tbbctl --reset [--select=<set>]                                    # reset to factory images on selected boards" << endl;
+	cout << endl;
+	cout << " tbbctl --help                                                      # this help screen" << endl;
+	cout << "< < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < " << endl;
+	cout << endl;
 }
 //-----------------------------------------------------------------------------
 
@@ -1771,7 +2026,7 @@ TBBCtl::TBBCtl(string name, int argc, char** argv): GCFTask((State)&TBBCtl::init
 //-----------------------------------------------------------------------------
 TBBCtl::~TBBCtl()
 {
-  if (itsCommand)		{ delete itsCommand; }
+	if (itsCommand)		{ delete itsCommand; }
   if (itsCmdTimer)	{ delete itsCmdTimer; }
 }
 
@@ -1804,9 +2059,11 @@ GCFEvent::TResult TBBCtl::initial(GCFEvent& e, GCFPortInterface& port)
       itsMaxBoards		= ack.max_boards;
       itsActiveBoards	= ack.active_boards_mask;
 			itsMaxChannels = itsMaxBoards * 16;
-      //logMessage(cout,formatString("\nMax nr of TBB boards = %d",itsMaxBoards));
-			//logMessage(cout,formatString("Max nr of Channels   = %d\n",itsMaxChannels));
-			//logMessage(cout,formatString("Active boards mask   = 0x%03X",itsActiveBoards));
+      //cout << endl;
+      //cout << formatString("Max nr of TBB boards = %d",itsMaxBoards) << endl;
+			//cout << formatString("Max nr of Channels   = %d",itsMaxChannels)//cout << endl;;
+			//cout << endl;
+			//cout << formatString("Active boards mask   = 0x%03X",itsActiveBoards)//cout << endl;;
 			
 			// send subscribe 
       TBBSubscribeEvent subscribe;
@@ -1824,9 +2081,9 @@ GCFEvent::TResult TBBCtl::initial(GCFEvent& e, GCFPortInterface& port)
 
     case F_TIMER: {
       // try again
-      logMessage(cout,"========================================");
-      logMessage(cout,"  TBBDriver is not responding           ");
-      logMessage(cout,"========================================");
+      cout << "   =x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=" << endl;
+      cout << "   =x=         TBBDriver is NOT responding           =x=" << endl;
+			cout << "   =x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=" << endl;
       //itsServerPort.open();
       exit(EXIT_FAILURE);
     } break;
@@ -1852,7 +2109,7 @@ GCFEvent::TResult TBBCtl::docommand(GCFEvent& e, GCFPortInterface& port)
 	  	// reparse options
       itsCommand = parse_options(itsArgc, itsArgv);
       if (itsCommand == 0) {
-        logMessage(cerr,"Warning: no command specified.");
+        cout << "Warning: no command specified." << endl;
         exit(EXIT_FAILURE);
       }
       itsCommand->send();
@@ -1863,7 +2120,7 @@ GCFEvent::TResult TBBCtl::docommand(GCFEvent& e, GCFPortInterface& port)
     
     case F_DISCONNECTED: {
       port.close();
-      logMessage(cerr,formatString("Error: port '%s' disconnected.",port.getName().c_str()));
+      cout << formatString("Error: port '%s' disconnected.",port.getName().c_str()) << endl;
       exit(EXIT_FAILURE);
     } break;
 		
@@ -1871,20 +2128,17 @@ GCFEvent::TResult TBBCtl::docommand(GCFEvent& e, GCFPortInterface& port)
 			if (&port == itsCmdTimer) {
 				itsCommand->send();
 			} else {
-				logMessage(cout,"Timeout, tbbctl stopped\n");
+				cout << "Timeout, tbbctl stopped" << endl;
+				cout << endl;
 				TBBUnsubscribeEvent unsubscribe;
       	itsServerPort.send(unsubscribe);
     		GCFTask::stop();
     	}
 		} break;
     
-    case TBB_TRIG_GENERATE_ACK:
-    case TBB_TRIGGER: {
-    	itsServerPort.cancelAllTimers();
-    	itsServerPort.setTimer((long)5);
-    	status = itsCommand->ack(e); // handle the acknowledgement
+    case TBB_BOARDCHANGE: {
     } break;
-    	
+    		
     case TBB_ALLOC_ACK:
     case TBB_RCU_INFO_ACK:
     case TBB_FREE_ACK:
@@ -1893,7 +2147,9 @@ GCFEvent::TResult TBBCtl::docommand(GCFEvent& e, GCFPortInterface& port)
     case TBB_TRIG_RELEASE_ACK:
     case TBB_TRIG_SETUP_ACK:	
     case TBB_TRIG_COEF_ACK:
-    case TBB_TRIG_INFO_ACK:	
+    case TBB_TRIG_GENERATE_ACK:
+    case TBB_TRIG_INFO_ACK:
+    case TBB_TRIGGER:
     case TBB_READ_ACK:
     case TBB_MODE_ACK:
     case TBB_VERSION_ACK:
@@ -1913,28 +2169,28 @@ GCFEvent::TResult TBBCtl::docommand(GCFEvent& e, GCFPortInterface& port)
     case TBB_READX_ACK: {	
     	itsServerPort.cancelAllTimers();
     	status = itsCommand->ack(e); // handle the acknowledgement
-    	if (!itsCommand->isCmdDone()) {
+    	if (!itsCommand->isCmdDone() && itsCommand->isCmdSendNext()) {
     		// not done send next command
-    		//itsCommand->send();
     		itsCmdTimer->setTimer((long)0);
     	}
     } break;
 
     default: {
-      logMessage(cerr,"Error: unhandled event.");
-      logMessage(cerr,formatString("Error: unhandled event. %d",e.signal));
-      TBBUnsubscribeEvent unsubscribe;
-      itsServerPort.send(unsubscribe);
+      cout << "Error: unhandled event." << endl;
+      cout << formatString("Error: unhandled event. %d",e.signal) << endl;
+      //TBBUnsubscribeEvent unsubscribe;
+      //itsServerPort.send(unsubscribe);
       GCFTask::stop();
     } break;
   }
 	
 	if (itsCommand->isCmdDone()) {
-  	TBBUnsubscribeEvent unsubscribe;
-    itsServerPort.send(unsubscribe);
+  	//TBBUnsubscribeEvent unsubscribe;
+    //itsServerPort.send(unsubscribe);
+    cout << flush;
     GCFTask::stop();
-   }
-    	 
+  }
+	 	 
   return(status);
 }
 
@@ -1949,70 +2205,73 @@ Command* TBBCtl::parse_options(int argc, char** argv)
   
   while(1) {
   	static struct option long_options[] = {
-			{ "select",			required_argument,	0,	'l' }, //ok
-			{ "alloc",			no_argument,				0,	'a' }, //ok ??
-			{ "rcuinfo",		no_argument,				0,	'i' }, //ok ??
-			{ "free",				no_argument,				0,	'f' }, //ok ??
-		  { "record",			no_argument,				0,	'r' }, //ok ??
-		  { "stop",				no_argument,				0,	's' }, //ok ??
-		  { "release",		no_argument,				0,	'e' }, //ok ??
-		  { "generate",		no_argument,				0,	'g' }, //ok ??
-		  { "setup",			required_argument,	0,	't' }, //ok ??
-		  { "coef",				required_argument,	0,	'c' }, //ok ??
-		  { "triginfo",		required_argument,	0,	'I' }, //ok ??
-			{ "read",				required_argument,	0,	'R' }, //ok ??
-			{ "mode",				required_argument,	0,	'm' }, //ok ??
-			{ "version",		no_argument,				0,	'v' }, //ok
-			{ "size",				no_argument,				0,	'z' }, //ok
-			{ "status",			no_argument,				0,	'A' }, //ok
-			{ "readpage",		required_argument,	0,	'p' }, //ok ??
-			{ "clear",			no_argument,				0,	'C' }, //ok ??
-			{ "reset",			no_argument,				0,	'Z' }, //ok ??
-			{ "config",			required_argument,	0,	'S' }, //ok ??
-		  { "eraseimage",	required_argument,	0,	'1' }, //ok
-		  { "readimage",	required_argument,	0,	'2' }, //ok
-		  { "writeimage",	required_argument,	0,	'3' }, //ok
-			{ "imageinfo",	required_argument,	0,	'8' }, //ok
-		  { "readddr",		required_argument,	0,	'4' }, //ok
-		  { "writeddr",		required_argument,	0,	'5' }, //ok
-		  { "testddr",		required_argument,	0,	'9' }, //ok
-		  { "readreg",		required_argument,	0,	'6' }, //ok not in help
-		  { "writereg",		required_argument,	0,	'7' }, //ok not in help
-			{ "help",				no_argument,				0,	'h' }, //ok ??
+			{ "select",			required_argument,	0,	'l' }, 
+			{ "alloc",			no_argument,				0,	'a' }, 
+			{ "rcuinfo",		no_argument,				0,	'i' }, 
+			{ "free",				no_argument,				0,	'f' }, 
+		  { "record",			no_argument,				0,	'r' }, 
+		  { "stop",				no_argument,				0,	's' }, 
+		  { "release",		no_argument,				0,	'e' }, 
+		  { "generate",		no_argument,				0,	'g' }, 
+		  { "setup",			required_argument,	0,	't' }, 
+		  { "coef",				required_argument,	0,	'c' }, 
+		  { "triginfo",		required_argument,	0,	'I' }, 
+		  { "listen",     no_argument,				0,	'L' }, 
+			{ "read",				required_argument,	0,	'R' }, 
+			{ "mode",				required_argument,	0,	'm' }, 
+			{ "version",		no_argument,				0,	'v' }, 
+			{ "size",				no_argument,				0,	'z' }, 
+			{ "status",			no_argument,				0,	'A' }, 
+			{ "readpage",		required_argument,	0,	'p' }, 
+			{ "clear",			no_argument,				0,	'C' }, 
+			{ "reset",			no_argument,				0,	'Z' }, 
+			{ "config",			required_argument,	0,	'S' }, 
+		  { "eraseimage",	required_argument,	0,	'1' }, 
+		  { "readimage",	required_argument,	0,	'2' }, 
+		  { "writeimage",	required_argument,	0,	'3' }, 
+			{ "imageinfo",	required_argument,	0,	'8' }, 
+		  { "readddr",		required_argument,	0,	'4' }, 
+		  { "writeddr",		required_argument,	0,	'5' }, 
+		  { "testddr",		required_argument,	0,	'9' }, 
+		  { "readreg",		required_argument,	0,	'6' }, 
+		  { "writereg",		required_argument,	0,	'7' }, 
+			{ "help",				no_argument,				0,	'h' }, 
+			{ "expert",			no_argument,				0,	'X' }, 
 		  { 0, 					  0, 									0,	0 },
 		};
 
     int option_index = 0;
     int c = getopt_long(argc, argv,
-												"l:afrsegt:c:I:R:m:vzAp:CZS:1:2:3:8:4:5:9:6:7:h",
+												"l:afrsegt:c:I:LR:m:vzAp:CZS:1:2:3:8:4:5:9:6:7:hX",
 				long_options, &option_index);
-
-    if (c == -1)
+		
+    if (c == -1) {
 			break;
+		}
 
 		switch (c) {
 			
 			case 'l': { 	// --select
-	  		if (!command->getSelected()) {
+	  		if (!command->isSelectionDone()) {
   	  		if (optarg) {
   	      	if (!command) {
-  		  			logMessage(cerr,"Error: 'command' argument should come before --select argument");
+  		  			cout << "Error: 'command' argument should come before --select argument" << endl;
   		  			exit(EXIT_FAILURE);
   					}
   					select = strtolist(optarg, command->getMaxSelections());
   											
   	      	if (select.empty()) {
-  		  			logMessage(cerr,"Error: invalid or missing '--select' option");
+  		  			cout << "Error: invalid or missing '--select' option" << endl;
   		  			exit(EXIT_FAILURE);
   					}	else {
   						command->setSelected(true);
   					}
   	    	}	else {
-  	      	logMessage(cerr,"Error: option '--select' requires an argument");
+  	      	cout << "Error: option '--select' requires an argument" << endl;
   	      	exit(EXIT_FAILURE);
   	      }
 				} else {
-	      	logMessage(cerr,"Error: channels already selected");
+	      	cout << "Error: channels already selected" << endl;
 				}
 	    } break;
 	    
@@ -2056,15 +2315,15 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 				TrigReleaseCmd* trigreleasecmd = new TrigReleaseCmd(itsServerPort);
 				command = trigreleasecmd;
 				if (optarg) {
-					int channel = 0;
-					int numitems = sscanf(optarg, "%d",&channel);
-					if (numitems == 0 || numitems == EOF) {
-						logMessage(cerr,"Error: invalid number of arguments. Should be of the format "
-								"'--trigclr=rcu' ");  
+					int rcu = 0;
+					int numitems = sscanf(optarg, "%d",&rcu);
+					if (numitems == 0 || numitems == EOF || rcu < 0 || rcu >= MAX_N_RCUS) {
+						cout << "Error: invalid number of arguments. Should be of the format " << endl;
+						cout << "       '--trigclr=rcu' " << endl;  
 						exit(EXIT_FAILURE);
 					}
 					select.clear();
-		  		select.push_back(channel);
+		  		select.push_back(rcu);
 					command->setSelected(true);
 				}
 				
@@ -2083,24 +2342,32 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 				TrigSetupCmd* trigsetupcmd = new TrigSetupCmd(itsServerPort);
 				command = trigsetupcmd;
 				if (optarg) {
-					int level = 0;
-					int mode = 0;
-					int filter = 0;
-					int window = 0;
-					int dummy = 0;
-					int numitems = sscanf(optarg, "%x,%x,%x,%x,%x",&level, &mode, &filter, &window, &dummy);
-					if (numitems < 5 || numitems == EOF) {
-						logMessage(cerr,"Error: invalid number of arguments. Should be of the format "
-								"'--trigsetup=level,mode,filter,window,dummy'  (all hex values)");  
+					uint32 level = 0;
+					uint32 start = 0;
+					uint32 stop = 0;
+					uint32 filter = 0;
+					uint32 window = 0;
+					uint32 dummy = 0;
+					int numitems = sscanf(optarg, "%u,%u,%u,%u,%u,%u",&level, &start, &stop, &filter, &window, &dummy);
+					if (numitems < 6 || numitems == EOF 
+						|| level < 1 || level > 4096 
+						|| start < 1 || start > 15 
+						|| stop < 1 || stop > 15 
+						|| window > 6) {
+							
+						cout << "Error: invalid number of arguments. Should be of the format " << endl;
+						cout << "       '--trigsetup=level,start,stop,filter,window,dummy' (use decimal values)" << endl;  
+						cout << "       level=1..4096, start/stop=1..15, filter=0..254, window=0..6"<< endl;
 						exit(EXIT_FAILURE);
 					}
+					
 					trigsetupcmd->setLevel(static_cast<uint32>(level));
-					trigsetupcmd->setMode(static_cast<uint32>(mode));
+					trigsetupcmd->setMode(static_cast<uint32>(start + (stop << 4)));
 					trigsetupcmd->setFilter(static_cast<uint32>(filter));
 					trigsetupcmd->setWindow(static_cast<uint32>(window));
 					trigsetupcmd->setDummy(static_cast<uint32>(dummy));
 				}
-				command->setCmdType(BOARDCMD);
+				command->setCmdType(RCUCMD);
 			}	break;
 			
 			case 'c': { 	// --trigcoef
@@ -2108,22 +2375,23 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 				TrigCoefficientCmd* trigcoefficientcmd = new TrigCoefficientCmd(itsServerPort);
 				command = trigcoefficientcmd;
 				if (optarg) {
-					int c0 = 0;
-					int c1 = 0;
-					int c2 = 0;
-					int c3 = 0;
-					int numitems = sscanf(optarg, "%x,%x,%x,%x",&c0, &c1, &c2, &c3);
+					uint32 c0 = 0;
+					uint32 c1 = 0;
+					uint32 c2 = 0;
+					uint32 c3 = 0;
+					int numitems = sscanf(optarg, "%u,%u,%u,%u",&c0, &c1, &c2, &c3);
 					if (numitems < 4 || numitems == EOF) {
-						logMessage(cerr,"Error: invalid number of arguments. Should be of the format "
-								"'--trigcoef=c0,c1,c2,c3'   (all hex values)");  
+						cout << "Error: invalid number of arguments. Should be of the format " << endl;
+						cout << "       '--trigcoef=c0,c1,c2,c3'   (use decimal values)" << endl;
+						cout << "       co,c1,c2,c3=16bit"<< endl; 
 						exit(EXIT_FAILURE);
 					}
-					trigcoefficientcmd->setC0(static_cast<int16>(c0));
-					trigcoefficientcmd->setC1(static_cast<int16>(c1));
-					trigcoefficientcmd->setC2(static_cast<int16>(c2));
-					trigcoefficientcmd->setC3(static_cast<int16>(c3));
+					trigcoefficientcmd->setC0(static_cast<uint16>(c0));
+					trigcoefficientcmd->setC1(static_cast<uint16>(c1));
+					trigcoefficientcmd->setC2(static_cast<uint16>(c2));
+					trigcoefficientcmd->setC3(static_cast<uint16>(c3));
 				}
-				command->setCmdType(BOARDCMD);
+				command->setCmdType(RCUCMD);
 			}	break;
 			
 			case 'I': { 	// --triginfo
@@ -2131,20 +2399,27 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 				TrigInfoCmd* triginfocmd = new TrigInfoCmd(itsServerPort);
 				command = triginfocmd;
 				if (optarg) {
-					int channel = 0;
-					int numitems = sscanf(optarg, "%d",&channel);
+					int rcu = 0;
+					int numitems = sscanf(optarg, "%d",&rcu);
 					if (numitems < 1 || numitems == EOF) {
-						logMessage(cerr,"Error: invalid number of arguments. Should be of the format "
-								"'--triginfo=rcu' ");  
+						cout << "Error: invalid number of arguments. Should be of the format " << endl;
+						cout << "       '--triginfo=rcu' " << endl; 
+						cout << "       rcu=0.." << (MAX_N_RCUS - 1) << endl;  
 						exit(EXIT_FAILURE);
 					}
 					select.clear();
-		  		select.push_back(channel);
+		  		select.push_back(rcu);
 					command->setSelected(true);
 				}
 				command->setCmdType(RCUCMD);
 			}	break;
 			
+			case 'L': { 	// --listen
+				if (command) delete command;
+				ListenCmd* listencmd = new ListenCmd(itsServerPort);
+				command = listencmd;
+				command->setCmdType(RCUCMD);
+			}	break;
 			
 			case 'R': { 	// --read
 				if (command) delete command;
@@ -2152,16 +2427,17 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 				command = readcmd;
 				
 				if (optarg) {
-					int channel = 0;
+					int rcu = 0;
 					uint32 secondstime = 0;
 					uint32 sampletime = 0;
 					uint32 prepages = 0;
 					uint32 postpages = 0;
 					int numitems = sscanf(optarg, "%d,%u,%u,%u,%u",
-						&channel, &secondstime, &sampletime, &prepages, &postpages);
-					if (numitems < 5 || numitems == EOF) {
-						logMessage(cerr,"Error: invalid number of arguments. Should be of the format "
-								"'--read=rcu,secondstime,sampletime,prepages,postpages' ");  
+						&rcu, &secondstime, &sampletime, &prepages, &postpages);
+					if (numitems < 5 || numitems == EOF || rcu < 0 || rcu >= MAX_N_RCUS) {
+						cout << "Error: invalid number of arguments. Should be of the format " << endl;
+						cout <<	"       '--read=rcu,secondstime,sampletime,prepages,postpages' " << endl;
+						cout << "       rcu=0.." << (MAX_N_RCUS - 1) << ", time = secondstime + (sampletime * sample-interval) "<< endl;  
 						exit(EXIT_FAILURE);
 					}
 					readcmd->setSecondsTime(secondstime);
@@ -2170,9 +2446,9 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					readcmd->setPostPages(postpages);
 					
 					select.clear();
-		  		select.push_back(channel);
+		  		select.push_back(rcu);
 					command->setSelected(true);
-				}
+				} 
 				command->setCmdType(RCUCMD);
 			}	break;
 			
@@ -2185,9 +2461,10 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					char rec_mode[64];
 					int numitems = sscanf(optarg, "%d,%s",
 						&board, rec_mode);
-					if (numitems < 2 || numitems == EOF) {
-						logMessage(cerr,"Error: invalid number of arguments. Should be of the format "
-								"'--udp=board,rec_mode' ");  
+					if (numitems < 2 || numitems == EOF ||(strcmp(rec_mode,"transient") != 0 && strcmp(rec_mode,"subbands") != 0)) {
+						cout << "Error: invalid number of arguments. Should be of the format " << endl;
+						cout << "       '--udp=board,rec_mode'" << endl;
+						cout << "       rec_mode=transient or subbands" << endl;  
 						exit(EXIT_FAILURE);
 					}
 					
@@ -2199,7 +2476,7 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					select.clear();
 		  		select.push_back(board);
 					command->setSelected(true);
-				}
+				} 
 				command->setCmdType(BOARDCMD);
 			}	break;									
 						
@@ -2247,12 +2524,14 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					int32 imagenr = 0;
 					int numitems = sscanf(optarg, "%d", &imagenr);
 					if (numitems == 0 || numitems == EOF || imagenr < 0 || imagenr > 31) {
-						logMessage(cerr,"Error: invalid image value. Should be of the format "
-								"'--config=value' where value is a int value in the range [0,10].");  //TODO value range
+						cout << "Error: invalid image value. Should be of the format " << endl;
+						cout <<	"       '--config=value'" << endl;
+						cout << "       value=0..31" << endl; 
 						exit(EXIT_FAILURE);
 					}
 					configcmd->setImage((uint32)imagenr);
-				}
+				} 
+				
 				command->setCmdType(BOARDCMD);
 			}	break;
 			
@@ -2269,8 +2548,9 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					int numitems = sscanf(optarg, "%d,%u,%u", &rcu,&startpage,&pages);
 					
 					if (numitems < 3 || numitems == EOF || rcu < 0 || rcu >= MAX_N_RCUS) {
-						logMessage(cerr,"Error: invalid readpage value's. Should be of the format "
-								"'--readpage=rcu,startpage,pages' where rcu= 0..191");  
+						cout << "Error: invalid readpage value's. Should be of the format " << endl;
+						cout << "       '--readpage=rcu,startpage,pages'" << endl;
+						cout << "       rcu=0.." << (MAX_N_RCUS - 1) << endl; 
 						exit(EXIT_FAILURE);
 					}
 					readddrcmd->setStartPage(startpage);
@@ -2278,11 +2558,7 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					select.clear();
 		  		select.push_back(rcu);
 		  		command->setSelected(true);
-				}	else {
-					logMessage(cerr,"Error: invalid readpage value's. Should be of the format "
-							"'--readpage=rcu,startpage,pages' where rcu= 0..191");  
-						exit(EXIT_FAILURE);
-				}
+				}	
 				command->setCmdType(BOARDCMD);
 			}	break;			
 						
@@ -2295,18 +2571,17 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					int page = 0;
 					int numitems = sscanf(optarg, "%d,%d", &board, &page);
 					
-					if (numitems < 2 || numitems == EOF 
-							|| page < 0 || page >= FL_N_PAGES 
-							|| board < 0 || board >= MAX_N_TBBBOARDS) {
-						logMessage(cerr,"Error: invalid page value. Should be of the format "
-								"'--eraseimage=board,page' where board= 0 .. 11, image= 0..31");  
+					if (numitems < 2 || numitems == EOF || page < 0 || page >= FL_N_PAGES	|| board < 0 || board >= MAX_N_TBBBOARDS) {
+						cout << "Error: invalid page value. Should be of the format " << endl;
+						cout <<	"       '--eraseimage=board,page'" << endl;
+						cout << "       board=0.." << (MAX_N_TBBBOARDS - 1) << ", image=0..31" << endl; 
 						exit(EXIT_FAILURE);
 					}
 					erasefcmd->setPage(page);
 					select.clear();
 					select.push_back(board);
 					command->setSelected(true);
-				}
+				} 
 				command->setCmdType(BOARDCMD);
 			}	break;
 			
@@ -2319,18 +2594,17 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					int page = 0;
 					int numitems = sscanf(optarg, "%d,%d", &board, &page);
 					
-					if (numitems < 2 || numitems == EOF 
-							|| page < 0 || page >= FL_N_PAGES 
-							|| board < 0 || board >= MAX_N_TBBBOARDS) {
-						logMessage(cerr,"Error: invalid page value. Should be of the format "
-								"'--readimage=board,page' where board= 0 .. 11, image= 0..31");  
+					if (numitems < 2 || numitems == EOF || page < 0 || page >= FL_N_PAGES	|| board < 0 || board >= MAX_N_TBBBOARDS) {
+						cout << "Error: invalid image value. Should be of the format " << endl;
+						cout << "       '--readimage=board,image'"<< endl;
+						cout << "       board=0.." << (MAX_N_TBBBOARDS - 1) << ", image=0..31" << endl;  
 						exit(EXIT_FAILURE);
 					}
 					readfcmd->setPage(page);
 					select.clear();
 					select.push_back(board);
 					command->setSelected(true);
-				}
+				} 
 				command->setCmdType(BOARDCMD);
 			}	break;
 			
@@ -2348,11 +2622,10 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					memset(filename_mp,0,64);
 					
 					int numitems = sscanf(optarg, "%d,%d,%lf,%63[^,],%63[^,]", &board, &page, &version, filename_tp, filename_mp);
-					if (numitems < 5 || numitems == EOF 
-							|| page < 0 || page >= FL_N_PAGES 
-							|| board < 0 || board >= MAX_N_TBBBOARDS) {
-						logMessage(cerr,"Error: invalid values. Should be of the format "
-								"'--writeimage=board,page,filename tp,filename mp' where board= 0 .. 11, image= 0..31");  
+					if (numitems < 5 || numitems == EOF || page < 0 || page >= FL_N_PAGES	|| board < 0 || board >= MAX_N_TBBBOARDS) {
+						cout << "Error: invalid values. Should be of the format " << endl;
+						cout << "       '--writeimage=board,page,file-tp,file-mp'"<< endl;
+						cout << "       board=0.." << (MAX_N_TBBBOARDS - 1) << ", image=0..31" << endl;  
 						exit(EXIT_FAILURE);
 					}
 					writefcmd->setPage(page);
@@ -2363,7 +2636,7 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					select.clear();
 					select.push_back(board);
 					command->setSelected(true);
-				}
+				} 
 				command->setCmdType(BOARDCMD);
 			}	break;
 			
@@ -2375,14 +2648,15 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					int board = 0;
 					int numitems = sscanf(optarg, "%d", &board);
 					if (numitems < 1 || numitems == EOF || board < 0 || board >= MAX_N_TBBBOARDS) {
-						logMessage(cerr,"Error: invalid values. Should be of the format "
-								"'--imageinfo=board' where board= 0 .. 11");  
+						cout << "Error: invalid values. Should be of the format " << endl;
+						cout <<	"       '--imageinfo=board'"<< endl;
+						cout << "       board=0.." << (MAX_N_TBBBOARDS - 1) << endl;   
 						exit(EXIT_FAILURE);
 					}
 					select.clear();
 					select.push_back(board);
 					command->setSelected(true);
-				}
+				} 
 				command->setCmdType(BOARDCMD);
 			} break;
 			
@@ -2399,9 +2673,10 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					
 					int numitems = sscanf(optarg, "%d,%x,%x,%x", &board,&mp,&startaddr, &size);
 					
-					if (numitems < 3 || numitems == EOF || board < 0 || board > 11 || mp > 3) {
-						logMessage(cerr,"Error: invalid read ddr value. Should be of the format "
-								"'--readw=board,mp,addr' where board= 0..11, mp= 0..3 and addr= 0x..");  
+					if (numitems < 3 || numitems == EOF || board < 0 || board >= MAX_N_TBBBOARDS || mp > 3) {
+						cout << "Error: invalid read ddr value. Should be of the format " << endl;
+						cout <<	"       '--readw=board,mp,addr'" << endl;
+						cout << "       board=0.." << (MAX_N_TBBBOARDS - 1) << ", mp=0..3, addr=0x.." << endl;  
 						exit(EXIT_FAILURE);
 					}
 					readwcmd->setMp(mp);
@@ -2410,11 +2685,7 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					select.clear();
 		  		select.push_back(board);
 		  		command->setSelected(true);
-				} else {
-					logMessage(cerr,"Error: invalid read ddr value. Should be of the format "
-								"'--readw=board,mp,addr' where board= 0..11, mp= 0..3 and addr= 0x..");  
-						exit(EXIT_FAILURE);
-				}
+				} 
 				command->setCmdType(BOARDCMD);
 			}	break;
 			
@@ -2430,10 +2701,10 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					uint32 wordhi = 0;
 					
 					int numitems = sscanf(optarg, "%d,%d,%x,%x,%x", &board,&mp,&addr,&wordlo,&wordhi);
-					if (numitems < 5 || numitems == EOF || board < 0 || board > 11 || mp > 3) {
-						logMessage(cerr,"Error: invalid write ddr value. Should be of the format "
-								"'--writew=board,mp,addr,wordlo,wordhi' where board= 0..11, mp= 0..3 and\n"
-								"addr= 0x.., wordlo= 0x.., wordhi= 0x..");  
+					if (numitems < 5 || numitems == EOF || board < 0 || board >= MAX_N_TBBBOARDS || mp > 3) {
+						cout << "Error: invalid write ddr value. Should be of the format " << endl;
+						cout <<	"       '--writew=board,mp,addr,wordlo,wordhi'"<< endl; 
+						cout << "       board=0.." << (MAX_N_TBBBOARDS - 1) << ", mp=0..3, addr=0x.., wordlo=0x.., wordhi=0x.." << endl;  
 						exit(EXIT_FAILURE);
 					}
 					writewcmd->setMp(mp);
@@ -2443,11 +2714,7 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					select.clear();
 		  		select.push_back(board);
 		  		command->setSelected(true);
-				}	else {
-					logMessage(cerr,"Error: invalid write ddr value. Should be of the format "
-								"'--writew=board,mp,addr,wordlo,wordhi' where board= 0..11, mp= 0..3 and addr= 0..x.");  
-						exit(EXIT_FAILURE);
-				}
+				}	
 				command->setCmdType(BOARDCMD);
 			}	break;
 			
@@ -2459,27 +2726,51 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 					int32 board = 0;
 										
 					int numitems = sscanf(optarg, "%d", &board);
-					if (numitems < 1 || numitems == EOF || board < 0 || board > 11) {
-						logMessage(cerr,"Error: invalid write ddr value. Should be of the format "
-								"'--testddr=board' where board= 0..11");  
+					if (numitems < 1 || numitems == EOF || board < 0 || board >= MAX_N_TBBBOARDS) {
+						cout << "Error: invalid write ddr value. Should be of the format " << endl;
+						cout << "       '--testddr=board' "<< endl;  
+						cout << "       board=0.." << (MAX_N_TBBBOARDS - 1) << endl;
 						exit(EXIT_FAILURE);
 					}
 					select.clear();
 		  		select.push_back(board);
 		  		command->setSelected(true);
-				}	else {
-					logMessage(cerr,"Error: invalid write ddr value. Should be of the format "
-								"'--testddr=board' where board= 0..11");
-						exit(EXIT_FAILURE);
-				}
+				}	
 				command->setCmdType(BOARDCMD);
 			}	break;
-			
-			/*
+						
 			case '6': { 	// --readr
 				if (command) delete command;
 				ReadrCmd* readrcmd = new ReadrCmd(itsServerPort);
 				command = readrcmd;
+				
+				if (optarg) {
+					int32 board = 0;
+					uint32 mp = 0;
+					uint32 pid = 0;
+					uint32 regid = 0;
+										
+					int numitems = sscanf(optarg, "%d,%u,%u,%u", &board, &mp, &pid, &regid);
+					
+					if (numitems < 4 || numitems == EOF || board < 0 || board >= MAX_N_TBBBOARDS || mp > 3 || pid > 7 || regid > 7) {
+						cout << "Error: invalid read register value. Should be of the format" << endl;
+						cout << "       '--readreg=board,mp,pid,regid'" << endl;
+						cout << "       board=0.." << (MAX_N_TBBBOARDS - 1) << ", mp=0..3, pid=0..7, regid=0..7" << endl;  
+						exit(EXIT_FAILURE);
+					}
+					if ((REG_TABLE_3[pid][regid] == REG_WRITE_ONLY) || (REG_TABLE_3[pid][regid] == REG_NOT_USED)) {
+						cerr << "reading not posible on selected register" << endl;
+						exit(EXIT_FAILURE);
+					}
+					readrcmd->setMp(mp);
+					readrcmd->setPid(pid);
+					readrcmd->setRegId(regid);
+					
+					select.clear();
+					select.push_back(board);
+					command->setSelected(true);
+				}	
+				
 				command->setCmdType(BOARDCMD);
 			}	break;
 			
@@ -2487,24 +2778,75 @@ Command* TBBCtl::parse_options(int argc, char** argv)
 				if (command) delete command;
 				WriterCmd* writercmd = new WriterCmd(itsServerPort);
 				command = writercmd;
+				
+				if (optarg) {
+					int32 board = 0;
+					uint32 mp = 0;
+					uint32 pid = 0;
+					uint32 regid = 0;
+					char datastr[256];
+					//uint32 data1 = 0;
+					//uint32 data2 = 0;
+					//uint32 data3 = 0;
+					
+					int numitems = sscanf(optarg, "%d,%u,%u,%u,%s", &board, &mp, &pid, &regid, datastr);
+					if (numitems < 5 || numitems == EOF || board < 0 || board >= MAX_N_TBBBOARDS || mp > 3 || pid > 7 || regid > 7) {
+						cout << "Error: invalid write register value. Should be of the format " << endl;
+						cout <<	"       '--writereg=board,mp,pid,regid,data1,data2 etc.'" << endl;
+						cout << "       board=0.." << (MAX_N_TBBBOARDS - 1) << ", mp=0..3, pid=0..7, regid=0..7" << endl;   
+						exit(EXIT_FAILURE);
+					}
+					if ((REG_TABLE_3[pid][regid] == REG_READ_ONLY) || (REG_TABLE_3[pid][regid] == REG_NOT_USED)) {
+						cerr << "writing not posible on selected register" << endl;
+						exit(EXIT_FAILURE);
+					}
+					writercmd->setMp(mp);
+					writercmd->setPid(pid);
+					writercmd->setRegId(regid);
+					
+					char* dstr;
+					uint32 val = 0;
+					int wordcnt = 0;
+
+  				dstr = strtok (datastr," ,");
+  				while (dstr != NULL)
+  				{
+ 						val = strtol(dstr,NULL,16);
+   					//cout << formatString("%08x ",val);
+    				writercmd->setData(wordcnt,val);
+   					wordcnt++;
+    				dstr = strtok (NULL, " ,");
+  				}
+					cout << endl;
+					select.clear();
+					select.push_back(board);
+					command->setSelected(true);
+				}	
+				
 				command->setCmdType(BOARDCMD);
 			}	break;
-			*/			
-			case 'h': {
-				help();
-			}
+						
+			case 'h':
+			case '?': {
+				commandHelp(1);
+				exit(0);
+			} break;
+			
+			case 'X':	{
+				commandHelp(3);
+				exit(0);
+			} break;
 			
-			case '?':
 			default:
 			{
-				help();
+				commandHelp(1);
 				exit(EXIT_FAILURE);
 			} break;
 		}
 	}
 
 	if (command) {
-		if (!command->getSelected()) {	// --select not used, select all
+		if (!command->isSelectionDone()) {	// --select not used, select all
 			select.clear();
 			for (int i = 0; i < command->getMaxSelections(); i++) {
 				select.push_back(i);	
@@ -2532,7 +2874,7 @@ std::list<int> TBBCtl::strtolist(const char* str, int max)
     long val = strtol(start, &end, 10); // read decimal numbers
     start = (end ? (*end ? end + 1 : 0) : 0); // determine next start
     if (val >= max || val < 0) {
-      logMessage(cerr,formatString("Error: value %ld out of range",val));
+      cout << formatString("Error: value %ld out of range",val) << endl;
 			resultset.clear();
       return(resultset);
     }
@@ -2547,7 +2889,7 @@ std::list<int> TBBCtl::strtolist(const char* str, int max)
               val = max - 1;
             }
             if (val < prevval) {
-              logMessage(cerr,"Error: invalid range specification");
+              cout << "Error: invalid range specification" << endl;
 							resultset.clear();
 							return(resultset);
 						}
@@ -2564,7 +2906,7 @@ std::list<int> TBBCtl::strtolist(const char* str, int max)
         } break;
 
         default: {
-          logMessage(cerr,formatString("Error: invalid character %c",*end));
+          cout << formatString("Error: invalid character %c",*end) << endl;
 					resultset.clear();
 					return(resultset);
 				} break;
@@ -2576,21 +2918,14 @@ std::list<int> TBBCtl::strtolist(const char* str, int max)
   return(resultset);
 }
 
-//-----------------------------------------------------------------------------
-void TBBCtl::logMessage(ostream& stream, const string& message)
-{
-  if (itsCommand != 0) {
-    itsCommand->logMessage(stream,message);
-  } else {
-    stream << message << endl;
-  }
-}
-
 //-----------------------------------------------------------------------------
 void TBBCtl::mainloop()
 {
   start(); // make initial transition
   GCFTask::run();
+	
+	TBBUnsubscribeEvent unsubscribe;
+	itsServerPort.send(unsubscribe);
 }
 
 //-----------------------------------------------------------------------------
@@ -2606,12 +2941,13 @@ int main(int argc, char** argv)
     tbbctl.mainloop();
   }
   catch (Exception e) {
-    cerr << "Exception: " << e.text() << endl;
-    cout << endl << "== abnormal termination of tbbctl ============================================" << endl;
+    cout << "Exception: " << e.text() << endl;
+		cout << endl;
+		cout << "== abnormal termination of tbbctl ============================================" << endl;
     exit(EXIT_FAILURE);
   }
-	cout << endl << "== normal termination of tbbctl ==============================================" << endl;
-  LOG_DEBUG("Normal termination of program");
+	cout << endl;
+	cout << "== normal termination of tbbctl ==============================================" << endl;
 
   return(0);
 }
diff --git a/MAC/APL/PIC/TBBDriver/src/tbbctl.h b/MAC/APL/PIC/TBBDriver/src/tbbctl.h
index 442a873e80793ff00c15df6d6cd2256b9e27d20e..05e6c82f198c2726946c5a8244e4f66653ec1670 100644
--- a/MAC/APL/PIC/TBBDriver/src/tbbctl.h
+++ b/MAC/APL/PIC/TBBDriver/src/tbbctl.h
@@ -56,7 +56,30 @@ static const int FL_BLOCK_SIZE 			= FL_SIZE / FL_N_BLOCKS; // 1.024 bytes
 static const int FL_SECTORS_IN_PAGE	= FL_PAGE_SIZE / FL_SECTOR_SIZE; // 16 sectors per page
 static const int FL_BLOCKS_IN_PAGE	= FL_PAGE_SIZE / FL_BLOCK_SIZE; // 2048 blocks per page
 
-  	
+// register read/write table
+// 0 = not used, 1 = read only, 2 = write only, 3 = read/write
+static const int REG_NOT_USED = 0;
+static const int REG_READ_ONLY = 1;
+static const int REG_WRITE_ONLY = 2;
+static const int REG_READ_WRITE = 3;
+static const int REG_TABLE_3[8][8] = {
+	{2,2,2,2,2,2,2,2},
+	{2,2,2,2,2,2,0,0},
+	{2,2,2,2,1,1,1,0},
+	{2,2,2,2,1,1,1,0},
+	{2,2,2,2,1,1,1,0},
+	{2,2,2,2,1,1,1,0},
+	{2,2,0,3,1,0,0,0},	// 6-2, size 2048, to big for 100Mb/s
+	{1,1,1,3,3,3,3,1}};
+static const int REG_SIZE[8][8] = {
+	{1,1,1,1,1,1,1,1},
+	{1,1,1,1,1,1,0,0},
+	{1,1,1,1,2,1,2,0},
+	{1,1,1,1,2,1,2,0},
+	{1,1,1,1,2,1,2,0},
+	{1,1,1,1,2,1,2,0},
+	{1,1,0,2,1,0,0,0},	// 6-2, size 2048, to big for 100Mb/s
+	{1,1,1,8,4,16,4,16}};  	
 //-----------------------------------------------------------------------------
 // class Command :base class for control commands towards the TBBDriver.
 //
@@ -164,6 +187,18 @@ public:
 		return(itsCmdDone);
 	}
 	
+	//--------------------------------------------------------
+	void setCmdSendNext(bool next)
+	{
+		itsCmdSendNext = next;
+	}
+	
+	//--------------------------------------------------------
+	bool isCmdSendNext() const
+	{
+		return(itsCmdSendNext);
+	}
+	
 	//--selection is done-------------------------------------	
 	void setSelected(bool select)
 	{
@@ -171,7 +206,7 @@ public:
 	}
 	
 	//--check if selection is done----------------------------
-	bool getSelected(void) const
+	bool isSelectionDone(void) const
 	{
 		return itsSelected;	
 	}
@@ -236,6 +271,7 @@ protected:
   	itsPort(port),
   	itsSelected(false),
   	itsCmdDone(false),
+  	itsCmdSendNext(true),
 		itsCmdType(0)
 	{
 	}
@@ -246,6 +282,7 @@ protected:
 	GCFPortInterface& 			itsPort;
 	bool		itsSelected;
 	bool		itsCmdDone;
+	bool		itsCmdSendNext;
 	int			itsCmdType;
 	std::list<int>	itsSelection;
 		
@@ -364,15 +401,15 @@ class TrigCoefficientCmd : public Command
 		virtual ~TrigCoefficientCmd() { }
 		virtual void send();
 		virtual GCFEvent::TResult ack(GCFEvent& e);
-		void setC0(int16 c0) { itsC0 = c0; }
-		void setC1(int16 c1) { itsC1 = c1; }
-		void setC2(int16 c2) { itsC2 = c2; }
-		void setC3(int16 c3) { itsC3 = c3; }
+		void setC0(uint16 c0) { itsC0 = c0; }
+		void setC1(uint16 c1) { itsC1 = c1; }
+		void setC2(uint16 c2) { itsC2 = c2; }
+		void setC3(uint16 c3) { itsC3 = c3; }
 	private:
-		int16 itsC0;
-		int16 itsC1;
-		int16 itsC2;
-		int16 itsC3;
+		uint16 itsC0;
+		uint16 itsC1;
+		uint16 itsC2;
+		uint16 itsC3;
 };
 
 //-----------------------------------------------------------------------------
@@ -386,6 +423,18 @@ class TrigInfoCmd : public Command
 	private:
 };
 
+//-----------------------------------------------------------------------------
+class ListenCmd : public Command
+{
+	public:
+		ListenCmd(GCFPortInterface& port);
+		virtual ~ListenCmd() { }
+		virtual void send();
+		virtual GCFEvent::TResult ack(GCFEvent& e);
+	private:
+		int32 itsCmdStage;
+};
+
 //-----------------------------------------------------------------------------
 class ReadCmd : public Command
 {
@@ -595,6 +644,8 @@ class TestDdrCmd : public Command
 		uint32	itsTestPatern;
 		uint32	itsWordLo;
 		uint32	itsWordHi;
+		int	itsAddrLineErrors;
+		int	itsDataLineErrors;
 };
 
 //-----------------------------------------------------------------------------
@@ -605,7 +656,14 @@ class ReadrCmd : public Command
 		virtual ~ReadrCmd() { }
 		virtual void send();
 		virtual GCFEvent::TResult ack(GCFEvent& e);
+		void setMp(uint32 mp) {	itsMp = mp;	}
+		void setPid(uint32 pid) {	itsPid = pid;	}
+		void setRegId(uint32 regid) {	itsRegId = regid;	}
+		
 	private:
+		int32 itsMp;
+		int32 itsPid;
+		int32 itsRegId;
 };
 
 //-----------------------------------------------------------------------------
@@ -616,7 +674,15 @@ class WriterCmd : public Command
 		virtual ~WriterCmd() { }
 		virtual void send();
 		virtual GCFEvent::TResult ack(GCFEvent& e);
+		void setMp(uint32 mp) {	itsMp = mp;	}
+		void setPid(uint32 pid) {	itsPid = pid;	}
+		void setRegId(uint32 regid) {	itsRegId = regid;	}
+		void setData(int data_nr, uint32 data) { itsData[data_nr] = data; }
 	private:
+		int32 itsMp;
+		int32 itsPid;
+		int32 itsRegId;
+		uint32 itsData[16];	// total of 4 x 16 = 64 bytes 
 };
 
 //-----------------------------------------------------------------------------
@@ -716,7 +782,7 @@ private:
 	std::list<int> strtolist(const char* str, int max);
   void logMessage(ostream& stream, const string& message);
 	
-	void help();
+	void commandHelp(int level);
 private:
   // ports
   GCFPort				itsServerPort;