diff options
Diffstat (limited to '.pio/libdeps/esp32-s3-n16r8/Adafruit BusIO/Adafruit_SPIDevice.cpp')
| -rw-r--r-- | .pio/libdeps/esp32-s3-n16r8/Adafruit BusIO/Adafruit_SPIDevice.cpp | 512 |
1 files changed, 512 insertions, 0 deletions
diff --git a/.pio/libdeps/esp32-s3-n16r8/Adafruit BusIO/Adafruit_SPIDevice.cpp b/.pio/libdeps/esp32-s3-n16r8/Adafruit BusIO/Adafruit_SPIDevice.cpp new file mode 100644 index 0000000..3283de6 --- /dev/null +++ b/.pio/libdeps/esp32-s3-n16r8/Adafruit BusIO/Adafruit_SPIDevice.cpp @@ -0,0 +1,512 @@ +#include "Adafruit_SPIDevice.h" + +// #define DEBUG_SERIAL Serial + +#ifdef BUSIO_USE_FAST_PINIO +#define BUSIO_SET_CLOCK_LOW() (*clkPort = *clkPort & ~clkPinMask) +#define BUSIO_SET_CLOCK_HIGH() (*clkPort = *clkPort | clkPinMask) +#define BUSIO_READ_MISO() (*misoPort & misoPinMask) +#define BUSIO_WRITE_MOSI(value) \ + do { \ + if (value) \ + *mosiPort = *mosiPort | mosiPinMask; \ + else \ + *mosiPort = *mosiPort & ~mosiPinMask; \ + } while (0) +#else +#define BUSIO_SET_CLOCK_LOW() digitalWrite(_sck, LOW) +#define BUSIO_SET_CLOCK_HIGH() digitalWrite(_sck, HIGH) +#define BUSIO_READ_MISO() digitalRead(_miso) +#define BUSIO_WRITE_MOSI(value) digitalWrite(_mosi, value) +#endif + +/*! + * @brief Create an SPI device with the given CS pin and settings + * @param cspin The arduino pin number to use for chip select + * @param freq The SPI clock frequency to use, defaults to 1MHz + * @param dataOrder The SPI data order to use for bits within each byte, + * defaults to SPI_BITORDER_MSBFIRST + * @param dataMode The SPI mode to use, defaults to SPI_MODE0 + * @param theSPI The SPI bus to use, defaults to &theSPI + */ +Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq, + BusIOBitOrder dataOrder, + uint8_t dataMode, SPIClass *theSPI) { +#ifdef BUSIO_HAS_HW_SPI + _cs = cspin; + _sck = _mosi = _miso = -1; + _spi = theSPI; + _begun = false; + _spiSetting = new SPISettings(freq, dataOrder, dataMode); + _freq = freq; + _dataOrder = dataOrder; + _dataMode = dataMode; +#else + // unused, but needed to suppress compiler warns + (void)cspin; + (void)freq; + (void)dataOrder; + (void)dataMode; + (void)theSPI; +#endif +} + +/*! + * @brief Create an SPI device with the given CS pin and settings + * @param cspin The arduino pin number to use for chip select + * @param sckpin The arduino pin number to use for SCK + * @param misopin The arduino pin number to use for MISO, set to -1 if not + * used + * @param mosipin The arduino pin number to use for MOSI, set to -1 if not + * used + * @param freq The SPI clock frequency to use, defaults to 1MHz + * @param dataOrder The SPI data order to use for bits within each byte, + * defaults to SPI_BITORDER_MSBFIRST + * @param dataMode The SPI mode to use, defaults to SPI_MODE0 + */ +Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, int8_t sckpin, + int8_t misopin, int8_t mosipin, + uint32_t freq, BusIOBitOrder dataOrder, + uint8_t dataMode) { + _cs = cspin; + _sck = sckpin; + _miso = misopin; + _mosi = mosipin; + +#ifdef BUSIO_USE_FAST_PINIO + csPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(cspin)); + csPinMask = digitalPinToBitMask(cspin); + if (mosipin != -1) { + mosiPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(mosipin)); + mosiPinMask = digitalPinToBitMask(mosipin); + } + if (misopin != -1) { + misoPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(misopin)); + misoPinMask = digitalPinToBitMask(misopin); + } + clkPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(sckpin)); + clkPinMask = digitalPinToBitMask(sckpin); +#endif + + _freq = freq; + _dataOrder = dataOrder; + _dataMode = dataMode; + _begun = false; +} + +/*! + * @brief Release memory allocated in constructors + */ +Adafruit_SPIDevice::~Adafruit_SPIDevice() { + if (_spiSetting) + delete _spiSetting; +} + +/*! + * @brief Initializes SPI bus and sets CS pin high + * @return Always returns true because there's no way to test success of SPI + * init + */ +bool Adafruit_SPIDevice::begin(void) { + if (_cs != -1) { + pinMode(_cs, OUTPUT); + digitalWrite(_cs, HIGH); + } + + if (_spi) { // hardware SPI +#ifdef BUSIO_HAS_HW_SPI + _spi->begin(); +#endif + } else { + pinMode(_sck, OUTPUT); + + if ((_dataMode == SPI_MODE0) || (_dataMode == SPI_MODE1)) { + // idle low on mode 0 and 1 + digitalWrite(_sck, LOW); + } else { + // idle high on mode 2 or 3 + digitalWrite(_sck, HIGH); + } + if (_mosi != -1) { + pinMode(_mosi, OUTPUT); + digitalWrite(_mosi, HIGH); + } + if (_miso != -1) { + pinMode(_miso, INPUT); + } + } + + _begun = true; + return true; +} + +/*! + * @brief Transfer (send/receive) a buffer over hard/soft SPI, without + * transaction management + * @param buffer The buffer to send and receive at the same time + * @param len The number of bytes to transfer + */ +void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) { + // + // HARDWARE SPI + // + if (_spi) { +#ifdef BUSIO_HAS_HW_SPI +#if defined(SPARK) + _spi->transfer(buffer, buffer, len, nullptr); +#elif defined(STM32) + for (size_t i = 0; i < len; i++) { + _spi->transfer(buffer[i]); + } +#else + _spi->transfer(buffer, len); +#endif + return; +#endif + } + + // + // SOFTWARE SPI + // + uint8_t startbit; + if (_dataOrder == SPI_BITORDER_LSBFIRST) { + startbit = 0x1; + } else { + startbit = 0x80; + } + + bool towrite, lastmosi = !(buffer[0] & startbit); + uint8_t bitdelay_us = (1000000 / _freq) / 2; + + for (size_t i = 0; i < len; i++) { + uint8_t reply = 0; + uint8_t send = buffer[i]; + + /* + Serial.print("\tSending software SPI byte 0x"); + Serial.print(send, HEX); + Serial.print(" -> 0x"); + */ + + // Serial.print(send, HEX); + for (uint8_t b = startbit; b != 0; + b = (_dataOrder == SPI_BITORDER_LSBFIRST) ? b << 1 : b >> 1) { + + if (bitdelay_us) { + delayMicroseconds(bitdelay_us); + } + + if (_dataMode == SPI_MODE0 || _dataMode == SPI_MODE2) { + towrite = send & b; + if ((_mosi != -1) && (lastmosi != towrite)) { + BUSIO_WRITE_MOSI(towrite); + lastmosi = towrite; + } + + BUSIO_SET_CLOCK_HIGH(); + + if (bitdelay_us) { + delayMicroseconds(bitdelay_us); + } + + if (_miso != -1) { + if (BUSIO_READ_MISO()) + reply |= b; + } + + BUSIO_SET_CLOCK_LOW(); + + } else if (_dataMode == SPI_MODE3) { + + if (_mosi != -1) { // transmit on falling edge + BUSIO_WRITE_MOSI(send & b); + } + + BUSIO_SET_CLOCK_LOW(); + + if (bitdelay_us) { + delayMicroseconds(bitdelay_us); + } + + BUSIO_SET_CLOCK_HIGH(); + + if (bitdelay_us) { + delayMicroseconds(bitdelay_us); + } + + if (_miso != -1) { // read on rising edge + if (BUSIO_READ_MISO()) { + reply |= b; + } + } + + } else { // || _dataMode == SPI_MODE1) + + BUSIO_SET_CLOCK_HIGH(); + + if (bitdelay_us) { + delayMicroseconds(bitdelay_us); + } + + if (_mosi != -1) { + BUSIO_WRITE_MOSI(send & b); + } + + BUSIO_SET_CLOCK_LOW(); + + if (_miso != -1) { + if (BUSIO_READ_MISO()) { + reply |= b; + } + } + } + } + if (_miso != -1) { + buffer[i] = reply; + } + } + return; +} + +/*! + * @brief Transfer (send/receive) one byte over hard/soft SPI, without + * transaction management + * @param send The byte to send + * @return The byte received while transmitting + */ +uint8_t Adafruit_SPIDevice::transfer(uint8_t send) { + uint8_t data = send; + transfer(&data, 1); + return data; +} + +/*! + * @brief Manually begin a transaction (calls beginTransaction if hardware + * SPI) + */ +void Adafruit_SPIDevice::beginTransaction(void) { + if (_spi) { +#ifdef BUSIO_HAS_HW_SPI + _spi->beginTransaction(*_spiSetting); +#endif + } +} + +/*! + * @brief Manually end a transaction (calls endTransaction if hardware SPI) + */ +void Adafruit_SPIDevice::endTransaction(void) { + if (_spi) { +#ifdef BUSIO_HAS_HW_SPI + _spi->endTransaction(); +#endif + } +} + +/*! + * @brief Assert/Deassert the CS pin if it is defined + * @param value The state the CS is set to + */ +void Adafruit_SPIDevice::setChipSelect(int value) { + if (_cs != -1) { + digitalWrite(_cs, value); + } +} + +/*! + * @brief Write a buffer or two to the SPI device, with transaction + * management. + * @brief Manually begin a transaction (calls beginTransaction if hardware + * SPI) with asserting the CS pin + */ +void Adafruit_SPIDevice::beginTransactionWithAssertingCS() { + beginTransaction(); + setChipSelect(LOW); +} + +/*! + * @brief Manually end a transaction (calls endTransaction if hardware SPI) + * with deasserting the CS pin + */ +void Adafruit_SPIDevice::endTransactionWithDeassertingCS() { + setChipSelect(HIGH); + endTransaction(); +} + +/*! + * @brief Write a buffer or two to the SPI device, with transaction + * management. + * @param buffer Pointer to buffer of data to write + * @param len Number of bytes from buffer to write + * @param prefix_buffer Pointer to optional array of data to write before + * buffer. + * @param prefix_len Number of bytes from prefix buffer to write + * @return Always returns true because there's no way to test success of SPI + * writes + */ +bool Adafruit_SPIDevice::write(const uint8_t *buffer, size_t len, + const uint8_t *prefix_buffer, + size_t prefix_len) { + beginTransactionWithAssertingCS(); + + // do the writing +#if defined(ARDUINO_ARCH_ESP32) + if (_spi) { + if (prefix_len > 0) { + _spi->transferBytes((uint8_t *)prefix_buffer, nullptr, prefix_len); + } + if (len > 0) { + _spi->transferBytes((uint8_t *)buffer, nullptr, len); + } + } else +#endif + { + for (size_t i = 0; i < prefix_len; i++) { + transfer(prefix_buffer[i]); + } + for (size_t i = 0; i < len; i++) { + transfer(buffer[i]); + } + } + endTransactionWithDeassertingCS(); + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tSPIDevice Wrote: ")); + if ((prefix_len != 0) && (prefix_buffer != nullptr)) { + for (uint16_t i = 0; i < prefix_len; i++) { + DEBUG_SERIAL.print(F("0x")); + DEBUG_SERIAL.print(prefix_buffer[i], HEX); + DEBUG_SERIAL.print(F(", ")); + } + } + for (uint16_t i = 0; i < len; i++) { + DEBUG_SERIAL.print(F("0x")); + DEBUG_SERIAL.print(buffer[i], HEX); + DEBUG_SERIAL.print(F(", ")); + if (i % 32 == 31) { + DEBUG_SERIAL.println(); + } + } + DEBUG_SERIAL.println(); +#endif + + return true; +} + +/*! + * @brief Read from SPI into a buffer from the SPI device, with transaction + * management. + * @param buffer Pointer to buffer of data to read into + * @param len Number of bytes from buffer to read. + * @param sendvalue The 8-bits of data to write when doing the data read, + * defaults to 0xFF + * @return Always returns true because there's no way to test success of SPI + * writes + */ +bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) { + memset(buffer, sendvalue, len); // clear out existing buffer + + beginTransactionWithAssertingCS(); + transfer(buffer, len); + endTransactionWithDeassertingCS(); + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tSPIDevice Read: ")); + for (uint16_t i = 0; i < len; i++) { + DEBUG_SERIAL.print(F("0x")); + DEBUG_SERIAL.print(buffer[i], HEX); + DEBUG_SERIAL.print(F(", ")); + if (len % 32 == 31) { + DEBUG_SERIAL.println(); + } + } + DEBUG_SERIAL.println(); +#endif + + return true; +} + +/*! + * @brief Write some data, then read some data from SPI into another buffer, + * with transaction management. The buffers can point to same/overlapping + * locations. This does not transmit-receive at the same time! + * @param write_buffer Pointer to buffer of data to write from + * @param write_len Number of bytes from buffer to write. + * @param read_buffer Pointer to buffer of data to read into. + * @param read_len Number of bytes from buffer to read. + * @param sendvalue The 8-bits of data to write when doing the data read, + * defaults to 0xFF + * @return Always returns true because there's no way to test success of SPI + * writes + */ +bool Adafruit_SPIDevice::write_then_read(const uint8_t *write_buffer, + size_t write_len, uint8_t *read_buffer, + size_t read_len, uint8_t sendvalue) { + beginTransactionWithAssertingCS(); + // do the writing +#if defined(ARDUINO_ARCH_ESP32) + if (_spi) { + if (write_len > 0) { + _spi->transferBytes((uint8_t *)write_buffer, nullptr, write_len); + } + } else +#endif + { + for (size_t i = 0; i < write_len; i++) { + transfer(write_buffer[i]); + } + } + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tSPIDevice Wrote: ")); + for (uint16_t i = 0; i < write_len; i++) { + DEBUG_SERIAL.print(F("0x")); + DEBUG_SERIAL.print(write_buffer[i], HEX); + DEBUG_SERIAL.print(F(", ")); + if (write_len % 32 == 31) { + DEBUG_SERIAL.println(); + } + } + DEBUG_SERIAL.println(); +#endif + + // do the reading + for (size_t i = 0; i < read_len; i++) { + read_buffer[i] = transfer(sendvalue); + } + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tSPIDevice Read: ")); + for (uint16_t i = 0; i < read_len; i++) { + DEBUG_SERIAL.print(F("0x")); + DEBUG_SERIAL.print(read_buffer[i], HEX); + DEBUG_SERIAL.print(F(", ")); + if (read_len % 32 == 31) { + DEBUG_SERIAL.println(); + } + } + DEBUG_SERIAL.println(); +#endif + + endTransactionWithDeassertingCS(); + + return true; +} + +/*! + * @brief Write some data and read some data at the same time from SPI + * into the same buffer, with transaction management. This is basicaly a wrapper + * for transfer() with CS-pin and transaction management. This /does/ + * transmit-receive at the same time! + * @param buffer Pointer to buffer of data to write/read to/from + * @param len Number of bytes from buffer to write/read. + * @return Always returns true because there's no way to test success of SPI + * writes + */ +bool Adafruit_SPIDevice::write_and_read(uint8_t *buffer, size_t len) { + beginTransactionWithAssertingCS(); + transfer(buffer, len); + endTransactionWithDeassertingCS(); + + return true; +} |
