eive-obsw/linux/spi/SpiCookie.h

120 lines
3.7 KiB
C++

#ifndef LINUX_SPI_SPICOOKIE_H_
#define LINUX_SPI_SPICOOKIE_H_
#include "spiDefinitions.h"
#include <fsfw/devicehandlers/CookieIF.h>
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
#include <linux/spi/spidev.h>
class SpiCookie: public CookieIF {
public:
/**
* Each SPI device will have a corresponding cookie. The cookie is used by the communication
* interface and contains device specific information like the largest expected size to be
* sent and received and the GPIO pin used to toggle the SPI slave select pin.
* @param spiAddress
* @param chipSelect Chip select. gpio::NO_GPIO can be used for hardware slave selects.
* @param spiDev
* @param maxSize
*/
SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev,
const size_t maxReplySize, spi::SpiModes spiMode, uint32_t spiSpeed);
/**
* Like constructor above, but without a dedicated GPIO CS. Can be used for hardware
* slave select or if CS logic is performed with decoders.
*/
SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxReplySize,
spi::SpiModes spiMode, uint32_t spiSpeed);
address_t getSpiAddress() const;
std::string getSpiDevice() const;
gpioId_t getChipSelectPin() const;
size_t getMaxBufferSize() const;
/** Enables changing SPI speed at run-time */
void setSpiSpeed(uint32_t newSpeed);
/** Enables changing the SPI mode at run-time */
void setSpiMode(spi::SpiModes newMode);
/**
* True if SPI transfers should be performed in full duplex mode
* @return
*/
bool isFullDuplex() const;
/**
* Set transfer type to full duplex or half duplex. Full duplex is the default setting,
* ressembling common SPI hardware implementation with shift registers, where read and writes
* happen simultaneosly.
* @param fullDuplex
*/
void setFullOrHalfDuplex(bool halfDuplex);
/**
* This needs to be called to specify where the SPI driver writes to or reads from.
* @param readLocation
* @param writeLocation
*/
void assignReadBuffer(uint8_t* rx);
void assignWriteBuffer(const uint8_t* tx);
/**
* Assign size for the next transfer.
* @param transferSize
*/
void assignTransferSize(size_t transferSize);
size_t getCurrentTransferSize() const;
struct UncommonParameters {
uint8_t bitsPerWord = 8;
bool noCs = false;
bool csHigh = false;
bool threeWireSpi = false;
/* MSB first is more common */
bool lsbFirst = false;
};
/**
* Can be used to explicitely disable hardware chip select.
* Some drivers like the Raspberry Pi Linux driver will not use hardware chip select by default
* (see https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md)
* @param enable
*/
void setNoCs(bool enable);
void setThreeWireSpi(bool enable);
void setLsbFirst(bool enable);
void setCsHigh(bool enable);
void setBitsPerWord(uint8_t bitsPerWord);
void getSpiParameters(spi::SpiModes& spiMode, uint32_t& spiSpeed,
UncommonParameters* parameters = nullptr) const;
/**
* See spidev.h cs_change and delay_usecs
* @param deselectCs
* @param delayUsecs
*/
void activateCsDeselect(bool deselectCs, uint16_t delayUsecs);
spi_ioc_transfer* getTransferStructHandle();
private:
size_t currentTransferSize = 0;
address_t spiAddress;
gpioId_t chipSelectPin;
std::string spiDevice;
const size_t maxSize;
spi::SpiModes spiMode;
uint32_t spiSpeed;
bool halfDuplex = false;
struct spi_ioc_transfer spiTransferStruct = {};
UncommonParameters uncommonParameters;
};
#endif /* LINUX_SPI_SPICOOKIE_H_ */