Spi COM IF update #7
@ -138,7 +138,6 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) {
|
|||||||
ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) {
|
ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) {
|
||||||
SpiCookie* spiCookie = dynamic_cast<SpiCookie*>(cookie);
|
SpiCookie* spiCookie = dynamic_cast<SpiCookie*>(cookie);
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
int retval = 0;
|
|
||||||
|
|
||||||
if(spiCookie == nullptr) {
|
if(spiCookie == nullptr) {
|
||||||
return NULLPOINTER;
|
return NULLPOINTER;
|
||||||
@ -159,95 +158,100 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(spiCookie->getComIfMode() == spi::SpiComIfModes::REGULAR) {
|
if(spiCookie->getComIfMode() == spi::SpiComIfModes::REGULAR) {
|
||||||
/* Prepare transfer */
|
result = performRegularSendOperation(spiCookie, sendData, sendLen);
|
||||||
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<uint8_t*>(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<uint8_t*>(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<ssize_t>(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(spiCookie->getComIfMode() == spi::SpiComIfModes::CALLBACK) {
|
else if(spiCookie->getComIfMode() == spi::SpiComIfModes::CALLBACK) {
|
||||||
spi::send_callback_function_t sendFunc = nullptr;
|
spi::send_callback_function_t sendFunc = nullptr;
|
||||||
void* funcArgs = nullptr;
|
void* funcArgs = nullptr;
|
||||||
spiCookie->getCallback(&sendFunc, &funcArgs);
|
spiCookie->getCallback(&sendFunc, &funcArgs);
|
||||||
if(sendFunc != nullptr) {
|
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<uint8_t*>(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<uint8_t*>(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<ssize_t>(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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ private:
|
|||||||
|
|
||||||
SpiDeviceMap spiDeviceMap;
|
SpiDeviceMap spiDeviceMap;
|
||||||
|
|
||||||
|
ReturnValue_t performRegularSendOperation(SpiCookie* spiCookie, const uint8_t *sendData, size_t sendLen);
|
||||||
ReturnValue_t performHalfDuplexReception(SpiCookie* spiCookie);
|
ReturnValue_t performHalfDuplexReception(SpiCookie* spiCookie);
|
||||||
|
|
||||||
ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer);
|
ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer);
|
||||||
|
@ -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(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):
|
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) {
|
spi::SpiModes::MODE_0, 0, callback, args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ public:
|
|||||||
* Use the callback mode of the SPI communication interface. The user can pass the callback
|
* Use the callback mode of the SPI communication interface. The user can pass the callback
|
||||||
* function here or by using the setter function #setCallbackMode
|
* 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);
|
spi::send_callback_function_t callback, void *args);
|
||||||
|
|
||||||
void getCallback(spi::send_callback_function_t* callback, void** args);
|
void getCallback(spi::send_callback_function_t* callback, void** args);
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
#ifndef LINUX_SPI_SPIDEFINITONS_H_
|
#ifndef LINUX_SPI_SPIDEFINITONS_H_
|
||||||
#define LINUX_SPI_SPIDEFINITONS_H_
|
#define LINUX_SPI_SPIDEFINITONS_H_
|
||||||
|
|
||||||
|
#include "../../common/gpio/gpioDefinitions.h"
|
||||||
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
#include <linux/spi/spidev.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
class SpiCookie;
|
||||||
|
|
||||||
namespace spi {
|
namespace spi {
|
||||||
|
|
||||||
enum SpiModes: uint8_t {
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user