From 23f209fb077fb8b311a3cfc78eebcc96003536f3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 12 May 2022 09:48:41 +0200 Subject: [PATCH] added eive specific max31865 handler --- linux/ObjectFactory.cpp | 8 +- linux/devices/Max31865RtdReader.cpp | 73 ++++++---- linux/devices/Max31865RtdReader.h | 36 +---- mission/devices/CMakeLists.txt | 1 + mission/devices/Max31865EiveHandler.cpp | 132 ++++++++++++++++++ mission/devices/Max31865EiveHandler.h | 37 +++++ mission/devices/Max31865PT1000Handler.cpp | 2 +- .../devicedefinitions/Max31865Definitions.h | 54 ++++++- .../Max31865DeviceDefinitions.cpp | 1 - 9 files changed, 279 insertions(+), 65 deletions(-) create mode 100644 mission/devices/Max31865EiveHandler.cpp create mode 100644 mission/devices/Max31865EiveHandler.h delete mode 100644 mission/devices/devicedefinitions/Max31865DeviceDefinitions.cpp diff --git a/linux/ObjectFactory.cpp b/linux/ObjectFactory.cpp index e28f41fa..35d1cff9 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -286,10 +286,10 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF, std::array rtds = {}; RtdFdir* rtdFdir = nullptr; for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { - rtdCookies[idx] = - new SpiCookie(cookieArgs[idx].first, cookieArgs[idx].second, - MAX31865::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - rtds[idx] = new Max31865PT1000Handler(rtdInfos[idx].first, objects::SPI_MAIN_COM_IF, rtdCookies[idx]); + rtdCookies[idx] = new SpiCookie(cookieArgs[idx].first, cookieArgs[idx].second, + MAX31865::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); + rtds[idx] = + new Max31865PT1000Handler(rtdInfos[idx].first, objects::SPI_MAIN_COM_IF, rtdCookies[idx]); rtds[idx]->setParent(objects::TCS_BOARD_ASS); rtdFdir = new RtdFdir(rtdInfos[idx].first); rtds[idx]->setCustomFdir(rtdFdir); diff --git a/linux/devices/Max31865RtdReader.cpp b/linux/devices/Max31865RtdReader.cpp index 0e2f9724..132467e9 100644 --- a/linux/devices/Max31865RtdReader.cpp +++ b/linux/devices/Max31865RtdReader.cpp @@ -2,7 +2,7 @@ #include Max31865RtdReader::Max31865RtdReader(object_id_t objectId, SpiComIF* comIF) - : SystemObject(objectId), rtds(NUM_RTDS), comIF(comIF) { + : SystemObject(objectId), rtds(EiveMax31855::NUM_RTDS), comIF(comIF) { readerMutex = MutexFactory::instance()->createMutex(); } @@ -32,8 +32,8 @@ void Max31865RtdReader::rtdMainLoop() { periodicReadHandling(); } -bool Max31865RtdReader::rtdCanBeUsed(uint8_t idx) { - if (rtds[idx]->active and rtds[idx]->configured) { +bool Max31865RtdReader::rtdIsActive(uint8_t idx) { + if (rtds[idx]->on and rtds[idx]->active and rtds[idx]->configured) { return true; } return false; @@ -48,24 +48,26 @@ bool Max31865RtdReader::periodicInitHandling() { return false; } - bool someRtdActive = false; + bool someRtdOn = false; for (auto& rtd : rtds) { if (rtd == nullptr) { continue; } - if (rtd->active and not rtd->configured) { - someRtdActive = true; - uint8_t cfg = (Bias::OFF << CfgBitPos::BIAS_SEL) | (Wires::FOUR_WIRE << CfgBitPos::WIRE_SEL) | - (ConvMode::NORM_OFF << CfgBitPos::CONV_MODE) | - (1 << CfgBitPos::FAULTY_STATUS_CLEAR); - result = writeCfgReg(rtd->spiCookie, cfg); - if (result != HasReturnvaluesIF::RETURN_OK) { - // TODO: Check retval + if (rtd->on and not rtd->configured) { + if (rtd->cd.hasTimedOut()) { + uint8_t cfg = + (Bias::OFF << CfgBitPos::BIAS_SEL) | (Wires::FOUR_WIRE << CfgBitPos::WIRE_SEL) | + (ConvMode::NORM_OFF << CfgBitPos::CONV_MODE) | (1 << CfgBitPos::FAULTY_STATUS_CLEAR); + result = writeCfgReg(rtd->spiCookie, cfg); + if (result != HasReturnvaluesIF::RETURN_OK) { + // TODO: Check retval + } + someRtdOn = true; + rtd->configured = true; } - rtd->configured = true; } } - if (not someRtdActive) { + if (not someRtdOn) { return false; } bool someRtdUsable = false; @@ -73,7 +75,7 @@ bool Max31865RtdReader::periodicInitHandling() { if (rtd == nullptr) { continue; } - if (rtdCanBeUsed(rtd->idx)) { + if (rtdIsActive(rtd->idx)) { someRtdUsable = true; result = biasSel(Bias::ON, rtd->spiCookie); } @@ -93,7 +95,7 @@ void Max31865RtdReader::periodicReadReqHandling() { if (rtd == nullptr) { continue; } - if (rtd->active) { + if (rtdIsActive(rtd->idx)) { uint8_t currentCfg = 0; auto result = readCfgReg(rtd->spiCookie, currentCfg); if (result != RETURN_OK) { @@ -119,7 +121,7 @@ void Max31865RtdReader::periodicReadHandling() { if (rtd == nullptr) { continue; } - if (rtd->active) { + if (rtdIsActive(rtd->idx)) { uint16_t rtdVal = 0; bool faultBitSet = false; result = readRtdVal(rtd->spiCookie, rtdVal, faultBitSet); @@ -137,7 +139,9 @@ void Max31865RtdReader::periodicReadHandling() { if (rtd == nullptr) { continue; } - if (rtd->active) { + // Even if a device was made inactive, turn off the bias here. If it was turned off, not + // necessary anymore.. + if (rtd->on) { result = biasSel(Bias::OFF, rtd->spiCookie); } } @@ -152,7 +156,7 @@ ReturnValue_t Max31865RtdReader::initializeInterface(CookieIF* cookie) { if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - if (rtdCookie->idx > NUM_RTDS) { + if (rtdCookie->idx > EiveMax31855::NUM_RTDS) { throw std::invalid_argument("Invalid RTD index"); } rtds[rtdCookie->idx] = rtdCookie; @@ -178,21 +182,40 @@ ReturnValue_t Max31865RtdReader::sendMessage(CookieIF* cookie, const uint8_t* se // TODO: Emit warning, invalid command return RETURN_OK; } - auto cmd = static_cast(sendData[0]); + auto cmd = static_cast(sendData[0]); switch (cmd) { - case (RtdCommands::ON): { - if (not rtdCookie->active) { - rtdCookie->active = true; + case (EiveMax31855::RtdCommands::ON): { + if (not rtdCookie->on) { + rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS); + rtdCookie->cd.resetTimer(); + rtdCookie->on = true; + rtdCookie->active = false; rtdCookie->configured = false; } break; } - case (RtdCommands::OFF): { + case (EiveMax31855::RtdCommands::ACTIVE): { + if (not rtdCookie->on) { + rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS); + rtdCookie->cd.resetTimer(); + rtdCookie->on = true; + rtdCookie->active = true; + rtdCookie->configured = false; + } else { + rtdCookie->active = true; + } + break; + } + case (EiveMax31855::RtdCommands::OFF): { + rtdCookie->on = false; rtdCookie->active = false; rtdCookie->configured = false; break; } - case (RtdCommands::CFG): { + case (EiveMax31855::RtdCommands::HIGH_TRESHOLD): + case (EiveMax31855::RtdCommands::LOW_THRESHOLD): + case (EiveMax31855::RtdCommands::CFG): + default: { // TODO: Only implement if needed break; } diff --git a/linux/devices/Max31865RtdReader.h b/linux/devices/Max31865RtdReader.h index 4a1bbb47..79ae1786 100644 --- a/linux/devices/Max31865RtdReader.h +++ b/linux/devices/Max31865RtdReader.h @@ -9,32 +9,6 @@ #include "fsfw/devicehandlers/DeviceCommunicationIF.h" #include "mission/devices/devicedefinitions/Max31865Definitions.h" -static constexpr uint8_t NUM_RTDS = 16; - -enum RtdCommands : uint8_t { ON = 0, OFF = 1, CFG = 2 }; - -class ReadOutStruct : public SerialLinkedListAdapter { - public: - ReadOutStruct() { setLinks(); } - ReadOutStruct(uint32_t spiErrCnt, bool faultBitSet, uint8_t faultVal, uint16_t rtdVal) - : spiErrorCount(spiErrCnt), faultBitSet(faultBitSet), faultValue(faultVal), rtdVal(rtdVal) { - setLinks(); - } - - SerializeElement spiErrorCount = 0; - SerializeElement faultBitSet = false; - SerializeElement faultValue = 0; - SerializeElement rtdVal = 0; - - private: - void setLinks() { - setStart(&spiErrorCount); - spiErrorCount.setNext(&faultBitSet); - faultBitSet.setNext(&faultValue); - faultValue.setNext(&rtdVal); - }; -}; - struct Max31865ReaderCookie { Max31865ReaderCookie(){}; Max31865ReaderCookie(object_id_t handlerId_, uint8_t idx_, const std::string& locString_, @@ -46,14 +20,14 @@ struct Max31865ReaderCookie { std::string locString = ""; std::array exchangeBuf{}; - bool active = false; - + Countdown cd = Countdown(MAX31865::WARMUP_MS); + bool on = false; bool configured = false; - + bool active = false; SpiCookie* spiCookie = nullptr; // Exchange data buffer struct - ReadOutStruct db; + EiveMax31855::ReadOutStruct db; }; class Max31865RtdReader : public SystemObject, @@ -74,7 +48,7 @@ class Max31865RtdReader : public SystemObject, void periodicReadReqHandling(); void periodicReadHandling(); - bool rtdCanBeUsed(uint8_t idx); + bool rtdIsActive(uint8_t idx); ReturnValue_t writeCfgReg(SpiCookie* cookie, uint8_t cfg); ReturnValue_t biasSel(MAX31865::Bias bias, SpiCookie* cookie); ReturnValue_t readCfgReg(SpiCookie* cookie, uint8_t& cfg); diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 2919ff1f..d5f33e39 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -8,6 +8,7 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE PDU2Handler.cpp ACUHandler.cpp SyrlinksHkHandler.cpp + Max31865EiveHandler.cpp Max31865PT1000Handler.cpp IMTQHandler.cpp HeaterHandler.cpp diff --git a/mission/devices/Max31865EiveHandler.cpp b/mission/devices/Max31865EiveHandler.cpp new file mode 100644 index 00000000..17afa718 --- /dev/null +++ b/mission/devices/Max31865EiveHandler.cpp @@ -0,0 +1,132 @@ +#include "Max31865EiveHandler.h" + +Max31865EiveHandler::Max31865EiveHandler(object_id_t objectId, object_id_t comIF, + CookieIF* comCookie) + : DeviceHandlerBase(objectId, comIF, comCookie, nullptr), + sensorDataset(this, EiveMax31855::RtdCommands::EXCHANGE_SET_ID) {} + +void Max31865EiveHandler::doStartUp() { + if (state == InternalState::NONE or state == InternalState::INACTIVE) { + if (instantNormal) { + state = InternalState::ACTIVE; + } else { + state = InternalState::ON; + } + transitionOk = false; + } + if ((state == InternalState::ON or state == InternalState::ACTIVE) and transitionOk) { + if (instantNormal) { + setMode(_MODE_TO_NORMAL); + } else { + setMode(MODE_ON); + } + } +} + +void Max31865EiveHandler::doShutDown() { + if (state == InternalState::NONE or state == InternalState::ACTIVE or + state == InternalState::ON) { + state = InternalState::INACTIVE; + transitionOk = false; + } else { + transitionOk = true; + } + if (state == InternalState::INACTIVE and transitionOk) { + setMode(_MODE_POWER_DOWN); + } +} + +ReturnValue_t Max31865EiveHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { + *id = EiveMax31855::RtdCommands::EXCHANGE_SET_ID; + return RETURN_OK; +} + +ReturnValue_t Max31865EiveHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { + if (state == InternalState::ON) { + *id = EiveMax31855::RtdCommands::ON; + buildCommandFromCommand(*id, nullptr, 0); + } + if (state == InternalState::ACTIVE) { + *id = EiveMax31855::RtdCommands::ACTIVE; + buildCommandFromCommand(*id, nullptr, 0); + } + if (state == InternalState::INACTIVE) { + *id = EiveMax31855::RtdCommands::OFF; + buildCommandFromCommand(*id, nullptr, 0); + } + return NOTHING_TO_SEND; +} + +ReturnValue_t Max31865EiveHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t* commandData, + size_t commandDataLen) { + auto cmdTyped = static_cast(deviceCommand); + switch (cmdTyped) { + case (EiveMax31855::RtdCommands::ON): + case (EiveMax31855::RtdCommands::ACTIVE): + case (EiveMax31855::RtdCommands::OFF): { + simpleCommand(cmdTyped); + break; + } + case (EiveMax31855::RtdCommands::LOW_THRESHOLD): + case (EiveMax31855::RtdCommands::HIGH_TRESHOLD): { + break; + } + case (EiveMax31855::RtdCommands::CFG): { + break; + } + default: + return NOTHING_TO_SEND; + } + return RETURN_OK; +} + +void Max31865EiveHandler::simpleCommand(EiveMax31855::RtdCommands cmd) { + cmdBuf[0] = cmd; + rawPacket = cmdBuf.data(); + rawPacketLen = 1; +} +void Max31865EiveHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { + if (mode == _MODE_TO_NORMAL) { + state = InternalState::ACTIVE; + transitionOk = false; + if (transitionOk) { + setMode(MODE_NORMAL); + } + } else { + DeviceHandlerBase::doTransition(modeFrom, subModeFrom); + } +} + +void Max31865EiveHandler::fillCommandAndReplyMap() { + insertInReplyMap(EiveMax31855::RtdCommands::EXCHANGE_SET_ID, 2, &sensorDataset); +} + +ReturnValue_t Max31865EiveHandler::scanForReply(const uint8_t* start, size_t remainingSize, + DeviceCommandId_t* foundId, size_t* foundLen) { + if (remainingSize != exchangeStruct.getSerializedSize()) { + sif::error << "Invalid reply from RTD reader detected, reply size " << remainingSize + << "not equal to exchange struct size" << exchangeStruct.getSerializedSize() + << std::endl; + return RETURN_FAILED; + } + *foundId = EiveMax31855::RtdCommands::EXCHANGE_SET_ID; + *foundLen = remainingSize; + return RETURN_OK; +} + +ReturnValue_t Max31865EiveHandler::interpretDeviceReply(DeviceCommandId_t id, + const uint8_t* packet) { + return RETURN_OK; +} + +uint32_t Max31865EiveHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 2000; } + +ReturnValue_t Max31865EiveHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) { + localDataPoolMap.emplace(MAX31865::PoolIds::RTD_VALUE, new PoolEntry({0})); + localDataPoolMap.emplace(MAX31865::PoolIds::TEMPERATURE_C, new PoolEntry({0})); + localDataPoolMap.emplace(MAX31865::PoolIds::FAULT_BYTE, new PoolEntry({0})); + poolManager.subscribeForPeriodicPacket(sensorDataset.getSid(), false, 30.0, false); + return RETURN_OK; +} diff --git a/mission/devices/Max31865EiveHandler.h b/mission/devices/Max31865EiveHandler.h new file mode 100644 index 00000000..9214c680 --- /dev/null +++ b/mission/devices/Max31865EiveHandler.h @@ -0,0 +1,37 @@ +#ifndef MISSION_DEVICES_MAX31865EIVEHANDLER_H_ +#define MISSION_DEVICES_MAX31865EIVEHANDLER_H_ + +#include + +#include "devicedefinitions/Max31865Definitions.h" + +class Max31865EiveHandler : public DeviceHandlerBase { + public: + Max31865EiveHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie); + + private: + void doStartUp() override; + void doShutDown() override; + void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; + ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override; + ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override; + void fillCommandAndReplyMap() override; + ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData, + size_t commandDataLen) override; + ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId, + size_t* foundLen) override; + ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override; + uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; + ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; + + void simpleCommand(EiveMax31855::RtdCommands cmd); + std::array cmdBuf = {}; + EiveMax31855::ReadOutStruct exchangeStruct; + bool instantNormal = false; + MAX31865::Max31865Set sensorDataset; + enum class InternalState { NONE, ON, ACTIVE, INACTIVE } state = InternalState::NONE; + bool transitionOk = false; +}; + +#endif /* MISSION_DEVICES_MAX31865EIVEHANDLER_H_ */ diff --git a/mission/devices/Max31865PT1000Handler.cpp b/mission/devices/Max31865PT1000Handler.cpp index 6ac888cd..debe60e9 100644 --- a/mission/devices/Max31865PT1000Handler.cpp +++ b/mission/devices/Max31865PT1000Handler.cpp @@ -8,7 +8,7 @@ Max31865PT1000Handler::Max31865PT1000Handler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie) : DeviceHandlerBase(objectId, comIF, comCookie), - sensorDataset(this), + sensorDataset(this, MAX31865::REQUEST_RTD), sensorDatasetSid(sensorDataset.getSid()) { #if OBSW_VERBOSE_LEVEL >= 1 debugDivider = new PeriodicOperationDivider(10); diff --git a/mission/devices/devicedefinitions/Max31865Definitions.h b/mission/devices/devicedefinitions/Max31865Definitions.h index efd81681..d1b67429 100644 --- a/mission/devices/devicedefinitions/Max31865Definitions.h +++ b/mission/devices/devicedefinitions/Max31865Definitions.h @@ -28,6 +28,8 @@ enum CfgBitPos { BIAS_SEL = 7 }; +static constexpr uint32_t WARMUP_MS = 100; + static constexpr DeviceCommandId_t CONFIG_CMD = 0x80; static constexpr DeviceCommandId_t WRITE_HIGH_THRESHOLD = 0x83; static constexpr DeviceCommandId_t WRITE_LOW_THRESHOLD = 0x85; @@ -50,20 +52,20 @@ static constexpr uint8_t REG_RTD = 0x01; static constexpr size_t MAX_REPLY_SIZE = 5; -class Max31865Set : public StaticLocalDataSet { +class Max31865Set : public StaticLocalDataSet<3> { public: /** * Constructor used by owner and data creators like device handlers. * @param owner * @param setId */ - Max31865Set(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, MAX31865_SET_ID) {} + Max31865Set(HasLocalDataPoolIF* owner, uint32_t setId) : StaticLocalDataSet(owner, setId) {} /** * Constructor used by data users like controllers. * @param sid */ - Max31865Set(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, MAX31865_SET_ID)) {} + Max31865Set(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {} lp_var_t rtdValue = lp_var_t(sid.objectId, PoolIds::RTD_VALUE, this); lp_var_t temperatureCelcius = lp_var_t(sid.objectId, PoolIds::TEMPERATURE_C, this); @@ -72,4 +74,50 @@ class Max31865Set : public StaticLocalDataSet { } // namespace MAX31865 +namespace EiveMax31855 { + +static constexpr uint8_t NUM_RTDS = 16; + +enum RtdCommands : DeviceCommandId_t { + ON = 0, + EXCHANGE_SET_ID = MAX31865::REQUEST_RTD, + ACTIVE = 2, + LOW_THRESHOLD = 3, + HIGH_TRESHOLD = 4, + OFF = 5, + CFG = 6, + +}; + +class ReadOutStruct : public SerialLinkedListAdapter { + public: + ReadOutStruct() { setLinks(); } + ReadOutStruct(bool active, uint32_t spiErrCnt, bool faultBitSet, uint8_t faultVal, + uint16_t rtdVal) + : active(active), + rtdVal(rtdVal), + faultBitSet(faultBitSet), + faultValue(faultVal), + spiErrorCount(spiErrCnt) { + setLinks(); + } + + SerializeElement active = false; + SerializeElement rtdVal = 0; + SerializeElement faultBitSet = false; + SerializeElement faultValue = 0; + SerializeElement spiErrorCount = 0; + + private: + void setLinks() { + setStart(&active); + active.setNext(&rtdVal); + rtdVal.setNext(&faultBitSet); + faultBitSet.setNext(&faultValue); + faultValue.setNext(&spiErrorCount); + }; +}; + +}; // namespace EiveMax31855 + #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_MAX13865DEFINITIONS_H_ */ diff --git a/mission/devices/devicedefinitions/Max31865DeviceDefinitions.cpp b/mission/devices/devicedefinitions/Max31865DeviceDefinitions.cpp deleted file mode 100644 index 0f050093..00000000 --- a/mission/devices/devicedefinitions/Max31865DeviceDefinitions.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Max31865Definitions.h"