Display Driver for Zephyr
In this project, I use an nRF52 development board and a cheap 3.5" TFT module to experiment with graphical displays on Zephyr RTOS. The display module is hard-wired to use the parallel 8-bit 8080 interface of the ILI9486 driver chip. It has a 480 x 320 resolution and supports 16 bit colors. Thanks to the Arduino headers on both the display and the dev board, no wiring is necessary.
The display’s parallel 8080 bus is part of the MIPI DBI (Display Bus Interface) specification, which, besides the type B (Intel 8080) variant, also defines a type A (Motorola 6800), and a type C variant that uses an SPI-based interface.
Software-wise, Zephyr has a nice framework for display drivers and an API for the low-level MIPI DBI drivers. However, at the time of starting this project, only a driver for MIPI DBI type C, so the SPI-based mode, was implemented for general platforms.
To use my display on my nRF52 board with Zephyr, I implemented a GPIO-based MIPI DBI driver that uses bit banging for the parallel type A and B interfaces. This makes displays similar to mine work on any platform that has GPIO support.
In Zephyr, GPIO pins are usually defined using a device tree, where each pin is identified by a port and a pin. This means that each pin of the data bus can be on a different port, and must therefore be set individually, which obviously leads to a significant performance penalty. As an optimization, I check whether all pins are located on the same GPIO port, and if so, generate a look-up table at compile-time which is used to translate data bytes to GPIO port patterns. With this, it is possible to set the whole data port in one go, without the need to iterate over the data bus bits, leading to a theoretical 8x speed up compared to the naive implementation.
My MIPI DBI driver was merged upstream in 2571ae8b.
For the higher-level display controller driver, I reused the existing ILI9488 driver with slight modifications.