old approach gpio lib

This commit is contained in:
Jakob Meier 2021-01-16 12:22:17 +01:00
parent 51feaf962c
commit b7d3818202
6 changed files with 400 additions and 3 deletions

View File

@ -56,9 +56,9 @@ void ObjectFactory::produce(){
CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_LENGTH,
addresses::ACU);
I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-1"));
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0"));
I2cCookie* i2cCookieTmp1075tcs2 = new I2cCookie(addresses::TMP1075_TCS_2,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-1"));
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0"));
/* Communication interfaces */
new CspComIF(objects::CSP_COM_IF);
@ -77,6 +77,7 @@ void ObjectFactory::produce(){
new GomspaceDeviceHandler(objects::ACU_HANDLER, objects::CSP_COM_IF,
acuCspCookie, ACU::MAX_CONFIGTABLE_ADDRESS,
ACU::MAX_HKTABLE_ADDRESS);
/* Temperature sensors */
Tmp1075Handler* tmp1075Handler_1 = new Tmp1075Handler(
objects::TMP1075_HANDLER_1, objects::I2C_COM_IF,
i2cCookieTmp1075tcs1);

265
bsp_q7s/comIF/GpioComIF.cpp Normal file
View File

@ -0,0 +1,265 @@
#include <bsp_q7s/comIF/GpioComIF.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <fcntl.h>
#include <string.h>
GpioComIF::GpioComIF(object_id_t objectId): SystemObject(objectId){
}
GpioComIF::~GpioComIF() {}
ReturnValue_t GpioComIF::initializeInterface(CookieIF * cookie) {
ReturnValue_t result;
GpioMap mapToAdd;
if(cookie == nullptr) {
return NULLPOINTER;
}
GpioCookie* GpioCookie = dynamic_cast<GpioCookie*>(cookie);
if(GpioCookie == nullptr) {
sif::error << "GpioComIF: Invalid Gpio Cookie!"
<< std::endl;
return NULLPOINTER;
}
mapToAdd = GpioCookie->getGpioMap();
result = checkForConflicts(mapToAdd);
if (result != HasReturnvaluesIF::RETURN_OK){
return result;
}
/* Register new GPIOs in gpioMap*/
result = initializeAndConfigure(mapToAdd);
if (result != HasReturnvaluesIF::RETURN_OK){
return result;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GpioComIF::sendMessage(CookieIF *cookie,
const uint8_t *sendData, size_t sendLen) {
ReturnValue_t result;
int fd;
std::string deviceFile;
if(sendData == nullptr) {
sif::error << "GpioComIF::sendMessage: Send Data is nullptr"
<< std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
if(sendLen == 0) {
return HasReturnvaluesIF::RETURN_OK;
}
I2cCookie* i2cCookie = dynamic_cast<I2cCookie*>(cookie);
if(i2cCookie == nullptr) {
sif::error << "GpioComIF::sendMessasge: Invalid I2C Cookie!"
<< std::endl;
return NULLPOINTER;
}
address_t i2cAddress = i2cCookie->getAddress();
i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
sif::error << "GpioComIF::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;
}
if (write(fd, sendData, sendLen) != (int)sendLen) {
sif::error << "GpioComIF::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 GpioComIF::getSendSuccess(CookieIF *cookie) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GpioComIF::requestReceiveMessage(CookieIF *cookie,
size_t requestLen) {
ReturnValue_t result;
int fd;
std::string deviceFile;
if (requestLen == 0) {
return HasReturnvaluesIF::RETURN_OK;
}
I2cCookie* i2cCookie = dynamic_cast<I2cCookie*>(cookie);
if(i2cCookie == nullptr) {
sif::error << "GpioComIF::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 << "GpioComIF::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;
}
uint8_t* replyBuffer = i2cDeviceMapIter->second.replyBuffer.data();
if (read(fd, replyBuffer, requestLen) != (int)requestLen) {
sif::error << "GpioComIF::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;
}
ReturnValue_t GpioComIF::readReceivedMessage(CookieIF *cookie,
uint8_t **buffer, size_t* size) {
I2cCookie* i2cCookie = dynamic_cast<I2cCookie*>(cookie);
if(i2cCookie == nullptr) {
sif::error << "GpioComIF::readReceivedMessage: Invalid I2C Cookie!"
<< std::endl;
return NULLPOINTER;
}
address_t i2cAddress = i2cCookie->getAddress();
i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
sif::error << "GpioComIF::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;
}
ReturnValue_t GpioComIF::openDevice(std::string deviceFile,
address_t i2cAddress, int* fileDescriptor) {
*fileDescriptor = open(deviceFile.c_str(), O_RDWR);
if (*fileDescriptor < 0) {
sif::error << "GpioComIF: 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 << "GpioComIF: Specifying target device failed with error "
<< "code " << errno << ". Error description "
<< strerror(errno) << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GpioComIF::checkForConflicts(GpioMap mapToAdd){
gpio_t gpio;
GpioMapIter mapToAddIter = mapToAdd.begin();
for(; mapToAddIter != mapToAdd.end(); mapToAddIter++){
gpio = mapToAddIter.first();
if(gpioMapIter.find(gpio) != mapToAdd.end()){
/* An entry for this GPIO already exists. Check if configuration
* of direction is equivalent */
if (mapToAddIter.second() != gpioMapIter.second()){
sif::error << "GpioComIF::checkForConflicts: Detected conflict "
<< "for GPIO " << mapToAddIter.first() << std::endl;
return HasReturnvaluesIF::RETURN_OK;
}
/* Remove element from map to add because a entry for this GPIO
* already exists */
mapToAdd.erase(mapToAddIter);
}
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GpioComIF::initializeAndConfigure(GpioMap mapToAdd){
int exportfd;
int directionfd;
std::string gpioStr;
GpioMapIter mapToAddItr;
mapToAddItr = mapToAdd.begin();
/* Perform initialization for all GPIOs in map */
for(; mapToAddItr != mapToAdd.end(); mapToAddItr++){
/* The GPIO has to be exported to be able to see it in sysfs */
exportfd = open("/sys/class/gpio/export", O_WRONLY);
if (exportfd < 0)
{
sif::error << "GpioComIF::initializeAndConfigure: Cannot open GPIO "
<< mapToAddItr.first() << " to export it" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
gpioStr = std::to_string(mapToAddItr.first());
write(exportfd, gpioStr.c_str(), gpioStr.length() + 1);
close(exportfd);
/* Set direction of the GPIO */
std::string directionPath = "/sys/class/gpio/" + gpioStr +
"/direction";
directionfd = open(directionPath.c_str(), O_RDWR);
if (directionfd < 0)
{
sif::error << "Cannot open " << directionPath.c_str() << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
if (mapToAdd.second() == Gpio::IN) {
write(directionfd, "in", 3);
}
else if (mapToAdd.second() == Gpio::OUT) {
write(directionfd, "out", 4);
}
else {
sif::error << "GpioComIF::initializeAndConfigure: Invalid direction"
<< " specified" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
close(directionfd);
/* Add GPIO to GpioMap of GpioComIF */
std::pair insertionResult = gpioMap.insert(mapToAddItr);
if (insertionResult.second() != true) {
sif::error << "GpioComIF::initializeAndConfigure: Failed to add "
<< "GPIO " << gpioStr.c_st() << " to gpioMap" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
}
return HasReturnvaluesIF::RETURN_OK;
}

57
bsp_q7s/comIF/GpioComIF.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef BSP_Q7S_COMIF_I2s COMIF_H_
#define BSP_Q7S_COMIF_I2COMIF_H_
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
#include <bsp_q7s/comIF/cookies/GpioCookie.h>
/**
* @brief This is the communication interface to drive GPIOs by using the
* the linux sysfs.
*
* @author J. Meier
*/
class GpioComIF: public DeviceCommunicationIF, public SystemObject {
public:
GpioComIF(object_id_t objectId);
virtual ~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:
/* All GPIOs will be stored in this map after successful initialization */
GpioMap gpioMap;
GpioMapIter gpioMapIter;
/**
* @brief This function checks if GPIOs are already registered and whether
* there exists a conflict in the GPIO configuration. E.g. the
* direction.
*
* @param mapToAdd The GPIOs which shall be added to the gpioMap
*
* @return RETURN_OK if successful, otherwise RETURN_FAILED
*/
ReturnValue_t checkForConflicts(GpioMap mapToAdd);
/**
* @brief This function initializes all GPIOs specified in the mapToAdd.
*
* @param Map with the GPIOs to initialize.
*
* @return RETURN_OK if successful, otherwise RETURN_FAILED
*/
ReturnValue_t GpioComIF::initializeAndConfigure(GpioMap mapToAdd);
};
#endif /* BSP_Q7S_COMIF_I2COMIF_H_ */

View File

@ -121,7 +121,7 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF *cookie,
I2cCookie* i2cCookie = dynamic_cast<I2cCookie*>(cookie);
if(i2cCookie == nullptr) {
sif::error << "I2cComIF::sendMessage: Invalid I2C Cookie!"
sif::error << "I2cComIF::requestReceiveMessage: Invalid I2C Cookie!"
<< std::endl;
i2cDeviceMapIter->second.replyLen = 0;
return NULLPOINTER;

View File

@ -0,0 +1,26 @@
#include <bsp_q7s/comIF/cookies/GpioCookie.h>
GpioCookie::GpioCookie() {
}
void GpioCookie::addGpio(gpioMap newEntry){
gpioMapIter = gpioMap.find(newEntry);
if(gpioMapIter == gpioMap.end()) {
std::pair status = i2cDeviceMap.emplace(newEntry);
if (status.second == false) {
sif::error << "GpioCookie::addGpio: Failed to add GPIO "
<< newEntry.first << "to GPIO map" << std::endl;
return HasReturnvaluesIF::RETURN_OK;
}
}
else {
sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map "
<< std::endl;
}
}
GpioMap getGpioMap() const{
return gpioMap;
}
GpioCookie::~GpioCookie() {}

View File

@ -0,0 +1,48 @@
#ifndef SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_
#define SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_
#include <fsfw/devicehandlers/CookieIF.h>
#include <string>
namespace Gpio {
enum Direction {
IN = 0,
OUT = 1
};
}
using gpio_t = uint32_t;
using direction_t = bool;
using GpioMap = std::unordered_map<gpio_t, direction_t>;
using GpioMapIter = GpioMap::iterator;
/**
* @brief Cookie for the GpioComIF. Allows the GpioComIF to determine which
* GPIOs to initialize and whether they should be configured as in- or
* output.
* @details One GpioCookie can hold multiple GPIO configurations. To add a new
* GPIO configuration to a GpioCookie use the GpioCookie::addGpio
* function.
*
* @author J. Meier
*/
class GpioCookie: public CookieIF {
public:
GpioCookie();
virtual ~GpioCookie();
void addGpio(gpioMap newEntry);
/**
* @brief Get map with register GPIOs.
*/
GpioMap getGpioMap() const;
private:
GpioMap gpioMap;
GpioMapIter gpioMapIter;
};
#endif