As opposed to I2C, SPI on Fedora ARM doesn’t work out of the box. In this post I will describe what I did in order to use a Nokia 5110 LCD display on a Raspberry Pi 3 running Fedora 28 (Fedora-Minimal-armhfp-28).
This is due to the fact that the device tree definition file shipped with the upstream kernel doesn’t include all the necessary bits. And some other thing.
Disclaimer: I’m not an engineer nor a kernel developer. This post comes from try and fail tasks, googling for info, observations, etc. Pay attention when working with the GPIO pins and the electricity. I’m still alive and my RPi still works pretty well, but damages to your RPi coming from tasks here described cannot be attributed to me :-) As usual, forgive my English. The purpose of this post is for test and tinkering.
How to add the required bits
Look into a DTB file
Fedora on the Raspberry Pi 3 load the bcm2837-rpi-3-b dtb located in /boot/dtb/bcm2837-rpi-3-b.dtb
.
Since this file is compiled you have to use some command line tool to read the content. The human readable format is DTS (Device Tree Source Format), more info here. You can compile and decompile them using the dtc
command.
sudo fdtdump /boot/dtb/bcm2837-rpi-3-b.dtb
To get a specific value:
sudo fdtget /boot/dtb/bcm2837-rpi-3-b.dtb /soc/spi@7e204000 status
You will see that the spi status is disabled. You could use fdtput
to enable it, but it is not sufficient.
Install some RPM packages
Let’s install some packages. Maybe there are other ways to put the necessary bits in place. But I was unable to do it better.
sudo dnf update
sudo systemcl reboot # if there are kernel updates
sudo dnf install -y rpmdevtools
sudo dnf builddep -y kernel
Messing with the kernel sources
Let’s install the kernel source.
sudo dnf install -y rpmdevtools
sudo dnf builddep -y kernel
dnf download --source kernel
rpm -i kernel-*.src.rpm
cd rpmbuild
Run “rpmbuild -bp” for extracting source tree.
rpmbuild -bp SPECS/kernel.spec
Now go to the arm dts directory
cd ~/rpmbuild/BUILD/kernel-4.17.fc28/linux-4.17.14-202.fc28.armv7hl/arch/arm/boot/dts
Download and apply these patches. The involved files are: bcm2837-rpi-3-b.dts
, bcm283x.dtsi
and bcm2835-rpi.dtsi
.
The last one contains the gpiomem
descriptor, that as far as I can understand, it is needed by various python libraries.
Now compile the final dtb file
cpp -I../../../../include -E -P -x assembler-with-cpp bcm2837-rpi-3-b.dts | dtc -I dts -O dtb -o bcm2837-rpi-3-b.dtb -
In the previous step we didn’t enable the spi device, we can do that using th fdtput
command
fdtput --type s bcm2837-rpi-3-b.dtb /soc/spi@7e204000 status okay
At this point we can copy the file to the final destination and reboot the Raspberry.
sudo cp /boot/dtb/bcm2837-rpi-3-b.dtb /boot/dtb/bcm2837-rpi-3-b.dtb.ORIG
sudo cp ./bcm2837-rpi-3-b.dtb /boot/dtb/bcm2837-rpi-3-b.dtb
sudo systemctl reboot
If everything seems to be all right, you should see the devices under /dev
ls -la /dev/spidev*
crw-------. 1 root root 153, 0 May 11 12:26 /dev/spidev0.0
crw-------. 1 root root 153, 1 May 11 12:26 /dev/spidev0.1
Test the SPI interface
Let’s use a tool included in the kernel sources.
cd ~/rpmbuild/BUILD/kernel-4.17.fc28/linux-4.17.14-202.fc28.armv7hl/tools/spi/
make
Running this program
sudo ./spidev_fdx /dev/spidev0.0
You should see
/dev/spidev0.0: spi mode 0x0, 8 bits per word, 125000000 Hz max`
Running this other program
sudo ./spidev_test -D /dev/spidev0.0
This should be the result:
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
gpiomem
Stuff like Adafruit_Nokia_LCD, and many drivers and libraries require the existence of /dev/gpiomem
, as far as I can understand.
But the bcm2835-gpiomem kernel module is not upstream, so you need to download and compile it.
Again: maybe there are better ways to achieve this task.
sudo dnf install kernel-devel
mkdir /var/tmp/bcm2835-gpiomem
cd /var/tmp/bcm2835-gpiomem
curl -O https://raw.githubusercontent.com/raspberrypi/linux/rpi-4.17.y/drivers/char/broadcom/bcm2835-gpiomem.c
vi Makefile
In the Makefile put these lines:
Note: before $(MAKE) there is a TAB.
Now let’s compile the module.
make -C /lib/modules/`uname -r`/build M=`pwd` modules
sudo make -C /lib/modules/`uname -r`/build M=`pwd` modules_install
And let’s try to load it:
sudo modprobe bcm2835-gpiomem
Verify that /dev/gpiomem
is in place.
Let’s try the LCD DISPLAY
Wiring
Follow some better guide related to how to wire the Nokia 5110 LDC display to the RPi.
RPi Physical pin | RPi pin | LCD pin |
---|---|---|
18 | GPIO 24 | RST |
24 | CE0 | CE |
16 | GPIO 23 | DC |
19 | MOSI | DIN |
23 | SCLK | CLK |
1 | 3.3V | VCC |
11 | GPIO 17 | BL |
6 | GND | GND |
Using the Adafruit Nokia LCD Python library
sudo dnf install python3-devel python3-pillow python3-RPi.GPIO
git clone https://github.com/adafruit/Adafruit_Nokia_LCD.git
cd Adafruit_Nokia_LCD
sudo python3 setup.py install
cd examples
Run some example code.
kernel updates
Remember that the /boot/dtb is a link to a directory related to the current kernel and it will be changed at every kernel update, so the bcm2837-rpi-3-b.dtb
loaded at boot will be replaced.