diff --git a/README.md b/README.md index adb3c3e5..6ad16a87 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Target systems: relevant pages. The most recent datasheet can be found [here](https://trac2.xiphos.ca/manual/wiki/Q7RevB/UserManual). * Linux OS built with Yocto 2.5 - * Linux Kernel https://github.com/XiphosSystemsCorp/linux-xlnx.git . EIVE version can be found + * [Linux Kernel](https://github.com/XiphosSystemsCorp/linux-xlnx.git) . EIVE version can be found [here](https://github.com/spacefisch/linux-xlnx) . Pre-compiled files can be found [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/q7s-linux-components&fileid=777299). * Q7S base project can be found [here](https://egit.irs.uni-stuttgart.de/eive/q7s-base) @@ -1093,7 +1093,7 @@ The [TCF agent](https://wiki.eclipse.org/TCF) can be used to perform remote debu 1. Install the TCF agent plugin in Eclipse from the [releases](https://www.eclipse.org/tcf/downloads.php). Go to Help → Install New Software and use the download page, for - example https://download.eclipse.org/tools/tcf/releases/1.6/1.6.2/ to search for the plugin and install it. + example https://download.eclipse.org/tools/tcf/releases/1.7/1.7.0/ to search for the plugin and install it. You can find the newest version [here](https://www.eclipse.org/tcf/downloads.php) 2. Go to Window → Perspective → Open Perspective and open the **Target Explorer Perspective**. Here, the Q7S should show up if the local port forwarding was set up as explained previously. diff --git a/bsp_q7s/callbacks/CMakeLists.txt b/bsp_q7s/callbacks/CMakeLists.txt index 8c83e26f..a85bf6fb 100644 --- a/bsp_q7s/callbacks/CMakeLists.txt +++ b/bsp_q7s/callbacks/CMakeLists.txt @@ -1,4 +1,5 @@ target_sources(${TARGET_NAME} PRIVATE rwSpiCallback.cpp gnssCallback.cpp + pcduSwitchCb.cpp ) diff --git a/bsp_q7s/callbacks/pcduSwitchCb.cpp b/bsp_q7s/callbacks/pcduSwitchCb.cpp new file mode 100644 index 00000000..ec5f4dc5 --- /dev/null +++ b/bsp_q7s/callbacks/pcduSwitchCb.cpp @@ -0,0 +1,32 @@ +#include "pcduSwitchCb.h" + +#include + +#include "devices/gpioIds.h" + +void pcdu::switchCallback(GOMSPACE::Pdu pdu, uint8_t channel, bool state, void* args) { + LinuxLibgpioIF* gpioComIF = reinterpret_cast(args); + if (gpioComIF == nullptr) { + return; + } + if (pdu == GOMSPACE::Pdu::PDU1) { + PDU1::SwitchChannels typedChannel = static_cast(channel); + if (typedChannel == PDU1::SwitchChannels::ACS_A_SIDE) { + if (state) { + gpioComIF->pullHigh(gpioIds::GNSS_0_NRESET); + } else { + gpioComIF->pullLow(gpioIds::GNSS_0_NRESET); + } + } + + } else if (pdu == GOMSPACE::Pdu::PDU2) { + PDU2::SwitchChannels typedChannel = static_cast(channel); + if (typedChannel == PDU2::SwitchChannels::ACS_B_SIDE) { + if (state) { + gpioComIF->pullHigh(gpioIds::GNSS_1_NRESET); + } else { + gpioComIF->pullLow(gpioIds::GNSS_1_NRESET); + } + } + } +} diff --git a/bsp_q7s/callbacks/pcduSwitchCb.h b/bsp_q7s/callbacks/pcduSwitchCb.h new file mode 100644 index 00000000..d0f2b748 --- /dev/null +++ b/bsp_q7s/callbacks/pcduSwitchCb.h @@ -0,0 +1,14 @@ +#ifndef BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_ +#define BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_ + +#include + +#include "mission/devices/devicedefinitions/GomspaceDefinitions.h" + +namespace pcdu { + +void switchCallback(GOMSPACE::Pdu pdu, uint8_t channel, bool state, void* args); + +} + +#endif /* BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_ */ diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index dce7f27e..96a43a81 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -206,7 +206,7 @@ void initmission::initTasks() { #endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif - acsCtrl->startTask(); + // acsCtrl->startTask(); sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 4c57ab34..7c089465 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -5,6 +5,7 @@ #include "OBSWConfig.h" #include "bsp_q7s/boardtest/Q7STestTask.h" #include "bsp_q7s/callbacks/gnssCallback.h" +#include "bsp_q7s/callbacks/pcduSwitchCb.h" #include "bsp_q7s/callbacks/rwSpiCallback.h" #include "bsp_q7s/core/CoreController.h" #include "bsp_q7s/devices/PlocMemoryDumper.h" @@ -122,13 +123,14 @@ void ObjectFactory::produce(void* args) { #if BOARD_TE0720 == 0 new CoreController(objects::CORE_CONTROLLER); - createPcduComponents(); + createPcduComponents(gpioComIF); createRadSensorComponent(gpioComIF); createSunSensorComponents(gpioComIF, spiComIF); #if OBSW_ADD_ACS_BOARD == 1 createAcsBoardComponents(gpioComIF, uartComIF); -#endif /* OBSW_ADD_ACS_BOARD == 1 */ +#endif + createHeaterComponents(); createSolarArrayDeploymentComponents(); #if OBSW_ADD_SYRLINKS == 1 @@ -234,7 +236,7 @@ void ObjectFactory::createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, Ua #endif } -void ObjectFactory::createPcduComponents() { +void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF) { CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, addresses::P60DOCK); CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU1); CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU2); @@ -244,8 +246,10 @@ void ObjectFactory::createPcduComponents() { new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, p60DockCspCookie); PDU1Handler* pdu1handler = new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, pdu1CspCookie); + pdu1handler->assignChannelHookFunction(&pcdu::switchCallback, gpioComIF); PDU2Handler* pdu2handler = new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie); + pdu2handler->assignChannelHookFunction(&pcdu::switchCallback, gpioComIF); ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie); new PCDUHandler(objects::PCDU_HANDLER, 50); @@ -472,6 +476,7 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI gpioComIF->addGpios(gpioCookieAcsBoard); +#if OBSW_ADD_ACS_HANDLERS == 1 std::string spiDev = q7s::SPI_DEFAULT_DEV; SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev, @@ -561,6 +566,7 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI resetArgsGnss0.waitPeriodMs = 100; auto gpsHandler0 = new GPSHyperionHandler(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps); gpsHandler0->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss0); +#endif /* OBSW_ADD_ACS_HANDLERS == 1 */ } void ObjectFactory::createHeaterComponents() { @@ -857,6 +863,7 @@ void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF) { rwHandler1->setStartUpImmediately(); #endif rw1SpiCookie->setCallbackArgs(rwHandler1); + rwHandler1->setStartUpImmediately(); auto rwHandler2 = new RwHandler(objects::RW2, objects::SPI_COM_IF, rw2SpiCookie, gpioComIF, gpioIds::EN_RW2); diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index 47e06e33..8fa4a147 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -13,7 +13,7 @@ void produce(void* args); void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF, SpiComIF** spiComIF); void createTmpComponents(); -void createPcduComponents(); +void createPcduComponents(LinuxLibgpioIF* gpioComIF); void createRadSensorComponent(LinuxLibgpioIF* gpioComIF); void createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF); void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF); diff --git a/bsp_q7s/core/obsw.cpp b/bsp_q7s/core/obsw.cpp index 04163a82..a69e94a2 100644 --- a/bsp_q7s/core/obsw.cpp +++ b/bsp_q7s/core/obsw.cpp @@ -29,7 +29,7 @@ int obsw::obsw() { if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { sif::warning << "File " << watchdog::RUNNING_FILE_NAME << " exists so the software might " - "already be running. Check if obsw systemd service has been stopped." + "already be running. Aborting.." << std::endl; return OBSW_ALREADY_RUNNING; } diff --git a/cmake/scripts/Q7S/win_path_helper_xilinx_tools.sh b/cmake/scripts/Q7S/q7s-env-win.sh similarity index 100% rename from cmake/scripts/Q7S/win_path_helper_xilinx_tools.sh rename to cmake/scripts/Q7S/q7s-env-win.sh diff --git a/cmake/scripts/Q7S/q7s-env.sh b/cmake/scripts/Q7S/q7s-env.sh new file mode 100755 index 00000000..818ff213 --- /dev/null +++ b/cmake/scripts/Q7S/q7s-env.sh @@ -0,0 +1,7 @@ +#!/bin/bash -i +export PATH=$PATH:"$HOME/EIVE/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin" +export CROSS_COMPILE="arm-linux-gnueabihf" + +export Q7S_SYSROOT="$HOME/Xilinx/cortexa9hf-neon-xiphos-linux-gnueabi" +export CONSOLE_PREFIX="[Q7S ENV]" +/bin/bash diff --git a/cmake/scripts/Q7S/unix_path_helper.sh b/cmake/scripts/Q7S/unix_path_helper.sh deleted file mode 100644 index 296bfdd8..00000000 --- a/cmake/scripts/Q7S/unix_path_helper.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -export PATH=$PATH:"/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin" -export CROSS_COMPILE="arm-linux-gnueabihf" - -export Q7S_SYSROOT="$HOME/Xilinx/cortexa9hf-neon-xiphos-linux-gnueabi" - diff --git a/fsfw b/fsfw index c1e0bcee..9b770602 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit c1e0bcee6db652d6c474c87a4099e61ecf86b694 +Subproject commit 9b77060295c9c32ebfc2e7cf6517eb2e66216191 diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 06e0b841..f52b2f9a 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -44,7 +44,8 @@ debugging. */ #define OBSW_ADD_PLOC_SUPERVISOR 0 #define OBSW_ADD_PLOC_MPSOC 0 #define OBSW_ADD_SUN_SENSORS 0 -#define OBSW_ADD_ACS_BOARD 0 +#define OBSW_ADD_ACS_BOARD 1 +#define OBSW_ADD_ACS_HANDLERS 0 #define OBSW_ADD_RW 0 #define OBSW_ADD_RTD_DEVICES 0 #define OBSW_ADD_TMP_DEVICES 0 diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 814e5c2d..0675cf0d 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -435,7 +435,7 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::RW4, length * 0.8, DeviceHandlerIF::GET_READ); #endif -#if OBSW_ADD_ACS_BOARD == 1 +#if OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1 bool enableAside = true; bool enableBside = false; if (enableAside) { @@ -501,7 +501,7 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); } -#endif /* OBSW_ADD_ACS_BOARD == 1 */ +#endif /* OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1 */ ReturnValue_t seqCheck = thisSequence->checkSequence(); if (seqCheck != HasReturnvaluesIF::RETURN_OK) { diff --git a/mission/devices/ACUHandler.cpp b/mission/devices/ACUHandler.cpp index 239a0c7a..60e26302 100644 --- a/mission/devices/ACUHandler.cpp +++ b/mission/devices/ACUHandler.cpp @@ -273,7 +273,8 @@ ReturnValue_t ACUHandler::initializeLocalDataPool(localpool::DataPool &localData return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t ACUHandler::deviceSpecificCommand(DeviceCommandId_t cmd) { +ReturnValue_t ACUHandler::childCommandHook(DeviceCommandId_t cmd, const uint8_t *commandData, + size_t commandDataLen) { switch (cmd) { case PRINT_CHANNEL_STATS: { printChannelStats(); diff --git a/mission/devices/ACUHandler.h b/mission/devices/ACUHandler.h index 0d93c5fe..f3af5eae 100644 --- a/mission/devices/ACUHandler.h +++ b/mission/devices/ACUHandler.h @@ -28,7 +28,8 @@ class ACUHandler : public GomspaceDeviceHandler { virtual void fillCommandAndReplyMap() override; - virtual ReturnValue_t deviceSpecificCommand(DeviceCommandId_t cmd) override; + virtual ReturnValue_t childCommandHook(DeviceCommandId_t cmd, const uint8_t* commandData, + size_t commandDataLen) override; private: static const DeviceCommandId_t PRINT_CHANNEL_STATS = 51; diff --git a/mission/devices/GomspaceDeviceHandler.cpp b/mission/devices/GomspaceDeviceHandler.cpp index eea1368a..ce86d13a 100644 --- a/mission/devices/GomspaceDeviceHandler.cpp +++ b/mission/devices/GomspaceDeviceHandler.cpp @@ -36,7 +36,7 @@ ReturnValue_t GomspaceDeviceHandler::buildTransitionDeviceCommand(DeviceCommandI ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData, size_t commandDataLen) { - ReturnValue_t result; + ReturnValue_t result = childCommandHook(deviceCommand, commandData, commandDataLen); switch (deviceCommand) { case (GOMSPACE::PING): { result = generatePingCommand(commandData, commandDataLen); @@ -82,7 +82,7 @@ ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(DeviceCommandId_t d break; } default: - return deviceSpecificCommand(deviceCommand); + return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; } return HasReturnvaluesIF::RETURN_OK; } @@ -170,6 +170,7 @@ ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, if (*packet != PARAM_SET_OK) { return HasReturnvaluesIF::RETURN_FAILED; } + setParamCallback(setParamCacher, true); break; } case (GOMSPACE::REQUEST_HK_TABLE): { @@ -186,8 +187,7 @@ void GomspaceDeviceHandler::setNormalDatapoolEntriesInvalid() {} ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* commandData, size_t commandDataLen) { - SetParamMessageUnpacker setParamMessageUnpacker; - ReturnValue_t result = setParamMessageUnpacker.deSerialize(&commandData, &commandDataLen, + ReturnValue_t result = setParamCacher.deSerialize(&commandData, &commandDataLen, SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { sif::error << "GomspaceDeviceHandler: Failed to deserialize set parameter " @@ -195,8 +195,12 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* comm << std::endl; return result; } + result = setParamCallback(setParamCacher, false); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } /* Get and check address */ - uint16_t address = setParamMessageUnpacker.getAddress(); + uint16_t address = setParamCacher.getAddress(); if (address > maxConfigTableAddress) { sif::error << "GomspaceDeviceHandler: Invalid address for set parameter " << "action" << std::endl; @@ -207,8 +211,8 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* comm uint16_t total = 0; /* CSP reply only contains the transaction state */ uint16_t querySize = 1; - const uint8_t* parameterPtr = setParamMessageUnpacker.getParameter(); - uint8_t parameterSize = setParamMessageUnpacker.getParameterSize(); + const uint8_t* parameterPtr = setParamCacher.getParameter(); + uint8_t parameterSize = setParamCacher.getParameterSize(); uint16_t payloadlength = sizeof(address) + parameterSize; /* Generate command for CspComIF */ @@ -335,6 +339,17 @@ void GomspaceDeviceHandler::generateRebootCommand() { rawPacketLen = cspPacketLen; } +ReturnValue_t GomspaceDeviceHandler::childCommandHook(DeviceCommandId_t cmd, + const uint8_t* commandData, + size_t commandDataLen) { + return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; +} + +ReturnValue_t GomspaceDeviceHandler::setParamCallback(SetParamMessageUnpacker& unpacker, + bool afterExecution) { + return HasReturnvaluesIF::RETURN_OK; +} + ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd() { WatchdogResetCommand watchdogResetCommand; size_t cspPacketLen = 0; @@ -386,10 +401,6 @@ LocalPoolDataSetBase* GomspaceDeviceHandler::getDataSetHandle(sid_t sid) { } } -ReturnValue_t GomspaceDeviceHandler::deviceSpecificCommand(DeviceCommandId_t cmd) { - return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; -} - void GomspaceDeviceHandler::setModeNormal() { mode = MODE_NORMAL; } ReturnValue_t GomspaceDeviceHandler::printStatus(DeviceCommandId_t cmd) { diff --git a/mission/devices/GomspaceDeviceHandler.h b/mission/devices/GomspaceDeviceHandler.h index c9c08609..efe18ee5 100644 --- a/mission/devices/GomspaceDeviceHandler.h +++ b/mission/devices/GomspaceDeviceHandler.h @@ -1,6 +1,8 @@ #ifndef MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_ #define MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_ +#include + #include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "mission/devices/devicedefinitions/GomspaceDefinitions.h" #include "returnvalues/classIds.h" @@ -101,17 +103,31 @@ class GomspaceDeviceHandler : public DeviceHandlerBase { virtual LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override; /** - * @brief Can be used by gomspace devices to implement device specific commands. + * @brief Can be overriden by child classes to implement device specific commands. + * @return Return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED to let this handler handle + * the command or RETURN_OK if the child handles the command */ - virtual ReturnValue_t deviceSpecificCommand(DeviceCommandId_t cmd); + virtual ReturnValue_t childCommandHook(DeviceCommandId_t cmd, const uint8_t *commandData, + size_t commandDataLen); private: + SetParamMessageUnpacker setParamCacher; /** * @brief Function to generate the command to set a parameter. Command * will be sent to the ComIF over the rawPacket buffer. */ ReturnValue_t generateSetParamCommand(const uint8_t *commandData, size_t commandDataLen); + /** + * Callback is called on a parameter set command. It is called before executing it and after + * after successful execution + * @param unpacker Passed before + * @param beforeSet False for callback before execution, true if called after successful + * execution + * @return + */ + virtual ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExecution); + /** * @brief Function to generate the command to get a parameter from a * gomspace device. Command will be sent to the ComIF over the diff --git a/mission/devices/PDU1Handler.cpp b/mission/devices/PDU1Handler.cpp index a1486588..d1276c7f 100644 --- a/mission/devices/PDU1Handler.cpp +++ b/mission/devices/PDU1Handler.cpp @@ -1,6 +1,7 @@ #include "PDU1Handler.h" #include +#include #include "OBSWConfig.h" @@ -67,6 +68,60 @@ void PDU1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pac #endif } +void PDU1Handler::assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void *args) { + this->channelSwitchHook = hook; + this->hookArgs = args; +} + +ReturnValue_t PDU1Handler::setParamCallback(SetParamMessageUnpacker &unpacker, bool afterExecution) { + using namespace PDU1; + GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU1; + if(not afterExecution) { + return HasReturnvaluesIF::RETURN_OK; + } + if (channelSwitchHook != nullptr and unpacker.getParameterSize() == 1) { + switch (unpacker.getAddress()) { + case (CONFIG_ADDRESS_OUT_EN_TCS_BOARD_3V3): { + channelSwitchHook(pdu, 0, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_SYRLINKS): { + channelSwitchHook(pdu, 1, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_STAR_TRACKER): { + channelSwitchHook(pdu, 2, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_MGT): { + channelSwitchHook(pdu, 3, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_SUS_NOMINAL): { + channelSwitchHook(pdu, 4, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_SOLAR_CELL_EXP): { + channelSwitchHook(pdu, 5, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_PLOC): { + channelSwitchHook(pdu, 6, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_A): { + channelSwitchHook(pdu, 7, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_CHANNEL8): { + channelSwitchHook(pdu, 8, unpacker.getParameter()[0], hookArgs); + break; + } + } + } + return HasReturnvaluesIF::RETURN_OK; +} + void PDU1Handler::parseHkTableReply(const uint8_t *packet) { uint16_t dataOffset = 0; PoolReadGuard pg(&pdu1HkTableDataset); diff --git a/mission/devices/PDU1Handler.h b/mission/devices/PDU1Handler.h index 0715b078..c140648b 100644 --- a/mission/devices/PDU1Handler.h +++ b/mission/devices/PDU1Handler.h @@ -27,6 +27,8 @@ class PDU1Handler : public GomspaceDeviceHandler { virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; + void assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void* args); + protected: /** * @brief In MODE_NORMAL, a command will be built periodically by this function. @@ -35,9 +37,13 @@ class PDU1Handler : public GomspaceDeviceHandler { virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override; ReturnValue_t printStatus(DeviceCommandId_t cmd) override; + ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExectuion) override; + private: /** Dataset for the housekeeping table of the PDU1 */ PDU1::PDU1HkTableDataset pdu1HkTableDataset; + GOMSPACE::ChannelSwitchHook channelSwitchHook = nullptr; + void* hookArgs = nullptr; void printHkTable(); void parseHkTableReply(const uint8_t* packet); diff --git a/mission/devices/PDU2Handler.cpp b/mission/devices/PDU2Handler.cpp index b5c34af6..61e9bb6a 100644 --- a/mission/devices/PDU2Handler.cpp +++ b/mission/devices/PDU2Handler.cpp @@ -49,6 +49,11 @@ void PDU2Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pac #endif } +void PDU2Handler::assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void *args) { + this->channelSwitchHook = hook; + this->hookArgs = args; +} + void PDU2Handler::parseHkTableReply(const uint8_t *packet) { uint16_t dataOffset = 0; pdu2HkTableDataset.read(); @@ -421,3 +426,52 @@ void PDU2Handler::printHkTable() { << std::setw(4) << pdu2HkTableDataset.voltageOutPayloadCamera.value << std::right << std::endl; } + +ReturnValue_t PDU2Handler::setParamCallback(SetParamMessageUnpacker &unpacker, bool afterExecution) { + using namespace PDU2; + GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU2; + if(not afterExecution) { + return HasReturnvaluesIF::RETURN_OK; + } + if (channelSwitchHook != nullptr and unpacker.getParameterSize() == 1) { + switch (unpacker.getAddress()) { + case (CONFIG_ADDRESS_OUT_EN_Q7S): { + channelSwitchHook(pdu, 0, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH1): { + channelSwitchHook(pdu, 1, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_RW): { + channelSwitchHook(pdu, 2, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN): { + channelSwitchHook(pdu, 3, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_SUS_REDUNDANT): { + channelSwitchHook(pdu, 4, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM): { + channelSwitchHook(pdu, 5, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6PLOC): { + channelSwitchHook(pdu, 6, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_B): { + channelSwitchHook(pdu, 7, unpacker.getParameter()[0], hookArgs); + break; + } + case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_CAMERA): { + channelSwitchHook(pdu, 8, unpacker.getParameter()[0], hookArgs); + break; + } + } + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/mission/devices/PDU2Handler.h b/mission/devices/PDU2Handler.h index 258b616d..f2323615 100644 --- a/mission/devices/PDU2Handler.h +++ b/mission/devices/PDU2Handler.h @@ -26,6 +26,7 @@ class PDU2Handler : public GomspaceDeviceHandler { virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; + void assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void* args); protected: /** @@ -34,10 +35,13 @@ class PDU2Handler : public GomspaceDeviceHandler { virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override; virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override; ReturnValue_t printStatus(DeviceCommandId_t cmd) override; + ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExecution) override; private: /** Dataset for the housekeeping table of the PDU2 */ PDU2::PDU2HkTableDataset pdu2HkTableDataset; + GOMSPACE::ChannelSwitchHook channelSwitchHook = nullptr; + void* hookArgs = nullptr; void printHkTable(); diff --git a/mission/devices/devicedefinitions/GomspaceDefinitions.h b/mission/devices/devicedefinitions/GomspaceDefinitions.h index a575747f..fde4e047 100644 --- a/mission/devices/devicedefinitions/GomspaceDefinitions.h +++ b/mission/devices/devicedefinitions/GomspaceDefinitions.h @@ -1,11 +1,3 @@ -/* - * GomspaceDefinitions.h - * - * @brief This file holds all definitions specific for devices from gomspace. - * @date 20.12.2020 - * @author J. Meier - */ - #ifndef MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEDEFINITIONS_H_ #define MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEDEFINITIONS_H_ @@ -16,6 +8,11 @@ #include namespace GOMSPACE { + +enum class Pdu { PDU1, PDU2 }; + +using ChannelSwitchHook = void (*)(Pdu pdu, uint8_t channel, bool on, void* args); + static const uint16_t IGNORE_CHECKSUM = 0xbb0; /** The size of the header of a gomspace CSP packet. */ static const uint8_t GS_HDR_LENGTH = 12; @@ -611,19 +608,32 @@ static const uint8_t HK_TABLE_ENTRIES = 73; namespace PDU1 { static const uint32_t HK_TABLE_DATA_SET_ID = 0x1; // hk table has table id 4 + +enum SwitchChannels : uint8_t { + TCS_BOARD_3V3 = 0, + SYRLINKS = 1, + STR = 2, + MGT = 3, + SUS_NOMINAL = 4, + SOL_CELL_EXPERIMENT = 5, + PLOC = 6, + ACS_A_SIDE = 7, + UNUSED = 8 +}; + /** * Addresses within configuration table to enable or disable output channels. Refer also to * gs-man-nanopower-p60-pdu-200.pdf on page 16. */ static const uint16_t CONFIG_ADDRESS_OUT_EN_TCS_BOARD_3V3 = 0x48; static const uint16_t CONFIG_ADDRESS_OUT_EN_SYRLINKS = 0x49; -static const uint16_t CONFIG_ADDRESS_OUT_EN_STAR_TRACKER = 0x50; -static const uint16_t CONFIG_ADDRESS_OUT_EN_MGT = 0x51; -static const uint16_t CONFIG_ADDRESS_OUT_EN_SUS_NOMINAL = 0x52; -static const uint16_t CONFIG_ADDRESS_OUT_EN_SOLAR_CELL_EXP = 0x53; -static const uint16_t CONFIG_ADDRESS_OUT_EN_PLOC = 0x54; -static const uint16_t CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_A = 0x55; -static const uint16_t CONFIG_ADDRESS_OUT_EN_CHANNEL8 = 0x56; +static const uint16_t CONFIG_ADDRESS_OUT_EN_STAR_TRACKER = 0x4A; +static const uint16_t CONFIG_ADDRESS_OUT_EN_MGT = 0x4B; +static const uint16_t CONFIG_ADDRESS_OUT_EN_SUS_NOMINAL = 0x4C; +static const uint16_t CONFIG_ADDRESS_OUT_EN_SOLAR_CELL_EXP = 0x4D; +static const uint16_t CONFIG_ADDRESS_OUT_EN_PLOC = 0x4E; +static const uint16_t CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_A = 0x4F; +static const uint16_t CONFIG_ADDRESS_OUT_EN_CHANNEL8 = 0x50; /** * @brief This class defines a dataset for the hk table of the PDU1. @@ -799,6 +809,19 @@ class PDU1HkTableDataset : public StaticLocalDataSet { namespace PDU2 { static const uint32_t HK_TABLE_DATA_SET_ID = 0x2; + +enum SwitchChannels : uint8_t { + Q7S = 0, + PAYLOAD_PCDU_CH1 = 1, + RW = 2, + TCS_HEATER_IN = 3, + SUS_REDUNDANT = 4, + DEPY_MECHANISM = 5, + PAYLOAD_PCDU_CH6 = 6, + ACS_B_SIDE = 7, + PAYLOAD_CAMERA = 8 +}; + /** * Addresses within configuration table to enable or disable output channels. Refer also to * gs-man-nanopower-p60-pdu-200.pdf on page 16. diff --git a/tmtc b/tmtc index 580ac8b2..6f24d6a8 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 580ac8b2d7e73aa860f3de55066187d7684d2d64 +Subproject commit 6f24d6a83995ca7a895c17a77a00bceac4d7f141