Merge branch 'develop' into hotfix_acs_brd_polling
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...

This commit is contained in:
Robin Müller 2023-03-03 15:36:35 +01:00
commit 8720dacb7f
10 changed files with 124 additions and 110 deletions

View File

@ -28,6 +28,9 @@ will consitute of a breaking change warranting a new major release:
- IMTQ: Sets were filled with wrong data, e.g. Raw MTM was filled with calibrated MTM measurements. - IMTQ: Sets were filled with wrong data, e.g. Raw MTM was filled with calibrated MTM measurements.
- Set RM3100 dataset to valid. - Set RM3100 dataset to valid.
- Fixed units in calculation of ACS control laws safe and detumble. - Fixed units in calculation of ACS control laws safe and detumble.
- Bump FSFW for change in Countdown: Use system clock instead of reading uptime from file
to prevent possible race condition.
- GPS: No fix for 30 minutes considered a faulty now instead of 5 hours.
## Added ## Added

2
fsfw

@ -1 +1 @@
Subproject commit 245886c55500b9e70ba71eab68c46d44af9f6836 Subproject commit 6e17e45506b0d9834d3ae9ded6f044e13e3c4abd

View File

@ -4,6 +4,7 @@
#include <fsfw/globalfunctions/arrayprinter.h> #include <fsfw/globalfunctions/arrayprinter.h>
#include <fsfw/tasks/SemaphoreFactory.h> #include <fsfw/tasks/SemaphoreFactory.h>
#include <fsfw/tasks/TaskFactory.h> #include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
#include <fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h> #include <fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h>
#include <fsfw_hal/devicehandlers/devicedefinitions/mgmLis3Helpers.h> #include <fsfw_hal/devicehandlers/devicedefinitions/mgmLis3Helpers.h>
#include <fsfw_hal/linux/UnixFileGuard.h> #include <fsfw_hal/linux/UnixFileGuard.h>
@ -25,20 +26,24 @@ AcsBoardPolling::AcsBoardPolling(object_id_t objectId, SpiComIF& lowLevelComIF,
ReturnValue_t AcsBoardPolling::performOperation(uint8_t operationCode) { ReturnValue_t AcsBoardPolling::performOperation(uint8_t operationCode) {
while (true) { while (true) {
ipcLock->lockMutex(); ipcLock->lockMutex(LOCK_TYPE, LOCK_TIMEOUT);
state = InternalState::IDLE; state = InternalState::IDLE;
ipcLock->unlockMutex(); ipcLock->unlockMutex();
semaphore->acquire(); semaphore->acquire();
// Give all tasks or the PST some time to submit all consecutive requests. // Give all tasks or the PST some time to submit all consecutive requests.
TaskFactory::delayTask(2); TaskFactory::delayTask(2);
gyroAdisHandler(gyro0Adis); {
gyroAdisHandler(gyro2Adis); // Measured to take 0-1 ms in debug build.
gyroL3gHandler(gyro1L3g); // Stopwatch watch;
gyroL3gHandler(gyro3L3g); gyroAdisHandler(gyro0Adis);
mgmRm3100Handler(mgm1Rm3100); gyroAdisHandler(gyro2Adis);
mgmRm3100Handler(mgm3Rm3100); gyroL3gHandler(gyro1L3g);
mgmLis3Handler(mgm0Lis3); gyroL3gHandler(gyro3L3g);
mgmLis3Handler(mgm2Lis3); mgmRm3100Handler(mgm1Rm3100);
mgmRm3100Handler(mgm3Rm3100);
mgmLis3Handler(mgm0Lis3);
mgmLis3Handler(mgm2Lis3);
}
// To prevent task being not reactivated by tardy tasks // To prevent task being not reactivated by tardy tasks
TaskFactory::delayTask(20); TaskFactory::delayTask(20);
} }
@ -109,7 +114,6 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
if (req->mode == acs::SimpleSensorMode::NORMAL) { if (req->mode == acs::SimpleSensorMode::NORMAL) {
adis.type = req->type; adis.type = req->type;
adis.countdown.setTimeout(adis1650x::START_UP_TIME); adis.countdown.setTimeout(adis1650x::START_UP_TIME);
adis.countdown.resetTimer();
if (adis.type == adis1650x::Type::ADIS16507) { if (adis.type == adis1650x::Type::ADIS16507) {
adis.ownReply.data.accelScaling = adis1650x::ACCELEROMETER_RANGE_16507; adis.ownReply.data.accelScaling = adis1650x::ACCELEROMETER_RANGE_16507;
} else if (adis.type == adis1650x::Type::ADIS16505) { } else if (adis.type == adis1650x::Type::ADIS16505) {
@ -170,7 +174,6 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
return returnvalue::FAILED; return returnvalue::FAILED;
} }
auto* req = reinterpret_cast<const acs::MgmRm3100Request*>(sendData); auto* req = reinterpret_cast<const acs::MgmRm3100Request*>(sendData);
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
if (req->mode != mgm.mode) { if (req->mode != mgm.mode) {
if (req->mode == acs::SimpleSensorMode::NORMAL) { if (req->mode == acs::SimpleSensorMode::NORMAL) {
mgm.performStartup = true; mgm.performStartup = true;
@ -181,45 +184,47 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
} }
return returnvalue::OK; return returnvalue::OK;
}; };
switch (spiCookie->getChipSelectPin()) { {
case (gpioIds::MGM_0_LIS3_CS): { MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
handleLis3Request(mgm0Lis3); switch (spiCookie->getChipSelectPin()) {
break; case (gpioIds::MGM_0_LIS3_CS): {
handleLis3Request(mgm0Lis3);
break;
}
case (gpioIds::MGM_1_RM3100_CS): {
handleRm3100Request(mgm1Rm3100);
break;
}
case (gpioIds::MGM_2_LIS3_CS): {
handleLis3Request(mgm2Lis3);
break;
}
case (gpioIds::MGM_3_RM3100_CS): {
handleRm3100Request(mgm3Rm3100);
break;
}
case (gpioIds::GYRO_0_ADIS_CS): {
handleAdisRequest(gyro0Adis);
break;
}
case (gpioIds::GYRO_2_ADIS_CS): {
handleAdisRequest(gyro2Adis);
break;
}
case (gpioIds::GYRO_1_L3G_CS): {
handleL3gRequest(gyro1L3g);
break;
}
case (gpioIds::GYRO_3_L3G_CS): {
handleL3gRequest(gyro3L3g);
break;
}
} }
case (gpioIds::MGM_1_RM3100_CS): { if (state == InternalState::IDLE) {
handleRm3100Request(mgm1Rm3100); state = InternalState::BUSY;
break;
}
case (gpioIds::MGM_2_LIS3_CS): {
handleLis3Request(mgm2Lis3);
break;
}
case (gpioIds::MGM_3_RM3100_CS): {
handleRm3100Request(mgm3Rm3100);
break;
}
case (gpioIds::GYRO_0_ADIS_CS): {
handleAdisRequest(gyro0Adis);
break;
}
case (gpioIds::GYRO_2_ADIS_CS): {
handleAdisRequest(gyro2Adis);
break;
}
case (gpioIds::GYRO_1_L3G_CS): {
handleL3gRequest(gyro1L3g);
break;
}
case (gpioIds::GYRO_3_L3G_CS): {
handleL3gRequest(gyro3L3g);
break;
} }
} }
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); semaphore->release();
if (state == InternalState::IDLE) {
state = InternalState::BUSY;
semaphore->release();
}
return returnvalue::OK; return returnvalue::OK;
} }
@ -291,8 +296,8 @@ ReturnValue_t AcsBoardPolling::readReceivedMessage(CookieIF* cookie, uint8_t** b
void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) { void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
ReturnValue_t result; ReturnValue_t result;
acs::SimpleSensorMode mode; acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
bool gyroPerformStartup; bool gyroPerformStartup = false;
{ {
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
mode = l3g.mode; mode = l3g.mode;
@ -437,7 +442,7 @@ ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen
void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) { void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
ReturnValue_t result; ReturnValue_t result;
acs::SimpleSensorMode mode; acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
bool cdHasTimedOut = false; bool cdHasTimedOut = false;
bool mustPerformStartup = false; bool mustPerformStartup = false;
{ {
@ -539,7 +544,7 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) { void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {
ReturnValue_t result; ReturnValue_t result;
acs::SimpleSensorMode mode; acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
bool mustPerformStartup = false; bool mustPerformStartup = false;
{ {
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
@ -632,7 +637,7 @@ void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {
void AcsBoardPolling::mgmRm3100Handler(MgmRm3100& mgm) { void AcsBoardPolling::mgmRm3100Handler(MgmRm3100& mgm) {
ReturnValue_t result; ReturnValue_t result;
acs::SimpleSensorMode mode; acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
bool mustPerformStartup = false; bool mustPerformStartup = false;
{ {
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);

View File

@ -19,9 +19,7 @@
GpsHyperionLinuxController::GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId, GpsHyperionLinuxController::GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId,
bool debugHyperionGps) bool debugHyperionGps)
: ExtendedControllerBase(objectId), gpsSet(this), debugHyperionGps(debugHyperionGps) { : ExtendedControllerBase(objectId), gpsSet(this), debugHyperionGps(debugHyperionGps) {}
timeUpdateCd.resetTimer();
}
GpsHyperionLinuxController::~GpsHyperionLinuxController() { GpsHyperionLinuxController::~GpsHyperionLinuxController() {
gps_stream(&gps, WATCH_DISABLE, nullptr); gps_stream(&gps, WATCH_DISABLE, nullptr);
@ -196,8 +194,8 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
if (mode != MODE_OFF) { if (mode != MODE_OFF) {
if (maxTimeToReachFix.hasTimedOut() and oneShotSwitches.cantGetFixSwitch) { if (maxTimeToReachFix.hasTimedOut() and oneShotSwitches.cantGetFixSwitch) {
sif::warning << "GpsHyperionLinuxController: No mode could be set in allowed " sif::warning << "GpsHyperionLinuxController: No mode could be set in allowed "
<< maxTimeToReachFix.timeout / 1000 << " seconds" << std::endl; << maxTimeToReachFix.getTimeoutMs() / 1000 << " seconds" << std::endl;
triggerEvent(GpsHyperion::CANT_GET_FIX, maxTimeToReachFix.timeout); triggerEvent(GpsHyperion::CANT_GET_FIX, maxTimeToReachFix.getTimeoutMs());
oneShotSwitches.cantGetFixSwitch = false; oneShotSwitches.cantGetFixSwitch = false;
} }
modeIsSet = false; modeIsSet = false;

View File

@ -23,7 +23,8 @@
*/ */
class GpsHyperionLinuxController : public ExtendedControllerBase { class GpsHyperionLinuxController : public ExtendedControllerBase {
public: public:
static constexpr uint32_t MAX_SECONDS_TO_REACH_FIX = 60 * 60 * 5; // 30 minutes
static constexpr uint32_t MAX_SECONDS_TO_REACH_FIX = 60 * 30;
enum ReadModes { SHM = 0, SOCKET = 1 }; enum ReadModes { SHM = 0, SOCKET = 1 };
@ -79,7 +80,6 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
bool debugHyperionGps = false; bool debugHyperionGps = false;
int32_t noModeSetCntr = 0; int32_t noModeSetCntr = 0;
Countdown timeUpdateCd = Countdown(60);
// Returns true if the function should be called again or false if other // Returns true if the function should be called again or false if other
// controller handling can be done. // controller handling can be done.

View File

@ -57,19 +57,28 @@ bool Max31865RtdPolling::rtdIsActive(uint8_t idx) {
return false; return false;
} }
bool Max31865RtdPolling::periodicInitHandling() { ReturnValue_t Max31865RtdPolling::periodicInitHandling() {
using namespace MAX31865; using namespace MAX31865;
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
for (auto& rtd : rtds) { for (auto& rtd : rtds) {
if (rtd == nullptr) { if (rtd == nullptr) {
continue; continue;
} }
MutexGuard mg(readerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); bool mustPerformInitHandling = false;
if (mg.getLockResult() != returnvalue::OK) { bool doWriteLowThreshold = false;
sif::warning << "Max31865RtdReader::periodicInitHandling: Mutex lock failed" << std::endl; bool doWriteHighThreshold = false;
return false; {
MutexGuard mg(readerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
if (mg.getLockResult() != returnvalue::OK) {
sif::warning << "Max31865RtdReader::periodicInitHandling: Mutex lock failed" << std::endl;
continue;
}
mustPerformInitHandling =
(rtd->on or rtd->db.active) and not rtd->db.configured and rtd->cd.hasTimedOut();
doWriteHighThreshold = rtd->writeHighThreshold;
doWriteLowThreshold = rtd->writeLowThreshold;
} }
if ((rtd->on or rtd->db.active) and not rtd->db.configured and rtd->cd.hasTimedOut()) { if (mustPerformInitHandling) {
// Please note that using the manual CS lock wrapper here is problematic. Might be a SPI // Please note that using the manual CS lock wrapper here is problematic. Might be a SPI
// or hardware specific issue where the CS needs to be pulled high and then low again // or hardware specific issue where the CS needs to be pulled high and then low again
// between transfers // between transfers
@ -78,13 +87,13 @@ bool Max31865RtdPolling::periodicInitHandling() {
handleSpiError(rtd, result, "writeCfgReg"); handleSpiError(rtd, result, "writeCfgReg");
continue; continue;
} }
if (rtd->writeLowThreshold) { if (doWriteLowThreshold) {
result = writeLowThreshold(rtd->spiCookie, rtd->lowThreshold); result = writeLowThreshold(rtd->spiCookie, rtd->lowThreshold);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
handleSpiError(rtd, result, "writeLowThreshold"); handleSpiError(rtd, result, "writeLowThreshold");
} }
} }
if (rtd->writeHighThreshold) { if (doWriteHighThreshold) {
result = writeHighThreshold(rtd->spiCookie, rtd->highThreshold); result = writeHighThreshold(rtd->spiCookie, rtd->highThreshold);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
handleSpiError(rtd, result, "writeHighThreshold"); handleSpiError(rtd, result, "writeHighThreshold");
@ -94,23 +103,12 @@ bool Max31865RtdPolling::periodicInitHandling() {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
handleSpiError(rtd, result, "clearFaultStatus"); handleSpiError(rtd, result, "clearFaultStatus");
} }
MutexGuard mg(readerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
rtd->db.configured = true; rtd->db.configured = true;
rtd->db.active = true; rtd->db.active = true;
} }
} }
bool someRtdUsable = false; return returnvalue::OK;
for (auto& rtd : rtds) {
if (rtd == nullptr) {
continue;
}
if (rtdIsActive(rtd->idx)) {
#if OBSW_RTD_AUTO_MODE == 0
result = writeBiasSel(Bias::ON, rtd->spiCookie, BASE_CFG);
#endif
someRtdUsable = true;
}
}
return someRtdUsable;
} }
ReturnValue_t Max31865RtdPolling::periodicReadReqHandling() { ReturnValue_t Max31865RtdPolling::periodicReadReqHandling() {
@ -120,12 +118,8 @@ ReturnValue_t Max31865RtdPolling::periodicReadReqHandling() {
if (rtd == nullptr) { if (rtd == nullptr) {
continue; continue;
} }
MutexGuard mg(readerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); updateActiveRtdsArray();
if (mg.getLockResult() != returnvalue::OK) { if (activeRtdsArray[rtd->idx]) {
sif::warning << "Max31865RtdReader::periodicReadReqHandling: Mutex lock failed" << std::endl;
return returnvalue::FAILED;
}
if (rtdIsActive(rtd->idx)) {
ReturnValue_t result = writeCfgReg(rtd->spiCookie, BASE_CFG | (1 << CfgBitPos::ONE_SHOT)); ReturnValue_t result = writeCfgReg(rtd->spiCookie, BASE_CFG | (1 << CfgBitPos::ONE_SHOT));
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
handleSpiError(rtd, result, "writeCfgReg"); handleSpiError(rtd, result, "writeCfgReg");
@ -145,12 +139,8 @@ ReturnValue_t Max31865RtdPolling::periodicReadHandling() {
if (rtd == nullptr) { if (rtd == nullptr) {
continue; continue;
} }
MutexGuard mg(readerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); updateActiveRtdsArray();
if (mg.getLockResult() != returnvalue::OK) { if (activeRtdsArray[rtd->idx]) {
sif::warning << "Max31865RtdReader::periodicReadHandling: Mutex lock failed" << std::endl;
return returnvalue::FAILED;
}
if (rtdIsActive(rtd->idx)) {
// Please note that using the manual CS lock wrapper here is problematic. Might be a SPI // Please note that using the manual CS lock wrapper here is problematic. Might be a SPI
// or hardware specific issue where the CS needs to be pulled high and then low again // or hardware specific issue where the CS needs to be pulled high and then low again
// between transfers // between transfers
@ -167,6 +157,7 @@ ReturnValue_t Max31865RtdPolling::periodicReadHandling() {
handleSpiError(rtd, result, "readRtdVal"); handleSpiError(rtd, result, "readRtdVal");
continue; continue;
} }
MutexGuard mg(readerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
if (faultBitSet) { if (faultBitSet) {
rtd->db.faultBitSet = faultBitSet; rtd->db.faultBitSet = faultBitSet;
} }
@ -213,6 +204,10 @@ ReturnValue_t Max31865RtdPolling::sendMessage(CookieIF* cookie, const uint8_t* s
if (cookie == nullptr) { if (cookie == nullptr) {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
auto* rtdCookie = dynamic_cast<Max31865ReaderCookie*>(cookie);
if (rtdCookie == nullptr) {
return returnvalue::FAILED;
}
// Empty command.. don't fail for now // Empty command.. don't fail for now
if (sendLen < 1) { if (sendLen < 1) {
return returnvalue::OK; return returnvalue::OK;
@ -222,7 +217,6 @@ ReturnValue_t Max31865RtdPolling::sendMessage(CookieIF* cookie, const uint8_t* s
sif::warning << "Max31865RtdReader::sendMessage: Mutex lock failed" << std::endl; sif::warning << "Max31865RtdReader::sendMessage: Mutex lock failed" << std::endl;
return returnvalue::FAILED; return returnvalue::FAILED;
} }
auto* rtdCookie = dynamic_cast<Max31865ReaderCookie*>(cookie);
uint8_t cmdRaw = sendData[0]; uint8_t cmdRaw = sendData[0];
if (cmdRaw > EiveMax31855::RtdCommands::NUM_CMDS) { if (cmdRaw > EiveMax31855::RtdCommands::NUM_CMDS) {
sif::warning << "Max31865RtdReader::sendMessage: Invalid command" << std::endl; sif::warning << "Max31865RtdReader::sendMessage: Invalid command" << std::endl;
@ -241,7 +235,6 @@ ReturnValue_t Max31865RtdPolling::sendMessage(CookieIF* cookie, const uint8_t* s
case (EiveMax31855::RtdCommands::ON): { case (EiveMax31855::RtdCommands::ON): {
if (not rtdCookie->on) { if (not rtdCookie->on) {
rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS); rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS);
rtdCookie->cd.resetTimer();
rtdCookie->on = true; rtdCookie->on = true;
rtdCookie->db.active = false; rtdCookie->db.active = false;
rtdCookie->db.configured = false; rtdCookie->db.configured = false;
@ -254,7 +247,6 @@ ReturnValue_t Max31865RtdPolling::sendMessage(CookieIF* cookie, const uint8_t* s
case (EiveMax31855::RtdCommands::ACTIVE): { case (EiveMax31855::RtdCommands::ACTIVE): {
if (not rtdCookie->on) { if (not rtdCookie->on) {
rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS); rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS);
rtdCookie->cd.resetTimer();
rtdCookie->on = true; rtdCookie->on = true;
rtdCookie->db.active = true; rtdCookie->db.active = true;
rtdCookie->db.configured = false; rtdCookie->db.configured = false;
@ -313,15 +305,15 @@ ReturnValue_t Max31865RtdPolling::requestReceiveMessage(CookieIF* cookie, size_t
ReturnValue_t Max31865RtdPolling::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, ReturnValue_t Max31865RtdPolling::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
size_t* size) { size_t* size) {
auto* rtdCookie = dynamic_cast<Max31865ReaderCookie*>(cookie);
if (rtdCookie == nullptr) {
return returnvalue::FAILED;
}
MutexGuard mg(readerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); MutexGuard mg(readerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
if (mg.getLockResult() != returnvalue::OK) { if (mg.getLockResult() != returnvalue::OK) {
// TODO: Emit warning // TODO: Emit warning
return returnvalue::FAILED; return returnvalue::FAILED;
} }
auto* rtdCookie = dynamic_cast<Max31865ReaderCookie*>(cookie);
if (rtdCookie == nullptr) {
return returnvalue::FAILED;
}
uint8_t* exchangePtr = rtdCookie->exchangeBuf.data(); uint8_t* exchangePtr = rtdCookie->exchangeBuf.data();
size_t serLen = 0; size_t serLen = 0;
auto result = rtdCookie->db.serialize(&exchangePtr, &serLen, rtdCookie->exchangeBuf.size(), auto result = rtdCookie->db.serialize(&exchangePtr, &serLen, rtdCookie->exchangeBuf.size(),
@ -462,6 +454,18 @@ ReturnValue_t Max31865RtdPolling::readNFromReg(SpiCookie* cookie, uint8_t reg, s
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t Max31865RtdPolling::updateActiveRtdsArray() {
MutexGuard mg(readerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
if (mg.getLockResult() != returnvalue::OK) {
sif::warning << "Max31865RtdReader::periodicReadHandling: Mutex lock failed" << std::endl;
return returnvalue::FAILED;
}
for (const auto& rtd : rtds) {
activeRtdsArray[rtd->idx] = rtdIsActive(rtd->idx);
}
return returnvalue::OK;
}
ReturnValue_t Max31865RtdPolling::handleSpiError(Max31865ReaderCookie* cookie, ReturnValue_t result, ReturnValue_t Max31865RtdPolling::handleSpiError(Max31865ReaderCookie* cookie, ReturnValue_t result,
const char* ctx) { const char* ctx) {
cookie->db.spiErrorCount.value += 1; cookie->db.spiErrorCount.value += 1;

View File

@ -47,6 +47,7 @@ class Max31865RtdPolling : public SystemObject,
private: private:
std::vector<Max31865ReaderCookie*> rtds; std::vector<Max31865ReaderCookie*> rtds;
std::array<uint8_t, 4> cmdBuf = {}; std::array<uint8_t, 4> cmdBuf = {};
std::array<bool, 12> activeRtdsArray{};
size_t dbLen = 0; size_t dbLen = 0;
MutexIF* readerLock; MutexIF* readerLock;
static constexpr MutexIF::TimeoutType LOCK_TYPE = MutexIF::TimeoutType::WAITING; static constexpr MutexIF::TimeoutType LOCK_TYPE = MutexIF::TimeoutType::WAITING;
@ -59,7 +60,7 @@ class Max31865RtdPolling : public SystemObject,
uint32_t csTimeoutMs = spi::RTD_CS_TIMEOUT; uint32_t csTimeoutMs = spi::RTD_CS_TIMEOUT;
MutexIF* csLock = nullptr; MutexIF* csLock = nullptr;
bool periodicInitHandling(); ReturnValue_t periodicInitHandling();
ReturnValue_t periodicReadReqHandling(); ReturnValue_t periodicReadReqHandling();
ReturnValue_t periodicReadHandling(); ReturnValue_t periodicReadHandling();
@ -84,6 +85,8 @@ class Max31865RtdPolling : public SystemObject,
ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override; ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override;
ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override; ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override;
ReturnValue_t updateActiveRtdsArray();
ReturnValue_t handleSpiError(Max31865ReaderCookie* cookie, ReturnValue_t result, const char* ctx); ReturnValue_t handleSpiError(Max31865ReaderCookie* cookie, ReturnValue_t result, const char* ctx);
}; };

View File

@ -220,7 +220,7 @@ ReturnValue_t RwPollingTask::readNextReply(RwCookie& rwCookie, uint8_t* replyBuf
} }
pullCsLow(gpioId, gpioIF); pullCsLow(gpioId, gpioIF);
bool lastByteWasFrameMarker = false; bool lastByteWasFrameMarker = false;
Countdown cd(3000); Countdown cd(2000);
size_t readIdx = 0; size_t readIdx = 0;
while (true) { while (true) {

View File

@ -84,10 +84,11 @@ ReturnValue_t SafeCtrl::safeMekf(timeval now, double *quatBJ, bool quatBJValid,
} }
// Will be the version in worst case scenario in event of no working MEKF (nor GYRs) // Will be the version in worst case scenario in event of no working MEKF (nor GYRs)
ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBValid, double *sunRateB, ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBValid,
bool sunRateBValid, double *magFieldB, bool magFieldBValid, double *sunRateB, bool sunRateBValid, double *magFieldB,
double *magRateB, bool magRateBValid, double *sunDirRef, bool magFieldBValid, double *magRateB, bool magRateBValid,
double *satRateRef, double *outputAngle, double *outputMagMomB) { double *sunDirRef, double *satRateRef, double *outputAngle,
double *outputMagMomB) {
// Check for invalid Inputs // Check for invalid Inputs
if (!susDirBValid || !magFieldBValid || !magRateBValid) { if (!susDirBValid || !magFieldBValid || !magRateBValid) {
return returnvalue::FAILED; return returnvalue::FAILED;
@ -99,7 +100,7 @@ ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBVal
// normalize sunDir and magDir // normalize sunDir and magDir
double magDirB[3] = {0, 0, 0}; double magDirB[3] = {0, 0, 0};
VectorOperations<double>::normalize(magFieldB, magDirB, 3); VectorOperations<double>::normalize(magFieldBT, magDirB, 3);
VectorOperations<double>::normalize(susDirB, susDirB, 3); VectorOperations<double>::normalize(susDirB, susDirB, 3);
// Cosinus angle between sunDir and magDir // Cosinus angle between sunDir and magDir
@ -160,8 +161,8 @@ ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBVal
// Magnetic moment // Magnetic moment
double magMomB[3] = {0, 0, 0}; double magMomB[3] = {0, 0, 0};
double crossMagFieldTorque[3] = {0, 0, 0}; double crossMagFieldTorque[3] = {0, 0, 0};
VectorOperations<double>::cross(magFieldB, torqueB, crossMagFieldTorque); VectorOperations<double>::cross(magFieldBT, torqueB, crossMagFieldTorque);
double magMomFactor = pow(VectorOperations<double>::norm(magFieldB, 3), 2); double magMomFactor = pow(VectorOperations<double>::norm(magFieldBT, 3), 2);
VectorOperations<double>::mulScalar(crossMagFieldTorque, 1 / magMomFactor, magMomB, 3); VectorOperations<double>::mulScalar(crossMagFieldTorque, 1 / magMomFactor, magMomB, 3);
std::memcpy(outputMagMomB, magMomB, 3 * sizeof(double)); std::memcpy(outputMagMomB, magMomB, 3 * sizeof(double));

2
tmtc

@ -1 +1 @@
Subproject commit 77fbcede10d44fd15dc7d5d1b3965f06c6a8e7fc Subproject commit 783d5a8ed56a9683fc75d2aaffcabe82af34ffa9