From 42d2af80fe295ade26f7fe423b2f45b916b8c221 Mon Sep 17 00:00:00 2001 From: Ruud Overeem <overeem@astron.nl> Date: Thu, 12 Jun 2008 12:32:52 +0000 Subject: [PATCH] Bug 1196: Added a command rspctl --realdelays to return the delay-values from the tiles. Value 255 is returned when an element is broken. Since I inserted a command in the RSPprotocol I increased the RSP_versionnumber to 3.1 in MACServiceInfo.h. --- MAC/APL/PIC/RSPDriver/src/Cache.cc | 13 + MAC/APL/PIC/RSPDriver/src/Cache.h | 2 + MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc | 133 +- MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc | 115 +- MAC/APL/PIC/RSPDriver/src/Makefile.am | 2 + MAC/APL/PIC/RSPDriver/src/RSPDriver.cc | 36 +- MAC/APL/PIC/RSPDriver/src/RSPDriver.h | 1 + MAC/APL/PIC/RSPDriver/src/ReadHBACmd.cc | 110 ++ MAC/APL/PIC/RSPDriver/src/ReadHBACmd.h | 78 + MAC/APL/PIC/RSPDriver/src/rspctl.cc | 1673 +++++++++-------- .../PIC/RSP_Protocol/src/RSP_Protocol.prot | 39 + MAC/MACIO/include/MACIO/MACServiceInfo.h | 2 +- 12 files changed, 1272 insertions(+), 932 deletions(-) create mode 100644 MAC/APL/PIC/RSPDriver/src/ReadHBACmd.cc create mode 100644 MAC/APL/PIC/RSPDriver/src/ReadHBACmd.h diff --git a/MAC/APL/PIC/RSPDriver/src/Cache.cc b/MAC/APL/PIC/RSPDriver/src/Cache.cc index 54926b7d846..c42c82077c2 100644 --- a/MAC/APL/PIC/RSPDriver/src/Cache.cc +++ b/MAC/APL/PIC/RSPDriver/src/Cache.cc @@ -62,6 +62,8 @@ CacheBuffer::CacheBuffer(Cache* cache) : m_cache(cache) LOG_DEBUG_STR("m_beamletweights().size() =" << m_beamletweights().size() * sizeof(complex<int16>)); LOG_DEBUG_STR("m_subbandselection().size() =" << m_subbandselection().size() * sizeof(uint16)); LOG_DEBUG_STR("m_rcusettings().size() =" << m_rcusettings().size() * sizeof(uint8)); + LOG_DEBUG_STR("m_hbasettings().size() =" << m_hbasettings().size() * sizeof(uint8)); + LOG_DEBUG_STR("m_hbareadings().size() =" << m_hbareadings().size() * sizeof(uint8)); LOG_DEBUG_STR("m_rsusettings().size() =" << m_rsusettings().size() * sizeof(uint8)); LOG_DEBUG_STR("m_wgsettings().size() =" << m_wgsettings().size() * sizeof(WGSettings::WGRegisterType)); LOG_DEBUG_STR("m_subbandstats().size() =" << m_subbandstats().size() * sizeof(uint16)); @@ -78,6 +80,8 @@ CacheBuffer::CacheBuffer(Cache* cache) : m_cache(cache) m_beamletweights().size() + m_subbandselection().size() + m_rcusettings().size() + + m_hbasettings().size() + + m_hbareadings().size() + m_rsusettings().size() + m_wgsettings().size() + m_subbandstats().size() @@ -96,6 +100,8 @@ CacheBuffer::~CacheBuffer() m_beamletweights().free(); m_subbandselection().free(); m_rcusettings().free(); + m_hbasettings().free(); + m_hbareadings().free(); m_rsusettings().free(); m_wgsettings().free(); m_wgsettings.waveforms().free(); @@ -154,6 +160,8 @@ void CacheBuffer::reset(void) // initialize HBA settings m_hbasettings().resize(StationSettings::instance()->nrRcus(), MEPHeader::N_HBA_DELAYS); m_hbasettings() = 0; // initialize to 0 + m_hbareadings().resize(StationSettings::instance()->nrRcus(), MEPHeader::N_HBA_DELAYS); + m_hbareadings() = 0; // initialize to 0 // RSU settings m_rsusettings().resize(StationSettings::instance()->nrRspBoards()); @@ -245,6 +253,11 @@ HBASettings& CacheBuffer::getHBASettings() return m_hbasettings; } +HBASettings& CacheBuffer::getHBAReadings() +{ + return m_hbareadings; +} + RSUSettings& CacheBuffer::getRSUSettings() { return m_rsusettings; diff --git a/MAC/APL/PIC/RSPDriver/src/Cache.h b/MAC/APL/PIC/RSPDriver/src/Cache.h index d9f4282332d..aca9584693a 100644 --- a/MAC/APL/PIC/RSPDriver/src/Cache.h +++ b/MAC/APL/PIC/RSPDriver/src/Cache.h @@ -60,6 +60,7 @@ namespace LOFAR { RSP_Protocol::SubbandSelection& getSubbandSelection(); RSP_Protocol::RCUSettings& getRCUSettings(); RSP_Protocol::HBASettings& getHBASettings(); + RSP_Protocol::HBASettings& getHBAReadings(); RSP_Protocol::RSUSettings& getRSUSettings(); RSP_Protocol::WGSettings& getWGSettings(); RSP_Protocol::SystemStatus& getSystemStatus(); @@ -103,6 +104,7 @@ namespace LOFAR { RSP_Protocol::SubbandSelection m_subbandselection; RSP_Protocol::RCUSettings m_rcusettings; RSP_Protocol::HBASettings m_hbasettings; + RSP_Protocol::HBASettings m_hbareadings; RSP_Protocol::RSUSettings m_rsusettings; RSP_Protocol::WGSettings m_wgsettings; RSP_Protocol::Statistics m_subbandstats; diff --git a/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc b/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc index 9ffe9ae4e19..90967c677df 100644 --- a/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc +++ b/MAC/APL/PIC/RSPDriver/src/HBAProtocolWrite.cc @@ -297,87 +297,83 @@ HBAProtocolWrite::~HBAProtocolWrite() void HBAProtocolWrite::sendrequest() { - uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + (getCurrentIndex() / N_WRITES); + uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + (getCurrentIndex() / N_WRITES); - // only update if rcuprotocol is not being updated and one of hbaprotocol needs updating - if (RTC::RegisterState::IDLE != Cache::getInstance().getState().rcuprotocol().get(global_blp * MEPHeader::N_POL) - || RTC::RegisterState::IDLE != Cache::getInstance().getState().rcuprotocol().get(global_blp * MEPHeader::N_POL + 1)) - { - setContinue(true); - return; - } + // only update if rcuprotocol is not being updated and one of hbaprotocol needs updating + if (RTC::RegisterState::IDLE != Cache::getInstance().getState().rcuprotocol().get(global_blp * MEPHeader::N_POL) + || RTC::RegisterState::IDLE != Cache::getInstance().getState().rcuprotocol().get(global_blp * MEPHeader::N_POL + 1)) { + setContinue(true); + return; + } - if (RTC::RegisterState::WRITE != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL) - && RTC::RegisterState::WRITE != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL + 1)) - { - Cache::getInstance().getState().hbaprotocol().unmodified(global_blp * MEPHeader::N_POL); - Cache::getInstance().getState().hbaprotocol().unmodified(global_blp * MEPHeader::N_POL + 1); - setContinue(true); - return; - } + if (RTC::RegisterState::WRITE != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL) + && RTC::RegisterState::WRITE != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL + 1)) { + Cache::getInstance().getState().hbaprotocol().unmodified(global_blp * MEPHeader::N_POL); + Cache::getInstance().getState().hbaprotocol().unmodified(global_blp * MEPHeader::N_POL + 1); + setContinue(true); + return; + } - // delays for at least on HBA need to be written, and the RCUProtocol register is not in use by RCUProtocolWrite + // delays for at least on HBA need to be written, and the RCUProtocol register is not in use by RCUProtocolWrite LOG_INFO_STR("HBAsendrequest: " << getCurrentIndex()); - switch (getCurrentIndex() % N_WRITES) { - - case 0: - { + switch (getCurrentIndex() % N_WRITES) { + case 0: { #ifdef HBA_WRITE_DELAYS - if (PROTOCOL_DELAY_OFFSET > 0) { - Array<uint8, 2> delays(i2c_protocol + PROTOCOL_DELAY_OFFSET, - shape(MEPHeader::N_HBA_DELAYS, 2), - neverDeleteData); + if (PROTOCOL_DELAY_OFFSET > 0) { + Array<uint8, 2> delays(i2c_protocol + PROTOCOL_DELAY_OFFSET, + shape(MEPHeader::N_HBA_DELAYS, 2), + neverDeleteData); - delays(Range::all(), 0) = Cache::getInstance().getBack().getHBASettings()()(global_blp * MEPHeader::N_POL, Range::all()); - delays(Range::all(), 1) = Cache::getInstance().getBack().getHBASettings()()(global_blp * MEPHeader::N_POL + 1, Range::all()); + delays(Range::all(), 0) = Cache::getInstance().getBack().getHBASettings()()(global_blp * MEPHeader::N_POL, Range::all()); + delays(Range::all(), 1) = Cache::getInstance().getBack().getHBASettings()()(global_blp * MEPHeader::N_POL + 1, Range::all()); - // copy set delays to i2c_result which is the expected result - uint8* cur = i2c_result + RESULT_DELAY_OFFSET; - for (int elem = 0; elem < MEPHeader::N_HBA_DELAYS; elem++){ - *(cur+0) = delays(elem, 0); // X - *(cur+1) = delays(elem, 1); // Y - cur += RESULT_DELAY_STRIDE; + // copy set delays to i2c_result which is the expected result + uint8* cur = i2c_result + RESULT_DELAY_OFFSET; + for (int elem = 0; elem < MEPHeader::N_HBA_DELAYS; elem++){ + *(cur+0) = delays(elem, 0); // X + *(cur+1) = delays(elem, 1); // Y + cur += RESULT_DELAY_STRIDE; + } + } +#else + i2c_protocol[PROTOCOL_LED_OFFSET] = (m_on_off ? 0xf : 0x0); + i2c_result[RESULT_LED_OFFSET] = i2c_protocol[PROTOCOL_LED_OFFSET]; + LOG_INFO(formatString("Switch LED (HBA_blp=%d) %s", global_blp, m_on_off ? "on" : "off")); +#endif + // create the event + EPARcuProtocolEvent rcuprotocol; + rcuprotocol.hdr.set(MEPHeader::RCU_PROTOCOLY_HDR, 1 << (getCurrentIndex() / N_WRITES), MEPHeader::WRITE, sizeof(i2c_protocol)); + rcuprotocol.protocol.setBuffer(i2c_protocol, sizeof(i2c_protocol)); + + string tmpbuf; + hexdump (tmpbuf, i2c_protocol, sizeof(i2c_protocol)); + LOG_INFO_STR("HBA WRITE: " << tmpbuf); + + m_hdr = rcuprotocol.hdr; // remember header to match with ack + getBoardPort().send(rcuprotocol); } - } + break; -#else + case 1: { + EPAWriteEvent rcuresultwrite; - i2c_protocol[PROTOCOL_LED_OFFSET] = (m_on_off ? 0xf : 0x0); - i2c_result[RESULT_LED_OFFSET] = i2c_protocol[PROTOCOL_LED_OFFSET]; - LOG_INFO(formatString("Switch LED (HBA_blp=%d) %s", global_blp, m_on_off ? "on" : "off")); + // set the result register to 0xBB's + rcuresultwrite.hdr.set(MEPHeader::WRITE, 1 << (getCurrentIndex() / N_WRITES), + MEPHeader::RCU, MEPHeader::RCU_RESULTY, sizeof(i2c_result), 0); + uint8 clear[RESULT_SIZE]; + memset(clear, 0xBB, RESULT_SIZE); // clear result + rcuresultwrite.payload.setBuffer(clear, RESULT_SIZE); -#endif + string tmpbuf; + hexdump (tmpbuf, clear, sizeof(clear)); + LOG_INFO_STR("HBA RESULT WRITE: " << tmpbuf); - // create the event - EPARcuProtocolEvent rcuprotocol; - rcuprotocol.hdr.set(MEPHeader::RCU_PROTOCOLY_HDR, 1 << (getCurrentIndex() / N_WRITES), MEPHeader::WRITE, sizeof(i2c_protocol)); - rcuprotocol.protocol.setBuffer(i2c_protocol, sizeof(i2c_protocol)); - string tmpbuf; - hexdump (tmpbuf, i2c_protocol, sizeof(i2c_protocol)); - LOG_INFO_STR("HBA WRITE: " << tmpbuf); - - m_hdr = rcuprotocol.hdr; // remember header to match with ack - getBoardPort().send(rcuprotocol); - } - break; - - case 1: - { - EPAWriteEvent rcuresultwrite; - - // set the result register to 0xBB's - rcuresultwrite.hdr.set(MEPHeader::WRITE, 1 << (getCurrentIndex() / N_WRITES), - MEPHeader::RCU, MEPHeader::RCU_RESULTY, sizeof(i2c_result), 0); - uint8 clear[RESULT_SIZE]; - memset(clear, 0xBB, RESULT_SIZE); // clear result - rcuresultwrite.payload.setBuffer(clear, RESULT_SIZE); - - m_hdr = rcuresultwrite.hdr; // remember header to match with ack - getBoardPort().send(rcuresultwrite); - } - break; - } + m_hdr = rcuresultwrite.hdr; // remember header to match with ack + getBoardPort().send(rcuresultwrite); + } + break; + } } void HBAProtocolWrite::sendrequest_status() @@ -397,6 +393,7 @@ GCFEvent::TResult HBAProtocolWrite::handleack(GCFEvent& event, GCFPortInterface& uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + (getCurrentIndex() / N_WRITES); +LOG_INFO_STR("hba[" << (int)(global_blp) << "]: handleAck"); if (!ack.hdr.isValidAck(m_hdr)) { LOG_ERROR("HBAProtocolWrite::handleack: invalid ack"); diff --git a/MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc b/MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc index 02864ebafe5..ce3118531d2 100644 --- a/MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc +++ b/MAC/APL/PIC/RSPDriver/src/HBAResultRead.cc @@ -22,6 +22,7 @@ #include <lofar_config.h> #include <Common/LofarLogger.h> +#include <Common/hexdump.h> #include <APL/RSP_Protocol/EPA_Protocol.ph> #include <APL/RTCCommon/PSAccess.h> @@ -52,58 +53,82 @@ HBAResultRead::~HBAResultRead() void HBAResultRead::sendrequest() { - uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + getCurrentIndex(); - - // skip update if the RCU settings have not been applied yet - if (RTC::RegisterState::READ != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL) - && RTC::RegisterState::READ != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL + 1)) { - setContinue(true); - return; - } - - // set appropriate header - EPAReadEvent rcuresult; - rcuresult.hdr.set(MEPHeader::RCU_RESULTY_HDR, 1 << getCurrentIndex(), - MEPHeader::READ, sizeof(HBAProtocolWrite::i2c_result)); - - m_hdr = rcuresult.hdr; // remember header to match with ack - getBoardPort().send(rcuresult); + uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + getCurrentIndex(); + //LOG_DEBUG_STR("HBA request result for " << (int) global_blp); + + // skip update if the RCU settings have not been applied yet + if (RTC::RegisterState::READ != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL) && + RTC::RegisterState::READ != Cache::getInstance().getState().hbaprotocol().get(global_blp * MEPHeader::N_POL + 1)) { + setContinue(true); + return; + } + + // set appropriate header + EPAReadEvent rcuresult; + rcuresult.hdr.set(MEPHeader::RCU_RESULTY_HDR, 1 << getCurrentIndex(), + MEPHeader::READ, sizeof(HBAProtocolWrite::i2c_result)); + + m_hdr = rcuresult.hdr; // remember header to match with ack + getBoardPort().send(rcuresult); } void HBAResultRead::sendrequest_status() { - // intentionally left empty + // intentionally left empty } GCFEvent::TResult HBAResultRead::handleack(GCFEvent& event, GCFPortInterface& /*port*/) { - if (EPA_RCU_RESULT != event.signal) - { - LOG_WARN("HBAResultRead::handleack:: unexpected ack"); - return GCFEvent::NOT_HANDLED; - } + if (EPA_RCU_RESULT != event.signal) { + LOG_WARN("HBAResultRead::handleack:: unexpected ack"); + return GCFEvent::NOT_HANDLED; + } - EPARcuResultEvent ack(event); - - uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + getCurrentIndex(); - - if (!ack.hdr.isValidAck(m_hdr)) - { - LOG_ERROR("HBAResultRead::handleack: invalid ack"); - Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL); - Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL + 1); - return GCFEvent::HANDLED; - } - - // compare result with expected result - if (0 == memcmp(HBAProtocolWrite::i2c_result, ack.result, sizeof(HBAProtocolWrite::i2c_result))) { - Cache::getInstance().getState().hbaprotocol().read_ack(global_blp * MEPHeader::N_POL); - Cache::getInstance().getState().hbaprotocol().read_ack(global_blp * MEPHeader::N_POL + 1); - } else { - LOG_WARN("HBAResultRead::handleack: unexpected I2C result response"); - Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL); - Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL + 1); - } - - return GCFEvent::HANDLED; + EPARcuResultEvent ack(event); + uint8 global_blp = (getBoardId() * StationSettings::instance()->nrBlpsPerBoard()) + getCurrentIndex(); + +#if 0 + string received, expected; + hexdump (received, (char*)(&(ack.result)), HBAProtocolWrite::RESULT_SIZE); + hexdump (expected, HBAProtocolWrite::i2c_result, HBAProtocolWrite::RESULT_SIZE); + LOG_INFO_STR("ack for hba[" << (int)(global_blp) << "]=" << received); + LOG_INFO_STR("exp for hba[" << (int)(global_blp) << "]=" << expected); +#endif + + // copy read-values to HBAReadings-cache. + string faultyElements; + uint8* cur = ack.result + HBAProtocolWrite::RESULT_DELAY_OFFSET; + for (int element = 0; element < MEPHeader::N_HBA_DELAYS; element++) { + if ((int)(*(cur-2)) != (int)(0x81+element)) { + faultyElements.append(formatString("%d,", element)); + Cache::getInstance().getBack().getHBAReadings()()((global_blp*2), element) = 255; // X + Cache::getInstance().getBack().getHBAReadings()()((global_blp*2)+1, element) = 255; // Y + } + else { + Cache::getInstance().getBack().getHBAReadings()()((global_blp*2), element) = *(cur+0); // X + Cache::getInstance().getBack().getHBAReadings()()((global_blp*2)+1, element) = *(cur+1); // Y + } + cur += HBAProtocolWrite::RESULT_DELAY_STRIDE; + } + + // check result + if (!ack.hdr.isValidAck(m_hdr)) { + LOG_ERROR("HBAResultRead::handleack: invalid ack"); + Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL); + Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL + 1); + return GCFEvent::HANDLED; + } + + // compare result with expected result + if (memcmp(HBAProtocolWrite::i2c_result, ack.result, sizeof(HBAProtocolWrite::i2c_result)) == 0) { + Cache::getInstance().getState().hbaprotocol().read_ack(global_blp * MEPHeader::N_POL); + Cache::getInstance().getState().hbaprotocol().read_ack(global_blp * MEPHeader::N_POL + 1); + } else { + LOG_WARN_STR("HBAResultRead: unexpected I2C result response for element(s):" << faultyElements << + " of antenna " << (int)(global_blp)); + Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL); + Cache::getInstance().getState().hbaprotocol().read_error(global_blp * MEPHeader::N_POL + 1); + } + + return GCFEvent::HANDLED; } diff --git a/MAC/APL/PIC/RSPDriver/src/Makefile.am b/MAC/APL/PIC/RSPDriver/src/Makefile.am index fccfa1ce24a..d6375e77b6b 100644 --- a/MAC/APL/PIC/RSPDriver/src/Makefile.am +++ b/MAC/APL/PIC/RSPDriver/src/Makefile.am @@ -106,6 +106,8 @@ RSPDriverFiles = \ SetHBACmd.cc \ GetHBACmd.h \ GetHBACmd.cc \ + ReadHBACmd.h \ + ReadHBACmd.cc \ UpdHBACmd.h \ UpdHBACmd.cc \ SetRSUCmd.h \ diff --git a/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc b/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc index 867278f7ac0..bc7e226d963 100644 --- a/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc +++ b/MAC/APL/PIC/RSPDriver/src/RSPDriver.cc @@ -60,6 +60,7 @@ #include "UpdRCUCmd.h" #include "SetHBACmd.h" #include "GetHBACmd.h" +#include "ReadHBACmd.h" #include "UpdHBACmd.h" #include "SetRSUCmd.h" #include "SetWGCmd.h" @@ -1008,6 +1009,10 @@ GCFEvent::TResult RSPDriver::enabled(GCFEvent& event, GCFPortInterface& port) rsp_gethba(event, port); break; + case RSP_READHBA: + rsp_readhba(event, port); + break; + case RSP_SUBHBA: rsp_subhba(event, port); break; @@ -1728,6 +1733,35 @@ void RSPDriver::rsp_gethba(GCFEvent& event, GCFPortInterface& port) } } +// +// rsp_readhba(event,port) +// +void RSPDriver::rsp_readhba(GCFEvent& event, GCFPortInterface& port) +{ + Ptr<ReadHBACmd> command = new ReadHBACmd(event, port, Command::READ); + + if (!command->validate()) { + LOG_ERROR("READHBA: invalid parameter"); + + RSPReadhbaackEvent ack; + ack.timestamp = Timestamp(0,0); + ack.status = FAILURE; + ack.settings().resize(1, 1); // create something to pack + ack.settings() = 0; + port.send(ack); + return; + } + + // if null timestamp get value from the cache and acknowledge immediately + if ( (Timestamp(0,0) == command->getTimestamp()) && (true == command->readFromCache())) { + command->setTimestamp(Cache::getInstance().getFront().getTimestamp()); + command->ack(Cache::getInstance().getFront()); + } + else { + (void)m_scheduler.enter(Ptr<Command>(&(*command))); + } +} + // // rsp_subhba(event,port) // @@ -2587,7 +2621,7 @@ void RSPDriver::rsp_gettbb(GCFEvent& event, GCFPortInterface& port) // int main(int argc, char** argv) { - GCFTask::init(argc, argv); // initializes log system + GCFTask::init(argc, argv, "RSPDriver"); // initializes log system LOG_INFO(formatString("Starting up %s", argv[0])); diff --git a/MAC/APL/PIC/RSPDriver/src/RSPDriver.h b/MAC/APL/PIC/RSPDriver/src/RSPDriver.h index fdd19b3eb9c..934466c8762 100644 --- a/MAC/APL/PIC/RSPDriver/src/RSPDriver.h +++ b/MAC/APL/PIC/RSPDriver/src/RSPDriver.h @@ -124,6 +124,7 @@ namespace LOFAR { void rsp_sethba (GCFEvent& event, GCFPortInterface &port); void rsp_gethba (GCFEvent& event, GCFPortInterface &port); + void rsp_readhba (GCFEvent& event, GCFPortInterface &port); void rsp_subhba (GCFEvent& event, GCFPortInterface &port); void rsp_unsubhba(GCFEvent& event, GCFPortInterface &port); diff --git a/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.cc b/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.cc new file mode 100644 index 00000000000..9da0cbbd0be --- /dev/null +++ b/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.cc @@ -0,0 +1,110 @@ +//# ReadHBACmd.cc: implementation of the ReadHBACmd class +//# +//# Copyright (C) 2008 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#include <lofar_config.h> +#include <Common/LofarLogger.h> + +#include <APL/RSP_Protocol/RSP_Protocol.ph> +#include <APL/RTCCommon/PSAccess.h> + +#include <blitz/array.h> + +#include "StationSettings.h" +#include "ReadHBACmd.h" + +using namespace blitz; +using namespace LOFAR; +using namespace RSP; +using namespace RSP_Protocol; +using namespace RTC; + +ReadHBACmd::ReadHBACmd(GCFEvent& event, GCFPortInterface& port, Operation oper) +{ + m_event = new RSPReadhbaEvent(event); + + setOperation(oper); + setPeriod(0); + setPort(port); +} + +ReadHBACmd::~ReadHBACmd() +{ + delete m_event; +} + +void ReadHBACmd::ack(CacheBuffer& cache) +{ +LOG_INFO("READHBACMD::ack"); + RSPReadhbaackEvent ack; + + ack.timestamp = getTimestamp(); + ack.status = SUCCESS; + + ack.settings().resize(m_event->rcumask.count(), MEPHeader::N_HBA_DELAYS); + + int result_rcu = 0; + for (int cache_rcu = 0; cache_rcu < StationSettings::instance()->nrRcus(); cache_rcu++) { + if (m_event->rcumask[cache_rcu]) { + if (cache_rcu < StationSettings::instance()->nrRcus()) { + ack.settings()(result_rcu, Range::all()) = cache.getHBAReadings()()(cache_rcu, Range::all()); + } + else { + LOG_WARN(formatString("invalid RCU index %d, there are only %d RCU's", cache_rcu, + StationSettings::instance()->nrRcus())); + } + + result_rcu++; + } + } + + getPort()->send(ack); +} + +void ReadHBACmd::apply(CacheBuffer& /*cache*/, bool /*setModFlag*/) +{ + /* intentionally left empty */ +} + +void ReadHBACmd::complete(CacheBuffer& cache) +{ + ack(cache); +} + +const RTC::Timestamp& ReadHBACmd::getTimestamp() const +{ + return (m_event->timestamp); +} + +void ReadHBACmd::setTimestamp(const RTC::Timestamp& timestamp) +{ + m_event->timestamp = timestamp; +} + +bool ReadHBACmd::validate() const +{ + return ((m_event->rcumask.count() <= (unsigned int)StationSettings::instance()->nrRcus())); +} + +bool ReadHBACmd::readFromCache() const +{ + return (m_event->cache); +} diff --git a/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.h b/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.h new file mode 100644 index 00000000000..09ee416d079 --- /dev/null +++ b/MAC/APL/PIC/RSPDriver/src/ReadHBACmd.h @@ -0,0 +1,78 @@ +//# -*- mode: c++ -*- +//# +//# ReadHBACmd.h: Returns the HBA-delays that are readback fro the tiles. +//# +//# Copyright (C) 2008 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef READHBACMD_H_ +#define READHBACMD_H_ + +#include "Command.h" +#include <APL/RSP_Protocol/RSP_Protocol.ph> + +#include <Common/LofarTypes.h> +#include <GCF/TM/GCF_Control.h> + +namespace LOFAR { + namespace RSP { + +class ReadHBACmd : public Command +{ +public: + // Constructors for a ReadHBACmd object. + ReadHBACmd(GCFEvent& event, GCFPortInterface& port, Operation oper); + + // Destructor for ReadHBACmd. + virtual ~ReadHBACmd(); + + // Acknowledge the command by sending the appropriate + // response on m_port. + virtual void ack(CacheBuffer& cache); + + // Make necessary changes to the cache for the next synchronization. + // Any changes will be sent to the RSP boards. + virtual void apply(CacheBuffer& cache, bool setModFlag = true); + + // Complete the command by sending the appropriate response on + // the m_answerport; + virtual void complete(CacheBuffer& cache); + + // get timestamp of the event + virtual const RTC::Timestamp& getTimestamp() const; + virtual void setTimestamp(const RTC::Timestamp& timestamp); + + // Validate the event that underlies the command. + virtual bool validate() const; + + // Return true if value should be read from cache. + bool readFromCache() const; + +private: + // default construction not allowed. + ReadHBACmd(); + + RSPReadhbaEvent* m_event; +}; + + }; +}; + +#endif /* READHBACMD_H_ */ diff --git a/MAC/APL/PIC/RSPDriver/src/rspctl.cc b/MAC/APL/PIC/RSPDriver/src/rspctl.cc index cb614b2e168..5587187075b 100644 --- a/MAC/APL/PIC/RSPDriver/src/rspctl.cc +++ b/MAC/APL/PIC/RSPDriver/src/rspctl.cc @@ -67,6 +67,9 @@ double WGCommand::AMPLITUDE_SCALE = (1.0 * ((uint32)(1 << 11)-1) / (uint32)(1 << // local funtions static void usage(); +// getting real or sent hba values +static bool realDelays = false; + // Constants #define BITSOFBYTE 8 @@ -529,98 +532,133 @@ HBACommand::HBACommand(GCFPortInterface& port) : Command(port) void HBACommand::send() { - if (getMode()) - { - // GET - RSPGethbaEvent gethba; - - gethba.timestamp = Timestamp(0,0); - gethba.rcumask = getRCUMask(); - gethba.cache = false; - - m_rspport.send(gethba); - } - else - { - // SET - RSPSethbaEvent sethba; - sethba.timestamp = Timestamp(0,0); - sethba.rcumask = getRCUMask(); - - sethba.settings().resize(sethba.rcumask.count(), MEPHeader::N_HBA_DELAYS); - - if (1 == m_delaylist.size()) { - std::list<int>::iterator it = m_delaylist.begin(); - sethba.settings() = (*it); - } else { + if (getMode()) { + // GET + if (realDelays) { + RSPReadhbaEvent readhba; + readhba.timestamp = Timestamp(0,0); + readhba.rcumask = getRCUMask(); + readhba.cache = true; - // clear first - sethba.settings() = 0; + m_rspport.send(readhba); + } + else { + RSPGethbaEvent gethba; + gethba.timestamp = Timestamp(0,0); + gethba.rcumask = getRCUMask(); + gethba.cache = false; - int i = 0; - std::list<int>::iterator it; - for (it = m_delaylist.begin(); it != m_delaylist.end(); it++, i++) { - if (i >= MEPHeader::N_HBA_DELAYS) break; - sethba.settings()(Range::all(), i) = (*it); - } - } + m_rspport.send(gethba); + } + } + else { // SET + // Note: also accept the 'set'-form for the readHBA command + // why bother the user if we know what he realy ment + RSPSethbaEvent sethba; + sethba.timestamp = Timestamp(0,0); + sethba.rcumask = getRCUMask(); + + sethba.settings().resize(sethba.rcumask.count(), MEPHeader::N_HBA_DELAYS); + + if (1 == m_delaylist.size()) { + std::list<int>::iterator it = m_delaylist.begin(); + sethba.settings() = (*it); + } + else { + // clear first + sethba.settings() = 0; + + int i = 0; + std::list<int>::iterator it; + for (it = m_delaylist.begin(); it != m_delaylist.end(); it++, i++) { + if (i >= MEPHeader::N_HBA_DELAYS) + break; + sethba.settings()(Range::all(), i) = (*it); + } + } #if 0 - for (int i = 0; i < sethba.settings().extent(firstDim); i++) { - printf("delays(%d)=", i); - cout << sethba.settings()(i) << endl; - } + for (int i = 0; i < sethba.settings().extent(firstDim); i++) { + printf("delays(%d)=", i); + cout << sethba.settings()(i) << endl; + } #endif - - m_rspport.send(sethba); - } + m_rspport.send(sethba); + } } GCFEvent::TResult HBACommand::ack(GCFEvent& e) { - switch (e.signal) - { - case RSP_GETHBAACK: - { - RSPGethbaackEvent ack(e); - bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask(); - - cout << "settings().shape()=" << ack.settings().shape() << endl; - - if (SUCCESS == ack.status) - { - int hbain = 0; - for (int hbaout = 0; hbaout < get_ndevices(); hbaout++) { - - if (mask[hbaout]) { - logMessage(cout, formatString("HBA[%2d].delays=", hbaout)); - for (int i = 0; i < MEPHeader::N_HBA_DELAYS; i++) { - logMessage(cout, formatString("%3d", (int)(ack.settings()(hbain, i)))); - } - hbain++; - } - } - } - else - { - logMessage(cerr,"Error: RSP_GETHBA command failed."); - } - } - break; + switch (e.signal) { + case RSP_GETHBAACK: + { + RSPGethbaackEvent ack(e); + bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask(); + + cout << "settings().shape()=" << ack.settings().shape() << endl; + + if (SUCCESS == ack.status) { + int hbain = 0; + for (int hbaout = 0; hbaout < get_ndevices(); hbaout++) { + if (mask[hbaout]) { + cout << formatString("HBA[%2d].delays=", hbaout); + for (int i = 0; i < MEPHeader::N_HBA_DELAYS; i++) { + cout << formatString(" %3d", (int)(ack.settings()(hbain, i))); + } + cout << endl; + hbain++; + } + } + } + else { + logMessage(cerr,"Error: RSP_GETHBA command failed."); + } + } + break; - case RSP_SETHBAACK: - { - RSPSethbaackEvent ack(e); + case RSP_READHBAACK: + { + RSPReadhbaackEvent ack(e); + bitset<MEPHeader::MAX_N_RCUS> mask = getRCUMask(); + + cout << "settings().shape()=" << ack.settings().shape() << endl; + + if (SUCCESS == ack.status) { + int hbain = 0; + for (int hbaout = 0; hbaout < get_ndevices(); hbaout++) { + if (mask[hbaout]) { + cout << formatString("HBA[%2d].real delays=", hbaout); + for (int i = 0; i < MEPHeader::N_HBA_DELAYS; i++) { + if ((int)(ack.settings()(hbain, i)) == 255) { + cout << " ???"; + } + else { + cout << formatString(" %3d", (int)(ack.settings()(hbain, i))); + } + } + cout << endl; + hbain++; + } + } + } + else { + logMessage(cerr,"Error: RSP_READHBA command failed."); + } + } + break; - if (SUCCESS != ack.status) - { - logMessage(cerr,"Error: RSP_SETHBA command failed."); - } - } - } + case RSP_SETHBAACK: + { + RSPSethbaackEvent ack(e); + if (SUCCESS != ack.status) { + logMessage(cerr,"Error: RSP_SETHBA command failed."); + } + } + break; + } - GCFTask::stop(); + GCFTask::stop(); - return GCFEvent::HANDLED; + return (GCFEvent::HANDLED); } // @@ -2100,6 +2138,7 @@ RSPCtl::~RSPCtl() GCFEvent::TResult RSPCtl::initial(GCFEvent& e, GCFPortInterface& port) { + LOG_DEBUG_STR ("initial:" << eventName(e) << "@" << port.getName()); GCFEvent::TResult status = GCFEvent::HANDLED; switch(e.signal) @@ -2163,120 +2202,114 @@ GCFEvent::TResult RSPCtl::initial(GCFEvent& e, GCFPortInterface& port) GCFEvent::TResult RSPCtl::docommand(GCFEvent& e, GCFPortInterface& port) { - GCFEvent::TResult status = GCFEvent::HANDLED; + LOG_DEBUG_STR ("docommand:" << eventName(e) << "@" << port.getName()); - switch (e.signal) - { - case F_ENTRY: - { - m_subclock.send(); // subscribe to clock updates - // after receiving the clock update execute the actual requested command - } - break; + GCFEvent::TResult status = GCFEvent::HANDLED; - case F_CONNECTED: - { - // connection with te frontend! send the command to the rsp driver - FECommand* feCommand = dynamic_cast<FECommand*>(m_command); - if(feCommand != 0) - { - if(feCommand->isConnected(port)) - { - m_command->send(); - } - } - } - break; - - case F_DISCONNECTED: - { - port.close(); - logMessage(cerr,formatString("Error: port '%s' disconnected.",port.getName().c_str())); - exit(EXIT_FAILURE); - } - break; + switch (e.signal) { + case F_ENTRY: + { + m_subclock.send(); // subscribe to clock updates + // after receiving the clock update execute the actual requested command + } + break; - case RSP_GETRCUACK: - case RSP_SETRCUACK: - case RSP_SETRSUACK: - case RSP_GETSTATSACK: - case RSP_SUBSTATSACK: - case RSP_UPDSTATS: - case RSP_SUBXCSTATSACK: - case RSP_UPDXCSTATS: - case RSP_GETVERSIONACK: - case RSP_GETSUBBANDSACK: - case RSP_SETSUBBANDSACK: - case RSP_SETWEIGHTSACK: - case RSP_GETWEIGHTSACK: - case RSP_GETWGACK: - case RSP_SETWGACK: - case RSP_SETCLOCKACK: - case RSP_GETSTATUSACK: - case RSP_GETTDSTATUSACK: - case RSP_SUBREGISTERSTATEACK: - case RSP_UPDREGISTERSTATE: - case RSP_SETHBAACK: - case RSP_GETHBAACK: - case RSP_SETTBBACK: - case RSP_GETTBBACK: - case RSP_GETBYPASSACK: - case RSP_SETBYPASSACK: - status = m_command->ack(e); // handle the acknowledgement - break; + case F_CONNECTED: + { + // connection with te frontend! send the command to the rsp driver + FECommand* feCommand = dynamic_cast<FECommand*>(m_command); + if(feCommand != 0) { + if(feCommand->isConnected(port)) { + m_command->send(); + } + } + } + break; - case RSP_UPDCLOCK: - case RSP_SUBCLOCKACK: - case RSP_GETCLOCKACK: - { - status = m_subclock.ack(e); // handle clock updates + case F_DISCONNECTED: + { + port.close(); + logMessage(cerr,formatString("Error: port '%s' disconnected.",port.getName().c_str())); + exit(EXIT_FAILURE); + } + break; - if (RSP_GETCLOCKACK == e.signal) { + case RSP_GETRCUACK: + case RSP_SETRCUACK: + case RSP_SETRSUACK: + case RSP_GETSTATSACK: + case RSP_SUBSTATSACK: + case RSP_UPDSTATS: + case RSP_SUBXCSTATSACK: + case RSP_UPDXCSTATS: + case RSP_GETVERSIONACK: + case RSP_GETSUBBANDSACK: + case RSP_SETSUBBANDSACK: + case RSP_SETWEIGHTSACK: + case RSP_GETWEIGHTSACK: + case RSP_GETWGACK: + case RSP_SETWGACK: + case RSP_SETCLOCKACK: + case RSP_GETSTATUSACK: + case RSP_GETTDSTATUSACK: + case RSP_SUBREGISTERSTATEACK: + case RSP_UPDREGISTERSTATE: + case RSP_SETHBAACK: + case RSP_GETHBAACK: + case RSP_READHBAACK: + case RSP_SETTBBACK: + case RSP_GETTBBACK: + case RSP_GETBYPASSACK: + case RSP_SETBYPASSACK: + status = m_command->ack(e); // handle the acknowledgement + break; - // reparse options - if (0 == (m_command = parse_options(m_argc, m_argv))) - { - logMessage(cerr,"Warning: no command specified."); - usage(); - exit(EXIT_FAILURE); - } - // check if a connection must be made with a frontend. If so, connect first - // and send the command to the rspdriver when connected with the frontend - FECommand* feCommand = dynamic_cast<FECommand*>(m_command); - if(feCommand != 0) - { - if(feCommand->isFrontEndSet()) - { - feCommand->connect(*this); - } - else - { - m_command->send(); + case RSP_UPDCLOCK: + case RSP_SUBCLOCKACK: + case RSP_GETCLOCKACK: + { + status = m_subclock.ack(e); // handle clock updates + + if (RSP_GETCLOCKACK == e.signal) { + // reparse options + if (0 == (m_command = parse_options(m_argc, m_argv))) { + logMessage(cerr,"Warning: no command specified."); + usage(); + exit(EXIT_FAILURE); + } + // check if a connection must be made with a frontend. If so, connect first + // and send the command to the rspdriver when connected with the frontend + FECommand* feCommand = dynamic_cast<FECommand*>(m_command); + if(feCommand != 0) { + if(feCommand->isFrontEndSet()) { + feCommand->connect(*this); + } + else { + m_command->send(); + } + } + else { + m_command->send(); + } } - } - else - { - m_command->send(); - } } - } - break; + break; #ifdef ENABLE_RSPFE - case RSPFE_STOP_RSPCTL: - logMessage(cout,"Rspctl stopped by frontend."); - m_command->stop(); - GCFTask::stop(); - break; + case RSPFE_STOP_RSPCTL: + logMessage(cout,"Rspctl stopped by frontend."); + m_command->stop(); + GCFTask::stop(); + break; #endif - default: - logMessage(cerr,"Error: unhandled event."); - GCFTask::stop(); - break; - } + default: + logMessage(cerr,"Error: unhandled event."); + GCFTask::stop(); + break; + } - return status; + return status; } void RSPCtl::mainloop() @@ -2289,17 +2322,10 @@ static void usage() { cout << "rspctl usage:" << endl; cout << endl; - cout << "rspctl --weights [--select=<set>] # get weights as complex values" << endl; - cout << " Example --weights --select=1,2,4:7 or --select=1:3,5:7" << endl; - cout << "rspctl --weights=value.re[,value.im][--select=<set>][--beamlets=<set>] # set weights as complex value" << endl; - cout << "rspctl --aweights [--select=<set>] # get weights as power and angle (in degrees)" << endl; - cout << "rspctl --aweights=amplitude[,angle] [--select=<set>] # set weights as amplitude and angle (in degrees)" << endl; - cout << "rspctl --subbands [--select=<set>] # get subband selection" << endl; - cout << "rspctl --subbands=<set> [--select=<set>] # set subband selection" << endl; - cout << " Example --subbands sets: --subbands=0:39 or --select=0:19,40:59" << endl; + cout << "--- RCU control ----------------------------------------------------------------------------------------------" << endl; cout << "rspctl --rcu [--select=<set>] # show current rcu control setting" << endl; cout << "rspctl --rcu=0x00000000 [--select=<set>] # set the rcu control registers" << endl; - cout << " mask value " << endl; + cout << " mask value " << endl; cout << " 0x0000007F INPUT_DELAY Sample delay for the data from the RCU." << endl; cout << " 0x00000080 INPUT_ENABLE Enable RCU input." << endl; cout << endl; @@ -2310,10 +2336,10 @@ static void usage() cout << " 0x00001000 HB-SEL-0 HBA filter selection" << endl; cout << " 0x00002000 HB-SEL-1 HBA filter selection" << endl; cout << " Options : HBA-SEL-0 HBA-SEL-1 Function" << endl; - cout << " 0 0 210-270 MHz" << endl; - cout << " 0 1 170-230 MHz" << endl; - cout << " 1 0 110-190 MHz" << endl; - cout << " 1 1 all off" << endl; + cout << " 0 0 210-270 MHz" << endl; + cout << " 0 1 170-230 MHz" << endl; + cout << " 1 0 110-190 MHz" << endl; + cout << " 1 1 all off" << endl; cout << " 0x00004000 VL-EN low band supply on (1) or off (0)" << endl; cout << " 0x00008000 VH-EN high band supply on (1) or off (0)" << endl; cout << endl; @@ -2357,10 +2383,30 @@ static void usage() cout << " --rcudelay=[0..127] # set the delay for rcu's" << endl; cout << " --rcuenable[=0] # enable (or disable) input from RCU's" << endl; cout << endl; - cout << "rspctl --wg [--select=<set>] # get waveform generator settings" << endl; + cout << "rspctl --specinv[=0] [--select=<set>] # enable (or disable) spectral inversion" << endl; + cout << endl; + cout << "--- Signalprocessing -----------------------------------------------------------------------------------------" << endl; + cout << "rspctl --weights [--select=<set>] # get weights as complex values" << endl; + cout << " Example --weights --select=1,2,4:7 or --select=1:3,5:7" << endl; + cout << "rspctl --weights=value.re[,value.im][--select=<set>][--beamlets=<set>] # set weights as complex value" << endl; + cout << "rspctl --aweights [--select=<set>] # get weights as power and angle (in degrees)" << endl; + cout << "rspctl --aweights=amplitude[,angle] [--select=<set>] # set weights as amplitude and angle (in degrees)" << endl; + cout << "rspctl --subbands [--select=<set>] # get subband selection" << endl; + cout << "rspctl --subbands=<set> [--select=<set>] # set subband selection" << endl; + cout << " Example --subbands sets: --subbands=0:39 or --select=0:19,40:59" << endl; + cout << "rspctl --xcsubband # get the subband selection for cross correlation" << endl; + cout << "rspctl --xcsubband=<int> # set the subband to cross correlate" << endl; + cout << "rspctl --wg [--select=<set>] # get waveform generator settings" << endl; cout << "rspctl --wg=freq [--phase=..] [--amplitude=..] [--select=<set>] # set waveform generator settings" << endl; + cout << endl; + cout << "--- Status info ----------------------------------------------------------------------------------------------" << endl; + cout << "rspctl --version [--select=<set>] # get version information" << endl; cout << "rspctl --status [--select=<set>] # get status of RSP boards" << endl; cout << "rspctl --tdstatus [--select=<set>] # get status of TD boards" << endl; + cout << "rspctl --realdelays[=<list>] [--select=<set>] # get the installed 16 delays of one or more HBA's" << endl; + cout << "rspctl --regstate # show update status of all registers once every second" << endl; + cout << endl; + cout << "--- Statistics -----------------------------------------------------------------------------------------------" << endl; cout << "rspctl --statistics[=(subband|beamlet)] # get subband (default) or beamlet statistics" << endl; cout << " [--select=<set>] #" << endl; cout << " [--duration=<seconds>] #" << endl; @@ -2376,658 +2422,651 @@ static void usage() #ifdef ENABLE_RSPFE cout << " [--feport=<hostname>:<port>] #" << endl; #endif - cout << "rspctl --xcsubband # get the subband selection for cross correlation" << endl; - cout << "rspctl --xcsubband=<int> # set the subband to cross correlate" << endl; + cout << endl; + cout << "--- Miscellaneous --------------------------------------------------------------------------------------------" << endl; cout << "rspctl --clock[=<int>] # get or set the clock frequency of clocks in MHz" << endl; + cout << "rspctl --rspclear [--select=<set>] # clear FPGA registers on RSPboard" << endl; cout << "rspctl --hbadelays[=<list>] [--select=<set>] # set or get the 16 delays of one or more HBA's" << endl; cout << "rspctl --tbbmode[=transient | =subbands,<set>] # set or get TBB mode, 'transient' or 'subbands', if subbands then specify subband set" << endl; - cout << "rspctl --version [--select=<set>] # get version information" << endl; - cout << "rspctl --rspclear [--select=<set>] # clear FPGA registers on RSPboard" << endl; - cout << "rspctl --regstate # show update status of all registers once every second" << endl; - cout << "rspctl --specinv[=0] [--select=<set>] # enable (or disable) spectral inversion" << endl; } Command* RSPCtl::parse_options(int argc, char** argv) { - Command* command = 0; - RCUCommand* rcumodecommand = 0; - HBACommand* hbacommand = 0; - list<int> select; - list<int> beamlets; - bool xcangle = false; + Command* command = 0; + RCUCommand* rcumodecommand = 0; + HBACommand* hbacommand = 0; + list<int> select; + list<int> beamlets; + bool xcangle = false; - // select all by default - select.clear(); - for (int i = 0; i < MEPHeader::MAX_N_RCUS; ++i) select.push_back(i); + // select all by default + select.clear(); + for (int i = 0; i < MEPHeader::MAX_N_RCUS; ++i) + select.push_back(i); beamlets.clear(); - for (int i = 0; i < MEPHeader::N_BEAMLETS; ++i) beamlets.push_back(i); - - optind = 0; // reset option parsing - //opterr = 0; // no error reporting to stderr - while (1) { - static struct option long_options[] = { - { "select", required_argument, 0, 'l' }, - { "beamlets", required_argument, 0, 'b' }, - { "weights", optional_argument, 0, 'w' }, - { "aweights", optional_argument, 0, 'a' }, - { "subbands", optional_argument, 0, 's' }, - { "rcu", optional_argument, 0, 'r' }, - { "rcumode", required_argument, 0, 'm' }, - { "rcuprsg", optional_argument, 0, 'p' }, - { "rcureset", optional_argument, 0, 'e' }, - { "rcuattenuation", required_argument, 0, 'n' }, - { "rcudelay", required_argument, 0, 'y' }, - { "rcuenable", optional_argument, 0, 'E' }, - { "wg", optional_argument, 0, 'g' }, - { "wgmode", required_argument, 0, 'G' }, - { "amplitude", required_argument, 0, 'A' }, - { "phase", required_argument, 0, 'P' }, - { "status", no_argument, 0, 'q' }, - { "tdstatus", no_argument, 0, 'Q' }, - { "statistics", optional_argument, 0, 't' }, - { "xcstatistics", no_argument, 0, 'x' }, - { "xcangle", no_argument, 0, 'B' }, - { "xcsubband", optional_argument, 0, 'z' }, - { "clock", optional_argument, 0, 'c' }, - { "hbadelays", optional_argument, 0, 'H' }, - { "tbbmode", optional_argument, 0, 'T' }, - { "version", no_argument, 0, 'v' }, - // { "rspreset", optional_argument, 0, 'R' }, - { "rspclear", optional_argument, 0, 'C' }, - { "regstate", no_argument, 0, 'S' }, - { "help", no_argument, 0, 'h' }, + for (int i = 0; i < MEPHeader::N_BEAMLETS; ++i) + beamlets.push_back(i); + + optind = 0; // reset option parsing + //opterr = 0; // no error reporting to stderr + static struct option long_options[] = { + { "aweights", optional_argument, 0, 'a' }, + { "beamlets", required_argument, 0, 'b' }, + { "clock", optional_argument, 0, 'c' }, + { "duration", required_argument, 0, 'd' }, + { "rcureset", optional_argument, 0, 'e' }, #ifdef ENABLE_RSPFE - { "feport", required_argument, 0, 'f' }, + { "feport", required_argument, 0, 'f' }, #endif - { "duration", required_argument, 0, 'd' }, - { "integration", required_argument, 0, 'i' }, - { "specinv", optional_argument, 0, 'I' }, -// { "instance", required_argument, 0, 'I' }, - { "directory" , required_argument, 0, 'D' }, - - { 0, 0, 0, 0 }, + { "wg", optional_argument, 0, 'g' }, + { "help", no_argument, 0, 'h' }, + { "integration", required_argument, 0, 'i' }, + { "select", required_argument, 0, 'l' }, + { "rcumode", required_argument, 0, 'm' }, + { "rcuattenuation", required_argument, 0, 'n' }, + { "rcuprsg", optional_argument, 0, 'p' }, + { "status", no_argument, 0, 'q' }, + { "rcu", optional_argument, 0, 'r' }, + { "subbands", optional_argument, 0, 's' }, + { "statistics", optional_argument, 0, 't' }, + { "version", no_argument, 0, 'v' }, + { "weights", optional_argument, 0, 'w' }, + { "xcstatistics", no_argument, 0, 'x' }, + { "rcudelay", required_argument, 0, 'y' }, + { "xcsubband", optional_argument, 0, 'z' }, + + { "amplitude", required_argument, 0, 'A' }, + { "xcangle", no_argument, 0, 'B' }, + { "rspclear", optional_argument, 0, 'C' }, + { "directory" , required_argument, 0, 'D' }, + { "rcuenable", optional_argument, 0, 'E' }, + { "wgmode", required_argument, 0, 'G' }, + { "hbadelays", optional_argument, 0, 'H' }, + { "specinv", optional_argument, 0, 'I' }, + { "phase", required_argument, 0, 'P' }, + { "tdstatus", no_argument, 0, 'Q' }, +// { "rspreset", optional_argument, 0, 'R' }, + { "realdelays", optional_argument, 0, 'R' }, + { "regstate", no_argument, 0, 'S' }, + { "tbbmode", optional_argument, 0, 'T' }, + + { 0, 0, 0, 0 }, }; - int option_index = 0; - int c = getopt_long(argc, argv, - "l:b:w::a::s::r::g::qQt::xz::vc::hf:d:i:I:", long_options, &option_index); + realDelays = false; + while (1) { + int option_index = 0; + int c = getopt_long(argc, argv, "l:b:w::a::s::r::g::qQt::xz::vc::hf:d:i:I:", long_options, &option_index); - if (c == -1) - break; + if (c == -1) // end of argument list reached? + break; - switch (c) - { - case 'l': // --select - if (optarg) { - if (!command || 0 == command->get_ndevices()) { - logMessage(cerr,"Error: 'command' argument should come before --select argument"); - exit(EXIT_FAILURE); - } - select = strtolist(optarg, command->get_ndevices()); - if (select.empty()) { - logMessage(cerr,"Error: invalid or missing '--select' option"); - exit(EXIT_FAILURE); - } - } - else { - logMessage(cerr,"Error: option '--select' requires an argument"); - } - break; + switch (c) { + case 'l': // --select + if (optarg) { + if (!command || 0 == command->get_ndevices()) { + logMessage(cerr,"Error: 'command' argument should come before --select argument"); + exit(EXIT_FAILURE); + } + select = strtolist(optarg, command->get_ndevices()); + if (select.empty()) { + logMessage(cerr,"Error: invalid or missing '--select' option"); + exit(EXIT_FAILURE); + } + } + else { + logMessage(cerr,"Error: option '--select' requires an argument"); + } + break; - case 'b': // --beamlets - if (optarg) { - if (!command || 0 == command->get_ndevices()) { - logMessage(cerr,"Error: 'command' argument should come before --beamlets argument"); - exit(EXIT_FAILURE); - } - beamlets = strtolist(optarg, MEPHeader::N_BEAMLETS); - if (beamlets.empty()) { - logMessage(cerr,"Error: invalid or missing '--beamlets' option"); - exit(EXIT_FAILURE); - } - - } - else { - logMessage(cerr,"Error: option '--beamlets' requires an argument"); - } - break; - - - case 'w': // --weights - { - if (command) - delete command; - WeightsCommand* weightscommand = new WeightsCommand(m_server); - weightscommand->setType(WeightsCommand::COMPLEX); - command = weightscommand; - - command->set_ndevices(m_nrcus); - - if (optarg) { - weightscommand->setMode(false); - double re = 0.0, im = 0.0; - int numitems = sscanf(optarg, "%lf,%lf", &re, &im); - if (numitems == 0 || numitems == EOF) { - logMessage(cerr,"Error: invalid weights value. Should be of the format " - "'--weights=value.re[,value.im]' where value is a floating point value in the range (-1,1]."); - exit(EXIT_FAILURE); - } - weightscommand->setValue(complex<double>(re,im)); - } - } - break; - - case 'a': // --aweights - { - if (command) - delete command; - WeightsCommand* weightscommand = new WeightsCommand(m_server); - weightscommand->setType(WeightsCommand::ANGLE); - command = weightscommand; - - command->set_ndevices(m_nrcus); - - if (optarg) { - weightscommand->setMode(false); - double amplitude = 0.0, angle = 0.0; - int numitems = sscanf(optarg, "%lf,%lf", &litude, &angle); - if (numitems == 0 || numitems == EOF) { - logMessage(cerr,"Error: invalid aweights value. Should be of the format " - "'--weights=amplitude[,angle]' where angle is in degrees."); - exit(EXIT_FAILURE); + case 'b': // --beamlets + if (optarg) { + if (!command || 0 == command->get_ndevices()) { + logMessage(cerr,"Error: 'command' argument should come before --beamlets argument"); + exit(EXIT_FAILURE); + } + beamlets = strtolist(optarg, MEPHeader::N_BEAMLETS); + if (beamlets.empty()) { + logMessage(cerr,"Error: invalid or missing '--beamlets' option"); + exit(EXIT_FAILURE); + } + } + else { + logMessage(cerr,"Error: option '--beamlets' requires an argument"); + } + break; + + case 'w': // --weights + { + if (command) + delete command; + WeightsCommand* weightscommand = new WeightsCommand(m_server); + weightscommand->setType(WeightsCommand::COMPLEX); + command = weightscommand; + + command->set_ndevices(m_nrcus); + + if (optarg) { + weightscommand->setMode(false); + double re = 0.0, im = 0.0; + int numitems = sscanf(optarg, "%lf,%lf", &re, &im); + if (numitems == 0 || numitems == EOF) { + logMessage(cerr,"Error: invalid weights value. Should be of the format " + "'--weights=value.re[,value.im]' where value is a floating point value in the range (-1,1]."); + exit(EXIT_FAILURE); + } + weightscommand->setValue(complex<double>(re,im)); + } } - - if (angle < -180.0 || angle > 180.0) { - logMessage(cerr, "Error: invalid angle, should be between -180 < angle < 180.0."); - exit(EXIT_FAILURE); + break; + + case 'a': // --aweights + { + if (command) + delete command; + WeightsCommand* weightscommand = new WeightsCommand(m_server); + weightscommand->setType(WeightsCommand::ANGLE); + command = weightscommand; + + command->set_ndevices(m_nrcus); + + if (optarg) { + weightscommand->setMode(false); + double amplitude = 0.0, angle = 0.0; + int numitems = sscanf(optarg, "%lf,%lf", &litude, &angle); + if (numitems == 0 || numitems == EOF) { + logMessage(cerr,"Error: invalid aweights value. Should be of the format " + "'--weights=amplitude[,angle]' where angle is in degrees."); + exit(EXIT_FAILURE); + } + + if (angle < -180.0 || angle > 180.0) { + logMessage(cerr, "Error: invalid angle, should be between -180 < angle < 180.0."); + exit(EXIT_FAILURE); + } + + //weightscommand->setValue(complex<double>(amplitude * ::cos(angle), amplitude * ::sin(angle))); + weightscommand->setValue(amplitude * exp(complex<double>(0,angle / 180.0 * M_PI))); + } } - - //weightscommand->setValue(complex<double>(amplitude * ::cos(angle), amplitude * ::sin(angle))); - weightscommand->setValue(amplitude * exp(complex<double>(0,angle / 180.0 * M_PI))); - } - } - break; - - case 's': // --subbands - { - if (command) - delete command; - SubbandsCommand* subbandscommand = new SubbandsCommand(m_server); - subbandscommand->setType(SubbandSelection::BEAMLET); - - command = subbandscommand; - command->set_ndevices(m_nrcus); - - if (optarg) { - subbandscommand->setMode(false); - list<int> subbandlist = strtolist(optarg, MEPHeader::N_SUBBANDS); - if (subbandlist.empty()) { - logMessage(cerr,"Error: invalid or empty '--subbands' option"); - exit(EXIT_FAILURE); + break; + + case 's': // --subbands + { + if (command) + delete command; + SubbandsCommand* subbandscommand = new SubbandsCommand(m_server); + subbandscommand->setType(SubbandSelection::BEAMLET); + + command = subbandscommand; + command->set_ndevices(m_nrcus); + + if (optarg) { + subbandscommand->setMode(false); + list<int> subbandlist = strtolist(optarg, MEPHeader::N_SUBBANDS); + if (subbandlist.empty()) { + logMessage(cerr,"Error: invalid or empty '--subbands' option"); + exit(EXIT_FAILURE); + } + subbandscommand->setSubbandList(subbandlist); + } } - subbandscommand->setSubbandList(subbandlist); - } - } - break; - - case 'r': // --rcu - { - if (command) - delete command; - RCUCommand* rcucommand = new RCUCommand(m_server); - command = rcucommand; - - command->set_ndevices(m_nrcus); - - if (optarg) { - rcucommand->setMode(false); - unsigned long controlopt = strtoul(optarg, 0, 0); - if ( controlopt > 0xFFFFFFFF ) { - logMessage(cerr,"Error: option '--rcu' parameter must be < 0xFFFFFFFF"); - delete command; - return 0; + break; + + case 'r': // --rcu + { + if (command) + delete command; + RCUCommand* rcucommand = new RCUCommand(m_server); + command = rcucommand; + + command->set_ndevices(m_nrcus); + + if (optarg) { + rcucommand->setMode(false); + unsigned long controlopt = strtoul(optarg, 0, 0); + if (controlopt > 0xFFFFFFFF) { + logMessage(cerr,"Error: option '--rcu' parameter must be < 0xFFFFFFFF"); + delete command; + return 0; + } + + rcucommand->control().setRaw((uint32)controlopt); + } } + break; - rcucommand->control().setRaw((uint32)controlopt); - } - } - break; - - case 'm': // --rcumode - case 'p': // --rcuprsg - case 'e': // --rcureset - case 'n': // --rcuattenuation -// case 'u': // --rcuspecinv - case 'y': // --rcudelay - case 'E': // --rcuenable - { - // instantiate once, then reuse to add control bits - if (!rcumodecommand) { - if (command) delete command; - rcumodecommand = new RCUCommand(m_server); - } + case 'm': // --rcumode + case 'p': // --rcuprsg + case 'e': // --rcureset + case 'n': // --rcuattenuation + case 'y': // --rcudelay + case 'E': // --rcuenable + { + // instantiate once, then reuse to add control bits + if (!rcumodecommand) { + if (command) + delete command; + rcumodecommand = new RCUCommand(m_server); + } - command = rcumodecommand; - command->set_ndevices(m_nrcus); + command = rcumodecommand; + command->set_ndevices(m_nrcus); - if ('m' == c || 'n' == c || 'y' == c) { - if (!optarg) { - logMessage(cerr,"Error: option requires an argument"); - delete command; - return 0; - } - } + if ('m' == c || 'n' == c || 'y' == c) { + if (!optarg) { + logMessage(cerr,"Error: option requires an argument"); + delete command; + return 0; + } + } - rcumodecommand->setMode(false); - unsigned long controlopt = 0; + rcumodecommand->setMode(false); + unsigned long controlopt = 0; - switch (c) { + switch (c) { + case 'm': // --rcumode + controlopt = strtoul(optarg, 0, 0); + if (controlopt >= 8) { + logMessage(cerr,"Error: --rcumode value should be < 8"); + delete command; + return 0; + } + rcumodecommand->control().setMode((RCUSettings::Control::RCUMode)controlopt); + break; - case 'm': // --rcumode - controlopt = strtoul(optarg, 0, 0); - if (controlopt >= 8) { - logMessage(cerr,"Error: --rcumode value should be < 8"); - delete command; - return 0; - } - rcumodecommand->control().setMode((RCUSettings::Control::RCUMode)controlopt); - break; + case 'p': // --rcuprsg + if (optarg && !strncmp(optarg, "0", 1)) { + rcumodecommand->control().setPRSG(false); + } else { + rcumodecommand->control().setPRSG(true); + } + break; - case 'p': // --rcuprsg - if (optarg && !strncmp(optarg, "0", 1)) { - rcumodecommand->control().setPRSG(false); - } else { - rcumodecommand->control().setPRSG(true); - } - break; + case 'e': // --rcureset + if (optarg && !strncmp(optarg, "0", 1)) { + rcumodecommand->control().setReset(false); + } else { + rcumodecommand->control().setReset(true); + } + break; - case 'e': // --rcureset - if (optarg && !strncmp(optarg, "0", 1)) { - rcumodecommand->control().setReset(false); - } else { - rcumodecommand->control().setReset(true); - } - break; - - case 'n': // --rcuattenuation - controlopt = strtoul(optarg, 0, 0); - if (controlopt > 31) { - logMessage(cerr,"Error: --rcuattenuation value should be <= 31"); - delete command; - return 0; - } - rcumodecommand->control().setAttenuation((uint8)controlopt); - break; - -// case 'u': // --rcuspecinv -// if (optarg && !strncmp(optarg, "0", 1)) { -// rcumodecommand->control().setSpecinv(false); -// } else { -// rcumodecommand->control().setSpecinv(true); -// } -// break; - - case 'y': // --rcudelay - controlopt = strtoul(optarg, 0, 0); - if (controlopt > 127) { - logMessage(cerr,"Error: --rcudelay value should be <= 127"); - delete command; - return 0; - } - rcumodecommand->control().setDelay((uint8)controlopt); - break; + case 'n': // --rcuattenuation + controlopt = strtoul(optarg, 0, 0); + if (controlopt > 31) { + logMessage(cerr,"Error: --rcuattenuation value should be <= 31"); + delete command; + return 0; + } + rcumodecommand->control().setAttenuation((uint8)controlopt); + break; - case 'E': // --rcuenable - if (optarg && !strncmp(optarg, "0", 1)) { - rcumodecommand->control().setEnable(false); - } else { - rcumodecommand->control().setEnable(true); - } - break; - } + case 'y': // --rcudelay + controlopt = strtoul(optarg, 0, 0); + if (controlopt > 127) { + logMessage(cerr,"Error: --rcudelay value should be <= 127"); + delete command; + return 0; + } + rcumodecommand->control().setDelay((uint8)controlopt); + break; - } - break; - - case 'g': // --wg - { - if (command) - delete command; - WGCommand* wgcommand = new WGCommand(m_server); - command = wgcommand; - - command->set_ndevices(m_nrcus); - - if (optarg) { - wgcommand->setMode(false); - double frequency = atof(optarg); - if ( frequency < 0 ) { - logMessage(cerr,"Error: option '--wg' parameter must be > 0"); - delete command; - return 0; - } - wgcommand->setFrequency(frequency, g_sample_frequency); - } - } - break; - - case 'G': // --wgmode - { - if (optarg) { - int mode = atoi(optarg); - if (mode != 0 && mode != 1 && mode != 3 && mode != 5) { - logMessage(cerr,"Error: option '--wgmode' parameter must be 0,1,3 or 5"); - delete command; - return 0; - } - WGCommand* wgcommand = dynamic_cast<WGCommand*>(command); - wgcommand->setWaveMode(mode); - } - } - break; - - case 'P': // --phase - { - if (optarg) { - double phase = atof(optarg); - if (phase < 0 || phase > (M_PI * 2.0)) { - logMessage(cerr,"Error: option '--phase' parameter must be between 0 and 2 pi"); - delete command; - return 0; - } - WGCommand* wgcommand = dynamic_cast<WGCommand*>(command); - wgcommand->setPhase((uint8)((phase / (2 * M_PI)) * (1 << 8))); - } - } - break; - - case 'A': // --amplitude - { - if (optarg) { - double amplitude = atof(optarg); - if (amplitude > 2.0 || amplitude < 0.0) { - logMessage(cerr, "Error: option '--amplitude' paramter must be >= 0 and <= 1.0"); - delete command; - return 0; - } - WGCommand *wgcommand = dynamic_cast<WGCommand*>(command); - wgcommand->setAmplitude(amplitude); - } - } - break; + case 'E': // --rcuenable + if (optarg && !strncmp(optarg, "0", 1)) { + rcumodecommand->control().setEnable(false); + } else { + rcumodecommand->control().setEnable(true); + } + break; + } // switch - case 'q' : // --status - { - if (command) - delete command; - StatusCommand* statuscommand = new StatusCommand(m_server); - command = statuscommand; + } + break; - command->set_ndevices(m_nrspboards); - } - break; - - case 'Q': // --tdstatus - { - if (command) delete command; - TDStatusCommand* tdstatuscommand = new TDStatusCommand(m_server); - command = tdstatuscommand; - command->set_ndevices(m_nrspboards); - } - break; - - case 't': // --statistics - { - if (command) - delete command; - StatisticsCommand* statscommand = new StatisticsCommand(m_server); - command = statscommand; - - command->set_ndevices(m_nrcus); - - if (optarg) { - if (!strcmp(optarg, "subband")) { - statscommand->setType(Statistics::SUBBAND_POWER); - } else if (!strcmp(optarg, "beamlet")) { - command->set_ndevices(m_nrspboards * MEPHeader::N_POL); - statscommand->setType(Statistics::BEAMLET_POWER); - } else { - logMessage(cerr, formatString("Error: invalid statistics type %s", optarg)); - exit(EXIT_FAILURE); + case 'g': // --wg + { + if (command) + delete command; + WGCommand* wgcommand = new WGCommand(m_server); + command = wgcommand; + + command->set_ndevices(m_nrcus); + + if (optarg) { + wgcommand->setMode(false); + double frequency = atof(optarg); + if ( frequency < 0 ) { + logMessage(cerr,"Error: option '--wg' parameter must be > 0"); + delete command; + return 0; + } + wgcommand->setFrequency(frequency, g_sample_frequency); + } } - } - } - break; - case 'B': - { - xcangle = true; - } - break; - - case 'x': // -- xcstatistics - { - if (command) - delete command; - XCStatisticsCommand* xcstatscommand = new XCStatisticsCommand(m_server); - xcstatscommand->setAngle(xcangle); - command = xcstatscommand; - command->set_ndevices(m_nrspboards); - } - break; + break; - case 'z': // -- xcsubbands - { - if (command) - delete command; - SubbandsCommand* subbandscommand = new SubbandsCommand(m_server); - subbandscommand->setType(SubbandSelection::XLET); - command = subbandscommand; + case 'G': // --wgmode + { + if (optarg) { + int mode = atoi(optarg); + if (mode != 0 && mode != 1 && mode != 3 && mode != 5) { + logMessage(cerr,"Error: option '--wgmode' parameter must be 0,1,3 or 5"); + delete command; + return 0; + } + WGCommand* wgcommand = dynamic_cast<WGCommand*>(command); + wgcommand->setWaveMode(mode); + } + } + break; - command->set_ndevices(m_nrcus); + case 'P': // --phase + { + if (optarg) { + double phase = atof(optarg); + if (phase < 0 || phase > (M_PI * 2.0)) { + logMessage(cerr,"Error: option '--phase' parameter must be between 0 and 2 pi"); + delete command; + return 0; + } + WGCommand* wgcommand = dynamic_cast<WGCommand*>(command); + wgcommand->setPhase((uint8)((phase / (2 * M_PI)) * (1 << 8))); + } + } + break; - if (optarg) { - subbandscommand->setMode(false); + case 'A': // --amplitude + { + if (optarg) { + double amplitude = atof(optarg); + if (amplitude > 2.0 || amplitude < 0.0) { + logMessage(cerr, "Error: option '--amplitude' paramter must be >= 0 and <= 1.0"); + delete command; + return 0; + } + WGCommand *wgcommand = dynamic_cast<WGCommand*>(command); + wgcommand->setAmplitude(amplitude); + } + } + break; - int subband = atoi(optarg); + case 'q' : // --status + { + if (command) + delete command; + StatusCommand* statuscommand = new StatusCommand(m_server); + command = statuscommand; - if (subband < 0 || subband >= MEPHeader::N_SUBBANDS) { - logMessage(cerr,formatString("Error: argument to --xcsubband out of range, value must be >= 0 and < %d",MEPHeader::N_SUBBANDS)); - exit(EXIT_FAILURE); + command->set_ndevices(m_nrspboards); } + break; - list<int> subbandlist; - for (int rcu = 0; rcu < m_nrcus / MEPHeader::N_POL; rcu++) { - subbandlist.push_back(subband); + case 'Q': // --tdstatus + { + if (command) + delete command; + TDStatusCommand* tdstatuscommand = new TDStatusCommand(m_server); + command = tdstatuscommand; + command->set_ndevices(m_nrspboards); } - subbandscommand->setSubbandList(subbandlist); - } - } - break; - - case 'c': // --clock - { - if (command) - delete command; - ClockCommand* clockcommand = new ClockCommand(m_server); - command = clockcommand; - - command->set_ndevices(m_nrspboards); - - if (optarg) { - clockcommand->setMode(false); - double clock = atof(optarg); - if ( 0 != (uint32)clock && 160 != (uint32)clock && 200 != (uint32)clock) - { - logMessage(cerr,"Error: option '--clocks' parameter must be 0 (off), 160 (MHz) or 200 (MHz)"); - delete command; - return 0; - } - clockcommand->setClock((uint32)clock); + break; - } - } - break; - - case 'C': // --rspclear - { - if (command) - delete command; - RSUCommand* rsucommand = new RSUCommand(m_server); - command = rsucommand; - command->set_ndevices(m_nrspboards); - - rsucommand->setMode(false); // is a SET command - rsucommand->control().setClear(true); - } - break; + case 't': // --statistics + { + if (command) + delete command; + StatisticsCommand* statscommand = new StatisticsCommand(m_server); + command = statscommand; + + command->set_ndevices(m_nrcus); + + if (optarg) { + if (!strcmp(optarg, "subband")) { + statscommand->setType(Statistics::SUBBAND_POWER); + } else if (!strcmp(optarg, "beamlet")) { + command->set_ndevices(m_nrspboards * MEPHeader::N_POL); + statscommand->setType(Statistics::BEAMLET_POWER); + } else { + logMessage(cerr, formatString("Error: invalid statistics type %s", optarg)); + exit(EXIT_FAILURE); + } + } + } + break; - case 'S': // --regstate - { - if (command) delete command; - RegisterStateCommand* regstatecommand = new RegisterStateCommand(m_server); - command = regstatecommand; - } - break; - - case 'v': // --version - { - if (command) - delete command; - VersionCommand* versioncommand = new VersionCommand(m_server); - command = versioncommand; - command->set_ndevices(m_nrspboards); - } - break; + case 'B': + { + xcangle = true; + } + break; - case 'H': // --hbadelays - { - if (!hbacommand) { - if (command) delete command; - hbacommand = new HBACommand(m_server); - } + case 'x': // -- xcstatistics + { + if (command) + delete command; + XCStatisticsCommand* xcstatscommand = new XCStatisticsCommand(m_server); + xcstatscommand->setAngle(xcangle); + command = xcstatscommand; + command->set_ndevices(m_nrspboards); + } + break; - command = hbacommand; - command->set_ndevices(m_nrcus); + case 'z': // -- xcsubbands + { + if (command) + delete command; + SubbandsCommand* subbandscommand = new SubbandsCommand(m_server); + subbandscommand->setType(SubbandSelection::XLET); + command = subbandscommand; - if (optarg) { - hbacommand->setMode(false); // set the HBA delays + command->set_ndevices(m_nrcus); - hbacommand->setDelayList(strtolist(optarg, (uint8)-1)); - } - } - break; - - case 'T': // --tbbmode - { - if (command) delete command; - TBBCommand* tbbcommand = new TBBCommand(m_server); - command = tbbcommand; - - command->set_ndevices(m_nrcus); - - if (optarg) { - tbbcommand->setMode(false); - if (!strcmp(optarg, "transient")) { - tbbcommand->setType(TBBCommand::TRANSIENT); - } else if (!strncmp(optarg, "subbands", strlen("subbands"))) { - tbbcommand->setType(TBBCommand::SUBBANDS); - - char* liststring = strchr(optarg, ','); - liststring++; // skip the , - if (liststring && *liststring) { - list<int> subbandlist = strtolist(liststring, MEPHeader::N_SUBBANDS); - if (subbandlist.empty()) { - logMessage(cerr,"Error: missing or invalid subband set '--tbbmode=subbands' option"); - exit(EXIT_FAILURE); - } - tbbcommand->setSubbandSet(subbandlist); - } else { - logMessage(cerr,"Error: missing or invalid subband set '--tbbmode=subbands' option"); - } - } else { - logMessage(cerr, formatString("Error: invalid statistics type %s", optarg)); - exit(EXIT_FAILURE); + if (optarg) { + subbandscommand->setMode(false); + + int subband = atoi(optarg); + + if (subband < 0 || subband >= MEPHeader::N_SUBBANDS) { + logMessage(cerr,formatString("Error: argument to --xcsubband out of range, value must be >= 0 and < %d",MEPHeader::N_SUBBANDS)); + exit(EXIT_FAILURE); + } + + list<int> subbandlist; + for (int rcu = 0; rcu < m_nrcus / MEPHeader::N_POL; rcu++) { + subbandlist.push_back(subband); + } + subbandscommand->setSubbandList(subbandlist); + } } - } - } - break; + break; + + case 'c': // --clock + { + if (command) + delete command; + ClockCommand* clockcommand = new ClockCommand(m_server); + command = clockcommand; + + command->set_ndevices(m_nrspboards); + + if (optarg) { + clockcommand->setMode(false); + double clock = atof(optarg); + if ( 0 != (uint32)clock && 160 != (uint32)clock && 200 != (uint32)clock) { + logMessage(cerr,"Error: option '--clocks' parameter must be 0 (off), 160 (MHz) or 200 (MHz)"); + delete command; + return 0; + } + clockcommand->setClock((uint32)clock); + } + } + break; + + case 'C': // --rspclear + { + if (command) + delete command; + RSUCommand* rsucommand = new RSUCommand(m_server); + command = rsucommand; + command->set_ndevices(m_nrspboards); + + rsucommand->setMode(false); // is a SET command + rsucommand->control().setClear(true); + } + break; - case 'I': // --spectral Inversion - { - if (command) - delete command; - SICommand* specInvCmd = new SICommand(m_server); - command = specInvCmd; + case 'S': // --regstate + { + if (command) + delete command; + RegisterStateCommand* regstatecommand = new RegisterStateCommand(m_server); + command = regstatecommand; + } + break; - command->set_ndevices(m_nrcus); + case 'v': // --version + { + if (command) + delete command; + VersionCommand* versioncommand = new VersionCommand(m_server); + command = versioncommand; + command->set_ndevices(m_nrspboards); + } + break; - if (optarg) { - specInvCmd->setMode(false); - specInvCmd->setSI(strncmp(optarg, "0", 1)); - } - } - break; + case 'R': // --realdelays + realDelays = true; + // no break!!! + case 'H': // --hbadelays + { + if (!hbacommand) { + if (command) + delete command; + hbacommand = new HBACommand(m_server); + } - case 'h': // --help - usage(); - break; + command = hbacommand; + command->set_ndevices(m_nrcus); -#ifdef ENABLE_RSPFE - case 'f': // --feport - if (optarg) { - if (!command || 0 == command->get_ndevices()) { - logMessage(cerr,"Error: 'command' argument should come before --feport argument"); - exit(EXIT_FAILURE); + if (optarg) { + hbacommand->setMode(false); // set the HBA delays + hbacommand->setDelayList(strtolist(optarg, (uint8)-1)); + } } - FECommand* feCommand = dynamic_cast<FECommand*>(command); - if (feCommand == 0) { - logMessage(cerr,"Error: 'feport' argument can not be used in conjunction with the specified command"); - exit(EXIT_FAILURE); + break; + + case 'T': // --tbbmode + { + if (command) + delete command; + TBBCommand* tbbcommand = new TBBCommand(m_server); + command = tbbcommand; + + command->set_ndevices(m_nrcus); + + if (optarg) { + tbbcommand->setMode(false); + if (!strcmp(optarg, "transient")) { + tbbcommand->setType(TBBCommand::TRANSIENT); + } else if (!strncmp(optarg, "subbands", strlen("subbands"))) { + tbbcommand->setType(TBBCommand::SUBBANDS); + + char* liststring = strchr(optarg, ','); + liststring++; // skip the , + if (liststring && *liststring) { + list<int> subbandlist = strtolist(liststring, MEPHeader::N_SUBBANDS); + if (subbandlist.empty()) { + logMessage(cerr,"Error: missing or invalid subband set '--tbbmode=subbands' option"); + exit(EXIT_FAILURE); + } + tbbcommand->setSubbandSet(subbandlist); + } else { + logMessage(cerr,"Error: missing or invalid subband set '--tbbmode=subbands' option"); + } + } else { + logMessage(cerr, formatString("Error: invalid statistics type %s", optarg)); + exit(EXIT_FAILURE); + } + } } - feCommand->setFrontEnd(optarg); - } - else { - logMessage(cerr,"Error: option '--feport' requires an argument"); - } - break; + break; + + case 'I': // --spectral Inversion + { + if (command) + delete command; + SICommand* specInvCmd = new SICommand(m_server); + command = specInvCmd; + + command->set_ndevices(m_nrcus); + + if (optarg) { + specInvCmd->setMode(false); + specInvCmd->setSI(strncmp(optarg, "0", 1)); + } + } + break; + + case 'h': // --help + usage(); + break; + +#ifdef ENABLE_RSPFE + case 'f': // --feport + if (optarg) { + if (!command || 0 == command->get_ndevices()) { + logMessage(cerr,"Error: 'command' argument should come before --feport argument"); + exit(EXIT_FAILURE); + } + FECommand* feCommand = dynamic_cast<FECommand*>(command); + if (feCommand == 0) { + logMessage(cerr,"Error: 'feport' argument can not be used in conjunction with the specified command"); + exit(EXIT_FAILURE); + } + feCommand->setFrontEnd(optarg); + } + else { + logMessage(cerr,"Error: option '--feport' requires an argument"); + } + break; #endif - case 'd': // --duration - if (optarg) { - if (!command || 0 == command->get_ndevices()) { - logMessage(cerr,"Error: 'command' argument should come before --duration argument"); - exit(EXIT_FAILURE); - } - StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command); - if (statisticsBaseCommand == 0) { - logMessage(cerr,"Error: 'duration' argument can not be used in conjunction with the specified command"); - exit(EXIT_FAILURE); - } - statisticsBaseCommand->setDuration(atoi(optarg)); - } - else { - logMessage(cerr,"Error: option '--duration' requires an argument"); - } - break; + case 'd': // --duration + if (optarg) { + if (!command || 0 == command->get_ndevices()) { + logMessage(cerr,"Error: 'command' argument should come before --duration argument"); + exit(EXIT_FAILURE); + } + StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command); + if (statisticsBaseCommand == 0) { + logMessage(cerr,"Error: 'duration' argument can not be used in conjunction with the specified command"); + exit(EXIT_FAILURE); + } + statisticsBaseCommand->setDuration(atoi(optarg)); + } + else { + logMessage(cerr,"Error: option '--duration' requires an argument"); + } + break; - case 'i': // -- integration - if (optarg) { - if (!command || 0 == command->get_ndevices()) { - logMessage(cerr,"Error: 'command' argument should come before --integration argument"); - exit(EXIT_FAILURE); - } - StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command); - if (statisticsBaseCommand == 0) { - logMessage(cerr,"Error: 'integration' argument can not be used in conjunction with the specified command"); - exit(EXIT_FAILURE); - } - statisticsBaseCommand->setIntegration(atoi(optarg)); - } - else { - logMessage(cerr,"Error: option '--integration' requires an argument"); - } - break; + case 'i': // -- integration + if (optarg) { + if (!command || 0 == command->get_ndevices()) { + logMessage(cerr,"Error: 'command' argument should come before --integration argument"); + exit(EXIT_FAILURE); + } + StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command); + if (statisticsBaseCommand == 0) { + logMessage(cerr,"Error: 'integration' argument can not be used in conjunction with the specified command"); + exit(EXIT_FAILURE); + } + statisticsBaseCommand->setIntegration(atoi(optarg)); + } + else { + logMessage(cerr,"Error: option '--integration' requires an argument"); + } + break; // case 'I': // -- instance // if (optarg) { @@ -3038,38 +3077,38 @@ Command* RSPCtl::parse_options(int argc, char** argv) // } // break; - case 'D': // -- directory - if (optarg) { - if (!command || 0 == command->get_ndevices()) { - logMessage(cerr,"Error: 'command' argument should come before --directory argument"); - exit(EXIT_FAILURE); - } - StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command); - if (statisticsBaseCommand == 0) { - logMessage(cerr,"Error: 'directory' argument can not be used in conjunction with the specified command"); - exit(EXIT_FAILURE); - } - statisticsBaseCommand->setDirectory(optarg); - } - else { - logMessage(cerr,"Error: option '--directory' requires an argument"); - } - break; + case 'D': // -- directory + if (optarg) { + if (!command || 0 == command->get_ndevices()) { + logMessage(cerr,"Error: 'command' argument should come before --directory argument"); + exit(EXIT_FAILURE); + } + StatisticsBaseCommand* statisticsBaseCommand = dynamic_cast<StatisticsBaseCommand*>(command); + if (statisticsBaseCommand == 0) { + logMessage(cerr,"Error: 'directory' argument can not be used in conjunction with the specified command"); + exit(EXIT_FAILURE); + } + statisticsBaseCommand->setDirectory(optarg); + } + else { + logMessage(cerr,"Error: option '--directory' requires an argument"); + } + break; - case '?': - default: - logMessage(cerr, "Error: invalid option"); - exit(EXIT_FAILURE); - break; - } + case '?': + default: + logMessage(cerr, "Error: invalid option"); + exit(EXIT_FAILURE); + break; + } } - if (command) { - command->setSelect(select); - command->setBeamlets(beamlets); - } + if (command) { + command->setSelect(select); + command->setBeamlets(beamlets); + } - return command; + return (command); } std::list<int> RSPCtl::strtolist(const char* str, int max) @@ -3143,7 +3182,7 @@ void RSPCtl::logMessage(ostream& stream, const string& message) int main(int argc, char** argv) { - GCFTask::init(argc, argv); + GCFTask::init(argc, argv, "rspctl"); LOG_INFO(formatString("Program %s has started", argv[0])); diff --git a/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot b/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot index eddde48b55f..80acb10d617 100644 --- a/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot +++ b/MAC/APL/PIC/RSP_Protocol/src/RSP_Protocol.prot @@ -125,6 +125,8 @@ static const int FAILURE = 0; // SETHBAACK (timestamp, status) // GETHBA (timestamp, rcumask,cache) // GETHBAACK (timestamp, status, settings) +// READHBA (timestamp, rcumask,cache) +// READHBAACK (timestamp, status, settings) // SUBHBA (timestamp, rcumask,period) // SUBHBAACK (timestamp, status, handle) // UPDHBA (timestamp, status, handle, settings) @@ -1423,6 +1425,43 @@ event = { }; }; +event = { + signal = READHBA; + dir = IN; + param = { + name = "timestamp"; + type = "RTC::Timestamp"; + userdefined; + }; + param = { + name = "rcumask"; + type = "bitset<MEPHeader::MAX_N_RCUS>"; + }; + param = { + name = "cache"; + type = "uint8"; + }; +}; + +event = { + signal = READHBAACK; + dir = OUT; + param = { + name = "timestamp"; + type = "RTC::Timestamp"; + userdefined; + }; + param = { + name = "status"; + type = "int16"; + }; + param = { + name = "settings"; + type = "HBASettings"; + userdefined; + }; +}; + event = { signal = SUBHBA; dir = IN; diff --git a/MAC/MACIO/include/MACIO/MACServiceInfo.h b/MAC/MACIO/include/MACIO/MACServiceInfo.h index 7f2c20aed8b..306451cce8e 100644 --- a/MAC/MACIO/include/MACIO/MACServiceInfo.h +++ b/MAC/MACIO/include/MACIO/MACServiceInfo.h @@ -42,7 +42,7 @@ namespace LOFAR { #define MAC_SERVICEBROKER_PORT 24000 // Define names for the services -#define MAC_SVCMASK_RSPDRIVER "RSPDriver%s:acceptor_v3" +#define MAC_SVCMASK_RSPDRIVER "RSPDriver%s:acceptor_v3.1" #define MAC_SVCMASK_CALSERVER "CalServer%s:acceptor_v2" #define MAC_SVCMASK_BEAMSERVER "BeamServer%s:acceptor_v2" #define MAC_SVCMASK_TBBDRIVER "TBBDriver%s:acceptor" -- GitLab