summaryrefslogtreecommitdiff
path: root/.pio/libdeps/esp32-s3-n16r8/Adafruit BusIO/Adafruit_SPIDevice.cpp
diff options
context:
space:
mode:
authorkrolyxon <me@krolyxon.com>2026-06-08 23:10:46 +0530
committerkrolyxon <me@krolyxon.com>2026-06-08 23:10:46 +0530
commit3120783000d0025b183b0397acaa8b769499eb38 (patch)
tree1c4f93be213f1b1d48f59e554562d847b4e7c25e /.pio/libdeps/esp32-s3-n16r8/Adafruit BusIO/Adafruit_SPIDevice.cpp
Initial gh-pages firmware hosting
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.cpp512
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;
+}