├── 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 | ![TFT-SHIELD-2](https://user-images.githubusercontent.com/6020549/77811736-c0082a80-70df-11ea-861e-d2117e2718a0.JPG) 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 | ![r61505](https://user-images.githubusercontent.com/6020549/34552852-70d1e6bc-f167-11e7-8df9-41587ebccc79.JPG) 187 | 188 | - STM32F103 + SPFD5408 2.4 inch TFT 189 | 190 | ![spfd5408](https://user-images.githubusercontent.com/6020549/34552862-7ae8d62e-f167-11e7-84dd-73b07476cd50.JPG) 191 | 192 | - STM32F103 + ILI9325 2.4 inch TFT 193 | 194 | ![ili9325](https://user-images.githubusercontent.com/6020549/34552868-848b0fd0-f167-11e7-92f1-9c07e741a33e.JPG) 195 | 196 | - STM32F103 + ILI9341 2.4 inch TFT 197 | 198 | ![ili9341](https://user-images.githubusercontent.com/6020549/34552875-8eb6c832-f167-11e7-9c8c-7e3e602887d3.JPG) 199 | 200 | - STM32F103 + ILI9342 2.4 inch TFT 201 | 202 | ![ili9342](https://user-images.githubusercontent.com/6020549/34552887-9aa02fb2-f167-11e7-8ca6-6517de127a4a.JPG) 203 | 204 | - STM32F401 + ILI9341 2.4 inch TFT 205 | 206 | ![STM32F401](https://user-images.githubusercontent.com/6020549/77814907-ce167500-70f8-11ea-8952-d6d1c1cc8801.JPG) 207 | 208 | - STM32F407 + ILI9341 2.4 inch TFT 209 | 210 | ![STM32F407](https://user-images.githubusercontent.com/6020549/77814593-a540b080-70f5-11ea-93c2-564f9bb0d817.JPG) 211 | 212 | - NUCLEO F446RE + ILI9341 2.4 inch TFT (Use PC0-PC7 for D0-D7) 213 | 214 | ![8bitTFT](https://user-images.githubusercontent.com/6020549/77814188-2ac26180-70f2-11ea-8080-9e3cac22ce5a.JPG) 215 | 216 | - STM32G431 + ILI9341 2.4 inch TFT (Use Serial remapping) 217 | 218 | ![STM32G431](https://github.com/nopnop2002/Arduino-STM32-8bitTFT/assets/6020549/3ff0df09-08d8-418a-a346-5b17dc0ef67b) 219 | 220 | - STM32H750 + ILI9341 2.4 inch TFT (Use PC0-PC7 for D0-D7) 221 | 222 | ![STM32H750](https://github.com/nopnop2002/Arduino-STM32-8bitTFT/assets/6020549/d61c0ed1-f251-464b-a680-735ffa685785) 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 | --------------------------------------------------------------------------------