mirror of
https://github.com/adafruit/TFTLCD-Library.git
synced 2026-09-13 18:13:06 +00:00
Compare commits
70
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bed0a09f54 | ||
|
|
67a3652b26 | ||
|
|
4a07aa2b42 | ||
|
|
07b5fb3f10 | ||
|
|
a8bf039fa7 | ||
|
|
d019918913 | ||
|
|
d8f88e76a4 | ||
|
|
2b2727074e | ||
|
|
2f61770de5 | ||
|
|
ffce7315b6 | ||
|
|
2926bacdbc | ||
|
|
b229812d29 | ||
|
|
e4b0fa892d | ||
|
|
f74dd70f2c | ||
|
|
4e398c8eef | ||
|
|
a857c4960f | ||
|
|
d44a453e17 | ||
|
|
2938be3d5a | ||
|
|
5cb1161bf8 | ||
|
|
73f030d62e | ||
|
|
10e5109e61 | ||
|
|
936e71a5f0 | ||
|
|
450a1929d9 | ||
|
|
ca4b16ac34 | ||
|
|
ce39dff490 | ||
|
|
7167fc5a02 | ||
|
|
df86262987 | ||
|
|
f891b23d38 | ||
|
|
33ad503675 | ||
|
|
418ae2f913 | ||
|
|
7838b6dad8 | ||
|
|
949444204d | ||
|
|
115fc817ef | ||
|
|
8566cff258 | ||
|
|
41f69a0d66 | ||
|
|
164456f6f5 | ||
|
|
59e176c21a | ||
|
|
3bc51273a2 | ||
|
|
934226e5d2 | ||
|
|
afe10512ab | ||
|
|
18f10bb713 | ||
|
|
b20c0ea119 | ||
|
|
c97a399067 | ||
|
|
3090da8b2f | ||
|
|
d0854b30db | ||
|
|
d723ae0eb9 | ||
|
|
8ed1df7bea | ||
|
|
23f92b31a1 | ||
|
|
d06df75d29 | ||
|
|
409ee5e8c4 | ||
|
|
c792899657 | ||
|
|
ae8c502f61 | ||
|
|
f6d0a609e2 | ||
|
|
8fb4cda17b | ||
|
|
9f29d4fc3e | ||
|
|
301e179fde | ||
|
|
e068240057 | ||
|
|
f9a3d8c3f0 | ||
|
|
f56b15bede | ||
|
|
d62573ff58 | ||
|
|
d47f6ec8d0 | ||
|
|
6499cc904b | ||
|
|
ff3d3c7d39 | ||
|
|
706b8f2882 | ||
|
|
d81eb3cade | ||
|
|
20c0851274 | ||
|
|
2eb12095df | ||
|
|
6e8edf0202 | ||
|
|
adbdc7b8db | ||
|
|
68a8afecd3 |
@@ -0,0 +1,984 @@
|
||||
// IMPORTANT: LIBRARY MUST BE SPECIFICALLY CONFIGURED FOR EITHER TFT SHIELD
|
||||
// OR BREAKOUT BOARD USAGE. SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h
|
||||
|
||||
// Graphics library by ladyada/adafruit with init code from Rossum
|
||||
// MIT license
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
#include <include/pio.h>
|
||||
#define PROGMEM
|
||||
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
||||
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
|
||||
#endif
|
||||
#ifdef __AVR__
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
#include "pins_arduino.h"
|
||||
#include "wiring_private.h"
|
||||
#include "Adafruit_TFTLCD.h"
|
||||
#include "pin_magic.h"
|
||||
|
||||
#define TFTWIDTH 240
|
||||
#define TFTHEIGHT 320
|
||||
|
||||
// LCD controller chip identifiers
|
||||
#define ID_932X 0
|
||||
#define ID_7575 1
|
||||
#define ID_9341 2
|
||||
#define ID_UNKNOWN 0xFF
|
||||
|
||||
// Register names from Peter Barrett's Microtouch code
|
||||
#define ILI932X_START_OSC 0x00
|
||||
#define ILI932X_DRIV_OUT_CTRL 0x01
|
||||
#define ILI932X_DRIV_WAV_CTRL 0x02
|
||||
#define ILI932X_ENTRY_MOD 0x03
|
||||
#define ILI932X_RESIZE_CTRL 0x04
|
||||
#define ILI932X_DISP_CTRL1 0x07
|
||||
#define ILI932X_DISP_CTRL2 0x08
|
||||
#define ILI932X_DISP_CTRL3 0x09
|
||||
#define ILI932X_DISP_CTRL4 0x0A
|
||||
#define ILI932X_RGB_DISP_IF_CTRL1 0x0C
|
||||
#define ILI932X_FRM_MARKER_POS 0x0D
|
||||
#define ILI932X_RGB_DISP_IF_CTRL2 0x0F
|
||||
#define ILI932X_POW_CTRL1 0x10
|
||||
#define ILI932X_POW_CTRL2 0x11
|
||||
#define ILI932X_POW_CTRL3 0x12
|
||||
#define ILI932X_POW_CTRL4 0x13
|
||||
#define ILI932X_GRAM_HOR_AD 0x20
|
||||
#define ILI932X_GRAM_VER_AD 0x21
|
||||
#define ILI932X_RW_GRAM 0x22
|
||||
#define ILI932X_POW_CTRL7 0x29
|
||||
#define ILI932X_FRM_RATE_COL_CTRL 0x2B
|
||||
#define ILI932X_GAMMA_CTRL1 0x30
|
||||
#define ILI932X_GAMMA_CTRL2 0x31
|
||||
#define ILI932X_GAMMA_CTRL3 0x32
|
||||
#define ILI932X_GAMMA_CTRL4 0x35
|
||||
#define ILI932X_GAMMA_CTRL5 0x36
|
||||
#define ILI932X_GAMMA_CTRL6 0x37
|
||||
#define ILI932X_GAMMA_CTRL7 0x38
|
||||
#define ILI932X_GAMMA_CTRL8 0x39
|
||||
#define ILI932X_GAMMA_CTRL9 0x3C
|
||||
#define ILI932X_GAMMA_CTRL10 0x3D
|
||||
#define ILI932X_HOR_START_AD 0x50
|
||||
#define ILI932X_HOR_END_AD 0x51
|
||||
#define ILI932X_VER_START_AD 0x52
|
||||
#define ILI932X_VER_END_AD 0x53
|
||||
#define ILI932X_GATE_SCAN_CTRL1 0x60
|
||||
#define ILI932X_GATE_SCAN_CTRL2 0x61
|
||||
#define ILI932X_GATE_SCAN_CTRL3 0x6A
|
||||
#define ILI932X_PART_IMG1_DISP_POS 0x80
|
||||
#define ILI932X_PART_IMG1_START_AD 0x81
|
||||
#define ILI932X_PART_IMG1_END_AD 0x82
|
||||
#define ILI932X_PART_IMG2_DISP_POS 0x83
|
||||
#define ILI932X_PART_IMG2_START_AD 0x84
|
||||
#define ILI932X_PART_IMG2_END_AD 0x85
|
||||
#define ILI932X_PANEL_IF_CTRL1 0x90
|
||||
#define ILI932X_PANEL_IF_CTRL2 0x92
|
||||
#define ILI932X_PANEL_IF_CTRL3 0x93
|
||||
#define ILI932X_PANEL_IF_CTRL4 0x95
|
||||
#define ILI932X_PANEL_IF_CTRL5 0x97
|
||||
#define ILI932X_PANEL_IF_CTRL6 0x98
|
||||
|
||||
#define HX8347G_COLADDRSTART_HI 0x02
|
||||
#define HX8347G_COLADDRSTART_LO 0x03
|
||||
#define HX8347G_COLADDREND_HI 0x04
|
||||
#define HX8347G_COLADDREND_LO 0x05
|
||||
#define HX8347G_ROWADDRSTART_HI 0x06
|
||||
#define HX8347G_ROWADDRSTART_LO 0x07
|
||||
#define HX8347G_ROWADDREND_HI 0x08
|
||||
#define HX8347G_ROWADDREND_LO 0x09
|
||||
#define HX8347G_MEMACCESS 0x16
|
||||
|
||||
#define ILI9341_SOFTRESET 0x01
|
||||
#define ILI9341_SLEEPIN 0x10
|
||||
#define ILI9341_SLEEPOUT 0x11
|
||||
#define ILI9341_NORMALDISP 0x13
|
||||
#define ILI9341_INVERTOFF 0x20
|
||||
#define ILI9341_INVERTON 0x21
|
||||
#define ILI9341_GAMMASET 0x26
|
||||
#define ILI9341_DISPLAYOFF 0x28
|
||||
#define ILI9341_DISPLAYON 0x29
|
||||
#define ILI9341_COLADDRSET 0x2A
|
||||
#define ILI9341_PAGEADDRSET 0x2B
|
||||
#define ILI9341_MEMORYWRITE 0x2C
|
||||
#define ILI9341_PIXELFORMAT 0x3A
|
||||
#define ILI9341_FRAMECONTROL 0xB1
|
||||
#define ILI9341_DISPLAYFUNC 0xB6
|
||||
#define ILI9341_ENTRYMODE 0xB7
|
||||
#define ILI9341_POWERCONTROL1 0xC0
|
||||
#define ILI9341_POWERCONTROL2 0xC1
|
||||
#define ILI9341_VCOMCONTROL1 0xC5
|
||||
#define ILI9341_VCOMCONTROL2 0xC7
|
||||
#define ILI9341_MEMCONTROL 0x36
|
||||
|
||||
// Constructor for breakout board (configurable LCD control lines).
|
||||
// Can still use this w/shield, but parameters are ignored.
|
||||
Adafruit_TFTLCD::Adafruit_TFTLCD(
|
||||
uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t rst) :
|
||||
Adafruit_GFX(TFTWIDTH, TFTHEIGHT) {
|
||||
setup(cs, cd, wr, rd, rst);
|
||||
}
|
||||
|
||||
// Constructor for shield (fixed LCD control lines)
|
||||
Adafruit_TFTLCD::Adafruit_TFTLCD(void) : Adafruit_GFX(TFTWIDTH, TFTHEIGHT) {
|
||||
init();
|
||||
}
|
||||
|
||||
void Adafruit_TFTLCD::setup(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t rst)
|
||||
{
|
||||
#ifndef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
// Convert pin numbers to registers and bitmasks
|
||||
_reset = rst;
|
||||
#ifdef __AVR__
|
||||
#if defined(CORE_ADAX) || defined(VARIANT_MICROTOUCHX)
|
||||
csPort = (uint8_t*)portRegister(digitalPinToPort(cs));
|
||||
cdPort = (uint8_t*)portRegister(digitalPinToPort(cd));
|
||||
wrPort = (uint8_t*)portRegister(digitalPinToPort(wr));
|
||||
rdPort = (uint8_t*)portRegister(digitalPinToPort(rd));
|
||||
#else
|
||||
csPort = portOutputRegister(digitalPinToPort(cs));
|
||||
cdPort = portOutputRegister(digitalPinToPort(cd));
|
||||
wrPort = portOutputRegister(digitalPinToPort(wr));
|
||||
rdPort = portOutputRegister(digitalPinToPort(rd));
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__SAM3X8E__)
|
||||
csPort = digitalPinToPort(cs);
|
||||
cdPort = digitalPinToPort(cd);
|
||||
wrPort = digitalPinToPort(wr);
|
||||
rdPort = digitalPinToPort(rd);
|
||||
#endif
|
||||
|
||||
csPinSet = digitalPinToBitMask(cs);
|
||||
cdPinSet = digitalPinToBitMask(cd);
|
||||
wrPinSet = digitalPinToBitMask(wr);
|
||||
rdPinSet = digitalPinToBitMask(rd);
|
||||
csPinUnset = ~csPinSet;
|
||||
cdPinUnset = ~cdPinSet;
|
||||
wrPinUnset = ~wrPinSet;
|
||||
rdPinUnset = ~rdPinSet;
|
||||
|
||||
#ifdef __AVR__
|
||||
pinMode(cs, OUTPUT);
|
||||
pinMode(cd, OUTPUT);
|
||||
pinMode(wr, OUTPUT);
|
||||
pinMode(rd, OUTPUT);
|
||||
digitalWrite(cs, HIGH);
|
||||
digitalWrite(cd, HIGH);
|
||||
digitalWrite(wr, HIGH);
|
||||
digitalWrite(rd, HIGH);
|
||||
#endif
|
||||
#if defined(__SAM3X8E__)
|
||||
csPort->PIO_SODR |= csPinSet; // Set all control bits to HIGH (idle)
|
||||
cdPort->PIO_SODR |= cdPinSet; // Signals are ACTIVE LOW
|
||||
wrPort->PIO_SODR |= wrPinSet;
|
||||
rdPort->PIO_SODR |= rdPinSet;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
// Initialization common to both shield & breakout configs
|
||||
void Adafruit_TFTLCD::init(void) {
|
||||
|
||||
#ifdef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
CS_IDLE; // Set all control bits to idle state
|
||||
WR_IDLE;
|
||||
RD_IDLE;
|
||||
CD_DATA;
|
||||
digitalWrite(5, HIGH); // Reset line
|
||||
pinMode(A3, OUTPUT); // Enable outputs
|
||||
pinMode(A2, OUTPUT);
|
||||
pinMode(A1, OUTPUT);
|
||||
pinMode(A0, OUTPUT);
|
||||
pinMode( 5, OUTPUT);
|
||||
#endif
|
||||
|
||||
setWriteDir(); // Set up LCD data port(s) for WRITE operations
|
||||
|
||||
rotation = 0;
|
||||
cursor_y = cursor_x = 0;
|
||||
textsize = 1;
|
||||
textcolor = 0xFFFF;
|
||||
_width = TFTWIDTH;
|
||||
_height = TFTHEIGHT;
|
||||
}
|
||||
|
||||
// Initialization command tables for different LCD controllers
|
||||
#define TFTLCD_DELAY 0xFF
|
||||
static const uint8_t HX8347G_regValues[] PROGMEM = {
|
||||
0x2E , 0x89,
|
||||
0x29 , 0x8F,
|
||||
0x2B , 0x02,
|
||||
0xE2 , 0x00,
|
||||
0xE4 , 0x01,
|
||||
0xE5 , 0x10,
|
||||
0xE6 , 0x01,
|
||||
0xE7 , 0x10,
|
||||
0xE8 , 0x70,
|
||||
0xF2 , 0x00,
|
||||
0xEA , 0x00,
|
||||
0xEB , 0x20,
|
||||
0xEC , 0x3C,
|
||||
0xED , 0xC8,
|
||||
0xE9 , 0x38,
|
||||
0xF1 , 0x01,
|
||||
|
||||
// skip gamma, do later
|
||||
|
||||
0x1B , 0x1A,
|
||||
0x1A , 0x02,
|
||||
0x24 , 0x61,
|
||||
0x25 , 0x5C,
|
||||
|
||||
0x18 , 0x36,
|
||||
0x19 , 0x01,
|
||||
0x1F , 0x88,
|
||||
TFTLCD_DELAY , 5 , // delay 5 ms
|
||||
0x1F , 0x80,
|
||||
TFTLCD_DELAY , 5 ,
|
||||
0x1F , 0x90,
|
||||
TFTLCD_DELAY , 5 ,
|
||||
0x1F , 0xD4,
|
||||
TFTLCD_DELAY , 5 ,
|
||||
0x17 , 0x05,
|
||||
|
||||
0x36 , 0x09,
|
||||
0x28 , 0x38,
|
||||
TFTLCD_DELAY , 40 ,
|
||||
0x28 , 0x3C,
|
||||
|
||||
0x02 , 0x00,
|
||||
0x03 , 0x00,
|
||||
0x04 , 0x00,
|
||||
0x05 , 0xEF,
|
||||
0x06 , 0x00,
|
||||
0x07 , 0x00,
|
||||
0x08 , 0x01,
|
||||
0x09 , 0x3F
|
||||
};
|
||||
|
||||
static const uint16_t ILI932x_regValues[] PROGMEM = {
|
||||
ILI932X_START_OSC , 0x0001, // Start oscillator
|
||||
TFTLCD_DELAY , 50, // 50 millisecond delay
|
||||
ILI932X_DRIV_OUT_CTRL , 0x0100,
|
||||
ILI932X_DRIV_WAV_CTRL , 0x0700,
|
||||
ILI932X_ENTRY_MOD , 0x1030,
|
||||
ILI932X_RESIZE_CTRL , 0x0000,
|
||||
ILI932X_DISP_CTRL2 , 0x0202,
|
||||
ILI932X_DISP_CTRL3 , 0x0000,
|
||||
ILI932X_DISP_CTRL4 , 0x0000,
|
||||
ILI932X_RGB_DISP_IF_CTRL1, 0x0,
|
||||
ILI932X_FRM_MARKER_POS , 0x0,
|
||||
ILI932X_RGB_DISP_IF_CTRL2, 0x0,
|
||||
ILI932X_POW_CTRL1 , 0x0000,
|
||||
ILI932X_POW_CTRL2 , 0x0007,
|
||||
ILI932X_POW_CTRL3 , 0x0000,
|
||||
ILI932X_POW_CTRL4 , 0x0000,
|
||||
TFTLCD_DELAY , 200,
|
||||
ILI932X_POW_CTRL1 , 0x1690,
|
||||
ILI932X_POW_CTRL2 , 0x0227,
|
||||
TFTLCD_DELAY , 50,
|
||||
ILI932X_POW_CTRL3 , 0x001A,
|
||||
TFTLCD_DELAY , 50,
|
||||
ILI932X_POW_CTRL4 , 0x1800,
|
||||
ILI932X_POW_CTRL7 , 0x002A,
|
||||
TFTLCD_DELAY , 50,
|
||||
ILI932X_GAMMA_CTRL1 , 0x0000,
|
||||
ILI932X_GAMMA_CTRL2 , 0x0000,
|
||||
ILI932X_GAMMA_CTRL3 , 0x0000,
|
||||
ILI932X_GAMMA_CTRL4 , 0x0206,
|
||||
ILI932X_GAMMA_CTRL5 , 0x0808,
|
||||
ILI932X_GAMMA_CTRL6 , 0x0007,
|
||||
ILI932X_GAMMA_CTRL7 , 0x0201,
|
||||
ILI932X_GAMMA_CTRL8 , 0x0000,
|
||||
ILI932X_GAMMA_CTRL9 , 0x0000,
|
||||
ILI932X_GAMMA_CTRL10 , 0x0000,
|
||||
ILI932X_GRAM_HOR_AD , 0x0000,
|
||||
ILI932X_GRAM_VER_AD , 0x0000,
|
||||
ILI932X_HOR_START_AD , 0x0000,
|
||||
ILI932X_HOR_END_AD , 0x00EF,
|
||||
ILI932X_VER_START_AD , 0X0000,
|
||||
ILI932X_VER_END_AD , 0x013F,
|
||||
ILI932X_GATE_SCAN_CTRL1 , 0xA700, // Driver Output Control (R60h)
|
||||
ILI932X_GATE_SCAN_CTRL2 , 0x0003, // Driver Output Control (R61h)
|
||||
ILI932X_GATE_SCAN_CTRL3 , 0x0000, // Driver Output Control (R62h)
|
||||
ILI932X_PANEL_IF_CTRL1 , 0X0010, // Panel Interface Control 1 (R90h)
|
||||
ILI932X_PANEL_IF_CTRL2 , 0X0000,
|
||||
ILI932X_PANEL_IF_CTRL3 , 0X0003,
|
||||
ILI932X_PANEL_IF_CTRL4 , 0X1100,
|
||||
ILI932X_PANEL_IF_CTRL5 , 0X0000,
|
||||
ILI932X_PANEL_IF_CTRL6 , 0X0000,
|
||||
ILI932X_DISP_CTRL1 , 0x0133, // Main screen turn on
|
||||
};
|
||||
|
||||
void Adafruit_TFTLCD::begin(uint16_t id) {
|
||||
|
||||
uint8_t i = 0;
|
||||
|
||||
reset();
|
||||
|
||||
if((id == 0x9325) || (id == 0x9328)) {
|
||||
|
||||
uint16_t a, d;
|
||||
driver = ID_932X;
|
||||
CS_ACTIVE;
|
||||
while(i < sizeof(ILI932x_regValues) / sizeof(uint16_t)) {
|
||||
a = pgm_read_word(&ILI932x_regValues[i++]);
|
||||
d = pgm_read_word(&ILI932x_regValues[i++]);
|
||||
if(a == TFTLCD_DELAY) delay(d);
|
||||
else writeRegister16(a, d);
|
||||
}
|
||||
setRotation(rotation);
|
||||
setAddrWindow(0, 0, TFTWIDTH-1, TFTHEIGHT-1);
|
||||
|
||||
} else if (id == 0x9341) {
|
||||
|
||||
uint16_t a, d;
|
||||
driver = ID_9341;
|
||||
CS_ACTIVE;
|
||||
writeRegister8(ILI9341_SOFTRESET, 0);
|
||||
delay(50);
|
||||
writeRegister8(ILI9341_DISPLAYOFF, 0);
|
||||
|
||||
writeRegister8(ILI9341_POWERCONTROL1, 0x23);
|
||||
writeRegister8(ILI9341_POWERCONTROL2, 0x10);
|
||||
writeRegister16(ILI9341_VCOMCONTROL1, 0x2B2B);
|
||||
writeRegister8(ILI9341_VCOMCONTROL2, 0xC0);
|
||||
writeRegister8(ILI9341_MEMCONTROL, 0x48);
|
||||
writeRegister8(ILI9341_PIXELFORMAT, 0x55);
|
||||
writeRegister16(ILI9341_FRAMECONTROL, 0x001B);
|
||||
|
||||
writeRegister8(ILI9341_ENTRYMODE, 0x07);
|
||||
/* writeRegister32(ILI9341_DISPLAYFUNC, 0x0A822700);*/
|
||||
|
||||
writeRegister8(ILI9341_SLEEPOUT, 0);
|
||||
delay(150);
|
||||
writeRegister8(ILI9341_DISPLAYON, 0);
|
||||
delay(500);
|
||||
setAddrWindow(0, 0, TFTWIDTH-1, TFTHEIGHT-1);
|
||||
|
||||
} else if(id == 0x7575) {
|
||||
|
||||
uint8_t a, d;
|
||||
driver = ID_7575;
|
||||
CS_ACTIVE;
|
||||
while(i < sizeof(HX8347G_regValues)) {
|
||||
a = pgm_read_byte(&HX8347G_regValues[i++]);
|
||||
d = pgm_read_byte(&HX8347G_regValues[i++]);
|
||||
if(a == TFTLCD_DELAY) delay(d);
|
||||
else writeRegister8(a, d);
|
||||
}
|
||||
setRotation(rotation);
|
||||
setLR(); // Lower-right corner of address window
|
||||
|
||||
} else {
|
||||
driver = ID_UNKNOWN;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Adafruit_TFTLCD::reset(void) {
|
||||
|
||||
CS_IDLE;
|
||||
// CD_DATA;
|
||||
WR_IDLE;
|
||||
RD_IDLE;
|
||||
|
||||
#ifdef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
pinMode(5, OUTPUT);
|
||||
digitalWrite(5, LOW);
|
||||
delay(1);
|
||||
digitalWrite(5, HIGH);
|
||||
delay(1);
|
||||
#else
|
||||
if(_reset) {
|
||||
pinMode(_reset, OUTPUT);
|
||||
digitalWrite(_reset, LOW);
|
||||
delay(1);
|
||||
digitalWrite(_reset, HIGH);
|
||||
delay(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Data transfer sync
|
||||
CS_ACTIVE;
|
||||
CD_COMMAND;
|
||||
write8(0x00);
|
||||
for(uint8_t i=0; i<7; i++) WR_STROBE; // Three extra 0x00s
|
||||
CS_IDLE;
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// Sets the LCD address window (and address counter, on 932X).
|
||||
// Relevant to rect/screen fills and H/V lines. Input coordinates are
|
||||
// assumed pre-sorted (e.g. x2 >= x1).
|
||||
void Adafruit_TFTLCD::setAddrWindow(int x1, int y1, int x2, int y2) {
|
||||
|
||||
CS_ACTIVE;
|
||||
if(driver == ID_932X) {
|
||||
|
||||
// Values passed are in current (possibly rotated) coordinate
|
||||
// system. 932X requires hardware-native coords regardless of
|
||||
// MADCTL, so rotate inputs as needed. The address counter is
|
||||
// set to the top-left corner -- although fill operations can be
|
||||
// done in any direction, the current screen rotation is applied
|
||||
// because some users find it disconcerting when a fill does not
|
||||
// occur top-to-bottom.
|
||||
int x, y, t;
|
||||
switch(rotation) {
|
||||
default:
|
||||
x = x1;
|
||||
y = y1;
|
||||
break;
|
||||
case 1:
|
||||
t = y1;
|
||||
y1 = x1;
|
||||
x1 = TFTWIDTH - 1 - y2;
|
||||
y2 = x2;
|
||||
x2 = TFTWIDTH - 1 - t;
|
||||
x = x2;
|
||||
y = y1;
|
||||
break;
|
||||
case 2:
|
||||
t = x1;
|
||||
x1 = TFTWIDTH - 1 - x2;
|
||||
x2 = TFTWIDTH - 1 - t;
|
||||
t = y1;
|
||||
y1 = TFTHEIGHT - 1 - y2;
|
||||
y2 = TFTHEIGHT - 1 - t;
|
||||
x = x2;
|
||||
y = y2;
|
||||
break;
|
||||
case 3:
|
||||
t = x1;
|
||||
x1 = y1;
|
||||
y1 = TFTHEIGHT - 1 - x2;
|
||||
x2 = y2;
|
||||
y2 = TFTHEIGHT - 1 - t;
|
||||
x = x1;
|
||||
y = y2;
|
||||
break;
|
||||
}
|
||||
writeRegister16(0x0050, x1); // Set address window
|
||||
writeRegister16(0x0051, x2);
|
||||
writeRegister16(0x0052, y1);
|
||||
writeRegister16(0x0053, y2);
|
||||
writeRegister16(0x0020, x ); // Set address counter to top left
|
||||
writeRegister16(0x0021, y );
|
||||
|
||||
} else if(driver == ID_7575) {
|
||||
|
||||
writeRegisterPair(HX8347G_COLADDRSTART_HI, HX8347G_COLADDRSTART_LO, x1);
|
||||
writeRegisterPair(HX8347G_ROWADDRSTART_HI, HX8347G_ROWADDRSTART_LO, y1);
|
||||
writeRegisterPair(HX8347G_COLADDREND_HI , HX8347G_COLADDREND_LO , x2);
|
||||
writeRegisterPair(HX8347G_ROWADDREND_HI , HX8347G_ROWADDREND_LO , y2);
|
||||
|
||||
} else if (driver == ID_9341) {
|
||||
uint32_t t;
|
||||
|
||||
t = x1;
|
||||
t <<= 16;
|
||||
t |= x2;
|
||||
writeRegister32(ILI9341_COLADDRSET, t);
|
||||
t = y1;
|
||||
t <<= 16;
|
||||
t |= y2;
|
||||
writeRegister32(ILI9341_PAGEADDRSET, t);
|
||||
|
||||
}
|
||||
CS_IDLE;
|
||||
}
|
||||
|
||||
// Unlike the 932X drivers that set the address window to the full screen
|
||||
// by default (using the address counter for drawPixel operations), the
|
||||
// 7575 needs the address window set on all graphics operations. In order
|
||||
// to save a few register writes on each pixel drawn, the lower-right
|
||||
// corner of the address window is reset after most fill operations, so
|
||||
// that drawPixel only needs to change the upper left each time.
|
||||
void Adafruit_TFTLCD::setLR(void) {
|
||||
CS_ACTIVE;
|
||||
writeRegisterPair(HX8347G_COLADDREND_HI, HX8347G_COLADDREND_LO, _width - 1);
|
||||
writeRegisterPair(HX8347G_ROWADDREND_HI, HX8347G_ROWADDREND_LO, _height - 1);
|
||||
CS_IDLE;
|
||||
}
|
||||
|
||||
// Fast block fill operation for fillScreen, fillRect, H/V line, etc.
|
||||
// Requires setAddrWindow() has previously been called to set the fill
|
||||
// bounds. 'len' is inclusive, MUST be >= 1.
|
||||
void Adafruit_TFTLCD::flood(uint16_t color, uint32_t len) {
|
||||
uint16_t blocks;
|
||||
uint8_t i, hi = color >> 8,
|
||||
lo = color;
|
||||
|
||||
CS_ACTIVE;
|
||||
CD_COMMAND;
|
||||
if (driver == ID_9341) {
|
||||
write8(0x2C);
|
||||
} else if (driver == ID_932X) {
|
||||
write8(0x00); // High byte of GRAM register...
|
||||
write8(0x22); // Write data to GRAM
|
||||
} else {
|
||||
write8(0x22); // Write data to GRAM
|
||||
}
|
||||
|
||||
// Write first pixel normally, decrement counter by 1
|
||||
CD_DATA;
|
||||
write8(hi);
|
||||
write8(lo);
|
||||
len--;
|
||||
|
||||
blocks = (uint16_t)(len / 64); // 64 pixels/block
|
||||
if(hi == lo) {
|
||||
// High and low bytes are identical. Leave prior data
|
||||
// on the port(s) and just toggle the write strobe.
|
||||
while(blocks--) {
|
||||
i = 16; // 64 pixels/block / 4 pixels/pass
|
||||
do {
|
||||
WR_STROBE; WR_STROBE; WR_STROBE; WR_STROBE; // 2 bytes/pixel
|
||||
WR_STROBE; WR_STROBE; WR_STROBE; WR_STROBE; // x 4 pixels
|
||||
} while(--i);
|
||||
}
|
||||
// Fill any remaining pixels (1 to 64)
|
||||
for(i = (uint8_t)len & 63; i--; ) {
|
||||
WR_STROBE;
|
||||
WR_STROBE;
|
||||
}
|
||||
} else {
|
||||
while(blocks--) {
|
||||
i = 16; // 64 pixels/block / 4 pixels/pass
|
||||
do {
|
||||
write8(hi); write8(lo); write8(hi); write8(lo);
|
||||
write8(hi); write8(lo); write8(hi); write8(lo);
|
||||
} while(--i);
|
||||
}
|
||||
for(i = (uint8_t)len & 63; i--; ) {
|
||||
write8(hi);
|
||||
write8(lo);
|
||||
}
|
||||
}
|
||||
CS_IDLE;
|
||||
}
|
||||
|
||||
void Adafruit_TFTLCD::drawFastHLine(int16_t x, int16_t y, int16_t length,
|
||||
uint16_t color)
|
||||
{
|
||||
int16_t x2;
|
||||
|
||||
// Initial off-screen clipping
|
||||
if((length <= 0 ) ||
|
||||
(y < 0 ) || ( y >= _height) ||
|
||||
(x >= _width) || ((x2 = (x+length-1)) < 0 )) return;
|
||||
|
||||
if(x < 0) { // Clip left
|
||||
length += x;
|
||||
x = 0;
|
||||
}
|
||||
if(x2 >= _width) { // Clip right
|
||||
x2 = _width - 1;
|
||||
length = x2 - x + 1;
|
||||
}
|
||||
|
||||
setAddrWindow(x, y, x2, y);
|
||||
flood(color, length);
|
||||
if(driver == ID_932X) setAddrWindow(0, 0, _width - 1, _height - 1);
|
||||
else setLR();
|
||||
}
|
||||
|
||||
void Adafruit_TFTLCD::drawFastVLine(int16_t x, int16_t y, int16_t length,
|
||||
uint16_t color)
|
||||
{
|
||||
int16_t y2;
|
||||
|
||||
// Initial off-screen clipping
|
||||
if((length <= 0 ) ||
|
||||
(x < 0 ) || ( x >= _width) ||
|
||||
(y >= _height) || ((y2 = (y+length-1)) < 0 )) return;
|
||||
if(y < 0) { // Clip top
|
||||
length += y;
|
||||
y = 0;
|
||||
}
|
||||
if(y2 >= _height) { // Clip bottom
|
||||
y2 = _height - 1;
|
||||
length = y2 - y + 1;
|
||||
}
|
||||
|
||||
setAddrWindow(x, y, x, y2);
|
||||
flood(color, length);
|
||||
if(driver == ID_932X) setAddrWindow(0, 0, _width - 1, _height - 1);
|
||||
else setLR();
|
||||
}
|
||||
|
||||
void Adafruit_TFTLCD::fillRect(int16_t x1, int16_t y1, int16_t w, int16_t h,
|
||||
uint16_t fillcolor) {
|
||||
int16_t x2, y2;
|
||||
|
||||
// Initial off-screen clipping
|
||||
if( (w <= 0 ) || (h <= 0 ) ||
|
||||
(x1 >= _width) || (y1 >= _height) ||
|
||||
((x2 = x1+w-1) < 0 ) || ((y2 = y1+h-1) < 0 )) return;
|
||||
if(x1 < 0) { // Clip left
|
||||
w += x1;
|
||||
x1 = 0;
|
||||
}
|
||||
if(y1 < 0) { // Clip top
|
||||
h += y1;
|
||||
y1 = 0;
|
||||
}
|
||||
if(x2 >= _width) { // Clip right
|
||||
x2 = _width - 1;
|
||||
w = x2 - x1 + 1;
|
||||
}
|
||||
if(y2 >= _height) { // Clip bottom
|
||||
y2 = _height - 1;
|
||||
h = y2 - y1 + 1;
|
||||
}
|
||||
|
||||
setAddrWindow(x1, y1, x2, y2);
|
||||
flood(fillcolor, (uint32_t)w * (uint32_t)h);
|
||||
if(driver == ID_932X) setAddrWindow(0, 0, _width - 1, _height - 1);
|
||||
else setLR();
|
||||
}
|
||||
|
||||
void Adafruit_TFTLCD::fillScreen(uint16_t color) {
|
||||
|
||||
if(driver == ID_932X) {
|
||||
|
||||
// For the 932X, a full-screen address window is already the default
|
||||
// state, just need to set the address pointer to the top-left corner.
|
||||
// Although we could fill in any direction, the code uses the current
|
||||
// screen rotation because some users find it disconcerting when a
|
||||
// fill does not occur top-to-bottom.
|
||||
uint16_t x, y;
|
||||
switch(rotation) {
|
||||
default: x = 0 ; y = 0 ; break;
|
||||
case 1 : x = TFTWIDTH - 1; y = 0 ; break;
|
||||
case 2 : x = TFTWIDTH - 1; y = TFTHEIGHT - 1; break;
|
||||
case 3 : x = 0 ; y = TFTHEIGHT - 1; break;
|
||||
}
|
||||
CS_ACTIVE;
|
||||
writeRegister16(0x0020, x);
|
||||
writeRegister16(0x0021, y);
|
||||
|
||||
} else if (driver == ID_9341) {
|
||||
setAddrWindow(0, 0, _width - 1, _height - 1);
|
||||
|
||||
} else if(driver == ID_7575) {
|
||||
|
||||
// For the 7575, there is no settable address pointer, instead the
|
||||
// address window must be set for each drawing operation. However,
|
||||
// this display takes rotation into account for the parameters, no
|
||||
// need to do extra rotation math here.
|
||||
setAddrWindow(0, 0, _width - 1, _height - 1);
|
||||
|
||||
}
|
||||
flood(color, (long)TFTWIDTH * (long)TFTHEIGHT);
|
||||
}
|
||||
|
||||
void Adafruit_TFTLCD::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
|
||||
// Clip
|
||||
if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return;
|
||||
|
||||
CS_ACTIVE;
|
||||
if(driver == ID_932X) {
|
||||
int16_t t;
|
||||
switch(rotation) {
|
||||
case 1:
|
||||
t = x;
|
||||
x = TFTWIDTH - 1 - y;
|
||||
y = t;
|
||||
break;
|
||||
case 2:
|
||||
x = TFTWIDTH - 1 - x;
|
||||
y = TFTHEIGHT - 1 - y;
|
||||
break;
|
||||
case 3:
|
||||
t = x;
|
||||
x = y;
|
||||
y = TFTHEIGHT - 1 - t;
|
||||
break;
|
||||
}
|
||||
writeRegister16(0x0020, x);
|
||||
writeRegister16(0x0021, y);
|
||||
writeRegister16(0x0022, color);
|
||||
|
||||
} else if(driver == ID_7575) {
|
||||
|
||||
uint8_t hi, lo;
|
||||
switch(rotation) {
|
||||
default: lo = 0 ; break;
|
||||
case 1 : lo = 0x60; break;
|
||||
case 2 : lo = 0xc0; break;
|
||||
case 3 : lo = 0xa0; break;
|
||||
}
|
||||
writeRegister8( HX8347G_MEMACCESS , lo);
|
||||
// Only upper-left is set -- bottom-right is full screen default
|
||||
writeRegisterPair(HX8347G_COLADDRSTART_HI, HX8347G_COLADDRSTART_LO, x);
|
||||
writeRegisterPair(HX8347G_ROWADDRSTART_HI, HX8347G_ROWADDRSTART_LO, y);
|
||||
hi = color >> 8; lo = color;
|
||||
CD_COMMAND; write8(0x22); CD_DATA; write8(hi); write8(lo);
|
||||
|
||||
} else if (driver == ID_9341) {
|
||||
setAddrWindow(x, y, 239, 319);
|
||||
CS_ACTIVE;
|
||||
CD_COMMAND;
|
||||
write8(0x2C);
|
||||
CD_DATA;
|
||||
write8(color >> 8); write8(color);
|
||||
}
|
||||
CS_IDLE;
|
||||
}
|
||||
|
||||
// Issues 'raw' an array of 16-bit color values to the LCD; used
|
||||
// externally by BMP examples. Assumes that setWindowAddr() has
|
||||
// previously been set to define the bounds. Max 255 pixels at
|
||||
// a time (BMP examples read in small chunks due to limited RAM).
|
||||
void Adafruit_TFTLCD::pushColors(uint16_t *data, uint8_t len, boolean first) {
|
||||
uint16_t color;
|
||||
uint8_t hi, lo;
|
||||
CS_ACTIVE;
|
||||
if(first == true) { // Issue GRAM write command only on first call
|
||||
CD_COMMAND;
|
||||
if(driver == ID_932X) write8(0x00);
|
||||
write8(0x22);
|
||||
}
|
||||
CD_DATA;
|
||||
while(len--) {
|
||||
color = *data++;
|
||||
hi = color >> 8; // Don't simplify or merge these
|
||||
lo = color; // lines, there's macro shenanigans
|
||||
write8(hi); // going on.
|
||||
write8(lo);
|
||||
}
|
||||
CS_IDLE;
|
||||
}
|
||||
|
||||
void Adafruit_TFTLCD::setRotation(uint8_t x) {
|
||||
|
||||
// Call parent rotation func first -- sets up rotation flags, etc.
|
||||
Adafruit_GFX::setRotation(x);
|
||||
// Then perform hardware-specific rotation operations...
|
||||
|
||||
CS_ACTIVE;
|
||||
if(driver == ID_932X) {
|
||||
|
||||
uint16_t t;
|
||||
switch(rotation) {
|
||||
default: t = 0x1030; break;
|
||||
case 1 : t = 0x1028; break;
|
||||
case 2 : t = 0x1000; break;
|
||||
case 3 : t = 0x1018; break;
|
||||
}
|
||||
writeRegister16(0x0003, t ); // MADCTL
|
||||
// For 932X, init default full-screen address window:
|
||||
setAddrWindow(0, 0, _width - 1, _height - 1); // CS_IDLE happens here
|
||||
|
||||
} else if(driver == ID_7575) {
|
||||
|
||||
uint8_t t;
|
||||
switch(rotation) {
|
||||
default: t = 0 ; break;
|
||||
case 1 : t = 0x60; break;
|
||||
case 2 : t = 0xc0; break;
|
||||
case 3 : t = 0xa0; break;
|
||||
}
|
||||
writeRegister8(HX8347G_MEMACCESS, t);
|
||||
// 7575 has to set the address window on most drawing operations.
|
||||
// drawPixel() cheats by setting only the top left...by default,
|
||||
// the lower right is always reset to the corner.
|
||||
setLR(); // CS_IDLE happens here
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef read8isFunctionalized
|
||||
#define read8(x) x=read8fn()
|
||||
#endif
|
||||
|
||||
// Because this function is used infrequently, it configures the ports for
|
||||
// the read operation, reads the data, then restores the ports to the write
|
||||
// configuration. Write operations happen a LOT, so it's advantageous to
|
||||
// leave the ports in that state as a default.
|
||||
uint16_t Adafruit_TFTLCD::readPixel(int16_t x, int16_t y) {
|
||||
|
||||
if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return 0;
|
||||
|
||||
CS_ACTIVE;
|
||||
if(driver == ID_932X) {
|
||||
|
||||
uint8_t hi, lo;
|
||||
int16_t t;
|
||||
switch(rotation) {
|
||||
case 1:
|
||||
t = x;
|
||||
x = TFTWIDTH - 1 - y;
|
||||
y = t;
|
||||
break;
|
||||
case 2:
|
||||
x = TFTWIDTH - 1 - x;
|
||||
y = TFTHEIGHT - 1 - y;
|
||||
break;
|
||||
case 3:
|
||||
t = x;
|
||||
x = y;
|
||||
y = TFTHEIGHT - 1 - t;
|
||||
break;
|
||||
}
|
||||
writeRegister16(0x0020, x);
|
||||
writeRegister16(0x0021, y);
|
||||
// Inexplicable thing: sometimes pixel read has high/low bytes
|
||||
// reversed. A second read fixes this. Unsure of reason. Have
|
||||
// tried adjusting timing in read8() etc. to no avail.
|
||||
for(uint8_t pass=0; pass<2; pass++) {
|
||||
CD_COMMAND; write8(0x00); write8(0x22); // Read data from GRAM
|
||||
CD_DATA;
|
||||
setReadDir(); // Set up LCD data port(s) for READ operations
|
||||
read8(hi); // First 2 bytes back are a dummy read
|
||||
read8(hi);
|
||||
read8(hi); // Bytes 3, 4 are actual pixel value
|
||||
read8(lo);
|
||||
setWriteDir(); // Restore LCD data port(s) to WRITE configuration
|
||||
}
|
||||
CS_IDLE;
|
||||
return ((uint16_t)hi << 8) | lo;
|
||||
|
||||
} else if(driver == ID_7575) {
|
||||
|
||||
uint8_t r, g, b;
|
||||
writeRegisterPair(HX8347G_COLADDRSTART_HI, HX8347G_COLADDRSTART_LO, x);
|
||||
writeRegisterPair(HX8347G_ROWADDRSTART_HI, HX8347G_ROWADDRSTART_LO, y);
|
||||
CD_COMMAND; write8(0x22); // Read data from GRAM
|
||||
setReadDir(); // Set up LCD data port(s) for READ operations
|
||||
CD_DATA;
|
||||
read8(r); // First byte back is a dummy read
|
||||
read8(r);
|
||||
read8(g);
|
||||
read8(b);
|
||||
setWriteDir(); // Restore LCD data port(s) to WRITE configuration
|
||||
CS_IDLE;
|
||||
return (((uint16_t)r & B11111000) << 8) |
|
||||
(((uint16_t)g & B11111100) << 3) |
|
||||
( b >> 3);
|
||||
} else if(driver == ID_9341) {
|
||||
uint8_t hi, lo;
|
||||
setReadDir(); // Set up LCD data port(s) for READ operations
|
||||
CD_DATA;
|
||||
read8(hi);
|
||||
read8(lo);
|
||||
setWriteDir(); // Restore LCD data port(s) to WRITE configuration
|
||||
CS_IDLE;
|
||||
return ((uint16_t)hi << 8) | lo;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Ditto with the read/write port directions, as above.
|
||||
uint16_t Adafruit_TFTLCD::readID(void) {
|
||||
|
||||
#if defined(VARIANT_MICROTOUCHX)
|
||||
uint32_t id;
|
||||
|
||||
id = readReg(0xD3);
|
||||
if (id == 0x9341) {
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t hi, lo;
|
||||
|
||||
CS_ACTIVE;
|
||||
CD_COMMAND;
|
||||
write8(0x00);
|
||||
WR_STROBE; // Repeat prior byte (0x00)
|
||||
setReadDir(); // Set up LCD data port(s) for READ operations
|
||||
CD_DATA;
|
||||
read8(hi);
|
||||
read8(lo);
|
||||
setWriteDir(); // Restore LCD data port(s) to WRITE configuration
|
||||
CS_IDLE;
|
||||
|
||||
return (hi << 8) | lo;
|
||||
}
|
||||
|
||||
uint32_t Adafruit_TFTLCD::readReg(uint8_t r) {
|
||||
uint32_t id = 0;
|
||||
|
||||
#if defined(VARIANT_MICROTOUCHX)
|
||||
// try reading register #4
|
||||
CS_ACTIVE;
|
||||
CD_COMMAND;
|
||||
write8(r);
|
||||
setReadDir(); // Set up LCD data port(s) for READ operations
|
||||
CD_DATA;
|
||||
uint8_t a, b, c, d;
|
||||
read8(a);
|
||||
read8(b);
|
||||
read8(c);
|
||||
read8(d);
|
||||
CS_IDLE;
|
||||
setWriteDir(); // Restore LCD data port(s) to WRITE configuration
|
||||
id = ((uint32_t)a << 24) | ((uint32_t)b << 16) | ((uint32_t)c << 8) | ((uint32_t)d << 0);
|
||||
#endif
|
||||
return id;
|
||||
}
|
||||
|
||||
// Pass 8-bit (each) R,G,B, get back 16-bit packed color
|
||||
uint16_t Adafruit_TFTLCD::color565(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
|
||||
}
|
||||
|
||||
// For I/O macros that were left undefined, declare function
|
||||
// versions that reference the inline macros just once:
|
||||
|
||||
#ifndef write8
|
||||
void Adafruit_TFTLCD::write8(uint8_t value) {
|
||||
write8inline(value);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef read8isFunctionalized
|
||||
uint8_t Adafruit_TFTLCD::read8fn(void) {
|
||||
uint8_t result;
|
||||
read8inline(result);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef setWriteDir
|
||||
void Adafruit_TFTLCD::setWriteDir(void) {
|
||||
setWriteDirInline();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef setReadDir
|
||||
void Adafruit_TFTLCD::setReadDir(void) {
|
||||
setReadDirInline();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef writeRegister8
|
||||
void Adafruit_TFTLCD::writeRegister8(uint8_t a, uint8_t d) {
|
||||
writeRegister8inline(a, d);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef writeRegister16
|
||||
void Adafruit_TFTLCD::writeRegister16(uint16_t a, uint16_t d) {
|
||||
writeRegister16inline(a, d);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef writeRegister32
|
||||
void Adafruit_TFTLCD::writeRegister32(uint8_t a, uint32_t d) {
|
||||
writeRegister32inline(a, d);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef writeRegisterPair
|
||||
void Adafruit_TFTLCD::writeRegisterPair(uint8_t aH, uint8_t aL, uint16_t d) {
|
||||
writeRegisterPairInline(aH, aL, d);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
// IMPORTANT: SEE COMMENTS @ LINE 15 REGARDING SHIELD VS BREAKOUT BOARD USAGE.
|
||||
|
||||
// Graphics library by ladyada/adafruit with init code from Rossum
|
||||
// MIT license
|
||||
|
||||
#ifndef _ADAFRUIT_TFTLCD_H_
|
||||
#define _ADAFRUIT_TFTLCD_H_
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include <Adafruit_GFX.h>
|
||||
|
||||
// **** IF USING THE LCD BREAKOUT BOARD, COMMENT OUT THIS NEXT LINE. ****
|
||||
// **** IF USING THE LCD SHIELD, LEAVE THE LINE ENABLED: ****
|
||||
//#define USE_ADAFRUIT_SHIELD_PINOUT
|
||||
|
||||
class Adafruit_TFTLCD : public Adafruit_GFX {
|
||||
|
||||
public:
|
||||
|
||||
Adafruit_TFTLCD(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t rst);
|
||||
Adafruit_TFTLCD(void);
|
||||
|
||||
void setup(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t rst);
|
||||
void begin(uint16_t id = 0x9325);
|
||||
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||
void drawFastHLine(int16_t x0, int16_t y0, int16_t w, uint16_t color);
|
||||
void drawFastVLine(int16_t x0, int16_t y0, int16_t h, uint16_t color);
|
||||
void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t c);
|
||||
void fillScreen(uint16_t color);
|
||||
void reset(void);
|
||||
void setRegisters8(uint8_t *ptr, uint8_t n);
|
||||
void setRegisters16(uint16_t *ptr, uint8_t n);
|
||||
void setRotation(uint8_t x);
|
||||
// These methods are public in order for BMP examples to work:
|
||||
void setAddrWindow(int x1, int y1, int x2, int y2);
|
||||
void pushColors(uint16_t *data, uint8_t len, boolean first);
|
||||
|
||||
uint16_t color565(uint8_t r, uint8_t g, uint8_t b),
|
||||
readPixel(int16_t x, int16_t y),
|
||||
readID(void);
|
||||
|
||||
uint32_t readReg(uint8_t r);
|
||||
|
||||
private:
|
||||
|
||||
void init(),
|
||||
// These items may have previously been defined as macros
|
||||
// in pin_magic.h. If not, function versions are declared:
|
||||
#ifndef write8
|
||||
write8(uint8_t value),
|
||||
#endif
|
||||
#ifndef setWriteDir
|
||||
setWriteDir(void),
|
||||
#endif
|
||||
#ifndef setReadDir
|
||||
setReadDir(void),
|
||||
#endif
|
||||
#ifndef writeRegister8
|
||||
writeRegister8(uint8_t a, uint8_t d),
|
||||
#endif
|
||||
#ifndef writeRegister16
|
||||
writeRegister16(uint16_t a, uint16_t d),
|
||||
#endif
|
||||
#ifndef writeRegister32
|
||||
writeRegister32(uint16_t a, uint32_t d),
|
||||
#endif
|
||||
#ifndef writeRegisterPair
|
||||
writeRegisterPair(uint8_t aH, uint8_t aL, uint16_t d),
|
||||
#endif
|
||||
setLR(void),
|
||||
flood(uint16_t color, uint32_t len);
|
||||
uint8_t driver;
|
||||
|
||||
#ifndef read8
|
||||
uint8_t read8fn(void);
|
||||
#define read8isFunctionalized
|
||||
#endif
|
||||
|
||||
#ifndef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
|
||||
#ifdef __AVR__
|
||||
volatile uint8_t *csPort , *cdPort , *wrPort , *rdPort;
|
||||
uint8_t csPinSet , cdPinSet , wrPinSet , rdPinSet ,
|
||||
csPinUnset, cdPinUnset, wrPinUnset, rdPinUnset,
|
||||
_reset;
|
||||
#endif
|
||||
#if defined(__SAM3X8E__)
|
||||
Pio *csPort , *cdPort , *wrPort , *rdPort;
|
||||
uint32_t csPinSet , cdPinSet , wrPinSet , rdPinSet ,
|
||||
csPinUnset, cdPinUnset, wrPinUnset, rdPinUnset,
|
||||
_reset;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
// For compatibility with sketches written for older versions of library.
|
||||
// Color function name was changed to 'color565' for parity with 2.2" LCD
|
||||
// library.
|
||||
#define Color565 color565
|
||||
|
||||
#endif
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
This is a library for the Adafruit 2.8" TFT display.
|
||||
This library works with the Adafruit 2.8" TFT Breakout w/SD card
|
||||
----> http://www.adafruit.com/products/335
|
||||
as well as Adafruit TFT Touch Shield
|
||||
----> http://www.adafruit.com/products/376
|
||||
|
||||
Check out the links above for our tutorials and wiring diagrams.
|
||||
These displays use 8-bit parallel to communicate, 12 or 13 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
|
||||
|
||||
To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_TFTLCD. Check that the Adafruit_TFTLCD folder contains Adafruit_TFTLCD.cpp and Adafruit_TFTLCD.
|
||||
|
||||
Place the Adafruit_TFT library folder your <arduinosketchfolder>/libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE
|
||||
|
||||
Also requires the Adafruit_GFX library for Arduino. https://github.com/adafruit/Adafruit-GFX-Library
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 225 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 225 KiB |
Executable
+380
@@ -0,0 +1,380 @@
|
||||
// IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY
|
||||
// CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
|
||||
// SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.
|
||||
|
||||
#include <Adafruit_GFX.h> // Core graphics library
|
||||
#include <Adafruit_TFTLCD.h> // Hardware-specific library
|
||||
|
||||
// The control pins for the LCD can be assigned to any digital or
|
||||
// analog pins...but we'll use the analog pins as this allows us to
|
||||
// double up the pins with the touch screen (see the TFT paint example).
|
||||
#define LCD_CS A3 // Chip Select goes to Analog 3
|
||||
#define LCD_CD A2 // Command/Data goes to Analog 2
|
||||
#define LCD_WR A1 // LCD Write goes to Analog 1
|
||||
#define LCD_RD A0 // LCD Read goes to Analog 0
|
||||
|
||||
#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin
|
||||
|
||||
// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
|
||||
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
|
||||
// D0 connects to digital pin 8 (Notice these are
|
||||
// D1 connects to digital pin 9 NOT in order!)
|
||||
// D2 connects to digital pin 2
|
||||
// D3 connects to digital pin 3
|
||||
// D4 connects to digital pin 4
|
||||
// D5 connects to digital pin 5
|
||||
// D6 connects to digital pin 6
|
||||
// D7 connects to digital pin 7
|
||||
// For the Arduino Mega, use digital pins 22 through 29
|
||||
// (on the 2-row header at the end of the board).
|
||||
|
||||
// Assign human-readable names to some common 16-bit color values:
|
||||
#define BLACK 0x0000
|
||||
#define BLUE 0x001F
|
||||
#define RED 0xF800
|
||||
#define GREEN 0x07E0
|
||||
#define CYAN 0x07FF
|
||||
#define MAGENTA 0xF81F
|
||||
#define YELLOW 0xFFE0
|
||||
#define WHITE 0xFFFF
|
||||
|
||||
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
|
||||
// If using the shield, all control and data lines are fixed, and
|
||||
// a simpler declaration can optionally be used:
|
||||
// Adafruit_TFTLCD tft;
|
||||
|
||||
void setup(void) {
|
||||
Serial.begin(9600);
|
||||
Serial.println(F("TFT LCD test"));
|
||||
|
||||
#ifdef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
Serial.println(F("Using Adafruit 2.8\" TFT Arduino Shield Pinout"));
|
||||
#else
|
||||
Serial.println(F("Using Adafruit 2.8\" TFT Breakout Board Pinout"));
|
||||
#endif
|
||||
|
||||
tft.reset();
|
||||
|
||||
uint16_t identifier = tft.readID();
|
||||
|
||||
if(identifier == 0x9325) {
|
||||
Serial.println(F("Found ILI9325 LCD driver"));
|
||||
} else if(identifier == 0x9328) {
|
||||
Serial.println(F("Found ILI9328 LCD driver"));
|
||||
} else if(identifier == 0x7575) {
|
||||
Serial.println(F("Found HX8347G LCD driver"));
|
||||
} else {
|
||||
Serial.print(F("Unknown LCD driver chip: "));
|
||||
Serial.println(identifier, HEX);
|
||||
Serial.println(F("If using the Adafruit 2.8\" TFT Arduino shield, the line:"));
|
||||
Serial.println(F(" #define USE_ADAFRUIT_SHIELD_PINOUT"));
|
||||
Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
|
||||
Serial.println(F("If using the breakout board, it should NOT be #defined!"));
|
||||
Serial.println(F("Also if using the breakout, double-check that all wiring"));
|
||||
Serial.println(F("matches the tutorial."));
|
||||
return;
|
||||
}
|
||||
|
||||
tft.begin(identifier);
|
||||
|
||||
Serial.println(F("Benchmark Time (microseconds)"));
|
||||
|
||||
Serial.print(F("Screen fill "));
|
||||
Serial.println(testFillScreen());
|
||||
delay(500);
|
||||
|
||||
Serial.print(F("Text "));
|
||||
Serial.println(testText());
|
||||
delay(3000);
|
||||
|
||||
Serial.print(F("Lines "));
|
||||
Serial.println(testLines(CYAN));
|
||||
delay(500);
|
||||
|
||||
Serial.print(F("Horiz/Vert Lines "));
|
||||
Serial.println(testFastLines(RED, BLUE));
|
||||
delay(500);
|
||||
|
||||
Serial.print(F("Rectangles (outline) "));
|
||||
Serial.println(testRects(GREEN));
|
||||
delay(500);
|
||||
|
||||
Serial.print(F("Rectangles (filled) "));
|
||||
Serial.println(testFilledRects(YELLOW, MAGENTA));
|
||||
delay(500);
|
||||
|
||||
Serial.print(F("Circles (filled) "));
|
||||
Serial.println(testFilledCircles(10, MAGENTA));
|
||||
|
||||
Serial.print(F("Circles (outline) "));
|
||||
Serial.println(testCircles(10, WHITE));
|
||||
delay(500);
|
||||
|
||||
Serial.print(F("Triangles (outline) "));
|
||||
Serial.println(testTriangles());
|
||||
delay(500);
|
||||
|
||||
Serial.print(F("Triangles (filled) "));
|
||||
Serial.println(testFilledTriangles());
|
||||
delay(500);
|
||||
|
||||
Serial.print(F("Rounded rects (outline) "));
|
||||
Serial.println(testRoundRects());
|
||||
delay(500);
|
||||
|
||||
Serial.print(F("Rounded rects (filled) "));
|
||||
Serial.println(testFilledRoundRects());
|
||||
delay(500);
|
||||
|
||||
Serial.println(F("Done!"));
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
for(uint8_t rotation=0; rotation<4; rotation++) {
|
||||
tft.setRotation(rotation);
|
||||
testText();
|
||||
delay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long testFillScreen() {
|
||||
unsigned long start = micros();
|
||||
tft.fillScreen(BLACK);
|
||||
tft.fillScreen(RED);
|
||||
tft.fillScreen(GREEN);
|
||||
tft.fillScreen(BLUE);
|
||||
tft.fillScreen(BLACK);
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testText() {
|
||||
tft.fillScreen(BLACK);
|
||||
unsigned long start = micros();
|
||||
tft.setCursor(0, 0);
|
||||
tft.setTextColor(WHITE); tft.setTextSize(1);
|
||||
tft.println("Hello World!");
|
||||
tft.setTextColor(YELLOW); tft.setTextSize(2);
|
||||
tft.println(1234.56);
|
||||
tft.setTextColor(RED); tft.setTextSize(3);
|
||||
tft.println(0xDEADBEEF, HEX);
|
||||
tft.println();
|
||||
tft.setTextColor(GREEN);
|
||||
tft.setTextSize(5);
|
||||
tft.println("Groop");
|
||||
tft.setTextSize(2);
|
||||
tft.println("I implore thee,");
|
||||
tft.setTextSize(1);
|
||||
tft.println("my foonting turlingdromes.");
|
||||
tft.println("And hooptiously drangle me");
|
||||
tft.println("with crinkly bindlewurdles,");
|
||||
tft.println("Or I will rend thee");
|
||||
tft.println("in the gobberwarts");
|
||||
tft.println("with my blurglecruncheon,");
|
||||
tft.println("see if I don't!");
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testLines(uint16_t color) {
|
||||
unsigned long start, t;
|
||||
int x1, y1, x2, y2,
|
||||
w = tft.width(),
|
||||
h = tft.height();
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
|
||||
x1 = y1 = 0;
|
||||
y2 = h - 1;
|
||||
start = micros();
|
||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = w - 1;
|
||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
t = micros() - start; // fillScreen doesn't count against timing
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
|
||||
x1 = w - 1;
|
||||
y1 = 0;
|
||||
y2 = h - 1;
|
||||
start = micros();
|
||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = 0;
|
||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
t += micros() - start;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
|
||||
x1 = 0;
|
||||
y1 = h - 1;
|
||||
y2 = 0;
|
||||
start = micros();
|
||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = w - 1;
|
||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
t += micros() - start;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
|
||||
x1 = w - 1;
|
||||
y1 = h - 1;
|
||||
y2 = 0;
|
||||
start = micros();
|
||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = 0;
|
||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFastLines(uint16_t color1, uint16_t color2) {
|
||||
unsigned long start;
|
||||
int x, y, w = tft.width(), h = tft.height();
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
start = micros();
|
||||
for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
|
||||
for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testRects(uint16_t color) {
|
||||
unsigned long start;
|
||||
int n, i, i2,
|
||||
cx = tft.width() / 2,
|
||||
cy = tft.height() / 2;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
n = min(tft.width(), tft.height());
|
||||
start = micros();
|
||||
for(i=2; i<n; i+=6) {
|
||||
i2 = i / 2;
|
||||
tft.drawRect(cx-i2, cy-i2, i, i, color);
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
|
||||
unsigned long start, t = 0;
|
||||
int n, i, i2,
|
||||
cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
n = min(tft.width(), tft.height());
|
||||
for(i=n; i>0; i-=6) {
|
||||
i2 = i / 2;
|
||||
start = micros();
|
||||
tft.fillRect(cx-i2, cy-i2, i, i, color1);
|
||||
t += micros() - start;
|
||||
// Outlines are not included in timing results
|
||||
tft.drawRect(cx-i2, cy-i2, i, i, color2);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
|
||||
unsigned long start;
|
||||
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
start = micros();
|
||||
for(x=radius; x<w; x+=r2) {
|
||||
for(y=radius; y<h; y+=r2) {
|
||||
tft.fillCircle(x, y, radius, color);
|
||||
}
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testCircles(uint8_t radius, uint16_t color) {
|
||||
unsigned long start;
|
||||
int x, y, r2 = radius * 2,
|
||||
w = tft.width() + radius,
|
||||
h = tft.height() + radius;
|
||||
|
||||
// Screen is not cleared for this one -- this is
|
||||
// intentional and does not affect the reported time.
|
||||
start = micros();
|
||||
for(x=0; x<w; x+=r2) {
|
||||
for(y=0; y<h; y+=r2) {
|
||||
tft.drawCircle(x, y, radius, color);
|
||||
}
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testTriangles() {
|
||||
unsigned long start;
|
||||
int n, i, cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
n = min(cx, cy);
|
||||
start = micros();
|
||||
for(i=0; i<n; i+=5) {
|
||||
tft.drawTriangle(
|
||||
cx , cy - i, // peak
|
||||
cx - i, cy + i, // bottom left
|
||||
cx + i, cy + i, // bottom right
|
||||
tft.color565(0, 0, i));
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFilledTriangles() {
|
||||
unsigned long start, t = 0;
|
||||
int i, cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
start = micros();
|
||||
for(i=min(cx,cy); i>10; i-=5) {
|
||||
start = micros();
|
||||
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
||||
tft.color565(0, i, i));
|
||||
t += micros() - start;
|
||||
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
||||
tft.color565(i, i, 0));
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
unsigned long testRoundRects() {
|
||||
unsigned long start;
|
||||
int w, i, i2,
|
||||
cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
w = min(tft.width(), tft.height());
|
||||
start = micros();
|
||||
for(i=0; i<w; i+=6) {
|
||||
i2 = i / 2;
|
||||
tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFilledRoundRects() {
|
||||
unsigned long start;
|
||||
int i, i2,
|
||||
cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
start = micros();
|
||||
for(i=min(tft.width(), tft.height()); i>20; i-=6) {
|
||||
i2 = i / 2;
|
||||
tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,351 @@
|
||||
// This is the same "graphicstest" demo, except modified
|
||||
// to work on a XMEGA A3BU Xplained board
|
||||
// DO NOT DEFINE "USE_ADAFRUIT_SHIELD_PINOUT" in Adafruit_TFTLCD.h
|
||||
// the pin mapping are different, and Serial4 is used for debug messages
|
||||
// SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.
|
||||
|
||||
#include <Adafruit_GFX.h> // Core graphics library
|
||||
#include <Adafruit_TFTLCD.h> // Hardware-specific library
|
||||
|
||||
#define LCD_CS 31 // PA4
|
||||
#define LCD_CD 38 // PB3
|
||||
#define LCD_WR 37 // PB2
|
||||
#define LCD_RD 36 // PB1
|
||||
#define LCD_RESET 35 // PA0
|
||||
|
||||
// Frank: On the XMEGA256A3BU-Xplained, PORTC is connected to the LCD data bus directly
|
||||
|
||||
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
|
||||
|
||||
// Assign human-readable names to some common 16-bit color values:
|
||||
#define BLACK 0x0000
|
||||
#define BLUE 0x001F
|
||||
#define RED 0xF800
|
||||
#define GREEN 0x07E0
|
||||
#define CYAN 0x07FF
|
||||
#define MAGENTA 0xF81F
|
||||
#define YELLOW 0xFFE0
|
||||
#define WHITE 0xFFFF
|
||||
|
||||
void setup(void) {
|
||||
Serial4.begin(9600);
|
||||
Serial4.println("TFT LCD test");
|
||||
|
||||
tft.reset();
|
||||
|
||||
uint16_t identifier = tft.readID();
|
||||
|
||||
if(identifier == 0x9325) {
|
||||
Serial4.println(F("Found ILI9325 LCD driver"));
|
||||
} else if(identifier == 0x9328) {
|
||||
Serial4.println(F("Found ILI9328 LCD driver"));
|
||||
} else if(identifier == 0x7575) {
|
||||
Serial4.println(F("Found HX8347G LCD driver"));
|
||||
} else {
|
||||
Serial4.print(F("Unknown LCD driver chip: "));
|
||||
Serial4.println(identifier, HEX);
|
||||
return;
|
||||
}
|
||||
|
||||
tft.begin(identifier);
|
||||
|
||||
Serial4.println(F("Benchmark Time (microseconds)"));
|
||||
|
||||
Serial4.print(F("Screen fill "));
|
||||
Serial4.println(testFillScreen());
|
||||
delay(500);
|
||||
|
||||
Serial4.print(F("Text "));
|
||||
Serial4.println(testText());
|
||||
delay(3000);
|
||||
|
||||
Serial4.print(F("Lines "));
|
||||
Serial4.println(testLines(CYAN));
|
||||
delay(500);
|
||||
|
||||
Serial4.print(F("Horiz/Vert Lines "));
|
||||
Serial4.println(testFastLines(RED, BLUE));
|
||||
delay(500);
|
||||
|
||||
Serial4.print(F("Rectangles (outline) "));
|
||||
Serial4.println(testRects(GREEN));
|
||||
delay(500);
|
||||
|
||||
Serial4.print(F("Rectangles (filled) "));
|
||||
Serial4.println(testFilledRects(YELLOW, MAGENTA));
|
||||
delay(500);
|
||||
|
||||
Serial4.print(F("Circles (filled) "));
|
||||
Serial4.println(testFilledCircles(10, MAGENTA));
|
||||
|
||||
Serial4.print(F("Circles (outline) "));
|
||||
Serial4.println(testCircles(10, WHITE));
|
||||
delay(500);
|
||||
|
||||
Serial4.print(F("Triangles (outline) "));
|
||||
Serial4.println(testTriangles());
|
||||
delay(500);
|
||||
|
||||
Serial4.print(F("Triangles (filled) "));
|
||||
Serial4.println(testFilledTriangles());
|
||||
delay(500);
|
||||
|
||||
Serial4.print(F("Rounded rects (outline) "));
|
||||
Serial4.println(testRoundRects());
|
||||
delay(500);
|
||||
|
||||
Serial4.print(F("Rounded rects (filled) "));
|
||||
Serial4.println(testFilledRoundRects());
|
||||
delay(500);
|
||||
|
||||
Serial4.println(F("Done!"));
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
for(uint8_t rotation=0; rotation<4; rotation++) {
|
||||
tft.setRotation(rotation);
|
||||
testText();
|
||||
delay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long testFillScreen() {
|
||||
unsigned long start = micros();
|
||||
tft.fillScreen(BLACK);
|
||||
tft.fillScreen(RED);
|
||||
tft.fillScreen(GREEN);
|
||||
tft.fillScreen(BLUE);
|
||||
tft.fillScreen(BLACK);
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testText() {
|
||||
tft.fillScreen(BLACK);
|
||||
unsigned long start = micros();
|
||||
tft.setCursor(0, 0);
|
||||
tft.setTextColor(WHITE); tft.setTextSize(1);
|
||||
tft.println("Hello World!");
|
||||
tft.setTextColor(YELLOW); tft.setTextSize(2);
|
||||
tft.println(1234.56);
|
||||
tft.setTextColor(RED); tft.setTextSize(3);
|
||||
tft.println(0xDEADBEEF, HEX);
|
||||
tft.println();
|
||||
tft.setTextColor(GREEN);
|
||||
tft.setTextSize(5);
|
||||
tft.println("Groop");
|
||||
tft.setTextSize(2);
|
||||
tft.println("I implore thee,");
|
||||
tft.setTextSize(1);
|
||||
tft.println("my foonting turlingdromes.");
|
||||
tft.println("And hooptiously drangle me");
|
||||
tft.println("with crinkly bindlewurdles,");
|
||||
tft.println("Or I will rend thee");
|
||||
tft.println("in the gobberwarts");
|
||||
tft.println("with my blurglecruncheon,");
|
||||
tft.println("see if I don't!");
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testLines(uint16_t color) {
|
||||
unsigned long start, t;
|
||||
int x1, y1, x2, y2,
|
||||
w = tft.width(),
|
||||
h = tft.height();
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
|
||||
x1 = y1 = 0;
|
||||
y2 = h - 1;
|
||||
start = micros();
|
||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = w - 1;
|
||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
t = micros() - start; // fillScreen doesn't count against timing
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
|
||||
x1 = w - 1;
|
||||
y1 = 0;
|
||||
y2 = h - 1;
|
||||
start = micros();
|
||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = 0;
|
||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
t += micros() - start;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
|
||||
x1 = 0;
|
||||
y1 = h - 1;
|
||||
y2 = 0;
|
||||
start = micros();
|
||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = w - 1;
|
||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
t += micros() - start;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
|
||||
x1 = w - 1;
|
||||
y1 = h - 1;
|
||||
y2 = 0;
|
||||
start = micros();
|
||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
x2 = 0;
|
||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFastLines(uint16_t color1, uint16_t color2) {
|
||||
unsigned long start;
|
||||
int x, y, w = tft.width(), h = tft.height();
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
start = micros();
|
||||
for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
|
||||
for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testRects(uint16_t color) {
|
||||
unsigned long start;
|
||||
int n, i, i2,
|
||||
cx = tft.width() / 2,
|
||||
cy = tft.height() / 2;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
n = min(tft.width(), tft.height());
|
||||
start = micros();
|
||||
for(i=2; i<n; i+=6) {
|
||||
i2 = i / 2;
|
||||
tft.drawRect(cx-i2, cy-i2, i, i, color);
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
|
||||
unsigned long start, t = 0;
|
||||
int n, i, i2,
|
||||
cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
n = min(tft.width(), tft.height());
|
||||
for(i=n; i>0; i-=6) {
|
||||
i2 = i / 2;
|
||||
start = micros();
|
||||
tft.fillRect(cx-i2, cy-i2, i, i, color1);
|
||||
t += micros() - start;
|
||||
// Outlines are not included in timing results
|
||||
tft.drawRect(cx-i2, cy-i2, i, i, color2);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
|
||||
unsigned long start;
|
||||
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
start = micros();
|
||||
for(x=radius; x<w; x+=r2) {
|
||||
for(y=radius; y<h; y+=r2) {
|
||||
tft.fillCircle(x, y, radius, color);
|
||||
}
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testCircles(uint8_t radius, uint16_t color) {
|
||||
unsigned long start;
|
||||
int x, y, r2 = radius * 2,
|
||||
w = tft.width() + radius,
|
||||
h = tft.height() + radius;
|
||||
|
||||
// Screen is not cleared for this one -- this is
|
||||
// intentional and does not affect the reported time.
|
||||
start = micros();
|
||||
for(x=0; x<w; x+=r2) {
|
||||
for(y=0; y<h; y+=r2) {
|
||||
tft.drawCircle(x, y, radius, color);
|
||||
}
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testTriangles() {
|
||||
unsigned long start;
|
||||
int n, i, cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
n = min(cx, cy);
|
||||
start = micros();
|
||||
for(i=0; i<n; i+=5) {
|
||||
tft.drawTriangle(
|
||||
cx , cy - i, // peak
|
||||
cx - i, cy + i, // bottom left
|
||||
cx + i, cy + i, // bottom right
|
||||
tft.color565(0, 0, i));
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFilledTriangles() {
|
||||
unsigned long start, t = 0;
|
||||
int i, cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
start = micros();
|
||||
for(i=min(cx,cy); i>10; i-=5) {
|
||||
start = micros();
|
||||
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
||||
tft.color565(0, i, i));
|
||||
t += micros() - start;
|
||||
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
||||
tft.color565(i, i, 0));
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
unsigned long testRoundRects() {
|
||||
unsigned long start;
|
||||
int w, i, i2,
|
||||
cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
w = min(tft.width(), tft.height());
|
||||
start = micros();
|
||||
for(i=0; i<w; i+=6) {
|
||||
i2 = i / 2;
|
||||
tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
|
||||
unsigned long testFilledRoundRects() {
|
||||
unsigned long start;
|
||||
int i, i2,
|
||||
cx = tft.width() / 2 - 1,
|
||||
cy = tft.height() / 2 - 1;
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
start = micros();
|
||||
for(i=min(tft.width(), tft.height()); i>20; i-=6) {
|
||||
i2 = i / 2;
|
||||
tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
|
||||
}
|
||||
|
||||
return micros() - start;
|
||||
}
|
||||
Executable
+219
@@ -0,0 +1,219 @@
|
||||
// IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY
|
||||
// CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
|
||||
// SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.
|
||||
|
||||
#include <Adafruit_GFX.h> // Core graphics library
|
||||
#include <Adafruit_TFTLCD.h> // Hardware-specific library
|
||||
|
||||
// The control pins for the LCD can be assigned to any digital or
|
||||
// analog pins...but we'll use the analog pins as this allows us to
|
||||
// double up the pins with the touch screen (see the TFT paint example).
|
||||
#define LCD_CS A3 // Chip Select goes to Analog 3
|
||||
#define LCD_CD A2 // Command/Data goes to Analog 2
|
||||
#define LCD_WR A1 // LCD Write goes to Analog 1
|
||||
#define LCD_RD A0 // LCD Read goes to Analog 0
|
||||
|
||||
#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin
|
||||
|
||||
// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
|
||||
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
|
||||
// D0 connects to digital pin 8 (Notice these are
|
||||
// D1 connects to digital pin 9 NOT in order!)
|
||||
// D2 connects to digital pin 2
|
||||
// D3 connects to digital pin 3
|
||||
// D4 connects to digital pin 4
|
||||
// D5 connects to digital pin 5
|
||||
// D6 connects to digital pin 6
|
||||
// D7 connects to digital pin 7
|
||||
// For the Arduino Mega, use digital pins 22 through 29
|
||||
// (on the 2-row header at the end of the board).
|
||||
|
||||
// Assign human-readable names to some common 16-bit color values:
|
||||
#define BLACK 0x0000
|
||||
#define BLUE 0x001F
|
||||
#define RED 0xF800
|
||||
#define GREEN 0x07E0
|
||||
#define CYAN 0x07FF
|
||||
#define MAGENTA 0xF81F
|
||||
#define YELLOW 0xFFE0
|
||||
#define WHITE 0xFFFF
|
||||
|
||||
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
|
||||
// If using the shield, all control and data lines are fixed, and
|
||||
// a simpler declaration can optionally be used:
|
||||
// Adafruit_TFTLCD tft;
|
||||
|
||||
void setup(void) {
|
||||
Serial.begin(9600);
|
||||
Serial.println(F("TFT LCD test"));
|
||||
|
||||
#ifdef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
Serial.println(F("Using Adafruit 2.8\" TFT Arduino Shield Pinout"));
|
||||
#else
|
||||
Serial.println(F("Using Adafruit 2.8\" TFT Breakout Board Pinout"));
|
||||
#endif
|
||||
|
||||
tft.reset();
|
||||
|
||||
uint16_t identifier = tft.readID();
|
||||
|
||||
if(identifier == 0x9325) {
|
||||
Serial.println(F("Found ILI9325 LCD driver"));
|
||||
} else if(identifier == 0x9328) {
|
||||
Serial.println(F("Found ILI9328 LCD driver"));
|
||||
} else if(identifier == 0x7575) {
|
||||
Serial.println(F("Found HX8347G LCD driver"));
|
||||
} else {
|
||||
Serial.print(F("Unknown LCD driver chip: "));
|
||||
Serial.println(identifier, HEX);
|
||||
Serial.println(F("If using the Adafruit 2.8\" TFT Arduino shield, the line:"));
|
||||
Serial.println(F(" #define USE_ADAFRUIT_SHIELD_PINOUT"));
|
||||
Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
|
||||
Serial.println(F("If using the breakout board, it should NOT be #defined!"));
|
||||
Serial.println(F("Also if using the breakout, double-check that all wiring"));
|
||||
Serial.println(F("matches the tutorial."));
|
||||
return;
|
||||
}
|
||||
|
||||
tft.begin(identifier);
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
|
||||
Serial.println(F("This is a test of the rotation capabilities of the TFT library!"));
|
||||
Serial.println(F("Press <SEND> (or type a character) to advance"));
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
rotatePixel();
|
||||
rotateLine();
|
||||
rotateFastline();
|
||||
rotateDrawrect();
|
||||
rotateFillrect();
|
||||
rotateDrawcircle();
|
||||
rotateFillcircle();
|
||||
rotateText();
|
||||
}
|
||||
|
||||
void rotateText() {
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
tft.fillScreen(BLACK);
|
||||
Serial.println(tft.getRotation(), DEC);
|
||||
|
||||
tft.setCursor(0, 30);
|
||||
tft.setTextColor(RED);
|
||||
tft.setTextSize(1);
|
||||
tft.println("Hello World!");
|
||||
tft.setTextColor(YELLOW);
|
||||
tft.setTextSize(2);
|
||||
tft.println("Hello World!");
|
||||
tft.setTextColor(GREEN);
|
||||
tft.setTextSize(3);
|
||||
tft.println("Hello World!");
|
||||
tft.setTextColor(BLUE);
|
||||
tft.setTextSize(4);
|
||||
tft.print(1234.567);
|
||||
|
||||
while (!Serial.available());
|
||||
Serial.read(); Serial.read(); Serial.read();
|
||||
|
||||
tft.setRotation(tft.getRotation()+1);
|
||||
}
|
||||
}
|
||||
|
||||
void rotateFillcircle(void) {
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
tft.fillScreen(BLACK);
|
||||
Serial.println(tft.getRotation(), DEC);
|
||||
|
||||
tft.fillCircle(10, 30, 10, YELLOW);
|
||||
|
||||
while (!Serial.available());
|
||||
Serial.read(); Serial.read(); Serial.read();
|
||||
|
||||
tft.setRotation(tft.getRotation()+1);
|
||||
}
|
||||
}
|
||||
|
||||
void rotateDrawcircle(void) {
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
tft.fillScreen(BLACK);
|
||||
Serial.println(tft.getRotation(), DEC);
|
||||
|
||||
tft.drawCircle(10, 30, 10, YELLOW);
|
||||
|
||||
while (!Serial.available());
|
||||
Serial.read(); Serial.read(); Serial.read();
|
||||
|
||||
tft.setRotation(tft.getRotation()+1);
|
||||
}
|
||||
}
|
||||
|
||||
void rotateFillrect(void) {
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
tft.fillScreen(BLACK);
|
||||
Serial.println(tft.getRotation(), DEC);
|
||||
|
||||
tft.fillRect(10, 20, 10, 20, GREEN);
|
||||
|
||||
while (!Serial.available());
|
||||
Serial.read(); Serial.read(); Serial.read();
|
||||
|
||||
tft.setRotation(tft.getRotation()+1);
|
||||
}
|
||||
}
|
||||
|
||||
void rotateDrawrect(void) {
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
tft.fillScreen(BLACK);
|
||||
Serial.println(tft.getRotation(), DEC);
|
||||
|
||||
tft.drawRect(10, 20, 10, 20, GREEN);
|
||||
|
||||
while (!Serial.available());
|
||||
Serial.read(); Serial.read(); Serial.read();
|
||||
|
||||
tft.setRotation(tft.getRotation()+1);
|
||||
}
|
||||
}
|
||||
|
||||
void rotateFastline(void) {
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
tft.fillScreen(BLACK);
|
||||
Serial.println(tft.getRotation(), DEC);
|
||||
|
||||
tft.drawFastHLine(0, 20, tft.width(), RED);
|
||||
tft.drawFastVLine(20, 0, tft.height(), BLUE);
|
||||
|
||||
while (!Serial.available());
|
||||
Serial.read(); Serial.read(); Serial.read();
|
||||
|
||||
tft.setRotation(tft.getRotation()+1);
|
||||
}
|
||||
}
|
||||
|
||||
void rotateLine(void) {
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
tft.fillScreen(BLACK);
|
||||
Serial.println(tft.getRotation(), DEC);
|
||||
|
||||
tft.drawLine(tft.width()/2, tft.height()/2, 0, 0, RED);
|
||||
while (!Serial.available());
|
||||
Serial.read(); Serial.read(); Serial.read();
|
||||
|
||||
tft.setRotation(tft.getRotation()+1);
|
||||
}
|
||||
}
|
||||
|
||||
void rotatePixel(void) {
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
tft.fillScreen(BLACK);
|
||||
Serial.println(tft.getRotation(), DEC);
|
||||
|
||||
tft.drawPixel(10,20, RED);
|
||||
while (!Serial.available());
|
||||
Serial.read(); Serial.read(); Serial.read();
|
||||
|
||||
tft.setRotation(tft.getRotation()+1);
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+243
@@ -0,0 +1,243 @@
|
||||
// BMP-loading example specifically for the TFTLCD breakout board.
|
||||
// If using the Arduino shield, use the tftbmp_shield.pde sketch instead!
|
||||
// If using an Arduino Mega, make sure the SD library is configured for
|
||||
// 'soft' SPI in the file Sd2Card.h.
|
||||
|
||||
#include <Adafruit_GFX.h> // Core graphics library
|
||||
#include <Adafruit_TFTLCD.h> // Hardware-specific library
|
||||
#include <SD.h>
|
||||
|
||||
// The control pins for the LCD can be assigned to any digital or
|
||||
// analog pins...but we'll use the analog pins as this allows us to
|
||||
// double up the pins with the touch screen (see the TFT paint example).
|
||||
#define LCD_CS A3 // Chip Select goes to Analog 3
|
||||
#define LCD_CD A2 // Command/Data goes to Analog 2
|
||||
#define LCD_WR A1 // LCD Write goes to Analog 1
|
||||
#define LCD_RD A0 // LCD Read goes to Analog 0
|
||||
|
||||
// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
|
||||
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
|
||||
// D0 connects to digital pin 8 (Notice these are
|
||||
// D1 connects to digital pin 9 NOT in order!)
|
||||
// D2 connects to digital pin 2
|
||||
// D3 connects to digital pin 3
|
||||
// D4 connects to digital pin 4
|
||||
// D5 connects to digital pin 5
|
||||
// D6 connects to digital pin 6
|
||||
// D7 connects to digital pin 7
|
||||
// For the Arduino Mega, use digital pins 22 through 29
|
||||
// (on the 2-row header at the end of the board).
|
||||
|
||||
// For Arduino Uno/Duemilanove, etc
|
||||
// connect the SD card with DI going to pin 11, DO going to pin 12 and SCK going to pin 13 (standard)
|
||||
// Then pin 10 goes to CS (or whatever you have set up)
|
||||
#define SD_CS 10 // Set the chip select line to whatever you use (10 doesnt conflict with the library)
|
||||
|
||||
// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)
|
||||
// There are examples in the sketch folder
|
||||
|
||||
// our TFT wiring
|
||||
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, A4);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
|
||||
tft.reset();
|
||||
|
||||
uint16_t identifier = tft.readID();
|
||||
|
||||
if(identifier == 0x9325) {
|
||||
Serial.println(F("Found ILI9325 LCD driver"));
|
||||
} else if(identifier == 0x9328) {
|
||||
Serial.println(F("Found ILI9328 LCD driver"));
|
||||
} else if(identifier == 0x7575) {
|
||||
Serial.println(F("Found HX8347G LCD driver"));
|
||||
} else {
|
||||
Serial.print(F("Unknown LCD driver chip: "));
|
||||
Serial.println(identifier, HEX);
|
||||
Serial.println(F("If using the Adafruit 2.8\" TFT Arduino shield, the line:"));
|
||||
Serial.println(F(" #define USE_ADAFRUIT_SHIELD_PINOUT"));
|
||||
Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
|
||||
Serial.println(F("If using the breakout board, it should NOT be #defined!"));
|
||||
Serial.println(F("Also if using the breakout, double-check that all wiring"));
|
||||
Serial.println(F("matches the tutorial."));
|
||||
return;
|
||||
}
|
||||
|
||||
tft.begin(identifier);
|
||||
|
||||
Serial.print(F("Initializing SD card..."));
|
||||
if (!SD.begin(SD_CS)) {
|
||||
Serial.println(F("failed!"));
|
||||
return;
|
||||
}
|
||||
Serial.println(F("OK!"));
|
||||
|
||||
bmpDraw("woof.bmp", 0, 0);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
for(int i = 0; i<4; i++) {
|
||||
tft.setRotation(i);
|
||||
tft.fillScreen(0);
|
||||
for(int j=0; j <= 200; j += 50) {
|
||||
bmpDraw("miniwoof.bmp", j, j);
|
||||
}
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// This function opens a Windows Bitmap (BMP) file and
|
||||
// displays it at the given coordinates. It's sped up
|
||||
// by reading many pixels worth of data at a time
|
||||
// (rather than pixel by pixel). Increasing the buffer
|
||||
// size takes more of the Arduino's precious RAM but
|
||||
// makes loading a little faster. 20 pixels seems a
|
||||
// good balance.
|
||||
|
||||
#define BUFFPIXEL 20
|
||||
|
||||
void bmpDraw(char *filename, int x, int y) {
|
||||
|
||||
File bmpFile;
|
||||
int bmpWidth, bmpHeight; // W+H in pixels
|
||||
uint8_t bmpDepth; // Bit depth (currently must be 24)
|
||||
uint32_t bmpImageoffset; // Start of image data in file
|
||||
uint32_t rowSize; // Not always = bmpWidth; may have padding
|
||||
uint8_t sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel)
|
||||
uint16_t lcdbuffer[BUFFPIXEL]; // pixel out buffer (16-bit per pixel)
|
||||
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
|
||||
boolean goodBmp = false; // Set to true on valid header parse
|
||||
boolean flip = true; // BMP is stored bottom-to-top
|
||||
int w, h, row, col;
|
||||
uint8_t r, g, b;
|
||||
uint32_t pos = 0, startTime = millis();
|
||||
uint8_t lcdidx = 0;
|
||||
boolean first = true;
|
||||
|
||||
if((x >= tft.width()) || (y >= tft.height())) return;
|
||||
|
||||
Serial.println();
|
||||
Serial.print(F("Loading image '"));
|
||||
Serial.print(filename);
|
||||
Serial.println('\'');
|
||||
// Open requested file on SD card
|
||||
if ((bmpFile = SD.open(filename)) == NULL) {
|
||||
Serial.println(F("File not found"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse BMP header
|
||||
if(read16(bmpFile) == 0x4D42) { // BMP signature
|
||||
Serial.println(F("File size: ")); Serial.println(read32(bmpFile));
|
||||
(void)read32(bmpFile); // Read & ignore creator bytes
|
||||
bmpImageoffset = read32(bmpFile); // Start of image data
|
||||
Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
|
||||
// Read DIB header
|
||||
Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
|
||||
bmpWidth = read32(bmpFile);
|
||||
bmpHeight = read32(bmpFile);
|
||||
if(read16(bmpFile) == 1) { // # planes -- must be '1'
|
||||
bmpDepth = read16(bmpFile); // bits per pixel
|
||||
Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
|
||||
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
|
||||
|
||||
goodBmp = true; // Supported BMP format -- proceed!
|
||||
Serial.print(F("Image size: "));
|
||||
Serial.print(bmpWidth);
|
||||
Serial.print('x');
|
||||
Serial.println(bmpHeight);
|
||||
|
||||
// BMP rows are padded (if needed) to 4-byte boundary
|
||||
rowSize = (bmpWidth * 3 + 3) & ~3;
|
||||
|
||||
// If bmpHeight is negative, image is in top-down order.
|
||||
// This is not canon but has been observed in the wild.
|
||||
if(bmpHeight < 0) {
|
||||
bmpHeight = -bmpHeight;
|
||||
flip = false;
|
||||
}
|
||||
|
||||
// Crop area to be loaded
|
||||
w = bmpWidth;
|
||||
h = bmpHeight;
|
||||
if((x+w-1) >= tft.width()) w = tft.width() - x;
|
||||
if((y+h-1) >= tft.height()) h = tft.height() - y;
|
||||
|
||||
// Set TFT address window to clipped image bounds
|
||||
tft.setAddrWindow(x, y, x+w-1, y+h-1);
|
||||
|
||||
for (row=0; row<h; row++) { // For each scanline...
|
||||
// Seek to start of scan line. It might seem labor-
|
||||
// intensive to be doing this on every line, but this
|
||||
// method covers a lot of gritty details like cropping
|
||||
// and scanline padding. Also, the seek only takes
|
||||
// place if the file position actually needs to change
|
||||
// (avoids a lot of cluster math in SD library).
|
||||
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
|
||||
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
|
||||
else // Bitmap is stored top-to-bottom
|
||||
pos = bmpImageoffset + row * rowSize;
|
||||
if(bmpFile.position() != pos) { // Need seek?
|
||||
bmpFile.seek(pos);
|
||||
buffidx = sizeof(sdbuffer); // Force buffer reload
|
||||
}
|
||||
|
||||
for (col=0; col<w; col++) { // For each column...
|
||||
// Time to read more pixel data?
|
||||
if (buffidx >= sizeof(sdbuffer)) { // Indeed
|
||||
// Push LCD buffer to the display first
|
||||
if(lcdidx > 0) {
|
||||
tft.pushColors(lcdbuffer, lcdidx, first);
|
||||
lcdidx = 0;
|
||||
first = false;
|
||||
}
|
||||
bmpFile.read(sdbuffer, sizeof(sdbuffer));
|
||||
buffidx = 0; // Set index to beginning
|
||||
}
|
||||
|
||||
// Convert pixel from BMP to TFT format
|
||||
b = sdbuffer[buffidx++];
|
||||
g = sdbuffer[buffidx++];
|
||||
r = sdbuffer[buffidx++];
|
||||
lcdbuffer[lcdidx++] = tft.color565(r,g,b);
|
||||
} // end pixel
|
||||
} // end scanline
|
||||
// Write any remaining data to LCD
|
||||
if(lcdidx > 0) {
|
||||
tft.pushColors(lcdbuffer, lcdidx, first);
|
||||
}
|
||||
Serial.print(F("Loaded in "));
|
||||
Serial.print(millis() - startTime);
|
||||
Serial.println(" ms");
|
||||
} // end goodBmp
|
||||
}
|
||||
}
|
||||
|
||||
bmpFile.close();
|
||||
if(!goodBmp) Serial.println(F("BMP format not recognized."));
|
||||
}
|
||||
|
||||
// These read 16- and 32-bit types from the SD card file.
|
||||
// BMP data is stored little-endian, Arduino is little-endian too.
|
||||
// May need to reverse subscript order if porting elsewhere.
|
||||
|
||||
uint16_t read16(File f) {
|
||||
uint16_t result;
|
||||
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||
((uint8_t *)&result)[1] = f.read(); // MSB
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t read32(File f) {
|
||||
uint32_t result;
|
||||
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||
((uint8_t *)&result)[1] = f.read();
|
||||
((uint8_t *)&result)[2] = f.read();
|
||||
((uint8_t *)&result)[3] = f.read(); // MSB
|
||||
return result;
|
||||
}
|
||||
|
||||
Executable
+225
@@ -0,0 +1,225 @@
|
||||
// BMP-loading example specifically for the TFTLCD Arduino shield.
|
||||
// If using the breakout board, use the tftbmp.pde sketch instead!
|
||||
// If using an Arduino Mega, make sure the SD library is configured for
|
||||
// 'soft' SPI in the file Sd2Card.h.
|
||||
|
||||
#include <Adafruit_GFX.h> // Core graphics library
|
||||
#include <Adafruit_TFTLCD.h> // Hardware-specific library
|
||||
#include <SD.h>
|
||||
|
||||
// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)
|
||||
// There are examples in the sketch folder
|
||||
|
||||
#define SD_CS 5 // Card select for shield use
|
||||
|
||||
Adafruit_TFTLCD tft;
|
||||
uint8_t spi_save;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
|
||||
tft.reset();
|
||||
|
||||
uint16_t identifier = tft.readID();
|
||||
|
||||
if(identifier == 0x9325) {
|
||||
Serial.println(F("Found ILI9325 LCD driver"));
|
||||
} else if(identifier == 0x9328) {
|
||||
Serial.println(F("Found ILI9328 LCD driver"));
|
||||
} else if(identifier == 0x7575) {
|
||||
Serial.println(F("Found HX8347G LCD driver"));
|
||||
} else {
|
||||
Serial.print(F("Unknown LCD driver chip: "));
|
||||
Serial.println(identifier, HEX);
|
||||
Serial.println(F("If using the Adafruit 2.8\" TFT Arduino shield, the line:"));
|
||||
Serial.println(F(" #define USE_ADAFRUIT_SHIELD_PINOUT"));
|
||||
Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
|
||||
Serial.println(F("If using the breakout board, it should NOT be #defined!"));
|
||||
Serial.println(F("Also if using the breakout, double-check that all wiring"));
|
||||
Serial.println(F("matches the tutorial."));
|
||||
return;
|
||||
}
|
||||
|
||||
tft.begin(identifier);
|
||||
|
||||
Serial.print(F("Initializing SD card..."));
|
||||
if (!SD.begin(SD_CS)) {
|
||||
Serial.println(F("failed!"));
|
||||
return;
|
||||
}
|
||||
Serial.println(F("OK!"));
|
||||
spi_save = SPCR;
|
||||
|
||||
bmpDraw("woof.bmp", 0, 0);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
for(int i = 0; i<4; i++) {
|
||||
tft.setRotation(i);
|
||||
tft.fillScreen(0);
|
||||
for(int j=0; j <= 200; j += 50) {
|
||||
bmpDraw("miniwoof.bmp", j, j);
|
||||
}
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// This function opens a Windows Bitmap (BMP) file and
|
||||
// displays it at the given coordinates. It's sped up
|
||||
// by reading many pixels worth of data at a time
|
||||
// (rather than pixel by pixel). Increasing the buffer
|
||||
// size takes more of the Arduino's precious RAM but
|
||||
// makes loading a little faster. 20 pixels seems a
|
||||
// good balance.
|
||||
|
||||
#define BUFFPIXEL 20
|
||||
|
||||
void bmpDraw(char *filename, int x, int y) {
|
||||
File bmpFile;
|
||||
int bmpWidth, bmpHeight; // W+H in pixels
|
||||
uint8_t bmpDepth; // Bit depth (currently must be 24)
|
||||
uint32_t bmpImageoffset; // Start of image data in file
|
||||
uint32_t rowSize; // Not always = bmpWidth; may have padding
|
||||
uint8_t sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel)
|
||||
uint16_t lcdbuffer[BUFFPIXEL]; // pixel out buffer (16-bit per pixel)
|
||||
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
|
||||
boolean goodBmp = false; // Set to true on valid header parse
|
||||
boolean flip = true; // BMP is stored bottom-to-top
|
||||
int w, h, row, col;
|
||||
uint8_t r, g, b;
|
||||
uint32_t pos = 0, startTime = millis();
|
||||
uint8_t lcdidx = 0;
|
||||
boolean first = true;
|
||||
|
||||
if((x >= tft.width()) || (y >= tft.height())) return;
|
||||
|
||||
Serial.println();
|
||||
Serial.print("Loading image '");
|
||||
Serial.print(filename);
|
||||
Serial.println('\'');
|
||||
// Open requested file on SD card
|
||||
SPCR = spi_save;
|
||||
if ((bmpFile = SD.open(filename)) == NULL) {
|
||||
Serial.print("File not found");
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse BMP header
|
||||
if(read16(bmpFile) == 0x4D42) { // BMP signature
|
||||
Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
|
||||
(void)read32(bmpFile); // Read & ignore creator bytes
|
||||
bmpImageoffset = read32(bmpFile); // Start of image data
|
||||
Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
|
||||
// Read DIB header
|
||||
Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
|
||||
bmpWidth = read32(bmpFile);
|
||||
bmpHeight = read32(bmpFile);
|
||||
if(read16(bmpFile) == 1) { // # planes -- must be '1'
|
||||
bmpDepth = read16(bmpFile); // bits per pixel
|
||||
Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
|
||||
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
|
||||
|
||||
goodBmp = true; // Supported BMP format -- proceed!
|
||||
Serial.print(F("Image size: "));
|
||||
Serial.print(bmpWidth);
|
||||
Serial.print('x');
|
||||
Serial.println(bmpHeight);
|
||||
|
||||
// BMP rows are padded (if needed) to 4-byte boundary
|
||||
rowSize = (bmpWidth * 3 + 3) & ~3;
|
||||
|
||||
// If bmpHeight is negative, image is in top-down order.
|
||||
// This is not canon but has been observed in the wild.
|
||||
if(bmpHeight < 0) {
|
||||
bmpHeight = -bmpHeight;
|
||||
flip = false;
|
||||
}
|
||||
|
||||
// Crop area to be loaded
|
||||
w = bmpWidth;
|
||||
h = bmpHeight;
|
||||
if((x+w-1) >= tft.width()) w = tft.width() - x;
|
||||
if((y+h-1) >= tft.height()) h = tft.height() - y;
|
||||
|
||||
// Set TFT address window to clipped image bounds
|
||||
SPCR = 0;
|
||||
tft.setAddrWindow(x, y, x+w-1, y+h-1);
|
||||
|
||||
for (row=0; row<h; row++) { // For each scanline...
|
||||
// Seek to start of scan line. It might seem labor-
|
||||
// intensive to be doing this on every line, but this
|
||||
// method covers a lot of gritty details like cropping
|
||||
// and scanline padding. Also, the seek only takes
|
||||
// place if the file position actually needs to change
|
||||
// (avoids a lot of cluster math in SD library).
|
||||
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
|
||||
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
|
||||
else // Bitmap is stored top-to-bottom
|
||||
pos = bmpImageoffset + row * rowSize;
|
||||
SPCR = spi_save;
|
||||
if(bmpFile.position() != pos) { // Need seek?
|
||||
bmpFile.seek(pos);
|
||||
buffidx = sizeof(sdbuffer); // Force buffer reload
|
||||
}
|
||||
|
||||
for (col=0; col<w; col++) { // For each column...
|
||||
// Time to read more pixel data?
|
||||
if (buffidx >= sizeof(sdbuffer)) { // Indeed
|
||||
// Push LCD buffer to the display first
|
||||
if(lcdidx > 0) {
|
||||
SPCR = 0;
|
||||
tft.pushColors(lcdbuffer, lcdidx, first);
|
||||
lcdidx = 0;
|
||||
first = false;
|
||||
}
|
||||
SPCR = spi_save;
|
||||
bmpFile.read(sdbuffer, sizeof(sdbuffer));
|
||||
buffidx = 0; // Set index to beginning
|
||||
}
|
||||
|
||||
// Convert pixel from BMP to TFT format
|
||||
b = sdbuffer[buffidx++];
|
||||
g = sdbuffer[buffidx++];
|
||||
r = sdbuffer[buffidx++];
|
||||
lcdbuffer[lcdidx++] = tft.color565(r,g,b);
|
||||
} // end pixel
|
||||
} // end scanline
|
||||
// Write any remaining data to LCD
|
||||
if(lcdidx > 0) {
|
||||
SPCR = 0;
|
||||
tft.pushColors(lcdbuffer, lcdidx, first);
|
||||
}
|
||||
Serial.print(F("Loaded in "));
|
||||
Serial.print(millis() - startTime);
|
||||
Serial.println(" ms");
|
||||
} // end goodBmp
|
||||
}
|
||||
}
|
||||
|
||||
bmpFile.close();
|
||||
if(!goodBmp) Serial.println("BMP format not recognized.");
|
||||
}
|
||||
|
||||
// These read 16- and 32-bit types from the SD card file.
|
||||
// BMP data is stored little-endian, Arduino is little-endian too.
|
||||
// May need to reverse subscript order if porting elsewhere.
|
||||
|
||||
uint16_t read16(File f) {
|
||||
uint16_t result;
|
||||
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||
((uint8_t *)&result)[1] = f.read(); // MSB
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t read32(File f) {
|
||||
uint32_t result;
|
||||
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||
((uint8_t *)&result)[1] = f.read();
|
||||
((uint8_t *)&result)[2] = f.read();
|
||||
((uint8_t *)&result)[3] = f.read(); // MSB
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
// Paint example specifically for the TFTLCD breakout board.
|
||||
// If using the Arduino shield, use the tftpaint_shield.pde sketch instead!
|
||||
// DOES NOT CURRENTLY WORK ON ARDUINO LEONARDO
|
||||
|
||||
#include <Adafruit_GFX.h> // Core graphics library
|
||||
#include <Adafruit_TFTLCD.h> // Hardware-specific library
|
||||
#include <TouchScreen.h>
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
#undef __FlashStringHelper::F(string_literal)
|
||||
#define F(string_literal) string_literal
|
||||
#endif
|
||||
|
||||
// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
|
||||
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
|
||||
// D0 connects to digital pin 8 (Notice these are
|
||||
// D1 connects to digital pin 9 NOT in order!)
|
||||
// D2 connects to digital pin 2
|
||||
// D3 connects to digital pin 3
|
||||
// D4 connects to digital pin 4
|
||||
// D5 connects to digital pin 5
|
||||
// D6 connects to digital pin 6
|
||||
// D7 connects to digital pin 7
|
||||
|
||||
// For the Arduino Mega, use digital pins 22 through 29
|
||||
// (on the 2-row header at the end of the board).
|
||||
// D0 connects to digital pin 22
|
||||
// D1 connects to digital pin 23
|
||||
// D2 connects to digital pin 24
|
||||
// D3 connects to digital pin 25
|
||||
// D4 connects to digital pin 26
|
||||
// D5 connects to digital pin 27
|
||||
// D6 connects to digital pin 28
|
||||
// D7 connects to digital pin 29
|
||||
|
||||
// For the Arduino Due, use digital pins 33 through 40
|
||||
// (on the 2-row header at the end of the board).
|
||||
// D0 connects to digital pin 33
|
||||
// D1 connects to digital pin 34
|
||||
// D2 connects to digital pin 35
|
||||
// D3 connects to digital pin 36
|
||||
// D4 connects to digital pin 37
|
||||
// D5 connects to digital pin 38
|
||||
// D6 connects to digital pin 39
|
||||
// D7 connects to digital pin 40
|
||||
|
||||
#define YP A3 // must be an analog pin, use "An" notation!
|
||||
#define XM A2 // must be an analog pin, use "An" notation!
|
||||
#define YM 9 // can be a digital pin
|
||||
#define XP 8 // can be a digital pin
|
||||
|
||||
#define TS_MINX 150
|
||||
#define TS_MINY 120
|
||||
#define TS_MAXX 920
|
||||
#define TS_MAXY 940
|
||||
|
||||
// For better pressure precision, we need to know the resistance
|
||||
// between X+ and X- Use any multimeter to read it
|
||||
// For the one we're using, its 300 ohms across the X plate
|
||||
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
|
||||
|
||||
#define LCD_CS A3
|
||||
#define LCD_CD A2
|
||||
#define LCD_WR A1
|
||||
#define LCD_RD A0
|
||||
// optional
|
||||
#define LCD_RESET A4
|
||||
|
||||
// Assign human-readable names to some common 16-bit color values:
|
||||
#define BLACK 0x0000
|
||||
#define BLUE 0x001F
|
||||
#define RED 0xF800
|
||||
#define GREEN 0x07E0
|
||||
#define CYAN 0x07FF
|
||||
#define MAGENTA 0xF81F
|
||||
#define YELLOW 0xFFE0
|
||||
#define WHITE 0xFFFF
|
||||
|
||||
|
||||
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
|
||||
|
||||
#define BOXSIZE 40
|
||||
#define PENRADIUS 3
|
||||
int oldcolor, currentcolor;
|
||||
|
||||
void setup(void) {
|
||||
Serial.begin(9600);
|
||||
Serial.println(F("Paint!"));
|
||||
|
||||
tft.reset();
|
||||
|
||||
uint16_t identifier = tft.readID();
|
||||
|
||||
if(identifier == 0x9325) {
|
||||
Serial.println(F("Found ILI9325 LCD driver"));
|
||||
} else if(identifier == 0x9328) {
|
||||
Serial.println(F("Found ILI9328 LCD driver"));
|
||||
} else if(identifier == 0x7575) {
|
||||
Serial.println(F("Found HX8347G LCD driver"));
|
||||
} else {
|
||||
Serial.print(F("Unknown LCD driver chip: "));
|
||||
Serial.println(identifier, HEX);
|
||||
return;
|
||||
}
|
||||
|
||||
tft.begin(identifier);
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
|
||||
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
|
||||
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
|
||||
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, GREEN);
|
||||
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, CYAN);
|
||||
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, BLUE);
|
||||
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, MAGENTA);
|
||||
// tft.fillRect(BOXSIZE*6, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
|
||||
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
currentcolor = RED;
|
||||
|
||||
pinMode(13, OUTPUT);
|
||||
}
|
||||
|
||||
#define MINPRESSURE 10
|
||||
#define MAXPRESSURE 1000
|
||||
|
||||
void loop()
|
||||
{
|
||||
digitalWrite(13, HIGH);
|
||||
Point p = ts.getPoint();
|
||||
digitalWrite(13, LOW);
|
||||
|
||||
// if sharing pins, you'll need to fix the directions of the touchscreen pins
|
||||
//pinMode(XP, OUTPUT);
|
||||
pinMode(XM, OUTPUT);
|
||||
pinMode(YP, OUTPUT);
|
||||
//pinMode(YM, OUTPUT);
|
||||
|
||||
// we have some minimum pressure we consider 'valid'
|
||||
// pressure of 0 means no pressing!
|
||||
|
||||
if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
|
||||
/*
|
||||
Serial.print("X = "); Serial.print(p.x);
|
||||
Serial.print("\tY = "); Serial.print(p.y);
|
||||
Serial.print("\tPressure = "); Serial.println(p.z);
|
||||
*/
|
||||
|
||||
if (p.y < (TS_MINY-5)) {
|
||||
Serial.println("erase");
|
||||
// press the bottom of the screen to erase
|
||||
tft.fillRect(0, BOXSIZE, tft.width(), tft.height()-BOXSIZE, BLACK);
|
||||
}
|
||||
// scale from 0->1023 to tft.width
|
||||
p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
|
||||
p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);
|
||||
/*
|
||||
Serial.print("("); Serial.print(p.x);
|
||||
Serial.print(", "); Serial.print(p.y);
|
||||
Serial.println(")");
|
||||
*/
|
||||
if (p.y < BOXSIZE) {
|
||||
oldcolor = currentcolor;
|
||||
|
||||
if (p.x < BOXSIZE) {
|
||||
currentcolor = RED;
|
||||
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
} else if (p.x < BOXSIZE*2) {
|
||||
currentcolor = YELLOW;
|
||||
tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
} else if (p.x < BOXSIZE*3) {
|
||||
currentcolor = GREEN;
|
||||
tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
} else if (p.x < BOXSIZE*4) {
|
||||
currentcolor = CYAN;
|
||||
tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
} else if (p.x < BOXSIZE*5) {
|
||||
currentcolor = BLUE;
|
||||
tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
} else if (p.x < BOXSIZE*6) {
|
||||
currentcolor = MAGENTA;
|
||||
tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
}
|
||||
|
||||
if (oldcolor != currentcolor) {
|
||||
if (oldcolor == RED) tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
|
||||
if (oldcolor == YELLOW) tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
|
||||
if (oldcolor == GREEN) tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, GREEN);
|
||||
if (oldcolor == CYAN) tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, CYAN);
|
||||
if (oldcolor == BLUE) tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, BLUE);
|
||||
if (oldcolor == MAGENTA) tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, MAGENTA);
|
||||
}
|
||||
}
|
||||
if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) {
|
||||
tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,264 @@
|
||||
|
||||
#ifndef FONT5X7_H
|
||||
#define FONT5X7_H
|
||||
|
||||
// standard ascii 5x7 font
|
||||
|
||||
static unsigned char font[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
|
||||
0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
|
||||
0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
|
||||
0x18, 0x3C, 0x7E, 0x3C, 0x18,
|
||||
0x1C, 0x57, 0x7D, 0x57, 0x1C,
|
||||
0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
|
||||
0x00, 0x18, 0x3C, 0x18, 0x00,
|
||||
0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
|
||||
0x00, 0x18, 0x24, 0x18, 0x00,
|
||||
0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
|
||||
0x30, 0x48, 0x3A, 0x06, 0x0E,
|
||||
0x26, 0x29, 0x79, 0x29, 0x26,
|
||||
0x40, 0x7F, 0x05, 0x05, 0x07,
|
||||
0x40, 0x7F, 0x05, 0x25, 0x3F,
|
||||
0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
|
||||
0x7F, 0x3E, 0x1C, 0x1C, 0x08,
|
||||
0x08, 0x1C, 0x1C, 0x3E, 0x7F,
|
||||
0x14, 0x22, 0x7F, 0x22, 0x14,
|
||||
0x5F, 0x5F, 0x00, 0x5F, 0x5F,
|
||||
0x06, 0x09, 0x7F, 0x01, 0x7F,
|
||||
0x00, 0x66, 0x89, 0x95, 0x6A,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60,
|
||||
0x94, 0xA2, 0xFF, 0xA2, 0x94,
|
||||
0x08, 0x04, 0x7E, 0x04, 0x08,
|
||||
0x10, 0x20, 0x7E, 0x20, 0x10,
|
||||
0x08, 0x08, 0x2A, 0x1C, 0x08,
|
||||
0x08, 0x1C, 0x2A, 0x08, 0x08,
|
||||
0x1E, 0x10, 0x10, 0x10, 0x10,
|
||||
0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
|
||||
0x30, 0x38, 0x3E, 0x38, 0x30,
|
||||
0x06, 0x0E, 0x3E, 0x0E, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x5F, 0x00, 0x00,
|
||||
0x00, 0x07, 0x00, 0x07, 0x00,
|
||||
0x14, 0x7F, 0x14, 0x7F, 0x14,
|
||||
0x24, 0x2A, 0x7F, 0x2A, 0x12,
|
||||
0x23, 0x13, 0x08, 0x64, 0x62,
|
||||
0x36, 0x49, 0x56, 0x20, 0x50,
|
||||
0x00, 0x08, 0x07, 0x03, 0x00,
|
||||
0x00, 0x1C, 0x22, 0x41, 0x00,
|
||||
0x00, 0x41, 0x22, 0x1C, 0x00,
|
||||
0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
|
||||
0x08, 0x08, 0x3E, 0x08, 0x08,
|
||||
0x00, 0x80, 0x70, 0x30, 0x00,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x00, 0x00, 0x60, 0x60, 0x00,
|
||||
0x20, 0x10, 0x08, 0x04, 0x02,
|
||||
0x3E, 0x51, 0x49, 0x45, 0x3E,
|
||||
0x00, 0x42, 0x7F, 0x40, 0x00,
|
||||
0x72, 0x49, 0x49, 0x49, 0x46,
|
||||
0x21, 0x41, 0x49, 0x4D, 0x33,
|
||||
0x18, 0x14, 0x12, 0x7F, 0x10,
|
||||
0x27, 0x45, 0x45, 0x45, 0x39,
|
||||
0x3C, 0x4A, 0x49, 0x49, 0x31,
|
||||
0x41, 0x21, 0x11, 0x09, 0x07,
|
||||
0x36, 0x49, 0x49, 0x49, 0x36,
|
||||
0x46, 0x49, 0x49, 0x29, 0x1E,
|
||||
0x00, 0x00, 0x14, 0x00, 0x00,
|
||||
0x00, 0x40, 0x34, 0x00, 0x00,
|
||||
0x00, 0x08, 0x14, 0x22, 0x41,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x00, 0x41, 0x22, 0x14, 0x08,
|
||||
0x02, 0x01, 0x59, 0x09, 0x06,
|
||||
0x3E, 0x41, 0x5D, 0x59, 0x4E,
|
||||
0x7C, 0x12, 0x11, 0x12, 0x7C,
|
||||
0x7F, 0x49, 0x49, 0x49, 0x36,
|
||||
0x3E, 0x41, 0x41, 0x41, 0x22,
|
||||
0x7F, 0x41, 0x41, 0x41, 0x3E,
|
||||
0x7F, 0x49, 0x49, 0x49, 0x41,
|
||||
0x7F, 0x09, 0x09, 0x09, 0x01,
|
||||
0x3E, 0x41, 0x41, 0x51, 0x73,
|
||||
0x7F, 0x08, 0x08, 0x08, 0x7F,
|
||||
0x00, 0x41, 0x7F, 0x41, 0x00,
|
||||
0x20, 0x40, 0x41, 0x3F, 0x01,
|
||||
0x7F, 0x08, 0x14, 0x22, 0x41,
|
||||
0x7F, 0x40, 0x40, 0x40, 0x40,
|
||||
0x7F, 0x02, 0x1C, 0x02, 0x7F,
|
||||
0x7F, 0x04, 0x08, 0x10, 0x7F,
|
||||
0x3E, 0x41, 0x41, 0x41, 0x3E,
|
||||
0x7F, 0x09, 0x09, 0x09, 0x06,
|
||||
0x3E, 0x41, 0x51, 0x21, 0x5E,
|
||||
0x7F, 0x09, 0x19, 0x29, 0x46,
|
||||
0x26, 0x49, 0x49, 0x49, 0x32,
|
||||
0x03, 0x01, 0x7F, 0x01, 0x03,
|
||||
0x3F, 0x40, 0x40, 0x40, 0x3F,
|
||||
0x1F, 0x20, 0x40, 0x20, 0x1F,
|
||||
0x3F, 0x40, 0x38, 0x40, 0x3F,
|
||||
0x63, 0x14, 0x08, 0x14, 0x63,
|
||||
0x03, 0x04, 0x78, 0x04, 0x03,
|
||||
0x61, 0x59, 0x49, 0x4D, 0x43,
|
||||
0x00, 0x7F, 0x41, 0x41, 0x41,
|
||||
0x02, 0x04, 0x08, 0x10, 0x20,
|
||||
0x00, 0x41, 0x41, 0x41, 0x7F,
|
||||
0x04, 0x02, 0x01, 0x02, 0x04,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40,
|
||||
0x00, 0x03, 0x07, 0x08, 0x00,
|
||||
0x20, 0x54, 0x54, 0x78, 0x40,
|
||||
0x7F, 0x28, 0x44, 0x44, 0x38,
|
||||
0x38, 0x44, 0x44, 0x44, 0x28,
|
||||
0x38, 0x44, 0x44, 0x28, 0x7F,
|
||||
0x38, 0x54, 0x54, 0x54, 0x18,
|
||||
0x00, 0x08, 0x7E, 0x09, 0x02,
|
||||
0x18, 0xA4, 0xA4, 0x9C, 0x78,
|
||||
0x7F, 0x08, 0x04, 0x04, 0x78,
|
||||
0x00, 0x44, 0x7D, 0x40, 0x00,
|
||||
0x20, 0x40, 0x40, 0x3D, 0x00,
|
||||
0x7F, 0x10, 0x28, 0x44, 0x00,
|
||||
0x00, 0x41, 0x7F, 0x40, 0x00,
|
||||
0x7C, 0x04, 0x78, 0x04, 0x78,
|
||||
0x7C, 0x08, 0x04, 0x04, 0x78,
|
||||
0x38, 0x44, 0x44, 0x44, 0x38,
|
||||
0xFC, 0x18, 0x24, 0x24, 0x18,
|
||||
0x18, 0x24, 0x24, 0x18, 0xFC,
|
||||
0x7C, 0x08, 0x04, 0x04, 0x08,
|
||||
0x48, 0x54, 0x54, 0x54, 0x24,
|
||||
0x04, 0x04, 0x3F, 0x44, 0x24,
|
||||
0x3C, 0x40, 0x40, 0x20, 0x7C,
|
||||
0x1C, 0x20, 0x40, 0x20, 0x1C,
|
||||
0x3C, 0x40, 0x30, 0x40, 0x3C,
|
||||
0x44, 0x28, 0x10, 0x28, 0x44,
|
||||
0x4C, 0x90, 0x90, 0x90, 0x7C,
|
||||
0x44, 0x64, 0x54, 0x4C, 0x44,
|
||||
0x00, 0x08, 0x36, 0x41, 0x00,
|
||||
0x00, 0x00, 0x77, 0x00, 0x00,
|
||||
0x00, 0x41, 0x36, 0x08, 0x00,
|
||||
0x02, 0x01, 0x02, 0x04, 0x02,
|
||||
0x3C, 0x26, 0x23, 0x26, 0x3C,
|
||||
0x1E, 0xA1, 0xA1, 0x61, 0x12,
|
||||
0x3A, 0x40, 0x40, 0x20, 0x7A,
|
||||
0x38, 0x54, 0x54, 0x55, 0x59,
|
||||
0x21, 0x55, 0x55, 0x79, 0x41,
|
||||
0x21, 0x54, 0x54, 0x78, 0x41,
|
||||
0x21, 0x55, 0x54, 0x78, 0x40,
|
||||
0x20, 0x54, 0x55, 0x79, 0x40,
|
||||
0x0C, 0x1E, 0x52, 0x72, 0x12,
|
||||
0x39, 0x55, 0x55, 0x55, 0x59,
|
||||
0x39, 0x54, 0x54, 0x54, 0x59,
|
||||
0x39, 0x55, 0x54, 0x54, 0x58,
|
||||
0x00, 0x00, 0x45, 0x7C, 0x41,
|
||||
0x00, 0x02, 0x45, 0x7D, 0x42,
|
||||
0x00, 0x01, 0x45, 0x7C, 0x40,
|
||||
0xF0, 0x29, 0x24, 0x29, 0xF0,
|
||||
0xF0, 0x28, 0x25, 0x28, 0xF0,
|
||||
0x7C, 0x54, 0x55, 0x45, 0x00,
|
||||
0x20, 0x54, 0x54, 0x7C, 0x54,
|
||||
0x7C, 0x0A, 0x09, 0x7F, 0x49,
|
||||
0x32, 0x49, 0x49, 0x49, 0x32,
|
||||
0x32, 0x48, 0x48, 0x48, 0x32,
|
||||
0x32, 0x4A, 0x48, 0x48, 0x30,
|
||||
0x3A, 0x41, 0x41, 0x21, 0x7A,
|
||||
0x3A, 0x42, 0x40, 0x20, 0x78,
|
||||
0x00, 0x9D, 0xA0, 0xA0, 0x7D,
|
||||
0x39, 0x44, 0x44, 0x44, 0x39,
|
||||
0x3D, 0x40, 0x40, 0x40, 0x3D,
|
||||
0x3C, 0x24, 0xFF, 0x24, 0x24,
|
||||
0x48, 0x7E, 0x49, 0x43, 0x66,
|
||||
0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
|
||||
0xFF, 0x09, 0x29, 0xF6, 0x20,
|
||||
0xC0, 0x88, 0x7E, 0x09, 0x03,
|
||||
0x20, 0x54, 0x54, 0x79, 0x41,
|
||||
0x00, 0x00, 0x44, 0x7D, 0x41,
|
||||
0x30, 0x48, 0x48, 0x4A, 0x32,
|
||||
0x38, 0x40, 0x40, 0x22, 0x7A,
|
||||
0x00, 0x7A, 0x0A, 0x0A, 0x72,
|
||||
0x7D, 0x0D, 0x19, 0x31, 0x7D,
|
||||
0x26, 0x29, 0x29, 0x2F, 0x28,
|
||||
0x26, 0x29, 0x29, 0x29, 0x26,
|
||||
0x30, 0x48, 0x4D, 0x40, 0x20,
|
||||
0x38, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x38,
|
||||
0x2F, 0x10, 0xC8, 0xAC, 0xBA,
|
||||
0x2F, 0x10, 0x28, 0x34, 0xFA,
|
||||
0x00, 0x00, 0x7B, 0x00, 0x00,
|
||||
0x08, 0x14, 0x2A, 0x14, 0x22,
|
||||
0x22, 0x14, 0x2A, 0x14, 0x08,
|
||||
0xAA, 0x00, 0x55, 0x00, 0xAA,
|
||||
0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
||||
0x00, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x10, 0x10, 0x10, 0xFF, 0x00,
|
||||
0x14, 0x14, 0x14, 0xFF, 0x00,
|
||||
0x10, 0x10, 0xFF, 0x00, 0xFF,
|
||||
0x10, 0x10, 0xF0, 0x10, 0xF0,
|
||||
0x14, 0x14, 0x14, 0xFC, 0x00,
|
||||
0x14, 0x14, 0xF7, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0xFF,
|
||||
0x14, 0x14, 0xF4, 0x04, 0xFC,
|
||||
0x14, 0x14, 0x17, 0x10, 0x1F,
|
||||
0x10, 0x10, 0x1F, 0x10, 0x1F,
|
||||
0x14, 0x14, 0x14, 0x1F, 0x00,
|
||||
0x10, 0x10, 0x10, 0xF0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x1F, 0x10,
|
||||
0x10, 0x10, 0x10, 0x1F, 0x10,
|
||||
0x10, 0x10, 0x10, 0xF0, 0x10,
|
||||
0x00, 0x00, 0x00, 0xFF, 0x10,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10,
|
||||
0x10, 0x10, 0x10, 0xFF, 0x10,
|
||||
0x00, 0x00, 0x00, 0xFF, 0x14,
|
||||
0x00, 0x00, 0xFF, 0x00, 0xFF,
|
||||
0x00, 0x00, 0x1F, 0x10, 0x17,
|
||||
0x00, 0x00, 0xFC, 0x04, 0xF4,
|
||||
0x14, 0x14, 0x17, 0x10, 0x17,
|
||||
0x14, 0x14, 0xF4, 0x04, 0xF4,
|
||||
0x00, 0x00, 0xFF, 0x00, 0xF7,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0xF7, 0x00, 0xF7,
|
||||
0x14, 0x14, 0x14, 0x17, 0x14,
|
||||
0x10, 0x10, 0x1F, 0x10, 0x1F,
|
||||
0x14, 0x14, 0x14, 0xF4, 0x14,
|
||||
0x10, 0x10, 0xF0, 0x10, 0xF0,
|
||||
0x00, 0x00, 0x1F, 0x10, 0x1F,
|
||||
0x00, 0x00, 0x00, 0x1F, 0x14,
|
||||
0x00, 0x00, 0x00, 0xFC, 0x14,
|
||||
0x00, 0x00, 0xF0, 0x10, 0xF0,
|
||||
0x10, 0x10, 0xFF, 0x10, 0xFF,
|
||||
0x14, 0x14, 0x14, 0xFF, 0x14,
|
||||
0x10, 0x10, 0x10, 0x1F, 0x00,
|
||||
0x00, 0x00, 0x00, 0xF0, 0x10,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x38, 0x44, 0x44, 0x38, 0x44,
|
||||
0x7C, 0x2A, 0x2A, 0x3E, 0x14,
|
||||
0x7E, 0x02, 0x02, 0x06, 0x06,
|
||||
0x02, 0x7E, 0x02, 0x7E, 0x02,
|
||||
0x63, 0x55, 0x49, 0x41, 0x63,
|
||||
0x38, 0x44, 0x44, 0x3C, 0x04,
|
||||
0x40, 0x7E, 0x20, 0x1E, 0x20,
|
||||
0x06, 0x02, 0x7E, 0x02, 0x02,
|
||||
0x99, 0xA5, 0xE7, 0xA5, 0x99,
|
||||
0x1C, 0x2A, 0x49, 0x2A, 0x1C,
|
||||
0x4C, 0x72, 0x01, 0x72, 0x4C,
|
||||
0x30, 0x4A, 0x4D, 0x4D, 0x30,
|
||||
0x30, 0x48, 0x78, 0x48, 0x30,
|
||||
0xBC, 0x62, 0x5A, 0x46, 0x3D,
|
||||
0x3E, 0x49, 0x49, 0x49, 0x00,
|
||||
0x7E, 0x01, 0x01, 0x01, 0x7E,
|
||||
0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
|
||||
0x44, 0x44, 0x5F, 0x44, 0x44,
|
||||
0x40, 0x51, 0x4A, 0x44, 0x40,
|
||||
0x40, 0x44, 0x4A, 0x51, 0x40,
|
||||
0x00, 0x00, 0xFF, 0x01, 0x03,
|
||||
0xE0, 0x80, 0xFF, 0x00, 0x00,
|
||||
0x08, 0x08, 0x6B, 0x6B, 0x08,
|
||||
0x36, 0x12, 0x36, 0x24, 0x36,
|
||||
0x06, 0x0F, 0x09, 0x0F, 0x06,
|
||||
0x00, 0x00, 0x18, 0x18, 0x00,
|
||||
0x00, 0x00, 0x10, 0x10, 0x00,
|
||||
0x30, 0x40, 0xFF, 0x01, 0x01,
|
||||
0x00, 0x1F, 0x01, 0x01, 0x1E,
|
||||
0x00, 0x19, 0x1D, 0x17, 0x12,
|
||||
0x00, 0x3C, 0x3C, 0x3C, 0x3C,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,175 @@
|
||||
// Paint example specifically for the TFTLCD Arduino shield.
|
||||
// If using the breakout board, use the tftpaint.pde sketch instead!
|
||||
|
||||
#include <Adafruit_GFX.h> // Core graphics library
|
||||
#include <Adafruit_TFTLCD.h> // Hardware-specific library
|
||||
#include <TouchScreen.h>
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
#undef __FlashStringHelper::F(string_literal)
|
||||
#define F(string_literal) string_literal
|
||||
#endif
|
||||
|
||||
#ifndef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
#error "This sketch is intended for use with the TFT LCD Shield. Make sure that USE_ADAFRUIT_SHIELD_PINOUT is #defined in the Adafruit_TFTLCD.h library file."
|
||||
#endif
|
||||
|
||||
// These are the pins for the shield!
|
||||
#define YP A1 // must be an analog pin, use "An" notation!
|
||||
#define XM A2 // must be an analog pin, use "An" notation!
|
||||
#define YM 7 // can be a digital pin
|
||||
#define XP 6 // can be a digital pin
|
||||
|
||||
#ifdef __SAM3X8E__
|
||||
#define TS_MINX 125
|
||||
#define TS_MINY 170
|
||||
#define TS_MAXX 880
|
||||
#define TS_MAXY 940
|
||||
#else
|
||||
#define TS_MINX 150
|
||||
#define TS_MINY 120
|
||||
#define TS_MAXX 920
|
||||
#define TS_MAXY 940
|
||||
#endif
|
||||
|
||||
// For better pressure precision, we need to know the resistance
|
||||
// between X+ and X- Use any multimeter to read it
|
||||
// For the one we're using, its 300 ohms across the X plate
|
||||
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
|
||||
|
||||
#define LCD_CS A3
|
||||
#define LCD_CD A2
|
||||
#define LCD_WR A1
|
||||
#define LCD_RD A0
|
||||
|
||||
// Assign human-readable names to some common 16-bit color values:
|
||||
#define BLACK 0x0000
|
||||
#define BLUE 0x001F
|
||||
#define RED 0xF800
|
||||
#define GREEN 0x07E0
|
||||
#define CYAN 0x07FF
|
||||
#define MAGENTA 0xF81F
|
||||
#define YELLOW 0xFFE0
|
||||
#define WHITE 0xFFFF
|
||||
|
||||
|
||||
Adafruit_TFTLCD tft;
|
||||
|
||||
#define BOXSIZE 40
|
||||
#define PENRADIUS 4
|
||||
int oldcolor, currentcolor;
|
||||
|
||||
void setup(void) {
|
||||
Serial.begin(9600);
|
||||
Serial.println(F("Paint!"));
|
||||
|
||||
tft.reset();
|
||||
|
||||
uint16_t identifier = tft.readID();
|
||||
|
||||
if(identifier == 0x9325) {
|
||||
Serial.println(F("Found ILI9325 LCD driver"));
|
||||
} else if(identifier == 0x9328) {
|
||||
Serial.println(F("Found ILI9328 LCD driver"));
|
||||
} else if(identifier == 0x7575) {
|
||||
Serial.println(F("Found HX8347G LCD driver"));
|
||||
} else {
|
||||
Serial.print(F("Unknown LCD driver chip: "));
|
||||
Serial.println(identifier, HEX);
|
||||
return;
|
||||
}
|
||||
|
||||
tft.begin(identifier);
|
||||
|
||||
tft.fillScreen(BLACK);
|
||||
|
||||
tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
|
||||
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
|
||||
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, GREEN);
|
||||
tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, CYAN);
|
||||
tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, BLUE);
|
||||
tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, MAGENTA);
|
||||
// tft.fillRect(BOXSIZE*6, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
|
||||
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
currentcolor = RED;
|
||||
|
||||
pinMode(13, OUTPUT);
|
||||
}
|
||||
|
||||
#define MINPRESSURE 10
|
||||
#define MAXPRESSURE 1000
|
||||
|
||||
void loop()
|
||||
{
|
||||
digitalWrite(13, HIGH);
|
||||
Point p = ts.getPoint();
|
||||
digitalWrite(13, LOW);
|
||||
|
||||
// if sharing pins, you'll need to fix the directions of the touchscreen pins
|
||||
//pinMode(XP, OUTPUT);
|
||||
pinMode(XM, OUTPUT);
|
||||
pinMode(YP, OUTPUT);
|
||||
//pinMode(YM, OUTPUT);
|
||||
|
||||
// we have some minimum pressure we consider 'valid'
|
||||
// pressure of 0 means no pressing!
|
||||
|
||||
if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
|
||||
/*
|
||||
Serial.print("X = "); Serial.print(p.x);
|
||||
Serial.print("\tY = "); Serial.print(p.y);
|
||||
Serial.print("\tPressure = "); Serial.println(p.z);
|
||||
*/
|
||||
|
||||
if (p.y < (TS_MINY-5)) {
|
||||
Serial.println("erase");
|
||||
// press the bottom of the screen to erase
|
||||
tft.fillRect(0, BOXSIZE, tft.width(), tft.height()-BOXSIZE, BLACK);
|
||||
}
|
||||
// scale from 0->1023 to tft.width
|
||||
p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
|
||||
p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);
|
||||
/*
|
||||
Serial.print("("); Serial.print(p.x);
|
||||
Serial.print(", "); Serial.print(p.y);
|
||||
Serial.println(")");
|
||||
*/
|
||||
if (p.y < BOXSIZE) {
|
||||
oldcolor = currentcolor;
|
||||
|
||||
if (p.x < BOXSIZE) {
|
||||
currentcolor = RED;
|
||||
tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
} else if (p.x < BOXSIZE*2) {
|
||||
currentcolor = YELLOW;
|
||||
tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
} else if (p.x < BOXSIZE*3) {
|
||||
currentcolor = GREEN;
|
||||
tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
} else if (p.x < BOXSIZE*4) {
|
||||
currentcolor = CYAN;
|
||||
tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
} else if (p.x < BOXSIZE*5) {
|
||||
currentcolor = BLUE;
|
||||
tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
} else if (p.x < BOXSIZE*6) {
|
||||
currentcolor = MAGENTA;
|
||||
tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, WHITE);
|
||||
}
|
||||
|
||||
if (oldcolor != currentcolor) {
|
||||
if (oldcolor == RED) tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
|
||||
if (oldcolor == YELLOW) tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
|
||||
if (oldcolor == GREEN) tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, GREEN);
|
||||
if (oldcolor == CYAN) tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, CYAN);
|
||||
if (oldcolor == BLUE) tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, BLUE);
|
||||
if (oldcolor == MAGENTA) tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, MAGENTA);
|
||||
}
|
||||
}
|
||||
if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) {
|
||||
tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+474
@@ -0,0 +1,474 @@
|
||||
#ifndef _pin_magic_
|
||||
#define _pin_magic_
|
||||
|
||||
// This header file serves two purposes:
|
||||
//
|
||||
// 1) Isolate non-portable MCU port- and pin-specific identifiers and
|
||||
// operations so the library code itself remains somewhat agnostic
|
||||
// (PORTs and pin numbers are always referenced through macros).
|
||||
//
|
||||
// 2) GCC doesn't always respect the "inline" keyword, so this is a
|
||||
// ham-fisted manner of forcing the issue to minimize function calls.
|
||||
// This sometimes makes the library a bit bigger than before, but fast++.
|
||||
// However, because they're macros, we need to be SUPER CAREFUL about
|
||||
// parameters -- for example, write8(x) may expand to multiple PORT
|
||||
// writes that all refer to x, so it needs to be a constant or fixed
|
||||
// variable and not something like *ptr++ (which, after macro
|
||||
// expansion, may increment the pointer repeatedly and run off into
|
||||
// la-la land). Macros also give us fine-grained control over which
|
||||
// operations are inlined on which boards (balancing speed against
|
||||
// available program space).
|
||||
|
||||
// When using the TFT shield, control and data pins exist in set physical
|
||||
// locations, but the ports and bitmasks corresponding to each vary among
|
||||
// boards. A separate set of pin definitions is given for each supported
|
||||
// board type.
|
||||
// When using the TFT breakout board, control pins are configurable but
|
||||
// the data pins are still fixed -- making every data pin configurable
|
||||
// would be much too slow. The data pin layouts are not the same between
|
||||
// the shield and breakout configurations -- for the latter, pins were
|
||||
// chosen to keep the tutorial wiring manageable more than making optimal
|
||||
// use of ports and bitmasks. So there's a second set of pin definitions
|
||||
// given for each supported board.
|
||||
|
||||
// Shield pin usage:
|
||||
// LCD Data Bit : 7 6 5 4 3 2 1 0
|
||||
// Digital pin #: 7 6 13 4 11 10 9 8
|
||||
// Uno port/pin : PD7 PD6 PB5 PD4 PB3 PB2 PB1 PB0
|
||||
// Mega port/pin: PH4 PH3 PB7 PG5 PB5 PB4 PH6 PH5
|
||||
// Leo port/pin : PE6 PD7 PC7 PD4 PB7 PB6 PB5 PB4
|
||||
// Due port/pin : PC23 PC24 PB27 PC26 PD7 PC29 PC21 PC22
|
||||
// Breakout pin usage:
|
||||
// LCD Data Bit : 7 6 5 4 3 2 1 0
|
||||
// Uno dig. pin : 7 6 5 4 3 2 9 8
|
||||
// Uno port/pin : PD7 PD6 PD5 PD4 PD3 PD2 PB1 PB0
|
||||
// Mega dig. pin: 29 28 27 26 25 24 23 22
|
||||
// Mega port/pin: PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 (one contiguous PORT)
|
||||
// Leo dig. pin : 7 6 5 4 3 2 9 8
|
||||
// Leo port/pin : PE6 PD7 PC6 PD4 PD0 PD1 PB5 PB4
|
||||
// Due dig. pin : 40 39 38 37 36 35 34 33
|
||||
// Due port/pin : PC8 PC7 PC6 PC5 PC4 PC3 PC2 PC1 (one contiguous PORT. -ish…)
|
||||
|
||||
// Pixel read operations require a minimum 400 nS delay from RD_ACTIVE
|
||||
// to polling the input pins. At 16 MHz, one machine cycle is 62.5 nS.
|
||||
// This code burns 7 cycles (437.5 nS) doing nothing; the RJMPs are
|
||||
// equivalent to two NOPs each, final NOP burns the 7th cycle, and the
|
||||
// last line is a radioactive mutant emoticon.
|
||||
#define DELAY7 \
|
||||
asm volatile( \
|
||||
"rjmp .+0" "\n\t" \
|
||||
"rjmp .+0" "\n\t" \
|
||||
"rjmp .+0" "\n\t" \
|
||||
"nop" "\n" \
|
||||
::);
|
||||
|
||||
// Xmega runs at 32 MHz instead of 16, so 13 cycle delays are needed
|
||||
#define DELAY13 \
|
||||
asm volatile( \
|
||||
"rjmp .+0" "\n\t" \
|
||||
"rjmp .+0" "\n\t" \
|
||||
"rjmp .+0" "\n\t" \
|
||||
"rjmp .+0" "\n\t" \
|
||||
"rjmp .+0" "\n\t" \
|
||||
"rjmp .+0" "\n\t" \
|
||||
"nop" "\n" \
|
||||
::);
|
||||
|
||||
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega8__)
|
||||
|
||||
// Arduino Uno, Duemilanove, etc.
|
||||
|
||||
#ifdef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
|
||||
// LCD control lines:
|
||||
// RD (read), WR (write), CD (command/data), CS (chip select)
|
||||
#define RD_PORT PORTC /*pin A0 */
|
||||
#define WR_PORT PORTC /*pin A1 */
|
||||
#define CD_PORT PORTC /*pin A2 */
|
||||
#define CS_PORT PORTC /*pin A3 */
|
||||
#define RD_MASK B00000001
|
||||
#define WR_MASK B00000010
|
||||
#define CD_MASK B00000100
|
||||
#define CS_MASK B00001000
|
||||
|
||||
// These are macros for I/O operations...
|
||||
|
||||
// Write 8-bit value to LCD data lines
|
||||
#define write8inline(d) { \
|
||||
PORTD = (PORTD & B00101111) | ((d) & B11010000); \
|
||||
PORTB = (PORTB & B11010000) | ((d) & B00101111); \
|
||||
WR_STROBE; } // STROBEs are defined later
|
||||
|
||||
// Read 8-bit value from LCD data lines. The signle argument
|
||||
// is a destination variable; this isn't a function and doesn't
|
||||
// return a value in the conventional sense.
|
||||
#define read8inline(result) { \
|
||||
RD_ACTIVE; \
|
||||
DELAY7; \
|
||||
result = (PIND & B11010000) | (PINB & B00101111); \
|
||||
RD_IDLE; }
|
||||
|
||||
// These set the PORT directions as required before the write and read
|
||||
// operations. Because write operations are much more common than reads,
|
||||
// the data-reading functions in the library code set the PORT(s) to
|
||||
// input before a read, and restore them back to the write state before
|
||||
// returning. This avoids having to set it for output inside every
|
||||
// drawing method. The default state has them initialized for writes.
|
||||
#define setWriteDirInline() { DDRD |= B11010000; DDRB |= B00101111; }
|
||||
#define setReadDirInline() { DDRD &= ~B11010000; DDRB &= ~B00101111; }
|
||||
|
||||
#else // Uno w/Breakout board
|
||||
|
||||
#define write8inline(d) { \
|
||||
PORTD = (PORTD & B00000011) | ((d) & B11111100); \
|
||||
PORTB = (PORTB & B11111100) | ((d) & B00000011); \
|
||||
WR_STROBE; }
|
||||
#define read8inline(result) { \
|
||||
RD_ACTIVE; \
|
||||
DELAY7; \
|
||||
result = (PIND & B11111100) | (PINB & B00000011); \
|
||||
RD_IDLE; }
|
||||
#define setWriteDirInline() { DDRD |= B11111100; DDRB |= B00000011; }
|
||||
#define setReadDirInline() { DDRD &= ~B11111100; DDRB &= ~B00000011; }
|
||||
|
||||
#endif
|
||||
|
||||
// As part of the inline control, macros reference other macros...if any
|
||||
// of these are left undefined, an equivalent function version (non-inline)
|
||||
// is declared later. The Uno has a moderate amount of program space, so
|
||||
// only write8() is inlined -- that one provides the most performance
|
||||
// benefit, but unfortunately also generates the most bloat. This is
|
||||
// why only certain cases are inlined for each board.
|
||||
#define write8 write8inline
|
||||
|
||||
#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
|
||||
|
||||
// Arduino Mega, ADK, etc.
|
||||
|
||||
#ifdef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
|
||||
#define RD_PORT PORTF
|
||||
#define WR_PORT PORTF
|
||||
#define CD_PORT PORTF
|
||||
#define CS_PORT PORTF
|
||||
#define RD_MASK B00000001
|
||||
#define WR_MASK B00000010
|
||||
#define CD_MASK B00000100
|
||||
#define CS_MASK B00001000
|
||||
|
||||
#define write8inline(d) { \
|
||||
PORTH = (PORTH&B10000111)|(((d)&B11000000)>>3)|(((d)&B00000011)<<5); \
|
||||
PORTB = (PORTB&B01001111)|(((d)&B00101100)<<2); \
|
||||
PORTG = (PORTG&B11011111)|(((d)&B00010000)<<1); \
|
||||
WR_STROBE; }
|
||||
#define read8inline(result) { \
|
||||
RD_ACTIVE; \
|
||||
DELAY7; \
|
||||
result = ((PINH & B00011000) << 3) | ((PINB & B10110000) >> 2) | \
|
||||
((PING & B00100000) >> 1) | ((PINH & B01100000) >> 5); \
|
||||
RD_IDLE; }
|
||||
#define setWriteDirInline() { \
|
||||
DDRH |= B01111000; DDRB |= B10110000; DDRG |= B00100000; }
|
||||
#define setReadDirInline() { \
|
||||
DDRH &= ~B01111000; DDRB &= ~B10110000; DDRG &= ~B00100000; }
|
||||
|
||||
#else // Mega w/Breakout board
|
||||
|
||||
#define write8inline(d) { PORTA = (d); WR_STROBE; }
|
||||
#define read8inline(result) { \
|
||||
RD_ACTIVE; \
|
||||
DELAY7; \
|
||||
result = PINA; \
|
||||
RD_IDLE; }
|
||||
#define setWriteDirInline() DDRA = 0xff
|
||||
#define setReadDirInline() DDRA = 0
|
||||
|
||||
#endif
|
||||
|
||||
// All of the functions are inlined on the Arduino Mega. When using the
|
||||
// breakout board, the macro versions aren't appreciably larger than the
|
||||
// function equivalents, and they're super simple and fast. When using
|
||||
// the shield, the macros become pretty complicated...but this board has
|
||||
// so much code space, the macros are used anyway. If you need to free
|
||||
// up program space, some macros can be removed, at a minor cost in speed.
|
||||
#define write8 write8inline
|
||||
#define read8 read8inline
|
||||
#define setWriteDir setWriteDirInline
|
||||
#define setReadDir setReadDirInline
|
||||
#define writeRegister8 writeRegister8inline
|
||||
#define writeRegister16 writeRegister16inline
|
||||
#define writeRegister32 writeRegister32inline
|
||||
#define writeRegisterPair writeRegisterPairInline
|
||||
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
|
||||
// Arduino Leonardo
|
||||
|
||||
#ifdef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
|
||||
#define RD_PORT PORTF
|
||||
#define WR_PORT PORTF
|
||||
#define CD_PORT PORTF
|
||||
#define CS_PORT PORTF
|
||||
#define RD_MASK B10000000
|
||||
#define WR_MASK B01000000
|
||||
#define CD_MASK B00100000
|
||||
#define CS_MASK B00010000
|
||||
|
||||
#define write8inline(d) { \
|
||||
PORTE = (PORTE & B10111111) | (((d) & B10000000)>>1); \
|
||||
PORTD = (PORTD & B01101111) | (((d) & B01000000)<<1) | ((d) & B00010000); \
|
||||
PORTC = (PORTC & B01111111) | (((d) & B00100000)<<2); \
|
||||
PORTB = (PORTB & B00001111) | (((d) & B00001111)<<4); \
|
||||
WR_STROBE; }
|
||||
#define read8inline(result) { \
|
||||
RD_ACTIVE; \
|
||||
DELAY7; \
|
||||
result = ((PINE & B01000000) << 1) | ((PIND & B10000000) >> 1) | \
|
||||
((PINC & B10000000) >> 2) | ((PINB & B11110000) >> 4) | \
|
||||
(PIND & B00010000); \
|
||||
RD_IDLE; }
|
||||
#define setWriteDirInline() { \
|
||||
DDRE |= B01000000; DDRD |= B10010000; \
|
||||
DDRC |= B10000000; DDRB |= B11110000; }
|
||||
#define setReadDirInline() { \
|
||||
DDRE &= ~B01000000; DDRD &= ~B10010000; \
|
||||
DDRC &= ~B10000000; DDRB &= ~B11110000; }
|
||||
|
||||
#else // Leonardo w/Breakout board
|
||||
|
||||
#define write8inline(d) { \
|
||||
uint8_t dr1 = (d) >> 1, dl1 = (d) << 1; \
|
||||
PORTE = (PORTE & B10111111) | (dr1 & B01000000); \
|
||||
PORTD = (PORTD & B01101100) | (dl1 & B10000000) | (((d) & B00001000)>>3) |\
|
||||
(dr1 & B00000010) | ((d) & B00010000); \
|
||||
PORTC = (PORTC & B10111111) | (dl1 & B01000000); \
|
||||
PORTB = (PORTB & B11001111) |(((d) & B00000011)<<4); \
|
||||
WR_STROBE; }
|
||||
#define read8inline(result) { \
|
||||
RD_ACTIVE; \
|
||||
DELAY7; \
|
||||
result = (((PINE & B01000000) | (PIND & B00000010)) << 1) | \
|
||||
(((PINC & B01000000) | (PIND & B10000000)) >> 1) | \
|
||||
((PIND & B00000001) << 3) | ((PINB & B00110000) >> 4) | \
|
||||
(PIND & B00010000); \
|
||||
RD_IDLE; }
|
||||
#define setWriteDirInline() { \
|
||||
DDRE |= B01000000; DDRD |= B10010011; \
|
||||
DDRC |= B01000000; DDRB |= B00110000; }
|
||||
#define setReadDirInline() { \
|
||||
DDRE &= ~B01000000; DDRD &= ~B10010011; \
|
||||
DDRC &= ~B01000000; DDRB &= ~B00110000; }
|
||||
|
||||
#endif
|
||||
|
||||
// On the Leonardo, only the write8() macro is used -- though even that
|
||||
// might be excessive given the code size and available program space
|
||||
// on this board. You may need to disable this to get any sizable
|
||||
// program to compile.
|
||||
#define write8 write8inline
|
||||
|
||||
#elif defined(VARIANT_ADAX256A3BU)
|
||||
|
||||
#define write8inline(d) do { PORTC_OUT = d; WR_STROBE; } while (0)
|
||||
#define read8inline(result) do { RD_ACTIVE; DELAY13; result = PORTC_IN; RD_IDLE; } while (0)
|
||||
#define setWriteDirInline() do { PORTC_DIR = 0xFF; } while (0)
|
||||
#define setReadDirInline() do { PORTC_DIR = 0x00; } while (0)
|
||||
|
||||
#define write8 write8inline
|
||||
#define read8 read8inline
|
||||
#define setWriteDir setWriteDirInline
|
||||
#define setReadDir setReadDirInline
|
||||
#define writeRegister8 writeRegister8inline
|
||||
#define writeRegister16 writeRegister16inline
|
||||
#define writeRegister32 writeRegister32inline
|
||||
#define writeRegisterPair writeRegisterPairInline
|
||||
|
||||
#elif defined(VARIANT_MICROTOUCHX)
|
||||
|
||||
#define write8inline(d) do { PORTA_OUT = d; WR_STROBE; } while (0)
|
||||
#define read8inline(result) do { RD_ACTIVE; DELAY13; result = PORTA_IN; RD_IDLE; } while (0)
|
||||
#define setWriteDirInline() do { PORTA_DIR = 0xFF; } while (0)
|
||||
#define setReadDirInline() do { PORTA_DIR = 0x00; } while (0)
|
||||
|
||||
#define write8 write8inline
|
||||
#define read8 read8inline
|
||||
#define setWriteDir setWriteDirInline
|
||||
#define setReadDir setReadDirInline
|
||||
#define writeRegister8 writeRegister8inline
|
||||
#define writeRegister16 writeRegister16inline
|
||||
#define writeRegister32 writeRegister32inline
|
||||
#define writeRegisterPair writeRegisterPairInline
|
||||
|
||||
#elif defined(__SAM3X8E__)
|
||||
|
||||
// Arduino Due
|
||||
|
||||
#ifdef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
|
||||
#define RD_PORT PIOA /*pin A0 */
|
||||
#define WR_PORT PIOA /*pin A1 */
|
||||
#define CD_PORT PIOA /*pin A2 */
|
||||
#define CS_PORT PIOA /*pin A3 */
|
||||
#define RD_MASK 0x00010000
|
||||
#define WR_MASK 0x01000000
|
||||
#define CD_MASK 0x00800000
|
||||
#define CS_MASK 0x00400000
|
||||
|
||||
#define write8inline(d) { \
|
||||
PIO_Set(PIOD, (((d) & 0x08)<<(7-3))); \
|
||||
PIO_Clear(PIOD, (((~d) & 0x08)<<(7-3))); \
|
||||
PIO_Set(PIOC, (((d) & 0x01)<<(22-0)) | (((d) & 0x02)<<(21-1))| (((d) & 0x04)<<(29-2))| (((d) & 0x10)<<(26-4))| (((d) & 0x40)<<(24-6))| (((d) & 0x80)<<(23-7))); \
|
||||
PIO_Clear(PIOC, (((~d) & 0x01)<<(22-0)) | (((~d) & 0x02)<<(21-1))| (((~d) & 0x04)<<(29-2))| (((~d) & 0x10)<<(26-4))| (((~d) & 0x40)<<(24-6))| (((~d) & 0x80)<<(23-7))); \
|
||||
PIO_Set(PIOB, (((d) & 0x20)<<(27-5))); \
|
||||
PIO_Clear(PIOB, (((~d) & 0x20)<<(27-5))); \
|
||||
WR_STROBE; }
|
||||
|
||||
#define read8inline(result) { \
|
||||
RD_ACTIVE; \
|
||||
delayMicroseconds(1); \
|
||||
result = (((PIOC->PIO_PDSR & (1<<23)) >> (23-7)) | ((PIOC->PIO_PDSR & (1<<24)) >> (24-6)) | \
|
||||
((PIOB->PIO_PDSR & (1<<27)) >> (27-5)) | ((PIOC->PIO_PDSR & (1<<26)) >> (26-4)) | \
|
||||
((PIOD->PIO_PDSR & (1<< 7)) >> ( 7-3)) | ((PIOC->PIO_PDSR & (1<<29)) >> (29-2)) | \
|
||||
((PIOC->PIO_PDSR & (1<<21)) >> (21-1)) | ((PIOC->PIO_PDSR & (1<<22)) >> (22-0))); \
|
||||
RD_IDLE;}
|
||||
|
||||
#define setWriteDirInline() { \
|
||||
PIOD->PIO_MDDR |= 0x00000080; /*PIOD->PIO_SODR = 0x00000080;*/ PIOD->PIO_OER |= 0x00000080; PIOD->PIO_PER |= 0x00000080; \
|
||||
PIOC->PIO_MDDR |= 0x25E00000; /*PIOC->PIO_SODR = 0x25E00000;*/ PIOC->PIO_OER |= 0x25E00000; PIOC->PIO_PER |= 0x25E00000; \
|
||||
PIOB->PIO_MDDR |= 0x08000000; /*PIOB->PIO_SODR = 0x08000000;*/ PIOB->PIO_OER |= 0x08000000; PIOB->PIO_PER |= 0x08000000; }
|
||||
|
||||
#define setReadDirInline() { \
|
||||
pmc_enable_periph_clk( ID_PIOD ) ; pmc_enable_periph_clk( ID_PIOC ) ; pmc_enable_periph_clk( ID_PIOB ) ; \
|
||||
PIOD->PIO_PUDR |= 0x00000080; PIOD->PIO_IFDR |= 0x00000080; PIOD->PIO_ODR |= 0x00000080; PIOD->PIO_PER |= 0x00000080; \
|
||||
PIOC->PIO_PUDR |= 0x25E00000; PIOC->PIO_IFDR |= 0x25E00000; PIOC->PIO_ODR |= 0x25E00000; PIOC->PIO_PER |= 0x25E00000; \
|
||||
PIOB->PIO_PUDR |= 0x08000000; PIOB->PIO_IFDR |= 0x08000000; PIOB->PIO_ODR |= 0x08000000; PIOB->PIO_PER |= 0x08000000; }
|
||||
|
||||
// Control signals are ACTIVE LOW (idle is HIGH)
|
||||
// Command/Data: LOW = command, HIGH = data
|
||||
// These are single-instruction operations and always inline
|
||||
#define RD_ACTIVE RD_PORT->PIO_CODR |= RD_MASK
|
||||
#define RD_IDLE RD_PORT->PIO_SODR |= RD_MASK
|
||||
#define WR_ACTIVE WR_PORT->PIO_CODR |= WR_MASK
|
||||
#define WR_IDLE WR_PORT->PIO_SODR |= WR_MASK
|
||||
#define CD_COMMAND CD_PORT->PIO_CODR |= CD_MASK
|
||||
#define CD_DATA CD_PORT->PIO_SODR |= CD_MASK
|
||||
#define CS_ACTIVE CS_PORT->PIO_CODR |= CS_MASK
|
||||
#define CS_IDLE CS_PORT->PIO_SODR |= CS_MASK
|
||||
|
||||
|
||||
#else // Due w/Breakout board
|
||||
|
||||
#define write8inline(d) { \
|
||||
PIO_Set(PIOC, (((d) & 0xFF)<<1)); \
|
||||
PIO_Clear(PIOC, (((~d) & 0xFF)<<1)); \
|
||||
WR_STROBE; }
|
||||
|
||||
#define read8inline(result) { \
|
||||
RD_ACTIVE; \
|
||||
delayMicroseconds(1); \
|
||||
result = ((PIOC->PIO_PDSR & 0x1FE) >> 1); \
|
||||
RD_IDLE;}
|
||||
|
||||
#define setWriteDirInline() { \
|
||||
PIOC->PIO_MDDR |= 0x000001FE; /*PIOC->PIO_SODR |= 0x000001FE;*/ PIOC->PIO_OER |= 0x000001FE; PIOC->PIO_PER |= 0x000001FE; }
|
||||
|
||||
#define setReadDirInline() { \
|
||||
pmc_enable_periph_clk( ID_PIOC ) ; \
|
||||
PIOC->PIO_PUDR |= 0x000001FE; PIOC->PIO_IFDR |= 0x000001FE; PIOC->PIO_ODR |= 0x000001FE; PIOC->PIO_PER |= 0x000001FE; }
|
||||
|
||||
// When using the TFT breakout board, control pins are configurable.
|
||||
#define RD_ACTIVE rdPort->PIO_CODR |= rdPinSet //PIO_Clear(rdPort, rdPinSet)
|
||||
#define RD_IDLE rdPort->PIO_SODR |= rdPinSet //PIO_Set(rdPort, rdPinSet)
|
||||
#define WR_ACTIVE wrPort->PIO_CODR |= wrPinSet //PIO_Clear(wrPort, wrPinSet)
|
||||
#define WR_IDLE wrPort->PIO_SODR |= wrPinSet //PIO_Set(wrPort, wrPinSet)
|
||||
#define CD_COMMAND cdPort->PIO_CODR |= cdPinSet //PIO_Clear(cdPort, cdPinSet)
|
||||
#define CD_DATA cdPort->PIO_SODR |= cdPinSet //PIO_Set(cdPort, cdPinSet)
|
||||
#define CS_ACTIVE csPort->PIO_CODR |= csPinSet //PIO_Clear(csPort, csPinSet)
|
||||
#define CS_IDLE csPort->PIO_SODR |= csPinSet //PIO_Set(csPort, csPinSet)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#error "Board type unsupported / not recognized"
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(__SAM3X8E__)
|
||||
// Stuff common to all Arduino AVR board types:
|
||||
|
||||
#ifdef USE_ADAFRUIT_SHIELD_PINOUT
|
||||
|
||||
// Control signals are ACTIVE LOW (idle is HIGH)
|
||||
// Command/Data: LOW = command, HIGH = data
|
||||
// These are single-instruction operations and always inline
|
||||
#define RD_ACTIVE RD_PORT &= ~RD_MASK
|
||||
#define RD_IDLE RD_PORT |= RD_MASK
|
||||
#define WR_ACTIVE WR_PORT &= ~WR_MASK
|
||||
#define WR_IDLE WR_PORT |= WR_MASK
|
||||
#define CD_COMMAND CD_PORT &= ~CD_MASK
|
||||
#define CD_DATA CD_PORT |= CD_MASK
|
||||
#define CS_ACTIVE CS_PORT &= ~CS_MASK
|
||||
#define CS_IDLE CS_PORT |= CS_MASK
|
||||
|
||||
#elif defined(CORE_ADAX) || defined(CORE_MICROTOUCHX)
|
||||
|
||||
#define RD_ACTIVE ((PORT_t*)rdPort)->OUTCLR = rdPinSet
|
||||
#define RD_IDLE ((PORT_t*)rdPort)->OUTSET = rdPinSet
|
||||
#define WR_ACTIVE ((PORT_t*)wrPort)->OUTCLR = wrPinSet
|
||||
#define WR_IDLE ((PORT_t*)wrPort)->OUTSET = wrPinSet
|
||||
#define CD_COMMAND ((PORT_t*)cdPort)->OUTCLR = cdPinSet
|
||||
#define CD_DATA ((PORT_t*)cdPort)->OUTSET = cdPinSet
|
||||
#define CS_ACTIVE ((PORT_t*)csPort)->OUTCLR = csPinSet
|
||||
#define CS_IDLE ((PORT_t*)csPort)->OUTSET = csPinSet
|
||||
|
||||
#else // Breakout board
|
||||
|
||||
// When using the TFT breakout board, control pins are configurable.
|
||||
#define RD_ACTIVE *rdPort &= rdPinUnset
|
||||
#define RD_IDLE *rdPort |= rdPinSet
|
||||
#define WR_ACTIVE *wrPort &= wrPinUnset
|
||||
#define WR_IDLE *wrPort |= wrPinSet
|
||||
#define CD_COMMAND *cdPort &= cdPinUnset
|
||||
#define CD_DATA *cdPort |= cdPinSet
|
||||
#define CS_ACTIVE *csPort &= csPinUnset
|
||||
#define CS_IDLE *csPort |= csPinSet
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Data write strobe, ~2 instructions and always inline
|
||||
#define WR_STROBE do { WR_ACTIVE; WR_IDLE; } while (0)
|
||||
|
||||
// These higher-level operations are usually functionalized,
|
||||
// except on Mega where's there's gobs and gobs of program space.
|
||||
|
||||
// Set value of TFT register: 8-bit address, 8-bit value
|
||||
#define writeRegister8inline(a, d) do { \
|
||||
CD_COMMAND; write8(a); CD_DATA; write8(d); } while (0)
|
||||
|
||||
// Set value of TFT register: 16-bit address, 16-bit value
|
||||
// See notes at top about macro expansion, hence hi & lo temp vars
|
||||
#define writeRegister16inline(a, d) do { \
|
||||
uint8_t hi, lo; \
|
||||
hi = (a) >> 8; lo = (a); CD_COMMAND; write8(hi); write8(lo); \
|
||||
hi = (d) >> 8; lo = (d); CD_DATA ; write8(hi); write8(lo); } while (0)
|
||||
|
||||
// Set value of TFT register: 8-bit address, 32-bit value
|
||||
// only used for ID_9341
|
||||
// See notes at top about macro expansion, hence hi & lo temp vars
|
||||
#define writeRegister32inline(a, d) do { \
|
||||
CS_ACTIVE; CD_COMMAND;\
|
||||
write8(a);\
|
||||
CD_DATA;\
|
||||
write8(d >> 24); write8(d >> 16); write8(d >> 8); write8(d); \
|
||||
CS_IDLE; } while (0)
|
||||
|
||||
// Set value of 2 TFT registers: Two 8-bit addresses (hi & lo), 16-bit value
|
||||
#define writeRegisterPairInline(aH, aL, d) do { \
|
||||
uint8_t hi = (d) >> 8, lo = (d); \
|
||||
CD_COMMAND; write8(aH); CD_DATA; write8(hi); \
|
||||
CD_COMMAND; write8(aL); CD_DATA; write8(lo); } while(0)
|
||||
|
||||
#endif // _pin_magic_
|
||||
Reference in New Issue
Block a user