From 5890e639feb5dbe22bd6dab9d9ba977be9dcc009 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 10:17:41 +0100 Subject: [PATCH 01/13] bugfix for dual to single side transition --- mission/system/objects/DualLaneAssemblyBase.cpp | 12 ++++++++++-- mission/system/objects/DualLaneAssemblyBase.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/mission/system/objects/DualLaneAssemblyBase.cpp b/mission/system/objects/DualLaneAssemblyBase.cpp index ca969dbb..582ba886 100644 --- a/mission/system/objects/DualLaneAssemblyBase.cpp +++ b/mission/system/objects/DualLaneAssemblyBase.cpp @@ -34,10 +34,17 @@ void DualLaneAssemblyBase::performChildOperation() { } void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) { - // doStartTransition(mode, submode); using namespace duallane; pwrStateMachine.reset(); if (mode != MODE_OFF) { + // Special exception: A transition from dual side to single mode must be handled like + // going OFF. + if ((this->mode == MODE_ON or this->mode == DeviceHandlerIF::MODE_NORMAL) and + this->submode == DUAL_MODE and submode != DUAL_MODE) { + dualToSingleSideTransition = true; + AssemblyBase::startTransition(mode, submode); + return; + } // If anything other than MODE_OFF is commanded, perform power state machine first // Cache the target modes, required by power state machine pwrStateMachine.start(mode, submode); @@ -111,7 +118,7 @@ ReturnValue_t DualLaneAssemblyBase::isModeCombinationValid(Mode_t mode, Submode_ void DualLaneAssemblyBase::handleModeReached() { using namespace duallane; - if (targetMode == MODE_OFF) { + if (targetMode == MODE_OFF or dualToSingleSideTransition) { pwrStateMachine.start(targetMode, targetSubmode); // Now we can switch off the power. After that, the AssemblyBase::handleModeReached function // will be called @@ -229,6 +236,7 @@ void DualLaneAssemblyBase::finishModeOp() { pwrStateMachine.reset(); powerRetryCounter = 0; tryingOtherSide = false; + dualToSingleSideTransition = false; dualModeErrorSwitch = true; } diff --git a/mission/system/objects/DualLaneAssemblyBase.h b/mission/system/objects/DualLaneAssemblyBase.h index a8a2f521..929ef3f9 100644 --- a/mission/system/objects/DualLaneAssemblyBase.h +++ b/mission/system/objects/DualLaneAssemblyBase.h @@ -31,6 +31,7 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF { uint8_t powerRetryCounter = 0; bool tryingOtherSide = false; bool dualModeErrorSwitch = true; + bool dualToSingleSideTransition = false; duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE; enum RecoveryCustomStates { From 74bb27e61f87d70a5a3245276312c6fccead4cf5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 11:12:19 +0100 Subject: [PATCH 02/13] some more fixes --- .../system/objects/DualLaneAssemblyBase.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/mission/system/objects/DualLaneAssemblyBase.cpp b/mission/system/objects/DualLaneAssemblyBase.cpp index 582ba886..22728457 100644 --- a/mission/system/objects/DualLaneAssemblyBase.cpp +++ b/mission/system/objects/DualLaneAssemblyBase.cpp @@ -82,9 +82,13 @@ ReturnValue_t DualLaneAssemblyBase::pwrStateMachineWrapper() { // Will be called for transitions to MODE_OFF, where everything is done after power switching finishModeOp(); } else if (opCode == OpCodes::TO_NOT_OFF_DONE) { - // Will be called for transitions from MODE_OFF to anything else, where the mode still has - // to be commanded after power switching - AssemblyBase::startTransition(targetMode, targetSubmode); + if (dualToSingleSideTransition) { + finishModeOp(); + } else { + // Will be called for transitions from MODE_OFF to anything else, where the mode still has + // to be commanded after power switching + AssemblyBase::startTransition(targetMode, targetSubmode); + } } else if (opCode == OpCodes::TIMEOUT_OCCURED) { if (powerRetryCounter == 0) { powerRetryCounter++; @@ -118,13 +122,20 @@ ReturnValue_t DualLaneAssemblyBase::isModeCombinationValid(Mode_t mode, Submode_ void DualLaneAssemblyBase::handleModeReached() { using namespace duallane; - if (targetMode == MODE_OFF or dualToSingleSideTransition) { + if (targetMode == MODE_OFF) { pwrStateMachine.start(targetMode, targetSubmode); // Now we can switch off the power. After that, the AssemblyBase::handleModeReached function // will be called // Ignore failures for now. pwrStateMachineWrapper(); } else { + // For dual to single side transition, devices should be logically off, but the switch + // handling still needs to be done. + if (dualToSingleSideTransition) { + pwrStateMachine.start(targetMode, targetSubmode); + pwrStateMachineWrapper(); + return; + } finishModeOp(); } } From 7cf3247cbd96a291839841f66163a196fc222503 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 13:08:38 +0100 Subject: [PATCH 03/13] seems to work now --- linux/devices/AcsBoardPolling.cpp | 162 ++++++++++++------------ mission/devices/GyrAdis1650XHandler.cpp | 5 +- 2 files changed, 84 insertions(+), 83 deletions(-) diff --git a/linux/devices/AcsBoardPolling.cpp b/linux/devices/AcsBoardPolling.cpp index 307ddebb..adcbbf19 100644 --- a/linux/devices/AcsBoardPolling.cpp +++ b/linux/devices/AcsBoardPolling.cpp @@ -451,95 +451,99 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) { cdHasTimedOut = gyro.countdown.hasTimedOut(); mustPerformStartup = gyro.performStartup; } - if (mode == acs::SimpleSensorMode::NORMAL and cdHasTimedOut) { - if (mustPerformStartup) { - uint8_t regList[6]; - // Read configuration - regList[0] = adis1650x::DIAG_STAT_REG; - regList[1] = adis1650x::FILTER_CTRL_REG; - regList[2] = adis1650x::RANG_MDL_REG; - regList[3] = adis1650x::MSC_CTRL_REG; - regList[4] = adis1650x::DEC_RATE_REG; - regList[5] = adis1650x::PROD_ID_REG; - size_t transferLen = - adis1650x::prepareReadCommand(regList, sizeof(regList), cmdBuf.data(), cmdBuf.size()); - result = readAdisCfg(*gyro.cookie, transferLen); - if (result != returnvalue::OK) { - gyro.replyResult = result; - return; - } - result = spiComIF.readReceivedMessage(gyro.cookie, &rawReply, &dummy); - if (result != returnvalue::OK or rawReply == nullptr) { - gyro.replyResult = result; - return; - } - uint16_t prodId = (rawReply[12] << 8) | rawReply[13]; - if (((gyro.type == adis1650x::Type::ADIS16505) and (prodId != adis1650x::PROD_ID_16505)) or - ((gyro.type == adis1650x::Type::ADIS16507) and (prodId != adis1650x::PROD_ID_16507))) { - sif::warning << "AcsPollingTask: Invalid ADIS product ID " << prodId << std::endl; - gyro.replyResult = returnvalue::FAILED; - return; - } - MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); - gyro.ownReply.cfgWasSet = true; - gyro.ownReply.cfg.diagStat = (rawReply[2] << 8) | rawReply[3]; - gyro.ownReply.cfg.filterSetting = (rawReply[4] << 8) | rawReply[5]; - gyro.ownReply.cfg.rangMdl = (rawReply[6] << 8) | rawReply[7]; - gyro.ownReply.cfg.mscCtrlReg = (rawReply[8] << 8) | rawReply[9]; - gyro.ownReply.cfg.decRateReg = (rawReply[10] << 8) | rawReply[11]; - gyro.ownReply.cfg.prodId = prodId; - gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl); - gyro.performStartup = false; - } - // Read regular registers - std::memcpy(cmdBuf.data(), adis1650x::BURST_READ_ENABLE.data(), - adis1650x::BURST_READ_ENABLE.size()); - std::memset(cmdBuf.data() + 2, 0, 10 * 2); - result = spiComIF.sendMessage(gyro.cookie, cmdBuf.data(), adis1650x::SENSOR_READOUT_SIZE); + if (mode == acs::SimpleSensorMode::OFF) { + return; + } + if (not cdHasTimedOut) { + return; + } + if (mustPerformStartup) { + uint8_t regList[6]; + // Read configuration + regList[0] = adis1650x::DIAG_STAT_REG; + regList[1] = adis1650x::FILTER_CTRL_REG; + regList[2] = adis1650x::RANG_MDL_REG; + regList[3] = adis1650x::MSC_CTRL_REG; + regList[4] = adis1650x::DEC_RATE_REG; + regList[5] = adis1650x::PROD_ID_REG; + size_t transferLen = + adis1650x::prepareReadCommand(regList, sizeof(regList), cmdBuf.data(), cmdBuf.size()); + result = readAdisCfg(*gyro.cookie, transferLen); if (result != returnvalue::OK) { - gyro.replyResult = returnvalue::FAILED; + gyro.replyResult = result; return; } result = spiComIF.readReceivedMessage(gyro.cookie, &rawReply, &dummy); if (result != returnvalue::OK or rawReply == nullptr) { + gyro.replyResult = result; + return; + } + uint16_t prodId = (rawReply[12] << 8) | rawReply[13]; + if (((gyro.type == adis1650x::Type::ADIS16505) and (prodId != adis1650x::PROD_ID_16505)) or + ((gyro.type == adis1650x::Type::ADIS16507) and (prodId != adis1650x::PROD_ID_16507))) { + sif::warning << "AcsPollingTask: Invalid ADIS product ID " << prodId << std::endl; gyro.replyResult = returnvalue::FAILED; return; } - uint16_t checksum = (rawReply[20] << 8) | rawReply[21]; - - // Now verify the read checksum with the expected checksum according to datasheet p. 20 - uint16_t calcChecksum = 0; - for (size_t idx = 2; idx < 20; idx++) { - calcChecksum += rawReply[idx]; - } - if (checksum != calcChecksum) { - sif::warning << "AcsPollingTask: Invalid ADIS reply checksum" << std::endl; - gyro.replyResult = returnvalue::FAILED; - return; - } - - auto burstMode = adis1650x::burstModeFromMscCtrl(gyro.ownReply.cfg.mscCtrlReg); - if (burstMode != adis1650x::BurstModes::BURST_16_BURST_SEL_0) { - sif::error << "GyroADIS1650XHandler::interpretDeviceReply: Analysis for select burst mode" - " not implemented!" - << std::endl; - gyro.replyResult = returnvalue::FAILED; - return; - } - MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); - gyro.ownReply.dataWasSet = true; - gyro.ownReply.cfg.diagStat = rawReply[2] << 8 | rawReply[3]; - gyro.ownReply.data.angVelocities[0] = (rawReply[4] << 8) | rawReply[5]; - gyro.ownReply.data.angVelocities[1] = (rawReply[6] << 8) | rawReply[7]; - gyro.ownReply.data.angVelocities[2] = (rawReply[8] << 8) | rawReply[9]; - - gyro.ownReply.data.accelerations[0] = (rawReply[10] << 8) | rawReply[11]; - gyro.ownReply.data.accelerations[1] = (rawReply[12] << 8) | rawReply[13]; - gyro.ownReply.data.accelerations[2] = (rawReply[14] << 8) | rawReply[15]; - - gyro.ownReply.data.temperatureRaw = (rawReply[16] << 8) | rawReply[17]; + gyro.ownReply.cfgWasSet = true; + gyro.ownReply.cfg.diagStat = (rawReply[2] << 8) | rawReply[3]; + gyro.ownReply.cfg.filterSetting = (rawReply[4] << 8) | rawReply[5]; + gyro.ownReply.cfg.rangMdl = (rawReply[6] << 8) | rawReply[7]; + gyro.ownReply.cfg.mscCtrlReg = (rawReply[8] << 8) | rawReply[9]; + gyro.ownReply.cfg.decRateReg = (rawReply[10] << 8) | rawReply[11]; + gyro.ownReply.cfg.prodId = prodId; + gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl); + gyro.performStartup = false; } + // Read regular registers + std::memcpy(cmdBuf.data(), adis1650x::BURST_READ_ENABLE.data(), + adis1650x::BURST_READ_ENABLE.size()); + std::memset(cmdBuf.data() + 2, 0, 10 * 2); + result = spiComIF.sendMessage(gyro.cookie, cmdBuf.data(), adis1650x::SENSOR_READOUT_SIZE); + if (result != returnvalue::OK) { + gyro.replyResult = returnvalue::FAILED; + return; + } + result = spiComIF.readReceivedMessage(gyro.cookie, &rawReply, &dummy); + if (result != returnvalue::OK or rawReply == nullptr) { + gyro.replyResult = returnvalue::FAILED; + return; + } + uint16_t checksum = (rawReply[20] << 8) | rawReply[21]; + + // Now verify the read checksum with the expected checksum according to datasheet p. 20 + uint16_t calcChecksum = 0; + for (size_t idx = 2; idx < 20; idx++) { + calcChecksum += rawReply[idx]; + } + if (checksum != calcChecksum) { + sif::warning << "AcsPollingTask: Invalid ADIS reply checksum" << std::endl; + gyro.replyResult = returnvalue::FAILED; + return; + } + + auto burstMode = adis1650x::burstModeFromMscCtrl(gyro.ownReply.cfg.mscCtrlReg); + if (burstMode != adis1650x::BurstModes::BURST_16_BURST_SEL_0) { + sif::error << "GyroADIS1650XHandler::interpretDeviceReply: Analysis for select burst mode" + " not implemented!" + << std::endl; + gyro.replyResult = returnvalue::FAILED; + return; + } + + MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); + gyro.ownReply.dataWasSet = true; + gyro.ownReply.cfg.diagStat = rawReply[2] << 8 | rawReply[3]; + gyro.ownReply.data.angVelocities[0] = (rawReply[4] << 8) | rawReply[5]; + gyro.ownReply.data.angVelocities[1] = (rawReply[6] << 8) | rawReply[7]; + gyro.ownReply.data.angVelocities[2] = (rawReply[8] << 8) | rawReply[9]; + + gyro.ownReply.data.accelerations[0] = (rawReply[10] << 8) | rawReply[11]; + gyro.ownReply.data.accelerations[1] = (rawReply[12] << 8) | rawReply[13]; + gyro.ownReply.data.accelerations[2] = (rawReply[14] << 8) | rawReply[15]; + + gyro.ownReply.data.temperatureRaw = (rawReply[16] << 8) | rawReply[17]; } void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) { diff --git a/mission/devices/GyrAdis1650XHandler.cpp b/mission/devices/GyrAdis1650XHandler.cpp index 73e9a0cd..7d576238 100644 --- a/mission/devices/GyrAdis1650XHandler.cpp +++ b/mission/devices/GyrAdis1650XHandler.cpp @@ -65,10 +65,7 @@ ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_ } case (InternalState::SHUTDOWN): { *id = adis1650x::REQUEST; - acs::Adis1650XRequest *request = reinterpret_cast(cmdBuf.data()); - request->mode = acs::SimpleSensorMode::OFF; - request->type = adisType; - return returnvalue::OK; + return preparePeriodicRequest(acs::SimpleSensorMode::OFF); } default: { return NOTHING_TO_SEND; From 22f8d256ddd3395c106ee9102908fab692404fd9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 13:09:28 +0100 Subject: [PATCH 04/13] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f68f5ad..e5ca13ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +## Fixed + +- Fixed transition for dual power lane assemblies: When going from dual side submode to single side + submode, perform logical commanding first, similarly to when going to OFF mode. + # [v1.38.0] 2023-03-17 eive-tmtc: v2.19.2 From b516f12a61f8d4978bc01e6176e647fdf8b369dd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 15:16:20 +0100 Subject: [PATCH 05/13] str transition fixes --- linux/devices/startracker/StarTrackerHandler.cpp | 16 ++++++++++++++-- linux/devices/startracker/StarTrackerHandler.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/linux/devices/startracker/StarTrackerHandler.cpp b/linux/devices/startracker/StarTrackerHandler.cpp index 0edf6de1..2dd73cbf 100644 --- a/linux/devices/startracker/StarTrackerHandler.cpp +++ b/linux/devices/startracker/StarTrackerHandler.cpp @@ -268,7 +268,8 @@ void StarTrackerHandler::doStartUp() { default: return; } - setMode(_MODE_TO_ON, SUBMODE_BOOTLOADER); + boot = true; + setMode(_MODE_TO_ON); } void StarTrackerHandler::doShutDown() { @@ -707,6 +708,13 @@ void StarTrackerHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) { uint8_t dhbSubmode = getSubmode(); + // We hide that the transition to submode firmware actually goes through the submode bootloader. + // This is because the startracker always starts in bootloader mode but we want to allow direct + // transitions to firmware mode. + if (boot) { + subModeFrom = SUBMODE_BOOTLOADER; + boot = false; + } if (dhbSubmode == SUBMODE_BOOTLOADER && subModeFrom == SUBMODE_FIRMWARE) { bootBootloader(); } else if (dhbSubmode == SUBMODE_FIRMWARE && subModeFrom == SUBMODE_FIRMWARE) { @@ -747,7 +755,11 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) { internalState = InternalState::IDLE; break; case InternalState::DONE: - setMode(toMode); + if (toMode == MODE_NORMAL) { + setMode(toMode, 0); + } else { + setMode(toMode); + } internalState = InternalState::IDLE; break; default: diff --git a/linux/devices/startracker/StarTrackerHandler.h b/linux/devices/startracker/StarTrackerHandler.h index 11cf7fc3..d6c8c72d 100644 --- a/linux/devices/startracker/StarTrackerHandler.h +++ b/linux/devices/startracker/StarTrackerHandler.h @@ -212,6 +212,7 @@ class StarTrackerHandler : public DeviceHandlerBase { // Pointer to object responsible for uploading and downloading images to/from the star tracker StrHelper* strHelper = nullptr; + bool boot = false; uint8_t commandBuffer[startracker::MAX_FRAME_SIZE]; From d8f84ed00d6656b8b3d2ad9bde8ca01e4ee0eeb7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 15:17:34 +0100 Subject: [PATCH 06/13] small tweak --- linux/devices/startracker/StarTrackerHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/devices/startracker/StarTrackerHandler.cpp b/linux/devices/startracker/StarTrackerHandler.cpp index 2dd73cbf..a195f596 100644 --- a/linux/devices/startracker/StarTrackerHandler.cpp +++ b/linux/devices/startracker/StarTrackerHandler.cpp @@ -275,6 +275,7 @@ void StarTrackerHandler::doStartUp() { void StarTrackerHandler::doShutDown() { // If the star tracker is shutdown also stop all running processes in the image loader task strHelper->stopProcess(); + boot = false; setMode(_MODE_POWER_DOWN); } From f9e04ed9a2d0077ba8cc15718f067cd547dbb10a Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 20 Mar 2023 15:42:45 +0100 Subject: [PATCH 07/13] updated gyr bias --- mission/controller/acs/AcsParameters.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mission/controller/acs/AcsParameters.h b/mission/controller/acs/AcsParameters.h index fca8ed8e..5b185ea4 100644 --- a/mission/controller/acs/AcsParameters.h +++ b/mission/controller/acs/AcsParameters.h @@ -768,10 +768,10 @@ class AcsParameters : public HasParametersIF { double gyr2orientationMatrix[3][3] = {{0, 0, -1}, {0, -1, 0}, {-1, 0, 0}}; double gyr3orientationMatrix[3][3] = {{0, 0, -1}, {0, 1, 0}, {1, 0, 0}}; - double gyr0bias[3] = {0.06318149743589743, 0.4283235025641024, -0.16383500000000004}; - double gyr1bias[3] = {-0.12855128205128205, 1.6737307692307695, 1.031724358974359}; - double gyr2bias[3] = {0.15039212820512823, 0.7094475589743591, -0.22298363589743594}; - double gyr3bias[3] = {0.0021730769230769217, -0.6655897435897435, 0.034096153846153845}; + double gyr0bias[3] = {0.0, 0.4, -0.1}; + double gyr1bias[3] = {0.0956745283018868, 2.0854575471698116, 1.2505990566037737}; + double gyr2bias[3] = {0.1, 0.7, -0.2}; + double gyr3bias[3] = {-0.10721698113207549, -0.6111650943396226, 0.1716462264150944}; /* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is * assumed to be equal for the same class of sensors */ From 881a03fbed3d8117a05a684b41d14249c32399d3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 15:49:41 +0100 Subject: [PATCH 08/13] direct transition to normal works again --- fsfw | 2 +- linux/devices/startracker/StarTrackerHandler.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/fsfw b/fsfw index 43fd0b2f..227524a2 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 43fd0b2f59c3aeb2d3f4db10cfad56ee3709d68d +Subproject commit 227524a21da755d125bcb1a5ff67bcbc452f8cf9 diff --git a/linux/devices/startracker/StarTrackerHandler.cpp b/linux/devices/startracker/StarTrackerHandler.cpp index a195f596..9e75c910 100644 --- a/linux/devices/startracker/StarTrackerHandler.cpp +++ b/linux/devices/startracker/StarTrackerHandler.cpp @@ -716,6 +716,9 @@ void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) { subModeFrom = SUBMODE_BOOTLOADER; boot = false; } + if (dhbSubmode == SUBMODE_NONE) { + bootFirmware(MODE_ON); + } if (dhbSubmode == SUBMODE_BOOTLOADER && subModeFrom == SUBMODE_FIRMWARE) { bootBootloader(); } else if (dhbSubmode == SUBMODE_FIRMWARE && subModeFrom == SUBMODE_FIRMWARE) { @@ -759,7 +762,7 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) { if (toMode == MODE_NORMAL) { setMode(toMode, 0); } else { - setMode(toMode); + setMode(toMode, SUBMODE_FIRMWARE); } internalState = InternalState::IDLE; break; From 11c54e270f96db00ceea885f5a26d540f730c9f4 Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 20 Mar 2023 15:50:50 +0100 Subject: [PATCH 09/13] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5ca13ae..6c7c5f65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,11 @@ will consitute of a breaking change warranting a new major release: - Fixed transition for dual power lane assemblies: When going from dual side submode to single side submode, perform logical commanding first, similarly to when going to OFF mode. +## Changed + +- Updated GYR bias values to newest measurements. This also corrects the ADIS values to always + consit of just one digit. + # [v1.38.0] 2023-03-17 eive-tmtc: v2.19.2 From aea4313b7d090ddafdfa9df0f0fb2f6098dd84d3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 15:52:58 +0100 Subject: [PATCH 10/13] some more tweaks --- linux/devices/startracker/StarTrackerHandler.cpp | 7 ++----- linux/devices/startracker/StarTrackerHandler.h | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/linux/devices/startracker/StarTrackerHandler.cpp b/linux/devices/startracker/StarTrackerHandler.cpp index 9e75c910..79c3a294 100644 --- a/linux/devices/startracker/StarTrackerHandler.cpp +++ b/linux/devices/startracker/StarTrackerHandler.cpp @@ -276,12 +276,9 @@ void StarTrackerHandler::doShutDown() { // If the star tracker is shutdown also stop all running processes in the image loader task strHelper->stopProcess(); boot = false; - setMode(_MODE_POWER_DOWN); -} - -void StarTrackerHandler::doOffActivity() { - startupState = StartupState::IDLE; internalState = InternalState::IDLE; + startupState = StartupState::IDLE; + setMode(_MODE_POWER_DOWN); } ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { diff --git a/linux/devices/startracker/StarTrackerHandler.h b/linux/devices/startracker/StarTrackerHandler.h index d6c8c72d..e76c0047 100644 --- a/linux/devices/startracker/StarTrackerHandler.h +++ b/linux/devices/startracker/StarTrackerHandler.h @@ -60,7 +60,6 @@ class StarTrackerHandler : public DeviceHandlerBase { 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; From c682d75aff3a405e7dec06714af27871a36480f5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 17:05:57 +0100 Subject: [PATCH 11/13] works now --- linux/devices/startracker/StarTrackerHandler.cpp | 5 ++++- linux/devices/startracker/StarTrackerHandler.h | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/linux/devices/startracker/StarTrackerHandler.cpp b/linux/devices/startracker/StarTrackerHandler.cpp index 79c3a294..d4aa8019 100644 --- a/linux/devices/startracker/StarTrackerHandler.cpp +++ b/linux/devices/startracker/StarTrackerHandler.cpp @@ -268,6 +268,8 @@ void StarTrackerHandler::doStartUp() { default: return; } + startupState = StartupState::IDLE; + internalState = InternalState::IDLE; boot = true; setMode(_MODE_TO_ON); } @@ -711,7 +713,6 @@ void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) { // transitions to firmware mode. if (boot) { subModeFrom = SUBMODE_BOOTLOADER; - boot = false; } if (dhbSubmode == SUBMODE_NONE) { bootFirmware(MODE_ON); @@ -749,6 +750,7 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) { break; case InternalState::BOOT_DELAY: if (bootCountdown.hasTimedOut()) { + sif::info << "STR: Starting firmware boot" << std::endl; internalState = InternalState::REQ_VERSION; } break; @@ -2086,6 +2088,7 @@ void StarTrackerHandler::handleStartup(const uint8_t* parameterId) { break; } case (startracker::ID::DEBUG_CAMERA): { + sif::info << "Star Tracker configuration done" << std::endl; internalState = InternalState::DONE; break; } diff --git a/linux/devices/startracker/StarTrackerHandler.h b/linux/devices/startracker/StarTrackerHandler.h index e76c0047..3d9f2b93 100644 --- a/linux/devices/startracker/StarTrackerHandler.h +++ b/linux/devices/startracker/StarTrackerHandler.h @@ -277,6 +277,10 @@ class StarTrackerHandler : public DeviceHandlerBase { BOOTING_BOOTLOADER_FAILED }; + enum class CfgSetupState { + + }; + InternalState internalState = InternalState::IDLE; enum class StartupState { From 043a458f420828f61b88c4c9e5d1a9b79726f75d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 17:51:10 +0100 Subject: [PATCH 12/13] seems to work now --- .../startracker/StarTrackerHandler.cpp | 227 ++++++++++-------- .../devices/startracker/StarTrackerHandler.h | 47 ++-- 2 files changed, 146 insertions(+), 128 deletions(-) diff --git a/linux/devices/startracker/StarTrackerHandler.cpp b/linux/devices/startracker/StarTrackerHandler.cpp index d4aa8019..61b77fe2 100644 --- a/linux/devices/startracker/StarTrackerHandler.cpp +++ b/linux/devices/startracker/StarTrackerHandler.cpp @@ -268,18 +268,17 @@ void StarTrackerHandler::doStartUp() { default: return; } - startupState = StartupState::IDLE; + startupState = StartupState::DONE; internalState = InternalState::IDLE; - boot = true; setMode(_MODE_TO_ON); } void StarTrackerHandler::doShutDown() { // If the star tracker is shutdown also stop all running processes in the image loader task strHelper->stopProcess(); - boot = false; internalState = InternalState::IDLE; startupState = StartupState::IDLE; + bootState = FwBootState::NONE; setMode(_MODE_POWER_DOWN); } @@ -303,81 +302,103 @@ ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id ReturnValue_t StarTrackerHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { switch (internalState) { - case InternalState::BOOT: - *id = startracker::BOOT; - bootCountdown.setTimeout(BOOT_TIMEOUT); - internalState = InternalState::BOOT_DELAY; - return buildCommandFromCommand(*id, nullptr, 0); - case InternalState::REQ_VERSION: - internalState = InternalState::VERIFY_BOOT; - // Again read program to check if firmware boot was successful - *id = startracker::REQ_VERSION; - return buildCommandFromCommand(*id, nullptr, 0); - case InternalState::LOGLEVEL: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::LOGLEVEL; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::LIMITS: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::LIMITS; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::TRACKING: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::TRACKING; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::MOUNTING: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::MOUNTING; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::IMAGE_PROCESSOR: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::IMAGE_PROCESSOR; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::CAMERA: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::CAMERA; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::CENTROIDING: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::CENTROIDING; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::LISA: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::LISA; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::MATCHING: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::MATCHING; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::VALIDATION: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::VALIDATION; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::ALGO: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::ALGO; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::LOG_SUBSCRIPTION: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::LOGSUBSCRIPTION; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); - case InternalState::DEBUG_CAMERA: - internalState = InternalState::WAIT_FOR_EXECUTION; - *id = startracker::DEBUG_CAMERA; - return buildCommandFromCommand(*id, reinterpret_cast(paramJsonFile.c_str()), - paramJsonFile.size()); + case InternalState::BOOT_FIRMWARE: { + if (bootState == FwBootState::WAIT_FOR_EXECUTION or bootState == FwBootState::VERIFY_BOOT) { + return NOTHING_TO_SEND; + } + if (bootState == FwBootState::NONE) { + *id = startracker::BOOT; + bootCountdown.setTimeout(BOOT_TIMEOUT); + bootState = FwBootState::BOOT_DELAY; + return buildCommandFromCommand(*id, nullptr, 0); + } + if (bootState == FwBootState::BOOT_DELAY) { + if (bootCountdown.isBusy()) { + return NOTHING_TO_SEND; + } + bootState = FwBootState::REQ_VERSION; + } + switch (bootState) { + case (FwBootState::REQ_VERSION): { + bootState = FwBootState::VERIFY_BOOT; + // Again read program to check if firmware boot was successful + *id = startracker::REQ_VERSION; + return buildCommandFromCommand(*id, nullptr, 0); + } + case (FwBootState::LOGLEVEL): { + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::LOGLEVEL; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + } + case (FwBootState::LIMITS): { + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::LIMITS; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + } + case (FwBootState::TRACKING): { + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::TRACKING; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + } + case FwBootState::MOUNTING: + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::MOUNTING; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + case FwBootState::IMAGE_PROCESSOR: + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::IMAGE_PROCESSOR; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + case FwBootState::CAMERA: + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::CAMERA; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + case FwBootState::CENTROIDING: + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::CENTROIDING; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + case FwBootState::LISA: + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::LISA; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + case FwBootState::MATCHING: + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::MATCHING; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + case FwBootState::VALIDATION: + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::VALIDATION; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + case FwBootState::ALGO: + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::ALGO; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + case FwBootState::LOG_SUBSCRIPTION: + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::LOGSUBSCRIPTION; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + case FwBootState::DEBUG_CAMERA: + bootState = FwBootState::WAIT_FOR_EXECUTION; + *id = startracker::DEBUG_CAMERA; + return buildCommandFromCommand( + *id, reinterpret_cast(paramJsonFile.c_str()), paramJsonFile.size()); + default: { + sif::error << "STR: Unexpected boot state" << (int)bootState << std::endl; + return NOTHING_TO_SEND; + } + } + } case InternalState::BOOT_BOOTLOADER: internalState = InternalState::BOOTLOADER_CHECK; *id = startracker::SWITCH_TO_BOOTLOADER_PROGRAM; @@ -711,7 +732,7 @@ void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) { // We hide that the transition to submode firmware actually goes through the submode bootloader. // This is because the startracker always starts in bootloader mode but we want to allow direct // transitions to firmware mode. - if (boot) { + if (startupState == StartupState::DONE) { subModeFrom = SUBMODE_BOOTLOADER; } if (dhbSubmode == SUBMODE_NONE) { @@ -746,13 +767,10 @@ void StarTrackerHandler::doNormalTransition(Mode_t modeFrom, Submode_t subModeFr void StarTrackerHandler::bootFirmware(Mode_t toMode) { switch (internalState) { case InternalState::IDLE: - internalState = InternalState::BOOT; + sif::info << "STR: Booting to firmware mode" << std::endl; + internalState = InternalState::BOOT_FIRMWARE; break; - case InternalState::BOOT_DELAY: - if (bootCountdown.hasTimedOut()) { - sif::info << "STR: Starting firmware boot" << std::endl; - internalState = InternalState::REQ_VERSION; - } + case InternalState::BOOT_FIRMWARE: break; case InternalState::FAILED_FIRMWARE_BOOT: internalState = InternalState::IDLE; @@ -763,7 +781,9 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) { } else { setMode(toMode, SUBMODE_FIRMWARE); } + sif::info << "STR: Firmware boot success" << std::endl; internalState = InternalState::IDLE; + startupState = StartupState::IDLE; break; default: return; @@ -791,10 +811,11 @@ void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonF void StarTrackerHandler::bootBootloader() { if (internalState == InternalState::IDLE) { internalState = InternalState::BOOT_BOOTLOADER; - } else if (internalState == InternalState::BOOTING_BOOTLOADER_FAILED) { + } else if (internalState == InternalState::FAILED_BOOTLOADER_BOOT) { internalState = InternalState::IDLE; } else if (internalState == InternalState::DONE) { internalState = InternalState::IDLE; + startupState = StartupState::IDLE; setMode(MODE_ON); } } @@ -1949,7 +1970,7 @@ ReturnValue_t StarTrackerHandler::checkProgram() { if (startupState == StartupState::WAIT_CHECK_PROGRAM) { startupState = StartupState::DONE; } - if (internalState == InternalState::VERIFY_BOOT) { + if (bootState == FwBootState::VERIFY_BOOT) { sif::warning << "StarTrackerHandler::checkProgram: Failed to boot firmware" << std::endl; // Device handler will run into timeout and fall back to transition source mode triggerEvent(BOOTING_FIRMWARE_FAILED_EVENT); @@ -1962,11 +1983,11 @@ ReturnValue_t StarTrackerHandler::checkProgram() { if (startupState == StartupState::WAIT_CHECK_PROGRAM) { startupState = StartupState::BOOT_BOOTLOADER; } - if (internalState == InternalState::VERIFY_BOOT) { - internalState = InternalState::LOGLEVEL; + if (bootState == FwBootState::VERIFY_BOOT) { + bootState = FwBootState::LOGLEVEL; } else if (internalState == InternalState::BOOTLOADER_CHECK) { triggerEvent(BOOTING_BOOTLOADER_FAILED_EVENT); - internalState = InternalState::BOOTING_BOOTLOADER_FAILED; + internalState = InternalState::FAILED_BOOTLOADER_BOOT; } break; default: @@ -2040,55 +2061,55 @@ ReturnValue_t StarTrackerHandler::handleActionReplySet(LocalPoolDataSetBase& dat void StarTrackerHandler::handleStartup(const uint8_t* parameterId) { switch (*parameterId) { case (startracker::ID::LOG_LEVEL): { - internalState = InternalState::LIMITS; + bootState = FwBootState::LIMITS; break; } case (startracker::ID::LIMITS): { - internalState = InternalState::TRACKING; + bootState = FwBootState::TRACKING; break; } case (startracker::ID::TRACKING): { - internalState = InternalState::MOUNTING; + bootState = FwBootState::MOUNTING; break; } case (startracker::ID::MOUNTING): { - internalState = InternalState::IMAGE_PROCESSOR; + bootState = FwBootState::IMAGE_PROCESSOR; break; } case (startracker::ID::IMAGE_PROCESSOR): { - internalState = InternalState::CAMERA; + bootState = FwBootState::CAMERA; break; } case (startracker::ID::CAMERA): { - internalState = InternalState::CENTROIDING; + bootState = FwBootState::CENTROIDING; break; } case (startracker::ID::CENTROIDING): { - internalState = InternalState::LISA; + bootState = FwBootState::LISA; break; } case (startracker::ID::LISA): { - internalState = InternalState::MATCHING; + bootState = FwBootState::MATCHING; break; } case (startracker::ID::MATCHING): { - internalState = InternalState::VALIDATION; + bootState = FwBootState::VALIDATION; break; } case (startracker::ID::VALIDATION): { - internalState = InternalState::ALGO; + bootState = FwBootState::ALGO; break; } case (startracker::ID::ALGO): { - internalState = InternalState::LOG_SUBSCRIPTION; + bootState = FwBootState::LOG_SUBSCRIPTION; break; } case (startracker::ID::LOG_SUBSCRIPTION): { - internalState = InternalState::DEBUG_CAMERA; + bootState = FwBootState::DEBUG_CAMERA; break; } case (startracker::ID::DEBUG_CAMERA): { - sif::info << "Star Tracker configuration done" << std::endl; + bootState = FwBootState::NONE; internalState = InternalState::DONE; break; } diff --git a/linux/devices/startracker/StarTrackerHandler.h b/linux/devices/startracker/StarTrackerHandler.h index 3d9f2b93..a70ff8cf 100644 --- a/linux/devices/startracker/StarTrackerHandler.h +++ b/linux/devices/startracker/StarTrackerHandler.h @@ -211,7 +211,6 @@ class StarTrackerHandler : public DeviceHandlerBase { // Pointer to object responsible for uploading and downloading images to/from the star tracker StrHelper* strHelper = nullptr; - bool boot = false; uint8_t commandBuffer[startracker::MAX_FRAME_SIZE]; @@ -247,14 +246,31 @@ class StarTrackerHandler : public DeviceHandlerBase { NormalState normalState = NormalState::TEMPERATURE_REQUEST; + enum class StartupState { + IDLE, + CHECK_PROGRAM, + WAIT_CHECK_PROGRAM, + BOOT_BOOTLOADER, + WAIT_JCFG, + DONE + }; + StartupState startupState = StartupState::IDLE; + enum class InternalState { IDLE, - BOOT, + BOOT_FIRMWARE, + DONE, + FAILED_FIRMWARE_BOOT, + BOOT_BOOTLOADER, + BOOTLOADER_CHECK, + FAILED_BOOTLOADER_BOOT + }; + + enum class FwBootState { + NONE, + BOOT_DELAY, REQ_VERSION, VERIFY_BOOT, - STARTUP_CHECK, - BOOT_DELAY, - FIRMWARE_CHECK, LOGLEVEL, LIMITS, TRACKING, @@ -270,30 +286,11 @@ class StarTrackerHandler : public DeviceHandlerBase { LOG_SUBSCRIPTION, DEBUG_CAMERA, WAIT_FOR_EXECUTION, - DONE, - FAILED_FIRMWARE_BOOT, - BOOT_BOOTLOADER, - BOOTLOADER_CHECK, - BOOTING_BOOTLOADER_FAILED - }; - - enum class CfgSetupState { - }; + FwBootState bootState = FwBootState::NONE; InternalState internalState = InternalState::IDLE; - enum class StartupState { - IDLE, - CHECK_PROGRAM, - WAIT_CHECK_PROGRAM, - BOOT_BOOTLOADER, - WAIT_JCFG, - DONE - }; - - StartupState startupState = StartupState::IDLE; - bool strHelperExecuting = false; const power::Switch_t powerSwitch = power::NO_SWITCH; From 0dbe6b985432e2e8df2f3e659310d20f0374f72b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Mar 2023 17:53:33 +0100 Subject: [PATCH 13/13] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f68f5ad..ed5f4a77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +## Changed + +- Bugfixes for STR mode transitions: Booting to mode ON with submode FIRMWARE now works properly. + Furthermore, the submode in the NORMAL mode now should be 0 instead of some ON mode submode. + # [v1.38.0] 2023-03-17 eive-tmtc: v2.19.2