From ad5dd9e9d2c27593c71d0a16c868a2577ae9a479 Mon Sep 17 00:00:00 2001
From: Pieter Donker <donker@astron.nl>
Date: Wed, 6 Oct 2010 11:54:50 +0000
Subject: [PATCH] Bug 335: futher development TBBDriver

---
 MAC/APL/PIC/RSP_Driver/src/Cache.h            |   2 +
 MAC/APL/PIC/TBB_Driver/src/BoardCmdHandler.cc |  27 +--
 MAC/APL/PIC/TBB_Driver/src/BoardCmdHandler.h  |   1 -
 MAC/APL/PIC/TBB_Driver/src/Command.cc         | 158 +++++++-----------
 MAC/APL/PIC/TBB_Driver/src/DriverSettings.cc  |   2 +
 MAC/APL/PIC/TBB_Driver/src/DriverSettings.h   |  16 +-
 MAC/APL/PIC/TBB_Driver/src/ReadxCmd.cc        |  19 ++-
 MAC/APL/PIC/TBB_Driver/src/TBBDriver.cc       |  90 ++++++----
 MAC/APL/PIC/TBB_Driver/src/tbbctl.cc          |  31 ++--
 MAC/APL/PIC/TBB_Driver/src/tbbctl.h           |   2 +-
 10 files changed, 170 insertions(+), 178 deletions(-)

diff --git a/MAC/APL/PIC/RSP_Driver/src/Cache.h b/MAC/APL/PIC/RSP_Driver/src/Cache.h
index 38fb0272b2a..d400bc121ee 100644
--- a/MAC/APL/PIC/RSP_Driver/src/Cache.h
+++ b/MAC/APL/PIC/RSP_Driver/src/Cache.h
@@ -26,6 +26,7 @@
 #define CACHE_H_
 
 #include <Common/LofarTypes.h>
+#include <Common/lofar_bitset.h>
 #include <blitz/array.h>
 #include <APL/RSP_Protocol/AllRegisterState.h>
 #include <APL/RSP_Protocol/RSP_Protocol.ph>
@@ -144,6 +145,7 @@ private:
 	bool							itsSplitterActive;
 	bool							itsCepEnabled;
 	RSP_Protocol::Latency			itsLatencys;
+	bitset<MAX_N_RSPBOARDS*8>       itsSwapXY;
 	
 	Cache* m_cache;		// pointer to container
 };
diff --git a/MAC/APL/PIC/TBB_Driver/src/BoardCmdHandler.cc b/MAC/APL/PIC/TBB_Driver/src/BoardCmdHandler.cc
index bd158970556..326b1769d96 100644
--- a/MAC/APL/PIC/TBB_Driver/src/BoardCmdHandler.cc
+++ b/MAC/APL/PIC/TBB_Driver/src/BoardCmdHandler.cc
@@ -40,7 +40,6 @@ BoardCmdHandler::BoardCmdHandler(GCFTimerPort* port):
 {
 	itsSleepTimer = port;
 	TS = TbbSettings::instance();
-	itsDone = true;
 	itsRetries = 0;
 	itsClientPort	= 0;
 	itsCmd = 0;
@@ -49,6 +48,7 @@ BoardCmdHandler::BoardCmdHandler(GCFTimerPort* port):
 BoardCmdHandler::~BoardCmdHandler()
 {
 	delete itsSleepTimer;
+	if (itsCmd) delete itsCmd;
 }
 
 
@@ -74,12 +74,8 @@ GCFEvent::TResult BoardCmdHandler::idle_state(GCFEvent& event, GCFPortInterface&
 			if (itsCmd && itsCmd->isValid(event)) { // isValid returns true if event is a valid cmd
 				LOG_DEBUG_STR("==== NEW CMD ==================================================");
 				itsClientPort = &port;
-				itsDone = false;
 				itsCmd->reset();
 				itsCmd->saveTbbEvent(event);
-				if (itsCmd->isDone()) {
-					itsDone = true;
-				}
 				TRAN(BoardCmdHandler::send_state);
 			} else {
 				status = GCFEvent::NOT_HANDLED;
@@ -97,11 +93,11 @@ GCFEvent::TResult BoardCmdHandler::send_state(GCFEvent& event, GCFPortInterface&
 		} break;
 
 		case F_ENTRY: {
-			if (itsDone) {
+			if (itsCmd->isDone()) {
 				LOG_DEBUG_STR("entering send state, cmd is done");
 				itsCmd->sendTbbAckEvent(itsClientPort);
 				// set timer for TBBDriver, to return to idle state
-				itsSleepTimer->setTimer(0.01);
+				itsSleepTimer->setTimer(0.0);
 				TRAN(BoardCmdHandler::idle_state);
 			} else {
 				LOG_DEBUG_STR("entering send state, next cmd");
@@ -135,18 +131,12 @@ GCFEvent::TResult BoardCmdHandler::waitack_state(GCFEvent& event, GCFPortInterfa
 		case F_ENTRY: {
 			// if cmd returns no ack or board/channel is not selected or not responding return to send_state		
 			if (!itsCmd->waitAck()) {
-			    if (itsCmd->isDone()) {
-					itsDone = true;
-				}
-				TRAN(BoardCmdHandler::send_state);
+			    TRAN(BoardCmdHandler::send_state);
 			}
 		} break;
 
 		case F_TIMER: {
 			if (&port == itsSleepTimer) {
-				if (itsCmd->isDone()) {
-					itsDone = true;
-				}
 				TRAN(BoardCmdHandler::send_state);	
 				break;
 			}
@@ -166,9 +156,6 @@ GCFEvent::TResult BoardCmdHandler::waitack_state(GCFEvent& event, GCFPortInterfa
 					itsSleepTimer->setTimer(itsCmd->getSleepTime());
 					itsCmd->setSleepTime(0.0);
 				} else {
-					if (itsCmd->isDone()) {
-						itsDone = true;
-					}
 					TRAN(BoardCmdHandler::send_state);
 				}
 			}	
@@ -187,9 +174,6 @@ GCFEvent::TResult BoardCmdHandler::waitack_state(GCFEvent& event, GCFPortInterfa
 					itsSleepTimer->setTimer(itsCmd->getSleepTime());
 					itsCmd->setSleepTime(0.0);
 				} else {
-					if (itsCmd->isDone()) {
-						itsDone = true;
-					}
 					TRAN(BoardCmdHandler::send_state);
 				}
 			} else {
@@ -207,5 +191,6 @@ void BoardCmdHandler::setTpCmd(Command *cmd)
 
 bool BoardCmdHandler::tpCmdDone()
 {
-	return (itsDone);
+	if (itsCmd) { return(itsCmd->isDone()); }
+	return (true);
 }
diff --git a/MAC/APL/PIC/TBB_Driver/src/BoardCmdHandler.h b/MAC/APL/PIC/TBB_Driver/src/BoardCmdHandler.h
index 24b4e0b6f31..a99e7f7c698 100644
--- a/MAC/APL/PIC/TBB_Driver/src/BoardCmdHandler.h
+++ b/MAC/APL/PIC/TBB_Driver/src/BoardCmdHandler.h
@@ -69,7 +69,6 @@ public:
 	bool tpCmdDone();
 private:
 	TbbSettings* TS;
-	bool itsDone;
 	bool itsFlashMode;
 	// variables
 	int32 itsRetries;
diff --git a/MAC/APL/PIC/TBB_Driver/src/Command.cc b/MAC/APL/PIC/TBB_Driver/src/Command.cc
index 668a1bcebce..f172b1e5647 100644
--- a/MAC/APL/PIC/TBB_Driver/src/Command.cc
+++ b/MAC/APL/PIC/TBB_Driver/src/Command.cc
@@ -32,7 +32,7 @@ using namespace TBB;
 // ----------------------------------------------------------------------------
 Command::Command() :
 	itsRetry(true), itsWaitAck(false), itsDone(false), itsAllPorts(false), itsBoard(-1),
-	itsChannel(-1), itsSleepTime(0)
+	itsChannel(-1), itsSleepTime(0.0)
 {
 	TS = TbbSettings::instance();
 	itsBoards.reset();
@@ -48,48 +48,38 @@ Command::~Command() { }
 // ----------------------------------------------------------------------------
 void Command::setBoard(int32 board)
 {
-	if (board >= TS->maxBoards()) {
-		itsStatus[board] = TBB_NO_BOARD;
-	} else {
-
-		if (TS->isBoardReady(board) == false) {
-			itsStatus[board] = TBB_NOT_READY;
+	if (board < TS->maxBoards()) {
+		if (TS->isBoardReady(board)) {
+		    itsBoards.set(board);
+		    return;
 		}
-
-		if (TS->isBoardActive(board) == false) {
+		else if (TS->isBoardActive(board) == false) {
 			itsStatus[board] = TBB_NOT_ACTIVE;
 		}
-
-		if (itsStatus[board] == TBB_SUCCESS) {
-			itsBoards.set(board);
+		else if (TS->isBoardReady(board) == false) {
+			itsStatus[board] = TBB_NOT_READY;
 		}
 	}
+	else {
+		itsStatus[board] = TBB_NO_BOARD;
+	} 
 }
 
 // ----------------------------------------------------------------------------
 void Command::setBoards(uint32 board_mask)
 {
-	for (int i = 0; i < TS->maxBoards(); i++) {
-
-		if (i >= TS->maxBoards()) {
-			itsStatus[i] = TBB_NO_BOARD;
-			continue;
-		}
-
-		if (board_mask & (1 << i)) {
-
-			if (TS->isBoardReady(i) == false) {
-				itsStatus[i] = TBB_NOT_READY;
-			}
-
-			if (TS->isBoardActive(i) == false) {
-				itsStatus[i] = TBB_NOT_ACTIVE;
-			}
-
-			if (itsStatus[i] == TBB_SUCCESS) {
-				itsBoards.set(i);
-			}
-		}
+	for (int board = 0; board < TS->maxBoards(); board++) {
+        if (board_mask & (1 << board)) {
+    		if (TS->isBoardReady(board)) {
+    		    itsBoards.set(board);
+    		}
+    		else if (TS->isBoardActive(board) == false) {
+    			itsStatus[board] = TBB_NOT_ACTIVE;
+    		}
+    		else if (TS->isBoardReady(board) == false) {
+    			itsStatus[board] = TBB_NOT_READY;
+    		}
+    	}
 	}
 }
 
@@ -100,23 +90,21 @@ void Command::setChannel(int32 rcu)
 	int32 board   = TS->convertRcuToBoard(rcu);
 	int32 channel = TS->convertRcuToChan(rcu);
 
-	if (board >= TS->maxBoards()) {
-		itsStatus[board] = TBB_NO_BOARD;
-	} else {
-
-		if (TS->isBoardReady(board) == false) {
-			itsStatus[board] = TBB_NOT_READY;
-		}
-
-		if (TS->isBoardActive(board) == false) {
+	if (board < TS->maxBoards()) {
+	    if (TS->isBoardReady(board)) {
+	        itsBoards.set(board);
+			itsChannels.set(channel);
+	    }
+	    else if (TS->isBoardActive(board) == false) {
 			itsStatus[board] = TBB_NOT_ACTIVE;
 		}
-
-		if (itsStatus[board] == TBB_SUCCESS) {
-			itsBoards.set(board);
-			itsChannels.set(channel);
+		else if (TS->isBoardReady(board) == false) {
+			itsStatus[board] = TBB_NOT_READY;
 		}
 	}
+	else {
+		itsStatus[board] = TBB_NO_BOARD;
+	} 
 }
 
 // ----------------------------------------------------------------------------
@@ -127,28 +115,20 @@ void Command::setChannels(bitset<MAX_N_RCUS> rcus)
 	int32 channel;
 
 	for (int rcu = 0; rcu < TS->maxChannels(); rcu++) {
-		board = TS->convertRcuToBoard(rcu);
-		if (board >= TS->maxBoards()) {
-			itsStatus[board] = TBB_NO_BOARD;
-			continue;
-		}
-
-		if (rcus.test(rcu)) {
-			channel = TS->convertRcuToChan(rcu);
-
-			if (TS->isBoardReady(board) == false) {
-				itsStatus[board] = TBB_NOT_READY;
-			}
-
-			if (TS->isBoardActive(board) == false) {
-				itsStatus[board] = TBB_NOT_ACTIVE;
-			}
-
-			if (itsStatus[board] == TBB_SUCCESS) {
-				itsBoards.set(board);
-				itsChannels.set(channel);
-			}
-		}
+	    if (rcus.test(rcu)) {
+    	    board = TS->convertRcuToBoard(rcu);
+    	    channel = TS->convertRcuToChan(rcu);
+    	    if (TS->isBoardReady(board)) {
+    	        itsBoards.set(board);
+    			itsChannels.set(channel);
+    	    }
+    	    else if (TS->isBoardActive(board) == false) {
+    			itsStatus[board] = TBB_NOT_ACTIVE;
+    		}
+    		else if (TS->isBoardReady(board) == false) {
+    			itsStatus[board] = TBB_NOT_READY;
+    		}
+    	}
 	}
 }
 
@@ -210,46 +190,36 @@ void Command::setDone(bool done)
 // ----------------------------------------------------------------------------
 void Command::nextBoardNr()
 {
-	bool validNr = false;
-
-	do {
-		itsBoard++;
+	while (1) {
+	    itsBoard++;
 		if (itsBoard == TS->maxBoards()) { break; }
 		itsChannel = itsBoard * TS->nrChannelsOnBoard();
 		if (itsBoards.test(itsBoard) && (itsStatus[itsBoard] == TBB_SUCCESS)) {
-			validNr = true;
+			LOG_DEBUG_STR(formatString("nextBoardNr() = %d",itsBoard));
+			return;
 		}
-	} while (validNr == false);
-
-	// if all nr done send clear all variables
-	if (validNr == false) {
-		itsDone = true;
-		itsBoard = -1;
-		itsChannel = -1;
 	}
-	LOG_DEBUG_STR(formatString("nextBoardNr() = %d",itsBoard));
+	itsDone = true;
+	itsBoard = -1;
+	itsChannel = -1;
+	LOG_DEBUG_STR("all boards done");
 }
 
 // ----------------------------------------------------------------------------
 void Command::nextChannelNr()
 {
-	bool validNr = false;
-
-	do {
-		itsChannel++;
+	while (1) {
+	    itsChannel++;
 		if (itsChannel == TS->maxChannels()) { break; }
 		itsBoard = TS->getChBoardNr(itsChannel);
 		if (itsChannels.test(itsChannel)  && (itsStatus[itsBoard] == TBB_SUCCESS)) {
-			validNr = true;
+			LOG_DEBUG_STR(formatString("nextChannelNr() = %d",itsChannel));
+			return;
 		}
-	} while (validNr == false);
-
-	// if all nr done send clear all variables
-	if (validNr == false) {
-		itsDone = true;
-		itsBoard = -1;
-		itsChannel = -1;
 	}
-	LOG_DEBUG_STR(formatString("nextChannelNr() = %d",itsChannel));
+	itsDone = true;
+	itsBoard = -1;
+	itsChannel = -1;
+	LOG_DEBUG_STR("all channels done");
 }
 
diff --git a/MAC/APL/PIC/TBB_Driver/src/DriverSettings.cc b/MAC/APL/PIC/TBB_Driver/src/DriverSettings.cc
index b06c7d9410b..2e11f6a15b5 100644
--- a/MAC/APL/PIC/TBB_Driver/src/DriverSettings.cc
+++ b/MAC/APL/PIC/TBB_Driver/src/DriverSettings.cc
@@ -229,6 +229,7 @@ void TbbSettings::setMaxBoards (int32 maxboards)
 	itsBoardInfo = new BoardInfo[itsMaxBoards];
 	
 	for (int nr = 0;nr < itsMaxBoards; nr++) {
+	    itsBoardInfo[nr].used = false;
 		itsBoardInfo[nr].boardState = noBoard;
 		itsBoardInfo[nr].setupWaitTime = 0;
 		itsBoardInfo[nr].setupRetries = 0;
@@ -249,6 +250,7 @@ void TbbSettings::setBoardState(int32 boardnr, BoardStateT boardstate)
 	itsBoardInfo[boardnr].boardState = boardstate; 
 	if ((boardstate > noBoard) && (boardstate < boardReady)) {
 		itsBoardSetup = true;
+		itsBoardInfo[boardnr].used = false;
 	}
 }
 
diff --git a/MAC/APL/PIC/TBB_Driver/src/DriverSettings.h b/MAC/APL/PIC/TBB_Driver/src/DriverSettings.h
index d55f57c1120..04c0d2fa9db 100644
--- a/MAC/APL/PIC/TBB_Driver/src/DriverSettings.h
+++ b/MAC/APL/PIC/TBB_Driver/src/DriverSettings.h
@@ -35,7 +35,7 @@ namespace LOFAR {
 	using GCF::TM::GCFPortInterface;
 	namespace TBB {
 
-static const int DRIVER_VERSION = 230;
+static const int DRIVER_VERSION = 231;
 
 enum BoardStateT {noBoard,
 				  setImage1, image1Set,
@@ -75,6 +75,7 @@ struct ChannelInfo
 struct BoardInfo
 {
 	GCFPortInterface* port;
+	bool   used;
 	BoardStateT boardState;
 	time_t setupWaitTime;
 	int32  setupRetries;
@@ -201,6 +202,8 @@ public:
 	int32 convertChanToRcu(int32 channelnr);
 	bool isBoardActive(int32 boardnr);
 	bool isBoardReady(int32 boardnr);
+	bool isBoardUsed(int32 boardnr);
+	void resetBoardUsed();
 	void logChannelInfo(int32 channel);
 		
 	uint32 getMemorySize(int32 boardnr);
@@ -270,7 +273,10 @@ inline	int32 TbbSettings::flashBlockSize() { return (itsFlashBlockSize); }
 inline	uint32 TbbSettings::activeBoardsMask()	{ return (itsActiveBoardsMask);   }
 inline	int32 TbbSettings::maxRetries()	{ return (itsMaxRetries);   }
 inline	double TbbSettings::timeout()	{ return (itsTimeOut);   }
-inline	GCFPortInterface& TbbSettings::boardPort(int32 boardnr)	{ return (*itsBoardInfo[boardnr].port); }
+inline	GCFPortInterface& TbbSettings::boardPort(int32 boardnr)	{ 
+            itsBoardInfo[boardnr].used = true;
+            return (*itsBoardInfo[boardnr].port);
+        }
 
 inline	BoardStateT TbbSettings::getBoardState(int32 boardnr) { return (itsBoardInfo[boardnr].boardState); }
 inline  bool TbbSettings::boardSetupNeeded() { return (itsBoardSetup); }
@@ -366,6 +372,12 @@ inline	void TbbSettings::setImageNr(int32 boardnr,uint32 image) { itsBoardInfo[b
 inline	bool TbbSettings::getFreeToReset(int32 boardnr) { return (itsBoardInfo[boardnr].freeToReset); }
 inline	void TbbSettings::setFreeToReset(int32 boardnr, bool reset) { itsBoardInfo[boardnr].freeToReset = reset; }
 inline	bool TbbSettings::isBoardReady(int32 boardnr) { return(itsBoardInfo[boardnr].boardState == boardReady); }
+inline  bool TbbSettings::isBoardUsed(int32 boardnr) { return(itsBoardInfo[boardnr].used); }
+inline  void TbbSettings::resetBoardUsed() {
+            for (int boardnr = 0; boardnr < itsMaxBoards; boardnr++) {
+                itsBoardInfo[boardnr].used = false;
+            }
+        }
 	 
 	} // namespace TBB
 } // namespace LOFAR
diff --git a/MAC/APL/PIC/TBB_Driver/src/ReadxCmd.cc b/MAC/APL/PIC/TBB_Driver/src/ReadxCmd.cc
index 7bd121bce14..83e532101e7 100644
--- a/MAC/APL/PIC/TBB_Driver/src/ReadxCmd.cc
+++ b/MAC/APL/PIC/TBB_Driver/src/ReadxCmd.cc
@@ -86,11 +86,12 @@ void ReadxCmd::sendTpEvent()
 	tp_event.pagelength = itsPageLength;
 	tp_event.pageaddr   = itsPageAddr;
 	
+	
 	LOG_DEBUG_STR(formatString("Readx[%x][%x][%x][%x][%x][%x]", 
 										tp_event.opcode,tp_event.mp,tp_event.pid,
 										tp_event.regid,tp_event.pagelength,
 										tp_event.pageaddr));
-
+    
 	TS->boardPort(getBoardNr()).send(tp_event);
 	TS->boardPort(getBoardNr()).setTimer(TS->timeout());
 }
@@ -108,9 +109,10 @@ void ReadxCmd::saveTpAckEvent(GCFEvent& event)
 		if (tp_ack.status != 0) {
 			setStatus(0, (tp_ack.status << 24));
 		} else {
-			for (int32 an = 0; an < 256;an++) {
-				itsData[an]	= tp_ack.pagedata[an];
-			}
+		    memcpy(itsData, tp_ack.pagedata, 256 * sizeof(uint32));
+			//for (int32 an = 0; an < 256;an++) {
+			//	itsData[an]	= tp_ack.pagedata[an];
+			//}
 		}
 	}
 	setDone(true);
@@ -122,10 +124,11 @@ void ReadxCmd::sendTbbAckEvent(GCFPortInterface* clientport)
 	TBBReadxAckEvent tbb_ack;
 	
 	tbb_ack.status_mask = getStatus(0);
-
-	for (int32 an = 0; an < 256;an++) {
-		tbb_ack.pagedata[an] = itsData[an];
-	}
+	
+    memcpy(tbb_ack.pagedata, itsData, 256 * sizeof(uint32));
+	//for (int32 an = 0; an < 256;an++) {
+	//	tbb_ack.pagedata[an] = itsData[an];
+	//}
 	
 	if (clientport->isConnected()) { clientport->send(tbb_ack); }
 }
diff --git a/MAC/APL/PIC/TBB_Driver/src/TBBDriver.cc b/MAC/APL/PIC/TBB_Driver/src/TBBDriver.cc
index 66d3ae9137b..931790a96e2 100644
--- a/MAC/APL/PIC/TBB_Driver/src/TBBDriver.cc
+++ b/MAC/APL/PIC/TBB_Driver/src/TBBDriver.cc
@@ -156,8 +156,8 @@ TBBDriver::TBBDriver(string name)
 
 	itsAcceptor.init(*this, MAC_SVCMASK_TBBDRIVER + acceptorID, GCFPortInterface::MSPP, TBB_PROTOCOL);
 
-	// open port with TBB board
-	LOG_DEBUG_STR("Connecting to TBB boards");
+	// open port with TB board
+	LOG_DEBUG_STR("Connecting to TB boards");
 	itsBoard = new GCFETHRawPort[TS->maxBoards()];
 	ASSERT(itsBoard);
 
@@ -455,7 +455,7 @@ GCFEvent::TResult TBBDriver::setup_state(GCFEvent& event, GCFPortInterface& port
 		case TP_TRIGGER: {
 			for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) {
 				if (&port == &TS->boardPort(boardnr)) {
-					itsMsgHandler->sendTrigger(event,boardnr);
+					itsMsgHandler->sendTrigger(event, boardnr);
 					break;
 				}
 			}
@@ -564,6 +564,7 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
 			if (&port == itsQueueTimer) {
 				if (handleTbbCommandFromQueue()) {
 					TRAN(TBBDriver::busy_state);
+					return(status);
 				}
 				if (!itsTbbQueue->empty()) {
 					itsQueueTimer->setTimer(0.0);
@@ -572,6 +573,7 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
 			else if (&port == itsSetupTimer) {
 				LOG_DEBUG_STR("need boards setup");
 				TRAN(TBBDriver::setup_state);
+				return(status);
 			}
 			else if (&port == itsAliveTimer) {
 				CheckAlive(event, port);
@@ -604,7 +606,7 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
 		case TP_TRIGGER: {
 			for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) {
 				if (&port == &TS->boardPort(boardnr)) {
-					itsMsgHandler->sendTrigger(event,boardnr);
+					itsMsgHandler->sendTrigger(event, boardnr);
 					break;
 				}
 			}
@@ -616,27 +618,29 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
 
 		default: {
 			// look if there is already a command in the queue
-			if (!itsTbbQueue->empty()) {
-				if (addTbbCommandToQueue(event, port)) {
-					LOG_DEBUG_STR("idle_state: received TBB cmd, and put on queue");
-				} else {
-					status = GCFEvent::NOT_HANDLED;
-				}
-			}
-			else {
+			if (itsTbbQueue->empty()) {
 				// look if the event is a Tbb event
-				if (sendInfo(event, port)) {
-					// oke event is handled, no further action needed
-				}
-				else if (SetTbbCommand(event.signal)) {
+				if (SetTbbCommand(event.signal)) {
 					status = itsCmdHandler->doEvent(event,port);
 					TRAN(TBBDriver::busy_state);
+					return(status);
+				}
+				else if (sendInfo(event, port)) {
+					// oke event is handled, no further action needed
 				}
 				else {
 					// if not a Tbb event, return not-handled
 					status = GCFEvent::NOT_HANDLED;
 				}
 			}
+			else {
+				if (addTbbCommandToQueue(event, port)) {
+					LOG_DEBUG_STR("idle_state: received TBB cmd, and put on queue");
+				}
+				else {
+					status = GCFEvent::NOT_HANDLED;
+				}
+			}
 		} break;
 	}
 
@@ -662,9 +666,9 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port)
 
 		case F_ENTRY: {
 			LOG_DEBUG_STR("Entering busy_state");
-			if (itsCmdHandler->tpCmdDone()) {
-				TRAN(TBBDriver::idle_state);
-			}
+			//if (itsCmdHandler->tpCmdDone()) {
+			//	TRAN(TBBDriver::idle_state);
+			//}
 		} break;
 
 		case F_ACCEPT_REQ: {
@@ -695,7 +699,14 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port)
 		} break;
 
 		case F_TIMER: {
-			if (&port == itsSetupTimer) {
+			if (&port == itsCmdTimer) {
+			    if (itsCmdHandler->tpCmdDone()) {
+					TRAN(TBBDriver::idle_state);
+					return(status);
+				}
+				status = itsCmdHandler->doEvent(event,port); // dispatch timer event
+			}
+			else if (&port == itsSetupTimer) {
 			}
 			else if (&port == itsAliveTimer) {
 				CheckAlive(event, port);
@@ -703,6 +714,7 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port)
 			else {
 				if (itsCmdHandler->tpCmdDone()) {
 					TRAN(TBBDriver::idle_state);
+					return(status);
 				}
 				else {
 					status = itsCmdHandler->doEvent(event,port); // dispatch timer event
@@ -738,7 +750,7 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port)
 		case TP_TRIGGER: {
 			for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) {
 				if (&port == &TS->boardPort(boardnr)) {
-					itsMsgHandler->sendTrigger(event,boardnr);
+					itsMsgHandler->sendTrigger(event, boardnr);
 					break;
 				}
 			}
@@ -856,7 +868,11 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 		// mask all boards to check
 		for(int nr = 0; nr < TS->maxBoards(); nr++) {
 			// if board is busy, don't check alive
-			if ((itsCmd != 0) && (itsCmd->getBoardNr() == nr)) {
+			//if ((itsCmd != 0) && (itsCmd->getBoardNr() == nr)) {
+			
+			// if board was busy last 30 seconds, don't check alive
+			if (TS->isBoardUsed(nr)) {
+			    LOG_INFO_STR(formatString("board %d is used last 30 seconds, no alive check needed", nr));
 				sendmask |= (1 << nr);
 				activeboards |= (1 << nr);
 			}
@@ -865,11 +881,13 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 					 (TS->getBoardState(nr) == boardReady) ||
 					 (TS->getBoardState(nr) == boardError) ||
 					 (TS->getBoardState(nr) == boardCleared)) {
+			    LOG_INFO_STR(formatString("board %d alive check needed", nr));
 				itsBoard[nr].send(tp_event);
 				sendmask |= (1 << nr);
 			}
 			// not busy or active state, must be in service
 			else {
+			    LOG_INFO_STR(formatString("board %d active now", nr));
 				sendmask |= (1 << nr);
 				activeboards |= (1 << nr);
 			}
@@ -877,6 +895,7 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 
 		// if all boards busy or in service, end check and shedule new one
 		if (activeboards == sendmask) {
+		    TS->resetBoardUsed();
 			itsAliveTimer->setTimer(ALIVECHECKTIME);
 			itsAliveCheck = false;
 			return(!itsAliveCheck);
@@ -931,6 +950,7 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 
 			for (int board = 0; board < TS->maxBoards(); board++) {
 				if ((activeboards & (1 << board)) == 0) { // look for not active boards
+					//TS->setBoardState(board, noBoard);
 					if (retries < 3) {
 						itsBoard[board].send(tp_event);
 						LOG_INFO_STR("retry(" << retries << ") AliveCmd for board " << board);
@@ -938,15 +958,17 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 					else {
 						TS->setBoardState(board, noBoard);
 					}
+					
 				}
 			}
+			
 			if (retries == 3) { retries = 0; }
 
 			if (retries > 0) {
 				itsAliveTimer->setTimer(5.0);
 				return(!itsAliveCheck);
 			}
-
+            
 			if ((itsFirstAliveCheck == false) && (activeboards != TS->activeBoardsMask())) {
 				LOG_DEBUG_STR("sendmask[" << sendmask
 							<< "] activeboards[" << activeboards
@@ -965,7 +987,7 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 					}
 				}
 				itsMsgHandler->sendBoardChange(TS->activeBoardsMask());
-				LOG_INFO_STR("Available TBB boards changed:" << boardstr);
+				LOG_INFO_STR("Available TB boards changed:" << boardstr);
 			}
 			if (boardreset) {
 				itsSetupTimer->cancelAllTimers();
@@ -973,7 +995,8 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 			}
 			itsFirstAliveCheck = false;
 
-			LOG_DEBUG_STR("Active TBB boards check");
+			LOG_DEBUG_STR("Active TB boards check");
+			TS->resetBoardUsed();
 			itsAliveTimer->setTimer(ALIVECHECKTIME);
 			itsAliveCheck = false;
 		}
@@ -984,8 +1007,6 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 //-----------------------------------------------------------------------------
 bool TBBDriver::sendInfo(GCFEvent& event, GCFPortInterface& port)
 {
-	bool valid = true;
-
 	switch (event.signal) {
 
 		case TBB_GET_CONFIG: {
@@ -1086,17 +1107,15 @@ bool TBBDriver::sendInfo(GCFEvent& event, GCFPortInterface& port)
 		} break;
 
 		default: {
-			valid = false;
+			return(false);
 		} break;
 	}
-	return (valid);
+	return (true);
 }
 
 //-----------------------------------------------------------------------------
 bool TBBDriver::addTbbCommandToQueue(GCFEvent& event, GCFPortInterface& port)
 {
-	bool event_saved;
-
 	switch(event.signal)
 	{
 		case TBB_GET_CONFIG:
@@ -1157,14 +1176,13 @@ bool TBBDriver::addTbbCommandToQueue(GCFEvent& event, GCFPortInterface& port)
 			else {
 				itsTbbQueue->push_back(tbbevent);
 			}
-			event_saved = true;
 		} break;
 
 		default: {
-			event_saved = false;
+			return(false);
 		} break;
 	}
-	return(event_saved);
+	return(true);
 }
 
 // return true if TP-cmd and Driver must go to busy_state
@@ -1179,7 +1197,6 @@ bool TBBDriver::handleTbbCommandFromQueue()
 	if (SetTbbCommand(e->signal)) {
 		// communication with board needed
 		status = itsCmdHandler->doEvent(*e,*itsTbbQueue->front()->port);
-
 		tp_cmd = true;
 	} else {
 		// no communication needed with board
@@ -1434,7 +1451,8 @@ bool TBBDriver::SetTbbCommand(unsigned short signal)
 int main(int argc, char** argv)
 {
 	LOFAR::GCF::TM::GCFScheduler::instance()->init(argc, argv, "TBBDriver");    // initializes log system
-
+    GCFScheduler::instance()->disableQueue();					// run as fast as possible
+        
 	// Inform Logprocessor who we are
 	LOG_INFO("MACProcessScope: LOFAR_PermSW_TBBDriver");
 
diff --git a/MAC/APL/PIC/TBB_Driver/src/tbbctl.cc b/MAC/APL/PIC/TBB_Driver/src/tbbctl.cc
index 55157053994..276719e709a 100644
--- a/MAC/APL/PIC/TBB_Driver/src/tbbctl.cc
+++ b/MAC/APL/PIC/TBB_Driver/src/tbbctl.cc
@@ -2277,12 +2277,12 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 			if (!(ack.status_mask == TBB_SUCCESS)) {
 				cout << formatString("4 %s", getDriverErrorStr(ack.status_mask).c_str()) << endl;
 				itsCmdStage = 10;
-		  }
+		    }
 
-		  // memcpy(itsData, ack.pagedata, sizeof(ack.pagedata));
-			for (int32 dn = 0; dn < 256; dn++) {
-				itsData[dn] = ack.pagedata[dn];
-			}
+		    memcpy(itsData, ack.pagedata, 256 * sizeof(uint32));
+			//for (int32 dn = 0; dn < 256; dn++) {
+			//	itsData[dn] = ack.pagedata[dn];
+			//}
 		} break;
 
 		case 5: {
@@ -2290,10 +2290,11 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 			if (!(ack.status_mask == TBB_SUCCESS)) {
 				cout << formatString("5 %s", getDriverErrorStr(ack.status_mask).c_str()) << endl;
 				itsCmdStage = 10;
-		  }
-			for (int32 dn = 0; dn < 256; dn++) {
-				itsData[256 + dn] = ack.pagedata[dn];
-			}
+		    }
+			memcpy(itsData+256, ack.pagedata, 256 * sizeof(uint32));
+			//for (int32 dn = 0; dn < 256; dn++) {
+			//	itsData[256 + dn] = ack.pagedata[dn];
+			//}
 		} break;
 	}
 
@@ -2346,7 +2347,9 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 
 			// print size of progressbar on screen
 			bar_interval = itsPages / bar_size;
-			int recvtime = static_cast<int>((673. / 100000.) * itsPages);  // measured 100000 pages in 673 seconds
+			// calculate estimated receive time
+			// TBBDriver V2.31, measured 100000 pages in 277 seconds(logger on info)
+			int recvtime = static_cast<int>((280. / 100000.) * itsPages);  
 			int hours = recvtime / (60 * 60);
 			int mins = (recvtime - (hours * 60 * 60)) / 60;
 			int secs = recvtime - (hours * 60 * 60) - (mins * 60) + 1; // 1 second for overhead
@@ -2503,12 +2506,10 @@ GCFEvent::TResult ReadPageCmd::ack(GCFEvent& e)
 
 		if (val_cnt > 0) {
 			// save unpacked frame to file
-			//snprintf(filename, PATH_MAX, "%s.dat",itsBaseFileName);
-			//file = fopen(filename,"a");
 			if (itsFile) {
-				fwrite(&itsData[0],sizeof(uint32),22,itsFile);     // frame header 88 bytes (4 x 22)
-				fwrite(&val[0],sizeof(int16),val_cnt,itsFile);     // payload
-				fwrite(&itsData[509],sizeof(uint32),1,itsFile); // payload CRC 4 bytes (4 x 1)
+				fwrite(&itsData[0],sizeof(uint32),22,itsFile);   // frame header 88 bytes (4 x 22)
+				fwrite(&val[0],sizeof(int16),val_cnt,itsFile);   // payload
+				fwrite(&itsData[509],sizeof(uint32),1,itsFile);  // payload CRC 4 bytes (4 x 1)
 			}
 		}
 
diff --git a/MAC/APL/PIC/TBB_Driver/src/tbbctl.h b/MAC/APL/PIC/TBB_Driver/src/tbbctl.h
index 18a03f0b9eb..58e9524a8e0 100644
--- a/MAC/APL/PIC/TBB_Driver/src/tbbctl.h
+++ b/MAC/APL/PIC/TBB_Driver/src/tbbctl.h
@@ -45,7 +45,7 @@ namespace LOFAR {
 
 GCFTimerPort* itsCmdTimer;
 
-static const int TBBCTL_VERSION = 230;
+static const int TBBCTL_VERSION = 231;
 
 // MAX_N_TBBOARDS and MAX_N_RCUS come from TBB_protocol.ph
 
-- 
GitLab