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

Problem setting up T4.1 on SPI0 #2

Closed FZFalzar closed 2 years ago

FZFalzar commented 2 years ago

Hi, I am trying to compile and run some examples from your library + tgx but I am running into an error at

if (!_pspi->pinIsChipSelect(_dc)) in tft.begin()

The pins that I am using are: `

define TFT_DC 9

define TFT_CS 10

define TFT_SCLK 13

define TFT_MOSI 11

define TFT_MISO 12

`

I am not sure if the DC pin on teensy 4.1 must be a specific pin like the others

I have verified that these pins are working and I can run demos from the ILI9341_t3n library fine

FZFalzar commented 2 years ago

Okay I caught notice of the DC and CS pin being swapped around on the readme, but even after changing it and calling it as such, I am still unable to initialize the screen (it turns grey/black)

ILI9341_T4::ILI9341Driver tft(TFT_DC, TFT_CS, TFT_SCLK, TFT_MOSI, TFT_MISO); where the TFT_DC and TFT_CS fields are swapped

vindar commented 2 years ago

Hello,

Yes, it is strange but indeed, it is the DC pin from the ILI9341 which must be connected to a 'CS specific' pin on the Teensy...

In your second message, you say you swapped the TFT_DC and TFT_CS fields but did you physically connect the DC pin from the ILI screen to pin 10 on the teensy and the CS pin from the ILI screen to pin 9 on the Teensy ?

Also, did you connect the RESET and BACKLIGHT pin from the ILI9341 ? At least the screen should light up. when the BACKLIGHT pin is high.

I am attaching an .ino script for the luftballon example that is using SPI0 on Teensy 4 and which works for me. Can you try it to see if it works for you also ?

99luftballons.zip

The physical connections between the Teensy and the screen are as follow:

ILI9341 Teensy
SCK 13
SDO (miso) 12
SDI (mosi) 11
DC 10
CS 9
RESET 6 (you could use any pin)
LED 5 (you could use any pin or connect directly to +3.3v)

Other pins for touch (T_CLK, T_CS, T_DIN, T_DO, T_IRQ) not connected.

Best, Arvind

FZFalzar commented 2 years ago

My backlight and reset pins are pulled high constantly following the official pin list on https://www.pjrc.com/store/display_ili9341_touch.html (backlight on +5V, RESET on +3.3V), so the screen definitely comes on and I can run the examples such as the demoscenes from ILI9341_t3n using the exact same pinouts

I have tried running the example you provided (before and after swapping DC/CS pins physically) but I end up with initialization error on both connection methods. Specifically, when DC was connected to pin 10 and CS on pin 9, the screen momentarily flashed from white to slightly grey, but nothing else happened.

I will attempt to use SPI1 and see what happens (with the default provided examples) later.

Just for additional info, I am trying to use your library to get a DMA double buffering setup combined with https://github.com/lvgl/lvgl, with tgx as the drawing provider

vindar commented 2 years ago

This is a strange one: I just tried the code from my previous post with a Teensy 4.1 and it works for me. I also tried moving RESET to +3.3V and LED to +5V as you did and it is still ok...

Some random ideas:

  1. Try connecting RESET to a Teensy pin and let the driver know about it (e.g. pin 6 in the example code above). This way the driver will reset the screen during initialization if it detects a problem.
  2. The screen becoming slightly grey is a good sign. Do not forget to open the serial console otherwise the screen initialization may take longer.
  3. Do not connect any of the touchscreen pin (at first). Connecting them on the same bus can mess up the SPI connection.
  4. Try a lower SPI speed such as tft.begin(10000000, 1000000) to see if it helps. If so, the wires may be a bit too long...
  5. Diminish the screen refresh rate: tft.setRefreshRate(60) to check if your screen might have trouble handling high refresh rates.

here is a picture of my wiring while running the code I posted above, and with RESET to 3.3V (the long yellow wire) and LED to +5V (the long blue wire). However, I still strongly advise using a dedicated pin for RESET. The +5V comes from the breadboard sides and the +3.3V from the Teensy 3.3V regulator.

IMG_20210728_004652

IMG_20210728_005841

FZFalzar commented 2 years ago

So I swapped all the physical pins to use SPI1 with the touchscreen disconnected, following this original setup in the example:

#define PIN_MISO        1
#define PIN_MOSI        26
#define PIN_DC          0
#define PIN_RESET       29
#define PIN_CS          30
#define PIN_BACKLIGHT   28  // 255 if not connected to MCU. 

and was able to run both the examples in here and tgx (the characters demo was especially impressive!)

After that, I swapped back to SPI0 using the following (touchscreen still disconnected) and was able to run it

#define PIN_SCK     13
#define PIN_MISO    12
#define PIN_MOSI    11
#define PIN_DC      10
#define PIN_RESET   6
#define PIN_CS      9
#define PIN_BACKLIGHT   255  // 255 if not connected to MCU. 
#define PIN_TOUCH_IRQ 255  // 255 if not used (or not on the same spi bus)
#define PIN_TOUCH_CS  255  // 255 if not used (or not on the same spi bus)

I then connected the touchscreen back and then there was no issue Later on I removed the existing dependency from my project on XPT2046_TouchScreen.h to use yours, and still no problem

I finally narrowed the problem down to the RESET pin, for some reason pulling it up to +3.3V is causing issues. However in my PCB design I have already fabricated a design where RESET is pulled high to +3.3V so I am not sure what is the difference your library is causing versus ILI9341_t3n at the moment

vindar commented 2 years ago

Hi,

Good to know you did manage to make it work ! Unfortunately, I have found after several tests that the ILI9341 screen cannot be correctly reset via software. Sometimes, after issuing the SW_RESET spi command, the PASET/CASET commands become corrupted... These two commands play a critical role in my library for diff updates. As this is not the the case with KurtE's ILI9341_t3n library, it may explain why your code works with his lib...

Anyway, I just changed a few lines in the initialization code to improve compatibility when the reset pin is not available. You may try it to see if it mitigates your problem but I am not very hopeful.

FZFalzar commented 2 years ago

Hi, sorry for the delay, I tried the new code and unfortunately it is still not working

My pins for my pcb have the DC and CS reversed (ILI9341_t3n compatibility) so I manually swapped them in the initialization code

before:
ILI9341_T4::ILI9341Driver tft(PIN_CS, PIN_DC, PIN_SCK, PIN_MOSI, PIN_MISO, PIN_RESET, PIN_TOUCH_CS, PIN_TOUCH_IRQ);

after:
ILI9341_T4::ILI9341Driver tft(PIN_DC, PIN_CS, PIN_SCK, PIN_MOSI, PIN_MISO, PIN_RESET, PIN_TOUCH_CS, PIN_TOUCH_IRQ);

What I have observed however is the screen flashes black->white upon every attempted reset(?) cycle with RESET as 255, before it prints Error initializing lcd, so one of the changes made must have been working but there may be some other commands that need modification

vindar commented 2 years ago

Hi,

Sorry, I am just realizing that your connexions are hardwired so you cannot change them... Then unfortunately, if the DC pin on your screen is not physically wired to a CS compatible pin on the teensy on your PCB, then there is no way that the library will work. When using SPI0, this means that DC must be physically connected to pin 10 on the teensy (or pin 36 or 37).

The reason for this requirement is that the library sends a lots of commands when performing differential updates (possibly 1000s in a single transfer) so it needs to toogle the DC line extremely fast. This can only be done by toogling DC via the spi hardware like a CS pin instead of using digitalWrite() which would not be synchronous with the MOSI line... On the other hand, the CS pin itself is not really important since it is used only at the beginning and end of a transfer which is why any digital pin can do the job.

Other library such as ILI9341_t3 and ILI9342_t3n do not have this requirement because they are sending only a couple of commands per frame (because the whole screen is being redrawn) so they do not care if sending commands is slow.

As a side note, Your wiring is the one recommended for the original ili9341_t3 library but not for the ili9341_t3n library. For that second library, same as for mine, it is better to connect DC to as CS compatible pin as this will give you the best performance (in fact, I learned the trick that DC can be used as a CS pin from this library). In particular, the wiring I gave in my first post will work with both my library and ili9341_t3n (I do not know if it will work with the original ili9341 lib).

For details, see KurtE's answer in this forum thread: https://forum.pjrc.com/threads/66100-Alternate-pins-for-ILI9341-and-SPI-flash-in-T4-1

I am sorry you probably won't be able to use my lib with your PCB but, on the bright side, KurtE's ili8341_t3n is already really fast so it should still work well for your project.

FZFalzar commented 2 years ago

Hi, thanks for looking into it, I think I am out of luck there and will have to use the existing libraries instead of yours. While I can revise the PCB, I consider that a nuclear option for now.

I will close this issue, all the best for your library!

vindar commented 2 years ago

Hi,

I do not know whether you you are still interested in driving a ILI9341 screen but I just want to let you know that I made some changes to the library and CS and DC can now use any pin on the Teensy...