Snippets

Peter Scargill QDTech Display Header - Modified Adafruit code for ESP8266 - C CODE

Created by Peter Scargill

File snippet.txt Added

  • Ignore whitespace
  • Hide word diff
+/***************************************************
+
+	This is a first stab at modifying the code below, which
+	originally worked on an Arduino, to work directly with 
+	an ESP8266, it is not clever, it is not optimised yet
+	but it works. I've tested in landscape mode using GPIOs
+	4,5,12 and 15 (you may not need RST at all, I hooked it
+	to ESP reset. I did check to see if you can do away with
+	CE - you  can't).
+	You need EASYGPIO for this - OR you could decide beforehand
+	the pins you want to use and hard-code the IO which would make
+	it marginally faster. Or you could go HERE
+	https://github.com/MetalPhreak/ESP8266_SPI_Driver
+	and transform this software by using hardware SPI on the ESP.
+	I've not done this yet as I want to get the fonts working.
+	
+	Next step is to put the init code in FLASH but it gets messy
+	(fonts will really need to be in flash) so I thought I'd 
+	make this available before I start really hacking it up.
+	
+	17/09/2015 Peter Scargill - http://tech.scargill.net
+
+	So in use I added this to my main code
+	
+	#include "QDTech/QDTech.h"
+
+	Then this code to test... remember to scrap any other init or use
+	of the relevant port bits in your code
+	
+	    QD_init(4,5,15,12,0,160,128);
+		QD_setRotation(1);
+		QD_setAddrWindow(0,0,160,128);
+		QD_fillScreen(QD_Color565(255,0,0));
+		QD_fillRect(30,30,90,90,QD_Color565(0,255,0));
+		for (int qq=0; qq<160;qq++) QD_drawPixel(qq,qq,QD_Color565(0,0,255));
+	
+	There is referrence below to the stock Adafruit GFX library for fonts
+	- not included that yet as that will need modifying to put the fonts
+	in FLASH
+/***************************************************
+	This is a modification of the Adafruit SPI LCD library,
+	customised for hardware SPI and the QDTech board 
+	using a Samsung S6D02A1 chip.
+
+	Most changes are made to the initialisation routine but
+	non-Arduino code has been removed too.
+
+	The initialisation sequence comes from Henning Karlsen's
+	UTFT library: http://henningkarlsen.com
+
+	Using the hardware SPI pins is highly recommeneded.
+	
+	You will also need the stock "Adafruit_GFX" library.
+	https://github.com/adafruit/Adafruit-GFX-Library
+
+	Gilchrist 30/1/2014
+	6/2/14	1.1	Fixed RGB colour order error
+
+
+/***************************************************
+  This is a library for the Adafruit 1.8" SPI display.
+  This library works with the Adafruit 1.8" TFT Breakout w/SD card
+  ----> http://www.adafruit.com/products/358
+  as well as Adafruit raw 1.8" TFT display
+  ----> http://www.adafruit.com/products/618
+ 
+  Check out the links above for our tutorials and wiring diagrams
+  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!
+
+  Written by Limor Fried/Ladyada for Adafruit Industries.
+  MIT license, all text above must be included in any redistribution
+ ****************************************************/
+
+#include "QDTech/QDTech.h"
+
+// Rather than a bazillion writecommand() and writedata() calls, screen
+// initialization commands and arguments are organized in these tables
+// stored in PROGMEM.  The table may look bulky, but that's mostly the
+// formatting -- storage-wise this is hundreds of bytes more compact
+// than the equivalent code.  Companion function follows.
+#define DELAY 0x80
+
+void delay(uint16 de)
+{
+	os_delay_us(de*1000);
+}
+static const uint8_t QDTech[] = { // QDTech support only now
+	29,
+	0xf0,	2,	0x5a, 0x5a,				// Excommand2
+	0xfc,	2,	0x5a, 0x5a,				// Excommand3
+	0x26,	1,	0x01,					// Gamma set
+	0xfa,	15,	0x02, 0x1f,	0x00, 0x10,	0x22, 0x30, 0x38, 0x3A, 0x3A, 0x3A,	0x3A, 0x3A,	0x3d, 0x02, 0x01,	// Positive gamma control
+	0xfb,	15,	0x21, 0x00,	0x02, 0x04,	0x07, 0x0a, 0x0b, 0x0c, 0x0c, 0x16,	0x1e, 0x30,	0x3f, 0x01, 0x02,	// Negative gamma control
+	0xfd,	11,	0x00, 0x00, 0x00, 0x17, 0x10, 0x00, 0x01, 0x01, 0x00, 0x1f, 0x1f,							// Analog parameter control
+	0xf4,	15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00,	// Power control
+	0xf5,	13, 0x00, 0x70, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x66, 0x06,				// VCOM control
+	0xf6,	11, 0x02, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x01, 0x00,							// Source control
+	0xf2,	17, 0x00, 0x01, 0x03, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x08, 0x08,	//Display control
+	0xf8,	1,	0x11,					// Gate control
+	0xf7,	4, 0xc8, 0x20, 0x00, 0x00,	// Interface control
+	0xf3,	2, 0x00, 0x00,				// Power sequence control
+	0x11,	DELAY, 50,					// Wake
+	0xf3,	2+DELAY, 0x00, 0x01, 50,	// Power sequence control
+	0xf3,	2+DELAY, 0x00, 0x03, 50,	// Power sequence control
+	0xf3,	2+DELAY, 0x00, 0x07, 50,	// Power sequence control
+	0xf3,	2+DELAY, 0x00, 0x0f, 50,	// Power sequence control
+	0xf4,	15+DELAY, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00, 50,	// Power control
+	0xf3,	2+DELAY, 0x00, 0x1f, 50,	// Power sequence control
+	0xf3,	2+DELAY, 0x00, 0x7f, 50,	// Power sequence control
+	0xf3,	2+DELAY, 0x00, 0xff, 50,	// Power sequence control
+	0xfd,	11, 0x00, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0x01, 0x00, 0x16, 0x16,							// Analog parameter control
+	0xf4,	15, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00,	// Power control
+	0x36,	1, 0x08,					// Memory access data control
+	0x35,	1, 0x00,					// Tearing effect line on
+	0x3a,	1+DELAY, 0x05, 150,			// Interface pixel control
+	0x29,	0,							// Display on
+	0x2c,	0							// Memory write
+  };
+
+
+
+inline uint16_t QD_swapcolor(uint16_t x) { 
+  return (x << 11) | (x & 0x07E0) | (x >> 11);
+}
+
+
+// Init when using software SPI.  All output pins are configurable.
+void ICACHE_FLASH_ATTR QD_init(uint8_t cs, uint8_t rs, uint8_t sid, uint8_t sclk, uint8_t rst,uint8_t qwidth,uint8_t qheight)
+{
+  _cs   = cs;
+  _rs   = rs;
+  _sid  = sid;
+  _sclk = sclk;
+  _rst  = rst;
+  _width=qwidth;
+  _height=qheight;
+  delay(200);
+  QD_commonInit(0);
+  delay(200);
+  QD_commandList(QDTech);
+  delay(200);
+}
+
+
+
+void QD_spiwrite(uint8_t c) {
+    // Fast SPI bitbang swiped from LPD8806 library
+    for(uint8_t bit = 0x80; bit; bit >>= 1) {
+      if(c & bit) easygpio_outputSet(_sid,1);
+      else        easygpio_outputSet(_sid,0);
+      easygpio_outputSet(_sclk,1);
+      easygpio_outputSet(_sclk,0);	  
+    }
+}
+
+
+void QD_writecommand(uint8_t c) {
+  easygpio_outputSet(_rs,0);	 
+  easygpio_outputSet(_cs,0);	
+  QD_spiwrite(c);
+  easygpio_outputSet(_cs,1);
+}
+
+
+void QD_writedata(uint8_t c) {
+  easygpio_outputSet(_rs,1);	 
+  easygpio_outputSet(_cs,0);	
+  QD_spiwrite(c);
+  easygpio_outputSet(_cs,1);
+
+} 
+
+
+
+// Companion code to the above tables.  Reads and issues
+// a series of LCD commands stored in PROGMEM byte array.
+void ICACHE_FLASH_ATTR QD_commandList(const uint8_t *addr) {
+
+  uint8_t  numCommands, numArgs;
+  uint16_t ms;
+
+  numCommands = *addr++;   // Number of commands to follow
+  
+  while(numCommands--) {                 // For each command...
+	QD_writecommand(*addr++); //   Read, issue command
+    numArgs  = *addr++;    //   Number of args to follow
+    ms       = numArgs & DELAY;          //   If hibit set, delay follows args
+    numArgs &= ~DELAY;                   //   Mask out delay bit
+    while(numArgs--) {                   //   For each argument...
+      QD_writedata(*addr++);  //     Read, issue argument
+    }
+    if(ms) {
+      ms = *addr++; // Read post-command delay time (ms)
+      if(ms == 255) ms = 500;     // If 255, delay for 500 ms
+      delay(ms);
+    }
+  }
+}
+
+
+// Initialization code for  QDTech displays
+void ICACHE_FLASH_ATTR QD_commonInit(const uint8_t *cmdList) {
+  colstart  = rowstart = 0; // May be overridden in init func
+
+  easygpio_pinMode(_rs, EASYGPIO_PULLUP, EASYGPIO_OUTPUT);
+  easygpio_pinMode(_cs, EASYGPIO_PULLUP, EASYGPIO_OUTPUT);
+  easygpio_pinMode(_sclk, EASYGPIO_PULLUP, EASYGPIO_OUTPUT);
+  easygpio_pinMode(_sid, EASYGPIO_PULLUP, EASYGPIO_OUTPUT);
+
+    easygpio_outputSet(_sclk,0);
+    easygpio_outputSet(_sid,0);
+
+  // toggle RST low to reset; CS low so it'll listen to us
+  easygpio_outputSet(_cs,0);
+  if (_rst) {
+    easygpio_pinMode(_rst, EASYGPIO_PULLUP, EASYGPIO_OUTPUT);  
+    easygpio_outputSet(_rst,1);
+    delay(500);
+    easygpio_outputSet(_rst,0);
+    delay(500);
+    easygpio_outputSet(_rst,1);
+    delay(500);
+  }
+
+  if(cmdList) QD_commandList(cmdList);
+}
+
+
+
+
+
+void ICACHE_FLASH_ATTR QD_setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1,
+ uint8_t y1) {
+
+  QD_writecommand(QDTech_CASET); // Column addr set
+  QD_writedata(0x00);
+  QD_writedata(x0+colstart);     // XSTART 
+  QD_writedata(0x00);
+  QD_writedata(x1+colstart);     // XEND
+
+  QD_writecommand(QDTech_RASET); // Row addr set
+  QD_writedata(0x00);
+  QD_writedata(y0+rowstart);     // YSTART
+  QD_writedata(0x00);
+  QD_writedata(y1+rowstart);     // YEND
+
+  QD_writecommand(QDTech_RAMWR); // write to RAM
+}
+
+
+void ICACHE_FLASH_ATTR QD_pushColor(uint16_t color) {
+  easygpio_outputSet(_rs,1);	 
+  easygpio_outputSet(_cs,0);
+  QD_spiwrite(color >> 8);
+  QD_spiwrite(color);
+  easygpio_outputSet(_cs,1);
+
+ }
+
+void QD_drawPixel(int16_t x, int16_t y, uint16_t color) {
+
+  if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;
+
+  QD_setAddrWindow(x,y,x+1,y+1);
+  easygpio_outputSet(_rs,1);	 
+  easygpio_outputSet(_cs,0);  
+  QD_spiwrite(color >> 8);
+  QD_spiwrite(color);
+
+  easygpio_outputSet(_cs,1);
+}
+
+void ICACHE_FLASH_ATTR QD_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
+  // Rudimentary clipping
+  if((x >= _width) || (y >= _height)) return;
+  if((y+h-1) >= _height) h = _height-y;
+  QD_setAddrWindow(x, y, x, y+h-1);
+
+  uint8_t hi = color >> 8, lo = color;
+  easygpio_outputSet(_rs,1);	 
+  easygpio_outputSet(_cs,0); 
+
+  while (h--) {
+    QD_spiwrite(hi);
+    QD_spiwrite(lo);
+  }
+  easygpio_outputSet(_cs,1);
+}
+
+
+void ICACHE_FLASH_ATTR QD_drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
+  // Rudimentary clipping
+  if((x >= _width) || (y >= _height)) return;
+  if((x+w-1) >= _width)  w = _width-x;
+  QD_setAddrWindow(x, y, x+w-1, y);
+
+  uint8_t hi = color >> 8, lo = color;
+  easygpio_outputSet(_rs,1);	 
+  easygpio_outputSet(_cs,0); 
+  while (w--) {
+    QD_spiwrite(hi);
+    QD_spiwrite(lo);
+  }
+   easygpio_outputSet(_cs,1);
+}
+
+
+void ICACHE_FLASH_ATTR QD_fillScreen(uint16_t color) {
+  QD_fillRect(0, 0,  _width, _height, color);
+}
+
+
+// fill a rectangle
+void ICACHE_FLASH_ATTR QD_fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
+  uint16_t color) {
+
+  // rudimentary clipping (drawChar w/big text requires this)
+  if((x >= _width) || (y >= _height)) return;
+  if((x + w - 1) >= _width)  w = _width  - x;
+  if((y + h - 1) >= _height) h = _height - y;
+  QD_setAddrWindow(x, y, x+w-1, y+h-1);
+
+  uint8_t hi = color >> 8, lo = color;
+  easygpio_outputSet(_rs,1);	 
+  easygpio_outputSet(_cs,0);
+  for(y=h; y>0; y--) {
+    for(x=w; x>0; x--) {
+      QD_spiwrite(hi);
+      QD_spiwrite(lo);
+    }
+  }
+  easygpio_outputSet(_cs,1);
+}
+
+// Pass 8-bit (each) R,G,B, get back 16-bit packed color
+uint16_t QD_Color565(uint8_t r, uint8_t g, uint8_t b) {
+  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
+}
+
+#define MADCTL_MY  0x80
+#define MADCTL_MX  0x40
+#define MADCTL_MV  0x20
+#define MADCTL_ML  0x10
+#define MADCTL_RGB 0x00
+#define MADCTL_BGR 0x08
+#define MADCTL_MH  0x04
+
+void ICACHE_FLASH_ATTR QD_setRotation(uint8_t m) {
+// Generally 0 - Portrait 1 - Landscape
+
+  QD_writecommand(QDTech_MADCTL);
+  rotation = m % 4; // can't be higher than 3
+  switch (rotation) {
+   case 0:
+     QD_writedata(MADCTL_MX | MADCTL_MY | MADCTL_BGR);
+     _width  = QDTech_TFTWIDTH;
+     _height = QDTech_TFTHEIGHT;
+     break;
+   case 1:
+     QD_writedata(MADCTL_MY | MADCTL_MV | MADCTL_BGR);
+     _width  = QDTech_TFTHEIGHT;
+     _height = QDTech_TFTWIDTH;
+     break;
+  case 2:
+     QD_writedata(MADCTL_BGR);
+     _width  = QDTech_TFTWIDTH;
+     _height = QDTech_TFTHEIGHT;
+    break;
+   case 3:
+//     writedata(MADCTL_MX | MADCTL_MV | MADCTL_RGB);
+     QD_writedata(MADCTL_MX | MADCTL_MV | MADCTL_BGR);
+     _width  = QDTech_TFTHEIGHT;
+     _height = QDTech_TFTWIDTH;
+     break;
+  }
+}
+
+
+void ICACHE_FLASH_ATTR QD_invertDisplay(uint8_t i) {
+  QD_writecommand(i ? QDTech_INVON : QDTech_INVOFF);
+}
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.