#ifndef LINUX_SPI_SPICOOKIE_H_ #define LINUX_SPI_SPICOOKIE_H_ #include "spiDefinitions.h" #include #include #include 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_ */