Adafruit_SPITFT.h 24 KB

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