summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Make.config2
-rw-r--r--glcddrivers/Makefile8
-rw-r--r--glcddrivers/drivers.c16
-rw-r--r--glcddrivers/drivers.h9
-rw-r--r--glcddrivers/ili9341.c366
-rw-r--r--glcddrivers/ili9341.h53
-rw-r--r--graphlcd.conf10
7 files changed, 457 insertions, 7 deletions
diff --git a/Make.config b/Make.config
index 19cbfd8..3ddedd2 100644
--- a/Make.config
+++ b/Make.config
@@ -85,3 +85,5 @@ HAVE_DRIVER_VNCSERVER=1
#HAVE_DRIVER_picoLCD_256x64=1
#HAVE_DRIVER_SSD1306=1
+
+#HAVE_DRIVER_ILI9341=1
diff --git a/glcddrivers/Makefile b/glcddrivers/Makefile
index dcf0c5f..e144698 100644
--- a/glcddrivers/Makefile
+++ b/glcddrivers/Makefile
@@ -40,7 +40,7 @@ ifeq ($(shell pkg-config --exists libusb && echo 1), 1)
LIBS += $(shell pkg-config --libs libusb)
DEFINES += -DHAVE_DRIVER_picoLCD_256x64
endif
-endif
+endif
ifeq ($(HAVE_DRIVER_VNCSERVER), 1)
ifeq ($(shell libvncserver-config --version >/dev/null && echo 1), 1)
@@ -57,6 +57,12 @@ ifeq ($(HAVE_DRIVER_SSD1306), 1)
LIBS += -lwiringPi
endif
+ifeq ($(HAVE_DRIVER_ILI9341), 1)
+ DEFINES += -DHAVE_DRIVER_ILI9341
+ OBJS += ili9341.o
+ LIBS += -lwiringPi
+endif
+
### Implicit rules:
%.o: %.c
diff --git a/glcddrivers/drivers.c b/glcddrivers/drivers.c
index 44e19c1..d30a2e5 100644
--- a/glcddrivers/drivers.c
+++ b/glcddrivers/drivers.c
@@ -42,6 +42,9 @@
#ifdef HAVE_DRIVER_SSD1306
#include "ssd1306.h"
#endif
+#ifdef HAVE_DRIVER_ILI9341
+#include "ili9341.h"
+#endif
namespace GLCD
{
@@ -68,16 +71,19 @@ tDriver drivers[] =
{"g15daemon", kDriverG15daemon},
#ifdef HAVE_DRIVER_AX206DPF
{"ax206dpf", kDriverAX206DPF},
-#endif
+#endif
#ifdef HAVE_DRIVER_picoLCD_256x64
{"picolcd256x64", kDriverPicoLCD_256x64},
-#endif
+#endif
#ifdef HAVE_DRIVER_VNCSERVER
{"vncserver", kDriverVncServer},
-#endif
+#endif
#ifdef HAVE_DRIVER_SSD1306
{"ssd1306", kDriverSSD1306},
#endif
+#ifdef HAVE_DRIVER_ILI9341
+ {"ili9341", kDriverILI9341},
+#endif
{"", kDriverUnknown}
};
@@ -152,6 +158,10 @@ cDriver * CreateDriver(int driverID, cDriverConfig * config)
case kDriverSSD1306:
return new cDriverSSD1306(config);
#endif
+#ifdef HAVE_DRIVER_ILI9341
+ case kDriverILI9341:
+ return new cDriverILI9341(config);
+#endif
case kDriverUnknown:
default:
return NULL;
diff --git a/glcddrivers/drivers.h b/glcddrivers/drivers.h
index f3bfbbf..fe19d2f 100644
--- a/glcddrivers/drivers.h
+++ b/glcddrivers/drivers.h
@@ -42,16 +42,19 @@ enum eDriver
kDriverDM140GINK = 16,
#ifdef HAVE_DRIVER_AX206DPF
kDriverAX206DPF = 17,
-#endif
+#endif
#ifdef HAVE_DRIVER_picoLCD_256x64
kDriverPicoLCD_256x64 = 18,
-#endif
+#endif
#ifdef HAVE_DRIVER_VNCSERVER
kDriverVncServer = 19,
-#endif
+#endif
#ifdef HAVE_DRIVER_SSD1306
kDriverSSD1306 = 20,
#endif
+#ifdef HAVE_DRIVER_ILI9341
+ kDriverILI9341 = 21,
+#endif
kDriverSerDisp = 100,
kDriverG15daemon = 200
};
diff --git a/glcddrivers/ili9341.c b/glcddrivers/ili9341.c
new file mode 100644
index 0000000..eb3a819
--- /dev/null
+++ b/glcddrivers/ili9341.c
@@ -0,0 +1,366 @@
+/*
+ * GraphLCD driver library
+ *
+ * ili9341.c - ILI9341 TFT driver class
+ *
+ * This file is released under the GNU General Public License. Refer
+ * to the COPYING file distributed with this package.
+ *
+ * (c) 2015 Andreas Regel <andreas.regel AT powarman.de>
+ */
+
+#include <stdint.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <cstring>
+
+#include <wiringPi.h>
+#include <wiringPiSPI.h>
+
+#include "common.h"
+#include "config.h"
+#include "ili9341.h"
+
+
+namespace GLCD
+{
+
+const int kLcdWidth = 240;
+const int kLcdHeight = 320;
+
+const int kSpiBus = 0;
+
+const int kGpioReset = 4;
+const int kGpioDC = 5;
+
+const uint8_t kCmdNop = 0x00;
+const uint8_t kCmdSleepOut = 0x11;
+const uint8_t kCmdGammaSet = 0x26;
+const uint8_t kCmdDisplayOn = 0x29;
+const uint8_t kCmdColumnAddressSet = 0x2A;
+const uint8_t kCmdPageAddressSet = 0x2B;
+const uint8_t kCmdMemoryWrite = 0x2C;
+const uint8_t kCmdMemoryAccessControl = 0x36;
+const uint8_t kCmdPixelFormatSet = 0x3A;
+const uint8_t kCmdFrameRateControl = 0xB1;
+const uint8_t kCmdDisplayFunctionControl = 0xB6;
+
+const uint8_t kCmdPowerControl1 = 0xC0;
+const uint8_t kCmdPowerControl2 = 0xC1;
+const uint8_t kCmdVcomControl1 = 0xC5;
+const uint8_t kCmdVcomControl2 = 0xC7;
+const uint8_t kCmdPositiveGammaControl = 0xE0;
+const uint8_t kCmdNegativeGammaControl = 0xE1;
+
+const uint8_t kCmdPowerControlA = 0xCB;
+const uint8_t kCmdPowerControlB = 0xCF;
+const uint8_t kCmdDriverTimingControlA = 0xE8;
+const uint8_t kCmdDriverTimingControlB = 0xEA;
+const uint8_t kCmdPowerOnSequenceControl = 0xED;
+const uint8_t kCmdUnknownEF = 0xEF;
+const uint8_t kCmdEnable3G = 0xF2;
+const uint8_t kCmdPumpRatioControl = 0xF7;
+
+
+cDriverILI9341::cDriverILI9341(cDriverConfig * config)
+: cDriver(config)
+{
+ refreshCounter = 0;
+
+ wiringPiSetup();
+}
+
+cDriverILI9341::~cDriverILI9341()
+{
+}
+
+int cDriverILI9341::Init()
+{
+ width = config->width;
+ if (width <= 0)
+ width = kLcdWidth;
+ height = config->height;
+ if (height <= 0)
+ height = kLcdHeight;
+
+ for (unsigned int i = 0; i < config->options.size(); i++)
+ {
+ if (config->options[i].name == "")
+ {
+ }
+ }
+
+ // setup lcd array (wanted state)
+ newLCD = new uint32_t[width * height];
+ if (newLCD)
+ {
+ memset(newLCD, 0, width * height * sizeof(uint32_t));
+ }
+ // setup lcd array (current state)
+ oldLCD = new uint32_t[width * height];
+ if (oldLCD)
+ {
+ memset(oldLCD, 0, width * height * sizeof(uint32_t));
+ }
+
+ if (config->device == "")
+ {
+ return -1;
+ }
+
+ pinMode(kGpioReset, OUTPUT);
+ pinMode(kGpioDC, OUTPUT);
+
+ digitalWrite(kGpioReset, HIGH);
+ digitalWrite(kGpioDC, LOW);
+
+ wiringPiSPISetup(kSpiBus, 64000000);
+
+ /* reset display */
+ Reset();
+
+ WriteCommand(kCmdUnknownEF);
+ WriteData(0x03);
+ WriteData(0x80);
+ WriteData(0x02);
+ WriteCommand(kCmdPowerControlB);
+ WriteData(0x00);
+ WriteData(0xC1);
+ WriteData(0x30);
+ WriteCommand(kCmdPowerOnSequenceControl);
+ WriteData(0x64);
+ WriteData(0x03);
+ WriteData(0x12);
+ WriteData(0x81);
+ WriteCommand(kCmdDriverTimingControlA);
+ WriteData(0x85);
+ WriteData(0x00);
+ WriteData(0x78);
+ WriteCommand(kCmdPowerControlA);
+ WriteData(0x39);
+ WriteData(0x2C);
+ WriteData(0x00);
+ WriteData(0x34);
+ WriteData(0x02);
+ WriteCommand(kCmdPumpRatioControl);
+ WriteData(0x20);
+ WriteCommand(kCmdDriverTimingControlB);
+ WriteData(0x00);
+ WriteData(0x00);
+
+ WriteCommand(kCmdPowerControl1);
+ WriteData(0x23);
+ WriteCommand(kCmdPowerControl2);
+ WriteData(0x10);
+ WriteCommand(kCmdVcomControl1);
+ WriteData(0x3e);
+ WriteData(0x28);
+ WriteCommand(kCmdVcomControl2);
+ WriteData(0x86);
+ WriteCommand(kCmdMemoryAccessControl);
+ WriteData(0x48);
+ WriteCommand(kCmdPixelFormatSet);
+ WriteData(0x55);
+ WriteCommand(kCmdFrameRateControl);
+ WriteData(0x00);
+ WriteData(0x18);
+ WriteCommand(kCmdDisplayFunctionControl);
+ WriteData(0x08);
+ WriteData(0x82);
+ WriteData(0x27);
+ WriteCommand(kCmdEnable3G);
+ WriteData(0x00);
+ WriteCommand(kCmdGammaSet);
+ WriteData(0x01);
+ WriteCommand(kCmdPositiveGammaControl);
+ WriteData(0x0F);
+ WriteData(0x31);
+ WriteData(0x2B);
+ WriteData(0x0C);
+ WriteData(0x0E);
+ WriteData(0x08);
+ WriteData(0x4E);
+ WriteData(0xF1);
+ WriteData(0x37);
+ WriteData(0x07);
+ WriteData(0x10);
+ WriteData(0x03);
+ WriteData(0x0E);
+ WriteData(0x09);
+ WriteData(0x00);
+ WriteCommand(kCmdNegativeGammaControl);
+ WriteData(0x00);
+ WriteData(0x0E);
+ WriteData(0x14);
+ WriteData(0x03);
+ WriteData(0x11);
+ WriteData(0x07);
+ WriteData(0x31);
+ WriteData(0xC1);
+ WriteData(0x48);
+ WriteData(0x08);
+ WriteData(0x0F);
+ WriteData(0x0C);
+ WriteData(0x31);
+ WriteData(0x36);
+ WriteData(0x0F);
+ WriteCommand(kCmdSleepOut);
+ usleep(120000);
+ WriteCommand(kCmdDisplayOn);
+
+ *oldConfig = *config;
+
+ // clear display
+ Clear();
+
+ syslog(LOG_INFO, "%s: ILI9341 initialized.\n", config->name.c_str());
+ return 0;
+}
+
+int cDriverILI9341::DeInit()
+{
+ // free lcd array (wanted state)
+ if (newLCD)
+ {
+ delete[] newLCD;
+ }
+ // free lcd array (current state)
+ if (oldLCD)
+ {
+ delete[] oldLCD;
+ }
+
+ return 0;
+}
+
+int cDriverILI9341::CheckSetup()
+{
+ if (config->device != oldConfig->device ||
+ config->width != oldConfig->width ||
+ config->height != oldConfig->height)
+ {
+ DeInit();
+ Init();
+ return 0;
+ }
+
+ if (config->upsideDown != oldConfig->upsideDown)
+ {
+ oldConfig->upsideDown = config->upsideDown;
+ return 1;
+ }
+ return 0;
+}
+
+void cDriverILI9341::Clear()
+{
+ memset(newLCD, 0, width * height * sizeof(uint32_t));
+}
+
+
+void cDriverILI9341::SetPixel(int x, int y, uint32_t data)
+{
+ if (x >= width || y >= height)
+ return;
+
+ if (config->upsideDown)
+ {
+ x = width - 1 - x;
+ y = height - 1 - y;
+ }
+
+ newLCD[y * width + x] = data;
+}
+
+
+void cDriverILI9341::Refresh(bool refreshAll)
+{
+ int y;
+
+ if (CheckSetup() == 1)
+ refreshAll = true;
+
+ if (config->refreshDisplay > 0)
+ {
+ refreshCounter = (refreshCounter + 1) % config->refreshDisplay;
+ if (!refreshAll && !refreshCounter)
+ refreshAll = true;
+ }
+
+ refreshAll = true;
+ if (refreshAll)
+ {
+ SetWindow(0, 0, width - 1, height - 1);
+ WriteCommand(kCmdMemoryWrite);
+ for (y = 0; y < height; y++)
+ {
+ uint8_t line[width * 2];
+ uint32_t * pixel = &newLCD[y * width];
+
+ for (int x = 0; x < (width * 2); x += 2)
+ {
+ line[x] = ((*pixel & 0x00F80000) >> 16)
+ | ((*pixel & 0x0000E000) >> 13);
+ line[x + 1] = ((*pixel & 0x00001C00) >> 5)
+ | ((*pixel & 0x000000F8) >> 3);
+ pixel++;
+ }
+ WriteData((uint8_t *) line, width * 2);
+ }
+ memcpy(oldLCD, newLCD, width * height * sizeof(uint32_t));
+ // and reset RefreshCounter
+ refreshCounter = 0;
+ }
+ else
+ {
+ // draw only the changed bytes
+ }
+}
+
+void cDriverILI9341::SetBrightness(unsigned int percent)
+{
+ //WriteCommand(kCmdSetContrast, percent * 255 / 100);
+}
+
+void cDriverILI9341::Reset()
+{
+ digitalWrite(kGpioReset, HIGH);
+ usleep(100000);
+ digitalWrite(kGpioReset, LOW);
+ usleep(100000);
+ digitalWrite(kGpioReset, HIGH);
+ usleep(100000);
+}
+
+void cDriverILI9341::SetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
+{
+ WriteCommand(kCmdColumnAddressSet);
+ WriteData(x0 >> 8);
+ WriteData(x0);
+ WriteData(x1 >> 8);
+ WriteData(x1);
+ WriteCommand(kCmdPageAddressSet);
+ WriteData(y0 >> 8);
+ WriteData(y0);
+ WriteData(y1 >> 8);
+ WriteData(y1);
+}
+
+void cDriverILI9341::WriteCommand(uint8_t command)
+{
+ digitalWrite(kGpioDC, LOW);
+ wiringPiSPIDataRW(kSpiBus, &command, 1);
+ digitalWrite(kGpioDC, HIGH);
+}
+
+void cDriverILI9341::WriteData(uint8_t data)
+{
+ wiringPiSPIDataRW(kSpiBus, &data, 1);
+}
+
+void cDriverILI9341::WriteData(uint8_t * buffer, uint32_t length)
+{
+ wiringPiSPIDataRW(kSpiBus, buffer, length);
+}
+
+} // end of namespace
diff --git a/glcddrivers/ili9341.h b/glcddrivers/ili9341.h
new file mode 100644
index 0000000..d729971
--- /dev/null
+++ b/glcddrivers/ili9341.h
@@ -0,0 +1,53 @@
+/*
+ * GraphLCD driver library
+ *
+ * ili9341.h - ILI9341 OLED driver class
+ *
+ * This file is released under the GNU General Public License. Refer
+ * to the COPYING file distributed with this package.
+ *
+ * (c) 2015 Andreas Regel <andreas.regel AT powarman.de>
+ */
+
+#ifndef _GLCDDRIVERS_ILI9341_H_
+#define _GLCDDRIVERS_ILI9341_H_
+
+#include "driver.h"
+
+namespace GLCD
+{
+
+class cDriverConfig;
+
+class cDriverILI9341 : public cDriver
+{
+private:
+ uint32_t * newLCD; // wanted state
+ uint32_t * oldLCD; // current state
+ int refreshCounter;
+
+ int CheckSetup();
+
+ void Reset();
+ void SetWindow(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1);
+ void WriteCommand(uint8_t command);
+ void WriteData(uint8_t data);
+ void WriteData(uint8_t * buffer, uint32_t length);
+
+public:
+ cDriverILI9341(cDriverConfig * config);
+ virtual ~cDriverILI9341();
+
+ virtual int Init();
+ virtual int DeInit();
+
+ virtual void Clear();
+ virtual void SetPixel(int x, int y, uint32_t data);
+ //virtual void Set8Pixels(int x, int y, unsigned char data);
+ virtual void Refresh(bool refreshAll = false);
+ virtual void SetBrightness(unsigned int percent);
+};
+
+} // end of namespace
+
+#endif
diff --git a/graphlcd.conf b/graphlcd.conf
index 66ee396..fce9270 100644
--- a/graphlcd.conf
+++ b/graphlcd.conf
@@ -672,3 +672,13 @@ Driver=ssd1306
Device=0
Width=128
Height=64
+
+[ili9341]
+# ili9341 driver
+# This is a driver module for the ILI9341 TFT display controller.
+# Default size: 320x240
+Driver=ili9341
+Device=0
+Width=320
+Height=240
+