diff --git a/fsfw b/fsfw index d74a373f..c4a05598 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit d74a373f1d6bc341c11d7ad89f369da5ff957928 +Subproject commit c4a055986c30526d15dbb227e00bb131f22a7365 diff --git a/linux/devices/CMakeLists.txt b/linux/devices/CMakeLists.txt index a2bfa035..5a367b28 100644 --- a/linux/devices/CMakeLists.txt +++ b/linux/devices/CMakeLists.txt @@ -1,6 +1,5 @@ target_sources(${OBSW_NAME} PRIVATE SolarArrayDeploymentHandler.cpp - PayloadPcduHandler.cpp SusHandler.cpp ) diff --git a/linux/devices/devicedefinitions/payloadPcduDefinitions.h b/linux/devices/devicedefinitions/payloadPcduDefinitions.h deleted file mode 100644 index a2c362a0..00000000 --- a/linux/devices/devicedefinitions/payloadPcduDefinitions.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_ -#define LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_ - -#include - -namespace plpcdu { - -static constexpr size_t MAX_ADC_REPLY_SIZE = 32; - -} - -#endif /* LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_ */ diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 2e956c0e..2f434d09 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -9,6 +9,7 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE ACUHandler.cpp SyrlinksHkHandler.cpp Max31865PT1000Handler.cpp + PayloadPcduHandler.cpp IMTQHandler.cpp HeaterHandler.cpp PlocMPSoCHandler.cpp diff --git a/linux/devices/PayloadPcduHandler.cpp b/mission/devices/PayloadPcduHandler.cpp similarity index 63% rename from linux/devices/PayloadPcduHandler.cpp rename to mission/devices/PayloadPcduHandler.cpp index 08ebd6a5..35551eba 100644 --- a/linux/devices/PayloadPcduHandler.cpp +++ b/mission/devices/PayloadPcduHandler.cpp @@ -1,10 +1,9 @@ #include "PayloadPcduHandler.h" - #include "devices/gpioIds.h" PayloadPcduHandler::PayloadPcduHandler(object_id_t objectId, object_id_t comIF, CookieIF* cookie, GpioIF* gpioIF) - : DeviceHandlerBase(objectId, comIF, cookie), gpioIF(gpioIF) {} + : DeviceHandlerBase(objectId, comIF, cookie), adcSet(this), gpioIF(gpioIF) {} void PayloadPcduHandler::doStartUp() { if ((state != States::PCDU_OFF) and (state != States::ON_TRANS_SSR)) { @@ -24,6 +23,7 @@ void PayloadPcduHandler::doStartUp() { transitionOk = false; // We are now in ON mode setMode(MODE_ON); + adcState = AdcStates::BOOT_DELAY; // The ADC can now be read. If the values are not close to zero, we should not allow // transition monMode = MonitoringMode::CLOSE_TO_ZERO; @@ -33,6 +33,18 @@ void PayloadPcduHandler::doStartUp() { void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { if (mode == _MODE_TO_NORMAL) { + if(adcState == AdcStates::BOOT_DELAY) { + if (adcCountdown.hasTimedOut()) { + adcState = AdcStates::SEND_SETUP; + adcCmdExecuted = false; + } + } + if(adcState == AdcStates::SEND_SETUP) { + if(adcCmdExecuted) { + adcState = AdcStates::NORMAL; + adcCmdExecuted = false; + } + } if (state == States::ON_TRANS_ADC_CLOSE_ZERO) { if (not commandExecuted) { countdown.resetTimer(); @@ -125,28 +137,86 @@ void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { void PayloadPcduHandler::doShutDown() {} ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { - return HasReturnvaluesIF::RETURN_OK; + switch(adcState) { + case(AdcStates::SEND_SETUP): { + *id = plpcdu::SETUP_CMD; + buildCommandFromCommand(*id, nullptr, 0); + break; + } + case(AdcStates::NORMAL): { + *id = plpcdu::READ_WITH_TEMP; + buildCommandFromCommand(*id, nullptr, 0); + break; + } + default: { + break; + } + } + return NOTHING_TO_SEND; } ReturnValue_t PayloadPcduHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { + if(adcState == AdcStates::SEND_SETUP) { + *id = plpcdu::SETUP_CMD; + buildCommandFromCommand(*id, nullptr, 0); + } return HasReturnvaluesIF::RETURN_OK; } -void PayloadPcduHandler::fillCommandAndReplyMap() {} +void PayloadPcduHandler::fillCommandAndReplyMap() { + insertInCommandAndReplyMap(plpcdu::READ_CMD, 2, &adcSet); + insertInCommandAndReplyMap(plpcdu::READ_TEMP, 1, &adcSet); + insertInCommandAndReplyMap(plpcdu::READ_WITH_TEMP, 1, &adcSet); + insertInCommandAndReplyMap(plpcdu::SETUP_CMD, 1); +} ReturnValue_t PayloadPcduHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData, size_t commandDataLen) { - return HasReturnvaluesIF::RETURN_OK; + switch(deviceCommand) { + case(plpcdu::SETUP_CMD): { + cmdBuf[0] = plpcdu::SETUP_BYTE; + rawPacket = cmdBuf.data(); + rawPacketLen = 1; + break; + } + case(plpcdu::READ_CMD): { + max1227::prepareExternallyClockedRead0ToN(cmdBuf.data(), plpcdu::CHANNEL_N, rawPacketLen); + rawPacket = cmdBuf.data(); + break; + } + case(plpcdu::READ_TEMP): { + max1227::prepareExternallyClockedTemperatureRead(cmdBuf.data(), rawPacketLen); + rawPacket = cmdBuf.data(); + break; + } + case(plpcdu::READ_WITH_TEMP): { + size_t sz = 0; + max1227::prepareExternallyClockedRead0ToN(cmdBuf.data(), plpcdu::CHANNEL_N, sz); + max1227::prepareExternallyClockedTemperatureRead(cmdBuf.data() + sz, sz); + rawPacketLen = sz; + rawPacket = cmdBuf.data(); + } + } + return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; } ReturnValue_t PayloadPcduHandler::scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId, size_t* foundLen) { + // SPI is full duplex + *foundId = getPendingCommand(); + *foundLen = remainingSize; return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t PayloadPcduHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) { + using namespace plpcdu; + switch(id) { + case(SETUP_CMD): { + break; + } + } return HasReturnvaluesIF::RETURN_OK; } @@ -157,5 +227,18 @@ uint32_t PayloadPcduHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo ReturnValue_t PayloadPcduHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) { + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_0, &ain0); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_1, &ain1); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_2, &ain2); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_3, &ain3); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_4, &ain4); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_5, &ain5); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_6, &ain6); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_7, &ain7); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_8, &ain8); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_9, &ain9); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_10, &ain10); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_11, &ain11); + localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::TEMP, &tempC); return HasReturnvaluesIF::RETURN_OK; } diff --git a/linux/devices/PayloadPcduHandler.h b/mission/devices/PayloadPcduHandler.h similarity index 74% rename from linux/devices/PayloadPcduHandler.h rename to mission/devices/PayloadPcduHandler.h index 53a96a5e..4f99cc1a 100644 --- a/linux/devices/PayloadPcduHandler.h +++ b/mission/devices/PayloadPcduHandler.h @@ -3,7 +3,7 @@ #include #include - +#include "devicedefinitions/payloadPcduDefinitions.h" #include "fsfw_hal/common/gpio/GpioIF.h" /** @@ -48,13 +48,34 @@ class PayloadPcduHandler : DeviceHandlerBase { enum class MonitoringMode { NONE, CLOSE_TO_ZERO, NEGATIVE } monMode = MonitoringMode::NONE; + enum class AdcStates { OFF, BOOT_DELAY, SEND_SETUP, NORMAL } adcState = AdcStates::OFF; + + plpcdu::PlPcduAdcSet adcSet; + std::array cmdBuf = {}; // This variable is tied to DRO +6 V voltage. Voltages, currents are monitored and the experiment // is shut down immediately if there is a negative voltage. bool transitionOk = false; bool commandExecuted = false; + bool adcCmdExecuted = false; + uint8_t tempReadDivisor = 1; Countdown countdown = Countdown(5000); + Countdown adcCountdown = Countdown(50); GpioIF* gpioIF; + PoolEntry ain0 = PoolEntry({0}); + PoolEntry ain1 = PoolEntry({0}); + PoolEntry ain2 = PoolEntry({0}); + PoolEntry ain3 = PoolEntry({0}); + PoolEntry ain4 = PoolEntry({0}); + PoolEntry ain5 = PoolEntry({0}); + PoolEntry ain6 = PoolEntry({0}); + PoolEntry ain7 = PoolEntry({0}); + PoolEntry ain8 = PoolEntry({0}); + PoolEntry ain9 = PoolEntry({0}); + PoolEntry ain10 = PoolEntry({0}); + PoolEntry ain11 = PoolEntry({0}); + PoolEntry tempC = PoolEntry({0.0}); + void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; void doStartUp() override; void doShutDown() override; diff --git a/mission/devices/devicedefinitions/payloadPcduDefinitions.h b/mission/devices/devicedefinitions/payloadPcduDefinitions.h new file mode 100644 index 00000000..22e7b504 --- /dev/null +++ b/mission/devices/devicedefinitions/payloadPcduDefinitions.h @@ -0,0 +1,69 @@ +#ifndef LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_ +#define LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_ + +#include +#include +#include "mission/devices/max1227.h" +#include + +namespace plpcdu { + +using namespace max1227; + +enum PlPcduPoolIds: uint32_t { + AIN_0 = 0, + AIN_1 = 1, + AIN_2 = 2, + AIN_3 = 3, + AIN_4 = 4, + AIN_5 = 5, + AIN_6 = 6, + AIN_7 = 7, + AIN_8 = 8, + AIN_9 = 9, + AIN_10 = 10, + AIN_11 = 11, + TEMP = 12 +}; + +static constexpr size_t MAX_ADC_REPLY_SIZE = 64; + +static constexpr DeviceCommandId_t READ_CMD = 0; +static constexpr DeviceCommandId_t SETUP_CMD = 1; +static constexpr DeviceCommandId_t READ_TEMP = 2; +static constexpr DeviceCommandId_t READ_WITH_TEMP = 3; + +static constexpr uint8_t SETUP_BYTE = max1227::buildSetupByte(ClkSel::EXT_CONV_EXT_TIMED, + RefSel::INT_REF_NO_WAKEUP, DiffSel::NONE_0); + +static constexpr uint32_t ADC_SET_ID = READ_CMD; +static constexpr uint8_t CHANNELS_NUM = 12; +static constexpr uint8_t CHANNEL_N = CHANNELS_NUM - 1; +// Store temperature as well +static constexpr size_t DATASET_ENTRIES = CHANNELS_NUM + 1; + +class PlPcduAdcSet : public StaticLocalDataSet { + public: + PlPcduAdcSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, ADC_SET_ID) {} + + PlPcduAdcSet(object_id_t objectId) + : StaticLocalDataSet(sid_t(objectId, ADC_SET_ID)) {} + + lp_var_t ain0 = lp_var_t(sid.objectId, AIN_0, this); + lp_var_t ain1 = lp_var_t(sid.objectId, AIN_1, this); + lp_var_t ain2= lp_var_t(sid.objectId, AIN_2, this); + lp_var_t ain3 = lp_var_t(sid.objectId, AIN_3, this); + lp_var_t ain4 = lp_var_t(sid.objectId, AIN_4, this); + lp_var_t ain5 = lp_var_t(sid.objectId, AIN_5, this); + lp_var_t ain6 = lp_var_t(sid.objectId, AIN_6, this); + lp_var_t ain7 = lp_var_t(sid.objectId, AIN_7, this); + lp_var_t ain8 = lp_var_t(sid.objectId, AIN_8, this); + lp_var_t ain9 = lp_var_t(sid.objectId, AIN_9, this); + lp_var_t ain10 = lp_var_t(sid.objectId, AIN_10, this); + lp_var_t ain11 = lp_var_t(sid.objectId, AIN_11, this); + lp_var_t tempC = lp_var_t(sid.objectId, TEMP, this); +}; + +} + +#endif /* LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_ */ diff --git a/mission/devices/max1227.cpp b/mission/devices/max1227.cpp index 88cab185..f89e161e 100644 --- a/mission/devices/max1227.cpp +++ b/mission/devices/max1227.cpp @@ -2,14 +2,6 @@ #include -uint8_t max1227::buildConvByte(ScanModes scanMode, uint8_t channel, bool readTemp) { - return (1 << 7) | (channel << 3) | (scanMode << 1) | readTemp; -} - -uint8_t max1227::buildSetupByte(ClkSel clkSel, RefSel refSel, DiffSel diffSel) { - return (1 << 6) | (clkSel << 4) | (refSel << 2) | diffSel; -} - void max1227::prepareExternallyClockedSingleChannelRead(uint8_t *spiBuf, uint8_t channel, size_t &sz) { spiBuf[0] = buildConvByte(ScanModes::N_ONCE, channel, false); @@ -18,21 +10,19 @@ void max1227::prepareExternallyClockedSingleChannelRead(uint8_t *spiBuf, uint8_t sz = 3; } -uint8_t max1227::buildResetByte(bool fifoOnly) { return (1 << 4) | (fifoOnly << 3); } - void max1227::prepareExternallyClockedRead0ToN(uint8_t *spiBuf, uint8_t n, size_t &sz) { for (uint8_t idx = 0; idx <= n; idx++) { spiBuf[idx * 2] = buildConvByte(ScanModes::N_ONCE, idx, false); spiBuf[idx * 2 + 1] = 0x00; } spiBuf[(n + 1) * 2] = 0x00; - sz = (n + 1) * 2 + 1; + sz += (n + 1) * 2 + 1; } void max1227::prepareExternallyClockedTemperatureRead(uint8_t *spiBuf, size_t &sz) { spiBuf[0] = buildConvByte(ScanModes::N_ONCE, 0, true); std::memset(spiBuf + 1, 0, 24); - sz = 25; + sz += 25; } float max1227::getTemperature(int16_t temp) { return static_cast(temp) * 0.125; } diff --git a/mission/devices/max1227.h b/mission/devices/max1227.h index bf76a81b..9d29b38c 100644 --- a/mission/devices/max1227.h +++ b/mission/devices/max1227.h @@ -40,9 +40,17 @@ enum DiffSel : uint8_t { BIPOLAR_CFG = 0b11 }; -uint8_t buildResetByte(bool fifoOnly); -uint8_t buildConvByte(ScanModes scanMode, uint8_t channel, bool readTemp); -uint8_t buildSetupByte(ClkSel clkSel, RefSel refSel, DiffSel diffSel); +constexpr uint8_t buildResetByte(bool fifoOnly) { + return (1 << 4) | (fifoOnly << 3); +} + +constexpr uint8_t buildConvByte(ScanModes scanMode, uint8_t channel, bool readTemp) { + return (1 << 7) | (channel << 3) | (scanMode << 1) | readTemp; +} + +constexpr uint8_t buildSetupByte(ClkSel clkSel, RefSel refSel, DiffSel diffSel) { + return (1 << 6) | (clkSel << 4) | (refSel << 2) | diffSel; +} /** * If there is a wakeup delay, there needs to be a 65 us delay between sending