diff --git a/ILI9341_regValues.txt b/ILI9341_regValues.txt new file mode 100644 index 0000000..2d4ff13 --- /dev/null +++ b/ILI9341_regValues.txt @@ -0,0 +1,247 @@ + case 0x9341: + _lcd_capable = AUTO_READINC | TWO_PARM_WINDOW | MV_AXIS; + static const uint8_t ILI9341_regValues_kbv[] PROGMEM = { //.kbv MCUFRIEND_kbv + 0x01, 0, // software reset + TFTLCD_DELAY, 150, // 5ms if awake, 125ms if asleep. + 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, //Power Control A [39 2C 00 34 02] + 0xCF, 3, 0x00, 0xC1, 0x30, //Power Control B [00 81 30] + 0xE8, 3, 0x85, 0x00, 0x78, //Driver Timing A [04 11 7A] + 0xEA, 2, 0x00, 0x00, //Driver Timing B [66 00] + 0xED, 4, 0x64, 0x03, 0x12, 0x81, //Power On Seq [55 01 23 01] + 0xF7, 1, 0x20, //Pump Ratio [10] + 0xC0, 1, 0x23, //Power Control 1 [26] + 0xC1, 1, 0x10, //Power Control 2 [00] + 0xC5, 2, 0x3E, 0x28, //VCOM 1 [31 3C] + 0xC7, 1, 0x86, //VCOM 2 [C0] + 0x36, 1, 0x48, //Memory Access [00] + 0xB1, 2, 0x00, 0x18, //Frame Control [00 1B] + 0xB6, 3, 0x08, 0x82, 0x27, //Display Function [0A 82 27 XX] + 0xF2, 1, 0x00, //Enable 3G [02] + 0x26, 1, 0x01, //Gamma Set [01] + 0xE0, 15, 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1, 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00, + 0xE1, 15, 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f, + 0x11, 0, //Sleep Out + TFTLCD_DELAY, 150, + 0x29, 0, //Display On + 0x3A, 1, 0x55, //Pixel Format [66] + }; + static const uint8_t ILI9341_regValues_2_6[] PROGMEM = { // LG 2.6" from AN + 0x01, 0, // software reset + 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, //Power Control A [39 2C 00 34 02] + 0xCF, 3, 0x00, 0xC1, 0x30, //Power Control B [00 81 30] + 0xE8, 3, 0x85, 0x00, 0x78, //Driver Timing A [04 11 7A] + 0xEA, 2, 0x00, 0x00, //Driver Timing B [66 00] + 0xED, 4, 0x64, 0x03, 0x12, 0x81, //Power On Seq [55 01 23 01] + 0xF7, 1, 0x20, //Pump Ratio [10] + 0xC0, 1, 0x23, //Power Control 1 [26] + 0xC1, 1, 0x10, //Power Control 2 [00] + 0xC5, 2, 0x2B, 0x2B, //VCOM 1 [31 3C] + 0xC7, 1, 0xC0, //VCOM 2 [C0] + 0x36, 1, 0x48, //Memory Access [00] + 0xB1, 2, 0x00, 0x1B, //Frame Control [00 1B] +// 0xB6, 3, 0x0A, 0x02, 0x27, //Display Function [0A 82 27 XX] .kbv REV=0 + 0xF2, 1, 0x00, //Enable 3G [02] + 0x26, 1, 0x01, //Gamma Set [01] + 0xE0, 15, 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1, 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00, + 0xE1, 15, 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f, + 0x11, 0, //Sleep Out + TFTLCD_DELAY, 150, + 0x29, 0, //Display On + 0x3A, 1, 0x55, //Pixel Format [66] + }; + static const uint8_t ILI9341_regValues_2_0[] PROGMEM = { // BOE 2.0" + 0x01, 0, // software reset + 0xCF, 3, 0x00, 0x99, 0x30, //Power Control B [00 81 30] + 0xED, 4, 0x64, 0x03, 0x12, 0x81, //Power On Seq [55 01 23 01] + 0xE8, 3, 0x85, 0x10, 0x78, //Driver Timing A [04 11 7A] + 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, //Power Control A [39 2C 00 34 02] + 0xF7, 1, 0x20, //Pump Ratio [10] + 0xEA, 2, 0x00, 0x00, //Driver Timing B [66 00] + 0xC0, 1, 0x26, //Power Control 1 [26] + 0xC1, 1, 0x12, //Power Control 2 [00] + 0xC5, 2, 0x2B, 0x2C, //VCOM 1 [31 3C] + 0xC7, 1, 0xC4, //VCOM 2 [C0] + 0x36, 1, 0x08, //Memory Access [00] + 0xB1, 2, 0x00, 0x1B, //Frame Control [00 1B] +// 0xB6, 3, 0x0A, 0xA2, 0x27, //?? Display Function [0A 82 27 XX] .kbv SS=1 + 0xF2, 1, 0x00, //Enable 3G [02] + 0x26, 1, 0x01, //Gamma Set [01] + 0xE0, 15, 0x0f, 0x24, 0x21, 0x0a, 0x0e, 0x09, 0x51, 0xa9, 0x44, 0x07, 0x10, 0x03, 0x2c, 0x0b, 0x00, + 0xE1, 15, 0x00, 0x1b, 0x1e, 0x05, 0x11, 0x06, 0x2e, 0x56, 0x3b, 0x08, 0x0f, 0x0c, 0x13, 0x14, 0x0f, + 0x11, 0, //Sleep Out + TFTLCD_DELAY, 150, + 0x29, 0, //Display On + 0x3A, 1, 0x55, //Pixel Format [66] + }; + static const uint8_t ILI9341_regValues_2_4[] PROGMEM = { // BOE 2.4" + 0x01, 0, // software reset + TFTLCD_DELAY, 50, // .kbv + 0xCF, 3, 0x00, 0x81, 0x30, //Power Control B [00 81 30] + 0xED, 4, 0x64, 0x03, 0x12, 0x81, //Power On Seq [55 01 23 01] + 0xE8, 3, 0x85, 0x10, 0x78, //Driver Timing A [04 11 7A] + 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, //Power Control A [39 2C 00 34 02] + 0xF7, 1, 0x20, //Pump Ratio [10] + 0xEA, 2, 0x00, 0x00, //Driver Timing B [66 00] + 0xB1, 2, 0x00, 0x1B, //Frame Control [00 1B] +// 0xB6, 2, 0x0A, 0xA2, 0x27, //Display Function [0A 82 27 XX] .kbv SS=1 + 0xC0, 1, 0x21, //Power Control 1 [26] + 0xC1, 1, 0x11, //Power Control 2 [00] + 0xC5, 2, 0x3F, 0x3C, //VCOM 1 [31 3C] + 0xC7, 1, 0xB5, //VCOM 2 [C0] + 0x36, 1, 0x48, //Memory Access [00] + 0xF2, 1, 0x00, //Enable 3G [02] + 0x26, 1, 0x01, //Gamma Set [01] + 0xE0, 15, 0x0f, 0x26, 0x24, 0x0b, 0x0e, 0x09, 0x54, 0xa8, 0x46, 0x0c, 0x17, 0x09, 0x0f, 0x07, 0x00, + 0xE1, 15, 0x00, 0x19, 0x1b, 0x04, 0x10, 0x07, 0x2a, 0x47, 0x39, 0x03, 0x06, 0x06, 0x30, 0x38, 0x0f, + 0x11, 0, //Sleep Out + TFTLCD_DELAY, 150, + 0x29, 0, //Display On + 0x3A, 1, 0x55, //Pixel Format [66] + }; + static const uint8_t ILI9341_regValues_ada[] PROGMEM = { // Adafruit_TFTLCD only works with EXTC=0 + 0x01, 0, // software reset + TFTLCD_DELAY, 50, + 0x28, 0, //Display Off + 0xC0, 1, 0x23, //Power Control 1 [26] + 0xC1, 1, 0x10, //Power Control 2 [00] + 0xC5, 2, 0x2B, 0x2B, //VCOM 1 [31 3C] + 0xC7, 1, 0xC0, //VCOM 2 [C0] + 0x36, 1, 0x88, //Memory Access [00] + 0xB1, 2, 0x00, 0x1B, //Frame Control [00 1B] + 0xB7, 1, 0x07, //Entry Mode [00] + 0x11, 0, //Sleep Out + TFTLCD_DELAY, 150, + 0x29, 0, //Display On + 0x3A, 1, 0x55, //Pixel Format [66] + }; + static const uint8_t ILI9341_regValues_ada9341[] PROGMEM = { // Adafruit_ILI9341 + 0xEF, 3, 0x03, 0x80, 0x02, // + 0xCF, 3, 0x00, 0xC1, 0x30, //Power Control B [00 81 30] + 0xED, 4, 0x64, 0x03, 0x12, 0x81, //Power On Seq [55 01 23 01] + 0xE8, 3, 0x85, 0x00, 0x78, //Driver Timing A [04 11 7A] + 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, //Power Control A [39 2C 00 34 02] + 0xF7, 1, 0x20, //Pump Ratio [10] + 0xEA, 2, 0x00, 0x00, //Driver Timing B [66 00] + 0xC0, 1, 0x23, //Power Control 1 [26] + 0xC1, 1, 0x11, //Power Control 2 [00] + 0xC5, 2, 0x3E, 0x28, //VCOM 1 [31 3C] + 0xC7, 1, 0x86, //VCOM 2 [C0] + 0x36, 1, 0x48, //Memory Access [00] + 0xB1, 2, 0x00, 0x18, //Frame Control [00 1B] + 0xB6, 3, 0x0A, 0x82, 0x27, //?? Display Function [0A 82 27 XX] + 0xF2, 1, 0x00, //Enable 3G [02] + 0x26, 1, 0x01, //Gamma Set [01] + 0xE0, 15, 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1, 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00, + 0xE1, 15, 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f, + + 0x11, 0, //Sleep Out + TFTLCD_DELAY, 150, + 0x29, 0, //Display On + 0x3A, 1, 0x55, //Pixel Format [66] + }; +// init_table(ILI9341_regValues_kbv, sizeof(ILI9341_regValues_kbv)); //ok for me +// init_table(ILI9341_regValues_2_0, sizeof(ILI9341_regValues_2_0)); //wrong direction + init_table(ILI9341_regValues_2_4, sizeof(ILI9341_regValues_2_4)); //wrong direction +// init_table(ILI9341_regValues_2_6, sizeof(ILI9341_regValues_2_6)); //inverted +// init_table(ILI9341_regValues_ada, sizeof(ILI9341_regValues_ada)); //white screen +// init_table(ILI9341_regValues_ada9341, sizeof(ILI9341_regValues_ada9341)); //ok for me + break; + + case 0x9486: + _lcd_capable = AUTO_READINC | TWO_PARM_WINDOW | MV_AXIS; + static const uint8_t ILI9486_regValues[] PROGMEM = { + 0x01, 0, //Soft Reset + 0x28, 0, //Display Off + 0xC0, 2, 0x0d, 0x0d, //Power Control 1 [0x0E0E] + 0xC1, 2, 0x43, 0x00, //Power Control 2 [0x4300] + 0xC2, 1, 0x00, //Power Control 3 + 0xC5, 4, 0x00, 0x48, 0x00, 0x48, //VCOM Control 1 [0x00400040] + 0xB6, 3, 0x00, 0x22, 0x3B, // Display Function Control .kbv SS=1 + // 0xE0,15, 0x0f,0x31,0x2b,0x0c,0x0e,0x08,0x4e,0xf1,0x37,0x07,0x10,0x03,0x0e,0x09,0x00, + // 0xE1,15, 0x00,0x0e,0x14,0x03,0x11,0x07,0x31,0xC1,0x48,0x08,0x0f,0x0c,0x31,0x36,0x0f, + 0x20, 0, // Display Inversion OFF + 0x36, 1, 0x0A, //Memory Access + 0x3A, 1, 0x55, //Interlace Pixel +// 0x21, 0, //Invert display !!! + 0x11, 0, //Sleep Out + TFTLCD_DELAY, 50, + 0x29, 0, //Display On + }; + init_table(ILI9486_regValues, sizeof(ILI9486_regValues)); + p16 = (int16_t *) & HEIGHT; + *p16 = 480; + p16 = (int16_t *) & WIDTH; + *p16 = 320; + break; + + case 0x9488: + _lcd_capable = AUTO_READINC | TWO_PARM_WINDOW | MV_AXIS; + static const uint8_t ILI9488_regValues[] PROGMEM = { + 0x01, 0, //Soft Reset + 0x28, 0, //Display Off + 0xC0, 2, 0x0E, 0x0E, //Power Control 1 [0E 0E] + 0xC1, 1, 0x43, //Power Control 2 [43] + 0xC5, 4, 0x00, 0x22, 0x80, 0x40, //VCOM Control 1 [00 40 00 40] + 0x36, 1, 0x08, //Memory Access [00] + 0x3A, 1, 0x55, //Interlace Pixel [XX] + 0xB1, 2, 0xB0, 0x11, //Frame Rate Control [B0 11] + 0xB6, 3, 0x02, 0x02, 0x3B, //Display Function [02 02 3B] .kbv SS=0 + 0x11, 0, //Sleep Out + TFTLCD_DELAY, 150, + 0x29, 0, //Display On + // 0x2C, 0, + }; + static const uint8_t ILI9488_regValues_max[] PROGMEM = { // Atmel MaxTouch + 0x01, 0, //Soft Reset + TFTLCD_DELAY, 50, + 0x28, 0, //Display Off + 0xC0, 2, 0x10, 0x10, //Power Control 1 [0E 0E] + 0xC1, 1, 0x41, //Power Control 2 [43] + 0xC5, 4, 0x00, 0x22, 0x80, 0x40, //VCOM Control 1 [00 40 00 40] + 0x36, 1, 0x68, //Memory Access [00] + 0xB0, 1, 0x00, //Interface [00] + 0xB1, 2, 0xB0, 0x11, //Frame Rate Control [B0 11] + 0xB4, 1, 0x02, //Inversion Control [02] + 0xB7, 1, 0xC6, //Entry Mode [06] + 0x3A, 1, 0x55, //Interlace Pixel Format [XX] + 0xF7, 4, 0xA9, 0x51, 0x2C, 0x82, //Adjustment Control 3 [A9 51 2C 82] + 0x11, 0, //Sleep Out + TFTLCD_DELAY, 150, + 0x29, 0, //Display On + }; +// init_table(ILI9488_regValues, sizeof(ILI9488_regValues)); + init_table(ILI9488_regValues_max, sizeof(ILI9488_regValues_max)); + p16 = (int16_t *) & HEIGHT; + *p16 = 480; + p16 = (int16_t *) & WIDTH; + *p16 = 320; + break; +// ################################################################################### + case 0x7789: + case 0x8552: + _lcd_capable = AUTO_READINC | TWO_PARM_WINDOW | MV_AXIS; + static const uint8_t ST7789_regValues[] PROGMEM = { + (0x0011); //exit SLEEP mode + TFTLCD_DELAY, 10, + (0x0036), 1, 0x80, //MADCTL: memory data access control + (0x003A), 1, 0x66, //COLMOD: Interface Pixel format *** I use 262K-colors in 18bit/pixel format when using 8-bit interface to allow 3-bytes per pixel +// (0x003A), 1, 0x0055, //COLMOD: Interface Pixel format *** I use 65K-colors in 16bit/pixel (5-6-5) format when using 16-bit interface to allow 1-byte per pixel + (0x00B2), 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, //PORCTRK: Porch setting + (0x00B7), 1, 0x35, //GCTRL: Gate Control + (0x00BB), 1, 0x2B, //VCOMS: VCOM setting + (0x00C0), 1, 0x2C, //LCMCTRL: LCM Control + (0x00C2), 2, 0x01, 0xFF, //VDVVRHEN: VDV and VRH Command Enable + (0x00C3), 1, 0x11, //VRHS: VRH Set + (0x00C4), 1, 0x20, //VDVS: VDV Set + (0x00C6), 1, 0x0F, //FRCTRL2: Frame Rate control in normal mode + (0x00D0), 2, 0xA4, 0xA1, //PWCTRL1: Power Control 1 + (0x00E0), 14, 0xD0, 0x00, 0x05, 0x0E, 0x15, 0x0D, 0x37, 0x43, 0x47, 0x09, 0x15, 0x12, 0x16, 0x19, //PVGAMCTRL: Positive Voltage Gamma control + (0x00E1), 14, 0xD0, 0x00, 0x05, 0x0D, 0x0C, 0x06, 0x2D, 0x44, 0x40, 0x0E, 0x1C, 0x18, 0x16, 0x19, //NVGAMCTRL: Negative Voltage Gamma control + (0x002A), 4, 0x00, 0x00, 0x00, 0xEF, //X address set + (0x002B), 4, 0x00, 0x00, 0x01, 0x3F, //Y address set + TFTLCD_DELAY, 10, + }; + init_table(ST7789_regValues, sizeof(ST7789_regValues)); // + break; + + diff --git a/MCUFRIEND_kbv.cpp b/MCUFRIEND_kbv.cpp new file mode 100644 index 0000000..db65c84 --- /dev/null +++ b/MCUFRIEND_kbv.cpp @@ -0,0 +1,1832 @@ + //#define SUPPORT_0139 //costs about 238 bytes + //#define SUPPORT_1963 +#define SUPPORT_4535 //costs about 184 bytes + //#define SUPPORT_8347A //costs about 408 bytes +#define SUPPORT_8347D //costs about 408 bytes + +#include "MCUFRIEND_kbv.h" +#if defined(USE_SERIAL) + //#include +#include "mcufriend_serial.h" + //uint8_t running; +#elif defined(USE_KEIL) +#include "pin_freedom_8.h" +#define CTL_INIT() { RD_OUTPUT; WR_OUTPUT; CD_OUTPUT; CS_OUTPUT; RESET_OUTPUT; } +#define WriteCmd(x) { CD_COMMAND; write16(x); } +#define WriteData(x) { CD_DATA; write16(x); } +#else +#include "mcufriend_shield.h" +#endif + +#define wait_ms(ms) delay(ms) +#define MIPI_DCS_REV1 (1<<0) +#define AUTO_READINC (1<<1) +#define READ_BGR (1<<2) +#define READ_LOWHIGH (1<<3) +#define READ_24BITS (1<<4) +#define XSA_XEA_16BIT (1<<5) +#define READ_NODUMMY (1<<6) +#define INVERT_GS (1<<8) +#define INVERT_SS (1<<9) +#define MV_AXIS (1<<10) +#define INVERT_RGB (1<<11) +#define REV_SCREEN (1<<12) + +#if (defined(__AVR_ATmega2560__) || defined(__SAM3X8E__))\ + && (defined(USE_MEGA_16BIT_SHIELD) || defined(USE_DUE_16BIT_SHIELD)) +#define USING_16BIT_BUS 1 +#else +#define USING_16BIT_BUS 0 +#endif + +#if defined USE_GFX_KBV +MCUFRIEND_kbv::MCUFRIEND_kbv():Adafruit_GFX(240, 320) +{ + // we can not access GPIO pins until AHB has been enabled. +} +#else +MCUFRIEND_kbv::MCUFRIEND_kbv(int CS, int RS, int WR, int RD, int RST):Adafruit_GFX(240, 320) +{ + // we can not access GPIO pins until AHB has been enabled. +} +#endif + +static uint8_t done_reset, is8347; + +void MCUFRIEND_kbv::reset(void) +{ + done_reset = 1; + setWriteDir(); + CTL_INIT(); + CS_IDLE; + RD_IDLE; + WR_IDLE; + RESET_IDLE; + wait_ms(50); + RESET_ACTIVE; + wait_ms(100); + RESET_IDLE; + wait_ms(100); +} + +void MCUFRIEND_kbv::WriteCmdData(uint16_t cmd, uint16_t dat) +{ + CS_ACTIVE; + WriteCmd(cmd); + WriteData(dat); + CS_IDLE; +} + +static void WriteCmdParamN(uint16_t cmd, int8_t N, uint8_t * block) + //void MCUFRIEND_kbv::WriteCmdParamN(uint16_t cmd, int8_t N, uint8_t * block) +{ + CS_ACTIVE; + WriteCmd(cmd); + while (N-- > 0) { + uint8_t u8 = *block++; + CD_DATA; + write8(u8); + if (N && is8347) { + cmd++; + WriteCmd(cmd); + } + } + CS_IDLE; +} + +static inline void WriteCmdParam4(uint8_t cmd, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4) +{ + uint8_t d[4]; + d[0] = d1, d[1] = d2, d[2] = d3, d[3] = d4; + WriteCmdParamN(cmd, 4, d); +} + +static uint16_t read16bits(void) +{ + uint16_t ret; + uint8_t lo; +#if USING_16BIT_BUS + READ_16(ret); //single strobe to read whole bus + if (ret > 255) //ID might say 0x00D3 + return ret; +#else + READ_8(ret); +#endif + //all MIPI_DCS_REV1 style params are 8-bit + READ_8(lo); + return (ret << 8) | lo; +} + +uint16_t MCUFRIEND_kbv::readReg(uint16_t reg) +{ + uint16_t ret; + uint8_t lo; + if (!done_reset) + reset(); + CS_ACTIVE; + WriteCmd(reg); + setReadDir(); + CD_DATA; + // READ_16(ret); + ret = read16bits(); + RD_IDLE; + CS_IDLE; + setWriteDir(); + return ret; +} + +uint32_t MCUFRIEND_kbv::readReg32(uint16_t reg) +{ + uint16_t h, l; + CS_ACTIVE; + WriteCmd(reg); + setReadDir(); + CD_DATA; + h = read16bits(); + l = read16bits(); + RD_IDLE; + CS_IDLE; + setWriteDir(); + return ((uint32_t) h << 16) | (l); +} + +uint16_t MCUFRIEND_kbv::readID(void) +{ + uint16_t ret, ret2; + uint8_t msb; + ret = readReg(0); //forces a reset() if called before begin() + if (ret == 0x5408) //the SPFD5408 fails the 0xD3D3 test. + return 0x5408; + if (ret == 0x0089 || ret == 0x8989) + return 0x1289; + ret = readReg(0x67); //HX8347-A + if (ret == 0x4747) + return 0x8347; + ret = readReg32(0xA1); //for SSD1963 [0x01576101] + if (ret == 0x6101) + return 0x1963; + ret = readReg32(0xBF); //for ILI9481 + if (ret == 0x0494) + return 0x9481; + ret = readReg32(0xEF); //for ILI9327 + if (ret == 0x0493) + return 0x9327; + ret = readReg32(0x04); //0x8552 for ST7789V + if (ret == 0x8552) + return 0x7789; + ret = readReg32(0xD3); //for ILI9488, 9486, 9340, 9341 + msb = ret >> 8; + if (msb == 0x93 || msb == 0x94) + return ret; //0x9488, 9486, 9340, 9341 + if (ret == 0x00D3 || ret == 0xD3D3) + return ret; //16-bit write-only bus + return readReg(0); //0154, 7783, 9320, 9325, 9335, B505, B509 +} + + // independent cursor and window registers. S6D0154, ST7781 increments. ILI92320/5 do not. +int16_t MCUFRIEND_kbv::readGRAM(int16_t x, int16_t y, uint16_t * block, int16_t w, int16_t h) +{ + uint16_t ret, dummy, _MR = _MW; + int16_t n = w * h, row = 0, col = 0; + uint8_t r, g, b, tmp; + if (_lcd_capable & MIPI_DCS_REV1) + _MR = 0x2E; + setAddrWindow(x, y, x + w - 1, y + h - 1); + while (n > 0) { + if (!(_lcd_capable & MIPI_DCS_REV1)) { + WriteCmdData(_MC, x + col); + WriteCmdData(_MP, y + row); + } + CS_ACTIVE; + WriteCmd(_MR); + setReadDir(); + CD_DATA; + if (_lcd_capable & READ_NODUMMY) { + ; + } else if ((_lcd_capable & MIPI_DCS_REV1) || _lcd_ID == 0x1289) { + READ_8(r); + } else { + READ_16(dummy); + } + while (n) { + if (_lcd_capable & READ_24BITS) { + READ_8(r); + READ_8(g); + READ_8(b); + if (_lcd_capable & READ_BGR) + ret = color565(b, g, r); + else + ret = color565(r, g, b); + } else { + READ_16(ret); + if (_lcd_capable & READ_LOWHIGH) + ret = (ret >> 8) | (ret << 8); + if (_lcd_capable & READ_BGR) + ret = (ret & 0x07E0) | (ret >> 11) | (ret << 11); + } + *block++ = ret; + n--; + if (!(_lcd_capable & AUTO_READINC)) + break; + } + if (++col >= w) { + col = 0; + if (++row >= h) + row = 0; + } + RD_IDLE; + CS_IDLE; + setWriteDir(); + } + if (!(_lcd_capable & MIPI_DCS_REV1)) + setAddrWindow(0, 0, width() - 1, height() - 1); + return 0; +} + +void MCUFRIEND_kbv::setRotation(uint8_t r) +{ + uint16_t GS, SS, ORG, REV = _lcd_rev; + uint8_t val, d[3]; + rotation = r & 3; // just perform the operation ourselves on the protected variables + _width = (rotation & 1) ? HEIGHT : WIDTH; + _height = (rotation & 1) ? WIDTH : HEIGHT; + switch (rotation) { + case 0: //PORTRAIT: + val = 0x48; //MY=0, MX=1, MV=0, ML=0, BGR=1 + break; + case 1: //LANDSCAPE: 90 degrees + val = 0x28; //MY=0, MX=0, MV=1, ML=0, BGR=1 + break; + case 2: //PORTRAIT_REV: 180 degrees + val = 0x98; //MY=1, MX=0, MV=0, ML=1, BGR=1 + break; + case 3: //LANDSCAPE_REV: 270 degrees + val = 0xF8; //MY=1, MX=1, MV=1, ML=1, BGR=1 + break; + } + if (_lcd_capable & INVERT_GS) + val ^= 0x80; + if (_lcd_capable & INVERT_SS) + val ^= 0x40; + if (_lcd_capable & INVERT_RGB) + val ^= 0x08; + if (_lcd_capable & MIPI_DCS_REV1) { + if (_lcd_ID == 0x9486) { +#if USING_16BIT_BUS + // my 16-bit write-only shield seems to be an ILI9486 + _lcd_capable &= ~REV_SCREEN; + GS = (val & 0x80) ? (1 << 6) : 0; //MY + SS = (val & 0x40) ? (1 << 5) : 0; //MX + val &= 0x28; //keep MV, BGR, MY=0, MX=0, ML=0 + d[0] = 0; + d[1] = GS | SS | 0x02; //MY, MX + d[2] = 0x3B; + WriteCmdParamN(0xB6, 3, d); +#endif + goto common_MC; + } else if (_lcd_ID == 0x1963 || _lcd_ID == 0x9481) { + if (val & 0x80) + val |= 0x01; //GS + if ((val & 0x40)) + val |= 0x02; //SS + val &= (_lcd_ID == 0x1963) ? ~0xC0 : ~0xD0; //MY=0, MX=0 with ML=0 for ILI9481 + goto common_MC; + } else if (is8347) { + _MC = 0x02, _MP = 0x06, _MW = 0x22, _SC = 0x02, _EC = 0x04, _SP = 0x06, _EP = 0x08; + goto common_BGR; + } + common_MC: + _MC = 0x2A, _MP = 0x2B, _MW = 0x2C, _SC = 0x2A, _EC = 0x2A, _SP = 0x2B, _EP = 0x2B; + common_BGR: + WriteCmdParamN(is8347 ? 0x16 : 0x36, 1, &val); + _lcd_madctl = val; + } + // cope with 9320 variants + else { + switch (_lcd_ID) { +#ifdef SUPPORT_0139 + case 0x0139: + _SC = 0x46, _EC = 0x46, _SP = 0x48, _EP = 0x47; + goto common_S6D; +#endif + case 0x0154: + _SC = 0x37, _EC = 0x36, _SP = 0x39, _EP = 0x38; + common_S6D: + _MC = 0x20, _MP = 0x21, _MW = 0x22; + GS = (val & 0x80) ? (1 << 9) : 0; + SS = (val & 0x40) ? (1 << 8) : 0; + WriteCmdData(0x01, GS | SS | 0x0028); // set Driver Output Control + goto common_ORG; + case 0xB509: + _MC = 0x200, _MP = 0x201, _MW = 0x202, _SC = 0x210, _EC = 0x211, _SP = 0x212, _EP = 0x213; + GS = (val & 0x80) ? (1 << 15) : 0; + WriteCmdData(0x400, GS | 0x6200); + goto common_SS; + default: + _MC = 0x20, _MP = 0x21, _MW = 0x22, _SC = 0x50, _EC = 0x51, _SP = 0x52, _EP = 0x53; + GS = (val & 0x80) ? (1 << 15) : 0; + WriteCmdData(0x60, GS | 0x2700); // Gate Scan Line (0xA700) + common_SS: + SS = (val & 0x40) ? (1 << 8) : 0; + WriteCmdData(0x01, SS); // set Driver Output Control + common_ORG: + ORG = (val & 0x20) ? (1 << 3) : 0; + if (val & 0x08) + ORG |= 0x1000; //BGR + _lcd_madctl = ORG | 0x0030; + WriteCmdData(0x03, _lcd_madctl); // set GRAM write direction and BGR=1. + break; + case 0x1289: + _MC = 0x4E, _MP = 0x4F, _MW = 0x22, _SC = 0x44, _EC = 0x44, _SP = 0x45, _EP = 0x46; + if (rotation & 1) + val ^= 0xD0; // exchange Landscape modes + GS = (val & 0x80) ? (1 << 14) | (1 << 12) : 0; //called TB (top-bottom) + SS = (val & 0x40) ? (1 << 9) : 0; //called RL (right-left) + ORG = (val & 0x20) ? (1 << 3) : 0; //called AM + _lcd_drivOut = GS | SS | (REV << 13) | 0x013F; //REV=0, BGR=0, MUX=319 + if (val & 0x08) + _lcd_drivOut |= 0x0800; //BGR + WriteCmdData(0x01, _lcd_drivOut); // set Driver Output Control + WriteCmdData(0x11, ORG | 0x6070); // set GRAM write direction. + break; + } + } + if ((rotation & 1) && ((_lcd_capable & MV_AXIS) == 0)) { + uint16_t x; + x = _MC, _MC = _MP, _MP = x; + x = _SC, _SC = _SP, _SP = x; //.kbv check 0139 + x = _EC, _EC = _EP, _EP = x; //.kbv check 0139 + } + setAddrWindow(0, 0, width() - 1, height() - 1); + vertScroll(0, HEIGHT, 0); //reset scrolling after a rotation +} + +void MCUFRIEND_kbv::drawPixel(int16_t x, int16_t y, uint16_t color) +{ + // MCUFRIEND just plots at edge if you try to write outside of the box: + if (x < 0 || y < 0 || x >= width() || y >= height()) + return; + if (_lcd_capable & MIPI_DCS_REV1) { + WriteCmdParam4(_MC, x >> 8, x, x >> 8, x); + WriteCmdParam4(_MP, y >> 8, y, y >> 8, y); + } else { + WriteCmdData(_MC, x); + WriteCmdData(_MP, y); + } + WriteCmdData(_MW, color); +} + +void MCUFRIEND_kbv::setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1) +{ + if (_lcd_capable & MIPI_DCS_REV1) { + WriteCmdParam4(_MC, x >> 8, x, x1 >> 8, x1); + WriteCmdParam4(_MP, y >> 8, y, y1 >> 8, y1); + } else { + WriteCmdData(_MC, x); + WriteCmdData(_MP, y); + if (_lcd_capable & XSA_XEA_16BIT) { + if (rotation & 1) + y1 = y = (y1 << 8) | y; + else + x1 = x = (x1 << 8) | x; + } + WriteCmdData(_SC, x); + WriteCmdData(_SP, y); + WriteCmdData(_EC, x1); + WriteCmdData(_EP, y1); + } +} + +void MCUFRIEND_kbv::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) +{ + int16_t end; + if (w < 0) { + w = -w; + x -= w; + } //+ve w + end = x + w; + if (x < 0) + x = 0; + if (end > width()) + end = width(); + w = end - x; + if (h < 0) { + h = -h; + y -= h; + } //+ve h + end = y + h; + if (y < 0) + y = 0; + if (end > height()) + end = height(); + h = end - y; + + setAddrWindow(x, y, x + w - 1, y + h - 1); + CS_ACTIVE; + WriteCmd(_MW); + if (h > w) { + end = h; + h = w; + w = end; + } + uint8_t hi = color >> 8, lo = color & 0xFF; + CD_DATA; + while (h-- > 0) { + end = w; +#if USING_16BIT_BUS +#if defined(__SAM3X8E__) +#define STROBE_16BIT {WR_ACTIVE;WR_ACTIVE;WR_ACTIVE;WR_IDLE;WR_IDLE;} +#else +#define STROBE_16BIT {WR_ACTIVE; WR_IDLE;} +#endif + write_16(color); //we could just do the strobe + lo = end & 7; + hi = end >> 3; + if (hi) + do { + STROBE_16BIT; + STROBE_16BIT; + STROBE_16BIT; + STROBE_16BIT; + STROBE_16BIT; + STROBE_16BIT; + STROBE_16BIT; + STROBE_16BIT; + } while (--hi > 0); + while (lo-- > 0) { + STROBE_16BIT; + } +#else + do { + write8(hi); + write8(lo); + } while (--end != 0); +#endif + } + CS_IDLE; + if (!(_lcd_capable & MIPI_DCS_REV1)) + setAddrWindow(0, 0, width() - 1, height() - 1); +} + +void MCUFRIEND_kbv::pushColors(uint16_t * block, int16_t n, bool first) +{ + uint16_t color; + CS_ACTIVE; + if (first) { + WriteCmd(_MW); + } + CD_DATA; + while (n-- > 0) { + color = *block++; + write16(color); + } + CS_IDLE; +} + +void MCUFRIEND_kbv::pushColors(uint8_t * block, int16_t n, bool first) +{ + uint16_t color; + uint8_t h, l; + CS_ACTIVE; + if (first) { + WriteCmd(_MW); + } + CD_DATA; + while (n-- > 0) { + h = (*block++); + l = (*block++); + color = h << 8 | l; + write16(color); + } + CS_IDLE; +} + +void MCUFRIEND_kbv::pushColors(const uint8_t * block, int16_t n, bool first) +{ + uint16_t color; + uint8_t h, l; + CS_ACTIVE; + if (first) { + WriteCmd(_MW); + } + CD_DATA; + while (n-- > 0) { + l = pgm_read_byte(block++); + h = pgm_read_byte(block++); + color = h << 8 | l; + write16(color); + } + CS_IDLE; +} + +void MCUFRIEND_kbv::vertScroll(int16_t top, int16_t scrollines, int16_t offset) +{ + int16_t bfa = HEIGHT - top - scrollines; // bottom fixed area + int16_t vsp; + int16_t sea = top; + vsp = top + offset; // vertical start position + if (offset < 0) + vsp += scrollines; //keep in unsigned range + sea = top + scrollines - 1; + if (_lcd_capable & MIPI_DCS_REV1) { + uint8_t d[6]; // for multi-byte parameters + if (_lcd_ID == 0x9327) { //panel is wired for 240x432 + if (rotation == 2 || rotation == 3) { //180 or 270 degrees + if (scrollines == HEIGHT) { + scrollines = 432; // we get a glitch but hey-ho + vsp -= 432 - HEIGHT; + } + if (vsp < 0) + vsp += 432; + } + bfa = 432 - top - scrollines; + } + d[0] = top >> 8; //TFA + d[1] = top; + d[2] = scrollines >> 8; //VSA + d[3] = scrollines; + d[4] = bfa >> 8; //BFA + d[5] = bfa; + WriteCmdParamN(is8347 ? 0x0E : 0x33, 6, d); + d[0] = vsp >> 8; //VSP + d[1] = vsp; + WriteCmdParamN(is8347 ? 0x14 : 0x37, 2, d); + return; + } + // cope with 9320 style variants: + switch (_lcd_ID) { + case 0x7783: + WriteCmdData(0x61, _lcd_rev); //!NDL, !VLE, REV + WriteCmdData(0x6A, vsp); //VL# + break; +#ifdef SUPPORT_0139 + case 0x0139: + WriteCmdData(0x41, sea); //SEA + WriteCmdData(0x42, top); //SSA + WriteCmdData(0x43, vsp - top); //SST + break; +#endif + case 0x0154: + WriteCmdData(0x31, sea); //SEA + WriteCmdData(0x32, top); //SSA + WriteCmdData(0x33, vsp - top); //SST + break; + case 0x1289: + WriteCmdData(0x41, vsp); //VL# + break; + case 0xB509: + WriteCmdData(0x401, (1 << 1) | _lcd_rev); //VLE, REV + WriteCmdData(0x404, vsp); //VL# + break; + default: + // 0x6809, 0x9320, 0x9325, 0x9335, 0xB505 can only scroll whole screen + WriteCmdData(0x61, (1 << 1) | _lcd_rev); //!NDL, VLE, REV + WriteCmdData(0x6A, vsp); //VL# + break; + } +} + +void MCUFRIEND_kbv::invertDisplay(boolean i) +{ + uint8_t val; + _lcd_rev = ((_lcd_capable & REV_SCREEN) != 0) ^ i; + if (_lcd_capable & MIPI_DCS_REV1) { + if (is8347) { + // HX8347D: 0x36 Panel Characteristic. REV_Panel + // HX8347A: 0x36 is Display Control 10 +#if defined(SUPPORT_8347D) + val = _lcd_rev ? 8 : 10; //HX8347-D: SCROLLON=bit3, INVON=bit1 +#else + val = _lcd_rev ? 6 : 2; //INVON id bit#2 on HX8347-A. NORON=bit#1 +#endif + // HX8347: 0x01 Display Mode has diff bit mapping for A, D + WriteCmdParamN(0x01, 1, &val); + } else + WriteCmdParamN(_lcd_rev ? 0x21 : 0x20, 0, NULL); + return; + } + // cope with 9320 style variants: + switch (_lcd_ID) { +#ifdef SUPPORT_0139 + case 0x0139: +#endif + case 0x0154: + WriteCmdData(0x07, 0x13 | (_lcd_rev << 2)); //.kbv kludge + break; + case 0x1289: + _lcd_drivOut &= ~(1 << 13); + if (_lcd_rev) + _lcd_drivOut |= (1 << 13); + WriteCmdData(0x01, _lcd_drivOut); + break; + case 0xB509: + WriteCmdData(0x401, (1 << 1) | _lcd_rev); //.kbv kludge VLE + break; + default: + WriteCmdData(0x61, _lcd_rev); + break; + } +} + +#define TFTLCD_DELAY 0xFFFF +#define TFTLCD_DELAY8 0xFF +static void init_table(const void *table, int16_t size) +{ + uint8_t *p = (uint8_t *) table, dat[16]; + while (size > 0) { + uint8_t cmd = pgm_read_byte(p++); + uint8_t len = pgm_read_byte(p++); + if (cmd == TFTLCD_DELAY8) { + delay(len); + len = 0; + } else { + for (uint8_t i = 0; i < len; i++) + dat[i] = pgm_read_byte(p++); + WriteCmdParamN(cmd, len, dat); + } + size -= len + 2; + } +} + +static void init_table16(const void *table, int16_t size) +{ + uint16_t *p = (uint16_t *) table; + while (size > 0) { + uint16_t cmd = pgm_read_word(p++); + uint16_t d = pgm_read_word(p++); + if (cmd == TFTLCD_DELAY) + delay(d); + else { + CS_ACTIVE; + WriteCmd(cmd); + WriteData(d); + CS_IDLE; + } + size -= 2 * sizeof(int16_t); + } +} + +void MCUFRIEND_kbv::begin(uint16_t ID) +{ + int16_t *p16; //so we can "write" to a const protected variable. + reset(); + _lcd_xor = 0; + if (ID == 0) + ID = 0x9341; + switch (_lcd_ID = ID) { +/* + static const uint16_t _regValues[] PROGMEM = { + 0x0000, 0x0001, // start oscillation + 0x0007, 0x0000, // source output control 0 D0 + 0x0013, 0x0000, // power control 3 off + 0x0011, 0x2604, // + 0x0014, 0x0015, // + 0x0010, 0x3C00, // + // 0x0013, 0x0040, // + // 0x0013, 0x0060, // + // 0x0013, 0x0070, // + 0x0013, 0x0070, // power control 3 PON PON1 AON + + 0x0001, 0x0127, // driver output control + // 0x0002, 0x0700, // field 0 b/c waveform xor waveform + 0x0003, 0x1030, // + 0x0007, 0x0000, // + 0x0008, 0x0404, // + 0x000B, 0x0200, // + 0x000C, 0x0000, // + 0x00015,0x0000, // + + //gamma setting + 0x0030, 0x0000, + 0x0031, 0x0606, + 0x0032, 0x0006, + 0x0033, 0x0403, + 0x0034, 0x0107, + 0x0035, 0x0101, + 0x0036, 0x0707, + 0x0037, 0x0304, + 0x0038, 0x0A00, + 0x0039, 0x0706, + + 0x0040, 0x0000, + 0x0041, 0x0000, + 0x0042, 0x013F, + 0x0043, 0x0000, + 0x0044, 0x0000, + 0x0045, 0x0000, + 0x0046, 0xEF00, + 0x0047, 0x013F, + 0x0048, 0x0000, + 0x0007, 0x0011, + 0x0007, 0x0017, +}; +*/ +#ifdef SUPPORT_0139 + case 0x0139: + _lcd_capable = AUTO_READINC | REV_SCREEN | XSA_XEA_16BIT; + static const uint16_t S6D0139_regValues[] PROGMEM = { + 0x0000, 0x0001, //Start oscillator + 0x0011, 0x1a00, //Power Control 2 + 0x0014, 0x2020, //Power Control 4 + 0x0010, 0x0900, //Power Control 1 + 0x0013, 0x0040, //Power Control 3 + 0x0013, 0x0060, //Power Control 3 + 0x0013, 0x0070, //Power Control 3 + 0x0011, 0x1a04, //Power Control 2 + 0x0010, 0x2f00, //Power Control 1 + 0x0001, 0x0127, //Driver Control: SM=0, GS=0, SS=1, 240x320 + 0x0002, 0x0100, //LCD Control: (.kbv was 0700) FLD=0, BC= 0, EOR=1 + 0x0003, 0x1030, //Entry Mode: TR1=0, DFM=0, BGR=1, I_D=3 + 0x0007, 0x0000, //Display Control: everything off + 0x0008, 0x0808, //Blank Period: FP=98, BP=8 + 0x0009, 0x0000, //f.k. + 0x000b, 0x0000, //Frame Control: + 0x000c, 0x0000, //Interface Control: system i/f + 0x0040, 0x0000, //Scan Line + 0x0041, 0x0000, //Vertical Scroll Control + 0x0042, 0x013f, //Screen 1 End + 0x0043, 0x0000, //Screen 1 start + 0x0044, 0x00ef, //Screen 2 end + 0x0045, 0x0000, //Screen 2 start + 0x0046, 0xef00, //Horiz address H=end, L=start + 0x0047, 0x013f, //Vert end + 0x0048, 0x0000, //Vert start + 0x0007, 0x0014, //Display Control: SPT=1, REV=1 + 0x0007, 0x0016, //Display Control: SPT=1, REV=1, display on + 0x0007, 0x0017, //Display Control: SPT=1, REV=1, display on, GON + }; + init_table16(S6D0139_regValues, sizeof(S6D0139_regValues)); + break; +#endif + case 0x0154: + _lcd_capable = AUTO_READINC | REV_SCREEN; + static const uint16_t S6D0154_regValues[] PROGMEM = { + 0x0011, 0x001A, + 0x0012, 0x3121, + 0x0013, 0x006C, + 0x0014, 0x4249, + + 0x0010, 0x0800, + TFTLCD_DELAY, 10, + 0x0011, 0x011A, + TFTLCD_DELAY, 10, + 0x0011, 0x031A, + TFTLCD_DELAY, 10, + 0x0011, 0x071A, + TFTLCD_DELAY, 10, + 0x0011, 0x0F1A, + TFTLCD_DELAY, 10, + 0x0011, 0x0F3A, + TFTLCD_DELAY, 30, + + 0x0001, 0x0128, + 0x0002, 0x0100, + 0x0003, 0x1030, + 0x0007, 0x1012, + 0x0008, 0x0303, + 0x000B, 0x1100, + 0x000C, 0x0000, + 0x000F, 0x1801, + 0x0015, 0x0020, + /* + 0x0050,0x0101, + 0x0051,0x0603, + 0x0052,0x0408, + 0x0053,0x0000, + 0x0054,0x0605, + 0x0055,0x0406, + 0x0056,0x0303, + 0x0057,0x0303, + 0x0058,0x0010, + 0x0059,0x1000, + */ + 0x0007, 0x0012, + TFTLCD_DELAY, 40, + 0x0007, 0x0013, /* GRAM Address Set */ + 0x0007, 0x0017, /* Display Control DISPLAY ON */ + + 0x0036, 0x00EF, + 0x0037, 0x0000, + 0x0038, 0x013F, + 0x0039, 0x0000, + }; + init_table16(S6D0154_regValues, sizeof(S6D0154_regValues)); + + break; + + case 0x1289: + _lcd_capable = 0 | XSA_XEA_16BIT | REV_SCREEN; + // came from MikroElektronika library http://www.hmsprojects.com/tft_lcd.html + static const uint16_t SSD1289_regValues[] PROGMEM = { + 0x0000, 0x0001, + 0x0003, 0xA8A4, + 0x000C, 0x0000, + 0x000D, 0x080C, // was 0x800C + 0x000E, 0x2B00, + 0x001E, 0x00B7, + 0x0001, 0x2B3F, // was 0x2B3F, + 0x0002, 0x0400, // was 0x0600 + 0x0010, 0x0000, + 0x0011, 0x6070, // was 0x6070 + 0x0005, 0x0000, + 0x0006, 0x0000, + 0x0016, 0xEF1C, + 0x0017, 0x0003, + 0x0007, 0x0233, + 0x000B, 0x0000, + 0x000F, 0x0000, + 0x0041, 0x0000, + 0x0042, 0x0000, + 0x0048, 0x0000, + 0x0049, 0x013F, + 0x004A, 0x0000, + 0x004B, 0x0000, + 0x0044, 0xEF95, + 0x0045, 0x0000, + 0x0046, 0x013F, + 0x0030, 0x0707, + 0x0031, 0x0204, + 0x0032, 0x0204, + 0x0033, 0x0502, + 0x0034, 0x0507, + 0x0035, 0x0204, + 0x0036, 0x0204, + 0x0037, 0x0502, + 0x003A, 0x0302, + 0x003B, 0x0302, + 0x0023, 0x0000, + 0x0024, 0x0000, + 0x0025, 0x8000, + 0x004f, 0x0000, + 0x004e, 0x0000, + }; + init_table16(SSD1289_regValues, sizeof(SSD1289_regValues)); + break; + +#ifdef SUPPORT_1963 + case 0x1963: + _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | READ_NODUMMY | INVERT_SS | INVERT_RGB; + // from NHD 5.0" 8-bit + static const uint8_t SSD1963_NHD_50_regValues[] PROGMEM = { + 0x01, 0, //Soft Reset + TFTLCD_DELAY8, 100, + (0xE0), 1, 0x01, // PLL enable + TFTLCD_DELAY8, 10, + (0xE0), 1, 0x03, // Lock PLL + (0xB0), 7, 0x08, 0x80, 0x03, 0x1F, 0x01, 0xDF, 0x00, //LCD SPECIFICATION + (0xF0), 1, 0x03, //was 00 pixel data interface + // (0x3A), 1, 0x60, // SET R G B format = 6 6 6 + (0xE2), 3, 0x1D, 0x02, 0x54, //PLL multiplier, set PLL clock to 120M + (0xE6), 3, 0x02, 0xFF, 0xFF, //PLL setting for PCLK, depends on resolution + (0xB4), 8, 0x04, 0x20, 0x00, 0x58, 0x80, 0x00, 0x00, 0x00, //HSYNC + (0xB6), 7, 0x02, 0x0D, 0x00, 0x20, 0x01, 0x00, 0x00, //VSYNC + (0x13), 0, //Enter Normal mode + (0x38), 0, //Exit Idle mode + 0x29, 0, //Display On + }; + // from NHD 7.0" 8-bit + static const uint8_t SSD1963_NHD_70_regValues[] PROGMEM = { + 0x01, 0, //Soft Reset + TFTLCD_DELAY8, 120, + (0xE2), 3, 0x1D, 0x02, 0x04, //PLL multiplier, set PLL clock to 120M + (0xE0), 1, 0x01, // PLL enable + TFTLCD_DELAY8, 10, + (0xE0), 1, 0x03, // Lock PLL + 0x01, 0, //Soft Reset + TFTLCD_DELAY8, 120, + (0xB0), 7, 0x08, 0x80, 0x03, 0x1F, 0x01, 0xDF, 0x00, //LCD SPECIFICATION + (0xF0), 1, 0x03, //was 00 pixel data interface + // (0x3A), 1, 0x60, // SET R G B format = 6 6 6 + (0xE6), 3, 0x0F, 0xFF, 0xFF, //PLL setting for PCLK, depends on resolution + (0xB4), 8, 0x04, 0x20, 0x00, 0x58, 0x80, 0x00, 0x00, 0x00, //HSYNC + (0xB6), 7, 0x02, 0x0D, 0x00, 0x20, 0x01, 0x00, 0x00, //VSYNC + (0x13), 0, //Enter Normal mode + (0x38), 0, //Exit Idle mode + 0x29, 0, //Display On + }; + // from UTFTv2.81 initlcd.h + static const uint8_t SSD1963_800_regValues[] PROGMEM = { + (0xE2), 3, 0x1E, 0x02, 0x54, //PLL multiplier, set PLL clock to 120M + (0xE0), 1, 0x01, // PLL enable + TFTLCD_DELAY8, 10, + (0xE0), 1, 0x03, // + TFTLCD_DELAY8, 10, + 0x01, 0, //Soft Reset + TFTLCD_DELAY8, 100, + (0xE6), 3, 0x03, 0xFF, 0xFF, //PLL setting for PCLK, depends on resolution + (0xB0), 7, 0x24, 0x00, 0x03, 0x1F, 0x01, 0xDF, 0x00, //LCD SPECIFICATION + // (0xB0), 7, 0x24, 0x00, 0x03, 0x1F, 0x01, 0xDF, 0x2D, //LCD SPECIFICATION + (0xB4), 8, 0x03, 0xA0, 0x00, 0x2E, 0x30, 0x00, 0x0F, 0x00, //HSYNC + (0xB6), 7, 0x02, 0x0D, 0x00, 0x10, 0x10, 0x00, 0x08, //VSYNC + (0xBA), 1, 0x0F, //GPIO[3:0] out 1 + (0xB8), 2, 0x07, 0x01, //GPIO3=input, GPIO[2:0]=output + (0xF0), 1, 0x03, //pixel data interface + TFTLCD_DELAY8, 1, + 0x28, 0, //Display Off + 0x11, 0, //Sleep Out + TFTLCD_DELAY8, 100, + 0x29, 0, //Display On + (0xBE), 6, 0x06, 0xF0, 0x01, 0xF0, 0x00, 0x00, //set PWM for B/L + (0xD0), 1, 0x0D, + }; + init_table(SSD1963_800_regValues, sizeof(SSD1963_800_regValues)); + p16 = (int16_t *) & HEIGHT; + *p16 = 480; + p16 = (int16_t *) & WIDTH; + *p16 = 800; + break; +#endif + +#ifdef SUPPORT_4535 + case 0x4535: + _lcd_capable = 0 | REV_SCREEN; // | INVERT_GS; + static const uint16_t LGDP4535_regValues[] PROGMEM = { + 0x0015, 0x0030, // Set the internal vcore voltage + 0x009A, 0x0010, // Start internal OSC + 0x0011, 0x0020, // set SS and SM bit + 0x0010, 0x3428, // set 1 line inversion + 0x0012, 0x0002, // set GRAM write direction and BGR=1 + 0x0013, 0x1038, // Resize register + TFTLCD_DELAY, 40, + 0x0012, 0x0012, // set the back porch and front porch + TFTLCD_DELAY, 40, + 0x0010, 0x3420, // set non-display area refresh cycle ISC[3:0] + 0x0013, 0x3045, // FMARK function + TFTLCD_DELAY, 70, + 0x0030, 0x0000, // RGB interface setting + 0x0031, 0x0402, // Frame marker Position + 0x0032, 0x0307, // RGB interface polarity + 0x0033, 0x0304, // SAP, BT[3:0], AP, DSTB, SLP, STB + 0x0034, 0x0004, // DC1[2:0], DC0[2:0], VC[2:0] + 0x0035, 0x0401, // VREG1OUT voltage + 0x0036, 0x0707, // VDV[4:0] for VCOM amplitude + 0x0037, 0x0305, // SAP, BT[3:0], AP, DSTB, SLP, STB + 0x0038, 0x0610, // DC1[2:0], DC0[2:0], VC[2:0] + 0x0039, 0x0610, // VREG1OUT voltage + 0x0001, 0x0100, // VDV[4:0] for VCOM amplitude + 0x0002, 0x0300, // VCM[4:0] for VCOMH + 0x0003, 0x1030, // GRAM horizontal Address + 0x0008, 0x0808, // GRAM Vertical Address + 0x000A, 0x0008, + 0x0060, 0x2700, // Gate Scan Line + 0x0061, 0x0001, // NDL,VLE, REV + 0x0090, 0x013E, + 0x0092, 0x0100, + 0x0093, 0x0100, + 0x00A0, 0x3000, + 0x00A3, 0x0010, + 0x0007, 0x0001, + 0x0007, 0x0021, + 0x0007, 0x0023, + 0x0007, 0x0033, + 0x0007, 0x0133, + }; + init_table16(LGDP4535_regValues, sizeof(LGDP4535_regValues)); + break; +#endif + + case 0x7783: + _lcd_capable = AUTO_READINC | REV_SCREEN | INVERT_GS; + static const uint16_t ST7781_regValues[] PROGMEM = { + 0x00FF, 0x0001, //can we do 0xFF + 0x00F3, 0x0008, + // LCD_Write_COM(0x00F3, + + 0x00, 0x0001, + 0x0001, 0x0100, // Driver Output Control Register (R01h) + 0x0002, 0x0700, // LCD Driving Waveform Control (R02h) + 0x0003, 0x1030, // Entry Mode (R03h) + 0x0008, 0x0302, + 0x0009, 0x0000, + 0x0010, 0x0000, // Power Control 1 (R10h) + 0x0011, 0x0007, // Power Control 2 (R11h) + 0x0012, 0x0000, // Power Control 3 (R12h) + 0x0013, 0x0000, // Power Control 4 (R13h) + TFTLCD_DELAY, 50, + 0x0010, 0x14B0, // Power Control 1 (R10h) + TFTLCD_DELAY, 10, + 0x0011, 0x0007, // Power Control 2 (R11h) + TFTLCD_DELAY, 10, + 0x0012, 0x008E, // Power Control 3 (R12h) + 0x0013, 0x0C00, // Power Control 4 (R13h) + 0x0029, 0x0015, // NVM read data 2 (R29h) + TFTLCD_DELAY, 10, + 0x0030, 0x0000, // Gamma Control 1 + 0x0031, 0x0107, // Gamma Control 2 + 0x0032, 0x0000, // Gamma Control 3 + 0x0035, 0x0203, // Gamma Control 6 + 0x0036, 0x0402, // Gamma Control 7 + 0x0037, 0x0000, // Gamma Control 8 + 0x0038, 0x0207, // Gamma Control 9 + 0x0039, 0x0000, // Gamma Control 10 + 0x003C, 0x0203, // Gamma Control 13 + 0x003D, 0x0403, // Gamma Control 14 + 0x0050, 0x0000, // Window Horizontal RAM Address Start (R50h) + 0x0051, 240 - 1, // Window Horizontal RAM Address End (R51h) + 0x0052, 0X0000, // Window Vertical RAM Address Start (R52h) + 0x0053, 320 - 1, // Window Vertical RAM Address End (R53h) + 0x0060, 0xA700, // Driver Output Control (R60h) .kbv was 0xa700 + 0x0061, 0x0001, // Driver Output Control (R61h) + 0x0090, 0X0029, // Panel Interface Control 1 (R90h) + + // Display On + 0x0007, 0x0133, // Display Control (R07h) + TFTLCD_DELAY, 50, + }; + init_table16(ST7781_regValues, sizeof(ST7781_regValues)); + break; + case 0x7789: + _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS | READ_24BITS; + static const uint8_t ST7789_regValues[] PROGMEM = { + 0x01, 0, //Soft Reset + (0x11), 0, //exit SLEEP mode + TFTLCD_DELAY8, 100, // if from Sleep + (0x36), 1, 0x80, //MADCTL: memory data access control + // (0x3A), 1, 0x66, //COLMOD: Interface Pixel format *** I use 262K-colors in 18bit/pixel format when using 8-bit interface to allow 3-bytes per pixel + (0x3A), 1, 0x55, //COLMOD: Interface Pixel format *** I use 65K-colors in 16bit/pixel (5-6-5) format when using 16-bit interface to allow 1-byte per pixel + (0xB2), 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, //PORCTRK: Porch setting [08 08 00 22 22] PSEN=0 anyway + (0xB7), 1, 0x35, //GCTRL: Gate Control [35] + (0xBB), 1, 0x2B, //VCOMS: VCOM setting VCOM=1.175 [20] VCOM=0.9 + (0xC0), 1, 0x04, //LCMCTRL: LCM Control [2C] + (0xC2), 2, 0x01, 0xFF, //VDVVRHEN: VDV and VRH Command Enable [01 FF] + (0xC3), 1, 0x11, //VRHS: VRH Set VAP=4.4, VAN=-4.4 [0B] + (0xC4), 1, 0x20, //VDVS: VDV Set [20] + (0xC6), 1, 0x0F, //FRCTRL2: Frame Rate control in normal mode [0F] + (0xD0), 2, 0xA4, 0xA1, //PWCTRL1: Power Control 1 [A4 A1] + (0xE0), 14, 0xD0, 0x00, 0x05, 0x0E, 0x15, 0x0D, 0x37, 0x43, 0x47, 0x09, 0x15, 0x12, 0x16, 0x19, //PVGAMCTRL: Positive Voltage Gamma control + (0xE1), 14, 0xD0, 0x00, 0x05, 0x0D, 0x0C, 0x06, 0x2D, 0x44, 0x40, 0x0E, 0x1C, 0x18, 0x16, 0x19, //NVGAMCTRL: Negative Voltage Gamma control + (0x2A), 4, 0x00, 0x00, 0x00, 0xEF, //X address set + (0x2B), 4, 0x00, 0x00, 0x01, 0x3F, //Y address set + 0x29, 0, //Display On + TFTLCD_DELAY8, 10, + }; + static const uint8_t ST7789_regValues_arcain6[] PROGMEM = { + 0x01, 0, //Soft Reset + (0x11), 0, //exit SLEEP mode + TFTLCD_DELAY8, 100, // if from Sleep + (0x36), 1, 0x00, //MADCTL: memory data access control + (0x3A), 1, 0x05, //COLMOD: Interface Pixel format *** I use 65K-colors in 16bit/pixel (5-6-5) format when using 16-bit interface to allow 1-byte per pixel + (0xB2), 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, //PORCTRK: Porch setting [08 08 00 22 22] PSEN=0 anyway + (0xB7), 1, 0x35, //GCTRL: Gate Control [35] + (0xBB), 1, 0x35, //VCOMS: VCOM setting VCOM=??? [20] VCOM=0.9 + (0xC0), 1, 0x2C, //LCMCTRL: LCM Control [2C] + (0xC2), 2, 0x01, 0xFF, //VDVVRHEN: VDV and VRH Command Enable [01 FF] + (0xC3), 1, 0x13, //VRHS: VRH Set VAP=???, VAN=-??? [0B] + (0xC4), 1, 0x20, //VDVS: VDV Set [20] + (0xC6), 1, 0x0F, //FRCTRL2: Frame Rate control in normal mode [0F] + (0xCA), 1, 0x0F, //REGSEL2 [0F] + (0xC8), 1, 0x08, //REGSEL1 [08] + (0x55), 1, 0x90, //WRCACE [00] + (0xD0), 2, 0xA4, 0xA1, //PWCTRL1: Power Control 1 [A4 A1] + (0xE0), 14, 0xD0, 0x00, 0x06, 0x09, 0x0B, 0x2A, 0x3C, 0x55, 0x4B, 0x08, 0x16, 0x14, 0x19, 0x20, //PVGAMCTRL: Positive Voltage Gamma control + (0xE1), 14, 0xD0, 0x00, 0x06, 0x09, 0x0B, 0x29, 0x36, 0x54, 0x4B, 0x0D, 0x16, 0x14, 0x21, 0x20, //NVGAMCTRL: Negative Voltage Gamma control + // (0x2A), 4, 0x00, 0x00, 0x00, 0xEF, //X address set + // (0x2B), 4, 0x00, 0x00, 0x01, 0x3F, //Y address set + 0x29, 0, //Display On + TFTLCD_DELAY8, 10, + }; + init_table(ST7789_regValues, sizeof(ST7789_regValues)); // + break; +#ifdef SUPPORT_8347D + case 0x4747: //HX8347-D + _lcd_capable = REV_SCREEN | MIPI_DCS_REV1 | MV_AXIS | INVERT_SS; + goto common_8347DGI; + case 0x9595: //HX8347-I + _lcd_capable = REV_SCREEN | MIPI_DCS_REV1 | MV_AXIS; + common_8347DGI: + is8347 = 1; + static const uint8_t HX8347G_2_regValues[] PROGMEM = { + 0xEA, 2, 0x00, 0x20, //PTBA[15:0] + 0xEC, 2, 0x0C, 0xC4, //STBA[15:0] + 0xE8, 1, 0x38, //OPON[7:0] + 0xE9, 1, 0x10, //OPON1[7:0] + 0xF1, 1, 0x01, //OTPS1B + 0xF2, 1, 0x10, //GEN + //Gamma 2.2 Setting + 0x40, 13, 0x01, 0x00, 0x00, 0x10, 0x0E, 0x24, 0x04, 0x50, 0x02, 0x13, 0x19, 0x19, 0x16, + 0x50, 14, 0x1B, 0x31, 0x2F, 0x3F, 0x3F, 0x3E, 0x2F, 0x7B, 0x09, 0x06, 0x06, 0x0C, 0x1D, 0xCC, + //Power Voltage Setting + 0x1B, 1, 0x1B, //VRH=4.65V + 0x1A, 1, 0x01, //BT (VGH~15V,VGL~-10V,DDVDH~5V) + 0x24, 1, 0x2F, //VMH(VCOM High voltage ~3.2V) + 0x25, 1, 0x57, //VML(VCOM Low voltage -1.2V) + //****VCOM offset**/// + 0x23, 1, 0x88, //for Flicker adjust //can reload from OTP + //Power on Setting + 0x18, 1, 0x34, //I/P_RADJ,N/P_RADJ, Normal mode 60Hz + 0x19, 1, 0x01, //OSC_EN='1', start Osc + 0x01, 1, 0x00, //DP_STB='0', out deep sleep + 0x1F, 1, 0x88, // GAS=1, VOMG=00, PON=0, DK=1, XDK=0, DVDH_TRI=0, STB=0 + TFTLCD_DELAY8, 5, + 0x1F, 1, 0x80, // GAS=1, VOMG=00, PON=0, DK=0, XDK=0, DVDH_TRI=0, STB=0 + TFTLCD_DELAY8, 3, + 0x1F, 1, 0x90, // GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0 + TFTLCD_DELAY8, 5, + 0x1F, 1, 0xD0, // GAS=1, VOMG=10, PON=1, DK=0, XDK=0, DDVDH_TRI=0, STB=0 + TFTLCD_DELAY8, 5, + //262k/65k color selection + 0x17, 1, 0x05, //default 0x06 262k color // 0x05 65k color + //SET PANEL + 0x36, 1, 0x00, //SS_P, GS_P,REV_P,BGR_P + //Display ON Setting + 0x28, 1, 0x38, //GON=1, DTE=1, D=1000 + TFTLCD_DELAY8, 40, + 0x28, 1, 0x3F, //GON=1, DTE=1, D=1100 + + 0x16, 1, 0x18, + //Set GRAM Area + 0x02, 2, 0x00, 0x00, //Column Start + 0x04, 2, 0x00, 0xEF, //Column End + 0x06, 2, 0x00, 0x00, //Row Start + 0x08, 2, 0x01, 0x3F, //Row End + }; + init_table(HX8347G_2_regValues, sizeof(HX8347G_2_regValues)); + break; +#endif +#ifdef SUPPORT_8347A + case 0x8347: + _lcd_capable = REV_SCREEN | MIPI_DCS_REV1 | MV_AXIS; + // AN.01 The reference setting of CMO 3.2” Panel + static const uint8_t HX8347A_CMO32_regValues[] PROGMEM = { + // VENDOR Gamma for 3.2" + (0x46), 12, 0xA4, 0x53, 0x00, 0x44, 0x04, 0x67, 0x33, 0x77, 0x12, 0x4C, 0x46, 0x44, + //240x320 window setting + (0x02), 2, 0x00, 0x00, // Column address start2 + (0x04), 2, 0x00, 0xEF, // Column address end2 + (0x06), 2, 0x00, 0x00, // Row address start2 + (0x08), 2, 0x01, 0x3F, // Row address end2 + // Display Setting + (0x01), 1, 0x06, // IDMON=0, INVON=1, NORON=1, PTLON=0 + (0x16), 1, 0x48, // MY=0, MX=0, MV=0, ML=1, BGR=0, TEON=0 + (0x23), 3, 0x95, 0x95, 0xFF, // N_DC=1001 0101, PI_DC=1001 0101, I_DC=1111 1111 + + (0x27), 4, 0x02, 0x02, 0x02, 0x02, // N_BP=2, N_FP=2, PI_BP=2, PI_FP=2 + (0x2C), 2, 0x02, 0x02, // I_BP=2, I_FP=2 + + (0x3a), 4, 0x01, 0x01, 0xF0, 0x00, // N_RTN=0, N_NW=1, P_RTN=0, P_NW=1, I_RTN=15, I_NW=0, DIV=0 + TFTLCD_DELAY8, 5, + (0x35), 2, 0x38, 0x78, // EQS=38h, EQP=78h + (0x3E), 1, 0x38, // SON=38h + (0x40), 2, 0x0F, 0xF0, // GDON=0Fh, GDOFF + // Power Supply Setting + (0x19), 1, 0x49, // CADJ=0100, CUADJ=100, OSD_EN=1 ,60Hz + (0x93), 1, 0x0F, // RADJ=1111, 100% + TFTLCD_DELAY8, 5, + (0x20), 1, 0x40, // BT=0100 + (0x1D), 3, 0x07, 0x00, 0x04, // VC1=7, VC3=0, VRH=?? + //VCOM SETTING for 3.2" + (0x44), 2, 0x4D, 0x11, // VCM=100 1101, VDV=1 0001 + TFTLCD_DELAY8, 10, + (0x1C), 1, 0x04, // AP=100 + TFTLCD_DELAY8, 20, + (0x1B), 1, 0x18, // GASENB=0, PON=0, DK=1, XDK=0, VLCD_TRI=0, STB=0 + TFTLCD_DELAY8, 40, + (0x1B), 1, 0x10, // GASENB=0, PON=1, DK=0, XDK=0, VLCD_TRI=0, STB=0 + TFTLCD_DELAY8, 40, + (0x43), 1, 0x80, //set VCOMG=1 + TFTLCD_DELAY8, 100, + // Display ON Setting + (0x90), 1, 0x7F, // SAP=0111 1111 + (0x26), 1, 0x04, //GON=0, DTE=0, D=01 + TFTLCD_DELAY8, 40, + (0x26), 1, 0x24, //GON=1, DTE=0, D=01 + (0x26), 1, 0x2C, //GON=1, DTE=0, D=11 + TFTLCD_DELAY8, 40, + (0x26), 1, 0x3C, //GON=1, DTE=1, D=11 + // INTERNAL REGISTER SETTING + (0x57), 1, 0x02, // TEST_Mode=1: into TEST mode + (0x55), 1, 0x00, // VDC_SEL=000, VDDD=1.95V + (0xFE), 1, 0x5A, // For ESD protection + (0x57), 1, 0x00, // TEST_Mode=0: exit TEST mode + }; + // AN.01 The reference setting of CMO 2.4” Panel + static const uint8_t HX8347A_CMO24_regValues[] PROGMEM = { + // VENDOR Gamma for 2.4" + (0x46), 12, 0x94, 0x41, 0x00, 0x33, 0x23, 0x45, 0x44, 0x77, 0x12, 0xCC, 0x46, 0x82, + //240x320 window setting + (0x02), 2, 0x00, 0x00, // Column address start2 + (0x04), 2, 0x00, 0xEF, // Column address end2 + (0x06), 2, 0x00, 0x00, // Row address start2 + (0x08), 2, 0x01, 0x3F, // Row address end2 + // Display Setting + (0x01), 1, 0x06, // IDMON=0, INVON=1, NORON=1, PTLON=0 + (0x16), 1, 0x48, // MY=0, MX=0, MV=0, ML=1, BGR=0, TEON=0 + (0x23), 3, 0x95, 0x95, 0xFF, // N_DC=1001 0101, PI_DC=1001 0101, I_DC=1111 1111 + + (0x27), 4, 0x02, 0x02, 0x02, 0x02, // N_BP=2, N_FP=2, PI_BP=2, PI_FP=2 + (0x2C), 2, 0x02, 0x02, // I_BP=2, I_FP=2 + + (0x3a), 4, 0x01, 0x01, 0xF0, 0x00, // N_RTN=0, N_NW=1, P_RTN=0, P_NW=1, I_RTN=15, I_NW=0, DIV=0 + TFTLCD_DELAY8, 5, + (0x35), 2, 0x38, 0x78, // EQS=38h, EQP=78h + (0x3E), 1, 0x38, // SON=38h + (0x40), 2, 0x0F, 0xF0, // GDON=0Fh, GDOFF + // Power Supply Setting + (0x19), 1, 0x49, // CADJ=0100, CUADJ=100, OSD_EN=1 ,60Hz + (0x93), 1, 0x0F, // RADJ=1111, 100% + TFTLCD_DELAY8, 5, + (0x20), 1, 0x40, // BT=0100 + (0x1D), 3, 0x07, 0x00, 0x04, // VC1=7, VC3=0, VRH=?? + //VCOM SETTING for 2.4" + (0x44), 2, 0x40, 0x12, // VCM=100 0000, VDV=1 0001 + TFTLCD_DELAY8, 10, + (0x1C), 1, 0x04, // AP=100 + TFTLCD_DELAY8, 20, + (0x1B), 1, 0x18, // GASENB=0, PON=0, DK=1, XDK=0, VLCD_TRI=0, STB=0 + TFTLCD_DELAY8, 40, + (0x1B), 1, 0x10, // GASENB=0, PON=1, DK=0, XDK=0, VLCD_TRI=0, STB=0 + TFTLCD_DELAY8, 40, + (0x43), 1, 0x80, //set VCOMG=1 + TFTLCD_DELAY8, 100, + // Display ON Setting + (0x90), 1, 0x7F, // SAP=0111 1111 + (0x26), 1, 0x04, //GON=0, DTE=0, D=01 + TFTLCD_DELAY8, 40, + (0x26), 1, 0x24, //GON=1, DTE=0, D=01 + (0x26), 1, 0x2C, //GON=1, DTE=0, D=11 + TFTLCD_DELAY8, 40, + (0x26), 1, 0x3C, //GON=1, DTE=1, D=11 + // INTERNAL REGISTER SETTING + (0x57), 1, 0x02, // TEST_Mode=1: into TEST mode + (0x55), 1, 0x00, // VDC_SEL=000, VDDD=1.95V + (0xFE), 1, 0x5A, // For ESD protection + (0x57), 1, 0x00, // TEST_Mode=0: exit TEST mode + }; + static const uint8_t HX8347A_ITDB02_regValues[] PROGMEM = { + // VENDOR Gamma ITDB02 same as CMO32. Delays are shorter than AN01 + (0x46), 12, 0xA4, 0x53, 0x00, 0x44, 0x04, 0x67, 0x33, 0x77, 0x12, 0x4C, 0x46, 0x44, + //240x320 window setting + (0x02), 2, 0x00, 0x00, // Column address start2 + (0x04), 2, 0x00, 0xEF, // Column address end2 + (0x06), 2, 0x00, 0x00, // Row address start2 + (0x08), 2, 0x01, 0x3F, // Row address end2 + // Display Setting + (0x01), 1, 0x06, // IDMON=0, INVON=1, NORON=1, PTLON=0 + (0x16), 1, 0xC8, // MY=0, MX=0, MV=0, ML=1, BGR=0, TEON=0 .itead + (0x23), 3, 0x95, 0x95, 0xFF, // N_DC=1001 0101, PI_DC=1001 0101, I_DC=1111 1111 + + (0x27), 4, 0x02, 0x02, 0x02, 0x02, // N_BP=2, N_FP=2, PI_BP=2, PI_FP=2 + (0x2C), 2, 0x02, 0x02, // I_BP=2, I_FP=2 + + (0x3a), 4, 0x01, 0x00, 0xF0, 0x00, // N_RTN=0, N_NW=1, P_RTN=0, ?? P_NW=1, I_RTN=15, I_NW=0, DIV=0 .itead + TFTLCD_DELAY8, 5, + (0x35), 2, 0x38, 0x78, // EQS=38h, EQP=78h + (0x3E), 1, 0x38, // SON=38h + (0x40), 2, 0x0F, 0xF0, // GDON=0Fh, GDOFF + // Power Supply Setting + (0x19), 1, 0x49, // CADJ=0100, CUADJ=100, OSD_EN=1 ,60Hz + (0x93), 1, 0x0F, // RADJ=1111, 100% + TFTLCD_DELAY8, 5, + (0x20), 1, 0x40, // BT=0100 + (0x1D), 3, 0x07, 0x00, 0x04, // VC1=7, VC3=0, VRH=?? + //VCOM SETTING for ITDB02 + (0x44), 2, 0x4D, 0x0E, // VCM=101 0000 4D, VDV=1 0001 .itead + TFTLCD_DELAY8, 5, + (0x1C), 1, 0x04, // AP=100 + TFTLCD_DELAY8, 5, + (0x1B), 1, 0x18, // GASENB=0, PON=0, DK=1, XDK=0, VLCD_TRI=0, STB=0 + TFTLCD_DELAY8, 5, + (0x1B), 1, 0x10, // GASENB=0, PON=1, DK=0, XDK=0, VLCD_TRI=0, STB=0 + TFTLCD_DELAY8, 5, + (0x43), 1, 0x80, //set VCOMG=1 + TFTLCD_DELAY8, 5, + // Display ON Setting + (0x90), 1, 0x7F, // SAP=0111 1111 + (0x26), 1, 0x04, //GON=0, DTE=0, D=01 + TFTLCD_DELAY8, 5, + (0x26), 1, 0x24, //GON=1, DTE=0, D=01 + (0x26), 1, 0x2C, //GON=1, DTE=0, D=11 + TFTLCD_DELAY8, 5, + (0x26), 1, 0x3C, //GON=1, DTE=1, D=11 + // INTERNAL REGISTER SETTING for ITDB02 + (0x57), 1, 0x02, // TEST_Mode=1: into TEST mode + (0x95), 1, 0x01, // SET DISPLAY CLOCK AND PUMPING CLOCK TO SYNCHRONIZE .itead + (0x57), 1, 0x00, // TEST_Mode=0: exit TEST mode + }; + static const uint8_t HX8347A_NHD_regValues[] PROGMEM = { + //Gamma Setting NHD + (0x46), 12, 0x94, 0x41, 0x00, 0x33, 0x23, 0x45, 0x44, 0x77, 0x12, 0xCC, 0x46, 0x82, + (0x02), 2, 0x00, 0x00, //COLSTARTH + (0x04), 2, 0x00, 0xEF, //COLENDH + (0x06), 2, 0x00, 0x00, //ROWSTARTH + (0x08), 2, 0x01, 0x3F, //ROWENDH + (0x01), 1, 0x06, //Display Mode [06] + (0x16), 1, 0xC8, //MADCTL [00] MY=1, MX=1, BGR=1 +// (0x70), 1, 0x05, //Panel [06] 16-bit + (0x23), 3, 0x95, 0x95, 0xFF, //Cycle Control 1-3 [95 95 FF] + (0x27), 4, 0x02, 0x02, 0x02, 0x02, //Display Control 2-5 [02 02 02 02] + (0x2C), 2, 0x02, 0x02, //Display Control 6-7 [02 02] + (0x3A), 4, 0x01, 0x01, 0xF0, 0x00, //Cycle Control 1-4 [01 01 F0 00] + TFTLCD_DELAY8, 80, + (0x35), 2, 0x38, 0x78, //Display Control 9-10 [09 09] EQS=56, EQP=120 + (0x3E), 1, 0x38, //Cycle Control 5 [38] + (0x40), 1, 0x0F, //Cycle Control 6 [03] GDON=15 + (0x41), 1, 0xF0, //Cycle Control 14 [F8] GDOF=248 + + (0x19), 1, 0x2D, //OSC Control 1 [86] CADJ=2, CUADJ=6, OSCEN=1 + (0x93), 1, 0x06, //SAP Idle mode [00] ??? .nhd + TFTLCD_DELAY8, 80, + (0x20), 1, 0x40, //Power Control 6 [40] + (0x1D), 3, 0x07, 0x00, 0x04, //Power Control 3-5 [04 00 06] VC=7 + (0x44), 2, 0x3C, 0x12, //VCOM Control 2-3 [5A 11] VCM=60, VDV=18 + TFTLCD_DELAY8, 80, + (0x1C), 1, 0x04, //Power Control 2 [04] + TFTLCD_DELAY8, 80, + (0x43), 1, 0x80, //VCOM Control 1 [80] + TFTLCD_DELAY8, 80, + (0x1B), 1, 0x08, //Power Control 1 [00] DK=1 + TFTLCD_DELAY8, 80, + (0x1B), 1, 0x10, //Power Control 1 [00] PON=1 + TFTLCD_DELAY8, 80, + (0x90), 1, 0x7F, //Display Control 8 [0A] + (0x26), 1, 0x04, //Display Control 1 [A0] D=1 + TFTLCD_DELAY8, 80, + (0x26), 1, 0x24, //Display Control 1 [A0] GON=1, D=1 + (0x26), 1, 0x2C, //Display Control 1 [A0] GON=1, D=3 + TFTLCD_DELAY8, 80, + (0x26), 1, 0x3C, //Display Control 1 [A0] GON=1, DTE=1, D=3 + (0x57), 1, 0x02, //? + (0x55), 1, 0x00, //? + (0x57), 1, 0x00, //? + }; + // Atmel ASF code uses VCOM2-3: 0x38, 0x12. 50ms delays and no TEST mode changes. + init_table(HX8347A_NHD_regValues, sizeof(HX8347A_NHD_regValues)); + // init_table(HX8347A_CMO32_regValues, sizeof(HX8347A_CMO32_regValues)); + // init_table(HX8347A_CMO24_regValues, sizeof(HX8347A_CMO24_regValues)); + // init_table(HX8347A_ITDB02_regValues, sizeof(HX8347A_ITDB02_regValues)); + // init_table(HX8347G_2_regValues, sizeof(HX8347G_2_regValues)); + break; +#endif + case 0x5408: + _lcd_capable = 0 | REV_SCREEN | READ_BGR | INVERT_GS; + goto common_9320; + case 0x9320: + _lcd_capable = 0 | REV_SCREEN | READ_BGR; + common_9320: + static const uint16_t ILI9320_regValues[] PROGMEM = { + 0x00e5, 0x8000, + 0x0000, 0x0001, + 0x0001, 0x100, + 0x0002, 0x0700, + 0x0003, 0x1030, + 0x0004, 0x0000, + 0x0008, 0x0202, + 0x0009, 0x0000, + 0x000A, 0x0000, + 0x000C, 0x0000, + 0x000D, 0x0000, + 0x000F, 0x0000, + //-----Power On sequence----------------------- + 0x0010, 0x0000, + 0x0011, 0x0007, + 0x0012, 0x0000, + 0x0013, 0x0000, + TFTLCD_DELAY, 50, + 0x0010, 0x17B0, + 0x0011, 0x0007, + TFTLCD_DELAY, 10, + 0x0012, 0x013A, + TFTLCD_DELAY, 10, + 0x0013, 0x1A00, + 0x0029, 0x000c, + TFTLCD_DELAY, 10, + //-----Gamma control----------------------- + 0x0030, 0x0000, + 0x0031, 0x0505, + 0x0032, 0x0004, + 0x0035, 0x0006, + 0x0036, 0x0707, + 0x0037, 0x0105, + 0x0038, 0x0002, + 0x0039, 0x0707, + 0x003C, 0x0704, + 0x003D, 0x0807, + //-----Set RAM area----------------------- + 0x0050, 0x0000, + 0x0051, 0x00EF, + 0x0052, 0x0000, + 0x0053, 0x013F, + 0x0060, 0xA700, //GS=1 + 0x0061, 0x0001, + 0x006A, 0x0000, + 0x0021, 0x0000, + 0x0020, 0x0000, + //-----Partial Display Control------------ + 0x0080, 0x0000, + 0x0081, 0x0000, + 0x0082, 0x0000, + 0x0083, 0x0000, + 0x0084, 0x0000, + 0x0085, 0x0000, + //-----Panel Control---------------------- + 0x0090, 0x0010, + 0x0092, 0x0000, + 0x0093, 0x0003, + 0x0095, 0x0110, + 0x0097, 0x0000, + 0x0098, 0x0000, + //-----Display on----------------------- + 0x0007, 0x0173, + TFTLCD_DELAY, 50, + }; + init_table16(ILI9320_regValues, sizeof(ILI9320_regValues)); + break; + case 0x6809: + _lcd_capable = 0 | REV_SCREEN | INVERT_GS | AUTO_READINC; + goto common_93x5; + case 0x9325: + _lcd_capable = 0 | REV_SCREEN | INVERT_GS; + goto common_93x5; + case 0x9335: + _lcd_capable = 0 | REV_SCREEN; + common_93x5: + static const uint16_t ILI9325_regValues[] PROGMEM = { + 0x00E5, 0x78F0, // set SRAM internal timing + 0x0001, 0x0100, // set Driver Output Control + 0x0002, 0x0200, // set 1 line inversion + 0x0003, 0x1030, // set GRAM write direction and BGR=1. + 0x0004, 0x0000, // Resize register + 0x0005, 0x0000, // .kbv 16bits Data Format Selection + 0x0008, 0x0207, // set the back porch and front porch + 0x0009, 0x0000, // set non-display area refresh cycle ISC[3:0] + 0x000A, 0x0000, // FMARK function + 0x000C, 0x0000, // RGB interface setting + 0x000D, 0x0000, // Frame marker Position + 0x000F, 0x0000, // RGB interface polarity + // ----------- Power On sequence ----------- // + 0x0010, 0x0000, // SAP, BT[3:0], AP, DSTB, SLP, STB + 0x0011, 0x0007, // DC1[2:0], DC0[2:0], VC[2:0] + 0x0012, 0x0000, // VREG1OUT voltage + 0x0013, 0x0000, // VDV[4:0] for VCOM amplitude + 0x0007, 0x0001, + TFTLCD_DELAY, 200, // Dis-charge capacitor power voltage + 0x0010, 0x1690, // SAP, BT[3:0], AP, DSTB, SLP, STB + 0x0011, 0x0227, // Set DC1[2:0], DC0[2:0], VC[2:0] + TFTLCD_DELAY, 50, // wait_ms 50ms + 0x0012, 0x000D, // 0012 + TFTLCD_DELAY, 50, // wait_ms 50ms + 0x0013, 0x1200, // VDV[4:0] for VCOM amplitude + 0x0029, 0x000A, // 04 VCM[5:0] for VCOMH + 0x002B, 0x000D, // Set Frame Rate + TFTLCD_DELAY, 50, // wait_ms 50ms + 0x0020, 0x0000, // GRAM horizontal Address + 0x0021, 0x0000, // GRAM Vertical Address + // ----------- Adjust the Gamma Curve ----------// + + 0x0030, 0x0000, + 0x0031, 0x0404, + 0x0032, 0x0003, + 0x0035, 0x0405, + 0x0036, 0x0808, + 0x0037, 0x0407, + 0x0038, 0x0303, + 0x0039, 0x0707, + 0x003C, 0x0504, + 0x003D, 0x0808, + + //------------------ Set GRAM area ---------------// + 0x0050, 0x0000, // Horizontal GRAM Start Address + 0x0051, 0x00EF, // Horizontal GRAM End Address + 0x0052, 0x0000, // Vertical GRAM Start Address + 0x0053, 0x013F, // Vertical GRAM Start Address + 0x0060, 0x2700, // Gate Scan Line GS=0 [0xA700] + 0x0061, 0x0001, // NDL,VLE, REV .kbv + 0x006A, 0x0000, // set scrolling line + //-------------- Partial Display Control ---------// + 0x0080, 0x0000, + 0x0081, 0x0000, + 0x0082, 0x0000, + 0x0083, 0x0000, + 0x0084, 0x0000, + 0x0085, 0x0000, + //-------------- Panel Control -------------------// + 0x0090, 0x0010, + 0x0092, 0x0000, + 0x0007, 0x0133, // 262K color and display ON + }; + init_table16(ILI9325_regValues, sizeof(ILI9325_regValues)); + break; + case 0x9327: + _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS; + static const uint8_t ILI9327_regValues[] PROGMEM = { + 0x01, 0, //Soft Reset + 0x28, 0, //Display Off + // 0xE0, 1, 0x20, //NV Memory Write [00] + 0x11, 0, //Sleep Out + TFTLCD_DELAY8, 100, + 0xB0, 1, 0x00, //Disable Protect for cmds B1-DF, E0-EF, F0-FF + // 0xD1, 3, 0x00, 0x71, 0x19, //VCOM control [00 40 0F] + // 0xD0, 3, 0x07, 0x01, 0x08, //Power Setting [07 04 8C] + 0xC1, 4, 0x10, 0x10, 0x02, 0x02, //Display Timing [10 10 02 02] + 0xC0, 6, 0x00, 0x35, 0x00, 0x00, 0x01, 0x02, //Panel Drive [00 35 00 00 01 02 REV=0,GS=0,SS=0 + 0xC5, 1, 0x04, //Frame Rate [04] + 0xD2, 2, 0x01, 0x04, //Power Setting [01 44] + // 0xC8, 15, 0x04, 0x67, 0x35, 0x04, 0x08, 0x06, 0x24, 0x01, 0x37, 0x40, 0x03, 0x10, 0x08, 0x80, 0x00, + // 0xC8, 15, 0x00, 0x77, 0x77, 0x04, 0x04, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xCA, 1, 0x00, //DGC LUT ??? + 0xEA, 1, 0x80, //3-Gamma Function Enable + // 0xB0, 1, 0x03, //Enable Protect + 0x36, 1, 0x48, // Memory Access + 0x3A, 1, 0x55, //Pixel read=565, write=565 + 0x2A, 4, 0x00, 0x00, 0x00, 0xEF, // wid: 0, 239 + 0x2B, 4, 0x00, 0x00, 0x01, 0x8F, // ht: 0, 399 + 0x30, 4, 0x00, 0x00, 0x01, 0x8F, // Partial Area: 0, 399 + 0x29, 0, //Display On + }; + init_table(ILI9327_regValues, sizeof(ILI9327_regValues)); + p16 = (int16_t *) & HEIGHT; + *p16 = 400; + p16 = (int16_t *) & WIDTH; + *p16 = 240; + break; + case 0x9302: + _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS | INVERT_SS; + goto common_9329; + case 0x9329: + _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS; + common_9329: + static const uint8_t ILI9329_regValues[] PROGMEM = { + 0x01, 0, //Soft Reset + TFTLCD_DELAY8, 50, // .kbv will power up with ONLY reset, sleep out, display on + 0x28, 0, //Display Off + // 0xF6, 3, 0x01, 0x01, 0x00, //Interface Control needs EXTC=1 MX_EOR=1, TM=0, RIM=0 + 0xB6, 3, 0x0A, 0x22, 0x27, //Display Function [0A 82 27] ILI9329: REV=0, SS=1 + 0x11, 0, //Sleep Out + TFTLCD_DELAY8, 150, + 0x29, 0, //Display On + 0x3A, 1, 0x55, //Pixel read=565, write=565 + }; + init_table(ILI9329_regValues, sizeof(ILI9329_regValues)); + break; + case 0x9341: + _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS | READ_24BITS; + static const uint8_t ILI9341_regValues_2_4[] PROGMEM = { // BOE 2.4" + 0x01, 0, // software reset + TFTLCD_DELAY8, 50, // .kbv will power up with ONLY reset, sleep out, display on + 0x28, 0, //Display Off + 0xF6, 3, 0x01, 0x01, 0x00, //Interface Control needs EXTC=1 MV_EOR=0, TM=0, RIM=0 + 0xCF, 3, 0x00, 0x81, 0x30, //Power Control B [00 81 30] + 0xED, 4, 0x64, 0x03, 0x12, 0x81, //Power On Seq [55 01 23 01] + 0xE8, 3, 0x85, 0x10, 0x78, //Driver Timing A [04 11 7A] + 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, //Power Control A [39 2C 00 34 02] + 0xF7, 1, 0x20, //Pump Ratio [10] + 0xEA, 2, 0x00, 0x00, //Driver Timing B [66 00] + 0xB1, 2, 0x00, 0x1B, //Frame Control [00 1B] + // 0xB6, 2, 0x0A, 0xA2, 0x27, //Display Function [0A 82 27 XX] .kbv SS=1 + 0xB4, 1, 0x00, //Inversion Control [02] .kbv NLA=1, NLB=1, NLC=1 + 0xC0, 1, 0x21, //Power Control 1 [26] + 0xC1, 1, 0x11, //Power Control 2 [00] + 0xC5, 2, 0x3F, 0x3C, //VCOM 1 [31 3C] + 0xC7, 1, 0xB5, //VCOM 2 [C0] + 0x36, 1, 0x48, //Memory Access [00] + 0xF2, 1, 0x00, //Enable 3G [02] + 0x26, 1, 0x01, //Gamma Set [01] + 0xE0, 15, 0x0f, 0x26, 0x24, 0x0b, 0x0e, 0x09, 0x54, 0xa8, 0x46, 0x0c, 0x17, 0x09, 0x0f, 0x07, 0x00, + 0xE1, 15, 0x00, 0x19, 0x1b, 0x04, 0x10, 0x07, 0x2a, 0x47, 0x39, 0x03, 0x06, 0x06, 0x30, 0x38, 0x0f, + 0x11, 0, //Sleep Out + TFTLCD_DELAY8, 150, + 0x29, 0, //Display On + 0x3A, 1, 0x55, //Pixel Format [66] + }; + static const uint8_t ILI9341_regValues_ada[] PROGMEM = { // Adafruit_TFTLCD only works with EXTC=0 + 0x01, 0, // software reset + TFTLCD_DELAY8, 50, + 0x28, 0, //Display Off + // 0xF6, 3, 0x00, 0x01, 0x00, //Interface Control needs EXTC=1 TM=0, RIM=0 + // 0xF6, 3, 0x01, 0x01, 0x03, //Interface Control needs EXTC=1 RM=1, RIM=1 + 0xF6, 3, 0x09, 0x01, 0x03, //Interface Control needs EXTC=1 RM=0, RIM=1 + 0xB0, 1, 0x40, //RGB Signal [40] RCM=2 + 0xB4, 1, 0x00, //Inversion Control [02] .kbv NLA=1, NLB=1, NLC=1 + 0xC0, 1, 0x23, //Power Control 1 [26] + 0xC1, 1, 0x10, //Power Control 2 [00] + 0xC5, 2, 0x2B, 0x2B, //VCOM 1 [31 3C] + 0xC7, 1, 0xC0, //VCOM 2 [C0] + 0x36, 1, 0x88, //Memory Access [00] + 0xB1, 2, 0x00, 0x1B, //Frame Control [00 1B] + 0xB7, 1, 0x07, //Entry Mode [00] + 0x11, 0, //Sleep Out + TFTLCD_DELAY8, 150, + 0x29, 0, //Display On + 0x3A, 1, 0x55, //Pixel Format [66] + }; +#if !defined(USE_SERIAL) + if (readReg32(0xD3) == 0x0000) { //weird DealExtreme EXTC=0 shield + init_table(ILI9341_regValues_ada, sizeof(ILI9341_regValues_ada)); + _lcd_capable |= REV_SCREEN | READ_BGR; + } else +#endif + { + init_table(ILI9341_regValues_2_4, sizeof(ILI9341_regValues_2_4)); // + } + break; + case 0x9481: + _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS | READ_BGR; + static const uint8_t ILI9481_regValues[] PROGMEM = { // Atmel MaxTouch + 0x01, 0, //Soft Reset + TFTLCD_DELAY8, 50, + 0x11, 0, //Sleep Out + TFTLCD_DELAY8, 20, + 0xD0, 3, 0x07, 0x42, 0x18, //Set Power + 0xD1, 3, 0x00, 0x07, 0x10, // Set VCOM + 0xD2, 2, 0x01, 0x02, // Set Power for Normal Mode + 0xC0, 5, 0x10, 0x3B, 0x00, 0x02, 0x11, //Set Panel Driving + 0xC5, 1, 0x08, //Frame Rate + 0xC8, 12, 0x00, 0x32, 0x36, 0x45, 0x06, 0x16, 0x37, 0x75, 0x77, 0x54, 0x0C, 0x00, + 0x36, 1, 0x0A, //Memory Access [00] + 0x3A, 1, 0x55, //Interlace Pixel Format [XX] + + 0x2A, 4, 0x00, 0x00, 0x01, 0x3F, + 0x2B, 4, 0x00, 0x00, 0x01, 0xE0, + 0x11, 0, //Sleep Out + TFTLCD_DELAY8, 120, + 0x29, 0, //Display On + TFTLCD_DELAY8, 25, + }; + init_table(ILI9481_regValues, sizeof(ILI9481_regValues)); + p16 = (int16_t *) & HEIGHT; + *p16 = 480; + p16 = (int16_t *) & WIDTH; + *p16 = 320; + break; + case 0x9486: + _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS | REV_SCREEN; + static const uint8_t ILI9486_regValues[] PROGMEM = { + 0x01, 0, //Soft Reset + TFTLCD_DELAY8, 50, + 0x28, 0, //Display Off + 0xC0, 2, 0x0d, 0x0d, //Power Control 1 [0x0E0E] + 0xC1, 2, 0x43, 0x00, //Power Control 2 [0x4300] + 0xC2, 1, 0x00, //Power Control 3 + 0xC5, 4, 0x00, 0x48, 0x00, 0x48, //VCOM Control 1 [0x00400040] + 0xB4, 1, 0x00, //Inversion Control + 0xB6, 3, 0x00, 0x02, 0x3B, // Display Function Control .kbv GS=0,SS=0 + 0xE0, 15, 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1, 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00, + 0xE1, 15, 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f, + 0x20, 0, // Display Inversion OFF + 0x36, 1, 0x0A, //Memory Access + 0x3A, 1, 0x55, //Interlace Pixel + // 0x21, 0, //Invert display !!! + 0x11, 0, //Sleep Out + TFTLCD_DELAY8, 50, + 0x29, 0, //Display On + }; + init_table(ILI9486_regValues, sizeof(ILI9486_regValues)); + p16 = (int16_t *) & HEIGHT; + *p16 = 480; + p16 = (int16_t *) & WIDTH; + *p16 = 320; + break; + case 0x9488: + _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS | READ_24BITS; + static const uint8_t ILI9488_regValues_max[] PROGMEM = { // Atmel MaxTouch + 0x01, 0, //Soft Reset + TFTLCD_DELAY8, 50, + 0x28, 0, //Display Off + 0xC0, 2, 0x10, 0x10, //Power Control 1 [0E 0E] + 0xC1, 1, 0x41, //Power Control 2 [43] + 0xC5, 4, 0x00, 0x22, 0x80, 0x40, //VCOM Control 1 [00 40 00 40] + 0x36, 1, 0x68, //Memory Access [00] + 0xB0, 1, 0x00, //Interface [00] + 0xB1, 2, 0xB0, 0x11, //Frame Rate Control [B0 11] + 0xB4, 1, 0x02, //Inversion Control [02] + 0xB6, 3, 0x02, 0x02, 0x3B, // Display Function Control [02 02 3B] .kbv NL=480 + 0xB7, 1, 0xC6, //Entry Mode [06] + 0x3A, 1, 0x55, //Interlace Pixel Format [XX] + 0xF7, 4, 0xA9, 0x51, 0x2C, 0x82, //Adjustment Control 3 [A9 51 2C 82] + 0x11, 0, //Sleep Out + TFTLCD_DELAY8, 150, + 0x29, 0, //Display On + }; + init_table(ILI9488_regValues_max, sizeof(ILI9488_regValues_max)); + p16 = (int16_t *) & HEIGHT; + *p16 = 480; + p16 = (int16_t *) & WIDTH; + *p16 = 320; + break; + case 0xB505: //R61505V + case 0xC505: //R61505W + _lcd_capable = 0 | REV_SCREEN | READ_LOWHIGH; + static const uint16_t R61505V_regValues[] PROGMEM = { + 0x0000, 0x0000, + 0x0000, 0x0000, + 0x0000, 0x0000, + 0x0000, 0x0001, + 0x00A4, 0x0001, //CALB=1 + TFTLCD_DELAY, 10, + 0x0060, 0x2700, //NL + 0x0008, 0x0808, //FP & BP + 0x0030, 0x0214, //Gamma settings + 0x0031, 0x3715, + 0x0032, 0x0604, + 0x0033, 0x0E16, + 0x0034, 0x2211, + 0x0035, 0x1500, + 0x0036, 0x8507, + 0x0037, 0x1407, + 0x0038, 0x1403, + 0x0039, 0x0020, + 0x0090, 0x0015, //DIVI & RTNI + 0x0010, 0x0410, //BT,AP + 0x0011, 0x0237, //VC,DC0,DC1 + 0x0029, 0x0046, //VCM1 + 0x002A, 0x0046, //VCMSEL,VCM2 + // Sleep mode IN sequence + 0x0007, 0x0000, + //0x0012, 0x0000, //PSON=0,PON=0 + // Sleep mode EXIT sequence + 0x0012, 0x0189, //VRH=9,VCMR=1,PSON=0,PON=0 + 0x0013, 0x1100, //VDV + TFTLCD_DELAY, 150, + 0x0012, 0x01B9, //VRH=9,VCMR=1,PSON=1,PON=1 [018F] + 0x0001, 0x0100, //SS=1 Other mode settings + 0x0002, 0x0200, //BC0=1--Line inversion + 0x0003, 0x1030, + 0x0009, 0x0001, //ISC=1 [0000] + 0x000A, 0x0000, // [0000] + // 0x000C, 0x0001, //RIM=1 [0000] + 0x000D, 0x0000, // [0000] + 0x000E, 0x0030, //VEM=3 VCOM equalize [0000] + 0x0050, 0x0000, //Display window area setting + 0x0051, 0x00EF, + 0x0052, 0x0000, + 0x0053, 0x013F, + 0x0061, 0x0001, + 0x006A, 0x0000, + 0x0080, 0x0000, + 0x0081, 0x0000, + 0x0082, 0x005F, + 0x0092, 0x0100, + 0x0093, 0x0701, + TFTLCD_DELAY, 80, + 0x0007, 0x0100, //BASEE=1--Display On + }; + init_table16(R61505V_regValues, sizeof(R61505V_regValues)); + break; + case 0xB509: + _lcd_capable = REV_SCREEN; + static const uint16_t R61509V_regValues[] PROGMEM = { + 0x0000, 0x0000, + 0x0000, 0x0000, + 0x0000, 0x0000, + 0x0000, 0x0000, + TFTLCD_DELAY, 15, + 0x0400, 0x6200, //NL=0x31 (49) i.e. 400 rows + 0x0008, 0x0808, + //gamma + 0x0300, 0x0C00, + 0x0301, 0x5A0B, + 0x0302, 0x0906, + 0x0303, 0x1017, + 0x0304, 0x2300, + 0x0305, 0x1700, + 0x0306, 0x6309, + 0x0307, 0x0C09, + 0x0308, 0x100C, + 0x0309, 0x2232, + + 0x0010, 0x0016, //69.5Hz 0016 + 0x0011, 0x0101, + 0x0012, 0x0000, + 0x0013, 0x0001, + + 0x0100, 0x0330, //BT,AP + 0x0101, 0x0237, //DC0,DC1,VC + 0x0103, 0x0D00, //VDV + 0x0280, 0x6100, //VCM + 0x0102, 0xC1B0, //VRH,VCMR,PSON,PON + TFTLCD_DELAY, 50, + + 0x0001, 0x0100, + 0x0002, 0x0100, + 0x0003, 0x1030, //1030 + 0x0009, 0x0001, + 0x000C, 0x0000, + 0x0090, 0x8000, + 0x000F, 0x0000, + + 0x0210, 0x0000, + 0x0211, 0x00EF, + 0x0212, 0x0000, + 0x0213, 0x018F, //432=01AF,400=018F + 0x0500, 0x0000, + 0x0501, 0x0000, + 0x0502, 0x005F, //??? + 0x0401, 0x0001, //REV=1 + 0x0404, 0x0000, + TFTLCD_DELAY, 50, + + 0x0007, 0x0100, //BASEE + TFTLCD_DELAY, 50, + + 0x0200, 0x0000, + 0x0201, 0x0000, + }; + init_table16(R61509V_regValues, sizeof(R61509V_regValues)); + p16 = (int16_t *) & HEIGHT; + *p16 = 400; + break; + } + _lcd_rev = ((_lcd_capable & REV_SCREEN) != 0); + setRotation(0); //PORTRAIT + invertDisplay(false); +} diff --git a/MCUFRIEND_kbv.h b/MCUFRIEND_kbv.h new file mode 100644 index 0000000..a754fcc --- /dev/null +++ b/MCUFRIEND_kbv.h @@ -0,0 +1,50 @@ +#ifndef MCUFRIEND_KBV_H_ +#define MCUFRIEND_KBV_H_ 281 + +//#define USE_KEIL +//#define USE_SERIAL + +#if ARDUINO < 165 +#define USE_GFX_KBV +#include "ADA_GFX_kbv.h" +#else +#include "Adafruit_GFX.h" +#endif + +class MCUFRIEND_kbv : public Adafruit_GFX { + + public: +#if defined USE_GFX_KBV + MCUFRIEND_kbv(); +#else + MCUFRIEND_kbv(int CS=A3, int RS=A2, int WR=A1, int RD=A0, int RST=A4); +#endif + void reset(void); // you only need the constructor + void begin(uint16_t ID = 0x9341); // you only need the constructor + virtual void drawPixel(int16_t x, int16_t y, uint16_t color); // and these three + void WriteCmdData(uint16_t cmd, uint16_t dat); // ?public methods !!! + uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } + uint16_t readID(void); + virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { fillRect(x, y, 1, h, color); } + virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { fillRect(x, y, w, 1, color); } + virtual void fillScreen(uint16_t color) { fillRect(0, 0, _width, _height, color); } + virtual void setRotation(uint8_t r); + virtual void invertDisplay(boolean i); + + uint16_t readReg(uint16_t reg); + uint32_t readReg32(uint16_t reg); + int16_t readGRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h); + uint16_t readPixel(int16_t x, int16_t y) { uint16_t color; readGRAM(x, y, &color, 1, 1); return color; } + void setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1); + void pushColors(uint16_t *block, int16_t n, bool first); + void pushColors(uint8_t *block, int16_t n, bool first); + void pushColors(const uint8_t *block, int16_t n, bool first); + void vertScroll(int16_t top, int16_t scrollines, int16_t offset); + + private: + uint16_t _lcd_ID, _lcd_rev, _lcd_madctl, _lcd_drivOut, _MC, _MP, _MW, _SC, _EC, _SP, _EP; + uint16_t _lcd_xor, _lcd_capable; +}; + +#endif diff --git a/TFT_HX8357GLUE.h b/TFT_HX8357GLUE.h new file mode 100644 index 0000000..7d802fc --- /dev/null +++ b/TFT_HX8357GLUE.h @@ -0,0 +1,146 @@ +// NOT FOR PUBLIC USE + +#define HX8357_BLACK 0x0000 +#define HX8357_BLUE 0x001F +#define HX8357_RED 0xF800 +#define HX8357_GREEN 0x07E0 +#define HX8357_CYAN 0x07FF +#define HX8357_MAGENTA 0xF81F +#define HX8357_YELLOW 0xFFE0 +#define HX8357_WHITE 0xFFFF + +#include // Core graphics library +#include // Hardware-specific library + +#include +#include +#include +#include +#include + +const GFXfont *Fonts[] = { + NULL, + NULL, + &FreeSans9pt7b, + NULL, + &FreeSans12pt7b, + NULL, + &FreeSans18pt7b, + &FreeSerifItalic12pt7b, + &FreeMonoBold24pt7b, +}; +#define TFT_BLACK 0x0000 +#define TFT_NAVY 0x000F +#define TFT_DARKGREEN 0x03E0 +#define TFT_DARKCYAN 0x03EF +#define TFT_MAROON 0x7800 +#define TFT_PURPLE 0x780F +#define TFT_OLIVE 0x7BE0 +#define TFT_LIGHTGREY 0xC618 +#define TFT_DARKGREY 0x7BEF +#define TFT_BLUE 0x001F +#define TFT_GREEN 0x07E0 +#define TFT_CYAN 0x07FF +#define TFT_RED 0xF800 +#define TFT_MAGENTA 0xF81F +#define TFT_YELLOW 0xFFE0 +#define TFT_WHITE 0xFFFF +#define TFT_ORANGE 0xFD20 +#define TFT_GREENYELLOW 0xAFE5 +#define TFT_PINK 0xF81F + +class TFT_HX8357GLUE : public MCUFRIEND_kbv +{ + public: + TFT_HX8357GLUE() {} + void begin(void) { + init(); + } + void init(void) + { + MCUFRIEND_kbv::reset(); + _ID = MCUFRIEND_kbv::readID(); +// if (_ID == 0x00D3 || ID == 0xD3D3) + _ID = 0x9481; + MCUFRIEND_kbv::begin(_ID); + MCUFRIEND_kbv::setRotation(1); + _first = true; + } + void setWindow(int16_t x0, int16_t y0, int16_t x1, int16_t y1) + { + MCUFRIEND_kbv::setAddrWindow(x0, y0, x1, y1); + _first = true; + } + + void pushColors(uint8_t *data, uint16_t len) + { + MCUFRIEND_kbv::pushColors((uint8_t*)data, len, _first); + _first = false; + } + + void pushColors(uint16_t *data, uint8_t len) + { + MCUFRIEND_kbv::pushColors((uint16_t*)data, len, _first); + _first = false; + } + + void pushColor(uint16_t color) + { + uint16_t c = color; + MCUFRIEND_kbv::pushColors(&c, 1, _first); + _first = false; + } + + void setCursor(int16_t x, int16_t y) + { + setCursor(x, y, _font); + } + + void setCursor(int16_t x, int16_t y, uint8_t idx) + { + + const GFXfont *f = Fonts[idx]; + MCUFRIEND_kbv::setFont(f); +// MCUFRIEND_kbv::setCursor(x, y + f->glyph->height); + + MCUFRIEND_kbv::setCursor(x, y); + } + + void setTextFont(uint8_t font) + { + _font = font; + MCUFRIEND_kbv::setFont(Fonts[_font]); + } + + int16_t drawNumber(long long_num, int16_t poX, int16_t poY, int16_t idx) + { + char buf[12]; + ltoa(long_num, buf, 10); + return drawString(buf, poX, poY, idx); + } + + int16_t drawChar(char c, int16_t poX, int16_t poY, int16_t idx) + { + char buf[2]; + buf[0] = c; + buf[1] = 0; + return drawString(buf, poX, poY, idx); + } + + int16_t drawString(char *string, int16_t poX, int16_t poY, int16_t idx) + { + int16_t x1, y1; + uint16_t w, h; + setFont(Fonts[_font = idx]); + getTextBounds(string, poX, poY, &x1, &y1, &w, &h); + fillRect(x1, y1 + h, w, h, 0x0000); + MCUFRIEND_kbv::setCursor(poX, poY + h); + print(string); + return w; + } + + private: + uint16_t _ID; + uint8_t _font, _first; +}; + diff --git a/UTFTGLUE.h b/UTFTGLUE.h new file mode 100644 index 0000000..3df5c24 --- /dev/null +++ b/UTFTGLUE.h @@ -0,0 +1,119 @@ +/* + * utftglue.h + * + * Created: 02/03/2013 14:25:06 + * Author: David Prentice + */ + + +#ifndef UTFTGLUE_H_ +#define UTFTGLUE_H_ + +#define LEFT 0 +#define RIGHT 9999 +#define CENTER 9998 + +#define PORTRAIT 0 +#define LANDSCAPE 1 + +#include + +struct _current_font +{ + uint8_t* font; + uint8_t x_size; + uint8_t y_size; + uint8_t offset; + uint8_t numchars; +}; + +class UTFTGLUE : public MCUFRIEND_kbv +{ + public: +// UTFTGLUE() : MCUFRIEND_kbv() {} + UTFTGLUE(byte model, int RS, int WR,int CS, int RST, int RD = A0) : MCUFRIEND_kbv(CS, RS, WR, RD, RST) {} + void InitLCD(byte orientation=LANDSCAPE) { + MCUFRIEND_kbv::reset(); + uint16_t ID = MCUFRIEND_kbv::readID(); + if (ID == 0) ID = 0x9341; //DealExtreme with EXTC=0 +// if (ID == 0x0089 || ID == 0x8989) ID = 0x1289; + if (ID == 0x00D3 || ID == 0xD3D3) ID = 0x9481; //write-only controller +// if (ID == 0x00D3 || ID == 0xD3D3) ID = 0x9486; //write-only controller +// if (ID == 0x9327 && orientation == LANDSCAPE) orientation = 3; + MCUFRIEND_kbv::begin(ID); + MCUFRIEND_kbv::setRotation(_orient = orientation); + _radius = 4; + } + void clrScr() { MCUFRIEND_kbv::fillScreen(0x0000);} + void drawPixel(int x, int y) { MCUFRIEND_kbv::drawPixel(x, y, _fcolor);} + void drawLine(int x1, int y1, int x2, int y2) { MCUFRIEND_kbv::drawLine(x1, y1, x2, y2, _fcolor);} + void fillScr(byte r, byte g, byte b) { MCUFRIEND_kbv::fillScreen(setrgb(r, g, b));} + void drawRect(int x1, int y1, int x2, int y2) { + int w = x2 - x1 + 1, h = y2 - y1 + 1; + if (w < 0) { x1 = x2; w = -w; } + if (h < 0) { y1 = y2; h = -h; } + MCUFRIEND_kbv::drawRect(x1, y1, w, h, _fcolor); + } + void drawRoundRect(int x1, int y1, int x2, int y2) { + int w = x2 - x1 + 1, h = y2 - y1 + 1; + if (w < 0) { x1 = x2; w = -w; } + if (h < 0) { y1 = y2; h = -h; } + MCUFRIEND_kbv::drawRoundRect(x1, y1, w, h, _radius, _fcolor); + } + void fillRect(int x1, int y1, int x2, int y2) { + int w = x2 - x1 + 1, h = y2 - y1 + 1; + if (w < 0) { x1 = x2; w = -w; } + if (h < 0) { y1 = y2; h = -h; } + MCUFRIEND_kbv::fillRect(x1, y1, w, h, _fcolor); + } + void fillRoundRect(int x1, int y1, int x2, int y2) { + int w = x2 - x1 + 1, h = y2 - y1 + 1; + if (w < 0) { x1 = x2; w = -w; } + if (h < 0) { y1 = y2; h = -h; } + MCUFRIEND_kbv::fillRoundRect(x1, y1, w, h, _radius, _fcolor); + } + void drawCircle(int x, int y, int radius) { MCUFRIEND_kbv::drawCircle(x, y, radius, _fcolor);} + void fillCircle(int x, int y, int radius) { MCUFRIEND_kbv::fillCircle(x, y, radius, _fcolor);} + void setColor(byte r, byte g, byte b) { MCUFRIEND_kbv::setTextColor(_fcolor = setrgb(r, g, b), _bcolor);} + void setBackColor(byte r, byte g, byte b) { MCUFRIEND_kbv::setTextColor(_fcolor, _bcolor = setrgb(r, g, b));} + void print(const char *st, int x, int y, int deg=0) { + settextcursor((char*)st, x, y); MCUFRIEND_kbv::print(st);} + void print(char *st, int x, int y, int deg=0) { + settextcursor(st, x, y); MCUFRIEND_kbv::print(st);} + void print(String st, int x, int y, int deg=0) { + MCUFRIEND_kbv::print(st);} + void printNumI(long num, int x, int y, int length=0, char filler=' ') { + char buf[16]; ltoa(num, buf, 10); + settextcursor(buf, x, y); MCUFRIEND_kbv::print(buf);} + void printNumF(double num, byte dec, int x, int y, char divider='.', int length=0, char filler=' ') { + settextcursor((char*)"", x, y); MCUFRIEND_kbv::print(num, dec);} + void setFont(uint8_t* font) { MCUFRIEND_kbv::setTextSize(1);} + +// void drawBitmap(int x, int y, int sx, int sy, bitmapdatatype data, int scale=1) { +// MCUFRIEND_kbv::drawBitmap(x, y, (const uint8_t*)data, sx, sy, _fcolor);} +// void drawBitmap(int x, int y, int sx, int sy, bitmapdatatype data, int deg, int rox, int roy); +// void lcdOff(); +// void lcdOn(); +// void setContrast(char c); + int getDisplayXSize() { return MCUFRIEND_kbv::width(); } + int getDisplayYSize() { return MCUFRIEND_kbv::height(); } +// void LCD_Write_DATA(char VH,char VL); + // void dispBitmap(File inFile); + protected: + uint16_t _fcolor; + uint16_t _bcolor; + uint8_t _radius; + uint8_t _orient; + void settextcursor(char *st, int x, int y) { + int pos; + if (x == CENTER || x == RIGHT) { + pos = (MCUFRIEND_kbv::width() - strlen(st) * 6); + if (x == CENTER) x = pos/2; + else x = pos; + } + MCUFRIEND_kbv::setCursor(x, y); + } + uint16_t setrgb(byte r, byte g, byte b) { return ((r&0xF8) << 8) | ((g&0xFC) << 3) | (b>>3);} +}; + +#endif /* UTFTGLUE_H_ */ \ No newline at end of file diff --git a/bitmaps/miniwoof.bmp b/bitmaps/miniwoof.bmp new file mode 100644 index 0000000..d5045d5 Binary files /dev/null and b/bitmaps/miniwoof.bmp differ diff --git a/bitmaps/test.bmp b/bitmaps/test.bmp new file mode 100644 index 0000000..2d8e2bc Binary files /dev/null and b/bitmaps/test.bmp differ diff --git a/bitmaps/woof.bmp b/bitmaps/woof.bmp new file mode 100644 index 0000000..8c461e2 Binary files /dev/null and b/bitmaps/woof.bmp differ diff --git a/examples/GLUE_Demo_320x240/GLUE_Demo_320x240.ino b/examples/GLUE_Demo_320x240/GLUE_Demo_320x240.ino new file mode 100644 index 0000000..e68ca76 --- /dev/null +++ b/examples/GLUE_Demo_320x240/GLUE_Demo_320x240.ino @@ -0,0 +1,353 @@ +// UTFT_Demo_320x240 (C)2012 uCtronics +// web: http://www.uctronics.com +// UTFT_Demo_320x240 is derived from +// UTFT_Demo_320x240 (C)2010 Henning Karlsen +// web: http://www.henningkarlsen.com/electronics +// to fit for our 3.2 inch TFT LCD shield for Arduino/Maple/Chipkit +// +// This program is a demo of how to use most of the functions +// of the library with a supported display modules. +// +// This demo was made for modules with a screen resolution +// of 320x240 pixels. +// +// This program requires the UTFT library (8bit mode) +// and the code is compatible with both UNO and Mega board. +// No code modification required. +// + +// if I want to use a GLUE class that implements the UTFT API +// with the Adafruit classes, I MUST include those headers +// because the Arduino Java does not look at nested includes ! + + +#include +//#include // this header is not needed +#include // class methods are in here +//UTFTGLUE myGLCD; // use for default shield +//UTFTGLUE myGLCD(0x9320,A2,A1,A3,A4,A0); +//UTFTGLUE myGLCD(0x9325,A2,A1,A3,A4,A0); +//UTFTGLUE myGLCD(0x7783,A2,A1,A3,A4,A0); +//UTFTGLUE myGLCD(0x1289,A1,A2,A0,0,A3); // this might choose the pins +UTFTGLUE myGLCD(0x0154,A2,A1,A3,A4,A0); + +/* +#include +//#include +//UTFT myGLCD(ILI9325C,A2,A1,A3,A4); // Remember to change the model parameter to suit your display module! +//UTFT myGLCD(ILI9325D_8,A2,A1,A3,A4); // Remember to change the model parameter to suit your display module! +UTFT myGLCD(SSD1289_8,A1,A2,A0,A3); // Remember to change the model parameter to suit your display module! +*/ + +// Uncomment the next line for Arduino 2009/Uno +// UTFT(byte model, int RS, int WR,int CS,int RD) +//UTFT myGLCD(ILI9325C,A2,A1,A3,A0); // Remember to change the model parameter to suit your display module! +//Adafruit_UTFT myGLCD; + +// Declare which fonts we will be using +extern uint8_t SmallFont[]; + +void setup() +{ + randomSeed(analogRead(0)); + pinMode(A0, OUTPUT); + digitalWrite(A0, HIGH); + +// Setup the LCD + myGLCD.InitLCD(); + myGLCD.setFont(SmallFont); +} + +void loop() +{ + int buf[318]; + int x, x2; + int y, y2; + int r; + +// Clear the screen and draw the frame + myGLCD.clrScr(); + + myGLCD.setColor(255, 0, 0); + myGLCD.fillRect(0, 0, 319, 13); + myGLCD.setColor(64, 64, 64); + myGLCD.fillRect(0, 226, 319, 239); + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.print("* Universal Color TFT Display Library *", CENTER, 1); + myGLCD.setBackColor(64, 64, 64); + myGLCD.setColor(255,255,0); + myGLCD.print("", CENTER, 227); + + myGLCD.setColor(0, 0, 255); + myGLCD.drawRect(0, 14, 319, 225); + +// Draw crosshairs + myGLCD.setColor(0, 0, 255); + myGLCD.setBackColor(0, 0, 0); + myGLCD.drawLine(159, 15, 159, 224); + myGLCD.drawLine(1, 119, 318, 119); + for (int i=9; i<310; i+=10) + myGLCD.drawLine(i, 117, i, 121); + for (int i=19; i<220; i+=10) + myGLCD.drawLine(157, i, 161, i); + +// Draw sin-, cos- and tan-lines + myGLCD.setColor(0,255,255); + myGLCD.print("Sin", 5, 15); + for (int i=1; i<318; i++) + { + myGLCD.drawPixel(i,119+(sin(((i*1.13)*3.14)/180)*95)); + } + + myGLCD.setColor(255,0,0); + myGLCD.print("Cos", 5, 27); + for (int i=1; i<318; i++) + { + myGLCD.drawPixel(i,119+(cos(((i*1.13)*3.14)/180)*95)); + } + + myGLCD.setColor(255,255,0); + myGLCD.print("Tan", 5, 39); + for (int i=1; i<318; i++) + { + myGLCD.drawPixel(i,119+(tan(((i*1.13)*3.14)/180))); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,318,224); + myGLCD.setColor(0, 0, 255); + myGLCD.setBackColor(0, 0, 0); + myGLCD.drawLine(159, 15, 159, 224); + myGLCD.drawLine(1, 119, 318, 119); + +// Draw a moving sinewave + x=1; + for (int i=1; i<(318*20); i++) + { + x++; + if (x==319) + x=1; + if (i>319) + { + if ((x==159)||(buf[x-1]==119)) + myGLCD.setColor(0,0,255); + else + myGLCD.setColor(0,0,0); + myGLCD.drawPixel(x,buf[x-1]); + } + myGLCD.setColor(0,255,255); + y=119+(sin(((i*1.1)*3.14)/180)*(90-(i / 100))); + myGLCD.drawPixel(x,y); + buf[x-1]=y; + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,318,224); + +// Draw some filled rectangles + for (int i=1; i<6; i++) + { + switch (i) + { + case 1: + myGLCD.setColor(255,0,255); + break; + case 2: + myGLCD.setColor(255,0,0); + break; + case 3: + myGLCD.setColor(0,255,0); + break; + case 4: + myGLCD.setColor(0,0,255); + break; + case 5: + myGLCD.setColor(255,255,0); + break; + } + myGLCD.fillRect(70+(i*20), 30+(i*20), 130+(i*20), 90+(i*20)); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,318,224); + +// Draw some filled, rounded rectangles + for (int i=1; i<6; i++) + { + switch (i) + { + case 1: + myGLCD.setColor(255,0,255); + break; + case 2: + myGLCD.setColor(255,0,0); + break; + case 3: + myGLCD.setColor(0,255,0); + break; + case 4: + myGLCD.setColor(0,0,255); + break; + case 5: + myGLCD.setColor(255,255,0); + break; + } + myGLCD.fillRoundRect(190-(i*20), 30+(i*20), 250-(i*20), 90+(i*20)); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,318,224); + +// Draw some filled circles + for (int i=1; i<6; i++) + { + switch (i) + { + case 1: + myGLCD.setColor(255,0,255); + break; + case 2: + myGLCD.setColor(255,0,0); + break; + case 3: + myGLCD.setColor(0,255,0); + break; + case 4: + myGLCD.setColor(0,0,255); + break; + case 5: + myGLCD.setColor(255,255,0); + break; + } + myGLCD.fillCircle(100+(i*20),60+(i*20), 30); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,318,224); + +// Draw some lines in a pattern + myGLCD.setColor (255,0,0); + for (int i=15; i<224; i+=5) + { + myGLCD.drawLine(1, i, (i*1.44)-10, 224); + } + myGLCD.setColor (255,0,0); + for (int i=224; i>15; i-=5) + { + myGLCD.drawLine(318, i, (i*1.44)-11, 15); + } + myGLCD.setColor (0,255,255); + for (int i=224; i>15; i-=5) + { + myGLCD.drawLine(1, i, 331-(i*1.44), 15); + } + myGLCD.setColor (0,255,255); + for (int i=15; i<224; i+=5) + { + myGLCD.drawLine(318, i, 330-(i*1.44), 224); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,318,225); + +// Draw some random circles + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=32+random(256); + y=45+random(146); + r=random(30); + myGLCD.drawCircle(x, y, r); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,318,224); + +// Draw some random rectangles + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=2+random(316); + y=16+random(207); + x2=2+random(316); + y2=16+random(207); + myGLCD.drawRect(x, y, x2, y2); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,318,224); + +// Draw some random rounded rectangles + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=2+random(316); + y=16+random(207); + x2=2+random(316); + y2=16+random(207); + myGLCD.drawRoundRect(x, y, x2, y2); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,318,224); + + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=2+random(316); + y=16+random(209); + x2=2+random(316); + y2=16+random(209); + myGLCD.drawLine(x, y, x2, y2); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,318,224); + + for (int i=0; i<10000; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + myGLCD.drawPixel(2+random(316), 16+random(209)); + } + + delay(2000); + + myGLCD.fillScr(0, 0, 255); + myGLCD.setColor(255, 0, 0); + myGLCD.fillRoundRect(80, 70, 239, 169); + + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.print("That's it!", CENTER, 93); + myGLCD.print("Restarting in a", CENTER, 119); + myGLCD.print("few seconds...", CENTER, 132); + + myGLCD.setColor(0, 255, 0); + myGLCD.setBackColor(0, 0, 255); + myGLCD.print("Runtime: (msecs)", CENTER, 210); + myGLCD.printNumI(millis(), CENTER, 225); + + delay (10000); +} + diff --git a/examples/GLUE_Demo_400x240/GLUE_Demo_400x240.ino b/examples/GLUE_Demo_400x240/GLUE_Demo_400x240.ino new file mode 100644 index 0000000..3507581 --- /dev/null +++ b/examples/GLUE_Demo_400x240/GLUE_Demo_400x240.ino @@ -0,0 +1,337 @@ +// UTFT_Demo_400x240 (C)2012 Henning Karlsen +// web: http://www.henningkarlsen.com/electronics +// +// This program is a demo of how to use most of the functions +// of the library with a supported display modules. +// +// This demo was made for modules with a screen resolution +// of 400x240 pixels. +// +// This program requires the UTFT library. +// + +#include +//#include +#include +#include +//UTFTGLUE myGLCD; // use for default shield +UTFTGLUE myGLCD(0x9327,A2,A1,A3,A4,A0); +extern uint8_t SmallFont[]; + +/* +#include + +// Declare which fonts we will be using +extern uint8_t SmallFont[]; + +// Uncomment the next line for Arduino 2009/Uno +UTFT myGLCD(ITDB32WD,19,18,17,16); // Remember to change the model parameter to suit your display module! + +// Uncomment the next line for Arduino Mega +//UTFT myGLCD(ITDB32WD,38,39,40,41); // Remember to change the model parameter to suit your display module! +*/ + +void setup() +{ + randomSeed(analogRead(0)); + +// Setup the LCD + myGLCD.InitLCD(); + myGLCD.setFont(SmallFont); +} + +void loop() +{ + int buf[398]; + int x, x2; + int y, y2; + int r; + +// Clear the screen and draw the frame + myGLCD.clrScr(); + + myGLCD.setColor(255, 0, 0); + myGLCD.fillRect(0, 0, 399, 13); + myGLCD.setColor(64, 64, 64); + myGLCD.fillRect(0, 226, 399, 239); + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.print("*** Universal Color TFT Display Library ***", CENTER, 1); + myGLCD.setBackColor(64, 64, 64); + myGLCD.setColor(255,255,0); + myGLCD.print("< http://electronics.henningkarlsen.com >", CENTER, 227); + + myGLCD.setColor(0, 0, 255); + myGLCD.drawRect(0, 14, 399, 225); + +// Draw crosshairs + myGLCD.setColor(0, 0, 255); + myGLCD.setBackColor(0, 0, 0); + myGLCD.drawLine(199, 15, 199, 224); + myGLCD.drawLine(1, 119, 398, 119); + for (int i=9; i<390; i+=10) + myGLCD.drawLine(i, 117, i, 121); + for (int i=19; i<220; i+=10) + myGLCD.drawLine(197, i, 201, i); + +// Draw sin-, cos- and tan-lines + myGLCD.setColor(0,255,255); + myGLCD.print("Sin", 5, 15); + for (int i=1; i<398; i++) + { + myGLCD.drawPixel(i,119+(sin(((i*0.9)*3.14)/180)*95)); + } + + myGLCD.setColor(255,0,0); + myGLCD.print("Cos", 5, 27); + for (int i=1; i<398; i++) + { + myGLCD.drawPixel(i,119+(cos(((i*0.9)*3.14)/180)*95)); + } + + myGLCD.setColor(255,255,0); + myGLCD.print("Tan", 5, 39); + for (int i=1; i<398; i++) + { + y=119+(tan(((i*0.9)*3.14)/180)); + if ((y>15) && (y<224)) + myGLCD.drawPixel(i,y); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,398,224); + myGLCD.setColor(0, 0, 255); + myGLCD.setBackColor(0, 0, 0); + myGLCD.drawLine(199, 15, 199, 224); + myGLCD.drawLine(1, 119, 398, 119); + +// Draw a moving sinewave + x=1; + for (int i=1; i<(398*20); i++) + { + x++; + if (x==399) + x=1; + if (i>399) + { + if ((x==199)||(buf[x-1]==119)) + myGLCD.setColor(0,0,255); + else + myGLCD.setColor(0,0,0); + myGLCD.drawPixel(x,buf[x-1]); + } + myGLCD.setColor(0,255,255); + y=119+(sin(((i)*3.14)/180)*(90-(i / 100))); + myGLCD.drawPixel(x,y); + buf[x-1]=y; + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,398,224); + +// Draw some filled rectangles + for (int i=1; i<6; i++) + { + switch (i) + { + case 1: + myGLCD.setColor(255,0,255); + break; + case 2: + myGLCD.setColor(255,0,0); + break; + case 3: + myGLCD.setColor(0,255,0); + break; + case 4: + myGLCD.setColor(0,0,255); + break; + case 5: + myGLCD.setColor(255,255,0); + break; + } + myGLCD.fillRect(110+(i*20), 30+(i*20), 170+(i*20), 90+(i*20)); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,398,224); + +// Draw some filled, rounded rectangles + for (int i=1; i<6; i++) + { + switch (i) + { + case 1: + myGLCD.setColor(255,0,255); + break; + case 2: + myGLCD.setColor(255,0,0); + break; + case 3: + myGLCD.setColor(0,255,0); + break; + case 4: + myGLCD.setColor(0,0,255); + break; + case 5: + myGLCD.setColor(255,255,0); + break; + } + myGLCD.fillRoundRect(230-(i*20), 30+(i*20), 290-(i*20), 90+(i*20)); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,398,224); + +// Draw some filled circles + for (int i=1; i<6; i++) + { + switch (i) + { + case 1: + myGLCD.setColor(255,0,255); + break; + case 2: + myGLCD.setColor(255,0,0); + break; + case 3: + myGLCD.setColor(0,255,0); + break; + case 4: + myGLCD.setColor(0,0,255); + break; + case 5: + myGLCD.setColor(255,255,0); + break; + } + myGLCD.fillCircle(110+(i*30),60+(i*20), 30); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,398,224); + +// Draw some lines in a pattern + myGLCD.setColor (255,0,0); + for (int i=15; i<224; i+=5) + { + myGLCD.drawLine(1, i, (i*1.77)-10, 224); + } + myGLCD.setColor (255,0,0); + for (int i=224; i>15; i-=5) + { + myGLCD.drawLine(398, i, (i*1.77)-11, 15); + } + myGLCD.setColor (0,255,255); + for (int i=224; i>15; i-=5) + { + myGLCD.drawLine(1, i, 411-(i*1.77), 15); + } + myGLCD.setColor (0,255,255); + for (int i=15; i<224; i+=5) + { + myGLCD.drawLine(398, i, 410-(i*1.77), 224); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,398,224); + +// Draw some random circles + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=32+random(336); + y=45+random(146); + r=random(30); + myGLCD.drawCircle(x, y, r); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,398,224); + +// Draw some random rectangles + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=2+random(396); + y=16+random(207); + x2=2+random(396); + y2=16+random(207); + myGLCD.drawRect(x, y, x2, y2); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,398,224); + +// Draw some random rounded rectangles + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=2+random(396); + y=16+random(207); + x2=2+random(396); + y2=16+random(207); + myGLCD.drawRoundRect(x, y, x2, y2); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,398,224); + + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=2+random(396); + y=16+random(209); + x2=2+random(396); + y2=16+random(209); + myGLCD.drawLine(x, y, x2, y2); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,398,224); + + for (int i=0; i<10000; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + myGLCD.drawPixel(2+random(396), 16+random(209)); + } + + delay(2000); + + myGLCD.fillScr(0, 0, 255); + myGLCD.setColor(255, 0, 0); + myGLCD.fillRoundRect(120, 70, 279, 169); + + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.print("That's it!", CENTER, 93); + myGLCD.print("Restarting in a", CENTER, 119); + myGLCD.print("few seconds...", CENTER, 132); + + myGLCD.setColor(0, 255, 0); + myGLCD.setBackColor(0, 0, 255); + myGLCD.print("Runtime: (msecs)", CENTER, 210); + myGLCD.printNumI(millis(), CENTER, 225); + + delay (10000); +} + diff --git a/examples/GLUE_Demo_480x320/GLUE_Demo_480x320.ino b/examples/GLUE_Demo_480x320/GLUE_Demo_480x320.ino new file mode 100644 index 0000000..4aa4b40 --- /dev/null +++ b/examples/GLUE_Demo_480x320/GLUE_Demo_480x320.ino @@ -0,0 +1,333 @@ +// UTFT_Demo_480x320 (C)2013 Henning Karlsen +// web: http://www.henningkarlsen.com/electronics +// +// This program is a demo of how to use most of the functions +// of the library with a supported display modules. +// +// This demo was made for modules with a screen resolution +// of 480x320 pixels. +// +// This program requires the UTFT library. +// + +#include +//#include +#include +//UTFTGLUE myGLCD; // use for default shield +UTFTGLUE myGLCD(0x9488,A2,A1,A3,A4,A0); +extern uint8_t SmallFont[]; + +/* +#include +// Declare which fonts we will be using +extern uint8_t SmallFont[]; + +// Uncomment the next line for Arduino 2009/Uno +//UTFT myGLCD(CTE32HR,19,18,17,16); // Remember to change the model parameter to suit your display module! + +// Uncomment the next line for Arduino Mega +UTFT myGLCD(CTE32HR,38,39,40,41); // Remember to change the model parameter to suit your display module! +*/ + +void setup() +{ + randomSeed(analogRead(0)); + +// Setup the LCD + myGLCD.InitLCD(); + myGLCD.setFont(SmallFont); +} + +void loop() +{ + int buf[478]; + int x, x2; + int y, y2; + int r; + +// Clear the screen and draw the frame + myGLCD.clrScr(); + + myGLCD.setColor(255, 0, 0); + myGLCD.fillRect(0, 0, 479, 13); + myGLCD.setColor(64, 64, 64); + myGLCD.fillRect(0, 306, 479, 319); + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.print("* Universal Color TFT Display Library *", CENTER, 1); + myGLCD.setBackColor(64, 64, 64); + myGLCD.setColor(255,255,0); + myGLCD.print("", CENTER, 307); + + myGLCD.setColor(0, 0, 255); + myGLCD.drawRect(0, 14, 479, 305); + +// Draw crosshairs + myGLCD.setColor(0, 0, 255); + myGLCD.setBackColor(0, 0, 0); + myGLCD.drawLine(239, 15, 239, 304); + myGLCD.drawLine(1, 159, 478, 159); + for (int i=9; i<470; i+=10) + myGLCD.drawLine(i, 157, i, 161); + for (int i=19; i<220; i+=10) + myGLCD.drawLine(237, i, 241, i); + +// Draw sin-, cos- and tan-lines + myGLCD.setColor(0,255,255); + myGLCD.print("Sin", 5, 15); + for (int i=1; i<478; i++) + { + myGLCD.drawPixel(i,159+(sin(((i*1.13)*3.14)/180)*95)); + } + + myGLCD.setColor(255,0,0); + myGLCD.print("Cos", 5, 27); + for (int i=1; i<478; i++) + { + myGLCD.drawPixel(i,159+(cos(((i*1.13)*3.14)/180)*95)); + } + + myGLCD.setColor(255,255,0); + myGLCD.print("Tan", 5, 39); + for (int i=1; i<478; i++) + { + myGLCD.drawPixel(i,159+(tan(((i*1.13)*3.14)/180))); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,478,304); + myGLCD.setColor(0, 0, 255); + myGLCD.setBackColor(0, 0, 0); + myGLCD.drawLine(239, 15, 239, 304); + myGLCD.drawLine(1, 159, 478, 159); + +// Draw a moving sinewave + x=1; + for (int i=1; i<(478*15); i++) + { + x++; + if (x==479) + x=1; + if (i>479) + { + if ((x==239)||(buf[x-1]==159)) + myGLCD.setColor(0,0,255); + else + myGLCD.setColor(0,0,0); + myGLCD.drawPixel(x,buf[x-1]); + } + myGLCD.setColor(0,255,255); + y=159+(sin(((i*0.7)*3.14)/180)*(90-(i / 100))); + myGLCD.drawPixel(x,y); + buf[x-1]=y; + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,478,304); + +// Draw some filled rectangles + for (int i=1; i<6; i++) + { + switch (i) + { + case 1: + myGLCD.setColor(255,0,255); + break; + case 2: + myGLCD.setColor(255,0,0); + break; + case 3: + myGLCD.setColor(0,255,0); + break; + case 4: + myGLCD.setColor(0,0,255); + break; + case 5: + myGLCD.setColor(255,255,0); + break; + } + myGLCD.fillRect(150+(i*20), 70+(i*20), 210+(i*20), 130+(i*20)); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,478,304); + +// Draw some filled, rounded rectangles + for (int i=1; i<6; i++) + { + switch (i) + { + case 1: + myGLCD.setColor(255,0,255); + break; + case 2: + myGLCD.setColor(255,0,0); + break; + case 3: + myGLCD.setColor(0,255,0); + break; + case 4: + myGLCD.setColor(0,0,255); + break; + case 5: + myGLCD.setColor(255,255,0); + break; + } + myGLCD.fillRoundRect(270-(i*20), 70+(i*20), 330-(i*20), 130+(i*20)); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,478,304); + +// Draw some filled circles + for (int i=1; i<6; i++) + { + switch (i) + { + case 1: + myGLCD.setColor(255,0,255); + break; + case 2: + myGLCD.setColor(255,0,0); + break; + case 3: + myGLCD.setColor(0,255,0); + break; + case 4: + myGLCD.setColor(0,0,255); + break; + case 5: + myGLCD.setColor(255,255,0); + break; + } + myGLCD.fillCircle(180+(i*20),100+(i*20), 30); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,478,304); + +// Draw some lines in a pattern + myGLCD.setColor (255,0,0); + for (int i=15; i<304; i+=5) + { + myGLCD.drawLine(1, i, (i*1.6)-10, 304); + } + myGLCD.setColor (255,0,0); + for (int i=304; i>15; i-=5) + { + myGLCD.drawLine(478, i, (i*1.6)-11, 15); + } + myGLCD.setColor (0,255,255); + for (int i=304; i>15; i-=5) + { + myGLCD.drawLine(1, i, 491-(i*1.6), 15); + } + myGLCD.setColor (0,255,255); + for (int i=15; i<304; i+=5) + { + myGLCD.drawLine(478, i, 490-(i*1.6), 304); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,478,304); + +// Draw some random circles + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=32+random(416); + y=45+random(226); + r=random(30); + myGLCD.drawCircle(x, y, r); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,478,304); + +// Draw some random rectangles + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=2+random(476); + y=16+random(289); + x2=2+random(476); + y2=16+random(289); + myGLCD.drawRect(x, y, x2, y2); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,478,304); + +// Draw some random rounded rectangles + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=2+random(476); + y=16+random(289); + x2=2+random(476); + y2=16+random(289); + myGLCD.drawRoundRect(x, y, x2, y2); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,478,304); + + for (int i=0; i<100; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + x=2+random(476); + y=16+random(289); + x2=2+random(476); + y2=16+random(289); + myGLCD.drawLine(x, y, x2, y2); + } + + delay(2000); + + myGLCD.setColor(0,0,0); + myGLCD.fillRect(1,15,478,304); + + for (int i=0; i<10000; i++) + { + myGLCD.setColor(random(255), random(255), random(255)); + myGLCD.drawPixel(2+random(476), 16+random(289)); + } + + delay(2000); + + myGLCD.fillScr(0, 0, 255); + myGLCD.setColor(255, 0, 0); + myGLCD.fillRoundRect(160, 70, 319, 169); + + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.print("That's it!", CENTER, 93); + myGLCD.print("Restarting in a", CENTER, 119); + myGLCD.print("few seconds...", CENTER, 132); + + myGLCD.setColor(0, 255, 0); + myGLCD.setBackColor(0, 0, 255); + myGLCD.print("Runtime: (msecs)", CENTER, 290); + myGLCD.printNumI(millis(), CENTER, 305); + + delay (10000); +} + diff --git a/examples/LCD_ID_readreg/LCD_ID_readreg.ino b/examples/LCD_ID_readreg/LCD_ID_readreg.ino new file mode 100644 index 0000000..1eedb37 --- /dev/null +++ b/examples/LCD_ID_readreg/LCD_ID_readreg.ino @@ -0,0 +1,257 @@ +// adapted from LCD_ID_Reader from http://misc.ws/lcd_information +// controllers either read as 16-bit or as a sequence of 8-bit values + +//-- Arduino UNO or Mega 2560 Plugged as shield +#define LCD_RST A4 +#define LCD_CS A3 +#define LCD_RS A2 +#define LCD_WR A1 +#define LCD_RD A0 + +#define LCD_D0 8 +#define LCD_D1 9 +#define LCD_D2 2 +#define LCD_D3 3 +#define LCD_D4 4 +#define LCD_D5 5 +#define LCD_D6 6 +#define LCD_D7 7 + +void setup() +{ + Serial.begin(9600); + while (!Serial) ; + Serial.println("Read Registers on MCUFRIEND UNO shield"); + Serial.println("controllers either read as single 16-bit"); + Serial.println("e.g. the ID is at readReg(0)"); + Serial.println("or as a sequence of 8-bit values"); + Serial.println("in special locations (first is dummy)"); + Serial.println(""); + lcdInit(); + lcdReset(); //ensures that controller is in default state + readReg(0x00, 2, "ID: ILI9320, ILI9325, ILI9335, ..."); + readReg(0x04, 4, "Manufacturer ID"); + readReg(0x09, 5, "Status Register"); + readReg(0x61, 2, "RDID1 HX8347-G"); + readReg(0x62, 2, "RDID2 HX8347-G"); + readReg(0x63, 2, "RDID3 HX8347-G"); + readReg(0x64, 2, "RDID1 HX8347-A"); + readReg(0x65, 2, "RDID2 HX8347-A"); + readReg(0x66, 2, "RDID3 HX8347-A"); + readReg(0x67, 2, "RDID Himax HX8347-A"); + readReg(0x70, 2, "Panel Himax HX8347-A"); + readReg(0xA1, 5, "RD_DDB SSD1963"); + readReg(0xB0, 2, "RGB Interface Signal Control"); + readReg(0xB4, 2, "Inversion Control"); + readReg(0xB6, 5, "Display Control"); + readReg(0xB7, 2, "Entry Mode Set"); + readReg(0xBF, 6, "ILI9481, HX8357-B"); + readReg(0xC0, 6, "Panel Control"); + readReg(0xCC, 2, "Panel Control"); + readReg(0xD0, 3, "Power Control"); + readReg(0xD2, 5, "NVM Read"); + readReg(0xD3, 4, "ILI9341, ILI9488"); + readReg(0xDA, 2, "RDID1"); + readReg(0xDB, 2, "RDID2"); + readReg(0xDC, 2, "RDID3"); + readReg(0xEF, 6, "ILI9327"); + readReg(0xF2, 12, "Adjust Control 2"); + readReg(0xF6, 4, "Interface Control"); +} + +void loop() +{ + // put your main code here, to run repeatedly: + +} + +void printhex(uint8_t val) +{ + if (val < 0x10) Serial.print("0"); + Serial.print(val, HEX); +} + +void readReg(uint16_t reg, uint8_t n, const char *msg) +{ + uint8_t val8; + lcdReset(); + lcdSetWriteDir(); +/* + lcdWriteCommand(0xF6); + lcdWriteData(0x01); + lcdWriteData(0x01); + lcdWriteData(0x03); +*/ + lcdWriteCommand(reg); + Serial.print("reg(0x"); + printhex(reg >> 8); + printhex(reg); + Serial.print(")"); + lcdSetReadDir(); + while (n--) { + val8 = lcdReadData8(); + Serial.print(" "); + printhex(val8); + } + lcdSetWriteDir(); + Serial.print("\t"); + Serial.println(msg); +} + +void lcdInit() +{ + pinMode(LCD_CS, OUTPUT); + digitalWrite(LCD_CS, HIGH); + pinMode(LCD_RS, OUTPUT); + digitalWrite(LCD_RS, HIGH); + pinMode(LCD_WR, OUTPUT); + digitalWrite(LCD_WR, HIGH); + pinMode(LCD_RD, OUTPUT); + digitalWrite(LCD_RD, HIGH); + pinMode(LCD_RST, OUTPUT); + digitalWrite(LCD_RST, HIGH); +} + +void lcdReset() +{ + digitalWrite(LCD_RST, LOW); + delay(2); + digitalWrite(LCD_RST, HIGH); + delay(10); //allow controller to re-start +} + +void lcdWrite8(uint16_t data) +{ + digitalWrite(LCD_D0, data & 1); + digitalWrite(LCD_D1, (data & 2) >> 1); + digitalWrite(LCD_D2, (data & 4) >> 2); + digitalWrite(LCD_D3, (data & 8) >> 3); + digitalWrite(LCD_D4, (data & 16) >> 4); + digitalWrite(LCD_D5, (data & 32) >> 5); + digitalWrite(LCD_D6, (data & 64) >> 6); + digitalWrite(LCD_D7, (data & 128) >> 7); +} + +uint16_t lcdRead8() +{ + uint16_t result = digitalRead(LCD_D7); + result <<= 1; + result |= digitalRead(LCD_D6); + result <<= 1; + result |= digitalRead(LCD_D5); + result <<= 1; + result |= digitalRead(LCD_D4); + result <<= 1; + result |= digitalRead(LCD_D3); + result <<= 1; + result |= digitalRead(LCD_D2); + result <<= 1; + result |= digitalRead(LCD_D1); + result <<= 1; + result |= digitalRead(LCD_D0); + + return result; +} + +void lcdSetWriteDir() +{ + pinMode(LCD_D0, OUTPUT); + pinMode(LCD_D1, OUTPUT); + pinMode(LCD_D2, OUTPUT); + pinMode(LCD_D3, OUTPUT); + pinMode(LCD_D4, OUTPUT); + pinMode(LCD_D5, OUTPUT); + pinMode(LCD_D6, OUTPUT); + pinMode(LCD_D7, OUTPUT); +} + + +void lcdSetReadDir() +{ + pinMode(LCD_D0, INPUT); + pinMode(LCD_D1, INPUT); + pinMode(LCD_D2, INPUT); + pinMode(LCD_D3, INPUT); + pinMode(LCD_D4, INPUT); + pinMode(LCD_D5, INPUT); + pinMode(LCD_D6, INPUT); + pinMode(LCD_D7, INPUT); +} + +void lcdWriteData(uint16_t data) +{ + lcdSetWriteDir(); + digitalWrite(LCD_CS, LOW); + digitalWrite(LCD_RS, HIGH); + digitalWrite(LCD_RD, HIGH); + digitalWrite(LCD_WR, HIGH); + + lcdWrite8(data >> 8); + + digitalWrite(LCD_WR, LOW); + delayMicroseconds(10); + digitalWrite(LCD_WR, HIGH); + + lcdWrite8(data); + + digitalWrite(LCD_WR, LOW); + delayMicroseconds(10); + digitalWrite(LCD_WR, HIGH); + + digitalWrite(LCD_CS, HIGH); +} + +void lcdWriteCommand(uint16_t command) +{ + lcdSetWriteDir(); + digitalWrite(LCD_CS, LOW); + digitalWrite(LCD_RS, LOW); + digitalWrite(LCD_RD, HIGH); + digitalWrite(LCD_WR, HIGH); + lcdWrite8(command >> 8); + digitalWrite(LCD_WR, LOW); + delayMicroseconds(10); + digitalWrite(LCD_WR, HIGH); + lcdWrite8(command); + digitalWrite(LCD_WR, LOW); + delayMicroseconds(10); + digitalWrite(LCD_WR, HIGH); + digitalWrite(LCD_CS, HIGH); +} + +uint8_t lcdReadData8() +{ + uint8_t result; + lcdSetReadDir(); + digitalWrite(LCD_CS, LOW); + digitalWrite(LCD_RS, HIGH); + digitalWrite(LCD_RD, HIGH); + digitalWrite(LCD_WR, HIGH); + + digitalWrite(LCD_RD, LOW); + delayMicroseconds(10); + result = lcdRead8(); + digitalWrite(LCD_RD, HIGH); + + delayMicroseconds(10); + + return result; +} + + +uint16_t lcdReadData16() +{ + uint16_t result; + result = lcdReadData8() << 8; + result |= lcdReadData8(); + return result; +} + + +void lcdWriteRegister(uint16_t addr, uint16_t data) +{ + lcdWriteCommand(addr); + lcdWriteData(data); +} + + diff --git a/examples/TouchScreen_Calibr_kbv/TouchScreen_Calibr_kbv.ino b/examples/TouchScreen_Calibr_kbv/TouchScreen_Calibr_kbv.ino new file mode 100644 index 0000000..2d4b5e3 --- /dev/null +++ b/examples/TouchScreen_Calibr_kbv/TouchScreen_Calibr_kbv.ino @@ -0,0 +1,364 @@ +// TouchScreen_Calibr_kbv for MCUFRIEND UNO Display Shields +// adapted by David Prentice +// for Adafruit's Resistive Touch Screen Library +// from Henning Karlsen's original program. Many Thanks. + +// UTouch_Calibration (C)2013-2014 Henning Karlsen +// web: http://www.henningkarlsen.com/electronics +// +// This program can be used to calibrate the touchscreen +// of the display modules. +// +// It is assumed that the display module is connected to an +// appropriate shield or that you know how to change the pin +// numbers in the setup. +// +// Instructions will be given on the display. + +#define TOUCH_ORIENTATION PORTRAIT +#define TITLE "TouchScreen.h Calibration" + +#include +#include //we are using UTFT display methods +UTFTGLUE myGLCD(0x9341, A2, A1, A3, A4, A0); + +#include //Adafruit Library + +// MCUFRIEND UNO shield shares pins with the TFT. Due does NOT work +#define YP A1 //[A1], A3 for ILI9320, A2 for ST7789V +#define YM 7 //[ 7], 9 , 7 +#define XM A2 //[A2], A2 for ILI9320, A1 for ST7789V +#define XP 6 //[ 6], 8 , 6 + +TouchScreen myTouch(XP, YP, XM, YM, 300); +TSPoint tp; //Touchscreen_due branch uses Point + +void readResistiveTouch(void) +{ + tp = myTouch.getPoint(); + pinMode(YP, OUTPUT); //restore shared pins + pinMode(XM, OUTPUT); + digitalWrite(YP, HIGH); //because TFT control pins + digitalWrite(XM, HIGH); +} + +bool ISPRESSED(void) +{ + // .kbv this was too sensitive !! + // now touch has to be stable for 50ms + int count = 0; + bool state, oldstate; + while (count < 10) { + readResistiveTouch(); + state = tp.z > 20 && tp.z < 1000; + if (state == oldstate) count++; + else count = 0; + oldstate = state; + delay(5); + } + return oldstate; +} + +void showpoint(void) +{ + Serial.print("\r\nx="); Serial.print(tp.x); + Serial.print(" y="); Serial.print(tp.y); + Serial.print(" z="); Serial.print(tp.z); +} + +// ************************************ +// DO NOT EDIT ANYTHING BELOW THIS LINE +// ************************************ + +// Declare which fonts we will be using +extern uint8_t SmallFont[]; + +uint32_t cx, cy; +uint32_t rx[8], ry[8]; +int32_t clx, crx, cty, cby; +float px, py; +int dispx, dispy, text_y_center, swapxy; +uint32_t calx, caly, cals; +char buf[13]; + +void setup() +{ + Serial.begin(9600); + Serial.println(TITLE); + digitalWrite(A0, HIGH); + pinMode(A0, OUTPUT); + myGLCD.InitLCD(TOUCH_ORIENTATION); + myGLCD.clrScr(); + myGLCD.setFont(SmallFont); + dispx = myGLCD.getDisplayXSize(); + dispy = myGLCD.getDisplayYSize(); + text_y_center = (dispy / 2) - 6; +} + +void drawCrossHair(int x, int y) +{ + myGLCD.drawRect(x - 10, y - 10, x + 10, y + 10); + myGLCD.drawLine(x - 5, y, x + 5, y); + myGLCD.drawLine(x, y - 5, x, y + 5); +} + +void readCoordinates() +{ + int iter = 5000; + int failcount = 0; + int cnt = 0; + uint32_t tx = 0; + uint32_t ty = 0; + boolean OK = false; + + while (OK == false) + { + myGLCD.setColor(255, 255, 255); + myGLCD.print("* PRESS *", CENTER, text_y_center); + while (ISPRESSED() == false) {} + myGLCD.print("* HOLD! *", CENTER, text_y_center); + cnt = 0; + iter = 400; + do + { + readResistiveTouch(); + // showpoint(tp); + if (tp.z > 20 && tp.z < 1000) + { + tx += tp.x; + ty += tp.y; + cnt++; + } + else + failcount++; + } while ((cnt < iter) && (failcount < 10000)); + if (cnt >= iter) + { + OK = true; + } + else + { + tx = 0; + ty = 0; + cnt = 0; + } + if (failcount >= 10000) + fail(); + } + + cx = tx / iter; + cy = ty / iter; +} + +void calibrate(int x, int y, int i) +{ + myGLCD.setColor(255, 255, 255); + drawCrossHair(x, y); + myGLCD.setBackColor(255, 0, 0); + readCoordinates(); + myGLCD.setColor(255, 255, 255); + myGLCD.print("* RELEASE *", CENTER, text_y_center); + myGLCD.setColor(80, 80, 80); + drawCrossHair(x, y); + rx[i] = cx; + ry[i] = cy; + Serial.print("\r\ncx="); Serial.print(cx); + Serial.print(" cy="); Serial.print(cy); + while (ISPRESSED() == true) {} +} + +void waitForTouch() +{ + while (ISPRESSED() == true) {} + while (ISPRESSED() == false) {} + while (ISPRESSED() == true) {} +} + +void toHex(uint32_t num) +{ + buf[0] = '0'; + buf[1] = 'x'; + buf[10] = 'U'; + buf[11] = 'L'; + buf[12] = 0; + for (int zz = 9; zz > 1; zz--) + { + if ((num & 0xF) > 9) + buf[zz] = (num & 0xF) + 55; + else + buf[zz] = (num & 0xF) + 48; + num = num >> 4; + } +} + +void startup() +{ + myGLCD.setColor(255, 0, 0); + myGLCD.fillRect(0, 0, dispx - 1, 13); + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.drawLine(0, 14, dispx - 1, 14); + myGLCD.print(TITLE, CENTER, 1); + myGLCD.setBackColor(0, 0, 0); + + myGLCD.print("Use a stylus or something", LEFT, 30); + myGLCD.print("similar to touch as close", LEFT, 42); + myGLCD.print("to the center of the", LEFT, 54); + myGLCD.print("highlighted crosshair as", LEFT, 66); + myGLCD.print("possible. Keep as still as", LEFT, 78); + myGLCD.print("possible and keep holding", LEFT, 90); + myGLCD.print("until the highlight is", LEFT, 102); + myGLCD.print("removed. Repeat for all", LEFT, 114); + myGLCD.print("crosshairs in sequence.", LEFT, 126); + myGLCD.print("Touch screen to continue", CENTER, 162); + + waitForTouch(); + myGLCD.clrScr(); +} + +void showNumI(char *msg, uint32_t val, int x, int y) +{ + myGLCD.print(msg, x, y); + myGLCD.printNumI(val, x + 50, y); +} + +void done() +{ + uint16_t TS_LEFT, TS_RT, TS_TOP, TS_BOT, TS_WID, TS_HT, TS_SWAP; + int16_t tmp; + myGLCD.clrScr(); + myGLCD.setColor(255, 0, 0); + myGLCD.fillRect(0, 0, dispx - 1, 13); + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.drawLine(0, 14, dispx - 1, 14); + myGLCD.print(TITLE, CENTER, 1); + myGLCD.setBackColor(0, 0, 0); + myGLCD.print("To use the new calibration", LEFT, 30); + myGLCD.print("settings you must map the values", LEFT, 42); + myGLCD.print("from Point p = ts.getPoint() e.g. ", LEFT, 54); + myGLCD.print("x = map(p.x, LEFT, RT, 0, tft.width());", LEFT, 66); + myGLCD.print("y = map(p.y, TOP, BOT, 0, tft.height());", LEFT, 78); + myGLCD.print("swap p.x and p.y if diff ORIENTATION", LEFT, 90); + + //.kbv show human values + TS_LEFT = (calx >> 14) & 0x3FFF; + TS_RT = (calx >> 0) & 0x3FFF; + TS_TOP = (caly >> 14) & 0x3FFF; + TS_BOT = (caly >> 0) & 0x3FFF; + TS_WID = ((cals >> 12) & 0x0FFF) + 1; + TS_HT = ((cals >> 0) & 0x0FFF) + 1; + TS_SWAP = (cals >> 31); + if (TOUCH_ORIENTATION != 0) { + myGLCD.print("Sketch is LANDSCAPE", 0, 126); + myGLCD.printNumI(TS_WID, 150, 126); + myGLCD.print("x", 174, 126); + myGLCD.printNumI(TS_HT, 186, 126); + showNumI("LEFT ", TS_LEFT, 0, 138); + showNumI("RT ", TS_RT, 100, 138); + showNumI("TOP ", TS_TOP, 0, 150); + showNumI("BOT ", TS_BOT, 100, 150); + switch (TOUCH_ORIENTATION) { + case 1: + tmp = TS_LEFT, TS_LEFT = TS_TOP, TS_TOP = TS_RT, TS_RT = TS_BOT, TS_BOT = tmp; + tmp = TS_WID, TS_WID = TS_HT, TS_HT = tmp; + break; + } + } + myGLCD.print("PORTRAIT CALIBRATION", 0, 174); + myGLCD.printNumI(TS_WID, 150, 174); + myGLCD.print("x", 174, 174); + myGLCD.printNumI(TS_HT, 186, 174); + showNumI("LEFT ", TS_LEFT, 0, 186); + showNumI("RT ", TS_RT, 100, 186); + myGLCD.printNumF(((float)TS_RT - TS_LEFT) / TS_WID, 2, 200, 186); + showNumI("TOP ", TS_TOP, 0, 198); + showNumI("BOT ", TS_BOT, 100, 198); + myGLCD.printNumF(((float)TS_BOT - TS_TOP) / TS_HT, 2, 200, 198); + myGLCD.print("Touch Pin Wiring is ", 0, 222); + myGLCD.print((cals >> 31) ? "SWAPXY" : "PORTRAIT", 170, 222); + +} + +void fail() +{ + myGLCD.clrScr(); + myGLCD.setColor(255, 0, 0); + myGLCD.fillRect(0, 0, dispx - 1, 13); + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.drawLine(0, 14, dispx - 1, 14); + myGLCD.print("Touch Calibration FAILED", CENTER, 1); + myGLCD.setBackColor(0, 0, 0); + + myGLCD.print("Unable to read the position", LEFT, 30); + myGLCD.print("of the press. This is a", LEFT, 42); + myGLCD.print("hardware issue and can", LEFT, 54); + myGLCD.print("not be corrected in", LEFT, 66); + myGLCD.print("software.", LEFT, 78); + myGLCD.print("check XP, XM pins with a multimeter", LEFT, 102); + myGLCD.print("check YP, YM pins with a multimeter", LEFT, 114); + myGLCD.print("should be about 300 ohms", LEFT, 126); + + while (true) {}; +} + +void loop() +{ + startup(); + + myGLCD.setColor(80, 80, 80); + drawCrossHair(dispx - 11, 10); + drawCrossHair(dispx / 2, 10); + drawCrossHair(10, 10); + drawCrossHair(dispx - 11, dispy / 2); + drawCrossHair(10, dispy / 2); + drawCrossHair(dispx - 11, dispy - 11); + drawCrossHair(dispx / 2, dispy - 11); + drawCrossHair(10, dispy - 11); + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.print("***********", CENTER, text_y_center - 12); + myGLCD.print("***********", CENTER, text_y_center + 12); + + calibrate(10, 10, 0); + calibrate(10, dispy / 2, 1); + calibrate(10, dispy - 11, 2); + calibrate(dispx / 2, 10, 3); + calibrate(dispx / 2, dispy - 11, 4); + calibrate(dispx - 11, 10, 5); + calibrate(dispx - 11, dispy / 2, 6); + calibrate(dispx - 11, dispy - 11, 7); + + cals = (long(dispx - 1) << 12) + (dispy - 1); + if (TOUCH_ORIENTATION == PORTRAIT) swapxy = rx[2] - rx[0]; + else swapxy = ry[2] - ry[0]; + swapxy = (swapxy < -500 || swapxy > 500); + if ((TOUCH_ORIENTATION == PORTRAIT) ^ (swapxy != 0)) { + clx = (rx[0] + rx[1] + rx[2]) / 3; + crx = (rx[5] + rx[6] + rx[7]) / 3; + cty = (ry[0] + ry[3] + ry[5]) / 3; + cby = (ry[2] + ry[4] + ry[7]) / 3; + } else { + clx = (ry[0] + ry[1] + ry[2]) / 3; + crx = (ry[5] + ry[6] + ry[7]) / 3; + cty = (rx[0] + rx[3] + rx[5]) / 3; + cby = (rx[2] + rx[4] + rx[7]) / 3; + } + px = float(crx - clx) / (dispx - 20); + py = float(cby - cty) / (dispy - 20); + // px = 0; + clx -= px * 10; + crx += px * 10; + cty -= py * 10; + cby += py * 10; + + calx = (long(clx) << 14) + long(crx); + caly = (long(cty) << 14) + long(cby); + if (swapxy) + cals |= (1L << 31); + + done(); + while (true) {} +} + diff --git a/examples/Touch_shield_kbv/Touch_shield_kbv.ino b/examples/Touch_shield_kbv/Touch_shield_kbv.ino new file mode 100644 index 0000000..c817de8 --- /dev/null +++ b/examples/Touch_shield_kbv/Touch_shield_kbv.ino @@ -0,0 +1,290 @@ +// the regular Adafruit "TouchScreen.h" library only works on AVRs + +// different mcufriend shields have Touchscreen on different pins +// and rotation. +// Run the UTouch_calibr_kbv sketch for calibration of your shield + +#include // Core graphics library +//#include // Hardware-specific library +//Adafruit_TFTLCD tft(A3, A2, A1, A0, A4); +#include +MCUFRIEND_kbv tft; // hard-wired for UNO shields anyway. +#include + +#if defined(__SAM3X8E__) +#undef __FlashStringHelper::F(string_literal) +#define F(string_literal) string_literal +#endif + +// These are the pins for some typical shields! +// S6D0154: YP=A1, XM=A2, YM=7, XP=6 +// ST7783 : YP=A2, XM=A1, YM=6, XP=7 +// ILI9320: YP=A2, XM=A3, YM=8, XP=9 +// ILI9325: YP=A1, XM=A2, YM=7, XP=6 +// ILI9325BG: YP=A2, XM=A1, YM=6, XP=7 +// ILI9341: YP=A2, XM=A1, YM=7, XP=6 +// ILI9488: YP=A1, XM=A2, YM=7, XP=6 +// R65109V: YP=A2, XM=A1, YM=6, XP=7 + +// most mcufriend shields use these pins and Portrait mode: +uint8_t YP = A1; // must be an analog pin, use "An" notation! +uint8_t XM = A2; // must be an analog pin, use "An" notation! +uint8_t YM = 7; // can be a digital pin +uint8_t XP = 6; // can be a digital pin +uint8_t SwapXY = 0; + +uint16_t TS_LEFT = 920; +uint16_t TS_RT = 150; +uint16_t TS_TOP = 940; +uint16_t TS_BOT = 120; +char *name = "Unknown controller"; + +// 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); +TSPoint tp; + +#define MINPRESSURE 20 +#define MAXPRESSURE 1000 + +#define SWAP(a, b) {uint16_t tmp = a; a = b; b = tmp;} + +int16_t BOXSIZE; +int16_t PENRADIUS = 3; +uint16_t identifier, oldcolor, currentcolor; +uint8_t Orientation = 0; //PORTRAIT + +// 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 show_Serial(void) +{ + Serial.print(F("Found ")); + Serial.print(name); + Serial.println(F(" LCD driver")); + Serial.print(F("ID=0x")); + Serial.println(identifier, HEX); + Serial.println("Screen is " + String(tft.width()) + "x" + String(tft.height())); + Serial.println("Calibration is: "); + Serial.println("LEFT = " + String(TS_LEFT) + " RT = " + String(TS_RT)); + Serial.println("TOP = " + String(TS_TOP) + " BOT = " + String(TS_BOT)); + Serial.print("Wiring is: "); + Serial.println(SwapXY ? "SWAPXY" : "PORTRAIT"); + Serial.println("YP=" + String(YP) + " XM=" + String(XM)); + Serial.println("YM=" + String(YM) + " XP=" + String(XP)); +} + +void show_tft(void) +{ + tft.setCursor(0, 0); + tft.setTextSize(2); + tft.print(F("Found ")); + tft.print(name); + tft.println(F(" LCD")); + tft.setTextSize(1); + tft.print(F("ID=0x")); + tft.println(identifier, HEX); + tft.println("Screen is " + String(tft.width()) + "x" + String(tft.height())); + tft.println("Calibration is: "); + tft.println("LEFT = " + String(TS_LEFT) + " RT = " + String(TS_RT)); + tft.println("TOP = " + String(TS_TOP) + " BOT = " + String(TS_BOT)); + tft.print("\nWiring is: "); + if (SwapXY) { + tft.setTextColor(CYAN); + tft.setTextSize(2); + } + tft.println(SwapXY ? "SWAPXY" : "PORTRAIT"); + tft.println("YP=" + String(YP) + " XM=" + String(XM)); + tft.println("YM=" + String(YM) + " XP=" + String(XP)); + tft.setTextSize(2); + tft.setTextColor(RED); + tft.setCursor((tft.width() - 48) / 2, (tft.height() * 2) / 4); + tft.print("EXIT"); + tft.setTextColor(YELLOW, BLACK); + tft.setCursor(0, (tft.height() * 6) / 8); + tft.print("Touch screen for loc"); + while (1) { + tp = ts.getPoint(); + pinMode(XM, OUTPUT); + pinMode(YP, OUTPUT); + pinMode(XP, OUTPUT); + pinMode(YM, OUTPUT); + if (tp.z < MINPRESSURE || tp.z > MAXPRESSURE) continue; + if (tp.x > 450 && tp.x < 570 && tp.y > 450 && tp.y < 570) break; + tft.setCursor(0, (tft.height() * 3) / 4); + tft.print("tp.x=" + String(tp.x) + " tp.y=" + String(tp.y) + " "); + } +} + + +void setup(void) +{ + uint16_t tmp; + tft.begin(9600); + + tft.reset(); + identifier = tft.readID(); + // if (identifier == 0) identifier = 0x9341; + if (0) { + } else if (identifier == 0x0154) { + name = "S6D0154"; + TS_LEFT = 914; TS_RT = 181; TS_TOP = 957; TS_BOT = 208; + } else if (identifier == 0x7783) { + name = "ST7781"; + TS_LEFT = 865; TS_RT = 155; TS_TOP = 942; TS_BOT = 153; + SwapXY = 1; + } else if (identifier == 0x7789) { + name = "ST7789V"; + YP = A2; XM = A1; YM = 7; XP = 6; + TS_LEFT = 906; TS_RT = 169; TS_TOP = 161; TS_BOT = 919; + } else if (identifier == 0x9320) { + name = "ILI9320"; + YP = A3; XM = A2; YM = 9; XP = 8; + TS_LEFT = 902; TS_RT = 137; TS_TOP = 941; TS_BOT = 134; + } else if (identifier == 0x9325) { + name = "ILI9325"; + TS_LEFT = 900; TS_RT = 103; TS_TOP = 96; TS_BOT = 904; + } else if (identifier == 0x9325) { + name = "ILI9325 Green Dog"; + TS_LEFT = 900; TS_RT = 130; TS_TOP = 940; TS_BOT = 130; + } else if (identifier == 0x9327) { + name = "ILI9327"; + TS_LEFT = 899; TS_RT = 135; TS_TOP = 935; TS_BOT = 79; + SwapXY = 1; + } else if (identifier == 0x9329) { + name = "ILI9329"; + TS_LEFT = 143; TS_RT = 885; TS_TOP = 941; TS_BOT = 131; + SwapXY = 1; + } else if (identifier == 0x9341) { + name = "ILI9341 BLUE"; + TS_LEFT = 920; TS_RT = 139; TS_TOP = 944; TS_BOT = 150; + SwapXY = 0; + } else if (identifier == 0) { + name = "ILI9341 DealExtreme"; + TS_LEFT = 893; TS_RT = 145; TS_TOP = 930; TS_BOT = 135; + SwapXY = 1; + } else if (identifier == 0 || identifier == 0x9341) { + name = "ILI9341"; + TS_LEFT = 128; TS_RT = 911; TS_TOP = 105; TS_BOT = 908; + SwapXY = 1; + } else if (identifier == 0x9486) { + name = "ILI9486"; + TS_LEFT = 904; TS_RT = 170; TS_TOP = 950; TS_BOT = 158; + } else if (identifier == 0x9488) { + name = "ILI9488"; + TS_LEFT = 904; TS_RT = 170; TS_TOP = 950; TS_BOT = 158; + } else if (identifier == 0xB509) { + name = "R61509V"; + TS_LEFT = 889; TS_RT = 149; TS_TOP = 106; TS_BOT = 975; + SwapXY = 1; + } else { + name = "unknown"; + } + switch (Orientation) { // adjust for different aspects + case 0: break; //no change, calibrated for PORTRAIT + case 1: tmp = TS_LEFT, TS_LEFT = TS_BOT, TS_BOT = TS_RT, TS_RT = TS_TOP, TS_TOP = tmp; break; + case 2: SWAP(TS_LEFT, TS_RT); SWAP(TS_TOP, TS_BOT); break; + case 3: tmp = TS_LEFT, TS_LEFT = TS_TOP, TS_TOP = TS_RT, TS_RT = TS_BOT, TS_BOT = tmp; break; + } + + Serial.begin(9600); + ts = TouchScreen(XP, YP, XM, YM, 300); //call the constructor AGAIN with new values. + tft.begin(identifier); + show_Serial(); + tft.setRotation(Orientation); + tft.fillScreen(BLACK); + show_tft(); + + BOXSIZE = tft.width() / 6; + 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.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE); + currentcolor = RED; + delay(1000); +} + +void loop() +{ + uint16_t xpos, ypos; //screen coordinates + tp = ts.getPoint(); //tp.x, tp.y are ADC values + + // if sharing pins, you'll need to fix the directions of the touchscreen pins + pinMode(XM, OUTPUT); + pinMode(YP, OUTPUT); + pinMode(XP, OUTPUT); + pinMode(YM, OUTPUT); + // digitalWrite(XM, HIGH); + // digitalWrite(YP, HIGH); + // we have some minimum pressure we consider 'valid' + // pressure of 0 means no pressing! + + if (tp.z > MINPRESSURE && tp.z < MAXPRESSURE) { + // is controller wired for Landscape ? or are we oriented in Landscape? + if (SwapXY != (Orientation & 1)) SWAP(tp.x, tp.y); + // scale from 0->1023 to tft.width i.e. left = 0, rt = width + // most mcufriend have touch (with icons) that extends below the TFT + // screens without icons need to reserve a space for "erase" + // scale the ADC values from ts.getPoint() to screen values e.g. 0-239 + xpos = map(tp.x, TS_LEFT, TS_RT, 0, tft.width()); + ypos = map(tp.y, TS_TOP, TS_BOT, 0, tft.height()); + + // are we in top color box area ? + if (ypos < BOXSIZE) { //draw white border on selected color box + oldcolor = currentcolor; + + if (xpos < BOXSIZE) { + currentcolor = RED; + tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE); + } else if (xpos < BOXSIZE * 2) { + currentcolor = YELLOW; + tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE); + } else if (xpos < BOXSIZE * 3) { + currentcolor = GREEN; + tft.drawRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, WHITE); + } else if (xpos < BOXSIZE * 4) { + currentcolor = CYAN; + tft.drawRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, WHITE); + } else if (xpos < BOXSIZE * 5) { + currentcolor = BLUE; + tft.drawRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, WHITE); + } else if (xpos < BOXSIZE * 6) { + currentcolor = MAGENTA; + tft.drawRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, WHITE); + } + + if (oldcolor != currentcolor) { //rub out the previous white border + 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); + } + } + // are we in drawing area ? + if (((ypos - PENRADIUS) > BOXSIZE) && ((ypos + PENRADIUS) < tft.height())) { + tft.fillCircle(xpos, ypos, PENRADIUS, currentcolor); + } + // are we in erase area ? + if (ypos > tft.height() - 10) { + // press the bottom of the screen to erase + tft.fillRect(0, BOXSIZE, tft.width(), tft.height() - BOXSIZE, BLACK); + } + } +} + diff --git a/examples/UTouch_Calibr_kbv/UTouch_Calibr_kbv.ino b/examples/UTouch_Calibr_kbv/UTouch_Calibr_kbv.ino new file mode 100644 index 0000000..c9b3afe --- /dev/null +++ b/examples/UTouch_Calibr_kbv/UTouch_Calibr_kbv.ino @@ -0,0 +1,376 @@ +// TouchScreen_Calibr_kbv for MCUFRIEND UNO Display Shields +// adapted by David Prentice +// for Adafruit's Resistive Touch Screen Library +// from Henning Karlsen's original program. Many Thanks. + +// UTouch_Calibration (C)2013-2014 Henning Karlsen +// web: http://www.henningkarlsen.com/electronics +// +// This program can be used to calibrate the touchscreen +// of the display modules. +// This program requires the UTFT library and a touch +// screen module that is compatible with UTFT. +// +// It is assumed that the display module is connected to an +// appropriate shield or that you know how to change the pin +// numbers in the setup. +// +// Instructions will be given on the display. + +#define TOUCH_ORIENTATION PORTRAIT +#define USE_UTOUCH 0 + +#if !(USE_UTOUCH) +#define TITLE "TouchScreen.h Calibration" +#include +#include //we are using UTFT display methods +UTFTGLUE myGLCD(0x9341, A2, A1, A3, A4, A0); + +#include + +// MCUFRIEND UNO shield shares pins with the TFT. Due does NOT work +#define YP A1 //A3 for ILI9320 +#define YM 7 //9 +#define XM A2 +#define XP 6 //8 + +TouchScreen myTouch(XP, YP, XM, YM, 300); +TSPoint tp; //Touchscreen_due branch uses Point + +void readResistiveTouch(void) +{ + tp = myTouch.getPoint(); + pinMode(YP, OUTPUT); //restore shared pins + pinMode(XM, OUTPUT); + digitalWrite(YP, HIGH); + digitalWrite(XM, HIGH); +} + +bool ISPRESSED(void) +{ + readResistiveTouch(); + return tp.z > 20 && tp.z < 1000; +} + +void showpoint(void) +{ + Serial.print("\r\nx="); Serial.print(tp.x); + Serial.print(" y="); Serial.print(tp.y); + Serial.print(" z="); Serial.print(tp.z); +} +#else +#define TITLE "UTouch.h Calibration" +#include +#include +#include +UTFT myGLCD(ILI9486, 38, 39, 40, 41); +UTouch myTouch( 6, 5, 4, 3, 2); + +#define ISPRESSED() myTouch.dataAvailable() +extern void fail(); + +#endif + +// ************************************ +// DO NOT EDIT ANYTHING BELOW THIS LINE +// ************************************ + +// Declare which fonts we will be using +extern uint8_t SmallFont[]; + +uint32_t cx, cy; +uint32_t rx[8], ry[8]; +int32_t clx, crx, cty, cby; +float px, py; +int dispx, dispy, text_y_center, swapxy; +uint32_t calx, caly, cals; +char buf[13]; + +void setup() +{ + Serial.begin(9600); + Serial.println("UTouch_Calibr_kbv"); + digitalWrite(A0, HIGH); + pinMode(A0, OUTPUT); + myGLCD.InitLCD(TOUCH_ORIENTATION); + myGLCD.clrScr(); + myGLCD.setFont(SmallFont); +#if (USE_UTOUCH) + myTouch.InitTouch(TOUCH_ORIENTATION); +#endif + dispx = myGLCD.getDisplayXSize(); + dispy = myGLCD.getDisplayYSize(); + text_y_center = (dispy / 2) - 6; +} + +void drawCrossHair(int x, int y) +{ + myGLCD.drawRect(x - 10, y - 10, x + 10, y + 10); + myGLCD.drawLine(x - 5, y, x + 5, y); + myGLCD.drawLine(x, y - 5, x, y + 5); +} + +void readCoordinates() +{ + int iter = 5000; + int failcount = 0; + int cnt = 0; + uint32_t tx = 0; + uint32_t ty = 0; + boolean OK = false; + + while (OK == false) + { + myGLCD.setColor(255, 255, 255); + myGLCD.print("* PRESS *", CENTER, text_y_center); + while (ISPRESSED() == false) {} + myGLCD.print("* HOLD! *", CENTER, text_y_center); +#if (USE_UTOUCH) + while ((ISPRESSED() == true) && (cnt < iter) && (failcount < 10000)) + { + myTouch.calibrateRead(); + if (!((myTouch.TP_X == 65535) || (myTouch.TP_Y == 65535))) + { + tx += myTouch.TP_X; + ty += myTouch.TP_Y; + cnt++; + } + else + failcount++; + } +#else + cnt = 0; + iter = 400; + do + { + readResistiveTouch(); + // showpoint(tp); + if (tp.z > 20 && tp.z < 1000) + { + tx += tp.x; + ty += tp.y; + cnt++; + } + else + failcount++; + } while ((cnt < iter) && (failcount < 10000)); +#endif + if (cnt >= iter) + { + OK = true; + } + else + { + tx = 0; + ty = 0; + cnt = 0; + } + if (failcount >= 10000) + fail(); + } + + cx = tx / iter; + cy = ty / iter; +} + +void calibrate(int x, int y, int i) +{ + myGLCD.setColor(255, 255, 255); + drawCrossHair(x, y); + myGLCD.setBackColor(255, 0, 0); + readCoordinates(); + myGLCD.setColor(255, 255, 255); + myGLCD.print("* RELEASE *", CENTER, text_y_center); + myGLCD.setColor(80, 80, 80); + drawCrossHair(x, y); + rx[i] = cx; + ry[i] = cy; + Serial.print("\r\ncx="); Serial.print(cx); + Serial.print(" cy="); Serial.print(cy); + while (ISPRESSED() == true) {} +} + +void waitForTouch() +{ + while (ISPRESSED() == true) {} + while (ISPRESSED() == false) {} + while (ISPRESSED() == true) {} +} + +void toHex(uint32_t num) +{ + buf[0] = '0'; + buf[1] = 'x'; + buf[10] = 'U'; + buf[11] = 'L'; + buf[12] = 0; + for (int zz = 9; zz > 1; zz--) + { + if ((num & 0xF) > 9) + buf[zz] = (num & 0xF) + 55; + else + buf[zz] = (num & 0xF) + 48; + num = num >> 4; + } +} + +void startup() +{ + myGLCD.setColor(255, 0, 0); + myGLCD.fillRect(0, 0, dispx - 1, 13); + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.drawLine(0, 14, dispx - 1, 14); + myGLCD.print(TITLE, CENTER, 1); + myGLCD.setBackColor(0, 0, 0); + + myGLCD.print("Use a stylus or something", LEFT, 30); + myGLCD.print("similar to touch as close", LEFT, 42); + myGLCD.print("to the center of the", LEFT, 54); + myGLCD.print("highlighted crosshair as", LEFT, 66); + myGLCD.print("possible. Keep as still as", LEFT, 78); + myGLCD.print("possible and keep holding", LEFT, 90); + myGLCD.print("until the highlight is", LEFT, 102); + myGLCD.print("removed. Repeat for all", LEFT, 114); + myGLCD.print("crosshairs in sequence.", LEFT, 126); + myGLCD.print("Touch screen to continue", CENTER, 162); + + waitForTouch(); + myGLCD.clrScr(); +} + +void showNumI(char *msg, uint32_t val, int x, int y) +{ + myGLCD.print(msg, x, y); + myGLCD.printNumI(val, x + 50, y); +} + +void done() +{ + myGLCD.clrScr(); + myGLCD.setColor(255, 0, 0); + myGLCD.fillRect(0, 0, dispx - 1, 13); + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.drawLine(0, 14, dispx - 1, 14); + myGLCD.print(TITLE, CENTER, 1); + myGLCD.setBackColor(0, 0, 0); +#if (USE_UTOUCH) + myGLCD.print("To use the new calibration", LEFT, 30); + myGLCD.print("settings you must edit the", LEFT, 42); + myGLCD.setColor(160, 160, 255); + myGLCD.print("UTouchCD.h", LEFT, 54); + myGLCD.setColor(255, 255, 255); + myGLCD.print("file and change", 88, 54); + myGLCD.print("the following values. The", LEFT, 66); + myGLCD.print("values are located right", LEFT, 78); + myGLCD.print("below the opening comment.", LEFT, 90); + myGLCD.print("CAL_X", LEFT, 110); + myGLCD.print("CAL_Y", LEFT, 122); + myGLCD.print("CAL_S", LEFT, 134); + toHex(calx); + myGLCD.print(buf, 75, 110); + toHex(caly); + myGLCD.print(buf, 75, 122); + toHex(cals); + myGLCD.print(buf, 75, 134); +#else + myGLCD.print("To use the new calibration", LEFT, 30); + myGLCD.print("settings you must map the values", LEFT, 42); + myGLCD.print("from Point p = ts.getPoint() e.g. ", LEFT, 54); + myGLCD.print("x = map(p.x, LEFT, RT, 0, tft.width());", LEFT, 66); + myGLCD.print("y = map(p.y, TOP, BOT, 0, tft.height());", LEFT, 78); + myGLCD.print("swap p.x and p.y if diff ORIENTATION", LEFT, 90); +#endif + //.kbv show human values + showNumI("LEFT ", (calx >> 14) & 0x3FFF, 0, 186); + showNumI("RT ", (calx) & 0x3FFF, 100, 186); + myGLCD.printNumF(px, 2, 200, 186); + showNumI("TOP ", (caly >> 14) & 0x3FFF, 0, 198); + showNumI("BOT ", (caly) & 0x3FFF, 100, 198); + myGLCD.printNumF(py, 2, 200, 198); + showNumI("WID ", (cals >> 12) & 0xFFF, 0, 210); + showNumI("HT ", (cals) & 0xFFF, 100, 210); + myGLCD.print("Touch Controller is ", 0, 222); + myGLCD.print((cals >> 31) ? "LANDSCAPE" : "PORTRAIT", 170, 222); + +} + +void fail() +{ + myGLCD.clrScr(); + myGLCD.setColor(255, 0, 0); + myGLCD.fillRect(0, 0, dispx - 1, 13); + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.drawLine(0, 14, dispx - 1, 14); + myGLCD.print("Touch Calibration FAILED", CENTER, 1); + myGLCD.setBackColor(0, 0, 0); + + myGLCD.print("Unable to read the position", LEFT, 30); + myGLCD.print("of the press. This is a", LEFT, 42); + myGLCD.print("hardware issue and can", 88, 54); + myGLCD.print("not be corrected in", LEFT, 66); + myGLCD.print("software.", LEFT, 78); + + while (true) {}; +} + +void loop() +{ + startup(); + + myGLCD.setColor(80, 80, 80); + drawCrossHair(dispx - 11, 10); + drawCrossHair(dispx / 2, 10); + drawCrossHair(10, 10); + drawCrossHair(dispx - 11, dispy / 2); + drawCrossHair(10, dispy / 2); + drawCrossHair(dispx - 11, dispy - 11); + drawCrossHair(dispx / 2, dispy - 11); + drawCrossHair(10, dispy - 11); + myGLCD.setColor(255, 255, 255); + myGLCD.setBackColor(255, 0, 0); + myGLCD.print("***********", CENTER, text_y_center - 12); + myGLCD.print("***********", CENTER, text_y_center + 12); + + calibrate(10, 10, 0); + calibrate(10, dispy / 2, 1); + calibrate(10, dispy - 11, 2); + calibrate(dispx / 2, 10, 3); + calibrate(dispx / 2, dispy - 11, 4); + calibrate(dispx - 11, 10, 5); + calibrate(dispx - 11, dispy / 2, 6); + calibrate(dispx - 11, dispy - 11, 7); + + cals = (long(dispx - 1) << 12) + (dispy - 1); + if (TOUCH_ORIENTATION == PORTRAIT) swapxy = rx[2] - rx[0]; + else swapxy = ry[2] - ry[0]; + swapxy = (swapxy < -500 || swapxy > 500); + if ((TOUCH_ORIENTATION == PORTRAIT) ^ (swapxy != 0)) { + clx = (rx[0] + rx[1] + rx[2]) / 3; + crx = (rx[5] + rx[6] + rx[7]) / 3; + cty = (ry[0] + ry[3] + ry[5]) / 3; + cby = (ry[2] + ry[4] + ry[7]) / 3; + } else { + clx = (ry[0] + ry[1] + ry[2]) / 3; + crx = (ry[5] + ry[6] + ry[7]) / 3; + cty = (rx[0] + rx[3] + rx[5]) / 3; + cby = (rx[2] + rx[4] + rx[7]) / 3; + } + px = float(crx - clx) / (dispx - 20); + py = float(cby - cty) / (dispy - 20); + // px = 0; + clx -= px * 10; + crx += px * 10; + cty -= py * 10; + cby += py * 10; + + calx = (long(clx) << 14) + long(crx); + caly = (long(cty) << 14) + long(cby); + if (swapxy) + cals |= (1L << 31); + + done(); + while (true) {} +} diff --git a/examples/aspect_kbv/aspect_kbv.ino b/examples/aspect_kbv/aspect_kbv.ino new file mode 100644 index 0000000..1de1ae3 --- /dev/null +++ b/examples/aspect_kbv/aspect_kbv.ino @@ -0,0 +1,40 @@ +#include // Hardware-specific library +#include +MCUFRIEND_kbv tft; + +void setup() +{ + // put your setup code here, to run once: + Serial.begin(9600); + tft.reset(); + uint16_t identifier = tft.readID(); + Serial.print("ID = 0x"); + Serial.println(identifier, HEX); + if (identifier == 0xEFEF) identifier = 0x9486; + tft.begin(identifier); + // tft.fillScreen(BLACK); +} + +char *msg[] = { "PORTRAIT", "LANDSCAPE", "PORTRAIT_REV", "LANDSCAPE_REV" }; +uint8_t aspect; + +void loop() +{ + // put your main code here, to run repeatedly: + uint16_t x = 50, y = 100; + tft.setRotation(aspect); + tft.fillScreen(0x0000); + tft.setCursor(0, 0); + tft.setTextSize(2); + tft.println(msg[aspect]); + tft.setCursor(x, y); + tft.println("[x=" + String(x) + ",y=" + String(y) + "]"); + delay(5000); + tft.println("INVERT ON"); + tft.invertDisplay(true); + delay(1000); + tft.invertDisplay(false); + tft.println("INVERT OFF"); + delay(1000); + if (++aspect >= 4) aspect = 0; +} diff --git a/examples/graphictest_kbv/graphictest_kbv.ino b/examples/graphictest_kbv/graphictest_kbv.ino new file mode 100644 index 0000000..f55f25e --- /dev/null +++ b/examples/graphictest_kbv/graphictest_kbv.ino @@ -0,0 +1,569 @@ +// All the mcufriend.com UNO shields have the same pinout. +// i.e. control pins A0-A4. Data D2-D9. microSD D10-D13. +// Touchscreens are normally A1, A2, D7, D6 but the order varies +// +// This demo should work with most Adafruit TFT libraries +// If you are not using a shield, use a full Adafruit constructor() +// e.g. Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); + +#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 + +#include // f.k. for Arduino-1.5.2 +#include "Adafruit_GFX.h"// Hardware-specific library +#include +MCUFRIEND_kbv tft; +//#include +//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 + +#ifndef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +void setup(void); +void loop(void); +unsigned long testFillScreen(); +unsigned long testText(); +unsigned long testLines(uint16_t color); +unsigned long testFastLines(uint16_t color1, uint16_t color2); +unsigned long testRects(uint16_t color); +unsigned long testFilledRects(uint16_t color1, uint16_t color2); +unsigned long testFilledCircles(uint8_t radius, uint16_t color); +unsigned long testCircles(uint8_t radius, uint16_t color); +unsigned long testTriangles(); +unsigned long testFilledTriangles(); +unsigned long testRoundRects(); +unsigned long testFilledRoundRects(); +void progmemPrint(const char *str); +void progmemPrintln(const char *str); + +void runtests(void); + +uint16_t g_identifier; + +extern const uint8_t hanzi[]; +void showhanzi(unsigned int x, unsigned int y, unsigned char index) +{ + uint8_t i, j, c, first = 1; + uint8_t *temp = (uint8_t*)hanzi; + uint16_t color; + tft.setAddrWindow(x, y, x + 31, y + 31); //设置区域 + temp += index * 128; + for (j = 0; j < 128; j++) + { + c = pgm_read_byte(temp); + for (i = 0; i < 8; i++) + { + if ((c & (1 << i)) != 0) + { + color = RED; + } + else + { + color = BLACK; + } + tft.pushColors(&color, 1, first); + first = 0; + } + temp++; + } +} + +void setup(void) { + Serial.begin(9600); + uint32_t when = millis(); + // while (!Serial) ; //hangs a Leonardo until you connect a Serial + if (!Serial) delay(5000); //allow some time for Leonardo + Serial.println("Serial took " + String((millis() - when)) + "ms to start"); + static uint16_t identifier; + // tft.reset(); //we can't read ID on 9341 until begin() + g_identifier = tft.readID(); // + Serial.print("ID = 0x"); + Serial.println(g_identifier, HEX); + if (g_identifier == 0x00D3 || g_identifier == 0xD3D3) g_identifier = 0x9595; // write-only shield + if (g_identifier == 0xFFFF) g_identifier = 0x9341; // serial +// g_identifier = 0x9329; // force ID + tft.begin(g_identifier); +} + +#if defined(MCUFRIEND_KBV_H_) +uint16_t scrollbuf[320]; // my biggest screen is 320x480 +#define READGRAM(x, y, buf, w, h) tft.readGRAM(x, y, buf, w, h) +#else +uint16_t scrollbuf[320]; // Adafruit only does 240x320 +// Adafruit can read a block by one pixel at a time +int16_t READGRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h) +{ + uint16_t *p; + for (int row = 0; row < h; row++) { + p = block + row * w; + for (int col = 0; col < w; col++) { + *p++ = tft.readPixel(x + col, y + row); + } + } +} +#endif + +void windowScroll(int16_t x, int16_t y, int16_t wid, int16_t ht, int16_t dx, int16_t dy, uint16_t *buf) +{ + if (dx) for (int16_t row = 0; row < ht; row++) { + READGRAM(x, y + row, buf, wid, 1); + tft.setAddrWindow(x, y + row, x + wid - 1, y + row); + tft.pushColors(buf + dx, wid - dx, 1); + tft.pushColors(buf + 0, dx, 0); + } + if (dy) for (int16_t col = 0; col < wid; col++) { + READGRAM(x + col, y, buf, 1, ht); + tft.setAddrWindow(x + col, y, x + col, y + ht - 1); + tft.pushColors(buf + dy, ht - dy, 1); + tft.pushColors(buf + 0, dy, 0); + } +} + +void loop(void) { + uint8_t aspect; + uint16_t pixel; + char *aspectname[] = { + "PORTRAIT", "LANDSCAPE", "PORTRAIT_REV", "LANDSCAPE_REV" + }; + char *colorname[] = { "BLUE", "GREEN", "RED", "GRAY" }; + uint16_t colormask[] = { 0x001F, 0x07E0, 0xF800, 0xFFFF }; + uint16_t dx, rgb, n, wid, ht; + tft.setRotation(0); +// for (uint8_t i = 0; i < 2; i++) showhanzi(0, 0, i), delay(1000); + runtests(); + delay(2000); + if (tft.height() > 64) { + for (uint8_t cnt = 0; cnt < 4; cnt++) { + aspect = (cnt + 0) & 3; + tft.setRotation(aspect); + wid = tft.width(); + ht = tft.height(); + testText(); + dx = wid / 32; + for (n = 0; n < 32; n++) { + rgb = n * 8; + rgb = tft.color565(rgb, rgb, rgb); + tft.fillRect(n * dx, 48, dx, 64, rgb & colormask[aspect]); + } + tft.setTextSize(2); + tft.setTextColor(colormask[aspect], BLACK); + tft.setCursor(0, 72); + tft.print(colorname[aspect]); + tft.setTextColor(WHITE); + tft.println(" COLOR GRADES"); + tft.setTextColor(WHITE, BLACK); + tft.setCursor(0, 184); + tft.println(aspectname[aspect]); + delay(1000); + tft.drawPixel(0, 0, YELLOW); + pixel = tft.readPixel(0, 0); +#if defined(MCUFRIEND_KBV_H_) + extern const uint8_t penguin[]; + tft.setAddrWindow(wid - 40 - 40, 20 + 0, wid - 1 - 40, 20 + 39); + tft.pushColors(penguin, 1600, 1); + tft.setTextColor(WHITE, BLACK); + tft.println("VERTICAL SCROLL UP"); + uint16_t maxscroll; + if (tft.getRotation() & 1) maxscroll = wid; + else maxscroll = ht; + for (uint16_t i = 1; i <= maxscroll; i++) { + tft.vertScroll(0, maxscroll, i); + delay(10); + } + tft.vertScroll(0, maxscroll, 0); + tft.setCursor(0, 200); + tft.println("VERTICAL SCROLL DN"); + for (uint16_t i = 1; i <= maxscroll; i++) { + tft.vertScroll(0, maxscroll, 0 - (int16_t)i); + delay(10); + } + delay(1000); + tft.vertScroll(0, maxscroll, 0); + if ((aspect & 1) == 0) { //Portrait + tft.setCursor(0, 200); + tft.setTextColor(BLUE, BLACK); + tft.println("ONLY THE COLOR BAND"); + for (uint16_t i = 1; i <= 64; i++) { + tft.vertScroll(48, 64, i); + delay(20); + } + delay(1000); + tft.vertScroll(0, maxscroll, 0); + } +#endif + tft.setCursor(0, 200); + tft.setTextColor(YELLOW, BLACK); + if (pixel == YELLOW) { + tft.println("SOFTWARE SCROLL "); +#if 0 + for (int16_t i = 45, dx = 2, dy = 1; i > 0; i -= dx) { + windowScroll(24, 8, 90, 40, dx, dy, scrollbuf); + } +#else + // scroll a whole width of the screen + n = (wid > 320) ? 320 : wid; + for (int16_t i = n, dx = 4, dy = 0; i > 0; i -= dx) { + windowScroll(0, 200, n, 16, dx, dy, scrollbuf); + } +#endif + } + else if (pixel == CYAN) + tft.println("readPixel() reads as BGR"); + else if ((pixel & 0xF8F8) == 0xF8F8) + tft.println("readPixel() should be 24-bit"); + else { + tft.print("readPixel() reads 0x"); + tft.println(pixel, HEX); + } + delay(5000); + } + } + tft.println("INVERT DISPLAY"); + tft.invertDisplay(true); + delay(2000); + tft.invertDisplay(false); +} + +typedef struct { + PGM_P msg; + uint32_t ms; +} TEST; +TEST result[12]; + +#define RUNTEST(n, str, test) { result[n].msg = PSTR(str); result[n].ms = test; delay(500); } + +void runtests(void) +{ + uint8_t i, len = 24, cnt; + uint32_t total; + RUNTEST(0, "FillScreen ", testFillScreen()); + RUNTEST(1, "Text ", testText()); + RUNTEST(2, "Lines ", testLines(CYAN)); + RUNTEST(3, "Horiz/Vert Lines ", testFastLines(RED, BLUE)); + RUNTEST(4, "Rectangles (outline) ", testRects(GREEN)); + RUNTEST(5, "Rectangles (filled) ", testFilledRects(YELLOW, MAGENTA)); + RUNTEST(6, "Circles (filled) ", testFilledCircles(10, MAGENTA)); + RUNTEST(7, "Circles (outline) ", testCircles(10, WHITE)); + RUNTEST(8, "Triangles (outline) ", testTriangles()); + RUNTEST(9, "Triangles (filled) ", testFilledTriangles()); + RUNTEST(10, "Rounded rects (outline) ", testRoundRects()); + RUNTEST(11, "Rounded rects (filled) ", testFilledRoundRects()); + + tft.fillScreen(BLACK); + tft.setTextColor(GREEN); + tft.setCursor(0, 0); + uint16_t wid = tft.width(); + if (wid > 176) { + tft.setTextSize(2); +#if defined(MCUFRIEND_KBV_H_) + tft.print("MCUFRIEND "); +#if MCUFRIEND_KBV_H_ != 0 + tft.print(0.01 * MCUFRIEND_KBV_H_, 1); +#else + tft.print("for"); +#endif + tft.println(" UNO"); +#else + tft.println("Adafruit-Style Tests"); +#endif + } else len = wid / 6 - 8; + tft.setTextSize(1); + total = 0; + for (i = 0; i < 12; i++) { + PGM_P str = result[i].msg; + char c; + if (len > 24) { + if (i < 10) tft.print(" "); + tft.print(i); + tft.print(": "); + } + uint8_t cnt = len; + while ((c = pgm_read_byte(str++)) && cnt--) tft.print(c); + tft.print(" "); + tft.println(result[i].ms); + total += result[i].ms; + } + tft.setTextSize(2); + tft.print("Total:"); + tft.print(0.000001 * total); + tft.println("sec"); + g_identifier = tft.readID(); + tft.print("ID: 0x"); + tft.println(tft.readID(), HEX); + tft.print("Reg(00):0x"); + tft.println(tft.readReg(0x00), HEX); + tft.print("F_CPU:"); + tft.print(0.000001 * F_CPU); +#if defined(__OPTIMIZE_SIZE__) + tft.println("MHz -Os"); +#else + tft.println("MHz"); +#endif + + delay(10000); +} + +// Standard Adafruit tests. will adjust to screen size + +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() { + unsigned long start; + tft.fillScreen(BLACK); + start = micros(); + tft.setCursor(0, 0); + tft.setTextColor(WHITE); tft.setTextSize(1); + tft.println("Hello World!"); + tft.setTextColor(YELLOW); tft.setTextSize(2); + tft.println(123.45); + 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, red, step, + cx = tft.width() / 2 - 1, + cy = tft.height() / 2 - 1; + + tft.fillScreen(BLACK); + w = min(tft.width(), tft.height()); + start = micros(); + red = 0; + step = (256 * 6) / w; + for (i = 0; i < w; i += 6) { + i2 = i / 2; + red += step; + tft.drawRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(red, 0, 0)); + } + + return micros() - start; +} + +unsigned long testFilledRoundRects() { + unsigned long start; + int i, i2, green, step, + cx = tft.width() / 2 - 1, + cy = tft.height() / 2 - 1; + + tft.fillScreen(BLACK); + start = micros(); + green = 256; + step = (256 * 6) / min(tft.width(), tft.height()); + for (i = min(tft.width(), tft.height()); i > 20; i -= 6) { + i2 = i / 2; + green -= step; + tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(0, green, 0)); + } + + return micros() - start; +} + diff --git a/examples/graphictest_kbv/icons.c b/examples/graphictest_kbv/icons.c new file mode 100644 index 0000000..97edda8 --- /dev/null +++ b/examples/graphictest_kbv/icons.c @@ -0,0 +1,408 @@ +#include + +const unsigned char PROGMEM penguin[3200] = { /* 0X00,0X10,0X28,0X00,0X28,0X00,0X01,0X1B, */ + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, + 0XBA, 0XD6, 0XB6, 0XB5, 0XF3, 0X9C, 0XB2, 0X94, 0XB3, 0X9C, 0XB2, 0X94, 0X34, 0XA5, 0XF7, 0XBD, + 0XFB, 0XDE, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XFB, 0XDE, 0XF3, 0X9C, 0XCB, 0X5A, + 0XC7, 0X39, 0X04, 0X21, 0X82, 0X10, 0X42, 0X10, 0X42, 0X10, 0X41, 0X08, 0X83, 0X18, 0X45, 0X29, + 0XC7, 0X39, 0X0C, 0X63, 0X75, 0XAD, 0X3C, 0XE7, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XE7, 0XB2, 0X94, 0X08, 0X42, 0XC3, 0X18, 0X82, 0X10, + 0X04, 0X21, 0X45, 0X29, 0X86, 0X31, 0X86, 0X31, 0X86, 0X31, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, + 0X82, 0X10, 0X41, 0X08, 0XC3, 0X18, 0X08, 0X42, 0XF3, 0X9C, 0X3C, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFB, 0XDE, 0X0C, 0X63, 0XC3, 0X18, 0XC3, 0X18, 0X45, 0X29, 0XC7, 0X39, + 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0XC7, 0X39, 0XC7, 0X39, + 0X86, 0X31, 0X86, 0X31, 0X04, 0X21, 0X41, 0X08, 0X82, 0X10, 0XCB, 0X5A, 0XBA, 0XD6, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFB, 0XDE, 0XCB, 0X5A, 0X82, 0X10, 0X45, 0X29, 0XC7, 0X39, 0X08, 0X42, 0X08, 0X42, + 0X09, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X08, 0X42, 0XC7, 0X39, + 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X83, 0X18, 0X00, 0X00, 0XC8, 0X41, 0X38, 0XC6, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0X7D, 0XEF, 0X8E, 0X73, 0X82, 0X10, 0X45, 0X29, 0XC7, 0X39, 0X08, 0X42, 0X09, 0X4A, 0X8A, 0X52, + 0X30, 0X84, 0XCF, 0X7B, 0X8A, 0X52, 0X49, 0X4A, 0X4A, 0X52, 0X49, 0X4A, 0XCB, 0X5A, 0XCF, 0X7B, + 0X0C, 0X63, 0X08, 0X42, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0XC3, 0X18, 0X00, 0X00, 0X49, 0X4A, + 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XF3, 0X9C, 0XC3, 0X18, 0X04, 0X21, 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X72, 0X94, + 0X7D, 0XEF, 0X7D, 0XEF, 0XB2, 0X94, 0X4A, 0X52, 0X49, 0X4A, 0X8A, 0X52, 0X75, 0XAD, 0XBE, 0XF7, + 0XBA, 0XD6, 0X4D, 0X6B, 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0XC3, 0X18, 0X41, 0X08, + 0XCF, 0X7B, 0X7C, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBA, 0XD6, + 0X08, 0X42, 0X82, 0X10, 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X8E, 0X73, 0XFB, 0XDE, + 0XFF, 0XFF, 0XBE, 0XF7, 0XBA, 0XD6, 0X8E, 0X73, 0X08, 0X42, 0X30, 0X84, 0X3C, 0XE7, 0X7D, 0XEF, + 0XFF, 0XFF, 0XB6, 0XB5, 0X49, 0X4A, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, 0X41, 0X08, + 0X45, 0X29, 0XB6, 0XB5, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0X71, 0X8C, + 0X41, 0X08, 0X45, 0X29, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X4A, 0X52, 0XB2, 0X94, 0XBE, 0XF7, + 0XBE, 0XF7, 0XB2, 0X94, 0XCF, 0X7B, 0XCF, 0X7B, 0X49, 0X4A, 0XB6, 0XB5, 0XF3, 0X9C, 0X0C, 0X63, + 0X38, 0XC6, 0XBA, 0XD6, 0X0C, 0X63, 0X87, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0XC3, 0X18, + 0X41, 0X08, 0X30, 0X84, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XE7, 0XCB, 0X5A, + 0X41, 0X08, 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X4A, 0X52, 0X8A, 0X52, 0XF3, 0X9C, 0XFF, 0XFF, + 0X7D, 0XEF, 0XC7, 0X39, 0XC3, 0X18, 0X0C, 0X63, 0XCB, 0X5A, 0XB6, 0XB5, 0XB2, 0X94, 0XCB, 0X5A, + 0X75, 0XAD, 0XFA, 0XD6, 0X4D, 0X6B, 0X87, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, + 0X41, 0X08, 0X8A, 0X52, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X38, 0XC6, 0X86, 0X31, + 0X04, 0X21, 0XC8, 0X41, 0X49, 0X4A, 0X49, 0X4A, 0X4A, 0X52, 0X49, 0X4A, 0XB1, 0X8C, 0XBE, 0XF7, + 0XBE, 0XF7, 0XB2, 0X94, 0XCF, 0X7B, 0XCF, 0X7B, 0X49, 0X4A, 0X74, 0XA5, 0X7D, 0XEF, 0X7C, 0XE7, + 0XBE, 0XF7, 0X79, 0XCE, 0X0C, 0X63, 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, + 0X82, 0X10, 0X45, 0X29, 0X75, 0XAD, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X34, 0XA5, 0X82, 0X10, + 0X86, 0X31, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X8A, 0X52, 0X49, 0X4A, 0X4D, 0X6B, 0XBA, 0XD6, + 0XFF, 0XFF, 0XFF, 0XFF, 0X79, 0XCE, 0X0D, 0X63, 0XC7, 0X39, 0XCF, 0X7B, 0X7D, 0XEF, 0XFF, 0XFF, + 0XFF, 0XFF, 0X75, 0XAD, 0X08, 0X42, 0X86, 0X31, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X45, 0X29, + 0XC3, 0X18, 0XC3, 0X18, 0XB2, 0X94, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XB2, 0X8C, 0X41, 0X08, + 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X8A, 0X52, 0X8A, 0X52, 0X4A, 0X4A, 0XD0, 0X7B, + 0X7A, 0XC6, 0X7B, 0XBE, 0X90, 0X6B, 0XC9, 0X39, 0X88, 0X31, 0XC9, 0X39, 0XB3, 0X84, 0XBB, 0XC6, + 0XF8, 0XB5, 0XCC, 0X5A, 0X86, 0X31, 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X45, 0X29, + 0XC4, 0X20, 0X41, 0X08, 0X30, 0X84, 0X3C, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XE7, 0X8A, 0X4A, 0XC3, 0X10, + 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X4A, 0X4A, 0X4A, 0X42, 0X09, 0X3A, 0X08, 0X4A, + 0X09, 0X6B, 0X49, 0X7B, 0XC6, 0X7A, 0X05, 0X83, 0X46, 0X83, 0XC5, 0X7A, 0XC6, 0X72, 0X09, 0X7B, + 0X48, 0X5A, 0X87, 0X31, 0X88, 0X21, 0X88, 0X29, 0X86, 0X31, 0X86, 0X31, 0X45, 0X29, 0X45, 0X29, + 0X04, 0X21, 0X41, 0X08, 0X4A, 0X4A, 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XF7, 0XC5, 0X82, 0X50, 0X05, 0X41, + 0XC7, 0X29, 0X08, 0X42, 0X49, 0X4A, 0X4A, 0X42, 0X49, 0X4A, 0X09, 0X7B, 0X88, 0X9B, 0XC6, 0XB3, + 0X21, 0XD4, 0XA0, 0XDC, 0XE1, 0XE4, 0X61, 0XED, 0X61, 0XED, 0X21, 0XED, 0XA0, 0XE4, 0X20, 0XDC, + 0X80, 0XCB, 0X43, 0XAB, 0XC4, 0X82, 0X06, 0X5A, 0X47, 0X21, 0X46, 0X29, 0X45, 0X29, 0X04, 0X29, + 0X04, 0X19, 0X82, 0X10, 0X82, 0X18, 0XF3, 0X9C, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0X4D, 0X93, 0X00, 0XA0, 0X82, 0XB8, + 0XC7, 0X31, 0X09, 0X32, 0X49, 0X4A, 0X86, 0X7A, 0X43, 0XC3, 0X6B, 0XED, 0XF4, 0XF6, 0XEB, 0XFD, + 0X20, 0XFD, 0X20, 0XFD, 0X60, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X20, 0XFD, + 0XE0, 0XFC, 0XA0, 0XFC, 0X60, 0XF4, 0XC1, 0XDB, 0X83, 0X9A, 0XC5, 0X49, 0X45, 0X29, 0X04, 0X19, + 0XC4, 0X20, 0X82, 0X38, 0X00, 0X50, 0XCB, 0X6A, 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFB, 0XEE, 0X04, 0XA1, 0X00, 0XC0, 0X00, 0XF0, + 0XC3, 0XA0, 0XC8, 0X41, 0X49, 0X42, 0X05, 0X9B, 0X20, 0XFC, 0XA4, 0XFC, 0X69, 0XFD, 0XE8, 0XFD, + 0X63, 0XFD, 0X20, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0XE0, 0XFC, + 0XE0, 0XFC, 0XA0, 0XFC, 0X60, 0XFC, 0X20, 0XFC, 0X41, 0XD3, 0XC5, 0X49, 0X45, 0X19, 0XC4, 0X38, + 0X82, 0X68, 0X41, 0X88, 0X00, 0X70, 0X49, 0X5A, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFB, 0XF6, 0X82, 0XC0, 0X00, 0XD0, 0X86, 0XC1, + 0X46, 0XF1, 0X41, 0XC8, 0X45, 0X79, 0X89, 0X52, 0X88, 0X62, 0X86, 0X6A, 0XC6, 0X7A, 0XC4, 0XBB, + 0XE1, 0XFC, 0X60, 0XFD, 0X60, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0XE0, 0XFC, + 0X60, 0XE4, 0X03, 0X93, 0X84, 0X72, 0X44, 0X6A, 0XC5, 0X41, 0X45, 0X29, 0XC3, 0X58, 0X41, 0XA8, + 0X40, 0X98, 0X00, 0XB0, 0X00, 0X60, 0X0C, 0X6B, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0XCE, 0X83, 0X82, 0X88, 0X00, 0XF8, 0XC4, 0XD8, + 0X0C, 0XF3, 0X8A, 0XFA, 0X82, 0XE8, 0X82, 0XB0, 0X45, 0X69, 0XC7, 0X51, 0X08, 0X42, 0X08, 0X3A, + 0X86, 0X5A, 0X83, 0X9B, 0XA2, 0XBC, 0X22, 0XCD, 0X21, 0XCD, 0XA1, 0XC4, 0X22, 0XB4, 0XC4, 0X7A, + 0X06, 0X3A, 0X86, 0X29, 0X45, 0X29, 0X05, 0X31, 0XC4, 0X50, 0X41, 0X90, 0X00, 0XC0, 0X00, 0XA8, + 0X00, 0XA0, 0X00, 0XA8, 0X00, 0X30, 0X4A, 0X4A, 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0X8E, 0X73, 0XC3, 0X18, 0X05, 0X39, 0X82, 0XA8, 0X00, 0XF8, + 0XC3, 0XF8, 0X4D, 0XFB, 0X4D, 0XFB, 0XC7, 0XF9, 0XC3, 0XF0, 0X82, 0XD8, 0XC3, 0XB0, 0X04, 0X81, + 0X45, 0X61, 0X46, 0X51, 0X86, 0X49, 0X86, 0X49, 0X46, 0X41, 0X45, 0X41, 0X45, 0X41, 0X45, 0X41, + 0X05, 0X49, 0X04, 0X61, 0X82, 0X90, 0X41, 0XB0, 0X00, 0XD0, 0X00, 0XC8, 0X00, 0XA8, 0X00, 0XA8, + 0X00, 0XB8, 0X41, 0X58, 0X82, 0X10, 0X82, 0X10, 0XB2, 0X94, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XBE, 0XF7, 0XCF, 0X7B, 0X82, 0X10, 0X04, 0X21, 0X86, 0X29, 0X86, 0X41, 0X04, 0X99, + 0X40, 0XE8, 0X41, 0XF8, 0X86, 0XF9, 0XCB, 0XFA, 0X49, 0XFA, 0X82, 0XF8, 0X00, 0XF8, 0X00, 0XF0, + 0X00, 0XE8, 0X41, 0XD8, 0X41, 0XD0, 0X41, 0XC0, 0X41, 0XC0, 0X41, 0XC0, 0X41, 0XC0, 0X41, 0XC8, + 0X00, 0XD0, 0X00, 0XE0, 0X00, 0XE0, 0X00, 0XD8, 0X00, 0XD0, 0X00, 0XB8, 0X00, 0XA8, 0X41, 0X88, + 0X82, 0X48, 0X82, 0X10, 0X82, 0X10, 0X00, 0X00, 0X45, 0X29, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, + 0XBE, 0XF7, 0XF3, 0X9C, 0X82, 0X10, 0XC3, 0X18, 0X45, 0X29, 0X86, 0X31, 0XC7, 0X31, 0X30, 0X7C, + 0XF3, 0XDC, 0X86, 0XE1, 0X00, 0XF0, 0X00, 0XF8, 0X41, 0XF8, 0X41, 0XF8, 0X00, 0XF8, 0X00, 0XF8, + 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, + 0X00, 0XE8, 0X00, 0XE0, 0X00, 0XE0, 0X00, 0XD8, 0X00, 0XC8, 0X41, 0XA0, 0X8A, 0X9A, 0X0C, 0X63, + 0X04, 0X11, 0X82, 0X10, 0X82, 0X10, 0X41, 0X08, 0X00, 0X00, 0X4D, 0X6B, 0X7D, 0XEF, 0XFF, 0XFF, + 0XFB, 0XDE, 0X08, 0X42, 0X42, 0X10, 0X45, 0X29, 0X86, 0X31, 0X86, 0X31, 0X49, 0X4A, 0X38, 0XBE, + 0XFF, 0XFF, 0X38, 0XD6, 0X86, 0XA9, 0X00, 0XC8, 0X00, 0XE0, 0X00, 0XF0, 0X00, 0XF8, 0X00, 0XF8, + 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF0, 0X00, 0XF0, + 0X00, 0XE8, 0X00, 0XE0, 0X00, 0XD0, 0XC3, 0X98, 0X8A, 0X8A, 0XB2, 0XA4, 0XBA, 0XC6, 0XF7, 0XB5, + 0X08, 0X42, 0X41, 0X08, 0X82, 0X10, 0X41, 0X08, 0X00, 0X00, 0X45, 0X29, 0XF7, 0XBD, 0XFF, 0XFF, + 0X71, 0X8C, 0X41, 0X08, 0X04, 0X21, 0X45, 0X29, 0X86, 0X31, 0X86, 0X31, 0X0C, 0X63, 0X3C, 0XE7, + 0XFF, 0XFF, 0X79, 0XD6, 0X46, 0XB9, 0X00, 0XE0, 0X42, 0XC8, 0X82, 0XA8, 0X82, 0XB0, 0X41, 0XD8, + 0X82, 0XE8, 0X82, 0XF0, 0X41, 0XE8, 0X41, 0XE8, 0X41, 0XE8, 0X41, 0XF0, 0X41, 0XE8, 0X41, 0XD8, + 0X04, 0XC1, 0X08, 0X92, 0X4D, 0X8B, 0X34, 0XA5, 0XFB, 0XC6, 0XFB, 0XD6, 0XBA, 0XCE, 0X3C, 0XE7, + 0X30, 0X84, 0XC3, 0X18, 0X41, 0X08, 0X41, 0X08, 0X00, 0X00, 0X41, 0X08, 0XCF, 0X7B, 0X7D, 0XEF, + 0X49, 0X4A, 0X00, 0X00, 0X04, 0X21, 0X45, 0X29, 0X46, 0X31, 0X86, 0X31, 0X30, 0X84, 0XFF, 0XFF, + 0XFF, 0XF7, 0XF7, 0XDD, 0X09, 0XDA, 0X83, 0XF8, 0X01, 0XF0, 0X42, 0XC0, 0X82, 0X98, 0X49, 0X9A, + 0XF3, 0XB4, 0XF3, 0XCC, 0X71, 0XBC, 0X8E, 0XBB, 0X8E, 0XBB, 0X30, 0XBC, 0X71, 0XBC, 0XF3, 0XBC, + 0XB6, 0XBD, 0XFB, 0XCE, 0XBE, 0XE7, 0X7D, 0XE7, 0X3B, 0XDF, 0XBA, 0XD6, 0X79, 0XCE, 0XFB, 0XDE, + 0X75, 0XAD, 0X86, 0X31, 0X41, 0X08, 0X41, 0X08, 0X00, 0X00, 0X00, 0X00, 0X49, 0X4A, 0XFB, 0XDE, + 0X04, 0X21, 0X41, 0X08, 0X04, 0X21, 0X45, 0X29, 0X45, 0X29, 0X87, 0X39, 0XB2, 0X94, 0XFF, 0XFF, + 0XBE, 0XF7, 0X34, 0XDD, 0X0C, 0XEB, 0X09, 0XFA, 0X00, 0XF0, 0X01, 0XD8, 0X00, 0XD8, 0X8B, 0XD2, + 0X7D, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XBE, 0XFF, 0X7D, 0XEF, 0XFB, 0XDE, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XBA, 0XD6, + 0X78, 0XC6, 0XC7, 0X39, 0X00, 0X00, 0X41, 0X08, 0X00, 0X00, 0X00, 0X00, 0XC7, 0X39, 0X79, 0XCE, + 0X00, 0X00, 0X82, 0X10, 0XC3, 0X18, 0X04, 0X21, 0X05, 0X29, 0X86, 0X31, 0XB3, 0X9C, 0XFF, 0XFF, + 0XFF, 0XF7, 0X75, 0XDD, 0XC7, 0XE9, 0XC7, 0XF9, 0X01, 0XF8, 0X01, 0XF0, 0X00, 0XE8, 0X49, 0XE2, + 0XFB, 0XEE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, 0XFB, 0XDE, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XBA, 0XD6, + 0XB9, 0XCE, 0X08, 0X42, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0XC7, 0X39, 0X38, 0XC6, + 0X00, 0X00, 0X82, 0X10, 0X82, 0X10, 0X04, 0X21, 0X04, 0X21, 0X45, 0X29, 0X30, 0X84, 0XFF, 0XFF, + 0XFF, 0XFF, 0X38, 0XDE, 0XC4, 0XD0, 0X00, 0XF0, 0X01, 0XF8, 0X00, 0XF8, 0X00, 0XF0, 0X08, 0XD2, + 0XFB, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0XBA, 0XD6, + 0X79, 0XCE, 0XC7, 0X39, 0X41, 0X08, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X86, 0X31, 0X38, 0XC6, + 0X00, 0X00, 0X00, 0X00, 0XC3, 0X18, 0XCB, 0X5A, 0X86, 0X31, 0XC3, 0X18, 0XCB, 0X5A, 0X7D, 0XEF, + 0XFF, 0XFF, 0X7D, 0XEF, 0XCF, 0XBB, 0XC3, 0XB0, 0X41, 0XD0, 0X41, 0XD0, 0X82, 0XB8, 0X4D, 0XB3, + 0X7D, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XBE, 0XF7, 0XBE, 0XF7, 0X3D, 0XEF, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0XFA, 0XD6, + 0XF7, 0XBD, 0X04, 0X21, 0X86, 0X31, 0X04, 0X21, 0X00, 0X00, 0X00, 0X00, 0X86, 0X31, 0X38, 0XC6, + 0X86, 0X31, 0XC3, 0X18, 0XCB, 0X5A, 0X75, 0XAD, 0XCF, 0X7B, 0X41, 0X08, 0X86, 0X31, 0XF7, 0XBD, + 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XEF, 0X74, 0XB5, 0X30, 0X9C, 0X30, 0X9C, 0X72, 0XA4, 0XBB, 0XD6, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XBE, 0XF7, 0X7D, 0XEF, 0X3C, 0XE7, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0X3C, 0XE7, + 0X71, 0X8C, 0X81, 0X08, 0X0C, 0X63, 0XCF, 0X7B, 0X82, 0X10, 0X00, 0X00, 0X8A, 0X52, 0X38, 0XC6, + 0X75, 0XAD, 0X71, 0X8C, 0XB6, 0XB5, 0X3C, 0XE7, 0XFB, 0XDE, 0XC7, 0X39, 0X00, 0X00, 0XCF, 0X73, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, + 0X7D, 0XEF, 0X7D, 0XEF, 0X3B, 0XDF, 0XFA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0XFB, 0XDE, 0XB9, 0XCE, + 0XC7, 0X39, 0XC4, 0X20, 0X71, 0X8C, 0XBA, 0XD6, 0X71, 0X8C, 0XCB, 0X5A, 0XB2, 0X94, 0XBA, 0XD6, + 0XFF, 0XFF, 0X7D, 0XEF, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XB6, 0XB5, 0X46, 0X29, 0X05, 0X19, + 0X75, 0XA5, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, + 0X7D, 0XEF, 0X3C, 0XE7, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XBA, 0XD6, 0XFC, 0XDE, 0X4E, 0X63, + 0X42, 0X08, 0X0C, 0X63, 0XF7, 0XBD, 0XBE, 0XF7, 0XFF, 0XFF, 0XFB, 0XDE, 0XFB, 0XDE, 0XBE, 0XF7, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XF4, 0X9C, 0X04, 0X21, + 0X05, 0X21, 0XB6, 0XA5, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XBE, 0XF7, 0X7D, 0XEF, + 0X3C, 0XE7, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XFB, 0XDE, 0XBB, 0XD6, 0XD1, 0X73, 0X83, 0X18, + 0X86, 0X39, 0X34, 0X9D, 0XBD, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XFF, 0X35, 0XD6, 0XEB, 0XCC, 0X43, 0XB3, + 0X40, 0X51, 0X05, 0X19, 0XF5, 0X8C, 0XBE, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XBE, 0XF7, 0X7D, 0XEF, 0X7D, 0XEF, 0X3C, 0XE7, + 0XFB, 0XDE, 0XBA, 0XDE, 0XBA, 0XD6, 0X3C, 0XDF, 0X3A, 0XBE, 0X4F, 0X63, 0X82, 0X49, 0X40, 0XA3, + 0X23, 0XB4, 0XCC, 0X83, 0X3A, 0XBE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBF, 0XF7, 0XB5, 0XBD, 0X82, 0X92, 0X20, 0XF4, 0XA0, 0XFC, + 0X60, 0XE4, 0X40, 0X82, 0X84, 0X41, 0X8F, 0X6B, 0X77, 0XAD, 0X3D, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFE, 0XFF, 0XBE, 0XF7, 0XBE, 0XF7, 0XBE, 0XF7, 0X7D, 0XEF, 0X7D, 0XEF, 0X3C, 0XE7, 0XFB, 0XDE, + 0XFB, 0XDE, 0X3D, 0XE7, 0XBB, 0XCE, 0X36, 0X9D, 0X0B, 0X6B, 0X41, 0X6A, 0X60, 0XC4, 0X20, 0XFE, + 0X60, 0XF5, 0X00, 0X8B, 0XC7, 0X6A, 0X38, 0XC6, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0X4B, 0X7B, 0X80, 0XB2, 0XA0, 0XFC, 0XA0, 0XFC, + 0XE0, 0XFC, 0XE0, 0XFC, 0XC0, 0XCB, 0XC1, 0X8A, 0X45, 0X62, 0X4D, 0X6B, 0XB3, 0X94, 0XF7, 0XBD, + 0X3D, 0XDF, 0XFF, 0XF7, 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, 0X7D, 0XEF, 0X7D, 0XE7, 0X3D, 0XDF, + 0XBA, 0XC6, 0X75, 0XA5, 0X8D, 0X7B, 0X84, 0X7A, 0X40, 0XB3, 0XE0, 0XEC, 0XE0, 0XFD, 0XE0, 0XFD, + 0X60, 0XF5, 0X20, 0XE5, 0XA0, 0XD4, 0X0A, 0X6B, 0XFB, 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0XCC, 0X93, 0X40, 0XEB, 0X60, 0XFC, 0XA0, 0XFC, + 0XE0, 0XFC, 0X20, 0XFD, 0X60, 0XFD, 0X20, 0XF5, 0XA0, 0XD4, 0XC0, 0XBB, 0X42, 0X9B, 0X45, 0X8B, + 0X6B, 0X9C, 0XAE, 0X9C, 0X71, 0X8C, 0XB3, 0X94, 0X33, 0X9D, 0X34, 0XA5, 0XF2, 0XA4, 0XF0, 0XB4, + 0XCA, 0X9B, 0X04, 0X9B, 0X40, 0XBB, 0X20, 0XE4, 0X20, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XE0, 0XFD, + 0XE0, 0XFD, 0XE0, 0XFD, 0X20, 0XC4, 0X88, 0X5A, 0X38, 0XBE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X78, 0XD6, 0X46, 0XAB, 0X40, 0XDB, 0X20, 0XF4, + 0X60, 0XFC, 0XA0, 0XFC, 0XE0, 0XFC, 0X60, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X20, 0XF5, 0XA0, 0XDC, + 0XC0, 0XB3, 0XC0, 0X51, 0X86, 0X29, 0X0D, 0X63, 0X8F, 0X7B, 0X0D, 0X5B, 0XC7, 0X41, 0X01, 0X82, + 0X00, 0XC3, 0XC0, 0XE3, 0X60, 0XFC, 0XA0, 0XFC, 0XE0, 0XFC, 0XE0, 0XFC, 0X60, 0XF5, 0X60, 0XF5, + 0X20, 0XE5, 0X80, 0X9B, 0X86, 0X62, 0X30, 0X84, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X38, 0XC6, 0X2D, 0X9C, 0X05, 0X93, + 0X43, 0XA3, 0X82, 0XB3, 0XC2, 0XBB, 0XC2, 0XBB, 0X22, 0XB4, 0X82, 0XA3, 0X42, 0X93, 0XC3, 0X7A, + 0X85, 0X62, 0X0B, 0X63, 0X71, 0X84, 0XB6, 0XB5, 0X79, 0XCE, 0X79, 0XC6, 0XB5, 0XAD, 0X70, 0X94, + 0X4A, 0X8B, 0X06, 0X83, 0X04, 0X93, 0X04, 0X9B, 0X43, 0X9B, 0X43, 0X9B, 0X43, 0X93, 0X04, 0X83, + 0X08, 0X73, 0X8D, 0X73, 0XB3, 0X94, 0X79, 0XCE, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XDF, 0X38, 0XBE, + 0X75, 0XB5, 0X33, 0XA5, 0X33, 0XA5, 0XF3, 0X9C, 0XF3, 0X9C, 0XF3, 0X9C, 0XF3, 0X94, 0XF3, 0X9C, + 0X35, 0XA5, 0XF8, 0XBD, 0XFB, 0XDE, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7E, 0XEF, + 0XBB, 0XD6, 0XF8, 0XBD, 0XB6, 0XAD, 0X75, 0XAD, 0X34, 0XA5, 0X33, 0X9D, 0X34, 0X9D, 0X35, 0XA5, + 0XB7, 0XAD, 0X79, 0XC6, 0X3C, 0XE7, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, +}; + +const unsigned char PROGMEM icon_40x40[3200] = { /* 0X00,0X10,0X28,0X00,0X28,0X00,0X01,0X1B, */ + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X5D, 0XEF, 0X71, 0X8C, 0X31, 0X84, 0X31, 0X84, + 0X93, 0XC5, 0X92, 0XCD, 0X91, 0XCD, 0X91, 0XD5, 0X91, 0XD5, 0X91, 0XCD, 0X72, 0XCD, 0X72, 0XC5, + 0X56, 0XDE, 0XBE, 0XFF, 0XDB, 0XDE, 0XFB, 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XCE, 0X7B, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, + 0X00, 0X5A, 0X20, 0XDD, 0X20, 0XDD, 0X20, 0XDD, 0X20, 0XDD, 0X20, 0XDD, 0XE0, 0XD4, 0XA0, 0XD4, + 0X61, 0XA3, 0XA7, 0X39, 0XE5, 0X18, 0X05, 0X21, 0X92, 0X94, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XF9, 0XEE, 0XEB, 0X9B, 0XA1, 0X18, 0X23, 0X73, 0X81, 0XC5, 0X21, 0X9C, + 0X61, 0X39, 0X81, 0XEE, 0X40, 0XFF, 0XE0, 0XFE, 0XE0, 0XFE, 0XE0, 0XFE, 0X40, 0XFF, 0XC0, 0XF6, + 0XC0, 0X49, 0XA0, 0X18, 0X00, 0X42, 0X60, 0X18, 0X00, 0X00, 0X74, 0XB5, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0X93, 0XCD, 0XC3, 0XBB, 0XA0, 0X51, 0XE1, 0X39, 0XC2, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, + 0X63, 0XBD, 0X61, 0XE6, 0X40, 0XFF, 0XE0, 0XFE, 0XE0, 0XFE, 0XC0, 0XFE, 0X60, 0XFF, 0X21, 0X73, + 0XE1, 0X28, 0X81, 0XEE, 0X61, 0XFF, 0X21, 0XEE, 0XA0, 0X41, 0X20, 0X08, 0X90, 0XCD, 0XDE, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X5C, 0XF7, + 0X0B, 0XAC, 0XC0, 0XB3, 0XA1, 0XEE, 0XC3, 0X5A, 0X22, 0X8C, 0XE1, 0XFF, 0X40, 0XFF, 0X40, 0XFF, + 0XC0, 0XFF, 0X80, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0X20, 0XFF, 0XA1, 0XAC, + 0X21, 0XC5, 0X20, 0XFF, 0X60, 0XFE, 0X00, 0XFF, 0X02, 0XDE, 0XE0, 0X20, 0X40, 0X82, 0X49, 0XBC, + 0X3B, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X5C, 0XF7, 0X67, 0X9B, + 0XE0, 0XB3, 0X81, 0XFF, 0XC3, 0XFF, 0X83, 0X9C, 0X82, 0XDE, 0XC0, 0XFF, 0X60, 0XFF, 0X60, 0XFF, + 0X40, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0X60, 0XFF, + 0X40, 0XFF, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0XE0, 0XFE, 0XA2, 0XB4, 0X41, 0XBC, 0X20, 0XCC, + 0X87, 0XA3, 0XB8, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X9D, 0XF7, 0XA8, 0XA3, 0X60, 0XBC, + 0XA2, 0XFF, 0XA5, 0XFF, 0X44, 0XFF, 0XA1, 0XFF, 0XA0, 0XFF, 0X60, 0XFF, 0X80, 0XFF, 0X80, 0XFF, + 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, + 0X00, 0XFF, 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0X60, 0XFE, 0X20, 0XFE, 0X40, 0XFE, + 0XE0, 0XCB, 0XE3, 0X92, 0X7C, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X4C, 0XAC, 0XC0, 0XB3, 0XA4, 0XFF, + 0XA6, 0XFF, 0X45, 0XFF, 0X62, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, + 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, + 0X20, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, 0X80, 0XFE, 0X60, 0XFE, 0X40, 0XFE, 0X20, 0XFE, 0X00, 0XFE, + 0XE0, 0XFD, 0XE0, 0XC3, 0X2A, 0XAC, 0X7D, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XD4, 0XD5, 0X40, 0XAB, 0X43, 0XFF, 0XA8, 0XFF, + 0X67, 0XFF, 0X62, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, + 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X40, 0XFF, + 0X40, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0X20, 0XFE, 0XE0, 0XFD, + 0XE0, 0XFD, 0XC0, 0XFD, 0XA0, 0XA2, 0X11, 0XBD, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XDA, 0XE6, 0XE4, 0X9A, 0XE1, 0XE5, 0XE8, 0XFF, 0X69, 0XFF, + 0X65, 0XFF, 0X60, 0XFF, 0X80, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, + 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, + 0X40, 0XFF, 0X00, 0XFF, 0X00, 0XFF, 0X20, 0XFF, 0XE0, 0XFE, 0X60, 0XFE, 0X20, 0XFE, 0X00, 0XFE, + 0XC0, 0XFD, 0XE0, 0XFD, 0XE0, 0XE4, 0X85, 0XAB, 0XFA, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X2B, 0XB4, 0XC0, 0XB3, 0XC8, 0XFF, 0X8C, 0XFF, 0X68, 0XFF, + 0X61, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0XE1, 0XFF, 0XA1, 0XDE, 0X61, 0XEF, + 0XE1, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X60, 0XFF, + 0X40, 0XFF, 0X60, 0XFF, 0XC0, 0XFF, 0X61, 0XDE, 0X00, 0XE6, 0X80, 0XFE, 0X40, 0XFE, 0X00, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0XE0, 0XFD, 0XC0, 0XC3, 0XE9, 0XAB, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0X5D, 0XEF, 0XA3, 0XAB, 0XA3, 0XF6, 0XCC, 0XFF, 0X4C, 0XFF, 0X64, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0X61, 0XEF, 0X22, 0X6B, 0X82, 0X5A, 0X82, 0XB5, + 0XE2, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X60, 0XFF, + 0XA0, 0XFF, 0XE1, 0XFF, 0X42, 0X8C, 0XC1, 0X41, 0X21, 0XA4, 0XA0, 0XFE, 0X80, 0XFE, 0X20, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0XA0, 0XFD, 0X20, 0XF5, 0XC0, 0X9A, 0X35, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0X51, 0XC5, 0X60, 0XBC, 0XC9, 0XFF, 0X8E, 0XFF, 0X6A, 0XFF, 0X61, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE1, 0XFF, 0XE1, 0X62, 0X80, 0X10, 0X05, 0XE7, 0XA4, 0XF7, + 0XE4, 0XFF, 0XE3, 0XFF, 0XE2, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, + 0XC1, 0XFF, 0XE2, 0X83, 0X40, 0X08, 0X22, 0XCE, 0X60, 0XF7, 0XA0, 0XFE, 0X60, 0XFE, 0X20, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0XA0, 0XFD, 0XA0, 0XC3, 0XAC, 0XBC, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XDE, 0XFF, 0XA7, 0XAB, 0X81, 0XDD, 0XED, 0XFF, 0XB0, 0XFF, 0X69, 0XFF, 0X60, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0X61, 0XD6, 0X22, 0X29, 0XA6, 0X31, 0XE3, 0X7B, 0X46, 0XEF, + 0XE6, 0XFF, 0XE4, 0XFF, 0XE2, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, + 0X81, 0XD6, 0XA0, 0X18, 0XC4, 0X18, 0XA1, 0X62, 0XC1, 0XCD, 0X40, 0XFF, 0X60, 0XFE, 0X20, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0X80, 0XFD, 0XA0, 0XEC, 0X48, 0XBC, 0XDF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XF9, 0XE6, 0XE3, 0X9A, 0X67, 0XEE, 0XD1, 0XFF, 0XB0, 0XFF, 0X86, 0XFF, 0X60, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0X60, 0X94, 0X91, 0X73, 0XD9, 0XBD, 0X00, 0X00, 0X05, 0X84, + 0XE8, 0XFF, 0XE5, 0XFF, 0XE3, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, + 0X20, 0XAD, 0XE9, 0X41, 0XB7, 0XB5, 0X01, 0X00, 0X60, 0X62, 0X21, 0XFF, 0X80, 0XFE, 0X20, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X20, 0XF5, 0XE3, 0XBB, 0XD9, 0XE6, 0XFF, 0XFF, + 0XFF, 0XFF, 0XD3, 0XCD, 0X40, 0XA3, 0X2B, 0XF7, 0XD3, 0XFF, 0XB0, 0XFF, 0X63, 0XFF, 0X60, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0XA0, 0X9C, 0X30, 0X6B, 0X97, 0XB5, 0X00, 0X00, 0X83, 0X52, + 0XC6, 0XFF, 0XE5, 0XFF, 0XE3, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, + 0X20, 0XAD, 0XEA, 0X41, 0X77, 0XAD, 0X01, 0X00, 0XC0, 0X49, 0XE0, 0XF6, 0XA0, 0XFE, 0X20, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0XA0, 0XBB, 0XD3, 0XCD, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0X00, 0XB4, 0X8E, 0XFF, 0XF4, 0XFF, 0XB0, 0XFF, 0X42, 0XFF, 0X60, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0XA1, 0XDE, 0X01, 0X21, 0X00, 0X00, 0X00, 0X00, 0X25, 0X8C, + 0XE5, 0XFF, 0XE3, 0XFF, 0XE2, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, + 0XE1, 0XDE, 0X01, 0X21, 0X00, 0X00, 0X00, 0X00, 0X61, 0X5A, 0X20, 0XFF, 0X80, 0XFE, 0X20, 0XFE, + 0X00, 0XFE, 0XE0, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0XC0, 0XCB, 0X71, 0XCD, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0X40, 0XC4, 0XB0, 0XFF, 0XF5, 0XFF, 0X8F, 0XFF, 0X41, 0XFF, 0X80, 0XFF, + 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0XE1, 0XFF, 0X21, 0X8C, 0X60, 0X10, 0X43, 0X6B, 0X44, 0XEF, + 0XE2, 0XFF, 0XE2, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, + 0XE1, 0XFF, 0XC1, 0XA4, 0XC2, 0X18, 0XA2, 0X39, 0XA1, 0XCD, 0X20, 0XFF, 0X60, 0XFE, 0X20, 0XFE, + 0XC0, 0XFD, 0X80, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0XE0, 0XCB, 0X91, 0XCD, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0X40, 0XC4, 0XD2, 0XFF, 0XF7, 0XFF, 0XAF, 0XFF, 0X01, 0XFF, 0X00, 0XFF, + 0X00, 0XFF, 0X40, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0XA1, 0XFF, 0X82, 0XD6, 0XC2, 0XFF, 0XE0, 0XFF, + 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X60, 0XFF, + 0X60, 0XFF, 0XC1, 0XFF, 0X82, 0XDE, 0XC2, 0XEE, 0X61, 0XFF, 0X80, 0XFE, 0XC0, 0XFD, 0X20, 0XFD, + 0XA1, 0XFC, 0X61, 0XFC, 0X61, 0XFC, 0XC0, 0XFC, 0X60, 0XFD, 0XE0, 0XCB, 0X51, 0XC5, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0X60, 0XC4, 0XD4, 0XFF, 0XF9, 0XFF, 0X2D, 0XFF, 0X00, 0XFE, 0XC0, 0XFD, + 0XA1, 0XFD, 0X21, 0XFE, 0XE0, 0XFE, 0XC0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, + 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, + 0X40, 0XFF, 0X40, 0XFF, 0X80, 0XFF, 0X20, 0XFF, 0XA0, 0XFE, 0X20, 0XFE, 0X01, 0XFD, 0X01, 0XFC, + 0X62, 0XFB, 0X42, 0XFB, 0X82, 0XFB, 0X21, 0XFC, 0X20, 0XFD, 0X00, 0XD4, 0X71, 0XC5, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0X20, 0XC4, 0XD4, 0XFF, 0XBA, 0XFF, 0X2E, 0XFE, 0XE1, 0XFC, 0X61, 0XFC, + 0X61, 0XFC, 0X01, 0XFD, 0X01, 0XFE, 0X20, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, + 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X40, 0XFF, + 0X40, 0XFF, 0X00, 0XFF, 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X80, 0XFD, 0X61, 0XFC, 0X62, 0XFB, + 0XA3, 0XFA, 0XA3, 0XFA, 0X42, 0XFB, 0X01, 0XFC, 0XE0, 0XFC, 0XE0, 0XCB, 0X71, 0XCD, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0XC0, 0XB3, 0XB3, 0XFF, 0X7A, 0XFF, 0X91, 0XFD, 0X03, 0XFC, 0X02, 0XFB, + 0X22, 0XFB, 0X62, 0XFC, 0X81, 0XFD, 0XC0, 0XFE, 0XA0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, + 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, + 0X20, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, 0XA0, 0XFE, 0X60, 0XFE, 0X60, 0XFD, 0X41, 0XFC, 0X62, 0XFB, + 0XC3, 0XFA, 0XA3, 0XFA, 0X42, 0XFB, 0X01, 0XFC, 0X20, 0XFD, 0XC0, 0XCB, 0X91, 0XCD, 0XFF, 0XFF, + 0XFF, 0XFF, 0X14, 0XD6, 0X20, 0XAB, 0X51, 0XF7, 0XBE, 0XFF, 0X17, 0XFE, 0X65, 0XFC, 0X61, 0XFB, + 0XA2, 0XFB, 0XA1, 0XFC, 0XC1, 0XFD, 0X00, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, + 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X20, 0XFF, + 0X00, 0XFF, 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X60, 0XFE, 0XC0, 0XFD, 0XC0, 0XFC, 0X41, 0XFC, + 0XC1, 0XFB, 0XA2, 0XFB, 0X01, 0XFC, 0XA0, 0XFC, 0X40, 0XFD, 0XA0, 0XC3, 0XF4, 0XD5, 0XFF, 0XFF, + 0XFF, 0XFF, 0X5B, 0XEF, 0X24, 0X9B, 0X49, 0XE6, 0XB8, 0XFF, 0X92, 0XFE, 0X25, 0XFD, 0XA0, 0XFC, + 0X02, 0XFD, 0XE1, 0XFD, 0XE0, 0XFE, 0X40, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X60, 0XFF, 0X60, 0XFF, + 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X00, 0XFF, + 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0X40, 0XFE, 0X00, 0XFE, 0X80, 0XFD, 0X01, 0XF5, + 0X41, 0XFD, 0X01, 0XFD, 0XC0, 0XFC, 0X40, 0XFD, 0X00, 0XF5, 0XC4, 0XBB, 0XFA, 0XE6, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0X2A, 0XB4, 0XA0, 0XD4, 0XA2, 0XFE, 0X20, 0XFE, 0XE0, 0XFD, 0X00, 0XFE, + 0X80, 0XFE, 0X21, 0XEE, 0X41, 0XE6, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, + 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, + 0XA0, 0XFE, 0X80, 0XFE, 0X60, 0XFE, 0X40, 0XFE, 0X00, 0XFE, 0X00, 0XFE, 0X00, 0XFE, 0X40, 0XCC, + 0XE1, 0XAB, 0XC1, 0XED, 0X80, 0XFD, 0X60, 0XFD, 0X60, 0XE4, 0X29, 0XB4, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0X15, 0XD6, 0XE0, 0XBB, 0X60, 0XFE, 0XC8, 0XFE, 0XC8, 0XFE, 0X02, 0XFF, + 0X60, 0XDD, 0X40, 0XA3, 0XA1, 0XDD, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, + 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, 0XC0, 0XFE, 0XA0, 0XFE, + 0X80, 0XFE, 0X60, 0XFE, 0X40, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X40, 0XED, + 0XC0, 0X9A, 0X40, 0XA3, 0X80, 0XF5, 0X60, 0XFD, 0X60, 0XBB, 0XEE, 0XBC, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XDF, 0XFF, 0X63, 0XAB, 0X42, 0XE5, 0XB4, 0XFF, 0X97, 0XFF, 0XAA, 0XF6, + 0X80, 0XAB, 0XA0, 0X92, 0XA1, 0XDD, 0X41, 0XFF, 0X40, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X60, 0XFF, + 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, + 0XC0, 0XFE, 0X80, 0XFE, 0X61, 0XFE, 0X00, 0XFE, 0XA0, 0XED, 0X20, 0XE5, 0X21, 0XCC, 0X80, 0XB3, + 0X00, 0XBC, 0XE0, 0XC3, 0X40, 0XED, 0XC0, 0XEC, 0X60, 0X92, 0X97, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X0F, 0XC5, 0X00, 0XA3, 0XAA, 0XF6, 0X93, 0XFF, 0X2D, 0XEE, + 0X63, 0XDD, 0X80, 0XD5, 0X42, 0XB4, 0X82, 0XCC, 0X00, 0XCD, 0X40, 0XD5, 0XA0, 0XDD, 0XE1, 0XE5, + 0XC1, 0XE5, 0XC1, 0XE5, 0XC1, 0XE5, 0XC1, 0XE5, 0X80, 0XDD, 0X60, 0XDD, 0X20, 0XD5, 0XC0, 0XCC, + 0XA0, 0XCC, 0X61, 0XC4, 0X21, 0XC4, 0X01, 0XBC, 0X01, 0XBC, 0XE0, 0XBB, 0XC0, 0XBB, 0X60, 0XD4, + 0X80, 0XFD, 0X40, 0XFD, 0X80, 0XFD, 0X80, 0XBB, 0X2B, 0XAC, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X9D, 0XF7, 0X87, 0XA3, 0X60, 0XD4, 0X0A, 0XFF, 0XCF, 0XFE, + 0XC9, 0XFE, 0XC0, 0XFE, 0XC0, 0XF6, 0X40, 0XE6, 0X41, 0XCD, 0X42, 0XB4, 0XC1, 0XAB, 0X60, 0XA3, + 0X60, 0XA3, 0X80, 0XA3, 0X80, 0XA3, 0X80, 0XA3, 0XA0, 0XAB, 0XC1, 0XAB, 0XE1, 0XB3, 0X22, 0XB4, + 0X82, 0XC4, 0XC0, 0XCC, 0X00, 0XD5, 0X60, 0XE5, 0X81, 0XED, 0X80, 0XF5, 0X80, 0XFD, 0X80, 0XFD, + 0X40, 0XFD, 0X80, 0XFD, 0X80, 0XE4, 0X85, 0XAB, 0X5C, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFA, 0XE6, 0X23, 0XA3, 0XE0, 0XE4, 0XE8, 0XFE, + 0X6A, 0XFE, 0X05, 0XFE, 0X40, 0XFE, 0XA0, 0XFE, 0XC0, 0XFE, 0XE1, 0XFE, 0XA0, 0XF6, 0XA0, 0XF6, + 0XA0, 0XF6, 0XA0, 0XF6, 0X80, 0XF6, 0X80, 0XF6, 0X80, 0XF6, 0X60, 0XF6, 0X61, 0XFE, 0X81, 0XFE, + 0X61, 0XFE, 0X20, 0XFE, 0X00, 0XFE, 0XC0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X20, 0XFD, 0X20, 0XFD, + 0X60, 0XFD, 0X20, 0XF5, 0XA0, 0XA2, 0XB4, 0XCD, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X52, 0XC5, 0XE0, 0XA2, 0XA1, 0XF5, + 0X86, 0XFE, 0X06, 0XFE, 0XE2, 0XFD, 0XE0, 0XFD, 0X00, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, + 0X40, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X00, 0XFE, 0XE0, 0XFD, 0XE0, 0XFD, 0XC0, 0XFD, + 0XA0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X40, 0XFD, + 0X60, 0XFD, 0X60, 0XBB, 0X6C, 0XB4, 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X92, 0XCD, 0XC0, 0XA2, + 0X20, 0XED, 0X22, 0XFE, 0XC1, 0XFD, 0XA0, 0XFD, 0XC0, 0XFD, 0XE0, 0XFD, 0XE0, 0XFD, 0XE0, 0XFD, + 0XE0, 0XFD, 0XE0, 0XFD, 0XC0, 0XFD, 0XC0, 0XFD, 0XC0, 0XFD, 0XC0, 0XFD, 0XA0, 0XFD, 0X80, 0XFD, + 0X80, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X60, 0XFD, 0X40, 0XFD, + 0X20, 0XB3, 0XEA, 0XA3, 0X9D, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X8E, 0XBC, + 0XE1, 0XA2, 0X00, 0XE5, 0XE0, 0XFD, 0XC0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, + 0XC0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0X80, 0XFD, 0X80, 0XFD, 0X60, 0XFD, + 0X40, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X80, 0XFD, 0X00, 0XF5, 0X40, 0XBB, + 0X2B, 0XAC, 0X9D, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0X35, 0XD6, 0XE2, 0X9A, 0XA0, 0XC3, 0XA0, 0XFD, 0XE0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X80, 0XFD, + 0X80, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X40, 0XFD, + 0X20, 0XFD, 0X20, 0XFD, 0X40, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X00, 0XD4, 0XC1, 0X9A, 0X10, 0XC5, + 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0X98, 0XDE, 0X2B, 0XAC, 0X40, 0XB3, 0X00, 0XD4, 0X40, 0XFD, 0X80, 0XFD, 0X80, 0XFD, + 0X60, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, + 0X40, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X40, 0XDC, 0X80, 0XBB, 0XE8, 0XAB, 0X57, 0XDE, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XDF, 0XFF, 0X37, 0XD6, 0X86, 0XA3, 0XC0, 0X9A, 0XE0, 0XCB, 0X80, 0XEC, + 0XE0, 0XF4, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X00, 0XF5, + 0XA0, 0XEC, 0X00, 0XD4, 0X40, 0XB3, 0X03, 0X9B, 0X92, 0XC5, 0XBD, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XF5, 0XCD, 0XAD, 0XBC, 0X69, 0XBC, + 0X05, 0XBC, 0X03, 0XC4, 0X01, 0XC4, 0X01, 0XC4, 0X01, 0XC4, 0X01, 0XC4, 0XE2, 0XC3, 0X24, 0XC4, + 0X68, 0XBC, 0XAC, 0XBC, 0XD3, 0XCD, 0X9E, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0X5B, 0XEF, 0X98, 0XDE, 0X56, 0XD6, 0X57, 0XD6, 0X57, 0XD6, 0X56, 0XD6, 0X77, 0XDE, 0X1B, 0XEF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, +}; + diff --git a/examples/graphictest_slim/graphictest_slim.ino b/examples/graphictest_slim/graphictest_slim.ino new file mode 100644 index 0000000..e552137 --- /dev/null +++ b/examples/graphictest_slim/graphictest_slim.ino @@ -0,0 +1,21 @@ +#include // f.k. for Arduino-1.5.2 +#include "Adafruit_GFX.h"// Hardware-specific library +#include + +/* + * an empty Leonardo sketch uses 3.5kB + 4kB bootloader + * + * this C++ program avoids Serial and f-p. + * so it just fits in the Flash. + * + * This is a complete dummy sketch. + * its only purpose is to tell the IDE which libraries to use + * + * The actual program is in the graphictest_v25.cpp + * + * This enables me to build an identical AS7 project + * + * Edit the HOW_SLIM macro to build for other chips + * + */ + diff --git a/examples/graphictest_slim/graphictest_v25.cpp b/examples/graphictest_slim/graphictest_v25.cpp new file mode 100644 index 0000000..b2bf3f7 --- /dev/null +++ b/examples/graphictest_slim/graphictest_v25.cpp @@ -0,0 +1,552 @@ +#if defined(__AVR_ATmega32U4__) //Leonardo +#define HOW_SLIM 3 +#else +#define HOW_SLIM 0 //no slimming measures +#endif + +// All the mcufriend.com UNO shields have the same pinout. +// i.e. control pins A0-A4. Data D2-D9. microSD D10-D13. +// Touchscreens are normally A1, A2, D7, D6 but the order varies +// +// This demo should work with most Adafruit TFT libraries +// If you are not using a shield, use a full Adafruit constructor() +// e.g. Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); + +#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 + +#if ARDUINO < 165 +#define USE_GFX_KBV +#include "ADA_GFX_kbv.h" +#else +#include "Adafruit_GFX.h" +#endif +#include +MCUFRIEND_kbv tft; +//#include +//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 + +#ifndef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +void setup(void); +void loop(void); +unsigned long testFillScreen(); +unsigned long testText(); +unsigned long testLines(uint16_t color); +unsigned long testFastLines(uint16_t color1, uint16_t color2); +unsigned long testRects(uint16_t color); +unsigned long testFilledRects(uint16_t color1, uint16_t color2); +unsigned long testFilledCircles(uint8_t radius, uint16_t color); +unsigned long testCircles(uint8_t radius, uint16_t color); +unsigned long testTriangles(); +unsigned long testFilledTriangles(); +unsigned long testRoundRects(); +unsigned long testFilledRoundRects(); +void progmemPrint(const char *str); +void progmemPrintln(const char *str); + +void runtests(void); + +uint16_t g_identifier; + +void setup(void) { +#if HOW_SLIM < 1 + Serial.begin(9600); + uint32_t when = millis(); + // while (!Serial) ; //hangs a Leonardo until you connect a Serial + if (!Serial) delay(5000); //allow some time for Leonardo + Serial.println("Serial took " + String((millis() - when)) + "ms to start"); +#endif + static uint16_t identifier; + tft.reset(); //we can't read ID on 9341 until begin() + g_identifier = tft.readID(); // +#if HOW_SLIM < 1 + Serial.print("ID = 0x"); + Serial.println(g_identifier, HEX); +#endif + if (g_identifier == 0x00D3) g_identifier = 0x9481; // write-only shield + if (g_identifier == 0xFFFF) g_identifier = 0x9341; // serial + // g_identifier = 0x7789; // force ID + tft.begin(g_identifier); +} + +#if defined(MCUFRIEND_KBV_H_) +uint16_t scrollbuf[480]; // my biggest screen is 320x480 +#define READGRAM(x, y, buf, w, h) tft.readGRAM(x, y, buf, w, h) +#else +uint16_t scrollbuf[320]; // Adafruit only does 240x320 +// Adafruit can read a block by one pixel at a time +int16_t READGRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h) +{ + uint16_t *p; + for (int row = 0; row < h; row++) { + p = block + row * w; + for (int col = 0; col < w; col++) { + *p++ = tft.readPixel(x + col, y + row); + } + } +} +#endif + +void windowScroll(int16_t x, int16_t y, int16_t wid, int16_t ht, int16_t dx, int16_t dy, uint16_t *buf) +{ + if (dx) for (int16_t row = 0; row < ht; row++) { + READGRAM(x, y + row, buf, wid, 1); + tft.setAddrWindow(x, y + row, x + wid - 1, y + row); + tft.pushColors(buf + dx, wid - dx, 1); + tft.pushColors(buf + 0, dx, 0); + } + if (dy) for (int16_t col = 0; col < wid; col++) { + READGRAM(x + col, y, buf, 1, ht); + tft.setAddrWindow(x + col, y, x + col, y + ht - 1); + tft.pushColors(buf + dy, ht - dy, 1); + tft.pushColors(buf + 0, dy, 0); + } +} + +void loop(void) { + uint8_t aspect; + uint16_t pixel; + char *aspectname[] = { + "PORTRAIT", "LANDSCAPE", "PORTRAIT_REV", "LANDSCAPE_REV" + }; + char *colorname[] = { "BLUE", "GREEN", "RED", "GRAY" }; + uint16_t colormask[] = { 0x001F, 0x07E0, 0xF800, 0xFFFF }; + uint16_t dx, rgb, n, wid, ht; + tft.setRotation(1); + runtests(); + delay(2000); + if (tft.height() > 64) { + for (uint8_t cnt = 0; cnt < 4; cnt++) { + aspect = (cnt + 0) & 3; + tft.setRotation(aspect); + wid = tft.width(); + ht = tft.height(); + testText(); + dx = wid / 32; + for (n = 0; n < 32; n++) { + rgb = n * 8; + rgb = tft.color565(rgb, rgb, rgb); + tft.fillRect(n * dx, 48, dx, 64, rgb & colormask[aspect]); + } + tft.setTextSize(2); + tft.setTextColor(colormask[aspect], BLACK); + tft.setCursor(0, 72); + tft.print(colorname[aspect]); + tft.setTextColor(WHITE); + tft.println(" COLOR GRADES"); + tft.setTextColor(WHITE, BLACK); + tft.setCursor(0, 184); + tft.println(aspectname[aspect]); + delay(1000); + tft.drawPixel(0, 0, YELLOW); + pixel = tft.readPixel(0, 0); +#if defined(MCUFRIEND_KBV_H_) +#if HOW_SLIM < 3 + extern const uint8_t penguin[]; + tft.setAddrWindow(wid - 40 - 40, 20 + 0, wid - 1 - 40, 20 + 39); + tft.pushColors(penguin, 1600, 1); +#endif + tft.setTextColor(WHITE, BLACK); + tft.println("VERTICAL SCROLL UP"); + uint16_t maxscroll; + if (tft.getRotation() & 1) maxscroll = wid; + else maxscroll = ht; + for (uint16_t i = 1; i <= maxscroll; i++) { + tft.vertScroll(0, maxscroll, i); + delay(10); + } + tft.vertScroll(0, maxscroll, 0); + tft.setCursor(0, 200); + tft.println("VERTICAL SCROLL DN"); + for (uint16_t i = 1; i <= maxscroll; i++) { + tft.vertScroll(0, maxscroll, 0 - (int16_t)i); + delay(10); + } + delay(1000); + tft.vertScroll(0, maxscroll, 0); + if ((aspect & 1) == 0) { //Portrait + tft.setCursor(0, 200); + tft.setTextColor(BLUE, BLACK); + tft.println("ONLY THE COLOR BAND"); + for (uint16_t i = 0; i < 64; i++) { + tft.vertScroll(48, 64, i + 1); + delay(20); + } + delay(1000); + tft.vertScroll(0, maxscroll, 0); + } +#endif + tft.setCursor(0, 200); + tft.setTextColor(YELLOW, BLACK); + if (pixel == YELLOW) { + tft.println("SOFTWARE SCROLL "); +#if 1 + for (int16_t i = 45, dx = 2, dy = 1; i > 0; i -= dx) { + windowScroll(24, 8, 90, 40, dx, dy, scrollbuf); + } +#else + // scroll a whole width of the screen + for (int16_t i = wid, dx = 4, dy = 0; i > 0; i -= dx) { + windowScroll(0, 200, wid, 16, dx, dy, scrollbuf); + } +#endif + } + else if (pixel == CYAN) + tft.println("readPixel() reads as BGR"); + else if (pixel == 0xFFFF) + tft.println("readPixel() should be 24-bit"); + else { + tft.print("readPixel() reads 0x"); + tft.println(pixel, HEX); + } + delay(5000); + } + } + tft.println("INVERT DISPLAY"); + tft.invertDisplay(true); + delay(2000); + tft.invertDisplay(false); +} + +typedef struct { + PGM_P msg; + uint32_t ms; +} TEST; +TEST result[12]; + +#define RUNTEST(n, str, test) { result[n].msg = PSTR(str); result[n].ms = test; delay(500); } + +void runtests(void) +{ + uint8_t i; + uint32_t total; + RUNTEST(0, "FillScreen ", testFillScreen()); + RUNTEST(1, "Text ", testText()); + RUNTEST(2, "Lines ", testLines(CYAN)); + RUNTEST(3, "Horiz/Vert Lines ", testFastLines(RED, BLUE)); + RUNTEST(4, "Rectangles (outline) ", testRects(GREEN)); + RUNTEST(5, "Rectangles (filled) ", testFilledRects(YELLOW, MAGENTA)); + RUNTEST(6, "Circles (filled) ", testFilledCircles(10, MAGENTA)); + RUNTEST(7, "Circles (outline) ", testCircles(10, WHITE)); + RUNTEST(8, "Triangles (outline) ", testTriangles()); + RUNTEST(9, "Triangles (filled) ", testFilledTriangles()); + RUNTEST(10, "Rounded rects (outline) ", testRoundRects()); + RUNTEST(11, "Rounded rects (filled) ", testFilledRoundRects()); + + tft.setRotation(1); + tft.fillScreen(BLACK); + tft.setCursor(0, 0); + tft.setTextSize(2); + tft.println("MCUFRIEND for UNO"); + + tft.setTextSize(1); + total = 0; + for (i = 0; i < 12; i++) { + PGM_P str = result[i].msg; + char c; + if (i < 10) tft.print(" "); + tft.print(i); + tft.print(": "); + while (c = pgm_read_byte(str++)) tft.print(c); + tft.println(result[i].ms); + total += result[i].ms; + } + tft.setTextSize(2); + tft.print("Total:"); +#if HOW_SLIM < 2 + tft.print(0.000001 * total); + tft.println("sec"); +#else + tft.print(total / 1000, DEC); + tft.println(" ms"); +#endif + g_identifier = tft.readID(); + tft.print("ID: 0x"); + tft.println(tft.readID(), HEX); + tft.print("Reg(00):0x"); + tft.println(tft.readReg(0x00), HEX); + tft.print("F_CPU:"); +#if HOW_SLIM < 2 + tft.print(0.000001 * F_CPU); +#else + tft.print((int)(F_CPU/1000000)); +#endif +#if defined(__OPTIMIZE_SIZE__) + tft.println("MHz -Os"); +#else + tft.println("MHz"); +#endif + + delay(10000); +} + +// Standard Adafruit tests. will adjust to screen size + +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() { + unsigned long start; + tft.fillScreen(BLACK); + start = micros(); + tft.setCursor(0, 0); + tft.setTextColor(WHITE); tft.setTextSize(1); + tft.println("Hello World!"); + tft.setTextColor(YELLOW); tft.setTextSize(2); +#if HOW_SLIM < 2 + tft.println(123.45); +#else + tft.println("456.78"); +#endif + 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, red, step, + cx = tft.width() / 2 - 1, + cy = tft.height() / 2 - 1; + + tft.fillScreen(BLACK); + w = min(tft.width(), tft.height()); + start = micros(); + red = 0; + step = (256 * 6) / w; + for (i = 0; i < w; i += 6) { + i2 = i / 2; + red += step; + tft.drawRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(red, 0, 0)); + } + + return micros() - start; +} + +unsigned long testFilledRoundRects() { + unsigned long start; + int i, i2, green, step, + cx = tft.width() / 2 - 1, + cy = tft.height() / 2 - 1; + + tft.fillScreen(BLACK); + start = micros(); + green = 256; + step = (256 * 6) / min(tft.width(), tft.height()); + for (i = min(tft.width(), tft.height()); i > 20; i -= 6) { + i2 = i / 2; + green -= step; + tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(0, green, 0)); + } + + return micros() - start; +} + diff --git a/examples/graphictest_slim/icons.c b/examples/graphictest_slim/icons.c new file mode 100644 index 0000000..97edda8 --- /dev/null +++ b/examples/graphictest_slim/icons.c @@ -0,0 +1,408 @@ +#include + +const unsigned char PROGMEM penguin[3200] = { /* 0X00,0X10,0X28,0X00,0X28,0X00,0X01,0X1B, */ + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, + 0XBA, 0XD6, 0XB6, 0XB5, 0XF3, 0X9C, 0XB2, 0X94, 0XB3, 0X9C, 0XB2, 0X94, 0X34, 0XA5, 0XF7, 0XBD, + 0XFB, 0XDE, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XFB, 0XDE, 0XF3, 0X9C, 0XCB, 0X5A, + 0XC7, 0X39, 0X04, 0X21, 0X82, 0X10, 0X42, 0X10, 0X42, 0X10, 0X41, 0X08, 0X83, 0X18, 0X45, 0X29, + 0XC7, 0X39, 0X0C, 0X63, 0X75, 0XAD, 0X3C, 0XE7, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XE7, 0XB2, 0X94, 0X08, 0X42, 0XC3, 0X18, 0X82, 0X10, + 0X04, 0X21, 0X45, 0X29, 0X86, 0X31, 0X86, 0X31, 0X86, 0X31, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, + 0X82, 0X10, 0X41, 0X08, 0XC3, 0X18, 0X08, 0X42, 0XF3, 0X9C, 0X3C, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFB, 0XDE, 0X0C, 0X63, 0XC3, 0X18, 0XC3, 0X18, 0X45, 0X29, 0XC7, 0X39, + 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0XC7, 0X39, 0XC7, 0X39, + 0X86, 0X31, 0X86, 0X31, 0X04, 0X21, 0X41, 0X08, 0X82, 0X10, 0XCB, 0X5A, 0XBA, 0XD6, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFB, 0XDE, 0XCB, 0X5A, 0X82, 0X10, 0X45, 0X29, 0XC7, 0X39, 0X08, 0X42, 0X08, 0X42, + 0X09, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X08, 0X42, 0XC7, 0X39, + 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X83, 0X18, 0X00, 0X00, 0XC8, 0X41, 0X38, 0XC6, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0X7D, 0XEF, 0X8E, 0X73, 0X82, 0X10, 0X45, 0X29, 0XC7, 0X39, 0X08, 0X42, 0X09, 0X4A, 0X8A, 0X52, + 0X30, 0X84, 0XCF, 0X7B, 0X8A, 0X52, 0X49, 0X4A, 0X4A, 0X52, 0X49, 0X4A, 0XCB, 0X5A, 0XCF, 0X7B, + 0X0C, 0X63, 0X08, 0X42, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0XC3, 0X18, 0X00, 0X00, 0X49, 0X4A, + 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XF3, 0X9C, 0XC3, 0X18, 0X04, 0X21, 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X72, 0X94, + 0X7D, 0XEF, 0X7D, 0XEF, 0XB2, 0X94, 0X4A, 0X52, 0X49, 0X4A, 0X8A, 0X52, 0X75, 0XAD, 0XBE, 0XF7, + 0XBA, 0XD6, 0X4D, 0X6B, 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0XC3, 0X18, 0X41, 0X08, + 0XCF, 0X7B, 0X7C, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBA, 0XD6, + 0X08, 0X42, 0X82, 0X10, 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X8E, 0X73, 0XFB, 0XDE, + 0XFF, 0XFF, 0XBE, 0XF7, 0XBA, 0XD6, 0X8E, 0X73, 0X08, 0X42, 0X30, 0X84, 0X3C, 0XE7, 0X7D, 0XEF, + 0XFF, 0XFF, 0XB6, 0XB5, 0X49, 0X4A, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, 0X41, 0X08, + 0X45, 0X29, 0XB6, 0XB5, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0X71, 0X8C, + 0X41, 0X08, 0X45, 0X29, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X4A, 0X52, 0XB2, 0X94, 0XBE, 0XF7, + 0XBE, 0XF7, 0XB2, 0X94, 0XCF, 0X7B, 0XCF, 0X7B, 0X49, 0X4A, 0XB6, 0XB5, 0XF3, 0X9C, 0X0C, 0X63, + 0X38, 0XC6, 0XBA, 0XD6, 0X0C, 0X63, 0X87, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0XC3, 0X18, + 0X41, 0X08, 0X30, 0X84, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XE7, 0XCB, 0X5A, + 0X41, 0X08, 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X4A, 0X52, 0X8A, 0X52, 0XF3, 0X9C, 0XFF, 0XFF, + 0X7D, 0XEF, 0XC7, 0X39, 0XC3, 0X18, 0X0C, 0X63, 0XCB, 0X5A, 0XB6, 0XB5, 0XB2, 0X94, 0XCB, 0X5A, + 0X75, 0XAD, 0XFA, 0XD6, 0X4D, 0X6B, 0X87, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, + 0X41, 0X08, 0X8A, 0X52, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X38, 0XC6, 0X86, 0X31, + 0X04, 0X21, 0XC8, 0X41, 0X49, 0X4A, 0X49, 0X4A, 0X4A, 0X52, 0X49, 0X4A, 0XB1, 0X8C, 0XBE, 0XF7, + 0XBE, 0XF7, 0XB2, 0X94, 0XCF, 0X7B, 0XCF, 0X7B, 0X49, 0X4A, 0X74, 0XA5, 0X7D, 0XEF, 0X7C, 0XE7, + 0XBE, 0XF7, 0X79, 0XCE, 0X0C, 0X63, 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, + 0X82, 0X10, 0X45, 0X29, 0X75, 0XAD, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X34, 0XA5, 0X82, 0X10, + 0X86, 0X31, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X8A, 0X52, 0X49, 0X4A, 0X4D, 0X6B, 0XBA, 0XD6, + 0XFF, 0XFF, 0XFF, 0XFF, 0X79, 0XCE, 0X0D, 0X63, 0XC7, 0X39, 0XCF, 0X7B, 0X7D, 0XEF, 0XFF, 0XFF, + 0XFF, 0XFF, 0X75, 0XAD, 0X08, 0X42, 0X86, 0X31, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X45, 0X29, + 0XC3, 0X18, 0XC3, 0X18, 0XB2, 0X94, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XB2, 0X8C, 0X41, 0X08, + 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X8A, 0X52, 0X8A, 0X52, 0X4A, 0X4A, 0XD0, 0X7B, + 0X7A, 0XC6, 0X7B, 0XBE, 0X90, 0X6B, 0XC9, 0X39, 0X88, 0X31, 0XC9, 0X39, 0XB3, 0X84, 0XBB, 0XC6, + 0XF8, 0XB5, 0XCC, 0X5A, 0X86, 0X31, 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X45, 0X29, + 0XC4, 0X20, 0X41, 0X08, 0X30, 0X84, 0X3C, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XE7, 0X8A, 0X4A, 0XC3, 0X10, + 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X4A, 0X4A, 0X4A, 0X42, 0X09, 0X3A, 0X08, 0X4A, + 0X09, 0X6B, 0X49, 0X7B, 0XC6, 0X7A, 0X05, 0X83, 0X46, 0X83, 0XC5, 0X7A, 0XC6, 0X72, 0X09, 0X7B, + 0X48, 0X5A, 0X87, 0X31, 0X88, 0X21, 0X88, 0X29, 0X86, 0X31, 0X86, 0X31, 0X45, 0X29, 0X45, 0X29, + 0X04, 0X21, 0X41, 0X08, 0X4A, 0X4A, 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XF7, 0XC5, 0X82, 0X50, 0X05, 0X41, + 0XC7, 0X29, 0X08, 0X42, 0X49, 0X4A, 0X4A, 0X42, 0X49, 0X4A, 0X09, 0X7B, 0X88, 0X9B, 0XC6, 0XB3, + 0X21, 0XD4, 0XA0, 0XDC, 0XE1, 0XE4, 0X61, 0XED, 0X61, 0XED, 0X21, 0XED, 0XA0, 0XE4, 0X20, 0XDC, + 0X80, 0XCB, 0X43, 0XAB, 0XC4, 0X82, 0X06, 0X5A, 0X47, 0X21, 0X46, 0X29, 0X45, 0X29, 0X04, 0X29, + 0X04, 0X19, 0X82, 0X10, 0X82, 0X18, 0XF3, 0X9C, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0X4D, 0X93, 0X00, 0XA0, 0X82, 0XB8, + 0XC7, 0X31, 0X09, 0X32, 0X49, 0X4A, 0X86, 0X7A, 0X43, 0XC3, 0X6B, 0XED, 0XF4, 0XF6, 0XEB, 0XFD, + 0X20, 0XFD, 0X20, 0XFD, 0X60, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X20, 0XFD, + 0XE0, 0XFC, 0XA0, 0XFC, 0X60, 0XF4, 0XC1, 0XDB, 0X83, 0X9A, 0XC5, 0X49, 0X45, 0X29, 0X04, 0X19, + 0XC4, 0X20, 0X82, 0X38, 0X00, 0X50, 0XCB, 0X6A, 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFB, 0XEE, 0X04, 0XA1, 0X00, 0XC0, 0X00, 0XF0, + 0XC3, 0XA0, 0XC8, 0X41, 0X49, 0X42, 0X05, 0X9B, 0X20, 0XFC, 0XA4, 0XFC, 0X69, 0XFD, 0XE8, 0XFD, + 0X63, 0XFD, 0X20, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0XE0, 0XFC, + 0XE0, 0XFC, 0XA0, 0XFC, 0X60, 0XFC, 0X20, 0XFC, 0X41, 0XD3, 0XC5, 0X49, 0X45, 0X19, 0XC4, 0X38, + 0X82, 0X68, 0X41, 0X88, 0X00, 0X70, 0X49, 0X5A, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFB, 0XF6, 0X82, 0XC0, 0X00, 0XD0, 0X86, 0XC1, + 0X46, 0XF1, 0X41, 0XC8, 0X45, 0X79, 0X89, 0X52, 0X88, 0X62, 0X86, 0X6A, 0XC6, 0X7A, 0XC4, 0XBB, + 0XE1, 0XFC, 0X60, 0XFD, 0X60, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0XE0, 0XFC, + 0X60, 0XE4, 0X03, 0X93, 0X84, 0X72, 0X44, 0X6A, 0XC5, 0X41, 0X45, 0X29, 0XC3, 0X58, 0X41, 0XA8, + 0X40, 0X98, 0X00, 0XB0, 0X00, 0X60, 0X0C, 0X6B, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0XCE, 0X83, 0X82, 0X88, 0X00, 0XF8, 0XC4, 0XD8, + 0X0C, 0XF3, 0X8A, 0XFA, 0X82, 0XE8, 0X82, 0XB0, 0X45, 0X69, 0XC7, 0X51, 0X08, 0X42, 0X08, 0X3A, + 0X86, 0X5A, 0X83, 0X9B, 0XA2, 0XBC, 0X22, 0XCD, 0X21, 0XCD, 0XA1, 0XC4, 0X22, 0XB4, 0XC4, 0X7A, + 0X06, 0X3A, 0X86, 0X29, 0X45, 0X29, 0X05, 0X31, 0XC4, 0X50, 0X41, 0X90, 0X00, 0XC0, 0X00, 0XA8, + 0X00, 0XA0, 0X00, 0XA8, 0X00, 0X30, 0X4A, 0X4A, 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0X8E, 0X73, 0XC3, 0X18, 0X05, 0X39, 0X82, 0XA8, 0X00, 0XF8, + 0XC3, 0XF8, 0X4D, 0XFB, 0X4D, 0XFB, 0XC7, 0XF9, 0XC3, 0XF0, 0X82, 0XD8, 0XC3, 0XB0, 0X04, 0X81, + 0X45, 0X61, 0X46, 0X51, 0X86, 0X49, 0X86, 0X49, 0X46, 0X41, 0X45, 0X41, 0X45, 0X41, 0X45, 0X41, + 0X05, 0X49, 0X04, 0X61, 0X82, 0X90, 0X41, 0XB0, 0X00, 0XD0, 0X00, 0XC8, 0X00, 0XA8, 0X00, 0XA8, + 0X00, 0XB8, 0X41, 0X58, 0X82, 0X10, 0X82, 0X10, 0XB2, 0X94, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XBE, 0XF7, 0XCF, 0X7B, 0X82, 0X10, 0X04, 0X21, 0X86, 0X29, 0X86, 0X41, 0X04, 0X99, + 0X40, 0XE8, 0X41, 0XF8, 0X86, 0XF9, 0XCB, 0XFA, 0X49, 0XFA, 0X82, 0XF8, 0X00, 0XF8, 0X00, 0XF0, + 0X00, 0XE8, 0X41, 0XD8, 0X41, 0XD0, 0X41, 0XC0, 0X41, 0XC0, 0X41, 0XC0, 0X41, 0XC0, 0X41, 0XC8, + 0X00, 0XD0, 0X00, 0XE0, 0X00, 0XE0, 0X00, 0XD8, 0X00, 0XD0, 0X00, 0XB8, 0X00, 0XA8, 0X41, 0X88, + 0X82, 0X48, 0X82, 0X10, 0X82, 0X10, 0X00, 0X00, 0X45, 0X29, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, + 0XBE, 0XF7, 0XF3, 0X9C, 0X82, 0X10, 0XC3, 0X18, 0X45, 0X29, 0X86, 0X31, 0XC7, 0X31, 0X30, 0X7C, + 0XF3, 0XDC, 0X86, 0XE1, 0X00, 0XF0, 0X00, 0XF8, 0X41, 0XF8, 0X41, 0XF8, 0X00, 0XF8, 0X00, 0XF8, + 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, + 0X00, 0XE8, 0X00, 0XE0, 0X00, 0XE0, 0X00, 0XD8, 0X00, 0XC8, 0X41, 0XA0, 0X8A, 0X9A, 0X0C, 0X63, + 0X04, 0X11, 0X82, 0X10, 0X82, 0X10, 0X41, 0X08, 0X00, 0X00, 0X4D, 0X6B, 0X7D, 0XEF, 0XFF, 0XFF, + 0XFB, 0XDE, 0X08, 0X42, 0X42, 0X10, 0X45, 0X29, 0X86, 0X31, 0X86, 0X31, 0X49, 0X4A, 0X38, 0XBE, + 0XFF, 0XFF, 0X38, 0XD6, 0X86, 0XA9, 0X00, 0XC8, 0X00, 0XE0, 0X00, 0XF0, 0X00, 0XF8, 0X00, 0XF8, + 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF0, 0X00, 0XF0, + 0X00, 0XE8, 0X00, 0XE0, 0X00, 0XD0, 0XC3, 0X98, 0X8A, 0X8A, 0XB2, 0XA4, 0XBA, 0XC6, 0XF7, 0XB5, + 0X08, 0X42, 0X41, 0X08, 0X82, 0X10, 0X41, 0X08, 0X00, 0X00, 0X45, 0X29, 0XF7, 0XBD, 0XFF, 0XFF, + 0X71, 0X8C, 0X41, 0X08, 0X04, 0X21, 0X45, 0X29, 0X86, 0X31, 0X86, 0X31, 0X0C, 0X63, 0X3C, 0XE7, + 0XFF, 0XFF, 0X79, 0XD6, 0X46, 0XB9, 0X00, 0XE0, 0X42, 0XC8, 0X82, 0XA8, 0X82, 0XB0, 0X41, 0XD8, + 0X82, 0XE8, 0X82, 0XF0, 0X41, 0XE8, 0X41, 0XE8, 0X41, 0XE8, 0X41, 0XF0, 0X41, 0XE8, 0X41, 0XD8, + 0X04, 0XC1, 0X08, 0X92, 0X4D, 0X8B, 0X34, 0XA5, 0XFB, 0XC6, 0XFB, 0XD6, 0XBA, 0XCE, 0X3C, 0XE7, + 0X30, 0X84, 0XC3, 0X18, 0X41, 0X08, 0X41, 0X08, 0X00, 0X00, 0X41, 0X08, 0XCF, 0X7B, 0X7D, 0XEF, + 0X49, 0X4A, 0X00, 0X00, 0X04, 0X21, 0X45, 0X29, 0X46, 0X31, 0X86, 0X31, 0X30, 0X84, 0XFF, 0XFF, + 0XFF, 0XF7, 0XF7, 0XDD, 0X09, 0XDA, 0X83, 0XF8, 0X01, 0XF0, 0X42, 0XC0, 0X82, 0X98, 0X49, 0X9A, + 0XF3, 0XB4, 0XF3, 0XCC, 0X71, 0XBC, 0X8E, 0XBB, 0X8E, 0XBB, 0X30, 0XBC, 0X71, 0XBC, 0XF3, 0XBC, + 0XB6, 0XBD, 0XFB, 0XCE, 0XBE, 0XE7, 0X7D, 0XE7, 0X3B, 0XDF, 0XBA, 0XD6, 0X79, 0XCE, 0XFB, 0XDE, + 0X75, 0XAD, 0X86, 0X31, 0X41, 0X08, 0X41, 0X08, 0X00, 0X00, 0X00, 0X00, 0X49, 0X4A, 0XFB, 0XDE, + 0X04, 0X21, 0X41, 0X08, 0X04, 0X21, 0X45, 0X29, 0X45, 0X29, 0X87, 0X39, 0XB2, 0X94, 0XFF, 0XFF, + 0XBE, 0XF7, 0X34, 0XDD, 0X0C, 0XEB, 0X09, 0XFA, 0X00, 0XF0, 0X01, 0XD8, 0X00, 0XD8, 0X8B, 0XD2, + 0X7D, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XBE, 0XFF, 0X7D, 0XEF, 0XFB, 0XDE, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XBA, 0XD6, + 0X78, 0XC6, 0XC7, 0X39, 0X00, 0X00, 0X41, 0X08, 0X00, 0X00, 0X00, 0X00, 0XC7, 0X39, 0X79, 0XCE, + 0X00, 0X00, 0X82, 0X10, 0XC3, 0X18, 0X04, 0X21, 0X05, 0X29, 0X86, 0X31, 0XB3, 0X9C, 0XFF, 0XFF, + 0XFF, 0XF7, 0X75, 0XDD, 0XC7, 0XE9, 0XC7, 0XF9, 0X01, 0XF8, 0X01, 0XF0, 0X00, 0XE8, 0X49, 0XE2, + 0XFB, 0XEE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, 0XFB, 0XDE, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XBA, 0XD6, + 0XB9, 0XCE, 0X08, 0X42, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0XC7, 0X39, 0X38, 0XC6, + 0X00, 0X00, 0X82, 0X10, 0X82, 0X10, 0X04, 0X21, 0X04, 0X21, 0X45, 0X29, 0X30, 0X84, 0XFF, 0XFF, + 0XFF, 0XFF, 0X38, 0XDE, 0XC4, 0XD0, 0X00, 0XF0, 0X01, 0XF8, 0X00, 0XF8, 0X00, 0XF0, 0X08, 0XD2, + 0XFB, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0XBA, 0XD6, + 0X79, 0XCE, 0XC7, 0X39, 0X41, 0X08, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X86, 0X31, 0X38, 0XC6, + 0X00, 0X00, 0X00, 0X00, 0XC3, 0X18, 0XCB, 0X5A, 0X86, 0X31, 0XC3, 0X18, 0XCB, 0X5A, 0X7D, 0XEF, + 0XFF, 0XFF, 0X7D, 0XEF, 0XCF, 0XBB, 0XC3, 0XB0, 0X41, 0XD0, 0X41, 0XD0, 0X82, 0XB8, 0X4D, 0XB3, + 0X7D, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XBE, 0XF7, 0XBE, 0XF7, 0X3D, 0XEF, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0XFA, 0XD6, + 0XF7, 0XBD, 0X04, 0X21, 0X86, 0X31, 0X04, 0X21, 0X00, 0X00, 0X00, 0X00, 0X86, 0X31, 0X38, 0XC6, + 0X86, 0X31, 0XC3, 0X18, 0XCB, 0X5A, 0X75, 0XAD, 0XCF, 0X7B, 0X41, 0X08, 0X86, 0X31, 0XF7, 0XBD, + 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XEF, 0X74, 0XB5, 0X30, 0X9C, 0X30, 0X9C, 0X72, 0XA4, 0XBB, 0XD6, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XBE, 0XF7, 0X7D, 0XEF, 0X3C, 0XE7, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0X3C, 0XE7, + 0X71, 0X8C, 0X81, 0X08, 0X0C, 0X63, 0XCF, 0X7B, 0X82, 0X10, 0X00, 0X00, 0X8A, 0X52, 0X38, 0XC6, + 0X75, 0XAD, 0X71, 0X8C, 0XB6, 0XB5, 0X3C, 0XE7, 0XFB, 0XDE, 0XC7, 0X39, 0X00, 0X00, 0XCF, 0X73, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, + 0X7D, 0XEF, 0X7D, 0XEF, 0X3B, 0XDF, 0XFA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0XFB, 0XDE, 0XB9, 0XCE, + 0XC7, 0X39, 0XC4, 0X20, 0X71, 0X8C, 0XBA, 0XD6, 0X71, 0X8C, 0XCB, 0X5A, 0XB2, 0X94, 0XBA, 0XD6, + 0XFF, 0XFF, 0X7D, 0XEF, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XB6, 0XB5, 0X46, 0X29, 0X05, 0X19, + 0X75, 0XA5, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, + 0X7D, 0XEF, 0X3C, 0XE7, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XBA, 0XD6, 0XFC, 0XDE, 0X4E, 0X63, + 0X42, 0X08, 0X0C, 0X63, 0XF7, 0XBD, 0XBE, 0XF7, 0XFF, 0XFF, 0XFB, 0XDE, 0XFB, 0XDE, 0XBE, 0XF7, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XF4, 0X9C, 0X04, 0X21, + 0X05, 0X21, 0XB6, 0XA5, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XBE, 0XF7, 0X7D, 0XEF, + 0X3C, 0XE7, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XFB, 0XDE, 0XBB, 0XD6, 0XD1, 0X73, 0X83, 0X18, + 0X86, 0X39, 0X34, 0X9D, 0XBD, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XFF, 0X35, 0XD6, 0XEB, 0XCC, 0X43, 0XB3, + 0X40, 0X51, 0X05, 0X19, 0XF5, 0X8C, 0XBE, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XBE, 0XF7, 0X7D, 0XEF, 0X7D, 0XEF, 0X3C, 0XE7, + 0XFB, 0XDE, 0XBA, 0XDE, 0XBA, 0XD6, 0X3C, 0XDF, 0X3A, 0XBE, 0X4F, 0X63, 0X82, 0X49, 0X40, 0XA3, + 0X23, 0XB4, 0XCC, 0X83, 0X3A, 0XBE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBF, 0XF7, 0XB5, 0XBD, 0X82, 0X92, 0X20, 0XF4, 0XA0, 0XFC, + 0X60, 0XE4, 0X40, 0X82, 0X84, 0X41, 0X8F, 0X6B, 0X77, 0XAD, 0X3D, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFE, 0XFF, 0XBE, 0XF7, 0XBE, 0XF7, 0XBE, 0XF7, 0X7D, 0XEF, 0X7D, 0XEF, 0X3C, 0XE7, 0XFB, 0XDE, + 0XFB, 0XDE, 0X3D, 0XE7, 0XBB, 0XCE, 0X36, 0X9D, 0X0B, 0X6B, 0X41, 0X6A, 0X60, 0XC4, 0X20, 0XFE, + 0X60, 0XF5, 0X00, 0X8B, 0XC7, 0X6A, 0X38, 0XC6, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0X4B, 0X7B, 0X80, 0XB2, 0XA0, 0XFC, 0XA0, 0XFC, + 0XE0, 0XFC, 0XE0, 0XFC, 0XC0, 0XCB, 0XC1, 0X8A, 0X45, 0X62, 0X4D, 0X6B, 0XB3, 0X94, 0XF7, 0XBD, + 0X3D, 0XDF, 0XFF, 0XF7, 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, 0X7D, 0XEF, 0X7D, 0XE7, 0X3D, 0XDF, + 0XBA, 0XC6, 0X75, 0XA5, 0X8D, 0X7B, 0X84, 0X7A, 0X40, 0XB3, 0XE0, 0XEC, 0XE0, 0XFD, 0XE0, 0XFD, + 0X60, 0XF5, 0X20, 0XE5, 0XA0, 0XD4, 0X0A, 0X6B, 0XFB, 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0XCC, 0X93, 0X40, 0XEB, 0X60, 0XFC, 0XA0, 0XFC, + 0XE0, 0XFC, 0X20, 0XFD, 0X60, 0XFD, 0X20, 0XF5, 0XA0, 0XD4, 0XC0, 0XBB, 0X42, 0X9B, 0X45, 0X8B, + 0X6B, 0X9C, 0XAE, 0X9C, 0X71, 0X8C, 0XB3, 0X94, 0X33, 0X9D, 0X34, 0XA5, 0XF2, 0XA4, 0XF0, 0XB4, + 0XCA, 0X9B, 0X04, 0X9B, 0X40, 0XBB, 0X20, 0XE4, 0X20, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XE0, 0XFD, + 0XE0, 0XFD, 0XE0, 0XFD, 0X20, 0XC4, 0X88, 0X5A, 0X38, 0XBE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X78, 0XD6, 0X46, 0XAB, 0X40, 0XDB, 0X20, 0XF4, + 0X60, 0XFC, 0XA0, 0XFC, 0XE0, 0XFC, 0X60, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X20, 0XF5, 0XA0, 0XDC, + 0XC0, 0XB3, 0XC0, 0X51, 0X86, 0X29, 0X0D, 0X63, 0X8F, 0X7B, 0X0D, 0X5B, 0XC7, 0X41, 0X01, 0X82, + 0X00, 0XC3, 0XC0, 0XE3, 0X60, 0XFC, 0XA0, 0XFC, 0XE0, 0XFC, 0XE0, 0XFC, 0X60, 0XF5, 0X60, 0XF5, + 0X20, 0XE5, 0X80, 0X9B, 0X86, 0X62, 0X30, 0X84, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X38, 0XC6, 0X2D, 0X9C, 0X05, 0X93, + 0X43, 0XA3, 0X82, 0XB3, 0XC2, 0XBB, 0XC2, 0XBB, 0X22, 0XB4, 0X82, 0XA3, 0X42, 0X93, 0XC3, 0X7A, + 0X85, 0X62, 0X0B, 0X63, 0X71, 0X84, 0XB6, 0XB5, 0X79, 0XCE, 0X79, 0XC6, 0XB5, 0XAD, 0X70, 0X94, + 0X4A, 0X8B, 0X06, 0X83, 0X04, 0X93, 0X04, 0X9B, 0X43, 0X9B, 0X43, 0X9B, 0X43, 0X93, 0X04, 0X83, + 0X08, 0X73, 0X8D, 0X73, 0XB3, 0X94, 0X79, 0XCE, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XDF, 0X38, 0XBE, + 0X75, 0XB5, 0X33, 0XA5, 0X33, 0XA5, 0XF3, 0X9C, 0XF3, 0X9C, 0XF3, 0X9C, 0XF3, 0X94, 0XF3, 0X9C, + 0X35, 0XA5, 0XF8, 0XBD, 0XFB, 0XDE, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7E, 0XEF, + 0XBB, 0XD6, 0XF8, 0XBD, 0XB6, 0XAD, 0X75, 0XAD, 0X34, 0XA5, 0X33, 0X9D, 0X34, 0X9D, 0X35, 0XA5, + 0XB7, 0XAD, 0X79, 0XC6, 0X3C, 0XE7, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, +}; + +const unsigned char PROGMEM icon_40x40[3200] = { /* 0X00,0X10,0X28,0X00,0X28,0X00,0X01,0X1B, */ + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X5D, 0XEF, 0X71, 0X8C, 0X31, 0X84, 0X31, 0X84, + 0X93, 0XC5, 0X92, 0XCD, 0X91, 0XCD, 0X91, 0XD5, 0X91, 0XD5, 0X91, 0XCD, 0X72, 0XCD, 0X72, 0XC5, + 0X56, 0XDE, 0XBE, 0XFF, 0XDB, 0XDE, 0XFB, 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XCE, 0X7B, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, + 0X00, 0X5A, 0X20, 0XDD, 0X20, 0XDD, 0X20, 0XDD, 0X20, 0XDD, 0X20, 0XDD, 0XE0, 0XD4, 0XA0, 0XD4, + 0X61, 0XA3, 0XA7, 0X39, 0XE5, 0X18, 0X05, 0X21, 0X92, 0X94, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XF9, 0XEE, 0XEB, 0X9B, 0XA1, 0X18, 0X23, 0X73, 0X81, 0XC5, 0X21, 0X9C, + 0X61, 0X39, 0X81, 0XEE, 0X40, 0XFF, 0XE0, 0XFE, 0XE0, 0XFE, 0XE0, 0XFE, 0X40, 0XFF, 0XC0, 0XF6, + 0XC0, 0X49, 0XA0, 0X18, 0X00, 0X42, 0X60, 0X18, 0X00, 0X00, 0X74, 0XB5, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0X93, 0XCD, 0XC3, 0XBB, 0XA0, 0X51, 0XE1, 0X39, 0XC2, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, + 0X63, 0XBD, 0X61, 0XE6, 0X40, 0XFF, 0XE0, 0XFE, 0XE0, 0XFE, 0XC0, 0XFE, 0X60, 0XFF, 0X21, 0X73, + 0XE1, 0X28, 0X81, 0XEE, 0X61, 0XFF, 0X21, 0XEE, 0XA0, 0X41, 0X20, 0X08, 0X90, 0XCD, 0XDE, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X5C, 0XF7, + 0X0B, 0XAC, 0XC0, 0XB3, 0XA1, 0XEE, 0XC3, 0X5A, 0X22, 0X8C, 0XE1, 0XFF, 0X40, 0XFF, 0X40, 0XFF, + 0XC0, 0XFF, 0X80, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0X20, 0XFF, 0XA1, 0XAC, + 0X21, 0XC5, 0X20, 0XFF, 0X60, 0XFE, 0X00, 0XFF, 0X02, 0XDE, 0XE0, 0X20, 0X40, 0X82, 0X49, 0XBC, + 0X3B, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X5C, 0XF7, 0X67, 0X9B, + 0XE0, 0XB3, 0X81, 0XFF, 0XC3, 0XFF, 0X83, 0X9C, 0X82, 0XDE, 0XC0, 0XFF, 0X60, 0XFF, 0X60, 0XFF, + 0X40, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0X60, 0XFF, + 0X40, 0XFF, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0XE0, 0XFE, 0XA2, 0XB4, 0X41, 0XBC, 0X20, 0XCC, + 0X87, 0XA3, 0XB8, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X9D, 0XF7, 0XA8, 0XA3, 0X60, 0XBC, + 0XA2, 0XFF, 0XA5, 0XFF, 0X44, 0XFF, 0XA1, 0XFF, 0XA0, 0XFF, 0X60, 0XFF, 0X80, 0XFF, 0X80, 0XFF, + 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, + 0X00, 0XFF, 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0X60, 0XFE, 0X20, 0XFE, 0X40, 0XFE, + 0XE0, 0XCB, 0XE3, 0X92, 0X7C, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X4C, 0XAC, 0XC0, 0XB3, 0XA4, 0XFF, + 0XA6, 0XFF, 0X45, 0XFF, 0X62, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, + 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, + 0X20, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, 0X80, 0XFE, 0X60, 0XFE, 0X40, 0XFE, 0X20, 0XFE, 0X00, 0XFE, + 0XE0, 0XFD, 0XE0, 0XC3, 0X2A, 0XAC, 0X7D, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XD4, 0XD5, 0X40, 0XAB, 0X43, 0XFF, 0XA8, 0XFF, + 0X67, 0XFF, 0X62, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, + 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X40, 0XFF, + 0X40, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0X20, 0XFE, 0XE0, 0XFD, + 0XE0, 0XFD, 0XC0, 0XFD, 0XA0, 0XA2, 0X11, 0XBD, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XDA, 0XE6, 0XE4, 0X9A, 0XE1, 0XE5, 0XE8, 0XFF, 0X69, 0XFF, + 0X65, 0XFF, 0X60, 0XFF, 0X80, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, + 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, + 0X40, 0XFF, 0X00, 0XFF, 0X00, 0XFF, 0X20, 0XFF, 0XE0, 0XFE, 0X60, 0XFE, 0X20, 0XFE, 0X00, 0XFE, + 0XC0, 0XFD, 0XE0, 0XFD, 0XE0, 0XE4, 0X85, 0XAB, 0XFA, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X2B, 0XB4, 0XC0, 0XB3, 0XC8, 0XFF, 0X8C, 0XFF, 0X68, 0XFF, + 0X61, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0XE1, 0XFF, 0XA1, 0XDE, 0X61, 0XEF, + 0XE1, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X60, 0XFF, + 0X40, 0XFF, 0X60, 0XFF, 0XC0, 0XFF, 0X61, 0XDE, 0X00, 0XE6, 0X80, 0XFE, 0X40, 0XFE, 0X00, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0XE0, 0XFD, 0XC0, 0XC3, 0XE9, 0XAB, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0X5D, 0XEF, 0XA3, 0XAB, 0XA3, 0XF6, 0XCC, 0XFF, 0X4C, 0XFF, 0X64, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0X61, 0XEF, 0X22, 0X6B, 0X82, 0X5A, 0X82, 0XB5, + 0XE2, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X60, 0XFF, + 0XA0, 0XFF, 0XE1, 0XFF, 0X42, 0X8C, 0XC1, 0X41, 0X21, 0XA4, 0XA0, 0XFE, 0X80, 0XFE, 0X20, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0XA0, 0XFD, 0X20, 0XF5, 0XC0, 0X9A, 0X35, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0X51, 0XC5, 0X60, 0XBC, 0XC9, 0XFF, 0X8E, 0XFF, 0X6A, 0XFF, 0X61, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE1, 0XFF, 0XE1, 0X62, 0X80, 0X10, 0X05, 0XE7, 0XA4, 0XF7, + 0XE4, 0XFF, 0XE3, 0XFF, 0XE2, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, + 0XC1, 0XFF, 0XE2, 0X83, 0X40, 0X08, 0X22, 0XCE, 0X60, 0XF7, 0XA0, 0XFE, 0X60, 0XFE, 0X20, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0XA0, 0XFD, 0XA0, 0XC3, 0XAC, 0XBC, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XDE, 0XFF, 0XA7, 0XAB, 0X81, 0XDD, 0XED, 0XFF, 0XB0, 0XFF, 0X69, 0XFF, 0X60, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0X61, 0XD6, 0X22, 0X29, 0XA6, 0X31, 0XE3, 0X7B, 0X46, 0XEF, + 0XE6, 0XFF, 0XE4, 0XFF, 0XE2, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, + 0X81, 0XD6, 0XA0, 0X18, 0XC4, 0X18, 0XA1, 0X62, 0XC1, 0XCD, 0X40, 0XFF, 0X60, 0XFE, 0X20, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0X80, 0XFD, 0XA0, 0XEC, 0X48, 0XBC, 0XDF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XF9, 0XE6, 0XE3, 0X9A, 0X67, 0XEE, 0XD1, 0XFF, 0XB0, 0XFF, 0X86, 0XFF, 0X60, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0X60, 0X94, 0X91, 0X73, 0XD9, 0XBD, 0X00, 0X00, 0X05, 0X84, + 0XE8, 0XFF, 0XE5, 0XFF, 0XE3, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, + 0X20, 0XAD, 0XE9, 0X41, 0XB7, 0XB5, 0X01, 0X00, 0X60, 0X62, 0X21, 0XFF, 0X80, 0XFE, 0X20, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X20, 0XF5, 0XE3, 0XBB, 0XD9, 0XE6, 0XFF, 0XFF, + 0XFF, 0XFF, 0XD3, 0XCD, 0X40, 0XA3, 0X2B, 0XF7, 0XD3, 0XFF, 0XB0, 0XFF, 0X63, 0XFF, 0X60, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0XA0, 0X9C, 0X30, 0X6B, 0X97, 0XB5, 0X00, 0X00, 0X83, 0X52, + 0XC6, 0XFF, 0XE5, 0XFF, 0XE3, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, + 0X20, 0XAD, 0XEA, 0X41, 0X77, 0XAD, 0X01, 0X00, 0XC0, 0X49, 0XE0, 0XF6, 0XA0, 0XFE, 0X20, 0XFE, + 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0XA0, 0XBB, 0XD3, 0XCD, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0X00, 0XB4, 0X8E, 0XFF, 0XF4, 0XFF, 0XB0, 0XFF, 0X42, 0XFF, 0X60, 0XFF, + 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0XA1, 0XDE, 0X01, 0X21, 0X00, 0X00, 0X00, 0X00, 0X25, 0X8C, + 0XE5, 0XFF, 0XE3, 0XFF, 0XE2, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, + 0XE1, 0XDE, 0X01, 0X21, 0X00, 0X00, 0X00, 0X00, 0X61, 0X5A, 0X20, 0XFF, 0X80, 0XFE, 0X20, 0XFE, + 0X00, 0XFE, 0XE0, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0XC0, 0XCB, 0X71, 0XCD, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0X40, 0XC4, 0XB0, 0XFF, 0XF5, 0XFF, 0X8F, 0XFF, 0X41, 0XFF, 0X80, 0XFF, + 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0XE1, 0XFF, 0X21, 0X8C, 0X60, 0X10, 0X43, 0X6B, 0X44, 0XEF, + 0XE2, 0XFF, 0XE2, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, + 0XE1, 0XFF, 0XC1, 0XA4, 0XC2, 0X18, 0XA2, 0X39, 0XA1, 0XCD, 0X20, 0XFF, 0X60, 0XFE, 0X20, 0XFE, + 0XC0, 0XFD, 0X80, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0XE0, 0XCB, 0X91, 0XCD, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0X40, 0XC4, 0XD2, 0XFF, 0XF7, 0XFF, 0XAF, 0XFF, 0X01, 0XFF, 0X00, 0XFF, + 0X00, 0XFF, 0X40, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0XA1, 0XFF, 0X82, 0XD6, 0XC2, 0XFF, 0XE0, 0XFF, + 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X60, 0XFF, + 0X60, 0XFF, 0XC1, 0XFF, 0X82, 0XDE, 0XC2, 0XEE, 0X61, 0XFF, 0X80, 0XFE, 0XC0, 0XFD, 0X20, 0XFD, + 0XA1, 0XFC, 0X61, 0XFC, 0X61, 0XFC, 0XC0, 0XFC, 0X60, 0XFD, 0XE0, 0XCB, 0X51, 0XC5, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0X60, 0XC4, 0XD4, 0XFF, 0XF9, 0XFF, 0X2D, 0XFF, 0X00, 0XFE, 0XC0, 0XFD, + 0XA1, 0XFD, 0X21, 0XFE, 0XE0, 0XFE, 0XC0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, + 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, + 0X40, 0XFF, 0X40, 0XFF, 0X80, 0XFF, 0X20, 0XFF, 0XA0, 0XFE, 0X20, 0XFE, 0X01, 0XFD, 0X01, 0XFC, + 0X62, 0XFB, 0X42, 0XFB, 0X82, 0XFB, 0X21, 0XFC, 0X20, 0XFD, 0X00, 0XD4, 0X71, 0XC5, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0X20, 0XC4, 0XD4, 0XFF, 0XBA, 0XFF, 0X2E, 0XFE, 0XE1, 0XFC, 0X61, 0XFC, + 0X61, 0XFC, 0X01, 0XFD, 0X01, 0XFE, 0X20, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, + 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X40, 0XFF, + 0X40, 0XFF, 0X00, 0XFF, 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X80, 0XFD, 0X61, 0XFC, 0X62, 0XFB, + 0XA3, 0XFA, 0XA3, 0XFA, 0X42, 0XFB, 0X01, 0XFC, 0XE0, 0XFC, 0XE0, 0XCB, 0X71, 0XCD, 0XFF, 0XFF, + 0XFF, 0XFF, 0X50, 0XCD, 0XC0, 0XB3, 0XB3, 0XFF, 0X7A, 0XFF, 0X91, 0XFD, 0X03, 0XFC, 0X02, 0XFB, + 0X22, 0XFB, 0X62, 0XFC, 0X81, 0XFD, 0XC0, 0XFE, 0XA0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, + 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, + 0X20, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, 0XA0, 0XFE, 0X60, 0XFE, 0X60, 0XFD, 0X41, 0XFC, 0X62, 0XFB, + 0XC3, 0XFA, 0XA3, 0XFA, 0X42, 0XFB, 0X01, 0XFC, 0X20, 0XFD, 0XC0, 0XCB, 0X91, 0XCD, 0XFF, 0XFF, + 0XFF, 0XFF, 0X14, 0XD6, 0X20, 0XAB, 0X51, 0XF7, 0XBE, 0XFF, 0X17, 0XFE, 0X65, 0XFC, 0X61, 0XFB, + 0XA2, 0XFB, 0XA1, 0XFC, 0XC1, 0XFD, 0X00, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, + 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X20, 0XFF, + 0X00, 0XFF, 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X60, 0XFE, 0XC0, 0XFD, 0XC0, 0XFC, 0X41, 0XFC, + 0XC1, 0XFB, 0XA2, 0XFB, 0X01, 0XFC, 0XA0, 0XFC, 0X40, 0XFD, 0XA0, 0XC3, 0XF4, 0XD5, 0XFF, 0XFF, + 0XFF, 0XFF, 0X5B, 0XEF, 0X24, 0X9B, 0X49, 0XE6, 0XB8, 0XFF, 0X92, 0XFE, 0X25, 0XFD, 0XA0, 0XFC, + 0X02, 0XFD, 0XE1, 0XFD, 0XE0, 0XFE, 0X40, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X60, 0XFF, 0X60, 0XFF, + 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X00, 0XFF, + 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0X40, 0XFE, 0X00, 0XFE, 0X80, 0XFD, 0X01, 0XF5, + 0X41, 0XFD, 0X01, 0XFD, 0XC0, 0XFC, 0X40, 0XFD, 0X00, 0XF5, 0XC4, 0XBB, 0XFA, 0XE6, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0X2A, 0XB4, 0XA0, 0XD4, 0XA2, 0XFE, 0X20, 0XFE, 0XE0, 0XFD, 0X00, 0XFE, + 0X80, 0XFE, 0X21, 0XEE, 0X41, 0XE6, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, + 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, + 0XA0, 0XFE, 0X80, 0XFE, 0X60, 0XFE, 0X40, 0XFE, 0X00, 0XFE, 0X00, 0XFE, 0X00, 0XFE, 0X40, 0XCC, + 0XE1, 0XAB, 0XC1, 0XED, 0X80, 0XFD, 0X60, 0XFD, 0X60, 0XE4, 0X29, 0XB4, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0X15, 0XD6, 0XE0, 0XBB, 0X60, 0XFE, 0XC8, 0XFE, 0XC8, 0XFE, 0X02, 0XFF, + 0X60, 0XDD, 0X40, 0XA3, 0XA1, 0XDD, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, + 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, 0XC0, 0XFE, 0XA0, 0XFE, + 0X80, 0XFE, 0X60, 0XFE, 0X40, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X40, 0XED, + 0XC0, 0X9A, 0X40, 0XA3, 0X80, 0XF5, 0X60, 0XFD, 0X60, 0XBB, 0XEE, 0XBC, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XDF, 0XFF, 0X63, 0XAB, 0X42, 0XE5, 0XB4, 0XFF, 0X97, 0XFF, 0XAA, 0XF6, + 0X80, 0XAB, 0XA0, 0X92, 0XA1, 0XDD, 0X41, 0XFF, 0X40, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X60, 0XFF, + 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, + 0XC0, 0XFE, 0X80, 0XFE, 0X61, 0XFE, 0X00, 0XFE, 0XA0, 0XED, 0X20, 0XE5, 0X21, 0XCC, 0X80, 0XB3, + 0X00, 0XBC, 0XE0, 0XC3, 0X40, 0XED, 0XC0, 0XEC, 0X60, 0X92, 0X97, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X0F, 0XC5, 0X00, 0XA3, 0XAA, 0XF6, 0X93, 0XFF, 0X2D, 0XEE, + 0X63, 0XDD, 0X80, 0XD5, 0X42, 0XB4, 0X82, 0XCC, 0X00, 0XCD, 0X40, 0XD5, 0XA0, 0XDD, 0XE1, 0XE5, + 0XC1, 0XE5, 0XC1, 0XE5, 0XC1, 0XE5, 0XC1, 0XE5, 0X80, 0XDD, 0X60, 0XDD, 0X20, 0XD5, 0XC0, 0XCC, + 0XA0, 0XCC, 0X61, 0XC4, 0X21, 0XC4, 0X01, 0XBC, 0X01, 0XBC, 0XE0, 0XBB, 0XC0, 0XBB, 0X60, 0XD4, + 0X80, 0XFD, 0X40, 0XFD, 0X80, 0XFD, 0X80, 0XBB, 0X2B, 0XAC, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X9D, 0XF7, 0X87, 0XA3, 0X60, 0XD4, 0X0A, 0XFF, 0XCF, 0XFE, + 0XC9, 0XFE, 0XC0, 0XFE, 0XC0, 0XF6, 0X40, 0XE6, 0X41, 0XCD, 0X42, 0XB4, 0XC1, 0XAB, 0X60, 0XA3, + 0X60, 0XA3, 0X80, 0XA3, 0X80, 0XA3, 0X80, 0XA3, 0XA0, 0XAB, 0XC1, 0XAB, 0XE1, 0XB3, 0X22, 0XB4, + 0X82, 0XC4, 0XC0, 0XCC, 0X00, 0XD5, 0X60, 0XE5, 0X81, 0XED, 0X80, 0XF5, 0X80, 0XFD, 0X80, 0XFD, + 0X40, 0XFD, 0X80, 0XFD, 0X80, 0XE4, 0X85, 0XAB, 0X5C, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFA, 0XE6, 0X23, 0XA3, 0XE0, 0XE4, 0XE8, 0XFE, + 0X6A, 0XFE, 0X05, 0XFE, 0X40, 0XFE, 0XA0, 0XFE, 0XC0, 0XFE, 0XE1, 0XFE, 0XA0, 0XF6, 0XA0, 0XF6, + 0XA0, 0XF6, 0XA0, 0XF6, 0X80, 0XF6, 0X80, 0XF6, 0X80, 0XF6, 0X60, 0XF6, 0X61, 0XFE, 0X81, 0XFE, + 0X61, 0XFE, 0X20, 0XFE, 0X00, 0XFE, 0XC0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X20, 0XFD, 0X20, 0XFD, + 0X60, 0XFD, 0X20, 0XF5, 0XA0, 0XA2, 0XB4, 0XCD, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X52, 0XC5, 0XE0, 0XA2, 0XA1, 0XF5, + 0X86, 0XFE, 0X06, 0XFE, 0XE2, 0XFD, 0XE0, 0XFD, 0X00, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, + 0X40, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X00, 0XFE, 0XE0, 0XFD, 0XE0, 0XFD, 0XC0, 0XFD, + 0XA0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X40, 0XFD, + 0X60, 0XFD, 0X60, 0XBB, 0X6C, 0XB4, 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X92, 0XCD, 0XC0, 0XA2, + 0X20, 0XED, 0X22, 0XFE, 0XC1, 0XFD, 0XA0, 0XFD, 0XC0, 0XFD, 0XE0, 0XFD, 0XE0, 0XFD, 0XE0, 0XFD, + 0XE0, 0XFD, 0XE0, 0XFD, 0XC0, 0XFD, 0XC0, 0XFD, 0XC0, 0XFD, 0XC0, 0XFD, 0XA0, 0XFD, 0X80, 0XFD, + 0X80, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X60, 0XFD, 0X40, 0XFD, + 0X20, 0XB3, 0XEA, 0XA3, 0X9D, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X8E, 0XBC, + 0XE1, 0XA2, 0X00, 0XE5, 0XE0, 0XFD, 0XC0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, + 0XC0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0X80, 0XFD, 0X80, 0XFD, 0X60, 0XFD, + 0X40, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X80, 0XFD, 0X00, 0XF5, 0X40, 0XBB, + 0X2B, 0XAC, 0X9D, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0X35, 0XD6, 0XE2, 0X9A, 0XA0, 0XC3, 0XA0, 0XFD, 0XE0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X80, 0XFD, + 0X80, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X40, 0XFD, + 0X20, 0XFD, 0X20, 0XFD, 0X40, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X00, 0XD4, 0XC1, 0X9A, 0X10, 0XC5, + 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0X98, 0XDE, 0X2B, 0XAC, 0X40, 0XB3, 0X00, 0XD4, 0X40, 0XFD, 0X80, 0XFD, 0X80, 0XFD, + 0X60, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, + 0X40, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X40, 0XDC, 0X80, 0XBB, 0XE8, 0XAB, 0X57, 0XDE, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XDF, 0XFF, 0X37, 0XD6, 0X86, 0XA3, 0XC0, 0X9A, 0XE0, 0XCB, 0X80, 0XEC, + 0XE0, 0XF4, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X00, 0XF5, + 0XA0, 0XEC, 0X00, 0XD4, 0X40, 0XB3, 0X03, 0X9B, 0X92, 0XC5, 0XBD, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XF5, 0XCD, 0XAD, 0XBC, 0X69, 0XBC, + 0X05, 0XBC, 0X03, 0XC4, 0X01, 0XC4, 0X01, 0XC4, 0X01, 0XC4, 0X01, 0XC4, 0XE2, 0XC3, 0X24, 0XC4, + 0X68, 0XBC, 0XAC, 0XBC, 0XD3, 0XCD, 0X9E, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0X5B, 0XEF, 0X98, 0XDE, 0X56, 0XD6, 0X57, 0XD6, 0X57, 0XD6, 0X56, 0XD6, 0X77, 0XDE, 0X1B, 0XEF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, +}; + diff --git a/examples/readpixel_kbv/readpixel_kbv.ino b/examples/readpixel_kbv/readpixel_kbv.ino new file mode 100644 index 0000000..0fea603 --- /dev/null +++ b/examples/readpixel_kbv/readpixel_kbv.ino @@ -0,0 +1,135 @@ +#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 + +#include // Hardware-specific library +#include +MCUFRIEND_kbv tft; + +//#include // Hardware-specific library +//Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); +//Adafruit_TFTLCD tft; + +// 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); +void loop(void); + +uint16_t g_identifier; + +void setup(void) { + tft.reset(); + g_identifier = tft.readID(); + + Serial.begin(9600); + Serial.print("readID = 0x"); + Serial.println(g_identifier, HEX); + if (g_identifier == 0xFFFF) g_identifier = 0x9341; + if (g_identifier == 0) { + Serial.println("Unknown ID"); + while (1); + } + + tft.begin(g_identifier); + tft.setRotation(0); +} + +uint16_t colors[] = { + BLACK, BLUE +}; + +void colordump(uint16_t x, uint16_t y) +{ + uint16_t pixel, pixels[32]; + char i, j, buf[20], dirty; + uint8_t wid = (tft.width() - 9 * 6)/ (5 * 6), ht = (tft.height() / 8) - 1; + tft.setTextColor(WHITE); + tft.setTextSize(1); + for (j = 0; j < ht; j++) { + sprintf(buf, "%3d,%3d:", x, y + j); + tft.print(buf); + dirty = 1; + for (i = 0; i < wid; i++) { +#if 1 && defined(MCUFRIEND_KBV_H_) + if (dirty) tft.readGRAM(x, y + j, pixels, wid, 1); + dirty = 0; + pixel = pixels[i]; +#else + pixel = tft.readPixel(x + i, y + j); +#endif + tft.print(" "); + if (pixel == WHITE) tft.setTextColor(GREEN); + sprintf(buf, "%04X", pixel); + tft.print(buf); + tft.setTextColor(WHITE); + } + tft.println(); + } +} + +uint16_t bgr(uint16_t color) +{ + return ((color & 0xF800) >> 11) | (color & 0x7E0) | (color & 0x1F) << 11; +} + +void duffcolor(uint16_t color) +{ + uint16_t pixel, x, y; + char done, buf[20]; + uint16_t BGR = bgr(color); + for (done = 0, y = 0; y < 320 && !done; y++) { + for (x= 0; x < 240; x++) { + // pixel = readxy(x, y); + pixel = tft.readPixel(x, y); + if (pixel != BGR) { + done = 1; + sprintf(buf, "0x%04X @ %d, %d", pixel, x, y); + tft.println(buf); + break; + } + } + } +} + +uint8_t aspect; +char *aspectname[] = { + "PORTRAIT", "LANDSCAPE", "PORTRAIT_REV", "LANDSCAPE_REV" +}; + +void loop(void) +{ + uint16_t iter, color; + char buf[80]; + aspect = (aspect + 1) & 3; + tft.setRotation(aspect); + for (iter = 0; iter < sizeof(colors) / sizeof(uint16_t); iter++) { + color = colors[iter]; + tft.fillScreen(color); + tft.setTextColor(WHITE); + tft.setTextSize(1); + tft.setCursor(0, 0); + sprintf(buf, "ID=0x%04X Background=%04X %s", + tft.readID(), color, aspectname[aspect]); + tft.println(buf); + colordump(6 * 6, 0); + // duffcolor(color); + delay(5000); + } +} + + + + + + + diff --git a/examples/scroll_kbv/scroll_kbv.ino b/examples/scroll_kbv/scroll_kbv.ino new file mode 100644 index 0000000..a92db93 --- /dev/null +++ b/examples/scroll_kbv/scroll_kbv.ino @@ -0,0 +1,49 @@ +#include // Hardware-specific library +#include +MCUFRIEND_kbv tft; + +#define BLACK 0x0000 +#define BLUE 0x001F +#define RED 0xF800 +#define GREEN 0x07E0 +#define CYAN 0x07FF +#define MAGENTA 0xF81F +#define YELLOW 0xFFE0 +#define WHITE 0xFFFF + +// work in line numbers. Font height in ht +int16_t ht = 16, top = 3, line, lines = 15, scroll; + +void setup() +{ + tft.reset(); + uint16_t id = tft.readID(); + tft.begin(id); + tft.setRotation(0); //Portrait + tft.fillScreen(BLACK); + tft.setTextColor(WHITE, BLACK); + tft.setTextSize(2); // System font is 8 pixels. ht = 8*2=16 + tft.setCursor(100, 0); + tft.print("ID = 0x"); + tft.println(id, HEX); + if (id == 0x9320 || id == 0x9325 || id == 0xB509) { + top = 0; // these controllers scroll full screen + lines = tft.height() / ht; // we are in portrait mode + } + if (id == 0x7783) { + tft.println("can NOT scroll"); + while (1); // die. + } + tft.setCursor(0, 0); + for (line = 1; line < 21; line++) tft.println(String(line) + ": "); +} + +void loop() +{ + tft.setCursor(0, (scroll + top) * ht); + if (++scroll >= lines) scroll = 0; + tft.vertScroll(top * ht, lines * ht, (scroll) * ht); + tft.println(String(line) + ": [" + String(scroll) + "] "); + delay(100); + line++; +} diff --git a/examples/testcard_kbv/testcard_kbv.ino b/examples/testcard_kbv/testcard_kbv.ino new file mode 100644 index 0000000..27101a4 --- /dev/null +++ b/examples/testcard_kbv/testcard_kbv.ino @@ -0,0 +1,183 @@ +/* + * generate testcard similar to BMP + */ + +#include +#if defined(_GFXFONT_H_) //are we using the new library? +#include +#define ADJ_BASELINE 11 //new fonts setCursor to bottom of letter +#else +#define ADJ_BASELINE 0 //legacy setCursor to top of letter +#endif +#include +MCUFRIEND_kbv tft; + +#define BLACK 0x0000 +#define BLUE 0x001F +#define RED 0xF800 +#define GREEN 0x07E0 +#define CYAN 0x07FF +#define MAGENTA 0xF81F +#define YELLOW 0xFFE0 +#define WHITE 0xFFFF + +#define GREY 0x7BEF + +#include + +uint16_t ID; +uint8_t hh, mm, ss; //containers for current time + +uint8_t conv2d(const char* p) +{ + uint8_t v = 0; + if ('0' <= *p && *p <= '9') v = *p - '0'; + return 10 * v + *++p - '0'; +} + +void setup(void) +{ + Serial.begin(9600); + tft.reset(); + ID = tft.readID(); + Serial.print("TFT ID = 0x"); + Serial.println(ID, HEX); + // if (ID == 0x00D3) ID = 0x9481; // write-only shield + if (ID == 0x00D3) ID = 0x9486; // write-only shield + tft.begin(ID); + tft.setRotation(1); + tft.fillScreen(BLACK); +#if defined(_GFXFONT_H_) + tft.setFont(&FreeSans9pt7b); +#endif + hh = conv2d(__TIME__); + mm = conv2d(__TIME__ + 3); + ss = conv2d(__TIME__ + 6); + +} + +void loop(void) +{ + int16_t x, y, dx, dy, idx; + uint16_t w, h, len, mask; + uint16_t colors[8] = { BLACK, WHITE, YELLOW, CYAN, GREEN, MAGENTA, RED, BLUE }; + uint16_t height, width; + width = tft.width(); + height = tft.height(); + tft.fillRect(0, 0, 7, 3, WHITE); + tft.fillRect(313, 0, 7, 3, WHITE); + tft.fillRect(0, 237, 7, 3, WHITE); + tft.fillRect(313, 237, 7, 3, WHITE); + for (y = 0, w = 18, h = 3; y < 240; y += 13 * w + h) { + for (x = 25; x < 320 - 18; x += 2 * w) { + tft.fillRect(x, y, w, h, WHITE); + } + } + for (x = 0, w = 7, h = 18; x < 320; x += 17 * h + w) { + for (y = 21; y < 240 - 18; y += 2 * h) { + tft.fillRect(x, y, w, h, WHITE); + } + } + tft.fillRect(7, 3, 17 * 18, 13 * 18, GREY); + for (x = 7, y = 0, w = 1, h = 240; x < 320; x += 18) { + tft.fillRect(x, y, w, h, WHITE); + } + for (x = 0, y = 3, w = 320, h = 1; y < 240; y += 18) { + tft.fillRect(x, y, w, h, WHITE); + } + tft.fillRect(26, 22, 17, 99, tft.color565(0, 128, 64)); //turq + tft.fillRect(26, 120, 17, 99, tft.color565(255, 128, 192)); //pink + tft.fillRect(44, 22, 17, 35, tft.color565(0, 128, 255)); //blue + tft.fillRect(44, 184, 17, 35, tft.color565(255, 128, 64)); //orng + tft.fillRect(260, 22, 17, 35, tft.color565(0, 128, 255)); //blue + tft.fillRect(260, 184, 17, 35, tft.color565(255, 128, 64)); //orng + tft.fillRect(278, 22, 17, 99, tft.color565(128, 128, 0)); //grn + tft.fillRect(278, 120, 17, 99, tft.color565(128, 0, 255)); //purp + + for (dx = 111; dx > -111; dx--) { + w = sqrt(111 * 111 - dx * dx); + y = 120 - dx; + dy = (y - 3) / 18; + mask = 7; + switch (dy) { + case 0: + case 1: idx = 1; len = 0; break; + case 2: idx = 0; len = 0; break; + case 3: idx = 0; len = 13; mask = 1; break; + case 4: + case 5: idx = 2; len = 38; break; + case 6: + case 7: + case 8: idx = 0; len = 0; break; + case 9: for (idx = 2; idx < 8; idx++) { + dy = 0xFF >> (7 - idx); + colors[idx] = tft.color565(dy, dy, dy); + } + idx = 2; len = 38; break; + case 10: idx = 1; len = 0; break; + case 11: + case 12: colors[2] = YELLOW; idx = 2; len = 0; break; + } + if (len == 0) + tft.fillRect(160 - w, y, w * 2, 1, colors[idx]); + + else { + if (mask == 1) idx = 1 + (w) / len; + dy = w % len; + for (x = 160 - w; x < 160 + w; idx++) { + tft.fillRect(x, y, dy, 1, colors[idx & mask]); + x += dy; + if (x + len > 160 + w) dy = w % len; + else dy = len; + } + } + + } + for (x = 72, y = 129, dx = 5, dy = 0; dx > 0; x += 2 * dx) { + tft.fillRect(x, y, dx, 36, WHITE); + dy += dx * 2; + if (dy >= 36) { + dy = 0; + dx--; + } + } + tft.fillRect(160 - 8, 5 * 18 + 3, 17, 3 * 18, BLACK); + for (x = 3 * 18 + 7, y = 6 * 18 + 3, w = 1, h = 18; x < 160 + 108; x += 18) { + tft.fillRect(x, y, w, h, WHITE); + } + tft.fillRect(160 - 108, 120, 108 * 2, 1, WHITE); + tft.fillRect(160, 5 * 18 + 3, 1, 3 * 18, WHITE); + tft.fillRect(108, 2 * 18 + 3, 6 * 18, 18, WHITE); + // tft.fillRect(108, 10 * 18 + 3, 6 * 18, 18, BLACK); + tft.fillRect(160 - 8, 11 * 18 + 3, 17, 31, RED); + tft.setCursor(160 - 36, 24 + ADJ_BASELINE); + tft.setTextColor(BLACK); + tft.setTextSize(1); + tft.print("320x240"); + tft.setCursor(109, 43 + ADJ_BASELINE); + tft.setTextColor(BLACK); + tft.setTextSize(1); + tft.print("ID=0x"); + tft.print(tft.readID(), HEX); + tft.setTextColor(WHITE, BLACK); + // tft.setFont(NULL); + // tft.setTextSize(2); + while (1) { + if (++ss > 59) { + ss = 0; + mm++; + if (mm > 59) { + mm = 0; + hh++; + if (hh > 23) hh = 0; + } + } + char buf[20]; + sprintf(buf, "%02d:%02d:%02d", hh, mm, ss); + tft.fillRect(108, 10 * 18 + 3, 6 * 18, 18, BLACK); + tft.setCursor(128, 187 + ADJ_BASELINE); + tft.print(buf); + delay(1000); + } +} + diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..e13ddc1 --- /dev/null +++ b/keywords.txt @@ -0,0 +1,67 @@ +####################################### +# Syntax Coloring Map For Mcufriend_kbv +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +MCUFRIEND_kbv KEYWORD1 +#UTFTGLUE KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +#InitLCD KEYWORD2 +#LCD_Write_DATA KEYWORD2 +WriteCmdData KEYWORD2 +begin KEYWORD2 +#clrScr KEYWORD2 +color565 KEYWORD2 +#dispBitmap KEYWORD2 +#drawBitmap KEYWORD2 +drawCircle KEYWORD2 +drawFastHLine KEYWORD2 +drawFastVLine KEYWORD2 +drawLine KEYWORD2 +drawPixel KEYWORD2 +drawRect KEYWORD2 +drawRoundRect KEYWORD2 +fillCircle KEYWORD2 +fillRect KEYWORD2 +fillRoundRect KEYWORD2 +#fillScr KEYWORD2 +fillScreen KEYWORD2 +#getDisplayXSize KEYWORD2 +#getDisplayYSize KEYWORD2 +height KEYWORD2 +invertDisplay KEYWORD2 +#lcdOff KEYWORD2 +#lcdOn KEYWORD2 +#ltoa KEYWORD2 +#print KEYWORD2 +#printNumF KEYWORD2 +#printNumI KEYWORD2 +#println KEYWORD2 +pushColors KEYWORD2 +readGRAM KEYWORD2 +readID KEYWORD2 +readPixel KEYWORD2 +readReg KEYWORD2 +readReg32 KEYWORD2 +reset KEYWORD2 +setAddrWindow KEYWORD2 +#setBackColor KEYWORD2 +#setColor KEYWORD2 +#setContrast KEYWORD2 +setCursor KEYWORD2 +#setFont KEYWORD2 +setRotation KEYWORD2 +#setrgb KEYWORD2 +setTextColor KEYWORD2 +setTextSize KEYWORD2 +#settextcursor KEYWORD2 +vertScroll KEYWORD2 +width KEYWORD2 +#write_data_block KEYWORD2 diff --git a/mcufriend_kbv_2_8.txt b/mcufriend_kbv_2_8.txt new file mode 100644 index 0000000..aced41d --- /dev/null +++ b/mcufriend_kbv_2_8.txt @@ -0,0 +1,148 @@ +1. Install library from GitHub into your User libraries folder if not already there. + +2. Unzip the attached "MCUFRIEND_kbv.zip" into your User libraries folder. + +3. Insert your Mcufriend style display shield into UNO. + +4. Start your Arduino IDE. + +5. Build any of the Examples from the File->Examples->Mcufriend_kbv menu. +Most of them will write some text to the Serial window (9600 baud). The BMP examples require you to copy the pictures from the bitmaps/ folder to your microSD (root directory) + +6. This library is only intended for UNO and these specific Shields. It will work on a MEGA2560 but not very fast. + +7. The constructor takes no arguments (because it only works with these shields) + +8. The examples are the standard Adafruit ones. You can see my edits by searching for "kbv" + +9. Any Adafruit sketch should work with the MCUFRIEND_kbv constructor() but should allow extra ID values +An Adafruit constructor(cs, rs, wr, rd, rst) IGNORES any arguments. i.e. it only uses the shield control pins + +10. It currently supports UNO shields with "mcufriend.com" pcbs with controllers: +----- HX8347-A 240x320 ID=0x8347 new Untested +ILI9320 240x320 ID=0x9320 +ILI9325 240x320 ID=0x9325 +ILI9327 240x400 ID=0x9327 +ILI9329 240x320 ID=0x9329 +ILI9335 240x320 ID=0x9335 +ILI9341 240x320 ID=0x9341 +ILI9481 320x480 ID=0x9481 +ILI9486 320x480 ID=0x9486 +ILI9488 320x480 ID=0x9488 +LGDP4535 240x320 ID=0x4535 +RM68090 240x320 ID=0x6809 +R61505V 240x320 ID=0xB505 +R61505W 240x320 ID=0xC505 new Untested +R61509V 240x400 ID=0xB509 +----- S6D0139 240x320 ID=0x0139 removed due to lack of tester +S6D0154 240x320 ID=0x0154 +SPFD5408 240x320 ID=0x5408 +----- SSD1963 800x480 ID=0x1963 new Untested +SSD1289 240x320 ID=0x1289 +ST7781 240x320 ID=0x7783 +ST7789V 240x320 ID=0x7789 + +11. It should run on a UNO, MEGA2560, LEONARDO, DUE, ZERO and M0-PRO. + +12. These Mcufriend-style shields tend to have a resistive TouchScreen on A1, 7, A2, 6 but are not always the same rotation of direction. +Run the TouchScreen_Calibr_kbv.ino sketch to diagnose your model and then scale the result from TouchScreen.h methods() +The Resistive TouchScreen does not work on the Due. It seems to be upset by sharing pins. I have discovered why. +(You need a new Touch library.) + +13. The aspect_kbv.ino sketch should show the 4 different rotations. Please report the results for an ILI9335, ILI9327. + +14. The scroll_kbv.ino sketch should scroll a window or subwindow for most chips. Not all chips can scroll. + +15. The readpixel_kbv.ino sketch should display memory in each aspect. + +16. The GLUE_Demo_320x240.ino sketch uses a "GLUE" class to display a UTFT sketch on supported mcufriend shields. + It is NOT perfect. Please report any problems. It is designed as a CONVENIENCE for legacy UTFT code. + Please use MCUFRIEND_kbv method()s in new code. + +CHANGE HISTORY: + +Will Never Happen: + ILI9327 vertical scroll will ALWAYS be limited in Landscape and Portrait_Rev + ST7781 vert scroll is not implemented + ILI9320, 9325, ... can never vert scroll sub-window + Itead CPLD with ID=0x3082 ... will never work + +To Be Fixed: + GLUE Demo does not work with Due and IDE v1.6.6 + +v2.8: posted 26 February 2016 + MCUFRIEND_kbv.cpp: LANDSCAPE is now 90 degrees instead of 270 degrees + methods branch on MIPI / 9320 style + Added SPFD5408 + Added R61505W Untested + Added HX8347-A Untested + Added SSD1963 Untested + graphictest_kbv.ino: smaller buffer for Software Scroll. Just fits in Uno Flash + TouchScreen_Calibr_kbv: wait for consistent Touch + LCD_ID_readreg: Added some more registers + +v2.7: posted ........ NOT YET +v2.6: posted ........ NOT YET + MCUFRIEND_kbv.cpp: + Added R65105V + +v2.5: posted 11 January 2016 + MCUFRIEND_kbv.cpp: + Added ST7789V + Added RM68090 + Added ILI9481 + Added pushColors() from Flash + Improved downward Vertical Scroll. API is changed. + ILI9327 should work in all aspects. vertical scroll in PORT/LAND_REV + S6D0154 should vertical scroll a subwindow + + graphictest_kbv.ino: smooth colour gradation on rounded rectangle tests on bigger displays + added colour grading range. + added vertical scroll down + improve messages + + graphictest_slim.ino: reduced-fat version of graphictest_kbv.ino + testcard_kbv.ino: drawn version of common BMP photo. + scroll_kbv.ino: changed vertScroll() call for new API + + UTFTGLUE.h: improve calculate width and height of rectangles from coordinates. + +v2.4: posted 10 December 2015 + MCUFRIEND_kbv.cpp: LGDP4535 initialisation table fixed - UNTESTED + +v2.3: posted 8 December 2015 + MCUFRIEND_kbv.cpp: added S6D0139 UNTESTED + detect EXTC=0 ILI9341 shield from DX with ID == 0x0000. drive in RGB mode + ILI9327 should Vertical Scroll now. UNTESTED + UTFTGLUE.h: extra print(const char*) method to avoid warning messages + + graphictest_kbv.ino: software scroll a smaller block at top of screen + GLUE_Demo_320x240: removed unnecessary "include Adafruit_TFTLCD.h" + aspect_kbv.ino: invert display when in different aspects + readpixel_kbv.ino: support smaller geometries + LCD_ID_readreg.ino: report some more regs + TouchScreen_Calibr_kbv: for resistive Touch screens like on Mcufriend shields + UTouch_Calibr_kbv: can use UTouch.h library for hardware Touch Controllers (and UTFT) + +v2.2: posted 15 November 2015 + MCUFRIEND_kbv.cpp: changed readGRAM() for ILI9327, ILI9486, + added REV_SCREEN flag to _lcd_capable + implement invertDisplay() + added LGDP4535 + ILI9327: set Partial Area to 0, 399 + MCUFRIEND_kbv.h: USE_GFX_KBV default argument: println(char *s="") + MCUFRIEND_shield.h: regular Uno shield drivers for Uno, Mega, Leonardo, Due, Zero + MCUFRIEND_special.h: experimental drivers + UTFTGLUE.h: identity kludges for non-UNO shields + LCD_ID_readreg.ino: report reg(0x09) + +v2.1: posted 9 November 2015 + MCUFRIEND_kbv.cpp: return 0x9327 / 0x9481 in readID() + MCUFRIEND_shield.h: increase low pulse width in RD_STROBE + EXAMPLES/: add scroll_kbv.ino sketch + edit readpixel_kbv_ino, aspect_kbv.ino + +v2.0: posted 8 November 2015 + Massive changes from v1.0 + + diff --git a/mcufriend_serial.h b/mcufriend_serial.h new file mode 100644 index 0000000..93720ec --- /dev/null +++ b/mcufriend_serial.h @@ -0,0 +1,243 @@ +#if ARDUINO >= 165 +#include +#endif + +#if 0 +#elif defined(__AVR_ATmega328P__) + +#define SPI_INIT() { DDRB |= (1<<5)|(1<<3)|(1<<2); SPCR = (1<>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { dst = xchg8(0); } +#define READ_16(dst) { dst = xchg8(0); dst = (dst << 8) | xchg8(0); } + +#define PIN_LOW(p, b) (p) &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p) |= (1<<(b)) +#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) +#elif defined(__SAMD21G18A__) + +#define SPI_INIT() { SPI.begin(); SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(6); } + +#define CD_PORT PORT->Group[0] +#define CD_PIN 7 +#define CS_PORT PORT->Group[0] +#define CS_PIN 18 +#define RESET_PORT PORT->Group[0] +#define RESET_PIN 6 +#define RD_IDLE +#define WR_IDLE + + +uint8_t running; +static inline void write8(uint8_t c) +{ + running = 1; + while( SERCOM1->SPI.INTFLAG.bit.DRE == 0) ; + SERCOM1->SPI.DATA.bit.DATA = c; // Writing data into Data register +} + +static inline void flush(void) +{ + if (running) while( SERCOM1->SPI.INTFLAG.bit.TXC == 0) ; + running = 0; +} + +static inline uint8_t xchg8(uint8_t c) +{ +// flush(); + while( SERCOM1->SPI.INTFLAG.bit.RXC != 0) SERCOM1->SPI.DATA.bit.DATA; //eat up + while( SERCOM1->SPI.INTFLAG.bit.DRE == 0) ; + SERCOM1->SPI.DATA.bit.DATA = c; // Writing data into Data register + while( SERCOM1->SPI.INTFLAG.bit.RXC == 0) ; + return SERCOM1->SPI.DATA.bit.DATA; +} + + +#define setWriteDir() { } +#define setReadDir() { } +//#define flush() +//#define write8(x) xchg8(x) +//#define xchg8(x) SPI.transfer(x) +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { dst = xchg8(0); } +#define READ_16(dst) { dst = xchg8(0); dst = (dst << 8) | xchg8(0); } + +// Shield Control macros. +#define PIN_LOW(port, pin) (port).OUTCLR.reg = (1<<(pin)) +#define PIN_HIGH(port, pin) (port).OUTSET.reg = (1<<(pin)) +#define PIN_OUTPUT(port, pin) (port).DIR.reg |= (1<<(pin)) + +#elif defined(__AVR_ATxmega128A1__) //3.49s @ 32MHz -O2 + #define CD_PORT VPORT2 + #define CD_PIN 1 + #define CS_PORT VPORT3 + #define CS_PIN 4 + #define RESET_PORT VPORT2 + #define RESET_PIN 0 +#define SPCRVAL (USART_CLK2X_bm | USART_RXEN_bm | USART_TXEN_bm) +#define SETDDR {VPORT3.DIR |= (1<<4)|(1<<5)|(1<<7); VPORT2.DIR |= 0x03; } +#define SPI_INIT() { PORTCFG.VPCTRLB=PORTCFG_VP3MAP_PORTF_gc | PORTCFG_VP2MAP_PORTC_gc; CS_IDLE; RESET_IDLE; SETDDR; spi_init(); } + +void spi_init(void) +{ + SPIF.CTRL=SPI_ENABLE_bm | SPI_MODE_3_gc | (1<>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { dst = xchg8(0); } +#define READ_16(dst) { dst = xchg8(0); dst = (dst << 8) | xchg8(0); } + +#define PIN_LOW(p, b) (p).OUT &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p).OUT |= (1<<(b)) +#define PIN_OUTPUT(p, b) (p).DIR |= (1<<(b)) + +#endif + +#define CD_COMMAND {flush(); PIN_LOW(CD_PORT, CD_PIN); } +#define CD_DATA {flush(); PIN_HIGH(CD_PORT, CD_PIN); } +#define CD_OUTPUT PIN_OUTPUT(CD_PORT, CD_PIN) +#define CS_ACTIVE PIN_LOW(CS_PORT, CS_PIN) +#define CS_IDLE {flush(); PIN_HIGH(CS_PORT, CS_PIN); } +#define CS_OUTPUT PIN_OUTPUT(CS_PORT, CS_PIN) +#define RESET_ACTIVE PIN_LOW(RESET_PORT, RESET_PIN) +#define RESET_IDLE PIN_HIGH(RESET_PORT, RESET_PIN) +#define RESET_OUTPUT PIN_OUTPUT(RESET_PORT, RESET_PIN) + +// General macros. IOCLR registers are 1 cycle when optimised. + +#define CTL_INIT() { CD_OUTPUT; CS_OUTPUT; RESET_OUTPUT; SPI_INIT(); } +#define WriteCmd(x) { CD_COMMAND; write8(x); } +#define WriteData(x) { CD_DATA; write16(x); } diff --git a/mcufriend_shield.h b/mcufriend_shield.h new file mode 100644 index 0000000..3ddcb25 --- /dev/null +++ b/mcufriend_shield.h @@ -0,0 +1,262 @@ +#define USE_SPECIAL //check for custom drivers +#if defined(USE_SPECIAL) +#include "mcufriend_special.h" +#if !defined(USE_SPECIAL_FAIL) +#warning WE ARE USING A SPECIAL CUSTOM DRIVER +#endif +#endif +#if !defined(USE_SPECIAL) || defined (USE_SPECIAL_FAIL) + +#if 0 +#elif defined(__AVR_ATmega328P__) //regular UNO shield on UNO +#define RD_PORT PORTC +#define RD_PIN 0 +#define WR_PORT PORTC +#define WR_PIN 1 +#define CD_PORT PORTC +#define CD_PIN 2 +#define CS_PORT PORTC +#define CS_PIN 3 +#define RESET_PORT PORTC +#define RESET_PIN 4 + +#define DMASK 0x03 +#define NMASK ~DMASK +#define write_8(x) { PORTB = (PORTB & NMASK) | ((x) & DMASK); PORTD = (PORTD & DMASK) | ((x) & NMASK); } +#define read_8() ( (PINB & DMASK) | (PIND & NMASK) ) +#define setWriteDir() { DDRB = (DDRB & NMASK) | DMASK; DDRD = (DDRD & DMASK) | NMASK; } +#define setReadDir() { DDRB = (DDRB & NMASK) & NMASK; DDRD = (DDRD & DMASK) & DMASK; } +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } + +#define PIN_LOW(p, b) (p) &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p) |= (1<<(b)) +#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) + +#elif defined(__AVR_ATmega2560__) //regular UNO shield on MEGA2560 +#define RD_PORT PORTF +#define RD_PIN 0 +#define WR_PORT PORTF +#define WR_PIN 1 +#define CD_PORT PORTF +#define CD_PIN 2 +#define CS_PORT PORTF +#define CS_PIN 3 +#define RESET_PORT PORTF +#define RESET_PIN 4 + +#define EMASK 0x38 +#define GMASK 0x20 +#define HMASK 0x78 +#define write_8(x) { PORTH &= ~HMASK; PORTG &= ~GMASK; PORTE &= ~EMASK; \ + PORTH |= (((x) & (3<<0)) << 5); \ + PORTE |= (((x) & (3<<2)) << 2); \ + PORTG |= (((x) & (1<<4)) << 1); \ + PORTE |= (((x) & (1<<5)) >> 2); \ + PORTH |= (((x) & (3<<6)) >> 3); \ + } + +#define read_8() ( ((PINH & (3<<5)) >> 5)\ + | ((PINE & (3<<4)) >> 2)\ + | ((PING & (1<<5)) >> 1)\ + | ((PINE & (1<<3)) << 2)\ + | ((PINH & (3<<3)) << 3)\ + ) +#define setWriteDir() { DDRH |= HMASK; DDRG |= GMASK; DDRE |= EMASK; } +#define setReadDir() { DDRH &= ~HMASK; DDRG &= ~GMASK; DDRE &= ~EMASK; } +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } + +#define PIN_LOW(p, b) (p) &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p) |= (1<<(b)) +#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) + +#elif defined(__SAMD21G18A__) //regular UNO shield on ZERO or M0_PRO +#include "sam.h" + // configure macros for the control pins +#define RD_PORT PORT->Group[0] +#define RD_PIN 2 +#define WR_PORT PORT->Group[1] +#define WR_PIN 8 +#define CD_PORT PORT->Group[1] +#define CD_PIN 9 +#define CS_PORT PORT->Group[0] +#define CS_PIN 4 +#define RESET_PORT PORT->Group[0] +#define RESET_PIN 5 + // configure macros for data bus +#define DMASK 0x0030C3C0 + // #define write_8(x) PORT->Group[0].OUT.reg = (PORT->Group[0].OUT.reg & ~DMASK)|(((x) & 0x0F) << 6)|(((x) & 0x30) << 10)|(((x) & 0xC0)<<14) +#if defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_ZERO) // American ZERO +#define write_8(x) {\ + PORT->Group[0].OUTCLR.reg = DMASK;\ + PORT->Group[0].OUTSET.reg = (((x) & 0x0B) << 6)\ + |(((x) & (1<<2)) << 12)\ + |(((x) & (1<<4)) << 4)\ + |(((x) & (1<<5)) << 10)\ + |(((x) & 0xC0) << 14);\ + } +#define read_8() (((PORT->Group[0].IN.reg >> 6) & 0x0B)\ + |((PORT->Group[0].IN.reg >> 12) & (1<<2))\ + |((PORT->Group[0].IN.reg >> 4) & (1<<4))\ + |((PORT->Group[0].IN.reg >> 10) & (1<<5))\ + |((PORT->Group[0].IN.reg >> 14) & 0xC0)) +#else //default to an M0_PRO on v1.6.5 or 1.7.6 +#define write_8(x) {\ + PORT->Group[0].OUTCLR.reg = DMASK;\ + PORT->Group[0].OUTSET.reg = (((x) & 0x0F) << 6)\ + |(((x) & 0x30) << 10)\ + |(((x) & 0xC0) << 14);\ + } +#define read_8() (((PORT->Group[0].IN.reg >> 6) & 0x0F)|((PORT->Group[0].IN.reg >> 10) & 0x30)|((PORT->Group[0].IN.reg >> 14) & 0xC0)) +#endif +#define setWriteDir() { PORT->Group[0].DIRSET.reg = DMASK; \ + PORT->Group[0].WRCONFIG.reg = (DMASK & 0xFFFF) | (0<<22) | (1<<28) | (1<<30); \ + PORT->Group[0].WRCONFIG.reg = (DMASK>>16) | (0<<22) | (1<<28) | (1<<30) | (1<<31); \ + } +#define setReadDir() { PORT->Group[0].DIRCLR.reg = DMASK; \ + PORT->Group[0].WRCONFIG.reg = (DMASK & 0xFFFF) | (1<<17) | (1<<28) | (1<<30); \ + PORT->Group[0].WRCONFIG.reg = (DMASK>>16) | (1<<17) | (1<<28) | (1<<30) | (1<<31); \ + } +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } + // Shield Control macros. +#define PIN_LOW(port, pin) (port).OUTCLR.reg = (1<<(pin)) +#define PIN_HIGH(port, pin) (port).OUTSET.reg = (1<<(pin)) +#define PIN_OUTPUT(port, pin) (port).DIR.reg |= (1<<(pin)) + +#elif defined(__SAM3X8E__) //regular UNO shield on DUE + // configure macros for the control pins +#define RD_PORT PIOA +#define RD_PIN 16 +#define WR_PORT PIOA +#define WR_PIN 24 +#define CD_PORT PIOA +#define CD_PIN 23 +#define CS_PORT PIOA +#define CS_PIN 22 +#define RESET_PORT PIOA +#define RESET_PIN 6 + // configure macros for data bus +#define BMASK (1<<25) +#define CMASK (0xBF << 21) +#define write_8(x) { PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \ + PIOC->PIO_SODR = (((x) & (1<<0)) << 22); \ + PIOC->PIO_SODR = (((x) & (1<<1)) << 20); \ + PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \ + PIOC->PIO_SODR = (((x) & (1<<3)) << 25); \ + PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \ + PIOC->PIO_SODR = (((x) & (1<<5)) << 20); \ + PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \ + PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \ + } + +#define read_8() ( ((PIOC->PIO_PDSR & (1<<22)) >> 22)\ + | ((PIOC->PIO_PDSR & (1<<21)) >> 20)\ + | ((PIOB->PIO_PDSR & (1<<25)) >> 23)\ + | ((PIOC->PIO_PDSR & (1<<28)) >> 25)\ + | ((PIOC->PIO_PDSR & (1<<26)) >> 22)\ + | ((PIOC->PIO_PDSR & (1<<25)) >> 20)\ + | ((PIOC->PIO_PDSR & (1<<24)) >> 18)\ + | ((PIOC->PIO_PDSR & (1<<23)) >> 16)\ + ) +#define setWriteDir() { PIOB->PIO_OER = BMASK; PIOC->PIO_OER = CMASK; } +#define setReadDir() { \ + PMC->PMC_PCER0 = (1 << ID_PIOB)|(1 << ID_PIOC);\ + PIOB->PIO_ODR = BMASK; PIOC->PIO_ODR = CMASK;\ + } +#define write8(x) { write_8(x); WR_ACTIVE; WR_STROBE; WR_IDLE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; RD_ACTIVE; dst = read_8(); RD_IDLE; RD_IDLE; } +#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } + // Shield Control macros. +#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin)) +#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin)) +#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin)) + +#elif defined(__AVR_ATmega32U4__) //regular UNO shield on Leonardo +#define RD_PORT PORTF +#define RD_PIN 7 +#define WR_PORT PORTF +#define WR_PIN 6 +#define CD_PORT PORTF +#define CD_PIN 5 +#define CS_PORT PORTF +#define CS_PIN 4 +#define RESET_PORT PORTF +#define RESET_PIN 1 + +#define BMASK (3<<4) +#define CMASK (1<<6) +#define DMASK ((1<<7)|(1<<4)|(3<<0)) +#define EMASK (1<<6) +static inline //hope we use r24 +void write_8(uint8_t x) +{ + PORTB &= ~BMASK; + PORTC &= ~CMASK; + PORTD &= ~DMASK; + PORTE &= ~EMASK; + PORTB |= (((x) & (3 << 0)) << 4); + PORTD |= (((x) & (1 << 2)) >> 1); + PORTD |= (((x) & (1 << 3)) >> 3); + PORTD |= (((x) & (1 << 4)) << 0); + PORTC |= (((x) & (1 << 5)) << 1); + PORTD |= (((x) & (1 << 6)) << 1); + PORTE |= (((x) & (1 << 7)) >> 1); +} + +#define read_8() ( ((PINB & (3<<4)) >> 4)\ +| ((PIND & (1<<1)) << 1)\ +| ((PIND & (1<<0)) << 3)\ +| ((PIND & (1<<4)) >> 0)\ +| ((PINC & (1<<6)) >> 1)\ +| ((PIND & (1<<7)) >> 1)\ +| ((PINE & (1<<6)) << 1)\ +) +#define setWriteDir() { DDRB |= BMASK; DDRC |= CMASK; DDRD |= DMASK; DDRE |= EMASK; } +#define setReadDir() { DDRB &= ~BMASK; DDRC &= ~CMASK; DDRD &= ~DMASK; DDRE &= ~EMASK; } +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } + +#define PIN_LOW(p, b) (p) &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p) |= (1<<(b)) +#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) + +#else +#error MCU unsupported +#endif // regular UNO shields on Arduino boards + +#endif //!defined(USE_SPECIAL) || defined (USE_SPECIAL_FAIL) + +#define RD_ACTIVE PIN_LOW(RD_PORT, RD_PIN) +#define RD_IDLE PIN_HIGH(RD_PORT, RD_PIN) +#define RD_OUTPUT PIN_OUTPUT(RD_PORT, RD_PIN) +#define WR_ACTIVE PIN_LOW(WR_PORT, WR_PIN) +#define WR_IDLE PIN_HIGH(WR_PORT, WR_PIN) +#define WR_OUTPUT PIN_OUTPUT(WR_PORT, WR_PIN) +#define CD_COMMAND PIN_LOW(CD_PORT, CD_PIN) +#define CD_DATA PIN_HIGH(CD_PORT, CD_PIN) +#define CD_OUTPUT PIN_OUTPUT(CD_PORT, CD_PIN) +#define CS_ACTIVE PIN_LOW(CS_PORT, CS_PIN) +#define CS_IDLE PIN_HIGH(CS_PORT, CS_PIN) +#define CS_OUTPUT PIN_OUTPUT(CS_PORT, CS_PIN) +#define RESET_ACTIVE PIN_LOW(RESET_PORT, RESET_PIN) +#define RESET_IDLE PIN_HIGH(RESET_PORT, RESET_PIN) +#define RESET_OUTPUT PIN_OUTPUT(RESET_PORT, RESET_PIN) + + // General macros. IOCLR registers are 1 cycle when optimised. +#define WR_STROBE { WR_ACTIVE; WR_IDLE; } //PWLW=TWRL=50ns +#define RD_STROBE RD_IDLE, RD_ACTIVE, RD_ACTIVE, RD_ACTIVE //PWLR=TRDL=150ns, tDDR=100ns + +#define CTL_INIT() { RD_OUTPUT; WR_OUTPUT; CD_OUTPUT; CS_OUTPUT; RESET_OUTPUT; } +#define WriteCmd(x) { CD_COMMAND; write16(x); } +#define WriteData(x) { CD_DATA; write16(x); } diff --git a/mcufriend_special.h b/mcufriend_special.h new file mode 100644 index 0000000..3319c87 --- /dev/null +++ b/mcufriend_special.h @@ -0,0 +1,680 @@ +#define SSD1289_JUMPERS 2 //Uno Shield with VERY different pin-out to Mcufriend +// only define one "USE_XXX" macro at any time +//#define USE_SSD1289_SHIELD_UNO +//#define USE_SSD1289_SHIELD_MEGA +//#define USE_SSD1289_SHIELD_DUE +//#define USE_MEGA_8BIT_PROTOSHIELD +#define USE_MEGA_16BIT_SHIELD //RD on PL6 (D43) +//#define USE_BLD_BST_MEGA32U4 +//#define USE_BLD_BST_MEGA2560 +//#define USE_DUE_8BIT_PROTOSHIELD +//#define USE_DUE_16BIT_SHIELD //RD on PA15 (D24) + +#if 0 +#elif defined(__AVR_ATmega328P__) && defined(USE_SSD1289_SHIELD_UNO) //on UNO +#warning using SSD1289 Shield for mega328 +#define RD_PORT PORTC +#define RD_PIN 3 +#define WR_PORT PORTC +#define WR_PIN 2 +#define CD_PORT PORTC +#define CD_PIN 1 +#define CS_PORT PORTC +#define CS_PIN 0 +#define RESET_PORT PORTB +#define RESET_PIN 1 //actually SD_CS + +// SSD1289 shield has LCD_D0 on RXD0. Fine for write-only +// For any Read operations, put jumper from D0 to D8, Switch #2 to OFF. +// If using Serial, jumper D1 to A5, Switch #1 to OFF +#if SSD1289_JUMPERS == 0 +#warning no jumpers. Switch #1=ON, #2=ON +#define BMASK 0x00 //0x00 for output, 0x01 for Read + Serial +#define CMASK 0x00 //0x20 for Read + Serial +#define DMASK (~BMASK) +#define write8(x) { PORTD = x; WR_STROBE; } +#define read_8() ( PIND ) +#elif SSD1289_JUMPERS == 1 +#warning jumper D0 to D8. Switch #1=ON, #2=OFF +#define BMASK 0x01 //0x00 for output, 0x01 for Read + Serial +#define CMASK 0x00 //0x20 for Read + Serial +#define DMASK (~BMASK) +#define write8(x) { PORTD = (PORTD & ~DMASK) | (x & DMASK); PORTB = (PORTB & ~BMASK) | (x & BMASK); WR_STROBE; } +#define read_8() ( (PIND & DMASK)|(PINB & BMASK) ) +#elif SSD1289_JUMPERS == 2 +#warning jumper D0 to D8, D1 to A5. Switch #1=OFF, #2=OFF +#define BMASK (1<<0) //0x00 for output, 0x01 for Read + Serial +#define CMASK (1<<5) //0x20 for Read + Serial +#define DMASK (0xFC) +#define write8(x) { PORTC = (PORTC & ~CMASK) | ((x<<4) & CMASK);\ + PORTD = (PORTD & ~DMASK) | (x & DMASK);\ + PORTB = (PORTB & ~BMASK) | (x & BMASK); WR_STROBE; } +#define read_8() ( ((PINC & CMASK)>>4)|(PIND & DMASK)|(PINB & BMASK) ) +#endif +#define setWriteDir() { DDRC |= CMASK; DDRD |= DMASK; DDRB |= BMASK; } +#define setReadDir() { DDRC &= ~CMASK; DDRD &= ~DMASK; DDRB &= ~BMASK; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } + +#define PIN_LOW(p, b) (p) &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p) |= (1<<(b)) +#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) + +#elif defined(__AVR_ATxmega128A1__) // Home made shield with Xplained +#warning Home made shield with Xplained +#define RD_PORT VPORT3 +#define RD_PIN 0 +#define WR_PORT VPORT3 +#define WR_PIN 1 +#define CD_PORT VPORT3 +#define CD_PIN 2 +#define CS_PORT VPORT3 +#define CS_PIN 3 +#define RESET_PORT VPORT3 +#define RESET_PIN 4 + +// VPORTs are very fast. CBI, SBI are only one cycle. Hence all those RD_ACTIVEs +// ILI9320 data sheet says tDDR=100ns. We need 218ns to read REGs correctly. +#define write_8(x) { VPORT2.OUT = x; } +#define read_8() ( VPORT2.IN ) +#define setWriteDir() { PORTCFG.VPCTRLB=PORTCFG_VP3MAP_PORTF_gc | PORTCFG_VP2MAP_PORTC_gc; VPORT2.DIR = 0xFF; } +#define setReadDir() { VPORT2.DIR = 0x00; } +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } + +#define PIN_LOW(p, b) (p).OUT &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p).OUT |= (1<<(b)) +#define PIN_OUTPUT(p, b) (p).DIR |= (1<<(b)) +#elif defined(__AVR_ATxmega32A4U__) // Home made shield with Batsocks module +#warning Home made shield with Batsocks module +#define RD_PORT VPORT3 +#define RD_PIN 0 +#define WR_PORT VPORT3 +#define WR_PIN 1 +#define CD_PORT VPORT3 +#define CD_PIN 2 +#define CS_PORT VPORT3 +#define CS_PIN 3 +#define RESET_PORT PORTE +#define RESET_PIN 0 + +// VPORTs are very fast. CBI, SBI are only one cycle. Hence all those RD_ACTIVEs +// ILI9320 data sheet says tDDR=100ns. We need 218ns to read REGs correctly. +// S6D0154 data sheet says tDDR=250ns. We need ~500ns to read REGs correctly. +#define write_8(x) { VPORT2.OUT = x; } +#define read_8() ( VPORT2.IN ) +#define setWriteDir() { PORTCFG.VPCTRLB=PORTCFG_VP13MAP_PORTB_gc | PORTCFG_VP02MAP_PORTC_gc; VPORT2.DIR = 0xFF; } +#define setReadDir() { VPORT2.DIR = 0x00; } +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } + +#define PIN_LOW(p, b) (p).OUT &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p).OUT |= (1<<(b)) +#define PIN_OUTPUT(p, b) (p).DIR |= (1<<(b)) + +#elif defined(__AVR_ATmega2560__) && defined(USE_BLD_BST_MEGA2560) //regular UNO shield on MEGA2560 using BLD/BST +#warning regular UNO shield on MEGA2560 using BLD/BST +#define RD_PORT PORTF +#define RD_PIN 0 +#define WR_PORT PORTF +#define WR_PIN 1 +#define CD_PORT PORTF +#define CD_PIN 2 +#define CS_PORT PORTF +#define CS_PIN 3 +#define RESET_PORT PORTF +#define RESET_PIN 4 + +#define EMASK 0x38 +#define GMASK 0x20 +#define HMASK 0x78 +static inline void write_8(uint8_t val) +{ + asm volatile("lds __tmp_reg__,0x0102" "\n\t" + "BST %0,0" "\n\t" "BLD __tmp_reg__,5" "\n\t" + "BST %0,1" "\n\t" "BLD __tmp_reg__,6" "\n\t" + "BST %0,6" "\n\t" "BLD __tmp_reg__,3" "\n\t" + "BST %0,7" "\n\t" "BLD __tmp_reg__,4" "\n\t" + "sts 0x0102,__tmp_reg__" : : "a" (val)); + asm volatile("in __tmp_reg__,0x0E" "\n\t" + "BST %0,2" "\n\t" "BLD __tmp_reg__,4" "\n\t" + "BST %0,3" "\n\t" "BLD __tmp_reg__,5" "\n\t" + "BST %0,5" "\n\t" "BLD __tmp_reg__,3" "\n\t" + "out 0x0E,__tmp_reg__" : : "a" (val)); + asm volatile("in __tmp_reg__,0x14" "\n\t" + "BST %0,4" "\n\t" "BLD __tmp_reg__,5" "\n\t" + "out 0x14,__tmp_reg__" : : "a" (val)); +} + +#define read_8() ( ((PINH & (3<<5)) >> 5)\ +| ((PINE & (3<<4)) >> 2)\ +| ((PING & (1<<5)) >> 1)\ +| ((PINE & (1<<3)) << 2)\ +| ((PINH & (3<<3)) << 3)\ +) +#define setWriteDir() { DDRH |= HMASK; DDRG |= GMASK; DDRE |= EMASK; } +#define setReadDir() { DDRH &= ~HMASK; DDRG &= ~GMASK; DDRE &= ~EMASK; } +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; } + +#define PIN_LOW(p, b) (p) &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p) |= (1<<(b)) +#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) + +#elif defined(__AVR_ATmega2560__) && defined(USE_SSD1289_SHIELD_MEGA) //on MEGA2560 +#warning using SSD1289 Shield for mega2560 +#define RD_PORT PORTF +#define RD_PIN 3 //A3 +#define WR_PORT PORTF +#define WR_PIN 2 //A2 +#define CD_PORT PORTF +#define CD_PIN 1 //A1 +#define CS_PORT PORTF +#define CS_PIN 0 //A0 +#define RESET_PORT PORTH +#define RESET_PIN 6 //D9 DS_CS, D10=T_CS, D9=SD_CS, D8=n.c. + +// only for SSD1289 data bus on D2..D9 UNTESTED +#if (SSD1289_JUMPERS == 0) //Switch #1=ON, #2=ON +#warning no jumpers Switch #1=ON, #2=ON +#define EMASK 0x3B +#define FMASK 0x00 +#define HMASK 0x18 +#define GMASK 0x20 +#define write_8(x) { PORTH &= ~HMASK; PORTG &= ~GMASK; PORTE &= ~EMASK; \ + PORTE |= (((x) & (1<<0)) << 0); \ + PORTE |= (((x) & (1<<1)) << 0); \ + PORTE |= (((x) & (3<<2)) << 2); \ + PORTG |= (((x) & (1<<4)) << 1); \ + PORTE |= (((x) & (1<<5)) >> 2); \ + PORTH |= (((x) & (3<<6)) >> 3); \ +} + +#define read_8() ( ((PINE & (1<<0)) >> 0)\ + | ((PINE & (1<<1)) >> 0)\ + | ((PINE & (3<<4)) >> 2)\ + | ((PING & (1<<5)) >> 1)\ + | ((PINE & (1<<3)) << 2)\ + | ((PINH & (3<<3)) << 3)\ + ) +#elif (SSD1289_JUMPERS == 1) //jumper D0 to D8. Switch #1=ON, #2=OFF +#warning jumper D0 to D8. Switch #1=ON, #2=OFF +#define EMASK 0x3A +#define FMASK 0x00 +#define HMASK 0x38 +#define GMASK 0x20 +#define write_8(x) { PORTH &= ~HMASK; PORTG &= ~GMASK; PORTE &= ~EMASK; \ + PORTH |= (((x) & (1<<0)) << 5); \ + PORTE |= (((x) & (1<<1)) << 0); \ + PORTE |= (((x) & (3<<2)) << 2); \ + PORTG |= (((x) & (1<<4)) << 1); \ + PORTE |= (((x) & (1<<5)) >> 2); \ + PORTH |= (((x) & (3<<6)) >> 3); \ +} + +#define read_8() ( ((PINH & (1<<5)) >> 5)\ + | ((PINE & (1<<1)) >> 0)\ + | ((PINE & (3<<4)) >> 2)\ + | ((PING & (1<<5)) >> 1)\ + | ((PINE & (1<<3)) << 2)\ + | ((PINH & (3<<3)) << 3)\ + ) +#elif (SSD1289_JUMPERS == 2) //jumper D0 to D8, D1 to A5. Switch #1=OFF, #2=OFF +#warning jumper D0 to D8, D1 to A5. Switch #1=OFF, #2=OFF +#define FMASK 0x20 +#define EMASK 0x38 +#define HMASK 0x38 +#define GMASK 0x20 +#define write_8(x) { PORTH &= ~HMASK; PORTG &= ~GMASK; PORTF &= ~FMASK; PORTE &= ~EMASK; \ + PORTH |= (((x) & (1<<0)) << 5); \ + PORTF |= (((x) & (1<<1)) << 4); \ + PORTE |= (((x) & (3<<2)) << 2); \ + PORTG |= (((x) & (1<<4)) << 1); \ + PORTE |= (((x) & (1<<5)) >> 2); \ + PORTH |= (((x) & (3<<6)) >> 3); \ +} + +#define read_8() ( ((PINH & (1<<5)) >> 5)\ + | ((PINF & (1<<5)) >> 4)\ + | ((PINE & (3<<4)) >> 2)\ + | ((PING & (1<<5)) >> 1)\ + | ((PINE & (1<<3)) << 2)\ + | ((PINH & (3<<3)) << 3)\ + ) +#endif +#define setWriteDir() { DDRH |= HMASK; DDRG |= GMASK; DDRF |= FMASK; DDRE |= EMASK; } +#define setReadDir() { DDRH &= ~HMASK; DDRG &= ~GMASK; DDRF &= ~FMASK; DDRE &= ~EMASK; } +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; } + +#define PIN_LOW(p, b) (p) &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p) |= (1<<(b)) +#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) + +#elif defined(__AVR_ATmega2560__) && defined(USE_MEGA_16BIT_SHIELD) +#warning USE_MEGA_16BIT_SHIELD +#define RD_PORT PORTL +#define RD_PIN 6 //PL6 (D43). Graham has PA15 (D24) on Due Shield +#define WR_PORT PORTG +#define WR_PIN 2 //D39 CTE +#define CD_PORT PORTD +#define CD_PIN 7 //D38 CTE +#define CS_PORT PORTG +#define CS_PIN 1 //D40 CTE +#define RESET_PORT PORTG +#define RESET_PIN 0 //D41 CTE + +#define write_8(x) { PORTC = x; } +#define write_16(x) { PORTA = (x) >> 8; PORTC = x; } + +#define read_16() ( (PINA<<8) | (PINC) ) +#define setWriteDir() { DDRC = 0xFF; DDRA = 0xff; } +#define setReadDir() { DDRC = 0x00; DDRA = 0x00; } +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { write_16(x); WR_STROBE; } +#define READ_16(dst) { RD_STROBE; dst = read_16(); RD_IDLE; } +#define READ_8(dst) { READ_16(dst); dst &= 0xFFFF; } + +#define PIN_LOW(p, b) (p) &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p) |= (1<<(b)) +#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) + +#elif defined(__AVR_ATmega2560__) && defined(USE_MEGA_8BIT_PROTOSHIELD) +#warning USE_MEGA_8BIT_PROTOSHIELD +#define RD_PORT PORTF +#define RD_PIN 0 +#define WR_PORT PORTF +#define WR_PIN 1 +#define CD_PORT PORTF +#define CD_PIN 2 +#define CS_PORT PORTF +#define CS_PIN 3 +#define RESET_PORT PORTF +#define RESET_PIN 4 + +#define write_8(x) { PORTA = x;} + +#define read_8() ( PINA ) +#define setWriteDir() { DDRA = 0xFF; } +#define setReadDir() { DDRA = 0x00; } +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; } + +#define PIN_LOW(p, b) (p) &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p) |= (1<<(b)) +#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) + +#elif defined(__AVR_ATmega32U4__) && defined(USE_BLD_BST_MEGA32U4) //regular UNO shield on Leonardo using BST/BLD +#warning regular UNO shield on Leonardo using BST/BLD +#define RD_PORT PORTF +#define RD_PIN 7 +#define WR_PORT PORTF +#define WR_PIN 6 +#define CD_PORT PORTF +#define CD_PIN 5 +#define CS_PORT PORTF +#define CS_PIN 4 +#define RESET_PORT PORTF +#define RESET_PIN 1 + +#define BMASK (3<<4) +#define CMASK (1<<6) +#define DMASK ((1<<7)|(1<<4)|(3<<0)) +#define EMASK (1<<6) +static inline void write_8(uint8_t val) +{ + asm volatile("in __tmp_reg__,0x05" "\n\t" + "BST %0,0" "\n\t" "BLD __tmp_reg__,4" "\n\t" + "BST %0,1" "\n\t" "BLD __tmp_reg__,5" "\n\t" + "out 0x05,__tmp_reg__" : : "a" (val)); + asm volatile("in __tmp_reg__,0x0B" "\n\t" + "BST %0,2" "\n\t" "BLD __tmp_reg__,1" "\n\t" + "BST %0,3" "\n\t" "BLD __tmp_reg__,0" "\n\t" + "BST %0,4" "\n\t" "BLD __tmp_reg__,4" "\n\t" + "BST %0,6" "\n\t" "BLD __tmp_reg__,7" "\n\t" + "out 0x0B,__tmp_reg__" : : "a" (val)); + asm volatile("in __tmp_reg__,0x08" "\n\t" + "BST %0,5" "\n\t" "BLD __tmp_reg__,6" "\n\t" + "out 0x08,__tmp_reg__" : : "a" (val)); + asm volatile("in __tmp_reg__,0x0E" "\n\t" + "BST %0,7" "\n\t" "BLD __tmp_reg__,6" "\n\t" + "out 0x0E,__tmp_reg__" : : "a" (val)); +} +#define read_8() ( ((PINB & (3<<4)) >> 4)\ +| ((PIND & (1<<1)) << 1)\ +| ((PIND & (1<<0)) << 3)\ +| ((PIND & (1<<4)) >> 0)\ +| ((PINC & (1<<6)) >> 1)\ +| ((PIND & (1<<7)) >> 1)\ +| ((PINE & (1<<6)) << 1)\ +) +#define setWriteDir() { DDRB |= BMASK; DDRC |= CMASK; DDRD |= DMASK; DDRE |= EMASK; } +#define setReadDir() { DDRB &= ~BMASK; DDRC &= ~CMASK; DDRD &= ~DMASK; DDRE &= ~EMASK; } +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; } + +#define PIN_LOW(p, b) (p) &= ~(1<<(b)) +#define PIN_HIGH(p, b) (p) |= (1<<(b)) +#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) + +#elif defined(__SAMD21J18A__) //regular UNO shield on D21_XPRO +#warning regular UNO shield on D21_XPRO +#include "samd21.h" +// configure macros for the control pins +#define RD_PORT PORT->Group[1] +#define RD_PIN 0 +#define WR_PORT PORT->Group[1] +#define WR_PIN 1 +#define CD_PORT PORT->Group[0] +#define CD_PIN 10 +#define CS_PORT PORT->Group[0] +#define CS_PIN 11 +#define RESET_PORT PORT->Group[0] +#define RESET_PIN 8 +// configure macros for data bus +#define AMASK 0x00220000 +#define BMASK 0x0000C0E4 +#define write_8(d) { \ + PORT->Group[0].OUT.reg = (PORT->Group[0].OUT.reg & ~AMASK) \ + | (((d) & (1<<5)) << 16) \ + | (((d) & (1<<7)) << 10); \ + PORT->Group[1].OUT.reg = (PORT->Group[1].OUT.reg & ~BMASK) \ + | (((d) & (3<<0)) << 6) \ + | (((d) & (1<<2)) << 12) \ + | (((d) & (1<<3)) >> 1) \ + | (((d) & (1<<4)) << 1) \ + | (((d) & (1<<6)) << 9); \ +} +#define read_8() ( (((PORT->Group[0].IN.reg & (1<<21)) >> 16) \ +| ((PORT->Group[0].IN.reg & (1<<17)) >> 10) \ +| ((PORT->Group[1].IN.reg & (3<<6)) >> 6) \ +| ((PORT->Group[1].IN.reg & (1<<14)) >> 12) \ +| ((PORT->Group[1].IN.reg & (1<<2)) << 1) \ +| ((PORT->Group[1].IN.reg & (1<<5)) >> 1) \ +| ((PORT->Group[1].IN.reg & (1<<15)) >> 9))) +#define setWriteDir() { \ + PORT->Group[0].DIRSET.reg = AMASK; \ + PORT->Group[1].DIRSET.reg = BMASK; \ + PORT->Group[0].WRCONFIG.reg = (AMASK>>16) | (0<<22) | (0<<28) | (1<<30) | (1<<31); \ + PORT->Group[1].WRCONFIG.reg = (BMASK & 0xFFFF) | (0<<22) | (0<<28) | (1<<30); \ +} +#define setReadDir() { \ + PORT->Group[0].DIRCLR.reg = AMASK; \ + PORT->Group[1].DIRCLR.reg = BMASK; \ + PORT->Group[0].WRCONFIG.reg = (AMASK>>16) | (1<<17) | (0<<28) | (1<<30) | (1<<31); \ + PORT->Group[1].WRCONFIG.reg = (BMASK & 0xFFFF) | (1<<17) | (0<<28) | (1<<30); \ +} + +#define write8(x) { write_8(x); WR_STROBE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } +#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; } +// Shield Control macros. +#define PIN_LOW(port, pin) (port).OUTCLR.reg = (1<<(pin)) +#define PIN_HIGH(port, pin) (port).OUTSET.reg = (1<<(pin)) +#define PIN_OUTPUT(port, pin) (port).DIR.reg |= (1<<(pin)) + +#elif defined(__SAM3X8E__) && defined(USE_SSD1289_SHIELD_DUE) // on DUE +#warning USE_SSD1289_SHIELD_DUE +// configure macros for the control pins +#define RD_PORT PIOA +#define RD_PIN 22 //A3 +#define WR_PORT PIOA +#define WR_PIN 23 //A2 +#define CD_PORT PIOA +#define CD_PIN 24 //A1 +#define CS_PORT PIOA +#define CS_PIN 16 //A0 +#define RESET_PORT PIOC +#define RESET_PIN 21 //D9 Touch CS +// configure macros for data bus +// only for SSD1289 data bus on D2..D9 UNTESTED +#if SSD1289_JUMPERS == 0 +#warning no jumpers Switch #1=ON, #2=ON +#define AMASK (3<<8) +#define BMASK (1<<25) +#define CMASK (0xBC << 21) +#define write_8(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \ + PIOA->PIO_SODR = (((x) & (1<<0)) << 8); \ + PIOA->PIO_SODR = (((x) & (1<<1)) << 8); \ + PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \ + PIOC->PIO_SODR = (((x) & (1<<3)) << 25); \ + PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \ + PIOC->PIO_SODR = (((x) & (1<<5)) << 20); \ + PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \ + PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \ +} + +#define read_8() ( ((PIOA->PIO_PDSR & (1<<8)) >> 8)\ + | ((PIOA->PIO_PDSR & (1<<9)) >> 8)\ + | ((PIOB->PIO_PDSR & (1<<25)) >> 23)\ + | ((PIOC->PIO_PDSR & (1<<28)) >> 25)\ + | ((PIOC->PIO_PDSR & (1<<26)) >> 22)\ + | ((PIOC->PIO_PDSR & (1<<25)) >> 20)\ + | ((PIOC->PIO_PDSR & (1<<24)) >> 18)\ + | ((PIOC->PIO_PDSR & (1<<23)) >> 16)\ + ) +#elif SSD1289_JUMPERS == 1 +#warning jumper D0 to D8. Switch #1=ON, #2=OFF +#define AMASK (1<<9) +#define BMASK (1<<25) +#define CMASK (0xBE << 21) +#define write_8(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \ + PIOC->PIO_SODR = (((x) & (1<<0)) << 22); \ + PIOA->PIO_SODR = (((x) & (1<<1)) << 8); \ + PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \ + PIOC->PIO_SODR = (((x) & (1<<3)) << 25); \ + PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \ + PIOC->PIO_SODR = (((x) & (1<<5)) << 20); \ + PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \ + PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \ +} + +#define read_8() ( ((PIOC->PIO_PDSR & (1<<22)) >> 22)\ +| ((PIOA->PIO_PDSR & (1<<9)) >> 8)\ +| ((PIOB->PIO_PDSR & (1<<25)) >> 23)\ +| ((PIOC->PIO_PDSR & (1<<28)) >> 25)\ +| ((PIOC->PIO_PDSR & (1<<26)) >> 22)\ +| ((PIOC->PIO_PDSR & (1<<25)) >> 20)\ +| ((PIOC->PIO_PDSR & (1<<24)) >> 18)\ +| ((PIOC->PIO_PDSR & (1<<23)) >> 16)\ +) +#elif SSD1289_JUMPERS == 2 +#warning jumper D0 to D8, D1 to A5. Switch #1=OFF, #2=OFF +#define AMASK (1<<4) +#define BMASK (1<<25) +#define CMASK (0xBE << 21) +#define write_8(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \ + PIOC->PIO_SODR = (((x) & (1<<0)) << 22); \ + PIOA->PIO_SODR = (((x) & (1<<1)) << 3); \ + PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \ + PIOC->PIO_SODR = (((x) & (1<<3)) << 25); \ + PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \ + PIOC->PIO_SODR = (((x) & (1<<5)) << 20); \ + PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \ + PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \ + } + +#define read_8() ( ((PIOC->PIO_PDSR & (1<<22)) >> 22)\ + | ((PIOA->PIO_PDSR & (1<<4)) >> 3)\ + | ((PIOB->PIO_PDSR & (1<<25)) >> 23)\ + | ((PIOC->PIO_PDSR & (1<<28)) >> 25)\ + | ((PIOC->PIO_PDSR & (1<<26)) >> 22)\ + | ((PIOC->PIO_PDSR & (1<<25)) >> 20)\ + | ((PIOC->PIO_PDSR & (1<<24)) >> 18)\ + | ((PIOC->PIO_PDSR & (1<<23)) >> 16)\ + ) +#endif +#define setWriteDir() { PIOA->PIO_OER = AMASK; PIOB->PIO_OER = BMASK; PIOC->PIO_OER = CMASK; } +#define setReadDir() { \ + PMC->PMC_PCER0 = (1 << ID_PIOA)|(1 << ID_PIOB)|(1 << ID_PIOC);\ + PIOA->PIO_ODR = AMASK; PIOB->PIO_ODR = BMASK; PIOC->PIO_ODR = CMASK;\ +} +#define write8(x) { write_8(x); WR_ACTIVE; WR_STROBE; WR_IDLE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_8(); RD_IDLE; RD_IDLE; RD_IDLE; } +#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } +// Shield Control macros. +#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin)) +#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin)) +#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin)) + +#elif defined(__SAM3X8E__) && defined(USE_DUE_8BIT_PROTOSHIELD) //regular UNO shield on DUE +#warning USE_DUE_8BIT_PROTOSHIELD +// configure macros for the control pins + #define RD_PORT PIOA + #define RD_PIN 16 //A0 + #define WR_PORT PIOA + #define WR_PIN 24 //A1 + #define CD_PORT PIOA + #define CD_PIN 23 //A2 + #define CS_PORT PIOA + #define CS_PIN 22 //A3 + #define RESET_PORT PIOA + #define RESET_PIN 6 //A4 +// configure macros for data bus +#define DMASK (0xFF<<0) +#define write_8(x) { PIOD->PIO_CODR = DMASK; PIOD->PIO_SODR = x; } + +#define read_8() ( PIOD->PIO_PDSR & DMASK) + #define setWriteDir() { PIOD->PIO_OER = DMASK; PIOD->PIO_PER = DMASK; } + #define setReadDir() { PMC->PMC_PCER0 = (1 << ID_PIOD); PIOD->PIO_ODR = DMASK;} +#define write8(x) { write_8(x); WR_ACTIVE; WR_STROBE; WR_IDLE; WR_IDLE; } +#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } +#define READ_8(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_8(); RD_IDLE; RD_IDLE; RD_IDLE; } +#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } +// Shield Control macros. +#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin)) +#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin)) +#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin)) + +#elif defined(__SAM3X8E__) && defined(USE_DUE_16BIT_SHIELD) //regular CTE shield on DUE +#warning USE_DUE_16BIT_SHIELD +// configure macros for the control pins +#define RD_PORT PIOA +#define RD_PIN 15 //D24 Graham +#define WR_PORT PIOD +#define WR_PIN 1 //D26 +#define CD_PORT PIOD +#define CD_PIN 0 //D25 +#define CS_PORT PIOD +#define CS_PIN 2 //D27 +#define RESET_PORT PIOD +#define RESET_PIN 3 //D28 +// configure macros for data bus +// DB0..DB7 on PIOC1..PIOC8, DB8..DB15 on PIOC12..PIOC19 +// +#define CMASKH (0xFF00<<4) +#define CMASKL (0x00FF<<1) +#define CMASK (CMASKH | CMASKL) +#define write_8(x) { PIOC->PIO_CODR = CMASKL; PIOC->PIO_SODR = (((x)&0x00FF)<<1); } +#define write_16(x) { PIOC->PIO_CODR = CMASK; \ + PIOC->PIO_SODR = (((x)&0x00FF)<<1)|(((x)&0xFF00)<<4); } +#define read_16() (((PIOC->PIO_PDSR & CMASKH)>>4)|((PIOC->PIO_PDSR & CMASKL)>>1) ) +#define read_8() (read_16() & 0xFF) +#define setWriteDir() { PIOC->PIO_OER = CMASK; PIOC->PIO_PER = CMASK; } +#define setReadDir() { PMC->PMC_PCER0 = (1 << ID_PIOC); PIOC->PIO_ODR = CMASK; } +#define write8(x) { write16(x & 0xFF); } +#define write16(x) { write_16(x); WR_ACTIVE; WR_STROBE; WR_IDLE; WR_IDLE; } +#define READ_16(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_16(); RD_IDLE; RD_IDLE; RD_IDLE; } +#define READ_8(dst) { READ_16(dst); dst &= 0xFF; } + +// Shield Control macros. +#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin)) +#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin)) +#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin)) + +#elif defined(__SAM3X8E__) && defined(USE_MEGA_16BIT_SHIELD) //regular CTE shield on DUE +#warning USE_MEGA_16BIT_SHIELD +// configure macros for the control pins +#define RD_PORT PIOA +#define RD_PIN 20 //D43 +#define WR_PORT PIOC +#define WR_PIN 7 //D39 +#define CD_PORT PIOC +#define CD_PIN 6 //D38 +#define CS_PORT PIOC +#define CS_PIN 8 //D40 +#define RESET_PORT PIOC +#define RESET_PIN 9 //D41 +// configure macros for data bus +// +#define AMASK ((1<<7)|(3<<14)) //PA7, PA14-PA15 +#define BMASK (1<<26) //PB26 +#define CMASK (31<<1) //PC1-PC5 +#define DMASK ((15<<0)|(1<<6)|(3<<9)) //PD0-PD3, PD6, PD9-PD10 + +#define write_16(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; PIOD->PIO_CODR = DMASK; \ + PIOA->PIO_SODR = (((x)&(1<<6))<<1)|(((x)&(3<<9))<<5); \ + PIOB->PIO_SODR = (((x)&(1<<8))<<18); \ + PIOC->PIO_SODR = (((x)&(1<<0))<<5); \ + PIOC->PIO_SODR = (((x)&(1<<1))<<3); \ + PIOC->PIO_SODR = (((x)&(1<<2))<<1); \ + PIOC->PIO_SODR = (((x)&(1<<3))>>1); \ + PIOC->PIO_SODR = (((x)&(1<<4))>>3); \ + PIOD->PIO_SODR = (((x)&(1<<7))<<2)|(((x)&(1<<5))<<5)|(((x)&(15<<11))>>11)|(((x)&(1<<15))>>9); \ + } + +/* +#define write_16(VL) { PIOA->PIO_CODR = AMASK; PIOC->PIO_CODR = CMASK; PIOD->PIO_CODR = DMASK; \ + REG_PIOA_SODR=((((VL)>>8) & 0x06)<<13) | ((VL & 0x40)<<1);\ + if ((VL)&(1<<8)) REG_PIOB_SODR=(1<<26); else REG_PIOB_CODR=(1<<26);\ + REG_PIOC_SODR=((VL & 0x01)<<5) | ((VL & 0x02)<<3) | ((VL & 0x04)<<1) | ((VL & 0x08)>>1) | ((VL & 0x10)>>3);\ + REG_PIOD_SODR=((((VL)>>8) & 0x78)>>3) | ((((VL)>>8) & 0x80)>>1) | ((VL & 0x20)<<5) | ((VL & 0x80)<<2);\ +} +*/ +#define read_16() ( 0\ + |((PIOC->PIO_PDSR & (1<<5))>>5)\ + |((PIOC->PIO_PDSR & (1<<4))>>3)\ + |((PIOC->PIO_PDSR & (1<<3))>>1)\ + |((PIOC->PIO_PDSR & (1<<2))<<1)\ + |((PIOC->PIO_PDSR & (1<<1))<<3)\ + |((PIOD->PIO_PDSR & (1<<10))>>5)\ + |((PIOA->PIO_PDSR & (1<<7))>>1)\ + |((PIOD->PIO_PDSR & (1<<9))>>2)\ + |((PIOB->PIO_PDSR & (1<<26))>>18)\ + |((PIOA->PIO_PDSR & (3<<14))>>5)\ + |((PIOD->PIO_PDSR & (15<<0))<<11)\ + |((PIOD->PIO_PDSR & (1<<6))<<9)\ + ) +#define read_8() (read_16() & 0xFF) +#define setWriteDir() {\ + PIOA->PIO_OER = AMASK; PIOA->PIO_PER = AMASK; \ + PIOB->PIO_OER = BMASK; PIOB->PIO_PER = BMASK; \ + PIOC->PIO_OER = CMASK; PIOC->PIO_PER = CMASK; \ + PIOD->PIO_OER = DMASK; PIOD->PIO_PER = DMASK; \ + } +#define setReadDir() { \ + PMC->PMC_PCER0 = (1 << ID_PIOA)|(1 << ID_PIOB)|(1 << ID_PIOC)|(1 << ID_PIOD); \ + PIOA->PIO_ODR = AMASK; \ + PIOB->PIO_ODR = BMASK; \ + PIOC->PIO_ODR = CMASK; \ + PIOD->PIO_ODR = DMASK; \ + } +#define write8(x) { write16(x & 0xFF); } +// ILI9486 is slower than ILI9481 +#define write16(x) { write_16(x); WR_ACTIVE; WR_ACTIVE; WR_STROBE; } +#define READ_16(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_16(); RD_IDLE; RD_IDLE; RD_IDLE; } +#define READ_8(dst) { READ_16(dst); dst &= 0xFF; } + +// Shield Control macros. +#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin)) +#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin)) +#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin)) + +#else +#define USE_SPECIAL_FAIL +#endif diff --git a/mcufriend_special_2.h b/mcufriend_special_2.h new file mode 100644 index 0000000..45f624e --- /dev/null +++ b/mcufriend_special_2.h @@ -0,0 +1,77 @@ +#elif defined(__SAM3X8E__) && defined(USE_MEGA_16BIT_SHIELD) //regular CTE shield on DUE +#warning USE_MEGA_16BIT_SHIELD +// configure macros for the control pins +#define RD_PORT PIOA +#define RD_PIN 20 //D43 +#define WR_PORT PIOC +#define WR_PIN 7 //D39 +#define CD_PORT PIOC +#define CD_PIN 6 //D38 +#define CS_PORT PIOC +#define CS_PIN 8 //D40 +#define RESET_PORT PIOC +#define RESET_PIN 9 //D41 +// configure macros for data bus +// +#define AMASK ((1<<7)|(3<<14)) //PA7, PA14-PA15 +#define BMASK (1<<26) //PB26 +#define CMASK (31<<1) //PC1-PC5 +#define DMASK ((15<<0)|(1<<6)|(3<<9)) //PD0-PD3, PD6, PD9-PD10 + +#define write_16(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; PIOD->PIO_CODR = DMASK; \ + PIOA->PIO_SODR = (((x)&(1<<6))<<1)|(((x)&(3<<9))<<5); \ + PIOB->PIO_SODR = (((x)&(1<<8))<<18); \ + PIOC->PIO_SODR = (((x)&(1<<0))<<5); \ + PIOC->PIO_SODR = (((x)&(1<<1))<<3); \ + PIOC->PIO_SODR = (((x)&(1<<2))<<1); \ + PIOC->PIO_SODR = (((x)&(1<<3))>>1); \ + PIOC->PIO_SODR = (((x)&(1<<4))>>3); \ + PIOD->PIO_SODR = (((x)&(1<<7))<<2)|(((x)&(1<<5))<<5)|(((x)&(15<<11))>>11)|(((x)&(1<<15))>>9); \ + } + +/* +#define write_16(VL) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; PIOD->PIO_CODR = DMASK; \ + REG_PIOA_SODR=(((((VL)>>8) & 0x06)<<13) | ((VL & 0x40)<<1);\ + (((VL)>>8) & 0x01) ? REG_PIOB_SODR = 0x4000000 : REG_PIOB_CODR = 0x4000000;\ + REG_PIOC_SODR=((VL & 0x01)<<5) | ((VL & 0x02)<<3) | ((VL & 0x04)<<1) | ((VL & 0x08)>>1) | ((VL & 0x10)>>3);\ + REG_PIOD_SODR=((((VL)>>8) & 0x78)>>3) | ((((VL)>>8) & 0x80)>>1) | ((VL & 0x20)<<5) | ((VL & 0x80)<<2);\ +} +*/ +#define read_16() ( 0\ + |((PIOC->PIO_PDSR & (1<<5))>>5)\ + |((PIOC->PIO_PDSR & (1<<4))>>3)\ + |((PIOC->PIO_PDSR & (1<<3))>>1)\ + |((PIOC->PIO_PDSR & (1<<2))<<1)\ + |((PIOC->PIO_PDSR & (1<<1))<<3)\ + |((PIOD->PIO_PDSR & (1<<10))>>5)\ + |((PIOA->PIO_PDSR & (1<<7))>>1)\ + |((PIOD->PIO_PDSR & (1<<9))>>2)\ + |((PIOB->PIO_PDSR & (1<<26))>>18)\ + |((PIOA->PIO_PDSR & (3<<14))>>5)\ + |((PIOD->PIO_PDSR & (15<<0))<<11)\ + |((PIOD->PIO_PDSR & (1<<6))<<9)\ + ) +#define read_8() (read_16() & 0xFF) +#define setWriteDir() {\ + PIOA->PIO_OER = AMASK; PIOA->PIO_PER = AMASK; \ + PIOB->PIO_OER = BMASK; PIOB->PIO_PER = BMASK; \ + PIOC->PIO_OER = CMASK; PIOC->PIO_PER = CMASK; \ + PIOD->PIO_OER = DMASK; PIOD->PIO_PER = DMASK; \ + } +#define setReadDir() { \ + PMC->PMC_PCER0 = (1 << ID_PIOA)|(1 << ID_PIOB)|(1 << ID_PIOC)|(1 << ID_PIOD); \ + PIOA->PIO_ODR = AMASK; \ + PIOB->PIO_ODR = BMASK; \ + PIOC->PIO_ODR = CMASK; \ + PIOD->PIO_ODR = DMASK; \ + } +#define write8(x) { write16(x & 0xFF); } +#define write16(x) { write_16(x); WR_ACTIVE; WR_STROBE; WR_IDLE; WR_IDLE; } +#define READ_16(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_16(); RD_IDLE; RD_IDLE; RD_IDLE; } +#define READ_8(dst) { READ_16(dst); dst &= 0xFF; } + +// Shield Control macros. +#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin)) +#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin)) +#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin)) +