├── README.md ├── .gitattributes ├── serial_kbv_keil.h ├── .gitignore ├── ILI9163_kbv.h ├── ST7735_kbv.h ├── ILI9225_kbv.h ├── ILI9481_kbv.h ├── ILI9341_kbv.h ├── ST7735X_kbv.h ├── HX8347_kbv.h ├── serial8_kbv.h ├── serial9_kbv.h ├── examples ├── ST7735_readreg │ └── ST7735_readreg.ino └── graphictest_kbv │ ├── graphictest_kbv.ino │ └── icons.c ├── serial_stm32_kbv.h ├── serial_kbv.h ├── tftspi_avr.h ├── ST7735_kbv.cpp ├── ILI9163_kbv.cpp ├── ILI9481_kbv.cpp ├── ILI9225_kbv.cpp ├── serial_complex.h ├── ILI9341_kbv.cpp ├── HX8347_kbv.cpp ├── ST7735X_kbv.cpp └── pin_shield_1.h /README.md: -------------------------------------------------------------------------------- 1 | # TFT_SPI_kbv 2 | Library for ILI9225, ILI9341, HX8347D, ILI9163, ST7735 in SPI mode 3 | 4 | Install "Adafruit_GFX.h" library 5 | 6 | Interface is always HARD-WIRED to SPI pins (except ILI9225) 7 | 8 | ILI9225: only Uno, Mega2560 bit-banged on A0-A5 pins 9 | 10 | HX8347D: only on AVR shields. 11 | 12 | ILI9341: any Arduino 13 | 14 | ILI9163: only 3.3V 15 | 16 | ST7735S: only 3.3V 17 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /serial_kbv_keil.h: -------------------------------------------------------------------------------- 1 | #define NUCLEO 2 | #include "pin_shield_1.h" 3 | #define CD_PORT D9_PORT 4 | #define CD_PIN D9_PIN 5 | #define CS_PORT D10_PORT 6 | #define CS_PIN D10_PIN 7 | #define RESET_PORT D8_PORT 8 | #define RESET_PIN D8_PIN 9 | #define SD_PORT D4_PORT 10 | #define SD_PIN D4_PIN 11 | #define MOSI_PORT D11_PORT 12 | #define MOSI_PIN D11_PIN 13 | #define SCK_PORT D13_PORT 14 | #define SCK_PIN D13_PIN 15 | 16 | #define SPI_PORT MOSI_PORT 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /ILI9163_kbv.h: -------------------------------------------------------------------------------- 1 | #ifndef ILI9163_KBV_H_ 2 | #define ILI9163_KBV_H_ 100 3 | 4 | #define USE_MBED 0 5 | 6 | #if ARDUINO < 165 7 | #define USE_GFX_KBV 8 | #include "ADA_GFX_kbv.h" 9 | #else 10 | #include "Adafruit_GFX.h" 11 | #endif 12 | 13 | class ILI9163_kbv : public Adafruit_GFX { 14 | 15 | public: 16 | ILI9163_kbv(); 17 | void reset(void); // you only need the constructor 18 | void begin(uint16_t ID); // you only need the constructor 19 | virtual void drawPixel(int16_t x, int16_t y, uint16_t color); // and these three 20 | void WriteCmdData(uint16_t cmd, uint16_t dat); // public methods !!! 21 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } 22 | uint16_t readID(void); 23 | 24 | virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); 25 | virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { fillRect(x, y, 1, h, color); } 26 | virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { fillRect(x, y, w, 1, color); } 27 | virtual void fillScreen(uint16_t color) { fillRect(0, 0, _width, _height, color); } 28 | virtual void setRotation(uint8_t r); 29 | virtual void invertDisplay(boolean i); 30 | 31 | uint16_t readReg(uint16_t reg); 32 | uint32_t readReg32(uint16_t reg); 33 | int16_t readGRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h); 34 | uint16_t readPixel(int16_t x, int16_t y) { uint16_t color; readGRAM(x, y, &color, 1, 1); return color; } 35 | void setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1); 36 | void pushColors(uint16_t *block, int16_t n, bool first); 37 | void pushColors(const uint8_t *block, int16_t n, bool first); 38 | void vertScroll(int16_t top, int16_t scrollines, int16_t offset); 39 | 40 | protected: 41 | 42 | private: 43 | uint16_t _lcd_ID; 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /ST7735_kbv.h: -------------------------------------------------------------------------------- 1 | #ifndef ST7735_KBV_H_ 2 | #define ST7735_KBV_H_ 100 3 | 4 | #define USE_MBED 0 5 | 6 | #if ARDUINO < 165 7 | #define USE_GFX_KBV 8 | #include "ADA_GFX_kbv.h" 9 | #else 10 | #include "Adafruit_GFX.h" 11 | #endif 12 | 13 | class ST7735_kbv : public Adafruit_GFX { 14 | 15 | public: 16 | // ST7735_kbv(); 17 | ST7735_kbv(int w=128, int h=160); 18 | void reset(void); // you only need the constructor 19 | void begin(uint16_t ID=0x7735); // you only need the constructor 20 | virtual void drawPixel(int16_t x, int16_t y, uint16_t color); // and these three 21 | void WriteCmdData(uint16_t cmd, uint16_t dat); // public methods !!! 22 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } 23 | uint16_t readID(void); 24 | 25 | virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); 26 | virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { fillRect(x, y, 1, h, color); } 27 | virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { fillRect(x, y, w, 1, color); } 28 | virtual void fillScreen(uint16_t color) { fillRect(0, 0, _width, _height, color); } 29 | virtual void setRotation(uint8_t r); 30 | virtual void invertDisplay(boolean i); 31 | 32 | uint16_t readReg(uint16_t reg); 33 | uint32_t readReg32(uint16_t reg); 34 | int16_t readGRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h); 35 | uint16_t readPixel(int16_t x, int16_t y) { uint16_t color; readGRAM(x, y, &color, 1, 1); return color; } 36 | void setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1); 37 | void pushColors(uint16_t *block, int16_t n, bool first); 38 | void pushColors(const uint8_t *block, int16_t n, bool first); 39 | void vertScroll(int16_t top, int16_t scrollines, int16_t offset); 40 | 41 | protected: 42 | 43 | private: 44 | uint16_t _lcd_ID; 45 | uint8_t __OFFSET; 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /ILI9225_kbv.h: -------------------------------------------------------------------------------- 1 | #ifndef ILI9225_KBV_H_ 2 | #define ILI9225_KBV_H_ 100 3 | 4 | #define USE_MBED 0 5 | 6 | #if ARDUINO < 165 7 | #define USE_GFX_KBV 8 | #include "ADA_GFX_kbv.h" 9 | #else 10 | #include "Adafruit_GFX.h" 11 | #endif 12 | 13 | class ILI9225_kbv : public Adafruit_GFX { 14 | 15 | public: 16 | ILI9225_kbv(); 17 | void reset(void); // you only need the constructor 18 | void begin(uint16_t ID = 0x9225); // you only need the constructor 19 | virtual void drawPixel(int16_t x, int16_t y, uint16_t color); // and these three 20 | void WriteCmdData(uint16_t cmd, uint16_t dat); // public methods !!! 21 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } 22 | uint16_t readID(void) { return 0x9225; } 23 | 24 | virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); 25 | virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { fillRect(x, y, 1, h, color); } 26 | virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { fillRect(x, y, w, 1, color); } 27 | virtual void fillScreen(uint16_t color) { fillRect(0, 0, _width, _height, color); } 28 | virtual void setRotation(uint8_t r); 29 | virtual void invertDisplay(boolean i); 30 | 31 | uint16_t readReg(uint16_t reg); 32 | uint32_t readReg32(uint16_t reg); 33 | int16_t readGRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h); 34 | uint16_t readPixel(int16_t x, int16_t y) { uint16_t color; readGRAM(x, y, &color, 1, 1); return color; } 35 | void setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1); 36 | void pushColors(uint16_t *block, int16_t n, bool first); 37 | void pushColors(uint8_t *block, int16_t n, bool first); 38 | void pushColors(const uint8_t *block, int16_t n, bool first, bool bigend = false); 39 | void vertScroll(int16_t top, int16_t scrollines, int16_t offset); 40 | 41 | protected: 42 | 43 | private: 44 | uint16_t _lcd_ID; 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /ILI9481_kbv.h: -------------------------------------------------------------------------------- 1 | #ifndef ILI9481_KBV_H_ 2 | #define ILI9481_KBV_H_ 100 3 | 4 | #define USE_MBED 0 5 | 6 | #if ARDUINO < 165 7 | #define USE_GFX_KBV 8 | #include "ADA_GFX_kbv.h" 9 | #else 10 | #include "Adafruit_GFX.h" 11 | #endif 12 | 13 | class ILI9481_kbv : public Adafruit_GFX { 14 | 15 | public: 16 | ILI9481_kbv(); 17 | void reset(void); // you only need the constructor 18 | void begin(uint16_t ID = 0x9481); // you only need the constructor 19 | virtual void drawPixel(int16_t x, int16_t y, uint16_t color); // and these three 20 | // void WriteCmdData(uint16_t cmd, uint16_t dat); // public methods !!! 21 | void pushCommand(uint16_t cmd, uint8_t * block, int8_t N); 22 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } 23 | uint16_t readID(void) { return readReg32(0xBF) >> 8; } 24 | 25 | virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); 26 | virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { fillRect(x, y, 1, h, color); } 27 | virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { fillRect(x, y, w, 1, color); } 28 | virtual void fillScreen(uint16_t color) { fillRect(0, 0, _width, _height, color); } 29 | virtual void setRotation(uint8_t r); 30 | virtual void invertDisplay(boolean i); 31 | 32 | uint16_t readReg(uint16_t reg); 33 | uint32_t readReg32(uint16_t reg); 34 | int16_t readGRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h); 35 | uint16_t readPixel(int16_t x, int16_t y) { uint16_t color; readGRAM(x, y, &color, 1, 1); return color; } 36 | void setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1); 37 | void pushColors(uint16_t *block, int16_t n, bool first); 38 | void pushColors(uint8_t *block, int16_t n, bool first); 39 | void pushColors(const uint8_t *block, int16_t n, bool first, bool bigend = false); 40 | void vertScroll(int16_t top, int16_t scrollines, int16_t offset); 41 | 42 | protected: 43 | 44 | private: 45 | uint16_t _lcd_ID, _lcd_xor; 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /ILI9341_kbv.h: -------------------------------------------------------------------------------- 1 | #ifndef ILI9341_KBV_H_ 2 | #define ILI9341_KBV_H_ 100 3 | 4 | #define USE_MBED 0 5 | 6 | #if ARDUINO < 165 7 | #define USE_GFX_KBV 8 | #include "ADA_GFX_kbv.h" 9 | #else 10 | #include "Adafruit_GFX.h" 11 | #endif 12 | 13 | class ILI9341_kbv : public Adafruit_GFX { 14 | 15 | public: 16 | ILI9341_kbv(); 17 | void reset(void); // you only need the constructor 18 | void begin(uint16_t ID = 0x9341); // you only need the constructor 19 | virtual void drawPixel(int16_t x, int16_t y, uint16_t color); // and these three 20 | void pushCommand(uint16_t cmd, uint8_t * block, int8_t N); 21 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } 22 | uint16_t readID(void); // { return 0x9341; } 23 | 24 | virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); 25 | virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { fillRect(x, y, 1, h, color); } 26 | virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { fillRect(x, y, w, 1, color); } 27 | virtual void fillScreen(uint16_t color) { fillRect(0, 0, _width, _height, color); } 28 | virtual void setRotation(uint8_t r); 29 | virtual void invertDisplay(boolean i); 30 | 31 | uint8_t readcommand8(uint8_t reg, uint8_t idx = 0); //this is the same as Adafruit_ILI9341 32 | uint16_t readReg(uint16_t reg, uint8_t idx = 0); //note that this reads pairs of data bytes 33 | int16_t readGRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h); 34 | uint16_t readPixel(int16_t x, int16_t y) { uint16_t color; readGRAM(x, y, &color, 1, 1); return color; } 35 | void setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1); 36 | void pushColors(uint16_t *block, int16_t n, bool first); 37 | void pushColors(uint8_t *block, int16_t n, bool first); //NEW 38 | void pushColors(const uint8_t *block, int16_t n, bool first, bool bigend = false); //NEW 39 | void vertScroll(int16_t top, int16_t scrollines, int16_t offset); 40 | 41 | protected: 42 | 43 | private: 44 | uint16_t _lcd_ID; 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /ST7735X_kbv.h: -------------------------------------------------------------------------------- 1 | #ifndef ST7735X_KBV_H_ 2 | #define ST7735X_KBV_H_ 100 3 | 4 | #define USE_MBED 0 5 | 6 | #if ARDUINO < 165 7 | #define USE_GFX_KBV 8 | #include "ADA_GFX_kbv.h" 9 | #else 10 | #include "Adafruit_GFX.h" 11 | #endif 12 | 13 | class ST7735X_kbv : public Adafruit_GFX { 14 | 15 | public: 16 | // ST7735X_kbv(); 17 | ST7735X_kbv(int w=128, int h=160); 18 | void reset(void); // you only need the constructor 19 | void begin(uint16_t ID=0x7735); // you only need the constructor 20 | virtual void drawPixel(int16_t x, int16_t y, uint16_t color); // and these three 21 | void WriteCmdData(uint16_t cmd, uint16_t dat); // ?public methods !!! 22 | void pushCommand(uint16_t cmd, uint8_t * block, int8_t N); 23 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } 24 | uint16_t readID(void); 25 | 26 | virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); 27 | virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { fillRect(x, y, 1, h, color); } 28 | virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { fillRect(x, y, w, 1, color); } 29 | virtual void fillScreen(uint16_t color) { fillRect(0, 0, _width, _height, color); } 30 | virtual void setRotation(uint8_t r); 31 | virtual void invertDisplay(boolean i); 32 | 33 | uint16_t readReg(uint16_t reg); 34 | uint32_t readReg32(uint16_t reg); 35 | int16_t readGRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h); 36 | uint16_t readPixel(int16_t x, int16_t y) { uint16_t color; readGRAM(x, y, &color, 1, 1); return color; } 37 | void setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1); 38 | void pushColors(uint16_t *block, int16_t n, bool first); 39 | void pushColors(uint8_t *block, int16_t n, bool first); 40 | void pushColors(const uint8_t *block, int16_t n, bool first, bool bigend = false); 41 | void vertScroll(int16_t top, int16_t scrollines, int16_t offset); 42 | 43 | protected: 44 | 45 | private: 46 | uint16_t _lcd_ID; 47 | uint8_t _lcd_xor, _is7735, __OFFSET; 48 | }; 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /HX8347_kbv.h: -------------------------------------------------------------------------------- 1 | #ifndef HX8347_KBV_H_ 2 | #define HX8347_KBV_H_ 3 | 4 | #define USE_MBED 0 5 | 6 | #if ARDUINO < 165 7 | #define USE_GFX_KBV 8 | #include "ADA_GFX_kbv.h" 9 | #else 10 | #include "Adafruit_GFX.h" 11 | #endif 12 | 13 | class HX8347_kbv : public Adafruit_GFX { 14 | 15 | public: 16 | #if USE_MBED 17 | #if defined(TARGET_LPC1768) 18 | HX8347_kbv(PinName CS=p8, PinName RS=p7, PinName RST=p10); 19 | #else 20 | HX8347_kbv(PinName CS=D10, PinName RS=D7, PinName RST=D9); 21 | #endif 22 | #else 23 | HX8347_kbv(); 24 | #endif 25 | void reset(void); // you only need the constructor 26 | void begin(uint16_t ID = 0x7575); // you only need the constructor 27 | virtual void drawPixel(int16_t x, int16_t y, uint16_t color); // and these three 28 | void WriteCmdData(uint16_t cmd, uint16_t dat); // public methods !!! 29 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } 30 | uint16_t readID(void) { return _lcd_ID; } 31 | 32 | virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); 33 | virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { fillRect(x, y, 1, h, color); } 34 | virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { fillRect(x, y, w, 1, color); } 35 | virtual void fillScreen(uint16_t color) { fillRect(0, 0, _width, _height, color); } 36 | virtual void setRotation(uint8_t r); 37 | virtual void invertDisplay(boolean i); 38 | 39 | uint16_t readReg(uint16_t reg); 40 | int16_t readGRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h); 41 | uint16_t readPixel(int16_t x, int16_t y) { uint16_t color; readGRAM(x, y, &color, 1, 1); return color; } 42 | void setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1); 43 | void pushColors(uint16_t *block, int16_t n, bool first); 44 | void pushColors(uint8_t *block, int16_t n, bool first); 45 | void pushColors(const uint8_t *block, int16_t n, bool first, bool bigend = false); 46 | void vertScroll(int16_t top, int16_t scrollines, int16_t offset); 47 | 48 | 49 | protected: 50 | 51 | private: 52 | #if USE_MBED 53 | SPI _spi; 54 | DigitalOut _lcd_pin_cs, _lcd_pin_rs, _lcd_pin_reset; 55 | #endif 56 | uint16_t _lcd_ID; 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /serial8_kbv.h: -------------------------------------------------------------------------------- 1 | // this file is only used for 9-bit bidirectional ILI9481 2 | 3 | #define USE_SPICLASS 4 | //#define KLUDGE_328P 5 | 6 | #define CD_COMMAND PIN_LOW(CD_PORT, CD_PIN) 7 | #define CD_DATA PIN_HIGH(CD_PORT, CD_PIN) 8 | #define CD_OUTPUT PIN_OUTPUT(CD_PORT, CD_PIN) 9 | #define CS_ACTIVE PIN_LOW(CS_PORT, CS_PIN); 10 | #define CS_IDLE PIN_HIGH(CS_PORT, CS_PIN); 11 | #define CS_OUTPUT PIN_OUTPUT(CS_PORT, CS_PIN) 12 | #define RESET_ACTIVE PIN_LOW(RESET_PORT, RESET_PIN) 13 | #define RESET_IDLE PIN_HIGH(RESET_PORT, RESET_PIN) 14 | #define RESET_OUTPUT PIN_OUTPUT(RESET_PORT, RESET_PIN) 15 | #define SD_ACTIVE PIN_LOW(SD_PORT, SD_PIN) 16 | #define SD_IDLE PIN_HIGH(SD_PORT, SD_PIN) 17 | #define SD_OUTPUT PIN_OUTPUT(SD_PORT, SD_PIN) 18 | // bit-bang macros for SDIO 19 | #define SCK_LO PIN_LOW(SPI_PORT, SCK_PIN) 20 | #define SCK_HI PIN_HIGH(SPI_PORT, SCK_PIN) 21 | #define SCK_OUT PIN_OUTPUT(SPI_PORT, SCK_PIN) 22 | #define MOSI_LO PIN_LOW(SPI_PORT, MOSI_PIN) 23 | #define MOSI_HI PIN_HIGH(SPI_PORT, MOSI_PIN) 24 | #define MOSI_OUT PIN_OUTPUT(SPI_PORT, MOSI_PIN) 25 | #define MOSI_IN PIN_INPUT(SPI_PORT, MOSI_PIN) 26 | #define LED_LO PIN_LOW(LED_PORT, LED_PIN) 27 | #define LED_HI PIN_HIGH(LED_PORT, LED_PIN) 28 | #define LED_OUT PIN_OUTPUT(LED_PORT, LED_PIN) 29 | 30 | #define wait_ms(ms) delay(ms) 31 | #define xchg8(x) readbits(8) 32 | #define write8(x) SPI.transfer(x) 33 | #define write18(x) { write18_N(x, 1); } 34 | #define WriteCmd(x) { CD_COMMAND; write8(x); } 35 | #define WriteDat8(x) { CD_DATA; write8(x); } 36 | 37 | #include 38 | static uint8_t spibuf[16]; 39 | 40 | #define CD_PIN 9 41 | #define CS_PIN 10 42 | #define RESET_PIN 8 43 | #define SD_PIN 4 44 | #define MOSI_PIN 75 //11 45 | #define SCK_PIN 76 //13 46 | 47 | #define PIN_LOW(p, b) digitalWrite(b, LOW) 48 | #define PIN_HIGH(p, b) digitalWrite(b, HIGH) 49 | #define PIN_OUTPUT(p, b) pinMode(b, OUTPUT) 50 | #define PIN_INPUT(p, b) pinMode(b, INPUT_PULLUP) 51 | #define PIN_READ(p, b) digitalRead(b) 52 | 53 | #define SETDDR { CS_OUTPUT; CD_OUTPUT; RESET_OUTPUT; PIN_HIGH(SD_PORT, SD_PIN); PIN_OUTPUT(SD_PORT, SD_PIN); } 54 | #define INIT() { CS_IDLE; RESET_IDLE; SETDDR; SPI.begin(CS_PIN); } 55 | 56 | #define SDIO_OUTMODE() {MOSI_OUT;SCK_OUT;} 57 | 58 | static uint32_t readbits(int8_t bits) 59 | { 60 | uint32_t ret = 0; 61 | while (bits > 0) { 62 | ret <<= 8; 63 | ret |= SPI.transfer(0); 64 | bits -= 8; 65 | } 66 | return ret; 67 | } 68 | 69 | static inline void write18_N(uint16_t color, int16_t n) 70 | { 71 | uint8_t r = color >> 8, g = (color >> 5), b = color << 3; 72 | while (n-- > 0) { 73 | WriteDat8(r); 74 | WriteDat8(g); 75 | WriteDat8(b); 76 | } 77 | } 78 | 79 | static inline void write9_block(uint8_t * block, int16_t n) 80 | { 81 | while (n-- > 0) { 82 | WriteDat8(*block++); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /serial9_kbv.h: -------------------------------------------------------------------------------- 1 | // this file is only used for 9-bit bidirectional ILI9481 2 | 3 | #define USE_SPICLASS 4 | #define KLUDGE_328P 5 | 6 | #define CD_COMMAND PIN_LOW(CD_PORT, CD_PIN) 7 | #define CD_DATA PIN_HIGH(CD_PORT, CD_PIN) 8 | #define CD_OUTPUT PIN_OUTPUT(CD_PORT, CD_PIN) 9 | #define CS_ACTIVE PIN_LOW(CS_PORT, CS_PIN); 10 | #define CS_IDLE PIN_HIGH(CS_PORT, CS_PIN); 11 | #define CS_OUTPUT PIN_OUTPUT(CS_PORT, CS_PIN) 12 | #define RESET_ACTIVE PIN_LOW(RESET_PORT, RESET_PIN) 13 | #define RESET_IDLE PIN_HIGH(RESET_PORT, RESET_PIN) 14 | #define RESET_OUTPUT PIN_OUTPUT(RESET_PORT, RESET_PIN) 15 | #define SD_ACTIVE PIN_LOW(SD_PORT, SD_PIN) 16 | #define SD_IDLE PIN_HIGH(SD_PORT, SD_PIN) 17 | #define SD_OUTPUT PIN_OUTPUT(SD_PORT, SD_PIN) 18 | // bit-bang macros for SDIO 19 | #define SCK_LO PIN_LOW(SPI_PORT, SCK_PIN) 20 | #define SCK_HI PIN_HIGH(SPI_PORT, SCK_PIN) 21 | #define SCK_OUT PIN_OUTPUT(SPI_PORT, SCK_PIN) 22 | #define MOSI_LO PIN_LOW(SPI_PORT, MOSI_PIN) 23 | #define MOSI_HI PIN_HIGH(SPI_PORT, MOSI_PIN) 24 | #define MOSI_OUT PIN_OUTPUT(SPI_PORT, MOSI_PIN) 25 | #define MOSI_IN PIN_INPUT(SPI_PORT, MOSI_PIN) 26 | #define LED_LO PIN_LOW(LED_PORT, LED_PIN) 27 | #define LED_HI PIN_HIGH(LED_PORT, LED_PIN) 28 | #define LED_OUT PIN_OUTPUT(LED_PORT, LED_PIN) 29 | 30 | #define wait_ms(ms) delay(ms) 31 | #define xchg8(x) readbits(8); 32 | #define write24(x) { write24_N(x, 1); } 33 | #define WriteCmd(x) { SDIO_OUTMODE(); MOSI_LO; SCK_HI; SCK_LO; write_8(x); } 34 | #define WriteDat8(x) { MOSI_HI; SCK_HI; SCK_LO; write_8(x); } 35 | 36 | #if !defined(USE_SPICLASS) 37 | #include "serial_complex.h" 38 | #else 39 | #warning Using Arduino SPI methods 40 | 41 | #include 42 | static uint8_t spibuf[16]; 43 | 44 | #if defined(KLUDGE_328P) 45 | #define CD_PORT PORTB 46 | #define CD_PIN PB1 47 | #define CS_PORT PORTB 48 | #define CS_PIN PB2 49 | #define RESET_PORT PORTB 50 | #define RESET_PIN PB0 51 | #define SD_PORT PORTD 52 | #define SD_PIN PD4 53 | #define SPI_PORT PORTB 54 | #define MOSI_PIN PB3 55 | #define SCK_PIN PB5 56 | 57 | #define PIN_LOW(p, b) (p) &= ~(1<<(b)) 58 | #define PIN_HIGH(p, b) (p) |= (1<<(b)) 59 | #define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) 60 | #define PIN_INPUT(p, b) *(&p-1) &= ~(1<<(b)) 61 | #define PIN_READ(p, b) (*(&p-2) & (1<<(b))) 62 | #else 63 | #define CD_PIN 9 64 | #define CS_PIN 10 65 | #define RESET_PIN 8 66 | #define SD_PIN 4 67 | #define MOSI_PIN 11 68 | #define SCK_PIN 13 69 | 70 | #define PIN_LOW(p, b) digitalWrite(b, LOW) 71 | #define PIN_HIGH(p, b) digitalWrite(b, HIGH) 72 | #define PIN_OUTPUT(p, b) pinMode(b, OUTPUT) 73 | #define PIN_INPUT(p, b) pinMode(b, INPUT_PULLUP) 74 | #define PIN_READ(p, b) digitalRead(b) 75 | #endif 76 | 77 | #define SETDDR { CS_OUTPUT; CD_OUTPUT; RESET_OUTPUT; PIN_HIGH(SD_PORT, SD_PIN); PIN_OUTPUT(SD_PORT, SD_PIN); } 78 | #define INIT() { CS_IDLE; RESET_IDLE; SETDDR; } 79 | 80 | #define SDIO_INMODE() MOSI_IN;SCK_OUT //no braces 81 | #define SDIO_OUTMODE() {MOSI_OUT;SCK_OUT;} 82 | 83 | static inline void write_8(uint8_t val) 84 | { 85 | #if defined(KLUDGE_328P) // -90.0 sec 86 | SPCR = (1<> 9) | 0x80, g = (color >> 5) | 0x40, b = color | 0x20; 120 | while (n-- > 0) { 121 | SPCR = (1<> 8, g = (color >> 3), b = color << 3; 134 | while (n-- > 0) { 135 | WriteDat8(r); 136 | WriteDat8(g); 137 | WriteDat8(b); 138 | } 139 | #endif 140 | } 141 | 142 | static inline void write8_block(uint8_t * block, int16_t n) 143 | { 144 | while (n-- > 0) { 145 | WriteDat8(*block++); 146 | } 147 | } 148 | #endif 149 | -------------------------------------------------------------------------------- /examples/ST7735_readreg/ST7735_readreg.ino: -------------------------------------------------------------------------------- 1 | // see if 4-line mode can read anything 2 | 3 | #define TFT_MOSI 11 4 | #define TFT_SCK 13 5 | #define TFT_SS 10 6 | #define TFT_DC (9) //DC=7 for HX8347 7 | #define TFT_RESET (8) //Backlight on HX8347 8 | char *chip = "controller"; 9 | 10 | #if defined(SPDR) 11 | // use SPI mode #0 12 | uint8_t spi(uint8_t c) 13 | { 14 | SPDR = c; 15 | while ((SPSR & 0x80) == 0) ; 16 | return SPDR; 17 | } 18 | #endif 19 | 20 | uint32_t readwrite8(uint8_t cmd, uint8_t bits, uint8_t dummy) 21 | { 22 | uint32_t ret = 0; 23 | uint8_t val = cmd; 24 | int cnt = 8; 25 | digitalWrite(TFT_SS, LOW); 26 | #if 0 27 | SPSR = (0 << SPI2X); 28 | SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0); //1MHz 29 | digitalWrite(TFT_DC, LOW); 30 | pinMode(TFT_MOSI, OUTPUT); 31 | spi(cmd); 32 | if (bits) { 33 | digitalWrite(TFT_DC, HIGH); 34 | pinMode(TFT_MOSI, INPUT); 35 | while (bits) { 36 | ret <<= 8; 37 | ret |= spi(0x00); 38 | bits -= 8; 39 | } 40 | ret >>= dummy; 41 | } 42 | #elif 0 43 | digitalWrite(TFT_DC, LOW); 44 | pinMode(TFT_MOSI, OUTPUT); 45 | for (uint8_t i = 0; i < 8; i++) { //send command 46 | if (val & 0x80) PORTB |= (1 << 3); 47 | else PORTB &= ~(1 << 3); 48 | PORTB |= (1 << 5); 49 | PORTB &= ~(1 << 5); 50 | val <<= 1; 51 | } 52 | if (bits == 0) { 53 | digitalWrite(TFT_SS, HIGH); 54 | return 0; 55 | } 56 | pinMode(TFT_MOSI, INPUT_PULLUP); 57 | digitalWrite(TFT_DC, HIGH); 58 | for (uint8_t i = 0; i < dummy; i++) { //any dummy clocks 59 | PORTB |= (1 << 5); 60 | PORTB &= ~(1 << 5); 61 | } 62 | while (bits) { 63 | for (uint8_t i = 8; i-- > 0; ) { // read results 64 | val <<= 1; 65 | if (PINB & (1 << 3)) val |= 1;; 66 | PORTB |= (1 << 5); 67 | PORTB &= ~(1 << 5); 68 | } 69 | bits -= 8; 70 | ret <<= 8; 71 | ret |= val; 72 | } 73 | #else 74 | digitalWrite(TFT_DC, LOW); 75 | pinMode(TFT_MOSI, OUTPUT); 76 | for (int i = 0; i < 8; i++) { //send command 77 | digitalWrite(TFT_MOSI, (val & 0x80) != 0); 78 | digitalWrite(TFT_SCK, HIGH); 79 | digitalWrite(TFT_SCK, LOW); 80 | val <<= 1; 81 | } 82 | if (bits == 0) { 83 | digitalWrite(TFT_SS, HIGH); 84 | return 0; 85 | } 86 | pinMode(TFT_MOSI, INPUT_PULLUP); 87 | digitalWrite(TFT_DC, HIGH); 88 | for (int i = 0; i < dummy; i++) { //any dummy clocks 89 | digitalWrite(TFT_SCK, HIGH); 90 | digitalWrite(TFT_SCK, LOW); 91 | } 92 | for (int i = 0; i < bits; i++) { // read results 93 | ret <<= 1; 94 | if (digitalRead(TFT_MOSI)) ret |= 1;; 95 | digitalWrite(TFT_SCK, HIGH); 96 | digitalWrite(TFT_SCK, LOW); 97 | } 98 | #endif 99 | digitalWrite(TFT_SS, HIGH); 100 | return ret; 101 | } 102 | 103 | void showreg(uint8_t reg, uint8_t bits, uint8_t dummy) 104 | { 105 | uint32_t val; 106 | val = readwrite8(reg, bits, dummy); 107 | 108 | Serial.print(chip); 109 | Serial.print(" reg(0x"); 110 | if (reg < 0x10) Serial.print("0"); 111 | Serial.print(reg , HEX); 112 | Serial.print(") = 0x"); 113 | if (val < 0x10) Serial.print("0"); 114 | Serial.println(val, HEX); 115 | 116 | } 117 | 118 | void setup() { 119 | // put your setup code here, to run once: 120 | uint32_t ID = 0; 121 | Serial.begin(9600); 122 | Serial.println("Bi-directional Read registers"); 123 | digitalWrite(TFT_SS, HIGH); 124 | // digitalWrite(TFT_SCK, HIGH); 125 | pinMode(TFT_SS, OUTPUT); 126 | pinMode(TFT_SCK, OUTPUT); 127 | pinMode(TFT_MOSI, OUTPUT); 128 | pinMode(MISO, INPUT); 129 | pinMode(TFT_DC, OUTPUT); 130 | pinMode(TFT_RESET, OUTPUT); 131 | digitalWrite(TFT_RESET, HIGH); 132 | digitalWrite(TFT_RESET, LOW); //Hardware Reset 133 | delay(50); 134 | digitalWrite(TFT_RESET, HIGH); 135 | showreg(0x01, 0, 0); //Software Reset 136 | delay(100); 137 | ID = readwrite8(0x04, 24, 1); 138 | if (ID == 0x7C89F0uL) chip = "ST7735S"; 139 | if (ID == 0x548066uL) chip = "ILI9163C"; 140 | ID &= 0xFF0000; 141 | if (ID == 0x5C0000) chip = "ST7735"; 142 | showreg(0x04, 24, 1); //RDDID 143 | showreg(0x09, 32, 1); //RDDSTATUS 144 | showreg(0x0A, 8, 0); 145 | showreg(0x0B, 8, 0); //RDDMADCTL 146 | showreg(0x0C, 8, 0); //RDDCOLMOD 147 | showreg(0x0D, 8, 0); 148 | showreg(0x0E, 8, 0); 149 | showreg(0x0F, 8, 0); 150 | showreg(0x2E, 24, 8); //readGRAM 151 | showreg(0xDA, 8, 0); //RDID1 152 | showreg(0xDB, 8, 0); //RDID2 153 | showreg(0xDC, 8, 0); //RDID3 154 | } 155 | 156 | void loop() { 157 | // put your main code here, to run repeatedly: 158 | 159 | } 160 | -------------------------------------------------------------------------------- /serial_stm32_kbv.h: -------------------------------------------------------------------------------- 1 | #define CD_COMMAND PIN_LOW(CD_PORT, CD_PIN) 2 | #define CD_DATA PIN_HIGH(CD_PORT, CD_PIN) 3 | #define CD_OUTPUT PIN_OUTPUT(CD_PORT, CD_PIN) 4 | #define CS_ACTIVE PIN_LOW(CS_PORT, CS_PIN); 5 | #define CS_IDLE PIN_HIGH(CS_PORT, CS_PIN); 6 | #define CS_OUTPUT PIN_OUTPUT(CS_PORT, CS_PIN) 7 | #define RESET_ACTIVE PIN_LOW(RESET_PORT, RESET_PIN) 8 | #define RESET_IDLE PIN_HIGH(RESET_PORT, RESET_PIN) 9 | #define RESET_OUTPUT PIN_OUTPUT(RESET_PORT, RESET_PIN) 10 | #define SD_ACTIVE PIN_LOW(SD_PORT, SD_PIN) 11 | #define SD_IDLE PIN_HIGH(SD_PORT, SD_PIN) 12 | #define SD_OUTPUT PIN_OUTPUT(SD_PORT, SD_PIN) 13 | // bit-bang macros for SDIO 14 | #define SCK_LO PIN_LOW(SPI_PORT, SCK_PIN) 15 | #define SCK_HI PIN_HIGH(SPI_PORT, SCK_PIN) 16 | #define SCK_OUT PIN_OUTPUT(SPI_PORT, SCK_PIN) 17 | #define MOSI_LO PIN_LOW(SPI_PORT, MOSI_PIN) 18 | #define MOSI_HI PIN_HIGH(SPI_PORT, MOSI_PIN) 19 | #define MOSI_OUT PIN_OUTPUT(SPI_PORT, MOSI_PIN) 20 | #define MOSI_IN PIN_INPUT(SPI_PORT, MOSI_PIN) 21 | #define LED_LO PIN_LOW(LED_PORT, LED_PIN) 22 | #define LED_HI PIN_HIGH(LED_PORT, LED_PIN) 23 | #define LED_OUT PIN_OUTPUT(LED_PORT, LED_PIN) 24 | 25 | #if defined(__STM32F1__) && defined(ARDUINO_STM_NUCLEO_F103RB) // Uno Shield on NUCLEO-F103 26 | #warning Uno Shield on NUCLEO-F103 REGS 27 | // be wise to clear all four mode bits properly. 28 | #define GROUP_MODE(port, reg, mask, val) {port->regs->reg = (port->regs->reg & ~(mask)) | ((mask)&(val)); } 29 | #define GP_OUT(port, reg, mask) GROUP_MODE(port, reg, mask, 0x33333333) 30 | #define GP_INP(port, reg, mask) GROUP_MODE(port, reg, mask, 0x44444444) 31 | 32 | #define CD_PORT GPIOC 33 | #define CD_PIN 7 34 | #define CS_PORT GPIOB 35 | #define CS_PIN 6 36 | #define RESET_PORT GPIOA 37 | #define RESET_PIN 9 38 | #define SD_PORT GPIOB 39 | #define SD_PIN 5 40 | #define MOSI_PORT GPIOA 41 | #define MOSI_PIN 7 42 | #define SCK_PORT GPIOA 43 | #define SCK_PIN 5 44 | 45 | #define SPI_PORT GPIOA 46 | 47 | #define PIN_HIGH(port, pin) (port)->regs->BSRR = (1<<(pin)) 48 | #define PIN_LOW(port, pin) (port)->regs->BSRR = (1<<((pin)+16)) 49 | //#define PIN_LOW(port, pin) (port)->regs->ODR &= ~(1<<(pin)) 50 | #define PIN_OUTPUT(port, pin) gpio_set_mode(port, pin, GPIO_OUTPUT_PP) //50MHz push-pull only 0-7 51 | #define PIN_INPUT(port, pin) gpio_set_mode(port, pin, GPIO_INPUT_FLOATING) //digital input 52 | #define PIN_READ(port, pin) ((port)->regs->IDR & (1<<(pin))) 53 | #else 54 | #error mcu unsupported 55 | #endif 56 | 57 | #define xchg8(x) readbits(8) 58 | #define WriteCmd(x) { SDIO_OUTMODE(); MOSI_LO; SCK_HI; SCK_HI; SCK_LO; write_8(x); } 59 | #define WriteDat8(x) { MOSI_HI; SCK_HI; SCK_HI; SCK_LO; write_8(x); } 60 | #define INIT() { CS_IDLE; RESET_IDLE; SETDDR; } 61 | #define SDIO_INMODE() MOSI_IN;SCK_OUT //no braces 62 | #define SDIO_OUTMODE() {MOSI_OUT;SCK_OUT;} 63 | 64 | #define wait_ms(ms) delay(ms) 65 | #define write16(x) { write16_N(x, 1); } 66 | #define write24(x) { write24_N(x, 1); } 67 | #define WriteData(x) { write16(x); } 68 | 69 | #define SETDDR { CS_OUTPUT; CD_OUTPUT; RESET_OUTPUT; PIN_HIGH(SD_PORT, SD_PIN); PIN_OUTPUT(SD_PORT, SD_PIN); } 70 | 71 | static uint8_t spibuf[16]; 72 | 73 | static inline void write_8(uint8_t val) 74 | { 75 | //Saleae is unhappy with 41.67ns SCK pulses. It misses them 76 | //unrolling works fine for the TFT. Loop versions give 83ns SCK 77 | #if 0 78 | uint8_t mask = 0x80; 79 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; val <<= 1; SCK_LO; 80 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; val <<= 1; SCK_LO; 81 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; val <<= 1; SCK_LO; 82 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; val <<= 1; SCK_LO; 83 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; val <<= 1; SCK_LO; 84 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; val <<= 1; SCK_LO; 85 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; val <<= 1; SCK_LO; 86 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; val <<= 1; SCK_LO; 87 | #elif 0 88 | uint8_t mask = 0x80; 89 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; mask >>= 1; SCK_LO; 90 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; mask >>= 1; SCK_LO; 91 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; mask >>= 1; SCK_LO; 92 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; mask >>= 1; SCK_LO; 93 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; mask >>= 1; SCK_LO; 94 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; mask >>= 1; SCK_LO; 95 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; mask >>= 1; SCK_LO; 96 | if (val & mask) MOSI_HI; else MOSI_LO; SCK_HI; mask >>= 1; SCK_LO; 97 | #elif 1 98 | for (uint8_t mask = 0x80; mask; ) { //send command 99 | if (val & mask) MOSI_HI; 100 | else MOSI_LO; 101 | SCK_HI; 102 | mask >>= 1; 103 | SCK_LO; 104 | } 105 | #else 106 | for (uint32_t i = 0; i < 8; i++) { //send command 107 | if (val & 0x80) MOSI_HI; 108 | else MOSI_LO; 109 | SCK_HI; 110 | val <<= 1; 111 | SCK_LO; 112 | } 113 | #endif 114 | } 115 | 116 | static uint32_t readbits(uint8_t bits) 117 | { 118 | uint32_t ret = 0; 119 | while (bits--) { 120 | ret <<= 1; 121 | if (PIN_READ(SPI_PORT, MOSI_PIN)) 122 | ret++; 123 | SCK_HI; 124 | SCK_LO; 125 | } 126 | return ret; 127 | } 128 | 129 | static inline void write16_N(uint16_t color, int16_t n) 130 | { 131 | uint8_t hi = color >> 8, lo = color; 132 | while (n-- > 0) { 133 | WriteDat8(hi); 134 | WriteDat8(lo); 135 | } 136 | } 137 | 138 | static inline void write24_N(uint16_t color, int16_t n) 139 | { 140 | uint8_t r = color >> 8, g = (color >> 3), b = color << 3; 141 | while (n-- > 0) { 142 | WriteDat8(r); 143 | WriteDat8(g); 144 | WriteDat8(b); 145 | } 146 | } 147 | 148 | static inline void write8_block(uint8_t * block, int16_t n) 149 | { 150 | while (n-- > 0) WriteDat8(*block++); 151 | } 152 | -------------------------------------------------------------------------------- /serial_kbv.h: -------------------------------------------------------------------------------- 1 | #if defined(__AVR_ATmega328P__) && defined(ILI9488_KBV_H_) 2 | #define USE_SERIAL_COMPLEX //optimised C code for Uno, Xmega, ... 3 | #endif 4 | #if defined(__STM32F1__) 5 | #define DMA__STM32F1__ //special feature of MAPLE CORE 6 | #endif 7 | //#define MY_BLUEPILL 8 | // MAPLE core has SPI.write(block, n) 9 | // ST core has only got SPI.transfer(block, n) 10 | // SAMD core might have SPI.transfer(block, n) 11 | // SAM core has got SPI.transfer(block, n) 12 | // so it is probably safest to have a moderate stack buffer and use transfer 13 | 14 | //ST core is ok for ILI9341 but not for ST7735X 15 | 16 | #define CD_COMMAND PIN_LOW(CD_PORT, CD_PIN) 17 | #define CD_DATA PIN_HIGH(CD_PORT, CD_PIN) 18 | #define CD_OUTPUT PIN_OUTPUT(CD_PORT, CD_PIN) 19 | #define CS_ACTIVE PIN_LOW(CS_PORT, CS_PIN); 20 | #define CS_IDLE PIN_HIGH(CS_PORT, CS_PIN); 21 | #define CS_OUTPUT PIN_OUTPUT(CS_PORT, CS_PIN) 22 | #define RESET_ACTIVE PIN_LOW(RESET_PORT, RESET_PIN) 23 | #define RESET_IDLE PIN_HIGH(RESET_PORT, RESET_PIN) 24 | #define RESET_OUTPUT PIN_OUTPUT(RESET_PORT, RESET_PIN) 25 | #define SD_ACTIVE PIN_LOW(SD_PORT, SD_PIN) 26 | #define SD_IDLE PIN_HIGH(SD_PORT, SD_PIN) 27 | #define SD_OUTPUT PIN_OUTPUT(SD_PORT, SD_PIN) 28 | // bit-bang macros for SDIO 29 | #define SCK_LO PIN_LOW(SPI_PORT, SCK_PIN) 30 | #define SCK_HI PIN_HIGH(SPI_PORT, SCK_PIN) 31 | #define SCK_OUT PIN_OUTPUT(SPI_PORT, SCK_PIN) 32 | #define MOSI_LO PIN_LOW(SPI_PORT, MOSI_PIN) 33 | #define MOSI_HI PIN_HIGH(SPI_PORT, MOSI_PIN) 34 | #define MOSI_OUT PIN_OUTPUT(SPI_PORT, MOSI_PIN) 35 | #define MOSI_IN PIN_INPUT(SPI_PORT, MOSI_PIN) 36 | #define LED_LO PIN_LOW(LED_PORT, LED_PIN) 37 | #define LED_HI PIN_HIGH(LED_PORT, LED_PIN) 38 | #define LED_OUT PIN_OUTPUT(LED_PORT, LED_PIN) 39 | 40 | #if defined(USE_SERIAL_COMPLEX) 41 | #include "serial_complex.h" 42 | #else 43 | 44 | #include //include before write16() macro 45 | #warning Using Arduino SPI methods 46 | 47 | #if defined(NINEBITS) 48 | #define xchg8(x) readbits(8) 49 | #define WriteCmd(x) { SDIO_OUTMODE(); MOSI_LO; SCK_HI; SCK_LO; write_8(x); } 50 | #define WriteDat8(x) { MOSI_HI; SCK_HI; SCK_LO; write_8(x); } 51 | #define INIT() { CS_IDLE; RESET_IDLE; SETDDR; } 52 | #define SDIO_INMODE() MOSI_IN;SCK_OUT //no braces 53 | #define SDIO_OUTMODE() {MOSI_OUT;SCK_OUT;} 54 | #else 55 | #define xchg8(x) xchg8_1(x) 56 | #define WriteCmd(x) { CD_COMMAND; xchg8_1(x); CD_DATA; } 57 | #define INIT() { CS_IDLE; RESET_IDLE; SETDDR; SPI.begin(); SPI.beginTransaction(settings); } 58 | #define SDIO_INMODE() SPI.endTransaction(); MOSI_IN;SCK_OUT //no braces 59 | #define SDIO_OUTMODE() {MOSI_OUT;SCK_OUT;SPI.beginTransaction(settings);} 60 | #endif 61 | 62 | #define wait_ms(ms) delay(ms) 63 | #define write16(x) { write16_N(x, 1); } 64 | #define write24(x) { write24_N(x, 1); } 65 | #define WriteData(x) { write16(x); } 66 | 67 | static uint8_t spibuf[16]; 68 | 69 | #if defined(ESP8266) 70 | #define CD_PIN D9 71 | #define CS_PIN D10 72 | #define RESET_PIN D8 73 | #define SD_PIN D4 74 | #define MOSI_PIN D11 75 | #define SCK_PIN D13 76 | #elif defined(MY_BLUEPILL) 77 | #define CD_PIN PA10 78 | #define CS_PIN PB12 79 | #define RESET_PIN PA9 80 | #define SD_PIN PA0 81 | #define MOSI_PIN PB15 82 | #define SCK_PIN PB13 83 | #else 84 | #define CD_PIN 9 85 | #define CS_PIN 10 86 | #define RESET_PIN 8 87 | #define SD_PIN 4 88 | #define MOSI_PIN 11 89 | #define SCK_PIN 13 90 | #endif 91 | 92 | #define SETDDR { CS_OUTPUT; CD_OUTPUT; RESET_OUTPUT; PIN_HIGH(SD_PORT, SD_PIN); PIN_OUTPUT(SD_PORT, SD_PIN); } 93 | 94 | #define PIN_LOW(p, b) digitalWrite(b, LOW) 95 | #define PIN_HIGH(p, b) digitalWrite(b, HIGH) 96 | #define PIN_OUTPUT(p, b) pinMode(b, OUTPUT) 97 | #define PIN_INPUT(p, b) pinMode(b, INPUT_PULLUP) 98 | #define PIN_READ(p, b) digitalRead(b) 99 | 100 | static SPISettings settings(8000000, MSBFIRST, SPI_MODE0); 101 | 102 | static inline void write_8(uint8_t val) 103 | { 104 | for (uint8_t i = 0; i < 8; i++) { //send command 105 | if (val & 0x80) MOSI_HI; 106 | else MOSI_LO; 107 | SCK_HI; 108 | SCK_LO; 109 | val <<= 1; 110 | } 111 | } 112 | 113 | static inline uint8_t xchg8_1(uint8_t x) 114 | { 115 | #if defined(DMA__STM32F1__) 116 | uint8_t ret; 117 | SPI.dmaTransfer(&x, &ret, 1); 118 | return ret; 119 | #else 120 | return SPI.transfer(x); 121 | #endif 122 | } 123 | 124 | static uint32_t readbits(uint8_t bits) 125 | { 126 | uint32_t ret = 0; 127 | while (bits--) { 128 | ret <<= 1; 129 | if (PIN_READ(SPI_PORT, MOSI_PIN)) 130 | ret++; 131 | SCK_HI; 132 | SCK_LO; 133 | } 134 | return ret; 135 | } 136 | 137 | static inline void write16_N(uint16_t color, int16_t n) 138 | { 139 | #if defined(NINEBITS) 140 | uint8_t hi = color >> 8, lo = color; 141 | while (n-- > 0) { 142 | WriteDat8(hi); 143 | WriteDat8(lo); 144 | } 145 | #elif defined(ESP8266) 146 | uint8_t hilo[2]; 147 | hilo[0] = color >> 8; 148 | hilo[1] = color; 149 | SPI.writePattern(hilo, 2, (uint32_t)n); 150 | #elif defined(DMA__STM32F1__) 151 | SPI.setDataSize (SPI_CR1_DFF); // Set SPI 16bit mode 152 | SPI.dmaSend(&color, n, 0); 153 | SPI.setDataSize (0); 154 | #elif defined(__STM32F1__) 155 | uint8_t buf[64]; 156 | int cnt = (n > 32) ? 32 : n; 157 | uint8_t *p = buf; 158 | while (cnt--) { *p++ = color >> 8; *p++ = color; } 159 | while (n > 0) { 160 | cnt = (n > 32) ? 32 : n; 161 | SPI.write(buf, cnt << 1); 162 | n -= cnt; 163 | } 164 | #elif 1 165 | uint8_t buf[64]; 166 | while (n > 0) { 167 | uint8_t *p = buf; 168 | int cnt = (n > 32) ? 32 : n; 169 | while (cnt--) { *p++ = color >> 8; *p++ = color; } 170 | cnt = (n > 32) ? 32 : n; 171 | SPI.transfer(buf, cnt << 1); 172 | n -= cnt; 173 | } 174 | #else 175 | uint8_t hi = color >> 8, lo = color; 176 | while (n-- > 0) { 177 | SPI.transfer(hi); 178 | SPI.transfer(lo); 179 | } 180 | #endif 181 | } 182 | 183 | static inline void write24_N(uint16_t color, int16_t n) 184 | { 185 | #if defined(NINEBITS) 186 | uint8_t r = color >> 8, g = (color >> 3), b = color << 3; 187 | while (n-- > 0) { 188 | WriteDat8(r); 189 | WriteDat8(g); 190 | WriteDat8(b); 191 | } 192 | #elif defined(ESP8266) 193 | uint8_t rgb[3]; 194 | rgb[0] = color >> 8; 195 | rgb[1] = color >> 3; 196 | rgb[2] = color << 3; 197 | SPI.writePattern(rgb, 3, (uint32_t)n); 198 | #else 199 | uint8_t r = color >> 8, g = (color >> 3), b = color << 3; 200 | while (n-- > 0) { 201 | SPI.transfer(r); 202 | SPI.transfer(g); 203 | SPI.transfer(b); 204 | } 205 | #endif 206 | } 207 | 208 | static inline void write8_block(uint8_t * block, int16_t n) 209 | { 210 | #if defined(NINEBITS) 211 | while (n-- > 0) WriteDat8(*block++); 212 | #elif defined(ESP8266) 213 | SPI.writeBytes(block, (uint32_t)n); 214 | #elif defined(DMA__STM32F1__) 215 | SPI.dmaSend(block, n, 1); 216 | #elif defined(__STM32F1__) 217 | SPI.write(block, (uint32_t)n); 218 | #else 219 | SPI.transfer(block, n); 220 | #endif 221 | } 222 | #endif 223 | -------------------------------------------------------------------------------- /tftspi_avr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tftspi_avr.h 3 | * 4 | * Created: 10/11/2014 20:48:01 5 | * Author: David Prentice 6 | */ 7 | 8 | 9 | #ifndef TFTSPI_AVR_H_ 10 | #define TFTSPI_AVR_H_ 11 | 12 | #include 13 | 14 | #if 0 15 | #elif defined(__AVR_ATxmega128A1__) //3.49s @ 32MHz -O2 16 | #define CD_PORT VPORT2 17 | #define CD_PIN 1 18 | #define CS_PORT VPORT3 19 | #define CS_PIN 4 20 | #define RESET_PORT VPORT2 21 | #define RESET_PIN 0 22 | #define SPCRVAL (USART_CLK2X_bm | USART_RXEN_bm | USART_TXEN_bm) 23 | #define SETDDR {VPORT3.DIR |= (1<<4)|(1<<5)|(1<<7); VPORT2.DIR |= 0x03; } 24 | #define INIT() { PORTCFG.VPCTRLB=PORTCFG_VP3MAP_PORTF_gc | PORTCFG_VP2MAP_PORTC_gc; CS_IDLE; RESET_IDLE; SETDDR; spi_init(); } 25 | 26 | void spi_init(void) 27 | { 28 | SPIF.CTRL=SPI_ENABLE_bm | SPI_MODE_3_gc | (1<> 8; 58 | } 59 | 60 | #define ST7735_NOP 0x00 61 | #define ST7735_SWRESET 0x01 62 | #define ST7735_RDDID 0x04 63 | #define ST7735_RDDST 0x09 64 | 65 | #define ST7735_SLPIN 0x10 66 | #define ST7735_SLPOUT 0x11 67 | #define ST7735_PTLON 0x12 68 | #define ST7735_NORON 0x13 69 | 70 | #define ST7735_INVOFF 0x20 71 | #define ST7735_INVON 0x21 72 | #define ST7735_DISPOFF 0x28 73 | #define ST7735_DISPON 0x29 74 | #define ST7735_CASET 0x2A 75 | #define ST7735_RASET 0x2B 76 | #define ST7735_RAMWR 0x2C 77 | #define ST7735_RAMRD 0x2E 78 | 79 | #define ST7735_PTLAR 0x30 80 | #define ST7735_COLMOD 0x3A 81 | #define ST7735_MADCTL 0x36 82 | 83 | #define ST7735_FRMCTR1 0xB1 84 | #define ST7735_FRMCTR2 0xB2 85 | #define ST7735_FRMCTR3 0xB3 86 | #define ST7735_INVCTR 0xB4 87 | #define ST7735_DISSET5 0xB6 88 | 89 | #define ST7735_PWCTR1 0xC0 90 | #define ST7735_PWCTR2 0xC1 91 | #define ST7735_PWCTR3 0xC2 92 | #define ST7735_PWCTR4 0xC3 93 | #define ST7735_PWCTR5 0xC4 94 | #define ST7735_VMCTR1 0xC5 95 | 96 | #define ST7735_RDID1 0xDA 97 | #define ST7735_RDID2 0xDB 98 | #define ST7735_RDID3 0xDC 99 | #define ST7735_RDID4 0xDD 100 | 101 | #define ST7735_PWCTR6 0xFC 102 | 103 | #define ST7735_GMCTRP1 0xE0 104 | #define ST7735_GMCTRN1 0xE1 105 | 106 | int16_t ST7735_kbv::readGRAM(int16_t x, int16_t y, uint16_t * block, int16_t w, int16_t h) 107 | { 108 | uint8_t r, g, b; 109 | int16_t n = w * h; // we are NEVER going to read > 32k pixels at once 110 | setAddrWindow(x, y, x + w - 1, y + h - 1); 111 | CS_ACTIVE; 112 | WriteCmd(ST7735_RAMRD); 113 | CD_DATA; 114 | SDIO_INMODE(); // do this while CS is Active 115 | 116 | r = readbits(9); // needs 1 dummy read (8) for ILI9163 117 | while (n-- > 0) { 118 | r = readbits(8); 119 | g = readbits(8); 120 | b = readbits(8); 121 | *block++ = color565(r, g, b); 122 | } 123 | CS_IDLE; 124 | SDIO_OUTMODE(); //do this when CS is Idle 125 | setAddrWindow(0, 0, width() - 1, height() - 1); 126 | return 0; 127 | } 128 | 129 | void ST7735_kbv::setRotation(uint8_t r) 130 | { 131 | uint16_t mac = 0x800; 132 | Adafruit_GFX::setRotation(r & 3); 133 | switch (rotation) { 134 | case 0: 135 | mac = 0xD800; 136 | break; 137 | case 1: //LANDSCAPE 90 degrees 138 | mac = 0xB800; 139 | break; 140 | case 2: 141 | mac = 0x0800; 142 | break; 143 | case 3: 144 | mac = 0x6800; 145 | break; 146 | } 147 | if (__OFFSET == 0) mac ^= 0x0800; 148 | WriteCmdData(ST7735_MADCTL, mac); 149 | } 150 | 151 | void ST7735_kbv::drawPixel(int16_t x, int16_t y, uint16_t color) 152 | { 153 | // ILI934X just plots at edge if you try to write outside of the box: 154 | if (x < 0 || y < 0 || x >= width() || y >= height()) 155 | return; 156 | if (rotation == 0) y += __OFFSET; 157 | if (rotation == 1) x += __OFFSET; 158 | CS_ACTIVE; 159 | WriteCmd(ST7735_CASET); 160 | spibuf[0] = x >> 8; 161 | spibuf[1] = x; 162 | CD_DATA; 163 | write8_block(spibuf, 2); 164 | WriteCmd(ST7735_RASET); 165 | spibuf[0] = y >> 8; 166 | spibuf[1] = y; 167 | CD_DATA; 168 | write8_block(spibuf, 2); 169 | WriteCmd(ST7735_RAMWR); 170 | spibuf[0] = color >> 8; 171 | spibuf[1] = color; 172 | CD_DATA; 173 | write8_block(spibuf, 2); 174 | CS_IDLE; 175 | } 176 | 177 | void ST7735_kbv::setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1) 178 | { 179 | if (rotation == 0) y += __OFFSET, y1 += __OFFSET; 180 | if (rotation == 1) x += __OFFSET, x1 += __OFFSET; 181 | CS_ACTIVE; 182 | WriteCmd(ST7735_CASET); 183 | spibuf[0] = x >> 8; 184 | spibuf[1] = x; 185 | spibuf[2] = x1 >> 8; 186 | spibuf[3] = x1; 187 | CD_DATA; 188 | write8_block(spibuf, 4); 189 | WriteCmd(ST7735_RASET); 190 | spibuf[0] = y >> 8; 191 | spibuf[1] = y; 192 | spibuf[2] = y1 >> 8; 193 | spibuf[3] = y1; 194 | CD_DATA; 195 | write8_block(spibuf, 4); 196 | CS_IDLE; 197 | } 198 | 199 | void ST7735_kbv::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 200 | { 201 | int16_t end; 202 | if (w < 0) { 203 | w = -w; 204 | x -= w; 205 | } //+ve w 206 | end = x + w; 207 | if (x < 0) 208 | x = 0; 209 | if (end > width()) 210 | end = width(); 211 | w = end - x; 212 | if (h < 0) { 213 | h = -h; 214 | y -= h; 215 | } //+ve h 216 | end = y + h; 217 | if (y < 0) 218 | y = 0; 219 | if (end > height()) 220 | end = height(); 221 | h = end - y; 222 | setAddrWindow(x, y, x + w - 1, y + h - 1); 223 | CS_ACTIVE; 224 | WriteCmd(ST7735_RAMWR); 225 | CD_DATA; 226 | if (h > w) { 227 | end = h; 228 | h = w; 229 | w = end; 230 | } 231 | while (h-- > 0) { 232 | write16_N(color, w); 233 | } 234 | CS_IDLE; 235 | setAddrWindow(0, 0, width() - 1, height() - 1); 236 | } 237 | 238 | void ST7735_kbv::pushColors(uint16_t * block, int16_t n, bool first) 239 | { 240 | uint16_t color; 241 | CS_ACTIVE; 242 | if (first) { 243 | WriteCmd(ST7735_RAMWR); 244 | } 245 | CD_DATA; 246 | while (n-- > 0) { 247 | color = *block++; 248 | write16(color); 249 | } 250 | CS_IDLE; 251 | } 252 | 253 | void ST7735_kbv::pushColors(const uint8_t * block, int16_t n, bool first) 254 | { 255 | uint16_t color; 256 | uint8_t h, l; 257 | CS_ACTIVE; 258 | if (first) { 259 | WriteCmd(ST7735_RAMWR); 260 | } 261 | CD_DATA; 262 | while (n-- > 0) { 263 | l = pgm_read_byte(block++); 264 | h = pgm_read_byte(block++); 265 | color = h<<8 | l; 266 | write16(color); 267 | } 268 | CS_IDLE; 269 | } 270 | 271 | void ST7735_kbv::invertDisplay(boolean i) 272 | { 273 | WriteCmdData(i ? ST7735_INVON : ST7735_INVOFF, 0); 274 | } 275 | 276 | void ST7735_kbv::vertScroll(int16_t top, int16_t scrollines, int16_t offset) 277 | { 278 | if (rotation == 0 || rotation == 1) top += __OFFSET; 279 | int16_t bfa = HEIGHT + __OFFSET - top - scrollines; // bottom fixed area 280 | int16_t vsp; 281 | vsp = top + offset; // vertical start position 282 | if (offset < 0) 283 | vsp += scrollines; //keep in unsigned range 284 | CS_ACTIVE; 285 | WriteCmd(0x0033); 286 | WriteData(top); //TOP 287 | write16(scrollines); 288 | write16(bfa); 289 | 290 | WriteCmdData(0x0037, vsp); //VL# 291 | 292 | } 293 | 294 | #define TFTLCD_DELAY 0xFF 295 | 296 | const uint8_t PROGMEM table7735R[] = { 297 | // (COMMAND_BYTE), n, data_bytes.... 298 | (ST7735_SWRESET), 0, // software reset 299 | TFTLCD_DELAY, 50, 300 | (ST7735_SLPOUT), 0, //Sleep exit 301 | TFTLCD_DELAY, 250, 302 | //ST7735R Frame Rate 303 | (ST7735_FRMCTR1), 3, 0x01, 0x2C, 0x2D, 304 | (ST7735_FRMCTR2), 3, 0x01, 0x2C, 0x2D, 305 | (ST7735_FRMCTR3), 6, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, 306 | (ST7735_INVCTR), 1, 0x07, //Column inversion 307 | //ST7735R Power Sequence 308 | (ST7735_PWCTR1), 3, 0xA2, 0x02, 0x84, 309 | (ST7735_PWCTR2), 1, 0xC5, 310 | (ST7735_PWCTR3), 2, 0x0A, 0x00, 311 | (ST7735_PWCTR4), 2, 0x8A, 0x2A, 312 | (ST7735_PWCTR5), 2, 0x8A, 0xEE, 313 | (ST7735_VMCTR1), 1, 0x0E, //VCOM 314 | (ST7735_INVOFF), 0, //no inversion 315 | //(ST7735_MADCTL), 1, 0xC8, //MX, MY, RGB mode 316 | (ST7735_MADCTL), 1, 0x00, //MX, MY, RGB mode 317 | //ST7735R Gamma Sequence 318 | (ST7735_GMCTRP1), 16, 319 | 0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f, 0x1b, 0x23, 0x37, 320 | 0x00, 0x07, 0x02, 0x10, 321 | (ST7735_GMCTRN1), 16, 322 | 0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, 0x30, 0x30, 0x39, 0x3f, 323 | 0x00, 0x07, 0x03, 0x10, 324 | (ST7735_CASET), 4, 0x00, 0x00, 0x00, 0x7f, 325 | (ST7735_RASET), 4, 0x00, 0x00, 0x00, 0x9f, 326 | (0xF0), 1, 0x01, //Enable test command 327 | (0xF6), 1, 0x00, //Disable ram power save mode 328 | (ST7735_COLMOD), 1, 0x05, //65k mode 329 | (ST7735_DISPON), 0, //Display on 330 | }; 331 | 332 | void ST7735_kbv::begin(uint16_t ID) 333 | { 334 | _lcd_ID = ID; 335 | uint8_t *p = (uint8_t *) table7735R; 336 | int16_t size = sizeof(table7735R); 337 | reset(); 338 | while (size > 0) { 339 | uint8_t cmd = pgm_read_byte(p++); 340 | uint8_t len = pgm_read_byte(p++); 341 | if (cmd == TFTLCD_DELAY) { 342 | delay(len); 343 | len = 0; 344 | } else { 345 | CS_ACTIVE; 346 | WriteCmd(cmd); 347 | CD_DATA; 348 | for (uint8_t d = 0; d < len; d++) { 349 | uint8_t x = pgm_read_byte(p++); 350 | xchg8(x); 351 | } 352 | CS_IDLE; 353 | } 354 | size -= len + 2; 355 | } 356 | setRotation(0); //PORTRAIT 357 | } 358 | -------------------------------------------------------------------------------- /ILI9163_kbv.cpp: -------------------------------------------------------------------------------- 1 | //#define __OFFSET 0 //for Black 128x128 module 2 | #define __OFFSET 32 //for Red 128x128 module 3 | 4 | #include "ILI9163_kbv.h" 5 | #include "serial_kbv.h" 6 | 7 | ILI9163_kbv::ILI9163_kbv():Adafruit_GFX(128, 128) 8 | { 9 | INIT(); 10 | CS_IDLE; 11 | RESET_IDLE; 12 | } 13 | 14 | void ILI9163_kbv::reset(void) 15 | { 16 | wait_ms(50); 17 | RESET_ACTIVE; 18 | wait_ms(100); 19 | RESET_IDLE; 20 | wait_ms(100); 21 | } 22 | 23 | void ILI9163_kbv::WriteCmdData(uint16_t cmd, uint16_t dat) 24 | { 25 | CS_ACTIVE; 26 | WriteCmd(cmd); 27 | WriteData(dat); 28 | CS_IDLE; 29 | } 30 | 31 | static uint32_t readRegister(uint8_t reg) 32 | { 33 | uint32_t ret; 34 | uint8_t bits = 8; 35 | if (reg == 4) bits = 25; 36 | if (reg == 9) bits = 33; 37 | CS_ACTIVE; 38 | WriteCmd(reg); 39 | CD_DATA; //should do a flush() 40 | SDIO_INMODE(); // do this while CS is Active 41 | ret = readbits(bits); 42 | CS_IDLE; 43 | SDIO_OUTMODE(); //do this when CS is Idle 44 | return ret; 45 | } 46 | 47 | uint16_t ILI9163_kbv::readReg(uint16_t reg) 48 | { 49 | return readRegister(reg); 50 | } 51 | 52 | uint32_t ILI9163_kbv::readReg32(uint16_t reg) 53 | { 54 | return readRegister(reg); 55 | } 56 | 57 | uint16_t ILI9163_kbv::readID(void) 58 | { 59 | return readRegister(4) >> 8; 60 | } 61 | 62 | #define ILI9163_NOP 0x00 63 | #define ILI9163_SWRESET 0x01 64 | #define ILI9163_RDDID 0x04 65 | #define ILI9163_RDDST 0x09 66 | 67 | #define ILI9163_SLPIN 0x10 68 | #define ILI9163_SLPOUT 0x11 69 | #define ILI9163_PTLON 0x12 70 | #define ILI9163_NORON 0x13 71 | 72 | #define ILI9163_INVOFF 0x20 73 | #define CMD_GAMMASET 0x26//Gamma Set (0x01[1],0x02[2],0x04[3],0x08[4]) 74 | #define ILI9163_INVON 0x21 75 | #define ILI9163_DISPOFF 0x28 76 | #define ILI9163_DISPON 0x29 77 | #define ILI9163_CASET 0x2A 78 | #define ILI9163_RASET 0x2B 79 | #define ILI9163_RAMWR 0x2C 80 | #define ILI9163_RAMRD 0x2E 81 | 82 | #define ILI9163_PTLAR 0x30 83 | #define CMD_VSCLLDEF 0x33//Vertical Scroll Definition 84 | #define ILI9163_COLMOD 0x3A 85 | #define ILI9163_MADCTL 0x36 86 | #define CMD_VSSTADRS 0x37//Vertical Scrolling Start address 87 | 88 | #define ILI9163_FRMCTR1 0xB1 89 | #define ILI9163_FRMCTR2 0xB2 90 | #define ILI9163_FRMCTR3 0xB3 91 | #define ILI9163_INVCTR 0xB4 92 | #define CMD_DFUNCTR 0xB6//Display Fuction set 5 93 | #define CMD_SDRVDIR 0xB7//Source Driver Direction Control 94 | #define CMD_GDRVDIR 0xB8//Gate Driver Direction Control 95 | 96 | #define ILI9163_PWCTR1 0xC0 97 | #define ILI9163_PWCTR2 0xC1 98 | #define ILI9163_PWCTR3 0xC2 99 | #define ILI9163_PWCTR4 0xC3 100 | #define ILI9163_PWCTR5 0xC4 101 | #define ILI9163_VMCTR1 0xC5 102 | #define CMD_VCOMCTR2 0xC6//VCOM_Control 2 103 | #define CMD_VCOMOFFS 0xC7//VCOM Offset Control 104 | 105 | #define ILI9163_RDID1 0xDA 106 | #define ILI9163_RDID2 0xDB 107 | #define ILI9163_RDID3 0xDC 108 | #define ILI9163_RDID4 0xDD 109 | 110 | //#define ILI9163_PWCTR6 0xFC 111 | 112 | #define ILI9163_GMCTRP1 0xE0 113 | #define ILI9163_GMCTRN1 0xE1 114 | #define CMD_GAMRSEL 0xF2//GAM_R_SEL 115 | 116 | int16_t ILI9163_kbv::readGRAM(int16_t x, int16_t y, uint16_t * block, int16_t w, int16_t h) 117 | { 118 | 119 | uint8_t r, g, b; 120 | int16_t n = w * h; // we are NEVER going to read > 32k pixels at once 121 | setAddrWindow(x, y, x + w - 1, y + h - 1); 122 | CS_ACTIVE; 123 | WriteCmd(ILI9163_RAMRD); 124 | CD_DATA; 125 | SDIO_INMODE(); // do this while CS is Active 126 | 127 | // needs 1 dummy read 128 | r = readbits(8); //ST7735 needs 9 129 | while (n-- > 0) { 130 | 131 | r = readbits(8); 132 | g = readbits(8); 133 | b = readbits(8); 134 | *block++ = color565(r, g, b); 135 | } 136 | CS_IDLE; 137 | SDIO_OUTMODE(); //do this when CS is Idle 138 | 139 | return 0; 140 | } 141 | 142 | void ILI9163_kbv::setRotation(uint8_t r) 143 | { 144 | uint16_t mac = 0x800; 145 | Adafruit_GFX::setRotation(r & 3); 146 | switch (rotation) { 147 | case 0: 148 | mac = 0x0800; 149 | break; 150 | case 1: //LANDSCAPE 90 degrees BLACK pcb 151 | mac = 0x6800; 152 | break; 153 | case 2: 154 | mac = 0xD800; 155 | break; 156 | case 3: 157 | mac = 0xB800; 158 | break; 159 | } 160 | WriteCmdData(ILI9163_MADCTL, mac); 161 | setAddrWindow(0, 0, width() - 1, height() - 1); 162 | vertScroll(0, height(), 0); 163 | } 164 | 165 | void ILI9163_kbv::drawPixel(int16_t x, int16_t y, uint16_t color) 166 | { 167 | // ILI934X just plots at edge if you try to write outside of the box: 168 | if (x < 0 || y < 0 || x >= width() || y >= height()) 169 | return; 170 | if (rotation == 0) y += __OFFSET; 171 | if (rotation == 1) x += __OFFSET; 172 | CS_ACTIVE; 173 | WriteCmd(ILI9163_CASET); 174 | spibuf[0] = x >> 8; 175 | spibuf[1] = x; 176 | CD_DATA; 177 | write8_block(spibuf, 2); 178 | WriteCmd(ILI9163_RASET); 179 | spibuf[0] = y >> 8; 180 | spibuf[1] = y; 181 | CD_DATA; 182 | write8_block(spibuf, 2); 183 | WriteCmd(ILI9163_RAMWR); 184 | spibuf[0] = color >> 8; 185 | spibuf[1] = color; 186 | CD_DATA; 187 | write8_block(spibuf, 2); 188 | CS_IDLE; 189 | } 190 | 191 | void ILI9163_kbv::setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1) 192 | { 193 | if (rotation == 0) y += __OFFSET, y1 += __OFFSET; 194 | if (rotation == 1) x += __OFFSET, x1 += __OFFSET; 195 | CS_ACTIVE; 196 | WriteCmd(ILI9163_CASET); 197 | spibuf[0] = x >> 8; 198 | spibuf[1] = x; 199 | spibuf[2] = x1 >> 8; 200 | spibuf[3] = x1; 201 | CD_DATA; 202 | write8_block(spibuf, 4); 203 | WriteCmd(ILI9163_RASET); 204 | spibuf[0] = y >> 8; 205 | spibuf[1] = y; 206 | spibuf[2] = y1 >> 8; 207 | spibuf[3] = y1; 208 | CD_DATA; 209 | write8_block(spibuf, 4); 210 | CS_IDLE; 211 | } 212 | 213 | void ILI9163_kbv::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 214 | { 215 | int16_t end; 216 | if (w < 0) { 217 | w = -w; 218 | x -= w; 219 | } //+ve w 220 | end = x + w; 221 | if (x < 0) 222 | x = 0; 223 | if (end > width()) 224 | end = width(); 225 | w = end - x; 226 | if (h < 0) { 227 | h = -h; 228 | y -= h; 229 | } //+ve h 230 | end = y + h; 231 | if (y < 0) 232 | y = 0; 233 | if (end > height()) 234 | end = height(); 235 | h = end - y; 236 | setAddrWindow(x, y, x + w - 1, y + h - 1); 237 | CS_ACTIVE; 238 | WriteCmd(ILI9163_RAMWR); 239 | CD_DATA; 240 | if (h > w) { 241 | end = h; 242 | h = w; 243 | w = end; 244 | } 245 | while (h-- > 0) { 246 | write16_N(color, w); 247 | } 248 | CS_IDLE; 249 | setAddrWindow(0, 0, width() - 1, height() - 1); 250 | } 251 | 252 | void ILI9163_kbv::pushColors(uint16_t * block, int16_t n, bool first) 253 | { 254 | uint16_t color; 255 | CS_ACTIVE; 256 | if (first) { 257 | WriteCmd(ILI9163_RAMWR); 258 | } 259 | CD_DATA; 260 | while (n-- > 0) { 261 | color = *block++; 262 | write16(color); 263 | } 264 | CS_IDLE; 265 | } 266 | 267 | void ILI9163_kbv::pushColors(const uint8_t * block, int16_t n, bool first) 268 | { 269 | uint16_t color; 270 | uint8_t h, l; 271 | CS_ACTIVE; 272 | if (first) { 273 | WriteCmd(ILI9163_RAMWR); 274 | } 275 | CD_DATA; 276 | while (n-- > 0) { 277 | l = pgm_read_byte(block++); 278 | h = pgm_read_byte(block++); 279 | color = h<<8 | l; 280 | write16(color); 281 | } 282 | CS_IDLE; 283 | } 284 | 285 | void ILI9163_kbv::invertDisplay(boolean i) 286 | { 287 | WriteCmdData(i ? ILI9163_INVON : ILI9163_INVOFF, 0); 288 | } 289 | 290 | void ILI9163_kbv::vertScroll(int16_t top, int16_t scrollines, int16_t offset) 291 | { 292 | if (rotation == 0 || rotation == 1) top += __OFFSET; 293 | int16_t bfa = HEIGHT + __OFFSET - top - scrollines; // bottom fixed area 294 | int16_t vsp; 295 | vsp = top + offset; // vertical start position 296 | if (offset < 0) 297 | vsp += scrollines; //keep in unsigned range 298 | CS_ACTIVE; 299 | WriteCmd(0x0033); 300 | WriteData(top); //TOP 301 | write16(scrollines); 302 | write16(bfa); 303 | 304 | WriteCmdData(0x0037, vsp); //VL# 305 | 306 | } 307 | 308 | #define TFTLCD_DELAY 0xFF 309 | 310 | const uint8_t PROGMEM table9163C[] = { 311 | // (COMMAND_BYTE), n, data_bytes.... 312 | (ILI9163_SWRESET), 0, // software reset 313 | TFTLCD_DELAY, 250, 314 | TFTLCD_DELAY, 250, 315 | (ILI9163_SLPOUT), 0, //Sleep exit 316 | TFTLCD_DELAY, 5, 317 | (ILI9163_COLMOD), 1, 0x05, //65k mode 318 | TFTLCD_DELAY, 5, 319 | (CMD_GAMMASET), 1, 0x04, 320 | TFTLCD_DELAY, 1, 321 | (CMD_GAMRSEL), 1, 0x01, 322 | TFTLCD_DELAY, 1, 323 | (ILI9163_NORON), 0, //Normal 324 | // (CMD_DFUNCTR), 2, 0xFF, 0x06, //Display Function set 5 ??NL 325 | #if __OFFSET == 0 326 | (CMD_SDRVDIR), 1, 0x01, 327 | (CMD_GDRVDIR), 1, 0x01, 328 | #else 329 | (CMD_SDRVDIR), 1, 0x00, 330 | (CMD_GDRVDIR), 1, 0x00, 331 | #endif 332 | (ILI9163_GMCTRP1), 16, 333 | 0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f, 0x1b, 0x23, 0x37, 334 | 0x00, 0x07, 0x02, 0x10, 335 | (ILI9163_GMCTRN1), 16, 336 | 0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, 0x30, 0x30, 0x39, 0x3f, 337 | 0x00, 0x07, 0x03, 0x10, 338 | (ILI9163_FRMCTR1), 2, 0x08, 0x02, 339 | (ILI9163_INVCTR), 1, 0x07, //Column inversion 340 | TFTLCD_DELAY, 1, 341 | (ILI9163_PWCTR1), 2, 0x0A, 0x02, 342 | TFTLCD_DELAY, 1, 343 | (ILI9163_PWCTR2), 1, 0x02, 344 | TFTLCD_DELAY, 1, 345 | (ILI9163_VMCTR1), 2, 0x50, 0x63, //VCOM (#99) 346 | TFTLCD_DELAY, 1, 347 | (CMD_VCOMOFFS), 1, 0, 348 | TFTLCD_DELAY, 1, 349 | (CMD_VSCLLDEF), 6, 0, __OFFSET, 0, 128 + __OFFSET, 0, 0, 350 | (ILI9163_MADCTL), 1, 0x00, //MX, MY, RGB mode 351 | (ILI9163_PTLAR), 4, 0x00, 0x00, 0x00, 0x7f, 352 | (ILI9163_CASET), 4, 0x00, 0x00, 0x00, 0x7f, 353 | (ILI9163_RASET), 4, 0x00, 0x00, 0x00, 0x7f, 354 | // (0xF0), 1, 0x01, //Enable test command 355 | // (0xF6), 1, 0x00, //Disable ram power save mode 356 | (ILI9163_DISPON), 0, //Display on 357 | }; 358 | 359 | void ILI9163_kbv::begin(uint16_t ID) 360 | { 361 | _lcd_ID = ID; 362 | uint8_t *p = (uint8_t *) table9163C; 363 | int16_t size = sizeof(table9163C); 364 | reset(); 365 | while (size > 0) { 366 | uint8_t cmd = pgm_read_byte(p++); 367 | uint8_t len = pgm_read_byte(p++); 368 | if (cmd == TFTLCD_DELAY) { 369 | delay(len); 370 | len = 0; 371 | } else { 372 | CS_ACTIVE; 373 | WriteCmd(cmd); 374 | CD_DATA; 375 | for (uint8_t d = 0; d < len; d++) { 376 | uint8_t x = pgm_read_byte(p++); 377 | xchg8(x); 378 | } 379 | CS_IDLE; 380 | } 381 | size -= len + 2; 382 | } 383 | setRotation(0); //PORTRAIT 384 | } 385 | -------------------------------------------------------------------------------- /ILI9481_kbv.cpp: -------------------------------------------------------------------------------- 1 | #include "ILI9481_kbv.h" 2 | #define NINEBITS 3 | //#include "serial9_kbv.h" 4 | #include "serial_kbv.h" 5 | //#include "serial_stm32_kbv.h" 6 | 7 | ILI9481_kbv::ILI9481_kbv():Adafruit_GFX(320, 480) 8 | { 9 | } 10 | 11 | static uint8_t done_reset; 12 | 13 | void ILI9481_kbv::reset(void) 14 | { 15 | done_reset = 1; 16 | INIT(); 17 | CS_IDLE; 18 | RESET_IDLE; 19 | wait_ms(50); 20 | RESET_ACTIVE; 21 | wait_ms(100); 22 | RESET_IDLE; 23 | wait_ms(100); 24 | } 25 | 26 | void ILI9481_kbv::pushCommand(uint16_t cmd, uint8_t * block, int8_t N) 27 | { 28 | CS_ACTIVE; 29 | WriteCmd(cmd); 30 | write8_block(block, N); 31 | CS_IDLE; 32 | } 33 | 34 | #define ILI9481_CMD_NOP 0x00 35 | #define ILI9481_CMD_SOFTWARE_RESET 0x01 36 | #define ILI9481_CMD_READ_RED 0x06 37 | #define ILI9481_CMD_READ_GREEN 0x07 38 | #define ILI9481_CMD_READ_BLUE 0x08 39 | #define ILI9481_CMD_READ_DISP_POWER 0x0A 40 | #define ILI9481_CMD_READ_DISP_MADCTRL 0x0B 41 | #define ILI9481_CMD_READ_DISP_PIXEL_FORMAT 0x0C 42 | #define ILI9481_CMD_READ_DISP_IMAGE_FORMAT 0x0D 43 | #define ILI9481_CMD_READ_DISP_SIGNAL_MODE 0x0E 44 | #define ILI9481_CMD_READ_DISP_SELF_DIAGNOSTIC 0x0F 45 | #define ILI9481_CMD_ENTER_SLEEP_MODE 0x10 46 | #define ILI9481_CMD_SLEEP_OUT 0x11 47 | #define ILI9481_CMD_PARTIAL_MODE_ON 0x12 48 | #define ILI9481_CMD_NORMAL_DISP_MODE_ON 0x13 49 | #define ILI9481_CMD_DISP_INVERSION_OFF 0x20 50 | #define ILI9481_CMD_DISP_INVERSION_ON 0x21 51 | #define ILI9481_CMD_GAMMA_SET 0x26 52 | #define ILI9481_CMD_DISPLAY_OFF 0x28 53 | #define ILI9481_CMD_DISPLAY_ON 0x29 54 | #define ILI9481_CMD_COLUMN_ADDRESS_SET 0x2A 55 | #define ILI9481_CMD_PAGE_ADDRESS_SET 0x2B 56 | #define ILI9481_CMD_MEMORY_WRITE 0x2C 57 | #define ILI9481_CMD_COLOR_SET 0x2D 58 | #define ILI9481_CMD_MEMORY_READ 0x2E 59 | #define ILI9481_CMD_PARTIAL_AREA 0x30 60 | #define ILI9481_CMD_VERT_SCROLL_DEFINITION 0x33 61 | #define ILI9481_CMD_TEARING_EFFECT_LINE_OFF 0x34 62 | #define ILI9481_CMD_TEARING_EFFECT_LINE_ON 0x35 63 | #define ILI9481_CMD_MEMORY_ACCESS_CONTROL 0x36 64 | #define ILI9481_CMD_VERT_SCROLL_START_ADDRESS 0x37 65 | #define ILI9481_CMD_IDLE_MODE_OFF 0x38 66 | #define ILI9481_CMD_IDLE_MODE_ON 0x39 67 | #define ILI9481_CMD_COLMOD_PIXEL_FORMAT_SET 0x3A 68 | #define ILI9481_CMD_WRITE_MEMORY_CONTINUE 0x3C 69 | #define ILI9481_CMD_READ_MEMORY_CONTINUE 0x3E 70 | #define ILI9481_CMD_SET_TEAR_SCANLINE 0x44 71 | #define ILI9481_CMD_GET_SCANLINE 0x45 72 | #define ILI9481_CMD_COMMAND_ACCESS 0xB0 73 | #define ILI9481_CMD_READ_ID 0xBF 74 | 75 | uint16_t ILI9481_kbv::readReg(uint16_t reg) 76 | { 77 | uint8_t h, l; 78 | if (!done_reset) reset(); 79 | CS_ACTIVE; 80 | WriteCmd(reg); 81 | CD_DATA; //should do a flush() 82 | 83 | // needs 1 dummy read 84 | // h = xchg8(0); 85 | h = xchg8(0xFF); 86 | l = xchg8(0xFF); 87 | CS_IDLE; 88 | return (h << 8) | l; 89 | } 90 | 91 | uint32_t ILI9481_kbv::readReg32(uint16_t reg) 92 | { 93 | uint32_t ret = 0; 94 | CS_ACTIVE; 95 | WriteCmd(reg); 96 | CD_DATA; //should do a flush() 97 | 98 | readbits(1); 99 | for (uint8_t cnt = 5; cnt--; ) { 100 | ret <<= 8; 101 | ret |= xchg8(0); 102 | } 103 | CS_IDLE; 104 | return ret; 105 | } 106 | 107 | int16_t ILI9481_kbv::readGRAM(int16_t x, int16_t y, uint16_t * block, int16_t w, int16_t h) 108 | { 109 | uint8_t r, g, b; 110 | int16_t n = w * h; // we are NEVER going to read > 32k pixels at once 111 | setAddrWindow(x, y, x + w - 1, y + h - 1); 112 | CS_ACTIVE; 113 | WriteCmd(ILI9481_CMD_MEMORY_READ); 114 | CD_DATA; 115 | 116 | // needs 1 dummy read 117 | // r = xchg8(0xFF); 118 | r = readbits(9); 119 | while (n-- > 0) { 120 | b = xchg8(0xFF); 121 | g = xchg8(0xFF); 122 | r = xchg8(0xFF); 123 | *block++ = color565(r, g, b); 124 | } 125 | CS_IDLE; 126 | setAddrWindow(0, 0, width() - 1, height() - 1); 127 | return 0; 128 | } 129 | 130 | void ILI9481_kbv::setRotation(uint8_t r) 131 | { 132 | uint8_t mac = 0x00; 133 | Adafruit_GFX::setRotation(r & 3); 134 | switch (rotation) { 135 | case 0: 136 | mac = 0x08; 137 | break; 138 | case 1: //LANDSCAPE 90 degrees 139 | mac = 0x29; 140 | break; 141 | case 2: 142 | mac = 0x0B; 143 | break; 144 | case 3: 145 | mac = 0x2A; 146 | break; 147 | } 148 | mac ^= (_lcd_xor); 149 | pushCommand(ILI9481_CMD_MEMORY_ACCESS_CONTROL, &mac, 1); 150 | } 151 | 152 | void ILI9481_kbv::drawPixel(int16_t x, int16_t y, uint16_t color) 153 | { 154 | // ILI934X just plots at edge if you try to write outside of the box: 155 | if (x < 0 || y < 0 || x >= width() || y >= height()) 156 | return; 157 | setAddrWindow(x, y, x, y); 158 | #if 1 159 | CS_ACTIVE; 160 | WriteCmd(ILI9481_CMD_MEMORY_WRITE); 161 | CD_DATA; 162 | write24_N(color, 1); 163 | CS_IDLE; 164 | #else 165 | spibuf[0] = (color >> 8); 166 | spibuf[1] = (color >> 3); 167 | spibuf[2] = (color << 3); 168 | pushCommand(ILI9481_CMD_MEMORY_WRITE, spibuf, 3); 169 | #endif 170 | } 171 | 172 | void ILI9481_kbv::setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1) 173 | { 174 | spibuf[0] = x >> 8; 175 | spibuf[1] = x; 176 | spibuf[2] = x1 >> 8; 177 | spibuf[3] = x1; 178 | pushCommand(ILI9481_CMD_COLUMN_ADDRESS_SET, spibuf, 4); 179 | spibuf[0] = y >> 8; 180 | spibuf[1] = y; 181 | spibuf[2] = y1 >> 8; 182 | spibuf[3] = y1; 183 | pushCommand(ILI9481_CMD_PAGE_ADDRESS_SET, spibuf, 4); 184 | } 185 | 186 | void ILI9481_kbv::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 187 | { 188 | int16_t end; 189 | if (w < 0) { 190 | w = -w; 191 | x -= w; 192 | } //+ve w 193 | end = x + w; 194 | if (x < 0) 195 | x = 0; 196 | if (end > width()) 197 | end = width(); 198 | w = end - x; 199 | if (h < 0) { 200 | h = -h; 201 | y -= h; 202 | } //+ve h 203 | end = y + h; 204 | if (y < 0) 205 | y = 0; 206 | if (end > height()) 207 | end = height(); 208 | h = end - y; 209 | setAddrWindow(x, y, x + w - 1, y + h - 1); 210 | CS_ACTIVE; 211 | WriteCmd(ILI9481_CMD_MEMORY_WRITE); 212 | CD_DATA; 213 | if (h > w) { end = h; h = w; w = end; } 214 | while (h-- > 0) { 215 | write24_N(color, w); 216 | } 217 | CS_IDLE; 218 | setAddrWindow(0, 0, width() - 1, height() - 1); 219 | } 220 | 221 | void ILI9481_kbv::pushColors(uint16_t * block, int16_t n, bool first) 222 | { 223 | uint16_t color; 224 | CS_ACTIVE; 225 | if (first) { 226 | WriteCmd(ILI9481_CMD_MEMORY_WRITE); 227 | } 228 | CD_DATA; 229 | while (n-- > 0) { 230 | color = *block++; 231 | write24(color); 232 | } 233 | CS_IDLE; 234 | } 235 | 236 | void ILI9481_kbv::pushColors(uint8_t * block, int16_t n, bool first) 237 | { 238 | uint16_t color; 239 | uint8_t h, l; 240 | CS_ACTIVE; 241 | if (first) { 242 | WriteCmd(ILI9481_CMD_MEMORY_WRITE); 243 | } 244 | CD_DATA; 245 | while (n-- > 0) { 246 | h = (*block++); 247 | l = (*block++); 248 | color = (h << 8) | l; 249 | write24(color); 250 | } 251 | CS_IDLE; 252 | } 253 | 254 | void ILI9481_kbv::pushColors(const uint8_t * block, int16_t n, bool first, bool bigend) 255 | { 256 | uint16_t color; 257 | uint8_t h, l; 258 | CS_ACTIVE; 259 | if (first) { 260 | WriteCmd(ILI9481_CMD_MEMORY_WRITE); 261 | } 262 | CD_DATA; 263 | while (n-- > 0) { 264 | l = pgm_read_byte(block++); 265 | h = pgm_read_byte(block++); 266 | color = (bigend) ? (l << 8 ) | h : (h << 8) | l; 267 | write24(color); 268 | } 269 | CS_IDLE; 270 | } 271 | 272 | void ILI9481_kbv::invertDisplay(boolean i) 273 | { 274 | pushCommand(i ? ILI9481_CMD_DISP_INVERSION_ON : ILI9481_CMD_DISP_INVERSION_OFF, NULL, 0); 275 | } 276 | 277 | void ILI9481_kbv::vertScroll(int16_t top, int16_t scrollines, int16_t offset) 278 | { 279 | int16_t bfa = HEIGHT - top - scrollines; // bottom fixed area 280 | int16_t vsp; 281 | vsp = top + offset; // vertical start position 282 | if (offset < 0) 283 | vsp += scrollines; //keep in unsigned range 284 | spibuf[0] = top>>8; 285 | spibuf[1] = top; 286 | spibuf[2] = scrollines>>8; 287 | spibuf[3] = scrollines; 288 | spibuf[4] = bfa>>8; 289 | spibuf[5] = bfa; 290 | pushCommand(0x33, spibuf, 6); 291 | spibuf[0] = vsp>>8; 292 | spibuf[1] = vsp; 293 | pushCommand(0x37, spibuf, 2); 294 | } 295 | 296 | #define TFTLCD_DELAY8 0xFF 297 | static const uint8_t ILI9481_RGB_regValues[] PROGMEM = { // 320x480 298 | 0x01, 0, //Soft Reset 299 | TFTLCD_DELAY8, 125, 300 | 0x11, 0, //Sleep Out 301 | TFTLCD_DELAY8, 20, 302 | 0xB0, 1, 0x00, 303 | 0xD0, 3, 0x07, 0x41, 0x1D, // SETPOWER [00 43 18] 304 | 0xD1, 3, 0x00, 0x2B, 0x1F, // SETVCOM [00 00 00] x0.900, x1.32 305 | 0xD2, 2, 0x01, 0x11, // SETNORPOW for Normal Mode [01 22] 306 | 0xC0, 6, 0x00, 0x3B, 0x00, 0x02, 0x11, 0x00, //SETPANEL [10 3B 00 02 11] 307 | 0xC5, 1, 0x03, //SETOSC Frame Rate [03] 308 | 0xC6, 1, 0x80, //SETRGB interface control 309 | 0xC8, 12, 0x00, 0x14, 0x33, 0x10, 0x00, 0x16, 0x44, 0x36, 0x77, 0x00, 0x0F, 0x00, 310 | 0xF3, 2, 0x40, 0x0A, 311 | 0xF0, 1, 0x08, 312 | 0xF6, 1, 0x84, 313 | 0xF7, 1, 0x80, 314 | 0x0C, 2, 0x00, 0x55, //RDCOLMOD 315 | 0xB4, 1, 0x00, //SETDISPLAY 316 | // 0xB3, 4, 0x00, 0x01, 0x06, 0x01, //SETGRAM simple example 317 | 0xB3, 4, 0x00, 0x01, 0x06, 0x30, //jpegs example 318 | 0x36, 1, 0x48, //Memory Access [00] 319 | 0x3A, 1, 0x66, //Interlace Pixel Format [XX] 320 | // 0x20, 0, //INVOFF 321 | // 0x21, 0, //INVON 322 | 323 | // 0x3A, 1, 0x55, //Interlace Pixel Format [XX] 324 | 0x11, 0, //Sleep Out 325 | TFTLCD_DELAY8, 120, 326 | 0x29, 0, //Display On 327 | TFTLCD_DELAY8, 25, 328 | }; 329 | 330 | void ILI9481_kbv::begin(uint16_t ID) 331 | { 332 | _lcd_ID = ID; 333 | _lcd_xor = 0x02; 334 | uint8_t *p = (uint8_t *)ILI9481_RGB_regValues; 335 | int16_t size = sizeof(ILI9481_RGB_regValues); 336 | reset(); 337 | while (size > 0) { 338 | uint8_t cmd = pgm_read_byte(p++); 339 | uint8_t len = pgm_read_byte(p++); 340 | if (cmd == TFTLCD_DELAY8) { 341 | delay(len); 342 | len = 0; 343 | } else { 344 | CS_ACTIVE; 345 | WriteCmd(cmd); 346 | CD_DATA; 347 | for (uint8_t d = 0; d < len; d++) { 348 | uint8_t x = pgm_read_byte(p++); 349 | WriteDat8(x); 350 | } 351 | CS_IDLE; 352 | } 353 | size -= len + 2; 354 | } 355 | setRotation(0); //PORTRAIT 356 | } 357 | -------------------------------------------------------------------------------- /ILI9225_kbv.cpp: -------------------------------------------------------------------------------- 1 | #if defined(_____AVR) 2 | #include "ILI9225_kbv.h" 3 | #include "serial_kbv.h" 4 | 5 | /* 6 | #undef WriteCmd 7 | #define WriteCmd(x) { CD_COMMAND; write16(x); } 8 | */ 9 | static uint8_t _MC, _MP, _SC, _EC, _SP, _EP; 10 | 11 | static void xchg8_1(uint8_t c) 12 | { 13 | for(uint8_t bit = 0x80; bit; bit >>= 1) { 14 | if(c & bit) { 15 | MOSI_HI; 16 | } else { 17 | MOSI_LO; 18 | } 19 | SCK_HI; 20 | SCK_LO; 21 | } 22 | } 23 | 24 | static inline void write16_N(uint16_t color, int16_t n) 25 | { 26 | uint8_t hi = color >> 8, lo = color; 27 | while (n-- > 0) { 28 | // CS_ACTIVE; 29 | xchg8_1(hi); 30 | xchg8_1(lo); 31 | // CS_IDLE; 32 | } 33 | } 34 | 35 | ILI9225_kbv::ILI9225_kbv():Adafruit_GFX(176, 220) 36 | { 37 | } 38 | 39 | void ILI9225_kbv::reset(void) 40 | { 41 | INIT(); 42 | CS_IDLE; 43 | RESET_IDLE; 44 | wait_ms(50); 45 | RESET_ACTIVE; 46 | wait_ms(100); 47 | RESET_IDLE; 48 | wait_ms(100); 49 | } 50 | 51 | void ILI9225_kbv::WriteCmdData(uint16_t cmd, uint16_t dat) 52 | { 53 | CS_ACTIVE; 54 | WriteCmd(cmd); 55 | WriteData(dat); 56 | CS_IDLE; 57 | } 58 | 59 | #define ILI9225_DRIVER_OUTPUT_CTRL (0x01u) // Driver Output Control 60 | #define ILI9225_LCD_AC_DRIVING_CTRL (0x02u) // LCD AC Driving Control 61 | #define ILI9225_ENTRY_MODE (0x03u) // Entry Mode 62 | #define ILI9225_DISP_CTRL1 (0x07u) // Display Control 1 63 | #define ILI9225_BLANK_PERIOD_CTRL1 (0x08u) // Blank Period Control 64 | #define ILI9225_FRAME_CYCLE_CTRL (0x0Bu) // Frame Cycle Control 65 | #define ILI9225_INTERFACE_CTRL (0x0Cu) // Interface Control 66 | #define ILI9225_OSC_CTRL (0x0Fu) // Osc Control 67 | #define ILI9225_POWER_CTRL1 (0x10u) // Power Control 1 68 | #define ILI9225_POWER_CTRL2 (0x11u) // Power Control 2 69 | #define ILI9225_POWER_CTRL3 (0x12u) // Power Control 3 70 | #define ILI9225_POWER_CTRL4 (0x13u) // Power Control 4 71 | #define ILI9225_POWER_CTRL5 (0x14u) // Power Control 5 72 | #define ILI9225_VCI_RECYCLING (0x15u) // VCI Recycling 73 | #define ILI9225_RAM_ADDR_SET1 (0x20u) // Horizontal GRAM Address Set 74 | #define ILI9225_RAM_ADDR_SET2 (0x21u) // Vertical GRAM Address Set 75 | #define ILI9225_GRAM_DATA_REG (0x22u) // GRAM Data Register 76 | #define ILI9225_GATE_SCAN_CTRL (0x30u) // Gate Scan Control Register 77 | #define ILI9225_VERTICAL_SCROLL_CTRL1 (0x31u) // Vertical Scroll Control 1 Register 78 | #define ILI9225_VERTICAL_SCROLL_CTRL2 (0x32u) // Vertical Scroll Control 2 Register 79 | #define ILI9225_VERTICAL_SCROLL_CTRL3 (0x33u) // Vertical Scroll Control 3 Register 80 | #define ILI9225_PARTIAL_DRIVING_POS1 (0x34u) // Partial Driving Position 1 Register 81 | #define ILI9225_PARTIAL_DRIVING_POS2 (0x35u) // Partial Driving Position 2 Register 82 | #define ILI9225_HORIZONTAL_WINDOW_ADDR1 (0x36u) // Horizontal Address END Position HEA 83 | #define ILI9225_HORIZONTAL_WINDOW_ADDR2 (0x37u) // Horizontal Address START Position HSA 84 | #define ILI9225_VERTICAL_WINDOW_ADDR1 (0x38u) // Vertical Address END Position VEA 85 | #define ILI9225_VERTICAL_WINDOW_ADDR2 (0x39u) // Vertical Address START Position VSA 86 | #define ILI9225_GAMMA_CTRL1 (0x50u) // Gamma Control 1 87 | #define ILI9225_GAMMA_CTRL2 (0x51u) // Gamma Control 2 88 | #define ILI9225_GAMMA_CTRL3 (0x52u) // Gamma Control 3 89 | #define ILI9225_GAMMA_CTRL4 (0x53u) // Gamma Control 4 90 | #define ILI9225_GAMMA_CTRL5 (0x54u) // Gamma Control 5 91 | #define ILI9225_GAMMA_CTRL6 (0x55u) // Gamma Control 6 92 | #define ILI9225_GAMMA_CTRL7 (0x56u) // Gamma Control 7 93 | #define ILI9225_GAMMA_CTRL8 (0x57u) // Gamma Control 8 94 | #define ILI9225_GAMMA_CTRL9 (0x58u) // Gamma Control 9 95 | #define ILI9225_GAMMA_CTRL10 (0x59u) // Gamma Control 10 96 | 97 | #define ILI9225C_INVOFF 0x20 98 | #define ILI9225C_INVON 0x21 99 | 100 | uint16_t ILI9225_kbv::readReg(uint16_t reg) 101 | { 102 | return 0; 103 | } 104 | 105 | uint32_t ILI9225_kbv::readReg32(uint16_t reg) 106 | { 107 | return 0; 108 | } 109 | 110 | int16_t ILI9225_kbv::readGRAM(int16_t x, int16_t y, uint16_t * block, int16_t w, int16_t h) 111 | { 112 | return 0; 113 | } 114 | 115 | void ILI9225_kbv::setRotation(uint8_t r) 116 | { 117 | uint16_t mac; 118 | Adafruit_GFX::setRotation(r & 3); 119 | switch (rotation) { 120 | case 0: 121 | mac = 0x0800; 122 | break; 123 | case 1: 124 | mac = 0x6800; 125 | break; 126 | case 2: 127 | mac = 0xD800; 128 | break; 129 | case 3: 130 | mac = 0xB800; 131 | break; 132 | } 133 | if (mac & 0x2000) { 134 | _MC = ILI9225_RAM_ADDR_SET2, _MP = ILI9225_RAM_ADDR_SET1; 135 | _SC = ILI9225_VERTICAL_WINDOW_ADDR2, _EC = ILI9225_VERTICAL_WINDOW_ADDR1; 136 | _SP = ILI9225_HORIZONTAL_WINDOW_ADDR2, _EP = ILI9225_HORIZONTAL_WINDOW_ADDR1; 137 | WriteCmdData(ILI9225_ENTRY_MODE, 0x1038); 138 | } else { 139 | _MC = ILI9225_RAM_ADDR_SET1, _MP = ILI9225_RAM_ADDR_SET2; 140 | _SC = ILI9225_HORIZONTAL_WINDOW_ADDR2, _EC = ILI9225_HORIZONTAL_WINDOW_ADDR1; 141 | _SP = ILI9225_VERTICAL_WINDOW_ADDR2, _EP = ILI9225_VERTICAL_WINDOW_ADDR1; 142 | WriteCmdData(ILI9225_ENTRY_MODE, 0x1030); 143 | } 144 | mac ^= 0x4000; //flip SS 145 | WriteCmdData(ILI9225_DRIVER_OUTPUT_CTRL, ((mac & 0xC000) >> 6) | 0x001C); 146 | } 147 | 148 | void ILI9225_kbv::drawPixel(int16_t x, int16_t y, uint16_t color) 149 | { 150 | // ILI934X just plots at edge if you try to write outside of the box: 151 | if (x < 0 || y < 0 || x >= width() || y >= height()) 152 | return; 153 | WriteCmdData(_MC, x); 154 | WriteCmdData(_MP, y); 155 | WriteCmdData(ILI9225_GRAM_DATA_REG, color); 156 | } 157 | 158 | void ILI9225_kbv::setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1) 159 | { 160 | WriteCmdData(_SC, x); 161 | WriteCmdData(_EC, x1); 162 | WriteCmdData(_SP, y); 163 | WriteCmdData(_EP, y1); 164 | WriteCmdData(_MC, x); 165 | WriteCmdData(_MP, y); 166 | } 167 | 168 | void ILI9225_kbv::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 169 | { 170 | int16_t end; 171 | if (w < 0) { 172 | w = -w; 173 | x -= w; 174 | } //+ve w 175 | end = x + w; 176 | if (x < 0) 177 | x = 0; 178 | if (end > width()) 179 | end = width(); 180 | w = end - x; 181 | if (h < 0) { 182 | h = -h; 183 | y -= h; 184 | } //+ve h 185 | end = y + h; 186 | if (y < 0) 187 | y = 0; 188 | if (end > height()) 189 | end = height(); 190 | h = end - y; 191 | setAddrWindow(x, y, x + w - 1, y + h - 1); 192 | CS_ACTIVE; 193 | WriteCmd(ILI9225_GRAM_DATA_REG); 194 | CD_DATA; 195 | if (h > w) { end = h; h = w; w = end; } 196 | while (h-- > 0) { 197 | write16_N(color, w); 198 | } 199 | CS_IDLE; 200 | setAddrWindow(0, 0, width() - 1, height() - 1); 201 | } 202 | 203 | void ILI9225_kbv::pushColors(uint16_t * block, int16_t n, bool first) 204 | { 205 | uint16_t color; 206 | CS_ACTIVE; 207 | if (first) { 208 | WriteCmd(ILI9225_GRAM_DATA_REG); 209 | } 210 | CD_DATA; 211 | while (n-- > 0) { 212 | color = *block++; 213 | write16(color); 214 | } 215 | CS_IDLE; 216 | } 217 | 218 | void ILI9225_kbv::pushColors(uint8_t * block, int16_t n, bool first) 219 | { 220 | uint16_t color; 221 | uint8_t h, l; 222 | CS_ACTIVE; 223 | if (first) { 224 | WriteCmd(ILI9225_GRAM_DATA_REG); 225 | } 226 | CD_DATA; 227 | while (n-- > 0) { 228 | h = (*block++); 229 | l = (*block++); 230 | color = (h << 8) | l; 231 | write24(color); 232 | } 233 | CS_IDLE; 234 | } 235 | 236 | void ILI9225_kbv::pushColors(const uint8_t * block, int16_t n, bool first, bool bigend) 237 | { 238 | uint16_t color; 239 | uint8_t h, l; 240 | CS_ACTIVE; 241 | if (first) { 242 | WriteCmd(ILI9225_GRAM_DATA_REG); 243 | } 244 | CD_DATA; 245 | while (n-- > 0) { 246 | l = pgm_read_byte(block++); 247 | h = pgm_read_byte(block++); 248 | color = (bigend) ? (l << 8 ) | h : (h << 8) | l; 249 | write24(color); 250 | } 251 | CS_IDLE; 252 | } 253 | 254 | void ILI9225_kbv::invertDisplay(boolean i) 255 | { 256 | WriteCmdData(ILI9225_DISP_CTRL1, i ? 0x1013 : 0x1017); 257 | } 258 | 259 | void ILI9225_kbv::vertScroll(int16_t top, int16_t scrollines, int16_t offset) 260 | { 261 | int16_t bfa = HEIGHT - top - scrollines; // bottom fixed area 262 | int16_t vsp; 263 | int16_t sea = top; 264 | vsp = top + offset; // vertical start position 265 | if (offset < 0) 266 | vsp += scrollines; //keep in unsigned range 267 | sea = top + scrollines - 1; 268 | WriteCmdData(ILI9225_VERTICAL_SCROLL_CTRL1, sea); //SEA 269 | WriteCmdData(ILI9225_VERTICAL_SCROLL_CTRL2, top); //SSA 270 | WriteCmdData(ILI9225_VERTICAL_SCROLL_CTRL3, vsp - top); //SST 271 | } 272 | 273 | #define TFTLCD_DELAY 0xFFFF 274 | static const uint16_t ILI9225_regValues[] PROGMEM = { 275 | /* Start Initial Sequence */ 276 | /* Set SS bit and direction output from S528 to S1 */ 277 | ILI9225_POWER_CTRL1, 0x0000, // Set SAP,DSTB,STB 278 | ILI9225_POWER_CTRL2, 0x0000, // Set APON,PON,AON,VCI1EN,VC 279 | ILI9225_POWER_CTRL3, 0x0000, // Set BT,DC1,DC2,DC3 280 | ILI9225_POWER_CTRL4, 0x0000, // Set GVDD 281 | ILI9225_POWER_CTRL5, 0x0000, // Set VCOMH/VCOML voltage 282 | TFTLCD_DELAY, 40, 283 | 284 | // Power-on sequence 285 | ILI9225_POWER_CTRL2, 0x0018, // Set APON,PON,AON,VCI1EN,VC 286 | ILI9225_POWER_CTRL3, 0x6121, // Set BT,DC1,DC2,DC3 287 | ILI9225_POWER_CTRL4, 0x006F, // Set GVDD /*007F 0088 */ 288 | ILI9225_POWER_CTRL5, 0x495F, // Set VCOMH/VCOML voltage 289 | ILI9225_POWER_CTRL1, 0x0800, // Set SAP,DSTB,STB 290 | TFTLCD_DELAY, 10, 291 | ILI9225_POWER_CTRL2, 0x103B, // Set APON,PON,AON,VCI1EN,VC 292 | TFTLCD_DELAY, 50, 293 | 294 | ILI9225_DRIVER_OUTPUT_CTRL, 0x011C, // set the display line number and display direction 295 | ILI9225_LCD_AC_DRIVING_CTRL, 0x0100, // set 1 line inversion 296 | ILI9225_ENTRY_MODE, 0x1030, // set GRAM write direction and BGR=1. 297 | ILI9225_DISP_CTRL1, 0x0000, // Display off 298 | ILI9225_BLANK_PERIOD_CTRL1, 0x0808, // set the back porch and front porch 299 | ILI9225_FRAME_CYCLE_CTRL, 0x1100, // set the clocks number per line 300 | ILI9225_INTERFACE_CTRL, 0x0000, // CPU interface 301 | ILI9225_OSC_CTRL, 0x0D01, // Set Osc /*0e01*/ 302 | ILI9225_VCI_RECYCLING, 0x0020, // Set VCI recycling 303 | ILI9225_RAM_ADDR_SET1, 0x0000, // RAM Address 304 | ILI9225_RAM_ADDR_SET2, 0x0000, // RAM Address 305 | 306 | /* Set GRAM area */ 307 | ILI9225_GATE_SCAN_CTRL, 0x0000, 308 | ILI9225_VERTICAL_SCROLL_CTRL1, 0x00DB, 309 | ILI9225_VERTICAL_SCROLL_CTRL2, 0x0000, 310 | ILI9225_VERTICAL_SCROLL_CTRL3, 0x0000, 311 | ILI9225_PARTIAL_DRIVING_POS1, 0x00DB, 312 | ILI9225_PARTIAL_DRIVING_POS2, 0x0000, 313 | ILI9225_HORIZONTAL_WINDOW_ADDR1, 0x00AF, 314 | ILI9225_HORIZONTAL_WINDOW_ADDR2, 0x0000, 315 | ILI9225_VERTICAL_WINDOW_ADDR1, 0x00DB, 316 | ILI9225_VERTICAL_WINDOW_ADDR2, 0x0000, 317 | 318 | /* Set GAMMA curve */ 319 | ILI9225_GAMMA_CTRL1, 0x0000, 320 | ILI9225_GAMMA_CTRL2, 0x0808, 321 | ILI9225_GAMMA_CTRL3, 0x080A, 322 | ILI9225_GAMMA_CTRL4, 0x000A, 323 | ILI9225_GAMMA_CTRL5, 0x0A08, 324 | ILI9225_GAMMA_CTRL6, 0x0808, 325 | ILI9225_GAMMA_CTRL7, 0x0000, 326 | ILI9225_GAMMA_CTRL8, 0x0A00, 327 | ILI9225_GAMMA_CTRL9, 0x0710, 328 | ILI9225_GAMMA_CTRL10, 0x0710, 329 | 330 | ILI9225_DISP_CTRL1, 0x0012, 331 | TFTLCD_DELAY, 50, 332 | ILI9225_DISP_CTRL1, 0x1017, 333 | }; 334 | 335 | static void init_table16(const void *table, int16_t size) 336 | { 337 | uint16_t *p = (uint16_t *) table; 338 | while (size > 0) { 339 | uint16_t cmd = pgm_read_word(p++); 340 | uint16_t d = pgm_read_word(p++); 341 | if (cmd == TFTLCD_DELAY) 342 | delay(d); 343 | else { 344 | CS_ACTIVE; 345 | WriteCmd(cmd); 346 | WriteData(d); 347 | CS_IDLE; 348 | } 349 | size -= 2 * sizeof(int16_t); 350 | } 351 | } 352 | 353 | void ILI9225_kbv::begin(uint16_t ID) 354 | { 355 | _lcd_ID = ID; 356 | reset(); 357 | init_table16(ILI9225_regValues, sizeof(ILI9225_regValues)); 358 | setRotation(0); //PORTRAIT 359 | } 360 | #endif 361 | -------------------------------------------------------------------------------- /serial_complex.h: -------------------------------------------------------------------------------- 1 | #define USE_NOPS_MAX 1 2 | 3 | #define wait_ms(ms) delay(ms) 4 | #define xchg8(x) xchg8_1(x) 5 | #define write16(x) { write16_N(x, 1); } 6 | #define write24(x) { write24_N(x, 1); } 7 | #define WriteCmd(x) { CD_COMMAND; xchg8_1(x); CD_DATA; } 8 | #define WriteData(x) { write16(x); } 9 | 10 | static uint8_t spibuf[16]; 11 | 12 | #if 0 13 | #elif defined(ILI9225_KBV_H_) && defined(__AVR_ATmega328P__) 14 | #define LED_PORT PORTC 15 | #define LED_PIN PC0 16 | #define CD_PORT PORTC 17 | #define CD_PIN PC3 18 | #define CS_PORT PORTC 19 | #define CS_PIN PC5 20 | #define RESET_PORT PORTC 21 | #define RESET_PIN PC4 22 | #define SD_PORT PORTD 23 | #define SD_PIN PD4 24 | #define SPI_PORT PORTC 25 | #define MOSI_PIN PC2 26 | #define SCK_PIN PC1 27 | 28 | #define spi_init() 29 | #define SPCRVAL ((1<> 8, lo = color; 126 | do { 127 | SPSR; 128 | SPDR = hi; 129 | NOP16; 130 | SPSR; 131 | SPDR = lo; 132 | NOP11; 133 | } while (--n > 0); 134 | NOP6; 135 | SPSR; 136 | SPDR; 137 | } 138 | 139 | static inline void write24_N(uint16_t color, int16_t n) 140 | { 141 | uint8_t r = color >> 8, g = (color >> 3), b = color << 3; 142 | do { 143 | SPSR; 144 | SPDR = r; 145 | NOP16; 146 | SPSR; 147 | SPDR = g; 148 | NOP16; 149 | SPSR; 150 | SPDR = b; 151 | NOP11; 152 | } while (--n > 0); 153 | NOP6; 154 | SPSR; 155 | SPDR; 156 | } 157 | 158 | static inline void write8_block(uint8_t * block, int16_t n) 159 | { 160 | uint8_t c = *block++; 161 | do { 162 | SPSR; 163 | SPDR = c; 164 | c = *block++; 165 | NOP10; 166 | } while (--n > 0); 167 | NOP4; 168 | SPSR; 169 | SPDR; 170 | } 171 | 172 | #else // 9.41s 173 | 174 | static inline void write16_N(uint16_t color, int16_t n) 175 | { 176 | uint8_t hi = color >> 8, lo = color; 177 | SPDR = hi; 178 | while ((SPSR & 0x80) == 0); 179 | SPDR = lo; 180 | while (--n > 0) { 181 | NOP2; 182 | while ((SPSR & 0x80) == 0); 183 | SPDR = hi; 184 | NOP1; 185 | while ((SPSR & 0x80) == 0); 186 | SPDR = lo; 187 | } 188 | while ((SPSR & 0x80) == 0); 189 | } 190 | 191 | static inline void write24_N(uint16_t color, int16_t n) 192 | { 193 | uint8_t r = color >> 8, g = (color >> 3), b = color << 3; 194 | SPDR = r; 195 | while ((SPSR & 0x80) == 0); 196 | SPDR = g; 197 | while ((SPSR & 0x80) == 0); 198 | SPDR = b; 199 | while (--n > 0) { 200 | NOP2; 201 | while ((SPSR & 0x80) == 0); 202 | SPDR = r; 203 | NOP1; 204 | while ((SPSR & 0x80) == 0); 205 | SPDR = g; 206 | NOP1; 207 | while ((SPSR & 0x80) == 0); 208 | SPDR = b; 209 | } 210 | while ((SPSR & 0x80) == 0); 211 | } 212 | 213 | static inline void write8_block(uint8_t * block, int16_t n) 214 | { 215 | SPDR = *block++; 216 | while (--n > 0) { 217 | NOP2; 218 | while ((SPSR & 0x80) == 0); 219 | SPDR = *block++; 220 | } 221 | while ((SPSR & 0x80) == 0); 222 | } 223 | #endif 224 | #elif defined(__AVR_ATxmega32A4U__) //3.49s @ 32MHz -O2. 225 | // 100ns/150ns for ILI9341 W/R cycle. 100ns/200ns for ILI920. 20ns/150ns HX8347 226 | // Xmega @ 60MHz i.e. 30MHz SCK works with 9341. 227 | #warning Using ATxmega32A4U USART_MSPI 228 | #define CD_PORT VPORT2 229 | #define CD_PIN 1 230 | #define CS_PORT VPORT3 231 | #define CS_PIN 0 232 | #define RESET_PORT VPORT2 233 | #define RESET_PIN 0 234 | #define SD_PORT PORTC 235 | #define SD_PIN 4 236 | #define SPI_PORT VPORT3 237 | #define MOSI_PIN 3 238 | #define SCK_PIN 1 239 | 240 | #define SPCRVAL (USART_CLK2X_bm | USART_RXEN_bm | USART_TXEN_bm) 241 | #define SETDDR {PORTCFG.VPCTRLB=PORTCFG_VP13MAP_PORTD_gc | PORTCFG_VP02MAP_PORTC_gc; VPORT3.DIR |= (1<<0)|(1<<1)|(1<<3); VPORT2.DIR |= 0x03; PIN_HIGH(SD_PORT, SD_PIN); SD_PORT.DIR |= (1<> 8, lo = color; 287 | USARTD0.DATA = hi; 288 | while (--n > 0) { 289 | while ((USARTD0.STATUS & USART_DREIF_bm) == 0); 290 | USARTD0.DATA = lo; 291 | while ((USARTD0.STATUS & USART_DREIF_bm) == 0); 292 | USARTD0.DATA = hi; 293 | } 294 | while ((USARTD0.STATUS & USART_DREIF_bm) == 0); 295 | asm("cli"); 296 | USARTD0.DATA = lo; 297 | USARTD0.STATUS = USART_TXCIF_bm; 298 | asm("sei"); 299 | while ((USARTD0.STATUS & USART_TXCIF_bm) == 0); 300 | while ((USARTD0.STATUS & USART_RXCIF_bm) != 0) 301 | USARTD0.DATA; 302 | } 303 | 304 | static inline void write8_block(uint8_t * block, int16_t n) 305 | { 306 | USARTD0.DATA = *block++; 307 | while (--n > 0) { 308 | while ((USARTD0.STATUS & USART_DREIF_bm) == 0); 309 | asm("cli"); 310 | USARTD0.DATA = *block++; 311 | USARTD0.STATUS = USART_TXCIF_bm; 312 | asm("sei"); 313 | } 314 | while ((USARTD0.STATUS & USART_TXCIF_bm) == 0); 315 | while ((USARTD0.STATUS & USART_RXCIF_bm) != 0) 316 | USARTD0.DATA; 317 | } 318 | 319 | //#elif defined(__SAM3X8E__) //3.49s @ 32MHz -O2. 320 | #else 321 | // 100ns/150ns for ILI9341 W/R cycle. 100ns/200ns for ILI920. 20ns/150ns HX8347 322 | // Xmega @ 60MHz i.e. 30MHz SCK works with 9341. 323 | #warning Using Arduino SPI methods 324 | 325 | #include 326 | 327 | #define CD_PIN 9 328 | #define CS_PIN 10 329 | #define RESET_PIN 8 330 | #define SD_PIN 4 331 | #define MOSI_PIN 11 332 | #define SCK_PIN 13 333 | 334 | #define SETDDR { CS_OUTPUT; CD_OUTPUT; RESET_OUTPUT; PIN_HIGH(SD_PORT, SD_PIN); PIN_OUTPUT(SD_PORT, SD_PIN); } 335 | #define INIT() { CS_IDLE; RESET_IDLE; SETDDR; SPI.begin(); SPI.beginTransaction(settings); } 336 | 337 | #define PIN_LOW(p, b) digitalWrite(b, LOW) 338 | #define PIN_HIGH(p, b) digitalWrite(b, HIGH) 339 | #define PIN_OUTPUT(p, b) pinMode(b, OUTPUT) 340 | #define PIN_INPUT(p, b) pinMode(b, INPUT) 341 | #define PIN_READ(p, b) digitalRead(b) 342 | 343 | static SPISettings settings(42000000, MSBFIRST, SPI_MODE0); 344 | 345 | static inline uint8_t xchg8_1(uint8_t x) 346 | { 347 | return SPI.transfer(x); 348 | } 349 | 350 | #define SDIO_INMODE() SPI.endTransaction();MOSI_IN;SCK_OUT //no braces 351 | #define SDIO_OUTMODE() {MOSI_OUT;SCK_OUT;SPI.beginTransaction(settings);} 352 | static uint32_t readbits(uint8_t bits) 353 | { 354 | uint32_t ret = 0; 355 | while (bits--) { 356 | ret <<= 1; 357 | if (PIN_READ(SPI_PORT, MOSI_PIN)) 358 | ret++; 359 | SCK_HI; 360 | SCK_LO; 361 | } 362 | return ret; 363 | } 364 | 365 | static inline void write16_N(uint16_t color, int16_t n) 366 | { 367 | #if defined(__SAMD21G18A__) 368 | uint8_t hi = color >> 8, lo = color; 369 | Sercom *s = SERCOM1; 370 | while (n--) { 371 | while (s->SPI.INTFLAG.bit.DRE == 0) ; 372 | s->SPI.DATA.bit.DATA = hi; 373 | while (s->SPI.INTFLAG.bit.DRE == 0) ; 374 | s->SPI.DATA.bit.DATA = lo; 375 | } 376 | while (s->SPI.INTFLAG.bit.TXC == 0) ; 377 | s->SPI.DATA.bit.DATA; 378 | s->SPI.DATA.bit.DATA; 379 | #elif defined(___SAM3X8E__) // this does NOT work 380 | uint8_t hi = color >> 8, lo = color; 381 | // Spi *spi = SPI0; 382 | while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0) ; 383 | SPI0->SPI_TDR = hi; 384 | while (n-- > 1) { 385 | while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0) ; 386 | SPI0->SPI_TDR = lo; 387 | while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0) ; 388 | SPI0->SPI_TDR = hi; 389 | } 390 | while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0) ; 391 | SPI0->SPI_TDR = lo | SPI_TDR_LASTXFER; 392 | while ((SPI0->SPI_SR & SPI_SR_TXEMPTY) == 0) ; 393 | while ((SPI0->SPI_SR & SPI_SR_RDRF) != 0) 394 | SPI0->SPI_RDR; 395 | #else 396 | uint8_t hi = color >> 8, lo = color; 397 | while (n-- > 0) { 398 | SPI.transfer(hi); 399 | SPI.transfer(lo); 400 | } 401 | #endif 402 | } 403 | 404 | static inline void write8_block(uint8_t * block, int16_t n) 405 | { 406 | #if defined(__SAMD21G18A__) 407 | Sercom *s = SERCOM1; 408 | while (n--) { 409 | while (s->SPI.INTFLAG.bit.DRE == 0) ; 410 | s->SPI.DATA.bit.DATA = *block++; 411 | } 412 | while (s->SPI.INTFLAG.bit.TXC == 0) ; 413 | s->SPI.DATA.bit.DATA; 414 | s->SPI.DATA.bit.DATA; 415 | #else 416 | SPI.transfer(block, n); 417 | #endif 418 | } 419 | 420 | #endif 421 | -------------------------------------------------------------------------------- /ILI9341_kbv.cpp: -------------------------------------------------------------------------------- 1 | #include "ILI9341_kbv.h" 2 | #include "serial_kbv.h" 3 | 4 | ILI9341_kbv::ILI9341_kbv():Adafruit_GFX(240, 320) 5 | { 6 | } 7 | 8 | static uint8_t done_reset; 9 | 10 | void ILI9341_kbv::reset(void) 11 | { 12 | done_reset = 1; 13 | INIT(); 14 | CS_IDLE; 15 | RESET_IDLE; 16 | wait_ms(50); 17 | RESET_ACTIVE; 18 | wait_ms(100); 19 | RESET_IDLE; 20 | wait_ms(100); 21 | } 22 | 23 | void ILI9341_kbv::pushCommand(uint16_t cmd, uint8_t * block, int8_t N) 24 | { 25 | CS_ACTIVE; 26 | WriteCmd(cmd); 27 | write8_block(block, N); 28 | CS_IDLE; 29 | } 30 | 31 | #define ILI9341_CMD_NOP 0x00 32 | #define ILI9341_CMD_SOFTWARE_RESET 0x01 33 | #define ILI9341_CMD_READ_DISP_ID 0x04 34 | #define ILI9341_CMD_READ_DISP_STATUS 0x09 35 | #define ILI9341_CMD_READ_DISP_MADCTRL 0x0B 36 | #define ILI9341_CMD_READ_DISP_PIXEL_FORMAT 0x0C 37 | #define ILI9341_CMD_READ_DISP_IMAGE_FORMAT 0x0D 38 | #define ILI9341_CMD_READ_DISP_SIGNAL_MODE 0x0E 39 | #define ILI9341_CMD_READ_DISP_SELF_DIAGNOSTIC 0x0F 40 | #define ILI9341_CMD_ENTER_SLEEP_MODE 0x10 41 | #define ILI9341_CMD_SLEEP_OUT 0x11 42 | #define ILI9341_CMD_PARTIAL_MODE_ON 0x12 43 | #define ILI9341_CMD_NORMAL_DISP_MODE_ON 0x13 44 | #define ILI9341_CMD_DISP_INVERSION_OFF 0x20 45 | #define ILI9341_CMD_DISP_INVERSION_ON 0x21 46 | #define ILI9341_CMD_GAMMA_SET 0x26 47 | #define ILI9341_CMD_DISPLAY_OFF 0x28 48 | #define ILI9341_CMD_DISPLAY_ON 0x29 49 | #define ILI9341_CMD_COLUMN_ADDRESS_SET 0x2A 50 | #define ILI9341_CMD_PAGE_ADDRESS_SET 0x2B 51 | #define ILI9341_CMD_MEMORY_WRITE 0x2C 52 | #define ILI9341_CMD_COLOR_SET 0x2D 53 | #define ILI9341_CMD_MEMORY_READ 0x2E 54 | #define ILI9341_CMD_PARTIAL_AREA 0x30 55 | #define ILI9341_CMD_VERT_SCROLL_DEFINITION 0x33 56 | #define ILI9341_CMD_TEARING_EFFECT_LINE_OFF 0x34 57 | #define ILI9341_CMD_TEARING_EFFECT_LINE_ON 0x35 58 | #define ILI9341_CMD_MEMORY_ACCESS_CONTROL 0x36 59 | #define ILI9341_CMD_VERT_SCROLL_START_ADDRESS 0x37 60 | #define ILI9341_CMD_IDLE_MODE_OFF 0x38 61 | #define ILI9341_CMD_IDLE_MODE_ON 0x39 62 | #define ILI9341_CMD_COLMOD_PIXEL_FORMAT_SET 0x3A 63 | #define ILI9341_CMD_WRITE_MEMORY_CONTINUE 0x3C 64 | #define ILI9341_CMD_READ_MEMORY_CONTINUE 0x3E 65 | #define ILI9341_CMD_SET_TEAR_SCANLINE 0x44 66 | #define ILI9341_CMD_GET_SCANLINE 0x45 67 | #define ILI9341_CMD_WRITE_DISPLAY_BRIGHTNESS 0x51 68 | #define ILI9341_CMD_READ_DISPLAY_BRIGHTNESS 0x52 69 | #define ILI9341_CMD_WRITE_CTRL_DISPLAY 0x53 70 | #define ILI9341_CMD_READ_CTRL_DISPLAY 0x54 71 | #define ILI9341_CMD_WRITE_CONTENT_ADAPT_BRIGHTNESS 0x55 72 | #define ILI9341_CMD_READ_CONTENT_ADAPT_BRIGHTNESS 0x56 73 | #define ILI9341_CMD_WRITE_MIN_CAB_LEVEL 0x5E 74 | #define ILI9341_CMD_READ_MIN_CAB_LEVEL 0x5F 75 | #define ILI9341_CMD_READ_ID1 0xDA 76 | #define ILI9341_CMD_READ_ID2 0xDB 77 | #define ILI9341_CMD_READ_ID3 0xDC 78 | 79 | static uint8_t readReg8(uint8_t reg, uint8_t dat) 80 | { 81 | uint8_t ret; 82 | CD_COMMAND; 83 | CS_ACTIVE; 84 | xchg8(reg); 85 | CD_DATA; //should do a flush() 86 | ret = xchg8(dat); //only safe to read @ SCK=16MHz 87 | CS_IDLE; 88 | return ret; 89 | } 90 | 91 | uint8_t ILI9341_kbv::readcommand8(uint8_t reg, uint8_t idx) //this is the same as Adafruit_ILI9341 92 | { 93 | readReg8(0xD9, 0x10 | idx); 94 | return readReg8(reg, 0xFF); 95 | } 96 | 97 | uint16_t ILI9341_kbv::readID(void) //{ return 0x9341; } 98 | { 99 | if (!done_reset) reset(); 100 | return (readcommand8(0xD3, 2) << 8) | readcommand8(0xD3, 3); 101 | } 102 | 103 | uint16_t ILI9341_kbv::readReg(uint16_t reg, uint8_t idx) //note that this reads pairs of data bytes 104 | { 105 | uint8_t h, l; 106 | idx <<= 1; 107 | h = readcommand8(reg, idx); 108 | l = readcommand8(reg, idx + 1); 109 | return (h << 8) | l; 110 | } 111 | 112 | int16_t ILI9341_kbv::readGRAM(int16_t x, int16_t y, uint16_t * block, int16_t w, int16_t h) 113 | { 114 | uint8_t r, g, b; 115 | int16_t n = w * h; // we are NEVER going to read > 32k pixels at once 116 | setAddrWindow(x, y, x + w - 1, y + h - 1); 117 | CS_ACTIVE; 118 | WriteCmd(ILI9341_CMD_MEMORY_READ); 119 | 120 | // needs 1 dummy read 121 | r = xchg8(0xFF); 122 | while (n-- > 0) { 123 | r = xchg8(0xFF); 124 | g = xchg8(0xFF); 125 | b = xchg8(0xFF); 126 | *block++ = color565(r, g, b); 127 | } 128 | CS_IDLE; 129 | setAddrWindow(0, 0, width() - 1, height() - 1); 130 | return 0; 131 | } 132 | 133 | void ILI9341_kbv::setRotation(uint8_t r) 134 | { 135 | uint8_t mac = 0x00; 136 | Adafruit_GFX::setRotation(r & 3); 137 | switch (rotation) { 138 | case 0: 139 | mac = 0x08; 140 | break; 141 | case 1: //LANDSCAPE 90 degrees 142 | mac = 0x68; 143 | break; 144 | case 2: 145 | mac = 0xD8; 146 | break; 147 | case 3: 148 | mac = 0xB8; 149 | break; 150 | } 151 | pushCommand(ILI9341_CMD_MEMORY_ACCESS_CONTROL, &mac, 1); 152 | } 153 | 154 | void ILI9341_kbv::drawPixel(int16_t x, int16_t y, uint16_t color) 155 | { 156 | // ILI934X just plots at edge if you try to write outside of the box: 157 | if (x < 0 || y < 0 || x >= width() || y >= height()) 158 | return; 159 | CS_ACTIVE; 160 | WriteCmd(ILI9341_CMD_COLUMN_ADDRESS_SET); 161 | write16(x); 162 | WriteCmd(ILI9341_CMD_PAGE_ADDRESS_SET); 163 | write16(y); 164 | WriteCmd(ILI9341_CMD_MEMORY_WRITE); 165 | write16(color); 166 | CS_IDLE; 167 | } 168 | 169 | void ILI9341_kbv::setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1) 170 | { 171 | CS_ACTIVE; 172 | WriteCmd(ILI9341_CMD_COLUMN_ADDRESS_SET); 173 | write16(x); 174 | write16(x1); 175 | WriteCmd(ILI9341_CMD_PAGE_ADDRESS_SET); 176 | write16(y); 177 | write16(y1); 178 | CS_IDLE; 179 | } 180 | 181 | void ILI9341_kbv::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 182 | { 183 | int16_t end; 184 | if (w < 0) { 185 | w = -w; 186 | x -= w; 187 | } //+ve w 188 | end = x + w; 189 | if (x < 0) 190 | x = 0; 191 | if (end > width()) 192 | end = width(); 193 | w = end - x; 194 | if (h < 0) { 195 | h = -h; 196 | y -= h; 197 | } //+ve h 198 | end = y + h; 199 | if (y < 0) 200 | y = 0; 201 | if (end > height()) 202 | end = height(); 203 | h = end - y; 204 | setAddrWindow(x, y, x + w - 1, y + h - 1); 205 | CS_ACTIVE; 206 | WriteCmd(ILI9341_CMD_MEMORY_WRITE); 207 | if (h > w) { end = h; h = w; w = end; } 208 | while (h-- > 0) { 209 | write16_N(color, w); 210 | } 211 | CS_IDLE; 212 | setAddrWindow(0, 0, width() - 1, height() - 1); 213 | } 214 | 215 | void ILI9341_kbv::pushColors(uint16_t * block, int16_t n, bool first) 216 | { 217 | uint16_t color; 218 | CS_ACTIVE; 219 | if (first) { 220 | WriteCmd(ILI9341_CMD_MEMORY_WRITE); 221 | } 222 | while (n-- > 0) { 223 | color = *block++; 224 | write16(color); 225 | } 226 | CS_IDLE; 227 | } 228 | 229 | void ILI9341_kbv::pushColors(uint8_t * block, int16_t n, bool first) 230 | { 231 | uint16_t color; 232 | uint8_t h, l; 233 | CS_ACTIVE; 234 | if (first) { 235 | WriteCmd(ILI9341_CMD_MEMORY_WRITE); 236 | } 237 | while (n-- > 0) { 238 | h = (*block++); 239 | l = (*block++); 240 | color = (h << 8) | l; 241 | write16(color); 242 | } 243 | CS_IDLE; 244 | } 245 | 246 | void ILI9341_kbv::pushColors(const uint8_t * block, int16_t n, bool first, bool bigend) 247 | { 248 | uint16_t color; 249 | uint8_t h, l; 250 | CS_ACTIVE; 251 | if (first) { 252 | WriteCmd(ILI9341_CMD_MEMORY_WRITE); 253 | } 254 | while (n-- > 0) { 255 | l = pgm_read_byte(block++); 256 | h = pgm_read_byte(block++); 257 | color = (bigend) ? (l << 8 ) | h : (h << 8) | l; 258 | write16(color); 259 | } 260 | CS_IDLE; 261 | } 262 | 263 | void ILI9341_kbv::invertDisplay(boolean i) 264 | { 265 | pushCommand(i ? ILI9341_CMD_DISP_INVERSION_ON : ILI9341_CMD_DISP_INVERSION_OFF, NULL, 0); 266 | } 267 | 268 | void ILI9341_kbv::vertScroll(int16_t top, int16_t scrollines, int16_t offset) 269 | { 270 | int16_t bfa = HEIGHT - top - scrollines; // bottom fixed area 271 | int16_t vsp; 272 | vsp = top + offset; // vertical start position 273 | if (offset < 0) 274 | vsp += scrollines; //keep in unsigned range 275 | CS_ACTIVE; 276 | WriteCmd( 0x0033); 277 | write16(top); //TOP 278 | write16(scrollines); //VSA 279 | write16(bfa); //BFA 280 | 281 | WriteCmd(0x0037) 282 | write16(vsp); //VLSP 283 | CS_IDLE; 284 | } 285 | 286 | #define TFTLCD_DELAY8 0xFF 287 | 288 | const uint8_t PROGMEM ILI9341_regValues_kbv[] = { 289 | // (COMMAND_BYTE), n, data_bytes.... 290 | (0x01), 0, //ILI9341_CMD_SOFTWARE_RESET 291 | TFTLCD_DELAY8, 50, // .kbv 292 | (0xCF), 3, //ILI9341_CMD_POWER_CONTROL_B 293 | 0x00, 0x8B, 0x30, 294 | (0xED), 4, //ILI9341_CMD_POWER_ON_SEQ_CONTROL 295 | 0x67, 0x03, 0x12, 0x81, 296 | (0xE8), 3, //ILI9341_CMD_DRIVER_TIMING_CONTROL_A 297 | 0x85, 0x10, 0x7A, 298 | (0xCB), 5, //ILI9341_CMD_POWER_CONTROL_A 299 | 0x39, 0x2C, 0x00, 0x34, 0x02, 300 | (0xF7), 1, //ILI9341_CMD_PUMP_RATIO_CONTROL 301 | 0x20, 302 | (0xEA), 2, //ILI9341_CMD_DRIVER_TIMING_CONTROL_B 303 | 0x00, 0x00, 304 | (0xC0), 1, //ILI9341_CMD_POWER_CONTROL_1 305 | 0x1B, /* VRH[5:0] */ 306 | (0xC1), 1, //ILI9341_CMD_POWER_CONTROL_2 307 | 0x10, /* SAP[2:0];BT[3:0] */ 308 | (0xC5), 2, //ILI9341_CMD_VCOM_CONTROL_1 309 | 0x3F, 0x3C, 310 | (0xC7), 1, //ILI9341_CMD_VCOM_CONTROL_2 311 | 0xB7, 312 | (0x36), 1, //ILI9341_CMD_MEMORY_ACCESS_CONTROL 313 | 0x08, 314 | (0x3A), 1, //ILI9341_CMD_COLMOD_PIXEL_FORMAT_SET 315 | 0x55, 316 | (0xB1), 2, //ILI9341_CMD_FRAME_RATE_CONTROL_NORMAL 317 | 0x00, 0x1B, 318 | (0xB4), 1, 0x00, //Inversion Control [02] .kbv NLA=1, NLB=1, NLC=1 Extended anyway 319 | (0xB6), 2, //ILI9341_CMD_DISPLAY_FUNCTION_CONTROL 320 | 0x0A, 0xA2, 321 | (0xF2), 1, //ILI9341_CMD_ENABLE_3_GAMMA_CONTROL 322 | 0x00, /* 3Gamma Function Disable */ 323 | (0x26), 1, //ILI9341_CMD_GAMMA_SET 324 | 0x01, 325 | (0xE0), 15, //ILI9341_CMD_POSITIVE_GAMMA_CORRECTION 326 | 0x0F, 0x2A, 0x28, 0x08, 0x0E, 0x08, 0x54, 0XA9, 0x43, 0x0A, 0x0F, 0x00, 327 | 0x00, 0x00, 0x00, 328 | (0xE1), 15, //ILI9341_CMD_NEGATIVE_GAMMA_CORRECTION 329 | 0x00, 0x15, 0x17, 0x07, 0x11, 0x06, 0x2B, 0x56, 0x3C, 0x05, 0x10, 0x0F, 330 | 0x3F, 0x3F, 0x0F, 331 | (0x11), 0, //ILI9341_CMD_SLEEP_OUT 332 | TFTLCD_DELAY8, 150, // .kbv 333 | (0x29), 0, //ILI9341_CMD_DISPLAY_ON 334 | }; 335 | static const uint8_t ILI9341_regValues_2_4[] PROGMEM = { // BOE 2.4" 336 | 0x01, 0, // software reset 337 | TFTLCD_DELAY8, 50, // .kbv 338 | 0xCF, 3, 0x00, 0x81, 0x30, //Power Control B [00 81 30] 339 | 0xED, 4, 0x64, 0x03, 0x12, 0x81, //Power On Seq [55 01 23 01] 340 | 0xE8, 3, 0x85, 0x10, 0x78, //Driver Timing A [04 11 7A] 341 | 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, //Power Control A [39 2C 00 34 02] 342 | 0xF7, 1, 0x20, //Pump Ratio [10] 343 | 0xEA, 2, 0x00, 0x00, //Driver Timing B [66 00] 344 | 0xB1, 2, 0x00, 0x1B, //Frame Control [00 1B] 345 | 0xB6, 2, 0x0A, 0xA2, 0x27, //Display Function [0A 82 27 XX] .kbv SS=1 346 | 0xB4, 1, 0x00, //Inversion Control [02] .kbv NLA=1, NLB=1, NLC=1 347 | 0xC0, 1, 0x21, //Power Control 1 [26] 348 | 0xC1, 1, 0x11, //Power Control 2 [00] 349 | 0xC5, 2, 0x3F, 0x3C, //VCOM 1 [31 3C] 350 | 0xC7, 1, 0xB5, //VCOM 2 [C0] 351 | 0x36, 1, 0x48, //Memory Access [00] 352 | 0xF2, 1, 0x00, //Enable 3G [02] 353 | 0x26, 1, 0x01, //Gamma Set [01] 354 | 0xE0, 15, 0x0f, 0x26, 0x24, 0x0b, 0x0e, 0x09, 0x54, 0xa8, 0x46, 0x0c, 0x17, 0x09, 0x0f, 0x07, 0x00, 355 | 0xE1, 15, 0x00, 0x19, 0x1b, 0x04, 0x10, 0x07, 0x2a, 0x47, 0x39, 0x03, 0x06, 0x06, 0x30, 0x38, 0x0f, 356 | 0x11, 0, //Sleep Out 357 | TFTLCD_DELAY8, 150, 358 | 0x29, 0, //Display On 359 | 0x3A, 1, 0x55, //Pixel Format [66] 360 | }; 361 | // init_table(ILI9341_regValues_2_4, sizeof(ILI9341_regValues_2_4)); // 362 | 363 | //#define tableNNNN ILI9341_regValues_2_4 364 | #define tableNNNN ILI9341_regValues_kbv 365 | 366 | void ILI9341_kbv::begin(uint16_t ID) 367 | { 368 | _lcd_ID = ID; 369 | uint8_t *p = (uint8_t *) tableNNNN; 370 | int16_t size = sizeof(tableNNNN); 371 | reset(); 372 | while (size > 0) { 373 | uint8_t cmd = pgm_read_byte(p++); 374 | uint8_t len = pgm_read_byte(p++); 375 | if (cmd == TFTLCD_DELAY8) { 376 | delay(len); 377 | len = 0; 378 | } else { 379 | CS_ACTIVE; 380 | WriteCmd(cmd); 381 | for (uint8_t d = 0; d < len; d++) { 382 | uint8_t x = pgm_read_byte(p++); 383 | xchg8(x); 384 | } 385 | CS_IDLE; 386 | } 387 | size -= len + 2; 388 | } 389 | setRotation(0); //PORTRAIT 390 | } 391 | -------------------------------------------------------------------------------- /HX8347_kbv.cpp: -------------------------------------------------------------------------------- 1 | #if defined(AVR) 2 | #include "HX8347_kbv.h" 3 | 4 | #if USE_MBED 5 | #define CS_IDLE { _lcd_pin_cs = 1; } 6 | #define CS_ACTIVE _lcd_pin_cs = 0 7 | #define CD_DATA { _lcd_pin_rs = 1; } 8 | #define CD_COMMAND _lcd_pin_rs = 0 9 | #define RESET_IDLE _lcd_pin_reset = 1 10 | #define RESET_ACTIVE _lcd_pin_reset = 0 11 | #define xchg8(x) _spi.write((uint8_t)x) 12 | #define write8(x) { _spi.write((uint8_t)x); } 13 | #define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } 14 | #define WriteCmd(x) { CD_COMMAND; write8(x); } 15 | #define WriteData(x) { CD_DATA; write8(x); } 16 | 17 | HX8347_kbv::HX8347_kbv(PinName CS, PinName RS, PinName RST) 18 | : _lcd_pin_rs(RS), _lcd_pin_cs(CS), _lcd_pin_reset(RST), _spi(D11, D12, D13), Adafruit_GFX(240, 320) 19 | { 20 | _spi.format(8, 0); 21 | _spi.frequency(12000000); 22 | CS_IDLE; 23 | RESET_IDLE; 24 | } 25 | #else 26 | #if 1 27 | #include 28 | #if 0 29 | #elif defined(__AVR_ATmega328P__) 30 | #define CD_PORT PORTD 31 | #define CD_PIN PD7 //digital#7 32 | #define CS_PORT PORTB 33 | #define CS_PIN PB2 //digital#10 34 | #define RESET_PORT PORTB 35 | #define RESET_PIN PB1 //Backlight //digital#9 36 | #define SD_PORT PORTD 37 | #define SD_PIN PD5 //digital#5 38 | #define XPT_PORT PORTD 39 | #define XPT_PIN PD4 //digital#4 40 | #define SPI_SS PB2 41 | #define SPI_SCK PB5 42 | #define SPI_MOSI PB3 43 | #elif defined(__AVR_ATmega32U4__) 44 | #define CD_PORT PORTE 45 | #define CD_PIN PE6 //digital#7 46 | #define CS_PORT PORTB 47 | #define CS_PIN PB6 //digital#10 48 | #define RESET_PORT PORTB 49 | #define RESET_PIN PB5 //Backlight //digital#9 50 | #define SD_PORT PORTC 51 | #define SD_PIN PC6 //digital#5 52 | #define XPT_PORT PORTD 53 | #define XPT_PIN PD4 //digital#4 54 | #define SPI_SS PB0 55 | #define SPI_SCK PB1 56 | #define SPI_MOSI PB2 57 | #elif defined(__AVR_ATmega2560__) 58 | #define CD_PORT PORTH 59 | #define CD_PIN PH4 //digital#7 60 | #define CS_PORT PORTB 61 | #define CS_PIN PB4 //digital#10 62 | #define RESET_PORT PORTH 63 | #define RESET_PIN PH6 //Backlight //digital#9 64 | #define SD_PORT PORTE 65 | #define SD_PIN PE3 //digital#5 66 | #define XPT_PORT PORTG 67 | #define XPT_PIN PG5 //digital#4 68 | #define SPI_SS PB0 69 | #define SPI_SCK PB1 70 | #define SPI_MOSI PB2 71 | #else 72 | #error 73 | #endif 74 | 75 | #define SETDDR { CS_OUTPUT; RESET_OUTPUT; CD_OUTPUT; SD_OUTPUT; XPT_OUTPUT; } 76 | #define INIT() { CS_IDLE; RESET_IDLE; SD_IDLE; XPT_IDLE; SETDDR; spi_init(); } 77 | 78 | #define SPCRVAL ((1<>8, l = x; write8(h); write8(l); } 137 | #define WriteCmd(x) { flush(); CD_COMMAND; write8(x); flush(); } 138 | #define WriteData(x) { CD_DATA; write16(x); } 139 | 140 | #define wait_ms(ms) delay(ms) 141 | 142 | HX8347_kbv::HX8347_kbv():Adafruit_GFX(240, 320) 143 | { 144 | INIT(); 145 | CS_IDLE; 146 | RESET_IDLE; 147 | } 148 | #endif 149 | 150 | void HX8347_kbv::reset(void) 151 | { 152 | wait_ms(50); 153 | RESET_ACTIVE; 154 | wait_ms(100); 155 | RESET_IDLE; 156 | wait_ms(100); 157 | } 158 | 159 | void HX8347_kbv::WriteCmdData(uint16_t cmd, uint16_t dat) 160 | { 161 | CS_ACTIVE; 162 | WriteCmd(cmd); 163 | WriteData(dat); 164 | CS_IDLE; 165 | } 166 | 167 | #define WriteCmdDataPair(c, d) { WriteCmdData(c, (d)>>8); WriteCmdData(c+1, (d)&0xFF); } 168 | #define HX8347G_COLADDRSTART_HI 0x02 169 | #define HX8347G_COLADDRSTART_LO 0x03 170 | #define HX8347G_COLADDREND_HI 0x04 171 | #define HX8347G_COLADDREND_LO 0x05 172 | #define HX8347G_ROWADDRSTART_HI 0x06 173 | #define HX8347G_ROWADDRSTART_LO 0x07 174 | #define HX8347G_ROWADDREND_HI 0x08 175 | #define HX8347G_ROWADDREND_LO 0x09 176 | #define HX8347G_MEMACCESS 0x16 177 | #define HX8347G_MEMWRITE 0x22 178 | #define HX8347G_MEMREAD 0x22 179 | 180 | uint16_t HX8347_kbv::readReg(uint16_t reg) 181 | { 182 | uint8_t h, l; 183 | CS_ACTIVE; 184 | WriteCmd(reg); 185 | CD_DATA; //should do a flush() 186 | 187 | // h = xchg8(0xFF); 188 | l = xchg8(0xFF); 189 | CS_IDLE; 190 | return (h << 8) | l; 191 | } 192 | 193 | int16_t HX8347_kbv::readGRAM(int16_t x, int16_t y, uint16_t * block, int16_t w, int16_t h) 194 | { 195 | return -1; // .kbv HX8347-D has IM=0110. HX8347-G is r/w IM=1110 (4-wire Serial II) 196 | /* 197 | uint8_t r, g, b; 198 | int16_t n = w * h; // we are NEVER going to read > 32k pixels at once 199 | 200 | setAddrWindow(x, y, x + n - 1, y + h - 1); 201 | CS_ACTIVE; 202 | WriteCmd(HX8347G_MEMREAD); 203 | CD_DATA; 204 | 205 | r = xchg8(0xFF); // needs 2 dummy read 206 | g = xchg8(0xFF); // needs 2 dummy read 207 | while (n-- > 0) { 208 | r = xchg8(0xFF); 209 | g = xchg8(0xFF); 210 | *block++ = (r << 8u)|(g); 211 | } 212 | CS_IDLE; 213 | return 0; 214 | */ 215 | } 216 | 217 | void HX8347_kbv::setRotation(uint8_t r) 218 | { 219 | uint16_t mac = 0x0800; 220 | Adafruit_GFX::setRotation(r & 3); 221 | switch (rotation) { 222 | case 0: 223 | mac = 0x0800; // BGR=1 224 | break; 225 | case 1: 226 | mac = 0x6800; //MY=0, MX=1, MV=0, ML=0, BGR=1 227 | break; 228 | case 2: 229 | mac = 0xD800; //MY=1, MX=1, MV=0, ML=1, BGR=1 230 | break; 231 | case 3: 232 | mac = 0xB800; //MY=1, MX=0, MV=1, ML=1, BGR=1 233 | break; 234 | } 235 | WriteCmdData(HX8347G_MEMACCESS, mac >> 8); 236 | } 237 | 238 | void HX8347_kbv::drawPixel(int16_t x, int16_t y, uint16_t color) 239 | { 240 | // ILI934X just plots at edge if you try to write outside of the box: 241 | if (x < 0 || y < 0 || x >= width() || y >= height()) return; 242 | WriteCmdDataPair(HX8347G_COLADDRSTART_HI, x); 243 | WriteCmdDataPair(HX8347G_COLADDREND_HI, x); 244 | WriteCmdDataPair(HX8347G_ROWADDRSTART_HI, y); 245 | WriteCmdDataPair(HX8347G_ROWADDREND_HI, y); 246 | CS_ACTIVE; 247 | WriteCmd(HX8347G_MEMWRITE); 248 | CD_DATA; 249 | write16(color); 250 | CS_IDLE; 251 | } 252 | 253 | void HX8347_kbv::setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1) 254 | { 255 | CS_ACTIVE; 256 | WriteCmdDataPair(HX8347G_COLADDRSTART_HI, x); 257 | WriteCmdDataPair(HX8347G_COLADDREND_HI, x1); 258 | WriteCmdDataPair(HX8347G_ROWADDRSTART_HI, y); 259 | WriteCmdDataPair(HX8347G_ROWADDREND_HI, y1); 260 | CS_IDLE; 261 | } 262 | 263 | void HX8347_kbv::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 264 | { 265 | int16_t end; 266 | if (w < 0) { w = -w; x -= w; } //+ve w 267 | end = x + w; 268 | if (x < 0) x = 0; 269 | if (end > width()) end = width(); 270 | w = end - x; 271 | if (h < 0) { h = -h; y -= h; } //+ve h 272 | end = y + h; 273 | if (y < 0) y = 0; 274 | if (end > height()) end = height(); 275 | h = end - y; 276 | setAddrWindow(x, y, x+w-1, y+h-1); 277 | CS_ACTIVE; 278 | WriteCmd(HX8347G_MEMWRITE); 279 | CD_DATA; 280 | if (h > w) { end = h; h = w; w = end; } 281 | uint8_t hi = color >> 8; 282 | uint8_t lo = color; 283 | while (h-- > 0) { 284 | for (int16_t i = w; i-- > 0; ) { 285 | write8(hi); 286 | asm("nop"); 287 | asm("nop"); 288 | asm("nop"); 289 | write8(lo); 290 | // asm("nop"); 291 | // asm("nop"); 292 | } 293 | } 294 | CS_IDLE; 295 | // setAddrWindow(0, 0, width()-1, height()-1); 296 | } 297 | 298 | void HX8347_kbv::pushColors(uint16_t * block, int16_t n, bool first) 299 | { 300 | uint16_t color; 301 | CS_ACTIVE; 302 | if (first) { 303 | WriteCmd(HX8347G_MEMWRITE); 304 | } 305 | CD_DATA; 306 | while (n-- > 0) { 307 | color = *block++; 308 | write16(color); 309 | } 310 | CS_IDLE; 311 | } 312 | 313 | void HX8347_kbv::pushColors(uint8_t * block, int16_t n, bool first) 314 | { 315 | uint16_t color; 316 | uint8_t h, l; 317 | CS_ACTIVE; 318 | if (first) { 319 | WriteCmd(HX8347G_MEMWRITE); 320 | } 321 | CD_DATA; 322 | while (n-- > 0) { 323 | h = (*block++); 324 | l = (*block++); 325 | color = (h << 8) | l; 326 | write16(color); 327 | } 328 | CS_IDLE; 329 | } 330 | 331 | void HX8347_kbv::pushColors(const uint8_t * block, int16_t n, bool first, bool bigend) 332 | { 333 | uint16_t color; 334 | uint8_t h, l; 335 | CS_ACTIVE; 336 | if (first) { 337 | WriteCmd(HX8347G_MEMWRITE); 338 | } 339 | CD_DATA; 340 | while (n-- > 0) { 341 | l = pgm_read_byte(block++); 342 | h = pgm_read_byte(block++); 343 | color = (bigend) ? (l << 8 ) | h : (h << 8) | l; 344 | write16(color); 345 | } 346 | CS_IDLE; 347 | } 348 | 349 | void HX8347_kbv::invertDisplay(bool i) 350 | { 351 | uint8_t val = 0x00; 352 | // val = readReg(0x36); //.kbv HX8347-D can't read SPI. 353 | if (i) val |= 2; 354 | else val &= ~2; 355 | WriteCmdData(0x36, val); 356 | } 357 | 358 | void HX8347_kbv::vertScroll(int16_t top, int16_t scrollines, int16_t offset) 359 | { 360 | int16_t bfa = HEIGHT - top - scrollines; // bottom fixed area 361 | int16_t vsp; 362 | if (offset <= -scrollines || offset >= scrollines) offset = 0; //valid scroll 363 | vsp = top + offset; // vertical start position 364 | if (offset < 0) 365 | vsp += scrollines; //keep in unsigned range 366 | WriteCmdData(0x01, 8); //VLE 367 | WriteCmdDataPair(0x0E, top); //TOP 368 | WriteCmdDataPair(0x10, scrollines); 369 | WriteCmdDataPair(0x12, 320 - top - scrollines); 370 | WriteCmdDataPair(0x14, vsp); //VL# 371 | 372 | } 373 | 374 | #define TFTLCD_DELAY 0xFF 375 | 376 | static const uint8_t HX8347G_regValues[] PROGMEM = { 377 | 0x2E , 0x89, 378 | 0x29 , 0x8F, 379 | 0x2B , 0x02, 380 | 0xE2 , 0x00, 381 | 0xE4 , 0x01, 382 | 0xE5 , 0x10, 383 | 0xE6 , 0x01, 384 | 0xE7 , 0x10, 385 | 0xE8 , 0x70, 386 | 0xF2 , 0x00, 387 | 0xEA , 0x00, 388 | 0xEB , 0x20, 389 | 0xEC , 0x3C, 390 | 0xED , 0xC8, 391 | 0xE9 , 0x38, 392 | 0xF1 , 0x01, 393 | 394 | // skip gamma, do later 395 | 396 | 0x1B , 0x1A, 397 | 0x1A , 0x02, 398 | 0x24 , 0x61, 399 | 0x25 , 0x5C, 400 | 401 | 0x18 , 0x36, 402 | 0x19 , 0x01, 403 | 0x1F , 0x88, 404 | TFTLCD_DELAY , 5 , // delay 5 ms 405 | 0x1F , 0x80, 406 | TFTLCD_DELAY , 5 , 407 | 0x1F , 0x90, 408 | TFTLCD_DELAY , 5 , 409 | 0x1F , 0xD4, 410 | TFTLCD_DELAY , 5 , 411 | 0x17 , 0x05, 412 | 413 | 0x36 , 0x00, // .kbv was 0x09 414 | 0x28 , 0x38, 415 | TFTLCD_DELAY , 40 , 416 | 0x28 , 0x3C, 417 | 418 | 0x02 , 0x00, 419 | 0x03 , 0x00, 420 | 0x04 , 0x00, 421 | 0x05 , 0xEF, 422 | 0x06 , 0x00, 423 | 0x07 , 0x00, 424 | 0x08 , 0x01, 425 | 0x09 , 0x3F 426 | }; 427 | static const uint8_t HX8347G_2_regValues[] PROGMEM = { 428 | 0xEA,0x00, //PTBA[15:8] 429 | 0xEB,0x20, //PTBA[7:0] 430 | 0xEC,0x0C, //STBA[15:8] 431 | 0xED,0xC4, //STBA[7:0] 432 | 0xE8,0x38, //OPON[7:0] 433 | 0xE9,0x10, //OPON1[7:0] 434 | 0xF1,0x01, //OTPS1B 435 | 0xF2,0x10, //GEN 436 | //Gamma 2.2 Setting 437 | 0x40,0x01, // 438 | 0x41,0x00, // 439 | 0x42,0x00, // 440 | 0x43,0x10, // 441 | 0x44,0x0E, // 442 | 0x45,0x24, // 443 | 0x46,0x04, // 444 | 0x47,0x50, // 445 | 0x48,0x02, // 446 | 0x49,0x13, // 447 | 0x4A,0x19, // 448 | 0x4B,0x19, // 449 | 0x4C,0x16, // 450 | 0x50,0x1B, // 451 | 0x51,0x31, // 452 | 0x52,0x2F, // 453 | 0x53,0x3F, // 454 | 0x54,0x3F, // 455 | 0x55,0x3E, // 456 | 0x56,0x2F, // 457 | 0x57,0x7B, // 458 | 0x58,0x09, // 459 | 0x59,0x06, // 460 | 0x5A,0x06, // 461 | 0x5B,0x0C, // 462 | 0x5C,0x1D, // 463 | 0x5D,0xCC, // 464 | //Power Voltage Setting 465 | 0x1B,0x1B, //VRH=4.65V 466 | 0x1A,0x01, //BT (VGH~15V,VGL~-10V,DDVDH~5V) 467 | 0x24,0x2F, //VMH(VCOM High voltage ~3.2V) 468 | 0x25,0x57, //VML(VCOM Low voltage -1.2V) 469 | //****VCOM offset**/// 470 | 0x23,0x88, //for Flicker adjust //can reload from OTP 471 | //Power on Setting 472 | 0x18,0x34, //I/P_RADJ,N/P_RADJ, Normal mode 60Hz 473 | 0x19,0x01, //OSC_EN='1', start Osc 474 | 0x01,0x00, //DP_STB='0', out deep sleep 475 | 0x1F,0x88,// GAS=1, VOMG=00, PON=0, DK=1, XDK=0, DVDH_TRI=0, STB=0 476 | TFTLCD_DELAY, 5, 477 | 0x1F,0x80,// GAS=1, VOMG=00, PON=0, DK=0, XDK=0, DVDH_TRI=0, STB=0 478 | TFTLCD_DELAY, 5, 479 | 0x1F,0x90,// GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0 480 | TFTLCD_DELAY, 5, 481 | 0x1F,0xD0,// GAS=1, VOMG=10, PON=1, DK=0, XDK=0, DDVDH_TRI=0, STB=0 482 | TFTLCD_DELAY, 5, 483 | //262k/65k color selection 484 | 0x17,0x05, //default 0x06 262k color // 0x05 65k color 485 | //SET PANEL 486 | 0x36,0x00, //SS_P, GS_P,REV_P,BGR_P 487 | //Display ON Setting 488 | 0x28,0x38, //GON=1, DTE=1, D=1000 489 | TFTLCD_DELAY, 40, 490 | 0x28,0x3F, //GON=1, DTE=1, D=1100 491 | 492 | 0x16,0x18, 493 | //Set GRAM Area 494 | 0x02,0x00, 495 | 0x03,0x00, //Column Start 496 | 0x04,0x00, 497 | 0x05,0xEF, //Column End 498 | 0x06,0x00, 499 | 0x07,0x00, //Row Start 500 | 0x08,0x01, 501 | 0x09,0x3F, //Row End 502 | }; 503 | 504 | void HX8347_kbv::begin(uint16_t ID) 505 | { 506 | _lcd_ID = ID; 507 | uint8_t cmd, d; 508 | uint8_t *p = (uint8_t *) HX8347G_2_regValues; 509 | int16_t size = sizeof(HX8347G_2_regValues); 510 | reset(); 511 | while (size > 0) { 512 | cmd = pgm_read_byte(p++); 513 | d = pgm_read_byte(p++); 514 | size -= 2; 515 | if (cmd == TFTLCD_DELAY) wait_ms(d); 516 | else WriteCmdData(cmd, d); 517 | } 518 | setRotation(0); //PORTRAIT 519 | } 520 | #endif 521 | -------------------------------------------------------------------------------- /ST7735X_kbv.cpp: -------------------------------------------------------------------------------- 1 | #include "ST7735X_kbv.h" 2 | #include "serial_kbv.h" 3 | 4 | static uint8_t done_reset; 5 | 6 | ST7735X_kbv::ST7735X_kbv(int w, int h):Adafruit_GFX(w, h) 7 | { 8 | } 9 | 10 | void ST7735X_kbv::reset(void) 11 | { 12 | INIT(); 13 | CS_IDLE; 14 | RESET_IDLE; 15 | wait_ms(50); 16 | RESET_ACTIVE; 17 | wait_ms(100); 18 | RESET_IDLE; 19 | wait_ms(100); 20 | done_reset = 1; 21 | } 22 | /* 23 | void ST7735X_kbv::WriteCmdData(uint16_t cmd, uint16_t dat) 24 | { 25 | CS_ACTIVE; 26 | WriteCmd(cmd); 27 | WriteData(dat); 28 | CS_IDLE; 29 | } 30 | */ 31 | void ST7735X_kbv::pushCommand(uint16_t cmd, uint8_t * block, int8_t N) 32 | { 33 | uint16_t color; 34 | CS_ACTIVE; 35 | WriteCmd(cmd); 36 | CD_DATA; 37 | write8_block(block, N); 38 | CS_IDLE; 39 | } 40 | 41 | static uint32_t readRegister(uint8_t reg) 42 | { 43 | uint32_t ret; 44 | uint8_t bits = 8; 45 | if (reg == 4) bits = 25; 46 | if (reg == 9) bits = 33; 47 | CS_ACTIVE; 48 | WriteCmd(reg); 49 | CD_DATA; // 50 | SDIO_INMODE(); 51 | ret = readbits(bits); 52 | CS_IDLE; 53 | SDIO_OUTMODE(); 54 | return ret; 55 | } 56 | 57 | uint16_t ST7735X_kbv::readReg(uint16_t reg) 58 | { 59 | return readRegister(reg); 60 | } 61 | 62 | uint32_t ST7735X_kbv::readReg32(uint16_t reg) 63 | { 64 | return readRegister(reg); 65 | } 66 | 67 | uint16_t ST7735X_kbv::readID(void) 68 | { 69 | if (!done_reset) reset(); 70 | return readRegister(4) >> 8; 71 | } 72 | 73 | #define ST7735X_NOP 0x00 74 | #define ST7735X_SWRESET 0x01 75 | #define ST7735X_RDDID 0x04 76 | #define ST7735X_RDDST 0x09 77 | 78 | #define ST7735X_SLPIN 0x10 79 | #define ST7735X_SLPOUT 0x11 80 | #define ST7735X_PTLON 0x12 81 | #define ST7735X_NORON 0x13 82 | 83 | #define ST7735X_INVOFF 0x20 84 | #define ST7735X_INVON 0x21 85 | #define ST7735X_DISPOFF 0x28 86 | #define ST7735X_DISPON 0x29 87 | #define ST7735X_CASET 0x2A 88 | #define ST7735X_RASET 0x2B 89 | #define ST7735X_RAMWR 0x2C 90 | #define ST7735X_RAMRD 0x2E 91 | 92 | #define ST7735X_PTLAR 0x30 93 | #define ST7735X_COLMOD 0x3A 94 | #define ST7735X_MADCTL 0x36 95 | 96 | #define ST7735X_FRMCTR1 0xB1 97 | #define ST7735X_FRMCTR2 0xB2 98 | #define ST7735X_FRMCTR3 0xB3 99 | #define ST7735X_INVCTR 0xB4 100 | #define ST7735X_DISSET5 0xB6 101 | 102 | #define ST7735X_PWCTR1 0xC0 103 | #define ST7735X_PWCTR2 0xC1 104 | #define ST7735X_PWCTR3 0xC2 105 | #define ST7735X_PWCTR4 0xC3 106 | #define ST7735X_PWCTR5 0xC4 107 | #define ST7735X_VMCTR1 0xC5 108 | 109 | #define ST7735X_RDID1 0xDA 110 | #define ST7735X_RDID2 0xDB 111 | #define ST7735X_RDID3 0xDC 112 | #define ST7735X_RDID4 0xDD 113 | 114 | #define ST7735X_PWCTR6 0xFC 115 | 116 | #define ST7735X_GMCTRP1 0xE0 117 | #define ST7735X_GMCTRN1 0xE1 118 | 119 | #define ILI9163_NOP 0x00 120 | #define ILI9163_SWRESET 0x01 121 | #define ILI9163_RDDID 0x04 122 | #define ILI9163_RDDST 0x09 123 | 124 | #define ILI9163_SLPIN 0x10 125 | #define ILI9163_SLPOUT 0x11 126 | #define ILI9163_PTLON 0x12 127 | #define ILI9163_NORON 0x13 128 | 129 | #define ILI9163_INVOFF 0x20 130 | #define CMD_GAMMASET 0x26//Gamma Set (0x01[1],0x02[2],0x04[3],0x08[4]) 131 | #define ILI9163_INVON 0x21 132 | #define ILI9163_DISPOFF 0x28 133 | #define ILI9163_DISPON 0x29 134 | #define ILI9163_CASET 0x2A 135 | #define ILI9163_RASET 0x2B 136 | #define ILI9163_RAMWR 0x2C 137 | #define ILI9163_RAMRD 0x2E 138 | 139 | #define ILI9163_PTLAR 0x30 140 | #define CMD_VSCLLDEF 0x33//Vertical Scroll Definition 141 | #define ILI9163_COLMOD 0x3A 142 | #define ILI9163_MADCTL 0x36 143 | #define CMD_VSSTADRS 0x37//Vertical Scrolling Start address 144 | 145 | #define ILI9163_FRMCTR1 0xB1 146 | #define ILI9163_FRMCTR2 0xB2 147 | #define ILI9163_FRMCTR3 0xB3 148 | #define ILI9163_INVCTR 0xB4 149 | #define CMD_DFUNCTR 0xB6//Display Fuction set 5 150 | #define CMD_SDRVDIR 0xB7//Source Driver Direction Control 151 | #define CMD_GDRVDIR 0xB8//Gate Driver Direction Control 152 | 153 | #define ILI9163_PWCTR1 0xC0 154 | #define ILI9163_PWCTR2 0xC1 155 | #define ILI9163_PWCTR3 0xC2 156 | #define ILI9163_PWCTR4 0xC3 157 | #define ILI9163_PWCTR5 0xC4 158 | #define ILI9163_VMCTR1 0xC5 159 | #define CMD_VCOMCTR2 0xC6//VCOM_Control 2 160 | #define CMD_VCOMOFFS 0xC7//VCOM Offset Control 161 | 162 | #define ILI9163_RDID1 0xDA 163 | #define ILI9163_RDID2 0xDB 164 | #define ILI9163_RDID3 0xDC 165 | #define ILI9163_RDID4 0xDD 166 | 167 | //#define ILI9163_PWCTR6 0xFC 168 | 169 | #define ILI9163_GMCTRP1 0xE0 170 | #define ILI9163_GMCTRN1 0xE1 171 | #define CMD_GAMRSEL 0xF2//GAM_R_SEL 172 | 173 | int16_t ST7735X_kbv::readGRAM(int16_t x, int16_t y, uint16_t * block, int16_t w, int16_t h) 174 | { 175 | uint8_t r, g, b; 176 | int16_t n = w * h; // we are NEVER going to read > 32k pixels at once 177 | uint8_t colmod = 0x66; 178 | pushCommand(ST7735X_COLMOD, &colmod, 1); 179 | setAddrWindow(x, y, x + w - 1, y + h - 1); 180 | CS_ACTIVE; 181 | WriteCmd(ST7735X_RAMRD); 182 | CD_DATA; 183 | SDIO_INMODE(); // do this while CS is Active 184 | 185 | r = readbits(8 + _is7735); //(8) for ILI9163, (9) for ST7735 186 | while (n-- > 0) { 187 | r = readbits(8); 188 | g = readbits(8); 189 | b = readbits(8); 190 | *block++ = color565(r, g, b); 191 | } 192 | CS_IDLE; 193 | SDIO_OUTMODE(); //do this when CS is Idle 194 | setAddrWindow(0, 0, width() - 1, height() - 1); 195 | colmod = 0x05; 196 | pushCommand(ST7735X_COLMOD, &colmod, 1); 197 | return 0; 198 | } 199 | 200 | void ST7735X_kbv::setRotation(uint8_t r) 201 | { 202 | uint8_t mac = 0x00; 203 | Adafruit_GFX::setRotation(r & 3); 204 | switch (rotation) { 205 | case 0: 206 | mac = 0xD8; 207 | break; 208 | case 1: //LANDSCAPE 90 degrees 209 | mac = 0x68; 210 | break; 211 | case 2: 212 | mac = 0x08; 213 | break; 214 | case 3: 215 | mac = 0xB8; 216 | break; 217 | } 218 | mac ^= (_lcd_xor); 219 | pushCommand(ST7735X_MADCTL, &mac, 1); 220 | } 221 | 222 | void ST7735X_kbv::drawPixel(int16_t x, int16_t y, uint16_t color) 223 | { 224 | // ILI934X just plots at edge if you try to write outside of the box: 225 | if (x < 0 || y < 0 || x >= width() || y >= height()) 226 | return; 227 | if (rotation == 0) y += __OFFSET; 228 | if (rotation == 3) x += __OFFSET; 229 | spibuf[0] = x >> 8; 230 | spibuf[1] = x; 231 | pushCommand(ST7735X_CASET, spibuf, 2); 232 | spibuf[0] = y >> 8; 233 | spibuf[1] = y; 234 | pushCommand(ST7735X_RASET, spibuf, 2); 235 | spibuf[0] = color >> 8; 236 | spibuf[1] = color; 237 | pushCommand(ST7735X_RAMWR, spibuf, 2); 238 | } 239 | 240 | void ST7735X_kbv::setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1) 241 | { 242 | if (rotation == 0) y += __OFFSET, y1 += __OFFSET; 243 | if (rotation == 3) x += __OFFSET, x1 += __OFFSET; 244 | spibuf[0] = x >> 8; 245 | spibuf[1] = x; 246 | spibuf[2] = x1 >> 8; 247 | spibuf[3] = x1; 248 | pushCommand(ST7735X_CASET, spibuf, 4); 249 | spibuf[0] = y >> 8; 250 | spibuf[1] = y; 251 | spibuf[2] = y1 >> 8; 252 | spibuf[3] = y1; 253 | pushCommand(ST7735X_RASET, spibuf, 4); 254 | } 255 | 256 | void ST7735X_kbv::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 257 | { 258 | int16_t end; 259 | if (w < 0) { 260 | w = -w; 261 | x -= w; 262 | } //+ve w 263 | end = x + w; 264 | if (x < 0) 265 | x = 0; 266 | if (end > width()) 267 | end = width(); 268 | w = end - x; 269 | if (h < 0) { 270 | h = -h; 271 | y -= h; 272 | } //+ve h 273 | end = y + h; 274 | if (y < 0) 275 | y = 0; 276 | if (end > height()) 277 | end = height(); 278 | h = end - y; 279 | setAddrWindow(x, y, x + w - 1, y + h - 1); 280 | CS_ACTIVE; 281 | WriteCmd(ST7735X_RAMWR); 282 | CD_DATA; 283 | if (h > w) { 284 | end = h; 285 | h = w; 286 | w = end; 287 | } 288 | while (h-- > 0) { 289 | write16_N(color, w); 290 | } 291 | CS_IDLE; 292 | setAddrWindow(0, 0, width() - 1, height() - 1); 293 | } 294 | 295 | void ST7735X_kbv::pushColors(uint16_t * block, int16_t n, bool first) 296 | { 297 | uint16_t color; 298 | CS_ACTIVE; 299 | if (first) { 300 | WriteCmd(ST7735X_RAMWR); 301 | } 302 | CD_DATA; 303 | while (n-- > 0) { 304 | color = *block++; 305 | write16(color); 306 | } 307 | CS_IDLE; 308 | } 309 | 310 | void ST7735X_kbv::pushColors(uint8_t * block, int16_t n, bool first) 311 | { 312 | uint16_t color; 313 | uint8_t h, l; 314 | CS_ACTIVE; 315 | if (first) { 316 | WriteCmd(ST7735X_RAMWR); 317 | } 318 | CD_DATA; 319 | while (n-- > 0) { 320 | h = (*block++); 321 | l = (*block++); 322 | color = (h << 8) | l; 323 | write16(color); 324 | } 325 | CS_IDLE; 326 | } 327 | 328 | void ST7735X_kbv::pushColors(const uint8_t * block, int16_t n, bool first, bool bigend) 329 | { 330 | uint16_t color; 331 | uint8_t h, l; 332 | CS_ACTIVE; 333 | if (first) { 334 | WriteCmd(ST7735X_RAMWR); 335 | } 336 | CD_DATA; 337 | while (n-- > 0) { 338 | l = pgm_read_byte(block++); 339 | h = pgm_read_byte(block++); 340 | color = (bigend) ? (l << 8 ) | h : (h << 8) | l; 341 | write16(color); 342 | } 343 | CS_IDLE; 344 | } 345 | 346 | void ST7735X_kbv::invertDisplay(boolean i) 347 | { 348 | pushCommand(i ? ST7735X_INVON : ST7735X_INVOFF, NULL, 0); 349 | } 350 | 351 | void ST7735X_kbv::vertScroll(int16_t top, int16_t scrollines, int16_t offset) 352 | { 353 | if (rotation == 0 || rotation == 3) top += __OFFSET; 354 | int16_t bfa = HEIGHT + __OFFSET - top - scrollines; // bottom fixed area 355 | int16_t vsp; 356 | vsp = top + offset; // vertical start position 357 | if (offset < 0) 358 | vsp += scrollines; //keep in unsigned range 359 | spibuf[0] = top>>8; 360 | spibuf[1] = top; 361 | spibuf[2] = scrollines>>8; 362 | spibuf[3] = scrollines; 363 | spibuf[4] = bfa>>8; 364 | spibuf[5] = bfa; 365 | pushCommand(0x33, spibuf, 6); 366 | spibuf[0] = vsp>>8; 367 | spibuf[1] = vsp; 368 | pushCommand(0x37, spibuf, 2); 369 | } 370 | 371 | #define TFTLCD_DELAY 0xFF 372 | 373 | const uint8_t PROGMEM table7735S[] = { 374 | // (COMMAND_BYTE), n, data_bytes.... 375 | (ST7735X_SWRESET), 0, // software reset 376 | TFTLCD_DELAY, 50, 377 | (ST7735X_SLPOUT), 0, //Sleep exit 378 | TFTLCD_DELAY, 250, 379 | //ST7735XR Frame Rate 380 | (ST7735X_FRMCTR1), 3, 0x01, 0x2C, 0x2D, 381 | (ST7735X_FRMCTR2), 3, 0x01, 0x2C, 0x2D, 382 | (ST7735X_FRMCTR3), 6, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, 383 | (ST7735X_INVCTR), 1, 0x07, //Column inversion 384 | //ST7735XR Power Sequence 385 | (ST7735X_PWCTR1), 3, 0xA2, 0x02, 0x84, 386 | (ST7735X_PWCTR2), 1, 0xC5, 387 | (ST7735X_PWCTR3), 2, 0x0A, 0x00, 388 | (ST7735X_PWCTR4), 2, 0x8A, 0x2A, 389 | (ST7735X_PWCTR5), 2, 0x8A, 0xEE, 390 | (ST7735X_VMCTR1), 1, 0x0E, //VCOM 391 | (ST7735X_INVOFF), 0, //no inversion 392 | //(ST7735X_MADCTL), 1, 0xC8, //MX, MY, RGB mode 393 | (ST7735X_MADCTL), 1, 0x00, //MX, MY, RGB mode 394 | //ST7735XR Gamma Sequence 395 | (ST7735X_GMCTRP1), 16, 396 | 0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f, 0x1b, 0x23, 0x37, 397 | 0x00, 0x07, 0x02, 0x10, 398 | (ST7735X_GMCTRN1), 16, 399 | 0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, 0x30, 0x30, 0x39, 0x3f, 400 | 0x00, 0x07, 0x03, 0x10, 401 | 402 | (ST7735X_CASET), 4, 0x00, 0x00, 0x00, 0x7f, 403 | (ST7735X_RASET), 4, 0x00, 0x00, 0x00, 0x9f, 404 | (0xF0), 1, 0x00, //Enable test command [01] 405 | (0xF6), 1, 0x00, //Disable ram power save mode 406 | 407 | (ST7735X_COLMOD), 1, 0x65, //65k mode 408 | (ST7735X_DISPON), 0, //Display on 409 | }; 410 | 411 | const uint8_t PROGMEM table9101[] = { 412 | // (COMMAND_BYTE), n, data_bytes.... 413 | (ST7735X_SWRESET), 0, // software reset 414 | TFTLCD_DELAY, 50, 415 | (ST7735X_SLPOUT), 0, //Sleep exit 416 | TFTLCD_DELAY, 250, 417 | /* 418 | //ST7735XR Frame Rate 419 | (ST7735X_FRMCTR1), 3, 0x01, 0x2C, 0x2D, 420 | (ST7735X_FRMCTR2), 3, 0x01, 0x2C, 0x2D, 421 | (ST7735X_FRMCTR3), 6, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, 422 | (ST7735X_INVCTR), 1, 0x07, //Column inversion 423 | //ST7735XR Power Sequence 424 | (ST7735X_PWCTR1), 3, 0xA2, 0x02, 0x84, 425 | (ST7735X_PWCTR2), 1, 0xC5, 426 | (ST7735X_PWCTR3), 2, 0x0A, 0x00, 427 | (ST7735X_PWCTR4), 2, 0x8A, 0x2A, 428 | (ST7735X_PWCTR5), 2, 0x8A, 0xEE, 429 | (ST7735X_VMCTR1), 1, 0x0E, //VCOM 430 | (ST7735X_INVOFF), 0, //no inversion 431 | //(ST7735X_MADCTL), 1, 0xC8, //MX, MY, RGB mode 432 | (ST7735X_MADCTL), 1, 0x00, //MX, MY, RGB mode 433 | //ST7735XR Gamma Sequence 434 | (ST7735X_GMCTRP1), 16, 435 | 0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f, 0x1b, 0x23, 0x37, 436 | 0x00, 0x07, 0x02, 0x10, 437 | (ST7735X_GMCTRN1), 16, 438 | 0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, 0x30, 0x30, 0x39, 0x3f, 439 | 0x00, 0x07, 0x03, 0x10, 440 | 441 | (ST7735X_CASET), 4, 0x00, 0x00, 0x00, 0x7f, 442 | (ST7735X_RASET), 4, 0x00, 0x00, 0x00, 0x9f, 443 | */ 444 | // (0xB0), 2, 0x00, 0xF0, //RAMCTRL (B0h): RAM Control on ST7789V 445 | // (0xF6), 1, 0x01, 0x00, 0x00, //Interface Control (F6h) on ILI9341 446 | (ST7735X_COLMOD), 1, 0x05, //65k mode 447 | (ST7735X_DISPON), 0, //Display on 448 | }; 449 | 450 | const uint8_t PROGMEM table9163C[] = { 451 | // (COMMAND_BYTE), n, data_bytes.... 452 | (ILI9163_SWRESET), 0, // software reset 453 | TFTLCD_DELAY, 250, 454 | TFTLCD_DELAY, 250, 455 | (ILI9163_SLPOUT), 0, //Sleep exit 456 | TFTLCD_DELAY, 5, 457 | (ILI9163_COLMOD), 1, 0x05, //65k mode 458 | TFTLCD_DELAY, 5, 459 | (CMD_GAMMASET), 1, 0x04, 460 | TFTLCD_DELAY, 1, 461 | (CMD_GAMRSEL), 1, 0x01, 462 | TFTLCD_DELAY, 1, 463 | (ILI9163_NORON), 0, //Normal 464 | // (CMD_DFUNCTR), 2, 0xFF, 0x06, //Display Function set 5 ??NL 465 | //#if __OFFSET == 0 466 | // (CMD_SDRVDIR), 1, 0x01, 467 | // (CMD_GDRVDIR), 1, 0x01, 468 | //#else 469 | // (CMD_SDRVDIR), 1, 0x00, 470 | // (CMD_GDRVDIR), 1, 0x00, 471 | //#endif 472 | (ILI9163_GMCTRP1), 16, 473 | 0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, 0x1f, 0x1b, 0x23, 0x37, 474 | 0x00, 0x07, 0x02, 0x10, 475 | (ILI9163_GMCTRN1), 16, 476 | 0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, 0x30, 0x30, 0x39, 0x3f, 477 | 0x00, 0x07, 0x03, 0x10, 478 | (ILI9163_FRMCTR1), 2, 0x08, 0x02, 479 | (ILI9163_INVCTR), 1, 0x07, //Column inversion 480 | TFTLCD_DELAY, 1, 481 | (ILI9163_PWCTR1), 2, 0x0A, 0x02, 482 | TFTLCD_DELAY, 1, 483 | (ILI9163_PWCTR2), 1, 0x02, 484 | TFTLCD_DELAY, 1, 485 | (ILI9163_VMCTR1), 2, 0x50, 0x63, //VCOM (#99) 486 | TFTLCD_DELAY, 1, 487 | (CMD_VCOMOFFS), 1, 0, 488 | TFTLCD_DELAY, 1, 489 | // (CMD_VSCLLDEF), 6, 0, __OFFSET, 0, 128 + __OFFSET, 0, 0, 490 | (CMD_VSCLLDEF), 6, 0, 0, 0, 128 + 0, 0, 0, 491 | (ILI9163_MADCTL), 1, 0x00, //MX, MY, RGB mode 492 | (ILI9163_PTLAR), 4, 0x00, 0x00, 0x00, 0x7f, 493 | (ILI9163_CASET), 4, 0x00, 0x00, 0x00, 0x7f, 494 | (ILI9163_RASET), 4, 0x00, 0x00, 0x00, 0x7f, 495 | // (0xF0), 1, 0x01, //Enable test command 496 | // (0xF6), 1, 0x00, //Disable ram power save mode 497 | (ILI9163_DISPON), 0, //Display on 498 | }; 499 | 500 | void ST7735X_kbv::begin(uint16_t ID) 501 | { 502 | _lcd_ID = ID; 503 | _lcd_xor = 0x00; 504 | uint8_t *p = (uint8_t *) table7735S; 505 | int16_t size = sizeof(table7735S); 506 | reset(); 507 | switch(ID) { 508 | case 0x0091: //wot readID() 509 | case 0x9101: 510 | __OFFSET = 32; 511 | _lcd_xor = 0x00; 512 | p = (uint8_t *) table9101; 513 | size = sizeof(table9101); 514 | break; 515 | case 0x5480: //wot readID() 516 | case 0x9162: 517 | __OFFSET = 32; 518 | _lcd_xor = 0xD0; 519 | goto common_9163; 520 | case 0x9163: 521 | _lcd_xor = 0x00; 522 | common_9163: 523 | p = (uint8_t *) table9163C; 524 | size = sizeof(table9163C); 525 | break; 526 | case 0x7734: 527 | __OFFSET = 32; 528 | _lcd_xor = 0x00; 529 | goto common_7735; 530 | case 0x7C89: 531 | case 0x7735: 532 | default: 533 | _lcd_xor = 0x08; 534 | common_7735: 535 | _is7735 = 1; 536 | p = (uint8_t *) table7735S; 537 | size = sizeof(table7735S); 538 | break; 539 | } 540 | while (size > 0) { 541 | uint8_t cmd = pgm_read_byte(p++); 542 | uint8_t len = pgm_read_byte(p++); 543 | if (cmd == TFTLCD_DELAY) { 544 | delay(len); 545 | len = 0; 546 | } else { 547 | CS_ACTIVE; 548 | WriteCmd(cmd); 549 | CD_DATA; 550 | for (uint8_t d = 0; d < len; d++) { 551 | uint8_t x = pgm_read_byte(p++); 552 | xchg8(x); 553 | } 554 | CS_IDLE; 555 | } 556 | size -= len + 2; 557 | } 558 | setRotation(0); //PORTRAIT 559 | } 560 | -------------------------------------------------------------------------------- /pin_shield_1.h: -------------------------------------------------------------------------------- 1 | #ifndef PIN_SHIELD_1_H_ 2 | #define PIN_SHIELD_1_H_ 3 | 4 | // just provide macros for the Arduino pins 5 | // i.e. PIN_LOW(), PIN_HIGH(), PIN_OUTPUT(), PIN_INPUT(), PIN_READ() 6 | 7 | #define LPC810 810 8 | #define LPC812 812 9 | #define LPC1343 1343 10 | #define LPC1768 1768 11 | #define LPC2103 2103 12 | #define LPC2148 2148 13 | #warning Using pin_SHIELD_1.h 14 | 15 | #if 0 16 | 17 | #elif defined(NUCLEO) || defined(TARGET_NUCLEO_F072RB) || defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F103RB) 18 | #define PIN_MODE2(reg, pin, mode) reg=(reg&~(0x3<<((pin)<<1)))|(mode<<((pin)<<1)) 19 | #if __MBED__ 20 | #warning MBED knows everything 21 | #elif defined(STM32F072xB) 22 | #include 23 | #elif defined(STM32F103xB) 24 | #if defined(__CC_ARM) 25 | #include 26 | #else 27 | #include 28 | #endif 29 | #elif defined(STM32L476xx) 30 | #include 31 | #elif defined(STM32F401xE) || defined(STM32F411xE) 32 | #include 33 | #endif 34 | #define D0_PORT GPIOA 35 | #define D0_PIN 3 36 | #define D1_PORT GPIOA 37 | #define D1_PIN 2 38 | #define D2_PORT GPIOA 39 | #define D2_PIN 10 40 | #define D3_PORT GPIOB 41 | #define D3_PIN 3 42 | #define D4_PORT GPIOB 43 | #define D4_PIN 5 44 | #define D5_PORT GPIOB 45 | #define D5_PIN 4 46 | #define D6_PORT GPIOB 47 | #define D6_PIN 10 48 | #define D7_PORT GPIOA 49 | #define D7_PIN 8 50 | #define D8_PORT GPIOA 51 | #define D8_PIN 9 52 | #define D9_PORT GPIOC 53 | #define D9_PIN 7 54 | #define D10_PORT GPIOB 55 | #define D10_PIN 6 56 | #define D11_PORT GPIOA 57 | #define D11_PIN 7 58 | #define D12_PORT GPIOA 59 | #define D12_PIN 6 60 | #define D13_PORT GPIOA 61 | #define D13_PIN 5 62 | #define A0_PORT GPIOA 63 | #define A0_PIN 0 64 | #define A1_PORT GPIOA 65 | #define A1_PIN 1 66 | #define A2_PORT GPIOA 67 | #define A2_PIN 4 68 | #define A3_PORT GPIOB 69 | #define A3_PIN 0 70 | #define A4_PORT GPIOC 71 | #define A4_PIN 1 72 | #define A5_PORT GPIOC 73 | #define A5_PIN 0 74 | // Shield Control macros 75 | #define PIN_LOW(port, pin) (port)->BSRR = (1<<((pin)+16)) 76 | #define PIN_HIGH(port, pin) (port)->BSRR = (1<<(pin)) 77 | //#define PIN_LOW(port, pin) (port)->ODR &= ~(1<<(pin)) 78 | //#define PIN_HIGH(port, pin) (port)->ODR |= (1<<(pin)) 79 | #define PIN_READ(port, pin) (port)->IDR & (1<<(pin)) 80 | #if defined(STM32F103xB) 81 | #warning STM32F103xB ****************************** 82 | #define PIN_MODE4(reg, pin, mode) reg=(reg&~(0xF<<((pin)<<2)))|(mode<<((pin)<<2)) 83 | #define PIN_OUTPUT(port, pin) PIN_MODE4((port)->CRL, pin, 0x3) //50MHz push-pull only 0-7 84 | #define PIN_INPUT(port, pin) PIN_MODE4((port)->CRL, pin, 0x4) //digital input 85 | #else 86 | #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1) 87 | #define PIN_INPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x0) //.kbv check this 88 | #endif 89 | 90 | #elif __TARGET_PROCESSOR == LPC1768 91 | #include 92 | // configure macros for the control pins 93 | #define D0_PORT LPC_GPIO0 94 | #define D0_PIN 3 95 | #define D1_PORT LPC_GPIO0 96 | #define D1_PIN 2 97 | #define D2_PORT LPC_GPIO0 98 | #define D2_PIN 24 //p16 99 | #define D3_PORT LPC_GPIO0 100 | #define D3_PIN 23 //p15 101 | #define D4_PORT LPC_GPIO0 102 | #define D4_PIN 16 //p14 103 | #define D5_PORT LPC_GPIO0 104 | #define D5_PIN 15 //p13 105 | #define D6_PORT LPC_GPIO0 106 | #define D6_PIN 17 //p12 107 | #define D7_PORT LPC_GPIO0 108 | #define D7_PIN 18 //p11 109 | #define D8_PORT LPC_GPIO0 110 | #define D8_PIN 1 //p10 111 | #define D9_PORT LPC_GPIO0 112 | #define D9_PIN 0 //p9 113 | #define D10_PORT LPC_GPIO0 114 | #define D10_PIN 6 //p8 115 | #define D11_PORT LPC_GPIO0 116 | #define D11_PIN 9 //p5 117 | #define D12_PORT LPC_GPIO0 118 | #define D12_PIN 8 //p6 miso 119 | #define D13_PORT LPC_GPIO0 120 | #define D13_PIN 7 //p7 121 | #define A0_PORT LPC_GPIO0 122 | #define A0_PIN 25 //p17 123 | #define A1_PORT LPC_GPIO0 124 | #define A1_PIN 26 //p18 125 | #define A2_PORT LPC_GPIO1 126 | #define A2_PIN 30 //p19 127 | #define A3_PORT LPC_GPIO1 128 | #define A3_PIN 31 //p20 129 | #define A4_PORT LPC_GPIO0 130 | #define A4_PIN 10 //p28 131 | #define A5_PORT LPC_GP100 132 | #define A5_PIN 11 //p27 133 | // Shield Control macros 134 | #define PIN_LOW(port, pin) (port)->FIOCLR = (1u<<(pin)) 135 | #define PIN_HIGH(port, pin) (port)->FIOSET = (1u<<(pin)) 136 | #define PIN_OUTPUT(port, pin) (port)->FIODIR |= (1u<<(pin)) 137 | #define PIN_INPUT(port, pin) (port)->FIODIR &= ~(1u<<(pin)) 138 | #define PIN_READ(port, pin) (port)->FIOPIN & (1u<<(pin)) 139 | 140 | #elif defined(MK20D7) && defined(TEENSY) 141 | #include 142 | #define D0_PORT PTB 143 | #define D0_PIN 16 144 | #define D1_PORT PTB 145 | #define D1_PIN 17 146 | #define D2_PORT PTD 147 | #define D2_PIN 0 148 | #define D3_PORT PTA 149 | #define D3_PIN 12 150 | #define D4_PORT PTA 151 | #define D4_PIN 13 152 | #define D5_PORT PTD 153 | #define D5_PIN 7 154 | #define D6_PORT PTD 155 | #define D6_PIN 4 156 | #define D7_PORT PTD 157 | #define D7_PIN 2 158 | #define D8_PORT PTD 159 | #define D8_PIN 3 160 | #define D9_PORT PTC 161 | #define D9_PIN 3 162 | #define D10_PORT PTC 163 | #define D10_PIN 4 164 | #define D11_PORT PTC 165 | #define D11_PIN 6 166 | #define D12_PORT PTC 167 | #define D12_PIN 7 168 | #define D13_PORT PTC 169 | #define D13_PIN 5 170 | #define A0_PORT PTD 171 | #define A0_PIN 1 172 | #define A1_PORT PTC 173 | #define A1_PIN 0 174 | #define A2_PORT PTB 175 | #define A2_PIN 0 176 | #define A3_PORT PTB 177 | #define A3_PIN 1 178 | #define A4_PORT PTB 179 | #define A4_PIN 3 180 | #define A5_PORT PTB 181 | #define A5_PIN 2 182 | // Shield Control macros. Deliberately avoid the IOSET registers 183 | #define PIN_LOW(port, pin) (port)->PCOR = (1<<(pin)) 184 | #define PIN_HIGH(port, pin) (port)->PSOR = (1<<(pin)) 185 | //#define PIN_LOW(port, pin) (port)->PDOR &= ~(1<<(pin)) 186 | //#define PIN_HIGH(port, pin) (port)->PDOR |= (1<<(pin)) 187 | #define PIN_OUTPUT(port, pin) (port)->PDDR |= (1<<(pin)) 188 | #define PIN_INPUT(port, pin) (port)->PDDR &= ~(1u<<(pin)) 189 | #define PIN_READ(port, pin) (port)->PDIR & (1u<<(pin)) 190 | 191 | 192 | #elif defined(MKL25Z4) || defined(TARGET_KL25Z) 193 | #include 194 | #define D0_PORT PTA 195 | #define D0_PIN 1 196 | #define D1_PORT PTA 197 | #define D1_PIN 2 198 | #define D2_PORT PTD 199 | #define D2_PIN 4 200 | #define D3_PORT PTA 201 | #define D3_PIN 12 202 | #define D4_PORT PTA 203 | #define D4_PIN 4 204 | #define D5_PORT PTA 205 | #define D5_PIN 5 206 | #define D6_PORT PTC 207 | #define D6_PIN 8 208 | #define D7_PORT PTC 209 | #define D7_PIN 9 210 | #define D8_PORT PTA 211 | #define D8_PIN 13 212 | #define D9_PORT PTD 213 | #define D9_PIN 5 214 | #define D10_PORT PTD 215 | #define D10_PIN 0 216 | #define D11_PORT PTD 217 | #define D11_PIN 2 218 | #define D12_PORT PTD 219 | #define D12_PIN 3 220 | #define D13_PORT PTD 221 | #define D13_PIN 1 222 | #define A0_PORT PTB 223 | #define A0_PIN 0 224 | #define A1_PORT PTB 225 | #define A1_PIN 1 226 | #define A2_PORT PTB 227 | #define A2_PIN 2 228 | #define A3_PORT PTB 229 | #define A3_PIN 3 230 | #define A4_PORT PTC 231 | #define A4_PIN 2 232 | #define A5_PORT PTC 233 | #define A5_PIN 1 234 | // Shield Control macros. Deliberately avoid the IOSET registers 235 | #define PIN_LOW(port, pin) (port)->PCOR = (1<<(pin)) 236 | #define PIN_HIGH(port, pin) (port)->PSOR = (1<<(pin)) 237 | //#define PIN_LOW(port, pin) (port)->PDOR &= ~(1<<(pin)) 238 | //#define PIN_HIGH(port, pin) (port)->PDOR |= (1<<(pin)) 239 | #define PIN_OUTPUT(port, pin) (port)->PDDR |= (1<<(pin)) 240 | #define PIN_INPUT(port, pin) (port)->PDDR &= ~(1u<<(pin)) 241 | #define PIN_READ(port, pin) (port)->PDIR & (1u<<(pin)) 242 | 243 | #elif defined(MKL05Z4) 244 | #include 245 | #define D0_PORT PTB 246 | #define D0_PIN 2 247 | #define D1_PORT PTB 248 | #define D1_PIN 1 249 | #define D2_PORT PTA 250 | #define D2_PIN 11 251 | #define D3_PORT PTB 252 | #define D3_PIN 5 253 | #define D4_PORT PTA 254 | #define D4_PIN 10 255 | #define D5_PORT PTA 256 | #define D5_PIN 12 257 | #define D6_PORT PTB 258 | #define D6_PIN 6 259 | #define D7_PORT PTB 260 | #define D7_PIN 7 261 | #define D8_PORT PTB 262 | #define D8_PIN 13 263 | #define D9_PORT PTB 264 | #define D9_PIN 5 265 | #define D10_PORT PTA 266 | #define D10_PIN 0 267 | #define D11_PORT PTA 268 | #define D11_PIN 2 269 | #define D12_PORT PTA 270 | #define D12_PIN 3 271 | #define D13_PORT PTB 272 | #define D13_PIN 1 273 | #define A0_PORT PTB 274 | #define A0_PIN 8 275 | #define A1_PORT PTB 276 | #define A1_PIN 9 277 | #define A2_PORT PTA 278 | #define A2_PIN 8 279 | #define A3_PORT PTA 280 | #define A3_PIN 0 281 | #define A4_PORT PTA 282 | #define A4_PIN 9 283 | #define A5_PORT PTB 284 | #define A5_PIN 13 285 | // Shield Control macros 286 | //#define PIN_LOW(port, pin) (port)->PCOR = (1<<(pin)) 287 | //#define PIN_HIGH(port, pin) (port)->PSOR = (1<<(pin)) 288 | #define PIN_LOW(port, pin) (port)->PDOR &= ~(1<<(pin)) 289 | #define PIN_HIGH(port, pin) (port)->PDOR |= (1<<(pin)) 290 | #define PIN_OUTPUT(port, pin) (port)->PDDR |= (1<<(pin)) 291 | #define PIN_INPUT(port, pin) (port)->PDDR &= ~(1u<<(pin)) 292 | #define PIN_READ(port, pin) (port)->PDIR & (1u<<(pin)) 293 | 294 | #elif defined(MK20D5) || defined(TARGET_K20D50M) 295 | #include 296 | #define D0_PORT PTE 297 | #define D0_PIN 1 298 | #define D1_PORT PTE 299 | #define D1_PIN 0 300 | #define D2_PORT PTA 301 | #define D2_PIN 5 302 | #define D3_PORT PTD 303 | #define D3_PIN 4 304 | #define D4_PORT PTC 305 | #define D4_PIN 8 306 | #define D5_PORT PTA 307 | #define D5_PIN 1 308 | #define D6_PORT PTC 309 | #define D6_PIN 3 310 | #define D7_PORT PTC 311 | #define D7_PIN 4 312 | #define D8_PORT PTA 313 | #define D8_PIN 13 314 | #define D9_PORT PTA 315 | #define D9_PIN 5 316 | #define D10_PORT PTC 317 | #define D10_PIN 0 318 | #define D11_PORT PTD 319 | #define D11_PIN 2 320 | #define D12_PORT PTD 321 | #define D12_PIN 3 322 | #define D13_PORT PTD 323 | #define D13_PIN 1 324 | #define A0_PORT PTC 325 | #define A0_PIN 0 326 | #define A1_PORT PTC 327 | #define A1_PIN 1 328 | #define A2_PORT PTD 329 | #define A2_PIN 6 330 | #define A3_PORT PTD 331 | #define A3_PIN 5 332 | #define A4_PORT PTB 333 | #define A4_PIN 1 334 | #define A5_PORT PTB 335 | #define A5_PIN 0 336 | // Shield Control macros. Deliberately avoid the IOSET registers 337 | #define PIN_LOW(port, pin) (port)->PCOR = (1<<(pin)) 338 | #define PIN_HIGH(port, pin) (port)->PSOR = (1<<(pin)) 339 | //#define PIN_LOW(port, pin) (port)->PDOR &= ~(1<<(pin)) 340 | //#define PIN_HIGH(port, pin) (port)->PDOR |= (1<<(pin)) 341 | #define PIN_OUTPUT(port, pin) (port)->PDDR |= (1<<(pin)) 342 | #define PIN_INPUT(port, pin) (port)->PDDR &= ~(1u<<(pin)) 343 | #define PIN_READ(port, pin) (port)->PDIR & (1u<<(pin)) 344 | 345 | 346 | #elif defined(ZERO) 347 | #include 348 | // configure macros for the data pins 349 | #if defined(D21_XPRO) 350 | #define D0_PORT PORT->Group[1] 351 | #define D0_PIN 9 352 | #define D1_PORT PORT->Group[1] 353 | #define D1_PIN 8 354 | #define D2_PORT PORT->Group[1] 355 | #define D2_PIN 14 356 | #define D3_PORT PORT->Group[1] 357 | #define D3_PIN 2 358 | #define D4_PORT PORT->Group[1] 359 | #define D4_PIN 5 360 | #define D5_PORT PORT->Group[0] 361 | #define D5_PIN 21 362 | #define D6_PORT PORT->Group[1] 363 | #define D6_PIN 15 364 | #define D7_PORT PORT->Group[0] 365 | #define D7_PIN 17 366 | #define D8_PORT PORT->Group[1] 367 | #define D8_PIN 6 368 | #define D9_PORT PORT->Group[1] 369 | #define D9_PIN 7 370 | #define D10_PORT PORT->Group[0] 371 | #define D10_PIN 5 372 | #define D11_PORT PORT->Group[0] 373 | #define D11_PIN 6 374 | #define D12_PORT PORT->Group[0] 375 | #define D12_PIN 4 376 | #define D13_PORT PORT->Group[0] 377 | #define D13_PIN 7 378 | #define A0_PORT PORT->Group[1] 379 | #define A0_PIN 0 380 | #define A1_PORT PORT->Group[1] 381 | #define A1_PIN 1 382 | #define A2_PORT PORT->Group[0] 383 | #define A2_PIN 10 384 | #define A3_PORT PORT->Group[0] 385 | #define A3_PIN 11 386 | #define A4_PORT PORT->Group[0] 387 | #define A4_PIN 8 388 | #define A5_PORT PORT->Group[0] 389 | #define A5_PIN 9 390 | #elif defined(M0_PRO) 391 | #define D0_PORT PORT->Group[0] 392 | #define D0_PIN 11 393 | #define D1_PORT PORT->Group[0] 394 | #define D1_PIN 10 395 | #define D2_PORT PORT->Group[0] 396 | #define D2_PIN 8 397 | #define D3_PORT PORT->Group[0] 398 | #define D3_PIN 9 399 | #define D4_PORT PORT->Group[0] 400 | #define D4_PIN 14 401 | #define D5_PORT PORT->Group[0] 402 | #define D5_PIN 15 403 | #define D6_PORT PORT->Group[0] 404 | #define D6_PIN 20 405 | #define D7_PORT PORT->Group[0] 406 | #define D7_PIN 21 407 | #define D8_PORT PORT->Group[0] 408 | #define D8_PIN 6 409 | #define D9_PORT PORT->Group[0] 410 | #define D9_PIN 7 411 | #define D10_PORT PORT->Group[0] 412 | #define D10_PIN 18 413 | #define D11_PORT PORT->Group[0] 414 | #define D11_PIN 16 415 | #define D12_PORT PORT->Group[0] 416 | #define D12_PIN 19 417 | #define D13_PORT PORT->Group[0] 418 | #define D13_PIN 17 419 | #define A0_PORT PORT->Group[0] 420 | #define A0_PIN 2 421 | #define A1_PORT PORT->Group[1] 422 | #define A1_PIN 8 423 | #define A2_PORT PORT->Group[1] 424 | #define A2_PIN 9 425 | #define A3_PORT PORT->Group[0] 426 | #define A3_PIN 4 427 | #define A4_PORT PORT->Group[0] 428 | #define A4_PIN 5 429 | #define A5_PORT PORT->Group[1] 430 | #define A5_PIN 2 431 | 432 | #endif 433 | // Shield Control macros. 434 | #define PIN_LOW(port, pin) (port).OUTCLR.reg = (1<<(pin)) 435 | #define PIN_HIGH(port, pin) (port).OUTSET.reg = (1<<(pin)) 436 | #define PIN_OUTPUT(port, pin) (port).DIR.reg |= (1<<(pin)) 437 | #define PIN_INPUT(port, pin) (port).DIR.reg &= ~(1u<<(pin)) 438 | #define PIN_READ(port, pin) (port).IN.reg & (1u<<(pin)) 439 | 440 | 441 | #elif defined(__AVR_ATxmegaA4U__) 442 | #include 443 | // PD6, PD7 is used for USB. I could have used PORTA for bus, PORTC for MSPI, SPI and remap 444 | #define D0_PORT PORTE 445 | #define D0_PIN 2 446 | #define D1_PORT PORTE 447 | #define D1_PIN 3 448 | #define D2_PORT PORTC 449 | #define D2_PIN 2 450 | #define D3_PORT PORTC 451 | #define D3_PIN 3 452 | #define D4_PORT PORTC 453 | #define D4_PIN 4 454 | #define D5_PORT PORTC 455 | #define D5_PIN 5 456 | #define D6_PORT PORTC 457 | #define D6_PIN 6 458 | #define D7_PORT PORTC 459 | #define D7_PIN 7 460 | #define D8_PORT PORTC 461 | #define D8_PIN 0 462 | #define D9_PORT PORTC 463 | #define D9_PIN 1 464 | #define D10_PORT PORTD 465 | #define D10_PIN 0 466 | #define D11_PORT PORTD 467 | #define D11_PIN 3 468 | #define D12_PORT PORTD 469 | #define D12_PIN 2 470 | #define D13_PORT PORTD 471 | #define D13_PIN 1 472 | #define A0_PORT PORTB 473 | #define A0_PIN 0 474 | #define A1_PORT PORTB 475 | #define A1_PIN 1 476 | #define A2_PORT PORTB 477 | #define A2_PIN 2 478 | #define A3_PORT PORTB 479 | #define A3_PIN 3 480 | #define A4_PORT PORTE 481 | #define A4_PIN 0 482 | #define A5_PORT PORTE 483 | #define A5_PIN 1 484 | // Shield Control macros. 485 | #define PIN_LOW(port, pin) (port).OUTCLR.reg = (1<<(pin)) 486 | #define PIN_HIGH(port, pin) (port).OUTSET.reg = (1<<(pin)) 487 | #define PIN_OUTPUT(port, pin) (port).DIR.reg |= (1<<(pin)) 488 | #define PIN_INPUT(port, pin) (port).DIR.reg &= ~(1u<<(pin)) 489 | #define PIN_READ(port, pin) (port).IN.reg & (1u<<(pin)) 490 | 491 | 492 | #elif defined(__AVR_ATtiny1634__) 493 | #include 494 | // 495 | #define D0_PORT PORTA 496 | #define D0_PIN 7 497 | #define D1_PORT PORTB 498 | #define D1_PIN 0 499 | #define D2_PORT PORTA 500 | #define D2_PIN 0 501 | #define D3_PORT PORTA 502 | #define D3_PIN 3 503 | #define D4_PORT PORTA 504 | #define D4_PIN 4 505 | #define D5_PORT PORTB 506 | #define D5_PIN 3 507 | #define D6_PORT PORTA 508 | #define D6_PIN 1 509 | #define D7_PORT PORTA 510 | #define D7_PIN 0 511 | #define D8_PORT PORTA 512 | #define D8_PIN 2 513 | #define D9_PORT PORTB 514 | #define D9_PIN 2 515 | #define D10_PORT PORTA 516 | #define D10_PIN 6 517 | #define D11_PORT PORTB 518 | #define D11_PIN 2 519 | #define D12_PORT PORTB 520 | #define D12_PIN 1 521 | #define D13_PORT PORTC 522 | #define D13_PIN 1 523 | #define A0_PORT PORTB 524 | #define A0_PIN 3 525 | #define A1_PORT PORTC 526 | #define A1_PIN 0 527 | #define A2_PORT PORTA 528 | #define A2_PIN 5 529 | #define A3_PORT PORTB 530 | #define A3_PIN 2 531 | #define A4_PORT PORTB 532 | #define A4_PIN 1 533 | #define A5_PORT PORTC 534 | #define A5_PIN 1 535 | #else 536 | #error MCU unselected 537 | #endif // MCUs 538 | 539 | #endif //PIN_SHIELD_1_H 540 | #if 0 541 | #if defined(M0_PRO) 542 | #endif 543 | #if defined(D21_XPRO) 544 | #endif 545 | #endif 546 | -------------------------------------------------------------------------------- /examples/graphictest_kbv/graphictest_kbv.ino: -------------------------------------------------------------------------------- 1 | // All the mcufriend.com UNO shields have the same pinout. 2 | // i.e. control pins A0-A4. Data D2-D9. microSD D10-D13. 3 | // Touchscreens are normally A1, A2, D7, D6 but the order varies 4 | // 5 | // This demo should work with most Adafruit TFT libraries 6 | // If you are not using a shield, use a full Adafruit constructor() 7 | // e.g. Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); 8 | 9 | #define LCD_CS A3 // Chip Select goes to Analog 3 10 | #define LCD_CD A2 // Command/Data goes to Analog 2 11 | #define LCD_WR A1 // LCD Write goes to Analog 1 12 | #define LCD_RD A0 // LCD Read goes to Analog 0 13 | #define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin 14 | 15 | #include // f.k. for Arduino-1.5.2 16 | #include "Adafruit_GFX.h"// Hardware-specific library 17 | //#include 18 | //MCUFRIEND_kbv tft; 19 | //#include 20 | //Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); 21 | #include 22 | HX8347_kbv tft; 23 | uint8_t running; 24 | //#include 25 | //ILI9341_kbv tft; 26 | //#include 27 | //ILI9163_kbv tft; 28 | //#include 29 | //ST7735_kbv tft; 30 | //#include 31 | //SSD1289_kbv tft; 32 | #define MCUFRIEND_KBV_H_ 100 //force the extra tests 33 | 34 | // Assign human-readable names to some common 16-bit color values: 35 | #define BLACK 0x0000 36 | #define BLUE 0x001F 37 | #define RED 0xF800 38 | #define GREEN 0x07E0 39 | #define CYAN 0x07FF 40 | #define MAGENTA 0xF81F 41 | #define YELLOW 0xFFE0 42 | #define WHITE 0xFFFF 43 | 44 | #ifndef min 45 | #define min(a, b) (((a) < (b)) ? (a) : (b)) 46 | #endif 47 | 48 | void setup(void); 49 | void loop(void); 50 | unsigned long testFillScreen(); 51 | unsigned long testText(); 52 | unsigned long testLines(uint16_t color); 53 | unsigned long testFastLines(uint16_t color1, uint16_t color2); 54 | unsigned long testRects(uint16_t color); 55 | unsigned long testFilledRects(uint16_t color1, uint16_t color2); 56 | unsigned long testFilledCircles(uint8_t radius, uint16_t color); 57 | unsigned long testCircles(uint8_t radius, uint16_t color); 58 | unsigned long testTriangles(); 59 | unsigned long testFilledTriangles(); 60 | unsigned long testRoundRects(); 61 | unsigned long testFilledRoundRects(); 62 | void progmemPrint(const char *str); 63 | void progmemPrintln(const char *str); 64 | 65 | void runtests(void); 66 | 67 | uint16_t g_identifier; 68 | 69 | void setup(void) { 70 | Serial.begin(9600); 71 | uint32_t when = millis(); 72 | // while (!Serial) ; //hangs a Leonardo until you connect a Serial 73 | if (!Serial) delay(5000); //allow some time for Leonardo 74 | Serial.println("Serial took " + String((millis() - when)) + "ms to start"); 75 | static uint16_t identifier; 76 | // tft.reset(); //we can't read ID on 9341 until begin() 77 | g_identifier = tft.readID(); // 78 | Serial.print("ID = 0x"); 79 | Serial.println(g_identifier, HEX); 80 | if (g_identifier == 0x00D3) g_identifier = 0x9486; // write-only shield 81 | if (g_identifier == 0xFFFF) g_identifier = 0x9341; // serial 82 | // g_identifier = 0x7789; // force ID 83 | tft.begin(g_identifier); 84 | } 85 | 86 | #if defined(MCUFRIEND_KBV_H_) 87 | uint16_t scrollbuf[480]; // my biggest screen is 320x480 88 | #define READGRAM(x, y, buf, w, h) tft.readGRAM(x, y, buf, w, h) 89 | #else 90 | uint16_t scrollbuf[320]; // Adafruit only does 240x320 91 | // Adafruit can read a block by one pixel at a time 92 | int16_t READGRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h) 93 | { 94 | uint16_t *p; 95 | for (int row = 0; row < h; row++) { 96 | p = block + row * w; 97 | for (int col = 0; col < w; col++) { 98 | *p++ = tft.readPixel(x + col, y + row); 99 | } 100 | } 101 | } 102 | #endif 103 | 104 | void windowScroll(int16_t x, int16_t y, int16_t wid, int16_t ht, int16_t dx, int16_t dy, uint16_t *buf) 105 | { 106 | if (dx) for (int16_t row = 0; row < ht; row++) { 107 | READGRAM(x, y + row, buf, wid, 1); 108 | tft.setAddrWindow(x, y + row, x + wid - 1, y + row); 109 | tft.pushColors(buf + dx, wid - dx, 1); 110 | tft.pushColors(buf + 0, dx, 0); 111 | } 112 | if (dy) for (int16_t col = 0; col < wid; col++) { 113 | READGRAM(x + col, y, buf, 1, ht); 114 | tft.setAddrWindow(x + col, y, x + col, y + ht - 1); 115 | tft.pushColors(buf + dy, ht - dy, 1); 116 | tft.pushColors(buf + 0, dy, 0); 117 | } 118 | } 119 | 120 | void loop(void) { 121 | uint8_t aspect; 122 | uint16_t pixel; 123 | char *aspectname[] = { 124 | "PORTRAIT", "LANDSCAPE", "PORTRAIT_REV", "LANDSCAPE_REV" 125 | }; 126 | char *colorname[] = { "BLUE", "GREEN", "RED", "GRAY" }; 127 | uint16_t colormask[] = { 0x001F, 0x07E0, 0xF800, 0xFFFF }; 128 | uint16_t dx, rgb, n, wid, ht; 129 | tft.setRotation(0); 130 | runtests(); 131 | delay(2000); 132 | if (tft.height() > 64) { 133 | for (uint8_t cnt = 0; cnt < 4; cnt++) { 134 | aspect = (cnt + 0) & 3; 135 | tft.setRotation(aspect); 136 | wid = tft.width(); 137 | ht = tft.height(); 138 | testText(); 139 | dx = wid / 32; 140 | for (n = 0; n < 32; n++) { 141 | rgb = n * 8; 142 | rgb = tft.color565(rgb, rgb, rgb); 143 | tft.fillRect(n * dx, 48, dx, 64, rgb & colormask[aspect]); 144 | } 145 | tft.setTextSize(2); 146 | tft.setTextColor(colormask[aspect], BLACK); 147 | tft.setCursor(0, 72); 148 | tft.print(colorname[aspect]); 149 | tft.setTextColor(WHITE); 150 | tft.println(" COLOR GRADES"); 151 | tft.setTextColor(WHITE, BLACK); 152 | tft.setCursor(0, 184); 153 | tft.println(aspectname[aspect]); 154 | delay(1000); 155 | tft.drawPixel(0, 0, YELLOW); 156 | pixel = tft.readPixel(0, 0); 157 | #if defined(MCUFRIEND_KBV_H_) 158 | extern const uint8_t penguin[]; 159 | tft.setAddrWindow(wid - 40 - 40, 20 + 0, wid - 1 - 40, 20 + 39); 160 | tft.pushColors(penguin, 1600, 1); 161 | tft.setTextColor(WHITE, BLACK); 162 | tft.println("VERTICAL SCROLL UP"); 163 | uint16_t maxscroll; 164 | if (tft.getRotation() & 1) maxscroll = wid; 165 | else maxscroll = ht; 166 | for (uint16_t i = 1; i <= maxscroll; i++) { 167 | tft.vertScroll(0, maxscroll, i); 168 | delay(10); 169 | } 170 | tft.vertScroll(0, maxscroll, 0); 171 | tft.setCursor(0, 200); 172 | tft.println("VERTICAL SCROLL DN"); 173 | for (uint16_t i = 1; i <= maxscroll; i++) { 174 | tft.vertScroll(0, maxscroll, 0 - (int16_t)i); 175 | delay(10); 176 | } 177 | delay(1000); 178 | tft.vertScroll(0, maxscroll, 0); 179 | if ((aspect & 1) == 0) { //Portrait 180 | tft.setCursor(0, 200); 181 | tft.setTextColor(BLUE, BLACK); 182 | tft.println("ONLY THE COLOR BAND"); 183 | for (uint16_t i = 1; i <= 64; i++) { 184 | tft.vertScroll(48, 64, i); 185 | delay(20); 186 | } 187 | delay(1000); 188 | tft.vertScroll(0, maxscroll, 0); 189 | } 190 | #endif 191 | tft.setCursor(0, 200); 192 | tft.setTextColor(YELLOW, BLACK); 193 | if (pixel == YELLOW) { 194 | tft.println("SOFTWARE SCROLL "); 195 | #if 1 196 | for (int16_t i = 45, dx = 2, dy = 1; i > 0; i -= dx) { 197 | windowScroll(24, 8, 90, 40, dx, dy, scrollbuf); 198 | } 199 | #else 200 | // scroll a whole width of the screen 201 | for (int16_t i = wid, dx = 4, dy = 0; i > 0; i -= dx) { 202 | windowScroll(0, 200, wid, 16, dx, dy, scrollbuf); 203 | } 204 | #endif 205 | } 206 | else if (pixel == CYAN) 207 | tft.println("readPixel() reads as BGR"); 208 | else if (pixel == 0xFFFF) 209 | tft.println("readPixel() should be 24-bit"); 210 | else { 211 | tft.print("readPixel() reads 0x"); 212 | tft.println(pixel, HEX); 213 | } 214 | delay(5000); 215 | } 216 | } 217 | tft.println("INVERT DISPLAY"); 218 | tft.invertDisplay(true); 219 | delay(2000); 220 | tft.invertDisplay(false); 221 | } 222 | 223 | typedef struct { 224 | PGM_P msg; 225 | uint32_t ms; 226 | } TEST; 227 | TEST result[12]; 228 | 229 | #define RUNTEST(n, str, test) { result[n].msg = PSTR(str); result[n].ms = test; delay(500); } 230 | 231 | void runtests(void) 232 | { 233 | uint8_t i, len = 24, cnt; 234 | uint32_t total; 235 | RUNTEST(0, "FillScreen ", testFillScreen()); 236 | RUNTEST(1, "Text ", testText()); 237 | RUNTEST(2, "Lines ", testLines(CYAN)); 238 | RUNTEST(3, "Horiz/Vert Lines ", testFastLines(RED, BLUE)); 239 | RUNTEST(4, "Rectangles (outline) ", testRects(GREEN)); 240 | RUNTEST(5, "Rectangles (filled) ", testFilledRects(YELLOW, MAGENTA)); 241 | RUNTEST(6, "Circles (filled) ", testFilledCircles(10, MAGENTA)); 242 | RUNTEST(7, "Circles (outline) ", testCircles(10, WHITE)); 243 | RUNTEST(8, "Triangles (outline) ", testTriangles()); 244 | RUNTEST(9, "Triangles (filled) ", testFilledTriangles()); 245 | RUNTEST(10, "Rounded rects (outline) ", testRoundRects()); 246 | RUNTEST(11, "Rounded rects (filled) ", testFilledRoundRects()); 247 | 248 | tft.fillScreen(BLACK); 249 | tft.setCursor(0, 0); 250 | uint16_t wid = tft.width(); 251 | if (wid > 160) { 252 | tft.setTextSize(2); 253 | #if defined(MCUFRIEND_KBV_H_) 254 | tft.print("MCUFRIEND "); 255 | #if MCUFRIEND_KBV_H_ != 0 256 | tft.print(0.01 * MCUFRIEND_KBV_H_, 1); 257 | #else 258 | tft.print("for"); 259 | #endif 260 | tft.println(" UNO"); 261 | #else 262 | tft.println("Adafruit-Style Tests"); 263 | #endif 264 | } else len = wid / 6 - 8; 265 | tft.setTextSize(1); 266 | total = 0; 267 | for (i = 0; i < 12; i++) { 268 | PGM_P str = result[i].msg; 269 | char c; 270 | if (len > 20) { 271 | if (i < 10) tft.print(" "); 272 | tft.print(i); 273 | tft.print(": "); 274 | } 275 | uint8_t cnt = len; 276 | while ((c = pgm_read_byte(str++)) && cnt--) tft.print(c); 277 | tft.print(" "); 278 | tft.println(result[i].ms); 279 | total += result[i].ms; 280 | } 281 | tft.setTextSize(2); 282 | tft.print("Total:"); 283 | tft.print(0.000001 * total); 284 | tft.println("sec"); 285 | g_identifier = tft.readID(); 286 | tft.print("ID: 0x"); 287 | tft.println(tft.readID(), HEX); 288 | tft.print("Reg(00):0x"); 289 | tft.println(tft.readReg(0x00), HEX); 290 | tft.print("F_CPU:"); 291 | tft.print(0.000001 * F_CPU); 292 | #if defined(__OPTIMIZE_SIZE__) 293 | tft.println("MHz -Os"); 294 | #else 295 | tft.println("MHz"); 296 | #endif 297 | 298 | delay(10000); 299 | } 300 | 301 | // Standard Adafruit tests. will adjust to screen size 302 | 303 | unsigned long testFillScreen() { 304 | unsigned long start = micros(); 305 | tft.fillScreen(BLACK); 306 | tft.fillScreen(RED); 307 | tft.fillScreen(GREEN); 308 | tft.fillScreen(BLUE); 309 | tft.fillScreen(BLACK); 310 | return micros() - start; 311 | } 312 | 313 | unsigned long testText() { 314 | unsigned long start; 315 | tft.fillScreen(BLACK); 316 | start = micros(); 317 | tft.setCursor(0, 0); 318 | tft.setTextColor(WHITE); tft.setTextSize(1); 319 | tft.println("Hello World!"); 320 | tft.setTextColor(YELLOW); tft.setTextSize(2); 321 | tft.println(123.45); 322 | tft.setTextColor(RED); tft.setTextSize(3); 323 | tft.println(0xDEADBEEF, HEX); 324 | tft.println(); 325 | tft.setTextColor(GREEN); 326 | tft.setTextSize(5); 327 | tft.println("Groop"); 328 | tft.setTextSize(2); 329 | tft.println("I implore thee,"); 330 | tft.setTextSize(1); 331 | tft.println("my foonting turlingdromes."); 332 | tft.println("And hooptiously drangle me"); 333 | tft.println("with crinkly bindlewurdles,"); 334 | tft.println("Or I will rend thee"); 335 | tft.println("in the gobberwarts"); 336 | tft.println("with my blurglecruncheon,"); 337 | tft.println("see if I don't!"); 338 | return micros() - start; 339 | } 340 | 341 | unsigned long testLines(uint16_t color) { 342 | unsigned long start, t; 343 | int x1, y1, x2, y2, 344 | w = tft.width(), 345 | h = tft.height(); 346 | 347 | tft.fillScreen(BLACK); 348 | 349 | x1 = y1 = 0; 350 | y2 = h - 1; 351 | start = micros(); 352 | for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color); 353 | x2 = w - 1; 354 | for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color); 355 | t = micros() - start; // fillScreen doesn't count against timing 356 | 357 | tft.fillScreen(BLACK); 358 | 359 | x1 = w - 1; 360 | y1 = 0; 361 | y2 = h - 1; 362 | start = micros(); 363 | for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color); 364 | x2 = 0; 365 | for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color); 366 | t += micros() - start; 367 | 368 | tft.fillScreen(BLACK); 369 | 370 | x1 = 0; 371 | y1 = h - 1; 372 | y2 = 0; 373 | start = micros(); 374 | for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color); 375 | x2 = w - 1; 376 | for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color); 377 | t += micros() - start; 378 | 379 | tft.fillScreen(BLACK); 380 | 381 | x1 = w - 1; 382 | y1 = h - 1; 383 | y2 = 0; 384 | start = micros(); 385 | for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color); 386 | x2 = 0; 387 | for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color); 388 | 389 | return micros() - start; 390 | } 391 | 392 | unsigned long testFastLines(uint16_t color1, uint16_t color2) { 393 | unsigned long start; 394 | int x, y, w = tft.width(), h = tft.height(); 395 | 396 | tft.fillScreen(BLACK); 397 | start = micros(); 398 | for (y = 0; y < h; y += 5) tft.drawFastHLine(0, y, w, color1); 399 | for (x = 0; x < w; x += 5) tft.drawFastVLine(x, 0, h, color2); 400 | 401 | return micros() - start; 402 | } 403 | 404 | unsigned long testRects(uint16_t color) { 405 | unsigned long start; 406 | int n, i, i2, 407 | cx = tft.width() / 2, 408 | cy = tft.height() / 2; 409 | 410 | tft.fillScreen(BLACK); 411 | n = min(tft.width(), tft.height()); 412 | start = micros(); 413 | for (i = 2; i < n; i += 6) { 414 | i2 = i / 2; 415 | tft.drawRect(cx - i2, cy - i2, i, i, color); 416 | } 417 | 418 | return micros() - start; 419 | } 420 | 421 | unsigned long testFilledRects(uint16_t color1, uint16_t color2) { 422 | unsigned long start, t = 0; 423 | int n, i, i2, 424 | cx = tft.width() / 2 - 1, 425 | cy = tft.height() / 2 - 1; 426 | 427 | tft.fillScreen(BLACK); 428 | n = min(tft.width(), tft.height()); 429 | for (i = n; i > 0; i -= 6) { 430 | i2 = i / 2; 431 | start = micros(); 432 | tft.fillRect(cx - i2, cy - i2, i, i, color1); 433 | t += micros() - start; 434 | // Outlines are not included in timing results 435 | tft.drawRect(cx - i2, cy - i2, i, i, color2); 436 | } 437 | 438 | return t; 439 | } 440 | 441 | unsigned long testFilledCircles(uint8_t radius, uint16_t color) { 442 | unsigned long start; 443 | int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2; 444 | 445 | tft.fillScreen(BLACK); 446 | start = micros(); 447 | for (x = radius; x < w; x += r2) { 448 | for (y = radius; y < h; y += r2) { 449 | tft.fillCircle(x, y, radius, color); 450 | } 451 | } 452 | 453 | return micros() - start; 454 | } 455 | 456 | unsigned long testCircles(uint8_t radius, uint16_t color) { 457 | unsigned long start; 458 | int x, y, r2 = radius * 2, 459 | w = tft.width() + radius, 460 | h = tft.height() + radius; 461 | 462 | // Screen is not cleared for this one -- this is 463 | // intentional and does not affect the reported time. 464 | start = micros(); 465 | for (x = 0; x < w; x += r2) { 466 | for (y = 0; y < h; y += r2) { 467 | tft.drawCircle(x, y, radius, color); 468 | } 469 | } 470 | 471 | return micros() - start; 472 | } 473 | 474 | unsigned long testTriangles() { 475 | unsigned long start; 476 | int n, i, cx = tft.width() / 2 - 1, 477 | cy = tft.height() / 2 - 1; 478 | 479 | tft.fillScreen(BLACK); 480 | n = min(cx, cy); 481 | start = micros(); 482 | for (i = 0; i < n; i += 5) { 483 | tft.drawTriangle( 484 | cx , cy - i, // peak 485 | cx - i, cy + i, // bottom left 486 | cx + i, cy + i, // bottom right 487 | tft.color565(0, 0, i)); 488 | } 489 | 490 | return micros() - start; 491 | } 492 | 493 | unsigned long testFilledTriangles() { 494 | unsigned long start, t = 0; 495 | int i, cx = tft.width() / 2 - 1, 496 | cy = tft.height() / 2 - 1; 497 | 498 | tft.fillScreen(BLACK); 499 | start = micros(); 500 | for (i = min(cx, cy); i > 10; i -= 5) { 501 | start = micros(); 502 | tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, 503 | tft.color565(0, i, i)); 504 | t += micros() - start; 505 | tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, 506 | tft.color565(i, i, 0)); 507 | } 508 | 509 | return t; 510 | } 511 | 512 | unsigned long testRoundRects() { 513 | unsigned long start; 514 | int w, i, i2, red, step, 515 | cx = tft.width() / 2 - 1, 516 | cy = tft.height() / 2 - 1; 517 | 518 | tft.fillScreen(BLACK); 519 | w = min(tft.width(), tft.height()); 520 | start = micros(); 521 | red = 0; 522 | step = (256 * 6) / w; 523 | for (i = 0; i < w; i += 6) { 524 | i2 = i / 2; 525 | red += step; 526 | tft.drawRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(red, 0, 0)); 527 | } 528 | 529 | return micros() - start; 530 | } 531 | 532 | unsigned long testFilledRoundRects() { 533 | unsigned long start; 534 | int i, i2, green, step, 535 | cx = tft.width() / 2 - 1, 536 | cy = tft.height() / 2 - 1; 537 | 538 | tft.fillScreen(BLACK); 539 | start = micros(); 540 | green = 256; 541 | step = (256 * 6) / min(tft.width(), tft.height()); 542 | for (i = min(tft.width(), tft.height()); i > 20; i -= 6) { 543 | i2 = i / 2; 544 | green -= step; 545 | tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(0, green, 0)); 546 | } 547 | 548 | return micros() - start; 549 | } 550 | 551 | -------------------------------------------------------------------------------- /examples/graphictest_kbv/icons.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const unsigned char PROGMEM penguin[3200] = { /* 0X00,0X10,0X28,0X00,0X28,0X00,0X01,0X1B, */ 4 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 5 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, 6 | 0XBA, 0XD6, 0XB6, 0XB5, 0XF3, 0X9C, 0XB2, 0X94, 0XB3, 0X9C, 0XB2, 0X94, 0X34, 0XA5, 0XF7, 0XBD, 7 | 0XFB, 0XDE, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 8 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 9 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 10 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XFB, 0XDE, 0XF3, 0X9C, 0XCB, 0X5A, 11 | 0XC7, 0X39, 0X04, 0X21, 0X82, 0X10, 0X42, 0X10, 0X42, 0X10, 0X41, 0X08, 0X83, 0X18, 0X45, 0X29, 12 | 0XC7, 0X39, 0X0C, 0X63, 0X75, 0XAD, 0X3C, 0XE7, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 13 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 14 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 15 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XE7, 0XB2, 0X94, 0X08, 0X42, 0XC3, 0X18, 0X82, 0X10, 16 | 0X04, 0X21, 0X45, 0X29, 0X86, 0X31, 0X86, 0X31, 0X86, 0X31, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, 17 | 0X82, 0X10, 0X41, 0X08, 0XC3, 0X18, 0X08, 0X42, 0XF3, 0X9C, 0X3C, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 18 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 19 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 20 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFB, 0XDE, 0X0C, 0X63, 0XC3, 0X18, 0XC3, 0X18, 0X45, 0X29, 0XC7, 0X39, 21 | 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0X08, 0X42, 0XC7, 0X39, 0XC7, 0X39, 22 | 0X86, 0X31, 0X86, 0X31, 0X04, 0X21, 0X41, 0X08, 0X82, 0X10, 0XCB, 0X5A, 0XBA, 0XD6, 0XFF, 0XFF, 23 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 24 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 25 | 0XFF, 0XFF, 0XFB, 0XDE, 0XCB, 0X5A, 0X82, 0X10, 0X45, 0X29, 0XC7, 0X39, 0X08, 0X42, 0X08, 0X42, 26 | 0X09, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X49, 0X4A, 0X08, 0X42, 0XC7, 0X39, 27 | 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X83, 0X18, 0X00, 0X00, 0XC8, 0X41, 0X38, 0XC6, 28 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 29 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 30 | 0X7D, 0XEF, 0X8E, 0X73, 0X82, 0X10, 0X45, 0X29, 0XC7, 0X39, 0X08, 0X42, 0X09, 0X4A, 0X8A, 0X52, 31 | 0X30, 0X84, 0XCF, 0X7B, 0X8A, 0X52, 0X49, 0X4A, 0X4A, 0X52, 0X49, 0X4A, 0XCB, 0X5A, 0XCF, 0X7B, 32 | 0X0C, 0X63, 0X08, 0X42, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0XC3, 0X18, 0X00, 0X00, 0X49, 0X4A, 33 | 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 34 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 35 | 0XF3, 0X9C, 0XC3, 0X18, 0X04, 0X21, 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X72, 0X94, 36 | 0X7D, 0XEF, 0X7D, 0XEF, 0XB2, 0X94, 0X4A, 0X52, 0X49, 0X4A, 0X8A, 0X52, 0X75, 0XAD, 0XBE, 0XF7, 37 | 0XBA, 0XD6, 0X4D, 0X6B, 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0XC3, 0X18, 0X41, 0X08, 38 | 0XCF, 0X7B, 0X7C, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 39 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBA, 0XD6, 40 | 0X08, 0X42, 0X82, 0X10, 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X8E, 0X73, 0XFB, 0XDE, 41 | 0XFF, 0XFF, 0XBE, 0XF7, 0XBA, 0XD6, 0X8E, 0X73, 0X08, 0X42, 0X30, 0X84, 0X3C, 0XE7, 0X7D, 0XEF, 42 | 0XFF, 0XFF, 0XB6, 0XB5, 0X49, 0X4A, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, 0X41, 0X08, 43 | 0X45, 0X29, 0XB6, 0XB5, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 44 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0X71, 0X8C, 45 | 0X41, 0X08, 0X45, 0X29, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X4A, 0X52, 0XB2, 0X94, 0XBE, 0XF7, 46 | 0XBE, 0XF7, 0XB2, 0X94, 0XCF, 0X7B, 0XCF, 0X7B, 0X49, 0X4A, 0XB6, 0XB5, 0XF3, 0X9C, 0X0C, 0X63, 47 | 0X38, 0XC6, 0XBA, 0XD6, 0X0C, 0X63, 0X87, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0XC3, 0X18, 48 | 0X41, 0X08, 0X30, 0X84, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 49 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XE7, 0XCB, 0X5A, 50 | 0X41, 0X08, 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X4A, 0X52, 0X8A, 0X52, 0XF3, 0X9C, 0XFF, 0XFF, 51 | 0X7D, 0XEF, 0XC7, 0X39, 0XC3, 0X18, 0X0C, 0X63, 0XCB, 0X5A, 0XB6, 0XB5, 0XB2, 0X94, 0XCB, 0X5A, 52 | 0X75, 0XAD, 0XFA, 0XD6, 0X4D, 0X6B, 0X87, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, 53 | 0X41, 0X08, 0X8A, 0X52, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 54 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X38, 0XC6, 0X86, 0X31, 55 | 0X04, 0X21, 0XC8, 0X41, 0X49, 0X4A, 0X49, 0X4A, 0X4A, 0X52, 0X49, 0X4A, 0XB1, 0X8C, 0XBE, 0XF7, 56 | 0XBE, 0XF7, 0XB2, 0X94, 0XCF, 0X7B, 0XCF, 0X7B, 0X49, 0X4A, 0X74, 0XA5, 0X7D, 0XEF, 0X7C, 0XE7, 57 | 0XBE, 0XF7, 0X79, 0XCE, 0X0C, 0X63, 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X04, 0X21, 58 | 0X82, 0X10, 0X45, 0X29, 0X75, 0XAD, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 59 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X34, 0XA5, 0X82, 0X10, 60 | 0X86, 0X31, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X8A, 0X52, 0X49, 0X4A, 0X4D, 0X6B, 0XBA, 0XD6, 61 | 0XFF, 0XFF, 0XFF, 0XFF, 0X79, 0XCE, 0X0D, 0X63, 0XC7, 0X39, 0XCF, 0X7B, 0X7D, 0XEF, 0XFF, 0XFF, 62 | 0XFF, 0XFF, 0X75, 0XAD, 0X08, 0X42, 0X86, 0X31, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X45, 0X29, 63 | 0XC3, 0X18, 0XC3, 0X18, 0XB2, 0X94, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 64 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XB2, 0X8C, 0X41, 0X08, 65 | 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X8A, 0X52, 0X8A, 0X52, 0X4A, 0X4A, 0XD0, 0X7B, 66 | 0X7A, 0XC6, 0X7B, 0XBE, 0X90, 0X6B, 0XC9, 0X39, 0X88, 0X31, 0XC9, 0X39, 0XB3, 0X84, 0XBB, 0XC6, 67 | 0XF8, 0XB5, 0XCC, 0X5A, 0X86, 0X31, 0XC7, 0X39, 0XC7, 0X39, 0X86, 0X31, 0X45, 0X29, 0X45, 0X29, 68 | 0XC4, 0X20, 0X41, 0X08, 0X30, 0X84, 0X3C, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 69 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XE7, 0X8A, 0X4A, 0XC3, 0X10, 70 | 0XC7, 0X39, 0X08, 0X42, 0X49, 0X4A, 0X49, 0X4A, 0X4A, 0X4A, 0X4A, 0X42, 0X09, 0X3A, 0X08, 0X4A, 71 | 0X09, 0X6B, 0X49, 0X7B, 0XC6, 0X7A, 0X05, 0X83, 0X46, 0X83, 0XC5, 0X7A, 0XC6, 0X72, 0X09, 0X7B, 72 | 0X48, 0X5A, 0X87, 0X31, 0X88, 0X21, 0X88, 0X29, 0X86, 0X31, 0X86, 0X31, 0X45, 0X29, 0X45, 0X29, 73 | 0X04, 0X21, 0X41, 0X08, 0X4A, 0X4A, 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 74 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XF7, 0XC5, 0X82, 0X50, 0X05, 0X41, 75 | 0XC7, 0X29, 0X08, 0X42, 0X49, 0X4A, 0X4A, 0X42, 0X49, 0X4A, 0X09, 0X7B, 0X88, 0X9B, 0XC6, 0XB3, 76 | 0X21, 0XD4, 0XA0, 0XDC, 0XE1, 0XE4, 0X61, 0XED, 0X61, 0XED, 0X21, 0XED, 0XA0, 0XE4, 0X20, 0XDC, 77 | 0X80, 0XCB, 0X43, 0XAB, 0XC4, 0X82, 0X06, 0X5A, 0X47, 0X21, 0X46, 0X29, 0X45, 0X29, 0X04, 0X29, 78 | 0X04, 0X19, 0X82, 0X10, 0X82, 0X18, 0XF3, 0X9C, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 79 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0X4D, 0X93, 0X00, 0XA0, 0X82, 0XB8, 80 | 0XC7, 0X31, 0X09, 0X32, 0X49, 0X4A, 0X86, 0X7A, 0X43, 0XC3, 0X6B, 0XED, 0XF4, 0XF6, 0XEB, 0XFD, 81 | 0X20, 0XFD, 0X20, 0XFD, 0X60, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X20, 0XFD, 82 | 0XE0, 0XFC, 0XA0, 0XFC, 0X60, 0XF4, 0XC1, 0XDB, 0X83, 0X9A, 0XC5, 0X49, 0X45, 0X29, 0X04, 0X19, 83 | 0XC4, 0X20, 0X82, 0X38, 0X00, 0X50, 0XCB, 0X6A, 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 84 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFB, 0XEE, 0X04, 0XA1, 0X00, 0XC0, 0X00, 0XF0, 85 | 0XC3, 0XA0, 0XC8, 0X41, 0X49, 0X42, 0X05, 0X9B, 0X20, 0XFC, 0XA4, 0XFC, 0X69, 0XFD, 0XE8, 0XFD, 86 | 0X63, 0XFD, 0X20, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0XE0, 0XFC, 87 | 0XE0, 0XFC, 0XA0, 0XFC, 0X60, 0XFC, 0X20, 0XFC, 0X41, 0XD3, 0XC5, 0X49, 0X45, 0X19, 0XC4, 0X38, 88 | 0X82, 0X68, 0X41, 0X88, 0X00, 0X70, 0X49, 0X5A, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 89 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFB, 0XF6, 0X82, 0XC0, 0X00, 0XD0, 0X86, 0XC1, 90 | 0X46, 0XF1, 0X41, 0XC8, 0X45, 0X79, 0X89, 0X52, 0X88, 0X62, 0X86, 0X6A, 0XC6, 0X7A, 0XC4, 0XBB, 91 | 0XE1, 0XFC, 0X60, 0XFD, 0X60, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0XE0, 0XFC, 92 | 0X60, 0XE4, 0X03, 0X93, 0X84, 0X72, 0X44, 0X6A, 0XC5, 0X41, 0X45, 0X29, 0XC3, 0X58, 0X41, 0XA8, 93 | 0X40, 0X98, 0X00, 0XB0, 0X00, 0X60, 0X0C, 0X6B, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 94 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0XCE, 0X83, 0X82, 0X88, 0X00, 0XF8, 0XC4, 0XD8, 95 | 0X0C, 0XF3, 0X8A, 0XFA, 0X82, 0XE8, 0X82, 0XB0, 0X45, 0X69, 0XC7, 0X51, 0X08, 0X42, 0X08, 0X3A, 96 | 0X86, 0X5A, 0X83, 0X9B, 0XA2, 0XBC, 0X22, 0XCD, 0X21, 0XCD, 0XA1, 0XC4, 0X22, 0XB4, 0XC4, 0X7A, 97 | 0X06, 0X3A, 0X86, 0X29, 0X45, 0X29, 0X05, 0X31, 0XC4, 0X50, 0X41, 0X90, 0X00, 0XC0, 0X00, 0XA8, 98 | 0X00, 0XA0, 0X00, 0XA8, 0X00, 0X30, 0X4A, 0X4A, 0XBA, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 99 | 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0X8E, 0X73, 0XC3, 0X18, 0X05, 0X39, 0X82, 0XA8, 0X00, 0XF8, 100 | 0XC3, 0XF8, 0X4D, 0XFB, 0X4D, 0XFB, 0XC7, 0XF9, 0XC3, 0XF0, 0X82, 0XD8, 0XC3, 0XB0, 0X04, 0X81, 101 | 0X45, 0X61, 0X46, 0X51, 0X86, 0X49, 0X86, 0X49, 0X46, 0X41, 0X45, 0X41, 0X45, 0X41, 0X45, 0X41, 102 | 0X05, 0X49, 0X04, 0X61, 0X82, 0X90, 0X41, 0XB0, 0X00, 0XD0, 0X00, 0XC8, 0X00, 0XA8, 0X00, 0XA8, 103 | 0X00, 0XB8, 0X41, 0X58, 0X82, 0X10, 0X82, 0X10, 0XB2, 0X94, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 104 | 0XFF, 0XFF, 0XBE, 0XF7, 0XCF, 0X7B, 0X82, 0X10, 0X04, 0X21, 0X86, 0X29, 0X86, 0X41, 0X04, 0X99, 105 | 0X40, 0XE8, 0X41, 0XF8, 0X86, 0XF9, 0XCB, 0XFA, 0X49, 0XFA, 0X82, 0XF8, 0X00, 0XF8, 0X00, 0XF0, 106 | 0X00, 0XE8, 0X41, 0XD8, 0X41, 0XD0, 0X41, 0XC0, 0X41, 0XC0, 0X41, 0XC0, 0X41, 0XC0, 0X41, 0XC8, 107 | 0X00, 0XD0, 0X00, 0XE0, 0X00, 0XE0, 0X00, 0XD8, 0X00, 0XD0, 0X00, 0XB8, 0X00, 0XA8, 0X41, 0X88, 108 | 0X82, 0X48, 0X82, 0X10, 0X82, 0X10, 0X00, 0X00, 0X45, 0X29, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 109 | 0XBE, 0XF7, 0XF3, 0X9C, 0X82, 0X10, 0XC3, 0X18, 0X45, 0X29, 0X86, 0X31, 0XC7, 0X31, 0X30, 0X7C, 110 | 0XF3, 0XDC, 0X86, 0XE1, 0X00, 0XF0, 0X00, 0XF8, 0X41, 0XF8, 0X41, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 111 | 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 112 | 0X00, 0XE8, 0X00, 0XE0, 0X00, 0XE0, 0X00, 0XD8, 0X00, 0XC8, 0X41, 0XA0, 0X8A, 0X9A, 0X0C, 0X63, 113 | 0X04, 0X11, 0X82, 0X10, 0X82, 0X10, 0X41, 0X08, 0X00, 0X00, 0X4D, 0X6B, 0X7D, 0XEF, 0XFF, 0XFF, 114 | 0XFB, 0XDE, 0X08, 0X42, 0X42, 0X10, 0X45, 0X29, 0X86, 0X31, 0X86, 0X31, 0X49, 0X4A, 0X38, 0XBE, 115 | 0XFF, 0XFF, 0X38, 0XD6, 0X86, 0XA9, 0X00, 0XC8, 0X00, 0XE0, 0X00, 0XF0, 0X00, 0XF8, 0X00, 0XF8, 116 | 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF8, 0X00, 0XF0, 0X00, 0XF0, 117 | 0X00, 0XE8, 0X00, 0XE0, 0X00, 0XD0, 0XC3, 0X98, 0X8A, 0X8A, 0XB2, 0XA4, 0XBA, 0XC6, 0XF7, 0XB5, 118 | 0X08, 0X42, 0X41, 0X08, 0X82, 0X10, 0X41, 0X08, 0X00, 0X00, 0X45, 0X29, 0XF7, 0XBD, 0XFF, 0XFF, 119 | 0X71, 0X8C, 0X41, 0X08, 0X04, 0X21, 0X45, 0X29, 0X86, 0X31, 0X86, 0X31, 0X0C, 0X63, 0X3C, 0XE7, 120 | 0XFF, 0XFF, 0X79, 0XD6, 0X46, 0XB9, 0X00, 0XE0, 0X42, 0XC8, 0X82, 0XA8, 0X82, 0XB0, 0X41, 0XD8, 121 | 0X82, 0XE8, 0X82, 0XF0, 0X41, 0XE8, 0X41, 0XE8, 0X41, 0XE8, 0X41, 0XF0, 0X41, 0XE8, 0X41, 0XD8, 122 | 0X04, 0XC1, 0X08, 0X92, 0X4D, 0X8B, 0X34, 0XA5, 0XFB, 0XC6, 0XFB, 0XD6, 0XBA, 0XCE, 0X3C, 0XE7, 123 | 0X30, 0X84, 0XC3, 0X18, 0X41, 0X08, 0X41, 0X08, 0X00, 0X00, 0X41, 0X08, 0XCF, 0X7B, 0X7D, 0XEF, 124 | 0X49, 0X4A, 0X00, 0X00, 0X04, 0X21, 0X45, 0X29, 0X46, 0X31, 0X86, 0X31, 0X30, 0X84, 0XFF, 0XFF, 125 | 0XFF, 0XF7, 0XF7, 0XDD, 0X09, 0XDA, 0X83, 0XF8, 0X01, 0XF0, 0X42, 0XC0, 0X82, 0X98, 0X49, 0X9A, 126 | 0XF3, 0XB4, 0XF3, 0XCC, 0X71, 0XBC, 0X8E, 0XBB, 0X8E, 0XBB, 0X30, 0XBC, 0X71, 0XBC, 0XF3, 0XBC, 127 | 0XB6, 0XBD, 0XFB, 0XCE, 0XBE, 0XE7, 0X7D, 0XE7, 0X3B, 0XDF, 0XBA, 0XD6, 0X79, 0XCE, 0XFB, 0XDE, 128 | 0X75, 0XAD, 0X86, 0X31, 0X41, 0X08, 0X41, 0X08, 0X00, 0X00, 0X00, 0X00, 0X49, 0X4A, 0XFB, 0XDE, 129 | 0X04, 0X21, 0X41, 0X08, 0X04, 0X21, 0X45, 0X29, 0X45, 0X29, 0X87, 0X39, 0XB2, 0X94, 0XFF, 0XFF, 130 | 0XBE, 0XF7, 0X34, 0XDD, 0X0C, 0XEB, 0X09, 0XFA, 0X00, 0XF0, 0X01, 0XD8, 0X00, 0XD8, 0X8B, 0XD2, 131 | 0X7D, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 132 | 0XFF, 0XFF, 0XBE, 0XFF, 0X7D, 0XEF, 0XFB, 0XDE, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XBA, 0XD6, 133 | 0X78, 0XC6, 0XC7, 0X39, 0X00, 0X00, 0X41, 0X08, 0X00, 0X00, 0X00, 0X00, 0XC7, 0X39, 0X79, 0XCE, 134 | 0X00, 0X00, 0X82, 0X10, 0XC3, 0X18, 0X04, 0X21, 0X05, 0X29, 0X86, 0X31, 0XB3, 0X9C, 0XFF, 0XFF, 135 | 0XFF, 0XF7, 0X75, 0XDD, 0XC7, 0XE9, 0XC7, 0XF9, 0X01, 0XF8, 0X01, 0XF0, 0X00, 0XE8, 0X49, 0XE2, 136 | 0XFB, 0XEE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 137 | 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, 0XFB, 0XDE, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XBA, 0XD6, 138 | 0XB9, 0XCE, 0X08, 0X42, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0XC7, 0X39, 0X38, 0XC6, 139 | 0X00, 0X00, 0X82, 0X10, 0X82, 0X10, 0X04, 0X21, 0X04, 0X21, 0X45, 0X29, 0X30, 0X84, 0XFF, 0XFF, 140 | 0XFF, 0XFF, 0X38, 0XDE, 0XC4, 0XD0, 0X00, 0XF0, 0X01, 0XF8, 0X00, 0XF8, 0X00, 0XF0, 0X08, 0XD2, 141 | 0XFB, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 142 | 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0XBA, 0XD6, 143 | 0X79, 0XCE, 0XC7, 0X39, 0X41, 0X08, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X86, 0X31, 0X38, 0XC6, 144 | 0X00, 0X00, 0X00, 0X00, 0XC3, 0X18, 0XCB, 0X5A, 0X86, 0X31, 0XC3, 0X18, 0XCB, 0X5A, 0X7D, 0XEF, 145 | 0XFF, 0XFF, 0X7D, 0XEF, 0XCF, 0XBB, 0XC3, 0XB0, 0X41, 0XD0, 0X41, 0XD0, 0X82, 0XB8, 0X4D, 0XB3, 146 | 0X7D, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 147 | 0XBE, 0XF7, 0XBE, 0XF7, 0X3D, 0XEF, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0XFA, 0XD6, 148 | 0XF7, 0XBD, 0X04, 0X21, 0X86, 0X31, 0X04, 0X21, 0X00, 0X00, 0X00, 0X00, 0X86, 0X31, 0X38, 0XC6, 149 | 0X86, 0X31, 0XC3, 0X18, 0XCB, 0X5A, 0X75, 0XAD, 0XCF, 0X7B, 0X41, 0X08, 0X86, 0X31, 0XF7, 0XBD, 150 | 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XEF, 0X74, 0XB5, 0X30, 0X9C, 0X30, 0X9C, 0X72, 0XA4, 0XBB, 0XD6, 151 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 152 | 0XBE, 0XF7, 0X7D, 0XEF, 0X3C, 0XE7, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0X3C, 0XE7, 153 | 0X71, 0X8C, 0X81, 0X08, 0X0C, 0X63, 0XCF, 0X7B, 0X82, 0X10, 0X00, 0X00, 0X8A, 0X52, 0X38, 0XC6, 154 | 0X75, 0XAD, 0X71, 0X8C, 0XB6, 0XB5, 0X3C, 0XE7, 0XFB, 0XDE, 0XC7, 0X39, 0X00, 0X00, 0XCF, 0X73, 155 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 156 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 157 | 0X7D, 0XEF, 0X7D, 0XEF, 0X3B, 0XDF, 0XFA, 0XD6, 0X79, 0XCE, 0X79, 0XCE, 0XFB, 0XDE, 0XB9, 0XCE, 158 | 0XC7, 0X39, 0XC4, 0X20, 0X71, 0X8C, 0XBA, 0XD6, 0X71, 0X8C, 0XCB, 0X5A, 0XB2, 0X94, 0XBA, 0XD6, 159 | 0XFF, 0XFF, 0X7D, 0XEF, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XB6, 0XB5, 0X46, 0X29, 0X05, 0X19, 160 | 0X75, 0XA5, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 161 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 162 | 0X7D, 0XEF, 0X3C, 0XE7, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XBA, 0XD6, 0XFC, 0XDE, 0X4E, 0X63, 163 | 0X42, 0X08, 0X0C, 0X63, 0XF7, 0XBD, 0XBE, 0XF7, 0XFF, 0XFF, 0XFB, 0XDE, 0XFB, 0XDE, 0XBE, 0XF7, 164 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XF4, 0X9C, 0X04, 0X21, 165 | 0X05, 0X21, 0XB6, 0XA5, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 166 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XBE, 0XF7, 0X7D, 0XEF, 167 | 0X3C, 0XE7, 0XFB, 0XDE, 0XBA, 0XD6, 0X79, 0XCE, 0XFB, 0XDE, 0XBB, 0XD6, 0XD1, 0X73, 0X83, 0X18, 168 | 0X86, 0X39, 0X34, 0X9D, 0XBD, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 169 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XFF, 0X35, 0XD6, 0XEB, 0XCC, 0X43, 0XB3, 170 | 0X40, 0X51, 0X05, 0X19, 0XF5, 0X8C, 0XBE, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 171 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XBE, 0XF7, 0X7D, 0XEF, 0X7D, 0XEF, 0X3C, 0XE7, 172 | 0XFB, 0XDE, 0XBA, 0XDE, 0XBA, 0XD6, 0X3C, 0XDF, 0X3A, 0XBE, 0X4F, 0X63, 0X82, 0X49, 0X40, 0XA3, 173 | 0X23, 0XB4, 0XCC, 0X83, 0X3A, 0XBE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 174 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBF, 0XF7, 0XB5, 0XBD, 0X82, 0X92, 0X20, 0XF4, 0XA0, 0XFC, 175 | 0X60, 0XE4, 0X40, 0X82, 0X84, 0X41, 0X8F, 0X6B, 0X77, 0XAD, 0X3D, 0XE7, 0XFF, 0XFF, 0XFF, 0XFF, 176 | 0XFE, 0XFF, 0XBE, 0XF7, 0XBE, 0XF7, 0XBE, 0XF7, 0X7D, 0XEF, 0X7D, 0XEF, 0X3C, 0XE7, 0XFB, 0XDE, 177 | 0XFB, 0XDE, 0X3D, 0XE7, 0XBB, 0XCE, 0X36, 0X9D, 0X0B, 0X6B, 0X41, 0X6A, 0X60, 0XC4, 0X20, 0XFE, 178 | 0X60, 0XF5, 0X00, 0X8B, 0XC7, 0X6A, 0X38, 0XC6, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 179 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0X4B, 0X7B, 0X80, 0XB2, 0XA0, 0XFC, 0XA0, 0XFC, 180 | 0XE0, 0XFC, 0XE0, 0XFC, 0XC0, 0XCB, 0XC1, 0X8A, 0X45, 0X62, 0X4D, 0X6B, 0XB3, 0X94, 0XF7, 0XBD, 181 | 0X3D, 0XDF, 0XFF, 0XF7, 0XFF, 0XFF, 0XBE, 0XF7, 0X7D, 0XEF, 0X7D, 0XEF, 0X7D, 0XE7, 0X3D, 0XDF, 182 | 0XBA, 0XC6, 0X75, 0XA5, 0X8D, 0X7B, 0X84, 0X7A, 0X40, 0XB3, 0XE0, 0XEC, 0XE0, 0XFD, 0XE0, 0XFD, 183 | 0X60, 0XF5, 0X20, 0XE5, 0XA0, 0XD4, 0X0A, 0X6B, 0XFB, 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 184 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7D, 0XEF, 0XCC, 0X93, 0X40, 0XEB, 0X60, 0XFC, 0XA0, 0XFC, 185 | 0XE0, 0XFC, 0X20, 0XFD, 0X60, 0XFD, 0X20, 0XF5, 0XA0, 0XD4, 0XC0, 0XBB, 0X42, 0X9B, 0X45, 0X8B, 186 | 0X6B, 0X9C, 0XAE, 0X9C, 0X71, 0X8C, 0XB3, 0X94, 0X33, 0X9D, 0X34, 0XA5, 0XF2, 0XA4, 0XF0, 0XB4, 187 | 0XCA, 0X9B, 0X04, 0X9B, 0X40, 0XBB, 0X20, 0XE4, 0X20, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XE0, 0XFD, 188 | 0XE0, 0XFD, 0XE0, 0XFD, 0X20, 0XC4, 0X88, 0X5A, 0X38, 0XBE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 189 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X78, 0XD6, 0X46, 0XAB, 0X40, 0XDB, 0X20, 0XF4, 190 | 0X60, 0XFC, 0XA0, 0XFC, 0XE0, 0XFC, 0X60, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X20, 0XF5, 0XA0, 0XDC, 191 | 0XC0, 0XB3, 0XC0, 0X51, 0X86, 0X29, 0X0D, 0X63, 0X8F, 0X7B, 0X0D, 0X5B, 0XC7, 0X41, 0X01, 0X82, 192 | 0X00, 0XC3, 0XC0, 0XE3, 0X60, 0XFC, 0XA0, 0XFC, 0XE0, 0XFC, 0XE0, 0XFC, 0X60, 0XF5, 0X60, 0XF5, 193 | 0X20, 0XE5, 0X80, 0X9B, 0X86, 0X62, 0X30, 0X84, 0X79, 0XCE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 194 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X38, 0XC6, 0X2D, 0X9C, 0X05, 0X93, 195 | 0X43, 0XA3, 0X82, 0XB3, 0XC2, 0XBB, 0XC2, 0XBB, 0X22, 0XB4, 0X82, 0XA3, 0X42, 0X93, 0XC3, 0X7A, 196 | 0X85, 0X62, 0X0B, 0X63, 0X71, 0X84, 0XB6, 0XB5, 0X79, 0XCE, 0X79, 0XC6, 0XB5, 0XAD, 0X70, 0X94, 197 | 0X4A, 0X8B, 0X06, 0X83, 0X04, 0X93, 0X04, 0X9B, 0X43, 0X9B, 0X43, 0X9B, 0X43, 0X93, 0X04, 0X83, 198 | 0X08, 0X73, 0X8D, 0X73, 0XB3, 0X94, 0X79, 0XCE, 0X7D, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 199 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3C, 0XDF, 0X38, 0XBE, 200 | 0X75, 0XB5, 0X33, 0XA5, 0X33, 0XA5, 0XF3, 0X9C, 0XF3, 0X9C, 0XF3, 0X9C, 0XF3, 0X94, 0XF3, 0X9C, 201 | 0X35, 0XA5, 0XF8, 0XBD, 0XFB, 0XDE, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7E, 0XEF, 202 | 0XBB, 0XD6, 0XF8, 0XBD, 0XB6, 0XAD, 0X75, 0XAD, 0X34, 0XA5, 0X33, 0X9D, 0X34, 0X9D, 0X35, 0XA5, 203 | 0XB7, 0XAD, 0X79, 0XC6, 0X3C, 0XE7, 0XBE, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 204 | }; 205 | 206 | const unsigned char PROGMEM icon_40x40[3200] = { /* 0X00,0X10,0X28,0X00,0X28,0X00,0X01,0X1B, */ 207 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 208 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 209 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 210 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 211 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 212 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 213 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X5D, 0XEF, 0X71, 0X8C, 0X31, 0X84, 0X31, 0X84, 214 | 0X93, 0XC5, 0X92, 0XCD, 0X91, 0XCD, 0X91, 0XD5, 0X91, 0XD5, 0X91, 0XCD, 0X72, 0XCD, 0X72, 0XC5, 215 | 0X56, 0XDE, 0XBE, 0XFF, 0XDB, 0XDE, 0XFB, 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 216 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 217 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 218 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XCE, 0X7B, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 219 | 0X00, 0X5A, 0X20, 0XDD, 0X20, 0XDD, 0X20, 0XDD, 0X20, 0XDD, 0X20, 0XDD, 0XE0, 0XD4, 0XA0, 0XD4, 220 | 0X61, 0XA3, 0XA7, 0X39, 0XE5, 0X18, 0X05, 0X21, 0X92, 0X94, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 221 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 222 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 223 | 0XFF, 0XFF, 0XFF, 0XFF, 0XF9, 0XEE, 0XEB, 0X9B, 0XA1, 0X18, 0X23, 0X73, 0X81, 0XC5, 0X21, 0X9C, 224 | 0X61, 0X39, 0X81, 0XEE, 0X40, 0XFF, 0XE0, 0XFE, 0XE0, 0XFE, 0XE0, 0XFE, 0X40, 0XFF, 0XC0, 0XF6, 225 | 0XC0, 0X49, 0XA0, 0X18, 0X00, 0X42, 0X60, 0X18, 0X00, 0X00, 0X74, 0XB5, 0XFF, 0XFF, 0XFF, 0XFF, 226 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 227 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 228 | 0XFF, 0XFF, 0X93, 0XCD, 0XC3, 0XBB, 0XA0, 0X51, 0XE1, 0X39, 0XC2, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 229 | 0X63, 0XBD, 0X61, 0XE6, 0X40, 0XFF, 0XE0, 0XFE, 0XE0, 0XFE, 0XC0, 0XFE, 0X60, 0XFF, 0X21, 0X73, 230 | 0XE1, 0X28, 0X81, 0XEE, 0X61, 0XFF, 0X21, 0XEE, 0XA0, 0X41, 0X20, 0X08, 0X90, 0XCD, 0XDE, 0XFF, 231 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 232 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X5C, 0XF7, 233 | 0X0B, 0XAC, 0XC0, 0XB3, 0XA1, 0XEE, 0XC3, 0X5A, 0X22, 0X8C, 0XE1, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 234 | 0XC0, 0XFF, 0X80, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0X20, 0XFF, 0XA1, 0XAC, 235 | 0X21, 0XC5, 0X20, 0XFF, 0X60, 0XFE, 0X00, 0XFF, 0X02, 0XDE, 0XE0, 0X20, 0X40, 0X82, 0X49, 0XBC, 236 | 0X3B, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 237 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X5C, 0XF7, 0X67, 0X9B, 238 | 0XE0, 0XB3, 0X81, 0XFF, 0XC3, 0XFF, 0X83, 0X9C, 0X82, 0XDE, 0XC0, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 239 | 0X40, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0X60, 0XFF, 240 | 0X40, 0XFF, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0XE0, 0XFE, 0XA2, 0XB4, 0X41, 0XBC, 0X20, 0XCC, 241 | 0X87, 0XA3, 0XB8, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 242 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X9D, 0XF7, 0XA8, 0XA3, 0X60, 0XBC, 243 | 0XA2, 0XFF, 0XA5, 0XFF, 0X44, 0XFF, 0XA1, 0XFF, 0XA0, 0XFF, 0X60, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 244 | 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 245 | 0X00, 0XFF, 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0X60, 0XFE, 0X20, 0XFE, 0X40, 0XFE, 246 | 0XE0, 0XCB, 0XE3, 0X92, 0X7C, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 247 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X4C, 0XAC, 0XC0, 0XB3, 0XA4, 0XFF, 248 | 0XA6, 0XFF, 0X45, 0XFF, 0X62, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 249 | 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 250 | 0X20, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, 0X80, 0XFE, 0X60, 0XFE, 0X40, 0XFE, 0X20, 0XFE, 0X00, 0XFE, 251 | 0XE0, 0XFD, 0XE0, 0XC3, 0X2A, 0XAC, 0X7D, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 252 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XD4, 0XD5, 0X40, 0XAB, 0X43, 0XFF, 0XA8, 0XFF, 253 | 0X67, 0XFF, 0X62, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 254 | 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 255 | 0X40, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0X20, 0XFE, 0XE0, 0XFD, 256 | 0XE0, 0XFD, 0XC0, 0XFD, 0XA0, 0XA2, 0X11, 0XBD, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 257 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XDA, 0XE6, 0XE4, 0X9A, 0XE1, 0XE5, 0XE8, 0XFF, 0X69, 0XFF, 258 | 0X65, 0XFF, 0X60, 0XFF, 0X80, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 259 | 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 260 | 0X40, 0XFF, 0X00, 0XFF, 0X00, 0XFF, 0X20, 0XFF, 0XE0, 0XFE, 0X60, 0XFE, 0X20, 0XFE, 0X00, 0XFE, 261 | 0XC0, 0XFD, 0XE0, 0XFD, 0XE0, 0XE4, 0X85, 0XAB, 0XFA, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 262 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X2B, 0XB4, 0XC0, 0XB3, 0XC8, 0XFF, 0X8C, 0XFF, 0X68, 0XFF, 263 | 0X61, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0XE1, 0XFF, 0XA1, 0XDE, 0X61, 0XEF, 264 | 0XE1, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 265 | 0X40, 0XFF, 0X60, 0XFF, 0XC0, 0XFF, 0X61, 0XDE, 0X00, 0XE6, 0X80, 0XFE, 0X40, 0XFE, 0X00, 0XFE, 266 | 0XE0, 0XFD, 0XC0, 0XFD, 0XE0, 0XFD, 0XC0, 0XC3, 0XE9, 0XAB, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 267 | 0XFF, 0XFF, 0XFF, 0XFF, 0X5D, 0XEF, 0XA3, 0XAB, 0XA3, 0XF6, 0XCC, 0XFF, 0X4C, 0XFF, 0X64, 0XFF, 268 | 0X80, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0X61, 0XEF, 0X22, 0X6B, 0X82, 0X5A, 0X82, 0XB5, 269 | 0XE2, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 270 | 0XA0, 0XFF, 0XE1, 0XFF, 0X42, 0X8C, 0XC1, 0X41, 0X21, 0XA4, 0XA0, 0XFE, 0X80, 0XFE, 0X20, 0XFE, 271 | 0XE0, 0XFD, 0XC0, 0XFD, 0XA0, 0XFD, 0X20, 0XF5, 0XC0, 0X9A, 0X35, 0XD6, 0XFF, 0XFF, 0XFF, 0XFF, 272 | 0XFF, 0XFF, 0XFF, 0XFF, 0X51, 0XC5, 0X60, 0XBC, 0XC9, 0XFF, 0X8E, 0XFF, 0X6A, 0XFF, 0X61, 0XFF, 273 | 0X80, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XE1, 0XFF, 0XE1, 0X62, 0X80, 0X10, 0X05, 0XE7, 0XA4, 0XF7, 274 | 0XE4, 0XFF, 0XE3, 0XFF, 0XE2, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 275 | 0XC1, 0XFF, 0XE2, 0X83, 0X40, 0X08, 0X22, 0XCE, 0X60, 0XF7, 0XA0, 0XFE, 0X60, 0XFE, 0X20, 0XFE, 276 | 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0XA0, 0XFD, 0XA0, 0XC3, 0XAC, 0XBC, 0XFF, 0XFF, 0XFF, 0XFF, 277 | 0XFF, 0XFF, 0XDE, 0XFF, 0XA7, 0XAB, 0X81, 0XDD, 0XED, 0XFF, 0XB0, 0XFF, 0X69, 0XFF, 0X60, 0XFF, 278 | 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0X61, 0XD6, 0X22, 0X29, 0XA6, 0X31, 0XE3, 0X7B, 0X46, 0XEF, 279 | 0XE6, 0XFF, 0XE4, 0XFF, 0XE2, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 280 | 0X81, 0XD6, 0XA0, 0X18, 0XC4, 0X18, 0XA1, 0X62, 0XC1, 0XCD, 0X40, 0XFF, 0X60, 0XFE, 0X20, 0XFE, 281 | 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0X80, 0XFD, 0XA0, 0XEC, 0X48, 0XBC, 0XDF, 0XFF, 0XFF, 0XFF, 282 | 0XFF, 0XFF, 0XF9, 0XE6, 0XE3, 0X9A, 0X67, 0XEE, 0XD1, 0XFF, 0XB0, 0XFF, 0X86, 0XFF, 0X60, 0XFF, 283 | 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0X60, 0X94, 0X91, 0X73, 0XD9, 0XBD, 0X00, 0X00, 0X05, 0X84, 284 | 0XE8, 0XFF, 0XE5, 0XFF, 0XE3, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 285 | 0X20, 0XAD, 0XE9, 0X41, 0XB7, 0XB5, 0X01, 0X00, 0X60, 0X62, 0X21, 0XFF, 0X80, 0XFE, 0X20, 0XFE, 286 | 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X20, 0XF5, 0XE3, 0XBB, 0XD9, 0XE6, 0XFF, 0XFF, 287 | 0XFF, 0XFF, 0XD3, 0XCD, 0X40, 0XA3, 0X2B, 0XF7, 0XD3, 0XFF, 0XB0, 0XFF, 0X63, 0XFF, 0X60, 0XFF, 288 | 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0XA0, 0X9C, 0X30, 0X6B, 0X97, 0XB5, 0X00, 0X00, 0X83, 0X52, 289 | 0XC6, 0XFF, 0XE5, 0XFF, 0XE3, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 290 | 0X20, 0XAD, 0XEA, 0X41, 0X77, 0XAD, 0X01, 0X00, 0XC0, 0X49, 0XE0, 0XF6, 0XA0, 0XFE, 0X20, 0XFE, 291 | 0XE0, 0XFD, 0XC0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0XA0, 0XBB, 0XD3, 0XCD, 0XFF, 0XFF, 292 | 0XFF, 0XFF, 0X50, 0XCD, 0X00, 0XB4, 0X8E, 0XFF, 0XF4, 0XFF, 0XB0, 0XFF, 0X42, 0XFF, 0X60, 0XFF, 293 | 0X80, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0XA1, 0XDE, 0X01, 0X21, 0X00, 0X00, 0X00, 0X00, 0X25, 0X8C, 294 | 0XE5, 0XFF, 0XE3, 0XFF, 0XE2, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 295 | 0XE1, 0XDE, 0X01, 0X21, 0X00, 0X00, 0X00, 0X00, 0X61, 0X5A, 0X20, 0XFF, 0X80, 0XFE, 0X20, 0XFE, 296 | 0X00, 0XFE, 0XE0, 0XFD, 0XA0, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0XC0, 0XCB, 0X71, 0XCD, 0XFF, 0XFF, 297 | 0XFF, 0XFF, 0X50, 0XCD, 0X40, 0XC4, 0XB0, 0XFF, 0XF5, 0XFF, 0X8F, 0XFF, 0X41, 0XFF, 0X80, 0XFF, 298 | 0XA0, 0XFF, 0XC0, 0XFF, 0XE0, 0XFF, 0XE1, 0XFF, 0X21, 0X8C, 0X60, 0X10, 0X43, 0X6B, 0X44, 0XEF, 299 | 0XE2, 0XFF, 0XE2, 0XFF, 0XE1, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 300 | 0XE1, 0XFF, 0XC1, 0XA4, 0XC2, 0X18, 0XA2, 0X39, 0XA1, 0XCD, 0X20, 0XFF, 0X60, 0XFE, 0X20, 0XFE, 301 | 0XC0, 0XFD, 0X80, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0XE0, 0XCB, 0X91, 0XCD, 0XFF, 0XFF, 302 | 0XFF, 0XFF, 0X50, 0XCD, 0X40, 0XC4, 0XD2, 0XFF, 0XF7, 0XFF, 0XAF, 0XFF, 0X01, 0XFF, 0X00, 0XFF, 303 | 0X00, 0XFF, 0X40, 0XFF, 0XA0, 0XFF, 0XE0, 0XFF, 0XA1, 0XFF, 0X82, 0XD6, 0XC2, 0XFF, 0XE0, 0XFF, 304 | 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 305 | 0X60, 0XFF, 0XC1, 0XFF, 0X82, 0XDE, 0XC2, 0XEE, 0X61, 0XFF, 0X80, 0XFE, 0XC0, 0XFD, 0X20, 0XFD, 306 | 0XA1, 0XFC, 0X61, 0XFC, 0X61, 0XFC, 0XC0, 0XFC, 0X60, 0XFD, 0XE0, 0XCB, 0X51, 0XC5, 0XFF, 0XFF, 307 | 0XFF, 0XFF, 0X50, 0XCD, 0X60, 0XC4, 0XD4, 0XFF, 0XF9, 0XFF, 0X2D, 0XFF, 0X00, 0XFE, 0XC0, 0XFD, 308 | 0XA1, 0XFD, 0X21, 0XFE, 0XE0, 0XFE, 0XC0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 0XE0, 0XFF, 309 | 0XE0, 0XFF, 0XE0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 310 | 0X40, 0XFF, 0X40, 0XFF, 0X80, 0XFF, 0X20, 0XFF, 0XA0, 0XFE, 0X20, 0XFE, 0X01, 0XFD, 0X01, 0XFC, 311 | 0X62, 0XFB, 0X42, 0XFB, 0X82, 0XFB, 0X21, 0XFC, 0X20, 0XFD, 0X00, 0XD4, 0X71, 0XC5, 0XFF, 0XFF, 312 | 0XFF, 0XFF, 0X50, 0XCD, 0X20, 0XC4, 0XD4, 0XFF, 0XBA, 0XFF, 0X2E, 0XFE, 0XE1, 0XFC, 0X61, 0XFC, 313 | 0X61, 0XFC, 0X01, 0XFD, 0X01, 0XFE, 0X20, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XC0, 0XFF, 0XC0, 0XFF, 314 | 0XC0, 0XFF, 0XC0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 315 | 0X40, 0XFF, 0X00, 0XFF, 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X80, 0XFD, 0X61, 0XFC, 0X62, 0XFB, 316 | 0XA3, 0XFA, 0XA3, 0XFA, 0X42, 0XFB, 0X01, 0XFC, 0XE0, 0XFC, 0XE0, 0XCB, 0X71, 0XCD, 0XFF, 0XFF, 317 | 0XFF, 0XFF, 0X50, 0XCD, 0XC0, 0XB3, 0XB3, 0XFF, 0X7A, 0XFF, 0X91, 0XFD, 0X03, 0XFC, 0X02, 0XFB, 318 | 0X22, 0XFB, 0X62, 0XFC, 0X81, 0XFD, 0XC0, 0XFE, 0XA0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 0XA0, 0XFF, 319 | 0XA0, 0XFF, 0XA0, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 320 | 0X20, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, 0XA0, 0XFE, 0X60, 0XFE, 0X60, 0XFD, 0X41, 0XFC, 0X62, 0XFB, 321 | 0XC3, 0XFA, 0XA3, 0XFA, 0X42, 0XFB, 0X01, 0XFC, 0X20, 0XFD, 0XC0, 0XCB, 0X91, 0XCD, 0XFF, 0XFF, 322 | 0XFF, 0XFF, 0X14, 0XD6, 0X20, 0XAB, 0X51, 0XF7, 0XBE, 0XFF, 0X17, 0XFE, 0X65, 0XFC, 0X61, 0XFB, 323 | 0XA2, 0XFB, 0XA1, 0XFC, 0XC1, 0XFD, 0X00, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 324 | 0X80, 0XFF, 0X80, 0XFF, 0X80, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 325 | 0X00, 0XFF, 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X60, 0XFE, 0XC0, 0XFD, 0XC0, 0XFC, 0X41, 0XFC, 326 | 0XC1, 0XFB, 0XA2, 0XFB, 0X01, 0XFC, 0XA0, 0XFC, 0X40, 0XFD, 0XA0, 0XC3, 0XF4, 0XD5, 0XFF, 0XFF, 327 | 0XFF, 0XFF, 0X5B, 0XEF, 0X24, 0X9B, 0X49, 0XE6, 0XB8, 0XFF, 0X92, 0XFE, 0X25, 0XFD, 0XA0, 0XFC, 328 | 0X02, 0XFD, 0XE1, 0XFD, 0XE0, 0XFE, 0X40, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 329 | 0X60, 0XFF, 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 330 | 0XC0, 0XFE, 0XA0, 0XFE, 0X80, 0XFE, 0X40, 0XFE, 0X40, 0XFE, 0X00, 0XFE, 0X80, 0XFD, 0X01, 0XF5, 331 | 0X41, 0XFD, 0X01, 0XFD, 0XC0, 0XFC, 0X40, 0XFD, 0X00, 0XF5, 0XC4, 0XBB, 0XFA, 0XE6, 0XFF, 0XFF, 332 | 0XFF, 0XFF, 0XFF, 0XFF, 0X2A, 0XB4, 0XA0, 0XD4, 0XA2, 0XFE, 0X20, 0XFE, 0XE0, 0XFD, 0X00, 0XFE, 333 | 0X80, 0XFE, 0X21, 0XEE, 0X41, 0XE6, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 334 | 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, 335 | 0XA0, 0XFE, 0X80, 0XFE, 0X60, 0XFE, 0X40, 0XFE, 0X00, 0XFE, 0X00, 0XFE, 0X00, 0XFE, 0X40, 0XCC, 336 | 0XE1, 0XAB, 0XC1, 0XED, 0X80, 0XFD, 0X60, 0XFD, 0X60, 0XE4, 0X29, 0XB4, 0XFF, 0XFF, 0XFF, 0XFF, 337 | 0XFF, 0XFF, 0XFF, 0XFF, 0X15, 0XD6, 0XE0, 0XBB, 0X60, 0XFE, 0XC8, 0XFE, 0XC8, 0XFE, 0X02, 0XFF, 338 | 0X60, 0XDD, 0X40, 0XA3, 0XA1, 0XDD, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 339 | 0X20, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, 0XC0, 0XFE, 0XC0, 0XFE, 0XA0, 0XFE, 340 | 0X80, 0XFE, 0X60, 0XFE, 0X40, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X40, 0XED, 341 | 0XC0, 0X9A, 0X40, 0XA3, 0X80, 0XF5, 0X60, 0XFD, 0X60, 0XBB, 0XEE, 0XBC, 0XFF, 0XFF, 0XFF, 0XFF, 342 | 0XFF, 0XFF, 0XFF, 0XFF, 0XDF, 0XFF, 0X63, 0XAB, 0X42, 0XE5, 0XB4, 0XFF, 0X97, 0XFF, 0XAA, 0XF6, 343 | 0X80, 0XAB, 0XA0, 0X92, 0XA1, 0XDD, 0X41, 0XFF, 0X40, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 0X60, 0XFF, 344 | 0X60, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X40, 0XFF, 0X20, 0XFF, 0X20, 0XFF, 0X00, 0XFF, 0XE0, 0XFE, 345 | 0XC0, 0XFE, 0X80, 0XFE, 0X61, 0XFE, 0X00, 0XFE, 0XA0, 0XED, 0X20, 0XE5, 0X21, 0XCC, 0X80, 0XB3, 346 | 0X00, 0XBC, 0XE0, 0XC3, 0X40, 0XED, 0XC0, 0XEC, 0X60, 0X92, 0X97, 0XE6, 0XFF, 0XFF, 0XFF, 0XFF, 347 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X0F, 0XC5, 0X00, 0XA3, 0XAA, 0XF6, 0X93, 0XFF, 0X2D, 0XEE, 348 | 0X63, 0XDD, 0X80, 0XD5, 0X42, 0XB4, 0X82, 0XCC, 0X00, 0XCD, 0X40, 0XD5, 0XA0, 0XDD, 0XE1, 0XE5, 349 | 0XC1, 0XE5, 0XC1, 0XE5, 0XC1, 0XE5, 0XC1, 0XE5, 0X80, 0XDD, 0X60, 0XDD, 0X20, 0XD5, 0XC0, 0XCC, 350 | 0XA0, 0XCC, 0X61, 0XC4, 0X21, 0XC4, 0X01, 0XBC, 0X01, 0XBC, 0XE0, 0XBB, 0XC0, 0XBB, 0X60, 0XD4, 351 | 0X80, 0XFD, 0X40, 0XFD, 0X80, 0XFD, 0X80, 0XBB, 0X2B, 0XAC, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 352 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X9D, 0XF7, 0X87, 0XA3, 0X60, 0XD4, 0X0A, 0XFF, 0XCF, 0XFE, 353 | 0XC9, 0XFE, 0XC0, 0XFE, 0XC0, 0XF6, 0X40, 0XE6, 0X41, 0XCD, 0X42, 0XB4, 0XC1, 0XAB, 0X60, 0XA3, 354 | 0X60, 0XA3, 0X80, 0XA3, 0X80, 0XA3, 0X80, 0XA3, 0XA0, 0XAB, 0XC1, 0XAB, 0XE1, 0XB3, 0X22, 0XB4, 355 | 0X82, 0XC4, 0XC0, 0XCC, 0X00, 0XD5, 0X60, 0XE5, 0X81, 0XED, 0X80, 0XF5, 0X80, 0XFD, 0X80, 0XFD, 356 | 0X40, 0XFD, 0X80, 0XFD, 0X80, 0XE4, 0X85, 0XAB, 0X5C, 0XEF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 357 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFA, 0XE6, 0X23, 0XA3, 0XE0, 0XE4, 0XE8, 0XFE, 358 | 0X6A, 0XFE, 0X05, 0XFE, 0X40, 0XFE, 0XA0, 0XFE, 0XC0, 0XFE, 0XE1, 0XFE, 0XA0, 0XF6, 0XA0, 0XF6, 359 | 0XA0, 0XF6, 0XA0, 0XF6, 0X80, 0XF6, 0X80, 0XF6, 0X80, 0XF6, 0X60, 0XF6, 0X61, 0XFE, 0X81, 0XFE, 360 | 0X61, 0XFE, 0X20, 0XFE, 0X00, 0XFE, 0XC0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 361 | 0X60, 0XFD, 0X20, 0XF5, 0XA0, 0XA2, 0XB4, 0XCD, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 362 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X52, 0XC5, 0XE0, 0XA2, 0XA1, 0XF5, 363 | 0X86, 0XFE, 0X06, 0XFE, 0XE2, 0XFD, 0XE0, 0XFD, 0X00, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 364 | 0X40, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X20, 0XFE, 0X00, 0XFE, 0XE0, 0XFD, 0XE0, 0XFD, 0XC0, 0XFD, 365 | 0XA0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X40, 0XFD, 366 | 0X60, 0XFD, 0X60, 0XBB, 0X6C, 0XB4, 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 367 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X92, 0XCD, 0XC0, 0XA2, 368 | 0X20, 0XED, 0X22, 0XFE, 0XC1, 0XFD, 0XA0, 0XFD, 0XC0, 0XFD, 0XE0, 0XFD, 0XE0, 0XFD, 0XE0, 0XFD, 369 | 0XE0, 0XFD, 0XE0, 0XFD, 0XC0, 0XFD, 0XC0, 0XFD, 0XC0, 0XFD, 0XC0, 0XFD, 0XA0, 0XFD, 0X80, 0XFD, 370 | 0X80, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 371 | 0X20, 0XB3, 0XEA, 0XA3, 0X9D, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 372 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X8E, 0XBC, 373 | 0XE1, 0XA2, 0X00, 0XE5, 0XE0, 0XFD, 0XC0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 374 | 0XC0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0XA0, 0XFD, 0X80, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 375 | 0X40, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X80, 0XFD, 0X00, 0XF5, 0X40, 0XBB, 376 | 0X2B, 0XAC, 0X9D, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 377 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 378 | 0X35, 0XD6, 0XE2, 0X9A, 0XA0, 0XC3, 0XA0, 0XFD, 0XE0, 0XFD, 0X80, 0XFD, 0X60, 0XFD, 0X80, 0XFD, 379 | 0X80, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 380 | 0X20, 0XFD, 0X20, 0XFD, 0X40, 0XFD, 0X60, 0XFD, 0X60, 0XFD, 0X00, 0XD4, 0XC1, 0X9A, 0X10, 0XC5, 381 | 0XDE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 382 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 383 | 0XFF, 0XFF, 0X98, 0XDE, 0X2B, 0XAC, 0X40, 0XB3, 0X00, 0XD4, 0X40, 0XFD, 0X80, 0XFD, 0X80, 0XFD, 384 | 0X60, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 0X40, 0XFD, 385 | 0X40, 0XFD, 0X60, 0XFD, 0X40, 0XFD, 0X40, 0XDC, 0X80, 0XBB, 0XE8, 0XAB, 0X57, 0XDE, 0XFF, 0XFF, 386 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 387 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 388 | 0XFF, 0XFF, 0XFF, 0XFF, 0XDF, 0XFF, 0X37, 0XD6, 0X86, 0XA3, 0XC0, 0X9A, 0XE0, 0XCB, 0X80, 0XEC, 389 | 0XE0, 0XF4, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X20, 0XFD, 0X00, 0XF5, 390 | 0XA0, 0XEC, 0X00, 0XD4, 0X40, 0XB3, 0X03, 0X9B, 0X92, 0XC5, 0XBD, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 391 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 392 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 393 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XBE, 0XF7, 0XF5, 0XCD, 0XAD, 0XBC, 0X69, 0XBC, 394 | 0X05, 0XBC, 0X03, 0XC4, 0X01, 0XC4, 0X01, 0XC4, 0X01, 0XC4, 0X01, 0XC4, 0XE2, 0XC3, 0X24, 0XC4, 395 | 0X68, 0XBC, 0XAC, 0XBC, 0XD3, 0XCD, 0X9E, 0XF7, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 396 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 397 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 398 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 399 | 0X5B, 0XEF, 0X98, 0XDE, 0X56, 0XD6, 0X57, 0XD6, 0X57, 0XD6, 0X56, 0XD6, 0X77, 0XDE, 0X1B, 0XEF, 400 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 401 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 402 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 403 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 404 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 405 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 406 | 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 407 | }; 408 | 409 | --------------------------------------------------------------------------------