gpio bugfix

This commit is contained in:
Robin Müller 2021-02-23 16:47:34 +01:00 committed by Robin Mueller
parent bb04d4fb4c
commit ddabbd6e3b
6 changed files with 193 additions and 25 deletions

View File

@ -51,10 +51,10 @@ void ObjectFactory::produce(){
objects::TM_STORE, objects::TC_STORE); objects::TM_STORE, objects::TC_STORE);
new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); 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 #if RPI_ADD_SPI_TEST == 1
new SpiTestClass(objects::SPI_TEST); new SpiTestClass(objects::SPI_TEST, gpioIF);
#endif #endif
#if RPI_LOOPBACK_TEST_GPIO == 1 #if RPI_LOOPBACK_TEST_GPIO == 1

View File

@ -15,6 +15,15 @@ namespace gpioIds {
HEATER_7, HEATER_7,
DEPLSA1, DEPLSA1,
DEPLSA2, 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_0,
TEST_ID_1 TEST_ID_1
}; };

View File

@ -1,8 +1,91 @@
#include <linux/boardtest/SpiTestClass.h> #include "SpiTestClass.h"
SpiTestClass::SpiTestClass(object_id_t objectId): TestTask(objectId) { #include <fsfwconfig/devices/gpioIds.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <linux/spi/spidev.h>
#include <fcntl.h>
#include <linux/gpio/gpioDefinitions.h>
#include <linux/gpio/GpioCookie.h>
#include <unistd.h>
#include <sys/ioctl.h>
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() { ReturnValue_t SpiTestClass::performPeriodicAction() {
return HasReturnvaluesIF::RETURN_OK; 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);
}
}

View File

@ -1,15 +1,47 @@
#ifndef LINUX_BOARDTEST_SPITESTCLASS_H_ #ifndef LINUX_BOARDTEST_SPITESTCLASS_H_
#define LINUX_BOARDTEST_SPITESTCLASS_H_ #define LINUX_BOARDTEST_SPITESTCLASS_H_
#include <linux/gpio/GpioIF.h>
#include <linux/spi/SpiCookie.h>
#include <test/testtasks/TestTask.h> #include <test/testtasks/TestTask.h>
#include <vector>
class SpiTestClass: public TestTask { class SpiTestClass: public TestTask {
public: 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; ReturnValue_t performPeriodicAction() override;
private: private:
GpioIF* gpioIF;
std::array<uint8_t, 128> recvBuffer;
std::array<uint8_t, 128> 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;
}; };

View File

@ -24,6 +24,7 @@ ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) {
GpioMap mapToAdd = gpioCookie->getGpioMap(); GpioMap mapToAdd = gpioCookie->getGpioMap();
/* Check whether this ID already exists in the map and remove duplicates */
result = checkForConflicts(mapToAdd); result = checkForConflicts(mapToAdd);
if (result != RETURN_OK){ if (result != RETURN_OK){
return result; return result;
@ -48,6 +49,9 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
} }
case(gpio::GpioTypes::GPIOD_REGULAR): { case(gpio::GpioTypes::GPIOD_REGULAR): {
GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second); GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second);
if(regularGpio == nullptr) {
return GPIO_INVALID_INSTANCE;
}
configureRegularGpio(gpioConfig.first, regularGpio); configureRegularGpio(gpioConfig.first, regularGpio);
break; break;
} }
@ -57,7 +61,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
return GPIO_INVALID_INSTANCE; return GPIO_INVALID_INSTANCE;
} }
gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::READ, 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) { if(regularGpio == nullptr) {
return GPIO_TYPE_FAILURE; 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<GpioCallback*>(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) { if(result != HasReturnvaluesIF::RETURN_OK) {
status = result; status = result;
} }
@ -235,29 +252,53 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){
ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck, ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck,
GpiodRegular* gpioToCheck) { GpiodRegular* gpioToCheck, GpioMap& mapToAdd) {
/* Cross check with private map */ /* Cross check with private map */
gpioMapIter = gpioMap.find(gpioIdToCheck); gpioMapIter = gpioMap.find(gpioIdToCheck);
if(gpioMapIter != gpioMap.end()) { if(gpioMapIter != gpioMap.end()) {
if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { 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<GpiodRegular*>(gpioMapIter->second); auto ownRegularGpio = dynamic_cast<GpiodRegular*>(gpioMapIter->second);
if(ownRegularGpio == nullptr) { if(ownRegularGpio == nullptr) {
return GPIO_TYPE_FAILURE; return GPIO_TYPE_FAILURE;
} }
/* An entry for this GPIO already exists. Check if configuration /* An entry for this GPIO already exists. Check if configuration
* of direction is equivalent */ * of direction is equivalent */
if (gpioToCheck->direction != ownRegularGpio->direction){ if (gpioToCheck->direction != ownRegularGpio->direction) {
sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict for GPIO " << sif::warning << "LinuxLibgpioIF::checkForConflicts: Detected conflict for GPIO " <<
gpioIdToCheck << std::endl; gpioIdToCheck << std::endl;
return RETURN_FAILED;
}
} }
/* Remove element from map to add because a entry for this GPIO /* Remove element from map to add because a entry for this GPIO
* already exists */ already exists */
gpioMap.erase(gpioIdToCheck); 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; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -62,7 +62,10 @@ private:
*/ */
ReturnValue_t checkForConflicts(GpioMap& mapToAdd); 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. * @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd.