summaryrefslogtreecommitdiff
path: root/libraries/MultiLCD/ILI9341.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/MultiLCD/ILI9341.cpp')
-rw-r--r--libraries/MultiLCD/ILI9341.cpp590
1 files changed, 590 insertions, 0 deletions
diff --git a/libraries/MultiLCD/ILI9341.cpp b/libraries/MultiLCD/ILI9341.cpp
new file mode 100644
index 0000000..61bf7f9
--- /dev/null
+++ b/libraries/MultiLCD/ILI9341.cpp
@@ -0,0 +1,590 @@
+#include <Arduino.h>
+#include <SPI.h>
+#include "MultiLCD.h"
+
+/* Pins
+D4 : RESET
+D5 : CS
+D6 : D/C
+D7 : LED
+D11 : MOSI
+D12 : MISO
+D13 : SCK
+*/
+
+#define PIN_RESET 4
+#define PIN_CS 5
+#define PIN_DC 6
+#define PIN_LED 7
+
+//Basic Colors
+#define RED 0xf800
+#define GREEN 0x07e0
+#define BLUE 0x001f
+#define BLACK 0x0000
+#define YELLOW 0xffe0
+#define WHITE 0xffff
+
+//Other Colors
+#define CYAN 0x07ff
+#define BRIGHT_RED 0xf810
+#define GRAY1 0x8410
+#define GRAY2 0x4208
+
+//TFT resolution 240*320
+#define MIN_X 0
+#define MIN_Y 0
+#define MAX_X 239
+#define MAX_Y 319
+
+#define TFT_CS_LOW digitalWrite(PIN_CS, LOW)
+#define TFT_CS_HIGH digitalWrite(PIN_CS, HIGH)
+#define TFT_DC_LOW digitalWrite(PIN_DC, LOW)
+#define TFT_DC_HIGH digitalWrite(PIN_DC, HIGH)
+#define TFT_RST_OFF digitalWrite(PIN_RESET, HIGH)
+#define TFT_RST_ON digitalWrite(PIN_RESET, LOW)
+
+
+#define YP A2 // must be an analog pin, use "An" notation!
+#define XM A1 // must be an analog pin, use "An" notation!
+#define YM 14 // can be a digital pin, this is A0
+#define XP 17 // can be a digital pin, this is A3
+
+#define TS_MINX 116*2
+#define TS_MAXX 890*2
+#define TS_MINY 83*2
+#define TS_MAXY 913*2
+
+void LCD_ILI9341::sendCMD(uint8_t index)
+{
+ TFT_DC_LOW;
+ TFT_CS_LOW;
+ SPI.transfer(index);
+ TFT_CS_HIGH;
+}
+
+void LCD_ILI9341::WRITE_DATA(uint8_t data)
+{
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ SPI.transfer(data);
+ TFT_CS_HIGH;
+}
+
+void LCD_ILI9341::sendData(uint16_t data)
+{
+ uint8_t data1 = data>>8;
+ uint8_t data2 = data&0xff;
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ SPI.transfer(data1);
+ SPI.transfer(data2);
+ TFT_CS_HIGH;
+}
+
+void LCD_ILI9341::WRITE_Package(uint16_t *data, uint8_t howmany)
+{
+ uint16_t data1 = 0;
+ uint8_t data2 = 0;
+
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ uint8_t count=0;
+ for(count=0;count<howmany;count++)
+ {
+ data1 = data[count]>>8;
+ data2 = data[count]&0xff;
+ SPI.transfer(data1);
+ SPI.transfer(data2);
+ }
+ TFT_CS_HIGH;
+}
+
+uint8_t LCD_ILI9341::Read_Register(uint8_t Addr, uint8_t xParameter)
+{
+ uint8_t data=0;
+ sendCMD(0xd9); /* ext command */
+ WRITE_DATA(0x10+xParameter); /* 0x11 is the first Parameter */
+ TFT_DC_LOW;
+ TFT_CS_LOW;
+ SPI.transfer(Addr);
+ TFT_DC_HIGH;
+ data = SPI.transfer(0);
+ TFT_CS_HIGH;
+ return data;
+}
+
+void LCD_ILI9341::begin (void)
+{
+ pinMode(PIN_CS, OUTPUT);
+ pinMode(PIN_DC, OUTPUT);
+ pinMode(PIN_LED, OUTPUT);
+ pinMode(PIN_RESET, OUTPUT);
+
+ SPI.begin();
+ TFT_CS_HIGH;
+ TFT_DC_HIGH;
+ uint8_t i=0, TFTDriver=0;
+
+ TFT_RST_ON;
+ delay(10);
+ TFT_RST_OFF;
+
+ for(i=0;i<3;i++)
+ {
+ TFTDriver = readID();
+ }
+
+ sendCMD(0xCB);
+ WRITE_DATA(0x39);
+ WRITE_DATA(0x2C);
+ WRITE_DATA(0x00);
+ WRITE_DATA(0x34);
+ WRITE_DATA(0x02);
+
+ sendCMD(0xCF);
+ WRITE_DATA(0x00);
+ WRITE_DATA(0XC1);
+ WRITE_DATA(0X30);
+
+ sendCMD(0xE8);
+ WRITE_DATA(0x85);
+ WRITE_DATA(0x00);
+ WRITE_DATA(0x78);
+
+ sendCMD(0xEA);
+ WRITE_DATA(0x00);
+ WRITE_DATA(0x00);
+
+ sendCMD(0xED);
+ WRITE_DATA(0x64);
+ WRITE_DATA(0x03);
+ WRITE_DATA(0X12);
+ WRITE_DATA(0X81);
+
+ sendCMD(0xF7);
+ WRITE_DATA(0x20);
+
+ sendCMD(0xC0); //Power control
+ WRITE_DATA(0x23); //VRH[5:0]
+
+ sendCMD(0xC1); //Power control
+ WRITE_DATA(0x10); //SAP[2:0];BT[3:0]
+
+ sendCMD(0xC5); //VCM control
+ WRITE_DATA(0x3e); //Contrast
+ WRITE_DATA(0x28);
+
+ sendCMD(0xC7); //VCM control2
+ WRITE_DATA(0x86); //--
+
+ sendCMD(0x36); // Memory Access Control
+ WRITE_DATA(0x48); //C8
+
+ sendCMD(0x3A);
+ WRITE_DATA(0x55);
+
+ sendCMD(0xB1);
+ WRITE_DATA(0x00);
+ WRITE_DATA(0x18);
+
+ sendCMD(0xB6); // Display Function Control
+ WRITE_DATA(0x08);
+ WRITE_DATA(0x82);
+ WRITE_DATA(0x27);
+
+ sendCMD(0xF2); // 3Gamma Function Disable
+ WRITE_DATA(0x00);
+
+ sendCMD(0x26); //Gamma curve selected
+ WRITE_DATA(0x01);
+
+ sendCMD(0xE0); //Set Gamma
+ WRITE_DATA(0x0F);
+ WRITE_DATA(0x31);
+ WRITE_DATA(0x2B);
+ WRITE_DATA(0x0C);
+ WRITE_DATA(0x0E);
+ WRITE_DATA(0x08);
+ WRITE_DATA(0x4E);
+ WRITE_DATA(0xF1);
+ WRITE_DATA(0x37);
+ WRITE_DATA(0x07);
+ WRITE_DATA(0x10);
+ WRITE_DATA(0x03);
+ WRITE_DATA(0x0E);
+ WRITE_DATA(0x09);
+ WRITE_DATA(0x00);
+
+ sendCMD(0XE1); //Set Gamma
+ WRITE_DATA(0x00);
+ WRITE_DATA(0x0E);
+ WRITE_DATA(0x14);
+ WRITE_DATA(0x03);
+ WRITE_DATA(0x11);
+ WRITE_DATA(0x07);
+ WRITE_DATA(0x31);
+ WRITE_DATA(0xC1);
+ WRITE_DATA(0x48);
+ WRITE_DATA(0x08);
+ WRITE_DATA(0x0F);
+ WRITE_DATA(0x0C);
+ WRITE_DATA(0x31);
+ WRITE_DATA(0x36);
+ WRITE_DATA(0x0F);
+
+ sendCMD(0x11); //Exit Sleep
+ delay(120);
+
+ sendCMD(0x29); //Display on
+ sendCMD(0x2c);
+ clear();
+}
+
+uint8_t LCD_ILI9341::readID(void)
+{
+ uint8_t i=0;
+ uint8_t data[3] ;
+ uint8_t ID[3] = {0x00, 0x93, 0x41};
+ uint8_t ToF=1;
+ for(i=0;i<3;i++)
+ {
+ data[i]=Read_Register(0xd3,i+1);
+ if(data[i] != ID[i])
+ {
+ ToF=0;
+ }
+ }
+ if(!ToF) /* data!=ID */
+ {
+#if 0
+ Serial.print("Read TFT ID failed, ID should be 0x09341, but read ID = 0x");
+ for(i=0;i<3;i++)
+ {
+ Serial.print(data[i],HEX);
+ }
+ Serial.println();
+#endif
+ }
+ return ToF;
+}
+
+void LCD_ILI9341::setCol(uint16_t StartCol,uint16_t EndCol)
+{
+ sendCMD(0x2A); /* Column Command address */
+ sendData(StartCol);
+ sendData(EndCol);
+}
+
+void LCD_ILI9341::setPage(uint16_t StartPage,uint16_t EndPage)
+{
+ sendCMD(0x2B); /* Column Command address */
+ sendData(StartPage);
+ sendData(EndPage);
+}
+
+void LCD_ILI9341::clear(uint16_t XL, uint16_t XR, uint16_t YU, uint16_t YD, uint16_t color)
+{
+ unsigned long XY=0;
+ unsigned long i=0;
+
+ if(XL > XR)
+ {
+ XL = XL^XR;
+ XR = XL^XR;
+ XL = XL^XR;
+ }
+ if(YU > YD)
+ {
+ YU = YU^YD;
+ YD = YU^YD;
+ YU = YU^YD;
+ }
+ XL = constrain(XL, MIN_X,MAX_X);
+ XR = constrain(XR, MIN_X,MAX_X);
+ YU = constrain(YU, MIN_Y,MAX_Y);
+ YD = constrain(YD, MIN_Y,MAX_Y);
+
+ XY = (XR-XL+1);
+ XY = XY*(YD-YU+1);
+
+ setCol(XL,XR);
+ setPage(YU, YD);
+ sendCMD(0x2c); /* start to write to display ra */
+ /* m */
+
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+
+ uint8_t Hcolor = color>>8;
+ uint8_t Lcolor = color&0xff;
+ for(i=0; i < XY; i++)
+ {
+ SPI.transfer(Hcolor);
+ SPI.transfer(Lcolor);
+ }
+
+ TFT_CS_HIGH;
+}
+
+void LCD_ILI9341::clear(void)
+{
+ setCol(0, 239);
+ setPage(0, 319);
+ sendCMD(0x2c); /* start to write to display ra */
+ /* m */
+
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ for(uint16_t i=0; i<38400; i++)
+ {
+ SPI.transfer(0);
+ SPI.transfer(0);
+ SPI.transfer(0);
+ SPI.transfer(0);
+ }
+ TFT_CS_HIGH;
+
+ m_x = 0;
+ m_y = 0;
+}
+
+
+void LCD_ILI9341::setXY(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1)
+{
+ setCol(x0, x1);
+ setPage(319 - y1, 319 - y0);
+ sendCMD(0x2c);
+}
+
+void LCD_ILI9341::setPixel(uint16_t poX, uint16_t poY,uint16_t color)
+{
+ setXY(poX, poY, poX, poY);
+ sendData(color);
+}
+
+void LCD_ILI9341::backlight(bool on)
+{
+ digitalWrite(PIN_LED, on);
+}
+
+void LCD_ILI9341::clearPixels(uint16_t pixels)
+{
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ for(uint16_t i = 0; i < pixels; i++)
+ {
+ SPI.transfer(0);
+ SPI.transfer(0);
+ SPI.transfer(0);
+ SPI.transfer(0);
+ }
+ TFT_CS_HIGH;
+}
+
+size_t LCD_ILI9341::write(uint8_t c)
+{
+ if (c == '\n') {
+ m_x += (m_font + 1) << 3;
+ return 0;
+ } else if (c == '\r') {
+ setXY(m_x, m_x + 7, m_y, 319);
+ clearPixels((320 - m_y) * 8);
+ m_y = 0;
+ return 0;
+ }
+
+ if (m_font == FONT_SIZE_SMALL) {
+ setXY(m_x, m_x + 7, m_y, m_y + 4);
+ m_y += 6;
+ if (m_y >= 320) {
+ m_x += (m_font + 1) << 3;
+ m_y = 0;
+ if (m_x >= 240) {
+ m_x = 0;
+ }
+ }
+ if (c > 0x20 && c < 0x7f) {
+ byte pgm_buffer[5];
+ memcpy_P(pgm_buffer, &font5x8[c - 0x21], 5);
+ byte i = 4;
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ do {
+ unsigned char d = pgm_buffer[i];
+ for (byte j = 0; j < 8; j++, d >>= 1) {
+ SPI.transfer(m_color[d & 1][1]);
+ SPI.transfer(m_color[d & 1][0]);
+ }
+ } while (i--);
+ TFT_CS_HIGH;
+ } else {
+ clearPixels(5 * 8);
+ }
+ } else {
+ setXY(m_x, m_x + 15, m_y, m_y + 7);
+ m_y += 9;
+ if (m_y >= 320) {
+ m_x += (m_font + 1) << 3;
+ m_y = 0;
+ if (m_x >= 240) {
+ m_x = 0;
+ }
+ }
+ if (c > 0x20 && c < 0x7f) {
+ byte pgm_buffer[16];
+ memcpy_P(pgm_buffer, &font8x16_terminal[c - 0x21], 16);
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ for (byte i = 0; i < 16; i += 2) {
+ unsigned char d = pgm_buffer[14 - i];
+ for (byte j = 0; j < 8; j++, d >>= 1) {
+ SPI.transfer(m_color[d & 1][1]);
+ SPI.transfer(m_color[d & 1][0]);
+ }
+ d = pgm_buffer[15 - i];
+ for (byte j = 0; j < 8; j++, d >>= 1) {
+ SPI.transfer(m_color[d & 1][1]);
+ SPI.transfer(m_color[d & 1][0]);
+ }
+ }
+ TFT_CS_HIGH;
+ } else {
+ clearPixels(8 * 16);
+ }
+ }
+}
+
+void LCD_ILI9341::writeDigit(byte n)
+{
+ if (m_font == FONT_SIZE_SMALL) {
+ setXY(m_x, m_x + 7, m_y, m_y + 7);
+ sendCMD(0x2c);
+ if (n <= 9) {
+ byte pgm_buffer[8];
+ memcpy_P(pgm_buffer, &digits8x8[n], 8);
+ byte i = 7;
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ do {
+ unsigned char d = pgm_buffer[i];
+ for (byte j = 0; j < 8; j++, d >>= 1) {
+ SPI.transfer(m_color[d & 1][1]);
+ SPI.transfer(m_color[d & 1][0]);
+ }
+ } while (i--);
+ TFT_CS_HIGH;
+ m_y += 8;
+ } else {
+ clearPixels(8 * 8);
+ }
+ } else if (m_font == FONT_SIZE_MEDIUM) {
+ write(n <= 9 ? ('0' + n) : ' ');
+ } else if (m_font == FONT_SIZE_LARGE) {
+ setXY(m_x, m_x + 15, m_y, m_y + 15);
+ m_y += 16;
+ if (n <= 9) {
+ byte pgm_buffer[32];
+ memcpy_P(pgm_buffer, &digits16x16[n], sizeof(pgm_buffer));
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ for (byte i = 0; i < 16; i++) {
+ unsigned char d = pgm_buffer[15 - i];
+ for (byte j = 0; j < 8; j++, d >>= 1) {
+ SPI.transfer(m_color[d & 1][1]);
+ SPI.transfer(m_color[d & 1][0]);
+ }
+ d = pgm_buffer[31 - i];
+ for (byte j = 0; j < 8; j++, d >>= 1) {
+ SPI.transfer(m_color[d & 1][1]);
+ SPI.transfer(m_color[d & 1][0]);
+ }
+ }
+ TFT_CS_HIGH;
+ } else {
+ clearPixels(16 * 16);
+ }
+ } else if (m_font == FONT_SIZE_XLARGE) {
+ setXY(m_x, m_x + 23, m_y, m_y + 15);
+ m_y += 18;
+ if (n <= 9) {
+ byte pgm_buffer[48];
+ memcpy_P(pgm_buffer, &digits16x24[n], sizeof(pgm_buffer));
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ for (int i = 0; i < 48; i += 3) {
+ unsigned char d = pgm_buffer[45 - i];
+ for (int j = 0; j < 8; j++, d >>= 1) {
+ SPI.transfer(m_color[d & 1][1]);
+ SPI.transfer(m_color[d & 1][0]);
+ }
+ d = pgm_buffer[46 - i];
+ for (int j = 0; j < 8; j++, d >>= 1) {
+ SPI.transfer(m_color[d & 1][1]);
+ SPI.transfer(m_color[d & 1][0]);
+ }
+ d = pgm_buffer[47 - i];
+ for (int j = 0; j < 8; j++, d >>= 1) {
+ SPI.transfer(m_color[d & 1][1]);
+ SPI.transfer(m_color[d & 1][0]);
+ }
+ }
+ TFT_CS_HIGH;
+ } else {
+ clearPixels(16 * 24);
+ }
+ }
+}
+
+void LCD_ILI9341::draw(const PROGMEM byte* buffer, uint16_t x, uint16_t y, uint16_t width, uint16_t height)
+{
+ byte rows = height >> 3;
+ setXY(y, y + height - 1, x, x + width - 1);
+ uint16_t i = width - 1;
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ do {
+ for (uint8_t h = 0; h < rows; h++) {
+ byte d = pgm_read_byte(buffer + i + width * h);
+ for (byte j = 0; j < 8; j++, d >>= 1) {
+ SPI.transfer(m_color[d & 1][1]);
+ SPI.transfer(m_color[d & 1][0]);
+ }
+ }
+ } while (i--);
+ TFT_CS_HIGH;
+}
+
+void LCD_ILI9341::draw2x(const PROGMEM byte* buffer, uint16_t x, uint16_t y, byte width, byte height)
+{
+ byte rows = height >> 3;
+ setXY(y, y + height * 2 - 1, x, x + width * 2 - 1);
+ uint16_t i = width - 1;
+ TFT_DC_HIGH;
+ TFT_CS_LOW;
+ do {
+ for (uint8_t h = 0; h < rows; h++) {
+ byte d = pgm_read_byte(buffer + i + width * h);
+ for (byte j = 0; j < 8; j++, d >>= 1) {
+ byte h = m_color[d & 1][1];
+ byte l = m_color[d & 1][0];
+ SPI.transfer(h);
+ SPI.transfer(l);
+ SPI.transfer(h);
+ SPI.transfer(l);
+ }
+ }
+ for (uint8_t h = 0; h < rows; h++) {
+ byte d = pgm_read_byte(buffer + i + width * h);
+ for (byte j = 0; j < 8; j++, d >>= 1) {
+ byte h = m_color[d & 1][1];
+ byte l = m_color[d & 1][0];
+ SPI.transfer(h);
+ SPI.transfer(l);
+ SPI.transfer(h);
+ SPI.transfer(l);
+ }
+ }
+ } while (i--);
+ TFT_CS_HIGH;
+}