├── Arduino-STM32-8bitTFT.cpp
├── Arduino-STM32-8bitTFT.h
├── JPEGS
├── F103RBT6.jpg
├── JpegView.jpg
├── SMT32_PillBoard.jpg
├── healsky3.jpg
├── sunrise.jpg
└── tree.jpg
├── LICENSE
├── README.md
├── 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
│ └── README.md
├── JpegView_320x480_SMT32
│ ├── JPEG_Functions.ino
│ ├── JpegView_320x480_SMT32.ino
│ └── README.md
├── ScrollTest_STM32
│ ├── ScrollTest_STM32.ino
│ └── icons.c
├── 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
/Arduino-STM32-8bitTFT.h:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for Arduino_Core_STM32
3 | *
4 | * based on MCUFRIEND_kbv.cpp by David Prentice
5 | * https://github.com/prenticedavid/MCUFRIEND_kbv
6 |
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | */
20 |
21 |
22 | #ifndef _Arduino-STM32-8bitTFTH_
23 | #define _Arduino-STM32-8bitTFTH_
24 |
25 | #include "Arduino.h"
26 | #include "Print.h"
27 | #include
28 |
29 |
30 | /*
31 | To use a different resolution TFT, change this or use setResolution().
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 GPIO_INTERFACE 0 // Use LL_GPIO_WriteOutputPort fuction
60 | #define GPIO_INTERFACE 1 // Use Port output data (ODR) Register
61 |
62 | /*
63 | Define pins and Output Data Registers
64 | */
65 |
66 | #define PORT_LOW 0
67 | #define PORT_HIGH 1
68 |
69 | #if 1
70 | #define TFT_DATA GPIOA
71 | #define TFT_PORT PORT_LOW
72 | #define TFT_D0 LL_GPIO_PIN_0
73 | #define TFT_D1 LL_GPIO_PIN_1
74 | #define TFT_D2 LL_GPIO_PIN_2
75 | #define TFT_D3 LL_GPIO_PIN_3
76 | #define TFT_D4 LL_GPIO_PIN_4
77 | #define TFT_D5 LL_GPIO_PIN_5
78 | #define TFT_D6 LL_GPIO_PIN_6
79 | #define TFT_D7 LL_GPIO_PIN_7
80 | //Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
81 | //Pin stm32 |PA7|PA6|PA5|PA4|PA3|PA2|PA1|PA0|
82 | #endif
83 |
84 | #if 0
85 | #define TFT_DATA GPIOA
86 | #define TFT_PORT PORT_HIGH
87 | #define TFT_D0 LL_GPIO_PIN_8
88 | #define TFT_D1 LL_GPIO_PIN_9
89 | #define TFT_D2 LL_GPIO_PIN_10
90 | #define TFT_D3 LL_GPIO_PIN_11
91 | #define TFT_D4 LL_GPIO_PIN_12
92 | #define TFT_D5 LL_GPIO_PIN_13
93 | #define TFT_D6 LL_GPIO_PIN_14
94 | #define TFT_D7 LL_GPIO_PIN_15
95 | //Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
96 | //Pin stm32 |PA15|PA14|PA13|PA12|PA11|PA10|PA9|PA8|
97 | #endif
98 |
99 |
100 | #if 0
101 | #define TFT_DATA GPIOB
102 | #define TFT_PORT PORT_LOW
103 | #define TFT_D0 LL_GPIO_PIN_0
104 | #define TFT_D1 LL_GPIO_PIN_1
105 | #define TFT_D2 LL_GPIO_PIN_2
106 | #define TFT_D3 LL_GPIO_PIN_3
107 | #define TFT_D4 LL_GPIO_PIN_4
108 | #define TFT_D5 LL_GPIO_PIN_5
109 | #define TFT_D6 LL_GPIO_PIN_6
110 | #define TFT_D7 LL_GPIO_PIN_7
111 | //Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
112 | //Pin stm32 |PB7|PB6|PB5|PB4|PB3|PB2|PB1|PB0|
113 | #endif
114 |
115 | #if 0
116 | #define TFT_DATA GPIOB
117 | #define TFT_PORT PORT_HIGH
118 | #define TFT_D0 LL_GPIO_PIN_8
119 | #define TFT_D1 LL_GPIO_PIN_9
120 | #define TFT_D2 LL_GPIO_PIN_10
121 | #define TFT_D3 LL_GPIO_PIN_11
122 | #define TFT_D4 LL_GPIO_PIN_12
123 | #define TFT_D5 LL_GPIO_PIN_13
124 | #define TFT_D6 LL_GPIO_PIN_14
125 | #define TFT_D7 LL_GPIO_PIN_15
126 | //Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
127 | //Pin stm32 |PB15|PB14|PB13|PB12|PB11|PB10|PB9|PB8|
128 | #endif
129 |
130 | #if 0
131 | #define TFT_DATA GPIOC
132 | #define TFT_PORT PORT_LOW
133 | #define TFT_D0 LL_GPIO_PIN_0
134 | #define TFT_D1 LL_GPIO_PIN_1
135 | #define TFT_D2 LL_GPIO_PIN_2
136 | #define TFT_D3 LL_GPIO_PIN_3
137 | #define TFT_D4 LL_GPIO_PIN_4
138 | #define TFT_D5 LL_GPIO_PIN_5
139 | #define TFT_D6 LL_GPIO_PIN_6
140 | #define TFT_D7 LL_GPIO_PIN_7
141 | //Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
142 | //Pin stm32 |PC7|PC6|PC5|PC4|PC3|PC2|PC1|PC0|
143 | #endif
144 |
145 | #if 0
146 | #define TFT_DATA GPIOC
147 | #define TFT_PORT PORT_HIGH
148 | #define TFT_D0 LL_GPIO_PIN_8
149 | #define TFT_D1 LL_GPIO_PIN_9
150 | #define TFT_D2 LL_GPIO_PIN_10
151 | #define TFT_D3 LL_GPIO_PIN_11
152 | #define TFT_D4 LL_GPIO_PIN_12
153 | #define TFT_D5 LL_GPIO_PIN_13
154 | #define TFT_D6 LL_GPIO_PIN_14
155 | #define TFT_D7 LL_GPIO_PIN_15
156 | //Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
157 | //Pin stm32 |PC15|PC14|PC13|PC12|PC11|PC10|PC9|PC8|
158 | #endif
159 |
160 | #if 0
161 | #define TFT_DATA GPIOD
162 | #define TFT_PORT PORT_LOW
163 | #define TFT_D0 LL_GPIO_PIN_0
164 | #define TFT_D1 LL_GPIO_PIN_1
165 | #define TFT_D2 LL_GPIO_PIN_2
166 | #define TFT_D3 LL_GPIO_PIN_3
167 | #define TFT_D4 LL_GPIO_PIN_4
168 | #define TFT_D5 LL_GPIO_PIN_5
169 | #define TFT_D6 LL_GPIO_PIN_6
170 | #define TFT_D7 LL_GPIO_PIN_7
171 | //Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
172 | //Pin stm32 |PD7|PD6|PD5|PD4|PD3|PD2|PD1|PD0|
173 | #endif
174 |
175 | #if 0
176 | #define TFT_DATA GPIOD
177 | #define TFT_PORT PORT_HIGH
178 | #define TFT_D0 LL_GPIO_PIN_8
179 | #define TFT_D1 LL_GPIO_PIN_9
180 | #define TFT_D2 LL_GPIO_PIN_10
181 | #define TFT_D3 LL_GPIO_PIN_11
182 | #define TFT_D4 LL_GPIO_PIN_12
183 | #define TFT_D5 LL_GPIO_PIN_13
184 | #define TFT_D6 LL_GPIO_PIN_14
185 | #define TFT_D7 LL_GPIO_PIN_15
186 | //Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
187 | //Pin stm32 |PD15|PD14|PD13|PD12|PD11|PD10|PD9|PD8|
188 | #endif
189 |
190 |
191 | #define TFT_CNTRL GPIOB
192 | #define LL_LOW(LL_GPIO_PIN) LL_GPIO_WriteOutputPort(TFT_CNTRL, (LL_GPIO_ReadOutputPort(TFT_CNTRL) & ~(LL_GPIO_PIN)))
193 | #define LL_HIGH(LL_GPIO_PIN) LL_GPIO_WriteOutputPort(TFT_CNTRL, (LL_GPIO_ReadOutputPort(TFT_CNTRL) | LL_GPIO_PIN))
194 |
195 |
196 | // Note:
197 | // PA15 PB3 PB4 is assigned to JTAG debug port by default on some boards.
198 | // Therefore, it may not be available by default.
199 | #define TFT_RD LL_GPIO_PIN_0 // PB0
200 | #define TFT_WR LL_GPIO_PIN_1 // PB1
201 | #define TFT_RS LL_GPIO_PIN_5 // PB5
202 | #define TFT_CS LL_GPIO_PIN_6 // PB6
203 | #define TFT_RST LL_GPIO_PIN_7 // PB7
204 |
205 | //#define DELAY delayMicroseconds(10);
206 | #define DELAY (void)0 // NOP
207 |
208 | #define RD_ACTIVE LL_LOW(TFT_RD)
209 | #define RD_IDLE LL_HIGH(TFT_RD)
210 | #define WR_ACTIVE LL_LOW(TFT_WR)
211 | #define WR_IDLE LL_HIGH(TFT_WR)
212 | #define CD_COMMAND LL_LOW(TFT_RS)
213 | #define CD_DATA LL_HIGH(TFT_RS)
214 | #define CS_ACTIVE LL_LOW(TFT_CS)
215 | #define CS_IDLE LL_HIGH(TFT_CS)
216 | #define RST_ACTIVE LL_LOW(TFT_RST)
217 | #define RST_IDLE LL_HIGH(TFT_RST)
218 |
219 | #define RD_STROBE {RD_ACTIVE; RD_IDLE;} // Not use
220 | #define WR_STROBE {WR_ACTIVE; WR_IDLE;} // Not use
221 |
222 |
223 |
224 | class STM32_TFT_8bit : public Adafruit_GFX {
225 |
226 | public:
227 |
228 | STM32_TFT_8bit(void);
229 | void enablePortClock(GPIO_TypeDef *gpio);
230 | void setResolution(int16_t width, int16_t height);
231 | void setOffset(int16_t offset);
232 | void begin(uint16_t ID);
233 | void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
234 | void fillScreen(uint16_t color);
235 | void drawLine(int16_t x0, int16_t y0,int16_t x1, int16_t y1, uint16_t color);
236 | void drawPixel(int16_t x, int16_t y, uint16_t color);
237 | void pushColors8(uint8_t * block, int16_t n, bool first);
238 | void pushColors(uint16_t * block, int16_t n, bool first);
239 | void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
240 | void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
241 | void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
242 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
243 | int16_t readGRAM(int16_t x, int16_t y, uint16_t * block, int16_t w, int16_t h);
244 | uint16_t readPixel(int16_t x, int16_t y) { uint16_t color; readGRAM(x, y, &color, 1, 1); return color; }
245 | void setRotation(uint8_t r);
246 | void vertScroll(int16_t top, int16_t scrollines, int16_t offset);
247 | void invertDisplay(boolean i);
248 | uint16_t readID(void);
249 |
250 |
251 | private:
252 | void setWriteDataBus(void);
253 | void setReadDataBus(void);
254 | void write8(uint8_t);
255 | void writeCmdByte(uint8_t c);
256 | void WriteCmd(uint16_t c);
257 | void writeDataByte(uint8_t d);
258 | void writeDataWord(uint16_t d);
259 | void WriteCmdData(uint16_t cmd, uint16_t dat);
260 | void WriteCmdParamN(uint8_t cmd, int8_t N, uint8_t * block);
261 | void WriteCmdParam4(uint8_t cmd, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4);
262 | void init_table(const void *table, int16_t size);
263 | void init_table16(const void *table, int16_t size);
264 | void writeCmdWord(uint16_t c);
265 | uint8_t read8(void);
266 | uint8_t read8bits(void);
267 | uint16_t read16bits(void);
268 | uint16_t readReg16(uint16_t reg);
269 | uint16_t readReg16Index(uint16_t reg, int8_t index);
270 | uint32_t readReg32(uint16_t reg);
271 | uint32_t readReg40(uint16_t reg);
272 | uint16_t _lcd_ID, _lcd_capable, _lcd_rev, _lcd_madctl, _lcd_drivOut, _MC, _MP, _MW, _SC, _EC, _SP, _EP;
273 | int16_t _lcd_width = 0, _lcd_height = 0, _lcd_offset=0;
274 | uint32_t _pins[8];
275 | };
276 |
277 | #endif //endif of the header file
278 |
--------------------------------------------------------------------------------
/JPEGS/F103RBT6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/Arduino-STM32-8bitTFT/2d050f4007d00147ba219f597c5afbd257b71209/JPEGS/F103RBT6.jpg
--------------------------------------------------------------------------------
/JPEGS/JpegView.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/Arduino-STM32-8bitTFT/2d050f4007d00147ba219f597c5afbd257b71209/JPEGS/JpegView.jpg
--------------------------------------------------------------------------------
/JPEGS/SMT32_PillBoard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/Arduino-STM32-8bitTFT/2d050f4007d00147ba219f597c5afbd257b71209/JPEGS/SMT32_PillBoard.jpg
--------------------------------------------------------------------------------
/JPEGS/healsky3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/Arduino-STM32-8bitTFT/2d050f4007d00147ba219f597c5afbd257b71209/JPEGS/healsky3.jpg
--------------------------------------------------------------------------------
/JPEGS/sunrise.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/Arduino-STM32-8bitTFT/2d050f4007d00147ba219f597c5afbd257b71209/JPEGS/sunrise.jpg
--------------------------------------------------------------------------------
/JPEGS/tree.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nopnop2002/Arduino-STM32-8bitTFT/2d050f4007d00147ba219f597c5afbd257b71209/JPEGS/tree.jpg
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Arduino-STM32-8bitTFT
2 | 8bit TFT Library for Arduino_Core_STM32(ST 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/stm32duino/Arduino_Core_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 | |TFT||STM32|
22 | |:-:|:-:|:-:|
23 | |LCD_RD|--|PB0(*1)|
24 | |LCD_WR|--|PB1(*1)|
25 | |LCD_RS|--|PB5(*1)|
26 | |LCD_CS|--|PB6(*1)|
27 | |LCD_RST|--|PB7(*1)|
28 | |LCD_D0|--|PA0(*2)|
29 | |LCD_D1|--|PA1(*2)|
30 | |LCD_D2|--|PA2(*2)|
31 | |LCD_D3|--|PA3(*2)|
32 | |LCD_D4|--|PA4(*2)|
33 | |LCD_D5|--|PA5(*2)|
34 | |LCD_D6|--|PA6(*2)|
35 | |LCD_D7|--|PA7(*2)|
36 | |5V|--|5V(*3)|
37 | |3.3V|--|3.3V(*3)|
38 | |GND|--|GND|
39 |
40 | (\*1)
41 | You can change to other PB pin. To change the pin, change Arduino-STM32-8bitTFT.h.
42 | Some boards assign PB3 and PB4 to the JTAG debug port by default.
43 | Therefore, depending on the board, PB3 and PB4 may not be available as GPIO.
44 | These GPIO are controlled using LL_GPIO_WriteOutputPort().
45 |
46 | ```
47 | #define TFT_RD LL_GPIO_PIN_0 // PB0
48 | #define TFT_WR LL_GPIO_PIN_1 // PB1
49 | #define TFT_RS LL_GPIO_PIN_5 // PB5
50 | #define TFT_CS LL_GPIO_PIN_6 // PB6
51 | #define TFT_RST LL_GPIO_PIN_7 // PB7
52 | ```
53 |
54 |
55 | (\*2)
56 | __Serial.print of NUCLEO and DISC1 gose to PA2.__
57 | __Serial.print of STM32G series gose to PA2.__
58 | __Serial.print of STM32H series gose to PA0.__
59 | __If you are using these, you will need to do one of the following:__
60 |
61 | #### Change GPIO from D0 to D7
62 | To change the port, change Arduino-STM32-8bitTFT.h.
63 | D0 to D7 are controlled using CMSIS ODR Register.
64 | This register can change multiple IOs at once, but only IOs on the same port.
65 | Therefore, D0 to D7 must be the same port.
66 | If PORT-A is used for D0-D7, __all GPIOs on PORT-A cannot be used for other purposes.__
67 | Because CMSIS ODR Register manipulates all GPIOs of PORT-A.
68 |
69 | You can use any of the following:
70 | - PORT-A LOW
71 | TFT Pin|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
72 | STM32 Pin|PA7|PA6|PA5|PA4|PA3|PA2|PA1|PA0|
73 | - PORT-A HIGH
74 | TFT Pin|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
75 | STM32 Pin|PA15|PA14|PA13|PA12|PA11|PA10|PA9|PA8|
76 | - PORT-C LOW
77 | TFT Pin|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
78 | STM32 Pin|PC7|PC6|PC5|PC4|PC3|PC2|PC1|PC0|
79 | - PORT-C HIGH
80 | TFT Pin|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
81 | STM32 Pin|PC15|PC14|PC13|PC12|PC11|PC10|PC9|PC8|
82 | - PORT-D LOW
83 | TFT Pin|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
84 | STM32 Pin|PD7|PD6|PD5|PD4|PD3|PD2|PD1|PD0|
85 | - PORT-D HIGH
86 | TFT Pin|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
87 | STM32 Pin|PD15|PD14|PD13|PD12|PD11|PD10|PD9|PD8|
88 |
89 | #### Change default Serial instance pins
90 | You can use another GPIO as a Serial object.
91 | GPIO that can be used as a Serial object differs depending on the MCU.
92 | You can know which GPIOs can be used in PeripheralPins.c of the MCU.
93 | PeripheralPins.c is [here](https://github.com/stm32duino/Arduino_Core_STM32/tree/main/variants).
94 | ```
95 | Serial.setTx(PB3);
96 | Serial.setRx(PB4);
97 | Serial.begin(115200);
98 | ```
99 |
100 | (\*3)
101 | When a regulator(It's often AMS1117) is mounted on the back, it's operated 5V.
102 | When a regulator is NOT mounted on the back, it's operated 3.3V.
103 |
104 |
105 | __Note:Keep the wire length as short as possible.__
106 |
107 | ----
108 |
109 | # Tested TFT
110 | - ILI9325 2.4inch 240x320 TFT-Shield
111 | - ILI9341 2.4inch 240x320 TFT-Shield
112 | - ILI9342 2.4inch 240x320 TFT-Shield
113 | - SPFD5408 2.4inch 240x320 TFT-Shield
114 | - R61505 2.4inch 240x320 TFT-Shield
115 | - ST7783 2.4inch 240x320 TFT-Shield
116 | - LGDP4532 2.4inch 240x320 TFT-Shield
117 | - R61509V 3.6inch 240x400 TFT-Shield
118 | - ST7793 3.6inch 240x400 TFT-Shield
119 | - ILI9481 3.5inch 320x480 TFT-Shield
120 | - ILI9486 3.5inch 320x480 TFT-Shield
121 | - RM68140 3.95inch 320x480 TFT-Shield
122 | - ST7796 3.95inch 320x480 TFT-Shield
123 |
124 | I found that these display cannot follow high-speed GPIO-ON and GPIO-OFF.
125 | - OPEN-SMART ILI9225 TFT-Shield
126 | - OPEN-SMART ILI9327 TFT-Shield
127 | - OPEN-SMART ILI9340 TFT-Shield
128 | - OPEN-SMART S6D1121 16Pin-Parallel
129 | - OPEN-SMART ST7775 16Pin-Parallel
130 | - OPEN-SMART ST7783 16Pin-Parallel
131 | - OPEN-SMART R61509V 16Pin-Parallel
132 | - OPEN-SMART ILI9488 16Pin-Parallel
133 |
134 | 
135 |
136 |
137 | ----
138 |
139 | # Boards available
140 | This library uses LL GPIO Generic Driver and CMSIS ODR Register.
141 | Probably all boards have these available.
142 | I tested with these.
143 | - STM32F0/F1/F3/F4 series
144 | - STM32G4 series
145 | - STM32H5 series
146 | - STM32L4 series
147 |
148 | ----
149 |
150 | # Setting your TFT's resolution
151 |
152 | The default resolution of this library is 240x320.
153 | If your TFT's resolution is 320x480,
154 | you have to set your TFT's resolution using tft.setResoution.
155 |
156 | ```
157 | ID = tft.readID();
158 | tft.setResolution(320, 480); // Set your resolution
159 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
160 | tft.begin(ID);
161 | uint32_t width = tft.width();
162 | Serial.print("Width: "); Serial.println(width); // You will see 320
163 | uint32_t height = tft.height();
164 | Serial.print("Height: "); Serial.println(height); // You will see 480
165 | ```
166 |
167 | If your TFT's resolution is 240x400,
168 | you have to set your TFT's resolution and TFT's offset.
169 |
170 | ```
171 | ID = tft.readID();
172 | tft.setResolution(240, 400); // Set your resolution
173 | tft.setOffset(32); // Set your offset
174 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
175 | tft.begin(ID);
176 | uint32_t width = tft.width();
177 | Serial.print("Width: "); Serial.println(width); // You will see 240
178 | uint32_t height = tft.height();
179 | Serial.print("Height: "); Serial.println(height); // You will see 400
180 | ```
181 |
182 | ---
183 |
184 | - STM32F103 + R61505 2.4 inch TFT
185 |
186 | 
187 |
188 | - STM32F103 + SPFD5408 2.4 inch TFT
189 |
190 | 
191 |
192 | - STM32F103 + ILI9325 2.4 inch TFT
193 |
194 | 
195 |
196 | - STM32F103 + ILI9341 2.4 inch TFT
197 |
198 | 
199 |
200 | - STM32F103 + ILI9342 2.4 inch TFT
201 |
202 | 
203 |
204 | - STM32F401 + ILI9341 2.4 inch TFT
205 |
206 | 
207 |
208 | - STM32F407 + ILI9341 2.4 inch TFT
209 |
210 | 
211 |
212 | - NUCLEO F446RE + ILI9341 2.4 inch TFT (Use PC0-PC7 for D0-D7)
213 |
214 | 
215 |
216 | - STM32G431 + ILI9341 2.4 inch TFT (Use Serial remapping)
217 |
218 | 
219 |
220 | - STM32H750 + ILI9341 2.4 inch TFT (Use PC0-PC7 for D0-D7)
221 |
222 | 
223 |
224 | ----
225 |
226 | # Benchmark using ILI9341(240x320)
227 | |Benchmark|F072|F103|F303|F401|F411|F407|F446|G431|H750|L452|ATmega328|
228 | |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
229 | |Screen fill |713964 |737158 |358057 |247223 |216304 |141878 |132427 |140239 |222478 |259637 |1379560|
230 | |Text |73319 |58985 |37647 |25814 |22605 |15097 |14272 |16275 |14691 |28825 |344024 |
231 | |Lines |675985 |556282 |336332 |235522 |206064 |137693 |130958 |134605 |147000 |250545 |3390180|
232 | |Horiz/Vert Lines |60070 |61299 |30165 |20825 |18221 |11958 |11173 |11847 |18372 |21950 |144664 |
233 | |Rectangles (outline) |39824 |39994 |20040 |13835 |12106 |7953 |7437 |8178 |11863 |14875 |104260 |
234 | |Rectangles (filled) |1482576|1530389|743518 |513383 |449170 |294609 |274991 |291313 |461782 |539271 |3267476|
235 | |Circles (filled) |237519 |215466 |120380 |83212 |72840 |48080 |45358 |58606 |59632 |97797 |1211484|
236 | |Circles (outline) |297537 |245302 |148705 |103680 |90733 |60769 |57622 |59807 |64510 |110695 |1475108|
237 | |Triangles (outline) |149009 |123427 |74211 |51938 |45477 |30354 |28766 |29767 |32825 |55313 |1075596|
238 | |Triangles (filled) |542331 |528554 |268777 |185711 |162496 |106788 |99944 |112922 |155465 |202875 |1721636|
239 | |Rounded rects (outline)|117285 |101407 |58746 |40758 |35682 |23791 |22529 |23750 |27519 |43702 |506428 |
240 | |Rounded rects (filled) |1495318|1534484|750346 |518107 |453320 |297450 |277742 |298242 |132427 |548296 |3795228|
241 |
242 |
243 |
244 |
--------------------------------------------------------------------------------
/examples/ClockAnalog_STM32/ClockAnalog_STM32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for Arduino_Core_STM32
3 | *
4 | * An example analogue clock using a TFT LCD screen to show the time
5 | * use of some of the drawing commands with the Adafruit_GFX library.
6 | * For a more accurate clock, it would be better to use the RTC library.
7 | * But this is just a demo.
8 | *
9 | * Gilchrist 6/2/2014 1.0
10 | * Updated by Alan Senior 18/1/2015
11 | * Updated by nopnop2002 5/1/2018
12 | *
13 | */
14 |
15 |
16 | #include
17 | #include "Arduino-STM32-8bitTFT.h"
18 |
19 | STM32_TFT_8bit tft;
20 |
21 | float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0; // Saved H, M, S x & y multipliers
22 | float sdeg=0, mdeg=0, hdeg=0;
23 | uint16_t osx=120, osy=120, omx=120, omy=120, ohx=120, ohy=120; // Saved H, M, S x & y coords
24 | uint16_t x00=0, x11=0, y00=0, y11=0;
25 | uint32_t targetTime = 0; // for next 1 second timeout
26 | uint8_t hh,mm,ss;
27 | boolean initial = 1;
28 |
29 | void setup(void) {
30 | delay(1000);
31 | Serial.begin(115200);
32 | Serial.print("__TIME__=");
33 | Serial.println(__TIME__);
34 | hh=conv2d(__TIME__);
35 | mm=conv2d(__TIME__+3);
36 | ss=conv2d(__TIME__+6); // Get H, M, S from compile time
37 | uint16_t ID = tft.readID();
38 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
39 | tft.begin(ID);
40 | uint16_t wid = tft.width();
41 | uint16_t ht = tft.height();
42 | Serial.println("width=" + String(wid) + " height=" + String(ht));
43 |
44 | if (wid < ht) {
45 | tft.setRotation(0);
46 | } else {
47 | tft.setRotation(1);
48 | }
49 | tft.fillScreen(GRAY);
50 | tft.setTextColor(WHITE, GRAY); // Adding a background colour erases previous text automatically
51 |
52 | // Draw clock face
53 | tft.fillCircle(120, 120, 118, GREEN);
54 | tft.fillCircle(120, 120, 110, BLACK);
55 |
56 | // Draw 12 lines
57 | for(int i = 0; i<360; i+= 30) {
58 | sx = cos((i-90)*0.0174532925);
59 | sy = sin((i-90)*0.0174532925);
60 | x00 = sx*114+120;
61 | y00 = sy*114+120;
62 | x11 = sx*100+120;
63 | y11 = sy*100+120;
64 |
65 | tft.drawLine(x00, y00, x11, y11, GREEN);
66 | }
67 |
68 | // Draw 60 dots
69 | for(int i = 0; i<360; i+= 6) {
70 | sx = cos((i-90)*0.0174532925);
71 | sy = sin((i-90)*0.0174532925);
72 | x00 = sx*102+120;
73 | y00 = sy*102+120;
74 | // Draw minute markers
75 | tft.drawPixel(x00, y00, WHITE);
76 |
77 | // Draw main quadrant dots
78 | if(i==0 || i==180) tft.fillCircle(x00, y00, 2, WHITE);
79 | if(i==90 || i==270) tft.fillCircle(x00, y00, 2, WHITE);
80 | }
81 |
82 | tft.fillCircle(120, 121, 3, WHITE);
83 | tft.setCursor(20, 260);
84 | tft.setTextSize(3);
85 | tft.println(__DATE__);
86 | targetTime = millis() + 1000;
87 | }
88 |
89 | void loop() {
90 |
91 | if (targetTime < millis()) {
92 | targetTime = millis()+1000;
93 | ss++; // Advance second
94 | if (ss==60) {
95 | ss=0;
96 | mm++; // Advance minute
97 | if(mm>59) {
98 | mm=0;
99 | hh++; // Advance hour
100 | if (hh>23) {
101 | hh=0;
102 | }
103 | }
104 | }
105 | #ifdef _DEBUG_
106 | Serial.print("hh=");
107 | Serial.print(hh);
108 | Serial.print(" mm=");
109 | Serial.print(mm);
110 | Serial.print(" ss=");
111 | Serial.println(ss);
112 | #endif
113 |
114 | // Pre-compute hand degrees, x & y coords for a fast screen update
115 | sdeg = ss*6; // 0-59 -> 0-354
116 | mdeg = mm*6+sdeg*0.01666667; // 0-59 -> 0-360 - includes seconds
117 | hdeg = hh*30+mdeg*0.0833333; // 0-11 -> 0-360 - includes minutes and seconds
118 | hx = cos((hdeg-90)*0.0174532925);
119 | hy = sin((hdeg-90)*0.0174532925);
120 | mx = cos((mdeg-90)*0.0174532925);
121 | my = sin((mdeg-90)*0.0174532925);
122 | sx = cos((sdeg-90)*0.0174532925);
123 | sy = sin((sdeg-90)*0.0174532925);
124 |
125 | if (ss==0 || initial) {
126 | initial = 0;
127 | // Erase hour and minute hand positions every minute
128 | tft.drawLine(ohx, ohy, 120, 121, BLACK);
129 | ohx = hx*62+121;
130 | ohy = hy*62+121;
131 | tft.drawLine(omx, omy, 120, 121, BLACK);
132 | omx = mx*84+120;
133 | omy = my*84+121;
134 | }
135 |
136 | // Redraw new hand positions, hour and minute hands not erased here to avoid flicker
137 | tft.drawLine(osx, osy, 120, 121, BLACK);
138 | osx = sx*90+121;
139 | osy = sy*90+121;
140 | tft.drawLine(osx, osy, 120, 121, RED);
141 | tft.drawLine(ohx, ohy, 120, 121, WHITE);
142 | tft.drawLine(omx, omy, 120, 121, WHITE);
143 | tft.drawLine(osx, osy, 120, 121, RED);
144 |
145 | tft.fillCircle(120, 121, 3, RED);
146 | }
147 | }
148 |
149 | static uint8_t conv2d(const char* p) {
150 | uint8_t v = 0;
151 | if ('0' <= *p && *p <= '9')
152 | v = *p - '0';
153 | return 10 * v + *++p - '0';
154 | }
155 |
156 |
--------------------------------------------------------------------------------
/examples/CubeDemo_STM32/CubeDemo_STM32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * Cube demo for Arduino_Core_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 "Arduino-STM32-8bitTFT.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(115200);
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 Arduino_Core_STM32
3 | *
4 | * based on MCUFRIEND_kbv.cpp by David Prentice
5 | * https://github.com/prenticedavid/MCUFRIEND_kbv
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | */
20 |
21 |
22 | #include
23 | #include "Arduino-STM32-8bitTFT.h"
24 |
25 | STM32_TFT_8bit tft;
26 |
27 | uint32_t ID;
28 |
29 | void setup() {
30 | delay(1000);
31 | Serial.begin(115200);
32 | Serial.println("Arduino-STM32-8bitTFT");
33 |
34 | ID = tft.readID();
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/GraphicsTest_240x400_SMT32/GraphicsTest_240x400_SMT32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for Arduino_Core_STM32
3 | *
4 | * based on MCUFRIEND_kbv.cpp by David Prentice
5 | * https://github.com/prenticedavid/MCUFRIEND_kbv
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | */
20 |
21 |
22 | #include
23 | #include "Arduino-STM32-8bitTFT.h"
24 |
25 | STM32_TFT_8bit tft;
26 |
27 | uint32_t ID;
28 |
29 | void setup() {
30 | delay(1000);
31 | Serial.begin(115200);
32 | Serial.println("Arduino-STM32-8bitTFT");
33 |
34 | ID = tft.readID();
35 | // Set your TFT's resolution
36 | tft.setResolution(240, 400); // Set your resolution
37 | // Set your TFT's offset
38 | tft.setOffset(32); // Set your offset
39 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
40 | tft.begin(ID);
41 |
42 | uint32_t width = tft.width();
43 | Serial.print("Width: "); Serial.println(width);
44 | uint32_t height = tft.height();
45 | Serial.print("Height: "); Serial.println(height);
46 |
47 | Serial.println(F("Benchmark Time (microseconds)"));
48 |
49 | Serial.print(F("Screen fill "));
50 | Serial.println(testFillScreen());
51 | delay(500);
52 |
53 | Serial.print(F("Text "));
54 | Serial.println(testText(ID));
55 | delay(3000);
56 |
57 | Serial.print(F("Lines "));
58 | Serial.println(testLines(CYAN));
59 | delay(500);
60 |
61 | Serial.print(F("Horiz/Vert Lines "));
62 | Serial.println(testFastLines(RED, BLUE));
63 | delay(500);
64 |
65 | Serial.print(F("Rectangles (outline) "));
66 | Serial.println(testRects(GREEN));
67 | delay(500);
68 |
69 | Serial.print(F("Rectangles (filled) "));
70 | Serial.println(testFilledRects(YELLOW, MAGENTA));
71 | delay(500);
72 |
73 | Serial.print(F("Circles (filled) "));
74 | Serial.println(testFilledCircles(10, MAGENTA));
75 |
76 | Serial.print(F("Circles (outline) "));
77 | Serial.println(testCircles(10, WHITE));
78 | delay(500);
79 |
80 | Serial.print(F("Triangles (outline) "));
81 | Serial.println(testTriangles());
82 | delay(500);
83 |
84 | Serial.print(F("Triangles (filled) "));
85 | Serial.println(testFilledTriangles());
86 | delay(500);
87 |
88 | Serial.print(F("Rounded rects (outline) "));
89 | Serial.println(testRoundRects());
90 | delay(500);
91 |
92 | Serial.print(F("Rounded rects (filled) "));
93 | Serial.println(testFilledRoundRects());
94 | delay(500);
95 |
96 | Serial.println(F("Done!"));
97 |
98 | }
99 |
100 |
101 | void loop(void) {
102 | for(uint8_t rotation=0; rotation<4; rotation++) {
103 | tft.setRotation(rotation);
104 | testText(ID);
105 | delay(1000);
106 | }
107 | }
108 |
109 | unsigned long testFillScreen() {
110 | unsigned long start = micros();
111 | tft.fillScreen(BLACK);
112 | tft.fillScreen(RED);
113 | tft.fillScreen(GREEN);
114 | tft.fillScreen(BLUE);
115 | tft.fillScreen(BLACK);
116 | return micros() - start;
117 | }
118 |
119 | unsigned long testText(uint32_t ID) {
120 | tft.fillScreen(BLACK);
121 | unsigned long start = micros();
122 | tft.setCursor(0, 0);
123 | tft.setTextColor(WHITE); tft.setTextSize(1);
124 | tft.println("Hello World!");
125 | tft.setTextColor(YELLOW); tft.setTextSize(2);
126 | tft.println(1234.56);
127 | tft.setTextColor(RED); tft.setTextSize(3);
128 | tft.print("TFT is ");
129 | tft.println(ID, HEX);
130 | tft.println();
131 | tft.setTextColor(GREEN);
132 | tft.setTextSize(5);
133 | tft.println("Groop");
134 | tft.setTextSize(2);
135 | tft.println("I implore thee,");
136 | tft.setTextSize(1);
137 | tft.println("my foonting turlingdromes.");
138 | tft.println("And hooptiously drangle me");
139 | tft.println("with crinkly bindlewurdles,");
140 | tft.println("Or I will rend thee");
141 | tft.println("in the gobberwarts");
142 | tft.println("with my blurglecruncheon,");
143 | tft.println("see if I don't!");
144 | return micros() - start;
145 | }
146 |
147 | unsigned long testLines(uint16_t color) {
148 | unsigned long start, t;
149 | int x1, y1, x2, y2,
150 | w = tft.width(),
151 | h = tft.height();
152 |
153 | tft.fillScreen(BLACK);
154 |
155 | x1 = y1 = 0;
156 | y2 = h - 1;
157 | start = micros();
158 | for(x2=0; x20; i-=6) {
236 | i2 = i / 2;
237 | start = micros();
238 | tft.fillRect(cx-i2, cy-i2, i, i, color1);
239 | t += micros() - start;
240 | // Outlines are not included in timing results
241 | tft.drawRect(cx-i2, cy-i2, i, i, color2);
242 | }
243 |
244 | return t;
245 | }
246 |
247 | unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
248 | unsigned long start;
249 | int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
250 |
251 | tft.fillScreen(BLACK);
252 | start = micros();
253 | for(x=radius; x10; i-=5) {
307 | start = micros();
308 | tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
309 | BLACK);
310 | t += micros() - start;
311 | tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
312 | MAROON);
313 | }
314 |
315 | return t;
316 | }
317 |
318 | unsigned long testRoundRects() {
319 | unsigned long start;
320 | int w, i, i2,
321 | cx = tft.width() / 2 - 1,
322 | cy = tft.height() / 2 - 1;
323 |
324 | tft.fillScreen(BLACK);
325 | w = min(tft.width(), tft.height());
326 | start = micros();
327 | for(i=0; i20; i-=6) {
344 | i2 = i / 2;
345 | tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, DARKCYAN);
346 | }
347 |
348 | return micros() - start;
349 | }
350 |
--------------------------------------------------------------------------------
/examples/GraphicsTest_320x480_SMT32/GraphicsTest_320x480_SMT32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for Arduino_Core_STM32
3 | *
4 | * based on MCUFRIEND_kbv.cpp by David Prentice
5 | * https://github.com/prenticedavid/MCUFRIEND_kbv
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | */
20 |
21 |
22 | #include
23 | #include "Arduino-STM32-8bitTFT.h"
24 |
25 | STM32_TFT_8bit tft;
26 |
27 | uint32_t ID;
28 |
29 | void setup() {
30 | delay(1000);
31 | Serial.begin(115200);
32 | Serial.println("Arduino-STM32-8bitTFT");
33 |
34 | ID = tft.readID();
35 | tft.setResolution(320, 480); // Set your resolution
36 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
37 | tft.begin(ID);
38 |
39 | uint32_t width = tft.width();
40 | Serial.print("Width: "); Serial.println(width);
41 | uint32_t height = tft.height();
42 | Serial.print("Height: "); Serial.println(height);
43 |
44 | Serial.println(F("Benchmark Time (microseconds)"));
45 |
46 | Serial.print(F("Screen fill "));
47 | Serial.println(testFillScreen());
48 | delay(500);
49 |
50 | Serial.print(F("Text "));
51 | Serial.println(testText(ID));
52 | delay(3000);
53 |
54 | Serial.print(F("Lines "));
55 | Serial.println(testLines(CYAN));
56 | delay(500);
57 |
58 | Serial.print(F("Horiz/Vert Lines "));
59 | Serial.println(testFastLines(RED, BLUE));
60 | delay(500);
61 |
62 | Serial.print(F("Rectangles (outline) "));
63 | Serial.println(testRects(GREEN));
64 | delay(500);
65 |
66 | Serial.print(F("Rectangles (filled) "));
67 | Serial.println(testFilledRects(YELLOW, MAGENTA));
68 | delay(500);
69 |
70 | Serial.print(F("Circles (filled) "));
71 | Serial.println(testFilledCircles(10, MAGENTA));
72 |
73 | Serial.print(F("Circles (outline) "));
74 | Serial.println(testCircles(10, WHITE));
75 | delay(500);
76 |
77 | Serial.print(F("Triangles (outline) "));
78 | Serial.println(testTriangles());
79 | delay(500);
80 |
81 | Serial.print(F("Triangles (filled) "));
82 | Serial.println(testFilledTriangles());
83 | delay(500);
84 |
85 | Serial.print(F("Rounded rects (outline) "));
86 | Serial.println(testRoundRects());
87 | delay(500);
88 |
89 | Serial.print(F("Rounded rects (filled) "));
90 | Serial.println(testFilledRoundRects());
91 | delay(500);
92 |
93 | Serial.println(F("Done!"));
94 |
95 | }
96 |
97 |
98 | void loop(void) {
99 | for(uint8_t rotation=0; rotation<4; rotation++) {
100 | tft.setRotation(rotation);
101 | testText(ID);
102 | delay(1000);
103 | }
104 | }
105 |
106 | unsigned long testFillScreen() {
107 | unsigned long start = micros();
108 | tft.fillScreen(BLACK);
109 | tft.fillScreen(RED);
110 | tft.fillScreen(GREEN);
111 | tft.fillScreen(BLUE);
112 | tft.fillScreen(BLACK);
113 | return micros() - start;
114 | }
115 |
116 | unsigned long testText(uint32_t ID) {
117 | tft.fillScreen(BLACK);
118 | unsigned long start = micros();
119 | tft.setCursor(0, 0);
120 | tft.setTextColor(WHITE); tft.setTextSize(1);
121 | tft.println("Hello World!");
122 | tft.setTextColor(YELLOW); tft.setTextSize(2);
123 | tft.println(1234.56);
124 | tft.setTextColor(RED); tft.setTextSize(3);
125 | tft.print("TFT is ");
126 | tft.println(ID, HEX);
127 | tft.println();
128 | tft.setTextColor(GREEN);
129 | tft.setTextSize(5);
130 | tft.println("Groop");
131 | tft.setTextSize(2);
132 | tft.println("I implore thee,");
133 | tft.setTextSize(1);
134 | tft.println("my foonting turlingdromes.");
135 | tft.println("And hooptiously drangle me");
136 | tft.println("with crinkly bindlewurdles,");
137 | tft.println("Or I will rend thee");
138 | tft.println("in the gobberwarts");
139 | tft.println("with my blurglecruncheon,");
140 | tft.println("see if I don't!");
141 | return micros() - start;
142 | }
143 |
144 | unsigned long testLines(uint16_t color) {
145 | unsigned long start, t;
146 | int x1, y1, x2, y2,
147 | w = tft.width(),
148 | h = tft.height();
149 |
150 | tft.fillScreen(BLACK);
151 |
152 | x1 = y1 = 0;
153 | y2 = h - 1;
154 | start = micros();
155 | for(x2=0; x20; i-=6) {
233 | i2 = i / 2;
234 | start = micros();
235 | tft.fillRect(cx-i2, cy-i2, i, i, color1);
236 | t += micros() - start;
237 | // Outlines are not included in timing results
238 | tft.drawRect(cx-i2, cy-i2, i, i, color2);
239 | }
240 |
241 | return t;
242 | }
243 |
244 | unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
245 | unsigned long start;
246 | int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
247 |
248 | tft.fillScreen(BLACK);
249 | start = micros();
250 | for(x=radius; x10; i-=5) {
304 | start = micros();
305 | tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
306 | BLACK);
307 | t += micros() - start;
308 | tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
309 | MAROON);
310 | }
311 |
312 | return t;
313 | }
314 |
315 | unsigned long testRoundRects() {
316 | unsigned long start;
317 | int w, i, i2,
318 | cx = tft.width() / 2 - 1,
319 | cy = tft.height() / 2 - 1;
320 |
321 | tft.fillScreen(BLACK);
322 | w = min(tft.width(), tft.height());
323 | start = micros();
324 | for(i=0; i20; i-=6) {
341 | i2 = i / 2;
342 | tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, DARKCYAN);
343 | }
344 |
345 | return micros() - start;
346 | }
347 |
--------------------------------------------------------------------------------
/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 | jpgFile.close();
68 | }
69 |
70 | //====================================================================================
71 | // Decode and paint onto the TFT screen
72 | //====================================================================================
73 | void jpegRender(int xpos, int ypos, int options) {
74 |
75 | //if (options & OPT_REDUCTION) Serial.println("OPT_REDUCTION");
76 | //if (options & OPT_CENTER) Serial.println("OPT_CENTER");
77 | // retrieve infomration about the image
78 | uint16_t *pImg;
79 | uint16_t mcu_w = JpegDec.MCUWidth;
80 | uint16_t mcu_h = JpegDec.MCUHeight;
81 | uint32_t max_x = JpegDec.width;
82 | uint32_t max_y = JpegDec.height;
83 | //Serial.println("mcu_w=" + String(mcu_w));
84 | //Serial.println("mcu_h=" + String(mcu_h));
85 | //Serial.println("max_x=" + String(max_x));
86 | //Serial.println("max_y=" + String(max_y));
87 |
88 | uint16_t szImg2 = mcu_w * mcu_h;
89 | uint16_t *pImg2;
90 | pImg2 = (uint16_t *) malloc(szImg2*2);
91 |
92 | uint32_t tft_width = tft.width();
93 | //Serial.print("tft_width: "); Serial.println(tft_width);
94 | uint32_t tft_height = tft.height();
95 | //Serial.print("tft_height: "); Serial.println(tft_height);
96 |
97 | int reduction_x = 1;
98 | int reduction_y = 1;
99 | if (max_x > tft_width) {
100 | reduction_x = (max_x / tft_width);
101 | if (max_x % tft_width) reduction_x++;
102 | }
103 | if (max_y > tft_height) {
104 | reduction_y = (max_y / tft_height);
105 | if (max_y % tft_height) reduction_y++;
106 | }
107 | //Serial.println("reduction_x=" + String(reduction_x));
108 | //Serial.println("reduction_y=" + String(reduction_y));
109 | int reduction = maximum(reduction_x, reduction_y);
110 | //Serial.println("reduction=" + String(reduction));
111 |
112 | // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
113 | // Typically these MCUs are 16x16 pixel blocks
114 | // Determine the width and height of the right and bottom edge image blocks
115 | uint32_t min_w = minimum(mcu_w, max_x % mcu_w);
116 | uint32_t min_h = minimum(mcu_h, max_y % mcu_h);
117 | //Serial.println("min_w=" + String(min_w));
118 | //Serial.println("min_h=" + String(min_h));
119 |
120 |
121 | // save the current image block size
122 | uint32_t win_w = mcu_w;
123 | uint32_t win_h = mcu_h;
124 |
125 | // record the current time so we can measure how long it takes to draw an image
126 | uint32_t drawTime = millis();
127 |
128 | uint16_t max_xx = max_x;
129 | uint16_t max_yy = max_y;
130 | if (reduction > 1 && (options & OPT_REDUCTION) ) {
131 | max_xx = max_x / reduction; // new image size of X
132 | max_yy = max_y / reduction; // new image size of Y
133 | }
134 | //Serial.println("max_xx=" + String(max_xx));
135 | //Serial.println("max_yy=" + String(max_yy));
136 |
137 | // calculation center position
138 | int delta_x = 0;
139 | int delta_y = 0;
140 | if ( (max_xx < tft_width) && (options & OPT_CENTER) ) {
141 | delta_x = (tft_width - max_xx) / 2;
142 | }
143 | if ( (max_yy < tft_height) && (options & OPT_CENTER) ) {
144 | delta_y = (tft_height - max_yy) / 2;
145 | }
146 | //Serial.println("delta_x=" + String(delta_x));
147 | //Serial.println("delta_y=" + String(delta_y));
148 |
149 | // save the coordinate of the right and bottom edges to assist image cropping
150 | // to the screen size
151 | max_x += xpos;
152 | max_y += ypos;
153 |
154 | // read each MCU block until there are no more
155 | while ( JpegDec.read()) {
156 |
157 | // save a pointer to the image block
158 | pImg = JpegDec.pImage;
159 |
160 | // calculate where the image block should be drawn on the screen
161 | int mcu_x = JpegDec.MCUx * mcu_w + xpos;
162 | int mcu_y = JpegDec.MCUy * mcu_h + ypos;
163 |
164 | // check if the image block size needs to be changed for the right and bottom edges
165 | if (mcu_x + mcu_w <= max_x) win_w = mcu_w;
166 | else win_w = min_w;
167 | if (mcu_y + mcu_h <= max_y) win_h = mcu_h;
168 | else win_h = min_h;
169 |
170 | memcpy(pImg2, JpegDec.pImage, szImg2*2);
171 | int mcu_xx = mcu_x + delta_x;
172 | int mcu_yy = mcu_y + delta_y;
173 | uint32_t win_ww = win_w;
174 | uint32_t win_hh = win_h;
175 |
176 | if (reduction > 1 && (options & OPT_REDUCTION) ){
177 | int pos1 = 0;
178 | int pos2 = 0;
179 | for(int x=0; x 1 && (options & OPT_REDUCTION) ) {
244 | int reductionRate = (float)(1.0 / reduction) * 100;
245 | Serial.print ("Rate of reduction was : "); Serial.print(reductionRate); Serial.println(" %");
246 | }
247 | Serial.println("=====================================");
248 |
249 | }
250 | //====================================================================================
251 | // Send time taken to Serial port
252 | //====================================================================================
253 | void jpegInfo() {
254 | Serial.println(F("==============="));
255 | Serial.println(F("JPEG image info"));
256 | Serial.println(F("==============="));
257 | Serial.print(F( "Width :")); Serial.println(JpegDec.width);
258 | Serial.print(F( "Height :")); Serial.println(JpegDec.height);
259 | Serial.print(F( "Components :")); Serial.println(JpegDec.comps);
260 | Serial.print(F( "MCU / row :")); Serial.println(JpegDec.MCUSPerRow);
261 | Serial.print(F( "MCU / col :")); Serial.println(JpegDec.MCUSPerCol);
262 | Serial.print(F( "Scan type :")); Serial.println(JpegDec.scanType);
263 | Serial.print(F( "MCU width :")); Serial.println(JpegDec.MCUWidth);
264 | Serial.print(F( "MCU height :")); Serial.println(JpegDec.MCUHeight);
265 | Serial.println(F("==============="));
266 | }
267 |
268 | //====================================================================================
269 | // Open a Jpeg file on an SD card and dump it to the Serial port as a C array
270 | //====================================================================================
271 | void createArray(const char *filename) {
272 |
273 | File jpgFile; // File handle reference For SD library
274 |
275 | if ( !( jpgFile = sd.open( filename, FILE_READ))) {
276 | Serial.println(F("JPEG file not found"));
277 | return;
278 | }
279 |
280 | uint8_t data;
281 | byte line_len = 0;
282 | Serial.println("// Generated by a JPEGDecoder library example sketch:");
283 | Serial.println("// https://github.com/Bodmer/JPEGDecoder");
284 | Serial.println("");
285 | Serial.println("#if defined(__AVR__)");
286 | Serial.println(" #include ");
287 | Serial.println("#endif");
288 | Serial.println("");
289 | Serial.print("const uint8_t ");
290 | while (*filename != '.') Serial.print(*filename++);
291 | Serial.println("[] PROGMEM = {"); // PROGMEM added for AVR processors
292 |
293 | while ( jpgFile.available()) {
294 |
295 | data = jpgFile.read();
296 | Serial.print("0x"); if (abs(data) < 16) Serial.print("0");
297 | Serial.print(data, HEX); Serial.print(",");// Add value and comma
298 | line_len++;
299 | if ( line_len >= 32) {
300 | line_len = 0;
301 | Serial.println();
302 | }
303 |
304 | }
305 |
306 | Serial.println("};\r\n");
307 | jpgFile.close();
308 | }
309 |
310 |
311 | //====================================================================================
312 |
--------------------------------------------------------------------------------
/examples/JpegView_240x320_SMT32/JpegView_240x320_SMT32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for Arduino_Core_STM32
3 | *
4 | * based on MCUFRIEND_kbv.cpp by David Prentice
5 | * https://github.com/prenticedavid/MCUFRIEND_kbv
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | */
20 |
21 |
22 | #include
23 | #include "Arduino-STM32-8bitTFT.h"
24 | #include // https://github.com/greiman/SdFat
25 | #include // https://github.com/greiman/SdFat
26 | #include // https://github.com/Bodmer/JPEGDecoder
27 |
28 | STM32_TFT_8bit tft;
29 |
30 | // SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
31 | // 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
32 | #define SD_FAT_TYPE 1
33 |
34 | // Define SPI_2 object.
35 | // STM32F103's SPI_2 object uses the following GPIO.
36 | #define SD_CS PB12
37 | #define SD_SCLK PB13
38 | #define SD_MISO PB14
39 | #define SD_MOSI PB15
40 | static SPIClass SPI_2 (SD_MOSI, SD_MISO, SD_SCLK, SD_CS);
41 |
42 | // Define SdSpiConfig using SPI_2 object.
43 | #define SetSDSpeed 48
44 | #define SD_CONFIG SdSpiConfig (SD_CS, DEDICATED_SPI, SD_SCK_MHZ (SetSDSpeed), &SPI_2)
45 | //------------------------------------------------------------------------------
46 |
47 | #if SD_FAT_TYPE == 0
48 | SdFat sd;
49 | File file;
50 | File root;
51 | #elif SD_FAT_TYPE == 1
52 | SdFat32 sd;
53 | File32 file;
54 | File32 root;
55 | #elif SD_FAT_TYPE == 2
56 | SdExFat sd;
57 | ExFile file;
58 | ExFile root;
59 | #elif SD_FAT_TYPE == 3
60 | SdFs sd;
61 | FsFile file;
62 | FsFile root;
63 | #endif // SD_FAT_TYPE
64 |
65 | //------------------------------------------------------------------------------
66 | // Store error strings in flash to save RAM.
67 | #define error(s) sd.errorHalt(&Serial, F(s))
68 | //------------------------------------------------------------------------------
69 |
70 | #define OPT_REDUCTION 1
71 | #define OPT_CENTER 2
72 |
73 | #define maxFileCount 100
74 | int jpegFileCount;
75 | uint16_t jpegFileIndex[maxFileCount];
76 |
77 | int getFileNameByIndex(int index, char * fname, size_t fnameSize)
78 | {
79 | if (!file.open(&root, index, O_READ)) {
80 | error("open file failed");
81 | }
82 | //Serial.println("open ok ");
83 | file.getName(fname, fnameSize);
84 | //Serial.println("fname=" + String(fname));
85 | file.close();
86 | return strlen(fname);
87 | }
88 |
89 | void setup() {
90 | delay(1000);
91 | Serial.begin(115200);
92 | Serial.println("Arduino-STM32-8bitTFT");
93 |
94 | uint32_t ID = tft.readID();
95 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
96 | tft.begin(ID);
97 |
98 | uint32_t width = tft.width();
99 | Serial.print("Width: "); Serial.println(width);
100 | uint32_t height = tft.height();
101 | Serial.print("Height: "); Serial.println(height);
102 | if (width < height) tft.setRotation(3);
103 |
104 | // Initialize the SD card.
105 | if (!sd.begin(SD_CONFIG)) {
106 | sd.initErrorHalt(&Serial);
107 | }
108 |
109 | jpegFileCount = 0;
110 | if (!root.open("/")) {
111 | error("open root");
112 | }
113 | while (file.openNext(&root, O_RDONLY)) {
114 | // Skip directories and hidden files.
115 | if (!file.isSubDir() && !file.isHidden()) {
116 | // get file name
117 | char fname[32];
118 | file.getName(fname, sizeof(fname));
119 | Serial.print("fname=");
120 | Serial.println(fname);
121 | //jpegFileCount++;
122 |
123 | // Is jpeg file
124 | if (strstr(fname, ".jpg") != 0) {
125 | // Save dirIndex of file in directory.
126 | if (jpegFileCount < maxFileCount) {
127 | jpegFileIndex[jpegFileCount++] = file.dirIndex();
128 | }
129 | }
130 | }
131 | file.close();
132 | }
133 | Serial.println("jpegFileCount=" + String(jpegFileCount));
134 |
135 | for (int ipos=0;ipos (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 | jpgFile.close();
68 | }
69 |
70 | //====================================================================================
71 | // Decode and paint onto the TFT screen
72 | //====================================================================================
73 | void jpegRender(int xpos, int ypos, int options) {
74 |
75 | //if (options & OPT_REDUCTION) Serial.println("OPT_REDUCTION");
76 | //if (options & OPT_CENTER) Serial.println("OPT_CENTER");
77 | // retrieve infomration about the image
78 | uint16_t *pImg;
79 | uint16_t mcu_w = JpegDec.MCUWidth;
80 | uint16_t mcu_h = JpegDec.MCUHeight;
81 | uint32_t max_x = JpegDec.width;
82 | uint32_t max_y = JpegDec.height;
83 | //Serial.println("mcu_w=" + String(mcu_w));
84 | //Serial.println("mcu_h=" + String(mcu_h));
85 | //Serial.println("max_x=" + String(max_x));
86 | //Serial.println("max_y=" + String(max_y));
87 |
88 | uint16_t szImg2 = mcu_w * mcu_h;
89 | uint16_t *pImg2;
90 | pImg2 = (uint16_t *) malloc(szImg2*2);
91 |
92 | uint32_t tft_width = tft.width();
93 | //Serial.print("tft_width: "); Serial.println(tft_width);
94 | uint32_t tft_height = tft.height();
95 | //Serial.print("tft_height: "); Serial.println(tft_height);
96 |
97 | int reduction_x = 1;
98 | int reduction_y = 1;
99 | if (max_x > tft_width) {
100 | reduction_x = (max_x / tft_width);
101 | if (max_x % tft_width) reduction_x++;
102 | }
103 | if (max_y > tft_height) {
104 | reduction_y = (max_y / tft_height);
105 | if (max_y % tft_height) reduction_y++;
106 | }
107 | //Serial.println("reduction_x=" + String(reduction_x));
108 | //Serial.println("reduction_y=" + String(reduction_y));
109 | int reduction = maximum(reduction_x, reduction_y);
110 | //Serial.println("reduction=" + String(reduction));
111 |
112 | // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
113 | // Typically these MCUs are 16x16 pixel blocks
114 | // Determine the width and height of the right and bottom edge image blocks
115 | uint32_t min_w = minimum(mcu_w, max_x % mcu_w);
116 | uint32_t min_h = minimum(mcu_h, max_y % mcu_h);
117 | //Serial.println("min_w=" + String(min_w));
118 | //Serial.println("min_h=" + String(min_h));
119 |
120 |
121 | // save the current image block size
122 | uint32_t win_w = mcu_w;
123 | uint32_t win_h = mcu_h;
124 |
125 | // record the current time so we can measure how long it takes to draw an image
126 | uint32_t drawTime = millis();
127 |
128 | uint16_t max_xx = max_x;
129 | uint16_t max_yy = max_y;
130 | if (reduction > 1 && (options & OPT_REDUCTION) ) {
131 | max_xx = max_x / reduction; // new image size of X
132 | max_yy = max_y / reduction; // new image size of Y
133 | }
134 | //Serial.println("max_xx=" + String(max_xx));
135 | //Serial.println("max_yy=" + String(max_yy));
136 |
137 | // calculation center position
138 | int delta_x = 0;
139 | int delta_y = 0;
140 | if ( (max_xx < tft_width) && (options & OPT_CENTER) ) {
141 | delta_x = (tft_width - max_xx) / 2;
142 | }
143 | if ( (max_yy < tft_height) && (options & OPT_CENTER) ) {
144 | delta_y = (tft_height - max_yy) / 2;
145 | }
146 | //Serial.println("delta_x=" + String(delta_x));
147 | //Serial.println("delta_y=" + String(delta_y));
148 |
149 | // save the coordinate of the right and bottom edges to assist image cropping
150 | // to the screen size
151 | max_x += xpos;
152 | max_y += ypos;
153 |
154 | // read each MCU block until there are no more
155 | while ( JpegDec.read()) {
156 |
157 | // save a pointer to the image block
158 | pImg = JpegDec.pImage;
159 |
160 | // calculate where the image block should be drawn on the screen
161 | int mcu_x = JpegDec.MCUx * mcu_w + xpos;
162 | int mcu_y = JpegDec.MCUy * mcu_h + ypos;
163 |
164 | // check if the image block size needs to be changed for the right and bottom edges
165 | if (mcu_x + mcu_w <= max_x) win_w = mcu_w;
166 | else win_w = min_w;
167 | if (mcu_y + mcu_h <= max_y) win_h = mcu_h;
168 | else win_h = min_h;
169 |
170 | memcpy(pImg2, JpegDec.pImage, szImg2*2);
171 | int mcu_xx = mcu_x + delta_x;
172 | int mcu_yy = mcu_y + delta_y;
173 | uint32_t win_ww = win_w;
174 | uint32_t win_hh = win_h;
175 |
176 | if (reduction > 1 && (options & OPT_REDUCTION) ){
177 | int pos1 = 0;
178 | int pos2 = 0;
179 | for(int x=0; x 1 && (options & OPT_REDUCTION) ) {
244 | int reductionRate = (float)(1.0 / reduction) * 100;
245 | Serial.print ("Rate of reduction was : "); Serial.print(reductionRate); Serial.println(" %");
246 | }
247 | Serial.println("=====================================");
248 |
249 | }
250 | //====================================================================================
251 | // Send time taken to Serial port
252 | //====================================================================================
253 | void jpegInfo() {
254 | Serial.println(F("==============="));
255 | Serial.println(F("JPEG image info"));
256 | Serial.println(F("==============="));
257 | Serial.print(F( "Width :")); Serial.println(JpegDec.width);
258 | Serial.print(F( "Height :")); Serial.println(JpegDec.height);
259 | Serial.print(F( "Components :")); Serial.println(JpegDec.comps);
260 | Serial.print(F( "MCU / row :")); Serial.println(JpegDec.MCUSPerRow);
261 | Serial.print(F( "MCU / col :")); Serial.println(JpegDec.MCUSPerCol);
262 | Serial.print(F( "Scan type :")); Serial.println(JpegDec.scanType);
263 | Serial.print(F( "MCU width :")); Serial.println(JpegDec.MCUWidth);
264 | Serial.print(F( "MCU height :")); Serial.println(JpegDec.MCUHeight);
265 | Serial.println(F("==============="));
266 | }
267 |
268 | //====================================================================================
269 | // Open a Jpeg file on an SD card and dump it to the Serial port as a C array
270 | //====================================================================================
271 | void createArray(const char *filename) {
272 |
273 | File jpgFile; // File handle reference For SD library
274 |
275 | if ( !( jpgFile = sd.open( filename, FILE_READ))) {
276 | Serial.println(F("JPEG file not found"));
277 | return;
278 | }
279 |
280 | uint8_t data;
281 | byte line_len = 0;
282 | Serial.println("// Generated by a JPEGDecoder library example sketch:");
283 | Serial.println("// https://github.com/Bodmer/JPEGDecoder");
284 | Serial.println("");
285 | Serial.println("#if defined(__AVR__)");
286 | Serial.println(" #include ");
287 | Serial.println("#endif");
288 | Serial.println("");
289 | Serial.print("const uint8_t ");
290 | while (*filename != '.') Serial.print(*filename++);
291 | Serial.println("[] PROGMEM = {"); // PROGMEM added for AVR processors
292 |
293 | while ( jpgFile.available()) {
294 |
295 | data = jpgFile.read();
296 | Serial.print("0x"); if (abs(data) < 16) Serial.print("0");
297 | Serial.print(data, HEX); Serial.print(",");// Add value and comma
298 | line_len++;
299 | if ( line_len >= 32) {
300 | line_len = 0;
301 | Serial.println();
302 | }
303 |
304 | }
305 |
306 | Serial.println("};\r\n");
307 | jpgFile.close();
308 | }
309 |
310 |
311 | //====================================================================================
312 |
--------------------------------------------------------------------------------
/examples/JpegView_320x480_SMT32/JpegView_320x480_SMT32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for Arduino_Core_STM32
3 | *
4 | * based on MCUFRIEND_kbv.cpp by David Prentice
5 | * https://github.com/prenticedavid/MCUFRIEND_kbv
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | */
20 |
21 |
22 | #include
23 | #include "Arduino-STM32-8bitTFT.h"
24 | #include // https://github.com/greiman/SdFat
25 | #include // https://github.com/greiman/SdFat
26 | #include // https://github.com/Bodmer/JPEGDecoder
27 |
28 | STM32_TFT_8bit tft;
29 |
30 | // SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
31 | // 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
32 | #define SD_FAT_TYPE 1
33 |
34 | // Define SPI_2 object.
35 | // STM32F103's SPI_2 object uses the following GPIO.
36 | #define SD_CS PB12
37 | #define SD_SCLK PB13
38 | #define SD_MISO PB14
39 | #define SD_MOSI PB15
40 | static SPIClass SPI_2 (SD_MOSI, SD_MISO, SD_SCLK, SD_CS);
41 |
42 | // Define SdSpiConfig using SPI_2 object.
43 | #define SetSDSpeed 48
44 | #define SD_CONFIG SdSpiConfig (SD_CS, DEDICATED_SPI, SD_SCK_MHZ (SetSDSpeed), &SPI_2)
45 | //------------------------------------------------------------------------------
46 |
47 | #if SD_FAT_TYPE == 0
48 | SdFat sd;
49 | File file;
50 | File root;
51 | #elif SD_FAT_TYPE == 1
52 | SdFat32 sd;
53 | File32 file;
54 | File32 root;
55 | #elif SD_FAT_TYPE == 2
56 | SdExFat sd;
57 | ExFile file;
58 | ExFile root;
59 | #elif SD_FAT_TYPE == 3
60 | SdFs sd;
61 | FsFile file;
62 | FsFile root;
63 | #endif // SD_FAT_TYPE
64 |
65 | //------------------------------------------------------------------------------
66 | // Store error strings in flash to save RAM.
67 | #define error(s) sd.errorHalt(&Serial, F(s))
68 | //------------------------------------------------------------------------------
69 |
70 | #define OPT_REDUCTION 1
71 | #define OPT_CENTER 2
72 |
73 | #define maxFileCount 100
74 | int jpegFileCount;
75 | uint16_t jpegFileIndex[maxFileCount];
76 |
77 | int getFileNameByIndex(int index, char * fname, size_t fnameSize)
78 | {
79 | if (!file.open(&root, index, O_READ)) {
80 | error("open file failed");
81 | }
82 | //Serial.println("open ok ");
83 | file.getName(fname, fnameSize);
84 | //Serial.println("fname=" + String(fname));
85 | file.close();
86 | return strlen(fname);
87 | }
88 |
89 | void setup() {
90 | delay(1000);
91 | Serial.begin(115200);
92 | Serial.println("Arduino-STM32-8bitTFT");
93 |
94 | uint32_t ID = tft.readID();
95 | tft.setResolution(320, 480); // Set your resolution
96 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
97 | tft.begin(ID);
98 |
99 | uint32_t width = tft.width();
100 | Serial.print("Width: "); Serial.println(width);
101 | uint32_t height = tft.height();
102 | Serial.print("Height: "); Serial.println(height);
103 | if (width < height) tft.setRotation(3);
104 |
105 | // Initialize the SD card.
106 | if (!sd.begin(SD_CONFIG)) {
107 | sd.initErrorHalt(&Serial);
108 | }
109 |
110 | jpegFileCount = 0;
111 | if (!root.open("/")) {
112 | error("open root");
113 | }
114 | while (file.openNext(&root, O_RDONLY)) {
115 | // Skip directories and hidden files.
116 | if (!file.isSubDir() && !file.isHidden()) {
117 | // get file name
118 | char fname[32];
119 | file.getName(fname, sizeof(fname));
120 | Serial.print("fname=");
121 | Serial.println(fname);
122 | //jpegFileCount++;
123 |
124 | // Is jpeg file
125 | if (strstr(fname, ".jpg") != 0) {
126 | // Save dirIndex of file in directory.
127 | if (jpegFileCount < maxFileCount) {
128 | jpegFileIndex[jpegFileCount++] = file.dirIndex();
129 | }
130 | }
131 | }
132 | file.close();
133 | }
134 | Serial.println("jpegFileCount=" + String(jpegFileCount));
135 |
136 | for (int ipos=0;ipos.
19 | */
20 |
21 | #include
22 | #include "Arduino-STM32-8bitTFT.h"
23 |
24 | STM32_TFT_8bit tft;
25 |
26 | void setup(void) {
27 | delay(1000);
28 | Serial.begin(115200);
29 |
30 | uint16_t ID = tft.readID();
31 | Serial.println("ID = 0x" + String(ID,HEX));
32 | tft.begin(ID);
33 | }
34 |
35 |
36 | void loop(void) {
37 | uint8_t aspect;
38 | uint16_t pixel;
39 | const char *aspectname[] = {
40 | "PORTRAIT", "LANDSCAPE", "PORTRAIT_REV", "LANDSCAPE_REV"
41 | };
42 | const char *colorname[] = { "BLUE", "GREEN", "RED", "GRAY" };
43 | uint16_t colormask[] = { 0x001F, 0x07E0, 0xF800, 0xFFFF };
44 | uint16_t dx, rgb, n, wid, ht, msgline;
45 | tft.setRotation(0);
46 | if (tft.height() > 64) {
47 | for (uint8_t cnt = 0; cnt < 4; cnt++) {
48 | aspect = (cnt + 0) & 3;
49 | tft.setRotation(aspect);
50 | wid = tft.width();
51 | ht = tft.height();
52 | Serial.println("aspect=" + String(aspect));
53 | Serial.println("width=" + String(wid) + " height=" + String(ht));
54 | msgline = (ht > 160) ? 200 : 112;
55 | testText();
56 |
57 | // Show COLOR GRADES
58 | dx = wid / 32;
59 | for (n = 0; n < 32; n++) {
60 | rgb = n * 8;
61 | rgb = tft.color565(rgb, rgb, rgb);
62 | tft.fillRect(n * dx, 48, dx, 63, rgb & colormask[aspect]);
63 | }
64 | tft.drawRect(0, 48 + 63, wid, 1, WHITE);
65 | tft.setTextSize(2);
66 | tft.setTextColor(colormask[aspect], BLACK);
67 | tft.setCursor(0, 72);
68 | tft.print(colorname[aspect]);
69 | tft.setTextColor(WHITE);
70 | tft.println(" COLOR GRADES");
71 | tft.setTextColor(WHITE, BLACK);
72 | printmsg(184, aspectname[aspect]);
73 | delay(1000);
74 | tft.drawPixel(0, 0, YELLOW);
75 | pixel = tft.readPixel(0, 0);
76 | tft.setTextSize((ht > 160) ? 2 : 1); //for messages
77 |
78 | // Show penguin icon
79 | extern const uint8_t penguin[];
80 | tft.setAddrWindow(wid - 40 - 40, 20 + 0, wid - 1 - 40, 20 + 39);
81 | tft.pushColors8((uint8_t *)penguin, 1600, 1);
82 |
83 | // Scroll Screen
84 | tft.setAddrWindow(0, 0, wid - 1, ht - 1);
85 | if (aspect & 1) tft.drawRect(wid - 1, 0, 1, ht, WHITE);
86 | else tft.drawRect(0, ht - 1, wid, 1, WHITE);
87 | printmsg(msgline, "VERTICAL SCROLL UP");
88 | uint16_t maxscroll;
89 | if (tft.getRotation() & 1) maxscroll = wid;
90 | else maxscroll = ht;
91 | int step = -1;
92 | if ( wid < ht ) step = 1;
93 |
94 | // Scroll Up
95 | for (int16_t i = 1; i <= maxscroll; i++) {
96 | tft.vertScroll(0, maxscroll, i * step);
97 | delay(10);
98 | }
99 | delay(1000);
100 |
101 | // Scroll Down
102 | printmsg(msgline, "VERTICAL SCROLL DN");
103 | for (int16_t i = 1; i <= maxscroll; i++) {
104 | tft.vertScroll(0, maxscroll, (0 - i) * step);
105 | delay(10);
106 | }
107 | tft.vertScroll(0, maxscroll, 0);
108 | printmsg(msgline, "SCROLL DISABLED");
109 |
110 | // Scroll COLOR GRADES
111 | delay(1000);
112 | if ((aspect & 1) == 0) { //Portrait
113 | int stline;
114 | stline = 128;
115 | step = -1;
116 | if (wid < ht) {
117 | stline = 48;
118 | step = 1;
119 | }
120 | tft.setTextColor(BLUE, BLACK);
121 | printmsg(msgline, "ONLY THE COLOR BAND");
122 | for (int16_t i = 1; i <= 64; i++) {
123 | tft.vertScroll(stline, 64, i * step);
124 | delay(20);
125 | }
126 | delay(1000);
127 | for (int16_t i = 1; i <= 64; i++) {
128 | tft.vertScroll(stline, 64, (0 - i) * step);
129 | delay(20);
130 | }
131 | delay(1000);
132 |
133 | #if 0
134 | if ( wid < ht ) {
135 | stline = 48;
136 | for (int16_t i = 1; i <= 64; i++) {
137 | tft.vertScroll(stline, 64, i);
138 | delay(20);
139 | }
140 | delay(1000);
141 | for (int16_t i = 1; i <= 64; i++) {
142 | tft.vertScroll(stline, 64, 0 - i);
143 | delay(20);
144 | }
145 | delay(1000);
146 | } else {
147 | stline = 128;
148 | for (int16_t i = 1; i <= 64; i++) {
149 | tft.vertScroll(stline, 64, 0 - i);
150 | delay(20);
151 | }
152 | delay(1000);
153 | for (int16_t i = 1; i <= 64; i++) {
154 | tft.vertScroll(stline, 64, i);
155 | delay(20);
156 | }
157 | delay(1000);
158 | }
159 | #endif
160 | }
161 |
162 | printmsg(msgline, "INVERT DISPLAY");
163 | tft.invertDisplay(true);
164 | delay(3000);
165 | printmsg(msgline, "NORMAL DISPLAY");
166 | tft.invertDisplay(false);
167 | delay(3000);
168 | }
169 | }
170 | }
171 |
172 | void testText() {
173 | tft.fillScreen(BLACK);
174 | tft.setCursor(0, 0);
175 | tft.setTextColor(WHITE); tft.setTextSize(1);
176 | tft.println("Hello World!");
177 | tft.setTextColor(YELLOW); tft.setTextSize(2);
178 | tft.println(123.45);
179 | tft.setTextColor(RED); tft.setTextSize(3);
180 | tft.println(0xDEADBEEF, HEX);
181 | tft.println();
182 | tft.setTextColor(GREEN);
183 | tft.setTextSize(5);
184 | tft.println("Groop");
185 | tft.setTextSize(2);
186 | tft.println("I implore thee,");
187 | tft.setTextSize(1);
188 | tft.println("my foonting turlingdromes.");
189 | tft.println("And hooptiously drangle me");
190 | tft.println("with crinkly bindlewurdles,");
191 | tft.println("Or I will rend thee");
192 | tft.println("in the gobberwarts");
193 | tft.println("with my blurglecruncheon,");
194 | tft.println("see if I don't!");
195 | }
196 |
197 | void printmsg(int row, const char *msg)
198 | {
199 | static char primary_msg[64];
200 |
201 | if (strlen(primary_msg)) {
202 | tft.setTextColor(BLACK, BLACK);
203 | tft.setCursor(0, row);
204 | tft.println(primary_msg);
205 | }
206 | tft.setTextColor(YELLOW, BLACK);
207 | tft.setCursor(0, row);
208 | tft.println(msg);
209 | strcpy(primary_msg,msg);
210 | }
211 |
212 |
213 |
214 |
--------------------------------------------------------------------------------
/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_Meter_linear_STM32/TFT_Meter_linear_STM32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for Arduino_Core_STM32
3 | *
4 | * Demo based on:
5 | * TFT_Meter_linear by Bodmar
6 | * web: https://github.com/Bodmer/TFT_eSPI/tree/master/examples/320%20x%20240/TFT_Meter_linear
7 | *
8 | */
9 |
10 | // Define meter size as 1 for tft.rotation(0) or 1.3333 for tft.rotation(1)
11 | #define M_SIZE 1.3333
12 |
13 | #include
14 | #include
15 | #include "Arduino-STM32-8bitTFT.h"
16 |
17 | STM32_TFT_8bit tft;
18 |
19 | #define TFT_GREY GRAY
20 | #define TFT_BLACK BLACK
21 | #define TFT_WHITE WHITE
22 | #define TFT_GREEN GREEN
23 | #define TFT_ORANGE ORANGE
24 | #define TFT_RED RED
25 | #define TFT_MAGENTA MAGENTA
26 |
27 | float ltx = 0; // Saved x coord of bottom of needle
28 | uint16_t osx = M_SIZE*120, osy = M_SIZE*120; // Saved x & y coords
29 | uint32_t updateTime = 0; // time for next update
30 |
31 | int old_analog = -999; // Value last displayed
32 |
33 | int value[6] = {0, 0, 0, 0, 0, 0};
34 | int old_value[6] = { -1, -1, -1, -1, -1, -1};
35 | int d = 0;
36 |
37 | void setup(void) {
38 | delay(1000);
39 | Serial.begin(115200);
40 | uint32_t ID = tft.readID();
41 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
42 | tft.begin(ID);
43 | tft.setRotation(1);
44 | tft.fillScreen(TFT_BLACK);
45 |
46 | analogMeter(); // Draw analogue meter
47 |
48 | updateTime = millis(); // Next update time
49 | }
50 |
51 |
52 | void loop() {
53 | if (updateTime <= millis()) {
54 | updateTime = millis() + 35; // Update emter every 35 milliseconds
55 |
56 | // Create a Sine wave for testing
57 | d += 4; if (d >= 360) d = 0;
58 | value[0] = 50 + 50 * sin((d + 0) * 0.0174532925);
59 |
60 | plotNeedle(value[0], 0); // It takes between 2 and 12ms to replot the needle with zero delay
61 | }
62 | }
63 |
64 |
65 | // #########################################################################
66 | // Draw the analogue meter on the screen
67 | // #########################################################################
68 | void analogMeter()
69 | {
70 |
71 | // Meter outline
72 | tft.fillRect(0, 0, M_SIZE*239, M_SIZE*126, TFT_GREY);
73 | tft.fillRect(5, 3, M_SIZE*230, M_SIZE*119, TFT_WHITE);
74 |
75 | tft.setTextColor(TFT_BLACK); // Text colour
76 |
77 | // Draw ticks every 5 degrees from -50 to +50 degrees (100 deg. FSD swing)
78 | for (int i = -50; i < 51; i += 5) {
79 | // Long scale tick length
80 | int tl = 15;
81 |
82 | // Coodinates of tick to draw
83 | float sx = cos((i - 90) * 0.0174532925);
84 | float sy = sin((i - 90) * 0.0174532925);
85 | uint16_t x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120;
86 | uint16_t y0 = sy * (M_SIZE*100 + tl) + M_SIZE*140;
87 | uint16_t x1 = sx * M_SIZE*100 + M_SIZE*120;
88 | uint16_t y1 = sy * M_SIZE*100 + M_SIZE*140;
89 |
90 | // Coordinates of next tick for zone fill
91 | float sx2 = cos((i + 5 - 90) * 0.0174532925);
92 | float sy2 = sin((i + 5 - 90) * 0.0174532925);
93 | int x2 = sx2 * (M_SIZE*100 + tl) + M_SIZE*120;
94 | int y2 = sy2 * (M_SIZE*100 + tl) + M_SIZE*140;
95 | int x3 = sx2 * M_SIZE*100 + M_SIZE*120;
96 | int y3 = sy2 * M_SIZE*100 + M_SIZE*140;
97 |
98 | // Yellow zone limits
99 | //if (i >= -50 && i < 0) {
100 | // tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_YELLOW);
101 | // tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_YELLOW);
102 | //}
103 |
104 | // Green zone limits
105 | if (i >= 0 && i < 25) {
106 | tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_GREEN);
107 | tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREEN);
108 | }
109 |
110 | // Orange zone limits
111 | if (i >= 25 && i < 50) {
112 | tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_ORANGE);
113 | tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_ORANGE);
114 | }
115 |
116 | // Short scale tick length
117 | if (i % 25 != 0) tl = 8;
118 |
119 | // Recalculate coords incase tick lenght changed
120 | x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120;
121 | y0 = sy * (M_SIZE*100 + tl) + M_SIZE*140;
122 | x1 = sx * M_SIZE*100 + M_SIZE*120;
123 | y1 = sy * M_SIZE*100 + M_SIZE*140;
124 |
125 | // Draw tick
126 | tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
127 |
128 | // Check if labels should be drawn, with position tweaks
129 | if (i % 25 == 0) {
130 | // Calculate label positions
131 | x0 = sx * (M_SIZE*100 + tl + 10) + M_SIZE*120;
132 | y0 = sy * (M_SIZE*100 + tl + 10) + M_SIZE*140;
133 | switch (i / 25) {
134 | #if 0
135 | case -2: tft.drawCentreString("0", x0, y0 - 12, 2); break;
136 | case -1: tft.drawCentreString("25", x0, y0 - 9, 2); break;
137 | case 0: tft.drawCentreString("50", x0, y0 - 7, 2); break;
138 | case 1: tft.drawCentreString("75", x0, y0 - 9, 2); break;
139 | case 2: tft.drawCentreString("100", x0, y0 - 12, 2); break;
140 | #endif
141 | case -2: _drawString("0", x0-10, y0 - 12, 2); break;
142 | case -1: _drawString("25", x0-10, y0 - 9, 2); break;
143 | case 0: _drawString("50", x0-10, y0 - 7, 2); break;
144 | case 1: _drawString("75", x0-10, y0 - 9, 2); break;
145 | case 2: _drawString("100", x0-10, y0 - 12, 2); break;
146 | }
147 | }
148 |
149 | // Now draw the arc of the scale
150 | sx = cos((i + 5 - 90) * 0.0174532925);
151 | sy = sin((i + 5 - 90) * 0.0174532925);
152 | x0 = sx * M_SIZE*100 + M_SIZE*120;
153 | y0 = sy * M_SIZE*100 + M_SIZE*140;
154 | // Draw scale arc, don't draw the last part
155 | if (i < 50) tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
156 | }
157 |
158 | _drawString("%RH", M_SIZE*(5 + 230 - 40), M_SIZE*(119 - 20), 2); // Units at bottom right
159 | //tft.drawString("%RH", M_SIZE*(5 + 230 - 40), M_SIZE*(119 - 20), 2); // Units at bottom right
160 |
161 | //tft.drawCentreString("%RH", M_SIZE*120, M_SIZE*70, 4); // Comment out to avoid font 4
162 |
163 | tft.drawRect(5, 3, M_SIZE*230, M_SIZE*119, TFT_BLACK); // Draw bezel line
164 | plotNeedle(0, 0); // Put meter needle at 0
165 | }
166 |
167 | // #########################################################################
168 | // Update needle position
169 | // This function is blocking while needle moves, time depends on ms_delay
170 | // 10ms minimises needle flicker if text is drawn within needle sweep area
171 | // Smaller values OK if text not in sweep area, zero for instant movement but
172 | // does not look realistic... (note: 100 increments for full scale deflection)
173 | // #########################################################################
174 | void plotNeedle(int value, byte ms_delay)
175 | {
176 | tft.setTextColor(TFT_BLACK, TFT_WHITE);
177 | char buf[8]; dtostrf(value, 4, 0, buf);
178 | _drawString("%RH", M_SIZE*(5 + 230 - 40), M_SIZE*(119 - 20), 2); // Units at bottom right
179 | //tft.drawString("%RH", M_SIZE*(5 + 230 - 40), M_SIZE*(119 - 20), 2); // Units at bottom right
180 | _drawString(buf, M_SIZE*40-40, M_SIZE*(119 - 20), 2);
181 | //tft.drawRightString(buf, M_SIZE*40, M_SIZE*(119 - 20), 2);
182 |
183 | if (value < -10) value = -10; // Limit value to emulate needle end stops
184 | if (value > 110) value = 110;
185 |
186 | // Move the needle until new value reached
187 | while (!(value == old_analog)) {
188 | if (old_analog < value) old_analog++;
189 | else old_analog--;
190 |
191 | if (ms_delay == 0) old_analog = value; // Update immediately if delay is 0
192 |
193 | float sdeg = map(old_analog, -10, 110, -150, -30); // Map value to angle
194 | // Calcualte tip of needle coords
195 | float sx = cos(sdeg * 0.0174532925);
196 | float sy = sin(sdeg * 0.0174532925);
197 |
198 | // Calculate x delta of needle start (does not start at pivot point)
199 | float tx = tan((sdeg + 90) * 0.0174532925);
200 |
201 | // Erase old needle image
202 | tft.drawLine(M_SIZE*(120 + 20 * ltx - 1), M_SIZE*(140 - 20), osx - 1, osy, TFT_WHITE);
203 | tft.drawLine(M_SIZE*(120 + 20 * ltx), M_SIZE*(140 - 20), osx, osy, TFT_WHITE);
204 | tft.drawLine(M_SIZE*(120 + 20 * ltx + 1), M_SIZE*(140 - 20), osx + 1, osy, TFT_WHITE);
205 |
206 | // Re-plot text under needle
207 | tft.setTextColor(TFT_BLACK);
208 | tft.setFont(&FreeMonoBold24pt7b);
209 | _drawString("%RH", M_SIZE*80, M_SIZE*100, 1); // // Comment out to avoid font 4
210 | tft.setFont();
211 | //tft.drawCentreString("%RH", M_SIZE*120, M_SIZE*70, 4); // // Comment out to avoid font 4
212 |
213 | // Store new needle end coords for next erase
214 | ltx = tx;
215 | osx = M_SIZE*(sx * 98 + 120);
216 | osy = M_SIZE*(sy * 98 + 140);
217 |
218 | // Draw the needle in the new postion, magenta makes needle a bit bolder
219 | // draws 3 lines to thicken needle
220 | tft.drawLine(M_SIZE*(120 + 20 * ltx - 1), M_SIZE*(140 - 20), osx - 1, osy, TFT_RED);
221 | tft.drawLine(M_SIZE*(120 + 20 * ltx), M_SIZE*(140 - 20), osx, osy, TFT_MAGENTA);
222 | tft.drawLine(M_SIZE*(120 + 20 * ltx + 1), M_SIZE*(140 - 20), osx + 1, osy, TFT_RED);
223 |
224 | // Slow needle down slightly as it approaches new postion
225 | if (abs(old_analog - value) < 10) ms_delay += ms_delay / 5;
226 |
227 | // Wait before next update
228 | delay(ms_delay);
229 | }
230 | }
231 |
232 | void _drawString(char *buf, int16_t x, int16_t y, int16_t size)
233 | {
234 | tft.setTextSize(size);
235 | tft.setCursor(x, y);
236 | tft.print(buf);
237 | }
238 |
--------------------------------------------------------------------------------
/examples/TFT_Meters_STM32/TFT_Meters_STM32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for Arduino_Core_STM32
3 | *
4 | * Demo based on:
5 | * TFT_Meters by Bodmar
6 | * web: https://github.com/Bodmer/TFT_eSPI/tree/master/examples/320%20x%20240/TFT_Meters
7 | *
8 | */
9 |
10 |
11 | #include
12 | #include
13 | #include "Arduino-STM32-8bitTFT.h"
14 |
15 | STM32_TFT_8bit tft;
16 |
17 | #define TFT_GREY GRAY
18 | #define TFT_BLACK BLACK
19 | #define TFT_WHITE WHITE
20 | #define TFT_GREEN GREEN
21 | #define TFT_ORANGE ORANGE
22 | #define TFT_RED RED
23 | #define TFT_CYAN CYAN
24 | #define TFT_MAGENTA MAGENTA
25 |
26 | #define LOOP_PERIOD 35 // Display updates every 35 ms
27 |
28 | float ltx = 0; // Saved x coord of bottom of needle
29 | uint16_t osx = 120, osy = 120; // Saved x & y coords
30 | uint32_t updateTime = 0; // time for next update
31 | int16_t LinearY = 150;
32 |
33 | int old_analog = -999; // Value last displayed
34 | int old_digital = -999; // Value last displayed
35 |
36 | int value[6] = {0, 0, 0, 0, 0, 0};
37 | int old_value[6] = { -1, -1, -1, -1, -1, -1};
38 | int d = 0;
39 |
40 | void setup(void) {
41 | delay(1000);
42 | Serial.begin(115200);
43 | uint32_t ID = tft.readID();
44 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
45 | tft.begin(ID);
46 | tft.setRotation(0);
47 | Serial.begin(57600); // For debug
48 | tft.fillScreen(TFT_BLACK);
49 |
50 | analogMeter(); // Draw analogue meter
51 |
52 | // Draw 6 linear meters
53 | byte d = 40;
54 | plotLinear("A0", 0, LinearY);
55 | plotLinear("A1", 1 * d, LinearY);
56 | plotLinear("A2", 2 * d, LinearY);
57 | plotLinear("A3", 3 * d, LinearY);
58 | plotLinear("A4", 4 * d, LinearY);
59 | plotLinear("A5", 5 * d, LinearY);
60 |
61 | updateTime = millis(); // Next update time
62 | }
63 |
64 |
65 | void loop() {
66 | if (updateTime <= millis()) {
67 | updateTime = millis() + LOOP_PERIOD;
68 |
69 | d += 4; if (d >= 360) d = 0;
70 |
71 | //value[0] = map(analogRead(A0), 0, 1023, 0, 100); // Test with value form Analogue 0
72 |
73 | // Create a Sine wave for testing
74 | value[0] = 50 + 50 * sin((d + 0) * 0.0174532925);
75 | value[1] = 50 + 50 * sin((d + 60) * 0.0174532925);
76 | value[2] = 50 + 50 * sin((d + 120) * 0.0174532925);
77 | value[3] = 50 + 50 * sin((d + 180) * 0.0174532925);
78 | value[4] = 50 + 50 * sin((d + 240) * 0.0174532925);
79 | value[5] = 50 + 50 * sin((d + 300) * 0.0174532925);
80 |
81 | //unsigned long t = millis();
82 |
83 | plotPointer(LinearY);
84 |
85 | plotNeedle(value[0], 0);
86 |
87 | //Serial.println(millis()-t); // Print time taken for meter update
88 | }
89 | }
90 |
91 |
92 | // #########################################################################
93 | // Draw the analogue meter on the screen
94 | // #########################################################################
95 | void analogMeter()
96 | {
97 | // Meter outline
98 | tft.fillRect(0, 0, 239, 126, TFT_GREY);
99 | tft.fillRect(5, 3, 230, 119, TFT_WHITE);
100 |
101 | tft.setTextColor(TFT_BLACK); // Text colour
102 |
103 | // Draw ticks every 5 degrees from -50 to +50 degrees (100 deg. FSD swing)
104 | for (int i = -50; i < 51; i += 5) {
105 | // Long scale tick length
106 | int tl = 15;
107 |
108 | // Coodinates of tick to draw
109 | float sx = cos((i - 90) * 0.0174532925);
110 | float sy = sin((i - 90) * 0.0174532925);
111 | uint16_t x0 = sx * (100 + tl) + 120;
112 | uint16_t y0 = sy * (100 + tl) + 140;
113 | uint16_t x1 = sx * 100 + 120;
114 | uint16_t y1 = sy * 100 + 140;
115 |
116 | // Coordinates of next tick for zone fill
117 | float sx2 = cos((i + 5 - 90) * 0.0174532925);
118 | float sy2 = sin((i + 5 - 90) * 0.0174532925);
119 | int x2 = sx2 * (100 + tl) + 120;
120 | int y2 = sy2 * (100 + tl) + 140;
121 | int x3 = sx2 * 100 + 120;
122 | int y3 = sy2 * 100 + 140;
123 |
124 | // Yellow zone limits
125 | //if (i >= -50 && i < 0) {
126 | // tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_YELLOW);
127 | // tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_YELLOW);
128 | //}
129 |
130 | // Green zone limits
131 | if (i >= 0 && i < 25) {
132 | tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_GREEN);
133 | tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREEN);
134 | }
135 |
136 | // Orange zone limits
137 | if (i >= 25 && i < 50) {
138 | tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_ORANGE);
139 | tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_ORANGE);
140 | }
141 |
142 | // Short scale tick length
143 | if (i % 25 != 0) tl = 8;
144 |
145 | // Recalculate coords incase tick lenght changed
146 | x0 = sx * (100 + tl) + 120;
147 | y0 = sy * (100 + tl) + 140;
148 | x1 = sx * 100 + 120;
149 | y1 = sy * 100 + 140;
150 |
151 | // Draw tick
152 | tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
153 |
154 | // Check if labels should be drawn, with position tweaks
155 | if (i % 25 == 0) {
156 | // Calculate label positions
157 | x0 = sx * (100 + tl + 10) + 120;
158 | y0 = sy * (100 + tl + 10) + 140;
159 | switch (i / 25) {
160 | #if 0
161 | case -2: tft.drawCentreString("0", x0, y0 - 12, 2); break;
162 | case -1: tft.drawCentreString("25", x0, y0 - 9, 2); break;
163 | case 0: tft.drawCentreString("50", x0, y0 - 6, 2); break;
164 | case 1: tft.drawCentreString("75", x0, y0 - 9, 2); break;
165 | case 2: tft.drawCentreString("100", x0, y0 - 12, 2); break;
166 | #endif
167 | case -2: _drawString("0", x0-10, y0 - 12, 2); break;
168 | case -1: _drawString("25", x0-10, y0 - 9, 2); break;
169 | case 0: _drawString("50", x0-10, y0 - 6, 2); break;
170 | case 1: _drawString("75", x0-10, y0 - 9, 2); break;
171 | case 2: _drawString("100", x0-15, y0 - 12, 2); break;
172 | }
173 | }
174 |
175 | // Now draw the arc of the scale
176 | sx = cos((i + 5 - 90) * 0.0174532925);
177 | sy = sin((i + 5 - 90) * 0.0174532925);
178 | x0 = sx * 100 + 120;
179 | y0 = sy * 100 + 140;
180 | // Draw scale arc, don't draw the last part
181 | if (i < 50) tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
182 | }
183 |
184 | _drawString("%RH", 5 + 230 - 40, 119 - 20, 2); // Units at bottom right
185 | //tft.drawString("%RH", 5 + 230 - 40, 119 - 20, 2); // Units at bottom right
186 | //tft.drawCentreString("%RH", 120, 70, 4); // Comment out to avoid font 4
187 | tft.drawRect(5, 3, 230, 119, TFT_BLACK); // Draw bezel line
188 |
189 | plotNeedle(0, 0); // Put meter needle at 0
190 | }
191 |
192 | // #########################################################################
193 | // Update needle position
194 | // This function is blocking while needle moves, time depends on ms_delay
195 | // 10ms minimises needle flicker if text is drawn within needle sweep area
196 | // Smaller values OK if text not in sweep area, zero for instant movement but
197 | // does not look realistic... (note: 100 increments for full scale deflection)
198 | // #########################################################################
199 | void plotNeedle(int value, byte ms_delay)
200 | {
201 | tft.setTextColor(TFT_BLACK, TFT_WHITE);
202 | char buf[8]; dtostrf(value, 3, 0, buf);
203 | _drawString(buf, 10, 119 - 20, 2);
204 | //tft.drawRightString(buf, 40, 119 - 20, 2);
205 |
206 | if (value < -10) value = -10; // Limit value to emulate needle end stops
207 | if (value > 110) value = 110;
208 |
209 | // Move the needle util new value reached
210 | while (!(value == old_analog)) {
211 | if (old_analog < value) old_analog++;
212 | else old_analog--;
213 |
214 | if (ms_delay == 0) old_analog = value; // Update immediately id delay is 0
215 |
216 | float sdeg = map(old_analog, -10, 110, -150, -30); // Map value to angle
217 | // Calcualte tip of needle coords
218 | float sx = cos(sdeg * 0.0174532925);
219 | float sy = sin(sdeg * 0.0174532925);
220 |
221 | // Calculate x delta of needle start (does not start at pivot point)
222 | float tx = tan((sdeg + 90) * 0.0174532925);
223 |
224 | // Erase old needle image
225 | tft.drawLine(120 + 20 * ltx - 1, 140 - 20, osx - 1, osy, TFT_WHITE);
226 | tft.drawLine(120 + 20 * ltx, 140 - 20, osx, osy, TFT_WHITE);
227 | tft.drawLine(120 + 20 * ltx + 1, 140 - 20, osx + 1, osy, TFT_WHITE);
228 |
229 | // Re-plot text under needle
230 | tft.setTextColor(TFT_BLACK);
231 | tft.setFont(&FreeMonoBold18pt7b);
232 | _drawString("%RH", 80, 100, 1); // // Comment out to avoid font 4
233 | tft.setFont();
234 | //tft.drawCentreString("%RH", 120, 70, 4); // // Comment out to avoid font 4
235 |
236 | // Store new needle end coords for next erase
237 | ltx = tx;
238 | osx = sx * 98 + 120;
239 | osy = sy * 98 + 140;
240 |
241 | // Draw the needle in the new postion, magenta makes needle a bit bolder
242 | // draws 3 lines to thicken needle
243 | tft.drawLine(120 + 20 * ltx - 1, 140 - 20, osx - 1, osy, TFT_RED);
244 | tft.drawLine(120 + 20 * ltx, 140 - 20, osx, osy, TFT_MAGENTA);
245 | tft.drawLine(120 + 20 * ltx + 1, 140 - 20, osx + 1, osy, TFT_RED);
246 |
247 | // Slow needle down slightly as it approaches new postion
248 | if (abs(old_analog - value) < 10) ms_delay += ms_delay / 5;
249 |
250 | // Wait before next update
251 | delay(ms_delay);
252 | }
253 | }
254 |
255 | // #########################################################################
256 | // Draw a linear meter on the screen
257 | // #########################################################################
258 | void plotLinear(char *label, int x, int y)
259 | {
260 | int w = 36;
261 | tft.drawRect(x, y, w, 155, TFT_GREY);
262 | tft.fillRect(x + 2, y + 19, w - 3, 155 - 38, TFT_WHITE);
263 | tft.setTextColor(TFT_CYAN, TFT_BLACK);
264 | _drawString(label, (x + w / 2) - 10, y + 2, 2);
265 | //tft.drawCentreString(label, x + w / 2, y + 2, 2);
266 |
267 | for (int i = 0; i < 110; i += 10)
268 | {
269 | tft.drawFastHLine(x + 20, y + 27 + i, 6, TFT_BLACK);
270 | }
271 |
272 | for (int i = 0; i < 110; i += 50)
273 | {
274 | tft.drawFastHLine(x + 20, y + 27 + i, 9, TFT_BLACK);
275 | }
276 |
277 | tft.fillTriangle(x + 3, y + 127, x + 3 + 16, y + 127, x + 3, y + 127 - 5, TFT_RED);
278 | tft.fillTriangle(x + 3, y + 127, x + 3 + 16, y + 127, x + 3, y + 127 + 5, TFT_RED);
279 |
280 | //_drawString("---", (x + w / 2) - 18, y + 155 - 18, 2);
281 | //tft.drawCentreString("---", x + w / 2, y + 155 - 18, 2);
282 | }
283 |
284 | // #########################################################################
285 | // Adjust 6 linear meter pointer positions
286 | // #########################################################################
287 | void plotPointer(int y)
288 | {
289 | // int dy0 = 187;
290 | int dy0 = y + 27;
291 | byte pw = 16;
292 |
293 | tft.setTextColor(TFT_GREEN, TFT_BLACK);
294 |
295 | // Move the 6 pointers one pixel towards new value
296 | for (int i = 0; i < 6; i++)
297 | {
298 | char buf[8]; dtostrf(value[i], 3, 0, buf);
299 | // _drawString(buf, (i * 40 + 36 - 5) - 50, 187 - 27 + 155 - 18, 2);
300 | _drawString(buf, (i * 40 + 36 - 5) - 35, y + 137, 2);
301 | //tft.drawRightString(buf, i * 40 + 36 - 5, 187 - 27 + 155 - 18, 2);
302 |
303 | int dx = 3 + 40 * i;
304 | if (value[i] < 0) value[i] = 0; // Limit value to emulate needle end stops
305 | if (value[i] > 100) value[i] = 100;
306 |
307 | int dy;
308 | while (!(value[i] == old_value[i])) {
309 | //dy = 187 + 100 - old_value[i];
310 | dy = dy0 + 100 - old_value[i];
311 | if (old_value[i] > value[i])
312 | {
313 | tft.drawLine(dx, dy - 5, dx + pw, dy, TFT_WHITE);
314 | old_value[i]--;
315 | tft.drawLine(dx, dy + 6, dx + pw, dy + 1, TFT_RED);
316 | }
317 | else
318 | {
319 | tft.drawLine(dx, dy + 5, dx + pw, dy, TFT_WHITE);
320 | old_value[i]++;
321 | tft.drawLine(dx, dy - 6, dx + pw, dy - 1, TFT_RED);
322 | }
323 | }
324 | }
325 | }
326 |
327 | void _drawString(char *buf, int16_t x, int16_t y, int16_t size)
328 | {
329 | tft.setTextSize(size);
330 | tft.setCursor(x, y);
331 | tft.print(buf);
332 | }
333 |
--------------------------------------------------------------------------------
/examples/TFT_Pong_STM32/TFT_Pong_STM32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for Arduino_Core_STM32
3 | *
4 | * Pong
5 | * Original Code from https://github.com/rparrett/pongclock
6 | *
7 | * Demo based on:
8 | * TFT_Pong by Bodmar
9 | * web: https://github.com/Bodmer/TFT_eSPI/tree/master/examples/320%20x%20240/TFT_Pong
10 | */
11 |
12 | // Demo only - not playable
13 |
14 | #include
15 | #include "Arduino-STM32-8bitTFT.h"
16 |
17 | STM32_TFT_8bit tft;
18 |
19 | int16_t h = 240;
20 | int16_t w = 320;
21 |
22 | int dly = 5;
23 |
24 | int16_t paddle_h = 30;
25 | int16_t paddle_w = 4;
26 |
27 | int16_t lpaddle_x = 0;
28 | int16_t rpaddle_x = w - paddle_w;
29 |
30 | int16_t lpaddle_y = 0;
31 | int16_t rpaddle_y = h - paddle_h;
32 |
33 | int16_t lpaddle_d = 1;
34 | int16_t rpaddle_d = -1;
35 |
36 | int16_t lpaddle_ball_t = w - w / 4;
37 | int16_t rpaddle_ball_t = w / 4;
38 |
39 | int16_t target_y = 0;
40 |
41 | int16_t ball_x = 2;
42 | int16_t ball_y = 2;
43 | int16_t oldball_x = 2;
44 | int16_t oldball_y = 2;
45 |
46 | int16_t ball_dx = 1;
47 | int16_t ball_dy = 1;
48 |
49 | int16_t ball_w = 6;
50 | int16_t ball_h = 6;
51 |
52 | int16_t dashline_h = 4;
53 | int16_t dashline_w = 2;
54 | int16_t dashline_n = h / dashline_h;
55 | int16_t dashline_x = w / 2 - 1;
56 | int16_t dashline_y = dashline_h / 2;
57 |
58 | int16_t lscore = 12;
59 | int16_t rscore = 4;
60 |
61 | void setup(void) {
62 |
63 | //randomSeed(analogRead(0)*analogRead(1));
64 |
65 | delay(1000);
66 | Serial.begin(115200);
67 | uint32_t ID = tft.readID();
68 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
69 | tft.begin(ID);
70 |
71 | tft.setRotation(1);
72 |
73 | tft.fillScreen(BLACK);
74 | //tft.fillScreen(GREY);
75 |
76 | initgame();
77 |
78 | tft.setTextColor(WHITE, BLACK);
79 |
80 | }
81 |
82 | void loop() {
83 | delay(dly);
84 |
85 | lpaddle();
86 | rpaddle();
87 |
88 | midline();
89 |
90 | ball();
91 | }
92 |
93 | void initgame() {
94 | lpaddle_y = random(0, h - paddle_h);
95 | rpaddle_y = random(0, h - paddle_h);
96 |
97 | // ball is placed on the center of the left paddle
98 | ball_y = lpaddle_y + (paddle_h / 2);
99 |
100 | calc_target_y();
101 |
102 | midline();
103 |
104 | tft.fillRect(0,h-26,w,239,GRAY);
105 | //tft.setTextDatum(TC_DATUM);
106 | tft.setTextColor(WHITE,GRAY);
107 | _drawString("STM32 example", 05, h-26 , 4);
108 | //tft.drawString("TFT_eSPI example", w/2, h-26 , 4);
109 | }
110 |
111 | void midline() {
112 |
113 | // If the ball is not on the line then don't redraw the line
114 | if ((ball_x dashline_x+dashline_w)) return;
115 |
116 | // Quick way to draw a dashed line
117 | for(int16_t i = 0; i < w; i+=10) {
118 | tft.drawFastVLine(dashline_x,i,5,WHITE);
119 | }
120 | //tft.setWindow(dashline_x,0,dashline_x+dashline_w-1,h);
121 |
122 | for(int16_t i = 0; i < dashline_n; i+=2) {
123 | //tft.pushColor(WHITE, dashline_w*dashline_h); // push dash pixels
124 | //tft.pushColor(BLACK, dashline_w*dashline_h); // push gap pixels
125 | }
126 | }
127 |
128 | void lpaddle() {
129 |
130 | if (lpaddle_d == 1) {
131 | tft.fillRect(lpaddle_x, lpaddle_y, paddle_w, 1, BLACK);
132 | }
133 | else if (lpaddle_d == -1) {
134 | tft.fillRect(lpaddle_x, lpaddle_y + paddle_h - 1, paddle_w, 1, BLACK);
135 | }
136 |
137 | lpaddle_y = lpaddle_y + lpaddle_d;
138 |
139 | if (ball_dx == 1) lpaddle_d = 0;
140 | else {
141 | if (lpaddle_y + paddle_h / 2 == target_y) lpaddle_d = 0;
142 | else if (lpaddle_y + paddle_h / 2 > target_y) lpaddle_d = -1;
143 | else lpaddle_d = 1;
144 | }
145 |
146 | if (lpaddle_y + paddle_h >= h && lpaddle_d == 1) lpaddle_d = 0;
147 | else if (lpaddle_y <= 0 && lpaddle_d == -1) lpaddle_d = 0;
148 |
149 | tft.fillRect(lpaddle_x, lpaddle_y, paddle_w, paddle_h, CYAN);
150 | }
151 |
152 | void rpaddle() {
153 |
154 | if (rpaddle_d == 1) {
155 | tft.fillRect(rpaddle_x, rpaddle_y, paddle_w, 1, BLACK);
156 | }
157 | else if (rpaddle_d == -1) {
158 | tft.fillRect(rpaddle_x, rpaddle_y + paddle_h - 1, paddle_w, 1, BLACK);
159 | }
160 |
161 | rpaddle_y = rpaddle_y + rpaddle_d;
162 |
163 | if (ball_dx == -1) rpaddle_d = 0;
164 | else {
165 | if (rpaddle_y + paddle_h / 2 == target_y) rpaddle_d = 0;
166 | else if (rpaddle_y + paddle_h / 2 > target_y) rpaddle_d = -1;
167 | else rpaddle_d = 1;
168 | }
169 |
170 | if (rpaddle_y + paddle_h >= h && rpaddle_d == 1) rpaddle_d = 0;
171 | else if (rpaddle_y <= 0 && rpaddle_d == -1) rpaddle_d = 0;
172 |
173 | tft.fillRect(rpaddle_x, rpaddle_y, paddle_w, paddle_h, YELLOW);
174 | }
175 |
176 | void calc_target_y() {
177 | int16_t target_x;
178 | int16_t reflections;
179 | int16_t y;
180 |
181 | if (ball_dx == 1) {
182 | target_x = w - ball_w;
183 | }
184 | else {
185 | target_x = -1 * (w - ball_w);
186 | }
187 |
188 | y = abs(target_x * (ball_dy / ball_dx) + ball_y);
189 |
190 | reflections = floor(y / h);
191 |
192 | if (reflections % 2 == 0) {
193 | target_y = y % h;
194 | }
195 | else {
196 | target_y = h - (y % h);
197 | }
198 | }
199 |
200 | void ball() {
201 | ball_x = ball_x + ball_dx;
202 | ball_y = ball_y + ball_dy;
203 |
204 | if (ball_dx == -1 && ball_x == paddle_w && ball_y + ball_h >= lpaddle_y && ball_y <= lpaddle_y + paddle_h) {
205 | ball_dx = ball_dx * -1;
206 | dly = random(5); // change speed of ball after paddle contact
207 | calc_target_y();
208 | } else if (ball_dx == 1 && ball_x + ball_w == w - paddle_w && ball_y + ball_h >= rpaddle_y && ball_y <= rpaddle_y + paddle_h) {
209 | ball_dx = ball_dx * -1;
210 | dly = random(5); // change speed of ball after paddle contact
211 | calc_target_y();
212 | } else if ((ball_dx == 1 && ball_x >= w) || (ball_dx == -1 && ball_x + ball_w < 0)) {
213 | dly = 5;
214 | }
215 |
216 | if (ball_y > h - ball_w || ball_y < 0) {
217 | ball_dy = ball_dy * -1;
218 | ball_y += ball_dy; // Keep in bounds
219 | }
220 |
221 | //tft.fillRect(oldball_x, oldball_y, ball_w, ball_h, BLACK);
222 | tft.drawRect(oldball_x, oldball_y, ball_w, ball_h, BLACK); // Less TFT refresh aliasing than line above for large balls
223 | tft.fillRect( ball_x, ball_y, ball_w, ball_h, RED);
224 | oldball_x = ball_x;
225 | oldball_y = ball_y;
226 | }
227 |
228 | void _drawString(char *buf, int16_t x, int16_t y, int16_t size)
229 | {
230 | tft.setTextSize(size);
231 | tft.setCursor(x, y);
232 | tft.print(buf);
233 | }
234 |
--------------------------------------------------------------------------------
/examples/UTFT_demo_STM32/UTFT_demo_STM32.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * 8bit TFT Library for Arduino_Core_STM32
3 | *
4 | * Demo based on:
5 | * UTFT_Demo_320x240 by Henning Karlsen
6 | * web: http://www.henningkarlsen.com/electronics
7 | *
8 | */
9 |
10 | #include
11 | #include "Arduino-STM32-8bitTFT.h"
12 |
13 | STM32_TFT_8bit myGLCD;
14 |
15 |
16 | #define TFT_GREY GRAY
17 | #define TFT_BLACK BLACK
18 | #define TFT_RED RED
19 | #define TFT_CYAN CYAN
20 | #define TFT_YELLOW YELLOW
21 | #define TFT_BLUE BLUE
22 |
23 | int sbuf[318];
24 | int cbuf[318];
25 |
26 | void setup()
27 | {
28 | delay(1000);
29 | Serial.begin(115200);
30 | uint32_t ID = myGLCD.readID();
31 | Serial.print("Device ID: 0x"); Serial.println(ID, HEX);
32 | myGLCD.begin(ID);
33 |
34 | uint32_t width = myGLCD.width();
35 | Serial.print("Width: "); Serial.println(width);
36 | uint32_t height = myGLCD.height();
37 | Serial.print("Height: "); Serial.println(height);
38 |
39 | int buf[318];
40 |
41 | // Clear the screen and draw the frame
42 | myGLCD.setRotation(3);
43 | myGLCD.setFont();
44 | myGLCD.setTextSize(1);
45 |
46 | myGLCD.fillScreen(TFT_BLACK);
47 | myGLCD.fillRect(0, 0, 319, 14,TFT_RED);
48 | myGLCD.fillRect(0, 226, 319, 14,TFT_GREY);
49 |
50 | myGLCD.setTextColor(TFT_BLACK,TFT_RED);
51 | myGLCD.setCursor(100, 4);
52 | myGLCD.print("* STM32_TFT_8bit *");
53 | myGLCD.setTextColor(TFT_YELLOW,TFT_GREY);
54 | myGLCD.setCursor(100, 230);
55 | myGLCD.print("Adapted by nopnop2002");
56 |
57 | myGLCD.drawRect(0, 14, 319, 211, TFT_BLUE);
58 |
59 | // Draw crosshairs
60 | myGLCD.drawLine(159, 15, 159, 224,TFT_BLUE);
61 | myGLCD.drawLine(1, 119, 318, 119,TFT_BLUE);
62 | for (int i=9; i<310; i+=10)
63 | myGLCD.drawLine(i, 117, i, 121,TFT_BLUE);
64 | for (int i=19; i<220; i+=10)
65 | myGLCD.drawLine(157, i, 161, i,TFT_BLUE);
66 |
67 | // Draw sin-lines, cos-lines
68 | myGLCD.setTextColor(TFT_CYAN);
69 | _drawString("Sin", 5, 15,2);
70 | for (int i=1; i<318; i=i+2)
71 | {
72 | sbuf[i-1] = 119+(sin(((i*1.13)*3.14)/180)*95);
73 | myGLCD.drawPixel(i,sbuf[i-1],TFT_CYAN);
74 | }
75 | myGLCD.setTextColor(TFT_RED);
76 | _drawString("Cos", 5, 30,2);
77 | for (int i=1; i<318; i=i+2)
78 | {
79 | cbuf[i-1] = 119+(cos(((i*1.13)*3.14)/180)*95);
80 | myGLCD.drawPixel(i,cbuf[i-1],TFT_YELLOW);
81 | }
82 |
83 | }
84 |
85 | void loop()
86 | {
87 | static int delta = 0;
88 |
89 | // Erase sin-lines, cos-lines
90 | for (int i=1; i<318; i=i+2)
91 | {
92 | myGLCD.drawPixel(i,sbuf[i-1],TFT_BLACK);
93 | }
94 | for (int i=1; i<318; i=i+2)
95 | {
96 | myGLCD.drawPixel(i,cbuf[i-1],TFT_BLACK);
97 | }
98 |
99 | // Draw sin-lines, cos-lines
100 | delta++;
101 | if (delta == 318) delta = 0;
102 | for (int i=1; i<318; i=i+2)
103 | {
104 | sbuf[i-1] = 119+(sin((((i+delta)*1.13)*3.14)/180)*95);
105 | myGLCD.drawPixel(i,sbuf[i-1],TFT_CYAN);
106 | }
107 | for (int i=1; i<318; i=i+2)
108 | {
109 | cbuf[i-1] = 119+(cos((((i+delta)*1.13)*3.14)/180)*95);
110 | myGLCD.drawPixel(i,cbuf[i-1],TFT_YELLOW);
111 | }
112 |
113 | myGLCD.setTextColor(TFT_CYAN);
114 | // myGLCD.drawString("Sin", 5, 15,2);
115 | _drawString("Sin", 5, 15,2);
116 | myGLCD.setTextColor(TFT_YELLOW);
117 | // myGLCD.drawString("Cos", 5, 30,2);
118 | _drawString("Cos", 5, 30,2);
119 | myGLCD.drawLine(159, 15, 159, 224,TFT_BLUE);
120 | myGLCD.drawLine(1, 119, 318, 119,TFT_BLUE);
121 | }
122 |
123 | void _drawString(char *buf, int16_t x, int16_t y, int16_t size)
124 | {
125 | myGLCD.setTextSize(size);
126 | myGLCD.setCursor(x, y);
127 | myGLCD.print(buf);
128 | }
129 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=Arduino-STM32-8bitTFT
2 | version=1.0.0
3 | author=nopnop2002
4 | maintainer=nopnop2002
5 | sentence=TFT Library for mcufriend UNO Shields.
6 | paragraph=TFT Library for mcufriend UNO Shields. Must have /RD pin to be readable.
7 | category=Display
8 | url=https://github.com/nopnop2002/Arduino-STM32-8bitTFT
9 | architectures=*
10 |
--------------------------------------------------------------------------------