RTD Update #251

Merged
meierj merged 36 commits from mueller/rtds-update into develop 2022-05-23 16:20:38 +02:00
6 changed files with 84 additions and 103 deletions
Showing only changes of commit 017cfb9d56 - Show all commits

View File

@ -147,13 +147,13 @@ void initmission::initTasks() {
#endif
PeriodicTaskIF* tcsPollingTask = factory->createPeriodicTask(
"TCS_TASK", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
"TCS_POLLING_TASK", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
result = tcsPollingTask->addComponent(objects::SPI_RTD_COM_IF);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("SPI_RTD_POLLING", objects::SPI_RTD_COM_IF);
}
PeriodicTaskIF* tcsTask = factory->createPeriodicTask(
"TCS_TASK", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
"TCS_TASK", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
std::array<object_id_t, EiveMax31855::NUM_RTDS> rtdIds = {
objects::RTD_0_IC3_PLOC_HEATSPREADER,
objects::RTD_1_IC4_PLOC_MISSIONBOARD,
@ -180,6 +180,7 @@ void initmission::initTasks() {
tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_READ);
tcsTask->addComponent(rtd, DeviceHandlerIF::GET_READ);
}
tcsTask->addComponent(objects::TCS_BOARD_ASS);
#endif /* OBSW_ADD_RTD_DEVICES */
// FS task, task interval does not matter because it runs in permanent loop, priority low

View File

@ -31,7 +31,7 @@ static constexpr spi::SpiModes DEFAULT_L3G_MODE = spi::SpiModes::MODE_3;
static const uint32_t SUS_MAX1227_SPI_FREQ = 976'000;
static constexpr spi::SpiModes SUS_MAX_1227_MODE = spi::SpiModes::MODE_3;
static constexpr dur_millis_t RAD_SENSOR_CS_TIMEOUT = 250;
static constexpr dur_millis_t RAD_SENSOR_CS_TIMEOUT = 120;
static constexpr uint32_t DEFAULT_MAX_1227_SPEED = 976'000;
static constexpr spi::SpiModes DEFAULT_MAX_1227_MODE = spi::SpiModes::MODE_3;
@ -43,7 +43,7 @@ static constexpr spi::SpiModes DEFAULT_ADIS16507_MODE = spi::SpiModes::MODE_3;
static constexpr uint32_t RW_SPEED = 300'000;
static constexpr spi::SpiModes RW_MODE = spi::SpiModes::MODE_0;
static constexpr dur_millis_t RTD_CS_TIMEOUT = 40;
static constexpr dur_millis_t RTD_CS_TIMEOUT = 50;
static constexpr uint32_t RTD_SPEED = 2'000'000;
static constexpr spi::SpiModes RTD_MODE = spi::SpiModes::MODE_3;

2
fsfw

@ -1 +1 @@
Subproject commit bcd19045cc9f19d9fd0b61f991cb334c6315832a
Subproject commit 55ed7ab93e816ea083a961018a9383dc6c8ff33f

View File

@ -20,6 +20,7 @@ ReturnValue_t Max31865RtdReader::performOperation(uint8_t operationCode) {
void Max31865RtdReader::rtdMainLoop() {
using namespace MAX31865;
ReturnValue_t result = RETURN_OK;
// Stopwatch watch;
if (periodicInitHandling()) {
// 10 ms delay for VBIAS startup
@ -29,7 +30,10 @@ void Max31865RtdReader::rtdMainLoop() {
return;
}
periodicReadReqHandling();
result = periodicReadReqHandling();
if (result != RETURN_OK) {
return;
}
// After requesting, 65 milliseconds delay required
TaskFactory::delayTask(65);
@ -56,48 +60,41 @@ bool Max31865RtdReader::periodicInitHandling() {
if (rtd == nullptr) {
continue;
}
if ((rtd->on or rtd->active) and not rtd->configured) {
if (rtd->cd.hasTimedOut()) {
ManualCsLockWrapper mg(csLock, gpioIF, rtd->spiCookie, csTimeoutType, csTimeoutMs);
if (mg.lockResult != RETURN_OK or mg.gpioResult != RETURN_OK) {
sif::error << "Max31865RtdReader::periodicInitHandling: Manual CS lock failed"
<< std::endl;
break;
}
uint8_t cfg =
(Bias::OFF << CfgBitPos::BIAS_SEL) | (Wires::FOUR_WIRE << CfgBitPos::WIRE_SEL) |
(ConvMode::NORM_OFF << CfgBitPos::CONV_MODE) | (1 << CfgBitPos::FAULT_STATUS_CLEAR);
result = writeCfgReg(rtd->spiCookie, cfg);
if ((rtd->on or rtd->active) and not rtd->configured and rtd->cd.hasTimedOut()) {
ManualCsLockWrapper mg(csLock, gpioIF, rtd->spiCookie, csTimeoutType, csTimeoutMs);
if (mg.lockResult != RETURN_OK or mg.gpioResult != RETURN_OK) {
sif::error << "Max31865RtdReader::periodicInitHandling: Manual CS lock failed" << std::endl;
break;
}
uint8_t cfg = rtd->defCfg;
result = writeCfgReg(rtd->spiCookie, cfg);
if (result != HasReturnvaluesIF::RETURN_OK) {
handleSpiError(rtd, result, "writeCfgReg");
}
if (rtd->writeLowThreshold) {
result = writeLowThreshold(rtd->spiCookie, rtd->lowThreshold);
if (result != HasReturnvaluesIF::RETURN_OK) {
handleSpiError(rtd, result, "writeCfgReg");
}
bool additionalCfg = false;
if (rtd->writeLowThreshold) {
additionalCfg = true;
result = writeLowThreshold(rtd->spiCookie, rtd->lowThreshold);
if (result != HasReturnvaluesIF::RETURN_OK) {
handleSpiError(rtd, result, "writeLowThreshold");
}
}
if (rtd->writeHighThreshold) {
additionalCfg = true;
result = writeHighThreshold(rtd->spiCookie, rtd->highThreshold);
if (result != HasReturnvaluesIF::RETURN_OK) {
handleSpiError(rtd, result, "writeHighThreshold");
}
}
if (additionalCfg) {
result = clearFaultStatus(rtd->spiCookie);
if (result != HasReturnvaluesIF::RETURN_OK) {
handleSpiError(rtd, result, "clearFaultStatus");
}
}
rtd->configured = true;
rtd->db.configured = true;
if (rtd->active) {
rtd->db.active = true;
handleSpiError(rtd, result, "writeLowThreshold");
}
}
if (rtd->writeHighThreshold) {
result = writeHighThreshold(rtd->spiCookie, rtd->highThreshold);
if (result != HasReturnvaluesIF::RETURN_OK) {
handleSpiError(rtd, result, "writeHighThreshold");
}
}
result = clearFaultStatus(rtd->spiCookie);
if (result != HasReturnvaluesIF::RETURN_OK) {
handleSpiError(rtd, result, "clearFaultStatus");
}
rtd->configured = true;
rtd->db.configured = true;
if (rtd->active) {
rtd->db.active = true;
}
}
if (rtd->active and rtd->configured and not rtd->db.active) {
rtd->db.active = true;
}
}
bool someRtdUsable = false;
@ -106,24 +103,19 @@ bool Max31865RtdReader::periodicInitHandling() {
continue;
}
if (rtdIsActive(rtd->idx)) {
ManualCsLockWrapper mg(csLock, gpioIF, rtd->spiCookie, csTimeoutType, csTimeoutMs);
if (mg.lockResult != RETURN_OK or mg.gpioResult != RETURN_OK) {
sif::error << "Max31865RtdReader::periodicInitHandling: Manual CS lock failed" << std::endl;
break;
}
someRtdUsable = true;
result = writeBiasSel(Bias::ON, rtd->spiCookie);
result = writeBiasSel(Bias::ON, rtd->spiCookie, rtd->defCfg);
}
}
return someRtdUsable;
}
void Max31865RtdReader::periodicReadReqHandling() {
ReturnValue_t Max31865RtdReader::periodicReadReqHandling() {
using namespace MAX31865;
MutexGuard mg(readerMutex);
if (mg.getLockResult() != RETURN_OK) {
sif::warning << "Max31865RtdReader::periodicReadReqHandling: Mutex lock failed" << std::endl;
return;
return RETURN_FAILED;
}
// Now request one shot config for all active RTDs
for (auto& rtd : rtds) {
@ -131,36 +123,24 @@ void Max31865RtdReader::periodicReadReqHandling() {
continue;
}
if (rtdIsActive(rtd->idx)) {
ManualCsLockWrapper mg(csLock, gpioIF, rtd->spiCookie, csTimeoutType, csTimeoutMs);
if (mg.lockResult != RETURN_OK or mg.gpioResult != RETURN_OK) {
sif::error << "Max31865RtdReader::periodicInitHandling: Manual CS lock failed" << std::endl;
break;
}
uint8_t currentCfg = 0;
auto result = readCfgReg(rtd->spiCookie, currentCfg);
if (result != RETURN_OK) {
handleSpiError(rtd, result, "readCfgReg");
// Release mutex ASAP
break;
}
currentCfg |= (1 << CfgBitPos::ONE_SHOT);
result = writeCfgReg(rtd->spiCookie, currentCfg);
ReturnValue_t result = writeCfgReg(rtd->spiCookie, rtd->defCfg | (1 << CfgBitPos::ONE_SHOT));
if (result != RETURN_OK) {
handleSpiError(rtd, result, "writeCfgReg");
// Release mutex ASAP
break;
return RETURN_FAILED;
}
}
}
return RETURN_OK;
}
void Max31865RtdReader::periodicReadHandling() {
ReturnValue_t Max31865RtdReader::periodicReadHandling() {
using namespace MAX31865;
auto result = RETURN_OK;
MutexGuard mg(readerMutex);
if (mg.getLockResult() != RETURN_OK) {
sif::warning << "Max31865RtdReader::periodicReadReqHandling: Mutex lock failed" << std::endl;
return;
return RETURN_FAILED;
}
// Now read the RTD values
for (auto& rtd : rtds) {
@ -168,17 +148,12 @@ void Max31865RtdReader::periodicReadHandling() {
continue;
}
if (rtdIsActive(rtd->idx)) {
ManualCsLockWrapper mg(csLock, gpioIF, rtd->spiCookie, csTimeoutType, csTimeoutMs);
if (mg.lockResult != RETURN_OK or mg.gpioResult != RETURN_OK) {
sif::error << "Max31865RtdReader::periodicInitHandling: Manual CS lock failed" << std::endl;
break;
}
uint16_t rtdVal = 0;
bool faultBitSet = false;
result = readRtdVal(rtd->spiCookie, rtdVal, faultBitSet);
if (result != RETURN_OK) {
handleSpiError(rtd, result, "readRtdVal");
continue;
return RETURN_FAILED;
}
if (faultBitSet) {
rtd->db.faultBitSet = faultBitSet;
@ -193,14 +168,10 @@ void Max31865RtdReader::periodicReadHandling() {
// Even if a device was made inactive, turn off the bias here. If it was turned off, not
// necessary anymore..
if (rtd->on) {
ManualCsLockWrapper mg(csLock, gpioIF, rtd->spiCookie, csTimeoutType, csTimeoutMs);
if (mg.lockResult != RETURN_OK or mg.gpioResult != RETURN_OK) {
sif::error << "Max31865RtdReader::periodicInitHandling: Manual CS lock failed" << std::endl;
break;
}
result = writeBiasSel(Bias::OFF, rtd->spiCookie);
result = writeBiasSel(Bias::OFF, rtd->spiCookie, rtd->defCfg);
}
}
return RETURN_OK;
}
ReturnValue_t Max31865RtdReader::initializeInterface(CookieIF* cookie) {
@ -346,19 +317,15 @@ ReturnValue_t Max31865RtdReader::writeCfgReg(SpiCookie* cookie, uint8_t cfg) {
return writeNToReg(cookie, CONFIG, 1, &cfg, nullptr);
}
ReturnValue_t Max31865RtdReader::writeBiasSel(MAX31865::Bias bias, SpiCookie* cookie) {
ReturnValue_t Max31865RtdReader::writeBiasSel(MAX31865::Bias bias, SpiCookie* cookie,
uint8_t baseCfg) {
using namespace MAX31865;
uint8_t currentCfg = 0;
auto result = readCfgReg(cookie, currentCfg);
if (result != RETURN_OK) {
return result;
}
if (bias == MAX31865::Bias::OFF) {
currentCfg &= ~(1 << CfgBitPos::BIAS_SEL);
baseCfg &= ~(1 << CfgBitPos::BIAS_SEL);
} else {
currentCfg |= (1 << CfgBitPos::BIAS_SEL);
baseCfg |= (1 << CfgBitPos::BIAS_SEL);
}
return writeCfgReg(cookie, currentCfg);
return writeCfgReg(cookie, baseCfg);
}
ReturnValue_t Max31865RtdReader::clearFaultStatus(SpiCookie* cookie) {
@ -369,6 +336,8 @@ ReturnValue_t Max31865RtdReader::clearFaultStatus(SpiCookie* cookie) {
if (result != RETURN_OK) {
return result;
}
// Clear bytes 5, 3 and 2 which need to be 0
currentCfg &= ~0x2C;
currentCfg |= (1 << CfgBitPos::FAULT_STATUS_CLEAR);
return writeCfgReg(cookie, currentCfg);
}

View File

@ -21,6 +21,10 @@ struct Max31865ReaderCookie : public CookieIF {
std::string locString = "";
std::array<uint8_t, 12> exchangeBuf{};
Countdown cd = Countdown(MAX31865::WARMUP_MS);
// I'd prefer if we could use the NORM_OFF mode, but it does not work for some reason..
uint8_t defCfg = (MAX31865::Bias::ON << MAX31865::CfgBitPos::BIAS_SEL) |
(MAX31865::Wires::FOUR_WIRE << MAX31865::CfgBitPos::WIRE_SEL) |
(MAX31865::ConvMode::AUTO << MAX31865::CfgBitPos::CONV_MODE);
bool on = false;
bool configured = false;
bool active = false;
@ -57,12 +61,12 @@ class Max31865RtdReader : public SystemObject,
void rtdMainLoop();
bool periodicInitHandling();
void periodicReadReqHandling();
void periodicReadHandling();
ReturnValue_t periodicReadReqHandling();
ReturnValue_t periodicReadHandling();
bool rtdIsActive(uint8_t idx);
ReturnValue_t writeCfgReg(SpiCookie* cookie, uint8_t cfg);
ReturnValue_t writeBiasSel(MAX31865::Bias bias, SpiCookie* cookie);
ReturnValue_t writeBiasSel(MAX31865::Bias bias, SpiCookie* cookie, uint8_t baseCfg);
ReturnValue_t readCfgReg(SpiCookie* cookie, uint8_t& cfg);
ReturnValue_t readRtdVal(SpiCookie* cookie, uint16_t& val, bool& faultBitSet);
ReturnValue_t writeLowThreshold(SpiCookie* cookie, uint16_t val);

View File

@ -20,7 +20,7 @@ void Max31865EiveHandler::doStartUp() {
}
if ((state == InternalState::ON or state == InternalState::ACTIVE) and transitionOk) {
if (instantNormal) {
setMode(_MODE_TO_NORMAL);
setMode(MODE_NORMAL);
} else {
setMode(MODE_ON);
}
@ -102,7 +102,16 @@ void Max31865EiveHandler::simpleCommand(EiveMax31855::RtdCommands cmd) {
rawPacketLen = 1;
}
void Max31865EiveHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
if (mode == _MODE_TO_NORMAL) {
if (state != InternalState::ACTIVE) {
state = InternalState::ACTIVE;
transitionOk = false;
} else if (transitionOk) {
setMode(MODE_NORMAL);
}
} else {
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
}
}
void Max31865EiveHandler::fillCommandAndReplyMap() {
@ -131,13 +140,11 @@ ReturnValue_t Max31865EiveHandler::interpretDeviceReply(DeviceCommandId_t id,
if (result != RETURN_OK) {
return result;
}
if (mode == _MODE_START_UP) {
if (exchangeStruct.active and state == InternalState::ACTIVE) {
transitionOk = true;
}
if (exchangeStruct.configured and state == InternalState::ON) {
transitionOk = true;
}
if (mode == _MODE_TO_NORMAL and exchangeStruct.active and state == InternalState::ACTIVE) {
transitionOk = true;
}
if (mode == _MODE_START_UP and exchangeStruct.configured and state == InternalState::ON) {
transitionOk = true;
}
// Calculate resistance
float rtdValue = exchangeStruct.adcCode * EiveMax31855::RTD_RREF_PT1000 / INT16_MAX;