diff --git a/Adafruit_SPITFT.cpp.bak b/Adafruit_SPITFT.cpp.bak deleted file mode 100644 index ab3d188..0000000 --- a/Adafruit_SPITFT.cpp.bak +++ /dev/null @@ -1,831 +0,0 @@ -/*! -* @file Adafruit_SPITFT.cpp -* -* @mainpage Adafruit SPI TFT Displays -* -* @section intro_sec Introduction - This is our library for generic SPI TFT Displays with - address windows and 16 bit color (e.g. ILI9341, HX8357D, ST7735...) - - Check out the links above for our tutorials and wiring diagrams - These displays use SPI to communicate, 4 or 5 pins are required to - interface (RST is optional) - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - Written by Limor Fried/Ladyada for Adafruit Industries. - MIT license, all text above must be included in any redistribution -* @section dependencies Dependencies -* -* This library depends on -* Adafruit_GFX being present on your system. Please make sure you have -* installed the latest version before using this library. -* -* @section author Author -* -* Written by Limor "ladyada" Fried for Adafruit Industries. -* -* @section license License -* -* BSD license, all text here must be included in any redistribution. -* -*/ - -#if !defined(__AVR_ATtiny85__) // NOT A CHANCE of this stuff working on ATtiny - -#include "Adafruit_SPITFT.h" -#if !defined(ARDUINO_STM32_FEATHER) - #include "pins_arduino.h" -#endif -#if !defined(ARDUINO_STM32_FEATHER) && !defined(RASPI) - #include "wiring_private.h" -#endif -#include - -//elif defined(__SAMD21G18A__) || defined(__SAMD21J18A__) || defined(__SAMD21E17A__) || defined(__SAMD21E18A__) - -#ifdef ARDUINO_ARCH_SAMD && !defined(__SAMD51__) -// On SAMD21, redefine digitalPinToPort() to use the slightly-faster -// PORT_IOBUS rather than PORT (not needed on SAMD51). -#undef digitalPinToPort -#define digitalPinToPort(P) (&(PORT_IOBUS->Group[g_APinDescription[P].ulPort])) -#endif - -#include "Adafruit_SPITFT_Macros.h" - -#ifdef USE_SPI_DMA -#include -#include // memalign() function - -// DMA transfer-in-progress indicator and callback -static volatile boolean dma_busy = false; -static volatile Adafruit_SPITFT *spitft = NULL; -static void dma_callback(Adafruit_ZeroDMA *dma) { - // If spitft pointer is set, deselect TFT and end the SPI transaction - // here in the callback rather than at end of drawing function. Avoids - // a (possibly unnecessary) function call at the start of every graphics - // operation. Can't do this in SPI_BEGIN_TRANSACTION because other code - // outside the library (e.g. SD card reading) may be waiting on the - // GFX SPI transaction to end first. - if(spitft) { - ((Adafruit_SPITFT *)spitft)->endWrite(); - spitft = NULL; - } - dma_busy = false; -} - -/**************************************************************************/ -/*! - @brief Poll whether a previous DMA operation is still in-progress. - @return true if SPITFT DMA operation in progress, false if available. -*/ -/**************************************************************************/ -boolean Adafruit_SPITFT::DMA_busy(void) { - return dma_busy; -} - - #define DMA_WAIT while(dma_busy); ///< Wait for dma busy flag to clear -#else - #define DMA_WAIT ///< Do nothing; DMA not used -#endif // USE_SPI_DMA - -/**************************************************************************/ -/*! - @brief Pass 8-bit (each) R,G,B, get back 16-bit packed color - This function converts 8-8-8 RGB data to 16-bit 5-6-5 - @param red Red 8 bit color - @param green Green 8 bit color - @param blue Blue 8 bit color - @return Unsigned 16-bit down-sampled color in 5-6-5 format -*/ -/**************************************************************************/ -uint16_t Adafruit_SPITFT::color565(uint8_t red, uint8_t green, uint8_t blue) { - return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3); -} - - -/**************************************************************************/ -/*! - @brief Instantiate Adafruit SPI display driver with software SPI - @param w Display width in pixels - @param h Display height in pixels - @param cs Chip select pin # - @param dc Data/Command pin # - @param mosi SPI MOSI pin # - @param sclk SPI Clock pin # - @param rst Reset pin # (optional, pass -1 if unused) - @param miso SPI MISO pin # (optional, pass -1 if unused) -*/ -/**************************************************************************/ -Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, - int8_t cs, int8_t dc, int8_t mosi, - int8_t sclk, int8_t rst, int8_t miso) - : Adafruit_GFX(w, h) { - _cs = cs; - _dc = dc; - _rst = rst; - _sclk = sclk; - _mosi = mosi; - _miso = miso; - _freq = 0; -#ifdef USE_FAST_PINIO - dcport = (RwReg *)portOutputRegister(digitalPinToPort(dc)); - dcpinmask = digitalPinToBitMask(dc); - clkport = (RwReg *)portOutputRegister(digitalPinToPort(sclk)); - clkpinmask = digitalPinToBitMask(sclk); - mosiport = (RwReg *)portOutputRegister(digitalPinToPort(mosi)); - mosipinmask = digitalPinToBitMask(mosi); - if(miso >= 0){ - misoport = (RwReg *)portInputRegister(digitalPinToPort(miso)); - misopinmask = digitalPinToBitMask(miso); - } else { - misoport = 0; - misopinmask = 0; - } - if(cs >= 0) { - csport = (RwReg *)portOutputRegister(digitalPinToPort(cs)); - cspinmask = digitalPinToBitMask(cs); - } else { - // No chip-select line defined; might be permanently tied to GND. - // Assign a valid GPIO register (though not used for CS), and an - // empty pin bitmask...the nonsense bit-twiddling might be faster - // than checking _cs and possibly branching. - csport = dcport; - cspinmask = 0; - } -#endif -} - -/**************************************************************************/ -/*! - @brief Instantiate Adafruit SPI display driver with hardware SPI - @param w Display width in pixels - @param h Display height in pixels - @param cs Chip select pin # - @param dc Data/Command pin # - @param rst Reset pin # (optional, pass -1 if unused) -*/ -/**************************************************************************/ -Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, - int8_t cs, int8_t dc, int8_t rst) - : Adafruit_SPITFT(w, h, &SPI, cs, dc, rst) -{ - // We just call the hardware SPI instantiator with the default SPI device (&SPI) -} - -/**************************************************************************/ -/*! - @brief Instantiate Adafruit SPI display driver with hardware SPI - @param w Display width in pixels - @param h Display height in pixels - @param spiClass A pointer to an SPI hardware interface, e.g. &SPI1 - @param cs Chip select pin # - @param dc Data/Command pin # - @param rst Reset pin # (optional, pass -1 if unused) -*/ -/**************************************************************************/ -Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass, - int8_t cs, int8_t dc, int8_t rst) - : Adafruit_GFX(w, h) { - _cs = cs; - _dc = dc; - _rst = rst; - _spi = spiClass; - _sclk = -1; - _mosi = -1; - _miso = -1; - _freq = 0; -#ifdef USE_FAST_PINIO - clkport = 0; - clkpinmask = 0; - mosiport = 0; - mosipinmask = 0; - misoport = 0; - misopinmask = 0; - dcport = (RwReg *)portOutputRegister(digitalPinToPort(dc)); - dcpinmask = digitalPinToBitMask(dc); - if(cs >= 0) { - csport = (RwReg *)portOutputRegister(digitalPinToPort(cs)); - cspinmask = digitalPinToBitMask(cs); - } else { - // See notes in prior constructor. - csport = dcport; - cspinmask = 0; - } -#endif -} - -/**************************************************************************/ -/*! - @brief Initialiaze the SPI interface (hardware or software) - @param freq The desired maximum SPI hardware clock frequency -*/ -/**************************************************************************/ -void Adafruit_SPITFT::initSPI(uint32_t freq) { - _freq = freq; - - // Control Pins - if(_cs >= 0) { - pinMode(_cs, OUTPUT); - digitalWrite(_cs, HIGH); // Deselect - } - pinMode(_dc, OUTPUT); - digitalWrite(_dc, LOW); - - // Software SPI - if(_sclk >= 0){ - pinMode(_mosi, OUTPUT); - digitalWrite(_mosi, LOW); - pinMode(_sclk, OUTPUT); - digitalWrite(_sclk, HIGH); - if(_miso >= 0){ - pinMode(_miso, INPUT); - } - } - - // Hardware SPI - SPI_BEGIN(); - - // toggle RST low to reset - if (_rst >= 0) { - pinMode(_rst, OUTPUT); - digitalWrite(_rst, HIGH); - delay(100); - digitalWrite(_rst, LOW); - delay(100); - digitalWrite(_rst, HIGH); - delay(200); - } - -#ifdef USE_SPI_DMA - - // INITIALIZE DMA - - if(dma.allocate() == DMA_STATUS_OK) { // Allocate channel - // The DMA library needs to allocate at least one valid descriptor, - // so we do that here. It's not used in the conventional sense though, - // just before a transfer we copy descriptor[0] to this address. - if(dptr = dma.addDescriptor(NULL, NULL, 42, DMA_BEAT_SIZE_BYTE, - false, false)) { - // Determine maximum number of descriptors required based on - // total display pixels. Maximum of 32,767 (not 32,768) pixels - // per DMA descriptor (because 2 bytes/pixel, and max 65,535 - // (not 65,536) bytes/DMA desc). Round up for last descriptor. - int numDescriptors = - (WIDTH * HEIGHT + DMA_PIXELS - 1) / DMA_PIXELS; - // DMA descriptors MUST be 128-bit (16 byte) aligned. - // memalign() is considered 'obsolete' but it's replacements - // (aligned_alloc() or posix_memalign()) are not currently - // available in the version of ARM GCC in use, but this is, - // so here we are. - if((descriptor = (DmacDescriptor *)memalign(16, - numDescriptors * sizeof(DmacDescriptor)))) { - - // Set up SPI DMA on SAMD boards: - int dmac_id; - volatile uint32_t *data_reg; -Serial.println("_spi: "); -Serial.println((uint32_t)_spi); -Serial.println("&SPI: "); -Serial.println((uint32_t)&SPI); -Serial.println("&SPI1: "); -Serial.println((uint32_t)&SPI1); - if(&PERIPH_SPI == &sercom0) { - dmac_id = SERCOM0_DMAC_ID_TX; - data_reg = &SERCOM0->SPI.DATA.reg; -#if defined SERCOM1 - } else if(&PERIPH_SPI == &sercom1) { - dmac_id = SERCOM1_DMAC_ID_TX; - data_reg = &SERCOM1->SPI.DATA.reg; -#endif -#if defined SERCOM2 - } else if(&PERIPH_SPI == &sercom2) { - dmac_id = SERCOM2_DMAC_ID_TX; - data_reg = &SERCOM2->SPI.DATA.reg; -#endif -#if defined SERCOM3 - } else if(&PERIPH_SPI == &sercom3) { - dmac_id = SERCOM3_DMAC_ID_TX; - data_reg = &SERCOM3->SPI.DATA.reg; -#endif -#if defined SERCOM4 - } else if(&PERIPH_SPI == &sercom4) { - dmac_id = SERCOM4_DMAC_ID_TX; - data_reg = &SERCOM4->SPI.DATA.reg; -#endif -#if defined SERCOM5 - } else if(&PERIPH_SPI == &sercom5) { - dmac_id = SERCOM5_DMAC_ID_TX; - data_reg = &SERCOM5->SPI.DATA.reg; -#endif - } - - dma.setTrigger(dmac_id); - dma.setAction(DMA_TRIGGER_ACTON_BEAT); - - // Initialize descriptor list. - for(int d=0; d>= 1){ - if((b) & bit){ - SSPI_MOSI_HIGH(); - } else { - SSPI_MOSI_LOW(); - } - SSPI_SCK_LOW(); - SSPI_SCK_HIGH(); - } -} - - -/* - * Transaction API - * */ - -/**************************************************************************/ -/*! - @brief Begin an SPI transaction & set CS low. -*/ -/**************************************************************************/ -void inline Adafruit_SPITFT::startWrite(void){ - DMA_WAIT; // Wait for any prior SPI DMA to complete - SPI_BEGIN_TRANSACTION(); - SPI_CS_LOW(); -} - -/**************************************************************************/ -/*! - @brief Begin an SPI transaction & set CS high. -*/ -/**************************************************************************/ -void inline Adafruit_SPITFT::endWrite(void){ -#ifdef USE_SPI_DMA - // SPI DMA enabled: wait for DMA completion and end transaction ONLY if - // spitft is NULL. Otherwise, calling function can proceed and - // equivalent code in DMA callback is used. - if(!spitft) { - while(dma_busy); // Wait for DMA operation to complete - SPI_CS_HIGH(); - SPI_END_TRANSACTION(); - } -#else - SPI_CS_HIGH(); - SPI_END_TRANSACTION(); -#endif -} - -/**************************************************************************/ -/*! - @brief Write a command byte (must have a transaction in progress) - @param cmd The 8-bit command to send -*/ -/**************************************************************************/ -void Adafruit_SPITFT::writeCommand(uint8_t cmd){ - SPI_DC_LOW(); - spiWrite(cmd); - SPI_DC_HIGH(); -} - -/**************************************************************************/ -/*! - @brief Push a 2-byte color to the framebuffer RAM, will start transaction - @param color 16-bit 5-6-5 Color to draw -*/ -/**************************************************************************/ -void Adafruit_SPITFT::pushColor(uint16_t color) { - startWrite(); - SPI_WRITE16(color); - endWrite(); -} - -/**************************************************************************/ -/*! - @brief Blit multiple 2-byte colors (must have a transaction in progress) - @param colors Array of 16-bit 5-6-5 Colors to draw - @param len How many pixels to draw - 2 bytes per pixel! -*/ -/**************************************************************************/ -void Adafruit_SPITFT::writePixels(uint16_t *colors, uint32_t len) { -#ifdef USE_SPI_DMA - while(len) { - int count = len; - if(count > DMA_PIXELS) count = DMA_PIXELS; - - // Because TFT and SAMD endianisms are different, must swap bytes - // from the 'colors' array passed into a DMA working buffer. This - // can take place while the prior DMA transfer is in progress, - // hence the need for two pixelBufs. - for(int i=0; i> 8, - lo = color; -//while(dma_busy); - if(hi == lo) { // If high and low bytes of color are the same... - pixelBuf[pixelBufIdx][0] = lo * 0x0101; - // Can do this with a relatively short descriptor list, - // each transferring a max of 32767 (not 32768) pixels. - int numDescriptors = (len + 32766) / 32767; - for(int d=0; d 32767) count = 32767; - descriptor[d].SRCADDR.reg = - (uint32_t)&pixelBuf[pixelBufIdx]; - descriptor[d].BTCTRL.bit.SRCINC = 0; - descriptor[d].BTCNT.reg = count * 2; - descriptor[d].DESCADDR.reg = - (d < (numDescriptors - 1)) ? (uint32_t)&descriptor[d + 1] : 0; -//descriptor[d].DESCADDR.reg = 0; - len -= count; - } - } else { - // If high and low bytes are different, it's necessary to fill - // a buffer with pixel data (swapping high and low bytes because - // TFT and SAMD are different endianisms) and create a longer - // descriptor list pointing repeatedly to this data. -// This can maybe be avoided if color is same as last time and -// length is <= last time. Or should we always fill pixelBuf to a -// known length and then check pixel color? -uint32_t *pixelPtr = (uint32_t *)&pixelBuf[pixelBufIdx]; -if(color == lastFillColor) { - if(len > lastFillLen) { - // Work 32 bits (2 pixels) at a time... - uint32_t twoPixels = __builtin_bswap16(color) * 0x00010001; -int fillMin = lastFillLen / 2 + 1; -int fillMax = (((DMA_PIXELS < len) ? DMA_PIXELS : len) + 1) / 2; - for(int i=fillMin; i DMA_PIXELS) count = DMA_PIXELS; - descriptor[d].SRCADDR.reg = - (uint32_t)pixelPtr + lastFillLen * 2; - descriptor[d].BTCTRL.bit.SRCINC = 1; - descriptor[d].BTCNT.reg = count * 2; - descriptor[d].DESCADDR.reg = - (d < (numDescriptors - 1)) ? (uint32_t)&descriptor[d + 1] : 0; -//descriptor[d].DESCADDR.reg = 0; - len -= count; - } - } - memcpy(dptr, &descriptor[0], sizeof(DmacDescriptor)); - dma_busy = true; // ANY function using SPI must poll busy flag! - spitft = this; // Save pointer to Adafruit_SPITFT type for callback - dma.startJob(); // Trigger SPI DMA transfer - pixelBufIdx = 1 - pixelBufIdx; // Swap DMA pixel buffers -#else - #ifdef SPI_HAS_WRITE_PIXELS - if(_sclk >= 0){ - for (uint32_t t=0; t SPI_MAX_PIXELS_AT_ONCE)?SPI_MAX_PIXELS_AT_ONCE:len; - uint16_t tlen = 0; - - for (uint32_t t=0; tblen)?blen:len; - writePixels(temp, tlen); - len -= tlen; - } - #else - uint8_t hi = color >> 8, lo = color; - if(_sclk < 0){ //AVR Optimization - for (uint32_t t=len; t; t--){ - HSPI_WRITE(hi); - HSPI_WRITE(lo); - } - return; - } - for (uint32_t t=len; t; t--){ - spiWrite(hi); - spiWrite(lo); - } - #endif -#endif -} - -/**************************************************************************/ -/*! - @brief Write a pixel (must have a transaction in progress) - @param x x coordinate - @param y y coordinate - @param color 16-bit 5-6-5 Color to draw with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) { - if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; - DMA_WAIT; - setAddrWindow(x,y,1,1); - writePixel(color); -} - -/**************************************************************************/ -/*! - @brief Write a filled rectangle (must have a transaction in progress) - @param x Top left corner x coordinate - @param y Top left corner y coordinate - @param w Width in pixels - @param h Height in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){ - if((x >= _width) || (y >= _height)) return; - int16_t x2 = x + w - 1, y2 = y + h - 1; - if((x2 < 0) || (y2 < 0)) return; - - // Clip left/top - if(x < 0) { - x = 0; - w = x2 + 1; - } - if(y < 0) { - y = 0; - h = y2 + 1; - } - - // Clip right/bottom - if(x2 >= _width) w = _width - x; - if(y2 >= _height) h = _height - y; - - int32_t len = (int32_t)w * h; - DMA_WAIT; - setAddrWindow(x, y, w, h); - writeColor(color, len); -} - -/**************************************************************************/ -/*! - @brief Write a perfectly vertical line (must have a transaction in progress) - @param x Top-most x coordinate - @param y Top-most y coordinate - @param h Height in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void inline Adafruit_SPITFT::writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color){ - writeFillRect(x, y, 1, h, color); -} - -/**************************************************************************/ -/*! - @brief Write a perfectly horizontal line (must have a transaction in progress) - @param x Left-most x coordinate - @param y Left-most y coordinate - @param w Width in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void inline Adafruit_SPITFT::writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color){ - writeFillRect(x, y, w, 1, color); -} - -/**************************************************************************/ -/*! - @brief Draw a pixel - sets up transaction - @param x x coordinate - @param y y coordinate - @param color 16-bit 5-6-5 Color to draw with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::drawPixel(int16_t x, int16_t y, uint16_t color){ - startWrite(); - writePixel(x, y, color); - endWrite(); -} - -/**************************************************************************/ -/*! - @brief Write a perfectly vertical line - sets up transaction - @param x Top-most x coordinate - @param y Top-most y coordinate - @param h Height in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::drawFastVLine(int16_t x, int16_t y, - int16_t h, uint16_t color) { - startWrite(); - writeFastVLine(x, y, h, color); - endWrite(); -} - -/**************************************************************************/ -/*! - @brief Write a perfectly horizontal line - sets up transaction - @param x Left-most x coordinate - @param y Left-most y coordinate - @param w Width in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::drawFastHLine(int16_t x, int16_t y, - int16_t w, uint16_t color) { - startWrite(); - writeFastHLine(x, y, w, color); - endWrite(); -} - -/**************************************************************************/ -/*! - @brief Fill a rectangle completely with one color. - @param x Top left corner x coordinate - @param y Top left corner y coordinate - @param w Width in pixels - @param h Height in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color) { - startWrite(); - writeFillRect(x,y,w,h,color); - endWrite(); -} - - -/**************************************************************************/ -/*! - @brief Invert the display using built-in hardware command - @param i True if you want to invert, false to make 'normal' -*/ -/**************************************************************************/ -void Adafruit_SPITFT::invertDisplay(boolean i) { - startWrite(); - writeCommand(i ? invertOnCommand : invertOffCommand); - endWrite(); -} - - -/**************************************************************************/ -/*! - @brief Draw a 16-bit image (RGB 5/6/5) at the specified (x,y) position. - For 16-bit display devices; no color reduction performed. - Adapted from https://github.com/PaulStoffregen/ILI9341_t3 - by Marc MERLIN. See examples/pictureEmbed to use this. - 5/6/2017: function name and arguments have changed for compatibility - with current GFX library and to avoid naming problems in prior - implementation. Formerly drawBitmap() with arguments in different order. - - @param x Top left corner x coordinate - @param y Top left corner y coordinate - @param pcolors 16-bit array with 16-bit color bitmap - @param w Width of bitmap in pixels - @param h Height of bitmap in pixels -*/ -/**************************************************************************/ -void Adafruit_SPITFT::drawRGBBitmap(int16_t x, int16_t y, - uint16_t *pcolors, int16_t w, int16_t h) { - - int16_t x2, y2; // Lower-right coord - if(( x >= _width ) || // Off-edge right - ( y >= _height) || // " top - ((x2 = (x+w-1)) < 0 ) || // " left - ((y2 = (y+h-1)) < 0) ) return; // " bottom - - int16_t bx1=0, by1=0, // Clipped top-left within bitmap - saveW=w; // Save original bitmap width value - if(x < 0) { // Clip left - w += x; - bx1 = -x; - x = 0; - } - if(y < 0) { // Clip top - h += y; - by1 = -y; - y = 0; - } - if(x2 >= _width ) w = _width - x; // Clip right - if(y2 >= _height) h = _height - y; // Clip bottom - - pcolors += by1 * saveW + bx1; // Offset bitmap ptr to clipped top-left - startWrite(); // Includes a DMA_WAIT - setAddrWindow(x, y, w, h); // Clipped area - while(h--) { // For each (clipped) scanline... - writePixels(pcolors, w); // Push one (clipped) row - pcolors += saveW; // Advance pointer by one full (unclipped) line - } - endWrite(); -} - -#endif // !__AVR_ATtiny85__ - diff --git a/Adafruit_SPITFT.cpp.bak2 b/Adafruit_SPITFT.cpp.bak2 deleted file mode 100644 index 3928459..0000000 --- a/Adafruit_SPITFT.cpp.bak2 +++ /dev/null @@ -1,861 +0,0 @@ -/*! -* @file Adafruit_SPITFT.cpp -* -* @mainpage Adafruit SPI TFT Displays -* -* @section intro_sec Introduction - This is our library for generic SPI TFT Displays with - address windows and 16 bit color (e.g. ILI9341, HX8357D, ST7735...) - - Check out the links above for our tutorials and wiring diagrams - These displays use SPI to communicate, 4 or 5 pins are required to - interface (RST is optional) - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - Written by Limor Fried/Ladyada for Adafruit Industries. - MIT license, all text above must be included in any redistribution -* @section dependencies Dependencies -* -* This library depends on -* Adafruit_GFX being present on your system. Please make sure you have -* installed the latest version before using this library. -* -* @section author Author -* -* Written by Limor "ladyada" Fried for Adafruit Industries. -* -* @section license License -* -* BSD license, all text here must be included in any redistribution. -* -*/ - -#if !defined(__AVR_ATtiny85__) // NOT A CHANCE of this stuff working on ATtiny - -#include "Adafruit_SPITFT.h" -#if !defined(ARDUINO_STM32_FEATHER) - #include "pins_arduino.h" -#endif -#if !defined(ARDUINO_STM32_FEATHER) && !defined(RASPI) - #include "wiring_private.h" -#endif -#include - -#ifdef PORT_IOBUS -// On SAMD21, redefine digitalPinToPort() to use the slightly-faster -// PORT_IOBUS rather than PORT (not needed on SAMD51). -#undef digitalPinToPort -#define digitalPinToPort(P) (&(PORT_IOBUS->Group[g_APinDescription[P].ulPort])) -#endif - -#include "Adafruit_SPITFT_Macros.h" - -#ifdef USE_SPI_DMA -#include -#include // memalign() function - -// DMA transfer-in-progress indicator and callback -static volatile boolean dma_busy = false; -static volatile Adafruit_SPITFT *spitft = NULL; -static void dma_callback(Adafruit_ZeroDMA *dma) { - // If spitft pointer is set, deselect TFT and end the SPI transaction - // here in the callback rather than at end of drawing function. Avoids - // a (possibly unnecessary) function call at the start of every graphics - // operation. Can't do this in SPI_BEGIN_TRANSACTION because other code - // outside the library (e.g. SD card reading) may be waiting on the - // GFX SPI transaction to end first. - if(spitft) { - ((Adafruit_SPITFT *)spitft)->endWrite(); - spitft = NULL; - } - dma_busy = false; -} - -/**************************************************************************/ -/*! - @brief Poll whether a previous DMA operation is still in-progress. - @return true if SPITFT DMA operation in progress, false if available. -*/ -/**************************************************************************/ -boolean Adafruit_SPITFT::DMA_busy(void) { - return dma_busy; -} - - #define DMA_WAIT while(dma_busy); ///< Wait for dma busy flag to clear -#else - #define DMA_WAIT ///< Do nothing; DMA not used -#endif // USE_SPI_DMA - -/**************************************************************************/ -/*! - @brief Pass 8-bit (each) R,G,B, get back 16-bit packed color - This function converts 8-8-8 RGB data to 16-bit 5-6-5 - @param red Red 8 bit color - @param green Green 8 bit color - @param blue Blue 8 bit color - @return Unsigned 16-bit down-sampled color in 5-6-5 format -*/ -/**************************************************************************/ -uint16_t Adafruit_SPITFT::color565(uint8_t red, uint8_t green, uint8_t blue) { - return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3); -} - - -/**************************************************************************/ -/*! - @brief Instantiate Adafruit SPI display driver with software SPI - @param w Display width in pixels - @param h Display height in pixels - @param cs Chip select pin # - @param dc Data/Command pin # - @param mosi SPI MOSI pin # - @param sclk SPI Clock pin # - @param rst Reset pin # (optional, pass -1 if unused) - @param miso SPI MISO pin # (optional, pass -1 if unused) -*/ -/**************************************************************************/ -Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, - int8_t cs, int8_t dc, int8_t mosi, - int8_t sclk, int8_t rst, int8_t miso) - : Adafruit_GFX(w, h) { - _cs = cs; - _dc = dc; - _rst = rst; - _sclk = sclk; - _mosi = mosi; - _miso = miso; - _freq = 0; -#ifdef USE_FAST_PINIO - dcport = (RwReg *)portOutputRegister(digitalPinToPort(dc)); - dcpinmask = digitalPinToBitMask(dc); - clkport = (RwReg *)portOutputRegister(digitalPinToPort(sclk)); - clkpinmask = digitalPinToBitMask(sclk); - mosiport = (RwReg *)portOutputRegister(digitalPinToPort(mosi)); - mosipinmask = digitalPinToBitMask(mosi); - if(miso >= 0){ - misoport = (RwReg *)portInputRegister(digitalPinToPort(miso)); - misopinmask = digitalPinToBitMask(miso); - } else { - misoport = 0; - misopinmask = 0; - } - if(cs >= 0) { - csport = (RwReg *)portOutputRegister(digitalPinToPort(cs)); - cspinmask = digitalPinToBitMask(cs); - } else { - // No chip-select line defined; might be permanently tied to GND. - // Assign a valid GPIO register (though not used for CS), and an - // empty pin bitmask...the nonsense bit-twiddling might be faster - // than checking _cs and possibly branching. - csport = dcport; - cspinmask = 0; - } -#endif -} - -/**************************************************************************/ -/*! - @brief Instantiate Adafruit SPI display driver with hardware SPI - @param w Display width in pixels - @param h Display height in pixels - @param cs Chip select pin # - @param dc Data/Command pin # - @param rst Reset pin # (optional, pass -1 if unused) -*/ -/**************************************************************************/ -Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, - int8_t cs, int8_t dc, int8_t rst) - : Adafruit_SPITFT(w, h, &SPI, cs, dc, rst) -{ - // We just call the hardware SPI instantiator with the default SPI device (&SPI) -} - -/**************************************************************************/ -/*! - @brief Instantiate Adafruit SPI display driver with hardware SPI - @param w Display width in pixels - @param h Display height in pixels - @param spiClass A pointer to an SPI hardware interface, e.g. &SPI1 - @param cs Chip select pin # - @param dc Data/Command pin # - @param rst Reset pin # (optional, pass -1 if unused) -*/ -/**************************************************************************/ -Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass, - int8_t cs, int8_t dc, int8_t rst) - : Adafruit_GFX(w, h) { - _cs = cs; - _dc = dc; - _rst = rst; - _spi = spiClass; - _sclk = -1; - _mosi = -1; - _miso = -1; - _freq = 0; -#ifdef USE_FAST_PINIO - clkport = 0; - clkpinmask = 0; - mosiport = 0; - mosipinmask = 0; - misoport = 0; - misopinmask = 0; - dcport = (RwReg *)portOutputRegister(digitalPinToPort(dc)); - dcpinmask = digitalPinToBitMask(dc); - if(cs >= 0) { - csport = (RwReg *)portOutputRegister(digitalPinToPort(cs)); - cspinmask = digitalPinToBitMask(cs); - } else { - // See notes in prior constructor. - csport = dcport; - cspinmask = 0; - } -#endif -} - - -/**************************************************************************/ -/*! - @brief Initialiaze the SPI interface (hardware or software) - @param freq The desired maximum SPI hardware clock frequency -*/ -/**************************************************************************/ -void Adafruit_SPITFT::initSPI(uint32_t freq) { - _freq = freq; - - // Control Pins - if(_cs >= 0) { - pinMode(_cs, OUTPUT); - digitalWrite(_cs, HIGH); // Deselect - } - pinMode(_dc, OUTPUT); - digitalWrite(_dc, LOW); - - // Software SPI - if(_sclk >= 0){ - pinMode(_mosi, OUTPUT); - digitalWrite(_mosi, LOW); - pinMode(_sclk, OUTPUT); - digitalWrite(_sclk, HIGH); - if(_miso >= 0){ - pinMode(_miso, INPUT); - } - } - - // Hardware SPI - SPI_BEGIN(); - - // toggle RST low to reset - if (_rst >= 0) { - pinMode(_rst, OUTPUT); - digitalWrite(_rst, HIGH); - delay(100); - digitalWrite(_rst, LOW); - delay(100); - digitalWrite(_rst, HIGH); - delay(200); - } - -#ifdef USE_SPI_DMA - - // INITIALIZE DMA - - if(dma.allocate() == DMA_STATUS_OK) { // Allocate channel - // The DMA library needs to allocate at least one valid descriptor, - // so we do that here. It's not used in the usual sense though, - // just before a transfer we copy descriptor[0] to this address. - if(dptr = dma.addDescriptor(NULL, NULL, 42, DMA_BEAT_SIZE_BYTE, - false, false)) { - // Allocate 2 scanlines worth of pixels on display's major axis, - // whichever that is, rounding each up to 2-pixel boundary. - int major = (WIDTH > HEIGHT) ? WIDTH : HEIGHT; - major += (major & 1); // -> next 2-pixel bound, if needed. - maxFillLen = major * 2; // 2 scanlines - // Note to future self: if you decide to make the pixel buffer - // much larger, remember that DMA transfer descriptors can't - // exceed 65,535 bytes (not 65,536), meaning 32,767 pixels tops. - // Not that we have that kind of RAM to throw around right now. - if((pixelBuf[0] = - (uint16_t *)malloc(maxFillLen * sizeof(uint16_t)))) { - // Alloc OK. Get pointer to start of second scanline. - pixelBuf[1] = &pixelBuf[0][major]; - // Determine number of DMA descriptors needed to cover - // entire screen when entire 2-line pixelBuf is used - // (round up for fractional last descriptor). - int numDescriptors = (WIDTH * HEIGHT + (maxFillLen - 1)) / - maxFillLen; - // DMA descriptors MUST be 128-bit (16 byte) aligned. - // memalign() is considered 'obsolete' but it's replacements - // (aligned_alloc() or posix_memalign()) are not currently - // available in the version of ARM GCC in use, but this is, - // so here we are. - if((descriptor = (DmacDescriptor *)memalign(16, - numDescriptors * sizeof(DmacDescriptor)))) { - int dmac_id; - volatile uint32_t *data_reg; - - // THIS IS AN AFFRONT TO NATURE, but I don't know - // any "clean" way to get the sercom number from the - // SPIClass pointer (e.g. &SPI or &SPI1), which is - // all we have to work with. SPIClass does contain - // a SERCOM pointer but it is a PRIVATE member! - // Doing an UNSPEAKABLY HORRIBLE THING here, directly - // accessing the first 32-bit value in the SPIClass - // structure, knowing that's (currently) where the - // SERCOM pointer lives, but this ENTIRELY DEPENDS - // on that structure not changing nor the compiler - // rearranging things. Oh the humanity! - - if(*(SERCOM **)_spi == &sercom0) { - dmac_id = SERCOM0_DMAC_ID_TX; - data_reg = &SERCOM0->SPI.DATA.reg; -#if defined SERCOM1 - } else if(*(SERCOM **)_spi == &sercom1) { - dmac_id = SERCOM1_DMAC_ID_TX; - data_reg = &SERCOM1->SPI.DATA.reg; -#endif -#if defined SERCOM2 - } else if(*(SERCOM **)_spi == &sercom2) { - dmac_id = SERCOM2_DMAC_ID_TX; - data_reg = &SERCOM2->SPI.DATA.reg; -#endif -#if defined SERCOM3 - } else if(*(SERCOM **)_spi == &sercom3) { - dmac_id = SERCOM3_DMAC_ID_TX; - data_reg = &SERCOM3->SPI.DATA.reg; -#endif -#if defined SERCOM4 - } else if(*(SERCOM **)_spi == &sercom4) { - dmac_id = SERCOM4_DMAC_ID_TX; - data_reg = &SERCOM4->SPI.DATA.reg; -#endif -#if defined SERCOM5 - } else if(*(SERCOM **)_spi == &sercom5) { - dmac_id = SERCOM5_DMAC_ID_TX; - data_reg = &SERCOM5->SPI.DATA.reg; -#endif - } - - dma.setTrigger(dmac_id); - dma.setAction(DMA_TRIGGER_ACTON_BEAT); - - // Initialize descriptor list. - for(int d=0; d>= 1){ - if((b) & bit){ - SSPI_MOSI_HIGH(); - } else { - SSPI_MOSI_LOW(); - } - SSPI_SCK_LOW(); - SSPI_SCK_HIGH(); - } -} - - -/* - * Transaction API - * */ - -/**************************************************************************/ -/*! - @brief Begin an SPI transaction & set CS low. -*/ -/**************************************************************************/ -void inline Adafruit_SPITFT::startWrite(void){ - DMA_WAIT; // Wait for any prior SPI DMA to complete - SPI_BEGIN_TRANSACTION(); - SPI_CS_LOW(); -} - -/**************************************************************************/ -/*! - @brief Begin an SPI transaction & set CS high. -*/ -/**************************************************************************/ -void inline Adafruit_SPITFT::endWrite(void){ -#ifdef USE_SPI_DMA - // SPI DMA enabled: wait for DMA completion and end transaction ONLY if - // spitft is NULL. Otherwise, calling function can proceed and - // equivalent code in DMA callback is used. - if(!spitft) { - DMA_WAIT; // Wait for DMA operation to complete - SPI_CS_HIGH(); - SPI_END_TRANSACTION(); - } -#else - SPI_CS_HIGH(); - SPI_END_TRANSACTION(); -#endif -} - -/**************************************************************************/ -/*! - @brief Write a command byte (must have a transaction in progress) - @param cmd The 8-bit command to send -*/ -/**************************************************************************/ -void Adafruit_SPITFT::writeCommand(uint8_t cmd){ - SPI_DC_LOW(); - spiWrite(cmd); - SPI_DC_HIGH(); -} - -/**************************************************************************/ -/*! - @brief Push a 2-byte color to the framebuffer RAM, will start transaction - @param color 16-bit 5-6-5 Color to draw -*/ -/**************************************************************************/ -void Adafruit_SPITFT::pushColor(uint16_t color) { - startWrite(); - SPI_WRITE16(color); - endWrite(); -} - -/**************************************************************************/ -/*! - @brief Blit multiple 2-byte colors (must have a transaction in progress) - @param colors Array of 16-bit 5-6-5 Colors to draw - @param len How many pixels to draw - 2 bytes per pixel! -*/ -/**************************************************************************/ -void Adafruit_SPITFT::writePixels(uint16_t *colors, uint32_t len) { -#ifdef USE_SPI_DMA - int maxSpan = maxFillLen / 2; // One scanline max - uint8_t pixelBufIdx = 0; // Active pixel buffer number - while(len) { - int count = (len < maxSpan) ? len : maxSpan; - - // Because TFT and SAMD endianisms are different, must swap bytes - // from the 'colors' array passed into a DMA working buffer. This - // can take place while the prior DMA transfer is in progress, - // hence the need for two pixelBufs. - for(int i=0; i> 8) == (color & 0xFF)) { // If high & low bytes are same... - onePixelBuf = color; - // Can do this with a relatively short descriptor list, - // each transferring a max of 32,767 (not 32,768) pixels. - // This won't run off the end of the allocated descriptor list, - // since we're using much larger chunks per descriptor here. - int numDescriptors = (len + 32766) / 32767; - for(int d=0; d 32767) ? 32767 : len; - descriptor[d].SRCADDR.reg = (uint32_t)&onePixelBuf; - descriptor[d].BTCTRL.bit.SRCINC = 0; - descriptor[d].BTCNT.reg = count * 2; - descriptor[d].DESCADDR.reg = - (d < (numDescriptors - 1)) ? (uint32_t)&descriptor[d + 1] : 0; - len -= count; - } - } else { - // If high and low bytes are distinct, it's necessary to fill - // a buffer with pixel data (swapping high and low bytes because - // TFT and SAMD are different endianisms) and create a longer - // descriptor list pointing repeatedly to this data. We can do - // this slightly faster working 2 pixels (32 bits) at a time. - uint32_t *pixelPtr = (uint32_t *)pixelBuf[0], - twoPixels = __builtin_bswap16(color) * 0x00010001; - // We can avoid some or all of the buffer-filling if the color - // is the same as last time... - if(color == lastFillColor) { - // If length is longer than prior instance, fill only the - // additional pixels in the buffer and update lastFillLen. - if(len > lastFillLen) { - int fillStart = lastFillLen / 2 + 1, - fillEnd = (((maxFillLen < len) ? - maxFillLen : len) + 1) / 2; - for(int i=fillStart; i= 0){ - for (uint32_t t=0; t SPI_MAX_PIXELS_AT_ONCE)?SPI_MAX_PIXELS_AT_ONCE:len; - uint16_t tlen = 0; - - for (uint32_t t=0; tblen)?blen:len; - writePixels(temp, tlen); - len -= tlen; - } - #else - uint8_t hi = color >> 8, lo = color; - if(_sclk < 0){ //AVR Optimization - for (uint32_t t=len; t; t--){ - HSPI_WRITE(hi); - HSPI_WRITE(lo); - } - return; - } - for (uint32_t t=len; t; t--){ - spiWrite(hi); - spiWrite(lo); - } - #endif - -#endif // end non-DMA -} - -/**************************************************************************/ -/*! - @brief Write a pixel (must have a transaction in progress) - @param x x coordinate - @param y y coordinate - @param color 16-bit 5-6-5 Color to draw with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) { - if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; - DMA_WAIT; - setAddrWindow(x,y,1,1); - writePixel(color); -} - -/**************************************************************************/ -/*! - @brief Write a filled rectangle (must have a transaction in progress) - @param x Top left corner x coordinate - @param y Top left corner y coordinate - @param w Width in pixels - @param h Height in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){ - if((x >= _width) || (y >= _height)) return; - int16_t x2 = x + w - 1, y2 = y + h - 1; - if((x2 < 0) || (y2 < 0)) return; - - // Clip left/top - if(x < 0) { - x = 0; - w = x2 + 1; - } - if(y < 0) { - y = 0; - h = y2 + 1; - } - - // Clip right/bottom - if(x2 >= _width) w = _width - x; - if(y2 >= _height) h = _height - y; - - int32_t len = (int32_t)w * h; - DMA_WAIT; - setAddrWindow(x, y, w, h); - writeColor(color, len); -} - -/**************************************************************************/ -/*! - @brief Write a perfectly vertical line (must have a transaction in progress) - @param x Top-most x coordinate - @param y Top-most y coordinate - @param h Height in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void inline Adafruit_SPITFT::writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color){ - writeFillRect(x, y, 1, h, color); -} - -/**************************************************************************/ -/*! - @brief Write a perfectly horizontal line (must have a transaction in progress) - @param x Left-most x coordinate - @param y Left-most y coordinate - @param w Width in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void inline Adafruit_SPITFT::writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color){ - writeFillRect(x, y, w, 1, color); -} - -/**************************************************************************/ -/*! - @brief Draw a pixel - sets up transaction - @param x x coordinate - @param y y coordinate - @param color 16-bit 5-6-5 Color to draw with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::drawPixel(int16_t x, int16_t y, uint16_t color){ - // Clip first... - if((x >= 0) && (x < _width) && (y >= 0) && (y < _height)) { - // THEN set up transaction (if needed) and draw... - startWrite(); - setAddrWindow(x, y, 1, 1); - writePixel(color); - endWrite(); - } -} - -/**************************************************************************/ -/*! - @brief Write a perfectly vertical line - sets up transaction - @param x Top-most x coordinate - @param y Top-most y coordinate - @param h Height in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::drawFastVLine(int16_t x, int16_t y, - int16_t h, uint16_t color) { - startWrite(); - writeFastVLine(x, y, h, color); - endWrite(); -} - -/**************************************************************************/ -/*! - @brief Write a perfectly horizontal line - sets up transaction - @param x Left-most x coordinate - @param y Left-most y coordinate - @param w Width in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::drawFastHLine(int16_t x, int16_t y, - int16_t w, uint16_t color) { - startWrite(); - writeFastHLine(x, y, w, color); - endWrite(); -} - -/**************************************************************************/ -/*! - @brief Fill a rectangle completely with one color. - @param x Top left corner x coordinate - @param y Top left corner y coordinate - @param w Width in pixels - @param h Height in pixels - @param color 16-bit 5-6-5 Color to fill with -*/ -/**************************************************************************/ -void Adafruit_SPITFT::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color) { - startWrite(); - writeFillRect(x,y,w,h,color); - endWrite(); -} - - -/**************************************************************************/ -/*! - @brief Invert the display using built-in hardware command - @param i True if you want to invert, false to make 'normal' -*/ -/**************************************************************************/ -void Adafruit_SPITFT::invertDisplay(boolean i) { - startWrite(); - writeCommand(i ? invertOnCommand : invertOffCommand); - endWrite(); -} - - -/**************************************************************************/ -/*! - @brief Draw a 16-bit image (RGB 5/6/5) at the specified (x,y) position. - For 16-bit display devices; no color reduction performed. - Adapted from https://github.com/PaulStoffregen/ILI9341_t3 - by Marc MERLIN. See examples/pictureEmbed to use this. - 5/6/2017: function name and arguments have changed for compatibility - with current GFX library and to avoid naming problems in prior - implementation. Formerly drawBitmap() with arguments in different order. - - @param x Top left corner x coordinate - @param y Top left corner y coordinate - @param pcolors 16-bit array with 16-bit color bitmap - @param w Width of bitmap in pixels - @param h Height of bitmap in pixels -*/ -/**************************************************************************/ -void Adafruit_SPITFT::drawRGBBitmap(int16_t x, int16_t y, - uint16_t *pcolors, int16_t w, int16_t h) { - - int16_t x2, y2; // Lower-right coord - if(( x >= _width ) || // Off-edge right - ( y >= _height) || // " top - ((x2 = (x+w-1)) < 0 ) || // " left - ((y2 = (y+h-1)) < 0) ) return; // " bottom - - int16_t bx1=0, by1=0, // Clipped top-left within bitmap - saveW=w; // Save original bitmap width value - if(x < 0) { // Clip left - w += x; - bx1 = -x; - x = 0; - } - if(y < 0) { // Clip top - h += y; - by1 = -y; - y = 0; - } - if(x2 >= _width ) w = _width - x; // Clip right - if(y2 >= _height) h = _height - y; // Clip bottom - - pcolors += by1 * saveW + bx1; // Offset bitmap ptr to clipped top-left - startWrite(); // Includes a DMA_WAIT - setAddrWindow(x, y, w, h); // Clipped area - while(h--) { // For each (clipped) scanline... - writePixels(pcolors, w); // Push one (clipped) row - pcolors += saveW; // Advance pointer by one full (unclipped) line - } - endWrite(); -} - -#endif // !__AVR_ATtiny85__ - diff --git a/Adafruit_SPITFT.h.bak b/Adafruit_SPITFT.h.bak deleted file mode 100644 index 7a59d79..0000000 --- a/Adafruit_SPITFT.h.bak +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef _ADAFRUIT_SPITFT_ -#define _ADAFRUIT_SPITFT_ - -#if !defined(__AVR_ATtiny85__) // NOT A CHANCE of this stuff working on ATtiny - -#if ARDUINO >= 100 - #include "Arduino.h" - #include "Print.h" -#else - #include "WProgram.h" -#endif -#include -#include "Adafruit_GFX.h" - -#define USE_FAST_PINIO ///< If set, use PORT access instead of digitalWrite() -#define USE_SPI_DMA ///< If set, use SPI DMA if supported -#define DMA_PIXELS 256 - -#if !defined(ARDUINO_ARCH_SAMD) - #undef USE_SPI_DMA ///< Only for SAMD chips -#endif - -#ifdef USE_SPI_DMA - #include -#endif - -#if defined(__AVR__) - typedef volatile uint8_t RwReg; -#elif defined(ARDUINO_STM32_FEATHER) - typedef volatile uint32 RwReg; - #undef USE_FAST_PINIO - typedef class HardwareSPI SPIClass; -#elif defined(__OPENCR__) || defined (__OPENCM904__) - #undef USE_FAST_PINIO -#elif defined(ARDUINO_FEATHER52) || defined(__arm__) - typedef volatile uint32_t RwReg; -#elif defined(ESP32) || defined(ESP8266) - typedef volatile uint32_t RwReg; - #undef USE_FAST_PINIO -#else - #undef USE_FAST_PINIO -#endif - -#include "Adafruit_SPITFT_Macros.h" - -/// A heavily optimized SPI display subclass of GFX. Manages SPI bitbanging, transactions, DMA, etc! Despite being called SPITFT, the classic SPI data/command interface is also used by OLEDs. -class Adafruit_SPITFT : public Adafruit_GFX { - - public: - Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK, int8_t _RST = -1, int8_t _MISO = -1); - Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t _CS, int8_t _DC, int8_t _RST = -1); - Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass, int8_t _CS, int8_t _DC, int8_t _RST = -1); - virtual void begin(uint32_t freq) = 0; ///< Virtual begin() function to set SPI frequency, must be overridden in subclass. @param freq Maximum SPI hardware clock speed - - void initSPI(uint32_t freq); - - // Required Non-Transaction - void drawPixel(int16_t x, int16_t y, uint16_t color); - - // Transaction API - void startWrite(void); - void endWrite(void); - - void writePixel(int16_t x, int16_t y, uint16_t color); - void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); - void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); - void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - - // Transaction API not used by GFX - - /*! - @brief SPI displays set an address window rectangle for blitting pixels - @param x Top left corner x coordinate - @param y Top left corner x coordinate - @param w Width of window - @param h Height of window - */ - virtual void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) = 0; - - /*! - @brief Write a 2-byte color (must have a transaction in progress) - @param color 16-bit 5-6-5 Color to draw - */ - void inline writePixel(uint16_t color) { SPI_WRITE16(color); } - void writePixels(uint16_t * colors, uint32_t len); - void writeColor(uint16_t color, uint32_t len); - void pushColor(uint16_t color); - - // Recommended Non-Transaction - void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); - void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); - - using Adafruit_GFX::drawRGBBitmap; // Check base class first - void drawRGBBitmap(int16_t x, int16_t y, - uint16_t *pcolors, int16_t w, int16_t h); - void invertDisplay(boolean i); - - uint16_t color565(uint8_t r, uint8_t g, uint8_t b); - void writeCommand(uint8_t cmd); - void spiWrite(uint8_t v); - uint8_t spiRead(void); -#ifdef USE_SPI_DMA - boolean DMA_busy(void); -#endif - - protected: - SPIClass *_spi; ///< The SPI device we want to use (set in constructor) - uint32_t _freq; ///< SPI clock frequency (for hardware SPI) -#if defined (__AVR__) || defined(TEENSYDUINO) || defined (ESP8266) || defined (ESP32) - int8_t _cs, _dc, _rst, _sclk, _mosi, _miso; -#else - int32_t _cs, ///< Arduino pin # for chip-select pin - _dc, ///< Arduino pin # for data-command pin - _rst, ///< Arduino pin # for reset pin - _sclk, ///< Arduino pin # for SPI clock pin - _mosi, ///< Arduino pin # for SPI MOSI pin - _miso; ///< Arduino pin # for SPI MISO pin -#endif - -#ifdef USE_FAST_PINIO - volatile RwReg *mosiport, ///< Direct chip register for toggling MOSI with fast bitbang IO - *misoport, ///< Direct chip register for toggling MISO with fast bitbang IO - *clkport, ///< Direct chip register for toggling CLK with fast bitbang IO - *dcport, ///< Direct chip register for toggling DC with fast bitbang IO - *csport; ///< Direct chip register for toggling CS with fast bitbang IO - RwReg mosipinmask, ///< bitmask for turning on/off MOSI with fast register bitbang IO - misopinmask, ///< bitmask for turning on/off MISO with fast register bitbang IO - clkpinmask, ///< bitmask for turning on/off CLK with fast register bitbang IO - cspinmask, ///< bitmask for turning on/off CS with fast register bitbang IO - dcpinmask; ///< bitmask for turning on/off DC with fast register bitbang IO -#endif - - uint8_t invertOnCommand = 0, ///< SPI command byte to turn on invert - invertOffCommand = 0; ///< SPI command byte to turn off invert - int16_t _xstart = 0; ///< Many displays don't have pixels starting at (0,0) of the internal framebuffer, this is the x offset from 0 to align - int16_t _ystart = 0; ///< Many displays don't have pixels starting at (0,0) of the internal framebuffer, this is the y offset from 0 to align - -#ifdef USE_SPI_DMA - Adafruit_ZeroDMA dma; ///< DMA instance - DmacDescriptor *dptr = NULL; ///< 1st descriptor - DmacDescriptor *descriptor = NULL; ///< Allocated descriptor list -// uint16_t *pixelBuf[2]; ///< Working buffers - uint16_t pixelBuf[2][DMA_PIXELS]; ///< Working buffers - uint8_t pixelBufIdx = 0; ///< Active buffer # - uint16_t lastFillColor = 0; ///< Last color used in fill func - uint32_t lastFillLen = 0; ///< # of pixels w/lastFillColor -#endif -}; - -#endif // !__AVR_ATtiny85__ - -#endif // !_ADAFRUIT_SPITFT_ diff --git a/Adafruit_SPITFT.h.bak2 b/Adafruit_SPITFT.h.bak2 deleted file mode 100644 index fe928c1..0000000 --- a/Adafruit_SPITFT.h.bak2 +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef _ADAFRUIT_SPITFT_ -#define _ADAFRUIT_SPITFT_ - -#if !defined(__AVR_ATtiny85__) // NOT A CHANCE of this stuff working on ATtiny - -#if ARDUINO >= 100 - #include "Arduino.h" - #include "Print.h" -#else - #include "WProgram.h" -#endif -#include -#include "Adafruit_GFX.h" - -#define USE_FAST_PINIO ///< If set, use PORT access instead of digitalWrite() -#define USE_SPI_DMA ///< If set, use SPI DMA if available -// If DMA is enabled, Arduino sketch MUST #include -// Sketches MUST poll tft.DMA_busy() before doing other things that work -// on the SPI bus (e.g. accessing SD card). -// Estimated RAM usage: -// 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 ///< Only for SAMD chips -#endif - -#ifdef USE_SPI_DMA - #include -#endif - -#if defined(__AVR__) - typedef volatile uint8_t RwReg; -#elif defined(ARDUINO_STM32_FEATHER) - typedef volatile uint32 RwReg; - #undef USE_FAST_PINIO - typedef class HardwareSPI SPIClass; -#elif defined(__OPENCR__) || defined (__OPENCM904__) - #undef USE_FAST_PINIO -#elif defined(ARDUINO_FEATHER52) || defined(__arm__) - typedef volatile uint32_t RwReg; -#elif defined(ESP32) || defined(ESP8266) - typedef volatile uint32_t RwReg; - #undef USE_FAST_PINIO -#else - #undef USE_FAST_PINIO -#endif - -#include "Adafruit_SPITFT_Macros.h" - -/// A heavily optimized SPI display subclass of GFX. Manages SPI bitbanging, transactions, DMA, etc! Despite being called SPITFT, the classic SPI data/command interface is also used by OLEDs. -class Adafruit_SPITFT : public Adafruit_GFX { - - public: - Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK, int8_t _RST = -1, int8_t _MISO = -1); - Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t _CS, int8_t _DC, int8_t _RST = -1); - Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass, int8_t _CS, int8_t _DC, int8_t _RST = -1); - virtual void begin(uint32_t freq) = 0; ///< Virtual begin() function to set SPI frequency, must be overridden in subclass. @param freq Maximum SPI hardware clock speed - - void initSPI(uint32_t freq); - - // Required Non-Transaction - void drawPixel(int16_t x, int16_t y, uint16_t color); - - // Transaction API - void startWrite(void); - void endWrite(void); - - void writePixel(int16_t x, int16_t y, uint16_t color); - void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); - void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); - void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - - // Transaction API not used by GFX - - /*! - @brief SPI displays set an address window rectangle for blitting pixels - @param x Top left corner x coordinate - @param y Top left corner x coordinate - @param w Width of window - @param h Height of window - */ - virtual void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) = 0; - - /*! - @brief Write a 2-byte color (must have a transaction in progress) - @param color 16-bit 5-6-5 Color to draw - */ - void inline writePixel(uint16_t color) { SPI_WRITE16(color); } - void writePixels(uint16_t * colors, uint32_t len); - void writeColor(uint16_t color, uint32_t len); - void pushColor(uint16_t color); - - // Recommended Non-Transaction - void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); - void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); - - using Adafruit_GFX::drawRGBBitmap; // Check base class first - void drawRGBBitmap(int16_t x, int16_t y, - uint16_t *pcolors, int16_t w, int16_t h); - void invertDisplay(boolean i); - - uint16_t color565(uint8_t r, uint8_t g, uint8_t b); - void writeCommand(uint8_t cmd); - void spiWrite(uint8_t v); - uint8_t spiRead(void); -#ifdef USE_SPI_DMA - boolean DMA_busy(void); -#endif - - protected: - SPIClass *_spi; ///< The SPI device we want to use (set in constructor) - uint32_t _freq; ///< SPI clock frequency (for hardware SPI) -#if defined (__AVR__) || defined(TEENSYDUINO) || defined (ESP8266) || defined (ESP32) - int8_t _cs, _dc, _rst, _sclk, _mosi, _miso; -#else - int32_t _cs, ///< Arduino pin # for chip-select pin - _dc, ///< Arduino pin # for data-command pin - _rst, ///< Arduino pin # for reset pin - _sclk, ///< Arduino pin # for SPI clock pin - _mosi, ///< Arduino pin # for SPI MOSI pin - _miso; ///< Arduino pin # for SPI MISO pin -#endif - -#ifdef USE_FAST_PINIO - volatile RwReg *mosiport, ///< Direct chip register for toggling MOSI with fast bitbang IO - *misoport, ///< Direct chip register for toggling MISO with fast bitbang IO - *clkport, ///< Direct chip register for toggling CLK with fast bitbang IO - *dcport, ///< Direct chip register for toggling DC with fast bitbang IO - *csport; ///< Direct chip register for toggling CS with fast bitbang IO - RwReg mosipinmask, ///< bitmask for turning on/off MOSI with fast register bitbang IO - misopinmask, ///< bitmask for turning on/off MISO with fast register bitbang IO - clkpinmask, ///< bitmask for turning on/off CLK with fast register bitbang IO - cspinmask, ///< bitmask for turning on/off CS with fast register bitbang IO - dcpinmask; ///< bitmask for turning on/off DC with fast register bitbang IO -#endif - - uint8_t invertOnCommand = 0, ///< SPI command byte to turn on invert - invertOffCommand = 0; ///< SPI command byte to turn off invert - int16_t _xstart = 0; ///< Many displays don't have pixels starting at (0,0) of the internal framebuffer, this is the x offset from 0 to align - int16_t _ystart = 0; ///< Many displays don't have pixels starting at (0,0) of the internal framebuffer, this is the y offset from 0 to align - -#ifdef USE_SPI_DMA - Adafruit_ZeroDMA dma; ///< DMA instance - DmacDescriptor *dptr = NULL; ///< 1st descriptor - DmacDescriptor *descriptor = NULL; ///< Allocated descriptor list - uint16_t *pixelBuf[2]; ///< Working buffers - uint16_t maxFillLen; ///< Max pixels per DMA xfer - uint16_t lastFillColor = 0; ///< Last color used w/fill - uint32_t lastFillLen = 0; ///< # of pixels w/last fill - uint8_t onePixelBuf; ///< For hi==lo fill -#endif -}; - -#endif // !__AVR_ATtiny85__ - -#endif // !_ADAFRUIT_SPITFT_ diff --git a/benchmark b/benchmark deleted file mode 100644 index daa3682..0000000 --- a/benchmark +++ /dev/null @@ -1,28 +0,0 @@ -BENCHMARK TIME (MICROSECONDS) - NO DMA W/DMA SPEEDUP -Screen fill 1423496 513050 2.7X -Text 95811 97996 1X -Lines 844297 845960 1X -Horiz/Vert Lines 118764 47679 2.5X -Rectangles (outline) 75930 33124 2.3X -Rectangles (filled) 2955105 1087729 2.7X -Circles (filled) 374061 301426 1.2X -Circles (outline) 368583 367738 1X -Triangles (outline) 190206 183978 1X -Triangles (filled) 1004699 477874 2.1X -Rounded rects (outline) 164752 543676 0.3X WTF? -Rounded rects (filled) 2950025 1895088 1.6X - -M4: -Screen fill 771834 512267 1.5X -Text 44791 43447 1X -Lines 410014 409999 1X -Horiz/Vert Lines 63649 43144 1.5X -Rectangles (outline) 40636 27330 1.5X -Rectangles (filled) 1601076 1064273 1.5X -Circles (filled) 192210 157732 1.2X -Circles (outline) 179822 179750 1X -Triangles (outline) 93047 91328 1X -Triangles (filled) 528396 373338 1.4X -Rounded rects (outline) 82508 73489 1.1X -Rounded rects (filled) 1595105 1060465 1.5X