diff --git a/include/Alf/Lla.h b/include/Alf/Lla.h index adef0b1..87ebad4 100644 --- a/include/Alf/Lla.h +++ b/include/Alf/Lla.h @@ -33,7 +33,7 @@ class LlaSession LlaSession(std::shared_ptr llaSession); LlaSession(std::string sessionName, roc::SerialId serialId); ~LlaSession(); - void start(); + void start(int timeout=0); void stop(); private: diff --git a/include/Alf/Sca.h b/include/Alf/Sca.h index fb6ca4f..1b6f2bb 100644 --- a/include/Alf/Sca.h +++ b/include/Alf/Sca.h @@ -86,19 +86,21 @@ class Sca : public ScBase /// Executes an SCA command /// \param commandData SCA command, data pair /// \param lock Boolean enabling implicit locking + /// \param lockTimeout timeout (in ms) for aquiring the lock /// \throws o2::lla::LlaException on lock fail, /// o2::alf::ScaException on SCA error - CommandData executeCommand(CommandData commandData, bool lock = false) + CommandData executeCommand(CommandData commandData, bool lock = false, int lockTimeout = 0) { - return executeCommand(commandData.command, commandData.data, lock); + return executeCommand(commandData.command, commandData.data, lock, lockTimeout); } /// Executes an SCA command /// \param command SCA command /// \param data SCA data /// \param lock Boolean enabling implicit locking + /// \param lockTimeout timeout (in ms) for aquiring the lock /// \throws o2::lla::LlaException on lock fail /// o2::alf::ScaException on SCA error - CommandData executeCommand(uint32_t command, uint32_t data, bool lock = false); + CommandData executeCommand(uint32_t command, uint32_t data, bool lock = false, int lockTimeout = 0); /// Executes an SCA sequence /// \param operations A vector of Operation and Data pairs @@ -108,7 +110,7 @@ class Sca : public ScBase /// WaitTime for Waits /// std::string for Errors /// \throws o2::lla::LlaException on lock fail - std::vector> executeSequence(const std::vector>& operations, bool lock = false); + std::vector> executeSequence(const std::vector>& operations, bool lock = false, int lockTimeout = 0); /// Executes an SCA sequence for the ALF Server /// \param operations A vector of Data and Operation pairs @@ -116,7 +118,7 @@ class Sca : public ScBase /// \return A string of newline separated results; /// \throws o2::lla::LlaException on lock fail /// o2::alf::ScaException on invalid operation or error - std::string writeSequence(const std::vector>& operations, bool lock = false); + std::string writeSequence(const std::vector>& operations, bool lock = false, int lockTimeout = 0); static std::string ScaOperationToString(Operation op); static Sca::Operation StringToScaOperation(std::string op); diff --git a/include/Alf/Swt.h b/include/Alf/Swt.h index 34195a3..7904865 100644 --- a/include/Alf/Swt.h +++ b/include/Alf/Swt.h @@ -92,20 +92,24 @@ class Swt : public ScBase /// Executes an SWT sequence /// \param sequence A vector of Operation and Data pairs + /// \param lock Boolean enabling implicit locking + /// \param lockTimeout timeout (in ms) for aquiring the lock /// \return A vector of Operation and resulting Data pairs /// Write -> Echoes written data /// Read -> The SwtWord read /// Reset -> Empty Data /// Error -> Error message in std::string /// \throws o2:lla::LlaException on lock fail - std::vector> executeSequence(std::vector> sequence, bool lock = false); + std::vector> executeSequence(std::vector> sequence, bool lock = false, int lockTimeout = 0); /// Executes an SWT sequence for the ALF server /// \param sequence A vector of Data and Operation pairs + /// \param lock Boolean enabling implicit locking + /// \param lockTimeout timeout (in ms) for aquiring the lock /// \return A string of newline separated results; /// \throws o2:lla::LlaException on lock fail /// o2::alf::SwtException on invalid operation or error - std::string writeSequence(std::vector> sequence, bool lock = false); + std::string writeSequence(std::vector> sequence, bool lock = false, int lockTimeout = 0); static std::string SwtOperationToString(Operation op); static Operation StringToSwtOperation(std::string op); diff --git a/src/AlfServer.cxx b/src/AlfServer.cxx index c9f2886..e6ca264 100644 --- a/src/AlfServer.cxx +++ b/src/AlfServer.cxx @@ -245,9 +245,14 @@ std::pair AlfServer::stringToScaPair(const std::strin if (scaPair[scaPair.size() - 1] == "lock") { operation = Sca::Operation::Lock; - if (scaPair.size() != 1) { - BOOST_THROW_EXCEPTION( - AlfException() << ErrorInfo::Message("Too many arguments for LOCK operation")); + if (scaPair.size() == 2) { + try { + data = std::stoi(scaPair[0]); + } catch (const std::exception& e) { + BOOST_THROW_EXCEPTION(SwtException() << ErrorInfo::Message("SCA lock WaitTime provided cannot be converted to int")); + } + } else { + data = 0; } } else if (scaPair[scaPair.size() - 1] == "wait") { operation = Sca::Operation::Wait; @@ -315,12 +320,18 @@ std::pair AlfServer::stringToSwtPair(const std::strin } Swt::Operation operation; + Swt::Data data; if (swtPair[swtPair.size() - 1] == "lock") { operation = Swt::Operation::Lock; if (swtPair.size() == 2) { - BOOST_THROW_EXCEPTION( - AlfException() << ErrorInfo::Message("Too many arguments for LOCK operation")); + try { + data = std::stoi(swtPair[0]); + } catch (const std::exception& e) { + BOOST_THROW_EXCEPTION(SwtException() << ErrorInfo::Message("SWT lock WaitTime provided cannot be converted to int")); + } + } else { + data = 0; } } else if (swtPair[swtPair.size() - 1] == "read") { operation = Swt::Operation::Read; @@ -342,8 +353,6 @@ std::pair AlfServer::stringToSwtPair(const std::strin BOOST_THROW_EXCEPTION(std::out_of_range("Parameter for SWT operation unkown")); } - Swt::Data data; - if (operation == Swt::Operation::Write) { SwtWord word; word.setSize(swtWordSize); diff --git a/src/Lla.cxx b/src/Lla.cxx index 52719f7..9f93294 100644 --- a/src/Lla.cxx +++ b/src/Lla.cxx @@ -41,7 +41,7 @@ LlaSession::~LlaSession() stop(); } -void LlaSession::start() +void LlaSession::start(int timeout) { if (!mSession) { mParams = lla::SessionParameters::makeParameters(mSessionName, mSerialId); @@ -49,7 +49,8 @@ void LlaSession::start() } if (!mSession->isStarted()) { - if (!mSession->start()) { + bool started = (timeout==0) ? mSession->start() : mSession->timedStart(timeout); + if (!started) { BOOST_THROW_EXCEPTION(lla::LlaException() << lla::ErrorInfo::Message("Couldn't start session")); // couldn't grab the lock } diff --git a/src/Sca.cxx b/src/Sca.cxx index 85e3651..9d9a1fa 100644 --- a/src/Sca.cxx +++ b/src/Sca.cxx @@ -76,10 +76,10 @@ void Sca::svlConnect() barWrite(sc_regs::SCA_WR_CTRL.index, 0x0); } -Sca::CommandData Sca::executeCommand(uint32_t command, uint32_t data, bool lock) +Sca::CommandData Sca::executeCommand(uint32_t command, uint32_t data, bool lock, int lockTimeout) { if (lock) { - mLlaSession->start(); + mLlaSession->start(lockTimeout); } checkChannelSet(); @@ -221,10 +221,10 @@ void Sca::waitOnBusyClear() << ErrorInfo::Message("Exceeded timeout on busy wait")); } -std::vector> Sca::executeSequence(const std::vector>& operations, bool lock) +std::vector> Sca::executeSequence(const std::vector>& operations, bool lock, int lockTimeout) { if (lock) { - mLlaSession->start(); + mLlaSession->start(lockTimeout); } try { @@ -295,10 +295,10 @@ std::vector> Sca::executeSequence(const std return ret; } -std::string Sca::writeSequence(const std::vector>& operations, bool lock) +std::string Sca::writeSequence(const std::vector>& operations, bool lock, int lockTimeout) { std::stringstream resultBuffer; - auto out = executeSequence(operations, lock); + auto out = executeSequence(operations, lock, lockTimeout); for (const auto& it : out) { Operation operation = it.first; Data data = it.second; diff --git a/src/ScaPythonInterface.h b/src/ScaPythonInterface.h index 8037cd6..c5f6db5 100644 --- a/src/ScaPythonInterface.h +++ b/src/ScaPythonInterface.h @@ -88,6 +88,8 @@ auto sScaSequenceDoc = lock: boolean to execute the sequence within an LLA session + lockTimeout: maximum wait time to aquire the LLA session lock in ms + Returns: sequence: A list of tuples made up of: operation: The operation carried out (string, same as input) @@ -188,14 +190,14 @@ class ScaInterface return mSca->executeCommand(cmd, data); } - std::vector> sequence(std::vector sequence, bool lock = false) + std::vector> sequence(std::vector sequence, bool lock = false, int lockTimeout = 0) { ScopedGILRelease s; // enable boost::python multi-threading std::vector> scaSequence; for (const auto& v : sequence) { scaSequence.push_back(boost::apply_visitor(ScaArgsVariantVisitor(), v)); } - return mSca->executeSequence(scaSequence, lock); + return mSca->executeSequence(scaSequence, lock, lockTimeout); } std::vector> sequenceDefault(std::vector scaSeq) diff --git a/src/Swt.cxx b/src/Swt.cxx index c69a571..84b04a1 100644 --- a/src/Swt.cxx +++ b/src/Swt.cxx @@ -120,10 +120,10 @@ void Swt::write(const SwtWord& swtWord) //return barRead(sc_regs::SWT_MON.index); } -std::vector> Swt::executeSequence(std::vector> sequence, bool lock) +std::vector> Swt::executeSequence(std::vector> sequence, bool lock, int lockTimeout) { if (lock) { - mLlaSession->start(); + mLlaSession->start(lockTimeout); } try { @@ -199,10 +199,10 @@ std::vector> Swt::executeSequence(std::vect return ret; } -std::string Swt::writeSequence(std::vector> sequence, bool lock) +std::string Swt::writeSequence(std::vector> sequence, bool lock, int lockTimeout) { std::stringstream resultBuffer; - auto out = executeSequence(sequence, lock); + auto out = executeSequence(sequence, lock, lockTimeout); for (const auto& it : out) { Operation operation = it.first; Data data = it.second; diff --git a/src/SwtPythonInterface.h b/src/SwtPythonInterface.h index 2262158..a2e71bf 100644 --- a/src/SwtPythonInterface.h +++ b/src/SwtPythonInterface.h @@ -87,6 +87,8 @@ auto sSwtSequenceDoc = lock: boolean to execute the sequence within an LLA session + lockTimeout: maximum wait time to aquire the LLA session lock in ms + Returns: sequence: A list of tuples made up of: operation: The operation carried out (string, same as input) @@ -178,7 +180,7 @@ class SwtInterface return readDefault(); } - std::vector> sequence(std::vector sequence, bool lock = false) + std::vector> sequence(std::vector sequence, bool lock = false, int lockTimeout = 0) { ScopedGILRelease s; // enable boost::python multi-threading std::vector> swtSequence; @@ -186,7 +188,7 @@ class SwtInterface swtSequence.push_back(boost::apply_visitor(SwtArgsVariantVisitor(), v)); } - auto out = mSwt->executeSequence(swtSequence, lock); + auto out = mSwt->executeSequence(swtSequence, lock, lockTimeout); return out; }