In chapter 7, we made use of the segmented LCD display on the Wonder Gecko Starter Kit through the use of a pre-built LCD library and driver when designing the user interface for the sprinkler timer. That made things easy for us, and we didn’t really need to dwell on how the driver worked. In this chapter, we will dig into some of those details so that we can connect the EFM32 to any kind of display we choose.
The display we will be using for this chapter is the Adafruit 2.8” 240x320 TFT LCD Capacitive Touch screen, shown below. We will interface with it over SPI for transferring image data and I2C for reading the touch interface. We will learn how to interface with it with our own drivers and build our own simple graphics libraries, as well.
Materials Needed for this Chapter:
Types of Displays
Segmented Display: We have already worked with the segmented LCD display in chapter 7, also known as a character display. In such a display, there are a fixed matrix of LCD segments that are preconfigured in hardware to convey specific information. They are not flexible enough to display an image, but they don’t require many pins on the MCU and are easier to program. For example, the number “9” can be formed on such a display with as few as 6 signals.
Graphics Display: A graphics display has a matrix of pixels, each of which are individually addressable. Therefore, in order to display the number “9”, it can require many more pixels than the segmented display. The benefit of a graphic display is that the letter “9” can be in any font we choose, and better yet, we can display any shapes we choose. The drawback to a graphical display is that it takes an enormous number of signals to drive all of those pixels. For the display used in this chapter, which has a resolution of 240 pixels wide by 320 pixels tall, there are 76,800 individually-addressable pixels, and each of those are made up of red, green, and blue components for each pixel.
In order to cut down on the number of signals required to drive such a display, each pixel is driven one at a time in a column-and-row scan technique. This scanning only requires 240 + 320 wires for our chosen display, which are toggled on or off many times per second, even for a static image. The pixels do not hold their color information for very long, and therefore they require periodic refreshes.
Note that a new “Memory LCD” described in Silicon Labs application note AN0048 couples a memory device within each pixel so that constant refreshing is not necessary, reducing power consumption as well.
Graphical display screens have many different technologies, from passive-matrix Liquid Crystal Display (LCD) or active-matrix Thin Film Transistor (TFT) LCD, Light Emitting Diode (LED), or Organic LED (OLED). Display technology is not the focus of this chapter. No matter which technology you choose, you will still need to understand the topics of this chapter in order to display your images.
Components of a Display
A display is a layered device, with each part customizable by the manufacturer. The display is constructed on top of a circuit board which houses the connector and any controller chips that are necessary. The backlight is located on top of the circuit board, with the pixel matrix sitting on top of the backlight. The touch sensor is optional and is located at the top of the stackup.
LCD Pixel Matrix
The LCD pixel matrix is the heart of the display. This part is responsible for displaying the image and, in the case of LCD displays, it will either allow or prevent light from a backlight to pass through. In the case of LED displays, the pixel matrix produces the light and forms the image in one step. No matter the process, the pixel matrix is comprised of an array of pixels in height and width of a certain color depth that make up the display. For the display used in this chapter, the color depth is 18 bits, consisting of 6 bits each for the red/blue/green components of a pixel. That means that the information required to paint the screen one time is 240 bits wide x 320 bits tall x 18 bits of color = 172,800 bytes. That’s a lot of data, and it is more data than we can hold in the RAM of the Wonder Gecko MCU. Therefore, it will require some intelligent code to drive the display or an external memory buffer to store the image data.
The backlight is necessary for TFT LCD displays to allow the display to be seen. Without a backlight, a color TFT LCD will show no image. A monochrome LCD is a little different, since the segments can be seen if they are in the “on” state. The brightness of an LCD screen is sometimes controlled by applying a Pulse Width Modulated (PWM) signal to a pin (or pins) that controls the LED backlight. This is exactly what we have already done in the last chapter to dim an LED.
Display Driver Chip
A display driver chip is used to drive 76,800 signals by rotating through all horizontal and vertical scan lines many times per second. This component is an optional component of the display, and if it is present, it dramatically reduces work for the MCU to display (and continue to display) an image on the screen.
A frame buffer is a block of RAM that holds all of the color information for every pixel (172 kB for this display) that is used to paint a single image (or “frame”) to the display. This buffer is required to exist somewhere in the system because it is used by the display driver chip to refresh the LCD image many times per second.
A touch interface is an optional component and will often have its own control chip or control signals that are separate from the display driver chip.
A resistive touch screen is pressure sensitive. It requires that your finger (or stylus) makes contact with the screen and causes a tiny grid of precisely controlled resistance wires to touch each other, and then measures the resistance to calculate the position. The resistive touch screen requires four signals to interface the MCU, two of which must be fed into an Analog to Digital Comparator (ADC) in order to read the touches. The Wonder Gecko has several ADC inputs that can be used for this purpose. Resistive touch screens may require calibration by the user to perform accurately.
A capacitive touch screen requires no physical contact between the user and the sensor. Therefore, the sensor can be placed beneath hardened glass or plastic. A valid touch is formed by the change in capacitance measured on the sensor. A human finger can change the capacitance of this sensor, whereas a plastic stylus will not produce a change in capacitance. The capacitive touch screen used in this chapter uses a controller that communicates via the I2C interface.
Graphic Display Architecture
The type of architecture used in our display (and system) has a huge impact on how we will write our software code, as well as how well our display will perform. You cannot assume that any model of MCU can sufficiently drive any type of display. You must be aware of the architecture details and MCU pinout so that you can determine the best type of display for your needs.
In a general sense, all display architectures require the above control blocks. The display contains a number of scan lines (depending on the resolution) and an image driver that must continually feed the scan control circuitry with pixel data, even for a static image. The pixel control allows light to pass for an instant, and then the pixel goes dark again. If the scan control circuitry were stopped, the display would turn dark, as all pixels would be turned off. Therefore, the image driver needs a frame buffer of memory somewhere in the system to fetch the pixel data that is needed for every scan. The application fills the frame buffer as new drawing operations change what is to be displayed on the screen.
Displays without an Integrated Driver Chip (RGB Interface)
In the RGB interface mode, the MCU acts as the image driver. This means that it must constantly drive data to the display, refreshing all 320 x 240 pixels many times per second. You can imagine the amount of work that would require of your MCU. If the frame buffer is too big to fit in the MCU RAM, an external memory chip must be used. The frame buffer can be attached to the MCU via serial interfaces such as I2C or SPI for static images such as device menus, but must utilize a parallel interface in order to keep up with the demands of full motion video. The External Bus Interface (EBI) can be used with external memory for maximum speed and ease of use, as long as your particular model of EFM32 supports it. EBI extends the RAM of your EFM32 and allows you to address external memory as if it resides within the RAM address space of the EFM32 itself.
Displays with an Integrated Driver Chip
When a display has an integrated device driver chip and frame buffer (such as the Ilitek ILI9341 used in this chapter), the MCU doesn’t have to perform all of the constant refreshing of the display; it only sends data to the driver chip when the image changes. This enables the MCU to offload all of that work to stay focused on the application at hand rather than driving the display.
These driver chips usually offer both parallel and serial interfaces to receive image data from the MCU. Parallel interfaces are required if the display will be used for full-motion video and require 8 or more data interface pins. Serial interfaces can be used for static images like device menus and only require 3 or 4 interface data pins.
Fully Integrated Application Interface Displays
There are displays available on the market (such as the EVE series from FTDI) which go well beyond a display driver chip. They contain the ability to create graphical shapes such as lines, rectangles, and circles, as well as device controls such as windows, sliders, and buttons. These displays can even offer an integrated touch controller and audio capabilities. The displays communicate over I2C or SPI, and the data that is sent is similar to a software Application Programming Interface (API). The specs of such displays define the commands that the controller chip accepts, and the application software simply communicates each graphic primitive one-by-one to the display to paint the appropriate picture on the screen. These types of displays can be easier to program, but are not the focus of this chapter.
Since graphic displays are complex devices, the code that runs them should be broken up into parts that deal with only one part of the problem. This is known as a software stack.
At the top of the stack is the application software. Application software is focused on providing a solution to the end user, such as the content of menus, fetching images from flash storage, responding to user input, and generally deciding what to do next. Application software should not have to be bogged down with the simple task of how to write a snippet of text to the screen, or the exact details of how to display an image. These things should be handled further down the stack to keep your application code simple.
In order for your application code to stay focused on its mission, your graphics library should provide useful methods to do common things, such as paint the screen with a color, display text, create lines or shapes, and display graphic images. We will learn how to build a very simple graphics library of our own as part of this chapter.
Depending on the graphics library complexity, it may even create a full windowing capability with sliders or popups and add all of the comforts of a modern computer interface to your embedded application, all within the limited RAM available in an MCU. Silicon Labs provides the Segger emWin graphics library as part of the Simplicity Studio installation. We will introduce the emWin library at the end of this chapter.
Software Device Driver
At the bottom of the software stack, the device driver is the necessary code that customizes your graphics library for your particular display device architecture and physical hardware connection. (Note that a software device driver is not the same thing as the device driver chip on the physical display.) Graphics libraries are flexible, and can be adapted to many different display architectures, but they need to be configured for your display architecture and MCU. The device driver provides this customization, providing the display’s resolution and color depth, mapping the data bus for the display to GPIO pins on your MCU and setting up the memory for the frame buffer (if applicable).
See AN0047 Interfacing Graphical Displays and AN0048 Energy Optimized Display
Application for more in depth technical information on using displays with the EFM32 family.
In the next section, we will connect the display to the Wonder Gecko and start drawing some pictures.