diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index 8905a125..e68a1f19 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -16,6 +16,10 @@ static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ttyUL8"; static constexpr char UART_GNSS_0_DEV[] = "/dev/ttyUL0"; static constexpr char UART_GNSS_1_DEV[] = "/dev/ttyUL2"; +static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio0"; +static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio2"; +static constexpr char UIO_PDEC_RAM[] = "/dev/uio3"; + namespace gpioNames { static constexpr char GYRO_0_ADIS_CS[] = "gyro_0_adis_chip_select"; static constexpr char GYRO_1_L3G_CS[] = "gyro_1_l3g_chip_select"; @@ -62,6 +66,7 @@ namespace gpioNames { static constexpr char PAPB_EMPTY_SIGNAL_VC3[] = "papb_empty_signal_vc3"; static constexpr char RS485_EN_TX_CLOCK[] = "tx_clock_enable_ltc2872"; static constexpr char RS485_EN_TX_DATA[] = "tx_data_enable_ltc2872"; + static constexpr char PDEC_RESET[] = "pdec_reset"; } } diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 1715cada..2c1179d9 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -100,11 +100,21 @@ void initmission::initTasks() { #if OBSW_USE_CCSDS_IP_CORE == 1 PeriodicTaskIF* ccsdsHandlerTask = factory->createPeriodicTask( - "UDP_POLLING", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + "CCSDS_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); result = ccsdsHandlerTask->addComponent(objects::CCSDS_HANDLER); if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("CCSDS Handler", objects::CCSDS_HANDLER); } + + // Minimal distance between two received TCs amounts to 0.6 seconds + // If a command has not been read before the next one arrives, the old command will be + // overwritten by the PDEC. + PeriodicTaskIF* pdecHandlerTask = factory->createPeriodicTask( + "PDEC_HANDLER", 10, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc); + result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER); + } #endif /* OBSW_USE_CCSDS_IP_CORE == 1 */ # if BOARD_TE0720 == 0 @@ -158,6 +168,7 @@ void initmission::initTasks() { #if OBSW_USE_CCSDS_IP_CORE == 1 ccsdsHandlerTask->startTask(); + pdecHandlerTask->startTask(); #endif /* OBSW_USE_CCSDS_IP_CORE == 1 */ #if BOARD_TE0720 == 0 diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 66357373..a64a1493 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -76,6 +76,7 @@ #endif #include +#include #include #include @@ -171,7 +172,7 @@ void ObjectFactory::produce(void* args) { new StarTrackerHandler(objects::START_TRACKER, objects::UART_COM_IF, starTrackerCookie); #endif /* OBSW_ADD_STAR_TRACKER == 1 */ -#endif /* TE7020 != 0 */ +#endif /* TE7020 == 0 */ #if OBSW_USE_CCSDS_IP_CORE == 1 createCcsdsComponents(gpioComIF); @@ -936,7 +937,8 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { ptme->addVcInterface(ccsds::VC2, vc2); ptme->addVcInterface(ccsds::VC3, vc3); - CCSDSHandler* ccsdsHandler = new CCSDSHandler(objects::CCSDS_HANDLER, objects::PTME); + CCSDSHandler* ccsdsHandler = new CCSDSHandler(objects::CCSDS_HANDLER, objects::PTME, + objects::CCSDS_PACKET_DISTRIBUTOR); VirtualChannel* vc = nullptr; vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE); @@ -948,6 +950,21 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { vc = new VirtualChannel(ccsds::VC3, common::VC3_QUEUE_SIZE); ccsdsHandler->addVirtualChannel(ccsds::VC3, vc); + GpioCookie* gpioCookiePdec = new GpioCookie; + consumer.str(""); + consumer << "0x" << std::hex << objects::PDEC_HANDLER; + // GPIO also low after linux boot (specified by device-tree) + gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, consumer.str(), gpio::OUT, + gpio::LOW); + gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio); + + gpioComIF->addGpios(gpioCookiePdec); + + new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET, + std::string(q7s::UIO_PDEC_CONFIG_MEMORY), std::string(q7s::UIO_PDEC_RAM), + std::string(q7s::UIO_PDEC_REGISTERS)); + +#if BOARD_TE0720 == 0 GpioCookie* gpioRS485Chip = new GpioCookie; gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver", gpio::Direction::OUT, gpio::HIGH); @@ -957,6 +974,7 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_DATA, gpio); gpioComIF->addGpios(gpioRS485Chip); +#endif /* BOARD_TE0720 == 0 */ } void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) { diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index bddea49a..605ace3b 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -21,6 +21,7 @@ enum commonClassIds: uint8_t { PLOC_UPDATER, //PLUD GOM_SPACE_HANDLER, //GOMS PLOC_MEMORY_DUMPER, //PLMEMDUMP + PDEC_HANDLER, //PDEC COMMON_CLASS_ID_END // [EXPORT] : [END] }; diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index dc18995e..8cf45e9a 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -16,6 +16,7 @@ enum commonObjects: uint32_t { PAPB_VC1 = 0x50000701, PAPB_VC2 = 0x50000702, PAPB_VC3 = 0x50000703, + PDEC_HANDLER = 0x50000704, CCSDS_HANDLER = 0x50000800, /* 0x43 ('C') for Controllers */ diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index 4cef8774..05fda61c 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -17,6 +17,7 @@ enum: uint8_t { FILE_SYSTEM = 116, PLOC_UPDATER = 117, PLOC_MEMORY_DUMPER = 118, + PDEC_HANDLER = 119, COMMON_SUBSYSTEM_ID_END }; } diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index a5bbcde4..165ad708 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -1,106 +1,106 @@ -2200;STORE_SEND_WRITE_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2201;STORE_WRITE_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2202;STORE_SEND_READ_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2203;STORE_READ_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2204;UNEXPECTED_MSG;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2205;STORING_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2206;TM_DUMP_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2207;STORE_INIT_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2208;STORE_INIT_EMPTY;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2209;STORE_CONTENT_CORRUPTED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2210;STORE_INITIALIZE;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2211;INIT_DONE;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2212;DUMP_FINISHED;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2213;DELETION_FINISHED;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2214;DELETION_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2215;AUTO_CATALOGS_SENDING_FAILED;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2600;GET_DATA_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h -2601;STORE_DATA_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h -2800;DEVICE_BUILDING_COMMAND_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2801;DEVICE_SENDING_COMMAND_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2802;DEVICE_REQUESTING_REPLY_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2803;DEVICE_READING_REPLY_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2805;DEVICE_MISSED_REPLY;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2806;DEVICE_UNKNOWN_REPLY;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2807;DEVICE_UNREQUESTED_REPLY;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2808;INVALID_DEVICE_COMMAND;LOW;Indicates a SW bug in child class.;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2809;MONITORING_LIMIT_EXCEEDED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2810;MONITORING_AMBIGUOUS;HIGH;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -4201;FUSE_CURRENT_HIGH;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h -4202;FUSE_WENT_OFF;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h -4204;POWER_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h -4205;POWER_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h -4300;SWITCH_WENT_OFF;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h -5000;HEATER_ON;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h -5001;HEATER_OFF;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h -5002;HEATER_TIMEOUT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h -5003;HEATER_STAYED_ON;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h -5004;HEATER_STAYED_OFF;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h -5200;TEMP_SENSOR_HIGH;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5201;TEMP_SENSOR_LOW;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5202;TEMP_SENSOR_GRADIENT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5901;COMPONENT_TEMP_LOW;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5902;COMPONENT_TEMP_HIGH;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5903;COMPONENT_TEMP_OOL_LOW;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5904;COMPONENT_TEMP_OOL_HIGH;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5905;TEMP_NOT_IN_OP_RANGE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -7101;FDIR_CHANGED_STATE;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7102;FDIR_STARTS_RECOVERY;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7103;FDIR_TURNS_OFF_DEVICE;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7201;MONITOR_CHANGED_STATE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7202;VALUE_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7203;VALUE_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7204;VALUE_OUT_OF_RANGE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7301;SWITCHING_TM_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/HkSwitchHelper.h -7400;CHANGING_MODE;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h -7401;MODE_INFO;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h -7402;FALLBACK_FAILED;HIGH;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h -7403;MODE_TRANSITION_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h -7404;CANT_KEEP_MODE;HIGH;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h -7405;OBJECT_IN_INVALID_MODE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h -7406;FORCING_MODE;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h -7407;MODE_CMD_REJECTED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h -7506;HEALTH_INFO;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h -7507;CHILD_CHANGED_HEALTH;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h -7508;CHILD_PROBLEMS;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h -7509;OVERWRITING_HEALTH;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h -7510;TRYING_RECOVERY;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h -7511;RECOVERY_STEP;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h -7512;RECOVERY_DONE;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h -7900;RF_AVAILABLE;INFO;A RF available signal was detected. P1: raw RFA state, P2: 0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7901;RF_LOST;INFO;A previously found RF available signal was lost. P1: raw RFA state, P2: 0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7902;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7903;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7905;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -8900;CLOCK_SET;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h -8901;CLOCK_SET_FAILURE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h -9700;TEST;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service17Test.h -10600;CHANGE_OF_SETUP_PARAMETER;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/MGMHandlerLIS3MDL.h -11101;MEMORY_READ_RPT_CRC_FAILURE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h -11102;ACK_FAILURE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h -11103;EXE_FAILURE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h -11104;CRC_FAILURE_EVENT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h -11201;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h -11202;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h -11203;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h -11204;SELF_TEST_PWM_FAILURE;LOW;Get self test result returns PWM failure which concerns the coil actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h -11205;SELF_TEST_TC_FAILURE;LOW;Get self test result returns TC failure (system failure) P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h -11206;SELF_TEST_MTM_RANGE_FAILURE;LOW;Get self test result returns failure that MTM values were outside of the expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h -11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h -11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h -11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h -11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11600;SANITIZATION_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h -11700;UPDATE_FILE_NOT_EXISTS;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h -11701;ACTION_COMMANDING_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h -11702;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h -11703;UPDATE_TRANSFER_FAILED;LOW;Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet);C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h -11704;UPDATE_VERIFY_FAILED;LOW;Supervisor failed to execute the update verify command.;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h -11705;UPDATE_FINISHED;INFO;MPSoC update successful completed;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h -11800;SEND_MRAM_DUMP_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h -11801;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h -11802;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h +2200;STORE_SEND_WRITE_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2201;STORE_WRITE_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2202;STORE_SEND_READ_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2203;STORE_READ_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2204;UNEXPECTED_MSG;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2205;STORING_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2206;TM_DUMP_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2207;STORE_INIT_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2208;STORE_INIT_EMPTY;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2209;STORE_CONTENT_CORRUPTED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2210;STORE_INITIALIZE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2211;INIT_DONE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2212;DUMP_FINISHED;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2213;DELETION_FINISHED;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2214;DELETION_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2215;AUTO_CATALOGS_SENDING_FAILED;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2600;GET_DATA_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h +2601;STORE_DATA_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h +2800;DEVICE_BUILDING_COMMAND_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2801;DEVICE_SENDING_COMMAND_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2802;DEVICE_REQUESTING_REPLY_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2803;DEVICE_READING_REPLY_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2805;DEVICE_MISSED_REPLY;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2806;DEVICE_UNKNOWN_REPLY;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2807;DEVICE_UNREQUESTED_REPLY;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2808;INVALID_DEVICE_COMMAND;LOW;Indicates a SW bug in child class.;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2809;MONITORING_LIMIT_EXCEEDED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2810;MONITORING_AMBIGUOUS;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +4201;FUSE_CURRENT_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4202;FUSE_WENT_OFF;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4204;POWER_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4205;POWER_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4300;SWITCH_WENT_OFF;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h +5000;HEATER_ON;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5001;HEATER_OFF;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5002;HEATER_TIMEOUT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5003;HEATER_STAYED_ON;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5004;HEATER_STAYED_OFF;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5200;TEMP_SENSOR_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5201;TEMP_SENSOR_LOW;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5202;TEMP_SENSOR_GRADIENT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5901;COMPONENT_TEMP_LOW;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5902;COMPONENT_TEMP_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5903;COMPONENT_TEMP_OOL_LOW;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5904;COMPONENT_TEMP_OOL_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5905;TEMP_NOT_IN_OP_RANGE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +7101;FDIR_CHANGED_STATE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7102;FDIR_STARTS_RECOVERY;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7103;FDIR_TURNS_OFF_DEVICE;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7201;MONITOR_CHANGED_STATE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7202;VALUE_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7203;VALUE_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7204;VALUE_OUT_OF_RANGE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7301;SWITCHING_TM_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/HkSwitchHelper.h +7400;CHANGING_MODE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7401;MODE_INFO;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7402;FALLBACK_FAILED;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7403;MODE_TRANSITION_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7404;CANT_KEEP_MODE;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7405;OBJECT_IN_INVALID_MODE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7406;FORCING_MODE;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7407;MODE_CMD_REJECTED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7506;HEALTH_INFO;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7507;CHILD_CHANGED_HEALTH;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7508;CHILD_PROBLEMS;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7509;OVERWRITING_HEALTH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7510;TRYING_RECOVERY;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7511;RECOVERY_STEP;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7512;RECOVERY_DONE;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7900;RF_AVAILABLE;INFO;A RF available signal was detected. P1: raw RFA state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7901;RF_LOST;INFO;A previously found RF available signal was lost. P1: raw RFA state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7902;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7903;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7905;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +8900;CLOCK_SET;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h +8901;CLOCK_SET_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h +9700;TEST;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service17Test.h +10600;CHANGE_OF_SETUP_PARAMETER;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h +11101;MEMORY_READ_RPT_CRC_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11102;ACK_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11103;EXE_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11104;CRC_FAILURE_EVENT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11201;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11202;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11203;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11204;SELF_TEST_PWM_FAILURE;LOW;Get self test result returns PWM failure which concerns the coil actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11205;SELF_TEST_TC_FAILURE;LOW;Get self test result returns TC failure (system failure) P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11206;SELF_TEST_MTM_RANGE_FAILURE;LOW;Get self test result returns failure that MTM values were outside of the expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h +11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11600;SANITIZATION_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h +11700;UPDATE_FILE_NOT_EXISTS;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11701;ACTION_COMMANDING_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11702;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11703;UPDATE_TRANSFER_FAILED;LOW;Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet);C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11704;UPDATE_VERIFY_FAILED;LOW;Supervisor failed to execute the update verify command.;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11705;UPDATE_FINISHED;INFO;MPSoC update successful completed;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11800;SEND_MRAM_DUMP_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h +11801;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h +11802;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 9d817651..18f6ba50 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 106 translations. * @details - * Generated on: 2021-08-31 10:50:10 + * Generated on: 2021-10-31 17:56:40 */ #include "translateEvents.h" diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 6ccd6b6d..9dbc5428 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -109,6 +109,7 @@ debugging. */ #define OBSW_DEBUG_STARTRACKER 0 #define OBSW_DEBUG_PLOC_MPSOC 0 #define OBSW_DEBUG_PLOC_SUPERVISOR 0 +#define OBSW_DEBUG_PDEC_HANDLER 0 /*******************************************************************/ /** Hardcoded */ diff --git a/linux/fsfwconfig/devices/gpioIds.h b/linux/fsfwconfig/devices/gpioIds.h index ebe8a3eb..2fe715ea 100644 --- a/linux/fsfwconfig/devices/gpioIds.h +++ b/linux/fsfwconfig/devices/gpioIds.h @@ -100,6 +100,8 @@ enum gpioId_t { VC3_PAPB_EMPTY, VC3_PAPB_BUSY, + PDEC_RESET, + RS485_EN_TX_DATA, RS485_EN_TX_CLOCK diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 9d817651..18f6ba50 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 106 translations. * @details - * Generated on: 2021-08-31 10:50:10 + * Generated on: 2021-10-31 17:56:40 */ #include "translateEvents.h" diff --git a/linux/obc/CMakeLists.txt b/linux/obc/CMakeLists.txt index 315a0d33..371ea7cd 100644 --- a/linux/obc/CMakeLists.txt +++ b/linux/obc/CMakeLists.txt @@ -1,6 +1,8 @@ target_sources(${TARGET_NAME} PUBLIC PapbVcInterface.cpp Ptme.cpp + PdecHandler.cpp + PdecConfig.cpp ) diff --git a/linux/obc/PdecConfig.cpp b/linux/obc/PdecConfig.cpp new file mode 100644 index 00000000..bb2ffb13 --- /dev/null +++ b/linux/obc/PdecConfig.cpp @@ -0,0 +1,36 @@ +#include "PdecConfig.h" +#include "fsfw/serviceinterface/ServiceInterface.h" + +PdecConfig::PdecConfig() { + initialize(); +} + +PdecConfig::~PdecConfig() { + +} + +void PdecConfig::initialize() { + uint32_t word = 0; + word |= (VERSION_ID << 30); + word |= (BYPASS_FLAG << 29); + word |= (CONTROL_COMMAND_FLAG << 28); + word |= (RESERVED_FIELD_A << 26); + word |= (SPACECRAFT_ID << 16); + word |= (VIRTUAL_CHANNEL << 10); + word |= (DUMMY_BITS << 8); + word |= POSITIVE_WINDOW; + configWords[0] = word; + word = 0; + word |= (NEGATIVE_WINDOW << 24); + word |= (HIGH_AU_MAP_ID << 16); + word |= (ENABLE_DERANDOMIZER << 8); + configWords[1] = word; +} + +uint32_t PdecConfig::getConfigWord(uint8_t wordNo) { + if (wordNo >= CONFIG_WORDS_NUM) { + sif::error << "PdecConfig::getConfigWord: Invalid word number" << std::endl; + return 0; + } + return configWords[wordNo]; +} diff --git a/linux/obc/PdecConfig.h b/linux/obc/PdecConfig.h new file mode 100644 index 00000000..46cd5097 --- /dev/null +++ b/linux/obc/PdecConfig.h @@ -0,0 +1,52 @@ +#ifndef LINUX_OBC_PDECCONFIG_H_ +#define LINUX_OBC_PDECCONFIG_H_ + +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include + +/** + * @brief This class generates the configuration words for the configuration memory of the PDEC + * IP Cores. + * + * @details Fields are initialized according to pecification in PDEC datasheet section 6.11.3.1 + * PROM usage. + * + * @author J. Meier + */ +class PdecConfig { + +public: + PdecConfig(); + virtual ~PdecConfig(); + + /** + * @brief Returns the configuration word by specifying the position. + */ + uint32_t getConfigWord(uint8_t wordNo); + +private: + // TC transfer frame configuration parameters + static const uint8_t VERSION_ID = 0; + // BD Frames + static const uint8_t BYPASS_FLAG = 1; + static const uint8_t CONTROL_COMMAND_FLAG = 0; + + 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 DUMMY_BITS = 0; + // Parameters to control the FARM for AD frames + // Set here for future use + static const uint8_t POSITIVE_WINDOW = 10; + static const uint8_t NEGATIVE_WINDOW = 151; + static const uint8_t HIGH_AU_MAP_ID = 0xF; + static const uint8_t ENABLE_DERANDOMIZER = 1; + + static const uint8_t CONFIG_WORDS_NUM = 2; + + uint32_t configWords[CONFIG_WORDS_NUM]; + + void initialize(); +}; + +#endif /* LINUX_OBC_PDECCONFIG_H_ */ diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp new file mode 100644 index 00000000..3d80af8a --- /dev/null +++ b/linux/obc/PdecHandler.cpp @@ -0,0 +1,489 @@ +#include +#include + +#include +#include + +#include "PdecHandler.h" +#include "OBSWConfig.h" +#include "fsfw/serviceinterface/ServiceInterface.h" +#include "fsfw/tmtcservices/TmTcMessage.h" +#include "fsfw/objectmanager/ObjectManager.h" + +PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId, + LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioConfigMemory, + std::string uioRamMemory, std::string uioRegisters) : + SystemObject(objectId), tcDestinationId(tcDestinationId), gpioComIF(gpioComIF), pdecReset( + pdecReset), uioConfigMemory(uioConfigMemory), uioRamMemory(uioRamMemory), uioRegisters( + uioRegisters) { + +} + +PdecHandler::~PdecHandler() { +} + +ReturnValue_t PdecHandler::initialize() { + + tcStore = ObjectManager::instance()->get(objects::TC_STORE); + if (tcStore == nullptr) { + sif::error << "PdecHandler::initialize: Invalid TC store" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + tcDestination = ObjectManager::instance()->get( + tcDestinationId); + + if (tcDestination == nullptr) { + sif::error << "PdecHandler::initialize: Invalid tc destination specified" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + ReturnValue_t result = RETURN_OK; + + result = getRegisterAddress(); + if (result != RETURN_OK) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + result = getConfigMemoryBaseAddress(); + if (result != RETURN_OK) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + result = getRamBaseAddress(); + if (result != RETURN_OK) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + writePdecConfig(); + + result = releasePdec(); + if (result != RETURN_OK) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + return RETURN_OK; +} + +ReturnValue_t PdecHandler::getRegisterAddress() { + int fd = open(uioRegisters.c_str(), O_RDWR); + if (fd < 1) { + sif::warning << "PdecHandler::getRegisterAddress: Invalid UIO device file" << std::endl; + return RETURN_FAILED; + } + + registerBaseAddress = static_cast(mmap(NULL, REGISTER_MAP_SIZE, + PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0)); + + if (registerBaseAddress == MAP_FAILED) { + sif::error << "PdecHandler::getRegisterAddress: Failed to map uio address" << std::endl; + return RETURN_FAILED; + } + + return RETURN_OK; +} + +ReturnValue_t PdecHandler::getConfigMemoryBaseAddress() { + int fd = open(uioConfigMemory.c_str(), O_RDWR); + if (fd < 1) { + sif::warning << "PdecHandler::getConfigMemoryBaseAddress: Invalid UIO device file" << std::endl; + return RETURN_FAILED; + } + + memoryBaseAddress = static_cast(mmap(NULL, CONFIG_MEMORY_MAP_SIZE, PROT_WRITE | PROT_READ, + MAP_SHARED, fd, 0)); + + if (memoryBaseAddress == MAP_FAILED) { + sif::error << "PdecHandler::getConfigMemoryBaseAddress: Failed to map uio address" << std::endl; + return RETURN_FAILED; + } + + return RETURN_OK; +} + +ReturnValue_t PdecHandler::getRamBaseAddress() { + int fd = open(uioRamMemory.c_str(), O_RDWR); + + ramBaseAddress = static_cast(mmap(NULL, RAM_MAP_SIZE, PROT_WRITE | PROT_READ, + MAP_SHARED, fd, 0)); + + if (ramBaseAddress == MAP_FAILED) { + sif::error << "PdecHandler::getRamBaseAddress: Failed to map RAM base address" << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +void PdecHandler::writePdecConfig() { + + PdecConfig pdecConfig; + + *(memoryBaseAddress + FRAME_HEADER_OFFSET)= pdecConfig.getConfigWord(0); + *(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1); + + // Configure all MAP IDs as invalid + for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { + *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx + 1 / 4) = NO_DESTINATION << 24 + | NO_DESTINATION << 16 | NO_DESTINATION << 8 | NO_DESTINATION; + + } + + // All TCs with MAP ID 7 will be routed to the PM module (can then be read from memory) + uint8_t routeToPm = calcMapAddrEntry(PM_BUFFER); + *(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + 1) = (NO_DESTINATION << 24) | (NO_DESTINATION << 16) | (NO_DESTINATION << 8) + | routeToPm; + + // Write map id clock frequencies + for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { + *(memoryBaseAddress + MAP_CLK_FREQ_OFFSET + idx / 4) = MAP_CLK_FREQ << 24 + | MAP_CLK_FREQ << 16 | MAP_CLK_FREQ << 8 | MAP_CLK_FREQ; + + } +} + +ReturnValue_t PdecHandler::resetFarStatFlag() { + uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); + if (pdecFar != FAR_RESET) { + sif::warning << "PdecHandler::resetFarStatFlag: FAR register did not match expected value." + << " Read value: 0x" << std::hex << static_cast(pdecFar) << std::endl; + return RETURN_FAILED; + } +#if OBSW_DEBUG_PDEC_HANDLER == 1 + sif::debug << "PdecHandler::resetFarStatFlag: read FAR with value: 0x" << std::hex << pdecFar + << std::endl; +#endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */ + return RETURN_OK; +} + +ReturnValue_t PdecHandler::releasePdec() { + ReturnValue_t result = RETURN_OK; + result = gpioComIF->pullHigh(pdecReset); + if (result != RETURN_OK) { + sif::error << "PdecHandler::releasePdec: Failed to release PDEC reset signal" << std::endl; + } + return result; +} + +ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { + + ReturnValue_t result = RETURN_OK; + + switch(state) { + case State::INIT: + resetFarStatFlag(); + if (result != RETURN_OK) { + // Requires reconfiguration and reinitialization of PDEC + triggerEvent(INVALID_FAR); + state = State::WAIT_FOR_RECOVERY; + return result; + } + state = State::RUNNING; + break; + case State::RUNNING: + if (newTcReceived()) { + handleNewTc(); + } + getClcw(); + break; + case State::WAIT_FOR_RECOVERY: + break; + default: + sif::debug << "PdecHandler::performOperation: Invalid state" << std::endl; + break; + } + + return RETURN_OK; +} + +bool PdecHandler::newTcReceived() { + uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET); + + if (pdecFar >> STAT_POSITION != NEW_FAR_RECEIVED) { + return false; + } + if (!checkFrameAna(pdecFar)) { + return false; + } + return true; +} + +bool PdecHandler::checkFrameAna(uint32_t pdecFar) { + bool frameValid = false; + FrameAna_t frameAna = static_cast((pdecFar & FRAME_ANA_MASK) >> FRAME_ANA_POSITION); + switch(frameAna) { + case(FrameAna_t::ABANDONED_CLTU): { + triggerEvent(INVALID_TC_FRAME, ABANDONED_CLTU); + sif::debug << "PdecHandler::checkFrameAna: Abondoned CLTU" << std::endl; + break; + } + case(FrameAna_t::FRAME_DIRTY): { + triggerEvent(INVALID_TC_FRAME, FRAME_DIRTY); + sif::debug << "PdecHandler::checkFrameAna: Frame dirty" << std::endl; + break; + } + case(FrameAna_t::FRAME_ILLEGAL): { + sif::debug << "PdecHandler::checkFrameAna: Frame illegal for one reason" << std::endl; + handleIReason(pdecFar, FRAME_ILLEGAL_ONE_REASON); + break; + } + case(FrameAna_t::FRAME_ILLEGAL_MULTI_REASON): { + sif::debug << "PdecHandler::checkFrameAna: Frame illegal for multiple reasons" + << std::endl; + handleIReason(pdecFar, FRAME_ILLEGAL_MULTIPLE_REASONS); + break; + } + case(FrameAna_t::AD_DISCARDED_LOCKOUT): { + triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_LOCKOUT); + sif::debug << "PdecHandler::checkFrameAna: AD frame discarded because of lockout" + << std::endl; + break; + } + case(FrameAna_t::AD_DISCARDED_WAIT): { + triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_LOCKOUT); + sif::debug << "PdecHandler::checkFrameAna: AD frame discarded because of wait" + << std::endl; + break; + } + case(FrameAna_t::AD_DISCARDED_NS_VR): { + triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_NS_VS); + sif::debug << "PdecHandler::checkFrameAna: AD frame discarded because N(S) or V(R)" + << std::endl; + break; + } + case(FrameAna_t::FRAME_ACCEPTED): { + sif::debug << "PdecHandler::checkFrameAna: Accepted TC frame" << std::endl; + frameValid = true; + break; + } + default: { + sif::debug << "PdecHandler::checkFrameAna: Invalid frame analysis report" << std::endl; + break; + } + } + return frameValid; +} + +void PdecHandler::handleIReason(uint32_t pdecFar, ReturnValue_t parameter1) { + IReason_t ireason = static_cast((pdecFar & IREASON_MASK) >> IREASON_POSITION); + switch(ireason) { + case(IReason_t::NO_REPORT): { + triggerEvent(INVALID_TC_FRAME, parameter1, NO_REPORT); + sif::debug << "PdecHandler::handleIReason: No illegal report" << std::endl; + break; + } + case(IReason_t::ERROR_VERSION_NUMBER): { + triggerEvent(INVALID_TC_FRAME, parameter1, ERROR_VERSION_NUMBER); + sif::debug << "PdecHandler::handleIReason: Error in version number and reserved A and B " + << "fields" << std::endl; + break; + } + case(IReason_t::ILLEGAL_COMBINATION): { + triggerEvent(INVALID_TC_FRAME, parameter1, ILLEGAL_COMBINATION); + sif::debug << "PdecHandler::handleIReason: Illegal combination (AC) of bypass and control " + << "command flags" << std::endl; + break; + } + case(IReason_t::INVALID_SC_ID): { + triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_SC_ID); + sif::debug << "PdecHandler::handleIReason: Invalid spacecraft identifier " << std::endl; + break; + } + case(IReason_t::INVALID_VC_ID_MSB): { + triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_VC_ID_MSB); + sif::debug << "PdecHandler::handleIReason: VC identifier bit 0 to 4 did not match " + << std::endl; + break; + } + case(IReason_t::INVALID_VC_ID_LSB): { + triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_VC_ID_LSB); + sif::debug << "PdecHandler::handleIReason: VC identifier bit 5 did not match " << std::endl; + break; + } + case(IReason_t::NS_NOT_ZERO): { + triggerEvent(INVALID_TC_FRAME, parameter1, NS_NOT_ZERO); + sif::debug << "PdecHandler::handleIReason: N(S) of BC or BD frame not set to all zeros" + << std::endl; + break; + } + case(IReason_t::INCORRECT_BC_CC): { + triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_BC_CC); + sif::debug << "PdecHandler::handleIReason: Invalid BC control command format" << std::endl; + break; + } + default: { + sif::debug << "PdecHandler::handleIReason: Invalid reason id" << std::endl; + break; + } + } +} + +void PdecHandler::handleNewTc() { + ReturnValue_t result = RETURN_OK; + + uint32_t tcLength = 0; + result = readTc(tcLength); + if (result != RETURN_OK) { + return; + } +#if OBSW_DEBUG_PDEC_HANDLER == 1 + unsigned int mapId = tcSegment[0] & MAP_ID_MASK; + sif::debug << "PdecHandler::handleNewTc: Received TC segment with map ID " << mapId + << std::endl; + printTC(tcLength); +#endif /* OBSW_DEBUG_PDEC_HANDLER */ + + store_address_t storeId; + result = tcStore->addData(&storeId, tcSegment + 1, tcLength - 1); + if (result != RETURN_OK) { + sif::warning << "PdecHandler::handleNewTc: Failed to add received space packet to store" + << std::endl; + return; + } + + TmTcMessage message(storeId); + + result = MessageQueueSenderIF::sendMessage(tcDestination->getRequestQueue(), &message); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "PdecHandler::handleNewTc: Failed to send message to TC destination" + << std::endl; + tcStore->deleteData(storeId); + return; + } + + return; +} + +ReturnValue_t PdecHandler::readTc(uint32_t& tcLength) { + uint32_t tcOffset = (*(registerBaseAddress + PDEC_BPTR_OFFSET) - PHYSICAL_RAM_BASE_ADDRESS) / 4; + +#if OBSW_DEBUG_PDEC_HANDLER == 1 + sif::debug << "PdecHandler::readTc: TC offset: 0x" << std::hex << tcOffset << std::endl; +#endif /* OBSW_DEBUG_PDEC_HANDLER */ + + tcLength = *(registerBaseAddress + PDEC_SLEN_OFFSET); + +#if OBSW_DEBUG_PDEC_HANDLER == 1 + sif::debug << "PdecHandler::readTc: TC segment length: " << std::dec << tcLength << std::endl; +#endif /* OBSW_DEBUG_PDEC_HANDLER */ + + if (tcLength > MAX_TC_SEGMENT_SIZE) { + sif::warning << "PdecHandler::handleNewTc: Read invalid TC length from PDEC register" + << std::endl; + return RETURN_FAILED; + } + + uint32_t idx = 0; + uint32_t tcData = 0; + for (idx = 0; idx <= tcLength; idx = idx + 4) { + tcData = *(ramBaseAddress + tcOffset + idx / 4); + if (idx == 0) { + tcSegment[idx] = static_cast((tcData >> 16) & 0xFF); + tcSegment[idx + 1] = static_cast((tcData >> 8) & 0xFF); + tcSegment[idx + 2] = static_cast(tcData & 0xFF); + } + else if (tcLength - idx + 1 == 3) { + tcSegment[idx - 1] = static_cast((tcData >> 24) & 0xFF); + tcSegment[idx] = static_cast((tcData >> 16) & 0xFF); + tcSegment[idx + 1] = static_cast((tcData >> 8) & 0xFF); + } + else if (tcLength - idx + 1 == 2) { + tcSegment[idx - 1] = static_cast((tcData >> 24) & 0xFF); + tcSegment[idx] = static_cast((tcData >> 16) & 0xFF); + } + else if (tcLength - idx + 1 == 1) { + tcSegment[idx - 1] = static_cast((tcData >> 24) & 0xFF); + } + else { + tcSegment[idx - 1] = static_cast((tcData >> 24) & 0xFF); + tcSegment[idx] = static_cast((tcData >> 16) & 0xFF); + tcSegment[idx + 1] = static_cast((tcData >> 8) & 0xFF); + tcSegment[idx + 2] = static_cast(tcData & 0xFF); + } + } + + // Backend buffer is handled back to PDEC3 + *(registerBaseAddress + PDEC_BFREE_OFFSET) = 0; + + return RETURN_OK; +} + +void PdecHandler::printTC(uint32_t tcLength) { + std::stringstream tcSegmentStream; + tcSegmentStream << "TC segment data: 0x"; + for (uint32_t idx = 0; idx < tcLength; idx++) { + tcSegmentStream << std::setfill('0') << std::setw(2) << std::hex + << static_cast(tcSegment[idx]); + } + sif::debug << tcSegmentStream.str() << std::endl; +} + +uint8_t PdecHandler::calcMapAddrEntry(uint8_t moduleId) { + uint8_t lutEntry = 0; + uint8_t parity = getOddParity(moduleId | (1 << VALID_POSITION)); + lutEntry = (parity << PARITY_POSITION) | (1 << VALID_POSITION) | moduleId; + return lutEntry; +} + +uint8_t PdecHandler::getOddParity(uint8_t number) { + uint8_t parityBit = 0; + uint8_t countBits = 0; + for (unsigned int idx = 0; idx < sizeof(number) * 8; idx++) { + countBits += (number >> idx) & 0x1; + } + parityBit = ~(countBits & 0x1) & 0x1; + return parityBit; +} + +void PdecHandler::getClcw() { + +#if OBSW_DEBUG_PDEC_HANDLER == 1 + uint32_t clcw = *(registerBaseAddress + PDEC_CLCW_OFFSET); + if (debugDivider == 10) { + printClcw(clcw); + debugDivider = 0; + return; + } + debugDivider++; +#endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */ + +} + +void PdecHandler::printClcw(uint32_t clcw) { + uint8_t type = static_cast((clcw >> 31) & 0x1); + uint8_t versionNo = static_cast((clcw >> 29) & 0x3); + uint8_t status = static_cast((clcw >> 26) & 0x7); + uint8_t cop = static_cast((clcw >> 24) & 0x3); + uint8_t vcId = static_cast((clcw >> 18) & 0x3F); + uint8_t noRf = static_cast((clcw >> 15) & 0x1); + uint8_t noBitLock = static_cast((clcw >> 14) & 0x1); + uint8_t lockoutFlag = static_cast((clcw >> 13) & 0x1); + uint8_t waitFlag = static_cast((clcw >> 12) & 0x1); + uint8_t retransmitFlag = static_cast((clcw >> 11) & 0x1); + uint8_t farmBcnt = static_cast((clcw >> 9) & 0x3); + // Expected frame sequence number in te next AD frame + uint8_t repValue = static_cast(clcw & 0xFF); + sif::info << std::setw(30) << std::left << "CLCW type: " << std::hex + << "0x" << static_cast(type) << std::endl; + sif::info << std::setw(30) << std::left << "CLCW version no: " << std::hex + << "0x" << static_cast(versionNo) << std::endl; + sif::info << std::setw(30) << std::left << "CLCW status: " << std::hex + << "0x" << static_cast(status) << std::endl; + sif::info << std::setw(30) << std::left << "CLCW COP: " << std::hex + << "0x" << static_cast(cop) << std::endl; + sif::info << std::setw(30) << std::left << "CLCW virtual channel ID: " << std::hex + << "0x" << static_cast(vcId) << std::endl; + sif::info << std::setw(30) << std::left << "CLCW no RF: " << std::hex + << "0x" << static_cast(noRf) << std::endl; + sif::info << std::setw(30) << std::left << "CLCW no bit lock: " << std::hex + << "0x" << static_cast(noBitLock) << std::endl; + sif::info << std::setw(30) << std::left << "CLCW lockout flag: " << std::hex + << "0x" << static_cast(lockoutFlag) << std::endl; + sif::info << std::setw(30) << std::left << "CLCW wait flag: " << std::hex + << "0x" << static_cast(waitFlag) << std::endl; + sif::info << std::setw(30) << std::left << "CLCW retransmit flag: " << std::hex + << "0x" << static_cast(retransmitFlag) << std::endl; + sif::info << std::setw(30) << std::left << "CLCW FARM B count: " << std::hex + << "0x" << static_cast(farmBcnt) << std::endl; + sif::info << std::setw(30) << std::left << "CLCW rep value: " << std::hex + << "0x" << static_cast(repValue) << std::endl; +} diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h new file mode 100644 index 00000000..7696a7a0 --- /dev/null +++ b/linux/obc/PdecHandler.h @@ -0,0 +1,330 @@ +#ifndef LINUX_OBC_PDECHANDLER_H_ +#define LINUX_OBC_PDECHANDLER_H_ + +#include "OBSWConfig.h" +#include "PdecConfig.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw_hal/common/gpio/gpioDefinitions.h" +#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" +#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h" +#include "fsfw/storagemanager/StorageManagerIF.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/tasks/ExecutableObjectIF.h" + +/** + * @brief This class controls the PDEC IP Core implemented in the programmable logic of the + * Zynq-7020. All registers and memories of the PDEC IP Core are accessed via UIO + * drivers. + * + * @details The PDEC IP Core is responsible for processing data received in form of CLTUs from the + * S-Band transceiver. This comprises the BCH decoding of the CLTUs and reconstruction of + * telecommand transfer frames. Finally the PDEC stores the TC segment transported with + * the TC transfer frame in a register. As soon as a new TC has been received a new + * frame acceptance report (FAR) will be generated. If the FAR confirms the validity of + * a received TC segment, the data can be read out from the associated register. + * Currently, the ground software only supports transmissions of CLTUs containing one + * space packet. + * Link to datasheet of PDEC IP Core: https://eive-cloud.irs.uni-stuttgart.de/index.php/ + * apps/files/?dir=/EIVE_IRS/Arbeitsdaten/08_Used%20Components/CCSDS_IP_Cores&fileid=1108967 + * + * @author J. Meier + */ +class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF { + +public: + /** + * @brief Constructor + * @param objectId Object ID of PDEC handler system object + * @param tcDestinationId Object ID of object responsible for processing TCs. + * @param gpioComIF Pointer to GPIO interace responsible for driving GPIOs. + * @param pdecReset GPIO ID of GPIO connected to the reset signal of the PDEC. + * @param uioConfigMemory String of uio device file same mapped to the PDEC memory space + * @param uioregsiters String of uio device file same mapped to the PDEC register space + */ + PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF, + gpioId_t pdecReset, std::string uioConfigMemory, std::string uioRamMemory, + std::string uioRegisters); + + virtual ~PdecHandler(); + + ReturnValue_t performOperation(uint8_t operationCode = 0); + + ReturnValue_t initialize() override; + +private: + + static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; + + static const ReturnValue_t ABANDONED_CLTU = MAKE_RETURN_CODE(0xA0); + static const ReturnValue_t FRAME_DIRTY = MAKE_RETURN_CODE(0xA1); + static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2); + static const ReturnValue_t FRAME_ILLEGAL_MULTIPLE_REASONS = MAKE_RETURN_CODE(0xA2); + static const ReturnValue_t AD_DISCARDED_LOCKOUT = MAKE_RETURN_CODE(0xA3); + static const ReturnValue_t AD_DISCARDED_WAIT = MAKE_RETURN_CODE(0xA4); + static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5); + + static const ReturnValue_t NO_REPORT = MAKE_RETURN_CODE(0xA6); + //! Error in version number and reserved A and B fields + static const ReturnValue_t ERROR_VERSION_NUMBER = MAKE_RETURN_CODE(0xA7); + //! Illegal combination of bypass and control command flag + static const ReturnValue_t ILLEGAL_COMBINATION = MAKE_RETURN_CODE(0xA8); + //! Spacecraft identifier did not match + static const ReturnValue_t INVALID_SC_ID = MAKE_RETURN_CODE(0xA9); + //! VC identifier bits 0 to 4 did not match + static const ReturnValue_t INVALID_VC_ID_MSB = MAKE_RETURN_CODE(0xAA); + //! VC identifier bit 5 did not match + static const ReturnValue_t INVALID_VC_ID_LSB = MAKE_RETURN_CODE(0xAB); + //! N(S) of BC or BD frame not set to all zeros + static const ReturnValue_t NS_NOT_ZERO = MAKE_RETURN_CODE(0xAC); + //! Invalid BC control command + static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE); + + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER; + + //! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame + //! P1: The frame analysis information (FrameAna field of PDEC_FAR register) + //! P2: When frame declared illegal this parameter this parameter gives information about the reason (IReason field of the PDEC_FAR register) + static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH); + //! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup + static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH); + + static const uint8_t STAT_POSITION = 31; + static const uint8_t FRAME_ANA_POSITION = 28; + static const uint8_t IREASON_POSITION = 25; + + static const uint8_t NEW_FAR_RECEIVED = 0; + + static const uint32_t FRAME_ANA_MASK = 0x70000000; + static const uint32_t IREASON_MASK = 0x0E000000; + + /** + * UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4 + * Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10 + */ + static const uint32_t PDEC_FAR_OFFSET = 0xA10; + static const uint32_t PDEC_CLCW_OFFSET = 0xA12; + static const uint32_t PDEC_BFREE_OFFSET = 0xA24; + static const uint32_t PDEC_BPTR_OFFSET = 0xA25; + static const uint32_t PDEC_SLEN_OFFSET = 0xA26; + static const uint32_t PDEC_MON = 0xA27; + +#if BOARD_TE0720 == 1 + static const int CONFIG_MEMORY_MAP_SIZE = 0x400; + static const int RAM_MAP_SIZE = 0x4000; + static const int REGISTER_MAP_SIZE = 0x10000; +#else + static const int CONFIG_MEMORY_MAP_SIZE = 0x400; + static const int RAM_MAP_SIZE = 0x4000; + static const int REGISTER_MAP_SIZE = 0x4000; +#endif /* BOARD_TE0720 == 1 */ + + // 0x200 / 4 = 0x80 + static const uint32_t FRAME_HEADER_OFFSET = 0x80; + + static const size_t MAX_TC_SEGMENT_SIZE = 1017; + static const uint8_t MAP_ID_MASK = 0x3F; + + static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x32000000; + static const uint32_t MAP_ADDR_LUT_OFFSET = 0xA0; + static const uint32_t MAP_CLK_FREQ_OFFSET = 0x90; + + static const uint8_t MAX_MAP_ADDR = 63; + // Writing this to the map address in the look up table will invalidate a MAP ID. + static const uint8_t NO_DESTINATION = 0; + static const uint8_t VALID_POSITION = 6; + static const uint8_t PARITY_POSITION = 7; + + // Expected value stored in FAR register after reset + static const uint32_t FAR_RESET = 0x7FE0; + + static const uint32_t TC_SEGMENT_LEN = 1017; + + /** + * TCs with map addresses (also know as Map IDs) assigned to this channel will be stored in + * the PDEC memory. + */ + static const uint8_t PM_BUFFER = 7; + + // MAP clock frequency. Must be a value between 1 and 13 otherwise the TC segment will be + // discarded + static const uint8_t MAP_CLK_FREQ = 2; + + enum class FrameAna_t: uint8_t { + ABANDONED_CLTU, + FRAME_DIRTY, + FRAME_ILLEGAL, + FRAME_ILLEGAL_MULTI_REASON, + AD_DISCARDED_LOCKOUT, + AD_DISCARDED_WAIT, + AD_DISCARDED_NS_VR, + FRAME_ACCEPTED + }; + + enum class IReason_t: uint8_t { + NO_REPORT, + ERROR_VERSION_NUMBER, + ILLEGAL_COMBINATION, + INVALID_SC_ID, + INVALID_VC_ID_LSB, + INVALID_VC_ID_MSB, + NS_NOT_ZERO, + INCORRECT_BC_CC + }; + + enum class State: uint8_t { + INIT, + RUNNING, + WAIT_FOR_RECOVERY + }; + + /** + * @brief Opens UIO device assigned to AXI to AHB converter giving access to the PDEC + * registers. The register base address will be mapped into the virtual address space. + */ + ReturnValue_t getRegisterAddress(); + + /** + * @brief Opens UIO device assigned to the base address of the PDEC memory space and maps the + * physical address into the virtual address space. + */ + ReturnValue_t getConfigMemoryBaseAddress(); + + /** + * @brief Opens UIO device assigned to the RAM section of the PDEC IP core memory map. + * + * @details A received TC segment will be written to this memory area. + */ + ReturnValue_t getRamBaseAddress(); + + /** + * @brief This functions writes the configuration parameters to the configuration + * section of the PDEC. + */ + void writePdecConfig(); + + /** + * @brief Reading the FAR resets the set stat flag which signals a new TC. Without clearing + * this flag no new TC will be excepted. After start up the flag is set and needs + * to be reset. + * Stat flag 0 - new TC received + * Stat flag 1 - old TC (ready to receive next TC) + */ + ReturnValue_t resetFarStatFlag(); + + /** + * @brief Releases the PDEC from reset state. PDEC will start with loading the written + * configuration parameters. + */ + ReturnValue_t releasePdec(); + + /** + * @brief Reads the FAR register and checks if a new TC has been received. + */ + bool newTcReceived(); + + /** + * @brief Analyzes the FramAna field (frame analysis data) of a FAR report. + * + * @return True if frame valid, otherwise false. + */ + bool checkFrameAna(uint32_t pdecFar); + + /** + * @brief This function handles the IReason field of the frame analysis report. + * + * @details In case frame as been declared illegal for multiple reasons, the reason with the + * lowest value will be shown. + */ + void handleIReason(uint32_t pdecFar, ReturnValue_t parameter1); + + /** + * @brief Handles the reception of new TCs. Reads the pointer to the storage location of the + * new TC segment, extracts the PUS packet and forwards the data to the object + * responsible for processing the TC. + */ + void handleNewTc(); + + /** + * @brief Function reads the last received TC segment from the PDEC memory and copies + * the data to the tcSegement array. + * + * @param tcLength The length of the received TC. + * + */ + ReturnValue_t readTc(uint32_t& tcLength); + + /** + * @brief Prints the tc segment data + */ + void printTC(uint32_t tcLength); + + /** + * @brief This function calculates the entry for the configuration of the MAP ID routing. + * + * @param mapAddr The MAP ID to configure + * @param moduleId The destination module where all TCs with the map id mapAddr will be routed + * to. + * + * @details The PDEC has different modules where the TCs can be routed to. A lookup table is + * used which links the MAP ID field to the destination module. The entry for this + * lookup table is created by this function and must be stored in the configuration + * memory region of the PDEC. The entry has a specific format + */ + uint8_t calcMapAddrEntry(uint8_t moduleId); + + /** + * @brief This functions calculates the odd parity of the bits in number. + * + * @param number The number from which to calculate the odd parity. + */ + uint8_t getOddParity(uint8_t number); + + void getClcw(); + void printClcw(uint32_t clcw); + + object_id_t tcDestinationId; + + AcceptsTelecommandsIF* tcDestination = nullptr; + + LinuxLibgpioIF* gpioComIF = nullptr; + + /** + * Reset signal is required to hold PDEC in reset state until the configuration has been + * written to the appropriate memory space. + * Can also be used to reboot PDEC in case of erros. + */ + gpioId_t pdecReset = gpio::NO_GPIO; + + // UIO device file giving access to the PDEC configuration memory section + std::string uioConfigMemory; + + // UIO device file giving access to the PDEC RAM section + std::string uioRamMemory; + + // UIO device file giving access to the PDEC register space + std::string uioRegisters; + + StorageManagerIF* tcStore = nullptr; + + State state = State::INIT; + + /** + * Pointer pointing to base address of the PDEC memory space. + * This address is equivalent with the base address of the section named configuration area in + * the PDEC datasheet. + */ + uint32_t* memoryBaseAddress = nullptr; + + uint32_t* ramBaseAddress = nullptr; + + // Pointer pointing to base address of register space + uint32_t* registerBaseAddress = nullptr; + + uint32_t pdecFar = 0; + + uint8_t tcSegment[TC_SEGMENT_LEN]; + + uint8_t debugDivider = 0; +}; + +#endif /* LINUX_OBC_PDECHANDLER_H_ */ diff --git a/linux/obc/PtmeConfig.h b/linux/obc/PtmeConfig.h index f4468570..814dfeda 100644 --- a/linux/obc/PtmeConfig.h +++ b/linux/obc/PtmeConfig.h @@ -3,10 +3,10 @@ #include "fsfw/returnvalues/HasReturnvaluesIF.h" #include - +#include "OBSWConfig.h" /** - * @brief Configuration parameters derived from FPGA design and device tree. + * @brief PTME specific configuration parameters derived from FPGA design and device tree. * * @author J. Meier */ @@ -19,8 +19,12 @@ namespace PtmeConfig { static const uint32_t VC1_OFFSETT = 0x4000; static const uint32_t VC2_OFFSETT = 0x8000; static const uint32_t VC3_OFFSETT = 0xC000; +#if BOARD_TE0720 == 0 + static const char UIO_DEVICE_FILE[] = "/dev/uio1"; +#else + static const char UIO_DEVICE_FILE[] = "/dev/uio1"; +#endif - static const char UIO_DEVICE_FILE[] = "/dev/uio0"; }; #endif /* LINUX_OBC_PTMECONFIG_H_ */ diff --git a/mission/devices/StarTrackerHandler.cpp b/mission/devices/StarTrackerHandler.cpp index a695403f..c5718f02 100644 --- a/mission/devices/StarTrackerHandler.cpp +++ b/mission/devices/StarTrackerHandler.cpp @@ -86,7 +86,7 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t rema continue; } case ARC_DEC_ASYNC: { - sif::debug << "StarTrackerHandler::scanForReply: Received asychronous tm" << std::endl; + sif::debug << "StarTrackerHandler::scanForReply: Received asynchronous tm" << std::endl; /** No asynchronous replies are expected as of now */ return RETURN_FAILED; } diff --git a/mission/tmtc/CCSDSHandler.cpp b/mission/tmtc/CCSDSHandler.cpp index 9b2912c1..ad630044 100644 --- a/mission/tmtc/CCSDSHandler.cpp +++ b/mission/tmtc/CCSDSHandler.cpp @@ -5,8 +5,8 @@ #include "CCSDSHandler.h" -CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId) : - SystemObject(objectId), ptmeId(ptmeId), parameterHelper(this) { +CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination) : + SystemObject(objectId), ptmeId(ptmeId), tcDestination(tcDestination), parameterHelper(this) { commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); } @@ -39,6 +39,17 @@ ReturnValue_t CCSDSHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } + AcceptsTelecommandsIF* tcDistributor = + ObjectManager::instance()->get(tcDestination); + if (tcDistributor == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "CCSDSHandler::initialize: Invalid TC Distributor object" << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + tcDistributorQueueId = tcDistributor->getRequestQueue(); + result = parameterHelper.initialize(); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -120,3 +131,12 @@ ReturnValue_t CCSDSHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentif uint16_t startAtIndex) { return RETURN_OK; } + +uint16_t CCSDSHandler::getIdentifier() { + return 0; +} + +MessageQueueId_t CCSDSHandler::getRequestQueue() { + // Forward packets directly to TC distributor + return tcDistributorQueueId; +} diff --git a/mission/tmtc/CCSDSHandler.h b/mission/tmtc/CCSDSHandler.h index b53cb8cd..b1c3dd60 100644 --- a/mission/tmtc/CCSDSHandler.h +++ b/mission/tmtc/CCSDSHandler.h @@ -5,6 +5,8 @@ #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw/tmtcservices/AcceptsTelemetryIF.h" +#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h" #include "fsfw/parameters/ParameterHelper.h" #include "VirtualChannel.h" #include @@ -18,6 +20,7 @@ class CCSDSHandler: public SystemObject, public ExecutableObjectIF, public AcceptsTelemetryIF, + public AcceptsTelecommandsIF, public HasReturnvaluesIF, public ReceivesParameterMessagesIF { public: @@ -29,8 +32,9 @@ public: * * @param objectId Object ID of the CCSDS handler * @param ptmeId Object ID of the PTME object providing access to the PTME IP Core. + * @param tcDestination Object ID of object handling received TC space packets */ - CCSDSHandler(object_id_t objectId, object_id_t ptmeId); + CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination); ~CCSDSHandler(); @@ -51,6 +55,9 @@ public: ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues, uint16_t startAtIndex); + uint16_t getIdentifier() override; + MessageQueueId_t getRequestQueue() override; + private: static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE; @@ -63,10 +70,14 @@ private: // Object ID of PTME object object_id_t ptmeId; + object_id_t tcDestination; + MessageQueueIF* commandQueue = nullptr; ParameterHelper parameterHelper; + MessageQueueId_t tcDistributorQueueId; + void readCommandQueue(void); void handleTelemetry(); void handleTelecommands();