From f6b624f41e1caf1faf18c45892cc2b44f42a2558 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 17:44:16 +0100 Subject: [PATCH 01/51] reference returned now --- linux/gpio/GpioCookie.cpp | 2 +- linux/gpio/GpioCookie.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/gpio/GpioCookie.cpp b/linux/gpio/GpioCookie.cpp index f4e585d1..6355578c 100644 --- a/linux/gpio/GpioCookie.cpp +++ b/linux/gpio/GpioCookie.cpp @@ -19,7 +19,7 @@ void GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig){ } } -GpioMap GpioCookie::getGpioMap() const{ +GpioMap& GpioCookie::getGpioMap() const { return gpioMap; } diff --git a/linux/gpio/GpioCookie.h b/linux/gpio/GpioCookie.h index 72011750..8ec30d79 100644 --- a/linux/gpio/GpioCookie.h +++ b/linux/gpio/GpioCookie.h @@ -65,7 +65,7 @@ public: /** * @brief Get map with registered GPIOs. */ - GpioMap getGpioMap() const; + GpioMap& getGpioMap() const; private: From 60410fd6f82d18d60863f744adf52b908ab04c10 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:21:59 +0100 Subject: [PATCH 02/51] some minor improvements --- linux/gpio/GpioCookie.cpp | 20 ++++++------- linux/gpio/GpioCookie.h | 31 ++++++++++---------- linux/gpio/GpioIF.h | 4 +-- linux/gpio/LinuxLibgpioIF.cpp | 55 ++++++++++++++++++----------------- linux/gpio/LinuxLibgpioIF.h | 10 +++---- 5 files changed, 59 insertions(+), 61 deletions(-) diff --git a/linux/gpio/GpioCookie.cpp b/linux/gpio/GpioCookie.cpp index 6355578c..7f80b550 100644 --- a/linux/gpio/GpioCookie.cpp +++ b/linux/gpio/GpioCookie.cpp @@ -1,25 +1,23 @@ #include "GpioCookie.h" -#include +#include GpioCookie::GpioCookie() { } void GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig){ - gpioMapIter = gpioMap.find(gpioId); + auto gpioMapIter = gpioMap.find(gpioId); if(gpioMapIter == gpioMap.end()) { - std::pair status = gpioMap.emplace(gpioId, gpioConfig); - if (status.second == false) { - sif::error << "GpioCookie::addGpio: Failed to add GPIO " - << gpioId << "to GPIO map" << std::endl; + auto statusPair = gpioMap.emplace(gpioId, gpioConfig); + if (statusPair.second == false) { + sif::error << "GpioCookie::addGpio: Failed to add GPIO " << gpioId << + "to GPIO map" << std::endl; } + return; } - else { - sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map " - << std::endl; - } + sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map " << std::endl; } -GpioMap& GpioCookie::getGpioMap() const { +GpioMap GpioCookie::getGpioMap() const { return gpioMap; } diff --git a/linux/gpio/GpioCookie.h b/linux/gpio/GpioCookie.h index 8ec30d79..5e4a7b1d 100644 --- a/linux/gpio/GpioCookie.h +++ b/linux/gpio/GpioCookie.h @@ -17,23 +17,22 @@ enum Direction { /** * @brief Struct containing information about the GPIO to use. This is * required by the libgpiod to access and drive a GPIO. - * @param chipname String of the chipname specifying the group which contains - * the GPIO to access. E.g. gpiochip0. To detect names of - * GPIO groups run gpiodetect on the linux command line. - * @param lineNum The offset of the GPIO within the GPIO group. - * @param consumer Name of the consumer. Simply a description of the GPIO configuration. - * @param direction Specifies whether the GPIO should be used as in- or output. - * @param initValue Defines the initial state of the GPIO when configured as output. Only required - * for output GPIOs. + * @param chipname String of the chipname specifying the group which contains the GPIO to + * access. E.g. gpiochip0. To detect names of GPIO groups run gpiodetect on + * the linux command line. + * @param lineNum The offset of the GPIO within the GPIO group. + * @param consumer Name of the consumer. Simply a description of the GPIO configuration. + * @param direction Specifies whether the GPIO should be used as in- or output. + * @param initValue Defines the initial state of the GPIO when configured as output. + * Only required for output GPIOs. * @param lineHandle The handle returned by gpiod_chip_get_line will be later written to this * pointer. */ typedef struct GpioConfig { GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, - gpio::Direction direction_, int initValue_) : - chipname(chipname_), lineNum(lineNum_), consumer(consumer_), direction(direction_), - initValue(initValue_) { - } + gpio::Direction direction_, int initValue_): + chipname(chipname_), lineNum(lineNum_), consumer(consumer_), + direction(direction_), initValue(initValue_) {} std::string chipname; int lineNum; std::string consumer; @@ -41,6 +40,7 @@ typedef struct GpioConfig { int initValue; struct gpiod_line* lineHandle = nullptr; } GpioConfig_t; + using GpioMap = std::unordered_map; using GpioMapIter = GpioMap::iterator; @@ -65,12 +65,13 @@ public: /** * @brief Get map with registered GPIOs. */ - GpioMap& getGpioMap() const; + GpioMap getGpioMap() const; private: - + /** + * Returns a copy of the internal GPIO map. + */ GpioMap gpioMap; - GpioMapIter gpioMapIter; }; #endif diff --git a/linux/gpio/GpioIF.h b/linux/gpio/GpioIF.h index d1f02dd8..8d36a1b7 100644 --- a/linux/gpio/GpioIF.h +++ b/linux/gpio/GpioIF.h @@ -11,7 +11,7 @@ typedef uint16_t gpioId_t; * over GPIOs. * @author J. Meier */ -class GpioIF : public HasReturnvaluesIF{ +class GpioIF : public HasReturnvaluesIF { public: virtual ~GpioIF() {}; @@ -21,7 +21,7 @@ public: * @param cookie Cookie specifying informations of the GPIOs required * by a object. */ - virtual ReturnValue_t initialize(CookieIF * cookie) = 0; + virtual ReturnValue_t initialize(CookieIF* cookie) = 0; /** * @brief By implementing this function a child must provide the diff --git a/linux/gpio/LinuxLibgpioIF.cpp b/linux/gpio/LinuxLibgpioIF.cpp index e5db2934..da235716 100644 --- a/linux/gpio/LinuxLibgpioIF.cpp +++ b/linux/gpio/LinuxLibgpioIF.cpp @@ -33,7 +33,7 @@ ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){ return result; } - result = configureGpios(&mapToAdd); + result = configureGpios(mapToAdd); if (result != RETURN_OK) { return RETURN_FAILED; } @@ -44,8 +44,8 @@ ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){ return RETURN_OK; } -ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap* mapToAdd) { - GpioMapIter mapToAddIter; +ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { + //GpioMapIter mapToAddIter; std::string chipname; unsigned int lineNum; struct gpiod_chip *chip; @@ -54,18 +54,18 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap* mapToAdd) { struct gpiod_line *lineHandle; int result; - mapToAddIter = mapToAdd->begin(); - for (; mapToAddIter != mapToAdd->end(); mapToAddIter++) { - - chipname = mapToAddIter->second.chipname; + //mapToAddIter = mapToAdd->begin(); + for(auto& gpioConfig: mapToAdd) { + //for (; mapToAddIter != mapToAdd->end(); mapToAddIter++) { + chipname = gpioConfig.second.chipname; chip = gpiod_chip_open_by_name(chipname.c_str()); if (!chip) { sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip " - << chipname << ". Gpio ID: " << mapToAddIter->first << std::endl; + << chipname << ". Gpio ID: " << gpioConfig.first << std::endl; return RETURN_FAILED; } - lineNum = mapToAddIter->second.lineNum; + lineNum = gpioConfig.second.lineNum; lineHandle = gpiod_chip_get_line(chip, lineNum); if (!lineHandle) { sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line" << std::endl; @@ -73,16 +73,16 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap* mapToAdd) { return RETURN_FAILED; } - direction = mapToAddIter->second.direction; - consumer = mapToAddIter->second.consumer; + direction = gpioConfig.second.direction; + consumer = gpioConfig.second.consumer; /* Configure direction and add a description to the GPIO */ switch (direction) { case gpio::OUT: result = gpiod_line_request_output(lineHandle, consumer.c_str(), - mapToAddIter->second.initValue); + gpioConfig.second.initValue); if (result < 0) { sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " - << lineNum << " from GPIO instance with ID: " << mapToAddIter->first + << lineNum << " from GPIO instance with ID: " << gpioConfig.first << std::endl; gpiod_line_release(lineHandle); return RETURN_FAILED; @@ -92,7 +92,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap* mapToAdd) { result = gpiod_line_request_input(lineHandle, consumer.c_str()); if (result < 0) { sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " - << lineNum << " from GPIO instance with ID: " << mapToAddIter->first + << lineNum << " from GPIO instance with ID: " << gpioConfig.first << std::endl; gpiod_line_release(lineHandle); return RETURN_FAILED; @@ -107,7 +107,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap* mapToAdd) { * Write line handle to GPIO configuration instance so it can later be used to set or * read states of GPIOs. */ - mapToAddIter->second.lineHandle = lineHandle; + gpioConfig.second.lineHandle = lineHandle; } return RETURN_OK; } @@ -125,7 +125,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, int result; struct gpiod_line *lineHandle; - gpioMapIter = gpioMap.find(gpioId); + auto gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()){ sif::debug << "LinuxLibgpioIF::driveGpio: Unknown gpio id " << gpioId << std::endl; return RETURN_FAILED; @@ -145,7 +145,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { struct gpiod_line *lineHandle; - gpioMapIter = gpioMap.find(gpioId); + auto gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()){ sif::debug << "LinuxLibgpioIF::readGpio: Unknown gpio id " << gpioId << std::endl; return RETURN_FAILED; @@ -157,23 +157,24 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { return RETURN_OK; } -ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap mapToAdd){ +ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ gpioId_t gpioId; - GpioMapIter mapToAddIter = mapToAdd.begin(); - for(; mapToAddIter != mapToAdd.end(); mapToAddIter++){ - gpioId = mapToAddIter->first; + auto gpioMapIter = gpioMap.begin(); + for(auto& gpioConfig: mapToAdd) { + gpioId = gpioConfig.first; + /* Cross check with private map */ gpioMapIter = gpioMap.find(gpioId); - if(gpioMapIter != mapToAdd.end()){ + if(gpioMapIter != mapToAdd.end()) { /* An entry for this GPIO already exists. Check if configuration * of direction is equivalent */ - if (mapToAddIter->second.direction != gpioMapIter->second.direction){ - sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict " - << "for GPIO " << mapToAddIter->first << std::endl; - return RETURN_OK; + if (gpioConfig.second.direction != gpioMapIter->second.direction){ + sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict for GPIO " << + gpioConfig.first << std::endl; + return RETURN_FAILED; } /* Remove element from map to add because a entry for this GPIO * already exists */ - mapToAdd.erase(mapToAddIter); + mapToAdd.erase(gpioConfig.first); } } return RETURN_OK; diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index f91a35ca..6f210458 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -23,16 +23,14 @@ public: LinuxLibgpioIF(object_id_t objectId); virtual ~LinuxLibgpioIF(); - ReturnValue_t initialize(CookieIF * cookie) override; + ReturnValue_t initialize(CookieIF* gpioCookie) override; ReturnValue_t pullHigh(gpioId_t gpioId) override; ReturnValue_t pullLow(gpioId_t gpioId) override; ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override; private: - - /*Holds the information and configuration of all used GPIOs */ + /* Holds the information and configuration of all used GPIOs */ GpioMap gpioMap; - GpioMapIter gpioMapIter; /** * @brief This functions drives line of a GPIO specified by the GPIO ID. @@ -52,12 +50,12 @@ private: * * @return RETURN_OK if successful, otherwise RETURN_FAILED */ - ReturnValue_t checkForConflicts(GpioMap mapToAdd); + ReturnValue_t checkForConflicts(GpioMap& mapToAdd); /** * @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd. */ - ReturnValue_t configureGpios(GpioMap* mapToAdd); + ReturnValue_t configureGpios(GpioMap& mapToAdd); }; #endif /* BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_ */ From 41b70efcb90fa787a6382dabfd8d96385b2fa9a6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:30:12 +0100 Subject: [PATCH 03/51] moved heater handler --- bsp_q7s/CMakeLists.txt | 1 + bsp_q7s/ObjectFactory.cpp | 18 +++++++++--------- bsp_q7s/devices/CMakeLists.txt | 7 +++++++ {mission => bsp_q7s}/devices/HeaterHandler.cpp | 13 +++++++------ {mission => bsp_q7s}/devices/HeaterHandler.h | 2 +- mission/devices/CMakeLists.txt | 1 - 6 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 bsp_q7s/devices/CMakeLists.txt rename {mission => bsp_q7s}/devices/HeaterHandler.cpp (97%) rename {mission => bsp_q7s}/devices/HeaterHandler.h (99%) diff --git a/bsp_q7s/CMakeLists.txt b/bsp_q7s/CMakeLists.txt index 3d3a1c91..7b985558 100644 --- a/bsp_q7s/CMakeLists.txt +++ b/bsp_q7s/CMakeLists.txt @@ -6,6 +6,7 @@ target_sources(${TARGET_NAME} PUBLIC add_subdirectory(boardconfig) add_subdirectory(comIF) +add_subdirectory(devices) add_subdirectory(boardtest) diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index a4503981..aed9e23e 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -4,15 +4,9 @@ #include #include #include +#include -#include -#include -#include -#include -#include -#include - -#include +#include #include #include @@ -21,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -33,6 +26,13 @@ #include #include +#include +#include +#include +#include +#include +#include + #if TEST_LIBGPIOD == 1 #include "LibgpiodTest.h" #endif diff --git a/bsp_q7s/devices/CMakeLists.txt b/bsp_q7s/devices/CMakeLists.txt new file mode 100644 index 00000000..14eae324 --- /dev/null +++ b/bsp_q7s/devices/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${TARGET_NAME} PRIVATE + HeaterHandler.cpp +) + + + + diff --git a/mission/devices/HeaterHandler.cpp b/bsp_q7s/devices/HeaterHandler.cpp similarity index 97% rename from mission/devices/HeaterHandler.cpp rename to bsp_q7s/devices/HeaterHandler.cpp index a810e2a6..759c6d64 100644 --- a/mission/devices/HeaterHandler.cpp +++ b/bsp_q7s/devices/HeaterHandler.cpp @@ -1,15 +1,16 @@ -#include +#include "HeaterHandler.h" + #include #include #include HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, uint8_t mainLineSwitch_) : - SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), mainLineSwitcherObjectId( - mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), actionHelper(this, - nullptr) { - commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, - MessageQueueMessage::MAX_MESSAGE_SIZE); + SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), + mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), + actionHelper(this, nullptr) { + commandQueue = QueueFactory::instance()->createMessageQueue( + cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); } HeaterHandler::~HeaterHandler() { diff --git a/mission/devices/HeaterHandler.h b/bsp_q7s/devices/HeaterHandler.h similarity index 99% rename from mission/devices/HeaterHandler.h rename to bsp_q7s/devices/HeaterHandler.h index 4c37c30f..5406df8d 100644 --- a/mission/devices/HeaterHandler.h +++ b/bsp_q7s/devices/HeaterHandler.h @@ -117,7 +117,7 @@ private: CookieIF * gpioCookie; - GpioIF* gpioInterface; + GpioIF* gpioInterface = nullptr; /** Queue to receive messages from other objects. */ MessageQueueIF* commandQueue = nullptr; diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 9a2920d5..a8205276 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -10,7 +10,6 @@ target_sources(${TARGET_NAME} PUBLIC PDU1Handler.cpp PDU2Handler.cpp ACUHandler.cpp - HeaterHandler.cpp ) From 5c9b5627c6e318b52a80576c04548bddb5b5aa13 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:39:50 +0100 Subject: [PATCH 04/51] corrected include guards, changed GpioIF prototype --- bsp_q7s/devices/HeaterHandler.cpp | 3 +- linux/csp/CspComIF.h | 6 ++-- linux/csp/CspCookie.h | 6 ++-- linux/gpio/GpioCookie.h | 46 +++---------------------------- linux/gpio/GpioIF.h | 13 +++++---- linux/gpio/LinuxLibgpioIF.cpp | 16 ++++------- linux/gpio/LinuxLibgpioIF.h | 10 +++---- linux/gpio/gpioDefinitions.h | 46 +++++++++++++++++++++++++++++++ linux/i2c/I2cComIF.h | 6 ++-- linux/i2c/I2cCookie.h | 6 ++-- 10 files changed, 81 insertions(+), 77 deletions(-) create mode 100644 linux/gpio/gpioDefinitions.h diff --git a/bsp_q7s/devices/HeaterHandler.cpp b/bsp_q7s/devices/HeaterHandler.cpp index 759c6d64..eeda9a89 100644 --- a/bsp_q7s/devices/HeaterHandler.cpp +++ b/bsp_q7s/devices/HeaterHandler.cpp @@ -3,6 +3,7 @@ #include #include #include +#include HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, uint8_t mainLineSwitch_) : @@ -43,7 +44,7 @@ ReturnValue_t HeaterHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - result = gpioInterface->initialize(gpioCookie); + result = gpioInterface->initialize(dynamic_cast(gpioCookie)); if (result != RETURN_OK) { sif::error << "HeaterHandler::initialize: Failed to initialize Gpio interface" << std::endl; return ObjectManagerIF::CHILD_INIT_FAILED; diff --git a/linux/csp/CspComIF.h b/linux/csp/CspComIF.h index 78f5158f..5120f232 100644 --- a/linux/csp/CspComIF.h +++ b/linux/csp/CspComIF.h @@ -1,5 +1,5 @@ -#ifndef BSP_LINUX_COMIF_COOKIES_CSPCOMIF_H_ -#define BSP_LINUX_COMIF_COOKIES_CSPCOMIF_H_ +#ifndef LINUX_CSP_CSPCOMIF_H_ +#define LINUX_CSP_CSPCOMIF_H_ #include #include @@ -86,4 +86,4 @@ private: void initiatePingRequest(uint8_t cspAddress, uint16_t querySize); }; -#endif /* BSP_LINUX_COMIF_COOKIES_CSPCOMIF_H_ */ +#endif /* LINUX_CSP_CSPCOMIF_H_ */ diff --git a/linux/csp/CspCookie.h b/linux/csp/CspCookie.h index e877761d..4514c257 100644 --- a/linux/csp/CspCookie.h +++ b/linux/csp/CspCookie.h @@ -1,5 +1,5 @@ -#ifndef BSP_Q7S_COMIF_COOKIES_CSPCOOKIE_H_ -#define BSP_Q7S_COMIF_COOKIES_CSPCOOKIE_H_ +#ifndef LINUX_CSP_CSPCOOKIE_H_ +#define LINUX_CSP_CSPCOOKIE_H_ #include #include @@ -24,4 +24,4 @@ private: uint8_t cspAddress; }; -#endif /* BSP_Q7S_COMIF_COOKIES_CSPCOOKIE_H_ */ +#endif /* LINUX_CSP_CSPCOOKIE_H_ */ diff --git a/linux/gpio/GpioCookie.h b/linux/gpio/GpioCookie.h index 5e4a7b1d..05e80a2e 100644 --- a/linux/gpio/GpioCookie.h +++ b/linux/gpio/GpioCookie.h @@ -1,48 +1,10 @@ -#ifndef SAM9G20_COMIF_COOKIES_GPIO_COOKIE_H_ -#define SAM9G20_COMIF_COOKIES_GPIO_COOKIE_H_ +#ifndef LINUX_GPIO_GPIOCOOKIE_H_ +#define LINUX_GPIO_GPIOCOOKIE_H_ #include "GpioIF.h" +#include "gpioDefinitions.h" #include #include -#include -#include - -namespace gpio { -enum Direction { - IN = 0, - OUT = 1 -}; -} - -/** - * @brief Struct containing information about the GPIO to use. This is - * required by the libgpiod to access and drive a GPIO. - * @param chipname String of the chipname specifying the group which contains the GPIO to - * access. E.g. gpiochip0. To detect names of GPIO groups run gpiodetect on - * the linux command line. - * @param lineNum The offset of the GPIO within the GPIO group. - * @param consumer Name of the consumer. Simply a description of the GPIO configuration. - * @param direction Specifies whether the GPIO should be used as in- or output. - * @param initValue Defines the initial state of the GPIO when configured as output. - * Only required for output GPIOs. - * @param lineHandle The handle returned by gpiod_chip_get_line will be later written to this - * pointer. - */ -typedef struct GpioConfig { - GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, - gpio::Direction direction_, int initValue_): - chipname(chipname_), lineNum(lineNum_), consumer(consumer_), - direction(direction_), initValue(initValue_) {} - std::string chipname; - int lineNum; - std::string consumer; - gpio::Direction direction; - int initValue; - struct gpiod_line* lineHandle = nullptr; -} GpioConfig_t; - -using GpioMap = std::unordered_map; -using GpioMapIter = GpioMap::iterator; /** * @brief Cookie for the GpioIF. Allows the GpioIF to determine which @@ -74,4 +36,4 @@ private: GpioMap gpioMap; }; -#endif +#endif /* LINUX_GPIO_GPIOCOOKIE_H_ */ diff --git a/linux/gpio/GpioIF.h b/linux/gpio/GpioIF.h index 8d36a1b7..65b82573 100644 --- a/linux/gpio/GpioIF.h +++ b/linux/gpio/GpioIF.h @@ -1,10 +1,11 @@ -#ifndef BSP_Q7S_GPIO_GPIOIF_H_ -#define BSP_Q7S_GPIO_GPIOIF_H_ +#ifndef LINUX_GPIO_GPIOIF_H_ +#define LINUX_GPIO_GPIOIF_H_ +#include "gpioDefinitions.h" #include #include -typedef uint16_t gpioId_t; +class GpioCookie; /** * @brief This class defines the interface for objects requiring the control @@ -17,11 +18,11 @@ public: virtual ~GpioIF() {}; /** - * @brief Called by the GPIO using object. + * @brief Called by the GPIO using object. * @param cookie Cookie specifying informations of the GPIOs required * by a object. */ - virtual ReturnValue_t initialize(CookieIF* cookie) = 0; + virtual ReturnValue_t initialize(GpioCookie* cookie) = 0; /** * @brief By implementing this function a child must provide the @@ -49,4 +50,4 @@ public: virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0; }; -#endif /* BSP_Q7S_GPIO_GPIOIF_H_ */ +#endif /* LINUX_GPIO_GPIOIF_H_ */ diff --git a/linux/gpio/LinuxLibgpioIF.cpp b/linux/gpio/LinuxLibgpioIF.cpp index da235716..daaff8ba 100644 --- a/linux/gpio/LinuxLibgpioIF.cpp +++ b/linux/gpio/LinuxLibgpioIF.cpp @@ -1,4 +1,6 @@ #include "LinuxLibgpioIF.h" +#include "GpioCookie.h" + #include #include @@ -11,22 +13,14 @@ LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) { LinuxLibgpioIF::~LinuxLibgpioIF() { } -ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){ +ReturnValue_t LinuxLibgpioIF::initialize(GpioCookie* gpioCookie){ ReturnValue_t result; - GpioMap mapToAdd; - - if(cookie == nullptr) { + if(gpioCookie == nullptr) { sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl; return RETURN_FAILED; } - GpioCookie* gpioCookie = dynamic_cast(cookie); - if(gpioCookie == nullptr) { - sif::error << "LinuxLibgpioIF: Invalid Gpio Cookie!" - << std::endl; - return RETURN_FAILED; - } - mapToAdd = gpioCookie->getGpioMap(); + GpioMap mapToAdd = gpioCookie->getGpioMap(); result = checkForConflicts(mapToAdd); if (result != RETURN_OK){ diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index 6f210458..4e9130b9 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -1,11 +1,11 @@ -#ifndef BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_ -#define BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_ +#ifndef LINUX_GPIO_LINUXLIBGPIOIF_H_ +#define LINUX_GPIO_LINUXLIBGPIOIF_H_ #include -#include #include #include +class GpioCookie; /** * @brief This class implements the GpioIF for a linux based system. The * implementation is based on the libgpiod lib which requires linux 4.8 @@ -23,7 +23,7 @@ public: LinuxLibgpioIF(object_id_t objectId); virtual ~LinuxLibgpioIF(); - ReturnValue_t initialize(CookieIF* gpioCookie) override; + ReturnValue_t initialize(GpioCookie* gpioCookie) override; ReturnValue_t pullHigh(gpioId_t gpioId) override; ReturnValue_t pullLow(gpioId_t gpioId) override; ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override; @@ -58,4 +58,4 @@ private: ReturnValue_t configureGpios(GpioMap& mapToAdd); }; -#endif /* BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_ */ +#endif /* LINUX_GPIO_LINUXLIBGPIOIF_H_ */ diff --git a/linux/gpio/gpioDefinitions.h b/linux/gpio/gpioDefinitions.h new file mode 100644 index 00000000..bbc599ee --- /dev/null +++ b/linux/gpio/gpioDefinitions.h @@ -0,0 +1,46 @@ +#ifndef LINUX_GPIO_GPIODEFINITIONS_H_ +#define LINUX_GPIO_GPIODEFINITIONS_H_ + +#include +#include + +using gpioId_t = uint16_t; + +namespace gpio { +enum Direction { + IN = 0, + OUT = 1 +}; +} + +/** + * @brief Struct containing information about the GPIO to use. This is + * required by the libgpiod to access and drive a GPIO. + * @param chipname String of the chipname specifying the group which contains the GPIO to + * access. E.g. gpiochip0. To detect names of GPIO groups run gpiodetect on + * the linux command line. + * @param lineNum The offset of the GPIO within the GPIO group. + * @param consumer Name of the consumer. Simply a description of the GPIO configuration. + * @param direction Specifies whether the GPIO should be used as in- or output. + * @param initValue Defines the initial state of the GPIO when configured as output. + * Only required for output GPIOs. + * @param lineHandle The handle returned by gpiod_chip_get_line will be later written to this + * pointer. + */ +typedef struct GpioConfig { + GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, + gpio::Direction direction_, int initValue_): + chipname(chipname_), lineNum(lineNum_), consumer(consumer_), + direction(direction_), initValue(initValue_) {} + std::string chipname; + int lineNum; + std::string consumer; + gpio::Direction direction; + int initValue; + struct gpiod_line* lineHandle = nullptr; +} GpioConfig_t; + +using GpioMap = std::unordered_map; +using GpioMapIter = GpioMap::iterator; + +#endif /* LINUX_GPIO_GPIODEFINITIONS_H_ */ diff --git a/linux/i2c/I2cComIF.h b/linux/i2c/I2cComIF.h index 5e75a280..f5d07ac1 100644 --- a/linux/i2c/I2cComIF.h +++ b/linux/i2c/I2cComIF.h @@ -1,5 +1,5 @@ -#ifndef BSP_Q7S_COMIF_I2COMIF_H_ -#define BSP_Q7S_COMIF_I2COMIF_H_ +#ifndef LINUX_I2C_I2COMIF_H_ +#define LINUX_I2C_I2COMIF_H_ #include "I2cCookie.h" #include @@ -56,4 +56,4 @@ private: address_t i2cAddress, int* fileDescriptor); }; -#endif /* BSP_Q7S_COMIF_I2COMIF_H_ */ +#endif /* LINUX_I2C_I2COMIF_H_ */ diff --git a/linux/i2c/I2cCookie.h b/linux/i2c/I2cCookie.h index f03d6290..c924eb4e 100644 --- a/linux/i2c/I2cCookie.h +++ b/linux/i2c/I2cCookie.h @@ -1,5 +1,5 @@ -#ifndef SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_ -#define SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_ +#ifndef LINUX_I2C_I2CCOOKIE_H_ +#define LINUX_I2C_I2CCOOKIE_H_ #include #include @@ -34,4 +34,4 @@ private: std::string deviceFile; }; -#endif +#endif /* LINUX_I2C_I2CCOOKIE_H_ */ From cc9bb7a2c543691b471183a585d85beec3aacccd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:45:31 +0100 Subject: [PATCH 05/51] simplified i2c code --- linux/gpio/LinuxLibgpioIF.h | 1 + linux/i2c/I2cComIF.cpp | 285 ++++++++++++++++++------------------ 2 files changed, 140 insertions(+), 146 deletions(-) diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index 4e9130b9..f8a5e176 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -6,6 +6,7 @@ #include class GpioCookie; + /** * @brief This class implements the GpioIF for a linux based system. The * implementation is based on the libgpiod lib which requires linux 4.8 diff --git a/linux/i2c/I2cComIF.cpp b/linux/i2c/I2cComIF.cpp index 2f1d710a..ef77baa1 100644 --- a/linux/i2c/I2cComIF.cpp +++ b/linux/i2c/I2cComIF.cpp @@ -14,191 +14,184 @@ I2cComIF::I2cComIF(object_id_t objectId): SystemObject(objectId){ I2cComIF::~I2cComIF() {} -ReturnValue_t I2cComIF::initializeInterface(CookieIF * cookie) { +ReturnValue_t I2cComIF::initializeInterface(CookieIF* cookie) { - address_t i2cAddress; - std::string deviceFile; + address_t i2cAddress; + std::string deviceFile; - if(cookie == nullptr) { - return NULLPOINTER; - } - I2cCookie* i2cCookie = dynamic_cast(cookie); - if(i2cCookie == nullptr) { - sif::error << "I2cComIF: Invalid I2C Cookie!" - << std::endl; - return NULLPOINTER; - } + if(cookie == nullptr) { + sif::error << "I2cComIF::initializeInterface: Invalid cookie!" << std::endl; + return NULLPOINTER; + } + I2cCookie* i2cCookie = dynamic_cast(cookie); + if(i2cCookie == nullptr) { + sif::error << "I2cComIF::initializeInterface: Invalid I2C cookie!" << std::endl; + return NULLPOINTER; + } - i2cAddress = i2cCookie->getAddress(); + i2cAddress = i2cCookie->getAddress(); - i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); - if(i2cDeviceMapIter == i2cDeviceMap.end()) { - size_t maxReplyLen = i2cCookie->getMaxReplyLen(); - I2cInstance_t i2cInstance = {std::vector(maxReplyLen), 0}; - std::pair status = i2cDeviceMap.emplace(i2cAddress, i2cInstance); - if (status.second == false) { - sif::error << "I2cComIF::initializeInterface: Failed to insert " - << "device with address " << i2cAddress << "to I2C device " - << "map" << std::endl; - return HasReturnvaluesIF::RETURN_OK; - } - } - else { - sif::error << "I2cComIF: Device with address " << i2cAddress - << "already in use" << std::endl; - } + i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); + if(i2cDeviceMapIter == i2cDeviceMap.end()) { + size_t maxReplyLen = i2cCookie->getMaxReplyLen(); + I2cInstance_t i2cInstance = {std::vector(maxReplyLen), 0}; + auto statusPair = i2cDeviceMap.emplace(i2cAddress, i2cInstance); + if (not statusPair.second) { + sif::error << "I2cComIF::initializeInterface: Failed to insert device with address " << + i2cAddress << "to I2C device " << "map" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; + } - i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); - if(i2cDeviceMapIter == i2cDeviceMap.end()) { - sif::error << "Failure" << std::endl; - } - - return HasReturnvaluesIF::RETURN_OK; + sif::error << "I2cComIF::initializeInterface: Device with address " << i2cAddress << + "already in use" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; } ReturnValue_t I2cComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) { - ReturnValue_t result; - int fd; - std::string deviceFile; + ReturnValue_t result; + int fd; + std::string deviceFile; - if(sendData == nullptr) { - sif::error << "I2cComIF::sendMessage: Send Data is nullptr" - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } + if(sendData == nullptr) { + sif::error << "I2cComIF::sendMessage: Send Data is nullptr" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } - if(sendLen == 0) { - return HasReturnvaluesIF::RETURN_OK; - } + if(sendLen == 0) { + return HasReturnvaluesIF::RETURN_OK; + } - I2cCookie* i2cCookie = dynamic_cast(cookie); - if(i2cCookie == nullptr) { - sif::error << "I2cComIF::sendMessasge: Invalid I2C Cookie!" - << std::endl; - return NULLPOINTER; - } + I2cCookie* i2cCookie = dynamic_cast(cookie); + if(i2cCookie == nullptr) { + sif::error << "I2cComIF::sendMessasge: Invalid I2C Cookie!" + << std::endl; + return NULLPOINTER; + } - address_t i2cAddress = i2cCookie->getAddress(); - i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); - if (i2cDeviceMapIter == i2cDeviceMap.end()) { - sif::error << "I2cComIF::sendMessage: i2cAddress of Cookie not " - << "registered in i2cDeviceMap" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } + address_t i2cAddress = i2cCookie->getAddress(); + i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); + if (i2cDeviceMapIter == i2cDeviceMap.end()) { + sif::error << "I2cComIF::sendMessage: i2cAddress of Cookie not " + << "registered in i2cDeviceMap" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } - deviceFile = i2cCookie->getDeviceFile(); - result = openDevice(deviceFile, i2cAddress, &fd); - if (result != HasReturnvaluesIF::RETURN_OK){ - return result; - } + deviceFile = i2cCookie->getDeviceFile(); + result = openDevice(deviceFile, i2cAddress, &fd); + if (result != HasReturnvaluesIF::RETURN_OK){ + return result; + } - if (write(fd, sendData, sendLen) != (int)sendLen) { - sif::error << "I2cComIF::sendMessage: Failed to send data to I2C " - "device with error code " << errno << ". Error description: " - << strerror(errno) << std::endl; - close(fd); - return HasReturnvaluesIF::RETURN_FAILED; - } - close(fd); - return HasReturnvaluesIF::RETURN_OK; + if (write(fd, sendData, sendLen) != (int)sendLen) { + sif::error << "I2cComIF::sendMessage: Failed to send data to I2C " + "device with error code " << errno << ". Error description: " + << strerror(errno) << std::endl; + close(fd); + return HasReturnvaluesIF::RETURN_FAILED; + } + close(fd); + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t I2cComIF::getSendSuccess(CookieIF *cookie) { - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF *cookie, - size_t requestLen) { + size_t requestLen) { - ReturnValue_t result; - int fd; - std::string deviceFile; + ReturnValue_t result; + int fd; + std::string deviceFile; - if (requestLen == 0) { - return HasReturnvaluesIF::RETURN_OK; - } + if (requestLen == 0) { + return HasReturnvaluesIF::RETURN_OK; + } - I2cCookie* i2cCookie = dynamic_cast(cookie); - if(i2cCookie == nullptr) { - sif::error << "I2cComIF::requestReceiveMessage: Invalid I2C Cookie!" - << std::endl; - i2cDeviceMapIter->second.replyLen = 0; - return NULLPOINTER; - } + I2cCookie* i2cCookie = dynamic_cast(cookie); + if(i2cCookie == nullptr) { + sif::error << "I2cComIF::requestReceiveMessage: Invalid I2C Cookie!" + << std::endl; + i2cDeviceMapIter->second.replyLen = 0; + return NULLPOINTER; + } - address_t i2cAddress = i2cCookie->getAddress(); - i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); - if (i2cDeviceMapIter == i2cDeviceMap.end()) { - sif::error << "I2cComIF::requestReceiveMessage: i2cAddress of Cookie not " - << "registered in i2cDeviceMap" << std::endl; - i2cDeviceMapIter->second.replyLen = 0; - return HasReturnvaluesIF::RETURN_FAILED; - } + address_t i2cAddress = i2cCookie->getAddress(); + i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); + if (i2cDeviceMapIter == i2cDeviceMap.end()) { + sif::error << "I2cComIF::requestReceiveMessage: i2cAddress of Cookie not " + << "registered in i2cDeviceMap" << std::endl; + i2cDeviceMapIter->second.replyLen = 0; + return HasReturnvaluesIF::RETURN_FAILED; + } - deviceFile = i2cCookie->getDeviceFile(); - result = openDevice(deviceFile, i2cAddress, &fd); - if (result != HasReturnvaluesIF::RETURN_OK){ - i2cDeviceMapIter->second.replyLen = 0; - return result; - } + deviceFile = i2cCookie->getDeviceFile(); + result = openDevice(deviceFile, i2cAddress, &fd); + if (result != HasReturnvaluesIF::RETURN_OK){ + i2cDeviceMapIter->second.replyLen = 0; + return result; + } - uint8_t* replyBuffer = i2cDeviceMapIter->second.replyBuffer.data(); + uint8_t* replyBuffer = i2cDeviceMapIter->second.replyBuffer.data(); - if (read(fd, replyBuffer, requestLen) != (int)requestLen) { - sif::error << "I2cComIF::requestReceiveMessage: Reading from I2C " - << "device failed with error code " << errno <<". Description" - << " of error: " << strerror(errno) << std::endl; - close(fd); - i2cDeviceMapIter->second.replyLen = 0; - return HasReturnvaluesIF::RETURN_FAILED; - } + if (read(fd, replyBuffer, requestLen) != (int)requestLen) { + sif::error << "I2cComIF::requestReceiveMessage: Reading from I2C " + << "device failed with error code " << errno <<". Description" + << " of error: " << strerror(errno) << std::endl; + close(fd); + i2cDeviceMapIter->second.replyLen = 0; + return HasReturnvaluesIF::RETURN_FAILED; + } - i2cDeviceMapIter->second.replyLen = requestLen; + i2cDeviceMapIter->second.replyLen = requestLen; - close(fd); + close(fd); - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t I2cComIF::readReceivedMessage(CookieIF *cookie, - uint8_t **buffer, size_t* size) { - I2cCookie* i2cCookie = dynamic_cast(cookie); - if(i2cCookie == nullptr) { - sif::error << "I2cComIF::readReceivedMessage: Invalid I2C Cookie!" - << std::endl; - return NULLPOINTER; - } + uint8_t **buffer, size_t* size) { + I2cCookie* i2cCookie = dynamic_cast(cookie); + if(i2cCookie == nullptr) { + sif::error << "I2cComIF::readReceivedMessage: Invalid I2C Cookie!" + << std::endl; + return NULLPOINTER; + } - address_t i2cAddress = i2cCookie->getAddress(); - i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); - if (i2cDeviceMapIter == i2cDeviceMap.end()) { - sif::error << "I2cComIF::readReceivedMessage: i2cAddress of Cookie not " - << "found in i2cDeviceMap" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - *buffer = i2cDeviceMapIter->second.replyBuffer.data(); - *size = i2cDeviceMapIter->second.replyLen; + address_t i2cAddress = i2cCookie->getAddress(); + i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); + if (i2cDeviceMapIter == i2cDeviceMap.end()) { + sif::error << "I2cComIF::readReceivedMessage: i2cAddress of Cookie not " + << "found in i2cDeviceMap" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + *buffer = i2cDeviceMapIter->second.replyBuffer.data(); + *size = i2cDeviceMapIter->second.replyLen; - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t I2cComIF::openDevice(std::string deviceFile, - address_t i2cAddress, int* fileDescriptor) { - *fileDescriptor = open(deviceFile.c_str(), O_RDWR); - if (*fileDescriptor < 0) { - sif::error << "I2cComIF: Opening i2c device failed with error code " - << errno << ". Error description: " << strerror(errno) - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } + address_t i2cAddress, int* fileDescriptor) { + *fileDescriptor = open(deviceFile.c_str(), O_RDWR); + if (*fileDescriptor < 0) { + sif::error << "I2cComIF: Opening i2c device failed with error code " + << errno << ". Error description: " << strerror(errno) + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } - if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) { - sif::error << "I2cComIF: Specifying target device failed with error " - << "code " << errno << ". Error description " - << strerror(errno) << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; + if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) { + sif::error << "I2cComIF: Specifying target device failed with error " + << "code " << errno << ". Error description " + << strerror(errno) << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; } From 24a251cd1cd196d3629a36b8ad337283321cdae4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:52:40 +0100 Subject: [PATCH 06/51] added back member iter --- linux/gpio/LinuxLibgpioIF.cpp | 8 ++------ linux/gpio/LinuxLibgpioIF.h | 1 + 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/linux/gpio/LinuxLibgpioIF.cpp b/linux/gpio/LinuxLibgpioIF.cpp index daaff8ba..1b152a0f 100644 --- a/linux/gpio/LinuxLibgpioIF.cpp +++ b/linux/gpio/LinuxLibgpioIF.cpp @@ -39,7 +39,6 @@ ReturnValue_t LinuxLibgpioIF::initialize(GpioCookie* gpioCookie){ } ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { - //GpioMapIter mapToAddIter; std::string chipname; unsigned int lineNum; struct gpiod_chip *chip; @@ -48,9 +47,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { struct gpiod_line *lineHandle; int result; - //mapToAddIter = mapToAdd->begin(); for(auto& gpioConfig: mapToAdd) { - //for (; mapToAddIter != mapToAdd->end(); mapToAddIter++) { chipname = gpioConfig.second.chipname; chip = gpiod_chip_open_by_name(chipname.c_str()); if (!chip) { @@ -119,7 +116,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, int result; struct gpiod_line *lineHandle; - auto gpioMapIter = gpioMap.find(gpioId); + gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()){ sif::debug << "LinuxLibgpioIF::driveGpio: Unknown gpio id " << gpioId << std::endl; return RETURN_FAILED; @@ -139,7 +136,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { struct gpiod_line *lineHandle; - auto gpioMapIter = gpioMap.find(gpioId); + gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()){ sif::debug << "LinuxLibgpioIF::readGpio: Unknown gpio id " << gpioId << std::endl; return RETURN_FAILED; @@ -153,7 +150,6 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ gpioId_t gpioId; - auto gpioMapIter = gpioMap.begin(); for(auto& gpioConfig: mapToAdd) { gpioId = gpioConfig.first; /* Cross check with private map */ diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index f8a5e176..6a412733 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -32,6 +32,7 @@ public: private: /* Holds the information and configuration of all used GPIOs */ GpioMap gpioMap; + GpioMapIter gpioMapIter; /** * @brief This functions drives line of a GPIO specified by the GPIO ID. From 171a95328398f9488345c8d56d6bea55d7e0d9f8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:53:11 +0100 Subject: [PATCH 07/51] removed newlines --- bsp_q7s/devices/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bsp_q7s/devices/CMakeLists.txt b/bsp_q7s/devices/CMakeLists.txt index 14eae324..c720706a 100644 --- a/bsp_q7s/devices/CMakeLists.txt +++ b/bsp_q7s/devices/CMakeLists.txt @@ -1,7 +1,3 @@ target_sources(${TARGET_NAME} PRIVATE HeaterHandler.cpp ) - - - - From 7c1c2b46af00ab5bb3e97eeb5b3e824b690b4156 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 19:06:26 +0100 Subject: [PATCH 08/51] small form stuff --- linux/i2c/I2cCookie.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/linux/i2c/I2cCookie.cpp b/linux/i2c/I2cCookie.cpp index 7f86bdc3..fe0f3f92 100644 --- a/linux/i2c/I2cCookie.cpp +++ b/linux/i2c/I2cCookie.cpp @@ -2,8 +2,7 @@ I2cCookie::I2cCookie(address_t i2cAddress_, size_t maxReplyLen_, std::string deviceFile_) : - i2cAddress(i2cAddress_), maxReplyLen(maxReplyLen_), deviceFile( - deviceFile_) { + i2cAddress(i2cAddress_), maxReplyLen(maxReplyLen_), deviceFile(deviceFile_) { } address_t I2cCookie::getAddress() const { From 571606c251249a8f4005cc0ab82f414e53ac898f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 19:22:58 +0100 Subject: [PATCH 09/51] new linux boardtest folder --- bsp_q7s/ObjectFactory.cpp | 2 +- bsp_q7s/boardtest/CMakeLists.txt | 1 - linux/CMakeLists.txt | 1 + linux/boardtest/CMakeLists.txt | 10 ++++++++++ linux/boardtest/I2cTestClass.cpp | 8 ++++++++ linux/boardtest/I2cTestClass.h | 17 +++++++++++++++++ {bsp_q7s => linux}/boardtest/LibgpiodTest.cpp | 0 {bsp_q7s => linux}/boardtest/LibgpiodTest.h | 0 linux/boardtest/SpiTestClass.cpp | 8 ++++++++ linux/boardtest/SpiTestClass.h | 18 ++++++++++++++++++ linux/boardtest/UartTestClass.cpp | 8 ++++++++ linux/boardtest/UartTestClass.h | 15 +++++++++++++++ 12 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 linux/boardtest/CMakeLists.txt create mode 100644 linux/boardtest/I2cTestClass.cpp create mode 100644 linux/boardtest/I2cTestClass.h rename {bsp_q7s => linux}/boardtest/LibgpiodTest.cpp (100%) rename {bsp_q7s => linux}/boardtest/LibgpiodTest.h (100%) create mode 100644 linux/boardtest/SpiTestClass.cpp create mode 100644 linux/boardtest/SpiTestClass.h create mode 100644 linux/boardtest/UartTestClass.cpp create mode 100644 linux/boardtest/UartTestClass.h diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index aed9e23e..72e11d44 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -34,7 +34,7 @@ #include #if TEST_LIBGPIOD == 1 -#include "LibgpiodTest.h" +#include #endif void Factory::setStaticFrameworkObjectIds() { diff --git a/bsp_q7s/boardtest/CMakeLists.txt b/bsp_q7s/boardtest/CMakeLists.txt index 7e59ddb9..0599b73f 100644 --- a/bsp_q7s/boardtest/CMakeLists.txt +++ b/bsp_q7s/boardtest/CMakeLists.txt @@ -1,5 +1,4 @@ target_sources(${TARGET_NAME} PRIVATE - LibgpiodTest.cpp ) diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 9a25fdff..9101e15d 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -2,4 +2,5 @@ add_subdirectory(gpio) add_subdirectory(i2c) add_subdirectory(csp) add_subdirectory(spi) +add_subdirectory(boardtest) diff --git a/linux/boardtest/CMakeLists.txt b/linux/boardtest/CMakeLists.txt new file mode 100644 index 00000000..0fa4e322 --- /dev/null +++ b/linux/boardtest/CMakeLists.txt @@ -0,0 +1,10 @@ +target_sources(${TARGET_NAME} PRIVATE + LibgpiodTest.cpp + I2cTestClass.cpp + SpiTestClass.cpp + UartTestClass.cpp +) + + + + diff --git a/linux/boardtest/I2cTestClass.cpp b/linux/boardtest/I2cTestClass.cpp new file mode 100644 index 00000000..66c16b33 --- /dev/null +++ b/linux/boardtest/I2cTestClass.cpp @@ -0,0 +1,8 @@ +#include + +I2cTestClass::I2cTestClass(object_id_t objectId): TestTask(objectId) { +} + +ReturnValue_t I2cTestClass::performPeriodicAction() { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/linux/boardtest/I2cTestClass.h b/linux/boardtest/I2cTestClass.h new file mode 100644 index 00000000..172a7f71 --- /dev/null +++ b/linux/boardtest/I2cTestClass.h @@ -0,0 +1,17 @@ +#ifndef LINUX_BOARDTEST_I2CTESTCLASS_H_ +#define LINUX_BOARDTEST_I2CTESTCLASS_H_ + +#include + +class I2cTestClass: public TestTask { +public: + I2cTestClass(object_id_t objectId); + + ReturnValue_t performPeriodicAction() override; +private: + +}; + + + +#endif /* LINUX_BOARDTEST_I2CTESTCLASS_H_ */ diff --git a/bsp_q7s/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp similarity index 100% rename from bsp_q7s/boardtest/LibgpiodTest.cpp rename to linux/boardtest/LibgpiodTest.cpp diff --git a/bsp_q7s/boardtest/LibgpiodTest.h b/linux/boardtest/LibgpiodTest.h similarity index 100% rename from bsp_q7s/boardtest/LibgpiodTest.h rename to linux/boardtest/LibgpiodTest.h diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp new file mode 100644 index 00000000..daf38749 --- /dev/null +++ b/linux/boardtest/SpiTestClass.cpp @@ -0,0 +1,8 @@ +#include + +SpiTestClass::SpiTestClass(object_id_t objectId): TestTask(objectId) { +} + +ReturnValue_t SpiTestClass::performPeriodicAction() { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/linux/boardtest/SpiTestClass.h b/linux/boardtest/SpiTestClass.h new file mode 100644 index 00000000..b3f10222 --- /dev/null +++ b/linux/boardtest/SpiTestClass.h @@ -0,0 +1,18 @@ +#ifndef LINUX_BOARDTEST_SPITESTCLASS_H_ +#define LINUX_BOARDTEST_SPITESTCLASS_H_ + +#include + +class SpiTestClass: public TestTask { +public: + SpiTestClass(object_id_t objectId); + + ReturnValue_t performPeriodicAction() override; +private: + +}; + + + + +#endif /* LINUX_BOARDTEST_SPITESTCLASS_H_ */ diff --git a/linux/boardtest/UartTestClass.cpp b/linux/boardtest/UartTestClass.cpp new file mode 100644 index 00000000..dc9f79c3 --- /dev/null +++ b/linux/boardtest/UartTestClass.cpp @@ -0,0 +1,8 @@ +#include + +UartTestClass::UartTestClass(object_id_t objectId): TestTask(objectId) { +} + +ReturnValue_t UartTestClass::performPeriodicAction() { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/linux/boardtest/UartTestClass.h b/linux/boardtest/UartTestClass.h new file mode 100644 index 00000000..406d2af5 --- /dev/null +++ b/linux/boardtest/UartTestClass.h @@ -0,0 +1,15 @@ +#ifndef LINUX_BOARDTEST_UARTTESTCLASS_H_ +#define LINUX_BOARDTEST_UARTTESTCLASS_H_ + +#include + +class UartTestClass: public TestTask { +public: + UartTestClass(object_id_t objectId); + + ReturnValue_t performPeriodicAction() override; +private: + +}; + +#endif /* LINUX_BOARDTEST_UARTTESTCLASS_H_ */ From 97a752120a25045fae38fe6ff7d4602a7e06d75c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 12:36:28 +0100 Subject: [PATCH 10/51] separate folder for RPi builds --- cmake/scripts/RPi/create_cmake_debug_cfg.sh | 4 +++- cmake/scripts/RPi/create_cmake_release_cfg.sh | 4 +++- cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh | 4 +++- cmake/scripts/cmake_build_config.py | 5 +++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cmake/scripts/RPi/create_cmake_debug_cfg.sh b/cmake/scripts/RPi/create_cmake_debug_cfg.sh index deb78243..d0ec5d76 100644 --- a/cmake/scripts/RPi/create_cmake_debug_cfg.sh +++ b/cmake/scripts/RPi/create_cmake_debug_cfg.sh @@ -17,6 +17,7 @@ fi os_fsfw="linux" tgt_bsp="arm/raspberrypi" build_generator="" +build_dir="Debug-RPi" if [ "${OS}" = "Windows_NT" ]; then build_generator="MinGW Makefiles" # Could be other OS but this works for now. @@ -24,4 +25,5 @@ else build_generator="Unix Makefiles" fi -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" +python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ + -l"${build_dir}" diff --git a/cmake/scripts/RPi/create_cmake_release_cfg.sh b/cmake/scripts/RPi/create_cmake_release_cfg.sh index 0e23bee4..4eb9b38a 100644 --- a/cmake/scripts/RPi/create_cmake_release_cfg.sh +++ b/cmake/scripts/RPi/create_cmake_release_cfg.sh @@ -17,6 +17,7 @@ fi os_fsfw="linux" tgt_bsp="arm/raspberrypi" build_generator="" +build_dir="Release-RPi" if [ "${OS}" = "Windows_NT" ]; then build_generator="MinGW Makefiles" # Could be other OS but this works for now. @@ -24,4 +25,5 @@ else build_generator="Unix Makefiles" fi -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" +python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ + -l"${build_dir}" diff --git a/cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh b/cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh index 3e952750..de7651a7 100644 --- a/cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh +++ b/cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh @@ -17,6 +17,7 @@ fi os_fsfw="linux" tgt_bsp="arm/raspberrypi" build_generator="" +build_dir="RelWithDeb-RPi" if [ "${OS}" = "Windows_NT" ]; then build_generator="MinGW Makefiles" # Could be other OS but this works for now. @@ -24,4 +25,5 @@ else build_generator="Unix Makefiles" fi -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "reldeb" -t "${tgt_bsp}" +python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "reldeb" -t "${tgt_bsp}" \ + -l"${build_dir}" diff --git a/cmake/scripts/cmake_build_config.py b/cmake/scripts/cmake_build_config.py index a6388ef8..0e4b6f25 100644 --- a/cmake/scripts/cmake_build_config.py +++ b/cmake/scripts/cmake_build_config.py @@ -61,9 +61,10 @@ def main(): else: cmake_target_cfg_cmd = "" - # TODO: Use builddir if given (need to check whether path is relative or absolute) build_folder = cmake_build_type - + if args.builddir is not None: + build_folder = args.builddir + build_path = source_location + os.path.sep + build_folder if os.path.isdir(build_path): remove_old_dir = input(f"{build_folder} folder already exists. Remove old directory? [y/n]: ") From 7435ce903ad01df4e98a62ed6b9dcd3045d69e9b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 12:40:12 +0100 Subject: [PATCH 11/51] added loopback test mode --- linux/boardtest/LibgpiodTest.cpp | 27 +++++++++++++++++++-------- linux/boardtest/LibgpiodTest.h | 7 +++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index 51f89abe..dbd0947a 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -13,6 +13,7 @@ LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl; } gpioInterface->initialize(gpioCookie); + testCase = TestCases::READ; } LibgpiodTest::~LibgpiodTest() { @@ -22,16 +23,26 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { int gpioState; ReturnValue_t result; - result = gpioInterface->readGpio(gpioIds::Test_ID, &gpioState); - if (result != RETURN_OK) { - sif::debug << "LibgpiodTest::performPeriodicAction: Failed to read gpio " - << std::endl; - return RETURN_FAILED; + switch(testCase) { + case(testCase == TestCases::READ): { + result = gpioInterface->readGpio(gpioIds::Test_ID, &gpioState); + if (result != RETURN_OK) { + sif::debug << "LibgpiodTest::performPeriodicAction: Failed to read gpio " + << std::endl; + return RETURN_FAILED; + } + else { + sif::debug << "LibgpiodTest::performPeriodicAction: MIO 0 state = " << gpioState + << std::endl; + } + break; } - else { - sif::debug << "LibgpiodTest::performPeriodicAction: MIO 0 state = " << gpioState - << std::endl; + case(testCase == TestCases::LOOPBACK): { + } + } + + return RETURN_OK; } diff --git a/linux/boardtest/LibgpiodTest.h b/linux/boardtest/LibgpiodTest.h index 678c06a3..642d4cd7 100644 --- a/linux/boardtest/LibgpiodTest.h +++ b/linux/boardtest/LibgpiodTest.h @@ -12,6 +12,13 @@ */ class LibgpiodTest: public TestTask { public: + enum TestCases { + READ = 0, + LOOPBACK = 1 + }; + + TestCases testCase; + LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie); virtual ~LibgpiodTest(); From b75113b0849f0abc57d68bf56157ccf3da0b4eea Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 12:45:10 +0100 Subject: [PATCH 12/51] updated cmake lists --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22e45134..2cde6b98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,14 @@ if(TGT_BSP) set(ADD_LINUX_FILES TRUE) set(ADD_CSP_LIB TRUE) endif() + + if(${TGT_BSP} MATCHES "arm/raspberrypi") + add_definitions(-DRASPBERRY_PI) + endif() + + if(${TGT_BSP} MATCHES "arm/q7s") + add_definitions(-DXIPHOS_Q7S) + endif() else() # Required by FSFW library set(FSFW_CONFIG_PATH "${BSP_PATH}/fsfwconfig") From 7f969a47d6ef0365185c7a560f55d34f7e6ef2c3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 12:57:41 +0100 Subject: [PATCH 13/51] added link library gpiod --- bsp_rpi/ObjectFactory.cpp | 11 ++++++++++- bsp_rpi/boardconfig/rpi_config.h | 8 ++++++++ fsfwconfig/OBSWConfig.h | 7 +++++-- linux/boardtest/LibgpiodTest.cpp | 4 ++-- linux/gpio/CMakeLists.txt | 4 ++++ 5 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 bsp_rpi/boardconfig/rpi_config.h diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index c90db492..7a7820b8 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -1,17 +1,20 @@ #include "ObjectFactory.h" #include -#include #include #include #include #include +#include #include #include #include #include #include +#include +#include +#include #include #include @@ -45,4 +48,10 @@ void ObjectFactory::produce(){ new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); new SpiTest(objects::SPI_TEST); + new LinuxLibgpioIF(objects::GPIO_IF); + +#if RPI_TEST_GPIO == 1 + GpioCookie* gpioCookie = new GpioCookie(); + new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); +#endif } diff --git a/bsp_rpi/boardconfig/rpi_config.h b/bsp_rpi/boardconfig/rpi_config.h new file mode 100644 index 00000000..7d41e302 --- /dev/null +++ b/bsp_rpi/boardconfig/rpi_config.h @@ -0,0 +1,8 @@ +#ifndef BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ +#define BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ + +#define RPI_TEST_GPIO 1 + + + +#endif /* BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ */ diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index 66eddf12..b429f491 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -6,6 +6,11 @@ #ifndef FSFWCONFIG_OBSWCONFIG_H_ #define FSFWCONFIG_OBSWCONFIG_H_ +#ifdef RASPBERRY_PI +#include +#endif +#include "OBSWVersion.h" + #define TEST_LIBGPIOD 0 /* These defines should be disabled for mission code but are useful for @@ -18,8 +23,6 @@ debugging. */ #define PDU1_DEBUG 0 #define PDU2_DEBUG 0 -#include "OBSWVersion.h" - #ifdef __cplusplus #include "objects/systemObjectList.h" diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index dbd0947a..cc60ce18 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -24,7 +24,7 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { ReturnValue_t result; switch(testCase) { - case(testCase == TestCases::READ): { + case(TestCases::READ): { result = gpioInterface->readGpio(gpioIds::Test_ID, &gpioState); if (result != RETURN_OK) { sif::debug << "LibgpiodTest::performPeriodicAction: Failed to read gpio " @@ -37,7 +37,7 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { } break; } - case(testCase == TestCases::LOOPBACK): { + case(TestCases::LOOPBACK): { } } diff --git a/linux/gpio/CMakeLists.txt b/linux/gpio/CMakeLists.txt index 052173b3..9b20b35e 100644 --- a/linux/gpio/CMakeLists.txt +++ b/linux/gpio/CMakeLists.txt @@ -3,6 +3,10 @@ target_sources(${TARGET_NAME} PUBLIC LinuxLibgpioIF.cpp ) +target_link_libraries(${TARGET_NAME} PUBLIC + gpiod +) + From e581beaffcccb1a36fea245518f016d84ffa4e10 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 12:59:50 +0100 Subject: [PATCH 14/51] heater handler moved --- mission/devices/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 4f45a7e6..aec93c1c 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -10,7 +10,6 @@ target_sources(${TARGET_NAME} PUBLIC PDU1Handler.cpp PDU2Handler.cpp ACUHandler.cpp - HeaterHandler.cpp SolarArrayDeploymentHandler.cpp ) From ca0f50a9877a3634c6937f78bb0193257e914b47 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 13:01:46 +0100 Subject: [PATCH 15/51] explicit cast so it compiles --- mission/devices/SolarArrayDeploymentHandler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 45521800..a78478e5 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -2,6 +2,7 @@ #include #include #include +#include SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_, object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, @@ -38,7 +39,7 @@ ReturnValue_t SolarArrayDeploymentHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - result = gpioInterface->initialize(gpioCookie); + result = gpioInterface->initialize(dynamic_cast(gpioCookie)); if (result != RETURN_OK) { sif::error << "SolarArrayDeploymentHandler::initialize: Failed to initialize Gpio interface" << std::endl; From 219150b8ab94f8eb5d0fa09ed55cac7932177d9d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 14:25:46 +0100 Subject: [PATCH 16/51] bugfix --- bsp_q7s/ObjectFactory.cpp | 1 - bsp_q7s/devices/HeaterHandler.cpp | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index d3078f82..e5a1e039 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/bsp_q7s/devices/HeaterHandler.cpp b/bsp_q7s/devices/HeaterHandler.cpp index eeda9a89..2387ab2a 100644 --- a/bsp_q7s/devices/HeaterHandler.cpp +++ b/bsp_q7s/devices/HeaterHandler.cpp @@ -1,5 +1,4 @@ #include "HeaterHandler.h" - #include #include #include @@ -10,8 +9,8 @@ HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_ SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), actionHelper(this, nullptr) { - commandQueue = QueueFactory::instance()->createMessageQueue( - cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); + commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, + MessageQueueMessage::MAX_MESSAGE_SIZE); } HeaterHandler::~HeaterHandler() { From 430cf229735dcea5b8963dd434595a84a415c0ed Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 17:36:44 +0100 Subject: [PATCH 17/51] added service 20 --- bsp_hosted/InitMission.cpp | 2 + bsp_q7s/InitMission.cpp | 186 +++++++++--------- bsp_q7s/ObjectFactory.cpp | 6 +- bsp_rpi/CMakeLists.txt | 7 +- bsp_rpi/InitMission.cpp | 151 +++++++------- bsp_rpi/ObjectFactory.cpp | 20 +- bsp_rpi/boardconfig/rpi_config.h | 4 +- bsp_rpi/boardtest/CMakeLists.txt | 1 - bsp_rpi/gpio/CMakeLists.txt | 9 + bsp_rpi/gpio/GPIORPi.cpp | 36 ++++ bsp_rpi/gpio/GPIORPi.h | 26 +++ fsfwconfig/OBSWConfig.h | 16 +- fsfwconfig/devices/gpioIds.h | 3 +- linux/boardtest/LibgpiodTest.cpp | 40 +++- linux/boardtest/LibgpiodTest.h | 3 +- linux/gpio/GpioCookie.cpp | 10 +- linux/gpio/GpioCookie.h | 2 +- linux/gpio/GpioIF.h | 1 + linux/gpio/LinuxLibgpioIF.h | 1 + linux/gpio/gpioDefinitions.h | 3 + .../boardtest => misc/archive}/RPiGPIO.cpp | 0 {bsp_rpi/boardtest => misc/archive}/RPiGPIO.h | 0 mission/core/GenericFactory.cpp | 5 +- mission/utility/InitMission.h | 22 +++ 24 files changed, 358 insertions(+), 196 deletions(-) create mode 100644 bsp_rpi/gpio/CMakeLists.txt create mode 100644 bsp_rpi/gpio/GPIORPi.cpp create mode 100644 bsp_rpi/gpio/GPIORPi.h rename {bsp_rpi/boardtest => misc/archive}/RPiGPIO.cpp (100%) rename {bsp_rpi/boardtest => misc/archive}/RPiGPIO.h (100%) create mode 100644 mission/utility/InitMission.h diff --git a/bsp_hosted/InitMission.cpp b/bsp_hosted/InitMission.cpp index 39dcafff..4da13c70 100644 --- a/bsp_hosted/InitMission.cpp +++ b/bsp_hosted/InitMission.cpp @@ -11,6 +11,8 @@ #include #include +#include + #include // This is configured for linux without \cr diff --git a/bsp_q7s/InitMission.cpp b/bsp_q7s/InitMission.cpp index 681d6b48..2930803e 100644 --- a/bsp_q7s/InitMission.cpp +++ b/bsp_q7s/InitMission.cpp @@ -2,6 +2,8 @@ #include "ObjectFactory.h" #include +#include + #include #include #include @@ -13,7 +15,7 @@ #include -// This is configured for linux without \cr +/* This is configured for linux without CR */ #ifdef LINUX ServiceInterfaceStream sif::debug("DEBUG"); ServiceInterfaceStream sif::info("INFO"); @@ -39,144 +41,142 @@ void InitMission::initMission() { initTasks(); } -void InitMission::initTasks(){ +void InitMission::initTasks() { + TaskFactory* factory = TaskFactory::instance(); + if(factory == nullptr) { + /* Should never happen ! */ + return; + } + /* TMTC Distribution */ - PeriodicTaskIF* TmTcDistributor = TaskFactory::instance()-> - createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.2, nullptr); - ReturnValue_t result = TmTcDistributor->addComponent( + PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + ReturnValue_t result = tmTcDistributor->addComponent( objects::CCSDS_PACKET_DISTRIBUTOR); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR); } - result = TmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR); } - result = TmTcDistributor->addComponent(objects::TM_FUNNEL); + result = tmTcDistributor->addComponent(objects::TM_FUNNEL); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Object add component failed" << std::endl; + InitMission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL); } /* UDP bridge */ - PeriodicTaskIF* UdpBridgeTask = TaskFactory::instance()->createPeriodicTask( - "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.2, nullptr); - result = UdpBridgeTask->addComponent(objects::UDP_BRIDGE); + PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( + "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Add component UDP Unix Bridge failed" << std::endl; + InitMission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE); } - PeriodicTaskIF* UdpPollingTask = TaskFactory::instance()-> - createPeriodicTask("UDP_POLLING", 80, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); - result = UdpPollingTask->addComponent(objects::UDP_POLLING_TASK); + PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( + "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); + result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Add component UDP Polling failed" << std::endl; + InitMission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK); } /* PUS Services */ - PeriodicTaskIF* PusVerification = TaskFactory::instance()-> - createPeriodicTask("PUS_VERIF_1", 40, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); - result = PusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + PeriodicTaskIF* pusVerification = factory->createPeriodicTask( + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION); } - PeriodicTaskIF* PusEvents = TaskFactory::instance()-> - createPeriodicTask("PUS_VERIF_1", 60, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); - result = PusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + PeriodicTaskIF* pusEvents = factory->createPeriodicTask( + "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); } - PeriodicTaskIF* PusHighPrio = TaskFactory::instance()-> - createPeriodicTask("PUS_HIGH_PRIO", 50, - PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.200, nullptr); - result = PusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS); } - result = PusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT); } - PeriodicTaskIF* PusMedPrio = TaskFactory::instance()-> - createPeriodicTask("PUS_HIGH_PRIO", 40, - PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.8, nullptr); - result = PusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, nullptr); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT); } - result = PusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); } - PeriodicTaskIF* PusLowPrio = TaskFactory::instance()-> - createPeriodicTask("PUSB", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 1.6, nullptr); - result = PusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, nullptr); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST); } //TODO: Add handling of missed deadlines /* Polling Sequence Table Default */ - FixedTimeslotTaskIF * PollingSequenceTableTaskDefault = - TaskFactory::instance()->createFixedTimeslotTask("PST_TASK_DEFAULT", - 50, PeriodicTaskIF::MINIMUM_STACK_SIZE*4, 3.0, - nullptr); - result = pst::pollingSequenceInitDefault(PollingSequenceTableTaskDefault); + FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask( + "PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, nullptr); + result = pst::pollingSequenceInitDefault(pollingSequenceTableTaskDefault); if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: Creating PST failed!" - << std::endl; + sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; } #if TE0720 == 0 - FixedTimeslotTaskIF* GomSpacePstTask = TaskFactory::instance()-> + FixedTimeslotTaskIF* gomSpacePstTask = factory-> createFixedTimeslotTask("GS_PST_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, nullptr); - result = pst::gomspacePstInit(GomSpacePstTask); + result = pst::gomspacePstInit(gomSpacePstTask); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: GomSpace PST initialization " - << "failed!" << std::endl; + sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl; } #endif + PeriodicTaskIF* testTask = factory->createPeriodicTask( + "GPIOD_TEST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, nullptr); +#if OBSW_ADD_TEST_CODE == 1 + result = testTask->addComponent(objects::TEST_TASK); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + } +#endif /* OBSW_ADD_TEST_CODE == 1 */ #if TE0720 == 1 && TEST_LIBGPIOD == 1 - PeriodicTaskIF* TestTask = TaskFactory::instance()-> - createPeriodicTask("Libgpiod Test Task", 60, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, nullptr); - result = TestTask->addComponent(objects::LIBGPIOD_TEST); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component libgpiod test task object" << std::endl; + result = testTask->addComponent(objects::LIBGPIOD_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); } -#endif +#endif /* TE0720 == 1 && TEST_LIBGPIOD == 1 */ - //Main thread sleep sif::info << "Starting tasks.." << std::endl; - TmTcDistributor->startTask(); - UdpBridgeTask->startTask(); - UdpPollingTask->startTask(); + tmTcDistributor->startTask(); + udpBridgeTask->startTask(); + udpPollingTask->startTask(); #if TE0720 == 0 - GomSpacePstTask->startTask(); + gomSpacePstTask->startTask(); #endif - PollingSequenceTableTaskDefault->startTask(); + pollingSequenceTableTaskDefault->startTask(); - PusVerification->startTask(); - PusEvents->startTask(); - PusHighPrio->startTask(); - PusMedPrio->startTask(); - PusLowPrio->startTask(); + pusVerification->startTask(); + pusEvents->startTask(); + pusHighPrio->startTask(); + pusMedPrio->startTask(); + pusLowPrio->startTask(); -#if TE0720 == 1 && TEST_LIBGPIOD == 1 - TestTask->startTask(); -#endif + testTask->startTask(); sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index e5a1e039..1a54ca34 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -180,14 +180,14 @@ void ObjectFactory::produce(){ GpioConfig_t gpioConfigMio0(std::string("gpiochip0"), 0, std::string("MIO0"), gpio::IN, 0); GpioCookie* gpioCookie = new GpioCookie; - gpioCookie->addGpio(gpioIds::Test_ID, gpioConfigMio0); + gpioCookie->addGpio(gpioIds::TEST_ID_0, gpioConfigMio0); new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); #elif TE0720 == 1 /* Configuration for MIO0 on TE0720-03-1CFA */ GpioConfig_t gpioConfigForDummyHeater(std::string("gpiochip0"), 0, std::string("Heater0"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater); - new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, objects::PCDU_HANDLER, - pcduSwitches::TCS_BOARD_8V_HEATER_IN); + new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, + objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN); #endif } diff --git a/bsp_rpi/CMakeLists.txt b/bsp_rpi/CMakeLists.txt index 281994bf..da35633d 100644 --- a/bsp_rpi/CMakeLists.txt +++ b/bsp_rpi/CMakeLists.txt @@ -6,11 +6,8 @@ target_sources(${TARGET_NAME} PUBLIC add_subdirectory(boardconfig) add_subdirectory(boardtest) - -# wiringPi is deprecated unfortunately.. -#target_link_libraries(${TARGET_NAME} PRIVATE -# wiringPi -#) +add_subdirectory(gpio) + diff --git a/bsp_rpi/InitMission.cpp b/bsp_rpi/InitMission.cpp index 197abcc6..f3dc47ed 100644 --- a/bsp_rpi/InitMission.cpp +++ b/bsp_rpi/InitMission.cpp @@ -1,6 +1,12 @@ #include "InitMission.h" #include "ObjectFactory.h" +#include +#include +#include + +#include + #include #include #include @@ -8,9 +14,6 @@ #include #include #include -#include -#include -#include #include @@ -34,127 +37,129 @@ void InitMission::initMission() { void InitMission::initTasks(){ /* TMTC Distribution */ - PeriodicTaskIF* TmTcDistributor = TaskFactory::instance()-> + PeriodicTaskIF* tmTcDistributor = TaskFactory::instance()-> createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.100, nullptr); - ReturnValue_t result = TmTcDistributor->addComponent( + ReturnValue_t result = tmTcDistributor->addComponent( objects::CCSDS_PACKET_DISTRIBUTOR); if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } - result = TmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); + result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } - result = TmTcDistributor->addComponent(objects::TM_FUNNEL); + result = tmTcDistributor->addComponent(objects::TM_FUNNEL); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Object add component failed" << std::endl; } /* UDP bridge */ - PeriodicTaskIF* UdpBridgeTask = TaskFactory::instance()->createPeriodicTask( + PeriodicTaskIF* udpBridgeTask = TaskFactory::instance()->createPeriodicTask( "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); - result = UdpBridgeTask->addComponent(objects::UDP_BRIDGE); + result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Unix Bridge failed" << std::endl; } - PeriodicTaskIF* UdpPollingTask = TaskFactory::instance()-> + PeriodicTaskIF* udpPollingTask = TaskFactory::instance()-> createPeriodicTask("UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); - result = UdpPollingTask->addComponent(objects::UDP_POLLING_TASK); + result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Polling failed" << std::endl; } /* PUS Services */ - PeriodicTaskIF* PusVerification = TaskFactory::instance()-> - createPeriodicTask("PUS_VERIF_1", 40, + PeriodicTaskIF* pusVerification = TaskFactory::instance()-> + createPeriodicTask("PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); - result = PusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } - PeriodicTaskIF* PusEvents = TaskFactory::instance()-> - createPeriodicTask("PUS_VERIF_1", 60, + PeriodicTaskIF* pusEvents = TaskFactory::instance()-> + createPeriodicTask("PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); - result = PusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + InitMission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING); } - PeriodicTaskIF* PusHighPrio = TaskFactory::instance()-> + PeriodicTaskIF* pusHighPrio = TaskFactory::instance()-> createPeriodicTask("PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); - result = PusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); } - result = PusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); } - PeriodicTaskIF* PusMedPrio = TaskFactory::instance()-> + PeriodicTaskIF* pusMedPrio = TaskFactory::instance()-> createPeriodicTask("PUS_HIGH_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, nullptr); - result = PusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - result = PusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - - PeriodicTaskIF* PusLowPrio = TaskFactory::instance()-> - createPeriodicTask("PUSB", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 1.6, nullptr); - result = PusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - - -#if OBSW_ADD_TEST_CODE == 1 - FixedTimeslotTaskIF* TestTimeslotTask = TaskFactory::instance()-> - createFixedTimeslotTask("PST_TEST_TASK", 10, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr); - result = pst::pollingSequenceTestFunction(TestTimeslotTask); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::createTasks: Test PST initialization " - << "failed!" << std::endl; + InitMission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); } - -#endif - - PeriodicTaskIF* SpiTestTask = TaskFactory::instance()-> - createPeriodicTask("SPI_TEST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 2.0, nullptr); - result = SpiTestTask->addComponent(objects::SPI_TEST); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add SPI test failed" << std::endl; + result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); } - //Main thread sleep + PeriodicTaskIF* pusLowPrio = TaskFactory::instance()-> + createPeriodicTask("PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 1.6, nullptr); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); + } + + PeriodicTaskIF* testTask = TaskFactory::instance()-> + createPeriodicTask("SPI_TEST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 2.0, nullptr); +#if OBSW_ADD_TEST_CODE == 1 + result = testTask->addComponent(objects::TEST_TASK); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + } +#endif /* OBSW_ADD_TEST_CODE == 1 */ +#if RPI_ADD_SPI_TEST == 1 + result = testTask->addComponent(objects::SPI_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("SPI_TEST", objects::SPI_TEST); + } +#endif /* RPI_ADD_SPI_TEST == 1 */ +#if RPI_ADD_GPIO_TEST == 1 + result = testTask->addComponent(objects::LIBGPIOD_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); + } +#endif /* RPI_ADD_GPIO_TEST == 1 */ + sif::info << "Starting tasks.." << std::endl; - TmTcDistributor->startTask(); - UdpBridgeTask->startTask(); - UdpPollingTask->startTask(); + tmTcDistributor->startTask(); + udpBridgeTask->startTask(); + udpPollingTask->startTask(); - PusVerification->startTask(); - PusEvents->startTask(); - PusHighPrio->startTask(); - PusMedPrio->startTask(); - PusLowPrio->startTask(); - - SpiTestTask->startTask(); + pusVerification->startTask(); + pusEvents->startTask(); + pusHighPrio->startTask(); + pusMedPrio->startTask(); + pusLowPrio->startTask(); #if OBSW_ADD_TEST_CODE == 1 - TestTimeslotTask->startTask(); -#endif + testTask->startTask(); +#endif /* OBSW_ADD_TEST_CODE == 1 */ sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index 7a7820b8..458456c8 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -1,7 +1,9 @@ #include "ObjectFactory.h" #include +#include #include +#include #include #include #include @@ -47,11 +49,23 @@ void ObjectFactory::produce(){ objects::TM_STORE, objects::TC_STORE); new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); - new SpiTest(objects::SPI_TEST); - new LinuxLibgpioIF(objects::GPIO_IF); + new LinuxLibgpioIF(objects::GPIO_IF); -#if RPI_TEST_GPIO == 1 +#if RPI_ADD_SPI_TEST == 1 + new SpiTest(objects::SPI_TEST); +#endif + +#if RPI_LOOPBACK_TEST_GPIO == 1 GpioCookie* gpioCookie = new GpioCookie(); + /* Loopback pins. Adapt according to setup */ + gpioId_t gpioIdSender = gpioIds::TEST_ID_0; + int bcmPinSender = 26; + gpioId_t gpioIdReader = gpioIds::TEST_ID_1; + int bcmPinReader = 16; + gpio::createRpiGpioConfig(gpioCookie, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER", + gpio::Direction::OUT, 0); + gpio::createRpiGpioConfig(gpioCookie, gpioIdReader, bcmPinReader, "GPIO_LB_READER", + gpio::Direction::IN, 0); new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); #endif } diff --git a/bsp_rpi/boardconfig/rpi_config.h b/bsp_rpi/boardconfig/rpi_config.h index 7d41e302..89141b80 100644 --- a/bsp_rpi/boardconfig/rpi_config.h +++ b/bsp_rpi/boardconfig/rpi_config.h @@ -1,7 +1,9 @@ #ifndef BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ #define BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ -#define RPI_TEST_GPIO 1 +#define RPI_ADD_GPIO_TEST 1 +#define RPI_ADD_SPI_TEST 1 +#define RPI_LOOPBACK_TEST_GPIO 1 diff --git a/bsp_rpi/boardtest/CMakeLists.txt b/bsp_rpi/boardtest/CMakeLists.txt index 1e373efb..768fc52f 100644 --- a/bsp_rpi/boardtest/CMakeLists.txt +++ b/bsp_rpi/boardtest/CMakeLists.txt @@ -1,6 +1,5 @@ target_sources(${TARGET_NAME} PRIVATE SpiTest.cpp - RPiGPIO.cpp ) diff --git a/bsp_rpi/gpio/CMakeLists.txt b/bsp_rpi/gpio/CMakeLists.txt new file mode 100644 index 00000000..85bd6aa6 --- /dev/null +++ b/bsp_rpi/gpio/CMakeLists.txt @@ -0,0 +1,9 @@ +target_sources(${TARGET_NAME} PUBLIC + GPIORPi.cpp +) + + + + + + diff --git a/bsp_rpi/gpio/GPIORPi.cpp b/bsp_rpi/gpio/GPIORPi.cpp new file mode 100644 index 00000000..84a3365f --- /dev/null +++ b/bsp_rpi/gpio/GPIORPi.cpp @@ -0,0 +1,36 @@ +#include "GPIORPi.h" +#include + +#include +#include + +ReturnValue_t gpio::createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int bcmPin, + std::string consumer, gpio::Direction direction, int initValue) { + if(cookie == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + GpioConfig_t config; + /* Default chipname for Raspberry Pi. There is still gpiochip1 for expansion, but most users + will not need this */ + config.chipname = "gpiochip0"; + + config.consumer = consumer; + config.direction = direction; + config.initValue = initValue; + + /* Sanity check for the BCM pins before assigning it */ + if(bcmPin > 27) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "createRpiGpioConfig: BCM pin " << bcmPin << " invalid!" << std::endl; +#else + sif::printError("createRpiGpioConfig: BCM pin %d invalid!\n", bcmPin); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return HasReturnvaluesIF::RETURN_FAILED; + } + config.lineNum = bcmPin; + cookie->addGpio(gpioId, config); + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/bsp_rpi/gpio/GPIORPi.h b/bsp_rpi/gpio/GPIORPi.h new file mode 100644 index 00000000..a2c11879 --- /dev/null +++ b/bsp_rpi/gpio/GPIORPi.h @@ -0,0 +1,26 @@ +#ifndef BSP_RPI_GPIO_GPIORPI_H_ +#define BSP_RPI_GPIO_GPIORPI_H_ + +#include +#include + +class GpioCookie; + +namespace gpio { + +/** + * Create a GpioConfig_t. This function does a sanity check on the BCM pin number and fails if the + * BCM pin is invalid. + * @param cookie Adds the configuration to this cookie directly + * @param gpioId ID which identifies the GPIO configuration + * @param bcmPin Raspberry Pi BCM pin + * @param consumer Information string + * @param direction GPIO direction + * @param initValue Intial value for output pins, 0 for low, 1 for high + * @return + */ +ReturnValue_t createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int bcmPin, + std::string consumer, gpio::Direction direction, int initValue); +} + +#endif /* BSP_RPI_GPIO_GPIORPI_H_ */ diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index abfb7456..5f841062 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -11,18 +11,18 @@ #endif #include "OBSWVersion.h" -#define TEST_LIBGPIOD 0 - /* These defines should be disabled for mission code but are useful for debugging. */ -#define OBSW_VERBOSE_LEVEL 1 +#define OBSW_VERBOSE_LEVEL 1 +#define OBSW_ADD_TEST_CODE 1 +#define TEST_LIBGPIOD 0 -#define TE0720 0 +#define TE0720 0 -#define P60DOCK_DEBUG 0 -#define PDU1_DEBUG 0 -#define PDU2_DEBUG 0 -#define ACU_DEBUG 1 +#define P60DOCK_DEBUG 0 +#define PDU1_DEBUG 0 +#define PDU2_DEBUG 0 +#define ACU_DEBUG 1 #ifdef __cplusplus diff --git a/fsfwconfig/devices/gpioIds.h b/fsfwconfig/devices/gpioIds.h index 70507b42..1e95ab9d 100644 --- a/fsfwconfig/devices/gpioIds.h +++ b/fsfwconfig/devices/gpioIds.h @@ -15,7 +15,8 @@ namespace gpioIds { HEATER_7, DEPLSA1, DEPLSA2, - Test_ID + TEST_ID_0, + TEST_ID_1 }; } diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index cc60ce18..5dec5581 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -13,7 +13,7 @@ LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl; } gpioInterface->initialize(gpioCookie); - testCase = TestCases::READ; + testCase = TestCases::LOOPBACK; } LibgpiodTest::~LibgpiodTest() { @@ -25,7 +25,7 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { switch(testCase) { case(TestCases::READ): { - result = gpioInterface->readGpio(gpioIds::Test_ID, &gpioState); + result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState); if (result != RETURN_OK) { sif::debug << "LibgpiodTest::performPeriodicAction: Failed to read gpio " << std::endl; @@ -38,7 +38,7 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { break; } case(TestCases::LOOPBACK): { - + break; } } @@ -46,3 +46,37 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { return RETURN_OK; } +ReturnValue_t LibgpiodTest::performOneShotAction() { + int gpioState; + ReturnValue_t result; + + switch(testCase) { + case(TestCases::READ): { + break; + } + case(TestCases::LOOPBACK): { + result = gpioInterface->pullHigh(gpioIds::TEST_ID_0); + if(result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "LibgpiodTest::performOneShotAction:" + "GPIO pulled high successfully for loopback test" << std::endl; + } + else { + sif::warning << "LibgpiodTest::performOneShotAction: Could not pull GPIO high!" + << std::endl; + return HasReturnvaluesIF::RETURN_OK; + } + result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState); + if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 1) { + sif::info << "LibgpiodTest::performOneShotAction:" + "GPIO state read successfully and is high" << std::endl; + } + else { + sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not high!" + << std::endl; + return HasReturnvaluesIF::RETURN_OK; + } + break; + } + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/linux/boardtest/LibgpiodTest.h b/linux/boardtest/LibgpiodTest.h index 642d4cd7..e9c6c030 100644 --- a/linux/boardtest/LibgpiodTest.h +++ b/linux/boardtest/LibgpiodTest.h @@ -23,7 +23,8 @@ public: virtual ~LibgpiodTest(); protected: - virtual ReturnValue_t performPeriodicAction() override; + ReturnValue_t performOneShotAction() override; + ReturnValue_t performPeriodicAction() override; private: GpioIF* gpioInterface; diff --git a/linux/gpio/GpioCookie.cpp b/linux/gpio/GpioCookie.cpp index 7f80b550..cd73574c 100644 --- a/linux/gpio/GpioCookie.cpp +++ b/linux/gpio/GpioCookie.cpp @@ -4,17 +4,23 @@ GpioCookie::GpioCookie() { } -void GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig){ +ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t& gpioConfig){ auto gpioMapIter = gpioMap.find(gpioId); if(gpioMapIter == gpioMap.end()) { auto statusPair = gpioMap.emplace(gpioId, gpioConfig); if (statusPair.second == false) { +#if FSFW_VERBOSE_LEVEL >= 1 sif::error << "GpioCookie::addGpio: Failed to add GPIO " << gpioId << "to GPIO map" << std::endl; +#endif + return HasReturnvaluesIF::RETURN_FAILED; } - return; + return HasReturnvaluesIF::RETURN_OK; } +#if FSFW_VERBOSE_LEVEL >= 1 sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map " << std::endl; +#endif + return HasReturnvaluesIF::RETURN_FAILED; } GpioMap GpioCookie::getGpioMap() const { diff --git a/linux/gpio/GpioCookie.h b/linux/gpio/GpioCookie.h index 05e80a2e..e1436813 100644 --- a/linux/gpio/GpioCookie.h +++ b/linux/gpio/GpioCookie.h @@ -23,7 +23,7 @@ public: virtual ~GpioCookie(); - void addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig); + ReturnValue_t addGpio(gpioId_t gpioId, GpioConfig_t& gpioConfig); /** * @brief Get map with registered GPIOs. */ diff --git a/linux/gpio/GpioIF.h b/linux/gpio/GpioIF.h index 269174e4..80d3a727 100644 --- a/linux/gpio/GpioIF.h +++ b/linux/gpio/GpioIF.h @@ -29,6 +29,7 @@ public: * functionality to pull a certain GPIO to high logic level. * * @param gpioId A unique number which specifies the GPIO to drive. + * @return Returns RETURN_OK for success. This should never return RETURN_FAILED. */ virtual ReturnValue_t pullHigh(gpioId_t gpioId) = 0; diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index 6a412733..a849bb09 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -58,6 +58,7 @@ private: * @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd. */ ReturnValue_t configureGpios(GpioMap& mapToAdd); + }; #endif /* LINUX_GPIO_LINUXLIBGPIOIF_H_ */ diff --git a/linux/gpio/gpioDefinitions.h b/linux/gpio/gpioDefinitions.h index bbc599ee..ce26ec78 100644 --- a/linux/gpio/gpioDefinitions.h +++ b/linux/gpio/gpioDefinitions.h @@ -28,6 +28,9 @@ enum Direction { * pointer. */ typedef struct GpioConfig { + GpioConfig(): chipname(), lineNum(0), consumer(), direction(gpio::Direction::OUT), + initValue(0) {}; + GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, gpio::Direction direction_, int initValue_): chipname(chipname_), lineNum(lineNum_), consumer(consumer_), diff --git a/bsp_rpi/boardtest/RPiGPIO.cpp b/misc/archive/RPiGPIO.cpp similarity index 100% rename from bsp_rpi/boardtest/RPiGPIO.cpp rename to misc/archive/RPiGPIO.cpp diff --git a/bsp_rpi/boardtest/RPiGPIO.h b/misc/archive/RPiGPIO.h similarity index 100% rename from bsp_rpi/boardtest/RPiGPIO.h rename to misc/archive/RPiGPIO.h diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index 2a254cf0..2fcb4450 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -78,11 +79,13 @@ void ObjectFactory::produceGenericObjects() { apid::EIVE_OBSW, pus::PUS_SERVICE_9); new Service17Test(objects::PUS_SERVICE_17_TEST, apid::EIVE_OBSW, pus::PUS_SERVICE_17); + new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS, apid::EIVE_OBSW, + pus::PUS_SERVICE_20); new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, apid::EIVE_OBSW, pus::PUS_SERVICE_200); /* Test Device Handler */ #if OBSW_ADD_TEST_CODE == 1 - new TestTask(objects::TEST_TASK); + new TestTask(objects::TEST_TASK); #endif } diff --git a/mission/utility/InitMission.h b/mission/utility/InitMission.h new file mode 100644 index 00000000..93ebc9bc --- /dev/null +++ b/mission/utility/InitMission.h @@ -0,0 +1,22 @@ +#ifndef MISSION_UTILITY_INITMISSION_H_ +#define MISSION_UTILITY_INITMISSION_H_ + +#include +#include + +namespace InitMission { + +void printAddObjectError(const char* name, object_id_t objectId) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "InitMission::printAddError: Adding object " << name << " with object ID 0x" + << std::hex << std::setfill('0') << std::setw(8) << objectId + << " failed!" << std::dec << std::endl; +#else + sif::printError("InitMission::printAddError: Adding object %s with object ID 0x%08x failed!\n" , + name, objectId); +#endif +} + +} + +#endif /* MISSION_UTILITY_INITMISSION_H_ */ From 557a5fa45ffc3d3b896ae1f31eef1542a6be8a9f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 18:46:45 +0100 Subject: [PATCH 18/51] better missed deadline handling --- bsp_hosted/InitMission.cpp | 4 +- bsp_hosted/InitMission.h | 2 +- bsp_hosted/main.cpp | 2 +- bsp_q7s/InitMission.cpp | 62 ++++++++++++----------- bsp_q7s/InitMission.h | 2 +- bsp_q7s/main.cpp | 6 +-- bsp_rpi/InitMission.cpp | 84 ++++++++++++++++---------------- bsp_rpi/InitMission.h | 2 +- bsp_rpi/ObjectFactory.cpp | 18 ++++--- bsp_rpi/boardtest/CMakeLists.txt | 1 - bsp_rpi/boardtest/SpiTest.cpp | 61 ----------------------- bsp_rpi/boardtest/SpiTest.h | 45 ----------------- bsp_rpi/main.cpp | 10 ++-- fsfw | 2 +- fsfwconfig/OBSWConfig.h | 17 ++++--- linux/boardtest/LibgpiodTest.cpp | 17 +++++++ mission/utility/InitMission.h | 4 +- test/testtasks/TestTask.cpp | 21 +++----- test/testtasks/TestTask.h | 3 +- 19 files changed, 136 insertions(+), 227 deletions(-) delete mode 100644 bsp_rpi/boardtest/SpiTest.cpp delete mode 100644 bsp_rpi/boardtest/SpiTest.h diff --git a/bsp_hosted/InitMission.cpp b/bsp_hosted/InitMission.cpp index 4da13c70..5ed5775d 100644 --- a/bsp_hosted/InitMission.cpp +++ b/bsp_hosted/InitMission.cpp @@ -30,7 +30,7 @@ ServiceInterfaceStream sif::error("ERROR", true, false, true); ObjectManagerIF *objectManager = nullptr; -void InitMission::initMission() { +void initmission::initMission() { sif::info << "Building global objects.." << std::endl; /* Instantiate global object manager and also create all objects */ objectManager = new ObjectManager(ObjectFactory::produce); @@ -41,7 +41,7 @@ void InitMission::initMission() { initTasks(); } -void InitMission::initTasks(){ +void initmission::initTasks(){ /* TMTC Distribution */ PeriodicTaskIF* TmTcDistributor = TaskFactory::instance()-> createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, diff --git a/bsp_hosted/InitMission.h b/bsp_hosted/InitMission.h index 5ecf9e41..01c72008 100644 --- a/bsp_hosted/InitMission.h +++ b/bsp_hosted/InitMission.h @@ -1,7 +1,7 @@ #ifndef BSP_LINUX_INITMISSION_H_ #define BSP_LINUX_INITMISSION_H_ -namespace InitMission { +namespace initmission { void initMission(); void initTasks(); }; diff --git a/bsp_hosted/main.cpp b/bsp_hosted/main.cpp index 02d793f9..4fa1eb04 100644 --- a/bsp_hosted/main.cpp +++ b/bsp_hosted/main.cpp @@ -24,7 +24,7 @@ int main(void) << SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; - InitMission::initMission(); + initmission::initMission(); for(;;) { // suspend main thread by sleeping it. diff --git a/bsp_q7s/InitMission.cpp b/bsp_q7s/InitMission.cpp index 2930803e..a3d0c0dc 100644 --- a/bsp_q7s/InitMission.cpp +++ b/bsp_q7s/InitMission.cpp @@ -30,7 +30,7 @@ ServiceInterfaceStream sif::error("ERROR", true, false, true); ObjectManagerIF *objectManager = nullptr; -void InitMission::initMission() { +void initmission::initMission() { sif::info << "Building global objects.." << std::endl; /* Instantiate global object manager and also create all objects */ objectManager = new ObjectManager(ObjectFactory::produce); @@ -41,96 +41,102 @@ void InitMission::initMission() { initTasks(); } -void InitMission::initTasks() { +void initmission::initTasks() { TaskFactory* factory = TaskFactory::instance(); if(factory == nullptr) { /* Should never happen ! */ return; } +#if OBSW_PRINT_MISSED_DEADLINES == 1 + void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline; +#else + void (*missedDeadlineFunc) (void) = nullptr; +#endif /* TMTC Distribution */ PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( - "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); ReturnValue_t result = tmTcDistributor->addComponent( objects::CCSDS_PACKET_DISTRIBUTOR); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR); + initmission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR); } result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR); + initmission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR); } result = tmTcDistributor->addComponent(objects::TM_FUNNEL); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL); + initmission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL); } /* UDP bridge */ PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( - "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE); + initmission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE); } PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( - "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); + "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK); + initmission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK); } /* PUS Services */ PeriodicTaskIF* pusVerification = factory->createPeriodicTask( - "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION); + initmission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION); } PeriodicTaskIF* pusEvents = factory->createPeriodicTask( - "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); + initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); } PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( - "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS); + initmission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS); } result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT); + initmission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT); } PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( - "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, nullptr); + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT); + initmission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT); } result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT); + initmission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT); } result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); + initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); } PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( - "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, nullptr); + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST); + initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST); } //TODO: Add handling of missed deadlines /* Polling Sequence Table Default */ FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask( - "PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, nullptr); + "PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, + missedDeadlineFunc); result = pst::pollingSequenceInitDefault(pollingSequenceTableTaskDefault); if (result != HasReturnvaluesIF::RETURN_OK) { sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; @@ -139,7 +145,7 @@ void InitMission::initTasks() { #if TE0720 == 0 FixedTimeslotTaskIF* gomSpacePstTask = factory-> createFixedTimeslotTask("GS_PST_TASK", 50, - PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, nullptr); + PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, missedDeadlineFunc); result = pst::gomspacePstInit(gomSpacePstTask); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl; @@ -147,17 +153,17 @@ void InitMission::initTasks() { #endif PeriodicTaskIF* testTask = factory->createPeriodicTask( - "GPIOD_TEST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, nullptr); + "GPIOD_TEST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc); #if OBSW_ADD_TEST_CODE == 1 result = testTask->addComponent(objects::TEST_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); } #endif /* OBSW_ADD_TEST_CODE == 1 */ #if TE0720 == 1 && TEST_LIBGPIOD == 1 result = testTask->addComponent(objects::LIBGPIOD_TEST); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); + initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); } #endif /* TE0720 == 1 && TEST_LIBGPIOD == 1 */ diff --git a/bsp_q7s/InitMission.h b/bsp_q7s/InitMission.h index 89d65ada..568b26b5 100644 --- a/bsp_q7s/InitMission.h +++ b/bsp_q7s/InitMission.h @@ -1,7 +1,7 @@ #ifndef BSP_Q7S_INITMISSION_H_ #define BSP_Q7S_INITMISSION_H_ -namespace InitMission { +namespace initmission { void initMission(); void initTasks(); }; diff --git a/bsp_q7s/main.cpp b/bsp_q7s/main.cpp index 49416ae2..b087e315 100644 --- a/bsp_q7s/main.cpp +++ b/bsp_q7s/main.cpp @@ -13,15 +13,15 @@ int main(void) { std::cout << "-- EIVE OBSW --" << std::endl; - std::cout << "-- Compiled for Linux " << " --" << std::endl; + std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl; std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; - InitMission::initMission(); + initmission::initMission(); for(;;) { - // suspend main thread by sleeping it. + /* Suspend main thread by sleeping it. */ TaskFactory::delayTask(5000); } } diff --git a/bsp_rpi/InitMission.cpp b/bsp_rpi/InitMission.cpp index f3dc47ed..c31cbe22 100644 --- a/bsp_rpi/InitMission.cpp +++ b/bsp_rpi/InitMission.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -24,7 +24,7 @@ ServiceInterfaceStream sif::error("ERROR"); ObjectManagerIF *objectManager = nullptr; -void InitMission::initMission() { +void initmission::initMission() { sif::info << "Building global objects.." << std::endl; /* Instantiate global object manager and also create all objects */ objectManager = new ObjectManager(ObjectFactory::produce); @@ -35,11 +35,21 @@ void InitMission::initMission() { initTasks(); } -void InitMission::initTasks(){ +void initmission::initTasks() { + TaskFactory* factory = TaskFactory::instance(); + if(factory == nullptr) { + /* Should never happen ! */ + return; + } +#if OBSW_PRINT_MISSED_DEADLINES == 1 + void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline; +#else + void (*missedDeadlineFunc) (void) = nullptr; +#endif + /* TMTC Distribution */ - PeriodicTaskIF* tmTcDistributor = TaskFactory::instance()-> - createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.100, nullptr); + PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); ReturnValue_t result = tmTcDistributor->addComponent( objects::CCSDS_PACKET_DISTRIBUTOR); if(result != HasReturnvaluesIF::RETURN_OK){ @@ -55,95 +65,85 @@ void InitMission::initTasks(){ } /* UDP bridge */ - PeriodicTaskIF* udpBridgeTask = TaskFactory::instance()->createPeriodicTask( - "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.2, nullptr); + PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( + "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Unix Bridge failed" << std::endl; } - PeriodicTaskIF* udpPollingTask = TaskFactory::instance()-> - createPeriodicTask("UDP_POLLING", 80, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); + PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( + "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Polling failed" << std::endl; } /* PUS Services */ - PeriodicTaskIF* pusVerification = TaskFactory::instance()-> - createPeriodicTask("PUS_VERIF", 40, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + PeriodicTaskIF* pusVerification = factory->createPeriodicTask( + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } - PeriodicTaskIF* pusEvents = TaskFactory::instance()-> - createPeriodicTask("PUS_EVENTS", 60, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + PeriodicTaskIF* pusEvents = factory->createPeriodicTask( + "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); if(result != HasReturnvaluesIF::RETURN_OK){ - InitMission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING); + initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING); } - PeriodicTaskIF* pusHighPrio = TaskFactory::instance()-> - createPeriodicTask("PUS_HIGH_PRIO", 50, - PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.200, nullptr); + PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); + initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); } result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); + initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); } - PeriodicTaskIF* pusMedPrio = TaskFactory::instance()-> - createPeriodicTask("PUS_HIGH_PRIO", 40, - PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.8, nullptr); + PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( + "PUS_HIGH_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); + initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); } result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT); + initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT); } result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); + initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); } - PeriodicTaskIF* pusLowPrio = TaskFactory::instance()-> - createPeriodicTask("PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 1.6, nullptr); + PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); + initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); } - PeriodicTaskIF* testTask = TaskFactory::instance()-> - createPeriodicTask("SPI_TEST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 2.0, nullptr); + PeriodicTaskIF* testTask = factory->createPeriodicTask( + "TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); #if OBSW_ADD_TEST_CODE == 1 result = testTask->addComponent(objects::TEST_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); } #endif /* OBSW_ADD_TEST_CODE == 1 */ #if RPI_ADD_SPI_TEST == 1 result = testTask->addComponent(objects::SPI_TEST); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("SPI_TEST", objects::SPI_TEST); + initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST); } #endif /* RPI_ADD_SPI_TEST == 1 */ #if RPI_ADD_GPIO_TEST == 1 result = testTask->addComponent(objects::LIBGPIOD_TEST); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); + initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); } #endif /* RPI_ADD_GPIO_TEST == 1 */ diff --git a/bsp_rpi/InitMission.h b/bsp_rpi/InitMission.h index 5ecf9e41..01c72008 100644 --- a/bsp_rpi/InitMission.h +++ b/bsp_rpi/InitMission.h @@ -1,7 +1,7 @@ #ifndef BSP_LINUX_INITMISSION_H_ #define BSP_LINUX_INITMISSION_H_ -namespace InitMission { +namespace initmission { void initMission(); void initTasks(); }; diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index 458456c8..01552be8 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -1,5 +1,4 @@ #include "ObjectFactory.h" -#include #include #include @@ -8,18 +7,21 @@ #include #include +#include +#include +#include +#include + +#include +#include + #include #include #include #include #include #include -#include -#include -#include - -#include -#include +#include void Factory::setStaticFrameworkObjectIds() { PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; @@ -52,7 +54,7 @@ void ObjectFactory::produce(){ new LinuxLibgpioIF(objects::GPIO_IF); #if RPI_ADD_SPI_TEST == 1 - new SpiTest(objects::SPI_TEST); + new SpiTestClass(objects::SPI_TEST); #endif #if RPI_LOOPBACK_TEST_GPIO == 1 diff --git a/bsp_rpi/boardtest/CMakeLists.txt b/bsp_rpi/boardtest/CMakeLists.txt index 768fc52f..0599b73f 100644 --- a/bsp_rpi/boardtest/CMakeLists.txt +++ b/bsp_rpi/boardtest/CMakeLists.txt @@ -1,5 +1,4 @@ target_sources(${TARGET_NAME} PRIVATE - SpiTest.cpp ) diff --git a/bsp_rpi/boardtest/SpiTest.cpp b/bsp_rpi/boardtest/SpiTest.cpp deleted file mode 100644 index a78d0171..00000000 --- a/bsp_rpi/boardtest/SpiTest.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "SpiTest.h" - -#include - -#include -#include - - - -SpiTest::SpiTest(object_id_t objectId): SystemObject(objectId) { - sif::info << "Setting up Raspberry Pi WiringPi library." << std::endl; -// wiringPiSetupGpio(); - -// pinMode(SS_MGM_0_LIS3, OUTPUT); -// pinMode(SS_MGM_1_RM, OUTPUT); -// pinMode(SS_GYRO_0_ADIS, OUTPUT); -// pinMode(SS_GYRO_1_L3G, OUTPUT); -// pinMode(SS_GYRO_2_L3G, OUTPUT); -// pinMode(SS_MGM_2_LIS3, OUTPUT); -// pinMode(SS_MGM_3_RM, OUTPUT); -// -// digitalWrite(SS_MGM_0_LIS3, HIGH); -// digitalWrite(SS_MGM_1_RM, HIGH); -// digitalWrite(SS_GYRO_0_ADIS, HIGH); -// digitalWrite(SS_GYRO_1_L3G, HIGH); -// digitalWrite(SS_GYRO_2_L3G, HIGH); -// digitalWrite(SS_MGM_2_LIS3, HIGH); -// digitalWrite(SS_MGM_3_RM, HIGH); - - int spiFd = open(spiDeviceName.c_str(), O_RDWR); - if (spiFd < 0){ - sif::error << "Could not open SPI device!" << std::endl; - } - - spiMode = SPI_MODE_3; - int ret = ioctl(spiFd, SPI_IOC_WR_MODE, &spiMode); - if(ret < 0) { - sif::error << "Could not set write mode!" << std::endl; - } - - /* Datenrate setzen */ - ret = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed); - if(ret < 0) { - sif::error << "Could not SPI speed!" << std::endl; - } -} - -ReturnValue_t SpiTest::performOperation(uint8_t opCode) { - if(oneShot) { - - } - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t SpiTest::initialize() { - //transferHandle.rx_buf = reinterpret_cast<__u64>(receiveBuffer); - //transferHandle.tx_buf = reinterpret_cast<__u64>(sendBuffer); - //transferHandle.speed_hz = 976000; - //transferHandle.len = 2; - return HasReturnvaluesIF::RETURN_OK; -} diff --git a/bsp_rpi/boardtest/SpiTest.h b/bsp_rpi/boardtest/SpiTest.h deleted file mode 100644 index b4f37fe2..00000000 --- a/bsp_rpi/boardtest/SpiTest.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef BSP_LINUX_TEST_SPITEST_H_ -#define BSP_LINUX_TEST_SPITEST_H_ - -#include -#include -#include -#include - -class SpiTest: - public SystemObject, - public ExecutableObjectIF { -public: - SpiTest(object_id_t objectId); - - ReturnValue_t performOperation(uint8_t opCode) override; - ReturnValue_t initialize() override; -private: - // These chip selects (BCM number) will be pulled high if not used - // ACS board specific. - enum SpiChipSelects { - SS_MGM_0_LIS3 = 0, //!< MGM 0, LIS3MDLTR, U6, A side - SS_MGM_1_RM = 1, //!< MGM 1, RM3100, U7, A side - SS_GYRO_0_ADIS = 2, //!< Gyro 0, ADIS16485, U3, A side - SS_GYRO_1_L3G = 3, //!< Gyro 1, L3GD20H, U4, A side - SS_GYRO_2_L3G = 4, //!< Gyro 2, L3GD20h, U5, B side - SS_MGM_2_LIS3 = 17, //!< MGM 2, LIS3MDLTR, U8, B side - SS_MGM_3_RM = 27, //!< MGM 3, RM3100, U9, B side - }; - - const std::string spiDeviceName = "/dev/spidev0.0"; - int spiFd = 0; - - uint8_t spiMode = SPI_MODE_3; - uint32_t spiSpeed = 976000; - - uint8_t sendBuffer[32]; - uint8_t receiveBuffer[32]; - struct spi_ioc_transfer transferHandle; - - bool oneShot = true; - -}; - - -#endif /* BSP_LINUX_TEST_SPITEST_H_ */ diff --git a/bsp_rpi/main.cpp b/bsp_rpi/main.cpp index 5f6be8db..e1f8d9f6 100644 --- a/bsp_rpi/main.cpp +++ b/bsp_rpi/main.cpp @@ -1,12 +1,10 @@ #include "InitMission.h" - #include + #include #include -#include - /** * @brief This is the main program for the target hardware. * @return @@ -14,15 +12,15 @@ int main(void) { std::cout << "-- EIVE OBSW --" << std::endl; - std::cout << "-- Compiled for Linux " << " --" << std::endl; + std::cout << "-- Compiled for Linux (Raspberry Pi) --" << std::endl; std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; - InitMission::initMission(); + initmission::initMission(); for(;;) { - // suspend main thread by sleeping it. + /* suspend main thread by sleeping it. */ TaskFactory::delayTask(5000); } } diff --git a/fsfw b/fsfw index c2839825..14437582 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit c28398257b68facbabb19d7228b045f1388305df +Subproject commit 144375827441b80a601579fe4395e3bbc19df92c diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index 5f841062..d4220b9e 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -13,16 +13,17 @@ /* These defines should be disabled for mission code but are useful for debugging. */ -#define OBSW_VERBOSE_LEVEL 1 -#define OBSW_ADD_TEST_CODE 1 -#define TEST_LIBGPIOD 0 +#define OBSW_VERBOSE_LEVEL 1 +#define OBSW_PRINT_MISSED_DEADLINES 1 +#define OBSW_ADD_TEST_CODE 1 +#define TEST_LIBGPIOD 0 -#define TE0720 0 +#define TE0720 0 -#define P60DOCK_DEBUG 0 -#define PDU1_DEBUG 0 -#define PDU2_DEBUG 0 -#define ACU_DEBUG 1 +#define P60DOCK_DEBUG 0 +#define PDU1_DEBUG 0 +#define PDU2_DEBUG 0 +#define ACU_DEBUG 1 #ifdef __cplusplus diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index 5dec5581..d88e5676 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -3,6 +3,7 @@ #include #include #include +#include LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie): @@ -75,6 +76,22 @@ ReturnValue_t LibgpiodTest::performOneShotAction() { << std::endl; return HasReturnvaluesIF::RETURN_OK; } + + result = gpioInterface->pullLow(gpioIds::TEST_ID_0); + if(result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "LibgpiodTest::performOneShotAction:" + "GPIO pulled low successfully for loopback test" << std::endl; + } + result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState); + if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 0) { + sif::info << "LibgpiodTest::performOneShotAction:" + "GPIO state read successfully and is low" << std::endl; + } + else { + sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not low!" + << std::endl; + return HasReturnvaluesIF::RETURN_OK; + } break; } } diff --git a/mission/utility/InitMission.h b/mission/utility/InitMission.h index 93ebc9bc..b4a83a1e 100644 --- a/mission/utility/InitMission.h +++ b/mission/utility/InitMission.h @@ -4,7 +4,7 @@ #include #include -namespace InitMission { +namespace initmission { void printAddObjectError(const char* name, object_id_t objectId) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -14,7 +14,7 @@ void printAddObjectError(const char* name, object_id_t objectId) { #else sif::printError("InitMission::printAddError: Adding object %s with object ID 0x%08x failed!\n" , name, objectId); -#endif +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } } diff --git a/test/testtasks/TestTask.cpp b/test/testtasks/TestTask.cpp index e6fb8457..9a5018c5 100644 --- a/test/testtasks/TestTask.cpp +++ b/test/testtasks/TestTask.cpp @@ -8,14 +8,9 @@ #include #include -bool TestTask::oneShotAction = true; -MutexIF* TestTask::testLock = nullptr; TestTask::TestTask(object_id_t objectId_): SystemObject(objectId_), testMode(testModes::A) { - if(testLock == nullptr) { - testLock = MutexFactory::instance()->createMutex(); - } IPCStore = objectManager->get(objects::IPC_STORE); } @@ -24,19 +19,17 @@ TestTask::~TestTask() { ReturnValue_t TestTask::performOperation(uint8_t operationCode) { ReturnValue_t result = RETURN_OK; - sif::info << "Hallo EIVE!" << std::endl; - testLock ->lockMutex(MutexIF::TimeoutType::WAITING, 20); + if(oneShotAction) { - // Add code here which should only be run once + /* Add code here which should only be run once */ performOneShotAction(); oneShotAction = false; } - testLock->unlockMutex(); - // Add code here which should only be run once per performOperation + /* Add code here which should only be run once per performOperation */ performPeriodicAction(); - // Add code here which should only be run on alternating cycles. + /* Add code here which should only be run on alternating cycles. */ if(testMode == testModes::A) { performActionA(); testMode = testModes::B; @@ -49,7 +42,7 @@ ReturnValue_t TestTask::performOperation(uint8_t operationCode) { } ReturnValue_t TestTask::performOneShotAction() { - // Everything here will only be performed once. + /* Everything here will only be performed once. */ return HasReturnvaluesIF::RETURN_OK; } @@ -61,12 +54,12 @@ ReturnValue_t TestTask::performPeriodicAction() { ReturnValue_t TestTask::performActionA() { ReturnValue_t result = RETURN_OK; - // Add periodically executed code here + /* Add periodically executed code here */ return result; } ReturnValue_t TestTask::performActionB() { ReturnValue_t result = RETURN_OK; - // Add periodically executed code here + /* Add periodically executed code here */ return result; } diff --git a/test/testtasks/TestTask.h b/test/testtasks/TestTask.h index 24e62af1..fef1ff0e 100644 --- a/test/testtasks/TestTask.h +++ b/test/testtasks/TestTask.h @@ -48,8 +48,7 @@ protected: private: // Actually, to be really thread-safe, a mutex should be used as well // Let's keep it simple for now. - static bool oneShotAction; - static MutexIF* testLock; + bool oneShotAction = true; StorageManagerIF* IPCStore; }; From 16c1b1d97f173c2855bb3cd5540c13a4ed605cee Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 18:48:58 +0100 Subject: [PATCH 19/51] fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 14437582..1ccfb747 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 144375827441b80a601579fe4395e3bbc19df92c +Subproject commit 1ccfb74709ba0ce6d469eed3df1584dbcb444321 From f9edcf089cfbb8c1bf5ce62343f8b7a27c243234 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 11:31:50 +0100 Subject: [PATCH 20/51] spi com if almost finished --- fsfw | 2 +- linux/gpio/LinuxLibgpioIF.h | 3 +- linux/gpio/gpioDefinitions.h | 2 + linux/i2c/I2cComIF.cpp | 26 ++- linux/i2c/I2cComIF.h | 4 +- linux/spi/CMakeLists.txt | 2 + linux/spi/SpiComIF.cpp | 303 ++++++++++++++++++++++++++++++++++ linux/spi/SpiComIF.h | 61 +++++++ linux/spi/SpiCookie.cpp | 99 +++++++++++ linux/spi/SpiCookie.h | 113 +++++++++++++ linux/spi/spiDefinitions.h | 15 ++ linux/utility/errorhandling.h | 30 ++++ 12 files changed, 649 insertions(+), 11 deletions(-) create mode 100644 linux/spi/SpiComIF.cpp create mode 100644 linux/spi/SpiComIF.h create mode 100644 linux/spi/SpiCookie.cpp create mode 100644 linux/spi/SpiCookie.h create mode 100644 linux/spi/spiDefinitions.h create mode 100644 linux/utility/errorhandling.h diff --git a/fsfw b/fsfw index 1ccfb747..a3d245f5 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 1ccfb74709ba0ce6d469eed3df1584dbcb444321 +Subproject commit a3d245f5a030c9450c516552283d26da2c799301 diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index a849bb09..03c78fdb 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -40,8 +40,7 @@ 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, - unsigned int logiclevel); + ReturnValue_t driveGpio(gpioId_t gpioId, unsigned int logiclevel); /** * @brief This function checks if GPIOs are already registered and whether diff --git a/linux/gpio/gpioDefinitions.h b/linux/gpio/gpioDefinitions.h index ce26ec78..28ad1239 100644 --- a/linux/gpio/gpioDefinitions.h +++ b/linux/gpio/gpioDefinitions.h @@ -11,6 +11,8 @@ enum Direction { IN = 0, OUT = 1 }; + +static constexpr gpioId_t NO_GPIO = -1; } /** diff --git a/linux/i2c/I2cComIF.cpp b/linux/i2c/I2cComIF.cpp index ef77baa1..8e372b14 100644 --- a/linux/i2c/I2cComIF.cpp +++ b/linux/i2c/I2cComIF.cpp @@ -181,16 +181,30 @@ ReturnValue_t I2cComIF::openDevice(std::string deviceFile, address_t i2cAddress, int* fileDescriptor) { *fileDescriptor = open(deviceFile.c_str(), O_RDWR); if (*fileDescriptor < 0) { - sif::error << "I2cComIF: Opening i2c device failed with error code " - << errno << ". Error description: " << strerror(errno) - << std::endl; +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "I2cComIF: Opening I2C device failed with error code " << errno << "." << + std::endl; + sif::warning << "Error description: " << strerror(errno) << std::endl; +#else + sif::printWarning("I2cComIF: Opening I2C device failed with error code %d.\n"); + sif::printWarning("Error description: %s\n", strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ return HasReturnvaluesIF::RETURN_FAILED; } if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) { - sif::error << "I2cComIF: Specifying target device failed with error " - << "code " << errno << ". Error description " - << strerror(errno) << std::endl; +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "I2cComIF: Specifying target device failed with error code " << errno << "." + << std::endl; + sif::warning << "Error description " << strerror(errno) << std::endl; +#else + sif::printWarning("I2cComIF: Specifying target device failed with error code %d.\n"); + sif::printWarning("Error description: %s\n", strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; diff --git a/linux/i2c/I2cComIF.h b/linux/i2c/I2cComIF.h index f5d07ac1..3529bde7 100644 --- a/linux/i2c/I2cComIF.h +++ b/linux/i2c/I2cComIF.h @@ -45,8 +45,8 @@ private: I2cDeviceMapIter i2cDeviceMapIter; /** - * @brief This function opens an i2c device and binds the opened file - * to a specific i2c address. + * @brief This function opens an I2C device and binds the opened file + * to a specific I2C address. * @param deviceFile The name of the device file. E.g. i2c-0 * @param i2cAddress The address of the i2c slave device. * @param fileDescriptor Pointer to device descriptor. diff --git a/linux/spi/CMakeLists.txt b/linux/spi/CMakeLists.txt index 45a7edcc..cb1c9277 100644 --- a/linux/spi/CMakeLists.txt +++ b/linux/spi/CMakeLists.txt @@ -1,4 +1,6 @@ target_sources(${TARGET_NAME} PUBLIC + SpiComIF.cpp + SpiCookie.cpp ) diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp new file mode 100644 index 00000000..bdb0c705 --- /dev/null +++ b/linux/spi/SpiComIF.cpp @@ -0,0 +1,303 @@ +#include "SpiComIF.h" +#include "spiDefinitions.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(objectId), + gpioComIF(gpioComIF) { + if(gpioComIF == nullptr) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "SpiComIF::SpiComIF: GPIO communication interface invalid!" << std::endl; +#else + sif::printError("SpiComIF::SpiComIF: GPIO communication interface invalid!\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + } + + spiMutex = MutexFactory::instance()->createMutex(); +} + +ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { + SpiCookie* spiCookie = dynamic_cast(cookie); + if(spiCookie == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + address_t spiAddress = spiCookie->getSpiAddress(); + + auto iter = spiDeviceMap.find(spiAddress); + if(iter == spiDeviceMap.end()) { + size_t bufferSize = spiCookie->getMaxBufferSize(); + SpiInstance spiInstance = {std::vector(bufferSize)}; + auto statusPair = spiDeviceMap.emplace(spiAddress, spiInstance); + if (not statusPair.second) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "SpiComIF::initializeInterface: Failed to insert device with address " << + spiAddress << "to SPI device map" << std::endl; +#else + sif::printError("SpiComIF::initializeInterface: Failed to insert device with address " + "%lu to SPI device map\n", static_cast(spiAddress)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return HasReturnvaluesIF::RETURN_FAILED; + } + /* Now we emplaced the read buffer in the map, we still need to assign that location + to the SPI driver transfer struct */ + spiCookie->assignReadBuffer(statusPair.first->second.replyBuffer.data()); + } + else { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "SpiComIF::initializeInterface: SPI address already exists!" << std::endl; +#else + sif::printError("SpiComIF::initializeInterface: SPI address already exists!\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return HasReturnvaluesIF::RETURN_FAILED; + } + + gpioId_t gpioId = spiCookie->getChipSelectPin(); + if(gpioId != gpio::NO_GPIO) { + gpioComIF->pullHigh(gpioId); + } + + size_t spiSpeed = 0; + spi::SpiMode spiMode = spi::SpiMode::MODE_0; + + SpiCookie::UncommonParameters params; + spiCookie->getSpiParameters(spiMode, spiSpeed, ¶ms); + + int fileDescriptor = 0; + ReturnValue_t result = openDevice(spiCookie->getSpiDevice(), &fileDescriptor); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, spiSpeed); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initializeInterface: Setting SPI mode failed!"); + } + + retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, spiSpeed); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initializeInterface: Setting SPI speed failed!"); + } + + /* These flags are rather uncommon */ + if(params.threeWireSpi or params.noCs or params.csHigh) { + uint32_t currentMode = 0; + retval = ioctl(fileDescriptor, SPI_IOC_RD_MODE32, ¤tMode); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initialiezInterface: Could not read full mode!"); + } + + if(params.threeWireSpi) { + currentMode |= SPI_3WIRE; + } + if(params.noCs) { + /* Some drivers like the Raspberry Pi ignore this flag in any case */ + currentMode |= SPI_NO_CS; + } + if(params.csHigh) { + currentMode |= SPI_CS_HIGH; + } + /* Write adapted mode */ + retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE32, currentMode); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initialiezInterface: Could not write full mode!"); + } + } + if(params.lsbFirst) { + retval = ioctl(fileDescriptor, SPI_IOC_WR_LSB_FIRST, true); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initializeInterface: Setting LSB first failed"); + } + } + if(params.bitsPerWord != 8) { + retval = ioctl(fileDescriptor, SPI_IOC_WR_BITS_PER_WORD, params.bitsPerWord); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initializeInterface: " + "Could not write bits per word!"); + } + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) { + SpiCookie* spiCookie = dynamic_cast(cookie); + if(spiCookie == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + 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; +#else + sif::printWarning("SpiComIF::sendMessage: Too much data sent, send length %lu larger " + "than maximum buffer length %lu!\n", static_cast(sendLen), + static_cast(spiCookie->getMaxBufferSize())); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return DeviceCommunicationIF::TOO_MUCH_DATA; + } + + spiCookie->assignWriteBuffer(sendData); + spiCookie->assignTransferSize(sendLen); + int fileDescriptor = 0; + std::string device = spiCookie->getSpiDevice(); + ReturnValue_t result = openDevice(device, &fileDescriptor); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + bool fullDuplex = spiCookie->isFullDuplex(); + int retval = 0; + + gpioId_t gpioId = spiCookie->getChipSelectPin(); + MutexHelper(spiMutex, timeoutType, timeoutMs); + if(gpioId != gpio::NO_GPIO) { + /* For now, no support for active high given */ + gpioComIF->pullLow(gpioId); + } + + if(fullDuplex) { + /* Initiate a full duplex SPI transfer. */ + retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle()); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::sendMessage: ioctl error."); + /* TODO: Better returnvalue */ + return HasReturnvaluesIF::RETURN_FAILED; + } + } + else { + /* We write with a blocking transfer here */ + if (write(fileDescriptor, sendData, sendLen) != static_cast(sendLen)) { + sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << + std::endl; + /* TODO: Better returnvalue */ + return HasReturnvaluesIF::RETURN_FAILED; + } + } + + if(gpioId != gpio::NO_GPIO) { + gpioComIF->pullHigh(gpioId); + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::getSendSuccess(CookieIF *cookie) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) { + SpiCookie* spiCookie = dynamic_cast(cookie); + if(spiCookie == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + bool fullDuplex = spiCookie->isFullDuplex(); + if(fullDuplex) { + return HasReturnvaluesIF::RETURN_OK; + } + + std::string device = spiCookie->getSpiDevice(); + int fileDescriptor = 0; + ReturnValue_t result = openDevice(device, &fileDescriptor); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + uint8_t* rxBuf = nullptr; + size_t readSize = spiCookie->getCurrentTransferSize(); + result = getReadBuffer(spiCookie->getSpiAddress(), &rxBuf); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + gpioId_t gpioId = spiCookie->getChipSelectPin(); + MutexHelper(spiMutex, timeoutType, timeoutMs); + if(gpioId != gpio::NO_GPIO) { + gpioComIF->pullLow(gpioId); + } + + if(read(fileDescriptor, rxBuf, readSize) != static_cast(readSize)) { + sif::warning << "SpiComIF::sendMessage: Half-Duplex read operation failed!" << std::endl; + if(gpioId != gpio::NO_GPIO) { + gpioComIF->pullHigh(gpioId); + } + } + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) { + SpiCookie* spiCookie = dynamic_cast(cookie); + if(spiCookie == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + uint8_t* rxBuf = nullptr; + ReturnValue_t result = getReadBuffer(spiCookie->getSpiAddress(), &rxBuf); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + *buffer = rxBuf; + *size = spiCookie->getCurrentTransferSize(); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::openDevice(std::string deviceFile, int *fileDescriptor, bool nonBlocking) { + if(fileDescriptor == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + int flags = O_RDWR; + if(nonBlocking) { + flags |= O_NONBLOCK; + } + *fileDescriptor = open(deviceFile.c_str(), flags); + if (*fileDescriptor < 0) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "SpiComIF: Opening SPI device failed with error code " << errno << "." << + std::endl; + sif::warning << "Error description: " << strerror(errno) << std::endl; +#else + sif::printError("SpiComIF: Opening SPI device failed with error code %d.\n"); + sif::printWarning("Error description: %s\n", strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return HasReturnvaluesIF::RETURN_FAILED; + } + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::getReadBuffer(address_t spiAddress, uint8_t** buffer) { + if(buffer == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + auto iter = spiDeviceMap.find(spiAddress); + if(iter == spiDeviceMap.end()) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + *buffer = iter->second.replyBuffer.data(); + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/linux/spi/SpiComIF.h b/linux/spi/SpiComIF.h new file mode 100644 index 00000000..4009eed9 --- /dev/null +++ b/linux/spi/SpiComIF.h @@ -0,0 +1,61 @@ +#ifndef LINUX_SPI_SPICOMIF_H_ +#define LINUX_SPI_SPICOMIF_H_ + +#include +#include +#include + +#include +#include + +/** + * @brief Encapsulates access to linux SPI driver for FSFW objects + * @details + * Right now, only full-duplex SPI is supported. + * @author R. Mueller + */ +class SpiComIF: public DeviceCommunicationIF, public SystemObject { +public: + SpiComIF(object_id_t objectId, GpioIF* gpioComIF); + + ReturnValue_t initializeInterface(CookieIF * cookie) override; + ReturnValue_t sendMessage(CookieIF *cookie,const uint8_t *sendData, + size_t sendLen) override; + ReturnValue_t getSendSuccess(CookieIF *cookie) override; + ReturnValue_t requestReceiveMessage(CookieIF *cookie, + size_t requestLen) override; + ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, + size_t *size) override; +private: + + struct SpiInstance { + std::vector replyBuffer; + }; + + GpioIF* gpioComIF = nullptr; + + MutexIF* spiMutex = nullptr; + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + uint32_t timeoutMs = 20; + + using SpiDeviceMap = std::unordered_map; + using SpiDeviceMapIter = SpiDeviceMap::iterator; + + SpiDeviceMap spiDeviceMap; + + /** + * @brief This function opens an SPI device and binds the opened file + * to a specific SPI address. + * @param deviceFile The name of the device file. E.g. spi-0 + * @param i2cAddress The address of the SPI slave device. + * @param fileDescriptor Pointer to device descriptor. + * @return RETURN_OK if successful, otherwise RETURN_FAILED. + */ + ReturnValue_t openDevice(std::string deviceFile, int* fileDescriptor, bool nonBlocking = false); + + ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); +}; + + + +#endif /* LINUX_SPI_SPICOMIF_H_ */ diff --git a/linux/spi/SpiCookie.cpp b/linux/spi/SpiCookie.cpp new file mode 100644 index 00000000..f0b81f67 --- /dev/null +++ b/linux/spi/SpiCookie.cpp @@ -0,0 +1,99 @@ +#include "SpiCookie.h" + +SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, + const size_t maxSize, spi::SpiMode spiMode, uint32_t spiSpeed): spiAddress(spiAddress), + chipSelectPin(chipSelect), spiDevice(spiDev), maxSize(maxSize), spiMode(spiMode), + spiSpeed(spiSpeed) { +} + +SpiCookie::SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxSize, + spi::SpiMode spiMode, uint32_t spiSpeed): + SpiCookie(spiAddress, gpio::NO_GPIO, spiDev, maxSize, spiMode, spiSpeed) { +} + +void SpiCookie::getSpiParameters(spi::SpiMode& spiMode, uint32_t& spiSpeed, + UncommonParameters* parameters) const { + spiMode = this->spiMode; + spiSpeed = this->spiSpeed; + + if(parameters != nullptr) { + parameters->threeWireSpi = uncommonParameters.threeWireSpi; + parameters->lsbFirst = uncommonParameters.lsbFirst; + parameters->noCs = uncommonParameters.noCs; + parameters->bitsPerWord = uncommonParameters.bitsPerWord; + parameters->csHigh = uncommonParameters.csHigh; + } +} + +gpioId_t SpiCookie::getChipSelectPin() const { + return chipSelectPin; +} + +size_t SpiCookie::getMaxBufferSize() const { + return maxSize; +} + +address_t SpiCookie::getSpiAddress() const { + return spiAddress; +} + +std::string SpiCookie::getSpiDevice() const { + return spiDevice; +} + +void SpiCookie::setThreeWireSpi(bool enable) { + uncommonParameters.threeWireSpi = enable; +} + +void SpiCookie::setLsbFirst(bool enable) { + uncommonParameters.lsbFirst = enable; +} + +void SpiCookie::setNoCs(bool enable) { + uncommonParameters.noCs = enable; +} + +void SpiCookie::setBitsPerWord(uint8_t bitsPerWord) { + uncommonParameters.bitsPerWord = bitsPerWord; +} + +void SpiCookie::setCsHigh(bool enable) { + uncommonParameters.csHigh = enable; +} + +void SpiCookie::activateCsDeselect(bool deselectCs, uint16_t delayUsecs) { + spiTransferStruct.cs_change = deselectCs; + spiTransferStruct.delay_usecs = delayUsecs; +} + +void SpiCookie::assignReadBuffer(uint8_t* rx) { + if(rx != nullptr) { + spiTransferStruct.rx_buf = reinterpret_cast<__u64>(rx); + } +} + +void SpiCookie::assignWriteBuffer(const uint8_t* tx) { + if(tx != nullptr) { + spiTransferStruct.tx_buf = reinterpret_cast<__u64>(tx); + } +} + +spi_ioc_transfer* SpiCookie::getTransferStructHandle() { + return &spiTransferStruct; +} + +void SpiCookie::setFullOrHalfDuplex(bool halfDuplex) { + this->halfDuplex = halfDuplex; +} + +bool SpiCookie::isFullDuplex() const { + return not this->halfDuplex; +} + +void SpiCookie::assignTransferSize(size_t transferSize) { + spiTransferStruct.len = transferSize; +} + +size_t SpiCookie::getCurrentTransferSize() const { + return spiTransferStruct.len; +} diff --git a/linux/spi/SpiCookie.h b/linux/spi/SpiCookie.h new file mode 100644 index 00000000..91d42a3c --- /dev/null +++ b/linux/spi/SpiCookie.h @@ -0,0 +1,113 @@ +#ifndef LINUX_SPI_SPICOOKIE_H_ +#define LINUX_SPI_SPICOOKIE_H_ + +#include "spiDefinitions.h" +#include +#include +#include + +class SpiCookie: public CookieIF { +public: + + /** + * Each SPI device will have a corresponding cookie. The cookie is used by the communication + * interface and contains device specific information like the largest expected size to be + * sent and received and the GPIO pin used to toggle the SPI slave select pin. + * @param spiAddress + * @param chipSelect Chip select. gpio::NO_GPIO can be used for hardware slave selects. + * @param spiDev + * @param maxSize + */ + SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, + const size_t maxReplySize, spi::SpiMode spiMode, uint32_t spiSpeed); + + /** + * Like constructor above, but without a dedicated GPIO CS. Can be used for hardware + * slave select or if CS logic is performed with decoders. + */ + SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxReplySize, + spi::SpiMode spiMode, uint32_t spiSpeed); + + address_t getSpiAddress() const; + std::string getSpiDevice() const; + gpioId_t getChipSelectPin() const; + size_t getMaxBufferSize() const; + /** + * True if SPI transfers should be performed in full duplex mode + * @return + */ + bool isFullDuplex() const; + + /** + * Set transfer type to full duplex or half duplex. Full duplex is the default setting, + * ressembling common SPI hardware implementation with shift registers, where read and writes + * happen simultaneosly. + * @param fullDuplex + */ + void setFullOrHalfDuplex(bool halfDuplex); + + /** + * This needs to be called to specify where the SPI driver writes to or reads from. + * @param readLocation + * @param writeLocation + */ + void assignReadBuffer(uint8_t* rx); + void assignWriteBuffer(const uint8_t* tx); + /** + * Assign size for the next transfer. + * @param transferSize + */ + void assignTransferSize(size_t transferSize); + size_t getCurrentTransferSize() const; + + struct UncommonParameters { + uint8_t bitsPerWord = 8; + bool noCs = false; + bool csHigh = false; + bool threeWireSpi = false; + /* MSB first is more common */ + bool lsbFirst = false; + }; + + /** + * Can be used to explicitely disable hardware chip select. + * Some drivers like the Raspberry Pi Linux driver will not use hardware chip select by default + * (see https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md) + * @param enable + */ + void setNoCs(bool enable); + void setThreeWireSpi(bool enable); + void setLsbFirst(bool enable); + void setCsHigh(bool enable); + void setBitsPerWord(uint8_t bitsPerWord); + + void getSpiParameters(spi::SpiMode& spiMode, uint32_t& spiSpeed, + UncommonParameters* parameters = nullptr) const; + + /** + * See spidev.h cs_change and delay_usecs + * @param deselectCs + * @param delayUsecs + */ + void activateCsDeselect(bool deselectCs, uint16_t delayUsecs); + + spi_ioc_transfer* getTransferStructHandle(); +private: + size_t currentTransferSize = 0; + + address_t spiAddress; + gpioId_t chipSelectPin; + std::string spiDevice; + + const size_t maxSize; + spi::SpiMode spiMode; + uint32_t spiSpeed; + bool halfDuplex = false; + + struct spi_ioc_transfer spiTransferStruct; + UncommonParameters uncommonParameters; +}; + + + +#endif /* LINUX_SPI_SPICOOKIE_H_ */ diff --git a/linux/spi/spiDefinitions.h b/linux/spi/spiDefinitions.h new file mode 100644 index 00000000..9c278a70 --- /dev/null +++ b/linux/spi/spiDefinitions.h @@ -0,0 +1,15 @@ +#ifndef LINUX_SPI_SPIDEFINITONS_H_ +#define LINUX_SPI_SPIDEFINITONS_H_ + +namespace spi { + +enum SpiMode { + MODE_0, + MODE_1, + MODE_2, + MODE_3 +}; + +} + +#endif /* LINUX_SPI_SPIDEFINITONS_H_ */ diff --git a/linux/utility/errorhandling.h b/linux/utility/errorhandling.h new file mode 100644 index 00000000..1b4bc38b --- /dev/null +++ b/linux/utility/errorhandling.h @@ -0,0 +1,30 @@ +#ifndef LINUX_UTILITY_ERRORHANDLING_H_ +#define LINUX_UTILITY_ERRORHANDLING_H_ + +#include +#include +#include + +namespace utility { + +void handleIoctlError(const char* const customPrintout) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + if(customPrintout != nullptr) { + sif::warning << customPrintout << std::endl; + } + sif::warning << "handleIoctlError: Error code " << errno << ", "<< strerror(errno) << + std::endl; +#else + if(customPrintout != nullptr) { + sif::printWarning("%s\n", customPrintout); + } + sif::printWarning("handleIoctlError: Error code %d, %s\n", errno, strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + +} + +} + +#endif /* LINUX_UTILITY_ERRORHANDLING_H_ */ From 0cf486b60e14188b3f76a333fb3d6ac1908b9883 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 11:56:48 +0100 Subject: [PATCH 21/51] spi com if finished --- fsfwconfig/returnvalues/classIds.h | 1 + linux/spi/SpiComIF.cpp | 69 +++++++++----------------- linux/spi/SpiComIF.h | 29 +++++++---- linux/utility/errorhandling.h | 30 ------------ linux/utility/utility.h | 77 ++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 85 deletions(-) delete mode 100644 linux/utility/errorhandling.h create mode 100644 linux/utility/utility.h diff --git a/fsfwconfig/returnvalues/classIds.h b/fsfwconfig/returnvalues/classIds.h index 419a24ef..deafbd75 100644 --- a/fsfwconfig/returnvalues/classIds.h +++ b/fsfwconfig/returnvalues/classIds.h @@ -14,6 +14,7 @@ enum { MGM_LIS3MDL, MGM_RM3100, LINUX_LIBGPIO_IF, + LINUX_SPI_COM_IF, PCDU_HANDLER, HEATER_HANDLER, SA_DEPL_HANDLER diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index bdb0c705..144a6db0 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -2,8 +2,6 @@ #include "spiDefinitions.h" #include -#include - #include #include @@ -12,6 +10,7 @@ #include #include #include +#include #include SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(objectId), @@ -81,9 +80,10 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { spiCookie->getSpiParameters(spiMode, spiSpeed, ¶ms); int fileDescriptor = 0; - ReturnValue_t result = openDevice(spiCookie->getSpiDevice(), &fileDescriptor); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; + utility::UnixFileHelper fileHelper(spiCookie->getSpiDevice(), &fileDescriptor, O_RDWR, + "SpiComIF::initializeInterface: "); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return fileHelper.getOpenResult(); } int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, spiSpeed); @@ -138,6 +138,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) { SpiCookie* spiCookie = dynamic_cast(cookie); + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; if(spiCookie == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } @@ -160,9 +161,10 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s spiCookie->assignTransferSize(sendLen); int fileDescriptor = 0; std::string device = spiCookie->getSpiDevice(); - ReturnValue_t result = openDevice(device, &fileDescriptor); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; + utility::UnixFileHelper fileHelper(device, &fileDescriptor, O_RDWR, + "SpiComIF::sendMessage: "); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return OPENING_FILE_FAILED; } bool fullDuplex = spiCookie->isFullDuplex(); @@ -180,8 +182,7 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle()); if(retval != 0) { utility::handleIoctlError("SpiComIF::sendMessage: ioctl error."); - /* TODO: Better returnvalue */ - return HasReturnvaluesIF::RETURN_FAILED; + result = FULL_DUPLEX_TRANSFER_FAILED; } } else { @@ -189,15 +190,14 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s if (write(fileDescriptor, sendData, sendLen) != static_cast(sendLen)) { sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << std::endl; - /* TODO: Better returnvalue */ - return HasReturnvaluesIF::RETURN_FAILED; + result = HALF_DUPLEX_TRANSFER_FAILED; } } if(gpioId != gpio::NO_GPIO) { gpioComIF->pullHigh(gpioId); } - return HasReturnvaluesIF::RETURN_OK; + return result; } ReturnValue_t SpiComIF::getSendSuccess(CookieIF *cookie) { @@ -205,6 +205,7 @@ ReturnValue_t SpiComIF::getSendSuccess(CookieIF *cookie) { } ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; SpiCookie* spiCookie = dynamic_cast(cookie); if(spiCookie == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; @@ -217,9 +218,10 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLe std::string device = spiCookie->getSpiDevice(); int fileDescriptor = 0; - ReturnValue_t result = openDevice(device, &fileDescriptor); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; + utility::UnixFileHelper fileHelper(device, &fileDescriptor, O_RDWR, + "SpiComIF::requestReceiveMessage: "); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return OPENING_FILE_FAILED; } uint8_t* rxBuf = nullptr; @@ -237,9 +239,11 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLe if(read(fileDescriptor, rxBuf, readSize) != static_cast(readSize)) { sif::warning << "SpiComIF::sendMessage: Half-Duplex read operation failed!" << std::endl; - if(gpioId != gpio::NO_GPIO) { - gpioComIF->pullHigh(gpioId); - } + result = HALF_DUPLEX_TRANSFER_FAILED; + } + + if(gpioId != gpio::NO_GPIO) { + gpioComIF->pullHigh(gpioId); } return HasReturnvaluesIF::RETURN_OK; @@ -261,33 +265,6 @@ ReturnValue_t SpiComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t SpiComIF::openDevice(std::string deviceFile, int *fileDescriptor, bool nonBlocking) { - if(fileDescriptor == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; - } - - int flags = O_RDWR; - if(nonBlocking) { - flags |= O_NONBLOCK; - } - *fileDescriptor = open(deviceFile.c_str(), flags); - if (*fileDescriptor < 0) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "SpiComIF: Opening SPI device failed with error code " << errno << "." << - std::endl; - sif::warning << "Error description: " << strerror(errno) << std::endl; -#else - sif::printError("SpiComIF: Opening SPI device failed with error code %d.\n"); - sif::printWarning("Error description: %s\n", strerror(errno)); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - return HasReturnvaluesIF::RETURN_FAILED; - } - - return HasReturnvaluesIF::RETURN_OK; -} - ReturnValue_t SpiComIF::getReadBuffer(address_t spiAddress, uint8_t** buffer) { if(buffer == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; diff --git a/linux/spi/SpiComIF.h b/linux/spi/SpiComIF.h index 4009eed9..b91dd479 100644 --- a/linux/spi/SpiComIF.h +++ b/linux/spi/SpiComIF.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -16,6 +17,16 @@ */ class SpiComIF: public DeviceCommunicationIF, public SystemObject { public: + static constexpr uint8_t spiRetvalId = CLASS_ID::LINUX_SPI_COM_IF; + static constexpr ReturnValue_t OPENING_FILE_FAILED = + HasReturnvaluesIF::makeReturnCode(spiRetvalId, 0); + /* Full duplex (ioctl) transfer failure */ + static constexpr ReturnValue_t FULL_DUPLEX_TRANSFER_FAILED = + HasReturnvaluesIF::makeReturnCode(spiRetvalId, 1); + /* Half duplex (read/write) transfer failure */ + static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED = + HasReturnvaluesIF::makeReturnCode(spiRetvalId, 2); + SpiComIF(object_id_t objectId, GpioIF* gpioComIF); ReturnValue_t initializeInterface(CookieIF * cookie) override; @@ -43,15 +54,15 @@ private: SpiDeviceMap spiDeviceMap; - /** - * @brief This function opens an SPI device and binds the opened file - * to a specific SPI address. - * @param deviceFile The name of the device file. E.g. spi-0 - * @param i2cAddress The address of the SPI slave device. - * @param fileDescriptor Pointer to device descriptor. - * @return RETURN_OK if successful, otherwise RETURN_FAILED. - */ - ReturnValue_t openDevice(std::string deviceFile, int* fileDescriptor, bool nonBlocking = false); +// /** +// * @brief This function opens an SPI device and binds the opened file +// * to a specific SPI address. +// * @param deviceFile The name of the device file. E.g. spi-0 +// * @param i2cAddress The address of the SPI slave device. +// * @param fileDescriptor Pointer to device descriptor. +// * @return RETURN_OK if successful, otherwise RETURN_FAILED. +// */ +// ReturnValue_t openDevice(std::string deviceFile, int* fileDescriptor, bool nonBlocking = false); ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); }; diff --git a/linux/utility/errorhandling.h b/linux/utility/errorhandling.h deleted file mode 100644 index 1b4bc38b..00000000 --- a/linux/utility/errorhandling.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef LINUX_UTILITY_ERRORHANDLING_H_ -#define LINUX_UTILITY_ERRORHANDLING_H_ - -#include -#include -#include - -namespace utility { - -void handleIoctlError(const char* const customPrintout) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - if(customPrintout != nullptr) { - sif::warning << customPrintout << std::endl; - } - sif::warning << "handleIoctlError: Error code " << errno << ", "<< strerror(errno) << - std::endl; -#else - if(customPrintout != nullptr) { - sif::printWarning("%s\n", customPrintout); - } - sif::printWarning("handleIoctlError: Error code %d, %s\n", errno, strerror(errno)); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - -} - -} - -#endif /* LINUX_UTILITY_ERRORHANDLING_H_ */ diff --git a/linux/utility/utility.h b/linux/utility/utility.h new file mode 100644 index 00000000..278b081c --- /dev/null +++ b/linux/utility/utility.h @@ -0,0 +1,77 @@ +#ifndef LINUX_UTILITY_UTILITY_H_ +#define LINUX_UTILITY_UTILITY_H_ + +#include +#include +#include + +#include +#include + +namespace utility { + +void handleIoctlError(const char* const customPrintout) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + if(customPrintout != nullptr) { + sif::warning << customPrintout << std::endl; + } + sif::warning << "handleIoctlError: Error code " << errno << ", "<< strerror(errno) << + std::endl; +#else + if(customPrintout != nullptr) { + sif::printWarning("%s\n", customPrintout); + } + sif::printWarning("handleIoctlError: Error code %d, %s\n", errno, strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + +} + +class UnixFileHelper { +public: + static constexpr int READ_WRITE_FLAG = O_RDWR; + static constexpr int READ_ONLY_FLAG = O_RDONLY; + static constexpr int NON_BLOCKING_IO_FLAG = O_NONBLOCK; + + static constexpr ReturnValue_t OPEN_FILE_FAILED = 1; + + UnixFileHelper(std::string device, int* fileDescriptor, int flags, + std::string diagnosticPrefix = ""): + fileDescriptor(fileDescriptor) { + if(fileDescriptor == nullptr) { + return; + } + *fileDescriptor = open(device.c_str(), flags); + if (*fileDescriptor < 0) { + #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; + #else + sif::printError("%sOpening device failed with error code %d.\n", diagnosticPrefix); + sif::printWarning("Error description: %s\n", strerror(errno)); + #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ + #endif /* FSFW_VERBOSE_LEVEL >= 1 */ + openStatus = OPEN_FILE_FAILED; + } + } + + virtual~ UnixFileHelper() { + if(fileDescriptor != nullptr) { + close(*fileDescriptor); + } + } + + ReturnValue_t getOpenResult() const { + return openStatus; + } +private: + int* fileDescriptor = nullptr; + ReturnValue_t openStatus = HasReturnvaluesIF::RETURN_OK; +}; + +} + +#endif /* LINUX_UTILITY_UTILITY_H_ */ From b0e9cff27ccd87ab77d07fe58b3dc288acaf73dd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 12:13:04 +0100 Subject: [PATCH 22/51] source file for utility now --- linux/CMakeLists.txt | 1 + linux/i2c/I2cComIF.cpp | 45 +++++++-------------- linux/spi/SpiComIF.cpp | 10 ++--- linux/utility/CMakeLists.txt | 7 ++++ linux/utility/Utility.cpp | 52 ++++++++++++++++++++++++ linux/utility/Utility.h | 36 +++++++++++++++++ linux/utility/utility.h | 77 ------------------------------------ 7 files changed, 116 insertions(+), 112 deletions(-) create mode 100644 linux/utility/CMakeLists.txt create mode 100644 linux/utility/Utility.cpp create mode 100644 linux/utility/Utility.h delete mode 100644 linux/utility/utility.h diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 9101e15d..77bea0ef 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -2,5 +2,6 @@ add_subdirectory(gpio) add_subdirectory(i2c) add_subdirectory(csp) add_subdirectory(spi) +add_subdirectory(utility) add_subdirectory(boardtest) diff --git a/linux/i2c/I2cComIF.cpp b/linux/i2c/I2cComIF.cpp index 8e372b14..ed50293d 100644 --- a/linux/i2c/I2cComIF.cpp +++ b/linux/i2c/I2cComIF.cpp @@ -1,12 +1,13 @@ #include "I2cComIF.h" #include - #include #include #include #include #include -#include +#include + +#include I2cComIF::I2cComIF(object_id_t objectId): SystemObject(objectId){ @@ -68,8 +69,7 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF *cookie, I2cCookie* i2cCookie = dynamic_cast(cookie); if(i2cCookie == nullptr) { - sif::error << "I2cComIF::sendMessasge: Invalid I2C Cookie!" - << std::endl; + sif::error << "I2cComIF::sendMessage: Invalid I2C Cookie!" << std::endl; return NULLPOINTER; } @@ -82,6 +82,10 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF *cookie, } deviceFile = i2cCookie->getDeviceFile(); + utility::UnixFileHelper fileHelper(deviceFile, &fd, O_RDWR, "I2cComIF::sendMessage"); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return fileHelper.getOpenResult(); + } result = openDevice(deviceFile, i2cAddress, &fd); if (result != HasReturnvaluesIF::RETURN_OK){ return result; @@ -91,10 +95,8 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF *cookie, sif::error << "I2cComIF::sendMessage: Failed to send data to I2C " "device with error code " << errno << ". Error description: " << strerror(errno) << std::endl; - close(fd); return HasReturnvaluesIF::RETURN_FAILED; } - close(fd); return HasReturnvaluesIF::RETURN_OK; } @@ -104,7 +106,6 @@ ReturnValue_t I2cComIF::getSendSuccess(CookieIF *cookie) { ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) { - ReturnValue_t result; int fd; std::string deviceFile; @@ -115,8 +116,7 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF *cookie, I2cCookie* i2cCookie = dynamic_cast(cookie); if(i2cCookie == nullptr) { - sif::error << "I2cComIF::requestReceiveMessage: Invalid I2C Cookie!" - << std::endl; + sif::error << "I2cComIF::requestReceiveMessage: Invalid I2C Cookie!" << std::endl; i2cDeviceMapIter->second.replyLen = 0; return NULLPOINTER; } @@ -131,6 +131,10 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF *cookie, } deviceFile = i2cCookie->getDeviceFile(); + utility::UnixFileHelper fileHelper(deviceFile, &fd, O_RDWR, "I2cComIF::requestReceiveMessage"); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return fileHelper.getOpenResult(); + } result = openDevice(deviceFile, i2cAddress, &fd); if (result != HasReturnvaluesIF::RETURN_OK){ i2cDeviceMapIter->second.replyLen = 0; @@ -139,19 +143,15 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF *cookie, uint8_t* replyBuffer = i2cDeviceMapIter->second.replyBuffer.data(); - if (read(fd, replyBuffer, requestLen) != (int)requestLen) { + if (read(fd, replyBuffer, requestLen) != static_cast(requestLen)) { sif::error << "I2cComIF::requestReceiveMessage: Reading from I2C " << "device failed with error code " << errno <<". Description" << " of error: " << strerror(errno) << std::endl; - close(fd); i2cDeviceMapIter->second.replyLen = 0; return HasReturnvaluesIF::RETURN_FAILED; } i2cDeviceMapIter->second.replyLen = requestLen; - - close(fd); - return HasReturnvaluesIF::RETURN_OK; } @@ -159,8 +159,7 @@ ReturnValue_t I2cComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t* size) { I2cCookie* i2cCookie = dynamic_cast(cookie); if(i2cCookie == nullptr) { - sif::error << "I2cComIF::readReceivedMessage: Invalid I2C Cookie!" - << std::endl; + sif::error << "I2cComIF::readReceivedMessage: Invalid I2C Cookie!" << std::endl; return NULLPOINTER; } @@ -179,20 +178,6 @@ ReturnValue_t I2cComIF::readReceivedMessage(CookieIF *cookie, ReturnValue_t I2cComIF::openDevice(std::string deviceFile, address_t i2cAddress, int* fileDescriptor) { - *fileDescriptor = open(deviceFile.c_str(), O_RDWR); - if (*fileDescriptor < 0) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "I2cComIF: Opening I2C device failed with error code " << errno << "." << - std::endl; - sif::warning << "Error description: " << strerror(errno) << std::endl; -#else - sif::printWarning("I2cComIF: Opening I2C device failed with error code %d.\n"); - sif::printWarning("Error description: %s\n", strerror(errno)); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - return HasReturnvaluesIF::RETURN_FAILED; - } if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) { #if FSFW_VERBOSE_LEVEL >= 1 diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index 144a6db0..ebcf7991 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -3,14 +3,14 @@ #include #include - #include #include #include #include #include #include -#include +#include + #include SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(objectId), @@ -31,7 +31,7 @@ SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(object ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { SpiCookie* spiCookie = dynamic_cast(cookie); if(spiCookie == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; + return NULLPOINTER; } address_t spiAddress = spiCookie->getSpiAddress(); @@ -140,7 +140,7 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s SpiCookie* spiCookie = dynamic_cast(cookie); ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; if(spiCookie == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; + return NULLPOINTER; } if(sendLen > spiCookie->getMaxBufferSize()) { @@ -208,7 +208,7 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLe ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; SpiCookie* spiCookie = dynamic_cast(cookie); if(spiCookie == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; + return NULLPOINTER; } bool fullDuplex = spiCookie->isFullDuplex(); diff --git a/linux/utility/CMakeLists.txt b/linux/utility/CMakeLists.txt new file mode 100644 index 00000000..71151b6c --- /dev/null +++ b/linux/utility/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${TARGET_NAME} PUBLIC + Utility.cpp +) + + + + diff --git a/linux/utility/Utility.cpp b/linux/utility/Utility.cpp new file mode 100644 index 00000000..8f1ca912 --- /dev/null +++ b/linux/utility/Utility.cpp @@ -0,0 +1,52 @@ +#include "Utility.h" + +void utility::handleIoctlError(const char* const customPrintout) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + if(customPrintout != nullptr) { + sif::warning << customPrintout << std::endl; + } + sif::warning << "handleIoctlError: Error code " << errno << ", "<< strerror(errno) << + std::endl; +#else + if(customPrintout != nullptr) { + sif::printWarning("%s\n", customPrintout); + } + sif::printWarning("handleIoctlError: Error code %d, %s\n", errno, strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + +} + +utility::UnixFileHelper::UnixFileHelper(std::string device, int* fileDescriptor, int flags, + std::string diagnosticPrefix): + fileDescriptor(fileDescriptor) { + if(fileDescriptor == nullptr) { + return; + } + *fileDescriptor = open(device.c_str(), flags); + if (*fileDescriptor < 0) { +#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; +#else + sif::printError("%sOpening device failed with error code %d.\n", diagnosticPrefix); + sif::printWarning("Error description: %s\n", strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + openStatus = OPEN_FILE_FAILED; + } +} + +utility::UnixFileHelper::~UnixFileHelper() { + if(fileDescriptor != nullptr) { + close(*fileDescriptor); + } +} + +ReturnValue_t utility::UnixFileHelper::getOpenResult() const { + return openStatus; +} + diff --git a/linux/utility/Utility.h b/linux/utility/Utility.h new file mode 100644 index 00000000..a93b4936 --- /dev/null +++ b/linux/utility/Utility.h @@ -0,0 +1,36 @@ +#ifndef LINUX_UTILITY_UTILITY_H_ +#define LINUX_UTILITY_UTILITY_H_ + +#include +#include +#include + +#include +#include + +namespace utility { + +void handleIoctlError(const char* const customPrintout); + +class UnixFileHelper { +public: + static constexpr int READ_WRITE_FLAG = O_RDWR; + static constexpr int READ_ONLY_FLAG = O_RDONLY; + static constexpr int NON_BLOCKING_IO_FLAG = O_NONBLOCK; + + static constexpr ReturnValue_t OPEN_FILE_FAILED = 1; + + UnixFileHelper(std::string device, int* fileDescriptor, int flags, + std::string diagnosticPrefix = ""); + + virtual~ UnixFileHelper(); + + ReturnValue_t getOpenResult() const; +private: + int* fileDescriptor = nullptr; + ReturnValue_t openStatus = HasReturnvaluesIF::RETURN_OK; +}; + +} + +#endif /* LINUX_UTILITY_UTILITY_H_ */ diff --git a/linux/utility/utility.h b/linux/utility/utility.h deleted file mode 100644 index 278b081c..00000000 --- a/linux/utility/utility.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef LINUX_UTILITY_UTILITY_H_ -#define LINUX_UTILITY_UTILITY_H_ - -#include -#include -#include - -#include -#include - -namespace utility { - -void handleIoctlError(const char* const customPrintout) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - if(customPrintout != nullptr) { - sif::warning << customPrintout << std::endl; - } - sif::warning << "handleIoctlError: Error code " << errno << ", "<< strerror(errno) << - std::endl; -#else - if(customPrintout != nullptr) { - sif::printWarning("%s\n", customPrintout); - } - sif::printWarning("handleIoctlError: Error code %d, %s\n", errno, strerror(errno)); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - -} - -class UnixFileHelper { -public: - static constexpr int READ_WRITE_FLAG = O_RDWR; - static constexpr int READ_ONLY_FLAG = O_RDONLY; - static constexpr int NON_BLOCKING_IO_FLAG = O_NONBLOCK; - - static constexpr ReturnValue_t OPEN_FILE_FAILED = 1; - - UnixFileHelper(std::string device, int* fileDescriptor, int flags, - std::string diagnosticPrefix = ""): - fileDescriptor(fileDescriptor) { - if(fileDescriptor == nullptr) { - return; - } - *fileDescriptor = open(device.c_str(), flags); - if (*fileDescriptor < 0) { - #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; - #else - sif::printError("%sOpening device failed with error code %d.\n", diagnosticPrefix); - sif::printWarning("Error description: %s\n", strerror(errno)); - #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ - #endif /* FSFW_VERBOSE_LEVEL >= 1 */ - openStatus = OPEN_FILE_FAILED; - } - } - - virtual~ UnixFileHelper() { - if(fileDescriptor != nullptr) { - close(*fileDescriptor); - } - } - - ReturnValue_t getOpenResult() const { - return openStatus; - } -private: - int* fileDescriptor = nullptr; - ReturnValue_t openStatus = HasReturnvaluesIF::RETURN_OK; -}; - -} - -#endif /* LINUX_UTILITY_UTILITY_H_ */ From c9a42e2d1eaa1313365ff93c2dc13464021df4ae Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:24:05 +0100 Subject: [PATCH 23/51] refactored GPIO to support callbacks --- bsp_rpi/gpio/GPIORPi.cpp | 2 +- linux/boardtest/LibgpiodTest.cpp | 2 +- linux/gpio/GpioCookie.cpp | 4 +- linux/gpio/GpioCookie.h | 2 +- linux/gpio/GpioIF.h | 2 +- linux/gpio/LinuxLibgpioIF.cpp | 292 ++++++++++++------ linux/gpio/LinuxLibgpioIF.h | 19 +- linux/gpio/gpioDefinitions.h | 68 +++- .../devices/SolarArrayDeploymentHandler.cpp | 2 +- 9 files changed, 268 insertions(+), 125 deletions(-) diff --git a/bsp_rpi/gpio/GPIORPi.cpp b/bsp_rpi/gpio/GPIORPi.cpp index 84a3365f..74b67a42 100644 --- a/bsp_rpi/gpio/GPIORPi.cpp +++ b/bsp_rpi/gpio/GPIORPi.cpp @@ -10,7 +10,7 @@ ReturnValue_t gpio::createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int return HasReturnvaluesIF::RETURN_FAILED; } - GpioConfig_t config; + GpiodRegular config; /* Default chipname for Raspberry Pi. There is still gpiochip1 for expansion, but most users will not need this */ config.chipname = "gpiochip0"; diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index d88e5676..99602107 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -13,7 +13,7 @@ LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, if (gpioInterface == nullptr) { sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl; } - gpioInterface->initialize(gpioCookie); + gpioInterface->addGpios(gpioCookie); testCase = TestCases::LOOPBACK; } diff --git a/linux/gpio/GpioCookie.cpp b/linux/gpio/GpioCookie.cpp index cd73574c..f957d070 100644 --- a/linux/gpio/GpioCookie.cpp +++ b/linux/gpio/GpioCookie.cpp @@ -4,10 +4,10 @@ GpioCookie::GpioCookie() { } -ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t& gpioConfig){ +ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpiodRegular& gpioConfig){ auto gpioMapIter = gpioMap.find(gpioId); if(gpioMapIter == gpioMap.end()) { - auto statusPair = gpioMap.emplace(gpioId, gpioConfig); + auto statusPair = gpioMap.emplace(gpioId, new GpiodRegular(gpioConfig)); if (statusPair.second == false) { #if FSFW_VERBOSE_LEVEL >= 1 sif::error << "GpioCookie::addGpio: Failed to add GPIO " << gpioId << diff --git a/linux/gpio/GpioCookie.h b/linux/gpio/GpioCookie.h index e1436813..c7721a98 100644 --- a/linux/gpio/GpioCookie.h +++ b/linux/gpio/GpioCookie.h @@ -23,7 +23,7 @@ public: virtual ~GpioCookie(); - ReturnValue_t addGpio(gpioId_t gpioId, GpioConfig_t& gpioConfig); + ReturnValue_t addGpio(gpioId_t gpioId, GpiodRegular& gpioConfig); /** * @brief Get map with registered GPIOs. */ diff --git a/linux/gpio/GpioIF.h b/linux/gpio/GpioIF.h index 80d3a727..75feb3ce 100644 --- a/linux/gpio/GpioIF.h +++ b/linux/gpio/GpioIF.h @@ -22,7 +22,7 @@ public: * @param cookie Cookie specifying informations of the GPIOs required * by a object. */ - virtual ReturnValue_t initialize(GpioCookie* cookie) = 0; + virtual ReturnValue_t addGpios(GpioCookie* cookie) = 0; /** * @brief By implementing this function a child must provide the diff --git a/linux/gpio/LinuxLibgpioIF.cpp b/linux/gpio/LinuxLibgpioIF.cpp index 1b152a0f..0cf3858f 100644 --- a/linux/gpio/LinuxLibgpioIF.cpp +++ b/linux/gpio/LinuxLibgpioIF.cpp @@ -2,18 +2,20 @@ #include "GpioCookie.h" #include +#include #include #include #include + LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) { } LinuxLibgpioIF::~LinuxLibgpioIF() { } -ReturnValue_t LinuxLibgpioIF::initialize(GpioCookie* gpioCookie){ +ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) { ReturnValue_t result; if(gpioCookie == nullptr) { sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl; @@ -32,101 +34,153 @@ ReturnValue_t LinuxLibgpioIF::initialize(GpioCookie* gpioCookie){ return RETURN_FAILED; } - /* Register new GPIOs in gpioMap*/ + /* Register new GPIOs in gpioMap */ gpioMap.insert(mapToAdd.begin(), mapToAdd.end()); return RETURN_OK; } ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { + for(auto& gpioConfig: mapToAdd) { + switch(gpioConfig.second->gpioType) { + case(gpio::GpioTypes::NONE): { + return GPIO_INVALID_INSTANCE; + } + case(gpio::GpioTypes::GPIOD_REGULAR): { + GpiodRegular* regularGpio = dynamic_cast(gpioConfig.second); + configureRegularGpio(gpioConfig.first, regularGpio); + break; + } + case(gpio::GpioTypes::CALLBACK): { + auto gpioCallback = dynamic_cast(gpioMapIter->second); + if(gpioCallback->callback == nullptr) { + return GPIO_INVALID_INSTANCE; + } + gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::READ, + 0, gpioCallback->callbackArgs); + } + } + } + return RETURN_OK; +} + +ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular *regularGpio) { std::string chipname; unsigned int lineNum; struct gpiod_chip *chip; gpio::Direction direction; std::string consumer; struct gpiod_line *lineHandle; - int result; + int result = 0; - for(auto& gpioConfig: mapToAdd) { - chipname = gpioConfig.second.chipname; - chip = gpiod_chip_open_by_name(chipname.c_str()); - if (!chip) { - sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip " - << chipname << ". Gpio ID: " << gpioConfig.first << std::endl; - return RETURN_FAILED; - } - - lineNum = gpioConfig.second.lineNum; - lineHandle = gpiod_chip_get_line(chip, lineNum); - if (!lineHandle) { - sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line" << std::endl; - gpiod_chip_close(chip); - return RETURN_FAILED; - } - - direction = gpioConfig.second.direction; - consumer = gpioConfig.second.consumer; - /* Configure direction and add a description to the GPIO */ - switch (direction) { - case gpio::OUT: - result = gpiod_line_request_output(lineHandle, consumer.c_str(), - gpioConfig.second.initValue); - if (result < 0) { - sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " - << lineNum << " from GPIO instance with ID: " << gpioConfig.first - << std::endl; - gpiod_line_release(lineHandle); - return RETURN_FAILED; - } - break; - case gpio::IN: - result = gpiod_line_request_input(lineHandle, consumer.c_str()); - if (result < 0) { - sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " - << lineNum << " from GPIO instance with ID: " << gpioConfig.first - << std::endl; - gpiod_line_release(lineHandle); - return RETURN_FAILED; - } - break; - default: - sif::error << "LinuxLibgpioIF::configureGpios: Invalid direction specified" - << std::endl; - return RETURN_FAILED; - } - /** - * Write line handle to GPIO configuration instance so it can later be used to set or - * read states of GPIOs. - */ - gpioConfig.second.lineHandle = lineHandle; - } - return RETURN_OK; -} - -ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId){ - return driveGpio(gpioId, 1); -} - -ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId){ - return driveGpio(gpioId, 0); -} - -ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, - unsigned int logiclevel) { - int result; - struct gpiod_line *lineHandle; - - gpioMapIter = gpioMap.find(gpioId); - if (gpioMapIter == gpioMap.end()){ - sif::debug << "LinuxLibgpioIF::driveGpio: Unknown gpio id " << gpioId << std::endl; + chipname = regularGpio->chipname; + chip = gpiod_chip_open_by_name(chipname.c_str()); + if (!chip) { + sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip " + << chipname << ". Gpio ID: " << gpioId << std::endl; return RETURN_FAILED; } - lineHandle = gpioMapIter->second.lineHandle; - result = gpiod_line_set_value(lineHandle, logiclevel); + lineNum = regularGpio->lineNum; + lineHandle = gpiod_chip_get_line(chip, lineNum); + if (!lineHandle) { + sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line" << std::endl; + gpiod_chip_close(chip); + return RETURN_FAILED; + } + + 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); + if (result < 0) { + sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " << lineNum << + " from GPIO instance with ID: " << gpioId << std::endl; + gpiod_line_release(lineHandle); + return RETURN_FAILED; + } + break; + } + case(gpio::IN): { + result = gpiod_line_request_input(lineHandle, consumer.c_str()); + if (result < 0) { + sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " + << lineNum << " from GPIO instance with ID: " << gpioId << std::endl; + gpiod_line_release(lineHandle); + return RETURN_FAILED; + } + break; + } + default: { + sif::error << "LinuxLibgpioIF::configureGpios: Invalid direction specified" + << std::endl; + return GPIO_INVALID_INSTANCE; + } + + } + /** + * Write line handle to GPIO configuration instance so it can later be used to set or + * read states of GPIOs. + */ + regularGpio->lineHandle = lineHandle; + return RETURN_OK; +} + +ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) { + gpioMapIter = gpioMap.find(gpioId); + if (gpioMapIter == gpioMap.end()) { + sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl; + return UNKNOWN_GPIO_ID; + } + + if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { + return driveGpio(gpioId, dynamic_cast(gpioMapIter->second), 1); + } + else { + auto gpioCallback = dynamic_cast(gpioMapIter->second); + if(gpioCallback->callback == nullptr) { + return GPIO_INVALID_INSTANCE; + } + gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE, + 1, gpioCallback->callbackArgs); + } + return GPIO_TYPE_FAILURE; +} + +ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) { + gpioMapIter = gpioMap.find(gpioId); + if (gpioMapIter == gpioMap.end()) { + sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl; + return UNKNOWN_GPIO_ID; + } + + if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { + return driveGpio(gpioId, dynamic_cast(gpioMapIter->second), 0); + } + else { + auto gpioCallback = dynamic_cast(gpioMapIter->second); + if(gpioCallback->callback == nullptr) { + return GPIO_INVALID_INSTANCE; + } + gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE, + 0, gpioCallback->callbackArgs); + } + return GPIO_TYPE_FAILURE; +} + +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); if (result < 0) { - sif::error << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " - << gpioId << " to logic level " << logiclevel << std::endl; + sif::warning << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId << + " to logic level " << logicLevel << std::endl; return DRIVE_GPIO_FAILURE; } @@ -134,38 +188,76 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, } ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { - struct gpiod_line *lineHandle; - gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()){ - sif::debug << "LinuxLibgpioIF::readGpio: Unknown gpio id " << gpioId << std::endl; - return RETURN_FAILED; + sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl; + return UNKNOWN_GPIO_ID; + } + + if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { + GpiodRegular* regularGpio = dynamic_cast(gpioMapIter->second); + if(regularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + *gpioState = gpiod_line_get_value(regularGpio->lineHandle); + } + else { + } - lineHandle = gpioMapIter->second.lineHandle; - *gpioState = gpiod_line_get_value(lineHandle); return RETURN_OK; } ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ - gpioId_t gpioId; + ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; for(auto& gpioConfig: mapToAdd) { - gpioId = gpioConfig.first; - /* Cross check with private map */ - gpioMapIter = gpioMap.find(gpioId); - if(gpioMapIter != mapToAdd.end()) { - /* An entry for this GPIO already exists. Check if configuration - * of direction is equivalent */ - if (gpioConfig.second.direction != gpioMapIter->second.direction){ - sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict for GPIO " << - gpioConfig.first << std::endl; - return RETURN_FAILED; + switch(gpioConfig.second->gpioType) { + case(gpio::GpioTypes::GPIOD_REGULAR): { + auto regularGpio = dynamic_cast(gpioConfig.second); + if(regularGpio == nullptr) { + return GPIO_TYPE_FAILURE; } - /* Remove element from map to add because a entry for this GPIO - * already exists */ - mapToAdd.erase(gpioConfig.first); + result = checkForConflictsRegularGpio(gpioConfig.first, regularGpio); + if(result != HasReturnvaluesIF::RETURN_OK) { + status = result; + } + break; + } + default: { + + } } } - return RETURN_OK; + return status; +} + + +ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck, + GpiodRegular* gpioToCheck) { + /* Cross check with private map */ + gpioMapIter = gpioMap.find(gpioIdToCheck); + if(gpioMapIter != gpioMap.end()) { + if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { + auto ownRegularGpio = dynamic_cast(gpioMapIter->second); + if(ownRegularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + /* An entry for this GPIO already exists. Check if configuration + * of direction is equivalent */ + if (gpioToCheck->direction != ownRegularGpio->direction){ + sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict for GPIO " << + gpioIdToCheck << std::endl; + return RETURN_FAILED; + + } + } + + /* Remove element from map to add because a entry for this GPIO + * already exists */ + gpioMap.erase(gpioIdToCheck); + + } + return HasReturnvaluesIF::RETURN_OK; } diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index 03c78fdb..287e157d 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -17,14 +17,21 @@ class GpioCookie; class LinuxLibgpioIF : public GpioIF, public SystemObject { public: - static const uint8_t INTERFACE_ID = CLASS_ID::LINUX_LIBGPIO_IF; + static const uint8_t gpioRetvalId = CLASS_ID::LINUX_LIBGPIO_IF; - static const ReturnValue_t DRIVE_GPIO_FAILURE = MAKE_RETURN_CODE(0x2); + static constexpr ReturnValue_t UNKNOWN_GPIO_ID = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 1); + static constexpr ReturnValue_t DRIVE_GPIO_FAILURE = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 2); + static constexpr ReturnValue_t GPIO_TYPE_FAILURE = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 3); + static constexpr ReturnValue_t GPIO_INVALID_INSTANCE = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4); LinuxLibgpioIF(object_id_t objectId); virtual ~LinuxLibgpioIF(); - ReturnValue_t initialize(GpioCookie* gpioCookie) override; + ReturnValue_t addGpios(GpioCookie* gpioCookie) override; ReturnValue_t pullHigh(gpioId_t gpioId) override; ReturnValue_t pullLow(gpioId_t gpioId) override; ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override; @@ -40,7 +47,9 @@ 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, unsigned int logiclevel); + ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegular* regularGpio, unsigned int logiclevel); + + ReturnValue_t configureRegularGpio(gpioId_t gpioId, GpiodRegular* regularGpio); /** * @brief This function checks if GPIOs are already registered and whether @@ -53,6 +62,8 @@ private: */ ReturnValue_t checkForConflicts(GpioMap& mapToAdd); + ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegular* regularGpio); + /** * @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd. */ diff --git a/linux/gpio/gpioDefinitions.h b/linux/gpio/gpioDefinitions.h index 28ad1239..e4fb89bc 100644 --- a/linux/gpio/gpioDefinitions.h +++ b/linux/gpio/gpioDefinitions.h @@ -12,6 +12,17 @@ enum Direction { OUT = 1 }; +enum GpioOperation { + READ, + WRITE +}; + +enum GpioTypes { + NONE, + GPIOD_REGULAR, + CALLBACK +}; + static constexpr gpioId_t NO_GPIO = -1; } @@ -29,23 +40,52 @@ static constexpr gpioId_t NO_GPIO = -1; * @param lineHandle The handle returned by gpiod_chip_get_line will be later written to this * pointer. */ -typedef struct GpioConfig { - GpioConfig(): chipname(), lineNum(0), consumer(), direction(gpio::Direction::OUT), - initValue(0) {}; +class GpioBase { +public: - GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, - gpio::Direction direction_, int initValue_): - chipname(chipname_), lineNum(lineNum_), consumer(consumer_), - direction(direction_), initValue(initValue_) {} - std::string chipname; - int lineNum; + GpioBase() = default; + + GpioBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction, + int initValue): + gpioType(gpioType), consumer(consumer),direction(direction), initValue(initValue) {} + + virtual~ GpioBase() {}; + + /* Can be used to cast GpioBase to a concrete child implementation */ + gpio::GpioTypes gpioType = gpio::GpioTypes::NONE; std::string consumer; - gpio::Direction direction; - int initValue; - struct gpiod_line* lineHandle = nullptr; -} GpioConfig_t; + gpio::Direction direction = gpio::Direction::IN; + int initValue = 0; +}; -using GpioMap = std::unordered_map; +class GpiodRegular: public GpioBase { +public: + GpiodRegular(): GpioBase() {}; + + GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_, + gpio::Direction direction_, int initValue_): + GpioBase(gpio::GpioTypes::GPIOD_REGULAR, consumer_, direction_, initValue_), + chipname(chipname_), lineNum(lineNum_) {} + std::string chipname; + int lineNum = 0; + struct gpiod_line* lineHandle = nullptr; +}; + +class GpioCallback: public GpioBase { +public: + GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_, + void (* callback) (gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args), + void* callbackArgs): + GpioBase(gpio::GpioTypes::CALLBACK, consumer, direction_, initValue_), + callback(callback), callbackArgs(callbackArgs) {} + + void (* callback) (gpioId_t gpioId, gpio::GpioOperation gpioOp, + int value, void* args) = nullptr; + void* callbackArgs = nullptr; +}; + + +using GpioMap = std::unordered_map; using GpioMapIter = GpioMap::iterator; #endif /* LINUX_GPIO_GPIODEFINITIONS_H_ */ diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index a78478e5..5ce1558a 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -39,7 +39,7 @@ ReturnValue_t SolarArrayDeploymentHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - result = gpioInterface->initialize(dynamic_cast(gpioCookie)); + result = gpioInterface->addGpios(dynamic_cast(gpioCookie)); if (result != RETURN_OK) { sif::error << "SolarArrayDeploymentHandler::initialize: Failed to initialize Gpio interface" << std::endl; From ec70443056d75ce65cd500b30193e9573f727875 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:27:02 +0100 Subject: [PATCH 24/51] bugfix --- linux/gpio/gpioDefinitions.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux/gpio/gpioDefinitions.h b/linux/gpio/gpioDefinitions.h index e4fb89bc..3b0f70fd 100644 --- a/linux/gpio/gpioDefinitions.h +++ b/linux/gpio/gpioDefinitions.h @@ -60,7 +60,8 @@ public: class GpiodRegular: public GpioBase { public: - GpiodRegular(): GpioBase() {}; + GpiodRegular(): GpioBase(gpio::GpioTypes::GPIOD_REGULAR, std::string(), + gpio::Direction::IN, 0) {}; GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_, gpio::Direction direction_, int initValue_): From 9e74126e07b1535ea1c90999d69d3e17d5a134d0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:33:12 +0100 Subject: [PATCH 25/51] printf supportt --- linux/spi/SpiComIF.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index ebcf7991..25dd5ad5 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -188,8 +188,14 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s else { /* We write with a blocking transfer here */ if (write(fileDescriptor, sendData, sendLen) != static_cast(sendLen)) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << std::endl; +#else + sif::printWarning("SpiComIF::sendMessage: Half-Duplex write operation failed!\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ result = HALF_DUPLEX_TRANSFER_FAILED; } } @@ -238,7 +244,13 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLe } if(read(fileDescriptor, rxBuf, readSize) != static_cast(readSize)) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "SpiComIF::sendMessage: Half-Duplex read operation failed!" << std::endl; +#else + sif::printWarning("SpiComIF::sendMessage: Half-Duplex read operation failed!\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ result = HALF_DUPLEX_TRANSFER_FAILED; } From 56a982255cbc07356dee30f6ba8571b921c8df7b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:34:02 +0100 Subject: [PATCH 26/51] cleaned up includes --- linux/spi/SpiComIF.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index 25dd5ad5..cc2d9288 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -1,16 +1,18 @@ #include "SpiComIF.h" #include "spiDefinitions.h" +#include #include + #include +#include + +#include #include #include #include -#include -#include -#include -#include +#include #include SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(objectId), From 603a22409457cf95d04629cdf6bc88214e7943e5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:34:34 +0100 Subject: [PATCH 27/51] deleted unused code --- linux/spi/SpiComIF.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/linux/spi/SpiComIF.h b/linux/spi/SpiComIF.h index b91dd479..e454db21 100644 --- a/linux/spi/SpiComIF.h +++ b/linux/spi/SpiComIF.h @@ -54,19 +54,7 @@ private: SpiDeviceMap spiDeviceMap; -// /** -// * @brief This function opens an SPI device and binds the opened file -// * to a specific SPI address. -// * @param deviceFile The name of the device file. E.g. spi-0 -// * @param i2cAddress The address of the SPI slave device. -// * @param fileDescriptor Pointer to device descriptor. -// * @return RETURN_OK if successful, otherwise RETURN_FAILED. -// */ -// ReturnValue_t openDevice(std::string deviceFile, int* fileDescriptor, bool nonBlocking = false); - ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); }; - - #endif /* LINUX_SPI_SPICOMIF_H_ */ From d4f0ad5af2cec9c97d8dc2ddab3aef1bc4d0e3e7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:38:43 +0100 Subject: [PATCH 28/51] small fixes for Q7S --- bsp_q7s/ObjectFactory.cpp | 20 +++++++++---------- bsp_q7s/devices/HeaterHandler.cpp | 2 +- .../devices/SolarArrayDeploymentHandler.cpp | 14 +++++++------ mission/devices/SolarArrayDeploymentHandler.h | 2 +- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index 1a54ca34..d69683ef 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -119,37 +119,37 @@ void ObjectFactory::produce(){ new LinuxLibgpioIF(objects::GPIO_IF); #if TE0720 == 0 /* Pin H2-11 on stack connector */ - GpioConfig_t gpioConfigHeater0(std::string("gpiochip7"), 18, + GpiodRegular gpioConfigHeater0(std::string("gpiochip7"), 18, std::string("Heater0"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigHeater0); /* Pin H2-12 on stack connector */ - GpioConfig_t gpioConfigHeater1(std::string("gpiochip7"), 14, + GpiodRegular gpioConfigHeater1(std::string("gpiochip7"), 14, std::string("Heater1"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_1, gpioConfigHeater1); /* Pin H2-13 on stack connector */ - GpioConfig_t gpioConfigHeater2(std::string("gpiochip7"), 20, + GpiodRegular gpioConfigHeater2(std::string("gpiochip7"), 20, std::string("Heater2"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_2, gpioConfigHeater2); - GpioConfig_t gpioConfigHeater3(std::string("gpiochip7"), 16, + GpiodRegular gpioConfigHeater3(std::string("gpiochip7"), 16, std::string("Heater3"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_3, gpioConfigHeater3); - GpioConfig_t gpioConfigHeater4(std::string("gpiochip7"), 24, + GpiodRegular gpioConfigHeater4(std::string("gpiochip7"), 24, std::string("Heater4"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_4, gpioConfigHeater4); - GpioConfig_t gpioConfigHeater5(std::string("gpiochip7"), 26, + GpiodRegular gpioConfigHeater5(std::string("gpiochip7"), 26, std::string("Heater5"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_5, gpioConfigHeater5); - GpioConfig_t gpioConfigHeater6(std::string("gpiochip7"), 22, + GpiodRegular gpioConfigHeater6(std::string("gpiochip7"), 22, std::string("Heater6"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_6, gpioConfigHeater6); - GpioConfig_t gpioConfigHeater7(std::string("gpiochip7"), 28, + GpiodRegular gpioConfigHeater7(std::string("gpiochip7"), 28, std::string("Heater7"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpioConfigHeater7); @@ -157,10 +157,10 @@ void ObjectFactory::produce(){ pcduSwitches::TCS_BOARD_8V_HEATER_IN); GpioCookie* solarArrayDeplCookie = new GpioCookie; - GpioConfig_t gpioConfigDeplSA1(std::string("gpiochip7"), 25, + GpiodRegular gpioConfigDeplSA1(std::string("gpiochip7"), 25, std::string("DeplSA1"), gpio::OUT, 0); solarArrayDeplCookie->addGpio(gpioIds::DEPLSA1, gpioConfigDeplSA1); - GpioConfig_t gpioConfigDeplSA2(std::string("gpiochip7"), 23, + GpiodRegular gpioConfigDeplSA2(std::string("gpiochip7"), 23, std::string("DeplSA2"), gpio::OUT, 0); solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpioConfigDeplSA2); diff --git a/bsp_q7s/devices/HeaterHandler.cpp b/bsp_q7s/devices/HeaterHandler.cpp index 2387ab2a..ccf5b65c 100644 --- a/bsp_q7s/devices/HeaterHandler.cpp +++ b/bsp_q7s/devices/HeaterHandler.cpp @@ -43,7 +43,7 @@ ReturnValue_t HeaterHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - result = gpioInterface->initialize(dynamic_cast(gpioCookie)); + result = gpioInterface->addGpios(dynamic_cast(gpioCookie)); if (result != RETURN_OK) { sif::error << "HeaterHandler::initialize: Failed to initialize Gpio interface" << std::endl; return ObjectManagerIF::CHILD_INIT_FAILED; diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 5ce1558a..c114209b 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -1,15 +1,17 @@ -#include -#include -#include +#include #include + +#include #include +#include + SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_, object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, uint8_t mainLineSwitch_, gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs) : - SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), mainLineSwitcherObjectId( - mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), deplSA1(deplSA1), deplSA2( - deplSA2), burnTimeMs(burnTimeMs), actionHelper(this, nullptr) { + SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), + mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), + deplSA1(deplSA1), deplSA2(deplSA2), burnTimeMs(burnTimeMs), actionHelper(this, nullptr) { commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 279ae5da..f885928b 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -115,7 +115,7 @@ private: gpioId_t deplSA1; gpioId_t deplSA2; - GpioIF* gpioInterface; + GpioIF* gpioInterface = nullptr; /** Time duration switches are active to cut the burn wire */ uint32_t burnTimeMs; From a3b9c2d25d50b10ae60f07b87fdfb923ebe2157b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:39:01 +0100 Subject: [PATCH 29/51] redordered includes --- mission/devices/SolarArrayDeploymentHandler.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index f885928b..b7e94f23 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -1,6 +1,8 @@ #ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ #define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ +#include + #include #include #include @@ -9,7 +11,7 @@ #include #include #include -#include + #include /** From 7654e6cf20e07af9159a9b79cdcd98626e195bcc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 14:41:40 +0100 Subject: [PATCH 30/51] fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index a3d245f5..8eb25c02 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit a3d245f5a030c9450c516552283d26da2c799301 +Subproject commit 8eb25c02aa278bda46d0c3769500bddbddc989f5 From f17e983cad7e09202a3381adeac43b4e7559549b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 14:41:57 +0100 Subject: [PATCH 31/51] fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 8eb25c02..c55cf8f2 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 8eb25c02aa278bda46d0c3769500bddbddc989f5 +Subproject commit c55cf8f2796026818841266b78f3b6ad37aba3c8 From c36727bd3dc9d3945417b7cdf26eca446f48a56a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 14:44:16 +0100 Subject: [PATCH 32/51] libgpiod test --- linux/boardtest/LibgpiodTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index 99602107..d085671a 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -58,7 +58,7 @@ ReturnValue_t LibgpiodTest::performOneShotAction() { case(TestCases::LOOPBACK): { result = gpioInterface->pullHigh(gpioIds::TEST_ID_0); if(result == HasReturnvaluesIF::RETURN_OK) { - sif::info << "LibgpiodTest::performOneShotAction:" + sif::info << "LibgpiodTest::performOneShotAction: " "GPIO pulled high successfully for loopback test" << std::endl; } else { @@ -68,7 +68,7 @@ ReturnValue_t LibgpiodTest::performOneShotAction() { } result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState); if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 1) { - sif::info << "LibgpiodTest::performOneShotAction:" + sif::info << "LibgpiodTest::performOneShotAction: " "GPIO state read successfully and is high" << std::endl; } else { @@ -79,12 +79,12 @@ ReturnValue_t LibgpiodTest::performOneShotAction() { result = gpioInterface->pullLow(gpioIds::TEST_ID_0); if(result == HasReturnvaluesIF::RETURN_OK) { - sif::info << "LibgpiodTest::performOneShotAction:" + sif::info << "LibgpiodTest::performOneShotAction: " "GPIO pulled low successfully for loopback test" << std::endl; } result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState); if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 0) { - sif::info << "LibgpiodTest::performOneShotAction:" + sif::info << "LibgpiodTest::performOneShotAction: " "GPIO state read successfully and is low" << std::endl; } else { From bb04d4fb4c1c86dedca4ad80df31b1a9418d982a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 14:47:38 +0100 Subject: [PATCH 33/51] fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index c55cf8f2..91f69aa3 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit c55cf8f2796026818841266b78f3b6ad37aba3c8 +Subproject commit 91f69aa34fcdde9d3f6ae1a71e72a084bf3bc49d From ddabbd6e3b6fdf3bb8ac1799a0338e7a92bdf512 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 16:47:34 +0100 Subject: [PATCH 34/51] gpio bugfix --- bsp_rpi/ObjectFactory.cpp | 4 +- fsfwconfig/devices/gpioIds.h | 9 ++++ linux/boardtest/SpiTestClass.cpp | 87 +++++++++++++++++++++++++++++++- linux/boardtest/SpiTestClass.h | 34 ++++++++++++- linux/gpio/LinuxLibgpioIF.cpp | 79 ++++++++++++++++++++++------- linux/gpio/LinuxLibgpioIF.h | 5 +- 6 files changed, 193 insertions(+), 25 deletions(-) diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index 01552be8..5546a1b5 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -51,10 +51,10 @@ void ObjectFactory::produce(){ objects::TM_STORE, objects::TC_STORE); new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); - new LinuxLibgpioIF(objects::GPIO_IF); + GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF); #if RPI_ADD_SPI_TEST == 1 - new SpiTestClass(objects::SPI_TEST); + new SpiTestClass(objects::SPI_TEST, gpioIF); #endif #if RPI_LOOPBACK_TEST_GPIO == 1 diff --git a/fsfwconfig/devices/gpioIds.h b/fsfwconfig/devices/gpioIds.h index 1e95ab9d..8963bd20 100644 --- a/fsfwconfig/devices/gpioIds.h +++ b/fsfwconfig/devices/gpioIds.h @@ -15,6 +15,15 @@ namespace gpioIds { HEATER_7, DEPLSA1, DEPLSA2, + + MGM_0_LIS3_CS, + MGM_1_RM3100_CS, + GYRO_0_ADIS_CS, + GYRO_1_L3G_CS, + GYRO_2_L3G_CS, + MGM_2_LIS3_CS, + MGM_3_RM3100_CS, + TEST_ID_0, TEST_ID_1 }; diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index daf38749..a0006b7d 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -1,8 +1,91 @@ -#include +#include "SpiTestClass.h" -SpiTestClass::SpiTestClass(object_id_t objectId): TestTask(objectId) { +#include +#include + +#include +#include +#include +#include +#include +#include + + +SpiTestClass::SpiTestClass(object_id_t objectId, GpioIF* gpioIF): TestTask(objectId), + gpioIF(gpioIF) { + if(gpioIF == nullptr) { + sif::error << "SpiTestClass::SpiTestClass: Invalid GPIO ComIF!" << std::endl; + } + testMode = TestModes::MGM_RM3100; + spiTransferStruct.rx_buf = reinterpret_cast<__u64>(recvBuffer.data()); + spiTransferStruct.tx_buf = reinterpret_cast<__u64>(sendBuffer.data()); +} + +ReturnValue_t SpiTestClass::performOneShotAction() { + switch(testMode) { + case(TestModes::MGM_LIS3MDL): { + break; + } + case(TestModes::MGM_RM3100): { + performRm3100Test(); + break; + } + case(TestModes::GYRO_L3GD20H): { + break; + } + } + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t SpiTestClass::performPeriodicAction() { return HasReturnvaluesIF::RETURN_OK; } + +void SpiTestClass::performRm3100Test() { + /* Adapt accordingly */ + uint8_t chipSelectPin = mgm1Rm3100ChipSelect; + acsInit(); +} + +void SpiTestClass::acsInit() { + GpioCookie* gpioCookie = new GpioCookie(); + std::string rpiGpioName = "gpiochip0"; + { + GpiodRegular gpio(rpiGpioName.c_str(), mgm0Lis3ChipSelect, "MGM_0_LIS3", + gpio::Direction::OUT, 1); + gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio); + } + { + GpiodRegular gpio(rpiGpioName.c_str(), mgm1Rm3100ChipSelect, "MGM_1_RM3100", + gpio::Direction::OUT, 1); + gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio); + } + { + GpiodRegular gpio(rpiGpioName.c_str(), gyro0AdisChipSelect, "GYRO_0_ADIS", + gpio::Direction::OUT, 1); + gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio); + } + { + GpiodRegular gpio(rpiGpioName.c_str(), gyro1L3gd20ChipSelect, "GYRO_1_L3G", + gpio::Direction::OUT, 1); + gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio); + } + { + GpiodRegular gpio(rpiGpioName.c_str(), gyro2L3gd20ChipSelect, "GYRO_2_L3G", + gpio::Direction::OUT, 1); + gpioCookie->addGpio(gpioIds::GYRO_2_L3G_CS, gpio); + } + { + GpiodRegular gpio(rpiGpioName.c_str(), mgm2Lis3mdlChipSelect, "MGM_2_LIS3", + gpio::Direction::OUT, 1); + gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio); + } + { + GpiodRegular gpio(rpiGpioName.c_str(), mgm3Rm3100ChipSelect, "MGM_3_RM3100", + gpio::Direction::OUT, 1); + gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); + } + if(gpioIF != nullptr) { + gpioIF->addGpios(gpioCookie); + } +} diff --git a/linux/boardtest/SpiTestClass.h b/linux/boardtest/SpiTestClass.h index b3f10222..9ca9f963 100644 --- a/linux/boardtest/SpiTestClass.h +++ b/linux/boardtest/SpiTestClass.h @@ -1,15 +1,47 @@ #ifndef LINUX_BOARDTEST_SPITESTCLASS_H_ #define LINUX_BOARDTEST_SPITESTCLASS_H_ +#include +#include #include +#include + class SpiTestClass: public TestTask { public: - SpiTestClass(object_id_t objectId); + enum TestModes { + MGM_LIS3MDL, + MGM_RM3100, + GYRO_L3GD20H, + }; + TestModes testMode; + + SpiTestClass(object_id_t objectId, GpioIF* gpioIF); + + ReturnValue_t performOneShotAction() override; ReturnValue_t performPeriodicAction() override; private: + GpioIF* gpioIF; + + std::array recvBuffer; + std::array sendBuffer; + struct spi_ioc_transfer spiTransferStruct; + + void performRm3100Test(); + /* ACS board specific code which pulls all GPIOs high */ + void acsInit(); + + /* ACS board specific variables */ + uint8_t mgm0Lis3ChipSelect = 0; + uint8_t mgm1Rm3100ChipSelect = 1; + uint8_t gyro0AdisChipSelect = 5; + uint8_t gyro1L3gd20ChipSelect = 6; + uint8_t gyro2L3gd20ChipSelect = 4; + uint8_t mgm2Lis3mdlChipSelect = 17; + uint8_t mgm3Rm3100ChipSelect = 27; + }; diff --git a/linux/gpio/LinuxLibgpioIF.cpp b/linux/gpio/LinuxLibgpioIF.cpp index 0cf3858f..85bc59ac 100644 --- a/linux/gpio/LinuxLibgpioIF.cpp +++ b/linux/gpio/LinuxLibgpioIF.cpp @@ -24,6 +24,7 @@ ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) { GpioMap mapToAdd = gpioCookie->getGpioMap(); + /* Check whether this ID already exists in the map and remove duplicates */ result = checkForConflicts(mapToAdd); if (result != RETURN_OK){ return result; @@ -48,6 +49,9 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { } case(gpio::GpioTypes::GPIOD_REGULAR): { GpiodRegular* regularGpio = dynamic_cast(gpioConfig.second); + if(regularGpio == nullptr) { + return GPIO_INVALID_INSTANCE; + } configureRegularGpio(gpioConfig.first, regularGpio); break; } @@ -57,7 +61,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { return GPIO_INVALID_INSTANCE; } gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::READ, - 0, gpioCallback->callbackArgs); + gpioCallback->initValue, gpioCallback->callbackArgs); } } } @@ -219,7 +223,20 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ if(regularGpio == nullptr) { return GPIO_TYPE_FAILURE; } - result = checkForConflictsRegularGpio(gpioConfig.first, regularGpio); + /* Check for conflicts and remove duplicates if necessary */ + result = checkForConflictsRegularGpio(gpioConfig.first, regularGpio, mapToAdd); + if(result != HasReturnvaluesIF::RETURN_OK) { + status = result; + } + break; + } + case(gpio::GpioTypes::CALLBACK): { + auto callbackGpio = dynamic_cast(gpioConfig.second); + if(callbackGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + /* Check for conflicts and remove duplicates if necessary */ + result = checkForConflictsCallbackGpio(gpioConfig.first, callbackGpio, mapToAdd); if(result != HasReturnvaluesIF::RETURN_OK) { status = result; } @@ -235,29 +252,53 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck, - GpiodRegular* gpioToCheck) { + GpiodRegular* gpioToCheck, GpioMap& mapToAdd) { /* Cross check with private map */ gpioMapIter = gpioMap.find(gpioIdToCheck); if(gpioMapIter != gpioMap.end()) { - if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { - auto ownRegularGpio = dynamic_cast(gpioMapIter->second); - if(ownRegularGpio == nullptr) { - return GPIO_TYPE_FAILURE; - } - /* An entry for this GPIO already exists. Check if configuration - * of direction is equivalent */ - if (gpioToCheck->direction != ownRegularGpio->direction){ - sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict for GPIO " << - gpioIdToCheck << std::endl; - return RETURN_FAILED; - - } + if(gpioMapIter->second->gpioType != gpio::GpioTypes::GPIOD_REGULAR) { + 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); + if(ownRegularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + /* An entry for this GPIO already exists. Check if configuration + * of direction is equivalent */ + if (gpioToCheck->direction != ownRegularGpio->direction) { + sif::warning << "LinuxLibgpioIF::checkForConflicts: Detected conflict for GPIO " << + gpioIdToCheck << std::endl; } /* Remove element from map to add because a entry for this GPIO - * already exists */ - gpioMap.erase(gpioIdToCheck); - + already exists */ + sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition" + << " detected. Duplicate will be removed from map to add." << std::endl; + mapToAdd.erase(gpioIdToCheck); + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t LinuxLibgpioIF::checkForConflictsCallbackGpio(gpioId_t gpioIdToCheck, + GpioCallback *callbackGpio, GpioMap& mapToAdd) { + /* Cross check with private map */ + gpioMapIter = gpioMap.find(gpioIdToCheck); + if(gpioMapIter != gpioMap.end()) { + if(gpioMapIter->second->gpioType != gpio::GpioTypes::CALLBACK) { + sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different " + "GPIO type" << gpioIdToCheck << ". Removing duplicate." << std::endl; + mapToAdd.erase(gpioIdToCheck); + return HasReturnvaluesIF::RETURN_OK; + } + + /* Remove element from map to add because a entry for this GPIO + already exists */ + sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition" + << " detected. Duplicate will be removed from map to add." << std::endl; + mapToAdd.erase(gpioIdToCheck); } return HasReturnvaluesIF::RETURN_OK; } diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index 287e157d..a5015999 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -62,7 +62,10 @@ private: */ ReturnValue_t checkForConflicts(GpioMap& mapToAdd); - ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegular* regularGpio); + ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegular* regularGpio, + GpioMap& mapToAdd); + ReturnValue_t checkForConflictsCallbackGpio(gpioId_t gpiodId, GpioCallback* regularGpio, + GpioMap& mapToAdd); /** * @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd. From 981f988eed74ac6a0a8da3ab62b895d85c2e0cb3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 16:58:22 +0100 Subject: [PATCH 35/51] more bugfixes --- linux/boardtest/SpiTestClass.cpp | 21 +++++++++++++++++++++ linux/spi/SpiComIF.cpp | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index a0006b7d..537709fb 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,26 @@ ReturnValue_t SpiTestClass::performPeriodicAction() { void SpiTestClass::performRm3100Test() { /* Adapt accordingly */ uint8_t chipSelectPin = mgm1Rm3100ChipSelect; + uint32_t rm3100Speed = 3'900'000; + int rm3100mode = SPI_MODE_3; +#ifdef RASPBERRY_PI + std::string deviceName = "spidev0.0"; +#else +#endif + int fileDescriptor = 0; + + utility::UnixFileHelper fileHelper(deviceName, &fileDescriptor, O_RDWR, + "SpiComIF::initializeInterface: "); + if(fileHelper.getOpenResult()) { + sif::error << "SpiTestClass::performRm3100Test: File descriptor could not be opened!" + << std::endl; + return; + } + + int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, rm3100Speed); + if(retval != 0) { + utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!"); + } acsInit(); } diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index cc2d9288..7d5a5848 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -88,7 +88,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { return fileHelper.getOpenResult(); } - int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, spiSpeed); + int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, static_cast(spiMode)); if(retval != 0) { utility::handleIoctlError("SpiComIF::initializeInterface: Setting SPI mode failed!"); } From 71b9b460e183ba2a1575122f2df6582f20004618 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 17:01:25 +0100 Subject: [PATCH 36/51] continued test task --- linux/boardtest/SpiTestClass.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index 537709fb..f3baa778 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -43,9 +43,13 @@ ReturnValue_t SpiTestClass::performPeriodicAction() { } void SpiTestClass::performRm3100Test() { + /* Configure all SPI chip selects and pull them high */ + acsInit(); + /* Adapt accordingly */ uint8_t chipSelectPin = mgm1Rm3100ChipSelect; uint32_t rm3100Speed = 3'900'000; + uint8_t rm3100whoAmIReg = 0b0000'1111; int rm3100mode = SPI_MODE_3; #ifdef RASPBERRY_PI std::string deviceName = "spidev0.0"; @@ -61,11 +65,16 @@ void SpiTestClass::performRm3100Test() { return; } - int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, rm3100Speed); + int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, rm3100mode); if(retval != 0) { utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!"); } - acsInit(); + + retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, rm3100Speed); + if(retval != 0) { + utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!"); + } + } void SpiTestClass::acsInit() { From cfa76499ada255d6ed84a8e016af245443f7890b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 17:05:48 +0100 Subject: [PATCH 37/51] continued test class --- linux/boardtest/SpiTestClass.cpp | 17 +++++++++++++++-- linux/boardtest/SpiTestClass.h | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index f3baa778..1065a2f4 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -42,12 +42,22 @@ ReturnValue_t SpiTestClass::performPeriodicAction() { return HasReturnvaluesIF::RETURN_OK; } -void SpiTestClass::performRm3100Test() { +void SpiTestClass::performRm3100Test(uint8_t mgmId) { /* Configure all SPI chip selects and pull them high */ acsInit(); /* Adapt accordingly */ - uint8_t chipSelectPin = mgm1Rm3100ChipSelect; + if(mgmId != mgm1Rm3100ChipSelect or mgmId != mgm3Rm3100ChipSelect) { + sif::warning << "SpiTestClass::performRm3100Test: Invalid MGM ID!" << std::endl; + } + gpioId_t currentGpioId = 0; + uint8_t chipSelectPin = mgmId; + if(chipSelectPin == mgm1Rm3100ChipSelect) { + currentGpioId = gpioIds::MGM_1_RM3100_CS; + } + else { + currentGpioId = gpioIds::MGM_3_RM3100_CS; + } uint32_t rm3100Speed = 3'900'000; uint8_t rm3100whoAmIReg = 0b0000'1111; int rm3100mode = SPI_MODE_3; @@ -75,6 +85,9 @@ void SpiTestClass::performRm3100Test() { utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!"); } + gpioIF->pullLow(currentGpioId); + + } void SpiTestClass::acsInit() { diff --git a/linux/boardtest/SpiTestClass.h b/linux/boardtest/SpiTestClass.h index 9ca9f963..7a7c5f4c 100644 --- a/linux/boardtest/SpiTestClass.h +++ b/linux/boardtest/SpiTestClass.h @@ -29,7 +29,7 @@ private: std::array sendBuffer; struct spi_ioc_transfer spiTransferStruct; - void performRm3100Test(); + void performRm3100Test(uint8_t mgmId); /* ACS board specific code which pulls all GPIOs high */ void acsInit(); From 048b239b926edfb1b92c253e65e9a1163099a81e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 18:01:28 +0100 Subject: [PATCH 38/51] spi bugfixes --- linux/boardtest/SpiTestClass.cpp | 89 +++++++++++++++++++++++++------- linux/boardtest/SpiTestClass.h | 8 +++ linux/spi/SpiComIF.cpp | 10 ++-- linux/utility/Utility.cpp | 2 +- 4 files changed, 84 insertions(+), 25 deletions(-) diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index 1065a2f4..050f9f15 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -10,6 +10,7 @@ #include #include #include +#include SpiTestClass::SpiTestClass(object_id_t objectId, GpioIF* gpioIF): TestTask(objectId), @@ -28,7 +29,7 @@ ReturnValue_t SpiTestClass::performOneShotAction() { break; } case(TestModes::MGM_RM3100): { - performRm3100Test(); + performRm3100Test(mgm1Rm3100ChipSelect); break; } case(TestModes::GYRO_L3GD20H): { @@ -47,7 +48,7 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) { acsInit(); /* Adapt accordingly */ - if(mgmId != mgm1Rm3100ChipSelect or mgmId != mgm3Rm3100ChipSelect) { + if(mgmId != mgm1Rm3100ChipSelect and mgmId != mgm3Rm3100ChipSelect) { sif::warning << "SpiTestClass::performRm3100Test: Invalid MGM ID!" << std::endl; } gpioId_t currentGpioId = 0; @@ -58,15 +59,18 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) { else { currentGpioId = gpioIds::MGM_3_RM3100_CS; } - uint32_t rm3100Speed = 3'900'000; - uint8_t rm3100whoAmIReg = 0b0000'1111; - int rm3100mode = SPI_MODE_3; + uint32_t rm3100speed = 3'900'000; + uint8_t rm3100revidReg = 0x36; + spi::SpiMode rm3100mode = spi::SpiMode::MODE_3; + //spiTransferStruct.speed_hz = rm3100Speed; #ifdef RASPBERRY_PI - std::string deviceName = "spidev0.0"; + std::string deviceName = "/dev/spidev0.0"; #else + std::string deviceName = "placeholder"; #endif int fileDescriptor = 0; + utility::UnixFileHelper fileHelper(deviceName, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface: "); if(fileHelper.getOpenResult()) { @@ -74,20 +78,11 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) { << std::endl; return; } + setSpiSpeedAndMode(fileDescriptor, rm3100mode, rm3100speed); - int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, rm3100mode); - if(retval != 0) { - utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!"); - } - - retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, rm3100Speed); - if(retval != 0) { - utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!"); - } - - gpioIF->pullLow(currentGpioId); - - + uint8_t revId = readStmRegister(fileDescriptor, currentGpioId, rm3100revidReg, false); + sif::info << "SpiTestClass::performRm3100Test: Revision ID 0b" << std::bitset<8>(revId) << + std::endl; } void SpiTestClass::acsInit() { @@ -132,3 +127,59 @@ void SpiTestClass::acsInit() { gpioIF->addGpios(gpioCookie); } } + +void SpiTestClass::writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value, + bool autoIncrement) { + if(autoIncrement) { + reg |= STM_AUTO_INCR_MASK; + } + spiTransferStruct.len = 2; + sendBuffer[0] = reg; + sendBuffer[1] = value; + + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullLow(chipSelect); + } + int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct); + if(retval != 0) { + utility::handleIoctlError("SpiTestClass::writeStmRegister: Write failed"); + } + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullHigh(chipSelect); + } +} + +void SpiTestClass::setSpiSpeedAndMode(int spiFd, spi::SpiMode 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!"); + } + + retval = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + if(retval != 0) { + utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!"); + } +} + +uint8_t SpiTestClass::readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, + bool autoIncrement) { + reg |= STM_READ_MASK; + if(autoIncrement) { + reg |= STM_AUTO_INCR_MASK; + } + spiTransferStruct.len = 2; + sendBuffer[0] = reg; + sendBuffer[1] = 0; + + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullLow(chipSelect); + } + int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct); + if(retval < 0) { + utility::handleIoctlError("SpiTestClass::readStmRegiste: Read failed"); + } + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullHigh(chipSelect); + } + return recvBuffer[1]; +} diff --git a/linux/boardtest/SpiTestClass.h b/linux/boardtest/SpiTestClass.h index 7a7c5f4c..c15a3fab 100644 --- a/linux/boardtest/SpiTestClass.h +++ b/linux/boardtest/SpiTestClass.h @@ -42,6 +42,14 @@ private: uint8_t mgm2Lis3mdlChipSelect = 17; uint8_t mgm3Rm3100ChipSelect = 27; + static constexpr uint8_t STM_READ_MASK = 0b1000'0000; + static constexpr uint8_t STM_AUTO_INCR_MASK = 0b0100'0000; + + void setSpiSpeedAndMode(int spiFd, spi::SpiMode mode, uint32_t speed); + void writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value, + bool autoIncrement); + uint8_t readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, bool autoIncrement); + }; diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index 7d5a5848..b656ac2d 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -88,12 +88,12 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { return fileHelper.getOpenResult(); } - int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, static_cast(spiMode)); + int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, reinterpret_cast(&spiMode)); if(retval != 0) { utility::handleIoctlError("SpiComIF::initializeInterface: Setting SPI mode failed!"); } - retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, spiSpeed); + retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed); if(retval != 0) { utility::handleIoctlError("SpiComIF::initializeInterface: Setting SPI speed failed!"); } @@ -117,19 +117,19 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { currentMode |= SPI_CS_HIGH; } /* Write adapted mode */ - retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE32, currentMode); + retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE32, ¤tMode); if(retval != 0) { utility::handleIoctlError("SpiComIF::initialiezInterface: Could not write full mode!"); } } if(params.lsbFirst) { - retval = ioctl(fileDescriptor, SPI_IOC_WR_LSB_FIRST, true); + retval = ioctl(fileDescriptor, SPI_IOC_WR_LSB_FIRST, ¶ms.lsbFirst); if(retval != 0) { utility::handleIoctlError("SpiComIF::initializeInterface: Setting LSB first failed"); } } if(params.bitsPerWord != 8) { - retval = ioctl(fileDescriptor, SPI_IOC_WR_BITS_PER_WORD, params.bitsPerWord); + retval = ioctl(fileDescriptor, SPI_IOC_WR_BITS_PER_WORD, ¶ms.bitsPerWord); if(retval != 0) { utility::handleIoctlError("SpiComIF::initializeInterface: " "Could not write bits per word!"); diff --git a/linux/utility/Utility.cpp b/linux/utility/Utility.cpp index 8f1ca912..45c347db 100644 --- a/linux/utility/Utility.cpp +++ b/linux/utility/Utility.cpp @@ -20,7 +20,7 @@ void utility::handleIoctlError(const char* const customPrintout) { utility::UnixFileHelper::UnixFileHelper(std::string device, int* fileDescriptor, int flags, std::string diagnosticPrefix): - fileDescriptor(fileDescriptor) { + fileDescriptor(fileDescriptor) { if(fileDescriptor == nullptr) { return; } From e32de64f2130844d5ee46de02b64ace9fb605768 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 18:14:23 +0100 Subject: [PATCH 39/51] removed obsolete printout --- linux/gpio/LinuxLibgpioIF.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/linux/gpio/LinuxLibgpioIF.cpp b/linux/gpio/LinuxLibgpioIF.cpp index 85bc59ac..7f6be6c5 100644 --- a/linux/gpio/LinuxLibgpioIF.cpp +++ b/linux/gpio/LinuxLibgpioIF.cpp @@ -266,12 +266,6 @@ ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToChec if(ownRegularGpio == nullptr) { return GPIO_TYPE_FAILURE; } - /* An entry for this GPIO already exists. Check if configuration - * of direction is equivalent */ - if (gpioToCheck->direction != ownRegularGpio->direction) { - sif::warning << "LinuxLibgpioIF::checkForConflicts: Detected conflict for GPIO " << - gpioIdToCheck << std::endl; - } /* Remove element from map to add because a entry for this GPIO already exists */ From cd27b7e7c28d294fb537913b283a827180e9d4d1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 18:18:12 +0100 Subject: [PATCH 40/51] added stopwatch include --- linux/boardtest/SpiTestClass.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index 050f9f15..83b56629 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include From f67948524f89dbad246a9134bc6853e59980f094 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 18:19:11 +0100 Subject: [PATCH 41/51] disabled tests by default --- linux/boardtest/SpiTestClass.cpp | 5 ++++- linux/boardtest/SpiTestClass.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index 83b56629..be00ec75 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -19,13 +19,16 @@ SpiTestClass::SpiTestClass(object_id_t objectId, GpioIF* gpioIF): TestTask(objec if(gpioIF == nullptr) { sif::error << "SpiTestClass::SpiTestClass: Invalid GPIO ComIF!" << std::endl; } - testMode = TestModes::MGM_RM3100; + testMode = TestModes::NONE; spiTransferStruct.rx_buf = reinterpret_cast<__u64>(recvBuffer.data()); spiTransferStruct.tx_buf = reinterpret_cast<__u64>(sendBuffer.data()); } ReturnValue_t SpiTestClass::performOneShotAction() { switch(testMode) { + case(TestModes::NONE): { + break; + } case(TestModes::MGM_LIS3MDL): { break; } diff --git a/linux/boardtest/SpiTestClass.h b/linux/boardtest/SpiTestClass.h index c15a3fab..d4d946cd 100644 --- a/linux/boardtest/SpiTestClass.h +++ b/linux/boardtest/SpiTestClass.h @@ -10,6 +10,7 @@ class SpiTestClass: public TestTask { public: enum TestModes { + NONE, MGM_LIS3MDL, MGM_RM3100, GYRO_L3GD20H, From 43600962e6ffad4e200957c8b24479f47d8d1ac4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 22:07:39 +0100 Subject: [PATCH 42/51] testing mgm handler --- bsp_rpi/InitMission.cpp | 15 +- bsp_rpi/ObjectFactory.cpp | 41 +++++- bsp_rpi/boardconfig/rpi_config.h | 16 ++- fsfw | 2 +- fsfwconfig/devices/addresses.h | 18 ++- fsfwconfig/objects/systemObjectList.h | 12 +- .../PollingSequenceFactory.cpp | 133 ++++++++++-------- .../pollingsequence/PollingSequenceFactory.h | 2 + tmtc | 2 +- 9 files changed, 164 insertions(+), 77 deletions(-) diff --git a/bsp_rpi/InitMission.cpp b/bsp_rpi/InitMission.cpp index c31cbe22..c0f3e3ea 100644 --- a/bsp_rpi/InitMission.cpp +++ b/bsp_rpi/InitMission.cpp @@ -105,7 +105,7 @@ void initmission::initTasks() { } PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( - "PUS_HIGH_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); @@ -126,6 +126,15 @@ void initmission::initTasks() { initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); } +#if RPI_TEST_ACS_BOARD == 1 + FixedTimeslotTaskIF* acsTask = factory->createFixedTimeslotTask( + "ACS_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc); + result = pst::pollingSequenceAcsTest(acsTask); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "initmission::initTasks: ACS PST initialization failed!" << std::endl; + } +#endif /* RPI_TEST_ACS_BOARD == 1 */ + PeriodicTaskIF* testTask = factory->createPeriodicTask( "TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); #if OBSW_ADD_TEST_CODE == 1 @@ -161,5 +170,9 @@ void initmission::initTasks() { #if OBSW_ADD_TEST_CODE == 1 testTask->startTask(); #endif /* OBSW_ADD_TEST_CODE == 1 */ + +#if RPI_TEST_ACS_BOARD == 1 + acsTask->startTask(); +#endif /* RPI_TEST_ACS_BOARD == 1 */ sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index 5546a1b5..89d548dc 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -12,8 +13,11 @@ #include #include +#include + #include #include +#include #include #include @@ -22,6 +26,7 @@ #include #include #include +#include void Factory::setStaticFrameworkObjectIds() { PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; @@ -58,16 +63,44 @@ void ObjectFactory::produce(){ #endif #if RPI_LOOPBACK_TEST_GPIO == 1 - GpioCookie* gpioCookie = new GpioCookie(); + GpioCookie* gpioCookieLoopback = new GpioCookie(); /* Loopback pins. Adapt according to setup */ gpioId_t gpioIdSender = gpioIds::TEST_ID_0; int bcmPinSender = 26; gpioId_t gpioIdReader = gpioIds::TEST_ID_1; int bcmPinReader = 16; - gpio::createRpiGpioConfig(gpioCookie, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER", + gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER", gpio::Direction::OUT, 0); - gpio::createRpiGpioConfig(gpioCookie, gpioIdReader, bcmPinReader, "GPIO_LB_READER", + gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdReader, bcmPinReader, "GPIO_LB_READER", gpio::Direction::IN, 0); - new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); + new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookieLoopback); +#endif + + new SpiComIF(objects::SPI_COM_IF, gpioIF); + +#if RPI_TEST_ACS_BOARD == 1 + + GpioCookie* gpioCookieAcsBoard = new GpioCookie(); + gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_0_LIS3_CS, gpio::MGM_0_BCM_PIN, + "MGM_0_LIS3", gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_1_RM3100_CS, gpio::MGM_1_BCM_PIN, + "MGM_1_RM3100", gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_2_LIS3_CS, gpio::MGM_2_BCM_PIN, + "MGM_2_LIS3", gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_3_RM3100_CS, gpio::MGM_3_BCM_PIN, + "MGM_3_RM3100", gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN, + "GYRO_0_ADIS", gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::GYRO_1_L3G_CS, gpio::GYRO_1_BCM_PIN, + "GYRO_1_L3G", gpio::Direction::OUT, 1); + gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::GYRO_2_L3G_CS, gpio::GYRO_2_BCM_PIN, + "GYRO_2_L3G", gpio::Direction::OUT, 1); + gpioIF->addGpios(gpioCookieAcsBoard); + + SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, + gpioIds::MGM_0_LIS3_CS, "/dev/spidev0.0", 24, spi::SpiMode::MODE_3, 3'900'000); + auto mgmHandler = new MGMHandlerLIS3MDL(objects::MGM_0_LIS3_HANDLER, + objects::SPI_COM_IF, spiCookie); + mgmHandler->setStartUpImmediately(); #endif } diff --git a/bsp_rpi/boardconfig/rpi_config.h b/bsp_rpi/boardconfig/rpi_config.h index 89141b80..4326bd9e 100644 --- a/bsp_rpi/boardconfig/rpi_config.h +++ b/bsp_rpi/boardconfig/rpi_config.h @@ -1,10 +1,24 @@ #ifndef BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ #define BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ +#include + #define RPI_ADD_GPIO_TEST 1 -#define RPI_ADD_SPI_TEST 1 #define RPI_LOOPBACK_TEST_GPIO 1 +/* Only one of those 2 should be enabled! */ +#define RPI_ADD_SPI_TEST 0 +#define RPI_TEST_ACS_BOARD 1 +/* Adapt these values accordingly */ +namespace gpio { +static constexpr uint8_t MGM_0_BCM_PIN = 0; +static constexpr uint8_t MGM_1_BCM_PIN = 1; +static constexpr uint8_t MGM_2_BCM_PIN = 17; +static constexpr uint8_t MGM_3_BCM_PIN = 27; +static constexpr uint8_t GYRO_0_BCM_PIN = 5; +static constexpr uint8_t GYRO_1_BCM_PIN = 6; +static constexpr uint8_t GYRO_2_BCM_PIN = 4; +} #endif /* BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ */ diff --git a/fsfw b/fsfw index 91f69aa3..f3cc664d 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 91f69aa34fcdde9d3f6ae1a71e72a084bf3bc49d +Subproject commit f3cc664d4f9fdadc2f6e2ebf814dd0c924e5ae33 diff --git a/fsfwconfig/devices/addresses.h b/fsfwconfig/devices/addresses.h index c894fcc7..cd0b9d29 100644 --- a/fsfwconfig/devices/addresses.h +++ b/fsfwconfig/devices/addresses.h @@ -1,20 +1,24 @@ -/** - * \file addresses.cpp - * - * \date 07.11.2019 - */ - #ifndef FSFWCONFIG_DEVICES_ADDRESSES_H_ #define FSFWCONFIG_DEVICES_ADDRESSES_H_ -#include + #include #include +#include namespace addresses { /* Logical addresses have uint32_t datatype */ enum logicalAddresses: address_t { PCDU, + MGM_0_LIS3 = objects::MGM_0_LIS3_HANDLER, + MGM_1_RM3100 = objects::MGM_1_RM3100_HANDLER, + MGM_2_LIS3 = objects::MGM_2_LIS3_HANDLER, + MGM_3_RM3100 = objects::MGM_3_RM3100_HANDLER, + + GYRO_0_ADIS = objects::GYRO_0_ADIS_HANDLER, + GYRO_1_L3G = objects::GYRO_1_L3G_HANDLER, + GYRO_2_L3G = objects::GYRO_2_L3G_HANDLER, + /* Dummy and Test Addresses */ DUMMY_ECHO = 129, DUMMY_GPS0 = 130, diff --git a/fsfwconfig/objects/systemObjectList.h b/fsfwconfig/objects/systemObjectList.h index 153b3155..459cbd77 100644 --- a/fsfwconfig/objects/systemObjectList.h +++ b/fsfwconfig/objects/systemObjectList.h @@ -30,6 +30,7 @@ namespace objects { ARDUINO_COM_IF = 0x49000001, CSP_COM_IF = 0x49000002, I2C_COM_IF = 0x49000003, + SPI_COM_IF = 0x49000004, /* 0x47 ('G') for Gpio Interfaces */ GPIO_IF = 0x47000001, @@ -41,10 +42,17 @@ namespace objects { ACU_HANDLER = 0x44000004, TMP1075_HANDLER_1 = 0x44000005, TMP1075_HANDLER_2 = 0x44000006, + MGM_0_LIS3_HANDLER = 0x4400007, + MGM_1_RM3100_HANDLER = 0x44000008, + MGM_2_LIS3_HANDLER = 0x44000009, + MGM_3_RM3100_HANDLER = 0x44000010, + GYRO_0_ADIS_HANDLER = 0x44000011, + GYRO_1_L3G_HANDLER = 0x44000012, + GYRO_2_L3G_HANDLER = 0x44000013, /* Custom device handler */ - PCDU_HANDLER = 0x44000007, - SOLAR_ARRAY_DEPL_HANDLER = 0x44000008, + PCDU_HANDLER = 0x44001000, + SOLAR_ARRAY_DEPL_HANDLER = 0x44001001, /* 0x54 ('T') for thermal objects */ HEATER_HANDLER = 0x54000003, diff --git a/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp b/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp index d6f922dd..2c02cc6e 100644 --- a/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp +++ b/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp @@ -7,8 +7,8 @@ ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) { - /* Length of a communication cycle */ - uint32_t length = thisSequence->getPeriodMs(); + /* Length of a communication cycle */ + uint32_t length = thisSequence->getPeriodMs(); thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0, DeviceHandlerIF::PERFORM_OPERATION); @@ -30,73 +30,86 @@ ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.8, DeviceHandlerIF::GET_READ); - if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) { - return HasReturnvaluesIF::RETURN_OK; - } - else { - sif::error << "PollingSequence::initialize has errors!" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } + if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) { + return HasReturnvaluesIF::RETURN_OK; + } + + sif::error << "PollingSequence::initialize has errors!" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; } ReturnValue_t pst::gomspacePstInit(FixedTimeslotTaskIF *thisSequence){ + uint32_t length = thisSequence->getPeriodMs(); - uint32_t length = thisSequence->getPeriodMs(); + thisSequence->addSlot(objects::PCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::PCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::PCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::PCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::P60DOCK_HANDLER, + length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::PDU1_HANDLER, + length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::PDU2_HANDLER, + length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::ACU_HANDLER, + length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::P60DOCK_HANDLER, - length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::PDU1_HANDLER, - length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::PDU2_HANDLER, - length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::ACU_HANDLER, - length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::P60DOCK_HANDLER, + length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::PDU1_HANDLER, + length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::PDU2_HANDLER, + length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::ACU_HANDLER, + length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::P60DOCK_HANDLER, - length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::PDU1_HANDLER, - length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::PDU2_HANDLER, - length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::ACU_HANDLER, - length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::P60DOCK_HANDLER, + length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::PDU1_HANDLER, + length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::PDU2_HANDLER, + length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::ACU_HANDLER, + length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::P60DOCK_HANDLER, - length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::PDU1_HANDLER, - length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::PDU2_HANDLER, - length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::ACU_HANDLER, - length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::P60DOCK_HANDLER, + length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::PDU1_HANDLER, + length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::PDU2_HANDLER, + length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::ACU_HANDLER, + length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::P60DOCK_HANDLER, - length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::PDU1_HANDLER, - length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::PDU2_HANDLER, - length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::ACU_HANDLER, - length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::P60DOCK_HANDLER, + length * 0.8, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::PDU1_HANDLER, + length * 0.8, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::PDU2_HANDLER, + length * 0.8, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::ACU_HANDLER, + length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::P60DOCK_HANDLER, - length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::PDU1_HANDLER, - length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::PDU2_HANDLER, - length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::ACU_HANDLER, - length * 0.8, DeviceHandlerIF::GET_READ); - - if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) { - return HasReturnvaluesIF::RETURN_OK; - } - else { - sif::error << "Initialization of GomSpace PST failed" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } + if (thisSequence->checkSequence() != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Initialization of GomSpace PST failed" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; } +ReturnValue_t pst::pollingSequenceAcsTest(FixedTimeslotTaskIF *thisSequence) { + uint32_t length = thisSequence->getPeriodMs(); + + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.25, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.5, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.75, + DeviceHandlerIF::PERFORM_OPERATION); + if (thisSequence->checkSequence() != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Initialization of ACS Board PST failed" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/fsfwconfig/pollingsequence/PollingSequenceFactory.h b/fsfwconfig/pollingsequence/PollingSequenceFactory.h index 0b12e6b8..4003058b 100644 --- a/fsfwconfig/pollingsequence/PollingSequenceFactory.h +++ b/fsfwconfig/pollingsequence/PollingSequenceFactory.h @@ -32,6 +32,8 @@ ReturnValue_t pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence); * blocking calls when requesting data from devices. */ ReturnValue_t gomspacePstInit(FixedTimeslotTaskIF *thisSequence); + +ReturnValue_t pollingSequenceAcsTest(FixedTimeslotTaskIF* thisSequence); } diff --git a/tmtc b/tmtc index 2b85ece0..90c45ea0 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 2b85ece07195ee905c35b35494bc7a86b94335f5 +Subproject commit 90c45ea0c77f04677322b3c8c9077db841fc3129 From bbd022e5bec16bf9084f7c2d82e353024d433385 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 22:11:42 +0100 Subject: [PATCH 43/51] version is 1.0 now (i think were post alpha state..) --- fsfwconfig/OBSWVersion.h | 4 ++-- mission/devices/MGMHandlerLIS3MDL.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fsfwconfig/OBSWVersion.h b/fsfwconfig/OBSWVersion.h index d76b65c9..fd76332e 100644 --- a/fsfwconfig/OBSWVersion.h +++ b/fsfwconfig/OBSWVersion.h @@ -4,8 +4,8 @@ //! TODO: Think of a cool name for the software releases. const char* const SW_NAME = "eive"; -#define SW_VERSION 0 -#define SW_SUBVERSION 2 +#define SW_VERSION 1 +#define SW_SUBVERSION 0 #define SW_SUBSUBVERSION 0 diff --git a/mission/devices/MGMHandlerLIS3MDL.cpp b/mission/devices/MGMHandlerLIS3MDL.cpp index fad96f66..e9b456af 100644 --- a/mission/devices/MGMHandlerLIS3MDL.cpp +++ b/mission/devices/MGMHandlerLIS3MDL.cpp @@ -1,3 +1,4 @@ +#include #include "MGMHandlerLIS3MDL.h" @@ -257,13 +258,12 @@ ReturnValue_t MGMHandlerLIS3MDL::interpretDeviceReply(DeviceCommandId_t id, sif::info << "Z: " << mgmZ << " \xC2\xB5T" << std::endl; } #endif - ReturnValue_t result = dataset.read(); - if(result == HasReturnvaluesIF::RETURN_OK) { + PoolReadHelper readHelper(&dataset); + if(readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) { dataset.fieldStrengthX = mgmX; dataset.fieldStrengthY = mgmY; dataset.fieldStrengthZ = mgmZ; dataset.setValidity(true, true); - dataset.commit(); } break; } From 288bc0d38ec35535c425504a0273a547cb184c6d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 24 Feb 2021 00:24:14 +0100 Subject: [PATCH 44/51] lis 3 basic test code --- fsfw | 2 +- .../PollingSequenceFactory.cpp | 14 +++--- linux/boardtest/SpiTestClass.cpp | 44 ++++++++++++++++++- linux/boardtest/SpiTestClass.h | 2 + linux/spi/SpiComIF.cpp | 20 ++++++++- mission/devices/MGMHandlerLIS3MDL.cpp | 42 +++++++++++------- mission/devices/MGMHandlerLIS3MDL.h | 2 + 7 files changed, 101 insertions(+), 25 deletions(-) diff --git a/fsfw b/fsfw index f3cc664d..92f249dc 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit f3cc664d4f9fdadc2f6e2ebf814dd0c924e5ae33 +Subproject commit 92f249dc62cf02a5052fee4e9877bc89b2be1ab5 diff --git a/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp b/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp index 2c02cc6e..8b1e8e11 100644 --- a/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp +++ b/fsfwconfig/pollingsequence/PollingSequenceFactory.cpp @@ -101,12 +101,14 @@ ReturnValue_t pst::pollingSequenceAcsTest(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.25, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.5, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.75, - DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.2, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.4, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.6, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.8, + DeviceHandlerIF::GET_READ); if (thisSequence->checkSequence() != HasReturnvaluesIF::RETURN_OK) { sif::error << "Initialization of ACS Board PST failed" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index be00ec75..af996e87 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -19,7 +19,7 @@ SpiTestClass::SpiTestClass(object_id_t objectId, GpioIF* gpioIF): TestTask(objec if(gpioIF == nullptr) { sif::error << "SpiTestClass::SpiTestClass: Invalid GPIO ComIF!" << std::endl; } - testMode = TestModes::NONE; + testMode = TestModes::MGM_LIS3MDL; spiTransferStruct.rx_buf = reinterpret_cast<__u64>(recvBuffer.data()); spiTransferStruct.tx_buf = reinterpret_cast<__u64>(sendBuffer.data()); } @@ -30,6 +30,7 @@ ReturnValue_t SpiTestClass::performOneShotAction() { break; } case(TestModes::MGM_LIS3MDL): { + performLis3MdlTest(mgm0Lis3ChipSelect); break; } case(TestModes::MGM_RM3100): { @@ -89,6 +90,47 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) { std::endl; } +void SpiTestClass::performLis3MdlTest(uint8_t lis3Id) { + /* Configure all SPI chip selects and pull them high */ + acsInit(); + + /* Adapt accordingly */ + if(lis3Id != mgm0Lis3ChipSelect and lis3Id != mgm2Lis3mdlChipSelect) { + sif::warning << "SpiTestClass::performLis3MdlTest: Invalid MGM ID!" << std::endl; + } + gpioId_t currentGpioId = 0; + uint8_t chipSelectPin = lis3Id; + uint8_t whoAmIReg = 0b0000'1111; + if(chipSelectPin == mgm0Lis3ChipSelect) { + currentGpioId = gpioIds::MGM_0_LIS3_CS; + } + else { + currentGpioId = gpioIds::MGM_2_LIS3_CS; + } + uint32_t spiSpeed = 3'900'000; + spi::SpiMode spiMode = spi::SpiMode::MODE_3; +#ifdef RASPBERRY_PI + std::string deviceName = "/dev/spidev0.0"; +#else + std::string deviceName = "placeholder"; +#endif + int fileDescriptor = 0; + + utility::UnixFileHelper fileHelper(deviceName, &fileDescriptor, O_RDWR, + "SpiComIF::initializeInterface: "); + if(fileHelper.getOpenResult()) { + sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!" + << std::endl; + return; + } + setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); + + uint8_t whoAmIRegVal = readStmRegister(fileDescriptor, currentGpioId, whoAmIReg, false); + sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I Regiter 0b" << + std::bitset<8>(whoAmIRegVal) << std::endl; +} + + void SpiTestClass::acsInit() { GpioCookie* gpioCookie = new GpioCookie(); std::string rpiGpioName = "gpiochip0"; diff --git a/linux/boardtest/SpiTestClass.h b/linux/boardtest/SpiTestClass.h index d4d946cd..61c2d2b2 100644 --- a/linux/boardtest/SpiTestClass.h +++ b/linux/boardtest/SpiTestClass.h @@ -31,6 +31,8 @@ private: struct spi_ioc_transfer spiTransferStruct; void performRm3100Test(uint8_t mgmId); + void performLis3MdlTest(uint8_t lis3Id); + /* ACS board specific code which pulls all GPIOs high */ void acsInit(); diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index b656ac2d..1766d563 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -170,6 +171,23 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s } bool fullDuplex = spiCookie->isFullDuplex(); + if(fullDuplex) { + uint8_t* readBuf = nullptr; + ReturnValue_t result = getReadBuffer(spiCookie->getSpiAddress(), &readBuf); + if (result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "SpiComIF::sendMessage: Could not get read buffer!" << + std::endl; +#else + sif::printWarning("SpiComIF::sendMessage: Could not get read buffer!\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return result; + } + spiCookie->assignReadBuffer(readBuf); + } + int retval = 0; gpioId_t gpioId = spiCookie->getChipSelectPin(); @@ -182,7 +200,7 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s if(fullDuplex) { /* Initiate a full duplex SPI transfer. */ retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle()); - if(retval != 0) { + if(retval < 0) { utility::handleIoctlError("SpiComIF::sendMessage: ioctl error."); result = FULL_DUPLEX_TRANSFER_FAILED; } diff --git a/mission/devices/MGMHandlerLIS3MDL.cpp b/mission/devices/MGMHandlerLIS3MDL.cpp index e9b456af..97c0555b 100644 --- a/mission/devices/MGMHandlerLIS3MDL.cpp +++ b/mission/devices/MGMHandlerLIS3MDL.cpp @@ -9,7 +9,7 @@ MGMHandlerLIS3MDL::MGMHandlerLIS3MDL(object_id_t objectId, #if OBSW_VERBOSE_LEVEL >= 1 debugDivider = new PeriodicOperationDivider(10); #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; @@ -37,7 +37,7 @@ void MGMHandlerLIS3MDL::doStartUp() { break; case(InternalState::STATE_CHECK_REGISTERS): { - // Set up cached registers which will be used to configure the MGM. + /* Set up cached registers which will be used to configure the MGM. */ if(commandExecuted) { commandExecuted = false; setMode(_MODE_TO_ON); @@ -73,11 +73,17 @@ ReturnValue_t MGMHandlerLIS3MDL::buildTransitionDeviceCommand( *id = MGMLIS3MDL::READ_CONFIG_AND_DATA; break; } - default: - // might be a configuration error. - sif::debug << "GyroHandler::buildTransitionDeviceCommand: Unknown " - << "internal state!" << std::endl; - return HasReturnvaluesIF::RETURN_OK; + 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); } @@ -185,6 +191,9 @@ ReturnValue_t MGMHandlerLIS3MDL::scanForReply(const uint8_t *start, 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 OBSW_VERBOSE_LEVEL >= 1 + sif::warning << "MGMHandlerLIS3MDL::scanForReply: Invalid registers!" << std::endl; +#endif return DeviceHandlerIF::INVALID_DATA; } if(mode == _MODE_START_UP) { @@ -228,7 +237,7 @@ ReturnValue_t MGMHandlerLIS3MDL::interpretDeviceReply(DeviceCommandId_t id, break; } case MGMLIS3MDL::READ_CONFIG_AND_DATA: { - // TODO: Store configuration and sensor values in new local datasets. + // TODO: Store configuration in new local datasets. uint8_t scale = getFullScale(registers[2]); float sensitivityFactor = getSensitivityFactor(scale); @@ -240,7 +249,7 @@ ReturnValue_t MGMHandlerLIS3MDL::interpretDeviceReply(DeviceCommandId_t id, int16_t mgmMeasurementRawZ = packet[MGMLIS3MDL::Z_HIGHBYTE_IDX] << 8 | packet[MGMLIS3MDL::Z_LOWBYTE_IDX] ; - // Target value in microtesla + /* Target value in microtesla */ float mgmX = static_cast(mgmMeasurementRawX) * sensitivityFactor * MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR; float mgmY = static_cast(mgmMeasurementRawY) * sensitivityFactor @@ -252,7 +261,7 @@ ReturnValue_t MGMHandlerLIS3MDL::interpretDeviceReply(DeviceCommandId_t id, if(debugDivider->checkAndIncrement()) { sif::info << "MGMHandlerLIS3: Magnetic field strength in" " microtesla:" << std::endl; - // Set terminal to utf-8 if there is an issue with micro printout. + /* Set terminal to utf-8 if there is an issue with micro printout. */ sif::info << "X: " << mgmX << " \xC2\xB5T" << std::endl; sif::info << "Y: " << mgmY << " \xC2\xB5T" << std::endl; sif::info << "Z: " << mgmZ << " \xC2\xB5T" << std::endl; @@ -273,9 +282,8 @@ ReturnValue_t MGMHandlerLIS3MDL::interpretDeviceReply(DeviceCommandId_t id, float tempValue = 25.0 + ((static_cast(tempValueRaw)) / 8.0); #if OBSW_VERBOSE_LEVEL >= 1 if(debugDivider->check()) { - // Set terminal to utf-8 if there is an issue with micro printout. - sif::info << "MGMHandlerLIS3: Temperature: " << tempValue<< " °C" - << std::endl; + /* Set terminal to utf-8 if there is an issue with micro printout. */ + sif::info << "MGMHandlerLIS3: Temperature: " << tempValue<< " °C" << std::endl; } #endif ReturnValue_t result = dataset.read(); @@ -397,7 +405,6 @@ void MGMHandlerLIS3MDL::fillCommandAndReplyMap() { } ReturnValue_t MGMHandlerLIS3MDL::prepareCtrlRegisterWrite() { - commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1, true); for (size_t i = 0; i < MGMLIS3MDL::NR_OF_CTRL_REGISTERS; i++) { @@ -406,7 +413,7 @@ ReturnValue_t MGMHandlerLIS3MDL::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 it */ return RETURN_OK; } @@ -415,7 +422,7 @@ void MGMHandlerLIS3MDL::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { } uint32_t MGMHandlerLIS3MDL::getTransitionDelayMs(Mode_t from, Mode_t to) { - return 5000; + return 30000; } void MGMHandlerLIS3MDL::modeChanged(void) { @@ -434,3 +441,6 @@ ReturnValue_t MGMHandlerLIS3MDL::initializeLocalDataPool( new PoolEntry({0.0})); return HasReturnvaluesIF::RETURN_OK; } + +void MGMHandlerLIS3MDL::performOperationHook() { +} diff --git a/mission/devices/MGMHandlerLIS3MDL.h b/mission/devices/MGMHandlerLIS3MDL.h index 77874e33..e3fcf098 100644 --- a/mission/devices/MGMHandlerLIS3MDL.h +++ b/mission/devices/MGMHandlerLIS3MDL.h @@ -161,6 +161,8 @@ private: PeriodicOperationDivider* debugDivider; #endif + void performOperationHook() override; + }; #endif /* MISSION_DEVICES_MGMLIS3MDLHANDLER_H_ */ From 961dd7f769d82fd71e8e9c149957aad194b04c02 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 24 Feb 2021 10:36:23 +0100 Subject: [PATCH 45/51] added some testcode, zero init spi struct --- bsp_rpi/boardconfig/rpi_config.h | 4 +- bsp_rpi/main.cpp | 4 +- linux/boardtest/SpiTestClass.cpp | 14 +++--- linux/spi/SpiComIF.cpp | 18 +------ linux/spi/SpiCookie.h | 2 +- mission/devices/MGMHandlerLIS3MDL.cpp | 72 +++++++++++++++++++++++++++ 6 files changed, 85 insertions(+), 29 deletions(-) diff --git a/bsp_rpi/boardconfig/rpi_config.h b/bsp_rpi/boardconfig/rpi_config.h index 4326bd9e..d1acacb6 100644 --- a/bsp_rpi/boardconfig/rpi_config.h +++ b/bsp_rpi/boardconfig/rpi_config.h @@ -3,8 +3,8 @@ #include -#define RPI_ADD_GPIO_TEST 1 -#define RPI_LOOPBACK_TEST_GPIO 1 +#define RPI_ADD_GPIO_TEST 0 +#define RPI_LOOPBACK_TEST_GPIO 0 /* Only one of those 2 should be enabled! */ #define RPI_ADD_SPI_TEST 0 diff --git a/bsp_rpi/main.cpp b/bsp_rpi/main.cpp index e1f8d9f6..8eea768c 100644 --- a/bsp_rpi/main.cpp +++ b/bsp_rpi/main.cpp @@ -6,7 +6,7 @@ #include /** - * @brief This is the main program for the target hardware. + * @brief This is the main program and entry point for the Raspberry Pi. * @return */ int main(void) @@ -20,7 +20,7 @@ int main(void) initmission::initMission(); for(;;) { - /* suspend main thread by sleeping it. */ + /* Suspend main thread by sleeping it. */ TaskFactory::delayTask(5000); } } diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index af996e87..df32ec5b 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -135,37 +135,37 @@ void SpiTestClass::acsInit() { GpioCookie* gpioCookie = new GpioCookie(); std::string rpiGpioName = "gpiochip0"; { - GpiodRegular gpio(rpiGpioName.c_str(), mgm0Lis3ChipSelect, "MGM_0_LIS3", + GpiodRegular gpio(rpiGpioName, mgm0Lis3ChipSelect, "MGM_0_LIS3", gpio::Direction::OUT, 1); gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio); } { - GpiodRegular gpio(rpiGpioName.c_str(), mgm1Rm3100ChipSelect, "MGM_1_RM3100", + GpiodRegular gpio(rpiGpioName, mgm1Rm3100ChipSelect, "MGM_1_RM3100", gpio::Direction::OUT, 1); gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio); } { - GpiodRegular gpio(rpiGpioName.c_str(), gyro0AdisChipSelect, "GYRO_0_ADIS", + GpiodRegular gpio(rpiGpioName, gyro0AdisChipSelect, "GYRO_0_ADIS", gpio::Direction::OUT, 1); gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio); } { - GpiodRegular gpio(rpiGpioName.c_str(), gyro1L3gd20ChipSelect, "GYRO_1_L3G", + GpiodRegular gpio(rpiGpioName, gyro1L3gd20ChipSelect, "GYRO_1_L3G", gpio::Direction::OUT, 1); gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio); } { - GpiodRegular gpio(rpiGpioName.c_str(), gyro2L3gd20ChipSelect, "GYRO_2_L3G", + GpiodRegular gpio(rpiGpioName, gyro2L3gd20ChipSelect, "GYRO_2_L3G", gpio::Direction::OUT, 1); gpioCookie->addGpio(gpioIds::GYRO_2_L3G_CS, gpio); } { - GpiodRegular gpio(rpiGpioName.c_str(), mgm2Lis3mdlChipSelect, "MGM_2_LIS3", + GpiodRegular gpio(rpiGpioName, mgm2Lis3mdlChipSelect, "MGM_2_LIS3", gpio::Direction::OUT, 1); gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio); } { - GpiodRegular gpio(rpiGpioName.c_str(), mgm3Rm3100ChipSelect, "MGM_3_RM3100", + GpiodRegular gpio(rpiGpioName, mgm3Rm3100ChipSelect, "MGM_3_RM3100", gpio::Direction::OUT, 1); gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); } diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index 1766d563..3b5cb67e 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -71,6 +71,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { return HasReturnvaluesIF::RETURN_FAILED; } + /* Pull CS high in any case to be sure that device is inactive */ gpioId_t gpioId = spiCookie->getChipSelectPin(); if(gpioId != gpio::NO_GPIO) { gpioComIF->pullHigh(gpioId); @@ -171,23 +172,6 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s } bool fullDuplex = spiCookie->isFullDuplex(); - if(fullDuplex) { - uint8_t* readBuf = nullptr; - ReturnValue_t result = getReadBuffer(spiCookie->getSpiAddress(), &readBuf); - if (result != HasReturnvaluesIF::RETURN_OK) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "SpiComIF::sendMessage: Could not get read buffer!" << - std::endl; -#else - sif::printWarning("SpiComIF::sendMessage: Could not get read buffer!\n"); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - return result; - } - spiCookie->assignReadBuffer(readBuf); - } - int retval = 0; gpioId_t gpioId = spiCookie->getChipSelectPin(); diff --git a/linux/spi/SpiCookie.h b/linux/spi/SpiCookie.h index 91d42a3c..42004993 100644 --- a/linux/spi/SpiCookie.h +++ b/linux/spi/SpiCookie.h @@ -104,7 +104,7 @@ private: uint32_t spiSpeed; bool halfDuplex = false; - struct spi_ioc_transfer spiTransferStruct; + struct spi_ioc_transfer spiTransferStruct = {}; UncommonParameters uncommonParameters; }; diff --git a/mission/devices/MGMHandlerLIS3MDL.cpp b/mission/devices/MGMHandlerLIS3MDL.cpp index 97c0555b..7bd6dfba 100644 --- a/mission/devices/MGMHandlerLIS3MDL.cpp +++ b/mission/devices/MGMHandlerLIS3MDL.cpp @@ -442,5 +442,77 @@ ReturnValue_t MGMHandlerLIS3MDL::initializeLocalDataPool( return HasReturnvaluesIF::RETURN_OK; } +#include +#include +#include + +#include +#include +#include +#include +#include + void MGMHandlerLIS3MDL::performOperationHook() { + + /* Adapt accordingly */ +// if(lis3Id != mgm0Lis3ChipSelect and lis3Id != mgm2Lis3mdlChipSelect) { +// sif::warning << "SpiTestClass::performLis3MdlTest: Invalid MGM ID!" << std::endl; +// } + gpioId_t currentGpioId = gpioIds::MGM_0_LIS3_CS; + uint8_t chipSelectPin = 0; + uint8_t whoAmIReg = 0b0000'1111; + uint8_t reg = whoAmIReg; + + uint32_t spiSpeed = 3'900'000; + spi::SpiMode spiMode = spi::SpiMode::MODE_3; +#ifdef RASPBERRY_PI + std::string deviceName = "/dev/spidev0.0"; +#else + std::string deviceName = "placeholder"; +#endif + int fileDescriptor = 0; + uint8_t recvBuffer [16]; + uint8_t sendBuffer [16]; + + utility::UnixFileHelper fileHelper(deviceName, &fileDescriptor, O_RDWR, + "SpiComIF::initializeInterface: "); + if(fileHelper.getOpenResult()) { + sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!" + << std::endl; + return; + } + int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, reinterpret_cast(&spiMode)); + if(retval != 0) { + utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!"); + } + + retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed); + if(retval != 0) { + utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!"); + } + GpioIF* gpioIF = objectManager->get(objects::GPIO_IF); + uint8_t STM_READ_MASK = 0b1000'0000; + struct spi_ioc_transfer spiTransferStruct = {}; + reg |= STM_READ_MASK; + spiTransferStruct.len = 2; + sendBuffer[0] = reg; + sendBuffer[1] = 0; + spiTransferStruct.rx_buf = reinterpret_cast<__u64>(recvBuffer); + spiTransferStruct.tx_buf = reinterpret_cast<__u64>(sendBuffer); + //spiTransferStruct.bits_per_word = 8; + //spiTransferStruct.speed_hz = 3'900'000; + + if(gpioIF != nullptr and currentGpioId != gpio::NO_GPIO) { + gpioIF->pullLow(currentGpioId); + } + retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), &spiTransferStruct); + if(retval < 0) { + utility::handleIoctlError("SpiTestClass::readStmRegiste: Read failed"); + } + if(gpioIF != nullptr and currentGpioId != gpio::NO_GPIO) { + gpioIF->pullHigh(currentGpioId); + } + + sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I Regiter 0b" << + std::bitset<8>(recvBuffer[1]) << std::endl; } From 873412f3fb8b6f67dae325a2f55b1b6c73567853 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 24 Feb 2021 11:16:33 +0100 Subject: [PATCH 46/51] spi com if basic verification complete --- linux/spi/SpiComIF.cpp | 46 ++++++++++------ linux/spi/SpiComIF.h | 3 ++ mission/devices/MGMHandlerLIS3MDL.cpp | 76 ++------------------------- 3 files changed, 35 insertions(+), 90 deletions(-) diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index 3b5cb67e..eef44126 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -1,5 +1,4 @@ #include "SpiComIF.h" -#include "spiDefinitions.h" #include #include @@ -32,6 +31,7 @@ SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(object } ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { + int retval = 0; SpiCookie* spiCookie = dynamic_cast(cookie); if(spiCookie == nullptr) { return NULLPOINTER; @@ -90,16 +90,6 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { return fileHelper.getOpenResult(); } - int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, reinterpret_cast(&spiMode)); - if(retval != 0) { - utility::handleIoctlError("SpiComIF::initializeInterface: Setting SPI mode failed!"); - } - - retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed); - if(retval != 0) { - utility::handleIoctlError("SpiComIF::initializeInterface: Setting SPI speed failed!"); - } - /* These flags are rather uncommon */ if(params.threeWireSpi or params.noCs or params.csHigh) { uint32_t currentMode = 0; @@ -143,6 +133,8 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) { SpiCookie* spiCookie = dynamic_cast(cookie); ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + int retval = 0; + if(spiCookie == nullptr) { return NULLPOINTER; } @@ -161,8 +153,8 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s return DeviceCommunicationIF::TOO_MUCH_DATA; } - spiCookie->assignWriteBuffer(sendData); - spiCookie->assignTransferSize(sendLen); + + /* Prepare transfer */ int fileDescriptor = 0; std::string device = spiCookie->getSpiDevice(); utility::UnixFileHelper fileHelper(device, &fileDescriptor, O_RDWR, @@ -170,17 +162,25 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { return OPENING_FILE_FAILED; } + spi::SpiMode spiMode = spi::SpiMode::MODE_0; + uint32_t spiSpeed = 0; + spiCookie->getSpiParameters(spiMode, spiSpeed, nullptr); + setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); + spiCookie->assignWriteBuffer(sendData); + spiCookie->assignTransferSize(sendLen); bool fullDuplex = spiCookie->isFullDuplex(); - int retval = 0; - gpioId_t gpioId = spiCookie->getChipSelectPin(); + + /* GPIO access is mutex protected */ MutexHelper(spiMutex, timeoutType, timeoutMs); + + /* Pull SPI CS low. For now, no support for active high given */ if(gpioId != gpio::NO_GPIO) { - /* For now, no support for active high given */ gpioComIF->pullLow(gpioId); } + /* Execute transfer */ if(fullDuplex) { /* Initiate a full duplex SPI transfer. */ retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle()); @@ -190,7 +190,7 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s } } else { - /* We write with a blocking transfer here */ + /* We write with a blocking half-duplex transfer here */ if (write(fileDescriptor, sendData, sendLen) != static_cast(sendLen)) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -294,3 +294,15 @@ ReturnValue_t SpiComIF::getReadBuffer(address_t spiAddress, uint8_t** buffer) { *buffer = iter->second.replyBuffer.data(); return HasReturnvaluesIF::RETURN_OK; } + +void SpiComIF::setSpiSpeedAndMode(int spiFd, spi::SpiMode 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!"); + } + + retval = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + if(retval != 0) { + utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!"); + } +} diff --git a/linux/spi/SpiComIF.h b/linux/spi/SpiComIF.h index e454db21..cbcaa4e0 100644 --- a/linux/spi/SpiComIF.h +++ b/linux/spi/SpiComIF.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -54,7 +55,9 @@ private: SpiDeviceMap spiDeviceMap; + ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); + void setSpiSpeedAndMode(int spiFd, spi::SpiMode mode, uint32_t speed); }; #endif /* LINUX_SPI_SPICOMIF_H_ */ diff --git a/mission/devices/MGMHandlerLIS3MDL.cpp b/mission/devices/MGMHandlerLIS3MDL.cpp index 7bd6dfba..a3ab25cd 100644 --- a/mission/devices/MGMHandlerLIS3MDL.cpp +++ b/mission/devices/MGMHandlerLIS3MDL.cpp @@ -40,6 +40,7 @@ void MGMHandlerLIS3MDL::doStartUp() { /* Set up cached registers which will be used to configure the MGM. */ if(commandExecuted) { commandExecuted = false; + /* Replace _MODE_TO_ON with MODE_NORMAL to jump to normal mode quickly */ setMode(_MODE_TO_ON); } break; @@ -283,7 +284,8 @@ ReturnValue_t MGMHandlerLIS3MDL::interpretDeviceReply(DeviceCommandId_t id, #if OBSW_VERBOSE_LEVEL >= 1 if(debugDivider->check()) { /* Set terminal to utf-8 if there is an issue with micro printout. */ - sif::info << "MGMHandlerLIS3: Temperature: " << tempValue<< " °C" << std::endl; + sif::info << "MGMHandlerLIS3: Temperature: " << tempValue << " \xC2\xB0" << "C" << + std::endl; } #endif ReturnValue_t result = dataset.read(); @@ -442,77 +444,5 @@ ReturnValue_t MGMHandlerLIS3MDL::initializeLocalDataPool( return HasReturnvaluesIF::RETURN_OK; } -#include -#include -#include - -#include -#include -#include -#include -#include - void MGMHandlerLIS3MDL::performOperationHook() { - - /* Adapt accordingly */ -// if(lis3Id != mgm0Lis3ChipSelect and lis3Id != mgm2Lis3mdlChipSelect) { -// sif::warning << "SpiTestClass::performLis3MdlTest: Invalid MGM ID!" << std::endl; -// } - gpioId_t currentGpioId = gpioIds::MGM_0_LIS3_CS; - uint8_t chipSelectPin = 0; - uint8_t whoAmIReg = 0b0000'1111; - uint8_t reg = whoAmIReg; - - uint32_t spiSpeed = 3'900'000; - spi::SpiMode spiMode = spi::SpiMode::MODE_3; -#ifdef RASPBERRY_PI - std::string deviceName = "/dev/spidev0.0"; -#else - std::string deviceName = "placeholder"; -#endif - int fileDescriptor = 0; - uint8_t recvBuffer [16]; - uint8_t sendBuffer [16]; - - utility::UnixFileHelper fileHelper(deviceName, &fileDescriptor, O_RDWR, - "SpiComIF::initializeInterface: "); - if(fileHelper.getOpenResult()) { - sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!" - << std::endl; - return; - } - int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, reinterpret_cast(&spiMode)); - if(retval != 0) { - utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!"); - } - - retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed); - if(retval != 0) { - utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!"); - } - GpioIF* gpioIF = objectManager->get(objects::GPIO_IF); - uint8_t STM_READ_MASK = 0b1000'0000; - struct spi_ioc_transfer spiTransferStruct = {}; - reg |= STM_READ_MASK; - spiTransferStruct.len = 2; - sendBuffer[0] = reg; - sendBuffer[1] = 0; - spiTransferStruct.rx_buf = reinterpret_cast<__u64>(recvBuffer); - spiTransferStruct.tx_buf = reinterpret_cast<__u64>(sendBuffer); - //spiTransferStruct.bits_per_word = 8; - //spiTransferStruct.speed_hz = 3'900'000; - - if(gpioIF != nullptr and currentGpioId != gpio::NO_GPIO) { - gpioIF->pullLow(currentGpioId); - } - retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), &spiTransferStruct); - if(retval < 0) { - utility::handleIoctlError("SpiTestClass::readStmRegiste: Read failed"); - } - if(gpioIF != nullptr and currentGpioId != gpio::NO_GPIO) { - gpioIF->pullHigh(currentGpioId); - } - - sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I Regiter 0b" << - std::bitset<8>(recvBuffer[1]) << std::endl; } From a8f612f051cb5446c82aa986284790496903bfd2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 24 Feb 2021 11:24:31 +0100 Subject: [PATCH 47/51] who am i reg is now checked --- mission/devices/MGMHandlerLIS3MDL.cpp | 668 +++++++++--------- mission/devices/MGMHandlerLIS3MDL.h | 234 +++--- .../MGMHandlerLIS3Definitions.h | 36 +- 3 files changed, 477 insertions(+), 461 deletions(-) diff --git a/mission/devices/MGMHandlerLIS3MDL.cpp b/mission/devices/MGMHandlerLIS3MDL.cpp index a3ab25cd..ebe47487 100644 --- a/mission/devices/MGMHandlerLIS3MDL.cpp +++ b/mission/devices/MGMHandlerLIS3MDL.cpp @@ -3,18 +3,18 @@ MGMHandlerLIS3MDL::MGMHandlerLIS3MDL(object_id_t objectId, - object_id_t deviceCommunication, CookieIF* comCookie): - DeviceHandlerBase(objectId, deviceCommunication, comCookie), - dataset(this) { + object_id_t deviceCommunication, CookieIF* comCookie): + DeviceHandlerBase(objectId, deviceCommunication, comCookie), + dataset(this) { #if OBSW_VERBOSE_LEVEL >= 1 - debugDivider = new PeriodicOperationDivider(10); + debugDivider = new PeriodicOperationDivider(10); #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; + /* 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; } @@ -23,400 +23,416 @@ MGMHandlerLIS3MDL::~MGMHandlerLIS3MDL() { void MGMHandlerLIS3MDL::doStartUp() { - switch (internalState) { - case(InternalState::STATE_NONE): - internalState = InternalState::STATE_FIRST_CONTACT; - break; - - case(InternalState::STATE_FIRST_CONTACT): - 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; - /* Replace _MODE_TO_ON with MODE_NORMAL to jump to normal mode quickly */ - setMode(_MODE_TO_ON); - } - break; - } - default: - break; - } + 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; + /* Replace _MODE_TO_ON with MODE_NORMAL to jump to normal mode quickly */ + setMode(_MODE_TO_ON); + } + break; + } + default: + break; + } } void MGMHandlerLIS3MDL::doShutDown() { - setMode(_MODE_POWER_DOWN); + setMode(_MODE_POWER_DOWN); } ReturnValue_t MGMHandlerLIS3MDL::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. */ + 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; + sif::warning << "GyroHandler::buildTransitionDeviceCommand: Unknown internal state!" << + std::endl; #else - sif::printWarning("GyroHandler::buildTransitionDeviceCommand: Unknown internal state!\n"); + sif::printWarning("GyroHandler::buildTransitionDeviceCommand: Unknown internal state!\n"); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ - return HasReturnvaluesIF::RETURN_OK; - } + return HasReturnvaluesIF::RETURN_OK; + } - } - return buildCommandFromCommand(*id, NULL, 0); + } + return buildCommandFromCommand(*id, NULL, 0); } uint8_t MGMHandlerLIS3MDL::readCommand(uint8_t command, bool continuousCom) { - command |= (1 << MGMLIS3MDL::RW_BIT); - if (continuousCom == true) { - command |= (1 << MGMLIS3MDL::MS_BIT); - } - return command; + command |= (1 << MGMLIS3MDL::RW_BIT); + if (continuousCom == true) { + command |= (1 << MGMLIS3MDL::MS_BIT); + } + return command; } uint8_t MGMHandlerLIS3MDL::writeCommand(uint8_t command, bool continuousCom) { - command &= ~(1 << MGMLIS3MDL::RW_BIT); - if (continuousCom == true) { - command |= (1 << MGMLIS3MDL::MS_BIT); - } - return command; + command &= ~(1 << MGMLIS3MDL::RW_BIT); + if (continuousCom == true) { + command |= (1 << MGMLIS3MDL::MS_BIT); + } + return command; } void MGMHandlerLIS3MDL::setupMgm() { - registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT; - registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT; - registers[2] = MGMLIS3MDL::CTRL_REG3_DEFAULT; - registers[3] = MGMLIS3MDL::CTRL_REG4_DEFAULT; - registers[4] = MGMLIS3MDL::CTRL_REG5_DEFAULT; + registers[0] = 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(); + prepareCtrlRegisterWrite(); } ReturnValue_t MGMHandlerLIS3MDL::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); - } + 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 MGMHandlerLIS3MDL::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); + 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 = 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; + 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 MGMHandlerLIS3MDL::identifyDevice() { - uint32_t size = 2; - commandBuffer[0] = readCommand(MGMLIS3MDL::IDENTIFY_DEVICE_REG_ADDR); - commandBuffer[1] = 0x00; + uint32_t size = 2; + commandBuffer[0] = readCommand(MGMLIS3MDL::IDENTIFY_DEVICE_REG_ADDR); + commandBuffer[1] = 0x00; - rawPacket = commandBuffer; - rawPacketLen = size; + rawPacket = commandBuffer; + rawPacketLen = size; - return RETURN_OK; + return RETURN_OK; } ReturnValue_t MGMHandlerLIS3MDL::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]) { + 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 OBSW_VERBOSE_LEVEL >= 1 - sif::warning << "MGMHandlerLIS3MDL::scanForReply: Invalid registers!" << std::endl; + sif::warning << "MGMHandlerLIS3MDL::scanForReply: Invalid registers!" << std::endl; #endif - return DeviceHandlerIF::INVALID_DATA; - } - if(mode == _MODE_START_UP) { - commandExecuted = true; - } + 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(); - } - else { - return DeviceHandlerIF::INVALID_DATA; - } + } + 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 OBSW_VERBOSE_LEVEL >= 1 + sif::warning << "MGMHandlerLIS3MDL::scanForReply: Invalid registers!" << std::endl; +#endif + return DeviceHandlerIF::INVALID_DATA; + } - // Data with SPI Interface has always this answer - if (start[0] == 0b11111111) { - return RETURN_OK; - } - else { - 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 MGMHandlerLIS3MDL::interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) { + 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. + 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. - uint8_t scale = getFullScale(registers[2]); - float sensitivityFactor = getSensitivityFactor(scale); + uint8_t scale = getFullScale(registers[2]); + float sensitivityFactor = getSensitivityFactor(scale); - 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] ; + 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; + /* 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 OBSW_VERBOSE_LEVEL >= 1 - if(debugDivider->checkAndIncrement()) { - sif::info << "MGMHandlerLIS3: Magnetic field strength in" - " microtesla:" << std::endl; - /* Set terminal to utf-8 if there is an issue with micro printout. */ - sif::info << "X: " << mgmX << " \xC2\xB5T" << std::endl; - sif::info << "Y: " << mgmY << " \xC2\xB5T" << std::endl; - sif::info << "Z: " << mgmZ << " \xC2\xB5T" << std::endl; - } + if(debugDivider->checkAndIncrement()) { + sif::info << "MGMHandlerLIS3: Magnetic field strength in" + " microtesla:" << std::endl; + /* Set terminal to utf-8 if there is an issue with micro printout. */ + sif::info << "X: " << mgmX << " \xC2\xB5T" << std::endl; + sif::info << "Y: " << mgmY << " \xC2\xB5T" << std::endl; + sif::info << "Z: " << mgmZ << " \xC2\xB5T" << std::endl; + } #endif - PoolReadHelper readHelper(&dataset); - if(readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) { - dataset.fieldStrengthX = mgmX; - dataset.fieldStrengthY = mgmY; - dataset.fieldStrengthZ = mgmZ; - dataset.setValidity(true, true); - } - break; - } + PoolReadHelper 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); + case MGMLIS3MDL::READ_TEMPERATURE: { + int16_t tempValueRaw = packet[2] << 8 | packet[1]; + float tempValue = 25.0 + ((static_cast(tempValueRaw)) / 8.0); #if OBSW_VERBOSE_LEVEL >= 1 - if(debugDivider->check()) { - /* Set terminal to utf-8 if there is an issue with micro printout. */ - sif::info << "MGMHandlerLIS3: Temperature: " << tempValue << " \xC2\xB0" << "C" << - std::endl; - } + if(debugDivider->check()) { + /* Set terminal to utf-8 if there is an issue with micro printout. */ + sif::info << "MGMHandlerLIS3: Temperature: " << tempValue << " \xC2\xB0" << "C" << + std::endl; + } #endif ReturnValue_t result = dataset.read(); if(result == HasReturnvaluesIF::RETURN_OK) { dataset.temperature = tempValue; dataset.commit(); } - break; - } + break; + } - default: { - return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; - } + default: { + return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; + } - } - return RETURN_OK; + } + return RETURN_OK; } uint8_t MGMHandlerLIS3MDL::getFullScale(uint8_t ctrlRegister2) { - bool FS0 = false; - bool FS1 = false; - if ((ctrlRegister2 >> 5) == 1) - FS0 = true; - if ((ctrlRegister2 >> 6) == 1) - FS1 = true; - if ((FS0 == true) && (FS1 == true)) - return 16; - else if ((FS0 == false) && (FS1 == true)) - return 12; - else if ((FS0 == true) && (FS1 == false)) - return 8; - else - return 4; + bool FS0 = false; + bool FS1 = false; + if ((ctrlRegister2 >> 5) == 1) + FS0 = true; + if ((ctrlRegister2 >> 6) == 1) + FS1 = true; + if ((FS0 == true) && (FS1 == true)) + return 16; + else if ((FS0 == false) && (FS1 == true)) + return 12; + else if ((FS0 == true) && (FS1 == false)) + return 8; + else + return 4; } float MGMHandlerLIS3MDL::getSensitivityFactor(uint8_t scale) { - return (float) scale / (INT16_MAX); + return (float) scale / (INT16_MAX); } ReturnValue_t MGMHandlerLIS3MDL::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]; + 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; + rawPacket = commandBuffer; + rawPacketLen = size; - return RETURN_OK; + return RETURN_OK; } ReturnValue_t MGMHandlerLIS3MDL::setOperatingMode(const uint8_t *commandData, - size_t commandDataLen) { - triggerEvent(CHANGE_OF_SETUP_PARAMETER); - if (commandDataLen != 1) { - return INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS; - } + 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; + 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::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; - } + 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(); + return prepareCtrlRegisterWrite(); } void MGMHandlerLIS3MDL::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); + /* + * 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); } ReturnValue_t MGMHandlerLIS3MDL::prepareCtrlRegisterWrite() { - commandBuffer[0] = writeCommand(MGMLIS3MDL::CTRL_REG1, true); + 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; + 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; + /* We dont have to check if this is working because we just did it */ + return RETURN_OK; } void MGMHandlerLIS3MDL::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { @@ -424,24 +440,24 @@ void MGMHandlerLIS3MDL::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { } uint32_t MGMHandlerLIS3MDL::getTransitionDelayMs(Mode_t from, Mode_t to) { - return 30000; + return 30000; } void MGMHandlerLIS3MDL::modeChanged(void) { - internalState = InternalState::STATE_NONE; + internalState = InternalState::STATE_NONE; } ReturnValue_t MGMHandlerLIS3MDL::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; + 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; } void MGMHandlerLIS3MDL::performOperationHook() { diff --git a/mission/devices/MGMHandlerLIS3MDL.h b/mission/devices/MGMHandlerLIS3MDL.h index e3fcf098..fc998f46 100644 --- a/mission/devices/MGMHandlerLIS3MDL.h +++ b/mission/devices/MGMHandlerLIS3MDL.h @@ -18,150 +18,150 @@ */ class MGMHandlerLIS3MDL: public DeviceHandlerBase { public: - enum class CommunicationStep { - DATA, - TEMPERATURE - }; + 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); + 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); - MGMHandlerLIS3MDL(uint32_t objectId, object_id_t deviceCommunication, - CookieIF* comCookie); - virtual ~MGMHandlerLIS3MDL(); + MGMHandlerLIS3MDL(uint32_t objectId, object_id_t deviceCommunication, + CookieIF* comCookie); + virtual ~MGMHandlerLIS3MDL(); 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; + /** 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; + MGMLIS3MDL::MgmPrimaryDataset dataset; - /*------------------------------------------------------------------------*/ - /* 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); + /*------------------------------------------------------------------------*/ + /* 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); + /** + * 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 - */ - uint8_t getFullScale(uint8_t ctrlReg2); + /** + * 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 + */ + uint8_t getFullScale(uint8_t ctrlReg2); - /** - * The 16 bit value needs to be divided by the full range of a 16bit value - * and then multiplied with the current scale of the MGM. - * This factor returns the factor required to achieve this with - * one multiplication. - * - * @param scale is the return value of the getFulscale Method - * @return Multiplication factor to get the sensor value from raw data. - */ - float getSensitivityFactor(uint8_t scale); + /** + * The 16 bit value needs to be divided by the full range of a 16bit value + * and then multiplied with the current scale of the MGM. + * This factor returns the factor required to achieve this with + * one multiplication. + * + * @param scale is the return value of the getFulscale Method + * @return Multiplication factor to get the sensor value from raw data. + */ + float getSensitivityFactor(uint8_t scale); - /** - * This Command detects the device ID - */ - ReturnValue_t identifyDevice(); + /** + * This Command detects the device ID + */ + ReturnValue_t identifyDevice(); - virtual void setupMgm(); + 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); + /*------------------------------------------------------------------------*/ + /* 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); + /** + * 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); - //Length a sindgle command SPI answer - static const uint8_t SINGLE_COMMAND_ANSWER_LEN = 2; + //Length a sindgle command SPI answer + static const uint8_t SINGLE_COMMAND_ANSWER_LEN = 2; - //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]; + //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]; + /** + * 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; + uint8_t statusRegister = 0; - /** - * 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(); + /** + * 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(); - enum class InternalState { - STATE_NONE, - STATE_FIRST_CONTACT, - STATE_SETUP, - STATE_CHECK_REGISTERS, - STATE_NORMAL - }; + 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; + InternalState internalState = InternalState::STATE_NONE; + CommunicationStep communicationStep = CommunicationStep::DATA; + bool commandExecuted = false; #if OBSW_VERBOSE_LEVEL >= 1 - PeriodicOperationDivider* debugDivider; + PeriodicOperationDivider* debugDivider; #endif - void performOperationHook() override; + void performOperationHook() override; }; diff --git a/mission/devices/devicedefinitions/MGMHandlerLIS3Definitions.h b/mission/devices/devicedefinitions/MGMHandlerLIS3Definitions.h index 581e46e3..0d51cda1 100644 --- a/mission/devices/devicedefinitions/MGMHandlerLIS3Definitions.h +++ b/mission/devices/devicedefinitions/MGMHandlerLIS3Definitions.h @@ -24,11 +24,11 @@ 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 +/* Number of all control registers */ static const uint8_t NR_OF_CTRL_REGISTERS = 5; -//Number of registers in the MGM +/* Number of registers in the MGM */ static const uint8_t NR_OF_REGISTERS = 19; -//Total number of adresses for all registers +/* 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; @@ -37,47 +37,47 @@ static const uint8_t SETUP_REPLY_LEN = 6; /*------------------------------------------------------------------------*/ /* Register adresses */ /*------------------------------------------------------------------------*/ -// Register adress returns identifier of device with default 0b00111101 +/* 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 +/* Register adress to access register 1 */ static const uint8_t CTRL_REG1 = 0b00100000; -//Register adress to access register 2 +/* Register adress to access register 2 */ static const uint8_t CTRL_REG2 = 0b00100001; -//Register adress to access register 3 +/* Register adress to access register 3 */ static const uint8_t CTRL_REG3 = 0b00100010; -//Register adress to access register 4 +/* Register adress to access register 4 */ static const uint8_t CTRL_REG4 = 0b00100011; -//Register adress to access register 5 +/* Register adress to access register 5 */ static const uint8_t CTRL_REG5 = 0b00100100; -//Register adress to access status register +/* 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 +/* 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 +/* 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 +/* 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 +/* 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 +/* 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 +/* 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 +/* 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 +/* Register adress to access high byte of temperature sensor */ static const uint8_t TEMP_HIGHBYTE = 0b00101111; /*------------------------------------------------------------------------*/ From 593f30d1d862087941794b63002295e5714037b4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 24 Feb 2021 11:32:24 +0100 Subject: [PATCH 48/51] printf support added --- mission/devices/MGMHandlerLIS3MDL.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/mission/devices/MGMHandlerLIS3MDL.cpp b/mission/devices/MGMHandlerLIS3MDL.cpp index ebe47487..6eb7f5d4 100644 --- a/mission/devices/MGMHandlerLIS3MDL.cpp +++ b/mission/devices/MGMHandlerLIS3MDL.cpp @@ -197,7 +197,11 @@ ReturnValue_t MGMHandlerLIS3MDL::scanForReply(const uint8_t *start, start[3] != registers[2] or start[4] != registers[3] or start[5] != registers[4]) { #if OBSW_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; } @@ -220,7 +224,11 @@ ReturnValue_t MGMHandlerLIS3MDL::scanForReply(const uint8_t *start, if(*foundId == MGMLIS3MDL::IDENTIFY_DEVICE) { if(start[1] != MGMLIS3MDL::DEVICE_ID) { #if OBSW_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; } @@ -276,12 +284,19 @@ ReturnValue_t MGMHandlerLIS3MDL::interpretDeviceReply(DeviceCommandId_t id, #if OBSW_VERBOSE_LEVEL >= 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; - /* Set terminal to utf-8 if there is an issue with micro printout. */ sif::info << "X: " << mgmX << " \xC2\xB5T" << std::endl; sif::info << "Y: " << mgmY << " \xC2\xB5T" << std::endl; sif::info << "Z: " << mgmZ << " \xC2\xB5T" << std::endl; +#else + sif::printInfo("MGMHandlerLIS3: Magnetic field strength in microtesla:\n"); + sif::printInfo("X: %f " "\xC2\xB5" "T\n", mgmX); + sif::printInfo("Y: %f " "\xC2\xB5" "T\n", mgmY); + sif::printInfo("Z: %f " "\xC2\xB5" "T\n", mgmZ); +#endif } #endif PoolReadHelper readHelper(&dataset); @@ -300,8 +315,12 @@ ReturnValue_t MGMHandlerLIS3MDL::interpretDeviceReply(DeviceCommandId_t id, #if OBSW_VERBOSE_LEVEL >= 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 << " \xC2\xB0" << "C" << std::endl; +#else + sif::printInfo("MGMHandlerLIS3: Temperature: %f" "\xC2\xB0" "C\n"); +#endif } #endif ReturnValue_t result = dataset.read(); From 34239aa364d311630c39987e3be536a09d55cdfc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 24 Feb 2021 11:35:22 +0100 Subject: [PATCH 49/51] tab replacements --- bsp_rpi/InitMission.cpp | 142 +++++++++++++++++++------------------- bsp_rpi/ObjectFactory.cpp | 68 +++++++++--------- 2 files changed, 105 insertions(+), 105 deletions(-) diff --git a/bsp_rpi/InitMission.cpp b/bsp_rpi/InitMission.cpp index c0f3e3ea..ce2a5940 100644 --- a/bsp_rpi/InitMission.cpp +++ b/bsp_rpi/InitMission.cpp @@ -25,8 +25,8 @@ ServiceInterfaceStream sif::error("ERROR"); ObjectManagerIF *objectManager = nullptr; void initmission::initMission() { - sif::info << "Building global objects.." << std::endl; - /* Instantiate global object manager and also create all objects */ + sif::info << "Building global objects.." << std::endl; + /* Instantiate global object manager and also create all objects */ objectManager = new ObjectManager(ObjectFactory::produce); sif::info << "Initializing all objects.." << std::endl; objectManager->initialize(); @@ -47,98 +47,98 @@ void initmission::initTasks() { void (*missedDeadlineFunc) (void) = nullptr; #endif - /* TMTC Distribution */ - PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( - "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - ReturnValue_t result = tmTcDistributor->addComponent( - objects::CCSDS_PACKET_DISTRIBUTOR); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } + /* TMTC Distribution */ + PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + ReturnValue_t result = tmTcDistributor->addComponent( + objects::CCSDS_PACKET_DISTRIBUTOR); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Object add component failed" << std::endl; + } + result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Object add component failed" << std::endl; + } result = tmTcDistributor->addComponent(objects::TM_FUNNEL); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Object add component failed" << std::endl; + sif::error << "Object add component failed" << std::endl; } /* UDP bridge */ PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( - "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Add component UDP Unix Bridge failed" << std::endl; + sif::error << "Add component UDP Unix Bridge failed" << std::endl; } PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Add component UDP Polling failed" << std::endl; + sif::error << "Add component UDP Polling failed" << std::endl; } - /* PUS Services */ - PeriodicTaskIF* pusVerification = factory->createPeriodicTask( - "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } + /* PUS Services */ + PeriodicTaskIF* pusVerification = factory->createPeriodicTask( + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Object add component failed" << std::endl; + } - PeriodicTaskIF* pusEvents = factory->createPeriodicTask( - "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); - if(result != HasReturnvaluesIF::RETURN_OK){ + PeriodicTaskIF* pusEvents = factory->createPeriodicTask( + "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + if(result != HasReturnvaluesIF::RETURN_OK){ initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING); - } + } - PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( - "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); - if(result != HasReturnvaluesIF::RETURN_OK) { + PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); - } - result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { + } + result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); - } + } - PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( - "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); - result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { + PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT); - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); } - PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( - "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); - result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); - } + PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); + } #if RPI_TEST_ACS_BOARD == 1 - FixedTimeslotTaskIF* acsTask = factory->createFixedTimeslotTask( - "ACS_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc); - result = pst::pollingSequenceAcsTest(acsTask); + FixedTimeslotTaskIF* acsTask = factory->createFixedTimeslotTask( + "ACS_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc); + result = pst::pollingSequenceAcsTest(acsTask); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "initmission::initTasks: ACS PST initialization failed!" << std::endl; } #endif /* RPI_TEST_ACS_BOARD == 1 */ - PeriodicTaskIF* testTask = factory->createPeriodicTask( - "TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + PeriodicTaskIF* testTask = factory->createPeriodicTask( + "TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); #if OBSW_ADD_TEST_CODE == 1 - result = testTask->addComponent(objects::TEST_TASK); + result = testTask->addComponent(objects::TEST_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); } @@ -156,23 +156,23 @@ void initmission::initTasks() { } #endif /* RPI_ADD_GPIO_TEST == 1 */ - sif::info << "Starting tasks.." << std::endl; - tmTcDistributor->startTask(); - udpBridgeTask->startTask(); - udpPollingTask->startTask(); + sif::info << "Starting tasks.." << std::endl; + tmTcDistributor->startTask(); + udpBridgeTask->startTask(); + udpPollingTask->startTask(); - pusVerification->startTask(); - pusEvents->startTask(); - pusHighPrio->startTask(); - pusMedPrio->startTask(); - pusLowPrio->startTask(); + pusVerification->startTask(); + pusEvents->startTask(); + pusHighPrio->startTask(); + pusMedPrio->startTask(); + pusLowPrio->startTask(); #if OBSW_ADD_TEST_CODE == 1 - testTask->startTask(); + testTask->startTask(); #endif /* OBSW_ADD_TEST_CODE == 1 */ #if RPI_TEST_ACS_BOARD == 1 - acsTask->startTask(); + acsTask->startTask(); #endif /* RPI_TEST_ACS_BOARD == 1 */ - sif::info << "Tasks started.." << std::endl; + sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index 89d548dc..70e6e08e 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -29,60 +29,60 @@ #include void Factory::setStaticFrameworkObjectIds() { - PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; - PusServiceBase::packetDestination = objects::TM_FUNNEL; + PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; + PusServiceBase::packetDestination = objects::TM_FUNNEL; - CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; - CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; + CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; + CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; - TmFunnel::downlinkDestination = objects::UDP_BRIDGE; - // No storage object for now. - TmFunnel::storageDestination = objects::NO_OBJECT; + TmFunnel::downlinkDestination = objects::UDP_BRIDGE; + // No storage object for now. + TmFunnel::storageDestination = objects::NO_OBJECT; - LocalDataPoolManager::defaultHkDestination = objects::NO_OBJECT; + LocalDataPoolManager::defaultHkDestination = objects::NO_OBJECT; - VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION; - TmPacketStored::timeStamperId = objects::TIME_STAMPER; + VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION; + TmPacketStored::timeStamperId = objects::TIME_STAMPER; } void ObjectFactory::produce(){ - Factory::setStaticFrameworkObjectIds(); - ObjectFactory::produceGenericObjects(); + Factory::setStaticFrameworkObjectIds(); + ObjectFactory::produceGenericObjects(); - new TmTcUnixUdpBridge(objects::UDP_BRIDGE, - objects::CCSDS_PACKET_DISTRIBUTOR, - objects::TM_STORE, objects::TC_STORE); - new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); + new TmTcUnixUdpBridge(objects::UDP_BRIDGE, + objects::CCSDS_PACKET_DISTRIBUTOR, + objects::TM_STORE, objects::TC_STORE); + new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF); #if RPI_ADD_SPI_TEST == 1 - new SpiTestClass(objects::SPI_TEST, gpioIF); + new SpiTestClass(objects::SPI_TEST, gpioIF); #endif #if RPI_LOOPBACK_TEST_GPIO == 1 - GpioCookie* gpioCookieLoopback = new GpioCookie(); - /* Loopback pins. Adapt according to setup */ - gpioId_t gpioIdSender = gpioIds::TEST_ID_0; - int bcmPinSender = 26; - gpioId_t gpioIdReader = gpioIds::TEST_ID_1; - int bcmPinReader = 16; - gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER", - gpio::Direction::OUT, 0); + GpioCookie* gpioCookieLoopback = new GpioCookie(); + /* Loopback pins. Adapt according to setup */ + gpioId_t gpioIdSender = gpioIds::TEST_ID_0; + int bcmPinSender = 26; + gpioId_t gpioIdReader = gpioIds::TEST_ID_1; + int bcmPinReader = 16; + gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER", + gpio::Direction::OUT, 0); gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdReader, bcmPinReader, "GPIO_LB_READER", gpio::Direction::IN, 0); - new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookieLoopback); + new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookieLoopback); #endif new SpiComIF(objects::SPI_COM_IF, gpioIF); #if RPI_TEST_ACS_BOARD == 1 - GpioCookie* gpioCookieAcsBoard = new GpioCookie(); - gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_0_LIS3_CS, gpio::MGM_0_BCM_PIN, - "MGM_0_LIS3", gpio::Direction::OUT, 1); + GpioCookie* gpioCookieAcsBoard = new GpioCookie(); + gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_0_LIS3_CS, gpio::MGM_0_BCM_PIN, + "MGM_0_LIS3", gpio::Direction::OUT, 1); gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_1_RM3100_CS, gpio::MGM_1_BCM_PIN, "MGM_1_RM3100", gpio::Direction::OUT, 1); gpio::createRpiGpioConfig(gpioCookieAcsBoard, gpioIds::MGM_2_LIS3_CS, gpio::MGM_2_BCM_PIN, @@ -97,10 +97,10 @@ void ObjectFactory::produce(){ "GYRO_2_L3G", gpio::Direction::OUT, 1); gpioIF->addGpios(gpioCookieAcsBoard); - SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, - gpioIds::MGM_0_LIS3_CS, "/dev/spidev0.0", 24, spi::SpiMode::MODE_3, 3'900'000); - auto mgmHandler = new MGMHandlerLIS3MDL(objects::MGM_0_LIS3_HANDLER, - objects::SPI_COM_IF, spiCookie); - mgmHandler->setStartUpImmediately(); + SpiCookie* spiCookie = new SpiCookie(addresses::MGM_0_LIS3, + gpioIds::MGM_0_LIS3_CS, "/dev/spidev0.0", 24, spi::SpiMode::MODE_3, 3'900'000); + auto mgmHandler = new MGMHandlerLIS3MDL(objects::MGM_0_LIS3_HANDLER, + objects::SPI_COM_IF, spiCookie); + mgmHandler->setStartUpImmediately(); #endif } From 8a92e840acff3b36abb9386241d1e44f0bb4b060 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 24 Feb 2021 11:36:35 +0100 Subject: [PATCH 50/51] small form improvements --- bsp_rpi/ObjectFactory.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index 70e6e08e..3e6eeaa2 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -74,7 +74,7 @@ void ObjectFactory::produce(){ gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdReader, bcmPinReader, "GPIO_LB_READER", gpio::Direction::IN, 0); new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookieLoopback); -#endif +#endif /* RPI_LOOPBACK_TEST_GPIO == 1 */ new SpiComIF(objects::SPI_COM_IF, gpioIF); @@ -102,5 +102,6 @@ void ObjectFactory::produce(){ auto mgmHandler = new MGMHandlerLIS3MDL(objects::MGM_0_LIS3_HANDLER, objects::SPI_COM_IF, spiCookie); mgmHandler->setStartUpImmediately(); -#endif + +#endif /* RPI_TEST_ACS_BOARD == 1 */ } From adc5b9c01623ce6154b6e962bf648fffe08be693 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 24 Feb 2021 11:40:45 +0100 Subject: [PATCH 51/51] tab replacements --- bsp_q7s/InitMission.cpp | 170 +++++++++++++++++++------------------- bsp_q7s/ObjectFactory.cpp | 4 +- 2 files changed, 87 insertions(+), 87 deletions(-) diff --git a/bsp_q7s/InitMission.cpp b/bsp_q7s/InitMission.cpp index a3d0c0dc..72240c5b 100644 --- a/bsp_q7s/InitMission.cpp +++ b/bsp_q7s/InitMission.cpp @@ -31,8 +31,8 @@ ServiceInterfaceStream sif::error("ERROR", true, false, true); ObjectManagerIF *objectManager = nullptr; void initmission::initMission() { - sif::info << "Building global objects.." << std::endl; - /* Instantiate global object manager and also create all objects */ + sif::info << "Building global objects.." << std::endl; + /* Instantiate global object manager and also create all objects */ objectManager = new ObjectManager(ObjectFactory::produce); sif::info << "Initializing all objects.." << std::endl; objectManager->initialize(); @@ -53,18 +53,18 @@ void initmission::initTasks() { void (*missedDeadlineFunc) (void) = nullptr; #endif - /* TMTC Distribution */ - PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( - "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - ReturnValue_t result = tmTcDistributor->addComponent( - objects::CCSDS_PACKET_DISTRIBUTOR); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR); - } - result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); - if(result != HasReturnvaluesIF::RETURN_OK) { + /* TMTC Distribution */ + PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + ReturnValue_t result = tmTcDistributor->addComponent( + objects::CCSDS_PACKET_DISTRIBUTOR); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR); + } + result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR); - } + } result = tmTcDistributor->addComponent(objects::TM_FUNNEL); if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL); @@ -72,7 +72,7 @@ void initmission::initTasks() { /* UDP bridge */ PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( - "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE); @@ -84,81 +84,81 @@ void initmission::initTasks() { initmission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK); } - /* PUS Services */ - PeriodicTaskIF* pusVerification = factory->createPeriodicTask( - "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); - if(result != HasReturnvaluesIF::RETURN_OK) { + /* PUS Services */ + PeriodicTaskIF* pusVerification = factory->createPeriodicTask( + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION); - } + } - PeriodicTaskIF* pusEvents = factory->createPeriodicTask( - "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); - if(result != HasReturnvaluesIF::RETURN_OK) { + PeriodicTaskIF* pusEvents = factory->createPeriodicTask( + "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); - } + } - PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( - "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); - if(result != HasReturnvaluesIF::RETURN_OK) { + PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS); - } - result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { + } + result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT); - } + } - PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( - "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); - result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { + PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT); - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK) { + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT); - } - result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); - } + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); + } - PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( - "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); - result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); - if(result != HasReturnvaluesIF::RETURN_OK) { + PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST); - } + } - //TODO: Add handling of missed deadlines - /* Polling Sequence Table Default */ - FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask( - "PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, - missedDeadlineFunc); - result = pst::pollingSequenceInitDefault(pollingSequenceTableTaskDefault); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; - } + //TODO: Add handling of missed deadlines + /* Polling Sequence Table Default */ + FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask( + "PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, + missedDeadlineFunc); + result = pst::pollingSequenceInitDefault(pollingSequenceTableTaskDefault); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; + } #if TE0720 == 0 - FixedTimeslotTaskIF* gomSpacePstTask = factory-> - createFixedTimeslotTask("GS_PST_TASK", 50, - PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, missedDeadlineFunc); - result = pst::gomspacePstInit(gomSpacePstTask); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl; - } + FixedTimeslotTaskIF* gomSpacePstTask = factory-> + createFixedTimeslotTask("GS_PST_TASK", 50, + PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, missedDeadlineFunc); + result = pst::gomspacePstInit(gomSpacePstTask); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl; + } #endif - PeriodicTaskIF* testTask = factory->createPeriodicTask( - "GPIOD_TEST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc); + PeriodicTaskIF* testTask = factory->createPeriodicTask( + "GPIOD_TEST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc); #if OBSW_ADD_TEST_CODE == 1 - result = testTask->addComponent(objects::TEST_TASK); - if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); - } + result = testTask->addComponent(objects::TEST_TASK); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + } #endif /* OBSW_ADD_TEST_CODE == 1 */ #if TE0720 == 1 && TEST_LIBGPIOD == 1 result = testTask->addComponent(objects::LIBGPIOD_TEST); @@ -167,22 +167,22 @@ void initmission::initTasks() { } #endif /* TE0720 == 1 && TEST_LIBGPIOD == 1 */ - sif::info << "Starting tasks.." << std::endl; - tmTcDistributor->startTask(); - udpBridgeTask->startTask(); - udpPollingTask->startTask(); + sif::info << "Starting tasks.." << std::endl; + tmTcDistributor->startTask(); + udpBridgeTask->startTask(); + udpPollingTask->startTask(); #if TE0720 == 0 - gomSpacePstTask->startTask(); + gomSpacePstTask->startTask(); #endif - pollingSequenceTableTaskDefault->startTask(); + pollingSequenceTableTaskDefault->startTask(); - pusVerification->startTask(); - pusEvents->startTask(); - pusHighPrio->startTask(); - pusMedPrio->startTask(); - pusLowPrio->startTask(); + pusVerification->startTask(); + pusEvents->startTask(); + pusHighPrio->startTask(); + pusMedPrio->startTask(); + pusLowPrio->startTask(); - testTask->startTask(); - sif::info << "Tasks started.." << std::endl; + testTask->startTask(); + sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index d69683ef..6a3b16bc 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -158,10 +158,10 @@ void ObjectFactory::produce(){ GpioCookie* solarArrayDeplCookie = new GpioCookie; GpiodRegular gpioConfigDeplSA1(std::string("gpiochip7"), 25, - std::string("DeplSA1"), gpio::OUT, 0); + std::string("DeplSA1"), gpio::OUT, 0); solarArrayDeplCookie->addGpio(gpioIds::DEPLSA1, gpioConfigDeplSA1); GpiodRegular gpioConfigDeplSA2(std::string("gpiochip7"), 23, - std::string("DeplSA2"), gpio::OUT, 0); + std::string("DeplSA2"), gpio::OUT, 0); solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpioConfigDeplSA2); //TODO: Find out burn time. For now set to 1000 ms.