You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
5.2 KiB
144 lines
5.2 KiB
#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_MODE4 }; |
|
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) || defined(ARDUINO_SILABS) |
|
|
|
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(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_MBED) && !defined(ARDUINO_ARCH_RP2040) && \ |
|
!defined(ARDUINO_SILABS) && !defined(ARDUINO_UNOR4_MINIMA) && \ |
|
!defined(ARDUINO_UNOR4_WIFI) |
|
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
|
|
|