525 lines
22 KiB
C++
525 lines
22 KiB
C++
#include "GomspaceDeviceHandler.h"
|
|
|
|
#include <common/config/commonObjects.h>
|
|
#include <fsfw/datapool/PoolReadGuard.h>
|
|
|
|
#include "devicedefinitions/GomSpacePackets.h"
|
|
#include "devicedefinitions/powerDefinitions.h"
|
|
|
|
GomspaceDeviceHandler::GomspaceDeviceHandler(object_id_t objectId, object_id_t comIF,
|
|
CookieIF* comCookie, FailureIsolationBase* customFdir,
|
|
uint16_t maxConfigTableAddress,
|
|
uint16_t maxHkTableAddress, uint16_t hkTableReplySize)
|
|
: DeviceHandlerBase(objectId, comIF, comCookie, customFdir),
|
|
maxConfigTableAddress(maxConfigTableAddress),
|
|
maxHkTableAddress(maxHkTableAddress),
|
|
hkTableReplySize(hkTableReplySize) {
|
|
if (comCookie == nullptr) {
|
|
sif::error << "GomspaceDeviceHandler::GomspaceDeviceHandler: Invalid com cookie" << std::endl;
|
|
}
|
|
}
|
|
|
|
GomspaceDeviceHandler::~GomspaceDeviceHandler() {}
|
|
|
|
void GomspaceDeviceHandler::doStartUp() {}
|
|
|
|
void GomspaceDeviceHandler::doShutDown() {}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::handleAction(PrintSwitchVIAction* action) {
|
|
return printStatus(action->getId());
|
|
}
|
|
ReturnValue_t GomspaceDeviceHandler::handleAction(PrintLatchupsAction* action) {
|
|
return printStatus(action->getId());
|
|
}
|
|
|
|
void GomspaceDeviceHandler::fillCommandAndReplyMap() {
|
|
this->insertInCommandAndReplyMap(GOMSPACE::PING, 3);
|
|
this->insertInCommandMap(GOMSPACE::REBOOT);
|
|
this->insertInCommandAndReplyMap(GOMSPACE::PARAM_SET, 3);
|
|
this->insertInCommandAndReplyMap(GOMSPACE::PARAM_GET, 3);
|
|
this->insertInCommandAndReplyMap(GOMSPACE::REQUEST_HK_TABLE, 3);
|
|
this->insertInCommandMap(GOMSPACE::GNDWDT_RESET);
|
|
this->insertInCommandMap(GOMSPACE::PRINT_SWITCH_V_I);
|
|
this->insertInCommandMap(GOMSPACE::PRINT_LATCHUPS);
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::scanForReply(const uint8_t* start, size_t remainingSize,
|
|
DeviceCommandId_t* foundId, size_t* foundLen) {
|
|
switch (rememberCommandId) {
|
|
case (GOMSPACE::PING):
|
|
*foundId = GOMSPACE::PING;
|
|
*foundLen = PING_REPLY_SIZE;
|
|
rememberCommandId = GOMSPACE::NONE;
|
|
break;
|
|
case (GOMSPACE::PARAM_GET): {
|
|
*foundId = GOMSPACE::PARAM_GET;
|
|
*foundLen = rememberRequestedSize + GOMSPACE::GS_HDR_LENGTH;
|
|
rememberCommandId = GOMSPACE::NONE;
|
|
break;
|
|
}
|
|
case (GOMSPACE::PARAM_SET): {
|
|
*foundId = GOMSPACE::PARAM_SET;
|
|
*foundLen = rememberRequestedSize;
|
|
rememberCommandId = GOMSPACE::NONE;
|
|
break;
|
|
}
|
|
case (GOMSPACE::REQUEST_HK_TABLE): {
|
|
*foundId = GOMSPACE::REQUEST_HK_TABLE;
|
|
*foundLen = rememberRequestedSize + GOMSPACE::GS_HDR_LENGTH;
|
|
rememberCommandId = GOMSPACE::NONE;
|
|
break;
|
|
}
|
|
default:
|
|
return IGNORE_REPLY_DATA;
|
|
}
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
|
|
const uint8_t* packet) {
|
|
switch (id) {
|
|
case (GOMSPACE::PING): {
|
|
SerializeElement<uint32_t> replyTime = *packet;
|
|
handleDeviceTM(&replyTime, id, true);
|
|
break;
|
|
}
|
|
case (GOMSPACE::PARAM_GET): {
|
|
// -2 to subtract address size from gomspace parameter reply packet
|
|
uint16_t payloadLength = (*(packet + 2) << 8 | *(packet + 3)) - 2;
|
|
if (payloadLength > sizeof(uint32_t)) {
|
|
sif::error << "GomspaceDeviceHandler: PARAM_GET: Invalid payload "
|
|
<< "size in reply" << std::endl;
|
|
return INVALID_PAYLOAD_SIZE;
|
|
}
|
|
uint8_t tempPayloadBuffer[payloadLength];
|
|
/* Extract information from received data */
|
|
CspGetParamReply cspGetParamReply(tempPayloadBuffer, payloadLength);
|
|
size_t size = GOMSPACE::GS_HDR_LENGTH + payloadLength;
|
|
ReturnValue_t result =
|
|
cspGetParamReply.deSerialize(&packet, &size, SerializeIF::Endianness::BIG);
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
sif::error << "GomspaceDeviceHandler: Failed to deserialize get parameter"
|
|
<< "reply" << std::endl;
|
|
return result;
|
|
}
|
|
uint8_t action = cspGetParamReply.getAction();
|
|
uint8_t tableId = cspGetParamReply.getTableId();
|
|
uint16_t address = cspGetParamReply.getAddress();
|
|
/* Pack relevant information into a tm packet */
|
|
ParamReply paramReply(action, tableId, address, payloadLength, tempPayloadBuffer);
|
|
handleDeviceTM(¶mReply, id, true);
|
|
break;
|
|
}
|
|
case (GOMSPACE::PARAM_SET): {
|
|
/* When setting a parameter, the p60dock sends back the state of the
|
|
* operation */
|
|
if (*packet != PARAM_SET_OK) {
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
|
}
|
|
// TODO fix
|
|
setParamCallback(setParamCacher.getParameter(), setParamCacher.getParameter(), setParamCacher.getParameterSize(), true);
|
|
break;
|
|
}
|
|
case (GOMSPACE::REQUEST_HK_TABLE): {
|
|
letChildHandleHkReply(id, packet);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
void GomspaceDeviceHandler::setNormalDatapoolEntriesInvalid() {}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::handleAction(ParamSetAction* action) {
|
|
// This breaks layering but I really don't want to accept this command..
|
|
if (action->address == PDU2::CONFIG_ADDRESS_OUT_EN_Q7S and
|
|
this->getObjectId() == objects::PDU2_HANDLER) {
|
|
triggerEvent(power::SWITCHING_Q7S_DENIED, 0, 0);
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
|
}
|
|
//cache for later use
|
|
setParamCacher.set(action->address, action->parameter,
|
|
static_cast<uint8_t>(action->parameterSize.value));
|
|
ReturnValue_t result = setParamCallback(action->address, action->parameter,
|
|
static_cast<uint8_t>(action->parameterSize.value), false);
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
return result;
|
|
}
|
|
/* Get and check address */
|
|
if (action->address > maxConfigTableAddress) {
|
|
sif::error << "GomspaceDeviceHandler: Invalid address for set parameter "
|
|
<< "action" << std::endl;
|
|
return INVALID_ADDRESS;
|
|
}
|
|
uint16_t checksum = GOMSPACE::IGNORE_CHECKSUM;
|
|
uint16_t seq = 0;
|
|
uint16_t total = 0;
|
|
/* CSP reply only contains the transaction state */
|
|
uint16_t querySize = 1;
|
|
size_t parameterSize = 0;
|
|
uint8_t parameterBytes[4];
|
|
uint8_t* uselessPointer = parameterBytes;
|
|
switch (action->parameterSize.value) {
|
|
case ParamSetAction::ParameterByteSize::ONE_BYTE: {
|
|
if (action->parameter > 255) {
|
|
return INVALID_PARAMETERS;
|
|
}
|
|
uint8_t oneByte = action->parameter.value;
|
|
result = SerializeAdapter::serialize<uint8_t>(&oneByte, &uselessPointer, ¶meterSize,
|
|
sizeof(parameterBytes),
|
|
SerializeIF::Endianness::BIG);
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
return result;
|
|
}
|
|
parameterSize = 1;
|
|
} break;
|
|
case ParamSetAction::ParameterByteSize::TWO_BYTES: {
|
|
if (action->parameter > 65535) {
|
|
return INVALID_PARAMETERS;
|
|
}
|
|
uint16_t twoBytes = action->parameter.value;
|
|
result = SerializeAdapter::serialize<uint16_t>(&twoBytes, &uselessPointer, ¶meterSize,
|
|
sizeof(parameterBytes),
|
|
SerializeIF::Endianness::BIG);
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
return result;
|
|
}
|
|
parameterSize = 2;
|
|
} break;
|
|
case ParamSetAction::ParameterByteSize::FOUR_BYTES:
|
|
result = SerializeAdapter::serialize<uint32_t>(&(action->parameter.value), &uselessPointer,
|
|
¶meterSize, sizeof(parameterBytes),
|
|
SerializeIF::Endianness::BIG);
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
return result;
|
|
}
|
|
parameterSize = 4;
|
|
break;
|
|
}
|
|
|
|
uint16_t payloadlength = sizeof(action->address) + parameterSize;
|
|
|
|
/* Generate command for CspComIF */
|
|
CspSetParamCommand setParamCmd(querySize, payloadlength, checksum, seq, total, action->address,
|
|
parameterBytes, parameterSize);
|
|
size_t cspPacketLen = 0;
|
|
uint8_t* buffer = cspPacket;
|
|
result = setParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
|
|
SerializeIF::Endianness::BIG);
|
|
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
sif::error << "GomspaceDeviceHandler: Failed to serialize command for "
|
|
<< "CspComIF" << std::endl;
|
|
return result;
|
|
}
|
|
if (cspPacketLen > MAX_PACKET_LEN) {
|
|
sif::error << "GomspaceDeviceHandler: Invalid length of set parameter "
|
|
"command"
|
|
<< std::endl;
|
|
return PACKET_TOO_LONG;
|
|
}
|
|
rawPacket = cspPacket;
|
|
rawPacketLen = cspPacketLen;
|
|
rememberRequestedSize = querySize;
|
|
rememberCommandId = GOMSPACE::PARAM_SET;
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::handleAction(ParamGetAction* action) {
|
|
ReturnValue_t result;
|
|
auto tableId = action->tableId.value;
|
|
|
|
/* Get and check address */
|
|
uint16_t address = action->address;
|
|
if (address > maxHkTableAddress && tableId == ParamGetAction::TableId::HK_TABLE_ID) {
|
|
sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from "
|
|
<< "housekeeping table" << std::endl;
|
|
return INVALID_ADDRESS;
|
|
}
|
|
if (address > maxConfigTableAddress && tableId == ParamGetAction::TableId::CONFIG_TABLE_ID) {
|
|
sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from "
|
|
<< "configuration table" << std::endl;
|
|
return INVALID_ADDRESS;
|
|
}
|
|
uint16_t length = sizeof(address);
|
|
uint16_t checksum = GOMSPACE::IGNORE_CHECKSUM;
|
|
uint16_t seq = 0;
|
|
uint16_t total = 0;
|
|
uint8_t parameterSize = static_cast<uint8_t>(action->parameterSize.value);
|
|
uint16_t querySize = parameterSize + GOMSPACE::GS_HDR_LENGTH;
|
|
|
|
/* Generate the CSP command to send to the P60 Dock */
|
|
CspGetParamCommand getParamCmd(querySize, static_cast<uint8_t>(tableId), length, checksum, seq, total, address);
|
|
size_t cspPacketLen = 0;
|
|
uint8_t* buffer = cspPacket;
|
|
result = getParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
|
|
SerializeIF::Endianness::BIG);
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
sif::error << "GomspaceDeviceHandler: Failed to serialize command to "
|
|
<< "get parameter" << std::endl;
|
|
}
|
|
|
|
// checked by serialize above
|
|
/* if (cspPacketLen > MAX_PACKET_LEN) {
|
|
sif::error << "GomspaceDeviceHandler: Received invalid get parameter "
|
|
"command"
|
|
<< std::endl;
|
|
return PACKET_TOO_LONG;
|
|
}*/
|
|
rawPacket = cspPacket;
|
|
rawPacketLen = cspPacketLen;
|
|
rememberRequestedSize = querySize;
|
|
rememberCommandId = GOMSPACE::PARAM_GET;
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::handleAction(PingAction* action) {
|
|
CspPingCommand cspPingCommand(&action->pingData.value, 1); // TODO array
|
|
size_t cspPacketLen = 0;
|
|
uint8_t* buffer = cspPacket;
|
|
ReturnValue_t result = cspPingCommand.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
|
|
SerializeIF::Endianness::BIG);
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
sif::error << "GomspaceDeviceHandler: Failed to serialize ping command" << std::endl;
|
|
return result;
|
|
}
|
|
/* Checked by the serialize function
|
|
if (cspPacketLen > MAX_PACKET_LEN) {
|
|
sif::error << "GomspaceDeviceHandler: Received invalid ping message" << std::endl;
|
|
return PACKET_TOO_LONG;
|
|
}*/
|
|
rawPacket = cspPacket;
|
|
rawPacketLen = cspPacketLen;
|
|
rememberCommandId = GOMSPACE::PING;
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::handleAction(RebootAction* action) {
|
|
uint8_t cspPort = GOMSPACE::REBOOT_PORT;
|
|
uint16_t querySize = 0;
|
|
*cspPacket = GOMSPACE::REBOOT_PORT;
|
|
// TODO the following two lines look strange...
|
|
*(cspPacket + 1) = querySize;
|
|
size_t cspPacketLen = sizeof(cspPort) + sizeof(cspPacketLen);
|
|
rawPacket = cspPacket;
|
|
rawPacketLen = cspPacketLen;
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::childCommandHook(DeviceCommandId_t cmd,
|
|
const uint8_t* commandData,
|
|
size_t commandDataLen) {
|
|
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::setParamCallback(uint16_t address, uint32_t value,
|
|
uint8_t valueBytes, bool afterExecution) {
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::initializePduPool(
|
|
localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager,
|
|
std::array<uint8_t, PDU::CHANNELS_LEN> initOutEnb) {
|
|
localDataPoolMap.emplace(P60System::pool::PDU_CURRENTS, new PoolEntry<int16_t>(9));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_VOLTAGES, new PoolEntry<int16_t>(9));
|
|
|
|
localDataPoolMap.emplace(P60System::pool::PDU_VCC, new PoolEntry<int16_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_VBAT, new PoolEntry<int16_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_TEMPERATURE, new PoolEntry<float>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_CONV_EN, new PoolEntry<uint8_t>(3));
|
|
|
|
localDataPoolMap.emplace(P60System::pool::PDU_OUT_ENABLE,
|
|
new PoolEntry<uint8_t>(initOutEnb.data(), initOutEnb.size()));
|
|
|
|
localDataPoolMap.emplace(P60System::pool::PDU_BOOTCAUSE, new PoolEntry<uint32_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_BOOTCNT, new PoolEntry<uint32_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_UPTIME, new PoolEntry<uint32_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_RESETCAUSE, new PoolEntry<uint16_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_BATT_MODE, new PoolEntry<uint8_t>({0}));
|
|
|
|
localDataPoolMap.emplace(P60System::pool::PDU_LATCHUPS, new PoolEntry<uint16_t>(9));
|
|
|
|
localDataPoolMap.emplace(P60System::pool::PDU_DEVICES, new PoolEntry<uint8_t>(8));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_STATUSES, new PoolEntry<uint8_t>(8));
|
|
|
|
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CNT_GND, new PoolEntry<uint32_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CNT_I2C, new PoolEntry<uint32_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CNT_CAN, new PoolEntry<uint32_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CNT_CSP1, new PoolEntry<uint32_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CNT_CSP2, new PoolEntry<uint32_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_WDT_GND_LEFT, new PoolEntry<uint32_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_WDT_I2C_LEFT, new PoolEntry<uint32_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CAN_LEFT, new PoolEntry<uint32_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CSP_LEFT1, new PoolEntry<uint8_t>({0}));
|
|
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CSP_LEFT2, new PoolEntry<uint8_t>({0}));
|
|
return RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::handleAction(GndwdtResetAction* action) {
|
|
WatchdogResetCommand watchdogResetCommand;
|
|
size_t cspPacketLen = 0;
|
|
uint8_t* buffer = cspPacket;
|
|
ReturnValue_t result = watchdogResetCommand.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
|
|
SerializeIF::Endianness::BIG);
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
sif::error << "GomspaceDeviceHandler: Failed to serialize watchdog reset "
|
|
<< "command" << std::endl;
|
|
return result;
|
|
}
|
|
rawPacket = cspPacket;
|
|
rawPacketLen = cspPacketLen;
|
|
rememberRequestedSize = 0; // No bytes will be queried with the ground
|
|
// watchdog command.
|
|
rememberCommandId = GOMSPACE::GNDWDT_RESET;
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::handleAction(RequestHkTableAction* action) {
|
|
uint16_t querySize = hkTableReplySize;
|
|
uint8_t tableId = static_cast<uint8_t>(ParamGetAction::TableId::HK_TABLE_ID);
|
|
RequestFullTableCommand requestFullTableCommand(querySize, tableId);
|
|
|
|
size_t cspPacketLen = 0;
|
|
uint8_t* buffer = cspPacket;
|
|
ReturnValue_t result = requestFullTableCommand.serialize(
|
|
&buffer, &cspPacketLen, sizeof(cspPacket), SerializeIF::Endianness::BIG);
|
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
sif::error << "GomspaceDeviceHandler::generateRequestFullHkTableCmd Failed to serialize "
|
|
"full table request command "
|
|
<< std::endl;
|
|
return result;
|
|
}
|
|
rawPacket = cspPacket;
|
|
rawPacketLen = cspPacketLen;
|
|
rememberRequestedSize = querySize;
|
|
rememberCommandId = GOMSPACE::REQUEST_HK_TABLE;
|
|
return RETURN_OK;
|
|
}
|
|
|
|
uint32_t GomspaceDeviceHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 0; }
|
|
|
|
void GomspaceDeviceHandler::setModeNormal() { mode = MODE_NORMAL; }
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::printStatus(DeviceCommandId_t cmd) {
|
|
sif::info << "No printHkTable implementation given.." << std::endl;
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t GomspaceDeviceHandler::parsePduHkTable(PDU::PduCoreHk& coreHk, PDU::PduAuxHk& auxHk,
|
|
const uint8_t* packet) {
|
|
uint16_t dataOffset = 0;
|
|
PoolReadGuard pg0(&coreHk);
|
|
PoolReadGuard pg1(&auxHk);
|
|
if (pg0.getReadResult() != HasReturnvaluesIF::RETURN_OK or
|
|
pg1.getReadResult() != HasReturnvaluesIF::RETURN_OK) {
|
|
sif::warning << "Reading PDU1 datasets failed!" << std::endl;
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
|
}
|
|
/* Fist 10 bytes contain the gomspace header. Each variable is preceded by the 16-bit table
|
|
* address. */
|
|
dataOffset += 12;
|
|
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
|
|
coreHk.currents[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1];
|
|
dataOffset += 4;
|
|
}
|
|
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
|
|
coreHk.voltages[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1];
|
|
dataOffset += 4;
|
|
}
|
|
|
|
auxHk.vcc = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
|
|
dataOffset += 4;
|
|
auxHk.vbat = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
|
|
dataOffset += 4;
|
|
coreHk.temperature =
|
|
static_cast<int16_t>(*(packet + dataOffset) << 8 | *(packet + dataOffset + 1)) * 0.1;
|
|
dataOffset += 4;
|
|
|
|
for (uint8_t idx = 0; idx < 3; idx++) {
|
|
auxHk.converterEnable[idx] = packet[dataOffset];
|
|
dataOffset += 3;
|
|
}
|
|
|
|
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
|
|
coreHk.outputEnables[idx] = packet[dataOffset];
|
|
dataOffset += 3;
|
|
}
|
|
|
|
auxHk.bootcause = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
|
|
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
|
|
dataOffset += 6;
|
|
coreHk.bootcount = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
|
|
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
|
|
dataOffset += 6;
|
|
auxHk.uptime = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
|
|
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
|
|
dataOffset += 6;
|
|
auxHk.resetcause = *(packet + dataOffset + 1) << 8 | *(packet + dataOffset);
|
|
dataOffset += 4;
|
|
coreHk.battMode = *(packet + dataOffset);
|
|
/* +10 because here begins the second gomspace csp packet */
|
|
dataOffset += 3 + 10;
|
|
|
|
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
|
|
auxHk.latchups[idx] = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
|
|
dataOffset += 4;
|
|
}
|
|
|
|
for (uint8_t idx = 0; idx < PDU::DEVICES_NUM; idx++) {
|
|
auxHk.deviceTypes[idx] = *(packet + dataOffset);
|
|
dataOffset += 3;
|
|
}
|
|
for (uint8_t idx = 0; idx < PDU::DEVICES_NUM; idx++) {
|
|
auxHk.devicesStatus[idx] = *(packet + dataOffset);
|
|
dataOffset += 3;
|
|
}
|
|
|
|
auxHk.gndWdtReboots = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
|
|
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
|
|
dataOffset += 6;
|
|
auxHk.i2cWdtReboots = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
|
|
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
|
|
dataOffset += 6;
|
|
auxHk.canWdtReboots = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
|
|
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
|
|
dataOffset += 6;
|
|
auxHk.csp1WdtReboots = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
|
|
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
|
|
dataOffset += 6;
|
|
auxHk.csp2WdtReboots = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
|
|
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
|
|
dataOffset += 6;
|
|
auxHk.groundWatchdogSecondsLeft = *(packet + dataOffset) << 24 |
|
|
*(packet + dataOffset + 1) << 16 |
|
|
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
|
|
dataOffset += 6;
|
|
auxHk.i2cWatchdogSecondsLeft = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
|
|
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
|
|
dataOffset += 6;
|
|
auxHk.canWatchdogSecondsLeft = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
|
|
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
|
|
dataOffset += 6;
|
|
auxHk.csp1WatchdogPingsLeft = *(packet + dataOffset);
|
|
dataOffset += 3;
|
|
auxHk.csp2WatchdogPingsLeft = *(packet + dataOffset);
|
|
|
|
coreHk.setChanged(true);
|
|
if (not coreHk.isValid()) {
|
|
coreHk.setValidity(true, true);
|
|
}
|
|
if (not auxHk.isValid()) {
|
|
auxHk.setValidity(true, true);
|
|
}
|
|
return RETURN_OK;
|
|
}
|