TFT ILI9806 on ESP32 don't work

Hi

I trying to do work an TFT ILI9806 with an ESP32 over 8bit paralell por, but I don’t do work correctly

I Try with Mcufriend_kbv library concretly with LCD_ID_readreg.ino and I received this values

reg(0x00D3) 00 00 98 06 ID: ILI9806
reg(0x0004) 00 00 80 00 Manufacturer ID
reg(0x0009) 00 80 73 06 00      Status Register
reg(0x000A) 00 9C       Get Powsr Mode
reg(0x000B) 00 00       MADCTL
reg(0x000C) 00 07       Get Pixel Format
reg(0x0054) 00 00       Display CTRL
reg(0x0054) 00 00       Display CABC

Pixel Format is 0x07 and I think that I need received 0x77

I bought this screen TFT link

In the three resistor of pcb on default are IM0 1, IM1 0, IM2 0. 16bit
I changed IM0 resistor to 0 expecting 8bit
Can somebody help me?

Thanks

I do not claim to support ILI9806 in the how_to file.
I have never owned or even seen an ILI9806 screen.

I think that ZinggJM owns one. I wrote begin(0x9806) case block for ZinggJM.
From memory, I don't think that he ever chose to try it.

Yes, I would select IM# pins for 8080-8 interface.
Yes, I would run the LCD_ID_readreg sketch to verify the wiring.
Yes, I would uncomment the

//#define SUPPORT_9806              //UNTESTED

line.

And run the graphictest_kbv.ino from the examples.

What happens? Do you get a white screen? Do you see any graphics?

If you get "some response" please describe in words or post a video.

David.

Hi, thanks for your help.

I unmark support ili9806 as you describe me, I compiled Fine the graphictest_kbv.ino, but where I define my parallel pin setting?

In LCD_ID_readreg.ino, I can define LCD_D0, LCD_D1, LCD_D2 ..... directly in the sketch, I search in the library, I see some shield predefined files, but I don't have any shield, I need set LCD_D0, LCD_D1, LCD_D2 .... as digital pin from ESP32, for example:

#define LCD_D0 32
#define LCD_D1 33
#define LCD_D2 25
#define LCD_D3 26
#define LCD_D4 27
#define LCD_D5 14
#define LCD_D6 12
#define LCD_D7 13

Where can I define this?

Thank you.

I strongly suggest that you wire your ESP32 like the TTGO D1 R32 board as in utility/mcufriend_shield.h:

//################################### ESP32 ##############################
#elif defined(ESP32)       //regular UNO shield on TTGO D1 R32 (ESP32)
#define LCD_RD  2  //LED
#define LCD_WR  4
#define LCD_RS 15  //hard-wired to A2 (GPIO35) 
#define LCD_CS 33  //hard-wired to A3 (GPIO34)
#define LCD_RST 32 //hard-wired to A4 (GPIO36)

#define LCD_D0 12
#define LCD_D1 13
#define LCD_D2 26
#define LCD_D3 25
#define LCD_D4 17
#define LCD_D5 16
#define LCD_D6 27
#define LCD_D7 14

Connect the wiring as above. Copy-paste the defines to the LCD_ID_readreg sketch. Verify that everything is working ok.

That is it. Select your ESP32 board in the IDE. Run MCUFRIEND_kbv sketches in the usual way.

If you want to use a Touch Screen, hard-wire GPIO35 to GPIO15, GPIO34 to GPIO33.

Please let me know how you get on. Do you get a white screen?

David.

Edit. Although MCUFRIEND_kbv does not do SPI interface, you can select x011 for RGB888 and the ESP32 should work nicely with 9-bit SPI.

Hi.

I re-wire as you mentioned, like TTGO D1 R32 defined in utility/mcufriend_shield.h

I changed definition in LCD_ID_readreg.ino like TTGO D1 R32 defined in utility/mcufriend_shield.h

upload the sketch OK, and here is the values returned:

reg(0x0000) 00 00       ID: ILI9320, ILI9325, ILI9335, ...
reg(0x0004) 00 00 80 00 Manufacturer ID
reg(0x0009) 00 80 73 06 00      Status Register
reg(0x000A) 00 9C       Get Power Mode
reg(0x000C) 00 07       Get Pixel Format
reg(0x0061) 00 00       RDID1 HX8347-G
reg(0x0062) 00 00       RDID2 HX8347-G
reg(0x0063) 00 00       RDID3 HX8347-G

reg(0x0064) 00 00       RDID1 HX8347-A
reg(0x0065) 00 00       RDID2 HX8347-A
reg(0x0066) 00 00       RDID3 HX8347-A
reg(0x0067) 00 00       RDID Himax HX8347-A
reg(0x0070) 00 00       Panel Himax HX8347-A
reg(0x00A1) 00 00 00 00 00      RD_DDB SSD1963
reg(0x00B0) B0 B0       RGB Interface Signal Control
reg(0x00B4) B4 B4       Inversion Control
reg(0x00B6) B6 B6 B6 B6 B6      Display Control
reg(0x00B7) B7 B7       Entry Mode Set
reg(0x00BF) BF BF BF BF BF BF   ILI9481, HX8357-B
reg(0x00C0) C0 C0 C0 C0 C0 C0 C0 C0 C0  Panel Control
reg(0x00C8) C8 C8 C8 C8 C8 C8 C8 C8 C8 C8 C8 C8 C8      GAMMA
reg(0x00CC) FF FF       Panel Control
reg(0x00D0) D0 D0 D0    Power Control
reg(0x00D2) D2 D2 D2 D2 D2      NVM Read
reg(0x00D3) FF 00 98 06 ILI9341, ILI9488
reg(0x00D4) D4 D4 D4 D4 Novatek ID
reg(0x00DA) 00 00       RDID1
reg(0x00DB) 00 80       RDID2
reg(0x00DC) 00 00       RDID3
reg(0x00E0) E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0     GAMMA-P
reg(0x00E1) E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1     GAMMA-N
reg(0x00EF) EF EF EF EF EF EF   ILI9327
reg(0x00F2) F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 Adjust Control 2
reg(0x00F6) F6 F6 F6 F6 Interface Control

When I upload the graphic test_kbv.ino in ID I received 0.

Serial took 0ms to start
ID = 0x0

I don't know why.

Thanks

Since your wiring worked in LCD_ID_readreg, I would expect it to work in regular MCUFRIEND_kbv sketches.

Force tft.begin(0x9806); in setup().
Run graphictest_kbv
Observe ID value in Adafruit_Tests report page. (if you get any graphics)

I regard ESP32 operation as a little flaky unless you have a proper TTGO board.
My hand-wired ESP32 version is not as stable as my TTGO board.

I would expect to see the ID even if SUPPORT_9806 was not enabled.
Some controllers are very SLOW when reading ID or GRAM.
This is not noticeable on Uno or Mega. But gives problems with a 180MHz STM32.

David.

Hi.

I've stupid error, I forgot change pwm backlight pin and are same as RD. >:(

Now work, fillScreen and test Text OK
next test Lines CRASH, blink screen, and all black
them in test FastLines nothing, need reboot.

I'll try rewrite a independent library for debug work.

Thank you

Woo-hoo. So the controller is working!

It crashes during the angled lines. That sounds like a WatchDog. The drawLine() is an expensive method.
OTOH, ESP32 does not generally have WatchDog problems.

Look at the testLines() function. Add a delay(1) with each fillScreen(BLACK). That will give the WatchDog a kick.

I would appreciate it if you persevere with the graphictest_kbv sketch. I know it well. And it exercises all the methods.

If you do write your own test sketch(es), please post or link. So that we both know what is happening.

David.

Hi

I'm doing some tests, and I can say that the first initialize sequence don't work correctly, the LCD initialize on BGR order, and horizontal flip, REG 09h return me value 00 A4 53 06 00 when in initialize sequence I set REG 36h 0x60, this don't respond to my commandment.

I solved the color order BGR with not elegant way, redefining color

for example

#define	GREEN   0x07E0 
to 
#define	GREEN   0x0E70 
#define ....

At moment test not work properly are

  • testLines
  • testFilledCircles
  • testCircles
  • testFilledTriangles

can are problem because size of screen? 854 x 480 pix

other test work well
but I only see one middle.

I'll continue doing more test.

Thank you.

Hi

If I do this again

ID = tft.readID();

after

tft.begin(ID);

Change color order from BGR to RGB and I see screen at full screen

uint16_t ID = tft.readID(); //
Serial.print("ID = 0x");
Serial.println(ID, HEX);
if (ID == 0xD3D3) ID = 0x9481; // write-only shield
//    ID = 0x9329;                             // force ID
tft.begin(ID);
//tft.setRotation(2);
ID = tft.readID(); //execute Again for RGB order and FullScreen mode

Just say:

uint16_t ID = tft.readID(); //
Serial.print("ID = 0x");
Serial.println(ID, HEX);
if (ID == 0xD3D3) ID = 0x9481; // write-only shield
    ID = 0x9806;                             // force ID
tft.begin(ID);

Don't worry about directions or exact colours. Make notes on paper about them.
A photo of a Penguin screen is better than 1000 words.
A video is worth 10000 words.

I suspect that I can make all the corrections in one statement. (if I see a picture)

Did the delay(1) solve a WatchDog reset? Was it WatchDog?

There are two basic functions of a graphics program. Plotting one pixel at a time. Filling a rectangular block.
x1 text, circles, angle lines, require drawPixel()
x2 text, straight lines, filled rectangles, filled circles, ... require fillRect()

If you can post a photo I can solve several things.
Otherwise describe carefully in words.

David.

Hi

Here is the video of first test, BGR order, horizontal flip and not fullscreen.

http://www.codetronic.es/owncloud/index.php/s/EAbIZMSgW0V9AsP

And I attach too a foto of this

After recall tft.readID() after tft.begin() I obtain RGB order, no horizontal flip, and fullscreen view

I attached some fotos

Thanks for the photos. I had to fix RGB, SS and geometry.
I can see far more from the photos than you can describe in words.

The photo in #11 shows that I had assumed the display was natural 864x480 when it is 480x864.
I had assumed it was like the SSD1963 i.e. natural 800x480

Please edit the case 0x9806 block in MCUFRIEND_kbv.cpp:

#ifdef SUPPORT_9806
    case 0x9806:
        _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS | READ_24BITS | INVERT_RGB |INVERT_SS;
        // from ZinggJM
        static const uint8_t ILI9806_regValues[] PROGMEM = {
            (0xFF), 3, /* EXTC Command Set enable register*/ 0xFF, 0x98, 0x06,
            (0xBA), 1, /* SPI Interface Setting*/0xE0,
            (0xBC), 21, /* GIP 1*/0x03, 0x0F, 0x63, 0x69, 0x01, 0x01, 0x1B, 0x11, 0x70, 0x73, 0xFF, 0xFF, 0x08, 0x09, 0x05, 0x00, 0xEE, 0xE2, 0x01, 0x00, 0xC1,
            (0xBD), 8, /* GIP 2*/0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67,
            (0xBE), 9, /* GIP 3*/0x00, 0x22, 0x27, 0x6A, 0xBC, 0xD8, 0x92, 0x22, 0x22,
            (0xC7), 1, /* Vcom*/0x1E,
            (0xED), 3, /* EN_volt_reg*/0x7F, 0x0F, 0x00,
            (0xC0), 3, /* Power Control 1*/0xE3, 0x0B, 0x00,
            (0xFC), 1, 0x08,
            (0xDF), 6, /* Engineering Setting*/0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
            (0xF3), 1, /* DVDD Voltage Setting*/0x74,
            (0xB4), 3, /* Display Inversion Control*/0x00, 0x00, 0x00,
            (0xF7), 1, /* 480x854*/0x81,
            (0xB1), 3, /* Frame Rate*/0x00, 0x10, 0x14,
            (0xF1), 3, /* Panel Timing Control*/0x29, 0x8A, 0x07,
            (0xF2), 4, /*Panel Timing Control*/0x40, 0xD2, 0x50, 0x28,
            (0xC1), 4, /* Power Control 2*/0x17, 0x85, 0x85, 0x20,
            (0xE0), 16, 0x00, 0x0C, 0x15, 0x0D, 0x0F, 0x0C, 0x07, 0x05, 0x07, 0x0B, 0x10, 0x10, 0x0D, 0x17, 0x0F, 0x00,
            (0xE1), 16, 0x00, 0x0D, 0x15, 0x0E, 0x10, 0x0D, 0x08, 0x06, 0x07, 0x0C, 0x11, 0x11, 0x0E, 0x17, 0x0F, 0x00,
            (0x35), 1, /*Tearing Effect ON*/0x00,
        };
        table8_ads = ILI9806_regValues, table_size = sizeof(ILI9806_regValues);
        p16 = (int16_t *) & HEIGHT;  //natural portrait 480x864
        *p16 = 864;                       
        p16 = (int16_t *) & WIDTH;
        *p16 = 480;
        break;
#endif

It looks as if there is corruption in the "SOFTWARE SCROLL"

Software scroll corruption I think that are solved, I don’t have new photo because I’m not in house at now.

After modify this, direct port access vs digitalwrite()

#define WR_ACTIVE  REG_WRITE(GPIO_OUT_W1TC_REG, BIT4); //clear PIN_LOW(WR_PORT, WR_PIN)
#define WR_IDLE    REG_WRITE(GPIO_OUT_W1TS_REG, BIT4);//set PIN_HIGH(WR_PORT, WR_PIN)

Fillscreen complete in 212ms vs 338ms with digitalWrite(), and after this change, software scroll it’s see clean with out corruption

I have never made any attempt to get the fastest performance from an ESP32. There are several things that I can improve.

Yes, it will be very noticeable on a 864x480.

If you are prepared to provide feedback, I will create a Branch on GitHub.

David.

david_prentice:
Please edit the case 0x9806 block in MCUFRIEND_kbv.cpp:

#ifdef SUPPORT_9806

case 0x9806:
        _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS | READ_24BITS | INVERT_RGB |INVERT_SS;
        // from ZinggJM
        static const uint8_t ILI9806_regValues PROGMEM = {
            (0xFF), 3, /* EXTC Command Set enable register*/ 0xFF, 0x98, 0x06,
            (0xBA), 1, /* SPI Interface Setting*/0xE0,
            (0xBC), 21, /* GIP 1*/0x03, 0x0F, 0x63, 0x69, 0x01, 0x01, 0x1B, 0x11, 0x70, 0x73, 0xFF, 0xFF, 0x08, 0x09, 0x05, 0x00, 0xEE, 0xE2, 0x01, 0x00, 0xC1,
            (0xBD), 8, /* GIP 2*/0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67,
            (0xBE), 9, /* GIP 3*/0x00, 0x22, 0x27, 0x6A, 0xBC, 0xD8, 0x92, 0x22, 0x22,
            (0xC7), 1, /* Vcom*/0x1E,
            (0xED), 3, /* EN_volt_reg*/0x7F, 0x0F, 0x00,
            (0xC0), 3, /* Power Control 1*/0xE3, 0x0B, 0x00,
            (0xFC), 1, 0x08,
            (0xDF), 6, /* Engineering Setting*/0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
            (0xF3), 1, /* DVDD Voltage Setting*/0x74,
            (0xB4), 3, /* Display Inversion Control*/0x00, 0x00, 0x00,
            (0xF7), 1, /* 480x854*/0x81,
            (0xB1), 3, /* Frame Rate*/0x00, 0x10, 0x14,
            (0xF1), 3, /* Panel Timing Control*/0x29, 0x8A, 0x07,
            (0xF2), 4, /Panel Timing Control/0x40, 0xD2, 0x50, 0x28,
            (0xC1), 4, /* Power Control 2*/0x17, 0x85, 0x85, 0x20,
            (0xE0), 16, 0x00, 0x0C, 0x15, 0x0D, 0x0F, 0x0C, 0x07, 0x05, 0x07, 0x0B, 0x10, 0x10, 0x0D, 0x17, 0x0F, 0x00,
            (0xE1), 16, 0x00, 0x0D, 0x15, 0x0E, 0x10, 0x0D, 0x08, 0x06, 0x07, 0x0C, 0x11, 0x11, 0x0E, 0x17, 0x0F, 0x00,
            (0x35), 1, /Tearing Effect ON/0x00,
        };
        table8_ads = ILI9806_regValues, table_size = sizeof(ILI9806_regValues);
        p16 = (int16_t *) & HEIGHT;  //natural portrait 480x864
        *p16 = 864;                     
        p16 = (int16_t *) & WIDTH;
        *p16 = 480;
        break;
#endif




It looks as if there is corruption in the "SOFTWARE SCROLL"

Hi.

I change 0x9806 block in MCUFRIEND_kbv.cpp like you describe.
and this is the result: Video01.mp4

Scroll ONLY THE COLOR BAND don't work, and in PORTRAIT_REV and LANDSCAPE_REV, all graphics are corrupted

I change

table8_ads = ILI9806_regValues, table_size = sizeof(ILI9806_regValues);
        p16 = (int16_t *) & HEIGHT;  //natural portrait 480x864
        *p16 = 864;

to 854;

and result are this: Video02.mp4

At now scroll ONLY THE COLOR BAND work well, but PORTRAIT_REV and LANDSCAPE_REV, all graphics are corrupted equal to last change

Hi

I returned 854 to 864 like you describe in the past post, and I change setting register

(0xF7), 1, /* 480x854*/0x81,

to 0x80, in the datasheet register F7h byte D[2:0] config resolution0x80 represent 480x864

and scroll ONLY THE COLOR BAND ,PORTRAIT_REV and LANDSCAPE_REVl work properly, at now.

Only on PORTRAIT_REV and LANDSCAPE_REV are an black fix band, don’t move it on the scroll transition.

I attach a photo with this black bar

The controller is capable of 480x864. Your panel is actually 480x854.

Does readID() return the correct 0x9806 now? Or do you have to force the ID?
The diagnose_TFT_controller example draws rectangles that show up the physical geometry quite well.
All my examples use readID(). If there is a problem, this is the first thing to fix.

Yes, most controllers must know the correct size of GateScan to scroll. Ilitek is not as fussy as other makes.

There is something weird about the Portrait_Rev. Do you get the same result with 480x854 as on your 480x864 video? Your photo in #17 implies that you have good display but your 480x854 panel is scrolling 480x864. Actually it looks as if the "missing pixels" are 480x32 and not 480x10 that you would expect.

Yes, you get anomalies with "black band" or "leftover image" in Rev with some controllers when the geometry does not match. e.g. ILI9327 is 240x432 but most panels are 240x400.

Your videos are very helpful. Far better than words !!

Do you have a GitHub account? Or do you just install library with the Library Manager?

David.

Hi

Yes, now readId return me correct ID 0x9806

I tryed with the diagnose_TFT_controller example, and the rotation doesn’t correctly, I need to dissable INVERT_RGB and INVERT_SS flags from _lcd_capable because at this example color are see inverted with this flags.

I attach a photo with this example