2021-02-23 11:31:50 +01:00
|
|
|
#ifndef LINUX_SPI_SPICOOKIE_H_
|
|
|
|
#define LINUX_SPI_SPICOOKIE_H_
|
|
|
|
|
|
|
|
#include "spiDefinitions.h"
|
|
|
|
#include <fsfw/devicehandlers/CookieIF.h>
|
2021-03-23 16:45:07 +01:00
|
|
|
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
2021-02-23 11:31:50 +01:00
|
|
|
#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,
|
2021-03-07 14:06:29 +01:00
|
|
|
const size_t maxReplySize, spi::SpiModes spiMode, uint32_t spiSpeed);
|
2021-02-23 11:31:50 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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,
|
2021-03-07 14:06:29 +01:00
|
|
|
spi::SpiModes spiMode, uint32_t spiSpeed);
|
2021-02-23 11:31:50 +01:00
|
|
|
|
|
|
|
address_t getSpiAddress() const;
|
|
|
|
std::string getSpiDevice() const;
|
|
|
|
gpioId_t getChipSelectPin() const;
|
|
|
|
size_t getMaxBufferSize() const;
|
2021-03-07 14:06:29 +01:00
|
|
|
|
|
|
|
/** 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);
|
|
|
|
|
2021-02-23 11:31:50 +01:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
|
2021-03-07 14:06:29 +01:00
|
|
|
void getSpiParameters(spi::SpiModes& spiMode, uint32_t& spiSpeed,
|
2021-02-23 11:31:50 +01:00
|
|
|
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;
|
2021-03-07 14:06:29 +01:00
|
|
|
spi::SpiModes spiMode;
|
2021-02-23 11:31:50 +01:00
|
|
|
uint32_t spiSpeed;
|
|
|
|
bool halfDuplex = false;
|
|
|
|
|
2021-02-24 10:36:23 +01:00
|
|
|
struct spi_ioc_transfer spiTransferStruct = {};
|
2021-02-23 11:31:50 +01:00
|
|
|
UncommonParameters uncommonParameters;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* LINUX_SPI_SPICOOKIE_H_ */
|