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