diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index 84c26605..a4a876a3 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -591,26 +591,18 @@ void ObjectFactory::produce(void* args){ auto rwHandler1 = new RwHandler(objects::RW1, objects::SPI_COM_IF, rw1SpiCookie, gpioComIF, gpioIds::EN_RW1); - (void) rwHandler1; -// rwHandler1->setStartUpImmediately(); rw1SpiCookie->setCallbackArgs(rwHandler1); auto rwHandler2 = new RwHandler(objects::RW2, objects::SPI_COM_IF, rw2SpiCookie, gpioComIF, gpioIds::EN_RW2); -// rwHandler2->setStartUpImmediately(); - (void) rwHandler2; rw2SpiCookie->setCallbackArgs(rwHandler2); auto rwHandler3 = new RwHandler(objects::RW3, objects::SPI_COM_IF, rw3SpiCookie, gpioComIF, gpioIds::EN_RW3); -// rwHandler3->setStartUpImmediately(); - (void) rwHandler3; -// rw3SpiCookie->setCallbackArgs(rwHandler3); + rw3SpiCookie->setCallbackArgs(rwHandler3); auto rwHandler4 = new RwHandler(objects::RW4, objects::SPI_COM_IF, rw4SpiCookie, gpioComIF, gpioIds::EN_RW4); -// (void) rwHandler4; - rwHandler4->setStartUpImmediately(); rw4SpiCookie->setCallbackArgs(rwHandler4); #endif /* TE0720 == 0 */ diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index ce1a7526..a5a439ab 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -52,7 +52,7 @@ debugging. */ #include "OBSWVersion.h" /* Can be used to switch device to NORMAL mode immediately */ -#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 1 +#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 0 #ifdef __cplusplus diff --git a/mission/devices/RwHandler.cpp b/mission/devices/RwHandler.cpp index d423aac1..45c721a8 100644 --- a/mission/devices/RwHandler.cpp +++ b/mission/devices/RwHandler.cpp @@ -20,18 +20,12 @@ RwHandler::~RwHandler() { } void RwHandler::doStartUp() { - switch (startupStep) { - case StartupStep::ENABLE_RW: { - if(gpioComIF->pullHigh(enableGpio) != RETURN_OK) { - sif::debug << "RwHandler::doStartUp: Failed to pull enable gpio to high"; - } - return; - } - case StartupStep::STARTUP_COMPLETE: - break; - default: - return; - } + + internalState = InternalState::GET_RESET_STATUS; + + if(gpioComIF->pullHigh(enableGpio) != RETURN_OK) { + sif::debug << "RwHandler::doStartUp: Failed to pull enable gpio to high"; + } #if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1 setMode(MODE_NORMAL); @@ -44,23 +38,26 @@ void RwHandler::doShutDown() { if(gpioComIF->pullLow(enableGpio) != RETURN_OK) { sif::debug << "RwHandler::doStartUp: Failed to pull enable gpio to low"; } - /** Reset startup step for next doStartUp routine */ - startupStep = StartupStep::ENABLE_RW; } ReturnValue_t RwHandler::buildNormalDeviceCommand(DeviceCommandId_t * id) { - switch (communicationStep) { - case CommunicationStep::GET_RESET_STATUS: + switch (internalState) { + case InternalState::GET_RESET_STATUS: *id = RwDefinitions::GET_LAST_RESET_STATUS; - communicationStep = CommunicationStep::READ_TEMPERATURE; + internalState = InternalState::READ_TEMPERATURE; break; - case CommunicationStep::READ_TEMPERATURE: + case InternalState::CLEAR_RESET_STATUS: + *id = RwDefinitions::CLEAR_LAST_RESET_STATUS; + /** After reset status is cleared, reset status will be polled again for verification */ + internalState = InternalState::GET_RESET_STATUS; + break; + case InternalState::READ_TEMPERATURE: *id = RwDefinitions::GET_TEMPERATURE; - communicationStep = CommunicationStep::GET_RW_SATUS; + internalState = InternalState::GET_RW_SATUS; break; - case CommunicationStep::GET_RW_SATUS: + case InternalState::GET_RW_SATUS: *id = RwDefinitions::GET_RW_STATUS; - communicationStep = CommunicationStep::GET_RESET_STATUS; + internalState = InternalState::GET_RESET_STATUS; break; default: sif::debug << "RwHandler::buildNormalDeviceCommand: Invalid communication step" @@ -71,27 +68,7 @@ ReturnValue_t RwHandler::buildNormalDeviceCommand(DeviceCommandId_t * id) { } ReturnValue_t RwHandler::buildTransitionDeviceCommand(DeviceCommandId_t * id) { - switch (startupStep) { - case StartupStep::ENABLE_RW: - *id = RwDefinitions::GET_LAST_RESET_STATUS; - startupStep = StartupStep::CLEAR_RESET_STATUS; - break; - case StartupStep::CLEAR_RESET_STATUS: - *id = RwDefinitions::CLEAR_LAST_RESET_STATUS; - startupStep = StartupStep::INIT_RW; - break; - case StartupStep::INIT_RW: - *id = RwDefinitions::INIT_RW_CONTROLLER; - startupStep = StartupStep::STARTUP_COMPLETE; - break; - case StartupStep::STARTUP_COMPLETE: - break; - default: - sif::debug << "RwHandler::buildTransitionDeviceCommand: Invalid startup step" - << std::endl; - break; - } - return buildCommandFromCommand(*id, nullptr, 0);; + return RETURN_OK; } ReturnValue_t RwHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, @@ -100,9 +77,7 @@ ReturnValue_t RwHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand switch (deviceCommand) { case (RwDefinitions::RESET_MCU): { - commandBuffer[0] = static_cast(RwDefinitions::RESET_MCU); - rawPacket = commandBuffer; - rawPacketLen = 1; + prepareResetMcuCommand(); return RETURN_OK; } case (RwDefinitions::GET_LAST_RESET_STATUS): { @@ -255,7 +230,7 @@ void RwHandler::setNormalDatapoolEntriesInvalid() { } uint32_t RwHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { - return 15000; + return 500; } ReturnValue_t RwHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, @@ -263,9 +238,23 @@ ReturnValue_t RwHandler::initializeLocalDataPool(localpool::DataPool& localDataP localDataPoolMap.emplace(RwDefinitions::TEMPERATURE_C, new PoolEntry( { 0 })); + localDataPoolMap.emplace(RwDefinitions::CURR_SPEED, new PoolEntry( { 0 })); + localDataPoolMap.emplace(RwDefinitions::REFERENCE_SPEED, new PoolEntry( { 0 })); + localDataPoolMap.emplace(RwDefinitions::STATE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(RwDefinitions::CLC_MODE, new PoolEntry( { 0 })); + + localDataPoolMap.emplace(RwDefinitions::LAST_RESET_STATUS, new PoolEntry( { 0 })); + localDataPoolMap.emplace(RwDefinitions::CURRRENT_RESET_STATUS, new PoolEntry( { 0 })); + return RETURN_OK; } +void RwHandler::prepareResetMcuCommand() { + commandBuffer[0] = static_cast(RwDefinitions::RESET_MCU); + rawPacket = commandBuffer; + rawPacketLen = 1; +} + void RwHandler::prepareGetLastResetStatusCommand() { commandBuffer[0] = static_cast(RwDefinitions::GET_LAST_RESET_STATUS); uint16_t crc = CRC::crc16ccitt(commandBuffer, 1, 0xFFFF); @@ -352,15 +341,24 @@ void RwHandler::prepareSetSpeedCmd(const uint8_t * commandData, size_t commandDa } void RwHandler::handleResetStatusReply(const uint8_t* packet) { + PoolReadGuard rg(&lastResetStatusSet); uint8_t offset = 2; - lastResetStatusSet.lastResetStatus = *(packet + offset); + uint8_t resetStatus = *(packet + offset); + if (resetStatus != RwDefinitions::CLEARED) { + internalState = InternalState::CLEAR_RESET_STATUS; + lastResetStatusSet.lastResetStatus = resetStatus; + } + lastResetStatusSet.currentResetStatus = resetStatus; #if OBSW_VERBOSE_LEVEL >= 1 && RW_DEBUG == 1 sif::info << "RwHandler::handleResetStatusReply: Last reset status: " << static_cast(lastResetStatusSet.lastResetStatus.value) << std::endl; + sif::info << "RwHandler::handleResetStatusReply: Current reset status: " + << static_cast(lastResetStatusSet.currentResetStatus.value) << std::endl; #endif } void RwHandler::handleGetRwStatusReply(const uint8_t* packet) { + PoolReadGuard rg(&statusSet); uint8_t offset = 2; statusSet.currSpeed = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16 | *(packet + offset + 1) << 8 | *(packet + offset); @@ -372,6 +370,16 @@ void RwHandler::handleGetRwStatusReply(const uint8_t* packet) { offset += 1; statusSet.clcMode = *(packet + offset); + if (statusSet.state == RwDefinitions::ERROR) { + /** + * This requires the commanding of the init reaction wheel controller command to recover + * form error state which must be handled by the FDIR instance. + */ + triggerEvent(ERROR_STATE); + sif::error << "RwHandler::handleGetRwStatusReply: Reaction wheel in error state" + << std::endl; + } + #if OBSW_VERBOSE_LEVEL >= 1 && RW_DEBUG == 1 sif::info << "RwHandler::handleGetRwStatusReply: Current speed is: " << statusSet.currSpeed << " * 0.1 RPM" << std::endl; @@ -385,6 +393,7 @@ void RwHandler::handleGetRwStatusReply(const uint8_t* packet) { } void RwHandler::handleTemperatureReply(const uint8_t* packet) { + PoolReadGuard rg(&temperatureSet); uint8_t offset = 2; temperatureSet.temperatureCelcius = *(packet + offset + 3) << 24 | *(packet + offset + 2) << 16 | *(packet + offset + 1) << 8 | *(packet + offset); diff --git a/mission/devices/RwHandler.h b/mission/devices/RwHandler.h index a3d9ff1c..11fb4a30 100644 --- a/mission/devices/RwHandler.h +++ b/mission/devices/RwHandler.h @@ -79,6 +79,9 @@ private: //! [EXPORT] : [COMMENT] Reaction wheel reply has invalid crc static const ReturnValue_t CRC_ERROR = MAKE_RETURN_CODE(0xA4); + //! [EXPORT] : [COMMENT] Reaction wheel signals an error state + static const Event ERROR_STATE = MAKE_EVENT(1, severity::HIGH); + LinuxLibgpioIF* gpioComIF = nullptr; gpioId_t enableGpio = gpio::NO_GPIO; @@ -89,25 +92,23 @@ private: uint8_t commandBuffer[RwDefinitions::MAX_CMD_SIZE]; - enum class CommunicationStep { + enum class InternalState { GET_RESET_STATUS, + CLEAR_RESET_STATUS, READ_TEMPERATURE, GET_RW_SATUS }; - CommunicationStep communicationStep = CommunicationStep::READ_TEMPERATURE; - - enum class StartupStep { - ENABLE_RW, - CLEAR_RESET_STATUS, - INIT_RW, - STARTUP_COMPLETE - }; - - StartupStep startupStep = StartupStep::ENABLE_RW; + InternalState internalState = InternalState::GET_RESET_STATUS; size_t sizeOfReply = 0; + /** + * @brief This function fills the command buffer with the data to reset the MCU on a reaction + * wheel. + */ + void prepareResetMcuCommand(); + /** * @brief This function prepares the command to request the last reset status */ diff --git a/mission/devices/devicedefinitions/RwDefinitions.h b/mission/devices/devicedefinitions/RwDefinitions.h index e383920e..fbdbd5cf 100644 --- a/mission/devices/devicedefinitions/RwDefinitions.h +++ b/mission/devices/devicedefinitions/RwDefinitions.h @@ -16,7 +16,8 @@ enum PoolIds: lp_id_t { REFERENCE_SPEED, STATE, CLC_MODE, - LAST_RESET_STATUS + LAST_RESET_STATUS, + CURRRENT_RESET_STATUS }; enum States: uint8_t { @@ -27,6 +28,16 @@ enum States: uint8_t { RUNNING_SPEED_CHANGING }; +enum LastResetStatus: uint8_t { + CLEARED = 0, + PIN_RESET = 1, + POR_PDR_BOR_RESET = 2, + SOFTWARE_RESET = 4, + INDEPENDENT_WATCHDOG_RESET = 8, + WINDOW_WATCHDOG_RESET = 16, + LOW_POWER_RESET = 32 +}; + static const DeviceCommandId_t RESET_MCU = 1; static const DeviceCommandId_t GET_LAST_RESET_STATUS = 2; static const DeviceCommandId_t CLEAR_LAST_RESET_STATUS = 3; @@ -53,7 +64,7 @@ static const size_t SIZE_GET_TELEMETRY_REPLY = 83; static const size_t MAX_CMD_SIZE = 9; static const size_t MAX_REPLY_SIZE = SIZE_GET_TELEMETRY_REPLY; -static const uint8_t LAST_RESET_ENTRIES = 1; +static const uint8_t LAST_RESET_ENTRIES = 2; static const uint8_t TEMPERATURE_SET_ENTRIES = 1; static const uint8_t STATUS_SET_ENTRIES = 4; @@ -118,6 +129,8 @@ public: lp_var_t lastResetStatus = lp_var_t(sid.objectId, PoolIds::LAST_RESET_STATUS, this); + lp_var_t currentResetStatus = lp_var_t(sid.objectId, + PoolIds::CURRRENT_RESET_STATUS, this); }; } diff --git a/tmtc b/tmtc index 10ea97ff..a8ea01bb 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 10ea97ff0b685014f8f79b124edc8009db6fd879 +Subproject commit a8ea01bb2fced3d7562af4b200080e424468e9c6