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

How to keep one of the HDMI's frame buffer intact for a pi4 system? #175

Closed dattasaurabh82 closed 3 years ago

dattasaurabh82 commented 3 years ago

It is more of clarification/feature-understanding rather than an issue

Hello. First of all thank you so much for this as it is a very helpful tool to setup SPI TFTs with commonly found TFT chipsets. πŸ˜‡

If I understand correctly, it copies over frame data, available at /dev/fb0 [for default HDMI], with out creating a /dev/fb1 for the SPI display bus which is a huge advantage to run it faster at 60Hz, which basically means it kind of mirrors/copies over the HDMI Frame buffer [ in laymen's over simplified terms, as I'm a noob in this area of display and kernel settings ]

My question is, for a raspberry pi4, can I keep the 2nd HDMI fb (if there is any) intact and separate from being copied over to SPI. In other words, how can I assign, while compiling, that only copy over the HDMI-0's frame buffer and let the HDMI-1 be as it is? Or am I overthinking it and for Pi4, running latest buster, it will anyways only copy the HDMI-0's frame buffer? πŸ˜…

I understood, for proper resolution setting reasons, in /boot/config.txt you have suggested to add these settings:

hdmi_mode=87
hdmi_cvt=320 240 60 1 0 0 0
hdmi_force_hotplug=1

I have no way of testing at the moment as my Pi4 is still in transit. Any direction and help would be very much appreciated.

juj commented 3 years ago

I believe it will always copy the first HDMI display's framebuffer. I have not actually tried out either with two HDMI displays, so not sure how it will behave. Let me know as well.

I hear that on RPi4 one needs to manually enable DispmanX API in raspi-config by adjusting the OpenGL driver option in the menu settings.. with bad luck that disables dual HDMI output support, but I suppose you'll find out soon enough if that's the case...

juj commented 3 years ago

To be more precise, if there is only one HDMI connected, then it will always duplicate its framebuffer, possibly scaling it down to the SPI display resolution, in case the original HDMI output resolution is something else. If the two HDMI displays do show up as /dev/fb0 and /dev/fb1 then I presume the second HDMI would be able to operate independently to fbcp-ili9341 operation.

dattasaurabh82 commented 3 years ago

@juj that is my assumption as well. I will get the pi4 today and will post the updates here. BTW I've just started maintaining a small blog post on this here

dattasaurabh82 commented 3 years ago

@juj . So My Pi4 arrived and after configuring the system [ updating, upgrading etc. πŸ˜ͺ ].

# Enable DRM VC4 V3D driver on top of the dispmanx display stack
dtoverlay=vc4-fkms-v3d
max_framebuffers=2

[all]
hdmi_group=2
hdmi_mode=87
hdmi_cvt=240 240 60 1 0 0 0
hdmi_force_hotplug=1
juj commented 3 years ago
1. It says: `DISPLAY_FLIP_ORIENTATION_IN_SOFTWARE: Swapping width/height to update display in portrait mode to minimize tearing.` but in `config.h`, around line162, which is: `#define DISPLAY_OUTPUT_LANDSCAPE` is not commented out and I didn't pass any build option to rotate anything. 🧐

All the small SPI display panels are "portrait panels", i.e. their vsync refresh runs in portrait orientation. Well, a 240x240 display is square, so there identifying between portrait vs landscape requires looking at the datasheet of the casing manufacturer. DISPLAY_FLIP_ORIENTATION_IN_SOFTWARE makes the panel updates occur in the native/natural scan order to minimize this kind of diagonal tearing artifact that would otherwise occur if bytes are uploaded in landscape, but the panel updates in portrait. See "Diagonal Tearing Mode" in https://www.youtube.com/watch?v=EOICdpjiqv8 for what that effect looks like in slow motion. Basically DISPLAY_FLIP_ORIENTATION_IN_SOFTWARE enables the "Straight line tearing mode", at the expense of some added CPU usage.

2\. `.. Source GPU display is 240x240 ..` . Well first of all there is no source on HDMI-0 as I didn't connect anything to it. So is it because we asked in `/boot/config.txt` to `hdmi_force_hotplug=1`, so it created a virtual display!? But then, according to what? In `raspi-config->advanced-settings`, for _resolution settings_, it says (if I remember correctly), something along the lines: .. choose the best resolution based on attached display etc..

The HDMI output on the Pi is enabled/disabled independent of Linux framebuffer system. tvservice -s can be used to print out its current status. There will always be a HDMI output/framebuffer on the DispmanX, as long as tvservice -s says that HDMI is on. I don't know how tvservice -s works with two HDMI outputs, perhaps it prints two sets of output parameters, or something like that.

The size 240x240 was defined by you by choosing to target ST7789, and by enabling DISPLAY_CROPPED_INSTEAD_OF_SCALING=ON. You can also try setting hdmi_cvt=240 240 60 1 0 0 0 to get the HDMI output to run in the same resolution as the SPI display is. That way you can pass DISPLAY_CROPPED_INSTEAD_OF_SCALING=OFF to the build to get pixel-perfect output. (I think it is also possible to go faster than 60hz with a ST7789, but don't exactly remember what the max refresh rate is - check from a datasheet if you find one)

3\. After Quarrying `/dev/fb*` , I only still get `/dev/fb0` returned. So HDMI-1 is not fb1.

That is interesting.. No idea how that is supposed to work on the RPi4!

* **Good news is**, The _2nd HDMI_ [HDMI-1] is set to it's connected display's resolution and is separate and not mirrored (but can be set to mirror the first display).

Most excellent! Hopefully that will run smooth.

dattasaurabh82 commented 3 years ago

@juj, Thank you so much again, for the clarifications and information. Regarding your suggestion on driving ST7789 based displays at a higher rate, I found this: from the pi's documentation on core freq :

Changing core_freq in config.txt is not supported on the Pi 4, any change from the default will almost certainly cause a failure to boot.

juj commented 3 years ago

You do not need to change core_freq. Changing the refresh rate of ST7789 display is done via a SPI command. For ST7789VW model it is

https://github.com/juj/fbcp-ili9341/blob/662e8db76ba16d86cf6fd09d85240adc19e62735/st7735r.cpp#L101

though for other ST* display models it is not enabled.

To update at e.g. 100hz display rate, one would change

hdmi_cvt=240 240 60 1 0 0 0

to

hdmi_cvt=240 240 100 1 0 0 0

Although I am not sure if the Pi supports refresh rates > 60.

dattasaurabh82 commented 3 years ago

You do not need to change core_freq. Changing the refresh rate of ST7789 display is done via a SPI command. For ST7789VW model it is

https://github.com/juj/fbcp-ili9341/blob/662e8db76ba16d86cf6fd09d85240adc19e62735/st7735r.cpp#L101

though for other ST* display models it is not enabled.

To update at e.g. 100hz display rate, one would change

hdmi_cvt=240 240 60 1 0 0 0

to

hdmi_cvt=240 240 100 1 0 0 0

Although I am not sure if the Pi supports refresh rates > 60.

Cool. Will check and let you know

dattasaurabh82 commented 3 years ago

@juj . So the display runs smooth at 100 Hz. No problem πŸ˜ƒ