v6.1.0-branch #750
@ -18,6 +18,8 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
|
|
||||||
## Changed
|
## 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
|
- 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.
|
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
|
- 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.
|
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
|
- 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.
|
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
|
## Fixed
|
||||||
|
|
||||||
@ -42,6 +45,8 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
- TMP1075: Possibly ignored health commands.
|
- TMP1075: Possibly ignored health commands.
|
||||||
- Bugfix in FSFW where certain packet types could only be sent with source data fields with a
|
- Bugfix in FSFW where certain packet types could only be sent with source data fields with a
|
||||||
maximum size of 255 bytes.
|
maximum size of 255 bytes.
|
||||||
|
- TCS CTRL: Limit number of heater handler messages sent in case there are not sensors available
|
||||||
|
anymore.
|
||||||
|
|
||||||
# Added
|
# Added
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ ReturnValue_t Xadc::readValFromFile(const char* filename, T& val) {
|
|||||||
sif::warning << "Xadc::readValFromFile: Failed to open file " << filename << std::endl;
|
sif::warning << "Xadc::readValFromFile: Failed to open file " << filename << std::endl;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
char valstring[MAX_STR_LENGTH] = "";
|
char valstring[MAX_STR_LENGTH]{};
|
||||||
char* returnVal = fgets(valstring, MAX_STR_LENGTH, fp);
|
char* returnVal = fgets(valstring, MAX_STR_LENGTH, fp);
|
||||||
if (returnVal == nullptr) {
|
if (returnVal == nullptr) {
|
||||||
sif::warning << "Xadc::readValFromFile: Failed to read string from file " << filename
|
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);
|
std::istringstream valSstream(valstring);
|
||||||
valSstream >> val;
|
valSstream >> val;
|
||||||
|
if(valSstream.bad()) {
|
||||||
|
sif::warning << "Xadc: Conversion of value to target type failed" << std::endl;
|
||||||
|
fclose(fp);
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
void ThermalController::ctrlSBandTransceiver() {
|
||||||
ctrlCtx.thermalComponent = tcsCtrl::SBAND_TRANSCEIVER;
|
ctrlCtx.thermalComponent = tcsCtrl::SBAND_TRANSCEIVER;
|
||||||
sensors[0].first = deviceTemperatures.syrlinksPowerAmplifier.isValid();
|
sensors[0].first = deviceTemperatures.syrlinksPowerAmplifier.isValid();
|
||||||
@ -1554,7 +1535,6 @@ void ThermalController::performThermalModuleCtrl(
|
|||||||
ctrlIfBoard();
|
ctrlIfBoard();
|
||||||
ctrlTcsBoard();
|
ctrlTcsBoard();
|
||||||
ctrlObc();
|
ctrlObc();
|
||||||
ctrlObcIfBoard();
|
|
||||||
ctrlSBandTransceiver();
|
ctrlSBandTransceiver();
|
||||||
ctrlPcduP60Board();
|
ctrlPcduP60Board();
|
||||||
ctrlPcduAcu();
|
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
|
// No sensors available, so switch the heater off. We can not perform control tasks if we
|
||||||
// are blind..
|
// are blind..
|
||||||
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
|
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
|
||||||
if (heaterCtrlAllowed()) {
|
// Also track the counter to prevent heater handler message spam. The heater handle can only
|
||||||
heaterSwitchHelper(htrCtx.switchNr, heater::SwitchState::OFF, ctrlCtx.thermalComponent);
|
// process 2 messages per cycle.
|
||||||
}
|
if (heaterCtrlAllowed() and (thermalStates[currThermalComponent].noSensorAvailableCounter < 3)) {
|
||||||
|
heaterSwitchHelper(htrCtx.switchNr, heater::SwitchState::OFF, currThermalComponent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resetSensorsArray();
|
resetSensorsArray();
|
||||||
@ -1635,18 +1617,18 @@ bool ThermalController::selectAndReadSensorTemp(HeaterContext& htrCtx) {
|
|||||||
sensors[i].second < SANITY_LIMIT_UPPER_TEMP) {
|
sensors[i].second < SANITY_LIMIT_UPPER_TEMP) {
|
||||||
ctrlCtx.sensorTemp = sensors[i].second;
|
ctrlCtx.sensorTemp = sensors[i].second;
|
||||||
ctrlCtx.currentSensorIndex = i;
|
ctrlCtx.currentSensorIndex = i;
|
||||||
thermalStates[ctrlCtx.thermalComponent].errorCounter = 0;
|
thermalStates[ctrlCtx.thermalComponent].noSensorAvailableCounter = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
thermalStates[ctrlCtx.thermalComponent].errorCounter++;
|
thermalStates[currThermalComponent].noSensorAvailableCounter++;
|
||||||
if (ctrlCtx.thermalComponent != tcsCtrl::RW and ctrlCtx.thermalComponent != tcsCtrl::ACS_BOARD) {
|
if (currThermalComponent != RW and currThermalComponent != ACS_BOARD) {
|
||||||
if (thermalStates[ctrlCtx.thermalComponent].errorCounter <= 3) {
|
if (thermalStates[ctrlCtx.thermalComponent].noSensorAvailableCounter <= 3) {
|
||||||
triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, ctrlCtx.thermalComponent);
|
triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, ctrlCtx.thermalComponent);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (thermalStates[ctrlCtx.thermalComponent].errorCounter <= 8) {
|
if (thermalStates[ctrlCtx.thermalComponent].noSensorAvailableCounter <= 8) {
|
||||||
triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, ctrlCtx.thermalComponent);
|
triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, ctrlCtx.thermalComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1858,7 +1840,7 @@ bool ThermalController::heaterCtrlAllowed() const { return submode != SUBMODE_NO
|
|||||||
void ThermalController::resetThermalStates() {
|
void ThermalController::resetThermalStates() {
|
||||||
for (auto& thermalState : thermalStates) {
|
for (auto& thermalState : thermalStates) {
|
||||||
thermalState.heating = false;
|
thermalState.heating = false;
|
||||||
thermalState.errorCounter = 0;
|
thermalState.noSensorAvailableCounter = 0;
|
||||||
thermalState.heaterStartTime = 0;
|
thermalState.heaterStartTime = 0;
|
||||||
thermalState.heaterEndTime = 0;
|
thermalState.heaterEndTime = 0;
|
||||||
thermalState.sensorIndex = 0;
|
thermalState.sensorIndex = 0;
|
||||||
|
@ -26,6 +26,80 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <optional>
|
#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 {
|
class ThermalController : public ExtendedControllerBase {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t SUBMODE_NO_HEATER_CTRL = 1;
|
static constexpr uint8_t SUBMODE_NO_HEATER_CTRL = 1;
|
||||||
@ -298,7 +372,6 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
void ctrlIfBoard();
|
void ctrlIfBoard();
|
||||||
void ctrlTcsBoard();
|
void ctrlTcsBoard();
|
||||||
void ctrlObc();
|
void ctrlObc();
|
||||||
void ctrlObcIfBoard();
|
|
||||||
void ctrlSBandTransceiver();
|
void ctrlSBandTransceiver();
|
||||||
void ctrlPcduP60Board();
|
void ctrlPcduP60Board();
|
||||||
void ctrlPcduAcu();
|
void ctrlPcduAcu();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user