diff --git a/fsfw_hal b/fsfw_hal index 73a427d7..2893da04 160000 --- a/fsfw_hal +++ b/fsfw_hal @@ -1 +1 @@ -Subproject commit 73a427d7e0605519aecfa53fa289b94e0143394f +Subproject commit 2893da047bc695fcb02b0f9567cef0366a37793a diff --git a/linux/fsfwconfig/OBSWConfig.h b/linux/fsfwconfig/OBSWConfig.h index 3894aecb..5d11cb3b 100644 --- a/linux/fsfwconfig/OBSWConfig.h +++ b/linux/fsfwconfig/OBSWConfig.h @@ -21,6 +21,8 @@ debugging. */ #define OBSW_ADD_TEST_CODE 1 #define OBSW_ADD_TEST_PST 1 +#define FSFW_HAL_LINUX_SPI_WIRETAPPING 0 + #define TEST_LIBGPIOD 0 #define TEST_RADIATION_SENSOR_HANDLER 1 #define TEST_SUS_HANDLER 1 diff --git a/mission/devices/GyroADIS16507Handler.cpp b/mission/devices/GyroADIS16507Handler.cpp index 9bef3232..d8ce106b 100644 --- a/mission/devices/GyroADIS16507Handler.cpp +++ b/mission/devices/GyroADIS16507Handler.cpp @@ -1,17 +1,20 @@ #include +#include + #include "GyroADIS16507Handler.h" #if OBSW_ADIS16507_LINUX_COM_IF == 1 #include "fsfw_hal/linux/spi/SpiCookie.h" #include "fsfw_hal/linux/spi/SpiComIF.h" -#endif - +#include "fsfw_hal/linux/UnixFileGuard.h" +#include #include +#endif GyroADIS16507Handler::GyroADIS16507Handler(object_id_t objectId, object_id_t deviceCommunication, CookieIF * comCookie): - DeviceHandlerBase(objectId, deviceCommunication, comCookie), primaryDataset(this), - configDataset(this) { + DeviceHandlerBase(objectId, deviceCommunication, comCookie), primaryDataset(this), + configDataset(this) { #if OBSW_ADIS16507_LINUX_COM_IF == 1 SpiCookie* cookie = dynamic_cast(comCookie); if(cookie != nullptr) { @@ -260,8 +263,80 @@ ReturnValue_t GyroADIS16507Handler::spiSendCallback(SpiComIF *comIf, SpiCookie * case(ADIS16507::READ_SENSOR_DATA): { return comIf->performRegularSendOperation(cookie, sendData, sendLen); } - case(ADIS16507::READ_OUT_CONFIG): { - usleep(ADIS16507::STALL_TIME_MICROSECONDS); + case(ADIS16507::READ_OUT_CONFIG): + default: { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + int retval = 0; + // Prepare transfer + int fileDescriptor = 0; + std::string device = cookie->getSpiDevice(); + UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage: "); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return SpiComIF::OPENING_FILE_FAILED; + } + spi::SpiModes spiMode = spi::SpiModes::MODE_0; + uint32_t spiSpeed = 0; + cookie->getSpiParameters(spiMode, spiSpeed, nullptr); + comIf->setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); + cookie->assignWriteBuffer(sendData); + cookie->assignTransferSize(2); + + gpioId_t gpioId = cookie->getChipSelectPin(); + GpioIF* gpioIF = comIf->getGpioInterface(); + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + uint32_t timeoutMs = 0; + MutexIF* mutex = comIf->getMutex(&timeoutType, &timeoutMs); + if(mutex == nullptr or gpioIF == nullptr) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::warning << "GyroADIS16507Handler::spiSendCallback: " + "Mutex or GPIO interface invalid" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; +#endif + } + + size_t idx = 0; + while(idx < sendLen) { + // Pull SPI CS low. For now, no support for active high given + if(gpioId != gpio::NO_GPIO) { + result = mutex->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; + } + gpioIF->pullLow(gpioId); + } + + // Execute transfer + // Initiate a full duplex SPI transfer. + retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie->getTransferStructHandle()); + if(retval < 0) { + utility::handleIoctlError("SpiComIF::sendMessage: ioctl error."); + result = SpiComIF::FULL_DUPLEX_TRANSFER_FAILED; + } +#if FSFW_HAL_LINUX_SPI_WIRETAPPING == 1 + comIf->performSpiWiretapping(cookie); +#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */ + + if(gpioId != gpio::NO_GPIO) { + gpioIF->pullHigh(gpioId); + result = mutex->unlockMutex(); + if (result != RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "SpiComIF::getSendSuccess: Failed to unlock mutex" << std::endl; +#endif + return result; + } + } + + idx += 2; + if(idx < sendLen) { + usleep(ADIS16507::STALL_TIME_MICROSECONDS); + } + sendData += 2; + cookie->getTransferStructHandle()->rx_buf += 2; + } } } return HasReturnvaluesIF::RETURN_OK;