diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 8b2c4366..cbd0021b 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -44,8 +44,8 @@ #include "linux/csp/CspComIF.h" #include "linux/csp/CspCookie.h" #include "linux/devices/SolarArrayDeploymentHandler.h" -#include "linux/devices/SusHandler.h" -#include "linux/devices/devicedefinitions/SusDefinitions.h" +#include "mission/devices/SusHandler.h" +#include "mission/devices/devicedefinitions/SusDefinitions.h" #include "mission/core/GenericFactory.h" #include "mission/devices/ACUHandler.h" #include "mission/devices/BpxBatteryHandler.h" @@ -351,61 +351,57 @@ void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComI SpiCookie* spiCookieSus1 = new SpiCookie(addresses::SUS_1, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus2 = new SpiCookie(addresses::SUS_2, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus3 = new SpiCookie(addresses::SUS_3, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus4 = new SpiCookie(addresses::SUS_4, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus5 = new SpiCookie(addresses::SUS_5, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus6 = new SpiCookie(addresses::SUS_6, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus7 = new SpiCookie(addresses::SUS_7, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus8 = new SpiCookie(addresses::SUS_8, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus9 = new SpiCookie(addresses::SUS_9, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus10 = new SpiCookie(addresses::SUS_10, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus11 = new SpiCookie(addresses::SUS_11, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus12 = new SpiCookie(addresses::SUS_12, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); SpiCookie* spiCookieSus13 = new SpiCookie(addresses::SUS_13, gpio::NO_GPIO, std::string(q7s::SPI_DEFAULT_DEV), - SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, SUS::MAX1227_SPI_FREQ); + SUS::MAX_CMD_SIZE, spi::DEFAULT_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); - new SusHandler(objects::SUS_1, objects::SPI_COM_IF, spiCookieSus1, gpioComIF, gpioIds::CS_SUS_1); - new SusHandler(objects::SUS_2, objects::SPI_COM_IF, spiCookieSus2, gpioComIF, gpioIds::CS_SUS_2); - new SusHandler(objects::SUS_3, objects::SPI_COM_IF, spiCookieSus3, gpioComIF, gpioIds::CS_SUS_3); - new SusHandler(objects::SUS_4, objects::SPI_COM_IF, spiCookieSus4, gpioComIF, gpioIds::CS_SUS_4); - new SusHandler(objects::SUS_5, objects::SPI_COM_IF, spiCookieSus5, gpioComIF, gpioIds::CS_SUS_5); - new SusHandler(objects::SUS_6, objects::SPI_COM_IF, spiCookieSus6, gpioComIF, gpioIds::CS_SUS_6); - new SusHandler(objects::SUS_7, objects::SPI_COM_IF, spiCookieSus7, gpioComIF, gpioIds::CS_SUS_7); - new SusHandler(objects::SUS_8, objects::SPI_COM_IF, spiCookieSus8, gpioComIF, gpioIds::CS_SUS_8); - new SusHandler(objects::SUS_9, objects::SPI_COM_IF, spiCookieSus9, gpioComIF, gpioIds::CS_SUS_9); - new SusHandler(objects::SUS_10, objects::SPI_COM_IF, spiCookieSus10, gpioComIF, - gpioIds::CS_SUS_10); - new SusHandler(objects::SUS_11, objects::SPI_COM_IF, spiCookieSus11, gpioComIF, - gpioIds::CS_SUS_11); - new SusHandler(objects::SUS_12, objects::SPI_COM_IF, spiCookieSus12, gpioComIF, - gpioIds::CS_SUS_12); - new SusHandler(objects::SUS_13, objects::SPI_COM_IF, spiCookieSus13, gpioComIF, - gpioIds::CS_SUS_13); + new SusHandler(objects::SUS_1, 0, objects::SPI_COM_IF, spiCookieSus1); + new SusHandler(objects::SUS_2, 1, objects::SPI_COM_IF, spiCookieSus2); + new SusHandler(objects::SUS_3, 2, objects::SPI_COM_IF, spiCookieSus3); + new SusHandler(objects::SUS_4, 3, objects::SPI_COM_IF, spiCookieSus4); + new SusHandler(objects::SUS_5, 4, objects::SPI_COM_IF, spiCookieSus5); + new SusHandler(objects::SUS_6, 5, objects::SPI_COM_IF, spiCookieSus6); + new SusHandler(objects::SUS_7, 6, objects::SPI_COM_IF, spiCookieSus7); + new SusHandler(objects::SUS_8, 7, objects::SPI_COM_IF, spiCookieSus8); + new SusHandler(objects::SUS_9, 8, objects::SPI_COM_IF, spiCookieSus9); + new SusHandler(objects::SUS_10, 9, objects::SPI_COM_IF, spiCookieSus10); + new SusHandler(objects::SUS_11, 10, objects::SPI_COM_IF, spiCookieSus11); + new SusHandler(objects::SUS_12, 11, objects::SPI_COM_IF, spiCookieSus12); + new SusHandler(objects::SUS_13, 12, objects::SPI_COM_IF, spiCookieSus13); } void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF) { @@ -991,13 +987,13 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) { gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA); VirtualChannel* vc = nullptr; - vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE); + vc = new VirtualChannel(ccsds::VC0, common::VC0_QUEUE_SIZE, objects::CCSDS_HANDLER); ccsdsHandler->addVirtualChannel(ccsds::VC0, vc); - vc = new VirtualChannel(ccsds::VC1, common::VC1_QUEUE_SIZE); + vc = new VirtualChannel(ccsds::VC1, common::VC1_QUEUE_SIZE, objects::CCSDS_HANDLER); ccsdsHandler->addVirtualChannel(ccsds::VC1, vc); - vc = new VirtualChannel(ccsds::VC2, common::VC2_QUEUE_SIZE); + vc = new VirtualChannel(ccsds::VC2, common::VC2_QUEUE_SIZE, objects::CCSDS_HANDLER); ccsdsHandler->addVirtualChannel(ccsds::VC2, vc); - vc = new VirtualChannel(ccsds::VC3, common::VC3_QUEUE_SIZE); + vc = new VirtualChannel(ccsds::VC3, common::VC3_QUEUE_SIZE, objects::CCSDS_HANDLER); ccsdsHandler->addVirtualChannel(ccsds::VC3, vc); GpioCookie* gpioCookiePdec = new GpioCookie; diff --git a/bsp_q7s/devices/PlocMemoryDumper.cpp b/bsp_q7s/devices/PlocMemoryDumper.cpp index c7ba58bd..1d5dce85 100644 --- a/bsp_q7s/devices/PlocMemoryDumper.cpp +++ b/bsp_q7s/devices/PlocMemoryDumper.cpp @@ -10,7 +10,9 @@ PlocMemoryDumper::PlocMemoryDumper(object_id_t objectId) : SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) { - commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); + auto mqArgs = MqArgs(this->getObjectId()); + commandQueue = QueueFactory::instance()->createMessageQueue( + QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); } PlocMemoryDumper::~PlocMemoryDumper() {} diff --git a/bsp_q7s/devices/PlocUpdater.cpp b/bsp_q7s/devices/PlocUpdater.cpp index 1478fbb8..b1d7f0c9 100644 --- a/bsp_q7s/devices/PlocUpdater.cpp +++ b/bsp_q7s/devices/PlocUpdater.cpp @@ -8,7 +8,9 @@ PlocUpdater::PlocUpdater(object_id_t objectId) : SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) { - commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); + auto mqArgs = MqArgs(this->getObjectId()); + commandQueue = QueueFactory::instance()->createMessageQueue( + QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); } PlocUpdater::~PlocUpdater() {} diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp index 71df6b0b..e5601ac0 100644 --- a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp @@ -44,7 +44,9 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, if (strHelper == nullptr) { sif::error << "StarTrackerHandler: Invalid str image loader" << std::endl; } - eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5); + auto mqArgs = MqArgs(this->getObjectId()); + eventQueue = QueueFactory::instance()->createMessageQueue( + EventMessage::EVENT_MESSAGE_SIZE * 5, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); } StarTrackerHandler::~StarTrackerHandler() {} diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 8b5f85c2..7a4a791c 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -11,7 +11,9 @@ FileSystemHandler::FileSystemHandler(object_id_t fileSystemHandler) : SystemObject(fileSystemHandler) { - mq = QueueFactory::instance()->createMessageQueue(FS_MAX_QUEUE_SIZE); + auto mqArgs = MqArgs(this->getObjectId()); + mq = QueueFactory::instance()->createMessageQueue(FS_MAX_QUEUE_SIZE, + MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); } FileSystemHandler::~FileSystemHandler() { QueueFactory::instance()->deleteMessageQueue(mq); } diff --git a/common/config/devConf.h b/common/config/devConf.h index 78681ec7..deea6aa2 100644 --- a/common/config/devConf.h +++ b/common/config/devConf.h @@ -23,7 +23,13 @@ static constexpr uint32_t DEFAULT_L3G_SPEED = 976'000; 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; +/** + * Some MAX1227 could not be reached with frequencies around 4 MHz. Maybe this is caused by + * the decoder and buffer circuits. Thus frequency is here defined to 1 MHz. + */ +static const uint32_t SUS_MAX1227_SPI_FREQ = 976'000; + +static constexpr uint32_t DEFAULT_MAX_1227_SPEED = 976'000; static constexpr spi::SpiModes DEFAULT_MAX_1227_MODE = spi::SpiModes::MODE_3; static constexpr uint32_t DEFAULT_ADIS16507_SPEED = 976'000; diff --git a/fsfw b/fsfw index 32a9e0c7..19f8e41c 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 32a9e0c7044665f0265c10108c8d62d45c047769 +Subproject commit 19f8e41c7f2523d3684ebddd393e3a7700861328 diff --git a/linux/boardtest/UartTestClass.cpp b/linux/boardtest/UartTestClass.cpp index b8e7da10..1f8c2563 100644 --- a/linux/boardtest/UartTestClass.cpp +++ b/linux/boardtest/UartTestClass.cpp @@ -1,16 +1,11 @@ #include "UartTestClass.h" +#include // Error integer and strerror() function +#include // Contains file controls like O_RDWR #include -#if defined(RASPBERRY_PI) -#include "rpiConfig.h" -#elif defined(XIPHOS_Q7S) -#include "q7sConfig.h" -#endif - -#include // Error integer and strerror() function -#include // Contains file controls like O_RDWR #include // write(), read(), close() +#include "OBSWConfig.h" #include "fsfw/globalfunctions/CRC.h" #include "fsfw/globalfunctions/DleEncoder.h" #include "fsfw/globalfunctions/arrayprinter.h" @@ -42,7 +37,7 @@ ReturnValue_t UartTestClass::performPeriodicAction() { } void UartTestClass::gpsInit() { -#if RPI_TEST_GPS_DEVICE == 1 +#if RPI_TEST_GPS_HANDLER == 1 int result = lwgps_init(&gpsData); if (result == 0) { sif::warning << "lwgps_init error: " << result << std::endl; @@ -90,7 +85,7 @@ void UartTestClass::gpsInit() { } void UartTestClass::gpsPeriodic() { -#if RPI_TEST_GPS_DEVICE == 1 +#if RPI_TEST_GPS_HANDLER == 1 int bytesRead = 0; do { bytesRead = read(serialPort, reinterpret_cast(recBuf.data()), @@ -129,7 +124,7 @@ void UartTestClass::gpsPeriodic() { void UartTestClass::scexInit() { #if defined(RASPBERRY_PI) - std::string devname = "/dev/ttyUSB1"; + std::string devname = "/dev/serial0"; #else std::string devname = "/dev/ul-scex"; #endif @@ -156,6 +151,13 @@ void UartTestClass::scexInit() { tty.c_cc[VTIME] = 1; // In units of 0.1 seconds tty.c_cc[VMIN] = 255; // Read up to 255 bytes + // Q7S UART Lite has fixed baud rate. For other linux systems, set baud rate here. +#if !defined(XIPHOS_Q7S) + if (cfsetispeed(&tty, B57600) != 0) { + sif::warning << "UartTestClass::scexInit: Setting baud rate failed" << std::endl; + } +#endif + if (tcsetattr(serialPort, TCSANOW, &tty) != 0) { sif::warning << "tcsetattr call failed with error [" << errno << ", " << strerror(errno) << std::endl; @@ -165,37 +167,12 @@ void UartTestClass::scexInit() { } void UartTestClass::scexPeriodic() { - auto dleEncoder = DleEncoder(); - std::array tmpCmdBuf = {}; - // Send ping command - tmpCmdBuf[0] = scex::CMD_PING; - // These two fields are the packet counter and the total packet count. Those are 1 and 1 for each - // telecommand so far - tmpCmdBuf[1] = 1; - tmpCmdBuf[2] = 1; - uint16_t userDataLen = 0; - tmpCmdBuf[3] = (userDataLen >> 8) & 0xff; - tmpCmdBuf[4] = userDataLen & 0xff; - uint16_t crc = CRC::crc16ccitt(tmpCmdBuf.data(), 5); - tmpCmdBuf[5] = (crc >> 8) & 0xff; - tmpCmdBuf[6] = crc & 0xff; - - size_t encodedLen = 0; - ReturnValue_t result = - dleEncoder.encode(tmpCmdBuf.data(), 7, cmdBuf.data(), cmdBuf.size(), &encodedLen, true); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "UartTestClass::scexInit: Encoding failed" << std::endl; + sif::info << "UartTestClass::scexInit: Sending ping command to SCEX" << std::endl; + int result = prepareScexPing(); + if (result != 0) { return; - } - arrayprinter::print(cmdBuf.data(), 9); + }; size_t bytesWritten = write(serialPort, cmdBuf.data(), encodedLen); - - if (bytesWritten != encodedLen) { - sif::warning << "Sending ping command to solar experiment failed" << std::endl; - } - - TaskFactory::delayTask(20); - bytesWritten = write(serialPort, cmdBuf.data(), encodedLen); if (bytesWritten != encodedLen) { sif::warning << "Sending ping command to solar experiment failed" << std::endl; } @@ -210,12 +187,35 @@ void UartTestClass::scexPeriodic() { << ", " << strerror(errno) << "]" << std::endl; break; } else if (bytesRead >= static_cast(recBuf.size())) { - sif::debug << "UartTestClass::performPeriodicAction: " - "recv buffer might not be large enough" + sif::debug << "UartTestClass::performPeriodicAction: recv buffer might not be large enough" << std::endl; } else if (bytesRead > 0) { - sif::info << "Received " << bytesRead << " from the Solar Cell Experiment:" << std::endl; - arrayprinter::print(recBuf.data(), bytesRead); + sif::info << "Received " << bytesRead + << " bytes from the Solar Cell Experiment:" << std::endl; + arrayprinter::print(recBuf.data(), bytesRead, OutputType::HEX, false); } } while (bytesRead > 0); } + +int UartTestClass::prepareScexPing() { + std::array tmpCmdBuf = {}; + // Send ping command + tmpCmdBuf[0] = scex::CMD_PING; + // These two fields are the packet counter and the total packet count. Those are 1 and 1 for each + // telecommand so far + tmpCmdBuf[1] = 1; + tmpCmdBuf[2] = 1; + uint16_t userDataLen = 0; + tmpCmdBuf[3] = (userDataLen >> 8) & 0xff; + tmpCmdBuf[4] = userDataLen & 0xff; + uint16_t crc = CRC::crc16ccitt(tmpCmdBuf.data(), 5); + tmpCmdBuf[5] = (crc >> 8) & 0xff; + tmpCmdBuf[6] = crc & 0xff; + ReturnValue_t result = + dleEncoder.encode(tmpCmdBuf.data(), 7, cmdBuf.data(), cmdBuf.size(), &encodedLen, true); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "UartTestClass::scexInit: Encoding failed" << std::endl; + return -1; + } + return 0; +} diff --git a/linux/boardtest/UartTestClass.h b/linux/boardtest/UartTestClass.h index 33194598..786d01ce 100644 --- a/linux/boardtest/UartTestClass.h +++ b/linux/boardtest/UartTestClass.h @@ -1,6 +1,7 @@ #ifndef LINUX_BOARDTEST_UARTTESTCLASS_H_ #define LINUX_BOARDTEST_UARTTESTCLASS_H_ +#include #include // Contains POSIX terminal control definitions #include @@ -28,7 +29,10 @@ class UartTestClass : public TestTask { void scexInit(); void scexPeriodic(); + int prepareScexPing(); TestModes mode = TestModes::GPS; + DleEncoder dleEncoder = DleEncoder(); + size_t encodedLen = 0; lwgps_t gpsData = {}; struct termios tty = {}; int serialPort = 0; diff --git a/linux/devices/CMakeLists.txt b/linux/devices/CMakeLists.txt index 8d3272a1..e50b7626 100644 --- a/linux/devices/CMakeLists.txt +++ b/linux/devices/CMakeLists.txt @@ -1,4 +1,3 @@ target_sources(${OBSW_NAME} PRIVATE SolarArrayDeploymentHandler.cpp - SusHandler.cpp ) diff --git a/linux/devices/SusHandler.cpp b/linux/devices/SusHandler.cpp deleted file mode 100644 index 44755f41..00000000 --- a/linux/devices/SusHandler.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include "SusHandler.h" - -#include -#include - -#include "OBSWConfig.h" - -SusHandler::SusHandler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie, - LinuxLibgpioIF *gpioComIF, gpioId_t chipSelectId) - : DeviceHandlerBase(objectId, comIF, comCookie), - gpioComIF(gpioComIF), - chipSelectId(chipSelectId), - dataset(this) { - if (comCookie == NULL) { - sif::error << "SusHandler: Invalid com cookie" << std::endl; - } - if (gpioComIF == NULL) { - sif::error << "SusHandler: Invalid GpioComIF" << std::endl; - } -} - -SusHandler::~SusHandler() {} - -ReturnValue_t SusHandler::performOperation(uint8_t counter) { - if (counter != FIRST_WRITE) { - DeviceHandlerBase::performOperation(counter); - return RETURN_OK; - } - - if (mode != MODE_NORMAL) { - DeviceHandlerBase::performOperation(DeviceHandlerIF::SEND_WRITE); - return RETURN_OK; - } - - /* If device is in normale mode the communication sequence is initiated here */ - if (communicationStep == CommunicationStep::IDLE) { - communicationStep = CommunicationStep::WRITE_SETUP; - } - - DeviceHandlerBase::performOperation(DeviceHandlerIF::SEND_WRITE); - - return RETURN_OK; -} - -ReturnValue_t SusHandler::initialize() { - ReturnValue_t result = RETURN_OK; - result = DeviceHandlerBase::initialize(); - if (result != RETURN_OK) { - return result; - } - auto spiComIF = dynamic_cast(communicationInterface); - if (spiComIF == nullptr) { - sif::debug << "SusHandler::initialize: Invalid communication interface" << std::endl; - return ObjectManagerIF::CHILD_INIT_FAILED; - } - spiMutex = spiComIF->getMutex(); - if (spiMutex == nullptr) { - sif::debug << "SusHandler::initialize: Failed to get spi mutex" << std::endl; - return ObjectManagerIF::CHILD_INIT_FAILED; - } - return RETURN_OK; -} - -void SusHandler::doStartUp() { -#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1 - setMode(MODE_NORMAL); -#else - setMode(_MODE_TO_ON); -#endif -} - -void SusHandler::doShutDown() { setMode(_MODE_POWER_DOWN); } - -ReturnValue_t SusHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) { - if (communicationStep == CommunicationStep::IDLE) { - return NOTHING_TO_SEND; - } - - if (communicationStep == CommunicationStep::WRITE_SETUP) { - *id = SUS::WRITE_SETUP; - communicationStep = CommunicationStep::START_CONVERSIONS; - } else if (communicationStep == CommunicationStep::START_CONVERSIONS) { - *id = SUS::START_CONVERSIONS; - communicationStep = CommunicationStep::READ_CONVERSIONS; - } else if (communicationStep == CommunicationStep::READ_CONVERSIONS) { - *id = SUS::READ_CONVERSIONS; - communicationStep = CommunicationStep::IDLE; - } - return buildCommandFromCommand(*id, nullptr, 0); -} - -ReturnValue_t SusHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) { - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t SusHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, - const uint8_t *commandData, - size_t commandDataLen) { - switch (deviceCommand) { - case (SUS::WRITE_SETUP): { - /** - * The sun sensor ADC is shutdown when CS is pulled high, so each time requesting a - * measurement the setup has to be rewritten. There must also be a little delay between - * the transmission of the setup byte and the first conversion. Thus the conversion - * will be performed in an extra step. - * Because the chip select is driven manually by the SusHandler the SPI bus must be - * protected with a mutex here. - */ - ReturnValue_t result = spiMutex->lockMutex(timeoutType, timeoutMs); - if (result == MutexIF::MUTEX_TIMEOUT) { - sif::error << "SusHandler::buildCommandFromCommand: Mutex timeout" << std::endl; - return ERROR_LOCK_MUTEX; - } else if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "SusHandler::buildCommandFromCommand: Failed to lock spi mutex" << std::endl; - return ERROR_LOCK_MUTEX; - } - - gpioComIF->pullLow(chipSelectId); - cmdBuffer[0] = SUS::SETUP; - rawPacket = cmdBuffer; - rawPacketLen = 1; - return RETURN_OK; - } - case (SUS::START_CONVERSIONS): { - std::memset(cmdBuffer, 0, sizeof(cmdBuffer)); - cmdBuffer[0] = SUS::CONVERSION; - rawPacket = cmdBuffer; - rawPacketLen = 2; - return RETURN_OK; - } - case (SUS::READ_CONVERSIONS): { - std::memset(cmdBuffer, 0, sizeof(cmdBuffer)); - rawPacket = cmdBuffer; - rawPacketLen = SUS::SIZE_READ_CONVERSIONS; - return RETURN_OK; - } - default: - return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; - } - return HasReturnvaluesIF::RETURN_FAILED; -} - -void SusHandler::fillCommandAndReplyMap() { - this->insertInCommandMap(SUS::WRITE_SETUP); - this->insertInCommandMap(SUS::START_CONVERSIONS); - this->insertInCommandAndReplyMap(SUS::READ_CONVERSIONS, 1, &dataset, SUS::SIZE_READ_CONVERSIONS); -} - -ReturnValue_t SusHandler::scanForReply(const uint8_t *start, size_t remainingSize, - DeviceCommandId_t *foundId, size_t *foundLen) { - *foundId = this->getPendingCommand(); - *foundLen = remainingSize; - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { - switch (id) { - case SUS::READ_CONVERSIONS: { - PoolReadGuard readSet(&dataset); - dataset.temperatureCelcius = (*(packet) << 8 | *(packet + 1)) * 0.125; - dataset.ain0 = (*(packet + 2) << 8 | *(packet + 3)); - dataset.ain1 = (*(packet + 4) << 8 | *(packet + 5)); - dataset.ain2 = (*(packet + 6) << 8 | *(packet + 7)); - dataset.ain3 = (*(packet + 8) << 8 | *(packet + 9)); - dataset.ain4 = (*(packet + 10) << 8 | *(packet + 11)); - dataset.ain5 = (*(packet + 12) << 8 | *(packet + 13)); -#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_SUS - sif::info << "SUS object id 0x" << std::hex << this->getObjectId() - << ", Temperature: " << dataset.temperatureCelcius << " °C" << std::endl; - sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN0: " << std::dec - << dataset.ain0 << std::endl; - sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN1: " << std::dec - << dataset.ain1 << std::endl; - sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN2: " << std::dec - << dataset.ain2 << std::endl; - sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN3: " << std::dec - << dataset.ain3 << std::endl; - sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN4: " << std::dec - << dataset.ain4 << std::endl; - sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN5: " << std::dec - << dataset.ain5 << std::endl; -#endif - /** SUS can now be shutdown and thus the SPI bus released again */ - gpioComIF->pullHigh(chipSelectId); - ReturnValue_t result = spiMutex->unlockMutex(); - if (result != RETURN_OK) { - sif::error << "SusHandler::interpretDeviceReply: Failed to unlock spi mutex" << std::endl; - return ERROR_UNLOCK_MUTEX; - } - break; - } - default: { - sif::debug << "SusHandler::interpretDeviceReply: Unknown reply id" << std::endl; - return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; - } - } - return HasReturnvaluesIF::RETURN_OK; -} - -void SusHandler::setNormalDatapoolEntriesInvalid() {} - -uint32_t SusHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 1000; } - -ReturnValue_t SusHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, - LocalDataPoolManager &poolManager) { - localDataPoolMap.emplace(SUS::TEMPERATURE_C, new PoolEntry({0.0})); - localDataPoolMap.emplace(SUS::AIN0, new PoolEntry({0})); - localDataPoolMap.emplace(SUS::AIN1, new PoolEntry({0})); - localDataPoolMap.emplace(SUS::AIN2, new PoolEntry({0})); - localDataPoolMap.emplace(SUS::AIN3, new PoolEntry({0})); - localDataPoolMap.emplace(SUS::AIN4, new PoolEntry({0})); - localDataPoolMap.emplace(SUS::AIN5, new PoolEntry({0})); - return HasReturnvaluesIF::RETURN_OK; -} diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 9ddff5d3..38717c37 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -1,13 +1,13 @@ #include "pollingSequenceFactory.h" +#include "OBSWConfig.h" +#include "objects/systemObjectList.h" #include #include #include #include -#include "OBSWConfig.h" -#include "linux/devices/SusHandler.h" -#include "objects/systemObjectList.h" + ReturnValue_t pst::pstGpio(FixedTimeslotTaskIF *thisSequence) { // Length of a communication cycle diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index b17812e6..651ba993 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -69,7 +69,7 @@ void ObjectFactory::produceGenericObjects() { objects::CCSDS_PACKET_DISTRIBUTOR); // Every TM packet goes through this funnel - new TmFunnel(objects::TM_FUNNEL); + new TmFunnel(objects::TM_FUNNEL, 50); // PUS service stack new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION, apid::EIVE_OBSW, @@ -79,7 +79,7 @@ void ObjectFactory::produceGenericObjects() { new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, apid::EIVE_OBSW, pus::PUS_SERVICE_3); new Service5EventReporting(objects::PUS_SERVICE_5_EVENT_REPORTING, apid::EIVE_OBSW, - pus::PUS_SERVICE_5, 50); + pus::PUS_SERVICE_5, 15, 45); new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, apid::EIVE_OBSW, pus::PUS_SERVICE_8, 3, 60); new Service9TimeManagement(objects::PUS_SERVICE_9_TIME_MGMT, apid::EIVE_OBSW, pus::PUS_SERVICE_9); diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 680cc64c..dc4b6308 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -17,4 +17,5 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE GyroADIS1650XHandler.cpp RwHandler.cpp max1227.cpp + SusHandler.cpp ) diff --git a/mission/devices/HeaterHandler.cpp b/mission/devices/HeaterHandler.cpp index 572810bd..255ba6ec 100644 --- a/mission/devices/HeaterHandler.cpp +++ b/mission/devices/HeaterHandler.cpp @@ -16,8 +16,9 @@ HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_ mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), actionHelper(this, nullptr) { + auto mqArgs = MqArgs(setObjectId_, static_cast(this)); commandQueue = QueueFactory::instance()->createMessageQueue( - cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); + cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); } HeaterHandler::~HeaterHandler() {} diff --git a/mission/devices/SusHandler.cpp b/mission/devices/SusHandler.cpp new file mode 100644 index 00000000..9c55409e --- /dev/null +++ b/mission/devices/SusHandler.cpp @@ -0,0 +1,232 @@ +#include "SusHandler.h" + +#include +#include + +#include "OBSWConfig.h" + +SusHandler::SusHandler(object_id_t objectId, uint8_t susIdx, object_id_t comIF, CookieIF *comCookie) + : DeviceHandlerBase(objectId, comIF, comCookie), divider(5), dataset(this), susIdx(susIdx) {} + +SusHandler::~SusHandler() {} + +ReturnValue_t SusHandler::initialize() { + ReturnValue_t result = RETURN_OK; + result = DeviceHandlerBase::initialize(); + if (result != RETURN_OK) { + return result; + } + return RETURN_OK; +} + +void SusHandler::doStartUp() { + if (comState == ComStates::IDLE) { + comState = ComStates::WRITE_SETUP; + commandExecuted = false; + } + if (comState == ComStates::WRITE_SETUP) { + if (commandExecuted) { + if (goToNormalModeImmediately) { + setMode(MODE_NORMAL); + } else { + setMode(_MODE_TO_ON); + } + commandExecuted = false; + if (clkMode == ClkModes::INT_CLOCKED) { + comState = ComStates::START_INT_CLOCKED_CONVERSIONS; + } else { + comState = ComStates::EXT_CLOCKED_CONVERSIONS; + } + } + } +} + +void SusHandler::doShutDown() { setMode(_MODE_POWER_DOWN); } + +ReturnValue_t SusHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) { + switch (comState) { + case (ComStates::IDLE): { + break; + } + case (ComStates::WRITE_SETUP): { + *id = SUS::WRITE_SETUP; + return buildCommandFromCommand(*id, nullptr, 0); + } + case (ComStates::EXT_CLOCKED_CONVERSIONS): { + *id = SUS::READ_EXT_TIMED_CONVERSIONS; + return buildCommandFromCommand(*id, nullptr, 0); + } + case (ComStates::START_INT_CLOCKED_CONVERSIONS): { + *id = SUS::START_INT_TIMED_CONVERSIONS; + comState = ComStates::READ_INT_CLOCKED_CONVERSIONS; + return buildCommandFromCommand(*id, nullptr, 0); + } + case (ComStates::READ_INT_CLOCKED_CONVERSIONS): { + *id = SUS::READ_INT_TIMED_CONVERSIONS; + comState = ComStates::START_INT_CLOCKED_CONVERSIONS; + return buildCommandFromCommand(*id, nullptr, 0); + } + case (ComStates::EXT_CLOCKED_TEMP): { + *id = SUS::READ_EXT_TIMED_TEMPS; + return buildCommandFromCommand(*id, nullptr, 0); + } + } + return NOTHING_TO_SEND; +} + +ReturnValue_t SusHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) { + if (comState == ComStates::WRITE_SETUP) { + *id = SUS::WRITE_SETUP; + return buildCommandFromCommand(*id, nullptr, 0); + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SusHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t *commandData, + size_t commandDataLen) { + using namespace max1227; + switch (deviceCommand) { + case (SUS::WRITE_SETUP): { + if (clkMode == ClkModes::INT_CLOCKED) { + cmdBuffer[0] = SUS::SETUP_INT_CLOKED; + } else { + cmdBuffer[0] = SUS::SETUP_EXT_CLOCKED; + } + + rawPacket = cmdBuffer; + rawPacketLen = 1; + break; + } + case (SUS::START_INT_TIMED_CONVERSIONS): { + std::memset(cmdBuffer, 0, sizeof(cmdBuffer)); + cmdBuffer[0] = max1227::buildResetByte(true); + cmdBuffer[1] = SUS::CONVERSION; + rawPacket = cmdBuffer; + rawPacketLen = 2; + break; + } + case (SUS::READ_INT_TIMED_CONVERSIONS): { + std::memset(cmdBuffer, 0, sizeof(cmdBuffer)); + rawPacket = cmdBuffer; + rawPacketLen = SUS::SIZE_READ_INT_CONVERSIONS; + break; + } + case (SUS::READ_EXT_TIMED_CONVERSIONS): { + std::memset(cmdBuffer, 0, sizeof(cmdBuffer)); + rawPacket = cmdBuffer; + for (uint8_t idx = 0; idx < 6; idx++) { + cmdBuffer[idx * 2] = buildConvByte(ScanModes::N_ONCE, idx, false); + cmdBuffer[idx * 2 + 1] = 0; + } + cmdBuffer[12] = 0x00; + rawPacketLen = SUS::SIZE_READ_EXT_CONVERSIONS; + break; + } + case (SUS::READ_EXT_TIMED_TEMPS): { + cmdBuffer[0] = buildConvByte(ScanModes::N_ONCE, 0, true); + std::memset(cmdBuffer + 1, 0, 24); + rawPacket = cmdBuffer; + rawPacketLen = 25; + break; + } + default: + return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; + } + return HasReturnvaluesIF::RETURN_OK; +} + +void SusHandler::fillCommandAndReplyMap() { + insertInCommandAndReplyMap(SUS::WRITE_SETUP, 1); + insertInCommandAndReplyMap(SUS::START_INT_TIMED_CONVERSIONS, 1); + insertInCommandAndReplyMap(SUS::READ_INT_TIMED_CONVERSIONS, 1, &dataset, + SUS::SIZE_READ_INT_CONVERSIONS); + insertInCommandAndReplyMap(SUS::READ_EXT_TIMED_CONVERSIONS, 1, &dataset, + SUS::SIZE_READ_EXT_CONVERSIONS); + insertInCommandAndReplyMap(SUS::READ_EXT_TIMED_TEMPS, 1); +} + +ReturnValue_t SusHandler::scanForReply(const uint8_t *start, size_t remainingSize, + DeviceCommandId_t *foundId, size_t *foundLen) { + *foundId = this->getPendingCommand(); + *foundLen = remainingSize; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { + switch (id) { + case SUS::WRITE_SETUP: { + if (mode == _MODE_START_UP) { + commandExecuted = true; + } + return HasReturnvaluesIF::RETURN_OK; + } + case SUS::START_INT_TIMED_CONVERSIONS: { + return HasReturnvaluesIF::RETURN_OK; + } + case SUS::READ_INT_TIMED_CONVERSIONS: { + PoolReadGuard readSet(&dataset); + + dataset.temperatureCelcius = max1227::getTemperature(((packet[0] & 0x0f) << 8) | packet[1]); + for (uint8_t idx = 0; idx < 6; idx++) { + dataset.channels[idx] = packet[idx * 2 + 2] << 8 | packet[idx * 2 + 3]; + } + printDataset(); + break; + } + case (SUS::READ_EXT_TIMED_CONVERSIONS): { + PoolReadGuard readSet(&dataset); + for (uint8_t idx = 0; idx < 6; idx++) { + dataset.channels[idx] = packet[idx * 2 + 1] << 8 | packet[idx * 2 + 2]; + } + // Read temperature in next read cycle + if (clkMode == ClkModes::EXT_CLOCKED_WITH_TEMP) { + comState = ComStates::EXT_CLOCKED_TEMP; + } + printDataset(); + break; + } + case (SUS::READ_EXT_TIMED_TEMPS): { + PoolReadGuard readSet(&dataset); + dataset.temperatureCelcius = max1227::getTemperature(((packet[23] & 0x0f) << 8) | packet[24]); + comState = ComStates::EXT_CLOCKED_CONVERSIONS; + break; + } + default: { + sif::debug << "SusHandler::interpretDeviceReply: Unknown reply id" << std::endl; + return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; + } + } + return HasReturnvaluesIF::RETURN_OK; +} + +uint32_t SusHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 2000; } + +ReturnValue_t SusHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, + LocalDataPoolManager &poolManager) { + localDataPoolMap.emplace(SUS::TEMPERATURE_C, &tempC); + localDataPoolMap.emplace(SUS::CHANNEL_VEC, &channelVec); + return HasReturnvaluesIF::RETURN_OK; +} + +void SusHandler::setToGoToNormalMode(bool enable) { this->goToNormalModeImmediately = enable; } + +void SusHandler::printDataset() { + if (periodicPrintout) { + if (divider.checkAndIncrement()) { + sif::info << "SUS ADC " << static_cast(susIdx) << " hex [" << std::setfill('0') << std::hex; + for (uint8_t idx = 0; idx < 6; idx++) { + sif::info << std::setw(3) << dataset.channels[idx]; + if (idx < 6 - 1) { + sif::info << ","; + } + } + sif::info << "] | T[C] " << std::dec << dataset.temperatureCelcius.value << std::endl; + } + } +} + +void SusHandler::enablePeriodicPrintout(bool enable, uint8_t divider) { + this->periodicPrintout = enable; + this->divider.setDivider(divider); +} diff --git a/linux/devices/SusHandler.h b/mission/devices/SusHandler.h similarity index 58% rename from linux/devices/SusHandler.h rename to mission/devices/SusHandler.h index 0eab5fd0..18587c71 100644 --- a/linux/devices/SusHandler.h +++ b/mission/devices/SusHandler.h @@ -2,16 +2,18 @@ #define MISSION_DEVICES_SUSHANDLER_H_ #include -#include #include "devicedefinitions/SusDefinitions.h" +#include "fsfw/globalfunctions/PeriodicOperationDivider.h" +#include "mission/devices/max1227.h" /** - * @brief This is the device handler class for the SUS sensor. The sensor is - * based on the MAX1227 ADC. Details about the SUS electronic can be found at - * https://egit.irs.uni-stuttgart.de/eive/eive_dokumente/src/branch/master/400_Raumsegment/443_SunSensorDocumentation/release + * @brief This is the device handler class for the SUS sensor based on the MAX1227 ADC. * - * @details Datasheet of MAX1227: https://datasheets.maximintegrated.com/en/ds/MAX1227-MAX1231.pdf + * @details + * Datasheet of MAX1227: https://datasheets.maximintegrated.com/en/ds/MAX1227-MAX1231.pdf + * Details about the SUS electronic can be found at + * https://egit.irs.uni-stuttgart.de/eive/eive_dokumente/src/branch/master/400_Raumsegment/443_SunSensorDocumentation/release * * @note When adding a SusHandler to the polling sequence table make sure to add a slot with * the executionStep FIRST_WRITE. Otherwise the communication sequence will never be @@ -21,15 +23,17 @@ */ class SusHandler : public DeviceHandlerBase { public: + enum ClkModes { INT_CLOCKED, EXT_CLOCKED, EXT_CLOCKED_WITH_TEMP }; + static const uint8_t FIRST_WRITE = 7; - SusHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, - LinuxLibgpioIF* gpioComIF, gpioId_t chipSelectId); + SusHandler(object_id_t objectId, uint8_t susIdx, object_id_t comIF, CookieIF* comCookie); virtual ~SusHandler(); - virtual ReturnValue_t performOperation(uint8_t counter) override; + void enablePeriodicPrintout(bool enable, uint8_t divider); virtual ReturnValue_t initialize() override; + void setToGoToNormalMode(bool enable); protected: void doStartUp() override; @@ -42,7 +46,6 @@ class SusHandler : public DeviceHandlerBase { 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; @@ -53,19 +56,34 @@ class SusHandler : public DeviceHandlerBase { static const ReturnValue_t ERROR_UNLOCK_MUTEX = MAKE_RETURN_CODE(0xA0); static const ReturnValue_t ERROR_LOCK_MUTEX = MAKE_RETURN_CODE(0xA1); - enum class CommunicationStep { IDLE, WRITE_SETUP, START_CONVERSIONS, READ_CONVERSIONS }; + enum class ComStates { + IDLE, + WRITE_SETUP, + EXT_CLOCKED_CONVERSIONS, + EXT_CLOCKED_TEMP, + START_INT_CLOCKED_CONVERSIONS, + READ_INT_CLOCKED_CONVERSIONS + }; - LinuxLibgpioIF* gpioComIF = nullptr; - - gpioId_t chipSelectId = gpio::NO_GPIO; + bool periodicPrintout = false; + PeriodicOperationDivider divider; + bool goToNormalModeImmediately = false; + bool commandExecuted = false; SUS::SusDataset dataset; + // Read temperature in each alternating communication step when using + // externally clocked mode + ClkModes clkMode = ClkModes::INT_CLOCKED; + PoolEntry tempC = PoolEntry({0.0}); + PoolEntry channelVec = PoolEntry({0, 0, 0, 0, 0, 0}); + uint8_t susIdx = 0; uint8_t cmdBuffer[SUS::MAX_CMD_SIZE]; - CommunicationStep communicationStep = CommunicationStep::IDLE; + ComStates comState = ComStates::IDLE; MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; uint32_t timeoutMs = 20; + void printDataset(); MutexIF* spiMutex = nullptr; }; diff --git a/linux/devices/devicedefinitions/SusDefinitions.h b/mission/devices/devicedefinitions/SusDefinitions.h similarity index 64% rename from linux/devices/devicedefinitions/SusDefinitions.h rename to mission/devices/devicedefinitions/SusDefinitions.h index 2a45ebc5..973ae051 100644 --- a/linux/devices/devicedefinitions/SusDefinitions.h +++ b/mission/devices/devicedefinitions/SusDefinitions.h @@ -8,25 +8,23 @@ namespace SUS { -/** - * Some MAX1227 could not be reached with frequencies around 4 MHz. Maybe this is caused by - * the decoder and buffer circuits. Thus frequency is here defined to 1 MHz. - */ -static const uint32_t MAX1227_SPI_FREQ = 1000000; - static const DeviceCommandId_t NONE = 0x0; // Set when no command is pending -static const DeviceCommandId_t WRITE_SETUP = 0x1; +static const DeviceCommandId_t WRITE_SETUP = 1; /** * This command initiates the ADC conversion for all channels including the internal * temperature sensor. */ -static const DeviceCommandId_t START_CONVERSIONS = 0x2; +static const DeviceCommandId_t START_INT_TIMED_CONVERSIONS = 2; /** * This command reads the internal fifo which holds the temperature and the channel * conversions. */ -static const DeviceCommandId_t READ_CONVERSIONS = 0x3; +static constexpr DeviceCommandId_t READ_INT_TIMED_CONVERSIONS = 3; + +static constexpr DeviceCommandId_t READ_EXT_TIMED_CONVERSIONS = 4; + +static constexpr DeviceCommandId_t READ_EXT_TIMED_TEMPS = 5; /** * @brief This is the configuration byte which will be written to the setup register after @@ -39,7 +37,8 @@ static const DeviceCommandId_t READ_CONVERSIONS = 0x3; * written to the setup register * */ -static const uint8_t SETUP = 0b01101000; +static constexpr uint8_t SETUP_INT_CLOKED = 0b01101000; +static constexpr uint8_t SETUP_EXT_CLOCKED = 0b01111000; /** * @brief This values will always be written to the ADC conversion register to specify the @@ -51,24 +50,18 @@ static const uint8_t SETUP = 0b01101000; */ static const uint8_t CONVERSION = 0b10101001; -static const uint8_t SUS_DATA_SET_ID = READ_CONVERSIONS; +static const uint8_t SUS_DATA_SET_ID = READ_INT_TIMED_CONVERSIONS; /** Size of data replies. Temperature and 6 channel convesions (AIN0 - AIN5) */ -static const uint8_t SIZE_READ_CONVERSIONS = 14; +static const uint8_t SIZE_READ_INT_CONVERSIONS = 14; +// 6 * conv byte, 6 * 0 and one trailing zero +static constexpr uint8_t SIZE_READ_EXT_CONVERSIONS = 13; -static const uint8_t MAX_CMD_SIZE = SIZE_READ_CONVERSIONS; +static const uint8_t MAX_CMD_SIZE = 32; static const uint8_t POOL_ENTRIES = 7; -enum Max1227PoolIds : lp_id_t { - TEMPERATURE_C, - AIN0, - AIN1, - AIN2, - AIN3, - AIN4, - AIN5, -}; +enum Max1227PoolIds : lp_id_t { TEMPERATURE_C, CHANNEL_VEC }; class SusDataset : public StaticLocalDataSet { public: @@ -77,12 +70,7 @@ class SusDataset : public StaticLocalDataSet { SusDataset(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, SUS_DATA_SET_ID)) {} lp_var_t temperatureCelcius = lp_var_t(sid.objectId, TEMPERATURE_C, this); - lp_var_t ain0 = lp_var_t(sid.objectId, AIN0, this); - lp_var_t ain1 = lp_var_t(sid.objectId, AIN1, this); - lp_var_t ain2 = lp_var_t(sid.objectId, AIN2, this); - lp_var_t ain3 = lp_var_t(sid.objectId, AIN3, this); - lp_var_t ain4 = lp_var_t(sid.objectId, AIN4, this); - lp_var_t ain5 = lp_var_t(sid.objectId, AIN5, this); + lp_vec_t channels = lp_vec_t(sid.objectId, CHANNEL_VEC, this); }; } // namespace SUS diff --git a/mission/tmtc/CCSDSHandler.cpp b/mission/tmtc/CCSDSHandler.cpp index 35978627..d6c2367b 100644 --- a/mission/tmtc/CCSDSHandler.cpp +++ b/mission/tmtc/CCSDSHandler.cpp @@ -23,7 +23,9 @@ CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t enTxClock(enTxClock), enTxData(enTxData) { commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); - eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 2); + auto mqArgs = MqArgs(objectId, static_cast(this)); + eventQueue = + QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs); } CCSDSHandler::~CCSDSHandler() {} diff --git a/mission/tmtc/CCSDSHandler.h b/mission/tmtc/CCSDSHandler.h index 4f62102c..284cbcba 100644 --- a/mission/tmtc/CCSDSHandler.h +++ b/mission/tmtc/CCSDSHandler.h @@ -132,7 +132,7 @@ class CCSDSHandler : public SystemObject, ActionHelper actionHelper; - MessageQueueId_t tcDistributorQueueId; + MessageQueueId_t tcDistributorQueueId = MessageQueueIF::NO_QUEUE; PtmeConfig* ptmeConfig = nullptr; diff --git a/mission/tmtc/VirtualChannel.cpp b/mission/tmtc/VirtualChannel.cpp index 5b9387fd..9d413ca7 100644 --- a/mission/tmtc/VirtualChannel.cpp +++ b/mission/tmtc/VirtualChannel.cpp @@ -7,9 +7,11 @@ #include "fsfw/serviceinterface/ServiceInterfaceStream.h" #include "fsfw/tmtcservices/TmTcMessage.h" -VirtualChannel::VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth) : vcId(vcId) { - tmQueue = QueueFactory::instance()->createMessageQueue(tmQueueDepth, - MessageQueueMessage::MAX_MESSAGE_SIZE); +VirtualChannel::VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth, object_id_t ownerId) + : vcId(vcId) { + auto mqArgs = MqArgs(ownerId, reinterpret_cast(vcId)); + tmQueue = QueueFactory::instance()->createMessageQueue( + tmQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); } ReturnValue_t VirtualChannel::initialize() { diff --git a/mission/tmtc/VirtualChannel.h b/mission/tmtc/VirtualChannel.h index 48cc74a4..c661c4c5 100644 --- a/mission/tmtc/VirtualChannel.h +++ b/mission/tmtc/VirtualChannel.h @@ -24,7 +24,7 @@ class VirtualChannel : public AcceptsTelemetryIF, public HasReturnvaluesIF { * @param vcId The virtual channel id assigned to this object * @param tmQueueDepth Queue depth of queue receiving telemetry from other objects */ - VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth); + VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth, object_id_t ownerId); ReturnValue_t initialize(); MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) override; diff --git a/mission/utility/TmFunnel.cpp b/mission/utility/TmFunnel.cpp index 5577f5fa..e22eabdf 100644 --- a/mission/utility/TmFunnel.cpp +++ b/mission/utility/TmFunnel.cpp @@ -11,10 +11,11 @@ object_id_t TmFunnel::storageDestination = objects::NO_OBJECT; TmFunnel::TmFunnel(object_id_t objectId, uint32_t messageDepth) : SystemObject(objectId), messageDepth(messageDepth) { - tmQueue = QueueFactory::instance()->createMessageQueue(messageDepth, - MessageQueueMessage::MAX_MESSAGE_SIZE); + auto mqArgs = MqArgs(objectId, static_cast(this)); + tmQueue = QueueFactory::instance()->createMessageQueue( + messageDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); storageQueue = QueueFactory::instance()->createMessageQueue( - messageDepth, MessageQueueMessage::MAX_MESSAGE_SIZE); + messageDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); } TmFunnel::~TmFunnel() {}