Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
This commit is contained in:
@ -3,8 +3,9 @@ if(EIVE_BUILD_GPSD_GPS_HANDLER)
|
||||
endif()
|
||||
|
||||
target_sources(
|
||||
${OBSW_NAME} PRIVATE Max31865RtdLowlevelHandler.cpp ScexUartReader.cpp
|
||||
ScexDleParser.cpp ScexHelper.cpp RwPollingTask.cpp)
|
||||
${OBSW_NAME}
|
||||
PRIVATE Max31865RtdLowlevelHandler.cpp ScexUartReader.cpp ScexDleParser.cpp
|
||||
ScexHelper.cpp RwPollingTask.cpp ImtqPollingTask.cpp)
|
||||
|
||||
add_subdirectory(ploc)
|
||||
|
||||
|
433
linux/devices/ImtqPollingTask.cpp
Normal file
433
linux/devices/ImtqPollingTask.cpp
Normal file
@ -0,0 +1,433 @@
|
||||
#include "ImtqPollingTask.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <fsfw/tasks/SemaphoreFactory.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
#include <fsfw_hal/linux/UnixFileGuard.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
|
||||
ImtqPollingTask::ImtqPollingTask(object_id_t imtqPollingTask) : SystemObject(imtqPollingTask) {
|
||||
semaphore = SemaphoreFactory::instance()->createBinarySemaphore();
|
||||
semaphore->acquire();
|
||||
ipcLock = MutexFactory::instance()->createMutex();
|
||||
bufLock = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
ReturnValue_t ImtqPollingTask::performOperation(uint8_t operationCode) {
|
||||
while (true) {
|
||||
ipcLock->lockMutex();
|
||||
state = InternalState::IDLE;
|
||||
ipcLock->unlockMutex();
|
||||
semaphore->acquire();
|
||||
|
||||
comStatus = returnvalue::OK;
|
||||
// Stopwatch watch;
|
||||
switch (currentRequest) {
|
||||
case imtq::RequestType::MEASURE_NO_ACTUATION: {
|
||||
handleMeasureStep();
|
||||
break;
|
||||
}
|
||||
case imtq::RequestType::ACTUATE: {
|
||||
handleActuateStep();
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void ImtqPollingTask::handleMeasureStep() {
|
||||
size_t replyLen = 0;
|
||||
uint8_t* replyPtr;
|
||||
ImtqRepliesDefault replies(replyBuf.data());
|
||||
// Can be used later to verify correct timing (e.g. all data has been read)
|
||||
clearReadFlagsDefault(replies);
|
||||
auto i2cCmdExecMeasure = [&](imtq::CC::CC cc) {
|
||||
ccToReplyPtrMeasure(replies, cc, &replyPtr, replyLen);
|
||||
return i2cCmdExecDefault(cc, replyPtr, replyLen, imtq::MGM_MEASUREMENT_LOW_LEVEL_ERROR);
|
||||
};
|
||||
|
||||
cmdLen = 1;
|
||||
cmdBuf[0] = imtq::CC::GET_SYSTEM_STATE;
|
||||
if (i2cCmdExecMeasure(imtq::CC::GET_SYSTEM_STATE) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
ignoreNextActuateRequest =
|
||||
(replies.getSystemState()[2] == static_cast<uint8_t>(imtq::mode::SELF_TEST));
|
||||
if (ignoreNextActuateRequest) {
|
||||
// Do not command anything until self-test is done.
|
||||
return;
|
||||
}
|
||||
|
||||
if (specialRequest != imtq::SpecialRequest::NONE) {
|
||||
auto executeSelfTest = [&](imtq::selfTest::Axis axis) {
|
||||
cmdBuf[0] = imtq::CC::SELF_TEST_CMD;
|
||||
cmdBuf[1] = axis;
|
||||
return i2cCmdExecMeasure(imtq::CC::SELF_TEST_CMD);
|
||||
};
|
||||
// If a self-test is already ongoing, ignore the request.
|
||||
if (replies.getSystemState()[2] != static_cast<uint8_t>(imtq::mode::SELF_TEST)) {
|
||||
switch (specialRequest) {
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_POS_X): {
|
||||
executeSelfTest(imtq::selfTest::Axis::X_POSITIVE);
|
||||
break;
|
||||
}
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_NEG_X): {
|
||||
executeSelfTest(imtq::selfTest::Axis::X_NEGATIVE);
|
||||
break;
|
||||
}
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_POS_Y): {
|
||||
executeSelfTest(imtq::selfTest::Axis::Y_POSITIVE);
|
||||
break;
|
||||
}
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_NEG_Y): {
|
||||
executeSelfTest(imtq::selfTest::Axis::Y_NEGATIVE);
|
||||
break;
|
||||
}
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_POS_Z): {
|
||||
executeSelfTest(imtq::selfTest::Axis::Z_POSITIVE);
|
||||
break;
|
||||
}
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_NEG_Z): {
|
||||
executeSelfTest(imtq::selfTest::Axis::Z_NEGATIVE);
|
||||
break;
|
||||
}
|
||||
case (imtq::SpecialRequest::GET_SELF_TEST_RESULT): {
|
||||
cmdBuf[0] = imtq::CC::GET_SELF_TEST_RESULT;
|
||||
i2cCmdExecMeasure(imtq::CC::GET_SELF_TEST_RESULT);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// Should never happen
|
||||
break;
|
||||
}
|
||||
}
|
||||
// We are done. Only request self test or results here.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cmdBuf[0] = imtq::CC::START_MTM_MEASUREMENT;
|
||||
if (i2cCmdExecMeasure(imtq::CC::START_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
// Takes a bit of time to take measurements. Subtract a bit because of the delay of previous
|
||||
// commands.
|
||||
TaskFactory::delayTask(currentIntegrationTimeMs);
|
||||
|
||||
cmdBuf[0] = imtq::CC::GET_RAW_MTM_MEASUREMENT;
|
||||
if (i2cCmdExecMeasure(imtq::CC::GET_RAW_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmdBuf[0] = imtq::CC::GET_ENG_HK_DATA;
|
||||
if (i2cCmdExecMeasure(imtq::CC::GET_ENG_HK_DATA) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmdBuf[0] = imtq::CC::GET_CAL_MTM_MEASUREMENT;
|
||||
if (i2cCmdExecMeasure(imtq::CC::GET_CAL_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
// sif::debug << "measure done" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
void ImtqPollingTask::handleActuateStep() {
|
||||
uint8_t* replyPtr = nullptr;
|
||||
size_t replyLen = 0;
|
||||
// No point when self-test mode is active.
|
||||
if (ignoreNextActuateRequest) {
|
||||
return;
|
||||
}
|
||||
ImtqRepliesWithTorque replies(replyBufActuation.data());
|
||||
// Can be used later to verify correct timing (e.g. all data has been read)
|
||||
clearReadFlagsWithTorque(replies);
|
||||
auto i2cCmdExecActuate = [&](imtq::CC::CC cc) {
|
||||
ccToReplyPtrActuate(replies, cc, &replyPtr, replyLen);
|
||||
return i2cCmdExecDefault(cc, replyPtr, replyLen, imtq::ACTUATE_CMD_LOW_LEVEL_ERROR);
|
||||
};
|
||||
buildDipoleCommand();
|
||||
if (i2cCmdExecActuate(imtq::CC::START_ACTUATION_DIPOLE) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmdLen = 1;
|
||||
cmdBuf[0] = imtq::CC::START_MTM_MEASUREMENT;
|
||||
if (i2cCmdExecActuate(imtq::CC::START_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
TaskFactory::delayTask(currentIntegrationTimeMs);
|
||||
|
||||
cmdBuf[0] = imtq::CC::GET_RAW_MTM_MEASUREMENT;
|
||||
if (i2cCmdExecActuate(imtq::CC::GET_RAW_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
cmdBuf[0] = imtq::CC::GET_ENG_HK_DATA;
|
||||
if (i2cCmdExecActuate(imtq::CC::GET_ENG_HK_DATA) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
// sif::debug << "measure with torque done" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ReturnValue_t ImtqPollingTask::initialize() { return returnvalue::OK; }
|
||||
|
||||
ReturnValue_t ImtqPollingTask::initializeInterface(CookieIF* cookie) {
|
||||
i2cCookie = dynamic_cast<I2cCookie*>(cookie);
|
||||
if (i2cCookie == nullptr) {
|
||||
sif::error << "ImtqPollingTask::initializeInterface: Invalid I2C cookie" << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
i2cDev = i2cCookie->getDeviceFile().c_str();
|
||||
i2cAddr = i2cCookie->getAddress();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ImtqPollingTask::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
||||
size_t sendLen) {
|
||||
ImtqRequest request(sendData, sendLen);
|
||||
{
|
||||
MutexGuard mg(ipcLock);
|
||||
currentRequest = request.getRequestType();
|
||||
if (currentRequest == imtq::RequestType::ACTUATE) {
|
||||
std::memcpy(dipoles, request.getDipoles(), 6);
|
||||
torqueDuration = request.getTorqueDuration();
|
||||
}
|
||||
specialRequest = request.getSpecialRequest();
|
||||
if (state != InternalState::IDLE) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
state = InternalState::BUSY;
|
||||
}
|
||||
semaphore->release();
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ImtqPollingTask::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; }
|
||||
|
||||
ReturnValue_t ImtqPollingTask::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void ImtqPollingTask::ccToReplyPtrMeasure(ImtqRepliesDefault& replies, imtq::CC::CC cc,
|
||||
uint8_t** replyBuf, size_t& replyLen) {
|
||||
replyLen = imtq::getReplySize(cc);
|
||||
switch (cc) {
|
||||
case (imtq::CC::CC::GET_ENG_HK_DATA): {
|
||||
*replyBuf = replies.engHk;
|
||||
break;
|
||||
}
|
||||
case (imtq::CC::CC::SOFTWARE_RESET): {
|
||||
*replyBuf = replies.swReset;
|
||||
break;
|
||||
}
|
||||
case (imtq::CC::CC::GET_SYSTEM_STATE): {
|
||||
*replyBuf = replies.systemState;
|
||||
break;
|
||||
}
|
||||
case (imtq::CC::CC::START_MTM_MEASUREMENT): {
|
||||
*replyBuf = replies.startMtmMeasurement;
|
||||
break;
|
||||
}
|
||||
case (imtq::CC::CC::GET_RAW_MTM_MEASUREMENT): {
|
||||
*replyBuf = replies.rawMgmMeasurement;
|
||||
break;
|
||||
}
|
||||
case (imtq::CC::CC::GET_CAL_MTM_MEASUREMENT): {
|
||||
*replyBuf = replies.calibMgmMeasurement;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*replyBuf = replies.specialRequestReply;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImtqPollingTask::ccToReplyPtrActuate(ImtqRepliesWithTorque& replies, imtq::CC::CC cc,
|
||||
uint8_t** replyBuf, size_t& replyLen) {
|
||||
replyLen = imtq::getReplySize(cc);
|
||||
switch (cc) {
|
||||
case (imtq::CC::CC::START_ACTUATION_DIPOLE): {
|
||||
*replyBuf = replies.dipoleActuation;
|
||||
break;
|
||||
}
|
||||
case (imtq::CC::CC::GET_ENG_HK_DATA): {
|
||||
*replyBuf = replies.engHk;
|
||||
break;
|
||||
}
|
||||
case (imtq::CC::CC::START_MTM_MEASUREMENT): {
|
||||
*replyBuf = replies.startMtmMeasurement;
|
||||
break;
|
||||
}
|
||||
case (imtq::CC::CC::GET_RAW_MTM_MEASUREMENT): {
|
||||
*replyBuf = replies.rawMgmMeasurement;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*replyBuf = nullptr;
|
||||
replyLen = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
size_t ImtqPollingTask::getExchangeBufLen(imtq::SpecialRequest specialRequest) {
|
||||
size_t baseLen = ImtqRepliesDefault::BASE_LEN;
|
||||
switch (specialRequest) {
|
||||
case (imtq::SpecialRequest::NONE):
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_POS_X):
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_NEG_X):
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_POS_Y):
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_NEG_Y):
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_POS_Z):
|
||||
case (imtq::SpecialRequest::DO_SELF_TEST_NEG_Z): {
|
||||
break;
|
||||
}
|
||||
case (imtq::SpecialRequest::GET_SELF_TEST_RESULT): {
|
||||
baseLen += imtq::replySize::SELF_TEST_RESULTS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return baseLen;
|
||||
}
|
||||
|
||||
void ImtqPollingTask::buildDipoleCommand() {
|
||||
cmdBuf[0] = imtq::CC::CC::START_ACTUATION_DIPOLE;
|
||||
uint8_t* serPtr = cmdBuf.data() + 1;
|
||||
size_t serLen = 0;
|
||||
for (uint8_t idx = 0; idx < 3; idx++) {
|
||||
SerializeAdapter::serialize(&dipoles[idx], &serPtr, &serLen, cmdBuf.size(),
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
}
|
||||
SerializeAdapter::serialize(&torqueDuration, &serPtr, &serLen, cmdBuf.size(),
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
cmdLen = 1 + serLen;
|
||||
}
|
||||
|
||||
ReturnValue_t ImtqPollingTask::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
||||
size_t* size) {
|
||||
imtq::RequestType currentRequest;
|
||||
{
|
||||
MutexGuard mg(ipcLock);
|
||||
currentRequest = this->currentRequest;
|
||||
}
|
||||
|
||||
size_t replyLen = 0;
|
||||
MutexGuard mg(bufLock);
|
||||
if (currentRequest == imtq::RequestType::MEASURE_NO_ACTUATION) {
|
||||
replyLen = getExchangeBufLen(specialRequest);
|
||||
memcpy(exchangeBuf.data(), replyBuf.data(), replyLen);
|
||||
} else {
|
||||
replyLen = ImtqRepliesWithTorque::BASE_LEN;
|
||||
memcpy(exchangeBuf.data(), replyBufActuation.data(), replyLen);
|
||||
}
|
||||
*buffer = exchangeBuf.data();
|
||||
*size = replyLen;
|
||||
return comStatus;
|
||||
}
|
||||
|
||||
void ImtqPollingTask::clearReadFlagsDefault(ImtqRepliesDefault& replies) {
|
||||
replies.calibMgmMeasurement[0] = false;
|
||||
replies.rawMgmMeasurement[0] = false;
|
||||
replies.systemState[0] = false;
|
||||
replies.specialRequestReply[0] = false;
|
||||
replies.engHk[0] = false;
|
||||
}
|
||||
|
||||
ReturnValue_t ImtqPollingTask::i2cCmdExecDefault(imtq::CC::CC cc, uint8_t* replyPtr,
|
||||
size_t replyLen, ReturnValue_t comErrIfFails) {
|
||||
ReturnValue_t res = performI2cFullRequest(replyPtr + 1, replyLen);
|
||||
if (res != returnvalue::OK) {
|
||||
sif::error << "IMTQ: I2C transaction for command 0x" << std::hex << std::setw(2) << cc
|
||||
<< " failed" << std::dec << std::endl;
|
||||
comStatus = comErrIfFails;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (replyPtr[1] != cc) {
|
||||
sif::warning << "IMTQ: Unexpected CC 0x" << std::hex << std::setw(2)
|
||||
<< static_cast<int>(replyPtr[1]) << " for command 0x" << cc << std::dec
|
||||
<< std::endl;
|
||||
comStatus = comErrIfFails;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
replyPtr[0] = true;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void ImtqPollingTask::clearReadFlagsWithTorque(ImtqRepliesWithTorque& replies) {
|
||||
replies.dipoleActuation[0] = false;
|
||||
replies.engHk[0] = false;
|
||||
replies.rawMgmMeasurement[0] = false;
|
||||
replies.startMtmMeasurement[0] = false;
|
||||
}
|
||||
|
||||
ReturnValue_t ImtqPollingTask::performI2cFullRequest(uint8_t* reply, size_t replyLen) {
|
||||
int fd = 0;
|
||||
if (cmdLen == 0 or reply == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
{
|
||||
UnixFileGuard fileHelper(i2cDev, fd, O_RDWR, "ImtqPollingTask::performI2cFullRequest");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return fileHelper.getOpenResult();
|
||||
}
|
||||
if (ioctl(fd, I2C_SLAVE, i2cAddr) < 0) {
|
||||
sif::warning << "Opening IMTQ slave device failed with code " << errno << ": "
|
||||
<< strerror(errno) << std::endl;
|
||||
}
|
||||
|
||||
int written = write(fd, cmdBuf.data(), cmdLen);
|
||||
if (written < 0) {
|
||||
sif::error << "IMTQ: Failed to send with error code " << errno
|
||||
<< ". Error description: " << strerror(errno) << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
} else if (static_cast<size_t>(written) != cmdLen) {
|
||||
sif::error << "IMTQ: Could not write all bytes" << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
#if FSFW_HAL_I2C_WIRETAPPING == 1
|
||||
sif::info << "Sent I2C data to bus " << deviceFile << ":" << std::endl;
|
||||
arrayprinter::print(sendData, sendLen);
|
||||
#endif
|
||||
|
||||
// wait 1 ms like specified in the datasheet. This is the time the IMTQ needs
|
||||
// to prepare a reply.
|
||||
usleep(1000);
|
||||
|
||||
{
|
||||
UnixFileGuard fileHelper(i2cDev, fd, O_RDWR, "ImtqPollingTask::performI2cFullRequest");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return fileHelper.getOpenResult();
|
||||
}
|
||||
if (ioctl(fd, I2C_SLAVE, i2cAddr) < 0) {
|
||||
sif::warning << "Opening IMTQ slave device failed with code " << errno << ": "
|
||||
<< strerror(errno) << std::endl;
|
||||
}
|
||||
MutexGuard mg(bufLock);
|
||||
int readLen = read(fd, reply, replyLen);
|
||||
if (readLen != static_cast<int>(replyLen)) {
|
||||
if (readLen < 0) {
|
||||
sif::warning << "IMTQ: Reading failed with error code " << errno << " | " << strerror(errno)
|
||||
<< std::endl;
|
||||
} else {
|
||||
sif::warning << "IMTQ: Read only" << readLen << " from " << replyLen << " bytes"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reply[0] == 0xff or reply[1] == 0xff) {
|
||||
sif::warning << "IMTQ: No reply available after 1 millisecond";
|
||||
return NO_REPLY_AVAILABLE;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
70
linux/devices/ImtqPollingTask.h
Normal file
70
linux/devices/ImtqPollingTask.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef LINUX_DEVICES_IMTQPOLLINGTASK_H_
|
||||
#define LINUX_DEVICES_IMTQPOLLINGTASK_H_
|
||||
|
||||
#include <fsfw/tasks/SemaphoreIF.h>
|
||||
#include <fsfw_hal/linux/i2c/I2cCookie.h>
|
||||
|
||||
#include "fsfw/devicehandlers/DeviceCommunicationIF.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "mission/devices/devicedefinitions/imtqHelpers.h"
|
||||
|
||||
class ImtqPollingTask : public SystemObject,
|
||||
public ExecutableObjectIF,
|
||||
public DeviceCommunicationIF {
|
||||
public:
|
||||
ImtqPollingTask(object_id_t imtqPollingTask);
|
||||
|
||||
ReturnValue_t performOperation(uint8_t operationCode) override;
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
private:
|
||||
static constexpr ReturnValue_t NO_REPLY_AVAILABLE = returnvalue::makeCode(2, 0);
|
||||
|
||||
enum class InternalState { IDLE, BUSY } state = InternalState::IDLE;
|
||||
imtq::RequestType currentRequest = imtq::RequestType::MEASURE_NO_ACTUATION;
|
||||
|
||||
SemaphoreIF* semaphore;
|
||||
ReturnValue_t comStatus = returnvalue::OK;
|
||||
MutexIF* ipcLock;
|
||||
MutexIF* bufLock;
|
||||
I2cCookie* i2cCookie = nullptr;
|
||||
const char* i2cDev = nullptr;
|
||||
address_t i2cAddr = 0;
|
||||
uint32_t currentIntegrationTimeMs = 10;
|
||||
bool ignoreNextActuateRequest = false;
|
||||
|
||||
imtq::SpecialRequest specialRequest = imtq::SpecialRequest::NONE;
|
||||
int16_t dipoles[3] = {};
|
||||
uint16_t torqueDuration = 0;
|
||||
// uint8_t startActuateRawBuf[3] = {};
|
||||
|
||||
std::array<uint8_t, 32> cmdBuf;
|
||||
std::array<uint8_t, 524> replyBuf;
|
||||
std::array<uint8_t, 524> replyBufActuation;
|
||||
std::array<uint8_t, 524> exchangeBuf;
|
||||
size_t cmdLen = 0;
|
||||
|
||||
// DeviceCommunicationIF overrides
|
||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||
ReturnValue_t getSendSuccess(CookieIF* cookie) override;
|
||||
ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override;
|
||||
ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override;
|
||||
|
||||
void ccToReplyPtrMeasure(ImtqRepliesDefault& replies, imtq::CC::CC cc, uint8_t** replyBuf,
|
||||
size_t& replyLen);
|
||||
void ccToReplyPtrActuate(ImtqRepliesWithTorque& replies, imtq::CC::CC cc, uint8_t** replyBuf,
|
||||
size_t& replyLen);
|
||||
void clearReadFlagsDefault(ImtqRepliesDefault& replies);
|
||||
void clearReadFlagsWithTorque(ImtqRepliesWithTorque& replies);
|
||||
size_t getExchangeBufLen(imtq::SpecialRequest specialRequest);
|
||||
void buildDipoleCommand();
|
||||
void handleMeasureStep();
|
||||
void handleActuateStep();
|
||||
ReturnValue_t i2cCmdExecDefault(imtq::CC::CC cc, uint8_t* replyPtr, size_t replyLen,
|
||||
ReturnValue_t comErrIfFails);
|
||||
ReturnValue_t performI2cFullRequest(uint8_t* reply, size_t replyLen);
|
||||
};
|
||||
|
||||
#endif /* LINUX_DEVICES_IMTQPOLLINGTASK_H_ */
|
@ -162,11 +162,15 @@ ReturnValue_t RwPollingTask::requestReceiveMessage(CookieIF* cookie, size_t requ
|
||||
|
||||
ReturnValue_t RwPollingTask::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) {
|
||||
RwCookie* rwCookie = dynamic_cast<RwCookie*>(cookie);
|
||||
{
|
||||
MutexGuard mg(ipcLock);
|
||||
*buffer = rwCookie->replyBuf.data();
|
||||
*size = rwCookie->replyBuf.size();
|
||||
if (rwCookie == nullptr or rwCookie->bufLock == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
{
|
||||
MutexGuard mg(rwCookie->bufLock);
|
||||
memcpy(rwCookie->exchangeBuf.data(), rwCookie->replyBuf.data(), rwCookie->replyBuf.size());
|
||||
}
|
||||
*buffer = rwCookie->exchangeBuf.data();
|
||||
*size = rwCookie->exchangeBuf.size();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -248,6 +252,7 @@ ReturnValue_t RwPollingTask::readNextReply(RwCookie& rwCookie, uint8_t* replyBuf
|
||||
#endif
|
||||
|
||||
size_t decodedFrameLen = 0;
|
||||
MutexGuard mg(rwCookie.bufLock);
|
||||
|
||||
while (decodedFrameLen < maxReplyLen) {
|
||||
// First byte already read in
|
||||
@ -428,7 +433,12 @@ void RwPollingTask::handleSpecialRequests() {
|
||||
}
|
||||
uint8_t* replyBuf;
|
||||
size_t maxReadLen = idAndIdxToReadBuffer(specialRequestIds[idx], idx, &replyBuf);
|
||||
readNextReply(*rwCookies[idx], replyBuf, maxReadLen);
|
||||
result = readNextReply(*rwCookies[idx], replyBuf, maxReadLen);
|
||||
if (result == returnvalue::OK) {
|
||||
// The first byte is always a flag which shows whether the value was read
|
||||
// properly at least once.
|
||||
replyBuf[0] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,10 +18,14 @@ class RwCookie : public SpiCookie {
|
||||
static constexpr size_t REPLY_BUF_LEN = 524;
|
||||
RwCookie(uint8_t rwIdx, address_t spiAddress, gpioId_t chipSelect, const size_t maxSize,
|
||||
spi::SpiModes spiMode, uint32_t spiSpeed)
|
||||
: SpiCookie(spiAddress, chipSelect, maxSize, spiMode, spiSpeed), rwIdx(rwIdx) {}
|
||||
: SpiCookie(spiAddress, chipSelect, maxSize, spiMode, spiSpeed), rwIdx(rwIdx) {
|
||||
bufLock = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<uint8_t, REPLY_BUF_LEN> replyBuf{};
|
||||
std::array<uint8_t, REPLY_BUF_LEN> exchangeBuf{};
|
||||
MutexIF* bufLock;
|
||||
bool setSpeed = true;
|
||||
int32_t currentRwSpeed = 0;
|
||||
uint16_t currentRampTime = 0;
|
||||
@ -56,6 +60,13 @@ class RwPollingTask : public SystemObject, public ExecutableObjectIF, public Dev
|
||||
static constexpr uint32_t TIMEOUT_MS = 20;
|
||||
static constexpr uint8_t MAX_RETRIES_REPLY = 5;
|
||||
|
||||
// DeviceCommunicationIF overrides
|
||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||
ReturnValue_t getSendSuccess(CookieIF* cookie) override;
|
||||
ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override;
|
||||
ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override;
|
||||
|
||||
ReturnValue_t writeAndReadAllRws(DeviceCommandId_t id);
|
||||
ReturnValue_t writeOneRwCmd(uint8_t rwIdx, int fd);
|
||||
ReturnValue_t readAllRws(DeviceCommandId_t id);
|
||||
@ -64,15 +75,6 @@ class RwPollingTask : public SystemObject, public ExecutableObjectIF, public Dev
|
||||
ReturnValue_t readNextReply(RwCookie& rwCookie, uint8_t* replyBuf, size_t maxReplyLen);
|
||||
void handleSpecialRequests();
|
||||
|
||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||
|
||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||
|
||||
ReturnValue_t getSendSuccess(CookieIF* cookie) override;
|
||||
|
||||
ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override;
|
||||
|
||||
ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override;
|
||||
ReturnValue_t openSpi(int flags, int& fd);
|
||||
ReturnValue_t pullCsLow(gpioId_t gpioId, GpioIF& gpioIF);
|
||||
void prepareSimpleCommand(DeviceCommandId_t id);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 258 translations.
|
||||
* @details
|
||||
* Generated on: 2023-02-20 15:03:46
|
||||
* Generated on: 2023-02-21 11:14:30
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 157 translations.
|
||||
* Generated on: 2023-02-20 15:03:46
|
||||
* Contains 159 translations.
|
||||
* Generated on: 2023-02-21 11:14:30
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@ -37,6 +37,7 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER";
|
||||
const char *RW4_STRING = "RW4";
|
||||
const char *STAR_TRACKER_STRING = "STAR_TRACKER";
|
||||
const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER";
|
||||
const char *IMTQ_POLLING_STRING = "IMTQ_POLLING";
|
||||
const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER";
|
||||
const char *PCDU_HANDLER_STRING = "PCDU_HANDLER";
|
||||
const char *P60DOCK_HANDLER_STRING = "P60DOCK_HANDLER";
|
||||
@ -109,6 +110,7 @@ const char *PUS_SERVICE_5_EVENT_REPORTING_STRING = "PUS_SERVICE_5_EVENT_REPORTIN
|
||||
const char *PUS_SERVICE_8_FUNCTION_MGMT_STRING = "PUS_SERVICE_8_FUNCTION_MGMT";
|
||||
const char *PUS_SERVICE_9_TIME_MGMT_STRING = "PUS_SERVICE_9_TIME_MGMT";
|
||||
const char *PUS_SERVICE_11_TC_SCHEDULER_STRING = "PUS_SERVICE_11_TC_SCHEDULER";
|
||||
const char *PUS_SERVICE_15_TM_STORAGE_STRING = "PUS_SERVICE_15_TM_STORAGE";
|
||||
const char *PUS_SERVICE_17_TEST_STRING = "PUS_SERVICE_17_TEST";
|
||||
const char *PUS_SERVICE_20_PARAMETERS_STRING = "PUS_SERVICE_20_PARAMETERS";
|
||||
const char *PUS_SERVICE_200_MODE_MGMT_STRING = "PUS_SERVICE_200_MODE_MGMT";
|
||||
@ -228,6 +230,8 @@ const char *translateObject(object_id_t object) {
|
||||
return STAR_TRACKER_STRING;
|
||||
case 0x44130045:
|
||||
return GPS_CONTROLLER_STRING;
|
||||
case 0x44140013:
|
||||
return IMTQ_POLLING_STRING;
|
||||
case 0x44140014:
|
||||
return IMTQ_HANDLER_STRING;
|
||||
case 0x442000A1:
|
||||
@ -372,6 +376,8 @@ const char *translateObject(object_id_t object) {
|
||||
return PUS_SERVICE_9_TIME_MGMT_STRING;
|
||||
case 0x53000011:
|
||||
return PUS_SERVICE_11_TC_SCHEDULER_STRING;
|
||||
case 0x53000015:
|
||||
return PUS_SERVICE_15_TM_STORAGE_STRING;
|
||||
case 0x53000017:
|
||||
return PUS_SERVICE_17_TEST_STRING;
|
||||
case 0x53000020:
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||
#include <mission/devices/devicedefinitions/imtqHelpers.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "eive/definitions.h"
|
||||
@ -60,8 +61,8 @@ ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) {
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.2, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.3, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.3, DeviceHandlerIF::GET_READ);
|
||||
#endif
|
||||
// These are actually part of another bus, but this works, so keep it like this for now
|
||||
#if OBSW_ADD_TMP_DEVICES == 1
|
||||
@ -585,98 +586,76 @@ ReturnValue_t pst::pstTcsAndAcs(FixedTimeslotTaskIF *thisSequence, AcsPstCfg cfg
|
||||
if (cfg.scheduleImtq) {
|
||||
// This is the MTM measurement cycle
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
imtq::ComStep::DHB_OP);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
imtq::ComStep::START_MEASURE_SEND);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
imtq::ComStep::START_MEASURE_GET);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_3_PERIOD,
|
||||
imtq::ComStep::READ_MEASURE_SEND);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_3_PERIOD,
|
||||
imtq::ComStep::READ_MEASURE_GET);
|
||||
}
|
||||
|
||||
thisSequence->addSlot(objects::ACS_CONTROLLER, length * config::acs::SCHED_BLOCK_3_PERIOD, 0);
|
||||
thisSequence->addSlot(objects::ACS_CONTROLLER, length * config::acs::SCHED_BLOCK_4_PERIOD, 0);
|
||||
|
||||
if (cfg.scheduleImtq) {
|
||||
// This is the torquing cycle.
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
imtq::ComStep::START_ACTUATE_SEND);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
imtq::ComStep::START_ACTUATE_GET);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_6_PERIOD,
|
||||
imtq::ComStep::READ_ACTUATE_SEND);
|
||||
thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_6_PERIOD,
|
||||
imtq::ComStep::READ_ACTUATE_GET);
|
||||
}
|
||||
|
||||
if (cfg.scheduleRws) {
|
||||
// this is the torquing cycle
|
||||
thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
|
||||
thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
|
||||
thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_4_PERIOD,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
|
||||
thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
|
||||
thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_5_PERIOD,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
|
||||
thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_7_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_7_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_7_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_7_PERIOD,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
|
||||
thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_7_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_7_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_7_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_7_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user