diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d76f2fb..59d9d32d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,6 +177,7 @@ endif() if(NOT EIVE_BUILD_WATCHDOG) if(NOT EIVE_BUILD_UNITTESTS) if(EIVE_ADD_LINUX_FILES) + add_subdirectory(${LIB_ARCSEC_PATH}) add_subdirectory(${LINUX_PATH}) endif() add_subdirectory(${BSP_PATH}) @@ -192,7 +193,6 @@ if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT EIVE_BUILD_WATCHDOG)) add_subdirectory(${FSFW_PATH}) add_subdirectory(${MISSION_PATH}) add_subdirectory(${TEST_PATH}) - add_subdirectory(${LIB_ARCSEC_PATH}) endif() if(EIVE_BUILD_UNITTESTS) diff --git a/README.md b/README.md index ff2c359d..5ac8f6e6 100644 --- a/README.md +++ b/README.md @@ -11,14 +11,15 @@ 4. [Useful and Common Host Commands](#host-commands) 5. [Setting up Prerequisites](#set-up-prereq) 6. [Remote Debugging](#remote-debugging) -7. [TMTC testing](#tmtc-testing) -8. [Direct Debugging](#direct-debugging) -9. [Transfering Files to the Q7S](#file-transfer) -10. [Q7S OBC](#q7s) -11. [Static Code Analysis](#static-code-analysis) -12. [Eclipse](#eclipse) -13. [Running the OBSW on a Raspberry Pi](#rpi) -14. [FSFW](#fsfw) +6. [Remote Reset](#remote-reset) +8. [TMTC testing](#tmtc-testing) +9. [Direct Debugging](#direct-debugging) +10. [Transfering Files to the Q7S](#file-transfer) +11. [Q7S OBC](#q7s) +12. [Static Code Analysis](#static-code-analysis) +13. [Eclipse](#eclipse) +14. [Running the OBSW on a Raspberry Pi](#rpi) +15. [FSFW](#fsfw) # General information @@ -535,10 +536,10 @@ ssh root@192.168.133.10 ``` If this has not been done yet, you can access the serial -console of the Q7S like this to set it +console of the Q7S like this ```sh -picocom -b 115200 /dev/ttyUSB0 +picocom -b 115200 /dev/q7sSerial ``` The flatsat has the aliases and shell scripts `q7s_ssh` and `q7s_serial` for this task as well. @@ -575,6 +576,29 @@ alias or shell script to do this quickly. Note: When now setting up a debug session in the Xilinx SDK or Eclipse, the host must be set to localhost instead of the IP address of the Q7S. +# Remote Reset +1. Launch xilinx hardware server on flatsat with alias +```` +launch-hwserver-xilinx +```` +2. On host PC start xsc +3. In xsct console type the follwing command to connect to the hardware server (replace with the IP address of the flatsat PC. Can be found out with ifconfig) +```` +connect -url tcp::3121 +```` +4. The following command will list all available devices +```` +targets +```` +5. Connect to the APU of the Q7S +```` +target +```` +6. Perform reset +```` +rst +```` + # TMTC testing The OBSW supports sending PUS TM packets via TCP or the PDEC IP Core which transmits the data as diff --git a/bsp_hosted/fsfwconfig/devices/gpioIds.h b/bsp_hosted/fsfwconfig/devices/gpioIds.h index 1ab55d08..a4b4ac81 100644 --- a/bsp_hosted/fsfwconfig/devices/gpioIds.h +++ b/bsp_hosted/fsfwconfig/devices/gpioIds.h @@ -1,8 +1,6 @@ #ifndef FSFWCONFIG_DEVICES_GPIOIDS_H_ #define FSFWCONFIG_DEVICES_GPIOIDS_H_ -#include - namespace gpioIds { enum gpioId_t { HEATER_0, diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index af89d346..34516fa6 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -8,13 +8,11 @@ static constexpr char SPI_RW_DEV[] = "/dev/spidev3.0"; static constexpr char I2C_DEFAULT_DEV[] = "/dev/i2c-1"; -static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ttyUL3"; -static constexpr char UART_PLOC_SUPERVSIOR_DEV[] = "/dev/ttyUL4"; -static constexpr char UART_SYRLINKS_DEV[] = "/dev/ttyUL5"; -static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ttyUL8"; - -static constexpr char UART_GNSS_0_DEV[] = "/dev/ttyUL0"; -static constexpr char UART_GNSS_1_DEV[] = "/dev/ttyUL2"; +static constexpr char UART_GNSS_DEV[] = "/dev/ttyUL0"; +static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ttyUL2"; +static constexpr char UART_PLOC_SUPERVSIOR_DEV[] = "/dev/ttyUL3"; +static constexpr char UART_SYRLINKS_DEV[] = "/dev/ttyUL4"; +static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ttyUL7"; static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio0"; static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio2"; @@ -31,8 +29,10 @@ namespace gpioNames { static constexpr char MGM_3_CS[] = "mgm_3_rm3100_chip_select"; static constexpr char RESET_GNSS_0[] = "reset_gnss_0"; static constexpr char RESET_GNSS_1[] = "reset_gnss_1"; - static constexpr char GYRO_0_ENABLE[] = "gyro_0_enable"; - static constexpr char GYRO_2_ENABLE[] = "gyro_2_enable"; + static constexpr char GNSS_0_ENABLE[] = "enable_gnss_0"; + static constexpr char GNSS_1_ENABLE[] = "enable_gnss_1"; + static constexpr char GYRO_0_ENABLE[] = "enable_gyro_0"; + static constexpr char GYRO_2_ENABLE[] = "enable_gyro_2"; static constexpr char HEATER_0[] = "heater0"; static constexpr char HEATER_1[] = "heater1"; static constexpr char HEATER_2[] = "heater2"; @@ -54,7 +54,7 @@ namespace gpioNames { static constexpr char EN_RW_2[] = "enable_rw_2"; static constexpr char EN_RW_3[] = "enable_rw_3"; static constexpr char EN_RW_4[] = "enable_rw_4"; - static constexpr char SPI_MUX_SELECT[] = "spi_mux_select"; + static constexpr char GNSS_MUX_SELECT[] = "gnss_mux_select"; static constexpr char RAD_SENSOR_CHIP_SELECT[] = "rad_sensor_chip_select"; static constexpr char PAPB_BUSY_SIGNAL_VC0[] = "papb_busy_signal_vc0"; static constexpr char PAPB_EMPTY_SIGNAL_VC0[] = "papb_empty_signal_vc0"; diff --git a/bsp_q7s/boardtest/Q7STestTask.cpp b/bsp_q7s/boardtest/Q7STestTask.cpp index 965a6d63..5cead3d5 100644 --- a/bsp_q7s/boardtest/Q7STestTask.cpp +++ b/bsp_q7s/boardtest/Q7STestTask.cpp @@ -127,8 +127,18 @@ void Q7STestTask::testDummyParams() { param.writeJsonFile(); param.print(); - int test = param.getValue(DummyParameter::DUMMY_KEY_PARAM_1); - std::string test2 = param.getValue(DummyParameter::DUMMY_KEY_PARAM_2); + int test = 0; + result = param.getValue(DummyParameter::DUMMY_KEY_PARAM_1, &test); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1 + << " does not exist" << std::endl; + } + std::string test2; + result = param.getValue(DummyParameter::DUMMY_KEY_PARAM_2, &test2); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1 + << " does not exist" << std::endl; + } sif::info << "Test value (3 expected): " << test << std::endl; sif::info << "Test value 2 (\"blirb\" expected): " << test2 << std::endl; } diff --git a/bsp_q7s/callbacks/rwSpiCallback.cpp b/bsp_q7s/callbacks/rwSpiCallback.cpp index d5cab4aa..701fc8dc 100644 --- a/bsp_q7s/callbacks/rwSpiCallback.cpp +++ b/bsp_q7s/callbacks/rwSpiCallback.cpp @@ -51,11 +51,6 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sen return result; } - /** Disconnect PS SPI peripheral and select AXI SPI core */ - if(gpioIF->pullHigh(gpioIds::SPI_MUX) != HasReturnvaluesIF::RETURN_OK) { - sif::error << "rwSpiCallback::spiCallback: Failed to pull spi mux gpio high" << std::endl; - } - /** Sending frame start sign */ writeBuffer[0] = 0x7E; writeSize = 1; @@ -133,8 +128,15 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sen closeSpi(gpioId, gpioIF, mutex); return RwHandler::SPI_READ_FAILURE; } + if(idx == 0) { + if(byteRead != FLAG_BYTE) { + sif::error << "Invalid data, expected start marker" << std::endl; + closeSpi(gpioId, gpioIF, mutex); + return RwHandler::NO_START_MARKER; + } + } - if (byteRead != 0x7E) { + if (byteRead != FLAG_BYTE) { break; } @@ -145,6 +147,10 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sen } } +#if FSFW_HAL_SPI_WIRETAPPING == 1 + sif::info << "RW start marker detected" << std::endl; +#endif + size_t decodedFrameLen = 0; while(decodedFrameLen < replyBufferSize) { @@ -158,7 +164,7 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sen } } - if (byteRead == 0x7E) { + if (byteRead == FLAG_BYTE) { /** Reached end of frame */ break; } @@ -227,10 +233,5 @@ void closeSpi (gpioId_t gpioId, GpioIF* gpioIF, MutexIF* mutex) { if(mutex->unlockMutex() != HasReturnvaluesIF::RETURN_OK) { sif::error << "rwSpiCallback::closeSpi: Failed to unlock mutex" << std::endl;; } - - /** Route SPI interface again to PS SPI peripheral */ - if(gpioIF->pullLow(gpioIds::SPI_MUX) != HasReturnvaluesIF::RETURN_OK) { - sif::error << "rwSpiCallback::spiCallback: Failed to pull spi mux gpio low" << std::endl; - } } } diff --git a/bsp_q7s/callbacks/rwSpiCallback.h b/bsp_q7s/callbacks/rwSpiCallback.h index cc7c6cbe..8952f873 100644 --- a/bsp_q7s/callbacks/rwSpiCallback.h +++ b/bsp_q7s/callbacks/rwSpiCallback.h @@ -8,6 +8,9 @@ namespace rwSpiCallback { +//! This is the end and start marker of the frame datalinklayer +static constexpr uint8_t FLAG_BYTE = 0x7E; + /** * @brief This is the callback function to send commands to the nano avionics reaction wheels and * receive the replies. diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index d8149ccb..271ec508 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -1094,8 +1094,8 @@ ReturnValue_t CoreController::handleProtInfoUpdateLine(std::string nextLine) { uint8_t wordIdx = 0; uint8_t arrayIdx = 0; istringstream iss(nextLine); - Chip currentChip; - Copy currentCopy; + Chip currentChip = Chip::CHIP_0; + Copy currentCopy = Copy::COPY_0; while(iss >> word) { if(wordIdx == 1) { currentChip = static_cast(stoi(word)); diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 7923a2cd..7977deed 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -22,7 +22,7 @@ ServiceInterfaceStream sif::debug("DEBUG"); ServiceInterfaceStream sif::info("INFO"); ServiceInterfaceStream sif::warning("WARNING"); -ServiceInterfaceStream sif::error("ERROR", false, false, true); +ServiceInterfaceStream sif::error("ERROR"); #else ServiceInterfaceStream sif::debug("DEBUG", true); ServiceInterfaceStream sif::info("INFO", true); @@ -126,6 +126,16 @@ void initmission::initTasks() { if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::FILE_SYSTEM_HANDLER); } + +#if OBSW_ADD_STAR_TRACKER == 1 + PeriodicTaskIF* strImgLoaderTask = factory->createPeriodicTask( + "FILE_SYSTEM_TASK", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = strImgLoaderTask->addComponent(objects::STR_HELPER); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::STR_HELPER); + } +#endif /* OBSW_ADD_STAR_TRACKER == 1 */ + #endif /* BOARD_TE0720 */ #if OBSW_TEST_CCSDS_BRIDGE == 1 @@ -187,6 +197,9 @@ void initmission::initTasks() { #if BOARD_TE0720 == 0 fsTask->startTask(); +#if OBSW_ADD_STAR_TRACKER == 1 + strImgLoaderTask->startTask(); +#endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif sif::info << "Tasks started.." << std::endl; @@ -199,7 +212,7 @@ void initmission::createPstTasks(TaskFactory& factory, /* Polling Sequence Table Default */ #if OBSW_ADD_SPI_TEST_CODE == 0 FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask( - "PST_TASK_DEFAULT", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, + "PST_TASK_DEFAULT", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc); result = pst::pstSpi(spiPst); if (result != HasReturnvaluesIF::RETURN_OK) { @@ -213,21 +226,21 @@ void initmission::createPstTasks(TaskFactory& factory, #endif FixedTimeslotTaskIF* uartPst = factory.createFixedTimeslotTask( - "UART_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, missedDeadlineFunc); + "UART_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); result = pst::pstUart(uartPst); if (result != HasReturnvaluesIF::RETURN_OK) { sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; } taskVec.push_back(uartPst); FixedTimeslotTaskIF* gpioPst = factory.createFixedTimeslotTask( - "GPIO_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, missedDeadlineFunc); + "GPIO_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); result = pst::pstGpio(gpioPst); if (result != HasReturnvaluesIF::RETURN_OK) { sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; } taskVec.push_back(gpioPst); FixedTimeslotTaskIF* i2cPst = factory.createFixedTimeslotTask( - "I2C_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, missedDeadlineFunc); + "I2C_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); result = pst::pstI2c(i2cPst); if (result != HasReturnvaluesIF::RETURN_OK) { sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index b292f644..1c5bb2df 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -1,5 +1,8 @@ #include #include "ObjectFactory.h" + +#include "bsp_q7s/devices/startracker/StrHelper.h" +#include "bsp_q7s/devices/startracker/StarTrackerDefinitions.h" #include "OBSWConfig.h" #include "devConf.h" #include "ccsdsConfig.h" @@ -16,15 +19,17 @@ #include "bsp_q7s/devices/PlocSupervisorHandler.h" #include "bsp_q7s/devices/PlocUpdater.h" #include "bsp_q7s/devices/PlocMemoryDumper.h" +#include "bsp_q7s/devices/startracker/StarTrackerHandler.h" #include "bsp_q7s/callbacks/rwSpiCallback.h" #include "bsp_q7s/callbacks/gnssCallback.h" -#include "linux/devices/HeaterHandler.h" #include "linux/devices/SolarArrayDeploymentHandler.h" #include "linux/devices/devicedefinitions/SusDefinitions.h" #include "linux/devices/SusHandler.h" #include "linux/csp/CspCookie.h" #include "linux/csp/CspComIF.h" + +#include "mission/devices/HeaterHandler.h" #include "mission/core/GenericFactory.h" #include "mission/devices/PDU1Handler.h" #include "mission/devices/PDU2Handler.h" @@ -33,20 +38,19 @@ #include "mission/devices/P60DockHandler.h" #include "mission/devices/Tmp1075Handler.h" #include "mission/devices/Max31865PT1000Handler.h" -#include "mission/devices/GyroADIS16507Handler.h" +#include "mission/devices/GyroADIS1650XHandler.h" #include "mission/devices/IMTQHandler.h" #include "mission/devices/SyrlinksHkHandler.h" #include "mission/devices/PlocMPSoCHandler.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/PlocMPSoCDefinitions.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/devices/GPSHyperionHandler.h" #include "mission/tmtc/CCSDSHandler.h" #include "mission/tmtc/VirtualChannel.h" @@ -167,11 +171,15 @@ void ObjectFactory::produce(void* args) { new FileSystemHandler(objects::FILE_SYSTEM_HANDLER); #if OBSW_ADD_STAR_TRACKER == 1 - UartCookie* starTrackerCookie = new UartCookie(objects::START_TRACKER, + UartCookie* starTrackerCookie = new UartCookie(objects::STAR_TRACKER, q7s::UART_STAR_TRACKER_DEV, UartModes::NON_CANONICAL, uart::STAR_TRACKER_BAUD, StarTracker::MAX_FRAME_SIZE* 2 + 2); starTrackerCookie->setNoFixedSizeReply(); - new StarTrackerHandler(objects::START_TRACKER, objects::UART_COM_IF, starTrackerCookie); + StrHelper* strHelper = new StrHelper(objects::STR_HELPER); + StarTrackerHandler* starTrackerHandler = new StarTrackerHandler(objects::STAR_TRACKER, + objects::UART_COM_IF, starTrackerCookie, strHelper); + starTrackerHandler->setStartUpImmediately(); + #endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif /* TE7020 == 0 */ @@ -264,7 +272,7 @@ void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) { std::stringstream consumer; consumer << "0x" << std::hex << objects::RAD_SENSOR; GpiodRegularByLineName* gpio = new GpiodRegularByLineName( - q7s::gpioNames::RAD_SENSOR_CHIP_SELECT, consumer.str(), gpio::OUT, gpio::HIGH); + q7s::gpioNames::RAD_SENSOR_CHIP_SELECT, consumer.str(), gpio::DIR_OUT, gpio::HIGH); gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, gpio); gpioComIF->addGpios(gpioCookieRadSensor); @@ -278,43 +286,43 @@ void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF *gpioComIF, SpiComI GpioCookie* gpioCookieSus = new GpioCookie(); GpioCallback* susgpio = nullptr; - susgpio = new GpioCallback("Chip select SUS 1", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 1", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_1, susgpio); - susgpio = new GpioCallback("Chip select SUS 2", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 2", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_2, susgpio); - susgpio = new GpioCallback("Chip select SUS 3", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 3", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_3, susgpio); - susgpio = new GpioCallback("Chip select SUS 4", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 4", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_4, susgpio); - susgpio = new GpioCallback("Chip select SUS 5", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 5", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_5, susgpio); - susgpio = new GpioCallback("Chip select SUS 6", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 6", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_6, susgpio); - susgpio = new GpioCallback("Chip select SUS 7", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 7", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_7, susgpio); - susgpio = new GpioCallback("Chip select SUS 8", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 8", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_8, susgpio); - susgpio = new GpioCallback("Chip select SUS 9", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 9", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_9, susgpio); - susgpio = new GpioCallback("Chip select SUS 10", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 10", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_10, susgpio); - susgpio = new GpioCallback("Chip select SUS 11", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 11", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_11, susgpio); - susgpio = new GpioCallback("Chip select SUS 12", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 12", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_12, susgpio); - susgpio = new GpioCallback("Chip select SUS 13", gpio::OUT, gpio::HIGH, + susgpio = new GpioCallback("Chip select SUS 13", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieSus->addGpio(gpioIds::CS_SUS_13, susgpio); @@ -395,61 +403,61 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF *gpioComIF, UartComI GpiodRegularByLineName* gpio = nullptr; consumer << "0x" << std::hex << objects::GYRO_0_ADIS_HANDLER; gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ADIS_CS, consumer.str(), - gpio::OUT, gpio::HIGH); + gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::GYRO_1_L3G_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, consumer.str(), gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_1_L3G_CS, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::GYRO_2_ADIS_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, consumer.str(), gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_ADIS_CS, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::GYRO_3_L3G_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, consumer.str(), gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_3_L3G_CS, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::MGM_0_LIS3_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, consumer.str(), gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::MGM_0_LIS3_CS, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::MGM_1_RM3100_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, consumer.str(), gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::MGM_1_RM3100_CS, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::MGM_2_LIS3_HANDLER; gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, consumer.str(), - gpio::OUT, gpio::HIGH); + gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::MGM_2_LIS3_CS, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::MGM_3_RM3100_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_3_CS, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_3_CS, consumer.str(), gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::GPS0_HANDLER; // GNSS reset pins are active low - gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_0, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_0, consumer.str(), gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_NRESET, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::GPS1_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_1, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_1, consumer.str(), gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_NRESET, gpio); @@ -457,16 +465,28 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF *gpioComIF, UartComI consumer << "0x" << std::hex << objects::GYRO_0_ADIS_HANDLER; // Enable pins must be pulled low for regular operations gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, consumer.str(), - gpio::OUT, gpio::LOW); + gpio::DIR_OUT, gpio::LOW); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ENABLE, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::GYRO_2_ADIS_HANDLER; - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ENABLE, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ENABLE, consumer.str(), gpio::DIR_OUT, gpio::LOW); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_ENABLE, gpio); - // TODO: Add enable pins for GPS as soon as new interface board design is finished + // Enable pins for GNSS + consumer.str(""); + consumer << "0x" << std::hex << objects::GPS0_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_0_ENABLE, consumer.str(), + gpio::DIR_OUT, gpio::LOW); + gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_ENABLE, gpio); + + consumer.str(""); + consumer << "0x" << std::hex << objects::GPS1_HANDLER; + gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_1_ENABLE, consumer.str(), gpio::DIR_OUT, + gpio::LOW); + gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_ENABLE, gpio); + gpioComIF->addGpios(gpioCookieAcsBoard); std::string spiDev = q7s::SPI_DEFAULT_DEV; @@ -509,10 +529,10 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF *gpioComIF, UartComI // Commented until ACS board V2 in in clean room again // Gyro 0 Side A spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev, - ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, + ADIS1650X::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, spi::DEFAULT_ADIS16507_SPEED); - auto adisHandler = new GyroADIS16507Handler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, - spiCookie); + auto adisHandler = new GyroADIS1650XHandler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, + spiCookie, ADIS1650X::Type::ADIS16505); adisHandler->setStartUpImmediately(); // Gyro 1 Side A spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev, @@ -525,10 +545,10 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF *gpioComIF, UartComI #endif // Gyro 2 Side B spiCookie = new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev, - ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, + ADIS1650X::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, spi::DEFAULT_ADIS16507_SPEED); - adisHandler = new GyroADIS16507Handler(objects::GYRO_2_ADIS_HANDLER, objects::SPI_COM_IF, - spiCookie); + adisHandler = new GyroADIS1650XHandler(objects::GYRO_2_ADIS_HANDLER, objects::SPI_COM_IF, + spiCookie, ADIS1650X::Type::ADIS16505); adisHandler->setStartUpImmediately(); // Gyro 3 Side B spiCookie = new SpiCookie(addresses::GYRO_3_L3G, gpioIds::GYRO_3_L3G_CS, spiDev, @@ -550,22 +570,14 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF *gpioComIF, UartComI resetArgsGnss0.gnss1 = false; resetArgsGnss0.gpioComIF = gpioComIF; resetArgsGnss0.waitPeriodMs = 100; - auto uartCookieGps0 = new UartCookie(objects::GPS0_HANDLER, q7s::UART_GNSS_0_DEV, + auto uartCookieGps0 = new UartCookie(objects::GPS0_HANDLER, q7s::UART_GNSS_DEV, UartModes::CANONICAL, uart::GNSS_BAUD, uart::HYPERION_GPS_REPLY_MAX_BUFFER); uartCookieGps0->setToFlushInput(true); uartCookieGps0->setReadCycles(6); - auto uartCookieGps1 = new UartCookie(objects::GPS1_HANDLER, q7s::UART_GNSS_1_DEV, - UartModes::CANONICAL, uart::GNSS_BAUD, uart::HYPERION_GPS_REPLY_MAX_BUFFER); - uartCookieGps1->setToFlushInput(true); - uartCookieGps1->setReadCycles(6); auto gpsHandler0 = new GPSHyperionHandler(objects::GPS0_HANDLER, objects::UART_COM_IF, uartCookieGps0, debugGps); gpsHandler0->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss0); gpsHandler0->setStartUpImmediately(); - auto gpsHandler1 = new GPSHyperionHandler(objects::GPS1_HANDLER, objects::UART_COM_IF, - uartCookieGps1, debugGps); - gpsHandler1->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss1); - gpsHandler1->setStartUpImmediately(); } void ObjectFactory::createHeaterComponents() { @@ -576,37 +588,37 @@ void ObjectFactory::createHeaterComponents() { std::stringstream consumer; consumer << "0x" << std::hex << objects::HEATER_HANDLER; /* Pin H2-11 on stack connector */ - gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_0, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_0, consumer.str(), gpio::DIR_OUT, gpio::LOW); heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpio); /* Pin H2-12 on stack connector */ - gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_1, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_1, consumer.str(), gpio::DIR_OUT, gpio::LOW); heaterGpiosCookie->addGpio(gpioIds::HEATER_1, gpio); /* Pin H2-13 on stack connector */ - gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_2, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_2, consumer.str(), gpio::DIR_OUT, gpio::LOW); heaterGpiosCookie->addGpio(gpioIds::HEATER_2, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_3, consumer.str(), - gpio::OUT, gpio::LOW); + gpio::DIR_OUT, gpio::LOW); heaterGpiosCookie->addGpio(gpioIds::HEATER_3, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_4, consumer.str(), - gpio::OUT, gpio::LOW); + gpio::DIR_OUT, gpio::LOW); heaterGpiosCookie->addGpio(gpioIds::HEATER_4, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_5, consumer.str(), - gpio::OUT, gpio::LOW); + gpio::DIR_OUT, gpio::LOW); heaterGpiosCookie->addGpio(gpioIds::HEATER_5, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_6, consumer.str(), - gpio::OUT, gpio::LOW); + gpio::DIR_OUT, gpio::LOW); heaterGpiosCookie->addGpio(gpioIds::HEATER_6, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_7, consumer.str(), - gpio::OUT, gpio::LOW); + gpio::DIR_OUT, gpio::LOW); heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpio); new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, @@ -620,9 +632,9 @@ void ObjectFactory::createSolarArrayDeploymentComponents() { std::stringstream consumer; consumer << "0x" << std::hex << objects::SOLAR_ARRAY_DEPL_HANDLER; gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_0, - consumer.str(), gpio::OUT, gpio::LOW); + consumer.str(), gpio::DIR_OUT, gpio::LOW); solarArrayDeplCookie->addGpio(gpioIds::DEPLSA1, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_1, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_1, consumer.str(), gpio::DIR_OUT, gpio::LOW); solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpio); @@ -644,100 +656,100 @@ void ObjectFactory::createSyrlinksComponents() { void ObjectFactory::createRtdComponents(LinuxLibgpioIF *gpioComIF) { GpioCookie* rtdGpioCookie = new GpioCookie; - GpioCallback* gpioRtdIc0 = new GpioCallback("Chip select RTD IC0", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc0 = new GpioCallback("Chip select RTD IC0", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_3, gpioRtdIc0); - GpioCallback* gpioRtdIc1 = new GpioCallback("Chip select RTD IC1", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc1 = new GpioCallback("Chip select RTD IC1", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_4, gpioRtdIc1); - GpioCallback* gpioRtdIc2 = new GpioCallback("Chip select RTD IC2", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc2 = new GpioCallback("Chip select RTD IC2", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_5, gpioRtdIc2); - GpioCallback* gpioRtdIc3 = new GpioCallback("Chip select RTD IC3", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc3 = new GpioCallback("Chip select RTD IC3", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_6, gpioRtdIc3); - GpioCallback* gpioRtdIc4 = new GpioCallback("Chip select RTD IC4", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc4 = new GpioCallback("Chip select RTD IC4", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_7, gpioRtdIc4); - GpioCallback* gpioRtdIc5 = new GpioCallback("Chip select RTD IC5", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc5 = new GpioCallback("Chip select RTD IC5", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_8, gpioRtdIc5); - GpioCallback* gpioRtdIc6 = new GpioCallback("Chip select RTD IC6", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc6 = new GpioCallback("Chip select RTD IC6", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_9, gpioRtdIc6); - GpioCallback* gpioRtdIc7 = new GpioCallback("Chip select RTD IC7", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc7 = new GpioCallback("Chip select RTD IC7", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_10, gpioRtdIc7); - GpioCallback* gpioRtdIc8 = new GpioCallback("Chip select RTD IC8", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc8 = new GpioCallback("Chip select RTD IC8", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_11, gpioRtdIc8); - GpioCallback* gpioRtdIc9 = new GpioCallback("Chip select RTD IC9", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc9 = new GpioCallback("Chip select RTD IC9", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_12, gpioRtdIc9); - GpioCallback* gpioRtdIc10 = new GpioCallback("Chip select RTD IC10", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc10 = new GpioCallback("Chip select RTD IC10", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_13, gpioRtdIc10); - GpioCallback* gpioRtdIc11 = new GpioCallback("Chip select RTD IC11", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc11 = new GpioCallback("Chip select RTD IC11", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_14, gpioRtdIc11); - GpioCallback* gpioRtdIc12 = new GpioCallback("Chip select RTD IC12", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc12 = new GpioCallback("Chip select RTD IC12", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_15, gpioRtdIc12); - GpioCallback* gpioRtdIc13 = new GpioCallback("Chip select RTD IC13", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc13 = new GpioCallback("Chip select RTD IC13", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_16, gpioRtdIc13); - GpioCallback* gpioRtdIc14 = new GpioCallback("Chip select RTD IC14", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc14 = new GpioCallback("Chip select RTD IC14", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_17, gpioRtdIc14); - GpioCallback* gpioRtdIc15 = new GpioCallback("Chip select RTD IC15", gpio::OUT, gpio::HIGH, + GpioCallback* gpioRtdIc15 = new GpioCallback("Chip select RTD IC15", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); rtdGpioCookie->addGpio(gpioIds::RTD_IC_18, gpioRtdIc15); gpioComIF->addGpios(rtdGpioCookie); SpiCookie* spiRtdIc0 = new SpiCookie(addresses::RTD_IC_3, gpioIds::RTD_IC_3, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, spi::RTD_SPEED); + Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc1 = new SpiCookie(addresses::RTD_IC_4, gpioIds::RTD_IC_4, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, spi::RTD_SPEED); + Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc2 = new SpiCookie(addresses::RTD_IC_5, gpioIds::RTD_IC_5, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, spi::RTD_SPEED); + Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc3 = new SpiCookie(addresses::RTD_IC_6, gpioIds::RTD_IC_6, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, spi::RTD_SPEED); + Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc4 = new SpiCookie(addresses::RTD_IC_7, gpioIds::RTD_IC_7, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, spi::RTD_SPEED); + Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc5 = new SpiCookie(addresses::RTD_IC_8, gpioIds::RTD_IC_8, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, spi::RTD_SPEED); + Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc6 = new SpiCookie(addresses::RTD_IC_9, gpioIds::RTD_IC_9, q7s::SPI_DEFAULT_DEV, - Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, spi::RTD_SPEED); + Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc7 = new SpiCookie(addresses::RTD_IC_10, gpioIds::RTD_IC_10, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, + q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc8 = new SpiCookie(addresses::RTD_IC_11, gpioIds::RTD_IC_11, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, + q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc9 = new SpiCookie(addresses::RTD_IC_12, gpioIds::RTD_IC_12, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, + q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc10 = new SpiCookie(addresses::RTD_IC_13, gpioIds::RTD_IC_13, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, + q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc11 = new SpiCookie(addresses::RTD_IC_14, gpioIds::RTD_IC_14, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, + q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc12 = new SpiCookie(addresses::RTD_IC_15, gpioIds::RTD_IC_15, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, + q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc13 = new SpiCookie(addresses::RTD_IC_16, gpioIds::RTD_IC_16, std::string(q7s::SPI_DEFAULT_DEV), Max31865Definitions::MAX_REPLY_SIZE, - spi::SpiModes::MODE_1, spi::RTD_SPEED); + spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc14 = new SpiCookie(addresses::RTD_IC_17, gpioIds::RTD_IC_17, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, + q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); SpiCookie* spiRtdIc15 = new SpiCookie(addresses::RTD_IC_18, gpioIds::RTD_IC_18, - q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::SpiModes::MODE_1, + q7s::SPI_DEFAULT_DEV, Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED); - Max31865PT1000Handler* rtdIc0 = new Max31865PT1000Handler(objects::RTD_IC_6, objects::SPI_COM_IF, + Max31865PT1000Handler* rtdIc0 = new Max31865PT1000Handler(objects::RTD_IC_3, objects::SPI_COM_IF, spiRtdIc0); Max31865PT1000Handler* rtdIc1 = new Max31865PT1000Handler(objects::RTD_IC_4, objects::SPI_COM_IF, spiRtdIc1); @@ -773,6 +785,11 @@ void ObjectFactory::createRtdComponents(LinuxLibgpioIF *gpioComIF) { rtdIc0->setStartUpImmediately(); rtdIc1->setStartUpImmediately(); rtdIc2->setStartUpImmediately(); +#if OBSW_DEBUG_RTD == 1 + rtdIc0->setInstantNormal(true); + rtdIc1->setInstantNormal(true); + rtdIc2->setInstantNormal(true); +#endif static_cast(rtdIc0); static_cast(rtdIc1); @@ -794,50 +811,41 @@ void ObjectFactory::createRtdComponents(LinuxLibgpioIF *gpioComIF) { void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF) { GpioCookie* gpioCookieRw = new GpioCookie; - GpioCallback* csRw1 = new GpioCallback("Chip select reaction wheel 1", gpio::OUT, gpio::HIGH, + GpioCallback* csRw1 = new GpioCallback("Chip select reaction wheel 1", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieRw->addGpio(gpioIds::CS_RW1, csRw1); - GpioCallback* csRw2 = new GpioCallback("Chip select reaction wheel 2", gpio::OUT, gpio::HIGH, + GpioCallback* csRw2 = new GpioCallback("Chip select reaction wheel 2", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieRw->addGpio(gpioIds::CS_RW2, csRw2); - GpioCallback* csRw3 = new GpioCallback("Chip select reaction wheel 3", gpio::OUT, gpio::HIGH, + GpioCallback* csRw3 = new GpioCallback("Chip select reaction wheel 3", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieRw->addGpio(gpioIds::CS_RW3, csRw3); - GpioCallback* csRw4 = new GpioCallback("Chip select reaction wheel 4", gpio::OUT, gpio::HIGH, + GpioCallback* csRw4 = new GpioCallback("Chip select reaction wheel 4", gpio::DIR_OUT, gpio::HIGH, &gpioCallbacks::spiCsDecoderCallback, gpioComIF); gpioCookieRw->addGpio(gpioIds::CS_RW4, csRw4); std::stringstream consumer; GpiodRegularByLineName* gpio = nullptr; consumer << "0x" << std::hex << objects::RW1; - gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_1, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_1, consumer.str(), gpio::DIR_OUT, gpio::LOW); gpioCookieRw->addGpio(gpioIds::EN_RW1, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::RW2; - gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_2, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_2, consumer.str(), gpio::DIR_OUT, gpio::LOW); gpioCookieRw->addGpio(gpioIds::EN_RW2, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::RW3; - gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_3, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_3, consumer.str(), gpio::DIR_OUT, gpio::LOW); gpioCookieRw->addGpio(gpioIds::EN_RW3, gpio); consumer.str(""); consumer << "0x" << std::hex << objects::RW4; - gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_4, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_4, consumer.str(), gpio::DIR_OUT, gpio::LOW); gpioCookieRw->addGpio(gpioIds::EN_RW4, gpio); - /** - * This GPIO is only internally connected to the SPI MUX module and responsible to disconnect - * the PS SPI peripheral from the SPI interface and route out the SPI lines of the AXI SPI core. - * Per default the PS SPI is selected (EMIO = 0). - */ - gpio = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_SELECT, - "SPI Reaction Wheel Callback ", gpio::OUT, gpio::LOW); - gpioCookieRw->addGpio(gpioIds::SPI_MUX, gpio); - gpioComIF->addGpios(gpioCookieRw); auto rw1SpiCookie = new SpiCookie(addresses::RW1, gpioIds::CS_RW1, q7s::SPI_RW_DEV, @@ -942,7 +950,7 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { consumer.str(""); consumer << "ptme rate setter"; // Init to low -> default bit rate is low bit rate (200 kbps in downlink with syrlinks) - gpio = new GpiodRegularByLineName(q7s::gpioNames::BIT_RATE_SEL, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::BIT_RATE_SEL, consumer.str(), gpio::DIR_OUT, gpio::LOW); gpioCookieRateSetter->addGpio(gpioIds::BIT_RATE_SEL, gpio); gpioComIF->addGpios(gpioCookieRateSetter); @@ -967,7 +975,7 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { consumer.str(""); consumer << "0x" << std::hex << objects::PDEC_HANDLER; // GPIO also low after linux boot (specified by device-tree) - gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, consumer.str(), gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, consumer.str(), gpio::DIR_OUT, gpio::LOW); gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio); @@ -980,18 +988,18 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF *gpioComIF) { #if BOARD_TE0720 == 0 GpioCookie* gpioRS485Chip = new GpioCookie; gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver", - gpio::Direction::OUT, gpio::LOW); + gpio::Direction::DIR_OUT, gpio::LOW); gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_CLOCK, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_DATA, "RS485 Transceiver", - gpio::Direction::OUT, gpio::LOW); + gpio::Direction::DIR_OUT, gpio::LOW); gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_DATA, gpio); // Default configuration enables RX channels (RXEN = LOW) gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_CLOCK, "RS485 Transceiver", - gpio::Direction::OUT, gpio::LOW); + gpio::Direction::DIR_OUT, gpio::LOW); gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_CLOCK, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_DATA, "RS485 Transceiver", - gpio::Direction::OUT, gpio::LOW); + gpio::Direction::DIR_OUT, gpio::LOW); gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_DATA, gpio); gpioComIF->addGpios(gpioRS485Chip); @@ -1007,10 +1015,10 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) { #if BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1 #if OBSW_TEST_GPIO_OPEN_BYLABEL == 1 /* Configure MIO0 as input */ - GpiodRegular* testGpio = new GpiodRegular("MIO0", gpio::OUT, 0, "/amba_pl/gpio@41200000", 0); + GpiodRegular* testGpio = new GpiodRegular("MIO0", gpio::DIR_OUT, 0, "/amba_pl/gpio@41200000", 0); #elif OBSW_TEST_GPIO_OPEN_BY_LINE_NAME GpiodRegularByLineName* testGpio = new GpiodRegularByLineName("test-name", "gpio-test", - gpio::OUT, 0); + gpio::DIR_OUT, 0); #else /* Configure MIO0 as input */ GpiodRegular* testGpio = new GpiodRegular("gpiochip0", 0, "MIO0", gpio::IN, 0); @@ -1023,7 +1031,7 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) { #if BOARD_TE0720 == 1 && OBSW_TEST_SUS_HANDLER == 1 GpioCookie* gpioCookieSus = new GpioCookie; GpiodRegular* chipSelectSus = new GpiodRegular(std::string("gpiochip1"), 9, - std::string("Chip Select Sus Sensor"), gpio::OUT, 1); + std::string("Chip Select Sus Sensor"), gpio::DIR_OUT, 1); gpioCookieSus->addGpio(gpioIds::CS_SUS_1, chipSelectSus); gpioComIF->addGpios(gpioCookieSus); @@ -1051,7 +1059,7 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) { #if BOARD_TE0720 == 1 && OBSW_TEST_RADIATION_SENSOR_HANDLER == 1 GpioCookie* gpioCookieRadSensor = new GpioCookie; GpiodRegular* chipSelectRadSensor = new GpiodRegular(std::string("gpiochip1"), 0, - std::string("Chip select radiation sensor"), gpio::OUT, 1); + std::string("Chip select radiation sensor"), gpio::DIR_OUT, 1); gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, chipSelectRadSensor); gpioComIF->addGpios(gpioCookieRadSensor); diff --git a/bsp_q7s/devices/CMakeLists.txt b/bsp_q7s/devices/CMakeLists.txt index 6347b5f8..70705e83 100644 --- a/bsp_q7s/devices/CMakeLists.txt +++ b/bsp_q7s/devices/CMakeLists.txt @@ -2,4 +2,6 @@ target_sources(${TARGET_NAME} PRIVATE PlocSupervisorHandler.cpp PlocUpdater.cpp PlocMemoryDumper.cpp -) \ No newline at end of file +) + +add_subdirectory(startracker) \ No newline at end of file diff --git a/bsp_q7s/devices/PlocUpdater.cpp b/bsp_q7s/devices/PlocUpdater.cpp index 5a94495b..592a2c0d 100644 --- a/bsp_q7s/devices/PlocUpdater.cpp +++ b/bsp_q7s/devices/PlocUpdater.cpp @@ -168,14 +168,14 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { #if BOARD_TE0720 == 0 // Check if file is stored on SD card and if associated SD card is mounted if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { - if (!isSdCardMounted(sd::SLOT_0)) { - sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 0 not mounted" << std::endl; + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { + sif::warning << "PlocUpdater::getImageLocation: SD card 0 not mounted" << std::endl; return SD_NOT_MOUNTED; } } else if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { - if (!isSdCardMounted(sd::SLOT_0)) { - sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 1 not mounted" << std::endl; + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { + sif::warning << "PlocUpdater::getImageLocation: SD card 1 not mounted" << std::endl; return SD_NOT_MOUNTED; } } @@ -193,37 +193,6 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { return RETURN_OK; } -#if BOARD_TE0720 == 0 -bool PlocUpdater::isSdCardMounted(sd::SdCard sdCard) { - SdCardManager::SdStatePair active; - ReturnValue_t result = sdcMan->getSdCardActiveStatus(active); - if (result != RETURN_OK) { - sif::debug << "PlocUpdater::isSdCardMounted: Failed to get SD card active state"; - return false; - } - if (sdCard == sd::SLOT_0) { - if (active.first == sd::MOUNTED) { - return true; - } - else { - return false; - } - } - else if (sdCard == sd::SLOT_1) { - if (active.second == sd::MOUNTED) { - return true; - } - else { - return false; - } - } - else { - sif::debug << "PlocUpdater::isSdCardMounted: Unknown SD card specified" << std::endl; - } - return false; -} -#endif /* #if BOARD_TE0720 == 0 */ - void PlocUpdater::stepSuccessfulReceived(ActionId_t actionId, uint8_t step) { } diff --git a/bsp_q7s/devices/PlocUpdater.h b/bsp_q7s/devices/PlocUpdater.h index 50404d14..d016b9e5 100644 --- a/bsp_q7s/devices/PlocUpdater.h +++ b/bsp_q7s/devices/PlocUpdater.h @@ -174,13 +174,6 @@ private: */ void commandUpdateVerify(); -#if BOARD_TE0720 == 0 - /** - * @brief Checks whether the SD card to read from is mounted or not. - */ - bool isSdCardMounted(sd::SdCard sdCard); -#endif - void calcImageCrc(); void adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet); diff --git a/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.cpp b/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.cpp new file mode 100644 index 00000000..4e7c9458 --- /dev/null +++ b/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.cpp @@ -0,0 +1,78 @@ +#include "ArcsecDatalinkLayer.h" + +ArcsecDatalinkLayer::ArcsecDatalinkLayer() { + slipInit(); +} + +ArcsecDatalinkLayer::~ArcsecDatalinkLayer() { +} + +void ArcsecDatalinkLayer::slipInit() { + slipInfo.buffer = rxBuffer; + slipInfo.maxlength = StarTracker::MAX_FRAME_SIZE; + slipInfo.length = 0; + slipInfo.unescape_next = 0; + slipInfo.prev_state = SLIP_COMPLETE; +} + +ReturnValue_t ArcsecDatalinkLayer::decodeFrame(const uint8_t* rawData, size_t rawDataSize, + size_t* bytesLeft) { + size_t bytePos = 0; + for (bytePos = 0; bytePos < rawDataSize; bytePos++) { + enum arc_dec_result decResult = arc_transport_decode_body(*(rawData + bytePos), &slipInfo, + decodedFrame, &decFrameSize); + *bytesLeft = rawDataSize - bytePos - 1; + switch (decResult) { + case ARC_DEC_INPROGRESS: { + if (bytePos == rawDataSize - 1) { + return DEC_IN_PROGRESS; + } + continue; + } + case ARC_DEC_ERROR_FRAME_SHORT: + return REPLY_TOO_SHORT; + case ARC_DEC_ERROR_CHECKSUM: + return CRC_FAILURE; + case ARC_DEC_ASYNC: + case ARC_DEC_SYNC: { + // Reset length of SLIP struct for next frame + slipInfo.length = 0; + return RETURN_OK; + } + default: + sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl; + break; + return RETURN_FAILED; + } + } + return RETURN_FAILED; +} + +uint8_t ArcsecDatalinkLayer::getReplyFrameType() { + return decodedFrame[0]; +} + +const uint8_t* ArcsecDatalinkLayer::getReply() { + return &decodedFrame[1]; +} + +void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, uint32_t length) { + arc_transport_encode_body(data, length, encBuffer, &encFrameSize); +} + +uint8_t* ArcsecDatalinkLayer::getEncodedFrame() { + return encBuffer; +} + +uint32_t ArcsecDatalinkLayer::getEncodedLength() { + return encFrameSize; +} + +uint8_t ArcsecDatalinkLayer::getStatusField() { + return *(decodedFrame + STATUS_OFFSET); +} + +uint8_t ArcsecDatalinkLayer::getId() { + return *(decodedFrame + ID_OFFSET); +} + diff --git a/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.h b/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.h new file mode 100644 index 00000000..a65881c7 --- /dev/null +++ b/bsp_q7s/devices/startracker/ArcsecDatalinkLayer.h @@ -0,0 +1,100 @@ +#ifndef BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ +#define BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ + +#include "StarTrackerDefinitions.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" + +extern "C" { + #include "common/misc.h" +} + +/** + * @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec. + */ +class ArcsecDatalinkLayer: public HasReturnvaluesIF { +public: + + static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER; + + //! [EXPORT] : [COMMENT] More data required to complete frame + static const ReturnValue_t DEC_IN_PROGRESS = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Data too short to represent a valid frame + static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1); + //! [EXPORT] : [COMMENT] Detected CRC failure in received frame + static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2); + + static const uint8_t STATUS_OK = 0; + + ArcsecDatalinkLayer(); + virtual ~ArcsecDatalinkLayer(); + + /** + * @brief Applies decoding to data referenced by rawData pointer + * + * @param rawData Pointer to raw data received from star tracker + * @param rawDataSize Size of raw data stream + * @param remainingBytes Number of bytes left + */ + ReturnValue_t decodeFrame(const uint8_t* rawData, size_t rawDataSize, size_t* bytesLeft); + + /** + * @brief SLIP encodes data pointed to by data pointer. + * + * @param data Pointer to data to encode + * @param length Length of buffer to encode + */ + void encodeFrame(const uint8_t* data, uint32_t length); + + /** + * @brief Returns the frame type field of a decoded frame. + */ + uint8_t getReplyFrameType(); + + /** + * @brief Returns pointer to reply packet (first entry normally action ID, telemetry ID etc.) + */ + const uint8_t* getReply(); + + /** + * @brief Returns size of encoded frame + */ + uint32_t getEncodedLength(); + + /** + * @brief Returns pointer to encoded frame + */ + uint8_t* getEncodedFrame(); + + /** + * @brief Returns status of reply + */ + uint8_t getStatusField(); + + /** + * @brief Returns ID of reply + */ + uint8_t getId(); + +private: + + static const uint8_t ID_OFFSET = 1; + static const uint8_t STATUS_OFFSET = 2; + + // Used by arcsec slip decoding function process received data + uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE]; + // Decoded frame will be copied to this buffer + uint8_t decodedFrame[StarTracker::MAX_FRAME_SIZE]; + // Buffer where encoded frames will be stored. First byte of encoded frame represents type of + // reply + uint8_t encBuffer[StarTracker::MAX_FRAME_SIZE * 2 + 2]; + // Size of decoded frame + uint32_t decFrameSize = 0; + // Size of encoded frame + uint32_t encFrameSize = 0; + + slip_decode_state slipInfo; + + void slipInit(); +}; + +#endif /* BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ */ diff --git a/bsp_q7s/devices/startracker/ArcsecJsonKeys.h b/bsp_q7s/devices/startracker/ArcsecJsonKeys.h new file mode 100644 index 00000000..2c598b43 --- /dev/null +++ b/bsp_q7s/devices/startracker/ArcsecJsonKeys.h @@ -0,0 +1,126 @@ +#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ +#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ + +/** + * @brief Keys used in JSON file of ARCSEC. + */ +namespace arcseckeys { + static const char PROPERTIES[] = "properties"; + static const char NAME[] = "name"; + static const char VALUE[] = "value"; + + static const char LIMITS[] = "limits"; + static const char ACTION[] = "action"; + static const char FPGA18CURRENT[] = "FPGA18Current"; + static const char FPGA25CURRENT[] = "FPGA25Current"; + static const char FPGA10CURRENT[] = "FPGA10Current"; + static const char MCUCURRENT[] = "MCUCurrent"; + static const char CMOS21CURRENT[] = "CMOS21Current"; + static const char CMOSPIXCURRENT[] = "CMOSPixCurrent"; + static const char CMOS33CURRENT[] = "CMOS33Current"; + static const char CMOSVRESCURRENT[] = "CMOSVResCurrent"; + static const char CMOS_TEMPERATURE[] = "CMOSTemperature"; + static const char MCU_TEMPERATURE[] = "MCUTemperature"; + + static const char MOUNTING[] = "mounting"; + static const char qw[] = "qw"; + static const char qx[] = "qx"; + static const char qy[] = "qy"; + static const char qz[] = "qz"; + + static const char CAMERA[] = "camera"; + static const char MODE[] = "mode"; + static const char FOCALLENGTH[] = "focallength"; + static const char EXPOSURE[] = "exposure"; + static const char INTERVAL[] = "interval"; + static const char OFFSET[] = "offset"; + static const char PGAGAIN[] = "PGAGain"; + static const char ADCGAIN[] = "ADCGain"; + static const char REG_1[] = "reg1"; + static const char VAL_1[] = "val1"; + static const char REG_2[] = "reg2"; + static const char VAL_2[] = "val2"; + static const char REG_3[] = "reg3"; + static const char VAL_3[] = "val3"; + static const char REG_4[] = "reg4"; + static const char VAL_4[] = "val4"; + static const char REG_5[] = "reg5"; + static const char VAL_5[] = "val5"; + static const char REG_6[] = "reg6"; + static const char VAL_6[] = "val6"; + static const char REG_7[] = "reg7"; + static const char VAL_7[] = "val7"; + static const char REG_8[] = "reg8"; + static const char VAL_8[] = "val8"; + static const char FREQ_1[] = "freq1"; + static const char FREQ_2[] = "freq2"; + + static const char BLOB[] = "blob"; + static const char MIN_VALUE[] = "minValue"; + static const char MIN_DISTANCE[] = "minDistance"; + static const char NEIGHBOUR_DISTANCE[] = "neighbourDistance"; + static const char NEIGHBOUR_BRIGHT_PIXELS[] = "neighbourBrightPixels"; + static const char MIN_TOTAL_VALUE[] = "minTotalValue"; + static const char MAX_TOTAL_VALUE[] = "maxTotalValue"; + static const char MIN_BRIGHT_NEIGHBOURS[] = "minBrightNeighbours"; + static const char MAX_BRIGHT_NEIGHBOURS[] = "maxBrightNeighbours"; + static const char MAX_PIXEL_TO_CONSIDER[] = "maxPixelsToConsider"; + static const char SIGNAL_THRESHOLD[] = "signalThreshold"; + static const char DARK_THRESHOLD[] = "darkThreshold"; + static const char ENABLE_HISTOGRAM[] = "enableHistogram"; + static const char ENABLE_CONTRAST[] = "enableContrast"; + static const char BIN_MODE[] = "binMode"; + + static const char CENTROIDING[] = "centroiding"; + static const char ENABLE_FILTER[] = "enableFilter"; + static const char MAX_QUALITY[] = "maxquality"; + static const char MIN_QUALITY[] = "minquality"; + static const char MAX_INTENSITY[] = "maxintensity"; + static const char MIN_INTENSITY[] = "minintensity"; + static const char MAX_MAGNITUDE[] = "maxmagnitude"; + static const char GAUSSIAN_CMAX[] = "gaussianCmax"; + static const char GAUSSIAN_CMIN[] = "gaussianCmin"; + static const char TRANSMATRIX_00[] = "transmatrix00"; + static const char TRANSMATRIX_01[] = "transmatrix01"; + static const char TRANSMATRIX_10[] = "transmatrix10"; + static const char TRANSMATRIX_11[] = "transmatrix11"; + + static const char LISA[] = "lisa"; + static const char PREFILTER_DIST_THRESHOLD[] = "prefilterDistThreshold"; + static const char PREFILTER_ANGLE_THRESHOLD[] = "prefilterAngleThreshold"; + static const char FOV_WIDTH[] = "fov_width"; + static const char FOV_HEIGHT[] = "fov_height"; + static const char FLOAT_STAR_LIMIT[] = "float_star_limit"; + static const char CLOSE_STAR_LIMIT[] = "close_star_limit"; + static const char RATING_WEIGHT_CLOSE_STAR_COUNT[] = "rating_weight_close_star_count"; + static const char RATING_WEIGHT_FRACTION_CLOSE[] = "rating_weight_fraction_close"; + static const char RATING_WEIGHT_MEAN_SUM[] = "rating_weight_mean_sum"; + static const char RATING_WEIGHT_DB_STAR_COUNT[] = "rating_weight_db_star_count"; + static const char MAX_COMBINATIONS[] = "max_combinations"; + static const char NR_STARS_STOP[] = "nr_stars_stop"; + static const char FRACTION_CLOSE_STOP[] = "fraction_close_stop"; + + static const char MATCHING[] = "matching"; + static const char SQUARED_DISTANCE_LIMIT[] = "squaredDistanceLimit"; + static const char SQUARED_SHIFT_LIMIT[] = "squaredShiftLimit"; + + static const char VALIDATION[] = "validation"; + static const char STABLE_COUNT[] = "stable_count"; + static const char MAX_DIFFERENCE[] = "max_difference"; + static const char MIN_TRACKER_CONFIDENCE[] = "min_trackerConfidence"; + static const char MIN_MATCHED_STARS[] = "min_matchedStars"; + + static const char TRACKING[] = "tracking"; + static const char THIN_LIMIT[] = "thinLimit"; + static const char OUTLIER_THRESHOLD[] = "outlierThreshold"; + static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST"; + static const char TRACKER_CHOICE[] = "trackerChoice"; + + static const char ALGO[] = "algo"; + static const char L2T_MIN_CONFIDENCE[] = "l2t_minConfidence"; + static const char L2T_MIN_MATCHED[] = "l2t_minConfidence"; + static const char T2L_MIN_CONFIDENCE[] = "t2l_minConfidence"; + static const char T2L_MIN_MATCHED[] = "t2l_minMatched"; +} + +#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ */ diff --git a/bsp_q7s/devices/startracker/ArcsecJsonParamBase.cpp b/bsp_q7s/devices/startracker/ArcsecJsonParamBase.cpp new file mode 100644 index 00000000..339c3fe7 --- /dev/null +++ b/bsp_q7s/devices/startracker/ArcsecJsonParamBase.cpp @@ -0,0 +1,94 @@ +#include "ArcsecJsonParamBase.h" +#include "ArcsecJsonKeys.h" + +ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {} + +ReturnValue_t ArcsecJsonParamBase::create(std::string fullname, uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + result = init(fullname); + if (result != RETURN_OK) { + return result; + } + result = createCommand(buffer); + return result; +} + +ReturnValue_t ArcsecJsonParamBase::getParam(const std::string name, std::string& value) { + for (json::iterator it = set.begin(); it != set.end(); ++it) { + if ((*it)[arcseckeys::NAME] == name) { + value = (*it)[arcseckeys::VALUE]; + convertEmpty(value); + return RETURN_OK; + } + } + return PARAM_NOT_EXISTS; +} + +void ArcsecJsonParamBase::convertEmpty(std::string& value) { + if (value == "") { + value = "0"; + } +} + +void ArcsecJsonParamBase::addfloat(const std::string value, uint8_t* buffer) { + float param = std::stof(value); + std::memcpy(buffer, ¶m, sizeof(param)); +} + +void ArcsecJsonParamBase::adduint8(const std::string value, uint8_t* buffer) { + uint8_t param = std::stoi(value); + std::memcpy(buffer, ¶m, sizeof(param)); +} + +void ArcsecJsonParamBase::addint16(const std::string value, uint8_t* buffer) { + int16_t param = std::stoi(value); + std::memcpy(buffer, ¶m, sizeof(param)); +} + +void ArcsecJsonParamBase::adduint16(const std::string value, uint8_t* buffer) { + uint16_t param = std::stoi(value); + std::memcpy(buffer, ¶m, sizeof(param)); +} + +void ArcsecJsonParamBase::adduint32(const std::string value, uint8_t* buffer) { + uint32_t param = std::stoi(value); + std::memcpy(buffer, ¶m, sizeof(param)); +} + +void ArcsecJsonParamBase::addSetParamHeader(uint8_t* buffer, uint8_t setId) { + *buffer = static_cast(TMTC_SETPARAMREQ); + *(buffer + 1) = setId; +} + +ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) { + ReturnValue_t result = RETURN_OK; + if (not std::filesystem::exists(filename)) { + sif::warning << "ArcsecJsonParamBase::init: JSON file " << filename << " does not exist" + << std::endl; + return JSON_FILE_NOT_EXISTS; + } + createJsonObject(filename); + result = initSet(); + if (result != RETURN_OK) { + return result; + } + return RETURN_OK; +} + +void ArcsecJsonParamBase::createJsonObject(const std::string fullname) { + json j; + std::ifstream file(fullname); + file >> j; + file.close(); + properties = j[arcseckeys::PROPERTIES]; +} + +ReturnValue_t ArcsecJsonParamBase::initSet() { + for (json::iterator it = properties.begin(); it != properties.end(); ++it) { + if ((*it)["name"] == setName) { + set = (*it)["fields"]; + return RETURN_OK; + } + } + return SET_NOT_EXISTS; +} diff --git a/bsp_q7s/devices/startracker/ArcsecJsonParamBase.h b/bsp_q7s/devices/startracker/ArcsecJsonParamBase.h new file mode 100644 index 00000000..320eff53 --- /dev/null +++ b/bsp_q7s/devices/startracker/ArcsecJsonParamBase.h @@ -0,0 +1,149 @@ +#ifndef BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ +#define BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ + +#include +#include +#include + +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "StarTrackerDefinitions.h" + +extern "C" { + #include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h" + #include "thirdparty/arcsec_star_tracker/common/genericstructs.h" +} + +using json = nlohmann::json; + +/** + * @brief Base class for creation of parameter configuration commands. Reads parameter set + * from a json file located on the filesystem and generates the appropriate command + * to apply the parameters to the star tracker software. + * + * @author J. Meier + */ +class ArcsecJsonParamBase : public HasReturnvaluesIF { +public: + + static const uint8_t INTERFACE_ID = CLASS_ID::ARCSEC_JSON_BASE; + //! [EXPORT] : [COMMENT] Specified json file does not exist + static const ReturnValue_t JSON_FILE_NOT_EXISTS = MAKE_RETURN_CODE(1); + //! [EXPORT] : [COMMENT] Requested set does not exist in json file + static const ReturnValue_t SET_NOT_EXISTS = MAKE_RETURN_CODE(2); + //! [EXPORT] : [COMMENT] Requested parameter does not exist in json file + static const ReturnValue_t PARAM_NOT_EXISTS = MAKE_RETURN_CODE(3); + + /** + * @brief Constructor + * + * @param fullname Name with absolute path of json file containing the parameters to set. + */ + ArcsecJsonParamBase(std::string setName); + + /** + * @brief Fills a buffer with a parameter set + * + * @param fullname The name including the absolute path of the json file containing the + * parameter set. + * @param buffer Pointer to the buffer the command will be written to + */ + ReturnValue_t create(std::string fullname, uint8_t* buffer); + + /** + * @brief Returns the size of the parameter command. + */ + virtual size_t getSize() = 0; + +protected: + + /** + * @brief Reads the value of a parameter from a json set + * + * @param name The name of the parameter + * @param value The string representation of the read value + * + * @return RETURN_OK if successful, otherwise PARAM_NOT_EXISTS + */ + ReturnValue_t getParam(const std::string name, std::string& value); + + /** + * @brief Converts empty string which is equal to define a value as zero. + */ + void convertEmpty(std::string& value); + + /** + * @brief This function adds a float represented as string to a buffer + * + * @param value The float in string representation to add + * @param buffer Pointer to the buffer the float will be written to + */ + void addfloat(const std::string value, uint8_t* buffer); + + /** + * @brief This function adds a uint8_t represented as string to a buffer + * + * @param value The uint8_t in string representation to add + * @param buffer Pointer to the buffer the uint8_t will be written to + */ + void adduint8(const std::string value, uint8_t* buffer); + + /** + * @brief This function adds a int16_t represented as string to a buffer + * + * @param value The int16_t in string representation to add + * @param buffer Pointer to the buffer the int16_t will be written to + */ + void addint16(const std::string value, uint8_t* buffer); + + /** + * @brief This function adds a uint16_t represented as string to a buffer + * + * @param value The uint16_t in string representation to add + * @param buffer Pointer to the buffer the uint16_t will be written to + */ + void adduint16(const std::string value, uint8_t* buffer); + + /** + * @brief This function adds a uint32_t represented as string to a buffer + * + * @param value The uint32_t in string representation to add + * @param buffer Pointer to the buffer the uint32_t will be written to + */ + void adduint32(const std::string value, uint8_t* buffer); + + void addSetParamHeader(uint8_t* buffer, uint8_t setId); + +private: + + json properties; + json set; + std::string setName; + + /** + * @brief This function must be implemented by the derived class to define creation of a + * parameter command. + */ + virtual ReturnValue_t createCommand(uint8_t* buffer) = 0; + + /** + * @brief Initializes the properties json object and the set json object + * + * @param fullname Name including absolute path to json file + * @param setName The name of the set to work on + * + * @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise + * RETURN_OK + */ + ReturnValue_t init(const std::string filename); + + void createJsonObject(const std::string fullname); + + /** + * @brief Extracts the json set object form the json file + * + * @param setName The name of the set to create the json object from + */ + ReturnValue_t initSet(); +}; + +#endif /* BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ */ diff --git a/bsp_q7s/devices/startracker/CMakeLists.txt b/bsp_q7s/devices/startracker/CMakeLists.txt new file mode 100644 index 00000000..28704219 --- /dev/null +++ b/bsp_q7s/devices/startracker/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${TARGET_NAME} PRIVATE + StarTrackerHandler.cpp + StarTrackerJsonCommands.cpp + ArcsecDatalinkLayer.cpp + ArcsecJsonParamBase.cpp + StrHelper.cpp +) \ No newline at end of file diff --git a/bsp_q7s/devices/startracker/StarTrackerDefinitions.h b/bsp_q7s/devices/startracker/StarTrackerDefinitions.h new file mode 100644 index 00000000..f1f7b7d0 --- /dev/null +++ b/bsp_q7s/devices/startracker/StarTrackerDefinitions.h @@ -0,0 +1,1210 @@ +#ifndef MISSION_STARTRACKER_DEFINITIONS_H_ +#define MISSION_STARTRACKER_DEFINITIONS_H_ + +#include +#include +#include +#include +#include "objects/systemObjectList.h" +#include + +namespace StarTracker { + +/** This is the address of the star tracker */ +static const uint8_t ADDRESS = 33; + +static const uint8_t STATUS_OK = 0; + +enum PoolIds: lp_id_t { + TICKS_TIME_SET, + TIME_TIME_SET, + RUN_TIME, + UNIX_TIME, + TICKS_VERSION_SET, + TIME_VERSION_SET, + PROGRAM, + MAJOR, + MINOR, + TICKS_INTERFACE_SET, + TIME_INTERFACE_SET, + FRAME_COUNT, + CHECKSUM_ERROR_COUNT, + SET_PARAM_COUNT, + SET_PARAM_REPLY_COUNT, + PARAM_REQUEST_COUNT, + PARAM_REPLY_COUNT, + REQ_TM_COUNT, + TM_REPLY_COUNT, + ACTION_REQ_COUNT, + ACTION_REPLY_COUNT, + TICKS_POWER_SET, + TIME_POWER_SET, + MCU_CURRENT, + MCU_VOLTAGE, + FPGA_CORE_CURRENT, + FPGA_CORE_VOLTAGE, + FPGA_18_CURRENT, + FPGA_18_VOLTAGE, + FPGA_25_CURRENT, + FPGA_25_VOLTAGE, + CMV_21_CURRENT, + CMV_21_VOLTAGE, + CMV_PIX_CURRENT, + CMV_PIX_VOLTAGE, + CMV_33_CURRENT, + CMV_33_VOLTAGE, + CMV_RES_CURRENT, + CMV_RES_VOLTAGE, + TICKS_TEMPERATURE_SET, + TIME_TEMPERATURE_SET, + MCU_TEMPERATURE, + CMOS_TEMPERATURE, + TICKS_SOLUTION_SET, + TIME_SOLUTION_SET, + CALI_QW, + CALI_QX, + CALI_QY, + CALI_QZ, + TRACK_CONFIDENCE, + TRACK_QW, + TRACK_QX, + TRACK_QY, + TRACK_QZ, + TRACK_REMOVED, + STARS_CENTROIDED, + STARS_MATCHED_DATABASE, + LISA_QW, + LISA_QX, + LISA_QY, + LISA_QZ, + LISA_PERC_CLOSE, + LISA_NR_CLOSE, + TRUST_WORTHY, + STABLE_COUNT, + SOLUTION_STRATEGY, + TICKS_HISTOGRAM_SET, + TIME_HISTOGRAM_SET, + HISTOGRAM_BINA0, + HISTOGRAM_BINA1, + HISTOGRAM_BINA2, + HISTOGRAM_BINA3, + HISTOGRAM_BINA4, + HISTOGRAM_BINA5, + HISTOGRAM_BINA6, + HISTOGRAM_BINA7, + HISTOGRAM_BINA8, + HISTOGRAM_BINB0, + HISTOGRAM_BINB1, + HISTOGRAM_BINB2, + HISTOGRAM_BINB3, + HISTOGRAM_BINB4, + HISTOGRAM_BINB5, + HISTOGRAM_BINB6, + HISTOGRAM_BINB7, + HISTOGRAM_BINB8, + HISTOGRAM_BINC0, + HISTOGRAM_BINC1, + HISTOGRAM_BINC2, + HISTOGRAM_BINC3, + HISTOGRAM_BINC4, + HISTOGRAM_BINC5, + HISTOGRAM_BINC6, + HISTOGRAM_BINC7, + HISTOGRAM_BINC8, + HISTOGRAM_BIND0, + HISTOGRAM_BIND1, + HISTOGRAM_BIND2, + HISTOGRAM_BIND3, + HISTOGRAM_BIND4, + HISTOGRAM_BIND5, + HISTOGRAM_BIND6, + HISTOGRAM_BIND7, + HISTOGRAM_BIND8, + TICKS_CONTRAST_SET, + TIME_CONTRAST_SET, + CONTRAST_BINA0, + CONTRAST_BINA1, + CONTRAST_BINA2, + CONTRAST_BINA3, + CONTRAST_BINA4, + CONTRAST_BINA5, + CONTRAST_BINA6, + CONTRAST_BINA7, + CONTRAST_BINA8, + CONTRAST_BINB0, + CONTRAST_BINB1, + CONTRAST_BINB2, + CONTRAST_BINB3, + CONTRAST_BINB4, + CONTRAST_BINB5, + CONTRAST_BINB6, + CONTRAST_BINB7, + CONTRAST_BINB8, + CONTRAST_BINC0, + CONTRAST_BINC1, + CONTRAST_BINC2, + CONTRAST_BINC3, + CONTRAST_BINC4, + CONTRAST_BINC5, + CONTRAST_BINC6, + CONTRAST_BINC7, + CONTRAST_BINC8, + CONTRAST_BIND0, + CONTRAST_BIND1, + CONTRAST_BIND2, + CONTRAST_BIND3, + CONTRAST_BIND4, + CONTRAST_BIND5, + CONTRAST_BIND6, + CONTRAST_BIND7, + CONTRAST_BIND8, + CHKSUM, + DWL_ID, + DWL_PIXX, + DWL_PIXY, + DWL_X_UNCORRECTED, + DWL_Y_UNCORRECTED, + DWL_X_CORRECTED, + DWL_Y_CORRECTED, + DWL_MAGNITUDE, + DWL_CXA, + DWL_CYA, + DWL_QUALITY, + MATCHEDSTR_ID, + MATCHEDSTR_CAMFPX, + MATCHEDSTR_CAMFPY, + MATCHEDSTR_CAMCARTX, + MATCHEDSTR_CAMCARTY, + MATCHEDSTR_CAMCARTZ, + MATCHEDSTR_CAMMAGNITUDE, + MATCHEDSTR_DBFPX, + MATCHEDSTR_DBFPY, + MATCHEDSTR_DBCARTX, + MATCHEDSTR_DBCARTY, + MATCHEDSTR_DBCARTZ, + MATCHEDSTR_DBMAGNITUDE, + MATCHEDSTR_CATALOGID, + DBIMAGE_ID, + DBIMAGE_PIXX, + DBIMAGE_PIXY, + DBIMAGE_X, + DBIMAGE_Y, + DBIMAGE_MAGNITUDE, + BLOBPIX_ID, + BLOBPIX_X, + BLOBPIX_Y, + BLOBPIX_TOT_VAL, + BLOBPIX_IN_USE, + BLOBPIX_BRIGHT_NEIGHBOURS, + BLOBPIX_REGION +}; + +static const DeviceCommandId_t PING_REQUEST = 0; +// Boots image (works only in bootloader mode) +static const DeviceCommandId_t BOOT = 1; +static const DeviceCommandId_t REQ_VERSION = 2; +static const DeviceCommandId_t REQ_INTERFACE = 3; +static const DeviceCommandId_t REQ_TIME = 4; +static const DeviceCommandId_t ERASE = 5; +static const DeviceCommandId_t UNLOCK = 6; +static const DeviceCommandId_t SWITCH_TO_BOOTLOADER_PROGRAM = 7; +static const DeviceCommandId_t DOWNLOAD_IMAGE = 9; +static const DeviceCommandId_t UPLOAD_IMAGE = 10; +static const DeviceCommandId_t REQ_POWER = 11; +static const DeviceCommandId_t TAKE_IMAGE = 15; +static const DeviceCommandId_t DOWNLOAD_CENTROID = 16; +static const DeviceCommandId_t UPLOAD_CENTROID = 17; +static const DeviceCommandId_t SUBSCRIBE_TO_TM = 18; +static const DeviceCommandId_t REQ_SOLUTION = 24; +static const DeviceCommandId_t REQ_TEMPERATURE = 25; +static const DeviceCommandId_t REQ_HISTOGRAM = 28; +static const DeviceCommandId_t REQ_CONTRAST = 29; +static const DeviceCommandId_t LIMITS = 40; +static const DeviceCommandId_t MOUNTING = 41; +static const DeviceCommandId_t CAMERA = 42; +static const DeviceCommandId_t BLOB = 43; +static const DeviceCommandId_t CENTROIDING = 44; +static const DeviceCommandId_t LISA = 45; +static const DeviceCommandId_t MATCHING = 46; +static const DeviceCommandId_t TRACKING = 47; +static const DeviceCommandId_t VALIDATION = 48; +static const DeviceCommandId_t ALGO = 49; +static const DeviceCommandId_t CHECKSUM = 50; +static const DeviceCommandId_t READ = 51; +static const DeviceCommandId_t WRITE = 52; +static const DeviceCommandId_t DOWNLOAD_MATCHED_STAR = 53; +static const DeviceCommandId_t STOP_IMAGE_LOADER = 55; +static const DeviceCommandId_t RESET_ERROR = 56; +static const DeviceCommandId_t CHANGE_DOWNLOAD_FILE = 57; +static const DeviceCommandId_t SET_JSON_FILE_NAME = 58; +static const DeviceCommandId_t SET_READ_FILENAME = 59; +static const DeviceCommandId_t SET_TIME = 60; +static const DeviceCommandId_t DOWNLOAD_DBIMAGE = 61; +static const DeviceCommandId_t DOWNLOAD_BLOBPIXEL = 62; +static const DeviceCommandId_t DOWNLOAD_FPGA_IMAGE = 63; +static const DeviceCommandId_t CHANGE_FPGA_DOWNLOAD_FILE = 64; +static const DeviceCommandId_t UPLOAD_FPGA_IMAGE = 65; +static const DeviceCommandId_t FPGA_ACTION = 66; +static const DeviceCommandId_t NONE = 0xFFFFFFFF; + +static const uint32_t VERSION_SET_ID = REQ_VERSION; +static const uint32_t INTERFACE_SET_ID = REQ_INTERFACE; +static const uint32_t POWER_SET_ID = REQ_POWER; +static const uint32_t TEMPERATURE_SET_ID = REQ_TEMPERATURE; +static const uint32_t TIME_SET_ID = REQ_TIME; +static const uint32_t SOLUTION_SET_ID = REQ_SOLUTION; +static const uint32_t HISTOGRAM_SET_ID = REQ_HISTOGRAM; +static const uint32_t CONTRAST_SET_ID = REQ_CONTRAST; +static const uint32_t CHECKSUM_SET_ID = CHECKSUM; +static const uint32_t DOWNLOADCENTROID_SET_ID = DOWNLOAD_CENTROID; +static const uint32_t DOWNLOAD_MATCHED_STAR_SET_ID = DOWNLOAD_MATCHED_STAR; +static const uint32_t DOWNLOAD_DBIMAGE_SET_ID = DOWNLOAD_DBIMAGE; +static const uint32_t DOWNLOAD_BLOBPIXEL_SET_ID = DOWNLOAD_BLOBPIXEL; + +/** Max size of unencoded frame */ +static const size_t MAX_FRAME_SIZE = 1200; + +static const uint8_t TEMPERATURE_SET_ENTRIES = 4; +static const uint8_t VERSION_SET_ENTRIES = 5; +static const uint8_t INTERFACE_SET_ENTRIES = 4; +static const uint8_t POWER_SET_ENTRIES = 18; +static const uint8_t TIME_SET_ENTRIES = 4; +static const uint8_t SOLUTION_SET_ENTRIES = 23; +static const uint8_t HISTOGRAM_SET_ENTRIES = 38; +static const uint8_t CONTRAST_SET_ENTRIES = 38; +static const uint8_t CHECKSUM_SET_ENTRIES = 1; +static const uint8_t DOWNLOAD_CENTROID_SET_ENTRIES = 11; +static const uint8_t DOWNLOAD_MATCHED_STAR_SET_ENTRIES = 14; +static const uint8_t DOWNLOAD_DBIMAGE_SET_ENTRIES = 6; +static const uint8_t DOWNLOAD_BLOBPIXEL_SET_ENTRIES = 7; + +// Action, parameter and telemetry IDs +namespace ID { + static const uint8_t PING = 0; + static const uint8_t BOOT = 1; + static const uint8_t VERSION = 2; + static const uint8_t INTERFACE = 3; + static const uint8_t LIMITS = 5; + static const uint8_t MOUNTING = 6; + static const uint8_t CAMERA = 9; + static const uint8_t BLOB = 10; + static const uint8_t CENTROIDING = 11; + static const uint8_t LISA = 12; + static const uint8_t MATCHING = 13; + static const uint8_t TRACKING = 14; + static const uint8_t VALIDATION = 15; + static const uint8_t ALGO = 16; + static const uint8_t REBOOT = 7; + static const uint8_t UPLOAD_IMAGE = 10; + static const uint8_t POWER = 11; + static const uint8_t SET_TIME = 14; + static const uint8_t SUBSCRIBE = 18; + static const uint8_t SOLUTION = 24; + static const uint8_t TEMPERATURE = 25; + static const uint8_t HISTOGRAM = 28; + static const uint8_t CONTRAST = 29; + static const uint8_t TIME = 1; + static const uint8_t WRITE = 2; + static const uint8_t READ = 3; + static const uint8_t CHECKSUM = 4; + static const uint8_t ERASE = 5; + static const uint8_t UNLOCK = 6; + static const uint8_t TAKE_IMAGE = 15; + static const uint8_t ERROR_RESET = 12; + static const uint8_t DOWNLOAD_CENTROID = 16; + static const uint8_t UPLOAD_CENTROID = 17; + static const uint8_t DOWNLOAD_MATCHED_STAR = 18; + static const uint8_t DOWNLOAD_DBIMAGE = 19; + static const uint8_t DOWNLOAD_BLOBPIXEL = 24; + static const uint8_t FPGA_ACTION = 22; +} + +namespace Program { + static const uint8_t BOOTLOADER = 1; + static const uint8_t FIRMWARE = 2; +} + +/** + * @brief This dataset can be used to store the temperature of a reaction wheel. + */ +class TemperatureSet: + public StaticLocalDataSet { +public: + + static const size_t SIZE = 20; + + TemperatureSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, TEMPERATURE_SET_ID) { + } + + TemperatureSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, TEMPERATURE_SET_ID)) { + } + + // Ticks is time reference generated by internal counter of the star tracker + lp_var_t ticks = lp_var_t(sid.objectId, + PoolIds::TICKS_TEMPERATURE_SET, this); + /** Unix time in microseconds */ + lp_var_t time = lp_var_t(sid.objectId, + PoolIds::TIME_TEMPERATURE_SET, this); + lp_var_t mcuTemperature = lp_var_t(sid.objectId, + PoolIds::MCU_TEMPERATURE, this); + lp_var_t cmosTemperature = lp_var_t(sid.objectId, + PoolIds::CMOS_TEMPERATURE, this); + + void printSet() { + sif::info << "TemperatureSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "TemperatureSet::printSet: Time: " + << this->time << " us" << std::endl; + sif::info << "TemperatureSet::printSet: MCU Temperature: " + << this->mcuTemperature << " °C" << std::endl; + sif::info << "TemperatureSet::printSet: CMOS Temperature: " + << this->cmosTemperature << " °C" << std::endl; + } +}; + +/** + * @brief Package to store version parameters + */ +class VersionSet: + public StaticLocalDataSet { +public: + + static const size_t SIZE = 15; + + VersionSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, VERSION_SET_ID) { + } + + VersionSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, VERSION_SET_ID)) { + } + + lp_var_t ticks = lp_var_t(sid.objectId, + PoolIds::TICKS_VERSION_SET, this); + /** Unix time in microseconds */ + lp_var_t time = lp_var_t(sid.objectId, + PoolIds::TIME_VERSION_SET, this); + lp_var_t program = lp_var_t(sid.objectId, + PoolIds::PROGRAM, this); + lp_var_t major = lp_var_t(sid.objectId, + PoolIds::MAJOR, this); + lp_var_t minor = lp_var_t(sid.objectId, + PoolIds::MINOR, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "VersionSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "VersionSet::printSet: Unix Time: " + << this->time << " us" << std::endl; + sif::info << "VersionSet::printSet: Program: " + << static_cast(this->program.value) << std::endl; + sif::info << "VersionSet::printSet: Major: " + << static_cast(this->major.value) << std::endl; + sif::info << "VersionSet::printSet: Minor: " + << static_cast(this->minor.value) << std::endl; + } +}; + +/** + * @brief Dataset to store the interface telemtry data. + */ +class InterfaceSet: + public StaticLocalDataSet { +public: + + static const size_t SIZE = 20; + + InterfaceSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, REQ_INTERFACE) { + } + + InterfaceSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, REQ_INTERFACE)) { + } + + // Ticks is time reference generated by interanl counter of the star tracker + lp_var_t ticks = lp_var_t(sid.objectId, + PoolIds::TICKS_INTERFACE_SET, this); + /** Unix time in microseconds */ + lp_var_t time = lp_var_t(sid.objectId, + PoolIds::TIME_INTERFACE_SET, this); + lp_var_t frameCount = lp_var_t(sid.objectId, + PoolIds::FRAME_COUNT, this); + lp_var_t checksumerrorCount = lp_var_t(sid.objectId, + PoolIds::CHECKSUM_ERROR_COUNT, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "InterfaceSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "InterfaceSet::printSet: Time: " + << this->time << " us" << std::endl; + sif::info << "InterfaceSet::printSet: Frame Count: " + << this->frameCount << std::endl; + sif::info << "InterfaceSet::printSet: Checksum Error Count: " + << this->checksumerrorCount << std::endl; + } +}; + +/** + * @brief Dataset to store the data of the power telemetry reply. + */ +class PowerSet: + public StaticLocalDataSet { +public: + + static const size_t SIZE = 76; + + PowerSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, REQ_INTERFACE) { + } + + PowerSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, REQ_INTERFACE)) { + } + + // Ticks is time reference generated by interanl counter of the star tracker + lp_var_t ticks = lp_var_t(sid.objectId, + PoolIds::TICKS_POWER_SET, this); + /** Unix time in microseconds */ + lp_var_t time = lp_var_t(sid.objectId, + PoolIds::TIME_POWER_SET, this); + lp_var_t mcuCurrent = lp_var_t(sid.objectId, + PoolIds::MCU_CURRENT, this); + lp_var_t mcuVoltage = lp_var_t(sid.objectId, + PoolIds::MCU_VOLTAGE, this); + lp_var_t fpgaCoreCurrent = lp_var_t(sid.objectId, + PoolIds::FPGA_CORE_CURRENT, this); + lp_var_t fpgaCoreVoltage = lp_var_t(sid.objectId, + PoolIds::FPGA_CORE_VOLTAGE, this); + lp_var_t fpga18Current = lp_var_t(sid.objectId, + PoolIds::FPGA_18_CURRENT, this); + lp_var_t fpga18Voltage = lp_var_t(sid.objectId, + PoolIds::FPGA_18_VOLTAGE, this); + lp_var_t fpga25Current = lp_var_t(sid.objectId, + PoolIds::FPGA_25_CURRENT, this); + lp_var_t fpga25Voltage = lp_var_t(sid.objectId, + PoolIds::FPGA_25_VOLTAGE, this); + lp_var_t cmv21Current = lp_var_t(sid.objectId, + PoolIds::CMV_21_CURRENT, this); + lp_var_t cmv21Voltage = lp_var_t(sid.objectId, + PoolIds::CMV_21_VOLTAGE, this); + lp_var_t cmvPixCurrent = lp_var_t(sid.objectId, + PoolIds::CMV_PIX_CURRENT, this); + lp_var_t cmvPixVoltage = lp_var_t(sid.objectId, + PoolIds::CMV_PIX_VOLTAGE, this); + lp_var_t cmv33Current = lp_var_t(sid.objectId, + PoolIds::CMV_33_CURRENT, this); + lp_var_t cmv33Voltage = lp_var_t(sid.objectId, + PoolIds::CMV_33_VOLTAGE, this); + lp_var_t cmvResCurrent = lp_var_t(sid.objectId, + PoolIds::CMV_RES_CURRENT, this); + lp_var_t cmvResVoltage = lp_var_t(sid.objectId, + PoolIds::CMV_RES_VOLTAGE, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "PowerSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "PowerSet::printSet: Time: " + << this->time << " us" << std::endl; + sif::info << "PowerSet::printSet: MCU Current: " + << this->mcuCurrent << " A" << std::endl; + sif::info << "PowerSet::printSet: MCU Voltage: " + << this->mcuVoltage << " V" << std::endl; + sif::info << "PowerSet::printSet: FPGA Core current: " + << this->fpgaCoreCurrent << " A" << std::endl; + sif::info << "PowerSet::printSet: FPGA Core voltage: " + << this->fpgaCoreVoltage << " V" << std::endl; + sif::info << "PowerSet::printSet: FPGA 18 current: " + << this->fpga18Current << " A" << std::endl; + sif::info << "PowerSet::printSet: FPGA 18 voltage: " + << this->fpga18Voltage << " V" << std::endl; + sif::info << "PowerSet::printSet: FPGA 25 current: " + << this->fpga25Current << " A" << std::endl; + sif::info << "PowerSet::printSet: FPGA 25 voltage: " + << this->fpga25Voltage << " V" << std::endl; + sif::info << "PowerSet::printSet: CMV 21 current: " + << this->cmv21Current << " A" << std::endl; + sif::info << "PowerSet::printSet: CMV 21 voltage: " + << this->cmv21Voltage << " V" << std::endl; + sif::info << "PowerSet::printSet: CMV Pix current: " + << this->cmvPixCurrent << " A" << std::endl; + sif::info << "PowerSet::printSet: CMV Pix voltage: " + << this->cmvPixVoltage << " V" << std::endl; + sif::info << "PowerSet::printSet: CMV 33 current: " + << this->cmv33Current << " A" << std::endl; + sif::info << "PowerSet::printSet: CMV 33 voltage: " + << this->cmv33Voltage << " V" << std::endl; + sif::info << "PowerSet::printSet: CMV Res current: " + << this->cmvResCurrent << " A" << std::endl; + sif::info << "PowerSet::printSet: CMV Res voltage: " + << this->cmvResVoltage << " V" << std::endl; + } +}; + +/** + * @brief Data set to store the time telemetry packet. + */ +class TimeSet: + public StaticLocalDataSet { +public: + + static const size_t SIZE = 24; + + TimeSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, TIME_SET_ID) { + } + + TimeSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, TIME_SET_ID)) { + } + + lp_var_t ticks = lp_var_t(sid.objectId, + PoolIds::TICKS_TIME_SET, this); + /** Unix time in microseconds */ + lp_var_t time = lp_var_t(sid.objectId, + PoolIds::TIME_TIME_SET, this); + // Number of milliseconds since processor start-up + lp_var_t runTime = lp_var_t(sid.objectId, + PoolIds::RUN_TIME, this); + // Unix time in seconds?? --> maybe typo in datasheet. Seems to be microseconds + lp_var_t unixTime = lp_var_t(sid.objectId, + PoolIds::UNIX_TIME, this); + void printSet() { + PoolReadGuard rg(this); + sif::info << "TimeSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "TimeSet::printSet: Time (time stamp): " + << this->time << " us" << std::endl; + sif::info << "TimeSet::printSet: Run Time: " + << this->runTime << " ms" << std::endl; + sif::info << "TimeSet::printSet: Unix Time: " + << this->unixTime << " s" << std::endl; + } +}; + +/** + * @brief The solution dataset is the main dataset of the star tracker and contains the + * attitude information. + */ +class SolutionSet: + public StaticLocalDataSet { +public: + + static const size_t SIZE = 78; + + SolutionSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, SOLUTION_SET_ID) { + } + + SolutionSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, SOLUTION_SET_ID)) { + } + + // Ticks timestamp + lp_var_t ticks = lp_var_t(sid.objectId, + PoolIds::TICKS_SOLUTION_SET, this); + /// Unix time stamp + lp_var_t time = lp_var_t(sid.objectId, + PoolIds::TIME_SOLUTION_SET, this); + // Calibrated quaternion (takes into account the mounting quaternion), typically same as + // track q values + lp_var_t caliQw = lp_var_t(sid.objectId, PoolIds::CALI_QW, this); + lp_var_t caliQx = lp_var_t(sid.objectId, PoolIds::CALI_QX, this); + lp_var_t caliQy = lp_var_t(sid.objectId, PoolIds::CALI_QY, this); + lp_var_t caliQz = lp_var_t(sid.objectId, PoolIds::CALI_QZ, this); + // The lower this value the more confidence that the star tracker solution is correct + lp_var_t trackConfidence = lp_var_t(sid.objectId, PoolIds::TRACK_CONFIDENCE, + this); + // Estimated attitude of spacecraft + lp_var_t trackQw = lp_var_t(sid.objectId, PoolIds::TRACK_QW, this); + lp_var_t trackQx = lp_var_t(sid.objectId, PoolIds::TRACK_QX, this); + lp_var_t trackQy = lp_var_t(sid.objectId, PoolIds::TRACK_QY, this); + lp_var_t trackQz = lp_var_t(sid.objectId, PoolIds::TRACK_QZ, this); + // Number of stars removed from tracking solution + lp_var_t trackRemoved = lp_var_t(sid.objectId, PoolIds::TRACK_REMOVED, this); + // Number of stars for which a valid centroid was found + lp_var_t starsCentroided = lp_var_t(sid.objectId, PoolIds::STARS_CENTROIDED, + this); + // Number of stars that matched to a database star + lp_var_t starsMatchedDatabase = lp_var_t(sid.objectId, + PoolIds::STARS_MATCHED_DATABASE, this); + // Result of LISA (lost in space algorithm), searches for stars without prior knowledge of + // attitude + lp_var_t lisaQw = lp_var_t(sid.objectId, PoolIds::LISA_QW, this); + lp_var_t lisaQx = lp_var_t(sid.objectId, PoolIds::LISA_QX, this); + lp_var_t lisaQy = lp_var_t(sid.objectId, PoolIds::LISA_QY, this); + lp_var_t lisaQz = lp_var_t(sid.objectId, PoolIds::LISA_QZ, this); + // Percentage of close stars in LISA solution + lp_var_t lisaPercentageClose = lp_var_t(sid.objectId, PoolIds::LISA_PERC_CLOSE, + this); + // Number of close stars in LISA solution + lp_var_t lisaNrClose = lp_var_t(sid.objectId, PoolIds::LISA_NR_CLOSE, this); + // Gives a combined overview of the validation parameters (1 for valid solution, otherwise 0) + lp_var_t isTrustWorthy = lp_var_t(sid.objectId, PoolIds::TRUST_WORTHY, this); + // Number of times the validation criteria was met + lp_var_t stableCount = lp_var_t(sid.objectId, PoolIds::STABLE_COUNT, this); + // Shows the autonomous mode used to obtain the star tracker attitude + lp_var_t solutionStrategy = lp_var_t(sid.objectId, PoolIds::SOLUTION_STRATEGY, + this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "SolutionSet::printSet: Ticks: " + << this->ticks << std::endl; + sif::info << "SolutionSet::printSet: Time: " + << this->time << std::endl; + sif::info << "SolutionSet::printSet: Calibrated quaternion Qw: " + << this->caliQw << std::endl; + sif::info << "SolutionSet::printSet: Calibrated quaternion Qx: " + << this->caliQx << std::endl; + sif::info << "SolutionSet::printSet: Calibrated quaternion Qy: " + << this->caliQy << std::endl; + sif::info << "SolutionSet::printSet: Calibrated quaternion Qz: " + << this->caliQz << std::endl; + sif::info << "SolutionSet::printSet: Track confidence: " + << this->trackConfidence << std::endl; + sif::info << "SolutionSet::printSet: Track Qw: " + << this->trackQw << std::endl; + sif::info << "SolutionSet::printSet: Track Qx: " + << this->trackQx << std::endl; + sif::info << "SolutionSet::printSet: Track Qy: " + << this->trackQy << std::endl; + sif::info << "SolutionSet::printSet: Track Qz: " + << this->trackQz << std::endl; + sif::info << "SolutionSet::printSet: Track removed: " + << static_cast(this->trackRemoved.value) << std::endl; + sif::info << "SolutionSet::printSet: Number of stars centroided: " + << static_cast(this->starsCentroided.value) << std::endl; + sif::info << "SolutionSet::printSet: Number of stars matched database: " + << static_cast(this->starsMatchedDatabase.value) << std::endl; + sif::info << "SolutionSet::printSet: LISA Qw: " + << this->lisaQw << std::endl; + sif::info << "SolutionSet::printSet: LISA Qx: " + << this->lisaQx << std::endl; + sif::info << "SolutionSet::printSet: LISA Qy: " + << this->lisaQy << std::endl; + sif::info << "SolutionSet::printSet: LISA Qz: " + << this->lisaQz << std::endl; + sif::info << "SolutionSet::printSet: LISA Percentage close: " + << this->lisaPercentageClose << std::endl; + sif::info << "SolutionSet::printSet: LISA number of close stars: " + << static_cast(this->lisaNrClose.value) << std::endl; + sif::info << "SolutionSet::printSet: Is trust worthy: " + << static_cast(this->isTrustWorthy.value) << std::endl; + sif::info << "SolutionSet::printSet: Stable count: " + << this->stableCount << std::endl; + sif::info << "SolutionSet::printSet: Solution strategy: " + << static_cast(this->solutionStrategy.value) << std::endl; + } +}; + +/** + * @brief Dataset to store the histogram + */ +class HistogramSet: + public StaticLocalDataSet { +public: + + // Size of dataset + static const size_t SIZE = 156; + + HistogramSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, HISTOGRAM_SET_ID) { + } + + HistogramSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, HISTOGRAM_SET_ID)) { + } + + lp_var_t ticks = lp_var_t(sid.objectId, PoolIds::TICKS_HISTOGRAM_SET, this); + lp_var_t time = lp_var_t(sid.objectId, PoolIds::TIME_HISTOGRAM_SET, this); + lp_var_t binA0 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA0, this); + lp_var_t binA1 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA1, this); + lp_var_t binA2 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA2, this); + lp_var_t binA3 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA3, this); + lp_var_t binA4 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA4, this); + lp_var_t binA5 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA5, this); + lp_var_t binA6 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA6, this); + lp_var_t binA7 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA7, this); + lp_var_t binA8 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINA8, this); + lp_var_t binB0 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB0, this); + lp_var_t binB1 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB1, this); + lp_var_t binB2 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB2, this); + lp_var_t binB3 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB3, this); + lp_var_t binB4 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB4, this); + lp_var_t binB5 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB5, this); + lp_var_t binB6 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB6, this); + lp_var_t binB7 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB7, this); + lp_var_t binB8 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINB8, this); + lp_var_t binC0 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC0, this); + lp_var_t binC1 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC1, this); + lp_var_t binC2 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC2, this); + lp_var_t binC3 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC3, this); + lp_var_t binC4 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC4, this); + lp_var_t binC5 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC5, this); + lp_var_t binC6 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC6, this); + lp_var_t binC7 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC7, this); + lp_var_t binC8 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BINC8, this); + lp_var_t binD0 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND0, this); + lp_var_t binD1 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND1, this); + lp_var_t binD2 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND2, this); + lp_var_t binD3 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND3, this); + lp_var_t binD4 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND4, this); + lp_var_t binD5 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND5, this); + lp_var_t binD6 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND6, this); + lp_var_t binD7 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND7, this); + lp_var_t binD8 = lp_var_t(sid.objectId, PoolIds::HISTOGRAM_BIND8, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "HistogramSet::printSet: Ticks: " << this->ticks << std::endl; + sif::info << "HistogramSet::printSet: Time (time stamp): " << this->time << " us" + << std::endl; + sif::info << "HistogramSet::printSet: BinA0: " << this->binA0 << std::endl; + sif::info << "HistogramSet::printSet: BinA1: " << this->binA1 << std::endl; + sif::info << "HistogramSet::printSet: BinA2: " << this->binA2 << std::endl; + sif::info << "HistogramSet::printSet: BinA3: " << this->binA3 << std::endl; + sif::info << "HistogramSet::printSet: BinA4: " << this->binA4 << std::endl; + sif::info << "HistogramSet::printSet: BinA5: " << this->binA5 << std::endl; + sif::info << "HistogramSet::printSet: BinA6: " << this->binA6 << std::endl; + sif::info << "HistogramSet::printSet: BinA7: " << this->binA7 << std::endl; + sif::info << "HistogramSet::printSet: BinA8: " << this->binA8 << std::endl; + sif::info << "HistogramSet::printSet: BinB0: " << this->binB0 << std::endl; + sif::info << "HistogramSet::printSet: BinB1: " << this->binB1 << std::endl; + sif::info << "HistogramSet::printSet: BinB2: " << this->binB2 << std::endl; + sif::info << "HistogramSet::printSet: BinB3: " << this->binB3 << std::endl; + sif::info << "HistogramSet::printSet: BinB4: " << this->binB4 << std::endl; + sif::info << "HistogramSet::printSet: BinB5: " << this->binB5 << std::endl; + sif::info << "HistogramSet::printSet: BinB6: " << this->binB6 << std::endl; + sif::info << "HistogramSet::printSet: BinB7: " << this->binB7 << std::endl; + sif::info << "HistogramSet::printSet: BinB8: " << this->binB8 << std::endl; + sif::info << "HistogramSet::printSet: BinC0: " << this->binC0 << std::endl; + sif::info << "HistogramSet::printSet: BinC1: " << this->binC1 << std::endl; + sif::info << "HistogramSet::printSet: BinC2: " << this->binC2 << std::endl; + sif::info << "HistogramSet::printSet: BinC3: " << this->binC3 << std::endl; + sif::info << "HistogramSet::printSet: BinC4: " << this->binC4 << std::endl; + sif::info << "HistogramSet::printSet: BinC5: " << this->binC5 << std::endl; + sif::info << "HistogramSet::printSet: BinC6: " << this->binC6 << std::endl; + sif::info << "HistogramSet::printSet: BinC7: " << this->binC7 << std::endl; + sif::info << "HistogramSet::printSet: BinC8: " << this->binC8 << std::endl; + sif::info << "HistogramSet::printSet: BinD0: " << this->binD0 << std::endl; + sif::info << "HistogramSet::printSet: BinD1: " << this->binD1 << std::endl; + sif::info << "HistogramSet::printSet: BinD2: " << this->binD2 << std::endl; + sif::info << "HistogramSet::printSet: BinD3: " << this->binD3 << std::endl; + sif::info << "HistogramSet::printSet: BinD4: " << this->binD4 << std::endl; + sif::info << "HistogramSet::printSet: BinD5: " << this->binD5 << std::endl; + sif::info << "HistogramSet::printSet: BinD6: " << this->binD6 << std::endl; + sif::info << "HistogramSet::printSet: BinD7: " << this->binD7 << std::endl; + sif::info << "HistogramSet::printSet: BinD8: " << this->binD8 << std::endl; + } +}; + +/** + * @brief Dataset to store the contrast telemetry data + */ +class ContrastSet: + public StaticLocalDataSet { +public: + + // Size of dataset + static const size_t SIZE = 156; + + ContrastSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, CONTRAST_SET_ID) { + } + + ContrastSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, CONTRAST_SET_ID)) { + } + + lp_var_t ticks = lp_var_t(sid.objectId, PoolIds::TICKS_CONTRAST_SET, this); + lp_var_t time = lp_var_t(sid.objectId, PoolIds::TIME_CONTRAST_SET, this); + lp_var_t binA0 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA0, this); + lp_var_t binA1 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA1, this); + lp_var_t binA2 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA2, this); + lp_var_t binA3 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA3, this); + lp_var_t binA4 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA4, this); + lp_var_t binA5 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA5, this); + lp_var_t binA6 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA6, this); + lp_var_t binA7 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA7, this); + lp_var_t binA8 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINA8, this); + lp_var_t binb0 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB0, this); + lp_var_t binB1 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB1, this); + lp_var_t binB2 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB2, this); + lp_var_t binB3 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB3, this); + lp_var_t binB4 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB4, this); + lp_var_t binB5 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB5, this); + lp_var_t binB6 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB6, this); + lp_var_t binB7 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB7, this); + lp_var_t binB8 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINB8, this); + lp_var_t binC0 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC0, this); + lp_var_t binC1 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC1, this); + lp_var_t binC2 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC2, this); + lp_var_t binC3 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC3, this); + lp_var_t binC4 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC4, this); + lp_var_t binC5 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC5, this); + lp_var_t binC6 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC6, this); + lp_var_t binC7 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC7, this); + lp_var_t binC8 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BINC8, this); + lp_var_t binD0 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND0, this); + lp_var_t binD1 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND1, this); + lp_var_t binD2 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND2, this); + lp_var_t binD3 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND3, this); + lp_var_t binD4 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND4, this); + lp_var_t binD5 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND5, this); + lp_var_t binD6 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND6, this); + lp_var_t binD7 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND7, this); + lp_var_t binD8 = lp_var_t(sid.objectId, PoolIds::CONTRAST_BIND8, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "ContrastSet::printSet: Ticks: " << this->ticks << std::endl; + sif::info << "ContrastSet::printSet: Time (time stamp): " << this->time << " us" + << std::endl; + sif::info << "ContrastSet::printSet: BinA0: " << this->binA0 << std::endl; + sif::info << "ContrastSet::printSet: BinA1: " << this->binA1 << std::endl; + sif::info << "ContrastSet::printSet: BinA2: " << this->binA2 << std::endl; + sif::info << "ContrastSet::printSet: BinA3: " << this->binA3 << std::endl; + sif::info << "ContrastSet::printSet: BinA4: " << this->binA4 << std::endl; + sif::info << "ContrastSet::printSet: BinA5: " << this->binA5 << std::endl; + sif::info << "ContrastSet::printSet: BinA6: " << this->binA6 << std::endl; + sif::info << "ContrastSet::printSet: BinA7: " << this->binA7 << std::endl; + sif::info << "ContrastSet::printSet: BinA8: " << this->binA8 << std::endl; + sif::info << "ContrastSet::printSet: BinB0: " << this->binA0 << std::endl; + sif::info << "ContrastSet::printSet: BinB1: " << this->binB1 << std::endl; + sif::info << "ContrastSet::printSet: BinB2: " << this->binB2 << std::endl; + sif::info << "ContrastSet::printSet: BinB3: " << this->binB3 << std::endl; + sif::info << "ContrastSet::printSet: BinB4: " << this->binB4 << std::endl; + sif::info << "ContrastSet::printSet: BinB5: " << this->binB5 << std::endl; + sif::info << "ContrastSet::printSet: BinB6: " << this->binB6 << std::endl; + sif::info << "ContrastSet::printSet: BinB7: " << this->binB7 << std::endl; + sif::info << "ContrastSet::printSet: BinB8: " << this->binB8 << std::endl; + sif::info << "ContrastSet::printSet: BinC0: " << this->binC0 << std::endl; + sif::info << "ContrastSet::printSet: BinC1: " << this->binC1 << std::endl; + sif::info << "ContrastSet::printSet: BinC2: " << this->binC2 << std::endl; + sif::info << "ContrastSet::printSet: BinC3: " << this->binC3 << std::endl; + sif::info << "ContrastSet::printSet: BinC4: " << this->binC4 << std::endl; + sif::info << "ContrastSet::printSet: BinC5: " << this->binC5 << std::endl; + sif::info << "ContrastSet::printSet: BinC6: " << this->binC6 << std::endl; + sif::info << "ContrastSet::printSet: BinC7: " << this->binC7 << std::endl; + sif::info << "ContrastSet::printSet: BinC8: " << this->binC8 << std::endl; + sif::info << "ContrastSet::printSet: BinD0: " << this->binD0 << std::endl; + sif::info << "ContrastSet::printSet: BinD1: " << this->binD1 << std::endl; + sif::info << "ContrastSet::printSet: BinD2: " << this->binD2 << std::endl; + sif::info << "ContrastSet::printSet: BinD3: " << this->binD3 << std::endl; + sif::info << "ContrastSet::printSet: BinD4: " << this->binD4 << std::endl; + sif::info << "ContrastSet::printSet: BinD5: " << this->binD5 << std::endl; + sif::info << "ContrastSet::printSet: BinD6: " << this->binD6 << std::endl; + sif::info << "ContrastSet::printSet: BinD7: " << this->binD7 << std::endl; + sif::info << "ContrastSet::printSet: BinD8: " << this->binD8 << std::endl; + } +}; + +/** + * @brief Helper Class to extract information from bytestream. + */ +class ChecksumReply { +public: + + /** + * @brief Constructor + * + * @param datafield Pointer to datafield in reply buffer + * + */ + ChecksumReply(const uint8_t* datafield) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + region = *(datafield); + const uint8_t* addressData = datafield + ADDRESS_OFFSET; + size_t size = sizeof(address); + result = SerializeAdapter::deSerialize(&address, &addressData, &size, + SerializeIF::Endianness::LITTLE); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "ChecksumReply::ChecksumReply: Failed to deserialize address" + << std::endl; + } + const uint8_t* lengthData = datafield + LENGTH_OFFSET; + size = sizeof(length); + result = SerializeAdapter::deSerialize(&length, &lengthData, &size, + SerializeIF::Endianness::LITTLE); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "ChecksumReply::ChecksumReply: Failed to deserialize length" + << std::endl; + } + const uint8_t* checksumData = datafield + CHECKSUM_OFFSET; + size = sizeof(checksum); + result = SerializeAdapter::deSerialize(&checksum, &checksumData, &size, + SerializeIF::Endianness::LITTLE); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "ChecksumReply::ChecksumReply: Failed to deserialize checksum" + << std::endl; + } + } + + uint8_t getRegion() { + return region; + } + + uint32_t getAddress() { + return address; + } + + uint32_t getLength() { + return length; + } + + uint32_t getChecksum() { + return checksum; + } + + void printChecksum() { + sif::info << "ChecksumReply::printChecksum: 0x" << std::hex << checksum << std::endl; + } + +private: + + static const uint8_t ADDRESS_OFFSET = 1; + static const uint8_t LENGTH_OFFSET = 5; + static const uint8_t CHECKSUM_OFFSET = 9; + + uint8_t region = 0; + uint32_t address = 0; + uint32_t length = 0; + uint32_t checksum = 0; +}; + +class EraseReply { +public: + EraseReply(const uint8_t* datafield) { + region = *datafield; + } + + uint8_t getRegion() { + return region; + } + +private: + uint8_t region = 0; +}; + +class ChecksumSet: + public StaticLocalDataSet { +public: + + // Size of dataset + static const size_t SIZE = 156; + + ChecksumSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, CHECKSUM_SET_ID) { + } + + ChecksumSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, CHECKSUM_SET_ID)) { + } + + lp_var_t checksum = lp_var_t(sid.objectId, PoolIds::CHKSUM, this); +}; + +/** + * @brief Dataset to store download centroid response + */ +class DownloadCentroidSet: + public StaticLocalDataSet { +public: + + // Size of dataset + static const size_t SIZE = 34; + + DownloadCentroidSet(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, DOWNLOADCENTROID_SET_ID) { + } + + DownloadCentroidSet(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, DOWNLOADCENTROID_SET_ID)) { + } + + lp_var_t id = lp_var_t(sid.objectId, PoolIds::DWL_ID, this); + lp_var_t pixx = lp_var_t(sid.objectId, PoolIds::DWL_PIXX, this); + lp_var_t pixy = lp_var_t(sid.objectId, PoolIds::DWL_PIXY, this); + lp_var_t xUncorrected = lp_var_t(sid.objectId, PoolIds::DWL_X_UNCORRECTED, this); + lp_var_t yUncorrected = lp_var_t(sid.objectId, PoolIds::DWL_Y_UNCORRECTED, this); + lp_var_t xCorrected = lp_var_t(sid.objectId, PoolIds::DWL_X_CORRECTED, this); + lp_var_t yCorrected = lp_var_t(sid.objectId, PoolIds::DWL_Y_CORRECTED, this); + lp_var_t magnitude = lp_var_t(sid.objectId, PoolIds::DWL_MAGNITUDE, this); + lp_var_t cxa = lp_var_t(sid.objectId, PoolIds::DWL_CXA, this); + lp_var_t cya = lp_var_t(sid.objectId, PoolIds::DWL_CYA, this); + lp_var_t quality = lp_var_t(sid.objectId, PoolIds::DWL_QUALITY, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "ContrastSet::printSet: id: " << static_cast(this->id.value) + << std::endl; + sif::info << "ContrastSet::printSet: pixx: " << this->pixx << std::endl; + sif::info << "ContrastSet::printSet: pixy: " << this->pixy << std::endl; + sif::info << "ContrastSet::printSet: xUncorrected: " << this->xUncorrected << std::endl; + sif::info << "ContrastSet::printSet: yUncorrected: " << this->yUncorrected << std::endl; + sif::info << "ContrastSet::printSet: xCorrected: " << this->xCorrected << std::endl; + sif::info << "ContrastSet::printSet: yCorrected: " << this->yCorrected << std::endl; + sif::info << "ContrastSet::printSet: magnitude: " << this->magnitude << std::endl; + sif::info << "ContrastSet::printSet: cxa: " << this->cxa << std::endl; + sif::info << "ContrastSet::printSet: cya: " << this->cya << std::endl; + sif::info << "ContrastSet::printSet: quality: " << this->quality << std::endl; + } +}; + +namespace UploadCentroidKeys { + static const char id[] = "id"; + static const char pixx[] = "pixx"; + static const char pixy[] = "pixy"; + static const char x_uncorrected[] = "x_uncorrected"; + static const char y_uncorrected[] = "y_uncorrected"; + static const char x_corrected[] = "x_corrected"; + static const char y_corrected[] = "y_corrected"; + static const char magnitude[] = "magnitude"; + static const char cxa[] = "cxa"; + static const char cya[] = "cya"; + static const char quality[] = "quality"; +}; + +/** + * @brief Dataset to store matched star information + */ +class DownloadMatchedStar : + public StaticLocalDataSet { +public: + + // Size of dataset + static const size_t SIZE = 53; + + DownloadMatchedStar(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, DOWNLOAD_MATCHED_STAR_SET_ID) { + } + + DownloadMatchedStar(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, DOWNLOAD_MATCHED_STAR_SET_ID)) { + } + + lp_var_t id = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_ID, this); + lp_var_t camfpx = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMFPX, this); + lp_var_t camfpy = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMFPY, this); + lp_var_t camcartx = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMCARTX, this); + lp_var_t camcarty = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMCARTY, this); + lp_var_t camcartz = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMCARTZ, this); + lp_var_t cammagnitude = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CAMMAGNITUDE, + this); + lp_var_t dbfpx = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBFPX, this); + lp_var_t dbfpy = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBFPY, this); + lp_var_t dbcartx = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBCARTX, this); + lp_var_t dbcarty = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBCARTY, this); + lp_var_t dbcartz = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBCARTZ, this); + lp_var_t dbmagnitude = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_DBMAGNITUDE, + this); + lp_var_t catalogid = lp_var_t(sid.objectId, PoolIds::MATCHEDSTR_CATALOGID, + this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "DownloadMatchedStar::printSet: id: " + << static_cast(this->id.value) << std::endl; + sif::info << "DownloadMatchedStar::printSet: camfpx: " << this->camfpx << std::endl; + sif::info << "DownloadMatchedStar::printSet: camfpy: " << this->camfpy << std::endl; + sif::info << "DownloadMatchedStar::printSet: camcartx: " << this->camcartx << std::endl; + sif::info << "DownloadMatchedStar::printSet: camcarty: " << this->camcarty << std::endl; + sif::info << "DownloadMatchedStar::printSet: camcartz: " << this->camcartz << std::endl; + sif::info << "DownloadMatchedStar::printSet: cammagnitude: " << this->cammagnitude + << std::endl; + sif::info << "DownloadMatchedStar::printSet: dbfpx: " << this->dbfpx << std::endl; + sif::info << "DownloadMatchedStar::printSet: dbfpy: " << this->dbfpy << std::endl; + sif::info << "DownloadMatchedStar::printSet: dbcartx: " << this->dbcartx << std::endl; + sif::info << "DownloadMatchedStar::printSet: dbcarty: " << this->dbcarty << std::endl; + sif::info << "DownloadMatchedStar::printSet: dbcartz: " << this->dbcartz << std::endl; + sif::info << "DownloadMatchedStar::printSet: dbmagnitude: " << this->dbmagnitude + << std::endl; + sif::info << "DownloadMatchedStar::printSet: catalogid: " << this->catalogid << std::endl; + } +}; + +/** + * @brief Dataset to store the response to the DownloadDBImage request + */ +class DownloadDBImage : + public StaticLocalDataSet { +public: + + // Size of dataset + static const size_t SIZE = 21; + + DownloadDBImage(HasLocalDataPoolIF* owner): + StaticLocalDataSet(owner, DOWNLOAD_DBIMAGE_SET_ID) { + } + + DownloadDBImage(object_id_t objectId): + StaticLocalDataSet(sid_t(objectId, DOWNLOAD_DBIMAGE_SET_ID)) { + } + + lp_var_t id = lp_var_t(sid.objectId, PoolIds::DBIMAGE_ID, this); + lp_var_t pixx = lp_var_t(sid.objectId, PoolIds::DBIMAGE_PIXX, this); + lp_var_t pixy = lp_var_t(sid.objectId, PoolIds::DBIMAGE_PIXY, this); + lp_var_t x = lp_var_t(sid.objectId, PoolIds::DBIMAGE_X, this); + lp_var_t y = lp_var_t(sid.objectId, PoolIds::DBIMAGE_Y, this); + lp_var_t magnitude = lp_var_t(sid.objectId, PoolIds::DBIMAGE_MAGNITUDE, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "DownloadDBImage::printSet: id: " + << static_cast(this->id.value) << std::endl; + sif::info << "DownloadDBImage::printSet: pixx: " << this->pixx << std::endl; + sif::info << "DownloadDBImage::printSet: pixy: " << this->pixy << std::endl; + sif::info << "DownloadDBImage::printSet: x: " << this->x << std::endl; + sif::info << "DownloadDBImage::printSet: y: " << this->y << std::endl; + sif::info << "DownloadDBImage::printSet: magnitude: " << this->magnitude << std::endl; + } +}; + +/** + * @brief Dataset to store the response to the download blob pixel action request + */ +class DownloadBlobPixel: public StaticLocalDataSet { +public: + + // Size of dataset + static const size_t SIZE = 22; + + DownloadBlobPixel(HasLocalDataPoolIF* owner) : + StaticLocalDataSet(owner, DOWNLOAD_BLOBPIXEL_SET_ID) { + } + + DownloadBlobPixel(object_id_t objectId) : + StaticLocalDataSet(sid_t(objectId, DOWNLOAD_BLOBPIXEL_SET_ENTRIES)) { + } + + lp_var_t id = lp_var_t(sid.objectId, PoolIds::BLOBPIX_ID, this); + lp_var_t x = lp_var_t(sid.objectId, PoolIds::BLOBPIX_X, this); + lp_var_t y = lp_var_t(sid.objectId, PoolIds::BLOBPIX_Y, this); + lp_var_t totalValue = lp_var_t(sid.objectId, PoolIds::BLOBPIX_TOT_VAL, this); + lp_var_t inUse = lp_var_t(sid.objectId, PoolIds::BLOBPIX_IN_USE, this); + lp_var_t brightNeighbours = lp_var_t(sid.objectId, + PoolIds::BLOBPIX_BRIGHT_NEIGHBOURS, this); + lp_var_t region = lp_var_t(sid.objectId, PoolIds::BLOBPIX_REGION, this); + + void printSet() { + PoolReadGuard rg(this); + sif::info << "DownloadBlobPixel::printSet: id: " + << static_cast(this->id.value) << std::endl; + sif::info << "DownloadBlobPixel::printSet: x: " << this->x << std::endl; + sif::info << "DownloadBlobPixel::printSet: y: " << this->y << std::endl; + sif::info << "DownloadBlobPixel::printSet: totalValue: " << this->totalValue << std::endl; + sif::info << "DownloadBlobPixel::printSet: inUse: " + << static_cast(this->inUse.value) << std::endl; + sif::info << "DownloadBlobPixel::printSet: brightNeighbours: " << this->brightNeighbours + << std::endl; + sif::info << "DownloadBlobPixel::printSet: region: " << this->region << std::endl; + } +}; +} +#endif /* MISSION_STARTRACKER_DEFINITIONS_H_ */ diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp new file mode 100644 index 00000000..de70037a --- /dev/null +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp @@ -0,0 +1,1949 @@ +#include +#include "StarTrackerHandler.h" +#include "OBSWConfig.h" +#include "StarTrackerJsonCommands.h" +#include +#include +#include +extern "C" { + #include + #include + #include "common/misc.h" +} + +using json = nlohmann::json; + +StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, + CookieIF * comCookie, StrHelper* strHelper) : + DeviceHandlerBase(objectId, comIF, comCookie), temperatureSet(this), versionSet(this), powerSet( + this), interfaceSet(this), timeSet(this), solutionSet(this), histogramSet(this), contrastSet( + this), checksumSet(this), downloadCentroidSet(this), downloadMatchedStar(this), + downloadDbImage(this), downloadBlobPixel(this), strHelper( + strHelper) { + if (comCookie == nullptr) { + sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl; + } + if (strHelper == nullptr) { + sif::error << "StarTrackerHandler: Invalid str image loader" << std::endl; + } + eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5); +} + +StarTrackerHandler::~StarTrackerHandler() { +} + +ReturnValue_t StarTrackerHandler::initialize() { + ReturnValue_t result = RETURN_OK; + result = DeviceHandlerBase::initialize(); + if (result != RETURN_OK) { + return result; + } + + EventManagerIF* manager = ObjectManager::instance()->get( + objects::EVENT_MANAGER); + if (manager == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "StarTrackerHandler::initialize: Invalid event manager" << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED;; + } + result = manager->registerListener(eventQueue->getId()); + if (result != RETURN_OK) { + return result; + } + result = manager->subscribeToEventRange(eventQueue->getId(), + event::getEventId(StrHelper::IMAGE_UPLOAD_FAILED), + event::getEventId(StrHelper::FPGA_UPLOAD_FAILED)); + if (result != RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "StarTrackerHandler::initialize: Failed to subscribe to events from " + " str helper" << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + result = strHelper->setComIF(communicationInterface); + if (result != RETURN_OK) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } + strHelper->setComCookie(comCookie); + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) { + + ReturnValue_t result = RETURN_OK; + + switch(actionId) { + case(StarTracker::STOP_IMAGE_LOADER): { + strHelper->stopProcess(); + return EXECUTION_FINISHED; + } + case(StarTracker::SET_JSON_FILE_NAME): { + if (size > MAX_PATH_SIZE) { + return FILE_PATH_TOO_LONG; + } + paramJsonFile = std::string(reinterpret_cast(data), size); + return EXECUTION_FINISHED; + } + default: + break; + } + + if (strHelperExecuting == true) { + return IMAGE_LOADER_EXECUTING; + } + + result = checkMode(actionId); + if (result != RETURN_OK) { + return result; + } + + // Intercept image loader commands which do not follow the common DHB communication flow + switch(actionId) { + case(StarTracker::UPLOAD_IMAGE): { + result = DeviceHandlerBase::acceptExternalDeviceCommands(); + if (result != RETURN_OK) { + return result; + } + if (size > MAX_PATH_SIZE + MAX_FILE_NAME) { + return FILE_PATH_TOO_LONG; + } + result = strHelper->startImageUpload( + std::string(reinterpret_cast(data), size)); + if (result != RETURN_OK) { + return result; + } + strHelperExecuting = true; + return EXECUTION_FINISHED; + } + case(StarTracker::DOWNLOAD_IMAGE): { + result = DeviceHandlerBase::acceptExternalDeviceCommands(); + if (result != RETURN_OK) { + return result; + } + if (size > MAX_PATH_SIZE) { + return FILE_PATH_TOO_LONG; + } + result = strHelper->startImageDownload( + std::string(reinterpret_cast(data), size)); + if (result != RETURN_OK) { + return result; + } + strHelperExecuting = true; + return EXECUTION_FINISHED; + } + case(StarTracker::WRITE): { + result = DeviceHandlerBase::acceptExternalDeviceCommands(); + if (result != RETURN_OK) { + return result; + } + result = executeWriteCommand(data, size); + if (result != RETURN_OK) { + return result; + } + + strHelperExecuting = true; + return EXECUTION_FINISHED; + } + case(StarTracker::READ): { + result = DeviceHandlerBase::acceptExternalDeviceCommands(); + if (result != RETURN_OK) { + return result; + } + result = executeReadCommand(data, size); + if (result != RETURN_OK) { + return result; + } + strHelperExecuting = true; + return EXECUTION_FINISHED; + } + case(StarTracker::CHANGE_DOWNLOAD_FILE): { + if (size > MAX_FILE_NAME) { + return FILENAME_TOO_LONG; + } + strHelper->setDownloadImageName( + std::string(reinterpret_cast(data), size)); + return EXECUTION_FINISHED; + } + case(StarTracker::CHANGE_FPGA_DOWNLOAD_FILE): { + if (size > MAX_FILE_NAME) { + return FILENAME_TOO_LONG; + } + strHelper->setDownloadFpgaImage(std::string(reinterpret_cast(data), size)); + return EXECUTION_FINISHED; + } + case(StarTracker::SET_READ_FILENAME): { + if (size > MAX_FILE_NAME) { + return FILENAME_TOO_LONG; + } + strHelper->setDownloadImageName( + std::string(reinterpret_cast(data), size)); + return EXECUTION_FINISHED; + } + case(StarTracker::DOWNLOAD_FPGA_IMAGE): { + result = DeviceHandlerBase::acceptExternalDeviceCommands(); + if (result != RETURN_OK) { + return result; + } + if (size > MAX_PATH_SIZE) { + return FILE_PATH_TOO_LONG; + } + result = executeFpgaDownloadCommand(data, size); + if (result != RETURN_OK) { + return result; + } + strHelperExecuting = true; + return EXECUTION_FINISHED; + } + case(StarTracker::UPLOAD_FPGA_IMAGE): { + result = DeviceHandlerBase::acceptExternalDeviceCommands(); + if (result != RETURN_OK) { + return result; + } + if (size > MAX_PATH_SIZE + MAX_FILE_NAME) { + return FILE_PATH_TOO_LONG; + } + result = strHelper->startFpgaUpload(std::string(reinterpret_cast(data), size)); + if (result != RETURN_OK) { + return result; + } + strHelperExecuting = true; + return EXECUTION_FINISHED; + } + default: + break; + } + return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size); +} + +void StarTrackerHandler::performOperationHook() { + EventMessage event; + for (ReturnValue_t result = eventQueue->receiveMessage(&event); + result == RETURN_OK; result = eventQueue->receiveMessage(&event)) { + switch (event.getMessageId()) { + case EventMessage::EVENT_MESSAGE: + handleEvent(&event); + break; + default: + sif::debug << "CCSDSHandler::checkEvents: Did not subscribe to this event message" + << std::endl; + break; + } + } +} + +void StarTrackerHandler::doStartUp() { + switch(startupState) { + case StartupState::IDLE: + startupState = StartupState::CHECK_BOOT_STATE; + return; + case StartupState::BOOT_DELAY: + if (bootCountdown.hasTimedOut()) { + startupState = StartupState::LIMITS; + } + return; + case StartupState::DONE: + break; + default: + return; + } + setMode(_MODE_TO_ON); +} + +void StarTrackerHandler::doShutDown() { + // If star tracker is shutdown also stop all running processes in the image loader task + strHelper->stopProcess(); + setMode(_MODE_POWER_DOWN); +} + +void StarTrackerHandler::doOffActivity() { + startupState = StartupState::IDLE; +} + +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) { + if (mode != _MODE_START_UP) { + return NOTHING_TO_SEND; + } + switch (startupState) { + case StartupState::CHECK_BOOT_STATE: + *id = StarTracker::REQ_VERSION; + startupState = StartupState::WAIT_FOR_EXECUTION; + return buildCommandFromCommand(*id, nullptr, 0); + case StartupState::BOOT: + *id = StarTracker::BOOT; + bootCountdown.setTimeout(BOOT_TIMEOUT); + startupState = StartupState::BOOT_DELAY; + return buildCommandFromCommand(*id, nullptr, 0); + case StartupState::LIMITS: + startupState = StartupState::WAIT_FOR_EXECUTION; + *id = StarTracker::LIMITS; + return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), + paramJsonFile.size()); + case StartupState::TRACKING: + startupState = StartupState::WAIT_FOR_EXECUTION; + *id = StarTracker::TRACKING; + return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), + paramJsonFile.size()); + case StartupState::MOUNTING: + startupState = StartupState::WAIT_FOR_EXECUTION; + *id = StarTracker::MOUNTING; + return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), + paramJsonFile.size()); + case StartupState::CAMERA: + startupState = StartupState::WAIT_FOR_EXECUTION; + *id = StarTracker::CAMERA; + return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), + paramJsonFile.size()); + case StartupState::BLOB: + startupState = StartupState::WAIT_FOR_EXECUTION; + *id = StarTracker::BLOB; + return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), + paramJsonFile.size()); + case StartupState::CENTROIDING: + startupState = StartupState::WAIT_FOR_EXECUTION; + *id = StarTracker::CENTROIDING; + return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), + paramJsonFile.size()); + case StartupState::LISA: + startupState = StartupState::WAIT_FOR_EXECUTION; + *id = StarTracker::LISA; + return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), + paramJsonFile.size()); + case StartupState::MATCHING: + startupState = StartupState::WAIT_FOR_EXECUTION; + *id = StarTracker::MATCHING; + return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), + paramJsonFile.size()); + case StartupState::VALIDATION: + startupState = StartupState::WAIT_FOR_EXECUTION; + *id = StarTracker::VALIDATION; + return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), + paramJsonFile.size()); + case StartupState::ALGO: + startupState = StartupState::WAIT_FOR_EXECUTION; + *id = StarTracker::ALGO; + return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), + paramJsonFile.size()); + default: + break; + } + return NOTHING_TO_SEND; +} + +ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t * commandData, size_t commandDataLen) { + ReturnValue_t result = RETURN_OK; + switch (deviceCommand) { + case (StarTracker::PING_REQUEST): { + preparePingRequest(); + return RETURN_OK; + } + case (StarTracker::REQ_TIME): { + prepareTimeRequest(); + return RETURN_OK; + } + case (StarTracker::BOOT): { + prepareBootCommand(); + return RETURN_OK; + } + case (StarTracker::REQ_VERSION): { + prepareVersionRequest(); + return RETURN_OK; + } + case (StarTracker::REQ_INTERFACE): { + prepareInterfaceRequest(); + return RETURN_OK; + } + case (StarTracker::REQ_POWER): { + preparePowerRequest(); + return RETURN_OK; + } + case (StarTracker::SWITCH_TO_BOOTLOADER_PROGRAM): { + prepareRebootCommand(); + return RETURN_OK; + } + case (StarTracker::TAKE_IMAGE): { + prepareTakeImageCommand(commandData); + return RETURN_OK; + } + case (StarTracker::SUBSCRIBE_TO_TM): { + prepareSubscriptionCommand(commandData); + return RETURN_OK; + } + case (StarTracker::REQ_SOLUTION): { + prepareSolutionRequest(); + return RETURN_OK; + } + case (StarTracker::REQ_TEMPERATURE): { + prepareTemperatureRequest(); + return RETURN_OK; + } + case (StarTracker::REQ_HISTOGRAM): { + prepareHistogramRequest(); + return RETURN_OK; + } + case (StarTracker::REQ_CONTRAST): { + prepareContrastRequest(); + return RETURN_OK; + } + case (StarTracker::RESET_ERROR): { + prepareErrorResetRequest(); + return RETURN_OK; + } + case (StarTracker::LIMITS): { + Limits limits; + result = prepareParamCommand(commandData, commandDataLen, limits); + return result; + } + case (StarTracker::MOUNTING): { + Mounting mounting; + result = prepareParamCommand(commandData, commandDataLen, mounting); + return result; + } + case (StarTracker::CAMERA): { + Camera camera; + result = prepareParamCommand(commandData, commandDataLen, camera); + return result; + } + case (StarTracker::BLOB): { + Blob blob; + result = prepareParamCommand(commandData, commandDataLen, blob); + return result; + } + case (StarTracker::CENTROIDING): { + Centroiding centroiding; + result = prepareParamCommand(commandData, commandDataLen, centroiding); + return result; + } + case (StarTracker::LISA): { + Lisa lisa; + result = prepareParamCommand(commandData, commandDataLen, lisa); + return result; + } + case (StarTracker::MATCHING): { + Matching matching; + result = prepareParamCommand(commandData, commandDataLen, matching); + return result; + } + case (StarTracker::VALIDATION): { + Validation validation; + result = prepareParamCommand(commandData, commandDataLen, validation); + return result; + } + case (StarTracker::ALGO): { + Algo algo; + result = prepareParamCommand(commandData, commandDataLen, algo); + return result; + } + case (StarTracker::TRACKING): { + Tracking tracking; + result = prepareParamCommand(commandData, commandDataLen, tracking); + return result; + } + case (StarTracker::ERASE): { + result = prepareEraseCommand(commandData, commandDataLen); + return result; + } + case (StarTracker::UNLOCK): { + result = prepareUnlockCommand(commandData, commandDataLen); + return result; + } + case (StarTracker::CHECKSUM): { + result = prepareChecksumCommand(commandData, commandDataLen); + return result; + } + case (StarTracker::SET_TIME): { + result = prepareSetTimeCommand(commandData, commandDataLen); + return result; + } + case (StarTracker::DOWNLOAD_CENTROID): { + result = prepareDownloadCentroidCommand(commandData, commandDataLen); + return result; + } + case (StarTracker::UPLOAD_CENTROID): { + result = prepareUploadCentroidCommand(commandData, commandDataLen); + return result; + } + case (StarTracker::DOWNLOAD_MATCHED_STAR): { + result = prepareDownloadMatchedStarCommand(commandData, commandDataLen); + return result; + } + case (StarTracker::DOWNLOAD_DBIMAGE): { + result = prepareDownloadDbImageCommand(commandData, commandDataLen); + return result; + } + case (StarTracker::DOWNLOAD_BLOBPIXEL): { + result = prepareDownloadBlobPixelCommand(commandData, commandDataLen); + return result; + } + case (StarTracker::FPGA_ACTION): { + result = prepareFpgaActionCommand(commandData, commandDataLen); + return result; + } + 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::PING_REQUEST, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandMap(StarTracker::BOOT); + this->insertInCommandAndReplyMap(StarTracker::REQ_VERSION, 3, &versionSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_TIME, 3, &timeSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandMap(StarTracker::UPLOAD_IMAGE); + this->insertInCommandMap(StarTracker::DOWNLOAD_IMAGE); + this->insertInCommandAndReplyMap(StarTracker::REQ_POWER, 3, &powerSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_INTERFACE, 3, &interfaceSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + // Reboot has no reply. Star tracker reboots immediately + this->insertInCommandMap(StarTracker::SWITCH_TO_BOOTLOADER_PROGRAM); + this->insertInCommandAndReplyMap(StarTracker::SUBSCRIBE_TO_TM, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_SOLUTION, 3, &solutionSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_TEMPERATURE, 3, &temperatureSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_HISTOGRAM, 3, &histogramSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::REQ_CONTRAST, 3, &contrastSet, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::LIMITS, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::MOUNTING, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::CAMERA, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::BLOB, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::CENTROIDING, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::LISA, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::MATCHING, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::TRACKING, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::VALIDATION, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::ALGO, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::TAKE_IMAGE, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::RESET_ERROR, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::ERASE, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::UNLOCK, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::CHECKSUM, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::SET_TIME, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::DOWNLOAD_CENTROID, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::UPLOAD_CENTROID, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::DOWNLOAD_MATCHED_STAR, 3, &downloadMatchedStar, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::DOWNLOAD_DBIMAGE, 3, &downloadDbImage, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::DOWNLOAD_BLOBPIXEL, 3, &downloadBlobPixel, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::FPGA_ACTION, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); +} + +ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t remainingSize, + DeviceCommandId_t *foundId, size_t *foundLen) { + + ReturnValue_t result = RETURN_OK; + size_t bytesLeft = 0; + + result = dataLinkLayer.decodeFrame(start, remainingSize, &bytesLeft); + switch(result) { + case ArcsecDatalinkLayer::DEC_IN_PROGRESS: { + remainingSize = bytesLeft; + // Need a second doSendRead pass to reaa in whole packet + return IGNORE_REPLY_DATA; + } + case RETURN_OK: { + break; + } + default: + remainingSize = bytesLeft; + return result; + } + + switch (dataLinkLayer.getReplyFrameType()) { + case TMTC_ACTIONREPLY: { + *foundLen = remainingSize - bytesLeft; + result = scanForActionReply(foundId); + break; + } + case TMTC_SETPARAMREPLY: { + *foundLen = remainingSize - bytesLeft; + result = scanForParameterReply(foundId); + break; + } + case TMTC_TELEMETRYREPLYA: + case TMTC_TELEMETRYREPLY: { + *foundLen = remainingSize - bytesLeft; + result = scanForTmReply(foundId); + break; + } + default: { + sif::debug << "StarTrackerHandler::scanForReply: Reply has invalid type id" << std::endl; + result = RETURN_FAILED; + } + } + + remainingSize = bytesLeft; + + return result; +} + +ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { + + ReturnValue_t result = RETURN_OK; + + switch (id) { + case (StarTracker::SUBSCRIBE_TO_TM): { + result = handleSetParamReply(); + break; + } + case (StarTracker::REQ_TIME): { + result = handleTm(timeSet, StarTracker::TimeSet::SIZE); + break; + } + case (StarTracker::PING_REQUEST): { + result = handlePingReply(); + break; + } + case (StarTracker::BOOT): + case (StarTracker::TAKE_IMAGE): + case (StarTracker::RESET_ERROR): + case (StarTracker::UNLOCK): + case (StarTracker::SET_TIME): + case (StarTracker::FPGA_ACTION): { + result = handleActionReply(); + break; + } + case (StarTracker::DOWNLOAD_CENTROID): { + result = handleActionReplySet(downloadCentroidSet, StarTracker::DownloadCentroidSet::SIZE); + break; + } + case (StarTracker::DOWNLOAD_MATCHED_STAR): { + result = handleActionReplySet(downloadMatchedStar, StarTracker::DownloadMatchedStar::SIZE); + break; + } + case (StarTracker::DOWNLOAD_DBIMAGE): { + result = handleActionReplySet(downloadDbImage, StarTracker::DownloadDBImage::SIZE); + break; + } + case (StarTracker::DOWNLOAD_BLOBPIXEL): { + result = handleActionReplySet(downloadBlobPixel, StarTracker::DownloadBlobPixel::SIZE); + break; + } + case (StarTracker::UPLOAD_CENTROID): { + result = handleUploadCentroidReply(); + break; + } + case (StarTracker::ERASE): { + result = handleEraseReply(); + break; + } + case (StarTracker::CHECKSUM): { + result = handleChecksumReply(); + break; + } + case (StarTracker::REQ_VERSION): { + result = handleTm(versionSet, StarTracker::VersionSet::SIZE); + if (result != RETURN_OK) { + return result; + } + result = checkProgram(); + if (result != RETURN_OK) { + return result; + } + break; + } + case (StarTracker::REQ_INTERFACE): { + result = handleTm(interfaceSet, StarTracker::InterfaceSet::SIZE); + break; + } + case (StarTracker::REQ_POWER): { + result = handleTm(powerSet, StarTracker::PowerSet::SIZE); + break; + } + case (StarTracker::REQ_SOLUTION): { + result = handleTm(solutionSet, StarTracker::SolutionSet::SIZE); + break; + } + case (StarTracker::REQ_TEMPERATURE): { + result = handleTm(temperatureSet, StarTracker::TemperatureSet::SIZE); + break; + } + case (StarTracker::REQ_HISTOGRAM): { + result = handleTm(histogramSet, StarTracker::HistogramSet::SIZE); + break; + } + case (StarTracker::REQ_CONTRAST): { + result = handleTm(contrastSet, StarTracker::ContrastSet::SIZE); + break; + } + case (StarTracker::LIMITS): + case (StarTracker::MOUNTING): + case (StarTracker::CAMERA): + case (StarTracker::BLOB): + case (StarTracker::CENTROIDING): + case (StarTracker::LISA): + case (StarTracker::MATCHING): + case (StarTracker::TRACKING): + case (StarTracker::VALIDATION): + case (StarTracker::ALGO): { + result = handleSetParamReply(); + break; + } + default: { + sif::debug << "StarTrackerHandler::interpretDeviceReply: Unknown device reply id:" << id + << std::endl; + result = DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; + } + } + + return result; +} + + +void StarTrackerHandler::setNormalDatapoolEntriesInvalid() { + +} + +uint32_t StarTrackerHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { + return 20000; +} + +ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) { + + localDataPoolMap.emplace(StarTracker::TICKS_TIME_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_TIME_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::RUN_TIME, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::UNIX_TIME, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::TICKS_VERSION_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_VERSION_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::PROGRAM, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MAJOR, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MINOR, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::TICKS_INTERFACE_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_INTERFACE_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FRAME_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CHECKSUM_ERROR_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::SET_PARAM_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::SET_PARAM_REPLY_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::PARAM_REQUEST_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::PARAM_REPLY_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::REQ_TM_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TM_REPLY_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::ACTION_REQ_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::ACTION_REPLY_COUNT, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::TICKS_POWER_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_POWER_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MCU_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MCU_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_CORE_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_CORE_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_18_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_18_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_25_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::FPGA_25_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_21_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_21_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_PIX_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_PIX_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_33_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_33_VOLTAGE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_RES_CURRENT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMV_RES_VOLTAGE, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::TICKS_TEMPERATURE_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_TEMPERATURE_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MCU_TEMPERATURE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CMOS_TEMPERATURE, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::TICKS_SOLUTION_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_SOLUTION_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CALI_QW, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CALI_QX, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CALI_QY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CALI_QZ, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_CONFIDENCE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_QW, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_QX, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_QY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_QZ, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRACK_REMOVED, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::STARS_CENTROIDED, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::STARS_MATCHED_DATABASE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_QW, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_QX, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_QY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_QZ, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_PERC_CLOSE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::LISA_NR_CLOSE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TRUST_WORTHY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::STABLE_COUNT, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::SOLUTION_STRATEGY, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::TICKS_HISTOGRAM_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_HISTOGRAM_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA5, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA6, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA7, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINA8, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB5, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB6, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB7, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINB8, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC5, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC6, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC7, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BINC8, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND5, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND6, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND7, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::HISTOGRAM_BIND8, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::TICKS_CONTRAST_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::TIME_CONTRAST_SET, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINA0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINA1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINA2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINA3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINA4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINA5, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINA6, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINA7, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINA8, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINB0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINB1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINB2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINB3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINB4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINB5, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINB6, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINB7, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINB8, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINC8, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINC0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINC1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINC2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINC3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINC4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINC5, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINC6, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINC7, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BINC8, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BIND0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BIND1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BIND2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BIND3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BIND4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BIND5, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BIND6, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BIND7, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CONTRAST_BIND8, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::CHKSUM, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::DWL_ID, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::DWL_PIXX, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::DWL_PIXY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::DWL_X_UNCORRECTED, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::DWL_Y_UNCORRECTED, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::DWL_X_CORRECTED, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::DWL_Y_CORRECTED, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::DWL_MAGNITUDE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::DWL_CXA, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::DWL_CYA, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::DWL_QUALITY, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_ID, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMFPX, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMFPY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMCARTX, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMCARTY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMCARTZ, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CAMMAGNITUDE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBFPX, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBFPY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBCARTX, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBCARTY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBCARTZ, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_DBMAGNITUDE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::MATCHEDSTR_CATALOGID, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(StarTracker::BLOBPIX_ID, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::BLOBPIX_X, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::BLOBPIX_Y, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::BLOBPIX_TOT_VAL, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::BLOBPIX_IN_USE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::BLOBPIX_BRIGHT_NEIGHBOURS, new PoolEntry( { 0 })); + localDataPoolMap.emplace(StarTracker::BLOBPIX_REGION, new PoolEntry( { 0 })); + return RETURN_OK; +} + +size_t StarTrackerHandler::getNextReplyLength(DeviceCommandId_t commandId){ + return StarTracker::MAX_FRAME_SIZE; +} + +ReturnValue_t StarTrackerHandler::doSendReadHook() { + // Prevent DHB from polling UART during commands executed by the image loader task + if(strHelperExecuting) { + return RETURN_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::checkMode(ActionId_t actionId) { + switch(actionId) { + case StarTracker::UPLOAD_IMAGE: + case StarTracker::DOWNLOAD_IMAGE: { + return DeviceHandlerBase::acceptExternalDeviceCommands(); + default: + break; + } + } + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId) { + const uint8_t* reply = dataLinkLayer.getReply(); + switch (*reply) { + case (StarTracker::ID::PING): { + *foundId = StarTracker::PING_REQUEST; + break; + } + case (StarTracker::ID::WRITE): { + *foundId = StarTracker::WRITE; + break; + } + case (StarTracker::ID::BOOT): { + *foundId = StarTracker::BOOT; + break; + } + case (StarTracker::ID::TAKE_IMAGE): { + *foundId = StarTracker::TAKE_IMAGE; + break; + } + case (StarTracker::ID::UPLOAD_IMAGE): { + *foundId = StarTracker::UPLOAD_IMAGE; + break; + } + case (StarTracker::ID::ERROR_RESET): { + *foundId = StarTracker::RESET_ERROR; + break; + } + case (StarTracker::ID::ERASE): { + *foundId = StarTracker::ERASE; + break; + } + case (StarTracker::ID::UNLOCK): { + *foundId = StarTracker::UNLOCK; + break; + } + case (StarTracker::ID::CHECKSUM): { + *foundId = StarTracker::CHECKSUM; + break; + } + case (StarTracker::ID::SET_TIME): { + *foundId = StarTracker::SET_TIME; + break; + } + case (StarTracker::ID::DOWNLOAD_CENTROID): { + *foundId = StarTracker::DOWNLOAD_CENTROID; + break; + } + case (StarTracker::ID::UPLOAD_CENTROID): { + *foundId = StarTracker::UPLOAD_CENTROID; + break; + } + case (StarTracker::ID::DOWNLOAD_MATCHED_STAR): { + *foundId = StarTracker::DOWNLOAD_MATCHED_STAR; + break; + } + case (StarTracker::ID::DOWNLOAD_DBIMAGE): { + *foundId = StarTracker::DOWNLOAD_DBIMAGE; + break; + } + case (StarTracker::ID::DOWNLOAD_BLOBPIXEL): { + *foundId = StarTracker::DOWNLOAD_BLOBPIXEL; + break; + } + case (StarTracker::ID::FPGA_ACTION): { + *foundId = StarTracker::FPGA_ACTION; + break; + } + default: + sif::warning << "StarTrackerHandler::scanForParameterReply: Unknown parameter reply id" + << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::scanForParameterReply(DeviceCommandId_t *foundId) { + const uint8_t* reply = dataLinkLayer.getReply(); + switch (*reply) { + case (StarTracker::ID::SUBSCRIBE): { + *foundId = StarTracker::SUBSCRIBE_TO_TM; + break; + } + case (StarTracker::ID::LIMITS): { + *foundId = StarTracker::LIMITS; + break; + } + case (StarTracker::ID::MOUNTING): { + *foundId = StarTracker::MOUNTING; + break; + } + case (StarTracker::ID::CAMERA): { + *foundId = StarTracker::CAMERA; + break; + } + case (StarTracker::ID::BLOB): { + *foundId = StarTracker::BLOB; + break; + } + case (StarTracker::ID::CENTROIDING): { + *foundId = StarTracker::CENTROIDING; + break; + } + case (StarTracker::ID::LISA): { + *foundId = StarTracker::LISA; + break; + } + case (StarTracker::ID::MATCHING): { + *foundId = StarTracker::MATCHING; + break; + } + case (StarTracker::ID::TRACKING): { + *foundId = StarTracker::TRACKING; + break; + } + case (StarTracker::ID::VALIDATION): { + *foundId = StarTracker::VALIDATION; + break; + } + case (StarTracker::ID::ALGO): { + *foundId = StarTracker::ALGO; + break; + } + default: + sif::debug << "StarTrackerHandler::scanForParameterReply: Unknown parameter reply id" + << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::scanForTmReply(DeviceCommandId_t *foundId) { + const uint8_t* reply = dataLinkLayer.getReply(); + switch (*reply) { + case (StarTracker::ID::VERSION): { + *foundId = StarTracker::REQ_VERSION; + break; + } + case (StarTracker::ID::INTERFACE): { + *foundId = StarTracker::REQ_INTERFACE; + break; + } + case (StarTracker::ID::POWER): { + *foundId = StarTracker::REQ_POWER; + break; + } + case (StarTracker::ID::TEMPERATURE): { + *foundId = StarTracker::REQ_TEMPERATURE; + break; + } + case (StarTracker::ID::HISTOGRAM): { + *foundId = StarTracker::REQ_HISTOGRAM; + break; + } + case (StarTracker::ID::CONTRAST): { + *foundId = StarTracker::REQ_CONTRAST; + break; + } + case (StarTracker::ID::TIME): { + *foundId = StarTracker::REQ_TIME; + break; + } + case (StarTracker::ID::SOLUTION): { + *foundId = StarTracker::REQ_SOLUTION; + break; + } + default: { + sif::debug << "StarTrackerHandler::scanForTmReply: Reply contains invalid reply id" + << std::endl; + return RETURN_FAILED; + break; + } + } + return RETURN_OK; +} + +void StarTrackerHandler::handleEvent(EventMessage* eventMessage) { + object_id_t objectId = eventMessage->getReporter(); + switch(objectId){ + case objects::STR_HELPER: { + // All events from image loader signal either that the operation was successful or that it + // failed + strHelperExecuting = false; + break; + } + default: + sif::debug << "StarTrackerHandler::handleEvent: Did not subscribe to this event" + << std::endl; + break; + } +} + +ReturnValue_t StarTrackerHandler::executeWriteCommand(const uint8_t* commandData, + size_t commandDataLen) { + ReturnValue_t result = RETURN_OK; + if (commandDataLen < WriteCmd::MIN_LENGTH) { + sif::warning << "StarTrackerHandler::executeWriteCommand: Command too short" << std::endl; + return COMMAND_TOO_SHORT; + } + uint8_t region = *(commandData); + uint32_t address; + size_t size = sizeof(address); + const uint8_t* addressPtr = commandData + WriteCmd::ADDRESS_OFFSET; + result = SerializeAdapter::deSerialize(&address, addressPtr, &size, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + sif::debug << "StarTrackerHandler::executeWriteCommand: Deserialization of address failed" + << std::endl; + return result; + } + if (commandDataLen - sizeof(address) - sizeof(region) > MAX_PATH_SIZE) { + sif::warning << "StarTrackerHandler::executeWriteCommand: Received command with invalid" + << " path and filename" << std::endl; + return FILE_PATH_TOO_LONG; + } + const uint8_t* filePtr = commandData + WriteCmd::FILE_OFFSET; + std::string fullname = std::string(reinterpret_cast(filePtr), + commandDataLen - sizeof(address) - sizeof(region)); + result = strHelper->startFlashWrite(fullname, region, address); + if (result != RETURN_OK) { + return result; + } + return result; +} + +ReturnValue_t StarTrackerHandler::executeFpgaDownloadCommand(const uint8_t* commandData, + size_t commandDataLen) { + ReturnValue_t result = RETURN_OK; + if (commandDataLen < FpgaDownloadCmd::MIN_LENGTH) { + sif::warning << "StarTrackerHandler::executeFpgaDownloadCommand: Command too short" + << std::endl; + return COMMAND_TOO_SHORT; + } + uint32_t position; + size_t size = sizeof(position); + result = SerializeAdapter::deSerialize(&position, &commandData, &size, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + sif::debug << "StarTrackerHandler::executeWriteCommand: Deserialization of position failed" + << std::endl; + return result; + } + uint32_t length; + size = sizeof(length); + result = SerializeAdapter::deSerialize(&length, &commandData, &size, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + sif::debug << "StarTrackerHandler::executeWriteCommand: Deserialization of length failed" + << std::endl; + return result; + } + if (commandDataLen - sizeof(position) - sizeof(length) > MAX_PATH_SIZE) { + sif::warning << "StarTrackerHandler::executeFpgaDownloadCommand: Received command with " + " invalid path and filename" << std::endl; + return FILE_PATH_TOO_LONG; + } + std::string fullname = std::string(reinterpret_cast(commandData), + commandDataLen - sizeof(position) - sizeof(length)); + result = strHelper->startFpgaDownload(fullname, position, length); + if (result != RETURN_OK) { + return result; + } + return result; +} + +ReturnValue_t StarTrackerHandler::executeReadCommand(const uint8_t* commandData, + size_t commandDataLen) { + ReturnValue_t result = RETURN_OK; + if (commandDataLen < ReadCmd::MIN_LENGTH) { + sif::warning << "StarTrackerHandler::executeReadCommand: Command too short" << std::endl; + return COMMAND_TOO_SHORT; + } + uint8_t region = *(commandData); + uint32_t address; + size_t size = sizeof(address); + const uint8_t* addressPtr = commandData + ReadCmd::ADDRESS_OFFSET; + result = SerializeAdapter::deSerialize(&address, addressPtr, &size, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + sif::debug << "StarTrackerHandler::executeReadCommand: Deserialization of address failed" + << std::endl; + return result; + } + uint32_t length; + size = sizeof(length); + const uint8_t* lengthPtr = commandData + ReadCmd::LENGTH_OFFSET; + result = SerializeAdapter::deSerialize(&length, lengthPtr, &size, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + sif::debug << "StarTrackerHandler::executeReadCommand: Deserialization of length failed" + << std::endl; + return result; + } + if (commandDataLen - sizeof(address) - sizeof(region) - sizeof(length) > MAX_PATH_SIZE) { + sif::warning << "StarTrackerHandler::executeReadCommand: Received command with invalid" + << " path and filename" << std::endl; + return FILE_PATH_TOO_LONG; + } + const uint8_t* filePtr = commandData + ReadCmd::FILE_OFFSET; + std::string fullname = std::string(reinterpret_cast(filePtr), + commandDataLen - sizeof(address) - sizeof(region) - sizeof(length)); + result = strHelper->startFlashRead(fullname, region, address, length); + if (result != RETURN_OK) { + return result; + } + return result; +} + +void StarTrackerHandler::prepareBootCommand() { + uint32_t length = 0; + struct BootActionRequest bootRequest = {BOOT_REGION_ID}; + arc_pack_boot_action_req(&bootRequest, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +ReturnValue_t StarTrackerHandler::prepareEraseCommand(const uint8_t* commandData, + size_t commandDataLen) { + ReturnValue_t result = RETURN_OK; + if (commandDataLen != EraseCmd::LENGTH) { + return INVALID_LENGTH; + } + uint32_t length = 0; + struct EraseActionRequest req; + req.region = *commandData; + arc_pack_erase_action_req(&req, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + eraseCmd.rememberRegion = req.region; + return result; +} + +ReturnValue_t StarTrackerHandler::prepareUnlockCommand(const uint8_t* commandData, + size_t commandDataLen) { + ReturnValue_t result = RETURN_OK; + uint32_t length = 0; + struct UnlockActionRequest req; + req.region = *commandData; + size_t size = sizeof(req.code); + const uint8_t* codePtr = commandData + UnlockCmd::CODE_OFFSET; + result = SerializeAdapter::deSerialize(&req.code, &codePtr, &size, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + return result; + } + arc_pack_unlock_action_req(&req, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + return result; +} + +ReturnValue_t StarTrackerHandler::prepareChecksumCommand(const uint8_t* commandData, + size_t commandDataLen) { + struct ChecksumActionRequest req; + ReturnValue_t result = RETURN_OK; + if (commandDataLen != ChecksumCmd::LENGTH) { + sif::warning << "StarTrackerHandler::prepareChecksumCommand: Invalid length" << std::endl; + return INVALID_LENGTH; + } + req.region = *(commandData); + size_t size = sizeof(req.address); + const uint8_t* addressPtr = commandData + ChecksumCmd::ADDRESS_OFFSET; + result = SerializeAdapter::deSerialize(&req.address, addressPtr, &size, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + sif::debug << "StarTrackerHandler::prepareChecksumCommand: Deserialization of address " + << "failed" << std::endl; + return result; + } + size = sizeof(req.length); + const uint8_t* lengthPtr = commandData + ChecksumCmd::LENGTH_OFFSET; + result = SerializeAdapter::deSerialize(&req.length, lengthPtr, &size, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + sif::debug << "StarTrackerHandler::prepareChecksumCommand: Deserialization of length failed" + << std::endl; + return result; + } + uint32_t rawCmdLength = 0; + arc_pack_checksum_action_req(&req, commandBuffer, &rawCmdLength); + dataLinkLayer.encodeFrame(commandBuffer, rawCmdLength); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + checksumCmd.rememberRegion = req.region; + checksumCmd.rememberAddress = req.address; + checksumCmd.rememberLength = req.length; + return result; +} + + +ReturnValue_t StarTrackerHandler::prepareSetTimeCommand(const uint8_t* commandData, + size_t commandDataLen) { + ReturnValue_t result = RETURN_OK; + struct SetTimeActionRequest req; + if (commandDataLen != SetTimeCmd::LENGTH) { + sif::warning << "StarTrackerHandler::prepareSetTimeCommand: Invalid length" << std::endl; + return INVALID_LENGTH; + } + size_t size = sizeof(req.unixTime); + result = SerializeAdapter::deSerialize(&req.unixTime, commandData, &size, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + sif::debug << "StarTrackerHandler::prepareSetTimeCommand: Deserialization failed" + << std::endl; + return result; + } + uint32_t length = 0; + arc_pack_settime_action_req(&req, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + return result; +} + +ReturnValue_t StarTrackerHandler::prepareDownloadCentroidCommand(const uint8_t* commandData, + size_t commandDataLen) { + ReturnValue_t result = RETURN_OK; + struct DownloadCentroidActionRequest req; + if (commandDataLen != DownloadCentroidCmd::LENGTH) { + sif::warning << "StarTrackerHandler::prepareDownloadCentroidCommand: Invalid length" + << std::endl; + return INVALID_LENGTH; + } + req.id = *commandData; + uint32_t length = 0; + arc_pack_downloadcentroid_action_req(&req, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + return result; +} + +ReturnValue_t StarTrackerHandler::prepareUploadCentroidCommand(const uint8_t* commandData, + size_t commandDataLen) { + if (commandDataLen > MAX_PATH_SIZE) { + return FILE_PATH_TOO_LONG; + } + ReturnValue_t result = RETURN_OK; + struct UploadCentroidActionRequest req; + std::string jsonFileName = std::string(reinterpret_cast(commandData), + commandDataLen); + NVMParameterBase j(jsonFileName); + result = j.readJsonFile(); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: " << jsonFileName + << " does not exist" << std::endl; + return result; + } + result = j.getValue(StarTracker::UploadCentroidKeys::id, &req.id); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " + << StarTracker::UploadCentroidKeys::id << " does not exist" << std::endl; + return result; + } + result = j.getValue(StarTracker::UploadCentroidKeys::pixx, &req.pixx); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " + << StarTracker::UploadCentroidKeys::pixx << " does not exist" << std::endl; + return result; + } + result = j.getValue(StarTracker::UploadCentroidKeys::pixy, &req.pixy); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " + << StarTracker::UploadCentroidKeys::pixy << " does not exist" << std::endl; + return result; + } + result = j.getValue(StarTracker::UploadCentroidKeys::x_uncorrected, &req.x_uncorrected); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " + << StarTracker::UploadCentroidKeys::x_uncorrected << " does not exist" << std::endl; + return result; + } + result = j.getValue(StarTracker::UploadCentroidKeys::y_uncorrected, &req.y_uncorrected); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " + << StarTracker::UploadCentroidKeys::y_uncorrected << " does not exist" << std::endl; + return result; + } + result = j.getValue(StarTracker::UploadCentroidKeys::x_corrected, &req.x_corrected); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " + << StarTracker::UploadCentroidKeys::x_corrected << " does not exist" << std::endl; + return result; + } + result = j.getValue(StarTracker::UploadCentroidKeys::y_corrected, &req.y_corrected); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " + << StarTracker::UploadCentroidKeys::y_corrected << " does not exist" << std::endl; + return result; + } + result = j.getValue(StarTracker::UploadCentroidKeys::magnitude, &req.magnitude); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " + << StarTracker::UploadCentroidKeys::magnitude << " does not exist" << std::endl; + return result; + } + result = j.getValue(StarTracker::UploadCentroidKeys::cxa, &req.cxa); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " + << StarTracker::UploadCentroidKeys::cxa << " does not exist" << std::endl; + return result; + } + result = j.getValue(StarTracker::UploadCentroidKeys::cya, &req.cya); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " + << StarTracker::UploadCentroidKeys::cya << " does not exist" << std::endl; + return result; + } + result = j.getValue(StarTracker::UploadCentroidKeys::quality, &req.quality); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareUploadCentroidCommand: The key " + << StarTracker::UploadCentroidKeys::quality << " does not exist" << std::endl; + return result; + } + uint32_t length = 0; + arc_pack_uploadcentroid_action_req(&req, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + uploadCentroid.rememberId = req.id; + return result; +} + +void StarTrackerHandler::prepareTimeRequest() { + uint32_t length = 0; + arc_tm_pack_time_req(commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::preparePingRequest() { + uint32_t length = 0; + struct PingActionRequest pingRequest = {PING_ID}; + arc_pack_ping_action_req(&pingRequest, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::prepareVersionRequest() { + uint32_t length = 0; + arc_tm_pack_version_req(commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::prepareInterfaceRequest() { + uint32_t length = 0; + arc_tm_pack_interface_req(commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::preparePowerRequest() { + uint32_t length = 0; + arc_tm_pack_power_req(commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::prepareRebootCommand() { + uint32_t length = 0; + struct RebootActionRequest rebootReq; + arc_pack_reboot_action_req(&rebootReq, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::prepareTakeImageCommand(const uint8_t* commandData) { + uint32_t length = 0; + struct CameraActionRequest camReq; + camReq.actionid = *commandData; + arc_pack_camera_action_req(&camReq, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::prepareSubscriptionCommand(const uint8_t* tmId) { + uint32_t length = 18; + commandBuffer[0] = TMTC_SETPARAMREQ; + commandBuffer[1] = StarTracker::ID::SUBSCRIBE; + // Fill all other fields with invalid tm id + commandBuffer[2] = *tmId; + commandBuffer[3] = 0; + commandBuffer[4] = 0; + commandBuffer[5] = 0; + commandBuffer[6] = 0; + commandBuffer[7] = 0; + commandBuffer[8] = 0; + commandBuffer[9] = 0; + commandBuffer[10] = 0; + commandBuffer[11] = 0; + commandBuffer[12] = 0; + commandBuffer[13] = 0; + commandBuffer[14] = 0; + commandBuffer[15] = 0; + commandBuffer[16] = 0; + commandBuffer[17] = 0; + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::prepareSolutionRequest() { + uint32_t length = 0; + arc_tm_pack_solution_req(commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::prepareTemperatureRequest() { + uint32_t length = 0; + arc_tm_pack_temperature_req(commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::prepareHistogramRequest() { + uint32_t length = 0; + arc_tm_pack_histogram_req(commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::prepareContrastRequest() { + uint32_t length = 0; + arc_tm_pack_contrast_req(commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +void StarTrackerHandler::prepareErrorResetRequest() { + uint32_t length = 0; + struct ResetErrorSignalActionRequest req; + arc_pack_reseterrorsignal_action_req(&req, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); +} + +ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData, + size_t commandDataLen, ArcsecJsonParamBase& paramSet) { + ReturnValue_t result = RETURN_OK; + if (commandDataLen > MAX_PATH_SIZE) { + return FILE_PATH_TOO_LONG; + } + std::string fullName(reinterpret_cast(commandData), commandDataLen); + + result = paramSet.create(fullName, commandBuffer); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::prepareParamCommand: Failed to create parameter " + "command" << std::endl; + return result; + } + dataLinkLayer.encodeFrame(commandBuffer, paramSet.getSize()); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::prepareDownloadMatchedStarCommand(const uint8_t* commandData, + size_t commandDataLen) { + if (commandDataLen != DownloadMatchedStarCmd::LENGTH) { + return INVALID_LENGTH; + } + struct DownloadMatchedStarActionRequest req; + req.id = *commandData; + uint32_t length = 0; + arc_pack_downloadmatchedstar_action_req(&req, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::prepareDownloadDbImageCommand(const uint8_t* commandData, + size_t commandDataLen) { + if (commandDataLen != DownloadDbImageCmd::LENGTH) { + return INVALID_LENGTH; + } + struct DownloadDBImageActionRequest req; + req.id = *commandData; + uint32_t length = 0; + arc_pack_downloaddbimage_action_req(&req, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::prepareDownloadBlobPixelCommand(const uint8_t* commandData, + size_t commandDataLen) { + if (commandDataLen != DownloadBlobPixCmd::LENGTH) { + return INVALID_LENGTH; + } + struct DownloadBlobPixelActionRequest req; + req.id = *commandData; + req.type = *(commandData + 1); + if ((req.type != DownloadBlobPixCmd::NORMAL) && (req.type != DownloadBlobPixCmd::FAST)) { + return INVALID_TYPE; + } + uint32_t length = 0; + arc_pack_downloadblobpixel_action_req(&req, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::prepareFpgaActionCommand(const uint8_t* commandData, + size_t commandDataLen) { + if (commandDataLen != FpgaActionCmd::LENGTH) { + return INVALID_LENGTH; + } + struct FPGAActionActionRequest req; + req.id = *commandData; + if (req.id != FpgaActionCmd::ID) { + return INVALID_ID; + } + uint32_t length = 0; + arc_pack_fpgaaction_action_req(&req, commandBuffer, &length); + dataLinkLayer.encodeFrame(commandBuffer, length); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::handleSetParamReply() { + const uint8_t* reply = dataLinkLayer.getReply(); + uint8_t status = *(reply + STATUS_OFFSET); + if (status != StarTracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handleSetParamReply: Failed to execute parameter set " + " command with parameter ID" << + static_cast(*(reply + PARAMETER_ID_OFFSET)) << std::endl; + if (startupState != StartupState::IDLE) { + startupState = StartupState::IDLE; + } + return SET_PARAM_FAILED; + } + if (startupState != StartupState::IDLE) { + handleStartup(reply + PARAMETER_ID_OFFSET); + } + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::handleActionReply() { + const uint8_t* reply = dataLinkLayer.getReply(); + uint8_t status = *(reply + STATUS_OFFSET); + if (status != StarTracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handleActionReply: Failed to execute action " + << "command with action ID " + << static_cast(*(reply + ACTION_ID_OFFSET)) + << " and status "<< static_cast(status) << std::endl; + return ACTION_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::handleUploadCentroidReply() { + ReturnValue_t result = RETURN_OK; + result = handleActionReply(); + if (result != RETURN_OK) { + return result; + } + const uint8_t* reply = dataLinkLayer.getReply(); + if (*(reply + ACTION_DATA_OFFSET) != uploadCentroid.rememberId) { + return UPLOAD_CENTROID_ID_MISMATCH; + } + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::handleEraseReply() { + ReturnValue_t result = RETURN_OK; + result = handleActionReply(); + if (result != RETURN_OK) { + return result; + } + const uint8_t* replyData = dataLinkLayer.getReply() + ACTION_DATA_OFFSET; + StarTracker::EraseReply eraseReply(replyData); + if (eraseReply.getRegion() != eraseCmd.rememberRegion) { + sif::warning << "StarTrackerHandler::handleEraseReply: Region mismatch" << std::endl; + return REGION_MISMATCH; + } + return result; +} + +ReturnValue_t StarTrackerHandler::handleChecksumReply() { + ReturnValue_t result = RETURN_OK; + result = handleActionReply(); + if (result != RETURN_OK) { + return result; + } + const uint8_t* replyData = dataLinkLayer.getReply() + ACTION_DATA_OFFSET; + StarTracker::ChecksumReply checksumReply(replyData); + if (checksumReply.getRegion() != checksumCmd.rememberRegion) { + sif::warning << "StarTrackerHandler::handleChecksumReply: Region mismatch" << std::endl; + return REGION_MISMATCH; + } + if (checksumReply.getAddress() != checksumCmd.rememberAddress) { + sif::warning << "StarTrackerHandler::handleChecksumReply: Address mismatch" << std::endl; + return ADDRESS_MISMATCH; + } + if (checksumReply.getLength() != checksumCmd.rememberLength) { + sif::warning << "StarTrackerHandler::handleChecksumReply: Length mismatch" << std::endl; + return LENGTH_MISSMATCH; + } + PoolReadGuard rg(&checksumSet); + checksumSet.checksum = checksumReply.getChecksum(); + handleDeviceTM(&checksumSet, StarTracker::CHECKSUM); +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + checksumReply.printChecksum(); +#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::handlePingReply() { + ReturnValue_t result = RETURN_OK; + uint32_t pingId = 0; + const uint8_t* reply = dataLinkLayer.getReply(); + uint8_t status = dataLinkLayer.getStatusField(); + const uint8_t* buffer = reply + ACTION_DATA_OFFSET; + size_t size = sizeof(pingId); + SerializeAdapter::deSerialize(&pingId, &buffer, &size, SerializeIF::Endianness::LITTLE); +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + sif::info << "StarTracker: Ping status: "<< static_cast(status) << std::endl; + sif::info << "Ping id: 0x"<< std::hex << pingId << std::endl; +#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ + if (status != StarTracker::STATUS_OK || pingId != PING_ID) { + sif::warning << "StarTrackerHandler::handlePingReply: Ping failed" << std::endl; + result = PING_FAILED; + } + else { +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + sif::info << "StarTracker: Ping successful" << std::endl; +#endif + } + return result; +} + +ReturnValue_t StarTrackerHandler::checkProgram() { + PoolReadGuard pg(&versionSet); + switch(versionSet.program.value) { + case StarTracker::Program::BOOTLOADER: + // Star tracker currently in bootloader program. Need to send boot command to switch to + // firmware program + if (startupState != StartupState::IDLE) { + startupState = StartupState::BOOT; + } + break; + case StarTracker::Program::FIRMWARE: + // Firmware already booted + if (startupState != StartupState::IDLE) { + startupState = StartupState::LIMITS; + } + break; + default: + sif::warning << "StarTrackerHandler::checkProgram: Version set has invalid program ID" + << std::endl; + return INVALID_PROGRAM; + } + return RETURN_OK; +} + +ReturnValue_t StarTrackerHandler::handleTm(LocalPoolDataSetBase& dataset, size_t size) { + ReturnValue_t result = RETURN_OK; + uint8_t status = *(dataLinkLayer.getReply() + STATUS_OFFSET); + if(status != StarTracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handleTm: Reply error: " + << static_cast(status) << std::endl; + return REPLY_ERROR; + } + result = dataset.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } + const uint8_t* reply = dataLinkLayer.getReply() + TICKS_OFFSET; + dataset.setValidityBufferGeneration(false); + result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::handleTm: Deserialization failed" + << std::endl; + } + dataset.setValidityBufferGeneration(true); + dataset.setValidity(true, true); + result = dataset.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + dataset.printSet(); +#endif + return result; +} + +ReturnValue_t StarTrackerHandler::handleActionReplySet(LocalPoolDataSetBase& dataset, size_t size) { + ReturnValue_t result = RETURN_OK; + uint8_t status = *(dataLinkLayer.getReply() + STATUS_OFFSET); + if(status != StarTracker::STATUS_OK) { + sif::warning << "StarTrackerHandler::handleActionReplySet: Reply error: " + << static_cast(status) << std::endl; + return REPLY_ERROR; + } + result = dataset.read(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } + const uint8_t* reply = dataLinkLayer.getReply() + ACTION_DATA_OFFSET; + dataset.setValidityBufferGeneration(false); + result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE); + if (result != RETURN_OK) { + sif::warning << "StarTrackerHandler::handleActionReplySet Deserialization failed" + << std::endl; + } + dataset.setValidityBufferGeneration(true); + dataset.setValidity(true, true); + result = dataset.commit(TIMEOUT_TYPE, MUTEX_TIMEOUT); + if (result != RETURN_OK) { + return result; + } +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + dataset.printSet(); +#endif + return result; +} + +void StarTrackerHandler::handleStartup(const uint8_t* parameterId) { + switch(*parameterId) { + case (StarTracker::ID::LIMITS): { + startupState = StartupState::TRACKING; + break; + } + case (StarTracker::ID::TRACKING): { + startupState = StartupState::MOUNTING; + break; + } + case (StarTracker::ID::MOUNTING): { + startupState = StartupState::CAMERA; + break; + } + case (StarTracker::ID::CAMERA): { + startupState = StartupState::BLOB; + break; + } + case (StarTracker::ID::BLOB): { + startupState = StartupState::CENTROIDING; + break; + } + case (StarTracker::ID::CENTROIDING): { + startupState = StartupState::LISA; + break; + } + case (StarTracker::ID::LISA): { + startupState = StartupState::MATCHING; + break; + } + case (StarTracker::ID::MATCHING): { + startupState = StartupState::VALIDATION; + break; + } + case (StarTracker::ID::VALIDATION): { + startupState = StartupState::ALGO; + break; + } + case (StarTracker::ID::ALGO): { + startupState = StartupState::DONE; + break; + } + default: { + sif::debug << "StarTrackerHandler::handleStartup: Received parameter reply with unexpected" + << " parameter ID" << std::endl; + break; + } + } +} diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.h b/bsp_q7s/devices/startracker/StarTrackerHandler.h new file mode 100644 index 00000000..65bd65b8 --- /dev/null +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.h @@ -0,0 +1,548 @@ +#ifndef MISSION_DEVICES_STARTRACKERHANDLER_H_ +#define MISSION_DEVICES_STARTRACKERHANDLER_H_ + +#include "fsfw/devicehandlers/DeviceHandlerBase.h" +#include "fsfw/src/fsfw/serialize/SerializeAdapter.h" +#include "fsfw/timemanager/Countdown.h" +#include "thirdparty/arcsec_star_tracker/common/SLIP.h" +#include +#include "ArcsecDatalinkLayer.h" +#include "StarTrackerDefinitions.h" +#include "ArcsecJsonParamBase.h" +#include "StrHelper.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, + StrHelper* strHelper); + virtual ~StarTrackerHandler(); + + ReturnValue_t initialize() override; + + /** + * @brief Overwrite this function from DHB to handle commands executed by the str image + * loader task. + */ + ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) override; + + void performOperationHook() override; + +protected: + void doStartUp() override; + void doShutDown() override; + void doOffActivity() 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; + virtual ReturnValue_t doSendReadHook() 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(0xB1); + //! [EXPORT] : [COMMENT] Image loader executing + static const ReturnValue_t IMAGE_LOADER_EXECUTING = MAKE_RETURN_CODE(0xB2); + + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER; + + //! [EXPORT] : [COMMENT] Status in temperature reply signals error + static const ReturnValue_t TEMPERATURE_REQ_FAILED = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Ping command failed + static const ReturnValue_t PING_FAILED = MAKE_RETURN_CODE(0xA1); + //! [EXPORT] : [COMMENT] Status in version reply signals error + static const ReturnValue_t VERSION_REQ_FAILED = MAKE_RETURN_CODE(0xA3); + //! [EXPORT] : [COMMENT] Status in interface reply signals error + static const ReturnValue_t INTERFACE_REQ_FAILED = MAKE_RETURN_CODE(0xA4); + //! [EXPORT] : [COMMENT] Status in power reply signals error + static const ReturnValue_t POWER_REQ_FAILED = MAKE_RETURN_CODE(0xA5); + //! [EXPORT] : [COMMENT] Status of reply to parameter set command signals error + static const ReturnValue_t SET_PARAM_FAILED = MAKE_RETURN_CODE(0xA6); + //! [EXPORT] : [COMMENT] Status of reply to action command signals error + static const ReturnValue_t ACTION_FAILED = MAKE_RETURN_CODE(0xA7); + //! [EXPORT] : [COMMENT] Received upload image command with invalid length + static const ReturnValue_t UPLOAD_TOO_SHORT = MAKE_RETURN_CODE(0xA8); + //! [EXPORT] : [COMMENT] Received upload image command with invalid position field + static const ReturnValue_t UPLOAD_INVALID_POSITION = MAKE_RETURN_CODE(0xA8); + //! [EXPORT] : [COMMENT] Position value in upload image reply not matching sent position + static const ReturnValue_t UPLOAD_IMAGE_FAILED = MAKE_RETURN_CODE(0xA9); + //! [EXPORT] : [COMMENT] Received upload image command with invalid length + static const ReturnValue_t INVALID_UPLOAD_COMMAND = MAKE_RETURN_CODE(0xAA); + //! [EXPORT] : [COMMENT] Received invalid path string. Exceeds allowed length + static const ReturnValue_t FILE_PATH_TOO_LONG = MAKE_RETURN_CODE(0xAB); + //! [EXPORT] : [COMMENT] Name of file received with command is too long + static const ReturnValue_t FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xAC); + //! [EXPORT] : [COMMENT] Received version reply with invalid program ID + static const ReturnValue_t INVALID_PROGRAM = MAKE_RETURN_CODE(0xAD); + //! [EXPORT] : [COMMENT] Status field reply signals error + static const ReturnValue_t REPLY_ERROR = MAKE_RETURN_CODE(0xAE); + //! [EXPORT] : [COMMENT] Status field of contrast reply signals error + static const ReturnValue_t CONTRAST_REQ_FAILED = MAKE_RETURN_CODE(0xAE); + //! [EXPORT] : [COMMENT] Received command which is too short (some data is missing for proper execution) + static const ReturnValue_t COMMAND_TOO_SHORT = MAKE_RETURN_CODE(0xAF); + //! [EXPORT] : [COMMENT] Received command with invalid length (too few or too many parameters) + static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xB0); + //! [EXPORT] : [COMMENT] Region mismatch between send and received data + static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(0xB1); + //! [EXPORT] : [COMMENT] Address mismatch between send and received data + static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(0xB2); + //! [EXPORT] : [COMMENT] Length field mismatch between send and received data + static const ReturnValue_t lENGTH_MISMATCH = MAKE_RETURN_CODE(0xB3); + //! [EXPORT] : [COMMENT] Specified file does not exist + static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xB4); + //! [EXPORT] : [COMMENT] Reply to upload centroid does not match commanded centroid id + static const ReturnValue_t UPLOAD_CENTROID_ID_MISMATCH = MAKE_RETURN_CODE(0xB5); + //! [EXPORT] : [COMMENT] Download blob pixel command has invalid type field + static const ReturnValue_t INVALID_TYPE = MAKE_RETURN_CODE(0xB6); + //! [EXPORT] : [COMMENT] Received FPGA action command with invalid ID + static const ReturnValue_t INVALID_ID = MAKE_RETURN_CODE(0xB7); + + static const size_t MAX_PATH_SIZE = 50; + static const size_t MAX_FILE_NAME = 30; + + // position (uint32) + 1024 image data + static const size_t UPLOAD_COMMAND_LEN = 1028; + // Max valid position value in upload image command + static const uint16_t MAX_POSITION= 4095; + static const uint8_t STATUS_OFFSET = 1; + static const uint8_t TICKS_OFFSET = 2; + static const uint8_t TIME_OFFSET = 6; + static const uint8_t TM_DATA_FIELD_OFFSET = 14; + static const uint8_t PARAMETER_ID_OFFSET = 0; + static const uint8_t ACTION_ID_OFFSET = 0; + static const uint8_t ACTION_DATA_OFFSET = 2; + // Ping request will reply ping with this ID (data field) + static const uint32_t PING_ID = 0x55; + static const uint32_t BOOT_REGION_ID = 1; + static const MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING; + static const uint32_t MUTEX_TIMEOUT = 20; + static const uint32_t BOOT_TIMEOUT = 1000; + + class WriteCmd { + public: + static const uint8_t ADDRESS_OFFSET = 1; + static const uint8_t FILE_OFFSET = 5; + // Minimum length of a write command (region, address and filename) + static const size_t MIN_LENGTH = 7; + }; + + class ReadCmd { + public: + static const uint8_t ADDRESS_OFFSET = 1; + static const uint8_t LENGTH_OFFSET = 5; + static const uint8_t FILE_OFFSET = 9; + // Minimum length of a read command (region, address, length and filename) + static const size_t MIN_LENGTH = 11; + }; + + class EraseCmd { + public: + static const uint8_t LENGTH = 1; + uint8_t rememberRegion = 0; + }; + + EraseCmd eraseCmd; + + class UnlockCmd { + public: + static const uint8_t CODE_OFFSET = 1; + }; + + class ChecksumCmd { + public: + static const uint8_t ADDRESS_OFFSET = 1; + static const uint8_t LENGTH_OFFSET = 5; + // Length of checksum command + static const size_t LENGTH = 9; + uint8_t rememberRegion = 0; + uint32_t rememberAddress = 0; + uint32_t rememberLength = 0; + }; + + ChecksumCmd checksumCmd; + + class SetTimeCmd { + public: + static const uint8_t LENGTH = 8; + }; + + class DownloadCentroidCmd { + public: + static const uint8_t LENGTH = 1; + }; + + class UploadCentroid { + public: + uint8_t rememberId = 0; + }; + + UploadCentroid uploadCentroid; + + class DownloadMatchedStarCmd { + public: + static const uint8_t LENGTH = 1; + }; + + class DownloadDbImageCmd { + public: + static const uint8_t LENGTH = 1; + }; + + class DownloadBlobPixCmd { + public: + static const uint8_t LENGTH = 2; + static const uint8_t NORMAL = 0; + static const uint8_t FAST = 1; + }; + + class FpgaDownloadCmd { + public: + static const uint8_t MIN_LENGTH = 10; + }; + + class FpgaActionCmd { + public: + static const uint8_t LENGTH = 1; + static const uint8_t ID = 3; + }; + + MessageQueueIF* eventQueue = nullptr; + + ArcsecDatalinkLayer dataLinkLayer; + + StarTracker::TemperatureSet temperatureSet; + StarTracker::VersionSet versionSet; + StarTracker::PowerSet powerSet; + StarTracker::InterfaceSet interfaceSet; + StarTracker::TimeSet timeSet; + StarTracker::SolutionSet solutionSet; + StarTracker::HistogramSet histogramSet; + StarTracker::ContrastSet contrastSet; + StarTracker::ChecksumSet checksumSet; + StarTracker::DownloadCentroidSet downloadCentroidSet; + StarTracker::DownloadMatchedStar downloadMatchedStar; + StarTracker::DownloadDBImage downloadDbImage; + StarTracker::DownloadBlobPixel downloadBlobPixel; + + // Pointer to object responsible for uploading and downloading images to/from the star tracker + StrHelper* strHelper = nullptr; + + uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; + + // Countdown to insert delay for star tracker to switch from bootloader to firmware program + Countdown bootCountdown; + + std::string paramJsonFile = "/mnt/sd0/startracker/full.json"; + + enum class InternalState { + TEMPERATURE_REQUEST + }; + + InternalState internalState = InternalState::TEMPERATURE_REQUEST; + + enum class StartupState { + IDLE, + CHECK_BOOT_STATE, + BOOT, + BOOT_DELAY, + LIMITS, + TRACKING, + MOUNTING, + CAMERA, + BLOB, + CENTROIDING, + LISA, + MATCHING, + VALIDATION, + ALGO, + WAIT_FOR_EXECUTION, + DONE + }; + + StartupState startupState = StartupState::IDLE; + + bool strHelperExecuting = false; + + /** + * @brief Handles internal state + */ + void handleInternalState(); + + /** + * @brief Checks mode for commands requiring MODE_ON of MODE_NORMAL for execution. + * + * @param actionId Action id of command to execute + */ + ReturnValue_t checkMode(ActionId_t actionId); + + /** + * @brief This function initializes the serial link ip protocol struct slipInfo. + */ + void slipInit(); + + ReturnValue_t scanForActionReply(DeviceCommandId_t *foundId); + ReturnValue_t scanForParameterReply(DeviceCommandId_t *foundId); + ReturnValue_t scanForTmReply(DeviceCommandId_t *foundId); + + /** + * @brief Fills command buffer with data to ping the star tracker + */ + void preparePingRequest(); + + /** + * @brief Fills command buffer with data to request the time telemetry. + */ + void prepareTimeRequest(); + + /** + * @brief Handles all received event messages + */ + void handleEvent(EventMessage* eventMessage); + + /** + * @brief Executes the write command + * + * @param commandData Pointer to received command data + * @param commandDataLen Size of received command data + * + * @return RETURN_OK if start of execution was successful, otherwise error return value + */ + ReturnValue_t executeWriteCommand(const uint8_t* commandData, size_t commandDataLen); + + /** + * @brief Starts the execution of the fpga download command + * + * @param commandData Pointer to buffer with command data + * @param commandDataLen Size of received command + */ + ReturnValue_t executeFpgaDownloadCommand(const uint8_t* commandData, size_t commandDataLen); + + /** + * @brief Extracts information for flash-read-command from TC data and starts execution of + * flash-read-procedure + * + * @param commandData Pointer to received command data + * @param commandDataLen Size of received command data + * + * @return RETURN_OK if start of execution was successful, otherwise error return value + */ + ReturnValue_t executeReadCommand(const uint8_t* commandData, size_t commandDataLen); + + /** + * @brief Fills command buffer with data to boot image (works only when star tracker is + * in bootloader mode). + */ + void prepareBootCommand(); + + /** + * @brief Fills command buffer with command to erase a flash region + */ + ReturnValue_t prepareEraseCommand(const uint8_t* commandData, size_t commandDataLen); + + /** + * @brief Fills command buffer with command to unlock flash region + */ + ReturnValue_t prepareUnlockCommand(const uint8_t* commandData, size_t commandDataLen); + + /** + * @brief Fills command buffer with command to get the checksum of a flash part + */ + ReturnValue_t prepareChecksumCommand(const uint8_t* commandData, size_t commandDataLen); + + /** + * @brief Fills command buffer with command to set the unix time + */ + ReturnValue_t prepareSetTimeCommand(const uint8_t* commandData, size_t commandDataLen); + + /** + * @brief Fills command buffer with command to request a centroid + */ + ReturnValue_t prepareDownloadCentroidCommand(const uint8_t* commandData, size_t commandDataLen); + + /** + * @brief Fills command buffer with command to upload a centroid for testing purpose + */ + ReturnValue_t prepareUploadCentroidCommand(const uint8_t* commandData, size_t commandDataLen); + + /** + * @brief Fills the command buffer with the command to take an image. + */ + void prepareTakeImageCommand(const uint8_t* commandData); + + /** + * @brief Fills command buffer with data to request the version telemetry packet + */ + void prepareVersionRequest(); + + /** + * @brief Fills the command buffer with data to request the interface telemetry packet. + */ + void prepareInterfaceRequest(); + + /** + * @brief Fills the command buffer with data to request the power telemetry packet. + */ + void preparePowerRequest(); + + /** + * @brief Fills command buffer with data to reboot star tracker. + */ + void prepareRebootCommand(); + + /** + * @brief Fills command buffer with data to subscribe to a telemetry packet. + * + * @param tmId The ID of the telemetry packet to subscribe to + */ + void prepareSubscriptionCommand(const uint8_t* tmId); + + /** + * @brief Fills command buffer with data to request solution telemtry packet (contains + * attitude information) + */ + void prepareSolutionRequest(); + + /** + * @brief Fills command buffer with data to request temperature from star tracker + */ + void prepareTemperatureRequest(); + + /** + * @brief Fills command buffer with data to request histogram + */ + void prepareHistogramRequest(); + + void prepareContrastRequest(); + + /** + * @brief Fills command buffer with command to reset the error signal of the star tracker + */ + void prepareErrorResetRequest(); + + /** + * @brief Reads parameters from json file specified by string in commandData and + * prepares the command to apply the parameter set to the star tracker + * + * @param commandData Contains string with file name + * @param commandDataLen Length of command + * @param paramSet The object defining the command generation + * + * @return RETURN_OK if successful, otherwise error return Value + */ + ReturnValue_t prepareParamCommand(const uint8_t* commandData, size_t commandDataLen, + ArcsecJsonParamBase& paramSet); + + /** + * @brief Fills command buffer with data to request matched star. + */ + ReturnValue_t prepareDownloadMatchedStarCommand(const uint8_t* commandData, + size_t commandDataLen); + + /** + * @brief Fills command buffer with data to request matched star coordinates. + */ + ReturnValue_t prepareDownloadDbImageCommand(const uint8_t* commandData, + size_t commandDataLen); + + /** + * @brief Fills command buffer with data to request output of the blob filter algorithm. + */ + ReturnValue_t prepareDownloadBlobPixelCommand(const uint8_t* commandData, + size_t commandDataLen); + + /** + * @brief With this command the FPGA update will be applied to the star tracker + */ + ReturnValue_t prepareFpgaActionCommand(const uint8_t* commandData, size_t commandDataLen); + + /** + * @brief Handles action replies with datasets. + */ + ReturnValue_t handleActionReplySet(LocalPoolDataSetBase& dataset, size_t size); + + /** + * @brief Default function to handle action replies + */ + ReturnValue_t handleActionReply(); + + /** + * @brief Handles reply to upload centroid command + */ + ReturnValue_t handleUploadCentroidReply(); + + /** + * @brief Handles reply to erase command + */ + ReturnValue_t handleEraseReply(); + + /** + * @brief Handles reply to checksum command + */ + ReturnValue_t handleChecksumReply(); + + /** + * @brief Handles all set parameter replies + */ + ReturnValue_t handleSetParamReply(); + + ReturnValue_t handlePingReply(); + + /** + * @brief Checks the loaded program by means of the version set + */ + ReturnValue_t checkProgram(); + + /** + * @brief Handles the startup state machine + */ + void handleStartup(const uint8_t* parameterId); + + /** + * @brief Handles telemtry replies and fills the appropriate dataset + * + * @param dataset Dataset where reply data will be written to + * @param size Size of the dataset + * + * @return RETURN_OK if successful, otherwise error return value + */ + ReturnValue_t handleTm(LocalPoolDataSetBase& dataset, size_t size); +}; + +#endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */ diff --git a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp new file mode 100644 index 00000000..9c33e1c9 --- /dev/null +++ b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.cpp @@ -0,0 +1,716 @@ +#include "StarTrackerJsonCommands.h" +#include "ArcsecJsonKeys.h" + +Limits::Limits() : ArcsecJsonParamBase(arcseckeys::LIMITS) {} + +size_t Limits::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Limits::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::LIMITS); + offset = 2; + result = getParam(arcseckeys::ACTION, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::FPGA18CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FPGA25CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FPGA10CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MCUCURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOS21CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOSPIXCURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOS33CURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOSVRESCURRENT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CMOS_TEMPERATURE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MCU_TEMPERATURE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + return RETURN_OK; +} + + +Tracking::Tracking() : ArcsecJsonParamBase(arcseckeys::TRACKING) {} + +size_t Tracking::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Tracking::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::TRACKING); + offset = 2; + result = getParam(arcseckeys::THIN_LIMIT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::OUTLIER_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::OUTLIER_THRESHOLD_QUEST, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::TRACKER_CHOICE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + return RETURN_OK; +} + + +Mounting::Mounting() : ArcsecJsonParamBase(arcseckeys::MOUNTING) {} + +size_t Mounting::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Mounting::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::MOUNTING); + offset = 2; + result = getParam(arcseckeys::qw, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::qx, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::qy, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::qz, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + return RETURN_OK; +} + + +Camera::Camera() : ArcsecJsonParamBase(arcseckeys::CAMERA) {} + +size_t Camera::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Camera::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::CAMERA); + offset = 2; + result = getParam(arcseckeys::MODE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::FOCALLENGTH, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::EXPOSURE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::INTERVAL, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::OFFSET, param); + if (result != RETURN_OK) { + return result; + } + addint16(param, buffer + offset); + offset += sizeof(int16_t); + result = getParam(arcseckeys::PGAGAIN, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::ADCGAIN, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_1, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_1, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_2, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_2, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_3, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_3, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_4, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_4, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_5, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_5, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_6, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_6, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_7, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_7, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::REG_8, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::VAL_8, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::FREQ_1, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FREQ_2, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + return RETURN_OK; +} + + +Blob::Blob() : ArcsecJsonParamBase(arcseckeys::BLOB) {} + +size_t Blob::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Blob::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::BLOB); + offset = 2; + result = getParam(arcseckeys::MODE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MIN_VALUE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MIN_DISTANCE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::NEIGHBOUR_DISTANCE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::NEIGHBOUR_BRIGHT_PIXELS, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MIN_TOTAL_VALUE, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MAX_TOTAL_VALUE, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MIN_BRIGHT_NEIGHBOURS, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MAX_BRIGHT_NEIGHBOURS, param); + if (result != RETURN_OK) { + return result; + } + adduint16(param, buffer + offset); + offset += sizeof(uint16_t); + result = getParam(arcseckeys::MAX_PIXEL_TO_CONSIDER, param); + if (result != RETURN_OK) { + return result; + } + adduint32(param, buffer + offset); + offset += sizeof(uint32_t); + result = getParam(arcseckeys::SIGNAL_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::DARK_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::ENABLE_HISTOGRAM, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::ENABLE_CONTRAST, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::BIN_MODE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + return RETURN_OK; +} + + +Centroiding::Centroiding() : ArcsecJsonParamBase(arcseckeys::CENTROIDING) {} + +size_t Centroiding::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Centroiding::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::CENTROIDING); + offset = 2; + result = getParam(arcseckeys::ENABLE_FILTER, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MAX_QUALITY, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MIN_QUALITY, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MAX_INTENSITY, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MIN_INTENSITY, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MAX_MAGNITUDE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::GAUSSIAN_CMAX, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::GAUSSIAN_CMIN, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::TRANSMATRIX_00, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::TRANSMATRIX_01, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::TRANSMATRIX_10, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::TRANSMATRIX_11, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + return RETURN_OK; +} + + +Lisa::Lisa() : ArcsecJsonParamBase(arcseckeys::LISA) {} + +size_t Lisa::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Lisa::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::LISA); + offset = 2; + result = getParam(arcseckeys::PREFILTER_DIST_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::PREFILTER_ANGLE_THRESHOLD, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FOV_WIDTH, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FOV_HEIGHT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::FLOAT_STAR_LIMIT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::CLOSE_STAR_LIMIT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::RATING_WEIGHT_CLOSE_STAR_COUNT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::RATING_WEIGHT_FRACTION_CLOSE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::RATING_WEIGHT_DB_STAR_COUNT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MAX_COMBINATIONS, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::NR_STARS_STOP, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::FRACTION_CLOSE_STOP, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + return RETURN_OK; +} + + +Matching::Matching() : ArcsecJsonParamBase(arcseckeys::MATCHING) {} + +size_t Matching::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Matching::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::MATCHING); + offset = 2; + result = getParam(arcseckeys::SQUARED_DISTANCE_LIMIT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::SQUARED_SHIFT_LIMIT, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + return RETURN_OK; +} + + +Validation::Validation() : ArcsecJsonParamBase(arcseckeys::VALIDATION) {} + +size_t Validation::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Validation::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::VALIDATION); + offset = 2; + result = getParam(arcseckeys::STABLE_COUNT, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::MAX_DIFFERENCE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MIN_TRACKER_CONFIDENCE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::MIN_MATCHED_STARS, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + return RETURN_OK; +} + +Algo::Algo() : ArcsecJsonParamBase(arcseckeys::ALGO) {} + +size_t Algo::getSize() { + return COMMAND_SIZE; +} + +ReturnValue_t Algo::createCommand(uint8_t* buffer) { + ReturnValue_t result = RETURN_OK; + uint8_t offset = 0; + std::string param; + addSetParamHeader(buffer, StarTracker::ID::ALGO); + offset = 2; + result = getParam(arcseckeys::MODE, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::L2T_MIN_CONFIDENCE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::L2T_MIN_MATCHED, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + offset += sizeof(uint8_t); + result = getParam(arcseckeys::T2L_MIN_CONFIDENCE, param); + if (result != RETURN_OK) { + return result; + } + addfloat(param, buffer + offset); + offset += sizeof(float); + result = getParam(arcseckeys::T2L_MIN_MATCHED, param); + if (result != RETURN_OK) { + return result; + } + adduint8(param, buffer + offset); + return RETURN_OK; +} diff --git a/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h new file mode 100644 index 00000000..868c18ea --- /dev/null +++ b/bsp_q7s/devices/startracker/StarTrackerJsonCommands.h @@ -0,0 +1,215 @@ +#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ +#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ + +/** + * @brief This file defines a few helper classes to generate commands by means of the parameters + * defined in the arcsec json files. + * @author J. Meier + */ + +#include + +#include "fsfw/serviceinterface/ServiceInterface.h" +#include "ArcsecJsonParamBase.h" + + +/** + * @brief Generates command to set the limit parameters + * + */ +class Limits : public ArcsecJsonParamBase { +public: + + Limits(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 43; + + virtual ReturnValue_t createCommand(uint8_t* buffer) override; +}; + + +/** + * @brief Generates the command to configure the tracking algorithm. + * + */ +class Tracking : public ArcsecJsonParamBase { +public: + + Tracking(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 15; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates the command to set the mounting quaternion + * + */ +class Mounting : public ArcsecJsonParamBase { +public: + + Mounting(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 18; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates the command to set the mounting quaternion + * + */ +class Camera : public ArcsecJsonParamBase { +public: + + Camera(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 43; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates the command to configure the blob algorithm + * + */ +class Blob : public ArcsecJsonParamBase { +public: + + Blob(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 24; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates the command to configure the centroiding algorithm + * + */ +class Centroiding : public ArcsecJsonParamBase { +public: + + Centroiding(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 47; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates the command to configure the LISA (lost in space algorithm) + * + */ +class Lisa : public ArcsecJsonParamBase { +public: + + Lisa(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 48; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates the command to configure the matching algorithm + * + */ +class Matching : public ArcsecJsonParamBase { +public: + + Matching(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 10; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates the command to configure the validation parameters + * + */ +class Validation : public ArcsecJsonParamBase { +public: + + Validation(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 12; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + + +/** + * @brief Generates command to configure the mechanism of automatically switching between the + * LISA and other algorithms. + * + */ +class Algo : public ArcsecJsonParamBase { +public: + + Algo(); + + size_t getSize(); + +private: + + static const size_t COMMAND_SIZE = 13; + + ReturnValue_t createCommand(uint8_t* buffer) override; + +}; + +#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ */ diff --git a/bsp_q7s/devices/startracker/StrHelper.cpp b/bsp_q7s/devices/startracker/StrHelper.cpp new file mode 100644 index 00000000..0be38ad7 --- /dev/null +++ b/bsp_q7s/devices/startracker/StrHelper.cpp @@ -0,0 +1,702 @@ +#include "StrHelper.h" + +#include "mission/utility/Timestamp.h" + +#include +#include + +StrHelper::StrHelper(object_id_t objectId) : SystemObject(objectId){ + +} + +StrHelper::~StrHelper() { +} + +ReturnValue_t StrHelper::initialize() { + sdcMan = SdCardManager::instance(); + if (sdcMan == nullptr) { + sif::warning << "StrHelper::initialize: Invalid SD Card Manager" << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t StrHelper::performOperation(uint8_t operationCode) { + ReturnValue_t result = RETURN_OK; + semaphore.acquire(); + while(true) { + switch(internalState) { + case InternalState::IDLE: { + semaphore.acquire(); + break; + } + case InternalState::UPLOAD_IMAGE: { + result = performImageUpload(); + if (result == RETURN_OK){ + triggerEvent(IMAGE_UPLOAD_SUCCESSFUL); + } + else { + triggerEvent(IMAGE_UPLOAD_FAILED); + } + internalState = InternalState::IDLE; + break; + } + case InternalState::DOWNLOAD_IMAGE: { + result = performImageDownload(); + if (result == RETURN_OK){ + triggerEvent(IMAGE_DOWNLOAD_SUCCESSFUL); + } + else { + triggerEvent(IMAGE_DOWNLOAD_FAILED); + } + internalState = InternalState::IDLE; + break; + } + case InternalState::FLASH_WRITE: { + result = performFlashWrite(); + if (result == RETURN_OK){ + triggerEvent(FLASH_WRITE_SUCCESSFUL); + } + else { + triggerEvent(FLASH_WRITE_FAILED); + } + internalState = InternalState::IDLE; + break; + } + case InternalState::FLASH_READ: { + result = performFlashRead(); + if (result == RETURN_OK){ + triggerEvent(FLASH_READ_SUCCESSFUL); + } + else { + triggerEvent(FLASH_READ_FAILED); + } + internalState = InternalState::IDLE; + break; + } + case InternalState::DOWNLOAD_FPGA_IMAGE: { + result = performFpgaDownload(); + if (result == RETURN_OK){ + triggerEvent(FPGA_DOWNLOAD_SUCCESSFUL); + } + else { + triggerEvent(FPGA_DOWNLOAD_FAILED); + } + internalState = InternalState::IDLE; + break; + } + case InternalState::UPLOAD_FPGA_IMAGE: { + result = performFpgaUpload(); + if (result == RETURN_OK){ + triggerEvent(FPGA_UPLOAD_SUCCESSFUL); + } + else { + triggerEvent(FPGA_UPLOAD_FAILED); + } + internalState = InternalState::IDLE; + break; + } + default: + sif::debug << "StrHelper::performOperation: Invalid state" << std::endl; + break; + } + } +} + +ReturnValue_t StrHelper::setComIF(DeviceCommunicationIF* communicationInterface_) { + uartComIF = dynamic_cast(communicationInterface_); + if (uartComIF == nullptr) { + sif::warning << "StrHelper::initialize: Invalid uart com if" << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +void StrHelper::setComCookie(CookieIF* comCookie_) { + comCookie = comCookie_; +} + +ReturnValue_t StrHelper::startImageUpload(std::string fullname) { + ReturnValue_t result = checkPath(fullname); + if (result != RETURN_OK) { + return result; + } + uploadImage.uploadFile = fullname; + if(not std::filesystem::exists(fullname)) { + return FILE_NOT_EXISTS; + } + internalState = InternalState::UPLOAD_FPGA_IMAGE; + semaphore.release(); + terminate = false; + return RETURN_OK; +} + +ReturnValue_t StrHelper::startImageDownload(std::string path) { + ReturnValue_t result = checkPath(path); + if (result != RETURN_OK) { + return result; + } + if(not std::filesystem::exists(path)) { + return PATH_NOT_EXISTS; + } + downloadImage.path = path; + internalState = InternalState::DOWNLOAD_IMAGE; + terminate = false; + semaphore.release(); + return RETURN_OK; +} + +void StrHelper::stopProcess() { + terminate = true; +} + +void StrHelper::setDownloadImageName(std::string filename) { + downloadImage.filename = filename; +} + +void StrHelper::setFlashReadFilename(std::string filename) { + flashRead.filename = filename; +} + +void StrHelper::setDownloadFpgaImage(std::string filename) { + fpgaDownload.fileName = filename; +} + +ReturnValue_t StrHelper::startFlashWrite(std::string fullname, uint8_t region, + uint32_t address) { + ReturnValue_t result = checkPath(fullname); + if (result != RETURN_OK) { + return result; + } + flashWrite.fullname = fullname; + if(not std::filesystem::exists(flashWrite.fullname)) { + return FILE_NOT_EXISTS; + } + flashWrite.address = address; + flashWrite.region = region; + internalState = InternalState::FLASH_WRITE; + semaphore.release(); + terminate = false; + return RETURN_OK; +} + +ReturnValue_t StrHelper::startFlashRead(std::string path, uint8_t region, + uint32_t address, uint32_t length) { + ReturnValue_t result = checkPath(path); + if (result != RETURN_OK) { + return result; + } + flashRead.path = path; + if(not std::filesystem::exists(flashRead.path)) { + return FILE_NOT_EXISTS; + } + flashRead.address = address; + flashRead.region = region; + flashRead.size = length; + internalState = InternalState::FLASH_READ; + semaphore.release(); + terminate = false; + return RETURN_OK; +} + +ReturnValue_t StrHelper::startFpgaDownload(std::string path, uint32_t startPosition, + uint32_t length) { + fpgaDownload.path = path; + fpgaDownload.startPosition = startPosition; + fpgaDownload.length = length; + internalState = InternalState::DOWNLOAD_FPGA_IMAGE; + semaphore.release(); + terminate = false; + return RETURN_OK; +} + +ReturnValue_t StrHelper::startFpgaUpload(std::string uploadFile) { + fpgaUpload.uploadFile = uploadFile; + internalState = InternalState::UPLOAD_FPGA_IMAGE; + semaphore.release(); + terminate = false; + return RETURN_OK; +} + +ReturnValue_t StrHelper::performImageDownload() { + ReturnValue_t result; + struct DownloadActionRequest downloadReq; + uint32_t size = 0; + uint32_t retries = 0; + Timestamp timestamp; + std::string image = downloadImage.path + "/" + timestamp.str() + downloadImage.filename ; + std::ofstream file(image, std::ios_base::app | std::ios_base::out); + if(not std::filesystem::exists(image)) { + return FILE_CREATION_FAILED; + } + downloadReq.position = 0; + while(downloadReq.position < ImageDownload::LAST_POSITION) { + if (terminate) { + return RETURN_OK; + } + arc_pack_download_action_req(&downloadReq, commandBuffer, &size); + result = sendAndRead(size, downloadReq.position); + if (result != RETURN_OK) { + if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { + uartComIF->flushUartRxBuffer(comCookie); + retries++; + continue; + } + file.close(); + return result; + } + result = checkActionReply(); + if (result != RETURN_OK) { + if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { + uartComIF->flushUartRxBuffer(comCookie); + retries++; + continue; + } + file.close(); + return result; + } + result = checkReplyPosition(downloadReq.position); + if (result != RETURN_OK) { + if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { + uartComIF->flushUartRxBuffer(comCookie); + retries++; + continue; + } + file.close(); + return result; + } + file.write(reinterpret_cast(datalinkLayer.getReply() + IMAGE_DATA_OFFSET), + IMAGE_DATA_SIZE); + downloadReq.position++; + retries = 0; + } + file.close(); + return RETURN_OK; +} + +ReturnValue_t StrHelper::performImageUpload() { + ReturnValue_t result = RETURN_OK; + uint32_t size = 0; + uint32_t imageSize = 0; + struct UploadActionRequest uploadReq; + uploadReq.position = 0; + std::memset(&uploadReq.data, 0, sizeof(uploadReq.data)); + if (not std::filesystem::exists(uploadImage.uploadFile)) { + triggerEvent(STR_HELPER_FILE_NOT_EXISTS, static_cast(internalState)); + internalState = InternalState::IDLE; + return RETURN_FAILED; + } + std::ifstream file(uploadImage.uploadFile, std::ifstream::binary); + // Set position of next character to end of file input stream + file.seekg(0, file.end); + // tellg returns position of character in input stream + imageSize = file.tellg(); + while((uploadReq.position + 1) * SIZE_IMAGE_PART < imageSize) { + if (terminate) { + return RETURN_OK; + } + file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg); + file.read(reinterpret_cast(uploadReq.data), SIZE_IMAGE_PART); + arc_pack_upload_action_req(&uploadReq, commandBuffer, &size); + result = sendAndRead(size, uploadReq.position); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + result = checkActionReply(); + if (result != RETURN_OK) { + return result; + } + uploadReq.position++; + } + std::memset(uploadReq.data, 0, sizeof(uploadReq.data)); + uint32_t remainder = imageSize - uploadReq.position * SIZE_IMAGE_PART; + file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg); + file.read(reinterpret_cast(uploadReq.data), remainder); + file.close(); + uploadReq.position++; + arc_pack_upload_action_req(&uploadReq, commandBuffer, &size); + result = sendAndRead(size, uploadReq.position); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + result = checkActionReply(); + if (result != RETURN_OK) { + return result; + } + return RETURN_OK; +} + +ReturnValue_t StrHelper::performFlashWrite() { + ReturnValue_t result = RETURN_OK; + uint32_t size = 0; + uint32_t remainingBytes = 0; + uint32_t fileSize = 0; + struct WriteActionRequest req; + if (not std::filesystem::exists(flashWrite.fullname)) { + triggerEvent(STR_HELPER_FILE_NOT_EXISTS, static_cast(internalState)); + internalState = InternalState::IDLE; + return RETURN_FAILED; + } + std::ifstream file(flashWrite.fullname, std::ifstream::binary); + file.seekg(0, file.end); + fileSize = file.tellg(); + remainingBytes = fileSize; + req.region = flashWrite.region; + req.address = flashWrite.address; + req.length = MAX_FLASH_DATA; + while(remainingBytes >= MAX_FLASH_DATA) { + if (terminate) { + return RETURN_OK; + } + file.seekg(fileSize - remainingBytes, file.beg); + file.read(reinterpret_cast(req.data), MAX_FLASH_DATA); + arc_pack_write_action_req(&req, commandBuffer, &size); + result = sendAndRead(size, req.address); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + result = checkFlashActionReply(req.region, req.address, req.length); + if (result != RETURN_OK) { + return result; + } + remainingBytes = remainingBytes - MAX_FLASH_DATA; + } + file.seekg(fileSize - remainingBytes, file.beg); + file.read(reinterpret_cast(req.data), remainingBytes); + file.close(); + arc_pack_write_action_req(&req, commandBuffer, &size); + result = sendAndRead(size, req.address); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + result = checkFlashActionReply(req.region, req.address, req.length); + if (result != RETURN_OK) { + return result; + } + return RETURN_OK; +} + +ReturnValue_t StrHelper::performFlashRead() { + ReturnValue_t result; + struct ReadActionRequest req; + uint32_t bytesRead = 0; + uint32_t size = 0; + uint32_t retries = 0; + Timestamp timestamp; + std::string fullname = flashRead.path + "/" + timestamp.str() + flashRead.filename ; + std::ofstream file(fullname, std::ios_base::app | std::ios_base::out); + if (not std::filesystem::exists(fullname)) { + return FILE_CREATION_FAILED; + } + req.region = flashRead.region; + while(bytesRead < flashRead.size) { + if (terminate) { + return RETURN_OK; + } + if ((flashRead.size - bytesRead) < MAX_FLASH_DATA) { + req.length = flashRead.size - bytesRead; + } + else { + req.length = MAX_FLASH_DATA; + } + req.address = flashRead.address + bytesRead; + arc_pack_read_action_req(&req, commandBuffer, &size); + result = sendAndRead(size, req.address); + if (result != RETURN_OK) { + if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { + uartComIF->flushUartRxBuffer(comCookie); + retries++; + continue; + } + file.close(); + return result; + } + result = checkActionReply(); + if (result != RETURN_OK) { + if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { + uartComIF->flushUartRxBuffer(comCookie); + retries++; + continue; + } + file.close(); + return result; + } + result = checkFlashActionReply(req.region, req.address, req.length); + if (result != RETURN_OK) { + if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { + uartComIF->flushUartRxBuffer(comCookie); + retries++; + continue; + } + file.close(); + return result; + } + file.write(reinterpret_cast(datalinkLayer.getReply() + FLASH_READ_DATA_OFFSET), + req.length); + bytesRead += req.length; + retries = 0; + } + file.close(); + return RETURN_OK; +} + +ReturnValue_t StrHelper::performFpgaDownload() { + ReturnValue_t result; + struct DownloadFPGAImageActionRequest req; + uint32_t size = 0; + uint32_t retries = 0; + Timestamp timestamp; + std::string image = fpgaDownload.path + "/" + timestamp.str() + fpgaDownload.fileName; + std::ofstream file(image, std::ios_base::app | std::ios_base::out); + if(not std::filesystem::exists(image)) { + return FILE_CREATION_FAILED; + } + req.pos = fpgaDownload.startPosition; + while(req.pos < fpgaDownload.length) { + if (terminate) { + return RETURN_OK; + } + if (fpgaDownload.length - req.pos >= FpgaDownload::MAX_DATA) { + req.length = FpgaDownload::MAX_DATA; + } + else { + req.length = fpgaDownload.length - req.pos; + } + arc_pack_downloadfpgaimage_action_req(&req, commandBuffer, &size); + result = sendAndRead(size, req.pos); + if (result != RETURN_OK) { + if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { + uartComIF->flushUartRxBuffer(comCookie); + retries++; + continue; + } + file.close(); + return result; + } + result = checkFpgaActionReply(req.pos, req.length); + if (result != RETURN_OK) { + if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { + uartComIF->flushUartRxBuffer(comCookie); + retries++; + continue; + } + file.close(); + return result; + } + file.write(reinterpret_cast(datalinkLayer.getReply() + FpgaDownload::DATA_OFFSET), + req.length); + req.pos += req.length; + retries = 0; + } + file.close(); + return RETURN_OK; +} + +ReturnValue_t StrHelper::performFpgaUpload() { + ReturnValue_t result = RETURN_OK; + uint32_t commandSize = 0; + uint32_t bytesUploaded = 0; + uint32_t fileSize = 0; + struct UploadFPGAImageActionRequest req; + if (not std::filesystem::exists(fpgaUpload.uploadFile)) { + triggerEvent(STR_HELPER_FILE_NOT_EXISTS, static_cast(internalState)); + internalState = InternalState::IDLE; + return RETURN_FAILED; + } + std::ifstream file(flashWrite.fullname, std::ifstream::binary); + file.seekg(0, file.end); + fileSize = file.tellg(); + req.pos = 0; + while(bytesUploaded <= fileSize) { + if (terminate) { + return RETURN_OK; + } + if (fileSize - bytesUploaded > FpgaUpload::MAX_DATA) { + req.length = FpgaUpload::MAX_DATA; + } + else { + req.length = fileSize - bytesUploaded; + } + file.seekg(bytesUploaded, file.beg); + file.read(reinterpret_cast(req.data), req.length); + arc_pack_uploadfpgaimage_action_req(&req, commandBuffer, &commandSize); + result = sendAndRead(commandSize, req.pos); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + result = checkFpgaActionReply(req.pos, req.length); + if (result != RETURN_OK) { + return result; + } + bytesUploaded += req.length; + } + return RETURN_OK; +} + +ReturnValue_t StrHelper::sendAndRead(size_t size, uint32_t parameter) { + ReturnValue_t result = RETURN_OK; + ReturnValue_t decResult = RETURN_OK; + size_t receivedDataLen = 0; + uint8_t *receivedData = nullptr; + size_t bytesLeft = 0; + uint32_t missedReplies = 0; + datalinkLayer.encodeFrame(commandBuffer, size); + result = uartComIF->sendMessage(comCookie, datalinkLayer.getEncodedFrame(), + datalinkLayer.getEncodedLength()); + if (result != RETURN_OK) { + sif::warning << "StrHelper::sendAndRead: Failed to send packet" << std::endl; + triggerEvent(STR_HELPER_SENDING_PACKET_FAILED, result, parameter); + return RETURN_FAILED; + } + decResult = ArcsecDatalinkLayer::DEC_IN_PROGRESS; + while (decResult == ArcsecDatalinkLayer::DEC_IN_PROGRESS) { + result = uartComIF->requestReceiveMessage(comCookie, + StarTracker::MAX_FRAME_SIZE * 2 + 2); + if (result != RETURN_OK) { + sif::warning << "StrHelper::sendAndRead: Failed to request reply" << std::endl; + triggerEvent(STR_HELPER_REQUESTING_MSG_FAILED, result, parameter); + return RETURN_FAILED; + } + result = uartComIF->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); + if (result != RETURN_OK) { + sif::warning << "StrHelper::sendAndRead: Failed to read received message" << std::endl; + triggerEvent(STR_HELPER_READING_REPLY_FAILED, result, parameter); + return RETURN_FAILED; + } + if (receivedDataLen == 0 && missedReplies < MAX_POLLS) { + missedReplies++; + continue; + } + else if ((receivedDataLen == 0) && (missedReplies >= MAX_POLLS)) { + triggerEvent(STR_HELPER_NO_REPLY, parameter); + return RETURN_FAILED; + } + else { + missedReplies = 0; + } + decResult = datalinkLayer.decodeFrame(receivedData, receivedDataLen, &bytesLeft); + if (bytesLeft != 0) { + // This should never happen + sif::warning << "StrHelper::sendAndRead: Bytes left after decoding" << std::endl; + triggerEvent(STR_HELPER_COM_ERROR, result, parameter); + return RETURN_FAILED; + } + } + if (decResult != RETURN_OK) { + triggerEvent(STR_HELPER_DEC_ERROR, decResult, parameter); + return RETURN_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t StrHelper::checkActionReply() { + uint8_t type = datalinkLayer.getReplyFrameType(); + if (type != TMTC_ACTIONREPLY) { + sif::warning << "StrHelper::checkActionReply: Received reply with invalid type ID" + << std::endl; + return INVALID_TYPE_ID; + } + uint8_t status = datalinkLayer.getStatusField(); + if (status != ArcsecDatalinkLayer::STATUS_OK) { + sif::warning << "StrHelper::checkActionReply: Status failure: " + << static_cast(status) << std::endl; + return STATUS_ERROR; + } + return RETURN_OK; +} + +ReturnValue_t StrHelper::checkReplyPosition(uint32_t expectedPosition) { + uint32_t receivedPosition = 0; + std::memcpy(&receivedPosition, datalinkLayer.getReply() + POS_OFFSET, sizeof(receivedPosition)); + if (receivedPosition != expectedPosition) { + triggerEvent(POSITION_MISMATCH, receivedPosition); + return RETURN_FAILED; + } + return RETURN_OK; +} + +ReturnValue_t StrHelper::checkFlashActionReply(uint8_t region_, uint32_t address_, + uint16_t length_) { + ReturnValue_t result = RETURN_OK; + result = checkActionReply(); + if (result != RETURN_OK) { + return result; + } + const uint8_t* data = datalinkLayer.getReply(); + uint8_t region = *(data + REGION_OFFSET); + uint32_t address; + const uint8_t* addressData = data + ADDRESS_OFFSET; + size_t size = sizeof(address); + result = SerializeAdapter::deSerialize(&address, &addressData, &size, + SerializeIF::Endianness::LITTLE); + if (result != RETURN_OK) { + sif::warning << "StrHelper::checkFlashActionReply: Deserialization of address failed" + << std::endl; + return result; + } + uint16_t length; + size = sizeof(length); + const uint8_t* lengthData = data + LENGTH_OFFSET; + result = SerializeAdapter::deSerialize(&length, lengthData, &size, + SerializeIF::Endianness::LITTLE); + if (result != RETURN_OK) { + sif::warning << "StrHelper::checkFlashActionReply: Deserialization of length failed" + << std::endl; + } + if (region != region_) { + return REGION_MISMATCH; + } + if (address != address_) { + return ADDRESS_MISMATCH; + } + if (length != length_) { + return LENGTH_MISMATCH; + } + return RETURN_OK; +} + +ReturnValue_t StrHelper::checkFpgaActionReply(uint32_t expectedPosition, + uint32_t expectedLength) { + ReturnValue_t result = RETURN_OK; + result = checkActionReply(); + if (result != RETURN_OK) { + return result; + } + const uint8_t* data = datalinkLayer.getReply() + ACTION_DATA_OFFSET; + uint32_t position; + size_t size = sizeof(position); + result = SerializeAdapter::deSerialize(&position, &data, &size, + SerializeIF::Endianness::LITTLE); + if (result != RETURN_OK) { + sif::warning << "StrHelper::checkFpgaActionReply: Deserialization of position failed" + << std::endl; + return result; + } + uint32_t length; + size = sizeof(length); + result = SerializeAdapter::deSerialize(&length, &data, &size, + SerializeIF::Endianness::LITTLE); + if (result != RETURN_OK) { + sif::warning << "StrHelper::checkFpgaActionReply: Deserialization of length failed" + << std::endl; + return result; + } + return result; +} + +ReturnValue_t StrHelper::checkPath(std::string name) { + if (name.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT)) + == std::string(SdCardManager::SD_0_MOUNT_POINT)) { + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { + sif::warning << "StrHelper::checkPath: SD card 0 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } else if (name.substr(0, sizeof(SdCardManager::SD_1_MOUNT_POINT)) + == std::string(SdCardManager::SD_1_MOUNT_POINT)) { + if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { + sif::warning << "StrHelper::checkPath: SD card 1 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } + return RETURN_OK; +} diff --git a/bsp_q7s/devices/startracker/StrHelper.h b/bsp_q7s/devices/startracker/StrHelper.h new file mode 100644 index 00000000..e140a4d6 --- /dev/null +++ b/bsp_q7s/devices/startracker/StrHelper.h @@ -0,0 +1,397 @@ +#ifndef BSP_Q7S_DEVICES_STRHELPER_H_ +#define BSP_Q7S_DEVICES_STRHELPER_H_ + +#include +#include "ArcsecDatalinkLayer.h" +#include "fsfw/osal/linux/BinarySemaphore.h" +#include "bsp_q7s/memory/SdCardManager.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw_hal/linux/uart/UartComIF.h" +#include "fsfw/devicehandlers/CookieIF.h" + +extern "C" { + #include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h" + #include "thirdparty/arcsec_star_tracker/client/generated/actionreq.h" +} + +/** + * @brief Helper class for the star tracker handler to accelerate large data transfers. + */ +class StrHelper: public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF { +public: + + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HELPER; + + //! [EXPORT] : [COMMENT] Image upload failed + static const Event IMAGE_UPLOAD_FAILED = MAKE_EVENT(0, severity::LOW); + //! [EXPORT] : [COMMENT] Image download failed + static const Event IMAGE_DOWNLOAD_FAILED = MAKE_EVENT(1, severity::LOW); + //! [EXPORT] : [COMMENT] Uploading image to star tracker was successfulop + static const Event IMAGE_UPLOAD_SUCCESSFUL = MAKE_EVENT(2, severity::LOW); + //! [EXPORT] : [COMMENT] Image download was successful + static const Event IMAGE_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(3, severity::LOW); + //! [EXPORT] : [COMMENT] Finished flash write procedure successfully + static const Event FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(4, severity::LOW); + //! [EXPORT] : [COMMENT] Finished flash read procedure successfully + static const Event FLASH_READ_SUCCESSFUL = MAKE_EVENT(5, severity::LOW); + //! [EXPORT] : [COMMENT] Flash write procedure failed + static const Event FLASH_WRITE_FAILED = MAKE_EVENT(6, severity::LOW); + //! [EXPORT] : [COMMENT] Flash read procedure failed + static const Event FLASH_READ_FAILED = MAKE_EVENT(7, severity::LOW); + //! [EXPORT] : [COMMENT] Download of FPGA image successful + static const Event FPGA_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(8, severity::LOW); + //! [EXPORT] : [COMMENT] Download of FPGA image failed + static const Event FPGA_DOWNLOAD_FAILED = MAKE_EVENT(9, severity::LOW); + //! [EXPORT] : [COMMENT] Upload of FPGA image successful + static const Event FPGA_UPLOAD_SUCCESSFUL = MAKE_EVENT(10, severity::LOW); + //! [EXPORT] : [COMMENT] Upload of FPGA image failed + static const Event FPGA_UPLOAD_FAILED = MAKE_EVENT(11, severity::LOW); + //! [EXPORT] : [COMMENT] Failed to read communication interface reply data + //!P1: Return code of failed communication interface read call + //!P1: Upload/download position for which the read call failed + static const Event STR_HELPER_READING_REPLY_FAILED = MAKE_EVENT(12, severity::LOW); + //! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence + //!P1: Return code of failed communication interface read call + //!P1: Upload/download position for which the read call failed + static const Event STR_HELPER_COM_ERROR = MAKE_EVENT(13, severity::LOW); + //! [EXPORT] : [COMMENT] Star tracker did not send replies (maybe device is powered off) + //!P1: Position of upload or download packet for which no reply was sent + static const Event STR_HELPER_NO_REPLY = MAKE_EVENT(14, severity::LOW); + //! [EXPORT] : [COMMENT] Error during decoding of received reply occurred + //P1: Return value of decoding function + //P2: Position of upload/download packet, or address of flash write/read request + static const Event STR_HELPER_DEC_ERROR = MAKE_EVENT(15, severity::LOW); + //! [EXPORT] : [COMMENT] Position mismatch + //! P1: The expected position and thus the position for which the image upload/download failed + static const Event POSITION_MISMATCH = MAKE_EVENT(16, severity::LOW); + //! [EXPORT] : [COMMENT] Specified file does not exist + //!P1: Internal state of str helper + static const Event STR_HELPER_FILE_NOT_EXISTS = MAKE_EVENT(17, severity::LOW); + //! [EXPORT] : [COMMENT] Sending packet to star tracker failed + //!P1: Return code of communication interface sendMessage function + //!P2: Position of upload/download packet, or address of flash write/read request for which sending failed + static const Event STR_HELPER_SENDING_PACKET_FAILED = MAKE_EVENT(18, severity::LOW); + //! [EXPORT] : [COMMENT] Communication interface requesting reply failed + //!P1: Return code of failed request + //!P1: Upload/download position, or address of flash write/read request for which transmission failed + static const Event STR_HELPER_REQUESTING_MSG_FAILED = MAKE_EVENT(19, severity::LOW); + + StrHelper(object_id_t objectId); + virtual ~StrHelper(); + + ReturnValue_t initialize() override; + ReturnValue_t performOperation(uint8_t operationCode = 0) override; + + ReturnValue_t setComIF(DeviceCommunicationIF* communicationInterface_); + void setComCookie(CookieIF* comCookie_); + + /** + * @brief Starts sequence to upload image to star tracker + * + * @param uploadImage_ Name including absolute path of the image to upload. Must be previously + * transferred to the OBC with the CFDP protocol. + */ + ReturnValue_t startImageUpload(std::string uploadImage_); + + /** + * @brief Calling this function initiates the download of an image from the star tracker. + * + * @param path Path where downloaded image will be stored + */ + ReturnValue_t startImageDownload(std::string path); + + /** + * @brief Starts the flash write procedure + * + * @param fullname Full name including absolute path of file to write to flash + * @param region Region ID of flash region to write to + * @param address Start address of flash write procedure + */ + ReturnValue_t startFlashWrite(std::string fullname, uint8_t region, uint32_t address); + + /** + * @brief Starts the flash read procedure + * + * @param path Path where file with read flash data will be created + * @param region Region ID of flash region to read from + * @param address Start address of flash section to read + * @param length Number of bytes to read from flash + */ + ReturnValue_t startFlashRead(std::string path, uint8_t region, uint32_t address, + uint32_t length); + + /** + * @brief Starts the download of the FPGA image + * + * @param path The path where the file with the downloaded data will be created + * @param startPosition Offset in fpga image to read from + * @param length Number of bytes to dwonload from the FPGA image + * + */ + ReturnValue_t startFpgaDownload(std::string path, uint32_t startPosition, uint32_t length); + + /** + * @brief Starts upload of new image to FPGA + * + * @param uploadFile Full name of file containing FPGA image data + */ + ReturnValue_t startFpgaUpload(std::string uploadFile); + + /** + * @brief Can be used to interrupt a running data transfer. + */ + void stopProcess(); + + /** + * @brief Changes the dafault name of downloaded images + */ + void setDownloadImageName(std::string filename); + + /** + * @brief Sets the name of the file which will be created to store the data read from flash + */ + void setFlashReadFilename(std::string filename); + + /** + * @brief Set download FPGA image name + */ + void setDownloadFpgaImage(std::string filename); + +private: + + static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER; + + //! [EXPORT] : [COMMENT] SD card specified in path string not mounted + static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Specified file does not exist on filesystem + static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA1); + //! [EXPORT] : [COMMENT] Specified path does not exist + static const ReturnValue_t PATH_NOT_EXISTS = MAKE_RETURN_CODE(0xA2); + //! [EXPORT] : [COMMENT] Failed to create download image or read flash file + static const ReturnValue_t FILE_CREATION_FAILED = MAKE_RETURN_CODE(0xA3); + //! [EXPORT] : [COMMENT] Region in flash write/read reply does not match expected region + static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(0xA4); + //! [EXPORT] : [COMMENT] Address in flash write/read reply does not match expected address + static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(0xA5); + //! [EXPORT] : [COMMENT] Length in flash write/read reply does not match expected length + static const ReturnValue_t LENGTH_MISMATCH = MAKE_RETURN_CODE(0xA6); + //! [EXPORT] : [COMMENT] Status field in reply signals error + static const ReturnValue_t STATUS_ERROR = MAKE_RETURN_CODE(0xA7); + //! [EXPORT] : [COMMENT] Reply has invalid type ID (should be of action reply type) + static const ReturnValue_t INVALID_TYPE_ID = MAKE_RETURN_CODE(0xA8); + + // Size of one image part which can be sent per action request + static const size_t SIZE_IMAGE_PART = 1024; + + class ImageDownload { + public: + static const uint32_t LAST_POSITION = 4095; + }; + + class FpgaDownload { + public: + static const uint16_t MAX_DATA = 1024; + static const uint8_t DATA_OFFSET = 10; + // Start position of fpga image part to download + uint32_t startPosition = 0; + // Length of image part to download + uint32_t length = 0; + // Path where downloaded FPGA image will be stored + std::string path; + // Name of file containing downloaded FPGA image + std::string fileName = "fpgaimage.bin"; + }; + FpgaDownload fpgaDownload; + + class FpgaUpload { + public: + static const uint32_t MAX_DATA = 1024; + // Full name of file to upload + std::string uploadFile; + }; + FpgaUpload fpgaUpload; + + static const uint32_t MAX_POLLS = 10000; + + static const uint8_t ACTION_DATA_OFFSET = 2; + static const uint8_t POS_OFFSET = 2; + static const uint8_t IMAGE_DATA_OFFSET = 5; + static const uint8_t FLASH_READ_DATA_OFFSET = 8; + static const uint8_t REGION_OFFSET = 2; + static const uint8_t ADDRESS_OFFSET = 3; + static const uint8_t LENGTH_OFFSET = 7; + static const size_t IMAGE_DATA_SIZE = 1024; + static const size_t MAX_FLASH_DATA = 1024; + static const size_t CONFIG_MAX_DOWNLOAD_RETRIES = 3; + + enum class InternalState { + IDLE, + UPLOAD_IMAGE, + DOWNLOAD_IMAGE, + FLASH_WRITE, + FLASH_READ, + DOWNLOAD_FPGA_IMAGE, + UPLOAD_FPGA_IMAGE + }; + + InternalState internalState = InternalState::IDLE; + + ArcsecDatalinkLayer datalinkLayer; + + BinarySemaphore semaphore; + + class UploadImage { + public: + // Name including absolute path of image to upload + std::string uploadFile; + }; + UploadImage uploadImage; + + class DownloadImage { + public: + // Path where the downloaded image will be stored + std::string path; + // Default name of downloaded image, can be changed via command + std::string filename = "image.bin"; + }; + DownloadImage downloadImage; + + class FlashWrite { + public: + // File which contains data to write when executing the flash write command + std::string fullname; + // Will be set with the flash write command + uint8_t region = 0; + // Will be set with the flash write command and specifies the start address where to write the + // flash data to + uint32_t address = 0; + }; + FlashWrite flashWrite; + + class FlashRead { + public: + // Path where the file containing the read data will be stored + std::string path = ""; + // Default name of file containing the data read from flash, can be changed via command + std::string filename = "flashread.bin"; + // Will be set with the flash read command + uint8_t region = 0; + // Will be set with the flash read command and specifies the start address of the flash section + // to read + uint32_t address = 0; + // Number of bytes to read from flash + uint32_t size = 0; + }; + FlashRead flashRead; + + SdCardManager* sdcMan = nullptr; + + uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; + + bool terminate = false; + + /** + * UART communication object responsible for low level access of star tracker + * Must be set by star tracker handler + */ + UartComIF* uartComIF = nullptr; + // Communication cookie. Must be set by the star tracker handler + CookieIF* comCookie = nullptr; + + // Queue id of raw data receiver + MessageQueueId_t rawDataReceiver = MessageQueueIF::NO_QUEUE; + + /** + * @brief Performs image uploading + */ + ReturnValue_t performImageUpload(); + + /** + * @brief Performs download of last taken image from the star tracker. + * + * @details Download is split over multiple packets transporting each a maximum of 1024 bytes. + * In case the download of one position fails, the same packet will be again + * requested. If the download of the packet fails CONFIG_MAX_DOWNLOAD_RETRIES times, + * the download will be stopped. + */ + ReturnValue_t performImageDownload(); + + /** + * @brief Handles flash write procedure + * + * @return RETURN_OK if successful, otherwise RETURN_FAILED + */ + ReturnValue_t performFlashWrite(); + + /** + * @brief Sends a sequence of commands to the star tracker to read larger parts from the + * flash memory. + */ + ReturnValue_t performFlashRead(); + + /** + * @brief Performs the download of the FPGA image which requires to be slip over multiple + * action requests. + */ + ReturnValue_t performFpgaDownload(); + + /** + * @brief Performs upload of new FPGA image. Upload sequence split over multiple commands + * because one command can only transport 1024 bytes of image data. + */ + ReturnValue_t performFpgaUpload(); + + /** + * @brief Sends packet to the star tracker and reads reply by using the communication + * interface + * + * @param size Size of data beforehand written to the commandBuffer + * @param parameter Parameter 2 of trigger event function + * + * @return RETURN_OK if successful, otherwise RETURN_FAILED + */ + ReturnValue_t sendAndRead(size_t size, uint32_t parameter); + + /** + * @brief Checks the header (type id and status fields) of the action reply + * + * @return RETURN_OK if reply confirms success of packet transfer, otherwise REUTRN_FAILED + */ + ReturnValue_t checkActionReply(); + + /** + * @brief Checks the position field in a star tracker upload/download reply. + * + * @param expectedPosition Value of expected position + * + * @return RETURN_OK if received position matches expected position, otherwise RETURN_FAILED + */ + ReturnValue_t checkReplyPosition(uint32_t expectedPosition); + + /** + * @brief Checks the region, address and length value of a flash write or read reply. + * + * @return RETURN_OK if values match expected values, otherwise appropriate error return + * value. + */ + ReturnValue_t checkFlashActionReply(uint8_t region_, uint32_t address_, uint16_t length_); + + /** + * @brief Checks the reply to the fpga download and upload request + * + * @param expectedPosition The expected position value in the reply + * @param expectedLength The expected length field in the reply + */ + ReturnValue_t checkFpgaActionReply(uint32_t expectedPosition, uint32_t expectedLength); + + /** + * @brief Checks if a path points to an sd card and whether the SD card is monuted. + * + * @return SD_NOT_MOUNTED id SD card is not mounted, otherwise RETURN_OK + */ + ReturnValue_t checkPath(std::string name); +}; + +#endif /* BSP_Q7S_DEVICES_STRHELPER_H_ */ diff --git a/bsp_q7s/gpio/gpioCallbacks.cpp b/bsp_q7s/gpio/gpioCallbacks.cpp index 38c5b46e..2cbf3320 100644 --- a/bsp_q7s/gpio/gpioCallbacks.cpp +++ b/bsp_q7s/gpio/gpioCallbacks.cpp @@ -27,13 +27,15 @@ void initSpiCsDecoder(GpioIF* gpioComIF) { GpiodRegularByLineName* spiMuxBit = nullptr; /** Setting mux bit 1 to low will disable IC21 on the interface board */ spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_1_PIN, "SPI Mux Bit 1", - gpio::OUT, gpio::HIGH); + gpio::DIR_OUT, gpio::HIGH); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit); /** Setting mux bit 2 to low disables IC1 on the TCS board */ - spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_2_PIN, "SPI Mux Bit 2", gpio::OUT, gpio::HIGH); + spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_2_PIN, "SPI Mux Bit 2", + gpio::DIR_OUT, gpio::HIGH); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit); /** Setting mux bit 3 to low disables IC2 on the TCS board and IC22 on the interface board */ - spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_3_PIN, "SPI Mux Bit 3", gpio::OUT, gpio::LOW); + spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_3_PIN, "SPI Mux Bit 3", + gpio::DIR_OUT, gpio::LOW); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit); // spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_1_PIN, "SPI Mux Bit 1", @@ -47,14 +49,17 @@ void initSpiCsDecoder(GpioIF* gpioComIF) { // spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit); /** The following gpios can take arbitrary initial values */ - spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_4_PIN, "SPI Mux Bit 4", gpio::OUT, gpio::LOW); + spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_4_PIN, "SPI Mux Bit 4", + gpio::DIR_OUT, gpio::LOW); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_4, spiMuxBit); - spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_5_PIN, "SPI Mux Bit 5", gpio::OUT, gpio::LOW); + spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_5_PIN, "SPI Mux Bit 5", + gpio::DIR_OUT, gpio::LOW); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_5, spiMuxBit); - spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_6_PIN, "SPI Mux Bit 6", gpio::OUT, gpio::LOW); + spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_6_PIN, "SPI Mux Bit 6", + gpio::DIR_OUT, gpio::LOW); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_6, spiMuxBit); GpiodRegularByLineName* enRwDecoder = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_CS, - "EN_RW_CS", gpio::OUT, gpio::HIGH); + "EN_RW_CS", gpio::DIR_OUT, gpio::HIGH); spiMuxGpios->addGpio(gpioIds::EN_RW_CS, enRwDecoder); result = gpioComInterface->addGpios(spiMuxGpios); diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index ebebf854..8a3d11f2 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -455,3 +455,33 @@ void SdCardManager::setPrintCommandOutput(bool print) { } +bool SdCardManager::isSdCardMounted(sd::SdCard sdCard) { + SdCardManager::SdStatePair active; + ReturnValue_t result = this->getSdCardActiveStatus(active); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state"; + return false; + } + if (sdCard == sd::SLOT_0) { + if (active.first == sd::MOUNTED) { + return true; + } + else { + return false; + } + } + else if (sdCard == sd::SLOT_1) { + if (active.second == sd::MOUNTED) { + return true; + } + else { + return false; + } + } + else { + sif::debug << "SdCardManager::isSdCardMounted: Unknown SD card specified" << std::endl; + } + return false; +} + + diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 6f03e7f1..6e4930da 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -195,6 +195,15 @@ public: void setBlocking(bool blocking); void setPrintCommandOutput(bool print); + + /** + * @brief Checks if an SD card is mounted + * + * @param sdCard The SD crad to check + * + * @return true if mounted, otherwise false + */ + bool isSdCardMounted(sd::SdCard sdCard); private: CommandExecutor cmdExecutor; Operations currentOp = Operations::IDLE; diff --git a/cmake/scripts/Q7S/make-release-cfg.sh b/cmake/scripts/Q7S/make-release-cfg.sh index d71dcc83..233bf263 100755 --- a/cmake/scripts/Q7S/make-release-cfg.sh +++ b/cmake/scripts/Q7S/make-release-cfg.sh @@ -17,7 +17,7 @@ fi os_fsfw="linux" tgt_bsp="arm/q7s" -build_dir="build-Debug-Q7S" +build_dir="build-Release-Q7S" build_generator="make" if [ "${OS}" = "Windows_NT" ]; then python="py" @@ -28,6 +28,6 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ -l"${build_dir}" # set +x diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index 00b5ca25..cd90272d 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -19,10 +19,13 @@ enum commonClassIds: uint8_t { CCSDS_IP_CORE_BRIDGE, //IPCI PTME, //PTME PLOC_UPDATER, //PLUD + STR_HELPER, //STRHLP GOM_SPACE_HANDLER, //GOMS PLOC_MEMORY_DUMPER, //PLMEMDUMP PDEC_HANDLER, //PDEC - CCSDS_HANDLER, //PDEC + CCSDS_HANDLER, //CCSDS + ARCSEC_JSON_BASE, //JSONBASE + NVM_PARAM_BASE, //NVMB COMMON_CLASS_ID_END // [EXPORT] : [END] }; diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index 8cf45e9a..cce3616f 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -87,10 +87,11 @@ enum commonObjects: uint32_t { RW3 = 0x44120249, RW4 = 0x44120350, - START_TRACKER = 0x44130001, + STAR_TRACKER = 0x44130001, PLOC_UPDATER = 0x44330000, - PLOC_MEMORY_DUMPER = 0x44330001 + PLOC_MEMORY_DUMPER = 0x44330001, + STR_HELPER = 0x44330002 }; } diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index 05fda61c..55a4bed4 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -18,6 +18,7 @@ enum: uint8_t { PLOC_UPDATER = 117, PLOC_MEMORY_DUMPER = 118, PDEC_HANDLER = 119, + STR_HELPER = 120, COMMON_SUBSYSTEM_ID_END }; } diff --git a/common/config/devConf.h b/common/config/devConf.h index 3fbded81..78681ec7 100644 --- a/common/config/devConf.h +++ b/common/config/devConf.h @@ -12,15 +12,15 @@ namespace spi { // Default values, changing them is not supported for now static constexpr uint32_t DEFAULT_LIS3_SPEED = 976'000; -static constexpr uint32_t LIS3_TRANSITION_DELAY = 10000; +static constexpr uint32_t LIS3_TRANSITION_DELAY = 5000; static constexpr spi::SpiModes DEFAULT_LIS3_MODE = spi::SpiModes::MODE_3; static constexpr uint32_t DEFAULT_RM3100_SPEED = 976'000; -static constexpr uint32_t RM3100_TRANSITION_DELAY = 10000; +static constexpr uint32_t RM3100_TRANSITION_DELAY = 5000; static constexpr spi::SpiModes DEFAULT_RM3100_MODE = spi::SpiModes::MODE_3; static constexpr uint32_t DEFAULT_L3G_SPEED = 976'000; -static constexpr uint32_t L3G_TRANSITION_DELAY = 10000; +static constexpr uint32_t L3G_TRANSITION_DELAY = 5000; static constexpr spi::SpiModes DEFAULT_L3G_MODE = spi::SpiModes::MODE_3; static constexpr uint32_t DEFAULT_MAX_1227_SPEED = 3'900'000; diff --git a/linux/fsfwconfig/devices/heaterSwitcherList.h b/common/config/devices/heaterSwitcherList.h similarity index 100% rename from linux/fsfwconfig/devices/heaterSwitcherList.h rename to common/config/devices/heaterSwitcherList.h diff --git a/fsfw b/fsfw index ceb87b5a..b98c85d3 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit ceb87b5abb2992a18266328e0ea34d9af15db7af +Subproject commit b98c85d33fd79853e674f75dadd0a082a962aee4 diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 8dfa9e78..cdf4d181 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -1,120 +1,140 @@ -2200;STORE_SEND_WRITE_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2201;STORE_WRITE_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2202;STORE_SEND_READ_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2203;STORE_READ_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2204;UNEXPECTED_MSG;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2205;STORING_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2206;TM_DUMP_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2207;STORE_INIT_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2208;STORE_INIT_EMPTY;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2209;STORE_CONTENT_CORRUPTED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2210;STORE_INITIALIZE;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2211;INIT_DONE;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2212;DUMP_FINISHED;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2213;DELETION_FINISHED;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2214;DELETION_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2215;AUTO_CATALOGS_SENDING_FAILED;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2600;GET_DATA_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h -2601;STORE_DATA_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h -2800;DEVICE_BUILDING_COMMAND_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2801;DEVICE_SENDING_COMMAND_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2802;DEVICE_REQUESTING_REPLY_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2803;DEVICE_READING_REPLY_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2805;DEVICE_MISSED_REPLY;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2806;DEVICE_UNKNOWN_REPLY;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2807;DEVICE_UNREQUESTED_REPLY;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2808;INVALID_DEVICE_COMMAND;LOW;Indicates a SW bug in child class.;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2809;MONITORING_LIMIT_EXCEEDED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2810;MONITORING_AMBIGUOUS;HIGH;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -4201;FUSE_CURRENT_HIGH;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4202;FUSE_WENT_OFF;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4204;POWER_ABOVE_HIGH_LIMIT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4205;POWER_BELOW_LOW_LIMIT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4300;SWITCH_WENT_OFF;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h -5000;HEATER_ON;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5001;HEATER_OFF;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5002;HEATER_TIMEOUT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5003;HEATER_STAYED_ON;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5004;HEATER_STAYED_OFF;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5200;TEMP_SENSOR_HIGH;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5201;TEMP_SENSOR_LOW;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5202;TEMP_SENSOR_GRADIENT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5901;COMPONENT_TEMP_LOW;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5902;COMPONENT_TEMP_HIGH;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5903;COMPONENT_TEMP_OOL_LOW;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5904;COMPONENT_TEMP_OOL_HIGH;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5905;TEMP_NOT_IN_OP_RANGE;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -7101;FDIR_CHANGED_STATE;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7102;FDIR_STARTS_RECOVERY;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7103;FDIR_TURNS_OFF_DEVICE;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7201;MONITOR_CHANGED_STATE;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7202;VALUE_BELOW_LOW_LIMIT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7203;VALUE_ABOVE_HIGH_LIMIT;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7204;VALUE_OUT_OF_RANGE;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7301;SWITCHING_TM_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datapool/HkSwitchHelper.h -7400;CHANGING_MODE;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7401;MODE_INFO;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7402;FALLBACK_FAILED;HIGH;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7403;MODE_TRANSITION_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7404;CANT_KEEP_MODE;HIGH;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7405;OBJECT_IN_INVALID_MODE;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7406;FORCING_MODE;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7407;MODE_CMD_REJECTED;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7506;HEALTH_INFO;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7507;CHILD_CHANGED_HEALTH;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7508;CHILD_PROBLEMS;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7509;OVERWRITING_HEALTH;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7510;TRYING_RECOVERY;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7511;RECOVERY_STEP;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7512;RECOVERY_DONE;MEDIUM;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7900;RF_AVAILABLE;INFO;A RF available signal was detected. P1: raw RFA state, P2: 0;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7901;RF_LOST;INFO;A previously found RF available signal was lost. P1: raw RFA state, P2: 0;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7902;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7903;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7905;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -8900;CLOCK_SET;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h -8901;CLOCK_SET_FAILURE;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h -9700;TEST;INFO;;/home/eive/EIVE/Robin/eive-obsw/fsfw/src/fsfw/pus/Service17Test.h -10600;CHANGE_OF_SETUP_PARAMETER;LOW;;/home/eive/EIVE/Robin/eive-obsw/fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h -10900;GPIO_PULL_HIGH_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/HeaterHandler.h -10901;GPIO_PULL_LOW_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/HeaterHandler.h -10902;SWITCH_ALREADY_ON;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/HeaterHandler.h -10903;SWITCH_ALREADY_OFF;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/HeaterHandler.h -10904;MAIN_SWITCH_TIMEOUT;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/HeaterHandler.h -11000;MAIN_SWITCH_ON_TIMEOUT;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h -11001;MAIN_SWITCH_OFF_TIMEOUT;LOW;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h -11002;DEPLOYMENT_FAILED;HIGH;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h -11003;DEPL_SA1_GPIO_SWTICH_ON_FAILED;HIGH;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h -11004;DEPL_SA2_GPIO_SWTICH_ON_FAILED;HIGH;;/home/eive/EIVE/Robin/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h -11101;MEMORY_READ_RPT_CRC_FAILURE;LOW;;/home/eive/EIVE/Robin/eive-obsw/mission/devices/PlocMPSoCHandler.h -11102;ACK_FAILURE;LOW;;/home/eive/EIVE/Robin/eive-obsw/mission/devices/PlocMPSoCHandler.h -11103;EXE_FAILURE;LOW;;/home/eive/EIVE/Robin/eive-obsw/mission/devices/PlocMPSoCHandler.h -11104;CRC_FAILURE_EVENT;LOW;;/home/eive/EIVE/Robin/eive-obsw/mission/devices/PlocMPSoCHandler.h -11201;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11202;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11203;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11204;SELF_TEST_PWM_FAILURE;LOW;Get self test result returns PWM failure which concerns the coil actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11205;SELF_TEST_TC_FAILURE;LOW;Get self test result returns TC failure (system failure) P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11206;SELF_TEST_MTM_RANGE_FAILURE;LOW;Get self test result returns failure that MTM values were outside of the expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;/home/eive/EIVE/Robin/eive-obsw/mission/devices/IMTQHandler.h -11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;/home/eive/EIVE/Robin/eive-obsw/mission/devices/RwHandler.h -11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h -11600;SANITIZATION_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/memory/SdCardManager.h -11700;UPDATE_FILE_NOT_EXISTS;LOW;;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11701;ACTION_COMMANDING_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11702;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11703;UPDATE_TRANSFER_FAILED;LOW;Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet);/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11704;UPDATE_VERIFY_FAILED;LOW;Supervisor failed to execute the update verify command.;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11705;UPDATE_FINISHED;INFO;MPSoC update successful completed;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocUpdater.h -11800;SEND_MRAM_DUMP_FAILED;LOW;;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h -11801;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h -11802;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;/home/eive/EIVE/Robin/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h -11901;INVALID_TC_FRAME;HIGH;;/home/eive/EIVE/Robin/eive-obsw/linux/obc/PdecHandler.h -11902;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;/home/eive/EIVE/Robin/eive-obsw/linux/obc/PdecHandler.h -11903;CARRIER_LOCK;INFO;Carrier lock detected;/home/eive/EIVE/Robin/eive-obsw/linux/obc/PdecHandler.h -11904;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);/home/eive/EIVE/Robin/eive-obsw/linux/obc/PdecHandler.h +2200;STORE_SEND_WRITE_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2201;STORE_WRITE_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2202;STORE_SEND_READ_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2203;STORE_READ_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2204;UNEXPECTED_MSG;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2205;STORING_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2206;TM_DUMP_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2207;STORE_INIT_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2208;STORE_INIT_EMPTY;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2209;STORE_CONTENT_CORRUPTED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2210;STORE_INITIALIZE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2211;INIT_DONE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2212;DUMP_FINISHED;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2213;DELETION_FINISHED;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2214;DELETION_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2215;AUTO_CATALOGS_SENDING_FAILED;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2600;GET_DATA_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h +2601;STORE_DATA_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h +2800;DEVICE_BUILDING_COMMAND_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2801;DEVICE_SENDING_COMMAND_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2802;DEVICE_REQUESTING_REPLY_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2803;DEVICE_READING_REPLY_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2805;DEVICE_MISSED_REPLY;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2806;DEVICE_UNKNOWN_REPLY;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2807;DEVICE_UNREQUESTED_REPLY;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2808;INVALID_DEVICE_COMMAND;LOW;Indicates a SW bug in child class.;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2809;MONITORING_LIMIT_EXCEEDED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2810;MONITORING_AMBIGUOUS;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +4201;FUSE_CURRENT_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4202;FUSE_WENT_OFF;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4204;POWER_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4205;POWER_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4300;SWITCH_WENT_OFF;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h +5000;HEATER_ON;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5001;HEATER_OFF;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5002;HEATER_TIMEOUT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5003;HEATER_STAYED_ON;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5004;HEATER_STAYED_OFF;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5200;TEMP_SENSOR_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5201;TEMP_SENSOR_LOW;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5202;TEMP_SENSOR_GRADIENT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5901;COMPONENT_TEMP_LOW;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5902;COMPONENT_TEMP_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5903;COMPONENT_TEMP_OOL_LOW;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5904;COMPONENT_TEMP_OOL_HIGH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5905;TEMP_NOT_IN_OP_RANGE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +7101;FDIR_CHANGED_STATE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7102;FDIR_STARTS_RECOVERY;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7103;FDIR_TURNS_OFF_DEVICE;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7201;MONITOR_CHANGED_STATE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7202;VALUE_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7203;VALUE_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7204;VALUE_OUT_OF_RANGE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7301;SWITCHING_TM_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/HkSwitchHelper.h +7400;CHANGING_MODE;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7401;MODE_INFO;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7402;FALLBACK_FAILED;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7403;MODE_TRANSITION_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7404;CANT_KEEP_MODE;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7405;OBJECT_IN_INVALID_MODE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7406;FORCING_MODE;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7407;MODE_CMD_REJECTED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7506;HEALTH_INFO;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7507;CHILD_CHANGED_HEALTH;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7508;CHILD_PROBLEMS;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7509;OVERWRITING_HEALTH;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7510;TRYING_RECOVERY;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7511;RECOVERY_STEP;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7512;RECOVERY_DONE;MEDIUM;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7900;RF_AVAILABLE;INFO;A RF available signal was detected. P1: raw RFA state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7901;RF_LOST;INFO;A previously found RF available signal was lost. P1: raw RFA state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7902;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7903;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7905;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +8900;CLOCK_SET;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h +8901;CLOCK_SET_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h +9700;TEST;INFO;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service17Test.h +10600;CHANGE_OF_SETUP_PARAMETER;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h +10900;GPIO_PULL_HIGH_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/HeaterHandler.h +10901;GPIO_PULL_LOW_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/HeaterHandler.h +10902;SWITCH_ALREADY_ON;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/HeaterHandler.h +10903;SWITCH_ALREADY_OFF;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/HeaterHandler.h +10904;MAIN_SWITCH_TIMEOUT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/HeaterHandler.h +11000;MAIN_SWITCH_ON_TIMEOUT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h +11001;MAIN_SWITCH_OFF_TIMEOUT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h +11002;DEPLOYMENT_FAILED;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h +11003;DEPL_SA1_GPIO_SWTICH_ON_FAILED;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h +11004;DEPL_SA2_GPIO_SWTICH_ON_FAILED;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h +11101;MEMORY_READ_RPT_CRC_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11102;ACK_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11103;EXE_FAILURE;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11104;CRC_FAILURE_EVENT;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11201;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11202;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11203;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11204;SELF_TEST_PWM_FAILURE;LOW;Get self test result returns PWM failure which concerns the coil actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11205;SELF_TEST_TC_FAILURE;LOW;Get self test result returns TC failure (system failure) P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11206;SELF_TEST_MTM_RANGE_FAILURE;LOW;Get self test result returns failure that MTM values were outside of the expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h +11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h +11600;SANITIZATION_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h +11700;UPDATE_FILE_NOT_EXISTS;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11701;ACTION_COMMANDING_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11702;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11703;UPDATE_TRANSFER_FAILED;LOW;Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet);C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11704;UPDATE_VERIFY_FAILED;LOW;Supervisor failed to execute the update verify command.;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11705;UPDATE_FINISHED;INFO;MPSoC update successful completed;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocUpdater.h +11800;SEND_MRAM_DUMP_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h +11801;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h +11802;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h +11901;INVALID_TC_FRAME;HIGH;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/obc/PdecHandler.h +11902;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/obc/PdecHandler.h +11903;CARRIER_LOCK;INFO;Carrier lock detected;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/obc/PdecHandler.h +11904;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/linux/obc/PdecHandler.h +12000;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12001;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12002;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12003;IMAGE_DOWNLOAD_SUCCESSFUL;LOW;Image download was successful;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12004;FLASH_WRITE_SUCCESSFUL;LOW;Finished flash write procedure successfully;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12005;FLASH_READ_SUCCESSFUL;LOW;Finished flash read procedure successfully;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12006;FLASH_WRITE_FAILED;LOW;Flash write procedure failed;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12007;FLASH_READ_FAILED;LOW;Flash read procedure failed;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12008;FPGA_DOWNLOAD_SUCCESSFUL;LOW;Download of FPGA image successful;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12009;FPGA_DOWNLOAD_FAILED;LOW;Download of FPGA image failed;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12010;FPGA_UPLOAD_SUCCESSFUL;LOW;Upload of FPGA image successful;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12011;FPGA_UPLOAD_FAILED;LOW;Upload of FPGA image failed;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12012;STR_HELPER_READING_REPLY_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12013;STR_HELPER_COM_ERROR;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12014;STR_HELPER_NO_REPLY;LOW;Star tracker did not send replies (maybe device is powered off)P1: Position of upload or download packet for which no reply was sent;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12015;STR_HELPER_DEC_ERROR;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12016;POSITION_MISMATCH;LOW;Position mismatch P1: The expected position and thus the position for which the image upload/download failed;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12017;STR_HELPER_FILE_NOT_EXISTS;LOW;Specified file does not existP1: Internal state of str helper;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12018;STR_HELPER_SENDING_PACKET_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h +12019;STR_HELPER_REQUESTING_MSG_FAILED;LOW;;C:\Users\jakob\OneDrive\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/devices/startracker/StrHelper.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index fded183b..af48751f 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -27,7 +27,7 @@ 0x44120309;MGM_3_RM3100_HANDLER 0x44120313;GYRO_3_L3G_HANDLER 0x44120350;RW4 -0x44130001;START_TRACKER +0x44130001;STAR_TRACKER 0x44130045;GPS0_HANDLER 0x44130146;GPS1_HANDLER 0x44140014;IMTQ_HANDLER @@ -39,6 +39,7 @@ 0x443200A5;RAD_SENSOR 0x44330000;PLOC_UPDATER 0x44330001;PLOC_MEMORY_DUMPER +0x44330002;STR_HELPER 0x44330015;PLOC_MPSOC_HANDLER 0x44330016;PLOC_SUPERVISOR_HANDLER 0x444100A2;SOLAR_ARRAY_DEPL_HANDLER diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 943468c5..17150762 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 120 translations. + * @brief Auto-generated event translation file. Contains 140 translations. * @details - * Generated on: 2021-11-25 14:09:00 + * Generated on: 2021-12-29 20:24:08 */ #include "translateEvents.h" @@ -125,6 +125,26 @@ const char *INVALID_TC_FRAME_STRING = "INVALID_TC_FRAME"; const char *INVALID_FAR_STRING = "INVALID_FAR"; const char *CARRIER_LOCK_STRING = "CARRIER_LOCK"; const char *BIT_LOCK_PDEC_STRING = "BIT_LOCK_PDEC"; +const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED"; +const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED"; +const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL"; +const char *IMAGE_DOWNLOAD_SUCCESSFUL_STRING = "IMAGE_DOWNLOAD_SUCCESSFUL"; +const char *FLASH_WRITE_SUCCESSFUL_STRING = "FLASH_WRITE_SUCCESSFUL"; +const char *FLASH_READ_SUCCESSFUL_STRING = "FLASH_READ_SUCCESSFUL"; +const char *FLASH_WRITE_FAILED_STRING = "FLASH_WRITE_FAILED"; +const char *FLASH_READ_FAILED_STRING = "FLASH_READ_FAILED"; +const char *FPGA_DOWNLOAD_SUCCESSFUL_STRING = "FPGA_DOWNLOAD_SUCCESSFUL"; +const char *FPGA_DOWNLOAD_FAILED_STRING = "FPGA_DOWNLOAD_FAILED"; +const char *FPGA_UPLOAD_SUCCESSFUL_STRING = "FPGA_UPLOAD_SUCCESSFUL"; +const char *FPGA_UPLOAD_FAILED_STRING = "FPGA_UPLOAD_FAILED"; +const char *STR_HELPER_READING_REPLY_FAILED_STRING = "STR_HELPER_READING_REPLY_FAILED"; +const char *STR_HELPER_COM_ERROR_STRING = "STR_HELPER_COM_ERROR"; +const char *STR_HELPER_NO_REPLY_STRING = "STR_HELPER_NO_REPLY"; +const char *STR_HELPER_DEC_ERROR_STRING = "STR_HELPER_DEC_ERROR"; +const char *POSITION_MISMATCH_STRING = "POSITION_MISMATCH"; +const char *STR_HELPER_FILE_NOT_EXISTS_STRING = "STR_HELPER_FILE_NOT_EXISTS"; +const char *STR_HELPER_SENDING_PACKET_FAILED_STRING = "STR_HELPER_SENDING_PACKET_FAILED"; +const char *STR_HELPER_REQUESTING_MSG_FAILED_STRING = "STR_HELPER_REQUESTING_MSG_FAILED"; const char * translateEvents(Event event) { switch( (event & 0xffff) ) { @@ -368,6 +388,46 @@ const char * translateEvents(Event event) { return CARRIER_LOCK_STRING; case(11904): return BIT_LOCK_PDEC_STRING; + case(12000): + return IMAGE_UPLOAD_FAILED_STRING; + case(12001): + return IMAGE_DOWNLOAD_FAILED_STRING; + case(12002): + return IMAGE_UPLOAD_SUCCESSFUL_STRING; + case(12003): + return IMAGE_DOWNLOAD_SUCCESSFUL_STRING; + case(12004): + return FLASH_WRITE_SUCCESSFUL_STRING; + case(12005): + return FLASH_READ_SUCCESSFUL_STRING; + case(12006): + return FLASH_WRITE_FAILED_STRING; + case(12007): + return FLASH_READ_FAILED_STRING; + case(12008): + return FPGA_DOWNLOAD_SUCCESSFUL_STRING; + case(12009): + return FPGA_DOWNLOAD_FAILED_STRING; + case(12010): + return FPGA_UPLOAD_SUCCESSFUL_STRING; + case(12011): + return FPGA_UPLOAD_FAILED_STRING; + case(12012): + return STR_HELPER_READING_REPLY_FAILED_STRING; + case(12013): + return STR_HELPER_COM_ERROR_STRING; + case(12014): + return STR_HELPER_NO_REPLY_STRING; + case(12015): + return STR_HELPER_DEC_ERROR_STRING; + case(12016): + return POSITION_MISMATCH_STRING; + case(12017): + return STR_HELPER_FILE_NOT_EXISTS_STRING; + case(12018): + return STR_HELPER_SENDING_PACKET_FAILED_STRING; + case(12019): + return STR_HELPER_REQUESTING_MSG_FAILED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 48eb29e7..49900a5d 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 112 translations. - * Generated on: 2021-11-22 17:04:51 + * Contains 113 translations. + * Generated on: 2021-12-21 17:21:23 */ #include "translateObjects.h" @@ -35,7 +35,7 @@ const char *RW3_STRING = "RW3"; const char *MGM_3_RM3100_HANDLER_STRING = "MGM_3_RM3100_HANDLER"; const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER"; const char *RW4_STRING = "RW4"; -const char *START_TRACKER_STRING = "START_TRACKER"; +const char *STAR_TRACKER_STRING = "STAR_TRACKER"; const char *GPS0_HANDLER_STRING = "GPS0_HANDLER"; const char *GPS1_HANDLER_STRING = "GPS1_HANDLER"; const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER"; @@ -47,6 +47,7 @@ const char *ACU_HANDLER_STRING = "ACU_HANDLER"; const char *RAD_SENSOR_STRING = "RAD_SENSOR"; const char *PLOC_UPDATER_STRING = "PLOC_UPDATER"; const char *PLOC_MEMORY_DUMPER_STRING = "PLOC_MEMORY_DUMPER"; +const char *STR_HELPER_STRING = "STR_HELPER"; 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"; @@ -180,7 +181,7 @@ const char* translateObject(object_id_t object) { case 0x44120350: return RW4_STRING; case 0x44130001: - return START_TRACKER_STRING; + return STAR_TRACKER_STRING; case 0x44130045: return GPS0_HANDLER_STRING; case 0x44130146: @@ -203,6 +204,8 @@ const char* translateObject(object_id_t object) { return PLOC_UPDATER_STRING; case 0x44330001: return PLOC_MEMORY_DUMPER_STRING; + case 0x44330002: + return STR_HELPER_STRING; case 0x44330015: return PLOC_MPSOC_HANDLER_STRING; case 0x44330016: diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index 5168ba95..b043b55d 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -297,65 +297,65 @@ void SpiTestClass::acsInit() { GpiodRegularByChip* gpio = nullptr; std::string rpiGpioName = "gpiochip0"; gpio = new GpiodRegularByChip(rpiGpioName, mgm0Lis3mdlChipSelect, "MGM_0_LIS3", - gpio::Direction::OUT, 1); + gpio::DIR_OUT, 1); gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, mgm1Rm3100ChipSelect, "MGM_1_RM3100", - gpio::Direction::OUT, 1); + gpio::DIR_OUT, 1); gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, gyro0AdisChipSelect, "GYRO_0_ADIS", - gpio::Direction::OUT, 1); + gpio::DIR_OUT, 1); gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, gyro1L3gd20ChipSelect, "GYRO_1_L3G", - gpio::Direction::OUT, 1); + gpio::DIR_OUT, 1); gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, gyro3L3gd20ChipSelect, "GYRO_2_L3G", - gpio::Direction::OUT, 1); + gpio::DIR_OUT, 1); gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, mgm2Lis3mdlChipSelect, "MGM_2_LIS3", - gpio::Direction::OUT, 1); + gpio::DIR_OUT, 1); gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, mgm3Rm3100ChipSelect, "MGM_3_RM3100", - gpio::Direction::OUT, 1); + gpio::DIR_OUT, 1); gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); #elif defined(XIPHOS_Q7S) GpiodRegularByLineName* gpio = nullptr; - gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, "MGM_0_LIS3", gpio::Direction::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, "MGM_0_LIS3", gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_1_RM3100", gpio::Direction::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_1_RM3100", gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, "MGM_2_LIS3", gpio::Direction::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, "MGM_2_LIS3", gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_3_RM3100", gpio::Direction::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_3_RM3100", gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ADIS_CS, "GYRO_0_ADIS", - gpio::Direction::OUT, gpio::HIGH); + gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, "GYRO_1_L3G", gpio::Direction::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, "GYRO_1_L3G", gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio); gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, "GYRO_2_ADIS", - gpio::Direction::OUT, gpio::HIGH); + gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::GYRO_2_ADIS_CS, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, "GYRO_3_L3G", gpio::Direction::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, "GYRO_3_L3G", gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio); // Enable pins must be pulled low for regular operations - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_0_ENABLE", gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_0_ENABLE", gpio::DIR_OUT, gpio::LOW); gpioCookie->addGpio(gpioIds::GYRO_0_ENABLE, gpio); - gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_2_ENABLE", gpio::OUT, + gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_2_ENABLE", gpio::DIR_OUT, gpio::LOW); gpioCookie->addGpio(gpioIds::GYRO_2_ENABLE, gpio); #endif diff --git a/linux/devices/CMakeLists.txt b/linux/devices/CMakeLists.txt index 3871a6a6..b02c8e57 100644 --- a/linux/devices/CMakeLists.txt +++ b/linux/devices/CMakeLists.txt @@ -1,5 +1,4 @@ target_sources(${TARGET_NAME} PRIVATE - HeaterHandler.cpp SolarArrayDeploymentHandler.cpp SusHandler.cpp ) diff --git a/linux/fsfwconfig/FSFWConfig.h.in b/linux/fsfwconfig/FSFWConfig.h.in index 3b87078c..9e8f2016 100644 --- a/linux/fsfwconfig/FSFWConfig.h.in +++ b/linux/fsfwconfig/FSFWConfig.h.in @@ -78,6 +78,6 @@ static constexpr size_t FSFW_MAX_TM_PACKET_SIZE = 2048; #define FSFW_HAL_L3GD20_GYRO_DEBUG 0 #define FSFW_HAL_RM3100_MGM_DEBUG 0 #define FSFW_HAL_LIS3MDL_MGM_DEBUG 0 -#define FSFW_HAL_ADIS16507_GYRO_DEBUG 0 +#define FSFW_HAL_ADIS1650X_GYRO_DEBUG 0 #endif /* CONFIG_FSFWCONFIG_H_ */ diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 663ef00b..4a7bca35 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -102,7 +102,6 @@ debugging. */ #define OBSW_DEBUG_ACU 0 #define OBSW_DEBUG_SYRLINKS 0 #define OBSW_DEBUG_IMQT 0 -#define OBSW_DEBUG_ADIS16507 0 #define OBSW_DEBUG_RAD_SENSOR 0 #define OBSW_DEBUG_SUS 0 #define OBSW_DEBUG_RTD 0 @@ -110,13 +109,13 @@ debugging. */ #define OBSW_DEBUG_STARTRACKER 0 #define OBSW_DEBUG_PLOC_MPSOC 0 #define OBSW_DEBUG_PLOC_SUPERVISOR 0 -#define OBSW_DEBUG_PDEC_HANDLER 0 +#define OBSW_DEBUG_PDEC_HANDLER 1 /*******************************************************************/ /** Hardcoded */ /*******************************************************************/ -// Leave at one as the BSP is linux. Used by the ADIS16507 device handler -#define OBSW_ADIS16507_LINUX_COM_IF 1 +// Leave at one as the BSP is linux. Used by the ADIS1650X device handler +#define OBSW_ADIS1650X_LINUX_COM_IF 1 #include "OBSWVersion.h" @@ -132,6 +131,7 @@ namespace config { /* Add mission configuration flags here */ static constexpr uint32_t OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE = 50; static constexpr uint32_t PLOC_UPDATER_QUEUE_SIZE = 50; +static constexpr uint32_t STR_IMG_HELPER_QUEUE_SIZE = 50; static constexpr uint8_t LIVE_TM = 0; diff --git a/linux/fsfwconfig/devices/gpioIds.h b/linux/fsfwconfig/devices/gpioIds.h index 8d3f94ca..e4b9f727 100644 --- a/linux/fsfwconfig/devices/gpioIds.h +++ b/linux/fsfwconfig/devices/gpioIds.h @@ -27,6 +27,8 @@ enum gpioId_t { GNSS_0_NRESET, GNSS_1_NRESET, + GNSS_0_ENABLE, + GNSS_1_ENABLE, GYRO_0_ENABLE, GYRO_2_ENABLE, diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 943468c5..17150762 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 120 translations. + * @brief Auto-generated event translation file. Contains 140 translations. * @details - * Generated on: 2021-11-25 14:09:00 + * Generated on: 2021-12-29 20:24:08 */ #include "translateEvents.h" @@ -125,6 +125,26 @@ const char *INVALID_TC_FRAME_STRING = "INVALID_TC_FRAME"; const char *INVALID_FAR_STRING = "INVALID_FAR"; const char *CARRIER_LOCK_STRING = "CARRIER_LOCK"; const char *BIT_LOCK_PDEC_STRING = "BIT_LOCK_PDEC"; +const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED"; +const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED"; +const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL"; +const char *IMAGE_DOWNLOAD_SUCCESSFUL_STRING = "IMAGE_DOWNLOAD_SUCCESSFUL"; +const char *FLASH_WRITE_SUCCESSFUL_STRING = "FLASH_WRITE_SUCCESSFUL"; +const char *FLASH_READ_SUCCESSFUL_STRING = "FLASH_READ_SUCCESSFUL"; +const char *FLASH_WRITE_FAILED_STRING = "FLASH_WRITE_FAILED"; +const char *FLASH_READ_FAILED_STRING = "FLASH_READ_FAILED"; +const char *FPGA_DOWNLOAD_SUCCESSFUL_STRING = "FPGA_DOWNLOAD_SUCCESSFUL"; +const char *FPGA_DOWNLOAD_FAILED_STRING = "FPGA_DOWNLOAD_FAILED"; +const char *FPGA_UPLOAD_SUCCESSFUL_STRING = "FPGA_UPLOAD_SUCCESSFUL"; +const char *FPGA_UPLOAD_FAILED_STRING = "FPGA_UPLOAD_FAILED"; +const char *STR_HELPER_READING_REPLY_FAILED_STRING = "STR_HELPER_READING_REPLY_FAILED"; +const char *STR_HELPER_COM_ERROR_STRING = "STR_HELPER_COM_ERROR"; +const char *STR_HELPER_NO_REPLY_STRING = "STR_HELPER_NO_REPLY"; +const char *STR_HELPER_DEC_ERROR_STRING = "STR_HELPER_DEC_ERROR"; +const char *POSITION_MISMATCH_STRING = "POSITION_MISMATCH"; +const char *STR_HELPER_FILE_NOT_EXISTS_STRING = "STR_HELPER_FILE_NOT_EXISTS"; +const char *STR_HELPER_SENDING_PACKET_FAILED_STRING = "STR_HELPER_SENDING_PACKET_FAILED"; +const char *STR_HELPER_REQUESTING_MSG_FAILED_STRING = "STR_HELPER_REQUESTING_MSG_FAILED"; const char * translateEvents(Event event) { switch( (event & 0xffff) ) { @@ -368,6 +388,46 @@ const char * translateEvents(Event event) { return CARRIER_LOCK_STRING; case(11904): return BIT_LOCK_PDEC_STRING; + case(12000): + return IMAGE_UPLOAD_FAILED_STRING; + case(12001): + return IMAGE_DOWNLOAD_FAILED_STRING; + case(12002): + return IMAGE_UPLOAD_SUCCESSFUL_STRING; + case(12003): + return IMAGE_DOWNLOAD_SUCCESSFUL_STRING; + case(12004): + return FLASH_WRITE_SUCCESSFUL_STRING; + case(12005): + return FLASH_READ_SUCCESSFUL_STRING; + case(12006): + return FLASH_WRITE_FAILED_STRING; + case(12007): + return FLASH_READ_FAILED_STRING; + case(12008): + return FPGA_DOWNLOAD_SUCCESSFUL_STRING; + case(12009): + return FPGA_DOWNLOAD_FAILED_STRING; + case(12010): + return FPGA_UPLOAD_SUCCESSFUL_STRING; + case(12011): + return FPGA_UPLOAD_FAILED_STRING; + case(12012): + return STR_HELPER_READING_REPLY_FAILED_STRING; + case(12013): + return STR_HELPER_COM_ERROR_STRING; + case(12014): + return STR_HELPER_NO_REPLY_STRING; + case(12015): + return STR_HELPER_DEC_ERROR_STRING; + case(12016): + return POSITION_MISMATCH_STRING; + case(12017): + return STR_HELPER_FILE_NOT_EXISTS_STRING; + case(12018): + return STR_HELPER_SENDING_PACKET_FAILED_STRING; + case(12019): + return STR_HELPER_REQUESTING_MSG_FAILED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 48eb29e7..49900a5d 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 112 translations. - * Generated on: 2021-11-22 17:04:51 + * Contains 113 translations. + * Generated on: 2021-12-21 17:21:23 */ #include "translateObjects.h" @@ -35,7 +35,7 @@ const char *RW3_STRING = "RW3"; const char *MGM_3_RM3100_HANDLER_STRING = "MGM_3_RM3100_HANDLER"; const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER"; const char *RW4_STRING = "RW4"; -const char *START_TRACKER_STRING = "START_TRACKER"; +const char *STAR_TRACKER_STRING = "STAR_TRACKER"; const char *GPS0_HANDLER_STRING = "GPS0_HANDLER"; const char *GPS1_HANDLER_STRING = "GPS1_HANDLER"; const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER"; @@ -47,6 +47,7 @@ const char *ACU_HANDLER_STRING = "ACU_HANDLER"; const char *RAD_SENSOR_STRING = "RAD_SENSOR"; const char *PLOC_UPDATER_STRING = "PLOC_UPDATER"; const char *PLOC_MEMORY_DUMPER_STRING = "PLOC_MEMORY_DUMPER"; +const char *STR_HELPER_STRING = "STR_HELPER"; 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"; @@ -180,7 +181,7 @@ const char* translateObject(object_id_t object) { case 0x44120350: return RW4_STRING; case 0x44130001: - return START_TRACKER_STRING; + return STAR_TRACKER_STRING; case 0x44130045: return GPS0_HANDLER_STRING; case 0x44130146: @@ -203,6 +204,8 @@ const char* translateObject(object_id_t object) { return PLOC_UPDATER_STRING; case 0x44330001: return PLOC_MEMORY_DUMPER_STRING; + case 0x44330002: + return STR_HELPER_STRING; case 0x44330015: return PLOC_MPSOC_HANDLER_STRING; case 0x44330016: diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 73a27116..07bc4a8f 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -415,37 +415,37 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { #if OBSW_ADD_RW == 1 thisSequence->addSlot(objects::RW1, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::RW1, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RW1, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RW1, length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::RW1, length * 0.5, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::RW1, length * 0.65, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::RW1, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::RW2, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::RW2, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RW2, length * 0.6, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RW2, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RW2, length * 0.85, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::RW2, length * 0.5, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::RW2, length * 0.65, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::RW2, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::RW3, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::RW3, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RW3, length * 0.6, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RW3, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RW3, length * 0.85, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::RW3, length * 0.5, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::RW3, length * 0.65, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::RW3, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::RW4, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::RW4, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RW4, length * 0.6, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RW4, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RW4, length * 0.85, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::RW4, length * 0.5, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::RW4, length * 0.65, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::RW4, length * 0.8, DeviceHandlerIF::GET_READ); #endif #if OBSW_ADD_ACS_BOARD == 1 - bool enableAside = false; - bool enableBside = true; + bool enableAside = true; + bool enableBside = false; if(enableAside) { // A side thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.2, + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.25, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.6, DeviceHandlerIF::GET_WRITE); @@ -568,7 +568,6 @@ ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) { ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) { // Length of a communication cycle uint32_t length = thisSequence->getPeriodMs(); - static_cast(length); bool uartPstEmpty = true; #if OBSW_ADD_PLOC_MPSOC == 1 @@ -649,11 +648,11 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) { #if OBSW_ADD_STAR_TRACKER == 1 uartPstEmpty = false; - 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); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0.8, DeviceHandlerIF::GET_READ); #endif if(uartPstEmpty) { diff --git a/linux/obc/PdecHandler.cpp b/linux/obc/PdecHandler.cpp index 1ac83d44..aa46c23c 100644 --- a/linux/obc/PdecHandler.cpp +++ b/linux/obc/PdecHandler.cpp @@ -262,7 +262,7 @@ bool PdecHandler::checkFrameAna(uint32_t pdecFar) { } case(FrameAna_t::FRAME_DIRTY): { triggerEvent(INVALID_TC_FRAME, FRAME_DIRTY); - sif::debug << "PdecHandler::checkFrameAna: Frame dirty" << std::endl; + sif::warning << "PdecHandler::checkFrameAna: Frame dirty" << std::endl; break; } case(FrameAna_t::FRAME_ILLEGAL): { @@ -314,50 +314,50 @@ void PdecHandler::handleIReason(uint32_t pdecFar, ReturnValue_t parameter1) { switch(ireason) { case(IReason_t::NO_REPORT): { triggerEvent(INVALID_TC_FRAME, parameter1, NO_REPORT); - sif::debug << "PdecHandler::handleIReason: No illegal report" << std::endl; + sif::info << "PdecHandler::handleIReason: No illegal report" << std::endl; break; } case(IReason_t::ERROR_VERSION_NUMBER): { triggerEvent(INVALID_TC_FRAME, parameter1, ERROR_VERSION_NUMBER); - sif::debug << "PdecHandler::handleIReason: Error in version number and reserved A and B " + sif::info << "PdecHandler::handleIReason: Error in version number and reserved A and B " << "fields" << std::endl; break; } case(IReason_t::ILLEGAL_COMBINATION): { triggerEvent(INVALID_TC_FRAME, parameter1, ILLEGAL_COMBINATION); - sif::debug << "PdecHandler::handleIReason: Illegal combination (AC) of bypass and control " + sif::info << "PdecHandler::handleIReason: Illegal combination (AC) of bypass and control " << "command flags" << std::endl; break; } case(IReason_t::INVALID_SC_ID): { triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_SC_ID); - sif::debug << "PdecHandler::handleIReason: Invalid spacecraft identifier " << std::endl; + sif::info << "PdecHandler::handleIReason: Invalid spacecraft identifier " << std::endl; break; } case(IReason_t::INVALID_VC_ID_MSB): { triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_VC_ID_MSB); - sif::debug << "PdecHandler::handleIReason: VC identifier bit 0 to 4 did not match " + sif::info << "PdecHandler::handleIReason: VC identifier bit 0 to 4 did not match " << std::endl; break; } case(IReason_t::INVALID_VC_ID_LSB): { triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_VC_ID_LSB); - sif::debug << "PdecHandler::handleIReason: VC identifier bit 5 did not match " << std::endl; + sif::info << "PdecHandler::handleIReason: VC identifier bit 5 did not match " << std::endl; break; } case(IReason_t::NS_NOT_ZERO): { triggerEvent(INVALID_TC_FRAME, parameter1, NS_NOT_ZERO); - sif::debug << "PdecHandler::handleIReason: N(S) of BC or BD frame not set to all zeros" + sif::info << "PdecHandler::handleIReason: N(S) of BC or BD frame not set to all zeros" << std::endl; break; } case(IReason_t::INCORRECT_BC_CC): { triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_BC_CC); - sif::debug << "PdecHandler::handleIReason: Invalid BC control command format" << std::endl; + sif::info << "PdecHandler::handleIReason: Invalid BC control command format" << std::endl; break; } default: { - sif::debug << "PdecHandler::handleIReason: Invalid reason id" << std::endl; + sif::info << "PdecHandler::handleIReason: Invalid reason id" << std::endl; break; } } @@ -373,7 +373,7 @@ void PdecHandler::handleNewTc() { } #if OBSW_DEBUG_PDEC_HANDLER == 1 unsigned int mapId = tcSegment[0] & MAP_ID_MASK; - sif::debug << "PdecHandler::handleNewTc: Received TC segment with map ID " << mapId + sif::info << "PdecHandler::handleNewTc: Received TC segment with map ID " << mapId << std::endl; printTC(tcLength); #endif /* OBSW_DEBUG_PDEC_HANDLER */ @@ -460,7 +460,7 @@ void PdecHandler::printTC(uint32_t tcLength) { tcSegmentStream << std::setfill('0') << std::setw(2) << std::hex << static_cast(tcSegment[idx]); } - sif::debug << tcSegmentStream.str() << std::endl; + sif::info << tcSegmentStream.str() << std::endl; } uint8_t PdecHandler::calcMapAddrEntry(uint8_t moduleId) { @@ -484,6 +484,10 @@ uint32_t PdecHandler::getClcw() { return *(registerBaseAddress + PDEC_CLCW_OFFSET); } +uint32_t PdecHandler::getPdecMon() { + return *(registerBaseAddress + PDEC_MON_OFFSET); +} + void PdecHandler::printClcw() { uint32_t clcw = getClcw(); uint8_t type = static_cast((clcw >> 31) & 0x1); @@ -525,6 +529,39 @@ void PdecHandler::printClcw() { << "0x" << static_cast(repValue) << std::endl; } +void PdecHandler::printPdecMon() { + uint32_t pdecMon = getPdecMon(); + uint32_t tc0ChannelStatus = (pdecMon & TC0_STATUS_MASK) >> TC0_STATUS_POS; + uint32_t tc1ChannelStatus = (pdecMon & TC1_STATUS_MASK) >> TC1_STATUS_POS; + uint32_t tc2ChannelStatus = (pdecMon & TC2_STATUS_MASK) >> TC2_STATUS_POS; + uint32_t tc3ChannelStatus = (pdecMon & TC3_STATUS_MASK) >> TC3_STATUS_POS; + uint32_t tc4ChannelStatus = (pdecMon & TC4_STATUS_MASK) >> TC4_STATUS_POS; + uint32_t tc5ChannelStatus = (pdecMon & TC5_STATUS_MASK) >> TC5_STATUS_POS; + uint32_t lock = (pdecMon & LOCK_MASK) >> LOCK_POS; + sif::info << std::setw(30) << std::left << "TC0 status: " << getMonStatusString(tc0ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "TC1 status: " << getMonStatusString(tc1ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "TC2 status: " << getMonStatusString(tc2ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "TC3 status: " << getMonStatusString(tc3ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "TC4 status: " << getMonStatusString(tc4ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "TC5 status: " << getMonStatusString(tc5ChannelStatus) << std::endl; + sif::info << std::setw(30) << std::left << "Start sequence lock: " << lock << std::endl; +} + +std::string PdecHandler::getMonStatusString(uint32_t status) { + switch(status) { + case TC_CHANNEL_INACTIVE: + return std::string("inactive"); + case TC_CHANNEL_ACTIVE: + return std::string("active"); + case TC_CHANNEL_TIMEDOUT: + return std::string("timed out"); + default: + sif::warning << "PdecHandler::getMonStatusString: Invalid status" << std::endl; + return std::string(); + break; + } +} + ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { @@ -532,6 +569,9 @@ ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, case PRINT_CLCW: printClcw(); return EXECUTION_FINISHED; + case PRINT_PDEC_MON: + printPdecMon(); + return EXECUTION_FINISHED; default: return COMMAND_NOT_IMPLEMENTED; } diff --git a/linux/obc/PdecHandler.h b/linux/obc/PdecHandler.h index 8819df22..8c8e8d9b 100644 --- a/linux/obc/PdecHandler.h +++ b/linux/obc/PdecHandler.h @@ -61,16 +61,6 @@ public: ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) override; - /** - * brief Returns the 32-bit wide communication link control word (CLCW) - */ - uint32_t getClcw(); - - /** - * @rief Reads and prints the CLCW. Can be useful for debugging. - */ - void printClcw(); - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER; //! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame @@ -119,6 +109,8 @@ private: // Action IDs static const ActionId_t PRINT_CLCW = 0; + // Print PDEC monitor register + static const ActionId_t PRINT_PDEC_MON = 1; static const uint8_t STAT_POSITION = 31; static const uint8_t FRAME_ANA_POSITION = 28; @@ -129,6 +121,28 @@ private: static const uint32_t FRAME_ANA_MASK = 0x70000000; static const uint32_t IREASON_MASK = 0x0E000000; + static const uint32_t TC_CHANNEL_INACTIVE = 0x0; + static const uint32_t TC_CHANNEL_ACTIVE = 0x1; + static const uint32_t TC_CHANNEL_TIMEDOUT = 0x2; + + static const uint32_t TC0_STATUS_MASK = 0x3; + static const uint32_t TC1_STATUS_MASK = 0xC; + static const uint32_t TC2_STATUS_MASK = 0x300; + static const uint32_t TC3_STATUS_MASK = 0xC00; + static const uint32_t TC4_STATUS_MASK = 0x30000; + static const uint32_t TC5_STATUS_MASK = 0xc00000; + // Lock register set to 1 when start sequence has been found (CLTU is beeing processed) + static const uint32_t LOCK_MASK = 0xc00000; + + static const uint32_t TC0_STATUS_POS = 0; + static const uint32_t TC1_STATUS_POS = 2; + static const uint32_t TC2_STATUS_POS = 4; + static const uint32_t TC3_STATUS_POS = 6; + static const uint32_t TC4_STATUS_POS = 8; + static const uint32_t TC5_STATUS_POS = 10; + // Lock register set to 1 when start sequence has been found (CLTU is beeing processed) + static const uint32_t LOCK_POS = 12; + /** * UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4 * Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10 @@ -138,7 +152,7 @@ private: static const uint32_t PDEC_BFREE_OFFSET = 0xA24; static const uint32_t PDEC_BPTR_OFFSET = 0xA25; static const uint32_t PDEC_SLEN_OFFSET = 0xA26; - static const uint32_t PDEC_MON = 0xA27; + static const uint32_t PDEC_MON_OFFSET = 0xA27; #if BOARD_TE0720 == 1 static const int CONFIG_MEMORY_MAP_SIZE = 0x400; @@ -330,6 +344,29 @@ private: */ uint8_t getOddParity(uint8_t number); + /** + * brief Returns the 32-bit wide communication link control word (CLCW) + */ + uint32_t getClcw(); + + /** + * @brief Returns the PDEC monitor register content + * + */ + uint32_t getPdecMon(); + + /** + * @brief Reads and prints the CLCW. Can be useful for debugging. + */ + void printClcw(); + + /** + * @brief Prints monitor register information to debug console. + */ + void printPdecMon(); + + std::string getMonStatusString(uint32_t status); + object_id_t tcDestinationId; AcceptsTelecommandsIF* tcDestination = nullptr; diff --git a/misc/eclipse/.cproject b/misc/eclipse/.cproject index 7d7c4c09..3bab5367 100644 --- a/misc/eclipse/.cproject +++ b/misc/eclipse/.cproject @@ -19,7 +19,7 @@ - +