Using STM32F7 LCD Controller in Linux Print

 

This application note explains how to use the STM32F7 on-chip LCD controller in Linux.

All software tests documented below were performed on the Emcraft STM32F7 System-On-Module (SOM), plugged into a special development baseboard referred to as the "IOT-BSB-EXT baseboard". That baseboard provides various I/O interfaces including connectors to yet another board referred to as the "IOT-LCD module". The IOT-LCD module hosts a 4.3" 480 x 272 LCD with a touch panel controlled by an I2C device. Note that the IOT-BSB-EXT is a special baseboard developed by Emcraft in a certain project and differs from the SOM-BSB-EXT baseboard included with the STM32F7 SOM Starter Kit. Use the IOT-BSB-EXT and IOT-LCD schematics to understand the hardware connections between the STM32F7 LCD interface and the LCD module and touch panel on the IOT-LCD board.

The Linux framebuffer driver for the STM32F7 LCD controller is linux/drivers/video/stm32f4_lcdfb.c. To enable the LCD support in the kernel, you must enable the CONFIG_FB_STM32F4 build time option in the kernel configuration. To do so, start the kernel configuration GUI (make kmenuconfig from the project directory) and proceed to enable the following items: Device Drivers -> Graphics support -> Support for framebuffer devices -> STM32F4x9 LTDC controller support:

Once you have enabled CONFIG_FB_STM32F4, go to System Type -> STM32 I/O interfaces and enable STM32F4x9 LTDC framebuffer (CONFIG_STM32_FB).

The CONFIG_STM32_FB option is responsible for enabling kernel code that registers a platform device for the STM32F7 LCD controller with the framebuffer driver. That platform-specific code resides in linux/arch/arm/mach-stm32/fb.c. If you would like to port the framebuffer to a custom LCD, you will need to update that file to provide the framebuffer driver with configuration parameters appropriate for your LCD.

There must be a device node in the target root file system for the framebuffer to allow accessing it using standard Linux interfaces. Add the following line into your <project>.initramfs file to create a device node for the LCD interface:

nod /dev/fb0 0600 0 0 c 29 0

When you boot the newly installed Linux image on the target, there will be the following message in the kernel bootstrap print-out indicating that the framebuffer driver is available and has registered a platform device for the on-chip LCD controller:

...
fb0: fb device registered successfully
...

The next question is what you can do with the framebuffer from Linux userspace code in order to display something on an attached LCD. At a lowest level, the framebuffer exposes a device file /dev/fbN for the LCD interface it is responsible for. Typically, as is the case for the STM32F7, the framebuffer services a single LCD interface so N is 0 and the device file is /dev/fb0. Through that file, userspace applications can perform reads/writes to directly access the LCD framebuffer - i.e. the pixel values being displayed on the screen. Additional APIs are available via ioctl calls on that file, that provide functionality to determine parameters of the LCD (width, height, pixel-depth, etc) as well as to perform some other operations.

As an example, this is a demo project (lcdtest.tgz) that illustrates how to display a static test image on the LCD.

Note: This demo project was validated in context of Release 1.13.0. If you are using a different release, some porting changes may be needed.

When you unpack the tarball (lcdtest.tgz) in the projects/ directory, the userspace application that accesses the LCD is projects/lcdtest/app/lcdtest.c. You will see from the sources that the application uses standard POSIX APIs to open /dev/fd0, then calls appropriate ioctl commands to determine the LCD geometry, then maps the LCD memory buffer into the application address space using mmap and then renders the test image onto the LCD by writing directly into the LCD framebuffer. As mentioned, the application makes use of standard Linux APIs so the same code should work on any Linux system.

To build the project, simply go to projects/lcdtest and run make. The resultant bootable image will be lcdtest.uImage. When you have booted lcdtest.uImage to the target, call the application as follows in order to render the test image on the LCD:

~ # ./lcdtest -c
480x272, 32bpp
The framebuffer can be accessed at the address 0xc0f00000
Press Ctrl-C to exit
^C ~ #

Here is what the image will look like on the LCD:

Of course, in real-life designs developing low-level code that renders graphics directly through the framebuffer is not practical. Typically, developers use ready GUI frameworks, such as for instance the Qt GUI application software, to implement a feature-rich GUI.