From 2fe1a6683606eddb76aa810f88e5cf5d8cea94e5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 May 2021 00:13:59 +0200 Subject: [PATCH] added callback function --- linux/spi/SpiComIF.cpp | 166 +++++++++++++++++++------------------ linux/spi/SpiComIF.h | 1 + linux/spi/SpiCookie.cpp | 4 +- linux/spi/SpiCookie.h | 2 +- linux/spi/spiDefinitions.h | 7 +- 5 files changed, 95 insertions(+), 85 deletions(-) diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index 3cc81f8..494c112 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -138,7 +138,6 @@ 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; - int retval = 0; if(spiCookie == nullptr) { return NULLPOINTER; @@ -159,95 +158,100 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s } if(spiCookie->getComIfMode() == spi::SpiComIfModes::REGULAR) { - /* Prepare transfer */ - int fileDescriptor = 0; - std::string device = spiCookie->getSpiDevice(); - UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, - "SpiComIF::sendMessage: "); - if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { - return OPENING_FILE_FAILED; - } - spi::SpiModes spiMode = spi::SpiModes::MODE_0; - uint32_t spiSpeed = 0; - spiCookie->getSpiParameters(spiMode, spiSpeed, nullptr); - setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); - spiCookie->assignWriteBuffer(sendData); - spiCookie->assignTransferSize(sendLen); - - bool fullDuplex = spiCookie->isFullDuplex(); - gpioId_t gpioId = spiCookie->getChipSelectPin(); - - /* Pull SPI CS low. For now, no support for active high given */ - if(gpioId != gpio::NO_GPIO) { - result = spiMutex->lockMutex(timeoutType, timeoutMs); - if (result != RETURN_OK) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "SpiComIF::sendMessage: Failed to lock mutex" << std::endl; -#endif - return result; - } - gpioComIF->pullLow(gpioId); - } - - /* Execute transfer */ - if(fullDuplex) { - /* Initiate a full duplex SPI transfer. */ - retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle()); - if(retval < 0) { - utility::handleIoctlError("SpiComIF::sendMessage: ioctl error."); - result = FULL_DUPLEX_TRANSFER_FAILED; - } -#if FSFW_HAL_LINUX_SPI_WIRETAPPING == 1 - size_t dataLen = spiCookie->getTransferStructHandle()->len; - uint8_t* dataPtr = reinterpret_cast(spiCookie->getTransferStructHandle()->tx_buf); -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "Sent SPI data: " << std::endl; - arrayprinter::print(dataPtr, dataLen, OutputType::HEX, false); - sif::info << "Received SPI data: " << std::endl; -#else - sif::printInfo("Sent SPI data: \n"); - arrayprinter::print(dataPtr, dataLen, OutputType::HEX, false); - sif::printInfo("Received SPI data: \n"); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ - dataPtr = reinterpret_cast(spiCookie->getTransferStructHandle()->rx_buf); - arrayprinter::print(dataPtr, dataLen, OutputType::HEX, false); -#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */ - } - else { - /* We write with a blocking half-duplex transfer here */ - if (write(fileDescriptor, sendData, sendLen) != static_cast(sendLen)) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << - std::endl; -#else - sif::printWarning("SpiComIF::sendMessage: Half-Duplex write operation failed!\n"); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - result = HALF_DUPLEX_TRANSFER_FAILED; - } - } - - if(gpioId != gpio::NO_GPIO) { - gpioComIF->pullHigh(gpioId); - result = spiMutex->unlockMutex(); - if (result != RETURN_OK) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "SpiComIF::sendMessage: Failed to unlock mutex" << std::endl; -#endif - return result; - } - } + result = performRegularSendOperation(spiCookie, sendData, sendLen); } else if(spiCookie->getComIfMode() == spi::SpiComIfModes::CALLBACK) { spi::send_callback_function_t sendFunc = nullptr; void* funcArgs = nullptr; spiCookie->getCallback(&sendFunc, &funcArgs); if(sendFunc != nullptr) { - // sendFunc() + result = sendFunc(spiCookie, sendData, sendLen, funcArgs); + } + } + return result; +} + +ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie *spiCookie, const uint8_t *sendData, size_t sendLen) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + int retval = 0; + /* Prepare transfer */ + int fileDescriptor = 0; + std::string device = spiCookie->getSpiDevice(); + UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage: "); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return OPENING_FILE_FAILED; + } + spi::SpiModes spiMode = spi::SpiModes::MODE_0; + uint32_t spiSpeed = 0; + spiCookie->getSpiParameters(spiMode, spiSpeed, nullptr); + setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); + spiCookie->assignWriteBuffer(sendData); + spiCookie->assignTransferSize(sendLen); + + bool fullDuplex = spiCookie->isFullDuplex(); + gpioId_t gpioId = spiCookie->getChipSelectPin(); + + /* Pull SPI CS low. For now, no support for active high given */ + if(gpioId != gpio::NO_GPIO) { + result = spiMutex->lockMutex(timeoutType, timeoutMs); + if (result != RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "SpiComIF::sendMessage: Failed to lock mutex" << std::endl; +#endif + return result; + } + gpioComIF->pullLow(gpioId); + } + + /* Execute transfer */ + if(fullDuplex) { + /* Initiate a full duplex SPI transfer. */ + retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle()); + if(retval < 0) { + utility::handleIoctlError("SpiComIF::sendMessage: ioctl error."); + result = FULL_DUPLEX_TRANSFER_FAILED; + } +#if FSFW_HAL_LINUX_SPI_WIRETAPPING == 1 + size_t dataLen = spiCookie->getTransferStructHandle()->len; + uint8_t* dataPtr = reinterpret_cast(spiCookie->getTransferStructHandle()->tx_buf); +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "Sent SPI data: " << std::endl; + arrayprinter::print(dataPtr, dataLen, OutputType::HEX, false); + sif::info << "Received SPI data: " << std::endl; +#else + sif::printInfo("Sent SPI data: \n"); + arrayprinter::print(dataPtr, dataLen, OutputType::HEX, false); + sif::printInfo("Received SPI data: \n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ + dataPtr = reinterpret_cast(spiCookie->getTransferStructHandle()->rx_buf); + arrayprinter::print(dataPtr, dataLen, OutputType::HEX, false); +#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */ + } + else { + /* We write with a blocking half-duplex transfer here */ + if (write(fileDescriptor, sendData, sendLen) != static_cast(sendLen)) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << + std::endl; +#else + sif::printWarning("SpiComIF::sendMessage: Half-Duplex write operation failed!\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + result = HALF_DUPLEX_TRANSFER_FAILED; } } + if(gpioId != gpio::NO_GPIO) { + gpioComIF->pullHigh(gpioId); + result = spiMutex->unlockMutex(); + if (result != RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "SpiComIF::sendMessage: Failed to unlock mutex" << std::endl; +#endif + return result; + } + } return result; } diff --git a/linux/spi/SpiComIF.h b/linux/spi/SpiComIF.h index ddb7761..5a99da4 100644 --- a/linux/spi/SpiComIF.h +++ b/linux/spi/SpiComIF.h @@ -64,6 +64,7 @@ private: SpiDeviceMap spiDeviceMap; + ReturnValue_t performRegularSendOperation(SpiCookie* spiCookie, const uint8_t *sendData, size_t sendLen); ReturnValue_t performHalfDuplexReception(SpiCookie* spiCookie); ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); diff --git a/linux/spi/SpiCookie.cpp b/linux/spi/SpiCookie.cpp index 07acf28..1fff44e 100644 --- a/linux/spi/SpiCookie.cpp +++ b/linux/spi/SpiCookie.cpp @@ -12,9 +12,9 @@ SpiCookie::SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxS SpiCookie(spiAddress, gpio::NO_GPIO, spiDev, maxSize, spiMode, spiSpeed) { } -SpiCookie::SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxSize, +SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, const size_t maxSize, spi::send_callback_function_t callback, void *args): - SpiCookie(spi::SpiComIfModes::CALLBACK, spiAddress, gpio::NO_GPIO, spiDev, maxSize, + SpiCookie(spi::SpiComIfModes::CALLBACK, spiAddress, chipSelect, spiDev, maxSize, spi::SpiModes::MODE_0, 0, callback, args) { } diff --git a/linux/spi/SpiCookie.h b/linux/spi/SpiCookie.h index a686249..604f6b2 100644 --- a/linux/spi/SpiCookie.h +++ b/linux/spi/SpiCookie.h @@ -31,7 +31,7 @@ public: * Use the callback mode of the SPI communication interface. The user can pass the callback * function here or by using the setter function #setCallbackMode */ - SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxSize, + SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, const size_t maxSize, spi::send_callback_function_t callback, void *args); void getCallback(spi::send_callback_function_t* callback, void** args); diff --git a/linux/spi/spiDefinitions.h b/linux/spi/spiDefinitions.h index c131038..ff6d66d 100644 --- a/linux/spi/spiDefinitions.h +++ b/linux/spi/spiDefinitions.h @@ -1,10 +1,15 @@ #ifndef LINUX_SPI_SPIDEFINITONS_H_ #define LINUX_SPI_SPIDEFINITONS_H_ +#include "../../common/gpio/gpioDefinitions.h" + #include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include #include +class SpiCookie; + namespace spi { enum SpiModes: uint8_t { @@ -20,7 +25,7 @@ enum SpiComIfModes { }; -using send_callback_function_t = ReturnValue_t (*) (uint8_t** replyData, void* args); +using send_callback_function_t = ReturnValue_t (*) (SpiCookie *cookie, const uint8_t *sendData, size_t sendLen, void* args); }