mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-27 19:57:38 +00:00
846 lines
39 KiB
C++
846 lines
39 KiB
C++
/*!
|
|
* @file Adafruit_ILI9341.cpp
|
|
*
|
|
* @mainpage Adafruit ILI9341 TFT Displays
|
|
*
|
|
* @section intro_sec Introduction
|
|
*
|
|
* This is the documentation for Adafruit's ILI9341 driver for the
|
|
* Arduino platform.
|
|
*
|
|
* This library works with the Adafruit 2.8" Touch Shield V2 (SPI)
|
|
* http://www.adafruit.com/products/1651
|
|
*
|
|
* Adafruit 2.4" TFT LCD with Touchscreen Breakout w/MicroSD Socket - ILI9341
|
|
* https://www.adafruit.com/product/2478
|
|
*
|
|
* 2.8" TFT LCD with Touchscreen Breakout Board w/MicroSD Socket - ILI9341
|
|
* https://www.adafruit.com/product/1770
|
|
*
|
|
* 2.2" 18-bit color TFT LCD display with microSD card breakout - ILI9340
|
|
* https://www.adafruit.com/product/1770
|
|
*
|
|
* TFT FeatherWing - 2.4" 320x240 Touchscreen For All Feathers
|
|
* https://www.adafruit.com/product/3315
|
|
*
|
|
* These displays use SPI to communicate, 4 or 5 pins are required
|
|
* to interface (RST is optional).
|
|
*
|
|
* Adafruit invests time and resources providing this open source code,
|
|
* please support Adafruit and open-source hardware by purchasing
|
|
* products from Adafruit!
|
|
*
|
|
* @section dependencies Dependencies
|
|
*
|
|
* This library depends on <a href="https://github.com/adafruit/Adafruit_GFX">
|
|
* Adafruit_GFX</a> being present on your system. Please make sure you have
|
|
* installed the latest version before using this library.
|
|
*
|
|
* @section author Author
|
|
*
|
|
* Written by Limor "ladyada" Fried for Adafruit Industries.
|
|
*
|
|
* @section license License
|
|
*
|
|
* BSD license, all text here must be included in any redistribution.
|
|
*
|
|
*/
|
|
|
|
#include "Adafruit_ILI9341.h"
|
|
#ifndef ARDUINO_STM32_FEATHER
|
|
# include "pins_arduino.h"
|
|
# ifndef RASPI
|
|
# include "wiring_private.h"
|
|
# endif // ifndef RASPI
|
|
#endif // ifndef ARDUINO_STM32_FEATHER
|
|
#include <limits.h>
|
|
|
|
#if defined(ARDUINO_ARCH_ARC32) || defined(ARDUINO_MAXIM)
|
|
# define SPI_DEFAULT_FREQ 16000000
|
|
|
|
// Teensy 3.0, 3.1/3.2, 3.5, 3.6
|
|
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || \
|
|
defined(__MK64FX512__) || defined(__MK66FX1M0__)
|
|
# define SPI_DEFAULT_FREQ 40000000
|
|
#elif defined(__AVR__) || defined(TEENSYDUINO)
|
|
# define SPI_DEFAULT_FREQ 8000000
|
|
#elif defined(ESP8266) || defined(ESP32)
|
|
# define SPI_DEFAULT_FREQ 40000000
|
|
#elif defined(RASPI)
|
|
# define SPI_DEFAULT_FREQ 80000000
|
|
#elif defined(ARDUINO_ARCH_STM32F1)
|
|
# define SPI_DEFAULT_FREQ 36000000
|
|
#else // if defined(ARDUINO_ARCH_ARC32) || defined(ARDUINO_MAXIM)
|
|
# define SPI_DEFAULT_FREQ 24000000 ///< Default SPI data clock frequency
|
|
#endif // if defined(ARDUINO_ARCH_ARC32) || defined(ARDUINO_MAXIM)
|
|
|
|
#define MADCTL_MY 0x80 ///< Bottom to top
|
|
#define MADCTL_MX 0x40 ///< Right to left
|
|
#define MADCTL_MV 0x20 ///< Reverse Mode
|
|
#define MADCTL_ML 0x10 ///< LCD refresh Bottom to top
|
|
#define MADCTL_RGB 0x00 ///< Red-Green-Blue pixel order
|
|
#define MADCTL_BGR 0x08 ///< Blue-Green-Red pixel order
|
|
#define MADCTL_MH 0x04 ///< LCD refresh right to left
|
|
#define MADCTL_SS 0x02 ///< ?? ILI9481 mode
|
|
#define MADCTL_GS 0x01 ///< ?? ILI9481 mode
|
|
|
|
/**************************************************************************/
|
|
|
|
/*!
|
|
@brief Instantiate Adafruit ILI9341 driver with software SPI
|
|
@param cs Chip select pin #
|
|
@param dc Data/Command pin #
|
|
@param mosi SPI MOSI pin #
|
|
@param sclk SPI Clock pin #
|
|
@param rst Reset pin # (optional, pass -1 if unused)
|
|
@param miso SPI MISO pin # (optional, pass -1 if unused)
|
|
*/
|
|
|
|
/**************************************************************************/
|
|
|
|
// Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t mosi,
|
|
// int8_t sclk, int8_t rst, int8_t miso)
|
|
// : Adafruit_SPITFT(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT, cs, dc, mosi, sclk,
|
|
// rst, miso) {}
|
|
|
|
/**************************************************************************/
|
|
|
|
/*!
|
|
@brief Instantiate Adafruit ILI9341 driver with hardware SPI using the
|
|
default SPI peripheral.
|
|
@param cs Chip select pin # (OK to pass -1 if CS tied to GND).
|
|
@param dc Data/Command pin # (required).
|
|
@param rst Reset pin # (optional, pass -1 if unused).
|
|
@param model The display model to initiailize.
|
|
@param w Widht of the display in pixels.
|
|
@param h Height of the display in pixels.
|
|
*/
|
|
|
|
/**************************************************************************/
|
|
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t rst, uint8_t model, uint16_t w, uint16_t h)
|
|
: Adafruit_SPITFT(w, h, cs, dc, rst) {
|
|
_model = model;
|
|
_w = w;
|
|
_h = h;
|
|
}
|
|
|
|
#if !defined(ESP8266)
|
|
|
|
/**************************************************************************/
|
|
|
|
/*!
|
|
@brief Instantiate Adafruit ILI9341 driver with hardware SPI using
|
|
a specific SPI peripheral (not necessarily default).
|
|
@param spiClass Pointer to SPI peripheral (e.g. &SPI or &SPI1).
|
|
@param dc Data/Command pin # (required).
|
|
@param cs Chip select pin # (optional, pass -1 if unused and
|
|
CS is tied to GND).
|
|
@param rst Reset pin # (optional, pass -1 if unused).
|
|
@param model The display model to initiailize.
|
|
@param w Widht of the display in pixels.
|
|
@param h Height of the display in pixels.
|
|
*/
|
|
|
|
/**************************************************************************/
|
|
|
|
Adafruit_ILI9341::Adafruit_ILI9341(SPIClass *spiClass, int8_t dc, int8_t cs,
|
|
int8_t rst, uint8_t model, uint16_t w, uint16_t h)
|
|
: Adafruit_SPITFT(w, h, spiClass, cs, dc, rst) {
|
|
_model = model;
|
|
_w = w;
|
|
_h = h;
|
|
}
|
|
#endif // end !ESP8266
|
|
|
|
/**************************************************************************/
|
|
|
|
/*!
|
|
@brief Instantiate Adafruit ILI9341 driver using parallel interface.
|
|
@param busWidth If tft16 (enumeration in Adafruit_SPITFT.h), is a
|
|
16-bit interface, else 8-bit.
|
|
@param d0 Data pin 0 (MUST be a byte- or word-aligned LSB of a
|
|
PORT register -- pins 1-n are extrapolated from this).
|
|
@param wr Write strobe pin # (required).
|
|
@param dc Data/Command pin # (required).
|
|
@param cs Chip select pin # (optional, pass -1 if unused and CS
|
|
is tied to GND).
|
|
@param rst Reset pin # (optional, pass -1 if unused).
|
|
@param rd Read strobe pin # (optional, pass -1 if unused).
|
|
*/
|
|
|
|
/**************************************************************************/
|
|
|
|
// Adafruit_ILI9341::Adafruit_ILI9341(tftBusWidth busWidth, int8_t d0, int8_t wr,
|
|
// int8_t dc, int8_t cs, int8_t rst, int8_t rd)
|
|
// : Adafruit_SPITFT(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT, busWidth, d0, wr, dc,
|
|
// cs, rst, rd) {}
|
|
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd[] = { // ILI9341 & ILI9340
|
|
0xEF, 3, 0x03, 0x80, 0x02,
|
|
0xCF, 3, 0x00, 0xC1, 0x30,
|
|
0xED, 4, 0x64, 0x03, 0x12, 0x81,
|
|
0xE8, 3, 0x85, 0x00, 0x78,
|
|
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
|
0xF7, 1, 0x20,
|
|
0xEA, 2, 0x00, 0x00,
|
|
ILI9341_PWCTR1, 1, 0x23, // Power control VRH[5:0]
|
|
ILI9341_PWCTR2, 1, 0x10, // Power control SAP[2:0];BT[3:0]
|
|
ILI9341_VMCTR1, 2, 0x3e, 0x28, // VCM control
|
|
ILI9341_VMCTR2, 1, 0x86, // VCM control2
|
|
ILI9341_MADCTL, 1, (MADCTL_MX | MADCTL_BGR), // Memory Access Control
|
|
ILI9341_VSCRSADD, 1, 0x00, // Vertical scroll zero
|
|
ILI9341_PIXFMT, 1, 0x55,
|
|
ILI9341_FRMCTR1, 2, 0x00, 0x18,
|
|
ILI9341_DFUNCTR, 3, 0x08, 0x82, 0x27, // Display Function Control
|
|
0xF2, 1, 0x00, // 3Gamma Function Disable
|
|
ILI9341_GAMMASET, 1, 0x01, // Gamma curve selected
|
|
ILI9341_GMCTRP1, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E,
|
|
0x08,
|
|
0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E,
|
|
0x09, 0x00, // Set Gamma
|
|
ILI9341_GMCTRN1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11,
|
|
0x07,
|
|
0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31,
|
|
0x36, 0x0F, // Set Gamma
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd_9342[] = { // ILI9342
|
|
0xEF, 3, 0x03, 0x80, 0x02,
|
|
0xCF, 3, 0x00, 0xC1, 0x30,
|
|
0xED, 4, 0x64, 0x03, 0x12, 0x81,
|
|
0xE8, 3, 0x85, 0x00, 0x78,
|
|
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
|
0xF7, 1, 0x20,
|
|
0xEA, 2, 0x00, 0x00,
|
|
ILI9341_PWCTR1, 1, 0x23, // Power control VRH[5:0]
|
|
ILI9341_PWCTR2, 1, 0x10, // Power control SAP[2:0];BT[3:0]
|
|
ILI9341_VMCTR1, 2, 0x3e, 0x28, // VCM control
|
|
ILI9341_VMCTR2, 1, 0x86, // VCM control2
|
|
ILI9341_MADCTL, 1, (MADCTL_MY | MADCTL_MV | MADCTL_BGR), // Memory Access Control
|
|
ILI9341_VSCRSADD, 1, 0x00, // Vertical scroll zero
|
|
ILI9341_PIXFMT, 1, 0x55,
|
|
ILI9341_FRMCTR1, 2, 0x00, 0x18,
|
|
ILI9341_DFUNCTR, 3, 0x08, 0x82, 0x27, // Display Function Control
|
|
0xF2, 1, 0x00, // 3Gamma Function Disable
|
|
ILI9341_GAMMASET, 1, 0x01, // Gamma curve selected
|
|
ILI9341_GMCTRP1, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E,
|
|
0x08,
|
|
0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E,
|
|
0x09, 0x00, //
|
|
// Set
|
|
// Gamma
|
|
ILI9341_GMCTRN1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11,
|
|
0x07,
|
|
0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31,
|
|
0x36, 0x0F, // Set Gamma
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
#ifdef ESP32
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd_9342_2[] = { // ILI9342_2 (CYD/Adafruit)
|
|
0xEF, 3, 0x03, 0x80, 0x02,
|
|
0xCF, 3, 0x00, 0xC1, 0x30,
|
|
0xED, 4, 0x64, 0x03, 0x12, 0x81,
|
|
0xE8, 3, 0x85, 0x00, 0x78,
|
|
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
|
0xF7, 1, 0x20,
|
|
0xEA, 2, 0x00, 0x00,
|
|
ILI9341_PWCTR1, 1, 0x23, // Power control VRH[5:0]
|
|
ILI9341_PWCTR2, 1, 0x10, // Power control SAP[2:0];BT[3:0]
|
|
ILI9341_VMCTR1, 2, 0x2B, 0x2B, // VCM control
|
|
ILI9341_VMCTR2, 1, 0xC0, // VCM control2
|
|
ILI9341_MADCTL, 1, (MADCTL_MX | MADCTL_BGR), // Memory Access Control
|
|
ILI9341_VSCRSADD, 1, 0x00, // Vertical scroll zero
|
|
ILI9341_PIXFMT, 1, 0x55,
|
|
ILI9341_FRMCTR1, 2, 0x00, 0x1B,
|
|
ILI9341_DFUNCTR, 3, 0x08, 0x82, 0x27, // Display Function Control
|
|
0xF2, 1, 0x00, // 3Gamma Function Disable
|
|
ILI9341_GAMMASET, 1, 0x01, // Gamma curve selected
|
|
ILI9341_GMCTRP1, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E,
|
|
0x08,
|
|
0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E,
|
|
0x09, 0x00, //
|
|
// Set
|
|
// Gamma
|
|
ILI9341_GMCTRN1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11,
|
|
0x07,
|
|
0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31,
|
|
0x36, 0x0F, // Set Gamma
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd_9342_3[] = { // ILI9342_3 (CYD/Bodmer)
|
|
0xEF, 3, 0x03, 0x80, 0x02,
|
|
0xCF, 3, 0x00, 0xC1, 0x30,
|
|
0xED, 4, 0x64, 0x03, 0x12, 0x81,
|
|
0xE8, 3, 0x85, 0x00, 0x78,
|
|
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
|
0xF7, 1, 0x20,
|
|
0xEA, 2, 0x00, 0x00,
|
|
ILI9341_PWCTR1, 1, 0x10, // Power control VRH[5:0]
|
|
ILI9341_PWCTR2, 1, 0x00, // Power control SAP[2:0];BT[3:0]
|
|
ILI9341_VMCTR1, 2, 0x30, 0x30, // VCM control
|
|
ILI9341_VMCTR2, 1, 0xB7, // VCM control2
|
|
ILI9341_MADCTL, 1, (MADCTL_BGR), // Memory Access Control
|
|
// ILI9341_VSCRSADD, 1, 0x00, // Vertical scroll zero
|
|
ILI9341_PIXFMT, 1, 0x55,
|
|
ILI9341_FRMCTR1, 2, 0x00, 0x1A,
|
|
ILI9341_DFUNCTR, 3, 0x08, 0x82, 0x27, // Display Function Control
|
|
0xF2, 1, 0x00, // 3Gamma Function Disable
|
|
ILI9341_GAMMASET, 1, 0x01, // Gamma curve selected
|
|
ILI9341_GMCTRP1, 15, 0x0F, 0x2A, 0x28, 0x08, 0x0E,
|
|
0x08,
|
|
0x54, 0xA9, 0x43, 0x0A, 0x0F, 0x00, 0x00,
|
|
0x00, 0x00, //
|
|
// Set
|
|
// Gamma
|
|
ILI9341_GMCTRN1, 15, 0x00, 0x15, 0x17, 0x07, 0x11,
|
|
0x06,
|
|
0x2B, 0x56, 0x3C, 0x05, 0x10, 0x0F, 0x3F,
|
|
0x3F, 0x0F, // Set Gamma
|
|
ILI9341_PASET, 4, 0x00, 0x00, 0x01, 0x3F,
|
|
ILI9341_CASET, 4, 0x00, 0x00, 0x00, 0xEF,
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
#endif // ifdef ESP32
|
|
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd_9481[] = { // ILI9481
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
0xD0, 3, 0x07, 0x42, 0x18,
|
|
0xD1, 3, 0x00, 0x07, 0x10,
|
|
0xD2, 2, 0x01, 0x02,
|
|
ILI9341_PWCTR1, 5, 0x10, 0x3B, 0x00, 0x02, 0x11, // Power control VRH[5:0]
|
|
ILI9341_VMCTR1, 1, 0x03, // VCM control
|
|
0xC8, 12, 0x00, 0x32, 0x36, 0x45, 0x06, 0x16, 0x37,
|
|
0x75, 0x77, 0x54, 0x0C, 0x00,
|
|
ILI9341_MADCTL, 1, 0x0A, // Memory Access Control
|
|
ILI9341_PIXFMT, 1, 0x55, // Pixel format
|
|
// 0x55=16bit, 0x66=18bit
|
|
ILI9341_INVON, 0,
|
|
ILI9341_CASET, 4, 0x00, 0x00, 0x01, 0x3F,
|
|
ILI9341_PASET, 0x84, 0x00, 0x00, 0x01, 0xDF,
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd_9481_CPT29[] = { // ILI9481 CPT29 variation
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
0xD0, 3, 0x07, 0x41, 0x1D,
|
|
0xD1, 3, 0x00, 0x2b, 0x1f,
|
|
0xD2, 2, 0x01, 0x11,
|
|
ILI9341_PWCTR1, 5, 0x10, 0x3B, 0x00, 0x02, 0x11, // Power control VRH[5:0]
|
|
ILI9341_VMCTR1, 1, 0x03, // VCM control
|
|
0xC8, 12, 0x00, 0x14, 0x33, 0x10, 0x00, 0x16, 0x44,
|
|
0x36, 0x77, 0x00, 0x0F, 0x00,
|
|
0xB0, 1, 0x00,
|
|
0xE4, 1, 0xA0,
|
|
0xF0, 1, 0x01,
|
|
0xF3, 2, 0x02, 0x1A,
|
|
ILI9341_MADCTL, 1, 0x0A, // Memory Access Control
|
|
ILI9341_PIXFMT, 1, 0x55, // Pixel format 0x55=16bit,
|
|
// 0x66=18bit
|
|
ILI9341_INVON, 0,
|
|
ILI9341_CASET, 4, 0x00, 0x00, 0x01, 0x3F,
|
|
ILI9341_PASET, 0x84, 0x00, 0x00, 0x01, 0xDF,
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd_9481_PVI35[] = { // ILI9481 PVI35 variation
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
0xD0, 3, 0x07, 0x41, 0x1D,
|
|
0xD1, 3, 0x00, 0x2b, 0x1f,
|
|
0xD2, 2, 0x01, 0x11,
|
|
ILI9341_PWCTR1, 5, 0x10, 0x3B, 0x00, 0x02, 0x11, // Power control VRH[5:0]
|
|
ILI9341_VMCTR1, 1, 0x03, // VCM control
|
|
0xC8, 12, 0x00, 0x14, 0x33, 0x10, 0x00, 0x16, 0x44,
|
|
0x36, 0x77, 0x00, 0x0F, 0x00,
|
|
0xB0, 1, 0x00,
|
|
0xE4, 1, 0xA0,
|
|
0xF0, 1, 0x01,
|
|
0xF3, 2, 0x40, 0x0A,
|
|
ILI9341_MADCTL, 1, 0x0A, // Memory Access Control
|
|
ILI9341_PIXFMT, 1, 0x55, // Pixel format 0x55=16bit,
|
|
// 0x66=18bit
|
|
ILI9341_INVON, 0,
|
|
ILI9341_CASET, 4, 0x00, 0x00, 0x01, 0x3F,
|
|
ILI9341_PASET, 0x84, 0x00, 0x00, 0x01, 0xDF,
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd_9481_AUO317[] = { // ILI9481 AUO317 variation
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
0xD0, 3, 0x07, 0x40, 0x1D,
|
|
0xD1, 3, 0x00, 0x18, 0x13,
|
|
0xD2, 2, 0x01, 0x11,
|
|
ILI9341_PWCTR1, 5, 0x10, 0x3B, 0x00, 0x02, 0x11, // Power control VRH[5:0]
|
|
ILI9341_VMCTR1, 1, 0x03, // VCM control
|
|
0xC8, 12, 0x00, 0x44, 0x06, 0x44, 0x0A, 0x08, 0x17,
|
|
0x33, 0x77, 0x44, 0x08, 0x0C,
|
|
0xB0, 1, 0x00,
|
|
0xE4, 1, 0xA0,
|
|
0xF0, 1, 0x01,
|
|
ILI9341_MADCTL, 1, 0x0A, // Memory Access Control
|
|
ILI9341_PIXFMT, 1, 0x55, // Pixel format 0x55=16bit,
|
|
// 0x66=18bit
|
|
ILI9341_INVON, 0,
|
|
ILI9341_CASET, 4, 0x00, 0x00, 0x01, 0x3F,
|
|
ILI9341_PASET, 0x84, 0x00, 0x00, 0x01, 0xDF,
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd_9481_CM35[] = { // ILI9481 CMO36 variation
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
0xD0, 3, 0x07, 0x41, 0x1D,
|
|
0xD1, 3, 0x00, 0x1C, 0x1F,
|
|
0xD2, 2, 0x01, 0x11,
|
|
ILI9341_PWCTR1, 5, 0x10, 0x3B, 0x00, 0x02, 0x11, // Power control VRH[5:0]
|
|
ILI9341_VMCTR1, 1, 0x03, // VCM control
|
|
0xC6, 1, 0x83,
|
|
0xC8, 12, 0x00, 0x26, 0x21, 0x00, 0x00, 0x1F, 0x65,
|
|
0x23, 0x77, 0x00, 0x0F, 0x00,
|
|
0xB0, 1, 0x00,
|
|
0xE4, 1, 0xA0,
|
|
0xF0, 1, 0x01,
|
|
ILI9341_MADCTL, 1, 0x0A, // Memory Access Control
|
|
ILI9341_PIXFMT, 1, 0x55, // Pixel format 0x55=16bit, 0x66=18bit
|
|
ILI9341_INVON, 0,
|
|
ILI9341_CASET, 4, 0x00, 0x00, 0x01, 0x3F,
|
|
ILI9341_PASET, 0x84, 0x00, 0x00, 0x01, 0xDF,
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd_9481_RGB[] = { // ILI9481 RGB variation
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
0xD0, 3, 0x07, 0x41, 0x1D,
|
|
0xD1, 3, 0x00, 0x2B, 0x1F,
|
|
0xD2, 2, 0x01, 0x11,
|
|
ILI9341_PWCTR1, 6, 0x10, 0x3B, 0x00, 0x02, 0x11,
|
|
0x00, // Power control VRH[5:0]
|
|
ILI9341_VMCTR1, 1, 0x03, // VCM control
|
|
0xC6, 1, 0x80,
|
|
0xC8, 12, 0x00, 0x14, 0x33, 0x10, 0x00,
|
|
0x16,
|
|
0x44,
|
|
0x36, 0x77, 0x00, 0x0F, 0x00,
|
|
0xB0, 1, 0x00,
|
|
0xE4, 1, 0xA0,
|
|
0xF0, 1, 0x08,
|
|
0xF3, 2, 0x40, 0x0A,
|
|
0xF6, 1, 0x84,
|
|
0xF7, 1, 0x80,
|
|
ILI9341_FRMCTR3, 4, 0x00, 0x01, 0x06, 0x30,
|
|
ILI9341_INVCTR, 1, 0x00,
|
|
ILI9341_RDPIXFMT, 2, 0x00, 0x55,
|
|
ILI9341_MADCTL, 1, 0x0A, // Memory Access Control
|
|
ILI9341_PIXFMT, 1, 0x55, // Pixel format 0x55=16bit, 0x66=18bit
|
|
ILI9341_INVON, 0,
|
|
ILI9341_CASET, 4, 0x00, 0x00, 0x01, 0x3F,
|
|
ILI9341_PASET, 0x84, 0x00, 0x00, 0x01, 0xDF,
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd_9481_CMI7[] = { // ILI9481 CMI7 (TFT_eSPI INIT_7) variation
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
0xD0, 3, 0x07, 0x42, 0x1B,
|
|
0xD1, 3, 0x00, 0x14, 0x1B,
|
|
0xD2, 2, 0x01, 0x12,
|
|
ILI9341_PWCTR1, 5, 0x10, 0x3B, 0x00, 0x02, 0x01, // Power control VRH[5:0]
|
|
ILI9341_VMCTR1, 1, 0x03, // VCM control
|
|
0xC8, 12, 0x00, 0x46, 0x44, 0x50, 0x04, 0x16, 0x33,
|
|
0x13, 0x77, 0x05, 0x0F, 0x00,
|
|
ILI9341_MADCTL, 1, 0x0A, // Memory Access Control
|
|
ILI9341_PIXFMT, 1, 0x55, // Pixel format
|
|
// 0x55=16bit,
|
|
// 0x66=18bit
|
|
ILI9341_INVON, 0,
|
|
0x22, 4, 0x00, 0x00, 0x01, 0x3F,
|
|
ILI9341_PASET, 0x84, 0x00, 0x00, 0x01, 0xE0,
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
// clang-format off
|
|
static const uint8_t PROGMEM initcmd_9481_CMI8[] = { // ILI9481 CMI8 (TFT_eSPI INIT_8) variation
|
|
ILI9341_SLPOUT, 0x80, // Exit Sleep
|
|
0xD0, 0x83, 0x07, 0x44, 0x1E,
|
|
0xD1, 3, 0x00, 0x0C, 0x1A,
|
|
ILI9341_VMCTR1, 1, 0x03, // VCM control
|
|
0xD2, 2, 0x01, 0x11,
|
|
0xE4, 1, 0xA0,
|
|
0xF3, 2, 0x00, 0x2A,
|
|
0xC8, 12, 0x00, 0x26, 0x21, 0x00, 0x00, 0x1F,
|
|
0x65,
|
|
0x23, 0x77, 0x00, 0x0F, 0x00,
|
|
ILI9341_PWCTR1, 5, 0x00, 0x3B, 0x00, 0x02, 0x11, // Power control VRH[5:0]
|
|
0xC6, 1, 0x83,
|
|
0xF0, 1, 0x01,
|
|
0xE4, 1, 0xA0,
|
|
ILI9341_MADCTL, 1, 0x0A, // Memory Access Control
|
|
ILI9341_PIXFMT, 1, 0x55, // Pixel format 0x55=16bit,
|
|
// 0x66=18bit
|
|
ILI9341_INVCTR, 0x84, 0x02, 0x00, 0x00, 0x01,
|
|
ILI9341_CASET, 4, 0x00, 0x00, 0x01, 0x3F,
|
|
ILI9341_PASET, 4, 0x00, 0x00, 0x01, 0xDF,
|
|
ILI9341_DISPON, 0x80, // Display on
|
|
ILI9341_RAMWR, 0,
|
|
0x00 // End of list
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
/**************************************************************************/
|
|
|
|
/*!
|
|
@brief Initialize ILI9341 chip
|
|
Connects to the ILI9341 over SPI and sends initialization procedure commands
|
|
@param freq Desired SPI clock frequency
|
|
*/
|
|
|
|
/**************************************************************************/
|
|
void Adafruit_ILI9341::begin(uint32_t freq) {
|
|
if (!freq) {
|
|
freq = SPI_DEFAULT_FREQ;
|
|
}
|
|
initSPI(freq);
|
|
|
|
if (_rst < 0) { // If no hardware reset pin...
|
|
sendCommand(ILI9341_SWRESET); // Engage software reset
|
|
delay(150);
|
|
}
|
|
|
|
uint8_t cmd, x, numArgs;
|
|
const uint8_t *addr; // = initcmd;
|
|
|
|
switch (_model) {
|
|
case ILI_TYPE_9341: // ILI9341
|
|
addr = initcmd;
|
|
break;
|
|
case ILI_TYPE_9342: // ILI9342 M5STACK
|
|
addr = initcmd_9342;
|
|
break;
|
|
#ifdef ESP32
|
|
case ILI_TYPE_9342_2: // ILI9342 CYD/Adafruit
|
|
addr = initcmd_9342_2;
|
|
break;
|
|
case ILI_TYPE_9342_3: // ILI9342 CYD/Bodmer
|
|
addr = initcmd_9342_3;
|
|
break;
|
|
#endif // ifdef ESP32
|
|
case ILI_TYPE_9481: // ILI9481
|
|
addr = initcmd_9481;
|
|
break;
|
|
case ILI_TYPE_9481_CPT29: // ILI9481 CPT29
|
|
addr = initcmd_9481_CPT29;
|
|
break;
|
|
case ILI_TYPE_9481_PVI35: // ILI9481 PVI35
|
|
addr = initcmd_9481_PVI35;
|
|
break;
|
|
case ILI_TYPE_9481_AUO317: // ILI9481 AUO317
|
|
addr = initcmd_9481_AUO317;
|
|
break;
|
|
case ILI_TYPE_9481_CMO35: // ILI9481 CMO35
|
|
addr = initcmd_9481_CM35;
|
|
break;
|
|
case ILI_TYPE_9481_RGB: // ILI9481 RGB
|
|
addr = initcmd_9481_RGB;
|
|
break;
|
|
case ILI_TYPE_9481_CMI7: // ILI9481 CMI7
|
|
addr = initcmd_9481_CMI7;
|
|
break;
|
|
case ILI_TYPE_9481_CMI8: // ILI9481 CMI8
|
|
addr = initcmd_9481_CMI8;
|
|
break;
|
|
default:
|
|
addr = initcmd;
|
|
break;
|
|
}
|
|
|
|
while ((cmd = pgm_read_byte(addr++)) > 0) {
|
|
x = pgm_read_byte(addr++);
|
|
numArgs = x & 0x7F;
|
|
sendCommand(cmd, addr, numArgs);
|
|
addr += numArgs;
|
|
|
|
if (x & 0x80) {
|
|
delay(150);
|
|
}
|
|
}
|
|
|
|
_width = _w;
|
|
_height = _h;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
/*!
|
|
@brief Set origin of (0,0) and orientation of TFT display
|
|
@param m The index for rotation, from 0-3 inclusive
|
|
*/
|
|
|
|
/**************************************************************************/
|
|
void Adafruit_ILI9341::setRotation(uint8_t m) {
|
|
rotation = m % 4; // can't be higher than 3
|
|
|
|
switch (rotation) {
|
|
case 0:
|
|
|
|
switch (_model) {
|
|
case ILI_TYPE_9342: // ILI9342 M5STACK
|
|
m = (MADCTL_MY | MADCTL_MV | MADCTL_BGR);
|
|
break;
|
|
case ILI_TYPE_9342_2: // ILI9342 CYD/Adafruit
|
|
m = (MADCTL_BGR);
|
|
break;
|
|
case ILI_TYPE_9481: // ILI9481
|
|
case ILI_TYPE_9481_CPT29: // ILI9481 CPT29
|
|
case ILI_TYPE_9481_PVI35: // ILI9481 PVI35
|
|
case ILI_TYPE_9481_AUO317: // ILI9481 AUO317
|
|
case ILI_TYPE_9481_CMO35: // ILI9481 CMO35
|
|
case ILI_TYPE_9481_RGB: // ILI9481 RGB
|
|
case ILI_TYPE_9481_CMI7: // ILI9481 CMI7
|
|
case ILI_TYPE_9481_CMI8: // ILI9481 CMI8
|
|
m = (MADCTL_SS | MADCTL_BGR);
|
|
break;
|
|
case ILI_TYPE_9341: // ILI9341
|
|
case ILI_TYPE_9342_3: // ILI9342 CYD/Bodmer
|
|
// m = (MADCTL_MX | MADCTL_BGR);
|
|
// break;
|
|
default:
|
|
m = (MADCTL_MX | MADCTL_BGR);
|
|
break;
|
|
}
|
|
_width = _w;
|
|
_height = _h;
|
|
break;
|
|
case 1:
|
|
|
|
switch (_model) {
|
|
case ILI_TYPE_9342: // ILI9342 M5STACK
|
|
m = (MADCTL_BGR);
|
|
break;
|
|
case ILI_TYPE_9481: // ILI9481
|
|
case ILI_TYPE_9481_CPT29: // ILI9481 CPT29
|
|
case ILI_TYPE_9481_PVI35: // ILI9481 PVI35
|
|
case ILI_TYPE_9481_AUO317: // ILI9481 AUO317
|
|
case ILI_TYPE_9481_CMO35: // ILI9481 CMO35
|
|
case ILI_TYPE_9481_RGB: // ILI9481 RGB
|
|
case ILI_TYPE_9481_CMI7: // ILI9481 CMI7
|
|
case ILI_TYPE_9481_CMI8: // ILI9481 CMI8
|
|
// m = (MADCTL_MV | MADCTL_BGR);
|
|
// break;
|
|
case ILI_TYPE_9341: // ILI9341
|
|
case ILI_TYPE_9342_2: // ILI9342 CYD/Adafruit
|
|
case ILI_TYPE_9342_3: // ILI9342 CYD/Bodmer
|
|
// m = (MADCTL_MV | MADCTL_BGR);
|
|
// break;
|
|
default:
|
|
m = (MADCTL_MV | MADCTL_BGR);
|
|
break;
|
|
}
|
|
_width = _h;
|
|
_height = _w;
|
|
break;
|
|
case 2:
|
|
|
|
switch (_model) {
|
|
case ILI_TYPE_9342: // ILI9342 M5STACK
|
|
m = (MADCTL_MV | MADCTL_MX | MADCTL_BGR);
|
|
break;
|
|
case ILI_TYPE_9481: // ILI9481
|
|
case ILI_TYPE_9481_CPT29: // ILI9481 CPT29
|
|
case ILI_TYPE_9481_PVI35: // ILI9481 PVI35
|
|
case ILI_TYPE_9481_AUO317: // ILI9481 AUO317
|
|
case ILI_TYPE_9481_CMO35: // ILI9481 CMO35
|
|
case ILI_TYPE_9481_RGB: // ILI9481 RGB
|
|
case ILI_TYPE_9481_CMI7: // ILI9481 CMI7
|
|
case ILI_TYPE_9481_CMI8: // ILI9481 CMI8
|
|
m = (MADCTL_GS | MADCTL_BGR);
|
|
break;
|
|
case ILI_TYPE_9341: // ILI9341
|
|
case ILI_TYPE_9342_2: // ILI9342 CYD/Adafruit
|
|
case ILI_TYPE_9342_3: // ILI9342 CYD/Bodmer
|
|
// m = (MADCTL_MY | MADCTL_BGR);
|
|
// break;
|
|
default:
|
|
m = (MADCTL_MY | MADCTL_BGR);
|
|
break;
|
|
}
|
|
_width = _w;
|
|
_height = _h;
|
|
break;
|
|
case 3:
|
|
|
|
switch (_model) {
|
|
case ILI_TYPE_9342: // ILI9342 M5STACK
|
|
m = (MADCTL_MX | MADCTL_MY | MADCTL_BGR);
|
|
break;
|
|
case ILI_TYPE_9481: // ILI9481
|
|
case ILI_TYPE_9481_CPT29: // ILI9481 CPT29
|
|
case ILI_TYPE_9481_PVI35: // ILI9481 PVI35
|
|
case ILI_TYPE_9481_AUO317: // ILI9481 AUO317
|
|
case ILI_TYPE_9481_CMO35: // ILI9481 CMO35
|
|
case ILI_TYPE_9481_RGB: // ILI9481 RGB
|
|
case ILI_TYPE_9481_CMI7: // ILI9481 CMI7
|
|
case ILI_TYPE_9481_CMI8: // ILI9481 CMI8
|
|
m = (MADCTL_SS | MADCTL_GS | MADCTL_MV | MADCTL_BGR);
|
|
break;
|
|
case ILI_TYPE_9341: // ILI9341
|
|
case ILI_TYPE_9342_2: // ILI9342 CYD/Adafruit
|
|
case ILI_TYPE_9342_3: // ILI9342 CYD/Bodmer
|
|
// m = (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
|
|
// break;
|
|
default:
|
|
m = (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
|
|
break;
|
|
}
|
|
_width = _h;
|
|
_height = _w;
|
|
break;
|
|
}
|
|
|
|
sendCommand(ILI9341_MADCTL, &m, 1);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
/*!
|
|
@brief Enable/Disable display color inversion
|
|
@param invert True to invert, False to have normal color
|
|
*/
|
|
|
|
/**************************************************************************/
|
|
void Adafruit_ILI9341::invertDisplay(bool invert) {
|
|
sendCommand(invert ? ILI9341_INVON : ILI9341_INVOFF);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
/*!
|
|
@brief Scroll display memory
|
|
@param y How many pixels to scroll display by
|
|
*/
|
|
|
|
/**************************************************************************/
|
|
void Adafruit_ILI9341::scrollTo(uint16_t y) {
|
|
uint8_t data[2];
|
|
|
|
data[0] = y >> 8;
|
|
data[1] = y & 0xff;
|
|
sendCommand(ILI9341_VSCRSADD, (uint8_t *)data, 2);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
/*!
|
|
@brief Set the height of the Top and Bottom Scroll Margins
|
|
@param top The height of the Top scroll margin
|
|
@param bottom The height of the Bottom scroll margin
|
|
*/
|
|
|
|
/**************************************************************************/
|
|
void Adafruit_ILI9341::setScrollMargins(uint16_t top, uint16_t bottom) {
|
|
// TFA+VSA+BFA must equal 320
|
|
if (top + bottom <= ILI9341_TFTHEIGHT) {
|
|
uint16_t middle = ILI9341_TFTHEIGHT - (top + bottom);
|
|
uint8_t data[6];
|
|
data[0] = top >> 8;
|
|
data[1] = top & 0xff;
|
|
data[2] = middle >> 8;
|
|
data[3] = middle & 0xff;
|
|
data[4] = bottom >> 8;
|
|
data[5] = bottom & 0xff;
|
|
sendCommand(ILI9341_VSCRDEF, (uint8_t *)data, 6);
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
/*!
|
|
@brief Set the "address window" - the rectangle we will write to RAM with
|
|
the next chunk of SPI data writes. The ILI9341 will automatically wrap
|
|
the data as each row is filled
|
|
@param x1 TFT memory 'x' origin
|
|
@param y1 TFT memory 'y' origin
|
|
@param w Width of rectangle
|
|
@param h Height of rectangle
|
|
*/
|
|
|
|
/**************************************************************************/
|
|
void Adafruit_ILI9341::setAddrWindow(uint16_t x1, uint16_t y1, uint16_t w,
|
|
uint16_t h) {
|
|
uint16_t x2 = (x1 + w - 1), y2 = (y1 + h - 1);
|
|
|
|
writeCommand(ILI9341_CASET); // Column address set
|
|
SPI_WRITE16(x1);
|
|
SPI_WRITE16(x2);
|
|
writeCommand(ILI9341_PASET); // Row address set
|
|
SPI_WRITE16(y1);
|
|
SPI_WRITE16(y2);
|
|
writeCommand(ILI9341_RAMWR); // Write to RAM
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
/*!
|
|
@brief Read 8 bits of data from ILI9341 configuration memory. NOT from RAM!
|
|
This is highly undocumented/supported, it's really a hack but kinda
|
|
works?
|
|
@param commandByte The command register to read data from
|
|
@param index The byte index into the command to read from
|
|
@return Unsigned 8-bit data read from ILI9341 register
|
|
*/
|
|
|
|
/**************************************************************************/
|
|
uint8_t Adafruit_ILI9341::readcommand8(uint8_t commandByte, uint8_t index) {
|
|
uint8_t data = 0x10 + index;
|
|
|
|
sendCommand(0xD9, &data, 1); // Set Index Register
|
|
return Adafruit_SPITFT::readcommand8(commandByte);
|
|
}
|