Compare commits
95 Commits
tmtcbridge
...
245886c555
Author | SHA1 | Date | |
---|---|---|---|
245886c555 | |||
f84097543e | |||
511d07c0c7 | |||
cf735143fe | |||
bdfe31dba4 | |||
216f603d62 | |||
174a6aa862 | |||
c2d9370aa1 | |||
893b434728 | |||
6eba84566d | |||
f0415a97b1 | |||
abcf1b29b2 | |||
d373c45d36 | |||
bd208038dd | |||
206af00c8b | |||
2efff4d2c5 | |||
2a0c244468 | |||
e1711f0345 | |||
c327985222 | |||
b45206ccd6 | |||
c8469ca647 | |||
2d6622b8b8 | |||
5f9eb01d94 | |||
3568bdbecf | |||
fcd84b59ae | |||
e3c968096b | |||
c745c0c8b4 | |||
be015b4c66 | |||
dae5e988fd | |||
a6d707a7db | |||
fe41d73895 | |||
70b785984c | |||
9de6c4b3aa | |||
d256ede8c1 | |||
f0b8457ba2 | |||
dac2d210b5 | |||
8b4f73a97b | |||
7fae6cbd6d | |||
d302ba7185 | |||
14a92b3d89 | |||
e4fd424d66 | |||
341a66c265 | |||
b9b076aa4c | |||
d93486a340 | |||
820a7f059c | |||
f4d188c36f | |||
1841f92944 | |||
b279985859 | |||
fa7675897d | |||
3a2393885f | |||
c752b6d143 | |||
b676040c7c | |||
010509efb4 | |||
dfb1633f00 | |||
5f7172e130 | |||
0c6465cd95 | |||
f94987c46d | |||
1809ce359b | |||
8c712441ab | |||
6ce80ea6c5 | |||
f1b0ca7cff | |||
000df85556 | |||
1fffcc2229 | |||
7f907fb9d3 | |||
a419806a05 | |||
134d908f26 | |||
40a9e12416 | |||
f39054edd4 | |||
5adf89b911 | |||
c2e6a22dec | |||
c8e065a713 | |||
3ed49dbae3 | |||
a1567de9e8 | |||
4cf52d5dfe | |||
46230e6c6d | |||
b22d439300 | |||
7e7b3bbbc9 | |||
06dca7608a | |||
6af5274b68 | |||
b1e9dd9e4a | |||
0cc3231ceb | |||
041d1b8795 | |||
2aa4af6974 | |||
75fc7a056d | |||
1b005d706a | |||
e68f54b9bd | |||
296bc56e2a | |||
2b6a33e718 | |||
61fd5d1b62 | |||
046dbe1deb | |||
0303c1a885 | |||
4d2802a470 | |||
819a2bfac4 | |||
096af44e39 | |||
56e8e5a8b3 |
@ -12,15 +12,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Fixes
|
||||
|
||||
- Bugfix in `Service11TelecommandScheduling` which allowed commands
|
||||
time tagged in the past to be inserted.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/738
|
||||
- `CService200ModeManagement`: Various bugfixes which lead to now execution complete being generated
|
||||
on mode announcements, duplicate mode reply generated on announce commands, and the mode read
|
||||
subservice not working properly.
|
||||
- Memory leak fixes for the TCP/IP TMTC bridge.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/737
|
||||
- `Service9TimeManagement`: Fix the time dump at the `SET_TIME` subservice: Include clock timeval
|
||||
seconds instead of uptime.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726
|
||||
- HAL MGM3100 Handler: Use axis specific gain/scaling factors. Previously,
|
||||
only the X scaling factor was used.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/724
|
||||
- Bugfix for RM3100 MGM sensors. Z value was previously calculated
|
||||
with bytes of the X value.
|
||||
- DHB `setNormalDatapoolEntriesInvalid`: The default implementation did not set the validity
|
||||
to false correctly because the `read` and `write` calls were missing.
|
||||
- PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead
|
||||
@ -43,6 +50,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
- `CServiceHealthCommanding`: Add announce all health info implementation
|
||||
PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/122
|
||||
- Empty constructor for `CdsShortTimeStamper` which does not do an object manager registration.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/730
|
||||
- `Service9TimeManagement`: Add `DUMP_TIME` (129) subservice.
|
||||
- `TcpTmTcServer`: Allow setting the `SO_REUSEADDR` and `SO_REUSEPORT`
|
||||
option on the TCP server. CTOR prototype has changed and expects an explicit
|
||||
|
@ -153,12 +153,12 @@ if(FSFW_BUILD_TESTS)
|
||||
"${MSG_PREFIX} Building the FSFW unittests in addition to the static library"
|
||||
)
|
||||
# Check whether the user has already installed Catch2 first
|
||||
find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION})
|
||||
find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION} QUIET)
|
||||
# Not installed, so use FetchContent to download and provide Catch2
|
||||
if(NOT Catch2_FOUND)
|
||||
message(
|
||||
STATUS
|
||||
"${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent"
|
||||
"${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent."
|
||||
)
|
||||
include(FetchContent)
|
||||
|
||||
@ -196,13 +196,13 @@ message(
|
||||
)
|
||||
|
||||
# Check whether the user has already installed ETL first
|
||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} CONFIG QUIET)
|
||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
||||
# Not installed, so use FetchContent to download and provide etl
|
||||
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
||||
message(
|
||||
STATUS
|
||||
"${MSG_PREFIX} No ETL installation was found with find_package. Installing and providing "
|
||||
"etl with FindPackage")
|
||||
"${MSG_PREFIX} ETL installation not found. Downloading ETL with FetchContent."
|
||||
)
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
|
@ -178,16 +178,25 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
|
||||
dp.user.fileSegmentRecvdIndication(segParams);
|
||||
}
|
||||
result = dp.user.vfs.writeToFile(fileOpParams, fileData);
|
||||
if (offset.value() + fileSegmentLen > tp.progress) {
|
||||
tp.progress = offset.value() + fileSegmentLen;
|
||||
}
|
||||
if (result != returnvalue::OK) {
|
||||
// TODO: Proper Error handling
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "File write error" << std::endl;
|
||||
sif::error << "cfdp::DestHandler: VFS file write error with code 0x" << std::hex << std::setw(2)
|
||||
<< result << std::endl;
|
||||
#endif
|
||||
tp.vfsErrorCount++;
|
||||
if (tp.vfsErrorCount < 3) {
|
||||
// TODO: Provide execution step as parameter
|
||||
fp.eventReporter->forwardEvent(events::FILESTORE_ERROR, static_cast<uint8_t>(fsmRes.step),
|
||||
result);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
tp.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
|
||||
tp.vfsErrorCount = 0;
|
||||
}
|
||||
if (offset.value() + fileSegmentLen > tp.progress) {
|
||||
tp.progress = offset.value() + fileSegmentLen;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -271,35 +280,55 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
|
||||
return OK;
|
||||
}
|
||||
ReturnValue_t result = OK;
|
||||
fsmRes.step = TransactionStep::TRANSACTION_START;
|
||||
if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) {
|
||||
fsmRes.state = CfdpStates::BUSY_CLASS_1_NACKED;
|
||||
} else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) {
|
||||
fsmRes.state = CfdpStates::BUSY_CLASS_2_ACKED;
|
||||
}
|
||||
tp.checksumType = info.getChecksumType();
|
||||
tp.closureRequested = info.isClosureRequested();
|
||||
size_t sourceNameSize = 0;
|
||||
|
||||
const uint8_t* sourceNamePtr = info.getSourceFileName().getValue(&sourceNameSize);
|
||||
if (sourceNameSize > tp.sourceName.size()) {
|
||||
// TODO: Warning, event etc.
|
||||
if (sourceNameSize + 1 > tp.sourceName.size()) {
|
||||
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "source filename too large");
|
||||
return FAILED;
|
||||
}
|
||||
std::memcpy(tp.sourceName.data(), sourceNamePtr, sourceNameSize);
|
||||
tp.sourceName[sourceNameSize] = '\0';
|
||||
size_t destNameSize = 0;
|
||||
const uint8_t* destNamePtr = info.getDestFileName().getValue(&destNameSize);
|
||||
if (destNameSize > tp.destName.size()) {
|
||||
// TODO: Warning, event etc.
|
||||
if (destNameSize + 1 > tp.destName.size()) {
|
||||
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "dest filename too large");
|
||||
return FAILED;
|
||||
}
|
||||
std::memcpy(tp.destName.data(), destNamePtr, destNameSize);
|
||||
tp.destName[destNameSize] = '\0';
|
||||
reader.fillConfig(tp.pduConf);
|
||||
tp.pduConf.direction = Direction::TOWARDS_SENDER;
|
||||
tp.transactionId.entityId = tp.pduConf.sourceId;
|
||||
tp.transactionId.seqNum = tp.pduConf.seqNum;
|
||||
if (not dp.remoteCfgTable.getRemoteCfg(tp.pduConf.sourceId, &tp.remoteCfg)) {
|
||||
|
||||
// If both dest name size and source name size are 0, we are dealing with a metadata only PDU,
|
||||
// so there is no need to create a file or truncate an existing file
|
||||
if (destNameSize > 0 and sourceNameSize > 0) {
|
||||
FilesystemParams fparams(tp.destName.data());
|
||||
// handling to allow only specifying target directory. Example:
|
||||
// Source path /test/hello.txt, dest path /tmp -> dest path /tmp/hello.txt
|
||||
if (dp.user.vfs.isDirectory(tp.destName.data())) {
|
||||
result = tryBuildingAbsoluteDestName(destNameSize);
|
||||
if (result != OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (dp.user.vfs.fileExists(fparams)) {
|
||||
result = dp.user.vfs.truncateFile(fparams);
|
||||
if (result != returnvalue::OK) {
|
||||
fileErrorHandler(events::FILESTORE_ERROR, result, "file truncation error");
|
||||
return FAILED;
|
||||
// TODO: Relevant for filestore rejection error?
|
||||
}
|
||||
} else {
|
||||
result = dp.user.vfs.createFile(fparams);
|
||||
if (result != OK) {
|
||||
fileErrorHandler(events::FILESTORE_ERROR, result, "file creation error");
|
||||
return FAILED;
|
||||
// TODO: Relevant for filestore rejection error?
|
||||
}
|
||||
}
|
||||
}
|
||||
EntityId sourceId;
|
||||
reader.getSourceId(sourceId);
|
||||
if (not dp.remoteCfgTable.getRemoteCfg(sourceId, &tp.remoteCfg)) {
|
||||
// TODO: Warning, event etc.
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "cfdp::DestHandler" << __func__
|
||||
@ -308,22 +337,18 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
|
||||
#endif
|
||||
return FAILED;
|
||||
}
|
||||
// If both dest name size and source name size are 0, we are dealing with a metadata only PDU,
|
||||
// so there is no need to create a file or truncate an existing file
|
||||
if (destNameSize > 0 and sourceNameSize > 0) {
|
||||
FilesystemParams fparams(tp.destName.data());
|
||||
// TODO: Filesystem errors?
|
||||
if (dp.user.vfs.fileExists(fparams)) {
|
||||
dp.user.vfs.truncateFile(fparams);
|
||||
} else {
|
||||
result = dp.user.vfs.createFile(fparams);
|
||||
if (result != OK) {
|
||||
// TODO: Handle FS error. This is probably a case for the filestore rejection mechanism of
|
||||
// CFDP.
|
||||
// In any case, it does not really make sense to continue here
|
||||
}
|
||||
}
|
||||
fsmRes.step = TransactionStep::TRANSACTION_START;
|
||||
if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) {
|
||||
fsmRes.state = CfdpStates::BUSY_CLASS_1_NACKED;
|
||||
} else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) {
|
||||
fsmRes.state = CfdpStates::BUSY_CLASS_2_ACKED;
|
||||
}
|
||||
tp.checksumType = info.getChecksumType();
|
||||
tp.closureRequested = info.isClosureRequested();
|
||||
reader.fillConfig(tp.pduConf);
|
||||
tp.pduConf.direction = Direction::TOWARDS_SENDER;
|
||||
tp.transactionId.entityId = tp.pduConf.sourceId;
|
||||
tp.transactionId.seqNum = tp.pduConf.seqNum;
|
||||
fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS;
|
||||
MetadataRecvdParams params(tp.transactionId, tp.pduConf.sourceId);
|
||||
params.fileSize = tp.fileSize.getSize();
|
||||
@ -362,6 +387,37 @@ ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
||||
return OK;
|
||||
}
|
||||
|
||||
ReturnValue_t cfdp::DestHandler::tryBuildingAbsoluteDestName(size_t destNameSize) {
|
||||
char baseNameBuf[tp.destName.size()]{};
|
||||
FilesystemParams fparamsSrc(tp.sourceName.data());
|
||||
size_t baseNameLen = 0;
|
||||
ReturnValue_t result =
|
||||
dp.user.vfs.getBaseFilename(fparamsSrc, baseNameBuf, sizeof(baseNameBuf), baseNameLen);
|
||||
if (result != returnvalue::OK or baseNameLen == 0) {
|
||||
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "error retrieving source base name");
|
||||
return FAILED;
|
||||
}
|
||||
// Destination name + slash + base name + null termination
|
||||
if (destNameSize + 1 + baseNameLen + 1 > tp.destName.size()) {
|
||||
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0,
|
||||
"dest filename too large after adding source base name");
|
||||
return FAILED;
|
||||
}
|
||||
tp.destName[destNameSize++] = '/';
|
||||
std::memcpy(tp.destName.data() + destNameSize, baseNameBuf, baseNameLen);
|
||||
destNameSize += baseNameLen;
|
||||
tp.destName[destNameSize++] = '\0';
|
||||
return OK;
|
||||
}
|
||||
|
||||
void cfdp::DestHandler::fileErrorHandler(Event event, ReturnValue_t result, const char* info) {
|
||||
fp.eventReporter->forwardEvent(events::FILENAME_TOO_LARGE_ERROR,
|
||||
static_cast<uint8_t>(fsmRes.step), result);
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "cfdp::DestHandler: " << info << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cfdp::DestHandler::finish() {
|
||||
tp.reset();
|
||||
dp.packetListRef.clear();
|
||||
|
@ -84,7 +84,7 @@ enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN };
|
||||
|
||||
class DestHandler {
|
||||
public:
|
||||
enum class TransactionStep {
|
||||
enum class TransactionStep : uint8_t {
|
||||
IDLE = 0,
|
||||
TRANSACTION_START = 1,
|
||||
RECEIVING_FILE_DATA_PDUS = 2,
|
||||
@ -157,11 +157,13 @@ class DestHandler {
|
||||
progress = 0;
|
||||
remoteCfg = nullptr;
|
||||
closureRequested = false;
|
||||
vfsErrorCount = 0;
|
||||
checksumType = ChecksumType::NULL_CHECKSUM;
|
||||
}
|
||||
|
||||
ChecksumType checksumType = ChecksumType::NULL_CHECKSUM;
|
||||
bool closureRequested = false;
|
||||
uint16_t vfsErrorCount = 0;
|
||||
std::vector<char> sourceName;
|
||||
std::vector<char> destName;
|
||||
cfdp::FileSize fileSize;
|
||||
@ -189,9 +191,11 @@ class DestHandler {
|
||||
ReturnValue_t handleMetadataParseError(ReturnValue_t result, const uint8_t* rawData,
|
||||
size_t maxSize);
|
||||
ReturnValue_t handleTransferCompletion();
|
||||
ReturnValue_t tryBuildingAbsoluteDestName(size_t destNameSize);
|
||||
ReturnValue_t sendFinishedPdu();
|
||||
ReturnValue_t noticeOfCompletion();
|
||||
ReturnValue_t checksumVerification();
|
||||
void fileErrorHandler(Event event, ReturnValue_t result, const char* info);
|
||||
const FsmResult& updateFsmRes(uint8_t errors);
|
||||
void checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx);
|
||||
void finish();
|
||||
|
@ -12,6 +12,9 @@ namespace events {
|
||||
static constexpr Event STORE_ERROR = event::makeEvent(SSID, 0, severity::LOW);
|
||||
static constexpr Event MSG_QUEUE_ERROR = event::makeEvent(SSID, 1, severity::LOW);
|
||||
static constexpr Event SERIALIZATION_ERROR = event::makeEvent(SSID, 2, severity::LOW);
|
||||
static constexpr Event FILESTORE_ERROR = event::makeEvent(SSID, 3, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name
|
||||
static constexpr Event FILENAME_TOO_LARGE_ERROR = event::makeEvent(SSID, 4, severity::LOW);
|
||||
|
||||
} // namespace events
|
||||
|
||||
|
@ -58,12 +58,7 @@ void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
||||
this->hkDestination = hkDestination;
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setThermalStateRequestPoolIds(lp_id_t thermalStatePoolId,
|
||||
lp_id_t heaterRequestPoolId,
|
||||
uint32_t thermalSetId) {
|
||||
thermalSet =
|
||||
new DeviceHandlerThermalSet(this, thermalSetId, thermalStatePoolId, heaterRequestPoolId);
|
||||
}
|
||||
void DeviceHandlerBase::enableThermalModule(ThermalStateCfg cfg) { this->thermalStateCfg = cfg; }
|
||||
|
||||
DeviceHandlerBase::~DeviceHandlerBase() {
|
||||
if (comCookie != nullptr) {
|
||||
@ -227,12 +222,11 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
fillCommandAndReplyMap();
|
||||
|
||||
if (thermalSet != nullptr) {
|
||||
PoolReadGuard pg(thermalSet);
|
||||
// Set temperature target state to NON_OP.
|
||||
result = thermalSet->read();
|
||||
if (result == returnvalue::OK) {
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
||||
thermalSet->heaterRequest.setValid(true);
|
||||
thermalSet->commit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -382,7 +376,7 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
}
|
||||
ReturnValue_t switchState = getStateOfSwitches();
|
||||
if ((switchState == PowerSwitchIF::SWITCH_OFF) || (switchState == NO_SWITCH)) {
|
||||
setMode(_MODE_SWITCH_IS_OFF);
|
||||
setMode(MODE_OFF, SUBMODE_NONE);
|
||||
}
|
||||
} break;
|
||||
case MODE_OFF:
|
||||
@ -395,9 +389,6 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
case MODE_NORMAL:
|
||||
case MODE_ERROR_ON:
|
||||
break;
|
||||
case _MODE_SWITCH_IS_OFF:
|
||||
setMode(MODE_OFF, SUBMODE_NONE);
|
||||
break;
|
||||
default:
|
||||
triggerEvent(OBJECT_IN_INVALID_MODE, mode, submode);
|
||||
setMode(_MODE_POWER_DOWN, 0);
|
||||
@ -594,12 +585,12 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
Clock::getUptime(&timeoutStart);
|
||||
|
||||
if (mode == MODE_OFF and thermalSet != nullptr) {
|
||||
ReturnValue_t result = thermalSet->read();
|
||||
if (result == returnvalue::OK) {
|
||||
PoolReadGuard pg(thermalSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if (thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) {
|
||||
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
||||
}
|
||||
thermalSet->heaterRequest.commit(PoolVariableIF::VALID);
|
||||
thermalSet->heaterRequest.setValid(true);
|
||||
}
|
||||
}
|
||||
/* TODO: This will probably be done by the LocalDataPoolManager now */
|
||||
@ -1088,8 +1079,8 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, Submode_
|
||||
// Do not check thermal state for MODE_RAW
|
||||
if ((mode == MODE_OFF) and ((commandedMode == MODE_ON) or (commandedMode == MODE_NORMAL)) and
|
||||
(thermalSet != nullptr)) {
|
||||
ReturnValue_t result = thermalSet->read();
|
||||
if (result == returnvalue::OK) {
|
||||
PoolReadGuard pg(thermalSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if ((thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) and
|
||||
(not ThermalComponentIF::isOperational(thermalSet->thermalState.value))) {
|
||||
triggerEvent(ThermalComponentIF::TEMP_NOT_IN_OP_RANGE, thermalSet->thermalState.value);
|
||||
@ -1150,11 +1141,10 @@ void DeviceHandlerBase::handleTransitionToOnMode(Mode_t commandedMode, Submode_t
|
||||
childTransitionDelay = getTransitionDelayMs(_MODE_START_UP, MODE_ON);
|
||||
triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode);
|
||||
if (thermalSet != nullptr) {
|
||||
ReturnValue_t result = thermalSet->read();
|
||||
if (result == returnvalue::OK) {
|
||||
PoolReadGuard pg(thermalSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if (thermalSet->heaterRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) {
|
||||
thermalSet->heaterRequest = ThermalComponentIF::STATE_REQUEST_OPERATIONAL;
|
||||
thermalSet->commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1477,11 +1467,11 @@ void DeviceHandlerBase::performOperationHook() {}
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) {
|
||||
if (thermalSet != nullptr) {
|
||||
localDataPoolMap.emplace(thermalSet->thermalStatePoolId,
|
||||
new PoolEntry<DeviceHandlerIF::dh_thermal_state_t>);
|
||||
localDataPoolMap.emplace(thermalSet->heaterRequestPoolId,
|
||||
new PoolEntry<DeviceHandlerIF::dh_heater_request_t>);
|
||||
if (thermalStateCfg.has_value()) {
|
||||
localDataPoolMap.emplace(thermalStateCfg.value().thermalStatePoolId,
|
||||
new PoolEntry<DeviceHandlerIF::dh_thermal_state_t>());
|
||||
localDataPoolMap.emplace(thermalStateCfg.value().thermalRequestPoolId,
|
||||
new PoolEntry<DeviceHandlerIF::dh_heater_request_t>());
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
@ -1494,6 +1484,10 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
||||
}
|
||||
this->poolManager.initializeAfterTaskCreation();
|
||||
|
||||
if (thermalStateCfg.has_value()) {
|
||||
ThermalStateCfg& cfg = thermalStateCfg.value();
|
||||
thermalSet = new DeviceHandlerThermalSet(this, cfg);
|
||||
}
|
||||
if (setStartupImmediately) {
|
||||
startTransition(MODE_ON, getInitialSubmode());
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
|
||||
#include "DeviceCommunicationIF.h"
|
||||
#include "DeviceHandlerFailureIsolation.h"
|
||||
@ -149,11 +150,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
//! has been commanded on and the handler waits for it to be on.
|
||||
//! When the switch is on, the mode changes to @c _MODE_TO_ON.
|
||||
static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4;
|
||||
//! This is a transitional state which can not be commanded. The switch has
|
||||
//! been commanded off and is off now. This state is only to do an RMAP
|
||||
//! cycle once more where the doSendRead() function will set the mode to
|
||||
//! MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board.
|
||||
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5;
|
||||
|
||||
void setHkDestination(object_id_t hkDestination);
|
||||
|
||||
@ -163,13 +159,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* The device handler will then take care of creating local pool entries
|
||||
* for the device thermal state and device heating request.
|
||||
* Custom local pool IDs can be assigned as well.
|
||||
* @param thermalStatePoolId
|
||||
* @param thermalRequestPoolId
|
||||
*/
|
||||
void setThermalStateRequestPoolIds(
|
||||
lp_id_t thermalStatePoolId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID,
|
||||
lp_id_t thermalRequestPoolId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID,
|
||||
uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID);
|
||||
void enableThermalModule(ThermalStateCfg cfg);
|
||||
|
||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||
@ -931,6 +922,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
//! Object which may be the root cause of an identified fault.
|
||||
static object_id_t defaultFdirParentId;
|
||||
|
||||
std::optional<ThermalStateCfg> thermalStateCfg;
|
||||
|
||||
/**
|
||||
* @brief Send a reply to a received device handler command.
|
||||
*
|
||||
|
@ -136,4 +136,10 @@ class DeviceHandlerIF {
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
};
|
||||
|
||||
struct ThermalStateCfg {
|
||||
lp_id_t thermalStatePoolId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID;
|
||||
lp_id_t thermalRequestPoolId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID;
|
||||
uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID;
|
||||
};
|
||||
|
||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_ */
|
||||
|
@ -7,27 +7,21 @@
|
||||
|
||||
class DeviceHandlerThermalSet : public StaticLocalDataSet<2> {
|
||||
public:
|
||||
DeviceHandlerThermalSet(
|
||||
HasLocalDataPoolIF* hkOwner, uint32_t setId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID,
|
||||
lp_id_t thermalStateId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID,
|
||||
lp_id_t heaterRequestId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID)
|
||||
: DeviceHandlerThermalSet(hkOwner->getObjectId(), setId, thermalStateId, heaterRequestId) {}
|
||||
DeviceHandlerThermalSet(HasLocalDataPoolIF* hkOwner, ThermalStateCfg cfg)
|
||||
: DeviceHandlerThermalSet(hkOwner->getObjectId(), cfg) {}
|
||||
|
||||
DeviceHandlerThermalSet(
|
||||
object_id_t deviceHandler, uint32_t setId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID,
|
||||
lp_id_t thermalStateId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID,
|
||||
lp_id_t thermalStateRequestId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID)
|
||||
: StaticLocalDataSet(sid_t(deviceHandler, setId)),
|
||||
thermalStatePoolId(thermalStateId),
|
||||
heaterRequestPoolId(thermalStateRequestId) {}
|
||||
DeviceHandlerThermalSet(object_id_t deviceHandler, ThermalStateCfg cfg)
|
||||
: StaticLocalDataSet(sid_t(deviceHandler, cfg.thermalSetId)),
|
||||
thermalStatePoolId(cfg.thermalStatePoolId),
|
||||
heaterRequestPoolId(cfg.thermalRequestPoolId) {}
|
||||
|
||||
const lp_id_t thermalStatePoolId;
|
||||
const lp_id_t heaterRequestPoolId;
|
||||
|
||||
lp_var_t<DeviceHandlerIF::dh_thermal_state_t> thermalState =
|
||||
lp_var_t<DeviceHandlerIF::dh_thermal_state_t>(thermalStatePoolId, sid.objectId, this);
|
||||
lp_var_t<DeviceHandlerIF::dh_thermal_state_t>(sid.objectId, thermalStatePoolId, this);
|
||||
lp_var_t<DeviceHandlerIF::dh_heater_request_t> heaterRequest =
|
||||
lp_var_t<DeviceHandlerIF::dh_heater_request_t>(heaterRequestPoolId, sid.objectId, this);
|
||||
lp_var_t<DeviceHandlerIF::dh_heater_request_t>(sid.objectId, heaterRequestPoolId, this);
|
||||
};
|
||||
|
||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERTHERMALSET_H_ */
|
||||
|
@ -74,6 +74,12 @@ class HasFileSystemIF {
|
||||
return MessageQueueIF::NO_QUEUE;
|
||||
}
|
||||
|
||||
// Get the base filename without the full directory path
|
||||
virtual ReturnValue_t getBaseFilename(FilesystemParams params, char* nameBuf, size_t maxLen,
|
||||
size_t& baseNameLen) = 0;
|
||||
|
||||
virtual bool isDirectory(const char* path) = 0;
|
||||
|
||||
virtual bool fileExists(FilesystemParams params) = 0;
|
||||
|
||||
/**
|
||||
|
@ -7,14 +7,17 @@
|
||||
class MutexGuard {
|
||||
public:
|
||||
MutexGuard(MutexIF* mutex, MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::BLOCKING,
|
||||
uint32_t timeoutMs = 0)
|
||||
uint32_t timeoutMs = 0, const char* context = nullptr)
|
||||
: internalMutex(mutex) {
|
||||
if (context == nullptr) {
|
||||
context = "unknown";
|
||||
}
|
||||
if (mutex == nullptr) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "MutexGuard: Passed mutex is invalid!" << std::endl;
|
||||
sif::error << "MutexGuard::" << context << ": Passed mutex is invalid!" << std::endl;
|
||||
#else
|
||||
sif::printError("MutexGuard: Passed mutex is invalid!\n");
|
||||
sif::printError("MutexGuard::%s: Passed mutex is invalid!\n", context);
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return;
|
||||
|
@ -15,6 +15,7 @@ enum framework_objects : object_id_t {
|
||||
PUS_SERVICE_8_FUNCTION_MGMT = 0x53000008,
|
||||
PUS_SERVICE_9_TIME_MGMT = 0x53000009,
|
||||
PUS_SERVICE_11_TC_SCHEDULER = 0x53000011,
|
||||
PUS_SERVICE_15_TM_STORAGE = 0x53000015,
|
||||
PUS_SERVICE_17_TEST = 0x53000017,
|
||||
PUS_SERVICE_20_PARAMETERS = 0x53000020,
|
||||
PUS_SERVICE_200_MODE_MGMT = 0x53000200,
|
||||
|
@ -41,6 +41,7 @@ int TcpIpBase::closeSocket(socket_t socket) {
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
return close(socket);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
int TcpIpBase::getLastSocketError() {
|
||||
@ -49,4 +50,5 @@ int TcpIpBase::getLastSocketError() {
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
return errno;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -126,10 +126,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) {
|
||||
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL);
|
||||
}
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
|
||||
sif::debug << "TmTcUdpBridge::sendTm: " << bytesSent
|
||||
<< " bytes were"
|
||||
" sent."
|
||||
<< std::endl;
|
||||
sif::debug << "TmTcUdpBridge::sendTm: " << bytesSent << " bytes were sent" << std::endl;
|
||||
#endif
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ ReturnValue_t CService200ModeCommanding::isValidSubservice(uint8_t subservice) {
|
||||
switch (subservice) {
|
||||
case (Subservice::COMMAND_MODE_COMMAND):
|
||||
case (Subservice::COMMAND_MODE_READ):
|
||||
case (Subservice::COMMAND_MODE_ANNCOUNCE):
|
||||
case (Subservice::COMMAND_MODE_ANNOUNCE):
|
||||
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
|
||||
return returnvalue::OK;
|
||||
default:
|
||||
@ -54,6 +54,7 @@ ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue(
|
||||
ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
|
||||
const uint8_t *tcData, size_t tcDataLen,
|
||||
uint32_t *state, object_id_t objectId) {
|
||||
bool recursive = false;
|
||||
switch (subservice) {
|
||||
case (Subservice::COMMAND_MODE_COMMAND): {
|
||||
ModePacket modeCommandPacket;
|
||||
@ -67,22 +68,17 @@ ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message,
|
||||
modeCommandPacket.getMode(), modeCommandPacket.getSubmode());
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (Subservice::COMMAND_MODE_ANNCOUNCE):
|
||||
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY): {
|
||||
bool recursive = true;
|
||||
if (subservice == Subservice::COMMAND_MODE_ANNCOUNCE) {
|
||||
recursive = false;
|
||||
}
|
||||
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
|
||||
recursive = true;
|
||||
[[fallthrough]];
|
||||
case (Subservice::COMMAND_MODE_ANNOUNCE):
|
||||
ModeMessage::setModeAnnounceMessage(*message, recursive);
|
||||
return EXECUTION_COMPLETE;
|
||||
}
|
||||
case (Subservice::COMMAND_MODE_READ): {
|
||||
case (Subservice::COMMAND_MODE_READ):
|
||||
ModeMessage::setModeReadMessage(*message);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
default: {
|
||||
default:
|
||||
return CommandingServiceBase::INVALID_SUBSERVICE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ class CService200ModeCommanding : public CommandingServiceBase {
|
||||
COMMAND_MODE_READ = 3,
|
||||
//!< [EXPORT] : [COMMAND] Trigger an ModeInfo Event.
|
||||
//! This command does NOT have a reply
|
||||
COMMAND_MODE_ANNCOUNCE = 4,
|
||||
COMMAND_MODE_ANNOUNCE = 4,
|
||||
//!< [EXPORT] : [COMMAND] Trigger a ModeInfo Event and to send this
|
||||
//! command to every child. This command does NOT have a reply.
|
||||
COMMAND_MODE_ANNOUNCE_RECURSIVELY = 5,
|
||||
|
@ -79,7 +79,7 @@ ReturnValue_t CServiceHealthCommanding::prepareCommand(CommandMessage *message,
|
||||
}
|
||||
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
|
||||
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE);
|
||||
break;
|
||||
return CommandingServiceBase::EXECUTION_COMPLETE;
|
||||
}
|
||||
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
|
||||
ReturnValue_t result = iterateHealthTable(true);
|
||||
|
@ -160,7 +160,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
|
||||
// (See requirement for Time margin)
|
||||
timeval tNow = {};
|
||||
Clock::getClock_timeval(&tNow);
|
||||
if (timestamp - tNow.tv_sec <= RELEASE_TIME_MARGIN_SECONDS) {
|
||||
if (timestamp < static_cast<uint32_t>(tNow.tv_sec + RELEASE_TIME_MARGIN_SECONDS)) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Service11TelecommandScheduling::doInsertActivity: Release time too close to "
|
||||
"current time"
|
||||
|
@ -10,7 +10,7 @@ PoolManager::PoolManager(object_id_t setObjectId, const LocalPoolConfig& localPo
|
||||
PoolManager::~PoolManager() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||
|
||||
ReturnValue_t PoolManager::reserveSpace(const size_t size, store_address_t* address) {
|
||||
MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeoutMs);
|
||||
MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeoutMs, LOCK_CTX);
|
||||
ReturnValue_t status = LocalPool::reserveSpace(size, address);
|
||||
return status;
|
||||
}
|
||||
@ -22,12 +22,12 @@ ReturnValue_t PoolManager::deleteData(store_address_t storeId) {
|
||||
<< storeId.poolIndex << ". id is " << storeId.packetIndex << std::endl;
|
||||
#endif
|
||||
#endif
|
||||
MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeoutMs);
|
||||
MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeoutMs, LOCK_CTX);
|
||||
return LocalPool::deleteData(storeId);
|
||||
}
|
||||
|
||||
ReturnValue_t PoolManager::deleteData(uint8_t* buffer, size_t size, store_address_t* storeId) {
|
||||
MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, 20);
|
||||
MutexGuard mutexHelper(mutex, MutexIF::TimeoutType::WAITING, mutexTimeoutMs, LOCK_CTX);
|
||||
ReturnValue_t status = LocalPool::deleteData(buffer, size, storeId);
|
||||
return status;
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ class PoolManager : public LocalPool {
|
||||
protected:
|
||||
//! Default mutex timeout value to prevent permanent blocking.
|
||||
uint32_t mutexTimeoutMs = 20;
|
||||
static constexpr char LOCK_CTX[] = "PoolManager";
|
||||
|
||||
ReturnValue_t reserveSpace(size_t size, store_address_t* address) override;
|
||||
|
||||
|
@ -117,6 +117,20 @@ ReturnValue_t SubsystemBase::updateChildMode(MessageQueueId_t queue, Mode_t mode
|
||||
return CHILD_NOT_FOUND;
|
||||
}
|
||||
|
||||
ReturnValue_t SubsystemBase::updateChildModeByObjId(object_id_t objectId, Mode_t mode,
|
||||
Submode_t submode) {
|
||||
std::map<object_id_t, ChildInfo>::iterator iter;
|
||||
|
||||
for (iter = childrenMap.begin(); iter != childrenMap.end(); iter++) {
|
||||
if (iter->first == objectId) {
|
||||
iter->second.mode = mode;
|
||||
iter->second.submode = submode;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
}
|
||||
return CHILD_NOT_FOUND;
|
||||
}
|
||||
|
||||
ReturnValue_t SubsystemBase::updateChildChangedHealth(MessageQueueId_t queue, bool changedHealth) {
|
||||
for (auto iter = childrenMap.begin(); iter != childrenMap.end(); iter++) {
|
||||
if (iter->second.commandQueue == queue) {
|
||||
|
@ -115,6 +115,7 @@ class SubsystemBase : public SystemObject,
|
||||
Submode_t targetSubmode = SUBMODE_NONE);
|
||||
|
||||
ReturnValue_t updateChildMode(MessageQueueId_t queue, Mode_t mode, Submode_t submode);
|
||||
ReturnValue_t updateChildModeByObjId(object_id_t objectId, Mode_t mode, Submode_t submode);
|
||||
|
||||
ReturnValue_t updateChildChangedHealth(MessageQueueId_t queue, bool changedHealth = true);
|
||||
|
||||
|
@ -15,10 +15,10 @@ ReturnValue_t FixedTimeslotTaskBase::addSlot(object_id_t execId, ExecutableObjec
|
||||
uint32_t slotTimeMs, int8_t executionStep) {
|
||||
if (execObj == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Component 0x" << std::hex << std::setw(8) << std::setfill('0') << execObj
|
||||
sif::error << "Component 0x" << std::hex << std::setw(8) << std::setfill('0') << execId
|
||||
<< std::setfill(' ') << " not found, not adding it to PST" << std::dec << std::endl;
|
||||
#else
|
||||
sif::printError("Component 0x%08x not found, not adding it to PST\n");
|
||||
sif::printError("Component 0x%08x not found, not adding it to PST\n", execId);
|
||||
#endif
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
@ -246,6 +246,20 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t*
|
||||
return UNSUPPORTED_TIME_FORMAT;
|
||||
}
|
||||
|
||||
ReturnValue_t CCSDSTime::convertToAsciiWithSecs(int8_t* to, const Clock::TimeOfDay_t* from,
|
||||
uint8_t length) {
|
||||
if (from == nullptr or to == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
int count = snprintf(reinterpret_cast<char*>(to), length,
|
||||
"%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%2" SCNu32,
|
||||
from->year, from->month, from->day, from->hour, from->minute, from->second);
|
||||
if (count >= length) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CCSDSTime::checkCcs(const uint8_t* time, uint8_t length) {
|
||||
const Ccs_mseconds* time_struct = reinterpret_cast<const Ccs_mseconds*>(time);
|
||||
|
||||
|
@ -207,7 +207,8 @@ class CCSDSTime {
|
||||
|
||||
static ReturnValue_t convertFromASCII(Clock::TimeOfDay_t *to, uint8_t const *from,
|
||||
uint8_t length);
|
||||
|
||||
static ReturnValue_t convertToAsciiWithSecs(int8_t *to, const Clock::TimeOfDay_t *from,
|
||||
uint8_t length);
|
||||
static uint32_t subsecondsToMicroseconds(uint16_t subseconds);
|
||||
|
||||
private:
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include "fsfw/timemanager/Clock.h"
|
||||
|
||||
CdsShortTimeStamper::CdsShortTimeStamper() : SystemObject(0, false) {}
|
||||
|
||||
CdsShortTimeStamper::CdsShortTimeStamper(object_id_t objectId) : SystemObject(objectId) {}
|
||||
|
||||
ReturnValue_t CdsShortTimeStamper::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
|
@ -18,6 +18,7 @@
|
||||
class CdsShortTimeStamper : public TimeWriterIF, public TimeReaderIF, public SystemObject {
|
||||
public:
|
||||
static constexpr size_t TIMESTAMP_LEN = 7;
|
||||
CdsShortTimeStamper();
|
||||
/**
|
||||
* @brief Default constructor which also registers the time stamper as a
|
||||
* system object so it can be found with the #objectManager.
|
||||
|
@ -9,7 +9,7 @@
|
||||
Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode)
|
||||
: displayOnDestruction(displayOnDestruction), displayMode(displayMode) {
|
||||
// Measures start time on initialization.
|
||||
Clock::getUptime(&startTime);
|
||||
Clock::getClock_timeval(&startTime);
|
||||
}
|
||||
|
||||
void Stopwatch::start() { Clock::getUptime(&startTime); }
|
||||
@ -63,6 +63,6 @@ StopwatchDisplayMode Stopwatch::getDisplayMode() const { return displayMode; }
|
||||
|
||||
void Stopwatch::stopInternal() {
|
||||
timeval endTime;
|
||||
Clock::getUptime(&endTime);
|
||||
Clock::getClock_timeval(&endTime);
|
||||
elapsedTime = endTime - startTime;
|
||||
}
|
||||
|
@ -6,47 +6,12 @@
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "tmStorageConf.h"
|
||||
|
||||
class TmPacketMinimal;
|
||||
class SpacePacketBase;
|
||||
class PusTmReader;
|
||||
class SpacePacketReader;
|
||||
class TmStoreBackendIF;
|
||||
|
||||
class TmStoreFrontendIF {
|
||||
public:
|
||||
virtual TmStoreBackendIF* getBackend() const = 0;
|
||||
|
||||
/**
|
||||
* What do I need to implement here?
|
||||
* This is propably used by PUS Service 15 so we should propably check for messages..
|
||||
* Provide base implementation?
|
||||
* @param opCode
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t performOperation(uint8_t opCode) = 0;
|
||||
/**
|
||||
* Callback from the back-end to indicate a certain packet was received.
|
||||
* front-end takes care of discarding/downloading the packet.
|
||||
* @param packet Pointer to the newly received Space Packet.
|
||||
* @param address Start address of the packet found
|
||||
* @param isLastPacket Indicates if no more packets can be fetched.
|
||||
* @return If more packets shall be fetched, returnvalue::OK must be returned.
|
||||
* Any other code stops fetching packets.
|
||||
*/
|
||||
virtual ReturnValue_t packetRetrieved(TmPacketMinimal* packet, uint32_t address) = 0;
|
||||
virtual void noMorePacketsInStore() = 0;
|
||||
virtual void handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1 = 0,
|
||||
uint32_t parameter2 = 0) = 0;
|
||||
/**
|
||||
* To get the queue where commands shall be sent.
|
||||
* @return Id of command queue.
|
||||
*/
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
virtual ReturnValue_t fetchPackets(ApidSsc start, ApidSsc end) = 0;
|
||||
virtual ReturnValue_t deletePackets(ApidSsc upTo) = 0;
|
||||
virtual ReturnValue_t checkPacket(SpacePacketBase* tmPacket) = 0;
|
||||
virtual bool isEnabled() const = 0;
|
||||
virtual void setEnabled(bool enabled) = 0;
|
||||
virtual void resetDownlinkedPacketCount() = 0;
|
||||
virtual ReturnValue_t setDumpTarget(object_id_t dumpTarget) = 0;
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::TM_STORE_FRONTEND_IF;
|
||||
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t LAST_PACKET_FOUND = MAKE_RETURN_CODE(2);
|
||||
@ -57,7 +22,38 @@ class TmStoreFrontendIF {
|
||||
static const ReturnValue_t ALL_DELETED = MAKE_RETURN_CODE(7);
|
||||
static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(8);
|
||||
static const ReturnValue_t NOT_READY = MAKE_RETURN_CODE(9);
|
||||
virtual ~TmStoreFrontendIF() {}
|
||||
|
||||
virtual ~TmStoreFrontendIF() = default;
|
||||
|
||||
/**
|
||||
* To get the queue where commands shall be sent.
|
||||
* @return Id of command queue.
|
||||
*/
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
||||
virtual TmStoreBackendIF* getBackend() const = 0;
|
||||
|
||||
/**
|
||||
* Callback from the back-end to indicate a certain packet was received.
|
||||
* front-end takes care of discarding/downloading the packet.
|
||||
* @param packet Pointer to the newly received Space Packet.
|
||||
* @param address Start address of the packet found
|
||||
* @param isLastPacket Indicates if no more packets can be fetched.
|
||||
* @return If more packets shall be fetched, returnvalue::OK must be returned.
|
||||
* Any other code stops fetching packets.
|
||||
*/
|
||||
virtual ReturnValue_t packetRetrieved(PusTmReader* packet, uint32_t address) = 0;
|
||||
virtual void noMorePacketsInStore() = 0;
|
||||
virtual void handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1 = 0,
|
||||
uint32_t parameter2 = 0) = 0;
|
||||
|
||||
virtual ReturnValue_t fetchPackets(ApidSsc start, ApidSsc end) = 0;
|
||||
virtual ReturnValue_t deletePackets(ApidSsc upTo) = 0;
|
||||
virtual ReturnValue_t checkPacket(SpacePacketReader* tmPacket) = 0;
|
||||
virtual bool isEnabled() const = 0;
|
||||
virtual void setEnabled(bool enabled) = 0;
|
||||
virtual void resetDownlinkedPacketCount() = 0;
|
||||
virtual ReturnValue_t setDumpTarget(object_id_t dumpTarget) = 0;
|
||||
};
|
||||
|
||||
#endif /* FSFW_TMTCSERVICES_TMSTOREFRONTENDIF_H_ */
|
||||
|
15
src/fsfw/tmstorage/TmStoreFrontendSimpleIF.h
Normal file
15
src/fsfw/tmstorage/TmStoreFrontendSimpleIF.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_
|
||||
#define FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_
|
||||
|
||||
#include <fsfw/ipc/messageQueueDefinitions.h>
|
||||
|
||||
class TmStoreFrontendSimpleIF {
|
||||
public:
|
||||
virtual ~TmStoreFrontendSimpleIF() = default;
|
||||
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif /* FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_ */
|
@ -1,6 +1,10 @@
|
||||
#ifndef FSFW_TMSTORAGE_TMSTOREPACKETS_H_
|
||||
#define FSFW_TMSTORAGE_TMSTOREPACKETS_H_
|
||||
|
||||
#include <fsfw/tmtcpacket/pus/tm/PusTmReader.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "fsfw/globalfunctions/timevalOperations.h"
|
||||
#include "fsfw/serialize/SerialBufferAdapter.h"
|
||||
#include "fsfw/serialize/SerialFixedArrayListAdapter.h"
|
||||
@ -24,7 +28,7 @@ class ServiceSubservice : public SerialLinkedListAdapter<SerializeIF> {
|
||||
|
||||
class ApidSsc : public SerializeIF {
|
||||
public:
|
||||
ApidSsc() : apid(SpacePacketBase::LIMIT_APID), ssc(0) {}
|
||||
ApidSsc() : apid(ccsds::LIMIT_APID), ssc(0) {}
|
||||
ApidSsc(uint16_t apid, uint16_t ssc) : apid(apid), ssc(ssc) {}
|
||||
uint16_t apid;
|
||||
uint16_t ssc;
|
||||
@ -62,51 +66,59 @@ class ChangeSelectionDefinition : public SerialLinkedListAdapter<SerializeIF> {
|
||||
|
||||
class TmPacketInformation : public SerializeIF {
|
||||
public:
|
||||
TmPacketInformation(TmPacketMinimal* packet) { setContent(packet); }
|
||||
TmPacketInformation()
|
||||
: apid(SpacePacketBase::LIMIT_APID),
|
||||
TmPacketInformation(PusTmReader* packet, size_t timestampLen) : rawTimestamp(timestampLen) {
|
||||
setContent(packet);
|
||||
}
|
||||
TmPacketInformation(size_t timestampLen)
|
||||
: apid(ccsds::LIMIT_APID),
|
||||
sourceSequenceCount(0),
|
||||
serviceType(0),
|
||||
serviceSubtype(0),
|
||||
subCounter(0) {}
|
||||
subCounter(0),
|
||||
rawTimestamp(timestampLen) {}
|
||||
void reset() {
|
||||
apid = SpacePacketBase::LIMIT_APID;
|
||||
apid = ccsds::LIMIT_APID;
|
||||
sourceSequenceCount = 0;
|
||||
serviceType = 0;
|
||||
serviceSubtype = 0;
|
||||
subCounter = 0;
|
||||
memset(rawTimestamp, 0, sizeof(rawTimestamp));
|
||||
memset(rawTimestamp.data(), 0, rawTimestamp.size());
|
||||
}
|
||||
void setContent(TmPacketMinimal* packet) {
|
||||
apid = packet->getAPID();
|
||||
sourceSequenceCount = packet->getPacketSequenceCount();
|
||||
void setContent(PusTmReader* packet) {
|
||||
apid = packet->getApid();
|
||||
sourceSequenceCount = packet->getSequenceCount();
|
||||
serviceType = packet->getService();
|
||||
serviceSubtype = packet->getSubService();
|
||||
subCounter = packet->getPacketSubcounter();
|
||||
memset(rawTimestamp, 0, sizeof(rawTimestamp));
|
||||
const uint8_t* pField = NULL;
|
||||
uint32_t size = 0;
|
||||
ReturnValue_t result = packet->getPacketTimeRaw(&pField, &size);
|
||||
if (result != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
if (*pField == CCSDSTime::P_FIELD_CDS_SHORT && size <= TimeStamperIF::MISSION_TIMESTAMP_SIZE) {
|
||||
// Shortcut to avoid converting CDS back and forth.
|
||||
memcpy(rawTimestamp, pField, size);
|
||||
return;
|
||||
}
|
||||
timeval time = {0, 0};
|
||||
result = packet->getPacketTime(&time);
|
||||
if (result != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
CCSDSTime::CDS_short cdsFormat;
|
||||
result = CCSDSTime::convertToCcsds(&cdsFormat, &time);
|
||||
if (result != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
memcpy(rawTimestamp, &cdsFormat, sizeof(cdsFormat));
|
||||
subCounter = packet->getMessageTypeCounter();
|
||||
memset(rawTimestamp.data(), 0, rawTimestamp.size());
|
||||
// TODO: Fix all of this
|
||||
// const uint8_t* pField = NULL;
|
||||
// uint32_t size = 0;
|
||||
// auto* timeReader = packet->getTimeReader();
|
||||
// ReturnValue_t result = packet->getPacketTimeRaw(&pField, &size);
|
||||
// if (result != returnvalue::OK) {
|
||||
// return;
|
||||
//}
|
||||
// if (*pField == CCSDSTime::P_FIELD_CDS_SHORT && size <= TimeStamperIF::MISSION_TIMESTAMP_SIZE)
|
||||
// {
|
||||
// Shortcut to avoid converting CDS back and forth.
|
||||
// TODO: Fix
|
||||
// memcpy(rawTimestamp, pField, size);
|
||||
// return;
|
||||
// }
|
||||
// timeval time = {0, 0};
|
||||
// result = packet->getPacketTime(&time);
|
||||
// if (result != returnvalue::OK) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// CCSDSTime::CDS_short cdsFormat;
|
||||
// result = CCSDSTime::convertToCcsds(&cdsFormat, &time);
|
||||
// if (result != returnvalue::OK) {
|
||||
// return;
|
||||
// }
|
||||
// TODO: Fix
|
||||
// memcpy(rawTimestamp, &cdsFormat, sizeof(cdsFormat));
|
||||
}
|
||||
void setContent(TmPacketInformation* content) {
|
||||
apid = content->apid;
|
||||
@ -114,9 +126,10 @@ class TmPacketInformation : public SerializeIF {
|
||||
serviceType = content->serviceType;
|
||||
serviceSubtype = content->serviceSubtype;
|
||||
subCounter = content->subCounter;
|
||||
memcpy(rawTimestamp, content->rawTimestamp, sizeof(rawTimestamp));
|
||||
// TODO: Fix
|
||||
// memcpy(rawTimestamp, content->rawTimestamp, sizeof(rawTimestamp));
|
||||
}
|
||||
bool isValid() const { return (apid < SpacePacketBase::LIMIT_APID) ? true : false; }
|
||||
bool isValid() const { return (apid < ccsds::LIMIT_APID) ? true : false; }
|
||||
static void reset(TmPacketInformation* packet) { packet->reset(); }
|
||||
|
||||
static bool isOlderThan(const TmPacketInformation* packet, const timeval* cmpTime) {
|
||||
@ -216,7 +229,7 @@ class TmPacketInformation : public SerializeIF {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp));
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
|
||||
return adapter.serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
@ -227,7 +240,7 @@ class TmPacketInformation : public SerializeIF {
|
||||
size += SerializeAdapter::getSerializedSize(&serviceType);
|
||||
size += SerializeAdapter::getSerializedSize(&serviceSubtype);
|
||||
size += SerializeAdapter::getSerializedSize(&subCounter);
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp));
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
|
||||
size += adapter.getSerializedSize();
|
||||
return size;
|
||||
};
|
||||
@ -253,7 +266,7 @@ class TmPacketInformation : public SerializeIF {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp));
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
|
||||
return adapter.deSerialize(buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
@ -263,6 +276,6 @@ class TmPacketInformation : public SerializeIF {
|
||||
uint8_t serviceType;
|
||||
uint8_t serviceSubtype;
|
||||
uint8_t subCounter;
|
||||
uint8_t rawTimestamp[TimeStamperIF::MISSION_TIMESTAMP_SIZE];
|
||||
std::vector<uint8_t> rawTimestamp;
|
||||
};
|
||||
#endif /* FSFW_TMSTORAGE_TMSTOREPACKETS_H_ */
|
||||
|
@ -17,7 +17,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
||||
public:
|
||||
static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
|
||||
static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15;
|
||||
static constexpr unsigned int LIMIT_DOWNLINK_PACKETS_STORED = 1000;
|
||||
static constexpr unsigned int LIMIT_DOWNLINK_PACKETS_STORED = 500;
|
||||
|
||||
static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5;
|
||||
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "version.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "fsfw/FSFWVersion.h"
|
||||
|
||||
@ -20,7 +21,7 @@ fsfw::Version::Version(int major, int minor, int revision, const char* addInfo)
|
||||
|
||||
void fsfw::Version::getVersion(char* str, size_t maxLen) const {
|
||||
size_t len = snprintf(str, maxLen, "%d.%d.%d", major, minor, revision);
|
||||
if (addInfo != nullptr) {
|
||||
if (addInfo != nullptr and std::strcmp(addInfo, "") != 0) {
|
||||
snprintf(str + len, maxLen - len, "-%s", addInfo);
|
||||
}
|
||||
}
|
||||
@ -30,7 +31,7 @@ namespace fsfw {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
std::ostream& operator<<(std::ostream& os, const Version& v) {
|
||||
os << v.major << "." << v.minor << "." << v.revision;
|
||||
if (v.addInfo != nullptr) {
|
||||
if (v.addInfo != nullptr and std::strcmp(v.addInfo, "") != 0) {
|
||||
os << "-" << v.addInfo;
|
||||
}
|
||||
return os;
|
||||
|
@ -1,3 +1,5 @@
|
||||
target_sources(
|
||||
${LIB_FSFW_NAME} PRIVATE GyroL3GD20Handler.cpp MgmRM3100Handler.cpp
|
||||
MgmLIS3MDLHandler.cpp)
|
||||
|
||||
add_subdirectory(devicedefinitions)
|
||||
|
@ -46,17 +46,17 @@ ReturnValue_t GyroHandlerL3GD20H::buildTransitionDeviceCommand(DeviceCommandId_t
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
case (InternalState::CONFIGURE): {
|
||||
*id = L3GD20H::CONFIGURE_CTRL_REGS;
|
||||
*id = l3gd20h::CONFIGURE_CTRL_REGS;
|
||||
uint8_t command[5];
|
||||
command[0] = L3GD20H::CTRL_REG_1_VAL;
|
||||
command[1] = L3GD20H::CTRL_REG_2_VAL;
|
||||
command[2] = L3GD20H::CTRL_REG_3_VAL;
|
||||
command[3] = L3GD20H::CTRL_REG_4_VAL;
|
||||
command[4] = L3GD20H::CTRL_REG_5_VAL;
|
||||
command[0] = l3gd20h::CTRL_REG_1_VAL;
|
||||
command[1] = l3gd20h::CTRL_REG_2_VAL;
|
||||
command[2] = l3gd20h::CTRL_REG_3_VAL;
|
||||
command[3] = l3gd20h::CTRL_REG_4_VAL;
|
||||
command[4] = l3gd20h::CTRL_REG_5_VAL;
|
||||
return buildCommandFromCommand(*id, command, 5);
|
||||
}
|
||||
case (InternalState::CHECK_REGS): {
|
||||
*id = L3GD20H::READ_REGS;
|
||||
*id = l3gd20h::READ_REGS;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
default:
|
||||
@ -76,7 +76,7 @@ ReturnValue_t GyroHandlerL3GD20H::buildTransitionDeviceCommand(DeviceCommandId_t
|
||||
}
|
||||
|
||||
ReturnValue_t GyroHandlerL3GD20H::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
||||
*id = L3GD20H::READ_REGS;
|
||||
*id = l3gd20h::READ_REGS;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
|
||||
@ -84,15 +84,15 @@ ReturnValue_t GyroHandlerL3GD20H::buildCommandFromCommand(DeviceCommandId_t devi
|
||||
const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
switch (deviceCommand) {
|
||||
case (L3GD20H::READ_REGS): {
|
||||
commandBuffer[0] = L3GD20H::READ_START | L3GD20H::AUTO_INCREMENT_MASK | L3GD20H::READ_MASK;
|
||||
std::memset(commandBuffer + 1, 0, L3GD20H::READ_LEN);
|
||||
case (l3gd20h::READ_REGS): {
|
||||
commandBuffer[0] = l3gd20h::READ_START | l3gd20h::AUTO_INCREMENT_MASK | l3gd20h::READ_MASK;
|
||||
std::memset(commandBuffer + 1, 0, l3gd20h::READ_LEN);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = L3GD20H::READ_LEN + 1;
|
||||
rawPacketLen = l3gd20h::READ_LEN + 1;
|
||||
break;
|
||||
}
|
||||
case (L3GD20H::CONFIGURE_CTRL_REGS): {
|
||||
commandBuffer[0] = L3GD20H::CTRL_REG_1 | L3GD20H::AUTO_INCREMENT_MASK;
|
||||
case (l3gd20h::CONFIGURE_CTRL_REGS): {
|
||||
commandBuffer[0] = l3gd20h::CTRL_REG_1 | l3gd20h::AUTO_INCREMENT_MASK;
|
||||
if (commandData == nullptr or commandDataLen != 5) {
|
||||
return DeviceHandlerIF::INVALID_COMMAND_PARAMETER;
|
||||
}
|
||||
@ -103,15 +103,15 @@ ReturnValue_t GyroHandlerL3GD20H::buildCommandFromCommand(DeviceCommandId_t devi
|
||||
ctrlReg4Value = commandData[3];
|
||||
ctrlReg5Value = commandData[4];
|
||||
|
||||
bool fsH = ctrlReg4Value & L3GD20H::SET_FS_1;
|
||||
bool fsL = ctrlReg4Value & L3GD20H::SET_FS_0;
|
||||
bool fsH = ctrlReg4Value & l3gd20h::SET_FS_1;
|
||||
bool fsL = ctrlReg4Value & l3gd20h::SET_FS_0;
|
||||
|
||||
if (not fsH and not fsL) {
|
||||
sensitivity = L3GD20H::SENSITIVITY_00;
|
||||
sensitivity = l3gd20h::SENSITIVITY_00;
|
||||
} else if (not fsH and fsL) {
|
||||
sensitivity = L3GD20H::SENSITIVITY_01;
|
||||
sensitivity = l3gd20h::SENSITIVITY_01;
|
||||
} else {
|
||||
sensitivity = L3GD20H::SENSITIVITY_11;
|
||||
sensitivity = l3gd20h::SENSITIVITY_11;
|
||||
}
|
||||
|
||||
commandBuffer[1] = ctrlReg1Value;
|
||||
@ -124,8 +124,8 @@ ReturnValue_t GyroHandlerL3GD20H::buildCommandFromCommand(DeviceCommandId_t devi
|
||||
rawPacketLen = 6;
|
||||
break;
|
||||
}
|
||||
case (L3GD20H::READ_CTRL_REGS): {
|
||||
commandBuffer[0] = L3GD20H::READ_START | L3GD20H::AUTO_INCREMENT_MASK | L3GD20H::READ_MASK;
|
||||
case (l3gd20h::READ_CTRL_REGS): {
|
||||
commandBuffer[0] = l3gd20h::READ_START | l3gd20h::AUTO_INCREMENT_MASK | l3gd20h::READ_MASK;
|
||||
|
||||
std::memset(commandBuffer + 1, 0, 5);
|
||||
rawPacket = commandBuffer;
|
||||
@ -151,11 +151,11 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
switch (id) {
|
||||
case (L3GD20H::CONFIGURE_CTRL_REGS): {
|
||||
case (l3gd20h::CONFIGURE_CTRL_REGS): {
|
||||
commandExecuted = true;
|
||||
break;
|
||||
}
|
||||
case (L3GD20H::READ_CTRL_REGS): {
|
||||
case (l3gd20h::READ_CTRL_REGS): {
|
||||
if (packet[1] == ctrlReg1Value and packet[2] == ctrlReg2Value and
|
||||
packet[3] == ctrlReg3Value and packet[4] == ctrlReg4Value and
|
||||
packet[5] == ctrlReg5Value) {
|
||||
@ -167,7 +167,7 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (L3GD20H::READ_REGS): {
|
||||
case (l3gd20h::READ_REGS): {
|
||||
if (packet[1] != ctrlReg1Value and packet[2] != ctrlReg2Value and
|
||||
packet[3] != ctrlReg3Value and packet[4] != ctrlReg4Value and
|
||||
packet[5] != ctrlReg5Value) {
|
||||
@ -178,16 +178,16 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id,
|
||||
}
|
||||
}
|
||||
|
||||
statusReg = packet[L3GD20H::STATUS_IDX];
|
||||
statusReg = packet[l3gd20h::STATUS_IDX];
|
||||
|
||||
int16_t angVelocXRaw = packet[L3GD20H::OUT_X_H] << 8 | packet[L3GD20H::OUT_X_L];
|
||||
int16_t angVelocYRaw = packet[L3GD20H::OUT_Y_H] << 8 | packet[L3GD20H::OUT_Y_L];
|
||||
int16_t angVelocZRaw = packet[L3GD20H::OUT_Z_H] << 8 | packet[L3GD20H::OUT_Z_L];
|
||||
int16_t angVelocXRaw = packet[l3gd20h::OUT_X_H] << 8 | packet[l3gd20h::OUT_X_L];
|
||||
int16_t angVelocYRaw = packet[l3gd20h::OUT_Y_H] << 8 | packet[l3gd20h::OUT_Y_L];
|
||||
int16_t angVelocZRaw = packet[l3gd20h::OUT_Z_H] << 8 | packet[l3gd20h::OUT_Z_L];
|
||||
float angVelocX = angVelocXRaw * sensitivity;
|
||||
float angVelocY = angVelocYRaw * sensitivity;
|
||||
float angVelocZ = angVelocZRaw * sensitivity;
|
||||
|
||||
int8_t temperaturOffset = (-1) * packet[L3GD20H::TEMPERATURE_IDX];
|
||||
int8_t temperaturOffset = (-1) * packet[l3gd20h::TEMPERATURE_IDX];
|
||||
float temperature = 25.0 + temperaturOffset;
|
||||
if (periodicPrintout) {
|
||||
if (debugDivider.checkAndIncrement()) {
|
||||
@ -248,19 +248,19 @@ void GyroHandlerL3GD20H::setToGoToNormalMode(bool enable) { this->goNormalModeIm
|
||||
|
||||
ReturnValue_t GyroHandlerL3GD20H::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_X, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Y, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Z, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(L3GD20H::TEMPERATURE, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(l3gd20h::ANG_VELOC_X, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(l3gd20h::ANG_VELOC_Y, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(l3gd20h::ANG_VELOC_Z, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(l3gd20h::TEMPERATURE, new PoolEntry<float>({0.0}));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(dataset.getSid(), false, 10.0));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void GyroHandlerL3GD20H::fillCommandAndReplyMap() {
|
||||
insertInCommandAndReplyMap(L3GD20H::READ_REGS, 1, &dataset);
|
||||
insertInCommandAndReplyMap(L3GD20H::CONFIGURE_CTRL_REGS, 1);
|
||||
insertInCommandAndReplyMap(L3GD20H::READ_CTRL_REGS, 1);
|
||||
insertInCommandAndReplyMap(l3gd20h::READ_REGS, 1, &dataset);
|
||||
insertInCommandAndReplyMap(l3gd20h::CONFIGURE_CTRL_REGS, 1);
|
||||
insertInCommandAndReplyMap(l3gd20h::READ_CTRL_REGS, 1);
|
||||
}
|
||||
|
||||
void GyroHandlerL3GD20H::modeChanged() { internalState = InternalState::NONE; }
|
||||
|
@ -3,8 +3,7 @@
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||
|
||||
#include "devicedefinitions/GyroL3GD20Definitions.h"
|
||||
#include <fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h>
|
||||
|
||||
/**
|
||||
* @brief Device Handler for the L3GD20H gyroscope sensor
|
||||
@ -59,9 +58,9 @@ class GyroHandlerL3GD20H : public DeviceHandlerBase {
|
||||
uint32_t transitionDelayMs = 0;
|
||||
GyroPrimaryDataset dataset;
|
||||
|
||||
float absLimitX = L3GD20H::RANGE_DPS_00;
|
||||
float absLimitY = L3GD20H::RANGE_DPS_00;
|
||||
float absLimitZ = L3GD20H::RANGE_DPS_00;
|
||||
float absLimitX = l3gd20h::RANGE_DPS_00;
|
||||
float absLimitY = l3gd20h::RANGE_DPS_00;
|
||||
float absLimitZ = l3gd20h::RANGE_DPS_00;
|
||||
|
||||
enum class InternalState { NONE, CONFIGURE, CHECK_REGS, NORMAL };
|
||||
InternalState internalState = InternalState::NONE;
|
||||
@ -70,16 +69,16 @@ class GyroHandlerL3GD20H : public DeviceHandlerBase {
|
||||
uint8_t statusReg = 0;
|
||||
bool goNormalModeImmediately = false;
|
||||
|
||||
uint8_t ctrlReg1Value = L3GD20H::CTRL_REG_1_VAL;
|
||||
uint8_t ctrlReg2Value = L3GD20H::CTRL_REG_2_VAL;
|
||||
uint8_t ctrlReg3Value = L3GD20H::CTRL_REG_3_VAL;
|
||||
uint8_t ctrlReg4Value = L3GD20H::CTRL_REG_4_VAL;
|
||||
uint8_t ctrlReg5Value = L3GD20H::CTRL_REG_5_VAL;
|
||||
uint8_t ctrlReg1Value = l3gd20h::CTRL_REG_1_VAL;
|
||||
uint8_t ctrlReg2Value = l3gd20h::CTRL_REG_2_VAL;
|
||||
uint8_t ctrlReg3Value = l3gd20h::CTRL_REG_3_VAL;
|
||||
uint8_t ctrlReg4Value = l3gd20h::CTRL_REG_4_VAL;
|
||||
uint8_t ctrlReg5Value = l3gd20h::CTRL_REG_5_VAL;
|
||||
|
||||
uint8_t commandBuffer[L3GD20H::READ_LEN + 1];
|
||||
uint8_t commandBuffer[l3gd20h::READ_LEN + 1];
|
||||
|
||||
// Set default value
|
||||
float sensitivity = L3GD20H::SENSITIVITY_00;
|
||||
float sensitivity = l3gd20h::SENSITIVITY_00;
|
||||
|
||||
bool periodicPrintout = false;
|
||||
PeriodicOperationDivider debugDivider = PeriodicOperationDivider(3);
|
||||
|
@ -10,11 +10,11 @@ MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCom
|
||||
dataset(this),
|
||||
transitionDelay(transitionDelay) {
|
||||
// Set to default values right away
|
||||
registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT;
|
||||
registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT;
|
||||
registers[2] = MGMLIS3MDL::CTRL_REG3_DEFAULT;
|
||||
registers[3] = MGMLIS3MDL::CTRL_REG4_DEFAULT;
|
||||
registers[4] = MGMLIS3MDL::CTRL_REG5_DEFAULT;
|
||||
registers[0] = mgmLis3::CTRL_REG1_DEFAULT;
|
||||
registers[1] = mgmLis3::CTRL_REG2_DEFAULT;
|
||||
registers[2] = mgmLis3::CTRL_REG3_DEFAULT;
|
||||
registers[3] = mgmLis3::CTRL_REG4_DEFAULT;
|
||||
registers[4] = mgmLis3::CTRL_REG5_DEFAULT;
|
||||
}
|
||||
|
||||
MgmLIS3MDLHandler::~MgmLIS3MDLHandler() {}
|
||||
@ -63,15 +63,15 @@ ReturnValue_t MgmLIS3MDLHandler::buildTransitionDeviceCommand(DeviceCommandId_t
|
||||
return DeviceHandlerBase::NOTHING_TO_SEND;
|
||||
}
|
||||
case (InternalState::STATE_FIRST_CONTACT): {
|
||||
*id = MGMLIS3MDL::IDENTIFY_DEVICE;
|
||||
*id = mgmLis3::IDENTIFY_DEVICE;
|
||||
break;
|
||||
}
|
||||
case (InternalState::STATE_SETUP): {
|
||||
*id = MGMLIS3MDL::SETUP_MGM;
|
||||
*id = mgmLis3::SETUP_MGM;
|
||||
break;
|
||||
}
|
||||
case (InternalState::STATE_CHECK_REGISTERS): {
|
||||
*id = MGMLIS3MDL::READ_CONFIG_AND_DATA;
|
||||
*id = mgmLis3::READ_CONFIG_AND_DATA;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -88,28 +88,12 @@ ReturnValue_t MgmLIS3MDLHandler::buildTransitionDeviceCommand(DeviceCommandId_t
|
||||
return buildCommandFromCommand(*id, NULL, 0);
|
||||
}
|
||||
|
||||
uint8_t MgmLIS3MDLHandler::readCommand(uint8_t command, bool continuousCom) {
|
||||
command |= (1 << MGMLIS3MDL::RW_BIT);
|
||||
if (continuousCom == true) {
|
||||
command |= (1 << MGMLIS3MDL::MS_BIT);
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
uint8_t MgmLIS3MDLHandler::writeCommand(uint8_t command, bool continuousCom) {
|
||||
command &= ~(1 << MGMLIS3MDL::RW_BIT);
|
||||
if (continuousCom == true) {
|
||||
command |= (1 << MGMLIS3MDL::MS_BIT);
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
void MgmLIS3MDLHandler::setupMgm() {
|
||||
registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT;
|
||||
registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT;
|
||||
registers[2] = MGMLIS3MDL::CTRL_REG3_DEFAULT;
|
||||
registers[3] = MGMLIS3MDL::CTRL_REG4_DEFAULT;
|
||||
registers[4] = MGMLIS3MDL::CTRL_REG5_DEFAULT;
|
||||
registers[0] = mgmLis3::CTRL_REG1_DEFAULT;
|
||||
registers[1] = mgmLis3::CTRL_REG2_DEFAULT;
|
||||
registers[2] = mgmLis3::CTRL_REG3_DEFAULT;
|
||||
registers[3] = mgmLis3::CTRL_REG4_DEFAULT;
|
||||
registers[4] = mgmLis3::CTRL_REG5_DEFAULT;
|
||||
|
||||
prepareCtrlRegisterWrite();
|
||||
}
|
||||
@ -117,11 +101,11 @@ void MgmLIS3MDLHandler::setupMgm() {
|
||||
ReturnValue_t MgmLIS3MDLHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
||||
// Data/config register will be read in an alternating manner.
|
||||
if (communicationStep == CommunicationStep::DATA) {
|
||||
*id = MGMLIS3MDL::READ_CONFIG_AND_DATA;
|
||||
*id = mgmLis3::READ_CONFIG_AND_DATA;
|
||||
communicationStep = CommunicationStep::TEMPERATURE;
|
||||
return buildCommandFromCommand(*id, NULL, 0);
|
||||
} else {
|
||||
*id = MGMLIS3MDL::READ_TEMPERATURE;
|
||||
*id = mgmLis3::READ_TEMPERATURE;
|
||||
communicationStep = CommunicationStep::DATA;
|
||||
return buildCommandFromCommand(*id, NULL, 0);
|
||||
}
|
||||
@ -131,33 +115,33 @@ ReturnValue_t MgmLIS3MDLHandler::buildCommandFromCommand(DeviceCommandId_t devic
|
||||
const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
switch (deviceCommand) {
|
||||
case (MGMLIS3MDL::READ_CONFIG_AND_DATA): {
|
||||
case (mgmLis3::READ_CONFIG_AND_DATA): {
|
||||
std::memset(commandBuffer, 0, sizeof(commandBuffer));
|
||||
commandBuffer[0] = readCommand(MGMLIS3MDL::CTRL_REG1, true);
|
||||
commandBuffer[0] = mgmLis3::readCommand(mgmLis3::CTRL_REG1, true);
|
||||
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1;
|
||||
rawPacketLen = mgmLis3::NR_OF_DATA_AND_CFG_REGISTERS + 1;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (MGMLIS3MDL::READ_TEMPERATURE): {
|
||||
case (mgmLis3::READ_TEMPERATURE): {
|
||||
std::memset(commandBuffer, 0, 3);
|
||||
commandBuffer[0] = readCommand(MGMLIS3MDL::TEMP_LOWBYTE, true);
|
||||
commandBuffer[0] = mgmLis3::readCommand(mgmLis3::TEMP_LOWBYTE, true);
|
||||
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = 3;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (MGMLIS3MDL::IDENTIFY_DEVICE): {
|
||||
case (mgmLis3::IDENTIFY_DEVICE): {
|
||||
return identifyDevice();
|
||||
}
|
||||
case (MGMLIS3MDL::TEMP_SENSOR_ENABLE): {
|
||||
case (mgmLis3::TEMP_SENSOR_ENABLE): {
|
||||
return enableTemperatureSensor(commandData, commandDataLen);
|
||||
}
|
||||
case (MGMLIS3MDL::SETUP_MGM): {
|
||||
case (mgmLis3::SETUP_MGM): {
|
||||
setupMgm();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (MGMLIS3MDL::ACCURACY_OP_MODE_SET): {
|
||||
case (mgmLis3::ACCURACY_OP_MODE_SET): {
|
||||
return setOperatingMode(commandData, commandDataLen);
|
||||
}
|
||||
default:
|
||||
@ -168,7 +152,7 @@ ReturnValue_t MgmLIS3MDLHandler::buildCommandFromCommand(DeviceCommandId_t devic
|
||||
|
||||
ReturnValue_t MgmLIS3MDLHandler::identifyDevice() {
|
||||
uint32_t size = 2;
|
||||
commandBuffer[0] = readCommand(MGMLIS3MDL::IDENTIFY_DEVICE_REG_ADDR);
|
||||
commandBuffer[0] = mgmLis3::readCommand(mgmLis3::IDENTIFY_DEVICE_REG_ADDR);
|
||||
commandBuffer[1] = 0x00;
|
||||
|
||||
rawPacket = commandBuffer;
|
||||
@ -180,9 +164,9 @@ ReturnValue_t MgmLIS3MDLHandler::identifyDevice() {
|
||||
ReturnValue_t MgmLIS3MDLHandler::scanForReply(const uint8_t *start, size_t len,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
*foundLen = len;
|
||||
if (len == MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1) {
|
||||
if (len == mgmLis3::NR_OF_DATA_AND_CFG_REGISTERS + 1) {
|
||||
*foundLen = len;
|
||||
*foundId = MGMLIS3MDL::READ_CONFIG_AND_DATA;
|
||||
*foundId = mgmLis3::READ_CONFIG_AND_DATA;
|
||||
// Check validity by checking config registers
|
||||
if (start[1] != registers[0] or start[2] != registers[1] or start[3] != registers[2] or
|
||||
start[4] != registers[3] or start[5] != registers[4]) {
|
||||
@ -199,17 +183,17 @@ ReturnValue_t MgmLIS3MDLHandler::scanForReply(const uint8_t *start, size_t len,
|
||||
commandExecuted = true;
|
||||
}
|
||||
|
||||
} else if (len == MGMLIS3MDL::TEMPERATURE_REPLY_LEN) {
|
||||
} else if (len == mgmLis3::TEMPERATURE_REPLY_LEN) {
|
||||
*foundLen = len;
|
||||
*foundId = MGMLIS3MDL::READ_TEMPERATURE;
|
||||
} else if (len == MGMLIS3MDL::SETUP_REPLY_LEN) {
|
||||
*foundId = mgmLis3::READ_TEMPERATURE;
|
||||
} else if (len == mgmLis3::SETUP_REPLY_LEN) {
|
||||
*foundLen = len;
|
||||
*foundId = MGMLIS3MDL::SETUP_MGM;
|
||||
*foundId = mgmLis3::SETUP_MGM;
|
||||
} else if (len == SINGLE_COMMAND_ANSWER_LEN) {
|
||||
*foundLen = len;
|
||||
*foundId = getPendingCommand();
|
||||
if (*foundId == MGMLIS3MDL::IDENTIFY_DEVICE) {
|
||||
if (start[1] != MGMLIS3MDL::DEVICE_ID) {
|
||||
if (*foundId == mgmLis3::IDENTIFY_DEVICE) {
|
||||
if (start[1] != mgmLis3::DEVICE_ID) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "MGMHandlerLIS3MDL::scanForReply: "
|
||||
@ -241,30 +225,31 @@ ReturnValue_t MgmLIS3MDLHandler::scanForReply(const uint8_t *start, size_t len,
|
||||
}
|
||||
ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
|
||||
switch (id) {
|
||||
case MGMLIS3MDL::IDENTIFY_DEVICE: {
|
||||
case mgmLis3::IDENTIFY_DEVICE: {
|
||||
break;
|
||||
}
|
||||
case MGMLIS3MDL::SETUP_MGM: {
|
||||
case mgmLis3::SETUP_MGM: {
|
||||
break;
|
||||
}
|
||||
case MGMLIS3MDL::READ_CONFIG_AND_DATA: {
|
||||
case mgmLis3::READ_CONFIG_AND_DATA: {
|
||||
using namespace mgmLis3;
|
||||
// TODO: Store configuration in new local datasets.
|
||||
float sensitivityFactor = getSensitivityFactor(getSensitivity(registers[2]));
|
||||
|
||||
int16_t mgmMeasurementRawX =
|
||||
packet[MGMLIS3MDL::X_HIGHBYTE_IDX] << 8 | packet[MGMLIS3MDL::X_LOWBYTE_IDX];
|
||||
packet[mgmLis3::X_HIGHBYTE_IDX] << 8 | packet[mgmLis3::X_LOWBYTE_IDX];
|
||||
int16_t mgmMeasurementRawY =
|
||||
packet[MGMLIS3MDL::Y_HIGHBYTE_IDX] << 8 | packet[MGMLIS3MDL::Y_LOWBYTE_IDX];
|
||||
packet[mgmLis3::Y_HIGHBYTE_IDX] << 8 | packet[mgmLis3::Y_LOWBYTE_IDX];
|
||||
int16_t mgmMeasurementRawZ =
|
||||
packet[MGMLIS3MDL::Z_HIGHBYTE_IDX] << 8 | packet[MGMLIS3MDL::Z_LOWBYTE_IDX];
|
||||
packet[mgmLis3::Z_HIGHBYTE_IDX] << 8 | packet[mgmLis3::Z_LOWBYTE_IDX];
|
||||
|
||||
// Target value in microtesla
|
||||
float mgmX = static_cast<float>(mgmMeasurementRawX) * sensitivityFactor *
|
||||
MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR;
|
||||
mgmLis3::GAUSS_TO_MICROTESLA_FACTOR;
|
||||
float mgmY = static_cast<float>(mgmMeasurementRawY) * sensitivityFactor *
|
||||
MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR;
|
||||
mgmLis3::GAUSS_TO_MICROTESLA_FACTOR;
|
||||
float mgmZ = static_cast<float>(mgmMeasurementRawZ) * sensitivityFactor *
|
||||
MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR;
|
||||
mgmLis3::GAUSS_TO_MICROTESLA_FACTOR;
|
||||
|
||||
if (periodicPrintout) {
|
||||
if (debugDivider.checkAndIncrement()) {
|
||||
@ -306,7 +291,7 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
||||
break;
|
||||
}
|
||||
|
||||
case MGMLIS3MDL::READ_TEMPERATURE: {
|
||||
case mgmLis3::READ_TEMPERATURE: {
|
||||
int16_t tempValueRaw = packet[2] << 8 | packet[1];
|
||||
float tempValue = 25.0 + ((static_cast<float>(tempValueRaw)) / 8.0);
|
||||
if (periodicPrintout) {
|
||||
@ -334,41 +319,6 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
MGMLIS3MDL::Sensitivies MgmLIS3MDLHandler::getSensitivity(uint8_t ctrlRegister2) {
|
||||
bool fs0Set = ctrlRegister2 & (1 << MGMLIS3MDL::FSO); // Checks if FS0 bit is set
|
||||
bool fs1Set = ctrlRegister2 & (1 << MGMLIS3MDL::FS1); // Checks if FS1 bit is set
|
||||
|
||||
if (fs0Set && fs1Set)
|
||||
return MGMLIS3MDL::Sensitivies::GAUSS_16;
|
||||
else if (!fs0Set && fs1Set)
|
||||
return MGMLIS3MDL::Sensitivies::GAUSS_12;
|
||||
else if (fs0Set && !fs1Set)
|
||||
return MGMLIS3MDL::Sensitivies::GAUSS_8;
|
||||
else
|
||||
return MGMLIS3MDL::Sensitivies::GAUSS_4;
|
||||
}
|
||||
|
||||
float MgmLIS3MDLHandler::getSensitivityFactor(MGMLIS3MDL::Sensitivies sens) {
|
||||
switch (sens) {
|
||||
case (MGMLIS3MDL::GAUSS_4): {
|
||||
return MGMLIS3MDL::FIELD_LSB_PER_GAUSS_4_SENS;
|
||||
}
|
||||
case (MGMLIS3MDL::GAUSS_8): {
|
||||
return MGMLIS3MDL::FIELD_LSB_PER_GAUSS_8_SENS;
|
||||
}
|
||||
case (MGMLIS3MDL::GAUSS_12): {
|
||||
return MGMLIS3MDL::FIELD_LSB_PER_GAUSS_12_SENS;
|
||||
}
|
||||
case (MGMLIS3MDL::GAUSS_16): {
|
||||
return MGMLIS3MDL::FIELD_LSB_PER_GAUSS_16_SENS;
|
||||
}
|
||||
default: {
|
||||
// Should never happen
|
||||
return MGMLIS3MDL::FIELD_LSB_PER_GAUSS_4_SENS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t MgmLIS3MDLHandler::enableTemperatureSensor(const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
if (commandData == nullptr) {
|
||||
@ -376,16 +326,16 @@ ReturnValue_t MgmLIS3MDLHandler::enableTemperatureSensor(const uint8_t *commandD
|
||||
}
|
||||
triggerEvent(CHANGE_OF_SETUP_PARAMETER);
|
||||
uint32_t size = 2;
|
||||
commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1);
|
||||
commandBuffer[0] = mgmLis3::writeCommand(mgmLis3::CTRL_REG1);
|
||||
if (commandDataLen > 1) {
|
||||
return INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS;
|
||||
}
|
||||
switch (commandData[0]) {
|
||||
case (MGMLIS3MDL::ON): {
|
||||
case (mgmLis3::ON): {
|
||||
commandBuffer[1] = registers[0] | (1 << 7);
|
||||
break;
|
||||
}
|
||||
case (MGMLIS3MDL::OFF): {
|
||||
case (mgmLis3::OFF): {
|
||||
commandBuffer[1] = registers[0] & ~(1 << 7);
|
||||
break;
|
||||
}
|
||||
@ -408,23 +358,23 @@ ReturnValue_t MgmLIS3MDLHandler::setOperatingMode(const uint8_t *commandData,
|
||||
}
|
||||
|
||||
switch (commandData[0]) {
|
||||
case MGMLIS3MDL::LOW:
|
||||
registers[0] = (registers[0] & (~(1 << MGMLIS3MDL::OM1))) & (~(1 << MGMLIS3MDL::OM0));
|
||||
registers[3] = (registers[3] & (~(1 << MGMLIS3MDL::OMZ1))) & (~(1 << MGMLIS3MDL::OMZ0));
|
||||
case mgmLis3::LOW:
|
||||
registers[0] = (registers[0] & (~(1 << mgmLis3::OM1))) & (~(1 << mgmLis3::OM0));
|
||||
registers[3] = (registers[3] & (~(1 << mgmLis3::OMZ1))) & (~(1 << mgmLis3::OMZ0));
|
||||
break;
|
||||
case MGMLIS3MDL::MEDIUM:
|
||||
registers[0] = (registers[0] & (~(1 << MGMLIS3MDL::OM1))) | (1 << MGMLIS3MDL::OM0);
|
||||
registers[3] = (registers[3] & (~(1 << MGMLIS3MDL::OMZ1))) | (1 << MGMLIS3MDL::OMZ0);
|
||||
case mgmLis3::MEDIUM:
|
||||
registers[0] = (registers[0] & (~(1 << mgmLis3::OM1))) | (1 << mgmLis3::OM0);
|
||||
registers[3] = (registers[3] & (~(1 << mgmLis3::OMZ1))) | (1 << mgmLis3::OMZ0);
|
||||
break;
|
||||
|
||||
case MGMLIS3MDL::HIGH:
|
||||
registers[0] = (registers[0] | (1 << MGMLIS3MDL::OM1)) & (~(1 << MGMLIS3MDL::OM0));
|
||||
registers[3] = (registers[3] | (1 << MGMLIS3MDL::OMZ1)) & (~(1 << MGMLIS3MDL::OMZ0));
|
||||
case mgmLis3::HIGH:
|
||||
registers[0] = (registers[0] | (1 << mgmLis3::OM1)) & (~(1 << mgmLis3::OM0));
|
||||
registers[3] = (registers[3] | (1 << mgmLis3::OMZ1)) & (~(1 << mgmLis3::OMZ0));
|
||||
break;
|
||||
|
||||
case MGMLIS3MDL::ULTRA:
|
||||
registers[0] = (registers[0] | (1 << MGMLIS3MDL::OM1)) | (1 << MGMLIS3MDL::OM0);
|
||||
registers[3] = (registers[3] | (1 << MGMLIS3MDL::OMZ1)) | (1 << MGMLIS3MDL::OMZ0);
|
||||
case mgmLis3::ULTRA:
|
||||
registers[0] = (registers[0] | (1 << mgmLis3::OM1)) | (1 << mgmLis3::OM0);
|
||||
registers[3] = (registers[3] | (1 << mgmLis3::OMZ1)) | (1 << mgmLis3::OMZ0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -434,24 +384,24 @@ ReturnValue_t MgmLIS3MDLHandler::setOperatingMode(const uint8_t *commandData,
|
||||
}
|
||||
|
||||
void MgmLIS3MDLHandler::fillCommandAndReplyMap() {
|
||||
insertInCommandAndReplyMap(MGMLIS3MDL::READ_CONFIG_AND_DATA, 1, &dataset);
|
||||
insertInCommandAndReplyMap(MGMLIS3MDL::READ_TEMPERATURE, 1);
|
||||
insertInCommandAndReplyMap(MGMLIS3MDL::SETUP_MGM, 1);
|
||||
insertInCommandAndReplyMap(MGMLIS3MDL::IDENTIFY_DEVICE, 1);
|
||||
insertInCommandAndReplyMap(MGMLIS3MDL::TEMP_SENSOR_ENABLE, 1);
|
||||
insertInCommandAndReplyMap(MGMLIS3MDL::ACCURACY_OP_MODE_SET, 1);
|
||||
insertInCommandAndReplyMap(mgmLis3::READ_CONFIG_AND_DATA, 1, &dataset);
|
||||
insertInCommandAndReplyMap(mgmLis3::READ_TEMPERATURE, 1);
|
||||
insertInCommandAndReplyMap(mgmLis3::SETUP_MGM, 1);
|
||||
insertInCommandAndReplyMap(mgmLis3::IDENTIFY_DEVICE, 1);
|
||||
insertInCommandAndReplyMap(mgmLis3::TEMP_SENSOR_ENABLE, 1);
|
||||
insertInCommandAndReplyMap(mgmLis3::ACCURACY_OP_MODE_SET, 1);
|
||||
}
|
||||
|
||||
void MgmLIS3MDLHandler::setToGoToNormalMode(bool enable) { this->goToNormalMode = enable; }
|
||||
|
||||
ReturnValue_t MgmLIS3MDLHandler::prepareCtrlRegisterWrite() {
|
||||
commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1, true);
|
||||
commandBuffer[0] = mgmLis3::writeCommand(mgmLis3::CTRL_REG1, true);
|
||||
|
||||
for (size_t i = 0; i < MGMLIS3MDL::NR_OF_CTRL_REGISTERS; i++) {
|
||||
for (size_t i = 0; i < mgmLis3::NR_OF_CTRL_REGISTERS; i++) {
|
||||
commandBuffer[i + 1] = registers[i];
|
||||
}
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = MGMLIS3MDL::NR_OF_CTRL_REGISTERS + 1;
|
||||
rawPacketLen = mgmLis3::NR_OF_CTRL_REGISTERS + 1;
|
||||
|
||||
// We dont have to check if this is working because we just did i
|
||||
return returnvalue::OK;
|
||||
@ -467,8 +417,8 @@ void MgmLIS3MDLHandler::modeChanged(void) { internalState = InternalState::STATE
|
||||
|
||||
ReturnValue_t MgmLIS3MDLHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTHS, &mgmXYZ);
|
||||
localDataPoolMap.emplace(MGMLIS3MDL::TEMPERATURE_CELCIUS, &temperature);
|
||||
localDataPoolMap.emplace(mgmLis3::FIELD_STRENGTHS, &mgmXYZ);
|
||||
localDataPoolMap.emplace(mgmLis3::TEMPERATURE_CELCIUS, &temperature);
|
||||
poolManager.subscribeForRegularPeriodicPacket({dataset.getSid(), false, 10.0});
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
#ifndef MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
|
||||
#define MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
|
||||
|
||||
#include "devicedefinitions/MgmLIS3HandlerDefs.h"
|
||||
#include <fsfw_hal/devicehandlers/devicedefinitions/mgmLis3Helpers.h>
|
||||
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||
|
||||
@ -66,7 +67,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
||||
LocalDataPoolManager &poolManager) override;
|
||||
|
||||
private:
|
||||
MGMLIS3MDL::MgmPrimaryDataset dataset;
|
||||
mgmLis3::MgmPrimaryDataset dataset;
|
||||
// Length a single command SPI answer
|
||||
static const uint8_t SINGLE_COMMAND_ANSWER_LEN = 2;
|
||||
|
||||
@ -74,7 +75,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
||||
// Single SPI command has 2 bytes, first for adress, second for content
|
||||
size_t singleComandSize = 2;
|
||||
// Has the size for all adresses of the lis3mdl + the continous write bit
|
||||
uint8_t commandBuffer[MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1];
|
||||
uint8_t commandBuffer[mgmLis3::NR_OF_DATA_AND_CFG_REGISTERS + 1];
|
||||
|
||||
float absLimitX = 100;
|
||||
float absLimitY = 100;
|
||||
@ -85,7 +86,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
||||
* registers when we want to change something.
|
||||
* --> everytime we change set a register we have to save it
|
||||
*/
|
||||
uint8_t registers[MGMLIS3MDL::NR_OF_CTRL_REGISTERS];
|
||||
uint8_t registers[mgmLis3::NR_OF_CTRL_REGISTERS];
|
||||
|
||||
uint8_t statusRegister = 0;
|
||||
bool goToNormalMode = false;
|
||||
@ -107,35 +108,6 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Device specific commands and variables */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Sets the read bit for the command
|
||||
* @param single command to set the read-bit at
|
||||
* @param boolean to select a continuous read bit, default = false
|
||||
*/
|
||||
uint8_t readCommand(uint8_t command, bool continuousCom = false);
|
||||
|
||||
/**
|
||||
* Sets the write bit for the command
|
||||
* @param single command to set the write-bit at
|
||||
* @param boolean to select a continuous write bit, default = false
|
||||
*/
|
||||
uint8_t writeCommand(uint8_t command, bool continuousCom = false);
|
||||
|
||||
/**
|
||||
* This Method gets the full scale for the measurement range
|
||||
* e.g.: +- 4 gauss. See p.25 datasheet.
|
||||
* @return The ReturnValue does not contain the sign of the value
|
||||
*/
|
||||
MGMLIS3MDL::Sensitivies getSensitivity(uint8_t ctrlReg2);
|
||||
|
||||
/**
|
||||
* The 16 bit value needs to be multiplied with a sensitivity factor
|
||||
* which depends on the sensitivity configuration
|
||||
*
|
||||
* @param sens Configured sensitivity of the LIS3 device
|
||||
* @return Multiplication factor to get the sensor value from raw data.
|
||||
*/
|
||||
float getSensitivityFactor(MGMLIS3MDL::Sensitivies sens);
|
||||
|
||||
/**
|
||||
* This Command detects the device ID
|
||||
|
@ -63,21 +63,21 @@ ReturnValue_t MgmRM3100Handler::buildTransitionDeviceCommand(DeviceCommandId_t *
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
case (InternalState::CONFIGURE_CMM): {
|
||||
*id = RM3100::CONFIGURE_CMM;
|
||||
*id = mgmRm3100::CONFIGURE_CMM;
|
||||
break;
|
||||
}
|
||||
case (InternalState::READ_CMM): {
|
||||
*id = RM3100::READ_CMM;
|
||||
*id = mgmRm3100::READ_CMM;
|
||||
break;
|
||||
}
|
||||
case (InternalState::STATE_CONFIGURE_TMRC): {
|
||||
commandBuffer[0] = RM3100::TMRC_DEFAULT_VALUE;
|
||||
commandBuffer[0] = mgmRm3100::TMRC_DEFAULT_VALUE;
|
||||
commandLen = 1;
|
||||
*id = RM3100::CONFIGURE_TMRC;
|
||||
*id = mgmRm3100::CONFIGURE_TMRC;
|
||||
break;
|
||||
}
|
||||
case (InternalState::STATE_READ_TMRC): {
|
||||
*id = RM3100::READ_TMRC;
|
||||
*id = mgmRm3100::READ_TMRC;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -103,42 +103,42 @@ ReturnValue_t MgmRM3100Handler::buildCommandFromCommand(DeviceCommandId_t device
|
||||
const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
switch (deviceCommand) {
|
||||
case (RM3100::CONFIGURE_CMM): {
|
||||
commandBuffer[0] = RM3100::CMM_REGISTER;
|
||||
commandBuffer[1] = RM3100::CMM_VALUE;
|
||||
case (mgmRm3100::CONFIGURE_CMM): {
|
||||
commandBuffer[0] = mgmRm3100::CMM_REGISTER;
|
||||
commandBuffer[1] = mgmRm3100::CMM_VALUE;
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = 2;
|
||||
break;
|
||||
}
|
||||
case (RM3100::READ_CMM): {
|
||||
commandBuffer[0] = RM3100::CMM_REGISTER | RM3100::READ_MASK;
|
||||
case (mgmRm3100::READ_CMM): {
|
||||
commandBuffer[0] = mgmRm3100::CMM_REGISTER | mgmRm3100::READ_MASK;
|
||||
commandBuffer[1] = 0;
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = 2;
|
||||
break;
|
||||
}
|
||||
case (RM3100::CONFIGURE_TMRC): {
|
||||
case (mgmRm3100::CONFIGURE_TMRC): {
|
||||
return handleTmrcConfigCommand(deviceCommand, commandData, commandDataLen);
|
||||
}
|
||||
case (RM3100::READ_TMRC): {
|
||||
commandBuffer[0] = RM3100::TMRC_REGISTER | RM3100::READ_MASK;
|
||||
case (mgmRm3100::READ_TMRC): {
|
||||
commandBuffer[0] = mgmRm3100::TMRC_REGISTER | mgmRm3100::READ_MASK;
|
||||
commandBuffer[1] = 0;
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = 2;
|
||||
break;
|
||||
}
|
||||
case (RM3100::CONFIGURE_CYCLE_COUNT): {
|
||||
case (mgmRm3100::CONFIGURE_CYCLE_COUNT): {
|
||||
return handleCycleCountConfigCommand(deviceCommand, commandData, commandDataLen);
|
||||
}
|
||||
case (RM3100::READ_CYCLE_COUNT): {
|
||||
commandBuffer[0] = RM3100::CYCLE_COUNT_START_REGISTER | RM3100::READ_MASK;
|
||||
case (mgmRm3100::READ_CYCLE_COUNT): {
|
||||
commandBuffer[0] = mgmRm3100::CYCLE_COUNT_START_REGISTER | mgmRm3100::READ_MASK;
|
||||
std::memset(commandBuffer + 1, 0, 6);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = 7;
|
||||
break;
|
||||
}
|
||||
case (RM3100::READ_DATA): {
|
||||
commandBuffer[0] = RM3100::MEASUREMENT_REG_START | RM3100::READ_MASK;
|
||||
case (mgmRm3100::READ_DATA): {
|
||||
commandBuffer[0] = mgmRm3100::MEASUREMENT_REG_START | mgmRm3100::READ_MASK;
|
||||
std::memset(commandBuffer + 1, 0, 9);
|
||||
rawPacketLen = 10;
|
||||
break;
|
||||
@ -150,7 +150,7 @@ ReturnValue_t MgmRM3100Handler::buildCommandFromCommand(DeviceCommandId_t device
|
||||
}
|
||||
|
||||
ReturnValue_t MgmRM3100Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
||||
*id = RM3100::READ_DATA;
|
||||
*id = mgmRm3100::READ_DATA;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
|
||||
@ -165,16 +165,16 @@ ReturnValue_t MgmRM3100Handler::scanForReply(const uint8_t *start, size_t len,
|
||||
ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
switch (id) {
|
||||
case (RM3100::CONFIGURE_CMM):
|
||||
case (RM3100::CONFIGURE_CYCLE_COUNT):
|
||||
case (RM3100::CONFIGURE_TMRC): {
|
||||
case (mgmRm3100::CONFIGURE_CMM):
|
||||
case (mgmRm3100::CONFIGURE_CYCLE_COUNT):
|
||||
case (mgmRm3100::CONFIGURE_TMRC): {
|
||||
// We can only check whether write was successful with read operation
|
||||
if (getMode() == _MODE_START_UP) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (RM3100::READ_CMM): {
|
||||
case (mgmRm3100::READ_CMM): {
|
||||
uint8_t cmmValue = packet[1];
|
||||
// We clear the seventh bit in any case
|
||||
// because this one is zero sometimes for some reason
|
||||
@ -188,7 +188,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (RM3100::READ_TMRC): {
|
||||
case (mgmRm3100::READ_TMRC): {
|
||||
if (packet[1] == tmrcRegValue) {
|
||||
commandExecuted = true;
|
||||
// Reading TMRC was commanded. Trigger event to inform ground
|
||||
@ -202,7 +202,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (RM3100::READ_CYCLE_COUNT): {
|
||||
case (mgmRm3100::READ_CYCLE_COUNT): {
|
||||
uint16_t cycleCountX = packet[1] << 8 | packet[2];
|
||||
uint16_t cycleCountY = packet[3] << 8 | packet[4];
|
||||
uint16_t cycleCountZ = packet[5] << 8 | packet[6];
|
||||
@ -217,7 +217,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (RM3100::READ_DATA): {
|
||||
case (mgmRm3100::READ_DATA): {
|
||||
result = handleDataReadout(packet);
|
||||
break;
|
||||
}
|
||||
@ -244,7 +244,7 @@ ReturnValue_t MgmRM3100Handler::handleCycleCountConfigCommand(DeviceCommandId_t
|
||||
return DeviceHandlerIF::INVALID_COMMAND_PARAMETER;
|
||||
}
|
||||
|
||||
commandBuffer[0] = RM3100::CYCLE_COUNT_VALUE;
|
||||
commandBuffer[0] = mgmRm3100::CYCLE_COUNT_VALUE;
|
||||
std::memcpy(commandBuffer + 1, &cycleCountRegValueX, 2);
|
||||
std::memcpy(commandBuffer + 3, &cycleCountRegValueY, 2);
|
||||
std::memcpy(commandBuffer + 5, &cycleCountRegValueZ, 2);
|
||||
@ -255,7 +255,7 @@ ReturnValue_t MgmRM3100Handler::handleCycleCountConfigCommand(DeviceCommandId_t
|
||||
|
||||
ReturnValue_t MgmRM3100Handler::handleCycleCommand(bool oneCycleValue, const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
RM3100::CycleCountCommand command(oneCycleValue);
|
||||
mgmRm3100::CycleCountCommand command(oneCycleValue);
|
||||
ReturnValue_t result =
|
||||
command.deSerialize(&commandData, &commandDataLen, SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
@ -284,7 +284,7 @@ ReturnValue_t MgmRM3100Handler::handleTmrcConfigCommand(DeviceCommandId_t device
|
||||
return DeviceHandlerIF::INVALID_COMMAND_PARAMETER;
|
||||
}
|
||||
|
||||
commandBuffer[0] = RM3100::TMRC_REGISTER;
|
||||
commandBuffer[0] = mgmRm3100::TMRC_REGISTER;
|
||||
commandBuffer[1] = commandData[0];
|
||||
tmrcRegValue = commandData[0];
|
||||
rawPacketLen = 2;
|
||||
@ -293,23 +293,23 @@ ReturnValue_t MgmRM3100Handler::handleTmrcConfigCommand(DeviceCommandId_t device
|
||||
}
|
||||
|
||||
void MgmRM3100Handler::fillCommandAndReplyMap() {
|
||||
insertInCommandAndReplyMap(RM3100::CONFIGURE_CMM, 3);
|
||||
insertInCommandAndReplyMap(RM3100::READ_CMM, 3);
|
||||
insertInCommandAndReplyMap(mgmRm3100::CONFIGURE_CMM, 3);
|
||||
insertInCommandAndReplyMap(mgmRm3100::READ_CMM, 3);
|
||||
|
||||
insertInCommandAndReplyMap(RM3100::CONFIGURE_TMRC, 3);
|
||||
insertInCommandAndReplyMap(RM3100::READ_TMRC, 3);
|
||||
insertInCommandAndReplyMap(mgmRm3100::CONFIGURE_TMRC, 3);
|
||||
insertInCommandAndReplyMap(mgmRm3100::READ_TMRC, 3);
|
||||
|
||||
insertInCommandAndReplyMap(RM3100::CONFIGURE_CYCLE_COUNT, 3);
|
||||
insertInCommandAndReplyMap(RM3100::READ_CYCLE_COUNT, 3);
|
||||
insertInCommandAndReplyMap(mgmRm3100::CONFIGURE_CYCLE_COUNT, 3);
|
||||
insertInCommandAndReplyMap(mgmRm3100::READ_CYCLE_COUNT, 3);
|
||||
|
||||
insertInCommandAndReplyMap(RM3100::READ_DATA, 3, &primaryDataset);
|
||||
insertInCommandAndReplyMap(mgmRm3100::READ_DATA, 3, &primaryDataset);
|
||||
}
|
||||
|
||||
void MgmRM3100Handler::modeChanged() { internalState = InternalState::NONE; }
|
||||
|
||||
ReturnValue_t MgmRM3100Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(RM3100::FIELD_STRENGTHS, &mgmXYZ);
|
||||
localDataPoolMap.emplace(mgmRm3100::FIELD_STRENGTHS, &mgmXYZ);
|
||||
poolManager.subscribeForRegularPeriodicPacket({primaryDataset.getSid(), false, 10.0});
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
#ifndef MISSION_DEVICES_MGMRM3100HANDLER_H_
|
||||
#define MISSION_DEVICES_MGMRM3100HANDLER_H_
|
||||
|
||||
#include "devicedefinitions/MgmRM3100HandlerDefs.h"
|
||||
#include <fsfw_hal/devicehandlers/devicedefinitions/mgmRm3100Helpers.h>
|
||||
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||
|
||||
@ -69,19 +70,19 @@ class MgmRM3100Handler : public DeviceHandlerBase {
|
||||
};
|
||||
InternalState internalState = InternalState::NONE;
|
||||
bool commandExecuted = false;
|
||||
RM3100::Rm3100PrimaryDataset primaryDataset;
|
||||
mgmRm3100::Rm3100PrimaryDataset primaryDataset;
|
||||
|
||||
uint8_t commandBuffer[10];
|
||||
uint8_t commandBufferLen = 0;
|
||||
|
||||
uint8_t cmmRegValue = RM3100::CMM_VALUE;
|
||||
uint8_t tmrcRegValue = RM3100::TMRC_DEFAULT_VALUE;
|
||||
uint16_t cycleCountRegValueX = RM3100::CYCLE_COUNT_VALUE;
|
||||
uint16_t cycleCountRegValueY = RM3100::CYCLE_COUNT_VALUE;
|
||||
uint16_t cycleCountRegValueZ = RM3100::CYCLE_COUNT_VALUE;
|
||||
float scaleFactorX = 1.0 / RM3100::DEFAULT_GAIN;
|
||||
float scaleFactorY = 1.0 / RM3100::DEFAULT_GAIN;
|
||||
float scaleFactorZ = 1.0 / RM3100::DEFAULT_GAIN;
|
||||
uint8_t cmmRegValue = mgmRm3100::CMM_VALUE;
|
||||
uint8_t tmrcRegValue = mgmRm3100::TMRC_DEFAULT_VALUE;
|
||||
uint16_t cycleCountRegValueX = mgmRm3100::CYCLE_COUNT_VALUE;
|
||||
uint16_t cycleCountRegValueY = mgmRm3100::CYCLE_COUNT_VALUE;
|
||||
uint16_t cycleCountRegValueZ = mgmRm3100::CYCLE_COUNT_VALUE;
|
||||
float scaleFactorX = 1.0 / mgmRm3100::DEFAULT_GAIN;
|
||||
float scaleFactorY = 1.0 / mgmRm3100::DEFAULT_GAIN;
|
||||
float scaleFactorZ = 1.0 / mgmRm3100::DEFAULT_GAIN;
|
||||
|
||||
bool goToNormalModeAtStartup = false;
|
||||
uint32_t transitionDelay;
|
||||
|
@ -0,0 +1 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE gyroL3gHelpers.cpp mgmLis3Helpers.cpp)
|
@ -0,0 +1,14 @@
|
||||
#include <fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h>
|
||||
|
||||
float l3gd20h::ctrlReg4ToSensitivity(uint8_t reg) {
|
||||
bool fsH = reg & l3gd20h::SET_FS_1;
|
||||
bool fsL = reg & l3gd20h::SET_FS_0;
|
||||
|
||||
if (not fsH and not fsL) {
|
||||
return l3gd20h::SENSITIVITY_00;
|
||||
} else if (not fsH and fsL) {
|
||||
return l3gd20h::SENSITIVITY_01;
|
||||
} else {
|
||||
return l3gd20h::SENSITIVITY_11;
|
||||
}
|
||||
}
|
@ -6,7 +6,9 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace L3GD20H {
|
||||
namespace l3gd20h {
|
||||
|
||||
float ctrlReg4ToSensitivity(uint8_t reg);
|
||||
|
||||
/* Actual size is 15 but we round up a bit */
|
||||
static constexpr size_t MAX_BUFFER_SIZE = 16;
|
||||
@ -103,31 +105,33 @@ static constexpr DeviceCommandId_t READ_REGS = 0;
|
||||
static constexpr DeviceCommandId_t CONFIGURE_CTRL_REGS = 1;
|
||||
static constexpr DeviceCommandId_t READ_CTRL_REGS = 2;
|
||||
|
||||
static constexpr DeviceCommandId_t REQUEST = 0x70;
|
||||
static constexpr DeviceCommandId_t REPLY = 0x77;
|
||||
|
||||
static constexpr uint32_t GYRO_DATASET_ID = READ_REGS;
|
||||
|
||||
enum GyroPoolIds : lp_id_t { ANG_VELOC_X, ANG_VELOC_Y, ANG_VELOC_Z, TEMPERATURE };
|
||||
|
||||
} // namespace L3GD20H
|
||||
} // namespace l3gd20h
|
||||
|
||||
class GyroPrimaryDataset : public StaticLocalDataSet<5> {
|
||||
public:
|
||||
/** Constructor for data users like controllers */
|
||||
GyroPrimaryDataset(object_id_t mgmId)
|
||||
: StaticLocalDataSet(sid_t(mgmId, L3GD20H::GYRO_DATASET_ID)) {
|
||||
: StaticLocalDataSet(sid_t(mgmId, l3gd20h::GYRO_DATASET_ID)) {
|
||||
setAllVariablesReadOnly();
|
||||
}
|
||||
|
||||
/* Angular velocities in degrees per second (DPS) */
|
||||
lp_var_t<float> angVelocX = lp_var_t<float>(sid.objectId, L3GD20H::ANG_VELOC_X, this);
|
||||
lp_var_t<float> angVelocY = lp_var_t<float>(sid.objectId, L3GD20H::ANG_VELOC_Y, this);
|
||||
lp_var_t<float> angVelocZ = lp_var_t<float>(sid.objectId, L3GD20H::ANG_VELOC_Z, this);
|
||||
lp_var_t<float> temperature = lp_var_t<float>(sid.objectId, L3GD20H::TEMPERATURE, this);
|
||||
|
||||
private:
|
||||
friend class GyroHandlerL3GD20H;
|
||||
/** Constructor for the data creator */
|
||||
GyroPrimaryDataset(HasLocalDataPoolIF* hkOwner)
|
||||
: StaticLocalDataSet(hkOwner, L3GD20H::GYRO_DATASET_ID) {}
|
||||
: StaticLocalDataSet(hkOwner, l3gd20h::GYRO_DATASET_ID) {}
|
||||
|
||||
/* Angular velocities in degrees per second (DPS) */
|
||||
lp_var_t<float> angVelocX = lp_var_t<float>(sid.objectId, l3gd20h::ANG_VELOC_X, this);
|
||||
lp_var_t<float> angVelocY = lp_var_t<float>(sid.objectId, l3gd20h::ANG_VELOC_Y, this);
|
||||
lp_var_t<float> angVelocZ = lp_var_t<float>(sid.objectId, l3gd20h::ANG_VELOC_Z, this);
|
||||
lp_var_t<float> temperature = lp_var_t<float>(sid.objectId, l3gd20h::TEMPERATURE, this);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_GYROL3GD20DEFINITIONS_H_ */
|
@ -0,0 +1,52 @@
|
||||
#include "mgmLis3Helpers.h"
|
||||
|
||||
uint8_t mgmLis3::readCommand(uint8_t command, bool continuousCom) {
|
||||
command |= (1 << mgmLis3::RW_BIT);
|
||||
if (continuousCom == true) {
|
||||
command |= (1 << mgmLis3::MS_BIT);
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
uint8_t mgmLis3::writeCommand(uint8_t command, bool continuousCom) {
|
||||
command &= ~(1 << mgmLis3::RW_BIT);
|
||||
if (continuousCom == true) {
|
||||
command |= (1 << mgmLis3::MS_BIT);
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
mgmLis3::Sensitivies mgmLis3::getSensitivity(uint8_t ctrlRegister2) {
|
||||
bool fs0Set = ctrlRegister2 & (1 << mgmLis3::FSO); // Checks if FS0 bit is set
|
||||
bool fs1Set = ctrlRegister2 & (1 << mgmLis3::FS1); // Checks if FS1 bit is set
|
||||
|
||||
if (fs0Set && fs1Set)
|
||||
return mgmLis3::Sensitivies::GAUSS_16;
|
||||
else if (!fs0Set && fs1Set)
|
||||
return mgmLis3::Sensitivies::GAUSS_12;
|
||||
else if (fs0Set && !fs1Set)
|
||||
return mgmLis3::Sensitivies::GAUSS_8;
|
||||
else
|
||||
return mgmLis3::Sensitivies::GAUSS_4;
|
||||
}
|
||||
|
||||
float mgmLis3::getSensitivityFactor(mgmLis3::Sensitivies sens) {
|
||||
switch (sens) {
|
||||
case (mgmLis3::GAUSS_4): {
|
||||
return mgmLis3::FIELD_LSB_PER_GAUSS_4_SENS;
|
||||
}
|
||||
case (mgmLis3::GAUSS_8): {
|
||||
return mgmLis3::FIELD_LSB_PER_GAUSS_8_SENS;
|
||||
}
|
||||
case (mgmLis3::GAUSS_12): {
|
||||
return mgmLis3::FIELD_LSB_PER_GAUSS_12_SENS;
|
||||
}
|
||||
case (mgmLis3::GAUSS_16): {
|
||||
return mgmLis3::FIELD_LSB_PER_GAUSS_16_SENS;
|
||||
}
|
||||
default: {
|
||||
// Should never happen
|
||||
return mgmLis3::FIELD_LSB_PER_GAUSS_4_SENS;
|
||||
}
|
||||
}
|
||||
}
|
@ -7,13 +7,43 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace MGMLIS3MDL {
|
||||
namespace mgmLis3 {
|
||||
|
||||
enum Set { ON, OFF };
|
||||
enum OpMode { LOW, MEDIUM, HIGH, ULTRA };
|
||||
|
||||
enum Sensitivies : uint8_t { GAUSS_4 = 4, GAUSS_8 = 8, GAUSS_12 = 12, GAUSS_16 = 16 };
|
||||
|
||||
/**
|
||||
* Sets the read bit for the command
|
||||
* @param single command to set the read-bit at
|
||||
* @param boolean to select a continuous read bit, default = false
|
||||
*/
|
||||
uint8_t readCommand(uint8_t command, bool continuousCom = false);
|
||||
|
||||
/**
|
||||
* Sets the write bit for the command
|
||||
* @param single command to set the write-bit at
|
||||
* @param boolean to select a continuous write bit, default = false
|
||||
*/
|
||||
uint8_t writeCommand(uint8_t command, bool continuousCom = false);
|
||||
|
||||
/**
|
||||
* This Method gets the full scale for the measurement range
|
||||
* e.g.: +- 4 gauss. See p.25 datasheet.
|
||||
* @return The ReturnValue does not contain the sign of the value
|
||||
*/
|
||||
mgmLis3::Sensitivies getSensitivity(uint8_t ctrlReg2);
|
||||
|
||||
/**
|
||||
* The 16 bit value needs to be multiplied with a sensitivity factor
|
||||
* which depends on the sensitivity configuration
|
||||
*
|
||||
* @param sens Configured sensitivity of the LIS3 device
|
||||
* @return Multiplication factor to get the sensor value from raw data.
|
||||
*/
|
||||
float getSensitivityFactor(mgmLis3::Sensitivies sens);
|
||||
|
||||
/* Actually 15, we just round up a bit */
|
||||
static constexpr size_t MAX_BUFFER_SIZE = 16;
|
||||
|
||||
@ -154,6 +184,6 @@ class MgmPrimaryDataset : public StaticLocalDataSet<4> {
|
||||
lp_var_t<float> temperature = lp_var_t<float>(sid.objectId, TEMPERATURE_CELCIUS, this);
|
||||
};
|
||||
|
||||
} // namespace MGMLIS3MDL
|
||||
} // namespace mgmLis3
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_MGMLIS3HANDLERDEFS_H_ */
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace RM3100 {
|
||||
namespace mgmRm3100 {
|
||||
|
||||
/* Actually 10, we round up a little bit */
|
||||
static constexpr size_t MAX_BUFFER_SIZE = 12;
|
||||
@ -115,6 +115,6 @@ class Rm3100PrimaryDataset : public StaticLocalDataSet<3> {
|
||||
lp_vec_t<float, 3> fieldStrengths = lp_vec_t<float, 3>(sid.objectId, FIELD_STRENGTHS, this);
|
||||
};
|
||||
|
||||
} // namespace RM3100
|
||||
} // namespace mgmRm3100
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_MGMHANDLERRM3100DEFINITIONS_H_ */
|
@ -160,3 +160,18 @@ ReturnValue_t HostFilesystem::truncateFile(FilesystemParams params) {
|
||||
ofstream of(path);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
bool HostFilesystem::isDirectory(const char *path) { return filesystem::is_directory(path); }
|
||||
|
||||
ReturnValue_t HostFilesystem::getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
|
||||
size_t &baseNameLen) {
|
||||
std::string path(params.path);
|
||||
std::string baseName = path.substr(path.find_last_of("/\\") + 1);
|
||||
if (baseName.size() + 1 > maxLen) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
std::memcpy(nameBuf, baseName.c_str(), baseName.size());
|
||||
nameBuf[baseName.size()] = '\0';
|
||||
baseNameLen = baseName.size();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -9,6 +9,9 @@ class HostFilesystem : public HasFileSystemIF {
|
||||
public:
|
||||
HostFilesystem();
|
||||
|
||||
ReturnValue_t getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
|
||||
size_t &baseNameLen) override;
|
||||
bool isDirectory(const char *path) override;
|
||||
bool fileExists(FilesystemParams params) override;
|
||||
ReturnValue_t truncateFile(FilesystemParams params) override;
|
||||
ReturnValue_t writeToFile(FileOpParams params, const uint8_t *data) override;
|
||||
|
@ -6,14 +6,11 @@
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
UnixFileGuard::UnixFileGuard(const std::string& device, int* fileDescriptor, int flags,
|
||||
UnixFileGuard::UnixFileGuard(const std::string& device, int& fileDescriptor, int flags,
|
||||
std::string diagnosticPrefix)
|
||||
: fileDescriptor(fileDescriptor) {
|
||||
if (fileDescriptor == nullptr) {
|
||||
return;
|
||||
}
|
||||
*fileDescriptor = open(device.c_str(), flags);
|
||||
if (*fileDescriptor < 0) {
|
||||
: fdRef(fileDescriptor) {
|
||||
fileDescriptor = open(device.c_str(), flags);
|
||||
if (fileDescriptor < 0) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << diagnosticPrefix << ": Opening device failed with error code " << errno << ": "
|
||||
@ -27,10 +24,6 @@ UnixFileGuard::UnixFileGuard(const std::string& device, int* fileDescriptor, int
|
||||
}
|
||||
}
|
||||
|
||||
UnixFileGuard::~UnixFileGuard() {
|
||||
if (fileDescriptor != nullptr) {
|
||||
close(*fileDescriptor);
|
||||
}
|
||||
}
|
||||
UnixFileGuard::~UnixFileGuard() { close(fdRef); }
|
||||
|
||||
ReturnValue_t UnixFileGuard::getOpenResult() const { return openStatus; }
|
||||
|
@ -15,7 +15,15 @@ class UnixFileGuard {
|
||||
|
||||
static constexpr ReturnValue_t OPEN_FILE_FAILED = 1;
|
||||
|
||||
UnixFileGuard(const std::string& device, int* fileDescriptor, int flags,
|
||||
/**
|
||||
* Open a device and assign the given file descriptor variable
|
||||
* @param device [in] Device name.
|
||||
* @param fileDescriptor [in/out] Will be assigned by file guard and re-used to
|
||||
* close the guard.
|
||||
* @param flags
|
||||
* @param diagnosticPrefix
|
||||
*/
|
||||
UnixFileGuard(const std::string& device, int& fileDescriptor, int flags,
|
||||
std::string diagnosticPrefix = "");
|
||||
|
||||
virtual ~UnixFileGuard();
|
||||
@ -23,7 +31,7 @@ class UnixFileGuard {
|
||||
ReturnValue_t getOpenResult() const;
|
||||
|
||||
private:
|
||||
int* fileDescriptor = nullptr;
|
||||
int& fdRef;
|
||||
ReturnValue_t openStatus = returnvalue::OK;
|
||||
};
|
||||
|
||||
|
@ -66,8 +66,7 @@ ReturnValue_t I2cComIF::initializeInterface(CookieIF* cookie) {
|
||||
|
||||
ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
|
||||
ReturnValue_t result;
|
||||
int fd;
|
||||
std::string deviceFile;
|
||||
int fd = 0;
|
||||
|
||||
if (sendData == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -98,12 +97,12 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
deviceFile = i2cCookie->getDeviceFile();
|
||||
UnixFileGuard fileHelper(deviceFile, &fd, O_RDWR, "I2cComIF::sendMessage");
|
||||
const auto& deviceFile = i2cCookie->getDeviceFile();
|
||||
UnixFileGuard fileHelper(deviceFile, fd, O_RDWR, "I2cComIF::sendMessage");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return fileHelper.getOpenResult();
|
||||
}
|
||||
result = openDevice(deviceFile, i2cAddress, &fd);
|
||||
result = openI2cSlave(deviceFile, i2cAddress, fd);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
@ -131,8 +130,7 @@ ReturnValue_t I2cComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::O
|
||||
|
||||
ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
||||
ReturnValue_t result;
|
||||
int fd;
|
||||
std::string deviceFile;
|
||||
int fd = 0;
|
||||
|
||||
if (requestLen == 0) {
|
||||
return returnvalue::OK;
|
||||
@ -157,12 +155,12 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
}
|
||||
i2cDeviceMapIter->second.replyLen = 0;
|
||||
|
||||
deviceFile = i2cCookie->getDeviceFile();
|
||||
UnixFileGuard fileHelper(deviceFile, &fd, O_RDWR, "I2cComIF::requestReceiveMessage");
|
||||
auto& deviceFile = i2cCookie->getDeviceFile();
|
||||
UnixFileGuard fileHelper(deviceFile, fd, O_RDWR, "I2cComIF::requestReceiveMessage");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return fileHelper.getOpenResult();
|
||||
}
|
||||
result = openDevice(deviceFile, i2cAddress, &fd);
|
||||
result = openI2cSlave(deviceFile, i2cAddress, fd);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
@ -220,9 +218,9 @@ ReturnValue_t I2cComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t I2cComIF::openDevice(std::string deviceFile, address_t i2cAddress,
|
||||
int* fileDescriptor) {
|
||||
if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) {
|
||||
ReturnValue_t I2cComIF::openI2cSlave(const std::string& deviceFile, address_t i2cAddress,
|
||||
int& fileDescriptor) {
|
||||
if (ioctl(fileDescriptor, I2C_SLAVE, i2cAddress) < 0) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "I2cComIF: Specifying target device failed with error code " << errno << "."
|
||||
|
@ -49,7 +49,8 @@ class I2cComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
* @param fileDescriptor Pointer to device descriptor.
|
||||
* @return returnvalue::OK if successful, otherwise returnvalue::FAILED.
|
||||
*/
|
||||
ReturnValue_t openDevice(std::string deviceFile, address_t i2cAddress, int *fileDescriptor);
|
||||
ReturnValue_t openI2cSlave(const std::string &deviceFile, address_t i2cAddress,
|
||||
int &fileDescriptor);
|
||||
};
|
||||
|
||||
#endif /* LINUX_I2C_I2COMIF_H_ */
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include "fsfw_hal/linux/i2c/I2cCookie.h"
|
||||
|
||||
I2cCookie::I2cCookie(address_t i2cAddress_, size_t maxReplyLen_, std::string deviceFile_)
|
||||
: i2cAddress(i2cAddress_), maxReplyLen(maxReplyLen_), deviceFile(deviceFile_) {}
|
||||
: i2cAddress(i2cAddress_), maxReplyLen(maxReplyLen_), deviceFile(std::move(deviceFile_)) {}
|
||||
|
||||
address_t I2cCookie::getAddress() const { return i2cAddress; }
|
||||
|
||||
size_t I2cCookie::getMaxReplyLen() const { return maxReplyLen; }
|
||||
|
||||
std::string I2cCookie::getDeviceFile() const { return deviceFile; }
|
||||
const std::string& I2cCookie::getDeviceFile() const { return deviceFile; }
|
||||
|
||||
I2cCookie::~I2cCookie() {}
|
||||
|
@ -25,7 +25,7 @@ class I2cCookie : public CookieIF {
|
||||
|
||||
address_t getAddress() const;
|
||||
size_t getMaxReplyLen() const;
|
||||
std::string getDeviceFile() const;
|
||||
const std::string& getDeviceFile() const;
|
||||
|
||||
uint8_t errorCounter = 0;
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fsfw_hal/linux/serial/SerialComIF.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
||||
|
||||
#include "fsfw/ipc/MutexIF.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
|
@ -75,7 +75,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) {
|
||||
spiCookie->getSpiParameters(spiMode, spiSpeed, ¶ms);
|
||||
|
||||
int fileDescriptor = 0;
|
||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
||||
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return fileHelper.getOpenResult();
|
||||
}
|
||||
@ -171,7 +171,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
int retval = 0;
|
||||
/* Prepare transfer */
|
||||
int fileDescriptor = 0;
|
||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return OPENING_FILE_FAILED;
|
||||
}
|
||||
@ -179,12 +179,11 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
uint32_t spiSpeed = 0;
|
||||
spiCookie->getSpiParameters(spiMode, spiSpeed, nullptr);
|
||||
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||
spiCookie->assignWriteBuffer(sendData);
|
||||
spiCookie->setTransferSize(sendLen);
|
||||
|
||||
bool fullDuplex = spiCookie->isFullDuplex();
|
||||
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
||||
bool csLockManual = spiCookie->getCsLockManual();
|
||||
spiCookie->setTransferSize(0);
|
||||
|
||||
MutexIF::TimeoutType csType;
|
||||
dur_millis_t csTimeout = 0;
|
||||
@ -195,9 +194,13 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
|
||||
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
|
||||
<< std::endl;
|
||||
if (result == MutexIF::MUTEX_TIMEOUT) {
|
||||
sif::error << "SpiComIF::sendMessage: Lock timeout" << std::endl;
|
||||
} else {
|
||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
|
||||
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
#else
|
||||
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
||||
#endif
|
||||
@ -214,17 +217,22 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
sif::printWarning("SpiComIF::sendMessage: Pulling low CS pin failed");
|
||||
#endif
|
||||
#endif
|
||||
csMutex->unlockMutex();
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
updateLinePolarity(fileDescriptor);
|
||||
}
|
||||
|
||||
spiCookie->assignWriteBuffer(sendData);
|
||||
spiCookie->setTransferSize(sendLen);
|
||||
|
||||
/* Execute transfer */
|
||||
if (fullDuplex) {
|
||||
/* Initiate a full duplex SPI transfer. */
|
||||
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle());
|
||||
if (retval < 0) {
|
||||
spiCookie->setTransferSize(0);
|
||||
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||
result = FULL_DUPLEX_TRANSFER_FAILED;
|
||||
}
|
||||
@ -234,6 +242,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
} else {
|
||||
/* We write with a blocking half-duplex transfer here */
|
||||
if (write(fileDescriptor, sendData, sendLen) != static_cast<ssize_t>(sendLen)) {
|
||||
spiCookie->setTransferSize(0);
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << std::endl;
|
||||
@ -276,7 +285,7 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
int fileDescriptor = 0;
|
||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
|
||||
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return OPENING_FILE_FAILED;
|
||||
}
|
||||
|
@ -90,8 +90,6 @@ class SpiComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
* pulled high
|
||||
*/
|
||||
MutexIF* csMutex = nullptr;
|
||||
// MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||
// uint32_t timeoutMs = DEFAULT_MUTEX_TIMEOUT;
|
||||
spi_ioc_transfer clockUpdateTransfer = {};
|
||||
|
||||
using SpiDeviceMap = std::unordered_map<address_t, SpiInstance>;
|
||||
|
@ -138,3 +138,10 @@ ReturnValue_t FilesystemMock::truncateFile(FilesystemParams params) {
|
||||
truncateCalledOnFile = params.path;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t FilesystemMock::getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
|
||||
size_t &baseNameLen) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
bool FilesystemMock::isDirectory(const char *path) { return false; }
|
||||
|
@ -56,6 +56,10 @@ class FilesystemMock : public HasFileSystemIF {
|
||||
std::string truncateCalledOnFile;
|
||||
ReturnValue_t feedFile(const std::string &filename, std::ifstream &file);
|
||||
|
||||
ReturnValue_t getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
|
||||
size_t &baseNameLen) override;
|
||||
|
||||
bool isDirectory(const char *path) override;
|
||||
bool fileExists(FilesystemParams params) override;
|
||||
ReturnValue_t truncateFile(FilesystemParams params) override;
|
||||
|
||||
|
Reference in New Issue
Block a user