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.