| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- /*!
- * @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
- #endif
- #include <limits.h>
- #if defined (ARDUINO_ARCH_ARC32) || defined (ARDUINO_MAXIM)
- #define SPI_DEFAULT_FREQ 16000000
- #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
- #define SPI_DEFAULT_FREQ 24000000 ///< Default SPI data clock frequency
- #endif
- #define MADCTL_MY 0x80 ///< Bottom to top
- #define MADCTL_MX 0x40 ///< Right to left
- #define MADCTL_MV 0x20 ///< Reverse Mode
- #define MADCTL_ML 0x10 ///< LCD refresh Bottom to top
- #define MADCTL_RGB 0x00 ///< Red-Green-Blue pixel order
- #define MADCTL_BGR 0x08 ///< Blue-Green-Red pixel order
- #define MADCTL_MH 0x04 ///< LCD refresh right to left
- /**************************************************************************/
- /*!
- @brief Instantiate Adafruit ILI9341 driver 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
- @param cs Chip select pin #
- @param dc Data/Command pin #
- @param rst Reset pin # (optional, pass -1 if unused)
- */
- /**************************************************************************/
- Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t rst) : Adafruit_SPITFT(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT, cs, dc, rst) {
- }
- static const uint8_t PROGMEM initcmd[] = {
- 0xEF, 3, 0x03, 0x80, 0x02,
- 0xCF, 3, 0x00, 0xC1, 0x30,
- 0xED, 4, 0x64, 0x03, 0x12, 0x81,
- 0xE8, 3, 0x85, 0x00, 0x78,
- 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
- 0xF7, 1, 0x20,
- 0xEA, 2, 0x00, 0x00,
- ILI9341_PWCTR1 , 1, 0x23, // Power control VRH[5:0]
- ILI9341_PWCTR2 , 1, 0x10, // Power control SAP[2:0];BT[3:0]
- ILI9341_VMCTR1 , 2, 0x3e, 0x28, // VCM control
- ILI9341_VMCTR2 , 1, 0x86, // VCM control2
- ILI9341_MADCTL , 1, 0x48, // Memory Access Control
- ILI9341_VSCRSADD, 1, 0x00, // Vertical scroll zero
- ILI9341_PIXFMT , 1, 0x55,
- ILI9341_FRMCTR1 , 2, 0x00, 0x18,
- ILI9341_DFUNCTR , 3, 0x08, 0x82, 0x27, // Display Function Control
- 0xF2, 1, 0x00, // 3Gamma Function Disable
- ILI9341_GAMMASET , 1, 0x01, // Gamma curve selected
- ILI9341_GMCTRP1 , 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma
- 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
- ILI9341_GMCTRN1 , 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma
- 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
- ILI9341_SLPOUT , 0x80, // Exit Sleep
- ILI9341_DISPON , 0x80, // Display on
- 0x00 // End of list
- };
- /**************************************************************************/
- /*!
- @brief Initialize ILI9341 chip
- Connects to the ILI9341 over SPI and sends initialization procedure commands
- @param freq Desired SPI clock frequency
- */
- /**************************************************************************/
- void Adafruit_ILI9341::begin(uint32_t freq) {
- if(!freq) freq = SPI_DEFAULT_FREQ;
- _freq = freq;
- initSPI(freq);
- startWrite();
- uint8_t cmd, x, numArgs;
- const uint8_t *addr = initcmd;
- while((cmd = pgm_read_byte(addr++)) > 0) {
- writeCommand(cmd);
- x = pgm_read_byte(addr++);
- numArgs = x & 0x7F;
- while(numArgs--) spiWrite(pgm_read_byte(addr++));
- if(x & 0x80) delay(120);
- }
- endWrite();
- _width = ILI9341_TFTWIDTH;
- _height = ILI9341_TFTHEIGHT;
- }
- /**************************************************************************/
- /*!
- @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:
- m = (MADCTL_MX | MADCTL_BGR);
- _width = ILI9341_TFTWIDTH;
- _height = ILI9341_TFTHEIGHT;
- break;
- case 1:
- m = (MADCTL_MV | MADCTL_BGR);
- _width = ILI9341_TFTHEIGHT;
- _height = ILI9341_TFTWIDTH;
- break;
- case 2:
- m = (MADCTL_MY | MADCTL_BGR);
- _width = ILI9341_TFTWIDTH;
- _height = ILI9341_TFTHEIGHT;
- break;
- case 3:
- m = (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
- _width = ILI9341_TFTHEIGHT;
- _height = ILI9341_TFTWIDTH;
- break;
- }
- startWrite();
- writeCommand(ILI9341_MADCTL);
- spiWrite(m);
- endWrite();
- }
- /**************************************************************************/
- /*!
- @brief Enable/Disable display color inversion
- @param invert True to invert, False to have normal color
- */
- /**************************************************************************/
- void Adafruit_ILI9341::invertDisplay(boolean invert) {
- startWrite();
- writeCommand(invert ? ILI9341_INVON : ILI9341_INVOFF);
- endWrite();
- }
- /**************************************************************************/
- /*!
- @brief Scroll display memory
- @param y How many pixels to scroll display by
- */
- /**************************************************************************/
- void Adafruit_ILI9341::scrollTo(uint16_t y) {
- startWrite();
- writeCommand(ILI9341_VSCRSADD);
- SPI_WRITE16(y);
- endWrite();
- }
- /**************************************************************************/
- void Adafruit_ILI9341::setScrollMargins(uint16_t top, uint16_t bottom)
- {
- uint16_t height = _height - (top + bottom);
- startWrite();
- writeCommand(0x33);
- SPI_WRITE16(top);
- SPI_WRITE16(height);
- SPI_WRITE16(bottom);
- endWrite();
- }
- /**************************************************************************/
- /*!
- @brief Set the "address window" - the rectangle we will write to RAM with the next chunk of SPI data writes. The ILI9341 will automatically wrap the data as each row is filled
- @param x TFT memory 'x' origin
- @param y TFT memory 'y' origin
- @param w Width of rectangle
- @param h Height of rectangle
- */
- /**************************************************************************/
- void Adafruit_ILI9341::setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
- uint32_t xa = ((uint32_t)x << 16) | (x+w-1);
- uint32_t ya = ((uint32_t)y << 16) | (y+h-1);
- writeCommand(ILI9341_CASET); // Column addr set
- SPI_WRITE32(xa);
- writeCommand(ILI9341_PASET); // Row addr set
- SPI_WRITE32(ya);
- writeCommand(ILI9341_RAMWR); // write to RAM
- }
- /**************************************************************************/
- /*!
- @brief Read 8 bits of data from ILI9341 configuration memory. NOT from RAM!
- This is highly undocumented/supported, it's really a hack but kinda works?
- @param command The command register to read data from
- @param index The byte index into the command to read from
- @return Unsigned 8-bit data read from ILI9341 register
- */
- /**************************************************************************/
- uint8_t Adafruit_ILI9341::readcommand8(uint8_t command, uint8_t index) {
- uint32_t freq = _freq;
- if(_freq > 24000000) _freq = 24000000;
- startWrite();
- writeCommand(0xD9); // woo sekret command?
- spiWrite(0x10 + index);
- writeCommand(command);
- uint8_t r = spiRead();
- endWrite();
- _freq = freq;
- return r;
- }
|