fsfw-hal/linux/spi/SpiComIF.h

91 lines
3.1 KiB
C
Raw Permalink Normal View History

2021-04-01 10:59:23 +02:00
#ifndef LINUX_SPI_SPICOMIF_H_
#define LINUX_SPI_SPICOMIF_H_
#include "spiDefinitions.h"
2021-05-25 15:35:53 +02:00
#include "returnvalues/classIds.h"
#include "../../common/gpio/GpioIF.h"
2021-04-01 10:59:23 +02:00
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <vector>
#include <unordered_map>
2021-05-23 21:34:59 +02:00
class SpiCookie;
2021-04-01 10:59:23 +02:00
/**
* @brief Encapsulates access to linux SPI driver for FSFW objects
* @details
2021-05-25 15:34:44 +02:00
* Right now, only full-duplex SPI is supported. Most device specific transfer properties
* are contained in the SPI cookie.
2021-04-01 10:59:23 +02:00
* @author R. Mueller
*/
class SpiComIF: public DeviceCommunicationIF, public SystemObject {
public:
2021-06-15 16:04:35 +02:00
static constexpr uint8_t spiRetvalId = CLASS_ID::HAL_SPI;
2021-04-01 10:59:23 +02:00
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;
ReturnValue_t sendMessage(CookieIF *cookie,const uint8_t *sendData,
size_t sendLen) override;
ReturnValue_t getSendSuccess(CookieIF *cookie) override;
ReturnValue_t requestReceiveMessage(CookieIF *cookie,
size_t requestLen) override;
ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
size_t *size) override;
2021-05-23 21:34:59 +02:00
/**
* @brief This function returns the mutex which can be used to protect the spi bus when
* the chip select must be driven from outside of the com if.
*/
MutexIF* getMutex(MutexIF::TimeoutType* timeoutType = nullptr, uint32_t* timeoutMs = nullptr);
2021-05-24 20:33:43 +02:00
/**
* Perform a regular send operation using Linux iotcl. This is public so it can be used
2021-05-25 15:33:50 +02:00
* in functions like a user callback if special handling is only necessary for certain commands.
2021-05-24 20:33:43 +02:00
* @param spiCookie
* @param sendData
* @param sendLen
* @return
*/
ReturnValue_t performRegularSendOperation(SpiCookie* spiCookie, const uint8_t *sendData,
size_t sendLen);
GpioIF* getGpioInterface();
void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed);
2021-05-25 12:45:11 +02:00
void performSpiWiretapping(SpiCookie* spiCookie);
2021-06-21 14:49:20 +02:00
ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer);
2021-04-01 10:59:23 +02:00
private:
struct SpiInstance {
2021-06-05 14:31:49 +02:00
SpiInstance(size_t maxRecvSize): replyBuffer(std::vector<uint8_t>(maxRecvSize)) {}
2021-04-01 10:59:23 +02:00
std::vector<uint8_t> replyBuffer;
};
GpioIF* gpioComIF = nullptr;
MutexIF* spiMutex = nullptr;
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
uint32_t timeoutMs = 20;
using SpiDeviceMap = std::unordered_map<address_t, SpiInstance>;
using SpiDeviceMapIter = SpiDeviceMap::iterator;
SpiDeviceMap spiDeviceMap;
2021-05-23 21:34:59 +02:00
ReturnValue_t performHalfDuplexReception(SpiCookie* spiCookie);
2021-04-01 10:59:23 +02:00
};
#endif /* LINUX_SPI_SPICOMIF_H_ */