fsfw/hal/src/fsfw_hal/linux/spi/SpiComIF.h

106 lines
3.9 KiB
C
Raw Normal View History

2021-07-13 19:19:25 +02:00
#ifndef LINUX_SPI_SPICOMIF_H_
#define LINUX_SPI_SPICOMIF_H_
2022-02-02 10:29:30 +01:00
#include <unordered_map>
#include <vector>
2021-07-13 19:19:25 +02:00
2022-02-02 10:29:30 +01:00
#include "fsfw/FSFW.h"
#include "fsfw/devicehandlers/DeviceCommunicationIF.h"
#include "fsfw/objectmanager/SystemObject.h"
2022-02-02 10:29:30 +01:00
#include "fsfw_hal/common/gpio/GpioIF.h"
#include "returnvalues/classIds.h"
#include "spiDefinitions.h"
2021-07-13 19:19:25 +02:00
class SpiCookie;
/**
* @brief Encapsulates access to linux SPI driver for FSFW objects
* @details
* Right now, only full-duplex SPI is supported. Most device specific transfer properties
* are contained in the SPI cookie.
* @author R. Mueller
*/
2022-02-02 10:29:30 +01:00
class SpiComIF : public DeviceCommunicationIF, public SystemObject {
public:
static constexpr uint8_t spiRetvalId = CLASS_ID::HAL_SPI;
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, std::string devname, GpioIF* gpioComIF);
2022-02-02 10:29:30 +01:00
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;
/**
* @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);
/**
* Perform a regular send operation using Linux iotcl. This is public so it can be used
* in functions like a user callback if special handling is only necessary for certain commands.
* @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);
/**
* This updates the SPI clock default polarity. Only setting the mode does not update
* the line state, which can be an issue on mode switches because the clock line will
* switch the state after the chip select is pulled low.
*
* It is recommended to call this function after #setSpiSpeedAndMode if the SPI bus
* has multiple SPI devices with different speed and SPI modes attached.
* @param spiFd
*/
void updateLinePolarity(int spiFd);
2022-05-11 10:54:13 +02:00
void getSpiSpeedAndMode(int spiFd, spi::SpiModes& mode, uint32_t& speed) const;
const std::string& getSpiDev() const;
2022-02-02 10:29:30 +01:00
void performSpiWiretapping(SpiCookie* spiCookie);
ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer);
private:
struct SpiInstance {
SpiInstance(size_t maxRecvSize) : replyBuffer(std::vector<uint8_t>(maxRecvSize)) {}
std::vector<uint8_t> replyBuffer;
};
GpioIF* gpioComIF = nullptr;
std::string dev = "";
/**
* Protects the chip select operations. Lock when GPIO is pulled low, unlock after it was
* pulled high
*/
MutexIF* csMutex = nullptr;
2022-02-02 10:29:30 +01:00
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
uint32_t timeoutMs = 20;
spi_ioc_transfer clockUpdateTransfer = {};
2022-02-02 10:29:30 +01:00
using SpiDeviceMap = std::unordered_map<address_t, SpiInstance>;
using SpiDeviceMapIter = SpiDeviceMap::iterator;
SpiDeviceMap spiDeviceMap;
ReturnValue_t performHalfDuplexReception(SpiCookie* spiCookie);
2021-07-13 19:19:25 +02:00
};
#endif /* LINUX_SPI_SPICOMIF_H_ */