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_ */