moononournation / Arduino_GFX

Arduino GFX developing for various color displays and various data bus interfaces
Other
834 stars 163 forks source link

ILI9341 needs to be reset (re-run begin) after setting up SSD1331 on same SPI bus #105

Closed marcmerlin closed 2 years ago

marcmerlin commented 2 years ago

Hi, I have some time work on your lib again, I'll soon be able to contribute an extra framebuffer and FastLED APIs on top to allow of lot of other code to work on top of your driver.

As part of this, I've been testing multiple device support in MultipleDeviceTest.ino

For me, if I setup SSD1331 first and then ILI9341, both work. If I setup in the reverse order, ILI9341 does not work, and I'm wondering if the SSD1331 init breaks ILI9341 because its separate cable select pin is maybe still enabled?

Is there something that needs to be done to make sure CS disables the other TFTs when each is initialized? I'm thinking for the first run, the CS pin could be at some unknown value before begin is run, and begin of tft1 could send codes to tft2 if tft2 hasn't had it begin run first, and its CS pin is potentially enabled?

moononournation commented 2 years ago

I think it is because ili9341 requires specific SPI mode, so it have some settings code at begin function.

marcmerlin commented 2 years ago

Thank you so much for the hint, sure enough that was the problem, and not CS. So, before I change tfts, I need to run the begin command each time before that.

    tft_[i]->begin();

I didn't benchmark how long it takes to send the init each time I change screens, but hopefully it's not too bad. It is not a problem in MultipleDeviceTest.ino because the devices you use, are compatible, but maybe it would be a good idea to add a begin() command before each gfx switch?

marcmerlin commented 2 years ago

Ok, I did the benchmarking, re-running begin in a loop is pretty terrible and gives a speed that isn't acceptable. However, I found out that I can do this: 1) init ILI9341 2) init SSD1331 3) re-run tft_[0]->begin(); just once in setup

That's enough for things to work. Honestly I'm not sure if there is any generic solution to this, except maybe ensuring that all drivers use the same SPI mode? (SSD1331 works with the SPI mode set by ILI9341, but the reverse is not true)

marcmerlin commented 2 years ago

Ok, great news, I got everything working, although it was work, haha :) Here is a video: https://www.youtube.com/watch?v=Ui__2O9qBac

I was not able to use your gif viewer due to the bug I described in https://github.com/moononournation/Arduino_GFX/issues/108 , but I used the one I had and that works in Framebuffer::GFX. The gif is rendered in the framebuffer and then sent to the SSD1331. It's wasteful of memory, but it works.

The ILI9341 is split in 2. The top is also run by Framebuffer::GFX + FastLED_ArduinoGFX_TFT which then sends that 2nd framebuffer to your library (thank you again for that code). The 2nd half the screen, I talk to through your lib directly with adafruit calls since there isn't enough memory to hold everything in framebuffers, but at the same time, it's not needed either when only using adafruit::GFX

marcmerlin commented 2 years ago

Given that I don't have a good generic solution for this issue, I'm fine if you close it. At least this issue is searchable and maybe someone with the same problem can find it later.

moononournation commented 2 years ago

I am building a testing breadboard with 4 different displays on it for testing all multiple display code. I will test this case using it. But my progress is really really slow ;P

marcmerlin commented 2 years ago

Totally understood. Also the problem is when I made mine a while ago to test my library (the one I later ported from adafruit to your lib), the extra wiring caused problems with SPI and I had to bring the speed down to 20Mhz or it would fail image

Either way, take your time, thanks again for your work.

moononournation commented 2 years ago

I have just tested with latest MultipleDisplay example, both init ILI9341 begin() first or last still can work fine at 40 MHz.