diff --git a/linux/devices/ploc/PlocSupvHelper.cpp b/linux/devices/ploc/PlocSupvHelper.cpp index a7245cc1..ac9a3cd3 100644 --- a/linux/devices/ploc/PlocSupvHelper.cpp +++ b/linux/devices/ploc/PlocSupvHelper.cpp @@ -33,7 +33,7 @@ PlocSupvHelper::PlocSupvHelper(object_id_t objectId) : SystemObject(objectId), r lock = MutexFactory::instance()->createMutex(); } -PlocSupvHelper::~PlocSupvHelper() {} +PlocSupvHelper::~PlocSupvHelper() = default; ReturnValue_t PlocSupvHelper::initialize() { #ifdef XIPHOS_Q7S @@ -47,59 +47,102 @@ ReturnValue_t PlocSupvHelper::initialize() { } ReturnValue_t PlocSupvHelper::performOperation(uint8_t operationCode) { - ReturnValue_t result = returnvalue::OK; - semaphore->acquire(); + ReturnValue_t result; + lock->lockMutex(); + internalState = InternalState::IDLE; + lock->unlockMutex(); while (true) { - switch (internalState) { - case InternalState::IDLE: { - semaphore->acquire(); - break; - } - case InternalState::UPDATE: { - result = executeUpdate(); - if (result == returnvalue::OK) { - triggerEvent(SUPV_UPDATE_SUCCESSFUL, result); - } else if (result == PROCESS_TERMINATED) { - // Event already triggered - } else { - triggerEvent(SUPV_UPDATE_FAILED, result); + semaphore->acquire(); + int bytesRead = 0; + while (true) { + bytesRead = read(serialPort, reinterpret_cast(recBuf.data()), + static_cast(recBuf.size())); + if (bytesRead == 0) { + { + MutexGuard mg(lock); + if (internalState == InternalState::FINISH) { + // Flush received and unread data + tcflush(serialPort, TCIOFLUSH); + internalState = InternalState::IDLE; + break; + } } - internalState = InternalState::IDLE; + } else if (bytesRead < 0) { + sif::warning << "ScexUartReader::performOperation: read call failed with error [" << errno + << ", " << strerror(errno) << "]" << std::endl; break; - } - case InternalState::CHECK_MEMORY: { - executeFullCheckMemoryCommand(); - internalState = InternalState::IDLE; - break; - } - case InternalState::CONTINUE_UPDATE: { - result = continueUpdate(); - if (result == returnvalue::OK) { - triggerEvent(SUPV_CONTINUE_UPDATE_SUCCESSFUL, result); - } else if (result == PROCESS_TERMINATED) { - // Event already triggered - } else { - triggerEvent(SUPV_CONTINUE_UPDATE_FAILED, result); + } else if (bytesRead >= static_cast(recBuf.size())) { + sif::error << "ScexUartReader::performOperation: Receive buffer too small for " << bytesRead + << " bytes" << std::endl; + } else if (bytesRead > 0) { + if (debugMode) { + sif::info << "Received " << bytesRead + << " bytes from the Solar Cell Experiment:" << std::endl; } - internalState = InternalState::IDLE; - break; + // insert buffer into ring buffer here + // ReturnValue_t result = dleParser.passData(recBuf.data(), bytesRead); + // TODO: Parse ring buffer here } - case InternalState::REQUEST_EVENT_BUFFER: { - result = performEventBufferRequest(); - if (result == returnvalue::OK) { - triggerEvent(SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL, result); - } else if (result == PROCESS_TERMINATED) { - // Event already triggered + lock->lockMutex(); + InternalState currentState = internalState; + lock->unlockMutex(); + switch (currentState) { + case InternalState::IDLE: { break; - } else { - triggerEvent(SUPV_EVENT_BUFFER_REQUEST_FAILED, result); } - internalState = InternalState::IDLE; - break; + case InternalState::UPDATE: { + result = executeUpdate(); + if (result == returnvalue::OK) { + triggerEvent(SUPV_UPDATE_SUCCESSFUL, result); + } else if (result == PROCESS_TERMINATED) { + // Event already triggered + } else { + triggerEvent(SUPV_UPDATE_FAILED, result); + } + MutexGuard mg(lock); + internalState = InternalState::IDLE; + break; + } + case InternalState::CHECK_MEMORY: { + executeFullCheckMemoryCommand(); + MutexGuard mg(lock); + internalState = InternalState::IDLE; + break; + } + case InternalState::CONTINUE_UPDATE: { + result = continueUpdate(); + if (result == returnvalue::OK) { + triggerEvent(SUPV_CONTINUE_UPDATE_SUCCESSFUL, result); + } else if (result == PROCESS_TERMINATED) { + // Event already triggered + } else { + triggerEvent(SUPV_CONTINUE_UPDATE_FAILED, result); + } + MutexGuard mg(lock); + internalState = InternalState::IDLE; + break; + } + case InternalState::REQUEST_EVENT_BUFFER: { + result = performEventBufferRequest(); + if (result == returnvalue::OK) { + triggerEvent(SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL, result); + } else if (result == PROCESS_TERMINATED) { + // Event already triggered + break; + } else { + triggerEvent(SUPV_EVENT_BUFFER_REQUEST_FAILED, result); + } + MutexGuard mg(lock); + internalState = InternalState::IDLE; + break; + } + case InternalState::HANDLER_DRIVEN: { + continue; + } + default: + sif::debug << "PlocSupvHelper::performOperation: Invalid state" << std::endl; + break; } - default: - sif::debug << "PlocSupvHelper::performOperation: Invalid state" << std::endl; - break; } } } diff --git a/linux/devices/ploc/PlocSupvHelper.h b/linux/devices/ploc/PlocSupvHelper.h index 809dfd5b..a54b50a6 100644 --- a/linux/devices/ploc/PlocSupvHelper.h +++ b/linux/devices/ploc/PlocSupvHelper.h @@ -200,13 +200,22 @@ class PlocSupvHelper : public DeviceCommunicationIF, EventBufferRequest eventBufferReq; - enum class InternalState { IDLE, UPDATE, CONTINUE_UPDATE, REQUEST_EVENT_BUFFER, CHECK_MEMORY }; + enum class InternalState { + IDLE, + HANDLER_DRIVEN, + UPDATE, + CONTINUE_UPDATE, + REQUEST_EVENT_BUFFER, + CHECK_MEMORY, + FINISH + }; InternalState internalState = InternalState::IDLE; #ifdef XIPHOS_Q7S SdCardManager* sdcMan = nullptr; #endif + std::array recBuf = {}; uint8_t commandBuffer[supv::MAX_COMMAND_SIZE]{}; SpacePacketCreator creator; ploc::SpTcParams spParams = ploc::SpTcParams(creator); @@ -214,6 +223,7 @@ class PlocSupvHelper : public DeviceCommunicationIF, std::array tmBuf{}; bool terminate = false; + bool debugMode = false; SimpleRingBuffer ringBuf; /**