Update Linux GPIO #20

Merged
meierj merged 26 commits from mueller/update-linux-gpio into eive/develop 2021-09-27 15:28:20 +02:00
4 changed files with 107 additions and 15 deletions
Showing only changes of commit e227b5dead - Show all commits

View File

@ -28,6 +28,7 @@ enum GpioTypes {
NONE, NONE,
GPIO_REGULAR_BY_CHIP, GPIO_REGULAR_BY_CHIP,
GPIO_REGULAR_BY_LABEL, GPIO_REGULAR_BY_LABEL,
GPIO_REGULAR_BY_LINE_NAME,
CALLBACK CALLBACK
}; };
@ -75,6 +76,12 @@ public:
int initValue, int lineNum): GpioBase(gpioType, consumer, direction, initValue), int initValue, int lineNum): GpioBase(gpioType, consumer, direction, initValue),
lineNum(lineNum) { lineNum(lineNum) {
} }
// line number will be configured at a later point for the open by line name configuration
GpiodRegularBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction,
int initValue): GpioBase(gpioType, consumer, direction, initValue) {
}
int lineNum = 0; int lineNum = 0;
struct gpiod_line* lineHandle = nullptr; struct gpiod_line* lineHandle = nullptr;
}; };
@ -120,6 +127,27 @@ public:
std::string label; std::string label;
}; };
/**
* @brief Passing this GPIO configuration to the GPIO IF object will try to open the GPIO by its
* line name. This line name can be set in the device tree and must be unique. Otherwise
* the driver will open the first line with the given name.
*/
class GpiodRegularByLineName: public GpiodRegularBase {
public:
GpiodRegularByLineName(std::string lineName_, std::string consumer_, gpio::Direction direction_,
int initValue_) :
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_, direction_,
initValue_), lineName(lineName_) {
}
GpiodRegularByLineName(std::string lineName_, std::string consumer_) :
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_, gpio::Direction::IN,
gpio::LOW), lineName(lineName_) {
}
std::string lineName;
};
class GpioCallback: public GpioBase { class GpioCallback: public GpioBase {
public: public:
GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_, GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_,

View File

@ -73,7 +73,7 @@ ReturnValue_t MgmLIS3MDLHandler::buildTransitionDeviceCommand(
switch (internalState) { switch (internalState) {
case(InternalState::STATE_NONE): case(InternalState::STATE_NONE):
case(InternalState::STATE_NORMAL): { case(InternalState::STATE_NORMAL): {
return HasReturnvaluesIF::RETURN_OK; return DeviceHandlerBase::NOTHING_TO_SEND;
} }
case(InternalState::STATE_FIRST_CONTACT): { case(InternalState::STATE_FIRST_CONTACT): {
*id = MGMLIS3MDL::IDENTIFY_DEVICE; *id = MGMLIS3MDL::IDENTIFY_DEVICE;

View File

@ -66,6 +66,14 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
configureGpioByLabel(gpioConfig.first, *regularGpio); configureGpioByLabel(gpioConfig.first, *regularGpio);
break; break;
} }
case(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME):{
auto regularGpio = dynamic_cast<GpiodRegularByLineName*>(gpioConfig.second);
if(regularGpio == nullptr) {
return GPIO_INVALID_INSTANCE;
}
configureGpioByLineName(gpioConfig.first, *regularGpio);
break;
}
case(gpio::GpioTypes::CALLBACK): { case(gpio::GpioTypes::CALLBACK): {
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioConfig.second); auto gpioCallback = dynamic_cast<GpioCallback*>(gpioConfig.second);
if(gpioCallback->callback == nullptr) { if(gpioCallback->callback == nullptr) {
@ -84,13 +92,13 @@ ReturnValue_t LinuxLibgpioIF::configureGpioByLabel(gpioId_t gpioId,
std::string& label = gpioByLabel.label; std::string& label = gpioByLabel.label;
struct gpiod_chip* chip = gpiod_chip_open_by_label(label.c_str()); struct gpiod_chip* chip = gpiod_chip_open_by_label(label.c_str());
if (chip == nullptr) { if (chip == nullptr) {
sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open gpio from gpio " sif::warning << "LinuxLibgpioIF::configureGpioByLabel: Failed to open gpio from gpio "
<< "group with label " << label << ". Gpio ID: " << gpioId << std::endl; << "group with label " << label << ". Gpio ID: " << gpioId << std::endl;
return RETURN_FAILED; return RETURN_FAILED;
} }
std::string failOutput = "label: " + label; std::string failOutput = "label: " + label;
return configureRegularGpio(gpioId, gpioByLabel.gpioType, chip, gpioByLabel, failOutput); return configureRegularGpio(gpioId, chip, gpioByLabel, failOutput);
} }
ReturnValue_t LinuxLibgpioIF::configureGpioByChip(gpioId_t gpioId, ReturnValue_t LinuxLibgpioIF::configureGpioByChip(gpioId_t gpioId,
@ -98,16 +106,41 @@ ReturnValue_t LinuxLibgpioIF::configureGpioByChip(gpioId_t gpioId,
std::string& chipname = gpioByChip.chipname; std::string& chipname = gpioByChip.chipname;
struct gpiod_chip* chip = gpiod_chip_open_by_name(chipname.c_str()); struct gpiod_chip* chip = gpiod_chip_open_by_name(chipname.c_str());
if (chip == nullptr) { if (chip == nullptr) {
sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open chip " sif::warning << "LinuxLibgpioIF::configureGpioByChip: Failed to open chip "
<< chipname << ". Gpio ID: " << gpioId << std::endl; << chipname << ". Gpio ID: " << gpioId << std::endl;
return RETURN_FAILED; return RETURN_FAILED;
} }
std::string failOutput = "chipname: " + chipname; std::string failOutput = "chipname: " + chipname;
return configureRegularGpio(gpioId, gpioByChip.gpioType, chip, gpioByChip, failOutput); return configureRegularGpio(gpioId, chip, gpioByChip, failOutput);
} }
ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, gpio::GpioTypes gpioType, ReturnValue_t LinuxLibgpioIF::configureGpioByLineName(gpioId_t gpioId,
struct gpiod_chip* chip, GpiodRegularBase& regularGpio, std::string failOutput) { GpiodRegularByLineName &gpioByLineName) {
std::string& lineName = gpioByLineName.lineName;
char chipname[MAX_CHIPNAME_LENGTH];
unsigned int lineOffset;
int result = gpiod_ctxless_find_line(lineName.c_str(), chipname, MAX_CHIPNAME_LENGTH,
&lineOffset);
if (result != LINE_FOUND) {
parseFindeLineResult(result, lineName);
return RETURN_FAILED;
}
gpioByLineName.lineNum = static_cast<int>(lineOffset);
struct gpiod_chip* chip = gpiod_chip_open_by_name(chipname);
if (chip == nullptr) {
sif::warning << "LinuxLibgpioIF::configureGpioByLineName: Failed to open chip "
<< chipname << ". <Gpio ID: " << gpioId << std::endl;
return RETURN_FAILED;
}
std::string failOutput = "line name: " + lineName;
return configureRegularGpio(gpioId, chip, gpioByLineName, failOutput);
}
ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, struct gpiod_chip* chip,
GpiodRegularBase& regularGpio, std::string failOutput) {
unsigned int lineNum; unsigned int lineNum;
gpio::Direction direction; gpio::Direction direction;
std::string consumer; std::string consumer;
@ -173,8 +206,9 @@ ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) {
} }
auto gpioType = gpioMapIter->second->gpioType; auto gpioType = gpioMapIter->second->gpioType;
if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or if (gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP
gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL
or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME) {
auto regularGpio = dynamic_cast<GpiodRegularBase*>(gpioMapIter->second); auto regularGpio = dynamic_cast<GpiodRegularBase*>(gpioMapIter->second);
if(regularGpio == nullptr) { if(regularGpio == nullptr) {
return GPIO_TYPE_FAILURE; return GPIO_TYPE_FAILURE;
@ -201,8 +235,9 @@ ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) {
} }
auto& gpioType = gpioMapIter->second->gpioType; auto& gpioType = gpioMapIter->second->gpioType;
if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or if (gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP
gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL
or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME) {
auto regularGpio = dynamic_cast<GpiodRegularBase*>(gpioMapIter->second); auto regularGpio = dynamic_cast<GpiodRegularBase*>(gpioMapIter->second);
if(regularGpio == nullptr) { if(regularGpio == nullptr) {
return GPIO_TYPE_FAILURE; return GPIO_TYPE_FAILURE;
@ -239,9 +274,11 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) {
sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl; sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl;
return UNKNOWN_GPIO_ID; return UNKNOWN_GPIO_ID;
} }
auto gpioType = gpioMapIter->second->gpioType; auto gpioType = gpioMapIter->second->gpioType;
if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or if (gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP
gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL
or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME) {
auto regularGpio = dynamic_cast<GpiodRegularBase*>(gpioMapIter->second); auto regularGpio = dynamic_cast<GpiodRegularBase*>(gpioMapIter->second);
if(regularGpio == nullptr) { if(regularGpio == nullptr) {
return GPIO_TYPE_FAILURE; return GPIO_TYPE_FAILURE;
@ -342,3 +379,21 @@ ReturnValue_t LinuxLibgpioIF::checkForConflictsCallbackGpio(gpioId_t gpioIdToChe
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void LinuxLibgpioIF::parseFindeLineResult(int result, std::string& lineName) {
switch (result) {
case LINE_NOT_EXISTS:
sif::warning << "LinuxLibgpioIF::parseFindeLineResult: Line with name " << lineName
<< " does not exist" << std::endl;
break;
case LINE_ERROR:
sif::warning << "LinuxLibgpioIF::parseFindeLineResult: " << "Line with name "
<< lineName << " does not exist" << std::endl;
break;
default:
sif::warning << "LinuxLibgpioIF::parseFindeLineResult: Unknown return code for line with "
<< "name " << lineName << std::endl;
break;
}
}

View File

@ -38,6 +38,12 @@ public:
ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override; ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override;
private: private:
static const size_t MAX_CHIPNAME_LENGTH = 11;
static const int LINE_NOT_EXISTS = 0;
static const int LINE_ERROR = -1;
static const int LINE_FOUND = 1;
/* Holds the information and configuration of all used GPIOs */ /* Holds the information and configuration of all used GPIOs */
GpioUnorderedMap gpioMap; GpioUnorderedMap gpioMap;
GpioUnorderedMapIter gpioMapIter; GpioUnorderedMapIter gpioMapIter;
@ -53,8 +59,10 @@ private:
ReturnValue_t configureGpioByLabel(gpioId_t gpioId, GpiodRegularByLabel& gpioByLabel); ReturnValue_t configureGpioByLabel(gpioId_t gpioId, GpiodRegularByLabel& gpioByLabel);
ReturnValue_t configureGpioByChip(gpioId_t gpioId, GpiodRegularByChip& gpioByChip); ReturnValue_t configureGpioByChip(gpioId_t gpioId, GpiodRegularByChip& gpioByChip);
ReturnValue_t configureRegularGpio(gpioId_t gpioId, gpio::GpioTypes gpioType, ReturnValue_t configureGpioByLineName(gpioId_t gpioId,
struct gpiod_chip* chip, GpiodRegularBase& regularGpio, std::string failOutput); GpiodRegularByLineName &gpioByLineName);
ReturnValue_t configureRegularGpio(gpioId_t gpioId, struct gpiod_chip* chip,
GpiodRegularBase& regularGpio, std::string failOutput);
/** /**
* @brief This function checks if GPIOs are already registered and whether * @brief This function checks if GPIOs are already registered and whether
@ -77,6 +85,7 @@ private:
*/ */
ReturnValue_t configureGpios(GpioMap& mapToAdd); ReturnValue_t configureGpios(GpioMap& mapToAdd);
void parseFindeLineResult(int result, std::string& lineName);
}; };
#endif /* LINUX_GPIO_LINUXLIBGPIOIF_H_ */ #endif /* LINUX_GPIO_LINUXLIBGPIOIF_H_ */