SPI TFT (st7735r)


The st7735r is a very common SPI TFT display controller.

It is often found on 16-bit color displays up to 128x160 pixels. These displays can easily be found for under five US dollars and are extremely simple to wire up.

The most typical interface is seven wires:


  • VCC
  • GND


  • MOSI (Master-Out-Slave-In)
  • SCK (Serial Clock)


  • CS (Chip Select)
  • DC (Data / Command Selector)
  • RST (Reset)

Most displays also feature additional pins for backlight - these are usually just connected to one or more LEDs.

To use these displays, we provide the st7735r driver library, which integrates with the Graphics Framework.


As mentioned above, the wiring for these displays is fairly straightforward.

We start by hooking up the power (VCC / GND) and SPI bus (MOSI / SCK). Then we can hook 'CS', 'DC' and 'RST' to some digital outputs. If some backlight is present, we can hook up the backlight power to a digital output or even a PWM output to control the intensity of the backlight. To avoid frying the backlight LEDs in your display, place a small current-limiting resistor (between 100 and 1000 ohm) in series with the backlight.

Using the library

To use the display driver, we must first add it to our dependencies in dfe.conf:

# ...
  - st7735r


Next, we need to initialize the display so we can use it with the Graphics Framework.

The easy way to do this is to simply declare our display in our substrate.

With substrate

We can declare our display in our substrate as shown below:

# 80x160 TFT Display (with X offset of 24)
uses :st7735r_gfx, name: 'dsp0', width: 80, height: 160, x_off: 24, cs_pin: 5, dc_pin: 6, rst_pin: 7

However, because many displays have very similar configurations, we can also just use a standard profile:

# Generic 128x160 TFT Display
uses :st7735r_gfx, name: 'dsp0', profile: :gen128x160, cs_pin: 5, dc_pin: 6, rst_pin: 7

The table below shows available profiles:

Profile Display format Extras
:gen80x160 80x160 X Offset: 24
:gen128x160 128x64 N/A

We can even mix a profile with custom options if needed. For example, some displays ALMOST match these generic settings, maybe requiring only a small adjustment like the X offset:

# Generic 80x160 TFT Display (with X offset = 32)
uses :st7735r_gfx, name: 'dsp0', profile: :gen80x160, x_off: 32, cs_pin: 5, dc_pin: 6, rst_pin: 7

This will create a struct gfx_dsp *dsp0; that we can use right away.

Manual initialization (without substrate)

For those who prefer to go without the substrate, we can still initialize the display manually:

 1 #include <st7735r/st7735r.h>
 2 #include <gfx/dsp.h>
 3 #include <gfx/gfx.h>
 5 // TFT Display Driver
 6 struct st7735r dsp0_drv;
 8 // GFX Interface
 9 struct gfx_dsp dsp0_data;
10 struct gfx_dsp *dsp0;
12 void init()
13 {
14     // ...
16     // Display Params
17     uint8_t rst_pin = 7;
18     uint8_t dc_pin = 6;
19     uint8_t cs_pin = 5;
20     uint8_t width = 128;
21     uint8_t height = 160;
22     uint8_t x_off = 0;
23     uint8_t y_off = 0;
25     // Initialize st7735r driver
26     st7735r_init(&dsp0_drv, rst_pin, dc_pin, cs_pin, width, height, x_off, y_off);
28     // Initialize GFX interface
29     dsp0 = &dsp0_data;
30     gfx_dsp_init(dsp0, &dsp0_drv);
32     // ...
33 }


Once the display is initialized and we have a struct gfx_dsp *dsp0;, we can start using the Graphics Framework to actually do stuff with the display.