Merge remote-tracking branch 'origin/main' into relax-sus-fdir
This commit is contained in:
commit
5e79293d38
16
CHANGELOG.md
16
CHANGELOG.md
@ -26,7 +26,9 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
sensible raw values most of the time. Some further testing is necessary, but some changes in the
|
sensible raw values most of the time. Some further testing is necessary, but some changes in the
|
||||||
code should cause the SUS devices to remain healthy for now.
|
code should cause the SUS devices to remain healthy for now.
|
||||||
|
|
||||||
# [v3.0.0] to be released
|
# [v3.0.0] 2023-06-11
|
||||||
|
|
||||||
|
- `eive-tmtc` version v4.0.0
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
@ -61,6 +63,13 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
only be used to cancel a transfer.
|
only be used to cancel a transfer.
|
||||||
- Handling of multiple RWs in the ACS Controller is improved and can be changed by parameter
|
- Handling of multiple RWs in the ACS Controller is improved and can be changed by parameter
|
||||||
commands.
|
commands.
|
||||||
|
- The Directory Listing direct dumper now has a state machine to stagger the directory listing dump.
|
||||||
|
This is required because very large dumps will overload the queue capacities in the framework.
|
||||||
|
- The PUS Service 8 now has larger queue sizes to handle more action replies. The PUS Service 1
|
||||||
|
also has a larger queue size to handle a lot of step replies now.
|
||||||
|
- Moved PDU `vcc` and `vbat` variable from auxiliary dataset to core dataset.
|
||||||
|
- Tweak TCP/IP configuration: Only the TCP server will be included on the EM. For the FM, no
|
||||||
|
TCP/IP servers will be included by default.
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
@ -71,9 +80,12 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
- IMTQ HK sets
|
- IMTQ HK sets
|
||||||
- IMTQ dummy now handles power switch
|
- IMTQ dummy now handles power switch
|
||||||
- Added some new ACS parameters
|
- Added some new ACS parameters
|
||||||
|
- Enabled decimation filter for the ADIS GYRs
|
||||||
|
- Enabled second low-pass filter for L3GD20H GYRs
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
- CFDP low level protocol bugfix. Requires `fsfw` update and `tmtc` update.
|
||||||
- Compile fix if SCEX is compiled for the EM.
|
- Compile fix if SCEX is compiled for the EM.
|
||||||
- Set up Rad Sensor chip select even for EM to avoid SPI bus issues.
|
- Set up Rad Sensor chip select even for EM to avoid SPI bus issues.
|
||||||
- Correct ADIS Gyroscope type configuration for the EM, where the 16507 type is used instead of the
|
- Correct ADIS Gyroscope type configuration for the EM, where the 16507 type is used instead of the
|
||||||
@ -107,6 +119,8 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
quaternion.
|
quaternion.
|
||||||
- Various fixes for the pointing modes of the `ACS Controller`. All modes should work now as
|
- Various fixes for the pointing modes of the `ACS Controller`. All modes should work now as
|
||||||
intended.
|
intended.
|
||||||
|
- The variance for the ADIS GYRs now represents the used `-3` version and not the `-1` version
|
||||||
|
- CFDP funnel did not route packets to live channel VC0
|
||||||
|
|
||||||
# [v2.0.5] 2023-05-11
|
# [v2.0.5] 2023-05-11
|
||||||
|
|
||||||
|
@ -79,6 +79,13 @@ else()
|
|||||||
set(INIT_VAL 1)
|
set(INIT_VAL 1)
|
||||||
set(OBSW_STAR_TRACKER_GROUND_CONFIG 0)
|
set(OBSW_STAR_TRACKER_GROUND_CONFIG 0)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(OBSW_ADD_TMTC_TCP_SERVER
|
||||||
|
${OBSW_Q7S_EM}
|
||||||
|
CACHE STRING "Add TCP TMTC Server")
|
||||||
|
set(OBSW_ADD_TMTC_UDP_SERVER
|
||||||
|
0
|
||||||
|
CACHE STRING "Add UDP TMTC Server")
|
||||||
set(OBSW_ADD_MGT
|
set(OBSW_ADD_MGT
|
||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
CACHE STRING "Add MGT module")
|
CACHE STRING "Add MGT module")
|
||||||
|
@ -67,8 +67,8 @@
|
|||||||
// because UDP packets are not allowed in the VPN
|
// because UDP packets are not allowed in the VPN
|
||||||
// This will cause the OBSW to initialize the TMTC bridge responsible for exchanging data with the
|
// This will cause the OBSW to initialize the TMTC bridge responsible for exchanging data with the
|
||||||
// CCSDS IP Cores.
|
// CCSDS IP Cores.
|
||||||
#define OBSW_ADD_TMTC_TCP_SERVER 1
|
#define OBSW_ADD_TMTC_TCP_SERVER @OBSW_ADD_TMTC_TCP_SERVER@
|
||||||
#define OBSW_ADD_TMTC_UDP_SERVER 1
|
#define OBSW_ADD_TMTC_UDP_SERVER @OBSW_ADD_TMTC_UDP_SERVER@
|
||||||
|
|
||||||
// Can be used to switch device to NORMAL mode immediately
|
// Can be used to switch device to NORMAL mode immediately
|
||||||
#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 0
|
#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 0
|
||||||
|
@ -112,6 +112,9 @@ void CoreController::performControlOperation() {
|
|||||||
sdStateMachine();
|
sdStateMachine();
|
||||||
performMountedSdCardOperations();
|
performMountedSdCardOperations();
|
||||||
readHkData();
|
readHkData();
|
||||||
|
if (dumpContext.active) {
|
||||||
|
dirListingDumpHandler();
|
||||||
|
}
|
||||||
|
|
||||||
if (shellCmdIsExecuting) {
|
if (shellCmdIsExecuting) {
|
||||||
bool replyReceived = false;
|
bool replyReceived = false;
|
||||||
@ -1038,7 +1041,6 @@ ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionI
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::array<uint8_t, 1024> dirListingBuf{};
|
|
||||||
dirListingBuf[8] = parser.compressionOptionSet();
|
dirListingBuf[8] = parser.compressionOptionSet();
|
||||||
// First four bytes reserved for segment index. One byte for compression option information
|
// First four bytes reserved for segment index. One byte for compression option information
|
||||||
std::strcpy(reinterpret_cast<char *>(dirListingBuf.data() + 2 * sizeof(uint32_t) + 1), repoName);
|
std::strcpy(reinterpret_cast<char *>(dirListingBuf.data() + 2 * sizeof(uint32_t) + 1), repoName);
|
||||||
@ -1047,38 +1049,47 @@ ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionI
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
size_t totalFileSize = std::filesystem::file_size(LIST_DIR_DUMP_WORK_FILE, e);
|
dumpContext.totalFileSize = std::filesystem::file_size(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
uint32_t segmentIdx = 0;
|
dumpContext.segmentIdx = 0;
|
||||||
size_t dumpedBytes = 0;
|
dumpContext.dumpedBytes = 0;
|
||||||
size_t nextDumpLen = 0;
|
size_t nextDumpLen = 0;
|
||||||
size_t dummy = 0;
|
size_t dummy = 0;
|
||||||
size_t maxDumpLen = dirListingBuf.size() - 2 * sizeof(uint32_t) - 1 - repoNameLen - 1;
|
dumpContext.maxDumpLen = dirListingBuf.size() - 2 * sizeof(uint32_t) - 1 - repoNameLen - 1;
|
||||||
size_t listingDataOffset = 2 * sizeof(uint32_t) + 1 + repoNameLen + 1;
|
dumpContext.listingDataOffset = 2 * sizeof(uint32_t) + 1 + repoNameLen + 1;
|
||||||
uint32_t chunks = totalFileSize / maxDumpLen;
|
uint32_t chunks = dumpContext.totalFileSize / dumpContext.maxDumpLen;
|
||||||
if (totalFileSize % maxDumpLen != 0) {
|
if (dumpContext.totalFileSize % dumpContext.maxDumpLen != 0) {
|
||||||
chunks++;
|
chunks++;
|
||||||
}
|
}
|
||||||
SerializeAdapter::serialize(&chunks, dirListingBuf.data() + sizeof(uint32_t), &dummy,
|
SerializeAdapter::serialize(&chunks, dirListingBuf.data() + sizeof(uint32_t), &dummy,
|
||||||
dirListingBuf.size() - sizeof(uint32_t),
|
dirListingBuf.size() - sizeof(uint32_t),
|
||||||
SerializeIF::Endianness::NETWORK);
|
SerializeIF::Endianness::NETWORK);
|
||||||
while (dumpedBytes < totalFileSize) {
|
while (dumpContext.dumpedBytes < dumpContext.totalFileSize) {
|
||||||
ifile.seekg(dumpedBytes, std::ios::beg);
|
ifile.seekg(dumpContext.dumpedBytes, std::ios::beg);
|
||||||
nextDumpLen = maxDumpLen;
|
nextDumpLen = dumpContext.maxDumpLen;
|
||||||
if (totalFileSize - dumpedBytes < maxDumpLen) {
|
if (dumpContext.totalFileSize - dumpContext.dumpedBytes < dumpContext.maxDumpLen) {
|
||||||
nextDumpLen = totalFileSize - dumpedBytes;
|
nextDumpLen = dumpContext.totalFileSize - dumpContext.dumpedBytes;
|
||||||
}
|
}
|
||||||
SerializeAdapter::serialize(&segmentIdx, dirListingBuf.data(), &dummy, dirListingBuf.size(),
|
SerializeAdapter::serialize(&dumpContext.segmentIdx, dirListingBuf.data(), &dummy,
|
||||||
SerializeIF::Endianness::NETWORK);
|
dirListingBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||||
ifile.read(reinterpret_cast<char *>(dirListingBuf.data() + listingDataOffset), nextDumpLen);
|
ifile.read(reinterpret_cast<char *>(dirListingBuf.data() + dumpContext.listingDataOffset),
|
||||||
|
nextDumpLen);
|
||||||
result = actionHelper.reportData(commandedBy, actionId, dirListingBuf.data(),
|
result = actionHelper.reportData(commandedBy, actionId, dirListingBuf.data(),
|
||||||
listingDataOffset + nextDumpLen);
|
dumpContext.listingDataOffset + nextDumpLen);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
// Remove work file when we are done
|
// Remove work file when we are done
|
||||||
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
segmentIdx++;
|
dumpContext.segmentIdx++;
|
||||||
dumpedBytes += nextDumpLen;
|
dumpContext.dumpedBytes += nextDumpLen;
|
||||||
|
// Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles.
|
||||||
|
if (dumpContext.segmentIdx == 10) {
|
||||||
|
dumpContext.active = true;
|
||||||
|
dumpContext.firstDump = true;
|
||||||
|
dumpContext.commander = commandedBy;
|
||||||
|
dumpContext.actionId = actionId;
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Remove work file when we are done
|
// Remove work file when we are done
|
||||||
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
@ -2346,6 +2357,54 @@ MessageQueueId_t CoreController::getCommandQueue() const {
|
|||||||
return ExtendedControllerBase::getCommandQueue();
|
return ExtendedControllerBase::getCommandQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CoreController::dirListingDumpHandler() {
|
||||||
|
if (dumpContext.firstDump) {
|
||||||
|
dumpContext.firstDump = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t nextDumpLen = 0;
|
||||||
|
size_t dummy = 0;
|
||||||
|
ReturnValue_t result;
|
||||||
|
std::error_code e;
|
||||||
|
std::ifstream ifile(LIST_DIR_DUMP_WORK_FILE, std::ios::binary);
|
||||||
|
if (ifile.bad()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (dumpContext.dumpedBytes < dumpContext.totalFileSize) {
|
||||||
|
ifile.seekg(dumpContext.dumpedBytes, std::ios::beg);
|
||||||
|
nextDumpLen = dumpContext.maxDumpLen;
|
||||||
|
if (dumpContext.totalFileSize - dumpContext.dumpedBytes < dumpContext.maxDumpLen) {
|
||||||
|
nextDumpLen = dumpContext.totalFileSize - dumpContext.dumpedBytes;
|
||||||
|
}
|
||||||
|
SerializeAdapter::serialize(&dumpContext.segmentIdx, dirListingBuf.data(), &dummy,
|
||||||
|
dirListingBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||||
|
ifile.read(reinterpret_cast<char *>(dirListingBuf.data() + dumpContext.listingDataOffset),
|
||||||
|
nextDumpLen);
|
||||||
|
result =
|
||||||
|
actionHelper.reportData(dumpContext.commander, dumpContext.actionId, dirListingBuf.data(),
|
||||||
|
dumpContext.listingDataOffset + nextDumpLen);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
// Remove work file when we are done
|
||||||
|
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
|
dumpContext.active = false;
|
||||||
|
actionHelper.finish(false, dumpContext.commander, dumpContext.actionId, result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dumpContext.segmentIdx++;
|
||||||
|
dumpContext.dumpedBytes += nextDumpLen;
|
||||||
|
// Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles.
|
||||||
|
if (dumpContext.segmentIdx == 10) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dumpContext.dumpedBytes >= dumpContext.totalFileSize) {
|
||||||
|
actionHelper.finish(true, dumpContext.commander, dumpContext.actionId, result);
|
||||||
|
dumpContext.active = false;
|
||||||
|
// Remove work file when we are done
|
||||||
|
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CoreController::isNumber(const std::string &s) {
|
bool CoreController::isNumber(const std::string &s) {
|
||||||
return !s.empty() && std::find_if(s.begin(), s.end(),
|
return !s.empty() && std::find_if(s.begin(), s.end(),
|
||||||
[](unsigned char c) { return !std::isdigit(c); }) == s.end();
|
[](unsigned char c) { return !std::isdigit(c); }) == s.end();
|
||||||
|
@ -177,6 +177,20 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
|
|||||||
DeviceCommandId_t actionId;
|
DeviceCommandId_t actionId;
|
||||||
} sdCommandingInfo;
|
} sdCommandingInfo;
|
||||||
|
|
||||||
|
struct DirListingDumpContext {
|
||||||
|
bool active;
|
||||||
|
bool firstDump;
|
||||||
|
size_t dumpedBytes;
|
||||||
|
size_t totalFileSize;
|
||||||
|
size_t listingDataOffset;
|
||||||
|
size_t maxDumpLen;
|
||||||
|
uint32_t segmentIdx;
|
||||||
|
MessageQueueId_t commander = MessageQueueIF::NO_QUEUE;
|
||||||
|
DeviceCommandId_t actionId;
|
||||||
|
};
|
||||||
|
std::array<uint8_t, 1024> dirListingBuf{};
|
||||||
|
DirListingDumpContext dumpContext{};
|
||||||
|
|
||||||
RebootFile rebootFile = {};
|
RebootFile rebootFile = {};
|
||||||
|
|
||||||
CommandExecutor cmdExecutor;
|
CommandExecutor cmdExecutor;
|
||||||
@ -274,6 +288,7 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
|
|||||||
void rewriteRebootFile(RebootFile file);
|
void rewriteRebootFile(RebootFile file);
|
||||||
void announceBootCounts();
|
void announceBootCounts();
|
||||||
void readHkData();
|
void readHkData();
|
||||||
|
void dirListingDumpHandler();
|
||||||
bool isNumber(const std::string& s);
|
bool isNumber(const std::string& s);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -140,6 +140,7 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#if OBSW_TM_TO_PTME == 1
|
#if OBSW_TM_TO_PTME == 1
|
||||||
if (ccsdsArgs.liveDestination != nullptr) {
|
if (ccsdsArgs.liveDestination != nullptr) {
|
||||||
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
||||||
|
cfdpFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
||||||
|
@ -97,6 +97,7 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#if OBSW_TM_TO_PTME == 1
|
#if OBSW_TM_TO_PTME == 1
|
||||||
if (ccsdsArgs.liveDestination != nullptr) {
|
if (ccsdsArgs.liveDestination != nullptr) {
|
||||||
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
||||||
|
cfdpFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
||||||
|
@ -58,7 +58,9 @@ static constexpr uint32_t CFDP_STORE_QUEUE_SIZE = 300;
|
|||||||
|
|
||||||
static constexpr uint32_t MAX_PUS_FUNNEL_QUEUE_DEPTH = 100;
|
static constexpr uint32_t MAX_PUS_FUNNEL_QUEUE_DEPTH = 100;
|
||||||
static constexpr uint32_t MAX_CFDP_FUNNEL_QUEUE_DEPTH = 80;
|
static constexpr uint32_t MAX_CFDP_FUNNEL_QUEUE_DEPTH = 80;
|
||||||
|
static constexpr uint32_t VERIFICATION_SERVICE_QUEUE_DEPTH = 120;
|
||||||
static constexpr uint32_t HK_SERVICE_QUEUE_DEPTH = 60;
|
static constexpr uint32_t HK_SERVICE_QUEUE_DEPTH = 60;
|
||||||
|
static constexpr uint32_t ACTION_SERVICE_QUEUE_DEPTH = 60;
|
||||||
|
|
||||||
static constexpr uint32_t MAX_STORED_CMDS_UDP = 150;
|
static constexpr uint32_t MAX_STORED_CMDS_UDP = 150;
|
||||||
static constexpr uint32_t MAX_STORED_CMDS_TCP = 180;
|
static constexpr uint32_t MAX_STORED_CMDS_TCP = 180;
|
||||||
|
@ -19,7 +19,7 @@ struct DummyCfg {
|
|||||||
bool addTempSensorDummies = true;
|
bool addTempSensorDummies = true;
|
||||||
bool addRtdComIFDummy = true;
|
bool addRtdComIFDummy = true;
|
||||||
bool addPlocDummies = true;
|
bool addPlocDummies = true;
|
||||||
bool addCamSwitcherDummy = true;
|
bool addCamSwitcherDummy = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
void createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch, GpioIF* gpioIF, bool enableHkSets);
|
void createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch, GpioIF* gpioIF, bool enableHkSets);
|
||||||
|
2
fsfw
2
fsfw
@ -1 +1 @@
|
|||||||
Subproject commit 5eb9ee8bc1e6f8640cbea46febd11e4b92241881
|
Subproject commit 5322de059916efcf874b10ccc766b46e53d2470b
|
@ -113,6 +113,7 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
|||||||
if (req->mode != adis.mode) {
|
if (req->mode != adis.mode) {
|
||||||
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
||||||
adis.type = req->type;
|
adis.type = req->type;
|
||||||
|
adis.decRate = req->cfg.decRateReg;
|
||||||
// The initial countdown is handled by the device handler now.
|
// The initial countdown is handled by the device handler now.
|
||||||
// adis.countdown.setTimeout(adis1650x::START_UP_TIME);
|
// adis.countdown.setTimeout(adis1650x::START_UP_TIME);
|
||||||
if (adis.type == adis1650x::Type::ADIS16507) {
|
if (adis.type == adis1650x::Type::ADIS16507) {
|
||||||
@ -376,6 +377,80 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t AcsBoardPolling::writeAdisReg(SpiCookie& cookie) {
|
||||||
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
int retval = 0;
|
||||||
|
// Prepare transfer
|
||||||
|
int fileDescriptor = 0;
|
||||||
|
std::string device = spiComIF.getSpiDev();
|
||||||
|
UnixFileGuard fileHelper(device, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||||
|
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||||
|
return spi::OPENING_FILE_FAILED;
|
||||||
|
}
|
||||||
|
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
||||||
|
uint32_t spiSpeed = 0;
|
||||||
|
cookie.getSpiParameters(spiMode, spiSpeed, nullptr);
|
||||||
|
spiComIF.setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||||
|
cookie.assignWriteBuffer(cmdBuf.data());
|
||||||
|
cookie.setTransferSize(2);
|
||||||
|
|
||||||
|
gpioId_t gpioId = cookie.getChipSelectPin();
|
||||||
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
|
uint32_t timeoutMs = 0;
|
||||||
|
MutexIF* mutex = spiComIF.getCsMutex();
|
||||||
|
cookie.getMutexParams(timeoutType, timeoutMs);
|
||||||
|
if (mutex == nullptr) {
|
||||||
|
sif::warning << "GyroADIS16507Handler::spiSendCallback: "
|
||||||
|
"Mutex or GPIO interface invalid"
|
||||||
|
<< std::endl;
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = 0;
|
||||||
|
spi_ioc_transfer* transferStruct = cookie.getTransferStructHandle();
|
||||||
|
uint64_t origTx = transferStruct->tx_buf;
|
||||||
|
uint64_t origRx = transferStruct->rx_buf;
|
||||||
|
for (idx = 0; idx < 4; idx += 2) {
|
||||||
|
result = mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "AcsBoardPolling: Failed to lock mutex" << std::endl;
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// Pull SPI CS low. For now, no support for active high given
|
||||||
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
|
gpioIF.pullLow(gpioId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute transfer
|
||||||
|
// Initiate a full duplex SPI transfer.
|
||||||
|
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie.getTransferStructHandle());
|
||||||
|
if (retval < 0) {
|
||||||
|
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||||
|
result = spi::FULL_DUPLEX_TRANSFER_FAILED;
|
||||||
|
}
|
||||||
|
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||||
|
comIf->performSpiWiretapping(cookie);
|
||||||
|
#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */
|
||||||
|
|
||||||
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
|
gpioIF.pullHigh(gpioId);
|
||||||
|
}
|
||||||
|
mutex->unlockMutex();
|
||||||
|
|
||||||
|
transferStruct->tx_buf += 2;
|
||||||
|
transferStruct->rx_buf += 2;
|
||||||
|
if (idx < 4) {
|
||||||
|
usleep(adis1650x::STALL_TIME_MICROSECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transferStruct->tx_buf = origTx;
|
||||||
|
transferStruct->rx_buf = origRx;
|
||||||
|
cookie.setTransferSize(0);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen) {
|
ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
@ -455,15 +530,20 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
|||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
|
acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
|
||||||
bool mustPerformStartup = false;
|
bool mustPerformStartup = false;
|
||||||
|
uint16_t decRate = 0;
|
||||||
{
|
{
|
||||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||||
mode = gyro.mode;
|
mode = gyro.mode;
|
||||||
|
decRate = gyro.decRate;
|
||||||
mustPerformStartup = gyro.performStartup;
|
mustPerformStartup = gyro.performStartup;
|
||||||
}
|
}
|
||||||
if (mode == acs::SimpleSensorMode::OFF) {
|
if (mode == acs::SimpleSensorMode::OFF) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mustPerformStartup) {
|
if (mustPerformStartup) {
|
||||||
|
adis1650x::prepareWriteRegCommand(adis1650x::DEC_RATE_REG, decRate, cmdBuf.data(),
|
||||||
|
cmdBuf.size());
|
||||||
|
writeAdisReg(*gyro.cookie);
|
||||||
uint8_t regList[6];
|
uint8_t regList[6];
|
||||||
// Read configuration
|
// Read configuration
|
||||||
regList[0] = adis1650x::DIAG_STAT_REG;
|
regList[0] = adis1650x::DIAG_STAT_REG;
|
||||||
@ -491,13 +571,19 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
|||||||
gyro.replyResult = returnvalue::FAILED;
|
gyro.replyResult = returnvalue::FAILED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
uint16_t decRateReadBack = (rawReply[10] << 8) | rawReply[11];
|
||||||
|
if (decRateReadBack != decRate) {
|
||||||
|
sif::warning << "AcsPollingTask: DEC rate configuration failed. Read " << decRateReadBack
|
||||||
|
<< ", expected " << decRate << std::endl;
|
||||||
|
gyro.replyResult = returnvalue::FAILED;
|
||||||
|
}
|
||||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||||
gyro.ownReply.cfgWasSet = true;
|
gyro.ownReply.cfgWasSet = true;
|
||||||
gyro.ownReply.cfg.diagStat = (rawReply[2] << 8) | rawReply[3];
|
gyro.ownReply.cfg.diagStat = (rawReply[2] << 8) | rawReply[3];
|
||||||
gyro.ownReply.cfg.filterSetting = (rawReply[4] << 8) | rawReply[5];
|
gyro.ownReply.cfg.filterSetting = (rawReply[4] << 8) | rawReply[5];
|
||||||
gyro.ownReply.cfg.rangMdl = (rawReply[6] << 8) | rawReply[7];
|
gyro.ownReply.cfg.rangMdl = (rawReply[6] << 8) | rawReply[7];
|
||||||
gyro.ownReply.cfg.mscCtrlReg = (rawReply[8] << 8) | rawReply[9];
|
gyro.ownReply.cfg.mscCtrlReg = (rawReply[8] << 8) | rawReply[9];
|
||||||
gyro.ownReply.cfg.decRateReg = (rawReply[10] << 8) | rawReply[11];
|
gyro.ownReply.cfg.decRateReg = decRateReadBack;
|
||||||
gyro.ownReply.cfg.prodId = prodId;
|
gyro.ownReply.cfg.prodId = prodId;
|
||||||
gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl);
|
gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl);
|
||||||
gyro.performStartup = false;
|
gyro.performStartup = false;
|
||||||
|
@ -37,6 +37,7 @@ class AcsBoardPolling : public SystemObject,
|
|||||||
|
|
||||||
struct GyroAdis : public DevBase {
|
struct GyroAdis : public DevBase {
|
||||||
adis1650x::Type type;
|
adis1650x::Type type;
|
||||||
|
uint16_t decRate;
|
||||||
Countdown countdown;
|
Countdown countdown;
|
||||||
acs::Adis1650XReply ownReply;
|
acs::Adis1650XReply ownReply;
|
||||||
acs::Adis1650XReply readerReply;
|
acs::Adis1650XReply readerReply;
|
||||||
@ -84,6 +85,8 @@ class AcsBoardPolling : public SystemObject,
|
|||||||
void gyroAdisHandler(GyroAdis& gyro);
|
void gyroAdisHandler(GyroAdis& gyro);
|
||||||
void mgmLis3Handler(MgmLis3& mgm);
|
void mgmLis3Handler(MgmLis3& mgm);
|
||||||
void mgmRm3100Handler(MgmRm3100& mgm);
|
void mgmRm3100Handler(MgmRm3100& mgm);
|
||||||
|
// This fumction configures the register as specified on p.21 of the datasheet.
|
||||||
|
ReturnValue_t writeAdisReg(SpiCookie& cookie);
|
||||||
// Special readout: 16us stall time between small 2 byte transfers.
|
// Special readout: 16us stall time between small 2 byte transfers.
|
||||||
ReturnValue_t readAdisCfg(SpiCookie& spiCookie, size_t transferLen);
|
ReturnValue_t readAdisCfg(SpiCookie& spiCookie, size_t transferLen);
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,7 @@ GyrAdis1650XHandler::GyrAdis1650XHandler(object_id_t objectId, object_id_t devic
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GyrAdis1650XHandler::doStartUp() {
|
void GyrAdis1650XHandler::doStartUp() {
|
||||||
if (internalState != InternalState::STARTUP) {
|
if (internalState == InternalState::NONE) {
|
||||||
internalState = InternalState::STARTUP;
|
internalState = InternalState::STARTUP;
|
||||||
commandExecuted = false;
|
commandExecuted = false;
|
||||||
}
|
}
|
||||||
@ -24,13 +24,14 @@ void GyrAdis1650XHandler::doStartUp() {
|
|||||||
if (not commandExecuted) {
|
if (not commandExecuted) {
|
||||||
warningSwitch = true;
|
warningSwitch = true;
|
||||||
breakCountdown.setTimeout(adis1650x::START_UP_TIME);
|
breakCountdown.setTimeout(adis1650x::START_UP_TIME);
|
||||||
|
updatePeriodicReply(true, adis1650x::REPLY);
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
}
|
}
|
||||||
if (breakCountdown.hasTimedOut()) {
|
|
||||||
updatePeriodicReply(true, adis1650x::REPLY);
|
|
||||||
setMode(MODE_ON);
|
|
||||||
internalState = InternalState::NONE;
|
|
||||||
}
|
}
|
||||||
|
if (internalState == InternalState::STARTUP_DONE) {
|
||||||
|
setMode(MODE_ON);
|
||||||
|
commandExecuted = false;
|
||||||
|
internalState = InternalState::NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +62,7 @@ ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_
|
|||||||
return NOTHING_TO_SEND;
|
return NOTHING_TO_SEND;
|
||||||
}
|
}
|
||||||
*id = adis1650x::REQUEST;
|
*id = adis1650x::REQUEST;
|
||||||
|
adisRequest.cfg.decRateReg = adis1650x::DEC_RATE;
|
||||||
return preparePeriodicRequest(acs::SimpleSensorMode::NORMAL);
|
return preparePeriodicRequest(acs::SimpleSensorMode::NORMAL);
|
||||||
}
|
}
|
||||||
case (InternalState::SHUTDOWN): {
|
case (InternalState::SHUTDOWN): {
|
||||||
@ -91,6 +93,9 @@ ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t rem
|
|||||||
getMode() == _MODE_POWER_DOWN) {
|
getMode() == _MODE_POWER_DOWN) {
|
||||||
return IGNORE_FULL_PACKET;
|
return IGNORE_FULL_PACKET;
|
||||||
}
|
}
|
||||||
|
if (internalState == InternalState::STARTUP) {
|
||||||
|
internalState = InternalState::STARTUP_DONE;
|
||||||
|
}
|
||||||
*foundLen = remainingSize;
|
*foundLen = remainingSize;
|
||||||
if (remainingSize != sizeof(acs::Adis1650XReply)) {
|
if (remainingSize != sizeof(acs::Adis1650XReply)) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
|
@ -48,7 +48,7 @@ class GyrAdis1650XHandler : public DeviceHandlerBase {
|
|||||||
|
|
||||||
bool warningSwitch = true;
|
bool warningSwitch = true;
|
||||||
|
|
||||||
enum class InternalState { NONE, STARTUP, SHUTDOWN };
|
enum class InternalState { NONE, STARTUP, STARTUP_DONE, SHUTDOWN };
|
||||||
|
|
||||||
InternalState internalState = InternalState::STARTUP;
|
InternalState internalState = InternalState::STARTUP;
|
||||||
bool commandExecuted = false;
|
bool commandExecuted = false;
|
||||||
|
@ -8,11 +8,6 @@
|
|||||||
|
|
||||||
namespace acs {
|
namespace acs {
|
||||||
|
|
||||||
struct Adis1650XRequest {
|
|
||||||
SimpleSensorMode mode;
|
|
||||||
adis1650x::Type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Adis1650XConfig {
|
struct Adis1650XConfig {
|
||||||
uint16_t diagStat;
|
uint16_t diagStat;
|
||||||
uint16_t filterSetting;
|
uint16_t filterSetting;
|
||||||
@ -22,6 +17,12 @@ struct Adis1650XConfig {
|
|||||||
uint16_t prodId;
|
uint16_t prodId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Adis1650XRequest {
|
||||||
|
SimpleSensorMode mode;
|
||||||
|
adis1650x::Type type;
|
||||||
|
Adis1650XConfig cfg;
|
||||||
|
};
|
||||||
|
|
||||||
struct Adis1650XData {
|
struct Adis1650XData {
|
||||||
double sensitivity = 0.0;
|
double sensitivity = 0.0;
|
||||||
// Angular velocities in all axes (X, Y and Z)
|
// Angular velocities in all axes (X, Y and Z)
|
||||||
|
@ -52,3 +52,14 @@ double adis1650x::rangMdlToSensitivity(uint16_t rangMdl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void adis1650x::prepareWriteRegCommand(uint8_t regStart, uint16_t val, uint8_t* outBuf,
|
||||||
|
size_t maxLen) {
|
||||||
|
if (maxLen < 4) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
outBuf[0] = regStart | adis1650x::WRITE_MASK;
|
||||||
|
outBuf[1] = val & 0xff;
|
||||||
|
outBuf[2] = (regStart + 1) | adis1650x::WRITE_MASK;
|
||||||
|
outBuf[3] = (val >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
@ -16,6 +16,8 @@ enum class BurstModes {
|
|||||||
};
|
};
|
||||||
|
|
||||||
size_t prepareReadCommand(const uint8_t* regList, size_t len, uint8_t* outBuf, size_t maxLen);
|
size_t prepareReadCommand(const uint8_t* regList, size_t len, uint8_t* outBuf, size_t maxLen);
|
||||||
|
void prepareWriteRegCommand(uint8_t regStart, uint16_t val, uint8_t* outBuf, size_t maxLen);
|
||||||
|
|
||||||
BurstModes burstModeFromMscCtrl(uint16_t mscCtrl);
|
BurstModes burstModeFromMscCtrl(uint16_t mscCtrl);
|
||||||
double rangMdlToSensitivity(uint16_t rangMdl);
|
double rangMdlToSensitivity(uint16_t rangMdl);
|
||||||
|
|
||||||
@ -92,6 +94,9 @@ static constexpr size_t SENSOR_READOUT_SIZE = 20 + 2;
|
|||||||
static constexpr uint32_t ADIS_DATASET_ID = READ_SENSOR_DATA;
|
static constexpr uint32_t ADIS_DATASET_ID = READ_SENSOR_DATA;
|
||||||
static constexpr uint32_t ADIS_CFG_DATASET_ID = READ_OUT_CONFIG;
|
static constexpr uint32_t ADIS_CFG_DATASET_ID = READ_OUT_CONFIG;
|
||||||
|
|
||||||
|
static constexpr uint16_t FILT_CTRL = 0x0000;
|
||||||
|
static constexpr uint16_t DEC_RATE = 0x00C7;
|
||||||
|
|
||||||
enum GlobCmds : uint8_t {
|
enum GlobCmds : uint8_t {
|
||||||
FACTORY_CALIBRATION = 0b0000'0010,
|
FACTORY_CALIBRATION = 0b0000'0010,
|
||||||
SENSOR_SELF_TEST = 0b0000'0100,
|
SENSOR_SELF_TEST = 0b0000'0100,
|
||||||
|
@ -93,6 +93,7 @@ ReturnValue_t CfdpHandler::handleCfdpPacket(TmTcMessage& msg) {
|
|||||||
return INVALID_PDU_FORMAT;
|
return INVALID_PDU_FORMAT;
|
||||||
}
|
}
|
||||||
if (not FileDirectiveReader::checkFileDirective(pduDataField[0])) {
|
if (not FileDirectiveReader::checkFileDirective(pduDataField[0])) {
|
||||||
|
sif::error << "CfdpHandler: Invalid PDU directive field " << pduDataField[0] << std::endl;
|
||||||
return INVALID_DIRECTIVE_FIELD;
|
return INVALID_DIRECTIVE_FIELD;
|
||||||
}
|
}
|
||||||
auto directive = static_cast<FileDirective>(pduDataField[0]);
|
auto directive = static_cast<FileDirective>(pduDataField[0]);
|
||||||
|
@ -781,9 +781,9 @@ class AcsParameters : public HasParametersIF {
|
|||||||
|
|
||||||
/* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is
|
/* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is
|
||||||
* assumed to be equal for the same class of sensors */
|
* assumed to be equal for the same class of sensors */
|
||||||
float gyr02variance[3] = {pow(3.0e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms
|
float gyr02variance[3] = {pow(4.6e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms
|
||||||
pow(3.0e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
|
pow(4.6e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
|
||||||
pow(4.3e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms
|
pow(6.1e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms
|
||||||
float gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
|
float gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
|
||||||
uint8_t preferAdis = false;
|
uint8_t preferAdis = false;
|
||||||
float gyrFilterWeight = 0.6;
|
float gyrFilterWeight = 0.6;
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "mission/system/acs/acsModeTree.h"
|
#include "mission/system/acs/acsModeTree.h"
|
||||||
#include "mission/system/tcs/tcsModeTree.h"
|
#include "mission/system/tcs/tcsModeTree.h"
|
||||||
#include "mission/tcs/defs.h"
|
#include "mission/tcs/defs.h"
|
||||||
|
#include "mission/tmtc/Service15TmStorage.h"
|
||||||
#include "mission/tmtc/tmFilters.h"
|
#include "mission/tmtc/tmFilters.h"
|
||||||
#include "objects/systemObjectList.h"
|
#include "objects/systemObjectList.h"
|
||||||
#include "tmtc/pusIds.h"
|
#include "tmtc/pusIds.h"
|
||||||
@ -58,15 +59,13 @@ using persTmStore::PersistentTmStores;
|
|||||||
#if OBSW_ADD_TCPIP_SERVERS == 1
|
#if OBSW_ADD_TCPIP_SERVERS == 1
|
||||||
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
||||||
// UDP server includes
|
// UDP server includes
|
||||||
#include "devices/gpioIds.h"
|
#include <fsfw/osal/common/UdpTcPollingTask.h>
|
||||||
#include "fsfw/osal/common/UdpTcPollingTask.h"
|
#include <fsfw/osal/common/UdpTmTcBridge.h>
|
||||||
#include "fsfw/osal/common/UdpTmTcBridge.h"
|
|
||||||
#endif
|
#endif
|
||||||
#if OBSW_ADD_TMTC_TCP_SERVER == 1
|
#if OBSW_ADD_TMTC_TCP_SERVER == 1
|
||||||
// TCP server includes
|
// TCP server includes
|
||||||
#include "fsfw/osal/common/TcpTmTcBridge.h"
|
#include <fsfw/osal/common/TcpTmTcBridge.h>
|
||||||
#include "fsfw/osal/common/TcpTmTcServer.h"
|
#include <fsfw/osal/common/TcpTmTcServer.h>
|
||||||
#include "mission/tmtc/Service15TmStorage.h"
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -234,7 +233,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
|
|
||||||
// PUS service stack
|
// PUS service stack
|
||||||
new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION, config::EIVE_PUS_APID,
|
new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION, config::EIVE_PUS_APID,
|
||||||
pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL, 40);
|
pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL,
|
||||||
|
config::VERIFICATION_SERVICE_QUEUE_DEPTH);
|
||||||
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, config::EIVE_PUS_APID,
|
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, config::EIVE_PUS_APID,
|
||||||
pus::PUS_SERVICE_2, 3, 10);
|
pus::PUS_SERVICE_2, 3, 10);
|
||||||
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID,
|
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID,
|
||||||
@ -243,7 +243,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5),
|
PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5),
|
||||||
80, 160);
|
80, 160);
|
||||||
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, config::EIVE_PUS_APID,
|
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, config::EIVE_PUS_APID,
|
||||||
pus::PUS_SERVICE_8, 16, 60);
|
pus::PUS_SERVICE_8, config::ACTION_SERVICE_QUEUE_DEPTH, 16, 60);
|
||||||
new Service9TimeManagement(
|
new Service9TimeManagement(
|
||||||
PsbParams(objects::PUS_SERVICE_9_TIME_MGMT, config::EIVE_PUS_APID, pus::PUS_SERVICE_9));
|
PsbParams(objects::PUS_SERVICE_9_TIME_MGMT, config::EIVE_PUS_APID, pus::PUS_SERVICE_9));
|
||||||
|
|
||||||
|
@ -595,8 +595,8 @@ ReturnValue_t GomspaceDeviceHandler::parsePduHkTable(PDU::PduCoreHk& coreHk, PDU
|
|||||||
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
|
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
|
||||||
coreHk.voltages[idx] = as<uint16_t>(packet + 0x12 + (idx * 2));
|
coreHk.voltages[idx] = as<uint16_t>(packet + 0x12 + (idx * 2));
|
||||||
}
|
}
|
||||||
auxHk.vcc.value = as<int16_t>(packet + 0x24);
|
coreHk.vcc.value = as<int16_t>(packet + 0x24);
|
||||||
auxHk.vbat.value = as<int16_t>(packet + 0x26);
|
coreHk.vbat.value = as<int16_t>(packet + 0x26);
|
||||||
coreHk.temperature = as<int16_t>(packet + 0x28) * 0.1;
|
coreHk.temperature = as<int16_t>(packet + 0x28) * 0.1;
|
||||||
|
|
||||||
for (uint8_t idx = 0; idx < 3; idx++) {
|
for (uint8_t idx = 0; idx < 3; idx++) {
|
||||||
|
@ -404,6 +404,11 @@ class PduCoreHk : public StaticLocalDataSet<9> {
|
|||||||
/** Battery mode: 1 = Critical, 2 = Safe, 3 = Normal, 4 = Full */
|
/** Battery mode: 1 = Critical, 2 = Safe, 3 = Normal, 4 = Full */
|
||||||
lp_var_t<uint8_t> battMode = lp_var_t<uint8_t>(sid.objectId, pool::PDU_BATT_MODE, this);
|
lp_var_t<uint8_t> battMode = lp_var_t<uint8_t>(sid.objectId, pool::PDU_BATT_MODE, this);
|
||||||
lp_var_t<float> temperature = lp_var_t<float>(sid.objectId, pool::PDU_TEMPERATURE, this);
|
lp_var_t<float> temperature = lp_var_t<float>(sid.objectId, pool::PDU_TEMPERATURE, this);
|
||||||
|
|
||||||
|
/** Measured VCC */
|
||||||
|
lp_var_t<int16_t> vcc = lp_var_t<int16_t>(sid.objectId, pool::PDU_VCC, this);
|
||||||
|
/** Measured VBAT */
|
||||||
|
lp_var_t<int16_t> vbat = lp_var_t<int16_t>(sid.objectId, pool::PDU_VBAT, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PduConfig : public StaticLocalDataSet<32> {
|
class PduConfig : public StaticLocalDataSet<32> {
|
||||||
@ -451,11 +456,6 @@ class PduAuxHk : public StaticLocalDataSet<36> {
|
|||||||
|
|
||||||
PduAuxHk(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {}
|
PduAuxHk(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {}
|
||||||
|
|
||||||
/** Measured VCC */
|
|
||||||
lp_var_t<int16_t> vcc = lp_var_t<int16_t>(sid.objectId, pool::PDU_VCC, this);
|
|
||||||
/** Measured VBAT */
|
|
||||||
lp_var_t<int16_t> vbat = lp_var_t<int16_t>(sid.objectId, pool::PDU_VBAT, this);
|
|
||||||
|
|
||||||
/** Output converter enable status */
|
/** Output converter enable status */
|
||||||
lp_vec_t<uint8_t, 3> converterEnable =
|
lp_vec_t<uint8_t, 3> converterEnable =
|
||||||
lp_vec_t<uint8_t, 3>(sid.objectId, pool::PDU_CONV_EN, this);
|
lp_vec_t<uint8_t, 3>(sid.objectId, pool::PDU_CONV_EN, this);
|
||||||
|
Loading…
Reference in New Issue
Block a user