|
|
|
@ -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<SpiCookie*>(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<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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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<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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|