| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #ifndef Adafruit_SPIDevice_h
- #define Adafruit_SPIDevice_h
- #include <Arduino.h>
- #if !defined(SPI_INTERFACES_COUNT) || \
- (defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
- // HW SPI available
- #include <SPI.h>
- #define BUSIO_HAS_HW_SPI
- #else
- // SW SPI ONLY
- enum { SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3 };
- typedef uint8_t SPIClass;
- #endif
- // some modern SPI definitions don't have BitOrder enum
- #if (defined(__AVR__) && !defined(ARDUINO_ARCH_MEGAAVR)) || \
- defined(ESP8266) || defined(TEENSYDUINO) || defined(SPARK) || \
- defined(ARDUINO_ARCH_SPRESENSE) || defined(MEGATINYCORE) || \
- defined(DXCORE) || defined(ARDUINO_AVR_ATmega4809) || \
- defined(ARDUINO_AVR_ATmega4808) || defined(ARDUINO_AVR_ATmega3209) || \
- defined(ARDUINO_AVR_ATmega3208) || defined(ARDUINO_AVR_ATmega1609) || \
- defined(ARDUINO_AVR_ATmega1608) || defined(ARDUINO_AVR_ATmega809) || \
- defined(ARDUINO_AVR_ATmega808) || defined(ARDUINO_ARCH_ARC32) || \
- defined(ARDUINO_ARCH_XMC)
- typedef enum _BitOrder {
- SPI_BITORDER_MSBFIRST = MSBFIRST,
- SPI_BITORDER_LSBFIRST = LSBFIRST,
- } BusIOBitOrder;
- #elif defined(ESP32) || defined(__ASR6501__) || defined(__ASR6502__)
- // some modern SPI definitions don't have BitOrder enum and have different SPI
- // mode defines
- typedef enum _BitOrder {
- SPI_BITORDER_MSBFIRST = SPI_MSBFIRST,
- SPI_BITORDER_LSBFIRST = SPI_LSBFIRST,
- } BusIOBitOrder;
- #else
- // Some platforms have a BitOrder enum but its named MSBFIRST/LSBFIRST
- #define SPI_BITORDER_MSBFIRST MSBFIRST
- #define SPI_BITORDER_LSBFIRST LSBFIRST
- typedef BitOrder BusIOBitOrder;
- #endif
- #if defined(__IMXRT1062__) // Teensy 4.x
- // *Warning* I disabled the usage of FAST_PINIO as the set/clear operations
- // used in the cpp file are not atomic and can effect multiple IO pins
- // and if an interrupt happens in between the time the code reads the register
- // and writes out the updated value, that changes one or more other IO pins
- // on that same IO port, those change will be clobbered when the updated
- // values are written back. A fast version can be implemented that uses the
- // ports set and clear registers which are atomic.
- // typedef volatile uint32_t BusIO_PortReg;
- // typedef uint32_t BusIO_PortMask;
- // #define BUSIO_USE_FAST_PINIO
- #elif defined(__MBED__) || defined(__ZEPHYR__)
- // Boards based on RTOS cores like mbed or Zephyr are not going to expose the
- // low level registers needed for fast pin manipulation
- #undef BUSIO_USE_FAST_PINIO
- #elif defined(ARDUINO_ARCH_XMC)
- #undef BUSIO_USE_FAST_PINIO
- #elif defined(__AVR__) || defined(TEENSYDUINO)
- typedef volatile uint8_t BusIO_PortReg;
- typedef uint8_t BusIO_PortMask;
- #define BUSIO_USE_FAST_PINIO
- #elif defined(ESP8266) || defined(ESP32) || defined(__SAM3X8E__) || \
- defined(ARDUINO_ARCH_SAMD)
- typedef volatile uint32_t BusIO_PortReg;
- typedef uint32_t BusIO_PortMask;
- #define BUSIO_USE_FAST_PINIO
- #elif (defined(__arm__) || defined(ARDUINO_FEATHER52)) && \
- !defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_SILABS) && \
- !defined(ARDUINO_UNOR4_MINIMA) && !defined(ARDUINO_UNOR4_WIFI) && \
- !defined(PORTDUINO)
- typedef volatile uint32_t BusIO_PortReg;
- typedef uint32_t BusIO_PortMask;
- #if !defined(__ASR6501__) && !defined(__ASR6502__)
- #define BUSIO_USE_FAST_PINIO
- #endif
- #else
- #undef BUSIO_USE_FAST_PINIO
- #endif
- /**! The class which defines how we will talk to this device over SPI **/
- class Adafruit_SPIDevice {
- public:
- #ifdef BUSIO_HAS_HW_SPI
- Adafruit_SPIDevice(int8_t cspin, uint32_t freq = 1000000,
- BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
- uint8_t dataMode = SPI_MODE0, SPIClass *theSPI = &SPI);
- #else
- Adafruit_SPIDevice(int8_t cspin, uint32_t freq = 1000000,
- BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
- uint8_t dataMode = SPI_MODE0, SPIClass *theSPI = nullptr);
- #endif
- Adafruit_SPIDevice(int8_t cspin, int8_t sck, int8_t miso, int8_t mosi,
- uint32_t freq = 1000000,
- BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
- uint8_t dataMode = SPI_MODE0);
- ~Adafruit_SPIDevice();
- bool begin(void);
- bool read(uint8_t *buffer, size_t len, uint8_t sendvalue = 0xFF);
- bool write(const uint8_t *buffer, size_t len,
- const uint8_t *prefix_buffer = nullptr, size_t prefix_len = 0);
- bool write_then_read(const uint8_t *write_buffer, size_t write_len,
- uint8_t *read_buffer, size_t read_len,
- uint8_t sendvalue = 0xFF);
- bool write_and_read(uint8_t *buffer, size_t len);
- uint8_t transfer(uint8_t send);
- void transfer(uint8_t *buffer, size_t len);
- void beginTransaction(void);
- void endTransaction(void);
- void beginTransactionWithAssertingCS();
- void endTransactionWithDeassertingCS();
- private:
- #ifdef BUSIO_HAS_HW_SPI
- SPIClass *_spi = nullptr;
- SPISettings *_spiSetting = nullptr;
- #else
- uint8_t *_spi = nullptr;
- uint8_t *_spiSetting = nullptr;
- #endif
- uint32_t _freq;
- BusIOBitOrder _dataOrder;
- uint8_t _dataMode;
- void setChipSelect(int value);
- int8_t _cs, _sck, _mosi, _miso;
- #ifdef BUSIO_USE_FAST_PINIO
- BusIO_PortReg *mosiPort, *clkPort, *misoPort, *csPort;
- BusIO_PortMask mosiPinMask, misoPinMask, clkPinMask, csPinMask;
- #endif
- bool _begun;
- };
- #endif // Adafruit_SPIDevice_h
|