Merge remote-tracking branch 'origin/main' into tcs-observability
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit

This commit is contained in:
Robin Müller 2023-07-11 11:00:03 +02:00
commit 72dbc34936
Signed by: muellerr
GPG Key ID: 407F9B00F858F270
4 changed files with 96 additions and 31 deletions

View File

@ -18,6 +18,8 @@ will consitute of a breaking change warranting a new major release:
## Changed
- TCS: Remove OBC IF board thermal module, which is exactly identical to OBC module and therefore
obsolete.
- Swapped PL and PS I2C, BPX battery and MGT are connected to PS I2C now for firmware versions
equal or above v4. However, this software version is compatible to both v3 and v4 of the firmware.
- The firmware version variables are global statics inititalized early during the program
@ -26,6 +28,7 @@ will consitute of a breaking change warranting a new major release:
components (no sensors available), irrespective of current switch state.
- Make OBSW compatible to prospective FW version v5.0.0, where the Q7 I2C devices were
moved to a PL I2C block and the TMP sensor devices were moved to the PS I2C0.
- Made `Xadc` code a little bit more robust against errors.
## Fixed
@ -42,6 +45,8 @@ will consitute of a breaking change warranting a new major release:
- TMP1075: Possibly ignored health commands.
- Bugfix in FSFW where certain packet types could only be sent with source data fields with a
maximum size of 255 bytes.
- TCS CTRL: Limit number of heater handler messages sent in case there are not sensors available
anymore.
# Added

View File

@ -129,7 +129,7 @@ ReturnValue_t Xadc::readValFromFile(const char* filename, T& val) {
sif::warning << "Xadc::readValFromFile: Failed to open file " << filename << std::endl;
return returnvalue::FAILED;
}
char valstring[MAX_STR_LENGTH] = "";
char valstring[MAX_STR_LENGTH]{};
char* returnVal = fgets(valstring, MAX_STR_LENGTH, fp);
if (returnVal == nullptr) {
sif::warning << "Xadc::readValFromFile: Failed to read string from file " << filename
@ -139,6 +139,11 @@ ReturnValue_t Xadc::readValFromFile(const char* filename, T& val) {
}
std::istringstream valSstream(valstring);
valSstream >> val;
if(valSstream.bad()) {
sif::warning << "Xadc: Conversion of value to target type failed" << std::endl;
fclose(fp);
return returnvalue::FAILED;
}
fclose(fp);
return returnvalue::OK;
}

View File

@ -1269,25 +1269,6 @@ void ThermalController::ctrlObc() {
}
}
void ThermalController::ctrlObcIfBoard() {
ctrlCtx.thermalComponent = tcsCtrl::OBCIF_BOARD;
sensors[0].first = deviceTemperatures.q7s.isValid();
sensors[0].second = deviceTemperatures.q7s.value;
sensors[1].first = sensorTemperatures.tmp1075Tcs0.isValid();
sensors[1].second = sensorTemperatures.tmp1075Tcs0.value;
sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid();
sensors[2].second = sensorTemperatures.tmp1075Tcs1.value;
numSensors = 3;
HeaterContext htrCtx(heater::HEATER_3_OBC_BRD, heater::HEATER_2_ACS_BRD, obcIfBoardLimits);
ctrlComponentTemperature(htrCtx);
if (ctrlCtx.componentAboveUpperLimit and not tooHotFlags.obcTooHotFlag) {
triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32());
tooHotFlags.obcTooHotFlag = true;
} else if (not ctrlCtx.componentAboveUpperLimit) {
tooHotFlags.obcTooHotFlag = false;
}
}
void ThermalController::ctrlSBandTransceiver() {
ctrlCtx.thermalComponent = tcsCtrl::SBAND_TRANSCEIVER;
sensors[0].first = deviceTemperatures.syrlinksPowerAmplifier.isValid();
@ -1554,7 +1535,6 @@ void ThermalController::performThermalModuleCtrl(
ctrlIfBoard();
ctrlTcsBoard();
ctrlObc();
ctrlObcIfBoard();
ctrlSBandTransceiver();
ctrlPcduP60Board();
ctrlPcduAcu();
@ -1621,9 +1601,11 @@ void ThermalController::ctrlComponentTemperature(HeaterContext& htrCtx) {
// No sensors available, so switch the heater off. We can not perform control tasks if we
// are blind..
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
if (heaterCtrlAllowed()) {
heaterSwitchHelper(htrCtx.switchNr, heater::SwitchState::OFF, ctrlCtx.thermalComponent);
}
// Also track the counter to prevent heater handler message spam. The heater handle can only
// process 2 messages per cycle.
if (heaterCtrlAllowed() and (thermalStates[currThermalComponent].noSensorAvailableCounter < 3)) {
heaterSwitchHelper(htrCtx.switchNr, heater::SwitchState::OFF, currThermalComponent);
}
}
}
resetSensorsArray();
@ -1635,18 +1617,18 @@ bool ThermalController::selectAndReadSensorTemp(HeaterContext& htrCtx) {
sensors[i].second < SANITY_LIMIT_UPPER_TEMP) {
ctrlCtx.sensorTemp = sensors[i].second;
ctrlCtx.currentSensorIndex = i;
thermalStates[ctrlCtx.thermalComponent].errorCounter = 0;
thermalStates[ctrlCtx.thermalComponent].noSensorAvailableCounter = 0;
return true;
}
}
thermalStates[ctrlCtx.thermalComponent].errorCounter++;
if (ctrlCtx.thermalComponent != tcsCtrl::RW and ctrlCtx.thermalComponent != tcsCtrl::ACS_BOARD) {
if (thermalStates[ctrlCtx.thermalComponent].errorCounter <= 3) {
thermalStates[currThermalComponent].noSensorAvailableCounter++;
if (currThermalComponent != RW and currThermalComponent != ACS_BOARD) {
if (thermalStates[ctrlCtx.thermalComponent].noSensorAvailableCounter <= 3) {
triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, ctrlCtx.thermalComponent);
}
} else {
if (thermalStates[ctrlCtx.thermalComponent].errorCounter <= 8) {
if (thermalStates[ctrlCtx.thermalComponent].noSensorAvailableCounter <= 8) {
triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, ctrlCtx.thermalComponent);
}
}
@ -1858,7 +1840,7 @@ bool ThermalController::heaterCtrlAllowed() const { return submode != SUBMODE_NO
void ThermalController::resetThermalStates() {
for (auto& thermalState : thermalStates) {
thermalState.heating = false;
thermalState.errorCounter = 0;
thermalState.noSensorAvailableCounter = 0;
thermalState.heaterStartTime = 0;
thermalState.heaterEndTime = 0;
thermalState.sensorIndex = 0;

View File

@ -26,6 +26,80 @@
#include <list>
#include <optional>
/**
* NOP Limit: Hard limit for device, usually from datasheet. Device damage is possible lif NOP limit
* is exceeded.
* OP Limit: Soft limit. Device should be switched off or TCS controller should take action if the
* limit is exceeded to avoid reaching NOP limit
*/
struct TempLimits {
TempLimits(float nopLowerLimit, float opLowerLimit, float cutOffLimit, float opUpperLimit,
float nopUpperLimit)
: opLowerLimit(opLowerLimit),
opUpperLimit(opUpperLimit),
cutOffLimit(cutOffLimit),
nopLowerLimit(nopLowerLimit),
nopUpperLimit(nopUpperLimit) {}
float opLowerLimit;
float opUpperLimit;
float cutOffLimit;
float nopLowerLimit;
float nopUpperLimit;
};
struct ThermalState {
uint8_t noSensorAvailableCounter;
// Which sensor is used for this component?
uint8_t sensorIndex = 0;
// Is heating on for that thermal module?
bool heating = false;
// Which switch is being used for heating the component
heater::Switch heaterSwitch = heater::Switch::NUMBER_OF_SWITCHES;
// Heater start time and end times as UNIX seconds. Please note that these times will be updated
// when a switch command is sent, with no guarantess that the heater actually went on.
uint32_t heaterStartTime = 0;
uint32_t heaterEndTime = 0;
};
struct HeaterState {
bool switchTransition = false;
HeaterHandler::SwitchState target = HeaterHandler::SwitchState::OFF;
uint8_t heaterSwitchControlCycles = 0;
bool trackHeaterMaxPeriod = false;
Countdown heaterOnPeriod;
};
using HeaterSwitchStates = std::array<HeaterHandler::SwitchState, heater::NUMBER_OF_SWITCHES>;
enum ThermalComponents : uint8_t {
NONE = 0,
ACS_BOARD = 1,
MGT = 2,
RW = 3,
STR = 4,
IF_BOARD = 5,
TCS_BOARD = 6,
OBC = 7,
// Not used anymore, was identical to OBC module.
LEGACY_OBCIF_BOARD = 8,
SBAND_TRANSCEIVER = 9,
PCDUP60_BOARD = 10,
PCDUACU = 11,
PCDUPDU = 12,
PLPCDU_BOARD = 13,
PLOCMISSION_BOARD = 14,
PLOCPROCESSING_BOARD = 15,
DAC = 16,
CAMERA = 17,
DRO = 18,
X8 = 19,
HPA = 20,
TX = 21,
MPA = 22,
SCEX_BOARD = 23,
NUM_ENTRIES
};
class ThermalController : public ExtendedControllerBase {
public:
static constexpr uint8_t SUBMODE_NO_HEATER_CTRL = 1;
@ -298,7 +372,6 @@ class ThermalController : public ExtendedControllerBase {
void ctrlIfBoard();
void ctrlTcsBoard();
void ctrlObc();
void ctrlObcIfBoard();
void ctrlSBandTransceiver();
void ctrlPcduP60Board();
void ctrlPcduAcu();