Skip to content

Using SPI Displays with raylib

Ray edited this page Aug 10, 2025 · 1 revision

Source article and code sample: https://github.com/Radoslav-M/Raylib_SPI_Display

This is an example project for using SPI displays such as the 1.44inch LCD HAT.

The goal is to have the same Raylib application display on a desktop computer (for development) or a Raspberry Pi by changing a single preprocessor macro.

This approach has only been tested with the following hardware setup so far:

How it works

We must compile with the PLATFORM=PLATFORM_DESKTOP flag. This is because the PLATFORM_DRM will not initialize without a valid display device to output to. The /dev/fb0 isnt a valid device and i cannot seem to force raylib to output there.

The workaround works by setting the platform to desktop. The lite version of raspian does not have a DE, but we can use xvfb-run to create a virtual monitor. This is enough for the display to get recognised by raylib and complete the initialization. Raylib will output to an hidden virtual display, but we can capture the output by copying the image and writing it to the frame buffer after each frame is rendered.

This is not a perfect solution. The proper way to do this would be to add support for the PLATFORM_DRM to output into /dev/fb0. For now, this workaround works very well. The test scene in the application can reach 470 FPS on a RPI Zero 2. This will probably not be a bottleneck in your project

Installation instructions

Burn Raspberry Pi OS (Legacy, 32-bit) Lite on a sd card. Dont forget to add your wifi and configure ssh for headless.

After booting into the os, perform an update using sudo apt update && sudo apt upgrade

Display setup

We are using the following display https://www.waveshare.com/wiki/1.44inch_LCD_HAT.

NOTE: THIS SECTION MAY NOT WORK FOR YOUR SPECIFIC DISPLAY! TO GET THE DISPLAY ITSELF WORKING, FOLLOW THE MANUFACTURERS INSTRUCTIONS. THIS REPO IS FOCUSED ON GETTING RAYLIB RUNNIN ON THE DISPLAY

Enable SPI and install the FBCP

Run sudo raspi-config and go to: Interfacing Options → SPI → Yes → OK → Finish

sudo apt install git cmake p7zip-full libraspberrypi-dev libvcos-dev libvchiq-dev -y
cd ~
git clone https://github.com/juj/fbcp-ili9341.git
cd fbcp-ili9341
mkdir build
cd build
cmake -DSPI_BUS_CLOCK_DIVISOR=20 -DWAVESHARE_ST7735S_HAT=ON -DBACKLIGHT_CONTROL=OFF -DSTATISTICS=0 -DDISPLAY_SWAP_BGR=ON ..
make -j

Update config.txt

Change the config file to the following. Its important to comment #dtoverlay=vc4-kms-v3d and #max_framebuffers=2. At the bottom, copy the # Display section. You can change the display_rotate 1. Changes in this file take effect after a reboot.

sudo nano /boot/config.txt

# For more options and information see
# http://rptl.io/configtxt
# Some settings may impact device functionality. See link above for details

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
dtparam=spi=on

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

# Additional overlays and parameters are documented
# /boot/firmware/overlays/README

# Automatically load overlays for detected cameras
camera_auto_detect=1

# Automatically load overlays for detected DSI displays
display_auto_detect=1

# Automatically load initramfs files, if found
auto_initramfs=1

# Enable DRM VC4 V3D driver
#dtoverlay=vc4-kms-v3d
#max_framebuffers=2

# Don't have the firmware create an initial video= setting in cmdline.txt.
# Use the kernel's default instead.
disable_fw_kms_setup=1

# Disable compensation for displays with overscan
disable_overscan=1

# Run as fast as firmware / board allows
arm_boost=1

[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
otg_mode=1

[cm5]
dtoverlay=dwc2,dr_mode=host

[all]
dtparam=act_led_trigger=actpwr

# Display
dtparam=spi=on
hdmi_force_hotplug=1
hdmi_cvt=128 128 60 1 0 0 0
hdmi_group=2
hdmi_mode=87
display_rotate=1
disable_overscan=1
gpu_mem=128

Setting console font (optional)

The display is tiny, and the default terminal font will be too large to read.

sudo dpkg-reconfigure console-setup

And go to: UTF-8 → Latin1 → VGA → 8x8

Add fbcp to systemd to autostart and reboot to verify if the display works

sudo nano /etc/systemd/system/fbcp.service

Write the new service entry.

NOTE: DONT FORGET TO UPDATE YOUR USER IN THE PATH FOR EXEC START!

[Unit]
Description=Framebuffer copy for LCD
After=graphical.target

[Service]
Type=simple
User=root
ExecStart=/home/lime-dev/fbcp-ili9341/build/fbcp-ili9341  <<<<<<======= WARNING, UPDATE USER NAME HERE
Restart=always
RestartSec=1

[Install]
WantedBy=multi-user.target
sudo systemctl enable fbcp.service
sudo systemctl start fbcp.service
sudo reboot

Congrats, you should now see your terminal. If you are having trouble, you can debug by stopping the service, and trying to start fbcp manualy and read the log. (Dont forget to change the username here too)

sudo systemctl stop fbcp.service
/home/lime-dev/fbcp-ili9341/build/fbcp-ili9341

Configuring raylib for SPI

Dependencies

To be honest im not sure which of these are actually needed. While debuging I installed some packages i may not need. Some of these packages are needed for other setups ive made before, but probably not for this one. Im just too lazy to check which ones will break the setup if removed.

# Definitly needed
sudo apt install xvfb build-essential git cmake

# Some of these may not be needed and can be skipped.
sudo apt install xorg-dev libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxfixes-dev
sudo apt install libgl1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev
sudo apt install libdrm-dev libgbm-dev
sudo apt install libasound2-dev libglu1-mesa-dev libwayland-dev libxkbcommon-dev
sudo apt-get install raspberrypi-ui-mods lxterminal gvfs
sudo apt-get install mesa-common-dev
sudo apt-get install wayland-protocols

Download and compile raylib

Compile raylib as normal, but use PLATFORM=PLATFORM_DESKTOP

cd ~
git clone --depth 1 https://github.com/raysan5/raylib.git raylib
cd raylib/src/
make clean
make PLATFORM=PLATFORM_DESKTOP
sudo make install

User application

To test, you can use the program provided in the repo. The example shows how you can simply add framebuffer to your own application. Just add the // Framebuffer section, and add the InitFramebuffer(), CopyRaylibToFramebuffer() and CloseFramebuffer() functions to your main section.

You can simply enable and disable framebuffer support by commenting or uncommenting the #define USING_FRAMEBUFFER macro. This will let you test on your desktop and deploy on an device with the same code. You can also configure some parameters below.

Running the test code

You can use the CMake extension on vscode or compile manualy. First go into the build directory. If its missing just mkdir to create it.

cd build
cmake ..
make
cd ..
xvfb-run -a -s "-screen 0 128x128x24" ./RaylibSPIDisplay
Clone this wiki locally