Merge remote-tracking branch 'origin/develop' into mueller/master
This commit is contained in:
commit
2554afd503
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -16,6 +16,9 @@
|
||||
[submodule "generators/fsfwgen"]
|
||||
path = generators/fsfwgen
|
||||
url = https://egit.irs.uni-stuttgart.de/fsfw/fsfw-generators.git
|
||||
[submodule "thirdparty/arcsec_star_tracker"]
|
||||
path = thirdparty/arcsec_star_tracker
|
||||
url = https://egit.irs.uni-stuttgart.de/eive/arcsec_star_tracker.git
|
||||
[submodule "thirdparty/json"]
|
||||
path = thirdparty/json
|
||||
url = https://github.com/nlohmann/json.git
|
||||
|
@ -49,6 +49,7 @@ set(LIB_FSFW_NAME fsfw)
|
||||
set(LIB_ETL_NAME etl)
|
||||
set(LIB_CSP_NAME libcsp)
|
||||
set(LIB_LWGPS_NAME lwgps)
|
||||
set(LIB_ARCSEC wire)
|
||||
set(THIRD_PARTY_FOLDER thirdparty)
|
||||
set(LIB_CXX_FS -lstdc++fs)
|
||||
set(LIB_JSON_NAME nlohmann_json::nlohmann_json)
|
||||
@ -65,6 +66,7 @@ set(FSFW_HAL_LIB_PATH fsfw_hal)
|
||||
set(CSP_LIB_PATH ${THIRD_PARTY_FOLDER}/libcsp)
|
||||
set(ETL_LIB_PATH ${THIRD_PARTY_FOLDER}/etl)
|
||||
set(LWGPS_LIB_PATH ${THIRD_PARTY_FOLDER}/lwgps)
|
||||
set(ARCSEC_LIB_PATH ${THIRD_PARTY_FOLDER}/arcsec_star_tracker)
|
||||
set(LIB_JSON_PATH ${THIRD_PARTY_FOLDER}/json)
|
||||
|
||||
set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
|
||||
@ -153,6 +155,7 @@ if(NOT Q7S_SIMPLE_MODE)
|
||||
add_subdirectory(${FSFW_PATH})
|
||||
add_subdirectory(${MISSION_PATH})
|
||||
add_subdirectory(${TEST_PATH})
|
||||
add_subdirectory(${ARCSEC_LIB_PATH})
|
||||
endif()
|
||||
|
||||
|
||||
@ -168,6 +171,7 @@ if(NOT Q7S_SIMPLE_MODE)
|
||||
${LIB_FSFW_NAME}
|
||||
${LIB_OS_NAME}
|
||||
${LIB_LWGPS_NAME}
|
||||
${LIB_ARCSEC}
|
||||
${LIB_CXX_FS}
|
||||
)
|
||||
endif()
|
||||
@ -195,6 +199,7 @@ target_include_directories(${TARGET_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${FSFW_CONFIG_PATH}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${ARCSEC_LIB_PATH}
|
||||
)
|
||||
|
||||
|
||||
|
19
README.md
19
README.md
@ -606,6 +606,25 @@ Rebooting currently running image:
|
||||
xsc_boot_copy -r
|
||||
```
|
||||
|
||||
### Setting time on Q7S
|
||||
Setting date and time (only timezone UTC available)
|
||||
````
|
||||
timedatectl set-time 'YYYY-MM-DD HH:MM:SS'
|
||||
````
|
||||
Setting UNIX time
|
||||
````
|
||||
date +%s -s @1626337522
|
||||
````
|
||||
This only sets the system time and does not updating the time of the real time clock. To harmonize
|
||||
the system time with the real time clock run
|
||||
````
|
||||
hwclock -w
|
||||
````
|
||||
Reading the real time clock
|
||||
````
|
||||
hwclock --show
|
||||
````
|
||||
|
||||
## pa3tool Host Tool
|
||||
|
||||
The `pa3tool` is a host tool to interface with the ProASIC3 on the Q7S board. It was
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
CoreController::CoreController(object_id_t objectId):
|
||||
ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) {
|
||||
}
|
||||
|
@ -32,15 +32,19 @@
|
||||
#include "mission/devices/SyrlinksHkHandler.h"
|
||||
#include "mission/devices/MGMHandlerLIS3MDL.h"
|
||||
#include "mission/devices/MGMHandlerRM3100.h"
|
||||
#include "mission/devices/PlocHandler.h"
|
||||
#include "mission/devices/PlocMPSoCHandler.h"
|
||||
#include "mission/devices/PlocSupervisorHandler.h"
|
||||
#include "mission/devices/RadiationSensorHandler.h"
|
||||
#include "mission/devices/RwHandler.h"
|
||||
#include "mission/devices/StarTrackerHandler.h"
|
||||
#include "mission/devices/devicedefinitions/GomspaceDefinitions.h"
|
||||
#include "mission/devices/devicedefinitions/SyrlinksDefinitions.h"
|
||||
#include "mission/devices/devicedefinitions/PlocDefinitions.h"
|
||||
#include "mission/devices/devicedefinitions/PlocMPSoCDefinitions.h"
|
||||
#include "mission/devices/devicedefinitions/PlocSupervisorDefinitions.h"
|
||||
#include "mission/devices/devicedefinitions/RadSensorDefinitions.h"
|
||||
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
|
||||
#include "mission/devices/devicedefinitions/RwDefinitions.h"
|
||||
#include <mission/devices/devicedefinitions/StarTrackerDefinitions.h>
|
||||
#include "mission/utility/TmFunnel.h"
|
||||
#include "linux/obc/CCSDSIPCoreBridge.h"
|
||||
|
||||
@ -118,9 +122,11 @@ void ObjectFactory::produce(void* args){
|
||||
std::string("/dev/i2c-0"));
|
||||
new IMTQHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie);
|
||||
|
||||
UartCookie* plocUartCookie = new UartCookie(objects::RW1, std::string("/dev/ttyUL3"),
|
||||
UartModes::NON_CANONICAL, 115200, PLOC::MAX_REPLY_SIZE);
|
||||
new PlocHandler(objects::PLOC_HANDLER, objects::UART_COM_IF, plocUartCookie);
|
||||
#if ADD_PLOC_MPSOC == 1
|
||||
UartCookie* mpsocUartCookie = new UartCookie(objects::RW1, std::string("/dev/ttyUL3"),
|
||||
UartModes::NON_CANONICAL, 115200, PLOC_MPSOC::MAX_REPLY_SIZE);
|
||||
new PlocMPSoCHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, mpsocUartCookie);
|
||||
#endif /* ADD_PLOC_MPSOC */
|
||||
|
||||
createReactionWheelComponents(gpioComIF);
|
||||
#endif /* TE7020 != 0 */
|
||||
@ -134,6 +140,31 @@ void ObjectFactory::produce(void* args){
|
||||
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||
|
||||
new FileSystemHandler(objects::FILE_SYSTEM_HANDLER);
|
||||
|
||||
#if ADD_PLOC_MPSOC == 1
|
||||
UartCookie* plocMpsocCookie = new UartCookie(objects::RW1, std::string("/dev/ttyUL3"),
|
||||
UartModes::NON_CANONICAL, 115200, PLOC_MPSOC::MAX_REPLY_SIZE);
|
||||
new PlocMPSoCHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, plocMpsocCookie);
|
||||
#endif
|
||||
|
||||
#if OBSW_ADD_STAR_TRACKER == 1
|
||||
UartCookie* starTrackerCookie = new UartCookie(objects::START_TRACKER, std::string("/dev/ttyUL3"),
|
||||
UartModes::NON_CANONICAL, 115200, StarTracker::MAX_FRAME_SIZE* 2 + 2);
|
||||
starTrackerCookie->setNoFixedSizeReply();
|
||||
new StarTrackerHandler(objects::START_TRACKER, objects::UART_COM_IF, starTrackerCookie);
|
||||
#endif
|
||||
|
||||
#if ADD_PLOC_SUPERVISOR == 1
|
||||
/* Configuration for MIO0 on TE0720-03-1CFA */
|
||||
UartCookie* plocSupervisorCookie = new UartCookie(objects::PLOC_SUPERVISOR_HANDLER,
|
||||
std::string("/dev/ttyUL3"), UartModes::NON_CANONICAL, 115200,
|
||||
PLOC_SPV::MAX_REPLY_SIZE);
|
||||
PlocSupervisorHandler* plocSupervisor = new PlocSupervisorHandler(
|
||||
objects::PLOC_SUPERVISOR_HANDLER, objects::UART_COM_IF, plocSupervisorCookie);
|
||||
plocSupervisor->setStartUpImmediately();
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void ObjectFactory::createTmpComponents() {
|
||||
@ -477,9 +508,7 @@ void ObjectFactory::createSyrlinksComponents() {
|
||||
std::string("/dev/ttyUL0"), UartModes::NON_CANONICAL, 38400, SYRLINKS::MAX_REPLY_SIZE);
|
||||
syrlinksUartCookie->setParityEven();
|
||||
|
||||
SyrlinksHkHandler* syrlinksHkHandler = new SyrlinksHkHandler(objects::SYRLINKS_HK_HANDLER,
|
||||
objects::UART_COM_IF, syrlinksUartCookie);
|
||||
syrlinksHkHandler->setModeNormal();
|
||||
new SyrlinksHkHandler(objects::SYRLINKS_HK_HANDLER, objects::UART_COM_IF, syrlinksUartCookie);
|
||||
}
|
||||
|
||||
void ObjectFactory::createRtdComponents(LinuxLibgpioIF *gpioComIF) {
|
||||
@ -763,11 +792,11 @@ void ObjectFactory::createTestComponents() {
|
||||
|
||||
#if BOARD_TE0720 == 1 && TEST_PLOC_HANDLER == 1
|
||||
UartCookie* plocUartCookie = new UartCookie(std::string("/dev/ttyPS1"), 115200,
|
||||
PLOC::MAX_REPLY_SIZE);
|
||||
/* Testing PlocHandler on TE0720-03-1CFA */
|
||||
PlocHandler* plocHandler = new PlocHandler(objects::PLOC_HANDLER, objects::UART_COM_IF,
|
||||
PLOC_MPSOC::MAX_REPLY_SIZE);
|
||||
/* Testing PlocMPSoCHandler on TE0720-03-1CFA */
|
||||
PlocMPSoCHandler* mpsocPlocHandler = new PlocMPSoCHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF,
|
||||
plocUartCookie);
|
||||
plocHandler->setStartUpImmediately();
|
||||
mpsocPlocHandler->setStartUpImmediately();
|
||||
#endif
|
||||
|
||||
#if BOARD_TE0720 == 1 && TE0720_HEATER_TEST == 1
|
||||
@ -779,6 +808,17 @@ void ObjectFactory::createTestComponents() {
|
||||
pcduSwitches::TCS_BOARD_8V_HEATER_IN);
|
||||
#endif
|
||||
|
||||
#if TE0720 == 1 && ADD_PLOC_SUPERVISOR == 1
|
||||
/* Configuration for MIO0 on TE0720-03-1CFA */
|
||||
UartCookie* plocSupervisorCookie = new UartCookie(objects::PLOC_SUPERVISOR_HANDLER,
|
||||
std::string("/dev/ttyPS1"), UartModes::NON_CANONICAL, 115200,
|
||||
PLOC_SPV::MAX_REPLY_SIZE);
|
||||
PlocSupervisorHandler* plocSupervisor = new PlocSupervisorHandler(
|
||||
objects::PLOC_SUPERVISOR_HANDLER, objects::UART_COM_IF, plocSupervisorCookie);
|
||||
plocSupervisor->setStartUpImmediately();
|
||||
|
||||
#endif
|
||||
|
||||
#if Q7S_ADD_SPI_TEST == 1
|
||||
new SpiTestClass(objects::SPI_TEST, gpioComIF);
|
||||
#endif
|
||||
|
@ -1,8 +1,9 @@
|
||||
#include "obsw.h"
|
||||
#include "OBSWVersion.h"
|
||||
#include "OBSWConfig.h"
|
||||
#include "InitMission.h"
|
||||
#include "fsfw/tasks/TaskFactory.h"
|
||||
|
||||
#include "fsfw/tasks/TaskFactory.h"
|
||||
#include "fsfw/FSFWVersion.h"
|
||||
|
||||
#include <iostream>
|
||||
|
@ -14,7 +14,9 @@ enum commonClassIds: uint8_t {
|
||||
SYRLINKS_HANDLER, //SYRLINKS
|
||||
IMTQ_HANDLER, //IMTQ
|
||||
RW_HANDLER, //Reaction Wheels
|
||||
PLOC_HANDLER, //PLOC
|
||||
STR_HANDLER, //Star tracker
|
||||
PLOC_MPSOC_HANDLER, //PLOC MPSoC
|
||||
PLOC_SUPERVISOR_HANDLER, //PLOC Supervisor
|
||||
SUS_HANDLER, //SUSS
|
||||
CCSDS_IP_CORE_BRIDGE, // IP Core interface
|
||||
COMMON_CLASS_ID_END // [EXPORT] : [END]
|
||||
|
@ -34,7 +34,8 @@ enum commonObjects: uint32_t {
|
||||
GYRO_3_L3G_HANDLER = 0x44120313,
|
||||
|
||||
IMTQ_HANDLER = 0x44140014,
|
||||
PLOC_HANDLER = 0x44330015,
|
||||
PLOC_MPSOC_HANDLER = 0x44330015,
|
||||
PLOC_SUPERVISOR_HANDLER = 0x44330016,
|
||||
|
||||
/**
|
||||
* Not yet specified which pt1000 will measure which device/location in the satellite.
|
||||
@ -74,10 +75,12 @@ enum commonObjects: uint32_t {
|
||||
GPS0_HANDLER = 0x44130045,
|
||||
GPS1_HANDLER = 0x44130146,
|
||||
|
||||
RW1 = 0x44210001,
|
||||
RW2 = 0x44210002,
|
||||
RW3 = 0x44210003,
|
||||
RW4 = 0x44210004
|
||||
RW1 = 0x44120001,
|
||||
RW2 = 0x44120002,
|
||||
RW3 = 0x44120003,
|
||||
RW4 = 0x44120004,
|
||||
|
||||
START_TRACKER = 0x44130001
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -11,10 +11,12 @@ enum: uint8_t {
|
||||
PCDU_HANDLER = 108,
|
||||
HEATER_HANDLER = 109,
|
||||
SA_DEPL_HANDLER = 110,
|
||||
PLOC_HANDLER = 111,
|
||||
PLOC_MPSOC_HANDLER = 111,
|
||||
IMTQ_HANDLER = 112,
|
||||
RW_HANDLER = 113,
|
||||
FILE_SYSTEM = 114,
|
||||
STR_HANDLER = 114,
|
||||
PLOC_SUPERVISOR_HANDLER = 115,
|
||||
FILE_SYSTEM = 116,
|
||||
COMMON_SUBSYSTEM_ID_END
|
||||
};
|
||||
}
|
||||
|
@ -77,10 +77,10 @@
|
||||
8901;CLOCK_SET_FAILURE;LOW; ;../../fsfw/pus/Service9TimeManagement.h
|
||||
9700;TEST;INFO; ;../../fsfw/pus/Service17Test.h
|
||||
10600;CHANGE_OF_SETUP_PARAMETER;LOW; ;../../mission/devices/MGMHandlerLIS3MDL.h
|
||||
11101;MEMORY_READ_RPT_CRC_FAILURE;LOW; ;../../mission/devices/PlocHandler.h
|
||||
11102;ACK_FAILURE;LOW; ;../../mission/devices/PlocHandler.h
|
||||
11103;EXE_FAILURE;LOW; ;../../mission/devices/PlocHandler.h
|
||||
11104;CRC_FAILURE_EVENT;LOW; ;../../mission/devices/PlocHandler.h
|
||||
11101;MEMORY_READ_RPT_CRC_FAILURE;LOW; ;../../mission/devices/PlocMPSoCHandler.h
|
||||
11102;ACK_FAILURE;LOW; ;../../mission/devices/PlocMPSoCHandler.h
|
||||
11103;EXE_FAILURE;LOW; ;../../mission/devices/PlocMPSoCHandler.h
|
||||
11104;CRC_FAILURE_EVENT;LOW; ;../../mission/devices/PlocMPSoCHandler.h
|
||||
11201;SELF_TEST_I2C_FAILURE;LOW; ;../../mission/devices/IMTQHandler.h
|
||||
11202;SELF_TEST_SPI_FAILURE;LOW; ;../../mission/devices/IMTQHandler.h
|
||||
11203;SELF_TEST_ADC_FAILURE;LOW; ;../../mission/devices/IMTQHandler.h
|
||||
@ -90,3 +90,7 @@
|
||||
11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW; ;../../mission/devices/IMTQHandler.h
|
||||
11208;INVALID_ERROR_BYTE;LOW; ;../../mission/devices/IMTQHandler.h
|
||||
11301;ERROR_STATE;HIGH; ;../../mission/devices/RwHandler.h
|
||||
11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW; ;../../mission/devices/PlocSupervisorHandler.h
|
||||
11502;SUPV_ACK_FAILURE;LOW; ;../../mission/devices/PlocSupervisorHandler.h
|
||||
11503;SUPV_EXE_FAILURE;LOW; ;../../mission/devices/PlocSupervisorHandler.h
|
||||
11504;SUPV_CRC_FAILURE_EVENT;LOW; ;../../mission/devices/PlocSupervisorHandler.h
|
||||
|
|
@ -2,6 +2,10 @@
|
||||
0x43000003;CORE_CONTROLLER
|
||||
0x43100002;ACS_CONTROLLER
|
||||
0x43400001;THERMAL_CONTROLLER
|
||||
0x44120001;RW1
|
||||
0x44120002;RW2
|
||||
0x44120003;RW3
|
||||
0x44120004;RW4
|
||||
0x44120006;MGM_0_LIS3_HANDLER
|
||||
0x44120010;GYRO_0_ADIS_HANDLER
|
||||
0x44120032;SUS_1
|
||||
@ -23,20 +27,18 @@
|
||||
0x44120212;GYRO_2_ADIS_HANDLER
|
||||
0x44120309;MGM_3_RM3100_HANDLER
|
||||
0x44120313;GYRO_3_L3G_HANDLER
|
||||
0x44130001;START_TRACKER
|
||||
0x44130045;GPS0_HANDLER
|
||||
0x44130146;GPS1_HANDLER
|
||||
0x44140014;IMTQ_HANDLER
|
||||
0x442000A1;PCDU_HANDLER
|
||||
0x44210001;RW1
|
||||
0x44210002;RW2
|
||||
0x44210003;RW3
|
||||
0x44210004;RW4
|
||||
0x44250000;P60DOCK_HANDLER
|
||||
0x44250001;PDU1_HANDLER
|
||||
0x44250002;PDU2_HANDLER
|
||||
0x44250003;ACU_HANDLER
|
||||
0x443200A5;RAD_SENSOR
|
||||
0x44330015;PLOC_HANDLER
|
||||
0x44330015;PLOC_MPSOC_HANDLER
|
||||
0x44330016;PLOC_SUPERVISOR_HANDLER
|
||||
0x444100A2;SOLAR_ARRAY_DEPL_HANDLER
|
||||
0x444100A4;HEATER_HANDLER
|
||||
0x44420004;TMP1075_HANDLER_1
|
||||
|
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 92 translations.
|
||||
* @brief Auto-generated event translation file. Contains 96 translations.
|
||||
* @details
|
||||
* Generated on: 2021-06-29 16:20:09
|
||||
* Generated on: 2021-07-12 15:20:38
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -97,6 +97,10 @@ const char *SELF_TEST_MTM_RANGE_FAILURE_STRING = "SELF_TEST_MTM_RANGE_FAILURE";
|
||||
const char *SELF_TEST_COIL_CURRENT_FAILURE_STRING = "SELF_TEST_COIL_CURRENT_FAILURE";
|
||||
const char *INVALID_ERROR_BYTE_STRING = "INVALID_ERROR_BYTE";
|
||||
const char *ERROR_STATE_STRING = "ERROR_STATE";
|
||||
const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_FAILURE";
|
||||
const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE";
|
||||
const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
|
||||
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
|
||||
|
||||
const char * translateEvents(Event event) {
|
||||
switch( (event & 0xffff) ) {
|
||||
@ -284,6 +288,14 @@ const char * translateEvents(Event event) {
|
||||
return INVALID_ERROR_BYTE_STRING;
|
||||
case(11301):
|
||||
return ERROR_STATE_STRING;
|
||||
case(11501):
|
||||
return SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING;
|
||||
case(11502):
|
||||
return SUPV_ACK_FAILURE_STRING;
|
||||
case(11503):
|
||||
return SUPV_EXE_FAILURE_STRING;
|
||||
case(11504):
|
||||
return SUPV_CRC_FAILURE_EVENT_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 100 translations.
|
||||
* Generated on: 2021-06-29 16:19:57
|
||||
* Contains 102 translations.
|
||||
* Generated on: 2021-07-10 16:22:55
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@ -10,6 +10,10 @@ const char *P60DOCK_TEST_TASK_STRING = "P60DOCK_TEST_TASK";
|
||||
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
|
||||
const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
|
||||
const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER";
|
||||
const char *RW1_STRING = "RW1";
|
||||
const char *RW2_STRING = "RW2";
|
||||
const char *RW3_STRING = "RW3";
|
||||
const char *RW4_STRING = "RW4";
|
||||
const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER";
|
||||
const char *GYRO_0_ADIS_HANDLER_STRING = "GYRO_0_ADIS_HANDLER";
|
||||
const char *SUS_1_STRING = "SUS_1";
|
||||
@ -31,20 +35,18 @@ const char *MGM_2_LIS3_HANDLER_STRING = "MGM_2_LIS3_HANDLER";
|
||||
const char *GYRO_2_ADIS_HANDLER_STRING = "GYRO_2_ADIS_HANDLER";
|
||||
const char *MGM_3_RM3100_HANDLER_STRING = "MGM_3_RM3100_HANDLER";
|
||||
const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER";
|
||||
const char *START_TRACKER_STRING = "START_TRACKER";
|
||||
const char *GPS0_HANDLER_STRING = "GPS0_HANDLER";
|
||||
const char *GPS1_HANDLER_STRING = "GPS1_HANDLER";
|
||||
const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER";
|
||||
const char *PCDU_HANDLER_STRING = "PCDU_HANDLER";
|
||||
const char *RW1_STRING = "RW1";
|
||||
const char *RW2_STRING = "RW2";
|
||||
const char *RW3_STRING = "RW3";
|
||||
const char *RW4_STRING = "RW4";
|
||||
const char *P60DOCK_HANDLER_STRING = "P60DOCK_HANDLER";
|
||||
const char *PDU1_HANDLER_STRING = "PDU1_HANDLER";
|
||||
const char *PDU2_HANDLER_STRING = "PDU2_HANDLER";
|
||||
const char *ACU_HANDLER_STRING = "ACU_HANDLER";
|
||||
const char *RAD_SENSOR_STRING = "RAD_SENSOR";
|
||||
const char *PLOC_HANDLER_STRING = "PLOC_HANDLER";
|
||||
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
|
||||
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
|
||||
const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER";
|
||||
const char *HEATER_HANDLER_STRING = "HEATER_HANDLER";
|
||||
const char *TMP1075_HANDLER_1_STRING = "TMP1075_HANDLER_1";
|
||||
@ -117,6 +119,14 @@ const char* translateObject(object_id_t object) {
|
||||
return ACS_CONTROLLER_STRING;
|
||||
case 0x43400001:
|
||||
return THERMAL_CONTROLLER_STRING;
|
||||
case 0x44120001:
|
||||
return RW1_STRING;
|
||||
case 0x44120002:
|
||||
return RW2_STRING;
|
||||
case 0x44120003:
|
||||
return RW3_STRING;
|
||||
case 0x44120004:
|
||||
return RW4_STRING;
|
||||
case 0x44120006:
|
||||
return MGM_0_LIS3_HANDLER_STRING;
|
||||
case 0x44120010:
|
||||
@ -159,6 +169,8 @@ const char* translateObject(object_id_t object) {
|
||||
return MGM_3_RM3100_HANDLER_STRING;
|
||||
case 0x44120313:
|
||||
return GYRO_3_L3G_HANDLER_STRING;
|
||||
case 0x44130001:
|
||||
return START_TRACKER_STRING;
|
||||
case 0x44130045:
|
||||
return GPS0_HANDLER_STRING;
|
||||
case 0x44130146:
|
||||
@ -167,14 +179,6 @@ const char* translateObject(object_id_t object) {
|
||||
return IMTQ_HANDLER_STRING;
|
||||
case 0x442000A1:
|
||||
return PCDU_HANDLER_STRING;
|
||||
case 0x44210001:
|
||||
return RW1_STRING;
|
||||
case 0x44210002:
|
||||
return RW2_STRING;
|
||||
case 0x44210003:
|
||||
return RW3_STRING;
|
||||
case 0x44210004:
|
||||
return RW4_STRING;
|
||||
case 0x44250000:
|
||||
return P60DOCK_HANDLER_STRING;
|
||||
case 0x44250001:
|
||||
@ -186,7 +190,9 @@ const char* translateObject(object_id_t object) {
|
||||
case 0x443200A5:
|
||||
return RAD_SENSOR_STRING;
|
||||
case 0x44330015:
|
||||
return PLOC_HANDLER_STRING;
|
||||
return PLOC_MPSOC_HANDLER_STRING;
|
||||
case 0x44330016:
|
||||
return PLOC_SUPERVISOR_HANDLER_STRING;
|
||||
case 0x444100A2:
|
||||
return SOLAR_ARRAY_DEPL_HANDLER_STRING;
|
||||
case 0x444100A4:
|
||||
|
@ -72,6 +72,6 @@ static constexpr size_t FSFW_MAX_TM_PACKET_SIZE = 2048;
|
||||
|
||||
}
|
||||
|
||||
#define FSFW_HAL_LINUX_SPI_WIRETAPPING 0
|
||||
#define FSFW_HAL_LINUX_SPI_WIRETAPPING 1
|
||||
|
||||
#endif /* CONFIG_FSFWCONFIG_H_ */
|
||||
|
@ -21,13 +21,16 @@ debugging. */
|
||||
#define OBSW_ADD_TEST_CODE 1
|
||||
#define OBSW_ADD_TEST_PST 1
|
||||
#define OBSW_ADD_GPS 0
|
||||
#define OBSW_ADD_STAR_TRACKER 0
|
||||
|
||||
#define TEST_LIBGPIOD 0
|
||||
#define TEST_RADIATION_SENSOR_HANDLER 0
|
||||
#define TEST_SUS_HANDLER 1
|
||||
#define TEST_SUS_HANDLER 0
|
||||
#define TEST_PLOC_HANDLER 0
|
||||
#define TEST_CCSDS_BRIDGE 0
|
||||
#define PERFORM_PTME_TEST 0
|
||||
#define ADD_PLOC_SUPERVISOR 1
|
||||
#define ADD_PLOC_MPSOC 0
|
||||
|
||||
#define BOARD_TE0720 0
|
||||
#define TE0720_HEATER_TEST 0
|
||||
@ -40,11 +43,14 @@ debugging. */
|
||||
#define IMQT_DEBUG 0
|
||||
#define ADIS16507_DEBUG 1
|
||||
#define L3GD20_GYRO_DEBUG 0
|
||||
#define DEBUG_RAD_SENSOR 1
|
||||
#define DEBUG_RAD_SENSOR 0
|
||||
#define DEBUG_SUS 1
|
||||
#define DEBUG_RTD 1
|
||||
#define IMTQ_DEBUG 1
|
||||
#define RW_DEBUG 1
|
||||
#define RW_DEBUG 0
|
||||
#define START_TRACKER_DEBUG 0
|
||||
#define PLOC_MPSOC_DEBUG 0
|
||||
#define PLOC_SUPERVISOR_DEBUG 1
|
||||
|
||||
// Leave at one as the BSP is linux. Used by the ADIS16507 device handler
|
||||
#define OBSW_ADIS16507_LINUX_COM_IF 1
|
||||
@ -52,7 +58,7 @@ debugging. */
|
||||
#include "OBSWVersion.h"
|
||||
|
||||
/* Can be used to switch device to NORMAL mode immediately */
|
||||
#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 0
|
||||
#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 92 translations.
|
||||
* @brief Auto-generated event translation file. Contains 96 translations.
|
||||
* @details
|
||||
* Generated on: 2021-06-29 16:20:09
|
||||
* Generated on: 2021-07-12 15:20:38
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -97,6 +97,10 @@ const char *SELF_TEST_MTM_RANGE_FAILURE_STRING = "SELF_TEST_MTM_RANGE_FAILURE";
|
||||
const char *SELF_TEST_COIL_CURRENT_FAILURE_STRING = "SELF_TEST_COIL_CURRENT_FAILURE";
|
||||
const char *INVALID_ERROR_BYTE_STRING = "INVALID_ERROR_BYTE";
|
||||
const char *ERROR_STATE_STRING = "ERROR_STATE";
|
||||
const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_FAILURE";
|
||||
const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE";
|
||||
const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
|
||||
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
|
||||
|
||||
const char * translateEvents(Event event) {
|
||||
switch( (event & 0xffff) ) {
|
||||
@ -284,6 +288,14 @@ const char * translateEvents(Event event) {
|
||||
return INVALID_ERROR_BYTE_STRING;
|
||||
case(11301):
|
||||
return ERROR_STATE_STRING;
|
||||
case(11501):
|
||||
return SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING;
|
||||
case(11502):
|
||||
return SUPV_ACK_FAILURE_STRING;
|
||||
case(11503):
|
||||
return SUPV_EXE_FAILURE_STRING;
|
||||
case(11504):
|
||||
return SUPV_CRC_FAILURE_EVENT_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 100 translations.
|
||||
* Generated on: 2021-06-29 16:19:57
|
||||
* Contains 102 translations.
|
||||
* Generated on: 2021-07-10 16:22:55
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@ -10,6 +10,10 @@ const char *P60DOCK_TEST_TASK_STRING = "P60DOCK_TEST_TASK";
|
||||
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
|
||||
const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
|
||||
const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER";
|
||||
const char *RW1_STRING = "RW1";
|
||||
const char *RW2_STRING = "RW2";
|
||||
const char *RW3_STRING = "RW3";
|
||||
const char *RW4_STRING = "RW4";
|
||||
const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER";
|
||||
const char *GYRO_0_ADIS_HANDLER_STRING = "GYRO_0_ADIS_HANDLER";
|
||||
const char *SUS_1_STRING = "SUS_1";
|
||||
@ -31,20 +35,18 @@ const char *MGM_2_LIS3_HANDLER_STRING = "MGM_2_LIS3_HANDLER";
|
||||
const char *GYRO_2_ADIS_HANDLER_STRING = "GYRO_2_ADIS_HANDLER";
|
||||
const char *MGM_3_RM3100_HANDLER_STRING = "MGM_3_RM3100_HANDLER";
|
||||
const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER";
|
||||
const char *START_TRACKER_STRING = "START_TRACKER";
|
||||
const char *GPS0_HANDLER_STRING = "GPS0_HANDLER";
|
||||
const char *GPS1_HANDLER_STRING = "GPS1_HANDLER";
|
||||
const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER";
|
||||
const char *PCDU_HANDLER_STRING = "PCDU_HANDLER";
|
||||
const char *RW1_STRING = "RW1";
|
||||
const char *RW2_STRING = "RW2";
|
||||
const char *RW3_STRING = "RW3";
|
||||
const char *RW4_STRING = "RW4";
|
||||
const char *P60DOCK_HANDLER_STRING = "P60DOCK_HANDLER";
|
||||
const char *PDU1_HANDLER_STRING = "PDU1_HANDLER";
|
||||
const char *PDU2_HANDLER_STRING = "PDU2_HANDLER";
|
||||
const char *ACU_HANDLER_STRING = "ACU_HANDLER";
|
||||
const char *RAD_SENSOR_STRING = "RAD_SENSOR";
|
||||
const char *PLOC_HANDLER_STRING = "PLOC_HANDLER";
|
||||
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
|
||||
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
|
||||
const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER";
|
||||
const char *HEATER_HANDLER_STRING = "HEATER_HANDLER";
|
||||
const char *TMP1075_HANDLER_1_STRING = "TMP1075_HANDLER_1";
|
||||
@ -117,6 +119,14 @@ const char* translateObject(object_id_t object) {
|
||||
return ACS_CONTROLLER_STRING;
|
||||
case 0x43400001:
|
||||
return THERMAL_CONTROLLER_STRING;
|
||||
case 0x44120001:
|
||||
return RW1_STRING;
|
||||
case 0x44120002:
|
||||
return RW2_STRING;
|
||||
case 0x44120003:
|
||||
return RW3_STRING;
|
||||
case 0x44120004:
|
||||
return RW4_STRING;
|
||||
case 0x44120006:
|
||||
return MGM_0_LIS3_HANDLER_STRING;
|
||||
case 0x44120010:
|
||||
@ -159,6 +169,8 @@ const char* translateObject(object_id_t object) {
|
||||
return MGM_3_RM3100_HANDLER_STRING;
|
||||
case 0x44120313:
|
||||
return GYRO_3_L3G_HANDLER_STRING;
|
||||
case 0x44130001:
|
||||
return START_TRACKER_STRING;
|
||||
case 0x44130045:
|
||||
return GPS0_HANDLER_STRING;
|
||||
case 0x44130146:
|
||||
@ -167,14 +179,6 @@ const char* translateObject(object_id_t object) {
|
||||
return IMTQ_HANDLER_STRING;
|
||||
case 0x442000A1:
|
||||
return PCDU_HANDLER_STRING;
|
||||
case 0x44210001:
|
||||
return RW1_STRING;
|
||||
case 0x44210002:
|
||||
return RW2_STRING;
|
||||
case 0x44210003:
|
||||
return RW3_STRING;
|
||||
case 0x44210004:
|
||||
return RW4_STRING;
|
||||
case 0x44250000:
|
||||
return P60DOCK_HANDLER_STRING;
|
||||
case 0x44250001:
|
||||
@ -186,7 +190,9 @@ const char* translateObject(object_id_t object) {
|
||||
case 0x443200A5:
|
||||
return RAD_SENSOR_STRING;
|
||||
case 0x44330015:
|
||||
return PLOC_HANDLER_STRING;
|
||||
return PLOC_MPSOC_HANDLER_STRING;
|
||||
case 0x44330016:
|
||||
return PLOC_SUPERVISOR_HANDLER_STRING;
|
||||
case 0x444100A2:
|
||||
return SOLAR_ARRAY_DEPL_HANDLER_STRING;
|
||||
case 0x444100A4:
|
||||
|
@ -449,8 +449,32 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) {
|
||||
// Length of a communication cycle
|
||||
uint32_t length = thisSequence->getPeriodMs();
|
||||
|
||||
thisSequence->addSlot(objects::PLOC_HANDLER, length * 0,
|
||||
#if ADD_PLOC_MPSOC == 1
|
||||
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.2,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.4,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.6,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.8,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
#endif
|
||||
|
||||
#if ADD_PLOC_SUPERVISOR == 1
|
||||
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.2,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.4,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.6,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.8,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
#endif
|
||||
|
||||
#if Q7S_ADD_SYRLINKS_HANDLER == 1
|
||||
thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
@ -462,12 +486,9 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) {
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
#endif
|
||||
|
||||
thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.2,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
#if Q7S_ADD_SYRLINKS_HANDLER == 1
|
||||
thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.2,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
#endif
|
||||
|
||||
#if OBSW_ADD_ACS_BOARD == 1
|
||||
thisSequence->addSlot(objects::GPS0_HANDLER, length * 0.2,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
@ -475,8 +496,6 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) {
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
#endif
|
||||
|
||||
thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.4,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
#if Q7S_ADD_SYRLINKS_HANDLER == 1
|
||||
thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.4,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
@ -488,8 +507,6 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) {
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
#endif
|
||||
|
||||
thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.6,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
#if Q7S_ADD_SYRLINKS_HANDLER == 1
|
||||
thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.6,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
@ -501,8 +518,6 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) {
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
#endif
|
||||
|
||||
thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.8,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
#if Q7S_ADD_SYRLINKS_HANDLER == 1
|
||||
thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.8,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
@ -514,6 +529,14 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) {
|
||||
DeviceHandlerIF::GET_READ);
|
||||
#endif
|
||||
|
||||
#if OBSW_ADD_STAR_TRACKER == 1
|
||||
thisSequence->addSlot(objects::START_TRACKER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::START_TRACKER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::START_TRACKER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::START_TRACKER, length * 0.6, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::START_TRACKER, length * 0.8, DeviceHandlerIF::GET_READ);
|
||||
#endif
|
||||
|
||||
if (thisSequence->checkSequence() != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "UART PST initialization failed" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
@ -684,12 +707,12 @@ ReturnValue_t pst::pstTest(FixedTimeslotTaskIF* thisSequence) {
|
||||
ReturnValue_t pst::pollingSequenceTE0720(FixedTimeslotTaskIF *thisSequence) {
|
||||
uint32_t length = thisSequence->getPeriodMs();
|
||||
|
||||
#if TEST_PLOC_HANDLER == 1
|
||||
thisSequence->addSlot(objects::PLOC_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::PLOC_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
|
||||
#if TEST_PLOC_MPSOC_HANDLER == 1
|
||||
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
|
||||
#endif
|
||||
|
||||
#if TEST_RADIATION_SENSOR_HANDLER == 1
|
||||
@ -723,6 +746,14 @@ ReturnValue_t pst::pollingSequenceTE0720(FixedTimeslotTaskIF *thisSequence) {
|
||||
thisSequence->addSlot(objects::SUS_1, length * 0.915, DeviceHandlerIF::GET_READ);
|
||||
#endif
|
||||
|
||||
#if ADD_PLOC_SUPERVISOR == 1
|
||||
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
|
||||
#endif
|
||||
|
||||
if (thisSequence->checkSequence() != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "Initialization of TE0720 PST failed" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
|
@ -55,7 +55,7 @@ ReturnValue_t pstI2c(FixedTimeslotTaskIF* thisSequence);
|
||||
*/
|
||||
ReturnValue_t pstTest(FixedTimeslotTaskIF* thisSequence);
|
||||
|
||||
#if TE7020 == 1
|
||||
#if TE0720 == 1
|
||||
/**
|
||||
* @brief This polling sequence will be created when the software is compiled for the TE0720.
|
||||
*/
|
||||
|
@ -12,10 +12,12 @@ target_sources(${TARGET_NAME} PUBLIC
|
||||
SyrlinksHkHandler.cpp
|
||||
Max31865PT1000Handler.cpp
|
||||
IMTQHandler.cpp
|
||||
PlocHandler.cpp
|
||||
PlocMPSoCHandler.cpp
|
||||
PlocSupervisorHandler.cpp
|
||||
RadiationSensorHandler.cpp
|
||||
GyroADIS16507Handler.cpp
|
||||
RwHandler.cpp
|
||||
StarTrackerHandler.cpp
|
||||
)
|
||||
|
||||
|
||||
|
@ -1,66 +1,66 @@
|
||||
#include "PlocHandler.h"
|
||||
#include "PlocMPSoCHandler.h"
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
#include <fsfw/globalfunctions/CRC.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
|
||||
PlocHandler::PlocHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) :
|
||||
PlocMPSoCHandler::PlocMPSoCHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) :
|
||||
DeviceHandlerBase(objectId, comIF, comCookie) {
|
||||
if (comCookie == NULL) {
|
||||
sif::error << "PlocHandler: Invalid com cookie" << std::endl;
|
||||
sif::error << "PlocMPSoCHandler: Invalid com cookie" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
PlocHandler::~PlocHandler() {
|
||||
PlocMPSoCHandler::~PlocMPSoCHandler() {
|
||||
}
|
||||
|
||||
|
||||
void PlocHandler::doStartUp(){
|
||||
void PlocMPSoCHandler::doStartUp(){
|
||||
if(mode == _MODE_START_UP){
|
||||
setMode(MODE_ON);
|
||||
}
|
||||
}
|
||||
|
||||
void PlocHandler::doShutDown(){
|
||||
void PlocMPSoCHandler::doShutDown(){
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::buildNormalDeviceCommand(
|
||||
ReturnValue_t PlocMPSoCHandler::buildNormalDeviceCommand(
|
||||
DeviceCommandId_t * id) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::buildTransitionDeviceCommand(
|
||||
ReturnValue_t PlocMPSoCHandler::buildTransitionDeviceCommand(
|
||||
DeviceCommandId_t * id){
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::buildCommandFromCommand(
|
||||
ReturnValue_t PlocMPSoCHandler::buildCommandFromCommand(
|
||||
DeviceCommandId_t deviceCommand, const uint8_t * commandData,
|
||||
size_t commandDataLen) {
|
||||
switch(deviceCommand) {
|
||||
case(PLOC::TC_MEM_WRITE): {
|
||||
case(PLOC_MPSOC::TC_MEM_WRITE): {
|
||||
return prepareTcMemWriteCommand(commandData, commandDataLen);
|
||||
}
|
||||
case(PLOC::TC_MEM_READ): {
|
||||
case(PLOC_MPSOC::TC_MEM_READ): {
|
||||
return prepareTcMemReadCommand(commandData, commandDataLen);
|
||||
}
|
||||
default:
|
||||
sif::debug << "PlocHandler::buildCommandFromCommand: Command not implemented" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::buildCommandFromCommand: Command not implemented" << std::endl;
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
void PlocHandler::fillCommandAndReplyMap() {
|
||||
this->insertInCommandMap(PLOC::TC_MEM_WRITE);
|
||||
this->insertInCommandMap(PLOC::TC_MEM_READ);
|
||||
this->insertInReplyMap(PLOC::ACK_REPORT, 1, nullptr, PLOC::SIZE_ACK_REPORT);
|
||||
this->insertInReplyMap(PLOC::EXE_REPORT, 3, nullptr, PLOC::SIZE_EXE_REPORT);
|
||||
this->insertInReplyMap(PLOC::TM_MEMORY_READ_REPORT, 2, nullptr, PLOC::SIZE_TM_MEM_READ_REPORT);
|
||||
void PlocMPSoCHandler::fillCommandAndReplyMap() {
|
||||
this->insertInCommandMap(PLOC_MPSOC::TC_MEM_WRITE);
|
||||
this->insertInCommandMap(PLOC_MPSOC::TC_MEM_READ);
|
||||
this->insertInReplyMap(PLOC_MPSOC::ACK_REPORT, 1, nullptr, PLOC_MPSOC::SIZE_ACK_REPORT);
|
||||
this->insertInReplyMap(PLOC_MPSOC::EXE_REPORT, 3, nullptr, PLOC_MPSOC::SIZE_EXE_REPORT);
|
||||
this->insertInReplyMap(PLOC_MPSOC::TM_MEMORY_READ_REPORT, 2, nullptr, PLOC_MPSOC::SIZE_TM_MEM_READ_REPORT);
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::scanForReply(const uint8_t *start,
|
||||
ReturnValue_t PlocMPSoCHandler::scanForReply(const uint8_t *start,
|
||||
size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
@ -68,28 +68,28 @@ ReturnValue_t PlocHandler::scanForReply(const uint8_t *start,
|
||||
uint16_t apid = (*(start) << 8 | *(start + 1)) & APID_MASK;
|
||||
|
||||
switch(apid) {
|
||||
case(PLOC::APID_ACK_SUCCESS):
|
||||
*foundLen = PLOC::SIZE_ACK_REPORT;
|
||||
*foundId = PLOC::ACK_REPORT;
|
||||
case(PLOC_MPSOC::APID_ACK_SUCCESS):
|
||||
*foundLen = PLOC_MPSOC::SIZE_ACK_REPORT;
|
||||
*foundId = PLOC_MPSOC::ACK_REPORT;
|
||||
break;
|
||||
case(PLOC::APID_ACK_FAILURE):
|
||||
*foundLen = PLOC::SIZE_ACK_REPORT;
|
||||
*foundId = PLOC::ACK_REPORT;
|
||||
case(PLOC_MPSOC::APID_ACK_FAILURE):
|
||||
*foundLen = PLOC_MPSOC::SIZE_ACK_REPORT;
|
||||
*foundId = PLOC_MPSOC::ACK_REPORT;
|
||||
break;
|
||||
case(PLOC::APID_TM_MEMORY_READ_REPORT):
|
||||
*foundLen = PLOC::SIZE_TM_MEM_READ_REPORT;
|
||||
*foundId = PLOC::TM_MEMORY_READ_REPORT;
|
||||
case(PLOC_MPSOC::APID_TM_MEMORY_READ_REPORT):
|
||||
*foundLen = PLOC_MPSOC::SIZE_TM_MEM_READ_REPORT;
|
||||
*foundId = PLOC_MPSOC::TM_MEMORY_READ_REPORT;
|
||||
break;
|
||||
case(PLOC::APID_EXE_SUCCESS):
|
||||
*foundLen = PLOC::SIZE_EXE_REPORT;
|
||||
*foundId = PLOC::EXE_REPORT;
|
||||
case(PLOC_MPSOC::APID_EXE_SUCCESS):
|
||||
*foundLen = PLOC_MPSOC::SIZE_EXE_REPORT;
|
||||
*foundId = PLOC_MPSOC::EXE_REPORT;
|
||||
break;
|
||||
case(PLOC::APID_EXE_FAILURE):
|
||||
*foundLen = PLOC::SIZE_EXE_REPORT;
|
||||
*foundId = PLOC::EXE_REPORT;
|
||||
case(PLOC_MPSOC::APID_EXE_FAILURE):
|
||||
*foundLen = PLOC_MPSOC::SIZE_EXE_REPORT;
|
||||
*foundId = PLOC_MPSOC::EXE_REPORT;
|
||||
break;
|
||||
default: {
|
||||
sif::debug << "PlocHandler::scanForReply: Reply has invalid apid" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::scanForReply: Reply has invalid apid" << std::endl;
|
||||
*foundLen = remainingSize;
|
||||
return INVALID_APID;
|
||||
}
|
||||
@ -104,26 +104,26 @@ ReturnValue_t PlocHandler::scanForReply(const uint8_t *start,
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
ReturnValue_t PlocMPSoCHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
switch (id) {
|
||||
case PLOC::ACK_REPORT: {
|
||||
case PLOC_MPSOC::ACK_REPORT: {
|
||||
result = handleAckReport(packet);
|
||||
break;
|
||||
}
|
||||
case (PLOC::TM_MEMORY_READ_REPORT): {
|
||||
case (PLOC_MPSOC::TM_MEMORY_READ_REPORT): {
|
||||
result = handleMemoryReadReport(packet);
|
||||
break;
|
||||
}
|
||||
case (PLOC::EXE_REPORT): {
|
||||
case (PLOC_MPSOC::EXE_REPORT): {
|
||||
result = handleExecutionReport(packet);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "PlocHandler::interpretDeviceReply: Unknown device reply id" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::interpretDeviceReply: Unknown device reply id" << std::endl;
|
||||
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
|
||||
}
|
||||
}
|
||||
@ -131,62 +131,62 @@ ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
return result;
|
||||
}
|
||||
|
||||
void PlocHandler::setNormalDatapoolEntriesInvalid(){
|
||||
void PlocMPSoCHandler::setNormalDatapoolEntriesInvalid(){
|
||||
|
||||
}
|
||||
|
||||
uint32_t PlocHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){
|
||||
uint32_t PlocMPSoCHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){
|
||||
return 500;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
ReturnValue_t PlocMPSoCHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) {
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void PlocHandler::setModeNormal() {
|
||||
void PlocMPSoCHandler::setModeNormal() {
|
||||
mode = MODE_NORMAL;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::prepareTcMemWriteCommand(const uint8_t * commandData,
|
||||
ReturnValue_t PlocMPSoCHandler::prepareTcMemWriteCommand(const uint8_t * commandData,
|
||||
size_t commandDataLen) {
|
||||
const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16
|
||||
| *(commandData + 2) << 8 | *(commandData + 3);
|
||||
const uint32_t memoryData = *(commandData + 4) << 24 | *(commandData + 5) << 16
|
||||
| *(commandData + 6) << 8 | *(commandData + 7);
|
||||
packetSequenceCount = (packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK;
|
||||
PLOC::TcMemWrite tcMemWrite(memoryAddress, memoryData, packetSequenceCount);
|
||||
if (tcMemWrite.getFullSize() > PLOC::MAX_COMMAND_SIZE) {
|
||||
sif::debug << "PlocHandler::prepareTcMemWriteCommand: Command too big" << std::endl;
|
||||
PLOC_MPSOC::TcMemWrite tcMemWrite(memoryAddress, memoryData, packetSequenceCount);
|
||||
if (tcMemWrite.getFullSize() > PLOC_MPSOC::MAX_COMMAND_SIZE) {
|
||||
sif::debug << "PlocMPSoCHandler::prepareTcMemWriteCommand: Command too big" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
memcpy(commandBuffer, tcMemWrite.getWholeData(), tcMemWrite.getFullSize());
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = tcMemWrite.getFullSize();
|
||||
nextReplyId = PLOC::ACK_REPORT;
|
||||
nextReplyId = PLOC_MPSOC::ACK_REPORT;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::prepareTcMemReadCommand(const uint8_t * commandData,
|
||||
ReturnValue_t PlocMPSoCHandler::prepareTcMemReadCommand(const uint8_t * commandData,
|
||||
size_t commandDataLen) {
|
||||
const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16
|
||||
| *(commandData + 2) << 8 | *(commandData + 3);
|
||||
packetSequenceCount = (packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK;
|
||||
PLOC::TcMemRead tcMemRead(memoryAddress, packetSequenceCount);
|
||||
if (tcMemRead.getFullSize() > PLOC::MAX_COMMAND_SIZE) {
|
||||
sif::debug << "PlocHandler::prepareTcMemReadCommand: Command too big" << std::endl;
|
||||
PLOC_MPSOC::TcMemRead tcMemRead(memoryAddress, packetSequenceCount);
|
||||
if (tcMemRead.getFullSize() > PLOC_MPSOC::MAX_COMMAND_SIZE) {
|
||||
sif::debug << "PlocMPSoCHandler::prepareTcMemReadCommand: Command too big" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
memcpy(commandBuffer, tcMemRead.getWholeData(), tcMemRead.getFullSize());
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = tcMemRead.getFullSize();
|
||||
nextReplyId = PLOC::ACK_REPORT;
|
||||
nextReplyId = PLOC_MPSOC::ACK_REPORT;
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t foundLen) {
|
||||
ReturnValue_t PlocMPSoCHandler::verifyPacket(const uint8_t* start, size_t foundLen) {
|
||||
|
||||
uint16_t receivedCrc = *(start + foundLen - 2) << 8 | *(start + foundLen - 1);
|
||||
|
||||
@ -199,17 +199,17 @@ ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t foundLen) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::handleAckReport(const uint8_t* data) {
|
||||
ReturnValue_t PlocMPSoCHandler::handleAckReport(const uint8_t* data) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
result = verifyPacket(data, PLOC::SIZE_ACK_REPORT);
|
||||
result = verifyPacket(data, PLOC_MPSOC::SIZE_ACK_REPORT);
|
||||
if(result == CRC_FAILURE) {
|
||||
sif::error << "PlocHandler::handleAckReport: CRC failure" << std::endl;
|
||||
nextReplyId = PLOC::NONE;
|
||||
replyRawReplyIfnotWiretapped(data, PLOC::SIZE_ACK_REPORT);
|
||||
sif::error << "PlocMPSoCHandler::handleAckReport: CRC failure" << std::endl;
|
||||
nextReplyId = PLOC_MPSOC::NONE;
|
||||
replyRawReplyIfnotWiretapped(data, PLOC_MPSOC::SIZE_ACK_REPORT);
|
||||
triggerEvent(CRC_FAILURE_EVENT);
|
||||
sendFailureReport(PLOC::ACK_REPORT, CRC_FAILURE);
|
||||
sendFailureReport(PLOC_MPSOC::ACK_REPORT, CRC_FAILURE);
|
||||
disableAllReplies();
|
||||
return IGNORE_REPLY_DATA;
|
||||
}
|
||||
@ -217,25 +217,25 @@ ReturnValue_t PlocHandler::handleAckReport(const uint8_t* data) {
|
||||
uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK;
|
||||
|
||||
switch(apid) {
|
||||
case PLOC::APID_ACK_FAILURE: {
|
||||
case PLOC_MPSOC::APID_ACK_FAILURE: {
|
||||
//TODO: Interpretation of status field in acknowledgment report
|
||||
sif::debug << "PlocHandler::handleAckReport: Received Ack failure report" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::handleAckReport: Received Ack failure report" << std::endl;
|
||||
DeviceCommandId_t commandId = getPendingCommand();
|
||||
if (commandId != DeviceHandlerIF::NO_COMMAND_ID) {
|
||||
triggerEvent(ACK_FAILURE, commandId);
|
||||
}
|
||||
sendFailureReport(PLOC::ACK_REPORT, RECEIVED_ACK_FAILURE);
|
||||
sendFailureReport(PLOC_MPSOC::ACK_REPORT, RECEIVED_ACK_FAILURE);
|
||||
disableAllReplies();
|
||||
nextReplyId = PLOC::NONE;
|
||||
nextReplyId = PLOC_MPSOC::NONE;
|
||||
result = IGNORE_REPLY_DATA;
|
||||
break;
|
||||
}
|
||||
case PLOC::APID_ACK_SUCCESS: {
|
||||
case PLOC_MPSOC::APID_ACK_SUCCESS: {
|
||||
setNextReplyId();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "PlocHandler::handleAckReport: Invalid APID in Ack report" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::handleAckReport: Invalid APID in Ack report" << std::endl;
|
||||
result = RETURN_FAILED;
|
||||
break;
|
||||
}
|
||||
@ -244,71 +244,71 @@ ReturnValue_t PlocHandler::handleAckReport(const uint8_t* data) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::handleExecutionReport(const uint8_t* data) {
|
||||
ReturnValue_t PlocMPSoCHandler::handleExecutionReport(const uint8_t* data) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
result = verifyPacket(data, PLOC::SIZE_EXE_REPORT);
|
||||
result = verifyPacket(data, PLOC_MPSOC::SIZE_EXE_REPORT);
|
||||
if(result == CRC_FAILURE) {
|
||||
sif::error << "PlocHandler::handleExecutionReport: CRC failure" << std::endl;
|
||||
nextReplyId = PLOC::NONE;
|
||||
sif::error << "PlocMPSoCHandler::handleExecutionReport: CRC failure" << std::endl;
|
||||
nextReplyId = PLOC_MPSOC::NONE;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK;
|
||||
|
||||
switch (apid) {
|
||||
case (PLOC::APID_EXE_SUCCESS): {
|
||||
case (PLOC_MPSOC::APID_EXE_SUCCESS): {
|
||||
break;
|
||||
}
|
||||
case (PLOC::APID_EXE_FAILURE): {
|
||||
case (PLOC_MPSOC::APID_EXE_FAILURE): {
|
||||
//TODO: Interpretation of status field in execution report
|
||||
sif::error << "PlocHandler::handleExecutionReport: Received execution failure report"
|
||||
sif::error << "PlocMPSoCHandler::handleExecutionReport: Received execution failure report"
|
||||
<< std::endl;
|
||||
DeviceCommandId_t commandId = getPendingCommand();
|
||||
if (commandId != DeviceHandlerIF::NO_COMMAND_ID) {
|
||||
triggerEvent(EXE_FAILURE, commandId);
|
||||
}
|
||||
else {
|
||||
sif::debug << "PlocHandler::handleExecutionReport: Unknown command id" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::handleExecutionReport: Unknown command id" << std::endl;
|
||||
}
|
||||
sendFailureReport(PLOC::EXE_REPORT, RECEIVED_EXE_FAILURE);
|
||||
sendFailureReport(PLOC_MPSOC::EXE_REPORT, RECEIVED_EXE_FAILURE);
|
||||
disableExeReportReply();
|
||||
result = IGNORE_REPLY_DATA;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::error << "PlocHandler::handleExecutionReport: Unknown APID" << std::endl;
|
||||
sif::error << "PlocMPSoCHandler::handleExecutionReport: Unknown APID" << std::endl;
|
||||
result = RETURN_FAILED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nextReplyId = PLOC::NONE;
|
||||
nextReplyId = PLOC_MPSOC::NONE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::handleMemoryReadReport(const uint8_t* data) {
|
||||
ReturnValue_t PlocMPSoCHandler::handleMemoryReadReport(const uint8_t* data) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
result = verifyPacket(data, PLOC::SIZE_TM_MEM_READ_REPORT);
|
||||
result = verifyPacket(data, PLOC_MPSOC::SIZE_TM_MEM_READ_REPORT);
|
||||
|
||||
if(result == CRC_FAILURE) {
|
||||
sif::error << "PlocHandler::handleMemoryReadReport: Memory read report has invalid crc"
|
||||
sif::error << "PlocMPSoCHandler::handleMemoryReadReport: Memory read report has invalid crc"
|
||||
<< std::endl;
|
||||
}
|
||||
/** Send data to commanding queue */
|
||||
handleDeviceTM(data + PLOC::DATA_FIELD_OFFSET, PLOC::SIZE_MEM_READ_REPORT_DATA,
|
||||
PLOC::TM_MEMORY_READ_REPORT);
|
||||
handleDeviceTM(data + PLOC_MPSOC::DATA_FIELD_OFFSET, PLOC_MPSOC::SIZE_MEM_READ_REPORT_DATA,
|
||||
PLOC_MPSOC::TM_MEMORY_READ_REPORT);
|
||||
|
||||
nextReplyId = PLOC::EXE_REPORT;
|
||||
nextReplyId = PLOC_MPSOC::EXE_REPORT;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::enableReplyInReplyMap(DeviceCommandMap::iterator command,
|
||||
ReturnValue_t PlocMPSoCHandler::enableReplyInReplyMap(DeviceCommandMap::iterator command,
|
||||
uint8_t expectedReplies, bool useAlternateId,
|
||||
DeviceCommandId_t alternateReplyID) {
|
||||
|
||||
@ -317,21 +317,21 @@ ReturnValue_t PlocHandler::enableReplyInReplyMap(DeviceCommandMap::iterator comm
|
||||
uint8_t enabledReplies = 0;
|
||||
|
||||
switch (command->first) {
|
||||
case PLOC::TC_MEM_WRITE:
|
||||
case PLOC_MPSOC::TC_MEM_WRITE:
|
||||
enabledReplies = 2;
|
||||
break;
|
||||
case PLOC::TC_MEM_READ: {
|
||||
case PLOC_MPSOC::TC_MEM_READ: {
|
||||
enabledReplies = 3;
|
||||
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true,
|
||||
PLOC::TM_MEMORY_READ_REPORT);
|
||||
PLOC_MPSOC::TM_MEMORY_READ_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocHandler::enableReplyInReplyMap: Reply with id "
|
||||
<< PLOC::TM_MEMORY_READ_REPORT << " not in replyMap" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id "
|
||||
<< PLOC_MPSOC::TM_MEMORY_READ_REPORT << " not in replyMap" << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sif::debug << "PlocHandler::enableReplyInReplyMap: Unknown command id" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Unknown command id" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -340,38 +340,38 @@ ReturnValue_t PlocHandler::enableReplyInReplyMap(DeviceCommandMap::iterator comm
|
||||
* replies will be enabled here.
|
||||
*/
|
||||
result = DeviceHandlerBase::enableReplyInReplyMap(command,
|
||||
enabledReplies, true, PLOC::ACK_REPORT);
|
||||
enabledReplies, true, PLOC_MPSOC::ACK_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocHandler::enableReplyInReplyMap: Reply with id " << PLOC::ACK_REPORT
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id " << PLOC_MPSOC::ACK_REPORT
|
||||
<< " not in replyMap" << std::endl;
|
||||
}
|
||||
|
||||
result = DeviceHandlerBase::enableReplyInReplyMap(command,
|
||||
enabledReplies, true, PLOC::EXE_REPORT);
|
||||
enabledReplies, true, PLOC_MPSOC::EXE_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocHandler::enableReplyInReplyMap: Reply with id " << PLOC::EXE_REPORT
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id " << PLOC_MPSOC::EXE_REPORT
|
||||
<< " not in replyMap" << std::endl;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void PlocHandler::setNextReplyId() {
|
||||
void PlocMPSoCHandler::setNextReplyId() {
|
||||
switch(getPendingCommand()) {
|
||||
case PLOC::TC_MEM_READ:
|
||||
nextReplyId = PLOC::TM_MEMORY_READ_REPORT;
|
||||
case PLOC_MPSOC::TC_MEM_READ:
|
||||
nextReplyId = PLOC_MPSOC::TM_MEMORY_READ_REPORT;
|
||||
break;
|
||||
default:
|
||||
/* If no telemetry is expected the next reply is always the execution report */
|
||||
nextReplyId = PLOC::EXE_REPORT;
|
||||
nextReplyId = PLOC_MPSOC::EXE_REPORT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
size_t PlocHandler::getNextReplyLength(DeviceCommandId_t commandId){
|
||||
size_t PlocMPSoCHandler::getNextReplyLength(DeviceCommandId_t commandId){
|
||||
|
||||
size_t replyLen = 0;
|
||||
|
||||
if (nextReplyId == PLOC::NONE) {
|
||||
if (nextReplyId == PLOC_MPSOC::NONE) {
|
||||
return replyLen;
|
||||
}
|
||||
|
||||
@ -384,14 +384,14 @@ size_t PlocHandler::getNextReplyLength(DeviceCommandId_t commandId){
|
||||
replyLen = iter->second.replyLen;
|
||||
}
|
||||
else {
|
||||
sif::debug << "PlocHandler::getNextReplyLength: No entry for reply with reply id "
|
||||
sif::debug << "PlocMPSoCHandler::getNextReplyLength: No entry for reply with reply id "
|
||||
<< std::hex << nextReplyId << " in deviceReplyMap" << std::endl;
|
||||
}
|
||||
|
||||
return replyLen;
|
||||
}
|
||||
|
||||
void PlocHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId) {
|
||||
void PlocMPSoCHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
@ -402,7 +402,7 @@ void PlocHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCom
|
||||
|
||||
DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId);
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
sif::debug << "PlocHandler::handleDeviceTM: Unknown reply id" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::handleDeviceTM: Unknown reply id" << std::endl;
|
||||
return;
|
||||
}
|
||||
MessageQueueId_t queueId = iter->second.command->second.sendReplyTo;
|
||||
@ -413,16 +413,16 @@ void PlocHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCom
|
||||
|
||||
result = actionHelper.reportData(queueId, replyId, data, dataSize);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocHandler::handleDeviceTM: Failed to report data" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::handleDeviceTM: Failed to report data" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void PlocHandler::disableAllReplies() {
|
||||
void PlocMPSoCHandler::disableAllReplies() {
|
||||
|
||||
DeviceReplyMap::iterator iter;
|
||||
|
||||
/* Disable ack reply */
|
||||
iter = deviceReplyMap.find(PLOC::ACK_REPORT);
|
||||
iter = deviceReplyMap.find(PLOC_MPSOC::ACK_REPORT);
|
||||
DeviceReplyInfo *info = &(iter->second);
|
||||
info->delayCycles = 0;
|
||||
info->command = deviceCommandMap.end();
|
||||
@ -431,17 +431,17 @@ void PlocHandler::disableAllReplies() {
|
||||
|
||||
/* If the command expects a telemetry packet the appropriate tm reply will be disabled here */
|
||||
switch (commandId) {
|
||||
case PLOC::TC_MEM_WRITE:
|
||||
case PLOC_MPSOC::TC_MEM_WRITE:
|
||||
break;
|
||||
case PLOC::TC_MEM_READ: {
|
||||
iter = deviceReplyMap.find(PLOC::TM_MEMORY_READ_REPORT);
|
||||
case PLOC_MPSOC::TC_MEM_READ: {
|
||||
iter = deviceReplyMap.find(PLOC_MPSOC::TM_MEMORY_READ_REPORT);
|
||||
info = &(iter->second);
|
||||
info->delayCycles = 0;
|
||||
info->command = deviceCommandMap.end();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "PlocHandler::disableAllReplies: Unknown command id" << commandId
|
||||
sif::debug << "PlocMPSoCHandler::disableAllReplies: Unknown command id" << commandId
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
@ -451,19 +451,19 @@ void PlocHandler::disableAllReplies() {
|
||||
disableExeReportReply();
|
||||
}
|
||||
|
||||
void PlocHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status) {
|
||||
void PlocMPSoCHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status) {
|
||||
|
||||
DeviceReplyIter iter = deviceReplyMap.find(replyId);
|
||||
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
sif::debug << "PlocHandler::sendFailureReport: Reply not in reply map" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::sendFailureReport: Reply not in reply map" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceCommandInfo* info = &(iter->second.command->second);
|
||||
|
||||
if (info == nullptr) {
|
||||
sif::debug << "PlocHandler::sendFailureReport: Reply has no active command" << std::endl;
|
||||
sif::debug << "PlocMPSoCHandler::sendFailureReport: Reply has no active command" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -473,8 +473,8 @@ void PlocHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t sta
|
||||
info->isExecuting = false;
|
||||
}
|
||||
|
||||
void PlocHandler::disableExeReportReply() {
|
||||
DeviceReplyIter iter = deviceReplyMap.find(PLOC::EXE_REPORT);
|
||||
void PlocMPSoCHandler::disableExeReportReply() {
|
||||
DeviceReplyIter iter = deviceReplyMap.find(PLOC_MPSOC::EXE_REPORT);
|
||||
DeviceReplyInfo *info = &(iter->second);
|
||||
info->delayCycles = 0;
|
||||
info->command = deviceCommandMap.end();
|
||||
@ -482,12 +482,12 @@ void PlocHandler::disableExeReportReply() {
|
||||
info->command->second.expectedReplies = 0;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocHandler::checkPacketSequenceCount(const uint8_t* data) {
|
||||
ReturnValue_t PlocMPSoCHandler::checkPacketSequenceCount(const uint8_t* data) {
|
||||
uint16_t receivedSequenceCount = (*(data + 2) << 8 | *(data + 3)) & PACKET_SEQUENCE_COUNT_MASK;
|
||||
uint16_t expectedPacketSequenceCount = ((packetSequenceCount + 1) & PACKET_SEQUENCE_COUNT_MASK);
|
||||
if (receivedSequenceCount != expectedPacketSequenceCount) {
|
||||
sif::debug
|
||||
<< "PlocHandler::checkPacketSequenceCount: Packet sequence count mismatch. "
|
||||
<< "PlocMPSoCHandler::checkPacketSequenceCount: Packet sequence count mismatch. "
|
||||
<< std::endl;
|
||||
sif::debug << "Received sequence count: " << receivedSequenceCount << ". OBSW sequence "
|
||||
<< "count: " << expectedPacketSequenceCount << std::endl;
|
@ -1,25 +1,28 @@
|
||||
#ifndef MISSION_DEVICES_PLOCHANDLER_H_
|
||||
#define MISSION_DEVICES_PLOCHANDLER_H_
|
||||
#ifndef MISSION_DEVICES_PLOCMPSOCHANDLER_H_
|
||||
#define MISSION_DEVICES_PLOCMPSOCHANDLER_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <mission/devices/devicedefinitions/PlocDefinitions.h>
|
||||
#include <mission/devices/devicedefinitions/PlocMPSoCDefinitions.h>
|
||||
#include <cstring>
|
||||
|
||||
/**
|
||||
* @brief This is the device handler for the PLOC.
|
||||
* @brief This is the device handler for the MPSoC which is programmed by the ILH of the
|
||||
* university of stuttgart.
|
||||
*
|
||||
* @details
|
||||
* The PLOC uses the space packet protocol for communication. To each command the PLOC
|
||||
* answers with at least one acknowledgment and one execution report.
|
||||
* Flight manual:
|
||||
* https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/PLOC_Commands
|
||||
* ILH ICD: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/
|
||||
* Arbeitsdaten/08_Used%20Components/PLOC&fileid=940960
|
||||
* @author J. Meier
|
||||
*/
|
||||
class PlocHandler: public DeviceHandlerBase {
|
||||
class PlocMPSoCHandler: public DeviceHandlerBase {
|
||||
public:
|
||||
|
||||
PlocHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie);
|
||||
virtual ~PlocHandler();
|
||||
PlocMPSoCHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie);
|
||||
virtual ~PlocMPSoCHandler();
|
||||
|
||||
/**
|
||||
* @brief Sets mode to MODE_NORMAL. Can be used for debugging.
|
||||
@ -49,14 +52,14 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_HANDLER;
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MPSOC_HANDLER;
|
||||
|
||||
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0); //!> Space Packet received from PLOC has invalid CRC
|
||||
static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1); //!> Received ACK failure reply from PLOC
|
||||
static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2); //!> Received execution failure reply from PLOC
|
||||
static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3); //!> Received space packet with invalid APID from PLOC
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_HANDLER;
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HANDLER;
|
||||
|
||||
static const Event MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW); //!> PLOC crc failure in telemetry packet
|
||||
static const Event ACK_FAILURE = MAKE_EVENT(2, severity::LOW); //!> PLOC receive acknowledgment failure report
|
||||
@ -66,7 +69,7 @@ private:
|
||||
static const uint16_t APID_MASK = 0x7FF;
|
||||
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
|
||||
|
||||
uint8_t commandBuffer[PLOC::MAX_COMMAND_SIZE];
|
||||
uint8_t commandBuffer[PLOC_MPSOC::MAX_COMMAND_SIZE];
|
||||
|
||||
/**
|
||||
* @brief This object is incremented each time a packet is sent or received. By checking the
|
||||
@ -85,7 +88,7 @@ private:
|
||||
* because the PLOC sends as reply to each command at least one acknowledgment and execution
|
||||
* report.
|
||||
*/
|
||||
DeviceCommandId_t nextReplyId = PLOC::NONE;
|
||||
DeviceCommandId_t nextReplyId = PLOC_MPSOC::NONE;
|
||||
|
||||
/**
|
||||
* @brief This function fills the commandBuffer to initiate the write memory command.
|
||||
@ -200,4 +203,4 @@ private:
|
||||
ReturnValue_t checkPacketSequenceCount(const uint8_t* data);
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_PLOCHANDLER_H_ */
|
||||
#endif /* MISSION_DEVICES_PLOCMPSOCHANDLER_H_ */
|
646
mission/devices/PlocSupervisorHandler.cpp
Normal file
646
mission/devices/PlocSupervisorHandler.cpp
Normal file
@ -0,0 +1,646 @@
|
||||
#include "PlocSupervisorHandler.h"
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
#include <fsfw/globalfunctions/CRC.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/timemanager/Clock.h>
|
||||
|
||||
PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF * comCookie) :
|
||||
DeviceHandlerBase(objectId, uartComIFid, comCookie), hkset(this) {
|
||||
if (comCookie == NULL) {
|
||||
sif::error << "PlocSupervisorHandler: Invalid com cookie" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
PlocSupervisorHandler::~PlocSupervisorHandler() {
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::initialize() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
result = DeviceHandlerBase::initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
uartComIf = dynamic_cast<UartComIF*>(communicationInterface);
|
||||
if (uartComIf == nullptr) {
|
||||
sif::warning << "PlocSupervisorHandler::initialize: Invalid uart com if" << std::endl;
|
||||
return INVALID_UART_COM_IF;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void PlocSupervisorHandler::doStartUp(){
|
||||
#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1
|
||||
setMode(MODE_NORMAL);
|
||||
#else
|
||||
setMode(_MODE_TO_ON);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::doShutDown(){
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::buildNormalDeviceCommand(
|
||||
DeviceCommandId_t * id) {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::buildTransitionDeviceCommand(
|
||||
DeviceCommandId_t * id){
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(
|
||||
DeviceCommandId_t deviceCommand, const uint8_t * commandData,
|
||||
size_t commandDataLen) {
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
switch(deviceCommand) {
|
||||
case(PLOC_SPV::GET_HK_REPORT): {
|
||||
prepareEmptyCmd(PLOC_SPV::APID_GET_HK_REPORT);
|
||||
result = RETURN_OK;
|
||||
break;
|
||||
}
|
||||
case(PLOC_SPV::RESTART_MPSOC): {
|
||||
prepareEmptyCmd(PLOC_SPV::APID_RESTART_MPSOC);
|
||||
result = RETURN_OK;
|
||||
break;
|
||||
}
|
||||
case(PLOC_SPV::START_MPSOC): {
|
||||
prepareEmptyCmd(PLOC_SPV::APID_START_MPSOC);
|
||||
result = RETURN_OK;
|
||||
break;
|
||||
}
|
||||
case(PLOC_SPV::SHUTDOWN_MPSOC): {
|
||||
prepareEmptyCmd(PLOC_SPV::APID_SHUTWOWN_MPSOC);
|
||||
result = RETURN_OK;
|
||||
break;
|
||||
}
|
||||
case(PLOC_SPV::SEL_MPSOC_BOOT_IMAGE): {
|
||||
prepareSelBootImageCmd(commandData);
|
||||
result = RETURN_OK;
|
||||
break;
|
||||
}
|
||||
case(PLOC_SPV::RESET_MPSOC): {
|
||||
prepareEmptyCmd(PLOC_SPV::APID_RESET_MPSOC);
|
||||
result = RETURN_OK;
|
||||
break;
|
||||
}
|
||||
case(PLOC_SPV::SET_TIME_REF): {
|
||||
result = prepareSetTimeRefCmd();
|
||||
break;
|
||||
}
|
||||
case(PLOC_SPV::SET_BOOT_TIMEOUT): {
|
||||
prepareSetBootTimeoutCmd(commandData);
|
||||
result = RETURN_OK;
|
||||
break;
|
||||
}
|
||||
case(PLOC_SPV::SET_MAX_RESTART_TRIES): {
|
||||
prepareRestartTriesCmd(commandData);
|
||||
result = RETURN_OK;
|
||||
break;
|
||||
}
|
||||
case(PLOC_SPV::DISABLE_PERIOIC_HK_TRANSMISSION): {
|
||||
prepareDisableHk();
|
||||
result = RETURN_OK;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented"
|
||||
<< std::endl;
|
||||
result = DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == RETURN_OK) {
|
||||
/**
|
||||
* Flushing the receive buffer to make sure there are no data left from a faulty reply.
|
||||
*/
|
||||
uartComIf->flushUartRxBuffer(comCookie);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::fillCommandAndReplyMap() {
|
||||
this->insertInCommandMap(PLOC_SPV::GET_HK_REPORT);
|
||||
this->insertInCommandMap(PLOC_SPV::RESTART_MPSOC);
|
||||
this->insertInCommandMap(PLOC_SPV::START_MPSOC);
|
||||
this->insertInCommandMap(PLOC_SPV::SHUTDOWN_MPSOC);
|
||||
this->insertInCommandMap(PLOC_SPV::SEL_MPSOC_BOOT_IMAGE);
|
||||
this->insertInCommandMap(PLOC_SPV::SET_BOOT_TIMEOUT);
|
||||
this->insertInCommandMap(PLOC_SPV::SET_MAX_RESTART_TRIES);
|
||||
this->insertInCommandMap(PLOC_SPV::RESET_MPSOC);
|
||||
this->insertInCommandMap(PLOC_SPV::SET_TIME_REF);
|
||||
this->insertInCommandMap(PLOC_SPV::DISABLE_PERIOIC_HK_TRANSMISSION);
|
||||
this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT);
|
||||
this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT);
|
||||
this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, nullptr, PLOC_SPV::SIZE_HK_REPORT);
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t *start,
|
||||
size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
uint16_t apid = (*(start) << 8 | *(start + 1)) & APID_MASK;
|
||||
|
||||
switch(apid) {
|
||||
case(PLOC_SPV::APID_ACK_SUCCESS):
|
||||
*foundLen = PLOC_SPV::SIZE_ACK_REPORT;
|
||||
*foundId = PLOC_SPV::ACK_REPORT;
|
||||
break;
|
||||
case(PLOC_SPV::APID_ACK_FAILURE):
|
||||
*foundLen = PLOC_SPV::SIZE_ACK_REPORT;
|
||||
*foundId = PLOC_SPV::ACK_REPORT;
|
||||
break;
|
||||
case(PLOC_SPV::APID_HK_REPORT):
|
||||
*foundLen = PLOC_SPV::SIZE_HK_REPORT;
|
||||
*foundId = PLOC_SPV::HK_REPORT;
|
||||
break;
|
||||
case(PLOC_SPV::APID_EXE_SUCCESS):
|
||||
*foundLen = PLOC_SPV::SIZE_EXE_REPORT;
|
||||
*foundId = PLOC_SPV::EXE_REPORT;
|
||||
break;
|
||||
case(PLOC_SPV::APID_EXE_FAILURE):
|
||||
*foundLen = PLOC_SPV::SIZE_EXE_REPORT;
|
||||
*foundId = PLOC_SPV::EXE_REPORT;
|
||||
break;
|
||||
default: {
|
||||
sif::debug << "PlocSupervisorHandler::scanForReply: Reply has invalid apid" << std::endl;
|
||||
*foundLen = remainingSize;
|
||||
return INVALID_APID;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
switch (id) {
|
||||
case PLOC_SPV::ACK_REPORT: {
|
||||
result = handleAckReport(packet);
|
||||
break;
|
||||
}
|
||||
case (PLOC_SPV::HK_REPORT): {
|
||||
result = handleHkReport(packet);
|
||||
break;
|
||||
}
|
||||
case (PLOC_SPV::EXE_REPORT): {
|
||||
result = handleExecutionReport(packet);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "PlocSupervisorHandler::interpretDeviceReply: Unknown device reply id" << std::endl;
|
||||
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::setNormalDatapoolEntriesInvalid(){
|
||||
|
||||
}
|
||||
|
||||
uint32_t PlocSupervisorHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){
|
||||
return 500;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) {
|
||||
|
||||
localDataPoolMap.emplace(PLOC_SPV::NUM_TMS, new PoolEntry<uint32_t>( { 0 }));
|
||||
localDataPoolMap.emplace(PLOC_SPV::TEMP_PS, new PoolEntry<uint32_t>( { 0 }));
|
||||
localDataPoolMap.emplace(PLOC_SPV::TEMP_PL, new PoolEntry<uint32_t>( { 0 }));
|
||||
localDataPoolMap.emplace(PLOC_SPV::SOC_STATE, new PoolEntry<uint32_t>( { 0 }));
|
||||
localDataPoolMap.emplace(PLOC_SPV::NVM0_1_STATE, new PoolEntry<uint8_t>( { 0 }));
|
||||
localDataPoolMap.emplace(PLOC_SPV::NVM3_STATE, new PoolEntry<uint8_t>( { 0 }));
|
||||
localDataPoolMap.emplace(PLOC_SPV::MISSION_IO_STATE, new PoolEntry<uint8_t>( { 0 }));
|
||||
localDataPoolMap.emplace(PLOC_SPV::FMC_STATE, new PoolEntry<uint32_t>( { 0 }));
|
||||
localDataPoolMap.emplace(PLOC_SPV::NUM_TCS, new PoolEntry<uint32_t>( { 0 }));
|
||||
localDataPoolMap.emplace(PLOC_SPV::UPTIME, new PoolEntry<uint32_t>( { 0 }));
|
||||
localDataPoolMap.emplace(PLOC_SPV::CPULOAD, new PoolEntry<uint32_t>( { 0 }));
|
||||
localDataPoolMap.emplace(PLOC_SPV::AVAILABLEHEAP, new PoolEntry<uint32_t>( { 0 }));
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::verifyPacket(const uint8_t* start, size_t foundLen) {
|
||||
|
||||
uint16_t receivedCrc = *(start + foundLen - 2) << 8 | *(start + foundLen - 1);
|
||||
|
||||
uint16_t recalculatedCrc = CRC::crc16ccitt(start, foundLen - 2);
|
||||
|
||||
if (receivedCrc != recalculatedCrc) {
|
||||
return CRC_FAILURE;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::handleAckReport(const uint8_t* data) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
result = verifyPacket(data, PLOC_SPV::SIZE_ACK_REPORT);
|
||||
if(result == CRC_FAILURE) {
|
||||
sif::error << "PlocSupervisorHandler::handleAckReport: CRC failure" << std::endl;
|
||||
nextReplyId = PLOC_SPV::NONE;
|
||||
replyRawReplyIfnotWiretapped(data, PLOC_SPV::SIZE_ACK_REPORT);
|
||||
triggerEvent(SUPV_CRC_FAILURE_EVENT);
|
||||
sendFailureReport(PLOC_SPV::ACK_REPORT, CRC_FAILURE);
|
||||
disableAllReplies();
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK;
|
||||
|
||||
switch(apid) {
|
||||
case PLOC_SPV::APID_ACK_FAILURE: {
|
||||
//TODO: Interpretation of status field in acknowledgment report
|
||||
sif::debug << "PlocSupervisorHandler::handleAckReport: Received Ack failure report" << std::endl;
|
||||
DeviceCommandId_t commandId = getPendingCommand();
|
||||
if (commandId != DeviceHandlerIF::NO_COMMAND_ID) {
|
||||
triggerEvent(SUPV_ACK_FAILURE, commandId);
|
||||
}
|
||||
sendFailureReport(PLOC_SPV::ACK_REPORT, RECEIVED_ACK_FAILURE);
|
||||
disableAllReplies();
|
||||
nextReplyId = PLOC_SPV::NONE;
|
||||
result = IGNORE_REPLY_DATA;
|
||||
break;
|
||||
}
|
||||
case PLOC_SPV::APID_ACK_SUCCESS: {
|
||||
setNextReplyId();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "PlocSupervisorHandler::handleAckReport: Invalid APID in Ack report" << std::endl;
|
||||
result = RETURN_FAILED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::handleExecutionReport(const uint8_t* data) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
result = verifyPacket(data, PLOC_SPV::SIZE_EXE_REPORT);
|
||||
if(result == CRC_FAILURE) {
|
||||
sif::error << "PlocSupervisorHandler::handleExecutionReport: CRC failure" << std::endl;
|
||||
nextReplyId = PLOC_SPV::NONE;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t apid = (*(data) << 8 | *(data + 1)) & APID_MASK;
|
||||
|
||||
switch (apid) {
|
||||
case (PLOC_SPV::APID_EXE_SUCCESS): {
|
||||
break;
|
||||
}
|
||||
case (PLOC_SPV::APID_EXE_FAILURE): {
|
||||
//TODO: Interpretation of status field in execution report
|
||||
sif::error << "PlocSupervisorHandler::handleExecutionReport: Received execution failure report"
|
||||
<< std::endl;
|
||||
DeviceCommandId_t commandId = getPendingCommand();
|
||||
if (commandId != DeviceHandlerIF::NO_COMMAND_ID) {
|
||||
triggerEvent(SUPV_EXE_FAILURE, commandId);
|
||||
}
|
||||
else {
|
||||
sif::debug << "PlocSupervisorHandler::handleExecutionReport: Unknown command id" << std::endl;
|
||||
}
|
||||
sendFailureReport(PLOC_SPV::EXE_REPORT, RECEIVED_EXE_FAILURE);
|
||||
disableExeReportReply();
|
||||
result = IGNORE_REPLY_DATA;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::error << "PlocSupervisorHandler::handleExecutionReport: Unknown APID" << std::endl;
|
||||
result = RETURN_FAILED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nextReplyId = PLOC_SPV::NONE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::handleHkReport(const uint8_t* data) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
result = verifyPacket(data, PLOC_SPV::SIZE_HK_REPORT);
|
||||
|
||||
if(result == CRC_FAILURE) {
|
||||
sif::error << "PlocSupervisorHandler::handleHkReport: Hk report has invalid crc"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
uint16_t offset = PLOC_SPV::DATA_FIELD_OFFSET;
|
||||
hkset.tempPs = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8
|
||||
| *(data + offset + 3);
|
||||
offset += 4;
|
||||
hkset.tempPl = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8
|
||||
| *(data + offset + 3);
|
||||
offset += 4;
|
||||
hkset.tempSup = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8
|
||||
| *(data + offset + 3);
|
||||
offset += 4;
|
||||
hkset.uptime = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8
|
||||
| *(data + offset + 3);
|
||||
offset += 4;
|
||||
hkset.cpuLoad = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8
|
||||
| *(data + offset + 3);
|
||||
offset += 4;
|
||||
hkset.availableHeap = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8
|
||||
| *(data + offset + 3);
|
||||
offset += 4;
|
||||
hkset.numTcs = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8
|
||||
| *(data + offset + 3);
|
||||
offset += 4;
|
||||
hkset.numTms = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8
|
||||
| *(data + offset + 3);
|
||||
offset += 4;
|
||||
hkset.socState = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8
|
||||
| *(data + offset + 3);
|
||||
offset += 4;
|
||||
hkset.nvm0_1_state = *(data + offset);
|
||||
offset += 1;
|
||||
hkset.nvm3_state = *(data + offset);
|
||||
offset += 1;
|
||||
hkset.missionIoState = *(data + offset);
|
||||
offset += 1;
|
||||
hkset.fmcState = *(data + offset);
|
||||
offset += 1;
|
||||
|
||||
nextReplyId = PLOC_SPV::EXE_REPORT;
|
||||
|
||||
#if OBSW_VERBOSE_LEVEL >= 1 && PLOC_SUPERVISOR_DEBUG == 1
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: temp_ps: " << hkset.tempPs << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: temp_pl: " << hkset.tempPl << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: temp_sup: " << hkset.tempSup << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: uptime: " << hkset.uptime << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: cpu_load: " << hkset.cpuLoad << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: available_heap: " << hkset.availableHeap << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: num_tcs: " << hkset.numTcs << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: num_tms: " << hkset.numTms << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: soc_state: " << hkset.socState << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: nvm0_1_state: "
|
||||
<< static_cast<unsigned int>(hkset.nvm0_1_state.value) << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: nvm3_state: "
|
||||
<< static_cast<unsigned int>(hkset.nvm3_state.value) << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: missoin_io_state: "
|
||||
<< static_cast<unsigned int>(hkset.missionIoState.value) << std::endl;
|
||||
sif::info << "PlocSupervisorHandler::handleHkReport: fmc_state: "
|
||||
<< static_cast<unsigned int>(hkset.fmcState.value) << std::endl;
|
||||
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::iterator command,
|
||||
uint8_t expectedReplies, bool useAlternateId,
|
||||
DeviceCommandId_t alternateReplyID) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
uint8_t enabledReplies = 0;
|
||||
|
||||
switch (command->first) {
|
||||
case PLOC_SPV::GET_HK_REPORT: {
|
||||
enabledReplies = 3;
|
||||
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true,
|
||||
PLOC_SPV::HK_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id "
|
||||
<< PLOC_SPV::HK_REPORT << " not in replyMap" << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PLOC_SPV::RESTART_MPSOC:
|
||||
case PLOC_SPV::START_MPSOC:
|
||||
case PLOC_SPV::SHUTDOWN_MPSOC:
|
||||
case PLOC_SPV::SEL_MPSOC_BOOT_IMAGE:
|
||||
case PLOC_SPV::SET_BOOT_TIMEOUT:
|
||||
case PLOC_SPV::SET_MAX_RESTART_TRIES:
|
||||
case PLOC_SPV::RESET_MPSOC:
|
||||
case PLOC_SPV::SET_TIME_REF:
|
||||
enabledReplies = 2;
|
||||
break;
|
||||
default:
|
||||
sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Unknown command id" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* Every command causes at least one acknowledgment and one execution report. Therefore both
|
||||
* replies will be enabled here.
|
||||
*/
|
||||
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true,
|
||||
PLOC_SPV::ACK_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id "
|
||||
<< PLOC_SPV::ACK_REPORT << " not in replyMap" << std::endl;
|
||||
}
|
||||
|
||||
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true,
|
||||
PLOC_SPV::EXE_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id "
|
||||
<< PLOC_SPV::EXE_REPORT << " not in replyMap" << std::endl;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::setNextReplyId() {
|
||||
switch(getPendingCommand()) {
|
||||
case PLOC_SPV::GET_HK_REPORT:
|
||||
nextReplyId = PLOC_SPV::HK_REPORT;
|
||||
break;
|
||||
default:
|
||||
/* If no telemetry is expected the next reply is always the execution report */
|
||||
nextReplyId = PLOC_SPV::EXE_REPORT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
size_t PlocSupervisorHandler::getNextReplyLength(DeviceCommandId_t commandId){
|
||||
|
||||
size_t replyLen = 0;
|
||||
|
||||
if (nextReplyId == PLOC_SPV::NONE) {
|
||||
return replyLen;
|
||||
}
|
||||
|
||||
DeviceReplyIter iter = deviceReplyMap.find(nextReplyId);
|
||||
if (iter != deviceReplyMap.end()) {
|
||||
if (iter->second.delayCycles == 0) {
|
||||
/* Reply inactive */
|
||||
return replyLen;
|
||||
}
|
||||
replyLen = iter->second.replyLen;
|
||||
}
|
||||
else {
|
||||
sif::debug << "PlocSupervisorHandler::getNextReplyLength: No entry for reply with reply id "
|
||||
<< std::hex << nextReplyId << " in deviceReplyMap" << std::endl;
|
||||
}
|
||||
|
||||
return replyLen;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId) {
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
if (wiretappingMode == RAW) {
|
||||
/* Data already sent in doGetRead() */
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId);
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
sif::debug << "PlocSupervisorHandler::handleDeviceTM: Unknown reply id" << std::endl;
|
||||
return;
|
||||
}
|
||||
MessageQueueId_t queueId = iter->second.command->second.sendReplyTo;
|
||||
|
||||
if (queueId == NO_COMMANDER) {
|
||||
return;
|
||||
}
|
||||
|
||||
result = actionHelper.reportData(queueId, replyId, data, dataSize);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocSupervisorHandler::handleDeviceTM: Failed to report data" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::prepareEmptyCmd(uint16_t apid) {
|
||||
PLOC_SPV::EmptyPacket packet(apid);
|
||||
memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize());
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = packet.getFullSize();
|
||||
nextReplyId = PLOC_SPV::ACK_REPORT;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::prepareSelBootImageCmd(const uint8_t * commandData) {
|
||||
PLOC_SPV::MPSoCBootSelect packet(*commandData, *(commandData + 1), *(commandData + 2),
|
||||
*(commandData + 3));
|
||||
memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize());
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = packet.getFullSize();
|
||||
nextReplyId = PLOC_SPV::ACK_REPORT;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::prepareSetTimeRefCmd() {
|
||||
Clock::TimeOfDay_t time;
|
||||
ReturnValue_t result = Clock::getDateAndTime(&time);
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "PlocSupervisorHandler::prepareSetTimeRefCmd: Failed to get current time"
|
||||
<< std::endl;
|
||||
return GET_TIME_FAILURE;
|
||||
}
|
||||
PLOC_SPV::SetTimeRef packet(&time);
|
||||
memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize());
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = packet.getFullSize();
|
||||
nextReplyId = PLOC_SPV::ACK_REPORT;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::prepareDisableHk() {
|
||||
PLOC_SPV::DisablePeriodicHkTransmission packet;
|
||||
memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize());
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = packet.getFullSize();
|
||||
nextReplyId = PLOC_SPV::ACK_REPORT;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::prepareSetBootTimeoutCmd(const uint8_t * commandData) {
|
||||
uint32_t timeout = *(commandData) << 24 | *(commandData + 1) << 16 | *(commandData + 2) << 8
|
||||
| *(commandData + 3);
|
||||
PLOC_SPV::SetBootTimeout packet(timeout);
|
||||
memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize());
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = packet.getFullSize();
|
||||
nextReplyId = PLOC_SPV::ACK_REPORT;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::prepareRestartTriesCmd(const uint8_t * commandData) {
|
||||
uint8_t restartTries = *(commandData);
|
||||
PLOC_SPV::SetRestartTries packet(restartTries);
|
||||
memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize());
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = packet.getFullSize();
|
||||
nextReplyId = PLOC_SPV::ACK_REPORT;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::disableAllReplies() {
|
||||
|
||||
DeviceReplyMap::iterator iter;
|
||||
|
||||
/* Disable ack reply */
|
||||
iter = deviceReplyMap.find(PLOC_SPV::ACK_REPORT);
|
||||
DeviceReplyInfo *info = &(iter->second);
|
||||
info->delayCycles = 0;
|
||||
info->command = deviceCommandMap.end();
|
||||
|
||||
DeviceCommandId_t commandId = getPendingCommand();
|
||||
|
||||
/* If the command expects a telemetry packet the appropriate tm reply will be disabled here */
|
||||
switch (commandId) {
|
||||
case PLOC_SPV::GET_HK_REPORT: {
|
||||
iter = deviceReplyMap.find(PLOC_SPV::GET_HK_REPORT);
|
||||
info = &(iter->second);
|
||||
info->delayCycles = 0;
|
||||
info->command = deviceCommandMap.end();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We must always disable the execution report reply here */
|
||||
disableExeReportReply();
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status) {
|
||||
|
||||
DeviceReplyIter iter = deviceReplyMap.find(replyId);
|
||||
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
sif::debug << "PlocSupervisorHandler::sendFailureReport: Reply not in reply map" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceCommandInfo* info = &(iter->second.command->second);
|
||||
|
||||
if (info == nullptr) {
|
||||
sif::debug << "PlocSupervisorHandler::sendFailureReport: Reply has no active command" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->sendReplyTo != NO_COMMANDER) {
|
||||
actionHelper.finish(false, info->sendReplyTo, iter->first, status);
|
||||
}
|
||||
info->isExecuting = false;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::disableExeReportReply() {
|
||||
DeviceReplyIter iter = deviceReplyMap.find(PLOC_SPV::EXE_REPORT);
|
||||
DeviceReplyInfo *info = &(iter->second);
|
||||
info->delayCycles = 0;
|
||||
info->command = deviceCommandMap.end();
|
||||
/* Expected replies is set to one here. The value will set to 0 in replyToReply() */
|
||||
info->command->second.expectedReplies = 1;
|
||||
}
|
213
mission/devices/PlocSupervisorHandler.h
Normal file
213
mission/devices/PlocSupervisorHandler.h
Normal file
@ -0,0 +1,213 @@
|
||||
#ifndef MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_
|
||||
#define MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <mission/devices/devicedefinitions/PlocSupervisorDefinitions.h>
|
||||
#include <cstring>
|
||||
#include <fsfw/hal/linux/uart/UartComIF.h>
|
||||
|
||||
/**
|
||||
* @brief This is the device handler for the supervisor of the PLOC which is programmed by
|
||||
* Thales.
|
||||
*
|
||||
* @details The PLOC uses the space packet protocol for communication. To each command the PLOC
|
||||
* answers with at least one acknowledgment and one execution report.
|
||||
* Flight manual:
|
||||
* https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/PLOC_Commands
|
||||
* ILH ICD: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/
|
||||
* Arbeitsdaten/08_Used%20Components/PLOC&fileid=940960
|
||||
* @author J. Meier
|
||||
*/
|
||||
class PlocSupervisorHandler: public DeviceHandlerBase {
|
||||
public:
|
||||
|
||||
PlocSupervisorHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF * comCookie);
|
||||
virtual ~PlocSupervisorHandler();
|
||||
|
||||
virtual ReturnValue_t initialize() override;
|
||||
|
||||
protected:
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override;
|
||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) override;
|
||||
void fillCommandAndReplyMap() override;
|
||||
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t * commandData,size_t commandDataLen) override;
|
||||
ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) override;
|
||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) override;
|
||||
void setNormalDatapoolEntriesInvalid() override;
|
||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator command,
|
||||
uint8_t expectedReplies = 1, bool useAlternateId = false,
|
||||
DeviceCommandId_t alternateReplyID = 0) override;
|
||||
size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
|
||||
|
||||
private:
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_SUPERVISOR_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] Space Packet received from PLOC supervisor has invalid CRC
|
||||
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0);
|
||||
//! [EXPORT] : [COMMENT] Received ACK failure reply from PLOC supervisor
|
||||
static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1);
|
||||
//! [EXPORT] : [COMMENT] Received execution failure reply from PLOC supervisor
|
||||
static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2);
|
||||
//! [EXPORT] : [COMMENT] Received space packet with invalid APID from PLOC supervisor
|
||||
static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3);
|
||||
//! [EXPORT] : [COMMENT] Failed to read current system time
|
||||
static const ReturnValue_t GET_TIME_FAILURE = MAKE_RETURN_CODE(0xA4);
|
||||
//! [EXPORT] : [COMMENT] Invalid communication interface specified
|
||||
static const ReturnValue_t INVALID_UART_COM_IF = MAKE_RETURN_CODE(0xA5);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] PLOC supervrisor crc failure in telemetry packet
|
||||
static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report
|
||||
static const Event SUPV_ACK_FAILURE = MAKE_EVENT(2, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC received execution failure report
|
||||
static const Event SUPV_EXE_FAILURE = MAKE_EVENT(3, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc
|
||||
static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(4, severity::LOW);
|
||||
|
||||
static const uint16_t APID_MASK = 0x7FF;
|
||||
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
|
||||
|
||||
uint8_t commandBuffer[PLOC_SPV::MAX_COMMAND_SIZE];
|
||||
|
||||
/**
|
||||
* @brief This object is incremented each time a packet is sent or received. By checking the
|
||||
* packet sequence count of a received packet, no packets can be lost without noticing
|
||||
* it. Only the least significant 14 bits represent the packet sequence count in a
|
||||
* space packet. Thus the maximum value amounts to 16383 (0x3FFF).
|
||||
* @note Normally this should never happen because the PLOC replies are always sent in a
|
||||
* fixed order. However, the PLOC software checks this value and will return an ACK
|
||||
* failure report in case the sequence count is not incremented with each transferred
|
||||
* space packet.
|
||||
*/
|
||||
uint16_t packetSequenceCount = 0x3FFF;
|
||||
|
||||
/**
|
||||
* This variable is used to store the id of the next reply to receive. This is necessary
|
||||
* because the PLOC sends as reply to each command at least one acknowledgment and execution
|
||||
* report.
|
||||
*/
|
||||
DeviceCommandId_t nextReplyId = PLOC_SPV::NONE;
|
||||
|
||||
PLOC_SPV::HkSet hkset;
|
||||
|
||||
UartComIF* uartComIf = nullptr;
|
||||
|
||||
/**
|
||||
* @brief This function checks the crc of the received PLOC reply.
|
||||
*
|
||||
* @param start Pointer to the first byte of the reply.
|
||||
* @param foundLen Pointer to the length of the whole packet.
|
||||
*
|
||||
* @return RETURN_OK if CRC is ok, otherwise CRC_FAILURE.
|
||||
*/
|
||||
ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen);
|
||||
|
||||
/**
|
||||
* @brief This function handles the acknowledgment report.
|
||||
*
|
||||
* @param data Pointer to the data holding the acknowledgment report.
|
||||
*
|
||||
* @return RETURN_OK if successful, otherwise an error code.
|
||||
*/
|
||||
ReturnValue_t handleAckReport(const uint8_t* data);
|
||||
|
||||
/**
|
||||
* @brief This function handles the data of a execution report.
|
||||
*
|
||||
* @param data Pointer to the received data packet.
|
||||
*
|
||||
* @return RETURN_OK if successful, otherwise an error code.
|
||||
*/
|
||||
ReturnValue_t handleExecutionReport(const uint8_t* data);
|
||||
|
||||
/**
|
||||
* @brief This function handles the housekeeping report. This means verifying the CRC of the
|
||||
* reply and filling the appropriate dataset.
|
||||
*
|
||||
* @param data Pointer to the data buffer holding the housekeeping read report.
|
||||
*
|
||||
* @return RETURN_OK if successful, otherwise an error code.
|
||||
*/
|
||||
ReturnValue_t handleHkReport(const uint8_t* data);
|
||||
|
||||
/**
|
||||
* @brief Depending on the current active command, this function sets the reply id of the
|
||||
* next reply after a successful acknowledgment report has been received. This is
|
||||
* required by the function getNextReplyLength() to identify the length of the next
|
||||
* reply to read.
|
||||
*/
|
||||
void setNextReplyId();
|
||||
|
||||
/**
|
||||
* @brief This function handles action message replies in case the telemetry has been
|
||||
* requested by another object.
|
||||
*
|
||||
* @param data Pointer to the telemetry data.
|
||||
* @param dataSize Size of telemetry in bytes.
|
||||
* @param replyId Id of the reply. This will be added to the ActionMessage.
|
||||
*/
|
||||
void handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId);
|
||||
|
||||
/**
|
||||
* @brief This function prepares a space packet which does not transport any data in the
|
||||
* packet data field apart from the crc.
|
||||
*/
|
||||
void prepareEmptyCmd(uint16_t apid);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function initializes the space packet to select the boot image of the MPSoC.
|
||||
*/
|
||||
void prepareSelBootImageCmd(const uint8_t * commandData);
|
||||
|
||||
void prepareDisableHk();
|
||||
|
||||
/**
|
||||
* @brief This function fills the commandBuffer with the data to update the time of the
|
||||
* PLOC supervisor.
|
||||
*/
|
||||
ReturnValue_t prepareSetTimeRefCmd();
|
||||
|
||||
/**
|
||||
* @brief This function fills the commandBuffer with the data to change the boot timeout
|
||||
* value in the PLOC supervisor.
|
||||
*/
|
||||
void prepareSetBootTimeoutCmd(const uint8_t * commandData);
|
||||
|
||||
void prepareRestartTriesCmd(const uint8_t * commandData);
|
||||
|
||||
/**
|
||||
* @brief In case an acknowledgment failure reply has been received this function disables
|
||||
* all previously enabled commands and resets the exepected replies variable of an
|
||||
* active command.
|
||||
*/
|
||||
void disableAllReplies();
|
||||
|
||||
/**
|
||||
* @brief This function sends a failure report if the active action was commanded by an other
|
||||
* object.
|
||||
*
|
||||
* @param replyId The id of the reply which signals a failure.
|
||||
* @param status A status byte which gives information about the failure type.
|
||||
*/
|
||||
void sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status);
|
||||
|
||||
/**
|
||||
* @brief This function disables the execution report reply. Within this function also the
|
||||
* the variable expectedReplies of an active command will be set to 0.
|
||||
*/
|
||||
void disableExeReportReply();
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ */
|
@ -58,7 +58,7 @@ ReturnValue_t RadiationSensorHandler::buildTransitionDeviceCommand(
|
||||
*id = RAD_SENSOR::WRITE_SETUP;
|
||||
}
|
||||
else {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
@ -84,15 +84,19 @@ ReturnValue_t RadiationSensorHandler::buildCommandFromCommand(
|
||||
}
|
||||
case(RAD_SENSOR::READ_CONVERSIONS): {
|
||||
cmdBuffer[0] = RAD_SENSOR::DUMMY_BYTE;
|
||||
cmdBuffer[1] = RAD_SENSOR::DUMMY_BYTE;
|
||||
cmdBuffer[2] = RAD_SENSOR::DUMMY_BYTE;
|
||||
cmdBuffer[3] = RAD_SENSOR::DUMMY_BYTE;
|
||||
cmdBuffer[4] = RAD_SENSOR::DUMMY_BYTE;
|
||||
cmdBuffer[5] = RAD_SENSOR::DUMMY_BYTE;
|
||||
std::memset(cmdBuffer, RAD_SENSOR::DUMMY_BYTE, RAD_SENSOR::READ_SIZE);
|
||||
rawPacket = cmdBuffer;
|
||||
rawPacketLen = RAD_SENSOR::READ_SIZE;
|
||||
return RETURN_OK;
|
||||
}
|
||||
// case(RAD_SENSOR::AIN0_AND_TMP_CONVERSION): {
|
||||
// /* First the fifo will be reset here */
|
||||
// cmdBuffer[0] = RAD_SENSOR::RESET_DEFINITION;
|
||||
// cmdBuffer[1] = RAD_SENSOR::CONVERSION_DEFINITION;
|
||||
// rawPacket = cmdBuffer;
|
||||
// rawPacketLen = 2;
|
||||
// return RETURN_OK;
|
||||
// }
|
||||
default:
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
@ -109,7 +113,17 @@ void RadiationSensorHandler::fillCommandAndReplyMap() {
|
||||
ReturnValue_t RadiationSensorHandler::scanForReply(const uint8_t *start,
|
||||
size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
*foundId = this->getPendingCommand();
|
||||
|
||||
switch (*foundId) {
|
||||
case RAD_SENSOR::START_CONVERSION:
|
||||
case RAD_SENSOR::WRITE_SETUP:
|
||||
return IGNORE_REPLY_DATA;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*foundLen = remainingSize;
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -117,16 +131,36 @@ ReturnValue_t RadiationSensorHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) {
|
||||
switch (id) {
|
||||
case RAD_SENSOR::READ_CONVERSIONS: {
|
||||
uint8_t offset = 0;
|
||||
PoolReadGuard readSet(&dataset);
|
||||
dataset.temperatureCelcius = (*(packet) << 8 | *(packet + 1)) * 0.125;
|
||||
dataset.channel0 = (*(packet + 2) << 8 | *(packet + 3));
|
||||
dataset.channel1 = (*(packet + 4) << 8 | *(packet + 5));
|
||||
dataset.temperatureCelcius = (*(packet + offset) << 8 | *(packet + offset + 1)) * 0.125;
|
||||
offset += 2;
|
||||
dataset.ain0 = (*(packet + offset) << 8 | *(packet + offset +1));
|
||||
offset += 2;
|
||||
dataset.ain1 = (*(packet + offset) << 8 | *(packet + offset + 1));
|
||||
offset += 6;
|
||||
dataset.ain4 = (*(packet + offset) << 8 | *(packet + offset + 1));
|
||||
offset += 2;
|
||||
dataset.ain5 = (*(packet + offset) << 8 | *(packet + offset + 1));
|
||||
offset += 2;
|
||||
dataset.ain6 = (*(packet + offset) << 8 | *(packet + offset + 1));
|
||||
offset += 2;
|
||||
dataset.ain7 = (*(packet + offset) << 8 | *(packet + offset + 1));
|
||||
|
||||
#if OBSW_VERBOSE_LEVEL >= 1 && DEBUG_RAD_SENSOR
|
||||
sif::info << "Radiation sensor temperature: " << dataset.temperatureCelcius << " °C"
|
||||
<< std::endl;
|
||||
sif::info << "Radiation sensor temperature ADC value channel 0: " << dataset.channel0
|
||||
sif::info << "Radiation sensor ADC value channel 0: " << dataset.ain0
|
||||
<< std::endl;
|
||||
sif::info << "Radiation sensor temperature ADC value channel 1: " << dataset.channel1
|
||||
sif::info << "Radiation sensor ADC value channel 1: " << dataset.ain1
|
||||
<< std::endl;
|
||||
sif::info << "Radiation sensor ADC value channel 4: " << dataset.ain4
|
||||
<< std::endl;
|
||||
sif::info << "Radiation sensor ADC value channel 5: " << dataset.ain5
|
||||
<< std::endl;
|
||||
sif::info << "Radiation sensor ADC value channel 6: " << dataset.ain6
|
||||
<< std::endl;
|
||||
sif::info << "Radiation sensor ADC value channel 7: " << dataset.ain7
|
||||
<< std::endl;
|
||||
#endif
|
||||
break;
|
||||
@ -151,8 +185,12 @@ uint32_t RadiationSensorHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t mo
|
||||
ReturnValue_t RadiationSensorHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) {
|
||||
localDataPoolMap.emplace(RAD_SENSOR::TEMPERATURE_C, new PoolEntry<float>( { 0.0 }));
|
||||
localDataPoolMap.emplace(RAD_SENSOR::CHANNEL_0, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(RAD_SENSOR::CHANNEL_1, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(RAD_SENSOR::AIN0, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(RAD_SENSOR::AIN1, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(RAD_SENSOR::AIN4, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(RAD_SENSOR::AIN5, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(RAD_SENSOR::AIN6, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(RAD_SENSOR::AIN7, new PoolEntry<uint16_t>( { 0 }));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ ReturnValue_t RwHandler::buildNormalDeviceCommand(DeviceCommandId_t * id) {
|
||||
internalState = InternalState::GET_RESET_STATUS;
|
||||
break;
|
||||
default:
|
||||
sif::debug << "RwHandler::buildNormalDeviceCommand: Invalid communication step"
|
||||
sif::debug << "RwHandler::buildNormalDeviceCommand: Invalid internal step"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
@ -176,8 +176,7 @@ ReturnValue_t RwHandler::scanForReply(const uint8_t *start, size_t remainingSize
|
||||
break;
|
||||
}
|
||||
case (static_cast<uint8_t>(RwDefinitions::GET_TM)): {
|
||||
// *foundLen = RwDefinitions::SIZE_GET_TELEMETRY_REPLY;
|
||||
*foundLen = 91;
|
||||
*foundLen = RwDefinitions::SIZE_GET_TELEMETRY_REPLY;
|
||||
*foundId = RwDefinitions::GET_TM;
|
||||
break;
|
||||
}
|
||||
@ -264,6 +263,8 @@ ReturnValue_t RwHandler::initializeLocalDataPool(localpool::DataPool& localDataP
|
||||
|
||||
localDataPoolMap.emplace(RwDefinitions::TM_LAST_RESET_STATUS, new PoolEntry<uint8_t>( { 0 }));
|
||||
localDataPoolMap.emplace(RwDefinitions::TM_MCU_TEMPERATURE, new PoolEntry<int32_t>( { 0 }));
|
||||
localDataPoolMap.emplace(RwDefinitions::PRESSURE_SENSOR_TEMPERATURE, new PoolEntry<float>( { 0 }));
|
||||
localDataPoolMap.emplace(RwDefinitions::PRESSURE, new PoolEntry<float>( { 0 }));
|
||||
localDataPoolMap.emplace(RwDefinitions::TM_RW_STATE, new PoolEntry<uint8_t>( { 0 }));
|
||||
localDataPoolMap.emplace(RwDefinitions::TM_CLC_MODE, new PoolEntry<uint8_t>( { 0 }));
|
||||
localDataPoolMap.emplace(RwDefinitions::TM_RW_CURR_SPEED, new PoolEntry<int32_t>( { 0 }));
|
||||
@ -407,7 +408,12 @@ void RwHandler::handleGetTelemetryReply(const uint8_t* packet) {
|
||||
tmDataset.mcuTemperature = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16
|
||||
| *(packet + offset + 1) << 8 | *(packet + offset);
|
||||
offset += 4;
|
||||
offset += 8;
|
||||
tmDataset.pressureSensorTemperature = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16
|
||||
| *(packet + offset + 1) << 8 | *(packet + offset);
|
||||
offset += 4;
|
||||
tmDataset.pressure = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16
|
||||
| *(packet + offset + 1) << 8 | *(packet + offset);
|
||||
offset += 4;
|
||||
tmDataset.rwState = *(packet + offset);
|
||||
offset += 1;
|
||||
tmDataset.rwClcMode = *(packet + offset);
|
||||
@ -470,6 +476,10 @@ void RwHandler::handleGetTelemetryReply(const uint8_t* packet) {
|
||||
<< static_cast<unsigned int>(tmDataset.lastResetStatus.value) << std::endl;
|
||||
sif::info << "RwHandler::handleTemperatureReply: MCU temperature: " << tmDataset.mcuTemperature
|
||||
<< std::endl;
|
||||
sif::info << "RwHandler::handleTemperatureReply: Pressure sensor temperature: "
|
||||
<< tmDataset.pressureSensorTemperature << std::endl;
|
||||
sif::info << "RwHandler::handleTemperatureReply: Pressure "
|
||||
<< tmDataset.pressure << std::endl;
|
||||
sif::info << "RwHandler::handleTemperatureReply: State: "
|
||||
<< static_cast<unsigned int>(tmDataset.rwState.value) << std::endl;
|
||||
sif::info << "RwHandler::handleTemperatureReply: CLC mode: "
|
||||
|
216
mission/devices/StarTrackerHandler.cpp
Normal file
216
mission/devices/StarTrackerHandler.cpp
Normal file
@ -0,0 +1,216 @@
|
||||
#include "StarTrackerHandler.h"
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
#include <fsfw/globalfunctions/CRC.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
|
||||
extern "C" {
|
||||
#include <thirdparty/arcsec_star_tracker/client/generated/telemetry.h>
|
||||
#include "common/misc.h"
|
||||
}
|
||||
|
||||
StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF,
|
||||
CookieIF * comCookie) :
|
||||
DeviceHandlerBase(objectId, comIF, comCookie), temperatureSet(this) {
|
||||
if (comCookie == NULL) {
|
||||
sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl;
|
||||
}
|
||||
slipInit();
|
||||
}
|
||||
|
||||
StarTrackerHandler::~StarTrackerHandler() {
|
||||
}
|
||||
|
||||
void StarTrackerHandler::doStartUp() {
|
||||
|
||||
#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1
|
||||
setMode(MODE_NORMAL);
|
||||
#else
|
||||
setMode(_MODE_TO_ON);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void StarTrackerHandler::doShutDown() {
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t * id) {
|
||||
switch (internalState) {
|
||||
case InternalState::TEMPERATURE_REQUEST:
|
||||
*id = StarTracker::REQ_TEMPERATURE;
|
||||
break;
|
||||
default:
|
||||
sif::debug << "StarTrackerHandler::buildNormalDeviceCommand: Invalid internal step"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
return buildCommandFromCommand(*id, NULL, 0);
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::buildTransitionDeviceCommand(DeviceCommandId_t * id) {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t * commandData, size_t commandDataLen) {
|
||||
|
||||
switch (deviceCommand) {
|
||||
case (StarTracker::REQ_TEMPERATURE): {
|
||||
prepareTemperatureRequest();
|
||||
return RETURN_OK;
|
||||
}
|
||||
default:
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
void StarTrackerHandler::fillCommandAndReplyMap() {
|
||||
/** Reply lengths are unknown because of the slip encoding. Thus always maximum reply size
|
||||
* is specified */
|
||||
this->insertInCommandAndReplyMap(StarTracker::REQ_TEMPERATURE, 1, &temperatureSet,
|
||||
StarTracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t remainingSize,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
|
||||
uint32_t decodedLength = 0;
|
||||
|
||||
for (size_t idx = 0; idx < remainingSize; idx++) {
|
||||
enum arc_dec_result decResult = arc_transport_decode_body(*(start + idx), &slipInfo,
|
||||
decodedFrame, &decodedLength);
|
||||
|
||||
switch (decResult) {
|
||||
case ARC_DEC_INPROGRESS: {
|
||||
continue;
|
||||
}
|
||||
case ARC_DEC_ASYNC: {
|
||||
sif::debug << "StarTrackerHandler::scanForReply: Received asychronous tm" << std::endl;
|
||||
/** No asynchronous replies are expected as of now */
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
case ARC_DEC_ERROR_FRAME_SHORT:
|
||||
return REPLY_TOO_SHORT;
|
||||
case ARC_DEC_ERROR_CHECKSUM:
|
||||
return CRC_FAILURE;
|
||||
case ARC_DEC_SYNC: {
|
||||
/** Reset length of SLIP struct for next frame */
|
||||
slipInfo.length = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sif::debug << "StarTrackerHandler::scanForReply: Unknown result code" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (decodedFrame[1]) {
|
||||
case (static_cast<uint8_t>(StarTracker::REQ_TEMPERATURE)): {
|
||||
*foundLen = decodedLength;
|
||||
*foundId = StarTracker::REQ_TEMPERATURE;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "StarTrackerHandler::scanForReply: Reply contains invalid reply id"
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
|
||||
|
||||
switch (id) {
|
||||
case (StarTracker::REQ_TEMPERATURE): {
|
||||
handleTemperatureTm();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "StarTrackerHandler::interpretDeviceReply: Unknown device reply id" << std::endl;
|
||||
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
|
||||
}
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void StarTrackerHandler::setNormalDatapoolEntriesInvalid() {
|
||||
|
||||
}
|
||||
|
||||
uint32_t StarTrackerHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) {
|
||||
return 5000;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) {
|
||||
|
||||
localDataPoolMap.emplace(StarTracker::STATUS, new PoolEntry<uint8_t>( { 0 }));
|
||||
localDataPoolMap.emplace(StarTracker::TICKS, new PoolEntry<uint32_t>( { 0 }));
|
||||
localDataPoolMap.emplace(StarTracker::TIME, new PoolEntry<uint64_t>( { 0 }));
|
||||
localDataPoolMap.emplace(StarTracker::MCU_TEMPERATURE, new PoolEntry<float>( { 0 }));
|
||||
localDataPoolMap.emplace(StarTracker::CMOS_TEMPERATURE, new PoolEntry<float>( { 0 }));
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
size_t StarTrackerHandler::getNextReplyLength(DeviceCommandId_t commandId){
|
||||
return StarTracker::MAX_FRAME_SIZE;
|
||||
}
|
||||
|
||||
void StarTrackerHandler::slipInit() {
|
||||
slipInfo.buffer = rxBuffer;
|
||||
slipInfo.maxlength = StarTracker::MAX_FRAME_SIZE;
|
||||
slipInfo.length = 0;
|
||||
slipInfo.unescape_next = 0;
|
||||
slipInfo.prev_state = SLIP_COMPLETE;
|
||||
}
|
||||
|
||||
void StarTrackerHandler::prepareTemperatureRequest() {
|
||||
uint32_t length = 0;
|
||||
arc_tm_pack_temperature_req(commandBuffer, &length);
|
||||
uint32_t encLength = 0;
|
||||
arc_transport_encode_body(commandBuffer, length, encBuffer, &encLength);
|
||||
rawPacket = encBuffer;
|
||||
rawPacketLen = encLength;
|
||||
}
|
||||
|
||||
void StarTrackerHandler::handleTemperatureTm() {
|
||||
PoolReadGuard rg(&temperatureSet);
|
||||
uint32_t offset = 1;
|
||||
temperatureSet.status = *(decodedFrame + offset);
|
||||
offset += 1;
|
||||
if(temperatureSet.status.value != 0) {
|
||||
sif::warning << "StarTrackerHandler::handleTemperatureTm: Reply error: "
|
||||
<< static_cast<unsigned int>(temperatureSet.status.value) << std::endl;
|
||||
triggerEvent(TM_REPLY_ERROR, temperatureSet.status.value);
|
||||
}
|
||||
temperatureSet.ticks = *(decodedFrame + offset) << 24
|
||||
| *(decodedFrame + offset + 1) << 16 | *(decodedFrame + offset + 2) << 8
|
||||
| *(decodedFrame + offset + 3);
|
||||
offset += 4;
|
||||
temperatureSet.time = static_cast<uint64_t>(*(decodedFrame + offset)) << 56
|
||||
| static_cast<uint64_t>(*(decodedFrame + offset + 1)) << 48
|
||||
| static_cast<uint64_t>(*(decodedFrame + offset + 2)) << 40
|
||||
| static_cast<uint64_t>(*(decodedFrame + offset + 3)) << 32
|
||||
| *(decodedFrame + offset + 4) << 24 | *(decodedFrame + offset + 5) << 16
|
||||
| *(decodedFrame + offset + 6) << 8 | *(decodedFrame + offset + 7);
|
||||
offset += 8;
|
||||
temperatureSet.mcuTemperature = *(decodedFrame + offset) << 24
|
||||
| *(decodedFrame + offset + 1) << 16 | *(decodedFrame + offset + 2) << 8
|
||||
| *(decodedFrame + offset + 3);
|
||||
offset += 4;
|
||||
temperatureSet.cmosTemperature = *(decodedFrame + offset) << 24
|
||||
| *(decodedFrame + offset + 1) << 16 | *(decodedFrame + offset + 2) << 8
|
||||
| *(decodedFrame + offset + 3);
|
||||
#if OBSW_VERBOSE_LEVEL >= 1 && START_TRACKER_DEBUG == 1
|
||||
sif::info << "StarTrackerHandler::handleTemperatureTm: MCU Temperature: "
|
||||
<< temperatureSet.mcuTemperature << " °C" << std::endl;
|
||||
sif::info << "StarTrackerHandler::handleTemperatureTm: CMOS Temperature: "
|
||||
<< temperatureSet.mcuTemperature << " °C" << std::endl;
|
||||
#endif
|
||||
}
|
100
mission/devices/StarTrackerHandler.h
Normal file
100
mission/devices/StarTrackerHandler.h
Normal file
@ -0,0 +1,100 @@
|
||||
#ifndef MISSION_DEVICES_STARTRACKERHANDLER_H_
|
||||
#define MISSION_DEVICES_STARTRACKERHANDLER_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <mission/devices/devicedefinitions/StarTrackerDefinitions.h>
|
||||
#include <thirdparty/arcsec_star_tracker/common/SLIP.h>
|
||||
|
||||
/**
|
||||
* @brief This is the device handler for the star tracker from arcsec.
|
||||
*
|
||||
* @details Datasheet: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/
|
||||
* Arbeitsdaten/08_Used%20Components/ArcSec_KULeuven_Startracker/
|
||||
* Sagitta%201.0%20Datapack&fileid=659181
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class StarTrackerHandler: public DeviceHandlerBase {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param objectId
|
||||
* @param comIF
|
||||
* @param comCookie
|
||||
* @param gpioComIF Pointer to gpio communication interface
|
||||
* @param enablePin GPIO connected to the enable pin of the reaction wheels. Must be pulled
|
||||
* to high to enable the device.
|
||||
*/
|
||||
StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie);
|
||||
virtual ~StarTrackerHandler();
|
||||
|
||||
protected:
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override;
|
||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) override;
|
||||
void fillCommandAndReplyMap() override;
|
||||
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t * commandData,size_t commandDataLen) override;
|
||||
ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) override;
|
||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) override;
|
||||
void setNormalDatapoolEntriesInvalid() override;
|
||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
|
||||
/**
|
||||
* @brief Overwritten here to always read all available data from the UartComIF.
|
||||
*/
|
||||
virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
|
||||
|
||||
private:
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] Received reply is too short
|
||||
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xB0);
|
||||
//! [EXPORT] : [COMMENT] Received reply with invalid CRC
|
||||
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xB0);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] Result code of tm reply indicates an error
|
||||
static const ReturnValue_t TM_REPLY_ERROR = MAKE_RETURN_CODE(0xA0);
|
||||
//! P1: TM id
|
||||
|
||||
StarTracker::TemperatureSet temperatureSet;
|
||||
|
||||
uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE];
|
||||
uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE];
|
||||
uint8_t decodedFrame[StarTracker::MAX_FRAME_SIZE];
|
||||
|
||||
/** Size of buffer derived from the egse source code */
|
||||
uint8_t encBuffer[StarTracker::MAX_FRAME_SIZE * 2 + 2];
|
||||
|
||||
slip_decode_state slipInfo;
|
||||
|
||||
enum class InternalState {
|
||||
TEMPERATURE_REQUEST
|
||||
};
|
||||
|
||||
InternalState internalState = InternalState::TEMPERATURE_REQUEST;
|
||||
|
||||
/**
|
||||
* @brief This function initializes the serial link ip protocol struct slipInfo.
|
||||
*/
|
||||
void slipInit();
|
||||
|
||||
void prepareTemperatureRequest();
|
||||
|
||||
/**
|
||||
* @brief This function handles the telemetry reply of a temperature request.
|
||||
*/
|
||||
void handleTemperatureTm();
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */
|
@ -1,11 +1,11 @@
|
||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCDEFINITIONS_H_
|
||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCDEFINITIONS_H_
|
||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
|
||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
|
||||
|
||||
#include <fsfw/tmtcpacket/SpacePacket.h>
|
||||
#include <fsfw/globalfunctions/CRC.h>
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
|
||||
namespace PLOC {
|
||||
namespace PLOC_MPSOC {
|
||||
|
||||
static const DeviceCommandId_t NONE = 0x0;
|
||||
static const DeviceCommandId_t TC_MEM_WRITE = 0x1;
|
||||
@ -169,4 +169,4 @@ namespace PLOC {
|
||||
}
|
||||
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCDEFINITIONS_H_ */
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_ */
|
397
mission/devices/devicedefinitions/PlocSupervisorDefinitions.h
Normal file
397
mission/devices/devicedefinitions/PlocSupervisorDefinitions.h
Normal file
@ -0,0 +1,397 @@
|
||||
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_
|
||||
#define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_
|
||||
|
||||
#include <fsfw/tmtcpacket/SpacePacket.h>
|
||||
#include <fsfw/globalfunctions/CRC.h>
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
#include <fsfw/timemanager/Clock.h>
|
||||
|
||||
namespace PLOC_SPV {
|
||||
|
||||
/** Command IDs */
|
||||
static const DeviceCommandId_t NONE = 0;
|
||||
static const DeviceCommandId_t GET_HK_REPORT = 1;
|
||||
static const DeviceCommandId_t RESTART_MPSOC = 2;
|
||||
static const DeviceCommandId_t START_MPSOC = 3;
|
||||
static const DeviceCommandId_t SHUTDOWN_MPSOC = 4;
|
||||
static const DeviceCommandId_t SEL_MPSOC_BOOT_IMAGE = 5;
|
||||
static const DeviceCommandId_t SET_BOOT_TIMEOUT = 6;
|
||||
static const DeviceCommandId_t SET_MAX_RESTART_TRIES = 7;
|
||||
static const DeviceCommandId_t RESET_MPSOC = 8;
|
||||
static const DeviceCommandId_t SET_TIME_REF = 9;
|
||||
static const DeviceCommandId_t DISABLE_PERIOIC_HK_TRANSMISSION = 10;
|
||||
|
||||
/** Reply IDs */
|
||||
static const DeviceCommandId_t ACK_REPORT = 50;
|
||||
static const DeviceCommandId_t EXE_REPORT = 51;
|
||||
static const DeviceCommandId_t HK_REPORT = 52;
|
||||
|
||||
static const uint16_t SIZE_ACK_REPORT = 14;
|
||||
static const uint16_t SIZE_EXE_REPORT = 14;
|
||||
static const uint16_t SIZE_HK_REPORT = 48;
|
||||
|
||||
/**
|
||||
* SpacePacket apids of telemetry packets
|
||||
*/
|
||||
static const uint16_t APID_ACK_SUCCESS = 0x200;
|
||||
static const uint16_t APID_ACK_FAILURE = 0x201;
|
||||
static const uint16_t APID_EXE_SUCCESS = 0x202;
|
||||
static const uint16_t APID_EXE_FAILURE = 0x203;
|
||||
static const uint16_t APID_HK_REPORT = 0x204;
|
||||
static const uint16_t APID_BOOT_STATUS_REPORT = 0x205;
|
||||
static const uint16_t APID_UPDATE_STATUS_REPORT = 0x206;
|
||||
static const uint16_t APID_WDG_STATUS_REPORT = 0x207;
|
||||
static const uint16_t APID_LATCHUP_STATUS_REPORT = 0x208;
|
||||
static const uint16_t APID_SOC_SYSMON = 0x209;
|
||||
static const uint16_t APID_MRAM = 0x20A;
|
||||
static const uint16_t APID_SRAM = 0x20B;
|
||||
static const uint16_t APID_NOR_DATA = 0x20C;
|
||||
static const uint16_t APID_DATA_LOGGER_DATA = 0x20D;
|
||||
|
||||
/**
|
||||
* APIDs of telecommand packets
|
||||
*/
|
||||
static const uint16_t APID_RESTART_MPSOC = 0xA0;
|
||||
static const uint16_t APID_START_MPSOC = 0xA1;
|
||||
static const uint16_t APID_SHUTWOWN_MPSOC = 0xA2;
|
||||
static const uint16_t APID_SEL_MPSOC_BOOT_IMAGE = 0xA3;
|
||||
static const uint16_t APID_SET_BOOT_TIMEOUT = 0xA4;
|
||||
static const uint16_t APID_SET_MAX_RESTART_TRIES = 0xA5;
|
||||
static const uint16_t APID_RESET_MPSOC = 0xA6;
|
||||
static const uint16_t APID_GET_BOOT_STATUS_RPT = 0xA8;
|
||||
static const uint16_t APID_UPDATE_AVAILABLE = 0xB0;
|
||||
static const uint16_t APID_UPDATE_IMAGE_DATA = 0xB1;
|
||||
static const uint16_t APID_UPDATE_VERIFY = 0xB2;
|
||||
static const uint16_t APID_WTD_ENABLE = 0xC0;
|
||||
static const uint16_t APID_WTD_CONFIG_TIMEOUT = 0xC1;
|
||||
static const uint16_t APID_SET_TIME_REF = 0xC2;
|
||||
static const uint16_t APID_DISABLE_HK = 0xC3;
|
||||
|
||||
static const uint16_t APID_GET_HK_REPORT = 0xC6;
|
||||
|
||||
/** Offset from first byte in Space packet to first byte of data field */
|
||||
static const uint8_t DATA_FIELD_OFFSET = 6;
|
||||
|
||||
/**
|
||||
* Space packet length for fixed size packets. This is the size of the whole packet data
|
||||
* field. For the length field in the space packet this size will be substracted by one.
|
||||
*/
|
||||
static const uint16_t LENGTH_EMPTY_TC = 2; // Only CRC will be transported with the data field
|
||||
|
||||
/** This is the maximum length of a space packet as defined by the TAS ICD */
|
||||
static const size_t MAX_REPLY_SIZE = 1024;
|
||||
static const size_t MAX_COMMAND_SIZE = 1024;
|
||||
|
||||
enum SequenceFlags {
|
||||
CONTINUED_PKT = 0b00, FIRST_PKT = 0b01, LAST_PKT = 0b10, STANDALONE_PKT = 0b11
|
||||
};
|
||||
|
||||
enum PoolIds
|
||||
: lp_id_t {
|
||||
NUM_TMS,
|
||||
TEMP_PS,
|
||||
TEMP_PL,
|
||||
SOC_STATE,
|
||||
NVM0_1_STATE,
|
||||
NVM3_STATE,
|
||||
MISSION_IO_STATE,
|
||||
FMC_STATE,
|
||||
NUM_TCS,
|
||||
TEMP_SUP,
|
||||
UPTIME,
|
||||
CPULOAD,
|
||||
AVAILABLEHEAP
|
||||
};
|
||||
|
||||
static const uint8_t HK_SET_ENTRIES = 13;
|
||||
|
||||
static const uint32_t HK_SET_ID = HK_REPORT;
|
||||
|
||||
/**
|
||||
* @brief With this class a space packet can be created which does not contain any data.
|
||||
*/
|
||||
class EmptyPacket: public SpacePacket {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param apid The APID to set in the space packet.
|
||||
*
|
||||
* @note Sequence count of empty packet is always 1.
|
||||
*/
|
||||
EmptyPacket(uint16_t apid) :
|
||||
SpacePacket(LENGTH_EMPTY_TC - 1, true, apid, 1) {
|
||||
calcCrc();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief CRC calculation which involves only the header in an empty packet
|
||||
*/
|
||||
void calcCrc() {
|
||||
|
||||
/* Calculate crc */
|
||||
uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader));
|
||||
|
||||
/* Add crc to packet data field of space packet */
|
||||
size_t serializedSize = 0;
|
||||
uint8_t* crcPos = this->localData.fields.buffer;
|
||||
SerializeAdapter::serialize<uint16_t>(&crc, &crcPos, &serializedSize, sizeof(crc),
|
||||
SerializeIF::Endianness::BIG);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class can be used to generate the space packet selecting the boot image of
|
||||
* of the MPSoC.
|
||||
*/
|
||||
class MPSoCBootSelect: public SpacePacket {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param mem The memory to boot from: NVM0 (0), NVM1 (1)
|
||||
* @param bp0 Partition pin 0
|
||||
* @param bp1 Partition pin 1
|
||||
* @param bp2 Partition pin 2
|
||||
*/
|
||||
MPSoCBootSelect(uint8_t mem, uint8_t bp0, uint8_t bp1, uint8_t bp2) :
|
||||
SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SEL_MPSOC_BOOT_IMAGE,
|
||||
DEFAULT_SEQUENCE_COUNT), mem(mem), bp0(bp0), bp1(bp1), bp2(bp2) {
|
||||
initPacket();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static const uint16_t DATA_FIELD_LENGTH = 6;
|
||||
static const uint16_t DEFAULT_SEQUENCE_COUNT = 1;
|
||||
|
||||
static const uint8_t MEM_OFFSET = 0;
|
||||
static const uint8_t BP0_OFFSET = 1;
|
||||
static const uint8_t BP1_OFFSET = 2;
|
||||
static const uint8_t BP2_OFFSET = 3;
|
||||
static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2;
|
||||
|
||||
uint8_t mem = 0;
|
||||
uint8_t bp0 = 0;
|
||||
uint8_t bp1 = 0;
|
||||
uint8_t bp2 = 0;
|
||||
|
||||
void initPacket() {
|
||||
uint8_t* data_field_start = this->localData.fields.buffer;
|
||||
std::memcpy(data_field_start + MEM_OFFSET, &mem, sizeof(mem));
|
||||
std::memcpy(data_field_start + BP0_OFFSET, &bp0, sizeof(bp0));
|
||||
std::memcpy(data_field_start + BP1_OFFSET, &bp1, sizeof(bp1));
|
||||
std::memcpy(data_field_start + BP2_OFFSET, &bp2, sizeof(bp2));
|
||||
/* Calculate crc */
|
||||
uint16_t crc = CRC::crc16ccitt(this->localData.byteStream,
|
||||
sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2);
|
||||
|
||||
/* Add crc to packet data field of space packet */
|
||||
size_t serializedSize = 0;
|
||||
uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET;
|
||||
SerializeAdapter::serialize<uint16_t>(&crc, &crcPos, &serializedSize, sizeof(crc),
|
||||
SerializeIF::Endianness::BIG);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class generates the space packet to update the time of the PLOC supervisor.
|
||||
*/
|
||||
class SetTimeRef: public SpacePacket {
|
||||
public:
|
||||
|
||||
SetTimeRef(Clock::TimeOfDay_t* time) :
|
||||
SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_TIME_REF, DEFAULT_SEQUENCE_COUNT) {
|
||||
initPacket(time);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static const uint16_t DATA_FIELD_LENGTH = 34;
|
||||
static const uint16_t DEFAULT_SEQUENCE_COUNT = 1;
|
||||
static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2;
|
||||
|
||||
void initPacket(Clock::TimeOfDay_t* time) {
|
||||
size_t serializedSize = 0;
|
||||
uint8_t* data_field_ptr = this->localData.fields.buffer;
|
||||
SerializeAdapter::serialize<uint32_t>(&time->second, &data_field_ptr, &serializedSize,
|
||||
sizeof(time->second), SerializeIF::Endianness::BIG);
|
||||
serializedSize = 0;
|
||||
SerializeAdapter::serialize<uint32_t>(&time->minute, &data_field_ptr, &serializedSize,
|
||||
sizeof(time->minute), SerializeIF::Endianness::BIG);
|
||||
serializedSize = 0;
|
||||
SerializeAdapter::serialize<uint32_t>(&time->hour, &data_field_ptr, &serializedSize,
|
||||
sizeof(time->hour), SerializeIF::Endianness::BIG);
|
||||
serializedSize = 0;
|
||||
SerializeAdapter::serialize<uint32_t>(&time->day, &data_field_ptr, &serializedSize,
|
||||
sizeof(time->day), SerializeIF::Endianness::BIG);
|
||||
serializedSize = 0;
|
||||
SerializeAdapter::serialize<uint32_t>(&time->month, &data_field_ptr, &serializedSize,
|
||||
sizeof(time->month), SerializeIF::Endianness::BIG);
|
||||
serializedSize = 0;
|
||||
SerializeAdapter::serialize<uint32_t>(&time->year, &data_field_ptr, &serializedSize,
|
||||
sizeof(time->year), SerializeIF::Endianness::BIG);
|
||||
serializedSize = 0;
|
||||
uint32_t milliseconds = time->usecond / 1000;
|
||||
SerializeAdapter::serialize<uint32_t>(&milliseconds, &data_field_ptr, &serializedSize,
|
||||
sizeof(milliseconds), SerializeIF::Endianness::BIG);
|
||||
serializedSize = 0;
|
||||
uint32_t isSet = 0xFFFFFFFF;
|
||||
SerializeAdapter::serialize<uint32_t>(&isSet, &data_field_ptr, &serializedSize,
|
||||
sizeof(isSet), SerializeIF::Endianness::BIG);
|
||||
serializedSize = 0;
|
||||
/* Calculate crc */
|
||||
uint16_t crc = CRC::crc16ccitt(this->localData.byteStream,
|
||||
sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2);
|
||||
SerializeAdapter::serialize<uint16_t>(&crc, &data_field_ptr, &serializedSize, sizeof(crc),
|
||||
SerializeIF::Endianness::BIG);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class can be used to generate the set boot timout command.
|
||||
*/
|
||||
class SetBootTimeout: public SpacePacket {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param timeout The boot timeout in milliseconds.
|
||||
*/
|
||||
SetBootTimeout(uint32_t timeout) :
|
||||
SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_BOOT_TIMEOUT, 1), timeout(timeout) {
|
||||
initPacket();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint32_t timeout = 0;
|
||||
|
||||
/** boot timeout value (uint32_t) and crc (uint16_t) */
|
||||
static const uint16_t DATA_FIELD_LENGTH = 6;
|
||||
|
||||
void initPacket() {
|
||||
|
||||
size_t serializedSize = 0;
|
||||
uint8_t* data_field_ptr = this->localData.fields.buffer;
|
||||
SerializeAdapter::serialize<uint32_t>(&timeout, &data_field_ptr, &serializedSize,
|
||||
sizeof(timeout), SerializeIF::Endianness::BIG);
|
||||
/* Calculate crc */
|
||||
uint16_t crc = CRC::crc16ccitt(this->localData.byteStream,
|
||||
sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2);
|
||||
/* Add crc to packet data field of space packet */
|
||||
serializedSize = 0;
|
||||
SerializeAdapter::serialize<uint16_t>(&crc, &data_field_ptr, &serializedSize, sizeof(crc),
|
||||
SerializeIF::Endianness::BIG);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class can be used to generate the space packet to set the maximum boot tries.
|
||||
*/
|
||||
class SetRestartTries: public SpacePacket {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param restartTries Maximum restart tries to set.
|
||||
*/
|
||||
SetRestartTries(uint8_t restartTries) :
|
||||
SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_MAX_RESTART_TRIES, 1), restartTries(
|
||||
restartTries) {
|
||||
initPacket();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint8_t restartTries = 0;
|
||||
|
||||
/** Restart tries value (uint8_t) and crc (uint16_t) */
|
||||
static const uint16_t DATA_FIELD_LENGTH = 3;
|
||||
|
||||
void initPacket() {
|
||||
uint8_t* data_field_ptr = this->localData.fields.buffer;
|
||||
*data_field_ptr = restartTries;
|
||||
uint16_t crc = CRC::crc16ccitt(this->localData.byteStream,
|
||||
sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2);
|
||||
size_t serializedSize = 0;
|
||||
uint8_t* crcPtr = data_field_ptr + 1;
|
||||
SerializeAdapter::serialize<uint16_t>(&crc, &crcPtr, &serializedSize, sizeof(crc),
|
||||
SerializeIF::Endianness::BIG);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief With this class the space packet can be generated to disable to periodic transmission
|
||||
* of housekeeping data. Normally, this will be disabled by default. However, adding this
|
||||
* command can be useful for debugging.
|
||||
*/
|
||||
class DisablePeriodicHkTransmission: public SpacePacket {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
DisablePeriodicHkTransmission() :
|
||||
SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_DISABLE_HK, 1) {
|
||||
initPacket();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint8_t disableHk = 0;
|
||||
|
||||
/** Restart tries value (uint8_t) and crc (uint16_t) */
|
||||
static const uint16_t DATA_FIELD_LENGTH = 3;
|
||||
|
||||
void initPacket() {
|
||||
uint8_t* data_field_ptr = this->localData.fields.buffer;
|
||||
*data_field_ptr = disableHk;
|
||||
uint16_t crc = CRC::crc16ccitt(this->localData.byteStream,
|
||||
sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2);
|
||||
size_t serializedSize = 0;
|
||||
uint8_t* crcPtr = data_field_ptr + 1;
|
||||
SerializeAdapter::serialize<uint16_t>(&crc, &crcPtr, &serializedSize, sizeof(crc),
|
||||
SerializeIF::Endianness::BIG);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This dataset to store the housekeeping data of the supervisor.
|
||||
*/
|
||||
class HkSet: public StaticLocalDataSet<HK_SET_ENTRIES> {
|
||||
public:
|
||||
|
||||
HkSet(HasLocalDataPoolIF* owner) :
|
||||
StaticLocalDataSet(owner, HK_SET_ID) {
|
||||
}
|
||||
|
||||
HkSet(object_id_t objectId) :
|
||||
StaticLocalDataSet(sid_t(objectId, HK_SET_ID)) {
|
||||
}
|
||||
|
||||
lp_var_t<uint32_t> numTms = lp_var_t<uint32_t>(sid.objectId, PoolIds::NUM_TMS, this);
|
||||
lp_var_t<uint32_t> tempPs = lp_var_t<uint32_t>(sid.objectId, PoolIds::TEMP_PS, this);
|
||||
lp_var_t<uint32_t> tempPl = lp_var_t<uint32_t>(sid.objectId, PoolIds::TEMP_PS, this);
|
||||
lp_var_t<uint32_t> socState = lp_var_t<uint32_t>(sid.objectId, PoolIds::SOC_STATE, this);
|
||||
lp_var_t<uint8_t> nvm0_1_state = lp_var_t<uint8_t>(sid.objectId, PoolIds::NVM0_1_STATE, this);
|
||||
lp_var_t<uint8_t> nvm3_state = lp_var_t<uint8_t>(sid.objectId, PoolIds::NVM3_STATE, this);
|
||||
lp_var_t<uint8_t> missionIoState = lp_var_t<uint8_t>(sid.objectId, PoolIds::MISSION_IO_STATE,
|
||||
this);
|
||||
lp_var_t<uint8_t> fmcState = lp_var_t<uint8_t>(sid.objectId, PoolIds::FMC_STATE, this);
|
||||
lp_var_t<uint32_t> numTcs = lp_var_t<uint32_t>(sid.objectId, PoolIds::NUM_TCS, this);
|
||||
lp_var_t<uint32_t> tempSup = lp_var_t<uint32_t>(sid.objectId, PoolIds::TEMP_SUP, this);
|
||||
lp_var_t<uint32_t> uptime = lp_var_t<uint32_t>(sid.objectId, PoolIds::UPTIME, this);
|
||||
lp_var_t<uint32_t> cpuLoad = lp_var_t<uint32_t>(sid.objectId, PoolIds::CPULOAD, this);
|
||||
lp_var_t<uint32_t> availableHeap = lp_var_t<uint32_t>(sid.objectId, PoolIds::AVAILABLEHEAP,
|
||||
this);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_ */
|
@ -30,10 +30,11 @@ namespace RAD_SENSOR {
|
||||
* conversions to perform.
|
||||
* @details Bit0: 1 - Enables temperature conversion
|
||||
* Bit2 (SCAN1) and Bit1 (SCAN0): 0b00 (channel conversion from 0 to N)
|
||||
* Bit6 - Bit3 defines N: 0b0001 (N = 1)
|
||||
* Bit6 - Bit3 defines N: 0b0111 (N = 7)
|
||||
* Bit7: Always 1. Tells the ADC that this is the conversion register.
|
||||
*/
|
||||
static const uint8_t CONVERSION_DEFINITION = 0b10001001;
|
||||
static const uint8_t CONVERSION_DEFINITION = 0b10111001;
|
||||
// static const uint8_t CONVERSION_DEFINITION = 0b10111111;
|
||||
|
||||
/**
|
||||
* @brief Writing this value resets the fifo of the MAX1227.
|
||||
@ -44,18 +45,23 @@ namespace RAD_SENSOR {
|
||||
|
||||
static const uint8_t RAD_SENSOR_DATA_SET_ID = READ_CONVERSIONS;
|
||||
|
||||
static const uint8_t DATASET_ENTRIES = 7;
|
||||
/**
|
||||
* One temperature value, conversion of channel 0 and conversion of channel 1
|
||||
* One temperature value and conversions for AIN0 - AIN7
|
||||
*/
|
||||
static const uint8_t READ_SIZE = 6;
|
||||
static const uint8_t READ_SIZE = 18;
|
||||
|
||||
enum Max1227PoolIds: lp_id_t {
|
||||
TEMPERATURE_C,
|
||||
CHANNEL_0,
|
||||
CHANNEL_1,
|
||||
AIN0,
|
||||
AIN1,
|
||||
AIN4,
|
||||
AIN5,
|
||||
AIN6,
|
||||
AIN7,
|
||||
};
|
||||
|
||||
class RadSensorDataset: public StaticLocalDataSet<sizeof(float)> {
|
||||
class RadSensorDataset: public StaticLocalDataSet<DATASET_ENTRIES> {
|
||||
public:
|
||||
|
||||
RadSensorDataset(HasLocalDataPoolIF* owner) :
|
||||
@ -67,8 +73,12 @@ public:
|
||||
}
|
||||
|
||||
lp_var_t<float> temperatureCelcius = lp_var_t<float>(sid.objectId, TEMPERATURE_C, this);
|
||||
lp_var_t<uint16_t> channel0 = lp_var_t<uint16_t>(sid.objectId, CHANNEL_0, this);
|
||||
lp_var_t<uint16_t> channel1 = lp_var_t<uint16_t>(sid.objectId, CHANNEL_1, this);
|
||||
lp_var_t<uint16_t> ain0 = lp_var_t<uint16_t>(sid.objectId, AIN0, this);
|
||||
lp_var_t<uint16_t> ain1 = lp_var_t<uint16_t>(sid.objectId, AIN1, this);
|
||||
lp_var_t<uint16_t> ain4 = lp_var_t<uint16_t>(sid.objectId, AIN4, this);
|
||||
lp_var_t<uint16_t> ain5 = lp_var_t<uint16_t>(sid.objectId, AIN5, this);
|
||||
lp_var_t<uint16_t> ain6 = lp_var_t<uint16_t>(sid.objectId, AIN6, this);
|
||||
lp_var_t<uint16_t> ain7 = lp_var_t<uint16_t>(sid.objectId, AIN7, this);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,8 @@ enum PoolIds: lp_id_t {
|
||||
CURRRENT_RESET_STATUS,
|
||||
TM_LAST_RESET_STATUS,
|
||||
TM_MCU_TEMPERATURE,
|
||||
PRESSURE_SENSOR_TEMPERATURE,
|
||||
PRESSURE,
|
||||
TM_RW_STATE,
|
||||
TM_CLC_MODE,
|
||||
TM_RW_CURR_SPEED,
|
||||
@ -83,7 +85,7 @@ static const size_t SIZE_GET_RW_STATUS = 14;
|
||||
static const size_t SIZE_SET_SPEED_REPLY = 4;
|
||||
static const size_t SIZE_GET_TEMPERATURE_REPLY = 8;
|
||||
/** Max size when requesting telemetry */
|
||||
static const size_t SIZE_GET_TELEMETRY_REPLY = 83;
|
||||
static const size_t SIZE_GET_TELEMETRY_REPLY = 91;
|
||||
|
||||
/** Set speed command has maximum size */
|
||||
static const size_t MAX_CMD_SIZE = 9;
|
||||
@ -96,7 +98,7 @@ static const size_t MAX_REPLY_SIZE = 2 * SIZE_GET_TELEMETRY_REPLY;
|
||||
static const uint8_t LAST_RESET_ENTRIES = 2;
|
||||
static const uint8_t TEMPERATURE_SET_ENTRIES = 1;
|
||||
static const uint8_t STATUS_SET_ENTRIES = 4;
|
||||
static const uint8_t TM_SET_ENTRIES = 22;
|
||||
static const uint8_t TM_SET_ENTRIES = 24;
|
||||
|
||||
/**
|
||||
* @brief This dataset can be used to store the temperature of a reaction wheel.
|
||||
@ -184,6 +186,10 @@ public:
|
||||
PoolIds::TM_LAST_RESET_STATUS, this);
|
||||
lp_var_t<int32_t> mcuTemperature = lp_var_t<int32_t>(sid.objectId,
|
||||
PoolIds::TM_MCU_TEMPERATURE, this);
|
||||
lp_var_t<float> pressureSensorTemperature = lp_var_t<float>(sid.objectId,
|
||||
PoolIds::PRESSURE_SENSOR_TEMPERATURE, this);
|
||||
lp_var_t<float> pressure = lp_var_t<float>(sid.objectId,
|
||||
PoolIds::PRESSURE, this);
|
||||
lp_var_t<uint8_t> rwState = lp_var_t<uint8_t>(sid.objectId,
|
||||
PoolIds::TM_RW_STATE, this);
|
||||
lp_var_t<uint8_t> rwClcMode = lp_var_t<uint8_t>(sid.objectId,
|
||||
|
64
mission/devices/devicedefinitions/StarTrackerDefinitions.h
Normal file
64
mission/devices/devicedefinitions/StarTrackerDefinitions.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef MISSION_STARTRACKER_DEFINITIONS_H_
|
||||
#define MISSION_STARTRACKER_DEFINITIONS_H_
|
||||
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include "objects/systemObjectList.h"
|
||||
|
||||
namespace StarTracker {
|
||||
|
||||
/** This is the address of the star tracker */
|
||||
static const uint8_t ADDRESS = 33;
|
||||
|
||||
enum PoolIds: lp_id_t {
|
||||
STATUS,
|
||||
TICKS,
|
||||
TIME,
|
||||
MCU_TEMPERATURE,
|
||||
CMOS_TEMPERATURE
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const DeviceCommandId_t REQ_TEMPERATURE = 25;
|
||||
|
||||
static const uint32_t TEMPERATURE_SET_ID = REQ_TEMPERATURE;
|
||||
|
||||
/** Max size of unencoded frame */
|
||||
static const size_t MAX_FRAME_SIZE = 1200;
|
||||
|
||||
static const uint8_t TEMPERATURE_SET_ENTRIES = 5;
|
||||
|
||||
/**
|
||||
* @brief This dataset can be used to store the temperature of a reaction wheel.
|
||||
*/
|
||||
class TemperatureSet:
|
||||
public StaticLocalDataSet<TEMPERATURE_SET_ENTRIES> {
|
||||
public:
|
||||
|
||||
TemperatureSet(HasLocalDataPoolIF* owner):
|
||||
StaticLocalDataSet(owner, TEMPERATURE_SET_ID) {
|
||||
}
|
||||
|
||||
TemperatureSet(object_id_t objectId):
|
||||
StaticLocalDataSet(sid_t(objectId, TEMPERATURE_SET_ID)) {
|
||||
}
|
||||
|
||||
lp_var_t<uint8_t> status = lp_var_t<uint8_t>(sid.objectId,
|
||||
PoolIds::STATUS, this);
|
||||
lp_var_t<uint32_t> ticks = lp_var_t<uint32_t>(sid.objectId,
|
||||
PoolIds::TICKS, this);
|
||||
/** Unix time in microseconds */
|
||||
lp_var_t<uint64_t> time = lp_var_t<uint64_t>(sid.objectId,
|
||||
PoolIds::TIME, this);
|
||||
lp_var_t<float> mcuTemperature = lp_var_t<float>(sid.objectId,
|
||||
PoolIds::MCU_TEMPERATURE, this);
|
||||
lp_var_t<float> cmosTemperature = lp_var_t<float>(sid.objectId,
|
||||
PoolIds::CMOS_TEMPERATURE, this);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* MISSION_STARTRACKER_DEFINITIONS_H_ */
|
||||
|
1
thirdparty/arcsec_star_tracker
vendored
Submodule
1
thirdparty/arcsec_star_tracker
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f596c53315f1f81facb28faec3150612a5ad2ca0
|
Loading…
Reference in New Issue
Block a user