diff --git a/MAC/APL/CR_Protocol/src/CR_Protocol.prot b/MAC/APL/CR_Protocol/src/CR_Protocol.prot index 014bbb20b43391deb9829bf0b87ec41204b22556..0b340b73ec87dd7a16010cd3de4e65739059d553 100644 --- a/MAC/APL/CR_Protocol/src/CR_Protocol.prot +++ b/MAC/APL/CR_Protocol/src/CR_Protocol.prot @@ -52,14 +52,20 @@ error = { error = { id = TIME; - msg = "Time errors, given time in past"; + msg = "Time error, given time in past"; }; error = { id = OBSERVATION; - msg = "Observation errors, given observation not active"; + msg = "Observation error, given observation not active"; }; +error = { + id = BUSY; + msg = "Busy error, dumping data to cep not ready"; +}; + + // // CR events // @@ -238,4 +244,42 @@ event = { }; }; +// VHECR_STATE +event = { + signal = VHECR_STATE; + dir = IN; + param = { + name = "triggerID"; + type = "uint32"; + }; + param = { + name = "observationID"; + type = "uint32"; + }; + param = { + name = "stationList"; + type = "string"; + }; + param = { + name = "state"; + type = "uint32"; + }; +}; + +event = { + signal = VHECR_STATE_ACK; + dir = OUT; + param = { + name = "triggerID"; + type = "uint32"; + }; + param = { + name = "result"; + type = "uint32"; + }; +}; + + + + diff --git a/MAC/APL/MainCU/src/CRTriggerControl/TriggerControl.cc b/MAC/APL/MainCU/src/CRTriggerControl/TriggerControl.cc index 20bfc8f3204c91fa02c2fda634de8411c6e87cb5..1a2aaa683ca3fed5f88a30a817a19ea7d70236f1 100644 --- a/MAC/APL/MainCU/src/CRTriggerControl/TriggerControl.cc +++ b/MAC/APL/MainCU/src/CRTriggerControl/TriggerControl.cc @@ -300,7 +300,7 @@ GCFEvent::TResult TriggerControl::openPublisher(GCFEvent& event, GCFPortInterfac GCFEvent::TResult TriggerControl::operational_state(GCFEvent& event, GCFPortInterface& port) { LOG_DEBUG_STR ("operational:" << eventName(event) << "@" << port.getName()); - + switch (event.signal) { case F_ENTRY: { itsTimerPort->setTimer(5.0); @@ -311,7 +311,13 @@ GCFEvent::TResult TriggerControl::operational_state(GCFEvent& event, GCFPortInte itsPropertySet->setValue(PN_FSM_ERROR,GCFPVString("")); } break; - case F_ACCEPT_REQ: + case F_ACCEPT_REQ: { + GCFTCPPort* itsClient = new GCFTCPPort(); + itsClient->init(*this, "client", GCFPortInterface::SPP, CR_PROTOCOL); + itsListener->accept(*itsClient); + LOG_INFO_STR("NEW CLIENT CONNECTED"); + } break; + case F_CONNECTED: { if (&port == itsListener) { LOG_INFO("TCP Listener started successful"); @@ -322,7 +328,10 @@ GCFEvent::TResult TriggerControl::operational_state(GCFEvent& event, GCFPortInte case F_DISCONNECTED: { // TODO: CHECK FOR OUR OWN PORTS port.close(); - if (&port == itsListener) { + if (&port == itsClient) { + LOG_INFO_STR("CLIENT DISCONNECTED"); + } + else if (&port == itsListener) { LOG_FATAL("Failed to start TCP Listener"); } } break; @@ -552,7 +561,7 @@ bool TriggerControl::_addObservation(int obsID) LOG_DEBUG_STR("Trying to readfile " << filename); try { theObsPS.adoptFile(filename); - theObs = Observation(&theObsPS); + theObs = Observation(&theObsPS, false); LOG_DEBUG_STR("theOBS=" << theObs); } catch (Exception& ex) { @@ -651,7 +660,7 @@ void TriggerControl::_CRstopHandler(GCFEvent& event, GCFPortInterface& port) void TriggerControl::_CRreadHandler(GCFEvent& event, GCFPortInterface& port) { CRReadEvent e(event); - CRStopAckEvent ack; + CRReadAckEvent ack; ack.triggerID = e.triggerID; ack.result = CR_OBSERVATION_ERR; @@ -690,7 +699,7 @@ void TriggerControl::_CRreadHandler(GCFEvent& event, GCFPortInterface& port) void TriggerControl::_CRrecordHandler(GCFEvent& event, GCFPortInterface& port) { CRRecordEvent e(event); - CRStopAckEvent ack; + CRRecordAckEvent ack; ack.triggerID = e.triggerID; ack.result = CR_OBSERVATION_ERR; @@ -719,7 +728,7 @@ void TriggerControl::_CRrecordHandler(GCFEvent& event, GCFPortInterface& port) void TriggerControl::_CRstopDumpsHandler(GCFEvent& event, GCFPortInterface& port) { CRStopDumpsEvent e(event); - CRStopAckEvent ack; + CRStopDumpsAckEvent ack; ack.triggerID = e.triggerID; ack.result = CR_OBSERVATION_ERR; @@ -741,7 +750,7 @@ void TriggerControl::_CRstopDumpsHandler(GCFEvent& event, GCFPortInterface& port void TriggerControl::_CRcepSpeedHandler(GCFEvent& event, GCFPortInterface& port) { CRCepSpeedEvent e(event); - CRStopAckEvent ack; + CRCepSpeedAckEvent ack; ack.triggerID = e.triggerID; ack.result = CR_OBSERVATION_ERR; diff --git a/MAC/APL/MainCU/src/CRTriggerControl/TriggerControl.h b/MAC/APL/MainCU/src/CRTriggerControl/TriggerControl.h index 56bff4c2abd8d08a7c3f73ac2e75340aa3d23749..ec99d33d702008432db9fd9b1a27ee77e85bbbc0 100644 --- a/MAC/APL/MainCU/src/CRTriggerControl/TriggerControl.h +++ b/MAC/APL/MainCU/src/CRTriggerControl/TriggerControl.h @@ -102,6 +102,7 @@ private: int itsSubscriptionID; GCFRTDBPort* itsPublisher; GCFTCPPort* itsListener; + GCFTCPPort* itsClient; GCFTimerPort* itsTimerPort; typedef struct ObsInfo { diff --git a/MAC/APL/MainCU/src/CRTriggerControl/crctl.cc b/MAC/APL/MainCU/src/CRTriggerControl/crctl.cc index fbebd31b6b247c4f180cdcafa2dd2bf4ed4cac24..72857d51b551da151a0604b71414844688f8c8e5 100644 --- a/MAC/APL/MainCU/src/CRTriggerControl/crctl.cc +++ b/MAC/APL/MainCU/src/CRTriggerControl/crctl.cc @@ -62,7 +62,7 @@ static const double DELAY = 60.0; static CRCtl *thisCRCtl = 0; //---- STOP ---------------------------------------------------------------- -StopCmd::StopCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer) : Command(port, timer) +StopCmd::StopCmd(GCFPortInterface& port, GCFTimerPort& timer) : Command(port, timer) { cout << endl; cout << "== RTDB ================================================= stop tbb recording ====" << endl; @@ -95,7 +95,7 @@ GCFEvent::TResult StopCmd::ack(GCFEvent& e) cout << "recording stopped at: " << (double)itsStopTime << " sec" << endl; } else { - cout << "Error in STOP command" << endl; + cout << "Error in STOP command" << errorName(ack.result) << endl; } setCmdDone(true); @@ -103,10 +103,10 @@ GCFEvent::TResult StopCmd::ack(GCFEvent& e) } //---- READ ---------------------------------------------------------------- -ReadCmd::ReadCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer) : Command(port, timer) +ReadCmd::ReadCmd(GCFPortInterface& port, GCFTimerPort& timer) : Command(port, timer) { cout << endl; - cout << "== RTDB ================================================= read tbb data(cep) ====" << endl; + cout << "== CRTriggerControl =============================== read tbb data(cep) ====" << endl; cout << endl; } @@ -142,7 +142,7 @@ GCFEvent::TResult ReadCmd::ack(GCFEvent& e) cout << "time after : " << (double)itsTimeAfter << " sec" << endl; } else { - cout << "Error in READ command" << endl; + cout << "Error in READ command" << errorName(ack.result) << endl; } setCmdDone(true); @@ -150,10 +150,10 @@ GCFEvent::TResult ReadCmd::ack(GCFEvent& e) } //---- RECORD ---------------------------------------------------------------- -RecordCmd::RecordCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer) : Command(port, timer) +RecordCmd::RecordCmd(GCFPortInterface& port, GCFTimerPort& timer) : Command(port, timer) { cout << endl; - cout << "== RTDB ================================================= start record ====" << endl; + cout << "== CRTriggerControl ===================================== start record ====" << endl; cout << endl; } @@ -183,7 +183,7 @@ GCFEvent::TResult RecordCmd::ack(GCFEvent& e) cout << "for RCU : " << itsRcuStr << endl; } else { - cout << "Error in RECORD command" << endl; + cout << "Error in RECORD command" << errorName(ack.result) << endl; } setCmdDone(true); @@ -191,10 +191,10 @@ GCFEvent::TResult RecordCmd::ack(GCFEvent& e) } //---- CEPSPEED ---------------------------------------------------------------- -CepSpeedCmd::CepSpeedCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer) : Command(port, timer) +CepSpeedCmd::CepSpeedCmd(GCFPortInterface& port, GCFTimerPort& timer) : Command(port, timer) { cout << endl; - cout << "== RTDB ================================================= set cep speed ====" << endl; + cout << "== CRTriggerControl ==================================== set cep speed ====" << endl; cout << endl; } @@ -225,7 +225,7 @@ GCFEvent::TResult CepSpeedCmd::ack(GCFEvent& e) cout << "for Station: " << itsStationStr << endl; } else { - cout << "Error in CEPSPEED command" << endl; + cout << "Error in CEPSPEED command" << errorName(ack.result) << endl; } setCmdDone(true); @@ -233,10 +233,10 @@ GCFEvent::TResult CepSpeedCmd::ack(GCFEvent& e) } //---- STOPDUMPS ---------------------------------------------------------------- -StopDumpsCmd::StopDumpsCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer) : Command(port, timer) +StopDumpsCmd::StopDumpsCmd(GCFPortInterface& port, GCFTimerPort& timer) : Command(port, timer) { cout << endl; - cout << "== RTDB ================================================= stop dumps ====" << endl; + cout << "== CRTriggerControl ======================================= stop dumps ====" << endl; cout << endl; } @@ -264,7 +264,7 @@ GCFEvent::TResult StopDumpsCmd::ack(GCFEvent& e) cout << "for Station: " << itsStationStr << endl; } else { - cout << "Error in STOPDUMPS command" << endl; + cout << "Error in STOPDUMPS command" << errorName(ack.result) << endl; } setCmdDone(true); @@ -314,8 +314,8 @@ CRCtl::CRCtl(string name, int argc, char** argv): GCFTask((State)&CRCtl::initial itsCommand(0),itsArgc(argc),itsArgv(argv) { registerProtocol (CR_PROTOCOL, CR_PROTOCOL_STRINGS); - itsRTDBPort = new GCF::RTDB::GCFRTDBPort(*this, "RTDBControlPort", "LOFAR_TBBControl"); - ASSERTSTR(itsRTDBPort, "Can't allocate RTDBPort"); + itsCRTrigPort = new GCFTCPPort(*this, MAC_SVCMASK_TRIGGERCTRL, GCFPortInterface::SAP, CR_PROTOCOL); + ASSERTSTR(itsCRTrigPort, "Can't allocate itsCRTrigPort"); itsTimerPort = new GCFTimerPort(*this, "timerPort"); } @@ -324,7 +324,7 @@ CRCtl::CRCtl(string name, int argc, char** argv): GCFTask((State)&CRCtl::initial CRCtl::~CRCtl() { if (itsCommand) { delete itsCommand; } - if (itsRTDBPort) { delete itsRTDBPort; } + if (itsCRTrigPort) { delete itsCRTrigPort; } if (itsTimerPort) { delete itsTimerPort; } } @@ -345,7 +345,7 @@ void CRCtl::sigintHandler(int signum) // void CRCtl::finish() { - cout << "tbbctl stopped by user" << endl; + cout << "crctl stopped by user" << endl; sleep(1); GCFScheduler::instance()->stop(); //TRAN(StationControl::finishing_state); @@ -361,8 +361,8 @@ GCFEvent::TResult CRCtl::initial(GCFEvent& e, GCFPortInterface& port) } break; case F_ENTRY: { - if (!itsRTDBPort->isConnected()) { - itsRTDBPort->open(); + if (!itsCRTrigPort->isConnected()) { + itsCRTrigPort->open(); itsTimerPort->setTimer(5.0); } // first redirect signalHandler to our finishing state to leave PVSS @@ -373,7 +373,7 @@ GCFEvent::TResult CRCtl::initial(GCFEvent& e, GCFPortInterface& port) } break; case F_CONNECTED: { - if (itsRTDBPort->isConnected()) { + if (itsCRTrigPort->isConnected()) { itsTimerPort->cancelAllTimers(); cout << "connected, execute command" << endl; TRAN(CRCtl::docommand); @@ -387,7 +387,7 @@ GCFEvent::TResult CRCtl::initial(GCFEvent& e, GCFPortInterface& port) case F_TIMER: { // try again 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= RTDB is NOT responding =x=" << endl; + cout << " =x= CRTriggerControl 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; exit(EXIT_FAILURE); } break; @@ -402,7 +402,7 @@ GCFEvent::TResult CRCtl::initial(GCFEvent& e, GCFPortInterface& port) //----------------------------------------------------------------------------- GCFEvent::TResult CRCtl::docommand(GCFEvent& e, GCFPortInterface& port) { - cout << "docommand signal:" << eventName(e) << endl; + //cout << "docommand signal:" << eventName(e) << endl; GCFEvent::TResult status = GCFEvent::HANDLED; switch (e.signal) { @@ -550,7 +550,7 @@ Command* CRCtl::parse_options(int argc, char** argv) case 'b': { // --stop if (command) delete command; - StopCmd* cmd = new StopCmd(*itsRTDBPort, *itsTimerPort); + StopCmd* cmd = new StopCmd(*itsCRTrigPort, *itsTimerPort); command = cmd; double stopTime = 0.; @@ -568,7 +568,7 @@ Command* CRCtl::parse_options(int argc, char** argv) case 'c': { // --read if (command) delete command; - ReadCmd* cmd = new ReadCmd(*itsRTDBPort, *itsTimerPort); + ReadCmd* cmd = new ReadCmd(*itsCRTrigPort, *itsTimerPort); command = cmd; double time = 0.; @@ -590,13 +590,13 @@ Command* CRCtl::parse_options(int argc, char** argv) case 'd': { // --record if (command) delete command; - RecordCmd* cmd = new RecordCmd(*itsRTDBPort, *itsTimerPort); + RecordCmd* cmd = new RecordCmd(*itsCRTrigPort, *itsTimerPort); command = cmd; } break; case 'e': { // --cepspeed if (command) delete command; - CepSpeedCmd* cmd = new CepSpeedCmd(*itsRTDBPort, *itsTimerPort); + CepSpeedCmd* cmd = new CepSpeedCmd(*itsCRTrigPort, *itsTimerPort); command = cmd; uint32 delay = 0; uint32 datapaths = 0; @@ -618,7 +618,7 @@ Command* CRCtl::parse_options(int argc, char** argv) case 'f': { // --stopdumps if (command) delete command; - StopDumpsCmd* cmd = new StopDumpsCmd(*itsRTDBPort, *itsTimerPort); + StopDumpsCmd* cmd = new StopDumpsCmd(*itsCRTrigPort, *itsTimerPort); command = cmd; } break; diff --git a/MAC/APL/MainCU/src/CRTriggerControl/crctl.h b/MAC/APL/MainCU/src/CRTriggerControl/crctl.h index c705bef16297cfb3a36d37d2043a1ec923788380..6a16d4773fd5f631a08098fc945d8ce188e7cc42 100644 --- a/MAC/APL/MainCU/src/CRTriggerControl/crctl.h +++ b/MAC/APL/MainCU/src/CRTriggerControl/crctl.h @@ -28,7 +28,7 @@ #include <APL/CR_Protocol/CR_Protocol.ph> #include <APL/RTCCommon/NsTimestamp.h> #include <GCF/TM/GCF_Control.h> -#include <GCF/RTDB/GCF_RTDBPort.h> +#include <GCF/TM/GCF_DevicePort.h> #include <GCF/TM/GCF_TimerPort.h> #include <Common/lofar_bitset.h> #include <Common/lofar_list.h> @@ -116,7 +116,7 @@ public: } protected: - explicit Command(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer) : + explicit Command(GCFPortInterface& port, GCFTimerPort& timer) : itsPort(port), itsTimer(timer), itsCmdDone(false), @@ -131,7 +131,7 @@ protected: Command(); // no default construction allowed protected: - GCF::RTDB::GCFRTDBPort& itsPort; + GCFPortInterface& itsPort; GCFTimerPort& itsTimer; bool itsCmdDone; uint32 itsObservationID; @@ -147,7 +147,7 @@ private: class StopCmd : public Command { public: - StopCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer); + StopCmd(GCFPortInterface& port, GCFTimerPort& timer); virtual ~StopCmd() { } virtual void send(); virtual GCFEvent::TResult ack(GCFEvent& e); @@ -160,7 +160,7 @@ private: class ReadCmd : public Command { public: - ReadCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer); + ReadCmd(GCFPortInterface& port, GCFTimerPort& timer); virtual ~ReadCmd() { } virtual void send(); virtual GCFEvent::TResult ack(GCFEvent& e); @@ -177,7 +177,7 @@ private: class RecordCmd : public Command { public: - RecordCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer); + RecordCmd(GCFPortInterface& port, GCFTimerPort& timer); virtual ~RecordCmd() { } virtual void send(); virtual GCFEvent::TResult ack(GCFEvent& e); @@ -188,7 +188,7 @@ private: class CepSpeedCmd : public Command { public: - CepSpeedCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer); + CepSpeedCmd(GCFPortInterface& port, GCFTimerPort& timer); virtual ~CepSpeedCmd() { } virtual void send(); virtual GCFEvent::TResult ack(GCFEvent& e); @@ -203,7 +203,7 @@ private: class StopDumpsCmd : public Command { public: - StopDumpsCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer); + StopDumpsCmd(GCFPortInterface& port, GCFTimerPort& timer); virtual ~StopDumpsCmd() { } virtual void send(); virtual GCFEvent::TResult ack(GCFEvent& e); @@ -259,9 +259,9 @@ private: void logMessage(ostream& stream, const string& message); void commandHelp(); private: - GCF::RTDB::GCFRTDBPort* itsRTDBPort; - GCFTimerPort* itsTimerPort; - Command* itsCommand; // the command to execute + GCFPortInterface* itsCRTrigPort; + GCFTimerPort* itsTimerPort; + Command* itsCommand; // the command to execute // commandline parameters int itsArgc; diff --git a/MAC/APL/PIC/TBB_Driver/CMakeLists.txt b/MAC/APL/PIC/TBB_Driver/CMakeLists.txt index 841670508036ea9bc5b1685b9443dca99899599b..1e045ff534ee065694031aa3623b7b09b9e7427e 100644 --- a/MAC/APL/PIC/TBB_Driver/CMakeLists.txt +++ b/MAC/APL/PIC/TBB_Driver/CMakeLists.txt @@ -1,7 +1,7 @@ # $Id$ # Do not split the following line, otherwise makeversion will fail! -lofar_package(TBB_Driver 1.0 DEPENDS Common TestSuite GCFTM MACIO RTCCommon TBB_Protocol) +lofar_package(TBB_Driver 1.0 DEPENDS Common TestSuite GCFTM MACIO RTCCommon TBB_Protocol RSP_Protocol) include(LofarFindPackage) lofar_find_package(Boost REQUIRED) diff --git a/MAC/APL/PIC/TBB_Driver/src/CMakeLists.txt b/MAC/APL/PIC/TBB_Driver/src/CMakeLists.txt index d8788eddb94e2ba3b4d10cb22570e994ddc3d9b4..dd419dcd8cce886f8cbcff9c6c168026c2157ee9 100644 --- a/MAC/APL/PIC/TBB_Driver/src/CMakeLists.txt +++ b/MAC/APL/PIC/TBB_Driver/src/CMakeLists.txt @@ -20,11 +20,13 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) lofar_add_library(tp_protocol TP_Protocol.cc RawEvent.cc) + +add_dependencies(tp_protocol TBB_Driver-TP_Protocol) lofar_add_library(tbbdriver Package__Version.cc - TP_Protocol.ph DriverSettings.cc + TP_Protocol.ph Command.cc AllocCmd.cc BoardCmdHandler.cc diff --git a/MAC/APL/PIC/TBB_Driver/src/ClearCmd.cc b/MAC/APL/PIC/TBB_Driver/src/ClearCmd.cc index 73d5203cd3d55eafdf82fa4418da04a813c12a23..2292b838751c39d62126902fe8a2c91584d1afbf 100644 --- a/MAC/APL/PIC/TBB_Driver/src/ClearCmd.cc +++ b/MAC/APL/PIC/TBB_Driver/src/ClearCmd.cc @@ -89,7 +89,7 @@ void ClearCmd::saveTpAckEvent(GCFEvent& event) } else { // reset channel-information for selected board TS->clearRcuSettings(getBoardNr()); - TS->setBoardState(getBoardNr(),boardCleared); + TS->setBoardState(getBoardNr(), boardCleared); } } nextBoardNr(); diff --git a/MAC/APL/PIC/TBB_Driver/src/DriverSettings.cc b/MAC/APL/PIC/TBB_Driver/src/DriverSettings.cc index 82e8ee47ad68baf06eee6ca1c2546a74c3ecc369..adb1eed541892455f566e05ff1d227ed42fb3e7d 100644 --- a/MAC/APL/PIC/TBB_Driver/src/DriverSettings.cc +++ b/MAC/APL/PIC/TBB_Driver/src/DriverSettings.cc @@ -82,9 +82,8 @@ TbbSettings::TbbSettings() : itsActiveBoardsMask(0), // mask with active boards itsBoardInfo(0), itsChannelInfo(0), // Struct with channel info - itsClockFreq(200), + itsClockFreq(0), itsSampleTime(5.0), - itsBoardSetup(false), itsIfName(""), itsSetupNeeded(false), itsTriggerInfo(0) @@ -236,8 +235,6 @@ void TbbSettings::setMaxBoards (int32 maxboards) itsChannelInfo[ch].dstMacCep.clear(); } - itsBoardSetup = false; - if (itsBoardInfo) delete itsBoardInfo; itsBoardInfo = new BoardInfo[itsMaxBoards]; @@ -264,7 +261,6 @@ 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 2b1fabe80171d9ff8e35d9118b04c8c8aba15d88..0113b109a6347d7daeb68ab7cce936c55126130b 100644 --- a/MAC/APL/PIC/TBB_Driver/src/DriverSettings.h +++ b/MAC/APL/PIC/TBB_Driver/src/DriverSettings.h @@ -24,13 +24,14 @@ #define LOFAR_RSP_STATIONSETTINGS_H #include <APL/TBB_Protocol/TBB_Protocol.ph> -#include "TP_Protocol.ph" #include <GCF/TM/GCF_Control.h> #include <Common/LofarLogger.h> #include <Common/LofarTypes.h> +#include <Common/StringUtil.h> #include <time.h> #include <APL/RTCCommon/NsTimestamp.h> +#include "TP_Protocol.ph" namespace LOFAR { using GCF::TM::GCFPortInterface; @@ -195,8 +196,8 @@ public: bool isSetupCmdDone(int32 boardnr); void setSetupCmdDone(int32 boardnr, bool state); - bool boardSetupNeeded(); - void clearBoardSetup(); + //bool boardSetupNeeded(); + //void clearBoardSetup(); void setActiveBoardsMask (uint32 activeboardsmask); void setActiveBoard (int32 boardnr); void resetActiveBoard (int32 boardnr); @@ -224,6 +225,7 @@ public: void setClockFreq(int32 clock); int32 getClockFreq(); + bool isClockFreqChanged(); double getSampleTime(); void clearRcuSettings(int32 boardnr); @@ -297,9 +299,9 @@ private: ChannelInfo *itsChannelInfo; uint32 itsClockFreq; // freq in MHz + bool itsClockChanged; double itsSampleTime; // sample time in nsec - bool itsBoardSetup; string itsIfName; bool itsSetupNeeded; TriggerInfo *itsTriggerInfo; @@ -324,8 +326,6 @@ inline int32 TbbSettings::maxRetries() { return (itsMaxRetries); } inline double TbbSettings::timeout() { return (itsTimeOut); } inline GCFPortInterface& TbbSettings::boardPort(int32 boardnr) { return (*itsBoardInfo[boardnr].port); } inline BoardStateT TbbSettings::getBoardState(int32 boardnr) { return (itsBoardInfo[boardnr].boardState); } -inline bool TbbSettings::boardSetupNeeded() { return (itsBoardSetup); } -inline void TbbSettings::clearBoardSetup() { itsBoardSetup = false; } inline int32 TbbSettings::getSetupWaitTime(int32 boardnr) { if (time(NULL) >= itsBoardInfo[boardnr].setupWaitTime) { return(0); } @@ -390,14 +390,14 @@ inline void TbbSettings::resetTriggersLeft() { int missed = 0; for (int bnr = 0; bnr < itsMaxBoards; bnr++) { if (itsBoardInfo[bnr].triggersLeft < 0) { - missed += itsBoardInfo[bnr].triggersLeft; - LOG_DEBUG_STR(formatString("missed %d triggers on board %d", + missed += (itsBoardInfo[bnr].triggersLeft * -1); + LOG_DEBUG_STR(formatString("missed %d triggers on board %d last 100mSec", (itsBoardInfo[bnr].triggersLeft*-1), bnr)); } itsBoardInfo[bnr].triggersLeft = itsMaxTriggersPerInterval; } if (missed != 0) { - LOG_INFO_STR(formatString("missed %d triggers", (missed*-1))); + LOG_INFO_STR(formatString("missed %d triggers last 100mSec", (missed))); } } inline bool TbbSettings::isTriggersLeft(int32 boardnr) { @@ -491,10 +491,18 @@ inline void TbbSettings::resetBoardUsed() { inline void TbbSettings::setSetupNeeded(bool state) { itsSetupNeeded = state; } inline bool TbbSettings::isSetupNeeded() { return(itsSetupNeeded); } inline void TbbSettings::setClockFreq(int32 clock) { + itsClockChanged = true; itsClockFreq = clock; // sample clock freq in Mhz itsSampleTime = 1000./clock; // sample time = 1/clock in nsec } inline int32 TbbSettings::getClockFreq() { return(itsClockFreq); } +inline bool TbbSettings::isClockFreqChanged() { + if (itsClockChanged) { + itsClockChanged = false; + return(true); + } + return(false); + } inline double TbbSettings::getSampleTime() { return(itsSampleTime); } } // namespace TBB diff --git a/MAC/APL/PIC/TBB_Driver/src/MsgHandler.cc b/MAC/APL/PIC/TBB_Driver/src/MsgHandler.cc index 83d16aaceb71ce8ee9b824357ffb7279326b93e3..c273f1010b0635f71d0eb2a2b024a2369ee6544f 100644 --- a/MAC/APL/PIC/TBB_Driver/src/MsgHandler.cc +++ b/MAC/APL/PIC/TBB_Driver/src/MsgHandler.cc @@ -75,50 +75,21 @@ void MsgHandler::removeHardwareClient(GCFPortInterface& port) itsClientHardwareMsgList.remove(&port); // remove client from list } - -//----------------------------------------------------------------------------- -void MsgHandler::sendTrigger(GCFEvent& event, int boardnr) -{ - TPTriggerEvent tp_event(event); - TBBTriggerEvent tbb_event; - - int channel = tp_event.trigger.channel + (boardnr * TS->nrChannelsOnBoard()); - TS->convertCh2Rcu(channel, &tbb_event.rcu); - uint32 t_sec = tp_event.trigger.time; - uint32 t_nsec = (uint32)((double)tp_event.trigger.sample_nr * TS->getSampleTime()); - RTC::NsTimestamp nstimestamp(t_sec, t_nsec); - tbb_event.nstimestamp = nstimestamp; - tbb_event.trigger_sum = tp_event.trigger.sum; - tbb_event.trigger_samples = tp_event.trigger.samples; - tbb_event.peak_value = tp_event.trigger.peak; - tbb_event.power_before = tp_event.trigger.pwr_bt_at & 0x0000FFFF; - tbb_event.power_after = (tp_event.trigger.pwr_bt_at & 0xFFFF0000) >> 16; - tbb_event.missed = tp_event.trigger.missed & 0x0000FFFF; - - sendTriggerMessage(tbb_event); - - // save trigger messages to a file - if (TS->saveTriggersToFile()) { - //LOG_DEBUG_STR(formatString("write saved trigger from board %d to file", boardnr)); - writeTriggerToFile(&tbb_event); - } - TS->setChTriggered(channel, true); -} - //----------------------------------------------------------------------------- void MsgHandler::sendSavedTrigger() { //LOG_DEBUG_STR(formatString("send saved trigger from board %d to client", boardnr)); TBBTriggerEvent tbb_event; + TriggerInfo *triggerInfo = TS->getTriggerInfo(); - tbb_event.rcu = TS->getTriggerInfo()->rcu; - tbb_event.nstimestamp = TS->getTriggerInfo()->ns_timestamp; - tbb_event.trigger_sum = TS->getTriggerInfo()->trigger_sum; - tbb_event.trigger_samples = TS->getTriggerInfo()->trigger_samples; - tbb_event.peak_value = TS->getTriggerInfo()->peak_value; - tbb_event.power_before = TS->getTriggerInfo()->power_before; - tbb_event.power_after = TS->getTriggerInfo()->power_after; - tbb_event.missed = TS->getTriggerInfo()->missed & 0x00FFFFFF; + tbb_event.rcu = triggerInfo->rcu; + tbb_event.nstimestamp = triggerInfo->ns_timestamp; + tbb_event.trigger_sum = triggerInfo->trigger_sum; + tbb_event.trigger_samples = triggerInfo->trigger_samples; + tbb_event.peak_value = triggerInfo->peak_value; + tbb_event.power_before = triggerInfo->power_before; + tbb_event.power_after = triggerInfo->power_after; + tbb_event.missed = triggerInfo->missed & 0x00FFFFFF; sendTriggerMessage(tbb_event); diff --git a/MAC/APL/PIC/TBB_Driver/src/ReadCmd.cc b/MAC/APL/PIC/TBB_Driver/src/ReadCmd.cc index 4d2db97b7196e658bb5e17bb74a55bb7ab5b512b..41e447ba9e2b5fc64ea87a1590a03da5da76855c 100644 --- a/MAC/APL/PIC/TBB_Driver/src/ReadCmd.cc +++ b/MAC/APL/PIC/TBB_Driver/src/ReadCmd.cc @@ -181,6 +181,11 @@ void ReadCmd::sendTpEvent() TS->boardPort(getBoardNr()).send(tp_event); TS->setBoardUsed(getBoardNr()); TS->boardPort(getBoardNr()).setTimer(TS->timeout()); + LOG_INFO_STR(formatString("DATA->>CEP rcu %d : time=%lf timebefore=%lf timeafter=%lf", + TS->convertChanToRcu(getChannelNr()), + (double)itsTimestamp, + (double)itsTimeBefore, + (double)itsTimeAfter)); } break; } } @@ -233,6 +238,11 @@ void ReadCmd::saveTpAckEvent(GCFEvent& event) LOG_DEBUG_STR(formatString("startTimestamp = %lu seconds %lu nseconds", startTimestamp.sec(), startTimestamp.nsec())); LOG_DEBUG_STR(formatString("stopTimestamp = %lu seconds %lu nseconds", stopTimestamp.sec(), stopTimestamp.nsec())); #endif + + // to get last part of recording + if (itsTimestamp == 0.0) { + itsTimestamp = lastSampleTime; + } // check if center time in memory if ((itsTimestamp >= firstSampleTime) && (itsTimestamp <= lastSampleTime)) { @@ -256,7 +266,10 @@ void ReadCmd::saveTpAckEvent(GCFEvent& event) LOG_WARN_STR(formatString("requested time = %lf, in memory [%lf .. %lf]", (double)itsTimestamp, (double)firstSampleTime, (double)lastSampleTime)); setDone(true); } - + + itsTimeBefore = itsTimestamp - startTimestamp; + itsTimeAfter = stopTimestamp - itsTimestamp; + // convert it to board units itsSecondstime = (uint32)itsTimestamp.sec(); @@ -300,12 +313,15 @@ void ReadCmd::saveTpAckEvent(GCFEvent& event) LOG_INFO_STR(" page-offset :" << tp_ack.page_offset); */ if (tp_ack.status == 0xfd) { - LOG_DEBUG_STR(formatString("TBB busy, %d pages left, trying until free", tp_ack.pages_left)); + LOG_INFO_STR(formatString("TBB busy, %d pages left", tp_ack.pages_left)); + usleep(1000); // wait for some time and try again } - if (tp_ack.status != 0) { - setStatus(0, (tp_ack.status << 24)); + else { + if (tp_ack.status != 0) { + setStatus(0, (tp_ack.status << 24)); + } + setDone(true); } - setDone(true); } } diff --git a/MAC/APL/PIC/TBB_Driver/src/TBBDriver.cc b/MAC/APL/PIC/TBB_Driver/src/TBBDriver.cc index b839c449f4a87be5f5653ec5f1a10dbcbca1ad14..aee4ef06f8a8e04ef8e2c4bceae508aceaa2b20c 100644 --- a/MAC/APL/PIC/TBB_Driver/src/TBBDriver.cc +++ b/MAC/APL/PIC/TBB_Driver/src/TBBDriver.cc @@ -32,6 +32,8 @@ #include <getopt.h> #include <string> + + #include "TBBDriver.h" #include "RawEvent.h" @@ -80,6 +82,7 @@ using namespace LOFAR; using namespace GCF::TM; using namespace MACIO; using namespace TBB; +using namespace std; static bool itsDaemonize = false; static int32 itsInstancenr = -1; @@ -126,6 +129,7 @@ void parseOptions(int argc, char** argv) TBBDriver::TBBDriver(string name) : GCFTask((State)&TBBDriver::init_state, name) { + sleep(5); // use TS->getXXX() tot get settings of the driver TS = TbbSettings::instance(); @@ -136,12 +140,14 @@ TBBDriver::TBBDriver(string name) //itsNewBoards = 0; itsAliveCheck = false; itsResetCount = 0; + itsClockSubscription = 0; // tell broker we are here LOG_DEBUG_STR("Registering protocols"); - registerProtocol (TBB_PROTOCOL, TBB_PROTOCOL_STRINGS); - registerProtocol (TP_PROTOCOL, TP_PROTOCOL_STRINGS); + registerProtocol (TBB_PROTOCOL, TBB_PROTOCOL_STRINGS); + registerProtocol (TP_PROTOCOL, TP_PROTOCOL_STRINGS); + registerProtocol (RSP_PROTOCOL, RSP_PROTOCOL_STRINGS); // open client port LOG_DEBUG_STR("Opening listener for clients"); @@ -178,12 +184,16 @@ TBBDriver::TBBDriver(string name) TS->setActiveBoardsMask(0); + // prepare TCP port to RSPDriver. + itsRSPDriver = new GCFTCPPort(*this, MAC_SVCMASK_RSPDRIVER, GCFPortInterface::SAP, RSP_PROTOCOL); + ASSERTSTR(itsRSPDriver, "Cannot allocate TCPport to RSPDriver"); + itsAliveTimer = new GCFTimerPort(*this, "AliveTimer"); itsSetupTimer = new GCFTimerPort(*this, "SetupTimer"); itsCmdTimer = new GCFTimerPort(*this, "CmdTimer"); itsQueueTimer = new GCFTimerPort(*this, "QueueTimer"); itsTriggerTimer = new GCFTimerPort(*this, "TriggerTimer"); - + // create cmd & msg handler LOG_DEBUG_STR("initializing handlers"); itsCmdHandler = new BoardCmdHandler(itsCmdTimer); @@ -196,12 +206,15 @@ TBBDriver::TBBDriver(string name) LOG_DEBUG_STR("initializing TbbQueue"); itsTbbQueue = new deque<TbbEvent*>(100); itsTbbQueue->clear(); + LOG_INFO_STR("class init done"); } //----------------------------------------------------------------------------- TBBDriver::~TBBDriver() -{ +{ + cancelClockSubscription(); delete [] itsBoard; + delete itsRSPDriver; delete itsAliveTimer; delete itsSetupTimer; delete itsCmdTimer; @@ -225,6 +238,9 @@ GCFEvent::TResult TBBDriver::init_state(GCFEvent& event, GCFPortInterface& port) if (itsAcceptor.isConnected()) { itsAcceptor.close(); } + if (itsRSPDriver->isConnected()) { + itsRSPDriver->close(); + } } break; case F_EXIT: { @@ -236,44 +252,58 @@ GCFEvent::TResult TBBDriver::init_state(GCFEvent& event, GCFPortInterface& port) case F_CONNECTED: { LOG_DEBUG_STR("CONNECTED: port " << port.getName()); - + if (&port == &itsAcceptor) { if (itsAcceptor.isConnected()) { - openBoards(); + itsRSPDriver->open(); + } + } + else if (&port == itsRSPDriver) { + if (itsRSPDriver->isConnected()) { + openBoards(); } } - else { + else { if (boardsConnected()) { - // send watchdog = clk, so the boards will be reset by clock change - setWatchdogMode(TP_WATCHDOG_CLK); - // RSP set clock 22 seconds afther start - // reconfig takes 8 seconds - // so wait 30 seconds - // wait 2 seconds for TP_WATCHDOG_ACK's - itsAliveTimer->setTimer(2.0); + // take subscription on clock changes + itsAliveTimer->setTimer(0.0); } } + } break; case F_DATAIN: { status = RawEvent::dispatch(*this, port); } break; - - case TP_WATCHDOG_ACK: { - LOG_DEBUG_STR ("received watchdog ack in init state @ :" << port.getName()); - // do nothing - } break; case F_TIMER: { if (&port == itsAliveTimer) { - // start trigger reset timer - itsTriggerTimer->setTimer(90.0, 1.0); // first start over 60 seconds, then every 1 Sec - // shedule an alive command and go to idle state - itsAliveTimer->setTimer(30.0); - TRAN(TBBDriver::idle_state); + requestClockSubscription(); } } break; + case RSP_SUBCLOCKACK: { + RSPSubclockackEvent ack(event); + if (ack.status != RSP_SUCCESS) { + LOG_WARN ("Could not get subscription on clock, retry in 2 seconds."); + //itsOwnPropertySet->setValue(PN_FSM_ERROR, GCFPVString("subscribe failed")); + itsAliveTimer->setTimer(2.0); + break; + } + itsClockSubscription = ack.handle; + LOG_INFO("Subscription on the clock successful. going to operational mode"); + //itsOwnPropertySet->setValue(PN_CLC_ACTUAL_CLOCK,GCFPVInteger(itsClock)); + + // start trigger reset timer + itsTriggerTimer->setTimer(90.0, 0.1); // first start over 90 seconds, then every 0.1 Sec + itsAliveTimer->setTimer(45.0); + TRAN(TBBDriver::idle_state); + } break; + + case RSP_UPDCLOCK: { + setClockState(event); + } break; + default: { if (addTbbCommandToQueue(event, port)) { LOG_DEBUG_STR("init_state: received TBB cmd, and put on queue"); @@ -353,49 +383,8 @@ GCFEvent::TResult TBBDriver::setup_state(GCFEvent& event, GCFPortInterface& port continue; } - if ((TS->getBoardState(board) == setWatchdog) || - (TS->getBoardState(board) == boardCleared)) {//|| - //(TS->getBoardState(board) == image1Set)) { - - TPWatchdogEvent watchdog; - watchdog.opcode = oc_WATCHDOG; - watchdog.status = 0; - //watchdog.mode = TP_WATCHDOG_ETH; // watchdog is set to eth port - watchdog.mode = TP_WATCHDOG_CLK; // watchdog is set to clock - itsBoard[board].send(watchdog); - itsBoard[board].setTimer(TS->timeout()); - if (watchdog.mode == TP_WATCHDOG_ETH) { - LOG_INFO_STR("WATCHDOG = ETH is send to port '" << itsBoard[board].getName() << "'"); - } - else { - LOG_INFO_STR("WATCHDOG = CLK is send to port '" << itsBoard[board].getName() << "'"); - } - TS->setSetupCmdDone(board, false); - continue; - } - - if ((TS->getBoardState(board) == setArp) || - (TS->getBoardState(board) == statusChecked) || - (TS->getBoardState(board) == watchdogSet)) { - - TPArpModeEvent arp; - arp.opcode = oc_ARPMODE; - arp.status = 0; - //arp.mode=1; // set arp mode to auto - arp.mode=TP_ARP_DISABLE; // set arp mode to disabled - itsBoard[board].send(arp); - itsBoard[board].setTimer(TS->timeout()); - if (arp.mode == TP_ARP_DISABLE) { - LOG_INFO_STR("ARP = OFF is send to port '" << itsBoard[board].getName() << "'"); - } - else { - LOG_INFO_STR("ARP = AUTO is send to port '" << itsBoard[board].getName() << "'"); - } - TS->setSetupCmdDone(board, false); - continue; - } - if ((TS->getBoardState(board) == freeBoard) || + (TS->getBoardState(board) == statusChecked) || (TS->getBoardState(board) == arpSet)) { TPFreeEvent free; @@ -419,9 +408,14 @@ GCFEvent::TResult TBBDriver::setup_state(GCFEvent& event, GCFPortInterface& port port.close(); if (&port == &itsAcceptor) { - LOG_FATAL_STR("Failed to start listening for client connections."); + LOG_FATAL_STR("Client port closed."); + exit(EXIT_FAILURE); + } + else if (&port == itsRSPDriver) { + port.close(); + LOG_FATAL_STR("RSPDriver port closed."); exit(EXIT_FAILURE); - } + } else { itsClientList.remove(&port); itsMsgHandler->removeTriggerClient(port); @@ -487,28 +481,7 @@ GCFEvent::TResult TBBDriver::setup_state(GCFEvent& event, GCFPortInterface& port TS->setSetupCmdDone(board, true); } break; - case TP_WATCHDOG_ACK: { - int board = TS->port2Board(&port); // get board nr - itsBoard[board].cancelAllTimers(); - TPWatchdogAckEvent ack(event); - LOG_INFO_STR(formatString("Received WatchdogAck from boardnr[%d], status=%d", board, ack.status)); - if (ack.status == TBB_SUCCESS) { - TS->setBoardState(board, watchdogSet); - } - TS->setSetupCmdDone(board, true); - } break; - - case TP_ARP_MODE_ACK: { - int board = TS->port2Board(&port); // get board nr - itsBoard[board].cancelAllTimers(); - TPArpAckEvent ack(event); - LOG_INFO_STR(formatString("Received ArpAck from boardnr[%d], status=%d", board, ack.status)); - if (ack.status == TBB_SUCCESS) { - TS->setBoardState(board,arpSet); - } - TS->setSetupCmdDone(board, true); - } break; - + case TP_FREE_ACK: { int board = TS->port2Board(&port); // get board nr itsBoard[board].cancelAllTimers(); @@ -526,17 +499,17 @@ GCFEvent::TResult TBBDriver::setup_state(GCFEvent& event, GCFPortInterface& port TPStatusAckEvent ack(event); if (ack.status == TBB_SUCCESS) { // bit 0: // 0=image-0, 1=user-image - // bit 1..2: 00=by-power, 01=by-user, 10=by watchdog, 11=by-reset-button - TS->setFlashState(board, ((ack.info[5] >> 11) & 0x0007)); + // bit 1..2: 00=by-power, 01=by-user, 10=by watchdog, 11=by-reset-button + TS->setFlashState(board, ((ack.info[5] >> 11) & 0x0007)); if (TS->getConfigState(board) != 1) { // config not done by user TS->setImageNr(board, 0); LOG_WARN_STR("Image 1 NOT loaded"); - TS->setBoardState(board,setImage1); + TS->setBoardState(board, setImage1); } else { - TS->setBoardState(board,statusChecked); + TS->setBoardState(board, statusChecked); } - + LOG_INFO_STR(formatString("Received StatusAck from boardnr[%d], status=%d, imagenr=%d, configState=%d", board, ack.status, TS->getImageNr(board), TS->getConfigState(board))); } @@ -554,17 +527,16 @@ GCFEvent::TResult TBBDriver::setup_state(GCFEvent& event, GCFPortInterface& port } TS->setSetupCmdDone(board, true); } break; - - // tp_trigger message is handled in raw event + + case TP_TRIGGER: { - for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) { - if (&port == &TS->boardPort(boardnr)) { - itsMsgHandler->sendTrigger(event, boardnr); - break; - } - } + // tp_trigger message is handled in raw event } break; + case RSP_UPDCLOCK: { + setClockState(event); + } break; + default: { if (addTbbCommandToQueue(event, port)) { LOG_DEBUG_STR("setup_state: received TBB cmd, and put on queue"); @@ -619,10 +591,12 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port) } break; case F_ENTRY: { - // Setup needed can be set by reset or clear cmd - if ((TS->isSetupNeeded() && !itsAliveCheck)) { - itsAliveTimer->cancelAllTimers(); - itsAliveTimer->setTimer(0.0); + // Setup needed can be set by reset, clear cmd or clock change + if (TS->isSetupNeeded()) { + TS->setSetupNeeded(false); + itsAliveCheck = false; + itsAliveTimer->cancelAllTimers(); + itsAliveTimer->setTimer(1.0); } LOG_DEBUG_STR("Entering idle_state"); @@ -655,9 +629,15 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port) port.close(); if (&port == &itsAcceptor) { - LOG_FATAL_STR("Failed to start listening for client connections."); + LOG_FATAL_STR("Client port closed."); exit(EXIT_FAILURE); - } else { + } + else if (&port == itsRSPDriver) { + port.close(); + LOG_FATAL_STR("RSPDriver port closed."); + exit(EXIT_FAILURE); + } + else { itsClientList.remove(&port); itsMsgHandler->removeTriggerClient(port); itsMsgHandler->removeHardwareClient(port); @@ -726,22 +706,13 @@ GCFEvent::TResult TBBDriver::idle_state(GCFEvent& event, GCFPortInterface& port) port.send(unsubscribeack); } break; - case TBB_CLOCK: { - TBBClockEvent clockevent(event); - TS->setClockFreq(clockevent.clock); - TBBClockAckEvent clockack; - clockack.status_mask = 0; - port.send(clockack); + case RSP_UPDCLOCK: { + setClockState(event); } break; - // tp_trigger message is handled in raw event + case TP_TRIGGER: { - for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) { - if (&port == &TS->boardPort(boardnr)) { - itsMsgHandler->sendTrigger(event, boardnr); - break; - } - } + // tp_trigger message is handled in raw event } break; case TP_ERROR: { @@ -820,9 +791,14 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port) LOG_DEBUG_STR("DISCONNECTED: port '" << port.getName() << "'"); if (&port == &itsAcceptor) { port.close(); - LOG_FATAL_STR("Failed to start listening for client connections."); + LOG_FATAL_STR("Client port closed."); exit(EXIT_FAILURE); - } + } + else if (&port == itsRSPDriver) { + port.close(); + LOG_FATAL_STR("RSPDriver port closed."); + exit(EXIT_FAILURE); + } else { port.close(); itsClientList.remove(&port); @@ -899,14 +875,8 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port) status = itsCmdHandler->doEvent(event,port); } break; - // tp_trigger message is handled in raw event case TP_TRIGGER: { - for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) { - if (&port == &TS->boardPort(boardnr)) { - itsMsgHandler->sendTrigger(event, boardnr); - break; - } - } + // tp_trigger message is handled in raw event } break; case TP_ERROR: { @@ -953,7 +923,11 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port) { status = itsCmdHandler->doEvent(event,port); // dispatch ack from boards } break; - + + case RSP_UPDCLOCK: { + setClockState(event); + } break; + default: { if (addTbbCommandToQueue(event, port)) { LOG_DEBUG_STR("busy_state: received TBB cmd, and put on queue"); @@ -965,24 +939,6 @@ GCFEvent::TResult TBBDriver::busy_state(GCFEvent& event, GCFPortInterface& port) return(status); } -//----------------------------------------------------------------------------- -// setWatchdogToETH() -// mode=0 --> clock -// mode=1 --> eth -void TBBDriver::setWatchdogMode(int mode) -{ - LOG_DEBUG_STR(formatString("set watchdog=%s for all boards", mode?"ETH":"CLOCK")); - TPWatchdogEvent watchdog; - watchdog.opcode = oc_WATCHDOG; - watchdog.status = 0; - watchdog.mode = mode; - - for (int boardnr = 0; boardnr < TS->maxBoards(); boardnr++) { - if (itsBoard[boardnr].isConnected()) - itsBoard[boardnr].send(watchdog); - } -} - //----------------------------------------------------------------------------- // openBoards() // @@ -1095,7 +1051,7 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port) // new image loaded, auto reconfigure is now possible again TS->setFreeToReset(boardnr, true); if (TS->getImageNr(boardnr) != 0) { - TS->setBoardState(boardnr,setWatchdog); + TS->setBoardState(boardnr, freeBoard); } } boardreset = true; @@ -1177,6 +1133,43 @@ bool TBBDriver::CheckAlive(GCFEvent& event, GCFPortInterface& port) return(!itsAliveCheck); } +//----------------------------------------------------------------------------- +void TBBDriver::setClockState(GCFEvent& event) +{ + /* + After a clock change the TB Boards are in a unknown state, a clear is needed to solve this. + First clock change event is received, after that the clock is changed by the RSPDriver. + + changing clock will take about 25 seconds, so wait first before clearing the boards + */ + + RSPUpdclockEvent e(event); + if (e.status != RSP_SUCCESS) { + LOG_WARN ("Received and INVALID clock update, WHAT IS THE CLOCK?"); + return; + } + + if (TS->getClockFreq() == 0) { // my clock still uninitialized? + LOG_INFO_STR("My clock is still not initialized. StationClock is " << e.clock << " adopting this value"); + TS->setClockFreq((int32)e.clock); + } + + else if ((int32)e.clock != TS->getClockFreq()) { + LOG_WARN_STR ("CLOCK WAS CHANGED TO " << e.clock << "MHz, RESET NEEDED (wait 80 secs for done)"); + for (int bnr = 0; bnr < TS->maxBoards(); bnr++) { + TS->setBoardState(bnr, setImage1); + } + TS->setClockFreq((int32)e.clock); + + itsSetupTimer->cancelAllTimers(); + itsSetupTimer->setTimer(60.0, 1.0); + + itsAliveCheck = false; + itsAliveTimer->cancelAllTimers(); + itsAliveTimer->setTimer(90.0); + } +} + //----------------------------------------------------------------------------- bool TBBDriver::sendInfo(GCFEvent& event, GCFPortInterface& port) { @@ -1616,6 +1609,32 @@ bool TBBDriver::SetTbbCommand(unsigned short signal) return (true); } +// +// requestClockSubscription() +// +void TBBDriver::requestClockSubscription() +{ + LOG_INFO ("Taking subscription on clock settings"); + + RSPSubclockEvent msg; +// msg.timestamp = 0; + msg.period = 1; // let RSPdriver check every second + itsRSPDriver->send(msg); +} + +// +// cancelClockSubscription() +// +void TBBDriver::cancelClockSubscription() +{ + LOG_INFO ("Canceling subscription on clock settings"); + + RSPUnsubclockEvent msg; + msg.handle = itsClockSubscription; + itsClockSubscription = 0; + itsRSPDriver->send(msg); +} + //} // end namespace TBB //} // end namespace LOFAR @@ -1626,7 +1645,7 @@ 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 + 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/TBBDriver.h b/MAC/APL/PIC/TBB_Driver/src/TBBDriver.h index 309bad530913302d50777c2eb972a7ebda50f9b8..ed4efe7ea214a0e73f5264b74065b861f5523669 100644 --- a/MAC/APL/PIC/TBB_Driver/src/TBBDriver.h +++ b/MAC/APL/PIC/TBB_Driver/src/TBBDriver.h @@ -23,9 +23,6 @@ #ifndef LOFAR_TBBDRIVER_TBBDRIVER_H #define LOFAR_TBBDRIVER_TBBDRIVER_H -#include <APL/TBB_Protocol/TBB_Protocol.ph> -#include "TP_Protocol.ph" - #include <GCF/TM/GCF_Control.h> #include <GCF/TM/GCF_ETHRawPort.h> #include <GCF/TM/GCF_DevicePort.h> @@ -33,6 +30,10 @@ #include <Common/lofar_deque.h> +#include <APL/RSP_Protocol/RSP_Protocol.ph> +#include <APL/TBB_Protocol/TBB_Protocol.ph> +#include "TP_Protocol.ph" + #include "BoardCmdHandler.h" #include "MsgHandler.h" #include "DriverSettings.h" @@ -62,8 +63,6 @@ public: // int32 portToBoardNr(GCFPortInterface& port); - void setWatchdogMode(int mode); - // open all board ports void openBoards(); @@ -105,11 +104,14 @@ private: void sendMessage(GCFEvent& event); bool CheckAlive(GCFEvent& event, GCFPortInterface& port); bool CheckSize(GCFEvent& event, GCFPortInterface& port); + void setClockState(GCFEvent& event); bool sendInfo(GCFEvent& event, GCFPortInterface& port); bool addTbbCommandToQueue(GCFEvent& event, GCFPortInterface& port); bool handleTbbCommandFromQueue(); bool SetTbbCommand(unsigned short signal); - + void requestClockSubscription(); + void cancelClockSubscription(); + TbbSettings *TS; // define some variables @@ -121,6 +123,7 @@ private: uint32 itsNewBoards; bool itsActiveBoardsChange; int32 *itsResetCount; + void* itsClockSubscription; struct TbbEvent{ GCFPortInterface *port; @@ -131,6 +134,7 @@ private: GCFTCPPort itsAcceptor; // listen for clients on this port GCFETHRawPort* itsBoard; // array of ports, one for each TBB board + GCFTCPPort* itsRSPDriver; // port for clock subscription GCFTimerPort* itsAliveTimer; // used to check precence and reset of the boards GCFTimerPort* itsSetupTimer; // used in the setup state GCFTimerPort* itsCmdTimer; // used by CommandHandler diff --git a/MAC/APL/PIC/TBB_Driver/src/TrigSetupCmd.cc b/MAC/APL/PIC/TBB_Driver/src/TrigSetupCmd.cc index 50217b792db38d50a3a4a33f6bc1092fdb149dc7..5ff4c62fdec2376a8f8b5276b37be00bb9896c40 100644 --- a/MAC/APL/PIC/TBB_Driver/src/TrigSetupCmd.cc +++ b/MAC/APL/PIC/TBB_Driver/src/TrigSetupCmd.cc @@ -32,106 +32,106 @@ using namespace LOFAR; using namespace GCF::TM; using namespace TBB_Protocol; using namespace TP_Protocol; -using namespace TBB; +using namespace TBB; //--Constructors for a TrigSetupCmd object.---------------------------------------- TrigSetupCmd::TrigSetupCmd() { - TS = TbbSettings::instance(); - setWaitAck(true); + TS = TbbSettings::instance(); + setWaitAck(true); } - + //--Destructor for TrigSetupCmd.--------------------------------------------------- TrigSetupCmd::~TrigSetupCmd() { } // ---------------------------------------------------------------------------- bool TrigSetupCmd::isValid(GCFEvent& event) { - if ((event.signal == TBB_TRIG_SETUP)||(event.signal == TP_TRIG_SETUP_ACK)) { - return(true); - } - return(false); + if ((event.signal == TBB_TRIG_SETUP)||(event.signal == TP_TRIG_SETUP_ACK)) { + return(true); + } + return(false); } // ---------------------------------------------------------------------------- void TrigSetupCmd::saveTbbEvent(GCFEvent& event) { - TBBTrigSetupEvent tbb_event(event); - - int32 channel; // channel 0 .. 191 (= maxboard * max_channels_on_board) - for(int rcunr = 0; rcunr < TS->maxChannels(); rcunr++) { - channel = TS->convertRcuToChan(rcunr); - if ((tbb_event.rcu[rcunr].window > 2) && (tbb_event.rcu[rcunr].level > 80)){ - TS->setChTriggerLevel(channel, 80); - } - else { - TS->setChTriggerLevel(channel, static_cast<uint32>(tbb_event.rcu[rcunr].level)); - } - TS->setChTriggerStartMode(channel, static_cast<uint32>(tbb_event.rcu[rcunr].start_mode)); - TS->setChTriggerStopMode(channel, static_cast<uint32>(tbb_event.rcu[rcunr].stop_mode)); - TS->setChFilterSelect(channel, static_cast<uint32>(tbb_event.rcu[rcunr].filter_select)); - TS->setChDetectWindow(channel, static_cast<uint32>(tbb_event.rcu[rcunr].window)); - TS->setChTriggerMode(channel, static_cast<uint32>(tbb_event.rcu[rcunr].trigger_mode)); - TS->setChOperatingMode(channel, static_cast<uint32>(tbb_event.rcu[rcunr].operating_mode)); - } - - bitset<MAX_N_RCUS> channels; - channels.set(); - setChannels(channels); - - // select firt channel to handle - nextChannelNr(); + TBBTrigSetupEvent tbb_event(event); + + int32 channel; // channel 0 .. 191 (= maxboard * max_channels_on_board) + for(int rcunr = 0; rcunr < TS->maxChannels(); rcunr++) { + channel = TS->convertRcuToChan(rcunr); + if ((tbb_event.rcu[rcunr].window > 2) && (tbb_event.rcu[rcunr].level > 80)){ + TS->setChTriggerLevel(channel, 80); + } + else { + TS->setChTriggerLevel(channel, static_cast<uint32>(tbb_event.rcu[rcunr].level)); + } + TS->setChTriggerStartMode(channel, static_cast<uint32>(tbb_event.rcu[rcunr].start_mode)); + TS->setChTriggerStopMode(channel, static_cast<uint32>(tbb_event.rcu[rcunr].stop_mode)); + TS->setChFilterSelect(channel, static_cast<uint32>(tbb_event.rcu[rcunr].filter_select)); + TS->setChDetectWindow(channel, static_cast<uint32>(tbb_event.rcu[rcunr].window)); + TS->setChTriggerMode(channel, static_cast<uint32>(tbb_event.rcu[rcunr].trigger_mode)); + TS->setChOperatingMode(channel, static_cast<uint32>(tbb_event.rcu[rcunr].operating_mode)); + } + + bitset<MAX_N_RCUS> channels; + channels.set(); + setChannels(channels); + + // select firt channel to handle + nextChannelNr(); } // ---------------------------------------------------------------------------- void TrigSetupCmd::sendTpEvent() { - TPTrigSetupEvent tp_event; - tp_event.opcode = oc_TRIG_SETUP; - tp_event.status = 0; + TPTrigSetupEvent tp_event; + tp_event.opcode = oc_TRIG_SETUP; + tp_event.status = 0; - tp_event.mp = TS->getChMpNr(getChannelNr()); - for (int i = 0; i < 4; i++) { - tp_event.channel[i].level = TS->getChTriggerLevel(getChannelNr() + i); - tp_event.channel[i].td_mode = (TS->getChTriggerStartMode(getChannelNr() + i) + - (TS->getChTriggerStopMode(getChannelNr() + i) << 4)); - tp_event.channel[i].filter_select = TS->getChFilterSelect(getChannelNr() + i); - tp_event.channel[i].window = TS->getChDetectWindow(getChannelNr() + i); - tp_event.channel[i].trigger_mode = TS->getChTriggerMode(getChannelNr() + i); - } - - TS->boardPort(getBoardNr()).send(tp_event); - TS->setBoardUsed(getBoardNr()); - TS->boardPort(getBoardNr()).setTimer(TS->timeout()); + tp_event.mp = TS->getChMpNr(getChannelNr()); + for (int i = 0; i < 4; i++) { + tp_event.channel[i].level = TS->getChTriggerLevel(getChannelNr() + i); + tp_event.channel[i].td_mode =(TS->getChTriggerStartMode(getChannelNr() + i) + + (TS->getChTriggerStopMode(getChannelNr() + i) << 4)); + tp_event.channel[i].filter_select = TS->getChFilterSelect(getChannelNr() + i); + tp_event.channel[i].window = TS->getChDetectWindow(getChannelNr() + i); + tp_event.channel[i].trigger_mode = TS->getChTriggerMode(getChannelNr() + i); + } + + TS->boardPort(getBoardNr()).send(tp_event); + TS->setBoardUsed(getBoardNr()); + TS->boardPort(getBoardNr()).setTimer(TS->timeout()); } // ---------------------------------------------------------------------------- void TrigSetupCmd::saveTpAckEvent(GCFEvent& event) { - // in case of a time-out, set error mask - if (event.signal == F_TIMER) { - setStatus(getBoardNr(), TBB_TIME_OUT); - } else { - TPTrigSetupAckEvent tp_ack(event); - LOG_DEBUG_STR(formatString("Received TrigSetupAck from boardnr[%d]", getBoardNr())); - - if (tp_ack.status != 0) { - setStatus(getBoardNr(), (tp_ack.status << 24)); - } - } - // one mp done, go to next mp - setChannelNr(TS->getFirstChannelNr(getBoardNr(), TS->getChMpNr(getChannelNr())) + 3); - nextChannelNr(); + // in case of a time-out, set error mask + if (event.signal == F_TIMER) { + setStatus(getBoardNr(), TBB_TIME_OUT); + } else { + TPTrigSetupAckEvent tp_ack(event); + LOG_DEBUG_STR(formatString("Received TrigSetupAck from boardnr[%d]", getBoardNr())); + + if (tp_ack.status != 0) { + setStatus(getBoardNr(), (tp_ack.status << 24)); + } + } + // one mp done, go to next mp + setChannelNr(TS->getFirstChannelNr(getBoardNr(), TS->getChMpNr(getChannelNr())) + 3); + nextChannelNr(); } // ---------------------------------------------------------------------------- void TrigSetupCmd::sendTbbAckEvent(GCFPortInterface* clientport) { - TBBTrigSetupAckEvent tbb_ack; - - for (int32 i = 0; i < MAX_N_TBBOARDS; i++) { - tbb_ack.status_mask[i] = getStatus(i); - } - - if (clientport->isConnected()) { clientport->send(tbb_ack); } + TBBTrigSetupAckEvent tbb_ack; + + for (int32 i = 0; i < MAX_N_TBBOARDS; i++) { + tbb_ack.status_mask[i] = getStatus(i); + } + + if (clientport->isConnected()) { clientport->send(tbb_ack); } } diff --git a/MAC/APL/PIC/TBB_Protocol/src/TBB_Protocol.prot b/MAC/APL/PIC/TBB_Protocol/src/TBB_Protocol.prot index 30ab966d4ae03b41bcef85f994612b4457978b53..83e1ed8576007e31b3df74091145c2f9dd01caab 100644 --- a/MAC/APL/PIC/TBB_Protocol/src/TBB_Protocol.prot +++ b/MAC/APL/PIC/TBB_Protocol/src/TBB_Protocol.prot @@ -235,25 +235,6 @@ event = { }; }; -// set used clockfreq -event = { - signal = CLOCK; - dir = IN; - param = { - name = "clock"; - type = "int32"; - }; -}; - -event = { - signal = CLOCK_ACK; - dir = OUT; - param = { - name = "status_mask"; - type = "uint32"; - }; -}; - // data recording event = { signal = ALLOC; diff --git a/MAC/APL/StationCU/src/TBBControl/TBBControl.cc b/MAC/APL/StationCU/src/TBBControl/TBBControl.cc index dccdaccb18c92778e67f763d1879d531dfca5e8b..50ce71fe08b26ff1284ea7abdd4bd46325317280 100644 --- a/MAC/APL/StationCU/src/TBBControl/TBBControl.cc +++ b/MAC/APL/StationCU/src/TBBControl/TBBControl.cc @@ -138,6 +138,8 @@ TBBControl::TBBControl(const string& cntlrName) : itsMaxCepDatapaths = 1; itsActiveCepDatapaths = 0; itsCepDelay = 0; + itsAutoRecord = true; + itsVhecrTaskActive = true; //itsBoardCepActive.resize(itsNrTBBs, false); RcuInfo rcuinfo; @@ -673,7 +675,9 @@ GCFEvent::TResult TBBControl::active_state(GCFEvent& event, GCFPortInterface& po if (&port == itsVHECRtimer) { clock_t nexttime = clock() + (long)(VHECR_INTERVAL * CLOCKS_PER_SEC); vector<TBBReadCmd> readCommandVector; - itsVHECRTask->getReadCmd(readCommandVector); + if (itsVhecrTaskActive) { + itsVHECRTask->getReadCmd(readCommandVector); + } if (!readCommandVector.empty()) { readCmdToRequests(readCommandVector); @@ -725,7 +729,9 @@ GCFEvent::TResult TBBControl::active_state(GCFEvent& event, GCFPortInterface& po // -------------------- EVENTS RECEIVED FROM TBBDRIVER -------------------- // TODO TBB case TBB_TRIGGER:{ - status = handleTriggerEvent(event); + if (itsVhecrTaskActive) { + status = handleTriggerEvent(event); + } } break; case TBB_TRIG_RELEASE_ACK: { @@ -743,6 +749,7 @@ GCFEvent::TResult TBBControl::active_state(GCFEvent& event, GCFPortInterface& po cmdStatus = handleRecordAck(event); if (cmdStatus == SUCCESS) { sendRcuInfoCmd(); + itsVHECRtimer->setTimer(VHECR_INTERVAL); } } break; @@ -764,6 +771,7 @@ GCFEvent::TResult TBBControl::active_state(GCFEvent& event, GCFPortInterface& po int rcuNr; int boardNr; + double readTime = 0; vector<ReadRequest> requests(itsReadRequests); itsReadRequests.clear(); @@ -793,6 +801,9 @@ GCFEvent::TResult TBBControl::active_state(GCFEvent& event, GCFPortInterface& po } // send new read request + if (readTime == 0) { + readTime = (double)(request.timeBefore + request.timeAfter) * 4.0; + } request.readActive = true; sendReadCmd(request); itsReadRequests.push_back(request); // add request back to itsReadRequests @@ -801,13 +812,17 @@ GCFEvent::TResult TBBControl::active_state(GCFEvent& event, GCFPortInterface& po } if (itsActiveCepDatapaths > 0) { // dumping not ready - itsCepTimer->setTimer(0.01); + if (readTime == 0) { + readTime = 0.01; + } + itsCepTimer->setTimer(readTime); } else { - // all dumping done, set rcu's in recording state - sendRecordCmd(itsObs->allRCUset); - // start periodic timer to call VHECR task - itsVHECRtimer->setTimer(VHECR_INTERVAL); + if (itsAutoRecord) { + // all dumping done, set rcu's in recording state + usleep(500); // if pages left == 0, TBB can be busy sending last page + sendRecordCmd(itsObs->allRCUset); + } } } break; @@ -833,43 +848,53 @@ GCFEvent::TResult TBBControl::active_state(GCFEvent& event, GCFPortInterface& po // ------------ EVENTS RECEIVED FROM RTDB external trigger port ----------- case CR_STOP:{ // stop recording for selected rcu's on given time - CRStopEvent stopevent(event); + CRStopEvent e(event); + CRStopAckEvent ack; + + ack.triggerID = e.triggerID; + ack.result = CR_NO_ERR; + StopRequest stopRequest; vector<CRstopRequest>::iterator iter; - for (iter = stopevent.stopVector.requests.begin(); iter != stopevent.stopVector.requests.end(); iter++) { + for (iter = e.stopVector.requests.begin(); iter != e.stopVector.requests.end(); iter++) { // check if this station is in stationlist, if empty list select all string station_list(toUpper((*iter).stationList)); // empty station_list looks like "[]" if ((station_list.length() == 2) || (station_list.find(PVSSDatabaseName(""), 0) != string::npos)) { - LOG_DEBUG_STR("CR_Trig. Stop recording"); + LOG_INFO_STR("CR_Trig. Stop recording"); stopRequest.rcuSet = strToBitset((*iter).rcuList); stopRequest.stopTime = (*iter).stopTime; + itsStopRequests.push_back(stopRequest); - LOG_DEBUG_STR("CR_Trig. rcuSet=" << stopRequest.rcuSet); - LOG_DEBUG_STR("CR_Trig. stopTime=" << stopRequest.stopTime); + LOG_INFO_STR("CR_Trig. rcuSet=" << stopRequest.rcuSet); + LOG_INFO_STR("CR_Trig. stopTime=" << stopRequest.stopTime); } } if (!itsStopRequests.empty()) { + itsVHECRtimer->cancelAllTimers(); itsStopTimer->setTimer(0.0); } // send ack to triggerbox - CRStopAckEvent ack; - ack.triggerID = stopevent.triggerID; - ack.result = CR_NO_ERR; itsTriggerPort->send(ack); } break; case CR_READ:{ + itsAutoRecord = false; // send read commamd for given rcu's - CRReadEvent readevent(event); + CRReadEvent e(event); + CRReadAckEvent ack; + ReadRequest readRequest; RCUset_t rcuSet; rcuSet.reset(); + + ack.triggerID = e.triggerID; + ack.result = CR_NO_ERR; vector<CRreadRequest>::iterator iter; - for (iter = readevent.readVector.requests.begin(); iter != readevent.readVector.requests.end(); iter++) { + for (iter = e.readVector.requests.begin(); iter != e.readVector.requests.end(); iter++) { // check if this station is in stationlist string station_list(toUpper((*iter).stationList)); // empty station_list looks like "[]" @@ -880,7 +905,7 @@ GCFEvent::TResult TBBControl::active_state(GCFEvent& event, GCFPortInterface& po readRequest.timeAfter = (*iter).timeAfter; rcuSet = strToBitset((*iter).rcuList); - LOG_DEBUG_STR("CR_Trig. rcuSet=" << rcuSet); + LOG_INFO_STR("CR_Trig. rcuSet=" << rcuSet); for (int rcu = 0; rcu < itsNrRCUs; rcu++) { if (rcuSet.test(rcu) == true) { readRequest.rcuNr = rcu; @@ -895,62 +920,73 @@ GCFEvent::TResult TBBControl::active_state(GCFEvent& event, GCFPortInterface& po } // send acknowledge to triggerbox - CRReadAckEvent ack; - ack.triggerID = readevent.triggerID; - ack.result = CR_NO_ERR; itsTriggerPort->send(ack); } break; case CR_RECORD:{ - // send record command for given rcu's - CRRecordEvent recordevent(event); + + CRRecordEvent e(event); + CRRecordAckEvent ack; RCUset_t rcuSet; rcuSet.reset(); - LOG_INFO_STR("CR_Trig. Start recording"); + ack.triggerID = e.triggerID; + ack.result = CR_NO_ERR; + + vector<CRrecordRequest>::iterator iter; - for (iter = recordevent.recordVector.requests.begin(); iter != recordevent.recordVector.requests.end(); iter++) { + for (iter = e.recordVector.requests.begin(); iter != e.recordVector.requests.end(); iter++) { // check if this station is in stationlist string station_list(toUpper((*iter).stationList)); // empty station_list looks like "[]" if ((station_list.length() == 2) || (station_list.find(PVSSDatabaseName(""), 0) != string::npos)) { rcuSet |= strToBitset((*iter).rcuList); - LOG_DEBUG_STR("CR_Trig. rcuSet=" << rcuSet); } } if (rcuSet.count() > 0) { - sendRecordCmd(rcuSet); + // turn on recording, check first if dumping is done + if (itsReadRequests.empty()) { + LOG_INFO_STR("CR_Trig. Start recording"); + LOG_INFO_STR("CR_Trig. rcuSet=" << rcuSet); + sendRecordCmd(rcuSet); + } + else { + // busy dumping, start recording when ready + LOG_INFO_STR("CR_Trig. Auto recording turned on"); + itsAutoRecord = true; + } } - - CRRecordAckEvent ack; - ack.triggerID = recordevent.triggerID; - ack.result = CR_NO_ERR; itsTriggerPort->send(ack); } break; case CR_CEP_SPEED:{ - CRCepSpeedEvent cepspeedevent(event); + CRCepSpeedEvent e(event); + CRCepSpeedAckEvent ack; + + ack.triggerID = e.triggerID; + ack.result = CR_NO_ERR; - string station_list(toUpper(cepspeedevent.stationList)); + string station_list(toUpper(e.stationList)); // empty station_list looks like "[]" if ((station_list.length() == 2) || (station_list.find(PVSSDatabaseName(""), 0) != string::npos)) { - itsCepDelay = cepspeedevent.cepDelay; - itsMaxCepDatapaths = cepspeedevent.cepDatapaths; + itsCepDelay = e.cepDelay; + itsMaxCepDatapaths = e.cepDatapaths; LOG_INFO_STR(formatString("CR_Trig. CEP speed changed: delay= %d nsec, number of datapaths= %d", itsCepDelay*5, itsMaxCepDatapaths)); sendCepDelayCmd(); } - CRCepSpeedAckEvent ack; - ack.triggerID = cepspeedevent.triggerID; - ack.result = CR_NO_ERR; itsTriggerPort->send(ack); } break; case CR_STOP_DUMPS:{ - CRStopDumpsEvent stopdumpsevent(event); + CRStopDumpsEvent e(event); + CRStopDumpsAckEvent ack; + + ack.triggerID = e.triggerID; + ack.result = CR_NO_ERR; - string station_list(toUpper(stopdumpsevent.stationList)); + string station_list(toUpper(e.stationList)); // empty station_list looks like "[]" if ((station_list.length() == 2) || (station_list.find(PVSSDatabaseName(""), 0) != string::npos)) { LOG_INFO_STR("CR_Trig. Stop dumping CEP data"); @@ -959,12 +995,32 @@ GCFEvent::TResult TBBControl::active_state(GCFEvent& event, GCFPortInterface& po sendStopCepCmd(); } - CRStopDumpsAckEvent ack; - ack.triggerID = stopdumpsevent.triggerID; + itsTriggerPort->send(ack); + } break; + + case CR_VHECR_STATE:{ + CRVhecrStateEvent e(event); + CRVhecrStateAckEvent ack; + + ack.triggerID = e.triggerID; ack.result = CR_NO_ERR; + + string station_list(toUpper(e.stationList)); + // empty station_list looks like "[]" + if ((station_list.length() == 2) || (station_list.find(PVSSDatabaseName(""), 0) != string::npos)) { + LOG_INFO_STR(formatString("CR_Trig. VHECR state=%u", e.state)); + if (e.state == 1) { + itsVhecrTaskActive = true; + } + else { + itsVhecrTaskActive = false; + } + } + itsTriggerPort->send(ack); } break; + default: { status = _defaultEventHandler(event, port); } break; @@ -1125,6 +1181,7 @@ GCFEvent::TResult TBBControl::handleTriggerEvent(GCFEvent& event) //------------------------------------------------------------------------------ void TBBControl::sendRecordCmd(RCUset_t RCUset) { + itsAutoRecord = true; TBBRecordEvent cmd; cmd.rcu_mask = RCUset; LOG_DEBUG_STR("send TBB_RECORD cmd"); @@ -1215,7 +1272,7 @@ void TBBControl::sendStopCmd() struct timeval tv; gettimeofday(&tv, NULL); double timeNow = tv.tv_sec + (tv.tv_usec / 1000000.); - double nextStop = timeNow + 0.05; + double nextStop = timeNow + 3600.0; bool sendStop = false; vector<StopRequest> requests(itsStopRequests); @@ -1225,31 +1282,41 @@ void TBBControl::sendStopCmd() while (!requests.empty()) { request = requests.back(); requests.pop_back(); + LOG_INFO_STR(formatString("request stop time = %lf, timenow = %lf" , + (double)request.stopTime, timeNow )); + cmd.rcu_mask.reset(); for (int i = 0; i < itsNrRCUs; i++) { if (request.rcuSet.test(i)) { - if (((double)request.stopTime == 0.) || ((double)request.stopTime) > (timeNow - itsRcuInfo.at(i).bufferTime)) { + if ((double)request.stopTime == 0.) { cmd.rcu_mask.set(i); - request.rcuSet.reset(i); sendStop = true; } - else { - // check next stop time - if ((double)request.stopTime < nextStop) { - nextStop = (double)request.stopTime; + else if ((double)request.stopTime <= timeNow) { + if ((double)request.stopTime > (timeNow - itsRcuInfo.at(i).bufferTime)) { + cmd.rcu_mask.set(i); + sendStop = true; } } } } + + if (cmd.rcu_mask.count() > 0) { + request.rcuSet.reset(); + } + + if (request.rcuSet.count() > 0) { + if ((double)request.stopTime < nextStop) { + nextStop = (double)request.stopTime; + } + itsStopRequests.push_back(request); + } + if (sendStop) { - LOG_DEBUG_STR("send TBB_STOP cmd"); - LOG_DEBUG_STR("rcuSet=" << request.rcuSet); + LOG_INFO_STR("send TBB_STOP cmd"); + LOG_INFO_STR("rcuSet=" << cmd.rcu_mask); itsTBBDriver->send(cmd); - if (request.rcuSet.count() > 0) { - itsStopRequests.push_back(request); - } } - } if (!itsStopRequests.empty()) { @@ -1260,7 +1327,7 @@ void TBBControl::sendStopCmd() //------------------------------------------------------------------------------ // handleStopAck(event) // -// handle RSP_TBB_STOP_ACK cmd from the TBBDriver +// handle TBB_STOP_ACK cmd from the TBBDriver //------------------------------------------------------------------------------ int TBBControl::handleStopAck(GCFEvent& event) { @@ -1725,7 +1792,7 @@ int TBBControl::handleRcuInfoAck(GCFEvent& event) for (int i = 0; i < itsNrRCUs; i++) { if (itsRcuInfo.at(i).rcuNr == i) { itsRcuInfo.at(i).boardNr = ack.rcu_on_board[i]; - itsRcuInfo.at(i).bufferTime = (double)ack.rcu_pages[i] * itsObs->sampleTime; + itsRcuInfo.at(i).bufferTime = (double)ack.rcu_pages[i] * 1024 * itsObs->sampleTime; itsRcuInfo.at(i).rcuState = ack.rcu_state[i]; } else { @@ -2031,7 +2098,7 @@ RCUset_t TBBControl::strToBitset(string inputstring) while(start) { long val = strtol(start, &end, 10); // read decimal numbers start = (end ? (*end ? end + 1 : 0) : 0); // determine next start - if (val >= MAX_RCUS || val < 0) { + if (val >= itsNrRCUs || val < 0) { // Error: value out of range resultset.reset(); return(resultset); @@ -2043,7 +2110,7 @@ RCUset_t TBBControl::strToBitset(string inputstring) case 0: { if (range) { if (0 == prevval && 0 == val) { - val = MAX_RCUS - 1; + val = itsNrRCUs - 1; } if (val < prevval) { // Error: invalid range specification diff --git a/MAC/APL/StationCU/src/TBBControl/TBBControl.h b/MAC/APL/StationCU/src/TBBControl/TBBControl.h index ba46726d1e8a29b8165113b6a45233354c299358..de7469b2ce2e54a0b9439bba592757a9db2a64c1 100644 --- a/MAC/APL/StationCU/src/TBBControl/TBBControl.h +++ b/MAC/APL/StationCU/src/TBBControl/TBBControl.h @@ -246,6 +246,8 @@ private: int itsMaxCepDatapaths; int itsActiveCepDatapaths; int itsCepDelay; // 5 uSec/cnt + bool itsAutoRecord; + bool itsVhecrTaskActive; // pointer to parent control task ParentControl* itsParentControl; diff --git a/MAC/APL/StationCU/src/TBBControl/trigctl.cc b/MAC/APL/StationCU/src/TBBControl/trigctl.cc index 5f60daffebad98263d6ec06bfee903ed0a6fb909..b6f5b20a6584faaf3e6c5886df4684464639b4c1 100644 --- a/MAC/APL/StationCU/src/TBBControl/trigctl.cc +++ b/MAC/APL/StationCU/src/TBBControl/trigctl.cc @@ -77,7 +77,7 @@ void StopCmd::send() CRStopEvent event; event.triggerID = 50001; - event.stopVector.requests.push_back(CRstopRequest(itsStationStr, itsRcuStr, itsStopTime)); + event.stopVector.requests.push_back(CRstopRequest("[]", itsRcuStr, itsStopTime)); itsPort.send(event); itsTimer.setTimer(DELAY); @@ -90,7 +90,6 @@ GCFEvent::TResult StopCmd::ack(GCFEvent& e) if (ack.result == CR_NO_ERR) { cout << "STOP command arrived add TBBControl" << endl; - cout << "for Station: " << itsStationStr << endl; cout << "for RCU : " << itsRcuStr << endl; cout << "recording stopped at: " << (double)itsStopTime << " sec" << endl; } @@ -116,7 +115,7 @@ void ReadCmd::send() CRReadEvent event; event.triggerID = 50001; - event.readVector.requests.push_back(CRreadRequest(itsStationStr, + event.readVector.requests.push_back(CRreadRequest("[]", itsRcuStr, itsReadTime, itsTimeBefore, @@ -132,7 +131,6 @@ GCFEvent::TResult ReadCmd::ack(GCFEvent& e) if (ack.result == CR_NO_ERR) { cout << "READ command arrived add TBBControl" << endl; - cout << "for Station: " << itsStationStr << endl; cout << "for RCU : " << itsRcuStr << endl; cout << "read time : " << (double)itsReadTime << " sec" << endl; cout << "time before: " << (double)itsTimeBefore << " sec" << endl; @@ -160,7 +158,7 @@ void RecordCmd::send() CRRecordEvent event; event.triggerID = 50001; - event.recordVector.requests.push_back(CRrecordRequest(itsStationStr, + event.recordVector.requests.push_back(CRrecordRequest("[]", itsRcuStr) ); itsPort.send(event); @@ -174,7 +172,6 @@ GCFEvent::TResult RecordCmd::ack(GCFEvent& e) if (ack.result == CR_NO_ERR) { cout << "RECORD command arrived add TBBControl" << endl; - cout << "for Station: " << itsStationStr << endl; cout << "for RCU : " << itsRcuStr << endl; } else { @@ -199,7 +196,7 @@ void CepSpeedCmd::send() CRCepSpeedEvent event; event.triggerID = 50001; - event.stationList = itsStationStr; + event.stationList = "[]"; event.cepDelay = itsDelay; event.cepDatapaths = itsDatapaths; @@ -214,7 +211,6 @@ GCFEvent::TResult CepSpeedCmd::ack(GCFEvent& e) if (ack.result == CR_NO_ERR) { cout << "CEPSPEED command arrived add TBBControl" << endl; - cout << "for Station: " << itsStationStr << endl; } else { cout << "Error in CEPSPEED command" << endl; @@ -239,7 +235,7 @@ void StopDumpsCmd::send() CRStopDumpsEvent event; event.triggerID = 50001; - event.stationList = itsStationStr; + event.stationList = "[]"; itsPort.send(event); itsTimer.setTimer(DELAY); @@ -252,7 +248,6 @@ GCFEvent::TResult StopDumpsCmd::ack(GCFEvent& e) if (ack.result == CR_NO_ERR) { cout << "STOPDUMPS command arrived add TBBControl" << endl; - cout << "for Station: " << itsStationStr << endl; } else { cout << "Error in STOPDUMPS command" << endl; @@ -262,6 +257,44 @@ GCFEvent::TResult StopDumpsCmd::ack(GCFEvent& e) return(GCFEvent::HANDLED); } +//---- SET VHECR MODE ---------------------------------------------------------------- +VhecrEnableCmd::VhecrEnableCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer) : Command(port, timer) +{ + cout << endl; + cout << "== RTDB ================================================= set VHECR state ====" << endl; + cout << endl; +} + +//----------------------------------------------------------------------------- + +void VhecrEnableCmd::send() +{ + CRVhecrStateEvent event; + + event.triggerID = 50001; + event.stationList = "[]"; + event.state = itsState; + + itsPort.send(event); + itsTimer.setTimer(DELAY); +} + +//----------------------------------------------------------------------------- +GCFEvent::TResult VhecrEnableCmd::ack(GCFEvent& e) +{ + CRVhecrStateAckEvent ack(e); + + if (ack.result == CR_NO_ERR) { + cout << "VHECRSTATE command arrived add TBBControl" << endl; + } + else { + cout << "Error in VHECRSTATE command" << endl; + } + setCmdDone(true); + + return(GCFEvent::HANDLED); +} + //====END OF ETRIG COMMANDS========================================================================== @@ -277,21 +310,23 @@ void TRIGCtl::commandHelp() 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 << " trigctl --stop=time --obsid=observationId [--station=<stations>][--rcu=<rcuset>]" << endl; - cout << " # stop recording at given time for selected observation" << endl; - cout << " trigctl --read=time,timebefore, timeafter --obsid=observationId [--station=<stations>][--select=<rcuset>]" << endl; + cout << " trigctl --stop=time [--rcu=<rcuset>]" << endl; + cout << " # stop recording at given time for selected rcus" << endl; + cout << " trigctl --read=time,timebefore, timeafter [--select=<rcuset>]" << endl; cout << " # start dumping data to cep for given time and span" << endl; - cout << " trigctl --record --obsid=observationId [--station=<stations>][--rcu=<rcuset>]" << endl; - cout << " # start recording for selected observation" << endl; - cout << " trigctl --cepspeed=delay,datapaths --obsid=observationId [--station=<stations>]" << endl; - cout << " # set cep speed settings for selected observation" << endl; + cout << " trigctl --record [--rcu=<rcuset>]" << endl; + cout << " # start recording for selected rcus" << endl; + cout << " trigctl --cepspeed=delay,datapaths " << endl; + cout << " # set cep speed settings" << endl; cout << " # delay = delay between frames in nSec (1=5nSec)" << endl; cout << " # datapaths = number of datapaths to use 1..6" << endl; - cout << " trigctl --stopdumps --obsid=observationId [--station=<stations>]" << endl; - cout << " # stop dumping data to cep for selected observation" << endl; + cout << " trigctl --stopdumps" << endl; + cout << " # stop dumping data to cep" << endl; + cout << " trigctl --vhecrenable=1|0" << endl; + cout << " # turn on/off VHECRTask, 1 = on, 0 = off" << endl; + cout << endl; - cout << " for all optional arguments: if [--station=<stations>] is not used all stations are selected" << endl; - cout << " if [--rcu=<rcus>] is not used all rcus are selected" << endl; + cout << " for all optional arguments: if [--rcu=<rcus>] is not used all rcus are selected" << endl; cout << " trigctl --help # this help screen" << endl; cout << "< < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < " << endl; @@ -393,7 +428,7 @@ GCFEvent::TResult TRIGCtl::initial(GCFEvent& e, GCFPortInterface& port) //----------------------------------------------------------------------------- GCFEvent::TResult TRIGCtl::docommand(GCFEvent& e, GCFPortInterface& port) { - cout << "docommand signal:" << eventName(e) << endl; + //cout << "docommand signal:" << eventName(e) << endl; GCFEvent::TResult status = GCFEvent::HANDLED; switch (e.signal) { @@ -433,7 +468,8 @@ GCFEvent::TResult TRIGCtl::docommand(GCFEvent& e, GCFPortInterface& port) case CR_READ_ACK: case CR_RECORD_ACK: case CR_CEP_SPEED_ACK: - case CR_STOP_DUMPS_ACK: { + case CR_STOP_DUMPS_ACK: + case CR_VHECR_STATE_ACK: { itsTimerPort->cancelAllTimers(); status = itsCommand->ack(e); // handle the acknowledgement if (!itsCommand->isCmdDone()) { @@ -468,19 +504,18 @@ Command* TRIGCtl::parse_options(int argc, char** argv) while(1) { static struct option long_options[] = { { "rcu", required_argument, 0, 'a' }, - { "station", required_argument, 0, 'g' }, - { "obsid", required_argument, 0, 'h' }, { "stop", required_argument, 0, 'b' }, { "read", required_argument, 0, 'c' }, { "record", no_argument, 0, 'd' }, { "cepspeed", required_argument, 0, 'e' }, { "stopdumps", no_argument, 0, 'f' }, + { "vhecrenable",required_argument, 0, 'g' }, { 0, 0, 0, 0 }, }; int option_index = 0; int c = getopt_long( argc, argv, - "a:g:h:b:c:d:e:f:", + "a:b:c:d:e:f:g:", long_options, &option_index ); @@ -504,47 +539,12 @@ Command* TRIGCtl::parse_options(int argc, char** argv) } } break; - case 'g': { // --station - if (optarg) { - if (!command) { - cout << "Error: 'command' argument should come before --station argument" << endl; - exit(EXIT_FAILURE); - } - command->setStationStr(optarg); - } - else { - cout << "Error: option '--station' requires an argument" << endl; - exit(EXIT_FAILURE); - } - } break; - - case 'h': { // --obsid - if (optarg) { - if (!command) { - cout << "Error: 'command' argument should come before --station argument" << endl; - exit(EXIT_FAILURE); - } - uint32 obsid; - int numitems = sscanf(optarg, "%u",&obsid); - if ( numitems < 1 || numitems == EOF) { - cout << "Error: invalid number of arguments. Should be of the format " << endl; - cout << " '--obsid=id' (use int value)" << endl; - exit(EXIT_FAILURE); - } - command->setOnservationID(obsid); - } - else { - cout << "Error: option '--onsid' requires an argument" << endl; - exit(EXIT_FAILURE); - } - } break; - case 'b': { // --stop if (command) delete command; StopCmd* cmd = new StopCmd(*itsRTDBPort, *itsTimerPort); command = cmd; - double stopTime = 0.; + double stopTime = -1.; if (optarg) { int numitems = sscanf(optarg, "%lf",&stopTime); // check if valid arguments @@ -613,6 +613,24 @@ Command* TRIGCtl::parse_options(int argc, char** argv) command = cmd; } break; + case 'g': { // --vhecrenable + if (command) delete command; + VhecrEnableCmd* cmd = new VhecrEnableCmd(*itsRTDBPort, *itsTimerPort); + command = cmd; + uint32 state = 0; + if (optarg) { + int numitems = sscanf(optarg, "%u",&state); + // check if valid arguments + if ( numitems < 1 || numitems == EOF) { + cout << "Error: invalid number of arguments. Should be of the format " << endl; + cout << " '--vhecrenable=state' (state = 0/1)" << endl; + cout << " state=0: VHECRTask disabled, state=1: VHECRTask enabled" << endl; + exit(EXIT_FAILURE); + } + } + cmd->setState(state); + } break; + case 'L': case '?': { commandHelp(); @@ -626,12 +644,6 @@ Command* TRIGCtl::parse_options(int argc, char** argv) } } - if (command) { - if (!command->isSetObservationID()) { - cout << "Warning, ObservationID not set" << endl; - exit(EXIT_FAILURE); - } - } return(command); } diff --git a/MAC/APL/StationCU/src/TBBControl/trigctl.h b/MAC/APL/StationCU/src/TBBControl/trigctl.h index 391a5112290ddc22eb2f5865fa31926aa8295ab8..4bd84e79dd9b74ffa2a35a64348d7fd4f286fb6f 100644 --- a/MAC/APL/StationCU/src/TBBControl/trigctl.h +++ b/MAC/APL/StationCU/src/TBBControl/trigctl.h @@ -86,36 +86,14 @@ public: itsRcuStr.append("["+optarg+"]"); } - void setStationStr(string optarg) - { - itsStationStr.clear(); - itsStationStr.append("["+optarg+"]"); - } - - void setOnservationID(uint32 id) - { - itsObservationID = id; - } - - bool isSetObservationID() - { - if (itsObservationID == 0) { - return(false); - } - return(true); - } - protected: explicit Command(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer) : itsPort(port), itsTimer(timer), - itsCmdDone(false), - itsObservationID(0) + itsCmdDone(false) { itsRcuStr.clear(); itsRcuStr.append("[]"); - itsStationStr.clear(); - itsStationStr.append("[]"); } Command(); // no default construction allowed @@ -123,9 +101,7 @@ protected: GCF::RTDB::GCFRTDBPort& itsPort; GCFTimerPort& itsTimer; bool itsCmdDone; - uint32 itsObservationID; string itsRcuStr; - string itsStationStr; private: @@ -182,7 +158,7 @@ public: virtual void send(); virtual GCFEvent::TResult ack(GCFEvent& e); void setDelay(uint32 delay) { itsDelay = delay; } - void setDatapaths(uint32 datapaths) { itsDatapaths = datapaths; } + void setDatapaths(uint32 datapaths) { itsDatapaths = datapaths; } private: uint32 itsDelay; uint32 itsDatapaths; @@ -199,6 +175,20 @@ public: private: }; +//----------------------------------------------------------------------------- +class VhecrEnableCmd : public Command +{ +public: + VhecrEnableCmd(GCF::RTDB::GCFRTDBPort& port, GCFTimerPort& timer); + virtual ~VhecrEnableCmd() { } + virtual void send(); + virtual GCFEvent::TResult ack(GCFEvent& e); + void setState(uint32 state) { itsState = state; } +private: + uint32 itsState; +}; + + //----------------------------------------------------------------------------- // Controller class for etrigctl // class TRIGCtl diff --git a/MAC/APL/VHECR/src/VHECRTask.cc b/MAC/APL/VHECR/src/VHECRTask.cc index 8e66d297d2c45cd662bab3b67f2a5bf917e7ed47..ab8d39ede2fa645863d191d2e9cb9ad4a3d77f53 100644 --- a/MAC/APL/VHECR/src/VHECRTask.cc +++ b/MAC/APL/VHECR/src/VHECRTask.cc @@ -806,7 +806,18 @@ namespace LOFAR { int nrAntennas, nrPolarizations, nrDirections; //casa::Vector<MVPosition> all_positions; //casa::Vector<MVPosition> selected_positions; - do{antennaFile >> temp;} while(temp != antennaSelection); + + do { + antennaFile >> temp; + } while((temp != antennaSelection) && !antennaFile.eof()); + + if (antennaFile.eof()) { + LOG_FATAL("Failed to find antennaSelection!"); + //cerr << "VHECRTask: Failed to open Antenna Positions file!" << endl; + itsSettings->doDirectionFit = 0; + return; + }; + antennaFile >> temp; antennaFile >> temp; antennaFile >> temp; antennaFile >> temp; antennaFile >> temp; antennaFile >> temp; antennaFile >> nrAntennas; cout << " nr. antennas: " << nrAntennas << endl; antennaFile >> temp; antennaFile >> nrPolarizations; cout << " nr. polarizations: " << nrPolarizations << endl;