Merge pull request #249 from adafruit/spidmadisconfusion

Add nRF52 DMA support and enable CPX DMA
This commit is contained in:
Paint Your Dragon 2019-10-18 11:29:22 -07:00 committed by GitHub
commit e480c8bc40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 20 deletions

View File

@ -50,8 +50,8 @@
#define digitalPinToPort(P) (&(PORT_IOBUS->Group[g_APinDescription[P].ulPort]))
#endif // end PORT_IOBUS
#if defined(USE_SPI_DMA)
#pragma message ("GFX DMA IS ENABLED. HIGHLY EXPERIMENTAL.")
#if defined(USE_SPI_DMA) && (defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO))
// #pragma message ("GFX DMA IS ENABLED. HIGHLY EXPERIMENTAL.")
#include <Adafruit_ZeroDMA.h>
#include "wiring_private.h" // pinPeripheral() function
#include <malloc.h> // memalign() function
@ -648,7 +648,7 @@ void Adafruit_SPITFT::initSPI(uint32_t freq, uint8_t spiMode) {
delay(200);
}
#if defined(USE_SPI_DMA)
#if defined(USE_SPI_DMA) && (defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO))
if(((connection == TFT_HARD_SPI) || (connection == TFT_PARALLEL)) &&
(dma.allocate() == DMA_STATUS_OK)) { // Allocate channel
// The DMA library needs to alloc at least one valid descriptor,
@ -1003,7 +1003,7 @@ void Adafruit_SPITFT::writePixels(uint16_t *colors, uint32_t len,
}
return;
#elif defined(USE_SPI_DMA)
#elif defined(USE_SPI_DMA) && (defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO))
if((connection == TFT_HARD_SPI) || (connection == TFT_PARALLEL)) {
int maxSpan = maxFillLen / 2; // One scanline max
uint8_t pixelBufIdx = 0; // Active pixel buffer number
@ -1076,14 +1076,14 @@ void Adafruit_SPITFT::writePixels(uint16_t *colors, uint32_t len,
lastFillLen = 0;
if(block) {
while(dma_busy); // Wait for last line to complete
#if defined(__SAMD51__) || defined(_SAMD21_)
#if defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO)
if(connection == TFT_HARD_SPI) {
// See SAMD51/21 note in writeColor()
hwspi._spi->setDataMode(hwspi._mode);
} else {
pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO
}
#endif // end __SAMD51__ || _SAMD21_
#endif // end __SAMD51__ || ARDUINO_SAMD_ZERO
}
return;
}
@ -1103,16 +1103,16 @@ void Adafruit_SPITFT::writePixels(uint16_t *colors, uint32_t len,
was used (as is the default case).
*/
void Adafruit_SPITFT::dmaWait(void) {
#if defined(USE_SPI_DMA)
#if defined(USE_SPI_DMA) && (defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO))
while(dma_busy);
#if defined(__SAMD51__) || defined(_SAMD21_)
#if defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO)
if(connection == TFT_HARD_SPI) {
// See SAMD51/21 note in writeColor()
hwspi._spi->setDataMode(hwspi._mode);
} else {
pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO
}
#endif // end __SAMD51__ || _SAMD21_
#endif // end __SAMD51__ || ARDUINO_SAMD_ZERO
#endif
}
@ -1175,7 +1175,7 @@ void Adafruit_SPITFT::writeColor(uint16_t color, uint32_t len) {
return;
}
#else // !ESP32
#if defined(USE_SPI_DMA)
#if defined(USE_SPI_DMA) && (defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO))
if(((connection == TFT_HARD_SPI) || (connection == TFT_PARALLEL)) &&
(len >= 16)) { // Don't bother with DMA on short pixel runs
int i, d, numDescriptors;
@ -1252,7 +1252,7 @@ void Adafruit_SPITFT::writeColor(uint16_t color, uint32_t len) {
// turns out to be MUCH slower on many graphics operations (as when
// drawing lines, pixel-by-pixel), perhaps because it's a volatile
// type and doesn't cache. Working on this.
#if defined(__SAMD51__) || defined(_SAMD21_)
#if defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO)
if(connection == TFT_HARD_SPI) {
// SAMD51: SPI DMA seems to leave the SPI peripheral in a freaky
// state on completion. Workaround is to explicitly set it back...

View File

@ -71,8 +71,10 @@ typedef volatile ADAGFX_PORT_t* PORTreg_t; ///< PORT register type
#define DEFAULT_SPI_FREQ 16000000L ///< Hardware SPI default speed
#endif
#if defined(ADAFRUIT_PYPORTAL) || defined(ADAFRUIT_PYBADGE_M4_EXPRESS) || defined(ADAFRUIT_PYGAMER_M4_EXPRESS)|| defined(ADAFRUIT_MONSTER_M4SK_EXPRESS)
#define USE_SPI_DMA ///< Auto DMA if using PyPortal
#if defined(ADAFRUIT_PYPORTAL) || defined(ADAFRUIT_PYBADGE_M4_EXPRESS) || \
defined(ADAFRUIT_PYGAMER_M4_EXPRESS)|| defined(ADAFRUIT_MONSTER_M4SK_EXPRESS) || \
defined(NRF52_SERIES) || defined(ADAFRUIT_CIRCUITPLAYGROUND_M0)
#define USE_SPI_DMA ///< Auto DMA
#else
//#define USE_SPI_DMA ///< If set, use DMA if available
#endif
@ -82,11 +84,7 @@ typedef volatile ADAGFX_PORT_t* PORTreg_t; ///< PORT register type
// 4 bytes/pixel on display major axis + 8 bytes/pixel on minor axis,
// e.g. 320x240 pixels = 320 * 4 + 240 * 8 = 3,200 bytes.
#if !defined(ARDUINO_ARCH_SAMD)
#undef USE_SPI_DMA ///< DMA currently for SAMD chips only
#endif
#if defined(USE_SPI_DMA)
#if defined(USE_SPI_DMA) && (defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO))
#include <Adafruit_ZeroDMA.h>
#endif
@ -98,7 +96,8 @@ typedef volatile ADAGFX_PORT_t* PORTreg_t; ///< PORT register type
// an enumerated type as the first argument: tft8 (for 8-bit parallel) or
// tft16 (for 16-bit)...even though 16-bit isn't fully implemented or tested
// and might never be, still needed that disambiguation from soft SPI.
enum tftBusWidth { tft8bitbus, tft16bitbus }; ///< For first arg to parallel constructor
/*! For first arg to parallel constructor */
enum tftBusWidth { tft8bitbus, tft16bitbus };
// CLASS DEFINITION --------------------------------------------------------
@ -479,7 +478,7 @@ class Adafruit_SPITFT : public Adafruit_GFX {
#if defined(__cplusplus) && (__cplusplus >= 201100)
}; ///< Only one interface is active
#endif
#if defined(USE_SPI_DMA) // Used by hardware SPI and tft8
#if defined(USE_SPI_DMA) && (defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO)) // Used by hardware SPI and tft8
Adafruit_ZeroDMA dma; ///< DMA instance
DmacDescriptor *dptr = NULL; ///< 1st descriptor
DmacDescriptor *descriptor = NULL; ///< Allocated descriptor list