From 50c363fb6f4ef490fca06e121ec04e995449e10e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 May 2022 21:29:54 +0200 Subject: [PATCH] new RTD reader module handling all RTD SPI Communication --- linux/ObjectFactory.cpp | 48 +-- linux/devices/CMakeLists.txt | 4 + linux/devices/Max31865RtdReader.cpp | 289 ++++++++++++++++++ linux/devices/Max31865RtdReader.h | 92 ++++++ mission/devices/Max31865PT1000Handler.cpp | 122 ++++---- mission/devices/Max31865PT1000Handler.h | 5 +- .../devicedefinitions/Max31865Definitions.h | 26 +- .../Max31865DeviceDefinitions.cpp | 1 + mission/system/TcsBoardAssembly.cpp | 12 +- mission/system/TcsBoardAssembly.h | 5 +- tmtc | 2 +- 11 files changed, 510 insertions(+), 96 deletions(-) create mode 100644 linux/devices/Max31865RtdReader.cpp create mode 100644 linux/devices/Max31865RtdReader.h create mode 100644 mission/devices/devicedefinitions/Max31865DeviceDefinitions.cpp diff --git a/linux/ObjectFactory.cpp b/linux/ObjectFactory.cpp index fcf1f81f..5a740c33 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -265,34 +265,36 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF, {addresses::RTD_IC_17, gpioIds::RTD_IC_17}, {addresses::RTD_IC_18, gpioIds::RTD_IC_18}, }}; - std::array rtdIds = {objects::RTD_0_IC3_PLOC_HEATSPREADER, - objects::RTD_1_IC4_PLOC_MISSIONBOARD, - objects::RTD_2_IC5_4K_CAMERA, - objects::RTD_3_IC6_DAC_HEATSPREADER, - objects::RTD_4_IC7_STARTRACKER, - objects::RTD_5_IC8_RW1_MX_MY, - objects::RTD_6_IC9_DRO, - objects::RTD_7_IC10_SCEX, - objects::RTD_8_IC11_X8, - objects::RTD_9_IC12_HPA, - objects::RTD_10_IC13_PL_TX, - objects::RTD_11_IC14_MPA, - objects::RTD_12_IC15_ACU, - objects::RTD_13_IC16_PLPCDU_HEATSPREADER, - objects::RTD_14_IC17_TCS_BOARD, - objects::RTD_15_IC18_IMTQ}; + std::array, NUMBER_RTDS> rtdInfos = {{ + {objects::RTD_0_IC3_PLOC_HEATSPREADER, "RTD_0_PLOC_HEATSPREADER"}, + {objects::RTD_1_IC4_PLOC_MISSIONBOARD, "RTD_1_PLOC_MISSIONBOARD"}, + {objects::RTD_2_IC5_4K_CAMERA, "RTD_2_4K_CAMERA"}, + {objects::RTD_3_IC6_DAC_HEATSPREADER, "RTD_3_DAC_HEATSPREADER"}, + {objects::RTD_4_IC7_STARTRACKER, "RTD_4_STARTRACKER"}, + {objects::RTD_5_IC8_RW1_MX_MY, "RTD_5_RW1_MX_MY"}, + {objects::RTD_6_IC9_DRO, "RTD_6_DRO"}, + {objects::RTD_7_IC10_SCEX, "RTD_7_SCEX"}, + {objects::RTD_8_IC11_X8, "RTD_8_X8"}, + {objects::RTD_9_IC12_HPA, "RTD_9_HPA"}, + {objects::RTD_10_IC13_PL_TX, "RTD_10_PL_TX,"}, + {objects::RTD_11_IC14_MPA, "RTD_11_MPA"}, + {objects::RTD_12_IC15_ACU, "RTD_12_ACU"}, + {objects::RTD_13_IC16_PLPCDU_HEATSPREADER, "RTD_13_PLPCDU_HEATSPREADER"}, + {objects::RTD_14_IC17_TCS_BOARD, "RTD_14_TCS_BOARD"}, + {objects::RTD_15_IC18_IMTQ, "RTD_15_IMTQ"}, + }}; std::array rtdCookies = {}; 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, spiDev, - Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - rtds[idx] = new Max31865PT1000Handler(rtdIds[idx], objects::SPI_COM_IF, rtdCookies[idx]); + rtdCookies[idx] = new SpiCookie(cookieArgs[idx].first, cookieArgs[idx].second, spiDev, + MAX31865::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); + rtds[idx] = + new Max31865PT1000Handler(rtdInfos[idx].first, objects::SPI_COM_IF, rtdCookies[idx]); rtds[idx]->setParent(objects::TCS_BOARD_ASS); - rtdFdir = new RtdFdir(rtdIds[idx]); + rtdFdir = new RtdFdir(rtdInfos[idx].first); rtds[idx]->setCustomFdir(rtdFdir); - rtds[idx]->setDeviceIdx(idx + 3); + rtds[idx]->setDeviceInfo(idx + 3, rtdInfos[idx].second); #if OBSW_DEBUG_RTD == 1 rtds[idx]->setDebugMode(true); #endif @@ -306,7 +308,7 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF, } } #endif // OBSW_TEST_RTD == 1 - TcsBoardHelper helper(rtdIds); + TcsBoardHelper helper(rtdInfos); TcsBoardAssembly* tcsBoardAss = new TcsBoardAssembly(objects::TCS_BOARD_ASS, objects::NO_OBJECT, pwrSwitcher, pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper); diff --git a/linux/devices/CMakeLists.txt b/linux/devices/CMakeLists.txt index 00d407e8..e65987c6 100644 --- a/linux/devices/CMakeLists.txt +++ b/linux/devices/CMakeLists.txt @@ -4,5 +4,9 @@ if(EIVE_BUILD_GPSD_GPS_HANDLER) ) endif() +target_sources(${OBSW_NAME} PRIVATE + Max31865RtdReader.cpp +) + add_subdirectory(ploc) add_subdirectory(startracker) diff --git a/linux/devices/Max31865RtdReader.cpp b/linux/devices/Max31865RtdReader.cpp new file mode 100644 index 00000000..0e2f9724 --- /dev/null +++ b/linux/devices/Max31865RtdReader.cpp @@ -0,0 +1,289 @@ +#include +#include + +Max31865RtdReader::Max31865RtdReader(object_id_t objectId, SpiComIF* comIF) + : SystemObject(objectId), rtds(NUM_RTDS), comIF(comIF) { + readerMutex = MutexFactory::instance()->createMutex(); +} + +ReturnValue_t Max31865RtdReader::performOperation(uint8_t operationCode) { + using namespace MAX31865; + while (true) { + rtdMainLoop(); + // Read all RTDs at once every 500 ms for now + TaskFactory::delayTask(500); + } +} + +void Max31865RtdReader::rtdMainLoop() { + using namespace MAX31865; + if (periodicInitHandling()) { + // 10 ms delay for VBIAS startup + TaskFactory::delayTask(10); + } else { + // No devices usable (e.g. TCS board off) + return; + } + + periodicReadReqHandling(); + // After requesting, 65 milliseconds delay required + TaskFactory::delayTask(65); + + periodicReadHandling(); +} + +bool Max31865RtdReader::rtdCanBeUsed(uint8_t idx) { + if (rtds[idx]->active and rtds[idx]->configured) { + return true; + } + return false; +} + +bool Max31865RtdReader::periodicInitHandling() { + using namespace MAX31865; + MutexGuard mg(readerMutex); + ReturnValue_t result = RETURN_OK; + if (mg.getLockResult() != RETURN_OK) { + // TODO: Emit warning, return + return false; + } + + bool someRtdActive = 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 + } + rtd->configured = true; + } + } + if (not someRtdActive) { + return false; + } + bool someRtdUsable = false; + for (auto& rtd : rtds) { + if (rtd == nullptr) { + continue; + } + if (rtdCanBeUsed(rtd->idx)) { + someRtdUsable = true; + result = biasSel(Bias::ON, rtd->spiCookie); + } + } + return someRtdUsable; +} + +void Max31865RtdReader::periodicReadReqHandling() { + using namespace MAX31865; + MutexGuard mg(readerMutex); + if (mg.getLockResult() != RETURN_OK) { + // TODO: Emit warning, return + return; + } + // Now request one shot config for all active RTDs + for (auto& rtd : rtds) { + if (rtd == nullptr) { + continue; + } + if (rtd->active) { + uint8_t currentCfg = 0; + auto result = readCfgReg(rtd->spiCookie, currentCfg); + if (result != RETURN_OK) { + // TODO: Emit warning, FDIR? + continue; + } + currentCfg |= (1 << CfgBitPos::ONE_SHOT); + result = writeCfgReg(rtd->spiCookie, currentCfg); + } + } +} + +void Max31865RtdReader::periodicReadHandling() { + using namespace MAX31865; + auto result = RETURN_OK; + MutexGuard mg(readerMutex); + if (mg.getLockResult() != RETURN_OK) { + // TODO: Emit warning, return + return; + } + // Now read the RTD values + for (auto& rtd : rtds) { + if (rtd == nullptr) { + continue; + } + if (rtd->active) { + uint16_t rtdVal = 0; + bool faultBitSet = false; + result = readRtdVal(rtd->spiCookie, rtdVal, faultBitSet); + if (result != RETURN_OK) { + // TODO: Emit warning, FDIR? + continue; + } + if (faultBitSet) { + rtd->db.faultBitSet = faultBitSet; + } + rtd->db.rtdVal = rtdVal; + } + } + for (auto& rtd : rtds) { + if (rtd == nullptr) { + continue; + } + if (rtd->active) { + result = biasSel(Bias::OFF, rtd->spiCookie); + } + } +} + +ReturnValue_t Max31865RtdReader::initializeInterface(CookieIF* cookie) { + if (cookie == nullptr) { + throw std::invalid_argument("Invalid MAX31865 Reader Cookie"); + } + auto* rtdCookie = dynamic_cast(cookie); + ReturnValue_t result = comIF->initializeInterface(rtdCookie->spiCookie); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + if (rtdCookie->idx > NUM_RTDS) { + throw std::invalid_argument("Invalid RTD index"); + } + rtds[rtdCookie->idx] = rtdCookie; + return RETURN_OK; +} + +ReturnValue_t Max31865RtdReader::sendMessage(CookieIF* cookie, const uint8_t* sendData, + size_t sendLen) { + if (cookie == nullptr) { + return RETURN_FAILED; + } + if (sendLen < 1) { + return RETURN_OK; + } + MutexGuard mg(readerMutex); + if (mg.getLockResult() != RETURN_OK) { + // TODO: Emit warning, return + return RETURN_FAILED; + } + auto* rtdCookie = dynamic_cast(cookie); + uint8_t cmdRaw = sendData[0]; + if (cmdRaw > 2) { + // TODO: Emit warning, invalid command + return RETURN_OK; + } + auto cmd = static_cast(sendData[0]); + switch (cmd) { + case (RtdCommands::ON): { + if (not rtdCookie->active) { + rtdCookie->active = true; + rtdCookie->configured = false; + } + break; + } + case (RtdCommands::OFF): { + rtdCookie->active = false; + rtdCookie->configured = false; + break; + } + case (RtdCommands::CFG): { + // TODO: Only implement if needed + break; + } + } + return RETURN_OK; +} + +ReturnValue_t Max31865RtdReader::getSendSuccess(CookieIF* cookie) { return RETURN_OK; } + +ReturnValue_t Max31865RtdReader::requestReceiveMessage(CookieIF* cookie, size_t requestLen) { + return RETURN_OK; +} + +ReturnValue_t Max31865RtdReader::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, + size_t* size) { + MutexGuard mg(readerMutex); + if (mg.getLockResult() != RETURN_OK) { + // TODO: Emit warning + return RETURN_FAILED; + } + auto* rtdCookie = dynamic_cast(cookie); + uint8_t* exchangePtr = rtdCookie->exchangeBuf.data(); + size_t serLen = 0; + auto result = rtdCookie->db.serialize(&exchangePtr, &serLen, rtdCookie->exchangeBuf.size(), + SerializeIF::Endianness::MACHINE); + if (result != RETURN_OK) { + // TODO: Emit warning + return RETURN_FAILED; + } + *buffer = reinterpret_cast(rtdCookie->exchangeBuf.data()); + *size = rtdCookie->db.getSerializedSize(); + return RETURN_OK; +} + +ReturnValue_t Max31865RtdReader::writeCfgReg(SpiCookie* cookie, uint8_t cfg) { + using namespace MAX31865; + uint8_t cmd[2] = {REG_CONFIG | WRITE_BIT, cfg}; + return comIF->sendMessage(cookie, cmd, 2); +} + +ReturnValue_t Max31865RtdReader::biasSel(MAX31865::Bias bias, SpiCookie* cookie) { + using namespace MAX31865; + uint8_t currentCfg = 0; + auto result = readCfgReg(cookie, currentCfg); + if (result != RETURN_OK) { + return result; + } + if (bias == MAX31865::Bias::OFF) { + currentCfg &= ~(1 << CfgBitPos::BIAS_SEL); + } else { + currentCfg |= (1 << CfgBitPos::BIAS_SEL); + } + return writeCfgReg(cookie, currentCfg); +} + +ReturnValue_t Max31865RtdReader::readCfgReg(SpiCookie* cookie, uint8_t& cfg) { + using namespace MAX31865; + uint8_t cmd[2] = {REG_CONFIG, 0}; + ReturnValue_t result = comIF->sendMessage(cookie, cmd, 2); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + uint8_t reply[2] = {}; + uint8_t* replyPtr = reply; + size_t dummyLen = 0; + result = comIF->readReceivedMessage(cookie, &replyPtr, &dummyLen); + if (result != RETURN_OK) { + return result; + } + cfg = reply[1]; + return RETURN_OK; +} + +ReturnValue_t Max31865RtdReader::readRtdVal(SpiCookie* cookie, uint16_t& val, bool& faultBitSet) { + using namespace MAX31865; + uint8_t cmd[3] = {REG_RTD, 0, 0}; + auto result = comIF->sendMessage(cookie, cmd, 3); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + uint8_t reply[3] = {}; + uint8_t* replyPtr = reply; + size_t dummyLen = 0; + result = comIF->readReceivedMessage(cookie, &replyPtr, &dummyLen); + if (result != RETURN_OK) { + return result; + } + if (reply[2] & 0b0000'0001) { + faultBitSet = true; + } + // Shift 1 to the right to remove fault bit + val = ((reply[1] << 8) | reply[2]) >> 1; + return result; +} diff --git a/linux/devices/Max31865RtdReader.h b/linux/devices/Max31865RtdReader.h new file mode 100644 index 00000000..4a1bbb47 --- /dev/null +++ b/linux/devices/Max31865RtdReader.h @@ -0,0 +1,92 @@ +#ifndef LINUX_DEVICES_MAX31865RTDREADER_H_ +#define LINUX_DEVICES_MAX31865RTDREADER_H_ + +#include +#include +#include +#include + +#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_, + SpiCookie* spiCookie_) + : idx(idx_), handlerId(handlerId_), locString(locString_), spiCookie(spiCookie_) {} + + uint8_t idx = 0; + object_id_t handlerId = objects::NO_OBJECT; + + std::string locString = ""; + std::array exchangeBuf{}; + bool active = false; + + bool configured = false; + + SpiCookie* spiCookie = nullptr; + + // Exchange data buffer struct + ReadOutStruct db; +}; + +class Max31865RtdReader : public SystemObject, + public ExecutableObjectIF, + public DeviceCommunicationIF { + public: + Max31865RtdReader(object_id_t objectId, SpiComIF* comIF); + void addRtd(Max31865ReaderCookie rtdCookie); + + [[noreturn]] ReturnValue_t performOperation(uint8_t operationCode) override; + + private: + std::vector rtds; + MutexIF* readerMutex; + + void rtdMainLoop(); + bool periodicInitHandling(); + void periodicReadReqHandling(); + void periodicReadHandling(); + + bool rtdCanBeUsed(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); + ReturnValue_t readRtdVal(SpiCookie* cookie, uint16_t& val, bool& faultBitSet); + + ReturnValue_t initializeInterface(CookieIF* cookie) override; + ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override; + ReturnValue_t getSendSuccess(CookieIF* cookie) override; + ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override; + ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override; + + SpiComIF* comIF; +}; + +#endif /* LINUX_DEVICES_MAX31865RTDREADER_H_ */ diff --git a/mission/devices/Max31865PT1000Handler.cpp b/mission/devices/Max31865PT1000Handler.cpp index 580c8637..6ac888cd 100644 --- a/mission/devices/Max31865PT1000Handler.cpp +++ b/mission/devices/Max31865PT1000Handler.cpp @@ -93,13 +93,13 @@ void Max31865PT1000Handler::doShutDown() { ReturnValue_t Max31865PT1000Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) { if (internalState == InternalState::RUNNING) { - *id = Max31865Definitions::REQUEST_RTD; + *id = MAX31865::REQUEST_RTD; return buildCommandFromCommand(*id, nullptr, 0); } else if (internalState == InternalState::REQUEST_FAULT_BYTE) { - *id = Max31865Definitions::REQUEST_FAULT_BYTE; + *id = MAX31865::REQUEST_FAULT_BYTE; return buildCommandFromCommand(*id, nullptr, 0); } else if (internalState == InternalState::CLEAR_FAULT_BYTE) { - *id = Max31865Definitions::CLEAR_FAULT_BYTE; + *id = MAX31865::CLEAR_FAULT_BYTE; return buildCommandFromCommand(*id, nullptr, 0); } else { return DeviceHandlerBase::NOTHING_TO_SEND; @@ -113,32 +113,32 @@ ReturnValue_t Max31865PT1000Handler::buildTransitionDeviceCommand(DeviceCommandI case (InternalState::RUNNING): return DeviceHandlerBase::NOTHING_TO_SEND; case (InternalState::CONFIGURE): { - *id = Max31865Definitions::CONFIG_CMD; + *id = MAX31865::CONFIG_CMD; uint8_t config[1] = {DEFAULT_CONFIG}; return buildCommandFromCommand(*id, config, 1); } case (InternalState::REQUEST_CONFIG): { - *id = Max31865Definitions::REQUEST_CONFIG; + *id = MAX31865::REQUEST_CONFIG; return buildCommandFromCommand(*id, nullptr, 0); } case (InternalState::CONFIG_HIGH_THRESHOLD): { - *id = Max31865Definitions::WRITE_HIGH_THRESHOLD; + *id = MAX31865::WRITE_HIGH_THRESHOLD; return buildCommandFromCommand(*id, nullptr, 0); } case (InternalState::REQUEST_HIGH_THRESHOLD): { - *id = Max31865Definitions::REQUEST_HIGH_THRESHOLD; + *id = MAX31865::REQUEST_HIGH_THRESHOLD; return buildCommandFromCommand(*id, nullptr, 0); } case (InternalState::CONFIG_LOW_THRESHOLD): { - *id = Max31865Definitions::WRITE_LOW_THRESHOLD; + *id = MAX31865::WRITE_LOW_THRESHOLD; return buildCommandFromCommand(*id, nullptr, 0); } case (InternalState::REQUEST_LOW_THRESHOLD): { - *id = Max31865Definitions::REQUEST_LOW_THRESHOLD; + *id = MAX31865::REQUEST_LOW_THRESHOLD; return buildCommandFromCommand(*id, nullptr, 0); } case (InternalState::CLEAR_FAULT_BYTE): { - *id = Max31865Definitions::CLEAR_FAULT_BYTE; + *id = MAX31865::CLEAR_FAULT_BYTE; return buildCommandFromCommand(*id, nullptr, 0); } @@ -156,8 +156,8 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d const uint8_t *commandData, size_t commandDataLen) { switch (deviceCommand) { - case (Max31865Definitions::CONFIG_CMD): { - commandBuffer[0] = static_cast(Max31865Definitions::CONFIG_CMD); + case (MAX31865::CONFIG_CMD): { + commandBuffer[0] = static_cast(MAX31865::CONFIG_CMD); if (commandDataLen == 1) { commandBuffer[1] = commandData[0]; DeviceHandlerBase::rawPacketLen = 2; @@ -167,54 +167,54 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d return DeviceHandlerIF::NO_COMMAND_DATA; } } - case (Max31865Definitions::CLEAR_FAULT_BYTE): { - commandBuffer[0] = static_cast(Max31865Definitions::CONFIG_CMD); - commandBuffer[1] = Max31865Definitions::CLEAR_FAULT_BIT_VAL; + case (MAX31865::CLEAR_FAULT_BYTE): { + commandBuffer[0] = static_cast(MAX31865::CONFIG_CMD); + commandBuffer[1] = MAX31865::CLEAR_FAULT_BIT_VAL; DeviceHandlerBase::rawPacketLen = 2; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::REQUEST_CONFIG): { - commandBuffer[0] = static_cast(Max31865Definitions::REQUEST_CONFIG); + case (MAX31865::REQUEST_CONFIG): { + commandBuffer[0] = static_cast(MAX31865::REQUEST_CONFIG); commandBuffer[1] = 0x00; // dummy byte DeviceHandlerBase::rawPacketLen = 2; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::WRITE_HIGH_THRESHOLD): { - commandBuffer[0] = static_cast(Max31865Definitions::WRITE_HIGH_THRESHOLD); + case (MAX31865::WRITE_HIGH_THRESHOLD): { + commandBuffer[0] = static_cast(MAX31865::WRITE_HIGH_THRESHOLD); commandBuffer[1] = static_cast(HIGH_THRESHOLD >> 8); commandBuffer[2] = static_cast(HIGH_THRESHOLD & 0xFF); DeviceHandlerBase::rawPacketLen = 3; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::REQUEST_HIGH_THRESHOLD): { - commandBuffer[0] = static_cast(Max31865Definitions::REQUEST_HIGH_THRESHOLD); + case (MAX31865::REQUEST_HIGH_THRESHOLD): { + commandBuffer[0] = static_cast(MAX31865::REQUEST_HIGH_THRESHOLD); commandBuffer[1] = 0x00; // dummy byte commandBuffer[2] = 0x00; // dummy byte DeviceHandlerBase::rawPacketLen = 3; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::WRITE_LOW_THRESHOLD): { - commandBuffer[0] = static_cast(Max31865Definitions::WRITE_LOW_THRESHOLD); + case (MAX31865::WRITE_LOW_THRESHOLD): { + commandBuffer[0] = static_cast(MAX31865::WRITE_LOW_THRESHOLD); commandBuffer[1] = static_cast(LOW_THRESHOLD >> 8); commandBuffer[2] = static_cast(LOW_THRESHOLD & 0xFF); DeviceHandlerBase::rawPacketLen = 3; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::REQUEST_LOW_THRESHOLD): { - commandBuffer[0] = static_cast(Max31865Definitions::REQUEST_LOW_THRESHOLD); + case (MAX31865::REQUEST_LOW_THRESHOLD): { + commandBuffer[0] = static_cast(MAX31865::REQUEST_LOW_THRESHOLD); commandBuffer[1] = 0x00; // dummy byte commandBuffer[2] = 0x00; // dummy byte DeviceHandlerBase::rawPacketLen = 3; DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::REQUEST_RTD): { - commandBuffer[0] = static_cast(Max31865Definitions::REQUEST_RTD); + case (MAX31865::REQUEST_RTD): { + commandBuffer[0] = static_cast(MAX31865::REQUEST_RTD); // two dummy bytes commandBuffer[1] = 0x00; commandBuffer[2] = 0x00; @@ -222,8 +222,8 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d DeviceHandlerBase::rawPacket = commandBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } - case (Max31865Definitions::REQUEST_FAULT_BYTE): { - commandBuffer[0] = static_cast(Max31865Definitions::REQUEST_FAULT_BYTE); + case (MAX31865::REQUEST_FAULT_BYTE): { + commandBuffer[0] = static_cast(MAX31865::REQUEST_FAULT_BYTE); commandBuffer[1] = 0x00; DeviceHandlerBase::rawPacketLen = 2; DeviceHandlerBase::rawPacket = commandBuffer.data(); @@ -236,15 +236,15 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d } void Max31865PT1000Handler::fillCommandAndReplyMap() { - insertInCommandAndReplyMap(Max31865Definitions::CONFIG_CMD, 3); - insertInCommandAndReplyMap(Max31865Definitions::REQUEST_CONFIG, 3); - insertInCommandAndReplyMap(Max31865Definitions::WRITE_LOW_THRESHOLD, 3); - insertInCommandAndReplyMap(Max31865Definitions::REQUEST_LOW_THRESHOLD, 3); - insertInCommandAndReplyMap(Max31865Definitions::WRITE_HIGH_THRESHOLD, 3); - insertInCommandAndReplyMap(Max31865Definitions::REQUEST_HIGH_THRESHOLD, 3); - insertInCommandAndReplyMap(Max31865Definitions::REQUEST_RTD, 3, &sensorDataset); - insertInCommandAndReplyMap(Max31865Definitions::REQUEST_FAULT_BYTE, 3); - insertInCommandAndReplyMap(Max31865Definitions::CLEAR_FAULT_BYTE, 3); + insertInCommandAndReplyMap(MAX31865::CONFIG_CMD, 3); + insertInCommandAndReplyMap(MAX31865::REQUEST_CONFIG, 3); + insertInCommandAndReplyMap(MAX31865::WRITE_LOW_THRESHOLD, 3); + insertInCommandAndReplyMap(MAX31865::REQUEST_LOW_THRESHOLD, 3); + insertInCommandAndReplyMap(MAX31865::WRITE_HIGH_THRESHOLD, 3); + insertInCommandAndReplyMap(MAX31865::REQUEST_HIGH_THRESHOLD, 3); + insertInCommandAndReplyMap(MAX31865::REQUEST_RTD, 3, &sensorDataset); + insertInCommandAndReplyMap(MAX31865::REQUEST_FAULT_BYTE, 3); + insertInCommandAndReplyMap(MAX31865::CLEAR_FAULT_BYTE, 3); } ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t remainingSize, @@ -253,7 +253,7 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r size_t configReplySize = 2; if (remainingSize == rtdReplySize and internalState == InternalState::RUNNING) { - *foundId = Max31865Definitions::REQUEST_RTD; + *foundId = MAX31865::REQUEST_RTD; *foundLen = rtdReplySize; return RETURN_OK; } @@ -262,24 +262,24 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r switch (internalState) { case (InternalState::CONFIG_HIGH_THRESHOLD): { *foundLen = 3; - *foundId = Max31865Definitions::WRITE_HIGH_THRESHOLD; + *foundId = MAX31865::WRITE_HIGH_THRESHOLD; commandExecuted = true; return RETURN_OK; } case (InternalState::REQUEST_HIGH_THRESHOLD): { *foundLen = 3; - *foundId = Max31865Definitions::REQUEST_HIGH_THRESHOLD; + *foundId = MAX31865::REQUEST_HIGH_THRESHOLD; return RETURN_OK; } case (InternalState::CONFIG_LOW_THRESHOLD): { *foundLen = 3; - *foundId = Max31865Definitions::WRITE_LOW_THRESHOLD; + *foundId = MAX31865::WRITE_LOW_THRESHOLD; commandExecuted = true; return RETURN_OK; } case (InternalState::REQUEST_LOW_THRESHOLD): { *foundLen = 3; - *foundId = Max31865Definitions::REQUEST_LOW_THRESHOLD; + *foundId = MAX31865::REQUEST_LOW_THRESHOLD; return RETURN_OK; } default: { @@ -293,13 +293,13 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r if (internalState == InternalState::CONFIGURE) { commandExecuted = true; *foundLen = configReplySize; - *foundId = Max31865Definitions::CONFIG_CMD; + *foundId = MAX31865::CONFIG_CMD; } else if (internalState == InternalState::REQUEST_FAULT_BYTE) { - *foundId = Max31865Definitions::REQUEST_FAULT_BYTE; + *foundId = MAX31865::REQUEST_FAULT_BYTE; *foundLen = 2; internalState = InternalState::RUNNING; } else if (internalState == InternalState::CLEAR_FAULT_BYTE) { - *foundId = Max31865Definitions::CLEAR_FAULT_BYTE; + *foundId = MAX31865::CLEAR_FAULT_BYTE; *foundLen = 2; if (mode == _MODE_START_UP) { commandExecuted = true; @@ -307,7 +307,7 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r internalState = InternalState::RUNNING; } } else { - *foundId = Max31865Definitions::REQUEST_CONFIG; + *foundId = MAX31865::REQUEST_CONFIG; *foundLen = configReplySize; } } @@ -318,7 +318,7 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { switch (id) { - case (Max31865Definitions::REQUEST_CONFIG): { + case (MAX31865::REQUEST_CONFIG): { if (packet[1] != DEFAULT_CONFIG) { if (warningSwitch) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -342,7 +342,7 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, } break; } - case (Max31865Definitions::REQUEST_LOW_THRESHOLD): { + case (MAX31865::REQUEST_LOW_THRESHOLD): { uint16_t readLowThreshold = packet[1] << 8 | packet[2]; if (readLowThreshold != LOW_THRESHOLD) { #if FSFW_VERBOSE_LEVEL >= 1 @@ -360,7 +360,7 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, commandExecuted = true; break; } - case (Max31865Definitions::REQUEST_HIGH_THRESHOLD): { + case (MAX31865::REQUEST_HIGH_THRESHOLD): { uint16_t readHighThreshold = packet[1] << 8 | packet[2]; if (readHighThreshold != HIGH_THRESHOLD) { #if FSFW_VERBOSE_LEVEL >= 1 @@ -378,7 +378,7 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, commandExecuted = true; break; } - case (Max31865Definitions::REQUEST_RTD): { + case (MAX31865::REQUEST_RTD): { // first bit of LSB reply byte is the fault bit uint8_t faultBit = packet[2] & 0b0000'0001; if (resetFaultBit) { @@ -403,9 +403,9 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, #if OBSW_VERBOSE_LEVEL >= 1 if (debugDivider->checkAndIncrement()) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "Max31865: ObjID " << std::hex << this->getObjectId() << " | RTD " - << std::dec << static_cast(deviceIdx) << ": R[Ohm] " << rtdValue - << " Ohms | Approx T[C]: " << approxTemp << std::endl; + sif::info << "Max31865: " << std::setw(28) << std::left << locString << std::right + << " | R[Ohm] " << rtdValue << " Ohms | Approx T[C]: " << approxTemp + << std::endl; #else sif::printInfo("Max31685: Measured resistance is %f Ohms\n", rtdValue); sif::printInfo("Approximated temperature is %f C\n", approxTemp); @@ -438,7 +438,7 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id, sensorDataset.temperatureCelcius = approxTemp; break; } - case (Max31865Definitions::REQUEST_FAULT_BYTE): { + case (MAX31865::REQUEST_FAULT_BYTE): { faultByte = packet[1]; #if OBSW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -512,10 +512,9 @@ ReturnValue_t Max31865PT1000Handler::getSwitches(const uint8_t **switches, ReturnValue_t Max31865PT1000Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { - localDataPoolMap.emplace(Max31865Definitions::PoolIds::RTD_VALUE, new PoolEntry({0})); - localDataPoolMap.emplace(Max31865Definitions::PoolIds::TEMPERATURE_C, - new PoolEntry({0}, 1, true)); - localDataPoolMap.emplace(Max31865Definitions::PoolIds::FAULT_BYTE, new PoolEntry({0})); + localDataPoolMap.emplace(MAX31865::PoolIds::RTD_VALUE, new PoolEntry({0})); + localDataPoolMap.emplace(MAX31865::PoolIds::TEMPERATURE_C, new PoolEntry({0}, 1, true)); + localDataPoolMap.emplace(MAX31865::PoolIds::FAULT_BYTE, new PoolEntry({0})); poolManager.subscribeForPeriodicPacket(sensorDataset.getSid(), false, 30.0, false); return HasReturnvaluesIF::RETURN_OK; } @@ -530,6 +529,9 @@ void Max31865PT1000Handler::modeChanged() { } } -void Max31865PT1000Handler::setDeviceIdx(uint8_t idx) { deviceIdx = idx; } +void Max31865PT1000Handler::setDeviceInfo(uint8_t idx, const std::string &locString_) { + deviceIdx = idx; + locString = locString_; +} void Max31865PT1000Handler::setDebugMode(bool enable) { this->debugMode = enable; } diff --git a/mission/devices/Max31865PT1000Handler.h b/mission/devices/Max31865PT1000Handler.h index 4f617b9d..9a6b5add 100644 --- a/mission/devices/Max31865PT1000Handler.h +++ b/mission/devices/Max31865PT1000Handler.h @@ -48,7 +48,7 @@ class Max31865PT1000Handler : public DeviceHandlerBase { static constexpr uint8_t DEFAULT_CONFIG = 0b11000001; void setInstantNormal(bool instantNormal); - void setDeviceIdx(uint8_t idx); + void setDeviceInfo(uint8_t idx, const std::string &locString); /** * Expected temperature range is -100 C and 100 C. @@ -109,11 +109,12 @@ class Max31865PT1000Handler : public DeviceHandlerBase { bool resetFaultBit = false; dur_millis_t startTime = 0; + std::string locString; uint8_t faultByte = 0; uint8_t deviceIdx = 0; std::array commandBuffer{0}; - Max31865Definitions::Max31865Set sensorDataset; + MAX31865::Max31865Set sensorDataset; sid_t sensorDatasetSid; #if OBSW_VERBOSE_LEVEL >= 1 diff --git a/mission/devices/devicedefinitions/Max31865Definitions.h b/mission/devices/devicedefinitions/Max31865Definitions.h index 58faaf97..efd81681 100644 --- a/mission/devices/devicedefinitions/Max31865Definitions.h +++ b/mission/devices/devicedefinitions/Max31865Definitions.h @@ -7,9 +7,26 @@ #include "objects/systemObjectList.h" -namespace Max31865Definitions { +namespace MAX31865 { enum PoolIds : lp_id_t { RTD_VALUE, TEMPERATURE_C, FAULT_BYTE }; +enum Wires : unsigned int { TWO_WIRE = 0, THREE_WIRE = 1, FOUR_WIRE = 0 }; + +enum ConvMode : unsigned int { NORM_OFF = 0, AUTO = 1 }; + +enum Bias : unsigned int { ON = 0, OFF = 1 }; + +enum FilterSel : unsigned int { FIFTY_HERTZ = 1, SIXTY_HERTZ = 0 }; + +enum CfgBitPos { + FILTER_SEL = 0, + FAULTY_STATUS_CLEAR = 1, + FDCC = 2, + WIRE_SEL = 4, + ONE_SHOT = 5, + CONV_MODE = 6, + BIAS_SEL = 7 +}; static constexpr DeviceCommandId_t CONFIG_CMD = 0x80; static constexpr DeviceCommandId_t WRITE_HIGH_THRESHOLD = 0x83; @@ -26,6 +43,11 @@ static constexpr DeviceCommandId_t CLEAR_FAULT_BYTE = 0x08; static constexpr uint32_t MAX31865_SET_ID = REQUEST_RTD; static constexpr uint8_t CLEAR_FAULT_BIT_VAL = 0b0000'0010; +static constexpr uint8_t WRITE_BIT = 0b10000000; + +static constexpr uint8_t REG_CONFIG = 0x00; +static constexpr uint8_t REG_RTD = 0x01; + static constexpr size_t MAX_REPLY_SIZE = 5; class Max31865Set : public StaticLocalDataSet { @@ -48,6 +70,6 @@ class Max31865Set : public StaticLocalDataSet { lp_var_t errorByte = lp_var_t(sid.objectId, PoolIds::FAULT_BYTE, this); }; -} // namespace Max31865Definitions +} // namespace MAX31865 #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_MAX13865DEFINITIONS_H_ */ diff --git a/mission/devices/devicedefinitions/Max31865DeviceDefinitions.cpp b/mission/devices/devicedefinitions/Max31865DeviceDefinitions.cpp new file mode 100644 index 00000000..0f050093 --- /dev/null +++ b/mission/devices/devicedefinitions/Max31865DeviceDefinitions.cpp @@ -0,0 +1 @@ +#include "Max31865Definitions.h" diff --git a/mission/system/TcsBoardAssembly.cpp b/mission/system/TcsBoardAssembly.cpp index f011c931..ec4bce70 100644 --- a/mission/system/TcsBoardAssembly.cpp +++ b/mission/system/TcsBoardAssembly.cpp @@ -10,7 +10,7 @@ TcsBoardAssembly::TcsBoardAssembly(object_id_t objectId, object_id_t parentId, eventQueue = QueueFactory::instance()->createMessageQueue(24); ModeListEntry entry; for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { - entry.setObject(helper.rtdIds[idx]); + entry.setObject(helper.rtdInfos[idx].first); entry.setMode(MODE_OFF); entry.setSubmode(SUBMODE_NONE); entry.setInheritSubmode(false); @@ -57,7 +57,7 @@ ReturnValue_t TcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_ int devsInWrongMode = 0; try { for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { - if (childrenMap.at(helper.rtdIds[idx]).mode != wantedMode) { + if (childrenMap.at(helper.rtdInfos[idx].first).mode != wantedMode) { devsInWrongMode++; } } @@ -93,8 +93,8 @@ ReturnValue_t TcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t su ReturnValue_t TcsBoardAssembly::initialize() { ReturnValue_t result = RETURN_OK; - for (const auto& obj : helper.rtdIds) { - result = registerChild(obj); + for (const auto& obj : helper.rtdInfos) { + result = registerChild(obj.first); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -126,8 +126,8 @@ ReturnValue_t TcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s object_id_t objId = 0; try { for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) { - devMode = childrenMap.at(helper.rtdIds[idx]).mode; - objId = helper.rtdIds[idx]; + devMode = childrenMap.at(helper.rtdInfos[idx].first).mode; + objId = helper.rtdInfos[idx].first; if (mode == devMode) { modeTable[idx].setMode(mode); } else if (mode == DeviceHandlerIF::MODE_NORMAL) { diff --git a/mission/system/TcsBoardAssembly.h b/mission/system/TcsBoardAssembly.h index 832f335d..eb42abbf 100644 --- a/mission/system/TcsBoardAssembly.h +++ b/mission/system/TcsBoardAssembly.h @@ -6,9 +6,10 @@ #include struct TcsBoardHelper { - TcsBoardHelper(std::array rtdIds) : rtdIds(rtdIds) {} + TcsBoardHelper(std::array, 16> rtdInfos) + : rtdInfos(std::move(rtdInfos)) {} - std::array rtdIds = {}; + std::array, 16> rtdInfos = {}; }; class TcsBoardAssembly : public AssemblyBase, public ConfirmsFailuresIF { diff --git a/tmtc b/tmtc index 1e25b08e..6b7b07c3 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 1e25b08e40db28103b91814f7de5a47dae5b9e76 +Subproject commit 6b7b07c3409fc24a8585c39e308156b3657c655e