Update for NS2009 touch
This commit is contained in:
DanKoloff 2023-04-11 15:18:13 +03:00
parent fca38ce033
commit b5a05fc33c
7 changed files with 1316 additions and 1 deletions

@ -0,0 +1,667 @@
/***************************************************
This is our library for the Adafruit ILI9341 Breakout and Shield
----> http://www.adafruit.com/products/1651
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 "Adafruit_ILI9341.h"
#ifndef ARDUINO_STM32_FEATHER
#include "pins_arduino.h"
#ifndef RASPI
#include "wiring_private.h"
#endif
#endif
#include <limits.h>
#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
/*
* Control Pins
* */
#ifdef USE_FAST_PINIO
#define SPI_DC_HIGH() *dcport |= dcpinmask
#define SPI_DC_LOW() *dcport &= ~dcpinmask
#define SPI_CS_HIGH() *csport |= cspinmask
#define SPI_CS_LOW() *csport &= ~cspinmask
#else
#define SPI_DC_HIGH() digitalWrite(_dc, HIGH)
#define SPI_DC_LOW() digitalWrite(_dc, LOW)
#define SPI_CS_HIGH() digitalWrite(_cs, HIGH)
#define SPI_CS_LOW() digitalWrite(_cs, LOW)
#endif
/*
* Software SPI Macros
* */
#ifdef USE_FAST_PINIO
#define SSPI_MOSI_HIGH() *mosiport |= mosipinmask
#define SSPI_MOSI_LOW() *mosiport &= ~mosipinmask
#define SSPI_SCK_HIGH() *clkport |= clkpinmask
#define SSPI_SCK_LOW() *clkport &= ~clkpinmask
#define SSPI_MISO_READ() ((*misoport & misopinmask) != 0)
#else
#define SSPI_MOSI_HIGH() digitalWrite(_mosi, HIGH)
#define SSPI_MOSI_LOW() digitalWrite(_mosi, LOW)
#define SSPI_SCK_HIGH() digitalWrite(_sclk, HIGH)
#define SSPI_SCK_LOW() digitalWrite(_sclk, LOW)
#define SSPI_MISO_READ() digitalRead(_miso)
#endif
#define SSPI_BEGIN_TRANSACTION()
#define SSPI_END_TRANSACTION()
#define SSPI_WRITE(v) spiWrite(v)
#define SSPI_WRITE16(s) SSPI_WRITE((s) >> 8); SSPI_WRITE(s)
#define SSPI_WRITE32(l) SSPI_WRITE((l) >> 24); SSPI_WRITE((l) >> 16); SSPI_WRITE((l) >> 8); SSPI_WRITE(l)
#define SSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<(l); i+=2){ SSPI_WRITE(((uint8_t*)(c))[i+1]); SSPI_WRITE(((uint8_t*)(c))[i]); }
/*
* Hardware SPI Macros
* */
#ifndef ESP32
#define SPI_OBJECT SPI
#else
#define SPI_OBJECT _spi
#endif
#if defined (__AVR__) || defined(TEENSYDUINO) || defined(ARDUINO_ARCH_STM32F1)
#define HSPI_SET_CLOCK() SPI_OBJECT.setClockDivider(SPI_CLOCK_DIV2);
#elif defined (__arm__)
#define HSPI_SET_CLOCK() SPI_OBJECT.setClockDivider(11);
#elif defined(ESP8266) || defined(ESP32)
#define HSPI_SET_CLOCK() SPI_OBJECT.setFrequency(_freq);
#elif defined(RASPI)
#define HSPI_SET_CLOCK() SPI_OBJECT.setClock(_freq);
#elif defined(ARDUINO_ARCH_STM32F1)
#define HSPI_SET_CLOCK() SPI_OBJECT.setClock(_freq);
#else
#define HSPI_SET_CLOCK()
#endif
#ifdef SPI_HAS_TRANSACTION
#define HSPI_BEGIN_TRANSACTION() SPI_OBJECT.beginTransaction(SPISettings(_freq, MSBFIRST, SPI_MODE0))
#define HSPI_END_TRANSACTION() SPI_OBJECT.endTransaction()
#else
#define HSPI_BEGIN_TRANSACTION() HSPI_SET_CLOCK(); SPI_OBJECT.setBitOrder(MSBFIRST); SPI_OBJECT.setDataMode(SPI_MODE0)
#define HSPI_END_TRANSACTION()
#endif
#ifdef ESP32
#define SPI_HAS_WRITE_PIXELS
#endif
#if defined(ESP8266) || defined(ESP32)
// Optimized SPI (ESP8266 and ESP32)
#define HSPI_READ() SPI_OBJECT.transfer(0)
#define HSPI_WRITE(b) SPI_OBJECT.write(b)
#define HSPI_WRITE16(s) SPI_OBJECT.write16(s)
#define HSPI_WRITE32(l) SPI_OBJECT.write32(l)
#ifdef SPI_HAS_WRITE_PIXELS
#define SPI_MAX_PIXELS_AT_ONCE 32
#define HSPI_WRITE_PIXELS(c,l) SPI_OBJECT.writePixels(c,l)
#else
#define HSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<((l)/2); i++){ SPI_WRITE16(((uint16_t*)(c))[i]); }
#endif
#else
// Standard Byte-by-Byte SPI
#if defined (__AVR__) || defined(TEENSYDUINO)
static inline uint8_t _avr_spi_read(void) __attribute__((always_inline));
static inline uint8_t _avr_spi_read(void) {
uint8_t r = 0;
SPDR = r;
while(!(SPSR & _BV(SPIF)));
r = SPDR;
return r;
}
#define HSPI_WRITE(b) {SPDR = (b); while(!(SPSR & _BV(SPIF)));}
#define HSPI_READ() _avr_spi_read()
#else
#define HSPI_WRITE(b) SPI_OBJECT.transfer((uint8_t)(b))
#define HSPI_READ() HSPI_WRITE(0)
#endif
#define HSPI_WRITE16(s) HSPI_WRITE((s) >> 8); HSPI_WRITE(s)
#define HSPI_WRITE32(l) HSPI_WRITE((l) >> 24); HSPI_WRITE((l) >> 16); HSPI_WRITE((l) >> 8); HSPI_WRITE(l)
#define HSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<(l); i+=2){ HSPI_WRITE(((uint8_t*)(c))[i+1]); HSPI_WRITE(((uint8_t*)(c))[i]); }
#endif
/*
* Final SPI Macros
* */
#if defined (ARDUINO_ARCH_ARC32)
#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
#endif
#define SPI_BEGIN() if(_sclk < 0){SPI_OBJECT.begin();}
#define SPI_BEGIN_TRANSACTION() if(_sclk < 0){HSPI_BEGIN_TRANSACTION();}
#define SPI_END_TRANSACTION() if(_sclk < 0){HSPI_END_TRANSACTION();}
#define SPI_WRITE16(s) if(_sclk < 0){HSPI_WRITE16(s);}else{SSPI_WRITE16(s);}
#define SPI_WRITE32(l) if(_sclk < 0){HSPI_WRITE32(l);}else{SSPI_WRITE32(l);}
#define SPI_WRITE_PIXELS(c,l) if(_sclk < 0){HSPI_WRITE_PIXELS(c,l);}else{SSPI_WRITE_PIXELS(c,l);}
// Pass 8-bit (each) R,G,B, get back 16-bit packed color
uint16_t Adafruit_ILI9341::color565(uint8_t r, uint8_t g, uint8_t b) {
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
}
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t mosi,
int8_t sclk, int8_t rst, int8_t miso) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) {
_cs = cs;
_dc = dc;
_rst = rst;
_sclk = sclk;
_mosi = mosi;
_miso = miso;
_freq = 0;
#ifdef USE_FAST_PINIO
csport = portOutputRegister(digitalPinToPort(_cs));
cspinmask = digitalPinToBitMask(_cs);
dcport = portOutputRegister(digitalPinToPort(_dc));
dcpinmask = digitalPinToBitMask(_dc);
clkport = portOutputRegister(digitalPinToPort(_sclk));
clkpinmask = digitalPinToBitMask(_sclk);
mosiport = portOutputRegister(digitalPinToPort(_mosi));
mosipinmask = digitalPinToBitMask(_mosi);
if(miso >= 0){
misoport = portInputRegister(digitalPinToPort(_miso));
misopinmask = digitalPinToBitMask(_miso);
} else {
misoport = 0;
misopinmask = 0;
}
#endif
}
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) {
_cs = cs;
_dc = dc;
_rst = rst;
_sclk = -1;
_mosi = -1;
_miso = -1;
_freq = 0;
#ifdef USE_FAST_PINIO
csport = portOutputRegister(digitalPinToPort(_cs));
cspinmask = digitalPinToBitMask(_cs);
dcport = portOutputRegister(digitalPinToPort(_dc));
dcpinmask = digitalPinToBitMask(_dc);
clkport = 0;
clkpinmask = 0;
mosiport = 0;
mosipinmask = 0;
misoport = 0;
misopinmask = 0;
#endif
}
#ifdef ESP32
void Adafruit_ILI9341::begin(uint32_t freq, SPIClass &spi)
#else
void Adafruit_ILI9341::begin(uint32_t freq)
#endif
{
#ifdef ESP32
_spi = spi;
#endif
if(!freq){
freq = SPI_DEFAULT_FREQ;
}
_freq = freq;
// Control Pins
pinMode(_dc, OUTPUT);
digitalWrite(_dc, LOW);
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH);
// Software SPI
if(_sclk >= 0){
pinMode(_mosi, OUTPUT);
digitalWrite(_mosi, LOW);
pinMode(_sclk, OUTPUT);
digitalWrite(_sclk, HIGH);
if(_miso >= 0){
pinMode(_miso, INPUT);
}
}
// Hardware SPI
SPI_BEGIN();
pinMode(_dc, OUTPUT);
// toggle RST low to reset
if (_rst >= 0) {
pinMode(_rst, OUTPUT);
digitalWrite(_rst, HIGH);
delay(100);
digitalWrite(_rst, LOW);
delay(100);
digitalWrite(_rst, HIGH);
delay(200);
}
startWrite();
writeCommand(0xEF);
spiWrite(0x03);
spiWrite(0x80);
spiWrite(0x02);
writeCommand(0xCF);
spiWrite(0x00);
spiWrite(0XC1);
spiWrite(0X30);
writeCommand(0xED);
spiWrite(0x64);
spiWrite(0x03);
spiWrite(0X12);
spiWrite(0X81);
writeCommand(0xE8);
spiWrite(0x85);
spiWrite(0x00);
spiWrite(0x78);
writeCommand(0xCB);
spiWrite(0x39);
spiWrite(0x2C);
spiWrite(0x00);
spiWrite(0x34);
spiWrite(0x02);
writeCommand(0xF7);
spiWrite(0x20);
writeCommand(0xEA);
spiWrite(0x00);
spiWrite(0x00);
writeCommand(ILI9341_PWCTR1); //Power control
spiWrite(0x23); //VRH[5:0]
writeCommand(ILI9341_PWCTR2); //Power control
spiWrite(0x10); //SAP[2:0];BT[3:0]
writeCommand(ILI9341_VMCTR1); //VCM control
spiWrite(0x3e);
spiWrite(0x28);
writeCommand(ILI9341_VMCTR2); //VCM control2
spiWrite(0x86); //--
writeCommand(ILI9341_MADCTL); // Memory Access Control
spiWrite(0x48);
writeCommand(ILI9341_VSCRSADD); // Vertical scroll
SPI_WRITE16(0); // Zero
writeCommand(ILI9341_PIXFMT);
spiWrite(0x55);
writeCommand(ILI9341_FRMCTR1);
spiWrite(0x00);
spiWrite(0x18);
writeCommand(ILI9341_DFUNCTR); // Display Function Control
spiWrite(0x08);
spiWrite(0x82);
spiWrite(0x27);
writeCommand(0xF2); // 3Gamma Function Disable
spiWrite(0x00);
writeCommand(ILI9341_GAMMASET); //Gamma curve selected
spiWrite(0x01);
writeCommand(ILI9341_GMCTRP1); //Set Gamma
spiWrite(0x0F);
spiWrite(0x31);
spiWrite(0x2B);
spiWrite(0x0C);
spiWrite(0x0E);
spiWrite(0x08);
spiWrite(0x4E);
spiWrite(0xF1);
spiWrite(0x37);
spiWrite(0x07);
spiWrite(0x10);
spiWrite(0x03);
spiWrite(0x0E);
spiWrite(0x09);
spiWrite(0x00);
writeCommand(ILI9341_GMCTRN1); //Set Gamma
spiWrite(0x00);
spiWrite(0x0E);
spiWrite(0x14);
spiWrite(0x03);
spiWrite(0x11);
spiWrite(0x07);
spiWrite(0x31);
spiWrite(0xC1);
spiWrite(0x48);
spiWrite(0x08);
spiWrite(0x0F);
spiWrite(0x0C);
spiWrite(0x31);
spiWrite(0x36);
spiWrite(0x0F);
writeCommand(ILI9341_SLPOUT); //Exit Sleep
delay(120);
writeCommand(ILI9341_DISPON); //Display on
delay(120);
endWrite();
_width = ILI9341_TFTWIDTH;
_height = ILI9341_TFTHEIGHT;
}
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();
}
void Adafruit_ILI9341::invertDisplay(boolean i) {
startWrite();
writeCommand(i ? ILI9341_INVON : ILI9341_INVOFF);
endWrite();
}
void Adafruit_ILI9341::scrollTo(uint16_t y) {
startWrite();
writeCommand(ILI9341_VSCRSADD);
SPI_WRITE16(y);
endWrite();
}
uint8_t Adafruit_ILI9341::spiRead() {
if(_sclk < 0){
return HSPI_READ();
}
if(_miso < 0){
return 0;
}
uint8_t r = 0;
for (uint8_t i=0; i<8; i++) {
SSPI_SCK_LOW();
SSPI_SCK_HIGH();
r <<= 1;
if (SSPI_MISO_READ()){
r |= 0x1;
}
}
return r;
}
void Adafruit_ILI9341::spiWrite(uint8_t b) {
if(_sclk < 0){
HSPI_WRITE(b);
return;
}
for(uint8_t bit = 0x80; bit; bit >>= 1){
if((b) & bit){
SSPI_MOSI_HIGH();
} else {
SSPI_MOSI_LOW();
}
SSPI_SCK_LOW();
SSPI_SCK_HIGH();
}
}
/*
* Transaction API
* */
void Adafruit_ILI9341::startWrite(void){
SPI_BEGIN_TRANSACTION();
SPI_CS_LOW();
}
void Adafruit_ILI9341::endWrite(void){
SPI_CS_HIGH();
SPI_END_TRANSACTION();
}
void Adafruit_ILI9341::writeCommand(uint8_t cmd){
SPI_DC_LOW();
spiWrite(cmd);
SPI_DC_HIGH();
}
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
}
void Adafruit_ILI9341::pushColor(uint16_t color) {
startWrite();
SPI_WRITE16(color);
endWrite();
}
void Adafruit_ILI9341::writePixel(uint16_t color){
SPI_WRITE16(color);
}
void Adafruit_ILI9341::writePixels(uint16_t * colors, uint32_t len){
SPI_WRITE_PIXELS((uint8_t*)colors , len * 2);
}
void Adafruit_ILI9341::writeColor(uint16_t color, uint32_t len){
#ifdef SPI_HAS_WRITE_PIXELS
if(_sclk >= 0){
for (uint32_t t=0; t<len; t++){
writePixel(color);
}
return;
}
static uint16_t temp[SPI_MAX_PIXELS_AT_ONCE];
size_t blen = (len > SPI_MAX_PIXELS_AT_ONCE)?SPI_MAX_PIXELS_AT_ONCE:len;
uint16_t tlen = 0;
for (uint32_t t=0; t<blen; t++){
temp[t] = color;
}
while(len){
tlen = (len>blen)?blen:len;
writePixels(temp, tlen);
len -= tlen;
}
#else
uint8_t hi = color >> 8, lo = color;
if(_sclk < 0){ //AVR Optimization
for (uint32_t t=len; t; t--){
HSPI_WRITE(hi);
HSPI_WRITE(lo);
}
return;
}
for (uint32_t t=len; t; t--){
spiWrite(hi);
spiWrite(lo);
}
#endif
}
void Adafruit_ILI9341::writePixel(int16_t x, int16_t y, uint16_t color) {
if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;
setAddrWindow(x,y,1,1);
writePixel(color);
}
void Adafruit_ILI9341::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){
if((x >= _width) || (y >= _height)) return;
int16_t x2 = x + w - 1, y2 = y + h - 1;
if((x2 < 0) || (y2 < 0)) return;
// Clip left/top
if(x < 0) {
x = 0;
w = x2 + 1;
}
if(y < 0) {
y = 0;
h = y2 + 1;
}
// Clip right/bottom
if(x2 >= _width) w = _width - x;
if(y2 >= _height) h = _height - y;
int32_t len = (int32_t)w * h;
setAddrWindow(x, y, w, h);
writeColor(color, len);
}
void Adafruit_ILI9341::writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color){
writeFillRect(x, y, 1, h, color);
}
void Adafruit_ILI9341::writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color){
writeFillRect(x, y, w, 1, color);
}
uint8_t Adafruit_ILI9341::readcommand8(uint8_t c, uint8_t index) {
uint32_t freq = _freq;
if(_freq > 24000000){
_freq = 24000000;
}
startWrite();
writeCommand(0xD9); // woo sekret command?
spiWrite(0x10 + index);
writeCommand(c);
uint8_t r = spiRead();
endWrite();
_freq = freq;
return r;
}
void Adafruit_ILI9341::drawPixel(int16_t x, int16_t y, uint16_t color){
startWrite();
writePixel(x, y, color);
endWrite();
}
void Adafruit_ILI9341::drawFastVLine(int16_t x, int16_t y,
int16_t h, uint16_t color) {
startWrite();
writeFastVLine(x, y, h, color);
endWrite();
}
void Adafruit_ILI9341::drawFastHLine(int16_t x, int16_t y,
int16_t w, uint16_t color) {
startWrite();
writeFastHLine(x, y, w, color);
endWrite();
}
void Adafruit_ILI9341::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
uint16_t color) {
startWrite();
writeFillRect(x,y,w,h,color);
endWrite();
}
// Adapted from https://github.com/PaulStoffregen/ILI9341_t3
// by Marc MERLIN. See examples/pictureEmbed to use this.
// 5/6/2017: function name and arguments have changed for compatibility
// with current GFX library and to avoid naming problems in prior
// implementation. Formerly drawBitmap() with arguments in different order.
void Adafruit_ILI9341::drawRGBBitmap(int16_t x, int16_t y,
uint16_t *pcolors, int16_t w, int16_t h) {
int16_t x2, y2; // Lower-right coord
if(( x >= _width ) || // Off-edge right
( y >= _height) || // " top
((x2 = (x+w-1)) < 0 ) || // " left
((y2 = (y+h-1)) < 0) ) return; // " bottom
int16_t bx1=0, by1=0, // Clipped top-left within bitmap
saveW=w; // Save original bitmap width value
if(x < 0) { // Clip left
w += x;
bx1 = -x;
x = 0;
}
if(y < 0) { // Clip top
h += y;
by1 = -y;
y = 0;
}
if(x2 >= _width ) w = _width - x; // Clip right
if(y2 >= _height) h = _height - y; // Clip bottom
pcolors += by1 * saveW + bx1; // Offset bitmap ptr to clipped top-left
startWrite();
setAddrWindow(x, y, w, h); // Clipped area
while(h--) { // For each (clipped) scanline...
writePixels(pcolors, w); // Push one (clipped) row
pcolors += saveW; // Advance pointer by one full (unclipped) line
}
endWrite();
}

@ -0,0 +1,201 @@
/******************************************************************
This is our library for the Adafruit ILI9341 Breakout and Shield
----> http://www.adafruit.com/products/1651
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
*******************************************************************/
#ifndef _ADAFRUIT_ILI9341H_
#define _ADAFRUIT_ILI9341H_
#if ARDUINO >= 100
#include "Arduino.h"
#include "Print.h"
#else
#include "WProgram.h"
#endif
#include <SPI.h>
#include "Adafruit_GFX.h"
#if defined(ARDUINO_STM32_FEATHER)
typedef volatile uint32 RwReg;
#endif
#if defined(ARDUINO_FEATHER52)
typedef volatile uint32_t RwReg;
#endif
#define ILI9341_TFTWIDTH 240
#define ILI9341_TFTHEIGHT 320
#define ILI9341_NOP 0x00
#define ILI9341_SWRESET 0x01
#define ILI9341_RDDID 0x04
#define ILI9341_RDDST 0x09
#define ILI9341_SLPIN 0x10
#define ILI9341_SLPOUT 0x11
#define ILI9341_PTLON 0x12
#define ILI9341_NORON 0x13
#define ILI9341_RDMODE 0x0A
#define ILI9341_RDMADCTL 0x0B
#define ILI9341_RDPIXFMT 0x0C
#define ILI9341_RDIMGFMT 0x0D
#define ILI9341_RDSELFDIAG 0x0F
#define ILI9341_INVOFF 0x20
#define ILI9341_INVON 0x21
#define ILI9341_GAMMASET 0x26
#define ILI9341_DISPOFF 0x28
#define ILI9341_DISPON 0x29
#define ILI9341_CASET 0x2A
#define ILI9341_PASET 0x2B
#define ILI9341_RAMWR 0x2C
#define ILI9341_RAMRD 0x2E
#define ILI9341_PTLAR 0x30
#define ILI9341_MADCTL 0x36
#define ILI9341_VSCRSADD 0x37
#define ILI9341_PIXFMT 0x3A
#define ILI9341_FRMCTR1 0xB1
#define ILI9341_FRMCTR2 0xB2
#define ILI9341_FRMCTR3 0xB3
#define ILI9341_INVCTR 0xB4
#define ILI9341_DFUNCTR 0xB6
#define ILI9341_PWCTR1 0xC0
#define ILI9341_PWCTR2 0xC1
#define ILI9341_PWCTR3 0xC2
#define ILI9341_PWCTR4 0xC3
#define ILI9341_PWCTR5 0xC4
#define ILI9341_VMCTR1 0xC5
#define ILI9341_VMCTR2 0xC7
#define ILI9341_RDID1 0xDA
#define ILI9341_RDID2 0xDB
#define ILI9341_RDID3 0xDC
#define ILI9341_RDID4 0xDD
#define ILI9341_GMCTRP1 0xE0
#define ILI9341_GMCTRN1 0xE1
/*
#define ILI9341_PWCTR6 0xFC
*/
// Color definitions
#define ILI9341_BLACK 0x0000 /* 0, 0, 0 */
#define ILI9341_NAVY 0x000F /* 0, 0, 128 */
#define ILI9341_DARKGREEN 0x03E0 /* 0, 128, 0 */
#define ILI9341_DARKCYAN 0x03EF /* 0, 128, 128 */
#define ILI9341_MAROON 0x7800 /* 128, 0, 0 */
#define ILI9341_PURPLE 0x780F /* 128, 0, 128 */
#define ILI9341_OLIVE 0x7BE0 /* 128, 128, 0 */
#define ILI9341_LIGHTGREY 0xC618 /* 192, 192, 192 */
#define ILI9341_DARKGREY 0x7BEF /* 128, 128, 128 */
#define ILI9341_BLUE 0x001F /* 0, 0, 255 */
#define ILI9341_GREEN 0x07E0 /* 0, 255, 0 */
#define ILI9341_CYAN 0x07FF /* 0, 255, 255 */
#define ILI9341_RED 0xF800 /* 255, 0, 0 */
#define ILI9341_MAGENTA 0xF81F /* 255, 0, 255 */
#define ILI9341_YELLOW 0xFFE0 /* 255, 255, 0 */
#define ILI9341_WHITE 0xFFFF /* 255, 255, 255 */
#define ILI9341_ORANGE 0xFD20 /* 255, 165, 0 */
#define ILI9341_GREENYELLOW 0xAFE5 /* 173, 255, 47 */
#define ILI9341_PINK 0xF81F
#if defined (__AVR__) || defined(TEENSYDUINO) || defined(ESP8266) || defined (ESP32) || defined(__arm__)
#define USE_FAST_PINIO
#endif
class Adafruit_ILI9341 : public Adafruit_GFX {
protected:
public:
Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK, int8_t _RST = -1, int8_t _MISO = -1);
Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _RST = -1);
#ifndef ESP32
void begin(uint32_t freq = 0);
#else
void begin(uint32_t freq = 0, SPIClass &spi=SPI);
#endif
void setRotation(uint8_t r);
void invertDisplay(boolean i);
void scrollTo(uint16_t y);
// Required Non-Transaction
void drawPixel(int16_t x, int16_t y, uint16_t color);
// Transaction API
void startWrite(void);
void endWrite(void);
void writePixel(int16_t x, int16_t y, uint16_t color);
void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
// Transaction API not used by GFX
void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
void writePixel(uint16_t color);
void writePixels(uint16_t * colors, uint32_t len);
void writeColor(uint16_t color, uint32_t len);
void pushColor(uint16_t color);
// Recommended Non-Transaction
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
using Adafruit_GFX::drawRGBBitmap; // Check base class first
void drawRGBBitmap(int16_t x, int16_t y,
uint16_t *pcolors, int16_t w, int16_t h);
uint8_t readcommand8(uint8_t reg, uint8_t index = 0);
uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
private:
#ifdef ESP32
SPIClass _spi;
#endif
uint32_t _freq;
#if defined (__AVR__) || defined(TEENSYDUINO)
int8_t _cs, _dc, _rst, _sclk, _mosi, _miso;
#ifdef USE_FAST_PINIO
volatile uint8_t *mosiport, *misoport, *clkport, *dcport, *csport;
uint8_t mosipinmask, misopinmask, clkpinmask, cspinmask, dcpinmask;
#endif
#elif defined (__arm__)
int32_t _cs, _dc, _rst, _sclk, _mosi, _miso;
#ifdef USE_FAST_PINIO
typedef volatile uint32_t RwReg;
volatile RwReg *mosiport, *misoport, *clkport, *dcport, *csport;
uint32_t mosipinmask, misopinmask, clkpinmask, cspinmask, dcpinmask;
#endif
#elif defined (ESP8266) || defined (ESP32)
int8_t _cs, _dc, _rst, _sclk, _mosi, _miso;
#ifdef USE_FAST_PINIO
volatile uint32_t *mosiport, *misoport, *clkport, *dcport, *csport;
uint32_t mosipinmask, misopinmask, clkpinmask, cspinmask, dcpinmask;
#endif
#else
int8_t _cs, _dc, _rst, _sclk, _mosi, _miso;
#endif
void writeCommand(uint8_t cmd);
void spiWrite(uint8_t v);
uint8_t spiRead(void);
};
#endif

@ -0,0 +1,52 @@
#ifndef _BOARD_PINOUT_H
#define _BOARD_PINOUT_H
#if (defined ARDUINO_ESP32_POE) || (defined ARDUINO_ESP32_POE_ISO)
// This is pinouts for ESP32-PoE(-ISO)
#define TFT_DC 15
#define TFT_CS 5
#define TFT_MOSI 2
#define TFT_CLK 14
#elif defined ARDUINO_ESP32_EVB
// This is pinouts for ESP32-EVB
#define TFT_DC 15
#define TFT_CS 17
#define TFT_MOSI 2
#define TFT_CLK 14
#elif defined ARDUINO_AVR_OLIMEXINO_2560
// This is pinouts for Olimexino 2560
// Important!!! If using UEXT connector you need
// to UEXT Connect p34 to p50 with a wire !!!
#warning If display is connected to UEXT Connect p34 to p50 with a wire !!!
#define TFT_DC 34
#define TFT_CS 53
#define TFT_MOSI 51
#define TFT_CLK 52
#define TFT_BKL 0
#elif defined ARDUINO_AVR_MEGA2560
#warning You need to connect the respective SPI and I2C pins to the AVR_MEGA256
#define TFT_DC 34
#define TFT_CS 53
#define TFT_MOSI 51
#define TFT_CLK 52
#define TFT_BKL 0
#elif defined ARDUINO_OLIMEXINO_STM32F3
#define TFT_DC 12
#define TFT_CS 4
#define TFT_MOSI 11
#define TFT_CLK 13
#define TFT_MISO -1
#define TFT_RST -1
#else
#error This demo does not support selected board.
#define TFT_DC 0
#define TFT_CS 0
#define TFT_MOSI 0
#define TFT_CLK 0
#define TFT_BKL 0
#endif
#endif // #ifndef _BOARD_PINOUT_H

@ -0,0 +1,124 @@
#include <Wire.h>
#include <Arduino.h>
#include "NS2009.h"
int Map_Data (int Data, int InMin, int InMax, int OutMin, int OutMax)
{
if (Data < InMin)
Data = InMin;
if (Data > InMax)
Data = InMax;
return ((Data-InMin)*(OutMax-OutMin))/(InMax-InMin)+OutMin;
}
NS2009::NS2009 (void)
{
Address = DEFAULT_NS2009_ADDR;
FlipX = false;
FlipY = false;
}
NS2009::NS2009 (unsigned char _Address)
{
Address = _Address;
FlipX = false;
FlipY = false;
}
NS2009::NS2009 (bool _FlipX, bool _FlipY)
{
Address = DEFAULT_NS2009_ADDR;
FlipX = _FlipX;
FlipY = _FlipY;
}
NS2009::NS2009 (unsigned char _Address, bool _FlipX, bool _FlipY)
{
Address = _Address;
FlipX = _FlipX;
FlipY = _FlipY;
}
unsigned int NS2009::ReadRegister (unsigned char Command)
{
unsigned char ReadData[2], i=0;
Wire.beginTransmission(Address);
Wire.write(&Command, 1);
Wire.endTransmission();
Wire.requestFrom(Address, 2);
while (Wire.available())
ReadData[i++] = Wire.read();
return (ReadData[0] << 4) | (ReadData[1] >> 4);
}
void NS2009::Calibrate ()
{
int P1X, P1Y, P2X, P2Y;
Serial.println ("Touch corner of the screen\n\r");
ScanBlocking ();
P1X = RawX;
P1Y = RawY;
Serial.println ("Touch registered! Touch an opposite corner!\n\r");
while (CheckTouched ());
// opposite corner
ScanBlocking ();
P2X = RawX;
P2Y = RawY;
Serial.println ("Second touch registered!\n\r");
while (CheckTouched ());
MinX = MIN(P1X, P2X);
MaxX = MAX(P1X, P2X);
MinY = MIN(P1Y, P2Y);
MaxY = MAX(P1Y, P2Y);
}
void NS2009::Calibrate (int _MinX, int _MaxX, int _MinY, int _MaxY)
{
MinX = _MinX;
MaxX = _MaxX;
MinY = _MinY;
MaxY = _MaxY;
}
bool NS2009::CheckTouched ()
{
do
{
RawZ = ReadRegister(NS2009_READ_Z);
}
while (RawZ == 0xFFF); // sometimes the I2C reading gives a false positive by returning only ones ==> 0xFFF = 4095
Touched = (RawZ > THRESHOLD_Z);
return Touched;
}
void NS2009::Scan ()
{
CheckTouched ();
RawX = ReadRegister(NS2009_READ_X);
X = Map_Data (RawX, MinX, MaxX, 0, SCREEN_SIZE_X);
RawY = ReadRegister(NS2009_READ_Y);
Y = Map_Data (RawY, MinY, MaxY, 0, SCREEN_SIZE_Y);
if (FlipX)
X = SCREEN_SIZE_X - X;
if (FlipY)
Y = SCREEN_SIZE_Y - Y;
}
void NS2009::ScanBlocking ()
{
do
{
CheckTouched ();
}
while (!Touched);
RawX = ReadRegister(NS2009_READ_X);
X = Map_Data (RawX, MinX, MaxX, 0, SCREEN_SIZE_X);
RawY = ReadRegister(NS2009_READ_Y);
Y = Map_Data (RawY, MinY, MaxY, 0, SCREEN_SIZE_Y);
if (FlipX)
X = SCREEN_SIZE_X - X;
if (FlipY)
Y = SCREEN_SIZE_Y - Y;
}

@ -0,0 +1,41 @@
#ifndef _NS2009_H_
#define _NS2009_H_
#define DEFAULT_NS2009_ADDR 0x48 //10010000
#define THRESHOLD_Z 150 // this is a sensitivity threshold value on how hard the touch screen must be touched to react
#define NS2009_READ_X 0xC0
#define NS2009_READ_Y 0xD0
#define NS2009_READ_Z 0xE0
#define CALIBRATE_MIN_X 200
#define CALIBRATE_MIN_Y 400
#define CALIBRATE_MAX_X 3850
#define CALIBRATE_MAX_Y 3920
#define SCREEN_SIZE_X 240
#define SCREEN_SIZE_Y 320
#define MIN(A,B) (A<B?A:B)
#define MAX(A,B) (A>B?A:B)
class NS2009
{
int Address, MinX=CALIBRATE_MIN_X, MinY=CALIBRATE_MIN_Y, MaxX=CALIBRATE_MAX_X, MaxY=CALIBRATE_MAX_Y;
bool FlipX, FlipY;
unsigned int ReadRegister (unsigned char Command);
public:
int RawX, X, RawY, Y, RawZ;
bool Touched;
NS2009 (void);
NS2009 (unsigned char _Address);
NS2009 (bool _FlipX, bool _FlipY);
NS2009 (unsigned char _Address, bool _FlipX, bool _FlipY);
void Calibrate ();
void Calibrate (int _MinX, int _MaxX, int _MinY, int _MaxY);
bool CheckTouched ();
void Scan ();
void ScanBlocking ();
};
#endif

@ -0,0 +1,224 @@
/***************************************************
This is an example made by Adafruit and modifed by Olimex for MOD-LCD2.8RTP
This demo was tested with Olimex MOD-LCD2.8RTP and ESP32-EVB.
The boards were connected via UEXT connector and cable.
Make sure to establish proper hardware connections with your board.
The display requires SPI, the touschreen I2C. Refer to Board_Pinout.h.
The original example is a GFX example for the Adafruit ILI9341 Breakout and Shield
----> http://www.adafruit.com/products/1651
Check out the link above for Adafruit's 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 the 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
****************************************************/
// In order to work you have to install Adafruit GFX Library
// To do so go to:
// Main menu --> Sketch --> Inlcude Librariy --> Manage Libraries...
// In the search box filter "Adafruit GFX Library" and install it
// Tested with version 1.2.3 of the library
#include "Wire.h"
#include "Board_Pinout.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include "NS2009.h"
#ifdef ARDUINO_OLIMEXINO_STM32F3
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
#else
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
#endif
#define MODE_DRAW_PIXELS 0
#define MODE_DRAW_RECTANGLE 1
#define MODE_DRAW_CIRCLE 2
#define TEXT_HEIGHT 8
#define TEXT_WIDTH 6
NS2009 TS(false, true);
int Mode=MODE_DRAW_PIXELS, ActiveColor = ILI9341_WHITE;
void Print_Text (int X, int Y, int TextColor, int TextSize, char Text[])
{
tft.setCursor(X, Y);
tft.setTextColor(TextColor);
tft.setTextSize(TextSize);
tft.println(Text);
}
void Print_Text_In_Box (int X, int Y, int W, int H, int TextColor, int TextSize, char Text[])
{
int Len = strlen (Text)*TEXT_WIDTH;
Print_Text (X+(W-Len)/2, Y+(H-TEXT_HEIGHT)/2, TextColor, TextSize, Text);
}
void Draw_Outlined_Rectangle(int X, int Y, int W, int H, int OutlineColor, int InsideColor)
{
tft.fillRoundRect (X, Y, W, H, 0, InsideColor);
tft.drawRoundRect (X, Y, W, H, 0, OutlineColor);
}
void Draw_Palette ()
{
Draw_Outlined_Rectangle ( 0, 0, 30, 30, ILI9341_BLACK, ILI9341_WHITE);
Draw_Outlined_Rectangle ( 30, 0, 30, 30, ILI9341_BLACK, ILI9341_RED);
Draw_Outlined_Rectangle ( 60, 0, 30, 30, ILI9341_BLACK, ILI9341_YELLOW);
Draw_Outlined_Rectangle ( 90, 0, 30, 30, ILI9341_BLACK, ILI9341_GREEN);
Draw_Outlined_Rectangle (120, 0, 30, 30, ILI9341_BLACK, ILI9341_CYAN);
Draw_Outlined_Rectangle (150, 0, 30, 30, ILI9341_BLACK, ILI9341_BLUE);
Draw_Outlined_Rectangle (180, 0, 30, 30, ILI9341_BLACK, ILI9341_MAGENTA);
Draw_Outlined_Rectangle (210, 0, 30, 30, ILI9341_BLACK, ILI9341_BLACK);
}
void Draw_ActiveColor ()
{
// active color
Draw_Outlined_Rectangle ( 0, 30, 240, 30, ILI9341_BLACK, ActiveColor);
Print_Text_In_Box ( 0, 30, 240, 30, ~ActiveColor, 1, "Fill Screen");
}
void Draw_Modes ()
{
// modes
Draw_Outlined_Rectangle ( 0, 60, 80, 30, ILI9341_BLACK, ILI9341_LIGHTGREY);
Print_Text_In_Box ( 0, 60, 80, 30, ILI9341_BLACK, 1, "Pixel");
Draw_Outlined_Rectangle ( 80, 60, 80, 30, ILI9341_BLACK, ILI9341_DARKCYAN);
Print_Text_In_Box ( 80, 60, 80, 30, ILI9341_BLACK, 1, "Rectangle");
Draw_Outlined_Rectangle (160, 60, 80, 30, ILI9341_BLACK, ILI9341_ORANGE);
Print_Text_In_Box (160, 60, 80, 30, ILI9341_BLACK, 1, "Circle");
// outline the active mode
tft.drawFastHLine ( 0, 90, 240, ILI9341_BLACK);
switch (Mode)
{
case MODE_DRAW_PIXELS:
tft.drawRoundRect ( 0, 60, 80, 30, 0, ILI9341_WHITE);
Serial.printf ("Drawing pixels option selected!\n\r");
break;
case MODE_DRAW_RECTANGLE:
tft.drawRoundRect ( 80, 60, 80, 30, 0, ILI9341_WHITE);
Serial.printf ("Drawing a rectangle option selected!\n\r");
break;
case MODE_DRAW_CIRCLE:
tft.drawRoundRect (160, 60, 80, 30, 0, ILI9341_WHITE);
Serial.printf ("Drawing a circle option selected!\n\r");
break;
}
}
void Draw_Frame ()
{
Draw_Palette ();
Draw_ActiveColor ();
Draw_Modes ();
}
void Handle_Touch ()
{
if (TS.Y<90) // frame area
{
if (TS.Y<30) // palette area
{
if (TS.X< 30) // white color area
ActiveColor = ILI9341_WHITE;
else if (TS.X< 60) // red color area
ActiveColor = ILI9341_RED;
else if (TS.X< 90) // yellow color area
ActiveColor = ILI9341_YELLOW;
else if (TS.X<120) // green color area
ActiveColor = ILI9341_GREEN;
else if (TS.X<150) // cyan color area
ActiveColor = ILI9341_CYAN;
else if (TS.X<180) // blue color area
ActiveColor = ILI9341_BLUE;
else if (TS.X<210) // magenta color area
ActiveColor = ILI9341_MAGENTA;
else if (TS.X<240) // black color area
ActiveColor = ILI9341_BLACK;
Draw_ActiveColor ();
Serial.printf ("New color selected!\n\r");
}
else if (TS.Y<60) // fill screen area
{
tft.fillRoundRect (0, 90, 240, 230, 0, ActiveColor);
Serial.printf ("Screen area filled with the selected color!\n\r");
}
else if (TS.Y<90) // mode area
{
if (TS.X < 80) // pixel mode area
Mode = MODE_DRAW_PIXELS;
else if (TS.X < 160) // rectangle mode area
Mode = MODE_DRAW_RECTANGLE;
else if (TS.X < 240) // circle mode area
Mode = MODE_DRAW_CIRCLE;
Draw_Modes ();
}
}
else // drawing area
{
int PX=TS.X, PY=TS.Y, R;
switch (Mode)
{
case MODE_DRAW_PIXELS:
while (TS.Touched)
{
if (TS.Y>=90)
{
tft.drawPixel (TS.X, TS.Y, ActiveColor);
Serial.printf ("Drawn pixel at %d %d!\n\r", TS.X, TS.Y);
}
else
Serial.printf ("Invalid coordinates!\n\r", TS.X, TS.Y);
TS.Scan();
}
break;
case MODE_DRAW_RECTANGLE:
Serial.printf ("First corner of the rectangle is at %d %d. Touch to again to point the opposite corner!\n\r", TS.X, TS.Y);
while (TS.CheckTouched ());
TS.ScanBlocking ();
tft.fillRoundRect (min(PX, TS.X), min(PY, TS.Y), abs(TS.X-PX), abs(TS.Y-PY), 0, ActiveColor);
Draw_Frame ();
Serial.printf ("Rectangle drawn!\n\r");
break;
case MODE_DRAW_CIRCLE:
Serial.printf ("Center of the circle is at %d %d. Touch to again to point a point of the circle!\n\r", TS.X, TS.Y);
while (TS.CheckTouched ());
TS.ScanBlocking ();
R = sqrt( (PX-TS.X) * (PX-TS.X) + (PY-TS.Y) * (PY-TS.Y) );
tft.drawCircle (PX, PY, R, ActiveColor);
Draw_Frame ();
Serial.printf ("Circle drawn!\n\r");
break;
};
}
}
void setup()
{
Serial.begin (115200);
Wire.begin();
pinMode(TFT_DC, OUTPUT);
tft.begin();
tft.fillScreen(ILI9341_WHITE);
Draw_Frame ();
}
void loop ()
{
TS.ScanBlocking ();
Serial.printf ("Screen touched!\n\r");
Handle_Touch ();
while (TS.CheckTouched ());
Serial.printf ("Screen released!\n\r");
}

@ -2,9 +2,15 @@
Tested with Olimex boards - OLIMEXINO-2560, OLIMEXINO-STM32F3, and Olimex ESP32 boards (Olimex ESP32-EVB, ESP32-POE, ESP32-POE-ISO). Refer to the comments in the .ino sketch - make sure to download all the files (library and header files; and not just the .ino).
Folder "graphicstest_olimex_NS2009" contains demo for NS2009 touchscreen.
Folder "graphicstest_olimex" contains demo for STMPE610 touchscreen component.
Basically if touch is not working try the demo in the other folder.
If you use the demo with an ESP32 boards remember to prepare your Arduino IDE environment according to the arduino for ESP32 repository here: https://github.com/espressif/arduino-esp32#installation-instructions
NOTE OTHER BOARDS: You might need to edit the pins in board_pinout.h - for example, if you use ESP32-POE instead of ESP32-EVB, you need to change TFT_CS from 17 to 5 (since ESP32-POE uses pin #5 for chip select).
NOTE: You might need to edit the pins in board_pinout.h - for example, if you use ESP32-POE instead of ESP32-EVB, you need to change TFT_CS from 17 to 5 (since ESP32-POE uses pin #5 for chip select).
##PlatformIO example: