arduinoprojects

git clone https://git.tarina.org/arduinoprojects
Log | Files | Refs

Adafruit_SPITFT.h (24433B)


      1 /*!
      2  * @file Adafruit_SPITFT.h
      3  *
      4  * Part of Adafruit's GFX graphics library. Originally this class was
      5  * written to handle a range of color TFT displays connected via SPI,
      6  * but over time this library and some display-specific subclasses have
      7  * mutated to include some color OLEDs as well as parallel-interfaced
      8  * displays. The name's been kept for the sake of older code.
      9  *
     10  * Adafruit invests time and resources providing this open source code,
     11  * please support Adafruit and open-source hardware by purchasing
     12  * products from Adafruit!
     13  *
     14  * Written by Limor "ladyada" Fried for Adafruit Industries,
     15  * with contributions from the open source community.
     16  *
     17  * BSD license, all text here must be included in any redistribution.
     18  */
     19 
     20 #ifndef _ADAFRUIT_SPITFT_H_
     21 #define _ADAFRUIT_SPITFT_H_
     22 
     23 #if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all
     24 
     25 #include "Adafruit_GFX.h"
     26 #include <SPI.h>
     27 
     28 // HARDWARE CONFIG ---------------------------------------------------------
     29 
     30 #if defined(__AVR__)
     31 typedef uint8_t ADAGFX_PORT_t;       ///< PORT values are 8-bit
     32 #define USE_FAST_PINIO               ///< Use direct PORT register access
     33 #elif defined(ARDUINO_STM32_FEATHER) // WICED
     34 typedef class HardwareSPI SPIClass;        ///< SPI is a bit odd on WICED
     35 typedef uint32_t ADAGFX_PORT_t;            ///< PORT values are 32-bit
     36 #elif defined(__arm__)
     37 #if defined(ARDUINO_ARCH_SAMD)
     38 // Adafruit M0, M4
     39 typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit
     40 #define USE_FAST_PINIO   ///< Use direct PORT register access
     41 #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers
     42 #elif defined(CORE_TEENSY)
     43 // PJRC Teensy 4.x
     44 #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x
     45 typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit
     46                                 // PJRC Teensy 3.x
     47 #else
     48 typedef uint8_t ADAGFX_PORT_t; ///< PORT values are 8-bit
     49 #endif
     50 #define USE_FAST_PINIO   ///< Use direct PORT register access
     51 #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers
     52 #else
     53 // Arduino Due?
     54 typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit
     55 // USE_FAST_PINIO not available here (yet)...Due has a totally different
     56 // GPIO register set and will require some changes elsewhere (e.g. in
     57 // constructors especially).
     58 #endif
     59 #else                                      // !ARM
     60 // Probably ESP8266 or ESP32. USE_FAST_PINIO is not available here (yet)
     61 // but don't worry about it too much...the digitalWrite() implementation
     62 // on these platforms is reasonably efficient and already RAM-resident,
     63 // only gotcha then is no parallel connection support for now.
     64 typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit
     65 #endif                                     // end !ARM
     66 typedef volatile ADAGFX_PORT_t *PORTreg_t; ///< PORT register type
     67 
     68 #if defined(__AVR__)
     69 #define DEFAULT_SPI_FREQ 8000000L ///< Hardware SPI default speed
     70 #else
     71 #define DEFAULT_SPI_FREQ 16000000L ///< Hardware SPI default speed
     72 #endif
     73 
     74 #if defined(ADAFRUIT_PYPORTAL) || defined(ADAFRUIT_PYBADGE_M4_EXPRESS) ||      \
     75     defined(ADAFRUIT_PYGAMER_M4_EXPRESS) ||                                    \
     76     defined(ADAFRUIT_MONSTER_M4SK_EXPRESS) || defined(NRF52_SERIES) ||         \
     77     defined(ADAFRUIT_CIRCUITPLAYGROUND_M0)
     78 #define USE_SPI_DMA ///< Auto DMA
     79 #else
     80                                            //#define USE_SPI_DMA ///< If set,
     81                                            // use DMA if available
     82 #endif
     83 // Another "oops" name -- this now also handles parallel DMA.
     84 // If DMA is enabled, Arduino sketch MUST #include <Adafruit_ZeroDMA.h>
     85 // Estimated RAM usage:
     86 // 4 bytes/pixel on display major axis + 8 bytes/pixel on minor axis,
     87 // e.g. 320x240 pixels = 320 * 4 + 240 * 8 = 3,200 bytes.
     88 
     89 #if defined(USE_SPI_DMA) && (defined(__SAMD51__) || defined(ARDUINO_SAMD_ZERO))
     90 #include <Adafruit_ZeroDMA.h>
     91 #endif
     92 
     93 // This is kind of a kludge. Needed a way to disambiguate the software SPI
     94 // and parallel constructors via their argument lists. Originally tried a
     95 // bool as the first argument to the parallel constructor (specifying 8-bit
     96 // vs 16-bit interface) but the compiler regards this as equivalent to an
     97 // integer and thus still ambiguous. SO...the parallel constructor requires
     98 // an enumerated type as the first argument: tft8 (for 8-bit parallel) or
     99 // tft16 (for 16-bit)...even though 16-bit isn't fully implemented or tested
    100 // and might never be, still needed that disambiguation from soft SPI.
    101 /*! For first arg to parallel constructor */
    102 enum tftBusWidth { tft8bitbus, tft16bitbus };
    103 
    104 // CLASS DEFINITION --------------------------------------------------------
    105 
    106 /*!
    107   @brief  Adafruit_SPITFT is an intermediary class between Adafruit_GFX
    108           and various hardware-specific subclasses for different displays.
    109           It handles certain operations that are common to a range of
    110           displays (address window, area fills, etc.). Originally these were
    111           all color TFT displays interfaced via SPI, but it's since expanded
    112           to include color OLEDs and parallel-interfaced TFTs. THE NAME HAS
    113           BEEN KEPT TO AVOID BREAKING A LOT OF SUBCLASSES AND EXAMPLE CODE.
    114           Many of the class member functions similarly live on with names
    115           that don't necessarily accurately describe what they're doing,
    116           again to avoid breaking a lot of other code. If in doubt, read
    117           the comments.
    118 */
    119 class Adafruit_SPITFT : public Adafruit_GFX {
    120 
    121 public:
    122   // CONSTRUCTORS --------------------------------------------------------
    123 
    124   // Software SPI constructor: expects width & height (at default rotation
    125   // setting 0), 4 signal pins (cs, dc, mosi, sclk), 2 optional pins
    126   // (reset, miso). cs argument is required but can be -1 if unused --
    127   // rather than moving it to the optional arguments, it was done this way
    128   // to avoid breaking existing code (-1 option was a later addition).
    129   Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t cs, int8_t dc, int8_t mosi,
    130                   int8_t sck, int8_t rst = -1, int8_t miso = -1);
    131 
    132   // Hardware SPI constructor using the default SPI port: expects width &
    133   // height (at default rotation setting 0), 2 signal pins (cs, dc),
    134   // optional reset pin. cs is required but can be -1 if unused -- rather
    135   // than moving it to the optional arguments, it was done this way to
    136   // avoid breaking existing code (-1 option was a later addition).
    137   Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t cs, int8_t dc,
    138                   int8_t rst = -1);
    139 
    140 #if !defined(ESP8266) // See notes in .cpp
    141   // Hardware SPI constructor using an arbitrary SPI peripheral: expects
    142   // width & height (rotation 0), SPIClass pointer, 2 signal pins (cs, dc)
    143   // and optional reset pin. cs is required but can be -1 if unused.
    144   Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass, int8_t cs,
    145                   int8_t dc, int8_t rst = -1);
    146 #endif // end !ESP8266
    147 
    148   // Parallel constructor: expects width & height (rotation 0), flag
    149   // indicating whether 16-bit (true) or 8-bit (false) interface, 3 signal
    150   // pins (d0, wr, dc), 3 optional pins (cs, rst, rd). 16-bit parallel
    151   // isn't even fully implemented but the 'wide' flag was added as a
    152   // required argument to avoid ambiguity with other constructors.
    153   Adafruit_SPITFT(uint16_t w, uint16_t h, tftBusWidth busWidth, int8_t d0,
    154                   int8_t wr, int8_t dc, int8_t cs = -1, int8_t rst = -1,
    155                   int8_t rd = -1);
    156 
    157   // CLASS MEMBER FUNCTIONS ----------------------------------------------
    158 
    159   // These first two functions MUST be declared by subclasses:
    160 
    161   /*!
    162       @brief  Display-specific initialization function.
    163       @param  freq  SPI frequency, in hz (or 0 for default or unused).
    164   */
    165   virtual void begin(uint32_t freq) = 0;
    166 
    167   /*!
    168       @brief  Set up the specific display hardware's "address window"
    169               for subsequent pixel-pushing operations.
    170       @param  x  Leftmost pixel of area to be drawn (MUST be within
    171                  display bounds at current rotation setting).
    172       @param  y  Topmost pixel of area to be drawn (MUST be within
    173                  display bounds at current rotation setting).
    174       @param  w  Width of area to be drawn, in pixels (MUST be >0 and,
    175                  added to x, within display bounds at current rotation).
    176       @param  h  Height of area to be drawn, in pixels (MUST be >0 and,
    177                  added to x, within display bounds at current rotation).
    178   */
    179   virtual void setAddrWindow(uint16_t x, uint16_t y, uint16_t w,
    180                              uint16_t h) = 0;
    181 
    182   // Remaining functions do not need to be declared in subclasses
    183   // unless they wish to provide hardware-specific optimizations.
    184   // Brief comments here...documented more thoroughly in .cpp file.
    185 
    186   // Subclass' begin() function invokes this to initialize hardware.
    187   // freq=0 to use default SPI speed. spiMode must be one of the SPI_MODEn
    188   // values defined in SPI.h, which are NOT the same as 0 for SPI_MODE0,
    189   // 1 for SPI_MODE1, etc...use ONLY the SPI_MODEn defines! Only!
    190   // Name is outdated (interface may be parallel) but for compatibility:
    191   void initSPI(uint32_t freq = 0, uint8_t spiMode = SPI_MODE0);
    192   void setSPISpeed(uint32_t freq);
    193   // Chip select and/or hardware SPI transaction start as needed:
    194   void startWrite(void);
    195   // Chip deselect and/or hardware SPI transaction end as needed:
    196   void endWrite(void);
    197   void sendCommand(uint8_t commandByte, uint8_t *dataBytes,
    198                    uint8_t numDataBytes);
    199   void sendCommand(uint8_t commandByte, const uint8_t *dataBytes = NULL,
    200                    uint8_t numDataBytes = 0);
    201   void sendCommand16(uint16_t commandWord, const uint8_t *dataBytes = NULL,
    202                      uint8_t numDataBytes = 0);
    203   uint8_t readcommand8(uint8_t commandByte, uint8_t index = 0);
    204   uint16_t readcommand16(uint16_t addr);
    205 
    206   // These functions require a chip-select and/or SPI transaction
    207   // around them. Higher-level graphics primitives might start a
    208   // single transaction and then make multiple calls to these functions
    209   // (e.g. circle or text rendering might make repeated lines or rects)
    210   // before ending the transaction. It's more efficient than starting a
    211   // transaction every time.
    212   void writePixel(int16_t x, int16_t y, uint16_t color);
    213   void writePixels(uint16_t *colors, uint32_t len, bool block = true,
    214                    bool bigEndian = false);
    215   void writeColor(uint16_t color, uint32_t len);
    216   void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h,
    217                      uint16_t color);
    218   void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
    219   void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
    220   // This is a new function, similar to writeFillRect() except that
    221   // all arguments MUST be onscreen, sorted and clipped. If higher-level
    222   // primitives can handle their own sorting/clipping, it avoids repeating
    223   // such operations in the low-level code, making it potentially faster.
    224   // CALLING THIS WITH UNCLIPPED OR NEGATIVE VALUES COULD BE DISASTROUS.
    225   inline void writeFillRectPreclipped(int16_t x, int16_t y, int16_t w,
    226                                       int16_t h, uint16_t color);
    227   // Another new function, companion to the new non-blocking
    228   // writePixels() variant.
    229   void dmaWait(void);
    230 
    231   // These functions are similar to the 'write' functions above, but with
    232   // a chip-select and/or SPI transaction built-in. They're typically used
    233   // solo -- that is, as graphics primitives in themselves, not invoked by
    234   // higher-level primitives (which should use the functions above).
    235   void drawPixel(int16_t x, int16_t y, uint16_t color);
    236   void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
    237   void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
    238   void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
    239   // A single-pixel push encapsulated in a transaction. I don't think
    240   // this is used anymore (BMP demos might've used it?) but is provided
    241   // for backward compatibility, consider it deprecated:
    242   void pushColor(uint16_t color);
    243 
    244   using Adafruit_GFX::drawRGBBitmap; // Check base class first
    245   void drawRGBBitmap(int16_t x, int16_t y, uint16_t *pcolors, int16_t w,
    246                      int16_t h);
    247 
    248   void invertDisplay(bool i);
    249   uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
    250 
    251   // Despite parallel additions, function names kept for compatibility:
    252   void spiWrite(uint8_t b);          // Write single byte as DATA
    253   void writeCommand(uint8_t cmd);    // Write single byte as COMMAND
    254   uint8_t spiRead(void);             // Read single byte of data
    255   void write16(uint16_t w);          // Write 16-bit value as DATA
    256   void writeCommand16(uint16_t cmd); // Write 16-bit value as COMMAND
    257   uint16_t read16(void);             // Read single 16-bit value
    258 
    259   // Most of these low-level functions were formerly macros in
    260   // Adafruit_SPITFT_Macros.h. Some have been made into inline functions
    261   // to avoid macro mishaps. Despite the addition of code for a parallel
    262   // display interface, the names have been kept for backward
    263   // compatibility (some subclasses may be invoking these):
    264   void SPI_WRITE16(uint16_t w); // Not inline
    265   void SPI_WRITE32(uint32_t l); // Not inline
    266   // Old code had both a spiWrite16() function and SPI_WRITE16 macro
    267   // in addition to the SPI_WRITE32 macro. The latter two have been
    268   // made into functions here, and spiWrite16() removed (use SPI_WRITE16()
    269   // instead). It looks like most subclasses had gotten comfortable with
    270   // SPI_WRITE16 and SPI_WRITE32 anyway so those names were kept rather
    271   // than the less-obnoxious camelcase variants, oh well.
    272 
    273   // Placing these functions entirely in the class definition inlines
    274   // them implicitly them while allowing their use in other code:
    275 
    276   /*!
    277       @brief  Set the chip-select line HIGH. Does NOT check whether CS pin
    278               is set (>=0), that should be handled in calling function.
    279               Despite function name, this is used even if the display
    280               connection is parallel.
    281   */
    282   void SPI_CS_HIGH(void) {
    283 #if defined(USE_FAST_PINIO)
    284 #if defined(HAS_PORT_SET_CLR)
    285 #if defined(KINETISK)
    286     *csPortSet = 1;
    287 #else  // !KINETISK
    288     *csPortSet = csPinMask;
    289 #endif // end !KINETISK
    290 #else  // !HAS_PORT_SET_CLR
    291     *csPort |= csPinMaskSet;
    292 #endif // end !HAS_PORT_SET_CLR
    293 #else  // !USE_FAST_PINIO
    294     digitalWrite(_cs, HIGH);
    295 #endif // end !USE_FAST_PINIO
    296   }
    297 
    298   /*!
    299       @brief  Set the chip-select line LOW. Does NOT check whether CS pin
    300               is set (>=0), that should be handled in calling function.
    301               Despite function name, this is used even if the display
    302               connection is parallel.
    303   */
    304   void SPI_CS_LOW(void) {
    305 #if defined(USE_FAST_PINIO)
    306 #if defined(HAS_PORT_SET_CLR)
    307 #if defined(KINETISK)
    308     *csPortClr = 1;
    309 #else  // !KINETISK
    310     *csPortClr = csPinMask;
    311 #endif // end !KINETISK
    312 #else  // !HAS_PORT_SET_CLR
    313     *csPort &= csPinMaskClr;
    314 #endif // end !HAS_PORT_SET_CLR
    315 #else  // !USE_FAST_PINIO
    316     digitalWrite(_cs, LOW);
    317 #endif // end !USE_FAST_PINIO
    318   }
    319 
    320   /*!
    321       @brief  Set the data/command line HIGH (data mode).
    322   */
    323   void SPI_DC_HIGH(void) {
    324 #if defined(USE_FAST_PINIO)
    325 #if defined(HAS_PORT_SET_CLR)
    326 #if defined(KINETISK)
    327     *dcPortSet = 1;
    328 #else  // !KINETISK
    329     *dcPortSet = dcPinMask;
    330 #endif // end !KINETISK
    331 #else  // !HAS_PORT_SET_CLR
    332     *dcPort |= dcPinMaskSet;
    333 #endif // end !HAS_PORT_SET_CLR
    334 #else  // !USE_FAST_PINIO
    335     digitalWrite(_dc, HIGH);
    336 #endif // end !USE_FAST_PINIO
    337   }
    338 
    339   /*!
    340       @brief  Set the data/command line LOW (command mode).
    341   */
    342   void SPI_DC_LOW(void) {
    343 #if defined(USE_FAST_PINIO)
    344 #if defined(HAS_PORT_SET_CLR)
    345 #if defined(KINETISK)
    346     *dcPortClr = 1;
    347 #else  // !KINETISK
    348     *dcPortClr = dcPinMask;
    349 #endif // end !KINETISK
    350 #else  // !HAS_PORT_SET_CLR
    351     *dcPort &= dcPinMaskClr;
    352 #endif // end !HAS_PORT_SET_CLR
    353 #else  // !USE_FAST_PINIO
    354     digitalWrite(_dc, LOW);
    355 #endif // end !USE_FAST_PINIO
    356   }
    357 
    358 protected:
    359   // A few more low-level member functions -- some may have previously
    360   // been macros. Shouldn't have a need to access these externally, so
    361   // they've been moved to the protected section. Additionally, they're
    362   // declared inline here and the code is in the .cpp file, since outside
    363   // code doesn't need to see these.
    364   inline void SPI_MOSI_HIGH(void);
    365   inline void SPI_MOSI_LOW(void);
    366   inline void SPI_SCK_HIGH(void);
    367   inline void SPI_SCK_LOW(void);
    368   inline bool SPI_MISO_READ(void);
    369   inline void SPI_BEGIN_TRANSACTION(void);
    370   inline void SPI_END_TRANSACTION(void);
    371   inline void TFT_WR_STROBE(void); // Parallel interface write strobe
    372   inline void TFT_RD_HIGH(void);   // Parallel interface read high
    373   inline void TFT_RD_LOW(void);    // Parallel interface read low
    374 
    375   // CLASS INSTANCE VARIABLES --------------------------------------------
    376 
    377   // Here be dragons! There's a big union of three structures here --
    378   // one each for hardware SPI, software (bitbang) SPI, and parallel
    379   // interfaces. This is to save some memory, since a display's connection
    380   // will be only one of these. The order of some things is a little weird
    381   // in an attempt to get values to align and pack better in RAM.
    382 
    383 #if defined(USE_FAST_PINIO)
    384 #if defined(HAS_PORT_SET_CLR)
    385   PORTreg_t csPortSet; ///< PORT register for chip select SET
    386   PORTreg_t csPortClr; ///< PORT register for chip select CLEAR
    387   PORTreg_t dcPortSet; ///< PORT register for data/command SET
    388   PORTreg_t dcPortClr; ///< PORT register for data/command CLEAR
    389 #else                  // !HAS_PORT_SET_CLR
    390   PORTreg_t csPort;                 ///< PORT register for chip select
    391   PORTreg_t dcPort;                 ///< PORT register for data/command
    392 #endif                 // end HAS_PORT_SET_CLR
    393 #endif                 // end USE_FAST_PINIO
    394 #if defined(__cplusplus) && (__cplusplus >= 201100)
    395   union {
    396 #endif
    397     struct {          //   Values specific to HARDWARE SPI:
    398       SPIClass *_spi; ///< SPI class pointer
    399 #if defined(SPI_HAS_TRANSACTION)
    400       SPISettings settings; ///< SPI transaction settings
    401 #else
    402     uint32_t _freq; ///< SPI bitrate (if no SPI transactions)
    403 #endif
    404       uint32_t _mode; ///< SPI data mode (transactions or no)
    405     } hwspi;          ///< Hardware SPI values
    406     struct {          //   Values specific to SOFTWARE SPI:
    407 #if defined(USE_FAST_PINIO)
    408       PORTreg_t misoPort; ///< PORT (PIN) register for MISO
    409 #if defined(HAS_PORT_SET_CLR)
    410       PORTreg_t mosiPortSet; ///< PORT register for MOSI SET
    411       PORTreg_t mosiPortClr; ///< PORT register for MOSI CLEAR
    412       PORTreg_t sckPortSet;  ///< PORT register for SCK SET
    413       PORTreg_t sckPortClr;  ///< PORT register for SCK CLEAR
    414 #if !defined(KINETISK)
    415       ADAGFX_PORT_t mosiPinMask; ///< Bitmask for MOSI
    416       ADAGFX_PORT_t sckPinMask;  ///< Bitmask for SCK
    417 #endif                           // end !KINETISK
    418 #else                            // !HAS_PORT_SET_CLR
    419       PORTreg_t mosiPort;           ///< PORT register for MOSI
    420       PORTreg_t sckPort;            ///< PORT register for SCK
    421       ADAGFX_PORT_t mosiPinMaskSet; ///< Bitmask for MOSI SET (OR)
    422       ADAGFX_PORT_t mosiPinMaskClr; ///< Bitmask for MOSI CLEAR (AND)
    423       ADAGFX_PORT_t sckPinMaskSet;  ///< Bitmask for SCK SET (OR bitmask)
    424       ADAGFX_PORT_t sckPinMaskClr;  ///< Bitmask for SCK CLEAR (AND)
    425 #endif                           // end HAS_PORT_SET_CLR
    426 #if !defined(KINETISK)
    427       ADAGFX_PORT_t misoPinMask; ///< Bitmask for MISO
    428 #endif                           // end !KINETISK
    429 #endif                           // end USE_FAST_PINIO
    430       int8_t _mosi;              ///< MOSI pin #
    431       int8_t _miso;              ///< MISO pin #
    432       int8_t _sck;               ///< SCK pin #
    433     } swspi;                     ///< Software SPI values
    434     struct {                     //   Values specific to 8-bit parallel:
    435 #if defined(USE_FAST_PINIO)
    436 
    437 #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x
    438       volatile uint32_t *writePort; ///< PORT register for DATA WRITE
    439       volatile uint32_t *readPort;  ///< PORT (PIN) register for DATA READ
    440 #else
    441       volatile uint8_t *writePort;  ///< PORT register for DATA WRITE
    442       volatile uint8_t *readPort;   ///< PORT (PIN) register for DATA READ
    443 #endif
    444 #if defined(HAS_PORT_SET_CLR)
    445       // Port direction register pointers are always 8-bit regardless of
    446       // PORTreg_t -- even if 32-bit port, we modify a byte-aligned 8 bits.
    447 #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x
    448       volatile uint32_t *dirSet; ///< PORT byte data direction SET
    449       volatile uint32_t *dirClr; ///< PORT byte data direction CLEAR
    450 #else
    451       volatile uint8_t *dirSet; ///< PORT byte data direction SET
    452       volatile uint8_t *dirClr; ///< PORT byte data direction CLEAR
    453 #endif
    454       PORTreg_t wrPortSet; ///< PORT register for write strobe SET
    455       PORTreg_t wrPortClr; ///< PORT register for write strobe CLEAR
    456       PORTreg_t rdPortSet; ///< PORT register for read strobe SET
    457       PORTreg_t rdPortClr; ///< PORT register for read strobe CLEAR
    458 #if !defined(KINETISK)
    459       ADAGFX_PORT_t wrPinMask; ///< Bitmask for write strobe
    460 #endif                         // end !KINETISK
    461       ADAGFX_PORT_t rdPinMask; ///< Bitmask for read strobe
    462 #else                          // !HAS_PORT_SET_CLR
    463       // Port direction register pointer is always 8-bit regardless of
    464       // PORTreg_t -- even if 32-bit port, we modify a byte-aligned 8 bits.
    465       volatile uint8_t *portDir;  ///< PORT direction register
    466       PORTreg_t wrPort;           ///< PORT register for write strobe
    467       PORTreg_t rdPort;           ///< PORT register for read strobe
    468       ADAGFX_PORT_t wrPinMaskSet; ///< Bitmask for write strobe SET (OR)
    469       ADAGFX_PORT_t wrPinMaskClr; ///< Bitmask for write strobe CLEAR (AND)
    470       ADAGFX_PORT_t rdPinMaskSet; ///< Bitmask for read strobe SET (OR)
    471       ADAGFX_PORT_t rdPinMaskClr; ///< Bitmask for read strobe CLEAR (AND)
    472 #endif                         // end HAS_PORT_SET_CLR
    473 #endif                         // end USE_FAST_PINIO
    474       int8_t _d0;              ///< Data pin 0 #
    475       int8_t _wr;              ///< Write strobe pin #
    476       int8_t _rd;              ///< Read strobe pin # (or -1)
    477       bool wide = 0;           ///< If true, is 16-bit interface
    478     } tft8;                    ///< Parallel interface settings
    479 #if defined(__cplusplus) && (__cplusplus >= 201100)
    480   }; ///< Only one interface is active
    481 #endif
    482 #if defined(USE_SPI_DMA) &&                                                    \
    483     (defined(__SAMD51__) ||                                                    \
    484      defined(ARDUINO_SAMD_ZERO))     // Used by hardware SPI and tft8
    485   Adafruit_ZeroDMA dma;              ///< DMA instance
    486   DmacDescriptor *dptr = NULL;       ///< 1st descriptor
    487   DmacDescriptor *descriptor = NULL; ///< Allocated descriptor list
    488   uint16_t *pixelBuf[2];             ///< Working buffers
    489   uint16_t maxFillLen;               ///< Max pixels per DMA xfer
    490   uint16_t lastFillColor = 0;        ///< Last color used w/fill
    491   uint32_t lastFillLen = 0;          ///< # of pixels w/last fill
    492   uint8_t onePixelBuf;               ///< For hi==lo fill
    493 #endif
    494 #if defined(USE_FAST_PINIO)
    495 #if defined(HAS_PORT_SET_CLR)
    496 #if !defined(KINETISK)
    497   ADAGFX_PORT_t csPinMask; ///< Bitmask for chip select
    498   ADAGFX_PORT_t dcPinMask; ///< Bitmask for data/command
    499 #endif                     // end !KINETISK
    500 #else                      // !HAS_PORT_SET_CLR
    501   ADAGFX_PORT_t csPinMaskSet;     ///< Bitmask for chip select SET (OR)
    502   ADAGFX_PORT_t csPinMaskClr;     ///< Bitmask for chip select CLEAR (AND)
    503   ADAGFX_PORT_t dcPinMaskSet;     ///< Bitmask for data/command SET (OR)
    504   ADAGFX_PORT_t dcPinMaskClr;     ///< Bitmask for data/command CLEAR (AND)
    505 #endif                     // end HAS_PORT_SET_CLR
    506 #endif                     // end USE_FAST_PINIO
    507   uint8_t connection;      ///< TFT_HARD_SPI, TFT_SOFT_SPI, etc.
    508   int8_t _rst;             ///< Reset pin # (or -1)
    509   int8_t _cs;              ///< Chip select pin # (or -1)
    510   int8_t _dc;              ///< Data/command pin #
    511 
    512   int16_t _xstart = 0;          ///< Internal framebuffer X offset
    513   int16_t _ystart = 0;          ///< Internal framebuffer Y offset
    514   uint8_t invertOnCommand = 0;  ///< Command to enable invert mode
    515   uint8_t invertOffCommand = 0; ///< Command to disable invert mode
    516 
    517   uint32_t _freq = 0; ///< Dummy var to keep subclasses happy
    518 };
    519 
    520 #endif // end __AVR_ATtiny85__
    521 #endif // end _ADAFRUIT_SPITFT_H_