From 8d3fceea8f08c4f8f3aadc34e0d3aa3f5a7f75f6 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Sun, 8 Aug 2021 15:26:18 +0200 Subject: [PATCH 01/48] set sequence flags in space packet base --- src/fsfw/action/ActionHelper.cpp | 11 +++++++++++ src/fsfw/tmtcpacket/SpacePacketBase.cpp | 5 +++++ src/fsfw/tmtcpacket/SpacePacketBase.h | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/src/fsfw/action/ActionHelper.cpp b/src/fsfw/action/ActionHelper.cpp index 3e9d121a..85c39f05 100644 --- a/src/fsfw/action/ActionHelper.cpp +++ b/src/fsfw/action/ActionHelper.cpp @@ -32,6 +32,17 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) { setQueueToUse(queueToUse_); } + if(queueToUse == nullptr) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "ActionHelper::initialize: No queue set" << std::endl; +#else + sif::printWarning("ActionHelper::initialize: No queue set\n"); +#endif +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; } diff --git a/src/fsfw/tmtcpacket/SpacePacketBase.cpp b/src/fsfw/tmtcpacket/SpacePacketBase.cpp index e9a0b836..5dae94c9 100644 --- a/src/fsfw/tmtcpacket/SpacePacketBase.cpp +++ b/src/fsfw/tmtcpacket/SpacePacketBase.cpp @@ -54,6 +54,11 @@ void SpacePacketBase::setAPID( uint16_t new_apid ) { this->data->header.packet_id_l = ( new_apid & 0x00FF ); } +void SpacePacketBase::setSequenceFlags( uint8_t sequenceflags ) { + this->data->header.sequence_control_h &= 0x3F; + this->data->header.sequence_control_h |= sequenceflags << 6; +} + uint16_t SpacePacketBase::getPacketSequenceControl( void ) { return ( (this->data->header.sequence_control_h) << 8 ) + this->data->header.sequence_control_l; diff --git a/src/fsfw/tmtcpacket/SpacePacketBase.h b/src/fsfw/tmtcpacket/SpacePacketBase.h index 13cb3130..3cd3e552 100644 --- a/src/fsfw/tmtcpacket/SpacePacketBase.h +++ b/src/fsfw/tmtcpacket/SpacePacketBase.h @@ -109,6 +109,13 @@ public: * ignored. */ void setAPID( uint16_t setAPID ); + + /** + * Sets the sequence flags of a packet, which are bit 17 and 18 in the space packet header. + * @param The sequence flags to set + */ + void setSequenceFlags( uint8_t sequenceflags ); + /** * Returns the CCSDS packet sequence control field, which are the third and * the fourth byte of the CCSDS primary header. From ba5e2ad8bb97faf22702fa9aaaf47931db7ca6bb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 16:57:24 +0200 Subject: [PATCH 02/48] Cleaning up TCP and UDP code Same port number used as before, but some inconsistencies fixed --- src/fsfw/osal/common/TcpTmTcBridge.cpp | 2 +- src/fsfw/osal/common/TcpTmTcBridge.h | 2 +- src/fsfw/osal/common/TcpTmTcServer.cpp | 4 ++-- src/fsfw/osal/common/TcpTmTcServer.h | 3 +-- src/fsfw/osal/common/UdpTmTcBridge.cpp | 4 ++-- src/fsfw/osal/common/UdpTmTcBridge.h | 2 +- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/fsfw/osal/common/TcpTmTcBridge.cpp b/src/fsfw/osal/common/TcpTmTcBridge.cpp index 24f1a281..f873d5c7 100644 --- a/src/fsfw/osal/common/TcpTmTcBridge.cpp +++ b/src/fsfw/osal/common/TcpTmTcBridge.cpp @@ -17,7 +17,7 @@ #endif -const std::string TcpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; +const std::string TcpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId): diff --git a/src/fsfw/osal/common/TcpTmTcBridge.h b/src/fsfw/osal/common/TcpTmTcBridge.h index 6cfacb9f..be0d0d52 100644 --- a/src/fsfw/osal/common/TcpTmTcBridge.h +++ b/src/fsfw/osal/common/TcpTmTcBridge.h @@ -30,7 +30,7 @@ class TcpTmTcBridge: friend class TcpTmTcServer; public: /* The ports chosen here should not be used by any other process. */ - static const std::string DEFAULT_UDP_SERVER_PORT; + static const std::string DEFAULT_SERVER_PORT; /** * Constructor diff --git a/src/fsfw/osal/common/TcpTmTcServer.cpp b/src/fsfw/osal/common/TcpTmTcServer.cpp index f94449bb..057cd538 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.cpp +++ b/src/fsfw/osal/common/TcpTmTcServer.cpp @@ -22,14 +22,14 @@ #define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0 #endif -const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT = "7303"; +const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = TcpTmTcBridge::DEFAULT_SERVER_PORT; TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, size_t receptionBufferSize, std::string customTcpServerPort): SystemObject(objectId), tmtcBridgeId(tmtcTcpBridge), tcpPort(customTcpServerPort), receptionBuffer(receptionBufferSize) { if(tcpPort == "") { - tcpPort = DEFAULT_TCP_SERVER_PORT; + tcpPort = DEFAULT_SERVER_PORT; } } diff --git a/src/fsfw/osal/common/TcpTmTcServer.h b/src/fsfw/osal/common/TcpTmTcServer.h index f7c36d69..6588f111 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.h +++ b/src/fsfw/osal/common/TcpTmTcServer.h @@ -41,8 +41,7 @@ class TcpTmTcServer: public TcpIpBase, public ExecutableObjectIF { public: - /* The ports chosen here should not be used by any other process. */ - static const std::string DEFAULT_TCP_SERVER_PORT; + static const std::string DEFAULT_SERVER_PORT; static constexpr size_t ETHERNET_MTU_SIZE = 1500; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.cpp b/src/fsfw/osal/common/UdpTmTcBridge.cpp index 7015cf4a..db2546cd 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.cpp +++ b/src/fsfw/osal/common/UdpTmTcBridge.cpp @@ -17,13 +17,13 @@ #define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 #endif -const std::string UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; +const std::string UdpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, std::string udpServerPort, object_id_t tmStoreId, object_id_t tcStoreId): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { if(udpServerPort == "") { - this->udpServerPort = DEFAULT_UDP_SERVER_PORT; + this->udpServerPort = DEFAULT_SERVER_PORT; } else { this->udpServerPort = udpServerPort; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.h b/src/fsfw/osal/common/UdpTmTcBridge.h index 7a346de5..93c7511e 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.h +++ b/src/fsfw/osal/common/UdpTmTcBridge.h @@ -28,7 +28,7 @@ class UdpTmTcBridge: friend class UdpTcPollingTask; public: /* The ports chosen here should not be used by any other process. */ - static const std::string DEFAULT_UDP_SERVER_PORT; + static const std::string DEFAULT_SERVER_PORT; UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, std::string udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE, From fb36dc45019c0b57e79a7ac8af8d154cb3d6817b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 18:12:25 +0200 Subject: [PATCH 03/48] More improvements for TCP/UDP port definition --- src/fsfw/osal/common/TcpTmTcBridge.cpp | 3 --- src/fsfw/osal/common/TcpTmTcBridge.h | 4 +--- src/fsfw/osal/common/TcpTmTcServer.cpp | 6 +++++- src/fsfw/osal/common/TcpTmTcServer.h | 19 +++++++++++-------- src/fsfw/osal/common/UdpTmTcBridge.h | 4 ++-- src/fsfw/osal/common/tcpipCommon.h | 4 ++-- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/fsfw/osal/common/TcpTmTcBridge.cpp b/src/fsfw/osal/common/TcpTmTcBridge.cpp index f873d5c7..3cd03c36 100644 --- a/src/fsfw/osal/common/TcpTmTcBridge.cpp +++ b/src/fsfw/osal/common/TcpTmTcBridge.cpp @@ -1,6 +1,5 @@ #include "fsfw/platform.h" #include "fsfw/osal/common/TcpTmTcBridge.h" -#include "fsfw/osal/common/tcpipHelpers.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/ipc/MutexGuard.h" @@ -17,8 +16,6 @@ #endif -const std::string TcpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; - TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { diff --git a/src/fsfw/osal/common/TcpTmTcBridge.h b/src/fsfw/osal/common/TcpTmTcBridge.h index be0d0d52..dc46f1f0 100644 --- a/src/fsfw/osal/common/TcpTmTcBridge.h +++ b/src/fsfw/osal/common/TcpTmTcBridge.h @@ -2,7 +2,7 @@ #define FSFW_OSAL_COMMON_TCPTMTCBRIDGE_H_ #include "TcpIpBase.h" -#include "../../tmtcservices/TmTcBridge.h" +#include "fsfw/tmtcservices/TmTcBridge.h" #ifdef _WIN32 @@ -29,8 +29,6 @@ class TcpTmTcBridge: public TmTcBridge { friend class TcpTmTcServer; public: - /* The ports chosen here should not be used by any other process. */ - static const std::string DEFAULT_SERVER_PORT; /** * Constructor diff --git a/src/fsfw/osal/common/TcpTmTcServer.cpp b/src/fsfw/osal/common/TcpTmTcServer.cpp index 057cd538..11ab71af 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.cpp +++ b/src/fsfw/osal/common/TcpTmTcServer.cpp @@ -22,7 +22,7 @@ #define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0 #endif -const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = TcpTmTcBridge::DEFAULT_SERVER_PORT; +const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, size_t receptionBufferSize, std::string customTcpServerPort): @@ -200,6 +200,10 @@ void TcpTmTcServer::setTcpBacklog(uint8_t tcpBacklog) { this->tcpBacklog = tcpBacklog; } +std::string TcpTmTcServer::getTcpPort() const { + return tcpPort; +} + ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket) { // Access to the FIFO is mutex protected because it is filled by the bridge MutexGuard(tmtcBridge->mutex, tmtcBridge->timeoutType, tmtcBridge->mutexTimeoutMs); diff --git a/src/fsfw/osal/common/TcpTmTcServer.h b/src/fsfw/osal/common/TcpTmTcServer.h index 6588f111..c6916080 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.h +++ b/src/fsfw/osal/common/TcpTmTcServer.h @@ -3,13 +3,14 @@ #include "TcpIpBase.h" -#include "../../platform.h" -#include "../../ipc/messageQueueDefinitions.h" -#include "../../ipc/MessageQueueIF.h" -#include "../../objectmanager/frameworkObjects.h" -#include "../../objectmanager/SystemObject.h" -#include "../../storagemanager/StorageManagerIF.h" -#include "../../tasks/ExecutableObjectIF.h" +#include "fsfw/platform.h" +#include "fsfw/osal/common/tcpipHelpers.h" +#include "fsfw/ipc/messageQueueDefinitions.h" +#include "fsfw/ipc/MessageQueueIF.h" +#include "fsfw/objectmanager/frameworkObjects.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/storagemanager/StorageManagerIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" #ifdef PLATFORM_UNIX #include @@ -43,7 +44,7 @@ class TcpTmTcServer: public: static const std::string DEFAULT_SERVER_PORT; - static constexpr size_t ETHERNET_MTU_SIZE = 1500; + static constexpr size_t ETHERNET_MTU_SIZE = 1500; /** * TCP Server Constructor @@ -64,6 +65,8 @@ public: ReturnValue_t performOperation(uint8_t opCode) override; ReturnValue_t initializeAfterTaskCreation() override; + std::string getTcpPort() const; + protected: StorageManagerIF* tcStore = nullptr; StorageManagerIF* tmStore = nullptr; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.h b/src/fsfw/osal/common/UdpTmTcBridge.h index 93c7511e..dc695c81 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.h +++ b/src/fsfw/osal/common/UdpTmTcBridge.h @@ -2,8 +2,8 @@ #define FSFW_OSAL_COMMON_TMTCUDPBRIDGE_H_ #include "TcpIpBase.h" -#include "../../platform.h" -#include "../../tmtcservices/TmTcBridge.h" +#include "fsfw/platform.h" +#include "fsfw/tmtcservices/TmTcBridge.h" #ifdef PLATFORM_WIN #include diff --git a/src/fsfw/osal/common/tcpipCommon.h b/src/fsfw/osal/common/tcpipCommon.h index ce7a90cd..5a04144e 100644 --- a/src/fsfw/osal/common/tcpipCommon.h +++ b/src/fsfw/osal/common/tcpipCommon.h @@ -1,7 +1,7 @@ #ifndef FSFW_OSAL_COMMON_TCPIPCOMMON_H_ #define FSFW_OSAL_COMMON_TCPIPCOMMON_H_ -#include "../../timemanager/clockDefinitions.h" +#include "fsfw/timemanager/clockDefinitions.h" #include #ifdef _WIN32 @@ -13,7 +13,7 @@ namespace tcpip { -const char* const DEFAULT_SERVER_PORT = "7301"; +static constexpr char DEFAULT_SERVER_PORT[] = "7301"; enum class Protocol { UDP, From 1ac372cb89fabc868aa9cc6ef024f822c744eaed Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 18:22:22 +0200 Subject: [PATCH 04/48] getter function for UDP port --- src/fsfw/osal/common/UdpTmTcBridge.cpp | 4 ++++ src/fsfw/osal/common/UdpTmTcBridge.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/fsfw/osal/common/UdpTmTcBridge.cpp b/src/fsfw/osal/common/UdpTmTcBridge.cpp index db2546cd..734a2b15 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.cpp +++ b/src/fsfw/osal/common/UdpTmTcBridge.cpp @@ -108,6 +108,10 @@ UdpTmTcBridge::~UdpTmTcBridge() { } } +std::string UdpTmTcBridge::getUdpPort() const { + return udpServerPort; +} + ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { int flags = 0; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.h b/src/fsfw/osal/common/UdpTmTcBridge.h index dc695c81..4d634e64 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.h +++ b/src/fsfw/osal/common/UdpTmTcBridge.h @@ -44,6 +44,8 @@ public: void checkAndSetClientAddress(sockaddr& clientAddress); + std::string getUdpPort() const; + protected: virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; From 406b77ea81816c2113aec9239b3e5d2ed71e7cb5 Mon Sep 17 00:00:00 2001 From: IRS Cleanroom Laptop Date: Tue, 17 Aug 2021 16:34:25 +0200 Subject: [PATCH 05/48] moved SPI wiretapping cfg --- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 5 ----- hal/src/fsfw_hal/linux/spi/SpiComIF.h | 1 + src/fsfw/FSFW.h.in | 5 +++++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index fafe67be..fe6841f0 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -15,11 +15,6 @@ #include #include -/* Can be used for low-level debugging of the SPI bus */ -#ifndef FSFW_HAL_LINUX_SPI_WIRETAPPING -#define FSFW_HAL_LINUX_SPI_WIRETAPPING 0 -#endif - SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(objectId), gpioComIF(gpioComIF) { if(gpioComIF == nullptr) { diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.h b/hal/src/fsfw_hal/linux/spi/SpiComIF.h index d43e2505..bcca7462 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.h +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.h @@ -1,6 +1,7 @@ #ifndef LINUX_SPI_SPICOMIF_H_ #define LINUX_SPI_SPICOMIF_H_ +#include "fsfw/FSFW.h" #include "spiDefinitions.h" #include "returnvalues/classIds.h" #include "fsfw_hal/common/gpio/GpioIF.h" diff --git a/src/fsfw/FSFW.h.in b/src/fsfw/FSFW.h.in index 4d4b8aee..a3666058 100644 --- a/src/fsfw/FSFW.h.in +++ b/src/fsfw/FSFW.h.in @@ -11,6 +11,11 @@ #cmakedefine FSFW_ADD_MONITORING #cmakedefine FSFW_ADD_SGP4_PROPAGATOR +/* Can be used for low-level debugging of the SPI bus */ +#ifndef FSFW_HAL_LINUX_SPI_WIRETAPPING +#define FSFW_HAL_LINUX_SPI_WIRETAPPING 0 +#endif + #ifndef FSFW_HAL_L3GD20_GYRO_DEBUG #define FSFW_HAL_L3GD20_GYRO_DEBUG 0 #endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */ From e3697d6d8c38b278ebc34704fa772f671e36eb57 Mon Sep 17 00:00:00 2001 From: IRS Cleanroom Laptop Date: Tue, 17 Aug 2021 19:50:01 +0200 Subject: [PATCH 06/48] fixed printout --- hal/src/fsfw_hal/linux/UnixFileGuard.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/hal/src/fsfw_hal/linux/UnixFileGuard.cpp b/hal/src/fsfw_hal/linux/UnixFileGuard.cpp index f7901018..ad875623 100644 --- a/hal/src/fsfw_hal/linux/UnixFileGuard.cpp +++ b/hal/src/fsfw_hal/linux/UnixFileGuard.cpp @@ -1,5 +1,10 @@ +#include "fsfw/FSFW.h" +#include "fsfw/serviceinterface.h" #include "fsfw_hal/linux/UnixFileGuard.h" +#include +#include + UnixFileGuard::UnixFileGuard(std::string device, int* fileDescriptor, int flags, std::string diagnosticPrefix): fileDescriptor(fileDescriptor) { @@ -10,12 +15,11 @@ UnixFileGuard::UnixFileGuard(std::string device, int* fileDescriptor, int 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 << - "." << std::endl; - sif::warning << "Error description: " << strerror(errno) << std::endl; + sif::warning << diagnosticPrefix << "Opening device failed with error code " << + errno << ": " << strerror(errno) << std::endl; #else - sif::printError("%sOpening device failed with error code %d.\n", diagnosticPrefix); - sif::printWarning("Error description: %s\n", strerror(errno)); + sif::printWarning("%sOpening device failed with error code %d: %s\n", + diagnosticPrefix, errno, strerror(errno)); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */ openStatus = OPEN_FILE_FAILED; From 1183e5739d73da42978e0ab3218b3ca53fff4489 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 Aug 2021 11:23:45 +0200 Subject: [PATCH 07/48] using upstream action helper Will be merged upstream soon --- src/fsfw/action/ActionHelper.cpp | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/fsfw/action/ActionHelper.cpp b/src/fsfw/action/ActionHelper.cpp index 85c39f05..3dfe8b50 100644 --- a/src/fsfw/action/ActionHelper.cpp +++ b/src/fsfw/action/ActionHelper.cpp @@ -32,17 +32,6 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) { setQueueToUse(queueToUse_); } - if(queueToUse == nullptr) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "ActionHelper::initialize: No queue set" << std::endl; -#else - sif::printWarning("ActionHelper::initialize: No queue set\n"); -#endif -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; } @@ -66,19 +55,7 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress) { - if(ipcStore == nullptr) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "ActionHelper::prepareExecution: IPC Store not set. Call initialize first" - << std::endl; -#else - sif::printWarning("ActionHelper::prepareExecution: " - "IPC Store not set. Call initialize first\n"); -#endif -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - return; - } - const uint8_t* dataPtr = nullptr; + const uint8_t* dataPtr = NULL; size_t size = 0; ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); if (result != HasReturnvaluesIF::RETURN_OK) { From 7d0377845bd1bde75fcb81a8bf5fb4234718576a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 20 Aug 2021 15:46:34 +0200 Subject: [PATCH 08/48] printout for unknown command --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 96fe031a..478fc041 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -1336,10 +1336,20 @@ void DeviceHandlerBase::buildInternalCommand(void) { DeviceCommandMap::iterator iter = deviceCommandMap.find( deviceCommandId); if (iter == deviceCommandMap.end()) { +#if FSFW_VERBOSE_LEVEL >= 1 + char output[36]; + sprintf(output, "Command 0x%08x unknown", + static_cast(deviceCommandId)); + // so we can track misconfigurations + printWarningOrError(sif::OutputTypes::OUT_WARNING, + "buildInternalCommand", + COMMAND_NOT_SUPPORTED, + output); +#endif result = COMMAND_NOT_SUPPORTED; } else if (iter->second.isExecuting) { -#if FSFW_DISABLE_PRINTOUT == 0 +#if FSFW_VERBOSE_LEVEL >= 1 char output[36]; sprintf(output, "Command 0x%08x is executing", static_cast(deviceCommandId)); From 5454169e2056985428d36fee80e5a28a6952bf19 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 22 Aug 2021 19:48:35 +0200 Subject: [PATCH 09/48] UartComIF: set O_NONBLOCK in canonical mode When using the non-canonical mode, the file descriptor can be opened in blocking mode because the VTIME and VMIN termios parameters are used to configure non-blocking mode. However, in canonical mode, the fd needs to be opened with O_NONBLOCK --- hal/src/fsfw_hal/linux/uart/UartComIF.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp index f52b6b1e..29a79205 100644 --- a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp @@ -60,7 +60,13 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) { struct termios options = {}; std::string deviceFile = uartCookie->getDeviceFile(); - int fd = open(deviceFile.c_str(), O_RDWR); + int flags = O_RDWR; + if(uartCookie->getUartMode() == UartModes::CANONICAL) { + // In non-canonical mode, don't specify O_NONBLOCK because these properties will be + // controlled by the VTIME and VMIN parameters and O_NONBLOCK would override this + flags |= O_NONBLOCK; + } + int fd = open(deviceFile.c_str(), flags); if (fd < 0) { sif::warning << "UartComIF::configureUartPort: Failed to open uart " << deviceFile << From afd375a7f86730dd865aebac257f40c58fc690df Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 22 Aug 2021 20:24:50 +0200 Subject: [PATCH 10/48] minor fix for canonical read handling --- hal/src/fsfw_hal/linux/uart/UartComIF.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp index 29a79205..99f5f8df 100644 --- a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp @@ -1,6 +1,7 @@ -#include "fsfw_hal/linux/uart/UartComIF.h" +#include "UartComIF.h" #include "OBSWConfig.h" +#include "fsfw_hal/linux/utility.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include @@ -353,12 +354,13 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM size_t maxReplySize = uartCookie.getMaxReplyLen(); int fd = iter->second.fileDescriptor; auto bufferPtr = iter->second.replyBuffer.data(); + iter->second.replyLen = 0; do { size_t allowedReadSize = 0; if(currentBytesRead >= maxReplySize) { // Overflow risk. Emit warning, trigger event and break. If this happens, // the reception buffer is not large enough or data is not polled often enough. -#if OBSW_VERBOSE_LEVEL >= 1 +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!" << std::endl; @@ -376,7 +378,20 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM bytesRead = read(fd, bufferPtr, allowedReadSize); if (bytesRead < 0) { - return RETURN_FAILED; + // EAGAIN: No data available in non-blocking mode + if(errno != EAGAIN) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "UartComIF::handleCanonicalRead: read failed with code" << + errno << ": " << strerror(errno) << std::endl; +#else + sif::printWarning("UartComIF::handleCanonicalRead: read failed with code %d: %s\n", + errno, strerror(errno)); +#endif +#endif + return RETURN_FAILED; + } + } else if(bytesRead > 0) { iter->second.replyLen += bytesRead; From fd2916af1162aabbf5dc2b7914885b251700f907 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 23 Aug 2021 09:40:02 +0200 Subject: [PATCH 11/48] moved TCP cfg --- src/fsfw/FSFW.h.in | 4 ++++ src/fsfw/osal/common/TcpTmTcServer.cpp | 14 ++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/fsfw/FSFW.h.in b/src/fsfw/FSFW.h.in index a3666058..4702c6ac 100644 --- a/src/fsfw/FSFW.h.in +++ b/src/fsfw/FSFW.h.in @@ -11,6 +11,10 @@ #cmakedefine FSFW_ADD_MONITORING #cmakedefine FSFW_ADD_SGP4_PROPAGATOR +#ifndef FSFW_TCP_RECV_WIRETAPPING_ENABLED +#define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0 +#endif + /* Can be used for low-level debugging of the SPI bus */ #ifndef FSFW_HAL_LINUX_SPI_WIRETAPPING #define FSFW_HAL_LINUX_SPI_WIRETAPPING 0 diff --git a/src/fsfw/osal/common/TcpTmTcServer.cpp b/src/fsfw/osal/common/TcpTmTcServer.cpp index 11ab71af..534f5e7c 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.cpp +++ b/src/fsfw/osal/common/TcpTmTcServer.cpp @@ -1,8 +1,10 @@ -#include "fsfw/osal/common/TcpTmTcServer.h" -#include "fsfw/osal/common/TcpTmTcBridge.h" -#include "fsfw/osal/common/tcpipHelpers.h" - #include "fsfw/platform.h" +#include "fsfw/FSFW.h" + +#include "TcpTmTcServer.h" +#include "TcpTmTcBridge.h" +#include "tcpipHelpers.h" + #include "fsfw/container/SharedRingBuffer.h" #include "fsfw/ipc/MessageQueueSenderIF.h" #include "fsfw/ipc/MutexGuard.h" @@ -18,10 +20,6 @@ #include #endif -#ifndef FSFW_TCP_RECV_WIRETAPPING_ENABLED -#define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0 -#endif - const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, From 469eba3ce2f82c7b2fcdd494d4ac279eef308195 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 6 Sep 2021 11:35:14 +0200 Subject: [PATCH 12/48] raised limit --- src/fsfw/tmtcservices/TmTcBridge.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/tmtcservices/TmTcBridge.h b/src/fsfw/tmtcservices/TmTcBridge.h index d3689d19..4980caff 100644 --- a/src/fsfw/tmtcservices/TmTcBridge.h +++ b/src/fsfw/tmtcservices/TmTcBridge.h @@ -19,7 +19,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 uint8_t LIMIT_DOWNLINK_PACKETS_STORED = 20; + static constexpr uint8_t LIMIT_DOWNLINK_PACKETS_STORED = 200; static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5; static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10; From 924c150af27484f9eb4439ec80c048b46c226890 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 6 Sep 2021 12:05:30 +0200 Subject: [PATCH 13/48] Possible bugfix in DHB The delayCycles variables needs to be initialized differently for periodic replies. It is initialized to the maxDelayCycles value now --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 478fc041..dcce736e 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -430,7 +430,12 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, DeviceReplyInfo info; info.maxDelayCycles = maxDelayCycles; info.periodic = periodic; - info.delayCycles = 0; + if(info.periodic) { + info.delayCycles = info.maxDelayCycles; + } + else { + info.delayCycles = 0; + } info.replyLen = replyLen; info.dataSet = dataSet; info.command = deviceCommandMap.end(); From 73eb11f4f1e7cc80f61d04ad7722fe53608f8051 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 8 Sep 2021 16:01:46 +0200 Subject: [PATCH 14/48] bugfixes and improvements --- hal/src/fsfw_hal/linux/uart/UartComIF.cpp | 13 ++++++------- hal/src/fsfw_hal/linux/uart/UartCookie.cpp | 4 ++-- src/fsfw/devicehandlers/DeviceCommunicationIF.h | 7 ++++--- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 8 ++++---- src/fsfw/devicehandlers/DeviceHandlerBase.h | 8 +++++--- src/fsfw/devicehandlers/DeviceHandlerIF.h | 3 ++- src/fsfw/pus/Service8FunctionManagement.cpp | 4 ++-- src/fsfw/pus/servicepackets/Service1Packets.h | 8 ++++---- 8 files changed, 29 insertions(+), 26 deletions(-) diff --git a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp index 99f5f8df..f5754c6e 100644 --- a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp @@ -266,23 +266,22 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki ReturnValue_t UartComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) { - int fd = 0; std::string deviceFile; UartDeviceMapIter uartDeviceMapIter; - if(sendData == nullptr) { - sif::debug << "UartComIF::sendMessage: Send Data is nullptr" << std::endl; - return RETURN_FAILED; - } - if(sendLen == 0) { return RETURN_OK; } + if(sendData == nullptr) { + sif::warning << "UartComIF::sendMessage: Send data is nullptr" << std::endl; + return RETURN_FAILED; + } + UartCookie* uartCookie = dynamic_cast(cookie); if(uartCookie == nullptr) { - sif::debug << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl; + sif::warning << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl; return NULLPOINTER; } diff --git a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp index 339c7451..1c52e9cd 100644 --- a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp @@ -4,8 +4,8 @@ UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode, uint32_t baudrate, size_t maxReplyLen): - handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode), baudrate(baudrate), - maxReplyLen(maxReplyLen) { + handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode), + baudrate(baudrate), maxReplyLen(maxReplyLen) { } UartCookie::~UartCookie() {} diff --git a/src/fsfw/devicehandlers/DeviceCommunicationIF.h b/src/fsfw/devicehandlers/DeviceCommunicationIF.h index e0b473d3..527e4700 100644 --- a/src/fsfw/devicehandlers/DeviceCommunicationIF.h +++ b/src/fsfw/devicehandlers/DeviceCommunicationIF.h @@ -85,9 +85,10 @@ public: * Called by DHB in the GET_WRITE doGetWrite(). * Get send confirmation that the data in sendMessage() was sent successfully. * @param cookie - * @return - @c RETURN_OK if data was sent successfull - * - Everything else triggers falure event with - * returnvalue as parameter 1 + * @return + * - @c RETURN_OK if data was sent successfully but a reply is expected + * - NO_REPLY_EXPECTED if data was sent successfully and no reply is expected + * - Everything else to indicate failure */ virtual ReturnValue_t getSendSuccess(CookieIF *cookie) = 0; diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index dcce736e..b52cd83e 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -653,11 +653,11 @@ void DeviceHandlerBase::doGetWrite() { replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true); } - //We need to distinguish here, because a raw command never expects a reply. - //(Could be done in eRIRM, but then child implementations need to be careful. + // We need to distinguish here, because a raw command never expects a reply. + // (Could be done in eRIRM, but then child implementations need to be careful. result = enableReplyInReplyMap(cookieInfo.pendingCommand); - } else { - //always generate a failure event, so that FDIR knows what's up + } else if (result != NO_REPLY_EXPECTED) { + // always generate a failure event, so that FDIR knows what's up triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result, cookieInfo.pendingCommand->first); } diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index 53bd1e65..f6c22f0a 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -327,15 +327,17 @@ protected: * The existence of the command in the command map and the command size check against 0 are * done by the base class. * + * The base class will generate a finish reply or a step automatically as long as the + * send success is confirmed in the #getSendSuccess function call of the communication + * interface. NO_REPLY_EXPECTED should be returned for a finish reply, RETURN_OK should be + * returned for a step reply and everything else will trigger a step failure. + * * @param deviceCommand The command to build, already checked against deviceCommandMap * @param commandData Pointer to the data from the direct command * @param commandDataLen Length of commandData * @return * - @c RETURN_OK to send command after #rawPacket and #rawPacketLen * have been set. - * - @c HasActionsIF::EXECUTION_COMPLETE to generate a finish reply immediately. This can - * be used if no reply is expected. Otherwise, the developer can call #actionHelper.finish - * to finish the command handling. * - Anything else triggers an event with the return code as a parameter as well as a * step reply failed with the return code */ diff --git a/src/fsfw/devicehandlers/DeviceHandlerIF.h b/src/fsfw/devicehandlers/DeviceHandlerIF.h index 1933c571..1fc57c42 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerIF.h +++ b/src/fsfw/devicehandlers/DeviceHandlerIF.h @@ -120,7 +120,8 @@ public: static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5); static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6); static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7); - static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); //!< Used to indicate that this is a command-only command. + //!< Used to indicate that this is a command-only command. + static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9); static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA); diff --git a/src/fsfw/pus/Service8FunctionManagement.cpp b/src/fsfw/pus/Service8FunctionManagement.cpp index 39e872a0..48820d6e 100644 --- a/src/fsfw/pus/Service8FunctionManagement.cpp +++ b/src/fsfw/pus/Service8FunctionManagement.cpp @@ -33,8 +33,8 @@ ReturnValue_t Service8FunctionManagement::getMessageQueueAndObject( if(tcDataLen < sizeof(object_id_t)) { return CommandingServiceBase::INVALID_TC; } - SerializeAdapter::deSerialize(objectId, &tcData, - &tcDataLen, SerializeIF::Endianness::BIG); + // Can't fail, size was checked before + SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::BIG); return checkInterfaceAndAcquireMessageQueue(id,objectId); } diff --git a/src/fsfw/pus/servicepackets/Service1Packets.h b/src/fsfw/pus/servicepackets/Service1Packets.h index 2249b4b0..02ae339f 100644 --- a/src/fsfw/pus/servicepackets/Service1Packets.h +++ b/src/fsfw/pus/servicepackets/Service1Packets.h @@ -13,10 +13,10 @@ /** * @brief FailureReport class to serialize a failure report - * @brief Subservice 1, 3, 5, 7 + * @brief Subservice 2, 4, 6, 8 * @ingroup spacepackets */ -class FailureReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 3, 5, 7 +class FailureReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6, 8 public: FailureReport(uint8_t failureSubtype_, uint16_t packetId_, uint16_t packetSequenceControl_, uint8_t stepNumber_, @@ -108,10 +108,10 @@ private: }; /** - * @brief Subservices 2, 4, 6, 8 + * @brief Subservices 1, 3, 5, 7 * @ingroup spacepackets */ -class SuccessReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6, 8 +class SuccessReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 3, 5, 7 public: SuccessReport(uint8_t subtype_, uint16_t packetId_, uint16_t packetSequenceControl_,uint8_t stepNumber_) : From dfe49cc1e5fd21851bb935e6b3f9714bfefef373 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 8 Sep 2021 16:08:13 +0200 Subject: [PATCH 15/48] DHB improvements --- .../devicehandlers/DeviceCommunicationIF.h | 7 ++++--- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 21 ++++++++++++++----- src/fsfw/devicehandlers/DeviceHandlerBase.h | 8 ++++--- src/fsfw/devicehandlers/DeviceHandlerIF.h | 3 ++- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/fsfw/devicehandlers/DeviceCommunicationIF.h b/src/fsfw/devicehandlers/DeviceCommunicationIF.h index e0b473d3..527e4700 100644 --- a/src/fsfw/devicehandlers/DeviceCommunicationIF.h +++ b/src/fsfw/devicehandlers/DeviceCommunicationIF.h @@ -85,9 +85,10 @@ public: * Called by DHB in the GET_WRITE doGetWrite(). * Get send confirmation that the data in sendMessage() was sent successfully. * @param cookie - * @return - @c RETURN_OK if data was sent successfull - * - Everything else triggers falure event with - * returnvalue as parameter 1 + * @return + * - @c RETURN_OK if data was sent successfully but a reply is expected + * - NO_REPLY_EXPECTED if data was sent successfully and no reply is expected + * - Everything else to indicate failure */ virtual ReturnValue_t getSendSuccess(CookieIF *cookie) = 0; diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 96fe031a..c7944796 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -648,11 +648,12 @@ void DeviceHandlerBase::doGetWrite() { replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true); } - //We need to distinguish here, because a raw command never expects a reply. - //(Could be done in eRIRM, but then child implementations need to be careful. + // We need to distinguish here, because a raw command never expects a reply. + // This could be done in the #enableReplyInReplyMap call, + // but then child implementations would need to be careful. result = enableReplyInReplyMap(cookieInfo.pendingCommand); - } else { - //always generate a failure event, so that FDIR knows what's up + } else if (result != NO_REPLY_EXPECTED) { + // always generate a failure event, so that FDIR knows what's up triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result, cookieInfo.pendingCommand->first); } @@ -1336,10 +1337,20 @@ void DeviceHandlerBase::buildInternalCommand(void) { DeviceCommandMap::iterator iter = deviceCommandMap.find( deviceCommandId); if (iter == deviceCommandMap.end()) { +#if FSFW_VERBOSE_LEVEL >= 1 + char output[36]; + sprintf(output, "Command 0x%08x unknown", + static_cast(deviceCommandId)); + // so we can track misconfigurations + printWarningOrError(sif::OutputTypes::OUT_WARNING, + "buildInternalCommand", + COMMAND_NOT_SUPPORTED, + output); +#endif result = COMMAND_NOT_SUPPORTED; } else if (iter->second.isExecuting) { -#if FSFW_DISABLE_PRINTOUT == 0 +#if FSFW_VERBOSE_LEVEL >= 1 char output[36]; sprintf(output, "Command 0x%08x is executing", static_cast(deviceCommandId)); diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index 53bd1e65..f6c22f0a 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -327,15 +327,17 @@ protected: * The existence of the command in the command map and the command size check against 0 are * done by the base class. * + * The base class will generate a finish reply or a step automatically as long as the + * send success is confirmed in the #getSendSuccess function call of the communication + * interface. NO_REPLY_EXPECTED should be returned for a finish reply, RETURN_OK should be + * returned for a step reply and everything else will trigger a step failure. + * * @param deviceCommand The command to build, already checked against deviceCommandMap * @param commandData Pointer to the data from the direct command * @param commandDataLen Length of commandData * @return * - @c RETURN_OK to send command after #rawPacket and #rawPacketLen * have been set. - * - @c HasActionsIF::EXECUTION_COMPLETE to generate a finish reply immediately. This can - * be used if no reply is expected. Otherwise, the developer can call #actionHelper.finish - * to finish the command handling. * - Anything else triggers an event with the return code as a parameter as well as a * step reply failed with the return code */ diff --git a/src/fsfw/devicehandlers/DeviceHandlerIF.h b/src/fsfw/devicehandlers/DeviceHandlerIF.h index 1933c571..1fc57c42 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerIF.h +++ b/src/fsfw/devicehandlers/DeviceHandlerIF.h @@ -120,7 +120,8 @@ public: static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5); static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6); static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7); - static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); //!< Used to indicate that this is a command-only command. + //!< Used to indicate that this is a command-only command. + static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9); static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA); From 41f3d7cf9a5a0360a2abda34dc5abb0a2dc71802 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 8 Sep 2021 16:58:30 +0200 Subject: [PATCH 16/48] better name for function --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 2 +- src/fsfw/devicehandlers/DeviceHandlerBase.h | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 4d1d09bc..e7de914b 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -1566,7 +1566,7 @@ LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() { return &poolManager; } -MessageQueueId_t DeviceHandlerBase::getCommanderId(DeviceCommandId_t replyId) const { +MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyId) const { auto commandIter = deviceCommandMap.find(replyId); if(commandIter == deviceCommandMap.end()) { return MessageQueueIF::NO_QUEUE; diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index f6c22f0a..e8ef9ada 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -332,6 +332,9 @@ protected: * interface. NO_REPLY_EXPECTED should be returned for a finish reply, RETURN_OK should be * returned for a step reply and everything else will trigger a step failure. * + * If the commander ID is required for generating a finish reply immediately, it can be + * retrieved using the #getCommanderQueueId function. + * * @param deviceCommand The command to build, already checked against deviceCommandMap * @param commandData Pointer to the data from the direct command * @param commandDataLen Length of commandData @@ -401,7 +404,7 @@ protected: */ virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) = 0; - MessageQueueId_t getCommanderId(DeviceCommandId_t replyId) const; + MessageQueueId_t getCommanderQueueId(DeviceCommandId_t replyId) const; /** * Helper function to get pending command. This is useful for devices * like SPI sensors to identify the last sent command. From a8167f5431b73ea67b82b84740b48646a4b6e35a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 8 Sep 2021 17:02:08 +0200 Subject: [PATCH 17/48] added another helper function --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 8 ++++++++ src/fsfw/devicehandlers/DeviceHandlerBase.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index e7de914b..b14a46e9 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -1573,3 +1573,11 @@ MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyI } return commandIter->second.sendReplyTo; } + +void DeviceHandlerBase::finishCommandExecution(DeviceCommandId_t replyId) { + auto commandIter = deviceCommandMap.find(replyId); + if(commandIter == deviceCommandMap.end()) { + return; + } + commandIter->second.isExecuting = false; +} diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index e8ef9ada..aaf9d4ab 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -405,6 +405,8 @@ protected: virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) = 0; MessageQueueId_t getCommanderQueueId(DeviceCommandId_t replyId) const; + void finishCommandExecution(DeviceCommandId_t replyId); + /** * Helper function to get pending command. This is useful for devices * like SPI sensors to identify the last sent command. From 40adca5f1d13ef8d6c712842ebc37e37fe449446 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 8 Sep 2021 17:24:33 +0200 Subject: [PATCH 18/48] set reply recipient --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 7 ++++++- src/fsfw/osal/linux/MessageQueue.cpp | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index b14a46e9..f73f027e 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -1294,19 +1294,24 @@ ReturnValue_t DeviceHandlerBase::executeAction(ActionId_t actionId, return result; } DeviceCommandMap::iterator iter = deviceCommandMap.find(actionId); + MessageQueueId_t previousReplyRecipient = iter->second.sendReplyTo; if (iter == deviceCommandMap.end()) { result = COMMAND_NOT_SUPPORTED; } else if (iter->second.isExecuting) { result = COMMAND_ALREADY_SENT; } else { + // Set this so it can be used to finish a command immediately + iter->second.sendReplyTo = commandedBy; result = buildCommandFromCommand(actionId, data, size); } if (result == RETURN_OK) { - iter->second.sendReplyTo = commandedBy; iter->second.isExecuting = true; cookieInfo.pendingCommand = iter; cookieInfo.state = COOKIE_WRITE_READY; } + else { + iter->second.sendReplyTo = previousReplyRecipient; + } return result; } diff --git a/src/fsfw/osal/linux/MessageQueue.cpp b/src/fsfw/osal/linux/MessageQueue.cpp index b068c04f..d028f9f7 100644 --- a/src/fsfw/osal/linux/MessageQueue.cpp +++ b/src/fsfw/osal/linux/MessageQueue.cpp @@ -285,10 +285,10 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, utility::printUnixErrorGeneric(CLASS_NAME, "sendMessageFromMessageQueue", "EBADF"); #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "mq_send to: " << sendTo << " sent from " - << sentFrom << "failed" << std::endl; + sif::warning << "mq_send to " << sendTo << " sent from " + << sentFrom << " failed" << std::endl; #else - sif::printWarning("mq_send to: %d sent from %d failed\n", sendTo, sentFrom); + sif::printWarning("mq_send to %d sent from %d failed\n", sendTo, sentFrom); #endif return DESTINATION_INVALID; } From 6db5011b14f7f17605c939c6164ccd6a79c425d8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Sep 2021 16:55:24 +0200 Subject: [PATCH 19/48] spi and gyro l3g updates --- .../devicehandlers/GyroL3GD20Handler.cpp | 42 +++++++++---------- .../devicehandlers/GyroL3GD20Handler.h | 11 ++--- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 3 +- hal/src/fsfw_hal/linux/spi/SpiCookie.cpp | 2 +- hal/src/fsfw_hal/linux/spi/SpiCookie.h | 6 +-- 5 files changed, 30 insertions(+), 34 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp index 96d284e1..4a492e5d 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp @@ -3,9 +3,9 @@ #include "fsfw/datapool/PoolReadGuard.h" GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication, - CookieIF *comCookie): + CookieIF *comCookie, uint8_t switchId, uint32_t transitionDelayMs): DeviceHandlerBase(objectId, deviceCommunication, comCookie), - dataset(this) { + switchId(switchId), transitionDelayMs(transitionDelayMs), dataset(this) { #if FSFW_HAL_L3GD20_GYRO_DEBUG == 1 debugDivider = new PeriodicOperationDivider(5); #endif @@ -47,7 +47,7 @@ ReturnValue_t GyroHandlerL3GD20H::buildTransitionDeviceCommand(DeviceCommandId_t switch(internalState) { case(InternalState::NONE): case(InternalState::NORMAL): { - return HasReturnvaluesIF::RETURN_OK; + return NOTHING_TO_SEND; } case(InternalState::CONFIGURE): { *id = L3GD20H::CONFIGURE_CTRL_REGS; @@ -66,10 +66,11 @@ ReturnValue_t GyroHandlerL3GD20H::buildTransitionDeviceCommand(DeviceCommandId_t default: #if FSFW_CPP_OSTREAM_ENABLED == 1 /* Might be a configuration error. */ - sif::debug << "GyroHandler::buildTransitionDeviceCommand: Unknown internal state!" << - std::endl; + sif::warning << "GyroL3GD20Handler::buildTransitionDeviceCommand: " + "Unknown internal state!" << std::endl; #else - sif::printDebug("GyroHandler::buildTransitionDeviceCommand: Unknown internal state!\n"); + sif::printDebug("GyroL3GD20Handler::buildTransitionDeviceCommand: " + "Unknown internal state!\n"); #endif return HasReturnvaluesIF::RETURN_OK; } @@ -144,7 +145,7 @@ ReturnValue_t GyroHandlerL3GD20H::buildCommandFromCommand( ReturnValue_t GyroHandlerL3GD20H::scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, size_t *foundLen) { - /* For SPI, the ID will always be the one of the last sent command. */ + // For SPI, the ID will always be the one of the last sent command *foundId = this->getPendingCommand(); *foundLen = this->rawPacketLen; @@ -166,7 +167,7 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id, commandExecuted = true; } else { - /* Attempt reconfiguration. */ + // Attempt reconfiguration internalState = InternalState::CONFIGURE; return DeviceHandlerIF::DEVICE_REPLY_INVALID; } @@ -199,13 +200,12 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id, if(debugDivider->checkAndIncrement()) { /* Set terminal to utf-8 if there is an issue with micro printout. */ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "GyroHandlerL3GD20H: Angular velocities in degrees per second:" << - std::endl; - sif::info << "X: " << angVelocX << " \xC2\xB0" << std::endl; - sif::info << "Y: " << angVelocY << " \xC2\xB0" << std::endl; - sif::info << "Z: " << angVelocZ << " \xC2\xB0" << std::endl; + sif::info << "GyroHandlerL3GD20H: Angular velocities (deg/s):" << std::endl; + sif::info << "X: " << angVelocX << std::endl; + sif::info << "Y: " << angVelocY << std::endl; + sif::info << "Z: " << angVelocZ << std::endl; #else - sif::printInfo("GyroHandlerL3GD20H: Angular velocities in degrees per second:\n"); + sif::printInfo("GyroHandlerL3GD20H: Angular velocities (deg/s):\n"); sif::printInfo("X: %f\n", angVelocX); sif::printInfo("Y: %f\n", angVelocY); sif::printInfo("Z: %f\n", angVelocZ); @@ -231,7 +231,7 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id, uint32_t GyroHandlerL3GD20H::getTransitionDelayMs(Mode_t from, Mode_t to) { - return 10000; + return this->transitionDelayMs; } void GyroHandlerL3GD20H::setGoNormalModeAtStartup() { @@ -240,14 +240,10 @@ void GyroHandlerL3GD20H::setGoNormalModeAtStartup() { ReturnValue_t GyroHandlerL3GD20H::initializeLocalDataPool( localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { - localDataPoolMap.emplace(L3GD20H::ANG_VELOC_X, - new PoolEntry({0.0})); - localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Y, - new PoolEntry({0.0})); - localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Z, - new PoolEntry({0.0})); - localDataPoolMap.emplace(L3GD20H::TEMPERATURE, - new PoolEntry({0.0})); + localDataPoolMap.emplace(L3GD20H::ANG_VELOC_X, new PoolEntry({0.0})); + localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Y, new PoolEntry({0.0})); + localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Z, new PoolEntry({0.0})); + localDataPoolMap.emplace(L3GD20H::TEMPERATURE, new PoolEntry({0.0})); return HasReturnvaluesIF::RETURN_OK; } diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h index 020c5a32..bc1d9c1c 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h @@ -7,10 +7,6 @@ #include #include -#ifndef FSFW_HAL_L3GD20_GYRO_DEBUG -#define FSFW_HAL_L3GD20_GYRO_DEBUG 0 -#endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */ - /** * @brief Device Handler for the L3GD20H gyroscope sensor * (https://www.st.com/en/mems-and-sensors/l3gd20h.html) @@ -23,9 +19,12 @@ class GyroHandlerL3GD20H: public DeviceHandlerBase { public: GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication, - CookieIF* comCookie); + CookieIF* comCookie, uint8_t switchId, uint32_t transitionDelayMs = 10000); virtual ~GyroHandlerL3GD20H(); + /** + * @brief Configure device handler to go to normal mode immediately + */ void setGoNormalModeAtStartup(); protected: @@ -51,6 +50,8 @@ protected: LocalDataPoolManager &poolManager) override; private: + uint8_t switchId = 0; + uint32_t transitionDelayMs = 0; GyroPrimaryDataset dataset; enum class InternalState { diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index 2acf41e6..6cf6675f 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -188,7 +188,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie *spiCookie, const spiCookie->getSpiParameters(spiMode, spiSpeed, nullptr); setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); spiCookie->assignWriteBuffer(sendData); - spiCookie->assignTransferSize(sendLen); + spiCookie->setTransferSize(sendLen); bool fullDuplex = spiCookie->isFullDuplex(); gpioId_t gpioId = spiCookie->getChipSelectPin(); @@ -330,6 +330,7 @@ ReturnValue_t SpiComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, *buffer = rxBuf; *size = spiCookie->getCurrentTransferSize(); + spiCookie->setTransferSize(0); return HasReturnvaluesIF::RETURN_OK; } diff --git a/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp b/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp index 54d8aa16..f07954e9 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiCookie.cpp @@ -121,7 +121,7 @@ bool SpiCookie::isFullDuplex() const { return not this->halfDuplex; } -void SpiCookie::assignTransferSize(size_t transferSize) { +void SpiCookie::setTransferSize(size_t transferSize) { spiTransferStruct.len = transferSize; } diff --git a/hal/src/fsfw_hal/linux/spi/SpiCookie.h b/hal/src/fsfw_hal/linux/spi/SpiCookie.h index acf7c77c..844fd421 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiCookie.h +++ b/hal/src/fsfw_hal/linux/spi/SpiCookie.h @@ -103,10 +103,10 @@ public: void assignReadBuffer(uint8_t* rx); void assignWriteBuffer(const uint8_t* tx); /** - * Assign size for the next transfer. + * Set size for the next transfer. Set to 0 for no transfer * @param transferSize */ - void assignTransferSize(size_t transferSize); + void setTransferSize(size_t transferSize); size_t getCurrentTransferSize() const; struct UncommonParameters { @@ -158,8 +158,6 @@ private: std::string spiDev, const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed, spi::send_callback_function_t callback, void* args); - size_t currentTransferSize = 0; - address_t spiAddress; gpioId_t chipSelectPin; std::string spiDevice; From bdd7d59d82a0b9290d77844fbcc5be61c61bcbcb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Sep 2021 17:05:52 +0200 Subject: [PATCH 20/48] reverted some changes --- src/fsfw/devicehandlers/DeviceHandlerBase.cpp | 38 +++++----------- src/fsfw/devicehandlers/DeviceHandlerBase.h | 45 ++++++++----------- 2 files changed, 31 insertions(+), 52 deletions(-) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 71f31de0..535113fd 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -461,7 +461,7 @@ size_t DeviceHandlerBase::getNextReplyLength(DeviceCommandId_t commandId){ return iter->second.replyLen; }else{ return 0; - } + } } ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply, @@ -612,15 +612,15 @@ void DeviceHandlerBase::replyToReply(const DeviceCommandId_t command, DeviceRepl } DeviceCommandInfo* info = &replyInfo.command->second; if (info == nullptr){ - printWarningOrError(sif::OutputTypes::OUT_ERROR, - "replyToReply", HasReturnvaluesIF::RETURN_FAILED, - "Command pointer not found"); - return; + printWarningOrError(sif::OutputTypes::OUT_ERROR, + "replyToReply", HasReturnvaluesIF::RETURN_FAILED, + "Command pointer not found"); + return; } if (info->expectedReplies > 0){ - // Check before to avoid underflow - info->expectedReplies--; + // Check before to avoid underflow + info->expectedReplies--; } // Check if more replies are expected. If so, do nothing. if (info->expectedReplies == 0) { @@ -667,12 +667,11 @@ void DeviceHandlerBase::doGetWrite() { replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true); } - // We need to distinguish here, because a raw command never expects a reply. - // This could be done in the #enableReplyInReplyMap call, - // but then child implementations would need to be careful. + //We need to distinguish here, because a raw command never expects a reply. + //(Could be done in eRIRM, but then child implementations need to be careful. result = enableReplyInReplyMap(cookieInfo.pendingCommand); - } else if (result != NO_REPLY_EXPECTED) { - // always generate a failure event, so that FDIR knows what's up + } else { + //always generate a failure event, so that FDIR knows what's up triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result, cookieInfo.pendingCommand->first); } @@ -1308,24 +1307,19 @@ ReturnValue_t DeviceHandlerBase::executeAction(ActionId_t actionId, return result; } DeviceCommandMap::iterator iter = deviceCommandMap.find(actionId); - MessageQueueId_t previousReplyRecipient = iter->second.sendReplyTo; if (iter == deviceCommandMap.end()) { result = COMMAND_NOT_SUPPORTED; } else if (iter->second.isExecuting) { result = COMMAND_ALREADY_SENT; } else { - // Set this so it can be used to finish a command immediately - iter->second.sendReplyTo = commandedBy; result = buildCommandFromCommand(actionId, data, size); } if (result == RETURN_OK) { + iter->second.sendReplyTo = commandedBy; iter->second.isExecuting = true; cookieInfo.pendingCommand = iter; cookieInfo.state = COOKIE_WRITE_READY; } - else { - iter->second.sendReplyTo = previousReplyRecipient; - } return result; } @@ -1592,11 +1586,3 @@ MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyI } return commandIter->second.sendReplyTo; } - -void DeviceHandlerBase::finishCommandExecution(DeviceCommandId_t replyId) { - auto commandIter = deviceCommandMap.find(replyId); - if(commandIter == deviceCommandMap.end()) { - return; - } - commandIter->second.isExecuting = false; -} diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index 2843e5ea..b182b611 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -6,22 +6,22 @@ #include "DeviceHandlerFailureIsolation.h" #include "DeviceHandlerThermalSet.h" -#include "../serviceinterface/ServiceInterface.h" -#include "../serviceinterface/serviceInterfaceDefintions.h" -#include "../objectmanager/SystemObject.h" -#include "../tasks/ExecutableObjectIF.h" -#include "../returnvalues/HasReturnvaluesIF.h" -#include "../action/HasActionsIF.h" -#include "../datapool/PoolVariableIF.h" -#include "../modes/HasModesIF.h" -#include "../power/PowerSwitchIF.h" -#include "../ipc/MessageQueueIF.h" -#include "../tasks/PeriodicTaskIF.h" -#include "../action/ActionHelper.h" -#include "../health/HealthHelper.h" -#include "../parameters/ParameterHelper.h" -#include "../datapoollocal/HasLocalDataPoolIF.h" -#include "../datapoollocal/LocalDataPoolManager.h" +#include "fsfw/serviceinterface/ServiceInterface.h" +#include "fsfw/serviceinterface/serviceInterfaceDefintions.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw/action/HasActionsIF.h" +#include "fsfw/datapool/PoolVariableIF.h" +#include "fsfw/modes/HasModesIF.h" +#include "fsfw/power/PowerSwitchIF.h" +#include "fsfw/ipc/MessageQueueIF.h" +#include "fsfw/tasks/PeriodicTaskIF.h" +#include "fsfw/action/ActionHelper.h" +#include "fsfw/health/HealthHelper.h" +#include "fsfw/parameters/ParameterHelper.h" +#include "fsfw/datapoollocal/HasLocalDataPoolIF.h" +#include "fsfw/datapoollocal/LocalDataPoolManager.h" #include @@ -327,20 +327,15 @@ protected: * The existence of the command in the command map and the command size check against 0 are * done by the base class. * - * The base class will generate a finish reply or a step automatically as long as the - * send success is confirmed in the #getSendSuccess function call of the communication - * interface. NO_REPLY_EXPECTED should be returned for a finish reply, RETURN_OK should be - * returned for a step reply and everything else will trigger a step failure. - * - * If the commander ID is required for generating a finish reply immediately, it can be - * retrieved using the #getCommanderQueueId function. - * * @param deviceCommand The command to build, already checked against deviceCommandMap * @param commandData Pointer to the data from the direct command * @param commandDataLen Length of commandData * @return * - @c RETURN_OK to send command after #rawPacket and #rawPacketLen * have been set. + * - @c HasActionsIF::EXECUTION_COMPLETE to generate a finish reply immediately. This can + * be used if no reply is expected. Otherwise, the developer can call #actionHelper.finish + * to finish the command handling. * - Anything else triggers an event with the return code as a parameter as well as a * step reply failed with the return code */ @@ -405,8 +400,6 @@ protected: virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) = 0; MessageQueueId_t getCommanderQueueId(DeviceCommandId_t replyId) const; - void finishCommandExecution(DeviceCommandId_t replyId); - /** * Helper function to get pending command. This is useful for devices * like SPI sensors to identify the last sent command. From d986ab77200ae28e69d8818443856e7812e81ed4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Sep 2021 18:37:44 +0200 Subject: [PATCH 21/48] bugfix for TM packet stored PUS C --- src/fsfw/tmtcpacket/SpacePacketBase.cpp | 21 +++++++--- src/fsfw/tmtcpacket/SpacePacketBase.h | 4 +- src/fsfw/tmtcpacket/pus/tm/TmPacketPusC.cpp | 8 +++- src/fsfw/tmtcpacket/pus/tm/TmPacketPusC.h | 2 +- .../tmtcpacket/pus/tm/TmPacketStoredPusC.cpp | 41 ++++++++++++++++--- 5 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/fsfw/tmtcpacket/SpacePacketBase.cpp b/src/fsfw/tmtcpacket/SpacePacketBase.cpp index 5dae94c9..cffdec9a 100644 --- a/src/fsfw/tmtcpacket/SpacePacketBase.cpp +++ b/src/fsfw/tmtcpacket/SpacePacketBase.cpp @@ -3,8 +3,8 @@ #include -SpacePacketBase::SpacePacketBase( const uint8_t* set_address ) { - this->data = (SpacePacketPointer*) set_address; +SpacePacketBase::SpacePacketBase(const uint8_t* setAddress) { + this->data = reinterpret_cast(const_cast(setAddress)); } SpacePacketBase::~SpacePacketBase() { @@ -15,10 +15,21 @@ uint8_t SpacePacketBase::getPacketVersionNumber( void ) { return (this->data->header.packet_id_h & 0b11100000) >> 5; } -void SpacePacketBase::initSpacePacketHeader(bool isTelecommand, +ReturnValue_t SpacePacketBase::initSpacePacketHeader(bool isTelecommand, bool hasSecondaryHeader, uint16_t apid, uint16_t sequenceCount) { + if(data == nullptr) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "SpacePacketBase::initSpacePacketHeader: Data pointer is invalid" + << std::endl; +#else + sif::printWarning("SpacePacketBase::initSpacePacketHeader: Data pointer is invalid!\n"); +#endif +#endif + return HasReturnvaluesIF::RETURN_FAILED; + } //reset header to zero: - memset(data,0, sizeof(this->data->header) ); + memset(data, 0, sizeof(this->data->header) ); //Set TC/TM bit. data->header.packet_id_h = ((isTelecommand? 1 : 0)) << 4; //Set secondaryHeader bit @@ -27,7 +38,7 @@ void SpacePacketBase::initSpacePacketHeader(bool isTelecommand, //Always initialize as standalone packets. data->header.sequence_control_h = 0b11000000; setPacketSequenceCount(sequenceCount); - + return HasReturnvaluesIF::RETURN_OK; } bool SpacePacketBase::isTelecommand( void ) { diff --git a/src/fsfw/tmtcpacket/SpacePacketBase.h b/src/fsfw/tmtcpacket/SpacePacketBase.h index 3cd3e552..fae64745 100644 --- a/src/fsfw/tmtcpacket/SpacePacketBase.h +++ b/src/fsfw/tmtcpacket/SpacePacketBase.h @@ -2,6 +2,8 @@ #define FSFW_TMTCPACKET_SPACEPACKETBASE_H_ #include "ccsds_header.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" + #include /** @@ -82,7 +84,7 @@ public: */ bool isTelecommand( void ); - void initSpacePacketHeader(bool isTelecommand, bool hasSecondaryHeader, + ReturnValue_t initSpacePacketHeader(bool isTelecommand, bool hasSecondaryHeader, uint16_t apid, uint16_t sequenceCount = 0); /** * The CCSDS header provides a secondary header flag (the fifth-highest bit), diff --git a/src/fsfw/tmtcpacket/pus/tm/TmPacketPusC.cpp b/src/fsfw/tmtcpacket/pus/tm/TmPacketPusC.cpp index ea25f5d2..2c6e1d97 100644 --- a/src/fsfw/tmtcpacket/pus/tm/TmPacketPusC.cpp +++ b/src/fsfw/tmtcpacket/pus/tm/TmPacketPusC.cpp @@ -53,11 +53,14 @@ uint8_t* TmPacketPusC::getPacketTimeRaw() const{ } -void TmPacketPusC::initializeTmPacket(uint16_t apid, uint8_t service, +ReturnValue_t TmPacketPusC::initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, uint16_t packetSubcounter, uint16_t destinationId, uint8_t timeRefField) { //Set primary header: - initSpacePacketHeader(false, true, apid); + ReturnValue_t result = initSpacePacketHeader(false, true, apid); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } //Set data Field Header: //First, set to zero. memset(&tmData->dataField, 0, sizeof(tmData->dataField)); @@ -76,6 +79,7 @@ void TmPacketPusC::initializeTmPacket(uint16_t apid, uint8_t service, timeStamper->addTimeStamp(tmData->dataField.time, sizeof(tmData->dataField.time)); } + return HasReturnvaluesIF::RETURN_OK; } void TmPacketPusC::setSourceDataSize(uint16_t size) { diff --git a/src/fsfw/tmtcpacket/pus/tm/TmPacketPusC.h b/src/fsfw/tmtcpacket/pus/tm/TmPacketPusC.h index fe373c6f..3a9be132 100644 --- a/src/fsfw/tmtcpacket/pus/tm/TmPacketPusC.h +++ b/src/fsfw/tmtcpacket/pus/tm/TmPacketPusC.h @@ -100,7 +100,7 @@ protected: * @param subservice PUS Subservice * @param packetSubcounter Additional subcounter used. */ - void initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, + ReturnValue_t initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, uint16_t packetSubcounter, uint16_t destinationId = 0, uint8_t timeRefField = 0); /** diff --git a/src/fsfw/tmtcpacket/pus/tm/TmPacketStoredPusC.cpp b/src/fsfw/tmtcpacket/pus/tm/TmPacketStoredPusC.cpp index add4f4b9..84f8d28e 100644 --- a/src/fsfw/tmtcpacket/pus/tm/TmPacketStoredPusC.cpp +++ b/src/fsfw/tmtcpacket/pus/tm/TmPacketStoredPusC.cpp @@ -43,27 +43,56 @@ TmPacketStoredPusC::TmPacketStoredPusC(uint16_t apid, uint8_t service, return; } size_t sourceDataSize = 0; - if (content != NULL) { + if (content != nullptr) { sourceDataSize += content->getSerializedSize(); } - if (header != NULL) { + if (header != nullptr) { sourceDataSize += header->getSerializedSize(); } - uint8_t *p_data = NULL; + uint8_t *p_data = nullptr; + size_t sizeToReserve = getPacketMinimumSize() + sourceDataSize; ReturnValue_t returnValue = store->getFreeElement(&storeAddress, - (getPacketMinimumSize() + sourceDataSize), &p_data); + sizeToReserve, &p_data); if (returnValue != store->RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 + switch(returnValue) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + case(StorageManagerIF::DATA_STORAGE_FULL): { + sif::warning << "TmPacketStoredPusC::TmPacketStoredPusC: Store full for packet with " + "size " << sizeToReserve << std::endl; + break; + } + case(StorageManagerIF::DATA_TOO_LARGE): { + sif::warning << "TmPacketStoredPusC::TmPacketStoredPusC: Data with size " << + sizeToReserve << " too large" << std::endl; + break; + } +#else + case(StorageManagerIF::DATA_STORAGE_FULL): { + sif::printWarning("TmPacketStoredPusC::TmPacketStoredPusC: Store full for packet with " + "size %d\n", sizeToReserve); + break; + } + case(StorageManagerIF::DATA_TOO_LARGE): { + sif::printWarning("TmPacketStoredPusC::TmPacketStoredPusC: Data with size " + "%d too large\n", sizeToReserve); + break; + } +#endif +#endif + } TmPacketStoredBase::checkAndReportLostTm(); + return; } setData(p_data); initializeTmPacket(apid, service, subservice, packetSubcounter, destinationId, timeRefField); uint8_t *putDataHere = getSourceData(); size_t size = 0; - if (header != NULL) { + if (header != nullptr) { header->serialize(&putDataHere, &size, sourceDataSize, SerializeIF::Endianness::BIG); } - if (content != NULL) { + if (content != nullptr) { content->serialize(&putDataHere, &size, sourceDataSize, SerializeIF::Endianness::BIG); } From bc6b29e652a90f5a14bb32a1bcc2a956e410e678 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Sep 2021 18:48:09 +0200 Subject: [PATCH 22/48] use warning instead of debug --- src/fsfw/pus/Service5EventReporting.cpp | 10 ++++++---- src/fsfw/tmtcpacket/pus/tm/TmPacketStoredPusC.cpp | 7 +++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/fsfw/pus/Service5EventReporting.cpp b/src/fsfw/pus/Service5EventReporting.cpp index 36aa7e70..2293ab20 100644 --- a/src/fsfw/pus/Service5EventReporting.cpp +++ b/src/fsfw/pus/Service5EventReporting.cpp @@ -41,8 +41,7 @@ ReturnValue_t Service5EventReporting::performService() { } } #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "Service5EventReporting::generateEventReport:" - " Too many events" << std::endl; + sif::warning << "Service5EventReporting::generateEventReport: Too many events" << std::endl; #endif return HasReturnvaluesIF::RETURN_OK; } @@ -64,8 +63,11 @@ ReturnValue_t Service5EventReporting::generateEventReport( requestQueue->getDefaultDestination(),requestQueue->getId()); if(result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "Service5EventReporting::generateEventReport:" - " Could not send TM packet" << std::endl; + sif::warning << "Service5EventReporting::generateEventReport: " + "Could not send TM packet" << std::endl; +#else + sif::printWarning("Service5EventReporting::generateEventReport: " + "Could not send TM packet\n"); #endif } return result; diff --git a/src/fsfw/tmtcpacket/pus/tm/TmPacketStoredPusC.cpp b/src/fsfw/tmtcpacket/pus/tm/TmPacketStoredPusC.cpp index 84f8d28e..4a6e4d21 100644 --- a/src/fsfw/tmtcpacket/pus/tm/TmPacketStoredPusC.cpp +++ b/src/fsfw/tmtcpacket/pus/tm/TmPacketStoredPusC.cpp @@ -49,10 +49,9 @@ TmPacketStoredPusC::TmPacketStoredPusC(uint16_t apid, uint8_t service, if (header != nullptr) { sourceDataSize += header->getSerializedSize(); } - uint8_t *p_data = nullptr; + uint8_t *pData = nullptr; size_t sizeToReserve = getPacketMinimumSize() + sourceDataSize; - ReturnValue_t returnValue = store->getFreeElement(&storeAddress, - sizeToReserve, &p_data); + ReturnValue_t returnValue = store->getFreeElement(&storeAddress, sizeToReserve, &pData); if (returnValue != store->RETURN_OK) { #if FSFW_VERBOSE_LEVEL >= 1 switch(returnValue) { @@ -84,7 +83,7 @@ TmPacketStoredPusC::TmPacketStoredPusC(uint16_t apid, uint8_t service, TmPacketStoredBase::checkAndReportLostTm(); return; } - setData(p_data); + setData(pData); initializeTmPacket(apid, service, subservice, packetSubcounter, destinationId, timeRefField); uint8_t *putDataHere = getSourceData(); size_t size = 0; From 823c6ec5fc6357d342f4d0e3edc68d89ff492b87 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 16 Sep 2021 11:33:50 +0200 Subject: [PATCH 23/48] added RM3100 handler --- .../fsfw_hal/devicehandlers/CMakeLists.txt | 1 + .../devicehandlers/MgmRM3100Handler.cpp | 370 ++++++++++++++++++ .../devicehandlers/MgmRM3100Handler.h | 117 ++++++ .../devicedefinitions/MgmRM3100HandlerDefs.h | 132 +++++++ src/fsfw/FSFW.h.in | 10 +- 5 files changed, 627 insertions(+), 3 deletions(-) create mode 100644 hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp create mode 100644 hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h create mode 100644 hal/src/fsfw_hal/devicehandlers/devicedefinitions/MgmRM3100HandlerDefs.h diff --git a/hal/src/fsfw_hal/devicehandlers/CMakeLists.txt b/hal/src/fsfw_hal/devicehandlers/CMakeLists.txt index cf542d8d..eb48d190 100644 --- a/hal/src/fsfw_hal/devicehandlers/CMakeLists.txt +++ b/hal/src/fsfw_hal/devicehandlers/CMakeLists.txt @@ -1,3 +1,4 @@ target_sources(${LIB_FSFW_NAME} PRIVATE GyroL3GD20Handler.cpp + MgmRM3100Handler.cpp ) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp new file mode 100644 index 00000000..71193913 --- /dev/null +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp @@ -0,0 +1,370 @@ +#include "MgmRM3100Handler.h" + +#include "fsfw/datapool/PoolReadGuard.h" +#include "fsfw/globalfunctions/bitutility.h" +#include "fsfw/devicehandlers/DeviceHandlerMessage.h" +#include "fsfw/objectmanager/SystemObjectIF.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" + + +MgmRM3100Handler::MgmRM3100Handler(object_id_t objectId, + object_id_t deviceCommunication, CookieIF* comCookie, uint8_t switchId, + uint32_t transitionDelay): + DeviceHandlerBase(objectId, deviceCommunication, comCookie), + primaryDataset(this), switchId(switchId), transitionDelay(transitionDelay) { +#if FSFW_HAL_RM3100_MGM_DEBUG == 1 + debugDivider = new PeriodicOperationDivider(5); +#endif +} + +MgmRM3100Handler::~MgmRM3100Handler() {} + +void MgmRM3100Handler::doStartUp() { + switch(internalState) { + case(InternalState::NONE): { + internalState = InternalState::CONFIGURE_CMM; + break; + } + case(InternalState::CONFIGURE_CMM): { + internalState = InternalState::READ_CMM; + break; + } + case(InternalState::READ_CMM): { + if(commandExecuted) { + internalState = InternalState::STATE_CONFIGURE_TMRC; + } + break; + } + case(InternalState::STATE_CONFIGURE_TMRC): { + if(commandExecuted) { + internalState = InternalState::STATE_READ_TMRC; + } + break; + } + case(InternalState::STATE_READ_TMRC): { + if(commandExecuted) { + internalState = InternalState::NORMAL; + if(goToNormalModeAtStartup) { + setMode(MODE_NORMAL); + } + else { + setMode(_MODE_TO_ON); + } + } + break; + } + default: { + break; + } + } +} + +void MgmRM3100Handler::doShutDown() { + setMode(_MODE_POWER_DOWN); +} + +ReturnValue_t MgmRM3100Handler::buildTransitionDeviceCommand( + DeviceCommandId_t *id) { + size_t commandLen = 0; + switch(internalState) { + case(InternalState::NONE): + case(InternalState::NORMAL): { + return HasReturnvaluesIF::RETURN_OK; + } + case(InternalState::CONFIGURE_CMM): { + *id = RM3100::CONFIGURE_CMM; + break; + } + case(InternalState::READ_CMM): { + *id = RM3100::READ_CMM; + break; + } + case(InternalState::STATE_CONFIGURE_TMRC): { + commandBuffer[0] = RM3100::TMRC_DEFAULT_VALUE; + commandLen = 1; + *id = RM3100::CONFIGURE_TMRC; + break; + } + case(InternalState::STATE_READ_TMRC): { + *id = RM3100::READ_TMRC; + break; + } + default: + // Might be a configuration error + sif::warning << "MgmRM3100Handler::buildTransitionDeviceCommand: Unknown internal state!" << + std::endl; + return HasReturnvaluesIF::RETURN_OK; + } + + return buildCommandFromCommand(*id, commandBuffer, commandLen); +} + +ReturnValue_t MgmRM3100Handler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t *commandData, size_t commandDataLen) { + switch(deviceCommand) { + case(RM3100::CONFIGURE_CMM): { + commandBuffer[0] = RM3100::CMM_REGISTER; + commandBuffer[1] = RM3100::CMM_VALUE; + rawPacket = commandBuffer; + rawPacketLen = 2; + break; + } + case(RM3100::READ_CMM): { + commandBuffer[0] = RM3100::CMM_REGISTER | RM3100::READ_MASK; + commandBuffer[1] = 0; + rawPacket = commandBuffer; + rawPacketLen = 2; + break; + } + case(RM3100::CONFIGURE_TMRC): { + return handleTmrcConfigCommand(deviceCommand, commandData, commandDataLen); + } + case(RM3100::READ_TMRC): { + commandBuffer[0] = RM3100::TMRC_REGISTER | RM3100::READ_MASK; + commandBuffer[1] = 0; + rawPacket = commandBuffer; + rawPacketLen = 2; + break; + } + case(RM3100::CONFIGURE_CYCLE_COUNT): { + return handleCycleCountConfigCommand(deviceCommand, commandData, commandDataLen); + } + case(RM3100::READ_CYCLE_COUNT): { + commandBuffer[0] = RM3100::CYCLE_COUNT_START_REGISTER | RM3100::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; + std::memset(commandBuffer + 1, 0, 9); + rawPacketLen = 10; + break; + } + default: + return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; + } + return RETURN_OK; +} + +ReturnValue_t MgmRM3100Handler::buildNormalDeviceCommand( + DeviceCommandId_t *id) { + *id = RM3100::READ_DATA; + return buildCommandFromCommand(*id, nullptr, 0); +} + +ReturnValue_t MgmRM3100Handler::scanForReply(const uint8_t *start, + size_t len, DeviceCommandId_t *foundId, + size_t *foundLen) { + + /* For SPI, ID will always be the one of the last sent command. */ + *foundId = this->getPendingCommand(); + *foundLen = len; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + switch(id) { + case(RM3100::CONFIGURE_CMM): + case(RM3100::CONFIGURE_CYCLE_COUNT): + case(RM3100::CONFIGURE_TMRC): { + /* We can only check whether write was successful with read operation. */ + if(mode == _MODE_START_UP) { + commandExecuted = true; + } + break; + } + case(RM3100::READ_CMM): { + uint8_t cmmValue = packet[1]; + /* We clear the seventh bit in any case + * because this one is zero sometimes for some reason */ + bitutil::bitClear(&cmmValue, 6); + if(cmmValue == cmmRegValue and internalState == InternalState::READ_CMM) { + commandExecuted = true; + } + else { + /* Attempt reconfiguration. */ + internalState = InternalState::CONFIGURE_CMM; + return DeviceHandlerIF::DEVICE_REPLY_INVALID; + } + break; + } + case(RM3100::READ_TMRC): { + if(packet[1] == tmrcRegValue) { + commandExecuted = true; + /* Reading TMRC was commanded. Trigger event to inform ground. */ + if(mode != _MODE_START_UP) { + triggerEvent(tmrcSet, tmrcRegValue, 0); + } + } + else { + /* Attempt reconfiguration. */ + internalState = InternalState::STATE_CONFIGURE_TMRC; + return DeviceHandlerIF::DEVICE_REPLY_INVALID; + } + break; + } + case(RM3100::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]; + if(cycleCountX != cycleCountRegValueX or cycleCountY != cycleCountRegValueY or + cycleCountZ != cycleCountRegValueZ) { + return DeviceHandlerIF::DEVICE_REPLY_INVALID; + } + /* Reading TMRC was commanded. Trigger event to inform ground. */ + if(mode != _MODE_START_UP) { + uint32_t eventParam1 = (cycleCountX << 16) | cycleCountY; + triggerEvent(cycleCountersSet, eventParam1, cycleCountZ); + } + break; + } + case(RM3100::READ_DATA): { + result = handleDataReadout(packet); + break; + } + default: + return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; + } + + return result; +} + +ReturnValue_t MgmRM3100Handler::handleCycleCountConfigCommand(DeviceCommandId_t deviceCommand, + const uint8_t *commandData, size_t commandDataLen) { + if(commandData == nullptr) { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } + + // Set cycle count + if(commandDataLen == 2) { + handleCycleCommand(true, commandData, commandDataLen); + } + else if(commandDataLen == 6) { + handleCycleCommand(false, commandData, commandDataLen); + } + else { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } + + commandBuffer[0] = RM3100::CYCLE_COUNT_VALUE; + std::memcpy(commandBuffer + 1, &cycleCountRegValueX, 2); + std::memcpy(commandBuffer + 3, &cycleCountRegValueY, 2); + std::memcpy(commandBuffer + 5, &cycleCountRegValueZ, 2); + rawPacketLen = 7; + rawPacket = commandBuffer; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t MgmRM3100Handler::handleCycleCommand(bool oneCycleValue, + const uint8_t *commandData, size_t commandDataLen) { + RM3100::CycleCountCommand command(oneCycleValue); + ReturnValue_t result = command.deSerialize(&commandData, &commandDataLen, + SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + /* Data sheet p.30 "while noise limits the useful upper range to ~400 cycle counts." */ + if(command.cycleCountX > 450 ) { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } + + if(not oneCycleValue and (command.cycleCountY > 450 or command.cycleCountZ > 450)) { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } + + cycleCountRegValueX = command.cycleCountX; + cycleCountRegValueY = command.cycleCountY; + cycleCountRegValueZ = command.cycleCountZ; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t MgmRM3100Handler::handleTmrcConfigCommand(DeviceCommandId_t deviceCommand, + const uint8_t *commandData, size_t commandDataLen) { + if(commandData == nullptr or commandDataLen != 1) { + return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; + } + + commandBuffer[0] = RM3100::TMRC_REGISTER; + commandBuffer[1] = commandData[0]; + tmrcRegValue = commandData[0]; + rawPacketLen = 2; + rawPacket = commandBuffer; + return HasReturnvaluesIF::RETURN_OK; +} + +void MgmRM3100Handler::fillCommandAndReplyMap() { + insertInCommandAndReplyMap(RM3100::CONFIGURE_CMM, 3); + insertInCommandAndReplyMap(RM3100::READ_CMM, 3); + + insertInCommandAndReplyMap(RM3100::CONFIGURE_TMRC, 3); + insertInCommandAndReplyMap(RM3100::READ_TMRC, 3); + + insertInCommandAndReplyMap(RM3100::CONFIGURE_CYCLE_COUNT, 3); + insertInCommandAndReplyMap(RM3100::READ_CYCLE_COUNT, 3); + + insertInCommandAndReplyMap(RM3100::READ_DATA, 3, &primaryDataset); +} + +void MgmRM3100Handler::modeChanged(void) { + internalState = InternalState::NONE; +} + +ReturnValue_t MgmRM3100Handler::initializeLocalDataPool( + localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { + localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_X, new PoolEntry({0.0})); + localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Y, new PoolEntry({0.0})); + localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Z, new PoolEntry({0.0})); + return HasReturnvaluesIF::RETURN_OK; +} + +uint32_t MgmRM3100Handler::getTransitionDelayMs(Mode_t from, Mode_t to) { + return 25000; +} + +ReturnValue_t MgmRM3100Handler::getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) { + *switches = &switchId; + *numberOfSwitches = 1; + return HasReturnvaluesIF::RETURN_OK; +} + +void MgmRM3100Handler::setToGoToNormalMode(bool enable) { + goToNormalModeAtStartup = enable; +} + +ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) { + /* Analyze data here. The sensor generates 24 bit signed values so we need to do some bitshift + * trickery here to calculate the raw values first */ + int32_t fieldStrengthRawX = ((packet[1] << 24) | (packet[2] << 16) | (packet[3] << 8)) >> 8; + int32_t fieldStrengthRawY = ((packet[4] << 24) | (packet[5] << 16) | (packet[6] << 8)) >> 8; + int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[3] << 8)) >> 8; + + /* Now scale to physical value in microtesla */ + float fieldStrengthX = fieldStrengthRawX * scaleFactorX; + float fieldStrengthY = fieldStrengthRawY * scaleFactorX; + float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX; + +#if FSFW_HAL_RM3100_MGM_DEBUG == 1 + if(debugDivider->checkAndIncrement()) { + sif::info << "MgmRM3100Handler: Magnetic field strength in" + " microtesla:" << std::endl; + /* Set terminal to utf-8 if there is an issue with micro printout. */ + sif::info << "X: " << fieldStrengthX << " uT" << std::endl; + sif::info << "Y: " << fieldStrengthY << " uT" << std::endl; + sif::info << "Z: " << fieldStrengthZ << " uT" << std::endl; + } +#endif + + /* TODO: Sanity check on values */ + PoolReadGuard readGuard(&primaryDataset); + if(readGuard.getReadResult() == HasReturnvaluesIF::RETURN_OK) { + primaryDataset.fieldStrengthX = fieldStrengthX; + primaryDataset.fieldStrengthY = fieldStrengthY; + primaryDataset.fieldStrengthZ = fieldStrengthZ; + primaryDataset.setValidity(true, true); + } + return RETURN_OK; +} diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h new file mode 100644 index 00000000..eb6e62bc --- /dev/null +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h @@ -0,0 +1,117 @@ +#ifndef MISSION_DEVICES_MGMRM3100HANDLER_H_ +#define MISSION_DEVICES_MGMRM3100HANDLER_H_ + +#include "fsfw/FSFW.h" +#include "devices/powerSwitcherList.h" +#include "devicedefinitions/MgmRM3100HandlerDefs.h" +#include "fsfw/devicehandlers/DeviceHandlerBase.h" + +#if FSFW_HAL_RM3100_MGM_DEBUG == 1 +#include "fsfw/globalfunctions/PeriodicOperationDivider.h" +#endif + +/** + * @brief Device Handler for the RM3100 geomagnetic magnetometer sensor + * (https://www.pnicorp.com/rm3100/) + * @details + * Flight manual: + * https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/RM3100_MGM + */ +class MgmRM3100Handler: public DeviceHandlerBase { +public: + static const uint8_t INTERFACE_ID = CLASS_ID::MGM_RM3100; + + //! [EXPORT] : [COMMENT] P1: TMRC value which was set, P2: 0 + static constexpr Event tmrcSet = event::makeEvent(SUBSYSTEM_ID::MGM_RM3100, + 0x00, severity::INFO); + + //! [EXPORT] : [COMMENT] Cycle counter set. P1: First two bytes new Cycle Count X + //! P1: Second two bytes new Cycle Count Y + //! P2: New cycle count Z + static constexpr Event cycleCountersSet = event::makeEvent( + SUBSYSTEM_ID::MGM_RM3100, 0x01, severity::INFO); + + MgmRM3100Handler(object_id_t objectId, object_id_t deviceCommunication, + CookieIF* comCookie, uint8_t switchId, uint32_t transitionDelay = 10000); + virtual ~MgmRM3100Handler(); + + /** + * Configure device handler to go to normal mode after startup immediately + * @param enable + */ + void setToGoToNormalMode(bool enable); + +protected: + + /* DeviceHandlerBase overrides */ + ReturnValue_t buildTransitionDeviceCommand( + DeviceCommandId_t *id) override; + void doStartUp() override; + void doShutDown() override; + ReturnValue_t buildNormalDeviceCommand( + DeviceCommandId_t *id) override; + ReturnValue_t buildCommandFromCommand( + DeviceCommandId_t deviceCommand, const uint8_t *commandData, + size_t commandDataLen) override; + ReturnValue_t scanForReply(const uint8_t *start, size_t len, + DeviceCommandId_t *foundId, size_t *foundLen) override; + ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, + const uint8_t *packet) override; + ReturnValue_t getSwitches(const uint8_t **switches, + uint8_t *numberOfSwitches) override; + + void fillCommandAndReplyMap() override; + void modeChanged(void) override; + uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override; + ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, + LocalDataPoolManager &poolManager) override; + +private: + + enum class InternalState { + NONE, + CONFIGURE_CMM, + READ_CMM, + // The cycle count states are propably not going to be used because + // the default cycle count will be used. + STATE_CONFIGURE_CYCLE_COUNT, + STATE_READ_CYCLE_COUNT, + STATE_CONFIGURE_TMRC, + STATE_READ_TMRC, + NORMAL + }; + InternalState internalState = InternalState::NONE; + bool commandExecuted = false; + RM3100::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; + + bool goToNormalModeAtStartup = false; + uint8_t switchId; + uint32_t transitionDelay; + + ReturnValue_t handleCycleCountConfigCommand(DeviceCommandId_t deviceCommand, + const uint8_t *commandData,size_t commandDataLen); + ReturnValue_t handleCycleCommand(bool oneCycleValue, + const uint8_t *commandData, size_t commandDataLen); + + ReturnValue_t handleTmrcConfigCommand(DeviceCommandId_t deviceCommand, + const uint8_t *commandData,size_t commandDataLen); + + ReturnValue_t handleDataReadout(const uint8_t* packet); +#if FSFW_HAL_RM3100_MGM_DEBUG == 1 + PeriodicOperationDivider* debugDivider; +#endif +}; + +#endif /* MISSION_DEVICEHANDLING_MGMRM3100HANDLER_H_ */ diff --git a/hal/src/fsfw_hal/devicehandlers/devicedefinitions/MgmRM3100HandlerDefs.h b/hal/src/fsfw_hal/devicehandlers/devicedefinitions/MgmRM3100HandlerDefs.h new file mode 100644 index 00000000..08f80dd9 --- /dev/null +++ b/hal/src/fsfw_hal/devicehandlers/devicedefinitions/MgmRM3100HandlerDefs.h @@ -0,0 +1,132 @@ +#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_MGMHANDLERRM3100DEFINITIONS_H_ +#define MISSION_DEVICES_DEVICEDEFINITIONS_MGMHANDLERRM3100DEFINITIONS_H_ + +#include +#include +#include +#include +#include + +namespace RM3100 { + +/* Actually 10, we round up a little bit */ +static constexpr size_t MAX_BUFFER_SIZE = 12; + +static constexpr uint8_t READ_MASK = 0x80; + +/*----------------------------------------------------------------------------*/ +/* CMM Register */ +/*----------------------------------------------------------------------------*/ +static constexpr uint8_t SET_CMM_CMZ = 1 << 6; +static constexpr uint8_t SET_CMM_CMY = 1 << 5; +static constexpr uint8_t SET_CMM_CMX = 1 << 4; +static constexpr uint8_t SET_CMM_DRDM = 1 << 2; +static constexpr uint8_t SET_CMM_START = 1; +static constexpr uint8_t CMM_REGISTER = 0x01; + +static constexpr uint8_t CMM_VALUE = SET_CMM_CMZ | SET_CMM_CMY | SET_CMM_CMX | + SET_CMM_DRDM | SET_CMM_START; + +/*----------------------------------------------------------------------------*/ +/* Cycle count register */ +/*----------------------------------------------------------------------------*/ +// Default value (200) +static constexpr uint8_t CYCLE_COUNT_VALUE = 0xC8; + +static constexpr float DEFAULT_GAIN = static_cast(CYCLE_COUNT_VALUE) / + 100 * 38; +static constexpr uint8_t CYCLE_COUNT_START_REGISTER = 0x04; + +/*----------------------------------------------------------------------------*/ +/* TMRC register */ +/*----------------------------------------------------------------------------*/ +static constexpr uint8_t TMRC_150HZ_VALUE = 0x94; +static constexpr uint8_t TMRC_75HZ_VALUE = 0x95; +static constexpr uint8_t TMRC_DEFAULT_37HZ_VALUE = 0x96; + +static constexpr uint8_t TMRC_REGISTER = 0x0B; +static constexpr uint8_t TMRC_DEFAULT_VALUE = TMRC_DEFAULT_37HZ_VALUE; + +static constexpr uint8_t MEASUREMENT_REG_START = 0x24; +static constexpr uint8_t BIST_REGISTER = 0x33; +static constexpr uint8_t DATA_READY_VAL = 0b1000'0000; +static constexpr uint8_t STATUS_REGISTER = 0x34; +static constexpr uint8_t REVID_REGISTER = 0x36; + +// Range in Microtesla. 1 T equals 10000 Gauss (for comparison with LIS3 MGM) +static constexpr uint16_t RANGE = 800; + +static constexpr DeviceCommandId_t READ_DATA = 0; + +static constexpr DeviceCommandId_t CONFIGURE_CMM = 1; +static constexpr DeviceCommandId_t READ_CMM = 2; + +static constexpr DeviceCommandId_t CONFIGURE_TMRC = 3; +static constexpr DeviceCommandId_t READ_TMRC = 4; + +static constexpr DeviceCommandId_t CONFIGURE_CYCLE_COUNT = 5; +static constexpr DeviceCommandId_t READ_CYCLE_COUNT = 6; + +class CycleCountCommand: public SerialLinkedListAdapter { +public: + CycleCountCommand(bool oneCycleCount = true): oneCycleCount(oneCycleCount) { + setLinks(oneCycleCount); + } + + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override { + ReturnValue_t result = SerialLinkedListAdapter::deSerialize(buffer, + size, streamEndianness); + if(oneCycleCount) { + cycleCountY = cycleCountX; + cycleCountZ = cycleCountX; + } + return result; + } + + SerializeElement cycleCountX; + SerializeElement cycleCountY; + SerializeElement cycleCountZ; + +private: + void setLinks(bool oneCycleCount) { + setStart(&cycleCountX); + if(not oneCycleCount) { + cycleCountX.setNext(&cycleCountY); + cycleCountY.setNext(&cycleCountZ); + } + } + + bool oneCycleCount; +}; + +static constexpr uint32_t MGM_DATASET_ID = READ_DATA; + +enum MgmPoolIds: lp_id_t { + FIELD_STRENGTH_X, + FIELD_STRENGTH_Y, + FIELD_STRENGTH_Z, +}; + +class Rm3100PrimaryDataset: public StaticLocalDataSet<3 * sizeof(float)> { +public: + Rm3100PrimaryDataset(HasLocalDataPoolIF* hkOwner): + StaticLocalDataSet(hkOwner, MGM_DATASET_ID) {} + + Rm3100PrimaryDataset(object_id_t mgmId): + StaticLocalDataSet(sid_t(mgmId, MGM_DATASET_ID)) {} + + // Field strengths in micro Tesla. + lp_var_t fieldStrengthX = lp_var_t(sid.objectId, + FIELD_STRENGTH_X, this); + lp_var_t fieldStrengthY = lp_var_t(sid.objectId, + FIELD_STRENGTH_Y, this); + lp_var_t fieldStrengthZ = lp_var_t(sid.objectId, + FIELD_STRENGTH_Z, this); +}; + +} + + + +#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_MGMHANDLERRM3100DEFINITIONS_H_ */ diff --git a/src/fsfw/FSFW.h.in b/src/fsfw/FSFW.h.in index d053d3c0..e6dd2f8f 100644 --- a/src/fsfw/FSFW.h.in +++ b/src/fsfw/FSFW.h.in @@ -17,16 +17,20 @@ #cmakedefine FSFW_ADD_SGP4_PROPAGATOR #ifndef FSFW_TCP_RECV_WIRETAPPING_ENABLED -#define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0 +#define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0 #endif /* Can be used for low-level debugging of the SPI bus */ #ifndef FSFW_HAL_LINUX_SPI_WIRETAPPING -#define FSFW_HAL_LINUX_SPI_WIRETAPPING 0 +#define FSFW_HAL_LINUX_SPI_WIRETAPPING 0 #endif #ifndef FSFW_HAL_L3GD20_GYRO_DEBUG -#define FSFW_HAL_L3GD20_GYRO_DEBUG 0 +#define FSFW_HAL_L3GD20_GYRO_DEBUG 0 #endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */ +#ifndef FSFW_HAL_RM3100_MGM_DEBUG +#define FSFW_HAL_RM3100_MGM_DEBUG 0 +#endif /* FSFW_HAL_RM3100_MGM_DEBUG */ + #endif /* FSFW_FSFW_H_ */ From 0df8d358020be603d0224104882951813656233a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 16 Sep 2021 11:36:32 +0200 Subject: [PATCH 24/48] comment format --- .../devicehandlers/MgmRM3100Handler.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp index 71193913..3f9fdce2 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp @@ -158,7 +158,7 @@ ReturnValue_t MgmRM3100Handler::scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, size_t *foundLen) { - /* For SPI, ID will always be the one of the last sent command. */ + // For SPI, ID will always be the one of the last sent command *foundId = this->getPendingCommand(); *foundLen = len; return HasReturnvaluesIF::RETURN_OK; @@ -170,7 +170,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const case(RM3100::CONFIGURE_CMM): case(RM3100::CONFIGURE_CYCLE_COUNT): case(RM3100::CONFIGURE_TMRC): { - /* We can only check whether write was successful with read operation. */ + // We can only check whether write was successful with read operation if(mode == _MODE_START_UP) { commandExecuted = true; } @@ -178,14 +178,14 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const } case(RM3100::READ_CMM): { uint8_t cmmValue = packet[1]; - /* We clear the seventh bit in any case - * because this one is zero sometimes for some reason */ + // We clear the seventh bit in any case + // because this one is zero sometimes for some reason bitutil::bitClear(&cmmValue, 6); if(cmmValue == cmmRegValue and internalState == InternalState::READ_CMM) { commandExecuted = true; } else { - /* Attempt reconfiguration. */ + // Attempt reconfiguration internalState = InternalState::CONFIGURE_CMM; return DeviceHandlerIF::DEVICE_REPLY_INVALID; } @@ -194,13 +194,13 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const case(RM3100::READ_TMRC): { if(packet[1] == tmrcRegValue) { commandExecuted = true; - /* Reading TMRC was commanded. Trigger event to inform ground. */ + // Reading TMRC was commanded. Trigger event to inform ground if(mode != _MODE_START_UP) { triggerEvent(tmrcSet, tmrcRegValue, 0); } } else { - /* Attempt reconfiguration. */ + // Attempt reconfiguration internalState = InternalState::STATE_CONFIGURE_TMRC; return DeviceHandlerIF::DEVICE_REPLY_INVALID; } @@ -214,7 +214,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const cycleCountZ != cycleCountRegValueZ) { return DeviceHandlerIF::DEVICE_REPLY_INVALID; } - /* Reading TMRC was commanded. Trigger event to inform ground. */ + // Reading TMRC was commanded. Trigger event to inform ground if(mode != _MODE_START_UP) { uint32_t eventParam1 = (cycleCountX << 16) | cycleCountY; triggerEvent(cycleCountersSet, eventParam1, cycleCountZ); @@ -267,7 +267,7 @@ ReturnValue_t MgmRM3100Handler::handleCycleCommand(bool oneCycleValue, return result; } - /* Data sheet p.30 "while noise limits the useful upper range to ~400 cycle counts." */ + // Data sheet p.30 "while noise limits the useful upper range to ~400 cycle counts." if(command.cycleCountX > 450 ) { return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; } @@ -336,13 +336,13 @@ void MgmRM3100Handler::setToGoToNormalMode(bool enable) { } ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) { - /* Analyze data here. The sensor generates 24 bit signed values so we need to do some bitshift - * trickery here to calculate the raw values first */ + // Analyze data here. The sensor generates 24 bit signed values so we need to do some bitshift + // trickery here to calculate the raw values first int32_t fieldStrengthRawX = ((packet[1] << 24) | (packet[2] << 16) | (packet[3] << 8)) >> 8; int32_t fieldStrengthRawY = ((packet[4] << 24) | (packet[5] << 16) | (packet[6] << 8)) >> 8; int32_t fieldStrengthRawZ = ((packet[7] << 24) | (packet[8] << 16) | (packet[3] << 8)) >> 8; - /* Now scale to physical value in microtesla */ + // Now scale to physical value in microtesla float fieldStrengthX = fieldStrengthRawX * scaleFactorX; float fieldStrengthY = fieldStrengthRawY * scaleFactorX; float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX; @@ -358,7 +358,7 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) { } #endif - /* TODO: Sanity check on values */ + // TODO: Sanity check on values? PoolReadGuard readGuard(&primaryDataset); if(readGuard.getReadResult() == HasReturnvaluesIF::RETURN_OK) { primaryDataset.fieldStrengthX = fieldStrengthX; From 6d0d04ac230962024580ef3769cc8ec063db4093 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 16 Sep 2021 17:33:37 +0200 Subject: [PATCH 25/48] minor bugfix --- hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp index 3f9fdce2..60ad01b7 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp @@ -69,7 +69,7 @@ ReturnValue_t MgmRM3100Handler::buildTransitionDeviceCommand( switch(internalState) { case(InternalState::NONE): case(InternalState::NORMAL): { - return HasReturnvaluesIF::RETURN_OK; + return NOTHING_TO_SEND; } case(InternalState::CONFIGURE_CMM): { *id = RM3100::CONFIGURE_CMM; From b1a56a71cdba538e82b4052413e1663b34cfee90 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 16 Sep 2021 18:50:20 +0200 Subject: [PATCH 26/48] Added LIS3MDL to FSFW, per op divider tweak --- .../fsfw_hal/devicehandlers/CMakeLists.txt | 1 + .../devicehandlers/MgmLIS3MDLHandler.cpp | 503 ++++++++++++++++++ .../devicehandlers/MgmLIS3MDLHandler.h | 167 ++++++ .../devicehandlers/MgmRM3100Handler.cpp | 2 +- .../devicedefinitions/MgmLIS3HandlerDefs.h | 178 +++++++ src/fsfw/FSFW.h.in | 4 + .../PeriodicOperationDivider.cpp | 39 +- .../PeriodicOperationDivider.h | 78 +-- 8 files changed, 913 insertions(+), 59 deletions(-) create mode 100644 hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp create mode 100644 hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h create mode 100644 hal/src/fsfw_hal/devicehandlers/devicedefinitions/MgmLIS3HandlerDefs.h diff --git a/hal/src/fsfw_hal/devicehandlers/CMakeLists.txt b/hal/src/fsfw_hal/devicehandlers/CMakeLists.txt index eb48d190..94e67c72 100644 --- a/hal/src/fsfw_hal/devicehandlers/CMakeLists.txt +++ b/hal/src/fsfw_hal/devicehandlers/CMakeLists.txt @@ -1,4 +1,5 @@ target_sources(${LIB_FSFW_NAME} PRIVATE GyroL3GD20Handler.cpp MgmRM3100Handler.cpp + MgmLIS3MDLHandler.cpp ) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp new file mode 100644 index 00000000..c023dbda --- /dev/null +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -0,0 +1,503 @@ +#include "MgmLIS3MDLHandler.h" + +#include "fsfw/datapool/PoolReadGuard.h" +#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 +#include "fsfw/globalfunctions/PeriodicOperationDivider.h" +#endif + +MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication, + CookieIF* comCookie, uint8_t switchId, uint32_t transitionDelay): + DeviceHandlerBase(objectId, deviceCommunication, comCookie), + dataset(this), transitionDelay(transitionDelay) { +#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 + debugDivider = new PeriodicOperationDivider(5); +#endif + /* 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; + +} + +MgmLIS3MDLHandler::~MgmLIS3MDLHandler() { +} + + +void MgmLIS3MDLHandler::doStartUp() { + switch (internalState) { + case(InternalState::STATE_NONE): { + internalState = InternalState::STATE_FIRST_CONTACT; + break; + } + case(InternalState::STATE_FIRST_CONTACT): { + /* Will be set by checking device ID (WHO AM I register) */ + if(commandExecuted) { + commandExecuted = false; + internalState = InternalState::STATE_SETUP; + } + break; + } + case(InternalState::STATE_SETUP): { + internalState = InternalState::STATE_CHECK_REGISTERS; + break; + } + case(InternalState::STATE_CHECK_REGISTERS): { + /* Set up cached registers which will be used to configure the MGM. */ + if(commandExecuted) { + commandExecuted = false; + if(goToNormalMode) { + setMode(MODE_NORMAL); + } + else { + setMode(_MODE_TO_ON); + } + } + break; + } + default: + break; + } + +} + +void MgmLIS3MDLHandler::doShutDown() { + setMode(_MODE_POWER_DOWN); +} + +ReturnValue_t MgmLIS3MDLHandler::buildTransitionDeviceCommand( + DeviceCommandId_t *id) { + switch (internalState) { + case(InternalState::STATE_NONE): + case(InternalState::STATE_NORMAL): { + return HasReturnvaluesIF::RETURN_OK; + } + case(InternalState::STATE_FIRST_CONTACT): { + *id = MGMLIS3MDL::IDENTIFY_DEVICE; + break; + } + case(InternalState::STATE_SETUP): { + *id = MGMLIS3MDL::SETUP_MGM; + break; + } + case(InternalState::STATE_CHECK_REGISTERS): { + *id = MGMLIS3MDL::READ_CONFIG_AND_DATA; + break; + } + default: { + /* might be a configuration error. */ +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "GyroHandler::buildTransitionDeviceCommand: Unknown internal state!" << + std::endl; +#else + sif::printWarning("GyroHandler::buildTransitionDeviceCommand: Unknown internal state!\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ + return HasReturnvaluesIF::RETURN_OK; + } + + } + 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; + + prepareCtrlRegisterWrite(); +} + +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; + communicationStep = CommunicationStep::TEMPERATURE; + return buildCommandFromCommand(*id, NULL, 0); + } + else { + *id = MGMLIS3MDL::READ_TEMPERATURE; + communicationStep = CommunicationStep::DATA; + return buildCommandFromCommand(*id, NULL, 0); + } + +} + +ReturnValue_t MgmLIS3MDLHandler::buildCommandFromCommand( + DeviceCommandId_t deviceCommand, const uint8_t *commandData, + size_t commandDataLen) { + switch(deviceCommand) { + case(MGMLIS3MDL::READ_CONFIG_AND_DATA): { + std::memset(commandBuffer, 0, sizeof(commandBuffer)); + commandBuffer[0] = readCommand(MGMLIS3MDL::CTRL_REG1, true); + + rawPacket = commandBuffer; + rawPacketLen = MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1; + return RETURN_OK; + } + case(MGMLIS3MDL::READ_TEMPERATURE): { + std::memset(commandBuffer, 0, 3); + commandBuffer[0] = readCommand(MGMLIS3MDL::TEMP_LOWBYTE, true); + + rawPacket = commandBuffer; + rawPacketLen = 3; + return RETURN_OK; + } + case(MGMLIS3MDL::IDENTIFY_DEVICE): { + return identifyDevice(); + } + case(MGMLIS3MDL::TEMP_SENSOR_ENABLE): { + return enableTemperatureSensor(commandData, commandDataLen); + } + case(MGMLIS3MDL::SETUP_MGM): { + setupMgm(); + return HasReturnvaluesIF::RETURN_OK; + } + case(MGMLIS3MDL::ACCURACY_OP_MODE_SET): { + return setOperatingMode(commandData, commandDataLen); + } + default: + return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; + } + return HasReturnvaluesIF::RETURN_FAILED; +} + +ReturnValue_t MgmLIS3MDLHandler::identifyDevice() { + uint32_t size = 2; + commandBuffer[0] = readCommand(MGMLIS3MDL::IDENTIFY_DEVICE_REG_ADDR); + commandBuffer[1] = 0x00; + + rawPacket = commandBuffer; + rawPacketLen = size; + + return RETURN_OK; +} + +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) { + *foundLen = len; + *foundId = MGMLIS3MDL::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]) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "MGMHandlerLIS3MDL::scanForReply: Invalid registers!" << std::endl; +#else + sif::printWarning("MGMHandlerLIS3MDL::scanForReply: Invalid registers!\n"); +#endif +#endif + return DeviceHandlerIF::INVALID_DATA; + } + if(mode == _MODE_START_UP) { + commandExecuted = true; + } + + } + else if(len == MGMLIS3MDL::TEMPERATURE_REPLY_LEN) { + *foundLen = len; + *foundId = MGMLIS3MDL::READ_TEMPERATURE; + } + else if (len == MGMLIS3MDL::SETUP_REPLY_LEN) { + *foundLen = len; + *foundId = MGMLIS3MDL::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 FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "MGMHandlerLIS3MDL::scanForReply: Invalid registers!" << std::endl; +#else + sif::printWarning("MGMHandlerLIS3MDL::scanForReply: Invalid registers!\n"); +#endif +#endif + return DeviceHandlerIF::INVALID_DATA; + } + + if(mode == _MODE_START_UP) { + commandExecuted = true; + } + } + } + else { + return DeviceHandlerIF::INVALID_DATA; + } + + /* Data with SPI Interface always has this answer */ + if (start[0] == 0b11111111) { + return RETURN_OK; + } + else { + return DeviceHandlerIF::INVALID_DATA; + } + +} +ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, + const uint8_t *packet) { + + switch (id) { + case MGMLIS3MDL::IDENTIFY_DEVICE: { + break; + } + case MGMLIS3MDL::SETUP_MGM: { + break; + } + case MGMLIS3MDL::READ_CONFIG_AND_DATA: { + // 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] ; + int16_t mgmMeasurementRawY = packet[MGMLIS3MDL::Y_HIGHBYTE_IDX] << 8 + | packet[MGMLIS3MDL::Y_LOWBYTE_IDX] ; + int16_t mgmMeasurementRawZ = packet[MGMLIS3MDL::Z_HIGHBYTE_IDX] << 8 + | packet[MGMLIS3MDL::Z_LOWBYTE_IDX] ; + + /* Target value in microtesla */ + float mgmX = static_cast(mgmMeasurementRawX) * sensitivityFactor + * MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR; + float mgmY = static_cast(mgmMeasurementRawY) * sensitivityFactor + * MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR; + float mgmZ = static_cast(mgmMeasurementRawZ) * sensitivityFactor + * MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR; + +#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 + if(debugDivider->checkAndIncrement()) { + /* Set terminal to utf-8 if there is an issue with micro printout. */ +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "MGMHandlerLIS3: Magnetic field strength in" + " microtesla:" << std::endl; + sif::info << "X: " << mgmX << " uT" << std::endl; + sif::info << "Y: " << mgmY << " uT" << std::endl; + sif::info << "Z: " << mgmZ << " uT" << std::endl; +#else + sif::printInfo("MGMHandlerLIS3: Magnetic field strength in microtesla:\n"); + sif::printInfo("X: %f uT\n", mgmX); + sif::printInfo("Y: %f uT\n", mgmY); + sif::printInfo("Z: %f uT\n", mgmZ); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */ + } +#endif /* OBSW_VERBOSE_LEVEL >= 1 */ + PoolReadGuard readHelper(&dataset); + if(readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) { + dataset.fieldStrengthX = mgmX; + dataset.fieldStrengthY = mgmY; + dataset.fieldStrengthZ = mgmZ; + dataset.setValidity(true, true); + } + break; + } + + case MGMLIS3MDL::READ_TEMPERATURE: { + int16_t tempValueRaw = packet[2] << 8 | packet[1]; + float tempValue = 25.0 + ((static_cast(tempValueRaw)) / 8.0); + #if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 + if(debugDivider->check()) { + /* Set terminal to utf-8 if there is an issue with micro printout. */ +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "MGMHandlerLIS3: Temperature: " << tempValue << " C" << + std::endl; +#else + sif::printInfo("MGMHandlerLIS3: Temperature: %f C\n"); +#endif + } +#endif + ReturnValue_t result = dataset.read(); + if(result == HasReturnvaluesIF::RETURN_OK) { + dataset.temperature = tempValue; + dataset.commit(); + } + break; + } + + default: { + return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; + } + + } + return RETURN_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) { + triggerEvent(CHANGE_OF_SETUP_PARAMETER); + uint32_t size = 2; + commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1); + if (commandDataLen > 1) { + return INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS; + } + switch (*commandData) { + case (MGMLIS3MDL::ON): { + commandBuffer[1] = registers[0] | (1 << 7); + break; + } + case (MGMLIS3MDL::OFF): { + commandBuffer[1] = registers[0] & ~(1 << 7); + break; + } + default: + return INVALID_COMMAND_PARAMETER; + } + registers[0] = commandBuffer[1]; + + rawPacket = commandBuffer; + rawPacketLen = size; + + return RETURN_OK; +} + +ReturnValue_t MgmLIS3MDLHandler::setOperatingMode(const uint8_t *commandData, + size_t commandDataLen) { + triggerEvent(CHANGE_OF_SETUP_PARAMETER); + if (commandDataLen != 1) { + return INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS; + } + + 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)); + break; + case MGMLIS3MDL::MEDIUM: + registers[0] = (registers[0] & (~(1 << MGMLIS3MDL::OM1))) | (1 << MGMLIS3MDL::OM0); + registers[3] = (registers[3] & (~(1 << MGMLIS3MDL::OMZ1))) | (1 << MGMLIS3MDL::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)); + break; + + case MGMLIS3MDL::ULTRA: + registers[0] = (registers[0] | (1 << MGMLIS3MDL::OM1)) | (1 << MGMLIS3MDL::OM0); + registers[3] = (registers[3] | (1 << MGMLIS3MDL::OMZ1)) | (1 << MGMLIS3MDL::OMZ0); + break; + default: + break; + } + + return prepareCtrlRegisterWrite(); +} + +void MgmLIS3MDLHandler::fillCommandAndReplyMap() { + /* + * Regarding ArduinoBoard: + * Actually SPI answers directly, but as commanding ArduinoBoard the + * communication could be delayed + * SPI always has to be triggered, so there could be no periodic answer of + * the device, the device has to asked with a command, so periodic is zero. + * + * We dont read single registers, we just expect special + * reply from he Readall_MGM + */ + 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); +} + +void MgmLIS3MDLHandler::setToGoToNormalMode(bool enable) { + this->goToNormalMode = enable; +} + +ReturnValue_t MgmLIS3MDLHandler::prepareCtrlRegisterWrite() { + commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1, true); + + for (size_t i = 0; i < MGMLIS3MDL::NR_OF_CTRL_REGISTERS; i++) { + commandBuffer[i + 1] = registers[i]; + } + rawPacket = commandBuffer; + rawPacketLen = MGMLIS3MDL::NR_OF_CTRL_REGISTERS + 1; + + /* We dont have to check if this is working because we just did it */ + return RETURN_OK; +} + +void MgmLIS3MDLHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { + +} + +uint32_t MgmLIS3MDLHandler::getTransitionDelayMs(Mode_t from, Mode_t to) { + return transitionDelay; +} + +void MgmLIS3MDLHandler::modeChanged(void) { + internalState = InternalState::STATE_NONE; +} + +ReturnValue_t MgmLIS3MDLHandler::initializeLocalDataPool( + localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { + localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_X, + new PoolEntry({0.0})); + localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_Y, + new PoolEntry({0.0})); + localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_Z, + new PoolEntry({0.0})); + localDataPoolMap.emplace(MGMLIS3MDL::TEMPERATURE_CELCIUS, + new PoolEntry({0.0})); + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h new file mode 100644 index 00000000..9fb41156 --- /dev/null +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h @@ -0,0 +1,167 @@ +#ifndef MISSION_DEVICES_MGMLIS3MDLHANDLER_H_ +#define MISSION_DEVICES_MGMLIS3MDLHANDLER_H_ + +#include "fsfw/FSFW.h" +#include "events/subsystemIdRanges.h" +#include "devicedefinitions/MgmLIS3HandlerDefs.h" + +#include "fsfw/devicehandlers/DeviceHandlerBase.h" + +class PeriodicOperationDivider; + +/** + * @brief Device handler object for the LIS3MDL 3-axis magnetometer + * by STMicroeletronics + * @details + * Datasheet can be found online by googling LIS3MDL. + * Flight manual: + * https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/LIS3MDL_MGM + * @author L. Loidold, R. Mueller + */ +class MgmLIS3MDLHandler: public DeviceHandlerBase { +public: + enum class CommunicationStep { + DATA, + TEMPERATURE + }; + + static const uint8_t INTERFACE_ID = CLASS_ID::MGM_LIS3MDL; + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MGM_LIS3MDL; + //Notifies a command to change the setup parameters + static const Event CHANGE_OF_SETUP_PARAMETER = MAKE_EVENT(0, severity::LOW); + + MgmLIS3MDLHandler(uint32_t objectId, object_id_t deviceCommunication, CookieIF* comCookie, + uint8_t switchId, uint32_t transitionDelay = 10000); + virtual ~MgmLIS3MDLHandler(); + + void setToGoToNormalMode(bool enable); + +protected: + + /** DeviceHandlerBase overrides */ + void doShutDown() override; + void doStartUp() override; + void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; + uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override; + ReturnValue_t buildCommandFromCommand( + DeviceCommandId_t deviceCommand, const uint8_t *commandData, + size_t commandDataLen) override; + ReturnValue_t buildTransitionDeviceCommand( + DeviceCommandId_t *id) override; + ReturnValue_t buildNormalDeviceCommand( + DeviceCommandId_t *id) override; + ReturnValue_t scanForReply(const uint8_t *start, size_t len, + DeviceCommandId_t *foundId, size_t *foundLen) override; + ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, + const uint8_t *packet) override; + void fillCommandAndReplyMap() override; + void modeChanged(void) override; + ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, + LocalDataPoolManager &poolManager) override; + +private: + MGMLIS3MDL::MgmPrimaryDataset dataset; + //Length a sindgle command SPI answer + static const uint8_t SINGLE_COMMAND_ANSWER_LEN = 2; + + uint32_t transitionDelay; + //Single SPIcommand 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]; + + /** + * We want to save the registers we set, so we dont have to read the + * 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 statusRegister = 0; + bool goToNormalMode = false; + + enum class InternalState { + STATE_NONE, + STATE_FIRST_CONTACT, + STATE_SETUP, + STATE_CHECK_REGISTERS, + STATE_NORMAL + }; + + InternalState internalState = InternalState::STATE_NONE; + CommunicationStep communicationStep = CommunicationStep::DATA; + bool commandExecuted = false; + + /*------------------------------------------------------------------------*/ + /* 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 + */ + ReturnValue_t identifyDevice(); + + virtual void setupMgm(); + + /*------------------------------------------------------------------------*/ + /* Non normal commands */ + /*------------------------------------------------------------------------*/ + /** + * Enables/Disables the integrated Temperaturesensor + * @param commandData On or Off + * @param length of the commandData: has to be 1 + */ + virtual ReturnValue_t enableTemperatureSensor(const uint8_t *commandData, + size_t commandDataLen); + + /** + * Sets the accuracy of the measurement of the axis. The noise is changing. + * @param commandData LOW, MEDIUM, HIGH, ULTRA + * @param length of the command, has to be 1 + */ + virtual ReturnValue_t setOperatingMode(const uint8_t *commandData, + size_t commandDataLen); + + /** + * We always update all registers together, so this method updates + * the rawpacket and rawpacketLen, so we just manipulate the local + * saved register + * + */ + ReturnValue_t prepareCtrlRegisterWrite(); + +#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 + PeriodicOperationDivider* debugDivider; +#endif +}; + +#endif /* MISSION_DEVICES_MGMLIS3MDLHANDLER_H_ */ diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp index 60ad01b7..b483b6bf 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp @@ -13,7 +13,7 @@ MgmRM3100Handler::MgmRM3100Handler(object_id_t objectId, DeviceHandlerBase(objectId, deviceCommunication, comCookie), primaryDataset(this), switchId(switchId), transitionDelay(transitionDelay) { #if FSFW_HAL_RM3100_MGM_DEBUG == 1 - debugDivider = new PeriodicOperationDivider(5); + debugDivider = new PeriodicOperationDivider(1); #endif } diff --git a/hal/src/fsfw_hal/devicehandlers/devicedefinitions/MgmLIS3HandlerDefs.h b/hal/src/fsfw_hal/devicehandlers/devicedefinitions/MgmLIS3HandlerDefs.h new file mode 100644 index 00000000..b6f3fd84 --- /dev/null +++ b/hal/src/fsfw_hal/devicehandlers/devicedefinitions/MgmLIS3HandlerDefs.h @@ -0,0 +1,178 @@ +#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_MGMLIS3HANDLERDEFS_H_ +#define MISSION_DEVICES_DEVICEDEFINITIONS_MGMLIS3HANDLERDEFS_H_ + +#include +#include +#include +#include + +namespace MGMLIS3MDL { + +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 +}; + +/* Actually 15, we just round up a bit */ +static constexpr size_t MAX_BUFFER_SIZE = 16; + +/* Field data register scaling */ +static constexpr uint8_t GAUSS_TO_MICROTESLA_FACTOR = 100; +static constexpr float FIELD_LSB_PER_GAUSS_4_SENS = 1.0 / 6842.0; +static constexpr float FIELD_LSB_PER_GAUSS_8_SENS = 1.0 / 3421.0; +static constexpr float FIELD_LSB_PER_GAUSS_12_SENS = 1.0 / 2281.0; +static constexpr float FIELD_LSB_PER_GAUSS_16_SENS = 1.0 / 1711.0; + +static const DeviceCommandId_t READ_CONFIG_AND_DATA = 0x00; +static const DeviceCommandId_t SETUP_MGM = 0x01; +static const DeviceCommandId_t READ_TEMPERATURE = 0x02; +static const DeviceCommandId_t IDENTIFY_DEVICE = 0x03; +static const DeviceCommandId_t TEMP_SENSOR_ENABLE = 0x04; +static const DeviceCommandId_t ACCURACY_OP_MODE_SET = 0x05; + +/* Number of all control registers */ +static const uint8_t NR_OF_CTRL_REGISTERS = 5; +/* Number of registers in the MGM */ +static const uint8_t NR_OF_REGISTERS = 19; +/* Total number of adresses for all registers */ +static const uint8_t TOTAL_NR_OF_ADRESSES = 52; +static const uint8_t NR_OF_DATA_AND_CFG_REGISTERS = 14; +static const uint8_t TEMPERATURE_REPLY_LEN = 3; +static const uint8_t SETUP_REPLY_LEN = 6; + +/*------------------------------------------------------------------------*/ +/* Register adresses */ +/*------------------------------------------------------------------------*/ +/* Register adress returns identifier of device with default 0b00111101 */ +static const uint8_t IDENTIFY_DEVICE_REG_ADDR = 0b00001111; +static const uint8_t DEVICE_ID = 0b00111101; // Identifier for Device + +/* Register adress to access register 1 */ +static const uint8_t CTRL_REG1 = 0b00100000; +/* Register adress to access register 2 */ +static const uint8_t CTRL_REG2 = 0b00100001; +/* Register adress to access register 3 */ +static const uint8_t CTRL_REG3 = 0b00100010; +/* Register adress to access register 4 */ +static const uint8_t CTRL_REG4 = 0b00100011; +/* Register adress to access register 5 */ +static const uint8_t CTRL_REG5 = 0b00100100; + +/* Register adress to access status register */ +static const uint8_t STATUS_REG_IDX = 8; +static const uint8_t STATUS_REG = 0b00100111; + +/* Register adress to access low byte of x-axis */ +static const uint8_t X_LOWBYTE_IDX = 9; +static const uint8_t X_LOWBYTE = 0b00101000; +/* Register adress to access high byte of x-axis */ +static const uint8_t X_HIGHBYTE_IDX = 10; +static const uint8_t X_HIGHBYTE = 0b00101001; +/* Register adress to access low byte of y-axis */ +static const uint8_t Y_LOWBYTE_IDX = 11; +static const uint8_t Y_LOWBYTE = 0b00101010; +/* Register adress to access high byte of y-axis */ +static const uint8_t Y_HIGHBYTE_IDX = 12; +static const uint8_t Y_HIGHBYTE = 0b00101011; +/* Register adress to access low byte of z-axis */ +static const uint8_t Z_LOWBYTE_IDX = 13; +static const uint8_t Z_LOWBYTE = 0b00101100; +/* Register adress to access high byte of z-axis */ +static const uint8_t Z_HIGHBYTE_IDX = 14; +static const uint8_t Z_HIGHBYTE = 0b00101101; + +/* Register adress to access low byte of temperature sensor */ +static const uint8_t TEMP_LOWBYTE = 0b00101110; +/* Register adress to access high byte of temperature sensor */ +static const uint8_t TEMP_HIGHBYTE = 0b00101111; + +/*------------------------------------------------------------------------*/ +/* Initialize Setup Register set bits */ +/*------------------------------------------------------------------------*/ +/* General transfer bits */ +// Read=1 / Write=0 Bit +static const uint8_t RW_BIT = 7; +// Continous Read/Write Bit, increment adress +static const uint8_t MS_BIT = 6; + +/* CTRL_REG1 bits */ +static const uint8_t ST = 0; // Self test enable bit, enabled = 1 +// Enable rates higher than 80 Hz enabled = 1 +static const uint8_t FAST_ODR = 1; +static const uint8_t DO0 = 2; // Output data rate bit 2 +static const uint8_t DO1 = 3; // Output data rate bit 3 +static const uint8_t DO2 = 4; // Output data rate bit 4 +static const uint8_t OM0 = 5; // XY operating mode bit 5 +static const uint8_t OM1 = 6; // XY operating mode bit 6 +static const uint8_t TEMP_EN = 7; // Temperature sensor enable enabled = 1 +static const uint8_t CTRL_REG1_DEFAULT = (1 << TEMP_EN) | (1 << OM1) | + (1 << DO0) | (1 << DO1) | (1 << DO2); + +/* CTRL_REG2 bits */ +//reset configuration registers and user registers +static const uint8_t SOFT_RST = 2; +static const uint8_t REBOOT = 3; //reboot memory content +static const uint8_t FSO = 5; //full-scale selection bit 5 +static const uint8_t FS1 = 6; //full-scale selection bit 6 +static const uint8_t CTRL_REG2_DEFAULT = 0; + +/* CTRL_REG3 bits */ +static const uint8_t MD0 = 0; //Operating mode bit 0 +static const uint8_t MD1 = 1; //Operating mode bit 1 +//SPI serial interface mode selection enabled = 3-wire-mode +static const uint8_t SIM = 2; +static const uint8_t LP = 5; //low-power mode +static const uint8_t CTRL_REG3_DEFAULT = 0; + +/* CTRL_REG4 bits */ +//big/little endian data selection enabled = MSb at lower adress +static const uint8_t BLE = 1; +static const uint8_t OMZ0 = 2; //Z operating mode bit 2 +static const uint8_t OMZ1 = 3; //Z operating mode bit 3 +static const uint8_t CTRL_REG4_DEFAULT = (1 << OMZ1); + +/* CTRL_REG5 bits */ +static const uint8_t BDU = 6; //Block data update +static const uint8_t FAST_READ = 7; //Fast read enabled = 1 +static const uint8_t CTRL_REG5_DEFAULT = 0; + +static const uint32_t MGM_DATA_SET_ID = READ_CONFIG_AND_DATA; + +enum MgmPoolIds: lp_id_t { + FIELD_STRENGTH_X, + FIELD_STRENGTH_Y, + FIELD_STRENGTH_Z, + TEMPERATURE_CELCIUS +}; + +class MgmPrimaryDataset: public StaticLocalDataSet<5> { +public: + MgmPrimaryDataset(HasLocalDataPoolIF* hkOwner): + StaticLocalDataSet(hkOwner, MGM_DATA_SET_ID) {} + + MgmPrimaryDataset(object_id_t mgmId): + StaticLocalDataSet(sid_t(mgmId, MGM_DATA_SET_ID)) {} + + lp_var_t fieldStrengthX = lp_var_t(sid.objectId, + FIELD_STRENGTH_X, this); + lp_var_t fieldStrengthY = lp_var_t(sid.objectId, + FIELD_STRENGTH_Y, this); + lp_var_t fieldStrengthZ = lp_var_t(sid.objectId, + FIELD_STRENGTH_Z, this); + lp_var_t temperature = lp_var_t(sid.objectId, + TEMPERATURE_CELCIUS, this); +}; + +} + + +#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_MGMLIS3HANDLERDEFS_H_ */ diff --git a/src/fsfw/FSFW.h.in b/src/fsfw/FSFW.h.in index e6dd2f8f..3f005387 100644 --- a/src/fsfw/FSFW.h.in +++ b/src/fsfw/FSFW.h.in @@ -33,4 +33,8 @@ #define FSFW_HAL_RM3100_MGM_DEBUG 0 #endif /* FSFW_HAL_RM3100_MGM_DEBUG */ +#ifndef FSFW_HAL_LIS3MDL_MGM_DEBUG +#define FSFW_HAL_LIS3MDL_MGM_DEBUG 0 +#endif /* FSFW_HAL_LIS3MDL_MGM_DEBUG */ + #endif /* FSFW_FSFW_H_ */ diff --git a/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp b/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp index 62cc6f4c..d3b03c2b 100644 --- a/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp +++ b/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp @@ -2,43 +2,44 @@ PeriodicOperationDivider::PeriodicOperationDivider(uint32_t divider, - bool resetAutomatically): resetAutomatically(resetAutomatically), - counter(divider), divider(divider) { + bool resetAutomatically): resetAutomatically(resetAutomatically), + counter(divider), divider(divider) { } bool PeriodicOperationDivider::checkAndIncrement() { - bool opNecessary = check(); - if(opNecessary) { - if(resetAutomatically) { - counter = 0; - } - return opNecessary; - } - counter ++; - return opNecessary; + counter++; + bool opNecessary = check(); + if(opNecessary) { + if(resetAutomatically) { + counter = 0; + } + return opNecessary; + } + + return opNecessary; } bool PeriodicOperationDivider::check() { - if(counter >= divider) { - return true; - } - return false; + if(counter >= divider) { + return true; + } + return false; } void PeriodicOperationDivider::resetCounter() { - counter = 0; + counter = 0; } void PeriodicOperationDivider::setDivider(uint32_t newDivider) { - divider = newDivider; + divider = newDivider; } uint32_t PeriodicOperationDivider::getCounter() const { - return counter; + return counter; } uint32_t PeriodicOperationDivider::getDivider() const { - return divider; + return divider; } diff --git a/src/fsfw/globalfunctions/PeriodicOperationDivider.h b/src/fsfw/globalfunctions/PeriodicOperationDivider.h index 7f7fb469..bfc81eea 100644 --- a/src/fsfw/globalfunctions/PeriodicOperationDivider.h +++ b/src/fsfw/globalfunctions/PeriodicOperationDivider.h @@ -13,51 +13,51 @@ */ class PeriodicOperationDivider { public: - /** - * Initialize with the desired divider and specify whether the internal - * counter will be reset automatically. - * @param divider - * @param resetAutomatically - */ - PeriodicOperationDivider(uint32_t divider, bool resetAutomatically = true); + /** + * Initialize with the desired divider and specify whether the internal + * counter will be reset automatically. + * @param divider + * @param resetAutomatically + */ + PeriodicOperationDivider(uint32_t divider, bool resetAutomatically = true); - /** - * Check whether operation is necessary. - * If an operation is necessary and the class has been - * configured to be reset automatically, the counter will be reset. - * - * @return - * -@c true if the counter is larger or equal to the divider - * -@c false otherwise - */ - bool checkAndIncrement(); + /** + * Check whether operation is necessary. + * If an operation is necessary and the class has been + * configured to be reset automatically, the counter will be reset. + * + * @return + * -@c true if the counter is larger or equal to the divider + * -@c false otherwise + */ + bool checkAndIncrement(); - /** - * Checks whether an operation is necessary. - * This function will not increment the counter! - * @return - * -@c true if the counter is larger or equal to the divider - * -@c false otherwise - */ - bool check(); + /** + * Checks whether an operation is necessary. + * This function will not increment the counter! + * @return + * -@c true if the counter is larger or equal to the divider + * -@c false otherwise + */ + bool check(); - /** - * Can be used to reset the counter to 0 manually. - */ - void resetCounter(); - uint32_t getCounter() const; + /** + * Can be used to reset the counter to 0 manually. + */ + void resetCounter(); + uint32_t getCounter() const; - /** - * Can be used to set a new divider value. - * @param newDivider - */ - void setDivider(uint32_t newDivider); - uint32_t getDivider() const; + /** + * Can be used to set a new divider value. + * @param newDivider + */ + void setDivider(uint32_t newDivider); + uint32_t getDivider() const; private: - bool resetAutomatically = true; - uint32_t counter = 0; - uint32_t divider = 0; + bool resetAutomatically = true; + uint32_t counter = 0; + uint32_t divider = 0; }; From 7d44aab98e6861bc7999541e97085ba5a62b6633 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 17 Sep 2021 13:07:43 +0200 Subject: [PATCH 27/48] some tweaks for op divider --- src/fsfw/globalfunctions/PeriodicOperationDivider.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp b/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp index d3b03c2b..92f7e792 100644 --- a/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp +++ b/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp @@ -7,15 +7,13 @@ PeriodicOperationDivider::PeriodicOperationDivider(uint32_t divider, } bool PeriodicOperationDivider::checkAndIncrement() { - counter++; bool opNecessary = check(); if(opNecessary) { if(resetAutomatically) { - counter = 0; + counter = 1; } - return opNecessary; } - + counter++; return opNecessary; } From e8050183f4f54452caceba67a9d4da50bd230770 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 17 Sep 2021 16:52:31 +0200 Subject: [PATCH 28/48] better printout --- hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index c023dbda..63dabfc9 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -232,9 +232,11 @@ ReturnValue_t MgmLIS3MDLHandler::scanForReply(const uint8_t *start, if(start[1] != MGMLIS3MDL::DEVICE_ID) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "MGMHandlerLIS3MDL::scanForReply: Invalid registers!" << std::endl; + sif::warning << "MGMHandlerLIS3MDL::scanForReply: " + "Device identification failed!" << std::endl; #else - sif::printWarning("MGMHandlerLIS3MDL::scanForReply: Invalid registers!\n"); + sif::printWarning("MGMHandlerLIS3MDL::scanForReply: " + "Device identification failed!\n"); #endif #endif return DeviceHandlerIF::INVALID_DATA; From 635432d7ba68faf5a2cdfd0721ed3a70fdf67b37 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Sep 2021 18:29:57 +0200 Subject: [PATCH 29/48] missing return --- src/fsfw/globalfunctions/PeriodicOperationDivider.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp b/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp index 92f7e792..5d9e1624 100644 --- a/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp +++ b/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp @@ -12,6 +12,7 @@ bool PeriodicOperationDivider::checkAndIncrement() { if(resetAutomatically) { counter = 1; } + return opNecessary; } counter++; return opNecessary; From 784a0140f4fb510a2ba92a7d2e1b750272d45265 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Sep 2021 18:31:52 +0200 Subject: [PATCH 30/48] tweak op divider divisor --- hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp index b483b6bf..467141de 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp @@ -13,7 +13,7 @@ MgmRM3100Handler::MgmRM3100Handler(object_id_t objectId, DeviceHandlerBase(objectId, deviceCommunication, comCookie), primaryDataset(this), switchId(switchId), transitionDelay(transitionDelay) { #if FSFW_HAL_RM3100_MGM_DEBUG == 1 - debugDivider = new PeriodicOperationDivider(1); + debugDivider = new PeriodicOperationDivider(3); #endif } From 70a3749dbe2cf7d23c685b0e3b3ce350a7c9db05 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Mon, 20 Sep 2021 18:38:18 +0200 Subject: [PATCH 31/48] added option to open gpio by label instead of gpiochip* --- .../fsfw_hal/common/gpio/gpioDefinitions.h | 14 ++++++++- .../fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp | 29 +++++++++++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h b/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h index 710b2e2c..f3bafc42 100644 --- a/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h +++ b/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h @@ -85,7 +85,19 @@ public: GpioBase(gpio::GpioTypes::GPIO_REGULAR, consumer_, gpio::Direction::IN, 0), chipname(chipname_), lineNum(lineNum_) { } - std::string chipname; + + GpiodRegular(std::string consumer_, gpio::Direction direction_, int initValue_, + std::string label_, int lineNum_) : + GpioBase(gpio::GpioTypes::GPIO_REGULAR, consumer_, direction_, initValue_), label( + label_), lineNum(lineNum_) { + } + + GpiodRegular(std::string consumer_, std::string label_, int lineNum_) : + GpioBase(gpio::GpioTypes::GPIO_REGULAR, consumer_, gpio::Direction::IN, 0), label( + label_), lineNum(lineNum_) { + } + std::string chipname = "NONE"; + std::string label = "NONE"; int lineNum = 0; struct gpiod_line* lineHandle = nullptr; }; diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index eef61e58..4ee0749b 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -20,7 +20,7 @@ LinuxLibgpioIF::~LinuxLibgpioIF() { ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) { ReturnValue_t result; if(gpioCookie == nullptr) { - sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl; + sif::error << "LinuxLibgpioIF::addGpios: Invalid cookie" << std::endl; return RETURN_FAILED; } @@ -72,6 +72,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular *regularGpio) { std::string chipname; + std::string label; unsigned int lineNum; struct gpiod_chip *chip; gpio::Direction direction; @@ -80,11 +81,27 @@ ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular int result = 0; chipname = regularGpio->chipname; - chip = gpiod_chip_open_by_name(chipname.c_str()); - if (!chip) { - sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open chip " - << chipname << ". Gpio ID: " << gpioId << std::endl; - return RETURN_FAILED; + + if (chipname != "NONE") { + chip = gpiod_chip_open_by_name(chipname.c_str()); + if (!chip) { + sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open chip " + << chipname << ". Gpio ID: " << gpioId << std::endl; + return RETURN_FAILED; + } + } + else if (label != "NONE") { + label = regularGpio->label; + chip = gpiod_chip_open_by_label(label.c_str()); + if (!chip) { + sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open gpio from gpio " + << "group with label " << label << ". Gpio ID: " << gpioId << std::endl; + return RETURN_FAILED; + } + } + else { + sif::warning << "LinuxLibgpioIF::configureRegularGpio: No gpio group specified" + << std::endl; } lineNum = regularGpio->lineNum; From 8e65d2d3fcbccc9cfda4803f9cf6461981266356 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 21 Sep 2021 17:31:03 +0200 Subject: [PATCH 32/48] refactored GPIO components --- .../fsfw_hal/common/gpio/gpioDefinitions.h | 76 ++++++---- .../fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp | 142 ++++++++++-------- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h | 11 +- 3 files changed, 137 insertions(+), 92 deletions(-) diff --git a/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h b/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h index f3bafc42..688d9c9b 100644 --- a/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h +++ b/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h @@ -26,7 +26,8 @@ enum GpioOperation { enum GpioTypes { NONE, - GPIO_REGULAR, + GPIO_REGULAR_BY_CHIP, + GPIO_REGULAR_BY_LABEL, CALLBACK }; @@ -68,40 +69,57 @@ public: int initValue = 0; }; -class GpiodRegular: public GpioBase { +class GpiodRegularBase: public GpioBase { public: - GpiodRegular() : - GpioBase(gpio::GpioTypes::GPIO_REGULAR, std::string(), gpio::Direction::IN, 0) { + GpiodRegularBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction, + int initValue, int lineNum): GpioBase(gpioType, consumer, direction, initValue), + lineNum(lineNum) { } - ; - - GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_, - gpio::Direction direction_, int initValue_) : - GpioBase(gpio::GpioTypes::GPIO_REGULAR, consumer_, direction_, initValue_), - chipname(chipname_), lineNum(lineNum_) { - } - - GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_) : - GpioBase(gpio::GpioTypes::GPIO_REGULAR, consumer_, gpio::Direction::IN, 0), - chipname(chipname_), lineNum(lineNum_) { - } - - GpiodRegular(std::string consumer_, gpio::Direction direction_, int initValue_, - std::string label_, int lineNum_) : - GpioBase(gpio::GpioTypes::GPIO_REGULAR, consumer_, direction_, initValue_), label( - label_), lineNum(lineNum_) { - } - - GpiodRegular(std::string consumer_, std::string label_, int lineNum_) : - GpioBase(gpio::GpioTypes::GPIO_REGULAR, consumer_, gpio::Direction::IN, 0), label( - label_), lineNum(lineNum_) { - } - std::string chipname = "NONE"; - std::string label = "NONE"; int lineNum = 0; struct gpiod_line* lineHandle = nullptr; }; +class GpiodRegularByChip: public GpiodRegularBase { +public: + GpiodRegularByChip() : + GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, + std::string(), gpio::Direction::IN, gpio::LOW, 0) { + } + + GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_, + gpio::Direction direction_, int initValue_) : + GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, + consumer_, direction_, initValue_, lineNum_), + chipname(chipname_){ + } + + GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_) : + GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, consumer_, + gpio::Direction::IN, gpio::LOW, lineNum_), + chipname(chipname_) { + } + + std::string chipname; +}; + +class GpiodRegularByLabel: public GpiodRegularBase { +public: + GpiodRegularByLabel(std::string label_, int lineNum_, std::string consumer_, + gpio::Direction direction_, int initValue_) : + GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL, consumer_, + direction_, initValue_, lineNum_), + label(label_) { + } + + GpiodRegularByLabel(std::string label_, int lineNum_, std::string consumer_) : + GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL, consumer_, + gpio::Direction::IN, gpio::LOW, lineNum_), + label(label_) { + } + + std::string label; +}; + class GpioCallback: public GpioBase { public: GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_, diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index 4ee0749b..bcc48e58 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -45,16 +45,25 @@ ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) { ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { for(auto& gpioConfig: mapToAdd) { - switch(gpioConfig.second->gpioType) { + auto& gpioType = gpioConfig.second->gpioType; + switch(gpioType) { case(gpio::GpioTypes::NONE): { return GPIO_INVALID_INSTANCE; } - case(gpio::GpioTypes::GPIO_REGULAR): { - GpiodRegular* regularGpio = dynamic_cast(gpioConfig.second); + case(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP): { + auto regularGpio = dynamic_cast(gpioConfig.second); if(regularGpio == nullptr) { return GPIO_INVALID_INSTANCE; } - configureRegularGpio(gpioConfig.first, regularGpio); + configureGpioByChip(gpioConfig.first, *regularGpio); + break; + } + case(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL):{ + auto regularGpio = dynamic_cast(gpioConfig.second); + if(regularGpio == nullptr) { + return GPIO_INVALID_INSTANCE; + } + configureGpioByLabel(gpioConfig.first, *regularGpio); break; } case(gpio::GpioTypes::CALLBACK): { @@ -70,58 +79,59 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { return RETURN_OK; } -ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular *regularGpio) { - std::string chipname; - std::string label; +ReturnValue_t LinuxLibgpioIF::configureGpioByLabel(gpioId_t gpioId, + GpiodRegularByLabel &gpioByLabel) { + std::string& label = gpioByLabel.label; + struct gpiod_chip* chip = gpiod_chip_open_by_label(label.c_str()); + if (chip == nullptr) { + sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open gpio from gpio " + << "group with label " << label << ". Gpio ID: " << gpioId << std::endl; + return RETURN_FAILED; + + } + std::string failOutput = "label: " + label; + return configureRegularGpio(gpioId, gpioByLabel.gpioType, chip, gpioByLabel, failOutput); +} + +ReturnValue_t LinuxLibgpioIF::configureGpioByChip(gpioId_t gpioId, + GpiodRegularByChip &gpioByChip) { + std::string& chipname = gpioByChip.chipname; + struct gpiod_chip* chip = gpiod_chip_open_by_name(chipname.c_str()); + if (chip == nullptr) { + sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open chip " + << chipname << ". Gpio ID: " << gpioId << std::endl; + return RETURN_FAILED; + } + std::string failOutput = "chipname: " + chipname; + return configureRegularGpio(gpioId, gpioByChip.gpioType, chip, gpioByChip, failOutput); +} + +ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, gpio::GpioTypes gpioType, + struct gpiod_chip* chip, GpiodRegularBase& regularGpio, std::string failOutput) { unsigned int lineNum; - struct gpiod_chip *chip; gpio::Direction direction; std::string consumer; struct gpiod_line *lineHandle; int result = 0; - chipname = regularGpio->chipname; - - if (chipname != "NONE") { - chip = gpiod_chip_open_by_name(chipname.c_str()); - if (!chip) { - sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open chip " - << chipname << ". Gpio ID: " << gpioId << std::endl; - return RETURN_FAILED; - } - } - else if (label != "NONE") { - label = regularGpio->label; - chip = gpiod_chip_open_by_label(label.c_str()); - if (!chip) { - sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open gpio from gpio " - << "group with label " << label << ". Gpio ID: " << gpioId << std::endl; - return RETURN_FAILED; - } - } - else { - sif::warning << "LinuxLibgpioIF::configureRegularGpio: No gpio group specified" - << std::endl; - } - - lineNum = regularGpio->lineNum; + lineNum = regularGpio.lineNum; lineHandle = gpiod_chip_get_line(chip, lineNum); if (!lineHandle) { - sif::debug << "LinuxLibgpioIF::configureRegularGpio: Failed to open line " << std::endl; - sif::debug << "GPIO ID: " << gpioId << ", line number: " << lineNum << - ", chipname: " << chipname << std::endl; - sif::debug << "Check if linux GPIO configuration has changed. " << std::endl; + sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open line " << std::endl; + sif::warning << "GPIO ID: " << gpioId << ", line number: " << lineNum << + ", " << failOutput << std::endl; + sif::warning << "Check if Linux GPIO configuration has changed. " << std::endl; gpiod_chip_close(chip); return RETURN_FAILED; } - direction = regularGpio->direction; - consumer = regularGpio->consumer; + direction = regularGpio.direction; + consumer = regularGpio.consumer; /* Configure direction and add a description to the GPIO */ switch (direction) { case(gpio::OUT): { result = gpiod_line_request_output(lineHandle, consumer.c_str(), - regularGpio->initValue); + regularGpio.initValue); if (result < 0) { sif::error << "LinuxLibgpioIF::configureRegularGpio: Failed to request line " << lineNum << " from GPIO instance with ID: " << gpioId << std::endl; @@ -151,7 +161,7 @@ ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular * Write line handle to GPIO configuration instance so it can later be used to set or * read states of GPIOs. */ - regularGpio->lineHandle = lineHandle; + regularGpio.lineHandle = lineHandle; return RETURN_OK; } @@ -162,8 +172,14 @@ ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) { return UNKNOWN_GPIO_ID; } - if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIO_REGULAR) { - return driveGpio(gpioId, dynamic_cast(gpioMapIter->second), 1); + auto gpioType = gpioMapIter->second->gpioType; + if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or + gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { + auto regularGpio = dynamic_cast(gpioMapIter->second); + if(regularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + return driveGpio(gpioId, *regularGpio, gpio::HIGH); } else { auto gpioCallback = dynamic_cast(gpioMapIter->second); @@ -184,8 +200,14 @@ ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) { return UNKNOWN_GPIO_ID; } - if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIO_REGULAR) { - return driveGpio(gpioId, dynamic_cast(gpioMapIter->second), 0); + auto gpioType = gpioMapIter->second->gpioType; + if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or + gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { + auto regularGpio = dynamic_cast(gpioMapIter->second); + if(regularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + return driveGpio(gpioId, *regularGpio, gpio::LOW); } else { auto gpioCallback = dynamic_cast(gpioMapIter->second); @@ -200,12 +222,8 @@ ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) { } ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, - GpiodRegular* regularGpio, unsigned int logicLevel) { - if(regularGpio == nullptr) { - return GPIO_TYPE_FAILURE; - } - - int result = gpiod_line_set_value(regularGpio->lineHandle, logicLevel); + GpiodRegularBase& regularGpio, gpio::Levels logicLevel) { + int result = gpiod_line_set_value(regularGpio.lineHandle, logicLevel); if (result < 0) { sif::warning << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId << " to logic level " << logicLevel << std::endl; @@ -221,9 +239,10 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl; return UNKNOWN_GPIO_ID; } - - if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIO_REGULAR) { - GpiodRegular* regularGpio = dynamic_cast(gpioMapIter->second); + auto gpioType = gpioMapIter->second->gpioType; + if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or + gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { + auto regularGpio = dynamic_cast(gpioMapIter->second); if(regularGpio == nullptr) { return GPIO_TYPE_FAILURE; } @@ -242,13 +261,14 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; for(auto& gpioConfig: mapToAdd) { switch(gpioConfig.second->gpioType) { - case(gpio::GpioTypes::GPIO_REGULAR): { - auto regularGpio = dynamic_cast(gpioConfig.second); + case(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP): + case(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL): { + auto regularGpio = dynamic_cast(gpioConfig.second); if(regularGpio == nullptr) { return GPIO_TYPE_FAILURE; } /* Check for conflicts and remove duplicates if necessary */ - result = checkForConflictsRegularGpio(gpioConfig.first, regularGpio, mapToAdd); + result = checkForConflictsRegularGpio(gpioConfig.first, *regularGpio, mapToAdd); if(result != HasReturnvaluesIF::RETURN_OK) { status = result; } @@ -276,17 +296,19 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck, - GpiodRegular* gpioToCheck, GpioMap& mapToAdd) { + GpiodRegularBase& gpioToCheck, GpioMap& mapToAdd) { /* Cross check with private map */ gpioMapIter = gpioMap.find(gpioIdToCheck); if(gpioMapIter != gpioMap.end()) { - if(gpioMapIter->second->gpioType != gpio::GpioTypes::GPIO_REGULAR) { + auto& gpioType = gpioMapIter->second->gpioType; + if(gpioType != gpio::GpioTypes::GPIO_REGULAR_BY_CHIP and + gpioType != gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different " "GPIO type" << gpioIdToCheck << ". Removing duplicate." << std::endl; mapToAdd.erase(gpioIdToCheck); return HasReturnvaluesIF::RETURN_OK; } - auto ownRegularGpio = dynamic_cast(gpioMapIter->second); + auto ownRegularGpio = dynamic_cast(gpioMapIter->second); if(ownRegularGpio == nullptr) { return GPIO_TYPE_FAILURE; } diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h index 00e1bdfe..31e4a7e8 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h @@ -6,6 +6,7 @@ #include class GpioCookie; +class GpiodRegularIF; /** * @brief This class implements the GpioIF for a linux based system. The @@ -47,9 +48,13 @@ private: * @param gpioId The GPIO ID of the GPIO to drive. * @param logiclevel The logic level to set. O or 1. */ - ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegular* regularGpio, unsigned int logiclevel); + ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio, + gpio::Levels logicLevel); - ReturnValue_t configureRegularGpio(gpioId_t gpioId, GpiodRegular* regularGpio); + ReturnValue_t configureGpioByLabel(gpioId_t gpioId, GpiodRegularByLabel& gpioByLabel); + ReturnValue_t configureGpioByChip(gpioId_t gpioId, GpiodRegularByChip& gpioByChip); + ReturnValue_t configureRegularGpio(gpioId_t gpioId, gpio::GpioTypes gpioType, + struct gpiod_chip* chip, GpiodRegularBase& regularGpio, std::string failOutput); /** * @brief This function checks if GPIOs are already registered and whether @@ -62,7 +67,7 @@ private: */ ReturnValue_t checkForConflicts(GpioMap& mapToAdd); - ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegular* regularGpio, + ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegularBase& regularGpio, GpioMap& mapToAdd); ReturnValue_t checkForConflictsCallbackGpio(gpioId_t gpiodId, GpioCallback* regularGpio, GpioMap& mapToAdd); From 3d1be94e120b76f7d1c86ff8f2a82e596f13c165 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 21 Sep 2021 19:27:33 +0200 Subject: [PATCH 33/48] more checks and printouts --- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp | 2 +- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index bcc48e58..15c3d118 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -200,7 +200,7 @@ ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) { return UNKNOWN_GPIO_ID; } - auto gpioType = gpioMapIter->second->gpioType; + auto& gpioType = gpioMapIter->second->gpioType; if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { auto regularGpio = dynamic_cast(gpioMapIter->second); diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index 6cf6675f..ec55f863 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -197,12 +197,26 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie *spiCookie, const if(gpioId != gpio::NO_GPIO) { result = spiMutex->lockMutex(timeoutType, timeoutMs); if (result != RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "SpiComIF::sendMessage: Failed to lock mutex" << std::endl; +#else + sif::printError("SpiComIF::sendMessage: Failed to lock mutex\n"); +#endif +#endif + return result; + } + ReturnValue_t result = gpioComIF->pullLow(gpioId); + if(result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "SpiComIF::sendMessage: Pulling low CS pin failed" << std::endl; +#else + sif::printWarning("SpiComIF::sendMessage: Pulling low CS pin failed"); +#endif #endif return result; } - gpioComIF->pullLow(gpioId); } /* Execute transfer */ From 5c56eda61077e3aef00d32133c5546987b476e8c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Sep 2021 12:19:30 +0200 Subject: [PATCH 34/48] fix for raspberry pi code --- hal/src/fsfw_hal/linux/rpi/GpioRPi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hal/src/fsfw_hal/linux/rpi/GpioRPi.cpp b/hal/src/fsfw_hal/linux/rpi/GpioRPi.cpp index 6a71f291..e1c274c0 100644 --- a/hal/src/fsfw_hal/linux/rpi/GpioRPi.cpp +++ b/hal/src/fsfw_hal/linux/rpi/GpioRPi.cpp @@ -12,7 +12,7 @@ ReturnValue_t gpio::createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int return HasReturnvaluesIF::RETURN_FAILED; } - GpiodRegular* config = new GpiodRegular(); + auto config = new GpiodRegularByChip(); /* Default chipname for Raspberry Pi. There is still gpiochip1 for expansion, but most users will not need this */ config->chipname = "gpiochip0"; From d3b83f3cf9d702f76ddc5a00ac715dc3a9ef5343 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Sep 2021 15:02:34 +0200 Subject: [PATCH 35/48] API made more consistent --- hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp | 2 +- hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp index 4a492e5d..5b58bb46 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp @@ -234,7 +234,7 @@ uint32_t GyroHandlerL3GD20H::getTransitionDelayMs(Mode_t from, Mode_t to) { return this->transitionDelayMs; } -void GyroHandlerL3GD20H::setGoNormalModeAtStartup() { +void GyroHandlerL3GD20H::setToGoToNormalMode(bool enable) { this->goNormalModeImmediately = true; } diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h index bc1d9c1c..07d9835f 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h @@ -25,7 +25,7 @@ public: /** * @brief Configure device handler to go to normal mode immediately */ - void setGoNormalModeAtStartup(); + void setToGoToNormalMode(bool enable); protected: /* DeviceHandlerBase overrides */ From c51d2df43dca317175a9448e662f7f469e5f8725 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Sep 2021 16:00:18 +0200 Subject: [PATCH 36/48] printout fix --- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index ec55f863..e940cf32 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -141,8 +141,8 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s if(sendLen > spiCookie->getMaxBufferSize()) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "SpiComIF::sendMessage: Too much data sent, send length" << sendLen << - "larger than maximum buffer length" << spiCookie->getMaxBufferSize() << std::endl; + sif::warning << "SpiComIF::sendMessage: Too much data sent, send length " << sendLen << + "larger than maximum buffer length " << spiCookie->getMaxBufferSize() << std::endl; #else sif::printWarning("SpiComIF::sendMessage: Too much data sent, send length %lu larger " "than maximum buffer length %lu!\n", static_cast(sendLen), From 29c74283f117bb68186d1161896d82e3361680c2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Sep 2021 18:36:53 +0200 Subject: [PATCH 37/48] sanity checks --- .../devicehandlers/GyroL3GD20Handler.cpp | 29 ++++++++++++++++--- .../devicehandlers/GyroL3GD20Handler.h | 9 +++++- .../devicehandlers/MgmLIS3MDLHandler.cpp | 27 ++++++++++++++--- .../devicehandlers/MgmLIS3MDLHandler.h | 9 +++++- 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp index 5b58bb46..06b4548b 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp @@ -215,11 +215,32 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id, PoolReadGuard readSet(&dataset); if(readSet.getReadResult() == HasReturnvaluesIF::RETURN_OK) { - dataset.angVelocX = angVelocX; - dataset.angVelocY = angVelocY; - dataset.angVelocZ = angVelocZ; + if(std::abs(angVelocX) > 100) { + dataset.angVelocX = angVelocX; + dataset.angVelocX.setValid(true); + } + else { + dataset.angVelocX.setValid(false); + } + + if(std::abs(angVelocY) > 100) { + dataset.angVelocY = angVelocY; + dataset.angVelocY.setValid(true); + } + else { + dataset.angVelocY.setValid(false); + } + + if(std::abs(angVelocZ) > 100) { + dataset.angVelocZ = angVelocZ; + dataset.angVelocZ.setValid(true); + } + else { + dataset.angVelocZ.setValid(false); + } + dataset.temperature = temperature; - dataset.setValidity(true, true); + dataset.temperature.setValid(true); } break; } diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h index 07d9835f..de2884e8 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h @@ -40,7 +40,14 @@ protected: size_t commandDataLen) override; ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, size_t *foundLen) override; - ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, + /** + * This implementation is tailored towards space systems and flags angular velocities + * larger than 100 as invalid + * @param id + * @param packet + * @return + */ + virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override; void fillCommandAndReplyMap() override; diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index 63dabfc9..6bc8a19e 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -308,10 +308,29 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, #endif /* OBSW_VERBOSE_LEVEL >= 1 */ PoolReadGuard readHelper(&dataset); if(readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) { - dataset.fieldStrengthX = mgmX; - dataset.fieldStrengthY = mgmY; - dataset.fieldStrengthZ = mgmZ; - dataset.setValidity(true, true); + if(std::abs(mgmX) > 100.0) { + dataset.fieldStrengthX = mgmX; + dataset.fieldStrengthX.setValid(true); + } + else { + dataset.fieldStrengthX.setValid(false); + } + + if(std::abs(mgmY) > 100.0) { + dataset.fieldStrengthY = mgmY; + dataset.fieldStrengthY.setValid(true); + } + else { + dataset.fieldStrengthY.setValid(false); + } + + if(std::abs(mgmZ) > 150.0) { + dataset.fieldStrengthZ = mgmZ; + dataset.fieldStrengthZ.setValid(true); + } + else { + dataset.fieldStrengthZ.setValid(false); + } } break; } diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h index 9fb41156..b0f249a9 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h @@ -52,7 +52,14 @@ protected: DeviceCommandId_t *id) override; ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, size_t *foundLen) override; - ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, + /** + * This implementation is tailored towards space applications and will flag values larger + * than 100 microtesla on X,Y and 150 microtesla on Z as invalid + * @param id + * @param packet + * @return + */ + virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override; void fillCommandAndReplyMap() override; void modeChanged(void) override; From 81c33d2dc657b853cc7ec63b01123fce04e6e103 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 23 Sep 2021 14:56:20 +0200 Subject: [PATCH 38/48] added functions to set x,y,z limits --- .../devicehandlers/GyroL3GD20Handler.cpp | 12 ++++++--- .../devicehandlers/GyroL3GD20Handler.h | 20 +++++++++----- .../devicehandlers/MgmLIS3MDLHandler.cpp | 26 +++++++------------ .../devicehandlers/MgmLIS3MDLHandler.h | 12 +++++++++ 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp index 06b4548b..4c8495b3 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp @@ -215,7 +215,7 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id, PoolReadGuard readSet(&dataset); if(readSet.getReadResult() == HasReturnvaluesIF::RETURN_OK) { - if(std::abs(angVelocX) > 100) { + if(std::abs(angVelocX) < this->absLimitX) { dataset.angVelocX = angVelocX; dataset.angVelocX.setValid(true); } @@ -223,7 +223,7 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id, dataset.angVelocX.setValid(false); } - if(std::abs(angVelocY) > 100) { + if(std::abs(angVelocY) < this->absLimitY) { dataset.angVelocY = angVelocY; dataset.angVelocY.setValid(true); } @@ -231,7 +231,7 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id, dataset.angVelocY.setValid(false); } - if(std::abs(angVelocZ) > 100) { + if(std::abs(angVelocZ) < this->absLimitZ) { dataset.angVelocZ = angVelocZ; dataset.angVelocZ.setValid(true); } @@ -277,3 +277,9 @@ void GyroHandlerL3GD20H::fillCommandAndReplyMap() { void GyroHandlerL3GD20H::modeChanged() { internalState = InternalState::NONE; } + +void GyroHandlerL3GD20H::setAxisLimits(float limitX, float limitY, float limitZ) { + this->absLimitX = limitX; + this->absLimitY = limitY; + this->absLimitZ = limitZ; +} diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h index de2884e8..030833be 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h @@ -22,6 +22,15 @@ public: CookieIF* comCookie, uint8_t switchId, uint32_t transitionDelayMs = 10000); virtual ~GyroHandlerL3GD20H(); + /** + * Set the absolute limit for the values on the axis in degrees per second. + * The dataset values will be marked as invalid if that limit is exceeded + * @param xLimit + * @param yLimit + * @param zLimit + */ + void setAbsoluteLimits(float limitX, float limitY, float limitZ); + /** * @brief Configure device handler to go to normal mode immediately */ @@ -40,13 +49,6 @@ protected: size_t commandDataLen) override; ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, size_t *foundLen) override; - /** - * This implementation is tailored towards space systems and flags angular velocities - * larger than 100 as invalid - * @param id - * @param packet - * @return - */ virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override; @@ -61,6 +63,10 @@ private: uint32_t transitionDelayMs = 0; GyroPrimaryDataset dataset; + float absLimitX = L3GD20H::RANGE_DPS_00; + float absLimitY = L3GD20H::RANGE_DPS_00; + float absLimitZ = L3GD20H::RANGE_DPS_00; + enum class InternalState { NONE, CONFIGURE, diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index 6bc8a19e..4f164d79 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -291,7 +291,6 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, #if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 if(debugDivider->checkAndIncrement()) { - /* Set terminal to utf-8 if there is an issue with micro printout. */ #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "MGMHandlerLIS3: Magnetic field strength in" " microtesla:" << std::endl; @@ -308,7 +307,7 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, #endif /* OBSW_VERBOSE_LEVEL >= 1 */ PoolReadGuard readHelper(&dataset); if(readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) { - if(std::abs(mgmX) > 100.0) { + if(std::abs(mgmX) < absLimitX) { dataset.fieldStrengthX = mgmX; dataset.fieldStrengthX.setValid(true); } @@ -316,7 +315,7 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, dataset.fieldStrengthX.setValid(false); } - if(std::abs(mgmY) > 100.0) { + if(std::abs(mgmY) < absLimitY) { dataset.fieldStrengthY = mgmY; dataset.fieldStrengthY.setValid(true); } @@ -324,7 +323,7 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, dataset.fieldStrengthY.setValid(false); } - if(std::abs(mgmZ) > 150.0) { + if(std::abs(mgmZ) < absLimitZ) { dataset.fieldStrengthZ = mgmZ; dataset.fieldStrengthZ.setValid(true); } @@ -340,7 +339,6 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, float tempValue = 25.0 + ((static_cast(tempValueRaw)) / 8.0); #if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 if(debugDivider->check()) { - /* Set terminal to utf-8 if there is an issue with micro printout. */ #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "MGMHandlerLIS3: Temperature: " << tempValue << " C" << std::endl; @@ -463,16 +461,6 @@ ReturnValue_t MgmLIS3MDLHandler::setOperatingMode(const uint8_t *commandData, } void MgmLIS3MDLHandler::fillCommandAndReplyMap() { - /* - * Regarding ArduinoBoard: - * Actually SPI answers directly, but as commanding ArduinoBoard the - * communication could be delayed - * SPI always has to be triggered, so there could be no periodic answer of - * the device, the device has to asked with a command, so periodic is zero. - * - * We dont read single registers, we just expect special - * reply from he Readall_MGM - */ insertInCommandAndReplyMap(MGMLIS3MDL::READ_CONFIG_AND_DATA, 1, &dataset); insertInCommandAndReplyMap(MGMLIS3MDL::READ_TEMPERATURE, 1); insertInCommandAndReplyMap(MGMLIS3MDL::SETUP_MGM, 1); @@ -494,7 +482,7 @@ ReturnValue_t MgmLIS3MDLHandler::prepareCtrlRegisterWrite() { rawPacket = commandBuffer; rawPacketLen = MGMLIS3MDL::NR_OF_CTRL_REGISTERS + 1; - /* We dont have to check if this is working because we just did it */ + // We dont have to check if this is working because we just did i return RETURN_OK; } @@ -522,3 +510,9 @@ ReturnValue_t MgmLIS3MDLHandler::initializeLocalDataPool( new PoolEntry({0.0})); return HasReturnvaluesIF::RETURN_OK; } + +void MgmLIS3MDLHandler::setAbsoluteLimits(float xLimit, float yLimit, float zLimit) { + this->absLimitX = xLimit; + this->absLimitY = yLimit; + this->absLimitZ = zLimit; +} diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h index b0f249a9..7181d8a0 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h @@ -34,6 +34,14 @@ public: uint8_t switchId, uint32_t transitionDelay = 10000); virtual ~MgmLIS3MDLHandler(); + /** + * Set the absolute limit for the values on the axis in microtesla. The dataset values will + * be marked as invalid if that limit is exceeded + * @param xLimit + * @param yLimit + * @param zLimit + */ + void setAbsoluteLimits(float xLimit, float yLimit, float zLimit); void setToGoToNormalMode(bool enable); protected: @@ -77,6 +85,10 @@ private: //has the size for all adresses of the lis3mdl + the continous write bit uint8_t commandBuffer[MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1]; + float absLimitX = 100; + float absLimitY = 100; + float absLimitZ = 150; + /** * We want to save the registers we set, so we dont have to read the * registers when we want to change something. From c9b343ebcd92de1d214a9b1d7abafee4a7e79888 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 23 Sep 2021 15:20:10 +0200 Subject: [PATCH 39/48] op divider fixes --- .../devicehandlers/GyroL3GD20Handler.cpp | 8 ++++---- .../devicehandlers/GyroL3GD20Handler.h | 4 ++-- .../devicehandlers/MgmLIS3MDLHandler.cpp | 6 +++--- .../devicehandlers/MgmLIS3MDLHandler.h | 10 +++++----- .../devicehandlers/MgmRM3100Handler.cpp | 13 +++---------- .../fsfw_hal/devicehandlers/MgmRM3100Handler.h | 18 ++++++------------ .../PeriodicOperationDivider.cpp | 5 ++--- 7 files changed, 25 insertions(+), 39 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp index 4c8495b3..70ba49eb 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp @@ -3,11 +3,11 @@ #include "fsfw/datapool/PoolReadGuard.h" GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication, - CookieIF *comCookie, uint8_t switchId, uint32_t transitionDelayMs): + CookieIF *comCookie, uint32_t transitionDelayMs): DeviceHandlerBase(objectId, deviceCommunication, comCookie), - switchId(switchId), transitionDelayMs(transitionDelayMs), dataset(this) { + transitionDelayMs(transitionDelayMs), dataset(this) { #if FSFW_HAL_L3GD20_GYRO_DEBUG == 1 - debugDivider = new PeriodicOperationDivider(5); + debugDivider = new PeriodicOperationDivider(3); #endif } @@ -278,7 +278,7 @@ void GyroHandlerL3GD20H::modeChanged() { internalState = InternalState::NONE; } -void GyroHandlerL3GD20H::setAxisLimits(float limitX, float limitY, float limitZ) { +void GyroHandlerL3GD20H::setAbsoluteLimits(float limitX, float limitY, float limitZ) { this->absLimitX = limitX; this->absLimitY = limitY; this->absLimitZ = limitZ; diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h index 030833be..870f551d 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.h @@ -19,7 +19,7 @@ class GyroHandlerL3GD20H: public DeviceHandlerBase { public: GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication, - CookieIF* comCookie, uint8_t switchId, uint32_t transitionDelayMs = 10000); + CookieIF* comCookie, uint32_t transitionDelayMs); virtual ~GyroHandlerL3GD20H(); /** @@ -54,7 +54,7 @@ protected: void fillCommandAndReplyMap() override; void modeChanged() override; - uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override; + virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override; ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) override; diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index 4f164d79..891d6fdc 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -6,13 +6,13 @@ #endif MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication, - CookieIF* comCookie, uint8_t switchId, uint32_t transitionDelay): + CookieIF* comCookie, uint32_t transitionDelay): DeviceHandlerBase(objectId, deviceCommunication, comCookie), dataset(this), transitionDelay(transitionDelay) { #if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 - debugDivider = new PeriodicOperationDivider(5); + debugDivider = new PeriodicOperationDivider(3); #endif - /* Set to default values right away. */ + // Set to default values right away registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT; registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT; registers[2] = MGMLIS3MDL::CTRL_REG3_DEFAULT; diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h index 7181d8a0..6bf89a49 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h @@ -31,7 +31,7 @@ public: static const Event CHANGE_OF_SETUP_PARAMETER = MAKE_EVENT(0, severity::LOW); MgmLIS3MDLHandler(uint32_t objectId, object_id_t deviceCommunication, CookieIF* comCookie, - uint8_t switchId, uint32_t transitionDelay = 10000); + uint32_t transitionDelay); virtual ~MgmLIS3MDLHandler(); /** @@ -50,7 +50,7 @@ protected: void doShutDown() override; void doStartUp() override; void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; - uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override; + virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override; ReturnValue_t buildCommandFromCommand( DeviceCommandId_t deviceCommand, const uint8_t *commandData, size_t commandDataLen) override; @@ -76,13 +76,13 @@ protected: private: MGMLIS3MDL::MgmPrimaryDataset dataset; - //Length a sindgle command SPI answer + //Length a single command SPI answer static const uint8_t SINGLE_COMMAND_ANSWER_LEN = 2; uint32_t transitionDelay; - //Single SPIcommand has 2 bytes, first for adress, second for content + // 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 + // Has the size for all adresses of the lis3mdl + the continous write bit uint8_t commandBuffer[MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1]; float absLimitX = 100; diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp index 467141de..20cf95d2 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp @@ -8,10 +8,9 @@ MgmRM3100Handler::MgmRM3100Handler(object_id_t objectId, - object_id_t deviceCommunication, CookieIF* comCookie, uint8_t switchId, - uint32_t transitionDelay): + object_id_t deviceCommunication, CookieIF* comCookie, uint32_t transitionDelay): DeviceHandlerBase(objectId, deviceCommunication, comCookie), - primaryDataset(this), switchId(switchId), transitionDelay(transitionDelay) { + primaryDataset(this), transitionDelay(transitionDelay) { #if FSFW_HAL_RM3100_MGM_DEBUG == 1 debugDivider = new PeriodicOperationDivider(3); #endif @@ -322,13 +321,7 @@ ReturnValue_t MgmRM3100Handler::initializeLocalDataPool( } uint32_t MgmRM3100Handler::getTransitionDelayMs(Mode_t from, Mode_t to) { - return 25000; -} - -ReturnValue_t MgmRM3100Handler::getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) { - *switches = &switchId; - *numberOfSwitches = 1; - return HasReturnvaluesIF::RETURN_OK; + return this->transitionDelay; } void MgmRM3100Handler::setToGoToNormalMode(bool enable) { diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h index eb6e62bc..1ba680cb 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.h @@ -32,7 +32,7 @@ public: SUBSYSTEM_ID::MGM_RM3100, 0x01, severity::INFO); MgmRM3100Handler(object_id_t objectId, object_id_t deviceCommunication, - CookieIF* comCookie, uint8_t switchId, uint32_t transitionDelay = 10000); + CookieIF* comCookie, uint32_t transitionDelay); virtual ~MgmRM3100Handler(); /** @@ -48,21 +48,16 @@ protected: DeviceCommandId_t *id) override; void doStartUp() override; void doShutDown() override; - ReturnValue_t buildNormalDeviceCommand( - DeviceCommandId_t *id) override; - ReturnValue_t buildCommandFromCommand( - DeviceCommandId_t deviceCommand, const uint8_t *commandData, - size_t commandDataLen) override; + ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override; + ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t *commandData, size_t commandDataLen) override; ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, size_t *foundLen) override; - ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) override; - ReturnValue_t getSwitches(const uint8_t **switches, - uint8_t *numberOfSwitches) override; + ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override; void fillCommandAndReplyMap() override; void modeChanged(void) override; - uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override; + virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override; ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) override; @@ -97,7 +92,6 @@ private: float scaleFactorZ = 1.0 / RM3100::DEFAULT_GAIN; bool goToNormalModeAtStartup = false; - uint8_t switchId; uint32_t transitionDelay; ReturnValue_t handleCycleCountConfigCommand(DeviceCommandId_t deviceCommand, diff --git a/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp b/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp index 5d9e1624..ffba7574 100644 --- a/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp +++ b/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp @@ -7,14 +7,13 @@ PeriodicOperationDivider::PeriodicOperationDivider(uint32_t divider, } bool PeriodicOperationDivider::checkAndIncrement() { + counter++; bool opNecessary = check(); if(opNecessary) { if(resetAutomatically) { - counter = 1; + counter = 0; } - return opNecessary; } - counter++; return opNecessary; } From 350fbc385cedae73ea2396dafdeb5b74b28be74d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 23 Sep 2021 15:22:27 +0200 Subject: [PATCH 40/48] small tweak --- src/fsfw/globalfunctions/PeriodicOperationDivider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp b/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp index ffba7574..98f83d04 100644 --- a/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp +++ b/src/fsfw/globalfunctions/PeriodicOperationDivider.cpp @@ -11,7 +11,7 @@ bool PeriodicOperationDivider::checkAndIncrement() { bool opNecessary = check(); if(opNecessary) { if(resetAutomatically) { - counter = 0; + resetCounter(); } } return opNecessary; From dccc2f0ba77184933e3d551d95950a5b0801d2f2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 23 Sep 2021 15:57:50 +0200 Subject: [PATCH 41/48] printout fix SpiComIF --- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index e940cf32..1fa87121 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -398,11 +398,11 @@ GpioIF* SpiComIF::getGpioInterface() { void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) { int retval = ioctl(spiFd, SPI_IOC_WR_MODE, reinterpret_cast(&mode)); if(retval != 0) { - utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!"); + utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Setting SPI mode failed"); } retval = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); if(retval != 0) { - utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!"); + utility::handleIoctlError("SpiComIF::setSpiSpeedAndMode: Setting SPI speed failed"); } } From a3eb870ba06659d598d6f67c2baef731474ec468 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 23 Sep 2021 16:45:37 +0200 Subject: [PATCH 42/48] Corrected comment --- src/fsfw/devicehandlers/DeviceHandlerBase.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index b182b611..4bc54ac4 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -334,8 +334,7 @@ protected: * - @c RETURN_OK to send command after #rawPacket and #rawPacketLen * have been set. * - @c HasActionsIF::EXECUTION_COMPLETE to generate a finish reply immediately. This can - * be used if no reply is expected. Otherwise, the developer can call #actionHelper.finish - * to finish the command handling. + * be used if no reply is expected * - Anything else triggers an event with the return code as a parameter as well as a * step reply failed with the return code */ From e1a85b47c5018590e58b9b1130b1754b0079450f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 23 Sep 2021 17:13:53 +0200 Subject: [PATCH 43/48] tiny tweaks --- src/fsfw/devicehandlers/AssemblyBase.h | 2 +- src/fsfw/subsystem/SubsystemBase.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fsfw/devicehandlers/AssemblyBase.h b/src/fsfw/devicehandlers/AssemblyBase.h index 6cac81b4..7d54f14d 100644 --- a/src/fsfw/devicehandlers/AssemblyBase.h +++ b/src/fsfw/devicehandlers/AssemblyBase.h @@ -7,7 +7,7 @@ /** * @brief Base class to implement reconfiguration and failure handling for - * redundant devices by monitoring their modes health states. + * redundant devices by monitoring their modes and health states. * @details * Documentation: Dissertation Baetz p.156, 157. * diff --git a/src/fsfw/subsystem/SubsystemBase.h b/src/fsfw/subsystem/SubsystemBase.h index 6b2e9b5f..a1de077d 100644 --- a/src/fsfw/subsystem/SubsystemBase.h +++ b/src/fsfw/subsystem/SubsystemBase.h @@ -62,7 +62,8 @@ protected: struct ChildInfo { MessageQueueId_t commandQueue; Mode_t mode; - Submode_t submode;bool healthChanged; + Submode_t submode; + bool healthChanged; }; Mode_t mode; From 0987a160c9c200e1b7b72e992ae158d826147c30 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 23 Sep 2021 17:33:45 +0200 Subject: [PATCH 44/48] new retval for empty slot list --- src/fsfw/returnvalues/FwClassIds.h | 1 + src/fsfw/tasks/FixedSlotSequence.cpp | 6 +++--- src/fsfw/tasks/FixedSlotSequence.h | 4 +++- src/fsfw/tasks/FixedTimeslotTaskIF.h | 5 ++++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/fsfw/returnvalues/FwClassIds.h b/src/fsfw/returnvalues/FwClassIds.h index 7f355c40..ce093b09 100644 --- a/src/fsfw/returnvalues/FwClassIds.h +++ b/src/fsfw/returnvalues/FwClassIds.h @@ -77,6 +77,7 @@ enum: uint8_t { HAL_UART, //HURT HAL_I2C, //HI2C HAL_GPIO, //HGIO + FIXED_SLOT_TASK_IF, //FTIF FW_CLASS_ID_COUNT // [EXPORT] : [END] }; diff --git a/src/fsfw/tasks/FixedSlotSequence.cpp b/src/fsfw/tasks/FixedSlotSequence.cpp index 2e5384b7..5e896af4 100644 --- a/src/fsfw/tasks/FixedSlotSequence.cpp +++ b/src/fsfw/tasks/FixedSlotSequence.cpp @@ -1,4 +1,5 @@ #include "fsfw/tasks/FixedSlotSequence.h" +#include "fsfw/tasks/FixedTimeslotTaskIF.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include @@ -92,10 +93,9 @@ void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs, ReturnValue_t FixedSlotSequence::checkSequence() const { if(slotList.empty()) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "FixedSlotSequence::checkSequence:" - << " Slot list is empty!" << std::endl; + sif::warning << "FixedSlotSequence::checkSequence: Slot list is empty!" << std::endl; #endif - return HasReturnvaluesIF::RETURN_FAILED; + return FixedTimeslotTaskIF::SLOT_LIST_EMPTY; } if(customCheckFunction != nullptr) { diff --git a/src/fsfw/tasks/FixedSlotSequence.h b/src/fsfw/tasks/FixedSlotSequence.h index 077dd10b..7f49ea0c 100644 --- a/src/fsfw/tasks/FixedSlotSequence.h +++ b/src/fsfw/tasks/FixedSlotSequence.h @@ -2,7 +2,7 @@ #define FSFW_TASKS_FIXEDSLOTSEQUENCE_H_ #include "FixedSequenceSlot.h" -#include "../objectmanager/SystemObject.h" +#include "fsfw/objectmanager/SystemObject.h" #include @@ -136,6 +136,7 @@ public: * @details * Checks if timing is ok (must be ascending) and if all handlers were found. * @return + * - SLOT_LIST_EMPTY if the slot list is empty */ ReturnValue_t checkSequence() const; @@ -147,6 +148,7 @@ public: * The general check will be continued for now if the custom check function * fails but a diagnostic debug output will be given. * @param customCheckFunction + * */ void addCustomCheck(ReturnValue_t (*customCheckFunction)(const SlotList &)); diff --git a/src/fsfw/tasks/FixedTimeslotTaskIF.h b/src/fsfw/tasks/FixedTimeslotTaskIF.h index 2fc7e092..605239a4 100644 --- a/src/fsfw/tasks/FixedTimeslotTaskIF.h +++ b/src/fsfw/tasks/FixedTimeslotTaskIF.h @@ -2,7 +2,8 @@ #define FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_ #include "PeriodicTaskIF.h" -#include "../objectmanager/ObjectManagerIF.h" +#include "fsfw/objectmanager/ObjectManagerIF.h" +#include "fsfw/returnvalues/FwClassIds.h" /** * @brief Following the same principle as the base class IF. @@ -12,6 +13,8 @@ class FixedTimeslotTaskIF : public PeriodicTaskIF { public: virtual ~FixedTimeslotTaskIF() {} + static constexpr ReturnValue_t SLOT_LIST_EMPTY = HasReturnvaluesIF::makeReturnCode( + CLASS_ID::FIXED_SLOT_TASK_IF, 0); /** * Add an object with a slot time and the execution step to the task. * The execution step will be passed to the object (e.g. as an operation From 665be0d417a04b7bea5a4e18f1434153b166e37a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 23 Sep 2021 18:05:17 +0200 Subject: [PATCH 45/48] better name for wiretapping define --- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 2 +- src/fsfw/FSFW.h.in | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index 1fa87121..9c4e66ae 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -227,7 +227,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie *spiCookie, const utility::handleIoctlError("SpiComIF::sendMessage: ioctl error."); result = FULL_DUPLEX_TRANSFER_FAILED; } -#if FSFW_HAL_LINUX_SPI_WIRETAPPING == 1 +#if FSFW_HAL_SPI_WIRETAPPING == 1 performSpiWiretapping(spiCookie); #endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */ } diff --git a/src/fsfw/FSFW.h.in b/src/fsfw/FSFW.h.in index 3f005387..628cd521 100644 --- a/src/fsfw/FSFW.h.in +++ b/src/fsfw/FSFW.h.in @@ -20,9 +20,9 @@ #define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0 #endif -/* Can be used for low-level debugging of the SPI bus */ -#ifndef FSFW_HAL_LINUX_SPI_WIRETAPPING -#define FSFW_HAL_LINUX_SPI_WIRETAPPING 0 +// Can be used for low-level debugging of the SPI bus +#ifndef FSFW_HAL_SPI_WIRETAPPING +#define FSFW_HAL_SPI_WIRETAPPING 0 #endif #ifndef FSFW_HAL_L3GD20_GYRO_DEBUG From e0671a395ebea9d2297b2096293db80a2e412f4a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 23 Sep 2021 18:14:40 +0200 Subject: [PATCH 46/48] indentation --- src/fsfw/FSFW.h.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/fsfw/FSFW.h.in b/src/fsfw/FSFW.h.in index 628cd521..12703add 100644 --- a/src/fsfw/FSFW.h.in +++ b/src/fsfw/FSFW.h.in @@ -22,7 +22,7 @@ // Can be used for low-level debugging of the SPI bus #ifndef FSFW_HAL_SPI_WIRETAPPING -#define FSFW_HAL_SPI_WIRETAPPING 0 +#define FSFW_HAL_SPI_WIRETAPPING 0 #endif #ifndef FSFW_HAL_L3GD20_GYRO_DEBUG @@ -34,7 +34,6 @@ #endif /* FSFW_HAL_RM3100_MGM_DEBUG */ #ifndef FSFW_HAL_LIS3MDL_MGM_DEBUG -#define FSFW_HAL_LIS3MDL_MGM_DEBUG 0 +#define FSFW_HAL_LIS3MDL_MGM_DEBUG 0 #endif /* FSFW_HAL_LIS3MDL_MGM_DEBUG */ - #endif /* FSFW_FSFW_H_ */ From 59feaa4b5c272899e07915accc4c3b46d3f4d45d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 26 Sep 2021 22:38:47 +0200 Subject: [PATCH 47/48] moved class id and subsystem ID --- src/fsfw/events/fwSubsystemIdRanges.h | 2 ++ src/fsfw/returnvalues/FwClassIds.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/fsfw/events/fwSubsystemIdRanges.h b/src/fsfw/events/fwSubsystemIdRanges.h index 88dee9b4..08fb878d 100644 --- a/src/fsfw/events/fwSubsystemIdRanges.h +++ b/src/fsfw/events/fwSubsystemIdRanges.h @@ -29,6 +29,8 @@ enum: uint8_t { PUS_SERVICE_9 = 89, PUS_SERVICE_17 = 97, PUS_SERVICE_23 = 103, + MGM_LIS3MDL = 106, + MGM_RM3100 = 107, FW_SUBSYSTEM_ID_RANGE }; diff --git a/src/fsfw/returnvalues/FwClassIds.h b/src/fsfw/returnvalues/FwClassIds.h index af32f9a7..cdbf5657 100644 --- a/src/fsfw/returnvalues/FwClassIds.h +++ b/src/fsfw/returnvalues/FwClassIds.h @@ -76,6 +76,8 @@ enum: uint8_t { HAL_UART, //HURT HAL_I2C, //HI2C HAL_GPIO, //HGIO + MGM_LIS3MDL, //MGMLIS3 + MGM_RM3100, //MGMRM3100 FW_CLASS_ID_COUNT // [EXPORT] : [END] }; From 423f7c828189701230fe7161a680590e37bf40fb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 26 Sep 2021 22:45:32 +0200 Subject: [PATCH 48/48] missing include and printer compatbility fixes --- .../devicehandlers/GyroL3GD20Handler.cpp | 4 +++- .../devicehandlers/MgmLIS3MDLHandler.cpp | 2 ++ .../devicehandlers/MgmRM3100Handler.cpp | 19 ++++++++++++++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp index 70ba49eb..d27351d7 100644 --- a/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/GyroL3GD20Handler.cpp @@ -1,7 +1,9 @@ -#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h" +#include "GyroL3GD20Handler.h" #include "fsfw/datapool/PoolReadGuard.h" +#include + GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication, CookieIF *comCookie, uint32_t transitionDelayMs): DeviceHandlerBase(objectId, deviceCommunication, comCookie), diff --git a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp index 891d6fdc..804e83f2 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.cpp @@ -5,6 +5,8 @@ #include "fsfw/globalfunctions/PeriodicOperationDivider.h" #endif +#include + MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication, CookieIF* comCookie, uint32_t transitionDelay): DeviceHandlerBase(objectId, deviceCommunication, comCookie), diff --git a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp index 20cf95d2..124eebbc 100644 --- a/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp +++ b/hal/src/fsfw_hal/devicehandlers/MgmRM3100Handler.cpp @@ -89,9 +89,16 @@ ReturnValue_t MgmRM3100Handler::buildTransitionDeviceCommand( break; } default: +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 // Might be a configuration error - sif::warning << "MgmRM3100Handler::buildTransitionDeviceCommand: Unknown internal state!" << - std::endl; + sif::warning << "MgmRM3100Handler::buildTransitionDeviceCommand: " + "Unknown internal state" << std::endl; +#else + sif::printWarning("MgmRM3100Handler::buildTransitionDeviceCommand: " + "Unknown internal state\n"); +#endif +#endif return HasReturnvaluesIF::RETURN_OK; } @@ -342,12 +349,18 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) { #if FSFW_HAL_RM3100_MGM_DEBUG == 1 if(debugDivider->checkAndIncrement()) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "MgmRM3100Handler: Magnetic field strength in" " microtesla:" << std::endl; - /* Set terminal to utf-8 if there is an issue with micro printout. */ sif::info << "X: " << fieldStrengthX << " uT" << std::endl; sif::info << "Y: " << fieldStrengthY << " uT" << std::endl; sif::info << "Z: " << fieldStrengthZ << " uT" << std::endl; +#else + sif::printInfo("MgmRM3100Handler: Magnetic field strength in microtesla:\n"); + sif::printInfo("X: %f uT\n", fieldStrengthX); + sif::printInfo("Y: %f uT\n", fieldStrengthY); + sif::printInfo("Z: %f uT\n", fieldStrengthZ); +#endif } #endif