Working SPI Display

Sharing the simple guide that I put together based on other user @HejinYo, to make display work.
He made it for ST7789, while i was able to make it work for ST7735s.

link:

demo:

TODO:
Trying to implement framebuffer copy (fbcp) to run proper display on these spi screens.
If someone has already made one, please let me know.

6 Likes

WOW!!! on my radxa i have installed android 9, is there any way to install these drivers? or give these commanders? thank you

Wooo, the video looks very smooth, I see in your dts file that you use :
width = <135>;
height = <240>;

Is it still smooth with such a resolution?

I’m still struggling with my 240x240 SPI display wich blink and is still too slow to display animated picture on 240x240 resolution (Is there a way to increase SPI clock speed?)

I am not sure yet. I don’t think theres a way to update device tree on android to make lcd screen work.

1 Like

That was just a sample dts setup, but you can definitely modify it according to your lcd screen size.

Hi. Thanks for sharing your expirience. I found your repo with guide and did the same. As a result I found /dev/fb1 device after reboot. Now backlight of the device is off. But command
sudo fbi -d /dev/fb1 -T 1 -noverbose -a ./cat.jpg
to send something to fb1 doesn’t work. Only returning:
using "DejaVu Sans Mono-16", pixelsize=16.67 file=/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf

I have connected the following shield:
https://www.waveshare.com/1.44inch-lcd-hat.htm
Wiki: https://www.waveshare.com/wiki/1.44inch_LCD_HAT

Controller model is: st7735s, screen 128x128.
Do I need change some thing inside dts file?

Dmesg output: dmesg | grep fbtft

[    4.504514] fbtft: loading out-of-tree module taints kernel.
[    4.505309] fbtft: module verification failed: signature and/or required key missing - tainting kernel
[    4.581932] fb_st7789v spi1.0: fbtft_property_value: width = 135
[    4.581946] fb_st7789v spi1.0: fbtft_property_value: height = 240
[    4.581951] fb_st7789v spi1.0: fbtft_property_value: buswidth = 8
[    4.581956] fb_st7789v spi1.0: fbtft_property_value: debug = 1
[    4.581960] fb_st7789v spi1.0: fbtft_property_value: rotate = 270
[    4.581965] fb_st7789v spi1.0: fbtft_property_value: fps = 60
[    4.582074] fb_st7789v spi1.0: fbtft_request_one_gpio: 'reset' GPIO
[    4.582095] fb_st7789v spi1.0: fbtft_request_one_gpio: 'dc' GPIO
[    4.582113] fb_st7789v spi1.0: fbtft_request_one_gpio: 'rd' GPIO
[    4.582127] fb_st7789v spi1.0: fbtft_request_one_gpio: 'wr' GPIO
[    4.582140] fb_st7789v spi1.0: fbtft_request_one_gpio: 'cs' GPIO
[    4.582153] fb_st7789v spi1.0: fbtft_request_one_gpio: 'latch' GPIO
[    4.582166] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582183] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582197] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582211] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582224] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582238] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582251] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582264] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582277] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582291] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582304] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582317] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582330] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582344] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582357] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582370] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582384] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582397] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582410] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582424] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582437] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582451] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582464] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582477] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582491] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582505] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582520] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582533] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582547] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582560] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582574] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582587] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582601] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582614] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582628] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582641] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582655] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582668] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582681] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582694] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582708] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582722] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582735] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582748] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582761] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO
[    4.582775] fb_st7789v spi1.0: fbtft_request_one_gpio: 'db' GPIO
[    4.582788] fb_st7789v spi1.0: fbtft_request_one_gpio: 'led' GPIO
[    4.582802] fb_st7789v spi1.0: fbtft_request_one_gpio: 'aux' GPIO

Any idea how to use joystick and buttons on my shild? Is that general gpio? I mean I can use echo "500" > /sys/class/gpio/export

Button key2 is available as gpio:

 echo 422 > /sys/class/gpio/export
#press button (default value is 1)->0
 cat /sys/class/gpio/gpio422/value

Thanks in advance

you can try connecting the backlight led pin of your display directly to 3.3v to see if you can get the backlight on.

Yes. It is not a problem to turn on the backlight. I found the right gpio. Main problem is: You mentioned that you has been successfully connected st7735 display, but there is no driver inside git repo for that type of the display.

Some clarification would help a lot here, Mark. There is a section in the instructions where it is impossible to determine whether some of the lines are statements of things you should see as contrasted to things you should do.

For many of us, this is the first time we’ve ever been exposed to the concept of device tree overlays, let alone how to compile one; your instructions assume knowledge that many of us attempting to get our SPI displays working may not have.

Could you please give some clarification, and/or point us at some “do these steps and it will work” instructions?

Posting the driver source would be immensely helpful, for example.

Yes, but it should be just similar to what was in the repo.

I am also not the best person to teach you about device tree overlays. The guide is just fairly a working demo that was based on the original guide that I found. It was fairly translated to english since it was originally in Chinese.

Also, I stopped poking around this board due to very limited support. And as expected, if you want to make things work you might be required to have some good level of understanding just like some of the people who are still dedicated to work on this board.

1 Like

@mrkprdo Could you share how to connect the lcd to the zero? which pins go where?

…I was able to get what looks like “snow crash” on my display after reading up and moving some pins around today. I am still not sure where DS, RST, and BL, should go though. It really sucks that no one reads this forum.

It’s really depending on your display. But generally power goes to power, ground goes to ground, SPI goes to SPI, and the rest are usually any free GPIO pins. I have no idea what DS or BL stands for, but using this Waveshare display as an example:

  • SI/SO/CLK/CS are SPI pins
  • 5V/3.3V/GND are power pins
  • NC stands for not connected
  • rest are control pins that can be connected to GPIO pin, but requires device tree overlay and driver to properly control them

I’m trying to get a Waveshare 2" SPI TFT display working, with screen dimensions of 240v, 320w.

I’m attempting to use the instructions presented in the repository here: https://github.com/mrkprdo/radxa-zero-spi-display

There are no instructions available from Radxa directly on how to do this.


Okay - a very careful reading on the instructions gives me what I think is a complete understanding of how it’s supposed to work.

  1. Install the Radxa official Ubuntu bootable distro (“Buster”).
    Open a terminal shell and access your root account. Everything else you do will be via this open shell. sudo bash should do the trick. Change to your home directory with cd ~.

  2. Set up wifi via the main console (keyboard, mouse and screen). Access rootTo do this, open a shell and type:
    nmcli dev wifi connect <yourWifiMountPointName> password <yourWifiPassword>

  3. You can update your repository, but DO NOT UPGRADE anything. If you do, you can end up with multiple kernel-specific directories for different kernels. Only the currently active kernel as described in the /boot/uEnv.txt file will matter, so there’s no point in upgrading the kernel before you get this working the first time. Change as few variables as possible while you fiddle with it, then migrate the changes to the new kernel if you want to update the kernel afterwards.

  4. Install git, the device tree compiler, and the framebuffer command line tool: sudo apt install git fbi device-tree-compiler

  5. Use git to get the repository from Github:
    git clone https://github.com/mrkprdo/radxa-zero-spi-display

  6. Navigate to your device tree path: cd /boot/dtbs/5.10.xx-x-amlogic-xxxxxxxxxxxxx/amlogic/overlay

  7. Copy the sample .dts file from the repository you cloned into the current directory:
    cp /root/radxa-zero-spi-display/meson-g12a-spi-lcd.dts .

  8. Edit the file meson-g12a-spi-lcd.dts, and edit the screen dimensions to match your device. Mine has a width of 320 pixels and a height of 240 pixels.

Now this is where things get fuzzy.

  1. The instructions suggest changing pins for to something one looks up from a header file located at https://wiki.radxa.com/Zero/hardware/gpio, and they say that the value here should be GPIOH_8 for the Radxa Zero. Then we are told to check to see whether we should set it to initialize it as either HIGH or LOW, and that this second value should be 1 or 0 respectively.

Unfortunately exactly how we check this, or where to find this out, isn’t covered in the instructions.

Also unfortunately, nothing in the .dts file actually matches <pin>, and there is no inkling as to what this means. I am assuming they mean reset-gpios because it’s already set for <0x2b 8 1>, but it’s a leap of faith because I don’t know what <0x2b 8 1> actually means in context.

  1. After that, we are told to save the file and compile it to a dtbo file (ignoring the warnings - it generates five of them).
    dtc -@ -I dts -O dtb -o meson-g12a-spi-lcd.dtbo meson-g12a-spi-lcd.dts

  2. Then you update the file /boot/uEnv.txt to tell it to load the new overlay meson-g12a-spi-lcd, adding the following contents if missing (do not create a second “overlays” parameter line, just append meson-g12a-spi-lcd if it’s not present. Separate overlay names with spaces, not commas.):
    overlays=meson-g12a-spi-lcd
    param_spidev_spi_bus=1
    param_spidev_max_freq=10000000

  3. Save the file, then go to the code repository you’ve downloaded from Github and run the “make” command:
    cd /root/radxa-zero-spi-display/kernel-linux-5.10.y-radxa-zero/drivers/staging make
    This will produce the two .ko files you need.

  4. Copy fbtft.ko and fb_st7789v.ko to the staging directory for your currently active kernel:
    cp fbtft.ko /usr/lib/modules/5.10-xx-x-amlogic-xxxxxxxxxxxxx/kernel/drivers/staging

  5. Now all you have to do is reboot:
    reboot now

If one does do an apt upgrade, one gets a second modules directory under /usr/lib/modules for a new version of the kernel, and a new subdirectly under /boot/dtbs into which one must copy the code for the device driver and compile it. The /boot/dtbs and /usr/lib/modules directory contents must be in sync or the magic trick does not work.

Anyway, when it comes back up, you should be able to see it via dmesg:
dmesg | grep fbtft

For me, so far so good.

However, then we test the newly created SPI framebuffer device with the fbi command line tool:
fbi -d /dev/fb1 -T 1 -noverbose -a <sample_image> and that’s where I break.

If one follows the above steps exactly, it compiles and the modules load. However, there should be an /dev/fb1 device, and there isn’t one.

Apparently it’s related to the GPIO pin setting somehow. A search through the dmesg output produces several error messages to this effect:
[ 0.069614] OF: /soc/bus@ffd00000/spi@15000/st7789v@0: could not get #gpio-cells for /soc/bus@ff600000/bus@34400/pinctrl@40/i2c3-sck-a1

Does this mean my Radxa is broken? Shouldn’t it be able to get GPIO cells from the pinctrl device manager?

… and one important one bug that looks serious:

[ 7.088944] fb_st7789v spi1.0: error -EINVAL: Failed to request reset GPIO [ 7.099764] fb_st7789v: probe of spi1.0 failed with error -22

This error is probably why my device driver isn’t coming up, and I believe the problem may be related to step #10 above. Apparently the pinctl kernel module isn’t finding necessary GPIO data for the new device descriptors, but I can’t tell why. This is especially frustrating since others have followed the instructions and have apparently not hit this issue.

Anybody got any ideas?

Update

Apparently that’s exactly what it means: my Radxa is broken.

I have a defective Radxa Zero, because when I tried the entire above process on a second unit I had on hand, I got no GPIO error messages. However, now I have a new error when I try to use the fbi command line tool to display a graphics file:

fe-dai-link-0: ASoC: no backend DAIs enabled for fe.dai-link-0

This appears to be a kernel bug, but the version of the kernel I’m using isn’t supposed to have it. I also don’t know if it’s related at all to the SPI display not displaying anything, but it’s now the only error message I have.

My SPI display backlight lights up when the Radxa powers up, but otherwise it does nothing.

I’m following the connection directions from Waveshare as described here.

BL stands for Backlight.
DC stands for Display Clock (I think you meant DC)

The reason there is no instruction is because when I tried to follow and reproduce those guide I couldn’t get SPI display to work myself. The best I got was a /dev/fb1 with backlight on. However, the image is corrupted in strips, so that feels like some kind of timing issue.

Here is the code that I created back then. This installs fbtft driver as dkms module, and compile the dtb overlays. My test was done with meson-g12a-spi-ili9486.dts since that’s the screen sample I had back then.

I notice that the ST7789v driver is there too. I’ll try it, it’s worth a shot.

I have not touched my zero for a long time. Let me get back to it and try this again. And hopefully, i can get some proper guide or perhaps provide the drivers to make this work.

That would be pretty amazing, Mark!

I hope you find my detailed technical description of what I did and how it went useful.

You’re a mensch.

I’m using a Waveshare 2" display, with a resolution of 240x320.