├── assets └── image.jpg ├── examples ├── parrot.bmp ├── scroll │ └── scroll.ino ├── textmode │ └── textmode.ino ├── buildtest │ └── buildtest.ino ├── ra8875_bitmap │ └── ra8875_bitmap.ino ├── ra8875_bitmap_fast │ └── ra8875_bitmap_fast.ino └── ts_calibration │ └── ts_calibration.ino ├── library.properties ├── .github ├── workflows │ └── githubci.yml ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE.md ├── README.md ├── license.txt ├── Adafruit_RA8875.h └── Adafruit_RA8875.cpp /assets/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_RA8875/HEAD/assets/image.jpg -------------------------------------------------------------------------------- /examples/parrot.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/Adafruit_RA8875/HEAD/examples/parrot.bmp -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Adafruit RA8875 2 | version=1.4.4 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=Adafruit's Arduino driver for the RA8875 TFT driver 6 | paragraph=Adafruit's Arduino driver for the RA8875 TFT driver 7 | category=Display 8 | url=https://github.com/adafruit/Adafruit_RA8875 9 | architectures=* 10 | depends=Adafruit GFX Library, Adafruit STMPE610, SD 11 | -------------------------------------------------------------------------------- /.github/workflows/githubci.yml: -------------------------------------------------------------------------------- 1 | name: Arduino Library CI 2 | 3 | on: [pull_request, push, repository_dispatch] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/setup-python@v4 11 | with: 12 | python-version: '3.x' 13 | - uses: actions/checkout@v3 14 | - uses: actions/checkout@v3 15 | with: 16 | repository: adafruit/ci-arduino 17 | path: ci 18 | 19 | - name: Install the prerequisites 20 | run: bash ci/actions_install.sh 21 | 22 | - name: Check for correct code formatting with clang-format 23 | run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . 24 | 25 | - name: Check for correct documentation with doxygen 26 | env: 27 | GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }} 28 | PRETTYNAME : "Adafruit RA8875 Arduino Library" 29 | run: bash ci/doxy_gen_and_deploy.sh 30 | 31 | - name: Test the code on supported platforms 32 | run: python3 ci/build_platform.py main_platforms 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adafruit RA8875 [![Build Status](https://github.com/adafruit/Adafruit_RA8875/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_RA8875/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_RA8875/html/index.html) 2 | 3 | This is a library for our driver board 40-pin TFT Touch Displays - 800x480 Max 4 | 5 | 6 | 7 | Pick one up today in the adafruit shop! 8 | * https://www.adafruit.com/products/1590 9 | 10 | The RA8875 is a TFT driver for up to 800x480 dotclock'd displays 11 | It is tested to work with displays in the Adafruit shop. 12 | Other displays may need timing adjustments and are not guanteed to work. 13 | 14 | Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! 15 | 16 | Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, check license.txt for more information. 17 | 18 | All text above must be included in any redistribution 19 | -------------------------------------------------------------------------------- /examples/scroll/scroll.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Adafruit_GFX.h" 4 | #include "Adafruit_RA8875.h" 5 | 6 | // LCD 7 | // Library only supports hardware SPI at this time 8 | // Connect SCLK to UNO Digital #13 (Hardware SPI clock) 9 | // Connect MISO to UNO Digital #12 (Hardware SPI MISO) 10 | // Connect MOSI to UNO Digital #11 (Hardware SPI MOSI) 11 | #define RA8875_INT 3 12 | #define RA8875_CS 10 13 | #define RA8875_RESET 9 14 | 15 | #define NUMINPUTS 4 16 | 17 | Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET); 18 | 19 | void setup() { 20 | Serial.begin(9600); 21 | 22 | /* Initialize the display using 'RA8875_480x80', 'RA8875_480x128', 'RA8875_480x272' or 'RA8875_800x480' */ 23 | if (!tft.begin(RA8875_800x480)) { 24 | Serial.println("LCD not found!"); 25 | while (1); 26 | } 27 | 28 | tft.displayOn(true); 29 | tft.GPIOX(true); // Enable TFT - display enable tied to GPIOX 30 | tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight 31 | tft.PWM1out(255); 32 | 33 | tft.fillScreen(RA8875_BLACK); 34 | tft.setScrollWindow(0, 0, 800, 480, RA8875_SCROLL_BOTH); 35 | tft.fillCircle(690, 370, 100, RA8875_WHITE); 36 | } 37 | 38 | 39 | void loop() { 40 | static int Scroll=0; 41 | static int Dir=1; 42 | 43 | tft.scrollX(Scroll); 44 | tft.scrollY(Scroll); 45 | 46 | Scroll+=Dir; 47 | if(Scroll >= 250) { 48 | Dir=-1;; 49 | } else if(Scroll <= 0) { 50 | Dir=1; 51 | } 52 | 53 | delay(10); 54 | } 55 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for creating a pull request to contribute to Adafruit's GitHub code! 2 | Before you open the request please review the following guidelines and tips to 3 | help it be more easily integrated: 4 | 5 | - **Describe the scope of your change--i.e. what the change does and what parts 6 | of the code were modified.** This will help us understand any risks of integrating 7 | the code. 8 | 9 | - **Describe any known limitations with your change.** For example if the change 10 | doesn't apply to a supported platform of the library please mention it. 11 | 12 | - **Please run any tests or examples that can exercise your modified code.** We 13 | strive to not break users of the code and running tests/examples helps with this 14 | process. 15 | 16 | Thank you again for contributing! We will try to test and integrate the change 17 | as soon as we can, but be aware we have many GitHub repositories to manage and 18 | can't immediately respond to every request. There is no need to bump or check in 19 | on a pull request (it will clutter the discussion of the request). 20 | 21 | Also don't be worried if the request is closed or not integrated--sometimes the 22 | priorities of Adafruit's GitHub code (education, ease of use) might not match the 23 | priorities of the pull request. Don't fret, the open source community thrives on 24 | forks and GitHub makes it easy to keep your changes in a forked repo. 25 | 26 | After reviewing the guidelines above you can delete this text from the pull request. 27 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Software License Agreement (BSD License) 2 | 3 | Copyright (c) 2020, Limor Fried for Adafruit Industries 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the copyright holders nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY 18 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY 21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening an issue on an Adafruit Arduino library repository. To 2 | improve the speed of resolution please review the following guidelines and 3 | common troubleshooting steps below before creating the issue: 4 | 5 | - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use 6 | the forums at http://forums.adafruit.com to ask questions and troubleshoot why 7 | something isn't working as expected. In many cases the problem is a common issue 8 | that you will more quickly receive help from the forum community. GitHub issues 9 | are meant for known defects in the code. If you don't know if there is a defect 10 | in the code then start with troubleshooting on the forum first. 11 | 12 | - **If following a tutorial or guide be sure you didn't miss a step.** Carefully 13 | check all of the steps and commands to run have been followed. Consult the 14 | forum if you're unsure or have questions about steps in a guide/tutorial. 15 | 16 | - **For Arduino projects check these very common issues to ensure they don't apply**: 17 | 18 | - For uploading sketches or communicating with the board make sure you're using 19 | a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes 20 | very hard to tell the difference between a data and charge cable! Try using the 21 | cable with other devices or swapping to another cable to confirm it is not 22 | the problem. 23 | 24 | - **Be sure you are supplying adequate power to the board.** Check the specs of 25 | your board and plug in an external power supply. In many cases just 26 | plugging a board into your computer is not enough to power it and other 27 | peripherals. 28 | 29 | - **Double check all soldering joints and connections.** Flakey connections 30 | cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. 31 | 32 | - **Ensure you are using an official Arduino or Adafruit board.** We can't 33 | guarantee a clone board will have the same functionality and work as expected 34 | with this code and don't support them. 35 | 36 | If you're sure this issue is a defect in the code and checked the steps above 37 | please fill in the following fields to provide enough troubleshooting information. 38 | You may delete the guideline and text above to just leave the following details: 39 | 40 | - Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** 41 | 42 | - Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO 43 | VERSION HERE** 44 | 45 | - List the steps to reproduce the problem below (if possible attach a sketch or 46 | copy the sketch code in too): **LIST REPRO STEPS BELOW** 47 | -------------------------------------------------------------------------------- /examples/textmode/textmode.ino: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | This is an example for the Adafruit RA8875 Driver board for TFT displays 3 | ---------------> http://www.adafruit.com/products/1590 4 | The RA8875 is a TFT driver for up to 800x480 dotclock'd displays 5 | It is tested to work with displays in the Adafruit shop. Other displays 6 | may need timing adjustments and are not guanteed to work. 7 | 8 | Adafruit invests time and resources providing this open 9 | source code, please support Adafruit and open-source hardware 10 | by purchasing products from Adafruit! 11 | 12 | Written by Limor Fried/Ladyada for Adafruit Industries. 13 | BSD license, check license.txt for more information. 14 | All text above must be included in any redistribution. 15 | ******************************************************************/ 16 | 17 | 18 | #include 19 | #include "Adafruit_GFX.h" 20 | #include "Adafruit_RA8875.h" 21 | 22 | // Library only supports hardware SPI at this time 23 | // Connect SCLK to UNO Digital #13 (Hardware SPI clock) 24 | // Connect MISO to UNO Digital #12 (Hardware SPI MISO) 25 | // Connect MOSI to UNO Digital #11 (Hardware SPI MOSI) 26 | #define RA8875_INT 3 27 | #define RA8875_CS 10 28 | #define RA8875_RESET 9 29 | 30 | Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET); 31 | uint16_t tx, ty; 32 | 33 | void setup() 34 | { 35 | Serial.begin(9600); 36 | Serial.println("RA8875 start"); 37 | 38 | /* Initialize the display using 'RA8875_480x80', 'RA8875_480x128', 'RA8875_480x272' or 'RA8875_800x480' */ 39 | if (!tft.begin(RA8875_480x272)) { 40 | Serial.println("RA8875 Not Found!"); 41 | while (1); 42 | } 43 | 44 | tft.displayOn(true); 45 | tft.GPIOX(true); // Enable TFT - display enable tied to GPIOX 46 | tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight 47 | tft.PWM1out(255); 48 | tft.fillScreen(RA8875_BLACK); 49 | 50 | /* Switch to text mode */ 51 | tft.textMode(); 52 | tft.cursorBlink(32); 53 | 54 | 55 | /* Set a solid for + bg color ... */ 56 | 57 | /* ... or a fore color plus a transparent background */ 58 | 59 | 60 | /* Set the cursor location (in pixels) */ 61 | tft.textSetCursor(10, 10); 62 | 63 | /* Render some text! */ 64 | char string[15] = "Hello, World! "; 65 | tft.textTransparent(RA8875_WHITE); 66 | tft.textWrite(string); 67 | tft.textColor(RA8875_WHITE, RA8875_RED); 68 | tft.textWrite(string); 69 | tft.textTransparent(RA8875_CYAN); 70 | tft.textWrite(string); 71 | tft.textTransparent(RA8875_GREEN); 72 | tft.textWrite(string); 73 | tft.textColor(RA8875_YELLOW, RA8875_CYAN); 74 | tft.textWrite(string); 75 | tft.textColor(RA8875_BLACK, RA8875_MAGENTA); 76 | tft.textWrite(string); 77 | 78 | /* Change the cursor location and color ... */ 79 | tft.textSetCursor(100, 100); 80 | tft.textTransparent(RA8875_RED); 81 | /* If necessary, enlarge the font */ 82 | tft.textEnlarge(1); 83 | /* ... and render some more text! */ 84 | tft.textWrite(string); 85 | tft.textSetCursor(100, 150); 86 | tft.textEnlarge(2); 87 | tft.textWrite(string); 88 | } 89 | 90 | void loop() 91 | { 92 | } 93 | -------------------------------------------------------------------------------- /examples/buildtest/buildtest.ino: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | This is an example for the Adafruit RA8875 Driver board for TFT displays 3 | ---------------> http://www.adafruit.com/products/1590 4 | The RA8875 is a TFT driver for up to 800x480 dotclock'd displays 5 | It is tested to work with displays in the Adafruit shop. Other displays 6 | may need timing adjustments and are not guanteed to work. 7 | 8 | Adafruit invests time and resources providing this open 9 | source code, please support Adafruit and open-source hardware 10 | by purchasing products from Adafruit! 11 | 12 | Written by Limor Fried/Ladyada for Adafruit Industries. 13 | BSD license, check license.txt for more information. 14 | All text above must be included in any redistribution. 15 | ******************************************************************/ 16 | 17 | #include 18 | #include "Adafruit_GFX.h" 19 | #include "Adafruit_RA8875.h" 20 | 21 | 22 | // Library only supports hardware SPI at this time 23 | // Connect SCLK to UNO Digital #13 (Hardware SPI clock) 24 | // Connect MISO to UNO Digital #12 (Hardware SPI MISO) 25 | // Connect MOSI to UNO Digital #11 (Hardware SPI MOSI) 26 | #define RA8875_INT 3 27 | #define RA8875_CS 10 28 | #define RA8875_RESET 9 29 | 30 | Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET); 31 | uint16_t tx, ty; 32 | 33 | void setup() 34 | { 35 | Serial.begin(9600); 36 | Serial.println("RA8875 start"); 37 | 38 | /* Initialize the display using 'RA8875_480x80', 'RA8875_480x128', 'RA8875_480x272' or 'RA8875_800x480' */ 39 | if (!tft.begin(RA8875_480x272)) { 40 | Serial.println("RA8875 Not Found!"); 41 | while (1); 42 | } 43 | 44 | Serial.println("Found RA8875"); 45 | 46 | tft.displayOn(true); 47 | tft.GPIOX(true); // Enable TFT - display enable tied to GPIOX 48 | tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight 49 | tft.PWM1out(255); 50 | 51 | // With hardware accelleration this is instant 52 | tft.fillScreen(RA8875_WHITE); 53 | 54 | // Play with PWM 55 | for (uint8_t i=255; i!=0; i-=5 ) 56 | { 57 | tft.PWM1out(i); 58 | delay(10); 59 | } 60 | for (uint8_t i=0; i!=255; i+=5 ) 61 | { 62 | tft.PWM1out(i); 63 | delay(10); 64 | } 65 | tft.PWM1out(255); 66 | 67 | tft.fillScreen(RA8875_RED); 68 | delay(500); 69 | tft.fillScreen(RA8875_YELLOW); 70 | delay(500); 71 | tft.fillScreen(RA8875_GREEN); 72 | delay(500); 73 | tft.fillScreen(RA8875_CYAN); 74 | delay(500); 75 | tft.fillScreen(RA8875_MAGENTA); 76 | delay(500); 77 | tft.fillScreen(RA8875_BLACK); 78 | 79 | // Try some GFX acceleration! 80 | tft.drawCircle(100, 100, 50, RA8875_BLACK); 81 | tft.fillCircle(100, 100, 49, RA8875_GREEN); 82 | 83 | tft.fillRect(11, 11, 398, 198, RA8875_BLUE); 84 | tft.drawRect(10, 10, 400, 200, RA8875_GREEN); 85 | tft.fillRoundRect(200, 10, 200, 100, 10, RA8875_RED); 86 | tft.drawPixel(10,10,RA8875_BLACK); 87 | tft.drawPixel(11,11,RA8875_BLACK); 88 | tft.drawLine(10, 10, 200, 100, RA8875_RED); 89 | tft.drawTriangle(200, 15, 250, 100, 150, 125, RA8875_BLACK); 90 | tft.fillTriangle(200, 16, 249, 99, 151, 124, RA8875_YELLOW); 91 | tft.drawEllipse(300, 100, 100, 40, RA8875_BLACK); 92 | tft.fillEllipse(300, 100, 98, 38, RA8875_GREEN); 93 | // Argument 5 (curvePart) is a 2-bit value to control each corner (select 0, 1, 2, or 3) 94 | tft.drawCurve(50, 100, 80, 40, 2, RA8875_BLACK); 95 | tft.fillCurve(50, 100, 78, 38, 2, RA8875_WHITE); 96 | 97 | pinMode(RA8875_INT, INPUT); 98 | digitalWrite(RA8875_INT, HIGH); 99 | 100 | tft.touchEnable(true); 101 | 102 | Serial.print("Status: "); Serial.println(tft.readStatus(), HEX); 103 | Serial.println("Waiting for touch events ..."); 104 | } 105 | 106 | void loop() 107 | { 108 | float xScale = 1024.0F/tft.width(); 109 | float yScale = 1024.0F/tft.height(); 110 | 111 | /* Wait around for touch events */ 112 | if (! digitalRead(RA8875_INT)) 113 | { 114 | if (tft.touched()) 115 | { 116 | Serial.print("Touch: "); 117 | tft.touchRead(&tx, &ty); 118 | Serial.print(tx); Serial.print(", "); Serial.println(ty); 119 | /* Draw a circle */ 120 | tft.fillCircle((uint16_t)(tx/xScale), (uint16_t)(ty/yScale), 4, RA8875_WHITE); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /examples/ra8875_bitmap/ra8875_bitmap.ino: -------------------------------------------------------------------------------- 1 | #include // Core graphics library 2 | #include 3 | #include 4 | #include 5 | #include "Adafruit_RA8875.h" 6 | #include 7 | #define sd_cs 6 // uding ethernet shield sd 8 | 9 | // Library only supports hardware SPI at this time 10 | // Connect SCLK to UNO Digital #13 (Hardware SPI clock) 11 | // Connect MISO to UNO Digital #12 (Hardware SPI MISO) 12 | // Connect MOSI to UNO Digital #11 (Hardware SPI MOSI) 13 | #define RA8875_INT 3 14 | #define RA8875_CS 10 15 | #define RA8875_RESET 9 16 | 17 | Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET); 18 | 19 | void setup () { 20 | Serial.begin(9600); 21 | 22 | if (!SD.begin(sd_cs)) 23 | { 24 | Serial.println("initialization failed!"); 25 | return; 26 | } 27 | 28 | Serial.println("initialization done."); 29 | 30 | Serial.println("RA8875 start"); 31 | 32 | /* Initialize the display using 'RA8875_480x80', 'RA8875_480x128', 'RA8875_480x272' or 'RA8875_800x480' */ 33 | if (!tft.begin(RA8875_800x480)) { 34 | Serial.println("RA8875 Not Found!"); 35 | while (1); 36 | } 37 | 38 | Serial.println("Found RA8875"); 39 | 40 | tft.displayOn(true); 41 | tft.GPIOX(true); // Enable TFT - display enable tied to GPIOX 42 | tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight 43 | tft.PWM1out(255); 44 | 45 | Serial.print("("); 46 | Serial.print(tft.width()); 47 | Serial.print(", "); 48 | Serial.print(tft.height()); 49 | Serial.println(")"); 50 | tft.graphicsMode(); // go back to graphics mode 51 | tft.fillScreen(RA8875_BLACK); 52 | tft.graphicsMode(); 53 | bmpDraw("parrot.bmp", 0, 0); 54 | } 55 | 56 | void loop() 57 | { 58 | } 59 | 60 | // This function opens a Windows Bitmap (BMP) file and 61 | // displays it at the given coordinates. It's sped up 62 | // by reading many pixels worth of data at a time 63 | // (rather than pixel by pixel). Increasing the buffer 64 | // size takes more of the Arduino's precious RAM but 65 | // makes loading a little faster. 20 pixels seems a 66 | // good balance. 67 | 68 | #define BUFFPIXEL 20 69 | 70 | void bmpDraw(const char *filename, int x, int y) { 71 | File bmpFile; 72 | int bmpWidth, bmpHeight; // W+H in pixels 73 | uint8_t bmpDepth; // Bit depth (currently must be 24) 74 | uint32_t bmpImageoffset; // Start of image data in file 75 | uint32_t rowSize; // Not always = bmpWidth; may have padding 76 | uint8_t sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel) 77 | uint16_t lcdbuffer[BUFFPIXEL]; // pixel out buffer (16-bit per pixel) 78 | uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer 79 | boolean goodBmp = false; // Set to true on valid header parse 80 | boolean flip = true; // BMP is stored bottom-to-top 81 | int w, h, row, col; 82 | uint8_t r, g, b; 83 | uint32_t pos = 0, startTime = millis(); 84 | uint8_t lcdidx = 0; 85 | 86 | if((x >= tft.width()) || (y >= tft.height())) return; 87 | 88 | Serial.println(); 89 | Serial.print(F("Loading image '")); 90 | Serial.print(filename); 91 | Serial.println('\''); 92 | 93 | // Open requested file on SD card 94 | if ((bmpFile = SD.open(filename)) == false) { 95 | Serial.println(F("File not found")); 96 | return; 97 | } 98 | 99 | // Parse BMP header 100 | if(read16(bmpFile) == 0x4D42) { // BMP signature 101 | Serial.println(F("File size: ")); 102 | Serial.println(read32(bmpFile)); 103 | (void)read32(bmpFile); // Read & ignore creator bytes 104 | bmpImageoffset = read32(bmpFile); // Start of image data 105 | Serial.print(F("Image Offset: ")); 106 | Serial.println(bmpImageoffset, DEC); 107 | 108 | // Read DIB header 109 | Serial.print(F("Header size: ")); 110 | Serial.println(read32(bmpFile)); 111 | bmpWidth = read32(bmpFile); 112 | bmpHeight = read32(bmpFile); 113 | 114 | if(read16(bmpFile) == 1) { // # planes -- must be '1' 115 | bmpDepth = read16(bmpFile); // bits per pixel 116 | Serial.print(F("Bit Depth: ")); 117 | Serial.println(bmpDepth); 118 | if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed 119 | goodBmp = true; // Supported BMP format -- proceed! 120 | Serial.print(F("Image size: ")); 121 | Serial.print(bmpWidth); 122 | Serial.print('x'); 123 | Serial.println(bmpHeight); 124 | 125 | // BMP rows are padded (if needed) to 4-byte boundary 126 | rowSize = (bmpWidth * 3 + 3) & ~3; 127 | 128 | // If bmpHeight is negative, image is in top-down order. 129 | // This is not canon but has been observed in the wild. 130 | if(bmpHeight < 0) { 131 | bmpHeight = -bmpHeight; 132 | flip = false; 133 | } 134 | 135 | // Crop area to be loaded 136 | w = bmpWidth; 137 | h = bmpHeight; 138 | if((x+w-1) >= tft.width()) w = tft.width() - x; 139 | if((y+h-1) >= tft.height()) h = tft.height() - y; 140 | 141 | // Set TFT address window to clipped image bounds 142 | 143 | for (row=0; row= sizeof(sdbuffer)) { // Indeed 162 | // Push LCD buffer to the display first 163 | if(lcdidx > 0) { 164 | tft.drawPixel(col+x, row+y, lcdbuffer[lcdidx]); 165 | lcdidx = 0; 166 | } 167 | 168 | bmpFile.read(sdbuffer, sizeof(sdbuffer)); 169 | buffidx = 0; // Set index to beginning 170 | } 171 | 172 | // Convert pixel from BMP to TFT format 173 | b = sdbuffer[buffidx++]; 174 | g = sdbuffer[buffidx++]; 175 | r = sdbuffer[buffidx++]; 176 | lcdbuffer[lcdidx] = color565(r,g,b); 177 | tft.drawPixel(col+x, row+y, lcdbuffer[lcdidx]); 178 | } // end pixel 179 | 180 | } // end scanline 181 | 182 | // Write any remaining data to LCD 183 | if(lcdidx > 0) { 184 | tft.drawPixel(col+x, row+y, lcdbuffer[lcdidx]); 185 | } 186 | 187 | Serial.print(F("Loaded in ")); 188 | Serial.print(millis() - startTime); 189 | Serial.println(" ms"); 190 | 191 | } // end goodBmp 192 | } 193 | } 194 | 195 | bmpFile.close(); 196 | if(!goodBmp) Serial.println(F("BMP format not recognized.")); 197 | 198 | } 199 | 200 | // These read 16- and 32-bit types from the SD card file. 201 | // BMP data is stored little-endian, Arduino is little-endian too. 202 | // May need to reverse subscript order if porting elsewhere. 203 | 204 | uint16_t read16(File f) { 205 | uint16_t result; 206 | ((uint8_t *)&result)[0] = f.read(); // LSB 207 | ((uint8_t *)&result)[1] = f.read(); // MSB 208 | return result; 209 | } 210 | 211 | uint32_t read32(File f) { 212 | uint32_t result; 213 | ((uint8_t *)&result)[0] = f.read(); // LSB 214 | ((uint8_t *)&result)[1] = f.read(); 215 | ((uint8_t *)&result)[2] = f.read(); 216 | ((uint8_t *)&result)[3] = f.read(); // MSB 217 | return result; 218 | } 219 | 220 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { 221 | return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); 222 | } 223 | 224 | byte decToBcd(byte val){ 225 | // Convert normal decimal numbers to binary coded decimal 226 | return ( (val/10*16) + (val%10) ); 227 | } 228 | -------------------------------------------------------------------------------- /examples/ra8875_bitmap_fast/ra8875_bitmap_fast.ino: -------------------------------------------------------------------------------- 1 | #include // Core graphics library 2 | #include 3 | #include 4 | #include 5 | #include "Adafruit_RA8875.h" 6 | #include 7 | #define sd_cs 6 // using ethernet shield sd 8 | 9 | // Library only supports hardware SPI at this time 10 | // Connect SCLK to UNO Digital #13 (Hardware SPI clock) 11 | // Connect MISO to UNO Digital #12 (Hardware SPI MISO) 12 | // Connect MOSI to UNO Digital #11 (Hardware SPI MOSI) 13 | #define RA8875_INT 3 14 | #define RA8875_CS 10 15 | #define RA8875_RESET 9 16 | 17 | Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET); 18 | 19 | void setup () { 20 | Serial.begin(9600); 21 | 22 | if (!SD.begin(sd_cs)) 23 | { 24 | Serial.println("initialization failed!"); 25 | return; 26 | } 27 | 28 | Serial.println("initialization done."); 29 | 30 | Serial.println("RA8875 start"); 31 | 32 | /* Initialize the display using 'RA8875_480x80', 'RA8875_480x128', 'RA8875_480x272' or 'RA8875_800x480' */ 33 | if (!tft.begin(RA8875_800x480)) { 34 | Serial.println("RA8875 Not Found!"); 35 | while (1); 36 | } 37 | 38 | Serial.println("Found RA8875"); 39 | 40 | tft.displayOn(true); 41 | tft.GPIOX(true); // Enable TFT - display enable tied to GPIOX 42 | tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight 43 | tft.PWM1out(255); 44 | 45 | Serial.print("("); 46 | Serial.print(tft.width()); 47 | Serial.print(", "); 48 | Serial.print(tft.height()); 49 | Serial.println(")"); 50 | tft.graphicsMode(); // go back to graphics mode 51 | tft.fillScreen(RA8875_BLACK); 52 | tft.graphicsMode(); 53 | bmpDraw("parrot.bmp", 0, 0); 54 | } 55 | 56 | void loop() 57 | { 58 | } 59 | 60 | // This function opens a Windows Bitmap (BMP) file and 61 | // displays it at the given coordinates. It's sped up 62 | // by reading many pixels worth of data at a time 63 | // (rather than pixel by pixel). Increasing the buffer 64 | // size takes more of the Arduino's precious RAM but 65 | // makes loading a little faster. 20 pixels seems a 66 | // good balance. 67 | 68 | #define BUFFPIXEL 20 69 | 70 | void bmpDraw(const char *filename, int x, int y) { 71 | File bmpFile; 72 | int bmpWidth, bmpHeight; // W+H in pixels 73 | uint8_t bmpDepth; // Bit depth (currently must be 24) 74 | uint32_t bmpImageoffset; // Start of image data in file 75 | uint32_t rowSize; // Not always = bmpWidth; may have padding 76 | uint8_t sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel) 77 | uint16_t lcdbuffer[BUFFPIXEL]; // pixel out buffer (16-bit per pixel) 78 | uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer 79 | boolean goodBmp = false; // Set to true on valid header parse 80 | boolean flip = true; // BMP is stored bottom-to-top 81 | int w, h, row, col, xpos, ypos; 82 | uint8_t r, g, b; 83 | uint32_t pos = 0, startTime = millis(); 84 | uint8_t lcdidx = 0; 85 | 86 | if((x >= tft.width()) || (y >= tft.height())) return; 87 | 88 | Serial.println(); 89 | Serial.print(F("Loading image '")); 90 | Serial.print(filename); 91 | Serial.println('\''); 92 | 93 | // Open requested file on SD card 94 | if ((bmpFile = SD.open(filename)) == false) { 95 | Serial.println(F("File not found")); 96 | return; 97 | } 98 | 99 | // Parse BMP header 100 | if(read16(bmpFile) == 0x4D42) { // BMP signature 101 | Serial.println(F("File size: ")); 102 | Serial.println(read32(bmpFile)); 103 | (void)read32(bmpFile); // Read & ignore creator bytes 104 | bmpImageoffset = read32(bmpFile); // Start of image data 105 | Serial.print(F("Image Offset: ")); 106 | Serial.println(bmpImageoffset, DEC); 107 | 108 | // Read DIB header 109 | Serial.print(F("Header size: ")); 110 | Serial.println(read32(bmpFile)); 111 | bmpWidth = read32(bmpFile); 112 | bmpHeight = read32(bmpFile); 113 | 114 | if(read16(bmpFile) == 1) { // # planes -- must be '1' 115 | bmpDepth = read16(bmpFile); // bits per pixel 116 | Serial.print(F("Bit Depth: ")); 117 | Serial.println(bmpDepth); 118 | if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed 119 | goodBmp = true; // Supported BMP format -- proceed! 120 | Serial.print(F("Image size: ")); 121 | Serial.print(bmpWidth); 122 | Serial.print('x'); 123 | Serial.println(bmpHeight); 124 | 125 | // BMP rows are padded (if needed) to 4-byte boundary 126 | rowSize = (bmpWidth * 3 + 3) & ~3; 127 | 128 | // If bmpHeight is negative, image is in top-down order. 129 | // This is not canon but has been observed in the wild. 130 | if(bmpHeight < 0) { 131 | bmpHeight = -bmpHeight; 132 | flip = false; 133 | } 134 | 135 | // Crop area to be loaded 136 | w = bmpWidth; 137 | h = bmpHeight; 138 | if((x+w-1) >= tft.width()) w = tft.width() - x; 139 | if((y+h-1) >= tft.height()) h = tft.height() - y; 140 | 141 | // Set TFT address window to clipped image bounds 142 | ypos = y; 143 | for (row=0; row= sizeof(sdbuffer)) { // Indeed 163 | // Push LCD buffer to the display first 164 | if(lcdidx > 0) { 165 | tft.drawPixels(lcdbuffer, lcdidx, xpos, ypos); 166 | xpos += lcdidx; 167 | lcdidx = 0; 168 | } 169 | 170 | bmpFile.read(sdbuffer, sizeof(sdbuffer)); 171 | buffidx = 0; // Set index to beginning 172 | } 173 | 174 | // Convert pixel from BMP to TFT format 175 | b = sdbuffer[buffidx++]; 176 | g = sdbuffer[buffidx++]; 177 | r = sdbuffer[buffidx++]; 178 | lcdbuffer[lcdidx++] = color565(r,g,b); 179 | if (lcdidx >= sizeof(lcdbuffer) || (xpos - x + lcdidx) >= w) { 180 | tft.drawPixels(lcdbuffer, lcdidx, xpos, ypos); 181 | lcdidx = 0; 182 | xpos += lcdidx; 183 | } 184 | } // end pixel 185 | ypos++; 186 | } // end scanline 187 | 188 | // Write any remaining data to LCD 189 | if(lcdidx > 0) { 190 | tft.drawPixels(lcdbuffer, lcdidx, xpos, ypos); 191 | xpos += lcdidx; 192 | } 193 | 194 | Serial.print(F("Loaded in ")); 195 | Serial.print(millis() - startTime); 196 | Serial.println(" ms"); 197 | 198 | } // end goodBmp 199 | } 200 | } 201 | 202 | bmpFile.close(); 203 | if(!goodBmp) Serial.println(F("BMP format not recognized.")); 204 | 205 | } 206 | 207 | // These read 16- and 32-bit types from the SD card file. 208 | // BMP data is stored little-endian, Arduino is little-endian too. 209 | // May need to reverse subscript order if porting elsewhere. 210 | 211 | uint16_t read16(File f) { 212 | uint16_t result; 213 | ((uint8_t *)&result)[0] = f.read(); // LSB 214 | ((uint8_t *)&result)[1] = f.read(); // MSB 215 | return result; 216 | } 217 | 218 | uint32_t read32(File f) { 219 | uint32_t result; 220 | ((uint8_t *)&result)[0] = f.read(); // LSB 221 | ((uint8_t *)&result)[1] = f.read(); 222 | ((uint8_t *)&result)[2] = f.read(); 223 | ((uint8_t *)&result)[3] = f.read(); // MSB 224 | return result; 225 | } 226 | 227 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { 228 | return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); 229 | } 230 | 231 | byte decToBcd(byte val){ 232 | // Convert normal decimal numbers to binary coded decimal 233 | return ( (val/10*16) + (val%10) ); 234 | } 235 | -------------------------------------------------------------------------------- /examples/ts_calibration/ts_calibration.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Adafruit_GFX.h" 3 | #include "Adafruit_RA8875.h" 4 | #if defined(EEPROM_SUPPORTED) 5 | #include 6 | #endif 7 | 8 | #define RA8875_INT 3 9 | #define RA8875_CS 10 10 | #define RA8875_RESET 9 11 | 12 | Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET); 13 | tsPoint_t _tsLCDPoints[3]; 14 | tsPoint_t _tsTSPoints[3]; 15 | tsMatrix_t _tsMatrix; 16 | 17 | #define EEPROMLOCATION 100 18 | 19 | // Use to force a recalibration 20 | #define FORCE_CALIBRATION false 21 | 22 | /**************************************************************************/ 23 | /*! 24 | @brief Calculates the difference between the touch screen and the 25 | actual screen co-ordinates, taking into account misalignment 26 | and any physical offset of the touch screen. 27 | 28 | @note This is based on the public domain touch screen calibration code 29 | written by Carlos E. Vidales (copyright (c) 2001). 30 | 31 | For more information, see the following app notes: 32 | 33 | - AN2173 - Touch Screen Control and Calibration 34 | Svyatoslav Paliy, Cypress Microsystems 35 | - Calibration in touch-screen systems 36 | Wendy Fang and Tony Chang, 37 | Analog Applications Journal, 3Q 2007 (Texas Instruments) 38 | */ 39 | /**************************************************************************/ 40 | int setCalibrationMatrix( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * matrixPtr) 41 | { 42 | int retValue = 0; 43 | 44 | matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - 45 | ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; 46 | 47 | if( matrixPtr->Divider == 0 ) 48 | { 49 | retValue = -1 ; 50 | } 51 | else 52 | { 53 | matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - 54 | ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; 55 | 56 | matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) - 57 | ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ; 58 | 59 | matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y + 60 | (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y + 61 | (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ; 62 | 63 | matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) - 64 | ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ; 65 | 66 | matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) - 67 | ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ; 68 | 69 | matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y + 70 | (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y + 71 | (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ; 72 | 73 | #if defined(EEPROM_SUPPORTED) 74 | // Write the calibration matrix to the EEPROM 75 | tft.writeCalibration(EEPROMLOCATION, matrixPtr); 76 | #endif 77 | 78 | } 79 | 80 | return( retValue ) ; 81 | } 82 | 83 | /**************************************************************************/ 84 | /*! 85 | @brief Converts raw touch screen locations (screenPtr) into actual 86 | pixel locations on the display (displayPtr) using the 87 | supplied matrix. 88 | 89 | @param[out] displayPtr Pointer to the tsPoint_t object that will hold 90 | the compensated pixel location on the display 91 | @param[in] screenPtr Pointer to the tsPoint_t object that contains the 92 | raw touch screen co-ordinates (before the 93 | calibration calculations are made) 94 | @param[in] matrixPtr Pointer to the calibration matrix coefficients 95 | used during the calibration process (calculated 96 | via the tsCalibrate() helper function) 97 | 98 | @note This is based on the public domain touch screen calibration code 99 | written by Carlos E. Vidales (copyright (c) 2001). 100 | */ 101 | /**************************************************************************/ 102 | int calibrateTSPoint( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * matrixPtr ) 103 | { 104 | int retValue = 0 ; 105 | 106 | if( matrixPtr->Divider != 0 ) 107 | { 108 | displayPtr->x = ( (matrixPtr->An * screenPtr->x) + 109 | (matrixPtr->Bn * screenPtr->y) + 110 | matrixPtr->Cn 111 | ) / matrixPtr->Divider ; 112 | 113 | displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) + 114 | (matrixPtr->En * screenPtr->y) + 115 | matrixPtr->Fn 116 | ) / matrixPtr->Divider ; 117 | } 118 | else 119 | { 120 | return -1; 121 | } 122 | 123 | return( retValue ); 124 | } 125 | 126 | /**************************************************************************/ 127 | /*! 128 | @brief Waits for a touch event 129 | */ 130 | /**************************************************************************/ 131 | void waitForTouchEvent(tsPoint_t * point) 132 | { 133 | /* Clear the touch data object and placeholder variables */ 134 | memset(point, 0, sizeof(tsPoint_t)); 135 | 136 | /* Clear any previous interrupts to avoid false buffered reads */ 137 | uint16_t x, y; 138 | tft.touchRead(&x, &y); 139 | delay(1); 140 | 141 | /* Wait around for a new touch event (INT pin goes low) */ 142 | while (digitalRead(RA8875_INT)) 143 | { 144 | } 145 | 146 | /* Make sure this is really a touch event */ 147 | if (tft.touched()) 148 | { 149 | tft.touchRead(&x, &y); 150 | point->x = x; 151 | point->y = y; 152 | Serial.print("Touch: "); 153 | Serial.print(point->x); Serial.print(", "); Serial.println(point->y); 154 | } 155 | else 156 | { 157 | point->x = 0; 158 | point->y = 0; 159 | } 160 | } 161 | 162 | /**************************************************************************/ 163 | /*! 164 | @brief Renders the calibration screen with an appropriately 165 | placed test point and waits for a touch event 166 | */ 167 | /**************************************************************************/ 168 | tsPoint_t renderCalibrationScreen(uint16_t x, uint16_t y, uint16_t radius) 169 | { 170 | tft.fillScreen(RA8875_WHITE); 171 | tft.drawCircle(x, y, radius, RA8875_RED); 172 | tft.drawCircle(x, y, radius + 2, 0x8410); /* 50% Gray */ 173 | 174 | // Wait for a valid touch events 175 | tsPoint_t point = { 0, 0 }; 176 | 177 | /* Keep polling until the TS event flag is valid */ 178 | bool valid = false; 179 | while (!valid) 180 | { 181 | waitForTouchEvent(&point); 182 | if (point.x || point.y) 183 | { 184 | valid = true; 185 | } 186 | } 187 | 188 | return point; 189 | } 190 | 191 | /**************************************************************************/ 192 | /*! 193 | @brief Starts the screen calibration process. Each corner will be 194 | tested, meaning that each boundary (top, left, right and 195 | bottom) will be tested twice and the readings averaged. 196 | */ 197 | /**************************************************************************/ 198 | void tsCalibrate(void) 199 | { 200 | tsPoint_t data; 201 | 202 | /* --------------- Welcome Screen --------------- */ 203 | Serial.println("Starting the calibration process"); 204 | data = renderCalibrationScreen(tft.width() / 2, tft.height() / 2, 5); 205 | delay(250); 206 | 207 | /* ----------------- First Dot ------------------ */ 208 | // 10% over and 10% down 209 | data = renderCalibrationScreen(tft.width() / 10, tft.height() / 10, 5); 210 | _tsLCDPoints[0].x = tft.width() / 10; 211 | _tsLCDPoints[0].y = tft.height() / 10; 212 | _tsTSPoints[0].x = data.x; 213 | _tsTSPoints[0].y = data.y; 214 | Serial.print("Point 1 - LCD"); 215 | Serial.print(" X: "); 216 | Serial.print(_tsLCDPoints[0].x); 217 | Serial.print(" Y: "); 218 | Serial.print(_tsLCDPoints[0].y); 219 | Serial.print(" TS X: "); 220 | Serial.print(_tsTSPoints[0].x); 221 | Serial.print(" Y: "); 222 | Serial.println(_tsTSPoints[0].y); 223 | delay(250); 224 | 225 | /* ---------------- Second Dot ------------------ */ 226 | // 50% over and 90% down 227 | data = renderCalibrationScreen(tft.width() / 2, tft.height() - tft.height() / 10, 5); 228 | _tsLCDPoints[1].x = tft.width() / 2; 229 | _tsLCDPoints[1].y = tft.height() - tft.height() / 10; 230 | _tsTSPoints[1].x = data.x; 231 | _tsTSPoints[1].y = data.y; 232 | Serial.print("Point 2 - LCD"); 233 | Serial.print(" X: "); 234 | Serial.print(_tsLCDPoints[1].x); 235 | Serial.print(" Y: "); 236 | Serial.print(_tsLCDPoints[1].y); 237 | Serial.print(" TS X: "); 238 | Serial.print(_tsTSPoints[1].x); 239 | Serial.print(" Y: "); 240 | Serial.println(_tsTSPoints[1].y); 241 | delay(250); 242 | 243 | /* ---------------- Third Dot ------------------- */ 244 | // 90% over and 50% down 245 | data = renderCalibrationScreen(tft.width() - tft.width() / 10, tft.height() / 2, 5); 246 | _tsLCDPoints[2].x = tft.width() - tft.width() / 10; 247 | _tsLCDPoints[2].y = tft.height() / 2; 248 | _tsTSPoints[2].x = data.x; 249 | _tsTSPoints[2].y = data.y; 250 | Serial.print("Point 3 - LCD"); 251 | Serial.print(" X: "); 252 | Serial.print(_tsLCDPoints[2].x); 253 | Serial.print(" Y: "); 254 | Serial.print(_tsLCDPoints[2].y); 255 | Serial.print(" TS X: "); 256 | Serial.print(_tsTSPoints[2].x); 257 | Serial.print(" Y: "); 258 | Serial.println(_tsTSPoints[2].y); 259 | delay(250); 260 | 261 | /* Clear the screen */ 262 | tft.fillScreen(RA8875_WHITE); 263 | 264 | // Do matrix calculations for calibration and store to EEPROM 265 | setCalibrationMatrix(&_tsLCDPoints[0], &_tsTSPoints[0], &_tsMatrix); 266 | } 267 | 268 | /**************************************************************************/ 269 | /*! 270 | 271 | */ 272 | /**************************************************************************/ 273 | void setup() 274 | { 275 | Serial.begin(9600); 276 | Serial.println("Hello, RA8875!"); 277 | 278 | /* Initialize the display using 'RA8875_480x272' or 'RA8875_800x480' */ 279 | if (!tft.begin(RA8875_480x272)) 280 | { 281 | Serial.println("RA8875 not found ... check your wires!"); 282 | while (1); 283 | } 284 | 285 | /* Enables the display and sets up the backlight */ 286 | Serial.println("Found RA8875"); 287 | tft.displayOn(true); 288 | tft.GPIOX(true); // Enable TFT - display enable tied to GPIOX 289 | tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight 290 | tft.PWM1out(255); 291 | 292 | /* Enable the touch screen */ 293 | Serial.println("Enabled the touch screen"); 294 | pinMode(RA8875_INT, INPUT); 295 | digitalWrite(RA8875_INT, HIGH); 296 | tft.touchEnable(true); 297 | 298 | // Try some GFX acceleration! 299 | //tft.drawCircle(100, 100, 50, RA8875_BLACK); 300 | //tft.fillCircle(100, 100, 49, RA8875_GREEN); 301 | //tft.drawPixel(10,10,RA8875_BLACK); 302 | //tft.drawPixel(11,11,RA8875_BLACK); 303 | //tft.drawRect(10, 10, 400, 200, RA8875_GREEN); 304 | //tft.fillRect(11, 11, 398, 198, RA8875_BLUE); 305 | //tft.drawLine(10, 10, 200, 100, RA8875_RED); 306 | 307 | tft.fillScreen(RA8875_WHITE); 308 | delay(100); 309 | 310 | #if defined(EEPROM_SUPPORTED) 311 | /* Start the calibration process */ 312 | if (FORCE_CALIBRATION || tft.readCalibration(EEPROMLOCATION, &_tsMatrix) == false ){ 313 | Serial.println("Calibration not found. Calibrating..\n"); 314 | tsCalibrate(); 315 | } 316 | else 317 | Serial.println("Calibration found\n"); 318 | #else 319 | tsCalibrate(); 320 | #endif 321 | /* _tsMatrix should now be populated with the correct coefficients! */ 322 | Serial.println("Waiting for touch events ..."); 323 | } 324 | 325 | /**************************************************************************/ 326 | /*! 327 | 328 | */ 329 | /**************************************************************************/ 330 | void loop() 331 | { 332 | tsPoint_t raw; 333 | tsPoint_t calibrated; 334 | 335 | /* Wait around for a touch event */ 336 | waitForTouchEvent(&raw); 337 | 338 | /* Calcuate the real X/Y position based on the calibration matrix */ 339 | calibrateTSPoint(&calibrated, &raw, &_tsMatrix ); 340 | 341 | /* Draw a single pixel at the calibrated point */ 342 | tft.fillCircle(calibrated.x, calibrated.y, 3, RA8875_BLACK); 343 | } 344 | -------------------------------------------------------------------------------- /Adafruit_RA8875.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /*! 3 | @file Adafruit_RA8875.h 4 | @author Limor Friend/Ladyada, K.Townsend/KTOWN for Adafruit Industries 5 | 6 | This is the library for the Adafruit RA8875 Driver board for TFT displays 7 | ---------------> http://www.adafruit.com/products/1590 8 | The RA8875 is a TFT driver for up to 800x480 dotclock'd displays 9 | It is tested to work with displays in the Adafruit shop. Other displays 10 | may need timing adjustments and are not guanteed to work. 11 | 12 | Adafruit invests time and resources providing this open 13 | source code, please support Adafruit and open-source hardware 14 | by purchasing products from Adafruit! 15 | 16 | Written by Limor Fried/Ladyada for Adafruit Industries. 17 | BSD license, check license.txt for more information. 18 | All text above must be included in any redistribution. 19 | */ 20 | /**************************************************************************/ 21 | 22 | #if ARDUINO >= 100 23 | #include "Arduino.h" 24 | #include "Print.h" 25 | #else 26 | #include "WProgram.h" 27 | #endif 28 | 29 | #ifdef __AVR 30 | #include 31 | #elif defined(ESP8266) 32 | #include 33 | #endif 34 | 35 | /// @cond DISABLE 36 | #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega1280__) || \ 37 | defined(__AVR_ATmega2560__) || defined(ESP8266) || defined(ESP32) || \ 38 | defined(DOXYGEN) 39 | /// @endcond 40 | #define EEPROM_SUPPORTED ///< Board supports EEPROM Storage 41 | /// @cond DISABLE 42 | #endif 43 | /// @endcond 44 | 45 | #include 46 | 47 | #ifndef _ADAFRUIT_RA8875_H 48 | #define _ADAFRUIT_RA8875_H ///< File has been included 49 | 50 | // Touchscreen Calibration and EEPROM Storage Defines 51 | #define CFG_EEPROM_TOUCHSCREEN_CAL_AN 0 ///< EEPROM Storage Location 52 | #define CFG_EEPROM_TOUCHSCREEN_CAL_BN 4 ///< EEPROM Storage Location 53 | #define CFG_EEPROM_TOUCHSCREEN_CAL_CN 8 ///< EEPROM Storage Location 54 | #define CFG_EEPROM_TOUCHSCREEN_CAL_DN 12 ///< EEPROM Storage Location 55 | #define CFG_EEPROM_TOUCHSCREEN_CAL_EN 16 ///< EEPROM Storage Location 56 | #define CFG_EEPROM_TOUCHSCREEN_CAL_FN 20 ///< EEPROM Storage Location 57 | #define CFG_EEPROM_TOUCHSCREEN_CAL_DIVIDER 24 ///< EEPROM Storage Location 58 | #define CFG_EEPROM_TOUCHSCREEN_CALIBRATED 28 ///< EEPROM Storage Location 59 | 60 | /// @cond DISABLE 61 | #if defined(EEPROM_SUPPORTED) 62 | #if defined(__AVR_ATmega328P__) 63 | /// @endcond 64 | #define EEPROMSIZE 1024 ///< 1KB EEPROM 65 | /// @cond DISABLE 66 | #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 67 | /// @endcond 68 | #define EEPROMSIZE 4096 ///< 4KB EEPROM 69 | /// @cond DISABLE 70 | #else 71 | /// @endcond 72 | #define EEPROMSIZE 512 ///< 512 Byte EEPROM 73 | /// @cond DISABLE 74 | #endif 75 | #endif 76 | /// @endcond 77 | // Sizes! 78 | 79 | /**************************************************************************/ 80 | /*! 81 | @enum RA8875sizes The Supported Screen Sizes 82 | */ 83 | /**************************************************************************/ 84 | enum RA8875sizes { 85 | RA8875_480x80, /*!< 480x80 Pixel Display */ 86 | RA8875_480x128, /*!< 480x128 Pixel Display */ 87 | RA8875_480x272, /*!< 480x272 Pixel Display */ 88 | RA8875_800x480 /*!< 800x480 Pixel Display */ 89 | }; 90 | 91 | /**************************************************************************/ 92 | /*! 93 | @struct Point 94 | Calibration Point 95 | 96 | @var Point::x 97 | x-coordinate 98 | @var Point::y 99 | y-coordinate 100 | */ 101 | /**************************************************************************/ 102 | typedef struct Point { 103 | int32_t x; 104 | int32_t y; 105 | } tsPoint_t; ///< Nameless struct variable! 106 | 107 | /**************************************************************************/ 108 | /*! 109 | @struct tsMatrix_t 110 | Calibration Data Structure 111 | 112 | @var tsMatrix_t::An 113 | A Coefficient with the coarsest granularity 114 | @var tsMatrix_t::Bn 115 | B Coeffiecient 116 | @var tsMatrix_t::Cn 117 | C Coefficient 118 | @var tsMatrix_t::Dn 119 | D Coeffiecient 120 | @var tsMatrix_t::En 121 | E Coefficient 122 | @var tsMatrix_t::Fn 123 | F Coeffiecient with the finest granularity 124 | @var tsMatrix_t::Divider 125 | Divider for Coefficients 126 | */ 127 | /**************************************************************************/ 128 | typedef struct // Matrix 129 | { 130 | int32_t An, Bn, Cn, Dn, En, Fn, Divider; 131 | } tsMatrix_t; 132 | 133 | /**************************************************************************/ 134 | /*! 135 | @brief Class that stores state and functions for interacting with 136 | the RA8875 display controller. 137 | */ 138 | /**************************************************************************/ 139 | class Adafruit_RA8875 : public Adafruit_GFX { 140 | public: 141 | Adafruit_RA8875(uint8_t cs, uint8_t rst); 142 | 143 | boolean begin(enum RA8875sizes s); 144 | void softReset(void); 145 | void displayOn(boolean on); 146 | void sleep(boolean sleep); 147 | 148 | /* Text functions */ 149 | void textMode(void); 150 | void textSetCursor(uint16_t x, uint16_t y); 151 | void textColor(uint16_t foreColor, uint16_t bgColor); 152 | void textTransparent(uint16_t foreColor); 153 | void textEnlarge(uint8_t scale); 154 | void textWrite(const char *buffer, uint16_t len = 0); 155 | void cursorBlink(uint8_t rate); 156 | 157 | /* Graphics functions */ 158 | void graphicsMode(void); 159 | void setXY(uint16_t x, uint16_t y); 160 | void pushPixels(uint32_t num, uint16_t p); 161 | void fillRect(void); 162 | 163 | /* Adafruit_GFX functions */ 164 | void drawPixel(int16_t x, int16_t y, uint16_t color); 165 | void drawPixels(uint16_t *p, uint32_t count, int16_t x, int16_t y); 166 | void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); 167 | void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); 168 | 169 | /* HW accelerated wrapper functions (override Adafruit_GFX prototypes) */ 170 | void fillScreen(uint16_t color); 171 | void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color); 172 | void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); 173 | void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); 174 | void drawCircle(int16_t x, int16_t y, int16_t r, uint16_t color); 175 | void fillCircle(int16_t x, int16_t y, int16_t r, uint16_t color); 176 | void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, 177 | int16_t y2, uint16_t color); 178 | void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, 179 | int16_t y2, uint16_t color); 180 | void drawEllipse(int16_t xCenter, int16_t yCenter, int16_t longAxis, 181 | int16_t shortAxis, uint16_t color); 182 | void fillEllipse(int16_t xCenter, int16_t yCenter, int16_t longAxis, 183 | int16_t shortAxis, uint16_t color); 184 | void drawCurve(int16_t xCenter, int16_t yCenter, int16_t longAxis, 185 | int16_t shortAxis, uint8_t curvePart, uint16_t color); 186 | void fillCurve(int16_t xCenter, int16_t yCenter, int16_t longAxis, 187 | int16_t shortAxis, uint8_t curvePart, uint16_t color); 188 | void drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, 189 | uint16_t color); 190 | void fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, 191 | uint16_t color); 192 | 193 | /* Scroll */ 194 | void setScrollWindow(int16_t x, int16_t y, int16_t w, int16_t h, 195 | uint8_t mode); 196 | void scrollX(int16_t dist); 197 | void scrollY(int16_t dist); 198 | 199 | /* Backlight */ 200 | void GPIOX(boolean on); 201 | void PWM1config(boolean on, uint8_t clock); 202 | void PWM2config(boolean on, uint8_t clock); 203 | void PWM1out(uint8_t p); 204 | void PWM2out(uint8_t p); 205 | 206 | /* Touch screen */ 207 | void touchEnable(boolean on); 208 | boolean touched(void); 209 | boolean touchRead(uint16_t *x, uint16_t *y); 210 | 211 | /// @cond DISABLE 212 | #if defined(EEPROM_SUPPORTED) 213 | /// @endcond 214 | /* Touch screen calibration persistence*/ 215 | uint32_t eepromReadS32(int location); 216 | void eepromWriteS32(int location, int32_t value); 217 | bool readCalibration(int location, tsMatrix_t *matrixPtr); 218 | void writeCalibration(int location, tsMatrix_t *matrixPtr); 219 | /// @cond DISABLE 220 | #endif 221 | /// @endcond 222 | 223 | /* Low level access */ 224 | void writeReg(uint8_t reg, uint8_t val); 225 | uint8_t readReg(uint8_t reg); 226 | void writeData(uint8_t d); 227 | uint8_t readData(void); 228 | void writeCommand(uint8_t d); 229 | uint8_t readStatus(void); 230 | boolean waitPoll(uint8_t r, uint8_t f); 231 | uint16_t width(void); 232 | uint16_t height(void); 233 | void setRotation(int8_t rotation); 234 | int8_t getRotation(void); 235 | 236 | #ifndef USE_ADAFRUIT_GFX_FONTS 237 | /**************************************************************************/ 238 | /*! 239 | Alias of textWrite to Play nice with Arduino's Print class 240 | 241 | @param b The string to write 242 | 243 | @return The number of bytes written 244 | */ 245 | /**************************************************************************/ 246 | virtual size_t write(uint8_t b) { 247 | textWrite((const char *)&b, 1); 248 | return 1; 249 | } 250 | 251 | /**************************************************************************/ 252 | /*! 253 | Alias of textWrite to Play nice with Arduino's Print class 254 | 255 | @param buffer The buffer to write 256 | @param size The size of the buffer 257 | 258 | @return The number of bytes written 259 | */ 260 | /**************************************************************************/ 261 | virtual size_t write(const uint8_t *buffer, size_t size) { 262 | textWrite((const char *)buffer, size); 263 | return size; 264 | } 265 | #endif 266 | 267 | private: 268 | void PLLinit(void); 269 | void initialize(void); 270 | 271 | /* GFX Helper Functions */ 272 | void circleHelper(int16_t x, int16_t y, int16_t r, uint16_t color, 273 | bool filled); 274 | void rectHelper(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color, 275 | bool filled); 276 | void triangleHelper(int16_t x0, int16_t y0, int16_t x1, int16_t y1, 277 | int16_t x2, int16_t y2, uint16_t color, bool filled); 278 | void ellipseHelper(int16_t xCenter, int16_t yCenter, int16_t longAxis, 279 | int16_t shortAxis, uint16_t color, bool filled); 280 | void curveHelper(int16_t xCenter, int16_t yCenter, int16_t longAxis, 281 | int16_t shortAxis, uint8_t curvePart, uint16_t color, 282 | bool filled); 283 | void roundRectHelper(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, 284 | uint16_t color, bool filled); 285 | 286 | /* Rotation Functions */ 287 | int16_t applyRotationX(int16_t x); 288 | int16_t applyRotationY(int16_t y); 289 | 290 | void swap(int16_t &x, int16_t &y) { 291 | int16_t temp = x; 292 | x = y; 293 | y = temp; 294 | } 295 | 296 | uint8_t _cs, _rst; 297 | uint16_t _width, _height; 298 | uint8_t _textScale; 299 | uint8_t _rotation; 300 | uint8_t _voffset; 301 | enum RA8875sizes _size; 302 | }; 303 | 304 | // Colors (RGB565) 305 | #define RA8875_BLACK 0x0000 ///< Black Color 306 | #define RA8875_BLUE 0x001F ///< Blue Color 307 | #define RA8875_RED 0xF800 ///< Red Color 308 | #define RA8875_GREEN 0x07E0 ///< Green Color 309 | #define RA8875_CYAN 0x07FF ///< Cyan Color 310 | #define RA8875_MAGENTA 0xF81F ///< Magenta Color 311 | #define RA8875_YELLOW 0xFFE0 ///< Yellow Color 312 | #define RA8875_WHITE 0xFFFF ///< White Color 313 | 314 | // Command/Data pins for SPI 315 | #define RA8875_DATAWRITE 0x00 ///< See datasheet 316 | #define RA8875_DATAREAD 0x40 ///< See datasheet 317 | #define RA8875_CMDWRITE 0x80 ///< See datasheet 318 | #define RA8875_CMDREAD 0xC0 ///< See datasheet 319 | 320 | // Registers & bits 321 | #define RA8875_PWRR 0x01 ///< See datasheet 322 | #define RA8875_PWRR_DISPON 0x80 ///< See datasheet 323 | #define RA8875_PWRR_DISPOFF 0x00 ///< See datasheet 324 | #define RA8875_PWRR_SLEEP 0x02 ///< See datasheet 325 | #define RA8875_PWRR_NORMAL 0x00 ///< See datasheet 326 | #define RA8875_PWRR_SOFTRESET 0x01 ///< See datasheet 327 | 328 | #define RA8875_MRWC 0x02 ///< See datasheet 329 | 330 | #define RA8875_GPIOX 0xC7 ///< See datasheet 331 | 332 | #define RA8875_PLLC1 0x88 ///< See datasheet 333 | #define RA8875_PLLC1_PLLDIV2 0x80 ///< See datasheet 334 | #define RA8875_PLLC1_PLLDIV1 0x00 ///< See datasheet 335 | 336 | #define RA8875_PLLC2 0x89 ///< See datasheet 337 | #define RA8875_PLLC2_DIV1 0x00 ///< See datasheet 338 | #define RA8875_PLLC2_DIV2 0x01 ///< See datasheet 339 | #define RA8875_PLLC2_DIV4 0x02 ///< See datasheet 340 | #define RA8875_PLLC2_DIV8 0x03 ///< See datasheet 341 | #define RA8875_PLLC2_DIV16 0x04 ///< See datasheet 342 | #define RA8875_PLLC2_DIV32 0x05 ///< See datasheet 343 | #define RA8875_PLLC2_DIV64 0x06 ///< See datasheet 344 | #define RA8875_PLLC2_DIV128 0x07 ///< See datasheet 345 | 346 | #define RA8875_SYSR 0x10 ///< See datasheet 347 | #define RA8875_SYSR_8BPP 0x00 ///< See datasheet 348 | #define RA8875_SYSR_16BPP 0x0C ///< See datasheet 349 | #define RA8875_SYSR_MCU8 0x00 ///< See datasheet 350 | #define RA8875_SYSR_MCU16 0x03 ///< See datasheet 351 | 352 | #define RA8875_PCSR 0x04 ///< See datasheet 353 | #define RA8875_PCSR_PDATR 0x00 ///< See datasheet 354 | #define RA8875_PCSR_PDATL 0x80 ///< See datasheet 355 | #define RA8875_PCSR_CLK 0x00 ///< See datasheet 356 | #define RA8875_PCSR_2CLK 0x01 ///< See datasheet 357 | #define RA8875_PCSR_4CLK 0x02 ///< See datasheet 358 | #define RA8875_PCSR_8CLK 0x03 ///< See datasheet 359 | 360 | #define RA8875_HDWR 0x14 ///< See datasheet 361 | 362 | #define RA8875_HNDFTR 0x15 ///< See datasheet 363 | #define RA8875_HNDFTR_DE_HIGH 0x00 ///< See datasheet 364 | #define RA8875_HNDFTR_DE_LOW 0x80 ///< See datasheet 365 | 366 | #define RA8875_HNDR 0x16 ///< See datasheet 367 | #define RA8875_HSTR 0x17 ///< See datasheet 368 | #define RA8875_HPWR 0x18 ///< See datasheet 369 | #define RA8875_HPWR_LOW 0x00 ///< See datasheet 370 | #define RA8875_HPWR_HIGH 0x80 ///< See datasheet 371 | 372 | #define RA8875_VDHR0 0x19 ///< See datasheet 373 | #define RA8875_VDHR1 0x1A ///< See datasheet 374 | #define RA8875_VNDR0 0x1B ///< See datasheet 375 | #define RA8875_VNDR1 0x1C ///< See datasheet 376 | #define RA8875_VSTR0 0x1D ///< See datasheet 377 | #define RA8875_VSTR1 0x1E ///< See datasheet 378 | #define RA8875_VPWR 0x1F ///< See datasheet 379 | #define RA8875_VPWR_LOW 0x00 ///< See datasheet 380 | #define RA8875_VPWR_HIGH 0x80 ///< See datasheet 381 | 382 | #define RA8875_HSAW0 0x30 ///< See datasheet 383 | #define RA8875_HSAW1 0x31 ///< See datasheet 384 | #define RA8875_VSAW0 0x32 ///< See datasheet 385 | #define RA8875_VSAW1 0x33 ///< See datasheet 386 | 387 | #define RA8875_HEAW0 0x34 ///< See datasheet 388 | #define RA8875_HEAW1 0x35 ///< See datasheet 389 | #define RA8875_VEAW0 0x36 ///< See datasheet 390 | #define RA8875_VEAW1 0x37 ///< See datasheet 391 | 392 | #define RA8875_MCLR 0x8E ///< See datasheet 393 | #define RA8875_MCLR_START 0x80 ///< See datasheet 394 | #define RA8875_MCLR_STOP 0x00 ///< See datasheet 395 | #define RA8875_MCLR_READSTATUS 0x80 ///< See datasheet 396 | #define RA8875_MCLR_FULL 0x00 ///< See datasheet 397 | #define RA8875_MCLR_ACTIVE 0x40 ///< See datasheet 398 | 399 | #define RA8875_DCR 0x90 ///< See datasheet 400 | #define RA8875_DCR_LINESQUTRI_START 0x80 ///< See datasheet 401 | #define RA8875_DCR_LINESQUTRI_STOP 0x00 ///< See datasheet 402 | #define RA8875_DCR_LINESQUTRI_STATUS 0x80 ///< See datasheet 403 | #define RA8875_DCR_CIRCLE_START 0x40 ///< See datasheet 404 | #define RA8875_DCR_CIRCLE_STATUS 0x40 ///< See datasheet 405 | #define RA8875_DCR_CIRCLE_STOP 0x00 ///< See datasheet 406 | #define RA8875_DCR_FILL 0x20 ///< See datasheet 407 | #define RA8875_DCR_NOFILL 0x00 ///< See datasheet 408 | #define RA8875_DCR_DRAWLINE 0x00 ///< See datasheet 409 | #define RA8875_DCR_DRAWTRIANGLE 0x01 ///< See datasheet 410 | #define RA8875_DCR_DRAWSQUARE 0x10 ///< See datasheet 411 | 412 | #define RA8875_ELLIPSE 0xA0 ///< See datasheet 413 | #define RA8875_ELLIPSE_STATUS 0x80 ///< See datasheet 414 | 415 | #define RA8875_MWCR0 0x40 ///< See datasheet 416 | #define RA8875_MWCR0_GFXMODE 0x00 ///< See datasheet 417 | #define RA8875_MWCR0_TXTMODE 0x80 ///< See datasheet 418 | #define RA8875_MWCR0_CURSOR 0x40 ///< See datasheet 419 | #define RA8875_MWCR0_BLINK 0x20 ///< See datasheet 420 | 421 | #define RA8875_MWCR0_DIRMASK 0x0C ///< Bitmask for Write Direction 422 | #define RA8875_MWCR0_LRTD 0x00 ///< Left->Right then Top->Down 423 | #define RA8875_MWCR0_RLTD 0x04 ///< Right->Left then Top->Down 424 | #define RA8875_MWCR0_TDLR 0x08 ///< Top->Down then Left->Right 425 | #define RA8875_MWCR0_DTLR 0x0C ///< Down->Top then Left->Right 426 | 427 | #define RA8875_BTCR 0x44 ///< See datasheet 428 | #define RA8875_CURH0 0x46 ///< See datasheet 429 | #define RA8875_CURH1 0x47 ///< See datasheet 430 | #define RA8875_CURV0 0x48 ///< See datasheet 431 | #define RA8875_CURV1 0x49 ///< See datasheet 432 | 433 | #define RA8875_P1CR 0x8A ///< See datasheet 434 | #define RA8875_P1CR_ENABLE 0x80 ///< See datasheet 435 | #define RA8875_P1CR_DISABLE 0x00 ///< See datasheet 436 | #define RA8875_P1CR_CLKOUT 0x10 ///< See datasheet 437 | #define RA8875_P1CR_PWMOUT 0x00 ///< See datasheet 438 | 439 | #define RA8875_P1DCR 0x8B ///< See datasheet 440 | 441 | #define RA8875_P2CR 0x8C ///< See datasheet 442 | #define RA8875_P2CR_ENABLE 0x80 ///< See datasheet 443 | #define RA8875_P2CR_DISABLE 0x00 ///< See datasheet 444 | #define RA8875_P2CR_CLKOUT 0x10 ///< See datasheet 445 | #define RA8875_P2CR_PWMOUT 0x00 ///< See datasheet 446 | 447 | #define RA8875_P2DCR 0x8D ///< See datasheet 448 | 449 | #define RA8875_PWM_CLK_DIV1 0x00 ///< See datasheet 450 | #define RA8875_PWM_CLK_DIV2 0x01 ///< See datasheet 451 | #define RA8875_PWM_CLK_DIV4 0x02 ///< See datasheet 452 | #define RA8875_PWM_CLK_DIV8 0x03 ///< See datasheet 453 | #define RA8875_PWM_CLK_DIV16 0x04 ///< See datasheet 454 | #define RA8875_PWM_CLK_DIV32 0x05 ///< See datasheet 455 | #define RA8875_PWM_CLK_DIV64 0x06 ///< See datasheet 456 | #define RA8875_PWM_CLK_DIV128 0x07 ///< See datasheet 457 | #define RA8875_PWM_CLK_DIV256 0x08 ///< See datasheet 458 | #define RA8875_PWM_CLK_DIV512 0x09 ///< See datasheet 459 | #define RA8875_PWM_CLK_DIV1024 0x0A ///< See datasheet 460 | #define RA8875_PWM_CLK_DIV2048 0x0B ///< See datasheet 461 | #define RA8875_PWM_CLK_DIV4096 0x0C ///< See datasheet 462 | #define RA8875_PWM_CLK_DIV8192 0x0D ///< See datasheet 463 | #define RA8875_PWM_CLK_DIV16384 0x0E ///< See datasheet 464 | #define RA8875_PWM_CLK_DIV32768 0x0F ///< See datasheet 465 | 466 | #define RA8875_TPCR0 0x70 ///< See datasheet 467 | #define RA8875_TPCR0_ENABLE 0x80 ///< See datasheet 468 | #define RA8875_TPCR0_DISABLE 0x00 ///< See datasheet 469 | #define RA8875_TPCR0_WAIT_512CLK 0x00 ///< See datasheet 470 | #define RA8875_TPCR0_WAIT_1024CLK 0x10 ///< See datasheet 471 | #define RA8875_TPCR0_WAIT_2048CLK 0x20 ///< See datasheet 472 | #define RA8875_TPCR0_WAIT_4096CLK 0x30 ///< See datasheet 473 | #define RA8875_TPCR0_WAIT_8192CLK 0x40 ///< See datasheet 474 | #define RA8875_TPCR0_WAIT_16384CLK 0x50 ///< See datasheet 475 | #define RA8875_TPCR0_WAIT_32768CLK 0x60 ///< See datasheet 476 | #define RA8875_TPCR0_WAIT_65536CLK 0x70 ///< See datasheet 477 | #define RA8875_TPCR0_WAKEENABLE 0x08 ///< See datasheet 478 | #define RA8875_TPCR0_WAKEDISABLE 0x00 ///< See datasheet 479 | #define RA8875_TPCR0_ADCCLK_DIV1 0x00 ///< See datasheet 480 | #define RA8875_TPCR0_ADCCLK_DIV2 0x01 ///< See datasheet 481 | #define RA8875_TPCR0_ADCCLK_DIV4 0x02 ///< See datasheet 482 | #define RA8875_TPCR0_ADCCLK_DIV8 0x03 ///< See datasheet 483 | #define RA8875_TPCR0_ADCCLK_DIV16 0x04 ///< See datasheet 484 | #define RA8875_TPCR0_ADCCLK_DIV32 0x05 ///< See datasheet 485 | #define RA8875_TPCR0_ADCCLK_DIV64 0x06 ///< See datasheet 486 | #define RA8875_TPCR0_ADCCLK_DIV128 0x07 ///< See datasheet 487 | 488 | #define RA8875_TPCR1 0x71 ///< See datasheet 489 | #define RA8875_TPCR1_AUTO 0x00 ///< See datasheet 490 | #define RA8875_TPCR1_MANUAL 0x40 ///< See datasheet 491 | #define RA8875_TPCR1_VREFINT 0x00 ///< See datasheet 492 | #define RA8875_TPCR1_VREFEXT 0x20 ///< See datasheet 493 | #define RA8875_TPCR1_DEBOUNCE 0x04 ///< See datasheet 494 | #define RA8875_TPCR1_NODEBOUNCE 0x00 ///< See datasheet 495 | #define RA8875_TPCR1_IDLE 0x00 ///< See datasheet 496 | #define RA8875_TPCR1_WAIT 0x01 ///< See datasheet 497 | #define RA8875_TPCR1_LATCHX 0x02 ///< See datasheet 498 | #define RA8875_TPCR1_LATCHY 0x03 ///< See datasheet 499 | 500 | #define RA8875_TPXH 0x72 ///< See datasheet 501 | #define RA8875_TPYH 0x73 ///< See datasheet 502 | #define RA8875_TPXYL 0x74 ///< See datasheet 503 | 504 | #define RA8875_INTC1 0xF0 ///< See datasheet 505 | #define RA8875_INTC1_KEY 0x10 ///< See datasheet 506 | #define RA8875_INTC1_DMA 0x08 ///< See datasheet 507 | #define RA8875_INTC1_TP 0x04 ///< See datasheet 508 | #define RA8875_INTC1_BTE 0x02 ///< See datasheet 509 | 510 | #define RA8875_INTC2 0xF1 ///< See datasheet 511 | #define RA8875_INTC2_KEY 0x10 ///< See datasheet 512 | #define RA8875_INTC2_DMA 0x08 ///< See datasheet 513 | #define RA8875_INTC2_TP 0x04 ///< See datasheet 514 | #define RA8875_INTC2_BTE 0x02 ///< See datasheet 515 | 516 | #define RA8875_SCROLL_BOTH 0x00 ///< See datasheet 517 | #define RA8875_SCROLL_LAYER1 0x40 ///< See datasheet 518 | #define RA8875_SCROLL_LAYER2 0x80 ///< See datasheet 519 | #define RA8875_SCROLL_BUFFER 0xC0 ///< See datasheet 520 | 521 | #endif 522 | -------------------------------------------------------------------------------- /Adafruit_RA8875.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file Adafruit_RA8875.cpp 3 | * 4 | * @mainpage Adafruit RA8875 TFT Driver 5 | * 6 | * @author Limor Friend/Ladyada, K.Townsend/KTOWN for Adafruit Industries 7 | * 8 | * @section intro_sec Introduction 9 | * 10 | * This is the library for the Adafruit RA8875 Driver board for TFT displays 11 | * ---------------> http://www.adafruit.com/products/1590 12 | * The RA8875 is a TFT driver for up to 800x480 dotclock'd displays 13 | * It is tested to work with displays in the Adafruit shop. Other displays 14 | * may need timing adjustments and are not guanteed to work. 15 | * 16 | * Adafruit invests time and resources providing this open 17 | * source code, please support Adafruit and open-source hardware 18 | * by purchasing products from Adafruit! 19 | * 20 | * @section author Author 21 | * 22 | * Written by Limor Fried/Ladyada for Adafruit Industries. 23 | * 24 | * @section license License 25 | * 26 | * BSD license, check license.txt for more information. 27 | * All text above must be included in any redistribution. 28 | * 29 | * @section HISTORY 30 | * 31 | * v1.0 - First release 32 | * 33 | */ 34 | 35 | #include "Adafruit_RA8875.h" 36 | 37 | /// @cond DISABLE 38 | #if defined(EEPROM_SUPPORTED) 39 | /// @endcond 40 | #include 41 | /// @cond DISABLE 42 | #endif 43 | /// @endcond 44 | 45 | #include 46 | 47 | /// @cond DISABLE 48 | #if defined(ARDUINO_ARCH_ARC32) 49 | /// @endcond 50 | uint32_t spi_speed = 12000000; /*!< 12MHz */ 51 | /// @cond DISABLE 52 | #else 53 | /// @endcond 54 | uint32_t spi_speed = 4000000; /*!< 4MHz */ 55 | /// @cond DISABLE 56 | #endif 57 | /// @endcond 58 | 59 | // If the SPI library has transaction support, these functions 60 | // establish settings and protect from interference from other 61 | // libraries. Otherwise, they simply do nothing. 62 | #ifdef SPI_HAS_TRANSACTION 63 | static inline void spi_begin(void) __attribute__((always_inline)); 64 | static inline void spi_begin(void) { 65 | // max speed! 66 | SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE0)); 67 | } 68 | static inline void spi_end(void) __attribute__((always_inline)); 69 | static inline void spi_end(void) { SPI.endTransaction(); } 70 | #else 71 | #define spi_begin() ///< Create dummy Macro Function 72 | #define spi_end() ///< Create dummy Macro Function 73 | #endif 74 | 75 | /**************************************************************************/ 76 | /*! 77 | Constructor for a new RA8875 instance 78 | 79 | @param CS Location of the SPI chip select pin 80 | @param RST Location of the reset pin 81 | */ 82 | /**************************************************************************/ 83 | Adafruit_RA8875::Adafruit_RA8875(uint8_t CS, uint8_t RST) 84 | : Adafruit_GFX(800, 480) { 85 | _cs = CS; 86 | _rst = RST; 87 | } 88 | 89 | /**************************************************************************/ 90 | /*! 91 | Initialises the LCD driver and any HW required by the display 92 | 93 | @param s The display size, which can be either: 94 | 'RA8875_480x80' (3.8" displays) or 95 | 'RA8875_480x128' (3.9" displays) or 96 | 'RA8875_480x272' (4.3" displays) or 97 | 'RA8875_800x480' (5" and 7" displays) 98 | 99 | @return True if we reached the end 100 | */ 101 | /**************************************************************************/ 102 | boolean Adafruit_RA8875::begin(enum RA8875sizes s) { 103 | _size = s; 104 | 105 | if (_size == RA8875_480x80) { 106 | _width = 480; 107 | _height = 80; 108 | } else if (_size == RA8875_480x128) { 109 | _width = 480; 110 | _height = 128; 111 | } else if (_size == RA8875_480x272) { 112 | _width = 480; 113 | _height = 272; 114 | } else if (_size == RA8875_800x480) { 115 | _width = 800; 116 | _height = 480; 117 | } else { 118 | return false; 119 | } 120 | _rotation = 0; 121 | pinMode(_cs, OUTPUT); 122 | digitalWrite(_cs, HIGH); 123 | pinMode(_rst, OUTPUT); 124 | 125 | digitalWrite(_rst, LOW); 126 | delay(100); 127 | digitalWrite(_rst, HIGH); 128 | delay(100); 129 | 130 | SPI.begin(); 131 | 132 | #ifdef SPI_HAS_TRANSACTION 133 | /// @cond DISABLE 134 | #if defined(ARDUINO_ARCH_ARC32) 135 | /// @endcond 136 | spi_speed = 2000000; 137 | /// @cond DISABLE 138 | #else 139 | /// @endcond 140 | spi_speed = 125000; 141 | /// @cond DISABLE 142 | #endif 143 | /// @endcond 144 | #else 145 | #ifdef __AVR__ 146 | SPI.setClockDivider(SPI_CLOCK_DIV128); 147 | SPI.setDataMode(SPI_MODE0); 148 | #endif 149 | #endif 150 | 151 | uint8_t x = readReg(0); 152 | // Serial.print("x = 0x"); Serial.println(x,HEX); 153 | if (x != 0x75) { 154 | Serial.println(x); 155 | return false; 156 | } 157 | 158 | initialize(); 159 | 160 | #ifdef SPI_HAS_TRANSACTION 161 | /// @cond DISABLE 162 | #if defined(ARDUINO_ARCH_ARC32) 163 | /// @endcond 164 | spi_speed = 12000000L; 165 | #else 166 | spi_speed = 4000000L; 167 | #endif 168 | #else 169 | #ifdef __AVR__ 170 | SPI.setClockDivider(SPI_CLOCK_DIV4); 171 | #endif 172 | #endif 173 | 174 | return true; 175 | } 176 | 177 | /************************* Initialization *********************************/ 178 | 179 | /**************************************************************************/ 180 | /*! 181 | Performs a SW-based reset of the RA8875 182 | */ 183 | /**************************************************************************/ 184 | void Adafruit_RA8875::softReset(void) { 185 | writeCommand(RA8875_PWRR); 186 | writeData(RA8875_PWRR_SOFTRESET); 187 | writeData(RA8875_PWRR_NORMAL); 188 | delay(1); 189 | } 190 | 191 | /**************************************************************************/ 192 | /*! 193 | Initialise the PLL 194 | */ 195 | /**************************************************************************/ 196 | void Adafruit_RA8875::PLLinit(void) { 197 | if (_size == RA8875_480x80 || _size == RA8875_480x128 || 198 | _size == RA8875_480x272) { 199 | writeReg(RA8875_PLLC1, RA8875_PLLC1_PLLDIV1 + 10); 200 | delay(1); 201 | writeReg(RA8875_PLLC2, RA8875_PLLC2_DIV4); 202 | delay(1); 203 | } else /* (_size == RA8875_800x480) */ { 204 | writeReg(RA8875_PLLC1, RA8875_PLLC1_PLLDIV1 + 11); 205 | delay(1); 206 | writeReg(RA8875_PLLC2, RA8875_PLLC2_DIV4); 207 | delay(1); 208 | } 209 | } 210 | 211 | /**************************************************************************/ 212 | /*! 213 | Initialises the driver IC (clock setup, etc.) 214 | */ 215 | /**************************************************************************/ 216 | void Adafruit_RA8875::initialize(void) { 217 | PLLinit(); 218 | writeReg(RA8875_SYSR, RA8875_SYSR_16BPP | RA8875_SYSR_MCU8); 219 | 220 | /* Timing values */ 221 | uint8_t pixclk; 222 | uint8_t hsync_start; 223 | uint8_t hsync_pw; 224 | uint8_t hsync_finetune; 225 | uint8_t hsync_nondisp; 226 | uint8_t vsync_pw; 227 | uint16_t vsync_nondisp; 228 | uint16_t vsync_start; 229 | 230 | /* Set the correct values for the display being used */ 231 | if (_size == RA8875_480x80) { 232 | pixclk = RA8875_PCSR_PDATL | RA8875_PCSR_4CLK; 233 | hsync_nondisp = 10; 234 | hsync_start = 8; 235 | hsync_pw = 48; 236 | hsync_finetune = 0; 237 | vsync_nondisp = 3; 238 | vsync_start = 8; 239 | vsync_pw = 10; 240 | _voffset = 192; // This uses the bottom 80 pixels of a 272 pixel controller 241 | } else if (_size == RA8875_480x128 || _size == RA8875_480x272) { 242 | pixclk = RA8875_PCSR_PDATL | RA8875_PCSR_4CLK; 243 | hsync_nondisp = 10; 244 | hsync_start = 8; 245 | hsync_pw = 48; 246 | hsync_finetune = 0; 247 | vsync_nondisp = 3; 248 | vsync_start = 8; 249 | vsync_pw = 10; 250 | _voffset = 0; 251 | } else // (_size == RA8875_800x480) 252 | { 253 | pixclk = RA8875_PCSR_PDATL | RA8875_PCSR_2CLK; 254 | hsync_nondisp = 26; 255 | hsync_start = 32; 256 | hsync_pw = 96; 257 | hsync_finetune = 0; 258 | vsync_nondisp = 32; 259 | vsync_start = 23; 260 | vsync_pw = 2; 261 | _voffset = 0; 262 | } 263 | 264 | writeReg(RA8875_PCSR, pixclk); 265 | delay(1); 266 | 267 | /* Horizontal settings registers */ 268 | writeReg(RA8875_HDWR, (_width / 8) - 1); // H width: (HDWR + 1) * 8 = 480 269 | writeReg(RA8875_HNDFTR, RA8875_HNDFTR_DE_HIGH + hsync_finetune); 270 | writeReg(RA8875_HNDR, (hsync_nondisp - hsync_finetune - 2) / 271 | 8); // H non-display: HNDR * 8 + HNDFTR + 2 = 10 272 | writeReg(RA8875_HSTR, hsync_start / 8 - 1); // Hsync start: (HSTR + 1)*8 273 | writeReg(RA8875_HPWR, 274 | RA8875_HPWR_LOW + 275 | (hsync_pw / 8 - 1)); // HSync pulse width = (HPWR+1) * 8 276 | 277 | /* Vertical settings registers */ 278 | writeReg(RA8875_VDHR0, (uint16_t)(_height - 1 + _voffset) & 0xFF); 279 | writeReg(RA8875_VDHR1, (uint16_t)(_height - 1 + _voffset) >> 8); 280 | writeReg(RA8875_VNDR0, vsync_nondisp - 1); // V non-display period = VNDR + 1 281 | writeReg(RA8875_VNDR1, vsync_nondisp >> 8); 282 | writeReg(RA8875_VSTR0, vsync_start - 1); // Vsync start position = VSTR + 1 283 | writeReg(RA8875_VSTR1, vsync_start >> 8); 284 | writeReg(RA8875_VPWR, 285 | RA8875_VPWR_LOW + vsync_pw - 1); // Vsync pulse width = VPWR + 1 286 | 287 | /* Set active window X */ 288 | writeReg(RA8875_HSAW0, 0); // horizontal start point 289 | writeReg(RA8875_HSAW1, 0); 290 | writeReg(RA8875_HEAW0, (uint16_t)(_width - 1) & 0xFF); // horizontal end point 291 | writeReg(RA8875_HEAW1, (uint16_t)(_width - 1) >> 8); 292 | 293 | /* Set active window Y */ 294 | writeReg(RA8875_VSAW0, 0 + _voffset); // vertical start point 295 | writeReg(RA8875_VSAW1, 0 + _voffset); 296 | writeReg(RA8875_VEAW0, 297 | (uint16_t)(_height - 1 + _voffset) & 0xFF); // vertical end point 298 | writeReg(RA8875_VEAW1, (uint16_t)(_height - 1 + _voffset) >> 8); 299 | 300 | /* ToDo: Setup touch panel? */ 301 | 302 | /* Clear the entire window */ 303 | writeReg(RA8875_MCLR, RA8875_MCLR_START | RA8875_MCLR_FULL); 304 | delay(500); 305 | } 306 | 307 | /**************************************************************************/ 308 | /*! 309 | Returns the display width in pixels 310 | 311 | @return The 1-based display width in pixels 312 | */ 313 | /**************************************************************************/ 314 | uint16_t Adafruit_RA8875::width(void) { return _width; } 315 | 316 | /**************************************************************************/ 317 | /*! 318 | Returns the display height in pixels 319 | 320 | @return The 1-based display height in pixels 321 | */ 322 | /**************************************************************************/ 323 | uint16_t Adafruit_RA8875::height(void) { return _height; } 324 | 325 | /**************************************************************************/ 326 | /*! 327 | Returns the current rotation (0-3) 328 | 329 | @return The Rotation Setting 330 | */ 331 | /**************************************************************************/ 332 | int8_t Adafruit_RA8875::getRotation(void) { return _rotation; } 333 | 334 | /**************************************************************************/ 335 | /*! 336 | Sets the current rotation (0-3) 337 | 338 | @param rotation The Rotation Setting 339 | */ 340 | /**************************************************************************/ 341 | void Adafruit_RA8875::setRotation(int8_t rotation) { 342 | switch (rotation) { 343 | case 2: 344 | _rotation = rotation; 345 | break; 346 | default: 347 | _rotation = 0; 348 | break; 349 | } 350 | } 351 | 352 | /************************* Text Mode ***********************************/ 353 | 354 | /**************************************************************************/ 355 | /*! 356 | Sets the display in text mode (as opposed to graphics mode) 357 | */ 358 | /**************************************************************************/ 359 | void Adafruit_RA8875::textMode(void) { 360 | /* Set text mode */ 361 | writeCommand(RA8875_MWCR0); 362 | uint8_t temp = readData(); 363 | temp |= RA8875_MWCR0_TXTMODE; // Set bit 7 364 | writeData(temp); 365 | 366 | /* Select the internal (ROM) font */ 367 | writeCommand(0x21); 368 | temp = readData(); 369 | temp &= ~((1 << 7) | (1 << 5)); // Clear bits 7 and 5 370 | writeData(temp); 371 | } 372 | 373 | /**************************************************************************/ 374 | /*! 375 | Sets the display in text mode (as opposed to graphics mode) 376 | 377 | @param x The x position of the cursor (in pixels, 0..1023) 378 | @param y The y position of the cursor (in pixels, 0..511) 379 | */ 380 | /**************************************************************************/ 381 | void Adafruit_RA8875::textSetCursor(uint16_t x, uint16_t y) { 382 | x = applyRotationX(x); 383 | y = applyRotationY(y); 384 | 385 | /* Set cursor location */ 386 | writeCommand(0x2A); 387 | writeData(x & 0xFF); 388 | writeCommand(0x2B); 389 | writeData(x >> 8); 390 | writeCommand(0x2C); 391 | writeData(y & 0xFF); 392 | writeCommand(0x2D); 393 | writeData(y >> 8); 394 | } 395 | 396 | /**************************************************************************/ 397 | /*! 398 | Sets the fore and background color when rendering text 399 | 400 | @param foreColor The RGB565 color to use when rendering the text 401 | @param bgColor The RGB565 colot to use for the background 402 | */ 403 | /**************************************************************************/ 404 | void Adafruit_RA8875::textColor(uint16_t foreColor, uint16_t bgColor) { 405 | /* Set Fore Color */ 406 | writeCommand(0x63); 407 | writeData((foreColor & 0xf800) >> 11); 408 | writeCommand(0x64); 409 | writeData((foreColor & 0x07e0) >> 5); 410 | writeCommand(0x65); 411 | writeData((foreColor & 0x001f)); 412 | 413 | /* Set Background Color */ 414 | writeCommand(0x60); 415 | writeData((bgColor & 0xf800) >> 11); 416 | writeCommand(0x61); 417 | writeData((bgColor & 0x07e0) >> 5); 418 | writeCommand(0x62); 419 | writeData((bgColor & 0x001f)); 420 | 421 | /* Clear transparency flag */ 422 | writeCommand(0x22); 423 | uint8_t temp = readData(); 424 | temp &= ~(1 << 6); // Clear bit 6 425 | writeData(temp); 426 | } 427 | 428 | /**************************************************************************/ 429 | /*! 430 | Sets the fore color when rendering text with a transparent bg 431 | 432 | @param foreColor The RGB565 color to use when rendering the text 433 | */ 434 | /**************************************************************************/ 435 | void Adafruit_RA8875::textTransparent(uint16_t foreColor) { 436 | /* Set Fore Color */ 437 | writeCommand(0x63); 438 | writeData((foreColor & 0xf800) >> 11); 439 | writeCommand(0x64); 440 | writeData((foreColor & 0x07e0) >> 5); 441 | writeCommand(0x65); 442 | writeData((foreColor & 0x001f)); 443 | 444 | /* Set transparency flag */ 445 | writeCommand(0x22); 446 | uint8_t temp = readData(); 447 | temp |= (1 << 6); // Set bit 6 448 | writeData(temp); 449 | } 450 | 451 | /**************************************************************************/ 452 | /*! 453 | Sets the text enlarge settings, using one of the following values: 454 | 455 | 0 = 1x zoom 456 | 1 = 2x zoom 457 | 2 = 3x zoom 458 | 3 = 4x zoom 459 | 460 | @param scale The zoom factor (0..3 for 1-4x zoom) 461 | */ 462 | /**************************************************************************/ 463 | void Adafruit_RA8875::textEnlarge(uint8_t scale) { 464 | if (scale > 3) 465 | scale = 3; // highest setting is 3 466 | 467 | /* Set font size flags */ 468 | writeCommand(0x22); 469 | uint8_t temp = readData(); 470 | temp &= ~(0xF); // Clears bits 0..3 471 | temp |= scale << 2; 472 | temp |= scale; 473 | 474 | writeData(temp); 475 | 476 | _textScale = scale; 477 | } 478 | 479 | /**************************************************************************/ 480 | /*! 481 | Enable Cursor Visibility and Blink 482 | Here we set bits 6 and 5 in 40h 483 | As well as the set the blink rate in 44h 484 | The rate is 0 through max 255 485 | the lower the number the faster it blinks (00h is 1 frame time, 486 | FFh is 256 Frames time. 487 | Blink Time (sec) = BTCR[44h]x(1/Frame_rate) 488 | 489 | @param rate The frame rate to blink 490 | */ 491 | /**************************************************************************/ 492 | 493 | void Adafruit_RA8875::cursorBlink(uint8_t rate) { 494 | 495 | writeCommand(RA8875_MWCR0); 496 | uint8_t temp = readData(); 497 | temp |= RA8875_MWCR0_CURSOR; 498 | writeData(temp); 499 | 500 | writeCommand(RA8875_MWCR0); 501 | temp = readData(); 502 | temp |= RA8875_MWCR0_BLINK; 503 | writeData(temp); 504 | 505 | if (rate > 255) 506 | rate = 255; 507 | writeCommand(RA8875_BTCR); 508 | writeData(rate); 509 | } 510 | 511 | /**************************************************************************/ 512 | /*! 513 | Renders some text on the screen when in text mode 514 | 515 | @param buffer The buffer containing the characters to render 516 | @param len The size of the buffer in bytes 517 | */ 518 | /**************************************************************************/ 519 | void Adafruit_RA8875::textWrite(const char *buffer, uint16_t len) { 520 | if (len == 0) 521 | len = strlen(buffer); 522 | writeCommand(RA8875_MRWC); 523 | for (uint16_t i = 0; i < len; i++) { 524 | writeData(buffer[i]); 525 | /// @cond DISABLE 526 | #if defined(__arm__) 527 | /// @endcond 528 | // This delay is needed with textEnlarge(1) because 529 | // Teensy 3.X is much faster than Arduino Uno 530 | if (_textScale > 0) 531 | delay(1); 532 | /// @cond DISABLE 533 | #else 534 | /// @endcond 535 | // For others, delay starting with textEnlarge(2) 536 | if (_textScale > 1) 537 | delay(1); 538 | /// @cond DISABLE 539 | #endif 540 | /// @endcond 541 | } 542 | } 543 | 544 | /************************* Graphics ***********************************/ 545 | 546 | /**************************************************************************/ 547 | /*! 548 | Sets the display in graphics mode (as opposed to text mode) 549 | */ 550 | /**************************************************************************/ 551 | void Adafruit_RA8875::graphicsMode(void) { 552 | writeCommand(RA8875_MWCR0); 553 | uint8_t temp = readData(); 554 | temp &= ~RA8875_MWCR0_TXTMODE; // bit #7 555 | writeData(temp); 556 | } 557 | 558 | /**************************************************************************/ 559 | /*! 560 | Waits for screen to finish by polling the status! 561 | 562 | @param regname The register name to check 563 | @param waitflag The value to wait for the status register to match 564 | 565 | @return True if the expected status has been reached 566 | */ 567 | /**************************************************************************/ 568 | boolean Adafruit_RA8875::waitPoll(uint8_t regname, uint8_t waitflag) { 569 | /* Wait for the command to finish */ 570 | while (1) { 571 | uint8_t temp = readReg(regname); 572 | if (!(temp & waitflag)) 573 | return true; 574 | } 575 | return false; // MEMEFIX: yeah i know, unreached! - add timeout? 576 | } 577 | 578 | /**************************************************************************/ 579 | /*! 580 | Sets the current X/Y position on the display before drawing 581 | 582 | @param x The 0-based x location 583 | @param y The 0-base y location 584 | */ 585 | /**************************************************************************/ 586 | void Adafruit_RA8875::setXY(uint16_t x, uint16_t y) { 587 | writeReg(RA8875_CURH0, x); 588 | writeReg(RA8875_CURH1, x >> 8); 589 | writeReg(RA8875_CURV0, y); 590 | writeReg(RA8875_CURV1, y >> 8); 591 | } 592 | 593 | /**************************************************************************/ 594 | /*! 595 | HW accelerated function to push a chunk of raw pixel data 596 | 597 | @param num The number of pixels to push 598 | @param p The pixel color to use 599 | */ 600 | /**************************************************************************/ 601 | void Adafruit_RA8875::pushPixels(uint32_t num, uint16_t p) { 602 | digitalWrite(_cs, LOW); 603 | SPI.transfer(RA8875_DATAWRITE); 604 | while (num--) { 605 | SPI.transfer(p >> 8); 606 | SPI.transfer(p); 607 | } 608 | digitalWrite(_cs, HIGH); 609 | } 610 | 611 | /**************************************************************************/ 612 | /*! 613 | Fill the screen with the current color 614 | */ 615 | /**************************************************************************/ 616 | void Adafruit_RA8875::fillRect(void) { 617 | writeCommand(RA8875_DCR); 618 | writeData(RA8875_DCR_LINESQUTRI_STOP | RA8875_DCR_DRAWSQUARE); 619 | writeData(RA8875_DCR_LINESQUTRI_START | RA8875_DCR_FILL | 620 | RA8875_DCR_DRAWSQUARE); 621 | } 622 | 623 | /**************************************************************************/ 624 | /*! 625 | Apply current rotation in the X direction 626 | 627 | @return the X value with current rotation applied 628 | */ 629 | /**************************************************************************/ 630 | int16_t Adafruit_RA8875::applyRotationX(int16_t x) { 631 | switch (_rotation) { 632 | case 2: 633 | x = _width - 1 - x; 634 | break; 635 | } 636 | 637 | return x; 638 | } 639 | 640 | /**************************************************************************/ 641 | /*! 642 | Apply current rotation in the Y direction 643 | 644 | @return the Y value with current rotation applied 645 | */ 646 | /**************************************************************************/ 647 | int16_t Adafruit_RA8875::applyRotationY(int16_t y) { 648 | switch (_rotation) { 649 | case 2: 650 | y = _height - 1 - y; 651 | break; 652 | } 653 | 654 | return y + _voffset; 655 | } 656 | 657 | /**************************************************************************/ 658 | /*! 659 | Draws a single pixel at the specified location 660 | 661 | @param x The 0-based x location 662 | @param y The 0-base y location 663 | @param color The RGB565 color to use when drawing the pixel 664 | */ 665 | /**************************************************************************/ 666 | void Adafruit_RA8875::drawPixel(int16_t x, int16_t y, uint16_t color) { 667 | x = applyRotationX(x); 668 | y = applyRotationY(y); 669 | 670 | writeReg(RA8875_CURH0, x); 671 | writeReg(RA8875_CURH1, x >> 8); 672 | writeReg(RA8875_CURV0, y); 673 | writeReg(RA8875_CURV1, y >> 8); 674 | writeCommand(RA8875_MRWC); 675 | digitalWrite(_cs, LOW); 676 | SPI.transfer(RA8875_DATAWRITE); 677 | SPI.transfer(color >> 8); 678 | SPI.transfer(color); 679 | digitalWrite(_cs, HIGH); 680 | } 681 | 682 | /**************************************************************************/ 683 | /*! 684 | Draws a series of pixels at the specified location without the overhead 685 | 686 | @param p An array of RGB565 color pixels 687 | @param num The number of the pixels to draw 688 | @param x The 0-based x location 689 | @param y The 0-base y location 690 | */ 691 | /**************************************************************************/ 692 | void Adafruit_RA8875::drawPixels(uint16_t *p, uint32_t num, int16_t x, 693 | int16_t y) { 694 | x = applyRotationX(x); 695 | y = applyRotationY(y); 696 | 697 | writeReg(RA8875_CURH0, x); 698 | writeReg(RA8875_CURH1, x >> 8); 699 | writeReg(RA8875_CURV0, y); 700 | writeReg(RA8875_CURV1, y >> 8); 701 | 702 | uint8_t dir = RA8875_MWCR0_LRTD; 703 | if (_rotation == 2) { 704 | dir = RA8875_MWCR0_RLTD; 705 | } 706 | writeReg(RA8875_MWCR0, (readReg(RA8875_MWCR0) & ~RA8875_MWCR0_DIRMASK) | dir); 707 | 708 | writeCommand(RA8875_MRWC); 709 | digitalWrite(_cs, LOW); 710 | SPI.transfer(RA8875_DATAWRITE); 711 | while (num--) { 712 | SPI.transfer16(*p++); 713 | } 714 | digitalWrite(_cs, HIGH); 715 | } 716 | 717 | /**************************************************************************/ 718 | /*! 719 | Draws a HW accelerated line on the display 720 | 721 | @param x0 The 0-based starting x location 722 | @param y0 The 0-base starting y location 723 | @param x1 The 0-based ending x location 724 | @param y1 The 0-base ending y location 725 | @param color The RGB565 color to use when drawing the pixel 726 | */ 727 | /**************************************************************************/ 728 | void Adafruit_RA8875::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, 729 | uint16_t color) { 730 | x0 = applyRotationX(x0); 731 | y0 = applyRotationY(y0); 732 | x1 = applyRotationX(x1); 733 | y1 = applyRotationY(y1); 734 | 735 | /* Set X */ 736 | writeCommand(0x91); 737 | writeData(x0); 738 | writeCommand(0x92); 739 | writeData(x0 >> 8); 740 | 741 | /* Set Y */ 742 | writeCommand(0x93); 743 | writeData(y0); 744 | writeCommand(0x94); 745 | writeData(y0 >> 8); 746 | 747 | /* Set X1 */ 748 | writeCommand(0x95); 749 | writeData(x1); 750 | writeCommand(0x96); 751 | writeData((x1) >> 8); 752 | 753 | /* Set Y1 */ 754 | writeCommand(0x97); 755 | writeData(y1); 756 | writeCommand(0x98); 757 | writeData((y1) >> 8); 758 | 759 | /* Set Color */ 760 | writeCommand(0x63); 761 | writeData((color & 0xf800) >> 11); 762 | writeCommand(0x64); 763 | writeData((color & 0x07e0) >> 5); 764 | writeCommand(0x65); 765 | writeData((color & 0x001f)); 766 | 767 | /* Draw! */ 768 | writeCommand(RA8875_DCR); 769 | writeData(0x80); 770 | 771 | /* Wait for the command to finish */ 772 | waitPoll(RA8875_DCR, RA8875_DCR_LINESQUTRI_STATUS); 773 | } 774 | 775 | /**************************************************************************/ 776 | /*! 777 | Draw a vertical line 778 | 779 | @param x The X position 780 | @param y The Y position 781 | @param h Height 782 | @param color The color 783 | */ 784 | /**************************************************************************/ 785 | void Adafruit_RA8875::drawFastVLine(int16_t x, int16_t y, int16_t h, 786 | uint16_t color) { 787 | drawLine(x, y, x, y + h, color); 788 | } 789 | 790 | /**************************************************************************/ 791 | /*! 792 | Draw a horizontal line 793 | 794 | @param x The X position 795 | @param y The Y position 796 | @param w Width 797 | @param color The color 798 | */ 799 | /**************************************************************************/ 800 | void Adafruit_RA8875::drawFastHLine(int16_t x, int16_t y, int16_t w, 801 | uint16_t color) { 802 | drawLine(x, y, x + w, y, color); 803 | } 804 | 805 | /**************************************************************************/ 806 | /*! 807 | Draws a HW accelerated rectangle on the display 808 | 809 | @param x The 0-based x location of the top-right corner 810 | @param y The 0-based y location of the top-right corner 811 | @param w The rectangle width 812 | @param h The rectangle height 813 | @param color The RGB565 color to use when drawing the pixel 814 | */ 815 | /**************************************************************************/ 816 | void Adafruit_RA8875::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, 817 | uint16_t color) { 818 | rectHelper(x, y, x + w - 1, y + h - 1, color, false); 819 | } 820 | 821 | /**************************************************************************/ 822 | /*! 823 | Draws a HW accelerated filled rectangle on the display 824 | 825 | @param x The 0-based x location of the top-right corner 826 | @param y The 0-based y location of the top-right corner 827 | @param w The rectangle width 828 | @param h The rectangle height 829 | @param color The RGB565 color to use when drawing the pixel 830 | */ 831 | /**************************************************************************/ 832 | void Adafruit_RA8875::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 833 | uint16_t color) { 834 | rectHelper(x, y, x + w - 1, y + h - 1, color, true); 835 | } 836 | 837 | /**************************************************************************/ 838 | /*! 839 | Fills the screen with the spefied RGB565 color 840 | 841 | @param color The RGB565 color to use when drawing the pixel 842 | */ 843 | /**************************************************************************/ 844 | void Adafruit_RA8875::fillScreen(uint16_t color) { 845 | rectHelper(0, 0, _width - 1, _height - 1, color, true); 846 | } 847 | 848 | /**************************************************************************/ 849 | /*! 850 | Draws a HW accelerated circle on the display 851 | 852 | @param x The 0-based x location of the center of the circle 853 | @param y The 0-based y location of the center of the circle 854 | @param r The circle's radius 855 | @param color The RGB565 color to use when drawing the pixel 856 | */ 857 | /**************************************************************************/ 858 | void Adafruit_RA8875::drawCircle(int16_t x, int16_t y, int16_t r, 859 | uint16_t color) { 860 | circleHelper(x, y, r, color, false); 861 | } 862 | 863 | /**************************************************************************/ 864 | /*! 865 | Draws a HW accelerated filled circle on the display 866 | 867 | @param x The 0-based x location of the center of the circle 868 | @param y The 0-based y location of the center of the circle 869 | @param r The circle's radius 870 | @param color The RGB565 color to use when drawing the pixel 871 | */ 872 | /**************************************************************************/ 873 | void Adafruit_RA8875::fillCircle(int16_t x, int16_t y, int16_t r, 874 | uint16_t color) { 875 | circleHelper(x, y, r, color, true); 876 | } 877 | 878 | /**************************************************************************/ 879 | /*! 880 | Draws a HW accelerated triangle on the display 881 | 882 | @param x0 The 0-based x location of point 0 on the triangle 883 | @param y0 The 0-based y location of point 0 on the triangle 884 | @param x1 The 0-based x location of point 1 on the triangle 885 | @param y1 The 0-based y location of point 1 on the triangle 886 | @param x2 The 0-based x location of point 2 on the triangle 887 | @param y2 The 0-based y location of point 2 on the triangle 888 | @param color The RGB565 color to use when drawing the pixel 889 | */ 890 | /**************************************************************************/ 891 | void Adafruit_RA8875::drawTriangle(int16_t x0, int16_t y0, int16_t x1, 892 | int16_t y1, int16_t x2, int16_t y2, 893 | uint16_t color) { 894 | triangleHelper(x0, y0, x1, y1, x2, y2, color, false); 895 | } 896 | 897 | /**************************************************************************/ 898 | /*! 899 | Draws a HW accelerated filled triangle on the display 900 | 901 | @param x0 The 0-based x location of point 0 on the triangle 902 | @param y0 The 0-based y location of point 0 on the triangle 903 | @param x1 The 0-based x location of point 1 on the triangle 904 | @param y1 The 0-based y location of point 1 on the triangle 905 | @param x2 The 0-based x location of point 2 on the triangle 906 | @param y2 The 0-based y location of point 2 on the triangle 907 | @param color The RGB565 color to use when drawing the pixel 908 | */ 909 | /**************************************************************************/ 910 | void Adafruit_RA8875::fillTriangle(int16_t x0, int16_t y0, int16_t x1, 911 | int16_t y1, int16_t x2, int16_t y2, 912 | uint16_t color) { 913 | triangleHelper(x0, y0, x1, y1, x2, y2, color, true); 914 | } 915 | 916 | /**************************************************************************/ 917 | /*! 918 | Draws a HW accelerated ellipse on the display 919 | 920 | @param xCenter The 0-based x location of the ellipse's center 921 | @param yCenter The 0-based y location of the ellipse's center 922 | @param longAxis The size in pixels of the ellipse's long axis 923 | @param shortAxis The size in pixels of the ellipse's short axis 924 | @param color The RGB565 color to use when drawing the pixel 925 | */ 926 | /**************************************************************************/ 927 | void Adafruit_RA8875::drawEllipse(int16_t xCenter, int16_t yCenter, 928 | int16_t longAxis, int16_t shortAxis, 929 | uint16_t color) { 930 | ellipseHelper(xCenter, yCenter, longAxis, shortAxis, color, false); 931 | } 932 | 933 | /**************************************************************************/ 934 | /*! 935 | Draws a HW accelerated filled ellipse on the display 936 | 937 | @param xCenter The 0-based x location of the ellipse's center 938 | @param yCenter The 0-based y location of the ellipse's center 939 | @param longAxis The size in pixels of the ellipse's long axis 940 | @param shortAxis The size in pixels of the ellipse's short axis 941 | @param color The RGB565 color to use when drawing the pixel 942 | */ 943 | /**************************************************************************/ 944 | void Adafruit_RA8875::fillEllipse(int16_t xCenter, int16_t yCenter, 945 | int16_t longAxis, int16_t shortAxis, 946 | uint16_t color) { 947 | ellipseHelper(xCenter, yCenter, longAxis, shortAxis, color, true); 948 | } 949 | 950 | /**************************************************************************/ 951 | /*! 952 | Draws a HW accelerated curve on the display 953 | 954 | @param xCenter The 0-based x location of the ellipse's center 955 | @param yCenter The 0-based y location of the ellipse's center 956 | @param longAxis The size in pixels of the ellipse's long axis 957 | @param shortAxis The size in pixels of the ellipse's short axis 958 | @param curvePart The corner to draw, where in clock-wise motion: 959 | 0 = 180-270° 960 | 1 = 270-0° 961 | 2 = 0-90° 962 | 3 = 90-180° 963 | @param color The RGB565 color to use when drawing the pixel 964 | */ 965 | /**************************************************************************/ 966 | void Adafruit_RA8875::drawCurve(int16_t xCenter, int16_t yCenter, 967 | int16_t longAxis, int16_t shortAxis, 968 | uint8_t curvePart, uint16_t color) { 969 | curveHelper(xCenter, yCenter, longAxis, shortAxis, curvePart, color, false); 970 | } 971 | 972 | /**************************************************************************/ 973 | /*! 974 | Draws a HW accelerated filled curve on the display 975 | 976 | @param xCenter The 0-based x location of the ellipse's center 977 | @param yCenter The 0-based y location of the ellipse's center 978 | @param longAxis The size in pixels of the ellipse's long axis 979 | @param shortAxis The size in pixels of the ellipse's short axis 980 | @param curvePart The corner to draw, where in clock-wise motion: 981 | 0 = 180-270° 982 | 1 = 270-0° 983 | 2 = 0-90° 984 | 3 = 90-180° 985 | @param color The RGB565 color to use when drawing the pixel 986 | */ 987 | /**************************************************************************/ 988 | void Adafruit_RA8875::fillCurve(int16_t xCenter, int16_t yCenter, 989 | int16_t longAxis, int16_t shortAxis, 990 | uint8_t curvePart, uint16_t color) { 991 | curveHelper(xCenter, yCenter, longAxis, shortAxis, curvePart, color, true); 992 | } 993 | 994 | /**************************************************************************/ 995 | /*! 996 | Draws a HW accelerated rounded rectangle on the display 997 | 998 | @param x The 0-based x location of the rectangle's upper left corner 999 | @param y The 0-based y location of the rectangle's upper left corner 1000 | @param w The size in pixels of the rectangle's width 1001 | @param h The size in pixels of the rectangle's height 1002 | @param r The radius of the curves in the corners of the rectangle 1003 | @param color The RGB565 color to use when drawing the pixel 1004 | */ 1005 | /**************************************************************************/ 1006 | void Adafruit_RA8875::drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, 1007 | int16_t r, uint16_t color) { 1008 | roundRectHelper(x, y, x + w, y + h, r, color, false); 1009 | } 1010 | 1011 | /**************************************************************************/ 1012 | /*! 1013 | Draws a HW accelerated filled rounded rectangle on the display 1014 | 1015 | @param x The 0-based x location of the rectangle's upper left corner 1016 | @param y The 0-based y location of the rectangle's upper left corner 1017 | @param w The size in pixels of the rectangle's width 1018 | @param h The size in pixels of the rectangle's height 1019 | @param r The radius of the curves in the corners of the rectangle 1020 | @param color The RGB565 color to use when drawing the pixel 1021 | */ 1022 | /**************************************************************************/ 1023 | void Adafruit_RA8875::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, 1024 | int16_t r, uint16_t color) { 1025 | roundRectHelper(x, y, x + w, y + h, r, color, true); 1026 | } 1027 | 1028 | /**************************************************************************/ 1029 | /*! 1030 | Helper function for higher level circle drawing code 1031 | */ 1032 | /**************************************************************************/ 1033 | void Adafruit_RA8875::circleHelper(int16_t x, int16_t y, int16_t r, 1034 | uint16_t color, bool filled) { 1035 | x = applyRotationX(x); 1036 | y = applyRotationY(y); 1037 | 1038 | /* Set X */ 1039 | writeCommand(0x99); 1040 | writeData(x); 1041 | writeCommand(0x9a); 1042 | writeData(x >> 8); 1043 | 1044 | /* Set Y */ 1045 | writeCommand(0x9b); 1046 | writeData(y); 1047 | writeCommand(0x9c); 1048 | writeData(y >> 8); 1049 | 1050 | /* Set Radius */ 1051 | writeCommand(0x9d); 1052 | writeData(r); 1053 | 1054 | /* Set Color */ 1055 | writeCommand(0x63); 1056 | writeData((color & 0xf800) >> 11); 1057 | writeCommand(0x64); 1058 | writeData((color & 0x07e0) >> 5); 1059 | writeCommand(0x65); 1060 | writeData((color & 0x001f)); 1061 | 1062 | /* Draw! */ 1063 | writeCommand(RA8875_DCR); 1064 | if (filled) { 1065 | writeData(RA8875_DCR_CIRCLE_START | RA8875_DCR_FILL); 1066 | } else { 1067 | writeData(RA8875_DCR_CIRCLE_START | RA8875_DCR_NOFILL); 1068 | } 1069 | 1070 | /* Wait for the command to finish */ 1071 | waitPoll(RA8875_DCR, RA8875_DCR_CIRCLE_STATUS); 1072 | } 1073 | 1074 | /**************************************************************************/ 1075 | /*! 1076 | Helper function for higher level rectangle drawing code 1077 | */ 1078 | /**************************************************************************/ 1079 | void Adafruit_RA8875::rectHelper(int16_t x, int16_t y, int16_t w, int16_t h, 1080 | uint16_t color, bool filled) { 1081 | x = applyRotationX(x); 1082 | y = applyRotationY(y); 1083 | w = applyRotationX(w); 1084 | h = applyRotationY(h); 1085 | 1086 | /* Set X */ 1087 | writeCommand(0x91); 1088 | writeData(x); 1089 | writeCommand(0x92); 1090 | writeData(x >> 8); 1091 | 1092 | /* Set Y */ 1093 | writeCommand(0x93); 1094 | writeData(y); 1095 | writeCommand(0x94); 1096 | writeData(y >> 8); 1097 | 1098 | /* Set X1 */ 1099 | writeCommand(0x95); 1100 | writeData(w); 1101 | writeCommand(0x96); 1102 | writeData((w) >> 8); 1103 | 1104 | /* Set Y1 */ 1105 | writeCommand(0x97); 1106 | writeData(h); 1107 | writeCommand(0x98); 1108 | writeData((h) >> 8); 1109 | 1110 | /* Set Color */ 1111 | writeCommand(0x63); 1112 | writeData((color & 0xf800) >> 11); 1113 | writeCommand(0x64); 1114 | writeData((color & 0x07e0) >> 5); 1115 | writeCommand(0x65); 1116 | writeData((color & 0x001f)); 1117 | 1118 | /* Draw! */ 1119 | writeCommand(RA8875_DCR); 1120 | if (filled) { 1121 | writeData(0xB0); 1122 | } else { 1123 | writeData(0x90); 1124 | } 1125 | 1126 | /* Wait for the command to finish */ 1127 | waitPoll(RA8875_DCR, RA8875_DCR_LINESQUTRI_STATUS); 1128 | } 1129 | 1130 | /**************************************************************************/ 1131 | /*! 1132 | Helper function for higher level triangle drawing code 1133 | */ 1134 | /**************************************************************************/ 1135 | void Adafruit_RA8875::triangleHelper(int16_t x0, int16_t y0, int16_t x1, 1136 | int16_t y1, int16_t x2, int16_t y2, 1137 | uint16_t color, bool filled) { 1138 | x0 = applyRotationX(x0); 1139 | y0 = applyRotationY(y0); 1140 | x1 = applyRotationX(x1); 1141 | y1 = applyRotationY(y1); 1142 | x2 = applyRotationX(x2); 1143 | y2 = applyRotationY(y2); 1144 | 1145 | /* Set Point 0 */ 1146 | writeCommand(0x91); 1147 | writeData(x0); 1148 | writeCommand(0x92); 1149 | writeData(x0 >> 8); 1150 | writeCommand(0x93); 1151 | writeData(y0); 1152 | writeCommand(0x94); 1153 | writeData(y0 >> 8); 1154 | 1155 | /* Set Point 1 */ 1156 | writeCommand(0x95); 1157 | writeData(x1); 1158 | writeCommand(0x96); 1159 | writeData(x1 >> 8); 1160 | writeCommand(0x97); 1161 | writeData(y1); 1162 | writeCommand(0x98); 1163 | writeData(y1 >> 8); 1164 | 1165 | /* Set Point 2 */ 1166 | writeCommand(0xA9); 1167 | writeData(x2); 1168 | writeCommand(0xAA); 1169 | writeData(x2 >> 8); 1170 | writeCommand(0xAB); 1171 | writeData(y2); 1172 | writeCommand(0xAC); 1173 | writeData(y2 >> 8); 1174 | 1175 | /* Set Color */ 1176 | writeCommand(0x63); 1177 | writeData((color & 0xf800) >> 11); 1178 | writeCommand(0x64); 1179 | writeData((color & 0x07e0) >> 5); 1180 | writeCommand(0x65); 1181 | writeData((color & 0x001f)); 1182 | 1183 | /* Draw! */ 1184 | writeCommand(RA8875_DCR); 1185 | if (filled) { 1186 | writeData(0xA1); 1187 | } else { 1188 | writeData(0x81); 1189 | } 1190 | 1191 | /* Wait for the command to finish */ 1192 | waitPoll(RA8875_DCR, RA8875_DCR_LINESQUTRI_STATUS); 1193 | } 1194 | 1195 | /**************************************************************************/ 1196 | /*! 1197 | Helper function for higher level ellipse drawing code 1198 | */ 1199 | /**************************************************************************/ 1200 | void Adafruit_RA8875::ellipseHelper(int16_t xCenter, int16_t yCenter, 1201 | int16_t longAxis, int16_t shortAxis, 1202 | uint16_t color, bool filled) { 1203 | xCenter = applyRotationX(xCenter); 1204 | yCenter = applyRotationY(yCenter); 1205 | 1206 | /* Set Center Point */ 1207 | writeCommand(0xA5); 1208 | writeData(xCenter); 1209 | writeCommand(0xA6); 1210 | writeData(xCenter >> 8); 1211 | writeCommand(0xA7); 1212 | writeData(yCenter); 1213 | writeCommand(0xA8); 1214 | writeData(yCenter >> 8); 1215 | 1216 | /* Set Long and Short Axis */ 1217 | writeCommand(0xA1); 1218 | writeData(longAxis); 1219 | writeCommand(0xA2); 1220 | writeData(longAxis >> 8); 1221 | writeCommand(0xA3); 1222 | writeData(shortAxis); 1223 | writeCommand(0xA4); 1224 | writeData(shortAxis >> 8); 1225 | 1226 | /* Set Color */ 1227 | writeCommand(0x63); 1228 | writeData((color & 0xf800) >> 11); 1229 | writeCommand(0x64); 1230 | writeData((color & 0x07e0) >> 5); 1231 | writeCommand(0x65); 1232 | writeData((color & 0x001f)); 1233 | 1234 | /* Draw! */ 1235 | writeCommand(0xA0); 1236 | if (filled) { 1237 | writeData(0xC0); 1238 | } else { 1239 | writeData(0x80); 1240 | } 1241 | 1242 | /* Wait for the command to finish */ 1243 | waitPoll(RA8875_ELLIPSE, RA8875_ELLIPSE_STATUS); 1244 | } 1245 | 1246 | /**************************************************************************/ 1247 | /*! 1248 | Helper function for higher level curve drawing code 1249 | */ 1250 | /**************************************************************************/ 1251 | void Adafruit_RA8875::curveHelper(int16_t xCenter, int16_t yCenter, 1252 | int16_t longAxis, int16_t shortAxis, 1253 | uint8_t curvePart, uint16_t color, 1254 | bool filled) { 1255 | xCenter = applyRotationX(xCenter); 1256 | yCenter = applyRotationY(yCenter); 1257 | curvePart = (curvePart + _rotation) % 4; 1258 | 1259 | /* Set Center Point */ 1260 | writeCommand(0xA5); 1261 | writeData(xCenter); 1262 | writeCommand(0xA6); 1263 | writeData(xCenter >> 8); 1264 | writeCommand(0xA7); 1265 | writeData(yCenter); 1266 | writeCommand(0xA8); 1267 | writeData(yCenter >> 8); 1268 | 1269 | /* Set Long and Short Axis */ 1270 | writeCommand(0xA1); 1271 | writeData(longAxis); 1272 | writeCommand(0xA2); 1273 | writeData(longAxis >> 8); 1274 | writeCommand(0xA3); 1275 | writeData(shortAxis); 1276 | writeCommand(0xA4); 1277 | writeData(shortAxis >> 8); 1278 | 1279 | /* Set Color */ 1280 | writeCommand(0x63); 1281 | writeData((color & 0xf800) >> 11); 1282 | writeCommand(0x64); 1283 | writeData((color & 0x07e0) >> 5); 1284 | writeCommand(0x65); 1285 | writeData((color & 0x001f)); 1286 | 1287 | /* Draw! */ 1288 | writeCommand(0xA0); 1289 | if (filled) { 1290 | writeData(0xD0 | (curvePart & 0x03)); 1291 | } else { 1292 | writeData(0x90 | (curvePart & 0x03)); 1293 | } 1294 | 1295 | /* Wait for the command to finish */ 1296 | waitPoll(RA8875_ELLIPSE, RA8875_ELLIPSE_STATUS); 1297 | } 1298 | 1299 | /**************************************************************************/ 1300 | /*! 1301 | Helper function for higher level rounded rectangle drawing code 1302 | */ 1303 | /**************************************************************************/ 1304 | void Adafruit_RA8875::roundRectHelper(int16_t x, int16_t y, int16_t w, 1305 | int16_t h, int16_t r, uint16_t color, 1306 | bool filled) { 1307 | x = applyRotationX(x); 1308 | y = applyRotationY(y); 1309 | w = applyRotationX(w); 1310 | h = applyRotationY(h); 1311 | if (x > w) 1312 | swap(x, w); 1313 | if (y > h) 1314 | swap(y, h); 1315 | 1316 | /* Set X */ 1317 | writeCommand(0x91); 1318 | writeData(x); 1319 | writeCommand(0x92); 1320 | writeData(x >> 8); 1321 | 1322 | /* Set Y */ 1323 | writeCommand(0x93); 1324 | writeData(y); 1325 | writeCommand(0x94); 1326 | writeData(y >> 8); 1327 | 1328 | /* Set X1 */ 1329 | writeCommand(0x95); 1330 | writeData(w); 1331 | writeCommand(0x96); 1332 | writeData((w) >> 8); 1333 | 1334 | /* Set Y1 */ 1335 | writeCommand(0x97); 1336 | writeData(h); 1337 | writeCommand(0x98); 1338 | writeData((h) >> 8); 1339 | 1340 | writeCommand(0xA1); 1341 | writeData(r); 1342 | writeCommand(0xA2); 1343 | writeData((r) >> 8); 1344 | 1345 | writeCommand(0xA3); 1346 | writeData(r); 1347 | writeCommand(0xA4); 1348 | writeData((r) >> 8); 1349 | 1350 | /* Set Color */ 1351 | writeCommand(0x63); 1352 | writeData((color & 0xf800) >> 11); 1353 | writeCommand(0x64); 1354 | writeData((color & 0x07e0) >> 5); 1355 | writeCommand(0x65); 1356 | writeData((color & 0x001f)); 1357 | 1358 | /* Draw! */ 1359 | writeCommand(RA8875_ELLIPSE); 1360 | if (filled) { 1361 | writeData(0xE0); 1362 | } else { 1363 | writeData(0xA0); 1364 | } 1365 | 1366 | /* Wait for the command to finish */ 1367 | waitPoll(RA8875_ELLIPSE, RA8875_DCR_LINESQUTRI_STATUS); 1368 | } 1369 | /**************************************************************************/ 1370 | /*! 1371 | Set the scroll window 1372 | 1373 | @param x X position of the scroll window 1374 | @param y Y position of the scroll window 1375 | @param w Width of the Scroll Window 1376 | @param h Height of the Scroll window 1377 | @param mode Layer to Scroll 1378 | 1379 | */ 1380 | /**************************************************************************/ 1381 | void Adafruit_RA8875::setScrollWindow(int16_t x, int16_t y, int16_t w, 1382 | int16_t h, uint8_t mode) { 1383 | // Horizontal Start point of Scroll Window 1384 | writeCommand(0x38); 1385 | writeData(x); 1386 | writeCommand(0x39); 1387 | writeData(x >> 8); 1388 | 1389 | // Vertical Start Point of Scroll Window 1390 | writeCommand(0x3a); 1391 | writeData(y); 1392 | writeCommand(0x3b); 1393 | writeData(y >> 8); 1394 | 1395 | // Horizontal End Point of Scroll Window 1396 | writeCommand(0x3c); 1397 | writeData(x + w); 1398 | writeCommand(0x3d); 1399 | writeData((x + w) >> 8); 1400 | 1401 | // Vertical End Point of Scroll Window 1402 | writeCommand(0x3e); 1403 | writeData(y + h); 1404 | writeCommand(0x3f); 1405 | writeData((y + h) >> 8); 1406 | 1407 | // Scroll function setting 1408 | writeCommand(0x52); 1409 | writeData(mode); 1410 | } 1411 | 1412 | /**************************************************************************/ 1413 | /*! 1414 | Scroll in the X direction 1415 | 1416 | @param dist The distance to scroll 1417 | 1418 | */ 1419 | /**************************************************************************/ 1420 | void Adafruit_RA8875::scrollX(int16_t dist) { 1421 | writeCommand(0x24); 1422 | writeData(dist); 1423 | writeCommand(0x25); 1424 | writeData(dist >> 8); 1425 | } 1426 | 1427 | /**************************************************************************/ 1428 | /*! 1429 | Scroll in the Y direction 1430 | 1431 | @param dist The distance to scroll 1432 | 1433 | */ 1434 | /**************************************************************************/ 1435 | void Adafruit_RA8875::scrollY(int16_t dist) { 1436 | writeCommand(0x26); 1437 | writeData(dist); 1438 | writeCommand(0x27); 1439 | writeData(dist >> 8); 1440 | } 1441 | 1442 | /************************* Mid Level ***********************************/ 1443 | 1444 | /**************************************************************************/ 1445 | /*! 1446 | Set the Extra General Purpose IO Register 1447 | 1448 | @param on Whether to turn Extra General Purpose IO on or not 1449 | 1450 | */ 1451 | /**************************************************************************/ 1452 | void Adafruit_RA8875::GPIOX(boolean on) { 1453 | if (on) 1454 | writeReg(RA8875_GPIOX, 1); 1455 | else 1456 | writeReg(RA8875_GPIOX, 0); 1457 | } 1458 | 1459 | /**************************************************************************/ 1460 | /*! 1461 | Set the duty cycle of the PWM 1 Clock 1462 | 1463 | @param p The duty Cycle (0-255) 1464 | */ 1465 | /**************************************************************************/ 1466 | void Adafruit_RA8875::PWM1out(uint8_t p) { writeReg(RA8875_P1DCR, p); } 1467 | 1468 | /**************************************************************************/ 1469 | /*! 1470 | Set the duty cycle of the PWM 2 Clock 1471 | 1472 | @param p The duty Cycle (0-255) 1473 | */ 1474 | /**************************************************************************/ 1475 | void Adafruit_RA8875::PWM2out(uint8_t p) { writeReg(RA8875_P2DCR, p); } 1476 | 1477 | /**************************************************************************/ 1478 | /*! 1479 | Configure the PWM 1 Clock 1480 | 1481 | @param on Whether to enable the clock 1482 | @param clock The Clock Divider 1483 | */ 1484 | /**************************************************************************/ 1485 | void Adafruit_RA8875::PWM1config(boolean on, uint8_t clock) { 1486 | if (on) { 1487 | writeReg(RA8875_P1CR, RA8875_P1CR_ENABLE | (clock & 0xF)); 1488 | } else { 1489 | writeReg(RA8875_P1CR, RA8875_P1CR_DISABLE | (clock & 0xF)); 1490 | } 1491 | } 1492 | 1493 | /**************************************************************************/ 1494 | /*! 1495 | Configure the PWM 2 Clock 1496 | 1497 | @param on Whether to enable the clock 1498 | @param clock The Clock Divider 1499 | */ 1500 | /**************************************************************************/ 1501 | void Adafruit_RA8875::PWM2config(boolean on, uint8_t clock) { 1502 | if (on) { 1503 | writeReg(RA8875_P2CR, RA8875_P2CR_ENABLE | (clock & 0xF)); 1504 | } else { 1505 | writeReg(RA8875_P2CR, RA8875_P2CR_DISABLE | (clock & 0xF)); 1506 | } 1507 | } 1508 | 1509 | /**************************************************************************/ 1510 | /*! 1511 | Enables or disables the on-chip touch screen controller 1512 | 1513 | @param on Whether to turn touch sensing on or not 1514 | */ 1515 | /**************************************************************************/ 1516 | void Adafruit_RA8875::touchEnable(boolean on) { 1517 | uint8_t adcClk = (uint8_t)RA8875_TPCR0_ADCCLK_DIV4; 1518 | 1519 | if (_size == RA8875_800x480) // match up touch size with LCD size 1520 | adcClk = (uint8_t)RA8875_TPCR0_ADCCLK_DIV16; 1521 | 1522 | if (on) { 1523 | /* Enable Touch Panel (Reg 0x70) */ 1524 | writeReg(RA8875_TPCR0, RA8875_TPCR0_ENABLE | RA8875_TPCR0_WAIT_4096CLK | 1525 | RA8875_TPCR0_WAKEENABLE | adcClk); // 10mhz max! 1526 | /* Set Auto Mode (Reg 0x71) */ 1527 | writeReg(RA8875_TPCR1, RA8875_TPCR1_AUTO | 1528 | // RA8875_TPCR1_VREFEXT | 1529 | RA8875_TPCR1_DEBOUNCE); 1530 | /* Enable TP INT */ 1531 | writeReg(RA8875_INTC1, readReg(RA8875_INTC1) | RA8875_INTC1_TP); 1532 | } else { 1533 | /* Disable TP INT */ 1534 | writeReg(RA8875_INTC1, readReg(RA8875_INTC1) & ~RA8875_INTC1_TP); 1535 | /* Disable Touch Panel (Reg 0x70) */ 1536 | writeReg(RA8875_TPCR0, RA8875_TPCR0_DISABLE); 1537 | } 1538 | } 1539 | 1540 | /**************************************************************************/ 1541 | /*! 1542 | Checks if a touch event has occured 1543 | 1544 | @return True is a touch event has occured (reading it via 1545 | touchRead() will clear the interrupt in memory) 1546 | */ 1547 | /**************************************************************************/ 1548 | boolean Adafruit_RA8875::touched(void) { 1549 | if (readReg(RA8875_INTC2) & RA8875_INTC2_TP) 1550 | return true; 1551 | return false; 1552 | } 1553 | 1554 | /**************************************************************************/ 1555 | /*! 1556 | Reads the last touch event 1557 | 1558 | @param x Pointer to the uint16_t field to assign the raw X value 1559 | @param y Pointer to the uint16_t field to assign the raw Y value 1560 | 1561 | @return True if successful 1562 | 1563 | @note Calling this function will clear the touch panel interrupt on 1564 | the RA8875, resetting the flag used by the 'touched' function 1565 | */ 1566 | /**************************************************************************/ 1567 | boolean Adafruit_RA8875::touchRead(uint16_t *x, uint16_t *y) { 1568 | uint16_t tx, ty; 1569 | uint8_t temp; 1570 | 1571 | tx = readReg(RA8875_TPXH); 1572 | ty = readReg(RA8875_TPYH); 1573 | temp = readReg(RA8875_TPXYL); 1574 | tx <<= 2; 1575 | ty <<= 2; 1576 | tx |= temp & 0x03; // get the bottom x bits 1577 | ty |= (temp >> 2) & 0x03; // get the bottom y bits 1578 | 1579 | *x = tx; 1580 | *y = ty; 1581 | 1582 | /* Clear TP INT Status */ 1583 | writeReg(RA8875_INTC2, RA8875_INTC2_TP); 1584 | 1585 | return true; 1586 | } 1587 | 1588 | /**************************************************************************/ 1589 | /*! 1590 | Turns the display on or off 1591 | 1592 | @param on Whether to turn the display on or not 1593 | */ 1594 | /**************************************************************************/ 1595 | void Adafruit_RA8875::displayOn(boolean on) { 1596 | if (on) 1597 | writeReg(RA8875_PWRR, RA8875_PWRR_NORMAL | RA8875_PWRR_DISPON); 1598 | else 1599 | writeReg(RA8875_PWRR, RA8875_PWRR_NORMAL | RA8875_PWRR_DISPOFF); 1600 | } 1601 | 1602 | /**************************************************************************/ 1603 | /*! 1604 | Puts the display in sleep mode, or disables sleep mode if enabled 1605 | 1606 | @param sleep Whether to sleep or not 1607 | */ 1608 | /**************************************************************************/ 1609 | void Adafruit_RA8875::sleep(boolean sleep) { 1610 | if (sleep) 1611 | writeReg(RA8875_PWRR, RA8875_PWRR_DISPOFF | RA8875_PWRR_SLEEP); 1612 | else 1613 | writeReg(RA8875_PWRR, RA8875_PWRR_DISPOFF); 1614 | } 1615 | 1616 | /************************* Low Level ***********************************/ 1617 | 1618 | /**************************************************************************/ 1619 | /*! 1620 | Write data to the specified register 1621 | 1622 | @param reg Register to write to 1623 | @param val Value to write 1624 | */ 1625 | /**************************************************************************/ 1626 | void Adafruit_RA8875::writeReg(uint8_t reg, uint8_t val) { 1627 | writeCommand(reg); 1628 | writeData(val); 1629 | } 1630 | 1631 | /**************************************************************************/ 1632 | /*! 1633 | Set the register to read from 1634 | 1635 | @param reg Register to read 1636 | 1637 | @return The value 1638 | */ 1639 | /**************************************************************************/ 1640 | uint8_t Adafruit_RA8875::readReg(uint8_t reg) { 1641 | writeCommand(reg); 1642 | return readData(); 1643 | } 1644 | 1645 | /**************************************************************************/ 1646 | /*! 1647 | Write data to the current register 1648 | 1649 | @param d Data to write 1650 | */ 1651 | /**************************************************************************/ 1652 | void Adafruit_RA8875::writeData(uint8_t d) { 1653 | digitalWrite(_cs, LOW); 1654 | spi_begin(); 1655 | SPI.transfer(RA8875_DATAWRITE); 1656 | SPI.transfer(d); 1657 | spi_end(); 1658 | digitalWrite(_cs, HIGH); 1659 | } 1660 | 1661 | /**************************************************************************/ 1662 | /*! 1663 | Read the data from the current register 1664 | 1665 | @return The Value 1666 | */ 1667 | /**************************************************************************/ 1668 | uint8_t Adafruit_RA8875::readData(void) { 1669 | digitalWrite(_cs, LOW); 1670 | spi_begin(); 1671 | 1672 | SPI.transfer(RA8875_DATAREAD); 1673 | uint8_t x = SPI.transfer(0x0); 1674 | spi_end(); 1675 | 1676 | digitalWrite(_cs, HIGH); 1677 | return x; 1678 | } 1679 | 1680 | /**************************************************************************/ 1681 | /*! 1682 | Write a command to the current register 1683 | 1684 | @param d The data to write as a command 1685 | */ 1686 | /**************************************************************************/ 1687 | void Adafruit_RA8875::writeCommand(uint8_t d) { 1688 | digitalWrite(_cs, LOW); 1689 | spi_begin(); 1690 | 1691 | SPI.transfer(RA8875_CMDWRITE); 1692 | SPI.transfer(d); 1693 | spi_end(); 1694 | 1695 | digitalWrite(_cs, HIGH); 1696 | } 1697 | 1698 | /**************************************************************************/ 1699 | /*! 1700 | Read the status from the current register 1701 | 1702 | @return The value 1703 | */ 1704 | /**************************************************************************/ 1705 | uint8_t Adafruit_RA8875::readStatus(void) { 1706 | digitalWrite(_cs, LOW); 1707 | spi_begin(); 1708 | SPI.transfer(RA8875_CMDREAD); 1709 | uint8_t x = SPI.transfer(0x0); 1710 | spi_end(); 1711 | 1712 | digitalWrite(_cs, HIGH); 1713 | return x; 1714 | } 1715 | 1716 | /// @cond DISABLE 1717 | #if defined(EEPROM_SUPPORTED) 1718 | /// @endcond 1719 | /**************************************************************************/ 1720 | /*! 1721 | Read from the EEPROM location 1722 | 1723 | @param location The location of the EEPROM to read 1724 | 1725 | @return The value 1726 | */ 1727 | /**************************************************************************/ 1728 | 1729 | uint32_t Adafruit_RA8875::eepromReadS32(int location) { 1730 | uint32_t value = ((uint32_t)EEPROM.read(location)) << 24; 1731 | value = value | ((uint32_t)EEPROM.read(location + 1)) << 16; 1732 | value = value | ((uint32_t)EEPROM.read(location + 2)) << 8; 1733 | value = value | ((uint32_t)EEPROM.read(location + 3)); 1734 | return value; 1735 | } 1736 | 1737 | /**************************************************************************/ 1738 | /*! 1739 | Write to the EEPROM location 1740 | 1741 | @param location The location of the EEPROM to write to 1742 | @param value The value to write 1743 | */ 1744 | /**************************************************************************/ 1745 | void Adafruit_RA8875::eepromWriteS32(int location, int32_t value) { 1746 | EEPROM.write(location, (value >> 24) & 0xff); 1747 | EEPROM.write(location + 1, (value >> 16) & 0xff); 1748 | EEPROM.write(location + 2, (value >> 8) & 0xff); 1749 | EEPROM.write(location + 3, (value)&0xff); 1750 | } 1751 | 1752 | /**************************************************************************/ 1753 | /*! 1754 | Read Calibration Data from the EEPROM location 1755 | 1756 | @param location The location of the EEPROM to read from 1757 | @param matrixPtr The pointer to the Matrix Variable 1758 | 1759 | @return success 1760 | */ 1761 | /**************************************************************************/ 1762 | bool Adafruit_RA8875::readCalibration(int location, tsMatrix_t *matrixPtr) { 1763 | if (location + sizeof(tsMatrix_t) > EEPROMSIZE) { 1764 | return false; // readCalibration::Calibration location outside of EEPROM 1765 | // memory bound 1766 | } 1767 | if (EEPROM.read(location + CFG_EEPROM_TOUCHSCREEN_CALIBRATED) == 1) { 1768 | matrixPtr->An = eepromReadS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_AN); 1769 | matrixPtr->Bn = eepromReadS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_BN); 1770 | matrixPtr->Cn = eepromReadS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_CN); 1771 | matrixPtr->Dn = eepromReadS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_DN); 1772 | matrixPtr->En = eepromReadS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_EN); 1773 | matrixPtr->Fn = eepromReadS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_FN); 1774 | matrixPtr->Divider = 1775 | eepromReadS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_DIVIDER); 1776 | return true; 1777 | } 1778 | return false; 1779 | } 1780 | 1781 | /**************************************************************************/ 1782 | /*! 1783 | Write Calibration Data to the EEPROM location 1784 | 1785 | @param location The location of the EEPROM to write to 1786 | @param matrixPtr The pointer to the Matrix Variable 1787 | */ 1788 | /**************************************************************************/ 1789 | void Adafruit_RA8875::writeCalibration(int location, tsMatrix_t *matrixPtr) { 1790 | if (location + sizeof(tsMatrix_t) < 1791 | EEPROMSIZE) { // Check to see it calibration location outside of EEPROM 1792 | // memory bound 1793 | eepromWriteS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_AN, matrixPtr->An); 1794 | eepromWriteS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_BN, matrixPtr->Bn); 1795 | eepromWriteS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_CN, matrixPtr->Cn); 1796 | eepromWriteS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_DN, matrixPtr->Dn); 1797 | eepromWriteS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_EN, matrixPtr->En); 1798 | eepromWriteS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_FN, matrixPtr->Fn); 1799 | eepromWriteS32(location + CFG_EEPROM_TOUCHSCREEN_CAL_DIVIDER, 1800 | matrixPtr->Divider); 1801 | EEPROM.write(location + CFG_EEPROM_TOUCHSCREEN_CALIBRATED, 1); 1802 | } 1803 | } 1804 | /// @cond DISABLE 1805 | #endif 1806 | /// @endcond 1807 | --------------------------------------------------------------------------------