diff --git a/CHANGELOG.md b/CHANGELOG.md index 82b6443c..152bbead 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,9 +19,18 @@ list yields a list of all related PRs for each release. ## Changed +- The ACS Controller Gyro Sets (raw and processed) and the MEKF dataset are diagnostics now. - Bumped FSFW for Service 11 improvement which includes size and CRC check for contained TC - Syrlinks module now always included for both EM and FM +## Fixed + +- `GyroADIS1650XHandler`: Updated handler to determine correct dynamic range from `RANG_MDL` + register readout. This is because ADIS16505-3BMLZ devices are used on the ACS board and the + previous range setting was wrong. Also fixed a small error properly set internal state + on shut-down. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/342 + # [v1.19.0] 10.01.2023 ## Changed diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index 239b3639..44b53225 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -39,7 +39,7 @@ void ObjectFactory::produce(void* args) { createRadSensorComponent(gpioComIF, *stackHandler); #endif #if OBSW_ADD_SUN_SENSORS == 1 - createSunSensorComponents(gpioComIF, spiMainComIF, pwrSwitcher, q7s::SPI_DEFAULT_DEV); + createSunSensorComponents(gpioComIF, spiMainComIF, pwrSwitcher, q7s::SPI_DEFAULT_DEV, true); #endif #if OBSW_ADD_ACS_BOARD == 1 diff --git a/bsp_q7s/obsw.cpp b/bsp_q7s/obsw.cpp index dd0c486b..91bad041 100644 --- a/bsp_q7s/obsw.cpp +++ b/bsp_q7s/obsw.cpp @@ -1,13 +1,13 @@ #include "obsw.h" +#include +#include +#include + #include #include #include -#include -#include -#include - #include "OBSWConfig.h" #include "commonConfig.h" #include "core/scheduling.h" @@ -44,8 +44,8 @@ int obsw::obsw() { const char* homedir = nullptr; homedir = getenv("HOME"); - if(homedir == nullptr) { - homedir = getpwuid(getuid())->pw_dir; + if (homedir == nullptr) { + homedir = getpwuid(getuid())->pw_dir; } std::filesystem::path bootDelayFile = std::filesystem::path(homedir) / "boot_delay_secs.txt"; // Init delay handling. diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 2f1e5360..135981b6 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 240 translations. * @details - * Generated on: 2023-01-18 14:34:15 + * Generated on: 2023-01-18 16:08:56 */ #include "translateEvents.h" diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 7593d8cc..4d0f5c1f 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 150 translations. - * Generated on: 2023-01-18 14:34:15 + * Generated on: 2023-01-18 16:08:56 */ #include "translateObjects.h" diff --git a/linux/ObjectFactory.cpp b/linux/ObjectFactory.cpp index e35d7e96..af968ddd 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -30,7 +30,8 @@ #include "mission/system/tree/payloadModeTree.h" void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, - PowerSwitchIF* pwrSwitcher, std::string spiDev) { + PowerSwitchIF* pwrSwitcher, std::string spiDev, + bool swap0And6) { using namespace gpio; GpioCookie* gpioCookieSus = new GpioCookie(); GpioCallback* susgpio = nullptr; @@ -77,7 +78,11 @@ void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiCo #if OBSW_ADD_SUN_SENSORS == 1 SusFdir* fdir = nullptr; std::array susHandlers = {}; - SpiCookie* spiCookie = new SpiCookie(addresses::SUS_0, gpioIds::CS_SUS_0, SUS::MAX_CMD_SIZE, + gpioId_t gpioId = gpioIds::CS_SUS_0; + if (swap0And6) { + gpioId = gpioIds::CS_SUS_6; + } + SpiCookie* spiCookie = new SpiCookie(addresses::SUS_0, gpioId, SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[0] = new SusHandler(objects::SUS_0_N_LOC_XFYFZM_PT_XF, 0, objects::SPI_MAIN_COM_IF, spiCookie); @@ -119,8 +124,12 @@ void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiCo fdir = new SusFdir(objects::SUS_5_N_LOC_XFYMZB_PT_ZB); susHandlers[5]->setCustomFdir(fdir); - spiCookie = new SpiCookie(addresses::SUS_6, gpioIds::CS_SUS_6, SUS::MAX_CMD_SIZE, - spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); + gpioId = gpioIds::CS_SUS_6; + if (swap0And6) { + gpioId = gpioIds::CS_SUS_0; + } + spiCookie = new SpiCookie(addresses::SUS_6, gpioId, SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, + spi::SUS_MAX1227_SPI_FREQ); susHandlers[6] = new SusHandler(objects::SUS_6_R_LOC_XFYBZM_PT_XF, 6, objects::SPI_MAIN_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_6_R_LOC_XFYBZM_PT_XF); diff --git a/linux/ObjectFactory.h b/linux/ObjectFactory.h index 3704e9bd..bdfa846f 100644 --- a/linux/ObjectFactory.h +++ b/linux/ObjectFactory.h @@ -19,7 +19,7 @@ class AcsController; namespace ObjectFactory { void createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, PowerSwitchIF* pwrSwitcher, - std::string spiDev); + std::string spiDev, bool swap0And6); void createRtdComponents(std::string spiDev, GpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher, SpiComIF* comIF); diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 2f1e5360..135981b6 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 240 translations. * @details - * Generated on: 2023-01-18 14:34:15 + * Generated on: 2023-01-18 16:08:56 */ #include "translateEvents.h" diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 7593d8cc..4d0f5c1f 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 150 translations. - * Generated on: 2023-01-18 14:34:15 + * Generated on: 2023-01-18 16:08:56 */ #include "translateObjects.h" diff --git a/mission/controller/AcsController.cpp b/mission/controller/AcsController.cpp index ca030f1d..2702cfe6 100644 --- a/mission/controller/AcsController.cpp +++ b/mission/controller/AcsController.cpp @@ -358,14 +358,14 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_L3, &gyr1VecRaw); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_ADIS, &gyr2VecRaw); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_L3, &gyr3VecRaw); - poolManager.subscribeForRegularPeriodicPacket({gyrDataRaw.getSid(), false, 5.0}); + poolManager.subscribeForDiagPeriodicPacket({gyrDataRaw.getSid(), false, 5.0}); // GYR Processed localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_VEC, &gyr0VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_VEC, &gyr1VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_VEC, &gyr2VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_VEC, &gyr3VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_VEC_TOT, &gyrVecTot); - poolManager.subscribeForRegularPeriodicPacket({gyrDataProcessed.getSid(), false, 5.0}); + poolManager.subscribeForDiagPeriodicPacket({gyrDataProcessed.getSid(), false, 5.0}); // GPS Processed localDataPoolMap.emplace(acsctrl::PoolIds::GC_LATITUDE, &gcLatitude); localDataPoolMap.emplace(acsctrl::PoolIds::GD_LONGITUDE, &gdLongitude); @@ -373,7 +373,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD // MEKF localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf); localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf); - poolManager.subscribeForRegularPeriodicPacket({mekfData.getSid(), false, 5.0}); + poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), false, 5.0}); // Ctrl Values localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat); localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat); diff --git a/mission/devices/GyroADIS1650XHandler.cpp b/mission/devices/GyroADIS1650XHandler.cpp index 79e529b6..5b59d7f6 100644 --- a/mission/devices/GyroADIS1650XHandler.cpp +++ b/mission/devices/GyroADIS1650XHandler.cpp @@ -63,6 +63,7 @@ void GyroADIS1650XHandler::doStartUp() { void GyroADIS1650XHandler::doShutDown() { commandExecuted = false; + internalState = InternalState::STARTUP; setMode(_MODE_POWER_DOWN); } @@ -99,12 +100,13 @@ ReturnValue_t GyroADIS1650XHandler::buildCommandFromCommand(DeviceCommandId_t de switch (deviceCommand) { case (ADIS1650X::READ_OUT_CONFIG): { this->rawPacketLen = ADIS1650X::CONFIG_READOUT_SIZE; - uint8_t regList[5] = {}; + uint8_t regList[6] = {}; regList[0] = ADIS1650X::DIAG_STAT_REG; regList[1] = ADIS1650X::FILTER_CTRL_REG; - regList[2] = ADIS1650X::MSC_CTRL_REG; - regList[3] = ADIS1650X::DEC_RATE_REG; - regList[4] = ADIS1650X::PROD_ID_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; prepareReadCommand(regList, sizeof(regList)); this->rawPacket = commandBuffer.data(); break; @@ -203,9 +205,10 @@ ReturnValue_t GyroADIS1650XHandler::scanForReply(const uint8_t *start, size_t re ReturnValue_t GyroADIS1650XHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { + using namespace ADIS1650X; switch (id) { case (ADIS1650X::READ_OUT_CONFIG): { - uint16_t readProdId = packet[10] << 8 | packet[11]; + uint16_t readProdId = packet[12] << 8 | packet[13]; if (((adisType == ADIS1650X::Type::ADIS16507) and (readProdId != ADIS1650X::PROD_ID_16507)) or ((adisType == ADIS1650X::Type::ADIS16505) and (readProdId != ADIS1650X::PROD_ID_16505))) { #if OBSW_VERBOSE_LEVEL >= 1 @@ -220,8 +223,32 @@ ReturnValue_t GyroADIS1650XHandler::interpretDeviceReply(DeviceCommandId_t id, PoolReadGuard rg(&configDataset); configDataset.diagStatReg.value = packet[2] << 8 | packet[3]; configDataset.filterSetting.value = packet[4] << 8 | packet[5]; - configDataset.mscCtrlReg.value = packet[6] << 8 | packet[7]; - configDataset.decRateReg.value = packet[8] << 8 | packet[9]; + uint16_t rangMdlRaw = packet[6] << 8 | packet[7]; + ADIS1650X::RangMdlBitfield bitfield = + static_cast((rangMdlRaw >> 2) & 0b11); + switch (bitfield) { + case (ADIS1650X::RangMdlBitfield::RANGE_125_1BMLZ): { + rangeMultiplicator = RANGE_1BMLZ; + break; + } + case (ADIS1650X::RangMdlBitfield::RANGE_500_2BMLZ): { + rangeMultiplicator = RANGE_2BMLZ; + break; + } + case (ADIS1650X::RangMdlBitfield::RANGE_2000_3BMLZ): { + rangeMultiplicator = RANGE_3BMLZ; + break; + } + case (RangMdlBitfield::RESERVED): { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "ADIS1650X: Unexpected value for RANG_MDL register" << std::endl; +#endif + break; + } + } + configDataset.rangMdl.value = rangMdlRaw; + configDataset.mscCtrlReg.value = packet[8] << 8 | packet[9]; + configDataset.decRateReg.value = packet[10] << 8 | packet[11]; configDataset.setValidity(true, true); if (internalState == InternalState::CONFIG) { commandExecuted = true; @@ -272,13 +299,13 @@ ReturnValue_t GyroADIS1650XHandler::handleSensorData(const uint8_t *packet) { PoolReadGuard pg(&primaryDataset); int16_t angVelocXRaw = packet[4] << 8 | packet[5]; primaryDataset.angVelocX.value = - static_cast(angVelocXRaw) / INT16_MAX * ADIS1650X::GYRO_RANGE; + static_cast(angVelocXRaw) / static_cast(INT16_MAX) * rangeMultiplicator; int16_t angVelocYRaw = packet[6] << 8 | packet[7]; primaryDataset.angVelocY.value = - static_cast(angVelocYRaw) / INT16_MAX * ADIS1650X::GYRO_RANGE; + static_cast(angVelocYRaw) / static_cast(INT16_MAX) * rangeMultiplicator; int16_t angVelocZRaw = packet[8] << 8 | packet[9]; primaryDataset.angVelocZ.value = - static_cast(angVelocZRaw) / INT16_MAX * ADIS1650X::GYRO_RANGE; + static_cast(angVelocZRaw) / static_cast(INT16_MAX) * rangeMultiplicator; float accelScaling = 0; if (adisType == ADIS1650X::Type::ADIS16507) { diff --git a/mission/devices/GyroADIS1650XHandler.h b/mission/devices/GyroADIS1650XHandler.h index 9ad56206..f664407c 100644 --- a/mission/devices/GyroADIS1650XHandler.h +++ b/mission/devices/GyroADIS1650XHandler.h @@ -46,6 +46,8 @@ class GyroADIS1650XHandler : public DeviceHandlerBase { ADIS1650X::Type adisType; AdisGyroPrimaryDataset primaryDataset; AdisGyroConfigDataset configDataset; + double rangeMultiplicator = ADIS1650X::RANGE_UNSET; + bool goToNormalMode = false; bool warningSwitch = true; diff --git a/mission/devices/devicedefinitions/GyroADIS1650XDefinitions.h b/mission/devices/devicedefinitions/GyroADIS1650XDefinitions.h index 5932b756..fb9e4d44 100644 --- a/mission/devices/devicedefinitions/GyroADIS1650XDefinitions.h +++ b/mission/devices/devicedefinitions/GyroADIS1650XDefinitions.h @@ -13,7 +13,19 @@ enum class Type { ADIS16505, ADIS16507 }; static constexpr size_t MAXIMUM_REPLY_SIZE = 64; static constexpr uint8_t WRITE_MASK = 0b1000'0000; -static constexpr uint32_t GYRO_RANGE = 125; +// Ranges in deg / s +static constexpr double RANGE_UNSET = 0.0; +static constexpr double RANGE_1BMLZ = 125.0; +static constexpr double RANGE_2BMLZ = 500.0; +static constexpr double RANGE_3BMLZ = 2000.0; + +enum RangMdlBitfield { + RANGE_125_1BMLZ = 0b00, + RANGE_500_2BMLZ = 0b01, + RESERVED = 0b10, + RANGE_2000_3BMLZ = 0b11 +}; + static constexpr uint32_t ACCELEROMETER_RANGE_16507 = 392; static constexpr float ACCELEROMETER_RANGE_16505 = 78.4; @@ -33,6 +45,7 @@ static constexpr dur_millis_t SELF_TEST_BREAK = 24; static constexpr uint8_t DIAG_STAT_REG = 0x02; static constexpr uint8_t FILTER_CTRL_REG = 0x5c; +static constexpr uint8_t RANG_MDL_REG = 0x5e; static constexpr uint8_t MSC_CTRL_REG = 0x60; static constexpr uint8_t DEC_RATE_REG = 0x64; static constexpr uint8_t GLOB_CMD = 0x68; @@ -54,7 +67,7 @@ static constexpr uint16_t BURST_SEL_BIT = 1 << 8; static constexpr uint16_t LIN_ACCEL_COMPENSATION_BIT = 1 << 7; static constexpr uint16_t POINT_PERCUSSION_COMPENSATION_BIT = 1 << 6; -static constexpr size_t CONFIG_READOUT_SIZE = 10 + 2; +static constexpr size_t CONFIG_READOUT_SIZE = 12 + 2; static constexpr size_t SENSOR_READOUT_SIZE = 20 + 2; static constexpr uint32_t ADIS_DATASET_ID = READ_SENSOR_DATA; @@ -78,6 +91,7 @@ enum PrimaryPoolIds : lp_id_t { TEMPERATURE, DIAG_STAT_REGISTER, FILTER_SETTINGS, + RANG_MDL, MSC_CTRL_REGISTER, DEC_RATE_REGISTER, }; @@ -130,6 +144,7 @@ class AdisGyroConfigDataset : public StaticLocalDataSet<5> { lp_var_t diagStatReg = lp_var_t(sid.objectId, ADIS1650X::DIAG_STAT_REGISTER); lp_var_t filterSetting = lp_var_t(sid.objectId, ADIS1650X::FILTER_SETTINGS); + lp_var_t rangMdl = lp_var_t(sid.objectId, ADIS1650X::RANG_MDL); lp_var_t mscCtrlReg = lp_var_t(sid.objectId, ADIS1650X::MSC_CTRL_REGISTER); lp_var_t decRateReg = lp_var_t(sid.objectId, ADIS1650X::DEC_RATE_REGISTER);