├── Eve2_81x.c ├── Eve2_81x.h ├── MatrixEve2Conf.h ├── README.md ├── basic_eve_demo.c ├── hw_api.h ├── license.txt └── touch_cap_811.h /Eve2_81x.c: -------------------------------------------------------------------------------- 1 | // Eve2 Processor Agnostic Library (Condensed) 2 | // 3 | // This "library" consists of the files "Eve2_81x.c" and "Eve2_81x.h". 4 | // 5 | // In persuit of the common goal of simplicity and understandability I find that I am unable to 6 | // make function prototypes that match Bridgetek example code. I draw the line between the 7 | // Eve and all other hardware. The library is "clean" and includes no abstraction at all, unlike 8 | // much of the example code on the Internet which is sort of application and abstraction mixed 9 | // together in a confusing abuse of my eye-holes. 10 | // My intent is to be as straight forward and understandable as possible, so while function 11 | // names and parameter lists are different than Bridgetek code examples, they should be easily 12 | // recognizable. I have also made every attempt to reference Bridgetek documentation against 13 | // the code to act as a translation to help in understanding. 14 | 15 | // Notes on the operation of the Eve command processing engine - THE FIFO 16 | // 17 | // First be aware that the FTDI documentation variously refers to you as "User", "MCU", "Host". 18 | // 19 | // The FIFO, like all FIFO's needs pointers to indicate the starting address of buffered data and 20 | // the end address of buffered data. There is wrapping involved, but the basic idea is clear. 21 | // Eve takes data into it's FIFO using a fully defined write operation to a memory address - that 22 | // is, you need to take care of the wrapping - to you, it is not a FIFO - it is a piece of memory. 23 | // Eve keeps track of it's own read address location, but relies on you to write the address 24 | // of the end of buffered data. 25 | // 26 | // So as commands are loaded into RAM - into the FIFO space - Eve will do nothing in response. 27 | // Eve is happy to take your data and store it for you while it sits with it's read address and 28 | // write address set to the same value. Once the commands are loaded, the next available address 29 | // is manually written (by you) to the register in which Eve stores the FIFO write pointer 30 | // (REG_CMD_WRITE). 31 | // 32 | // Following this, Eve discovers that the addresses are different and begins processing commands while 33 | // updating it's own read pointer until the read and write pointers are the same. 34 | // 35 | // Be aware that Eve stores only the offset into the "FIFO" as 16 bits, so any use of the offset 36 | // requires adding the base address (RAM_CMD 0x308000) to the resultant 32 bit value. 37 | 38 | #include 39 | #include // Find integer types like "uint8_t" 40 | #include // for true/false 41 | #include "Eve2_81x.h" // Header for this file with prototypes, defines, and typedefs 42 | #include "MatrixEve2Conf.h" // Header for display selection 43 | #include "hw_api.h" // for spi abstraction 44 | 45 | #define WorkBuffSz 512 46 | #define Log printf 47 | 48 | // Global Variables 49 | uint16_t FifoWriteLocation = 0; 50 | char LogBuf[WorkBuffSz]; // The singular universal data array used for all things including logging 51 | 52 | static uint32_t Width; 53 | static uint32_t Height; 54 | static uint32_t HOffset; 55 | static uint32_t VOffset; 56 | static uint8_t Touch; 57 | 58 | uint32_t Display_Width() 59 | { 60 | return Width; 61 | } 62 | 63 | uint32_t Display_Height() 64 | { 65 | return Height; 66 | } 67 | 68 | uint8_t Display_Touch() 69 | { 70 | return Touch; 71 | } 72 | 73 | uint32_t Display_HOffset() 74 | { 75 | return HOffset; 76 | } 77 | uint32_t Display_VOffset() 78 | { 79 | return VOffset; 80 | } 81 | 82 | 83 | 84 | 85 | // Call this function once at powerup to reset and initialize the Eve chip 86 | int FT81x_Init(int display, int board, int touch) 87 | { 88 | uint32_t Ready = false; 89 | int DWIDTH; 90 | int DHEIGHT; 91 | int PIXVOFFSET; 92 | int PIXHOFFSET; 93 | int HCYCLE; 94 | int HOFFSET; 95 | int HSYNC0; 96 | int HSYNC1; 97 | int VCYCLE; 98 | int VOFFSET; 99 | int VSYNC0; 100 | int VSYNC1; 101 | int PCLK; 102 | int SWIZZLE; 103 | int PCLK_POL; 104 | int HSIZE; 105 | int VSIZE; 106 | int CSPREAD; 107 | int DITHER; 108 | 109 | switch (display) 110 | { 111 | case DISPLAY_70: 112 | DWIDTH = 800; 113 | DHEIGHT = 480; 114 | PIXVOFFSET = 0; 115 | PIXHOFFSET = 0; 116 | HCYCLE = 928; 117 | HOFFSET = 88; 118 | HSYNC0 = 0; 119 | HSYNC1 = 48; 120 | VCYCLE = 525; 121 | VOFFSET = 32; 122 | VSYNC0 = 0; 123 | VSYNC1 = 3; 124 | PCLK = 2; 125 | SWIZZLE = 0; 126 | PCLK_POL = 1; 127 | HSIZE = 800; 128 | VSIZE = 480; 129 | CSPREAD = 0; 130 | DITHER = 1; 131 | break; 132 | case DISPLAY_50: 133 | DWIDTH = 800; 134 | DHEIGHT = 480; 135 | PIXVOFFSET = 0; 136 | PIXHOFFSET = 0; 137 | HCYCLE = 928; 138 | HOFFSET = 88; 139 | HSYNC0 = 0; 140 | HSYNC1 = 48; 141 | VCYCLE = 525; 142 | VOFFSET = 32; 143 | VSYNC0 = 0; 144 | VSYNC1 = 3; 145 | PCLK = 2; 146 | SWIZZLE = 0; 147 | PCLK_POL = 1; 148 | HSIZE = 800; 149 | VSIZE = 480; 150 | CSPREAD = 0; 151 | DITHER = 1; 152 | break; 153 | case DISPLAY_43: 154 | DWIDTH = 480; 155 | DHEIGHT = 272; 156 | PIXVOFFSET = 0; 157 | PIXHOFFSET = 0; 158 | HCYCLE = 548; 159 | HOFFSET = 43; 160 | HSYNC0 = 0; 161 | HSYNC1 = 41; 162 | VCYCLE = 292; 163 | VOFFSET = 12; 164 | VSYNC0 = 0; 165 | VSYNC1 = 10; 166 | PCLK = 5; 167 | SWIZZLE = 0; 168 | PCLK_POL = 1; 169 | HSIZE = 480; 170 | VSIZE = 272; 171 | CSPREAD = 1; 172 | DITHER = 1; 173 | break; 174 | case DISPLAY_39: 175 | DWIDTH = 480; 176 | DHEIGHT = 128; 177 | PIXVOFFSET = 0; 178 | PIXHOFFSET = 0; 179 | HCYCLE = 524; 180 | HOFFSET = 16; 181 | HSYNC1 = 44; 182 | HSYNC0 = 0; 183 | VCYCLE = 288; 184 | VOFFSET = 12; 185 | VSYNC1 = 8; 186 | VSYNC0 = 7; 187 | PCLK = 5; 188 | SWIZZLE = 0; 189 | PCLK_POL = 1; 190 | HSIZE = 480; 191 | VSIZE = 272; 192 | CSPREAD = 1; 193 | DITHER = 1; 194 | break; 195 | case DISPLAY_38: 196 | DWIDTH = 480; 197 | DHEIGHT = 116; 198 | PIXVOFFSET = 10; 199 | PIXHOFFSET = 0; 200 | HCYCLE = 524; 201 | HOFFSET = 43; 202 | HSYNC0 = 0; 203 | HSYNC1 = 41; 204 | VCYCLE = 292; 205 | VOFFSET = 12; 206 | VSYNC0 = 152; 207 | VSYNC1 = 10; 208 | PCLK = 5; 209 | SWIZZLE = 0; 210 | PCLK_POL = 1; 211 | HSIZE = 480; 212 | VSIZE = 272; 213 | CSPREAD = 1; 214 | DITHER = 1; 215 | break; 216 | case DISPLAY_35: 217 | DWIDTH = 320; 218 | DHEIGHT = 240; 219 | PIXVOFFSET = 0; 220 | PIXHOFFSET = 0; 221 | HCYCLE = 408; 222 | HOFFSET = 68; 223 | HSYNC0 = 0; 224 | HSYNC1 = 10; 225 | VCYCLE = 262; 226 | VOFFSET = 18; 227 | VSYNC0 = 0; 228 | VSYNC1 = 2; 229 | PCLK = 8; 230 | SWIZZLE = 0; 231 | PCLK_POL = 0; 232 | HSIZE = 320; 233 | VSIZE = 240; 234 | CSPREAD = 1; 235 | DITHER = 1; 236 | break; 237 | case DISPLAY_29: 238 | DWIDTH = 320; 239 | DHEIGHT = 102; 240 | PIXVOFFSET = 0; 241 | PIXHOFFSET = 0; 242 | HCYCLE = 408; 243 | HOFFSET = 70; 244 | HSYNC0 = 0; 245 | HSYNC1 = 10; 246 | VCYCLE = 262; 247 | VOFFSET = 156; 248 | VSYNC0 = 0; 249 | VSYNC1 = 2; 250 | PCLK = 8; 251 | SWIZZLE = 0; 252 | PCLK_POL = 0; 253 | HSIZE = 320; 254 | VSIZE = 102; 255 | CSPREAD = 1; 256 | DITHER = 1; 257 | break; 258 | case DISPLAY_40: 259 | DWIDTH = 720; 260 | DHEIGHT = 720; 261 | PIXVOFFSET = 0; 262 | PIXHOFFSET = 0; 263 | HCYCLE = 812; 264 | HOFFSET = 91; 265 | HSYNC0 = 46; 266 | HSYNC1 = 48; 267 | VCYCLE = 756; 268 | VOFFSET = 35; 269 | VSYNC0 = 16; 270 | VSYNC1 = 18; 271 | PCLK = 2; 272 | SWIZZLE = 0; 273 | PCLK_POL = 1; 274 | HSIZE = 720; 275 | VSIZE = 720; 276 | CSPREAD = 0; 277 | DITHER = 0; 278 | break; 279 | case DISPLAY_101: 280 | DWIDTH = 1280; 281 | DHEIGHT = 800; 282 | PIXVOFFSET = 0; 283 | PIXHOFFSET = 0; 284 | HCYCLE = 1440; 285 | HOFFSET = 158; 286 | HSYNC0 = 78; 287 | HSYNC1 = 80; 288 | VCYCLE = 823; 289 | VOFFSET = 22; 290 | VSYNC0 = 11; 291 | VSYNC1 = 12; 292 | PCLK = 1; 293 | SWIZZLE = 0; 294 | PCLK_POL = 0; 295 | HSIZE = 1280; 296 | VSIZE = 800; 297 | CSPREAD = 0; 298 | DITHER = 1; 299 | break; 300 | default: 301 | printf("Unknown display type\n"); 302 | return 0; 303 | break; 304 | } 305 | Width = DWIDTH; 306 | Height = DHEIGHT; 307 | HOffset = PIXHOFFSET; 308 | VOffset = PIXVOFFSET; 309 | Touch = touch; 310 | Eve_Reset(); // Hard reset of the Eve chip 311 | 312 | // Wakeup Eve 313 | if (board >= BOARD_EVE3) 314 | { 315 | HostCommand(HCMD_CLKEXT); 316 | } 317 | HostCommand(HCMD_ACTIVE); 318 | HAL_Delay(300); 319 | 320 | do 321 | { 322 | Ready = Cmd_READ_REG_ID(); 323 | } while (!Ready); 324 | 325 | // Log("Eve now ACTIVE\n"); // 326 | 327 | Ready = rd32(REG_CHIP_ID); 328 | uint16_t ValH = Ready >> 16; 329 | uint16_t ValL = Ready & 0xFFFF; 330 | Log("Chip ID = 0x%04x%04x\n", ValH, ValL); 331 | 332 | 333 | if (display == DISPLAY_101) 334 | { 335 | wr32(REG_FREQUENCY + RAM_REG, 80000000); // Configure the system clock to 80MHz 336 | } 337 | else 338 | { 339 | wr32(REG_FREQUENCY + RAM_REG, 60000000); // Configure the system clock to 60MHz 340 | } 341 | // Before we go any further with Eve, it is a good idea to check to see if she is wigging out about something 342 | // that happened before the last reset. If Eve has just done a power cycle, this would be unnecessary. 343 | if (rd16(REG_CMD_READ + RAM_REG) == 0xFFF) 344 | { 345 | // Eve is unhappy - needs a paddling. 346 | uint32_t Patch_Add = rd32(REG_COPRO_PATCH_PTR + RAM_REG); 347 | wr8(REG_CPU_RESET + RAM_REG, 1); 348 | wr16(REG_CMD_READ + RAM_REG, 0); 349 | wr16(REG_CMD_WRITE + RAM_REG, 0); 350 | wr16(REG_CMD_DL + RAM_REG, 0); 351 | wr8(REG_CPU_RESET + RAM_REG, 0); 352 | wr32(REG_COPRO_PATCH_PTR + RAM_REG, Patch_Add); 353 | } 354 | 355 | // turn off screen output during startup 356 | wr8(REG_GPIOX + RAM_REG, 0); // Set REG_GPIOX to 0 to turn off the LCD DISP signal 357 | wr8(REG_PCLK + RAM_REG, 0); // Pixel Clock Output disable 358 | 359 | // load parameters of the physical screen to the Eve 360 | // All of these registers are 32 bits, but most bits are reserved, so only write what is actually used 361 | wr16(REG_HCYCLE + RAM_REG, HCYCLE); // Set H_Cycle to 548 362 | wr16(REG_HOFFSET + RAM_REG, HOFFSET); // Set H_Offset to 43 363 | wr16(REG_HSYNC0 + RAM_REG, HSYNC0); // Set H_SYNC_0 to 0 364 | wr16(REG_HSYNC1 + RAM_REG, HSYNC1); // Set H_SYNC_1 to 41 365 | wr16(REG_VCYCLE + RAM_REG, VCYCLE); // Set V_Cycle to 292 366 | wr16(REG_VOFFSET + RAM_REG, VOFFSET); // Set V_OFFSET to 12 367 | wr16(REG_VSYNC0 + RAM_REG, VSYNC0); // Set V_SYNC_0 to 0 368 | wr16(REG_VSYNC1 + RAM_REG, VSYNC1); // Set V_SYNC_1 to 10 369 | wr8(REG_SWIZZLE + RAM_REG, SWIZZLE); // Set SWIZZLE to 0 370 | wr8(REG_PCLK_POL + RAM_REG, PCLK_POL); // Set PCLK_POL to 1 371 | wr16(REG_HSIZE + RAM_REG, HSIZE); // Set H_SIZE to 480 372 | wr16(REG_VSIZE + RAM_REG, VSIZE); // Set V_SIZE to 272 373 | wr8(REG_CSPREAD + RAM_REG, CSPREAD); // Set CSPREAD to 1 (32 bit register - write only 8 bits) 374 | wr8(REG_DITHER + RAM_REG, DITHER); // Set DITHER to 1 (32 bit register - write only 8 bits) 375 | 376 | // configure touch & audio 377 | if (touch == TOUCH_TPR) 378 | { 379 | wr16(REG_TOUCH_CONFIG + RAM_REG, 0x8381); 380 | } 381 | else if (touch == TOUCH_TPC) 382 | { 383 | if (display == DISPLAY_40) 384 | wr16(REG_TOUCH_CONFIG + RAM_REG, 0x480); // FT6336U 385 | else 386 | wr16(REG_TOUCH_CONFIG + RAM_REG, 0x5d0); 387 | if (board == BOARD_EVE2) 388 | { 389 | Cap_Touch_Upload(); 390 | } 391 | } 392 | 393 | wr16(REG_TOUCH_RZTHRESH + RAM_REG, 1200); // set touch resistance threshold 394 | wr8(REG_TOUCH_MODE + RAM_REG, 0x02); // set touch on: continous - this is default 395 | wr8(REG_TOUCH_ADC_MODE + RAM_REG, 0x01); // set ADC mode: differential - this is default 396 | wr8(REG_TOUCH_OVERSAMPLE + RAM_REG, 15); // set touch oversampling to max 397 | 398 | wr16(REG_GPIOX_DIR + RAM_REG, 0x8000 | (1<<3)); // Set Disp GPIO Direction 399 | wr16(REG_GPIOX + RAM_REG, 0x8000 | (1<<3)); // Enable Disp (if used) 400 | 401 | wr16(REG_PWM_HZ + RAM_REG, 0x00FA); // Backlight PWM frequency 402 | wr8(REG_PWM_DUTY + RAM_REG, 128); // Backlight PWM duty (on) 403 | 404 | // write first display list (which is a clear and blank screen) 405 | wr32(RAM_DL+0, CLEAR_COLOR_RGB(0,0,0)); 406 | wr32(RAM_DL+4, CLEAR(1,1,1)); 407 | wr32(RAM_DL+8, DISPLAY()); 408 | wr8(REG_DLSWAP + RAM_REG, DLSWAP_FRAME); // swap display lists 409 | wr8(REG_PCLK + RAM_REG, PCLK); // after this display is visible on the LCD 410 | return 1; 411 | } 412 | 413 | // Reset Eve chip via the hardware PDN line 414 | void Eve_Reset(void) 415 | { 416 | HAL_Eve_Reset_HW(); 417 | } 418 | 419 | // Upload Goodix Calibration file 420 | void Cap_Touch_Upload(void) 421 | { 422 | #include "touch_cap_811.h" 423 | //---Goodix911 Configuration from AN336 424 | //Load the TOUCH_DATA_U8 or TOUCH_DATA_U32 array from file “touch_cap_811.h” via the FT81x command buffer RAM_CMD 425 | uint8_t CTOUCH_CONFIG_DATA_G911[] = { TOUCH_DATA_U8 }; 426 | CoProWrCmdBuf(CTOUCH_CONFIG_DATA_G911, TOUCH_DATA_LEN); 427 | //Execute the commands till completion 428 | UpdateFIFO(); 429 | Wait4CoProFIFOEmpty(); 430 | //Hold the touch engine in reset(write REG_CPURESET = 2) 431 | wr8(REG_CPU_RESET + RAM_REG, 2); 432 | //Set GPIO3 output LOW 433 | wr8(REG_GPIOX_DIR + RAM_REG, (rd8(RAM_REG + REG_GPIOX_DIR) | 0x08)); // Set Disp GPIO Direction 434 | wr8(REG_GPIOX + RAM_REG, (rd8(RAM_REG + REG_GPIOX) | 0xF7)); // Clear GPIO 435 | //Wait more than 100us 436 | HAL_Delay(1); 437 | //Write REG_CPURESET=0 438 | wr8(REG_CPU_RESET + RAM_REG, 0); 439 | //Wait more than 55ms 440 | HAL_Delay(100); 441 | //Set GPIO3 to input (floating) 442 | wr8(REG_GPIOX_DIR + RAM_REG, (rd8(RAM_REG + REG_GPIOX_DIR) & 0xF7)); // Set Disp GPIO Direction 443 | //---Goodix911 Configuration from AN336 444 | } 445 | 446 | // *** Host Command - FT81X Embedded Video Engine Datasheet - 4.1.5 ********************************************** 447 | // Host Command is a function for changing hardware related parameters of the Eve chip. The name is confusing. 448 | // These are related to power modes and the like. All defined parameters have HCMD_ prefix 449 | void HostCommand(uint8_t HCMD) 450 | { 451 | // Log("Inside HostCommand\n"); 452 | 453 | HAL_SPI_Enable(); 454 | 455 | /* HAL_SPI_Write(HCMD | 0x40); // In case the manual is making you believe that you just found the bug you were looking for - no. */ 456 | HAL_SPI_Write(HCMD); 457 | HAL_SPI_Write(0x00); // This second byte is set to 0 but if there is need for fancy, never used setups, then rewrite. 458 | HAL_SPI_Write(0x00); 459 | 460 | HAL_SPI_Disable(); 461 | } 462 | 463 | // *** Eve API Reference Definitions ***************************************************************************** 464 | // FT81X Embedded Video Engine Datasheet 1.3 - Section 4.1.4, page 16 465 | // These are all functions related to writing / reading data of various lengths with a memory address of 32 bits 466 | // *************************************************************************************************************** 467 | void wr32(uint32_t address, uint32_t parameter) 468 | { 469 | HAL_SPI_Enable(); 470 | 471 | HAL_SPI_Write((uint8_t)((address >> 16) | 0x80)); // RAM_REG = 0x302000 and high bit is set - result always 0xB0 472 | HAL_SPI_Write((uint8_t)(address >> 8)); // Next byte of the register address 473 | HAL_SPI_Write((uint8_t)address); // Low byte of register address - usually just the 1 byte offset 474 | 475 | HAL_SPI_Write((uint8_t)(parameter & 0xff)); // Little endian (yes, it is most significant bit first and least significant byte first) 476 | HAL_SPI_Write((uint8_t)((parameter >> 8) & 0xff)); 477 | HAL_SPI_Write((uint8_t)((parameter >> 16) & 0xff)); 478 | HAL_SPI_Write((uint8_t)((parameter >> 24) & 0xff)); 479 | 480 | HAL_SPI_Disable(); 481 | } 482 | 483 | void wr16(uint32_t address, uint16_t parameter) 484 | { 485 | HAL_SPI_Enable(); 486 | 487 | HAL_SPI_Write((uint8_t)((address >> 16) | 0x80)); // RAM_REG = 0x302000 and high bit is set - result always 0xB0 488 | HAL_SPI_Write((uint8_t)(address >> 8)); // Next byte of the register address 489 | HAL_SPI_Write((uint8_t)address); // Low byte of register address - usually just the 1 byte offset 490 | 491 | HAL_SPI_Write((uint8_t)(parameter & 0xff)); // Little endian (yes, it is most significant bit first and least significant byte first) 492 | HAL_SPI_Write((uint8_t)(parameter >> 8)); 493 | 494 | HAL_SPI_Disable(); 495 | } 496 | 497 | void wr8(uint32_t address, uint8_t parameter) 498 | { 499 | HAL_SPI_Enable(); 500 | 501 | HAL_SPI_Write((uint8_t)((address >> 16) | 0x80)); // RAM_REG = 0x302000 and high bit is set - result always 0xB0 502 | HAL_SPI_Write((uint8_t)(address >> 8)); // Next byte of the register address 503 | HAL_SPI_Write((uint8_t)(address)); // Low byte of register address - usually just the 1 byte offset 504 | 505 | HAL_SPI_Write(parameter); 506 | 507 | HAL_SPI_Disable(); 508 | } 509 | 510 | uint32_t rd32(uint32_t address) 511 | { 512 | uint8_t buf[4]; 513 | uint32_t Data32; 514 | 515 | HAL_SPI_Enable(); 516 | 517 | HAL_SPI_Write((address >> 16) & 0x3F); 518 | HAL_SPI_Write((address >> 8) & 0xff); 519 | HAL_SPI_Write(address & 0xff); 520 | 521 | HAL_SPI_ReadBuffer(buf, 4); 522 | 523 | HAL_SPI_Disable(); 524 | 525 | Data32 = buf[0] + ((uint32_t)buf[1] << 8) + ((uint32_t)buf[2] << 16) + ((uint32_t)buf[3] << 24); 526 | return (Data32); 527 | } 528 | 529 | uint16_t rd16(uint32_t address) 530 | { 531 | uint8_t buf[2] = { 0,0 }; 532 | 533 | HAL_SPI_Enable(); 534 | 535 | HAL_SPI_Write((address >> 16) & 0x3F); 536 | HAL_SPI_Write((address >> 8) & 0xff); 537 | HAL_SPI_Write(address & 0xff); 538 | 539 | HAL_SPI_ReadBuffer(buf, 2); 540 | 541 | HAL_SPI_Disable(); 542 | 543 | uint16_t Data16 = buf[0] + ((uint16_t)buf[1] << 8); 544 | return (Data16); 545 | } 546 | 547 | uint8_t rd8(uint32_t address) 548 | { 549 | uint8_t buf[1]; 550 | 551 | HAL_SPI_Enable(); 552 | 553 | HAL_SPI_Write((address >> 16) & 0x3F); 554 | HAL_SPI_Write((address >> 8) & 0xff); 555 | HAL_SPI_Write(address & 0xff); 556 | 557 | HAL_SPI_ReadBuffer(buf, 1); 558 | 559 | HAL_SPI_Disable(); 560 | 561 | return (buf[0]); 562 | } 563 | 564 | // *** Send_Cmd() - this is like cmd() in (some) Eve docs - sends 32 bits but does not update the write pointer *** 565 | // FT81x Series Programmers Guide Section 5.1.1 - Circular Buffer (AKA "the FIFO" and "Command buffer" and "CoProcessor") 566 | // Don't miss section 5.3 - Interaction with RAM_DL 567 | void Send_CMD(uint32_t data) 568 | { 569 | wr32(FifoWriteLocation + RAM_CMD, data); // write the command at the globally tracked "write pointer" for the FIFO 570 | 571 | FifoWriteLocation += FT_CMD_SIZE; // Increment the Write Address by the size of a command - which we just sent 572 | FifoWriteLocation %= FT_CMD_FIFO_SIZE; // Wrap the address to the FIFO space 573 | } 574 | 575 | // UpdateFIFO - Cause the CoProcessor to realize that it has work to do in the form of a 576 | // differential between the read pointer and write pointer. The CoProcessor (FIFO or "Command buffer") does 577 | // nothing until you tell it that the write position in the FIFO RAM has changed 578 | void UpdateFIFO(void) 579 | { 580 | wr16(REG_CMD_WRITE + RAM_REG, FifoWriteLocation); // We manually update the write position pointer 581 | } 582 | 583 | // Read the specific ID register and return TRUE if it is the expected 0x7C otherwise. 584 | uint8_t Cmd_READ_REG_ID(void) 585 | { 586 | uint8_t readData[2]; 587 | 588 | HAL_SPI_Enable(); 589 | HAL_SPI_Write(0x30); // Base address RAM_REG = 0x302000 590 | HAL_SPI_Write(0x20); 591 | HAL_SPI_Write(REG_ID); // REG_ID offset = 0x00 592 | HAL_SPI_ReadBuffer(readData, 1); // There was a dummy read of the first byte in there 593 | HAL_SPI_Disable(); 594 | 595 | if (readData[0] == 0x7C) // FT81x Datasheet section 5.1, Table 5-2. Return value always 0x7C 596 | { 597 | // Log("\nGood ID: 0x%02x\n", readData[0]); 598 | return 1; 599 | } 600 | else 601 | { 602 | // Log("0x%02x ", readData[0]); 603 | return 0; 604 | } 605 | } 606 | 607 | // **************************************** Co-Processor/GPU/FIFO/Command buffer Command Functions *************** 608 | // These are discussed in FT81x Series Programmers Guide, starting around section 5.10 609 | // While display list commands can be sent to the CoPro, these listed commands are specific to it. They are 610 | // mostly widgets like graphs, but also touch related functions like cmd_track() and memory operations. 611 | // Essentially, these commands set up parameters for CoPro functions which expand "macros" using those parameters 612 | // to then write a series of commands into the Display List to create all the primitives which make that widget. 613 | // *************************************************************************************************************** 614 | 615 | // ******************** Screen Object Creation CoProcessor Command Functions ****************************** 616 | 617 | // *** Draw Slider - FT81x Series Programmers Guide Section 5.38 ************************************************* 618 | void Cmd_Slider(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t options, uint16_t val, uint16_t range) 619 | { 620 | Send_CMD(CMD_SLIDER); 621 | Send_CMD( ((uint32_t)y << 16) | x ); 622 | Send_CMD( ((uint32_t)h << 16) | w ); 623 | Send_CMD( ((uint32_t)val << 16) | options ); 624 | Send_CMD( (uint32_t)range ); 625 | } 626 | 627 | // *** Draw Spinner - FT81x Series Programmers Guide Section 5.54 ************************************************* 628 | void Cmd_Spinner(uint16_t x, uint16_t y, uint16_t style, uint16_t scale) 629 | { 630 | Send_CMD(CMD_SPINNER); 631 | Send_CMD( ((uint32_t)y << 16) | x ); 632 | Send_CMD( ((uint32_t)scale << 16) | style ); 633 | } 634 | 635 | // *** Draw Gauge - FT81x Series Programmers Guide Section 5.33 ************************************************** 636 | void Cmd_Gauge(uint16_t x, uint16_t y, uint16_t r, uint16_t options, uint16_t major, uint16_t minor, uint16_t val, uint16_t range) 637 | { 638 | Send_CMD(CMD_GAUGE); 639 | Send_CMD( ((uint32_t)y << 16) | x ); 640 | Send_CMD( ((uint32_t)options << 16) | r ); 641 | Send_CMD( ((uint32_t)minor << 16) | major ); 642 | Send_CMD( ((uint32_t)range << 16) | val ); 643 | } 644 | 645 | // *** Draw Dial - FT81x Series Programmers Guide Section 5.39 ************************************************** 646 | // This is much like a Gauge except for the helpful range parameter. For some reason, all dials are 65535 around. 647 | void Cmd_Dial(uint16_t x, uint16_t y, uint16_t r, uint16_t options, uint16_t val) 648 | { 649 | Send_CMD(CMD_DIAL); 650 | Send_CMD( ((uint32_t)y << 16) | x ); 651 | Send_CMD( ((uint32_t)options << 16) | r ); 652 | Send_CMD( (uint32_t)val ); 653 | } 654 | 655 | // *** Make Track (for a slider) - FT81x Series Programmers Guide Section 5.62 ************************************ 656 | // tag refers to the tag # previously assigned to the object that this track is tracking. 657 | void Cmd_Track(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t tag) 658 | { 659 | Send_CMD(CMD_TRACK); 660 | Send_CMD( ((uint32_t)y << 16) | x ); 661 | Send_CMD( ((uint32_t)h << 16) | w ); 662 | Send_CMD( (uint32_t)tag ); 663 | } 664 | 665 | // *** Draw Number - FT81x Series Programmers Guide Section 5.43 ************************************************* 666 | void Cmd_Number(uint16_t x, uint16_t y, uint16_t font, uint16_t options, uint32_t num) 667 | { 668 | Send_CMD(CMD_NUMBER); 669 | Send_CMD( ((uint32_t)y << 16) | x ); 670 | Send_CMD( ((uint32_t)options << 16) | font ); 671 | Send_CMD(num); 672 | } 673 | 674 | // *** Draw Smooth Color Gradient - FT81x Series Programmers Guide Section 5.34 ********************************** 675 | void Cmd_Gradient(uint16_t x0, uint16_t y0, uint32_t rgb0, uint16_t x1, uint16_t y1, uint32_t rgb1) 676 | { 677 | Send_CMD(CMD_GRADIENT); 678 | Send_CMD( ((uint32_t)y0<<16)|x0 ); 679 | Send_CMD(rgb0); 680 | Send_CMD( ((uint32_t)y1<<16)|x1 ); 681 | Send_CMD(rgb1); 682 | } 683 | 684 | // *** Draw Button - FT81x Series Programmers Guide Section 5.28 ************************************************** 685 | void Cmd_Button(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t font, uint16_t options, const char* str) 686 | { 687 | uint16_t DataPtr, LoopCount, StrPtr; 688 | 689 | uint16_t length = (uint16_t)strlen(str); 690 | if(!length) 691 | return; 692 | 693 | uint32_t* data = (uint32_t*) calloc((length/4)+1, sizeof(uint32_t)); 694 | 695 | StrPtr = 0; 696 | for(DataPtr=0; DataPtr<(length/4); DataPtr++, StrPtr += 4) 697 | data[DataPtr] = (uint32_t)str[StrPtr+3]<<24 | (uint32_t)str[StrPtr+2]<<16 | (uint32_t)str[StrPtr+1]<<8 | (uint32_t)str[StrPtr]; 698 | 699 | for(LoopCount=0; LoopCount<(length%4); LoopCount++, StrPtr++) 700 | data[DataPtr] |= (uint32_t)str[StrPtr] << (LoopCount * 8); 701 | 702 | Send_CMD(CMD_BUTTON); 703 | Send_CMD( ((uint32_t)y << 16) | x ); // Put two 16 bit values together into one 32 bit value - do it little endian 704 | Send_CMD( ((uint32_t)h << 16) | w ); 705 | Send_CMD( ((uint32_t)options << 16) | font ); 706 | 707 | for (LoopCount = 0; LoopCount <= length / 4; LoopCount++) 708 | { 709 | Send_CMD(data[LoopCount]); 710 | } 711 | 712 | free(data); 713 | } 714 | 715 | // *** Draw Text - FT81x Series Programmers Guide Section 5.41 *************************************************** 716 | void Cmd_Text(uint16_t x, uint16_t y, uint16_t font, uint16_t options, const char* str) 717 | { 718 | uint16_t DataPtr, LoopCount, StrPtr; 719 | 720 | uint16_t length = (uint16_t) strlen(str); 721 | if(!length) 722 | return; 723 | 724 | uint32_t* data = (uint32_t*) calloc((length / 4) + 1, sizeof(uint32_t)); // Allocate memory for the string expansion 725 | 726 | StrPtr = 0; 727 | for(DataPtr=0; DataPtr<(length/4); ++DataPtr, StrPtr=StrPtr+4) 728 | data[DataPtr] = (uint32_t)str[StrPtr+3]<<24 | (uint32_t)str[StrPtr+2]<<16 | (uint32_t)str[StrPtr+1]<<8 | (uint32_t)str[StrPtr]; 729 | 730 | for(LoopCount=0; LoopCount<(length%4); ++LoopCount, ++StrPtr) 731 | data[DataPtr] |= (uint32_t)str[StrPtr] << (LoopCount*8); 732 | 733 | // Set up the command 734 | Send_CMD(CMD_TEXT); 735 | Send_CMD( ((uint32_t)y << 16) | x ); 736 | Send_CMD( ((uint32_t)options << 16) | font ); 737 | 738 | // Send out the text 739 | for(LoopCount = 0; LoopCount <= length/4; LoopCount++) 740 | Send_CMD(data[LoopCount]); // These text bytes get sucked up 4 at a time and fired at the FIFO 741 | 742 | free(data); 743 | } 744 | 745 | // ******************** Miscellaneous Operation CoProcessor Command Functions ****************************** 746 | 747 | // *** Cmd_SetBitmap - generate DL commands for bitmap parms - FT81x Series Programmers Guide Section 5.65 ******* 748 | void Cmd_SetBitmap(uint32_t addr, uint16_t fmt, uint16_t width, uint16_t height) 749 | { 750 | Send_CMD( CMD_SETBITMAP ); 751 | Send_CMD( addr ); 752 | Send_CMD( ((uint32_t)width << 16) | fmt ); 753 | Send_CMD( (uint32_t)height); 754 | } 755 | 756 | // *** Cmd_Memcpy - background copy a block of data - FT81x Series Programmers Guide Section 5.27 **************** 757 | void Cmd_Memcpy(uint32_t dest, uint32_t src, uint32_t num) 758 | { 759 | Send_CMD(CMD_MEMCPY); 760 | Send_CMD(dest); 761 | Send_CMD(src); 762 | Send_CMD(num); 763 | } 764 | 765 | // *** Cmd_GetPtr - Get the last used address from CoPro operation - FT81x Series Programmers Guide Section 5.47 * 766 | void Cmd_GetPtr(void) 767 | { 768 | Send_CMD(CMD_GETPTR); 769 | Send_CMD(0); 770 | } 771 | 772 | // *** Set Highlight Gradient Color - FT81x Series Programmers Guide Section 5.32 ******************************** 773 | void Cmd_GradientColor(uint32_t c) 774 | { 775 | Send_CMD(CMD_GRADCOLOR); 776 | Send_CMD(c); 777 | } 778 | 779 | // *** Set FG color - FT81x Series Programmers Guide Section 5.30 ************************************************ 780 | void Cmd_FGcolor(uint32_t c) 781 | { 782 | Send_CMD(CMD_FGCOLOR); 783 | Send_CMD(c); 784 | } 785 | 786 | // *** Set BG color - FT81x Series Programmers Guide Section 5.31 ************************************************ 787 | void Cmd_BGcolor(uint32_t c) 788 | { 789 | Send_CMD(CMD_BGCOLOR); 790 | Send_CMD(c); 791 | } 792 | 793 | // *** Translate Matrix - FT81x Series Programmers Guide Section 5.51 ******************************************** 794 | void Cmd_Translate(uint32_t tx, uint32_t ty) 795 | { 796 | Send_CMD(CMD_TRANSLATE); 797 | Send_CMD(tx); 798 | Send_CMD(ty); 799 | } 800 | 801 | // *** Rotate Matrix - FT81x Series Programmers Guide Section 5.50 *********************************************** 802 | void Cmd_Rotate(uint32_t a) 803 | { 804 | Send_CMD(CMD_ROTATE); 805 | Send_CMD(a); 806 | } 807 | 808 | // *** Rotate Screen - FT81x Series Programmers Guide Section 5.53 *********************************************** 809 | void Cmd_SetRotate(uint32_t rotation) 810 | { 811 | Send_CMD(CMD_SETROTATE); 812 | Send_CMD(rotation); 813 | } 814 | 815 | // *** Scale Matrix - FT81x Series Programmers Guide Section 5.49 ************************************************ 816 | void Cmd_Scale(uint32_t sx, uint32_t sy) 817 | { 818 | Send_CMD(CMD_SCALE); 819 | Send_CMD(sx); 820 | Send_CMD(sy); 821 | } 822 | 823 | void Cmd_Flash_Fast(void) 824 | { 825 | Send_CMD(CMD_FLASHFAST); 826 | Send_CMD(0); 827 | } 828 | 829 | // *** Calibrate Touch Digitizer - FT81x Series Programmers Guide Section 5.52 *********************************** 830 | // * This business about "result" in the manual really seems to be simply leftover cruft of no purpose - send zero 831 | void Cmd_Calibrate(uint32_t result) 832 | { 833 | Send_CMD(CMD_CALIBRATE); 834 | Send_CMD(result); 835 | } 836 | 837 | // An interactive calibration screen is created and executed. 838 | // New calibration values are written to the touch matrix registers of Eve. 839 | void Calibrate_Manual(uint16_t Width, uint16_t Height, uint16_t V_Offset, uint16_t H_Offset) 840 | { 841 | uint32_t displayX[3], displayY[3]; 842 | uint32_t touchX[3], touchY[3]; 843 | uint32_t touchValue = 0, storedValue = 0; 844 | int32_t tmp, k; 845 | int32_t TransMatrix[6]; 846 | uint8_t count = 0; 847 | uint8_t pressed = 0; 848 | char num[2]; 849 | 850 | // These values determine where your calibration points will be drawn on your display 851 | displayX[0] = (uint32_t) (Width * 0.15) + H_Offset; 852 | displayY[0] = (uint32_t) (Height * 0.15) + V_Offset; 853 | 854 | displayX[1] = (uint32_t) (Width * 0.85) + H_Offset; 855 | displayY[1] = (uint32_t) (Height / 2) + V_Offset; 856 | 857 | displayX[2] = (uint32_t) (Width / 2) + H_Offset; 858 | displayY[2] = (uint32_t) (Height * 0.85) + V_Offset; 859 | 860 | while (count < 3) 861 | { 862 | Send_CMD(CMD_DLSTART); 863 | Send_CMD(CLEAR_COLOR_RGB(0, 0, 0)); 864 | Send_CMD(CLEAR(1,1,1)); 865 | 866 | // Draw Calibration Point on screen 867 | Send_CMD(COLOR_RGB(255, 0, 0)); 868 | Send_CMD(POINT_SIZE(20 * 16)); 869 | Send_CMD(BEGIN(POINTS)); 870 | Send_CMD(VERTEX2F((uint32_t)(displayX[count]) * 16, (uint32_t)((displayY[count])) * 16)); 871 | Send_CMD(END()); 872 | Send_CMD(COLOR_RGB(255, 255, 255)); 873 | Cmd_Text((Width / 2) + H_Offset, (Height / 3) + V_Offset, 27, OPT_CENTER, "Calibrating"); 874 | Cmd_Text((Width / 2) + H_Offset, (Height / 2) + V_Offset, 27, OPT_CENTER, "Please tap the dots"); 875 | num[0] = count + 0x31; num[1] = 0; // null terminated string of one character 876 | Cmd_Text(displayX[count], displayY[count], 27, OPT_CENTER, num); 877 | 878 | Send_CMD(DISPLAY()); 879 | Send_CMD(CMD_SWAP); 880 | UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO 881 | Wait4CoProFIFOEmpty(); // wait here until the coprocessor has read and executed every pending command. 882 | HAL_Delay(300); 883 | 884 | while (pressed == count) 885 | { 886 | touchValue = rd32(REG_TOUCH_DIRECT_XY + RAM_REG); // Read for any new touch tag inputs 887 | if (!(touchValue & 0x80000000)) 888 | { 889 | touchX[count] = (touchValue >> 16) & 0x03FF; // Raw Touchscreen Y coordinate 890 | touchY[count] = touchValue & 0x03FF; // Raw Touchscreen Y coordinate 891 | 892 | //Log("\ndisplay x[%d]: %ld display y[%d]: %ld\n", count, displayX[count], count, displayY[count]); 893 | //Log("touch x[%d]: %ld touch y[%d]: %ld\n", count, touchX[count], count, touchY[count]); 894 | 895 | count++; 896 | } 897 | } 898 | pressed = count; 899 | 900 | } 901 | 902 | k = ((touchX[0] - touchX[2])*(touchY[1] - touchY[2])) - ((touchX[1] - touchX[2])*(touchY[0] - touchY[2])); 903 | 904 | tmp = (((displayX[0] - displayX[2]) * (touchY[1] - touchY[2])) - ((displayX[1] - displayX[2])*(touchY[0] - touchY[2]))); 905 | TransMatrix[0] = ((int64_t)tmp << 16) / k; 906 | 907 | tmp = (((touchX[0] - touchX[2]) * (displayX[1] - displayX[2])) - ((displayX[0] - displayX[2])*(touchX[1] - touchX[2]))); 908 | TransMatrix[1] = ((int64_t)tmp << 16) / k; 909 | 910 | tmp = ((touchY[0] * (((touchX[2] * displayX[1]) - (touchX[1] * displayX[2])))) + (touchY[1] * (((touchX[0] * displayX[2]) - (touchX[2] * displayX[0])))) + (touchY[2] * (((touchX[1] * displayX[0]) - (touchX[0] * displayX[1]))))); 911 | TransMatrix[2] = ((int64_t)tmp << 16) / k; 912 | 913 | tmp = (((displayY[0] - displayY[2]) * (touchY[1] - touchY[2])) - ((displayY[1] - displayY[2])*(touchY[0] - touchY[2]))); 914 | TransMatrix[3] = ((int64_t)tmp << 16) / k; 915 | 916 | tmp = (((touchX[0] - touchX[2]) * (displayY[1] - displayY[2])) - ((displayY[0] - displayY[2])*(touchX[1] - touchX[2]))); 917 | TransMatrix[4] = ((int64_t)tmp << 16) / k; 918 | 919 | tmp = ((touchY[0] * (((touchX[2] * displayY[1]) - (touchX[1] * displayY[2])))) + (touchY[1] * (((touchX[0] * displayY[2]) - (touchX[2] * displayY[0])))) + (touchY[2] * (((touchX[1] * displayY[0]) - (touchX[0] * displayY[1]))))); 920 | TransMatrix[5] = ((int64_t)tmp << 16) / k; 921 | 922 | count = 0; 923 | do 924 | { 925 | wr32(REG_TOUCH_TRANSFORM_A + RAM_REG + (count * 4), TransMatrix[count]); // Write to Eve config registers 926 | 927 | // uint16_t ValH = TransMatrix[count] >> 16; 928 | // uint16_t ValL = TransMatrix[count] & 0xFFFF; 929 | // Log("TM%d: 0x%04x %04x\n", count, ValH, ValL); 930 | 931 | count++; 932 | }while(count < 6); 933 | } 934 | // *************************************************************************************************************** 935 | // *** Animation functions *************************************************************************************** 936 | // *************************************************************************************************************** 937 | 938 | void Cmd_AnimStart(int32_t ch, uint32_t aoptr, uint32_t loop) 939 | { 940 | Send_CMD(CMD_ANIMSTART); 941 | Send_CMD(ch); 942 | Send_CMD(aoptr); 943 | Send_CMD(loop); 944 | } 945 | 946 | void Cmd_AnimStop(int32_t ch) 947 | { 948 | Send_CMD(CMD_ANIMSTOP); 949 | Send_CMD(ch); 950 | } 951 | 952 | void Cmd_AnimXY(int32_t ch, int16_t x, int16_t y) 953 | { 954 | Send_CMD(CMD_ANIMXY); 955 | Send_CMD(ch); 956 | Send_CMD(((uint32_t)y << 16) | x); 957 | } 958 | 959 | void Cmd_AnimDraw(int32_t ch) 960 | { 961 | Send_CMD(CMD_ANIMDRAW); 962 | Send_CMD(ch); 963 | } 964 | 965 | void Cmd_AnimDrawFrame(int16_t x, int16_t y, uint32_t aoptr, uint32_t frame) 966 | { 967 | Send_CMD(CMD_ANIMFRAME); 968 | Send_CMD(((uint32_t)y << 16) | x); 969 | Send_CMD(aoptr); 970 | Send_CMD(frame); 971 | } 972 | 973 | // *************************************************************************************************************** 974 | // *** Utility and helper functions ****************************************************************************** 975 | // *************************************************************************************************************** 976 | 977 | // Find the space available in the GPU AKA CoProcessor AKA command buffer AKA FIFO 978 | uint16_t CoProFIFO_FreeSpace(void) 979 | { 980 | uint16_t cmdBufferDiff, cmdBufferRd, cmdBufferWr, retval; 981 | 982 | cmdBufferRd = rd16(REG_CMD_READ + RAM_REG); 983 | cmdBufferWr = rd16(REG_CMD_WRITE + RAM_REG); 984 | 985 | cmdBufferDiff = (cmdBufferWr-cmdBufferRd) % FT_CMD_FIFO_SIZE; // FT81x Programmers Guide 5.1.1 986 | retval = (FT_CMD_FIFO_SIZE - 4) - cmdBufferDiff; 987 | return (retval); 988 | } 989 | 990 | // Sit and wait until there are the specified number of bytes free in the incoming FIFO 991 | void Wait4CoProFIFO(uint32_t room) 992 | { 993 | uint16_t getfreespace; 994 | 995 | do { 996 | getfreespace = CoProFIFO_FreeSpace(); 997 | }while(getfreespace < room); 998 | } 999 | 1000 | // Sit and wait until the CoPro FIFO is empty 1001 | // Detect operational errors and print the error and stop. 1002 | void Wait4CoProFIFOEmpty(void) 1003 | { 1004 | uint16_t ReadReg; 1005 | uint8_t ErrChar; 1006 | uint8_t buffy[2]; 1007 | do 1008 | { 1009 | ReadReg = rd16(REG_CMD_READ + RAM_REG); 1010 | if(ReadReg == 0xFFF) 1011 | { 1012 | // this is a error which would require sophistication to fix and continue but we fake it somewhat unsuccessfully 1013 | Log("\n"); 1014 | uint8_t Offset = 0; 1015 | do 1016 | { 1017 | // Get the error character and display it 1018 | ErrChar = rd8(RAM_ERR_REPORT + Offset); 1019 | Offset++; 1020 | sprintf(buffy, "%c", ErrChar); 1021 | Log(buffy); 1022 | }while ( (ErrChar != 0) && (Offset < 128) ); // when the last stuffed character was null, we are done 1023 | Log("\n"); 1024 | 1025 | // Eve is unhappy - needs a paddling. 1026 | uint32_t Patch_Add = rd32(REG_COPRO_PATCH_PTR + RAM_REG); 1027 | wr8(REG_CPU_RESET + RAM_REG, 1); 1028 | wr8(REG_CMD_READ + RAM_REG, 0); 1029 | wr8(REG_CMD_WRITE + RAM_REG, 0); 1030 | wr8(REG_CMD_DL + RAM_REG, 0); 1031 | wr8(REG_CPU_RESET + RAM_REG, 0); 1032 | wr32(REG_COPRO_PATCH_PTR + RAM_REG, Patch_Add); 1033 | HAL_Delay(250); // we already saw one error message and we don't need to see then 1000 times a second 1034 | } 1035 | }while( ReadReg != rd16(REG_CMD_WRITE + RAM_REG) ); 1036 | } 1037 | 1038 | // Every CoPro transaction starts with enabling the SPI and sending an address 1039 | void StartCoProTransfer(uint32_t address, uint8_t reading) 1040 | { 1041 | HAL_SPI_Enable(); 1042 | if (reading){ 1043 | HAL_SPI_Write(address >> 16); 1044 | HAL_SPI_Write(address >> 8); 1045 | HAL_SPI_Write(address); 1046 | HAL_SPI_Write(0); 1047 | }else{ 1048 | HAL_SPI_Write((address >> 16) | 0x80); 1049 | HAL_SPI_Write(address >> 8); 1050 | HAL_SPI_Write(address); 1051 | } 1052 | } 1053 | 1054 | // *** CoProWrCmdBuf() - Transfer a buffer into the CoPro FIFO as part of an ongoing command operation *********** 1055 | void CoProWrCmdBuf(const uint8_t *buff, uint32_t count) 1056 | { 1057 | uint32_t TransferSize = 0; 1058 | int32_t Remaining = count; // signed 1059 | 1060 | do { 1061 | // Here is the situation: You have up to about a megabyte of data to transfer into the FIFO 1062 | // Your buffer is LogBuf - limited to 64 bytes (or some other value, but always limited). 1063 | // You need to go around in loops taking 64 bytes at a time until all the data is gone. 1064 | // 1065 | // Most interactions with the FIFO are started and finished in one operation in an obvious fashion, but 1066 | // here it is important to understand the difference between Eve RAM registers and Eve FIFO. Even though 1067 | // you are in the middle of a FIFO operation and filling the FIFO is an ongoing task, you are still free 1068 | // to write and read non-FIFO registers on the Eve chip. 1069 | // 1070 | // Since the FIFO is 4K in size, but the RAM_G space is 1M in size, you can not, obviously, send all 1071 | // the possible RAM_G data through the FIFO in one step. Also, since the Eve is not capable of updating 1072 | // it's own FIFO pointer as data is written, you will need to intermittently tell Eve to go process some 1073 | // FIFO in order to make room in the FIFO for more RAM_G data. 1074 | Wait4CoProFIFO(WorkBuffSz); // It is reasonable to wait for a small space instead of firing data piecemeal 1075 | 1076 | if (Remaining > WorkBuffSz) // Remaining data exceeds the size of our buffer 1077 | TransferSize = WorkBuffSz; // So set the transfer size to that of our buffer 1078 | else 1079 | { 1080 | TransferSize = Remaining; // Set size to this last dribble of data 1081 | TransferSize = (TransferSize + 3) & 0xFFC; // 4 byte alignment 1082 | } 1083 | 1084 | StartCoProTransfer(FifoWriteLocation + RAM_CMD, false);// Base address of the Command Buffer plus our offset into it - Start SPI transaction 1085 | 1086 | HAL_SPI_WriteBuffer((uint8_t*)buff, TransferSize); // write the little bit for which we found space 1087 | buff += TransferSize; // move the working data read pointer to the next fresh data 1088 | 1089 | FifoWriteLocation = (FifoWriteLocation + TransferSize) % FT_CMD_FIFO_SIZE; 1090 | HAL_SPI_Disable(); // End SPI transaction with the FIFO 1091 | 1092 | wr16(REG_CMD_WRITE + RAM_REG, FifoWriteLocation); // Manually update the write position pointer to initiate processing of the FIFO 1093 | Remaining -= TransferSize; // reduce what we want by what we sent 1094 | 1095 | }while (Remaining > 0); // keep going as long as we still want more 1096 | } 1097 | 1098 | // Write a block of data into Eve RAM space a byte at a time. 1099 | // Return the last written address + 1 (The next available RAM address) 1100 | uint32_t WriteBlockRAM(uint32_t Add, const uint8_t *buff, uint32_t count) 1101 | { 1102 | uint32_t index; 1103 | uint32_t WriteAddress = Add; // I want to return the value instead of modifying the variable in place 1104 | 1105 | for (index = 0; index < count; index++) 1106 | { 1107 | wr8(WriteAddress++, buff[index]); 1108 | } 1109 | return (WriteAddress); 1110 | } 1111 | 1112 | // CalcCoef - Support function for manual screen calibration function 1113 | int32_t CalcCoef(int32_t Q, int32_t K) 1114 | { 1115 | int8_t sn = 0; 1116 | 1117 | if (Q < 0) // We need to work with positive values 1118 | { 1119 | Q *= -1; // So here we make them positive 1120 | sn++; // and remember that fact 1121 | } 1122 | 1123 | if (K < 0) 1124 | { 1125 | K *= -1; 1126 | sn++; // 1 + 1 = 2 = 0b00000010 1127 | } 1128 | 1129 | uint32_t I = ((uint32_t)Q / (uint32_t)K) << 16; // get the integer part and shift it by 16 1130 | uint32_t R = Q % K; // get the remainder of a/k; 1131 | R = R << 14; // shift by 14 1132 | R = R / K; // divide 1133 | R = R << 2; // Make up for the missing bits 1134 | int32_t returnValue = I + R; // combine them 1135 | 1136 | if (sn & 0x01) // If the result is supposed to be negative 1137 | returnValue *= -1; // then return it to that state. 1138 | 1139 | return (returnValue); 1140 | } 1141 | 1142 | bool FlashAttach(void) 1143 | { 1144 | Send_CMD(CMD_FLASHATTACH); 1145 | UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO 1146 | Wait4CoProFIFOEmpty(); // wait here until the coprocessor has read and executed every pending command. 1147 | 1148 | uint8_t FlashStatus = rd8(REG_FLASH_STATUS + RAM_REG); 1149 | if (FlashStatus != FLASH_STATUS_BASIC) 1150 | { 1151 | return false; 1152 | } 1153 | return true; 1154 | } 1155 | 1156 | bool FlashDetach(void) 1157 | { 1158 | Send_CMD(CMD_FLASHDETACH); 1159 | UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO 1160 | Wait4CoProFIFOEmpty(); // wait here until the coprocessor has read and executed every pending command. 1161 | 1162 | uint8_t FlashStatus = rd8(REG_FLASH_STATUS + RAM_REG); 1163 | if (FlashStatus != FLASH_STATUS_DETACHED) 1164 | { 1165 | return false; 1166 | } 1167 | return true; 1168 | } 1169 | 1170 | bool FlashFast(void) 1171 | { 1172 | Cmd_Flash_Fast(); 1173 | UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO 1174 | Wait4CoProFIFOEmpty(); // wait here until the coprocessor has read and executed every pending command. 1175 | 1176 | uint8_t FlashStatus = rd8(REG_FLASH_STATUS + RAM_REG); 1177 | if (FlashStatus != FLASH_STATUS_FULL) 1178 | { 1179 | return false; 1180 | } 1181 | return true; 1182 | } 1183 | 1184 | bool FlashErase(void) 1185 | { 1186 | Send_CMD(CMD_FLASHERASE); 1187 | UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO 1188 | Wait4CoProFIFOEmpty(); // wait here until the coprocessor has read and executed every pending command. 1189 | return true; 1190 | } 1191 | 1192 | #if defined(EVE_MO_INTERNAL_BUILD) 1193 | void EVE_SPI_Enable(void) 1194 | { 1195 | HAL_SPI_Enable(); 1196 | } 1197 | 1198 | void EVE_SPI_Disable(void) 1199 | { 1200 | HAL_SPI_Disable(); 1201 | } 1202 | 1203 | uint8_t EVE_SPI_Write(uint8_t data) 1204 | { 1205 | return HAL_SPI_Write(data); 1206 | } 1207 | 1208 | void EVE_SPI_WriteBuffer(uint8_t *Buffer, uint32_t Length) 1209 | { 1210 | HAL_SPI_WriteBuffer(Buffer, Length); 1211 | } 1212 | #endif -------------------------------------------------------------------------------- /Eve2_81x.h: -------------------------------------------------------------------------------- 1 | #ifndef __EVE81X_H 2 | #define __EVE81X_H 3 | 4 | /* For interal builds a dll version of this code is supported */ 5 | #if defined(EVE_MO_INTERNAL_BUILD) 6 | # include "eve_export.h" 7 | #else 8 | # define EVE_EXPORT 9 | #endif 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | // ===================================================================================== 17 | // Required Functions - Hardware driver or otherwise environment specific. Abstracted | 18 | // and found in hw_api.h. | 19 | // This library requires base support functions for SPI, delays, and hardware pin | 20 | // control. | 21 | // ===================================================================================== 22 | 23 | // Just in case this is for Arduino - Eve wants a DISPLAY() macro and Arduino already defines DISPLAY 24 | // for something else that we will not be using, so we can kill the Arduino define. 25 | #if defined(DISPLAY) 26 | # undef DISPLAY 27 | #endif 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | #define HCMD_ACTIVE 0x00 34 | #define HCMD_STANDBY 0x41 35 | #define HCMD_SLEEP 0x42 36 | #define HCMD_PWRDOWN 0x50 37 | #define HCMD_CLKINT 0x48 38 | #define HCMD_CLKEXT 0x44 39 | #define HCMD_CLK48M 0x62 40 | #define HCMD_CLK36M 0x61 41 | #define HCMD_CORERESET 0x68 42 | 43 | #define CMD_APPEND 0xFFFFFF1E 44 | #define CMD_BGCOLOR 0xFFFFFF09 45 | #define CMD_BUTTON 0xFFFFFF0D 46 | #define CMD_CALIBRATE 0xFFFFFF15 // 4294967061UL 47 | #define CMD_CLOCK 0xFFFFFF14 48 | #define CMD_COLDSTART 0xFFFFFF32 49 | #define CMD_CRC 0xFFFFFF18 50 | #define CMD_DIAL 0xFFFFFF2D 51 | #define CMD_DLSTART 0xFFFFFF00 52 | #define CMD_FGCOLOR 0xFFFFFF0A 53 | #define CMD_GAUGE 0xFFFFFF13 54 | #define CMD_GETMATRIX 0xFFFFFF33 55 | #define CMD_GETPROPS 0xFFFFFF25 56 | #define CMD_GETPTR 0xFFFFFF23 57 | #define CMD_GRADCOLOR 0xFFFFFF34 58 | #define CMD_GRADIENT 0xFFFFFF0B 59 | #define CMD_INFLATE 0xFFFFFF22 60 | #define CMD_INFLATE2 0xFFFFFF50 61 | #define CMD_INTERRUPT 0xFFFFFF02 62 | #define CMD_KEYS 0xFFFFFF0E 63 | #define CMD_LOADIDENTITY 0xFFFFFF26 64 | #define CMD_LOADIMAGE 0xFFFFFF24 65 | #define CMD_LOGO 0xFFFFFF31 66 | #define CMD_MEDIAFIFO 0xFFFFFF39 67 | #define CMD_MEMCPY 0xFFFFFF1D 68 | #define CMD_MEMCRC 0xFFFFFF18 69 | #define CMD_MEMSET 0xFFFFFF1B 70 | #define CMD_MEMWRITE 0xFFFFFF1A 71 | #define CMD_MEMZERO 0xFFFFFF1C 72 | #define CMD_NUMBER 0xFFFFFF2E 73 | #define CMD_PLAYVIDEO 0xFFFFFF3A 74 | #define CMD_PROGRESS 0xFFFFFF0F 75 | #define CMD_REGREAD 0xFFFFFF19 76 | #define CMD_ROTATE 0xFFFFFF29 77 | #define CMD_SCALE 0xFFFFFF28 78 | #define CMD_SCREENSAVER 0xFFFFFF2F 79 | #define CMD_SCROLLBAR 0xFFFFFF11 80 | #define CMD_SETBITMAP 0xFFFFFF43 81 | #define CMD_SETFONT 0xFFFFFF2B 82 | #define CMD_SETMATRIX 0xFFFFFF2A 83 | #define CMD_SETROTATE 0xFFFFFF36 84 | #define CMD_SKETCH 0xFFFFFF30 85 | #define CMD_SLIDER 0xFFFFFF10 86 | #define CMD_SNAPSHOT 0xFFFFFF1F 87 | #define CMD_SPINNER 0xFFFFFF16 88 | #define CMD_STOP 0xFFFFFF17 89 | #define CMD_SWAP 0xFFFFFF01 90 | #define CMD_TEXT 0xFFFFFF0C 91 | #define CMD_TOGGLE 0xFFFFFF12 92 | #define CMD_TRACK 0xFFFFFF2C 93 | #define CMD_TRANSLATE 0xFFFFFF27 94 | #define CMD_VIDEOFRAME 0xFFFFFF41 95 | #define CMD_VIDEOSTART 0xFFFFFF40 96 | #define CMD_ROMFONT 0xFFFFFF3F 97 | // BT81X COMMANDS 98 | #define CMD_FLASHERASE 0xFFFFFF44 99 | #define CMD_FLASHWRITE 0xFFFFFF45 100 | #define CMD_FLASHREAD 0xFFFFFF46 101 | #define CMD_FLASHUPDATE 0xFFFFFF47 102 | #define CMD_FLASHDETACH 0xFFFFFF48 103 | #define CMD_FLASHATTACH 0xFFFFFF49 104 | #define CMD_FLASHFAST 0xFFFFFF4A 105 | #define CMD_FLASHSPIDESEL 0xFFFFFF4B 106 | #define CMD_FLASHSPITX 0xFFFFFF4C 107 | #define CMD_FLASHSPIRX 0xFFFFFF4D 108 | #define CMD_FLASHSOURCE 0xFFFFFF4E 109 | #define CMD_CLEARCACHE 0xFFFFFF4F 110 | #define CMD_ANIMDRAW 4294967126UL 111 | #define CMD_ANIMFRAME 4294967130UL 112 | #define CMD_ANIMSTART 4294967123UL 113 | #define CMD_ANIMSTOP 4294967124UL 114 | #define CMD_ANIMXY 4294967125UL 115 | 116 | #define CMD_FLASHAPPENDF 0xFFFFFF59 117 | #define CMD_VIDEOSTARTF 0xFFFFFF5F 118 | 119 | #define DLSWAP_FRAME 2UL 120 | 121 | #define OPT_CENTER 1536UL 122 | #define OPT_CENTERX 512UL 123 | #define OPT_CENTERY 1024UL 124 | #define OPT_FLASH 64UL 125 | #define OPT_FLAT 256UL 126 | #define OPT_FULLSCREEN 8UL 127 | #define OPT_MEDIAFIFO 16UL 128 | #define OPT_MONO 1UL 129 | #define OPT_NOBACK 4096UL 130 | #define OPT_NODL 2UL 131 | #define OPT_NOHANDS 49152UL 132 | #define OPT_NOHM 16384UL 133 | #define OPT_NOPOINTER 16384UL 134 | #define OPT_NOSECS 32768UL 135 | #define OPT_NOTEAR 4UL 136 | #define OPT_NOTICKS 8192UL 137 | #define OPT_RGB565 0UL 138 | #define OPT_RIGHTX 2048UL 139 | #define OPT_SIGNED 256UL 140 | #define OPT_SOUND 32UL 141 | 142 | #define ANIM_HOLD 2UL 143 | #define ANIM_LOOP 1UL 144 | #define ANIM_ONCE 0UL 145 | 146 | // Definitions for FT8xx co processor command buffer 147 | #define FT_DL_SIZE (8*1024) // 8KB Display List buffer size 148 | #define FT_CMD_FIFO_SIZE (4*1024) // 4KB coprocessor Fifo size 149 | #define FT_CMD_SIZE (4) // 4 byte per coprocessor command of EVE 150 | 151 | // Memory base addresses 152 | #define RAM_G 0x0 153 | #define RAM_G_WORKING 0x0FF000 // This address may be used as the start of a 4K block to be used for copying data 154 | #define RAM_DL 0x300000 155 | #define RAM_REG 0x302000 156 | #define RAM_CMD 0x308000 157 | #define RAM_ERR_REPORT 0x309800 // max 128 bytes null terminated string 158 | #define RAM_FLASH 0x800000 159 | #define RAM_FLASH_POSTBLOB 0x801000 160 | 161 | // Graphics Engine Registers - FT81x Series Programmers Guide Section 3.1 162 | // Addresses defined as offsets from the base address called RAM_REG and located at 0x302000 163 | // Discussion: Defining this way leads to an additional add operation in code that can be avoided by defining 164 | // these addresses as 32 bit values, but this is easily paid for in clarity and coorelation to documentation. 165 | // Further, you can add defines together in code and allow the precompiler to do the add operation (as here). 166 | #define REG_CSPREAD 0x68 167 | #define REG_DITHER 0x60 168 | #define REG_DLSWAP 0x54 169 | #define REG_HCYCLE 0x2C 170 | #define REG_HOFFSET 0x30 171 | #define REG_HSIZE 0x34 172 | #define REG_HSYNC0 0x38 173 | #define REG_HSYNC1 0x3C 174 | #define REG_OUTBITS 0x5C 175 | #define REG_PCLK 0x70 176 | #define REG_PCLK_POL 0x6C 177 | #define REG_PLAY 0x8C 178 | #define REG_PLAYBACK_FORMAT 0xC4 179 | #define REG_PLAYBACK_FREQ 0xC0 180 | #define REG_PLAYBACK_LENGTH 0xB8 181 | #define REG_PLAYBACK_LOOP 0xC8 182 | #define REG_PLAYBACK_PLAY 0xCC 183 | #define REG_PLAYBACK_READPTR 0xBC 184 | #define REG_PLAYBACK_START 0xB4 185 | #define REG_PWM_DUTY 0xD4 186 | #define REG_ROTATE 0x58 187 | #define REG_SOUND 0x88 188 | #define REG_SWIZZLE 0x64 189 | #define REG_TAG 0x7C 190 | #define REG_TAG_X 0x74 191 | #define REG_TAG_Y 0x78 192 | #define REG_VCYCLE 0x40 193 | #define REG_VOFFSET 0x44 194 | #define REG_VOL_SOUND 0x84 195 | #define REG_VOL_PB 0x80 196 | #define REG_VSYNC0 0x4C 197 | #define REG_VSYNC1 0x50 198 | #define REG_VSIZE 0x48 199 | 200 | // Touch Screen Engine Registers - FT81x Series Programmers Guide Section 3.3 201 | // Addresses defined as offsets from the base address called RAM_REG and located at 0x302000 202 | #define REG_TOUCH_CONFIG 0x168 203 | #define REG_TOUCH_TRANSFORM_A 0x150 204 | #define REG_TOUCH_TRANSFORM_B 0x154 205 | #define REG_TOUCH_TRANSFORM_C 0x158 206 | #define REG_TOUCH_TRANSFORM_D 0x15C 207 | #define REG_TOUCH_TRANSFORM_E 0x160 208 | #define REG_TOUCH_TRANSFORM_F 0x164 209 | 210 | // Resistive Touch Engine Registers - FT81x Series Programmers Guide Section 3.3.3 - Document confused 211 | // Addresses defined as offsets from the base address called RAM_REG and located at 0x302000 212 | #define REG_TOUCH_ADC_MODE 0x108 213 | #define REG_TOUCH_CHARGE 0x10C 214 | #define REG_TOUCH_DIRECT_XY 0x18C 215 | #define REG_TOUCH_DIRECT_Z1Z2 0x190 216 | #define REG_TOUCH_MODE 0x104 217 | #define REG_TOUCH_OVERSAMPLE 0x114 218 | #define REG_TOUCH_RAW_XY 0x11C 219 | #define REG_TOUCH_RZ 0x120 220 | #define REG_TOUCH_RZTHRESH 0x118 221 | #define REG_TOUCH_SCREEN_XY 0x124 222 | #define REG_TOUCH_SETTLE 0x110 223 | #define REG_TOUCH_TAG 0x12C 224 | #define REG_TOUCH_TAG_XY 0x128 225 | 226 | // Capacitive Touch Engine Registers - FT81x Series Programmers Guide Section 3.3.4 227 | // Addresses defined as offsets from the base address called RAM_REG and located at 0x302000 228 | #define REG_CTOUCH_MODE 0x104 229 | #define REG_CTOUCH_EXTEND 0x108 230 | #define REG_CTOUCH_RAW_XY 0x11C 231 | #define REG_CTOUCH_TOUCH_XY 0x124 232 | #define REG_CTOUCH_TOUCH1_XY 0x11C 233 | #define REG_CTOUCH_TOUCH2_XY 0x18C 234 | #define REG_CTOUCH_TOUCH3_XY 0x190 235 | #define REG_CTOUCH_TOUCH4_X 0x16C 236 | #define REG_CTOUCH_TOUCH4_Y 0x120 237 | #define REG_CTOUCH_TAG 0x12C 238 | #define REG_CTOUCH_TAG1 0x134 239 | #define REG_CTOUCH_TAG2 0x13C 240 | #define REG_CTOUCH_TAG3 0x144 241 | #define REG_CTOUCH_TAG4 0x14C 242 | #define REG_CTOUCH_TAG_XY 0x128 243 | #define REG_CTOUCH_TAG1_XY 0x130 244 | #define REG_CTOUCH_TAG2_XY 0x138 245 | #define REG_CTOUCH_TAG3_XY 0x140 246 | #define REG_CTOUCH_TAG4_XY 0x148 247 | 248 | // Co-processor Engine Registers - FT81x Series Programmers Guide Section 3.4 249 | // Addresses defined as offsets from the base address called RAM_REG and located at 0x302000 250 | #define REG_CMD_DL 0x100 251 | #define REG_CMD_READ 0xF8 252 | #define REG_CMD_WRITE 0xFC 253 | #define REG_CMDB_SPACE 0x574 254 | #define REG_CMDB_WRITE 0x578 255 | #define REG_COPRO_PATCH_PTR 0x7162 256 | 257 | // Special Registers - FT81x Series Programmers Guide Section 3.5 258 | // Addresses assumed to be defined as offsets from the base address called RAM_REG and located at 0x302000 259 | #define REG_TRACKER 0x7000 260 | #define REG_TRACKER_1 0x7004 261 | #define REG_TRACKER_2 0x7008 262 | #define REG_TRACKER_3 0x700C 263 | #define REG_TRACKER_4 0x7010 264 | #define REG_MEDIAFIFO_READ 0x7014 265 | #define REG_MEDIAFIFO_WRITE 0x7018 266 | #define REG_PLAY_CONTROL 0x714E 267 | 268 | // Flash related registers 269 | #define REG_FLASH_STATUS 0x5F0 270 | #define REG_FLASH_SIZE 0x7024 271 | 272 | // Miscellaneous Registers - FT81x Series Programmers Guide Section 3.6 - Document inspecific about base address 273 | // Addresses assumed to be defined as offsets from the base address called RAM_REG and located at 0x302000 274 | #define REG_CPU_RESET 0x20 275 | #define REG_PWM_DUTY 0xD4 276 | #define REG_PWM_HZ 0xD0 277 | #define REG_INT_MASK 0xB0 278 | #define REG_INT_EN 0xAC 279 | #define REG_INT_FLAGS 0xA8 280 | #define REG_GPIO 0x94 281 | #define REG_GPIO_DIR 0x90 282 | #define REG_GPIOX 0x9C 283 | #define REG_GPIOX_DIR 0x98 284 | #define REG_FREQUENCY 0x0C 285 | #define REG_CLOCK 0x08 286 | #define REG_FRAMES 0x04 287 | #define REG_ID 0x00 288 | #define REG_TRIM 0x10256C 289 | #define REG_SPI_WIDTH 0x180 290 | #define REG_CHIP_ID 0xC0000 // Temporary Chip ID location in RAMG 291 | 292 | // Primitive Type Reference Definitions - FT81x Series Programmers Guide Section 4.5 - Table 6 293 | #define BITMAPS 1 294 | #define POINTS 2 295 | #define LINES 3 296 | #define LINE_STRIP 4 297 | #define EDGE_STRIP_R 5 298 | #define EDGE_STRIP_L 6 299 | #define EDGE_STRIP_A 7 300 | #define EDGE_STRIP_B 8 301 | #define RECTS 9 302 | 303 | // Bitmap Layout Format Definitions - FT81x Series Programmers Guide Section 4.7 - Table 7 304 | #define ARGB1555 0 305 | #define L1 1 306 | #define L4 2 307 | #define L8 3 308 | #define RGB332 4 309 | #define ARGB2 5 310 | #define ARGB4 6 311 | #define RGB565 7 312 | #define TEXT8X8 9 313 | #define TEXTVGA 10 314 | #define BARGRAPH 11 315 | #define PALETTED565 14 316 | #define PALETTED4444 15 317 | #define PALETTED8 16 318 | #define L2 17 319 | 320 | // Bitmap Layout Format Definitions - BT81X Series Programming Guide Section 4.6 321 | #define COMPRESSED_RGBA_ASTC_4x4_KHR 37808 // 8.00 322 | #define COMPRESSED_RGBA_ASTC_5x4_KHR 37809 // 6.40 323 | #define COMPRESSED_RGBA_ASTC_5x5_KHR 37810 // 5.12 324 | #define COMPRESSED_RGBA_ASTC_6x5_KHR 37811 // 4.27 325 | #define COMPRESSED_RGBA_ASTC_6x6_KHR 37812 // 3.56 326 | #define COMPRESSED_RGBA_ASTC_8x5_KHR 37813 // 3.20 327 | #define COMPRESSED_RGBA_ASTC_8x6_KHR 37814 // 2.67 328 | #define COMPRESSED_RGBA_ASTC_8x8_KHR 37815 // 2.56 329 | #define COMPRESSED_RGBA_ASTC_10x5_KHR 37816 // 2.13 330 | #define COMPRESSED_RGBA_ASTC_10x6_KHR 37817 // 2.00 331 | #define COMPRESSED_RGBA_ASTC_10x8_KHR 37818 // 1.60 332 | #define COMPRESSED_RGBA_ASTC_10x10_KHR 37819 // 1.28 333 | #define COMPRESSED_RGBA_ASTC_12x10_KHR 37820 // 1.07 334 | #define COMPRESSED_RGBA_ASTC_12x12_KHR 37821 // 0.89 335 | 336 | // Bitmap Parameters 337 | #define REPEAT 1 338 | #define BORDER 0 339 | #define NEAREST 0 340 | #define BILINEAR 1 341 | 342 | // Flash Status 343 | #define FLASH_STATUS_INIT 0UL 344 | #define FLASH_STATUS_DETACHED 1UL 345 | #define FLASH_STATUS_BASIC 2UL 346 | #define FLASH_STATUS_FULL 3UL 347 | 348 | 349 | // These defined "macros" are supplied by FTDI - Manufacture command bit-fields from parameters 350 | // FT81x Series Programmers Guide is refered to as "FT-PG" 351 | #define CLEAR(c,s,t) ((38UL<<24)|(((c)&1UL)<<2)|(((s)&1UL)<<1)|(((t)&1UL)<<0)) // CLEAR - FT-PG Section 4.21 352 | #define CLEAR_COLOR_RGB(red,green,blue) ((2UL<<24)|(((red)&255UL)<<16)|(((green)&255UL)<<8)|(((blue)&255UL)<<0)) // CLEAR_COLOR_RGB - FT-PG Section 4.23 353 | #define COLOR_RGB(red,green,blue) ((4UL<<24)|(((red)&255UL)<<16)|(((green)&255UL)<<8)|(((blue)&255UL)<<0)) // COLOR_RGB - FT-PG Section 4.28 354 | #define VERTEX2II(x,y,handle,cell) ((2UL<<30)|(((x)&511UL)<<21)|(((y)&511UL)<<12)|(((handle)&31UL)<<7)|(((cell)&127UL)<<0)) // VERTEX2II - FT-PG Section 4.48 355 | #define VERTEX2F(x,y) ((1UL<<30)|(((x)&32767UL)<<15)|(((y)&32767UL)<<0)) // VERTEX2F - FT-PG Section 4.47 356 | #define VERTEXFORMAT(frac) ((39UL<<24)|(frac)) // VERTEXFORMAT - FT-PG Section 4.51 357 | #define CELL(cell) ((6UL<<24)|(((cell)&127UL)<<0)) // CELL - FT-PG Section 4.20 358 | #define BITMAP_HANDLE(handle) ((5UL<<24) | (((handle) & 31UL) << 0)) // BITMAP_HANDLE - FT-PG Section 4.06 359 | #define BITMAP_SOURCE(addr) ((1UL<<24)|(((addr)&1048575UL)<<0)) // BITMAP_SOURCE - FT-PG Section 4.11 360 | #define BITMAP_LAYOUT(format,linestride,height) ((7UL<<24)|(((format)&31UL)<<19)|(((linestride)&1023UL)<<9)|(((height)&511UL)<<0)) // BITMAP_LAYOUT - FT-PG Section 4.07 361 | #define BITMAP_LAYOUT2(linestride,height) ((28UL<<24)|(((linestride >> 10)&3) << 2) | ((height >>9) & 3)) 362 | #define BITMAP_SIZE(filter,wrapx,wrapy,width,height) ((8UL<<24)|(((filter)&1UL)<<20)|(((wrapx)&1UL)<<19)|(((wrapy)&1UL)<<18)|(((width)&511UL)<<9)|(((height)&511UL)<<0)) // BITMAP_SIZE - FT-PG Section 4.09 363 | #define TAG(s) ((3UL<<24)|(((s)&255UL)<<0)) // TAG - FT-PG Section 4.43 364 | #define POINT_SIZE(sighs) ((13UL<<24)|(((sighs)&8191UL)<<0)) // POINT_SIZE - FT-PG Section 4.36 365 | #define LINE_WIDTH(width) ((14UL<<24)|(((width)&8191UL)<<0)) // POINT_SIZE - FT-PG Section 4.36 366 | #define BEGIN(PrimitiveTypeRef) ((31UL<<24)|(((PrimitiveTypeRef)&15UL)<<0)) // BEGIN - FT-PG Section 4.05 367 | #define END() ((33UL<<24)) // END - FT-PG Section 4.30 368 | #define DISPLAY() ((0UL<<24)) // DISPLAY - FT-PG Section 4.29 369 | 370 | // Non FTDI Helper Macros 371 | #define MAKE_COLOR(r,g,b) (( r << 16) | ( g << 8) | (b)) 372 | 373 | // Global Variables 374 | extern uint16_t FifoWriteLocation; 375 | 376 | // Function Prototypes 377 | int EVE_EXPORT FT81x_Init(int display, int board, int touch); 378 | void EVE_EXPORT Eve_Reset(void); 379 | void EVE_EXPORT Cap_Touch_Upload(void); 380 | 381 | void EVE_EXPORT HostCommand(uint8_t HostCommand); 382 | void EVE_EXPORT wr32(uint32_t address, uint32_t parameter); 383 | void EVE_EXPORT wr16(uint32_t, uint16_t parameter); 384 | void EVE_EXPORT wr8(uint32_t, uint8_t parameter); 385 | uint8_t EVE_EXPORT rd8(uint32_t RegAddr); 386 | uint16_t EVE_EXPORT rd16(uint32_t RegAddr); 387 | uint32_t EVE_EXPORT rd32(uint32_t RegAddr); 388 | void EVE_EXPORT Send_CMD(uint32_t data); 389 | void EVE_EXPORT UpdateFIFO(void); 390 | uint8_t EVE_EXPORT Cmd_READ_REG_ID(void); 391 | 392 | // Widgets and other significant screen objects 393 | void EVE_EXPORT Cmd_Slider(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t options, uint16_t val, uint16_t range); 394 | void EVE_EXPORT Cmd_Spinner(uint16_t x, uint16_t y, uint16_t style, uint16_t scale); 395 | void EVE_EXPORT Cmd_Gauge(uint16_t x, uint16_t y, uint16_t r, uint16_t options, uint16_t major, uint16_t minor, uint16_t val, uint16_t range); 396 | void EVE_EXPORT Cmd_Dial(uint16_t x, uint16_t y, uint16_t r, uint16_t options, uint16_t val); 397 | void EVE_EXPORT Cmd_Track(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t tag); 398 | void EVE_EXPORT Cmd_Number(uint16_t x, uint16_t y, uint16_t font, uint16_t options, uint32_t num); 399 | void EVE_EXPORT Cmd_Gradient(uint16_t x0, uint16_t y0, uint32_t rgb0, uint16_t x1, uint16_t y1, uint32_t rgb1); 400 | void EVE_EXPORT Cmd_Button(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t font, uint16_t options, const char* str); 401 | void EVE_EXPORT Cmd_Text(uint16_t x, uint16_t y, uint16_t font, uint16_t options, const char* str); 402 | 403 | void EVE_EXPORT Cmd_SetBitmap(uint32_t addr, uint16_t fmt, uint16_t width, uint16_t height); 404 | void EVE_EXPORT Cmd_Memcpy(uint32_t dest, uint32_t src, uint32_t num); 405 | void EVE_EXPORT Cmd_GetPtr(void); 406 | void EVE_EXPORT Cmd_GradientColor(uint32_t c); 407 | void EVE_EXPORT Cmd_FGcolor(uint32_t c); 408 | void EVE_EXPORT Cmd_BGcolor(uint32_t c); 409 | void EVE_EXPORT Cmd_Translate(uint32_t tx, uint32_t ty); 410 | void EVE_EXPORT Cmd_Rotate(uint32_t a); 411 | void EVE_EXPORT Cmd_SetRotate(uint32_t rotation); 412 | void EVE_EXPORT Cmd_Scale(uint32_t sx, uint32_t sy); 413 | void EVE_EXPORT Cmd_Calibrate(uint32_t result); 414 | void EVE_EXPORT Cmd_Flash_Fast(void); 415 | 416 | void EVE_EXPORT Cmd_AnimStart(int32_t ch, uint32_t aoptr, uint32_t loop); 417 | void EVE_EXPORT Cmd_AnimStop(int32_t ch); 418 | void EVE_EXPORT Cmd_AnimXY(int32_t ch, int16_t x, int16_t y); 419 | void EVE_EXPORT Cmd_AnimDraw(int32_t ch); 420 | void EVE_EXPORT Cmd_AnimDrawFrame(int16_t x, int16_t y, uint32_t aoptr, uint32_t frame); 421 | 422 | void EVE_EXPORT Calibrate_Manual(uint16_t Width, uint16_t Height, uint16_t V_Offset, uint16_t H_Offset); 423 | 424 | uint16_t EVE_EXPORT CoProFIFO_FreeSpace(void); 425 | void EVE_EXPORT Wait4CoProFIFO(uint32_t room); 426 | void EVE_EXPORT Wait4CoProFIFOEmpty(void); 427 | void EVE_EXPORT StartCoProTransfer(uint32_t address, uint8_t reading); 428 | void EVE_EXPORT CoProWrCmdBuf(const uint8_t *buffer, uint32_t count); 429 | uint32_t EVE_EXPORT WriteBlockRAM(uint32_t Add, const uint8_t *buff, uint32_t count); 430 | int32_t EVE_EXPORT CalcCoef(int32_t Q, int32_t K); 431 | uint32_t EVE_EXPORT Display_Width(); 432 | uint32_t EVE_EXPORT Display_Height(); 433 | uint8_t EVE_EXPORT Display_Touch(); 434 | uint32_t EVE_EXPORT Display_HOffset(); 435 | uint32_t EVE_EXPORT Display_VOffset(); 436 | 437 | /* Flash commands */ 438 | bool EVE_EXPORT FlashAttach(void); 439 | bool EVE_EXPORT FlashDetach(void); 440 | bool EVE_EXPORT FlashFast(void); 441 | bool EVE_EXPORT FlashErase(void); 442 | 443 | #if defined(EVE_MO_INTERNAL_BUILD) 444 | void EVE_EXPORT EVE_SPI_Enable(void); 445 | void EVE_EXPORT EVE_SPI_Disable(void); 446 | uint8_t EVE_EXPORT EVE_SPI_Write(uint8_t data); 447 | void EVE_EXPORT EVE_SPI_WriteBuffer(uint8_t *Buffer, uint32_t Length); 448 | #endif 449 | 450 | #ifdef __cplusplus 451 | } 452 | #endif 453 | 454 | #endif 455 | -------------------------------------------------------------------------------- /MatrixEve2Conf.h: -------------------------------------------------------------------------------- 1 | #define DISPLAY_70 1 2 | #define DISPLAY_50 2 3 | #define DISPLAY_43 3 4 | #define DISPLAY_39 4 5 | #define DISPLAY_38 5 6 | #define DISPLAY_35 6 7 | #define DISPLAY_29 7 8 | #define DISPLAY_40 8 9 | #define DISPLAY_101 9 10 | 11 | #define BOARD_EVE2 1 12 | #define BOARD_EVE3 2 13 | #define BOARD_EVE4 3 14 | 15 | #define TOUCH_TPN 0 16 | #define TOUCH_TPR 1 17 | #define TOUCH_TPC 2 18 | 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRICATED 2 | ## This library has been archived, please use the new one here: 3 | ## https://github.com/MatrixOrbital/EVE-Library 4 | 5 | 6 | 7 | A C library for a [Matrix Orbital EVE2, EVE3 or EVE4](https://www.matrixorbital.com/ftdi-eve) SPI TFT displays. 8 | 9 | ![alt text](https://www.matrixorbital.com/image/cache/catalog/products/EVE/EVE3-43G-300x300.jpg) 10 | 11 | - [Matrix Orbital Support Forums](http://www.lcdforums.com/forums/viewforum.php?f=45) 12 | - [Matrix Orbital EVE SPI TFT display information](https://www.matrixorbital.com/ftdi-eve) 13 | - [EVE2 FT812 & FT813 Programming Guide](https://brtchip.com/wp-content/uploads/Support/Documentation/Programming_Guides/ICs/EVE/FT81X_Series_Programmer_Guide.pdf) 14 | - [EVE3/4 BT815 & BT816 & BT817 & BT818 Programming Guide](https://brtchip.com/wp-content/uploads/Support/Documentation/Programming_Guides/ICs/EVE/BRT_AN_033_BT81X_Series_Programming_Guide.pdf) 15 | - [EVE Tool Chain](https://brtchip.com/eve-toolchains/) 16 | 17 | Supports 18 | - EVE2 FT812 & FT813 19 | - EVE3 BT815 & BT816 20 | - EVE4 BT817 & BT818 21 | 22 | For a quick and easy sanity check to ensure that your Matrix Orbital EVE2, EVE3 or EVE4 SPI TFT Display and touch hardware works properly try this: 23 | 24 | https://github.com/MatrixOrbital/Basic-EVE-Demo 25 | -------------------------------------------------------------------------------- /basic_eve_demo.c: -------------------------------------------------------------------------------- 1 | #ifdef _MSC_VER 2 | # include 3 | #endif 4 | #include "Eve2_81x.h" 5 | #include "hw_api.h" 6 | #include "MatrixEve2Conf.h" 7 | 8 | //MakeScreen_MatrixOrbital draws a blue dot in the center screen, along 9 | //with the text "MATRIX ORBITAL" 10 | void MakeScreen_MatrixOrbital(uint8_t DotSize) 11 | { 12 | Send_CMD(CMD_DLSTART); //Start a new display list 13 | Send_CMD(VERTEXFORMAT(0)); //setup VERTEX2F to take pixel coordinates 14 | Send_CMD(CLEAR_COLOR_RGB(0, 0, 0)); //Determine the clear screen color 15 | Send_CMD(CLEAR(1, 1, 1)); //Clear the screen and the curren display list 16 | Send_CMD(COLOR_RGB(26, 26, 192)); // change colour to blue 17 | Send_CMD(POINT_SIZE(DotSize * 16)); // set point size to DotSize pixels. Points = (pixels x 16) 18 | Send_CMD(BEGIN(POINTS)); // start drawing point 19 | Send_CMD(TAG(1)); // Tag the blue dot with a touch ID 20 | Send_CMD(VERTEX2F(Display_Width() / 2, Display_Height() / 2)); // place blue point 21 | Send_CMD(END()); // end drawing point 22 | Send_CMD(COLOR_RGB(255, 255, 255)); //Change color to white for text 23 | Cmd_Text(Display_Width() / 2, Display_Height() / 2, 30, OPT_CENTER, " MATRIX ORBITAL"); //Write text in the center of the screen 24 | Send_CMD(DISPLAY()); //End the display list 25 | Send_CMD(CMD_SWAP); //Swap commands into RAM 26 | UpdateFIFO(); // Trigger the CoProcessor to start processing the FIFO 27 | } 28 | 29 | 30 | // A calibration screen for the touch digitizer 31 | void Calibrate(void) 32 | { 33 | Calibrate_Manual(Display_Width(), Display_Height(), Display_VOffset(), Display_HOffset()); 34 | } 35 | 36 | // A Clear screen function 37 | void ClearScreen(void) 38 | { 39 | Send_CMD(CMD_DLSTART); 40 | Send_CMD(CLEAR_COLOR_RGB(0, 0, 0)); 41 | Send_CMD(CLEAR(1, 1, 1)); 42 | Send_CMD(DISPLAY()); 43 | Send_CMD(CMD_SWAP); 44 | UpdateFIFO(); // Trigger the CoProcessor to start processing commands out of the FIFO 45 | Wait4CoProFIFOEmpty(); // wait here until the coprocessor has read and executed every pending command. 46 | HAL_Delay(10); 47 | } 48 | 49 | int main() 50 | { 51 | FT81x_Init(DISPLAY_101, BOARD_EVE3, TOUCH_TPN); //Initialize the EVE graphics controller. 52 | ClearScreen(); //Clear any remnants in the RAM 53 | if (Display_Touch() == TOUCH_TPR) 54 | { 55 | Calibrate(); 56 | } 57 | 58 | MakeScreen_MatrixOrbital(30); //Draw the Matrix Orbital Screen 59 | uint8_t pressed = 0; 60 | 61 | while (1) 62 | { 63 | #ifdef _MSC_VER 64 | if (_kbhit()) 65 | break; 66 | #endif 67 | uint8_t Tag = rd8(REG_TOUCH_TAG + RAM_REG); //Check for touches 68 | switch (Tag) 69 | { 70 | case 1: 71 | if (!pressed) 72 | { 73 | MakeScreen_MatrixOrbital(120); //Blue dot is 120 when touched 74 | pressed = 1; 75 | } 76 | break; 77 | default: 78 | if (pressed) 79 | { 80 | pressed = 0; 81 | MakeScreen_MatrixOrbital(30); //Blue dot size is 30 when not touched 82 | } 83 | break; 84 | } 85 | } 86 | HAL_Close(); 87 | } 88 | -------------------------------------------------------------------------------- /hw_api.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include 8 | #include 9 | 10 | /* HAL_SPI_Enable() is to drive the CS Pin to the eve HIGH */ 11 | void HAL_SPI_Enable(void); 12 | 13 | /* HAL_SPI_Disable() is to drive the CS Pin to the eve LOW */ 14 | void HAL_SPI_Disable(void); 15 | 16 | /* HAL_SPI_Write(uint8_t data) does a single byte SPI write transfer */ 17 | uint8_t HAL_SPI_Write(uint8_t data); 18 | 19 | /* HAL_SPI_WriteBuffer does a buffer based SPI Write transfer */ 20 | void HAL_SPI_WriteBuffer(uint8_t *Buffer, uint32_t Length); 21 | 22 | /* HAL_SPI_WriteBuffer does a buffer based SPI Read transfer */ 23 | void HAL_SPI_ReadBuffer(uint8_t *Buffer, uint32_t Length); 24 | 25 | /* Stall the cpu for X milliseconds */ 26 | void HAL_Delay(uint32_t milliSeconds); 27 | 28 | /* Gives an opertunity to reset the EVE hardware */ 29 | void HAL_Eve_Reset_HW(void); 30 | 31 | /* Cleans up and resources allocated */ 32 | void HAL_Close(void); 33 | 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MatrixOrbital/EVE2-Library/44deba4b9420ccbd986385e48e78507d3fa78804/license.txt -------------------------------------------------------------------------------- /touch_cap_811.h: -------------------------------------------------------------------------------- 1 | // Touch-configuration code: 811-cap-100 2 | 3 | #define TOUCH_TARGET "811" 4 | #define TOUCH_FUNCTION "cap" 5 | #define TOUCH_VERSION "100" 6 | 7 | #define TOUCH_DATA_LEN 1216 8 | 9 | #define TOUCH_DATA_U8 \ 10 | 26,255,255,255,32,32,48,0,4,0,0,0,2,0,0,0,34,255,255,255,0,176,48,0,120,218,237,84,221,111,84,69,20,63,51,179,93,160,148,101,111,76,5,44,141,123,111,161,11,219,154,16,9,16,17,229,156,75,26,11,13,21,227,3,16,252,184,179,45,219,143,45,41,125,144,72,67,100,150,71,189,113,18,36,17,165,100,165,198,16,32,17,149,196,240,128,161,16,164,38,54,240,0,209,72,130,15,38,125,48,66,82,30,76,19,31,172,103,46,139,24,255,4,227,157,204,156,51,115,102,206,231,239,220,5,170,94,129,137,75,194,216,98,94,103,117,115,121,76,131,177,125,89,125,82,123,60,243,58,142,242,204,185,243,188,118,156,227,155,203,238,238,195,251,205,229,71,92,28,169,190,184,84,143,113,137,53,244,103,181,237,87,253,113,137,233,48,12,198,165,181,104,139,25,84,253,155,114,74,191,0,54,138,163,12,62,131,207,129,23,217,34,91,31,128,65,246,163,175,213,8,147,213,107,35,203,94,108,3,111,40,171,83,24,15,165,177,222,116,97,23,188,140,206,150,42,102,181,87,78,86,182,170,134,215,241,121,26,243,252,2,76,115,217,139,222,206,173,136,132,81,61,35,185,39,113,23,46,199,76,178,54,151,183,224,0,40,189,28,149,182,58,131,79,152,30,76,34,98,234,162,216,133,141,102,39,170,40,192,101,53,201,146,191,37,77,44,177,209,74,211,5,206,187,5,6,216,47,53,96,123,22,50,103,251,192,84,17,74,227,185,56,106,51,91,161,96,182,163,48,171,141,139,65,152,66,66,11,102,43,158,75,36,80,147,184,147,139,112,17,235,216,103,111,239,245,92,10,175,194,40,44,58,125,5,59,112,50,103,245,4,78,192,5,156,194,51,60,191,134,75,110,173,237,46,192,121,156,192,115,184,218,120,67,63,115,46,11,102,10,97,232,50,235,114,182,148,118,178,41,188,12,135,77,202,124,12,96,238,35,161,234,189,129,23,249,212,139,230,25,53,48,205,52,93,163,117,53,154,170,81,85,163,178,70,69,66,167,241,14,46,241,1,226,136,152,179,197,59,184,148,254,49,132,48,15,176,137,192,76,131,196,105,104,162,86,81,160,165,255,26,173,162,137,86,145,210,183,192,55,175,194,211,60,91,120,230,184,174,27,41,131,155,40,224,29,87,179,232,16,55,55,7,165,147,81,23,165,49,101,54,224,75,180,81,108,18,29,226,69,225,110,175,224,42,212,25,47,130,193,110,234,192,215,252,56,74,162,24,46,251,174,54,106,68,245,14,9,155,160,22,120,207,104,240,29,90,178,140,28,24,220,47,166,112,61,251,208,192,111,56,239,238,93,255,251,62,99,32,193,75,61,190,235,123,229,110,218,194,85,79,225,59,98,20,238,227,235,220,11,221,149,25,180,116,194,159,111,96,192,24,213,59,139,179,156,215,69,230,19,24,35,135,117,206,171,206,162,67,129,234,61,235,11,104,103,84,64,223,167,254,40,163,101,92,84,43,150,46,249,219,205,7,116,11,91,104,61,57,75,223,8,48,25,28,119,252,222,113,49,86,249,74,180,211,156,181,61,215,168,157,7,251,199,150,242,250,91,58,132,94,121,7,53,151,139,98,6,165,153,69,214,32,110,211,100,101,31,89,45,81,98,23,205,205,197,209,109,186,198,35,141,191,249,25,60,132,223,153,251,98,20,239,146,139,20,217,250,41,250,137,58,177,90,57,79,51,108,233,20,253,194,187,49,222,205,114,141,96,48,175,219,107,54,111,138,22,154,103,108,79,58,252,179,178,79,164,195,2,153,36,39,170,199,201,167,197,85,106,8,59,177,81,46,56,2,230,75,114,17,55,112,188,65,208,137,77,114,10,115,55,58,208,197,173,122,87,6,140,110,42,208,124,163,70,108,241,104,18,245,98,214,187,134,53,42,221,22,182,133,211,116,148,177,194,209,192,85,90,199,58,55,203,2,229,19,137,187,161,228,154,112,203,145,125,244,188,220,118,228,41,201,181,41,195,144,215,183,51,80,250,21,217,16,217,200,235,109,227,188,122,218,142,60,170,224,112,240,184,130,229,224,113,5,223,148,163,80,165,183,130,187,132,116,64,238,161,85,220,115,139,205,98,227,244,29,102,125,7,37,243,123,223,11,26,92,63,243,116,61,191,138,123,244,160,84,186,74,31,5,174,247,119,135,199,248,253,135,242,97,102,145,190,144,14,85,238,221,231,193,158,48,205,25,120,248,15,220,29,158,9,70,185,30,103,229,33,254,23,237,160,172,62,193,90,222,224,232,14,200,56,90,104,142,227,120,110,6,21,211,203,65,150,99,151,220,247,87,164,50,159,49,239,234,58,142,0,109,108,123,18,79,227,36,100,248,222,205,96,127,120,26,171,228,69,63,36,17,252,200,17,116,242,187,227,88,143,247,2,75,191,6,130,59,188,11,55,240,31,243,122,152,226,183,207,154,73,188,39,219,43,105,222,87,41,143,141,140,175,73,112,184,252,61,184,16,90,250,35,168,82,119,176,57,116,94,200,150,22,190,179,44,104,12,235,84,149,102,252,89,154,193,99,228,106,242,125,248,64,194,255,223,127,242,83,11,255,2,70,214,226,128,0,0,26,255,255,255,20,33,48,0,4,0,0,0,15,0,0,0,26,255,255,255,32,32,48,0,4,0,0,0,0,0,0,0 11 | 12 | #define TOUCH_DATA_U32 \ 13 | 0xffffff1a, 0x00302020, 0x00000004, 0x00000002, 0xffffff22,\ 14 | 0x0030b000, 0x54edda78, 0x45546fdd, 0xb3333f14, 0x6594a05d,\ 15 | 0x2c054c6f, 0xa16f7b8d, 0x109adb0b, 0xe5111009, 0x0b1a4b9c,\ 16 | 0x03e3150d, 0xb3b8fc10, 0x2d8fdb2d, 0x48907d29, 0x47966443,\ 17 | 0x241271bd, 0xa564a511, 0x112010c6, 0x80f0c495, 0x26a410a1,\ 18 | 0xd100f036, 0x260f8248, 0x5242307d, 0x1f134c1e, 0x8b2e67ac,\ 19 | 0xe304ff18, 0x339ccc9d, 0xe7ce6673, 0xaa05dcef, 0x4b89815e,\ 20 | 0x5e62d8c2, 0x79737567, 0x7db1834c, 0x7b527d59, 0x8e3af33c,\ 21 | 0xf3b9ccf2, 0xe39c76bc, 0xeeeecb9b, 0xe5cdfbc3, 0xa91c5c47,\ 22 | 0x8f54b8be, 0xf4358971, 0x57edb567, 0xe98971fd, 0xa5c60c30,\ 23 | 0x198b68b5, 0x729bfd54, 0x3600bf4a, 0x3e0ca38a, 0x1781cf83,\ 24 | 0x1f5b22d9, 0xa3f64180, 0x9308d5af, 0xcb236bd5, 0x6f036c5e,\ 25 | 0x1853ab28, 0xdeb1a50f, 0xbc176174, 0x2a96ce8c, 0x4e57b566,\ 26 | 0x86aab656, 0x1a79f1d7, 0x4c02fcf3, 0xde8bd973, 0x8488adce,\ 27 | 0xb9233d51, 0x2e177127, 0x36b24cc7, 0x00e0b797, 0x951cbd28,\ 28 | 0x4f833ab6, 0x224c1e98, 0xd8a2ea62, 0x27668d85, 0x65c028aa,\ 29 | 0xbf92c935, 0xb12c4d25, 0x05d34ad1, 0x0605bbce, 0x60352fd8,\ 30 | 0x6732167b, 0x1154c0fb, 0x38b9e34a, 0xa15b336a, 0x30a3b660,\ 31 | 0x418b8dab, 0x0b424298, 0x4b9e2b66, 0xb8935024, 0x11708b93,\ 32 | 0x6f67d8eb, 0x0a5cf5ef, 0x2c28c2af, 0x3b057d3a, 0xf5673270,\ 33 | 0x05c04e04, 0x3c33c29c, 0x6e4b86bf, 0xc02eedad, 0x73c09c79,\ 34 | 0x4378dab8, 0x0b2e733f, 0xe8610a66, 0xb672eb32, 0x29b27694,\ 35 | 0x4d870cbc, 0x600c7cca, 0xeaa123ee, 0xf91781bd, 0x19e68bd4,\ 36 | 0x34cd3035, 0x3575a35d, 0x5551aa9a, 0x4546b2a3, 0x0ef1a742,\ 37 | 0xe201f12e, 0xc5b39888, 0xfe94b83b, 0x0f308431, 0x4cc089b0,\ 38 | 0x6869c483, 0xa05156a2, 0xad1affa5, 0x915689a2, 0x37c0b7d2,\ 39 | 0x3cd3c2af, 0xb8e6785b, 0x83291bae, 0x1de0289b, 0x10e8b357,\ 40 | 0xa5073737, 0xa5175193, 0xe0366531, 0x6c51b44b, 0x45e21d12,\ 41 | 0xe0af6ee1, 0x2f19d42a, 0xea6ec182, 0x38fcd7c0, 0x2e18a24a,\ 42 | 0x6a36aefb, 0x090ef544, 0x7816a09b, 0x1df068cf, 0x1c8cb25a,\ 43 | 0xa62fdc18, 0xd0fb3d70, 0xef386fc0, 0xfbff5dee, 0xc120633e,\ 44 | 0xebbe3d4b, 0xda6ee57b, 0xe14f55c2, 0xee14623b, 0x0bdcebe3,\ 45 | 0xb41995dd, 0x6f9fc274, 0xd518c060, 0x9cb38b3b, 0x13e645d7,\ 46 | 0x75872318, 0xa2ceabce, 0x3dea8143, 0x67680beb, 0xa7df4054,\ 47 | 0x65a328fe, 0x962b545c, 0xcddbf92e, 0x5b0b7407, 0x4b393d68,\ 48 | 0x193008df, 0xdefc771c, 0xf9563171, 0x9cd3b44a, 0xa8d73db5,\ 49 | 0xc7fb079d, 0x5bfaf296, 0x795e843a, 0x8b973507, 0x99a50662,\ 50 | 0x6e20d645, 0x1f6564d3, 0x62512d59, 0xc5cdcd17, 0xc6ba6dd1,\ 51 | 0xf9bf8d23, 0xdf843c19, 0x1462fb99, 0x148b92ef, 0xfa29fad9,\ 52 | 0x5ab13a89, 0x6c334f39, 0xc2fd14e9, 0xcdde31bb, 0x30608d72,\ 53 | 0x366bdbaf, 0x9a168a6f, 0x3a4f6c67, 0x4fb2b3fc, 0x9902c3a4,\ 54 | 0xc7aa2724, 0x55c5a7c9, 0xb13b086a, 0x02382e51, 0x11724be6,\ 55 | 0x41bc7037, 0x724d89d0, 0x3a37730a, 0x7aadc5d0, 0x6e8c0657,\ 56 | 0xa37cd02a, 0x68f16c46, 0xd662f512, 0x2a3586bb, 0x85b616dd,\ 57 | 0xb19474d3, 0x55c0d1c2, 0x373ac75a, 0x13e502cb, 0xe4a1bb89,\ 58 | 0x91cb709a, 0xdcbcf47d, 0xc929e476, 0x90c329b5, 0x5033b7d7,\ 59 | 0x10d915fa, 0x6debc8d9, 0xda7abce3, 0xe0aa3c8e, 0x82b8f070,\ 60 | 0x0571e0e5, 0x50a394df, 0xbb82b7a5, 0xee407484, 0x73dc55a1,\ 61 | 0xe362cd8b, 0x7d661df4, 0x7bf32507, 0x5c1a0bdf, 0x3d74f33f,\ 62 | 0xf47b8abf, 0x4aba54a0, 0xf7ae051f, 0xf8c78777, 0x61f287fd,\ 63 | 0x90be9166, 0xddee550e, 0x309ec1e7, 0xf87819cd, 0x9e1ddc0f,\ 64 | 0x1eb94609, 0xfe21e567, 0xaca0ed17, 0xde5ac13e, 0xc80ee8e0,\ 65 | 0x8e685a38, 0x066e78e3, 0x41cbd315, 0xdc976396, 0x32a457f7,\ 66 | 0xeaef319f, 0x6d008e3a, 0x4f127b6c, 0xf86424e3, 0x7f60cdde,\ 67 | 0xe4ab1a78, 0x11243f45, 0x7411c8fc, 0x58e3bbf2, 0x4b02f78f,\ 68 | 0x3b8206bf, 0xf0370bbc, 0x987af31f, 0x9acfb7e2, 0xdb27bc49,\ 69 | 0x57de692b, 0x8c8d8f29, 0xb87049af, 0x10b83dfc, 0xa823fa5a,\ 70 | 0x39b07752, 0x96c85e74, 0x2cb3be16, 0x54eb0c68, 0x59fc6695,\ 71 | 0xe463c19a, 0xf87df26a, 0xdfffc240, 0x0b53f27f, 0xd64602ff,\ 72 | 0x000080e2, 0xffffff1a, 0x00302114, 0x00000004, 0x0000000f,\ 73 | 0xffffff1a, 0x00302020, 0x00000004, 0x00000000 74 | --------------------------------------------------------------------------------