kbr-net / sdrive-max

Arduino based Atari 8-bit Floppy Emulator with Touchscreen
http://www.kbrnet.de/projekte/sdrive-max/index.html
GNU General Public License v3.0
92 stars 23 forks source link

MCUFRIEND ILI9340 display issues #30

Closed TzOk83 closed 4 years ago

TzOk83 commented 4 years ago

My screen is made by MCUFRIEND. It is an 2,4" ILI9340 TFT display with 8-bit bus and analog touch-sensor in a form of Arduino-compatible shell.

When I use sdrive-max-v12b2.zip, I can pass the screen calibration, but then the app doesn't react on touch (but it wakes up from screen saver on touch), colors are correct.

If I use sdrive-max-v12b3.zip, the image is mirrored, but the app does respond to the touch. I always get sdrive.atr not found, but I on v12b3 I can browse the SD Card, and I see this file in the root directory. Card is FAT32 formatted 4GB micro-SDHC class 4.

Output from diagnose_Touchpins.ino is as follows:

Testing : (A1, D7) = 35
Testing : (A2, D6) = 25
Diagnosing as:-
YP,YM:  (A1, D7) = 35
XM,XP:  (A2, D6) = 25

Output from TouchScreen_Calibr_native.ino (from Arduino MCUFRIEND_kbv library) is:

const int XP=6,XM=A2,YP=A1,YM=7; //240x320 ID=0x9340
const int TS_LEFT=789,TS_RT=132,TS_TOP=397,TS_BOT=531;
PORTRAIT CALIBRATION     240 x 320
x = map(p.x, LEFT=789, RT=132, 0, 240)
y = map(p.y, TOP=397, BOT=531, 0, 320)
Touch Pin Wiring XP=6 XM=A2 YP=A1 YM=7
LANDSCAPE CALIBRATION    320 x 240
x = map(p.y, LEFT=397, RT=531, 0, 320)
y = map(p.x, TOP=132, BOT=789, 0, 240)
TzOk83 commented 4 years ago

Update: when I upload firmware using Arduino bootloader, the sdrive.atr is loaded correctly from the SD-Card at boot. Apparently, without the bootloader, the firmware tries to access the SD-Card before it is ready.

TzOk83 commented 4 years ago

I have complied v12 branch with ILI9329i profile, but I have changed in display.c

TFT_write(0x08) -> TFT_write(0x48) 
TFT_write(0xd8) -> TFT_write(0x98)

...and the screen and touchscreen seem to work ok.

TzOk83 commented 4 years ago

Actually a better patch is:

#ifdef INVERSE
    delay_ms(200);
//    TFT_write_cmd(ILI9341_RESET);
    TFT_write_cmd(ILI9341_DISPLAY_INVERSION_ON);
//    TFT_write(0x00);
#endif

#if defined HX8347G || defined HX8347I || defined HX8347D
    //set later after scroll init
    //TFT_write_cmd(0x01);  //scroll mode on
    //TFT_write(0x08);
    TFT_write_cmd(0x17);    //COLMOD 16bit
    TFT_write(0x05);
    TFT_write_cmd(0x18);    //frame rate idle/normal 50Hz/60Hz
    TFT_write(0x34);
    TFT_write_cmd(0x19);    //enable oscillator
    TFT_write(0x01);
    TFT_write_cmd(0x1f);    //set power on and exit standby mode
    TFT_write(0xd4);
    //TFT_write_cmd(0x36);  //characteristic SS, GS, BGR
    //TFT_write(0x00);
    TFT_write_cmd(0x28);    //gate output and display on
    TFT_write(0x3c);
    //TFT_write_cmd(0x22);  //GRAM

#else
    TFT_write_cmd(ILI9341_PIXEL_FORMAT);
    TFT_write(0x55);
    TFT_write_cmd(ILI9341_SLEEP_OUT);
    delay_ms(100);

    //TFT_write_cmd(ILI9341_DISPLAY_ON);
    //TFT_write_cmd(ILI9341_GRAM);
#endif

So basically, for DISPLAY, you've got 3 options:

... and 2 for TOUCH:

mamejay commented 4 years ago

Great work. Would you consider adding support for a different type of controller? RM68090

kbr-net commented 4 years ago

I think, this is also done with the new touchscreen autodetection firmware v12c.

TzOk83 commented 4 years ago

...actually I have found a better "patch", as I find out that my display really is ILI3940 which supports scrolling, and the only problem is differently "wired" touchscreen:

void waitTouch() {
    setIdling();
#if defined(HX8347G) || defined(ILI9329) || defined(ILI9340)
    PCMSK2 |= (1<<XM);      //select interrupt pin
    PCICR |= (1<<PCIE2);        //interrupt enable
#else
    PCMSK0 |= (1<<XM);      //select interrupt pin
    PCICR |= (1<<PCIE0);        //interrupt enable
#endif
    SMCR = (1<<SM1) | (1<<SM0) | (1<<SE);   //power save mode, sleep enable
    sleep_cpu();
    SMCR = 0;           //disable
#if defined(HX8347G) || defined(ILI9329) || defined(ILI9340)
    PCICR &= ~(1<<PCIE2);       //interrupt disable
#else
    PCICR &= ~(1<<PCIE0);       //interrupt disable
#endif
    restorePorts();
}

struct TSPoint getPoint () {
    cli();          //disable interrupts
    setIdling();
#if defined(HX8347G) || defined(ILI9329i) || defined(ILI9340)
    p.x = map(readTouch(1), TS_MINX, TS_MAXX, 0, MAX_X);
    p.y = map(readTouch(0), TS_MINY, TS_MAXY, 0, MAX_Y);
#else
    p.x = map(readTouch(0), TS_MINX, TS_MAXX, 0, MAX_X);
    p.y = map(readTouch(1), TS_MINY, TS_MAXY, 0, MAX_Y);
#endif
    restorePorts();
    sei();
    return(p);
}

struct TSPoint getRawPoint () {
    cli();
    setIdling();

#if defined(HX8347G) || defined(ILI9329i) || defined(ILI9340)
    p.x = readTouch(1);
    p.y = readTouch(0);
#else
    p.x = readTouch(0);
    p.y = readTouch(1);
#endif

    restorePorts();
    sei();
    return(p);
}