From ce7dacdd81d625dcb26a7dc82054f4fbac9acbb0 Mon Sep 17 00:00:00 2001
From: Pieter Donker <donker@astron.nl>
Date: Mon, 25 Feb 2008 09:15:24 +0000
Subject: [PATCH] Bug 335: further development of TBB_protocol

---
 MAC/APL/PIC/TBBDriver/src/ClearCmd.cc       |   5 +-
 MAC/APL/PIC/TBBDriver/src/DriverSettings.cc |  11 +-
 MAC/APL/PIC/TBBDriver/src/DriverSettings.h  |  12 +-
 MAC/APL/PIC/TBBDriver/src/ResetCmd.cc       |  12 +-
 MAC/APL/PIC/TBBDriver/src/TBBDriver.cc      | 134 ++++++++++++--------
 5 files changed, 113 insertions(+), 61 deletions(-)

diff --git a/MAC/APL/PIC/TBBDriver/src/ClearCmd.cc b/MAC/APL/PIC/TBBDriver/src/ClearCmd.cc
index e9dc5f0571d..953cd24ee21 100644
--- a/MAC/APL/PIC/TBBDriver/src/ClearCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/ClearCmd.cc
@@ -103,14 +103,15 @@ void ClearCmd::saveTpAckEvent(GCFEvent& event)
 	
 	// reset channel-information for selected board	
 	if (itsTPackE->status == 0) {
-		TS->clearRcuSettings(getBoardNr());	
+		TS->clearRcuSettings(getBoardNr());
+		TS->setBoardState(getBoardNr(),boardCleared);	
 	}
 	LOG_DEBUG_STR(formatString("Received ClearAck from boardnr[%d]", getBoardNr()));
 	delete itsTPackE;
 	
 	nextBoardNr();
 	if (isDone()) {
-		setSleepTime(1.0); // clearing the registers will last 3 seconds
+		setSleepTime(3.0); // clearing the registers will last 3 seconds
 	}
 }
 
diff --git a/MAC/APL/PIC/TBBDriver/src/DriverSettings.cc b/MAC/APL/PIC/TBBDriver/src/DriverSettings.cc
index 39732b8d097..b692e876d0d 100644
--- a/MAC/APL/PIC/TBBDriver/src/DriverSettings.cc
+++ b/MAC/APL/PIC/TBBDriver/src/DriverSettings.cc
@@ -52,7 +52,7 @@ TbbSettings* TbbSettings::instance()
 // Default constructor
 //
 TbbSettings::TbbSettings() :
-	itsDriverVersion(DRIVER_VERSION),				// set cvs version of TBBDriver.c (now 1.13)
+	itsDriverVersion(DRIVER_VERSION),				// set version of TBBDriver.cc
 	itsMaxBoards(0),							// max.number of boards on 1 driver 
 	itsMaxChannels(0),						// max.number of channels on 1 driver
 	itsMpsOnBoard(4),							// number of MPs on 1 board
@@ -212,6 +212,7 @@ void TbbSettings::setMaxBoards (int32 maxboards)
 		}
 	}
 	
+	itsBoardSetup  = false;
 	itsTriggerMode = 0;	
 		
 	if (itsBoardInfo) delete itsBoardInfo;
@@ -227,6 +228,14 @@ void TbbSettings::setMaxBoards (int32 maxboards)
 	}
 }
 
+void TbbSettings::setBoardState(int32 boardnr, BoardStateT boardstate)
+{
+	itsBoardInfo[boardnr].boardState = boardstate; 
+	if ((boardstate > noBoard) && (boardstate < boardReady)) {
+		itsBoardSetup = true;
+	}
+}
+
 //---- setActiveBoardsMask -----------------------
 void TbbSettings::setActiveBoardsMask (uint32 activeboardsmask)
 {
diff --git a/MAC/APL/PIC/TBBDriver/src/DriverSettings.h b/MAC/APL/PIC/TBBDriver/src/DriverSettings.h
index d30c077f338..45f5e9d3809 100644
--- a/MAC/APL/PIC/TBBDriver/src/DriverSettings.h
+++ b/MAC/APL/PIC/TBBDriver/src/DriverSettings.h
@@ -35,10 +35,10 @@
 namespace LOFAR {
   namespace TBB {
 
-static const int DRIVER_VERSION = 115; // 1.15 
-
-enum BoardStateT {noBoard, boardReset, boardCleared, boardFreed, boardReady, boardError};
+static const int DRIVER_VERSION = 200; // 2.00 
 
+//enum BoardStateT {noBoard, newBoard, boardReset, boardCleared, boardFreed, boardReady, boardError};
+enum BoardStateT {noBoard, resetBoard, boardReset, clearBoard, boardCleared, freeBoard, boardFreed, boardReady, boardError};
 // info for all channels
 struct ChannelInfo
 {
@@ -133,6 +133,8 @@ public:
 	
 	BoardStateT getBoardState(int32 boardnr);
 	void setBoardState(int32 boardnr, BoardStateT boardstate);
+	bool boardSetupNeeded();
+	void clearBoardSetup();
 	void setActiveBoardsMask (uint32 activeboardsmask);
 	void setActiveBoard (int32 boardnr);
 	void resetActiveBoard (int32 boardnr);
@@ -203,6 +205,7 @@ private:
 	int32				*itsCh2RcuTable;
 	BoardInfo		*itsBoardInfo;
 	ChannelInfo	*itsChannelInfo;
+	bool				itsBoardSetup;
 	uint16			itsTriggerMode;
 	string			itsIfName;
 	
@@ -230,8 +233,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, BoardStateT boardstate) { itsBoardInfo[boardnr].boardState = boardstate; }
 inline	BoardStateT TbbSettings::getBoardState(int32 boardnr) { return (itsBoardInfo[boardnr].boardState); }
+inline  bool TbbSettings::boardSetupNeeded() { return (itsBoardSetup); }
+inline  void TbbSettings::clearBoardSetup() { itsBoardSetup = false; }
 
 //---- inline functions for channel information ------------
 inline	bool TbbSettings::isChSelected(int32 channelnr) { return (itsChannelInfo[channelnr].Selected); }
diff --git a/MAC/APL/PIC/TBBDriver/src/ResetCmd.cc b/MAC/APL/PIC/TBBDriver/src/ResetCmd.cc
index c6c8199bfa0..db534705fc7 100644
--- a/MAC/APL/PIC/TBBDriver/src/ResetCmd.cc
+++ b/MAC/APL/PIC/TBBDriver/src/ResetCmd.cc
@@ -79,6 +79,7 @@ void ResetCmd::saveTbbEvent(GCFEvent& event)
 		itsTBBackE->status_mask[boardnr] = 0;
 	}
 	
+	// look for first board in mask
 	while ((itsBoardMask & (1 << itsBoardNr)) == 0) {
 		itsBoardNr++;
 		if (itsBoardNr >= TS->maxBoards()) { 
@@ -109,14 +110,19 @@ void ResetCmd::saveTpAckEvent(GCFEvent& event)
 {
 	// in case of a time-out, set error mask
 	if (event.signal == F_TIMER) {
-		//itsTBBackE->status_mask[getBoardNr()] |= TBB_RCU_COMM_ERROR;
+		TS->setBoardState(getBoardNr(),noBoard);
 	}	else {
 		itsTPackE = new TPResetAckEvent(event);
-	
+		if (itsTPackE->status == 0) {
+			TS->setBoardState(getBoardNr(),boardReset);
+		} else {
+			TS->setBoardState(getBoardNr(),boardError);
+		}
 		delete itsTPackE;
 	}
 	
 	itsBoardNr++;
+	// look for next board in mask
 	while ((itsBoardMask & (1 << itsBoardNr)) == 0) {
 		itsBoardNr++;
 		if (itsBoardNr >= TS->maxBoards()) { 
@@ -127,7 +133,7 @@ void ResetCmd::saveTpAckEvent(GCFEvent& event)
 	if (itsBoardNr < TS->maxBoards()) {
 		setBoardNr(itsBoardNr);
 	} else {
-		setSleepTime(1.0);
+		setSleepTime(3.0);
 		setDone(true);
 	}
 }
diff --git a/MAC/APL/PIC/TBBDriver/src/TBBDriver.cc b/MAC/APL/PIC/TBBDriver/src/TBBDriver.cc
index 3a946524c55..0cea3b4c6b8 100644
--- a/MAC/APL/PIC/TBBDriver/src/TBBDriver.cc
+++ b/MAC/APL/PIC/TBBDriver/src/TBBDriver.cc
@@ -126,10 +126,8 @@ TBBDriver::TBBDriver(string name)
   TS->getTbbSettings();
   
 	cmd = 0;
-	//itsActiveBoards = 0;
-	itsNewBoards = 0;
+	//itsNewBoards = 0;
 	itsAliveCheck = false;
-	//itsActiveBoardsChange = false;
 	itsResetCount = 0;
   
   // tell broker we are here
@@ -273,6 +271,7 @@ GCFEvent::TResult TBBDriver::setup_state(GCFEvent& event, GCFPortInterface& port
         
 		case F_ENTRY:	{	
 			itsSaveTimer->cancelAllTimers();
+			itsAliveTimer->cancelAllTimers();
 			retries = new int[TS->maxBoards()];
 			waitTimer = new int[TS->maxBoards()];
 
@@ -315,72 +314,92 @@ GCFEvent::TResult TBBDriver::setup_state(GCFEvent& event, GCFPortInterface& port
 				setupDone = true;
 				for (int board = 0; board < TS->maxBoards(); board++) {
 			
-					if ((TS->getBoardState(board) == noBoard) 
-							//|| (TS->getBoardState(board) == boardReady) 
-							|| (TS->getBoardState(board) == boardFreed) 
-							|| (TS->getBoardState(board) == boardError)) {
-						continue;
-					}
-				
 					if (waitTimer[board]) { waitTimer[board]--; }
 			 		if (waitTimer[board]) { 
 						setupDone = false;
 						continue; 
 					} // board still busy, next board
 					
-					/*
-					if (TS->getBoardState(board) == boardFreed) {
-						TS->setBoardState(board,boardReady);
-		    			LOG_INFO_STR("'" << itsBoard[board].getName() << "' is Ready");
-						continue; // no further service needed
+					if ((TS->getBoardState(board) == noBoard) 
+							|| (TS->getBoardState(board) == boardReady) 
+							|| (TS->getBoardState(board) == boardError)) {
+						continue;
 					}
-					*/
-				
-					if (TS->getBoardState(board) == boardReset) {
+					
+					if (TS->getBoardState(board) == resetBoard) {
+						TPResetEvent reset;
+		 				reset.opcode = TPRESET;
+		 				reset.status = 0;
+						itsBoard[board].send(reset);
+						itsBoard[board].setTimer(5.0);	
+						LOG_INFO_STR("RESET is send to port '" << itsBoard[board].getName() << "'");
+						waitTimer[board] = 10;
+						setupDone = false;
+						continue;
+					}
+					
+					if ((TS->getBoardState(board) == clearBoard) || (TS->getBoardState(board) == boardReset)) {
 						TPClearEvent clear;
 		 				clear.opcode = TPCLEAR;
 		 				clear.status = 0;
 						itsBoard[board].send(clear);
-						itsBoard[board].setTimer(2.0);	
+						itsBoard[board].setTimer(5.0);	
 						LOG_INFO_STR("CLEAR is send to port '" << itsBoard[board].getName() << "'");
-						waitTimer[board] = 2;
+						waitTimer[board] = 10;
 						setupDone = false;
 						continue;
 					}
 
-					if (TS->getBoardState(board) == boardCleared) {
+					if ((TS->getBoardState(board) == freeBoard) || (TS->getBoardState(board) == boardCleared)) {
 						TPFreeEvent free;
 		 				free.opcode = TPFREE;
 		 				free.status = 0;
 		 				free.channel = 0xFFFFFFFF;  // send channel = -1 to free all inputs
 						itsBoard[board].send(free);
-						itsBoard[board].setTimer(2.0);	
+						itsBoard[board].setTimer(5.0);	
 						LOG_INFO_STR("FREE -1 is send to port '" << itsBoard[board].getName() << "'");
-						waitTimer[board] = 2;
+						waitTimer[board] = 10;
+						setupDone = false;
+						continue;
+					}
+					
+					if (TS->getBoardState(board) == boardFreed) {
+						TPAliveEvent alive;
+		 				alive.opcode = TPALIVE;
+		 				alive.status = 0;
+						itsBoard[board].send(alive);
+						itsBoard[board].setTimer(5.0);	
+						LOG_INFO_STR("ALIVE is send to port '" << itsBoard[board].getName() << "'");
+						waitTimer[board] = 10;
 						setupDone = false;
 						continue;
 					}
 				}
 			
-				if (setupDone) {
-					LOG_INFO_STR("setting up boards done");	
-					itsNewBoards = 0;
-				} else {
+				if (!setupDone) {
 					itsSetupTimer->setTimer(1.0); // run this every second
 				}
 				
 			}	else { // no setup-timer event, must be a board time-out
 				int board = TS->port2Board(&port); // get board nr
-				waitTimer[board] = 0;
-				retries[board]++;
-				if (retries[board] >= TS->maxRetries()) { 
-			  		TS->resetActiveBoard(board);    			 
-			  		TS->setBoardState(board,boardError);
+				if (TS->getBoardState(board) == resetBoard) {
+					TS->resetActiveBoard(board);
+					TS->setBoardState(board,boardReset);	
+				} else {
+					waitTimer[board] = 0;
+					retries[board]++;
+					if (retries[board] >= TS->maxRetries()) { 
+			  			TS->resetActiveBoard(board);    			 
+			  			TS->setBoardState(board,boardError);
+					}
 				}
 			}
+			
 			if (setupDone) {
+				LOG_INFO_STR("setting up boards done");	
+				TS->clearBoardSetup();
 				if (TS->saveTriggersToFile()) { itsSaveTimer->setTimer(2.0, 2.0); }
-				itsAliveTimer->setTimer(0.0);	
+				itsAliveTimer->setTimer(ALIVECHECKTIME);	
 				TRAN(TBBDriver::idle_state);
 			} 
    	} break;
@@ -389,17 +408,34 @@ GCFEvent::TResult TBBDriver::setup_state(GCFEvent& event, GCFPortInterface& port
 			status = RawEvent::dispatch(*this, port);	
 		}	break;
 		
+		case TP_RESET_ACK: {
+			int board = TS->port2Board(&port); // get board nr
+			itsBoard[board].cancelAllTimers();
+			TS->setBoardState(board,boardReset);
+			waitTimer[board] = 4;
+    } break;
+		
 		case TP_CLEAR_ACK: {
 			int board = TS->port2Board(&port); // get board nr
 			itsBoard[board].cancelAllTimers();
 			TS->setBoardState(board,boardCleared);
-    	} break;
+			waitTimer[board] = 3;
+    } break;
 		
 		case TP_FREE_ACK: {
 			int board = TS->port2Board(&port); // get board nr
 			itsBoard[board].cancelAllTimers();
     		TS->setBoardState(board,boardFreed);
-    	} break;
+    		waitTimer[board] = 3;
+    } break;
+    
+    case TP_ALIVE_ACK: {
+			int board = TS->port2Board(&port); // get board nr
+			itsBoard[board].cancelAllTimers();
+    		TS->setBoardState(board,boardReady);
+    		LOG_INFO_STR("'" << itsBoard[board].getName() << "' is Ready");
+    		waitTimer[board] = 0;
+    } break;
 	
 		case TP_TRIGGER: {
 			for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) {
@@ -477,8 +513,9 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
 				break;                      
 			}                             
 						                        
-			// if new boards detected set them up
-			if (itsNewBoards != 0) {      
+			// if board setup needed
+			if (TS->boardSetupNeeded()) {      
+				LOG_DEBUG_STR("need boards setup");
 				TRAN(TBBDriver::setup_state);
 				break;
 			}
@@ -560,8 +597,8 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port)
 				CheckAlive(event, port);
 			}
 			// if new boards detected set them up
-			if (itsAliveCheck == false && itsNewBoards != 0) {
-				LOG_DEBUG_STR(formatString("new boards: %08x", itsNewBoards));
+			if (itsAliveCheck == false && TS->boardSetupNeeded()) {
+				LOG_DEBUG_STR("need boards setup");
 				TRAN(TBBDriver::setup_state);
 			}
 		} break;
@@ -865,7 +902,7 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 	//itsAliveTimer->cancelAllTimers();
 	if (!itsAliveCheck) {
 		itsAliveCheck	= true;
-		itsNewBoards	= 0;
+		//itsNewBoards	= 0;
 		boardnr				= 0;
 		sendmask			= 0;
 		activeboards	= 0;
@@ -887,22 +924,17 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port)
 		
 				TPAliveAckEvent ack(event);
 				
-				if (ack.resetflag == 0){
-					if (TS->getBoardState(boardnr) == boardFreed) {
-							TS->setBoardState(boardnr,boardReady);
-			    		LOG_INFO_STR("'" << itsBoard[boardnr].getName() << "' is Ready");
-			    } else {
-						itsNewBoards |= (1 << boardnr);	// board is reset, setup is needed
+				if (ack.resetflag == 0) {
+						//itsNewBoards |= (1 << boardnr);	// board is reset, setup is needed
 						itsResetCount[boardnr]++;
 						TS->clearRcuSettings(boardnr);
-						TS->setBoardState(boardnr,boardCleared);
+						TS->setBoardState(boardnr,clearBoard);
 						LOG_INFO_STR("=BOARD-RESET=, TBB board " << boardnr << " has been reset " << itsResetCount[boardnr] << " times");
-					}
 				}
-		
+						
 				if ((TS->activeBoardsMask() & (1 << boardnr)) == 0) {
-					itsNewBoards |= (1 << boardnr); // new board, setup is needed	
-					TS->setBoardState(boardnr,boardReset);
+					//itsNewBoards |= (1 << boardnr); // new board, setup is needed	
+					TS->setBoardState(boardnr,resetBoard);
 					LOG_INFO_STR("=NEW_BOARD=, TBB board " << boardnr << " is new");
 				}
 			}
-- 
GitLab