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
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
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. <pre> sudo dnf update sudo systemcl reboot # if there are kernel updates sudo dnf install -y rpmdevtools sudo dnf builddep -y kernel </pre> ## Messing with the kernel sources Let's install the kernel source. <pre> sudo dnf install -y rpmdevtools sudo dnf builddep -y kernel dnf download --source kernel rpm -i kernel-*.src.rpm cd rpmbuild </pre> Run "rpmbuild -bp" for extracting source tree. <pre> rpmbuild -bp SPECS/kernel.spec </pre> 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```. [bcm2837-rpi-3-b.dts.patch](https://alciregi.fedorapeople.org/dts/bcm2837-rpi-3-b.dts.patch)<br/> [bcm283x.dtsi.patch](https://alciregi.fedorapeople.org/dts/bcm283x.dtsi.patch)<br/> [bcm2835-rpi.dtsi.patch](https://alciregi.fedorapeople.org/dts/bcm2835-rpi.dtsi.patch) 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 <pre>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 -</pre> 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. <pre> 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 </pre> If everything seems to be all right, you should see the devices under ```/dev``` <pre> 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 </pre> ## Test the SPI interface Let's use a tool included in the kernel sources. <pre> cd ~/rpmbuild/BUILD/kernel-4.17.fc28/linux-4.17.14-202.fc28.armv7hl/tools/spi/ make </pre> 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 <pre> sudo ./spidev_test -D /dev/spidev0.0 </pre> This should be the result: <pre> spi mode: 0x0 bits per word: 8 max speed: 500000 Hz (500 KHz) </pre> ## 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. <pre> 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 </pre> In the Makefile put these lines:
obj-m := bcm2835-gpiomem.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KDIR) M=$(PWD) modules ```
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
/dev/gpiomem is in place.
Let’s try the LCD DISPLAY
Follow some better guide related to how to wire the Nokia 5110 LDC display to the RPi.
|RPi Physical pin||RPi pin||LCD pin|
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.
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.