Compare commits
35 Commits
cf735143fe
...
move_seman
Author | SHA1 | Date | |
---|---|---|---|
6fa453940f | |||
9a8d775eb1 | |||
4d6f6e6b23 | |||
55f6825a03 | |||
c162acb7df | |||
87462afe6d | |||
a8de395ea0 | |||
f0bddfcb21 | |||
23d9b44b3e | |||
26e4445189 | |||
9ee3cdf729 | |||
1b7493f945 | |||
7f6ba5f40b | |||
070b48ada2 | |||
d9a139e1ef | |||
c80a3752d9 | |||
af58c414fc | |||
4c48668125 | |||
2745b2080d | |||
e9d9f44605 | |||
2c5af91db1 | |||
5cd7b98ba7 | |||
a39f1271ec | |||
bbf0d7a0d2 | |||
04ee3c7362 | |||
95dab69b35 | |||
33de15205b | |||
4d353a1ad2 | |||
6006c97e48 | |||
6e17e45506 | |||
64537d442a | |||
78cf00315d | |||
245886c555 | |||
f84097543e | |||
511d07c0c7 |
@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Fixes
|
||||
|
||||
- Add monotonic watchdog Clock API and use it in `Countdown` and `Stopwatch` class.
|
||||
- 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
|
||||
|
@ -565,6 +565,9 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
*/
|
||||
if (newMode == MODE_ON and continueToNormal) {
|
||||
continueToNormal = false;
|
||||
// TODO: Check whether the following two lines are okay to do so.
|
||||
transitionSourceMode = MODE_ON;
|
||||
transitionSourceSubMode = submode;
|
||||
mode = _MODE_TO_NORMAL;
|
||||
return;
|
||||
}
|
||||
|
@ -15,12 +15,12 @@ const LocalPool::LocalPoolConfig EventManager::poolConfig = {
|
||||
{fsfwconfig::FSFW_EVENTMGMT_EVENTIDMATCHERS, sizeof(EventIdRangeMatcher)},
|
||||
{fsfwconfig::FSFW_EVENTMGMR_RANGEMATCHERS, sizeof(ReporterRangeMatcher)}};
|
||||
|
||||
EventManager::EventManager(object_id_t setObjectId)
|
||||
EventManager::EventManager(object_id_t setObjectId, uint32_t eventQueueDepth)
|
||||
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(
|
||||
MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
eventQueueDepth, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
}
|
||||
|
||||
EventManager::~EventManager() {
|
||||
|
@ -21,9 +21,9 @@ extern const char* translateEvents(Event event);
|
||||
|
||||
class EventManager : public EventManagerIF, public ExecutableObjectIF, public SystemObject {
|
||||
public:
|
||||
static const uint16_t MAX_EVENTS_PER_CYCLE = 80;
|
||||
static const uint16_t DEFAULT_MAX_EVENTS_PER_CYCLE = 80;
|
||||
|
||||
EventManager(object_id_t setObjectId);
|
||||
EventManager(object_id_t setObjectId, uint32_t eventQueueDepth);
|
||||
virtual ~EventManager();
|
||||
|
||||
void setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs);
|
||||
|
@ -68,7 +68,7 @@ ReturnValue_t FaultCounter::getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
parameterWrapper->set(faultCount);
|
||||
break;
|
||||
case ParameterIds::TIMEOUT:
|
||||
parameterWrapper->set(timer.timeout);
|
||||
parameterWrapper->set(timer.getTimeoutMs());
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
|
@ -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;
|
||||
@ -23,11 +26,11 @@ class MutexGuard {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
if (result == MutexIF::MUTEX_TIMEOUT) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "MutexGuard: Lock of mutex failed with timeout of " << timeoutMs
|
||||
<< " milliseconds!" << std::endl;
|
||||
sif::error << "MutexGuard::" << context << ": Lock of mutex failed with timeout of "
|
||||
<< timeoutMs << " milliseconds!" << std::endl;
|
||||
#else
|
||||
sif::printError("MutexGuard: Lock of mutex failed with timeout of %lu milliseconds\n",
|
||||
timeoutMs);
|
||||
sif::printError("MutexGuard::%s: Lock of mutex failed with timeout of %lu milliseconds\n",
|
||||
context, timeoutMs);
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
|
||||
} else if (result != returnvalue::OK) {
|
||||
|
@ -16,9 +16,9 @@
|
||||
|
||||
#endif
|
||||
|
||||
TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId,
|
||||
object_id_t tcStoreId)
|
||||
: TmTcBridge("TCP TMTC Bridge", objectId, tcDestination, tmStoreId, tcStoreId) {
|
||||
TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
|
||||
uint32_t msgQueueDepth, object_id_t tmStoreId, object_id_t tcStoreId)
|
||||
: TmTcBridge("TCP TMTC Bridge", objectId, tcDestination, msgQueueDepth, tmStoreId, tcStoreId) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
// Connection is always up, TM is requested by connecting to server and receiving packets
|
||||
registerCommConnect();
|
||||
|
@ -38,7 +38,7 @@ class TcpTmTcBridge : public TmTcBridge {
|
||||
* @param tmStoreId TM store object ID. It is recommended to the default object ID
|
||||
* @param tcStoreId TC store object ID. It is recommended to the default object ID
|
||||
*/
|
||||
TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
|
||||
TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, uint32_t msgQueueDepth,
|
||||
object_id_t tmStoreId = objects::TM_STORE,
|
||||
object_id_t tcStoreId = objects::TC_STORE);
|
||||
virtual ~TcpTmTcBridge();
|
||||
|
@ -20,9 +20,9 @@
|
||||
const std::string UdpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
|
||||
|
||||
UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
|
||||
const std::string &udpServerPort_, object_id_t tmStoreId,
|
||||
object_id_t tcStoreId)
|
||||
: TmTcBridge("UDP TMTC Bridge", objectId, tcDestination, tmStoreId, tcStoreId) {
|
||||
uint32_t msgQueueDepth, const std::string &udpServerPort_,
|
||||
object_id_t tmStoreId, object_id_t tcStoreId)
|
||||
: TmTcBridge("UDP TMTC Bridge", objectId, tcDestination, msgQueueDepth, tmStoreId, tcStoreId) {
|
||||
if (udpServerPort_.empty()) {
|
||||
udpServerPort = DEFAULT_SERVER_PORT;
|
||||
} else {
|
||||
|
@ -29,7 +29,7 @@ class UdpTmTcBridge : public TmTcBridge, public TcpIpBase {
|
||||
/* The ports chosen here should not be used by any other process. */
|
||||
static const std::string DEFAULT_SERVER_PORT;
|
||||
|
||||
UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
|
||||
UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, uint32_t msgQueueDepth,
|
||||
const std::string& udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE,
|
||||
object_id_t tcStoreId = objects::TC_STORE);
|
||||
~UdpTmTcBridge() override;
|
||||
|
@ -47,7 +47,32 @@ ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
ReturnValue_t Clock::getClockMonotonic(timeval* time) {
|
||||
#if defined(PLATFORM_WIN)
|
||||
// TODO: Implement with std::chrono::steady_clock.. or in some other way. I am not even sure
|
||||
// whether this is possible with steady_clock. The conversion we have to do here just to be
|
||||
// generic is kind of awkward..
|
||||
return returnvalue::FAILED;
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
timespec timeMonotonic;
|
||||
int status = clock_gettime(CLOCK_MONOTONIC_RAW, &timeMonotonic);
|
||||
if (status != 0) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
time->tv_sec = timeMonotonic.tv_sec;
|
||||
time->tv_usec = timeMonotonic.tv_nsec / 1000.0;
|
||||
return returnvalue::OK;
|
||||
#else
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Clock::getUptime: Not implemented for found OS!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("Clock::getUptime: Not implemented for found OS!\n");
|
||||
#endif
|
||||
return returnvalue::FAILED;
|
||||
#endif
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock(timeval* time) {
|
||||
#if defined(PLATFORM_WIN)
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto secondsChrono = std::chrono::time_point_cast<std::chrono::seconds>(now);
|
||||
@ -75,6 +100,8 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
#endif
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_timeval(timeval* time) { return Clock::getClock(time); }
|
||||
|
||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
if (time == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
|
@ -42,7 +42,7 @@ ReturnValue_t Clock::setClock(const timeval* time) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
ReturnValue_t Clock::getClock(timeval* time) {
|
||||
timespec timeUnix{};
|
||||
int status = clock_gettime(CLOCK_REALTIME, &timeUnix);
|
||||
if (status != 0) {
|
||||
@ -53,6 +53,8 @@ ReturnValue_t Clock::getClock_timeval(timeval* time) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClock_timeval(timeval* time) { return Clock::getClock(time); }
|
||||
|
||||
ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
timeval timeVal{};
|
||||
ReturnValue_t result = getClock_timeval(&timeVal);
|
||||
@ -64,6 +66,17 @@ ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getClockMonotonic(timeval* time) {
|
||||
timespec timeMonotonic{};
|
||||
int status = clock_gettime(CLOCK_MONOTONIC_RAW, &timeMonotonic);
|
||||
if (status != 0) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
time->tv_sec = timeMonotonic.tv_sec;
|
||||
time->tv_usec = timeMonotonic.tv_nsec / 1000.0;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
timeval Clock::getUptime() {
|
||||
timeval uptime{};
|
||||
auto result = getUptime(&uptime);
|
||||
@ -79,11 +92,16 @@ ReturnValue_t Clock::getUptime(timeval* uptime) {
|
||||
// TODO This is not posix compatible and delivers only seconds precision
|
||||
// Linux specific file read but more precise.
|
||||
double uptimeSeconds;
|
||||
if (std::ifstream("/proc/uptime", std::ios::in) >> uptimeSeconds) {
|
||||
std::ifstream ifile("/proc/uptime");
|
||||
if (ifile.bad()) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (ifile >> uptimeSeconds) {
|
||||
uptime->tv_sec = uptimeSeconds;
|
||||
uptime->tv_usec = uptimeSeconds * (double)1e6 - (uptime->tv_sec * 1e6);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
// Wait for new FSFW Clock function delivering seconds uptime.
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "DummyPowerSwitcher.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
DummyPowerSwitcher::DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwitches,
|
||||
size_t numberOfFuses, bool registerGlobally,
|
||||
uint32_t switchDelayMs)
|
||||
@ -9,11 +11,11 @@ DummyPowerSwitcher::DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwit
|
||||
switchDelayMs(switchDelayMs) {}
|
||||
|
||||
void DummyPowerSwitcher::setInitialSwitcherList(std::vector<ReturnValue_t> switcherList) {
|
||||
this->switcherList = switcherList;
|
||||
this->switcherList = std::move(switcherList);
|
||||
}
|
||||
|
||||
void DummyPowerSwitcher::setInitialFusesList(std::vector<ReturnValue_t> fuseList) {
|
||||
this->fuseList = fuseList;
|
||||
this->fuseList = std::move(fuseList);
|
||||
}
|
||||
|
||||
ReturnValue_t DummyPowerSwitcher::sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) {
|
||||
|
@ -68,6 +68,9 @@ ReturnValue_t CServiceHealthCommanding::prepareCommand(CommandMessage *message,
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
switch (subservice) {
|
||||
case (Subservice::COMMAND_SET_HEALTH): {
|
||||
if (tcDataLen != sizeof(object_id_t) + sizeof(HasHealthIF::HealthState)) {
|
||||
return CommandingServiceBase::INVALID_TC;
|
||||
}
|
||||
HealthSetCommand healthCommand;
|
||||
result = healthCommand.deSerialize(&tcData, &tcDataLen, SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -21,6 +21,7 @@ SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(c
|
||||
|
||||
ReturnValue_t SubsystemBase::checkStateAgainstTable(HybridIterator<ModeListEntry> tableIter,
|
||||
Submode_t targetSubmode) {
|
||||
using namespace mode;
|
||||
std::map<object_id_t, ChildInfo>::iterator childIter;
|
||||
|
||||
for (; tableIter.value != NULL; ++tableIter) {
|
||||
@ -34,13 +35,21 @@ ReturnValue_t SubsystemBase::checkStateAgainstTable(HybridIterator<ModeListEntry
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
Submode_t submodeToCheckAgainst = tableIter.value->getSubmode();
|
||||
// Check submodes here.
|
||||
uint8_t mask;
|
||||
bool submodesAllowedMask = tableIter.value->submodesAllowed(&mask);
|
||||
uint8_t submodeToCheckAgainst = tableIter.value->getSubmode();
|
||||
if (tableIter.value->inheritSubmode()) {
|
||||
submodeToCheckAgainst = targetSubmode;
|
||||
}
|
||||
|
||||
if (childIter->second.submode != submodeToCheckAgainst) {
|
||||
return returnvalue::FAILED;
|
||||
if (submodesAllowedMask) {
|
||||
if ((childIter->second.submode | mask) != mask) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
} else {
|
||||
if (childIter->second.submode != submodeToCheckAgainst) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnvalue::OK;
|
||||
|
@ -1,111 +1,126 @@
|
||||
#ifndef FSFW_SUBSYSTEM_MODES_MODEDEFINITIONS_H_
|
||||
#define FSFW_SUBSYSTEM_MODES_MODEDEFINITIONS_H_
|
||||
|
||||
#include "../../modes/HasModesIF.h"
|
||||
#include "../../objectmanager/SystemObjectIF.h"
|
||||
#include "../../serialize/SerialLinkedListAdapter.h"
|
||||
#include "../../serialize/SerializeIF.h"
|
||||
#include "fsfw/modes/HasModesIF.h"
|
||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
|
||||
class ModeListEntry : public SerializeIF, public LinkedElement<ModeListEntry> {
|
||||
namespace mode {
|
||||
enum SpecialSubmodeFlags : uint8_t { INHERIT = 1 << 0, ALLOWED_MASK = 1 << 1 };
|
||||
}
|
||||
|
||||
class ModeListEntry : public SerialLinkedListAdapter<SerializeIF>,
|
||||
public LinkedElement<ModeListEntry> {
|
||||
public:
|
||||
ModeListEntry() : LinkedElement<ModeListEntry>(this) {}
|
||||
static constexpr uint8_t ALL_SUBMODES_ALLOWED_MASK = 0xff;
|
||||
|
||||
uint32_t value1 = 0;
|
||||
uint32_t value2 = 0;
|
||||
uint8_t value3 = 0;
|
||||
uint8_t value4 = 0;
|
||||
ModeListEntry() : SerialLinkedListAdapter(), LinkedElement<ModeListEntry>(this) { setLinks(); }
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) const {
|
||||
ReturnValue_t result;
|
||||
SerializeElement<uint32_t> value1 = 0;
|
||||
SerializeElement<uint32_t> value2 = 0;
|
||||
SerializeElement<uint8_t> value3 = 0;
|
||||
SerializeElement<uint8_t> value4 = 0;
|
||||
SerializeElement<uint8_t> value5 = 0;
|
||||
|
||||
result = SerializeAdapter::serialize(&value1, buffer, size, maxSize, streamEndianness);
|
||||
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::serialize(&value2, buffer, size, maxSize, streamEndianness);
|
||||
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::serialize(&value3, buffer, size, maxSize, streamEndianness);
|
||||
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = SerializeAdapter::serialize(&value4, buffer, size, maxSize, streamEndianness);
|
||||
|
||||
return result;
|
||||
ModeListEntry(const ModeListEntry& other)
|
||||
: SerialLinkedListAdapter(), LinkedElement<ModeListEntry>(this) {
|
||||
value1.entry = other.value1.entry;
|
||||
value2.entry = other.value2.entry;
|
||||
value3.entry = other.value3.entry;
|
||||
value4.entry = other.value4.entry;
|
||||
value5.entry = other.value5.entry;
|
||||
setLinks();
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const {
|
||||
return sizeof(value1) + sizeof(value2) + sizeof(value3) + sizeof(value4);
|
||||
ModeListEntry& operator=(const ModeListEntry& other) {
|
||||
this->value1.entry = other.value1.entry;
|
||||
this->value2.entry = other.value2.entry;
|
||||
this->value3.entry = other.value3.entry;
|
||||
this->value4.entry = other.value4.entry;
|
||||
this->value5.entry = other.value5.entry;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t result;
|
||||
|
||||
result = SerializeAdapter::deSerialize(&value1, buffer, size, streamEndianness);
|
||||
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&value2, buffer, size, streamEndianness);
|
||||
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&value3, buffer, size, streamEndianness);
|
||||
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&value4, buffer, size, streamEndianness);
|
||||
|
||||
return result;
|
||||
void setLinks() {
|
||||
setStart(&value1);
|
||||
value1.setNext(&value2);
|
||||
value2.setNext(&value3);
|
||||
value3.setNext(&value4);
|
||||
value4.setNext(&value5);
|
||||
}
|
||||
|
||||
// for Sequences
|
||||
Mode_t getTableId() const { return value1; }
|
||||
Mode_t getTableId() const { return value1.entry; }
|
||||
|
||||
void setTableId(Mode_t tableId) { this->value1 = tableId; }
|
||||
void setTableId(Mode_t tableId) { this->value1.entry = tableId; }
|
||||
|
||||
uint8_t getWaitSeconds() const { return value2; }
|
||||
uint8_t getWaitSeconds() const { return value2.entry; }
|
||||
|
||||
void setWaitSeconds(uint8_t waitSeconds) { this->value2 = waitSeconds; }
|
||||
void setWaitSeconds(uint8_t waitSeconds) { this->value2.entry = waitSeconds; }
|
||||
|
||||
bool checkSuccess() const { return value3 == 1; }
|
||||
bool checkSuccess() const { return value3.entry == 1; }
|
||||
|
||||
void setCheckSuccess(bool checkSuccess) { this->value3 = checkSuccess; }
|
||||
void setCheckSuccess(bool checkSuccess) { this->value3.entry = checkSuccess; }
|
||||
|
||||
// for Tables
|
||||
object_id_t getObject() const { return value1; }
|
||||
object_id_t getObject() const { return value1.entry; }
|
||||
|
||||
void setObject(object_id_t object) { this->value1 = object; }
|
||||
void setObject(object_id_t object) { this->value1.entry = object; }
|
||||
|
||||
Mode_t getMode() const { return value2; }
|
||||
Mode_t getMode() const { return value2.entry; }
|
||||
|
||||
void setMode(Mode_t mode) { this->value2 = mode; }
|
||||
void setMode(Mode_t mode) { this->value2.entry = mode; }
|
||||
|
||||
Submode_t getSubmode() const { return value3; }
|
||||
Submode_t getSubmode() const { return value3.entry; }
|
||||
|
||||
void setSubmode(Submode_t submode) { this->value3 = submode; }
|
||||
void setSubmode(Submode_t submode) { this->value3.entry = submode; }
|
||||
|
||||
bool inheritSubmode() const { return value4 == 1; }
|
||||
|
||||
void setInheritSubmode(bool inherit) {
|
||||
if (inherit) {
|
||||
value4 = 1;
|
||||
} else {
|
||||
value4 = 0;
|
||||
bool inheritSubmode() const {
|
||||
return (value4.entry & mode::SpecialSubmodeFlags::INHERIT) ==
|
||||
mode::SpecialSubmodeFlags::INHERIT;
|
||||
}
|
||||
bool submodesAllowed(uint8_t* mask) const {
|
||||
bool submodesAllowed = (value4.entry & mode::SpecialSubmodeFlags::ALLOWED_MASK) ==
|
||||
mode::SpecialSubmodeFlags::ALLOWED_MASK;
|
||||
if (submodesAllowed and mask != nullptr) {
|
||||
*mask = value5.entry;
|
||||
}
|
||||
return submodesAllowed;
|
||||
}
|
||||
|
||||
bool operator==(ModeListEntry other) {
|
||||
return ((value1 == other.value1) && (value2 == other.value2) && (value3 == other.value3));
|
||||
/**
|
||||
* Enable the inheritance of submodes. This is relevant for both the execution
|
||||
* of mode tables and for mode checking.
|
||||
*/
|
||||
void enableInheritSubmode() { value4.entry |= mode::SpecialSubmodeFlags::INHERIT; }
|
||||
/**
|
||||
* Disable the inheritance of submodes. This is relevant for both the execution
|
||||
* of mode tables and for mode checking.
|
||||
*/
|
||||
void disableInheritSubmode() { value4.entry &= ~mode::SpecialSubmodeFlags::INHERIT; }
|
||||
|
||||
/**
|
||||
* Specialization of @enableSubmodeAllowed which allows all submodes.
|
||||
*/
|
||||
void allowAllSubmodes() { enableSubmodeAllowed(ALL_SUBMODES_ALLOWED_MASK); }
|
||||
|
||||
/**
|
||||
* Enable an allowed submode mask for mode checks. Any submode which contains bits
|
||||
* outside of the mask will be declined.
|
||||
*
|
||||
* For example, for a mask of 0b11, only the modes 0b00, 0b01 and 0b11 will be accepted.
|
||||
*/
|
||||
void enableSubmodeAllowed(uint8_t mask) {
|
||||
value4.entry |= mode::SpecialSubmodeFlags::ALLOWED_MASK;
|
||||
value5.entry = mask;
|
||||
}
|
||||
/**
|
||||
* Enforce the equality of submodes for mode checks. This is the default.
|
||||
*/
|
||||
void disableSubmodeAllowed() {
|
||||
value4.entry &= ~mode::SpecialSubmodeFlags::ALLOWED_MASK;
|
||||
value5.entry = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -283,7 +283,7 @@ ReturnValue_t Heater::getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
}
|
||||
switch (uniqueId) {
|
||||
case 0:
|
||||
parameterWrapper->set(heaterOnCountdown.timeout);
|
||||
parameterWrapper->set(heaterOnCountdown.getTimeoutMs());
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
|
@ -49,6 +49,13 @@ class Clock {
|
||||
* @return -@c returnvalue::OK on success. Otherwise, the OS failure code is returned.
|
||||
*/
|
||||
static ReturnValue_t setClock(const timeval *time);
|
||||
|
||||
/**
|
||||
* @deprecated Use getClock instead, which does the same.
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
static ReturnValue_t getClock_timeval(timeval *time);
|
||||
/**
|
||||
* This system call returns the current system clock in timeval format.
|
||||
* The timval format has the fields @c tv_sec with seconds and @c tv_usec with
|
||||
@ -56,7 +63,18 @@ class Clock {
|
||||
* @param time A pointer to a timeval struct where the current time is stored.
|
||||
* @return @c returnvalue::OK on success. Otherwise, the OS failure code is returned.
|
||||
*/
|
||||
static ReturnValue_t getClock_timeval(timeval *time);
|
||||
static ReturnValue_t getClock(timeval *time);
|
||||
|
||||
/**
|
||||
* Retrieve a monotonic clock. This clock this is also more suited for measuring elapsed times
|
||||
* between two time points, but less suited when the absolute time is required.
|
||||
*
|
||||
* Implementation example: A generic UNIX implementation can use CLOCK_MONOTONIC_RAW with
|
||||
* `clock_gettime`.
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
static ReturnValue_t getClockMonotonic(timeval *time);
|
||||
|
||||
/**
|
||||
* Get the time since boot in a timeval struct
|
||||
|
@ -1,49 +1,62 @@
|
||||
#include "fsfw/timemanager/Countdown.h"
|
||||
|
||||
Countdown::Countdown(uint32_t initialTimeout, bool startImmediately) : timeout(initialTimeout) {
|
||||
#include "fsfw/globalfunctions/timevalOperations.h"
|
||||
|
||||
Countdown::Countdown(uint32_t initialTimeout, bool startImmediately) {
|
||||
if (startImmediately) {
|
||||
setTimeout(initialTimeout);
|
||||
} else {
|
||||
timeout = initialTimeout;
|
||||
timeout.tv_sec = initialTimeout / 1000;
|
||||
timeout.tv_usec = (initialTimeout % 1000) * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
Countdown::~Countdown() {}
|
||||
Countdown::~Countdown() = default;
|
||||
|
||||
ReturnValue_t Countdown::setTimeout(uint32_t milliseconds) {
|
||||
ReturnValue_t returnValue = Clock::getUptime(&startTime);
|
||||
timeout = milliseconds;
|
||||
return returnValue;
|
||||
timeout.tv_sec = milliseconds / 1000;
|
||||
timeout.tv_usec = (milliseconds % 1000) * 1000;
|
||||
return Clock::getClockMonotonic(&startTime);
|
||||
}
|
||||
|
||||
bool Countdown::hasTimedOut() const {
|
||||
if (uint32_t(this->getCurrentTime() - startTime) >= timeout) {
|
||||
// Account for system clock going back in time.
|
||||
if (getCurrentTime() < startTime) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (getCurrentTime() - startTime >= timeout) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Countdown::isBusy() const { return !hasTimedOut(); }
|
||||
|
||||
ReturnValue_t Countdown::resetTimer() { return setTimeout(timeout); }
|
||||
ReturnValue_t Countdown::resetTimer() { return setTimeoutTv(timeout); }
|
||||
|
||||
void Countdown::timeOut() { startTime = this->getCurrentTime() - timeout; }
|
||||
|
||||
uint32_t Countdown::getRemainingMillis() const {
|
||||
// We fetch the time before the if-statement
|
||||
// to be sure that the return is in
|
||||
// range 0 <= number <= timeout
|
||||
uint32_t currentTime = this->getCurrentTime();
|
||||
if (this->hasTimedOut()) {
|
||||
return 0;
|
||||
} else {
|
||||
return (startTime + timeout) - currentTime;
|
||||
}
|
||||
timeval remainingMillisTv = (startTime + timeout) - this->getCurrentTime();
|
||||
return remainingMillisTv.tv_sec * 1000 + remainingMillisTv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
uint32_t Countdown::getCurrentTime() const {
|
||||
uint32_t currentTime;
|
||||
Clock::getUptime(¤tTime);
|
||||
uint32_t Countdown::timevalToMs(timeval &tv) { return tv.tv_sec * 1000 + tv.tv_usec / 1000; }
|
||||
|
||||
ReturnValue_t Countdown::setTimeoutTv(timeval tv) {
|
||||
timeout = tv;
|
||||
return Clock::getClockMonotonic(&startTime);
|
||||
}
|
||||
|
||||
uint32_t Countdown::getTimeoutMs() const { return timeout.tv_sec * 1000 + timeout.tv_usec / 1000; }
|
||||
|
||||
timeval Countdown::getTimeout() const { return timeout; }
|
||||
|
||||
timeval Countdown::getCurrentTime() const {
|
||||
timeval currentTime{};
|
||||
Clock::getClockMonotonic(¤tTime);
|
||||
return currentTime;
|
||||
}
|
||||
|
@ -6,6 +6,10 @@
|
||||
/**
|
||||
*
|
||||
* Countdown keeps track of a timespan.
|
||||
* This class uses the system clock internally to achieve
|
||||
* a high resolution. This means that the API is only partially
|
||||
* resistant against time jumps. The user must take care to account
|
||||
* for time jumps in some from if this relevant.
|
||||
*
|
||||
* Countdown::resetTimer restarts the timer.
|
||||
* Countdown::setTimeout sets a new countdown duration and resets.
|
||||
@ -39,6 +43,8 @@ class Countdown {
|
||||
* @return Returnvalue from Clock::getUptime
|
||||
*/
|
||||
ReturnValue_t setTimeout(uint32_t milliseconds);
|
||||
ReturnValue_t setTimeoutTv(timeval tv);
|
||||
|
||||
/**
|
||||
* Returns true if the countdown duration has passed.
|
||||
*
|
||||
@ -61,22 +67,31 @@ class Countdown {
|
||||
* Returns the remaining milliseconds (0 if timeout)
|
||||
*/
|
||||
uint32_t getRemainingMillis() const;
|
||||
|
||||
uint32_t getTimeoutMs() const;
|
||||
|
||||
timeval getTimeout() const;
|
||||
|
||||
/**
|
||||
* Makes hasTimedOut() return true
|
||||
*/
|
||||
void timeOut();
|
||||
/**
|
||||
* Internal countdown duration in milliseconds
|
||||
*/
|
||||
uint32_t timeout;
|
||||
|
||||
static inline uint32_t timevalToMs(timeval& tv);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Last time the timer was started (uptime)
|
||||
* Start time of the countdown.
|
||||
*/
|
||||
uint32_t startTime = 0;
|
||||
timeval startTime{};
|
||||
|
||||
uint32_t getCurrentTime() const;
|
||||
/**
|
||||
* Timeout as timeval type. The countdown has timed out when the
|
||||
* current time exceeds the start time plus the timeout.
|
||||
*/
|
||||
timeval timeout{};
|
||||
|
||||
timeval getCurrentTime() const;
|
||||
};
|
||||
|
||||
#endif /* FSFW_TIMEMANAGER_COUNTDOWN_H_ */
|
||||
|
@ -9,10 +9,10 @@
|
||||
Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode)
|
||||
: displayOnDestruction(displayOnDestruction), displayMode(displayMode) {
|
||||
// Measures start time on initialization.
|
||||
Clock::getClock_timeval(&startTime);
|
||||
Clock::getClockMonotonic(&startTime);
|
||||
}
|
||||
|
||||
void Stopwatch::start() { Clock::getUptime(&startTime); }
|
||||
void Stopwatch::start() { Clock::getClockMonotonic(&startTime); }
|
||||
|
||||
dur_millis_t Stopwatch::stop(bool display) {
|
||||
stopInternal();
|
||||
@ -63,6 +63,6 @@ StopwatchDisplayMode Stopwatch::getDisplayMode() const { return displayMode; }
|
||||
|
||||
void Stopwatch::stopInternal() {
|
||||
timeval endTime;
|
||||
Clock::getClock_timeval(&endTime);
|
||||
Clock::getClockMonotonic(&endTime);
|
||||
elapsedTime = endTime - startTime;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define TMTCBRIDGE_WIRETAPPING 0
|
||||
|
||||
TmTcBridge::TmTcBridge(const char* name, object_id_t objectId, object_id_t tcDestination,
|
||||
object_id_t tmStoreId, object_id_t tcStoreId)
|
||||
uint32_t msgQueueDepth, object_id_t tmStoreId, object_id_t tcStoreId)
|
||||
: SystemObject(objectId),
|
||||
name(name),
|
||||
tmStoreId(tmStoreId),
|
||||
@ -18,7 +18,7 @@ TmTcBridge::TmTcBridge(const char* name, object_id_t objectId, object_id_t tcDes
|
||||
{
|
||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(
|
||||
TMTC_RECEPTION_QUEUE_DEPTH, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
msgQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||
}
|
||||
|
||||
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); }
|
||||
|
@ -15,7 +15,6 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
||||
public ExecutableObjectIF,
|
||||
public SystemObject {
|
||||
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 = 500;
|
||||
|
||||
@ -23,7 +22,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
||||
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
|
||||
|
||||
TmTcBridge(const char* name, object_id_t objectId, object_id_t tcDestination,
|
||||
object_id_t tmStoreId, object_id_t tcStoreId);
|
||||
uint32_t msgQueueDepth, object_id_t tmStoreId, object_id_t tcStoreId);
|
||||
~TmTcBridge() override;
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -1 +1 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE gyroL3gHelpers.cpp)
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE gyroL3gHelpers.cpp mgmLis3Helpers.cpp)
|
||||
|
@ -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_ */
|
@ -15,7 +15,8 @@ ReturnValue_t HostFilesystem::writeToFile(FileOpParams params, const uint8_t *da
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
path path(params.path());
|
||||
if (not exists(path)) {
|
||||
std::error_code e;
|
||||
if (not exists(path, e)) {
|
||||
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
||||
}
|
||||
// This is equivalent to "r+" mode, which is what we need here. Only using ::out would truncate
|
||||
@ -35,7 +36,8 @@ ReturnValue_t HostFilesystem::readFromFile(FileOpParams params, uint8_t **buffer
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
path path(params.path());
|
||||
if (not exists(path)) {
|
||||
std::error_code e;
|
||||
if (not exists(path, e)) {
|
||||
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
||||
}
|
||||
ifstream file(path);
|
||||
@ -59,7 +61,8 @@ ReturnValue_t HostFilesystem::createFile(FilesystemParams params, const uint8_t
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
path path(params.path);
|
||||
if (exists(path)) {
|
||||
std::error_code e;
|
||||
if (exists(path, e)) {
|
||||
return HasFileSystemIF::FILE_ALREADY_EXISTS;
|
||||
}
|
||||
ofstream file(path);
|
||||
@ -74,7 +77,8 @@ ReturnValue_t HostFilesystem::removeFile(const char *path_, FileSystemArgsIF *ar
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
path path(path_);
|
||||
if (not exists(path)) {
|
||||
std::error_code e;
|
||||
if (not exists(path, e)) {
|
||||
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
||||
}
|
||||
if (remove(path, errorCode)) {
|
||||
@ -89,7 +93,8 @@ ReturnValue_t HostFilesystem::createDirectory(FilesystemParams params, bool crea
|
||||
}
|
||||
path dirPath(params.path);
|
||||
|
||||
if (exists(dirPath)) {
|
||||
std::error_code e;
|
||||
if (exists(dirPath, e)) {
|
||||
return HasFileSystemIF::DIRECTORY_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
@ -110,7 +115,8 @@ ReturnValue_t HostFilesystem::removeDirectory(FilesystemParams params, bool dele
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
path dirPath(params.path);
|
||||
if (not exists(dirPath)) {
|
||||
std::error_code e;
|
||||
if (not exists(dirPath, e)) {
|
||||
return HasFileSystemIF::DIRECTORY_DOES_NOT_EXIST;
|
||||
}
|
||||
if (is_regular_file(dirPath)) {
|
||||
@ -149,12 +155,14 @@ ReturnValue_t HostFilesystem::rename(const char *oldPath_, const char *newPath_,
|
||||
|
||||
bool HostFilesystem::fileExists(FilesystemParams params) {
|
||||
path path(params.path);
|
||||
return filesystem::exists(path);
|
||||
std::error_code e;
|
||||
return filesystem::exists(path, e);
|
||||
}
|
||||
|
||||
ReturnValue_t HostFilesystem::truncateFile(FilesystemParams params) {
|
||||
path path(params.path);
|
||||
if (not filesystem::exists(path)) {
|
||||
std::error_code e;
|
||||
if (not filesystem::exists(path, e)) {
|
||||
return FILE_DOES_NOT_EXIST;
|
||||
}
|
||||
ofstream of(path);
|
||||
|
@ -17,7 +17,7 @@ ReturnValue_t CommandExecutor::load(std::string command, bool blocking, bool pri
|
||||
return COMMAND_PENDING;
|
||||
}
|
||||
|
||||
currentCmd = command;
|
||||
currentCmd = std::move(command);
|
||||
this->blocking = blocking;
|
||||
this->printOutput = printOutput;
|
||||
if (state == States::IDLE) {
|
||||
|
@ -112,7 +112,7 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s
|
||||
if (i2cCookie->errorCounter < 3) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "I2cComIF::sendMessage: Failed to send data to I2C "
|
||||
"device with error code "
|
||||
"device from " << deviceFile << " with error code "
|
||||
<< errno << ". Error description: " << strerror(errno) << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ add_subdirectory(util)
|
||||
add_subdirectory(container)
|
||||
add_subdirectory(osal)
|
||||
add_subdirectory(pus)
|
||||
add_subdirectory(subsystem)
|
||||
add_subdirectory(serialize)
|
||||
add_subdirectory(datapoollocal)
|
||||
add_subdirectory(storagemanager)
|
||||
|
1
unittests/subsystem/CMakeLists.txt
Normal file
1
unittests/subsystem/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
||||
target_sources(${FSFW_TEST_TGT} PRIVATE testModeDef.cpp)
|
49
unittests/subsystem/testModeDef.cpp
Normal file
49
unittests/subsystem/testModeDef.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/subsystem/modes/ModeDefinitions.h"
|
||||
|
||||
TEST_CASE("Mode Definitions", "[mode]") {
|
||||
ModeListEntry entry;
|
||||
|
||||
SECTION("Basic") {
|
||||
entry.setMode(HasModesIF::MODE_OFF);
|
||||
entry.setSubmode(2);
|
||||
CHECK(entry.getMode() == HasModesIF::MODE_OFF);
|
||||
CHECK(entry.getSubmode() == 2);
|
||||
uint8_t mask;
|
||||
CHECK(entry.submodesAllowed(&mask) == false);
|
||||
}
|
||||
|
||||
SECTION("Allowed submode mask") {
|
||||
entry.allowAllSubmodes();
|
||||
uint8_t mask;
|
||||
CHECK(entry.submodesAllowed(&mask) == true);
|
||||
CHECK(mask == 0xff);
|
||||
}
|
||||
|
||||
SECTION("Serialization") {
|
||||
std::array<uint8_t, 32> buf{};
|
||||
entry.setObject(0x1f2f3f4f);
|
||||
entry.setMode(HasModesIF::MODE_ON);
|
||||
entry.setSubmode(2);
|
||||
entry.enableInheritSubmode();
|
||||
entry.enableSubmodeAllowed(0x1f);
|
||||
uint8_t* serPtr = buf.data();
|
||||
size_t serLen = 0;
|
||||
REQUIRE(entry.serialize(&serPtr, &serLen, buf.size(), SerializeIF::Endianness::NETWORK) ==
|
||||
returnvalue::OK);
|
||||
CHECK(buf[0] == 0x1f);
|
||||
CHECK(buf[1] == 0x2f);
|
||||
CHECK(buf[2] == 0x3f);
|
||||
CHECK(buf[3] == 0x4f);
|
||||
CHECK(buf[4] == 0);
|
||||
CHECK(buf[5] == 0);
|
||||
CHECK(buf[6] == 0);
|
||||
CHECK(buf[7] == HasModesIF::MODE_ON);
|
||||
CHECK(buf[8] == 2);
|
||||
CHECK(buf[9] == (mode::SpecialSubmodeFlags::ALLOWED_MASK | mode::SpecialSubmodeFlags::INHERIT));
|
||||
CHECK(buf[10] == 0x1f);
|
||||
}
|
||||
}
|
@ -1,15 +1,18 @@
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "CatchDefinitions.h"
|
||||
|
||||
static constexpr bool TEST_LONGER_CD = false;
|
||||
TEST_CASE("Countdown Tests", "[TestCountdown]") {
|
||||
INFO("Countdown Tests");
|
||||
Countdown count(20);
|
||||
REQUIRE(count.timeout == 20);
|
||||
REQUIRE(count.getTimeoutMs() == 20);
|
||||
REQUIRE(count.setTimeout(100) == static_cast<uint16_t>(returnvalue::OK));
|
||||
REQUIRE(count.timeout == 100);
|
||||
REQUIRE(count.getTimeoutMs() == 100);
|
||||
REQUIRE(count.setTimeout(150) == static_cast<uint16_t>(returnvalue::OK));
|
||||
REQUIRE(count.isBusy());
|
||||
REQUIRE(not count.hasTimedOut());
|
||||
@ -25,4 +28,19 @@ TEST_CASE("Countdown Tests", "[TestCountdown]") {
|
||||
count.resetTimer();
|
||||
REQUIRE(not count.hasTimedOut());
|
||||
REQUIRE(count.isBusy());
|
||||
count.setTimeout(100);
|
||||
REQUIRE(not count.hasTimedOut());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
REQUIRE(not count.hasTimedOut());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
REQUIRE(count.hasTimedOut());
|
||||
|
||||
// Takes longer, disabled by default
|
||||
if (TEST_LONGER_CD) {
|
||||
count.setTimeout(2500);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
REQUIRE(not count.hasTimedOut());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1500));
|
||||
REQUIRE(count.hasTimedOut());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user