Using an SPI OLED Display with the Linux Kernel

video showing a cursor clicking on various elements on a little monochrome OLED screen

To get familiar with the tools and concepts of the Yocto project, I wanted to do a project using an SPI OLED display I bought recently. Those tiny displays are popular with electronics hobbyists for use with microcontrollers, such as Arduino. However, there is no reason why you couldn’t also use those displays with more powerful hardware. Many embedded applications require a complex software environment (i.e., Linux) but don’t have the need for an elaborate user interface. Such little displays provide an aesthetically pleasing way of bridging the gap between LED indicators and a full embedded GUI.

Kernel vs. User Space Driver

Generally speaking, there are two ways to implement the driver logic for hardware on a Linux system. The first possibility is to use a general kernel driver, which only handles the very basic operations like driving GPIO pins and talking to SPI or I2C controllers. The actual driver for the specific hardware resides in user space. This could be done in the form of a C program or a Python script which bit bangs specific GPIO lines to communicate with a device, or which makes use of the generic userspace I2C or SPI interfaces that some kernels expose. Many tutorials on the Internet use this technique to easily use hardware with Raspberry Pi and co. However, drivers implemented like this are limited in what they can do.

The other possibility is to move the driver into the kernel. This method can be used to offload the hardware-specific details to the kernel and only expose a high-level, abstract hardware representation to user space. This allows easier integration with other software, improves portability and is generally better for performance as overhead (e.g., context switches) is reduced. While it may be more complex to set up than a user space script, using a dedicated kernel driver is the proper way to do things for many applications.

My setup

I used an Olimex Olinuxino A20 Micro board with an Allwinner A20 SoC (2x ARM Cortex A7) and a no-name (?) 128x64 OLED display with an integrated SSD1309 controller chip. This chip supports both I2C and SPI, I used SPI.

In Linux, I make use of the in-tree DRM driver for the ssd130x series. This driver allows the SPI display to be used like any other screen attached over, e.g., HDMI. It allows an X11 server (using the modesetting driver) to draw on the OLED display. The device tree specifies which GPIO pins are connected to the display, as well as some more settings specific to the used OLED panel.

rickroll video on the OLED screen

I think interfacing those tiny displays from Linux is very fun, especially because once the setup is working, it is trivial to display things like pictures and videos, GUIs, different fonts etc. using familiar Linux tools, which would be more difficult to achieve on a microcontroller.

The Yocto layer and some more information about this project can be found on Github.