Merge branch 'main' into gps-changes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
This commit is contained in:
commit
99dbab9311
12
CHANGELOG.md
12
CHANGELOG.md
@ -16,6 +16,8 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
|
|
||||||
# [unreleased]
|
# [unreleased]
|
||||||
|
|
||||||
|
# [v6.3.0] 2023-08-03
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
- Small SCEX fix: The temperatur check option was not passed
|
- Small SCEX fix: The temperatur check option was not passed
|
||||||
@ -24,16 +26,26 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
- ACS Controller strategy is now actually written to the dataset for detumbling.
|
- ACS Controller strategy is now actually written to the dataset for detumbling.
|
||||||
- During detumble the fused rotation rate is now calculated.
|
- During detumble the fused rotation rate is now calculated.
|
||||||
- Detumbling is now exited when its exit value is undercut and not its entry value.
|
- Detumbling is now exited when its exit value is undercut and not its entry value.
|
||||||
|
- Rotation rate of last cycle is now stored in all cases for the fused rotational rate
|
||||||
|
calculation.
|
||||||
|
- Fused rotation rate estimation during eclipse can be disabled. This will also prevent
|
||||||
|
detumbling during eclipse, as no relevant rotational rate is available for now.
|
||||||
- `EiveSystem`: Add a small delay between triggering an event for FDIR reboots and sending the
|
- `EiveSystem`: Add a small delay between triggering an event for FDIR reboots and sending the
|
||||||
command to the core controller.
|
command to the core controller.
|
||||||
|
- PL PDU: Fixed bounds checking logic. Bound checks will only be performed for modules which are
|
||||||
|
enabled.
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
- SCEX: Only perform filesystem checks when not in OFF mode.
|
- SCEX: Only perform filesystem checks when not in OFF mode.
|
||||||
- The `EiveSystem` now only sends reboot commands targetting the same image.
|
- The `EiveSystem` now only sends reboot commands targetting the same image.
|
||||||
|
- Added 200 ms delay between switching HPA/MPA/TX/X8 and DRO GPIO pin OFF.
|
||||||
|
- PL PCDU ADC set is now automatically enabled for `NORMAL` mode transitions. It is automatically
|
||||||
|
disabled for `OFF` mode transitions.
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
|
- PL PCDU for EM build.
|
||||||
- SCEX: Add warning event if filesystem is unusable.
|
- SCEX: Add warning event if filesystem is unusable.
|
||||||
|
|
||||||
# [v6.2.0] 2023-07-26
|
# [v6.2.0] 2023-07-26
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
set(OBSW_VERSION_MAJOR 6)
|
set(OBSW_VERSION_MAJOR 6)
|
||||||
set(OBSW_VERSION_MINOR 2)
|
set(OBSW_VERSION_MINOR 3)
|
||||||
set(OBSW_VERSION_REVISION 0)
|
set(OBSW_VERSION_REVISION 0)
|
||||||
|
|
||||||
# set(CMAKE_VERBOSE TRUE)
|
# set(CMAKE_VERBOSE TRUE)
|
||||||
@ -144,7 +144,7 @@ set(OBSW_ADD_RAD_SENSORS
|
|||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
CACHE STRING "Add Rad Sensor module")
|
CACHE STRING "Add Rad Sensor module")
|
||||||
set(OBSW_ADD_PL_PCDU
|
set(OBSW_ADD_PL_PCDU
|
||||||
${INIT_VAL}
|
1
|
||||||
CACHE STRING "Add Payload PCDU modukle")
|
CACHE STRING "Add Payload PCDU modukle")
|
||||||
set(OBSW_ADD_SYRLINKS
|
set(OBSW_ADD_SYRLINKS
|
||||||
1
|
1
|
||||||
|
@ -94,6 +94,9 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#if OBSW_ADD_ACS_BOARD == 1
|
#if OBSW_ADD_ACS_BOARD == 1
|
||||||
dummyCfg.addAcsBoardDummies = false;
|
dummyCfg.addAcsBoardDummies = false;
|
||||||
#endif
|
#endif
|
||||||
|
#if OBSW_ADD_PL_PCDU == 0
|
||||||
|
dummyCfg.addPlPcduDummy = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
PowerSwitchIF* pwrSwitcher = nullptr;
|
PowerSwitchIF* pwrSwitcher = nullptr;
|
||||||
#if OBSW_ADD_GOMSPACE_PCDU == 0
|
#if OBSW_ADD_GOMSPACE_PCDU == 0
|
||||||
@ -107,6 +110,8 @@ void ObjectFactory::produce(void* args) {
|
|||||||
|
|
||||||
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
|
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
|
||||||
|
|
||||||
|
auto* stackHandler = new Stack5VHandler(*pwrSwitcher);
|
||||||
|
|
||||||
// Initialize chip select to avoid SPI bus issues.
|
// Initialize chip select to avoid SPI bus issues.
|
||||||
createRadSensorChipSelect(gpioComIF);
|
createRadSensorChipSelect(gpioComIF);
|
||||||
|
|
||||||
@ -146,6 +151,9 @@ void ObjectFactory::produce(void* args) {
|
|||||||
createStrComponents(pwrSwitcher);
|
createStrComponents(pwrSwitcher);
|
||||||
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
||||||
|
|
||||||
|
#if OBSW_ADD_PL_PCDU == 1
|
||||||
|
createPlPcduComponents(gpioComIF, spiMainComIF, pwrSwitcher, *stackHandler);
|
||||||
|
#endif
|
||||||
createPayloadComponents(gpioComIF, *pwrSwitcher);
|
createPayloadComponents(gpioComIF, *pwrSwitcher);
|
||||||
|
|
||||||
#if OBSW_ADD_CCSDS_IP_CORES == 1
|
#if OBSW_ADD_CCSDS_IP_CORES == 1
|
||||||
|
@ -81,7 +81,9 @@ void ObjectFactory::produce(void* args) {
|
|||||||
createTmpComponents(tmpDevsToAdd);
|
createTmpComponents(tmpDevsToAdd);
|
||||||
#endif
|
#endif
|
||||||
createSolarArrayDeploymentComponents(*pwrSwitcher, *gpioComIF);
|
createSolarArrayDeploymentComponents(*pwrSwitcher, *gpioComIF);
|
||||||
|
#if OBSW_ADD_PL_PCDU == 1
|
||||||
createPlPcduComponents(gpioComIF, spiMainComIF, pwrSwitcher, *stackHandler);
|
createPlPcduComponents(gpioComIF, spiMainComIF, pwrSwitcher, *stackHandler);
|
||||||
|
#endif
|
||||||
#if OBSW_ADD_SYRLINKS == 1
|
#if OBSW_ADD_SYRLINKS == 1
|
||||||
createSyrlinksComponents(pwrSwitcher);
|
createSyrlinksComponents(pwrSwitcher);
|
||||||
#endif /* OBSW_ADD_SYRLINKS == 1 */
|
#endif /* OBSW_ADD_SYRLINKS == 1 */
|
||||||
|
@ -902,8 +902,6 @@ void ObjectFactory::createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF*
|
|||||||
new PayloadPcduHandler(objects::PLPCDU_HANDLER, objects::SPI_MAIN_COM_IF, spiCookie,
|
new PayloadPcduHandler(objects::PLPCDU_HANDLER, objects::SPI_MAIN_COM_IF, spiCookie,
|
||||||
gpioComIF, SdCardManager::instance(), stackHandler, false);
|
gpioComIF, SdCardManager::instance(), stackHandler, false);
|
||||||
spiCookie->setCallbackMode(PayloadPcduHandler::extConvAsTwoCallback, plPcduHandler);
|
spiCookie->setCallbackMode(PayloadPcduHandler::extConvAsTwoCallback, plPcduHandler);
|
||||||
// plPcduHandler->enablePeriodicPrintout(true, 5);
|
|
||||||
// static_cast<void>(plPcduHandler);
|
|
||||||
#if OBSW_TEST_PL_PCDU == 1
|
#if OBSW_TEST_PL_PCDU == 1
|
||||||
plPcduHandler->setStartUpImmediately();
|
plPcduHandler->setStartUpImmediately();
|
||||||
#endif
|
#endif
|
||||||
|
@ -248,9 +248,11 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
|
|||||||
auto* scexDummy = new ScexDummy(objects::SCEX, objects::DUMMY_COM_IF, comCookieDummy);
|
auto* scexDummy = new ScexDummy(objects::SCEX, objects::DUMMY_COM_IF, comCookieDummy);
|
||||||
scexDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
scexDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||||
}
|
}
|
||||||
auto* plPcduDummy =
|
if (cfg.addPlPcduDummy) {
|
||||||
new PlPcduDummy(objects::PLPCDU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
auto* plPcduDummy =
|
||||||
plPcduDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
new PlPcduDummy(objects::PLPCDU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
||||||
|
plPcduDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||||
|
}
|
||||||
if (cfg.addPlocDummies) {
|
if (cfg.addPlocDummies) {
|
||||||
auto* plocMpsocDummy =
|
auto* plocMpsocDummy =
|
||||||
new PlocMpsocDummy(objects::PLOC_MPSOC_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
new PlocMpsocDummy(objects::PLOC_MPSOC_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
||||||
|
@ -30,6 +30,7 @@ struct DummyCfg {
|
|||||||
bool addStrDummy = true;
|
bool addStrDummy = true;
|
||||||
bool addTmpDummies = true;
|
bool addTmpDummies = true;
|
||||||
bool addRadSensorDummy = true;
|
bool addRadSensorDummy = true;
|
||||||
|
bool addPlPcduDummy = false;
|
||||||
Tmp1075Cfg tmp1075Cfg;
|
Tmp1075Cfg tmp1075Cfg;
|
||||||
bool addCamSwitcherDummy = false;
|
bool addCamSwitcherDummy = false;
|
||||||
bool addScexDummy = false;
|
bool addScexDummy = false;
|
||||||
|
@ -26,6 +26,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case 0x1:
|
case 0x1:
|
||||||
parameterWrapper->set(onBoardParams.mekfViolationTimer);
|
parameterWrapper->set(onBoardParams.mekfViolationTimer);
|
||||||
break;
|
break;
|
||||||
|
case 0x2:
|
||||||
|
parameterWrapper->set(onBoardParams.fusedRateSafeDuringEclipse);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ class AcsParameters : public HasParametersIF {
|
|||||||
struct OnBoardParams {
|
struct OnBoardParams {
|
||||||
double sampleTime = 0.4; // [s]
|
double sampleTime = 0.4; // [s]
|
||||||
uint16_t mekfViolationTimer = 750;
|
uint16_t mekfViolationTimer = 750;
|
||||||
|
uint8_t fusedRateSafeDuringEclipse = true;
|
||||||
} onBoardParams;
|
} onBoardParams;
|
||||||
|
|
||||||
struct InertiaEIVE {
|
struct InertiaEIVE {
|
||||||
|
@ -18,10 +18,18 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
|||||||
std::memcpy(fusedRotRateData->rotRateTotal.value, ZERO_VEC, 3 * sizeof(double));
|
std::memcpy(fusedRotRateData->rotRateTotal.value, ZERO_VEC, 3 * sizeof(double));
|
||||||
fusedRotRateData->setValidity(false, true);
|
fusedRotRateData->setValidity(false, true);
|
||||||
}
|
}
|
||||||
|
// store for calculation of angular acceleration
|
||||||
|
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||||
|
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (not susDataProcessed->susVecTot.isValid()) {
|
if (not susDataProcessed->susVecTot.isValid()) {
|
||||||
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateData);
|
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateData);
|
||||||
|
// store for calculation of angular acceleration
|
||||||
|
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||||
|
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +50,10 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
|||||||
fusedRotRateParallel, 3);
|
fusedRotRateParallel, 3);
|
||||||
} else {
|
} else {
|
||||||
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateData);
|
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateData);
|
||||||
|
// store for calculation of angular acceleration
|
||||||
|
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||||
|
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,11 +70,6 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
|||||||
double fusedRotRateTotal[3] = {0, 0, 0};
|
double fusedRotRateTotal[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::add(fusedRotRateParallel, fusedRotRateOrthogonal, fusedRotRateTotal);
|
VectorOperations<double>::add(fusedRotRateParallel, fusedRotRateOrthogonal, fusedRotRateTotal);
|
||||||
|
|
||||||
// store for calculation of angular acceleration
|
|
||||||
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
|
||||||
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
PoolReadGuard pg(fusedRotRateData);
|
PoolReadGuard pg(fusedRotRateData);
|
||||||
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, fusedRotRateOrthogonal,
|
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, fusedRotRateOrthogonal,
|
||||||
@ -71,11 +78,17 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
|||||||
std::memcpy(fusedRotRateData->rotRateTotal.value, fusedRotRateTotal, 3 * sizeof(double));
|
std::memcpy(fusedRotRateData->rotRateTotal.value, fusedRotRateTotal, 3 * sizeof(double));
|
||||||
fusedRotRateData->setValidity(true, true);
|
fusedRotRateData->setValidity(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store for calculation of angular acceleration
|
||||||
|
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||||
|
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FusedRotationEstimation::estimateFusedRotationRateEclipse(
|
void FusedRotationEstimation::estimateFusedRotationRateEclipse(
|
||||||
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::FusedRotRateData *fusedRotRateData) {
|
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::FusedRotRateData *fusedRotRateData) {
|
||||||
if (not gyrDataProcessed->gyrVecTot.isValid() or
|
if (not acsParameters->onBoardParams.fusedRateSafeDuringEclipse or
|
||||||
|
not gyrDataProcessed->gyrVecTot.isValid() or
|
||||||
VectorOperations<double>::norm(fusedRotRateData->rotRateTotal.value, 3) == 0) {
|
VectorOperations<double>::norm(fusedRotRateData->rotRateTotal.value, 3) == 0) {
|
||||||
{
|
{
|
||||||
PoolReadGuard pg(fusedRotRateData);
|
PoolReadGuard pg(fusedRotRateData);
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#include <fsfw/src/fsfw/datapool/PoolReadGuard.h>
|
#include <fsfw/datapool/PoolReadGuard.h>
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
#include <mission/payload/PayloadPcduHandler.h>
|
#include <mission/payload/PayloadPcduHandler.h>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
|
#include "fsfw/thermal/tcsDefinitions.h"
|
||||||
|
|
||||||
#ifdef XIPHOS_Q7S
|
#ifdef XIPHOS_Q7S
|
||||||
#include <fsfw_hal/linux/UnixFileGuard.h>
|
#include <fsfw_hal/linux/UnixFileGuard.h>
|
||||||
@ -64,6 +66,16 @@ void PayloadPcduHandler::doShutDown() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state = States::PL_PCDU_OFF;
|
state = States::PL_PCDU_OFF;
|
||||||
|
quickTransitionAlreadyCalled = false;
|
||||||
|
{
|
||||||
|
PoolReadGuard pg(&adcSet);
|
||||||
|
adcSet.setReportingEnabled(false);
|
||||||
|
adcSet.tempC = thermal::INVALID_TEMPERATURE;
|
||||||
|
|
||||||
|
std::memset(adcSet.channels.value, 0, sizeof(adcSet.channels.value));
|
||||||
|
std::memset(adcSet.processed.value, 0, sizeof(adcSet.processed.value));
|
||||||
|
adcSet.setValidity(false, true);
|
||||||
|
}
|
||||||
// No need to set mode _MODE_POWER_DOWN, power switching was already handled
|
// No need to set mode _MODE_POWER_DOWN, power switching was already handled
|
||||||
setMode(MODE_OFF);
|
setMode(MODE_OFF);
|
||||||
}
|
}
|
||||||
@ -73,14 +85,7 @@ void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
|||||||
stateMachineToNormal(modeFrom, subModeFrom);
|
stateMachineToNormal(modeFrom, subModeFrom);
|
||||||
return;
|
return;
|
||||||
} else if (getMode() == _MODE_TO_ON and modeFrom == MODE_NORMAL) {
|
} else if (getMode() == _MODE_TO_ON and modeFrom == MODE_NORMAL) {
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_HPA);
|
pullAllGpiosLow(200);
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_MPA);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_X8);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_DRO);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT0);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT1);
|
|
||||||
state = States::STACK_5V_CORRECT;
|
state = States::STACK_5V_CORRECT;
|
||||||
}
|
}
|
||||||
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
|
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
|
||||||
@ -89,6 +94,11 @@ void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
|||||||
ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_t subModeFrom) {
|
ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||||
using namespace plpcdu;
|
using namespace plpcdu;
|
||||||
bool doFinish = true;
|
bool doFinish = true;
|
||||||
|
if (toNormalOneShot) {
|
||||||
|
PoolReadGuard pg(&adcSet);
|
||||||
|
adcSet.setReportingEnabled(true);
|
||||||
|
toNormalOneShot = false;
|
||||||
|
}
|
||||||
if (((getSubmode() >> SOLID_STATE_RELAYS_ADC_ON) & 0b1) == 1) {
|
if (((getSubmode() >> SOLID_STATE_RELAYS_ADC_ON) & 0b1) == 1) {
|
||||||
if (state == States::PL_PCDU_OFF) {
|
if (state == States::PL_PCDU_OFF) {
|
||||||
sif::error << "PayloadPcduHandler::stateMachineToNormal: Unexpected state PL_PCDU_OFF"
|
sif::error << "PayloadPcduHandler::stateMachineToNormal: Unexpected state PL_PCDU_OFF"
|
||||||
@ -114,23 +124,23 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_
|
|||||||
state = States::ON_TRANS_ADC_CLOSE_ZERO;
|
state = States::ON_TRANS_ADC_CLOSE_ZERO;
|
||||||
adcCountdown.setTimeout(50);
|
adcCountdown.setTimeout(50);
|
||||||
adcCountdown.resetTimer();
|
adcCountdown.resetTimer();
|
||||||
adcState = AdcStates::BOOT_DELAY;
|
adcState = AdcState::BOOT_DELAY;
|
||||||
doFinish = false;
|
doFinish = false;
|
||||||
// If the values are not close to zero, we should not allow transition
|
// If the values are not close to zero, we should not allow transition
|
||||||
monMode = MonitoringMode::CLOSE_TO_ZERO;
|
monMode = MonitoringMode::CLOSE_TO_ZERO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (state == States::ON_TRANS_ADC_CLOSE_ZERO) {
|
if (state == States::ON_TRANS_ADC_CLOSE_ZERO) {
|
||||||
if (adcState == AdcStates::BOOT_DELAY) {
|
if (adcState == AdcState::BOOT_DELAY) {
|
||||||
doFinish = false;
|
doFinish = false;
|
||||||
if (adcCountdown.hasTimedOut()) {
|
if (adcCountdown.hasTimedOut()) {
|
||||||
adcState = AdcStates::SEND_SETUP;
|
adcState = AdcState::SEND_SETUP;
|
||||||
adcCmdExecuted = false;
|
adcCmdExecuted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (adcState == AdcStates::SEND_SETUP) {
|
if (adcState == AdcState::SEND_SETUP) {
|
||||||
if (adcCmdExecuted) {
|
if (adcCmdExecuted) {
|
||||||
adcState = AdcStates::NORMAL;
|
adcState = AdcState::NORMAL;
|
||||||
doFinish = true;
|
doFinish = true;
|
||||||
adcCountdown.setTimeout(100);
|
adcCountdown.setTimeout(100);
|
||||||
adcCountdown.resetTimer();
|
adcCountdown.resetTimer();
|
||||||
@ -167,6 +177,7 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_
|
|||||||
switchHandler(MPA_ON, gpioIds::PLPCDU_ENB_MPA, "MPA");
|
switchHandler(MPA_ON, gpioIds::PLPCDU_ENB_MPA, "MPA");
|
||||||
switchHandler(HPA_ON, gpioIds::PLPCDU_ENB_HPA, "HPA");
|
switchHandler(HPA_ON, gpioIds::PLPCDU_ENB_HPA, "HPA");
|
||||||
if (doFinish) {
|
if (doFinish) {
|
||||||
|
toNormalOneShot = true;
|
||||||
setMode(MODE_NORMAL);
|
setMode(MODE_NORMAL);
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
@ -174,11 +185,11 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_
|
|||||||
|
|
||||||
ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||||
switch (adcState) {
|
switch (adcState) {
|
||||||
case (AdcStates::SEND_SETUP): {
|
case (AdcState::SEND_SETUP): {
|
||||||
*id = plpcdu::SETUP_CMD;
|
*id = plpcdu::SETUP_CMD;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
}
|
}
|
||||||
case (AdcStates::NORMAL): {
|
case (AdcState::NORMAL): {
|
||||||
*id = plpcdu::READ_WITH_TEMP_EXT;
|
*id = plpcdu::READ_WITH_TEMP_EXT;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
}
|
}
|
||||||
@ -190,7 +201,7 @@ ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PayloadPcduHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
ReturnValue_t PayloadPcduHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||||
if (adcState == AdcStates::SEND_SETUP) {
|
if (adcState == AdcState::SEND_SETUP) {
|
||||||
*id = plpcdu::SETUP_CMD;
|
*id = plpcdu::SETUP_CMD;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
}
|
}
|
||||||
@ -211,9 +222,9 @@ void PayloadPcduHandler::updateSwitchGpio(gpioId_t id, gpio::Levels level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PayloadPcduHandler::fillCommandAndReplyMap() {
|
void PayloadPcduHandler::fillCommandAndReplyMap() {
|
||||||
insertInCommandAndReplyMap(plpcdu::READ_CMD, 2, &adcSet);
|
insertInCommandAndReplyMap(plpcdu::READ_CMD, 2);
|
||||||
insertInCommandAndReplyMap(plpcdu::READ_TEMP_EXT, 1, &adcSet);
|
insertInCommandAndReplyMap(plpcdu::READ_TEMP_EXT, 1);
|
||||||
insertInCommandAndReplyMap(plpcdu::READ_WITH_TEMP_EXT, 1, &adcSet);
|
insertInCommandAndReplyMap(plpcdu::READ_WITH_TEMP_EXT, 1);
|
||||||
insertInCommandAndReplyMap(plpcdu::SETUP_CMD, 1);
|
insertInCommandAndReplyMap(plpcdu::SETUP_CMD, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,27 +288,31 @@ ReturnValue_t PayloadPcduHandler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (READ_CMD): {
|
case (READ_CMD): {
|
||||||
PoolReadGuard pg(&adcSet);
|
{
|
||||||
if (pg.getReadResult() != returnvalue::OK) {
|
PoolReadGuard pg(&adcSet);
|
||||||
return pg.getReadResult();
|
if (pg.getReadResult() != returnvalue::OK) {
|
||||||
|
return pg.getReadResult();
|
||||||
|
}
|
||||||
|
handleExtConvRead(packet);
|
||||||
|
checkAdcValues();
|
||||||
|
adcSet.setValidity(true, true);
|
||||||
}
|
}
|
||||||
handleExtConvRead(packet);
|
|
||||||
checkAdcValues();
|
|
||||||
adcSet.setValidity(true, true);
|
|
||||||
handlePrintout();
|
handlePrintout();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (READ_WITH_TEMP_EXT): {
|
case (READ_WITH_TEMP_EXT): {
|
||||||
PoolReadGuard pg(&adcSet);
|
{
|
||||||
if (pg.getReadResult() != returnvalue::OK) {
|
PoolReadGuard pg(&adcSet);
|
||||||
return pg.getReadResult();
|
if (pg.getReadResult() != returnvalue::OK) {
|
||||||
|
return pg.getReadResult();
|
||||||
|
}
|
||||||
|
handleExtConvRead(packet);
|
||||||
|
uint8_t tempStartIdx = ADC_REPLY_SIZE + TEMP_REPLY_SIZE - 2;
|
||||||
|
adcSet.tempC.value =
|
||||||
|
max1227::getTemperature(packet[tempStartIdx] << 8 | packet[tempStartIdx + 1]);
|
||||||
|
checkAdcValues();
|
||||||
|
adcSet.setValidity(true, true);
|
||||||
}
|
}
|
||||||
handleExtConvRead(packet);
|
|
||||||
uint8_t tempStartIdx = ADC_REPLY_SIZE + TEMP_REPLY_SIZE - 2;
|
|
||||||
adcSet.tempC.value =
|
|
||||||
max1227::getTemperature(packet[tempStartIdx] << 8 | packet[tempStartIdx + 1]);
|
|
||||||
checkAdcValues();
|
|
||||||
adcSet.setValidity(true, true);
|
|
||||||
handlePrintout();
|
handlePrintout();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -367,16 +382,9 @@ void PayloadPcduHandler::enablePeriodicPrintout(bool enable, uint8_t divider) {
|
|||||||
|
|
||||||
void PayloadPcduHandler::quickTransitionBackToOff(bool startTransitionToOff, bool notifyFdir) {
|
void PayloadPcduHandler::quickTransitionBackToOff(bool startTransitionToOff, bool notifyFdir) {
|
||||||
States currentState = state;
|
States currentState = state;
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_HPA);
|
pullAllGpiosLow(200);
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_MPA);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_X8);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_DRO);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT0);
|
|
||||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT1);
|
|
||||||
state = States::STACK_5V_SWITCHING;
|
state = States::STACK_5V_SWITCHING;
|
||||||
adcState = AdcStates::OFF;
|
adcState = AdcState::OFF;
|
||||||
if (startTransitionToOff) {
|
if (startTransitionToOff) {
|
||||||
startTransition(MODE_OFF, 0);
|
startTransition(MODE_OFF, 0);
|
||||||
}
|
}
|
||||||
@ -405,10 +413,13 @@ void PayloadPcduHandler::checkAdcValues() {
|
|||||||
adcSet.processed[U_DRO_DIV_6] = static_cast<float>(adcSet.channels[11]) * SCALE_VOLTAGE;
|
adcSet.processed[U_DRO_DIV_6] = static_cast<float>(adcSet.channels[11]) * SCALE_VOLTAGE;
|
||||||
float lowerBound = 0.0;
|
float lowerBound = 0.0;
|
||||||
float upperBound = 0.0;
|
float upperBound = 0.0;
|
||||||
bool adcTransition = false;
|
bool adcTransition = adcState == AdcState::NORMAL and adcCountdown.isBusy();
|
||||||
adcTransition = state == States::ON_TRANS_DRO and adcCountdown.isBusy();
|
if (NO_ADC_CHECKS or adcTransition) {
|
||||||
// Now check against voltage and current limits, depending on state
|
return;
|
||||||
if (state >= States::ON_TRANS_DRO and not adcTransition) {
|
}
|
||||||
|
// Now check against voltage and current limits.
|
||||||
|
uint8_t submode = getSubmode();
|
||||||
|
if (((submode >> NormalSubmodeBits::DRO_ON) & 0b1) == 0b1) {
|
||||||
if (ssrToDroInjectionRequested) {
|
if (ssrToDroInjectionRequested) {
|
||||||
handleFailureInjection("SSR to DRO", NEG_V_OUT_OF_BOUNDS);
|
handleFailureInjection("SSR to DRO", NEG_V_OUT_OF_BOUNDS);
|
||||||
ssrToDroInjectionRequested = false;
|
ssrToDroInjectionRequested = false;
|
||||||
@ -435,8 +446,7 @@ void PayloadPcduHandler::checkAdcValues() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
adcTransition = state == States::ON_TRANS_X8 and adcCountdown.isBusy();
|
if (((submode >> NormalSubmodeBits::X8_ON) & 0b1) == 0b1) {
|
||||||
if (state >= States::ON_TRANS_X8 and not adcTransition) {
|
|
||||||
if (droToX8InjectionRequested) {
|
if (droToX8InjectionRequested) {
|
||||||
handleFailureInjection("X8 to TX", U_X8_OUT_OF_BOUNDS);
|
handleFailureInjection("X8 to TX", U_X8_OUT_OF_BOUNDS);
|
||||||
droToX8InjectionRequested = false;
|
droToX8InjectionRequested = false;
|
||||||
@ -453,8 +463,7 @@ void PayloadPcduHandler::checkAdcValues() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
adcTransition = state == States::ON_TRANS_TX and adcCountdown.isBusy();
|
if (((submode >> NormalSubmodeBits::TX_ON) & 0b1) == 0b1) {
|
||||||
if (state >= States::ON_TRANS_TX and not adcTransition) {
|
|
||||||
if (txToMpaInjectionRequested) {
|
if (txToMpaInjectionRequested) {
|
||||||
handleFailureInjection("TX to MPA", U_TX_OUT_OF_BOUNDS);
|
handleFailureInjection("TX to MPA", U_TX_OUT_OF_BOUNDS);
|
||||||
txToMpaInjectionRequested = false;
|
txToMpaInjectionRequested = false;
|
||||||
@ -471,8 +480,7 @@ void PayloadPcduHandler::checkAdcValues() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
adcTransition = state == States::ON_TRANS_MPA and adcCountdown.isBusy();
|
if (((submode >> NormalSubmodeBits::MPA_ON) & 0b1) == 0b1) {
|
||||||
if (state >= States::ON_TRANS_MPA and not adcTransition) {
|
|
||||||
if (mpaToHpaInjectionRequested) {
|
if (mpaToHpaInjectionRequested) {
|
||||||
handleFailureInjection("MPA to HPA", U_HPA_OUT_OF_BOUNDS);
|
handleFailureInjection("MPA to HPA", U_HPA_OUT_OF_BOUNDS);
|
||||||
mpaToHpaInjectionRequested = false;
|
mpaToHpaInjectionRequested = false;
|
||||||
@ -489,8 +497,7 @@ void PayloadPcduHandler::checkAdcValues() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
adcTransition = state == States::ON_TRANS_HPA and adcCountdown.isBusy();
|
if (((submode >> NormalSubmodeBits::HPA_ON) & 0b1) == 0b1) {
|
||||||
if (state >= States::ON_TRANS_HPA and not adcTransition) {
|
|
||||||
if (allOnInjectRequested) {
|
if (allOnInjectRequested) {
|
||||||
handleFailureInjection("All On", U_HPA_OUT_OF_BOUNDS);
|
handleFailureInjection("All On", U_HPA_OUT_OF_BOUNDS);
|
||||||
allOnInjectRequested = false;
|
allOnInjectRequested = false;
|
||||||
@ -677,6 +684,18 @@ void PayloadPcduHandler::handleFailureInjection(std::string output, Event event)
|
|||||||
droToX8InjectionRequested = false;
|
droToX8InjectionRequested = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PayloadPcduHandler::pullAllGpiosLow(uint32_t delayBeforeSwitchingOffDro) {
|
||||||
|
sif::info << "Pulling all PL PCDU GPIOs to low" << std::endl;
|
||||||
|
gpioIF->pullLow(gpioIds::PLPCDU_ENB_HPA);
|
||||||
|
gpioIF->pullLow(gpioIds::PLPCDU_ENB_MPA);
|
||||||
|
gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX);
|
||||||
|
gpioIF->pullLow(gpioIds::PLPCDU_ENB_X8);
|
||||||
|
TaskFactory::delayTask(delayBeforeSwitchingOffDro);
|
||||||
|
gpioIF->pullLow(gpioIds::PLPCDU_ENB_DRO);
|
||||||
|
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT0);
|
||||||
|
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT1);
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t PayloadPcduHandler::handleDoubleParamUpdate(std::string key,
|
ReturnValue_t PayloadPcduHandler::handleDoubleParamUpdate(std::string key,
|
||||||
ParameterWrapper* parameterWrapper,
|
ParameterWrapper* parameterWrapper,
|
||||||
const ParameterWrapper* newValues) {
|
const ParameterWrapper* newValues) {
|
||||||
@ -692,6 +711,8 @@ ReturnValue_t PayloadPcduHandler::handleDoubleParamUpdate(std::string key,
|
|||||||
return params.writeJsonFile();
|
return params.writeJsonFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalPoolDataSetBase* PayloadPcduHandler::getDataSetHandle(sid_t sid) { return &adcSet; }
|
||||||
|
|
||||||
#ifdef XIPHOS_Q7S
|
#ifdef XIPHOS_Q7S
|
||||||
ReturnValue_t PayloadPcduHandler::extConvAsTwoCallback(SpiComIF* comIf, SpiCookie* cookie,
|
ReturnValue_t PayloadPcduHandler::extConvAsTwoCallback(SpiComIF* comIf, SpiCookie* cookie,
|
||||||
const uint8_t* sendData, size_t sendLen,
|
const uint8_t* sendData, size_t sendLen,
|
||||||
|
@ -76,6 +76,8 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr bool NO_ADC_CHECKS = false;
|
||||||
|
|
||||||
enum class States : uint8_t {
|
enum class States : uint8_t {
|
||||||
PL_PCDU_OFF,
|
PL_PCDU_OFF,
|
||||||
STACK_5V_SWITCHING,
|
STACK_5V_SWITCHING,
|
||||||
@ -84,20 +86,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
|||||||
// Solid State Relay, enable battery voltages VBAT0 and VBAT1. This will also switch on
|
// Solid State Relay, enable battery voltages VBAT0 and VBAT1. This will also switch on
|
||||||
// the ADC
|
// the ADC
|
||||||
ON_TRANS_SSR,
|
ON_TRANS_SSR,
|
||||||
ON_TRANS_ADC_CLOSE_ZERO,
|
ON_TRANS_ADC_CLOSE_ZERO
|
||||||
// Enable Dielectric Resonant Oscillator and start monitoring voltages as
|
|
||||||
// soon as DRO voltage reaches 6V
|
|
||||||
ON_TRANS_DRO,
|
|
||||||
// Switch on X8 compoennt and monitor voltages for 5 seconds
|
|
||||||
ON_TRANS_X8,
|
|
||||||
// Switch on TX component and monitor voltages for 5 seconds
|
|
||||||
ON_TRANS_TX,
|
|
||||||
// Switch on MPA component and monitor voltages for 5 seconds
|
|
||||||
ON_TRANS_MPA,
|
|
||||||
// Switch on HPA component and monitor voltages for 5 seconds
|
|
||||||
ON_TRANS_HPA,
|
|
||||||
// All components of the experiment are on
|
|
||||||
PL_PCDU_ON,
|
|
||||||
} state = States::PL_PCDU_OFF;
|
} state = States::PL_PCDU_OFF;
|
||||||
|
|
||||||
duallane::Submodes pwrSubmode = duallane::Submodes::A_SIDE;
|
duallane::Submodes pwrSubmode = duallane::Submodes::A_SIDE;
|
||||||
@ -106,7 +95,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
|||||||
|
|
||||||
enum class MonitoringMode { NONE, CLOSE_TO_ZERO, NEGATIVE } monMode = MonitoringMode::NONE;
|
enum class MonitoringMode { NONE, CLOSE_TO_ZERO, NEGATIVE } monMode = MonitoringMode::NONE;
|
||||||
|
|
||||||
enum class AdcStates { OFF, BOOT_DELAY, SEND_SETUP, NORMAL } adcState = AdcStates::OFF;
|
enum class AdcState { OFF, BOOT_DELAY, SEND_SETUP, NORMAL } adcState = AdcState::OFF;
|
||||||
|
|
||||||
bool goToNormalMode = false;
|
bool goToNormalMode = false;
|
||||||
plpcdu::PlPcduAdcSet adcSet;
|
plpcdu::PlPcduAdcSet adcSet;
|
||||||
@ -128,6 +117,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
|||||||
bool mpaToHpaInjectionRequested = false;
|
bool mpaToHpaInjectionRequested = false;
|
||||||
bool allOnInjectRequested = false;
|
bool allOnInjectRequested = false;
|
||||||
bool clearSetOnOffFlag = true;
|
bool clearSetOnOffFlag = true;
|
||||||
|
bool toNormalOneShot = true;
|
||||||
|
|
||||||
PeriodicOperationDivider opDivider = PeriodicOperationDivider(5);
|
PeriodicOperationDivider opDivider = PeriodicOperationDivider(5);
|
||||||
uint8_t tempReadDivisor = 1;
|
uint8_t tempReadDivisor = 1;
|
||||||
@ -168,6 +158,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
|||||||
|
|
||||||
void handleExtConvRead(const uint8_t* bufStart);
|
void handleExtConvRead(const uint8_t* bufStart);
|
||||||
void handlePrintout();
|
void handlePrintout();
|
||||||
|
void pullAllGpiosLow(uint32_t delayBeforeSwitchingOffDro);
|
||||||
void checkAdcValues();
|
void checkAdcValues();
|
||||||
void handleOutOfBoundsPrintout();
|
void handleOutOfBoundsPrintout();
|
||||||
void checkJsonFileInit();
|
void checkJsonFileInit();
|
||||||
@ -178,6 +169,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
|||||||
ReturnValue_t serializeFloat(uint32_t& param, float val);
|
ReturnValue_t serializeFloat(uint32_t& param, float val);
|
||||||
ReturnValue_t handleDoubleParamUpdate(std::string key, ParameterWrapper* parameterWrapper,
|
ReturnValue_t handleDoubleParamUpdate(std::string key, ParameterWrapper* parameterWrapper,
|
||||||
const ParameterWrapper* newValues);
|
const ParameterWrapper* newValues);
|
||||||
|
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* LINUX_DEVICES_PLPCDUHANDLER_H_ */
|
#endif /* LINUX_DEVICES_PLPCDUHANDLER_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user