From 7f66a34b9cfeba0b819e5b60b44768a0b4aa123f Mon Sep 17 00:00:00 2001 From: Monroe Williams Date: Thu, 13 Jan 2022 19:18:00 -0800 Subject: [PATCH 1/3] In the Adafruit_SPIDevice class, when running on the SAMD architecture in the hardware SPI case, use the SPIClass::transfer(txbuf, rxbuf, count, block) method when writing instead of looping over individual bytes. This makes use of DMA and is noticeably faster. --- Adafruit_SPIDevice.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Adafruit_SPIDevice.cpp b/Adafruit_SPIDevice.cpp index a17111b..b43e280 100644 --- a/Adafruit_SPIDevice.cpp +++ b/Adafruit_SPIDevice.cpp @@ -310,6 +310,15 @@ bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len, _spi->transferBytes(buffer, nullptr, len); } } else +#elif defined(ARDUINO_ARCH_SAMD) + if (_spi) { + if (prefix_len > 0) { + _spi->transfer(prefix_buffer, nullptr, prefix_len); + } + if (len > 0) { + _spi->transfer(buffer, nullptr, len); + } + } else #endif { for (size_t i = 0; i < prefix_len; i++) { @@ -414,6 +423,12 @@ bool Adafruit_SPIDevice::write_then_read(uint8_t *write_buffer, _spi->transferBytes(write_buffer, nullptr, write_len); } } else +#elif defined(ARDUINO_ARCH_SAMD) + if (_spi) { + if (write_len > 0) { + _spi->transfer(write_buffer, nullptr, write_len); + } + } else #endif { for (size_t i = 0; i < write_len; i++) { From 67bd6e7db5e627ff6da61e34b4ee953cfdc879de Mon Sep 17 00:00:00 2001 From: Monroe Williams Date: Fri, 21 Jan 2022 18:12:50 -0800 Subject: [PATCH 2/3] Add a hack to work around the differences between the Adafruit SAMD core and the official Arduino SAMD core. --- Adafruit_SPIDevice.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Adafruit_SPIDevice.cpp b/Adafruit_SPIDevice.cpp index b43e280..ea9f0bc 100644 --- a/Adafruit_SPIDevice.cpp +++ b/Adafruit_SPIDevice.cpp @@ -310,7 +310,14 @@ bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len, _spi->transferBytes(buffer, nullptr, len); } } else -#elif defined(ARDUINO_ARCH_SAMD) +#elif defined(ARDUINO_ARCH_SAMD) && defined(_ADAFRUIT_ZERODMA_H_) + // The variant of transfer() used below currently only exists in the Adafruit core. + // It causes a build failure when building against the main Arduino SAMD core. + // Unfortunately there doesn't seem to be a supported #define that this code + // can use to tell which core it's building against. This hack + // (checking for the include guard that gets defined when the Adafruit core's + // SPI.h includes Adafruit_ZeroDMA.h) works for now, but it should be improved + // when possible. if (_spi) { if (prefix_len > 0) { _spi->transfer(prefix_buffer, nullptr, prefix_len); @@ -423,7 +430,14 @@ bool Adafruit_SPIDevice::write_then_read(uint8_t *write_buffer, _spi->transferBytes(write_buffer, nullptr, write_len); } } else -#elif defined(ARDUINO_ARCH_SAMD) +#elif defined(ARDUINO_ARCH_SAMD) && defined(_ADAFRUIT_ZERODMA_H_) + // The variant of transfer() used below currently only exists in the Adafruit core. + // It causes a build failure when building against the main Arduino SAMD core. + // Unfortunately there doesn't seem to be a supported #define that this code + // can use to tell which core it's building against. This hack + // (checking for the include guard that gets defined when the Adafruit core's + // SPI.h includes Adafruit_ZeroDMA.h) works for now, but it should be improved + // when possible. if (_spi) { if (write_len > 0) { _spi->transfer(write_buffer, nullptr, write_len); From 5efa09dbe71a43a0843ad7f735c30984999d9bd6 Mon Sep 17 00:00:00 2001 From: Monroe Williams Date: Fri, 21 Jan 2022 18:28:04 -0800 Subject: [PATCH 3/3] Comment formatting. --- Adafruit_SPIDevice.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Adafruit_SPIDevice.cpp b/Adafruit_SPIDevice.cpp index ea9f0bc..d1397cf 100644 --- a/Adafruit_SPIDevice.cpp +++ b/Adafruit_SPIDevice.cpp @@ -311,13 +311,13 @@ bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len, } } else #elif defined(ARDUINO_ARCH_SAMD) && defined(_ADAFRUIT_ZERODMA_H_) - // The variant of transfer() used below currently only exists in the Adafruit core. - // It causes a build failure when building against the main Arduino SAMD core. - // Unfortunately there doesn't seem to be a supported #define that this code - // can use to tell which core it's building against. This hack - // (checking for the include guard that gets defined when the Adafruit core's - // SPI.h includes Adafruit_ZeroDMA.h) works for now, but it should be improved - // when possible. + // The variant of transfer() used below currently only exists in the Adafruit + // core. It causes a build failure when building against the main Arduino SAMD + // core. Unfortunately there doesn't seem to be a supported #define that this + // code can use to tell which core it's building against. This hack (checking + // for the include guard that gets defined when the Adafruit core's SPI.h + // includes Adafruit_ZeroDMA.h) works for now, but it should be improved when + // possible. if (_spi) { if (prefix_len > 0) { _spi->transfer(prefix_buffer, nullptr, prefix_len); @@ -431,13 +431,13 @@ bool Adafruit_SPIDevice::write_then_read(uint8_t *write_buffer, } } else #elif defined(ARDUINO_ARCH_SAMD) && defined(_ADAFRUIT_ZERODMA_H_) - // The variant of transfer() used below currently only exists in the Adafruit core. - // It causes a build failure when building against the main Arduino SAMD core. - // Unfortunately there doesn't seem to be a supported #define that this code - // can use to tell which core it's building against. This hack - // (checking for the include guard that gets defined when the Adafruit core's - // SPI.h includes Adafruit_ZeroDMA.h) works for now, but it should be improved - // when possible. + // The variant of transfer() used below currently only exists in the Adafruit + // core. It causes a build failure when building against the main Arduino SAMD + // core. Unfortunately there doesn't seem to be a supported #define that this + // code can use to tell which core it's building against. This hack (checking + // for the include guard that gets defined when the Adafruit core's SPI.h + // includes Adafruit_ZeroDMA.h) works for now, but it should be improved when + // possible. if (_spi) { if (write_len > 0) { _spi->transfer(write_buffer, nullptr, write_len);