ILI9488_t3 - Support for the ILI9488 on T3.x and beyond...

KurtE

Senior Member+
This is a modified version of the official PJRC ILI9341_t3 library (https://github.com/PaulStoffregen/ILI9341_t3) to work with ILI9488 displays. And it is always a Work In Progress.

[Warning] Currently the library has been verified to work with Teensy 3.2 (no framebuffer), T3.5, T3.6 and newer Teensies. Teensy LC is not supported at this time.

This library borrows some concepts and functionality from another ILI9341 library, https://github.com/KurtE/ILI9341_t3n. It also incorporates functionality from the TFT_ILI9341_ESP, https://github.com/Bodmer/TFT_ILI9341_ESP, for additional functions:
Code:
    int16_t  drawNumber(long long_num,int poX, int poY);
    int16_t  drawFloat(float floatNumber,int decimal,int poX, int poY);   
    int16_t drawString(const String& string, int poX, int poY);
    int16_t drawString1(char string[], int16_t len, int poX, int poY);
    void setTextDatum(uint8_t datum);

In addition, scrolling text has been added using appropriate function from, https://github.com/vitormhenrique/ILI9341_t3:
Code:
    void enableScroll(void);
    void resetScrollBackgroundColor(uint16_t color);
    void setScrollTextArea(int16_t x, int16_t y, int16_t w, int16_t h);
    void setScrollBackgroundColor(uint16_t color);
    void scrollTextArea(uint8_t scrollSize);
    void resetScrollBackgroundColor(uint16_t color);
This library was created to allow extended use on the ILI9488 larger display and supports T3.5, t3.6 and beyond.
For further development status see: https://forum.pjrc.com/threads/55735-ILI9488_t3-Support-for-the-ILI9488-on-T3-x-and-beyond
Frame Buffer

The teensy 3.6 and now 3.5 have a lot more memory than previous Teensy processors, so on these boards, I borrowed some ideas from the ILI9341_t3DMA library and added code to be able to use a logical Frame Buffer. To enable this I added a couple of API's
Code:
    uint8_t useFrameBuffer(boolean b) - if b non-zero it will allocate memory and start using
    void	freeFrameBuffer(void) - Will free up the memory that was used.
    void	updateScreen(void); - Will update the screen with all of your updates...
	void	setFrameBuffer(uint16_t *frame_buffer); - Now have the ability allocate the frame buffer and pass it in, to avoid use of malloc
Asynchronous Update support (Frame buffer)

The code now has support to use DMA for Asynchronous updates of the screen. You can choose to do the updates once or in continuous mode. Note: I mainly use the oneshot as I prefer more control on when the screen updates which helps to minimize things like flashing and tearing. Some of the New methods for this include:
Code:
	bool	updateScreenAsync(bool update_cont = false); - Starts an update either one shot or continuous
	void	waitUpdateAsyncComplete(void);  - Wait for any active update to complete
	void	endUpdateAsync();			 - Turn of the continuous mode.
	boolean	asyncUpdateActive(void)      - Lets you know if an async operation is still active

Additional APIs
In particular it now supports, the ability to set a clipping rectangle as well as setting an origin that is used with the drawing primitives. These new API's include:
Code:
	void setOrigin(int16_t x = 0, int16_t y = 0); 
	void getOrigin(int16_t* x, int16_t* y);
	void setClipRect(int16_t x1, int16_t y1, int16_t w, int16_t h); 
	void setClipRect();
 
Last edited by a moderator:
Continued from: https://forum.pjrc.com/threads/54711-Teensy-4-0-First-Beta-Test?p=203046&viewfull=1#post203046

Last posting there:
I am also wondering about the font text char output if it has any issues or not... Probably should try it on ILI9341 as well, but if you update my test case program like:
Code:
//=============================================================================
//=============================================================================

#include <ILI9488_t3.h>
#include <ILI9488_t3_font_Arial.h>
#define TFT_RST 8
#define TFT_DC 10
#define TFT_CS 9
ILI9488_t3 tft = ILI9488_t3(TFT_CS, TFT_DC, TFT_RST);
//=============================================================================
// Setup
//=============================================================================
void setup()
{
  tft.begin();
  tft.setRotation(3); // 180
  delay(100);

  tft.fillScreen(ILI9488_BLACK);
  delay(250);
  tft.fillScreen(ILI9488_RED);
  delay(250);
  tft.fillScreen(ILI9488_BLUE);
  delay(250);
  tft.fillScreen(ILI9488_GREEN);
  delay(250);
  tft.fillScreen(ILI9488_BLACK);
  

  drawColor(0, 0, "Red", ILI9488_RED);
  drawColor(0, 80, "Green", ILI9488_GREEN);
  drawColor(0, 160, "Blue", ILI9488_BLUE);
  drawColor(0, 240, "White", ILI9488_WHITE);

  drawColor(240, 0, "Yellow", ILI9488_YELLOW);
  drawColor(240, 80, "Orange", ILI9488_ORANGE);
  drawColor(240, 160, "Cyan", ILI9488_CYAN);
  drawColor(240, 240, "Pink", ILI9488_PINK);
}

void drawColor(uint16_t x, uint16_t y, const char *psz, uint16_t color)
{
  tft.setFontAdafruit();
  tft.setTextColor(color);
  tft.setTextSize(2);
  tft.setCursor(x,y);
  tft.print(psz);
  tft.drawRect(x+100, y, 50, 50, color);
  tft.fillRect(x+110, y+10, 30, 30, color);
  tft.drawLine(x+100, y+70,x+200, y+70, color);
  tft.drawLine(x+220, y, x+220, y+70, color);
  tft.drawLine(x+100, y+70, x+220, y, color); 
  tft.drawCircle(x+50, y+50, 30, color);
  tft.fillCircle(x+50, y+50, 20, color);  
  tft.setFont(Arial_12);
  tft.setCursor(x+160, y+50);
  tft.print(psz);
}


//=============================================================================
// Loop
//=============================================================================
void loop()
{
}
The text looks like it might be missing some pixels... Looked worse with with Arial_10...

Might simply be the font is not well tuned for this display the Bold version looks OK: tft.setFont(Arial_12_Bold);
 
@KurtE

Just updated the sketch and played around with Arial fonts and it doesn't look like it is - looked at it under a magnifier. You think the issue may be with the font being really setup for a 320x240 display vs a 480x320.

As for fifosize I did find this in the SPI library:
Code:
hardware().queue_size
Is that what you were referring to as a substitute for fifosize?

Sorry put this in the wrong thread
 
@KurtE

Just updated the sketch and played around with Arial fonts and it doesn't look like it is - looked at it under a magnifier. You think the issue may be with the font being really setup for a 320x240 display vs a 480x320.

As for fifosize I did find this in the SPI library:
Code:
hardware().queue_size
Is that what you were referring to as a substitute for fifosize?

Yes, that should be the one.
If you look in SPI.cpp, you will see at about line 227 for T3.5/6 that SPI0 has queue of 4 and SPI1 (line 241) has a value 1 likewise for SPI2...

For the most part it does not mater in a lot of the code except keeping from over filling. Where it first hit me on the ili9341_t3n conversion was in places like readPixel. For example if you look at
/
current ili9341_t3 implementation, not this may be my slightly hacked up version::
Code:
uint16_t ILI9341_t3::readPixel(int16_t x, int16_t y)
{
   if (_miso == 0xff) return 0xffff;	// bail if not valid miso
	uint8_t dummy __attribute__((unused));
	uint8_t r,g,b;

	beginSPITransaction(ILI9341_SPICLOCK_READ);

	setAddr(x, y, x, y);
	writecommand_cont(ILI9341_RAMRD); // read from RAM
	waitTransmitComplete();

	// Push 4 bytes over SPI
	KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0)| SPI_PUSHR_CONT;
	waitFifoEmpty();    // wait for both queues to be empty.

	KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0)| SPI_PUSHR_CONT;
	KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0)| SPI_PUSHR_CONT;
	KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0)| SPI_PUSHR_EOQ;

	// Wait for End of Queue
	while ((KINETISK_SPI0.SR & SPI_SR_EOQF) == 0) ;
	KINETISK_SPI0.SR = SPI_SR_EOQF;  // make sure it is clear

	// Read Pixel Data
	dummy = KINETISK_SPI0.POPR;	// Read a DUMMY byte of GRAM
	r = KINETISK_SPI0.POPR;		// Read a RED byte of GRAM
	g = KINETISK_SPI0.POPR;		// Read a GREEN byte of GRAM
	b = KINETISK_SPI0.POPR;		// Read a BLUE byte of GRAM

	endSPITransaction();
	return color565(r,g,b);
}
This will not work when queue size is 1... Hard to hold all 3 values for the POPR in a 1 position queue...

And yes I think the issue may be the font is not right for this size display
 
Last edited:
link to GitHub work and displays used/test:

GitHub? :: https://github.com/mjs513/ILI9488_t3

Following Paul's link to what he has I got two of these that work - except the MISO pin is not TriStated - so either no Touch use or no display ReadRect
aliexpress … 3-5-inch-480-320-SPI-Serial-TFT-LCD-Module-Display-Screen-with-Touch-Panel-Driver
> This device has same single row pin layout ordering as the well tested 2.8" ili9341

Yep and yep. The display looks like the one I am using but I cant touch working on anything but the Teensy64 even with displays direct from PRJC. That's another project for another day to deal with.
 
@KurtE
Yes, that should be the one.
If you look in SPI.cpp, you will see at about line 227 for T3.5/6 that SPI0 has queue of 4 and SPI1 (line 241) has a value 1 likewise for SPI2...
So pretty much for the displays you want to keep things on SPI0.

Been trying to use get into the ili9488 lib but its getting complicated. Can't just reference hardware()…. not sure how to do that.

Going to go ahead and push the changes I made to fillrect and for kineticsk changes.
 
That would be preferred for highest performance... (of course things are different on T$)... And the readPixel code in ili9341_t3n was redone to work with smaller queue...

Sounds good for pushing up the changes...

Today I received from Amazon a cheap ST7789 display that I thought I would try out the GFX library issue in other thread, but not sure how to hook it up? ... (details in the Adafruit GFX not working thread)
 
link to GitHub work and displays used/test:

GitHub? :: https://github.com/mjs513/ILI9488_t3

Following Paul's link to what he has I got two of these that work - except the MISO pin is not TriStated - so either no Touch use or no display ReadRect
aliexpress … 3-5-inch-480-320-SPI-Serial-TFT-LCD-Module-Display-Screen-with-Touch-Panel-Driver
> This device has same single row pin layout ordering as the well tested 2.8" ili9341

@defragster
So basically after reading the PRJC page of tri-state spi you need a buffer circuit that looks like the one on cc3000 from adafruit:
Capture.JPG

Well another redesign for me :) Easy enough though

NOTE: VBAT would be 3.3v
 
@KurtE, @defragster and others

Can't figure out how to get access to hardware().queue_size. Maybe a lightning bolt will hit me :)

EDIT: Got it working but its a kludge....
 
Github refresh change … 31 seconds ago … :)

Not sure if KurtE has gotten 9488/9341 plugged into a Teensy64 on his end? @mjs513 - not sure what is up with yours? It should work with the linked display - except that MISO 3state :(. Seeing it work with provided pin #defines on the v0.1 and v0.3 is very nice and they both have USB host connector - other pins likely consumed in large part, but nice having display solid on standoffs. I have a pair of 1st & 2nd version for VGA too.
 
Github refresh change … 31 seconds ago … :)

Not sure if KurtE has gotten 9488/9341 plugged into a Teensy64 on his end? @mjs513 - not sure what is up with yours? It should work with the linked display - except that MISO 3state :(. Seeing it work with provided pin #defines on the v0.1 and v0.3 is very nice and they both have USB host connector - other pins likely consumed in large part, but nice having display solid on standoffs. I have a pair of 1st & 2nd version for VGA too.

@defragster
Got the fix in to use the ili9488 lib with a T3.6. The display works fine no problem on the Teensy64, touch is not working. Touch works on the Teensy64 but on the T4 or with a T3.6 using SPI so not sure whats up with that.
 
@defragster
Got the fix in to use the ili9488 lib with a T3.6. The display works fine no problem on the Teensy64, touch is not working. Touch works on the Teensy64 but on the T4 or with a T3.6 using SPI so not sure whats up with that.

Sounds good. The Touch will work if the MISO from TFT were cut - but then no display reading.

A shame touch seems useful - just seeing the second glare layer on the 9488 sitting here at an angle - the screen would be clearer and brighter if ordered without ( an option that saves $1 ) the Touch plastic layer overlay. Paul's '2017 large display' post noted that design would require Capacitive touch - not sure if that is much better - even modern phones - improving but still - suffer from the touch overlay in bright light.
 
@defragster, @KurtE and others

Ok, I got the sn74ahc1g125 ordered. But I do have a question, OEbar in the diagram is tied to say the display CS. Is this all I need - what about T_CS? Do I also add pull up resistors to the CS lines?
 
don't know the sn74ahc1g125 device - but AFAIK TFT_CS select (LOW) should enable the MISO signal. When TFT_CS is not selected it needs to tri-state on the common MISO line. When inactive all CS lines need to go high so adding pullups won't hurt - but needing to add them depends on having more than one device and not having them default to high when not selected? Since the Touch hardware MISO does tristate and T_CS is handled properly with that it works without add/change in hardware.

I noticed when I was having ILI_TFT issues it turned out to be the reset line - most obvious when the default in the sketches used 8 and I had 23 wired for reset before. Not sure if that is behind my T$_breakout issue - but I thought reset wired HIGH and providing 255 for pin # made it work?
 
@defragster - Yes I have one of Franks board, which has T3.6 in it and tested some of the USB Host stuff with it recently.

@mjs513 @defragster ...
As for This display I have a different one than you all have. By BuyDisplay.com... I have not tried out their touch stuff, nor anything else on the SPI buss...

Maybe I should try out their touch interface.

With the displays you have, You of course maybe have the option of using a different SPI buss for the touch versus the display. With T3.5/6 you can use SPI1 or SPI2 to do this.
For T$, we could make a version of the touch library that uses the SPI I created with Flex IO...
 
Might be a fun/good FlexSpi test for Touch - but lots of extra wires and 'wasted' pins for real usage.

Other than downloading and compiling with - I have not followed or looked at the code - is it using MISO to read for scroll - or other method?

My SPEED note on 9488 - where I bumped T$ along with T_3.6 to 60 MHz - I'm not sure what the T$ is limited by and which it best speed - but 60M worked and then ran faster than T_3.6.
 
DemoSauce_9488 working T_3.6 {teensy64} and T$::

<EDIT>: Twice now after some short couple dozen iterations the T$ 9488 goes WHITE and USB stats keep printing? TyComm Reset brings it back up, T_3.6 running not showing that.
<EDIT>: 3rd time - sometime in 134 test parts T$ 9488 is blank white again- but code still running … wonder if it is the TFT as that is how they seem to fail … then work for a while … I'll swap the 2 here

ili9488 DemoSauce runs looking as ili9341 noted on T4 thread - T$ cube jumpy, T_3.6 no leaves {all white} and the other <edit> all yellow WaveForm, and blank PlasmaYellow. <edit> T-3.6 'TriangleWeb' doesn't show with same contrast either?

Also so I can stop re-editing - here is the .h for the SPI speed HACK - and the SUM time edits for graphicsTest
<opps>: That .h SPI speed only crudely accounts for T_3.6 and T$ - T_3.5 don't have an #else
@mjs513 - let me know if you can merge ...- just opened code compare and got an update.

T_3.6 at 256 MHz with 60 MHz SPI {theoretical T4 #}:
---
TwistyText
Frame count (more is better): 885 {1192}
---
PlasmaCloud [20 secs]
Frame count (more is better): 377 (18.85 FPS) {375 (18.75 FPS)}
---
Waveform [20 secs]
Frame count (more is better): 66972 (3348.60 FPS) {79159 (3957.95 FPS)}
---
MagentaSquares [20 secs]
Frame count (more is better): 723 (36.15 FPS) {734 (36.70 FPS)}
---
Sphere3D [20 secs]
Frame count (more is better): 709 (35.45 FPS) {608 (30.40 FPS)}
---
Checkerboard [20 secs]
Frame count (more is better): 144 (7.20 FPS) {198 (9.90 FPS)}
---
Leaves [20 secs]
Frame count (more is better): 1259 (62.95 FPS) {1079 (53.95 FPS)}
---
Cube3D [20 secs]
Frame count (more is better): 1479 (73.95 FPS) {1034 (51.70 FPS)}
---
PlasmaYellow [20 secs]
Frame count (more is better): 747 (37.35 FPS) {745 (37.25 FPS)}
---
TriangleWeb [20 secs]
Frame count (more is better): 1021 (51.05 FPS) {956 (47.80 FPS)}

<edit> displays swapped and counter added … counting to 50 good so far - if fail will see after ZZzzz's
 
Last edited:
Good news is it doesn't seem to follow the Display!

Bad news I just saw the T$ screen go/stay all white for 20 and counting more Animations - as before the T_3.6 keeps ticking - on the 9341 it ran 12-16 hours on both.

This made something up to 80 animations … 3/min is about 26 minutes. Order goes Random after first pass … not sure if a general fail or something specific - order or runtime?

Again TyComm 'reset' starts fresh … but just did power off restart - though it was off for TFT swap.

Will look for another fail then maybe disable random to see if fixed order acts diff - then reorder test array to the following … could also be the transition code used ...

Code:
PlasmaYellow  [20 secs]
Frame count (more is better):  746  (37.30 FPS) Anim# 70
---
TwistyText
Frame count (more is better):  1183 Anim# 71
---
MagentaSquares  [20 secs]
Frame count (more is better):  734  (36.70 FPS) Anim# 72
---
Cube3D  [20 secs]
Frame count (more is better):  1032  (51.60 FPS) Anim# 73
---
PlasmaYellow  [20 secs]
Frame count (more is better):  745  (37.25 FPS) Anim# 74
---
Sphere3D  [20 secs]
Frame count (more is better):  609  (30.45 FPS) Anim# 75
---
TriangleWeb  [20 secs]
Frame count (more is better):  905  (45.25 FPS) Anim# 76
---
Waveform  [20 secs]
Frame count (more is better):  79197  (3959.85 FPS) Anim# 77
---
PlasmaCloud  [20 secs]
Frame count (more is better):  375  (18.75 FPS) Anim# 78
---
Leaves  [20 secs]
Frame count (more is better):  1078  (53.90 FPS) [COLOR="#FF0000"]Anim# 79[/COLOR]
---
Checkerboard  [20 secs]
Frame count (more is better):  198  (9.90 FPS) [COLOR="#FF0000"]Anim# 80[/COLOR]

Away an hour and back to white over 170 Anims … just stopped shuffle … transitions still random, but not noted which …

T_3.6 untouched and good at 296 Anims.
 
Last edited:
@defragster
I have been running with normal SPI (30Mhz) on the T$ for over an hour with about 330 10sec animations with no issue. Going to let it run while I go out and do some errands and see where we are when I get back. Will keep you updated.
 
My guess is 60mhz is pushing it, especially depending on how well the display is connected (hard connections short lines...)
 
I know there was a lot of SPI clock tests done on the beta thread but can't seem to find it now. But @KurtE is probably correct.

Also seems like for these long duration tests we should wait until the new board is out for testing,. Just a thought.
 
@KurtE and @defragster

Running for 3 hours with a break when the computer went to sleep. However, the sketch and display started right back up when the PC came out of sleep. Its up to about 900 cycles. So think the problem maybe as Kurt said the SPI speed too fast at 64Mhz
 
Longer time is a handy thing as I get interrupted … I just leave it run. Also not bad for a baseline … just like recording speed/times - in case something goes better/worse when is easy to see.

Good idea … I dropped back to :: ILI9488_SPICLOCK 30000000

Running overnight with [1 secs] interval was white by breakfast - was good with 790 1 secs interval test first thing this AM - just went back to 20 secs at 30M SPI … will see in 30 minutes if it was that.

Maybe there is a better T$ bus multiple for a speed over 30M … the T_3.6 is running perfectly fine with 1574 [20 secs] Animations.

Quick scan of the code and normalized calling interface from array - very odd that T_3.6 display has some Animations that don't run the same as T$ - unless they are using that 'mic' input ?

Nice Teensy woke with the computer - mine has always waited when SerMon left - except as noted last on T4 thread. This PC never sleeps … but I did close and update TyComm to 0.8.11
 
Longer time is a handy thing as I get interrupted … I just leave it run. Also not bad for a baseline … just like recording speed/times - in case something goes better/worse when is easy to see.

Good idea … I dropped back to :: ILI9488_SPICLOCK 30000000

Running overnight with [1 secs] interval was white by breakfast - was good with 790 1 secs interval test first thing this AM - just went back to 20 secs at 30M SPI … will see in 30 minutes if it was that.

Maybe there is a better T$ bus multiple for a speed over 30M … the T_3.6 is running perfectly fine with 1574 [20 secs] Animations.

Quick scan of the code and normalized calling interface from array - very odd that T_3.6 display has some Animations that don't run the same as T$ - unless they are using that 'mic' input ?

Nice Teensy woke with the computer - mine has always waited when SerMon left - except as noted last on T4 thread. This PC never sleeps … but I did close and update TyComm to 0.8.11

I just deleted mic/backlight lines and then changed analogRead(micpin) to random(0,1023). Works better and more consistently.

Know there was a lot of discussion on the other thread about SPI speed over 30M. I just couldn't find the right post - I remember it clearly, but too much over there.

@KurtE and @defragster,
I pushed up a new branch for framebuffer that I am working on. No DMA stuff though - do it need to get that incorporated as well for framebuffer to work?

EDIT: Just a major issue - Keep getting a 45K memory overflow using the ILI9488 480x320 display.
 
Last edited:
Back
Top