emuapi.cpp
1 #define KEYMAP_PRESENT 1 2 3 extern "C" { 4 #include "emuapi.h" 5 #include "iopins.h" 6 } 7 8 #include "tft_t_dma.h" 9 #include "logo.h" 10 #include "bmpjoy.h" 11 #include "bmpvbar.h" 12 #ifdef OLD_LAYOUT 13 #include "bmpvga.h" 14 #include "bmptft.h" 15 #endif 16 17 18 #ifdef HAS_I2CKBD 19 #include <Wire.h> 20 #endif 21 22 #ifdef USE_SDFS 23 #include "uSDFS.h" 24 static FATFS fatfs; 25 static FIL file; 26 #else 27 28 #ifdef USE_SDFAT 29 #include "SdFat.h" 30 #include "sdios.h" 31 32 #ifndef SDCARD_SS_PIN 33 const uint8_t SD_CS_PIN = SS; 34 35 #else // SDCARD_SS_PIN 36 // Assume built-in SD is used. 37 const uint8_t SD_CS_PIN = SDCARD_SS_PIN; 38 #endif // SDCARD_SS_PIN 39 40 #define SD_CONFIG SdioConfig(FIFO_SDIO) 41 42 // Try to select the best SD card configuration. 43 #if HAS_SDIO_CLASS 44 #define SD_CONFIG SdioConfig(FIFO_SDIO) 45 #elif ENABLE_DEDICATED_SPI 46 #define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI) 47 #else // HAS_SDIO_CLASS 48 #define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI) 49 #endif // HAS_SDIO_CLASS 50 //------------------------------------------------------------------------------ 51 52 #if SD_FAT_TYPE == 0 53 #elif SD_FAT_TYPE == 1 54 #define SdFat SdFat32 55 #define File File32 56 #elif SD_FAT_TYPE == 2 57 #define SdFat SdExFat 58 #define File ExFile 59 #elif SD_FAT_TYPE == 3 60 #define SdFat SdFs 61 #define File FsFile 62 #endif // SD_FAT_TYPE 63 static SdFat SD; 64 #else 65 #include <SD.h> 66 #endif 67 static File file; 68 #endif 69 70 #define CALIBRATION_FILE "/cal.cfg" 71 72 #define MKEY_L1 1 73 #define MKEY_L2 2 74 #define MKEY_L3 3 75 #define MKEY_L4 4 76 #define MKEY_L5 5 77 #define MKEY_L6 6 78 #define MKEY_L7 7 79 #define MKEY_L8 8 80 #define MKEY_L9 9 81 #define MKEY_UP 20 82 #define MKEY_DOWN 21 83 #define MKEY_JOY 22 84 #define MKEY_TFT 23 85 #define MKEY_VGA 24 86 87 #define MAX_FILES 64 88 #define MAX_FILENAME_SIZE 24 89 #define MAX_MENULINES (MKEY_L9) 90 #define TEXT_HEIGHT 16 91 #define TEXT_WIDTH 8 92 #define MENU_FILE_XOFFSET (6*TEXT_WIDTH) 93 #define MENU_FILE_YOFFSET (2*TEXT_HEIGHT) 94 #define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH) 95 #define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT) 96 #define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x20) 97 #define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT) 98 #define MENU_VBAR_XOFFSET (0*TEXT_WIDTH) 99 #define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET) 100 101 #define MENU_TFT_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) 102 #define MENU_TFT_YOFFSET (MENU_VBAR_YOFFSET+32) 103 #define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) 104 #define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37) 105 106 extern TFT_T_DMA tft; 107 108 static char romspath[64]; 109 static int nbFiles=0; 110 static int curFile=0; 111 static int topFile=0; 112 static char selection[MAX_FILENAME_SIZE+1]=""; 113 static char files[MAX_FILES][MAX_FILENAME_SIZE]; 114 static bool menuRedraw=true; 115 116 static int16_t calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1; 117 static bool i2cKeyboardPresent = false; 118 //const uint16_t deflogo[] = { 119 // 0x0000,0x0000 120 //}; 121 //static const uint16_t * logo = deflogo; 122 static unsigned short * keys; 123 static int keyMap; 124 125 const unsigned short menutouchareas[] = { 126 TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET, 127 TAREA_WH,MENU_FILE_W, TEXT_HEIGHT, 128 TAREA_NEW_COL,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT,TEXT_HEIGHT, 129 130 TAREA_XY,MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET, 131 TAREA_WH,32,48, 132 TAREA_NEW_COL, 72,72,8,40, 133 134 TAREA_XY,MENU_TFT_XOFFSET,MENU_TFT_YOFFSET, 135 TAREA_WH,32,37, 136 TAREA_NEW_COL, 38,38, 137 138 TAREA_END}; 139 140 const unsigned short menutouchactions[] = { 141 MKEY_L1,MKEY_L2,MKEY_L3,MKEY_L4,MKEY_L5,MKEY_L6,MKEY_L7,MKEY_L8,MKEY_L9, 142 MKEY_UP,MKEY_DOWN,ACTION_NONE,MKEY_JOY, 143 MKEY_TFT,MKEY_VGA}; 144 145 146 static int keypadval=0; 147 static boolean joySwapped = false; 148 static uint16_t bLastState; 149 static int xRef; 150 static int yRef; 151 static uint8_t prev_zt=0; 152 153 static bool menuOn=true; 154 static bool callibrationOn=false; 155 static int callibrationStep=0; 156 157 158 static char captureTouchZone(const unsigned short * areas, const unsigned short * actions, int *rx, int *ry, int *rw, int * rh) { 159 uint16_t xt=0; 160 uint16_t yt=0; 161 uint16_t zt=0; 162 boolean hDir=true; 163 164 if (tft.isTouching()) 165 { 166 if (prev_zt == 0) { 167 prev_zt =1; 168 tft.readCal(&xt,&yt,&zt); 169 if (zt<1000) { 170 prev_zt=0; 171 return ACTION_NONE; 172 } 173 int i=0; 174 int k=0; 175 int y2=0, y1=0; 176 int x2=0, x1=0; 177 int x=KEYBOARD_X,y=KEYBOARD_Y; 178 int w=TAREA_W_DEF,h=TAREA_H_DEF; 179 uint8_t s; 180 while ( (s=areas[i++]) != TAREA_END ) { 181 if (s == TAREA_XY) { 182 x = areas[i++]; 183 y = areas[i++]; 184 x2 = x; 185 y2 = y; 186 } 187 else if (s == TAREA_WH) { 188 w = areas[i++]; 189 h = areas[i++]; 190 } 191 else if (s == TAREA_NEW_ROW) { 192 hDir = true; 193 y1 = y2; 194 y2 = y1 + h; 195 x2 = x; 196 } 197 else if (s == TAREA_NEW_COL) { 198 hDir = false; 199 x1 = x2; 200 x2 = x1 + w; 201 y2 = y; 202 } 203 else { 204 if (hDir) { 205 x1 = x2; 206 x2 = x1+s; 207 } else { 208 y1 = y2; 209 y2 = y1+s; 210 } 211 if ( (yt >= y1) && (yt < y2) && (xt >= x1) && (xt < x2) ) { 212 *rx = x1; 213 *ry = y1; 214 *rw = x2-x1; 215 *rh = y2-y1; 216 return (actions[k]); 217 } 218 k++; 219 } 220 } 221 } 222 prev_zt =1; 223 } else { 224 prev_zt=0; 225 } 226 227 return ACTION_NONE; 228 } 229 230 231 232 233 234 235 236 237 void emu_printf(char * text) 238 { 239 Serial.println(text); 240 } 241 242 void emu_printf(int val) 243 { 244 Serial.println(val); 245 } 246 247 void emu_printi(int val) 248 { 249 Serial.println(val,HEX); 250 } 251 252 void emu_printh(int val) 253 { 254 Serial.println(val,HEX); 255 } 256 257 static int malbufpt = 0; 258 static char malbuf[EXTRA_HEAP]; 259 260 void * emu_Malloc(int size) 261 { 262 void * retval = malloc(size); 263 if (!retval) { 264 emu_printf("failled to allocate"); 265 emu_printf(size); 266 emu_printf("fallback"); 267 if ( (malbufpt+size) < sizeof(malbuf) ) { 268 retval = (void *)&malbuf[malbufpt]; 269 malbufpt += size; 270 } 271 else { 272 emu_printf("failure to allocate"); 273 } 274 } 275 else { 276 emu_printf("could allocate dynamic "); 277 emu_printf(size); 278 } 279 280 return retval; 281 } 282 283 void * emu_MallocI(int size) 284 { 285 void * retval = NULL; 286 287 if ( (malbufpt+size) < sizeof(malbuf) ) { 288 retval = (void *)&malbuf[malbufpt]; 289 malbufpt += size; 290 emu_printf("could allocate static "); 291 emu_printf(size); 292 } 293 else { 294 emu_printf("failure to allocate"); 295 } 296 297 return retval; 298 } 299 void emu_Free(void * pt) 300 { 301 free(pt); 302 } 303 304 305 306 307 308 int emu_ReadAnalogJoyX(int min, int max) 309 { 310 int val = analogRead(PIN_JOY2_A1X); 311 #if INVX 312 val = 4095 - val; 313 #endif 314 val = val-xRef; 315 val = ((val*140)/100); 316 if ( (val > -512) && (val < 512) ) val = 0; 317 val = val+2048; 318 return (val*(max-min))/4096; 319 } 320 321 int emu_ReadAnalogJoyY(int min, int max) 322 { 323 int val = analogRead(PIN_JOY2_A2Y); 324 #if INVY 325 val = 4095 - val; 326 #endif 327 val = val-yRef; 328 val = ((val*120)/100); 329 if ( (val > -512) && (val < 512) ) val = 0; 330 //val = (val*(max-min))/4096; 331 val = val+2048; 332 //return val+(max-min)/2; 333 return (val*(max-min))/4096; 334 } 335 336 337 static uint16_t readAnalogJoystick(void) 338 { 339 uint16_t joysval = 0; 340 341 int xReading = emu_ReadAnalogJoyX(0,256); 342 if (xReading > 128) joysval |= MASK_JOY2_LEFT; 343 else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; 344 345 int yReading = emu_ReadAnalogJoyY(0,256); 346 if (yReading < 128) joysval |= MASK_JOY2_UP; 347 else if (yReading > 128) joysval |= MASK_JOY2_DOWN; 348 349 #ifdef PIN_JOY2_BTN 350 joysval |= (digitalRead(PIN_JOY2_BTN) == HIGH ? 0 : MASK_JOY2_BTN); 351 #endif 352 return (joysval); 353 } 354 355 356 int emu_SwapJoysticks(int statusOnly) { 357 if (!statusOnly) { 358 if (joySwapped) { 359 joySwapped = false; 360 } 361 else { 362 joySwapped = true; 363 } 364 } 365 return(joySwapped?1:0); 366 } 367 368 int emu_GetPad(void) 369 { 370 return(keypadval/*|((joySwapped?1:0)<<7)*/); 371 } 372 373 int emu_ReadKeys(void) 374 { 375 uint16_t retval; 376 uint16_t j1 = readAnalogJoystick(); 377 uint16_t j2 = 0; 378 379 // Second joystick 380 #if INVY 381 #ifdef PIN_JOY1_1 382 if ( digitalRead(PIN_JOY1_1) == LOW ) j2 |= MASK_JOY2_DOWN; 383 #endif 384 #ifdef PIN_JOY1_2 385 if ( digitalRead(PIN_JOY1_2) == LOW ) j2 |= MASK_JOY2_UP; 386 #endif 387 #else 388 #ifdef PIN_JOY1_1 389 if ( digitalRead(PIN_JOY1_1) == LOW ) j2 |= MASK_JOY2_UP; 390 #endif 391 #ifdef PIN_JOY1_2 392 if ( digitalRead(PIN_JOY1_2) == LOW ) j2 |= MASK_JOY2_DOWN; 393 #endif 394 #endif 395 #if INVX 396 #ifdef PIN_JOY1_3 397 if ( digitalRead(PIN_JOY1_3) == LOW ) j2 |= MASK_JOY2_LEFT; 398 #endif 399 #ifdef PIN_JOY1_4 400 if ( digitalRead(PIN_JOY1_4) == LOW ) j2 |= MASK_JOY2_RIGHT; 401 #endif 402 #else 403 #ifdef PIN_JOY1_3 404 if ( digitalRead(PIN_JOY1_3) == LOW ) j2 |= MASK_JOY2_RIGHT; 405 #endif 406 #ifdef PIN_JOY1_4 407 if ( digitalRead(PIN_JOY1_4) == LOW ) j2 |= MASK_JOY2_LEFT; 408 #endif 409 #endif 410 #ifdef PIN_JOY1_BTN 411 if ( digitalRead(PIN_JOY1_BTN) == LOW ) j2 |= MASK_JOY2_BTN; 412 #endif 413 if (joySwapped) { 414 retval = ((j1 << 8) | j2); 415 } 416 else { 417 retval = ((j2 << 8) | j1); 418 } 419 420 #ifdef PIN_KEY_USER1 421 if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1; 422 #endif 423 #ifdef PIN_KEY_USER2 424 if ( digitalRead(PIN_KEY_USER2) == LOW ) retval |= MASK_KEY_USER2; 425 #endif 426 #ifdef PIN_KEY_USER3 427 if ( digitalRead(PIN_KEY_USER3) == LOW ) retval |= MASK_KEY_USER3; 428 #endif 429 #ifdef PIN_KEY_USER4 430 if ( digitalRead(PIN_KEY_USER4) == LOW ) retval |= MASK_KEY_USER4; 431 #endif 432 433 //Serial.println(retval,HEX); 434 435 if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) 436 || (retval & MASK_KEY_USER4 ) ) 437 { 438 // Reset procedure T3.X and T4.0 by Frank Boesing !! 439 #if defined(__IMXRT1052__) || defined(__IMXRT1062__) 440 uint32_t tmp = SNVS_LPCR; // save control register 441 442 SNVS_LPSR |= 1; 443 444 // disable alarm 445 SNVS_LPCR &= ~0x02; 446 while (SNVS_LPCR & 0x02); 447 448 __disable_irq(); 449 //get Time: 450 uint32_t lsb, msb; 451 do { 452 msb = SNVS_LPSRTCMR; 453 lsb = SNVS_LPSRTCLR; 454 } while ( (SNVS_LPSRTCLR != lsb) | (SNVS_LPSRTCMR != msb) ); 455 uint32_t secs = (msb << 17) | (lsb >> 15); 456 457 //set alarm 458 secs += 2; 459 SNVS_LPTAR = secs; 460 while (SNVS_LPTAR != secs); 461 462 SNVS_LPCR = tmp | 0x02; // restore control register and set alarm 463 while (!(SNVS_LPCR & 0x02)); 464 465 SNVS_LPCR |= (1 << 6); // turn off power 466 while (1) asm("wfi"); 467 #else 468 *(volatile uint32_t *)0xE000ED0C = 0x5FA0004; 469 while (true) { 470 ; 471 } 472 #endif 473 } 474 475 return (retval); 476 } 477 478 unsigned short emu_DebounceLocalKeys(void) 479 { 480 uint16_t bCurState = emu_ReadKeys(); 481 uint16_t bClick = bCurState & ~bLastState; 482 bLastState = bCurState; 483 484 return (bClick); 485 } 486 487 int emu_ReadI2CKeyboard(void) { 488 int retval=0; 489 #ifdef HAS_I2CKBD 490 if (i2cKeyboardPresent) { 491 byte msg[7]={0,0,0,0,0,0,0}; 492 Wire.requestFrom(8, 7); // request 7 bytes from slave device #8 493 int i = 0; 494 int hitindex=-1; 495 while (Wire.available() && (i<7) ) { // slave may send less than requested 496 byte b = Wire.read(); // receive a byte 497 if (b != 0xff) hitindex=i; 498 msg[i++] = b; 499 } 500 501 if (hitindex >=0 ) { 502 /* 503 Serial.println(msg[0], BIN); 504 Serial.println(msg[1], BIN); 505 Serial.println(msg[2], BIN); 506 Serial.println(msg[3], BIN); 507 Serial.println(msg[4], BIN); 508 Serial.println(msg[5], BIN); 509 Serial.println(msg[6], BIN); 510 */ 511 unsigned short match = (~msg[hitindex])&0x00FF | (hitindex<<8); 512 //Serial.println(match,HEX); 513 for (i=0; i<sizeof(i2ckeys); i++) { 514 if (match == i2ckeys[i]) { 515 //Serial.println((int)keys[i]); 516 return (keys[i]); 517 } 518 } 519 } 520 } 521 #endif 522 return(retval); 523 } 524 525 void emu_InitJoysticks(void) { 526 527 // Second Joystick 528 #ifdef PIN_JOY1_1 529 pinMode(PIN_JOY1_1, INPUT_PULLUP); 530 #endif 531 #ifdef PIN_JOY1_2 532 pinMode(PIN_JOY1_2, INPUT_PULLUP); 533 #endif 534 #ifdef PIN_JOY1_3 535 pinMode(PIN_JOY1_3, INPUT_PULLUP); 536 #endif 537 #ifdef PIN_JOY1_4 538 pinMode(PIN_JOY1_4, INPUT_PULLUP); 539 #endif 540 #ifdef PIN_JOY1_BTN 541 pinMode(PIN_JOY1_BTN, INPUT_PULLUP); 542 #endif 543 544 #ifdef PIN_KEY_USER1 545 pinMode(PIN_KEY_USER1, INPUT_PULLUP); 546 #endif 547 #ifdef PIN_KEY_USER2 548 pinMode(PIN_KEY_USER2, INPUT_PULLUP); 549 #endif 550 #ifdef PIN_KEY_USER3 551 pinMode(PIN_KEY_USER3, INPUT_PULLUP); 552 #endif 553 #ifdef PIN_KEY_USER4 554 pinMode(PIN_KEY_USER4, INPUT_PULLUP); 555 #endif 556 #ifdef PIN_JOY2_BTN 557 pinMode(PIN_JOY2_BTN, INPUT_PULLUP); 558 #endif 559 analogReadResolution(12); 560 xRef=0; yRef=0; 561 for (int i=0; i<10; i++) { 562 xRef += analogRead(PIN_JOY2_A1X); 563 yRef += analogRead(PIN_JOY2_A2Y); 564 delay(20); 565 } 566 567 #if INVX 568 xRef = 4095 -xRef/10; 569 #else 570 xRef /= 10; 571 #endif 572 #if INVY 573 yRef = 4095 -yRef/10; 574 #else 575 yRef /= 10; 576 #endif 577 } 578 579 580 581 static bool vkbKeepOn = false; 582 static bool vkbActive = false; 583 static bool vkeyRefresh=false; 584 static bool exitVkbd = false; 585 static uint8_t keyPressCount=0; 586 587 588 bool virtualkeyboardIsActive(void) { 589 return (vkbActive); 590 } 591 592 void toggleVirtualkeyboard(bool keepOn) { 593 594 if (keepOn) { 595 tft.drawSpriteNoDma(0,0,(uint16_t*)logo); 596 //prev_zt = 0; 597 vkbKeepOn = true; 598 vkbActive = true; 599 exitVkbd = false; 600 } 601 else { 602 vkbKeepOn = false; 603 if ( (vkbActive) /*|| (exitVkbd)*/ ) { 604 tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) ); 605 tft.startDMA(); 606 //prev_zt = 0; 607 vkbActive = false; 608 exitVkbd = false; 609 } 610 else { 611 tft.stopDMA(); 612 tft.drawSpriteNoDma(0,0,(uint16_t*)logo); 613 //prev_zt = 0; 614 vkbActive = true; 615 exitVkbd = false; 616 } 617 } 618 } 619 620 621 void handleVirtualkeyboard() { 622 int rx=0,ry=0,rw=0,rh=0; 623 624 if (keyPressCount == 0) { 625 keypadval = 0; 626 } else { 627 keyPressCount--; 628 } 629 630 if ( (!virtualkeyboardIsActive()) && (tft.isTouching()) && (!keyPressCount) ) { 631 toggleVirtualkeyboard(false); 632 return; 633 } 634 635 if ( ( (vkbKeepOn) || (virtualkeyboardIsActive()) ) ) { 636 char c = captureTouchZone(keysw, keys, &rx,&ry,&rw,&rh); 637 if (c) { 638 639 tft.drawRectNoDma( rx,ry,rw,rh, KEYBOARD_HIT_COLOR ); 640 if ( (c >=1) && (c <= ACTION_MAXKBDVAL) ) { 641 642 keypadval = c; 643 keyPressCount = 10; 644 delay(50); 645 vkeyRefresh = true; 646 exitVkbd = true; 647 } 648 else if (c == ACTION_EXITKBD) { 649 vkeyRefresh = true; 650 exitVkbd = true; 651 } 652 } 653 } 654 655 if (vkeyRefresh) { 656 vkeyRefresh = false; 657 tft.drawSpriteNoDma(0,0,(uint16_t*)logo, rx, ry, rw, rh); 658 } 659 660 if ( (exitVkbd) && (vkbActive) ) { 661 if (!vkbKeepOn) { 662 toggleVirtualkeyboard(false); 663 } 664 else { 665 toggleVirtualkeyboard(true); 666 } 667 } 668 } 669 670 int emu_setKeymap(int index) { 671 if (keyMap == 1) { 672 keyMap = 0; 673 keys = key_map1; 674 tft.drawText(0, 0+16, " 1 I 2 I 3 I 4 I 5 I 6 I 7 I 8 I 9 I 10I", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true); 675 tft.drawText(0,16+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false); 676 tft.drawText(0,24+16, " q I w I e I r I t I y I u I i I o I p I", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), true); 677 tft.drawText(0,40+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), false); 678 tft.drawText(0,48+16, " a I s I d I f I g I h I j I k I l IRTNI", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true); 679 tft.drawText(0,64+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false); 680 tft.drawText(0,72+16, " z I x I c I v I b I n I m I , IDELISPCI", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), true); 681 tft.drawText(0,88+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), false); 682 delay(500); 683 } 684 else if (keyMap == 0) { 685 keyMap = 1; 686 keys = key_map2; 687 tft.drawText(0, 0+16, "F1 IF2 IF3 IF4 IF5 IF6 IF7 IF8 IF9 IF10I", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true); 688 tft.drawText(0,16+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false); 689 tft.drawText(0,24+16, " q I w I e I r I t I y I u I i I o I p I", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), true); 690 tft.drawText(0,40+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), false); 691 tft.drawText(0,48+16, " a I s I d I f I g I h I j I k I l IRTNI", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true); 692 tft.drawText(0,64+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false); 693 tft.drawText(0,72+16, " z I x I c I v I b I n I m I , IDELISPCI", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), true); 694 tft.drawText(0,88+16, "--- --- --- --- --- --- --- --- --- --- ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0x80), false); 695 delay(500); 696 } 697 698 } 699 700 701 702 703 static int readNbFiles(void) { 704 int totalFiles = 0; 705 706 #ifdef USE_SDFS 707 DIR dir; 708 FILINFO entry; 709 f_opendir(&dir, romspath); 710 while ( (true) && (totalFiles<MAX_FILES) ) { 711 f_readdir(&dir, &entry); 712 if (!entry.fname[0]) { 713 // no more files 714 break; 715 } 716 char * filename = entry.fname; 717 Serial.println(filename); 718 if ( !(entry.fattrib & AM_DIR) ) { 719 strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1); 720 totalFiles++; 721 } 722 else { 723 if ( (strcmp(filename,".")) && (strcmp(filename,"..")) ) { 724 strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1); 725 totalFiles++; 726 } 727 } 728 } 729 f_closedir(&dir); 730 #else 731 File entry; 732 file = SD.open(romspath); 733 while ( (true) && (totalFiles<MAX_FILES) ) { 734 entry = file.openNextFile(); 735 if (! entry) { 736 // no more files 737 break; 738 } 739 #ifdef USE_SDFAT 740 char filename[MAX_FILENAME_SIZE]; 741 entry.getName(&filename[0], MAX_FILENAME_SIZE); 742 #else 743 char * filename = entry.name(); 744 #endif 745 Serial.println(filename); 746 if (!entry.isDirectory()) { 747 strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1); 748 totalFiles++; 749 } 750 else { 751 if ( (strcmp(filename,".")) && (strcmp(filename,"..")) ) { 752 strncpy(&files[totalFiles][0], filename, MAX_FILENAME_SIZE-1); 753 totalFiles++; 754 } 755 } 756 entry.close(); 757 } 758 file.close(); 759 #endif 760 return totalFiles; 761 } 762 763 764 765 void backgroundMenu(void) { 766 menuRedraw=true; 767 tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); 768 tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true); 769 tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,(uint16_t*)bmpvbar); 770 #ifdef OLD_LAYOUT 771 tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,(uint16_t*)bmptft); 772 tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,(uint16_t*)bmpvga); 773 #endif 774 } 775 776 int handleMenu(uint16_t bClick) 777 { 778 int action = ACTION_NONE; 779 780 char newpath[80]; 781 strcpy(newpath, romspath); 782 strcat(newpath, "/"); 783 strcat(newpath, selection); 784 785 int rx=0,ry=0,rw=0,rh=0; 786 char c = 0; //captureTouchZone(menutouchareas, menutouchactions, &rx,&ry,&rw,&rh); 787 788 if ( (bClick & MASK_JOY2_BTN) || (c == MKEY_TFT) ) { 789 emu_printf(newpath); 790 #ifdef USE_SDFS 791 FILINFO entry; 792 f_stat(newpath, &entry); 793 if ( (entry.fattrib & AM_DIR) ) { 794 #else 795 File file = SD.open(newpath); 796 if (file.isDirectory()) { 797 #endif 798 strcpy(romspath,newpath); 799 curFile = 0; 800 nbFiles = readNbFiles(); 801 } 802 else { 803 action = ACTION_RUNTFT; 804 } 805 menuRedraw=true; 806 } 807 else if ( (bClick & MASK_KEY_USER1) || (c == MKEY_VGA) ) { 808 menuRedraw=true; 809 action = ACTION_RUNVGA; 810 } 811 else if ( (c >= MKEY_L1) && (c <= MKEY_L9) ) { 812 if ( (topFile+(int)c-1) <= (nbFiles-1) ) 813 { 814 curFile = topFile + (int)c -1; 815 menuRedraw=true; 816 //tft.drawRectNoDma( rx,ry,rw,rh, KEYBOARD_HIT_COLOR ); 817 } 818 } 819 else if (bClick & MASK_JOY2_UP) { 820 if (curFile!=0) { 821 menuRedraw=true; 822 curFile--; 823 } 824 } 825 else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) || (c == MKEY_UP) ) { 826 if ((curFile-9)>=0) { 827 menuRedraw=true; 828 curFile -= 9; 829 } else if (curFile!=0) { 830 menuRedraw=true; 831 curFile--; 832 } 833 } 834 else if (bClick & MASK_JOY2_DOWN) { 835 if ((curFile<(nbFiles-1)) && (nbFiles)) { 836 curFile++; 837 menuRedraw=true; 838 } 839 } 840 else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) || (c == MKEY_DOWN) ) { 841 if ((curFile<(nbFiles-9)) && (nbFiles)) { 842 curFile += 9; 843 menuRedraw=true; 844 } 845 else if ((curFile<(nbFiles-1)) && (nbFiles)) { 846 curFile++; 847 menuRedraw=true; 848 } 849 } 850 else if ( (bClick & MASK_KEY_USER2) || (c == MKEY_JOY) ) { 851 emu_SwapJoysticks(0); 852 menuRedraw=true; 853 } 854 855 if (menuRedraw && nbFiles) { 856 int fileIndex = 0; 857 tft.drawRectNoDma(MENU_FILE_XOFFSET,MENU_FILE_YOFFSET, MENU_FILE_W, MENU_FILE_H, MENU_FILE_BGCOLOR); 858 // if (curFile <= (MAX_MENULINES/2-1)) topFile=0; 859 // else topFile=curFile-(MAX_MENULINES/2); 860 if (curFile <= (MAX_MENULINES-1)) topFile=0; 861 else topFile=curFile-(MAX_MENULINES/2); 862 863 //Serial.print("curfile: "); 864 //Serial.println(curFile); 865 //Serial.print("topFile: "); 866 //Serial.println(topFile); 867 868 int i=0; 869 while (i<MAX_MENULINES) { 870 if (fileIndex>=nbFiles) { 871 // no more files 872 break; 873 } 874 char * filename = &files[fileIndex][0]; 875 if (fileIndex >= topFile) { 876 if ((i+topFile) < nbFiles ) { 877 if ((i+topFile)==curFile) { 878 tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); 879 strcpy(selection,filename); 880 } 881 else { 882 tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, 0xFFFF, 0x0000, true); 883 } 884 } 885 i++; 886 } 887 fileIndex++; 888 } 889 890 tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy); 891 tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0xff,0x00,0x00), false); 892 menuRedraw=false; 893 } 894 895 return (action); 896 } 897 898 bool menuActive(void) 899 { 900 return (menuOn); 901 } 902 903 void toggleMenu(bool on) { 904 if (on) { 905 callibrationOn=false; 906 menuOn=true; 907 backgroundMenu(); 908 } else { 909 menuOn = false; 910 } 911 } 912 913 char * menuSelection(void) 914 { 915 return (selection); 916 } 917 918 919 920 921 static void callibrationInit(void) 922 { 923 callibrationOn=true; 924 menuOn=false; 925 callibrationStep = 0; 926 calMinX=0,calMinY=0,calMaxX=0,calMaxY=0; 927 tft.fillScreenNoDma(RGBVAL16(0xff,0xff,0xff)); 928 tft.drawTextNoDma(0,100, " Callibration process:", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 929 tft.drawTextNoDma(0,116, " Hit the red cross at each corner", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 930 tft.drawTextNoDma(0,0, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 931 prev_zt = 1; 932 } 933 934 935 static void readCallibration(void) 936 { 937 char fileBuffer[64]; 938 939 #ifdef USE_SDFS 940 FIL file; 941 int retval; 942 if( !(f_open(&file, CALIBRATION_FILE, FA_READ)) ) { 943 if( !(f_read (&file, fileBuffer, 64, &retval)) ) { 944 if (retval == 64) { 945 sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY); 946 } 947 } 948 f_close(&file); 949 } 950 #else 951 File file = SD.open(CALIBRATION_FILE, O_READ); 952 if (file) { 953 if ( file.read(fileBuffer, 64) ) { 954 sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY); 955 } 956 file.close(); 957 Serial.println("Current callibration params:"); 958 Serial.println(calMinX); 959 Serial.println(calMinY); 960 Serial.println(calMaxX); 961 Serial.println(calMaxY); 962 } 963 #endif 964 else { 965 Serial.println("Callibration read error"); 966 } 967 tft.callibrateTouch(calMinX,calMinY,calMaxX,calMaxY); 968 } 969 970 static void writeCallibration(void) 971 { 972 tft.callibrateTouch(calMinX,calMinY,calMaxX,calMaxY); 973 974 #ifdef USE_SDFS 975 FIL file; 976 int retval; 977 if( !(f_open(&file, CALIBRATION_FILE, FA_WRITE)) ) { 978 //if( !(f_read (&file, fileBuffer, 64, &retval)) ) { 979 // if (retval == 64) { 980 // sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY); 981 // } 982 //} 983 f_close(&file); 984 } 985 #else 986 File file = SD.open(CALIBRATION_FILE, O_WRITE | O_CREAT | O_TRUNC); 987 if (file) { 988 file.print(calMinX); 989 file.print(" "); 990 file.print(calMinY); 991 file.print(" "); 992 file.print(calMaxX); 993 file.print(" "); 994 file.println(calMaxY); 995 file.close(); 996 } 997 #endif 998 else { 999 Serial.println("Callibration write error"); 1000 } 1001 } 1002 1003 1004 bool callibrationActive(void) 1005 { 1006 return (callibrationOn); 1007 } 1008 1009 1010 1011 int handleCallibration(uint16_t bClick) { 1012 uint16_t xt=0; 1013 uint16_t yt=0; 1014 uint16_t zt=0; 1015 if (tft.isTouching()) { 1016 if (prev_zt == 0) { 1017 prev_zt = 1; 1018 tft.readRaw(&xt,&yt,&zt); 1019 if (zt < 1000) { 1020 return 0; 1021 } 1022 switch (callibrationStep) 1023 { 1024 case 0: 1025 callibrationStep++; 1026 tft.drawTextNoDma(0,0, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true); 1027 tft.drawTextNoDma(TFT_REALWIDTH-8,0, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 1028 calMinX += xt; 1029 calMinY += yt; 1030 break; 1031 case 1: 1032 callibrationStep++; 1033 tft.drawTextNoDma(TFT_REALWIDTH-8,0, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true); 1034 tft.drawTextNoDma(TFT_REALWIDTH-8,TFT_REALHEIGHT-16, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 1035 calMaxX += xt; 1036 calMinY += yt; 1037 break; 1038 case 2: 1039 callibrationStep++; 1040 tft.drawTextNoDma(TFT_REALWIDTH-8,TFT_REALHEIGHT-16, " ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0xff,0xff,0xff), true); 1041 tft.drawTextNoDma(0,TFT_REALHEIGHT-16, "+", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 1042 calMaxX += xt; 1043 calMaxY += yt; 1044 break; 1045 case 3: 1046 tft.fillScreenNoDma(RGBVAL16(0xff,0xff,0xff)); 1047 tft.drawTextNoDma(0,100, " Callibration done!", RGBVAL16(0x00,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 1048 tft.drawTextNoDma(0,116, " (Click center to exit)", RGBVAL16(0xff,0x00,0x00), RGBVAL16(0xff,0xff,0xff), true); 1049 callibrationStep++; 1050 calMinX += xt; 1051 calMaxY += yt; 1052 break; 1053 case 4: 1054 //Serial.println(xt); 1055 //Serial.println(yt); 1056 if ( (xt > (TFT_REALWIDTH/4)) && (xt < (TFT_REALWIDTH*3)/4) 1057 && (yt > (TFT_REALHEIGHT/4)) && (yt < (TFT_REALHEIGHT*3)/4) ) { 1058 calMinX /= 2; 1059 calMinY /= 2; 1060 calMaxX /= 2; 1061 calMaxY /= 2; 1062 writeCallibration(); 1063 toggleMenu(true); 1064 } 1065 else { 1066 callibrationInit(); 1067 } 1068 break; 1069 1070 } 1071 delay(100); 1072 } 1073 } 1074 else { 1075 prev_zt = 0; 1076 } 1077 } 1078 1079 1080 1081 1082 1083 int emu_FileOpen(char * filename) 1084 { 1085 int retval = 0; 1086 1087 char filepath[80]; 1088 strcpy(filepath, romspath); 1089 strcat(filepath, "/"); 1090 strcat(filepath, filename); 1091 emu_printf("FileOpen..."); 1092 emu_printf(filepath); 1093 #ifdef USE_SDFS 1094 if( !(f_open(&file, filepath, FA_READ)) ) { 1095 #else 1096 if ((file = SD.open(filepath, O_READ))) { 1097 #endif 1098 retval = 1; 1099 } 1100 else { 1101 emu_printf("FileOpen failed"); 1102 } 1103 return (retval); 1104 } 1105 1106 int emu_FileRead(char * buf, int size) 1107 { 1108 unsigned char buffer[256]; 1109 1110 int remaining = size; 1111 int byteread = 0; 1112 int retval=0; 1113 if (size < 256) { 1114 #ifdef USE_SDFS 1115 if( !(f_read (&file, buffer, size, &retval)) ) 1116 #else 1117 retval = file.read(buffer, size); 1118 #endif 1119 if (retval>0) { 1120 memcpy(buf,buffer,retval); 1121 byteread += retval; 1122 } 1123 } 1124 else { 1125 while (remaining>0) { 1126 #ifdef USE_SDFS 1127 if( !(f_read (&file, buffer, 256, &retval)) ) 1128 //f_read (&file, buffer, 256, &retval); 1129 #else 1130 retval = file.read(buffer, 256); 1131 #endif 1132 if (retval>0) { 1133 //emu_printi(retval); 1134 memcpy(buf,buffer,retval); 1135 buf += retval; 1136 byteread += retval; 1137 remaining -= retval; 1138 } 1139 else { 1140 break; 1141 } 1142 } 1143 } 1144 1145 return byteread; 1146 } 1147 1148 unsigned char emu_FileGetc(void) { 1149 unsigned char c; 1150 #ifdef USE_SDFS 1151 int retval=0; 1152 if( !(f_read (&file, &c, 1, &retval)) ) 1153 #else 1154 int retval = file.read(&c, 1); 1155 #endif 1156 if (retval != 1) { 1157 emu_printf("emu_FileGetc failed"); 1158 } 1159 return c; 1160 } 1161 1162 1163 void emu_FileClose(void) 1164 { 1165 #ifdef USE_SDFS 1166 f_close(&file); 1167 #else 1168 file.close(); 1169 #endif 1170 } 1171 1172 int emu_FileSize(char * filename) 1173 { 1174 int filesize=0; 1175 char filepath[80]; 1176 strcpy(filepath, romspath); 1177 strcat(filepath, "/"); 1178 strcat(filepath, filename); 1179 emu_printf("FileSize..."); 1180 emu_printf(filepath); 1181 #ifdef USE_SDFS 1182 FILINFO entry; 1183 f_stat(filepath, &entry); 1184 filesize = entry.fsize; 1185 #else 1186 if ((file = SD.open(filepath, O_READ))) 1187 { 1188 emu_printf("filesize is..."); 1189 filesize = file.size(); 1190 emu_printf(filesize); 1191 file.close(); 1192 } 1193 #endif 1194 1195 return(filesize); 1196 } 1197 1198 int emu_FileSeek(int seek) 1199 { 1200 #ifdef USE_SDFS 1201 f_lseek(&file, seek); 1202 #else 1203 file.seek(seek); 1204 #endif 1205 return (seek); 1206 } 1207 1208 int emu_FileTell(void) 1209 { 1210 #ifdef USE_SDFS 1211 return (f_tell(&file)); 1212 #else 1213 return (50); 1214 #endif 1215 } 1216 1217 1218 int emu_LoadFile(char * filename, char * buf, int size) 1219 { 1220 int filesize = 0; 1221 1222 char filepath[80]; 1223 strcpy(filepath, romspath); 1224 strcat(filepath, "/"); 1225 strcat(filepath, filename); 1226 emu_printf("LoadFile..."); 1227 emu_printf(filepath); 1228 #ifdef USE_SDFS 1229 if( !(f_open(&file, filepath, FA_READ)) ) { 1230 filesize = f_size(&file); 1231 emu_printf(filesize); 1232 if (size >= filesize) 1233 { 1234 int retval=0; 1235 if( (f_read (&file, buf, filesize, &retval)) ) { 1236 emu_printf("File read failed"); 1237 } 1238 } 1239 f_close(&file); 1240 } 1241 #else 1242 if ((file = SD.open(filepath, O_READ))) 1243 { 1244 filesize = file.size(); 1245 emu_printf(filesize); 1246 1247 if (size >= filesize) 1248 { 1249 if (emu_FileRead(buf, filesize) != filesize) 1250 { 1251 emu_printf("File read failed"); 1252 } 1253 } 1254 file.close(); 1255 } 1256 #endif 1257 1258 return(filesize); 1259 } 1260 1261 int emu_LoadFileSeek(char * filename, char * buf, int size, int seek) 1262 { 1263 int filesize = 0; 1264 1265 char filepath[80]; 1266 strcpy(filepath, romspath); 1267 strcat(filepath, "/"); 1268 strcat(filepath, filename); 1269 emu_printf("LoadFileSeek..."); 1270 emu_printf(filepath); 1271 #ifdef USE_SDFS 1272 if( !(f_open(&file, filepath, FA_READ)) ) { 1273 f_lseek(&file, seek); 1274 emu_printf(size); 1275 if (size >= filesize) 1276 { 1277 int retval=0; 1278 if( (!f_read (&file, buf, size, &retval)) ) 1279 if (retval != size) 1280 { 1281 emu_printf("File read failed"); 1282 } 1283 } 1284 f_close(&file); 1285 } 1286 #else 1287 if ((file = SD.open(filepath, O_READ))) 1288 { 1289 file.seek(seek); 1290 emu_printf(size); 1291 if (file.read(buf, size) != size) { 1292 emu_printf("File read failed"); 1293 } 1294 file.close(); 1295 } 1296 #endif 1297 1298 return(filesize); 1299 } 1300 1301 const uint32_t FILE_SIZE_MB = 8; 1302 const uint32_t FILE_SIZE = 1000000UL*FILE_SIZE_MB; 1303 #ifdef USE_SDFS 1304 static FIL tempfile; 1305 #else 1306 static File tempfile; 1307 #endif 1308 1309 void emu_FileTempInit(void) 1310 { 1311 #ifdef USE_SDFS 1312 if( (f_open(&tempfile, SDFSDEV "/bench.dat", FA_READ| FA_WRITE )) ) { 1313 #else 1314 #ifdef USE_SDFAT 1315 if (!tempfile.open("/bench.dat", O_RDWR /*| O_CREAT | O_TRUNC*/)) { 1316 #else 1317 if ((tempfile = SD.open("/bench.dat", O_RDWR))) { 1318 #endif 1319 #endif 1320 Serial.println("psram open failed"); 1321 } 1322 /* 1323 else { 1324 uint8_t buf[256]; 1325 Serial.println("psram creating"); 1326 file = SD.open("/bench.dat", O_RDWR | O_CREAT | O_TRUNC); 1327 if (file) { 1328 Serial.println("psram opened"); 1329 file.truncate(0); 1330 1331 if (!file.preAllocate(FILE_SIZE)) { 1332 Serial.println("allocate failed"); 1333 } 1334 for(int i=0;i<FILE_SIZE/256;i++){ 1335 file.write(buf, 256); 1336 Serial.println(i); 1337 1338 } 1339 Serial.println("psram created"); 1340 } 1341 1342 //file.close(); 1343 } 1344 */ 1345 #ifdef USE_SDFS 1346 FILINFO entry; 1347 f_stat(SDFSDEV "/bench.dat", &entry); 1348 int fs=entry.fsize; 1349 #else 1350 int fs=tempfile.size(); 1351 #endif 1352 Serial.print("psram size is "); 1353 Serial.println(fs); 1354 } 1355 1356 void emu_FileTempRead(int addr, unsigned char * val, int n) 1357 { 1358 #ifdef USE_SDFS 1359 f_lseek(&file, addr); 1360 int retval=0; 1361 f_read (&file, val, n, &retval); 1362 #else 1363 tempfile.seek(addr); 1364 tempfile.read(val, n); 1365 #endif 1366 } 1367 1368 void emu_FileTempWrite(int addr, unsigned char val) 1369 { 1370 uint8_t v=val; 1371 #ifdef USE_SDFS 1372 f_lseek(&tempfile, addr); 1373 int retval=0; 1374 f_write (&tempfile, &v, 1, &retval); 1375 #else 1376 tempfile.seek(addr); 1377 tempfile.write(&v, 1); 1378 #endif 1379 } 1380 1381 1382 void emu_init(void) 1383 { 1384 Serial.begin(115200); 1385 1386 #ifdef USE_SDFS 1387 strcpy(romspath,SDFSDEV); 1388 strcat(romspath,ROMSDIR); 1389 FRESULT rc; 1390 if((rc = f_mount (&fatfs, romspath, 1))) { 1391 emu_printf("Fail mounting SDFS"); 1392 } 1393 else { 1394 rc = f_chdrive(ROMSDIR); 1395 } 1396 #else 1397 #ifdef USE_SDFAT 1398 while (!SD.begin(SD_CONFIG)) 1399 #else 1400 while (!SD.begin(SD_CS)) 1401 #endif 1402 { 1403 Serial.println("SD begin failed, retrying..."); 1404 delay(1000); 1405 } 1406 strcpy(romspath,ROMSDIR); 1407 #endif 1408 1409 nbFiles = readNbFiles(); 1410 1411 Serial.print("SD initialized, files found: "); 1412 Serial.println(nbFiles); 1413 1414 1415 emu_InitJoysticks(); 1416 #ifdef SWAP_JOYSTICK 1417 joySwapped = true; 1418 #else 1419 joySwapped = false; 1420 #endif 1421 readCallibration(); 1422 1423 if ((tft.isTouching()) || (emu_ReadKeys() & MASK_JOY2_BTN) ) { 1424 callibrationInit(); 1425 } 1426 else 1427 { 1428 toggleMenu(true); 1429 } 1430 1431 #ifdef HAS_I2CKBD 1432 byte msg[7]={0,0,0,0,0,0,0}; 1433 Wire.begin(); // join i2c bus SDA2/SCL2 1434 Wire.requestFrom(8, 7); // request 7 bytes from slave device #8 1435 int i = 0; 1436 while (Wire.available() && (i<7) ) { // slave may send less than requested 1437 byte b = Wire.read(); // receive a byte 1438 msg[i++] = b; 1439 } 1440 /* 1441 Serial.println(msg[0], BIN); 1442 Serial.println(msg[1], BIN); 1443 Serial.println(msg[2], BIN); 1444 Serial.println(msg[3], BIN); 1445 Serial.println(msg[4], BIN); 1446 Serial.println(msg[5], BIN); 1447 Serial.println(msg[6], BIN); 1448 */ 1449 if ( (msg[0] == 0xff) && (msg[1] == 0xff) && 1450 (msg[2] == 0xff) && (msg[3] == 0xff) && 1451 (msg[4] == 0xff) && (msg[5] == 0xff) && (msg[6] == 0xff)) { 1452 i2cKeyboardPresent = true; 1453 Serial.println("i2C keyboard found"); 1454 } 1455 #endif 1456 1457 keys = key_map1; 1458 keyMap = 0; 1459 } 1460 1461