juj / fbcp-ili9341

A blazing fast display driver for SPI-based LCD displays for Raspberry Pi A, B, 2, 3, 4 and Zero
MIT License
1.58k stars 265 forks source link

Screen stays white #3

Closed turtiustrek closed 6 years ago

turtiustrek commented 6 years ago

Hello! i came across this page and i am wondering why my display is not working (ILI9341) i have connected the D/C pin to 22 and rest to 3.3v after running sudo ./fbcp-ili9341 my screen stays white ;-; but with FBTFT it works any help would be great :D

Thanks, M.Mubin

EmulatedBen commented 6 years ago

Hi mubin were you able to fix this issue?

juj commented 6 years ago

If you still have the hardware to play around with, it is possible that after https://github.com/juj/fbcp-ili9341/commit/3a98d0da2c65766d54d19786acdcf6c5c6a1665e the issue might be fixed. I noticed that my PiTFT display was actually ignoring the chip select line, and always unconditionally communicated on the SPI bus independent of whether its CS was enabled or disabled. Recently I ported this to another display, which honors CS properly, and it too stayed white until the CS was applied to it.

EmulatedBen commented 6 years ago

Juj I have manged to fix all the issues including auto start after reboot. it works perfectly. I cant thank you enough. I will do a video tutorial on your menthod to help others out, if you dont mind. A BIG THANK YOU!!!

juj commented 6 years ago

@EmulatedBen: Sweet, so great to hear!

I would love to see a video and the setup you are running with, that would be amazing. :) One thing to mention for possible users is the increased power consumption that the driver currently incurs, as something to keep an eye on as a drawback. I don't know how much more the Pi will consume energy with fbcp-ili9341 vs the original fbcp driver. It may be a negligible difference or a big one, but definitely something to measure if that is a big item in the project in question. It may be possible to reduce power consumption in the future with DMA transfers, but I have not yet been able to pull it off without sacrificing throughput performance (too much).

@MohammadMubin : I am fairly sure that this code block fixes the white screen problem, since this code was wrong (it configured SPI peripheral to take control the CS line, but in the SPI peripheral registers, we don't actually want to let it do that, but always keep CS enabled for the display).

I'll close this issue assuming it's resolved. If this still does not work for you, one thing that might be the cause is if there is a reset line on your display that needs to be enabled. Fore example my pitft 2.8 does not need such code, but a waveshare32b I've been running with recently does. It uses the following code: https://github.com/juj/fbcp-ili9341/commit/3a98d0da2c65766d54d19786acdcf6c5c6a1665e#diff-eccee615a2b3ab684f0a041466726930R77 . If your display has a custom reset line that needs to be enabled, then you may need to adapt the above code for your purposes.

What I generally do to debug is connect to the Pi via SSH and run watch -n 0.1 gpio -g readall to observe what the IN/OUT and HIGH/LOW status of each GPIO register is, and cross reference the schematics of the display to see if the reset line is as needed.

dotmick commented 6 years ago

Hi,

I've got the same issue (white screen) using my lcd (NeoSec 2.8 inch TFT ili9341). I've tried freeplaytech_waveshare32b as well as pitft_28r_ili9341 with no luck :/

Thanks

juj commented 6 years ago

You will probably need to port the driver to customize for that display. Pinout diagram from http://www.neosecsolutions.com/products.php?78&cPath=20 suggests setting https://github.com/juj/fbcp-ili9341/blob/master/freeplaytech_waveshare32b.h#L8 to 24 or 23 (not sure what RS vs RST there is), and likely https://github.com/juj/fbcp-ili9341/blob/master/ili9341.cpp#L74 will need to be ported to tailor for that display.

dotmick commented 6 years ago

Hi @juj,

Thanks! I'll see if I can write it myself 😃

At the moment, I've found out that using RecalBox for my project (instead of RetroPie) with their own implementation of fbcp gives me the best results for now. I am still unhappy about the responsiveness of the screen: there's a tiny delay (<1s) from when I press a button to the actual screen update. But I don't know what else I can do...

I'll keep you updated about the driver.

juj commented 6 years ago

Interesting - did not know RecalBox had their own version. Digging out, looks like this is the optimization they did over to the original: https://github.com/ian57/rpi-fbcp/commit/c1d05f8d8e02641726691f95d9cd85a76a33af85.

(not sure what RS vs RST there is)

It looks like RS is Register Select. That is what this driver call Data/Control pin, so that one corresponds to https://github.com/juj/fbcp-ili9341/blob/master/freeplaytech_waveshare32b.h#L6. RST is then Reset, or https://github.com/juj/fbcp-ili9341/blob/master/freeplaytech_waveshare32b.h#L8. So perhaps the needed change is

#define GPIO_TFT_DATA_CONTROL 24
#define GPIO_TFT_RESET_PIN 23

for NeoSec display. You also likely want to set all these to 0 as well: https://github.com/juj/fbcp-ili9341/blob/master/freeplaytech_waveshare32b.h#L16.

After that it is then a question of what the needed initialization sequence is.

dotmick commented 6 years ago

Gotcha, I'll try that.

About the sequence, is it not this one https://github.com/notro/fbtft/blob/master/fb_ili9341.c ? (which looks similar to https://github.com/juj/fbcp-ili9341/blob/master/ili9341.cpp#L74 no?)

turtiustrek commented 6 years ago

@juj @dotmick @EmulatedBen Hi! so sorry for not being active.I have broken both of my ili9341 displays so no i haven't been able to fix this :P I have ordered the ILI9488 SPI and wondering if that will work its 3.5" and perfect for my project.

juj commented 6 years ago

About the sequence, is it not this one

It is somehow peculiar that even with all these vendors coming up with "ili9341" displays, it looks like they are not all equal, but each display vendor still has their own, and sometimes undocumented, set of device initialization commands that need to be sent to the display. For example, the two ILI9341 displays I have that fbcp-ili9341 now supports are Adafruit's PiTFT 2.8" ILI9341 display and Waveshare's 3.2" ILI9341 display, but still in order to get them working, they need different initialization commands, as shown in here for Adafruit's one, and here for the Waveshare one. Browsing notro's fbtft repository, other ili9341 displays there have different initialization commands as well.

I have documented there the commands that are described in the ILI9341 Datasheet, but oddly, Waveshare needs some undocumented extra commands that I have no idea what they do. Those were taken from notro's fbtft repository, and they are not documented as part of the ILI9341 spec, or in fbtft - someone just contributed them there - possibly the original device manufacturer(?). Other displays that advertise being ILI9341 often also need custom initialization commands, so it seems that there is not one "pure" ILI9341 spec, but it seems that the hardware market is fragmented a bit there.

Although there is an off chance that these undocumented initialization commands are just garbage and don't really do anything and someone was misguided adding them into notro's fbtft repository (that's a bit doubtful though), I think I did not actually try deleting the undocumented ones from Waveshare32b initialization routine after I got the display working - might give that a try later.

After getting the initialization successfully over though, I have not seen discrepancies between the devices at runtime, but they all use the same documented ILI9341 pixel commands in SPI mode to send image data over.

juj commented 6 years ago

@MohammadMubin : no worries. Getting ILI9488 to work is definitely going to need some code changes. When you get the device, try cross-referencing between ILI9341 Datasheet and ILI9488 Datasheet to figure out what the differences are. Looking at the Table of Contents of both, many of the commands seem to be identical, so there is a chance that it might work with only small changes needed. DISPLAY_WIDTH and DISPLAY_HEIGHT at https://github.com/juj/fbcp-ili9341/blob/master/freeplaytech_waveshare32b.h#L10 will definitely need to be changed to 320x480 at least.

juj commented 6 years ago

I have documented there the commands that are described in the ILI9341 Datasheet, but oddly, Waveshare needs some undocumented extra commands that I have no idea what they do. Those were taken from notro's fbtft repository, and they are not documented as part of the ILI9341 spec, or in fbtft - someone just contributed them there - possibly the original device manufacturer(?). Other displays that advertise being ILI9341 often also need custom initialization commands, so it seems that there is not one "pure" ILI9341 spec, but it seems that the hardware market is fragmented a bit there.

Digging a bit further, I found a newer version v1.11 of the ILI9341 spec sheet at crystalfontz.com from 2011/06/10, whereas the earlier one I had was v1.02 downloaded from Adafruit servers. The newer spec sheet documents these missing initialization commands, but I have no idea whether this is about a different hardware revision, or if the newer spec sheet is just an updated documentation about also possibly earlier hardware (I hope so). Assuming the latter, the initialization routines between my two ILI9341 displays are now unified: https://github.com/juj/fbcp-ili9341/commit/c3db8e53d1a23ef209e609ab13d328162f7bcf38.

turtiustrek commented 6 years ago

@juj i have altered the ardunio SPI Ili9341 parameters to ILI9488 before (but never got proper colour/color) .i hope to use these parameters of the program for the pi once the new display arrives.

dotmick commented 6 years ago

@juj nice one! Do I just need to create a .h file for the neosec lcd then?

juj commented 6 years ago

Yeah, you can go that route. Try first with either of the existing -DADAFRUIT_ILI9341_PITFT=ON or -DFREEPLAYTECH_WAVESHARE32B=ON build configurations as a basis, and see if you can get away with just overriding the GPIO pins to use, and if there are more things to customize e.g. in the init sequence, you can try creating a new #ifdef for that specific display.

EmulatedBen commented 6 years ago

HI Juj the video is live. thanks again https://www.youtube.com/watch?v=r1J0Hd-abVA&t=368s

juj commented 6 years ago

Very nice! Clear instructions and also great to see some games running on the display I haven't tried. Happy to see that the program works on other devices than Adafruit/Waveshare as well.

dotmick commented 6 years ago

Alright, so I've tried the following:

cmake -DCMAKE_BUILD_TYPE=Release -DILI9341=ON -DFREEPLAYTECH_WAVESHARE32B=ON -DGPIO_TFT_DATA_CONTROL=24 -DGPIO_TFT_RESET_PIN=23 ..

giving me this output:

Initializing display Creating SPI task thread InitSPI done Relevant source display area size with overscan cropped away: 966x646. Source GPU display is 1024x768. Output SPI display is 320x240 with a drawable area of 302x202. Applying scaling factor 0.31x, xOffset: 18, yOffset: 9, scaledWidth: 302, scaledHeight: 202 Creating dispmanX resource of size 320x240 (aspect ratio=1.333333). GPU grab rectangle is offset x=9,y=19, size w=302xh=202, aspect ratio=1.495050

But the screen remains white :/

dotmick commented 6 years ago

And same result with:

cmake -DCMAKE_BUILD_TYPE=Release -DILI9341=ON -DADAFRUIT_ILI9341_PITFT=ON -DGPIO_TFT_DATA_CONTROL=24 -DGPIO_TFT_RESET_PIN=23 ..

juj commented 6 years ago

Hmm, sorry to hear, not quite sure what would be off. The second CMake line based on Adafruit display looks good, tough to say what would be wrong. The original notro/fbtft + dtoverlay -based method works ok? If so, then a way to debug may be to use

watch -n 0.1 gpio -g readall

to observe the communication on the GPIO pins when fbtft + original fbcp is running, to try to find which pins are carrying communication there, to double check the pins to rule out if the issue would lie there. The GPIO_TFT_DATA_CONTROL pin should be observed to semi-infrequently toggle state in the fbtft driver, and the GPIO_TFT_RESET_PIN should be HIGH at all times. Both pins should be in OUT state (they will boot up in IN state, and possibly LOW).

Another method may be to start out with the fbtft dtoverlay active in /boot/config.txt, and then sudo pkill fbcp after boot to kill the original fbcp driver, and then comment out the initialization sequence code in fbcp-ili9341, and run it without it doing initialization to see if it manages to work then. If that works, i.e. fbtft initializing + fbcp-ili9341 running on top of it, then it would suggest that the issue is somewhere in fbcp-ili9341s attempted initialization. If that doesn't work even then, it suggests some of the pins are probably wrong.

Also, it may be worth trying a slower bus speed setting at https://github.com/juj/fbcp-ili9341/blob/master/config.h#L60, such as 8 or even 10 to see if that has any issues. I don't know if all displays are able to run at speed 6, although my both Waveshare and Adafruit displays are able to. (smaller number means higher bus speed here)

dotmick commented 6 years ago

@juj thanks for your detailed answer!

Got some news. I've tried your second method (using fbtft initialization, commenting the init function in ili9341.cpp and starting fbcp-ili9341) and it does work!

Is there anything you'd like me to do to help understanding what the init sequence should be?

Note: this is the command I've used to initialize the screen:

sudo modprobe fbtft_device custom name=fb_ili9341 gpios=reset:25,dc:24,led:18 speed=16000000 bgr=1

juj commented 6 years ago

Ooh, that's cool progress!

That then confirms that the Data/Control pin must be correct, since it would not work to update the display if that was off. It is then likely that either the Reset sequence is giving trouble, or something in the initialization sequence itself is not quite right.

Double-checking the code out, I did notice ili9341.cpp was not sending 0x01 Display Reset and 0x28 Display OFF commands in the beginning of the initialization sequence. Added those at https://github.com/juj/fbcp-ili9341/commit/80d2e67c3238320a4ddbaac5bb5040d75deea6d1 as well as a print to make sure the GPIO reset sequence is actually being performed. Try out if that might have an effect.

If not, then try cross referencing with the existing ILI9341 initialization sequences in fbtft or ILI9341 application notes to see if you can spot a difference that might be relevant, and try adapting the ili9341.cpp sequences to pinpoint what would be needed. Different resources on the web have subtly different values for the initialization commands, so it's hard to know which exactly might be the important ones.

dotmick commented 6 years ago

I'll try your updated version thanks!

In the meantime, I've found this in main.c that was attached to an email I've received with my order:

void TFT_Initialize(void) { //TFT_RST=1; //delay(100); TFT_RST=0; delay(500); TFT_RST=1; delay(250); //***** Start Initial Sequence **// write_comm_data(0x0001, 0x0100); // set SS and SM bit write_comm_data(0x0002, 0x0700); // set 1 line inversion //write_comm_data(0x0003, 0x1030); // set GRAM write direction and BGR=1

ifdef vertical

  write_comm_data(0x0003, 0x1030);  //1018 

else

  write_comm_data(0x0003, 0x1018 );

endif

write_comm_data(0x0004, 0x0000); // Resize register write_comm_data(0x0008, 0x0202); // set the back porch and front porch write_comm_data(0x0009, 0x0000); // set non-display area refresh cycle ISC[3:0] write_comm_data(0x000A, 0x0000); // FMARK function disable write_comm_data(0x000C, 0x0000); // RGB interface setting write_comm_data(0x000D, 0x0000); // Frame marker Position write_comm_data(0x000F, 0x0000); // RGB interface polarity delay(100); // Delay 10 ms //*****Power On sequence ****// write_comm_data(0x0010, 0x0000); // SAP, BT[3:0], AP, DSTB, SLP, STB write_comm_data(0x0011, 0x0007); // DC1[2:0], DC0[2:0], VC[2:0] write_comm_data(0x0012, 0x0000); // VREG1OUT voltage write_comm_data(0x0013, 0x0000); // VDV[4:0] for VCOM amplitude write_comm_data(0x0007, 0x0001); write_comm_data(0x0007, 0x0020); delay(200); // Dis-charge capacitor power voltage write_comm_data(0x0010, 0x1490); // SAP, BT[3:0], AP, DSTB, SLP, STB write_comm_data(0x0011, 0x0117); // Set DC1[2:0], DC0[2:0], VC[2:0] delay(500); // Delay 50ms write_comm_data(0x0012, 0x008E); // Internal reference voltage delay(10); // Delay 10ms write_comm_data(0x0013, 0x1900); // VDV[4:0] for VCOM amplitude write_comm_data(0x0029, 0x0023); // VCM[5:0] for VCOMH write_comm_data(0x002B, 0x000C); // Set Frame Rate delay(500); // Delay 50ms write_comm_data(0x0020, 0x0000); // GRAM horizontal Address write_comm_data(0x0021, 0x0000); // GRAM Vertical Address // ----------- Adjust the Gamma Curve ----------// write_comm_data(0x0030, 0x0000); write_comm_data(0x0031, 0x0406); write_comm_data(0x0032, 0x0004); write_comm_data(0x0035, 0x0405); write_comm_data(0x0036, 0x0200); write_comm_data(0x0037, 0x0407); write_comm_data(0x0038, 0x0103); write_comm_data(0x0039, 0x0707); write_comm_data(0x003C, 0x0504); write_comm_data(0x003D, 0x0000); //------------------ Set GRAM area ---------------// write_comm_data(0x0050, 0x0000); // Horizontal GRAM Start Address write_comm_data(0x0051, 0x00EF); // Horizontal GRAM End Address write_comm_data(0x0052, 0x0000); // Vertical GRAM Start Address write_comm_data(0x0053, 0x013F); // Vertical GRAM Start Address write_comm_data(0x0060, 0xA700); // Gate Scan Line write_comm_data(0x0061, 0x0001); // NDL,VLE, REV write_comm_data(0x006A, 0x0000); // set scrolling line //-------------- Panel Control -------------------// write_comm_data(0x0090, 0x0010); write_comm_data(0x0092, 0x0000); delay(100); // Delay 10ms write_comm_data(0x0007, 0x0133); // 262K color and display ON
}

dotmick commented 6 years ago

@juj tried your last version but still doesn't work.

juj commented 6 years ago

Darn :/

That code you posted looks something very different from any ILI9341 initialization sequence I've seen. The lines in write_comm_data() read like the first value is the command byte, and the second one is a data byte for that command. However the data bytes here are 16-bit values, but the SPI protocol in ILI9341 is a 8-bit wide protocol, so either the above initialization is for a 16-bit wide SPI, or the 16-bit values are split to two parts.

Also, the comments refer to something completely different. For example,

write_comm_data(0x0001, 0x0100); // set SS and SM bit

suggests a command 0x01, but in ILI9341 spec sheet, command 0x01 is Software Reset. Likewise, the next commands 0x02 and 0x03 are not defined in ILI9341 spec. The comment on command 0x03 says "set GRAM write direction and BGR=1", which is an activity that does exist for ILI9341; the BGR vs RGB order and write direction are set via Memory Access Control command that is command 0x36, so I'm not sure how to interpret that initialization sequence in the context of ILI9341.

juj commented 6 years ago

Google search for some of the comments in the above initialization sequence find https://github.com/notro/fbtft/blob/master/fb_ili9325.c#L120, i.e. ILI9325 controller instead. I wonder if the above code does not actually apply to your ILI9341 display and they posted the wrong code, or if the display might actually be a ILI9325 after all, instead of ILI9341? ILI9325 has a register width of 16 bits, that is something I'm not familiar with, and may need bigger changes to port to.

If you do conclude that it is actually a ILI9325 display, then it looks like Adafruit has a spec pdf online for that display, so you could try cross referencing that against ILI9341 spec sheet to find how to port to ILI9325.

dotmick commented 6 years ago

Good catch.

My gut feeling says they sent me the wrong sample code. The screen is perfectly initialized with the fb_ili9341 from the fbtft drivers.

I will not have access to my screen before next week but I'll try to analyse the initializing sequence from the fbtft and compare it with yours.

dotmick commented 6 years ago

Got some update!

I've changed the line from:

cmake -DCMAKE_BUILD_TYPE=Release -DILI9341=ON -DFREEPLAYTECH_WAVESHARE32B=ON -DGPIO_TFT_DATA_CONTROL=24 -DGPIO_TFT_RESET_PIN=23 ..

to:

cmake -DCMAKE_BUILD_TYPE=Release -DILI9341=ON -DFREEPLAYTECH_WAVESHARE32B=ON -DGPIO_TFT_DATA_CONTROL=24 -DGPIO_TFT_RESET_PIN=25 ..

and now it works! (well, the screen needs a 180deg rotation)

I need to optimise it now.

juj commented 6 years ago

Really nice!

A special thing about -DFREEPLAYTECH_WAVESHARE32B=ON configuration is that it targets the FreePlayTech CM3/Zero devices specifically, which I got a couple to play with recently. Those devices use a 3.2" 320x240 display, but parts of the display extend under the edges of the visible screen display glass, and the practical usable resolution is about 302x202 pixels. When -DFREEPLAYTECH_WAVESHARE32B=ON is passed, the display resolution is reduced to 302x202, which probably is not what you are looking for. To skip this property, you can try instead of

cmake -DCMAKE_BUILD_TYPE=Release -DILI9341=ON -DFREEPLAYTECH_WAVESHARE32B=ON -DGPIO_TFT_DATA_CONTROL=24 -DGPIO_TFT_RESET_PIN=25 ..

to build with

cmake -DCMAKE_BUILD_TYPE=Release -DILI9341=ON -DADAFRUIT_ILI9341_PITFT=ON -DGPIO_TFT_DATA_CONTROL=24 -DGPIO_TFT_RESET_PIN=25 ..

which does not shrink the visible display size to a smaller rectangle. I think they should behave identically otherwise.

To apply a 180deg rotation, you can uncomment this line, i.e. change to

#define DISPLAY_ROTATE_180_DEGREES

and rebuild. That should make the display initialize with 180 degrees rotation.

Out of the box, performance should be the "fastest possible" when -DCMAKE_BUILD_TYPE=Release is used, so it should be expected that e.g. in Quake or another fast paced moving content, the driver should get up to about 50-60mbps peak transfer speed as shown in the statistics bar up top.

dotmick commented 6 years ago

Indeed, it works better with -DADAFRUIT_ILI9341_PITFT=ON, I do not have a black border at the bottom. The rotation is now done too.

Performance wise, I'm most of the time under 1mbps (peak at 2-3, low at 100kbps) running Retroarch (snes9x core) with Super Mario World :/

juj commented 6 years ago

Super Mario World and other NES and SNES emulator games don't have much moving content on the screen, so there you should be seeing 50fps PAL / 60fps if on NTSC, even if the on-screen display is showing low mbps transfer numbers. If there are no moving content on screen, then the FPS display will also go down, since dispmanx cannot distinguish new frames that did not change with respect to previous ones.

Try cross referencing against the YouTube demo video perhaps, to see how close performance is on some of the games shown in the detailed demo video. Also, you can try disabling DMA with -DUSE_DMA_TRANSFERS=OFF to CMake. That is very recent feature I added only a couple of nights ago, so not much tested yet.

dotmick commented 6 years ago

Thanks @juj, I'll check the DMA flag tomorrow.

After watching the video, there's definitely something wrong. I know you made the tests with a RPi B and that I have a Zero but I'm too far off your numbers/stats... I'll see what I can do.

juj commented 6 years ago

Oh, you are on a Zero? That will unfortunately not work, Zero has one core only, but fbcp-ili9341 utilizes a multiple threads that need to run concurrently, it is not currently feasible otherwise. (https://github.com/juj/fbcp-ili9341/commit/9926321d3d0270e324d9d8879e00456fa0a97aa3)

dotmick commented 6 years ago

Makes sense. I'll stick with https://github.com/ian57/rpi-fbcp/ for now, that's the one which gave me the best results so far.

How DMA can improve performances on single threaded Pis? Could the use of interrupts help too?

juj commented 6 years ago

With DMA, the DMA controller does the communication with the display, rather than a thread on the main CPU. If enough work can be fed to the DMA chip at a time, then the main CPU is freed to do other actual tasks. Current master branch does utilize DMA, but it does not yet use enough of it (too small work slices). I have been working in https://github.com/juj/fbcp-ili9341/tree/dma_hacks branch to make the work slices longer so that the main CPU can be put to sleep, but not quite working yet.

Using interrupts can also help, but it's tricky. There does exist an interrupts based version in https://github.com/juj/fbcp-ili9341/blob/master/kernel/bcm2835_spi_display.c, but it does also need DMA, or otherwise the number of interrupts that fire is too large and the constant IRQ pre-emptions starve the main CPU from having time to do any real computation. After DMA is working, then it may make sense to also add interrupts to DMA.

dotmick commented 6 years ago

Thanks @juj

I'll keep an eye anyway and will make more tests when DMA will be working :)

dotmick commented 6 years ago

Hey @juj, I saw that you've made some work on the DMA, nice! If you need me to test anything give me a shout.

juj commented 6 years ago

Yeah, DMA, and also DMA task chaining are now implemented and enabled by default, and as result the driver also works on Pi Zero. NES emulated games are running at 60fps, although unfortunately due to https://github.com/raspberrypi/userland/issues/440 there can be some amount of microstuttering that does not occur on Pi 3B. There is an option #define SELF_SYNCHRONIZE_TO_GPU_VSYNC_PRODUCED_NEW_FRAMES in config.h that you can try testing to find a middle ground with CPU usage and stuttering on the Pi Zero, although it feels a bit subjective as to what currently works best.

If you do have a Pi Zero setup at hand, it'd be great to hear how well the latest code works out for you!

turtiustrek commented 6 years ago

That's great !I can finally experience 60fps out of a 2.4" display. Although regarding the micro stutter how bad is it as the buffer fills up?

On May 30, 2018 10:15 PM, "juj" notifications@github.com wrote:

Yeah, DMA, and also DMA task chaining are now implemented and enabled by default, and as result the driver also works on Pi Zero. NES emulated games are running at 60fps, although unfortunately due to raspberrypi/userland#440 https://github.com/raspberrypi/userland/issues/440 there can be some amount of microstuttering that does not occur on Pi 3B. There is an option #define SELF_SYNCHRONIZE_TO_GPU_VSYNC_PRODUCED_NEW_FRAMES in config.h that you can try testing to find a middle ground with CPU usage and stuttering on the Pi Zero, although it feels a bit subjective as to what currently works best.

If you do have a Pi Zero setup at hand, it'd be great to hear how well the latest code works out for you!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/juj/fbcp-ili9341/issues/3#issuecomment-393283643, or mute the thread https://github.com/notifications/unsubscribe-auth/AL4Xb4bPdWRC2hQLtMosTjd6f-a2pdOqks5t3u_FgaJpZM4SSXnO .

juj commented 6 years ago

I recommend you try it out yourself to see how much of an issue stuttering is. You can certainly remove the stuttering on Pi Zero with SELF_SYNCHRONIZE_TO_GPU_VSYNC_PRODUCED_NEW_FRAMES, but then CPU usage will be higher. Not so high that NES games for example still are unaffected, but e.g. noticed that SNES games started to slow down.

dotmick commented 6 years ago

Alright so a couple of tests on my RPi Zero. No optimization yet (no overclocking, no fbcp-ili9341 modifications,...). The only change is a lower HDMI resolution.

Super Mario Super Mario https://youtu.be/BqbzSgr1n_4

Sailor Moon Super Mario https://youtu.be/xEiDQl_rwHI

juj commented 6 years ago

Very nice!

To tune further, some things you can try:

For Pi Zero, interlacing can be a bit hurtful, so it's only good to use on the slower screens. I notice I disable interlacing on Zero by default only when CDIV=4 or better at https://github.com/juj/fbcp-ili9341/blob/master/config.h#L59, and I see you're running with CDIV=6, so that did not kick in automatically.

The second option reduces CPU usage on the Pi Zero at the expense of submitting more pixels. It can be a bit subjective as to which way is better, but certainly something to consider.

juj commented 6 years ago

To get a bit better bandwidth, you can try underclocking core_freq down from 400 to e.g. 300, and set CDIV=4 to get SPI bus speed of 300/6=75MHz, which should be enough to allow full 60fps (320x240x16x60=73.728MHz needed). If you run with SPI bus speed of 75MHz or better, then it's expected that #define UPDATE_FRAMES_IN_SINGLE_RECTANGULAR_DIFF would have no tradeoffs and is good to be enabled.

dotmick commented 6 years ago

So I've made a few tests based on your feedback.

First test

#define NO_INTERLACING and #define UPDATE_FRAMES_IN_SINGLE_RECTANGULAR_DIFF enabled. Amazing performances. A few slowdowns but the best result so far.

Second test

(built on First test)

I've underclocked from 400 to 300 with #define UPDATE_FRAMES_IN_SINGLE_RECTANGULAR_DIFF enabled. Way slower than the previous test.

dotmick commented 6 years ago

Apologies, for Second test I've forgot to change CDIV to 4. Now it's done.

This is better that Second test (with CDIV=6) but still, not as good as First test.

juj commented 6 years ago

Good info!

Curious to hear that 400/6=66.67MHz worked better than 300/4=75MHz. Probably the performance in the applications you are running is Pi Zero CPU bound and even if there's more SPI bandwidth, underclocking hurts Pi Zero performance itself which then slows down the application so the extra SPI bandwidth does not help. You could try going the other way, i.e. overclock the core, although I do recall that if I tried to clock the core up even a bit from 400MHz to e.g. 401MHz, for some reason I was getting visual artifacts on the display, so that may or may not work well.

Clay-Tron commented 2 years ago

I'm having difficulty getting anything but a white screen, after trying multiple settings when building.

I have a 2.8" ili9341 as seen here: http://www.lcdwiki.com/2.8inch_RPi_Display

The unit works fine with LCD-show, but no matter what I do I can't get it working with this driver.

I tried setting control to pin 15 and reset to pin 13, but still no luck.

Any tips?

juj commented 2 years ago

Unfortunately tricky to say. In these kinds of scenarios a logic analyzer has been a life saver. I developed the driver based on a logic analyzer I got off of AliExpress for a few dollars, it looks identical to this:

https://www.aliexpress.com/item/1005001621950241.html

basically reverse engineering the existing drivers and comparing them against fbcp-ili9341.

LCD-show working is good so it means that physical wiring must be ok, the same wiring should work for fbcp-ili9341. Unfortunately it's hard to say what might be wrong here, try to double check the pin wiring and the troubleshooting section from the documentation - I tried to list as many of the known white screen issues there as possible.

Clay-Tron commented 2 years ago

I have had some progress. It looks like because I had fbcp running from LCD28-show it caused conflict when trying to run the driver.

I was able to kill fbcp as per the documentation and then run the program (without being able to see what I was typing) and that was able to show text until quitting the program.

So looks like I need to purge the goodtft code.

Edit: Yep that did the trick. Works great!

For Australians reading the Jaycar 2.8" screen works well with this driver. http://www.lcdwiki.com/2.8inch_RPi_Display https://www.jaycar.com.au/240x320-lcd-touch-screen-for-arduino/p/XC4630?gclid=CjwKCAiAgbiQBhAHEiwAuQ6BktvEpsHHGegjkeNhO8Y0bd1DEuaz1HDGUB_a4ImdpBuwStV7WTuGohoCgesQAvD_BwE