├── libraries ├── TouchScreen │ ├── readme.txt │ ├── TouchScreen.h │ └── TouchScreen.cpp ├── Adafruit_TFTLCD │ ├── README.txt │ ├── Adafruit_TFTLCD.h │ ├── pin_magic_UNO.h │ ├── registers.h │ ├── pin_magic_MEGA.h │ └── Adafruit_TFTLCD.cpp └── Adafruit_GFX │ ├── license.txt │ ├── Adafruit_GFX.h │ ├── glcdfont.c │ └── Adafruit_GFX.cpp ├── README.md └── MyTFTanaGraph.ino /libraries/TouchScreen/readme.txt: -------------------------------------------------------------------------------- 1 | Alternative libraries for this project 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino-TFT-Touch-Screen-Analog-Graphing 2 | This sketch allows graphing of two analog signals on a TFT Touch Screen. You will need to download and install 3 libraries. There is an instructable available here: http://www.instructables.com/id/Arduino-Analog-Signal-Graphing-on-a-TFT-Touch-Scre/ 3 | -------------------------------------------------------------------------------- /libraries/TouchScreen/TouchScreen.h: -------------------------------------------------------------------------------- 1 | // Touch screen library with X Y and Z (pressure) readings as well 2 | // as oversampling to avoid 'bouncing' 3 | // (c) ladyada / adafruit 4 | // Code under MIT License 5 | 6 | #ifndef _ADAFRUIT_TOUCHSCREEN_H_ 7 | #define _ADAFRUIT_TOUCHSCREEN_H_ 8 | #include 9 | 10 | class TSPoint { 11 | public: 12 | TSPoint(void); 13 | TSPoint(int16_t x, int16_t y, int16_t z); 14 | 15 | bool operator==(TSPoint); 16 | bool operator!=(TSPoint); 17 | 18 | int16_t x, y, z; 19 | }; 20 | 21 | class TouchScreen { 22 | public: 23 | TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym); 24 | TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym, uint16_t rx); 25 | 26 | bool isTouching(void); 27 | uint16_t pressure(void); 28 | int readTouchY(); 29 | int readTouchX(); 30 | TSPoint getPoint(); 31 | int16_t pressureThreshhold; 32 | 33 | private: 34 | uint8_t _yp, _ym, _xm, _xp; 35 | uint16_t _rxplate; 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /libraries/Adafruit_TFTLCD/README.txt: -------------------------------------------------------------------------------- 1 | This is a library for the Adafruit 2.8" TFT display. 2 | This library works with the Adafruit 2.8" TFT Breakout w/SD card 3 | ----> http://www.adafruit.com/products/335 4 | as well as Adafruit TFT Touch Shield 5 | ----> http://www.adafruit.com/products/376 6 | 7 | Check out the links above for our tutorials and wiring diagrams. 8 | These displays use 8-bit parallel to communicate, 12 or 13 pins are required 9 | to interface (RST is optional). 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 Fried/Ladyada for Adafruit Industries. 15 | MIT license, all text above must be included in any redistribution 16 | 17 | To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_TFTLCD. Check that the Adafruit_TFTLCD folder contains Adafruit_TFTLCD.cpp and Adafruit_TFTLCD. 18 | 19 | Place the Adafruit_TFT library folder your /libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE 20 | 21 | Also requires the Adafruit_GFX library for Arduino. https://github.com/adafruit/Adafruit-GFX-Library 22 | -------------------------------------------------------------------------------- /libraries/Adafruit_GFX/license.txt: -------------------------------------------------------------------------------- 1 | Software License Agreement (BSD License) 2 | 3 | Copyright (c) 2012 Adafruit Industries. All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | - Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | - Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /libraries/Adafruit_GFX/Adafruit_GFX.h: -------------------------------------------------------------------------------- 1 | #ifndef _ADAFRUIT_GFX_H 2 | #define _ADAFRUIT_GFX_H 3 | 4 | #if ARDUINO >= 100 5 | #include "Arduino.h" 6 | #include "Print.h" 7 | #else 8 | #include "WProgram.h" 9 | #endif 10 | 11 | #define swap(a, b) { int16_t t = a; a = b; b = t; } 12 | 13 | class Adafruit_GFX : public Print { 14 | 15 | public: 16 | 17 | Adafruit_GFX(int16_t w, int16_t h); // Constructor 18 | 19 | // This MUST be defined by the subclass: 20 | virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0; 21 | 22 | // These MAY be overridden by the subclass to provide device-specific 23 | // optimized code. Otherwise 'generic' versions are used. 24 | virtual void 25 | drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color), 26 | drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color), 27 | drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color), 28 | drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), 29 | fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), 30 | fillScreen(uint16_t color), 31 | invertDisplay(boolean i); 32 | 33 | // These exist only with Adafruit_GFX (no subclass overrides) 34 | void 35 | drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color), 36 | drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, 37 | uint16_t color), 38 | fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color), 39 | fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, 40 | int16_t delta, uint16_t color), 41 | drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, 42 | int16_t x2, int16_t y2, uint16_t color), 43 | fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, 44 | int16_t x2, int16_t y2, uint16_t color), 45 | drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, 46 | int16_t radius, uint16_t color), 47 | fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, 48 | int16_t radius, uint16_t color), 49 | drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, 50 | int16_t w, int16_t h, uint16_t color), 51 | drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, 52 | int16_t w, int16_t h, uint16_t color, uint16_t bg), 53 | drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, 54 | int16_t w, int16_t h, uint16_t color), 55 | drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, 56 | uint16_t bg, uint8_t size), 57 | setCursor(int16_t x, int16_t y), 58 | setTextColor(uint16_t c), 59 | setTextColor(uint16_t c, uint16_t bg), 60 | setTextSize(uint8_t s), 61 | setTextWrap(boolean w), 62 | setRotation(uint8_t r); 63 | 64 | #if ARDUINO >= 100 65 | virtual size_t write(uint8_t); 66 | #else 67 | virtual void write(uint8_t); 68 | #endif 69 | 70 | int16_t height(void) const; 71 | int16_t width(void) const; 72 | 73 | uint8_t getRotation(void) const; 74 | 75 | protected: 76 | const int16_t 77 | WIDTH, HEIGHT; // This is the 'raw' display w/h - never changes 78 | int16_t 79 | _width, _height, // Display w/h as modified by current rotation 80 | cursor_x, cursor_y; 81 | uint16_t 82 | textcolor, textbgcolor; 83 | uint8_t 84 | textsize, 85 | rotation; 86 | boolean 87 | wrap; // If set, 'wrap' text at right edge of display 88 | }; 89 | 90 | #endif // _ADAFRUIT_GFX_H 91 | -------------------------------------------------------------------------------- /libraries/Adafruit_TFTLCD/Adafruit_TFTLCD.h: -------------------------------------------------------------------------------- 1 | // IMPORTANT: SEE COMMENTS @ LINE 15 REGARDING SHIELD VS BREAKOUT BOARD USAGE. 2 | 3 | // Graphics library by ladyada/adafruit with init code from Rossum 4 | // MIT license 5 | 6 | #ifndef _ADAFRUIT_TFTLCD_H_ 7 | #define _ADAFRUIT_TFTLCD_H_ 8 | 9 | #if ARDUINO >= 100 10 | #include "Arduino.h" 11 | #else 12 | #include "WProgram.h" 13 | #endif 14 | 15 | #include 16 | 17 | // **** IF USING THE LCD BREAKOUT BOARD, COMMENT OUT THIS NEXT LINE. **** 18 | // **** IF USING THE LCD SHIELD, LEAVE THE LINE ENABLED: **** 19 | 20 | //#define USE_ADAFRUIT_SHIELD_PINOUT 1 21 | 22 | class Adafruit_TFTLCD : public Adafruit_GFX { 23 | 24 | public: 25 | 26 | Adafruit_TFTLCD(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t rst); 27 | Adafruit_TFTLCD(void); 28 | 29 | void begin(uint16_t id = 0x9325); 30 | void drawPixel(int16_t x, int16_t y, uint16_t color); 31 | void drawFastHLine(int16_t x0, int16_t y0, int16_t w, uint16_t color); 32 | void drawFastVLine(int16_t x0, int16_t y0, int16_t h, uint16_t color); 33 | void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t c); 34 | void fillScreen(uint16_t color); 35 | void reset(void); 36 | void setRegisters8(uint8_t *ptr, uint8_t n); 37 | void setRegisters16(uint16_t *ptr, uint8_t n); 38 | void setRotation(uint8_t x); 39 | // These methods are public in order for BMP examples to work: 40 | void setAddrWindow(int x1, int y1, int x2, int y2); 41 | void pushColors(uint16_t *data, uint8_t len, boolean first); 42 | 43 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b), 44 | readPixel(int16_t x, int16_t y), 45 | readID(void); 46 | uint32_t readReg(uint8_t r); 47 | 48 | private: 49 | 50 | void init(), 51 | // These items may have previously been defined as macros 52 | // in pin_magic.h. If not, function versions are declared: 53 | #ifndef write8 54 | write8(uint8_t value), 55 | #endif 56 | #ifndef setWriteDir 57 | setWriteDir(void), 58 | #endif 59 | #ifndef setReadDir 60 | setReadDir(void), 61 | #endif 62 | #ifndef writeRegister8 63 | writeRegister8(uint8_t a, uint8_t d), 64 | #endif 65 | #ifndef writeRegister16 66 | writeRegister16(uint16_t a, uint16_t d), 67 | #endif 68 | writeRegister24(uint8_t a, uint32_t d), 69 | writeRegister32(uint8_t a, uint32_t d), 70 | #ifndef writeRegisterPair 71 | writeRegisterPair(uint8_t aH, uint8_t aL, uint16_t d), 72 | #endif 73 | setLR(void), 74 | flood(uint16_t color, uint32_t len); 75 | uint8_t driver; 76 | 77 | #ifndef read8 78 | uint8_t read8fn(void); 79 | #define read8isFunctionalized 80 | #endif 81 | 82 | #ifndef USE_ADAFRUIT_SHIELD_PINOUT 83 | 84 | #ifdef __AVR__ 85 | volatile uint8_t *csPort , *cdPort , *wrPort , *rdPort; 86 | uint8_t csPinSet , cdPinSet , wrPinSet , rdPinSet , 87 | csPinUnset, cdPinUnset, wrPinUnset, rdPinUnset, 88 | _reset; 89 | #endif 90 | #if defined(__SAM3X8E__) 91 | Pio *csPort , *cdPort , *wrPort , *rdPort; 92 | uint32_t csPinSet , cdPinSet , wrPinSet , rdPinSet , 93 | csPinUnset, cdPinUnset, wrPinUnset, rdPinUnset, 94 | _reset; 95 | #endif 96 | 97 | #endif 98 | }; 99 | 100 | // For compatibility with sketches written for older versions of library. 101 | // Color function name was changed to 'color565' for parity with 2.2" LCD 102 | // library. 103 | #define Color565 color565 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /libraries/Adafruit_TFTLCD/pin_magic_UNO.h: -------------------------------------------------------------------------------- 1 | #ifndef _pin_magic_ 2 | #define _pin_magic_ 3 | // This header file serves two purposes: 4 | // 5 | // 1) Isolate non-portable MCU port- and pin-specific identifiers and 6 | // operations so the library code itself remains somewhat agnostic 7 | // (PORTs and pin numbers are always referenced through macros). 8 | // 9 | // 2) GCC doesn't always respect the "inline" keyword, so this is a 10 | // ham-fisted manner of forcing the issue to minimize function calls. 11 | // This sometimes makes the library a bit bigger than before, but fast++. 12 | // However, because they're macros, we need to be SUPER CAREFUL about 13 | // parameters -- for example, write8(x) may expand to multiple PORT 14 | // writes that all refer to x, so it needs to be a constant or fixed 15 | // variable and not something like *ptr++ (which, after macro 16 | // expansion, may increment the pointer repeatedly and run off into 17 | // la-la land). Macros also give us fine-grained control over which 18 | // operations are inlined on which boards (balancing speed against 19 | // available program space). 20 | // When using the TFT shield, control and data pins exist in set physical 21 | // locations, but the ports and bitmasks corresponding to each vary among 22 | // boards. A separate set of pin definitions is given for each supported 23 | // board type. 24 | // When using the TFT breakout board, control pins are configurable but 25 | // the data pins are still fixed -- making every data pin configurable 26 | // would be much too slow. The data pin layouts are not the same between 27 | // the shield and breakout configurations -- for the latter, pins were 28 | // chosen to keep the tutorial wiring manageable more than making optimal 29 | // use of ports and bitmasks. So there's a second set of pin definitions 30 | // given for each supported board. 31 | // Shield pin usage: 32 | 33 | // Breakout pin usage: 34 | // LCD Data Bit : 7 6 5 4 3 2 1 0 35 | // Uno dig. pin : 7 6 5 4 3 2 9 8 36 | // Uno port/pin : PD7 PD6 PD5 PD4 PD3 PD2 PB1 PB0 37 | // Mega dig. pin: 27 6 5 4 3 2 9 8 38 | // Mega port/pin: PH4 PH3 PE3 PG5 PE5 PE4 PH6 PH5 39 | 40 | // Pixel read operations require a minimum 400 nS delay from RD_ACTIVE 41 | // to polling the input pins. At 16 MHz, one machine cycle is 62.5 nS. 42 | // This code burns 7 cycles (437.5 nS) doing nothing; the RJMPs are 43 | // equivalent to two NOPs each, final NOP burns the 7th cycle, and the 44 | // last line is a radioactive mutant emoticon. 45 | #define DELAY7 \ 46 | asm volatile( \ 47 | "rjmp .+0" "\n\t" \ 48 | "rjmp .+0" "\n\t" \ 49 | "rjmp .+0" "\n\t" \ 50 | "nop" "\n" \ 51 | ::); 52 | // As part of the inline control, macros reference other macros...if any 53 | // of these are left undefined, an equivalent function version (non-inline) 54 | // is declared later. The Uno has a moderate amount of program space, so 55 | // only write8() is inlined -- that one provides the most performance 56 | // benefit, but unfortunately also generates the most bloat. This is 57 | // why only certain cases are inlined for each board. 58 | //Uno w/Breakout board 59 | // Uno dig. pin : 7 6 5 4 3 2 9 8 60 | // Uno port/pin : PD7 PD6 PD5 PD4 PD3 PD2 PB1 PB0 61 | #define write8inline(d) { \ 62 | PORTD = (PORTD & B00000011) | ((d) & B11111100); \ 63 | PORTB = (PORTB & B11111100) | ((d) & B00000011); \ 64 | WR_STROBE; } 65 | #define read8inline(result) { \ 66 | RD_ACTIVE; \ 67 | DELAY7; \ 68 | result = (PIND & B11111100) | (PINB & B00000011); \ 69 | RD_IDLE; } 70 | #define setWriteDirInline() { DDRD |= B11111100; DDRB |= B00000011; } 71 | #define setReadDirInline() { DDRD &= ~B11111100; DDRB &= ~B00000011; } 72 | 73 | 74 | 75 | // All of the functions are inlined on the Arduino Mega. When using the 76 | // breakout board, the macro versions aren't appreciably larger than the 77 | // function equivalents, and they're super simple and fast. When using 78 | // the shield, the macros become pretty complicated...but this board has 79 | // so much code space, the macros are used anyway. If you need to free 80 | // up program space, some macros can be removed, at a minor cost in speed. 81 | #define write8 write8inline 82 | #define read8 read8inline 83 | #define setWriteDir setWriteDirInline 84 | #define setReadDir setReadDirInline 85 | #define writeRegister8 writeRegister8inline 86 | #define writeRegister16 writeRegister16inline 87 | #define writeRegisterPair writeRegisterPairInline 88 | // When using the TFT breakout board, control pins are configurable. 89 | #define RD_ACTIVE *rdPort &= rdPinUnset 90 | #define RD_IDLE *rdPort |= rdPinSet 91 | #define WR_ACTIVE *wrPort &= wrPinUnset 92 | #define WR_IDLE *wrPort |= wrPinSet 93 | #define CD_COMMAND *cdPort &= cdPinUnset 94 | #define CD_DATA *cdPort |= cdPinSet 95 | #define CS_ACTIVE *csPort &= csPinUnset 96 | #define CS_IDLE *csPort |= csPinSet 97 | #endif 98 | // Data read and write strobes, ~2 instructions and always inline 99 | #define RD_STROBE { RD_ACTIVE; RD_IDLE; } 100 | #define WR_STROBE { WR_ACTIVE; WR_IDLE; } 101 | // These higher-level operations are usually functionalized, 102 | // except on Mega where's there's gobs and gobs of program space. 103 | // Set value of TFT register: 8-bit address, 8-bit value 104 | #define writeRegister8inline(a, d) { \ 105 | CD_COMMAND; write8(a); CD_DATA; write8(d); } 106 | // Set value of TFT register: 16-bit address, 16-bit value 107 | // See notes at top about macro expansion, hence hi & lo temp vars 108 | #define writeRegister16inline(a, d) { \ 109 | uint8_t hi, lo; \ 110 | hi = (a) >> 8; lo = (a); CD_COMMAND; write8(hi); write8(lo); \ 111 | hi = (d) >> 8; lo = (d); CD_DATA ; write8(hi); write8(lo); } 112 | // Set value of 2 TFT registers: Two 8-bit addresses (hi & lo), 16-bit value 113 | #define writeRegisterPairInline(aH, aL, d) { \ 114 | uint8_t hi = (d) >> 8, lo = (d); \ 115 | CD_COMMAND; write8(aH); CD_DATA; write8(hi); \ 116 | CD_COMMAND; write8(aL); CD_DATA; write8(lo); } 117 | 118 | -------------------------------------------------------------------------------- /libraries/Adafruit_TFTLCD/registers.h: -------------------------------------------------------------------------------- 1 | // Register names from Peter Barrett's Microtouch code 2 | #define ILI932X_START_OSC 0x00 3 | #define ILI932X_DRIV_OUT_CTRL 0x01 4 | #define ILI932X_DRIV_WAV_CTRL 0x02 5 | #define ILI932X_ENTRY_MOD 0x03 6 | #define ILI932X_RESIZE_CTRL 0x04 7 | #define ILI932X_DISP_CTRL1 0x07 8 | #define ILI932X_DISP_CTRL2 0x08 9 | #define ILI932X_DISP_CTRL3 0x09 10 | #define ILI932X_DISP_CTRL4 0x0A 11 | #define ILI932X_RGB_DISP_IF_CTRL1 0x0C 12 | #define ILI932X_FRM_MARKER_POS 0x0D 13 | #define ILI932X_RGB_DISP_IF_CTRL2 0x0F 14 | #define ILI932X_POW_CTRL1 0x10 15 | #define ILI932X_POW_CTRL2 0x11 16 | #define ILI932X_POW_CTRL3 0x12 17 | #define ILI932X_POW_CTRL4 0x13 18 | #define ILI932X_GRAM_HOR_AD 0x20 19 | #define ILI932X_GRAM_VER_AD 0x21 20 | #define ILI932X_RW_GRAM 0x22 21 | #define ILI932X_POW_CTRL7 0x29 22 | #define ILI932X_FRM_RATE_COL_CTRL 0x2B 23 | #define ILI932X_GAMMA_CTRL1 0x30 24 | #define ILI932X_GAMMA_CTRL2 0x31 25 | #define ILI932X_GAMMA_CTRL3 0x32 26 | #define ILI932X_GAMMA_CTRL4 0x35 27 | #define ILI932X_GAMMA_CTRL5 0x36 28 | #define ILI932X_GAMMA_CTRL6 0x37 29 | #define ILI932X_GAMMA_CTRL7 0x38 30 | #define ILI932X_GAMMA_CTRL8 0x39 31 | #define ILI932X_GAMMA_CTRL9 0x3C 32 | #define ILI932X_GAMMA_CTRL10 0x3D 33 | #define ILI932X_HOR_START_AD 0x50 34 | #define ILI932X_HOR_END_AD 0x51 35 | #define ILI932X_VER_START_AD 0x52 36 | #define ILI932X_VER_END_AD 0x53 37 | #define ILI932X_GATE_SCAN_CTRL1 0x60 38 | #define ILI932X_GATE_SCAN_CTRL2 0x61 39 | #define ILI932X_GATE_SCAN_CTRL3 0x6A 40 | #define ILI932X_PART_IMG1_DISP_POS 0x80 41 | #define ILI932X_PART_IMG1_START_AD 0x81 42 | #define ILI932X_PART_IMG1_END_AD 0x82 43 | #define ILI932X_PART_IMG2_DISP_POS 0x83 44 | #define ILI932X_PART_IMG2_START_AD 0x84 45 | #define ILI932X_PART_IMG2_END_AD 0x85 46 | #define ILI932X_PANEL_IF_CTRL1 0x90 47 | #define ILI932X_PANEL_IF_CTRL2 0x92 48 | #define ILI932X_PANEL_IF_CTRL3 0x93 49 | #define ILI932X_PANEL_IF_CTRL4 0x95 50 | #define ILI932X_PANEL_IF_CTRL5 0x97 51 | #define ILI932X_PANEL_IF_CTRL6 0x98 52 | 53 | #define HX8347G_COLADDRSTART_HI 0x02 54 | #define HX8347G_COLADDRSTART_LO 0x03 55 | #define HX8347G_COLADDREND_HI 0x04 56 | #define HX8347G_COLADDREND_LO 0x05 57 | #define HX8347G_ROWADDRSTART_HI 0x06 58 | #define HX8347G_ROWADDRSTART_LO 0x07 59 | #define HX8347G_ROWADDREND_HI 0x08 60 | #define HX8347G_ROWADDREND_LO 0x09 61 | #define HX8347G_MEMACCESS 0x16 62 | 63 | 64 | 65 | #define ILI9341_SOFTRESET 0x01 66 | #define ILI9341_SLEEPIN 0x10 67 | #define ILI9341_SLEEPOUT 0x11 68 | #define ILI9341_NORMALDISP 0x13 69 | #define ILI9341_INVERTOFF 0x20 70 | #define ILI9341_INVERTON 0x21 71 | #define ILI9341_GAMMASET 0x26 72 | #define ILI9341_DISPLAYOFF 0x28 73 | #define ILI9341_DISPLAYON 0x29 74 | #define ILI9341_COLADDRSET 0x2A 75 | #define ILI9341_PAGEADDRSET 0x2B 76 | #define ILI9341_MEMORYWRITE 0x2C 77 | #define ILI9341_PIXELFORMAT 0x3A 78 | #define ILI9341_FRAMECONTROL 0xB1 79 | #define ILI9341_DISPLAYFUNC 0xB6 80 | #define ILI9341_ENTRYMODE 0xB7 81 | #define ILI9341_POWERCONTROL1 0xC0 82 | #define ILI9341_POWERCONTROL2 0xC1 83 | #define ILI9341_VCOMCONTROL1 0xC5 84 | #define ILI9341_VCOMCONTROL2 0xC7 85 | #define ILI9341_MEMCONTROL 0x36 86 | #define ILI9341_MADCTL 0x36 87 | 88 | #define ILI9341_MADCTL_MY 0x80 89 | #define ILI9341_MADCTL_MX 0x40 90 | #define ILI9341_MADCTL_MV 0x20 91 | #define ILI9341_MADCTL_ML 0x10 92 | #define ILI9341_MADCTL_RGB 0x00 93 | #define ILI9341_MADCTL_BGR 0x08 94 | #define ILI9341_MADCTL_MH 0x04 95 | 96 | 97 | 98 | #define HX8357_NOP 0x00 99 | #define HX8357_SWRESET 0x01 100 | #define HX8357_RDDID 0x04 101 | #define HX8357_RDDST 0x09 102 | 103 | #define HX8357B_RDPOWMODE 0x0A 104 | #define HX8357B_RDMADCTL 0x0B 105 | #define HX8357B_RDCOLMOD 0x0C 106 | #define HX8357B_RDDIM 0x0D 107 | #define HX8357B_RDDSDR 0x0F 108 | 109 | #define HX8357_SLPIN 0x10 110 | #define HX8357_SLPOUT 0x11 111 | #define HX8357B_PTLON 0x12 112 | #define HX8357B_NORON 0x13 113 | 114 | #define HX8357_INVOFF 0x20 115 | #define HX8357_INVON 0x21 116 | #define HX8357_DISPOFF 0x28 117 | #define HX8357_DISPON 0x29 118 | 119 | #define HX8357_CASET 0x2A 120 | #define HX8357_PASET 0x2B 121 | #define HX8357_RAMWR 0x2C 122 | #define HX8357_RAMRD 0x2E 123 | 124 | #define HX8357B_PTLAR 0x30 125 | #define HX8357_TEON 0x35 126 | #define HX8357_TEARLINE 0x44 127 | #define HX8357_MADCTL 0x36 128 | #define HX8357_COLMOD 0x3A 129 | 130 | #define HX8357_SETOSC 0xB0 131 | #define HX8357_SETPWR1 0xB1 132 | #define HX8357B_SETDISPLAY 0xB2 133 | #define HX8357_SETRGB 0xB3 134 | #define HX8357D_SETCOM 0xB6 135 | 136 | #define HX8357B_SETDISPMODE 0xB4 137 | #define HX8357D_SETCYC 0xB4 138 | #define HX8357B_SETOTP 0xB7 139 | #define HX8357D_SETC 0xB9 140 | 141 | #define HX8357B_SET_PANEL_DRIVING 0xC0 142 | #define HX8357D_SETSTBA 0xC0 143 | #define HX8357B_SETDGC 0xC1 144 | #define HX8357B_SETID 0xC3 145 | #define HX8357B_SETDDB 0xC4 146 | #define HX8357B_SETDISPLAYFRAME 0xC5 147 | #define HX8357B_GAMMASET 0xC8 148 | #define HX8357B_SETCABC 0xC9 149 | #define HX8357_SETPANEL 0xCC 150 | 151 | 152 | #define HX8357B_SETPOWER 0xD0 153 | #define HX8357B_SETVCOM 0xD1 154 | #define HX8357B_SETPWRNORMAL 0xD2 155 | 156 | #define HX8357B_RDID1 0xDA 157 | #define HX8357B_RDID2 0xDB 158 | #define HX8357B_RDID3 0xDC 159 | #define HX8357B_RDID4 0xDD 160 | 161 | #define HX8357D_SETGAMMA 0xE0 162 | 163 | #define HX8357B_SETGAMMA 0xC8 164 | #define HX8357B_SETPANELRELATED 0xE9 165 | 166 | #define HX8357B_MADCTL_MY 0x80 167 | #define HX8357B_MADCTL_MX 0x40 168 | #define HX8357B_MADCTL_MV 0x20 169 | #define HX8357B_MADCTL_ML 0x10 170 | #define HX8357B_MADCTL_RGB 0x00 171 | #define HX8357B_MADCTL_BGR 0x08 172 | #define HX8357B_MADCTL_MH 0x04 173 | -------------------------------------------------------------------------------- /libraries/TouchScreen/TouchScreen.cpp: -------------------------------------------------------------------------------- 1 | // Touch screen library with X Y and Z (pressure) readings as well 2 | // as oversampling to avoid 'bouncing' 3 | // (c) ladyada / adafruit 4 | // Code under MIT License 5 | 6 | #include "pins_arduino.h" 7 | #include "wiring_private.h" 8 | #include 9 | #include "TouchScreen.h" 10 | 11 | // increase or decrease the touchscreen oversampling. This is a little different than you make think: 12 | // 1 is no oversampling, whatever data we get is immediately returned 13 | // 2 is double-sampling and we only return valid data if both points are the same 14 | // 3+ uses insert sort to get the median value. 15 | // We found 2 is precise yet not too slow so we suggest sticking with it! 16 | 17 | #define NUMSAMPLES 2 18 | 19 | TSPoint::TSPoint(void) { 20 | x = y = 0; 21 | } 22 | 23 | TSPoint::TSPoint(int16_t x0, int16_t y0, int16_t z0) { 24 | x = x0; 25 | y = y0; 26 | z = z0; 27 | } 28 | 29 | bool TSPoint::operator==(TSPoint p1) { 30 | return ((p1.x == x) && (p1.y == y) && (p1.z == z)); 31 | } 32 | 33 | bool TSPoint::operator!=(TSPoint p1) { 34 | return ((p1.x != x) || (p1.y != y) || (p1.z != z)); 35 | } 36 | 37 | #if (NUMSAMPLES > 2) 38 | static void insert_sort(int array[], uint8_t size) { 39 | uint8_t j; 40 | int save; 41 | 42 | for (int i = 1; i < size; i++) { 43 | save = array[i]; 44 | for (j = i; j >= 1 && save < array[j - 1]; j--) 45 | array[j] = array[j - 1]; 46 | array[j] = save; 47 | } 48 | } 49 | #endif 50 | 51 | TSPoint TouchScreen::getPoint(void) { 52 | int x, y, z; 53 | int samples[NUMSAMPLES]; 54 | uint8_t i, valid; 55 | 56 | 57 | uint8_t xp_port = digitalPinToPort(_xp); 58 | uint8_t yp_port = digitalPinToPort(_yp); 59 | uint8_t xm_port = digitalPinToPort(_xm); 60 | uint8_t ym_port = digitalPinToPort(_ym); 61 | 62 | uint8_t xp_pin = digitalPinToBitMask(_xp); 63 | uint8_t yp_pin = digitalPinToBitMask(_yp); 64 | uint8_t xm_pin = digitalPinToBitMask(_xm); 65 | uint8_t ym_pin = digitalPinToBitMask(_ym); 66 | 67 | 68 | valid = 1; 69 | 70 | pinMode(_yp, INPUT); 71 | pinMode(_ym, INPUT); 72 | 73 | *portOutputRegister(yp_port) &= ~yp_pin; 74 | *portOutputRegister(ym_port) &= ~ym_pin; 75 | //digitalWrite(_yp, LOW); 76 | //digitalWrite(_ym, LOW); 77 | 78 | pinMode(_xp, OUTPUT); 79 | pinMode(_xm, OUTPUT); 80 | //digitalWrite(_xp, HIGH); 81 | //digitalWrite(_xm, LOW); 82 | *portOutputRegister(xp_port) |= xp_pin; 83 | *portOutputRegister(xm_port) &= ~xm_pin; 84 | 85 | for (i=0; i 2 89 | insert_sort(samples, NUMSAMPLES); 90 | #endif 91 | #if NUMSAMPLES == 2 92 | if (samples[0] != samples[1]) { valid = 0; } 93 | #endif 94 | x = (1023-samples[NUMSAMPLES/2]); 95 | 96 | pinMode(_xp, INPUT); 97 | pinMode(_xm, INPUT); 98 | *portOutputRegister(xp_port) &= ~xp_pin; 99 | //digitalWrite(_xp, LOW); 100 | 101 | pinMode(_yp, OUTPUT); 102 | *portOutputRegister(yp_port) |= yp_pin; 103 | //digitalWrite(_yp, HIGH); 104 | pinMode(_ym, OUTPUT); 105 | 106 | for (i=0; i 2 111 | insert_sort(samples, NUMSAMPLES); 112 | #endif 113 | #if NUMSAMPLES == 2 114 | if (samples[0] != samples[1]) { valid = 0; } 115 | #endif 116 | 117 | y = (1023-samples[NUMSAMPLES/2]); 118 | 119 | // Set X+ to ground 120 | pinMode(_xp, OUTPUT); 121 | *portOutputRegister(xp_port) &= ~xp_pin; 122 | //digitalWrite(_xp, LOW); 123 | 124 | // Set Y- to VCC 125 | *portOutputRegister(ym_port) |= ym_pin; 126 | //digitalWrite(_ym, HIGH); 127 | 128 | // Hi-Z X- and Y+ 129 | *portOutputRegister(yp_port) &= ~yp_pin; 130 | //digitalWrite(_yp, LOW); 131 | pinMode(_yp, INPUT); 132 | 133 | int z1 = analogRead(_xm); 134 | int z2 = analogRead(_yp); 135 | 136 | if (_rxplate != 0) { 137 | // now read the x 138 | float rtouch; 139 | rtouch = z2; 140 | rtouch /= z1; 141 | rtouch -= 1; 142 | rtouch *= x; 143 | rtouch *= _rxplate; 144 | rtouch /= 1024; 145 | 146 | z = rtouch; 147 | } else { 148 | z = (1023-(z2-z1)); 149 | } 150 | 151 | if (! valid) { 152 | z = 0; 153 | } 154 | 155 | return TSPoint(x, y, z); 156 | } 157 | 158 | TouchScreen::TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym) { 159 | _yp = yp; 160 | _xm = xm; 161 | _ym = ym; 162 | _xp = xp; 163 | _rxplate = 0; 164 | pressureThreshhold = 10; 165 | } 166 | 167 | 168 | TouchScreen::TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym, 169 | uint16_t rxplate) { 170 | _yp = yp; 171 | _xm = xm; 172 | _ym = ym; 173 | _xp = xp; 174 | _rxplate = rxplate; 175 | 176 | pressureThreshhold = 10; 177 | } 178 | 179 | int TouchScreen::readTouchX(void) { 180 | pinMode(_yp, INPUT); 181 | pinMode(_ym, INPUT); 182 | digitalWrite(_yp, LOW); 183 | digitalWrite(_ym, LOW); 184 | 185 | pinMode(_xp, OUTPUT); 186 | digitalWrite(_xp, HIGH); 187 | pinMode(_xm, OUTPUT); 188 | digitalWrite(_xm, LOW); 189 | 190 | return (1023-analogRead(_yp)); 191 | } 192 | 193 | 194 | int TouchScreen::readTouchY(void) { 195 | pinMode(_xp, INPUT); 196 | pinMode(_xm, INPUT); 197 | digitalWrite(_xp, LOW); 198 | digitalWrite(_xm, LOW); 199 | 200 | pinMode(_yp, OUTPUT); 201 | digitalWrite(_yp, HIGH); 202 | pinMode(_ym, OUTPUT); 203 | digitalWrite(_ym, LOW); 204 | 205 | return (1023-analogRead(_xm)); 206 | } 207 | 208 | 209 | uint16_t TouchScreen::pressure(void) { 210 | // Set X+ to ground 211 | pinMode(_xp, OUTPUT); 212 | digitalWrite(_xp, LOW); 213 | 214 | // Set Y- to VCC 215 | pinMode(_ym, OUTPUT); 216 | digitalWrite(_ym, HIGH); 217 | 218 | // Hi-Z X- and Y+ 219 | digitalWrite(_xm, LOW); 220 | pinMode(_xm, INPUT); 221 | digitalWrite(_yp, LOW); 222 | pinMode(_yp, INPUT); 223 | 224 | int z1 = analogRead(_xm); 225 | int z2 = analogRead(_yp); 226 | 227 | if (_rxplate != 0) { 228 | // now read the x 229 | float rtouch; 230 | rtouch = z2; 231 | rtouch /= z1; 232 | rtouch -= 1; 233 | rtouch *= readTouchX(); 234 | rtouch *= _rxplate; 235 | rtouch /= 1024; 236 | 237 | return rtouch; 238 | } else { 239 | return (1023-(z2-z1)); 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /libraries/Adafruit_TFTLCD/pin_magic_MEGA.h: -------------------------------------------------------------------------------- 1 | #ifndef _pin_magic_ 2 | #define _pin_magic_ 3 | // This header file serves two purposes: 4 | // 5 | // 1) Isolate non-portable MCU port- and pin-specific identifiers and 6 | // operations so the library code itself remains somewhat agnostic 7 | // (PORTs and pin numbers are always referenced through macros). 8 | // 9 | // 2) GCC doesn't always respect the "inline" keyword, so this is a 10 | // ham-fisted manner of forcing the issue to minimize function calls. 11 | // This sometimes makes the library a bit bigger than before, but fast++. 12 | // However, because they're macros, we need to be SUPER CAREFUL about 13 | // parameters -- for example, write8(x) may expand to multiple PORT 14 | // writes that all refer to x, so it needs to be a constant or fixed 15 | // variable and not something like *ptr++ (which, after macro 16 | // expansion, may increment the pointer repeatedly and run off into 17 | // la-la land). Macros also give us fine-grained control over which 18 | // operations are inlined on which boards (balancing speed against 19 | // available program space). 20 | // When using the TFT shield, control and data pins exist in set physical 21 | // locations, but the ports and bitmasks corresponding to each vary among 22 | // boards. A separate set of pin definitions is given for each supported 23 | // board type. 24 | // When using the TFT breakout board, control pins are configurable but 25 | // the data pins are still fixed -- making every data pin configurable 26 | // would be much too slow. The data pin layouts are not the same between 27 | // the shield and breakout configurations -- for the latter, pins were 28 | // chosen to keep the tutorial wiring manageable more than making optimal 29 | // use of ports and bitmasks. So there's a second set of pin definitions 30 | // given for each supported board. 31 | // Shield pin usage: 32 | 33 | // Breakout pin usage: 34 | // LCD Data Bit : 7 6 5 4 3 2 1 0 35 | // Uno dig. pin : 7 6 5 4 3 2 9 8 36 | // Uno port/pin : PD7 PD6 PD5 PD4 PD3 PD2 PB1 PB0 37 | // Mega dig. pin: 27 6 5 4 3 2 9 8 38 | // Mega port/pin: PH4 PH3 PE3 PG5 PE5 PE4 PH6 PH5 39 | 40 | // Pixel read operations require a minimum 400 nS delay from RD_ACTIVE 41 | // to polling the input pins. At 16 MHz, one machine cycle is 62.5 nS. 42 | // This code burns 7 cycles (437.5 nS) doing nothing; the RJMPs are 43 | // equivalent to two NOPs each, final NOP burns the 7th cycle, and the 44 | // last line is a radioactive mutant emoticon. 45 | #define DELAY7 \ 46 | asm volatile( \ 47 | "rjmp .+0" "\n\t" \ 48 | "rjmp .+0" "\n\t" \ 49 | "rjmp .+0" "\n\t" \ 50 | "nop" "\n" \ 51 | ::); 52 | 53 | 54 | // As part of the inline control, macros reference other macros...if any 55 | // of these are left undefined, an equivalent function version (non-inline) 56 | // is declared later. The Uno has a moderate amount of program space, so 57 | // only write8() is inlined -- that one provides the most performance 58 | // benefit, but unfortunately also generates the most bloat. This is 59 | // why only certain cases are inlined for each board. 60 | 61 | 62 | // Arduino Mega, ADK, etc. 63 | // Mega port/pin: PH4 PH3 PE3 PG5 PE5 PE4 PH6 PH5 64 | // Because the MEGA port to pin mapping is very messy it is necessary to shift the data bits around a lot. 65 | #define write8inline(d) { \ 66 | PORTE = (PORTE & B11001111) | ((d << 2) & B00110000); \ 67 | PORTE = (PORTE & B11110111) | ((d >> 2) & B00001000); \ 68 | PORTG = (PORTG & B11011111) | ((d << 1) & B00100000); \ 69 | PORTH = (PORTH & B11100111) | ((d >> 3) & B00011000); \ 70 | PORTH = (PORTH & B10011111) | ((d << 5) & B01100000); \ 71 | WR_STROBE; } 72 | #define read8inline(result) { \ 73 | RD_ACTIVE; \ 74 | DELAY7; \ 75 | result = ((PINH & B00011000) << 3) | ((PINE & B00001000) << 2) | ((PING & B00100000) >> 1) |((PINE & B00110000) >> 2) | ((PINH & B01100000) >> 5); \ 76 | RD_IDLE; } 77 | 78 | // // These set the PORT directions as required before the write and read 79 | // // operations. 80 | #define setWriteDirInline() { DDRE |= B00111000; DDRG |= B00100000; DDRH |= B01111000;} 81 | #define setReadDirInline() { DDRE &= ~B00111000; DDRG &= ~B00100000; DDRH &= ~B01111000;} 82 | 83 | 84 | // All of the functions are inlined on the Arduino Mega. When using the 85 | // breakout board, the macro versions aren't appreciably larger than the 86 | // function equivalents, and they're super simple and fast. When using 87 | // the shield, the macros become pretty complicated...but this board has 88 | // so much code space, the macros are used anyway. If you need to free 89 | // up program space, some macros can be removed, at a minor cost in speed. 90 | #define write8 write8inline 91 | #define read8 read8inline 92 | #define setWriteDir setWriteDirInline 93 | #define setReadDir setReadDirInline 94 | #define writeRegister8 writeRegister8inline 95 | #define writeRegister16 writeRegister16inline 96 | #define writeRegisterPair writeRegisterPairInline 97 | // When using the TFT breakout board, control pins are configurable. 98 | #define RD_ACTIVE *rdPort &= rdPinUnset 99 | #define RD_IDLE *rdPort |= rdPinSet 100 | #define WR_ACTIVE *wrPort &= wrPinUnset 101 | #define WR_IDLE *wrPort |= wrPinSet 102 | #define CD_COMMAND *cdPort &= cdPinUnset 103 | #define CD_DATA *cdPort |= cdPinSet 104 | #define CS_ACTIVE *csPort &= csPinUnset 105 | #define CS_IDLE *csPort |= csPinSet 106 | #endif 107 | // Data read and write strobes, ~2 instructions and always inline 108 | #define RD_STROBE { RD_ACTIVE; RD_IDLE; } 109 | #define WR_STROBE { WR_ACTIVE; WR_IDLE; } 110 | // These higher-level operations are usually functionalized, 111 | // except on Mega where's there's gobs and gobs of program space. 112 | // Set value of TFT register: 8-bit address, 8-bit value 113 | #define writeRegister8inline(a, d) { \ 114 | CD_COMMAND; write8(a); CD_DATA; write8(d); } 115 | // Set value of TFT register: 16-bit address, 16-bit value 116 | // See notes at top about macro expansion, hence hi & lo temp vars 117 | #define writeRegister16inline(a, d) { \ 118 | uint8_t hi, lo; \ 119 | hi = (a) >> 8; lo = (a); CD_COMMAND; write8(hi); write8(lo); \ 120 | hi = (d) >> 8; lo = (d); CD_DATA ; write8(hi); write8(lo); } 121 | // Set value of 2 TFT registers: Two 8-bit addresses (hi & lo), 16-bit value 122 | #define writeRegisterPairInline(aH, aL, d) { \ 123 | uint8_t hi = (d) >> 8, lo = (d); \ 124 | CD_COMMAND; write8(aH); CD_DATA; write8(hi); \ 125 | CD_COMMAND; write8(aL); CD_DATA; write8(lo); } 126 | 127 | -------------------------------------------------------------------------------- /libraries/Adafruit_GFX/glcdfont.c: -------------------------------------------------------------------------------- 1 | #ifndef FONT5X7_H 2 | #define FONT5X7_H 3 | 4 | #ifdef __AVR__ 5 | #include 6 | #include 7 | #else 8 | #define PROGMEM 9 | #endif 10 | 11 | // Standard ASCII 5x7 font 12 | 13 | static const unsigned char font[] PROGMEM = { 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 16 | 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 17 | 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 18 | 0x18, 0x3C, 0x7E, 0x3C, 0x18, 19 | 0x1C, 0x57, 0x7D, 0x57, 0x1C, 20 | 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 21 | 0x00, 0x18, 0x3C, 0x18, 0x00, 22 | 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 23 | 0x00, 0x18, 0x24, 0x18, 0x00, 24 | 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 25 | 0x30, 0x48, 0x3A, 0x06, 0x0E, 26 | 0x26, 0x29, 0x79, 0x29, 0x26, 27 | 0x40, 0x7F, 0x05, 0x05, 0x07, 28 | 0x40, 0x7F, 0x05, 0x25, 0x3F, 29 | 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 30 | 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 31 | 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 32 | 0x14, 0x22, 0x7F, 0x22, 0x14, 33 | 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 34 | 0x06, 0x09, 0x7F, 0x01, 0x7F, 35 | 0x00, 0x66, 0x89, 0x95, 0x6A, 36 | 0x60, 0x60, 0x60, 0x60, 0x60, 37 | 0x94, 0xA2, 0xFF, 0xA2, 0x94, 38 | 0x08, 0x04, 0x7E, 0x04, 0x08, 39 | 0x10, 0x20, 0x7E, 0x20, 0x10, 40 | 0x08, 0x08, 0x2A, 0x1C, 0x08, 41 | 0x08, 0x1C, 0x2A, 0x08, 0x08, 42 | 0x1E, 0x10, 0x10, 0x10, 0x10, 43 | 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 44 | 0x30, 0x38, 0x3E, 0x38, 0x30, 45 | 0x06, 0x0E, 0x3E, 0x0E, 0x06, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x5F, 0x00, 0x00, 48 | 0x00, 0x07, 0x00, 0x07, 0x00, 49 | 0x14, 0x7F, 0x14, 0x7F, 0x14, 50 | 0x24, 0x2A, 0x7F, 0x2A, 0x12, 51 | 0x23, 0x13, 0x08, 0x64, 0x62, 52 | 0x36, 0x49, 0x56, 0x20, 0x50, 53 | 0x00, 0x08, 0x07, 0x03, 0x00, 54 | 0x00, 0x1C, 0x22, 0x41, 0x00, 55 | 0x00, 0x41, 0x22, 0x1C, 0x00, 56 | 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 57 | 0x08, 0x08, 0x3E, 0x08, 0x08, 58 | 0x00, 0x80, 0x70, 0x30, 0x00, 59 | 0x08, 0x08, 0x08, 0x08, 0x08, 60 | 0x00, 0x00, 0x60, 0x60, 0x00, 61 | 0x20, 0x10, 0x08, 0x04, 0x02, 62 | 0x3E, 0x51, 0x49, 0x45, 0x3E, 63 | 0x00, 0x42, 0x7F, 0x40, 0x00, 64 | 0x72, 0x49, 0x49, 0x49, 0x46, 65 | 0x21, 0x41, 0x49, 0x4D, 0x33, 66 | 0x18, 0x14, 0x12, 0x7F, 0x10, 67 | 0x27, 0x45, 0x45, 0x45, 0x39, 68 | 0x3C, 0x4A, 0x49, 0x49, 0x31, 69 | 0x41, 0x21, 0x11, 0x09, 0x07, 70 | 0x36, 0x49, 0x49, 0x49, 0x36, 71 | 0x46, 0x49, 0x49, 0x29, 0x1E, 72 | 0x00, 0x00, 0x14, 0x00, 0x00, 73 | 0x00, 0x40, 0x34, 0x00, 0x00, 74 | 0x00, 0x08, 0x14, 0x22, 0x41, 75 | 0x14, 0x14, 0x14, 0x14, 0x14, 76 | 0x00, 0x41, 0x22, 0x14, 0x08, 77 | 0x02, 0x01, 0x59, 0x09, 0x06, 78 | 0x3E, 0x41, 0x5D, 0x59, 0x4E, 79 | 0x7C, 0x12, 0x11, 0x12, 0x7C, 80 | 0x7F, 0x49, 0x49, 0x49, 0x36, 81 | 0x3E, 0x41, 0x41, 0x41, 0x22, 82 | 0x7F, 0x41, 0x41, 0x41, 0x3E, 83 | 0x7F, 0x49, 0x49, 0x49, 0x41, 84 | 0x7F, 0x09, 0x09, 0x09, 0x01, 85 | 0x3E, 0x41, 0x41, 0x51, 0x73, 86 | 0x7F, 0x08, 0x08, 0x08, 0x7F, 87 | 0x00, 0x41, 0x7F, 0x41, 0x00, 88 | 0x20, 0x40, 0x41, 0x3F, 0x01, 89 | 0x7F, 0x08, 0x14, 0x22, 0x41, 90 | 0x7F, 0x40, 0x40, 0x40, 0x40, 91 | 0x7F, 0x02, 0x1C, 0x02, 0x7F, 92 | 0x7F, 0x04, 0x08, 0x10, 0x7F, 93 | 0x3E, 0x41, 0x41, 0x41, 0x3E, 94 | 0x7F, 0x09, 0x09, 0x09, 0x06, 95 | 0x3E, 0x41, 0x51, 0x21, 0x5E, 96 | 0x7F, 0x09, 0x19, 0x29, 0x46, 97 | 0x26, 0x49, 0x49, 0x49, 0x32, 98 | 0x03, 0x01, 0x7F, 0x01, 0x03, 99 | 0x3F, 0x40, 0x40, 0x40, 0x3F, 100 | 0x1F, 0x20, 0x40, 0x20, 0x1F, 101 | 0x3F, 0x40, 0x38, 0x40, 0x3F, 102 | 0x63, 0x14, 0x08, 0x14, 0x63, 103 | 0x03, 0x04, 0x78, 0x04, 0x03, 104 | 0x61, 0x59, 0x49, 0x4D, 0x43, 105 | 0x00, 0x7F, 0x41, 0x41, 0x41, 106 | 0x02, 0x04, 0x08, 0x10, 0x20, 107 | 0x00, 0x41, 0x41, 0x41, 0x7F, 108 | 0x04, 0x02, 0x01, 0x02, 0x04, 109 | 0x40, 0x40, 0x40, 0x40, 0x40, 110 | 0x00, 0x03, 0x07, 0x08, 0x00, 111 | 0x20, 0x54, 0x54, 0x78, 0x40, 112 | 0x7F, 0x28, 0x44, 0x44, 0x38, 113 | 0x38, 0x44, 0x44, 0x44, 0x28, 114 | 0x38, 0x44, 0x44, 0x28, 0x7F, 115 | 0x38, 0x54, 0x54, 0x54, 0x18, 116 | 0x00, 0x08, 0x7E, 0x09, 0x02, 117 | 0x18, 0xA4, 0xA4, 0x9C, 0x78, 118 | 0x7F, 0x08, 0x04, 0x04, 0x78, 119 | 0x00, 0x44, 0x7D, 0x40, 0x00, 120 | 0x20, 0x40, 0x40, 0x3D, 0x00, 121 | 0x7F, 0x10, 0x28, 0x44, 0x00, 122 | 0x00, 0x41, 0x7F, 0x40, 0x00, 123 | 0x7C, 0x04, 0x78, 0x04, 0x78, 124 | 0x7C, 0x08, 0x04, 0x04, 0x78, 125 | 0x38, 0x44, 0x44, 0x44, 0x38, 126 | 0xFC, 0x18, 0x24, 0x24, 0x18, 127 | 0x18, 0x24, 0x24, 0x18, 0xFC, 128 | 0x7C, 0x08, 0x04, 0x04, 0x08, 129 | 0x48, 0x54, 0x54, 0x54, 0x24, 130 | 0x04, 0x04, 0x3F, 0x44, 0x24, 131 | 0x3C, 0x40, 0x40, 0x20, 0x7C, 132 | 0x1C, 0x20, 0x40, 0x20, 0x1C, 133 | 0x3C, 0x40, 0x30, 0x40, 0x3C, 134 | 0x44, 0x28, 0x10, 0x28, 0x44, 135 | 0x4C, 0x90, 0x90, 0x90, 0x7C, 136 | 0x44, 0x64, 0x54, 0x4C, 0x44, 137 | 0x00, 0x08, 0x36, 0x41, 0x00, 138 | 0x00, 0x00, 0x77, 0x00, 0x00, 139 | 0x00, 0x41, 0x36, 0x08, 0x00, 140 | 0x02, 0x01, 0x02, 0x04, 0x02, 141 | 0x3C, 0x26, 0x23, 0x26, 0x3C, 142 | 0x1E, 0xA1, 0xA1, 0x61, 0x12, 143 | 0x3A, 0x40, 0x40, 0x20, 0x7A, 144 | 0x38, 0x54, 0x54, 0x55, 0x59, 145 | 0x21, 0x55, 0x55, 0x79, 0x41, 146 | 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut 147 | 0x21, 0x55, 0x54, 0x78, 0x40, 148 | 0x20, 0x54, 0x55, 0x79, 0x40, 149 | 0x0C, 0x1E, 0x52, 0x72, 0x12, 150 | 0x39, 0x55, 0x55, 0x55, 0x59, 151 | 0x39, 0x54, 0x54, 0x54, 0x59, 152 | 0x39, 0x55, 0x54, 0x54, 0x58, 153 | 0x00, 0x00, 0x45, 0x7C, 0x41, 154 | 0x00, 0x02, 0x45, 0x7D, 0x42, 155 | 0x00, 0x01, 0x45, 0x7C, 0x40, 156 | 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut 157 | 0xF0, 0x28, 0x25, 0x28, 0xF0, 158 | 0x7C, 0x54, 0x55, 0x45, 0x00, 159 | 0x20, 0x54, 0x54, 0x7C, 0x54, 160 | 0x7C, 0x0A, 0x09, 0x7F, 0x49, 161 | 0x32, 0x49, 0x49, 0x49, 0x32, 162 | 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut 163 | 0x32, 0x4A, 0x48, 0x48, 0x30, 164 | 0x3A, 0x41, 0x41, 0x21, 0x7A, 165 | 0x3A, 0x42, 0x40, 0x20, 0x78, 166 | 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 167 | 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut 168 | 0x3D, 0x40, 0x40, 0x40, 0x3D, 169 | 0x3C, 0x24, 0xFF, 0x24, 0x24, 170 | 0x48, 0x7E, 0x49, 0x43, 0x66, 171 | 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 172 | 0xFF, 0x09, 0x29, 0xF6, 0x20, 173 | 0xC0, 0x88, 0x7E, 0x09, 0x03, 174 | 0x20, 0x54, 0x54, 0x79, 0x41, 175 | 0x00, 0x00, 0x44, 0x7D, 0x41, 176 | 0x30, 0x48, 0x48, 0x4A, 0x32, 177 | 0x38, 0x40, 0x40, 0x22, 0x7A, 178 | 0x00, 0x7A, 0x0A, 0x0A, 0x72, 179 | 0x7D, 0x0D, 0x19, 0x31, 0x7D, 180 | 0x26, 0x29, 0x29, 0x2F, 0x28, 181 | 0x26, 0x29, 0x29, 0x29, 0x26, 182 | 0x30, 0x48, 0x4D, 0x40, 0x20, 183 | 0x38, 0x08, 0x08, 0x08, 0x08, 184 | 0x08, 0x08, 0x08, 0x08, 0x38, 185 | 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 186 | 0x2F, 0x10, 0x28, 0x34, 0xFA, 187 | 0x00, 0x00, 0x7B, 0x00, 0x00, 188 | 0x08, 0x14, 0x2A, 0x14, 0x22, 189 | 0x22, 0x14, 0x2A, 0x14, 0x08, 190 | 0xAA, 0x00, 0x55, 0x00, 0xAA, 191 | 0xAA, 0x55, 0xAA, 0x55, 0xAA, 192 | 0x00, 0x00, 0x00, 0xFF, 0x00, 193 | 0x10, 0x10, 0x10, 0xFF, 0x00, 194 | 0x14, 0x14, 0x14, 0xFF, 0x00, 195 | 0x10, 0x10, 0xFF, 0x00, 0xFF, 196 | 0x10, 0x10, 0xF0, 0x10, 0xF0, 197 | 0x14, 0x14, 0x14, 0xFC, 0x00, 198 | 0x14, 0x14, 0xF7, 0x00, 0xFF, 199 | 0x00, 0x00, 0xFF, 0x00, 0xFF, 200 | 0x14, 0x14, 0xF4, 0x04, 0xFC, 201 | 0x14, 0x14, 0x17, 0x10, 0x1F, 202 | 0x10, 0x10, 0x1F, 0x10, 0x1F, 203 | 0x14, 0x14, 0x14, 0x1F, 0x00, 204 | 0x10, 0x10, 0x10, 0xF0, 0x00, 205 | 0x00, 0x00, 0x00, 0x1F, 0x10, 206 | 0x10, 0x10, 0x10, 0x1F, 0x10, 207 | 0x10, 0x10, 0x10, 0xF0, 0x10, 208 | 0x00, 0x00, 0x00, 0xFF, 0x10, 209 | 0x10, 0x10, 0x10, 0x10, 0x10, 210 | 0x10, 0x10, 0x10, 0xFF, 0x10, 211 | 0x00, 0x00, 0x00, 0xFF, 0x14, 212 | 0x00, 0x00, 0xFF, 0x00, 0xFF, 213 | 0x00, 0x00, 0x1F, 0x10, 0x17, 214 | 0x00, 0x00, 0xFC, 0x04, 0xF4, 215 | 0x14, 0x14, 0x17, 0x10, 0x17, 216 | 0x14, 0x14, 0xF4, 0x04, 0xF4, 217 | 0x00, 0x00, 0xFF, 0x00, 0xF7, 218 | 0x14, 0x14, 0x14, 0x14, 0x14, 219 | 0x14, 0x14, 0xF7, 0x00, 0xF7, 220 | 0x14, 0x14, 0x14, 0x17, 0x14, 221 | 0x10, 0x10, 0x1F, 0x10, 0x1F, 222 | 0x14, 0x14, 0x14, 0xF4, 0x14, 223 | 0x10, 0x10, 0xF0, 0x10, 0xF0, 224 | 0x00, 0x00, 0x1F, 0x10, 0x1F, 225 | 0x00, 0x00, 0x00, 0x1F, 0x14, 226 | 0x00, 0x00, 0x00, 0xFC, 0x14, 227 | 0x00, 0x00, 0xF0, 0x10, 0xF0, 228 | 0x10, 0x10, 0xFF, 0x10, 0xFF, 229 | 0x14, 0x14, 0x14, 0xFF, 0x14, 230 | 0x10, 0x10, 0x10, 0x1F, 0x00, 231 | 0x00, 0x00, 0x00, 0xF0, 0x10, 232 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 233 | 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 234 | 0xFF, 0xFF, 0xFF, 0x00, 0x00, 235 | 0x00, 0x00, 0x00, 0xFF, 0xFF, 236 | 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 237 | 0x38, 0x44, 0x44, 0x38, 0x44, 238 | 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta 239 | 0x7E, 0x02, 0x02, 0x06, 0x06, 240 | 0x02, 0x7E, 0x02, 0x7E, 0x02, 241 | 0x63, 0x55, 0x49, 0x41, 0x63, 242 | 0x38, 0x44, 0x44, 0x3C, 0x04, 243 | 0x40, 0x7E, 0x20, 0x1E, 0x20, 244 | 0x06, 0x02, 0x7E, 0x02, 0x02, 245 | 0x99, 0xA5, 0xE7, 0xA5, 0x99, 246 | 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 247 | 0x4C, 0x72, 0x01, 0x72, 0x4C, 248 | 0x30, 0x4A, 0x4D, 0x4D, 0x30, 249 | 0x30, 0x48, 0x78, 0x48, 0x30, 250 | 0xBC, 0x62, 0x5A, 0x46, 0x3D, 251 | 0x3E, 0x49, 0x49, 0x49, 0x00, 252 | 0x7E, 0x01, 0x01, 0x01, 0x7E, 253 | 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 254 | 0x44, 0x44, 0x5F, 0x44, 0x44, 255 | 0x40, 0x51, 0x4A, 0x44, 0x40, 256 | 0x40, 0x44, 0x4A, 0x51, 0x40, 257 | 0x00, 0x00, 0xFF, 0x01, 0x03, 258 | 0xE0, 0x80, 0xFF, 0x00, 0x00, 259 | 0x08, 0x08, 0x6B, 0x6B, 0x08, 260 | 0x36, 0x12, 0x36, 0x24, 0x36, 261 | 0x06, 0x0F, 0x09, 0x0F, 0x06, 262 | 0x00, 0x00, 0x18, 0x18, 0x00, 263 | 0x00, 0x00, 0x10, 0x10, 0x00, 264 | 0x30, 0x40, 0xFF, 0x01, 0x01, 265 | 0x00, 0x1F, 0x01, 0x01, 0x1E, 266 | 0x00, 0x19, 0x1D, 0x17, 0x12, 267 | 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 268 | 0x00, 0x00, 0x00, 0x00, 0x00 269 | }; 270 | #endif // FONT5X7_H 271 | -------------------------------------------------------------------------------- /libraries/Adafruit_GFX/Adafruit_GFX.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This is the core graphics library for all our displays, providing a common 3 | set of graphics primitives (points, lines, circles, etc.). It needs to be 4 | paired with a hardware-specific library for each display device we carry 5 | (to handle the lower-level functions). 6 | 7 | Adafruit invests time and resources providing this open source code, please 8 | support Adafruit & open-source hardware by purchasing products from Adafruit! 9 | 10 | Copyright (c) 2013 Adafruit Industries. All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | 15 | - Redistributions of source code must retain the above copyright notice, 16 | this list of conditions and the following disclaimer. 17 | - Redistributions in binary form must reproduce the above copyright notice, 18 | this list of conditions and the following disclaimer in the documentation 19 | and/or other materials provided with the distribution. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | 34 | #include "Adafruit_GFX.h" 35 | #include "glcdfont.c" 36 | #ifdef __AVR__ 37 | #include 38 | #else 39 | #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 40 | #endif 41 | 42 | Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h): 43 | WIDTH(w), HEIGHT(h) 44 | { 45 | _width = WIDTH; 46 | _height = HEIGHT; 47 | rotation = 0; 48 | cursor_y = cursor_x = 0; 49 | textsize = 1; 50 | textcolor = textbgcolor = 0xFFFF; 51 | wrap = true; 52 | } 53 | 54 | // Draw a circle outline 55 | void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, 56 | uint16_t color) { 57 | int16_t f = 1 - r; 58 | int16_t ddF_x = 1; 59 | int16_t ddF_y = -2 * r; 60 | int16_t x = 0; 61 | int16_t y = r; 62 | 63 | drawPixel(x0 , y0+r, color); 64 | drawPixel(x0 , y0-r, color); 65 | drawPixel(x0+r, y0 , color); 66 | drawPixel(x0-r, y0 , color); 67 | 68 | while (x= 0) { 70 | y--; 71 | ddF_y += 2; 72 | f += ddF_y; 73 | } 74 | x++; 75 | ddF_x += 2; 76 | f += ddF_x; 77 | 78 | drawPixel(x0 + x, y0 + y, color); 79 | drawPixel(x0 - x, y0 + y, color); 80 | drawPixel(x0 + x, y0 - y, color); 81 | drawPixel(x0 - x, y0 - y, color); 82 | drawPixel(x0 + y, y0 + x, color); 83 | drawPixel(x0 - y, y0 + x, color); 84 | drawPixel(x0 + y, y0 - x, color); 85 | drawPixel(x0 - y, y0 - x, color); 86 | } 87 | } 88 | 89 | void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0, 90 | int16_t r, uint8_t cornername, uint16_t color) { 91 | int16_t f = 1 - r; 92 | int16_t ddF_x = 1; 93 | int16_t ddF_y = -2 * r; 94 | int16_t x = 0; 95 | int16_t y = r; 96 | 97 | while (x= 0) { 99 | y--; 100 | ddF_y += 2; 101 | f += ddF_y; 102 | } 103 | x++; 104 | ddF_x += 2; 105 | f += ddF_x; 106 | if (cornername & 0x4) { 107 | drawPixel(x0 + x, y0 + y, color); 108 | drawPixel(x0 + y, y0 + x, color); 109 | } 110 | if (cornername & 0x2) { 111 | drawPixel(x0 + x, y0 - y, color); 112 | drawPixel(x0 + y, y0 - x, color); 113 | } 114 | if (cornername & 0x8) { 115 | drawPixel(x0 - y, y0 + x, color); 116 | drawPixel(x0 - x, y0 + y, color); 117 | } 118 | if (cornername & 0x1) { 119 | drawPixel(x0 - y, y0 - x, color); 120 | drawPixel(x0 - x, y0 - y, color); 121 | } 122 | } 123 | } 124 | 125 | void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, 126 | uint16_t color) { 127 | drawFastVLine(x0, y0-r, 2*r+1, color); 128 | fillCircleHelper(x0, y0, r, 3, 0, color); 129 | } 130 | 131 | // Used to do circles and roundrects 132 | void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, 133 | uint8_t cornername, int16_t delta, uint16_t color) { 134 | 135 | int16_t f = 1 - r; 136 | int16_t ddF_x = 1; 137 | int16_t ddF_y = -2 * r; 138 | int16_t x = 0; 139 | int16_t y = r; 140 | 141 | while (x= 0) { 143 | y--; 144 | ddF_y += 2; 145 | f += ddF_y; 146 | } 147 | x++; 148 | ddF_x += 2; 149 | f += ddF_x; 150 | 151 | if (cornername & 0x1) { 152 | drawFastVLine(x0+x, y0-y, 2*y+1+delta, color); 153 | drawFastVLine(x0+y, y0-x, 2*x+1+delta, color); 154 | } 155 | if (cornername & 0x2) { 156 | drawFastVLine(x0-x, y0-y, 2*y+1+delta, color); 157 | drawFastVLine(x0-y, y0-x, 2*x+1+delta, color); 158 | } 159 | } 160 | } 161 | 162 | // Bresenham's algorithm - thx wikpedia 163 | void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, 164 | int16_t x1, int16_t y1, 165 | uint16_t color) { 166 | int16_t steep = abs(y1 - y0) > abs(x1 - x0); 167 | if (steep) { 168 | swap(x0, y0); 169 | swap(x1, y1); 170 | } 171 | 172 | if (x0 > x1) { 173 | swap(x0, x1); 174 | swap(y0, y1); 175 | } 176 | 177 | int16_t dx, dy; 178 | dx = x1 - x0; 179 | dy = abs(y1 - y0); 180 | 181 | int16_t err = dx / 2; 182 | int16_t ystep; 183 | 184 | if (y0 < y1) { 185 | ystep = 1; 186 | } else { 187 | ystep = -1; 188 | } 189 | 190 | for (; x0<=x1; x0++) { 191 | if (steep) { 192 | drawPixel(y0, x0, color); 193 | } else { 194 | drawPixel(x0, y0, color); 195 | } 196 | err -= dy; 197 | if (err < 0) { 198 | y0 += ystep; 199 | err += dx; 200 | } 201 | } 202 | } 203 | 204 | // Draw a rectangle 205 | void Adafruit_GFX::drawRect(int16_t x, int16_t y, 206 | int16_t w, int16_t h, 207 | uint16_t color) { 208 | drawFastHLine(x, y, w, color); 209 | drawFastHLine(x, y+h-1, w, color); 210 | drawFastVLine(x, y, h, color); 211 | drawFastVLine(x+w-1, y, h, color); 212 | } 213 | 214 | void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, 215 | int16_t h, uint16_t color) { 216 | // Update in subclasses if desired! 217 | drawLine(x, y, x, y+h-1, color); 218 | } 219 | 220 | void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, 221 | int16_t w, uint16_t color) { 222 | // Update in subclasses if desired! 223 | drawLine(x, y, x+w-1, y, color); 224 | } 225 | 226 | void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 227 | uint16_t color) { 228 | // Update in subclasses if desired! 229 | for (int16_t i=x; i= y1 >= y0) 281 | if (y0 > y1) { 282 | swap(y0, y1); swap(x0, x1); 283 | } 284 | if (y1 > y2) { 285 | swap(y2, y1); swap(x2, x1); 286 | } 287 | if (y0 > y1) { 288 | swap(y0, y1); swap(x0, x1); 289 | } 290 | 291 | if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing 292 | a = b = x0; 293 | if(x1 < a) a = x1; 294 | else if(x1 > b) b = x1; 295 | if(x2 < a) a = x2; 296 | else if(x2 > b) b = x2; 297 | drawFastHLine(a, y0, b-a+1, color); 298 | return; 299 | } 300 | 301 | int16_t 302 | dx01 = x1 - x0, 303 | dy01 = y1 - y0, 304 | dx02 = x2 - x0, 305 | dy02 = y2 - y0, 306 | dx12 = x2 - x1, 307 | dy12 = y2 - y1; 308 | int32_t 309 | sa = 0, 310 | sb = 0; 311 | 312 | // For upper part of triangle, find scanline crossings for segments 313 | // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 314 | // is included here (and second loop will be skipped, avoiding a /0 315 | // error there), otherwise scanline y1 is skipped here and handled 316 | // in the second loop...which also avoids a /0 error here if y0=y1 317 | // (flat-topped triangle). 318 | if(y1 == y2) last = y1; // Include y1 scanline 319 | else last = y1-1; // Skip it 320 | 321 | for(y=y0; y<=last; y++) { 322 | a = x0 + sa / dy01; 323 | b = x0 + sb / dy02; 324 | sa += dx01; 325 | sb += dx02; 326 | /* longhand: 327 | a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); 328 | b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 329 | */ 330 | if(a > b) swap(a,b); 331 | drawFastHLine(a, y, b-a+1, color); 332 | } 333 | 334 | // For lower part of triangle, find scanline crossings for segments 335 | // 0-2 and 1-2. This loop is skipped if y1=y2. 336 | sa = dx12 * (y - y1); 337 | sb = dx02 * (y - y0); 338 | for(; y<=y2; y++) { 339 | a = x1 + sa / dy12; 340 | b = x0 + sb / dy02; 341 | sa += dx12; 342 | sb += dx02; 343 | /* longhand: 344 | a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); 345 | b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 346 | */ 347 | if(a > b) swap(a,b); 348 | drawFastHLine(a, y, b-a+1, color); 349 | } 350 | } 351 | 352 | void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, 353 | const uint8_t *bitmap, int16_t w, int16_t h, 354 | uint16_t color) { 355 | 356 | int16_t i, j, byteWidth = (w + 7) / 8; 357 | 358 | for(j=0; j> (i & 7))) { 361 | drawPixel(x+i, y+j, color); 362 | } 363 | } 364 | } 365 | } 366 | 367 | // Draw a 1-bit color bitmap at the specified x, y position from the 368 | // provided bitmap buffer (must be PROGMEM memory) using color as the 369 | // foreground color and bg as the background color. 370 | void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, 371 | const uint8_t *bitmap, int16_t w, int16_t h, 372 | uint16_t color, uint16_t bg) { 373 | 374 | int16_t i, j, byteWidth = (w + 7) / 8; 375 | 376 | for(j=0; j> (i & 7))) { 379 | drawPixel(x+i, y+j, color); 380 | } 381 | else { 382 | drawPixel(x+i, y+j, bg); 383 | } 384 | } 385 | } 386 | } 387 | 388 | //Draw XBitMap Files (*.xbm), exported from GIMP, 389 | //Usage: Export from GIMP to *.xbm, rename *.xbm to *.c and open in editor. 390 | //C Array can be directly used with this function 391 | void Adafruit_GFX::drawXBitmap(int16_t x, int16_t y, 392 | const uint8_t *bitmap, int16_t w, int16_t h, 393 | uint16_t color) { 394 | 395 | int16_t i, j, byteWidth = (w + 7) / 8; 396 | 397 | for(j=0; j= 100 407 | size_t Adafruit_GFX::write(uint8_t c) { 408 | #else 409 | void Adafruit_GFX::write(uint8_t c) { 410 | #endif 411 | if (c == '\n') { 412 | cursor_y += textsize*8; 413 | cursor_x = 0; 414 | } else if (c == '\r') { 415 | // skip em 416 | } else { 417 | drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); 418 | cursor_x += textsize*6; 419 | if (wrap && (cursor_x > (_width - textsize*6))) { 420 | cursor_y += textsize*8; 421 | cursor_x = 0; 422 | } 423 | } 424 | #if ARDUINO >= 100 425 | return 1; 426 | #endif 427 | } 428 | 429 | // Draw a character 430 | void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, 431 | uint16_t color, uint16_t bg, uint8_t size) { 432 | 433 | if((x >= _width) || // Clip right 434 | (y >= _height) || // Clip bottom 435 | ((x + 6 * size - 1) < 0) || // Clip left 436 | ((y + 8 * size - 1) < 0)) // Clip top 437 | return; 438 | 439 | for (int8_t i=0; i<6; i++ ) { 440 | uint8_t line; 441 | if (i == 5) 442 | line = 0x0; 443 | else 444 | line = pgm_read_byte(font+(c*5)+i); 445 | for (int8_t j = 0; j<8; j++) { 446 | if (line & 0x1) { 447 | if (size == 1) // default size 448 | drawPixel(x+i, y+j, color); 449 | else { // big size 450 | fillRect(x+(i*size), y+(j*size), size, size, color); 451 | } 452 | } else if (bg != color) { 453 | if (size == 1) // default size 454 | drawPixel(x+i, y+j, bg); 455 | else { // big size 456 | fillRect(x+i*size, y+j*size, size, size, bg); 457 | } 458 | } 459 | line >>= 1; 460 | } 461 | } 462 | } 463 | 464 | void Adafruit_GFX::setCursor(int16_t x, int16_t y) { 465 | cursor_x = x; 466 | cursor_y = y; 467 | } 468 | 469 | void Adafruit_GFX::setTextSize(uint8_t s) { 470 | textsize = (s > 0) ? s : 1; 471 | } 472 | 473 | void Adafruit_GFX::setTextColor(uint16_t c) { 474 | // For 'transparent' background, we'll set the bg 475 | // to the same as fg instead of using a flag 476 | textcolor = textbgcolor = c; 477 | } 478 | 479 | void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) { 480 | textcolor = c; 481 | textbgcolor = b; 482 | } 483 | 484 | void Adafruit_GFX::setTextWrap(boolean w) { 485 | wrap = w; 486 | } 487 | 488 | uint8_t Adafruit_GFX::getRotation(void) const { 489 | return rotation; 490 | } 491 | 492 | void Adafruit_GFX::setRotation(uint8_t x) { 493 | rotation = (x & 3); 494 | switch(rotation) { 495 | case 0: 496 | case 2: 497 | _width = WIDTH; 498 | _height = HEIGHT; 499 | break; 500 | case 1: 501 | case 3: 502 | _width = HEIGHT; 503 | _height = WIDTH; 504 | break; 505 | } 506 | } 507 | 508 | // Return the size of the display (per current rotation) 509 | int16_t Adafruit_GFX::width(void) const { 510 | return _width; 511 | } 512 | 513 | int16_t Adafruit_GFX::height(void) const { 514 | return _height; 515 | } 516 | 517 | void Adafruit_GFX::invertDisplay(boolean i) { 518 | // Do nothing, must be subclassed if supported 519 | } 520 | 521 | -------------------------------------------------------------------------------- /MyTFTanaGraph.ino: -------------------------------------------------------------------------------- 1 | // Touch screen library with X Y and Z (pressure) readings as well 2 | // Analog sensor data graph 3 | // Code by Damon Borgnino 4 | 5 | #include "TouchScreen.h" 6 | #include // Core graphics library 7 | #include // Hardware-specific library 8 | 9 | #define DEBUG 10 | 11 | #define LCD_CS A3 12 | #define LCD_CD A2 13 | #define LCD_WR A1 14 | #define LCD_RD A0 15 | 16 | #define LCD_RESET A4 17 | 18 | // These are the pins for the shield! 19 | #define YP A3 // must be an analog pin, use "An" notation! 20 | #define XM A2 // must be an analog pin, use "An" notation! 21 | #define YM 9 // can be a digital pin 22 | #define XP 8 // can be a digital pin 23 | 24 | #define MINPRESSURE 1 25 | #define MAXPRESSURE 1000 26 | 27 | // calibration mins and max for raw data when touching edges of screen 28 | // YOU CAN USE THIS SKETCH TO DETERMINE THE RAW X AND Y OF THE EDGES TO GET YOUR HIGHS AND LOWS FOR X AND Y 29 | #define TS_MINX 210 30 | #define TS_MINY 210 31 | #define TS_MAXX 915 32 | #define TS_MAXY 910 33 | 34 | #define BLACK 0x0000 35 | #define BLUE 0x001F 36 | #define RED 0xF800 37 | #define GREEN 0x07E0 38 | //#define CYAN 0x07FF 39 | //#define MAGENTA 0xF81F 40 | #define YELLOW 0xFFE0 41 | #define WHITE 0xFFFF 42 | //#define GREY 0xCE79 43 | #define LIGHTGREY 0xDEDB 44 | 45 | 46 | #define powerPin 53 //will turn on to power sensor(s) 47 | #define sensorPin A14 // sensor one 48 | #define sensor2Pin A15 // sensor two 49 | 50 | 51 | const char* touchMeStr = " Analog Line Graph"; 52 | 53 | const int BASEVAL = 500; // Center graph baseline 54 | 55 | Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); 56 | 57 | TouchScreen ts = TouchScreen(XP, YP, XM, YM, 364); 58 | 59 | int loopCounter = 0; 60 | int pauseState = 0; 61 | int menuState = 0; 62 | 63 | int sensor1Val = 0; // used to hold sensor data 64 | int sensor1ValOld = 0; // holds previous value for line graph 65 | int sensor2Val = 0; // used t hold sensor 2 data 66 | int sensor2ValOld = 0; // keeps old value needed to draw lines 67 | 68 | // regions used for touch detection 69 | int TopBtnArea[] = {0, 0, 0, 0}; 70 | int CenterBtnArea[] = {0, 0, 0, 0}; 71 | int BottomBtnArea[] = {0, 0, 0, 0}; 72 | int DataArea[] = {0, 0, 0, 0}; 73 | int DoneBtnArea[] = {220, 35, 65, 30}; 74 | 75 | // arrow buttons 76 | int LeftArrowArea[] = { 33, 181, 41, 27}; // touch region for left arrow 77 | int RightArrowArea[] = { 76, 181, 42, 27 }; // touch region for right arrow 78 | 79 | // color buttons 80 | int RedBtn[] = {40, 140, 35, 35}; 81 | int GreenBtn[] = {80, 140, 35, 35}; 82 | int YellowBtn[] = {120, 140, 35, 35}; 83 | int BlueBtn[] = {160, 140, 35, 35}; 84 | int WhiteBtn[] = {200, 140, 35, 35}; 85 | int BlackBtn[] = {240, 140, 35, 35}; 86 | 87 | int TopGraphColor = RED; 88 | int CenterGraphColor = WHITE; 89 | int BottomGraphColor = YELLOW; 90 | 91 | int TopDirection = 1; // 0=right, 1=left 92 | int CenterDirection = 0; 93 | int BottomDirection = 0; 94 | ///////////////////////////////////////////////////////////////////////////////////////////// 95 | 96 | void setup(void) { 97 | 98 | #ifdef DEBUG 99 | Serial.begin(9600); 100 | #endif // DEBUG 101 | 102 | pinMode(powerPin, OUTPUT); 103 | digitalWrite(powerPin, HIGH); // turn sensor power on 104 | 105 | tft.reset(); 106 | 107 | uint16_t identifier = tft.readID(); 108 | 109 | tft.begin(identifier); 110 | 111 | tft.fillScreen(BLACK); 112 | tft.setRotation(1); 113 | tft.setCursor(30, 100); 114 | tft.setTextColor(RED); tft.setTextSize(2); 115 | tft.println("LCD driver chip: "); 116 | tft.setCursor(100, 150); 117 | tft.setTextColor(BLUE); 118 | tft.println(identifier, HEX); 119 | 120 | delay(500); 121 | 122 | tft.fillScreen(BLACK); 123 | tft.setTextColor(YELLOW); 124 | 125 | tft.setCursor(0, 0); 126 | tft.println(touchMeStr); 127 | 128 | 129 | } 130 | 131 | 132 | ////////////////////////////////////////////////////////////////////////////////// 133 | 134 | 135 | void loop(void) { 136 | 137 | 138 | sensor1Val = analogRead(sensorPin); // read sensor data 139 | sensor2Val = analogRead(sensor2Pin); // read sensor data 140 | 141 | int audioVal = sensor2Val; // raw 142 | 143 | if (audioVal < BASEVAL) 144 | audioVal = (BASEVAL - audioVal) + BASEVAL; 145 | 146 | // a point object holds x y and z coordinates 147 | TSPoint p = ts.getPoint(); 148 | 149 | pinMode(XM, OUTPUT); 150 | pinMode(YP, OUTPUT); 151 | 152 | // we have some minimum pressure we consider 'valid' 153 | // pressure of 0 means no pressing! 154 | if (p.z > MINPRESSURE && p.z < MAXPRESSURE) { 155 | 156 | ////////////////////////////////////////////////////////////////////////// 157 | // because of rotation x is traNsposed with and y and height with width 158 | // this is typically the cause of cordinates being reversed 159 | ////////////////////////////////////////////////////////////////////////// 160 | int YY = tft.height() - (map(p.x, TS_MINX, TS_MAXX, 0, tft.height())); 161 | int XX = tft.width() - (map(p.y, TS_MINY, TS_MAXY, 0, tft.width())); 162 | 163 | // flip the pause state on/off 164 | if (pauseState == 0) 165 | { 166 | pauseState = 1; 167 | } 168 | else // already in pause state 169 | { 170 | 171 | checkMenuPress( XX, YY); 172 | 173 | } 174 | 175 | 176 | // PRINTS OUT THE RAW AND TRANSPOSED DATA useful for troubleshooting 177 | if (pauseState == 1) 178 | { 179 | 180 | showMenuOptions(); 181 | if (menuState == 0) 182 | showData(p.x, p.y, p.z, XX, YY); 183 | 184 | /////////////////////////////////////////////////////////////////////////// 185 | #ifdef DEBUG 186 | 187 | // serial data 188 | Serial.print("Raw X = "); Serial.print(p.x); 189 | Serial.print(" Raw Y = "); Serial.println(p.y); 190 | Serial.print("Pressure = "); Serial.println(p.z); 191 | Serial.print("Screen XX: " ); 192 | Serial.print(XX); 193 | Serial.print(" Screen YY:"); 194 | Serial.println(YY); 195 | Serial.print("Raw Sensor 1 = "); Serial.println(sensor1Val); 196 | Serial.print("Raw Sensor 2 = "); Serial.println(sensor2Val); 197 | Serial.print("Loop counter "); Serial.println(loopCounter); 198 | 199 | #endif // DEBUG /////////////////////////////////////////////////////////// 200 | 201 | delay(500); 202 | } 203 | else 204 | { 205 | 206 | // or reset the whole screen 207 | tft.fillScreen(BLACK); 208 | loopCounter = 0; 209 | 210 | } 211 | 212 | } 213 | else // if there is no touch event do this 214 | { 215 | 216 | if (pauseState == 0) // start / stop drawing data on touch 217 | { 218 | // the raw value can be used, but this can range from 0-1023 so some adjustments may be needed 219 | // here to make the graph more readable, otherwise values will easily go off the screen 220 | int sensor1Transposed = sensor1Val; 221 | 222 | // the value for this sensor is different so it needs to be adjusted to fit nice on the display 223 | // the more division used the less granular the data becomes 224 | // the raw data was too variable and higher than the other sensor 225 | // so to get them to fit together nicely, one or both sensor needs to be adjusted. 226 | 227 | int sensor2Transposed = (sensor2Val - tft.height()) / 2 ; 228 | 229 | 230 | // draw top graph 231 | if (TopDirection == 0) 232 | tft.drawLine(loopCounter, sensor1Transposed, loopCounter, 0, TopGraphColor); 233 | else 234 | tft.drawLine(tft.width() - loopCounter, sensor1Transposed, tft.width() - loopCounter, 0, TopGraphColor); 235 | 236 | 237 | //draw center graph 238 | if (CenterDirection == 0) 239 | tft.drawLine(loopCounter, sensor2ValOld, loopCounter + 1, sensor2Transposed, CenterGraphColor); 240 | else 241 | tft.drawLine(tft.width() - loopCounter + 1, sensor2ValOld, tft.width() - loopCounter, sensor2Transposed, CenterGraphColor); 242 | 243 | sensor2ValOld = sensor2Transposed; 244 | sensor1ValOld = sensor1Transposed; 245 | 246 | 247 | // draw bottom graph == 0) 248 | if (BottomDirection == 0) 249 | tft.drawLine( loopCounter, tft.height() - (audioVal - BASEVAL), loopCounter, tft.height(), BottomGraphColor); 250 | else 251 | tft.drawLine(tft.width() - loopCounter, tft.height() - (audioVal - BASEVAL), tft.width() - loopCounter, tft.height(), BottomGraphColor); 252 | 253 | 254 | if (loopCounter == tft.width() ) 255 | { 256 | loopCounter = 0; 257 | tft.fillScreen(BLACK); 258 | } 259 | else 260 | { 261 | loopCounter = loopCounter + 1; 262 | } 263 | 264 | } 265 | 266 | } 267 | 268 | delay(20); // helps smooth out graphs especially if more than one is drawing 269 | } 270 | 271 | 272 | //////////////////////////////////////////////////////////////////////////////////////////////// 273 | 274 | 275 | void checkMenuPress(int XX, int YY) 276 | { 277 | 278 | if (XX >= TopBtnArea[0] && XX <= TopBtnArea[0] + TopBtnArea[2] && 279 | YY >= TopBtnArea[1] && YY <= TopBtnArea[1] + TopBtnArea[3] ) 280 | { 281 | menuState = 1; 282 | } 283 | else if (XX >= CenterBtnArea[0] && XX <= CenterBtnArea[0] + CenterBtnArea[2] && 284 | YY >= CenterBtnArea[1] && YY <= CenterBtnArea[1] + CenterBtnArea[3] ) 285 | { 286 | menuState = 2; 287 | } 288 | else if (XX >= BottomBtnArea[0] && XX <= BottomBtnArea[0] + BottomBtnArea[2] && 289 | YY >= BottomBtnArea[1] && YY <= BottomBtnArea[1] + BottomBtnArea[3] ) 290 | { 291 | menuState = 3; 292 | } 293 | 294 | else if (XX >= DoneBtnArea[0] && XX <= DoneBtnArea[0] + DoneBtnArea[2] && 295 | YY >= DoneBtnArea[1] && YY <= DoneBtnArea[1] + DoneBtnArea[3] ) 296 | { 297 | 298 | menuState = 0; 299 | pauseState = 0; 300 | 301 | } 302 | 303 | 304 | 305 | switch (menuState) 306 | { 307 | 308 | case 1: // top graph direction 309 | 310 | if (XX >= LeftArrowArea[0] && XX <= LeftArrowArea[0] + LeftArrowArea[2] && 311 | YY >= LeftArrowArea[1] && YY <= LeftArrowArea[1] + LeftArrowArea[3] ) 312 | { 313 | TopDirection = 1; 314 | tft.drawRect(LeftArrowArea[0], LeftArrowArea[1], LeftArrowArea[2], LeftArrowArea[3], GREEN); 315 | } 316 | 317 | if (XX >= RightArrowArea[0] && XX <= RightArrowArea[0] + RightArrowArea[2] && 318 | YY >= RightArrowArea[1] && YY <= RightArrowArea[1] + RightArrowArea[3] ) 319 | { 320 | TopDirection = 0; 321 | tft.drawRect(RightArrowArea[0], RightArrowArea[1], RightArrowArea[2], RightArrowArea[3], GREEN); 322 | } 323 | 324 | ////////////////////////// 325 | //top graph colors 326 | 327 | if (XX >= RedBtn[0] && XX <= RedBtn[0] + RedBtn[2] && 328 | YY >= RedBtn[1] && YY <= RedBtn[1] + RedBtn[3] ) 329 | { 330 | TopGraphColor = RED; 331 | tft.fillRect(RedBtn[0], RedBtn[1], RedBtn[2], RedBtn[3], RED); 332 | } 333 | else if (XX >= GreenBtn[0] && XX <= GreenBtn[0] + GreenBtn[2] && 334 | YY >= GreenBtn[1] && YY <= GreenBtn[1] + GreenBtn[3] ) 335 | { 336 | TopGraphColor = GREEN; 337 | tft.fillRect(GreenBtn[0], GreenBtn[1], GreenBtn[2], GreenBtn[3], GREEN); 338 | } 339 | else if (XX >= YellowBtn[0] && XX <= YellowBtn[0] + YellowBtn[2] && 340 | YY >= YellowBtn[1] && YY <= YellowBtn[1] + YellowBtn[3] ) 341 | { 342 | TopGraphColor = YELLOW; 343 | tft.fillRect(YellowBtn[0], YellowBtn[1], YellowBtn[2], YellowBtn[3], YELLOW); 344 | } 345 | else if (XX >= BlueBtn[0] && XX <= BlueBtn[0] + BlueBtn[2] && 346 | YY >= BlueBtn[1] && YY <= BlueBtn[1] + BlueBtn[3] ) 347 | { 348 | TopGraphColor = BLUE; 349 | tft.fillRect(BlueBtn[0], BlueBtn[1], BlueBtn[2], BlueBtn[3], BLUE); 350 | } 351 | else if (XX >= WhiteBtn[0] && XX <= WhiteBtn[0] + WhiteBtn[2] && 352 | YY >= WhiteBtn[1] && YY <= WhiteBtn[1] + WhiteBtn[3] ) 353 | { 354 | TopGraphColor = WHITE; 355 | tft.fillRect(WhiteBtn[0], WhiteBtn[1], WhiteBtn[2], WhiteBtn[3], WHITE); 356 | } 357 | else if (XX >= BlackBtn[0] && XX <= BlackBtn[0] + BlackBtn[2] && 358 | YY >= BlackBtn[1] && YY <= BlackBtn[1] + BlackBtn[3] ) 359 | { 360 | TopGraphColor = BLACK; 361 | tft.fillRect(BlackBtn[0], BlackBtn[1], BlackBtn[2], BlackBtn[3], BLACK); 362 | } 363 | 364 | break; 365 | 366 | case 2: // center graph 367 | 368 | // center graph arrows 369 | if (XX >= LeftArrowArea[0] && XX <= LeftArrowArea[0] + LeftArrowArea[2] && 370 | YY >= LeftArrowArea[1] && YY <= LeftArrowArea[1] + LeftArrowArea[3] ) 371 | { 372 | CenterDirection = 1; 373 | tft.drawRect(LeftArrowArea[0], LeftArrowArea[1], LeftArrowArea[2], LeftArrowArea[3], GREEN); 374 | } 375 | 376 | if (XX >= RightArrowArea[0] && XX <= RightArrowArea[0] + RightArrowArea[2] && 377 | YY >= RightArrowArea[1] && YY <= RightArrowArea[1] + RightArrowArea[3] ) 378 | { 379 | CenterDirection = 0; 380 | tft.drawRect(RightArrowArea[0], RightArrowArea[1], RightArrowArea[2], RightArrowArea[3], GREEN); 381 | } 382 | 383 | //////////////// 384 | // center graph colors 385 | 386 | 387 | if (XX >= RedBtn[0] && XX <= RedBtn[0] + RedBtn[2] && 388 | YY >= RedBtn[1] && YY <= RedBtn[1] + RedBtn[3] ) 389 | { 390 | CenterGraphColor = RED; 391 | tft.fillRect(RedBtn[0], RedBtn[1], RedBtn[2], RedBtn[3], RED); 392 | } 393 | else if (XX >= GreenBtn[0] && XX <= GreenBtn[0] + GreenBtn[2] && 394 | YY >= GreenBtn[1] && YY <= GreenBtn[1] + GreenBtn[3] ) 395 | { 396 | CenterGraphColor = GREEN; 397 | tft.fillRect(GreenBtn[0], GreenBtn[1], GreenBtn[2], GreenBtn[3], GREEN); 398 | } 399 | else if (XX >= YellowBtn[0] && XX <= YellowBtn[0] + YellowBtn[2] && 400 | YY >= YellowBtn[1] && YY <= YellowBtn[1] + YellowBtn[3] ) 401 | { 402 | CenterGraphColor = YELLOW; 403 | tft.fillRect(YellowBtn[0], YellowBtn[1], YellowBtn[2], YellowBtn[3], YELLOW); 404 | } 405 | else if (XX >= BlueBtn[0] && XX <= BlueBtn[0] + BlueBtn[2] && 406 | YY >= BlueBtn[1] && YY <= BlueBtn[1] + BlueBtn[3] ) 407 | { 408 | CenterGraphColor = BLUE; 409 | tft.fillRect(BlueBtn[0], BlueBtn[1], BlueBtn[2], BlueBtn[3], BLUE); 410 | } 411 | else if (XX >= WhiteBtn[0] && XX <= WhiteBtn[0] + WhiteBtn[2] && 412 | YY >= WhiteBtn[1] && YY <= WhiteBtn[1] + WhiteBtn[3] ) 413 | { 414 | CenterGraphColor = WHITE; 415 | tft.fillRect(WhiteBtn[0], WhiteBtn[1], WhiteBtn[2], WhiteBtn[3], WHITE); 416 | } 417 | else if (XX >= BlackBtn[0] && XX <= BlackBtn[0] + BlackBtn[2] && 418 | YY >= BlackBtn[1] && YY <= BlackBtn[1] + BlackBtn[3] ) 419 | { 420 | CenterGraphColor = BLACK; 421 | tft.fillRect(BlackBtn[0], BlackBtn[1], BlackBtn[2], BlackBtn[3], BLACK); 422 | } 423 | break; 424 | 425 | case 3: 426 | // bottom graph arrows 427 | 428 | if (XX >= LeftArrowArea[0] && XX <= LeftArrowArea[0] + LeftArrowArea[2] && 429 | YY >= LeftArrowArea[1] && YY <= LeftArrowArea[1] + LeftArrowArea[3] ) 430 | { 431 | BottomDirection = 1; 432 | tft.drawRect(LeftArrowArea[0], LeftArrowArea[1], LeftArrowArea[2], LeftArrowArea[3], GREEN); 433 | } 434 | 435 | if (XX >= RightArrowArea[0] && XX <= RightArrowArea[0] + RightArrowArea[2] && 436 | YY >= RightArrowArea[1] && YY <= RightArrowArea[1] + RightArrowArea[3] ) 437 | { 438 | BottomDirection = 0; 439 | tft.drawRect(RightArrowArea[0], RightArrowArea[1], RightArrowArea[2], RightArrowArea[3], GREEN); 440 | } 441 | 442 | 443 | ///////////////////// 444 | // bottom graph colors 445 | 446 | if (XX >= RedBtn[0] && XX <= RedBtn[0] + RedBtn[2] && 447 | YY >= RedBtn[1] && YY <= RedBtn[1] + RedBtn[3] ) 448 | { 449 | BottomGraphColor = RED; 450 | tft.fillRect(RedBtn[0], RedBtn[1], RedBtn[2], RedBtn[3], RED); 451 | } 452 | else if (XX >= GreenBtn[0] && XX <= GreenBtn[0] + GreenBtn[2] && 453 | YY >= GreenBtn[1] && YY <= GreenBtn[1] + GreenBtn[3] ) 454 | { 455 | BottomGraphColor = GREEN; 456 | tft.fillRect(GreenBtn[0], GreenBtn[1], GreenBtn[2], GreenBtn[3], GREEN); 457 | } 458 | else if (XX >= YellowBtn[0] && XX <= YellowBtn[0] + YellowBtn[2] && 459 | YY >= YellowBtn[1] && YY <= YellowBtn[1] + YellowBtn[3] ) 460 | { 461 | BottomGraphColor = YELLOW; 462 | tft.fillRect(YellowBtn[0], YellowBtn[1], YellowBtn[2], YellowBtn[3], YELLOW); 463 | } 464 | else if (XX >= BlueBtn[0] && XX <= BlueBtn[0] + BlueBtn[2] && 465 | YY >= BlueBtn[1] && YY <= BlueBtn[1] + BlueBtn[3] ) 466 | { 467 | BottomGraphColor = BLUE; 468 | tft.fillRect(BlueBtn[0], BlueBtn[1], BlueBtn[2], BlueBtn[3], BLUE); 469 | } 470 | else if (XX >= WhiteBtn[0] && XX <= WhiteBtn[0] + WhiteBtn[2] && 471 | YY >= WhiteBtn[1] && YY <= WhiteBtn[1] + WhiteBtn[3] ) 472 | { 473 | BottomGraphColor = WHITE; 474 | tft.fillRect(WhiteBtn[0], WhiteBtn[1], WhiteBtn[2], WhiteBtn[3], WHITE); 475 | } 476 | else if (XX >= BlackBtn[0] && XX <= BlackBtn[0] + BlackBtn[2] && 477 | YY >= BlackBtn[1] && YY <= BlackBtn[1] + BlackBtn[3] ) 478 | { 479 | BottomGraphColor = BLACK; 480 | tft.fillRect(BlackBtn[0], BlackBtn[1], BlackBtn[2], BlackBtn[3], BLACK); 481 | } 482 | break; 483 | 484 | } 485 | 486 | } 487 | 488 | ////////////////////////////////////////////////////////////////////////////////////////////////// 489 | 490 | 491 | void showMenuOptions() // shows buttons and sets options 492 | { 493 | 494 | int borderSize = 30; // pixels 495 | int marginSize = 10; 496 | 497 | tft.setTextColor( YELLOW); 498 | tft.fillRect(borderSize, borderSize, tft.width() - (borderSize * 2), tft.height() - (borderSize * 2), LIGHTGREY); 499 | 500 | tft.drawRect(borderSize, borderSize, tft.width() - (borderSize * 2), tft.height() - (borderSize * 2), RED); 501 | tft.setCursor((tft.width() / 2) - borderSize, borderSize + marginSize); 502 | tft.setTextSize(3); 503 | tft.println("Menu"); 504 | 505 | int indentRight = 40; 506 | int indentTop = 60; // where to start the text block 507 | int lineHeight = 30; 508 | int buttonSize = 83; 509 | 510 | tft.setCursor( indentRight, indentTop = indentTop + 20); 511 | 512 | // set the button region so a press can be determined 513 | TopBtnArea[0] = indentRight - 5; 514 | TopBtnArea[1] = indentTop - 5; 515 | TopBtnArea[2] = buttonSize; 516 | TopBtnArea[3] = lineHeight + 7; 517 | 518 | 519 | 520 | if (menuState == 1) // top 521 | { 522 | // change button 523 | tft.fillRect(TopBtnArea[0], TopBtnArea[1], TopBtnArea[2], TopBtnArea[3], GREEN); 524 | tft.drawRect(TopBtnArea[0], TopBtnArea[1], TopBtnArea[2], TopBtnArea[3], RED); 525 | setDirectionButtons(); 526 | setColorOptions(); 527 | fillCurrentColor(TopGraphColor); 528 | 529 | } 530 | 531 | else 532 | { 533 | //reset button 534 | tft.fillRect(TopBtnArea[0], TopBtnArea[1], TopBtnArea[2], TopBtnArea[3], WHITE); 535 | tft.drawRect(TopBtnArea[0], TopBtnArea[1], TopBtnArea[2], TopBtnArea[3], RED); 536 | } 537 | tft.setTextSize(2); 538 | tft.setTextColor( BLACK); 539 | tft.setCursor( indentRight + 5, indentTop + 7 ); 540 | tft.print(" TOP "); 541 | 542 | CenterBtnArea[0] = indentRight - 5 + buttonSize; 543 | CenterBtnArea[1] = indentTop - 5; 544 | CenterBtnArea[2] = buttonSize; 545 | CenterBtnArea[3] = lineHeight + 7; 546 | 547 | if (menuState == 2) 548 | { 549 | 550 | tft.fillRect(CenterBtnArea[0], CenterBtnArea[1], CenterBtnArea[2], CenterBtnArea[3], GREEN); 551 | tft.drawRect(CenterBtnArea[0], CenterBtnArea[1], CenterBtnArea[2], CenterBtnArea[3], RED); 552 | setDirectionButtons(); 553 | setColorOptions(); 554 | fillCurrentColor(CenterGraphColor); 555 | } 556 | else 557 | { 558 | tft.fillRect(CenterBtnArea[0], CenterBtnArea[1], CenterBtnArea[2], CenterBtnArea[3], WHITE); 559 | tft.drawRect(CenterBtnArea[0], CenterBtnArea[1], CenterBtnArea[2], CenterBtnArea[3], RED); 560 | 561 | } 562 | 563 | tft.setTextSize(2); 564 | tft.setTextColor( BLACK); 565 | tft.setCursor( indentRight + buttonSize, indentTop + 7 ); 566 | tft.print("CENTER"); 567 | 568 | BottomBtnArea[0] = indentRight - 5 + (buttonSize * 2); 569 | BottomBtnArea[1] = indentTop - 5; 570 | BottomBtnArea[2] = buttonSize; 571 | BottomBtnArea[3] = lineHeight + 7; 572 | 573 | 574 | if (menuState == 3) 575 | { 576 | tft.fillRect(BottomBtnArea[0], BottomBtnArea[1], BottomBtnArea[2], BottomBtnArea[3], GREEN); 577 | tft.drawRect(BottomBtnArea[0], BottomBtnArea[1], BottomBtnArea[2], BottomBtnArea[3], RED); 578 | setDirectionButtons(); 579 | setColorOptions(); 580 | fillCurrentColor(BottomGraphColor); 581 | } 582 | else 583 | { 584 | tft.fillRect(BottomBtnArea[0], BottomBtnArea[1], BottomBtnArea[2], BottomBtnArea[3], WHITE); 585 | tft.drawRect(BottomBtnArea[0], BottomBtnArea[1], BottomBtnArea[2], BottomBtnArea[3], RED); 586 | } 587 | tft.setTextSize(2); 588 | tft.setTextColor( BLACK); 589 | tft.setCursor( indentRight + (buttonSize * 2), indentTop + 7 ); 590 | tft.println("BOTTOM"); 591 | 592 | 593 | drawDoneButton(); 594 | 595 | } 596 | 597 | void fillCurrentColor(int color) 598 | { 599 | switch (color) 600 | { 601 | case RED: 602 | tft.fillRect(RedBtn[0], RedBtn[1], RedBtn[2], RedBtn[3], RED); 603 | break; 604 | case GREEN: 605 | tft.fillRect(GreenBtn[0], GreenBtn[1], GreenBtn[2], GreenBtn[3], GREEN); 606 | break; 607 | case YELLOW: 608 | tft.fillRect(YellowBtn[0], YellowBtn[1], YellowBtn[2], YellowBtn[3], YELLOW); 609 | break; 610 | case BLUE: 611 | tft.fillRect(BlueBtn[0], BlueBtn[1], BlueBtn[2], BlueBtn[3], BLUE); 612 | break; 613 | case WHITE: 614 | tft.fillRect(WhiteBtn[0], WhiteBtn[1], WhiteBtn[2], WhiteBtn[3], WHITE); 615 | break; 616 | case BLACK: 617 | tft.fillRect(BlackBtn[0], BlackBtn[1], BlackBtn[2], BlackBtn[3], BLACK); 618 | break; 619 | } 620 | } 621 | 622 | 623 | void setDirectionButtons() 624 | { 625 | 626 | 627 | switch (menuState) 628 | { 629 | case 1: 630 | if (TopDirection == 1) 631 | tft.drawRect(LeftArrowArea[0], LeftArrowArea[1], LeftArrowArea[2], LeftArrowArea[3], GREEN); // touch region for left arrow 632 | else 633 | tft.drawRect(RightArrowArea[0], RightArrowArea[1], RightArrowArea[2], RightArrowArea[3], GREEN); // touch region for left arrow 634 | 635 | break; 636 | 637 | case 2: 638 | if (CenterDirection == 1) 639 | tft.drawRect(LeftArrowArea[0], LeftArrowArea[1], LeftArrowArea[2], LeftArrowArea[3], GREEN); // touch region for left arrow 640 | else 641 | tft.drawRect(RightArrowArea[0], RightArrowArea[1], RightArrowArea[2], RightArrowArea[3], GREEN); // touch region for left arrow 642 | 643 | break; 644 | 645 | case 3: 646 | if (BottomDirection == 1) 647 | tft.drawRect(LeftArrowArea[0], LeftArrowArea[1], LeftArrowArea[2], LeftArrowArea[3], GREEN); // touch region for left arrow 648 | else 649 | tft.drawRect(RightArrowArea[0], RightArrowArea[1], RightArrowArea[2], RightArrowArea[3], GREEN); // touch region for left arrow 650 | 651 | break; 652 | } 653 | tft.fillRect(50, 191, 20, 9, RED); 654 | tft.fillTriangle(35, 195, 50, 185, 50, 205, RED); 655 | 656 | // tft.drawRect(76, 181, 42, 27, BLUE); // touch region for right arrow 657 | tft.fillRect(80, 191, 20, 9, GREEN); 658 | tft.fillTriangle(115, 195, 100, 185, 100, 205, GREEN); 659 | 660 | 661 | } 662 | 663 | void setColorOptions() 664 | { 665 | 666 | tft.setCursor(DataArea[0], DataArea[1]); 667 | tft.setTextSize(1); 668 | tft.setTextColor(YELLOW); 669 | tft.println("Color"); 670 | 671 | 672 | tft.drawRect(RedBtn[0], RedBtn[1], RedBtn[2], RedBtn[3], RED); 673 | tft.drawRect(GreenBtn[0], GreenBtn[1], GreenBtn[2], GreenBtn[3], GREEN); 674 | tft.drawRect(YellowBtn[0], YellowBtn[1], YellowBtn[2], YellowBtn[3], YELLOW); 675 | tft.drawRect(BlueBtn[0], BlueBtn[1], BlueBtn[2], BlueBtn[3], BLUE); 676 | tft.drawRect(WhiteBtn[0], WhiteBtn[1], WhiteBtn[2], WhiteBtn[3], WHITE); 677 | tft.drawRect(BlackBtn[0], BlackBtn[1], BlackBtn[2], BlackBtn[3], BLACK); 678 | 679 | } 680 | 681 | 682 | void showData(int x, int y, int z, int XX, int YY) 683 | { 684 | int indentRight = 40; 685 | int indentTop = 125; // where to start the text block 686 | int lineHeight = 9; 687 | 688 | DataArea[0] = indentRight - 5; 689 | DataArea[1] = indentTop; 690 | DataArea[2] = 250; 691 | DataArea[3] = 80; 692 | 693 | tft.drawRect(DataArea[0], DataArea[1], DataArea[2], DataArea[3], RED); 694 | 695 | tft.setTextSize(1); 696 | tft.setTextColor( YELLOW); // converts the pressure reading to a color 697 | tft.setCursor( indentRight, indentTop = indentTop + lineHeight); 698 | 699 | tft.println("DATA CAPTURE"); 700 | tft.setCursor( indentRight, indentTop = indentTop + lineHeight); 701 | 702 | tft.setTextColor( WHITE); 703 | tft.print("Raw X = "); tft.print(x); 704 | tft.print(" Raw Y = "); tft.println(y); 705 | tft.setCursor( indentRight, indentTop = indentTop + lineHeight); 706 | 707 | tft.print("Pressure = "); tft.println(z); 708 | tft.setCursor( indentRight, indentTop = indentTop + lineHeight); 709 | 710 | tft.print("ScreenX: " ); tft.print(XX); 711 | tft.print(" ScreenY:"); tft.println(YY); 712 | tft.setCursor( indentRight, indentTop = indentTop + lineHeight); 713 | 714 | tft.print("Raw Sensor 1 "); tft.println(sensor1Val); 715 | tft.setCursor( indentRight, indentTop = indentTop + lineHeight); 716 | 717 | tft.print("Raw Sensor 2 "); tft.println(sensor2Val); 718 | tft.setCursor( indentRight, indentTop = indentTop + lineHeight); 719 | 720 | tft.print("Loop counter "); tft.println(loopCounter); 721 | tft.setCursor( indentRight, indentTop = indentTop + lineHeight); 722 | } 723 | 724 | ////////////////////// 725 | 726 | void drawDoneButton() 727 | { 728 | tft.fillRect(DoneBtnArea[0], DoneBtnArea[1], DoneBtnArea[2], DoneBtnArea[3], BLACK); 729 | tft.drawRect(DoneBtnArea[0], DoneBtnArea[1], DoneBtnArea[2], DoneBtnArea[3], WHITE); 730 | 731 | tft.setCursor(DoneBtnArea[0] + 10, DoneBtnArea[1] + 7); 732 | tft.setTextColor(WHITE); 733 | tft.print("Done"); 734 | } 735 | ///////////////////////////////////////////////////////////////////////////////////////////////////// 736 | -------------------------------------------------------------------------------- /libraries/Adafruit_TFTLCD/Adafruit_TFTLCD.cpp: -------------------------------------------------------------------------------- 1 | // IMPORTANT: LIBRARY MUST BE SPECIFICALLY CONFIGURED FOR EITHER TFT SHIELD 2 | // OR BREAKOUT BOARD USAGE. SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h 3 | 4 | // Graphics library by ladyada/adafruit with init code from Rossum 5 | // MIT license 6 | 7 | #if defined(__SAM3X8E__) 8 | #include 9 | #define PROGMEM 10 | #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 11 | #define pgm_read_word(addr) (*(const unsigned short *)(addr)) 12 | #endif 13 | #ifdef __AVR__ 14 | #include 15 | #endif 16 | #include "pins_arduino.h" 17 | #include "wiring_private.h" 18 | #include "Adafruit_TFTLCD.h" 19 | #if defined __AVR_ATmega328P__ 20 | #include "pin_magic_UNO.h" 21 | #endif 22 | #if defined __AVR_ATmega2560__ 23 | #include "pin_magic_MEGA.h" 24 | 25 | #endif 26 | 27 | 28 | //#define TFTWIDTH 320 29 | //#define TFTHEIGHT 480 30 | 31 | #define TFTWIDTH 240 32 | #define TFTHEIGHT 320 33 | 34 | // LCD controller chip identifiers 35 | #define ID_932X 0 36 | #define ID_7575 1 37 | #define ID_9341 2 38 | #define ID_HX8357D 3 39 | #define ID_UNKNOWN 0xFF 40 | 41 | #include "registers.h" 42 | 43 | // Constructor for breakout board (configurable LCD control lines). 44 | // Can still use this w/shield, but parameters are ignored. 45 | Adafruit_TFTLCD::Adafruit_TFTLCD( 46 | uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t reset) : 47 | Adafruit_GFX(TFTWIDTH, TFTHEIGHT) { 48 | 49 | #ifndef USE_ADAFRUIT_SHIELD_PINOUT 50 | // Convert pin numbers to registers and bitmasks 51 | _reset = reset; 52 | #ifdef __AVR__ 53 | csPort = portOutputRegister(digitalPinToPort(cs)); 54 | cdPort = portOutputRegister(digitalPinToPort(cd)); 55 | wrPort = portOutputRegister(digitalPinToPort(wr)); 56 | rdPort = portOutputRegister(digitalPinToPort(rd)); 57 | #endif 58 | #if defined(__SAM3X8E__) 59 | csPort = digitalPinToPort(cs); 60 | cdPort = digitalPinToPort(cd); 61 | wrPort = digitalPinToPort(wr); 62 | rdPort = digitalPinToPort(rd); 63 | #endif 64 | csPinSet = digitalPinToBitMask(cs); 65 | cdPinSet = digitalPinToBitMask(cd); 66 | wrPinSet = digitalPinToBitMask(wr); 67 | rdPinSet = digitalPinToBitMask(rd); 68 | csPinUnset = ~csPinSet; 69 | cdPinUnset = ~cdPinSet; 70 | wrPinUnset = ~wrPinSet; 71 | rdPinUnset = ~rdPinSet; 72 | #ifdef __AVR__ 73 | *csPort |= csPinSet; // Set all control bits to HIGH (idle) 74 | *cdPort |= cdPinSet; // Signals are ACTIVE LOW 75 | *wrPort |= wrPinSet; 76 | *rdPort |= rdPinSet; 77 | #endif 78 | #if defined(__SAM3X8E__) 79 | csPort->PIO_SODR |= csPinSet; // Set all control bits to HIGH (idle) 80 | cdPort->PIO_SODR |= cdPinSet; // Signals are ACTIVE LOW 81 | wrPort->PIO_SODR |= wrPinSet; 82 | rdPort->PIO_SODR |= rdPinSet; 83 | #endif 84 | pinMode(cs, OUTPUT); // Enable outputs 85 | pinMode(cd, OUTPUT); 86 | pinMode(wr, OUTPUT); 87 | pinMode(rd, OUTPUT); 88 | if(reset) { 89 | digitalWrite(reset, HIGH); 90 | pinMode(reset, OUTPUT); 91 | } 92 | #endif 93 | 94 | init(); 95 | } 96 | 97 | // Constructor for shield (fixed LCD control lines) 98 | Adafruit_TFTLCD::Adafruit_TFTLCD(void) : Adafruit_GFX(TFTWIDTH, TFTHEIGHT) { 99 | init(); 100 | } 101 | 102 | // Initialization common to both shield & breakout configs 103 | void Adafruit_TFTLCD::init(void) { 104 | 105 | #ifdef USE_ADAFRUIT_SHIELD_PINOUT 106 | CS_IDLE; // Set all control bits to idle state 107 | WR_IDLE; 108 | RD_IDLE; 109 | CD_DATA; 110 | digitalWrite(5, HIGH); // Reset line 111 | pinMode(A3, OUTPUT); // Enable outputs 112 | pinMode(A2, OUTPUT); 113 | pinMode(A1, OUTPUT); 114 | pinMode(A0, OUTPUT); 115 | pinMode( 5, OUTPUT); 116 | #endif 117 | 118 | setWriteDir(); // Set up LCD data port(s) for WRITE operations 119 | 120 | rotation = 0; 121 | cursor_y = cursor_x = 0; 122 | textsize = 1; 123 | textcolor = 0xFFFF; 124 | _width = TFTWIDTH; 125 | _height = TFTHEIGHT; 126 | } 127 | 128 | // Initialization command tables for different LCD controllers 129 | #define TFTLCD_DELAY 0xFF 130 | static const uint8_t HX8347G_regValues[] PROGMEM = { 131 | 0x2E , 0x89, 132 | 0x29 , 0x8F, 133 | 0x2B , 0x02, 134 | 0xE2 , 0x00, 135 | 0xE4 , 0x01, 136 | 0xE5 , 0x10, 137 | 0xE6 , 0x01, 138 | 0xE7 , 0x10, 139 | 0xE8 , 0x70, 140 | 0xF2 , 0x00, 141 | 0xEA , 0x00, 142 | 0xEB , 0x20, 143 | 0xEC , 0x3C, 144 | 0xED , 0xC8, 145 | 0xE9 , 0x38, 146 | 0xF1 , 0x01, 147 | 148 | // skip gamma, do later 149 | 150 | 0x1B , 0x1A, 151 | 0x1A , 0x02, 152 | 0x24 , 0x61, 153 | 0x25 , 0x5C, 154 | 155 | 0x18 , 0x36, 156 | 0x19 , 0x01, 157 | 0x1F , 0x88, 158 | TFTLCD_DELAY , 5 , // delay 5 ms 159 | 0x1F , 0x80, 160 | TFTLCD_DELAY , 5 , 161 | 0x1F , 0x90, 162 | TFTLCD_DELAY , 5 , 163 | 0x1F , 0xD4, 164 | TFTLCD_DELAY , 5 , 165 | 0x17 , 0x05, 166 | 167 | 0x36 , 0x09, 168 | 0x28 , 0x38, 169 | TFTLCD_DELAY , 40 , 170 | 0x28 , 0x3C, 171 | 172 | 0x02 , 0x00, 173 | 0x03 , 0x00, 174 | 0x04 , 0x00, 175 | 0x05 , 0xEF, 176 | 0x06 , 0x00, 177 | 0x07 , 0x00, 178 | 0x08 , 0x01, 179 | 0x09 , 0x3F 180 | }; 181 | 182 | static const uint8_t HX8357D_regValues[] PROGMEM = { 183 | HX8357_SWRESET, 0, 184 | HX8357D_SETC, 3, 0xFF, 0x83, 0x57, 185 | TFTLCD_DELAY, 250, 186 | HX8357_SETRGB, 4, 0x00, 0x00, 0x06, 0x06, 187 | HX8357D_SETCOM, 1, 0x25, // -1.52V 188 | HX8357_SETOSC, 1, 0x68, // Normal mode 70Hz, Idle mode 55 Hz 189 | HX8357_SETPANEL, 1, 0x05, // BGR, Gate direction swapped 190 | HX8357_SETPWR1, 6, 0x00, 0x15, 0x1C, 0x1C, 0x83, 0xAA, 191 | HX8357D_SETSTBA, 6, 0x50, 0x50, 0x01, 0x3C, 0x1E, 0x08, 192 | // MEME GAMMA HERE 193 | HX8357D_SETCYC, 7, 0x02, 0x40, 0x00, 0x2A, 0x2A, 0x0D, 0x78, 194 | HX8357_COLMOD, 1, 0x55, 195 | HX8357_MADCTL, 1, 0xC0, 196 | HX8357_TEON, 1, 0x00, 197 | HX8357_TEARLINE, 2, 0x00, 0x02, 198 | HX8357_SLPOUT, 0, 199 | TFTLCD_DELAY, 150, 200 | HX8357_DISPON, 0, 201 | TFTLCD_DELAY, 50, 202 | }; 203 | 204 | static const uint16_t ILI932x_regValues[] PROGMEM = { 205 | ILI932X_START_OSC , 0x0001, // Start oscillator 206 | TFTLCD_DELAY , 50, // 50 millisecond delay 207 | ILI932X_DRIV_OUT_CTRL , 0x0100, 208 | ILI932X_DRIV_WAV_CTRL , 0x0700, 209 | ILI932X_ENTRY_MOD , 0x1030, 210 | ILI932X_RESIZE_CTRL , 0x0000, 211 | ILI932X_DISP_CTRL2 , 0x0202, 212 | ILI932X_DISP_CTRL3 , 0x0000, 213 | ILI932X_DISP_CTRL4 , 0x0000, 214 | ILI932X_RGB_DISP_IF_CTRL1, 0x0, 215 | ILI932X_FRM_MARKER_POS , 0x0, 216 | ILI932X_RGB_DISP_IF_CTRL2, 0x0, 217 | ILI932X_POW_CTRL1 , 0x0000, 218 | ILI932X_POW_CTRL2 , 0x0007, 219 | ILI932X_POW_CTRL3 , 0x0000, 220 | ILI932X_POW_CTRL4 , 0x0000, 221 | TFTLCD_DELAY , 200, 222 | ILI932X_POW_CTRL1 , 0x1690, 223 | ILI932X_POW_CTRL2 , 0x0227, 224 | TFTLCD_DELAY , 50, 225 | ILI932X_POW_CTRL3 , 0x001A, 226 | TFTLCD_DELAY , 50, 227 | ILI932X_POW_CTRL4 , 0x1800, 228 | ILI932X_POW_CTRL7 , 0x002A, 229 | TFTLCD_DELAY , 50, 230 | ILI932X_GAMMA_CTRL1 , 0x0000, 231 | ILI932X_GAMMA_CTRL2 , 0x0000, 232 | ILI932X_GAMMA_CTRL3 , 0x0000, 233 | ILI932X_GAMMA_CTRL4 , 0x0206, 234 | ILI932X_GAMMA_CTRL5 , 0x0808, 235 | ILI932X_GAMMA_CTRL6 , 0x0007, 236 | ILI932X_GAMMA_CTRL7 , 0x0201, 237 | ILI932X_GAMMA_CTRL8 , 0x0000, 238 | ILI932X_GAMMA_CTRL9 , 0x0000, 239 | ILI932X_GAMMA_CTRL10 , 0x0000, 240 | ILI932X_GRAM_HOR_AD , 0x0000, 241 | ILI932X_GRAM_VER_AD , 0x0000, 242 | ILI932X_HOR_START_AD , 0x0000, 243 | ILI932X_HOR_END_AD , 0x00EF, 244 | ILI932X_VER_START_AD , 0X0000, 245 | ILI932X_VER_END_AD , 0x013F, 246 | ILI932X_GATE_SCAN_CTRL1 , 0xA700, // Driver Output Control (R60h) 247 | ILI932X_GATE_SCAN_CTRL2 , 0x0003, // Driver Output Control (R61h) 248 | ILI932X_GATE_SCAN_CTRL3 , 0x0000, // Driver Output Control (R62h) 249 | ILI932X_PANEL_IF_CTRL1 , 0X0010, // Panel Interface Control 1 (R90h) 250 | ILI932X_PANEL_IF_CTRL2 , 0X0000, 251 | ILI932X_PANEL_IF_CTRL3 , 0X0003, 252 | ILI932X_PANEL_IF_CTRL4 , 0X1100, 253 | ILI932X_PANEL_IF_CTRL5 , 0X0000, 254 | ILI932X_PANEL_IF_CTRL6 , 0X0000, 255 | ILI932X_DISP_CTRL1 , 0x0133, // Main screen turn on 256 | }; 257 | 258 | void Adafruit_TFTLCD::begin(uint16_t id) { 259 | uint8_t i = 0; 260 | 261 | reset(); 262 | 263 | delay(200); 264 | 265 | if((id == 0x9325) || (id == 0x9328)) { 266 | 267 | uint16_t a, d; 268 | driver = ID_932X; 269 | CS_ACTIVE; 270 | while(i < sizeof(ILI932x_regValues) / sizeof(uint16_t)) { 271 | a = pgm_read_word(&ILI932x_regValues[i++]); 272 | d = pgm_read_word(&ILI932x_regValues[i++]); 273 | if(a == TFTLCD_DELAY) delay(d); 274 | else writeRegister16(a, d); 275 | } 276 | setRotation(rotation); 277 | setAddrWindow(0, 0, TFTWIDTH-1, TFTHEIGHT-1); 278 | 279 | } else if (id == 0x9341) { 280 | 281 | uint16_t a, d; 282 | driver = ID_9341; 283 | CS_ACTIVE; 284 | writeRegister8(ILI9341_SOFTRESET, 0); 285 | delay(50); 286 | writeRegister8(ILI9341_DISPLAYOFF, 0); 287 | 288 | writeRegister8(ILI9341_POWERCONTROL1, 0x23); 289 | writeRegister8(ILI9341_POWERCONTROL2, 0x10); 290 | writeRegister16(ILI9341_VCOMCONTROL1, 0x2B2B); 291 | writeRegister8(ILI9341_VCOMCONTROL2, 0xC0); 292 | writeRegister8(ILI9341_MEMCONTROL, ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR); 293 | writeRegister8(ILI9341_PIXELFORMAT, 0x55); 294 | writeRegister16(ILI9341_FRAMECONTROL, 0x001B); 295 | 296 | writeRegister8(ILI9341_ENTRYMODE, 0x07); 297 | /* writeRegister32(ILI9341_DISPLAYFUNC, 0x0A822700);*/ 298 | 299 | writeRegister8(ILI9341_SLEEPOUT, 0); 300 | delay(150); 301 | writeRegister8(ILI9341_DISPLAYON, 0); 302 | delay(500); 303 | setAddrWindow(0, 0, TFTWIDTH-1, TFTHEIGHT-1); 304 | return; 305 | 306 | } else if (id == 0x8357) { 307 | // HX8357D 308 | driver = ID_HX8357D; 309 | CS_ACTIVE; 310 | while(i < sizeof(HX8357D_regValues)) { 311 | uint8_t r = pgm_read_byte(&HX8357D_regValues[i++]); 312 | uint8_t len = pgm_read_byte(&HX8357D_regValues[i++]); 313 | if(r == TFTLCD_DELAY) { 314 | delay(len); 315 | } else { 316 | //Serial.print("Register $"); Serial.print(r, HEX); 317 | //Serial.print(" datalen "); Serial.println(len); 318 | 319 | CS_ACTIVE; 320 | CD_COMMAND; 321 | write8(r); 322 | CD_DATA; 323 | for (uint8_t d=0; d= x1). 388 | void Adafruit_TFTLCD::setAddrWindow(int x1, int y1, int x2, int y2) { 389 | CS_ACTIVE; 390 | if(driver == ID_932X) { 391 | 392 | // Values passed are in current (possibly rotated) coordinate 393 | // system. 932X requires hardware-native coords regardless of 394 | // MADCTL, so rotate inputs as needed. The address counter is 395 | // set to the top-left corner -- although fill operations can be 396 | // done in any direction, the current screen rotation is applied 397 | // because some users find it disconcerting when a fill does not 398 | // occur top-to-bottom. 399 | int x, y, t; 400 | switch(rotation) { 401 | default: 402 | x = x1; 403 | y = y1; 404 | break; 405 | case 1: 406 | t = y1; 407 | y1 = x1; 408 | x1 = TFTWIDTH - 1 - y2; 409 | y2 = x2; 410 | x2 = TFTWIDTH - 1 - t; 411 | x = x2; 412 | y = y1; 413 | break; 414 | case 2: 415 | t = x1; 416 | x1 = TFTWIDTH - 1 - x2; 417 | x2 = TFTWIDTH - 1 - t; 418 | t = y1; 419 | y1 = TFTHEIGHT - 1 - y2; 420 | y2 = TFTHEIGHT - 1 - t; 421 | x = x2; 422 | y = y2; 423 | break; 424 | case 3: 425 | t = x1; 426 | x1 = y1; 427 | y1 = TFTHEIGHT - 1 - x2; 428 | x2 = y2; 429 | y2 = TFTHEIGHT - 1 - t; 430 | x = x1; 431 | y = y2; 432 | break; 433 | } 434 | writeRegister16(0x0050, x1); // Set address window 435 | writeRegister16(0x0051, x2); 436 | writeRegister16(0x0052, y1); 437 | writeRegister16(0x0053, y2); 438 | writeRegister16(0x0020, x ); // Set address counter to top left 439 | writeRegister16(0x0021, y ); 440 | 441 | } else if(driver == ID_7575) { 442 | 443 | writeRegisterPair(HX8347G_COLADDRSTART_HI, HX8347G_COLADDRSTART_LO, x1); 444 | writeRegisterPair(HX8347G_ROWADDRSTART_HI, HX8347G_ROWADDRSTART_LO, y1); 445 | writeRegisterPair(HX8347G_COLADDREND_HI , HX8347G_COLADDREND_LO , x2); 446 | writeRegisterPair(HX8347G_ROWADDREND_HI , HX8347G_ROWADDREND_LO , y2); 447 | 448 | } else if ((driver == ID_9341) || (driver == ID_HX8357D)){ 449 | uint32_t t; 450 | 451 | t = x1; 452 | t <<= 16; 453 | t |= x2; 454 | writeRegister32(ILI9341_COLADDRSET, t); // HX8357D uses same registers! 455 | t = y1; 456 | t <<= 16; 457 | t |= y2; 458 | writeRegister32(ILI9341_PAGEADDRSET, t); // HX8357D uses same registers! 459 | 460 | } 461 | CS_IDLE; 462 | } 463 | 464 | // Unlike the 932X drivers that set the address window to the full screen 465 | // by default (using the address counter for drawPixel operations), the 466 | // 7575 needs the address window set on all graphics operations. In order 467 | // to save a few register writes on each pixel drawn, the lower-right 468 | // corner of the address window is reset after most fill operations, so 469 | // that drawPixel only needs to change the upper left each time. 470 | void Adafruit_TFTLCD::setLR(void) { 471 | CS_ACTIVE; 472 | writeRegisterPair(HX8347G_COLADDREND_HI, HX8347G_COLADDREND_LO, _width - 1); 473 | writeRegisterPair(HX8347G_ROWADDREND_HI, HX8347G_ROWADDREND_LO, _height - 1); 474 | CS_IDLE; 475 | } 476 | 477 | // Fast block fill operation for fillScreen, fillRect, H/V line, etc. 478 | // Requires setAddrWindow() has previously been called to set the fill 479 | // bounds. 'len' is inclusive, MUST be >= 1. 480 | void Adafruit_TFTLCD::flood(uint16_t color, uint32_t len) { 481 | uint16_t blocks; 482 | uint8_t i, hi = color >> 8, 483 | lo = color; 484 | 485 | CS_ACTIVE; 486 | CD_COMMAND; 487 | if (driver == ID_9341) { 488 | write8(0x2C); 489 | } else if (driver == ID_932X) { 490 | write8(0x00); // High byte of GRAM register... 491 | write8(0x22); // Write data to GRAM 492 | } else if (driver == ID_HX8357D) { 493 | write8(HX8357_RAMWR); 494 | } else { 495 | write8(0x22); // Write data to GRAM 496 | } 497 | 498 | // Write first pixel normally, decrement counter by 1 499 | CD_DATA; 500 | write8(hi); 501 | write8(lo); 502 | len--; 503 | 504 | blocks = (uint16_t)(len / 64); // 64 pixels/block 505 | if(hi == lo) { 506 | // High and low bytes are identical. Leave prior data 507 | // on the port(s) and just toggle the write strobe. 508 | while(blocks--) { 509 | i = 16; // 64 pixels/block / 4 pixels/pass 510 | do { 511 | WR_STROBE; WR_STROBE; WR_STROBE; WR_STROBE; // 2 bytes/pixel 512 | WR_STROBE; WR_STROBE; WR_STROBE; WR_STROBE; // x 4 pixels 513 | } while(--i); 514 | } 515 | // Fill any remaining pixels (1 to 64) 516 | for(i = (uint8_t)len & 63; i--; ) { 517 | WR_STROBE; 518 | WR_STROBE; 519 | } 520 | } else { 521 | while(blocks--) { 522 | i = 16; // 64 pixels/block / 4 pixels/pass 523 | do { 524 | write8(hi); write8(lo); write8(hi); write8(lo); 525 | write8(hi); write8(lo); write8(hi); write8(lo); 526 | } while(--i); 527 | } 528 | for(i = (uint8_t)len & 63; i--; ) { 529 | write8(hi); 530 | write8(lo); 531 | } 532 | } 533 | CS_IDLE; 534 | } 535 | 536 | void Adafruit_TFTLCD::drawFastHLine(int16_t x, int16_t y, int16_t length, 537 | uint16_t color) 538 | { 539 | int16_t x2; 540 | 541 | // Initial off-screen clipping 542 | if((length <= 0 ) || 543 | (y < 0 ) || ( y >= _height) || 544 | (x >= _width) || ((x2 = (x+length-1)) < 0 )) return; 545 | 546 | if(x < 0) { // Clip left 547 | length += x; 548 | x = 0; 549 | } 550 | if(x2 >= _width) { // Clip right 551 | x2 = _width - 1; 552 | length = x2 - x + 1; 553 | } 554 | 555 | setAddrWindow(x, y, x2, y); 556 | flood(color, length); 557 | if(driver == ID_932X) setAddrWindow(0, 0, _width - 1, _height - 1); 558 | else setLR(); 559 | } 560 | 561 | void Adafruit_TFTLCD::drawFastVLine(int16_t x, int16_t y, int16_t length, 562 | uint16_t color) 563 | { 564 | int16_t y2; 565 | 566 | // Initial off-screen clipping 567 | if((length <= 0 ) || 568 | (x < 0 ) || ( x >= _width) || 569 | (y >= _height) || ((y2 = (y+length-1)) < 0 )) return; 570 | if(y < 0) { // Clip top 571 | length += y; 572 | y = 0; 573 | } 574 | if(y2 >= _height) { // Clip bottom 575 | y2 = _height - 1; 576 | length = y2 - y + 1; 577 | } 578 | 579 | setAddrWindow(x, y, x, y2); 580 | flood(color, length); 581 | if(driver == ID_932X) setAddrWindow(0, 0, _width - 1, _height - 1); 582 | else setLR(); 583 | } 584 | 585 | void Adafruit_TFTLCD::fillRect(int16_t x1, int16_t y1, int16_t w, int16_t h, 586 | uint16_t fillcolor) { 587 | int16_t x2, y2; 588 | 589 | // Initial off-screen clipping 590 | if( (w <= 0 ) || (h <= 0 ) || 591 | (x1 >= _width) || (y1 >= _height) || 592 | ((x2 = x1+w-1) < 0 ) || ((y2 = y1+h-1) < 0 )) return; 593 | if(x1 < 0) { // Clip left 594 | w += x1; 595 | x1 = 0; 596 | } 597 | if(y1 < 0) { // Clip top 598 | h += y1; 599 | y1 = 0; 600 | } 601 | if(x2 >= _width) { // Clip right 602 | x2 = _width - 1; 603 | w = x2 - x1 + 1; 604 | } 605 | if(y2 >= _height) { // Clip bottom 606 | y2 = _height - 1; 607 | h = y2 - y1 + 1; 608 | } 609 | 610 | setAddrWindow(x1, y1, x2, y2); 611 | flood(fillcolor, (uint32_t)w * (uint32_t)h); 612 | if(driver == ID_932X) setAddrWindow(0, 0, _width - 1, _height - 1); 613 | else setLR(); 614 | } 615 | 616 | void Adafruit_TFTLCD::fillScreen(uint16_t color) { 617 | 618 | if(driver == ID_932X) { 619 | 620 | // For the 932X, a full-screen address window is already the default 621 | // state, just need to set the address pointer to the top-left corner. 622 | // Although we could fill in any direction, the code uses the current 623 | // screen rotation because some users find it disconcerting when a 624 | // fill does not occur top-to-bottom. 625 | uint16_t x, y; 626 | switch(rotation) { 627 | default: x = 0 ; y = 0 ; break; 628 | case 1 : x = TFTWIDTH - 1; y = 0 ; break; 629 | case 2 : x = TFTWIDTH - 1; y = TFTHEIGHT - 1; break; 630 | case 3 : x = 0 ; y = TFTHEIGHT - 1; break; 631 | } 632 | CS_ACTIVE; 633 | writeRegister16(0x0020, x); 634 | writeRegister16(0x0021, y); 635 | 636 | } else if ((driver == ID_9341) || (driver == ID_7575) || (driver == ID_HX8357D)) { 637 | // For these, there is no settable address pointer, instead the 638 | // address window must be set for each drawing operation. However, 639 | // this display takes rotation into account for the parameters, no 640 | // need to do extra rotation math here. 641 | setAddrWindow(0, 0, _width - 1, _height - 1); 642 | 643 | } 644 | flood(color, (long)TFTWIDTH * (long)TFTHEIGHT); 645 | } 646 | 647 | void Adafruit_TFTLCD::drawPixel(int16_t x, int16_t y, uint16_t color) { 648 | 649 | // Clip 650 | if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return; 651 | 652 | CS_ACTIVE; 653 | if(driver == ID_932X) { 654 | int16_t t; 655 | switch(rotation) { 656 | case 1: 657 | t = x; 658 | x = TFTWIDTH - 1 - y; 659 | y = t; 660 | break; 661 | case 2: 662 | x = TFTWIDTH - 1 - x; 663 | y = TFTHEIGHT - 1 - y; 664 | break; 665 | case 3: 666 | t = x; 667 | x = y; 668 | y = TFTHEIGHT - 1 - t; 669 | break; 670 | } 671 | writeRegister16(0x0020, x); 672 | writeRegister16(0x0021, y); 673 | writeRegister16(0x0022, color); 674 | 675 | } else if(driver == ID_7575) { 676 | 677 | uint8_t hi, lo; 678 | switch(rotation) { 679 | default: lo = 0 ; break; 680 | case 1 : lo = 0x60; break; 681 | case 2 : lo = 0xc0; break; 682 | case 3 : lo = 0xa0; break; 683 | } 684 | writeRegister8( HX8347G_MEMACCESS , lo); 685 | // Only upper-left is set -- bottom-right is full screen default 686 | writeRegisterPair(HX8347G_COLADDRSTART_HI, HX8347G_COLADDRSTART_LO, x); 687 | writeRegisterPair(HX8347G_ROWADDRSTART_HI, HX8347G_ROWADDRSTART_LO, y); 688 | hi = color >> 8; lo = color; 689 | CD_COMMAND; write8(0x22); CD_DATA; write8(hi); write8(lo); 690 | 691 | } else if ((driver == ID_9341) || (driver == ID_HX8357D)) { 692 | setAddrWindow(x, y, _width-1, _height-1); 693 | CS_ACTIVE; 694 | CD_COMMAND; 695 | write8(0x2C); 696 | CD_DATA; 697 | write8(color >> 8); write8(color); 698 | } 699 | 700 | CS_IDLE; 701 | } 702 | 703 | // Issues 'raw' an array of 16-bit color values to the LCD; used 704 | // externally by BMP examples. Assumes that setWindowAddr() has 705 | // previously been set to define the bounds. Max 255 pixels at 706 | // a time (BMP examples read in small chunks due to limited RAM). 707 | void Adafruit_TFTLCD::pushColors(uint16_t *data, uint8_t len, boolean first) { 708 | uint16_t color; 709 | uint8_t hi, lo; 710 | CS_ACTIVE; 711 | if(first == true) { // Issue GRAM write command only on first call 712 | CD_COMMAND; 713 | if(driver == ID_932X) write8(0x00); 714 | if ((driver == ID_9341) || (driver == ID_HX8357D)){ 715 | write8(0x2C); 716 | } else { 717 | write8(0x22); 718 | } 719 | } 720 | CD_DATA; 721 | while(len--) { 722 | color = *data++; 723 | hi = color >> 8; // Don't simplify or merge these 724 | lo = color; // lines, there's macro shenanigans 725 | write8(hi); // going on. 726 | write8(lo); 727 | } 728 | CS_IDLE; 729 | } 730 | 731 | void Adafruit_TFTLCD::setRotation(uint8_t x) { 732 | 733 | // Call parent rotation func first -- sets up rotation flags, etc. 734 | Adafruit_GFX::setRotation(x); 735 | // Then perform hardware-specific rotation operations... 736 | 737 | CS_ACTIVE; 738 | if(driver == ID_932X) { 739 | 740 | uint16_t t; 741 | switch(rotation) { 742 | default: t = 0x1030; break; 743 | case 1 : t = 0x1028; break; 744 | case 2 : t = 0x1000; break; 745 | case 3 : t = 0x1018; break; 746 | } 747 | writeRegister16(0x0003, t ); // MADCTL 748 | // For 932X, init default full-screen address window: 749 | setAddrWindow(0, 0, _width - 1, _height - 1); // CS_IDLE happens here 750 | 751 | } 752 | if(driver == ID_7575) { 753 | 754 | uint8_t t; 755 | switch(rotation) { 756 | default: t = 0 ; break; 757 | case 1 : t = 0x60; break; 758 | case 2 : t = 0xc0; break; 759 | case 3 : t = 0xa0; break; 760 | } 761 | writeRegister8(HX8347G_MEMACCESS, t); 762 | // 7575 has to set the address window on most drawing operations. 763 | // drawPixel() cheats by setting only the top left...by default, 764 | // the lower right is always reset to the corner. 765 | setLR(); // CS_IDLE happens here 766 | } 767 | 768 | if (driver == ID_9341) { 769 | // MEME, HX8357D uses same registers as 9341 but different values 770 | uint16_t t; 771 | 772 | switch (rotation) { 773 | case 2: 774 | t = ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR; 775 | break; 776 | case 3: 777 | t = ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR; 778 | break; 779 | case 0: 780 | t = ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR; 781 | break; 782 | case 1: 783 | t = ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR; 784 | break; 785 | } 786 | writeRegister8(ILI9341_MADCTL, t ); // MADCTL 787 | // For 9341, init default full-screen address window: 788 | setAddrWindow(0, 0, _width - 1, _height - 1); // CS_IDLE happens here 789 | } 790 | 791 | if (driver == ID_HX8357D) { 792 | // MEME, HX8357D uses same registers as 9341 but different values 793 | uint16_t t; 794 | 795 | switch (rotation) { 796 | case 2: 797 | t = HX8357B_MADCTL_RGB; 798 | break; 799 | case 3: 800 | t = HX8357B_MADCTL_MX | HX8357B_MADCTL_MV | HX8357B_MADCTL_RGB; 801 | break; 802 | case 0: 803 | t = HX8357B_MADCTL_MX | HX8357B_MADCTL_MY | HX8357B_MADCTL_RGB; 804 | break; 805 | case 1: 806 | t = HX8357B_MADCTL_MY | HX8357B_MADCTL_MV | HX8357B_MADCTL_RGB; 807 | break; 808 | } 809 | writeRegister8(ILI9341_MADCTL, t ); // MADCTL 810 | // For 8357, init default full-screen address window: 811 | setAddrWindow(0, 0, _width - 1, _height - 1); // CS_IDLE happens here 812 | }} 813 | 814 | #ifdef read8isFunctionalized 815 | #define read8(x) x=read8fn() 816 | #endif 817 | 818 | // Because this function is used infrequently, it configures the ports for 819 | // the read operation, reads the data, then restores the ports to the write 820 | // configuration. Write operations happen a LOT, so it's advantageous to 821 | // leave the ports in that state as a default. 822 | uint16_t Adafruit_TFTLCD::readPixel(int16_t x, int16_t y) { 823 | 824 | if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return 0; 825 | 826 | CS_ACTIVE; 827 | if(driver == ID_932X) { 828 | 829 | uint8_t hi, lo; 830 | int16_t t; 831 | switch(rotation) { 832 | case 1: 833 | t = x; 834 | x = TFTWIDTH - 1 - y; 835 | y = t; 836 | break; 837 | case 2: 838 | x = TFTWIDTH - 1 - x; 839 | y = TFTHEIGHT - 1 - y; 840 | break; 841 | case 3: 842 | t = x; 843 | x = y; 844 | y = TFTHEIGHT - 1 - t; 845 | break; 846 | } 847 | writeRegister16(0x0020, x); 848 | writeRegister16(0x0021, y); 849 | // Inexplicable thing: sometimes pixel read has high/low bytes 850 | // reversed. A second read fixes this. Unsure of reason. Have 851 | // tried adjusting timing in read8() etc. to no avail. 852 | for(uint8_t pass=0; pass<2; pass++) { 853 | CD_COMMAND; write8(0x00); write8(0x22); // Read data from GRAM 854 | CD_DATA; 855 | setReadDir(); // Set up LCD data port(s) for READ operations 856 | read8(hi); // First 2 bytes back are a dummy read 857 | read8(hi); 858 | read8(hi); // Bytes 3, 4 are actual pixel value 859 | read8(lo); 860 | setWriteDir(); // Restore LCD data port(s) to WRITE configuration 861 | } 862 | CS_IDLE; 863 | return ((uint16_t)hi << 8) | lo; 864 | 865 | } else if(driver == ID_7575) { 866 | 867 | uint8_t r, g, b; 868 | writeRegisterPair(HX8347G_COLADDRSTART_HI, HX8347G_COLADDRSTART_LO, x); 869 | writeRegisterPair(HX8347G_ROWADDRSTART_HI, HX8347G_ROWADDRSTART_LO, y); 870 | CD_COMMAND; write8(0x22); // Read data from GRAM 871 | setReadDir(); // Set up LCD data port(s) for READ operations 872 | CD_DATA; 873 | read8(r); // First byte back is a dummy read 874 | read8(r); 875 | read8(g); 876 | read8(b); 877 | setWriteDir(); // Restore LCD data port(s) to WRITE configuration 878 | CS_IDLE; 879 | return (((uint16_t)r & B11111000) << 8) | 880 | (((uint16_t)g & B11111100) << 3) | 881 | ( b >> 3); 882 | } else return 0; 883 | } 884 | 885 | // Ditto with the read/write port directions, as above. 886 | uint16_t Adafruit_TFTLCD::readID(void) { 887 | 888 | uint8_t hi, lo; 889 | 890 | /* 891 | for (uint8_t i=0; i<128; i++) { 892 | Serial.print("$"); Serial.print(i, HEX); 893 | Serial.print(" = 0x"); Serial.println(readReg(i), HEX); 894 | } 895 | */ 896 | 897 | // caryg 898 | // somehow executing this debug code causes 899 | // us to correctly read 0x9341 below. 900 | // some sort of timing issue? 901 | // at least one of the Serial.print s below 902 | // needs to execute then we read 0x9341 903 | //uint16_t foo = readReg(0x04); 904 | //Serial.print("Foo "); 905 | //Serial.println(foo, HEX); 906 | 907 | //delay(1000); 908 | 909 | if (readReg(0x04) == 0x8000) { // eh close enough 910 | // setc! 911 | /* 912 | Serial.println("!"); 913 | for (uint8_t i=0; i<254; i++) { 914 | Serial.print("$"); Serial.print(i, HEX); 915 | Serial.print(" = 0x"); Serial.println(readReg(i), HEX); 916 | } 917 | */ 918 | writeRegister24(HX8357D_SETC, 0xFF8357); 919 | delay(300); 920 | if (readReg(0xD0) == 0x990000) { 921 | return 0x8357; 922 | } 923 | } 924 | 925 | uint16_t id = readReg(0xD3); 926 | if (id == 0x9341) { 927 | return id; 928 | } 929 | 930 | CS_ACTIVE; 931 | CD_COMMAND; 932 | write8(0x00); 933 | WR_STROBE; // Repeat prior byte (0x00) 934 | setReadDir(); // Set up LCD data port(s) for READ operations 935 | CD_DATA; 936 | read8(hi); 937 | read8(lo); 938 | setWriteDir(); // Restore LCD data port(s) to WRITE configuration 939 | CS_IDLE; 940 | 941 | id = hi; id <<= 8; id |= lo; 942 | return id; 943 | } 944 | 945 | uint32_t Adafruit_TFTLCD::readReg(uint8_t r) { 946 | uint32_t id; 947 | uint8_t x; 948 | 949 | // try reading register #4 950 | CS_ACTIVE; 951 | CD_COMMAND; 952 | write8(r); 953 | setReadDir(); // Set up LCD data port(s) for READ operations 954 | CD_DATA; 955 | delayMicroseconds(50); 956 | read8(x); 957 | id = x; // Do not merge or otherwise simplify 958 | id <<= 8; // these lines. It's an unfortunate 959 | read8(x); 960 | id |= x; // shenanigans that are going on. 961 | id <<= 8; // these lines. It's an unfortunate 962 | read8(x); 963 | id |= x; // shenanigans that are going on. 964 | id <<= 8; // these lines. It's an unfortunate 965 | read8(x); 966 | id |= x; // shenanigans that are going on. 967 | CS_IDLE; 968 | setWriteDir(); // Restore LCD data port(s) to WRITE configuration 969 | 970 | //Serial.print("Read $"); Serial.print(r, HEX); 971 | //Serial.print(":\t0x"); Serial.println(id, HEX); 972 | return id; 973 | } 974 | 975 | // Pass 8-bit (each) R,G,B, get back 16-bit packed color 976 | uint16_t Adafruit_TFTLCD::color565(uint8_t r, uint8_t g, uint8_t b) { 977 | return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); 978 | } 979 | 980 | // For I/O macros that were left undefined, declare function 981 | // versions that reference the inline macros just once: 982 | 983 | #ifndef write8 984 | void Adafruit_TFTLCD::write8(uint8_t value) { 985 | write8inline(value); 986 | } 987 | #endif 988 | 989 | #ifdef read8isFunctionalized 990 | uint8_t Adafruit_TFTLCD::read8fn(void) { 991 | uint8_t result; 992 | read8inline(result); 993 | return result; 994 | } 995 | #endif 996 | 997 | #ifndef setWriteDir 998 | void Adafruit_TFTLCD::setWriteDir(void) { 999 | setWriteDirInline(); 1000 | } 1001 | #endif 1002 | 1003 | #ifndef setReadDir 1004 | void Adafruit_TFTLCD::setReadDir(void) { 1005 | setReadDirInline(); 1006 | } 1007 | #endif 1008 | 1009 | #ifndef writeRegister8 1010 | void Adafruit_TFTLCD::writeRegister8(uint8_t a, uint8_t d) { 1011 | writeRegister8inline(a, d); 1012 | } 1013 | #endif 1014 | 1015 | #ifndef writeRegister16 1016 | void Adafruit_TFTLCD::writeRegister16(uint16_t a, uint16_t d) { 1017 | writeRegister16inline(a, d); 1018 | } 1019 | #endif 1020 | 1021 | #ifndef writeRegisterPair 1022 | void Adafruit_TFTLCD::writeRegisterPair(uint8_t aH, uint8_t aL, uint16_t d) { 1023 | writeRegisterPairInline(aH, aL, d); 1024 | } 1025 | #endif 1026 | 1027 | 1028 | void Adafruit_TFTLCD::writeRegister24(uint8_t r, uint32_t d) { 1029 | CS_ACTIVE; 1030 | CD_COMMAND; 1031 | write8(r); 1032 | CD_DATA; 1033 | delayMicroseconds(10); 1034 | write8(d >> 16); 1035 | delayMicroseconds(10); 1036 | write8(d >> 8); 1037 | delayMicroseconds(10); 1038 | write8(d); 1039 | CS_IDLE; 1040 | 1041 | } 1042 | 1043 | 1044 | void Adafruit_TFTLCD::writeRegister32(uint8_t r, uint32_t d) { 1045 | CS_ACTIVE; 1046 | CD_COMMAND; 1047 | write8(r); 1048 | CD_DATA; 1049 | delayMicroseconds(10); 1050 | write8(d >> 24); 1051 | delayMicroseconds(10); 1052 | write8(d >> 16); 1053 | delayMicroseconds(10); 1054 | write8(d >> 8); 1055 | delayMicroseconds(10); 1056 | write8(d); 1057 | CS_IDLE; 1058 | 1059 | } 1060 | --------------------------------------------------------------------------------