Phillip Burgess преди 6 години
родител
ревизия
6b5e177fb1
променени са 6 файла, в които са добавени 1339 реда и са изтрити 1292 реда
  1. 833 439
      Adafruit_SPITFT.cpp
  2. 441 130
      Adafruit_SPITFT.h
  3. 5 115
      Adafruit_SPITFT_Macros.h
  4. 0 608
      Adafruit_TFT8.cpp
  5. 0 0
      olde/Adafruit_TFT8.h
  6. 60 0
      olde/ttt.ttt

Файловите разлики са ограничени, защото са твърде много
+ 833 - 439
Adafruit_SPITFT.cpp


+ 441 - 130
Adafruit_SPITFT.h

@@ -1,154 +1,465 @@
-#ifndef _ADAFRUIT_SPITFT_
-#define _ADAFRUIT_SPITFT_
+/*!
+ * @file Adafruit_SPITFT.h
+ *
+ * Part of Adafruit's GFX graphics library. Originally this class was
+ * written to handle a range of color TFT displays connected via SPI,
+ * but over time this library and some display-specific subclasses have
+ * mutated to include some color OLEDs as well as parallel-interfaced
+ * displays. The name's been kept for the sake of older code.
+ *
+ * Adafruit invests time and resources providing this open source code,
+ * please support Adafruit and open-source hardware by purchasing
+ * products from Adafruit!
+ *
+ * @section author Author
+ *
+ * Written by Limor "ladyada" Fried for Adafruit Industries,
+ * with contributions from the open source community.
+ *
+ * @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
+#ifndef _ADAFRUIT_SPITFT_H_
+#define _ADAFRUIT_SPITFT_H_
+
+#if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all
 
-#if ARDUINO >= 100
- #include "Arduino.h"
- #include "Print.h"
-#else
- #include "WProgram.h"
-#endif
 #include <SPI.h>
 #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
+// HARDWARE CONFIG ---------------------------------------------------------
+
+#if defined(__AVR__)
+ typedef uint8_t  PORT_t;            ///< PORT values are 8-bit
+ #define USE_FAST_PINIO              ///< Use direct PORT register access
+#elif defined(__arm__)
+ #if defined(SAM)
+  // Arduino Due
+  typedef uint32_t PORT_t;           ///< PORT values are 32-bit
+  // USE_FAST_PINIO not available here (yet)...Due has a totally different
+  // GPIO register set and will require some changes elsewhere (e.g. in
+  // constructors especially).
+ #elif defined(CORE_TEENSY)
+  // PJRC Teensy 3.x
+  typedef uint8_t PORT_t;            ///< PORT values are 8-bit
+  #define USE_FAST_PINIO             ///< Use direct PORT register access
+  #define HAS_PORT_SET_CLR           ///< PORTs have set & clear registers
+ #else
+  // Adafruit M0, M4
+  typedef uint32_t PORT_t;           ///< PORT values are 32-bit
+  #define USE_FAST_PINIO             ///< Use direct PORT register access
+  #define HAS_PORT_SET_CLR           ///< PORTs have set & clear registers
+ #endif
+#else // !ARM
+ // Probably ESP8266 or ESP32. USE_FAST_PINIO is not available here (yet)
+ // but don't worry about it too much...the digitalWrite() implementation
+ // on these platforms is reasonably efficient and already RAM-resident,
+ // only gotcha then is no parallel connection support for now.
+ typedef uint32_t PORT_t;            ///< PORT values are 32-bit
+#endif // end !ARM
+typedef volatile  PORT_t* PORTreg_t; ///< PORT register type
+
+#if defined(__AVR__)
+ #define DEFAULT_SPI_FREQ  8000000L  ///< Hardware SPI default speed
+#else
+ #define DEFAULT_SPI_FREQ 16000000L  ///< Hardware SPI default speed
+#endif
+
+//#define USE_SPI_DMA                ///< If set, use SPI DMA if available
+// Another "oops" name -- in the future parallel DMA will also be handled.
 // If DMA is enabled, Arduino sketch MUST #include <Adafruit_ZeroDMA.h>
 // 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
+ #undef USE_SPI_DMA                  ///< DMA currently for SAMD chips only
 #endif
 
-#ifdef USE_SPI_DMA
- #pragma message ("SPI DMA IS ENABLED. HIGHLY EXPERIMENTAL.")
+#if defined(USE_SPI_DMA)
+ #pragma message ("GFX DMA IS ENABLED. HIGHLY EXPERIMENTAL.")
  #include <Adafruit_ZeroDMA.h>
 #endif
 
-#if defined(__AVR__)
-  typedef volatile uint8_t RwReg;
-#elif defined(ARDUINO_STM32_FEATHER)
-  typedef volatile uint32_t 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"
+// CLASS DEFINITION --------------------------------------------------------
 
-/// 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.
+/*!
+  @brief  Adafruit_SPITFT is an intermediary class between Adafruit_GFX
+          and various hardware-specific subclasses for different displays.
+          It handles certain operations that are common to a range of
+          displays (address window, area fills, etc.). Originally these were
+          all color TFT displays interfaced via SPI, but it's since expanded
+          to include color OLEDs and parallel-interfaced TFTs. THE NAME HAS
+          BEEN KEPT TO AVOID BREAKING A LOT OF SUBCLASSES AND EXAMPLE CODE.
+          Many of the class member functions similarly live on with names
+          that don't necessarily accurately describe what they're doing,
+          again to avoid breaking a lot of other code. If in doubt, read
+          the comments.
+*/
 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);
-
-    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
+  public:
 
-#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
+    // CONSTRUCTORS --------------------------------------------------------
+
+    // Software SPI constructor: expects width & height (at default rotation
+    // setting 0), 4 signal pins (cs, dc, mosi, sclk), 2 optional pins
+    // (reset, miso). cs argument is required but can be -1 if unused --
+    // rather than moving it to the optional arguments, it was done this way
+    // to avoid breaking existing code (-1 option was a later addition).
+    Adafruit_SPITFT(uint16_t w, uint16_t h,
+      int8_t cs, int8_t dc, int8_t mosi, int8_t sck,
+      int8_t rst = -1, int8_t miso = -1);
+
+    // Hardware SPI constructor using the default SPI port: expects width &
+    // height (at default rotation setting 0), 2 signal pins (cs, dc),
+    // optional reset pin. cs is required but can be -1 if unused -- rather
+    // than moving it to the optional arguments, it was done this way to
+    // avoid breaking existing code (-1 option was a later addition).
+    Adafruit_SPITFT(uint16_t w, uint16_t h,
+      int8_t cs, int8_t dc, int8_t rst = -1);
+
+    // Hardware SPI constructor using an arbitrary SPI peripheral: expects
+    // width & height (rotation 0), SPIClass pointer, 2 signal pins (cs, dc)
+    // and optional reset pin. cs is required but can be -1 if unused.
+    Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass,
+      int8_t cs, int8_t dc, int8_t rst = -1);
+
+    // Parallel constructor: expects width & height (rotation 0), flag
+    // indicating whether 16-bit (true) or 8-bit (false) interface, 3 signal
+    // pins (d0, wr, dc), 3 optional pins (cs, rst, rd). 16-bit parallel
+    // isn't even fully implemented but the 'wide' flag was added as a
+    // required argument to avoid ambiguity with other constructors.
+    Adafruit_SPITFT(uint16_t w, uint16_t h, bool wide,
+      int8_t d0, int8_t wr, int8_t dc,
+      int8_t cs = -1, int8_t rst = -1, int8_t rd = -1);
+
+    // CLASS MEMBER FUNCTIONS ----------------------------------------------
+
+    // These first two functions MUST be declared by subclasses:
 
-	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
+    /*!
+        @brief  Display-specific initialization function.
+        @param  freq  SPI frequency, in hz (or 0 for default or unused).
+    */
+    virtual void begin(uint32_t freq) = 0;
+
+    /*!
+        @brief  Set up the specific display hardware's "address window"
+                for subsequent pixel-pushing operations.
+        @param  x  Leftmost pixel of area to be drawn (MUST be within
+                   display bounds at current rotation setting).
+        @param  y  Topmost pixel of area to be drawn (MUST be within
+                   display bounds at current rotation setting).
+        @param  w  Width of area to be drawn, in pixels (MUST be >0 and,
+                   added to x, within display bounds at current rotation).
+        @param  h  Height of area to be drawn, in pixels (MUST be >0 and,
+                   added to x, within display bounds at current rotation).
+    */
+    virtual void setAddrWindow(
+                   uint16_t x, uint16_t y, uint16_t w, uint16_t h) = 0;
+
+    // Remaining functions do not need to be declared in subclasses
+    // unless they wish to provide hardware-specific optimizations.
+    // Brief comments here...documented more thoroughly in .cpp file.
+
+    // Subclass' begin() function invokes this to initialize hardware.
+    // Name is outdated (interface may be parallel) but for compatibility:
+    void         initSPI(uint32_t freq = 0); // 0 = use default SPI speed
+    // Chip select and/or hardware SPI transaction start as needed:
+    void         startWrite(void);
+    // Chip deselect and/or hardware SPI transaction end as needed:
+    void         endWrite(void);
+
+    // These functions require a chip-select and/or SPI transaction
+    // around them. Higher-level graphics primitives might start a
+    // single transaction and then make multiple calls to these functions
+    // (e.g. circle or text rendering might make repeated lines or rects)
+    // before ending the transaction. It's more efficient than starting a
+    // transaction every time.
+    void         writePixel(int16_t x, int16_t y, uint16_t color);
+    void         writePixels(uint16_t *colors, uint32_t len);
+    void         writeColor(uint16_t color, uint32_t len);
+    void         writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h,
+                   uint16_t color);
+    void         writeFastHLine(int16_t x, int16_t y, int16_t w,
+                   uint16_t color);
+    void         writeFastVLine(int16_t x, int16_t y, int16_t h,
+                   uint16_t color);
+    // This is a new function, similar to writeFillRect() except that
+    // all arguments MUST be onscreen, sorted and clipped. If higher-level
+    // primitives can handle their own sorting/clipping, it avoids repeating
+    // such operations in the low-level code, making it potentially faster.
+    // CALLING THIS WITH UNCLIPPED OR NEGATIVE VALUES COULD BE DISASTROUS.
+    inline void  writeFillRectPreclipped(int16_t x, int16_t y,
+                   int16_t w, int16_t h, uint16_t color);
+    // This variant of writePixel() just calls SPI_WRITE16()...new code
+    // should probably just do the latter, consider this deprecated:
+    inline void  writePixel(uint16_t color);
+
+    // These functions are similar to the 'write' functions above, but with
+    // a chip-select and/or SPI transaction built-in. They're typically used
+    // solo -- that is, as graphics primitives in themselves, not invoked by
+    // higher-level primitives (which should use the functions above).
+    void         drawPixel(int16_t x, int16_t y, uint16_t color);
+    void         fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
+                   uint16_t color);
+    void         drawFastHLine(int16_t x, int16_t y, int16_t w,
+                   uint16_t color);
+    void         drawFastVLine(int16_t x, int16_t y, int16_t h,
+                   uint16_t color);
+    // A single-pixel push encapsulated in a transaction. I don't think
+    // this is used anymore (BMP demos might've used it?) but is provided
+    // for backward compatibility, consider it deprecated:
+    void         pushColor(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(bool i);
+    uint16_t     color565(uint8_t r, uint8_t g, uint8_t b);
+
+    // Despite parallel additions, function names kept for compatibility:
+    void         spiWrite(uint8_t b);       // Write single byte as DATA
+    void         writeCommand(uint8_t cmd); // Write single byte as COMMAND
+    uint8_t      spiRead(void);             // Read single byte of data
+
+    // Most of these low-level functions were formerly macros in
+    // Adafruit_SPITFT_Macros.h. Some have been made into inline functions
+    // to avoid macro mishaps. Despite the addition of code for a parallel
+    // display interface, the names have been kept for backward
+    // compatibility (some subclasses may be invoking these):
+    void         SPI_WRITE16(uint16_t w); // Not inline
+    void         SPI_WRITE32(uint32_t l); // Not inline
+    void         SPI_WRITE_PIXELS(uint16_t *data, uint32_t bytes); // ditto
+    // Old code had both a spiWrite16() function and SPI_WRITE16 macro
+    // in addition to the SPI_WRITE32 macro. The latter two have been
+    // made into functions here, and spiWrite16() removed (use SPI_WRITE16()
+    // instead). It looks like most subclasses had gotten comfortable with
+    // SPI_WRITE16 and SPI_WRITE32 anyway so those names were kept rather
+    // than the less-obnoxious camelcase variants, oh well.
+
+    // Placing these functions entirely in the class definition inlines
+    // them implicitly them while allowing their use in other code:
+
+    /*!
+        @brief  Set the chip-select line HIGH. Does NOT check whether CS pin
+                is set (>=0), that should be handled in calling function.
+                Despite function name, this is used even if the display
+                connection is parallel.
+    */
+    void SPI_CS_HIGH(void) {
+    #if defined(USE_FAST_PINIO)
+     #if defined(HAS_PORT_SET_CLR)
+        *csPortSet = csPinMask;
+     #else  // !HAS_PORT_SET_CLR
+        *csPort   |= csPinMaskSet;
+     #endif // end !HAS_PORT_SET_CLR
+    #else  // !USE_FAST_PINIO
+        digitalWrite(_cs, HIGH);
+    #endif // end !USE_FAST_PINIO
+    }
+
+    /*!
+        @brief  Set the chip-select line LOW. Does NOT check whether CS pin
+                is set (>=0), that should be handled in calling function.
+                Despite function name, this is used even if the display
+                connection is parallel.
+    */
+    void SPI_CS_LOW(void) {
+    #if defined(USE_FAST_PINIO)
+     #if defined(HAS_PORT_SET_CLR)
+        *csPortClr = csPinMask;
+     #else  // !HAS_PORT_SET_CLR
+        *csPort   &= csPinMaskClr;
+     #endif // end !HAS_PORT_SET_CLR
+    #else  // !USE_FAST_PINIO
+        digitalWrite(_cs, LOW);
+    #endif // end !USE_FAST_PINIO
+    }
+
+    /*!
+        @brief  Set the data/command line HIGH (data mode).
+    */
+    void SPI_DC_HIGH(void) {
+    #if defined(USE_FAST_PINIO)
+     #if defined(HAS_PORT_SET_CLR)
+      #if defined(KINETISK)
+        *dcPortSet = 1;
+      #else  // !KINETISK
+        *dcPortSet = dcPinMask;
+      #endif // end !KINETISK
+     #else  // !HAS_PORT_SET_CLR
+        *dcPort   |= dcPinMaskSet;
+     #endif // end !HAS_PORT_SET_CLR
+    #else  // !USE_FAST_PINIO
+        digitalWrite(_dc, HIGH);
+    #endif // end !USE_FAST_PINIO
+    }
+
+    /*!
+        @brief  Set the data/command line LOW (command mode).
+    */
+    void SPI_DC_LOW(void) {
+    #if defined(USE_FAST_PINIO)
+     #if defined(HAS_PORT_SET_CLR)
+      #if defined(KINETISK)
+        *dcPortClr = 1;
+      #else  // !KINETISK
+        *dcPortClr = dcPinMask;
+      #endif // end !KINETISK
+     #else  // !HAS_PORT_SET_CLR
+        *dcPort   &= dcPinMaskClr;
+     #endif // end !HAS_PORT_SET_CLR
+    #else  // !USE_FAST_PINIO
+        digitalWrite(_dc, LOW);
+    #endif // end !USE_FAST_PINIO
+    }
+
+  protected:
+
+    // A few more low-level member functions -- some may have previously
+    // been macros. Shouldn't have a need to access these externally, so
+    // they've been moved to the protected section. Additionally, they're
+    // declared inline here and the code is in the .cpp file, since outside
+    // code doesn't need to see these.
+    inline void  SPI_MOSI_HIGH(void);
+    inline void  SPI_MOSI_LOW(void);
+    inline void  SPI_SCK_HIGH(void);
+    inline void  SPI_SCK_LOW(void);
+    inline bool  SPI_MISO_READ(void);
+    inline void  SPI_BEGIN_TRANSACTION(void);
+    inline void  SPI_END_TRANSACTION(void);
+    inline void  TFT_WR_STROBE(void); // Parallel interface write strobe
+    inline void  TFT_RD_HIGH(void);   // Parallel interface read high
+    inline void  TFT_RD_LOW(void);    // Parallel interface read low
+
+    // CLASS INSTANCE VARIABLES --------------------------------------------
+
+    // Here be dragons! There's a big union of three structures here --
+    // one each for hardware SPI, software (bitbang) SPI, and parallel
+    // interfaces. This is to save some memory, since a display's connection
+    // will be only one of these. The order of some things is a little weird
+    // in an attempt to get values to align and pack better in RAM.
+
+#if defined(USE_FAST_PINIO)
+#if defined(HAS_PORT_SET_CLR)
+    PORTreg_t     csPortSet;       ///< PORT register for chip select SET
+    PORTreg_t     csPortClr;       ///< PORT register for chip select CLEAR
+    PORTreg_t     dcPortSet;       ///< PORT register for data/command SET
+    PORTreg_t     dcPortClr;       ///< PORT register for data/command CLEAR
+#else  // !HAS_PORT_SET_CLR
+    PORTreg_t     csPort;          ///< PORT register for chip select
+    PORTreg_t     dcPort;          ///< PORT register for data/command
+#endif // end HAS_PORT_SET_CLR
+#endif // end USE_FAST_PINIO
+    union {
+      struct {                     //   Values specific to HARDWARE SPI:
+        SPIClass   *_spi;          ///< SPI class pointer
+        uint32_t    _freq;
+        SPISettings settings;
+      } hwspi;
+      struct {                     //   Values specific to SOFTWARE SPI:
+#if defined(USE_FAST_PINIO)
+        PORTreg_t misoPort;        ///< PORT (PIN) register for MISO
+#if defined(HAS_PORT_SET_CLR)
+        PORTreg_t mosiPortSet;     ///< PORT register for MOSI SET
+        PORTreg_t mosiPortClr;     ///< PORT register for MOSI CLEAR
+        PORTreg_t sckPortSet;      ///< PORT register for SCK SET
+        PORTreg_t sckPortClr;      ///< PORT register for SCK CLEAR
+ #if !defined(KINETISK)
+        PORT_t    mosiPinMask;     ///< Bitmask for MOSI
+        PORT_t    sckPinMask;      ///< Bitmask for SCK
+ #endif // end !KINETISK
+#else  // !HAS_PORT_SET_CLR
+        PORTreg_t mosiPort;        ///< PORT register for MOSI
+        PORTreg_t sckPort;         ///< PORT register for SCK
+        PORT_t    mosiPinMaskSet;  ///< Bitmask for MOSI SET (OR)
+        PORT_t    mosiPinMaskClr;  ///< Bitmask for MOSI CLEAR (AND)
+        PORT_t    sckPinMaskSet;   ///< Bitmask for SCK SET (OR bitmask)
+        PORT_t    sckPinMaskClr;   ///< Bitmask for SCK CLEAR (AND)
+#endif // end HAS_PORT_SET_CLR
+ #if !defined(KINETISK)
+        PORT_t    misoPinMask;     ///< Bitmask for MISO
+ #endif // end !KINETISK
+#endif // end USE_FAST_PINIO
+        int8_t    _mosi;           ///< MOSI pin #
+        int8_t    _miso;           ///< MISO pin #
+        int8_t    _sck;            ///< SCK pin #
+      } swspi;
+      struct {                     //   Values specific to 8-bit parallel:
+#if defined(USE_FAST_PINIO)
+        volatile uint8_t *writePort; ///< PORT register for DATA WRITE
+        volatile uint8_t *readPort;  ///< PORT (PIN) register for DATA READ
+#if defined(HAS_PORT_SET_CLR)
+        // Port direction register pointers are always 8-bit regardless of
+        // PORTreg_t -- even if 32-bit port, we modify a byte-aligned 8 bits.
+        volatile uint8_t *dirSet;  ///< PORT byte data direction SET
+        volatile uint8_t *dirClr;  ///< PORT byte data direction CLEAR
+        PORTreg_t wrPortSet;       ///< PORT register for write strobe SET
+        PORTreg_t wrPortClr;       ///< PORT register for write strobe CLEAR
+        PORTreg_t rdPortSet;       ///< PORT register for read strobe SET
+        PORTreg_t rdPortClr;       ///< PORT register for read strobe CLEAR
+ #if !defined(KINETISK)
+        PORT_t    wrPinMask;       ///< Bitmask for write strobe
+ #endif // end !KINETISK
+        PORT_t    rdPinMask;       ///< Bitmask for read strobe
+#else  // !HAS_PORT_SET_CLR
+        // Port direction register pointer is always 8-bit regardless of
+        // PORTreg_t -- even if 32-bit port, we modify a byte-aligned 8 bits.
+        volatile uint8_t *portDir; ///< PORT direction register
+        PORTreg_t wrPort;          ///< PORT register for write strobe
+        PORTreg_t rdPort;          ///< PORT register for read strobe
+        PORT_t    wrPinMaskSet;    ///< Bitmask for write strobe SET (OR)
+        PORT_t    wrPinMaskClr;    ///< Bitmask for write strobe CLEAR (AND)
+        PORT_t    rdPinMaskSet;    ///< Bitmask for read strobe SET (OR)
+        PORT_t    rdPinMaskClr;    ///< Bitmask for read strobe CLEAR (AND)
+#endif // end HAS_PORT_SET_CLR
+#endif // end USE_FAST_PINIO
+        int8_t    _d0;             ///< Data pin 0 #
+        int8_t    _wr;             ///< Write strobe pin #
+        int8_t    _rd;             ///< Read strobe pin # (or -1)
+        bool      wide = 0;        ///< If true, is 16-bit interface
+      } tft8;
+    };
+#if defined(USE_SPI_DMA) // Used by hardware SPI and tft8
+    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
-};
+#if defined(USE_FAST_PINIO)
+#if defined(HAS_PORT_SET_CLR)
+    PORT_t        csPinMask;       ///< Bitmask for chip select
+ #if !defined(KINETISK)
+    PORT_t        dcPinMask;       ///< Bitmask for data/command
+ #endif // end !KINETISK
+#else  // !HAS_PORT_SET_CLR
+    PORT_t        csPinMaskSet;    ///< Bitmask for chip select SET (OR)
+    PORT_t        csPinMaskClr;    ///< Bitmask for chip select CLEAR (AND)
+    PORT_t        dcPinMaskSet;    ///< Bitmask for data/command SET (OR)
+    PORT_t        dcPinMaskClr;    ///< Bitmask for data/command CLEAR (AND)
+#endif // end HAS_PORT_SET_CLR
+#endif // end USE_FAST_PINIO
+    uint8_t       connection;      ///< TFT_HARD_SPI, TFT_SOFT_SPI, etc.
+    int8_t        _rst;            ///< Reset pin # (or -1)
+    int8_t        _cs;             ///< Chip select pin # (or -1)
+    int8_t        _dc;             ///< Data/command pin #
 
-#endif // !__AVR_ATtiny85__
+    int16_t       _xstart   = 0;   ///< Internal framebuffer X offset
+    int16_t       _ystart   = 0;   ///< Internal framebuffer Y offset
+    uint8_t       invertOnCommand  = 0; ///< Command to enable invert mode
+    uint8_t       invertOffCommand = 0; ///< Command to disable invert mode
+
+    uint32_t      _freq = 0;       ///< Dummy var to keep subclasses happy
+};
 
-#endif // !_ADAFRUIT_SPITFT_
+#endif // end __AVR_ATtiny85__
+#endif // end _ADAFRUIT_SPITFT_H_

+ 5 - 115
Adafruit_SPITFT_Macros.h

@@ -1,116 +1,6 @@
-#ifndef _ADAFRUIT_SPITFT_MACROS
-#define _ADAFRUIT_SPITFT_MACROS
+// THIS FILE INTENTIONALLY LEFT BLANK.
 
-/*
- * Control Pins
- * */
-
-#ifdef USE_FAST_PINIO
-#define SPI_DC_HIGH()           *dcport |=  dcpinmask
-#define SPI_DC_LOW()            *dcport &= ~dcpinmask
-#define SPI_CS_HIGH()           *csport |=  cspinmask
-#define SPI_CS_LOW()            *csport &= ~cspinmask
-#else
-#define SPI_DC_HIGH()           digitalWrite(_dc, HIGH)
-#define SPI_DC_LOW()            digitalWrite(_dc, LOW)
-#define SPI_CS_HIGH()           { if(_cs >= 0) digitalWrite(_cs, HIGH); }
-#define SPI_CS_LOW()            { if(_cs >= 0) digitalWrite(_cs, LOW);  }
-#endif
-
-/*
- * Software SPI Macros
- * */
-
-#ifdef USE_FAST_PINIO
-#define SSPI_MOSI_HIGH()        *mosiport |=  mosipinmask
-#define SSPI_MOSI_LOW()         *mosiport &= ~mosipinmask
-#define SSPI_SCK_HIGH()         *clkport  |=  clkpinmask
-#define SSPI_SCK_LOW()          *clkport  &= ~clkpinmask
-#define SSPI_MISO_READ()        ((*misoport & misopinmask) != 0)
-#else
-#define SSPI_MOSI_HIGH()        digitalWrite(_mosi, HIGH)
-#define SSPI_MOSI_LOW()         digitalWrite(_mosi, LOW)
-#define SSPI_SCK_HIGH()         digitalWrite(_sclk, HIGH)
-#define SSPI_SCK_LOW()          digitalWrite(_sclk, LOW)
-#define SSPI_MISO_READ()        digitalRead(_miso)
-#endif
-
-#define SSPI_BEGIN_TRANSACTION()
-#define SSPI_END_TRANSACTION()
-#define SSPI_WRITE(v)           spiWrite(v)
-#define SSPI_WRITE16(s)         SSPI_WRITE((s) >> 8); SSPI_WRITE(s)
-#define SSPI_WRITE32(l)         SSPI_WRITE((l) >> 24); SSPI_WRITE((l) >> 16); SSPI_WRITE((l) >> 8); SSPI_WRITE(l)
-#define SSPI_WRITE_PIXELS(c,l)  for(uint32_t i=0; i<(l); i+=2){ SSPI_WRITE(((uint8_t*)(c))[i+1]); SSPI_WRITE(((uint8_t*)(c))[i]); }
-
-/*
- * Hardware SPI Macros
- * */
-
-#if defined (__AVR__) ||  defined(TEENSYDUINO) ||  defined(ARDUINO_ARCH_STM32F1)
-    #define HSPI_SET_CLOCK() _spi->setClockDivider(SPI_CLOCK_DIV2);
-#elif defined (__arm__)
-    #define HSPI_SET_CLOCK() _spi->setClockDivider(11);
-#elif defined(ESP8266) || defined(ESP32)
-    #define HSPI_SET_CLOCK() _spi->setFrequency(_freq);
-#elif defined(RASPI)
-    #define HSPI_SET_CLOCK() _spi->setClock(_freq);
-#elif defined(ARDUINO_ARCH_STM32F1)
-    #define HSPI_SET_CLOCK() _spi->setClock(_freq);
-#else
-    #define HSPI_SET_CLOCK()
-#endif
-
-#ifdef SPI_HAS_TRANSACTION
-    #define HSPI_BEGIN_TRANSACTION() _spi->beginTransaction(SPISettings(_freq, MSBFIRST, SPI_MODE0))
-    #define HSPI_END_TRANSACTION()   _spi->endTransaction()
-#else
-    #define HSPI_BEGIN_TRANSACTION() HSPI_SET_CLOCK(); _spi->setBitOrder(MSBFIRST); _spi->setDataMode(SPI_MODE0)
-    #define HSPI_END_TRANSACTION()
-#endif
-
-#ifdef ESP32
-    #define SPI_HAS_WRITE_PIXELS
-#endif
-#if defined(ESP8266) || defined(ESP32)
-    // Optimized SPI (ESP8266 and ESP32)
-    #define HSPI_READ()              _spi->transfer(0)
-    #define HSPI_WRITE(b)            _spi->write(b)
-    #define HSPI_WRITE16(s)          _spi->write16(s)
-    #define HSPI_WRITE32(l)          _spi->write32(l)
-    #ifdef SPI_HAS_WRITE_PIXELS
-        #define SPI_MAX_PIXELS_AT_ONCE  32
-        #define HSPI_WRITE_PIXELS(c,l)   _spi->writePixels(c,l)
-    #else
-        #define HSPI_WRITE_PIXELS(c,l)   for(uint32_t i=0; i<((l)/2); i++){ SPI_WRITE16(((uint16_t*)(c))[i]); }
-    #endif
-#else
-    // Standard Byte-by-Byte SPI
-
-    #if defined (__AVR__) || defined(TEENSYDUINO)
-static inline uint8_t _avr_spi_read(void) __attribute__((always_inline));
-static inline uint8_t _avr_spi_read(void) {
-    uint8_t r = 0;
-    SPDR = r;
-    while(!(SPSR & _BV(SPIF)));
-    r = SPDR;
-    return r;
-}
-        #define HSPI_WRITE(b)            {SPDR = (b); while(!(SPSR & _BV(SPIF)));}
-        #define HSPI_READ()              _avr_spi_read()
-    #else
-        #define HSPI_WRITE(b)            _spi->transfer((uint8_t)(b))
-        #define HSPI_READ()              HSPI_WRITE(0)
-    #endif
-    #define HSPI_WRITE16(s)          HSPI_WRITE((s) >> 8); HSPI_WRITE(s)
-    #define HSPI_WRITE32(l)          HSPI_WRITE((l) >> 24); HSPI_WRITE((l) >> 16); HSPI_WRITE((l) >> 8); HSPI_WRITE(l)
-    #define HSPI_WRITE_PIXELS(c,l)   for(uint32_t i=0; i<(l); i+=2){ HSPI_WRITE(((uint8_t*)(c))[i+1]); HSPI_WRITE(((uint8_t*)(c))[i]); }
-#endif
-
-  #define SPI_BEGIN()             if(_sclk < 0){_spi->begin();}
-  #define SPI_BEGIN_TRANSACTION() if(_sclk < 0){HSPI_BEGIN_TRANSACTION();}
-  #define SPI_END_TRANSACTION()   if(_sclk < 0){HSPI_END_TRANSACTION();}
-  #define SPI_WRITE16(s)          if(_sclk < 0){HSPI_WRITE16(s);}else{SSPI_WRITE16(s);}
-  #define SPI_WRITE32(l)          if(_sclk < 0){HSPI_WRITE32(l);}else{SSPI_WRITE32(l);}
-  #define SPI_WRITE_PIXELS(c,l)   if(_sclk < 0){HSPI_WRITE_PIXELS(c,l);}else{SSPI_WRITE_PIXELS(c,l);}
-
-#endif // _ADAFRUIT_SPITFT_MACROS
+// Macros previously #defined here have been made into (mostly) inline
+// functions in the Adafruit_SPITFT class. Other libraries might still
+// contain code trying to #include this header file, so until everything's
+// updated this file still exists (but doing nothing) to avoid trouble.

+ 0 - 608
Adafruit_TFT8.cpp

@@ -1,608 +0,0 @@
-/*!
-* @file Adafruit_TFT8.cpp
-*
-* @mainpage Adafruit 8-bit Parallel TFT Displays
-*
-* @section intro_sec Introduction
-* This is our library for TFT Displays using an 8-bit parallel interface
-* with address windows and 16 bit color.
-*
-* These displays use ip to 13 pins to communicate:
-*  - 8 data lines (required)
-*  - Write strobe (required)
-*  - Command/data (required)
-*  - Chip select  (optional, can be tied LOW)
-*  - Read strobe  (optional)
-*  - Reset        (optional, can connect to MCU reset)
-*
-* 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 <a href="https://github.com/adafruit/Adafruit_GFX">
-* Adafruit_GFX</a> 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 for ATtiny, at all
-
-#include "Adafruit_TFT8.h"
-
-#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
-
-#ifdef USE_PORT_DMA
-  #include <Adafruit_ZeroDMA.h>
-  #include <malloc.h> // memalign() function
-
-  // DMA transfer-in-progress indicator and callback
-  static volatile boolean dma_busy = false;
-  static void dma_callback(Adafruit_ZeroDMA *dma) {
-    dma_busy = false;
-  }
-#endif // USE_PORT_DMA
-
-#if defined(__AVR__)
-  #define WR_LOW()        *wrPort &= wrPinMaskClr;
-  #define WR_HIGH()       *wrPort |= wrPinMaskSet;
-  #define DC_LOW()        *dcPort &= dcPinMaskClr;
-  #define DC_HIGH()       *dcPort |= dcPinMaskSet;
-  #define CS_LOW()        if(_cs >= 0) *csPort &= csPinMaskClr;
-  #define CS_HIGH()       if(_cs >= 0) *csPort |= csPinMaskSet;
-  #define RD_LOW()        *rdPort &= rdPinMaskClr;
-  #define RD_HIGH()       *rdPort |= rdPinMaskSet;
-  #define PORT_OUTPUT()   *portDir = 0xFF;
-  #define PORT_INPUT()    *portDir = 0x00;
-#else
-  #define WR_LOW()        *wrPortClr = wrPinMask;
-  #define WR_HIGH()       *wrPortSet = wrPinMask;
-  #define DC_LOW()        *dcPortClr = dcPinMask;
-  #define DC_HIGH()       *dcPortSet = dcPinMask;
-  #define CS_LOW()        if(_cs >= 0) *csPortClr = csPinMask;
-  #define CS_HIGH()       if(_cs >= 0) *csPortSet = csPinMask;
-  #define RD_LOW()        *rdPortClr = rdPinMask;
-  #define RD_HIGH()       *rdPortSet = rdPinMask;
-  #define PORT_OUTPUT()   *dirSet    = 0xFF;
-  #define PORT_INPUT()    *dirClr    = 0xFF;
-  #define PORT_OUTPUT16() *(volatile uint16_t *)dirSet = 0xFFFF;
-  #define PORT_INPUT16()  *(volatile uint16_t *)dirClr = 0xFFFF;
-#endif
-#define WR_STROBE() { WR_LOW(); WR_HIGH(); }
-
-/*!
-    @brief  Instantiate Adafruit TFT8 display driver.
-    @param  w     Display width in pixels.
-    @param  h     Display height in pixels.
-    @param  D0    Arduino pin # for data bit 0 (1+ are extrapolated).
-                  The 8 data bits MUST be contiguous and byte-aligned
-                  (word-aligned for 'wide' interface) within the same
-                  PORT register (may not correspond to Arduino pin sequence).
-    @param  WR    Arduino pin # for write strobe.
-    @param  DC    Arduino pin # for data/command.
-    @param  CS    Arduino pin # for chip select (-1 if unused, tie CS low).
-    @param  RST   Arduino pin # for reset (-1 if unused, tie to MCU reset).
-    @param  RD    Arduino pin # for read strobe (-1 if unused).
-    @param  wide  If true, use 16-bit wide interface (not on AVR).
-*/
-Adafruit_TFT8::Adafruit_TFT8(uint16_t w, uint16_t h,
-  int8_t D0, int8_t WR, int8_t DC, int8_t CS, int8_t RST, int8_t RD,
-  bool wide) : Adafruit_GFX(w, h),
-  _d0(D0), _wr(WR), _dc(DC), _cs(CS), _rst(RST), _rd(RD)
-{
-#if defined(__AVR__)
-    if(digitalPinToBitMask(D0) != 1) return; // D0 MUST be port bit 0
-    _d0          = D0; // Save D0 pin to indicate valid alignment
-    wrPort       = (PORTreg_t)portOutputRegister(digitalPinToPort(WR));
-    wrPinMaskSet = digitalPinToBitMask(WR);
-    dcPort       = (PORTreg_t)portOutputRegister(digitalPinToPort(DC));
-    dcPinMaskSet = digitalPinToBitMask(DC);
-    if(CS >= 0) {
-      csPort       = (PORTreg_t)portOutputRegister(digitalPinToPort(CS));
-      csPinMaskSet = 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;
-      csPinMaskSet = 0;
-    }
-    if(RD >= 0) {
-      rdPort       = (PORTreg_t)portOutputRegister(digitalPinToPort(RD));
-      rdPinMaskSet = digitalPinToBitMask(RD);
-    } else {
-      // No read-strobe line defined; similar to CS case above
-      rdPort       = dcPort;
-      rdPinMaskSet = 0;
-    }
-    wrPinMaskClr = ~wrPinMaskSet;
-    dcPinMaskClr = ~dcPinMaskSet;
-    csPinMaskClr = ~csPinMaskSet;
-    rdPinMaskClr = ~rdPinMaskSet;
-    writePort    = (PORTreg_t)portOutputRegister(digitalPinToPort(D0));
-    readPort     = (PORTreg_t)portInputRegister(digitalPinToPort(D0));
-    portDir      = (PORTreg_t)portModeRegister(digitalPinToPort(D0));
-#else
-    // Confirm D0 bit is byte- or word-aligned in PORT...
-    if(g_APinDescription[D0].ulPin & (wide ? 15 : 7)) return;
-    _d0       = D0; // Save D0 pin to indicate valid alignment
-    _wide     = wide;
-    wrPinMask = digitalPinToBitMask(WR);
-    wrPortSet = &(PORT->Group[g_APinDescription[WR].ulPort].OUTSET.reg);
-    wrPortClr = &(PORT->Group[g_APinDescription[WR].ulPort].OUTCLR.reg);
-    dcPinMask = digitalPinToBitMask(DC);
-    dcPortSet = &(PORT->Group[g_APinDescription[DC].ulPort].OUTSET.reg);
-    dcPortClr = &(PORT->Group[g_APinDescription[DC].ulPort].OUTCLR.reg);
-    if(CS >= 0) { // If chip-select pin is specified...
-      csPinMask = digitalPinToBitMask(CS);
-      csPortSet = &(PORT->Group[g_APinDescription[CS].ulPort].OUTSET.reg);
-      csPortClr = &(PORT->Group[g_APinDescription[CS].ulPort].OUTCLR.reg);
-    } 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.
-      csPinMask = 0;
-      csPortSet = dcPortSet;
-      csPortClr = dcPortClr;
-    }
-    if(RD >= 0) { // If read-strobe pin is specified...
-      rdPinMask = digitalPinToBitMask(RD);
-      rdPortSet = &(PORT->Group[g_APinDescription[RD].ulPort].OUTSET.reg);
-      rdPortClr = &(PORT->Group[g_APinDescription[RD].ulPort].OUTCLR.reg);
-    } else {
-      rdPinMask = 0;
-      rdPortSet = dcPortSet;
-      rdPortClr = dcPortClr;
-    }
-
-    // Get pointers to PORT write/read/dir bytes within 32-bit PORT
-    uint8_t    dBit    = g_APinDescription[_d0].ulPin; // d0 bit # in PORT
-    PortGroup *p       = (&(PORT->Group[g_APinDescription[_d0].ulPort]));
-    uint8_t    offset  = dBit / 8; // d[7:0] byte # within PORT
-    if(wide)   offset &= ~1; // d[15:8] byte # within PORT
-    // These are all uint8_t* pointers -- elsewhere they're recast
-    // as necessary if a 'wide' 16-bit interface is in use.
-    writePort = (volatile uint8_t *)&(p->OUT.reg)    + offset;
-    readPort  = (volatile uint8_t *)&(p->IN.reg)     + offset;
-    dirSet    = (volatile uint8_t *)&(p->DIRSET.reg) + offset;
-    dirClr    = (volatile uint8_t *)&(p->DIRCLR.reg) + offset;
-#endif
-}
-
-/*!
-    @brief  Initialiaze hardware interface.
-*/
-bool Adafruit_TFT8::init(void) {
-
-  if(_d0 < 0) return false; // Bad alignment in constructor
-
-  // Initialize data pins.  We were only passed d0, so scan
-  // the pin description list looking for the other pins.
-  // They'll be on the same PORT, and within the next 7 (or 15) bits
-  // (because we need to write to a contiguous PORT byte or word).
-#if defined(__AVR__)
-  // PORT registers are 8 bits wide, so just need a register match...
-  for(uint8_t i=0; i<NUM_DIGITAL_PINS; i++) {
-    if((PORTreg_t)portOutputRegister(digitalPinToPort(i)) == writePort) {
-      pinMode(i, OUTPUT);
-      digitalWrite(i, LOW);
-    }
-  }
-#else
-  uint8_t portNum = g_APinDescription[_d0].ulPort, // d0 PORT #
-          dBit    = g_APinDescription[_d0].ulPin,  // d0 bit # in PORT
-          lastBit = dBit + (_wide ? 15 : 7);
-  for(uint8_t i=0; i<PINS_COUNT; i++) {
-    if((g_APinDescription[i].ulPort == portNum ) &&
-       (g_APinDescription[i].ulPin  >= dBit    ) &&
-       (g_APinDescription[i].ulPin  <= (uint32_t)lastBit)) {
-          pinMode(i, OUTPUT);
-          digitalWrite(i, LOW);
-    }
-  }
-#endif
-
-  // Initialize control signal pins, all active LOW
-  pinMode(_wr, OUTPUT);
-  digitalWrite(_wr, HIGH);
-  pinMode(_dc, OUTPUT);
-  digitalWrite(_dc, HIGH);
-  if(_cs >= 0) {
-    pinMode(_cs, OUTPUT);
-    digitalWrite(_cs, HIGH); // Deselect
-  }
-  if(_rd >= 0) {
-    pinMode(_rd, OUTPUT);
-    digitalWrite(_rd, HIGH);
-  }
-  if(_rst >= 0) {
-    pinMode(_rst, OUTPUT);
-    digitalWrite(_rst, HIGH);
-    delay(100);
-    digitalWrite(_rst, LOW); // Toggle RST low to reset
-    delay(100);
-    digitalWrite(_rst, HIGH);
-    delay(200);
-  }
-
-  return true;
-}
-
-/*!
-    @brief  Initiate write (or read!) operation.
-*/
-inline void Adafruit_TFT8::startWrite(void) {
-  CS_LOW(); // Chip select LOW
-}
-
-/*!
-    @brief  End write (or read!) operation.
-*/
-inline void Adafruit_TFT8::endWrite(void) {
-  CS_HIGH(); // Chip select HIGH
-}
-
-/*!
-    @brief  Write one byte to hardware interface.
-    @param  b  One byte to send, MSB order
-*/
-void Adafruit_TFT8::write8(uint8_t b) {
-#if defined(__AVR__)
-  *writePort = b;
-#else
-  if(!_wide) {
-    *writePort = b;
-  } else {
-    *(volatile uint16_t *)writePort = b;
-  }
-#endif
-  WR_STROBE(); // Write strobe LOW, HIGH
-}
-
-/*!
-    @brief  Write one word to hardware interface.
-    @param  w  One word to send, MSB order
-*/
-void Adafruit_TFT8::write16(uint16_t w) {
-#if defined(__AVR__)
-  *writePort = w >> 8;   // MSB
-  WR_STROBE();           // Write strobe LOW, HIGH
-  *writePort = w;        // LSB
-  WR_STROBE();           // Write strobe LOW, HIGH
-#else
-  if(!_wide) {
-    *writePort = w >> 8; // MSB
-    WR_STROBE();         // Write strobe LOW, HIGH
-    *writePort = w;      // LSB
-  } else {
-    *(volatile uint16_t *)writePort = w;
-  }
-  WR_STROBE();           // Write strobe LOW, HIGH
-#endif
-}
-
-/*!
-    @brief  Write a command byte.
-    @param  cmd  The 8-bit command to send.
-*/
-void Adafruit_TFT8::writeCommand(uint8_t cmd) {
-    DC_LOW();    // Data/Command LOW (command mode)
-    write8(cmd); // Issue value
-    DC_HIGH();   // Data/Command HIGH (data mode)
-}
-
-/*!
-    @brief    Read one byte or word from TFT interface.
-    @returns  One byte or word, native order.
-*/
-uint16_t Adafruit_TFT8::read(void) {
-  uint16_t r = 0;
-  if(_rd >= 0) {
-#if defined(__AVR__)
-    PORT_INPUT();      // Set port to INPUT
-    RD_LOW();          // Read strobe LOW
-    r = *readPort;     // Read value from port
-    RD_HIGH();         // Read strobe HIGH
-    PORT_OUTPUT();     // Set port back to OUTPUT
-#else
-    if(!_wide) {
-      PORT_INPUT();    // Set port to INPUT
-      RD_LOW();        // Read strobe LOW
-      r = *readPort;   // Read value from port
-      RD_HIGH();       // Read strobe HIGH
-      PORT_OUTPUT();   // Set port back to OUTPUT
-    } else {
-      PORT_INPUT16();  // Set port to INPUT (16-bit)
-      RD_LOW();        // Read strobe LOW
-      r = *(volatile uint16_t *)readPort; // Read value from port
-      RD_HIGH();       // Read strobe HIGH
-      PORT_OUTPUT16(); // Set port back to OUTPUT (16-bit)
-    }
-#endif
-  }
-  return r;
-}
-
-/*!
-    @brief  Draw a single pixel.
-    @param  x      X coordinate.
-    @param  y      Y coordinate.
-    @param  color  16-bit 5-6-5 pixel color.
-*/
-void Adafruit_TFT8::drawPixel(int16_t x, int16_t y, uint16_t color) {
-    // Clip first...
-    if((x >= 0) && (x < _width) && (y >= 0) && (y < _height)) {
-        // THEN device-select and draw...
-        startWrite();
-        setAddrWindow(x, y, 1, 1);
-        writePixel(color);
-        endWrite();
-    }
-}
-
-
-
-
-/*!
-    @brief   Converts 8-bit (each) R,G,B color to 16-bit packed 5-6-5 value.
-    @param   red   Red level, 0 to 255
-    @param   green Green level, 0 to 255
-    @param   blue  Blue level, 0 to 255
-    @return  Unsigned 16-bit decimated color in "5-6-5" format
-*/
-uint16_t Adafruit_TFT8::color565(uint8_t red, uint8_t green, uint8_t blue) {
-  return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3);
-}
-
-
-#if 0
-
-
-
-
-
-
-/*!
-    @brief  Issue multiple 2-byte colors.
-    @param  colors  Array of 16-bit 5-6-5 Colors to draw.
-    @param  len     How many pixels to draw.
-*/
-void Adafruit_TFT8::writePixels(uint16_t *colors, uint32_t len) {
-    SPI_WRITE_PIXELS((uint8_t*)colors , len * 2);
-}
-
-/*!
-    @brief  Issue a 2-byte color many times.
-    @param  color  The 16-bit 5-6-5 Color to draw.
-    @param  len    How many pixels to draw.
-*/
-void Adafruit_TFT8::writeColor(uint16_t color, uint32_t len) {
-
-  if(!len) return; // Avoid 0-byte transfers
-
-  uint8_t hi = color >> 8, lo = color;
-
-  if(hi != lo) {
-  } else {
-    len *= 2;
-// Issue as bytes
-  }
-}
-
-/**************************************************************************/
-/*!
-   @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;
-    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;
-
-    setAddrWindow(x, y, w, h);
-    writeColor(color, (int32_t)w * h);
-}
-
-/**************************************************************************/
-/*!
-   @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    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();
-    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 // 0
-
-
-
-
-#endif // !__AVR_ATtiny85__
-

+ 0 - 0
Adafruit_TFT8.h → olde/Adafruit_TFT8.h


+ 60 - 0
olde/ttt.ttt

@@ -0,0 +1,60 @@
+#define TFT_HARD_SPI 0
+#define TFT_SOFT_SPI 1
+#define TFT_PARALLEL 2
+
+#if defined(USE_FAST_PINIO)
+#if defined(HAS_PORT_SET_CLR)
+ #define TFT_CS_HIGH()       { *csPortSet   = csPinMask;               }
+ #define TFT_CS_LOW()        { *csPortClr   = csPinMask;               }
+ #define TFT_DC_HIGH()       { *dcPortSet   = dcPinMask;               }
+ #define TFT_DC_LOW()        { *dcPortClr   = dcPinMask;               }
+ #define TFT_MOSI_HIGH()     { *mosiPortSet = mosiPinMask;             }
+ #define TFT_MOSI_LOW()      { *mosiPortClr = mosiPinMask;             }
+ #define TFT_SCK_HIGH()      { *sckPortSet  = sckPinMask;              }
+ #define TFT_SCK_LOW()       { *sckPortClr  = sckPinMask;              }
+ #define TFT_WR_HIGH()       { *wrPortSet   = wrPinMask;               }
+ #define TFT_WR_LOW()        { *wrPortClr   = wrPinMask;               }
+ #define TFT_RD_HIGH()       { *rdPortSet   = rdPinMask;               }
+ #define TFT_RD_LOW()        { *rdPortClr   = rdPinMask;               }
+ #define TFT_PORT_OUTPUT()   { *dirSet      = 0xFF;                    }
+ #define TFT_PORT_INPUT()    { *dirClr      = 0xFF;                    }
+ #define TFT_PORT_OUTPUT16() { *(volatile uint16_t *)dirSet = 0xFFFF;  }
+ #define TFT_PORT_INPUT16()  { *(volatile uint16_t *)dirClr = 0xFFFF;  }
+#else  // !HAS_PORT_SET_CLR
+ #define TFT_CS_HIGH()       { *csPort     |= csPinMaskSet;            }
+ #define TFT_CS_LOW()        { *csPort     &= csPinMaskClr;            }
+ #define TFT_DC_HIGH()       { *dcPort     |= dcPinMaskSet;            }
+ #define TFT_DC_LOW()        { *dcPort     &= dcPinMaskClr;            }
+ #define TFT_MOSI_HIGH()     { *mosiPort   |= mosiPinMaskSet;          }
+ #define TFT_MOSI_LOW()      { *mosiPort   &= mosiPinMaskClr;          }
+ #define TFT_SCK_HIGH()      { *sckPort    |= sckPinMaskSet;           }
+ #define TFT_SCK_LOW()       { *sckPort    &= sckPinMaskClr;           }
+ #define TFT_WR_HIGH()       { *wrPort     |= wrPinMaskSet;            }
+ #define TFT_WR_LOW()        { *wrPort     &= wrPinMaskClr;            }
+ #define TFT_RD_HIGH()       { *rdPort     |= rdPinMaskSet;            }
+ #define TFT_RD_LOW()        { *rdPort     &= rdPinMaskClr;            }
+ #define TFT_PORT_OUTPUT()   { *portDir     = 0xFF;                    }
+ #define TFT_PORT_INPUT()    { *portDir     = 0x00;                    }
+ #define TFT_PORT_OUTPUT16() { *(volatile uint16_t *)portDir = 0xFFFF; }
+ #define TFT_PORT_INPUT16()  { *(volatile uint16_t *)portDir = 0x0000; }
+#endif // end HAS_PORT_SET_CLR
+ #define TFT_SPI_READ()      (*misoPort & misoPinMask)
+#else  // !USE_FAST_PINIO
+ #define TFT_CS_HIGH()       digitalWrite(_cs  , HIGH)
+ #define TFT_CS_LOW()        digitalWrite(_cs  , LOW )
+ #define TFT_DC_HIGH()       digitalWrite(_dc  , HIGH)
+ #define TFT_DC_LOW()        digitalWrite(_dc  , LOW )
+ #define TFT_MOSI_HIGH()     digitalWrite(_mosi, HIGH)
+ #define TFT_MOSI_LOW()      digitalWrite(_mosi, LOW )
+ #define TFT_SCK_HIGH()      digitalWrite(_sck , HIGH)
+ #define TFT_SCK_LOW()       digitalWrite(_sck , LOW )
+ #define TFT_WR_HIGH()       digitalWrite(_wr  , HIGH)
+ #define TFT_WR_LOW()        digitalWrite(_wr  , LOW )
+ #define TFT_RD_HIGH()       digitalWrite(_rd  , HIGH)
+ #define TFT_RD_LOW()        digitalWrite(_rd  , LOW )
+ #define TFT_PORT_OUTPUT()   { } // 8-bit parallel is not supported
+ #define TFT_PORT_INPUT()    { } // if USE_FAST_PINIO is unavailable.
+ #define TFT_PORT_OUTPUT16() { } // No plans to implement this. If no
+ #define TFT_PORT_INPUT16()  { } // PORT access, use an SPI display!
+ #define TFT_SPI_READ()      digitalRead(_miso)
+#endif // end USE_FAST_PINIO

Някои файлове не бяха показани, защото твърде много файлове са промени