Author Topic: ILI9341 mental support  (Read 2295 times)

0 Members and 1 Guest are viewing this topic.

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
ILI9341 mental support
« on: January 28, 2020, 03:24:52 pm »
Hi, i am finally getting started with color display.
I got the touch screen to work and the SD-card.

I have 2 versions : 1 with touch screen and without SPI 3,2 inch, and one without touch screen and with SPI 2,8 inch.
Since i have no pins enough i go for the 2,8 SPI version for my project.

My goal : is make a game-boy like thing, a handheld game computer, based on a PIC32.
Yes there are librarys available, only i am not the arduino type.

How does it works and what does it offer ?
Or you all been downloading the librarys ?
I like to make use of all the functions inside, there is not enough space in my PIC32.
Can you write text on the backbuffer inside ?

I always have problems getting started and need some mental support.
This year i want to have it finished.

thanks
 

Online dmills

  • Super Contributor
  • ***
  • Posts: 1788
Re: ILI9341 mental support
« Reply #1 on: January 29, 2020, 03:22:37 am »
There is no double buffer as such in the thing, and it basically understands setting pixels in memory regions to colours, it has no notion of fonts or text, you got to provide that in your processor.

I usually go for 4 wire mode so that there is an explicit command/data control line, as the PIC32 does not really do 9 bit SPI which is the other choice if not doing parallel.

Aggravatingly, 320 * 240 * 16 is more then 128k, so you cannot hold a frame buffer in the pic without getting sneaky. 

It all in the (rather annoying) datasheet, which like all LCD driver datasheets omits how the gamma stuff really works, and does not give you the initialisation vector that is right for your panel (Usually you can get that off the panel vendor).

If the TE signal is available on your screen (They vary) it is worth hooking this to an interrupt line.
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 1982
  • Country: fi
    • My home page and email address
Re: ILI9341 mental support
« Reply #2 on: January 29, 2020, 05:26:02 am »
As to overall support, you might wish to use two or three microcontrollers instead of just one: one for video processing (blitter, or graphics tile processor, as most games use sprites and tiles as the basis for their graphics), one for audio processing (if wavetable synthesis and/or MP3 decoding for music is supported), and the master one for the game mechanics.

The underlying idea is that the graphics processor handles the display without tearing, and essentially contains the secondary video buffer; so having lots and lots of RAM on this one is much more important than its computational speed.  You connect it to your primary processor using some sort of a serial protocol (UART with high baudrate, I2C, or SPI).  Typically, it contains a buffer or list of tiles, rotated or mirrored (usually 8 options), with the tiles using a lookup table (often 4 or 8 bits per pixel in a tile, with the lookup table to a 16-bit RGB or 32-bit RGBA, selectable per tile).  If you have enough memory for the tiles, you can use them for fonts too.  At update time, the blitter builds each scan line, and sends it (often using DMA) to the actual display module.  A single-cycle multiplication unit should let you implement per-tile and per-pixel partial transparency as well.

In simple terms, the main processor first defines some tiles (by sending their data, unless the graphics processor uses its own microSD for the data files), and then just tells the graphics processor which tiles to display and where; updating their locations and properties, and the palettes (code to RGB color mapping) as needed.

(I have a couple of Teensy 4's, which use an i.MX RT1062 crossover processor, with 2×512k of RAM, and enough pins for 9-bit parallel connection to a display, although the pins are not in consecutive bits in the same output GPIO port.  One can use either a 1024-byte translation map (512×16 bits), or bit masks and shifts at runtime to adjust, though.  Although the chip is not expensive, it is a BGA; fortunately, Teensy 4 only costs $20.  I don't use PIC32s, but I see there are lots of models with 512k RAM in 64-pin TQFP at reasonable prices.  Reserving half the memory for 4-bit 8x8 tiles gives you 8192 tiles; or 4096 tiles of 8x8 at 8 bits per pixel; or 2048 tiles of 16x16 at 4 bits per pixel; or 1024 tiles of 16x16 at 8 bits per pixel; or 512 tiles of 32x32 at 4 bits per pixel; or 256 tiles of 32x32 at 8 bits per pixel; with ample memory left for RGB color tables ("palettes"), scan line buffer, and the list of currently displayed tiles with their properties.  In practice, you'll want to shoot for covering the entire display with three or four tiles per each pixel, so you can implement things like backgrounds and parallax scrolling, with ample tiles left for sprites.)

There are a few technical tricks that one can do to make the scan rendering much easier and faster.  The main one is to have your scan line buffer start at -N, and end at W+N-1, where N is the size of your largest tiles (N×N), and W is the width of the scan line.  This way each sprite is either entirely visible on the scan line, or not at all.

Similarly, to blend colors, you can start with a scan-line specific RGB color (allows nice color blended backgrounds without any tiles at all), but use 30 bits per pixel for the scan line, in format 0B0000000RRRRR00000GGGGG00000BBBBB, where R, G, and B are the five-bit RGB components.  If your color lookup tables also have the RGB colors in this format, then you can blend from C0 to C1 using p=0..17, inclusive, with (C0×(16-p))+(C1×p)>>5) & 0B000000011111000001111100000; i.e. just two multiplications, one addition, one subtraction, one bit shift, and one AND.  Of course, this limits you to 32k colors (15 bits).

On architectures with a single-cycle 32×32=64-bit multiplication, you can use full 6 bits per color (actually, up to 10 bits per color, for p=0..1025), for the extra cost of one add-with-carry (64-bit addition splits into one add and one add-with-carry), and the bit shifts and ANDs being on 64-bit value.  Remember, the scan buffer does not need to hold the temporary result, as each tile/sprite is just blended on top.

(Note: p includes the upper limit of 2c+1, using c bits per color component, because the maximum color component value is 2c-1, and (2c+1)×(2c-1)=22c-1, i.e. all 2c bits set.  In other words, if you have c bits per color component, you have 2c+2 opacity levels: from 0 to 2c-1, inclusive.)

Personally, I would probably use both 8×8 and 32×32 tiles, with 4 bits per pixel.  Both tile sets I would split in half, so that lower half of tile maps use the low 4 bits, and upper half of tile maps use the upper 4 bits of each tile data byte.  Then, I would render the sprites so that half of the 32×32 sprites are rendered first, then half of the 8×8 ones, then the rest of the 32×32, and finally the rest of the 8×8 ones, each set in increasing sprite numbers (no separate z).  The small tiles can be used for fonts and projectiles and small stuff, and the large tiles for everything else.  Both tile sets use the same 16-color palette sets, with the sprite (and not the tile) specifying the palette; say, among 256 different palettes.  This not only makes the rasterizer straightforward, but allows pretty darn nice pixel graphics.  If speed is an issue, I'd drop the alpha channel, and only allow 0/1 transparency.
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #3 on: January 29, 2020, 04:13:12 pm »
I usually go for 4 wire mode so that there is an explicit command/data control line, as the PIC32 does not really do 9 bit SPI which is the other choice if not doing parallel.

4 wire parralel, wont it be slower very much ?
btw :  i see in this topic you can add another bit in software :
https://www.microchip.com/forums/m382024.aspx

Aggravatingly, 320 * 240 * 16 is more then 128k, so you cannot hold a frame buffer in the pic without getting sneaky. 

I have SRAMs from 1Mbit, i hope this all can be done with DMA ( all new to me ).


As to overall support, you might wish to use two or three microcontrollers instead of just one: one for video processing (blitter, or graphics tile processor, as most games use sprites and tiles as the basis for their graphics), one for audio processing (if wavetable synthesis and/or MP3 decoding for music is supported), and the master one for the game mechanics.

Yes only it still has to be hand-held.
I only use DIP packages, that is the reason i use PIC32.

First i are going to try in 1 chip for a 8-bit NES or 16-bit Sega, it should be possible.
The NES 8-bit chip is originally from 1976.
« Last Edit: January 29, 2020, 04:15:24 pm by Jan Audio »
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #4 on: January 29, 2020, 04:27:00 pm »
If the TE signal is available on your screen (They vary) it is worth hooking this to an interrupt line.

What is a TE signal ?

There are a few technical tricks that one can do to make the scan rendering much easier and faster.  The main one is to have your scan line buffer start at -N, and end at W+N-1, where N is the size of your largest tiles (N×N), and W is the width of the scan line.  This way each sprite is either entirely visible on the scan line, or not at all.

You mean updating a section ?
« Last Edit: January 29, 2020, 04:28:34 pm by Jan Audio »
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 1982
  • Country: fi
    • My home page and email address
Re: ILI9341 mental support
« Reply #5 on: January 29, 2020, 04:55:54 pm »
You mean updating a section?
I mean, if you use a tile blitter, you do not need a framebuffer at all.  Instead, you construct each scan line separately, and send it to the display module.
If the scan line buffer has a full tile of extra space before and after it, you always copy a full row of pixels from each tile, even when a tile is partially offscreen.

Or are you trying to emulate old consoles?
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #6 on: January 29, 2020, 04:58:45 pm »
Or are you trying to emulate old consoles?

I also like to, it will be simpler to make my own games.
First i need it working @ 60fps, then i can see what i do.
I just want to build such a thing so i wont have to give expensive presents.

edit : i want 2 frame buffers, i am 2D scrolling fanboy.
« Last Edit: January 29, 2020, 05:02:34 pm by Jan Audio »
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #7 on: January 31, 2020, 02:11:55 pm »
What do i need VSYNC or DE mode ?
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 1982
  • Country: fi
    • My home page and email address
Re: ILI9341 mental support
« Reply #8 on: January 31, 2020, 02:14:58 pm »
Older consoles didn't actually have a direct framebuffer.

Consider the SNES video modes.  In most modes, you have one to four stacked fixed grids of 8x8 tiles, where each grid can be scrolled separately (with the different grids having different number of bits per pixel), with 128 additional sprites (max. 32 on the same scan line).  The tile grid is usually larger than the actual display, so that scrolling is achieved by just updating the offset.

Let's say you have a 128×64 tile map, each tile being 8×8 pixels, with 16 colors per tile.  Each tile uses one of 16 palettes (each color chosen from 32768 possible colors), and can have 16 drawing modes (like mirrored and rotated).  The tile map takes 8192 bytes, the tile definitions another 8192 bytes, the palette and drawing mode selectors 256 bytes, and the palettes 512 bytes, for a total of 17152 bytes.

Or, let's say you have three separate 128×64 tile maps, with 256 possible 8×8-pixel tiles, 16 colors per tile; and separate 24-bit palettes for each layer (6-bit RGBA, for transparency support).  The tile maps take 3×8192 bytes, the tile definitions 8192 bytes, the palette and drawing mode selectors 3×256 bytes, and the palettes 3×256×24/8 bytes, for a total of 35840 bytes.  (A fast renderer might internally use a buffer with 16 scan lines and 8 extra pixels before and after each scan line, so that each tile could be rendered at once to the buffer, without any need to check for partially shown tiles.  That would be 7936 pixels for a 480-pixel wide display; or 31744 bytes for 32 bits per pixel, allowing for fast 6-bit color blending.)

To emulate existing games, the emulator part will do the blitting from somewhat similar structures on the emulated memory, to an actual framebuffer; then the framebuffer e.g. DMA'd to the ILI9341 display.



I have some nice 240×240 display modules with an IPS panel and ST7789 controllers.  It does support 18-bit colors (262144), but the 15/16-bit interface is much easier and nicer to use.

Let's say I want to use a Teensy 4 (30mm×18mm) as a blitter for this display for my own handheld games.  Four planes of 256×256 tiles of 8×8 pixels would need 262144 bytes.  At 256 colors per tile, the tile data takes 65536 bytes.  If each plane has their own palette (with 32-bit color entries), the palettes take 4096 bytes.  Total, about 331776 bytes.

I also want sprites.  Let's say 256 up to 32×32 pixel sprites, with 256 colors per sprite.  Each sprite can be mirrored and rotated, and uses one of 32 possible palettes.  The sprite data takes up to 262144 bytes, and the 32 palettes 32768 bytes.  (Palette swapping is common "trick" to add variety to the graphics; and palette modification to change the "mood".)

At this point we're at around 626688 bytes, not including sprite coordinate tables, communication buffers to the master microcontroller and so on; but because Teensy 4 has 1024k of RAM, this is quite possible.  In fact, there is ample room for a (32+240+32)×(32+240+32) = 304×304-pixel and a 240×240-pixel 16-bit framebuffers, allowing tear-free updates to the TFT, without blocking communications to the microcontroller during a TFT update.

The 304×304-pixel framebuffer means all tiles and sprites are rendered in their entirety, which simplifies the blitting functions significantly; any sprite or tile that does not have all four corners within this framebuffer, is not visible at all.

Since Teensy 4.0 runs at 600 MHz, it has ample power to do the blitting, even allowing for completely free rotation of the tile grids and sprites, although without antialiasing, it tends to look quite jaggy.  (Such blitters tend to be different, traversing either the tile map or the screen coordinates along odd directions, in which case a 256×256-pixel framebuffer would work better, as then the screen coordinates are exactly 8 bits.)



Reminescing time:

A quarter of a century ago I wrote a EGA/VGA "rotator" for 16-bit x86 (8086/80186/80286), that drew a scaled and rotated picture on-screen, casting a shadow in a fixed direction (up/down/left/right). The source was a 256×256 map, one byte per pixel. A 65536-byte/32768-entry (15 bits: 7 bits for current height, 8 bits for map data) determined the color of each displayed pixel and the current height for the next pixel; this to avoid conditional expressions.  Essentially, the low 8 (4) bits of the result determined the final color, and the high 7 bits the current height for the next pixel. To traverse the map, I used 16-bit fixed-point integers, with 8 integer bits and 8 fractional bits.  So, calculating each pixel involved just two additions (for the coordinates),  one 8-bit lookup (from source map) and one 16-bit lookup (from the lookup table), and some register moves which were almost free since x86 splits its 16-bit registers into two 8-bit registers that can be modified separately.  At the beginning of each scan line there was additional work (including setting various mask registers etc. for 16-color EGA/VGA), but the inner loop was fast enough to generate a smooth-ish rotation.

If you work out the code, everything just slots together nicely to powers of two, making it much simpler than one would otherwise guess.

One peculiarity of it was that even though you could "zoom" in, it would not lengthen the shadows, as it only applied to the XY plane and not the heights.  Or, alternatively, the zoom level changed the angle of the light, with the light at angle arctan(scale).  (To fix that, you'd need to recalculate the lookup table for each different zoom level.)

To change the direction of the shadows, one must traverse also the framebuffer in fractional pixel steps.  Unsigned 16-bit fixed point, with 8 integer and 8 fractional bits, suffices for 240×240.  If the framebuffer is double buffered, this causes no issues; otherwise worse artefacts than tearing will be visible.

In other words, you have two fixed-point coordinates for the framebuffer pixel, their constant deltas, two for the source map "pixel", their constant deltas, and a 16-bit register for the current "height" used with the 8-bit source map value to find out the new height and pixel color; or 9 registers.  16-bit x86 really only had six general purpose ones (ax, bx, cx, and dx, that split into ah/al, bh/bl, ch/cl, dh/dl; and di and si, 16-bit index registers), so I never implemented that (it would have been too slow).  Now, even Cortex M0 and better have at least 11 32-bit ones that a GCC extended inline assembly code in e.g. Arduino environment can safely use: R0-R8, R10, R11.

(This approach cannot really be used to implement radial lighting, because rays from the center of the screen to the edge overlap; you'd do a lot of extra calculations.  A variant that uses a temporary buffer for a row of heights can do a cone with central angle at most 90°, though; there the trick is that the temporary buffer is either expanded to the size of the next row, or traversed using two fixed-point registers.)
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #9 on: January 31, 2020, 03:13:15 pm »
That means DE mode then ?, whatever it is.
 

Online dmills

  • Super Contributor
  • ***
  • Posts: 1788
Re: ILI9341 mental support
« Reply #10 on: January 31, 2020, 03:27:31 pm »
Hsync, Vsync, DE are signals used when running in parallel video mode, and are not used in SPI or microprocessor mode.

If you can do the parallel video thing using the PIC parallel master port that would allow easy and fast DMA operations, going down the SPI route requires either 9 bit SPI transactions or an extra physical connection to select between control and data modes.

TE is 'Tearing Effect' and is an output from the screen that indicates that its internal update is at start of frame, you use this to synchronise your drawing to avoid image tearing. 
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #11 on: January 31, 2020, 04:01:23 pm »
Ah, thanks, so you dont really need a backbuffer to draw smoothly without flicker ?, nice.
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #12 on: January 31, 2020, 04:13:00 pm »
Ok, i have 2 versions, i like the 3,2inch with parallel only i dont know with a PIC32 with only 21 IO pins.

I have one SPI setup for the audio DAC, then i need on the other one to combine : TFT, SRAM, SD-card.
Maybe this is problematic, i have to figure out.

Easy DMA sounds good to me, i have to count pins, or find a way with more buttons on 1 ADC or something, i dont know if it is reactive enough ?

Ok, the SPI1 is 4 pins ( 8-bit + Data/Control pin )
+ another slave-select for the SRAM ( if this is possible on 1 SPI ? )
Audio DAC also 4 or was it 3.

Input buttons at least 8.
+ RX & TX pin for connect 2 computers.

I think there is no pins for parallel.
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #13 on: February 01, 2020, 03:42:51 pm »
So i set up SPI with BRG = 0, @ 24MHz, running 48MHz instruction clock.
Will it work on breadboard ?

MCC set up for enhanced mode, is it good or not ?

Now i have to send some instructions.
When i look at those librarys they send a whole lot of hexidecimal numbers without explain.
Did you copy those ?, or where can i find how the initialize works ?

In those librarys they also use read instructions, i dont want to read anything from a display, what is the use for this ?, it is not required or what ?

I made a picture of the version i have :


I guess it is only for 8-bit SPI since it has a Data/Command pin.
« Last Edit: February 01, 2020, 03:50:00 pm by Jan Audio »
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #14 on: February 01, 2020, 04:12:15 pm »
I calculated with this SPI speed :

( 1 / 24000000 ) * 240 *320 * 8 = 0,0256
It is not fast enough for 60fps, the reading from SRAM not even calculated.
 

Online RoGeorge

  • Super Contributor
  • ***
  • Posts: 2532
  • Country: ro
Re: ILI9341 mental support
« Reply #15 on: February 01, 2020, 04:37:23 pm »
I always have problems getting started and need some mental support.

Slightly offtopic, but are you trying to say mentoring, or mental support?

Mentoring is about guidance and advice, while mental support is about helping people with brain disabilities.  I don't get how an LCD could help with brain disorders.  Is there another meaning of mental that I don't know?

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #16 on: February 01, 2020, 04:47:52 pm »
I feel disabled at the moment.
Cant get 60 fps.

by the way : you dont need to be metal disabled, you can also be mentally strong.
please no negative comments.
« Last Edit: February 01, 2020, 05:35:35 pm by Jan Audio »
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 1982
  • Country: fi
    • My home page and email address
Re: ILI9341 mental support
« Reply #17 on: February 01, 2020, 09:35:34 pm »
mental support is about helping people with brain disabilities
Cambridge dictionary disagrees.  "To support" means to help or encourage, and "mental" means relating to the mind, or involving the process of thinking.  Although there is no direct entry for "mental support", Cambridge dictionary implies "ILI9341 mental support" simply means "helping with the process of thinking [about] [how to use] an ILI9341 [display module]".
 

Offline chickenHeadKnob

  • Frequent Contributor
  • **
  • Posts: 892
  • Country: ca
  • doofus programus semi-retiredae
Re: ILI9341 mental support
« Reply #18 on: February 02, 2020, 01:16:31 am »
mental support is about helping people with brain disabilities
Cambridge dictionary disagrees.  "To support" means to help or encourage, and "mental" means relating to the mind, or involving the process of thinking.  Although there is no direct entry for "mental support", Cambridge dictionary implies "ILI9341 mental support" simply means "helping with the process of thinking [about] [how to use] an ILI9341 [display module]".
RoGeorge was not being negative. As a native speaker of English I find the phrase 'mental support' unusual and ambiguous. No native speaker uses it. People do use  the phrase "emotional support" often, that directly means people sympathizing. Like when women gather and cry and hug each other and complain about men. I am going to guess Jan Audio didn't intend that meaning.
If as Nominal Animal suggests the intended meaning is " help me figure out the ILI9341 controller" then that would be the unambiguous way to phrase the thread title.
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 1982
  • Country: fi
    • My home page and email address
Re: ILI9341 mental support
« Reply #19 on: February 02, 2020, 07:30:36 am »
RoGeorge was not being negative.
Neither was I.  I only pointed out that for us non-native speakers, the dictionary implies a non-mental-health-related meaning.

(That is, my intention was only to point that out in a neutral manner; that one might use the phrase in a non-mental-health way.  No negativity or antagonism or unfriendlyness intended!  I probably failed; but me fail English often. :-//)
« Last Edit: February 02, 2020, 07:32:40 am by Nominal Animal »
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #20 on: February 02, 2020, 02:31:28 pm »
Ok, i translate directly from dutch.

No one more information about the TFT display ?
« Last Edit: February 02, 2020, 02:38:47 pm by Jan Audio »
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #21 on: February 02, 2020, 03:18:59 pm »
Look here : https://vivonomicon.com/2018/06/17/drawing-to-a-small-tft-display-the-ili9341-and-stm32/

Code: [Select]
  // (Display off)
  //hspi_cmd(SPIx, 0x28);
  // Issue a series of initialization commands from the
  // Adafruit library for a simple 'known good' test.
  // (TODO: Add named macro definitions for these hex values.)
  hspi_cmd(SPIx, 0xEF);
  hspi_w8(SPIx, 0x03);
  hspi_w8(SPIx, 0x80);
  hspi_w8(SPIx, 0x02);
  hspi_cmd(SPIx, 0xCF);
  hspi_w8(SPIx, 0x00);
  hspi_w8(SPIx, 0xC1);
  hspi_w8(SPIx, 0x30);
  hspi_cmd(SPIx, 0xED);
  hspi_w8(SPIx, 0x64);
  hspi_w8(SPIx, 0x03);
  hspi_w8(SPIx, 0x12);
  hspi_w8(SPIx, 0x81);
  hspi_cmd(SPIx, 0xE8);
  hspi_w8(SPIx, 0x85);
  hspi_w8(SPIx, 0x00);
  hspi_w8(SPIx, 0x78);
  hspi_cmd(SPIx, 0xCB);
  hspi_w8(SPIx, 0x39);
  hspi_w8(SPIx, 0x2C);
  hspi_w8(SPIx, 0x00);
  hspi_w8(SPIx, 0x34);
  hspi_w8(SPIx, 0x02);
  hspi_cmd(SPIx, 0xF7);
  hspi_w8(SPIx, 0x20);
  hspi_cmd(SPIx, 0xEA);
  hspi_w8(SPIx, 0x00);
  hspi_w8(SPIx, 0x00);
  // PWCTR1
  hspi_cmd(SPIx, 0xC0);
  hspi_w8(SPIx, 0x23);
  // PWCTR2
  hspi_cmd(SPIx, 0xC1);
  hspi_w8(SPIx, 0x10);
  // VMCTR1
  hspi_cmd(SPIx, 0xC5);
  hspi_w8(SPIx, 0x3E);
  hspi_w8(SPIx, 0x28);
  // VMCTR2
  hspi_cmd(SPIx, 0xC7);
  hspi_w8(SPIx, 0x86);
  // MADCTL
  hspi_cmd(SPIx, 0x36);
  hspi_w8(SPIx, 0x48);
  // VSCRSADD
  hspi_cmd(SPIx, 0x37);
  hspi_w8(SPIx, 0x00);
  // PIXFMT
  hspi_cmd(SPIx, 0x3A);
  hspi_w8(SPIx, 0x55);
  // FRMCTR1
  hspi_cmd(SPIx, 0xB1);
  hspi_w8(SPIx, 0x00);
  hspi_w8(SPIx, 0x18);
  // DFUNCTR
  hspi_cmd(SPIx, 0xB6);
  hspi_w8(SPIx, 0x08);
  hspi_w8(SPIx, 0x82);
  hspi_w8(SPIx, 0x27);
  hspi_cmd(SPIx, 0xF2);
  hspi_w8(SPIx, 0x00);
  // GAMMASET
  hspi_cmd(SPIx, 0x26);
  hspi_w8(SPIx, 0x01);
  // (Actual gamma settings)
  hspi_cmd(SPIx, 0xE0);
  hspi_w8(SPIx, 0x0F);
  hspi_w8(SPIx, 0x31);
  hspi_w8(SPIx, 0x2B);
  hspi_w8(SPIx, 0x0C);
  hspi_w8(SPIx, 0x0E);
  hspi_w8(SPIx, 0x08);
  hspi_w8(SPIx, 0x4E);
  hspi_w8(SPIx, 0xF1);
  hspi_w8(SPIx, 0x37);
  hspi_w8(SPIx, 0x07);
  hspi_w8(SPIx, 0x10);
  hspi_w8(SPIx, 0x03);
  hspi_w8(SPIx, 0x0E);
  hspi_w8(SPIx, 0x09);
  hspi_w8(SPIx, 0x00);
  hspi_cmd(SPIx, 0xE1);
  hspi_w8(SPIx, 0x00);
  hspi_w8(SPIx, 0x0E);
  hspi_w8(SPIx, 0x14);
  hspi_w8(SPIx, 0x03);
  hspi_w8(SPIx, 0x11);
  hspi_w8(SPIx, 0x07);
  hspi_w8(SPIx, 0x31);
  hspi_w8(SPIx, 0xC1);
  hspi_w8(SPIx, 0x48);
  hspi_w8(SPIx, 0x08);
  hspi_w8(SPIx, 0x0F);
  hspi_w8(SPIx, 0x0C);
  hspi_w8(SPIx, 0x31);
  hspi_w8(SPIx, 0x36);
  hspi_w8(SPIx, 0x0F);
  // Exit sleep mode.
  hspi_cmd(SPIx, 0x11);
  delay_cycles(2000000);
  // Display on.
  hspi_cmd(SPIx, 0x29);
  delay_cycles(2000000);
  // 'Normal' display mode.
  hspi_cmd(SPIx, 0x13);

They say : we just copy some adafruit code.
That is why these displays are not available in regular shops ?, because there is no manual ?
I dont like copying other peoples code especially without comments for all the commands.
It looks like the whole world copy this "adafruit" code, whatever that is.
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 1982
  • Country: fi
    • My home page and email address
Re: ILI9341 mental support
« Reply #22 on: February 02, 2020, 03:28:07 pm »
Which exact PIC32 you use?

For 60 FPS at 320×240 using 16-bit color, you need 320×240×16/8=153,600 bytes for the framebuffer, and transfer 320×240×16×60=73,728,000 bits per second.  In the serial mode, ILI9341 needs at least 100ns per write cycle, i.e. 10 MHz.  Thus, according to the specs, you can get up to 10,000,000/(320×240×16)≃8 frames per second.

If you use 12 I/O pins for the display (8 data pins, WRX, RDX, CSX, D/CX), and your PIC32 supports 8-bit DMA in parallel to those pins, triggered by falling edge of WRX (also in your own control; the display latches the 8 pins on rising edge of WRX), you might be able to reach 60 FPS.  According to the datasheet, 8-bit parallel WRX cycles must take at least 66ns, which corresponds to about 15 MHz.  Your WRX pin in parallel mode would be toggled at a rate of about 4.6 MHz. (You might be able to use SPI output for this, with a second DMA channel generating the clock pulses from a single 0b01010101 byte; noting that the length of the DMA data must then be a multiple of 4 bytes.)

Hopefully now you can see why I really believe using a dedicated microcontroller for the display alone is a good idea.  It does not need a lot of computational power, but it does need RAM, DMA, and sufficient number of pins.

Since 32-bit microcontrollers with sufficient amount of RAM have ample computational power, it also makes it sensible to do the blitting (of tiles and sprites to the framebuffer) on that dedicated microcontroller, too.  My previous posts have outlined some examples of the techniques used in games (and in 2D games libraries, like SDL; example), that allow one to generate framebuffer scan line dynamically, without a full framebuffer; or with a dual framebuffer where one is DMA'd to the display while the other is being manipulated, so that there is no tearing, but a dynamic frame rate.  Emulators need to access the framebuffer directly.

The ILI9341 controller datasheet contains the register and control information, and is freely available on the net.  The one Adafruit folks used to write their library is here, and it includes all information you need.  But first, you need to know how you'll be connecting to the ILI9341 controller; and to help with that, we'd need to know the STM32 you intend to use.
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 504
  • Country: nl
Re: ILI9341 mental support
« Reply #23 on: February 02, 2020, 04:23:31 pm »
The chip is PIC32MX170F256B, it should have everything on board.

Yes i am starting to see, i need a graphics chip for the parralel.
The SRAM has max 20MHz clock, a bigger problem.

This 3,2 inch display with parralel has a 2 row pin header, i need to add wired, thats why i favored the SPI, i can plug in breadboard.
I try getting the SPI working first, then i can see later for fast redraw.
For tetris and arknoid regions can be updated no problem.
« Last Edit: February 02, 2020, 04:27:26 pm by Jan Audio »
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 1982
  • Country: fi
    • My home page and email address
Re: ILI9341 mental support
« Reply #24 on: February 02, 2020, 08:41:35 pm »
The chip is PIC32MX170F256B, it should have everything on board.
21 I/O pins is a restriction.  The -D model, TQFP-44, would have been much easier, even if on an TQFP-44 to DIP adapter.

It looks like parallel I/O via DMA is only really possible using the Parallel Master Port.  (Do remember that I don't use PIC32s myself, so I am basing all this on datasheets and manuals; I could be wrong.)

On the 28-pin PIC32MX170F256B in SPDIP/SOIC/SSOP footprint, the data is on pins 23,22,21,18,17,16,15,14, the WRX strobe is pin 25, and RDX strobe is pin 24; these are all in port B.  CSX and C/DX can be on any other I/O pins.

On the 44-pin PIC32MX170F256D TQFP, the data is on pins 10,9,8,1,44,43,42,41, the WRX strobe is pin 14, and RDX strobe is pin 11, all in port B.  Since it has 35 I/O pins, you'd have 23 pins left over; including all of port A (0-4, 7-10) and all of port C (0-9); or including parallel master port address pins (0-10, port C 2,4-9, port A 7-10).  (So, technically, you could use the parallel master port for both external RAM in 2048-byte "pages", DMA'd to the processor, and to DMA data to the display module.  Assuming you use UART to communicate with the master controller, you have 10 bits left for "page" selection, or theoretically up to 2 Mbytes. This way you cannot directly access external RAM, but can select a 2048-byte page and DMA it (or any part of it) to memory while the processor is doing other stuff -- except transferring data to the display. For example, using an ISSI IS61WV5128EDBLL-10TLI 512k×8 SRAM, with 8 page pins for 256 pages, 2048 bytes each.)

A 64-pin TQFP (0.5mm spacing) PIC32MZ2048EFG064 has 512k of RAM and 46 I/O pins. The 8 parallel data pins are 58,61,62,63,64,1,2,3 (port E), the WRX strobe is pin 52 (port D), and RDX is pin 53 (port D).  So, on top of the 8+4 pins to a display module using DMA'ble 8-bit parallel, you'd have 34 I/O pins left; including all 16 port B pins.

On the 100-pin PIC32MZ2048EFG100, you'd have full 16-bit parallel data port (port E, pins 91,94,98,99,100,3,4,5,88,87,86,85,79,80,77,78), with WRX strobe on pin 8 (port C), RDX strobe on pin 9 (port C). They are the same as EBI data pins, so it'd be a bit difficult to try and use EBI for external RAM; but 512k gives a lot of options already.   Of course, a "paged" access (ie. any DMA within a 65536-byte/65536-word page) using the 16 parallel address bits, and some additional bits for the "page" selection, would let you expand the SRAM to as large as you can find a parallel SRAM chip for.  (Say, IS61WV25616EDBLL-10TLI, for an additional 512k of SRAM, organized as 4 pages of 131072 bytes each; accessed in 16-bit aligned units.)

This 3,2 inch display with parralel has a 2 row pin header, i need to add wired, thats why i favored the SPI, i can plug in breadboard.
I try getting the SPI working first, then i can see later for fast redraw.
Note that most of the ILI9431 displays' boards are just connectors, with some passives like resistors, and possibly a 3.3V regulator, and rarely voltage level translators so that 5V systems can talk to the 3.3V logic the ILI9431 uses.  32-bit microcontrollers typically use 3.3V logic levels, so they don't need level shifting.  You could probably rather easily design a replacement board for the display with your graphics microcontroller, so that the microcontroller pins go directly to the display flex cable.  The ILI9431 chip itself is usually bonded to the flex cable.

(I have a couple of those displays, with a resistive touchscreen on top.  The SD card connector on them is usually not worth trying to use; I think the traces pick up too much noise from the actual display or something.)

For tetris and arknoid regions can be updated no problem.
The technique to track which parts of the display have changed is often called "damage".  Essentially, you use one bit per a fixed size unit/tile of the framebuffer, and whenever you draw to the framebuffer, you mark the tile the pixel(s) belong to used by setting the corresponding bits.

For ILI9431, setting the region to be updated by consecutive data sent to the display takes 10 bytes or pixels worth of data.  The D/CX pin controls whether a command or data is sent, so data and commands may be impossible to mix in DMA transfers; you'll need at least an interrupt in between to flip the D/CX pin.

To make the math easier, you'll probably want 4×4, 8×8, or 16×16 damage regions (or maybe rectangular ones).  With 8×8 damage tiles, 320×200 has 40×30 damage tiles; putting the 30 damage tiles in each 8x240 slice in a 32-bit word, the damage map only needs 40 32-bit words, or 240 bytes: point (x,y) then belongs to damage word (x/8) bit (y/8).  If damage word (i) bit (j) is set, then the 8x8-pixel region at (i×8,j×8) to (i×8+7,j×8+7), inclusive, must be updated.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf