vindar / ILI9341_T4

Optimized ILI9341 screen driver library for Teensy 4/4.1, with vsync and diff. updates.
GNU Lesser General Public License v2.1
70 stars 12 forks source link

ILI9488 #5

Open DIYLAB-DE opened 2 years ago

DIYLAB-DE commented 2 years ago

Hi Arvind,

just a thought, don't panic ;o) Would it be possible to make the driver also for ILI9488? Or is the effort huge?

I find for the ILI9488 only fast drivers for ESP32, not for Teensy 4.x

Best regards Bruno

vindar commented 2 years ago

Hi Bruno,

Disclaimer: I do not have an ili9488 screen (and never used one) so I do not really know what I am taking about below ;-)

From what I have seen, both screens seem to have very similar hardware/driver interface so porting an ili9341 library to ili9488 should be manageable...

However, the ili9488 has a 480x320 screen so a (full colored) memory framebuffer will take 300kb of ram. This makes the approach taken with my ili9341_t4 library impractical as using a framebuffer + internal framebuffer would cost 600kb ! Even for the Teensy 4.1 this is a huge amount and will leave only very little RAM for the actual program since one framebuffer will need to be placed in DTCM memory while the other can go in DMAMEM ( EXTMEM, if present, would quite slow I think). When the next teensy is is released, which I expect will have 1.5mb of RAM, then this approach might become viable. But then, for such a big screen, it might make more sense to use the 16bits parallel interface rather than a slow SPI bus... And hopefully the next Teensy will have the necessary pins broken out to use the video hardware present in the NXT chip....

Anyway, I will probably try to adapt the ILI9341_T4 to ILI9488_T4 at some point but I cannot give a specific timeframe. I have quite a lot of work right now so I do not expect to have much time for hobby programming for a couple of months :-(

In the meantime, did you try Kurte's ILI9488_t3 library https://github.com/KurtE/ILI9488_t3 ? It should work with the T4 and and I suspect it is as fast as possible without a full internal framebuffer. Morever, looking at the code, it seems that this library does support "paleted" framebuffer...

Best, Arvind

DIYLAB-DE commented 2 years ago

Hi Arvind,

I have now tried the following libraries: https://github.com/KurtE/ILI9488_t3 https://github.com/mjs513/ILI9488_t3

Result is absolutely ok: https://youtu.be/ilsMmiQmcUI

Allow me one more question: is it possible to just use your TGX library with this driver? That would be absolutely awesome, then I wouldn't have to reinvent the wheel ;o)

Kind regards Bruno

DIYLAB-DE commented 2 years ago

Ok, this works with TGX:

#include <ILI9488_t3.h>
#include <tgx.h>

#define TFT_SCK         13
#define TFT_MISO        12
#define TFT_MOSI        11
#define TFT_DC          10
#define TFT_CS           9
#define TFT_RST          6
#define TFT_BACKLIGHT  255
#define TFT_TOUCH_IRQ  255
#define TFT_TOUCH_CS   255

using namespace tgx;

ILI9488_t3 tft = ILI9488_t3(&SPI, TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO);

// size of the drawing framebuffer
#define SLX 320
#define SLY 480

// framebuffer
uint16_t fb[SLX * SLY];

// the image that encapsulate framebuffer fb
Image<RGB565> im(fb, SLX, SLY);

void setup() {
    // backlight
    if (TFT_BACKLIGHT != 255) {
        pinMode(TFT_BACKLIGHT, OUTPUT);
        digitalWrite(TFT_BACKLIGHT, HIGH);
    }

    // display
    tft.begin(60000000);
    tft.setRotation(0);
    tft.setFrameBuffer(fb);
    tft.useFrameBuffer(true);
    tft.fillScreen(ILI9488_BLACK);
    tft.updateScreen();
}

void loop() {
    im.fillScreen(RGB565_Red);

    for (int i = 0; i < SLX / 2; i++) {
        im.drawCircle({ 160, 240 }, i, RGB565_Yellow);
        tft.updateScreen();
    }
}

Unfortunately very slow. I miss the diff buffers ;o)

Best, Bruno

vindar commented 2 years ago

Hi Bruno,

Indeed, you can use TGX with any driver library you wish provided it gives you a way to push a memory frame buffer onto the screen. All TGX does is to draw thing in RAM...

If you use ILI9343_t3 with a frame buffer, then the whole screen is redrawn each time when you are using DMA update (using tft.updateScreenAsync()). If you do not use DMA (with tft.updateScreen() as in your example above), I think there are methods to update only the rectangular region that contains the changes but it will still be quite a bit slower than diff. updates in most cases. However, if you up the SPI speed to 60Mhz (which is doable with short wire), you can already get around 48fps with full framebuffer updates. This is not buttery smooth for some animation but it is still a very decent frame rate.

Best, Arvind

DIYLAB-DE commented 2 years ago

Hi Arvind,

I thought I could "just quickly" rewrite the driver to ILI9488 - wrong thinking. The ILI9488 command codes seem to be identical to the ILI9341 ... Well, compiling works, display remains empty. Damn :o)

My test: ILI9488_T4.ZIP

Too bad you don't have time. Any little tip?

PS: Should I send you an ILI9488 display (for free)? ;)

blackketter commented 2 years ago

I was able, some time ago, to modify the ILI9341_t3 library to include a subclass that supported the ILI9488. You can find it here: https://github.com/blackketter/ILI9341_t3

Look at https://github.com/blackketter/ILI9341_t3/blob/master/ILI9488_t3.cpp and see which methods need to be overridden.

DIYLAB-DE commented 2 years ago

Thanks! I overwrote the init commands, but unfortunately I can't find the method "write16BitColor" in Arvind's driver.

blackketter commented 2 years ago

Yeah, it looks like I renamed writedata16 to write16BitColor and refactored it a bit.

You can see the relevant patch where I added ILI9488 support here:

https://github.com/blackketter/ILI9341_t3/commit/f46309bc2f7f8eb59c03c96f4dc9089938f1cff2#diff-44320b63faf812018e3abaf11d3f8b7c30ee32ae37c8da07c2a48bcc1e703bb2

and some more here:

https://github.com/blackketter/ILI9341_t3/commit/89b13e495c04818f0f2302fe5d3c8334c583813f

Sorry if this won't merge easily, but it should give you a head start.

DIYLAB-DE commented 2 years ago

Ah, now I understand, thank you! I'll try to implement that.

DIYLAB-DE commented 2 years ago

I give up, many hours of time and no success. So again take ILI9488_t3 and hope that Arvind sometime has desire.

Kind regards Bruno

vindar commented 2 years ago

Hi,

As it was mentioned in the PJRC forum's thread, I think the real problem here is that, unlike ILI9341, the ILI9488 controller do not allow 16 bits RGB565 colors via the SPI interface. Thus, changing the current driver will require quite a bit of work since each pixel color must be converted from 2 bytes (RGB565) to 3 bytes (RGB666) prior to upload via DMA. This will increase the CPU load significantly when doing uploads. Also, this means that, instead of transferring 2320240 bytes per frame as in the ILI9341 case, we here need to upload 3480320 bytes for a full frame so the frame rate will be 3x slower with the same SPI speed :-(

The fact that the SPI interface to do support 16 bits color suggests that SPI is only intended for simple static display. For anything which requires smooth animations, one should probably use the 8bits/16bits interface. Then it will be much simpler to achieve a high framerate.

Anyway, I am getting a ILI9488 screen delivered next week so I will probably play a bit with it but I do not really expect I will be able to do much...

DIYLAB-DE commented 2 years ago

Hi Arvind,

that you want to work on it after all, fills me with great joy! I think vSync and ansynchronous transfer will improve the situation significantly. Currently I am testing your 99 balloons with the ILI9488_t3 and my hair is standing on end. Without Async 8 FPS at 30 MHz SPI (twice as much with 60 MHz), with clipping regions not much better. Asynchronous refreshing brings a huge boost, but what good is that if the driver doesn't have VSync? Tearing wherever the eye looks :/ That's why I'm so in love with your driver :) THANK YOU for dealing with it!

Best Bruno

DIYLAB-DE commented 2 years ago

Hi Arvind,

have you had a chance to look into it a bit? That would be very nice.

If the buffer sizes are giving you trouble, maybe a suggestion: A buffer with one byte per pixel and a palette would be conceivable. 256 colors are quite sufficient for most applications. Then the space requirement would be halved.

Best Bruno