From f7f16243260fcbb7f650116ec2643f2eb54b27b6 Mon Sep 17 00:00:00 2001 From: Phillip Burgess Date: Thu, 31 Jan 2019 15:16:40 -0800 Subject: [PATCH] Add TFT8 version --- Adafruit_TFT8_ILI9341.cpp | 233 +++++++++++++++ Adafruit_TFT8_ILI9341.h | 145 ++++++++++ examples/TFT8_ILI9341/TFT8_ILI9341.ino | 383 +++++++++++++++++++++++++ 3 files changed, 761 insertions(+) create mode 100755 Adafruit_TFT8_ILI9341.cpp create mode 100755 Adafruit_TFT8_ILI9341.h create mode 100644 examples/TFT8_ILI9341/TFT8_ILI9341.ino diff --git a/Adafruit_TFT8_ILI9341.cpp b/Adafruit_TFT8_ILI9341.cpp new file mode 100755 index 0000000..ef762e5 --- /dev/null +++ b/Adafruit_TFT8_ILI9341.cpp @@ -0,0 +1,233 @@ +/*! +* @file Adafruit_ILI9341.cpp +* +* @mainpage Adafruit ILI9341 TFT Displays +* +* @section intro_sec Introduction +* +* This is the documentation for Adafruit's ILI9341 driver for the +* Arduino platform. +* +* This library works with the Adafruit 2.8" Touch Shield V2 (SPI) +* http://www.adafruit.com/products/1651 +* +* Adafruit 2.4" TFT LCD with Touchscreen Breakout w/MicroSD Socket - ILI9341 +* https://www.adafruit.com/product/2478 +* +* 2.8" TFT LCD with Touchscreen Breakout Board w/MicroSD Socket - ILI9341 +* https://www.adafruit.com/product/1770 +* +* 2.2" 18-bit color TFT LCD display with microSD card breakout - ILI9340 +* https://www.adafruit.com/product/1770 +* +* TFT FeatherWing - 2.4" 320x240 Touchscreen For All Feathers +* https://www.adafruit.com/product/3315 +* +* These displays use SPI to communicate, 4 or 5 pins are required +* to interface (RST is optional). +* +* Adafruit invests time and resources providing this open source code, +* please support Adafruit and open-source hardware by purchasing +* products from Adafruit! +* +* @section dependencies Dependencies +* +* This library depends on +* Adafruit_GFX being present on your system. Please make sure you have +* installed the latest version before using this library. +* +* @section author Author +* +* Written by Limor "ladyada" Fried for Adafruit Industries. +* +* @section license License +* +* BSD license, all text here must be included in any redistribution. +* +*/ + +#include "Adafruit_TFT8_ILI9341.h" + +#define MADCTL_MY 0x80 ///< Bottom to top +#define MADCTL_MX 0x40 ///< Right to left +#define MADCTL_MV 0x20 ///< Reverse Mode +#define MADCTL_ML 0x10 ///< LCD refresh Bottom to top +#define MADCTL_RGB 0x00 ///< Red-Green-Blue pixel order +#define MADCTL_BGR 0x08 ///< Blue-Green-Red pixel order +#define MADCTL_MH 0x04 ///< LCD refresh right to left + +/**************************************************************************/ +/*! + @brief Instantiate Adafruit ILI9341 driver + @param cs Chip select pin # + @param dc Data/Command pin # + @param rst Reset pin # (optional, pass -1 if unused) +*/ +/**************************************************************************/ +Adafruit_TFT8_ILI9341::Adafruit_TFT8_ILI9341(int8_t D0, int8_t WR, int8_t DC, + int8_t CS, int8_t RST, int8_t RD, bool wide) : Adafruit_TFT8( + ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT, D0, WR, DC, CS, RST, RD, wide) { +} + +static const uint8_t PROGMEM initcmd[] = { + 0xEF, 3, 0x03, 0x80, 0x02, + 0xCF, 3, 0x00, 0xC1, 0x30, + 0xED, 4, 0x64, 0x03, 0x12, 0x81, + 0xE8, 3, 0x85, 0x00, 0x78, + 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, + 0xF7, 1, 0x20, + 0xEA, 2, 0x00, 0x00, + ILI9341_PWCTR1 , 1, 0x23, // Power control VRH[5:0] + ILI9341_PWCTR2 , 1, 0x10, // Power control SAP[2:0];BT[3:0] + ILI9341_VMCTR1 , 2, 0x3e, 0x28, // VCM control + ILI9341_VMCTR2 , 1, 0x86, // VCM control2 + ILI9341_MADCTL , 1, 0x48, // Memory Access Control + ILI9341_VSCRSADD, 1, 0x00, // Vertical scroll zero + ILI9341_PIXFMT , 1, 0x55, + ILI9341_FRMCTR1 , 2, 0x00, 0x18, + ILI9341_DFUNCTR , 3, 0x08, 0x82, 0x27, // Display Function Control + 0xF2, 1, 0x00, // 3Gamma Function Disable + ILI9341_GAMMASET , 1, 0x01, // Gamma curve selected + ILI9341_GMCTRP1 , 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma + 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, + ILI9341_GMCTRN1 , 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma + 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, + ILI9341_SLPOUT , 0x80, // Exit Sleep + ILI9341_DISPON , 0x80, // Display on + 0x00 // End of list +}; + +/**************************************************************************/ +/*! + @brief Initialize ILI9341 chip + Connects to the ILI9341 over SPI and sends initialization procedure commands +*/ +/**************************************************************************/ +bool Adafruit_TFT8_ILI9341::begin(void) { + if(!init()) return false; // MCU hardware init in TFT8 class + + startWrite(); // Chip select + + uint8_t cmd, x, numArgs; + const uint8_t *addr = initcmd; + while((cmd = pgm_read_byte(addr++)) > 0) { + writeCommand(cmd); + x = pgm_read_byte(addr++); + numArgs = x & 0x7F; + while(numArgs--) write8(pgm_read_byte(addr++)); + if(x & 0x80) delay(120); + } + + endWrite(); + + _width = ILI9341_TFTWIDTH; + _height = ILI9341_TFTHEIGHT; + return true; +} + + +/**************************************************************************/ +/*! + @brief Set origin of (0,0) and orientation of TFT display + @param m The index for rotation, from 0-3 inclusive +*/ +/**************************************************************************/ +void Adafruit_TFT8_ILI9341::setRotation(uint8_t m) { + rotation = m % 4; // can't be higher than 3 + switch (rotation) { + case 0: + m = (MADCTL_MX | MADCTL_BGR); + _width = ILI9341_TFTWIDTH; + _height = ILI9341_TFTHEIGHT; + break; + case 1: + m = (MADCTL_MV | MADCTL_BGR); + _width = ILI9341_TFTHEIGHT; + _height = ILI9341_TFTWIDTH; + break; + case 2: + m = (MADCTL_MY | MADCTL_BGR); + _width = ILI9341_TFTWIDTH; + _height = ILI9341_TFTHEIGHT; + break; + case 3: + m = (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR); + _width = ILI9341_TFTHEIGHT; + _height = ILI9341_TFTWIDTH; + break; + } + + startWrite(); + writeCommand(ILI9341_MADCTL); + write8(m); + endWrite(); +} + +/**************************************************************************/ +/*! + @brief Enable/Disable display color inversion + @param invert True to invert, False to have normal color +*/ +/**************************************************************************/ +void Adafruit_TFT8_ILI9341::invertDisplay(boolean invert) { + startWrite(); + writeCommand(invert ? ILI9341_INVON : ILI9341_INVOFF); + endWrite(); +} + +/**************************************************************************/ +/*! + @brief Scroll display memory + @param y How many pixels to scroll display by +*/ +/**************************************************************************/ +void Adafruit_TFT8_ILI9341::scrollTo(uint16_t y) { + startWrite(); + writeCommand(ILI9341_VSCRSADD); + write16(y); + endWrite(); +} + +/**************************************************************************/ +/*! + @brief Set the "address window" - the rectangle we will write to RAM with the next chunk of SPI data writes. The ILI9341 will automatically wrap the data as each row is filled + @param x TFT memory 'x' origin + @param y TFT memory 'y' origin + @param w Width of rectangle + @param h Height of rectangle +*/ +/**************************************************************************/ +void Adafruit_TFT8_ILI9341::setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { + writeCommand(ILI9341_CASET); // Column addr set + write16(x); + write16(x + w - 1); + writeCommand(ILI9341_PASET); // Row addr set + write16(y); + write16(y + h - 1); + writeCommand(ILI9341_RAMWR); // write to RAM +} + +/**************************************************************************/ +/*! + @brief Read 8 bits of data from ILI9341 configuration memory. NOT from RAM! + This is highly undocumented/supported, it's really a hack but kinda works? + @param command The command register to read data from + @param index The byte index into the command to read from + @return Unsigned 8-bit data read from ILI9341 register +*/ +/**************************************************************************/ +uint8_t Adafruit_TFT8_ILI9341::readcommand8(uint8_t command, uint8_t index) { +#if 0 + uint32_t freq = _freq; + if(_freq > 24000000) _freq = 24000000; + startWrite(); + writeCommand(0xD9); // woo sekret command? + spiWrite(0x10 + index); + writeCommand(command); + uint8_t r = spiRead(); + endWrite(); + _freq = freq; + return r; +#endif +} + diff --git a/Adafruit_TFT8_ILI9341.h b/Adafruit_TFT8_ILI9341.h new file mode 100755 index 0000000..ea885a1 --- /dev/null +++ b/Adafruit_TFT8_ILI9341.h @@ -0,0 +1,145 @@ +/*! +* @file Adafruit_ILI9341.h +* +* This is the documentation for Adafruit's ILI9341 driver for the +* Arduino platform. +* +* This library works with the Adafruit 2.8" Touch Shield V2 (SPI) +* http://www.adafruit.com/products/1651 +* Adafruit 2.4" TFT LCD with Touchscreen Breakout w/MicroSD Socket - ILI9341 +* https://www.adafruit.com/product/2478 +* 2.8" TFT LCD with Touchscreen Breakout Board w/MicroSD Socket - ILI9341 +* https://www.adafruit.com/product/1770 +* 2.2" 18-bit color TFT LCD display with microSD card breakout - ILI9340 +* https://www.adafruit.com/product/1770 +* TFT FeatherWing - 2.4" 320x240 Touchscreen For All Feathers +* https://www.adafruit.com/product/3315 +* +* These displays use SPI to communicate, 4 or 5 pins are required +* to interface (RST is optional). +* +* Adafruit invests time and resources providing this open source code, +* please support Adafruit and open-source hardware by purchasing +* products from Adafruit! +* +* +* This library depends on +* Adafruit_GFX being present on your system. Please make sure you have +* installed the latest version before using this library. +* +* Written by Limor "ladyada" Fried for Adafruit Industries. +* +* BSD license, all text here must be included in any redistribution. +* +*/ + +#ifndef _ADAFRUIT_TFT8_ILI9341H_ +#define _ADAFRUIT_TFT8_ILI9341H_ + +#include "Arduino.h" +#include "Print.h" +#include +#include +#include + +#define ILI9341_TFTWIDTH 240 ///< ILI9341 max TFT width +#define ILI9341_TFTHEIGHT 320 ///< ILI9341 max TFT height + +#define ILI9341_NOP 0x00 ///< No-op register +#define ILI9341_SWRESET 0x01 ///< Software reset register +#define ILI9341_RDDID 0x04 ///< Read display identification information +#define ILI9341_RDDST 0x09 ///< Read Display Status + +#define ILI9341_SLPIN 0x10 ///< Enter Sleep Mode +#define ILI9341_SLPOUT 0x11 ///< Sleep Out +#define ILI9341_PTLON 0x12 ///< Partial Mode ON +#define ILI9341_NORON 0x13 ///< Normal Display Mode ON + +#define ILI9341_RDMODE 0x0A ///< Read Display Power Mode +#define ILI9341_RDMADCTL 0x0B ///< Read Display MADCTL +#define ILI9341_RDPIXFMT 0x0C ///< Read Display Pixel Format +#define ILI9341_RDIMGFMT 0x0D ///< Read Display Image Format +#define ILI9341_RDSELFDIAG 0x0F ///< Read Display Self-Diagnostic Result + +#define ILI9341_INVOFF 0x20 ///< Display Inversion OFF +#define ILI9341_INVON 0x21 ///< Display Inversion ON +#define ILI9341_GAMMASET 0x26 ///< Gamma Set +#define ILI9341_DISPOFF 0x28 ///< Display OFF +#define ILI9341_DISPON 0x29 ///< Display ON + +#define ILI9341_CASET 0x2A ///< Column Address Set +#define ILI9341_PASET 0x2B ///< Page Address Set +#define ILI9341_RAMWR 0x2C ///< Memory Write +#define ILI9341_RAMRD 0x2E ///< Memory Read + +#define ILI9341_PTLAR 0x30 ///< Partial Area +#define ILI9341_MADCTL 0x36 ///< Memory Access Control +#define ILI9341_VSCRSADD 0x37 ///< Vertical Scrolling Start Address +#define ILI9341_PIXFMT 0x3A ///< COLMOD: Pixel Format Set + +#define ILI9341_FRMCTR1 0xB1 ///< Frame Rate Control (In Normal Mode/Full Colors) +#define ILI9341_FRMCTR2 0xB2 ///< Frame Rate Control (In Idle Mode/8 colors) +#define ILI9341_FRMCTR3 0xB3 ///< Frame Rate control (In Partial Mode/Full Colors) +#define ILI9341_INVCTR 0xB4 ///< Display Inversion Control +#define ILI9341_DFUNCTR 0xB6 ///< Display Function Control + +#define ILI9341_PWCTR1 0xC0 ///< Power Control 1 +#define ILI9341_PWCTR2 0xC1 ///< Power Control 2 +#define ILI9341_PWCTR3 0xC2 ///< Power Control 3 +#define ILI9341_PWCTR4 0xC3 ///< Power Control 4 +#define ILI9341_PWCTR5 0xC4 ///< Power Control 5 +#define ILI9341_VMCTR1 0xC5 ///< VCOM Control 1 +#define ILI9341_VMCTR2 0xC7 ///< VCOM Control 2 + +#define ILI9341_RDID1 0xDA ///< Read ID 1 +#define ILI9341_RDID2 0xDB ///< Read ID 2 +#define ILI9341_RDID3 0xDC ///< Read ID 3 +#define ILI9341_RDID4 0xDD ///< Read ID 4 + +#define ILI9341_GMCTRP1 0xE0 ///< Positive Gamma Correction +#define ILI9341_GMCTRN1 0xE1 ///< Negative Gamma Correction +//#define ILI9341_PWCTR6 0xFC + +// Color definitions +#define ILI9341_BLACK 0x0000 ///< 0, 0, 0 +#define ILI9341_NAVY 0x000F ///< 0, 0, 123 +#define ILI9341_DARKGREEN 0x03E0 ///< 0, 125, 0 +#define ILI9341_DARKCYAN 0x03EF ///< 0, 125, 123 +#define ILI9341_MAROON 0x7800 ///< 123, 0, 0 +#define ILI9341_PURPLE 0x780F ///< 123, 0, 123 +#define ILI9341_OLIVE 0x7BE0 ///< 123, 125, 0 +#define ILI9341_LIGHTGREY 0xC618 ///< 198, 195, 198 +#define ILI9341_DARKGREY 0x7BEF ///< 123, 125, 123 +#define ILI9341_BLUE 0x001F ///< 0, 0, 255 +#define ILI9341_GREEN 0x07E0 ///< 0, 255, 0 +#define ILI9341_CYAN 0x07FF ///< 0, 255, 255 +#define ILI9341_RED 0xF800 ///< 255, 0, 0 +#define ILI9341_MAGENTA 0xF81F ///< 255, 0, 255 +#define ILI9341_YELLOW 0xFFE0 ///< 255, 255, 0 +#define ILI9341_WHITE 0xFFFF ///< 255, 255, 255 +#define ILI9341_ORANGE 0xFD20 ///< 255, 165, 0 +#define ILI9341_GREENYELLOW 0xAFE5 ///< 173, 255, 41 +#define ILI9341_PINK 0xFC18 ///< 255, 130, 198 + +/**************************************************************************/ +/*! +@brief Class to manage hardware interface with ILI9341 chipset (also seems to work with ILI9340) +*/ +/**************************************************************************/ + +class Adafruit_TFT8_ILI9341 : public Adafruit_TFT8 { + public: + Adafruit_TFT8_ILI9341(int8_t D0, int8_t WR, int8_t DC, + int8_t CS = -1, int8_t RST = -1, int8_t RD = -1, bool wide = false); + + bool begin(void); + void setRotation(uint8_t r); + void invertDisplay(boolean i); + void scrollTo(uint16_t y); + + void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h); + + uint8_t readcommand8(uint8_t reg, uint8_t index=0); +}; + +#endif // _ADAFRUIT_TFT8_ILI9341H_ diff --git a/examples/TFT8_ILI9341/TFT8_ILI9341.ino b/examples/TFT8_ILI9341/TFT8_ILI9341.ino new file mode 100644 index 0000000..d8e4522 --- /dev/null +++ b/examples/TFT8_ILI9341/TFT8_ILI9341.ino @@ -0,0 +1,383 @@ +/*************************************************** + This is our GFX example for the Adafruit ILI9341 Breakout and Shield + ----> http://www.adafruit.com/products/1651 + + Check out the links above for our tutorials and wiring diagrams + These displays use SPI to communicate, 4 or 5 pins are required to + interface (RST is optional) + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + MIT license, all text above must be included in any redistribution + ****************************************************/ + + +#include "SPI.h" +#include "Adafruit_GFX.h" +#include "Adafruit_TFT8_ILI9341.h" + +#if 0 +// Pin settings for ItsyBitsy M4 contraption on my desk +#define TFT_D0 0 +#define TFT_WR A3 +#define TFT_DC A2 +#define TFT_CS -1 +#define TFT_RST A4 +#define TFT_RD A0 +#else +// Pin settings for PyPortal +#define TFT_D0 34 +#define TFT_WR 26 +#define TFT_DC 10 +#define TFT_CS 11 +#define TFT_RST 24 +#define TFT_RD 9 +#define TFT_BACKLITE 25 +#endif + +Adafruit_TFT8_ILI9341 tft = Adafruit_TFT8_ILI9341(TFT_D0, TFT_WR, TFT_DC, TFT_CS, TFT_RST, TFT_RD); + +void setup() { + Serial.begin(9600); + while(!Serial); + Serial.println("ILI9341 Test!"); + +#ifdef TFT_BACKLITE + pinMode(TFT_BACKLITE, OUTPUT); + digitalWrite(TFT_BACKLITE, HIGH); +#endif + + tft.begin(); + + // read diagnostics (optional but can help debug problems) + uint8_t x = tft.readcommand8(ILI9341_RDMODE); + Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX); + x = tft.readcommand8(ILI9341_RDMADCTL); + Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX); + x = tft.readcommand8(ILI9341_RDPIXFMT); + Serial.print("Pixel Format: 0x"); Serial.println(x, HEX); + x = tft.readcommand8(ILI9341_RDIMGFMT); + Serial.print("Image Format: 0x"); Serial.println(x, HEX); + x = tft.readcommand8(ILI9341_RDSELFDIAG); + Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); + + Serial.println(F("Benchmark Time (microseconds)")); + delay(10); + Serial.print(F("Screen fill ")); + Serial.println(testFillScreen()); + delay(500); + + Serial.print(F("Text ")); + Serial.println(testText()); + delay(3000); + + Serial.print(F("Lines ")); + Serial.println(testLines(ILI9341_CYAN)); + delay(500); + + Serial.print(F("Horiz/Vert Lines ")); + Serial.println(testFastLines(ILI9341_RED, ILI9341_BLUE)); + delay(500); + + Serial.print(F("Rectangles (outline) ")); + Serial.println(testRects(ILI9341_GREEN)); + delay(500); + + Serial.print(F("Rectangles (filled) ")); + Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA)); + delay(500); + + Serial.print(F("Circles (filled) ")); + Serial.println(testFilledCircles(10, ILI9341_MAGENTA)); + + Serial.print(F("Circles (outline) ")); + Serial.println(testCircles(10, ILI9341_WHITE)); + delay(500); + + Serial.print(F("Triangles (outline) ")); + Serial.println(testTriangles()); + delay(500); + + Serial.print(F("Triangles (filled) ")); + Serial.println(testFilledTriangles()); + delay(500); + + Serial.print(F("Rounded rects (outline) ")); + Serial.println(testRoundRects()); + delay(500); + + Serial.print(F("Rounded rects (filled) ")); + Serial.println(testFilledRoundRects()); + delay(500); + + Serial.println(F("Done!")); + +} + + +void loop(void) { + for(uint8_t rotation=0; rotation<4; rotation++) { + tft.setRotation(rotation); + testText(); + delay(1000); + } +} + +unsigned long testFillScreen() { + unsigned long start = micros(); + tft.fillScreen(ILI9341_BLACK); + yield(); + tft.fillScreen(ILI9341_RED); + yield(); + tft.fillScreen(ILI9341_GREEN); + yield(); + tft.fillScreen(ILI9341_BLUE); + yield(); + tft.fillScreen(ILI9341_BLACK); + yield(); + return micros() - start; +} + +unsigned long testText() { + tft.fillScreen(ILI9341_BLACK); + unsigned long start = micros(); + tft.setCursor(0, 0); + tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1); + tft.println("Hello World!"); + tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2); + tft.println(1234.56); + tft.setTextColor(ILI9341_RED); tft.setTextSize(3); + tft.println(0xDEADBEEF, HEX); + tft.println(); + tft.setTextColor(ILI9341_GREEN); + tft.setTextSize(5); + tft.println("Groop"); + tft.setTextSize(2); + tft.println("I implore thee,"); + tft.setTextSize(1); + tft.println("my foonting turlingdromes."); + tft.println("And hooptiously drangle me"); + tft.println("with crinkly bindlewurdles,"); + tft.println("Or I will rend thee"); + tft.println("in the gobberwarts"); + tft.println("with my blurglecruncheon,"); + tft.println("see if I don't!"); + return micros() - start; +} + +unsigned long testLines(uint16_t color) { + unsigned long start, t; + int x1, y1, x2, y2, + w = tft.width(), + h = tft.height(); + + tft.fillScreen(ILI9341_BLACK); + yield(); + + x1 = y1 = 0; + y2 = h - 1; + start = micros(); + for(x2=0; x20; i-=6) { + i2 = i / 2; + start = micros(); + tft.fillRect(cx-i2, cy-i2, i, i, color1); + t += micros() - start; + // Outlines are not included in timing results + tft.drawRect(cx-i2, cy-i2, i, i, color2); + yield(); + } + + return t; +} + +unsigned long testFilledCircles(uint8_t radius, uint16_t color) { + unsigned long start; + int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2; + + tft.fillScreen(ILI9341_BLACK); + start = micros(); + for(x=radius; x10; i-=5) { + start = micros(); + tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, + tft.color565(0, i*10, i*10)); + t += micros() - start; + tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, + tft.color565(i*10, i*10, 0)); + yield(); + } + + return t; +} + +unsigned long testRoundRects() { + unsigned long start; + int w, i, i2, + cx = tft.width() / 2 - 1, + cy = tft.height() / 2 - 1; + + tft.fillScreen(ILI9341_BLACK); + w = min(tft.width(), tft.height()); + start = micros(); + for(i=0; i20; i-=6) { + i2 = i / 2; + tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0)); + yield(); + } + + return micros() - start; +}