Closed mattblovell closed 3 years ago
Nice!
Out of interest, have you tried the Linux framebuffer driver with this display?
To get this PR through we ought add some simple regression tests and update the documentation
... and probably convert the CI from Travis to GitHub actions (in another PR) beforehand
... and probably convert the CI from Travis to GitHub actions (in another PR) beforehand
See #137
Out of interest, have you tried the Linux framebuffer driver with this display?
Yes, I first tried out the display via the repository that Waveshare provides:
https://github.com/waveshare/LCD-show.git
I didn't use their shell scripts, but inspected what overlay they make use of and loaded it myself. The dtoverlay uses a compatible
string of ilitek,ili9486
with these addition parameters:
waveshare35b@0 {
compatible = "ilitek,ili9486";
reg = <0x00000000>;
pinctrl-names = "default";
pinctrl-0 = <0x00000001>;
spi-max-frequency = <0x00e4e1c0>;
txbuflen = <0x00008000>;
rotate = <0x0000005a>;
bgr = <0x00000000>;
fps = <0x0000001e>;
buswidth = <0x00000008>;
regwidth = <0x00000010>;
reset-gpios = <0xffffffff 0x00000019 0x00000001>;
dc-gpios = <0xffffffff 0x00000018 0x00000000>;
in addition to an array of init
bytes. The spi-max-frequency above is 15 MHz. The overlay file looks to be identical to the GPL-licensed one at
(The relationship between that github repository and Waveshare's is unclear to me.)
The luma.examples work fine via linux_framebuffer, with bounce achieving >20 fps when using the diff algorithm. The combination of luma.core's diff algorithm with whatever approach the device driver is taking for updates leads to a fair amount of tearing. Using full_frame, bounce gets 6.2 fps through the framebuffer.
Using luma.lcd directly at 50 MHz (a frequency that is certainly questionable for this display), bounce is achieving 5.3 fps with full_frame and 19 to 23 fps with diff. There's much less tearing, though! :)
To get this PR through we ought add some simple regression tests and update the documentation
I'll take a look at what the tests require. Since the tests presumably run without actual display hardware, are they just performing some sanity checks? The ili9486 addition mimics the structure of the ili9341 support identically.
My chief concern is that other ili9486 displays may not have the 16-bit registers of the particular Waveshare that I have. Looking around github at other (open license) implementations for ili9486 support, the byte padding only gets mentioned in conjunction with Waveshare. That would seem straightforward to support -- use a conditional to control whether padding gets added or not -- but that conditional would be unique to the ili9486. I also have no means of HW testing it.
Any hints on how one runs tests? I'm still relatively new to Python development, and the amount of infrastructure around Python projects is impressive. That said, I don't know how to run much!
@mattblovell from repo checkout directory:
make sure to install tox, pytest etc first using:
pip install -e .[test]
then run tests:
tox -e py37
or py38 or whatever version you're using.
also run:
tox -e qa
to check for any lint errors.
I tend to develop luma code & run tests on a Mac or desktop Linux machine rather than on an RPi. It was often painfully slow - certainly on RPi 2B, but might be better now on 4B
Also, I can help out with the tests. We can mostly do a cut’n’paste job from ili9341
Also, I can help out with the tests. We can mostly do a cut’n’paste job from ili9341
That would be most appreciated! I'll see if I can free up some time tonight to try out tox
(per @thijstriemstra's reply above), but I don't necessarily know what I'm doing with the test infrastructure.
I double-checked that the padding zeros are indeed needed for the Column Address Set (0x2A) and Page Address Set (0x2B) commands within ili9486.display()
. Removing any of the zero padding (either after the command or those in between any of the command's parameters) results in the diff_to_previous algorithm not getting drawn correctly on-screen.
"Armed" with that information, I thought I would reexamine the positive and negative gamma settings for ili9486 in both juh/fbcp-ili9341 and ImpulseAdventure/Waveshare_ILI9486. Adding the commands with byte pads just yields terrible colors -- blues and purples end up with really bad saturation.
Dumping the initialization bytes from the dtoverlay that Waveshare makes available and pulling the gamma correction from those, colors seem fine but don't appear noticeably different than what the display uses without any gamma controls specified.
The Waveshare overlay is using 18-bit colors, which matches the initialization I'm trying (via Memory Access Control, 0x36). The other two repositories are only set up for 16-bit colors. Perhaps that explains the difference.
Anyway, just thought I'd explore the gamma settings a bit further.
I think I have the entries in test_ili9486.py
working. I only have one screen size (full) supported.
tests/test_ili9486.py::test_init_320x480 PASSED [ 56%]
tests/test_ili9486.py::test_init_invalid_dimensions PASSED [ 58%]
tests/test_ili9486.py::test_offsets PASSED [ 60%]
tests/test_ili9486.py::test_contrast PASSED [ 61%]
tests/test_ili9486.py::test_hide PASSED [ 63%]
tests/test_ili9486.py::test_show PASSED [ 64%]
tests/test_ili9486.py::test_display_full_frame PASSED [ 66%]
Execution time for tox -e py37
on an RPi4:
real 0m14.644s
user 0m9.499s
sys 0m1.141s
I don't immediately know why the Python 3.8 tests are unhappy.
I don't immediately know why the Python 3.8 tests are unhappy.
Ah, linting woes. I like blank lines, though! :)
I'll try to clean that up...
FYI, you can run tox -e qa
to run the PEP8 and documentation checks, and usually flake8 can be used to auto format (we should probably have a tox target that does this)
I’ve got one of these on order now because of you!
Excellent! Hopefully it even works! 😄
Did you get the Waveshare one or a different ILI9486-based one? I have to say that the IPS panel is a nice feature.
Great!
I'm very glad to contribute back to luma.lcd. The excellent documentation for this project, and the breadth of supported displays, is what encouraged me to give these little LCD displays a try in the first place. I've learned a lot since September.
v2.8.0 released with this in :rocket: https://pypi.org/project/luma.lcd/2.8.0/
16-bit
RE: 16-bit registers, I just found this : https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/tiny/ili9486.c#L38
The following additions, primarily to
device.py
are working for me when using this ILI9486-based display:https://www.waveshare.com/3.5inch-rpi-lcd-b.htm
attached directly to the GPIO header of an RPi4 Model B. That particular display (or the controller) wants to run in portrait mode, 320x480. Rotation is thus necessary to use it as 480x320. (I was stuck for quite a while getting an odd display trying to use it in landscape mode.)
The various demos within luma.examples all seem to be happy, using either full_frame or the diff algorithm to update the framebuffer. Some misc observations:
I've run the
bounce.py
demo with a SPI bus frequency up to 50 MHz, achieving ~23 fps. Performance does still scale with SPI bus frequency.The
pi_logo.py
demo also runs at such high frequencies, but the rendered colors end up being incorrect. The leaves on the Pi logo end up being orange instead of green! Slowing down to 32 MHz gets the colors correct. (Animation speed is still quite good at that SPI frequency using the diff algorithm.)Interestingly, the gradient example within
colors.py
is still unhappy even at 32 MHz. Even though the rest of that example, including the opening photo and the rainbow screen, all look fine, the gradient screen ends up with artifacts suggesting bad data transfer. Slowing down to 28 MHz, the gradient screen looks perfectly normal (photos below).Thanks, Matt
fixes #135
Gradient screen from
colors.py
@ 32 MHzGradient screen from
colors.py
@ 28 MHz