├── JPEGS
├── F103RBT6.jpg
├── JpegView.jpg
├── SMT32_PillBoard.jpg
├── healsky3.jpg
├── sunrise.jpg
└── tree.jpg
├── README.md
├── STM32_TFT_8bit.cpp
├── STM32_TFT_8bit.h
├── examples
├── ClockAnalog_STM32
│ └── ClockAnalog_STM32.ino
├── CubeDemo_STM32
│ └── CubeDemo_STM32.ino
├── GraphicsTest_240x320_SMT32
│ └── GraphicsTest_240x320_SMT32.ino
├── GraphicsTest_240x400_SMT32
│ └── GraphicsTest_240x400_SMT32.ino
├── GraphicsTest_320x480_SMT32
│ └── GraphicsTest_320x480_SMT32.ino
├── JpegView_240x320_SMT32
│ ├── JPEG_Functions.ino
│ └── JpegView_240x320_SMT32.ino
├── JpegView_320x480_SMT32
│ ├── JPEG_Functions.ino
│ └── JpegView_320x480_SMT32.ino
├── LCD_ID_Reader
│ ├── LCD_ID_Reader.ino
│ └── README.md
├── ScrollTest_STM32
│ ├── ScrollTest_STM32.ino
│ └── icons.c
├── TFT_ArcFill_STM32
│ └── TFT_ArcFill_STM32.ino
├── TFT_Meter_linear_STM32
│ └── TFT_Meter_linear_STM32.ino
├── TFT_Meters_STM32
│ └── TFT_Meters_STM32.ino
├── TFT_Pong_STM32
│ └── TFT_Pong_STM32.ino
└── UTFT_demo_STM32
│ └── UTFT_demo_STM32.ino
└── library.properties
/JPEGS/F103RBT6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/STM32_TFT_8bit/a41ea46b5513001c74907149dc6d57235211c91d/JPEGS/F103RBT6.jpg
--------------------------------------------------------------------------------
/JPEGS/JpegView.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/STM32_TFT_8bit/a41ea46b5513001c74907149dc6d57235211c91d/JPEGS/JpegView.jpg
--------------------------------------------------------------------------------
/JPEGS/SMT32_PillBoard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/STM32_TFT_8bit/a41ea46b5513001c74907149dc6d57235211c91d/JPEGS/SMT32_PillBoard.jpg
--------------------------------------------------------------------------------
/JPEGS/healsky3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/STM32_TFT_8bit/a41ea46b5513001c74907149dc6d57235211c91d/JPEGS/healsky3.jpg
--------------------------------------------------------------------------------
/JPEGS/sunrise.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/STM32_TFT_8bit/a41ea46b5513001c74907149dc6d57235211c91d/JPEGS/sunrise.jpg
--------------------------------------------------------------------------------
/JPEGS/tree.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/STM32_TFT_8bit/a41ea46b5513001c74907149dc6d57235211c91d/JPEGS/tree.jpg
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # STM32_TFT_8bit
2 | 8bit TFT Library for Arduino_STM32(MAPLE Core)
3 |
4 | I ported from here.
5 | https://github.com/prenticedavid/MCUFRIEND_kbv
6 |
7 | ----
8 |
9 | # Software requirement
10 |
11 | - Core library
12 | https://github.com/rogerclarkmelbourne/Arduino_STM32
13 |
14 | - Adafruit GFX Library
15 | https://github.com/adafruit/Adafruit-GFX-Library
16 |
17 | ----
18 |
19 | # Wirering for 8bit Parallel TFT
20 |
21 | Using GPIOA as Data Port
22 | `#define TFT_DATA GPIOA`
23 |
24 | |TFT||STM32F103|
25 | |:-:|:-:|:-:|
26 | |LCD_RST|--|PB7|
27 | |LCD_CS|--|PB6|
28 | |LCD_RS|--|PB5|
29 | |LCD_WR|--|PB4(*2)|
30 | |LCD_RD|--|PB3(*2)|
31 | |LCD_D0|--|PA0|
32 | |LCD_D1|--|PA1|
33 | |LCD_D2|--|PA2|
34 | |LCD_D3|--|PA3|
35 | |LCD_D4|--|PA4|
36 | |LCD_D5|--|PA5|
37 | |LCD_D6|--|PA6|
38 | |LCD_D7|--|PA7|
39 | |5V|--|5V(*1)|
40 | |3.3V|--|3.3V(*1)|
41 | |GND|--|GND|
42 |
43 |
44 | Using GPIOC as Data Port
45 | `#define TFT_DATA GPIOC`
46 |
47 | |TFT||STM32F103|
48 | |:-:|:-:|:-:|
49 | |LCD_RST|--|PB7|
50 | |LCD_CS|--|PB6|
51 | |LCD_RS|--|PB5|
52 | |LCD_WR|--|PB4(*2)|
53 | |LCD_RD|--|PB3(*2)|
54 | |LCD_D0|--|PC0|
55 | |LCD_D1|--|PC1|
56 | |LCD_D2|--|PC2|
57 | |LCD_D3|--|PC3|
58 | |LCD_D4|--|PC4|
59 | |LCD_D5|--|PC5|
60 | |LCD_D6|--|PC6|
61 | |LCD_D7|--|PC7|
62 | |5V|--|5V(*1)|
63 | |3.3V|--|3.3V(*1)|
64 | |GND|--|GND|
65 |
66 | (*1)When a regulator(It's often AMS1117) is mounted on the back, it's operated 5V.
67 | When a regulator is NOT mounted on the back, it's operated 3.3V.
68 |
69 | (*2)By several boards, This port is used as JTAG.
70 | You need remap.
71 | afio_cfg_debug_ports(AFIO_DEBUG_NONE)
72 |
73 | Pin define is "STM32_TFT_8bit.h"
74 |
75 | ----
76 |
77 | # Tested TFT
78 | - ILI9325 2.4inch 240x320 TFT-Shield
79 | - ILI9341 2.4inch 240x320 TFT-Shield
80 | - ILI9342 2.4inch 240x320 TFT-Shield
81 | - SPFD5408 2.4inch 240x320 TFT-Shield
82 | - R61505 2.4inch 240x320 TFT-Shield
83 | - ST7783 2.4inch 240x320 TFT-Shield
84 | - LGDP4532 2.4inch 240x320 TFT-Shield
85 | - R61509V 3.6inch 240x400 TFT-Shield
86 | - ST7793 3.6inch 240x400 TFT-Shield
87 | - ILI9481 3.5inch 320x480 TFT-Shield
88 | - ILI9486 3.5inch 320x480 TFT-Shield
89 | - RM68140 3.95inch 320x480 TFT-Shield
90 | - ST7796 3.95inch 320x480 TFT-Shield
91 | - OPEN-SMART ILI9225 TFT-Shield
92 | - OPEN-SMART ILI9327 TFT-Shield
93 | - OPEN-SMART ILI9340 TFT-Shield
94 |
95 | I found that these display cannot follow high-speed GPIO-ON and GPIO-OFF.
96 | - OPEN-SMART S6D1121 16Pin-Parallel
97 | - OPEN-SMART ST7775 16Pin-Parallel
98 | - OPEN-SMART ST7783 16Pin-Parallel
99 | - OPEN-SMART R61509V 16Pin-Parallel
100 | - OPEN-SMART ILI9488 16Pin-Parallel
101 |
102 | ----
103 |
104 | # Setting your TFT's resolution
105 |
106 | If your TFT's resolution is 320x480,
107 | you have to set your TFT's resolution using tft.setResoution.
108 |
109 | Example:
110 | ```
111 | ID = tft.readID();
112 | tft.setResolution(320, 480); // Set your resolution
113 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
114 | tft.begin(ID);
115 | uint32_t width = tft.width();
116 | Serial.print("Width: "); Serial.println(width); // You will see 320
117 | uint32_t height = tft.height();
118 | Serial.print("Height: "); Serial.println(height); // You will see 480
119 | ```
120 |
121 | If your TFT's resolution is 240x400,
122 | you have to set your TFT's resolution and TFT's offset.
123 |
124 | Example:
125 | ```
126 | ID = tft.readID();
127 | tft.setResolution(240, 400); // Set your resolution
128 | tft.setOffset(32); // Set your offset
129 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
130 | tft.begin(ID);
131 | uint32_t width = tft.width();
132 | Serial.print("Width: "); Serial.println(width); // You will see 240
133 | uint32_t height = tft.height();
134 | Serial.print("Height: "); Serial.println(height); // You will see 400
135 | ```
136 |
137 | ---
138 |
139 | - SPFD5408 + ILI9486
140 | 
141 |
142 | - ILI9325 + ILI9481
143 | 
144 |
145 | - ILI9341 + ST7793
146 | 
147 |
148 | - ILI9342 + R61509V
149 | 
150 |
151 | - ST7783 + ST7796
152 | 
153 |
154 | ----
155 |
156 | # F4 board support
157 | If you want more faster, plase use [this](https://github.com/nopnop2002/Arduino-STM32-8bitTFT).
158 | F4 board is very fast.
159 |
160 | ----
161 |
162 | # JPEG Viewer
163 |
164 | Viewer of a JPEG file in the SD card.
165 |
166 | # Software requirement
167 |
168 | - Arduino FAT16/FAT32 Library
169 | https://github.com/greiman/SdFat
170 |
171 | - JPEG decoder library
172 | https://github.com/Bodmer/JPEGDecoder
173 |
174 | # Wirering for TFT built-in SD-CARD Reader
175 |
176 | |TFT||STM32F103|
177 | |:-:|:-:|:-:|
178 | |SD_SS|--|PB12|
179 | |SD_SCK|--|PB13|
180 | |SD_DI|--|PB15|
181 | |SD_DO|--|PB14|
182 | |5V|--|5V(*)|
183 | |3.3V|--|3.3V(*)|
184 | |GND|--|GND|
185 |
186 | \*When a regulator(It's often AMS1117) is mounted on the back, it's operated 5V.
187 | \*When a regulator is NOT mounted on the back, it's operated 3.3V.
188 |
189 | # How to use
190 |
191 | Copy JPEGS file to your SD-CARD.
192 | \*The biggest length of the JPEG file name is 32 character.
193 | Wire TFT built-in SD-CARD Reader to STM32.
194 | Execute JpegView_240x320_SMT32.
195 |
196 | 
197 |
198 |
--------------------------------------------------------------------------------
/STM32_TFT_8bit.h:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for STM32F103
3 | * based on MCUFRIEND_kbv.cpp by David Prentice
4 | * https://github.com/prenticedavid/MCUFRIEND_kbv
5 |
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with this program. If not, see .
18 | */
19 |
20 |
21 | #ifndef _STM32_TFTH_
22 | #define _STM32_TFTH_
23 |
24 | #include "Arduino.h"
25 | #include "Print.h"
26 | #include
27 | #include
28 |
29 |
30 | /*
31 | If you use TFT of different resolution, change this.
32 | */
33 | #define TFTWIDTH 240
34 | #define TFTHEIGHT 320
35 |
36 | // Color definitions
37 | #define BLACK 0x0000 /* 0, 0, 0 */
38 | #define NAVY 0x000F /* 0, 0, 128 */
39 | #define DARKGREEN 0x03E0 /* 0, 128, 0 */
40 | #define DARKCYAN 0x03EF /* 0, 128, 128 */
41 | #define MAROON 0x7800 /* 128, 0, 0 */
42 | #define PURPLE 0x780F /* 128, 0, 128 */
43 | #define OLIVE 0x7BE0 /* 128, 128, 0 */
44 | #define LIGHTGRAY 0xC618 /* 192, 192, 192 */
45 | #define DARKGRAY 0x7BEF /* 128, 128, 128 */
46 | #define BLUE 0x001F /* 0, 0, 255 */
47 | #define GREEN 0x07E0 /* 0, 255, 0 */
48 | #define CYAN 0x07FF /* 0, 255, 255 */
49 | #define RED 0xF800 /* 255, 0, 0 */
50 | #define MAGENTA 0xF81F /* 255, 0, 255 */
51 | #define YELLOW 0xFFE0 /* 255, 255, 0 */
52 | #define WHITE 0xFFFF /* 255, 255, 255 */
53 | #define ORANGE 0xFD20 /* 255, 165, 0 */
54 | #define GREENYELLOW 0xAFE5 /* 173, 255, 47 */
55 | #define PINK 0xF81F
56 | #define GRAY 0x5AEB
57 |
58 | /*
59 | Define pins and Output Data Registers
60 | */
61 |
62 | #define TFT_DATA GPIOA
63 | //Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
64 | //Pin stm32 |PA7|PA6|PA5|PA4|PA3|PA2|PA1|PA0|
65 |
66 | //#define TFT_DATA GPIOC
67 | //Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
68 | //Pin stm32 |PC7|PC6|PC5|PC4|PC3|PC2|PC1|PC0|
69 |
70 | #define TFT_CNTRL GPIOB
71 | //Control pins |RD |WR |RS |CS |RST|
72 | //Pin stm32 |PB3|PB4|PB5|PB6|PB7|
73 | #define TFT_RD PB3
74 | #define TFT_WR PB4
75 | #define TFT_RS PB5
76 | #define TFT_CS PB6
77 | #define TFT_RST PB7
78 | #define TFT_RD_MASK digitalPinToBitMask(TFT_RD)
79 | #define TFT_WR_MASK digitalPinToBitMask(TFT_WR)
80 | #define TFT_RS_MASK digitalPinToBitMask(TFT_RS)
81 | #define TFT_CS_MASK digitalPinToBitMask(TFT_CS)
82 | #define TFT_RST_MASK digitalPinToBitMask(TFT_RST)
83 |
84 | #define RD_ACTIVE TFT_CNTRL->regs->BRR = TFT_RD_MASK
85 | #define RD_IDLE TFT_CNTRL->regs->BSRR = TFT_RD_MASK
86 | #define WR_ACTIVE TFT_CNTRL->regs->BRR = TFT_WR_MASK
87 | #define WR_IDLE TFT_CNTRL->regs->BSRR = TFT_WR_MASK
88 | #define CD_COMMAND TFT_CNTRL->regs->BRR = TFT_RS_MASK
89 | #define CD_DATA TFT_CNTRL->regs->BSRR = TFT_RS_MASK
90 | #define CS_ACTIVE TFT_CNTRL->regs->BRR = TFT_CS_MASK
91 | #define CS_IDLE TFT_CNTRL->regs->BSRR = TFT_CS_MASK
92 | #define RST_ACTIVE TFT_CNTRL->regs->BRR = TFT_RST_MASK
93 | #define RST_IDLE TFT_CNTRL->regs->BSRR = TFT_RST_MASK
94 |
95 | #define RD_STROBE {RD_ACTIVE; RD_IDLE;} // Not used
96 | #define WR_STROBE {WR_ACTIVE; WR_IDLE;}
97 | #define swap(a, b) {int16_t t = a; a = b; b = t;} // Not used
98 |
99 |
100 | class STM32_TFT_8bit : public Adafruit_GFX {
101 |
102 | public:
103 |
104 | STM32_TFT_8bit(void);
105 |
106 | void setResolution(int16_t width, int16_t height);
107 | void setOffset(int16_t offset);
108 | void begin(uint16_t ID);
109 | void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
110 | void fillScreen(uint16_t color);
111 | void drawLine(int16_t x0, int16_t y0,int16_t x1, int16_t y1, uint16_t color);
112 | void drawPixel(int16_t x, int16_t y, uint16_t color);
113 | void pushColors8(uint8_t * block, int16_t n, bool first);
114 | void pushColors(uint16_t * block, int16_t n, bool first);
115 | void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
116 | void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
117 | void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
118 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
119 | int16_t readGRAM(int16_t x, int16_t y, uint16_t * block, int16_t w, int16_t h);
120 | uint16_t readPixel(int16_t x, int16_t y) { uint16_t color; readGRAM(x, y, &color, 1, 1); return color; }
121 | void setRotation(uint8_t r);
122 | void vertScroll(int16_t top, int16_t scrollines, int16_t offset);
123 | void invertDisplay(boolean i);
124 |
125 | /* These are not for current use, 8-bit protocol only! */
126 | //uint8_t readdata(void),
127 | uint8_t readcommand8(uint8_t reg);
128 | uint16_t read16bits(void);
129 | uint16_t readReg16(uint16_t reg);
130 | uint16_t readReg16Index(uint16_t reg, int8_t index);
131 | uint32_t readReg32(uint16_t reg);
132 | uint32_t readReg40(uint16_t reg);
133 | uint16_t readID(void);
134 |
135 |
136 | private:
137 | //uint8_t tabcolor;
138 | uint8_t read8(void);
139 | void setReadDataBus(void);
140 | void setWriteDataBus(void);
141 | void write8(uint8_t);
142 | void writeCmdByte(uint8_t c);
143 | void writeCmdWord(uint16_t c);
144 | void WriteCmd(uint16_t c);
145 | void writeDataByte(uint8_t d);
146 | void writeDataWord(uint16_t d);
147 | void WriteCmdData(uint16_t cmd, uint16_t dat);
148 | void WriteCmdParamN(uint8_t cmd, int8_t N, uint8_t * block);
149 | void WriteCmdParam4(uint8_t cmd, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4);
150 | void init_table(const void *table, int16_t size);
151 | void init_table16(const void *table, int16_t size);
152 | uint16_t _lcd_xor, _lcd_capable;
153 | uint16_t _lcd_ID, _lcd_rev, _lcd_madctl, _lcd_drivOut, _MC, _MP, _MW, _SC, _EC, _SP, _EP;
154 | int16_t _lcd_width = 0, _lcd_height = 0, _lcd_offset=0;
155 | };
156 |
157 | #endif //endif of the header file
158 |
--------------------------------------------------------------------------------
/examples/ClockAnalog_STM32/ClockAnalog_STM32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | An example analogue clock using a TFT LCD screen to show the time
3 | use of some of the drawing commands with the Adafruit_GFX library.
4 | For a more accurate clock, it would be better to use the RTC library.
5 | But this is just a demo.
6 |
7 | Gilchrist 6/2/2014 1.0
8 | Updated by Alan Senior 18/1/2015
9 | Updated by nopnop2002 5/1/2018
10 | */
11 |
12 |
13 | #include
14 | #include "STM32_TFT_8bit.h"
15 |
16 | STM32_TFT_8bit tft;
17 |
18 | float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0; // Saved H, M, S x & y multipliers
19 | float sdeg=0, mdeg=0, hdeg=0;
20 | uint16_t osx=120, osy=120, omx=120, omy=120, ohx=120, ohy=120; // Saved H, M, S x & y coords
21 | uint16_t x00=0, x11=0, y00=0, y11=0;
22 | uint32_t targetTime = 0; // for next 1 second timeout
23 | uint8_t hh,mm,ss;
24 | boolean initial = 1;
25 |
26 | void setup(void) {
27 | delay(1000);
28 | Serial.begin(9600);
29 | hh=conv2d(__TIME__);
30 | mm=conv2d(__TIME__+3);
31 | ss=conv2d(__TIME__+6); // Get H, M, S from compile time
32 | uint16_t ID = tft.readID();
33 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
34 | tft.begin(ID);
35 | uint16_t wid = tft.width();
36 | uint16_t ht = tft.height();
37 | Serial.println("width=" + String(wid) + " height=" + String(ht));
38 |
39 | if (wid < ht) {
40 | tft.setRotation(0);
41 | } else {
42 | tft.setRotation(1);
43 | }
44 | tft.fillScreen(GRAY);
45 | tft.setTextColor(WHITE, GRAY); // Adding a background colour erases previous text automatically
46 |
47 | // Draw clock face
48 | tft.fillCircle(120, 120, 118, GREEN);
49 | tft.fillCircle(120, 120, 110, BLACK);
50 |
51 | // Draw 12 lines
52 | for(int i = 0; i<360; i+= 30) {
53 | sx = cos((i-90)*0.0174532925);
54 | sy = sin((i-90)*0.0174532925);
55 | x00 = sx*114+120;
56 | y00 = sy*114+120;
57 | x11 = sx*100+120;
58 | y11 = sy*100+120;
59 |
60 | tft.drawLine(x00, y00, x11, y11, GREEN);
61 | }
62 |
63 | // Draw 60 dots
64 | for(int i = 0; i<360; i+= 6) {
65 | sx = cos((i-90)*0.0174532925);
66 | sy = sin((i-90)*0.0174532925);
67 | x00 = sx*102+120;
68 | y00 = sy*102+120;
69 | // Draw minute markers
70 | tft.drawPixel(x00, y00, WHITE);
71 |
72 | // Draw main quadrant dots
73 | if(i==0 || i==180) tft.fillCircle(x00, y00, 2, WHITE);
74 | if(i==90 || i==270) tft.fillCircle(x00, y00, 2, WHITE);
75 | }
76 |
77 | tft.fillCircle(120, 121, 3, WHITE);
78 | tft.setCursor(20, 260);
79 | tft.setTextSize(3);
80 | tft.println(__DATE__);
81 | targetTime = millis() + 1000;
82 | }
83 |
84 | void loop() {
85 |
86 | if (targetTime < millis()) {
87 | targetTime = millis()+1000;
88 | ss++; // Advance second
89 | if (ss==60) {
90 | ss=0;
91 | mm++; // Advance minute
92 | if(mm>59) {
93 | mm=0;
94 | hh++; // Advance hour
95 | if (hh>23) {
96 | hh=0;
97 | }
98 | }
99 | }
100 | #ifdef _DEBUG_
101 | Serial.print("hh=");
102 | Serial.print(hh);
103 | Serial.print(" mm=");
104 | Serial.print(mm);
105 | Serial.print(" ss=");
106 | Serial.println(ss);
107 | #endif
108 |
109 | // Pre-compute hand degrees, x & y coords for a fast screen update
110 | sdeg = ss*6; // 0-59 -> 0-354
111 | mdeg = mm*6+sdeg*0.01666667; // 0-59 -> 0-360 - includes seconds
112 | hdeg = hh*30+mdeg*0.0833333; // 0-11 -> 0-360 - includes minutes and seconds
113 | hx = cos((hdeg-90)*0.0174532925);
114 | hy = sin((hdeg-90)*0.0174532925);
115 | mx = cos((mdeg-90)*0.0174532925);
116 | my = sin((mdeg-90)*0.0174532925);
117 | sx = cos((sdeg-90)*0.0174532925);
118 | sy = sin((sdeg-90)*0.0174532925);
119 |
120 | if (ss==0 || initial) {
121 | initial = 0;
122 | // Erase hour and minute hand positions every minute
123 | tft.drawLine(ohx, ohy, 120, 121, BLACK);
124 | ohx = hx*62+121;
125 | ohy = hy*62+121;
126 | tft.drawLine(omx, omy, 120, 121, BLACK);
127 | omx = mx*84+120;
128 | omy = my*84+121;
129 | }
130 |
131 | // Redraw new hand positions, hour and minute hands not erased here to avoid flicker
132 | tft.drawLine(osx, osy, 120, 121, BLACK);
133 | osx = sx*90+121;
134 | osy = sy*90+121;
135 | tft.drawLine(osx, osy, 120, 121, RED);
136 | tft.drawLine(ohx, ohy, 120, 121, WHITE);
137 | tft.drawLine(omx, omy, 120, 121, WHITE);
138 | tft.drawLine(osx, osy, 120, 121, RED);
139 |
140 | tft.fillCircle(120, 121, 3, RED);
141 | }
142 | }
143 |
144 | static uint8_t conv2d(const char* p) {
145 | uint8_t v = 0;
146 | if ('0' <= *p && *p <= '9')
147 | v = *p - '0';
148 | return 10 * v + *++p - '0';
149 | }
150 |
151 |
--------------------------------------------------------------------------------
/examples/CubeDemo_STM32/CubeDemo_STM32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * Cube demo for STM32
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | #include
19 | #include "STM32_TFT_8bit.h"
20 |
21 | STM32_TFT_8bit tft;
22 |
23 | #define BACK_COLOR WHITE // You can change
24 |
25 | const float sin_d[] = {
26 | 0, 0.17, 0.34, 0.5, 0.64, 0.77, 0.87, 0.94, 0.98, 1, 0.98, 0.94,
27 | 0.87, 0.77, 0.64, 0.5, 0.34, 0.17, 0, -0.17, -0.34, -0.5, -0.64,
28 | -0.77, -0.87, -0.94, -0.98, -1, -0.98, -0.94, -0.87, -0.77,
29 | -0.64, -0.5, -0.34, -0.17
30 | };
31 | const float cos_d[] = {
32 | 1, 0.98, 0.94, 0.87, 0.77, 0.64, 0.5, 0.34, 0.17, 0, -0.17, -0.34,
33 | -0.5, -0.64, -0.77, -0.87, -0.94, -0.98, -1, -0.98, -0.94, -0.87,
34 | -0.77, -0.64, -0.5, -0.34, -0.17, 0, 0.17, 0.34, 0.5, 0.64, 0.77,
35 | 0.87, 0.94, 0.98
36 | };
37 | const float d = 5;
38 | float cube1_px[] = {
39 | -d, d, d, -d, -d, d, d, -d
40 | };
41 | float cube1_py[] = {
42 | -d, -d, d, d, -d, -d, d, d
43 | };
44 | float cube1_pz[] = {
45 | -d, -d, -d, -d, d, d, d, d
46 | };
47 |
48 | float cube1_p2x[] = {
49 | 0, 0, 0, 0, 0, 0, 0, 0
50 | };
51 | float cube1_p2y[] = {
52 | 0, 0, 0, 0, 0, 0, 0, 0
53 | };
54 |
55 | int cube1_r[] = {
56 | 0, 0, 0
57 | };
58 | const float d2 = 10;
59 | float cube2_px[] = {
60 | -d2, d2, d2, -d2, -d2, d2, d2, -d2
61 | };
62 | float cube2_py[] = {
63 | -d2, -d2, d2, d2, -d2, -d2, d2, d2
64 | };
65 | float cube2_pz[] = {
66 | -d2, -d2, -d2, -d2, d2, d2, d2, d2
67 | };
68 |
69 | float cube2_p2x[] = {
70 | 0, 0, 0, 0, 0, 0, 0, 0
71 | };
72 | float cube2_p2y[] = {
73 | 0, 0, 0, 0, 0, 0, 0, 0
74 | };
75 |
76 | int cube2_r[] = {
77 | 0, 0, 0
78 | };
79 |
80 | uint16_t cube1_x, cube1_y, cube2_x, cube2_y, cube1_color, cube2_color;
81 |
82 |
83 | void cube(float *px, float *py, float *pz, float *p2x, float *p2y, int *r, uint16_t *x, uint16_t *y, uint16_t *color) {
84 |
85 | for (int i = 0; i < 3; i++) {
86 | tft.drawLine(p2x[i], p2y[i], p2x[i + 1], p2y[i + 1], BACK_COLOR);
87 | tft.drawLine(p2x[i + 4], p2y[i + 4], p2x[i + 5], p2y[i + 5], BACK_COLOR);
88 | tft.drawLine(p2x[i], p2y[i], p2x[i + 4], p2y[i + 4], BACK_COLOR);
89 | }
90 | tft.drawLine(p2x[3], p2y[3], p2x[0], p2y[0], BACK_COLOR);
91 | tft.drawLine(p2x[7], p2y[7], p2x[4], p2y[4], BACK_COLOR);
92 | tft.drawLine(p2x[3], p2y[3], p2x[7], p2y[7], BACK_COLOR);
93 |
94 | r[0] = r[0] + 1;
95 | r[1] = r[1] + 1;
96 | if (r[0] == 36) r[0] = 0;
97 | if (r[1] == 36) r[1] = 0;
98 | if (r[2] == 36) r[2] = 0;
99 | for (int i = 0; i < 8; i++)
100 | {
101 | float px2 = px[i];
102 | float py2 = cos_d[r[0]] * py[i] - sin_d[r[0]] * pz[i];
103 | float pz2 = sin_d[r[0]] * py[i] + cos_d[r[0]] * pz[i];
104 |
105 | float px3 = cos_d[r[1]] * px2 + sin_d[r[1]] * pz2;
106 | float py3 = py2;
107 | float pz3 = -sin_d[r[1]] * px2 + cos_d[r[1]] * pz2;
108 |
109 | float ax = cos_d[r[2]] * px3 - sin_d[r[2]] * py3;
110 | float ay = sin_d[r[2]] * px3 + cos_d[r[2]] * py3;
111 | float az = pz3 - 190;
112 |
113 | p2x[i] = *x + ax * 500 / az;
114 | p2y[i] = *y + ay * 500 / az;
115 | }
116 |
117 | for (int i = 0; i < 3; i++) {
118 | tft.drawLine(p2x[i], p2y[i], p2x[i + 1], p2y[i + 1], *color);
119 | tft.drawLine(p2x[i + 4], p2y[i + 4], p2x[i + 5], p2y[i + 5], *color);
120 | tft.drawLine(p2x[i], p2y[i], p2x[i + 4], p2y[i + 4], *color);
121 | }
122 | tft.drawLine(p2x[3], p2y[3], p2x[0], p2y[0], *color);
123 | tft.drawLine(p2x[7], p2y[7], p2x[4], p2y[4], *color);
124 | tft.drawLine(p2x[3], p2y[3], p2x[7], p2y[7], *color);
125 | }
126 |
127 |
128 | void setup() {
129 | delay(1000);
130 | Serial.begin(9600);
131 | Serial.println("STM32_TFT_8bit Test!");
132 |
133 | uint32_t ID = tft.readID();
134 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
135 | tft.begin(ID);
136 |
137 | uint32_t width = tft.width();
138 | Serial.print("Width: "); Serial.println(width);
139 | uint32_t height = tft.height();
140 | Serial.print("Height: "); Serial.println(height);
141 |
142 | tft.fillScreen(BACK_COLOR);
143 | cube1_x = ((tft.width()) / 4);
144 | cube1_y = ((tft.height()) / 4);
145 | cube2_x = ((tft.width()) / 2);
146 | cube2_y = ((tft.height()) / 2);
147 | cube1_color = BLACK;
148 | cube2_color = RED;
149 |
150 | uint16_t x = 0;
151 | for (uint32_t n = 247583650 ; n > 247400000 ; n--) {
152 | x = sqrt (n);
153 | cube(cube1_px, cube1_py, cube1_pz, cube1_p2x, cube1_p2y, cube1_r, &cube1_x, &cube1_y, &cube1_color);
154 | cube(cube2_px, cube2_py, cube2_pz, cube2_p2x, cube2_p2y, cube2_r, &cube2_x, &cube2_y, &cube2_color);
155 | }
156 |
157 | }
158 |
159 | void loop() {
160 | }
161 |
--------------------------------------------------------------------------------
/examples/GraphicsTest_240x320_SMT32/GraphicsTest_240x320_SMT32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for STM32F103
3 | * based on MCUFRIEND_kbv.cpp by David Prentice
4 | * https://github.com/prenticedavid/MCUFRIEND_kbv
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with this program. If not, see .
18 | */
19 |
20 |
21 | #include
22 | #include "STM32_TFT_8bit.h"
23 |
24 | STM32_TFT_8bit tft;
25 |
26 | uint32_t ID;
27 |
28 | void setup() {
29 | delay(1000);
30 | Serial.begin(9600);
31 | Serial.println("STM32_TFT_8bit Test!");
32 |
33 | ID = tft.readID();
34 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
35 | tft.begin(ID);
36 |
37 | uint32_t width = tft.width();
38 | Serial.print("Width: "); Serial.println(width);
39 | uint32_t height = tft.height();
40 | Serial.print("Height: "); Serial.println(height);
41 |
42 | Serial.println(F("Benchmark Time (microseconds)"));
43 |
44 | Serial.print(F("Screen fill "));
45 | Serial.println(testFillScreen());
46 | delay(500);
47 |
48 | Serial.print(F("Text "));
49 | Serial.println(testText(ID));
50 | delay(3000);
51 |
52 | Serial.print(F("Lines "));
53 | Serial.println(testLines(CYAN));
54 | delay(500);
55 |
56 | Serial.print(F("Horiz/Vert Lines "));
57 | Serial.println(testFastLines(RED, BLUE));
58 | delay(500);
59 |
60 | Serial.print(F("Rectangles (outline) "));
61 | Serial.println(testRects(GREEN));
62 | delay(500);
63 |
64 | Serial.print(F("Rectangles (filled) "));
65 | Serial.println(testFilledRects(YELLOW, MAGENTA));
66 | delay(500);
67 |
68 | Serial.print(F("Circles (filled) "));
69 | Serial.println(testFilledCircles(10, MAGENTA));
70 |
71 | Serial.print(F("Circles (outline) "));
72 | Serial.println(testCircles(10, WHITE));
73 | delay(500);
74 |
75 | Serial.print(F("Triangles (outline) "));
76 | Serial.println(testTriangles());
77 | delay(500);
78 |
79 | Serial.print(F("Triangles (filled) "));
80 | Serial.println(testFilledTriangles());
81 | delay(500);
82 |
83 | Serial.print(F("Rounded rects (outline) "));
84 | Serial.println(testRoundRects());
85 | delay(500);
86 |
87 | Serial.print(F("Rounded rects (filled) "));
88 | Serial.println(testFilledRoundRects());
89 | delay(500);
90 |
91 | Serial.println(F("Done!"));
92 |
93 | }
94 |
95 |
96 | void loop(void) {
97 | for(uint8_t rotation=0; rotation<4; rotation++) {
98 | tft.setRotation(rotation);
99 | testText(ID);
100 | delay(1000);
101 | }
102 | }
103 |
104 | unsigned long testFillScreen() {
105 | unsigned long start = micros();
106 | tft.fillScreen(BLACK);
107 | tft.fillScreen(RED);
108 | tft.fillScreen(GREEN);
109 | tft.fillScreen(BLUE);
110 | tft.fillScreen(BLACK);
111 | return micros() - start;
112 | }
113 |
114 | unsigned long testText(uint32_t ID) {
115 | tft.fillScreen(BLACK);
116 | unsigned long start = micros();
117 | tft.setCursor(0, 0);
118 | tft.setTextColor(WHITE); tft.setTextSize(1);
119 | tft.println("Hello World!");
120 | tft.setTextColor(YELLOW); tft.setTextSize(2);
121 | tft.println(1234.56);
122 | tft.setTextColor(RED); tft.setTextSize(3);
123 | tft.print("TFT is ");
124 | tft.println(ID, HEX);
125 | tft.println();
126 | tft.setTextColor(GREEN);
127 | tft.setTextSize(5);
128 | tft.println("Groop");
129 | tft.setTextSize(2);
130 | tft.println("I implore thee,");
131 | tft.setTextSize(1);
132 | tft.println("my foonting turlingdromes.");
133 | tft.println("And hooptiously drangle me");
134 | tft.println("with crinkly bindlewurdles,");
135 | tft.println("Or I will rend thee");
136 | tft.println("in the gobberwarts");
137 | tft.println("with my blurglecruncheon,");
138 | tft.println("see if I don't!");
139 | return micros() - start;
140 | }
141 |
142 | unsigned long testLines(uint16_t color) {
143 | unsigned long start, t;
144 | int x1, y1, x2, y2,
145 | w = tft.width(),
146 | h = tft.height();
147 |
148 | tft.fillScreen(BLACK);
149 |
150 | x1 = y1 = 0;
151 | y2 = h - 1;
152 | start = micros();
153 | for(x2=0; x20; i-=6) {
231 | i2 = i / 2;
232 | start = micros();
233 | tft.fillRect(cx-i2, cy-i2, i, i, color1);
234 | t += micros() - start;
235 | // Outlines are not included in timing results
236 | tft.drawRect(cx-i2, cy-i2, i, i, color2);
237 | }
238 |
239 | return t;
240 | }
241 |
242 | unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
243 | unsigned long start;
244 | int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
245 |
246 | tft.fillScreen(BLACK);
247 | start = micros();
248 | for(x=radius; x10; i-=5) {
302 | start = micros();
303 | tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
304 | BLACK);
305 | t += micros() - start;
306 | tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
307 | MAROON);
308 | }
309 |
310 | return t;
311 | }
312 |
313 | unsigned long testRoundRects() {
314 | unsigned long start;
315 | int w, i, i2,
316 | cx = tft.width() / 2 - 1,
317 | cy = tft.height() / 2 - 1;
318 |
319 | tft.fillScreen(BLACK);
320 | w = min(tft.width(), tft.height());
321 | start = micros();
322 | for(i=0; i20; i-=6) {
339 | i2 = i / 2;
340 | tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, DARKCYAN);
341 | }
342 |
343 | return micros() - start;
344 | }
345 |
--------------------------------------------------------------------------------
/examples/GraphicsTest_240x400_SMT32/GraphicsTest_240x400_SMT32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for STM32F103
3 | * based on MCUFRIEND_kbv.cpp by David Prentice
4 | * https://github.com/prenticedavid/MCUFRIEND_kbv
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with this program. If not, see .
18 | */
19 |
20 |
21 | #include
22 | #include "STM32_TFT_8bit.h"
23 |
24 | STM32_TFT_8bit tft;
25 |
26 | uint32_t ID;
27 |
28 | void setup() {
29 | delay(1000);
30 | Serial.begin(9600);
31 | Serial.println("STM32_TFT_8bit Test!");
32 |
33 | ID = tft.readID();
34 | // Set your TFT's resolution
35 | tft.setResolution(240, 400); // Set your resolution
36 | // Set your TFT's offset
37 | tft.setOffset(32); // Set your offset
38 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
39 | tft.begin(ID);
40 |
41 | uint32_t width = tft.width();
42 | Serial.print("Width: "); Serial.println(width);
43 | uint32_t height = tft.height();
44 | Serial.print("Height: "); Serial.println(height);
45 |
46 | Serial.println(F("Benchmark Time (microseconds)"));
47 |
48 | Serial.print(F("Screen fill "));
49 | Serial.println(testFillScreen());
50 | delay(500);
51 |
52 | Serial.print(F("Text "));
53 | Serial.println(testText(ID));
54 | delay(3000);
55 |
56 | Serial.print(F("Lines "));
57 | Serial.println(testLines(CYAN));
58 | delay(500);
59 |
60 | Serial.print(F("Horiz/Vert Lines "));
61 | Serial.println(testFastLines(RED, BLUE));
62 | delay(500);
63 |
64 | Serial.print(F("Rectangles (outline) "));
65 | Serial.println(testRects(GREEN));
66 | delay(500);
67 |
68 | Serial.print(F("Rectangles (filled) "));
69 | Serial.println(testFilledRects(YELLOW, MAGENTA));
70 | delay(500);
71 |
72 | Serial.print(F("Circles (filled) "));
73 | Serial.println(testFilledCircles(10, MAGENTA));
74 |
75 | Serial.print(F("Circles (outline) "));
76 | Serial.println(testCircles(10, WHITE));
77 | delay(500);
78 |
79 | Serial.print(F("Triangles (outline) "));
80 | Serial.println(testTriangles());
81 | delay(500);
82 |
83 | Serial.print(F("Triangles (filled) "));
84 | Serial.println(testFilledTriangles());
85 | delay(500);
86 |
87 | Serial.print(F("Rounded rects (outline) "));
88 | Serial.println(testRoundRects());
89 | delay(500);
90 |
91 | Serial.print(F("Rounded rects (filled) "));
92 | Serial.println(testFilledRoundRects());
93 | delay(500);
94 |
95 | Serial.println(F("Done!"));
96 |
97 | }
98 |
99 |
100 | void loop(void) {
101 | for(uint8_t rotation=0; rotation<4; rotation++) {
102 | tft.setRotation(rotation);
103 | testText(ID);
104 | delay(1000);
105 | }
106 | }
107 |
108 | unsigned long testFillScreen() {
109 | unsigned long start = micros();
110 | tft.fillScreen(BLACK);
111 | tft.fillScreen(RED);
112 | tft.fillScreen(GREEN);
113 | tft.fillScreen(BLUE);
114 | tft.fillScreen(BLACK);
115 | return micros() - start;
116 | }
117 |
118 | unsigned long testText(uint32_t ID) {
119 | tft.fillScreen(BLACK);
120 | unsigned long start = micros();
121 | tft.setCursor(0, 0);
122 | tft.setTextColor(WHITE); tft.setTextSize(1);
123 | tft.println("Hello World!");
124 | tft.setTextColor(YELLOW); tft.setTextSize(2);
125 | tft.println(1234.56);
126 | tft.setTextColor(RED); tft.setTextSize(3);
127 | tft.print("TFT is ");
128 | tft.println(ID, HEX);
129 | tft.println();
130 | tft.setTextColor(GREEN);
131 | tft.setTextSize(5);
132 | tft.println("Groop");
133 | tft.setTextSize(2);
134 | tft.println("I implore thee,");
135 | tft.setTextSize(1);
136 | tft.println("my foonting turlingdromes.");
137 | tft.println("And hooptiously drangle me");
138 | tft.println("with crinkly bindlewurdles,");
139 | tft.println("Or I will rend thee");
140 | tft.println("in the gobberwarts");
141 | tft.println("with my blurglecruncheon,");
142 | tft.println("see if I don't!");
143 | return micros() - start;
144 | }
145 |
146 | unsigned long testLines(uint16_t color) {
147 | unsigned long start, t;
148 | int x1, y1, x2, y2,
149 | w = tft.width(),
150 | h = tft.height();
151 |
152 | tft.fillScreen(BLACK);
153 |
154 | x1 = y1 = 0;
155 | y2 = h - 1;
156 | start = micros();
157 | for(x2=0; x20; i-=6) {
235 | i2 = i / 2;
236 | start = micros();
237 | tft.fillRect(cx-i2, cy-i2, i, i, color1);
238 | t += micros() - start;
239 | // Outlines are not included in timing results
240 | tft.drawRect(cx-i2, cy-i2, i, i, color2);
241 | }
242 |
243 | return t;
244 | }
245 |
246 | unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
247 | unsigned long start;
248 | int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
249 |
250 | tft.fillScreen(BLACK);
251 | start = micros();
252 | for(x=radius; x10; i-=5) {
306 | start = micros();
307 | tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
308 | BLACK);
309 | t += micros() - start;
310 | tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
311 | MAROON);
312 | }
313 |
314 | return t;
315 | }
316 |
317 | unsigned long testRoundRects() {
318 | unsigned long start;
319 | int w, i, i2,
320 | cx = tft.width() / 2 - 1,
321 | cy = tft.height() / 2 - 1;
322 |
323 | tft.fillScreen(BLACK);
324 | w = min(tft.width(), tft.height());
325 | start = micros();
326 | for(i=0; i20; i-=6) {
343 | i2 = i / 2;
344 | tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, DARKCYAN);
345 | }
346 |
347 | return micros() - start;
348 | }
349 |
--------------------------------------------------------------------------------
/examples/GraphicsTest_320x480_SMT32/GraphicsTest_320x480_SMT32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for STM32F103
3 | * based on MCUFRIEND_kbv.cpp by David Prentice
4 | * https://github.com/prenticedavid/MCUFRIEND_kbv
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with this program. If not, see .
18 | */
19 |
20 |
21 | #include
22 | #include "STM32_TFT_8bit.h"
23 |
24 | STM32_TFT_8bit tft;
25 |
26 | uint32_t ID;
27 |
28 | void setup() {
29 | delay(1000);
30 | Serial.begin(9600);
31 | Serial.println("STM32_TFT_8bit Test!");
32 |
33 | ID = tft.readID();
34 | tft.setResolution(320, 480); // Set your resolution
35 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
36 | tft.begin(ID);
37 |
38 | uint32_t width = tft.width();
39 | Serial.print("Width: "); Serial.println(width);
40 | uint32_t height = tft.height();
41 | Serial.print("Height: "); Serial.println(height);
42 |
43 | Serial.println(F("Benchmark Time (microseconds)"));
44 |
45 | Serial.print(F("Screen fill "));
46 | Serial.println(testFillScreen());
47 | delay(500);
48 |
49 | Serial.print(F("Text "));
50 | Serial.println(testText(ID));
51 | delay(3000);
52 |
53 | Serial.print(F("Lines "));
54 | Serial.println(testLines(CYAN));
55 | delay(500);
56 |
57 | Serial.print(F("Horiz/Vert Lines "));
58 | Serial.println(testFastLines(RED, BLUE));
59 | delay(500);
60 |
61 | Serial.print(F("Rectangles (outline) "));
62 | Serial.println(testRects(GREEN));
63 | delay(500);
64 |
65 | Serial.print(F("Rectangles (filled) "));
66 | Serial.println(testFilledRects(YELLOW, MAGENTA));
67 | delay(500);
68 |
69 | Serial.print(F("Circles (filled) "));
70 | Serial.println(testFilledCircles(10, MAGENTA));
71 |
72 | Serial.print(F("Circles (outline) "));
73 | Serial.println(testCircles(10, WHITE));
74 | delay(500);
75 |
76 | Serial.print(F("Triangles (outline) "));
77 | Serial.println(testTriangles());
78 | delay(500);
79 |
80 | Serial.print(F("Triangles (filled) "));
81 | Serial.println(testFilledTriangles());
82 | delay(500);
83 |
84 | Serial.print(F("Rounded rects (outline) "));
85 | Serial.println(testRoundRects());
86 | delay(500);
87 |
88 | Serial.print(F("Rounded rects (filled) "));
89 | Serial.println(testFilledRoundRects());
90 | delay(500);
91 |
92 | Serial.println(F("Done!"));
93 |
94 | }
95 |
96 |
97 | void loop(void) {
98 | for(uint8_t rotation=0; rotation<4; rotation++) {
99 | tft.setRotation(rotation);
100 | testText(ID);
101 | delay(1000);
102 | }
103 | }
104 |
105 | unsigned long testFillScreen() {
106 | unsigned long start = micros();
107 | tft.fillScreen(BLACK);
108 | tft.fillScreen(RED);
109 | tft.fillScreen(GREEN);
110 | tft.fillScreen(BLUE);
111 | tft.fillScreen(BLACK);
112 | return micros() - start;
113 | }
114 |
115 | unsigned long testText(uint32_t ID) {
116 | tft.fillScreen(BLACK);
117 | unsigned long start = micros();
118 | tft.setCursor(0, 0);
119 | tft.setTextColor(WHITE); tft.setTextSize(1);
120 | tft.println("Hello World!");
121 | tft.setTextColor(YELLOW); tft.setTextSize(2);
122 | tft.println(1234.56);
123 | tft.setTextColor(RED); tft.setTextSize(3);
124 | tft.print("TFT is ");
125 | tft.println(ID, HEX);
126 | tft.println();
127 | tft.setTextColor(GREEN);
128 | tft.setTextSize(5);
129 | tft.println("Groop");
130 | tft.setTextSize(2);
131 | tft.println("I implore thee,");
132 | tft.setTextSize(1);
133 | tft.println("my foonting turlingdromes.");
134 | tft.println("And hooptiously drangle me");
135 | tft.println("with crinkly bindlewurdles,");
136 | tft.println("Or I will rend thee");
137 | tft.println("in the gobberwarts");
138 | tft.println("with my blurglecruncheon,");
139 | tft.println("see if I don't!");
140 | return micros() - start;
141 | }
142 |
143 | unsigned long testLines(uint16_t color) {
144 | unsigned long start, t;
145 | int x1, y1, x2, y2,
146 | w = tft.width(),
147 | h = tft.height();
148 |
149 | tft.fillScreen(BLACK);
150 |
151 | x1 = y1 = 0;
152 | y2 = h - 1;
153 | start = micros();
154 | for(x2=0; x20; i-=6) {
232 | i2 = i / 2;
233 | start = micros();
234 | tft.fillRect(cx-i2, cy-i2, i, i, color1);
235 | t += micros() - start;
236 | // Outlines are not included in timing results
237 | tft.drawRect(cx-i2, cy-i2, i, i, color2);
238 | }
239 |
240 | return t;
241 | }
242 |
243 | unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
244 | unsigned long start;
245 | int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
246 |
247 | tft.fillScreen(BLACK);
248 | start = micros();
249 | for(x=radius; x10; i-=5) {
303 | start = micros();
304 | tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
305 | BLACK);
306 | t += micros() - start;
307 | tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
308 | MAROON);
309 | }
310 |
311 | return t;
312 | }
313 |
314 | unsigned long testRoundRects() {
315 | unsigned long start;
316 | int w, i, i2,
317 | cx = tft.width() / 2 - 1,
318 | cy = tft.height() / 2 - 1;
319 |
320 | tft.fillScreen(BLACK);
321 | w = min(tft.width(), tft.height());
322 | start = micros();
323 | for(i=0; i20; i-=6) {
340 | i2 = i / 2;
341 | tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, DARKCYAN);
342 | }
343 |
344 | return micros() - start;
345 | }
346 |
--------------------------------------------------------------------------------
/examples/JpegView_240x320_SMT32/JPEG_Functions.ino:
--------------------------------------------------------------------------------
1 | /*====================================================================================
2 | This sketch contains support functions to render the Jpeg images.
3 |
4 | Created by Bodmer 5th Feb 2017
5 | Updated by nopnop2002 19/4/2018
6 | ==================================================================================*/
7 |
8 | // Return the minimum of two values a and b
9 | #define minimum(a,b) (((a) < (b)) ? (a) : (b))
10 | #define maximum(a,b) (((a) > (b)) ? (a) : (b))
11 |
12 | //====================================================================================
13 | // This function opens the array and primes the decoder
14 | //====================================================================================
15 | void drawArrayJpeg(const uint8_t arrayname[], uint32_t array_size, int xpos, int ypos) {
16 |
17 | boolean decoded = JpegDec.decodeArray(arrayname, array_size);
18 |
19 | if (decoded) {
20 | // print information about the image to the serial port
21 | jpegInfo();
22 |
23 | // render the image onto the screen at given coordinates
24 | jpegRender(xpos, ypos, 0);
25 | }
26 | else {
27 | Serial.println("Jpeg file format not supported!");
28 | }
29 | }
30 |
31 | //====================================================================================
32 | // This function opens the Filing System Jpeg image file and primes the decoder
33 | //
34 | // options : OPT_REDUCTION
35 | // If it's large than screen, it would reduce so that it may fit into a screen.
36 | // OPT_CENTER
37 | // If it's smaller than screen, it would show to the center of the screen.
38 | //====================================================================================
39 | void drawFSJpeg(const char *filename, int xpos, int ypos, int options) {
40 |
41 | Serial.println("=====================================");
42 | Serial.print("Drawing file: "); Serial.println(filename);
43 | Serial.println("=====================================");
44 |
45 | // Open the file (the Jpeg decoder library will close it)
46 | File jpgFile = SD.open( filename, FILE_READ); // file handle reference for SD library
47 |
48 | if ( !jpgFile ) {
49 | Serial.print("ERROR: File \""); Serial.print(filename); Serial.println ("\" not found!");
50 | return;
51 | }
52 |
53 | // To initialise the decoder and provide the file, we can use one of the following methods:
54 | boolean decoded = JpegDec.decodeSdFile(jpgFile); // we can pass the SD file handle to the decoder,
55 | //boolean decoded = JpegDec.decodeFsFile(filename); // or we can pass the filename
56 | // The filename can be a String or character array
57 | if (decoded) {
58 | // print information about the image to the serial port
59 | jpegInfo();
60 |
61 | // render the image onto the screen at given coordinates
62 | jpegRender(xpos, ypos, options);
63 | }
64 | else {
65 | Serial.println("Jpeg file format not supported!");
66 | }
67 | }
68 |
69 | //====================================================================================
70 | // Decode and paint onto the TFT screen
71 | //====================================================================================
72 | void jpegRender(int xpos, int ypos, int options) {
73 |
74 | //if (options & OPT_REDUCTION) Serial.println("OPT_REDUCTION");
75 | //if (options & OPT_CENTER) Serial.println("OPT_CENTER");
76 | // retrieve infomration about the image
77 | uint16_t *pImg;
78 | uint16_t mcu_w = JpegDec.MCUWidth;
79 | uint16_t mcu_h = JpegDec.MCUHeight;
80 | uint32_t max_x = JpegDec.width;
81 | uint32_t max_y = JpegDec.height;
82 | //Serial.println("mcu_w=" + String(mcu_w));
83 | //Serial.println("mcu_h=" + String(mcu_h));
84 | //Serial.println("max_x=" + String(max_x));
85 | //Serial.println("max_y=" + String(max_y));
86 |
87 | uint16_t szImg2 = mcu_w * mcu_h;
88 | uint16_t *pImg2;
89 | pImg2 = (uint16_t *) malloc(szImg2*2);
90 |
91 | uint32_t tft_width = tft.width();
92 | //Serial.print("tft_width: "); Serial.println(tft_width);
93 | uint32_t tft_height = tft.height();
94 | //Serial.print("tft_height: "); Serial.println(tft_height);
95 |
96 | int reduction_x = 1;
97 | int reduction_y = 1;
98 | if (max_x > tft_width) {
99 | reduction_x = (max_x / tft_width);
100 | if (max_x % tft_width) reduction_x++;
101 | }
102 | if (max_y > tft_height) {
103 | reduction_y = (max_y / tft_height);
104 | if (max_y % tft_height) reduction_y++;
105 | }
106 | //Serial.println("reduction_x=" + String(reduction_x));
107 | //Serial.println("reduction_y=" + String(reduction_y));
108 | int reduction = maximum(reduction_x, reduction_y);
109 | //Serial.println("reduction=" + String(reduction));
110 |
111 | // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
112 | // Typically these MCUs are 16x16 pixel blocks
113 | // Determine the width and height of the right and bottom edge image blocks
114 | uint32_t min_w = minimum(mcu_w, max_x % mcu_w);
115 | uint32_t min_h = minimum(mcu_h, max_y % mcu_h);
116 | //Serial.println("min_w=" + String(min_w));
117 | //Serial.println("min_h=" + String(min_h));
118 |
119 |
120 | // save the current image block size
121 | uint32_t win_w = mcu_w;
122 | uint32_t win_h = mcu_h;
123 |
124 | // record the current time so we can measure how long it takes to draw an image
125 | uint32_t drawTime = millis();
126 |
127 | uint16_t max_xx = max_x;
128 | uint16_t max_yy = max_y;
129 | if (reduction > 1 && (options & OPT_REDUCTION) ) {
130 | max_xx = max_x / reduction; // new image size of X
131 | max_yy = max_y / reduction; // new image size of Y
132 | }
133 | //Serial.println("max_xx=" + String(max_xx));
134 | //Serial.println("max_yy=" + String(max_yy));
135 |
136 | // calculation center position
137 | int delta_x = 0;
138 | int delta_y = 0;
139 | if ( (max_xx < tft_width) && (options & OPT_CENTER) ) {
140 | delta_x = (tft_width - max_xx) / 2;
141 | }
142 | if ( (max_yy < tft_height) && (options & OPT_CENTER) ) {
143 | delta_y = (tft_height - max_yy) / 2;
144 | }
145 | //Serial.println("delta_x=" + String(delta_x));
146 | //Serial.println("delta_y=" + String(delta_y));
147 |
148 | // save the coordinate of the right and bottom edges to assist image cropping
149 | // to the screen size
150 | max_x += xpos;
151 | max_y += ypos;
152 |
153 | // read each MCU block until there are no more
154 | while ( JpegDec.read()) {
155 |
156 | // save a pointer to the image block
157 | pImg = JpegDec.pImage;
158 |
159 | // calculate where the image block should be drawn on the screen
160 | int mcu_x = JpegDec.MCUx * mcu_w + xpos;
161 | int mcu_y = JpegDec.MCUy * mcu_h + ypos;
162 |
163 | // check if the image block size needs to be changed for the right and bottom edges
164 | if (mcu_x + mcu_w <= max_x) win_w = mcu_w;
165 | else win_w = min_w;
166 | if (mcu_y + mcu_h <= max_y) win_h = mcu_h;
167 | else win_h = min_h;
168 |
169 | memcpy(pImg2, JpegDec.pImage, szImg2*2);
170 | int mcu_xx = mcu_x + delta_x;
171 | int mcu_yy = mcu_y + delta_y;
172 | uint32_t win_ww = win_w;
173 | uint32_t win_hh = win_h;
174 |
175 | if (reduction > 1 && (options & OPT_REDUCTION) ){
176 | int pos1 = 0;
177 | int pos2 = 0;
178 | for(int x=0; x 1 && (options & OPT_REDUCTION) ) {
243 | int reductionRate = (float)(1.0 / reduction) * 100;
244 | Serial.print ("Rate of reduction was : "); Serial.print(reductionRate); Serial.println(" %");
245 | }
246 | Serial.println("=====================================");
247 |
248 | }
249 | //====================================================================================
250 | // Send time taken to Serial port
251 | //====================================================================================
252 | void jpegInfo() {
253 | Serial.println(F("==============="));
254 | Serial.println(F("JPEG image info"));
255 | Serial.println(F("==============="));
256 | Serial.print(F( "Width :")); Serial.println(JpegDec.width);
257 | Serial.print(F( "Height :")); Serial.println(JpegDec.height);
258 | Serial.print(F( "Components :")); Serial.println(JpegDec.comps);
259 | Serial.print(F( "MCU / row :")); Serial.println(JpegDec.MCUSPerRow);
260 | Serial.print(F( "MCU / col :")); Serial.println(JpegDec.MCUSPerCol);
261 | Serial.print(F( "Scan type :")); Serial.println(JpegDec.scanType);
262 | Serial.print(F( "MCU width :")); Serial.println(JpegDec.MCUWidth);
263 | Serial.print(F( "MCU height :")); Serial.println(JpegDec.MCUHeight);
264 | Serial.println(F("==============="));
265 | }
266 |
267 | //====================================================================================
268 | // Open a Jpeg file on an SD card and dump it to the Serial port as a C array
269 | //====================================================================================
270 | void createArray(const char *filename) {
271 |
272 | File jpgFile; // File handle reference For SD library
273 |
274 | if ( !( jpgFile = SD.open( filename, FILE_READ))) {
275 | Serial.println(F("JPEG file not found"));
276 | return;
277 | }
278 |
279 | uint8_t data;
280 | byte line_len = 0;
281 | Serial.println("// Generated by a JPEGDecoder library example sketch:");
282 | Serial.println("// https://github.com/Bodmer/JPEGDecoder");
283 | Serial.println("");
284 | Serial.println("#if defined(__AVR__)");
285 | Serial.println(" #include ");
286 | Serial.println("#endif");
287 | Serial.println("");
288 | Serial.print("const uint8_t ");
289 | while (*filename != '.') Serial.print(*filename++);
290 | Serial.println("[] PROGMEM = {"); // PROGMEM added for AVR processors
291 |
292 | while ( jpgFile.available()) {
293 |
294 | data = jpgFile.read();
295 | Serial.print("0x"); if (abs(data) < 16) Serial.print("0");
296 | Serial.print(data, HEX); Serial.print(",");// Add value and comma
297 | line_len++;
298 | if ( line_len >= 32) {
299 | line_len = 0;
300 | Serial.println();
301 | }
302 |
303 | }
304 |
305 | Serial.println("};\r\n");
306 | jpgFile.close();
307 | }
308 |
309 | // Function to print all timestamps.
310 | void printTimestamps(SdFile& f) {
311 | dir_t d;
312 | if (!f.dirEntry(&d)) {
313 | return;
314 | }
315 |
316 | //Serial.print("Creation: ");
317 | //f.printFatDate(d.creationDate);
318 | //Serial.print(" ");
319 | //f.printFatTime(d.creationTime);
320 |
321 | //Serial.print("Modify: ");
322 | f.printFatDate(d.lastWriteDate);
323 | Serial.print(" ");
324 | f.printFatTime(d.lastWriteTime);
325 |
326 | //Serial.print("Access: ");
327 | //f.printFatDate(d.lastAccessDate);
328 | Serial.print(" ");
329 | }
330 |
331 | // Max of ten files since files are selected with a single digit.
332 | #define nMax 100
333 |
334 | // Show JPEG file list on console
335 | int showJpegFileList (uint16_t * JPEGIndex, int MaxIndex) {
336 |
337 | // Position of file's directory entry.
338 | uint16_t *dirIndexP;
339 | dirIndexP = (uint16_t *) malloc(nMax);
340 |
341 | SdFile file;
342 | SdFile dirFile;
343 |
344 | // Save index in root directory.
345 | if (!dirFile.open("/", O_READ)) {
346 | SD.errorHalt("open root failed");
347 | }
348 | uint16_t n = 0;
349 | while (n < nMax && file.openNext(&dirFile, O_READ)) {
350 |
351 | // Skip directories and hidden files.
352 | if (!file.isSubDir() && !file.isHidden()) {
353 |
354 | // Save dirIndex of file in directory.
355 | dirIndexP[n] = file.dirIndex();
356 |
357 | #if 0
358 | // Print the file number and name.
359 | Serial.print(n);
360 | Serial.write(' ');
361 | file.printName(&Serial);
362 | Serial.println();
363 | #endif
364 | n++;
365 | }
366 | file.close();
367 | }
368 | //Serial.println("n=" + String(n));
369 |
370 | // List files in root directory.
371 | int ipos = 0;
372 | Serial.println("--------------------------------------------");
373 | for(int i=0;i=97 && fname[i]<=122)
387 | FNAME[i] = fname[i]-32;
388 | }
389 |
390 | //Serial.println("fname=" + String(fname));
391 | //Serial.println("FNAME=" + String(FNAME));
392 | if (strstr(FNAME, ".JPG")) {
393 | printTimestamps(file);
394 | sprintf(buf,"%10d %s",fsz,fname);
395 | //Serial.println("fname[" + String(i) + "]=" + String(fname));
396 | Serial.println(buf);
397 | if (ipos < MaxIndex) JPEGIndex[ipos++] = dirIndexP[i];
398 | }
399 | file.close();
400 | Serial.flush();
401 | }
402 | dirFile.close();
403 | free(dirIndexP);
404 | Serial.println("--------------------------------------------");
405 | return ipos;
406 | }
407 |
408 |
409 | char *getFileName(int index)
410 | {
411 | char fname[32];
412 |
413 | // Get JPEG file name
414 | //Serial.println("index=" + String(index));
415 | SdFile file;
416 | SdFile dirFile;
417 | if (!dirFile.open("/", O_READ)) {
418 | SD.errorHalt("open root failed");
419 | }
420 | if (!file.open(&dirFile, index, O_READ)) {
421 | SD.errorHalt(F("open file failed"));
422 | }
423 | //Serial.print("open ok ");
424 | file.getName(fname,sizeof(fname));
425 | //Serial.println("fname=" + String(fname));
426 | file.close();
427 | dirFile.close();
428 | return fname;
429 | }
430 |
431 | //====================================================================================
432 |
433 |
--------------------------------------------------------------------------------
/examples/JpegView_240x320_SMT32/JpegView_240x320_SMT32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for STM32F103
3 | * based on MCUFRIEND_kbv.cpp by David Prentice
4 | * https://github.com/prenticedavid/MCUFRIEND_kbv
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with this program. If not, see .
18 | */
19 |
20 |
21 | #include
22 | #include "STM32_TFT_8bit.h"
23 | #include // https://github.com/greiman/SdFat
24 | #include // https://github.com/Bodmer/JPEGDecoder
25 |
26 | STM32_TFT_8bit tft;
27 |
28 | uint32_t ID;
29 |
30 | // Use second SPI port
31 | /*
32 | * MOSI --- PB15
33 | * MISO --- PB14
34 | * SCK ---- PB13
35 | * CS ----- PB12
36 | */
37 | SPIClass SPI_2(2);
38 | SdFat SD(&SPI_2);
39 | // SdFatEX SD(&SPI_2);
40 | const uint8_t SD_CS = PB12; // chip select for sd2
41 |
42 | //------------------------------------------------------------------------------
43 | // print error msg, any SD error codes, and halt.
44 | // store messages in flash
45 | #define errorExit(msg) errorHalt(F(msg))
46 | #define initError(msg) initErrorHalt(F(msg))
47 | //------------------------------------------------------------------------------
48 |
49 | #define OPT_REDUCTION 1
50 | #define OPT_CENTER 2
51 |
52 | #define MaxJPEG 100
53 | int numJPEG;
54 | uint16_t JPEGIndex[MaxJPEG];
55 |
56 | void setup() {
57 | delay(1000);
58 | Serial.begin(9600);
59 | Serial.println("STM32_TFT_8bit Test!");
60 |
61 | ID = tft.readID();
62 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
63 | tft.begin(ID);
64 |
65 | uint32_t width = tft.width();
66 | Serial.print("Width: "); Serial.println(width);
67 | uint32_t height = tft.height();
68 | Serial.print("Height: "); Serial.println(height);
69 | if (width < height) tft.setRotation(3);
70 |
71 | // initialize the second card
72 | //if (!SD.begin(SD_CS, SD_SCK_MHZ(18))) {
73 | if (!SD.begin(SD_CS)) {
74 | SD.initError("sd:");
75 | }
76 |
77 | // Show JPEG file list on console
78 | numJPEG = showJpegFileList(JPEGIndex, MaxJPEG);
79 | Serial.println("numJPEG=" + String(numJPEG));
80 | }
81 |
82 |
83 | void loop(void) {
84 | static int ipos = 0;
85 | char fname[32];
86 |
87 | // Get JPEG file name
88 | strcpy(fname, getFileName(JPEGIndex[ipos]));
89 |
90 | // Draw JPEG image with recuction
91 | tft.fillScreen(random(0x10000));
92 | drawFSJpeg(fname, 0, 0, OPT_REDUCTION + OPT_CENTER);
93 |
94 | ipos++;
95 | if (ipos == numJPEG) ipos = 0;
96 |
97 | delay(5000);
98 | }
99 |
100 |
101 |
--------------------------------------------------------------------------------
/examples/JpegView_320x480_SMT32/JPEG_Functions.ino:
--------------------------------------------------------------------------------
1 | /*====================================================================================
2 | This sketch contains support functions to render the Jpeg images.
3 |
4 | Created by Bodmer 5th Feb 2017
5 | Updated by nopnop2002 19/4/2018
6 | ==================================================================================*/
7 |
8 | // Return the minimum of two values a and b
9 | #define minimum(a,b) (((a) < (b)) ? (a) : (b))
10 | #define maximum(a,b) (((a) > (b)) ? (a) : (b))
11 |
12 | //====================================================================================
13 | // This function opens the array and primes the decoder
14 | //====================================================================================
15 | void drawArrayJpeg(const uint8_t arrayname[], uint32_t array_size, int xpos, int ypos) {
16 |
17 | boolean decoded = JpegDec.decodeArray(arrayname, array_size);
18 |
19 | if (decoded) {
20 | // print information about the image to the serial port
21 | jpegInfo();
22 |
23 | // render the image onto the screen at given coordinates
24 | jpegRender(xpos, ypos, 0);
25 | }
26 | else {
27 | Serial.println("Jpeg file format not supported!");
28 | }
29 | }
30 |
31 | //====================================================================================
32 | // This function opens the Filing System Jpeg image file and primes the decoder
33 | //
34 | // options : OPT_REDUCTION
35 | // If it's large than screen, it would reduce so that it may fit into a screen.
36 | // OPT_CENTER
37 | // If it's smaller than screen, it would show to the center of the screen.
38 | //====================================================================================
39 | void drawFSJpeg(const char *filename, int xpos, int ypos, int options) {
40 |
41 | Serial.println("=====================================");
42 | Serial.print("Drawing file: "); Serial.println(filename);
43 | Serial.println("=====================================");
44 |
45 | // Open the file (the Jpeg decoder library will close it)
46 | File jpgFile = SD.open( filename, FILE_READ); // file handle reference for SD library
47 |
48 | if ( !jpgFile ) {
49 | Serial.print("ERROR: File \""); Serial.print(filename); Serial.println ("\" not found!");
50 | return;
51 | }
52 |
53 | // To initialise the decoder and provide the file, we can use one of the following methods:
54 | boolean decoded = JpegDec.decodeSdFile(jpgFile); // we can pass the SD file handle to the decoder,
55 | //boolean decoded = JpegDec.decodeFsFile(filename); // or we can pass the filename
56 | // The filename can be a String or character array
57 | if (decoded) {
58 | // print information about the image to the serial port
59 | jpegInfo();
60 |
61 | // render the image onto the screen at given coordinates
62 | jpegRender(xpos, ypos, options);
63 | }
64 | else {
65 | Serial.println("Jpeg file format not supported!");
66 | }
67 | }
68 |
69 | //====================================================================================
70 | // Decode and paint onto the TFT screen
71 | //====================================================================================
72 | void jpegRender(int xpos, int ypos, int options) {
73 |
74 | //if (options & OPT_REDUCTION) Serial.println("OPT_REDUCTION");
75 | //if (options & OPT_CENTER) Serial.println("OPT_CENTER");
76 | // retrieve infomration about the image
77 | uint16_t *pImg;
78 | uint16_t mcu_w = JpegDec.MCUWidth;
79 | uint16_t mcu_h = JpegDec.MCUHeight;
80 | uint32_t max_x = JpegDec.width;
81 | uint32_t max_y = JpegDec.height;
82 | //Serial.println("mcu_w=" + String(mcu_w));
83 | //Serial.println("mcu_h=" + String(mcu_h));
84 | //Serial.println("max_x=" + String(max_x));
85 | //Serial.println("max_y=" + String(max_y));
86 |
87 | uint16_t szImg2 = mcu_w * mcu_h;
88 | uint16_t *pImg2;
89 | pImg2 = (uint16_t *) malloc(szImg2*2);
90 |
91 | uint32_t tft_width = tft.width();
92 | //Serial.print("tft_width: "); Serial.println(tft_width);
93 | uint32_t tft_height = tft.height();
94 | //Serial.print("tft_height: "); Serial.println(tft_height);
95 |
96 | int reduction_x = 1;
97 | int reduction_y = 1;
98 | if (max_x > tft_width) {
99 | reduction_x = (max_x / tft_width);
100 | if (max_x % tft_width) reduction_x++;
101 | }
102 | if (max_y > tft_height) {
103 | reduction_y = (max_y / tft_height);
104 | if (max_y % tft_height) reduction_y++;
105 | }
106 | //Serial.println("reduction_x=" + String(reduction_x));
107 | //Serial.println("reduction_y=" + String(reduction_y));
108 | int reduction = maximum(reduction_x, reduction_y);
109 | //Serial.println("reduction=" + String(reduction));
110 |
111 | // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
112 | // Typically these MCUs are 16x16 pixel blocks
113 | // Determine the width and height of the right and bottom edge image blocks
114 | uint32_t min_w = minimum(mcu_w, max_x % mcu_w);
115 | uint32_t min_h = minimum(mcu_h, max_y % mcu_h);
116 | //Serial.println("min_w=" + String(min_w));
117 | //Serial.println("min_h=" + String(min_h));
118 |
119 |
120 | // save the current image block size
121 | uint32_t win_w = mcu_w;
122 | uint32_t win_h = mcu_h;
123 |
124 | // record the current time so we can measure how long it takes to draw an image
125 | uint32_t drawTime = millis();
126 |
127 | uint16_t max_xx = max_x;
128 | uint16_t max_yy = max_y;
129 | if (reduction > 1 && (options & OPT_REDUCTION) ) {
130 | max_xx = max_x / reduction; // new image size of X
131 | max_yy = max_y / reduction; // new image size of Y
132 | }
133 | //Serial.println("max_xx=" + String(max_xx));
134 | //Serial.println("max_yy=" + String(max_yy));
135 |
136 | // calculation center position
137 | int delta_x = 0;
138 | int delta_y = 0;
139 | if ( (max_xx < tft_width) && (options & OPT_CENTER) ) {
140 | delta_x = (tft_width - max_xx) / 2;
141 | }
142 | if ( (max_yy < tft_height) && (options & OPT_CENTER) ) {
143 | delta_y = (tft_height - max_yy) / 2;
144 | }
145 | //Serial.println("delta_x=" + String(delta_x));
146 | //Serial.println("delta_y=" + String(delta_y));
147 |
148 | // save the coordinate of the right and bottom edges to assist image cropping
149 | // to the screen size
150 | max_x += xpos;
151 | max_y += ypos;
152 |
153 | // read each MCU block until there are no more
154 | while ( JpegDec.read()) {
155 |
156 | // save a pointer to the image block
157 | pImg = JpegDec.pImage;
158 |
159 | // calculate where the image block should be drawn on the screen
160 | int mcu_x = JpegDec.MCUx * mcu_w + xpos;
161 | int mcu_y = JpegDec.MCUy * mcu_h + ypos;
162 |
163 | // check if the image block size needs to be changed for the right and bottom edges
164 | if (mcu_x + mcu_w <= max_x) win_w = mcu_w;
165 | else win_w = min_w;
166 | if (mcu_y + mcu_h <= max_y) win_h = mcu_h;
167 | else win_h = min_h;
168 |
169 | memcpy(pImg2, JpegDec.pImage, szImg2*2);
170 | int mcu_xx = mcu_x + delta_x;
171 | int mcu_yy = mcu_y + delta_y;
172 | uint32_t win_ww = win_w;
173 | uint32_t win_hh = win_h;
174 |
175 | if (reduction > 1 && (options & OPT_REDUCTION) ){
176 | int pos1 = 0;
177 | int pos2 = 0;
178 | for(int x=0; x 1 && (options & OPT_REDUCTION) ) {
243 | int reductionRate = (float)(1.0 / reduction) * 100;
244 | Serial.print ("Rate of reduction was : "); Serial.print(reductionRate); Serial.println(" %");
245 | }
246 | Serial.println("=====================================");
247 |
248 | }
249 | //====================================================================================
250 | // Send time taken to Serial port
251 | //====================================================================================
252 | void jpegInfo() {
253 | Serial.println(F("==============="));
254 | Serial.println(F("JPEG image info"));
255 | Serial.println(F("==============="));
256 | Serial.print(F( "Width :")); Serial.println(JpegDec.width);
257 | Serial.print(F( "Height :")); Serial.println(JpegDec.height);
258 | Serial.print(F( "Components :")); Serial.println(JpegDec.comps);
259 | Serial.print(F( "MCU / row :")); Serial.println(JpegDec.MCUSPerRow);
260 | Serial.print(F( "MCU / col :")); Serial.println(JpegDec.MCUSPerCol);
261 | Serial.print(F( "Scan type :")); Serial.println(JpegDec.scanType);
262 | Serial.print(F( "MCU width :")); Serial.println(JpegDec.MCUWidth);
263 | Serial.print(F( "MCU height :")); Serial.println(JpegDec.MCUHeight);
264 | Serial.println(F("==============="));
265 | }
266 |
267 | //====================================================================================
268 | // Open a Jpeg file on an SD card and dump it to the Serial port as a C array
269 | //====================================================================================
270 | void createArray(const char *filename) {
271 |
272 | File jpgFile; // File handle reference For SD library
273 |
274 | if ( !( jpgFile = SD.open( filename, FILE_READ))) {
275 | Serial.println(F("JPEG file not found"));
276 | return;
277 | }
278 |
279 | uint8_t data;
280 | byte line_len = 0;
281 | Serial.println("// Generated by a JPEGDecoder library example sketch:");
282 | Serial.println("// https://github.com/Bodmer/JPEGDecoder");
283 | Serial.println("");
284 | Serial.println("#if defined(__AVR__)");
285 | Serial.println(" #include ");
286 | Serial.println("#endif");
287 | Serial.println("");
288 | Serial.print("const uint8_t ");
289 | while (*filename != '.') Serial.print(*filename++);
290 | Serial.println("[] PROGMEM = {"); // PROGMEM added for AVR processors
291 |
292 | while ( jpgFile.available()) {
293 |
294 | data = jpgFile.read();
295 | Serial.print("0x"); if (abs(data) < 16) Serial.print("0");
296 | Serial.print(data, HEX); Serial.print(",");// Add value and comma
297 | line_len++;
298 | if ( line_len >= 32) {
299 | line_len = 0;
300 | Serial.println();
301 | }
302 |
303 | }
304 |
305 | Serial.println("};\r\n");
306 | jpgFile.close();
307 | }
308 |
309 | // Function to print all timestamps.
310 | void printTimestamps(SdFile& f) {
311 | dir_t d;
312 | if (!f.dirEntry(&d)) {
313 | return;
314 | }
315 |
316 | //Serial.print("Creation: ");
317 | //f.printFatDate(d.creationDate);
318 | //Serial.print(" ");
319 | //f.printFatTime(d.creationTime);
320 |
321 | //Serial.print("Modify: ");
322 | f.printFatDate(d.lastWriteDate);
323 | Serial.print(" ");
324 | f.printFatTime(d.lastWriteTime);
325 |
326 | //Serial.print("Access: ");
327 | //f.printFatDate(d.lastAccessDate);
328 | Serial.print(" ");
329 | }
330 |
331 | // Max of ten files since files are selected with a single digit.
332 | #define nMax 100
333 |
334 | // Show JPEG file list on console
335 | int showJpegFileList (uint16_t * JPEGIndex, int MaxIndex) {
336 |
337 | // Position of file's directory entry.
338 | uint16_t *dirIndexP;
339 | dirIndexP = (uint16_t *) malloc(nMax);
340 |
341 | SdFile file;
342 | SdFile dirFile;
343 |
344 | // Save index in root directory.
345 | if (!dirFile.open("/", O_READ)) {
346 | SD.errorHalt("open root failed");
347 | }
348 | uint16_t n = 0;
349 | while (n < nMax && file.openNext(&dirFile, O_READ)) {
350 |
351 | // Skip directories and hidden files.
352 | if (!file.isSubDir() && !file.isHidden()) {
353 |
354 | // Save dirIndex of file in directory.
355 | dirIndexP[n] = file.dirIndex();
356 |
357 | #if 0
358 | // Print the file number and name.
359 | Serial.print(n);
360 | Serial.write(' ');
361 | file.printName(&Serial);
362 | Serial.println();
363 | #endif
364 | n++;
365 | }
366 | file.close();
367 | }
368 | //Serial.println("n=" + String(n));
369 |
370 | // List files in root directory.
371 | int ipos = 0;
372 | Serial.println("--------------------------------------------");
373 | for(int i=0;i=97 && fname[i]<=122)
387 | FNAME[i] = fname[i]-32;
388 | }
389 |
390 | //Serial.println("fname=" + String(fname));
391 | //Serial.println("FNAME=" + String(FNAME));
392 | if (strstr(FNAME, ".JPG")) {
393 | printTimestamps(file);
394 | sprintf(buf,"%10d %s",fsz,fname);
395 | //Serial.println("fname[" + String(i) + "]=" + String(fname));
396 | Serial.println(buf);
397 | if (ipos < MaxIndex) JPEGIndex[ipos++] = dirIndexP[i];
398 | }
399 | file.close();
400 | Serial.flush();
401 | }
402 | dirFile.close();
403 | free(dirIndexP);
404 | Serial.println("--------------------------------------------");
405 | return ipos;
406 | }
407 |
408 |
409 | char *getFileName(int index)
410 | {
411 | char fname[32];
412 |
413 | // Get JPEG file name
414 | //Serial.println("index=" + String(index));
415 | SdFile file;
416 | SdFile dirFile;
417 | if (!dirFile.open("/", O_READ)) {
418 | SD.errorHalt("open root failed");
419 | }
420 | if (!file.open(&dirFile, index, O_READ)) {
421 | SD.errorHalt(F("open file failed"));
422 | }
423 | //Serial.print("open ok ");
424 | file.getName(fname,sizeof(fname));
425 | //Serial.println("fname=" + String(fname));
426 | file.close();
427 | dirFile.close();
428 | return fname;
429 | }
430 |
431 | //====================================================================================
432 |
433 |
--------------------------------------------------------------------------------
/examples/JpegView_320x480_SMT32/JpegView_320x480_SMT32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for STM32F103
3 | * based on MCUFRIEND_kbv.cpp by David Prentice
4 | * https://github.com/prenticedavid/MCUFRIEND_kbv
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with this program. If not, see .
18 | */
19 |
20 |
21 | #include
22 | #include "STM32_TFT_8bit.h"
23 | #include // https://github.com/greiman/SdFat
24 | #include // https://github.com/Bodmer/JPEGDecoder
25 |
26 | STM32_TFT_8bit tft;
27 |
28 | uint32_t ID;
29 |
30 | // Use second SPI port
31 | /*
32 | * MOSI --- PB15
33 | * MISO --- PB14
34 | * SCK ---- PB13
35 | * CS ----- PB12
36 | */
37 | SPIClass SPI_2(2);
38 | SdFat SD(&SPI_2);
39 | // SdFatEX SD(&SPI_2);
40 | const uint8_t SD_CS = PB12; // chip select for sd2
41 |
42 | //------------------------------------------------------------------------------
43 | // print error msg, any SD error codes, and halt.
44 | // store messages in flash
45 | #define errorExit(msg) errorHalt(F(msg))
46 | #define initError(msg) initErrorHalt(F(msg))
47 | //------------------------------------------------------------------------------
48 |
49 | #define OPT_REDUCTION 1
50 | #define OPT_CENTER 2
51 |
52 | #define MaxJPEG 100
53 | int numJPEG;
54 | uint16_t JPEGIndex[MaxJPEG];
55 |
56 | void setup() {
57 | delay(1000);
58 | Serial.begin(9600);
59 | Serial.println("STM32_TFT_8bit Test!");
60 |
61 | ID = tft.readID();
62 | tft.setResolution(320, 480); // Set your resolution
63 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
64 | tft.begin(ID);
65 |
66 | uint32_t width = tft.width();
67 | Serial.print("Width: "); Serial.println(width);
68 | uint32_t height = tft.height();
69 | Serial.print("Height: "); Serial.println(height);
70 | if (width < height) tft.setRotation(3);
71 |
72 | // initialize the second card
73 | //if (!SD.begin(SD_CS, SD_SCK_MHZ(18))) {
74 | if (!SD.begin(SD_CS)) {
75 | SD.initError("sd:");
76 | }
77 |
78 | // Show JPEG file list on console
79 | numJPEG = showJpegFileList(JPEGIndex, MaxJPEG);
80 | Serial.println("numJPEG=" + String(numJPEG));
81 | }
82 |
83 |
84 | void loop(void) {
85 | static int ipos = 0;
86 | char fname[32];
87 |
88 | // Get JPEG file name
89 | strcpy(fname, getFileName(JPEGIndex[ipos]));
90 |
91 | // Draw JPEG image with recuction
92 | tft.fillScreen(random(0x10000));
93 | drawFSJpeg(fname, 0, 0, OPT_REDUCTION + OPT_CENTER);
94 |
95 | ipos++;
96 | if (ipos == numJPEG) ipos = 0;
97 |
98 | delay(5000);
99 | }
100 |
101 |
102 |
--------------------------------------------------------------------------------
/examples/LCD_ID_Reader/LCD_ID_Reader.ino:
--------------------------------------------------------------------------------
1 | // adapted from LCD_ID_Reader from http://misc.ws/lcd_information
2 | // controllers either read as 16-bit or as a sequence of 8-bit values
3 |
4 | #define LCD_RST PB7
5 | #define LCD_CS PB6
6 | #define LCD_RS PB5
7 | #define LCD_WR PB4
8 | #define LCD_RD PB3
9 |
10 | #define LCD_D0 PA0
11 | #define LCD_D1 PA1
12 | #define LCD_D2 PA2
13 | #define LCD_D3 PA3
14 | #define LCD_D4 PA4
15 | #define LCD_D5 PA5
16 | #define LCD_D6 PA6
17 | #define LCD_D7 PA7
18 |
19 | void setup()
20 | {
21 | Serial.begin(9600);
22 | while (!Serial) ;
23 | Serial.println("Read Registers on MCUFRIEND UNO shield");
24 | Serial.println("controllers either read as single 16-bit");
25 | Serial.println("e.g. the ID is at readReg(0)");
26 | Serial.println("or as a sequence of 8-bit values");
27 | Serial.println("in special locations (first is dummy)");
28 | Serial.println("");
29 | lcdInit();
30 | lcdReset(); //ensures that controller is in default state
31 | // for (uint16_t i = 0; i < 256; i++) readReg(i, 7, "f.k");
32 | readReg(0x00, 2, "ID: ILI9320, ILI9325, ILI9335, ...");
33 | readReg(0x04, 4, "Manufacturer ID");
34 | readReg(0x09, 5, "Status Register");
35 | readReg(0x0A, 2, "Get Powsr Mode");
36 | readReg(0x0C, 2, "Get Pixel Format");
37 | readReg(0x61, 2, "RDID1 HX8347-G");
38 | readReg(0x62, 2, "RDID2 HX8347-G");
39 | readReg(0x63, 2, "RDID3 HX8347-G");
40 | readReg(0x64, 2, "RDID1 HX8347-A");
41 | readReg(0x65, 2, "RDID2 HX8347-A");
42 | readReg(0x66, 2, "RDID3 HX8347-A");
43 | readReg(0x67, 2, "RDID Himax HX8347-A");
44 | readReg(0x70, 2, "Panel Himax HX8347-A");
45 | readReg(0xA1, 5, "RD_DDB SSD1963");
46 | readReg(0xB0, 2, "RGB Interface Signal Control");
47 | readReg(0xB4, 2, "Inversion Control");
48 | readReg(0xB6, 5, "Display Control");
49 | readReg(0xB7, 2, "Entry Mode Set");
50 | readReg(0xBF, 6, "ILI9481, HX8357-B");
51 | readReg(0xC0, 9, "Panel Control");
52 | readReg(0xC8, 13, "GAMMA");
53 | readReg(0xCC, 2, "Panel Control");
54 | readReg(0xD0, 3, "Power Control");
55 | readReg(0xD2, 5, "NVM Read");
56 | readReg(0xD3, 4, "ILI9341, ILI9488");
57 | readReg(0xDA, 2, "RDID1");
58 | readReg(0xDB, 2, "RDID2");
59 | readReg(0xDC, 2, "RDID3");
60 | readReg(0xE0, 16, "GAMMA-P");
61 | readReg(0xE1, 16, "GAMMA-N");
62 | readReg(0xEF, 6, "ILI9327");
63 | readReg(0xF2, 12, "Adjust Control 2");
64 | readReg(0xF6, 4, "Interface Control");
65 | }
66 |
67 | void loop()
68 | {
69 | // put your main code here, to run repeatedly:
70 |
71 | }
72 |
73 | void printhex(uint8_t val)
74 | {
75 | if (val < 0x10) Serial.print("0");
76 | Serial.print(val, HEX);
77 | }
78 |
79 | void readReg(uint16_t reg, uint8_t n, const char *msg)
80 | {
81 | uint8_t val8;
82 | lcdReset();
83 | lcdSetWriteDir();
84 | lcdWriteCommand(0xB0); //Command Access Protect
85 | lcdWriteData(0x00); //looks wrong
86 | /*
87 | lcdWriteCommand(0xF6);
88 | lcdWriteData(0x01);
89 | lcdWriteData(0x01);
90 | lcdWriteData(0x03);
91 | */
92 | lcdWriteCommand(reg);
93 | Serial.print("reg(0x");
94 | printhex(reg >> 8);
95 | printhex(reg);
96 | Serial.print(")");
97 | lcdSetReadDir();
98 | while (n--) {
99 | val8 = lcdReadData8();
100 | Serial.print(" ");
101 | printhex(val8);
102 | }
103 | lcdSetWriteDir();
104 | Serial.print("\t");
105 | Serial.println(msg);
106 | }
107 |
108 | void lcdInit()
109 | {
110 | pinMode(LCD_CS, OUTPUT);
111 | digitalWrite(LCD_CS, HIGH);
112 | pinMode(LCD_RS, OUTPUT);
113 | digitalWrite(LCD_RS, HIGH);
114 | pinMode(LCD_WR, OUTPUT);
115 | digitalWrite(LCD_WR, HIGH);
116 | pinMode(LCD_RD, OUTPUT);
117 | digitalWrite(LCD_RD, HIGH);
118 | pinMode(LCD_RST, OUTPUT);
119 | digitalWrite(LCD_RST, HIGH);
120 | }
121 |
122 | void lcdReset()
123 | {
124 | digitalWrite(LCD_RST, LOW);
125 | delay(2);
126 | digitalWrite(LCD_RST, HIGH);
127 | delay(10); //allow controller to re-start
128 | }
129 |
130 | void lcdWrite8(uint16_t data)
131 | {
132 | digitalWrite(LCD_D0, data & 1);
133 | digitalWrite(LCD_D1, (data & 2) >> 1);
134 | digitalWrite(LCD_D2, (data & 4) >> 2);
135 | digitalWrite(LCD_D3, (data & 8) >> 3);
136 | digitalWrite(LCD_D4, (data & 16) >> 4);
137 | digitalWrite(LCD_D5, (data & 32) >> 5);
138 | digitalWrite(LCD_D6, (data & 64) >> 6);
139 | digitalWrite(LCD_D7, (data & 128) >> 7);
140 | }
141 |
142 | uint16_t lcdRead8()
143 | {
144 | uint16_t result = digitalRead(LCD_D7);
145 | result <<= 1;
146 | result |= digitalRead(LCD_D6);
147 | result <<= 1;
148 | result |= digitalRead(LCD_D5);
149 | result <<= 1;
150 | result |= digitalRead(LCD_D4);
151 | result <<= 1;
152 | result |= digitalRead(LCD_D3);
153 | result <<= 1;
154 | result |= digitalRead(LCD_D2);
155 | result <<= 1;
156 | result |= digitalRead(LCD_D1);
157 | result <<= 1;
158 | result |= digitalRead(LCD_D0);
159 |
160 | return result;
161 | }
162 |
163 | void lcdSetWriteDir()
164 | {
165 | pinMode(LCD_D0, OUTPUT);
166 | pinMode(LCD_D1, OUTPUT);
167 | pinMode(LCD_D2, OUTPUT);
168 | pinMode(LCD_D3, OUTPUT);
169 | pinMode(LCD_D4, OUTPUT);
170 | pinMode(LCD_D5, OUTPUT);
171 | pinMode(LCD_D6, OUTPUT);
172 | pinMode(LCD_D7, OUTPUT);
173 | }
174 |
175 |
176 | void lcdSetReadDir()
177 | {
178 | pinMode(LCD_D0, INPUT);
179 | pinMode(LCD_D1, INPUT);
180 | pinMode(LCD_D2, INPUT);
181 | pinMode(LCD_D3, INPUT);
182 | pinMode(LCD_D4, INPUT);
183 | pinMode(LCD_D5, INPUT);
184 | pinMode(LCD_D6, INPUT);
185 | pinMode(LCD_D7, INPUT);
186 | }
187 |
188 | void lcdWriteData(uint16_t data)
189 | {
190 | lcdSetWriteDir();
191 | digitalWrite(LCD_CS, LOW);
192 | digitalWrite(LCD_RS, HIGH);
193 | digitalWrite(LCD_RD, HIGH);
194 | digitalWrite(LCD_WR, HIGH);
195 |
196 | lcdWrite8(data >> 8);
197 |
198 | digitalWrite(LCD_WR, LOW);
199 | delayMicroseconds(10);
200 | digitalWrite(LCD_WR, HIGH);
201 |
202 | lcdWrite8(data);
203 |
204 | digitalWrite(LCD_WR, LOW);
205 | delayMicroseconds(10);
206 | digitalWrite(LCD_WR, HIGH);
207 |
208 | digitalWrite(LCD_CS, HIGH);
209 | }
210 |
211 | void lcdWriteCommand(uint16_t command)
212 | {
213 | lcdSetWriteDir();
214 | digitalWrite(LCD_CS, LOW);
215 | digitalWrite(LCD_RS, LOW);
216 | digitalWrite(LCD_RD, HIGH);
217 | digitalWrite(LCD_WR, HIGH);
218 | lcdWrite8(command >> 8);
219 | digitalWrite(LCD_WR, LOW);
220 | delayMicroseconds(10);
221 | digitalWrite(LCD_WR, HIGH);
222 | lcdWrite8(command);
223 | digitalWrite(LCD_WR, LOW);
224 | delayMicroseconds(10);
225 | digitalWrite(LCD_WR, HIGH);
226 | digitalWrite(LCD_CS, HIGH);
227 | }
228 |
229 | uint8_t lcdReadData8()
230 | {
231 | uint8_t result;
232 | lcdSetReadDir();
233 | digitalWrite(LCD_CS, LOW);
234 | digitalWrite(LCD_RS, HIGH);
235 | digitalWrite(LCD_RD, HIGH);
236 | digitalWrite(LCD_WR, HIGH);
237 |
238 | digitalWrite(LCD_RD, LOW);
239 | delayMicroseconds(10);
240 | result = lcdRead8();
241 | digitalWrite(LCD_RD, HIGH);
242 |
243 | delayMicroseconds(10);
244 |
245 | return result;
246 | }
247 |
248 |
249 | uint16_t lcdReadData16()
250 | {
251 | uint16_t result;
252 | result = lcdReadData8() << 8;
253 | result |= lcdReadData8();
254 | return result;
255 | }
256 |
257 |
258 | void lcdWriteRegister(uint16_t addr, uint16_t data)
259 | {
260 | lcdWriteCommand(addr);
261 | lcdWriteData(data);
262 | }
263 |
--------------------------------------------------------------------------------
/examples/LCD_ID_Reader/README.md:
--------------------------------------------------------------------------------
1 | # LCD_ID_Reader
2 | Many controllers are used in the parallel TFT for UNO.
3 | This is a tool to find the TFT controller.
4 |
5 | # Wirering for 8bit Parallel TFT
6 |
7 | |TFT||STM32F103|
8 | |:-:|:-:|:-:|
9 | |LCD_RST|--|PB7|
10 | |LCD_CS|--|PB6|
11 | |LCD_RS|--|PB5|
12 | |LCD_WR|--|PB4(*2)|
13 | |LCD_RD|--|PB3(*2)|
14 | |LCD_D0|--|PA0|
15 | |LCD_D1|--|PA1|
16 | |LCD_D2|--|PA2|
17 | |LCD_D3|--|PA3|
18 | |LCD_D4|--|PA4|
19 | |LCD_D5|--|PA5|
20 | |LCD_D6|--|PA6|
21 | |LCD_D7|--|PA7|
22 | |5V|--|5V(*1)|
23 | |3.3V|--|3.3V(*1)|
24 | |GND|--|GND|
25 |
26 | (*1)When a regulator(It's often AMS1117) is mounted on the back, it's operated 5V.
27 | When a regulator is NOT mounted on the back, it's operated 3.3V.
28 |
29 | (*2)By several boards, This port is used as JTAG.
30 | You need remap.
31 | afio_cfg_debug_ports(AFIO_DEBUG_NONE)
32 |
33 |
34 | # Serial print
35 | ```
36 | Read Registers on MCUFRIEND UNO shield
37 | controllers either read as single 16-bit
38 | e.g. the ID is at readReg(0)
39 | or as a sequence of 8-bit values
40 | in special locations (first is dummy)
41 |
42 | reg(0x0000) 00 00 ID: ILI9320, ILI9325, ILI9335, ...
43 | reg(0x0004) 00 54 80 66 Manufacturer ID
44 | reg(0x0009) 00 00 61 00 00 Status Register
45 | reg(0x000A) 00 08 Get Powsr Mode
46 | reg(0x000C) 00 66 Get Pixel Format
47 | reg(0x0061) 00 00 RDID1 HX8347-G
48 | reg(0x0062) 00 00 RDID2 HX8347-G
49 | reg(0x0063) 00 00 RDID3 HX8347-G
50 | reg(0x0064) 00 00 RDID1 HX8347-A
51 | reg(0x0065) 00 00 RDID2 HX8347-A
52 | reg(0x0066) 00 00 RDID3 HX8347-A
53 | reg(0x0067) 00 00 RDID Himax HX8347-A
54 | reg(0x0070) 00 00 Panel Himax HX8347-A
55 | reg(0x00A1) 00 93 30 93 30 RD_DDB SSD1963
56 | reg(0x00B0) 00 00 RGB Interface Signal Control
57 | reg(0x00B4) 00 00 Inversion Control
58 | reg(0x00B6) 00 02 02 3B 3B Display Control
59 | reg(0x00B7) 00 06 Entry Mode Set
60 | reg(0x00BF) 00 00 00 00 00 00 ILI9481, HX8357-B
61 | reg(0x00C0) 00 0E 0E 0E 0E 0E 0E 0E 0E Panel Control
62 | reg(0x00C8) 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA
63 | reg(0x00CC) 00 04 Panel Control
64 | reg(0x00D0) 00 00 00 Power Control
65 | reg(0x00D2) 00 00 00 00 00 NVM Read
66 | reg(0x00D3) 00 00 94 86 ILI9341, ILI9488
67 | reg(0x00DA) 00 54 RDID1
68 | reg(0x00DB) 00 80 RDID2
69 | reg(0x00DC) 00 66 RDID3
70 | reg(0x00E0) 00 0F 21 1C 0B 0E 08 49 98 38 09 11 03 14 10 00 GAMMA-P
71 | reg(0x00E1) 00 0F 2F 2B 0C 0E 06 47 76 37 07 11 04 23 1E 00 GAMMA-N
72 | reg(0x00EF) 00 80 00 10 60 40 ILI9327
73 | reg(0x00F2) 00 18 A3 12 02 B2 12 FF 10 00 00 00 Adjust Control 2
74 | reg(0x00F6) 00 54 80 66 Interface Control
75 | ```
76 |
77 | From the output of 0x00D3, you can see that the controller is ILI9486.
78 |
79 |
--------------------------------------------------------------------------------
/examples/ScrollTest_STM32/ScrollTest_STM32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for STM32F103
3 | * based on MCUFRIEND_kbv.cpp by David Prentice
4 | * https://github.com/prenticedavid/MCUFRIEND_kbv
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with this program. If not, see .
18 | */
19 |
20 | #include
21 | #include "STM32_TFT_8bit.h"
22 |
23 | STM32_TFT_8bit tft;
24 |
25 | void setup(void) {
26 | delay(1000);
27 | Serial.begin(9600);
28 |
29 | uint16_t ID = tft.readID();
30 | Serial.println("ID = 0x" + String(ID,HEX));
31 | tft.begin(ID);
32 | }
33 |
34 |
35 | void loop(void) {
36 | uint8_t aspect;
37 | uint16_t pixel;
38 | const char *aspectname[] = {
39 | "PORTRAIT", "LANDSCAPE", "PORTRAIT_REV", "LANDSCAPE_REV"
40 | };
41 | const char *colorname[] = { "BLUE", "GREEN", "RED", "GRAY" };
42 | uint16_t colormask[] = { 0x001F, 0x07E0, 0xF800, 0xFFFF };
43 | uint16_t dx, rgb, n, wid, ht, msgline;
44 | tft.setRotation(0);
45 | if (tft.height() > 64) {
46 | for (uint8_t cnt = 0; cnt < 4; cnt++) {
47 | aspect = (cnt + 0) & 3;
48 | tft.setRotation(aspect);
49 | wid = tft.width();
50 | ht = tft.height();
51 | Serial.println("aspect=" + String(aspect));
52 | Serial.println("width=" + String(wid) + " height=" + String(ht));
53 | msgline = (ht > 160) ? 200 : 112;
54 | testText();
55 |
56 | // Show COLOR GRADES
57 | dx = wid / 32;
58 | for (n = 0; n < 32; n++) {
59 | rgb = n * 8;
60 | rgb = tft.color565(rgb, rgb, rgb);
61 | tft.fillRect(n * dx, 48, dx, 63, rgb & colormask[aspect]);
62 | }
63 | tft.drawRect(0, 48 + 63, wid, 1, WHITE);
64 | tft.setTextSize(2);
65 | tft.setTextColor(colormask[aspect], BLACK);
66 | tft.setCursor(0, 72);
67 | tft.print(colorname[aspect]);
68 | tft.setTextColor(WHITE);
69 | tft.println(" COLOR GRADES");
70 | tft.setTextColor(WHITE, BLACK);
71 | printmsg(184, aspectname[aspect]);
72 | delay(1000);
73 | tft.drawPixel(0, 0, YELLOW);
74 | pixel = tft.readPixel(0, 0);
75 | tft.setTextSize((ht > 160) ? 2 : 1); //for messages
76 |
77 | // Show penguin icon
78 | extern const uint8_t penguin[];
79 | tft.setAddrWindow(wid - 40 - 40, 20 + 0, wid - 1 - 40, 20 + 39);
80 | tft.pushColors8((uint8_t *)penguin, 1600, 1);
81 |
82 | // Scroll Screen
83 | tft.setAddrWindow(0, 0, wid - 1, ht - 1);
84 | if (aspect & 1) tft.drawRect(wid - 1, 0, 1, ht, WHITE);
85 | else tft.drawRect(0, ht - 1, wid, 1, WHITE);
86 | printmsg(msgline, "VERTICAL SCROLL UP");
87 | uint16_t maxscroll;
88 | if (tft.getRotation() & 1) maxscroll = wid;
89 | else maxscroll = ht;
90 | int step = -1;
91 | if ( wid < ht ) step = 1;
92 |
93 | // Scroll Up
94 | for (int16_t i = 1; i <= maxscroll; i++) {
95 | tft.vertScroll(0, maxscroll, i * step);
96 | delay(10);
97 | }
98 | delay(1000);
99 |
100 | // Scroll Down
101 | printmsg(msgline, "VERTICAL SCROLL DN");
102 | for (int16_t i = 1; i <= maxscroll; i++) {
103 | tft.vertScroll(0, maxscroll, (0 - i) * step);
104 | delay(10);
105 | }
106 | tft.vertScroll(0, maxscroll, 0);
107 | printmsg(msgline, "SCROLL DISABLED");
108 |
109 | // Scroll COLOR GRADES
110 | delay(1000);
111 | if ((aspect & 1) == 0) { //Portrait
112 | int stline;
113 | stline = 128;
114 | step = -1;
115 | if (wid < ht) {
116 | stline = 48;
117 | step = 1;
118 | }
119 | tft.setTextColor(BLUE, BLACK);
120 | printmsg(msgline, "ONLY THE COLOR BAND");
121 | for (int16_t i = 1; i <= 64; i++) {
122 | tft.vertScroll(stline, 64, i * step);
123 | delay(20);
124 | }
125 | delay(1000);
126 | for (int16_t i = 1; i <= 64; i++) {
127 | tft.vertScroll(stline, 64, (0 - i) * step);
128 | delay(20);
129 | }
130 | delay(1000);
131 |
132 | #if 0
133 | if ( wid < ht ) {
134 | stline = 48;
135 | for (int16_t i = 1; i <= 64; i++) {
136 | tft.vertScroll(stline, 64, i);
137 | delay(20);
138 | }
139 | delay(1000);
140 | for (int16_t i = 1; i <= 64; i++) {
141 | tft.vertScroll(stline, 64, 0 - i);
142 | delay(20);
143 | }
144 | delay(1000);
145 | } else {
146 | stline = 128;
147 | for (int16_t i = 1; i <= 64; i++) {
148 | tft.vertScroll(stline, 64, 0 - i);
149 | delay(20);
150 | }
151 | delay(1000);
152 | for (int16_t i = 1; i <= 64; i++) {
153 | tft.vertScroll(stline, 64, i);
154 | delay(20);
155 | }
156 | delay(1000);
157 | }
158 | #endif
159 | }
160 |
161 | printmsg(msgline, "INVERT DISPLAY");
162 | tft.invertDisplay(true);
163 | delay(3000);
164 | printmsg(msgline, "NORMAL DISPLAY");
165 | tft.invertDisplay(false);
166 | delay(3000);
167 | }
168 | }
169 | }
170 |
171 | void testText() {
172 | tft.fillScreen(BLACK);
173 | tft.setCursor(0, 0);
174 | tft.setTextColor(WHITE); tft.setTextSize(1);
175 | tft.println("Hello World!");
176 | tft.setTextColor(YELLOW); tft.setTextSize(2);
177 | tft.println(123.45);
178 | tft.setTextColor(RED); tft.setTextSize(3);
179 | tft.println(0xDEADBEEF, HEX);
180 | tft.println();
181 | tft.setTextColor(GREEN);
182 | tft.setTextSize(5);
183 | tft.println("Groop");
184 | tft.setTextSize(2);
185 | tft.println("I implore thee,");
186 | tft.setTextSize(1);
187 | tft.println("my foonting turlingdromes.");
188 | tft.println("And hooptiously drangle me");
189 | tft.println("with crinkly bindlewurdles,");
190 | tft.println("Or I will rend thee");
191 | tft.println("in the gobberwarts");
192 | tft.println("with my blurglecruncheon,");
193 | tft.println("see if I don't!");
194 | }
195 |
196 | void printmsg(int row, const char *msg)
197 | {
198 | static char primary_msg[64];
199 |
200 | if (strlen(primary_msg)) {
201 | tft.setTextColor(BLACK, BLACK);
202 | tft.setCursor(0, row);
203 | tft.println(primary_msg);
204 | }
205 | tft.setTextColor(YELLOW, BLACK);
206 | tft.setCursor(0, row);
207 | tft.println(msg);
208 | strcpy(primary_msg,msg);
209 | }
210 |
211 |
212 |
213 |
--------------------------------------------------------------------------------
/examples/ScrollTest_STM32/icons.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | const uint8_t 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 | const unsigned char PROGMEM wifi_full[2048] = {
410 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x21, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2,
411 | 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2,
412 | 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2,
413 | 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x71, 0xC2, 0x41, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 | 0x00, 0x00, 0x28, 0xA0, 0xCB, 0x23, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
415 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
416 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
417 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xC3, 0x03, 0x18, 0x60, 0x00, 0x00,
418 | 0x08, 0x20, 0xD3, 0x23, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
419 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
420 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
421 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xC3, 0x03, 0x00, 0x00,
422 | 0x59, 0x61, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
423 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
424 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
425 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x41, 0x01,
426 | 0x8A, 0x22, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
427 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
428 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
429 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
430 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
431 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
432 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
433 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
434 | 0x92, 0x42, 0xF4, 0x89, 0xFE, 0x34, 0xFE, 0xB7, 0xFF, 0x19, 0xFF, 0x3A, 0xFF, 0x3A, 0xFE, 0xD8,
435 | 0xFE, 0x76, 0xF5, 0xD1, 0xF5, 0x0C, 0xEB, 0xE6, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
436 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
437 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
438 | 0x92, 0x42, 0xF4, 0xEC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
439 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x19, 0xF5, 0x90, 0xEC, 0x06, 0xEB, 0xA4,
440 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
441 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
442 | 0x92, 0x42, 0xF4, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
443 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x54,
444 | 0xF4, 0x47, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
445 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
446 | 0x92, 0x42, 0xEB, 0xA4, 0xFF, 0x9D, 0xFF, 0xFF, 0xFF, 0xBD, 0xFF, 0x7C, 0xFF, 0x7C, 0xFF, 0x9D,
447 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
448 | 0xFF, 0xFF, 0xF6, 0x13, 0xEB, 0xE5, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
449 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
450 | 0x92, 0x42, 0xEB, 0xA4, 0xF4, 0x47, 0xEB, 0xE5, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
451 | 0xEB, 0xC4, 0xF4, 0x48, 0xF5, 0x2E, 0xFE, 0x55, 0xFF, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
452 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7C, 0xF4, 0xAA, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
453 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
454 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
455 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xC4, 0xF5, 0x0C, 0xFE, 0xF9, 0xFF, 0xFF,
456 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xB1, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
457 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
458 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xF4, 0x27, 0xF4, 0xCB, 0xF5, 0x0C, 0xF5, 0x0C,
459 | 0xF4, 0xAB, 0xF4, 0x27, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xF4, 0xEC,
460 | 0xFF, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x34, 0xEB, 0xC4, 0xEB, 0xA4,
461 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
462 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xFE, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
463 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9D, 0xFE, 0x76, 0xF4, 0xEC, 0xEB, 0xC4, 0xEB, 0xA4, 0xEB, 0xA4,
464 | 0xEB, 0xC5, 0xFE, 0x34, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x55, 0xEB, 0xA4,
465 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
466 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xF6, 0x13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
467 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7C, 0xF5, 0x6F, 0xEB, 0xC4,
468 | 0xEB, 0xA4, 0xEB, 0xA4, 0xF5, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xF2,
469 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
470 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xF4, 0x69, 0xF5, 0x0C, 0xF4, 0xAA, 0xF4, 0x89,
471 | 0xF4, 0xCB, 0xF5, 0x6F, 0xFE, 0x55, 0xFF, 0x9D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A,
472 | 0xF4, 0x48, 0xEB, 0xA4, 0xEB, 0xA4, 0xF5, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
473 | 0xF5, 0x0D, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
474 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
475 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xC4, 0xF4, 0xEC, 0xFF, 0x19, 0xFF, 0xFF, 0xFF, 0xFF,
476 | 0xFF, 0xDE, 0xF5, 0x0D, 0xEB, 0xA4, 0xEB, 0xA4, 0xF5, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
477 | 0xFF, 0xBE, 0xF4, 0x27, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
478 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
479 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xF5, 0x4E, 0xFF, 0xDE,
480 | 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x4E, 0xEB, 0xA4, 0xEB, 0xA4, 0xFE, 0x54, 0xFF, 0xFF, 0xFF, 0xFF,
481 | 0xFF, 0xFF, 0xFE, 0xB7, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
482 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xC4, 0xFF, 0x3A, 0xFF, 0x9D,
483 | 0xFF, 0x9C, 0xFF, 0x19, 0xF6, 0x13, 0xF4, 0xAA, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xF4, 0x48,
484 | 0xFF, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xEC, 0xEB, 0xA4, 0xEB, 0xC5, 0xFF, 0x7C, 0xFF, 0xFF,
485 | 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xEC, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
486 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xFE, 0xD8, 0xFF, 0x19,
487 | 0xFF, 0x19, 0xFF, 0x9C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0xF4, 0xAA, 0xEB, 0xA4, 0xEB, 0xA4,
488 | 0xF4, 0x47, 0xFF, 0x9D, 0xFF, 0xFF, 0xFF, 0xBE, 0xF4, 0x47, 0xEB, 0xA4, 0xF4, 0xEC, 0xFF, 0xFF,
489 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x19, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
490 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
491 | 0xEB, 0xA4, 0xEB, 0xA4, 0xF4, 0x27, 0xF5, 0xD1, 0xFF, 0xBD, 0xFF, 0xFF, 0xF5, 0xD2, 0xEB, 0xA4,
492 | 0xEB, 0xA4, 0xF4, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xD8, 0xEB, 0xA4, 0xEB, 0xA4, 0xFE, 0xF9,
493 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xCB, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
494 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
495 | 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEC, 0x06, 0xFE, 0xB7, 0xFF, 0xFF, 0xFE, 0x34,
496 | 0xEB, 0xA4, 0xEB, 0xA4, 0xF6, 0x13, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xEC, 0xEB, 0xA4, 0xF5, 0x0C,
497 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x55, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
498 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4,
499 | 0xF4, 0x27, 0xF5, 0x4E, 0xF5, 0x2D, 0xEB, 0xE5, 0xEB, 0xA4, 0xEB, 0xC4, 0xFE, 0x96, 0xFF, 0xFF,
500 | 0xF5, 0x6F, 0xEB, 0xA4, 0xEB, 0xE5, 0xFF, 0xBE, 0xFF, 0xFF, 0xFE, 0xF9, 0xEB, 0xA4, 0xEB, 0xC4,
501 | 0xFF, 0x9D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xEB, 0xC5, 0xEB, 0xA4, 0xEB, 0xA4, 0x71, 0xC2,
502 | 0x92, 0x42, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xEB, 0xA4, 0xF4, 0xEC,
503 | 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9D, 0xEC, 0x48, 0xEB, 0x84, 0xEB, 0xC5, 0xFF, 0x5B,
504 | 0xFF, 0xDE, 0xEC, 0x07, 0xE3, 0x84, 0xF5, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0x28, 0xE3, 0x84,
505 | 0xF6, 0x14, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xAB, 0xE3, 0x64, 0xE3, 0x64, 0x79, 0xE2,
506 | 0xAA, 0x64, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0xC5, 0xFF, 0xFF,
507 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x98, 0xB2, 0x84, 0xB2, 0x84, 0xC4, 0x0C,
508 | 0xFF, 0xFF, 0xDD, 0x93, 0xB2, 0x84, 0xBB, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0x11, 0xB2, 0x84,
509 | 0xCC, 0x4D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0x32, 0xB2, 0x84, 0xB2, 0x84, 0x92, 0x23,
510 | 0xAA, 0x64, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xC3, 0x8A, 0xFF, 0xFF,
511 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
512 | 0xF7, 0x3B, 0xFF, 0x9D, 0xB2, 0x85, 0xB2, 0x84, 0xF7, 0x5C, 0xEE, 0xFA, 0xD4, 0xD0, 0xB2, 0x84,
513 | 0xB2, 0xE6, 0xDD, 0x93, 0xCC, 0x6E, 0xBB, 0x68, 0xB2, 0x85, 0xB2, 0x84, 0xB2, 0x84, 0x92, 0x23,
514 | 0xAA, 0x64, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xBB, 0x07, 0xFF, 0xFF,
515 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x5C, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
516 | 0xDD, 0x52, 0xEE, 0xD9, 0xBB, 0x07, 0xB2, 0x84, 0xB2, 0x85, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
517 | 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0x92, 0x23,
518 | 0xA2, 0x64, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xE5, 0xD5,
519 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xAF, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
520 | 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
521 | 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0x92, 0x23,
522 | 0x9A, 0x43, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0xA5,
523 | 0xD4, 0xF0, 0xEE, 0x99, 0xEE, 0x78, 0xCC, 0x4D, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
524 | 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
525 | 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0x79, 0xC3,
526 | 0x81, 0xE3, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
527 | 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
528 | 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
529 | 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0x59, 0x42,
530 | 0x79, 0xC3, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
531 | 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
532 | 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84,
533 | 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0xB2, 0x84, 0x59, 0x42,
534 | 0x51, 0x42, 0x79, 0xC3, 0x79, 0xC3, 0x9A, 0x23, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63,
535 | 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63,
536 | 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63,
537 | 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0xA2, 0x63, 0x92, 0x23, 0x79, 0xC3, 0x79, 0xC3, 0x38, 0xE1,
538 | };
539 |
--------------------------------------------------------------------------------
/examples/TFT_ArcFill_STM32/TFT_ArcFill_STM32.ino:
--------------------------------------------------------------------------------
1 | // Demo based on:
2 | // TFT_ArcFill by Bodmar
3 | // web: https://github.com/Bodmer/TFT_eSPI/tree/master/examples/320%20x%20240/TFT_ArcFill
4 |
5 |
6 | #include
7 | #include "STM32_TFT_8bit.h"
8 |
9 | STM32_TFT_8bit tft;
10 |
11 |
12 | #define DEG2RAD 0.0174532925
13 |
14 | #define LOOP_DELAY 10 // Loop delay to slow things down
15 |
16 | byte inc = 0;
17 | unsigned int col = 0;
18 |
19 | byte red = 31; // Red is the top 5 bits of a 16 bit colour value
20 | byte green = 0;// Green is the middle 6 bits
21 | byte blue = 0; // Blue is the bottom 5 bits
22 | byte state = 0;
23 |
24 | void setup(void) {
25 | Serial.begin(9600);
26 | uint32_t ID = tft.readID();
27 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
28 | tft.begin(ID);
29 |
30 | tft.setRotation(1);
31 |
32 | tft.fillScreen(BLACK);
33 |
34 | }
35 |
36 |
37 | void loop() {
38 |
39 | // Continuous elliptical arc drawing
40 | fillArc(160, 120, inc * 6, 1, 140, 100, 10, rainbow(col));
41 |
42 | // Continuous segmented (inc*2) elliptical arc drawing
43 | fillArc(160, 120, ((inc * 2) % 60) * 6, 1, 120, 80, 30, rainbow(col));
44 |
45 | // Circle drawing using arc with arc width = radius
46 | fillArc(160, 120, inc * 6, 1, 42, 42, 42, rainbow(col));
47 |
48 | inc++;
49 | col += 1;
50 | if (col > 191) col = 0;
51 | if (inc > 59) inc = 0;
52 |
53 | delay(LOOP_DELAY);
54 | }
55 |
56 |
57 | // #########################################################################
58 | // Draw a circular or elliptical arc with a defined thickness
59 | // #########################################################################
60 |
61 | // x,y == coords of centre of arc
62 | // start_angle = 0 - 359
63 | // seg_count = number of 6 degree segments to draw (60 => 360 degree arc)
64 | // rx = x axis outer radius
65 | // ry = y axis outer radius
66 | // w = width (thickness) of arc in pixels
67 | // colour = 16 bit colour value
68 | // Note if rx and ry are the same then an arc of a circle is drawn
69 |
70 | int fillArc(int x, int y, int start_angle, int seg_count, int rx, int ry, int w, unsigned int colour)
71 | {
72 |
73 | byte seg = 6; // Segments are 3 degrees wide = 120 segments for 360 degrees
74 | byte inc = 6; // Draw segments every 3 degrees, increase to 6 for segmented ring
75 |
76 | // Calculate first pair of coordinates for segment start
77 | float sx = cos((start_angle - 90) * DEG2RAD);
78 | float sy = sin((start_angle - 90) * DEG2RAD);
79 | uint16_t x0 = sx * (rx - w) + x;
80 | uint16_t y0 = sy * (ry - w) + y;
81 | uint16_t x1 = sx * rx + x;
82 | uint16_t y1 = sy * ry + y;
83 |
84 | // Draw colour blocks every inc degrees
85 | for (int i = start_angle; i < start_angle + seg * seg_count; i += inc) {
86 |
87 | // Calculate pair of coordinates for segment end
88 | float sx2 = cos((i + seg - 90) * DEG2RAD);
89 | float sy2 = sin((i + seg - 90) * DEG2RAD);
90 | int x2 = sx2 * (rx - w) + x;
91 | int y2 = sy2 * (ry - w) + y;
92 | int x3 = sx2 * rx + x;
93 | int y3 = sy2 * ry + y;
94 |
95 | tft.fillTriangle(x0, y0, x1, y1, x2, y2, colour);
96 | tft.fillTriangle(x1, y1, x2, y2, x3, y3, colour);
97 |
98 | // Copy segment end to sgement start for next segment
99 | x0 = x2;
100 | y0 = y2;
101 | x1 = x3;
102 | y1 = y3;
103 | }
104 | }
105 |
106 | // #########################################################################
107 | // Return the 16 bit colour with brightness 0-100%
108 | // #########################################################################
109 | unsigned int brightness(unsigned int colour, int brightness)
110 | {
111 | byte red = colour >> 11;
112 | byte green = (colour & 0x7E0) >> 5;
113 | byte blue = colour & 0x1F;
114 |
115 | blue = (blue * brightness) / 100;
116 | green = (green * brightness) / 100;
117 | red = (red * brightness) / 100;
118 |
119 | return (red << 11) + (green << 5) + blue;
120 | }
121 |
122 | // #########################################################################
123 | // Return a 16 bit rainbow colour
124 | // #########################################################################
125 | unsigned int rainbow(byte value)
126 | {
127 | // Value is expected to be in range 0-127
128 | // The value is converted to a spectrum colour from 0 = blue through to 127 = red
129 |
130 | switch (state) {
131 | case 0:
132 | green ++;
133 | if (green == 64) {
134 | green = 63;
135 | state = 1;
136 | }
137 | break;
138 | case 1:
139 | red--;
140 | if (red == 255) {
141 | red = 0;
142 | state = 2;
143 | }
144 | break;
145 | case 2:
146 | blue ++;
147 | if (blue == 32) {
148 | blue = 31;
149 | state = 3;
150 | }
151 | break;
152 | case 3:
153 | green --;
154 | if (green == 255) {
155 | green = 0;
156 | state = 4;
157 | }
158 | break;
159 | case 4:
160 | red ++;
161 | if (red == 32) {
162 | red = 31;
163 | state = 5;
164 | }
165 | break;
166 | case 5:
167 | blue --;
168 | if (blue == 255) {
169 | blue = 0;
170 | state = 0;
171 | }
172 | break;
173 | }
174 | return red << 11 | green << 5 | blue;
175 | }
176 |
177 |
--------------------------------------------------------------------------------
/examples/TFT_Meter_linear_STM32/TFT_Meter_linear_STM32.ino:
--------------------------------------------------------------------------------
1 | // Demo based on:
2 | // TFT_Meter_linear by Bodmar
3 | // web: https://github.com/Bodmer/TFT_eSPI/tree/master/examples/320%20x%20240/TFT_Meter_linear
4 |
5 |
6 | // Define meter size as 1 for tft.rotation(0) or 1.3333 for tft.rotation(1)
7 | #define M_SIZE 1.3333
8 |
9 | #include
10 | #include
11 | #include "STM32_TFT_8bit.h"
12 |
13 | STM32_TFT_8bit tft;
14 |
15 | #define TFT_GREY GRAY
16 | #define TFT_BLACK BLACK
17 | #define TFT_WHITE WHITE
18 | #define TFT_GREEN GREEN
19 | #define TFT_ORANGE ORANGE
20 | #define TFT_RED RED
21 | #define TFT_MAGENTA MAGENTA
22 |
23 | float ltx = 0; // Saved x coord of bottom of needle
24 | uint16_t osx = M_SIZE*120, osy = M_SIZE*120; // Saved x & y coords
25 | uint32_t updateTime = 0; // time for next update
26 |
27 | int old_analog = -999; // Value last displayed
28 |
29 | int value[6] = {0, 0, 0, 0, 0, 0};
30 | int old_value[6] = { -1, -1, -1, -1, -1, -1};
31 | int d = 0;
32 |
33 | void setup(void) {
34 | Serial.begin(9600);
35 | uint32_t ID = tft.readID();
36 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
37 | tft.begin(ID);
38 | tft.setRotation(1);
39 | tft.fillScreen(TFT_BLACK);
40 |
41 | analogMeter(); // Draw analogue meter
42 |
43 | updateTime = millis(); // Next update time
44 | }
45 |
46 |
47 | void loop() {
48 | if (updateTime <= millis()) {
49 | updateTime = millis() + 35; // Update emter every 35 milliseconds
50 |
51 | // Create a Sine wave for testing
52 | d += 4; if (d >= 360) d = 0;
53 | value[0] = 50 + 50 * sin((d + 0) * 0.0174532925);
54 |
55 | plotNeedle(value[0], 0); // It takes between 2 and 12ms to replot the needle with zero delay
56 | }
57 | }
58 |
59 |
60 | // #########################################################################
61 | // Draw the analogue meter on the screen
62 | // #########################################################################
63 | void analogMeter()
64 | {
65 |
66 | // Meter outline
67 | tft.fillRect(0, 0, M_SIZE*239, M_SIZE*126, TFT_GREY);
68 | tft.fillRect(5, 3, M_SIZE*230, M_SIZE*119, TFT_WHITE);
69 |
70 | tft.setTextColor(TFT_BLACK); // Text colour
71 |
72 | // Draw ticks every 5 degrees from -50 to +50 degrees (100 deg. FSD swing)
73 | for (int i = -50; i < 51; i += 5) {
74 | // Long scale tick length
75 | int tl = 15;
76 |
77 | // Coodinates of tick to draw
78 | float sx = cos((i - 90) * 0.0174532925);
79 | float sy = sin((i - 90) * 0.0174532925);
80 | uint16_t x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120;
81 | uint16_t y0 = sy * (M_SIZE*100 + tl) + M_SIZE*140;
82 | uint16_t x1 = sx * M_SIZE*100 + M_SIZE*120;
83 | uint16_t y1 = sy * M_SIZE*100 + M_SIZE*140;
84 |
85 | // Coordinates of next tick for zone fill
86 | float sx2 = cos((i + 5 - 90) * 0.0174532925);
87 | float sy2 = sin((i + 5 - 90) * 0.0174532925);
88 | int x2 = sx2 * (M_SIZE*100 + tl) + M_SIZE*120;
89 | int y2 = sy2 * (M_SIZE*100 + tl) + M_SIZE*140;
90 | int x3 = sx2 * M_SIZE*100 + M_SIZE*120;
91 | int y3 = sy2 * M_SIZE*100 + M_SIZE*140;
92 |
93 | // Yellow zone limits
94 | //if (i >= -50 && i < 0) {
95 | // tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_YELLOW);
96 | // tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_YELLOW);
97 | //}
98 |
99 | // Green zone limits
100 | if (i >= 0 && i < 25) {
101 | tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_GREEN);
102 | tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREEN);
103 | }
104 |
105 | // Orange zone limits
106 | if (i >= 25 && i < 50) {
107 | tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_ORANGE);
108 | tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_ORANGE);
109 | }
110 |
111 | // Short scale tick length
112 | if (i % 25 != 0) tl = 8;
113 |
114 | // Recalculate coords incase tick lenght changed
115 | x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120;
116 | y0 = sy * (M_SIZE*100 + tl) + M_SIZE*140;
117 | x1 = sx * M_SIZE*100 + M_SIZE*120;
118 | y1 = sy * M_SIZE*100 + M_SIZE*140;
119 |
120 | // Draw tick
121 | tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
122 |
123 | // Check if labels should be drawn, with position tweaks
124 | if (i % 25 == 0) {
125 | // Calculate label positions
126 | x0 = sx * (M_SIZE*100 + tl + 10) + M_SIZE*120;
127 | y0 = sy * (M_SIZE*100 + tl + 10) + M_SIZE*140;
128 | switch (i / 25) {
129 | #if 0
130 | case -2: tft.drawCentreString("0", x0, y0 - 12, 2); break;
131 | case -1: tft.drawCentreString("25", x0, y0 - 9, 2); break;
132 | case 0: tft.drawCentreString("50", x0, y0 - 7, 2); break;
133 | case 1: tft.drawCentreString("75", x0, y0 - 9, 2); break;
134 | case 2: tft.drawCentreString("100", x0, y0 - 12, 2); break;
135 | #endif
136 | case -2: _drawString("0", x0-10, y0 - 12, 2); break;
137 | case -1: _drawString("25", x0-10, y0 - 9, 2); break;
138 | case 0: _drawString("50", x0-10, y0 - 7, 2); break;
139 | case 1: _drawString("75", x0-10, y0 - 9, 2); break;
140 | case 2: _drawString("100", x0-10, y0 - 12, 2); break;
141 | }
142 | }
143 |
144 | // Now draw the arc of the scale
145 | sx = cos((i + 5 - 90) * 0.0174532925);
146 | sy = sin((i + 5 - 90) * 0.0174532925);
147 | x0 = sx * M_SIZE*100 + M_SIZE*120;
148 | y0 = sy * M_SIZE*100 + M_SIZE*140;
149 | // Draw scale arc, don't draw the last part
150 | if (i < 50) tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
151 | }
152 |
153 | _drawString("%RH", M_SIZE*(5 + 230 - 40), M_SIZE*(119 - 20), 2); // Units at bottom right
154 | //tft.drawString("%RH", M_SIZE*(5 + 230 - 40), M_SIZE*(119 - 20), 2); // Units at bottom right
155 |
156 | //tft.drawCentreString("%RH", M_SIZE*120, M_SIZE*70, 4); // Comment out to avoid font 4
157 |
158 | tft.drawRect(5, 3, M_SIZE*230, M_SIZE*119, TFT_BLACK); // Draw bezel line
159 | plotNeedle(0, 0); // Put meter needle at 0
160 | }
161 |
162 | // #########################################################################
163 | // Update needle position
164 | // This function is blocking while needle moves, time depends on ms_delay
165 | // 10ms minimises needle flicker if text is drawn within needle sweep area
166 | // Smaller values OK if text not in sweep area, zero for instant movement but
167 | // does not look realistic... (note: 100 increments for full scale deflection)
168 | // #########################################################################
169 | void plotNeedle(int value, byte ms_delay)
170 | {
171 | tft.setTextColor(TFT_BLACK, TFT_WHITE);
172 | char buf[8]; dtostrf(value, 4, 0, buf);
173 | _drawString("%RH", M_SIZE*(5 + 230 - 40), M_SIZE*(119 - 20), 2); // Units at bottom right
174 | //tft.drawString("%RH", M_SIZE*(5 + 230 - 40), M_SIZE*(119 - 20), 2); // Units at bottom right
175 | _drawString(buf, M_SIZE*40-40, M_SIZE*(119 - 20), 2);
176 | //tft.drawRightString(buf, M_SIZE*40, M_SIZE*(119 - 20), 2);
177 |
178 | if (value < -10) value = -10; // Limit value to emulate needle end stops
179 | if (value > 110) value = 110;
180 |
181 | // Move the needle until new value reached
182 | while (!(value == old_analog)) {
183 | if (old_analog < value) old_analog++;
184 | else old_analog--;
185 |
186 | if (ms_delay == 0) old_analog = value; // Update immediately if delay is 0
187 |
188 | float sdeg = map(old_analog, -10, 110, -150, -30); // Map value to angle
189 | // Calcualte tip of needle coords
190 | float sx = cos(sdeg * 0.0174532925);
191 | float sy = sin(sdeg * 0.0174532925);
192 |
193 | // Calculate x delta of needle start (does not start at pivot point)
194 | float tx = tan((sdeg + 90) * 0.0174532925);
195 |
196 | // Erase old needle image
197 | tft.drawLine(M_SIZE*(120 + 20 * ltx - 1), M_SIZE*(140 - 20), osx - 1, osy, TFT_WHITE);
198 | tft.drawLine(M_SIZE*(120 + 20 * ltx), M_SIZE*(140 - 20), osx, osy, TFT_WHITE);
199 | tft.drawLine(M_SIZE*(120 + 20 * ltx + 1), M_SIZE*(140 - 20), osx + 1, osy, TFT_WHITE);
200 |
201 | // Re-plot text under needle
202 | tft.setTextColor(TFT_BLACK);
203 | tft.setFont(&FreeMonoBold24pt7b);
204 | _drawString("%RH", M_SIZE*80, M_SIZE*100, 1); // // Comment out to avoid font 4
205 | tft.setFont();
206 | //tft.drawCentreString("%RH", M_SIZE*120, M_SIZE*70, 4); // // Comment out to avoid font 4
207 |
208 | // Store new needle end coords for next erase
209 | ltx = tx;
210 | osx = M_SIZE*(sx * 98 + 120);
211 | osy = M_SIZE*(sy * 98 + 140);
212 |
213 | // Draw the needle in the new postion, magenta makes needle a bit bolder
214 | // draws 3 lines to thicken needle
215 | tft.drawLine(M_SIZE*(120 + 20 * ltx - 1), M_SIZE*(140 - 20), osx - 1, osy, TFT_RED);
216 | tft.drawLine(M_SIZE*(120 + 20 * ltx), M_SIZE*(140 - 20), osx, osy, TFT_MAGENTA);
217 | tft.drawLine(M_SIZE*(120 + 20 * ltx + 1), M_SIZE*(140 - 20), osx + 1, osy, TFT_RED);
218 |
219 | // Slow needle down slightly as it approaches new postion
220 | if (abs(old_analog - value) < 10) ms_delay += ms_delay / 5;
221 |
222 | // Wait before next update
223 | delay(ms_delay);
224 | }
225 | }
226 |
227 | void _drawString(char *buf, int16_t x, int16_t y, int16_t size)
228 | {
229 | tft.setTextSize(size);
230 | tft.setCursor(x, y);
231 | tft.print(buf);
232 | }
233 |
--------------------------------------------------------------------------------
/examples/TFT_Meters_STM32/TFT_Meters_STM32.ino:
--------------------------------------------------------------------------------
1 | // Demo based on:
2 | // TFT_Meters by Bodmar
3 | // web: https://github.com/Bodmer/TFT_eSPI/tree/master/examples/320%20x%20240/TFT_Meters
4 |
5 |
6 |
7 | #include
8 | #include
9 | #include "STM32_TFT_8bit.h"
10 |
11 | STM32_TFT_8bit tft;
12 |
13 | #define TFT_GREY GRAY
14 | #define TFT_BLACK BLACK
15 | #define TFT_WHITE WHITE
16 | #define TFT_GREEN GREEN
17 | #define TFT_ORANGE ORANGE
18 | #define TFT_RED RED
19 | #define TFT_CYAN CYAN
20 | #define TFT_MAGENTA MAGENTA
21 |
22 | #define LOOP_PERIOD 35 // Display updates every 35 ms
23 |
24 | float ltx = 0; // Saved x coord of bottom of needle
25 | uint16_t osx = 120, osy = 120; // Saved x & y coords
26 | uint32_t updateTime = 0; // time for next update
27 | int16_t LinearY = 150;
28 |
29 | int old_analog = -999; // Value last displayed
30 | int old_digital = -999; // Value last displayed
31 |
32 | int value[6] = {0, 0, 0, 0, 0, 0};
33 | int old_value[6] = { -1, -1, -1, -1, -1, -1};
34 | int d = 0;
35 |
36 | void setup(void) {
37 | Serial.begin(9600);
38 | uint32_t ID = tft.readID();
39 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
40 | tft.begin(ID);
41 | tft.setRotation(0);
42 | Serial.begin(57600); // For debug
43 | tft.fillScreen(TFT_BLACK);
44 |
45 | analogMeter(); // Draw analogue meter
46 |
47 | // Draw 6 linear meters
48 | byte d = 40;
49 | plotLinear("A0", 0, LinearY);
50 | plotLinear("A1", 1 * d, LinearY);
51 | plotLinear("A2", 2 * d, LinearY);
52 | plotLinear("A3", 3 * d, LinearY);
53 | plotLinear("A4", 4 * d, LinearY);
54 | plotLinear("A5", 5 * d, LinearY);
55 |
56 | updateTime = millis(); // Next update time
57 | }
58 |
59 |
60 | void loop() {
61 | if (updateTime <= millis()) {
62 | updateTime = millis() + LOOP_PERIOD;
63 |
64 | d += 4; if (d >= 360) d = 0;
65 |
66 | //value[0] = map(analogRead(A0), 0, 1023, 0, 100); // Test with value form Analogue 0
67 |
68 | // Create a Sine wave for testing
69 | value[0] = 50 + 50 * sin((d + 0) * 0.0174532925);
70 | value[1] = 50 + 50 * sin((d + 60) * 0.0174532925);
71 | value[2] = 50 + 50 * sin((d + 120) * 0.0174532925);
72 | value[3] = 50 + 50 * sin((d + 180) * 0.0174532925);
73 | value[4] = 50 + 50 * sin((d + 240) * 0.0174532925);
74 | value[5] = 50 + 50 * sin((d + 300) * 0.0174532925);
75 |
76 | //unsigned long t = millis();
77 |
78 | plotPointer(LinearY);
79 |
80 | plotNeedle(value[0], 0);
81 |
82 | //Serial.println(millis()-t); // Print time taken for meter update
83 | }
84 | }
85 |
86 |
87 | // #########################################################################
88 | // Draw the analogue meter on the screen
89 | // #########################################################################
90 | void analogMeter()
91 | {
92 | // Meter outline
93 | tft.fillRect(0, 0, 239, 126, TFT_GREY);
94 | tft.fillRect(5, 3, 230, 119, TFT_WHITE);
95 |
96 | tft.setTextColor(TFT_BLACK); // Text colour
97 |
98 | // Draw ticks every 5 degrees from -50 to +50 degrees (100 deg. FSD swing)
99 | for (int i = -50; i < 51; i += 5) {
100 | // Long scale tick length
101 | int tl = 15;
102 |
103 | // Coodinates of tick to draw
104 | float sx = cos((i - 90) * 0.0174532925);
105 | float sy = sin((i - 90) * 0.0174532925);
106 | uint16_t x0 = sx * (100 + tl) + 120;
107 | uint16_t y0 = sy * (100 + tl) + 140;
108 | uint16_t x1 = sx * 100 + 120;
109 | uint16_t y1 = sy * 100 + 140;
110 |
111 | // Coordinates of next tick for zone fill
112 | float sx2 = cos((i + 5 - 90) * 0.0174532925);
113 | float sy2 = sin((i + 5 - 90) * 0.0174532925);
114 | int x2 = sx2 * (100 + tl) + 120;
115 | int y2 = sy2 * (100 + tl) + 140;
116 | int x3 = sx2 * 100 + 120;
117 | int y3 = sy2 * 100 + 140;
118 |
119 | // Yellow zone limits
120 | //if (i >= -50 && i < 0) {
121 | // tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_YELLOW);
122 | // tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_YELLOW);
123 | //}
124 |
125 | // Green zone limits
126 | if (i >= 0 && i < 25) {
127 | tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_GREEN);
128 | tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREEN);
129 | }
130 |
131 | // Orange zone limits
132 | if (i >= 25 && i < 50) {
133 | tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_ORANGE);
134 | tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_ORANGE);
135 | }
136 |
137 | // Short scale tick length
138 | if (i % 25 != 0) tl = 8;
139 |
140 | // Recalculate coords incase tick lenght changed
141 | x0 = sx * (100 + tl) + 120;
142 | y0 = sy * (100 + tl) + 140;
143 | x1 = sx * 100 + 120;
144 | y1 = sy * 100 + 140;
145 |
146 | // Draw tick
147 | tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
148 |
149 | // Check if labels should be drawn, with position tweaks
150 | if (i % 25 == 0) {
151 | // Calculate label positions
152 | x0 = sx * (100 + tl + 10) + 120;
153 | y0 = sy * (100 + tl + 10) + 140;
154 | switch (i / 25) {
155 | #if 0
156 | case -2: tft.drawCentreString("0", x0, y0 - 12, 2); break;
157 | case -1: tft.drawCentreString("25", x0, y0 - 9, 2); break;
158 | case 0: tft.drawCentreString("50", x0, y0 - 6, 2); break;
159 | case 1: tft.drawCentreString("75", x0, y0 - 9, 2); break;
160 | case 2: tft.drawCentreString("100", x0, y0 - 12, 2); break;
161 | #endif
162 | case -2: _drawString("0", x0-10, y0 - 12, 2); break;
163 | case -1: _drawString("25", x0-10, y0 - 9, 2); break;
164 | case 0: _drawString("50", x0-10, y0 - 6, 2); break;
165 | case 1: _drawString("75", x0-10, y0 - 9, 2); break;
166 | case 2: _drawString("100", x0-15, y0 - 12, 2); break;
167 | }
168 | }
169 |
170 | // Now draw the arc of the scale
171 | sx = cos((i + 5 - 90) * 0.0174532925);
172 | sy = sin((i + 5 - 90) * 0.0174532925);
173 | x0 = sx * 100 + 120;
174 | y0 = sy * 100 + 140;
175 | // Draw scale arc, don't draw the last part
176 | if (i < 50) tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
177 | }
178 |
179 | _drawString("%RH", 5 + 230 - 40, 119 - 20, 2); // Units at bottom right
180 | //tft.drawString("%RH", 5 + 230 - 40, 119 - 20, 2); // Units at bottom right
181 | //tft.drawCentreString("%RH", 120, 70, 4); // Comment out to avoid font 4
182 | tft.drawRect(5, 3, 230, 119, TFT_BLACK); // Draw bezel line
183 |
184 | plotNeedle(0, 0); // Put meter needle at 0
185 | }
186 |
187 | // #########################################################################
188 | // Update needle position
189 | // This function is blocking while needle moves, time depends on ms_delay
190 | // 10ms minimises needle flicker if text is drawn within needle sweep area
191 | // Smaller values OK if text not in sweep area, zero for instant movement but
192 | // does not look realistic... (note: 100 increments for full scale deflection)
193 | // #########################################################################
194 | void plotNeedle(int value, byte ms_delay)
195 | {
196 | tft.setTextColor(TFT_BLACK, TFT_WHITE);
197 | char buf[8]; dtostrf(value, 3, 0, buf);
198 | _drawString(buf, 10, 119 - 20, 2);
199 | //tft.drawRightString(buf, 40, 119 - 20, 2);
200 |
201 | if (value < -10) value = -10; // Limit value to emulate needle end stops
202 | if (value > 110) value = 110;
203 |
204 | // Move the needle util new value reached
205 | while (!(value == old_analog)) {
206 | if (old_analog < value) old_analog++;
207 | else old_analog--;
208 |
209 | if (ms_delay == 0) old_analog = value; // Update immediately id delay is 0
210 |
211 | float sdeg = map(old_analog, -10, 110, -150, -30); // Map value to angle
212 | // Calcualte tip of needle coords
213 | float sx = cos(sdeg * 0.0174532925);
214 | float sy = sin(sdeg * 0.0174532925);
215 |
216 | // Calculate x delta of needle start (does not start at pivot point)
217 | float tx = tan((sdeg + 90) * 0.0174532925);
218 |
219 | // Erase old needle image
220 | tft.drawLine(120 + 20 * ltx - 1, 140 - 20, osx - 1, osy, TFT_WHITE);
221 | tft.drawLine(120 + 20 * ltx, 140 - 20, osx, osy, TFT_WHITE);
222 | tft.drawLine(120 + 20 * ltx + 1, 140 - 20, osx + 1, osy, TFT_WHITE);
223 |
224 | // Re-plot text under needle
225 | tft.setTextColor(TFT_BLACK);
226 | tft.setFont(&FreeMonoBold18pt7b);
227 | _drawString("%RH", 80, 100, 1); // // Comment out to avoid font 4
228 | tft.setFont();
229 | //tft.drawCentreString("%RH", 120, 70, 4); // // Comment out to avoid font 4
230 |
231 | // Store new needle end coords for next erase
232 | ltx = tx;
233 | osx = sx * 98 + 120;
234 | osy = sy * 98 + 140;
235 |
236 | // Draw the needle in the new postion, magenta makes needle a bit bolder
237 | // draws 3 lines to thicken needle
238 | tft.drawLine(120 + 20 * ltx - 1, 140 - 20, osx - 1, osy, TFT_RED);
239 | tft.drawLine(120 + 20 * ltx, 140 - 20, osx, osy, TFT_MAGENTA);
240 | tft.drawLine(120 + 20 * ltx + 1, 140 - 20, osx + 1, osy, TFT_RED);
241 |
242 | // Slow needle down slightly as it approaches new postion
243 | if (abs(old_analog - value) < 10) ms_delay += ms_delay / 5;
244 |
245 | // Wait before next update
246 | delay(ms_delay);
247 | }
248 | }
249 |
250 | // #########################################################################
251 | // Draw a linear meter on the screen
252 | // #########################################################################
253 | void plotLinear(char *label, int x, int y)
254 | {
255 | int w = 36;
256 | tft.drawRect(x, y, w, 155, TFT_GREY);
257 | tft.fillRect(x + 2, y + 19, w - 3, 155 - 38, TFT_WHITE);
258 | tft.setTextColor(TFT_CYAN, TFT_BLACK);
259 | _drawString(label, (x + w / 2) - 10, y + 2, 2);
260 | //tft.drawCentreString(label, x + w / 2, y + 2, 2);
261 |
262 | for (int i = 0; i < 110; i += 10)
263 | {
264 | tft.drawFastHLine(x + 20, y + 27 + i, 6, TFT_BLACK);
265 | }
266 |
267 | for (int i = 0; i < 110; i += 50)
268 | {
269 | tft.drawFastHLine(x + 20, y + 27 + i, 9, TFT_BLACK);
270 | }
271 |
272 | tft.fillTriangle(x + 3, y + 127, x + 3 + 16, y + 127, x + 3, y + 127 - 5, TFT_RED);
273 | tft.fillTriangle(x + 3, y + 127, x + 3 + 16, y + 127, x + 3, y + 127 + 5, TFT_RED);
274 |
275 | //_drawString("---", (x + w / 2) - 18, y + 155 - 18, 2);
276 | //tft.drawCentreString("---", x + w / 2, y + 155 - 18, 2);
277 | }
278 |
279 | // #########################################################################
280 | // Adjust 6 linear meter pointer positions
281 | // #########################################################################
282 | void plotPointer(int y)
283 | {
284 | // int dy0 = 187;
285 | int dy0 = y + 27;
286 | byte pw = 16;
287 |
288 | tft.setTextColor(TFT_GREEN, TFT_BLACK);
289 |
290 | // Move the 6 pointers one pixel towards new value
291 | for (int i = 0; i < 6; i++)
292 | {
293 | char buf[8]; dtostrf(value[i], 3, 0, buf);
294 | // _drawString(buf, (i * 40 + 36 - 5) - 50, 187 - 27 + 155 - 18, 2);
295 | _drawString(buf, (i * 40 + 36 - 5) - 35, y + 137, 2);
296 | //tft.drawRightString(buf, i * 40 + 36 - 5, 187 - 27 + 155 - 18, 2);
297 |
298 | int dx = 3 + 40 * i;
299 | if (value[i] < 0) value[i] = 0; // Limit value to emulate needle end stops
300 | if (value[i] > 100) value[i] = 100;
301 |
302 | int dy;
303 | while (!(value[i] == old_value[i])) {
304 | //dy = 187 + 100 - old_value[i];
305 | dy = dy0 + 100 - old_value[i];
306 | if (old_value[i] > value[i])
307 | {
308 | tft.drawLine(dx, dy - 5, dx + pw, dy, TFT_WHITE);
309 | old_value[i]--;
310 | tft.drawLine(dx, dy + 6, dx + pw, dy + 1, TFT_RED);
311 | }
312 | else
313 | {
314 | tft.drawLine(dx, dy + 5, dx + pw, dy, TFT_WHITE);
315 | old_value[i]++;
316 | tft.drawLine(dx, dy - 6, dx + pw, dy - 1, TFT_RED);
317 | }
318 | }
319 | }
320 | }
321 |
322 | void _drawString(char *buf, int16_t x, int16_t y, int16_t size)
323 | {
324 | tft.setTextSize(size);
325 | tft.setCursor(x, y);
326 | tft.print(buf);
327 | }
328 |
--------------------------------------------------------------------------------
/examples/TFT_Pong_STM32/TFT_Pong_STM32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * Pong
3 | * Original Code from https://github.com/rparrett/pongclock
4 | *
5 | * Demo based on:
6 | * TFT_Pong by Bodmar
7 | * web: https://github.com/Bodmer/TFT_eSPI/tree/master/examples/320%20x%20240/TFT_Pong
8 | */
9 |
10 | // Demo only - not playable
11 |
12 | #include
13 | #include "STM32_TFT_8bit.h"
14 |
15 | STM32_TFT_8bit tft;
16 |
17 | int16_t h = 240;
18 | int16_t w = 320;
19 |
20 | int dly = 5;
21 |
22 | int16_t paddle_h = 30;
23 | int16_t paddle_w = 4;
24 |
25 | int16_t lpaddle_x = 0;
26 | int16_t rpaddle_x = w - paddle_w;
27 |
28 | int16_t lpaddle_y = 0;
29 | int16_t rpaddle_y = h - paddle_h;
30 |
31 | int16_t lpaddle_d = 1;
32 | int16_t rpaddle_d = -1;
33 |
34 | int16_t lpaddle_ball_t = w - w / 4;
35 | int16_t rpaddle_ball_t = w / 4;
36 |
37 | int16_t target_y = 0;
38 |
39 | int16_t ball_x = 2;
40 | int16_t ball_y = 2;
41 | int16_t oldball_x = 2;
42 | int16_t oldball_y = 2;
43 |
44 | int16_t ball_dx = 1;
45 | int16_t ball_dy = 1;
46 |
47 | int16_t ball_w = 6;
48 | int16_t ball_h = 6;
49 |
50 | int16_t dashline_h = 4;
51 | int16_t dashline_w = 2;
52 | int16_t dashline_n = h / dashline_h;
53 | int16_t dashline_x = w / 2 - 1;
54 | int16_t dashline_y = dashline_h / 2;
55 |
56 | int16_t lscore = 12;
57 | int16_t rscore = 4;
58 |
59 | void setup(void) {
60 |
61 | //randomSeed(analogRead(0)*analogRead(1));
62 |
63 | Serial.begin(9600);
64 | uint32_t ID = tft.readID();
65 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
66 | tft.begin(ID);
67 |
68 | tft.setRotation(1);
69 |
70 | tft.fillScreen(BLACK);
71 | //tft.fillScreen(GREY);
72 |
73 | initgame();
74 |
75 | tft.setTextColor(WHITE, BLACK);
76 |
77 | }
78 |
79 | void loop() {
80 | delay(dly);
81 |
82 | lpaddle();
83 | rpaddle();
84 |
85 | midline();
86 |
87 | ball();
88 | }
89 |
90 | void initgame() {
91 | lpaddle_y = random(0, h - paddle_h);
92 | rpaddle_y = random(0, h - paddle_h);
93 |
94 | // ball is placed on the center of the left paddle
95 | ball_y = lpaddle_y + (paddle_h / 2);
96 |
97 | calc_target_y();
98 |
99 | midline();
100 |
101 | tft.fillRect(0,h-26,w,239,GRAY);
102 | //tft.setTextDatum(TC_DATUM);
103 | tft.setTextColor(WHITE,GRAY);
104 | _drawString("STM32 example", 05, h-26 , 4);
105 | //tft.drawString("TFT_eSPI example", w/2, h-26 , 4);
106 | }
107 |
108 | void midline() {
109 |
110 | // If the ball is not on the line then don't redraw the line
111 | if ((ball_x dashline_x+dashline_w)) return;
112 |
113 | // Quick way to draw a dashed line
114 | for(int16_t i = 0; i < w; i+=10) {
115 | tft.drawFastVLine(dashline_x,i,5,WHITE);
116 | }
117 | //tft.setWindow(dashline_x,0,dashline_x+dashline_w-1,h);
118 |
119 | for(int16_t i = 0; i < dashline_n; i+=2) {
120 | //tft.pushColor(WHITE, dashline_w*dashline_h); // push dash pixels
121 | //tft.pushColor(BLACK, dashline_w*dashline_h); // push gap pixels
122 | }
123 | }
124 |
125 | void lpaddle() {
126 |
127 | if (lpaddle_d == 1) {
128 | tft.fillRect(lpaddle_x, lpaddle_y, paddle_w, 1, BLACK);
129 | }
130 | else if (lpaddle_d == -1) {
131 | tft.fillRect(lpaddle_x, lpaddle_y + paddle_h - 1, paddle_w, 1, BLACK);
132 | }
133 |
134 | lpaddle_y = lpaddle_y + lpaddle_d;
135 |
136 | if (ball_dx == 1) lpaddle_d = 0;
137 | else {
138 | if (lpaddle_y + paddle_h / 2 == target_y) lpaddle_d = 0;
139 | else if (lpaddle_y + paddle_h / 2 > target_y) lpaddle_d = -1;
140 | else lpaddle_d = 1;
141 | }
142 |
143 | if (lpaddle_y + paddle_h >= h && lpaddle_d == 1) lpaddle_d = 0;
144 | else if (lpaddle_y <= 0 && lpaddle_d == -1) lpaddle_d = 0;
145 |
146 | tft.fillRect(lpaddle_x, lpaddle_y, paddle_w, paddle_h, CYAN);
147 | }
148 |
149 | void rpaddle() {
150 |
151 | if (rpaddle_d == 1) {
152 | tft.fillRect(rpaddle_x, rpaddle_y, paddle_w, 1, BLACK);
153 | }
154 | else if (rpaddle_d == -1) {
155 | tft.fillRect(rpaddle_x, rpaddle_y + paddle_h - 1, paddle_w, 1, BLACK);
156 | }
157 |
158 | rpaddle_y = rpaddle_y + rpaddle_d;
159 |
160 | if (ball_dx == -1) rpaddle_d = 0;
161 | else {
162 | if (rpaddle_y + paddle_h / 2 == target_y) rpaddle_d = 0;
163 | else if (rpaddle_y + paddle_h / 2 > target_y) rpaddle_d = -1;
164 | else rpaddle_d = 1;
165 | }
166 |
167 | if (rpaddle_y + paddle_h >= h && rpaddle_d == 1) rpaddle_d = 0;
168 | else if (rpaddle_y <= 0 && rpaddle_d == -1) rpaddle_d = 0;
169 |
170 | tft.fillRect(rpaddle_x, rpaddle_y, paddle_w, paddle_h, YELLOW);
171 | }
172 |
173 | void calc_target_y() {
174 | int16_t target_x;
175 | int16_t reflections;
176 | int16_t y;
177 |
178 | if (ball_dx == 1) {
179 | target_x = w - ball_w;
180 | }
181 | else {
182 | target_x = -1 * (w - ball_w);
183 | }
184 |
185 | y = abs(target_x * (ball_dy / ball_dx) + ball_y);
186 |
187 | reflections = floor(y / h);
188 |
189 | if (reflections % 2 == 0) {
190 | target_y = y % h;
191 | }
192 | else {
193 | target_y = h - (y % h);
194 | }
195 | }
196 |
197 | void ball() {
198 | ball_x = ball_x + ball_dx;
199 | ball_y = ball_y + ball_dy;
200 |
201 | if (ball_dx == -1 && ball_x == paddle_w && ball_y + ball_h >= lpaddle_y && ball_y <= lpaddle_y + paddle_h) {
202 | ball_dx = ball_dx * -1;
203 | dly = random(5); // change speed of ball after paddle contact
204 | calc_target_y();
205 | } else if (ball_dx == 1 && ball_x + ball_w == w - paddle_w && ball_y + ball_h >= rpaddle_y && ball_y <= rpaddle_y + paddle_h) {
206 | ball_dx = ball_dx * -1;
207 | dly = random(5); // change speed of ball after paddle contact
208 | calc_target_y();
209 | } else if ((ball_dx == 1 && ball_x >= w) || (ball_dx == -1 && ball_x + ball_w < 0)) {
210 | dly = 5;
211 | }
212 |
213 | if (ball_y > h - ball_w || ball_y < 0) {
214 | ball_dy = ball_dy * -1;
215 | ball_y += ball_dy; // Keep in bounds
216 | }
217 |
218 | //tft.fillRect(oldball_x, oldball_y, ball_w, ball_h, BLACK);
219 | tft.drawRect(oldball_x, oldball_y, ball_w, ball_h, BLACK); // Less TFT refresh aliasing than line above for large balls
220 | tft.fillRect( ball_x, ball_y, ball_w, ball_h, RED);
221 | oldball_x = ball_x;
222 | oldball_y = ball_y;
223 | }
224 |
225 | void _drawString(char *buf, int16_t x, int16_t y, int16_t size)
226 | {
227 | tft.setTextSize(size);
228 | tft.setCursor(x, y);
229 | tft.print(buf);
230 | }
231 |
--------------------------------------------------------------------------------
/examples/UTFT_demo_STM32/UTFT_demo_STM32.ino:
--------------------------------------------------------------------------------
1 | // Demo based on:
2 | // UTFT_Demo_320x240 by Henning Karlsen
3 | // web: http://www.henningkarlsen.com/electronics
4 | //
5 |
6 | #include
7 | #include "STM32_TFT_8bit.h"
8 |
9 | STM32_TFT_8bit myGLCD;
10 |
11 |
12 | #define TFT_GREY GRAY
13 | #define TFT_BLACK BLACK
14 | #define TFT_RED RED
15 | #define TFT_CYAN CYAN
16 | #define TFT_YELLOW YELLOW
17 | #define TFT_BLUE BLUE
18 |
19 | int sbuf[318];
20 | int cbuf[318];
21 |
22 | void setup()
23 | {
24 | Serial.begin(9600);
25 | uint32_t ID = myGLCD.readID();
26 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
27 | myGLCD.begin(ID);
28 |
29 | uint32_t width = myGLCD.width();
30 | Serial.print("Width: "); Serial.println(width);
31 | uint32_t height = myGLCD.height();
32 | Serial.print("Height: "); Serial.println(height);
33 |
34 | int buf[318];
35 |
36 | // Clear the screen and draw the frame
37 | myGLCD.setRotation(3);
38 | myGLCD.setFont();
39 | myGLCD.setTextSize(1);
40 |
41 | myGLCD.fillScreen(TFT_BLACK);
42 | myGLCD.fillRect(0, 0, 319, 14,TFT_RED);
43 | myGLCD.fillRect(0, 226, 319, 14,TFT_GREY);
44 |
45 | myGLCD.setTextColor(TFT_BLACK,TFT_RED);
46 | myGLCD.setCursor(100, 4);
47 | myGLCD.print("* STM32_TFT_8bit *");
48 | myGLCD.setTextColor(TFT_YELLOW,TFT_GREY);
49 | myGLCD.setCursor(100, 230);
50 | myGLCD.print("Adapted by nopnop2002");
51 |
52 | myGLCD.drawRect(0, 14, 319, 211, TFT_BLUE);
53 |
54 | // Draw crosshairs
55 | myGLCD.drawLine(159, 15, 159, 224,TFT_BLUE);
56 | myGLCD.drawLine(1, 119, 318, 119,TFT_BLUE);
57 | for (int i=9; i<310; i+=10)
58 | myGLCD.drawLine(i, 117, i, 121,TFT_BLUE);
59 | for (int i=19; i<220; i+=10)
60 | myGLCD.drawLine(157, i, 161, i,TFT_BLUE);
61 |
62 | // Draw sin-lines, cos-lines
63 | myGLCD.setTextColor(TFT_CYAN);
64 | _drawString("Sin", 5, 15,2);
65 | for (int i=1; i<318; i=i+2)
66 | {
67 | sbuf[i-1] = 119+(sin(((i*1.13)*3.14)/180)*95);
68 | myGLCD.drawPixel(i,sbuf[i-1],TFT_CYAN);
69 | }
70 | myGLCD.setTextColor(TFT_RED);
71 | _drawString("Cos", 5, 30,2);
72 | for (int i=1; i<318; i=i+2)
73 | {
74 | cbuf[i-1] = 119+(cos(((i*1.13)*3.14)/180)*95);
75 | myGLCD.drawPixel(i,cbuf[i-1],TFT_YELLOW);
76 | }
77 |
78 | }
79 |
80 | void loop()
81 | {
82 | static int delta = 0;
83 |
84 | // Erase sin-lines, cos-lines
85 | for (int i=1; i<318; i=i+2)
86 | {
87 | myGLCD.drawPixel(i,sbuf[i-1],TFT_BLACK);
88 | }
89 | for (int i=1; i<318; i=i+2)
90 | {
91 | myGLCD.drawPixel(i,cbuf[i-1],TFT_BLACK);
92 | }
93 |
94 | // Draw sin-lines, cos-lines
95 | delta++;
96 | if (delta == 318) delta = 0;
97 | for (int i=1; i<318; i=i+2)
98 | {
99 | sbuf[i-1] = 119+(sin((((i+delta)*1.13)*3.14)/180)*95);
100 | myGLCD.drawPixel(i,sbuf[i-1],TFT_CYAN);
101 | }
102 | for (int i=1; i<318; i=i+2)
103 | {
104 | cbuf[i-1] = 119+(cos((((i+delta)*1.13)*3.14)/180)*95);
105 | myGLCD.drawPixel(i,cbuf[i-1],TFT_YELLOW);
106 | }
107 |
108 | myGLCD.setTextColor(TFT_CYAN);
109 | // myGLCD.drawString("Sin", 5, 15,2);
110 | _drawString("Sin", 5, 15,2);
111 | myGLCD.setTextColor(TFT_YELLOW);
112 | // myGLCD.drawString("Cos", 5, 30,2);
113 | _drawString("Cos", 5, 30,2);
114 | myGLCD.drawLine(159, 15, 159, 224,TFT_BLUE);
115 | myGLCD.drawLine(1, 119, 318, 119,TFT_BLUE);
116 | }
117 |
118 | void _drawString(char *buf, int16_t x, int16_t y, int16_t size)
119 | {
120 | myGLCD.setTextSize(size);
121 | myGLCD.setCursor(x, y);
122 | myGLCD.print(buf);
123 | }
124 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=STM32_TFT_8bit
2 | version=1.3.0
3 | author=David Prentice :: Ported to Arduino_STM32 by nopnop2002
4 | maintainer=David Prentice and nopnop2002 (for porting to Arduino_STM32)
5 | sentence=TFT Library for 2.4, 2.8, 3.5, 3.6, 3.95 inch mcufriend UNO Shields
6 | paragraph=TFT Library for 2.4, 2.8, 3.5, 3.6, 3.95 inch mcufriend UNO Shields. Must have /RD pin to be readable.
7 | category=Display
8 | url=https://github.com/nopnop2002/STM32_TFT_8bit
9 | architectures=stm32
10 |
--------------------------------------------------------------------------------