diff --git a/CHANGELOG.md b/CHANGELOG.md index 152bbead..b15c4f12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,20 +8,124 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). The [milestone](https://egit.irs.uni-stuttgart.de/eive/eive-obsw/milestones) list yields a list of all related PRs for each release. +Starting at v2.0.0, the following changes will consitute of a breaking +change warranting a new major release: + +- The TMTC interface changes in any shape of form. +- The behavour of the OBSW changes in a major shape or form relevant + for operations + # [unreleased] -## Added +## Fixed -- The Q7S SW now checks for a file named `boot_delay_secs.stxt` in the home directory. - If it exists and the file is empty, it will delay for 6 seconds before continuing - with the regular boot. It can also try to read delay seconds from the file. - PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/340. +- Bugfix in FSFW where the sequence flags of the PUS packets were set to continuation segment (0b00) + instead of unsegmented (0b11). + +# [v1.23.0] 2023-02-01 + +TMTC version: v2.9.0 ## Changed +- Bumped FSFW to include improvements and bugfix for Health Service. The health service now + supports the announce all health info command. + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/725 + +## Fixed + +- Bumped FSFW to include fixes in the time service. + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726 +- The CCSDS handler starts the transmitter timer each time it is commanded to MODE_ON and times + out the timer when the handler is commanded to MODE_OFF +- If the timer is timed out the CCSDS handler will disable the TX clock which will cause the + syrlinks to got to standby mode +- PDEC handler now parses the FAR register also in interrupt mode + + +# [v1.22.1] 2023-01-30 + +## Changed + +- Updated FSFW to include addition where the `SO_REUSEADDR` option is set + on the TCP server, which should improve its ergonomics. + +# [v1.22.0] 2023-01-28 + +TMTC version: v2.6.1 + +## Added + +- First COM subsystem implementation. It mirrors the Syrlinks mode/submodes but also takes + care of commanding the CCSDS handler. It expects the Syrlinks submodes as mode commands. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/358 +- The CCSDS handler has has a new submode (3) to configure the default datarate. +- Default datarate parameter commanding moved to COM subsystem. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/358 + +# [v1.21.0] 2023-01-26 + +TMTC version: v2.5.0 +Syrlinks PR: PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/353 + +## Fixed + +- The `OBSW_SYRLINKS_SIMULATED` flag is set to 0 for for both EM and FM. +- MGM4 handling in ACS sensor processing: Bugfix in `mulScalar` operation + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/354 +- Subsystem ID clash: CORE subsystem ID was the same as Syrlinks subsystem ID. + +## Changed + +- Startracker temperature set and PCDU switcher set are diagnostic now +- `SyrlinksHkHandler` renamed to `SyrlinksHandler` to better reflect that it does more than + just HK and is also responsible for setting the TX mode of the device. +- `SyrlinksHandler`: Go to startup immediately because the Syrlinks device should always be on + by default. +- `SyrlinksHandler`: Go to normal mode at startup. + +## Added + +- The Syrlinks handler has submodes for the TX mode now: RX Only (0), RX and TX default + datarate (1), RX and TX Low Rate (2), RX and TX High Rate (3) and TX Carrier Wave (4). + The submodes apply for both ON and NORMAL mode. The default datarate can be updated using + a parameter command (domain ID 0 and unique ID 0) with value 0 for low rate and 1 for high rate. +- The Syrlinks handler always sets TX to standby when switching off +- The Syrlinks handler triggers a new TX_ON event when the transmitter was switched on successfully + and a TX_OFF event when it was switched off successfully. +- Startracker temperature set and PCDU switcher set are diagnostic now +- The CCSDS handler can accept mode commands now. It accepts ON and OFF commands. Furthermore + it has a submode for low datarate (1) and high datarate (2) for the ON command. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/352 + +# [v1.20.0] 2023-01-24 + +## Added + +- The Q7S SW now checks for a file named `boot_delay_secs.txt` in the home directory. + If it exists and the file is empty, it will delay for 6 seconds before continuing + with the regular boot. It can also try to read delay seconds from the file. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/340. +- Basic TCS Subsystem component. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/319 +- Expose base set of STR periodic housekeeping packets + +## Changed + +- Moved some PDEC/PTME configuration to `common/config/eive/definitions.h` + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/319 - The ACS Controller Gyro Sets (raw and processed) and the MEKF dataset are diagnostics now. - Bumped FSFW for Service 11 improvement which includes size and CRC check for contained TC - Syrlinks module now always included for both EM and FM +- SA Deployment: Allow specifying the switch interval and the initial channel. This allows testing + the new deployment procedure where each channel is burned for half of the whole burn duration. + It also allows burning only one channel for the whole burn duration. The autonomous mechanism + was adapted to burn each channel for half of the burn time by default. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/347 + TMTC PR: https://egit.irs.uni-stuttgart.de/eive/eive-tmtc/pulls/127 +- `Max31865RtdLowlevelHandler.cpp`: For each RTD device, the config is now re-written before + every read. This seems to fix some issue with invalid temperature sensor readings. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/345 ## Fixed @@ -30,8 +134,15 @@ list yields a list of all related PRs for each release. previous range setting was wrong. Also fixed a small error properly set internal state on shut-down. PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/342 +- Syrlinks Handler: Read RX frequency shift as 24 bit signed number now. Also include + validity handling for datasets. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/350 +- `GyroADIS1650XHandler`: Changed calculation of angular rate to be sensitivity based instead of + max. range based, as previous fix still left an margin of error between ADIS16505 sensors + and L3GD20 sensors. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/346 -# [v1.19.0] 10.01.2023 +# [v1.19.0] 2023-01-10 ## Changed @@ -53,7 +164,7 @@ list yields a list of all related PRs for each release. - Add automatic 5V stack commanding for all connected devices PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/335 -# [v1.18.0] 01.12.2022 +# [v1.18.0] 2022-12-01 ## Changed @@ -62,7 +173,7 @@ list yields a list of all related PRs for each release. - Renamed `/dev/i2c_eive` to `/dev/i2c_pl` and `/dev/i2c-2` to `/dev/i2c_ps`. PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/328 -# [v1.17.0] 28.11.2022 +# [v1.17.0] 2022-11-28 ## Added @@ -71,7 +182,7 @@ list yields a list of all related PRs for each release. PR 2: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/324 PR 3: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/326 -# [v1.16.0] 18.11.2022 +# [v1.16.0] 2022-11-18 - It is now possible to compile Linux components for the hosted build conditionally PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/322 @@ -88,7 +199,7 @@ list yields a list of all related PRs for each release. - Add remaining missing TMP1075 device handlers. PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/318 -# [v1.15.0] 27.10.2022 +# [v1.15.0] 2022-10-27 - Consistent device file naming - Remove rad sensor from EM build, lead to weird bugs on EM which diff --git a/CMakeLists.txt b/CMakeLists.txt index 5886ba9c..55f4afe4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR_IF_GIT_FAILS 1) -set(OBSW_VERSION_MINOR_IF_GIT_FAILS 19) +set(OBSW_VERSION_MINOR_IF_GIT_FAILS 23) set(OBSW_VERSION_REVISION_IF_GIT_FAILS 0) # set(CMAKE_VERBOSE TRUE) @@ -150,7 +150,7 @@ set(OBSW_ADD_SCEX_DEVICE ${INIT_VAL} CACHE STRING "Add Solar Cell Experiment module") set(OBSW_SYRLINKS_SIMULATED - ${OBSW_Q7S_EM} + 0 CACHE STRING "Syrlinks is simulated") # ############################################################################## diff --git a/bsp_hosted/fsfwconfig/pollingsequence/DummyPst.cpp b/bsp_hosted/fsfwconfig/pollingsequence/DummyPst.cpp index 9a92f544..de1efa0e 100644 --- a/bsp_hosted/fsfwconfig/pollingsequence/DummyPst.cpp +++ b/bsp_hosted/fsfwconfig/pollingsequence/DummyPst.cpp @@ -44,12 +44,11 @@ ReturnValue_t dummy_pst::pst(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 7219b96d..847cce5f 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -48,13 +48,16 @@ #include "mission/system/objects/RwAssembly.h" #include "mission/system/objects/TcsBoardAssembly.h" #include "mission/system/tree/acsModeTree.h" +#include "mission/system/tree/comModeTree.h" #include "mission/system/tree/payloadModeTree.h" +#include "mission/system/tree/tcsModeTree.h" #include "tmtc/pusIds.h" #if OBSW_TEST_LIBGPIOD == 1 #include "linux/boardtest/LibgpiodTest.h" #endif #include #include +#include #include @@ -87,7 +90,6 @@ #include "mission/devices/RadiationSensorHandler.h" #include "mission/devices/RwHandler.h" #include "mission/devices/SolarArrayDeploymentHandler.h" -#include "mission/devices/SyrlinksHkHandler.h" #include "mission/devices/Tmp1075Handler.h" #include "mission/devices/devicedefinitions/GomspaceDefinitions.h" #include "mission/devices/devicedefinitions/Max31865Definitions.h" @@ -138,6 +140,7 @@ void ObjectFactory::createTmpComponents() { new I2cCookie(tmpDevIds[idx].second, TMP1075::MAX_REPLY_LENGTH, q7s::I2C_PS_EIVE)); auto* tmpDevHandler = new Tmp1075Handler(tmpDevIds[idx].first, objects::I2C_COM_IF, tmpDevCookies[idx]); + tmpDevHandler->connectModeTreeParent(satsystem::tcs::SUBSYSTEM); // TODO: Remove this after TCS subsystem was added // These devices are connected to the 3V3 stack and should be powered permanently. Therefore, // we set them to normal mode immediately here. @@ -578,15 +581,17 @@ void ObjectFactory::createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitc void ObjectFactory::createSyrlinksComponents(PowerSwitchIF* pwrSwitcher) { auto* syrlinksUartCookie = - new SerialCookie(objects::SYRLINKS_HK_HANDLER, q7s::UART_SYRLINKS_DEV, uart::SYRLINKS_BAUD, + new SerialCookie(objects::SYRLINKS_HANDLER, q7s::UART_SYRLINKS_DEV, uart::SYRLINKS_BAUD, syrlinks::MAX_REPLY_SIZE, UartModes::NON_CANONICAL); syrlinksUartCookie->setParityEven(); - auto syrlinksFdir = new SyrlinksFdir(objects::SYRLINKS_HK_HANDLER); + auto syrlinksFdir = new SyrlinksFdir(objects::SYRLINKS_HANDLER); auto syrlinksHandler = - new SyrlinksHkHandler(objects::SYRLINKS_HK_HANDLER, objects::UART_COM_IF, syrlinksUartCookie, - pcdu::PDU1_CH1_SYRLINKS_12V, syrlinksFdir); + new SyrlinksHandler(objects::SYRLINKS_HANDLER, objects::UART_COM_IF, syrlinksUartCookie, + pcdu::PDU1_CH1_SYRLINKS_12V, syrlinksFdir); syrlinksHandler->setPowerSwitcher(pwrSwitcher); + syrlinksHandler->setStartUpImmediately(); + syrlinksHandler->connectModeTreeParent(satsystem::com::SUBSYSTEM); #if OBSW_DEBUG_SYRLINKS == 1 syrlinksHandler->setDebugMode(true); #endif @@ -788,15 +793,22 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF, objects::CCSDS_HANDLER, objects::PTME, objects::CCSDS_PACKET_DISTRIBUTOR, ptmeConfig, gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA, TRANSMITTER_TIMEOUT); VirtualChannel* vc = nullptr; - vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE, objects::CCSDS_HANDLER); + vc = new VirtualChannel(ccsds::VC0, config::VC0_QUEUE_SIZE, objects::CCSDS_HANDLER); (*ipCoreHandler)->addVirtualChannel(ccsds::VC0, vc); - vc = new VirtualChannel(ccsds::VC1, common::VC1_QUEUE_SIZE, objects::CCSDS_HANDLER); + vc = new VirtualChannel(ccsds::VC1, config::VC1_QUEUE_SIZE, objects::CCSDS_HANDLER); (*ipCoreHandler)->addVirtualChannel(ccsds::VC1, vc); - vc = new VirtualChannel(ccsds::VC2, common::VC2_QUEUE_SIZE, objects::CCSDS_HANDLER); + vc = new VirtualChannel(ccsds::VC2, config::VC2_QUEUE_SIZE, objects::CCSDS_HANDLER); (*ipCoreHandler)->addVirtualChannel(ccsds::VC2, vc); - vc = new VirtualChannel(ccsds::VC3, common::VC3_QUEUE_SIZE, objects::CCSDS_HANDLER); + vc = new VirtualChannel(ccsds::VC3, config::VC3_QUEUE_SIZE, objects::CCSDS_HANDLER); (*ipCoreHandler)->addVirtualChannel(ccsds::VC3, vc); + ReturnValue_t result = (*ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM); + if (result != returnvalue::OK) { + sif::error + << "ObjectFactory::createCcsdsComponents: Connecting COM subsystem to CCSDS handler failed" + << std::endl; + } + GpioCookie* gpioCookiePdec = new GpioCookie; consumer.str(""); consumer << "0x" << std::hex << objects::PDEC_HANDLER; diff --git a/bsp_q7s/core/scheduling.cpp b/bsp_q7s/core/scheduling.cpp index 46d04831..d8136d3a 100644 --- a/bsp_q7s/core/scheduling.cpp +++ b/bsp_q7s/core/scheduling.cpp @@ -1,6 +1,7 @@ #include "scheduling.h" #include +#include #include #include @@ -142,10 +143,14 @@ void scheduling::initTasks() { #endif #endif -#if OBSW_ADD_CCSDS_IP_CORES == 1 - PeriodicTaskIF* ccsdsHandlerTask = factory->createPeriodicTask( + PeriodicTaskIF* comTask = factory->createPeriodicTask( "CCSDS_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = ccsdsHandlerTask->addComponent(objects::CCSDS_HANDLER); + result = comTask->addComponent(objects::COM_SUBSYSTEM); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("COM subsystem", objects::COM_SUBSYSTEM); + } +#if OBSW_ADD_CCSDS_IP_CORES == 1 + result = comTask->addComponent(objects::CCSDS_HANDLER); if (result != returnvalue::OK) { scheduling::printAddObjectError("CCSDS Handler", objects::CCSDS_HANDLER); } @@ -279,6 +284,10 @@ void scheduling::initTasks() { PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask( "TCS_TASK", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc); + result = tcsSystemTask->addComponent(objects::TCS_SUBSYSTEM); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("TCS_SUBSYSTEM", objects::TCS_SUBSYSTEM); + } #if OBSW_ADD_RTD_DEVICES == 1 result = tcsSystemTask->addComponent(objects::TCS_BOARD_ASS); if (result != returnvalue::OK) { @@ -376,8 +385,8 @@ void scheduling::initTasks() { #endif #endif + comTask->startTask(); #if OBSW_ADD_CCSDS_IP_CORES == 1 - ccsdsHandlerTask->startTask(); pdecHandlerTask->startTask(); #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 8d9edd6c..375ddb0f 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -14,6 +14,7 @@ #include "linux/ObjectFactory.h" #include "linux/callbacks/gpioCallbacks.h" #include "mission/core/GenericFactory.h" +#include "mission/system/tree/comModeTree.h" void ObjectFactory::produce(void* args) { ObjectFactory::setStatics(); @@ -108,4 +109,5 @@ void ObjectFactory::produce(void* args) { pcdu::Switches::PDU1_CH5_SOLAR_CELL_EXP_5V); #endif createAcsController(true); + satsystem::com::init(); } diff --git a/common/config/commonConfig.h.in b/common/config/commonConfig.h.in index effa9c4f..a6b7faab 100644 --- a/common/config/commonConfig.h.in +++ b/common/config/commonConfig.h.in @@ -36,14 +36,6 @@ extern const fsfw::Version OBSW_VERSION; extern const uint16_t PUS_PACKET_ID; extern const uint16_t CFDP_PACKET_ID; - -static constexpr uint32_t CCSDS_HANDLER_QUEUE_SIZE = 50; -static constexpr uint8_t NUMBER_OF_VIRTUAL_CHANNELS = 4; -static constexpr uint8_t VC0_QUEUE_SIZE = 50; -static constexpr uint8_t VC1_QUEUE_SIZE = 50; -static constexpr uint8_t VC2_QUEUE_SIZE = 50; -static constexpr uint8_t VC3_QUEUE_SIZE = 50; - } #endif /* COMMON_CONFIG_COMMONCONFIG_H_ */ diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index 33d37812..02896e1c 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -39,10 +39,22 @@ static constexpr uint32_t SA_DEPL_INIT_BUFFER_SECS = 120; static constexpr uint32_t SA_DEPL_BURN_TIME_SECS = 180; static constexpr uint32_t SA_DEPL_WAIT_TIME_SECS = 45 * 60; // HW constraints (current limit) mean that the GPIO channels need to be switched on in alternation -static constexpr uint32_t SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS = 5; +static constexpr uint32_t LEGACY_SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS = 5; // Maximum allowed burn time allowed by the software. static constexpr uint32_t SA_DEPL_MAX_BURN_TIME = 180; +static constexpr uint32_t CCSDS_HANDLER_QUEUE_SIZE = 50; +static constexpr uint8_t NUMBER_OF_VIRTUAL_CHANNELS = 4; +static constexpr uint8_t VC0_QUEUE_SIZE = 80; +static constexpr uint8_t VC1_QUEUE_SIZE = 80; +static constexpr uint8_t VC2_QUEUE_SIZE = 50; +static constexpr uint8_t VC3_QUEUE_SIZE = 50; + +static constexpr uint32_t MAX_PUS_FUNNEL_QUEUE_DEPTH = 100; + +static constexpr uint32_t MAX_STORED_CMDS_UDP = 120; +static constexpr uint32_t MAX_STORED_CMDS_TCP = 120; + } // namespace config #endif /* COMMON_CONFIG_DEFINITIONS_H_ */ diff --git a/common/config/eive/eventSubsystemIds.h b/common/config/eive/eventSubsystemIds.h index 8785f599..40926b00 100644 --- a/common/config/eive/eventSubsystemIds.h +++ b/common/config/eive/eventSubsystemIds.h @@ -35,6 +35,7 @@ enum : uint8_t { SYRLINKS = 137, SCEX_HANDLER = 138, CONFIGHANDLER = 139, + CORE = 140, COMMON_SUBSYSTEM_ID_END }; diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index 9fb4aeff..36cf009a 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -117,7 +117,9 @@ enum commonObjects : uint32_t { SUS_5_N_LOC_XFYMZB_PT_ZB = 0x44120037, SUS_11_R_LOC_XBYMZB_PT_ZB = 0x44120043, - SYRLINKS_HK_HANDLER = 0x445300A3, + SYRLINKS_HANDLER = 0x445300A3, + // might be obsolete, was not used in Q7S FM SW + // CCSDS_IP_CORE_BRIDGE = 0x73500000, /* 0x49 ('I') for Communication Interfaces */ SPI_RTD_COM_IF = 0x49020006, @@ -138,9 +140,12 @@ enum commonObjects : uint32_t { TCS_BOARD_ASS = 0x73000003, RW_ASS = 0x73000004, CAM_SWITCHER = 0x73000006, + EIVE_SYSTEM = 0x73010000, ACS_SUBSYSTEM = 0x73010001, PL_SUBSYSTEM = 0x73010002, - EIVE_SYSTEM = 0x73010000, + TCS_SUBSYSTEM = 0x73010003, + COM_SUBSYSTEM = 0x73010004, + TM_FUNNEL = 0x73000100, PUS_TM_FUNNEL = 0x73000101, CFDP_TM_FUNNEL = 0x73000102, diff --git a/dummies/helpers.cpp b/dummies/helpers.cpp index 0ffb724f..b47d74ef 100644 --- a/dummies/helpers.cpp +++ b/dummies/helpers.cpp @@ -41,7 +41,7 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch) { new SaDeplDummy(objects::SOLAR_ARRAY_DEPL_HANDLER); new StarTrackerDummy(objects::STAR_TRACKER, objects::DUMMY_COM_IF, comCookieDummy); if (cfg.addSyrlinksDummies) { - new SyrlinksDummy(objects::SYRLINKS_HK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); + new SyrlinksDummy(objects::SYRLINKS_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); } new ImtqDummy(objects::IMTQ_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); if (cfg.addPowerDummies) { diff --git a/fsfw b/fsfw index accaf855..01cc619e 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit accaf855ee53d3dc429d7bcdf1b7b89768c166b6 +Subproject commit 01cc619e67b84cef514b045377771ff1e11caf80 diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 5f55fa8b..666710e8 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -76,7 +76,8 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 7903;0x1edf;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7905;0x1ee1;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 8900;0x22c4;CLOCK_SET;INFO;;fsfw/src/fsfw/pus/Service9TimeManagement.h -8901;0x22c5;CLOCK_SET_FAILURE;LOW;;fsfw/src/fsfw/pus/Service9TimeManagement.h +8901;0x22c5;CLOCK_DUMP;INFO;;fsfw/src/fsfw/pus/Service9TimeManagement.h +8902;0x22c6;CLOCK_SET_FAILURE;LOW;;fsfw/src/fsfw/pus/Service9TimeManagement.h 9100;0x238c;TC_DELETION_FAILED;MEDIUM;Deletion of a TC from the map failed. P1: First 32 bit of request ID, P2. Last 32 bit of Request ID;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 9700;0x25e4;TEST;INFO;;fsfw/src/fsfw/pus/Service17Test.h 10600;0x2968;CHANGE_OF_SETUP_PARAMETER;LOW;;fsfw/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h @@ -226,11 +227,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 13630;0x353e;SUPV_UPDATE_PROGRESS;INFO;Will be triggered every 5 percent of the update progress. P1: First byte percent, third and fourth byte Sequence Count, P2: Bytes written;linux/devices/ploc/PlocSupvUartMan.h 13631;0x353f;HDLC_FRAME_REMOVAL_ERROR;INFO;;linux/devices/ploc/PlocSupvUartMan.h 13632;0x3540;HDLC_CRC_ERROR;INFO;;linux/devices/ploc/PlocSupvUartMan.h -13700;0x3584;ALLOC_FAILURE;MEDIUM;;bsp_q7s/core/CoreController.h -13701;0x3585;REBOOT_SW;MEDIUM; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h -13702;0x3586;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h -13703;0x3587;REBOOT_HW;MEDIUM;;bsp_q7s/core/CoreController.h -13704;0x3588;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h +13700;0x3584;FDIR_REACTION_IGNORED;MEDIUM;;mission/devices/devicedefinitions/SyrlinksDefinitions.h +13701;0x3585;TX_ON;INFO;Transmitter is on now. P1: Submode, P2: Current default datarate.;mission/devices/devicedefinitions/SyrlinksDefinitions.h +13702;0x3586;TX_OFF;INFO;Transmitter is off now.;mission/devices/devicedefinitions/SyrlinksDefinitions.h 13800;0x35e8;MISSING_PACKET;LOW;;mission/devices/devicedefinitions/ScexDefinitions.h 13801;0x35e9;EXPERIMENT_TIMEDOUT;LOW;;mission/devices/devicedefinitions/ScexDefinitions.h 13802;0x35ea;MULTI_PACKET_COMMAND_DONE;INFO;;mission/devices/devicedefinitions/ScexDefinitions.h @@ -239,3 +238,8 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;;mission/utility/GlobalConfigHandler.h 13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;;mission/utility/GlobalConfigHandler.h 13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;;mission/utility/GlobalConfigHandler.h +14000;0x36b0;ALLOC_FAILURE;MEDIUM;;bsp_q7s/core/CoreController.h +14001;0x36b1;REBOOT_SW;MEDIUM; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h +14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h +14003;0x36b3;REBOOT_HW;MEDIUM;;bsp_q7s/core/CoreController.h +14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index 59885ed6..35463225 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -72,7 +72,7 @@ 0x44420029;RTD_13_IC16_PLPCDU_HEATSPREADER 0x44420030;RTD_14_IC17_TCS_BOARD 0x44420031;RTD_15_IC18_IMTQ -0x445300A3;SYRLINKS_HK_HANDLER +0x445300A3;SYRLINKS_HANDLER 0x49000000;ARDUINO_COM_IF 0x49010005;GPIO_IF 0x49010006;SCEX_UART_READER @@ -146,5 +146,7 @@ 0x73010000;EIVE_SYSTEM 0x73010001;ACS_SUBSYSTEM 0x73010002;PL_SUBSYSTEM +0x73010003;TCS_SUBSYSTEM +0x73010004;COM_SUBSYSTEM 0x73500000;CCSDS_IP_CORE_BRIDGE 0xFFFFFFFF;NO_OBJECT diff --git a/generators/bsp_q7s_returnvalues.csv b/generators/bsp_q7s_returnvalues.csv index e78128c2..82f44173 100644 --- a/generators/bsp_q7s_returnvalues.csv +++ b/generators/bsp_q7s_returnvalues.csv @@ -30,21 +30,21 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x52a2;RWHA_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;RW_HANDLER;mission/devices/RwHandler.h 0x52a3;RWHA_ExecutionFailed;Command execution failed;163;RW_HANDLER;mission/devices/RwHandler.h 0x52a4;RWHA_CrcError;Reaction wheel reply has invalid crc;164;RW_HANDLER;mission/devices/RwHandler.h +0x50a0;SYRLINKS_CrcFailure;;160;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a1;SYRLINKS_UartFraminOrParityErrorAck;;161;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a2;SYRLINKS_BadCharacterAck;;162;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a3;SYRLINKS_BadParameterValueAck;;163;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a4;SYRLINKS_BadEndOfFrameAck;;164;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a5;SYRLINKS_UnknownCommandIdAck;;165;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a6;SYRLINKS_BadCrcAck;;166;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a7;SYRLINKS_ReplyWrongSize;;167;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a8;SYRLINKS_MissingStartFrameCharacter;;168;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h 0x5d00;GOMS_PacketTooLong;;0;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h 0x5d01;GOMS_InvalidTableId;;1;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h 0x5d02;GOMS_InvalidAddress;;2;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h 0x5d03;GOMS_InvalidParamSize;;3;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h 0x5d04;GOMS_InvalidPayloadSize;;4;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h 0x5d05;GOMS_UnknownReplyId;;5;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h -0x50a0;SYRLINKS_CrcFailure;;160;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a1;SYRLINKS_UartFraminOrParityErrorAck;;161;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a2;SYRLINKS_BadCharacterAck;;162;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a3;SYRLINKS_BadParameterValueAck;;163;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a4;SYRLINKS_BadEndOfFrameAck;;164;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a5;SYRLINKS_UnknownCommandIdAck;;165;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a6;SYRLINKS_BadCrcAck;;166;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a7;SYRLINKS_ReplyWrongSize;;167;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a8;SYRLINKS_MissingStartFrameCharacter;;168;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h 0x4fa1;HEATER_CommandNotSupported;;161;HEATER_HANDLER;mission/devices/HeaterHandler.h 0x4fa2;HEATER_InitFailed;;162;HEATER_HANDLER;mission/devices/HeaterHandler.h 0x4fa3;HEATER_InvalidSwitchNr;;163;HEATER_HANDLER;mission/devices/HeaterHandler.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 135981b6..65f118b2 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 240 translations. + * @brief Auto-generated event translation file. Contains 244 translations. * @details - * Generated on: 2023-01-18 16:08:56 + * Generated on: 2023-02-01 19:42:11 */ #include "translateEvents.h" @@ -82,6 +82,7 @@ const char *BIT_LOCK_STRING = "BIT_LOCK"; const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST"; const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED"; const char *CLOCK_SET_STRING = "CLOCK_SET"; +const char *CLOCK_DUMP_STRING = "CLOCK_DUMP"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED"; const char *TEST_STRING = "TEST"; @@ -228,11 +229,8 @@ const char *SUPV_REPLY_CRC_MISSMATCH_STRING = "SUPV_REPLY_CRC_MISSMATCH"; const char *SUPV_UPDATE_PROGRESS_STRING = "SUPV_UPDATE_PROGRESS"; const char *HDLC_FRAME_REMOVAL_ERROR_STRING = "HDLC_FRAME_REMOVAL_ERROR"; const char *HDLC_CRC_ERROR_STRING = "HDLC_CRC_ERROR"; -const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; -const char *REBOOT_SW_STRING = "REBOOT_SW"; -const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; -const char *REBOOT_HW_STRING = "REBOOT_HW"; -const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; +const char *TX_ON_STRING = "TX_ON"; +const char *TX_OFF_STRING = "TX_OFF"; const char *MISSING_PACKET_STRING = "MISSING_PACKET"; const char *EXPERIMENT_TIMEDOUT_STRING = "EXPERIMENT_TIMEDOUT"; const char *MULTI_PACKET_COMMAND_DONE_STRING = "MULTI_PACKET_COMMAND_DONE"; @@ -241,6 +239,11 @@ const char *GET_CONFIGFILEVALUE_FAILED_STRING = "GET_CONFIGFILEVALUE_FAILED"; const char *INSERT_CONFIGFILEVALUE_FAILED_STRING = "INSERT_CONFIGFILEVALUE_FAILED"; const char *WRITE_CONFIGFILE_FAILED_STRING = "WRITE_CONFIGFILE_FAILED"; const char *READ_CONFIGFILE_FAILED_STRING = "READ_CONFIGFILE_FAILED"; +const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; +const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; +const char *REBOOT_HW_STRING = "REBOOT_HW"; +const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -399,6 +402,8 @@ const char *translateEvents(Event event) { case (8900): return CLOCK_SET_STRING; case (8901): + return CLOCK_DUMP_STRING; + case (8902): return CLOCK_SET_FAILURE_STRING; case (9100): return TC_DELETION_FAILED_STRING; @@ -690,16 +695,10 @@ const char *translateEvents(Event event) { return HDLC_FRAME_REMOVAL_ERROR_STRING; case (13632): return HDLC_CRC_ERROR_STRING; - case (13700): - return ALLOC_FAILURE_STRING; case (13701): - return REBOOT_SW_STRING; + return TX_ON_STRING; case (13702): - return REBOOT_MECHANISM_TRIGGERED_STRING; - case (13703): - return REBOOT_HW_STRING; - case (13704): - return NO_SD_CARD_ACTIVE_STRING; + return TX_OFF_STRING; case (13800): return MISSING_PACKET_STRING; case (13801): @@ -716,6 +715,16 @@ const char *translateEvents(Event event) { return WRITE_CONFIGFILE_FAILED_STRING; case (13905): return READ_CONFIGFILE_FAILED_STRING; + case (14000): + return ALLOC_FAILURE_STRING; + case (14001): + return REBOOT_SW_STRING; + case (14002): + return REBOOT_MECHANISM_TRIGGERED_STRING; + case (14003): + return REBOOT_HW_STRING; + case (14004): + return NO_SD_CARD_ACTIVE_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 4d0f5c1f..fdc28d47 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 150 translations. - * Generated on: 2023-01-18 16:08:56 + * Contains 152 translations. + * Generated on: 2023-02-01 19:42:11 */ #include "translateObjects.h" @@ -80,7 +80,7 @@ const char *RTD_12_IC15_ACU_STRING = "RTD_12_IC15_ACU"; const char *RTD_13_IC16_PLPCDU_HEATSPREADER_STRING = "RTD_13_IC16_PLPCDU_HEATSPREADER"; const char *RTD_14_IC17_TCS_BOARD_STRING = "RTD_14_IC17_TCS_BOARD"; const char *RTD_15_IC18_IMTQ_STRING = "RTD_15_IC18_IMTQ"; -const char *SYRLINKS_HK_HANDLER_STRING = "SYRLINKS_HK_HANDLER"; +const char *SYRLINKS_HANDLER_STRING = "SYRLINKS_HANDLER"; const char *ARDUINO_COM_IF_STRING = "ARDUINO_COM_IF"; const char *GPIO_IF_STRING = "GPIO_IF"; const char *SCEX_UART_READER_STRING = "SCEX_UART_READER"; @@ -154,6 +154,8 @@ const char *CFDP_DISTRIBUTOR_STRING = "CFDP_DISTRIBUTOR"; const char *EIVE_SYSTEM_STRING = "EIVE_SYSTEM"; const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM"; const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM"; +const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM"; +const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -308,7 +310,7 @@ const char *translateObject(object_id_t object) { case 0x44420031: return RTD_15_IC18_IMTQ_STRING; case 0x445300A3: - return SYRLINKS_HK_HANDLER_STRING; + return SYRLINKS_HANDLER_STRING; case 0x49000000: return ARDUINO_COM_IF_STRING; case 0x49010005: @@ -455,6 +457,10 @@ const char *translateObject(object_id_t object) { return ACS_SUBSYSTEM_STRING; case 0x73010002: return PL_SUBSYSTEM_STRING; + case 0x73010003: + return TCS_SUBSYSTEM_STRING; + case 0x73010004: + return COM_SUBSYSTEM_STRING; case 0x73500000: return CCSDS_IP_CORE_BRIDGE_STRING; case 0xFFFFFFFF: diff --git a/linux/ObjectFactory.cpp b/linux/ObjectFactory.cpp index af968ddd..a147af26 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -28,6 +28,7 @@ #include "mission/system/objects/TcsBoardAssembly.h" #include "mission/system/tree/acsModeTree.h" #include "mission/system/tree/payloadModeTree.h" +#include "mission/system/tree/tcsModeTree.h" void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, PowerSwitchIF* pwrSwitcher, std::string spiDev, @@ -301,7 +302,7 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF, TcsBoardHelper helper(rtdInfos); TcsBoardAssembly* tcsBoardAss = new TcsBoardAssembly( objects::TCS_BOARD_ASS, pwrSwitcher, pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper); - static_cast(tcsBoardAss); + tcsBoardAss->connectModeTreeParent(satsystem::tcs::SUBSYSTEM); // Create special low level reader communication interface new Max31865RtdReader(objects::SPI_RTD_COM_IF, comIF, gpioComIF); for (uint8_t idx = 0; idx < NUM_RTDS; idx++) { @@ -350,7 +351,8 @@ void ObjectFactory::createScexComponents(std::string uartDev, PowerSwitchIF* pwr } void ObjectFactory::createThermalController() { - new ThermalController(objects::THERMAL_CONTROLLER); + auto* tcsCtrl = new ThermalController(objects::THERMAL_CONTROLLER); + tcsCtrl->connectModeTreeParent(satsystem::tcs::SUBSYSTEM); } AcsController* ObjectFactory::createAcsController(bool connectSubsystem) { diff --git a/linux/devices/Max31865RtdLowlevelHandler.cpp b/linux/devices/Max31865RtdLowlevelHandler.cpp index 38a9ac11..14ef9659 100644 --- a/linux/devices/Max31865RtdLowlevelHandler.cpp +++ b/linux/devices/Max31865RtdLowlevelHandler.cpp @@ -143,7 +143,7 @@ ReturnValue_t Max31865RtdReader::periodicReadHandling() { auto result = returnvalue::OK; MutexGuard mg(readerMutex); if (mg.getLockResult() != returnvalue::OK) { - sif::warning << "Max31865RtdReader::periodicReadReqHandling: Mutex lock failed" << std::endl; + sif::warning << "Max31865RtdReader::periodicReadHandling: Mutex lock failed" << std::endl; return returnvalue::FAILED; } // Now read the RTD values @@ -154,6 +154,10 @@ ReturnValue_t Max31865RtdReader::periodicReadHandling() { if (rtdIsActive(rtd->idx)) { uint16_t rtdVal = 0; bool faultBitSet = false; + result = writeCfgReg(rtd->spiCookie, BASE_CFG); + if (result != returnvalue::OK) { + handleSpiError(rtd, result, "writeCfgReg"); + } result = readRtdVal(rtd->spiCookie, rtdVal, faultBitSet); if (result != returnvalue::OK) { handleSpiError(rtd, result, "readRtdVal"); @@ -282,7 +286,13 @@ ReturnValue_t Max31865RtdReader::sendMessage(CookieIF* cookie, const uint8_t* se } break; } - case (EiveMax31855::RtdCommands::CFG): + case (EiveMax31855::RtdCommands::CFG): { + ReturnValue_t result = writeCfgReg(rtdCookie->spiCookie, BASE_CFG); + if (result != returnvalue::OK) { + handleSpiError(rtdCookie, result, "writeCfgReg"); + } + break; + } default: { // TODO: Only implement if needed break; diff --git a/linux/devices/startracker/StarTrackerHandler.cpp b/linux/devices/startracker/StarTrackerHandler.cpp index bede0a45..21f7174e 100644 --- a/linux/devices/startracker/StarTrackerHandler.cpp +++ b/linux/devices/startracker/StarTrackerHandler.cpp @@ -1209,6 +1209,21 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l localDataPoolMap.emplace(startracker::DEBUG_CAMERA_TEST, new PoolEntry({0})); localDataPoolMap.emplace(startracker::CHKSUM, new PoolEntry({0})); + + poolManager.subscribeForDiagPeriodicPacket( + subdp::DiagnosticsHkPeriodicParams(temperatureSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(powerSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(interfaceSet.getSid(), false, 10.0)); + poolManager.subscribeForDiagPeriodicPacket( + subdp::DiagnosticsHkPeriodicParams(solutionSet.getSid(), false, 5.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(cameraSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(histogramSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(lisaSet.getSid(), false, 10.0)); return returnvalue::OK; } diff --git a/linux/fsfwconfig/events/subsystemIdRanges.h b/linux/fsfwconfig/events/subsystemIdRanges.h index 6b7a1c1d..7e23e37d 100644 --- a/linux/fsfwconfig/events/subsystemIdRanges.h +++ b/linux/fsfwconfig/events/subsystemIdRanges.h @@ -13,7 +13,6 @@ namespace SUBSYSTEM_ID { enum : uint8_t { SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_END, - CORE = 137, }; } diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 135981b6..65f118b2 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 240 translations. + * @brief Auto-generated event translation file. Contains 244 translations. * @details - * Generated on: 2023-01-18 16:08:56 + * Generated on: 2023-02-01 19:42:11 */ #include "translateEvents.h" @@ -82,6 +82,7 @@ const char *BIT_LOCK_STRING = "BIT_LOCK"; const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST"; const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED"; const char *CLOCK_SET_STRING = "CLOCK_SET"; +const char *CLOCK_DUMP_STRING = "CLOCK_DUMP"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED"; const char *TEST_STRING = "TEST"; @@ -228,11 +229,8 @@ const char *SUPV_REPLY_CRC_MISSMATCH_STRING = "SUPV_REPLY_CRC_MISSMATCH"; const char *SUPV_UPDATE_PROGRESS_STRING = "SUPV_UPDATE_PROGRESS"; const char *HDLC_FRAME_REMOVAL_ERROR_STRING = "HDLC_FRAME_REMOVAL_ERROR"; const char *HDLC_CRC_ERROR_STRING = "HDLC_CRC_ERROR"; -const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; -const char *REBOOT_SW_STRING = "REBOOT_SW"; -const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; -const char *REBOOT_HW_STRING = "REBOOT_HW"; -const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; +const char *TX_ON_STRING = "TX_ON"; +const char *TX_OFF_STRING = "TX_OFF"; const char *MISSING_PACKET_STRING = "MISSING_PACKET"; const char *EXPERIMENT_TIMEDOUT_STRING = "EXPERIMENT_TIMEDOUT"; const char *MULTI_PACKET_COMMAND_DONE_STRING = "MULTI_PACKET_COMMAND_DONE"; @@ -241,6 +239,11 @@ const char *GET_CONFIGFILEVALUE_FAILED_STRING = "GET_CONFIGFILEVALUE_FAILED"; const char *INSERT_CONFIGFILEVALUE_FAILED_STRING = "INSERT_CONFIGFILEVALUE_FAILED"; const char *WRITE_CONFIGFILE_FAILED_STRING = "WRITE_CONFIGFILE_FAILED"; const char *READ_CONFIGFILE_FAILED_STRING = "READ_CONFIGFILE_FAILED"; +const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; +const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; +const char *REBOOT_HW_STRING = "REBOOT_HW"; +const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; const char *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -399,6 +402,8 @@ const char *translateEvents(Event event) { case (8900): return CLOCK_SET_STRING; case (8901): + return CLOCK_DUMP_STRING; + case (8902): return CLOCK_SET_FAILURE_STRING; case (9100): return TC_DELETION_FAILED_STRING; @@ -690,16 +695,10 @@ const char *translateEvents(Event event) { return HDLC_FRAME_REMOVAL_ERROR_STRING; case (13632): return HDLC_CRC_ERROR_STRING; - case (13700): - return ALLOC_FAILURE_STRING; case (13701): - return REBOOT_SW_STRING; + return TX_ON_STRING; case (13702): - return REBOOT_MECHANISM_TRIGGERED_STRING; - case (13703): - return REBOOT_HW_STRING; - case (13704): - return NO_SD_CARD_ACTIVE_STRING; + return TX_OFF_STRING; case (13800): return MISSING_PACKET_STRING; case (13801): @@ -716,6 +715,16 @@ const char *translateEvents(Event event) { return WRITE_CONFIGFILE_FAILED_STRING; case (13905): return READ_CONFIGFILE_FAILED_STRING; + case (14000): + return ALLOC_FAILURE_STRING; + case (14001): + return REBOOT_SW_STRING; + case (14002): + return REBOOT_MECHANISM_TRIGGERED_STRING; + case (14003): + return REBOOT_HW_STRING; + case (14004): + return NO_SD_CARD_ACTIVE_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/linux/fsfwconfig/objects/systemObjectList.h b/linux/fsfwconfig/objects/systemObjectList.h index 8f36b013..7624cd5f 100644 --- a/linux/fsfwconfig/objects/systemObjectList.h +++ b/linux/fsfwconfig/objects/systemObjectList.h @@ -39,8 +39,6 @@ enum sourceObjects : uint32_t { FW_ADDRESS_END = TIME_STAMPER, PUS_SERVICE_6 = 0x51000500, - CCSDS_IP_CORE_BRIDGE = 0x73500000, - /* 0x49 ('I') for Communication Interfaces **/ ARDUINO_COM_IF = 0x49000000, CSP_COM_IF = 0x49050001, diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 4d0f5c1f..fdc28d47 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 150 translations. - * Generated on: 2023-01-18 16:08:56 + * Contains 152 translations. + * Generated on: 2023-02-01 19:42:11 */ #include "translateObjects.h" @@ -80,7 +80,7 @@ const char *RTD_12_IC15_ACU_STRING = "RTD_12_IC15_ACU"; const char *RTD_13_IC16_PLPCDU_HEATSPREADER_STRING = "RTD_13_IC16_PLPCDU_HEATSPREADER"; const char *RTD_14_IC17_TCS_BOARD_STRING = "RTD_14_IC17_TCS_BOARD"; const char *RTD_15_IC18_IMTQ_STRING = "RTD_15_IC18_IMTQ"; -const char *SYRLINKS_HK_HANDLER_STRING = "SYRLINKS_HK_HANDLER"; +const char *SYRLINKS_HANDLER_STRING = "SYRLINKS_HANDLER"; const char *ARDUINO_COM_IF_STRING = "ARDUINO_COM_IF"; const char *GPIO_IF_STRING = "GPIO_IF"; const char *SCEX_UART_READER_STRING = "SCEX_UART_READER"; @@ -154,6 +154,8 @@ const char *CFDP_DISTRIBUTOR_STRING = "CFDP_DISTRIBUTOR"; const char *EIVE_SYSTEM_STRING = "EIVE_SYSTEM"; const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM"; const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM"; +const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM"; +const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -308,7 +310,7 @@ const char *translateObject(object_id_t object) { case 0x44420031: return RTD_15_IC18_IMTQ_STRING; case 0x445300A3: - return SYRLINKS_HK_HANDLER_STRING; + return SYRLINKS_HANDLER_STRING; case 0x49000000: return ARDUINO_COM_IF_STRING; case 0x49010005: @@ -455,6 +457,10 @@ const char *translateObject(object_id_t object) { return ACS_SUBSYSTEM_STRING; case 0x73010002: return PL_SUBSYSTEM_STRING; + case 0x73010003: + return TCS_SUBSYSTEM_STRING; + case 0x73010004: + return COM_SUBSYSTEM_STRING; case 0x73500000: return CCSDS_IP_CORE_BRIDGE_STRING; case 0xFFFFFFFF: diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 5dd87e0b..5fec0cd6 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -487,12 +487,11 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) { static_cast(length); #if OBSW_ADD_SYRLINKS == 1 - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); #endif #if OBSW_ADD_STAR_TRACKER == 1 diff --git a/linux/ipcore/PdecConfig.cpp b/linux/ipcore/PdecConfig.cpp index 321e5940..21de4610 100644 --- a/linux/ipcore/PdecConfig.cpp +++ b/linux/ipcore/PdecConfig.cpp @@ -9,8 +9,12 @@ PdecConfig::~PdecConfig() {} void PdecConfig::initialize() { uint32_t word = 0; word |= (VERSION_ID << 30); + + // Setting the bypass flag and the control command flag should not have any + // implication on the operation of the PDEC IP Core word |= (BYPASS_FLAG << 29); word |= (CONTROL_COMMAND_FLAG << 28); + word |= (RESERVED_FIELD_A << 26); word |= (SPACECRAFT_ID << 16); word |= (VIRTUAL_CHANNEL << 10); diff --git a/linux/ipcore/PdecConfig.h b/linux/ipcore/PdecConfig.h index 284af6ef..3d909581 100644 --- a/linux/ipcore/PdecConfig.h +++ b/linux/ipcore/PdecConfig.h @@ -34,7 +34,7 @@ class PdecConfig { static const uint8_t VIRTUAL_CHANNEL = 0; static const uint8_t RESERVED_FIELD_A = 0; - static const uint16_t SPACECRAFT_ID = 0x274; + static const uint16_t SPACECRAFT_ID = 0x3DC; static const uint16_t DUMMY_BITS = 0; // Parameters to control the FARM for AD frames // Set here for future use diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index bc33a220..57d59841 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -188,6 +188,7 @@ ReturnValue_t PdecHandler::irqOperation() { if ((pisr & NEW_FAR_MASK) == NEW_FAR_MASK) { // Read FAR here CURRENT_FAR = readFar(); + checkFrameAna(CURRENT_FAR); } if (lockCheckCd.hasTimedOut()) { checkLocks(); diff --git a/linux/ipcore/PdecHandler.h b/linux/ipcore/PdecHandler.h index b7089999..6ebd9ce6 100644 --- a/linux/ipcore/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -5,6 +5,7 @@ #include "OBSWConfig.h" #include "PdecConfig.h" +#include "eive/definitions.h" #include "fsfw/action/ActionHelper.h" #include "fsfw/action/HasActionsIF.h" #include "fsfw/objectmanager/SystemObject.h" @@ -120,7 +121,7 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc //! Invalid BC control command static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE); - static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE; + static const uint32_t QUEUE_SIZE = config::CCSDS_HANDLER_QUEUE_SIZE; // Action IDs static const ActionId_t PRINT_CLCW = 0; diff --git a/linux/ipcore/Ptme.cpp b/linux/ipcore/Ptme.cpp index 0c475236..50b1a37c 100644 --- a/linux/ipcore/Ptme.cpp +++ b/linux/ipcore/Ptme.cpp @@ -4,6 +4,7 @@ #include #include "PtmeConfig.h" +#include "eive/definitions.h" #include "fsfw/serviceinterface/ServiceInterface.h" Ptme::Ptme(object_id_t objectId) : SystemObject(objectId) {} @@ -32,7 +33,7 @@ ReturnValue_t Ptme::writeToVc(uint8_t vcId, const uint8_t* data, size_t size) { } void Ptme::addVcInterface(VcId_t vcId, VcInterfaceIF* vc) { - if (vcId > common::NUMBER_OF_VIRTUAL_CHANNELS) { + if (vcId > config::NUMBER_OF_VIRTUAL_CHANNELS) { sif::warning << "Ptme::addVcInterface: Invalid virtual channel ID" << std::endl; return; } diff --git a/mission/CMakeLists.txt b/mission/CMakeLists.txt index 6b4248bf..d3782d4b 100644 --- a/mission/CMakeLists.txt +++ b/mission/CMakeLists.txt @@ -7,3 +7,4 @@ add_subdirectory(tmtc) add_subdirectory(system) add_subdirectory(csp) add_subdirectory(cfdp) +add_subdirectory(config) diff --git a/mission/comDefs.h b/mission/comDefs.h new file mode 100644 index 00000000..5538b166 --- /dev/null +++ b/mission/comDefs.h @@ -0,0 +1,31 @@ +#ifndef MISSION_COMDEFS_H_ +#define MISSION_COMDEFS_H_ + +namespace com { + +enum class Datarate : uint8_t { + LOW_RATE_MODULATION_BPSK, + HIGH_RATE_MODULATION_0QPSK, + NUM_DATARATES +}; + +enum Submode : uint8_t { + RX_ONLY, + RX_AND_TX_DEFAULT_DATARATE, + RX_AND_TX_LOW_DATARATE, + RX_AND_TX_HIGH_DATARATE, + RX_AND_TX_CW, + NUM_SUBMODES +}; + +enum class CcsdsSubmode : uint8_t { + UNSET = 0, + DATARATE_LOW = 1, + DATARATE_HIGH = 2, + DATARATE_DEFAULT = 3 +}; +enum class ParameterId : uint8_t { DATARATE = 0 }; + +} // namespace com + +#endif /* MISSION_COMDEFS_H_ */ diff --git a/mission/config/CMakeLists.txt b/mission/config/CMakeLists.txt new file mode 100644 index 00000000..5cacbf02 --- /dev/null +++ b/mission/config/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(${LIB_EIVE_MISSION} PRIVATE comCfg.cpp torquer.cpp) diff --git a/mission/config/comCfg.cpp b/mission/config/comCfg.cpp new file mode 100644 index 00000000..9e350a9d --- /dev/null +++ b/mission/config/comCfg.cpp @@ -0,0 +1,26 @@ +#include "comCfg.h" + +#include +#include + +com::Datarate DATARATE_CFG_RAW = com::Datarate::LOW_RATE_MODULATION_BPSK; +MutexIF* DATARATE_LOCK = nullptr; + +MutexIF* lazyLock(); + +com::Datarate com::getCurrentDatarate() { + MutexGuard mg(lazyLock()); + return DATARATE_CFG_RAW; +} + +void com::setCurrentDatarate(com::Datarate newRate) { + MutexGuard mg(lazyLock()); + DATARATE_CFG_RAW = newRate; +} + +MutexIF* lazyLock() { + if (DATARATE_LOCK == nullptr) { + return MutexFactory::instance()->createMutex(); + } + return DATARATE_LOCK; +} diff --git a/mission/config/comCfg.h b/mission/config/comCfg.h new file mode 100644 index 00000000..54a49ade --- /dev/null +++ b/mission/config/comCfg.h @@ -0,0 +1,15 @@ +#ifndef MISSION_COMCFG_H_ +#define MISSION_COMCFG_H_ + +#include + +#include "mission/comDefs.h" + +namespace com { + +com::Datarate getCurrentDatarate(); +void setCurrentDatarate(com::Datarate newRate); + +} // namespace com + +#endif /* MISSION_COMCFG_H_ */ diff --git a/mission/devices/torquer.cpp b/mission/config/torquer.cpp similarity index 100% rename from mission/devices/torquer.cpp rename to mission/config/torquer.cpp diff --git a/mission/devices/torquer.h b/mission/config/torquer.h similarity index 100% rename from mission/devices/torquer.h rename to mission/config/torquer.h diff --git a/mission/controller/AcsController.cpp b/mission/controller/AcsController.cpp index 59b9676b..9e4d8ea0 100644 --- a/mission/controller/AcsController.cpp +++ b/mission/controller/AcsController.cpp @@ -2,7 +2,7 @@ #include -#include "mission/devices/torquer.h" +#include "mission/config/torquer.h" AcsController::AcsController(object_id_t objectId) : ExtendedControllerBase(objectId), diff --git a/mission/controller/ThermalController.cpp b/mission/controller/ThermalController.cpp index f0356f66..08244c03 100644 --- a/mission/controller/ThermalController.cpp +++ b/mission/controller/ThermalController.cpp @@ -746,7 +746,7 @@ void ThermalController::copyDevices() { { lp_var_t tempSyrlinksPowerAmplifier = - lp_var_t(objects::SYRLINKS_HK_HANDLER, syrlinks::TEMP_POWER_AMPLIFIER); + lp_var_t(objects::SYRLINKS_HANDLER, syrlinks::TEMP_POWER_AMPLIFIER); PoolReadGuard pg(&tempSyrlinksPowerAmplifier, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); if (pg.getReadResult() != returnvalue::OK) { sif::warning << "ThermalController: Failed to read syrlinks power amplifier temperature" @@ -761,7 +761,7 @@ void ThermalController::copyDevices() { { lp_var_t tempSyrlinksBasebandBoard = - lp_var_t(objects::SYRLINKS_HK_HANDLER, syrlinks::TEMP_BASEBAND_BOARD); + lp_var_t(objects::SYRLINKS_HANDLER, syrlinks::TEMP_BASEBAND_BOARD); PoolReadGuard pg(&tempSyrlinksBasebandBoard, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); if (pg.getReadResult() != returnvalue::OK) { sif::warning << "ThermalController: Failed to read syrlinks baseband board temperature" diff --git a/mission/controller/acs/AcsParameters.h b/mission/controller/acs/AcsParameters.h index 469112aa..98997e2c 100644 --- a/mission/controller/acs/AcsParameters.h +++ b/mission/controller/acs/AcsParameters.h @@ -51,21 +51,24 @@ class AcsParameters : public HasParametersIF { float mgm3orientationMatrix[3][3] = {{0, 0, 1}, {0, -1, 0}, {1, 0, 0}}; float mgm4orientationMatrix[3][3] = {{0, 0, -1}, {-1, 0, 0}, {0, 1, 0}}; - float mgm0hardIronOffset[3] = {19.89364, -29.94111, -31.07508}; - float mgm1hardIronOffset[3] = {10.95500, -8.053403, -33.36383}; - float mgm2hardIronOffset[3] = {15.72181, -26.87090, -62.19010}; + float mgm0hardIronOffset[3] = {0.0, 0.0, 0.0}; //{19.89364, -29.94111, -31.07508}; + float mgm1hardIronOffset[3] = {0.0, 0.0, 0.0}; //{10.95500, -8.053403, -33.36383}; + float mgm2hardIronOffset[3] = {0.0, 0.0, 0.0}; //{15.72181, -26.87090, -62.19010}; float mgm3hardIronOffset[3] = {0.0, 0.0, 0.0}; float mgm4hardIronOffset[3] = {0.0, 0.0, 0.0}; - float mgm0softIronInverse[3][3] = {{1420.727e-3, 9.352825e-3, -127.1979e-3}, - {9.352825e-3, 1031.965e-3, -80.02734e-3}, - {-127.1979e-3, -80.02734e-3, 934.8899e-3}}; - float mgm1softIronInverse[3][3] = {{126.7325e-2, -4.146410e-2, -18.37963e-2}, - {-4.146410e-2, 109.3310e-2, -5.246314e-2}, - {-18.37963e-2, -5.246314e-2, 105.7300e-2}}; - float mgm2softIronInverse[3][3] = {{143.0438e-2, 7.095763e-2, 15.67482e-2}, - {7.095763e-2, 99.65167e-2, -6.958760e-2}, - {15.67482e-2, -6.958760e-2, 94.50124e-2}}; + float mgm0softIronInverse[3][3] = { + {1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; /*{{1420.727e-3, 9.352825e-3, + -127.1979e-3}, {9.352825e-3, 1031.965e-3, -80.02734e-3}, + {-127.1979e-3, -80.02734e-3, 934.8899e-3}};*/ + float mgm1softIronInverse[3][3] = { + {1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; /*{{126.7325e-2, -4.146410e-2, -18.37963e-2}, + {-4.146410e-2, 109.3310e-2, -5.246314e-2}, + {-18.37963e-2, -5.246314e-2, 105.7300e-2}};*/ + float mgm2softIronInverse[3][3] = { + {1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; /*{{143.0438e-2, 7.095763e-2, + 15.67482e-2}, {7.095763e-2, 99.65167e-2, -6.958760e-2}, + {15.67482e-2, -6.958760e-2, 94.50124e-2}};*/ float mgm3softIronInverse[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; float mgm4softIronInverse[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; float mgm02variance[3] = {1, 1, 1}; diff --git a/mission/controller/acs/SensorProcessing.cpp b/mission/controller/acs/SensorProcessing.cpp index 815b3a6b..9a1a9637 100644 --- a/mission/controller/acs/SensorProcessing.cpp +++ b/mission/controller/acs/SensorProcessing.cpp @@ -125,7 +125,7 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const } if (mgm4valid) { float mgm4ValueNT[3]; - VectorOperations::mulScalar(mgm4Value, 1e3, mgm4ValueNT, 3); // uT to nT + VectorOperations::mulScalar(mgm4Value, 1e-3, mgm4ValueNT, 3); // uT to nT VectorOperations::subtract(mgm4ValueNT, mgmParameters->mgm4hardIronOffset, mgm4ValueNoBias, 3); MatrixOperations::multiply(mgmParameters->mgm4softIronInverse[0], mgm4ValueNoBias, diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index cca48baf..9c08726c 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include @@ -104,16 +104,17 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new UdpTcPollingTask(objects::UDP_TMTC_POLLING_TASK, objects::UDP_TMTC_SERVER); sif::info << "Created UDP server for TMTC commanding with listener port " << udpBridge->getUdpPort() << std::endl; - udpBridge->setMaxNumberOfPacketsStored(150); + udpBridge->setMaxNumberOfPacketsStored(config::MAX_STORED_CMDS_UDP); #endif #if OBSW_ADD_TMTC_TCP_SERVER == 1 auto tcpBridge = new TcpTmTcBridge(objects::TCP_TMTC_SERVER, objects::CCSDS_PACKET_DISTRIBUTOR); - auto tcpServer = new TcpTmTcServer(objects::TCP_TMTC_POLLING_TASK, objects::TCP_TMTC_SERVER); + TcpTmTcServer::TcpConfig cfg(true, true); + auto tcpServer = new TcpTmTcServer(objects::TCP_TMTC_POLLING_TASK, objects::TCP_TMTC_SERVER, cfg); // TCP is stream based. Use packet ID as start marker when parsing for space packets tcpServer->setSpacePacketParsingOptions({common::PUS_PACKET_ID, common::CFDP_PACKET_ID}); sif::info << "Created TCP server for TMTC commanding with listener port " << tcpServer->getTcpPort() << std::endl; - tcpBridge->setMaxNumberOfPacketsStored(150); + tcpBridge->setMaxNumberOfPacketsStored(config::MAX_STORED_CMDS_TCP); #endif /* OBSW_USE_TMTC_TCP_BRIDGE == 0 */ #endif /* OBSW_ADD_TCPIP_BRIDGE == 1 */ @@ -122,7 +123,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib); *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 50); - *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, 80); + *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, + config::MAX_PUS_FUNNEL_QUEUE_DEPTH); #if OBSW_ADD_TCPIP_SERVERS == 1 #if OBSW_ADD_TMTC_UDP_SERVER == 1 (*cfdpFunnel)->addDestination(*udpBridge, 0); @@ -160,8 +162,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun pus::PUS_SERVICE_20); new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, config::EIVE_PUS_APID, pus::PUS_SERVICE_200, 8); - new CService201HealthCommanding(objects::PUS_SERVICE_201_HEALTH, config::EIVE_PUS_APID, - pus::PUS_SERVICE_201); + HealthServiceCfg healthCfg(objects::PUS_SERVICE_201_HEALTH, config::EIVE_PUS_APID, *healthTable, 20); + new CServiceHealthCommanding(healthCfg); #if OBSW_ADD_CFDP_COMPONENTS == 1 using namespace cfdp; diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 1589a460..ce02c688 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -8,7 +8,7 @@ target_sources( PDU1Handler.cpp PDU2Handler.cpp ACUHandler.cpp - SyrlinksHkHandler.cpp + SyrlinksHandler.cpp Max31865PT1000Handler.cpp Max31865EiveHandler.cpp ImtqHandler.cpp @@ -20,7 +20,6 @@ target_sources( SusHandler.cpp PayloadPcduHandler.cpp SolarArrayDeploymentHandler.cpp - ScexDeviceHandler.cpp - torquer.cpp) + ScexDeviceHandler.cpp) add_subdirectory(devicedefinitions) diff --git a/mission/devices/GyroADIS1650XHandler.cpp b/mission/devices/GyroADIS1650XHandler.cpp index 5b59d7f6..765bc589 100644 --- a/mission/devices/GyroADIS1650XHandler.cpp +++ b/mission/devices/GyroADIS1650XHandler.cpp @@ -228,15 +228,15 @@ ReturnValue_t GyroADIS1650XHandler::interpretDeviceReply(DeviceCommandId_t id, static_cast((rangMdlRaw >> 2) & 0b11); switch (bitfield) { case (ADIS1650X::RangMdlBitfield::RANGE_125_1BMLZ): { - rangeMultiplicator = RANGE_1BMLZ; + sensitivity = SENSITIVITY_1BMLZ; break; } case (ADIS1650X::RangMdlBitfield::RANGE_500_2BMLZ): { - rangeMultiplicator = RANGE_2BMLZ; + sensitivity = SENSITIVITY_2BMLZ; break; } case (ADIS1650X::RangMdlBitfield::RANGE_2000_3BMLZ): { - rangeMultiplicator = RANGE_3BMLZ; + sensitivity = SENSITIVITY_3BMLZ; break; } case (RangMdlBitfield::RESERVED): { @@ -298,14 +298,11 @@ ReturnValue_t GyroADIS1650XHandler::handleSensorData(const uint8_t *packet) { { PoolReadGuard pg(&primaryDataset); int16_t angVelocXRaw = packet[4] << 8 | packet[5]; - primaryDataset.angVelocX.value = - static_cast(angVelocXRaw) / static_cast(INT16_MAX) * rangeMultiplicator; + primaryDataset.angVelocX.value = static_cast(angVelocXRaw) * sensitivity; int16_t angVelocYRaw = packet[6] << 8 | packet[7]; - primaryDataset.angVelocY.value = - static_cast(angVelocYRaw) / static_cast(INT16_MAX) * rangeMultiplicator; + primaryDataset.angVelocY.value = static_cast(angVelocYRaw) * sensitivity; int16_t angVelocZRaw = packet[8] << 8 | packet[9]; - primaryDataset.angVelocZ.value = - static_cast(angVelocZRaw) / static_cast(INT16_MAX) * rangeMultiplicator; + primaryDataset.angVelocZ.value = static_cast(angVelocZRaw) * sensitivity; float accelScaling = 0; if (adisType == ADIS1650X::Type::ADIS16507) { diff --git a/mission/devices/GyroADIS1650XHandler.h b/mission/devices/GyroADIS1650XHandler.h index f664407c..34335c51 100644 --- a/mission/devices/GyroADIS1650XHandler.h +++ b/mission/devices/GyroADIS1650XHandler.h @@ -46,7 +46,7 @@ class GyroADIS1650XHandler : public DeviceHandlerBase { ADIS1650X::Type adisType; AdisGyroPrimaryDataset primaryDataset; AdisGyroConfigDataset configDataset; - double rangeMultiplicator = ADIS1650X::RANGE_UNSET; + double sensitivity = ADIS1650X::SENSITIVITY_UNSET; bool goToNormalMode = false; bool warningSwitch = true; diff --git a/mission/devices/ImtqHandler.cpp b/mission/devices/ImtqHandler.cpp index a0e717f8..8cdb8de6 100644 --- a/mission/devices/ImtqHandler.cpp +++ b/mission/devices/ImtqHandler.cpp @@ -25,7 +25,7 @@ #include #include -#include "mission/devices/torquer.h" +#include "mission/config/torquer.h" static constexpr bool ACTUATION_WIRETAPPING = false; diff --git a/mission/devices/Max31865EiveHandler.cpp b/mission/devices/Max31865EiveHandler.cpp index db6f5a83..3fcd0f32 100644 --- a/mission/devices/Max31865EiveHandler.cpp +++ b/mission/devices/Max31865EiveHandler.cpp @@ -36,6 +36,7 @@ void Max31865EiveHandler::doShutDown() { transitionOk = false; } if (state == InternalState::INACTIVE and transitionOk) { + updatePeriodicReply(false, EiveMax31855::RtdCommands::EXCHANGE_SET_ID); setMode(MODE_OFF); } } @@ -69,7 +70,8 @@ ReturnValue_t Max31865EiveHandler::buildCommandFromCommand(DeviceCommandId_t dev switch (cmdTyped) { case (EiveMax31855::RtdCommands::ON): case (EiveMax31855::RtdCommands::ACTIVE): - case (EiveMax31855::RtdCommands::OFF): { + case (EiveMax31855::RtdCommands::OFF): + case (EiveMax31855::RtdCommands::CFG): { simpleCommand(cmdTyped); break; } @@ -77,9 +79,6 @@ ReturnValue_t Max31865EiveHandler::buildCommandFromCommand(DeviceCommandId_t dev case (EiveMax31855::RtdCommands::HIGH_TRESHOLD): { break; } - case (EiveMax31855::RtdCommands::CFG): { - break; - } default: return NOTHING_TO_SEND; } @@ -100,6 +99,7 @@ void Max31865EiveHandler::simpleCommand(EiveMax31855::RtdCommands cmd) { rawPacket = cmdBuf.data(); rawPacketLen = 1; } + void Max31865EiveHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { if (getMode() == _MODE_TO_NORMAL) { if (state != InternalState::ACTIVE) { @@ -117,6 +117,7 @@ void Max31865EiveHandler::fillCommandAndReplyMap() { insertInCommandMap(EiveMax31855::RtdCommands::ON); insertInCommandMap(EiveMax31855::RtdCommands::ACTIVE); insertInCommandMap(EiveMax31855::RtdCommands::OFF); + insertInCommandMap(EiveMax31855::RtdCommands::CFG); insertInReplyMap(EiveMax31855::RtdCommands::EXCHANGE_SET_ID, 200, &sensorDataset, 0, true); } diff --git a/mission/devices/PcduHandler.cpp b/mission/devices/PcduHandler.cpp index 29b8dc6e..06d296b4 100644 --- a/mission/devices/PcduHandler.cpp +++ b/mission/devices/PcduHandler.cpp @@ -424,8 +424,8 @@ ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool& localDat localDataPoolMap.emplace(PoolIds::PDU1_SWITCHES, &pdu1Switches); localDataPoolMap.emplace(PoolIds::PDU2_SWITCHES, &pdu2Switches); localDataPoolMap.emplace(PoolIds::P60DOCK_SWITCHES, &p60Dock5VSwitch); - poolManager.subscribeForRegularPeriodicPacket( - subdp::RegularHkPeriodicParams(switcherSet.getSid(), false, 5.0)); + poolManager.subscribeForDiagPeriodicPacket( + subdp::DiagnosticsHkPeriodicParams(switcherSet.getSid(), false, 5.0)); return returnvalue::OK; } diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 5656692d..2b4e22ac 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -97,12 +97,19 @@ void SolarArrayDeploymentHandler::handleStateMachine() { // This should never fail channelAlternationCd.resetTimer(); if (not fsmInfo.dryRun) { - sa2Off(); - sa1On(); - fsmInfo.alternationDummy = true; + if (fsmInfo.initChannel == 0) { + sa2Off(); + sa1On(); + fsmInfo.alternationDummy = true; + } else { + sa1Off(); + sa2On(); + fsmInfo.alternationDummy = false; + } } sif::info << "S/A Deployment: Burning" << std::endl; triggerEvent(BURN_PHASE_START, fsmInfo.burnCountdownMs, fsmInfo.dryRun); + channelAlternationCd.resetTimer(); stateMachine = BURNING; } if (stateMachine == BURNING) { @@ -219,7 +226,8 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(sd::SdCard sdCard, const if (stateSwitch or firstAutonomousCycle) { if (deplState == AutonomousDeplState::FIRST_BURN or deplState == AutonomousDeplState::SECOND_BURN) { - startFsmOn(config::SA_DEPL_BURN_TIME_SECS, dryRun); + startFsmOn(config::SA_DEPL_BURN_TIME_SECS, (config::SA_DEPL_BURN_TIME_SECS / 2) * 1000, 0, + dryRun); } else if (deplState == AutonomousDeplState::WAIT or deplState == AutonomousDeplState::DONE or deplState == AutonomousDeplState::INIT) { startFsmOff(); @@ -283,15 +291,19 @@ bool SolarArrayDeploymentHandler::checkMainPower(bool onOff) { return false; } -bool SolarArrayDeploymentHandler::startFsmOn(uint32_t burnCountdownSecs, bool dryRun) { +bool SolarArrayDeploymentHandler::startFsmOn(uint32_t burnCountdownSecs, + uint32_t channelAlternationIntervalMs, + uint8_t initChannel, bool dryRun) { if (stateMachine != StateMachine::IDLE) { return false; } + channelAlternationCd.setTimeout(channelAlternationIntervalMs); if (burnCountdownSecs > config::SA_DEPL_MAX_BURN_TIME) { burnCountdownSecs = config::SA_DEPL_MAX_BURN_TIME; } fsmInfo.dryRun = dryRun; fsmInfo.burnCountdownMs = burnCountdownSecs * 1000; + fsmInfo.initChannel = initChannel; stateMachine = StateMachine::MAIN_POWER_ON; retryCounter = 0; return true; @@ -354,8 +366,9 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, if (result != returnvalue::OK) { return result; } - uint32_t burnCountdown = cmd.getBurnTime(); - if (not startFsmOn(burnCountdown, cmd.isDryRun())) { + uint32_t burnCountdown = cmd.getBurnTimeSecs(); + if (not startFsmOn(burnCountdown, cmd.getSwitchIntervalMs(), cmd.getInitChannel(), + cmd.isDryRun())) { return HasActionsIF::IS_BUSY; } actionActive = true; diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index b935b096..63f1d3de 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -28,16 +28,24 @@ class ManualDeploymentCommand : public SerialLinkedListAdapter { ManualDeploymentCommand() { setLinks(); } void setLinks() { - setStart(&burnTime); - burnTime.setNext(&dryRun); + setStart(&burnTimeSecs); + burnTimeSecs.setNext(&switchIntervalMs); + switchIntervalMs.setNext(&initChannel); + initChannel.setNext(&dryRun); } - uint32_t getBurnTime() const { return burnTime.entry; } + uint32_t getBurnTimeSecs() const { return burnTimeSecs.entry; } + + uint32_t getSwitchIntervalMs() const { return switchIntervalMs.entry; }; + + uint8_t getInitChannel() const { return initChannel.entry; }; bool isDryRun() const { return dryRun.entry; } private: - SerializeElement burnTime; + SerializeElement burnTimeSecs; + SerializeElement switchIntervalMs; + SerializeElement initChannel; SerializeElement dryRun; }; @@ -50,7 +58,16 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, public SystemObject, public HasActionsIF { public: - //! Manual deployment of the solar arrays. Burn time and channels are supplied with TC parameters + //! Manual deployment of the solar arrays. Burn time, channel switch interval, initial + //! burn channel and dry run flag are supplied as parameters. There are following cases to + //! consider. + //! + //! - Channel switch interval greater or equal to burn time: Only burn one channel. The init + //! burn channel parameter can be used to select which channel is burned. + //! - Channel switch interval half of burn time: Burn each channel for half of the burn time. + //! + //! The dry run flag can be used to avoid actually toggling IO pins and only test the + //! application logic. static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x05; static constexpr DeviceCommandId_t SWITCH_OFF_DEPLOYMENT = 0x06; @@ -119,6 +136,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, // DeploymentChannels channel; bool dryRun; bool alternationDummy = false; + uint8_t initChannel = 0; uint32_t burnCountdownMs = config::SA_DEPL_MAX_BURN_TIME; }; @@ -157,7 +175,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, PeriodicOperationDivider opDivider = PeriodicOperationDivider(5); uint8_t retryCounter = 3; - bool startFsmOn(uint32_t burnCountdownSecs, bool dryRun); + bool startFsmOn(uint32_t burnCountdownSecs, uint32_t channelAlternationIntervalMs, + uint8_t initChannel, bool dryRun); void startFsmOff(); void finishFsm(ReturnValue_t resultForActionHelper); @@ -175,8 +194,9 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, */ Countdown burnCountdown; + // Only initial value, new approach is to burn each channel half of the total burn time. Countdown channelAlternationCd = - Countdown(config::SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS * 1000); + Countdown(config::LEGACY_SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS * 1000); /** * The message queue id of the component commanding an action will be stored in this variable. diff --git a/mission/devices/SyrlinksHkHandler.cpp b/mission/devices/SyrlinksHandler.cpp similarity index 68% rename from mission/devices/SyrlinksHkHandler.cpp rename to mission/devices/SyrlinksHandler.cpp index b07d665e..c1ebfa48 100644 --- a/mission/devices/SyrlinksHkHandler.cpp +++ b/mission/devices/SyrlinksHandler.cpp @@ -1,11 +1,12 @@ #include #include -#include +#include #include "OBSWConfig.h" +#include "mission/config/comCfg.h" -SyrlinksHkHandler::SyrlinksHkHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, - power::Switch_t powerSwitch, FailureIsolationBase* customFdir) +SyrlinksHandler::SyrlinksHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, + power::Switch_t powerSwitch, FailureIsolationBase* customFdir) : DeviceHandlerBase(objectId, comIF, comCookie, customFdir), rxDataset(this), txDataset(this), @@ -16,26 +17,40 @@ SyrlinksHkHandler::SyrlinksHkHandler(object_id_t objectId, object_id_t comIF, Co } } -SyrlinksHkHandler::~SyrlinksHkHandler() {} +SyrlinksHandler::~SyrlinksHandler() = default; -void SyrlinksHkHandler::doStartUp() { - switch (startupState) { - case StartupState::OFF: { - startupState = StartupState::ENABLE_TEMPERATURE_PROTECTION; - break; +void SyrlinksHandler::doStartUp() { + if (internalState == InternalState::OFF) { + internalState = InternalState::ENABLE_TEMPERATURE_PROTECTION; + commandExecuted = false; + } + if (internalState == InternalState::ENABLE_TEMPERATURE_PROTECTION) { + if (commandExecuted) { + // Go to normal mode immediately and disable transmitter on startup. + setMode(_MODE_TO_NORMAL); + internalState = InternalState::IDLE; + commandExecuted = false; } - case StartupState::DONE: { - setMode(_MODE_TO_ON); - break; - } - default: - break; } } -void SyrlinksHkHandler::doShutDown() { setMode(_MODE_POWER_DOWN); } +void SyrlinksHandler::doShutDown() { + // In any case, always disable TX first. + if (internalState != InternalState::SET_TX_STANDBY) { + internalState = InternalState::SET_TX_STANDBY; + commandExecuted = false; + } + if (internalState == InternalState::SET_TX_STANDBY) { + if (commandExecuted) { + temperatureSet.setValidity(false, true); + internalState = InternalState::OFF; + commandExecuted = false; + setMode(_MODE_POWER_DOWN); + } + } +} -ReturnValue_t SyrlinksHkHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { +ReturnValue_t SyrlinksHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { switch (nextCommand) { case (syrlinks::READ_RX_STATUS_REGISTERS): *id = syrlinks::READ_RX_STATUS_REGISTERS; @@ -81,21 +96,41 @@ ReturnValue_t SyrlinksHkHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) return buildCommandFromCommand(*id, nullptr, 0); } -ReturnValue_t SyrlinksHkHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { - switch (startupState) { - case StartupState::ENABLE_TEMPERATURE_PROTECTION: { +ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { + switch (internalState) { + case InternalState::ENABLE_TEMPERATURE_PROTECTION: { *id = syrlinks::WRITE_LCL_CONFIG; return buildCommandFromCommand(*id, nullptr, 0); } + case InternalState::SET_TX_MODULATION: { + *id = syrlinks::SET_TX_MODE_MODULATION; + return buildCommandFromCommand(*id, nullptr, 0); + } + case InternalState::SELECT_MODULATION_BPSK: { + *id = syrlinks::SET_WAVEFORM_BPSK; + return buildCommandFromCommand(*id, nullptr, 0); + } + case InternalState::SELECT_MODULATION_0QPSK: { + *id = syrlinks::SET_WAVEFORM_0QPSK; + return buildCommandFromCommand(*id, nullptr, 0); + } + case InternalState::SET_TX_CW: { + *id = syrlinks::SET_TX_MODE_CW; + return buildCommandFromCommand(*id, nullptr, 0); + } + case InternalState::SET_TX_STANDBY: { + *id = syrlinks::SET_TX_MODE_STANDBY; + return buildCommandFromCommand(*id, nullptr, 0); + } default: break; } return NOTHING_TO_SEND; } -ReturnValue_t SyrlinksHkHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, - const uint8_t* commandData, - size_t commandDataLen) { +ReturnValue_t SyrlinksHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t* commandData, + size_t commandDataLen) { switch (deviceCommand) { case (syrlinks::RESET_UNIT): { prepareCommand(resetCommand, deviceCommand); @@ -157,11 +192,11 @@ ReturnValue_t SyrlinksHkHandler::buildCommandFromCommand(DeviceCommandId_t devic prepareCommand(tempBasebandBoardLowByte, deviceCommand); return returnvalue::OK; } - case (syrlinks::CONFIG_BPSK): { + case (syrlinks::SET_WAVEFORM_BPSK): { prepareCommand(configBPSK, deviceCommand); return returnvalue::OK; } - case (syrlinks::CONFIG_OQPSK): { + case (syrlinks::SET_WAVEFORM_0QPSK): { prepareCommand(configOQPSK, deviceCommand); return returnvalue::OK; } @@ -181,7 +216,7 @@ ReturnValue_t SyrlinksHkHandler::buildCommandFromCommand(DeviceCommandId_t devic return returnvalue::FAILED; } -void SyrlinksHkHandler::fillCommandAndReplyMap() { +void SyrlinksHandler::fillCommandAndReplyMap() { this->insertInCommandAndReplyMap(syrlinks::RESET_UNIT, 1, nullptr, syrlinks::ACK_SIZE, false, true, syrlinks::ACK_REPLY); this->insertInCommandAndReplyMap(syrlinks::SET_TX_MODE_STANDBY, 1, nullptr, syrlinks::ACK_SIZE, @@ -192,10 +227,10 @@ void SyrlinksHkHandler::fillCommandAndReplyMap() { true, syrlinks::ACK_REPLY); this->insertInCommandAndReplyMap(syrlinks::WRITE_LCL_CONFIG, 1, nullptr, syrlinks::ACK_SIZE, false, true, syrlinks::ACK_REPLY); - this->insertInCommandAndReplyMap(syrlinks::CONFIG_BPSK, 1, nullptr, syrlinks::ACK_SIZE, false, - true, syrlinks::ACK_REPLY); - this->insertInCommandAndReplyMap(syrlinks::CONFIG_OQPSK, 1, nullptr, syrlinks::ACK_SIZE, false, - true, syrlinks::ACK_REPLY); + this->insertInCommandAndReplyMap(syrlinks::SET_WAVEFORM_BPSK, 1, nullptr, syrlinks::ACK_SIZE, + false, true, syrlinks::ACK_REPLY); + this->insertInCommandAndReplyMap(syrlinks::SET_WAVEFORM_0QPSK, 1, nullptr, syrlinks::ACK_SIZE, + false, true, syrlinks::ACK_REPLY); this->insertInCommandMap(syrlinks::ENABLE_DEBUG); this->insertInCommandMap(syrlinks::DISABLE_DEBUG); this->insertInCommandAndReplyMap(syrlinks::READ_LCL_CONFIG, 1, nullptr, @@ -220,8 +255,8 @@ void SyrlinksHkHandler::fillCommandAndReplyMap() { syrlinks::RX_STATUS_REGISTERS_REPLY_SIZE); } -ReturnValue_t SyrlinksHkHandler::scanForReply(const uint8_t* start, size_t remainingSize, - DeviceCommandId_t* foundId, size_t* foundLen) { +ReturnValue_t SyrlinksHandler::scanForReply(const uint8_t* start, size_t remainingSize, + DeviceCommandId_t* foundId, size_t* foundLen) { ReturnValue_t result = returnvalue::OK; if (*start != '<') { @@ -251,7 +286,7 @@ ReturnValue_t SyrlinksHkHandler::scanForReply(const uint8_t* start, size_t remai return result; } -ReturnValue_t SyrlinksHkHandler::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) { +ReturnValue_t SyrlinksHandler::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) { if (powerSwitch == power::NO_SWITCH) { return DeviceHandlerBase::NO_SWITCH; } @@ -260,7 +295,7 @@ ReturnValue_t SyrlinksHkHandler::getSwitches(const uint8_t** switches, uint8_t* return returnvalue::OK; } -ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) { +ReturnValue_t SyrlinksHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) { ReturnValue_t result; switch (id) { @@ -363,6 +398,7 @@ ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, cons tempBasebandBoard = calcTempVal(rawTempBasebandBoard); PoolReadGuard rg(&temperatureSet); temperatureSet.temperatureBasebandBoard = tempBasebandBoard; + temperatureSet.temperatureBasebandBoard.setValid(true); if (debugMode) { sif::info << "Syrlinks temperature baseband board: " << tempBasebandBoard << " °C" << std::endl; @@ -394,6 +430,7 @@ ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, cons tempPowerAmplifier = calcTempVal(rawTempPowerAmplifier); PoolReadGuard rg(&temperatureSet); temperatureSet.temperaturePowerAmplifier = tempPowerAmplifier; + temperatureSet.temperaturePowerAmplifier.setValid(true); if (debugMode) { sif::info << "Syrlinks temperature power amplifier board: " << tempPowerAmplifier << " °C" << std::endl; @@ -409,7 +446,7 @@ ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, cons return returnvalue::OK; } -LocalPoolDataSetBase* SyrlinksHkHandler::getDataSetHandle(sid_t sid) { +LocalPoolDataSetBase* SyrlinksHandler::getDataSetHandle(sid_t sid) { if (sid == rxDataset.getSid()) { return &rxDataset; } else if (sid == txDataset.getSid()) { @@ -422,13 +459,13 @@ LocalPoolDataSetBase* SyrlinksHkHandler::getDataSetHandle(sid_t sid) { } } -std::string SyrlinksHkHandler::convertUint16ToHexString(uint16_t intValue) { +std::string SyrlinksHandler::convertUint16ToHexString(uint16_t intValue) { std::stringstream stream; stream << std::setfill('0') << std::setw(4) << std::hex << std::uppercase << intValue; return stream.str(); } -uint8_t SyrlinksHkHandler::convertHexStringToUint8(const char* twoChars) { +uint8_t SyrlinksHandler::convertHexStringToUint8(const char* twoChars) { uint32_t value; std::string hexString(twoChars, 2); std::stringstream stream; @@ -437,36 +474,13 @@ uint8_t SyrlinksHkHandler::convertHexStringToUint8(const char* twoChars) { return static_cast(value); } -uint16_t SyrlinksHkHandler::convertHexStringToUint16(const char* fourChars) { +uint16_t SyrlinksHandler::convertHexStringToUint16(const char* fourChars) { uint16_t value = 0; value = convertHexStringToUint8(fourChars) << 8 | convertHexStringToUint8(fourChars + 2); return value; } -uint32_t SyrlinksHkHandler::convertHexStringToUint32(const char* characters, - uint8_t numberOfChars) { - uint32_t value = 0; - - switch (numberOfChars) { - case 6: - value = convertHexStringToUint8(characters) << 16 | - convertHexStringToUint8(characters + 2) << 8 | - convertHexStringToUint8(characters + 4); - return value; - case 8: - value = convertHexStringToUint8(characters) << 24 | - convertHexStringToUint8(characters + 2) << 16 | - convertHexStringToUint8(characters + 4) << 8 | - convertHexStringToUint8(characters + 4); - return value; - default: - sif::debug << "SyrlinksHkHandler::convertHexStringToUint32: Invalid number of characters. " - << "Must be either 6 or 8" << std::endl; - return 0; - } -} - -ReturnValue_t SyrlinksHkHandler::parseReplyStatus(const char* status) { +ReturnValue_t SyrlinksHandler::parseReplyStatus(const char* status) { switch (*status) { case '0': return returnvalue::OK; @@ -498,7 +512,7 @@ ReturnValue_t SyrlinksHkHandler::parseReplyStatus(const char* status) { } } -ReturnValue_t SyrlinksHkHandler::verifyReply(const uint8_t* packet, uint8_t size) { +ReturnValue_t SyrlinksHandler::verifyReply(const uint8_t* packet, uint8_t size) { int result = 0; /* Calculate crc from received packet */ uint16_t crc = @@ -518,28 +532,31 @@ ReturnValue_t SyrlinksHkHandler::verifyReply(const uint8_t* packet, uint8_t size return returnvalue::OK; } -void SyrlinksHkHandler::parseRxStatusRegistersReply(const uint8_t* packet) { +void SyrlinksHandler::parseRxStatusRegistersReply(const uint8_t* packet) { PoolReadGuard readHelper(&rxDataset); uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; rxDataset.rxStatus = convertHexStringToUint8(reinterpret_cast(packet + offset)); offset += 2; rxDataset.rxSensitivity = - convertHexStringToUint32(reinterpret_cast(packet + offset), 6); + convertHexStringTo32bit(reinterpret_cast(packet + offset), 6); offset += 6; rxDataset.rxFrequencyShift = - convertHexStringToUint32(reinterpret_cast(packet + offset), 6); + convertHexStringTo32bit(reinterpret_cast(packet + offset), 6); offset += 6; rxDataset.rxIqPower = convertHexStringToUint16(reinterpret_cast(packet + offset)); offset += 4; rxDataset.rxAgcValue = convertHexStringToUint16(reinterpret_cast(packet + offset)); offset += 4; offset += 2; // reserved register - rxDataset.rxDemodEb = convertHexStringToUint32(reinterpret_cast(packet + offset), 6); + rxDataset.rxDemodEb = + convertHexStringTo32bit(reinterpret_cast(packet + offset), 6); offset += 6; - rxDataset.rxDemodN0 = convertHexStringToUint32(reinterpret_cast(packet + offset), 6); + rxDataset.rxDemodN0 = + convertHexStringTo32bit(reinterpret_cast(packet + offset), 6); offset += 6; rxDataset.rxDataRate = convertHexStringToUint8(reinterpret_cast(packet + offset)); + rxDataset.setValidity(true, true); if (debugMode) { #if OBSW_VERBOSE_LEVEL >= 1 sif::info << "Syrlinks RX Status: 0x" << std::hex << (unsigned int)rxDataset.rxStatus.value @@ -555,7 +572,7 @@ void SyrlinksHkHandler::parseRxStatusRegistersReply(const uint8_t* packet) { } } -void SyrlinksHkHandler::parseLclConfigReply(const uint8_t* packet) { +void SyrlinksHandler::parseLclConfigReply(const uint8_t* packet) { uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; uint8_t lclConfig = convertHexStringToUint8(reinterpret_cast(packet + offset)); if (debugMode) { @@ -564,51 +581,54 @@ void SyrlinksHkHandler::parseLclConfigReply(const uint8_t* packet) { } } -void SyrlinksHkHandler::parseTxStatusReply(const uint8_t* packet) { +void SyrlinksHandler::parseTxStatusReply(const uint8_t* packet) { PoolReadGuard readHelper(&txDataset); uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; txDataset.txStatus = convertHexStringToUint8(reinterpret_cast(packet + offset)); + txDataset.txStatus.setValid(true); if (debugMode) { sif::info << "Syrlinks TX Status: 0x" << std::hex << (unsigned int)txDataset.txStatus.value << std::endl; } } -void SyrlinksHkHandler::parseTxWaveformReply(const uint8_t* packet) { +void SyrlinksHandler::parseTxWaveformReply(const uint8_t* packet) { PoolReadGuard readHelper(&txDataset); uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; txDataset.txWaveform = convertHexStringToUint8(reinterpret_cast(packet + offset)); + txDataset.txWaveform.setValid(true); if (debugMode) { sif::info << "Syrlinks TX Waveform: 0x" << std::hex << (unsigned int)txDataset.txWaveform.value << std::endl; } } -void SyrlinksHkHandler::parseAgcLowByte(const uint8_t* packet) { +void SyrlinksHandler::parseAgcLowByte(const uint8_t* packet) { PoolReadGuard readHelper(&txDataset); uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; txDataset.txAgcValue = agcValueHighByte << 8 | convertHexStringToUint8(reinterpret_cast(packet + offset)); + txDataset.txAgcValue.setValid(true); if (debugMode) { sif::info << "Syrlinks TX AGC Value: " << txDataset.txAgcValue << std::endl; } } -void SyrlinksHkHandler::parseAgcHighByte(const uint8_t* packet) { +void SyrlinksHandler::parseAgcHighByte(const uint8_t* packet) { PoolReadGuard readHelper(&txDataset); uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; agcValueHighByte = convertHexStringToUint8(reinterpret_cast(packet + offset)); } -void SyrlinksHkHandler::setNormalDatapoolEntriesInvalid() {} +void SyrlinksHandler::setNormalDatapoolEntriesInvalid() {} -uint32_t SyrlinksHkHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 500; } +uint32_t SyrlinksHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 2500; } -ReturnValue_t SyrlinksHkHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) { +ReturnValue_t SyrlinksHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) { localDataPoolMap.emplace(syrlinks::RX_STATUS, new PoolEntry({0})); localDataPoolMap.emplace(syrlinks::RX_SENSITIVITY, new PoolEntry({0})); - localDataPoolMap.emplace(syrlinks::RX_FREQUENCY_SHIFT, new PoolEntry({0})); + localDataPoolMap.emplace(syrlinks::RX_FREQUENCY_SHIFT, new PoolEntry({0})); localDataPoolMap.emplace(syrlinks::RX_IQ_POWER, new PoolEntry({0})); localDataPoolMap.emplace(syrlinks::RX_AGC_VALUE, new PoolEntry({0})); localDataPoolMap.emplace(syrlinks::RX_DEMOD_EB, new PoolEntry({0})); @@ -630,26 +650,162 @@ ReturnValue_t SyrlinksHkHandler::initializeLocalDataPool(localpool::DataPool& lo return returnvalue::OK; } -void SyrlinksHkHandler::setModeNormal() { setMode(MODE_NORMAL); } +void SyrlinksHandler::setModeNormal() { setMode(MODE_NORMAL); } -float SyrlinksHkHandler::calcTempVal(uint16_t raw) { return 0.126984 * raw - 67.87; } +float SyrlinksHandler::calcTempVal(uint16_t raw) { return 0.126984 * raw - 67.87; } -ReturnValue_t SyrlinksHkHandler::handleAckReply(const uint8_t* packet) { +ReturnValue_t SyrlinksHandler::handleAckReply(const uint8_t* packet) { ReturnValue_t result = parseReplyStatus(reinterpret_cast(packet + syrlinks::MESSAGE_HEADER_SIZE)); - if (rememberCommandId == syrlinks::WRITE_LCL_CONFIG and result != returnvalue::OK) { - startupState = StartupState::OFF; - } else if (rememberCommandId == syrlinks::WRITE_LCL_CONFIG and result == returnvalue::OK) { - startupState = StartupState::DONE; + switch (rememberCommandId) { + case (syrlinks::WRITE_LCL_CONFIG): { + if (isTransitionalMode()) { + if (result != returnvalue::OK) { + internalState = InternalState::OFF; + } else if (result == returnvalue::OK) { + commandExecuted = true; + } + } + break; + } + case (syrlinks::SET_WAVEFORM_BPSK): + case (syrlinks::SET_WAVEFORM_0QPSK): + case (syrlinks::SET_TX_MODE_STANDBY): + case (syrlinks::SET_TX_MODE_MODULATION): + case (syrlinks::SET_TX_MODE_CW): { + if (result == returnvalue::OK and isTransitionalMode()) { + commandExecuted = true; + } + break; + } + } + switch (rememberCommandId) { + case (syrlinks::SET_TX_MODE_STANDBY): { + triggerEvent(syrlinks::TX_OFF, 0, 0); + break; + } + case (syrlinks::SET_TX_MODE_MODULATION): + case (syrlinks::SET_TX_MODE_CW): { + triggerEvent(syrlinks::TX_ON, getSubmode(), static_cast(com::getCurrentDatarate())); + break; + } } return result; } -void SyrlinksHkHandler::prepareCommand(std::string command, DeviceCommandId_t commandId) { +ReturnValue_t SyrlinksHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) { + if (mode == HasModesIF::MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) { + if (submode >= com::Submode::NUM_SUBMODES) { + return HasModesIF::INVALID_SUBMODE; + } + return returnvalue::OK; + } + return DeviceHandlerBase::isModeCombinationValid(mode, submode); +} + +ReturnValue_t SyrlinksHandler::getParameter(uint8_t domainId, uint8_t uniqueId, + ParameterWrapper* parameterWrapper, + const ParameterWrapper* newValues, + uint16_t startAtIndex) { + return DeviceHandlerBase::getParameter(domainId, uniqueId, parameterWrapper, newValues, + startAtIndex); +} + +void SyrlinksHandler::prepareCommand(std::string command, DeviceCommandId_t commandId) { command.copy(reinterpret_cast(commandBuffer), command.size(), 0); rawPacketLen = command.size(); rememberCommandId = commandId; rawPacket = commandBuffer; } -void SyrlinksHkHandler::setDebugMode(bool enable) { this->debugMode = enable; } +void SyrlinksHandler::setDebugMode(bool enable) { this->debugMode = enable; } + +void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { + Mode_t tgtMode = getBaseMode(getMode()); + auto commandDone = [&]() { + setMode(tgtMode); + internalState = InternalState::IDLE; + }; + auto txOnHandler = [&](InternalState selMod) { + if (internalState == InternalState::IDLE) { + commandExecuted = false; + internalState = selMod; + } + // Select modulation first (BPSK or 0QPSK). + if (internalState == selMod) { + if (commandExecuted) { + internalState = InternalState::SET_TX_MODULATION; + commandExecuted = false; + } + } + // Now go into modulation mode. + if (internalState == InternalState::SET_TX_MODULATION) { + if (commandExecuted) { + commandDone(); + return true; + } + } + return false; + }; + auto txStandbyHandler = [&]() { + if (internalState == InternalState::IDLE) { + internalState = InternalState::SET_TX_STANDBY; + commandExecuted = false; + } + if (internalState == InternalState::SET_TX_STANDBY) { + if (commandExecuted) { + commandDone(); + return; + } + } + }; + if (tgtMode == HasModesIF::MODE_ON or tgtMode == DeviceHandlerIF::MODE_NORMAL) { + switch (getSubmode()) { + case (com::Submode::RX_AND_TX_DEFAULT_DATARATE): { + auto currentDatarate = com::getCurrentDatarate(); + if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) { + if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) { + return; + } + } else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) { + if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) { + return; + } + } + break; + } + case (com::Submode::RX_AND_TX_LOW_DATARATE): { + if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) { + return; + } + break; + } + case (com::Submode::RX_AND_TX_HIGH_DATARATE): { + if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) { + return; + } + break; + } + case (com::Submode::RX_ONLY): { + txStandbyHandler(); + return; + } + case (com::Submode::RX_AND_TX_CW): { + if (internalState == InternalState::IDLE) { + internalState = InternalState::SET_TX_STANDBY; + commandExecuted = false; + } + if (commandExecuted) { + commandDone(); + return; + } + break; + } + default: { + commandDone(); + } + } + } else if (tgtMode == HasModesIF::MODE_OFF) { + txStandbyHandler(); + } +} diff --git a/mission/devices/SyrlinksHkHandler.h b/mission/devices/SyrlinksHandler.h similarity index 77% rename from mission/devices/SyrlinksHkHandler.h rename to mission/devices/SyrlinksHandler.h index a3bf0a67..ea5c0336 100644 --- a/mission/devices/SyrlinksHkHandler.h +++ b/mission/devices/SyrlinksHandler.h @@ -1,5 +1,5 @@ -#ifndef MISSION_DEVICES_SYRLINKSHKHANDLER_H_ -#define MISSION_DEVICES_SYRLINKSHKHANDLER_H_ +#ifndef MISSION_DEVICES_SYRLINKSHANDLER_H_ +#define MISSION_DEVICES_SYRLINKSHANDLER_H_ #include @@ -7,6 +7,7 @@ #include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "fsfw/timemanager/Countdown.h" #include "fsfw_hal/linux/gpio/Gpio.h" +#include "mission/comDefs.h" #include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" #include "returnvalues/classIds.h" @@ -18,11 +19,11 @@ * * @author J. Meier */ -class SyrlinksHkHandler : public DeviceHandlerBase { +class SyrlinksHandler : public DeviceHandlerBase { public: - SyrlinksHkHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, - power::Switch_t powerSwitch, FailureIsolationBase* customFdir); - virtual ~SyrlinksHkHandler(); + SyrlinksHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, + power::Switch_t powerSwitch, FailureIsolationBase* customFdir); + virtual ~SyrlinksHandler(); /** * @brief Sets mode to MODE_NORMAL. Can be used for debugging. @@ -34,6 +35,8 @@ class SyrlinksHkHandler : public DeviceHandlerBase { protected: void doStartUp() override; void doShutDown() override; + void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; + ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override; ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override; ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData, @@ -49,6 +52,10 @@ class SyrlinksHkHandler : public DeviceHandlerBase { LocalDataPoolManager& poolManager) override; LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; + // Parameter IF + ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper, + const ParameterWrapper* newValues, uint16_t startAtIndex) override; + private: static const uint8_t INTERFACE_ID = CLASS_ID::SYRLINKS_HANDLER; @@ -104,12 +111,22 @@ class SyrlinksHkHandler : public DeviceHandlerBase { uint16_t rawTempBasebandBoard = 0; float tempPowerAmplifier = 0; float tempBasebandBoard = 0; + bool commandExecuted = false; uint8_t commandBuffer[syrlinks::MAX_COMMAND_SIZE]; - enum class StartupState { OFF, ENABLE_TEMPERATURE_PROTECTION, DONE }; + enum class InternalState { + OFF, + ENABLE_TEMPERATURE_PROTECTION, + SELECT_MODULATION_BPSK, + SELECT_MODULATION_0QPSK, + SET_TX_MODULATION, + SET_TX_CW, + SET_TX_STANDBY, + IDLE + }; - StartupState startupState = StartupState::OFF; + InternalState internalState = InternalState::OFF; /** * This object is used to store the id of the next command to execute. This controls the @@ -147,15 +164,16 @@ class SyrlinksHkHandler : public DeviceHandlerBase { uint16_t convertHexStringToUint16(const char* fourChars); /** - * @brief Function converts a hex number represented by 6 or 8 characters to an uint32_t. + * @brief Function converts a hex number represented by 6 or 8 characters to an uint32_t or + * int32_t, depending on the template parameter. * * @param characters Pointer to the hex characters array. * @param numberOfChars Number of characters representing the hex value. Must be 6 or 8. * - * @return The uint32_t value. + * @return The value. */ - uint32_t convertHexStringToUint32(const char* characters, uint8_t numberOfChars); - + template + T convertHexStringTo32bit(const char* characters, uint8_t numberOfChars); /** * @brief This function parses the status reply * @param status Pointer to the status information. @@ -214,4 +232,33 @@ class SyrlinksHkHandler : public DeviceHandlerBase { void prepareCommand(std::string command, DeviceCommandId_t commandId); }; -#endif /* MISSION_DEVICES_SYRLINKSHKHANDLER_H_ */ +template +T SyrlinksHandler::convertHexStringTo32bit(const char* characters, uint8_t numberOfChars) { + if (sizeof(T) < 4) { + sif::error << "SyrlinksHkHandler::convertHexStringToRaw: Only works for 32-bit conversion" + << std::endl; + } + T value = 0; + + switch (numberOfChars) { + case 6: + // The bitshift trickery required is necessary when creating an int32_t from a + // 24 bit signed value. + value = ((convertHexStringToUint8(characters) << 24) | + (convertHexStringToUint8(characters + 2) << 16) | + (convertHexStringToUint8(characters + 4) << 8)) >> + 8; + return value; + case 8: + value = convertHexStringToUint8(characters) << 24 | + convertHexStringToUint8(characters + 2) << 16 | + convertHexStringToUint8(characters + 4) << 8 | + convertHexStringToUint8(characters + 4); + return value; + default: + sif::debug << "SyrlinksHkHandler::convertHexStringToUint32: Invalid number of characters. " + << "Must be either 6 or 8" << std::endl; + return 0; + } +} +#endif /* MISSION_DEVICES_SYRLINKSHANDLER_H_ */ diff --git a/mission/devices/Tmp1075Handler.cpp b/mission/devices/Tmp1075Handler.cpp index 56e83ab7..def317e8 100644 --- a/mission/devices/Tmp1075Handler.cpp +++ b/mission/devices/Tmp1075Handler.cpp @@ -17,7 +17,10 @@ void Tmp1075Handler::doStartUp() { } } -void Tmp1075Handler::doShutDown() { setMode(_MODE_POWER_DOWN); } +void Tmp1075Handler::doShutDown() { + communicationStep = CommunicationStep::START_ADC_CONVERSION; + setMode(_MODE_POWER_DOWN); +} ReturnValue_t Tmp1075Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) { if (communicationStep == CommunicationStep::START_ADC_CONVERSION) { @@ -33,7 +36,7 @@ ReturnValue_t Tmp1075Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) { } ReturnValue_t Tmp1075Handler::buildTransitionDeviceCommand(DeviceCommandId_t *id) { - return returnvalue::OK; + return NOTHING_TO_SEND; } ReturnValue_t Tmp1075Handler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, diff --git a/mission/devices/devicedefinitions/GyroADIS1650XDefinitions.h b/mission/devices/devicedefinitions/GyroADIS1650XDefinitions.h index fb9e4d44..89a0c918 100644 --- a/mission/devices/devicedefinitions/GyroADIS1650XDefinitions.h +++ b/mission/devices/devicedefinitions/GyroADIS1650XDefinitions.h @@ -18,6 +18,11 @@ static constexpr double RANGE_UNSET = 0.0; static constexpr double RANGE_1BMLZ = 125.0; static constexpr double RANGE_2BMLZ = 500.0; static constexpr double RANGE_3BMLZ = 2000.0; +// Sensitivities in deg/s/LSB +static constexpr double SENSITIVITY_UNSET = 0.0; +static constexpr double SENSITIVITY_1BMLZ = 0.00625; +static constexpr double SENSITIVITY_2BMLZ = 0.025; +static constexpr double SENSITIVITY_3BMLZ = 0.1; enum RangMdlBitfield { RANGE_125_1BMLZ = 0b00, diff --git a/mission/devices/devicedefinitions/SyrlinksDefinitions.h b/mission/devices/devicedefinitions/SyrlinksDefinitions.h index 96ea1157..0e25501a 100644 --- a/mission/devices/devicedefinitions/SyrlinksDefinitions.h +++ b/mission/devices/devicedefinitions/SyrlinksDefinitions.h @@ -6,9 +6,15 @@ namespace syrlinks { +enum class ParameterId : uint8_t { DATARATE = 0 }; + static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYRLINKS; static constexpr Event FDIR_REACTION_IGNORED = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); +//! [EXPORT] : [COMMENT] Transmitter is on now. P1: Submode, P2: Current default datarate. +static constexpr Event TX_ON = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO); +//! [EXPORT] : [COMMENT] Transmitter is off now. +static constexpr Event TX_OFF = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO); static const DeviceCommandId_t NONE = 0; static const DeviceCommandId_t RESET_UNIT = 1; @@ -31,9 +37,9 @@ static const DeviceCommandId_t TEMP_POWER_AMPLIFIER_HIGH_BYTE = 13; static const DeviceCommandId_t TEMP_POWER_AMPLIFIER_LOW_BYTE = 14; static const DeviceCommandId_t TEMP_BASEBAND_BOARD_HIGH_BYTE = 15; static const DeviceCommandId_t TEMP_BASEBAND_BOARD_LOW_BYTE = 16; -static const DeviceCommandId_t CONFIG_OQPSK = 17; +static const DeviceCommandId_t SET_WAVEFORM_0QPSK = 17; // After startup syrlinks always in BSPK configuration -static const DeviceCommandId_t CONFIG_BPSK = 18; +static const DeviceCommandId_t SET_WAVEFORM_BPSK = 18; static const DeviceCommandId_t ENABLE_DEBUG = 20; static const DeviceCommandId_t DISABLE_DEBUG = 21; @@ -86,7 +92,7 @@ class RxDataset : public StaticLocalDataSet { lp_var_t rxStatus = lp_var_t(sid.objectId, RX_STATUS, this); lp_var_t rxSensitivity = lp_var_t(sid.objectId, RX_SENSITIVITY, this); - lp_var_t rxFrequencyShift = lp_var_t(sid.objectId, RX_FREQUENCY_SHIFT, this); + lp_var_t rxFrequencyShift = lp_var_t(sid.objectId, RX_FREQUENCY_SHIFT, this); lp_var_t rxIqPower = lp_var_t(sid.objectId, RX_IQ_POWER, this); lp_var_t rxAgcValue = lp_var_t(sid.objectId, RX_AGC_VALUE, this); lp_var_t rxDemodEb = lp_var_t(sid.objectId, RX_DEMOD_EB, this); diff --git a/mission/system/objects/ComSubsystem.cpp b/mission/system/objects/ComSubsystem.cpp index 794eede6..426e9c6c 100644 --- a/mission/system/objects/ComSubsystem.cpp +++ b/mission/system/objects/ComSubsystem.cpp @@ -1,5 +1,48 @@ #include "ComSubsystem.h" +#include + +#include "mission/config/comCfg.h" + ComSubsystem::ComSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables) - : Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) {} + : Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables), paramHelper(this) { + com::setCurrentDatarate(com::Datarate::LOW_RATE_MODULATION_BPSK); +} + +MessageQueueId_t ComSubsystem::getCommandQueue() const { return Subsystem::getCommandQueue(); } + +ReturnValue_t ComSubsystem::getParameter(uint8_t domainId, uint8_t uniqueIdentifier, + ParameterWrapper *parameterWrapper, + const ParameterWrapper *newValues, uint16_t startAtIndex) { + if ((domainId == 0) and (uniqueIdentifier == static_cast(com::ParameterId::DATARATE))) { + uint8_t newVal = 0; + ReturnValue_t result = newValues->getElement(&newVal); + if (result != returnvalue::OK) { + return result; + } + if (newVal >= static_cast(com::Datarate::NUM_DATARATES)) { + return HasParametersIF::INVALID_VALUE; + } + parameterWrapper->set(datarateCfg); + com::setCurrentDatarate(static_cast(newVal)); + return returnvalue::OK; + } + return returnvalue::OK; +} + +ReturnValue_t ComSubsystem::handleCommandMessage(CommandMessage *message) { + ReturnValue_t result = paramHelper.handleParameterMessage(message); + if (result == returnvalue::OK) { + return result; + } + return Subsystem::handleCommandMessage(message); +} + +ReturnValue_t ComSubsystem::initialize() { + ReturnValue_t result = paramHelper.initialize(); + if (result != returnvalue::OK) { + return result; + } + return Subsystem::initialize(); +} diff --git a/mission/system/objects/ComSubsystem.h b/mission/system/objects/ComSubsystem.h index 0bdaeb15..74f0c30e 100644 --- a/mission/system/objects/ComSubsystem.h +++ b/mission/system/objects/ComSubsystem.h @@ -1,13 +1,29 @@ #ifndef MISSION_SYSTEM_COMSUBSYSTEM_H_ #define MISSION_SYSTEM_COMSUBSYSTEM_H_ +#include +#include #include -class ComSubsystem : public Subsystem { +#include "mission/comDefs.h" + +class ComSubsystem : public Subsystem, public ReceivesParameterMessagesIF { public: ComSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables); + virtual ~ComSubsystem() = default; + + MessageQueueId_t getCommandQueue() const override; + ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier, + ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues, + uint16_t startAtIndex) override; private: + ReturnValue_t handleCommandMessage(CommandMessage *message) override; + + ReturnValue_t initialize() override; + + uint8_t datarateCfg = static_cast(com::Datarate::LOW_RATE_MODULATION_BPSK); + ParameterHelper paramHelper; }; #endif /* MISSION_SYSTEM_COMSUBSYSTEM_H_ */ diff --git a/mission/system/tree/CMakeLists.txt b/mission/system/tree/CMakeLists.txt index 6e7f1619..08d44e87 100644 --- a/mission/system/tree/CMakeLists.txt +++ b/mission/system/tree/CMakeLists.txt @@ -1,2 +1,4 @@ -target_sources(${LIB_EIVE_MISSION} PRIVATE acsModeTree.cpp payloadModeTree.cpp - system.cpp util.cpp) +target_sources( + ${LIB_EIVE_MISSION} + PRIVATE acsModeTree.cpp payloadModeTree.cpp comModeTree.cpp tcsModeTree.cpp + system.cpp util.cpp) diff --git a/mission/system/tree/acsModeTree.cpp b/mission/system/tree/acsModeTree.cpp index d91c59fc..8eaf36d9 100644 --- a/mission/system/tree/acsModeTree.cpp +++ b/mission/system/tree/acsModeTree.cpp @@ -16,12 +16,12 @@ namespace { // Alias for checker function const auto check = subsystem::checkInsert; -void buildOffSequence(Subsystem* ss, ModeListEntry& eh); -void buildDetumbleSequence(Subsystem* ss, ModeListEntry& entryHelper); -void buildSafeSequence(Subsystem* ss, ModeListEntry& entryHelper); -void buildIdleSequence(Subsystem* ss, ModeListEntry& entryHelper); -void buildIdleChargeSequence(Subsystem* ss, ModeListEntry& entryHelper); -void buildTargetPtSequence(Subsystem* ss, ModeListEntry& entryHelper); +void buildOffSequence(Subsystem& ss, ModeListEntry& eh); +void buildDetumbleSequence(Subsystem& ss, ModeListEntry& entryHelper); +void buildSafeSequence(Subsystem& ss, ModeListEntry& entryHelper); +void buildIdleSequence(Subsystem& ss, ModeListEntry& entryHelper); +void buildIdleChargeSequence(Subsystem& ss, ModeListEntry& entryHelper); +void buildTargetPtSequence(Subsystem& ss, ModeListEntry& entryHelper); } // namespace static const auto OFF = HasModesIF::MODE_OFF; @@ -81,18 +81,18 @@ auto ACS_TABLE_TARGET_PT_TRANS_1 = void satsystem::acs::init() { ModeListEntry entry; - buildOffSequence(&ACS_SUBSYSTEM, entry); - buildSafeSequence(&ACS_SUBSYSTEM, entry); - buildDetumbleSequence(&ACS_SUBSYSTEM, entry); - buildIdleSequence(&ACS_SUBSYSTEM, entry); - buildIdleChargeSequence(&ACS_SUBSYSTEM, entry); - buildTargetPtSequence(&ACS_SUBSYSTEM, entry); + buildOffSequence(ACS_SUBSYSTEM, entry); + buildSafeSequence(ACS_SUBSYSTEM, entry); + buildDetumbleSequence(ACS_SUBSYSTEM, entry); + buildIdleSequence(ACS_SUBSYSTEM, entry); + buildIdleChargeSequence(ACS_SUBSYSTEM, entry); + buildTargetPtSequence(ACS_SUBSYSTEM, entry); ACS_SUBSYSTEM.setInitialMode(HasModesIF::MODE_OFF); } namespace { -void buildOffSequence(Subsystem* ss, ModeListEntry& eh) { +void buildOffSequence(Subsystem& ss, ModeListEntry& eh) { std::string context = "satsystem::acs::buildOffSequence"; auto ctxc = context.c_str(); // Insert Helper Table @@ -112,7 +112,7 @@ void buildOffSequence(Subsystem* ss, ModeListEntry& eh) { }; // OFF Target table is empty - check(ss->addTable(&ACS_TABLE_OFF_TGT.second, ACS_TABLE_OFF_TGT.first, false, true), ctxc); + check(ss.addTable(&ACS_TABLE_OFF_TGT.second, ACS_TABLE_OFF_TGT.first, false, true), ctxc); // Build OFF transition iht(objects::ACS_CONTROLLER, OFF, 0, ACS_TABLE_OFF_TRANS.second); @@ -121,17 +121,17 @@ void buildOffSequence(Subsystem* ss, ModeListEntry& eh) { iht(objects::ACS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS.second); iht(objects::SUS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS.second); iht(objects::RW_ASS, OFF, 0, ACS_TABLE_OFF_TRANS.second); - check(ss->addTable(&ACS_TABLE_OFF_TRANS.second, ACS_TABLE_OFF_TRANS.first, false, true), ctxc); + check(ss.addTable(&ACS_TABLE_OFF_TRANS.second, ACS_TABLE_OFF_TRANS.first, false, true), ctxc); // Build OFF sequence ihs(ACS_SEQUENCE_OFF.second, ACS_TABLE_OFF_TGT.first, 0, false); ihs(ACS_SEQUENCE_OFF.second, ACS_TABLE_OFF_TRANS.first, 0, false); - check(ss->addSequence(&ACS_SEQUENCE_OFF.second, ACS_SEQUENCE_OFF.first, ACS_SEQUENCE_OFF.first, - false, true), + check(ss.addSequence(&ACS_SEQUENCE_OFF.second, ACS_SEQUENCE_OFF.first, ACS_SEQUENCE_OFF.first, + false, true), ctxc); } -void buildSafeSequence(Subsystem* ss, ModeListEntry& eh) { +void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) { std::string context = "satsystem::acs::buildSafeSequence"; auto ctxc = context.c_str(); // Insert Helper Table @@ -155,7 +155,7 @@ void buildSafeSequence(Subsystem* ss, ModeListEntry& eh) { iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_SAFE_TGT.second); iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TGT.second); iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TGT.second); - check(ss->addTable(&ACS_TABLE_SAFE_TGT.second, ACS_TABLE_SAFE_TGT.first, false, true), ctxc); + check(ss.addTable(&ACS_TABLE_SAFE_TGT.second, ACS_TABLE_SAFE_TGT.first, false, true), ctxc); // Build SAFE transition 0 iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_SAFE_TRANS_0.second); @@ -163,24 +163,24 @@ void buildSafeSequence(Subsystem* ss, ModeListEntry& eh) { iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TRANS_0.second); iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second); iht(objects::RW_ASS, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second); - check(ss->addTable(&ACS_TABLE_SAFE_TRANS_0.second, ACS_TABLE_SAFE_TRANS_0.first, false, true), + check(ss.addTable(&ACS_TABLE_SAFE_TRANS_0.second, ACS_TABLE_SAFE_TRANS_0.first, false, true), ctxc); // Build SAFE transition 1 iht(objects::ACS_CONTROLLER, acs::CtrlModes::SAFE, 0, ACS_TABLE_SAFE_TRANS_1.second); - check(ss->addTable(&ACS_TABLE_SAFE_TRANS_1.second, ACS_TABLE_SAFE_TRANS_1.first, false, true), + check(ss.addTable(&ACS_TABLE_SAFE_TRANS_1.second, ACS_TABLE_SAFE_TRANS_1.first, false, true), ctxc); // Build SAFE sequence ihs(ACS_SEQUENCE_SAFE.second, ACS_TABLE_SAFE_TGT.first, 0, true); ihs(ACS_SEQUENCE_SAFE.second, ACS_TABLE_SAFE_TRANS_0.first, 0, false); ihs(ACS_SEQUENCE_SAFE.second, ACS_TABLE_SAFE_TRANS_1.first, 0, false); - check(ss->addSequence(&ACS_SEQUENCE_SAFE.second, ACS_SEQUENCE_SAFE.first, ACS_SEQUENCE_SAFE.first, - false, true), + check(ss.addSequence(&ACS_SEQUENCE_SAFE.second, ACS_SEQUENCE_SAFE.first, ACS_SEQUENCE_SAFE.first, + false, true), ctxc); } -void buildDetumbleSequence(Subsystem* ss, ModeListEntry& eh) { +void buildDetumbleSequence(Subsystem& ss, ModeListEntry& eh) { std::string context = "satsystem::acs::buildDetumbleSequence"; auto ctxc = context.c_str(); // Insert Helper Table @@ -204,7 +204,7 @@ void buildDetumbleSequence(Subsystem* ss, ModeListEntry& eh) { iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_DETUMBLE_TGT.second); iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_DETUMBLE_TGT.second); iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_DETUMBLE_TGT.second); - check(ss->addTable(&ACS_TABLE_DETUMBLE_TGT.second, ACS_TABLE_DETUMBLE_TGT.first, false, true), + check(ss.addTable(&ACS_TABLE_DETUMBLE_TGT.second, ACS_TABLE_DETUMBLE_TGT.first, false, true), ctxc); // Build DETUMBLE transition 0 @@ -213,26 +213,26 @@ void buildDetumbleSequence(Subsystem* ss, ModeListEntry& eh) { iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_DETUMBLE_TRANS_0.second); iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_DETUMBLE_TRANS_0.second); iht(objects::RW_ASS, OFF, 0, ACS_TABLE_DETUMBLE_TRANS_0.second); - check(ss->addTable(&ACS_TABLE_DETUMBLE_TRANS_0.second, ACS_TABLE_DETUMBLE_TRANS_0.first, false, - true), + check(ss.addTable(&ACS_TABLE_DETUMBLE_TRANS_0.second, ACS_TABLE_DETUMBLE_TRANS_0.first, false, + true), ctxc); // Build DETUMBLE transition 1 iht(objects::ACS_CONTROLLER, acs::CtrlModes::DETUMBLE, 0, ACS_TABLE_DETUMBLE_TRANS_1.second); - check(ss->addTable(&ACS_TABLE_DETUMBLE_TRANS_1.second, ACS_TABLE_DETUMBLE_TRANS_1.first, false, - true), + check(ss.addTable(&ACS_TABLE_DETUMBLE_TRANS_1.second, ACS_TABLE_DETUMBLE_TRANS_1.first, false, + true), ctxc); // Build DETUMBLE sequence ihs(ACS_SEQUENCE_DETUMBLE.second, ACS_TABLE_DETUMBLE_TGT.first, 0, true); ihs(ACS_SEQUENCE_DETUMBLE.second, ACS_TABLE_DETUMBLE_TRANS_0.first, 0, false); ihs(ACS_SEQUENCE_DETUMBLE.second, ACS_TABLE_DETUMBLE_TRANS_1.first, 0, false); - check(ss->addSequence(&ACS_SEQUENCE_DETUMBLE.second, ACS_SEQUENCE_DETUMBLE.first, - ACS_SEQUENCE_SAFE.first, false, true), + check(ss.addSequence(&ACS_SEQUENCE_DETUMBLE.second, ACS_SEQUENCE_DETUMBLE.first, + ACS_SEQUENCE_SAFE.first, false, true), ctxc); } -void buildIdleSequence(Subsystem* ss, ModeListEntry& eh) { +void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) { std::string context = "satsystem::acs::buildIdleSequence"; auto ctxc = context.c_str(); // Insert Helper Table @@ -257,7 +257,7 @@ void buildIdleSequence(Subsystem* ss, ModeListEntry& eh) { iht(objects::RW_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second); iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second); iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second); - ss->addTable(&ACS_TABLE_IDLE_TGT.second, ACS_TABLE_IDLE_TGT.first, false, true); + ss.addTable(&ACS_TABLE_IDLE_TGT.second, ACS_TABLE_IDLE_TGT.first, false, true); // Build IDLE transition 0 iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); @@ -265,21 +265,21 @@ void buildIdleSequence(Subsystem* ss, ModeListEntry& eh) { iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); iht(objects::RW_ASS, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_IDLE_TRANS_0.second); - ss->addTable(&ACS_TABLE_IDLE_TRANS_0.second, ACS_TABLE_IDLE_TRANS_0.first, false, true); + ss.addTable(&ACS_TABLE_IDLE_TRANS_0.second, ACS_TABLE_IDLE_TRANS_0.first, false, true); // Build IDLE transition 1 iht(objects::ACS_CONTROLLER, acs::CtrlModes::IDLE, 0, ACS_TABLE_IDLE_TRANS_1.second); - ss->addTable(&ACS_TABLE_IDLE_TRANS_1.second, ACS_TABLE_IDLE_TRANS_1.first, false, true); + ss.addTable(&ACS_TABLE_IDLE_TRANS_1.second, ACS_TABLE_IDLE_TRANS_1.first, false, true); // Build IDLE sequence ihs(ACS_SEQUENCE_IDLE.second, ACS_TABLE_IDLE_TGT.first, 0, true); ihs(ACS_SEQUENCE_IDLE.second, ACS_TABLE_IDLE_TRANS_0.first, 0, true); ihs(ACS_SEQUENCE_IDLE.second, ACS_TABLE_IDLE_TRANS_1.first, 0, false); - ss->addSequence(&ACS_SEQUENCE_IDLE.second, ACS_SEQUENCE_IDLE.first, ACS_SEQUENCE_SAFE.first, - false, true); + ss.addSequence(&ACS_SEQUENCE_IDLE.second, ACS_SEQUENCE_IDLE.first, ACS_SEQUENCE_SAFE.first, false, + true); } -void buildIdleChargeSequence(Subsystem* ss, ModeListEntry& eh) { +void buildIdleChargeSequence(Subsystem& ss, ModeListEntry& eh) { std::string context = "satsystem::acs::buildIdleChargeSequence"; auto ctxc = context.c_str(); // Insert Helper Table @@ -304,7 +304,7 @@ void buildIdleChargeSequence(Subsystem* ss, ModeListEntry& eh) { iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_IDLE_CHRG_TGT.second); iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_CHRG_TGT.second); iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_CHRG_TGT.second); - check(ss->addTable(&ACS_TABLE_IDLE_CHRG_TGT.second, ACS_TABLE_IDLE_CHRG_TGT.first, false, true), + check(ss.addTable(&ACS_TABLE_IDLE_CHRG_TGT.second, ACS_TABLE_IDLE_CHRG_TGT.first, false, true), ctxc); // Build IDLE transition 0 @@ -313,27 +313,27 @@ void buildIdleChargeSequence(Subsystem* ss, ModeListEntry& eh) { iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_CHRG_TRANS_0.second); iht(objects::RW_ASS, OFF, 0, ACS_TABLE_IDLE_CHRG_TRANS_0.second); iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_IDLE_CHRG_TRANS_0.second); - check(ss->addTable(&ACS_TABLE_IDLE_CHRG_TRANS_0.second, ACS_TABLE_IDLE_CHRG_TRANS_0.first, false, - true), + check(ss.addTable(&ACS_TABLE_IDLE_CHRG_TRANS_0.second, ACS_TABLE_IDLE_CHRG_TRANS_0.first, false, + true), ctxc); // Build IDLE transition 1 iht(objects::ACS_CONTROLLER, acs::CtrlModes::IDLE, acs::IDLE_CHARGE, ACS_TABLE_IDLE_CHRG_TRANS_1.second); - check(ss->addTable(&ACS_TABLE_IDLE_CHRG_TRANS_1.second, ACS_TABLE_IDLE_CHRG_TRANS_1.first, false, - true), + check(ss.addTable(&ACS_TABLE_IDLE_CHRG_TRANS_1.second, ACS_TABLE_IDLE_CHRG_TRANS_1.first, false, + true), ctxc); // Build IDLE sequence ihs(ACS_SEQUENCE_IDLE_CHRG.second, ACS_TABLE_IDLE_CHRG_TGT.first, 0, true); ihs(ACS_SEQUENCE_IDLE_CHRG.second, ACS_TABLE_IDLE_CHRG_TRANS_0.first, 0, true); ihs(ACS_SEQUENCE_IDLE_CHRG.second, ACS_TABLE_IDLE_CHRG_TRANS_1.first, 0, false); - check(ss->addSequence(&ACS_SEQUENCE_IDLE_CHRG.second, ACS_SEQUENCE_IDLE_CHRG.first, - ACS_SEQUENCE_SAFE.first, false, true), + check(ss.addSequence(&ACS_SEQUENCE_IDLE_CHRG.second, ACS_SEQUENCE_IDLE_CHRG.first, + ACS_SEQUENCE_SAFE.first, false, true), ctxc); } -void buildTargetPtSequence(Subsystem* ss, ModeListEntry& eh) { +void buildTargetPtSequence(Subsystem& ss, ModeListEntry& eh) { std::string context = "satsystem::acs::buildTargetPtSequence"; auto ctxc = context.c_str(); // Insert Helper Table @@ -360,7 +360,7 @@ void buildTargetPtSequence(Subsystem* ss, ModeListEntry& eh) { iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_TARGET_PT_TGT.second); iht(objects::RW_ASS, NML, 0, ACS_TABLE_TARGET_PT_TGT.second); iht(objects::STAR_TRACKER, NML, 0, ACS_TABLE_TARGET_PT_TGT.second); - check(ss->addTable(&ACS_TABLE_TARGET_PT_TGT.second, ACS_TABLE_TARGET_PT_TGT.first, false, true), + check(ss.addTable(&ACS_TABLE_TARGET_PT_TGT.second, ACS_TABLE_TARGET_PT_TGT.first, false, true), ctxc); // Build TARGET PT transition 0 @@ -369,22 +369,22 @@ void buildTargetPtSequence(Subsystem* ss, ModeListEntry& eh) { iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_TARGET_PT_TRANS_0.second); iht(objects::RW_ASS, NML, 0, ACS_TABLE_TARGET_PT_TRANS_0.second); iht(objects::STAR_TRACKER, NML, 0, ACS_TABLE_TARGET_PT_TRANS_0.second); - check(ss->addTable(&ACS_TABLE_TARGET_PT_TRANS_0.second, ACS_TABLE_TARGET_PT_TRANS_0.first, false, - true), + check(ss.addTable(&ACS_TABLE_TARGET_PT_TRANS_0.second, ACS_TABLE_TARGET_PT_TRANS_0.first, false, + true), ctxc); // Build TARGET PT transition 1 iht(objects::ACS_CONTROLLER, acs::CtrlModes::TARGET_PT, 0, ACS_TABLE_TARGET_PT_TRANS_1.second); - check(ss->addTable(&ACS_TABLE_TARGET_PT_TRANS_1.second, ACS_TABLE_TARGET_PT_TRANS_1.first, false, - true), + check(ss.addTable(&ACS_TABLE_TARGET_PT_TRANS_1.second, ACS_TABLE_TARGET_PT_TRANS_1.first, false, + true), ctxc); // Build IDLE sequence ihs(ACS_SEQUENCE_TARGET_PT.second, ACS_TABLE_TARGET_PT_TGT.first, 0, true); ihs(ACS_SEQUENCE_TARGET_PT.second, ACS_TABLE_TARGET_PT_TRANS_0.first, 0, true); ihs(ACS_SEQUENCE_TARGET_PT.second, ACS_TABLE_TARGET_PT_TRANS_1.first, 0, false); - check(ss->addSequence(&ACS_SEQUENCE_TARGET_PT.second, ACS_SEQUENCE_TARGET_PT.first, - ACS_SEQUENCE_IDLE.first, false, true), + check(ss.addSequence(&ACS_SEQUENCE_TARGET_PT.second, ACS_SEQUENCE_TARGET_PT.first, + ACS_SEQUENCE_IDLE.first, false, true), ctxc); } diff --git a/mission/system/tree/comModeTree.cpp b/mission/system/tree/comModeTree.cpp new file mode 100644 index 00000000..e08ba5ba --- /dev/null +++ b/mission/system/tree/comModeTree.cpp @@ -0,0 +1,281 @@ +#include "comModeTree.h" + +#include +#include +#include +#include + +#include "eive/objects.h" +#include "mission/comDefs.h" +#include "util.h" + +const auto check = subsystem::checkInsert; + +ComSubsystem satsystem::com::SUBSYSTEM = ComSubsystem(objects::COM_SUBSYSTEM, 12, 24); + +static const auto OFF = HasModesIF::MODE_OFF; +static const auto ON = HasModesIF::MODE_ON; +static const auto NML = DeviceHandlerIF::MODE_NORMAL; + +auto COM_SEQUENCE_RX_ONLY = + std::make_pair(::com::Submode::RX_ONLY, FixedArrayList()); +auto COM_TABLE_RX_ONLY_TGT = + std::make_pair((::com::Submode::RX_ONLY << 24) | 1, FixedArrayList()); +auto COM_TABLE_RX_ONLY_TRANS_0 = + std::make_pair((::com::Submode::RX_ONLY << 24) | 2, FixedArrayList()); +auto COM_TABLE_RX_ONLY_TRANS_1 = + std::make_pair((::com::Submode::RX_ONLY << 24) | 3, FixedArrayList()); + +auto COM_SEQUENCE_RX_AND_TX_LOW_RATE = + std::make_pair(::com::Submode::RX_AND_TX_LOW_DATARATE, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_LOW_RATE_TGT = std::make_pair( + (::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 1, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0 = std::make_pair( + (::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 2, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1 = std::make_pair( + (::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 3, FixedArrayList()); + +auto COM_SEQUENCE_RX_AND_TX_HIGH_RATE = + std::make_pair(::com::Submode::RX_AND_TX_HIGH_DATARATE, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_HIGH_RATE_TGT = std::make_pair( + (::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 1, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0 = std::make_pair( + (::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 2, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1 = std::make_pair( + (::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 3, FixedArrayList()); + +auto COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE = + std::make_pair(::com::Submode::RX_AND_TX_DEFAULT_DATARATE, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT = std::make_pair( + (::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 1, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0 = std::make_pair( + (::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 2, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1 = std::make_pair( + (::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 3, FixedArrayList()); + +namespace { + +void buildRxOnlySequence(Subsystem& ss, ModeListEntry& eh); +void buildTxAndRxLowRateSequence(Subsystem& ss, ModeListEntry& eh); +void buildTxAndRxHighRateSequence(Subsystem& ss, ModeListEntry& eh); +void buildTxAndRxDefaultRateSequence(Subsystem& ss, ModeListEntry& eh); + +} // namespace + +void satsystem::com::init() { + ModeListEntry entry; + buildRxOnlySequence(SUBSYSTEM, entry); + buildTxAndRxLowRateSequence(SUBSYSTEM, entry); + buildTxAndRxHighRateSequence(SUBSYSTEM, entry); + buildTxAndRxDefaultRateSequence(SUBSYSTEM, entry); + SUBSYSTEM.setInitialMode(NML, ::com::Submode::RX_ONLY); +} + +namespace { + +void buildRxOnlySequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::com::buildRxOnlySequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(table.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // Build RX Only table. We could track the state of the CCSDS IP core handler + // as well but I do not think this is necessary because enabling that should + // not intefere with the Syrlinks Handler. + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_ONLY, COM_TABLE_RX_ONLY_TGT.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TGT.first, &COM_TABLE_RX_ONLY_TGT.second)), ctxc); + + // Build RX Only transition 0 + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_ONLY, COM_TABLE_RX_ONLY_TRANS_0.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TRANS_0.first, &COM_TABLE_RX_ONLY_TRANS_0.second)), + ctxc); + + // Build RX Only transition 1 + iht(objects::CCSDS_HANDLER, OFF, 0, COM_TABLE_RX_ONLY_TRANS_1.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TRANS_1.first, &COM_TABLE_RX_ONLY_TRANS_1.second)), + ctxc); + + // Build TX OFF sequence + ihs(COM_SEQUENCE_RX_ONLY.second, COM_TABLE_RX_ONLY_TGT.first, 0, true); + ihs(COM_SEQUENCE_RX_ONLY.second, COM_TABLE_RX_ONLY_TRANS_0.first, 0, false); + ihs(COM_SEQUENCE_RX_ONLY.second, COM_TABLE_RX_ONLY_TRANS_1.first, 0, false); + check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_ONLY.first, &COM_SEQUENCE_RX_ONLY.second, + COM_SEQUENCE_RX_ONLY.first)), + ctxc); +} + +void buildTxAndRxLowRateSequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::com::buildTxAndRxLowRateSequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(table.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // Build RX and TX low datarate table. + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_LOW_DATARATE, + COM_TABLE_RX_AND_TX_LOW_RATE_TGT.second); + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_LOW), + COM_TABLE_RX_AND_TX_LOW_RATE_TGT.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TGT.first, + &COM_TABLE_RX_AND_TX_LOW_RATE_TGT.second)), + ctxc); + + // Build TX and RX low datarate transition 0, switch CCSDS handler first + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_LOW), + COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.first, + &COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.second)), + ctxc); + + // Build TX and RX low transition 1 + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_LOW_DATARATE, + COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.first, + &COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second)), + ctxc); + + // Build TX and RX low datarate sequence + ihs(COM_SEQUENCE_RX_AND_TX_LOW_RATE.second, COM_TABLE_RX_AND_TX_LOW_RATE_TGT.first, 0, true); + ihs(COM_SEQUENCE_RX_AND_TX_LOW_RATE.second, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.first, 0, false); + ihs(COM_SEQUENCE_RX_AND_TX_LOW_RATE.second, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.first, 0, false); + check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_AND_TX_LOW_RATE.first, + &COM_SEQUENCE_RX_AND_TX_LOW_RATE.second, + COM_SEQUENCE_RX_ONLY.first)), + ctxc); +} + +void buildTxAndRxHighRateSequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::com::buildTxAndRxHighRateSequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(table.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // Build RX and TX high datarate table. + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_HIGH_DATARATE, + COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.second); + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_HIGH), + COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.first, + &COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.second)), + ctxc); + + // Build TX and RX high datarate transition 0, switch CCSDS handler first + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_HIGH), + COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.first, + &COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.second)), + ctxc); + + // Build TX and RX high transition 1 + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_HIGH_DATARATE, + COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.first, + &COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second)), + ctxc); + + // Build TX and RX low datarate sequence + ihs(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second, COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.first, 0, true); + ihs(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.first, 0, + false); + ihs(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.first, 0, + false); + check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.first, + &COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second, + COM_SEQUENCE_RX_ONLY.first)), + ctxc); +} + +void buildTxAndRxDefaultRateSequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::com::buildTxAndRxDefaultRateSequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(table.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // Build RX and TX default datarate table. + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_DEFAULT_DATARATE, + COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.second); + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_DEFAULT), + COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.first, + &COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.second)), + ctxc); + + // Build TX and RX low datarate transition 0, switch CCSDS handler first + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_DEFAULT), + COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.first, + &COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.second)), + ctxc); + + // Build TX and RX default transition 1 + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_DEFAULT_DATARATE, + COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.first, + &COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second)), + ctxc); + + // Build TX and RX default datarate sequence + ihs(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.first, 0, + true); + ihs(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.first, 0, + false); + ihs(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.first, 0, + false); + check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.first, + &COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second, + COM_SEQUENCE_RX_ONLY.first)), + ctxc); +} + +} // namespace diff --git a/mission/system/tree/comModeTree.h b/mission/system/tree/comModeTree.h new file mode 100644 index 00000000..ccc7f15f --- /dev/null +++ b/mission/system/tree/comModeTree.h @@ -0,0 +1,16 @@ +#ifndef MISSION_SYSTEM_TREE_COMMODETREE_H_ +#define MISSION_SYSTEM_TREE_COMMODETREE_H_ + +#include + +namespace satsystem { + +namespace com { +extern ComSubsystem SUBSYSTEM; + +void init(); +} // namespace com + +} // namespace satsystem + +#endif /* MISSION_SYSTEM_TREE_COMMODETREE_H_ */ diff --git a/mission/system/tree/system.cpp b/mission/system/tree/system.cpp index 4455588f..bf6cea9d 100644 --- a/mission/system/tree/system.cpp +++ b/mission/system/tree/system.cpp @@ -1,9 +1,13 @@ #include "system.h" #include "acsModeTree.h" +#include "comModeTree.h" #include "payloadModeTree.h" +#include "tcsModeTree.h" void satsystem::init() { acs::init(); pl::init(); + tcs::init(); + com::init(); } diff --git a/mission/system/tree/tcsModeTree.cpp b/mission/system/tree/tcsModeTree.cpp new file mode 100644 index 00000000..51b0ec79 --- /dev/null +++ b/mission/system/tree/tcsModeTree.cpp @@ -0,0 +1,125 @@ +#include "tcsModeTree.h" + +#include "eive/objects.h" +#include "fsfw/devicehandlers/DeviceHandlerIF.h" +#include "fsfw/subsystem/Subsystem.h" +#include "mission/system/tree/util.h" + +Subsystem satsystem::tcs::SUBSYSTEM(objects::TCS_SUBSYSTEM, 12, 24); + +namespace { +// Alias for checker function +const auto check = subsystem::checkInsert; +void buildOffSequence(Subsystem& ss, ModeListEntry& eh); +void buildNormalSequence(Subsystem& ss, ModeListEntry& eh); +} // namespace + +static const auto OFF = HasModesIF::MODE_OFF; +static const auto NML = DeviceHandlerIF::MODE_NORMAL; + +auto TCS_SEQUENCE_OFF = std::make_pair(OFF, FixedArrayList()); +auto TCS_TABLE_OFF_TGT = std::make_pair((OFF << 24) | 1, FixedArrayList()); +auto TCS_TABLE_OFF_TRANS_0 = std::make_pair((OFF << 24) | 2, FixedArrayList()); +auto TCS_TABLE_OFF_TRANS_1 = std::make_pair((OFF << 24) | 3, FixedArrayList()); + +auto TCS_SEQUENCE_NORMAL = std::make_pair(NML, FixedArrayList()); +auto TCS_TABLE_NORMAL_TGT = std::make_pair((NML << 24) | 1, FixedArrayList()); +auto TCS_TABLE_NORMAL_TRANS_0 = std::make_pair((NML << 24) | 2, FixedArrayList()); +auto TCS_TABLE_NORMAL_TRANS_1 = std::make_pair((NML << 24) | 3, FixedArrayList()); + +void satsystem::tcs::init() { + ModeListEntry entry; + buildOffSequence(SUBSYSTEM, entry); + buildNormalSequence(SUBSYSTEM, entry); + SUBSYSTEM.setInitialMode(OFF); +} + +namespace { + +void buildOffSequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::tcs::buildOffSequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(table.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // OFF target table is empty + check(ss.addTable(TableEntry(TCS_TABLE_OFF_TGT.first, &TCS_TABLE_OFF_TGT.second)), ctxc); + + iht(objects::TCS_BOARD_ASS, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); + iht(objects::TMP1075_HANDLER_TCS_0, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); + iht(objects::TMP1075_HANDLER_TCS_1, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); + iht(objects::TMP1075_HANDLER_PLPCDU_0, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); + // damaged + // iht(objects::TMP1075_HANDLER_PLPCDU_1, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); + iht(objects::TMP1075_HANDLER_IF_BOARD, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); + check(ss.addTable(TableEntry(TCS_TABLE_OFF_TRANS_0.first, &TCS_TABLE_OFF_TRANS_0.second)), ctxc); + + iht(objects::THERMAL_CONTROLLER, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); + check(ss.addTable(TableEntry(TCS_TABLE_OFF_TRANS_1.first, &TCS_TABLE_OFF_TRANS_1.second)), ctxc); + + ihs(TCS_SEQUENCE_OFF.second, TCS_TABLE_OFF_TGT.first, 0, false); + ihs(TCS_SEQUENCE_OFF.second, TCS_TABLE_OFF_TRANS_0.first, 0, false); + ihs(TCS_SEQUENCE_OFF.second, TCS_TABLE_OFF_TRANS_1.first, 0, false); + check(ss.addSequence(SequenceEntry(TCS_SEQUENCE_OFF.first, &TCS_SEQUENCE_OFF.second, + TCS_SEQUENCE_OFF.first)), + ctxc); +} + +void buildNormalSequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::tcs::buildNormalSequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(table.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // OFF target table is empty + check(ss.addTable(TableEntry(TCS_TABLE_NORMAL_TGT.first, &TCS_TABLE_NORMAL_TGT.second)), ctxc); + + iht(objects::TCS_BOARD_ASS, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); + iht(objects::TMP1075_HANDLER_TCS_0, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); + iht(objects::TMP1075_HANDLER_TCS_1, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); + iht(objects::TMP1075_HANDLER_PLPCDU_0, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); + // damaged + // iht(objects::TMP1075_HANDLER_PLPCDU_1, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); + iht(objects::TMP1075_HANDLER_IF_BOARD, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); + check(ss.addTable(TableEntry(TCS_TABLE_NORMAL_TRANS_0.first, &TCS_TABLE_NORMAL_TRANS_0.second)), + ctxc); + + iht(objects::THERMAL_CONTROLLER, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); + check(ss.addTable(TableEntry(TCS_TABLE_NORMAL_TRANS_1.first, &TCS_TABLE_NORMAL_TRANS_1.second)), + ctxc); + + ihs(TCS_SEQUENCE_NORMAL.second, TCS_TABLE_NORMAL_TGT.first, 0, false); + ihs(TCS_SEQUENCE_NORMAL.second, TCS_TABLE_NORMAL_TRANS_0.first, 0, false); + ihs(TCS_SEQUENCE_NORMAL.second, TCS_TABLE_NORMAL_TRANS_1.first, 0, false); + check(ss.addSequence(SequenceEntry(TCS_SEQUENCE_NORMAL.first, &TCS_SEQUENCE_NORMAL.second, + TCS_SEQUENCE_NORMAL.first)), + ctxc); +} + +} // namespace diff --git a/mission/system/tree/tcsModeTree.h b/mission/system/tree/tcsModeTree.h new file mode 100644 index 00000000..f223e87b --- /dev/null +++ b/mission/system/tree/tcsModeTree.h @@ -0,0 +1,15 @@ +#ifndef MISSION_SYSTEM_TREE_TCSMODETREE_H_ +#define MISSION_SYSTEM_TREE_TCSMODETREE_H_ + +class Subsystem; + +namespace satsystem { +namespace tcs { + +extern Subsystem SUBSYSTEM; +void init(); + +} // namespace tcs +} // namespace satsystem + +#endif /* MISSION_SYSTEM_TREE_TCSMODETREE_H_ */ diff --git a/mission/tmtc/CcsdsIpCoreHandler.cpp b/mission/tmtc/CcsdsIpCoreHandler.cpp index c65a12a8..85d1143b 100644 --- a/mission/tmtc/CcsdsIpCoreHandler.cpp +++ b/mission/tmtc/CcsdsIpCoreHandler.cpp @@ -1,8 +1,11 @@ #include "CcsdsIpCoreHandler.h" +#include #include #include +#include +#include "eive/definitions.h" #include "fsfw/events/EventManagerIF.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/objectmanager/ObjectManager.h" @@ -20,6 +23,7 @@ CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t ptmeId, tcDestination(tcDestination), parameterHelper(this), actionHelper(this, nullptr), + modeHelper(this), ptmeConfig(ptmeConfig), gpioIF(gpioIF), enTxClock(enTxClock), @@ -80,6 +84,11 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() { return result; } + result = modeHelper.initialize(); + if (result != returnvalue::OK) { + return result; + } + VirtualChannelMapIter iter; for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) { result = iter->second->initialize(); @@ -126,10 +135,12 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } + transmitterCountdown.setTimeout(transmitterTimeout); + transmitterCountdown.timeOut(); + #if OBSW_SYRLINKS_SIMULATED == 1 // Update data on rising edge ptmeConfig->invertTxClock(false); - transmitterCountdown.setTimeout(transmitterTimeout); linkState = UP; forwardLinkstate(); #endif /* OBSW_SYRLINKS_SIMULATED == 1*/ @@ -151,6 +162,10 @@ void CcsdsIpCoreHandler::readCommandQueue(void) { if (result == returnvalue::OK) { return; } + result = modeHelper.handleModeCommand(&commandMessage); + if (result == returnvalue::OK) { + return; + } CommandMessage reply; reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand()); commandQueue->reply(&reply); @@ -161,7 +176,7 @@ void CcsdsIpCoreHandler::readCommandQueue(void) { MessageQueueId_t CcsdsIpCoreHandler::getCommandQueue() const { return commandQueue->getId(); } void CcsdsIpCoreHandler::addVirtualChannel(VcId_t vcId, VirtualChannel* virtualChannel) { - if (vcId > common::NUMBER_OF_VIRTUAL_CHANNELS) { + if (vcId > config::NUMBER_OF_VIRTUAL_CHANNELS) { sif::warning << "CcsdsHandler::addVirtualChannel: Invalid virtual channel ID" << std::endl; return; } @@ -182,7 +197,7 @@ void CcsdsIpCoreHandler::addVirtualChannel(VcId_t vcId, VirtualChannel* virtualC } MessageQueueId_t CcsdsIpCoreHandler::getReportReceptionQueue(uint8_t virtualChannel) const { - if (virtualChannel < common::NUMBER_OF_VIRTUAL_CHANNELS) { + if (virtualChannel < config::NUMBER_OF_VIRTUAL_CHANNELS) { auto iter = virtualChannelMap.find(virtualChannel); if (iter != virtualChannelMap.end()) { return iter->second->getReportReceptionQueue(); @@ -217,10 +232,12 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu ReturnValue_t result = returnvalue::OK; switch (actionId) { case SET_LOW_RATE: { + submode = static_cast(com::CcsdsSubmode::DATARATE_LOW); result = ptmeConfig->setRate(RATE_100KBPS); break; } case SET_HIGH_RATE: { + submode = static_cast(com::CcsdsSubmode::DATARATE_HIGH); result = ptmeConfig->setRate(RATE_500KBPS); break; } @@ -232,10 +249,16 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu } case EN_TRANSMITTER: { enableTransmit(); + if (mode == HasModesIF::MODE_OFF) { + mode = HasModesIF::MODE_ON; + } return EXECUTION_FINISHED; } case DISABLE_TRANSMITTER: { disableTransmit(); + if (mode == HasModesIF::MODE_ON) { + mode = HasModesIF::MODE_OFF; + } return EXECUTION_FINISHED; } case ENABLE_TX_CLK_MANIPULATOR: { @@ -327,6 +350,9 @@ void CcsdsIpCoreHandler::enableTransmit() { gpioIF->pullHigh(enTxClock); gpioIF->pullHigh(enTxData); #endif + linkState = UP; + forwardLinkstate(); + transmitterCountdown.resetTimer(); } void CcsdsIpCoreHandler::checkTxTimer() { @@ -335,9 +361,69 @@ void CcsdsIpCoreHandler::checkTxTimer() { } if (transmitterCountdown.hasTimedOut()) { disableTransmit(); + //TODO: set mode to off (move timer to subsystem) } } +void CcsdsIpCoreHandler::getMode(Mode_t* mode, Submode_t* submode) { + *mode = this->mode; + *submode = this->submode; +} + +ReturnValue_t CcsdsIpCoreHandler::checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t* msToReachTheMode) { + if (mode == HasModesIF::MODE_ON) { + if (submode != static_cast(com::CcsdsSubmode::DATARATE_HIGH) and + submode != static_cast(com::CcsdsSubmode::DATARATE_LOW) and + submode != static_cast(com::CcsdsSubmode::DATARATE_DEFAULT)) { + return HasModesIF::INVALID_SUBMODE; + } + } else if (mode != HasModesIF::MODE_OFF) { + return returnvalue::FAILED; + } + *msToReachTheMode = 2000; + return returnvalue::OK; +} + +void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) { + auto rateHigh = [&]() { + ReturnValue_t result = ptmeConfig->setRate(RATE_500KBPS); + if (result == returnvalue::OK) { + this->mode = HasModesIF::MODE_ON; + } + }; + auto rateLow = [&]() { + ReturnValue_t result = ptmeConfig->setRate(RATE_100KBPS); + if (result == returnvalue::OK) { + this->mode = HasModesIF::MODE_ON; + } + }; + if (mode == HasModesIF::MODE_ON) { + enableTransmit(); + if (submode == static_cast(com::CcsdsSubmode::DATARATE_DEFAULT)) { + com::Datarate currentDatarate = com::getCurrentDatarate(); + if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) { + rateLow(); + } else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) { + rateHigh(); + } + } else if (submode == static_cast(com::CcsdsSubmode::DATARATE_HIGH)) { + rateHigh(); + } else if (submode == static_cast(com::CcsdsSubmode::DATARATE_LOW)) { + rateLow(); + } + + } else if (mode == HasModesIF::MODE_OFF) { + disableTransmit(); + this->mode = HasModesIF::MODE_OFF; + } + this->submode = submode; + modeHelper.modeChanged(mode, submode); + announceMode(false); +} + +void CcsdsIpCoreHandler::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); } + void CcsdsIpCoreHandler::disableTransmit() { #ifndef TE0720_1CFA gpioIF->pullLow(enTxClock); @@ -345,7 +431,19 @@ void CcsdsIpCoreHandler::disableTransmit() { #endif linkState = DOWN; forwardLinkstate(); - transmitterCountdown.setTimeout(0); + transmitterCountdown.timeOut(); } const char* CcsdsIpCoreHandler::getName() const { return "CCSDS Handler"; } + +const HasHealthIF* CcsdsIpCoreHandler::getOptHealthIF() const { return nullptr; } + +const HasModesIF& CcsdsIpCoreHandler::getModeIF() const { return *this; } + +ReturnValue_t CcsdsIpCoreHandler::connectModeTreeParent(HasModeTreeChildrenIF& parent) { + return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper); +} + +ModeTreeChildIF& CcsdsIpCoreHandler::getModeTreeChildIF() { return *this; } + +object_id_t CcsdsIpCoreHandler::getObjectId() const { return SystemObject::getObjectId(); } diff --git a/mission/tmtc/CcsdsIpCoreHandler.h b/mission/tmtc/CcsdsIpCoreHandler.h index 942b73cb..37212851 100644 --- a/mission/tmtc/CcsdsIpCoreHandler.h +++ b/mission/tmtc/CcsdsIpCoreHandler.h @@ -1,16 +1,21 @@ #ifndef CCSDSHANDLER_H_ #define CCSDSHANDLER_H_ +#include + +#include #include #include "OBSWConfig.h" #include "VirtualChannel.h" +#include "eive/definitions.h" #include "fsfw/action/ActionHelper.h" #include "fsfw/action/HasActionsIF.h" #include "fsfw/events/EventMessage.h" #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/parameters/ParameterHelper.h" #include "fsfw/returnvalues/returnvalue.h" +#include "fsfw/subsystem/ModeTreeConnectionIF.h" #include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/timemanager/Countdown.h" #include "fsfw/tmtcservices/AcceptsTelecommandsIF.h" @@ -18,6 +23,7 @@ #include "fsfw_hal/common/gpio/GpioIF.h" #include "fsfw_hal/common/gpio/gpioDefinitions.h" #include "linux/ipcore/PtmeConfig.h" +#include "mission/comDefs.h" /** * @brief This class handles the data exchange with the CCSDS IP cores implemented in the @@ -30,6 +36,9 @@ */ class CcsdsIpCoreHandler : public SystemObject, public ExecutableObjectIF, + public ModeTreeChildIF, + public ModeTreeConnectionIF, + public HasModesIF, public AcceptsTelemetryIF, public AcceptsTelecommandsIF, public ReceivesParameterMessagesIF, @@ -57,7 +66,14 @@ class CcsdsIpCoreHandler : public SystemObject, ReturnValue_t performOperation(uint8_t operationCode = 0) override; ReturnValue_t initialize(); - MessageQueueId_t getCommandQueue() const; + MessageQueueId_t getCommandQueue() const override; + + // ModesIF + void getMode(Mode_t* mode, Submode_t* submode) override; + ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t* msToReachTheMode) override; + void startTransition(Mode_t mode, Submode_t submode) override; + void announceMode(bool recursive) override; /** * @brief Function to add a virtual channel @@ -78,12 +94,17 @@ class CcsdsIpCoreHandler : public SystemObject, virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size); + const HasHealthIF* getOptHealthIF() const override; + const HasModesIF& getModeIF() const override; + object_id_t getObjectId() const override; + ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; + ModeTreeChildIF& getModeTreeChildIF() override; private: static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_HANDLER; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HANDLER; - static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE; + static const uint32_t QUEUE_SIZE = config::CCSDS_HANDLER_QUEUE_SIZE; static const ActionId_t SET_LOW_RATE = 0; static const ActionId_t SET_HIGH_RATE = 1; @@ -124,6 +145,9 @@ class CcsdsIpCoreHandler : public SystemObject, ParameterHelper parameterHelper; ActionHelper actionHelper; + Mode_t mode = HasModesIF::MODE_OFF; + Submode_t submode = static_cast(com::CcsdsSubmode::UNSET); + ModeHelper modeHelper; MessageQueueId_t tcDistributorQueueId = MessageQueueIF::NO_QUEUE; diff --git a/scripts/q7s-port-em.sh b/scripts/q7s-port-em.sh new file mode 100755 index 00000000..e697063f --- /dev/null +++ b/scripts/q7s-port-em.sh @@ -0,0 +1,11 @@ +#!/bin/bash +echo "Setting up all Q7S ports for EM" +echo "-L 1538:192.168.133.10:1534 for connection to the TCF agent on the EM" +echo "-L 1539:192.168.133.10:22 for file transfers to the EM" +echo "-L 1540:192.168.133.10:7301 for TMTC commanding using the TCP/IP IF on the EM" + +ssh -L 1538:192.168.133.10:1534 \ + -L 1539:192.168.133.10:22 \ + -L 1540:192.168.133.10:7301 \ + eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ + -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' diff --git a/tmtc b/tmtc index f3c0b756..c633893d 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit f3c0b7567aec22db02a07d76548617b8d163fb29 +Subproject commit c633893df43030bb26b8422604b569bf8419d454