ILI948x_t41_p - a parallel display driver for Teensy 4.1

@Rezo
It actually hangs on drawing circles

Code:
Benchmark                Time (microseconds)
Screen fill              380144
Lines                    287210
Horiz/Vert Lines         37025
Circles (filled)
 
TBH as long as you are not writing into a temp buffer that is bigger than 32 bytes (can’t recall what I set it to in the DMA setup function), DMA will have no advantage here
 
@mjs513 - I have the library working on the dev 4.0 board. Excuse the poor picture quality. It is actually green and uniform. I could blame it on the phone but it's probably me:D

ILI9486_GFX.jpg

Will play some more with it...
 
@mjs513 - I have the library working on the dev 4.0 board. Excuse the poor picture quality. It is actually green and uniform. I could blame it on the phone but it's probably me:D
Thanks for testing the lib - now I guess for text :) and its never me :) :)
 
Thanks for testing the lib - now I guess for text :) and its never me :) :)
When I was developing my VGA_4BIT_T4 library I had to do the same thing with text and fonts. I based a lot of the text and graphics on the uVGA library and the VGA_T4 library which was also based on uVGA. Hopefully it is simpler than dealing with 4 bits per pixel :D @jmarsh helped alot with that. I can also start playing with it...
 
When I was developing my VGA_4BIT_T4 library I had to do the same thing with text and fonts. I based a lot of the text and graphics on the uVGA library and the VGA_T4 library which was also based on uVGA. Hopefully it is simpler than dealing with 4 bits per pixel :D @jmarsh helped alot with that. I can also start playing with it...
Pretty much its going to be a copy/paste/edit operation from ILI9488_t3 lib. So just going to take time - lots of bits and pieces with what we did text :)
 
Can probably simplify from what is in
Pretty much it’s going to be a copy/paste/edit operation from ILI9488_t3 lib. So just going to take time - lots of bits and pieces with what we did text :)
as probably only deal with 16 bit pixels, where with spi stuff, we had 8 16 24 bit pixels
 
@KurtE - @Rezo - @wwatson
I have been a little busy with this stuff over the last couple of days so here goes the latest set of changes.

1. Broke out the Graphics stuff into a separate library Teensy_Parallel_GFX so it can be used with the Teensy4.1 and Teensy4.0 versions of your lib

2. The GFX lib now has the Font stuff working as we use in the SPI version of the ILI9488 lib which means Adafruit and ILI9341 fonts are supported. Right now I have not updated the ILI9341_fonts lib so its not available yet.

3. Restructured the Parallel lib to put the files in a src folder and added library.properties file.

4. @KurtE made a change to fillRect so it speeds up some of the graphics a bit:
Code:
Benchmark                Time (microseconds)
Screen fill              122895
Text                     9721
Lines                    292506
Horiz/Vert Lines         10925
Circles (filled)         94321
Circles (outline)        140213
Rectangles (outline)     6730
Rectangles (filled)      297103
Triangles (outline)      56165
Triangles (filled)       122857
Rounded rects (outline)  44643
Rounded rects (filled)   342493
Done!
 
That is looking great, and fast!
Happy to see what you have been able to do with the original library

EDIT
And I see you got the 9488 working in 8 bit mode!
 
Last edited:
I thought I would mention, that @mjs513 and myself have been playing around with enabling the read operations to these
displays. This includes both reading in register settings and now reading in Pixel data.

So for example with my Amazon purchased display: The startup code is now displaying:
Code:
Bus speed: 16 Mhz Div: 20
ILI9486 Initialized
Manufacturer ID: 0x54
Module Version ID: 0x80
Module ID: 0x66
Display Power Mode: 0x9C
MADCTL Mode: 0x48
Pixel Format: 0x55
Image Format: 0x00
Signal Mode: 0x00
Self Diagnostic: OK (0xC0)
Device Information: 548066
Device Status: A4530400
    Order: BGR
    interface pixel format: 16 bit

This is from one of my test sketches we ported to this setup:
1718113598016.png


It does not looks like much... But it shows several of the graphic primitives,
like writeRect, writeRect1BPP...
The color bars toward the bottom of the display, the top half was done by calling fillRect 8 times with different colors.
I then did a readRect of that area, and and a drawRect just below it... And they match.

Likewise, the Test and part of Tex text toward the top rightish is from a readRect/writeRect from the left side...

Still working out the differences between ILI9488 and ILI9486 on the return format...

Now back to playing
 
@Rezo
Just to add to what @KurtE said, since I am using the BuyDisplay ILI9488 versus the Arduino board which looks like its a ILI9486.

We finally got the ILI9488 buydisplay working like shown he the Arduino Display image by reading 3 bytes of data (r,g,b) vs 2 bytes need for the ILI9486.

The one difference we are seeing is the pixel format is 16 bit for both devices but the pixel format (0x3A) is a bit different:
Arduino ILI9486 - Pixel Format: 0x55
while
BuyDisplay ILI9488 - Pixel Format: 0x05
even though both are set in the sketch as setBitDepth(16)

This is what we are playing with now - at least one of them.
 
@KurtE @mjs513 I am very stoked to see the both of you taking this library to the next level!
I personally won’t benefit from the graphics primitives added, but others here most definitely will, and it will make this library more usable to the general forum audience - so Kudos for diving into it!

@Rezo
Just to add to what @KurtE said, since I am using the BuyDisplay ILI9488 versus the Arduino board which looks like its a ILI9486.

We finally got the ILI9488 buydisplay working like shown he the Arduino Display image by reading 3 bytes of data (r,g,b) vs 2 bytes need for the ILI9486.

The one difference we are seeing is the pixel format is 16 bit for both devices but the pixel format (0x3A) is a bit different:
Arduino ILI9486 - Pixel Format: 0x55
while
BuyDisplay ILI9488 - Pixel Format: 0x05
even though both are set in the sketch as setBitDepth(16)

This is what we are playing with now - at least one of them.
I think it’s worth defining a struct that will hold the init commands and the various command values for the variants, such as the pixel format value, rotation register values etc.
Use a pointer in the begin function to load the display config.

This would make it much easier and flexible to add support for more displays in the future.

What do you think?
 
@K7MDL asked me if I would post a link to his library he and I were working on while I was writing the driver for the Teensy in FlexIO 8080 parallel mode. He was a big help in testing and debugging using the MicroMod and the RA8876. This library is meant to be used with the MicroMod and the BuyDisplay TFT0784 display. His library is a stripped down version of the Ra8876LiteTeensy Library. I do not have that particular display so I could not test without modifying it. The library is setup to use PlatformIO. Here is link to the library if anybody is interested:
https://github.com/leutholl/TFT0784_mm/tree/main/lib
It has links to the issues thread we were using...
 
I think it’s worth defining a struct that will hold the init commands and the various command values for the variants, such as the pixel format value, rotation register values etc.
Use a pointer in the begin function to load the display config.

This would make it much easier and flexible to add support for more displays in the future.

What do you think?
Yes, it would be nice to convert all of that code that is setup for each of the displays into a table each. It might make it a lot easier to detect things like what is different between ILI9488 and ILI9486... At some point maybe someone will do so. How far does someone wish to take it...

Likewise at some point, I might be more interested in reducing how hard coded some parts are on things like pin numbers. That is
The majority of the pins are hard coded to:
Code:
Note: The are FLEXIO 2 pins on the Micromod The flexio pins shown in ()
* pin 10 - WR (0)
* pin 12 - RD (1)
* pin 40 - D0 (4)
* pin 41 - D1 (5)
* pin 42 - D2 (6)
* pin 43 - D3 (7)
* pin 44 - D4 (8)
* pin 45 - D5 (9)
* pin 6 - D6 (10)
* pin 9 - D7 (11)

I understand all of these pins need to be on the same FlexIO object and D0-D7 have to be contiguous Flexio pins.
But there are a few other FlexIO 2 pins on the Micromod:

Extracted from my readme file on flexio:
Code:
**FlexIO 2**
```
Arduino PIN:    6,       7,    8,    9,  10,    11,   12,   13,   32,   40,   41,   42,   43,   44,   45,
FlexIO pin:     10,     17,   16,   11,  0,      2,    1,    3,   12,    4,    5,    6,    7,    8,    9,

```
Ranges 0-12, 16-17

And for example, I may still need to use SPI for other purposes on the board, so would prefer to not use pins 11, 12. 13 for this.
So for example could choose pins 7 and 8 for RD and WR.

And on Teensy 4.1 could use FlexIO3, although you would lose DMA...
 
Just by way of a quick update @wwatson fixed a couple bugs that he found and we also converted the init_commands to use tables so easy enough to add a new device without having to go through all the commandvalue setup.

PS> also added scrolling text boxes like in our other display drivers.
 
Yes, it would be nice to convert all of that code that is setup for each of the displays into a table each. It might make it a lot easier to detect things like what is different between ILI9488 and ILI9486... At some point maybe someone will do so. How far does someone wish to take it...
Looks like someone did it :D
converted the init_commands to use tables so easy enough to add a new device without having to go through all the commandvalue setup.
Great Stuff:
Likewise at some point, I might be more interested in reducing how hard coded some parts are on things like pin numbers. That is
The majority of the pins are hard coded to:
Note: I have started to play with this: I have a branch in @mjs513 fork:

Where I have started working on this:
Note: There are a few optional methods in the FlexIO code which I posted about in a different thread:

I think I have modified most of the hard coded pin and FlexIO code in the library, to allow potentially any FlexIO pins that could
work: That is Data pins need to be 8 contiguous flexIO pins and RD and WR must be flexio pins on that same FlexIO object.

There is a header file, that has the default pins to use for the FlexIO. It can easily be setup to have different pins depending on which
teensy.

In addition, I added two versions of a method, setFlexIOPins. One which has 3 parameters, the write pin, read pin, and optionally Data 0 pin.
The other has 10 pins: Write, Read, Data 0, .... Data7

So far I have modified only one sketch: Kurts_ILI.._tests.ino that is in this branch.
I moved the Reset pin from pin 7 to pin 5 in the constructor. And then I setup pin 7 and 8 as the Write and Read pin.
Where I have tried running a couple different versions of these methods.

Note: These must be called before you call the begin method on the display object

Code:
tft.setFlexIOPins(7, 8);
Which simply sets Write as 7 and Read as 8

Code:
tft.setFlexIOPins(7, 8, 40);
Like above, except it sees that you want to use pin 40 as Data 0.
The method than asks FlexIO what this pin maps to FlexIO2:4
It then fills in Data1 as the pin that maps from FlexIO2:5 which is IO pin 41...

Code:
tft.setFlexIOPins(7, 8, 40, 41, 42, 43, 44, 45, 6, 9);
This case simply fills in the all of the FlexIO pins...

Note: the flexIO startup code, will validate that the items in the pin array map to contiguous FlexIO pins.

Next up, see how it might work on T4.1... I already relaxed some of the code in the library (not checked in).
And for example if I pass in:
tft.setFlexIOPins(26, 37, 19); // Teensy 4.1 pin
And run on T4.1 it computed the pins like: FlexIO pins: data: 19 18 14 15 40 41 17 16 WR:26 RD:37

So soon will hook a display up to T4.1 and debug...
I do have a few more displays coming soon. An Amazon one: tomorrow and two BuyDisplays which I don't have any clue how long
it might take... I also have a BuyDisplay RA8876 that I am also waiting for. So far it has been sitting for over a week in the state:
Code:
Pre-Shipment
Origin Post is Preparing Shipment
Processed Through Facility

SHENZHEN EMS, CHINA
June 7, 2024, 3:22 am

So it might be awhile ...
 
Note: These must be called before you call the begin method on the display object
This is similar to way we do it with the cameras as well.

I do have a few more displays coming soon. An Amazon one: tomorrow and two BuyDisplays which I don't have any clue how long
it might take... I also have a BuyDisplay RA8876 that I am also waiting for. So far it has been sitting for over a week in the state:
Mine is showing the same thing but if you translate the chinese to english from the 17allinonr link looks like its in the airlines possesion now:
1718393257660.png
 
@KurtE well done on the chages to the FlexIO library as well as the display driver.

I think this brings us closed to one library that supports all boards, be able to automatically detect which instance to use as well.
Eg 8-bit with DMA on a MicroMod using FlexIO2
16-bit with interrupts on a T4.1 using FlexIO3
Up to 24 bits with DMA on a Devboard v4.0++ using FlexIO2

Now this would also require different DMA configs for each bus width and pixel color depths.
 
Just pushed up a new branch to the Teensy_gfx library that starts support for frame buffering, https://github.com/mjs513/Teensy_Parallel_GFX/tree/framebuffer_wip.

Just running a modified graphicsTest sketch - quite a bit of a delta - still testing though.
Code:
Bus speed: 30 Mhz Div: 8
ILI9486 Initialized
Text                     430
Screen fill              2592
Lines                    4847
Horiz/Vert Lines         1092
Rectangles (outline)     413
Rectangles (filled)      6436
Circles (filled)         2558
Circles (outline)        1827
Triangles (outline)      932
Triangles (filled)       2105
Rounded rects (outline)  838
Rounded rects (filled)   12433
Done!
 
Just pushed up a new branch to the Teensy_gfx library that starts support for frame buffering, https://github.com/mjs513/Teensy_Parallel_GFX/tree/framebuffer_wip.
Great stuff, I am playing with it and looks like most things compile. I have tried to reenable the frame buffering in the fb and clip test and the screen is not changing color... Will debug. Maybe easier to restart it from another copy of that sketch, which I did not hack on...
I think this brings us closed to one library that supports all boards, be able to automatically detect which instance to use as well.
Eg 8-bit with DMA on a MicroMod using FlexIO2
16-bit with interrupts on a T4.1 using FlexIO3
Up to 24 bits with DMA on a Devboard v4.0++ using FlexIO2
Hopefully it will get closer to this. I probably won't have it automatically changing how many bits to output. Currently working
only with 8 bit...

My last delta in the WIP branch is to try to make it more configurable and hopefully play nicer with potential other FlexIO objects.

That is currently the code was hard coded to use Shifters 0 (Write) and 3 (READ), But it could have also used 4 for write and 7 for Read.
So the code now tries to claim the shifters and if 0 is not available use 4... Likewise, it tries to grab 3 and if that fails 7. Likewise I believe it could use any of the timers, so I call of to allocate one.

However, I understand that DMA probably only works on Shifters 0-3, so if it was forced to use 4 for example, DMA would stop working.

I then had to go through and hopefully update all of the places that were hard coded and use a variable for which one, and a mask that was
configured for that shifter or timer...

I also commented out all of the places that did a SWRST on the flexio object, as to keep this code from resetting the flexio from underneath any other FlexIO objects happen to be using the same IMXRT FlexIO object. Like maybe I might have a FlexIO Serial object using a few other
FlexIO Pins, timer, and shifter... So far it does not appear to hamper things.

I noticed that the functions like: FlexIO_Config_SnglBeat get called a lot. For example if you did a call like:
Code:
tft.drawRect(100, 100, 100, 100, RED);
It will call the drawFastHLine twice likewise for drawFastVLine and each of these will setAddr, and do the memory write.
So potentially 3 calls to FlexIO_Config_SnglBeat for each of the lines or up to 12 just to draw the rectangle.
(Probably only 9 times as setAddr checks if xs or ys are same as last call and then does not output them...

So I am experimenting, and have each of these functions which update the flexio settings starting off like:
Code:
FASTRUN void ILI948x_t4_mm::FlexIO_Config_SnglBeat_Read() {
    if (flex_config == CONFIG_SNGLREAD) return;
    flex_config = CONFIG_SNGLREAD;
    ...

So far it appears like it is still working. Potentially maybe some of the setting that get set each time
Although it looks like if you use Multibeat writes and then do a read operation, they will clobber each other.

Still experimenting and trying to get a better handle on how things work. I see I missed a few things like Multibeat
still has some hard coding of shifter starting at 0...

Back to playing
 
Back
Top