Close

Split ugfx, platform-specific driver, and project config

A project log for using uGFX in Arduino

uGFX was written for use with makefiles. Using it in arduino is possible with minimal effort, though. Here's how.

christophChristoph 11/24/2015 at 10:010 Comments

ugfx library:

Again I started with a bare ugfx clone, with an empty "ugfx.h" file in the base directory:

~/Arduino/libraries/ugfx/
├── src/...
├── other folders/
├── ugfx.h (this is not strictly necessary, but will be useful later)
├── gfx.h
├── other headers
ugfx-arduino library:

Another library is used to add ugfx to the compiler include path, without adding all headers to our sketch:

~/Arduino/libraries/ugfx-arduino/
.
├── ugfx-arduino.c
└── ugfx-arduino.h

ugfx-arduino.h:

#ifndef UGFX_ARDUINO_H
#define UGFX_ARDUINO_H

#include <ugfx.h> // look for ugfx library
#include <gfx.h>  // and use gfx.h in that directory

#endif // UGFX_ARDUINO_H

ugfx-arduino.c:

#include "src/gfx_mk.c" 

This includes all source code we need from ugfx.

ugfx-SSD1331-arduinomega library:

A driver library should be specific to a display connected to some arduino-compatible board. However, it should not specify which pins are used, because that is specific to the project. So I started with all files from ugfx/boards/base/ArduinoTinyScreen and modified them a bit. The main modifications:

The resulting structure:

~/Arduino/libraries/ugfx-SSD1331-arduinomega/
.
├── board_SSD1331.cpp
├── board_SSD1331.h
├── driver_SSD1331.c
├── gdisp_lld_config.h
├── SSD1331.h
└── ugfx-SSD1331-arduinomega.h

board_SSD1331.cpp was modified a bit to include a header for the pin definitions:

#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>

#include "board_SSD1331.h"

#define LCD_BOARD_ID		0		// 0 or 1 - set by the position of a resistor near SX1505 (see schematic and board design)

// GPIO Pins
#include "ssd1331_gpio_pins.h"
/*
#define GPIO_DC				0x01
#define GPIO_CS				0x02
#define GPIO_RES			0x08
#define GPIO_BTN1			0x10
#define GPIO_BTN2			0x20
#define GPIO_BTN3			0x40
#define GPIO_BTN4			0x80
*/
#define GPIO_CMD_START		~(GPIO_CS|GPIO_DC)
#define GPIO_DATA_START		~GPIO_CS
#define GPIO_TRANSFER_END	GPIO_CS

... more code
This header is not part of the driver library, but will be part of our project config.

ArduinoTinyScreen-ugfx-config library:

Unfortunately, the project config library is necessary. I was hoping that I could put the ugfx config in the sketch's base directory, but that is not added to the compiler's include path. So we need a library because we need the include path:

~/Arduino/libraries/ArduinoTinyScreen-ugfx-config/
.
├── ArduinoTinyScreen-ugfx-config.h
├── gfxconf.h
└── ssd1331_gpio_pins.h
ArduinoTinyScreen-ugfx-config is empty, but it doesn't have to be. It is only used to identify this library as the one to be included in our sketch.

gfxconf.h configures ugfx, and ssd1331_gpio_pins.h is the one included by ugfx-SSD1331-arduinomega. It contains the pin definitions commented out above:

#ifndef SSD1331_GPIO_PINS_H
#define SSD1331_GPIO_PINS_H

#define GPIO_DC        0x01
#define GPIO_CS       0x02
#define GPIO_RES      0x08
#define GPIO_BTN1     0x10
#define GPIO_BTN2     0x20
#define GPIO_BTN3     0x40
#define GPIO_BTN4     0x80

#endif // SSD1331_GPIO_PINS_H
Sketch

Now the sketch starts like this:

#include <ArduinoTinyScreen-ugfx-config.h>
#include <ugfx-SSD1331-arduinomega.h>
#include <ugfx-arduino.h>
//#include <gfx.h>
void setup() {
  coord_t		width, height;
  coord_t		i, j;

  pinMode(13, OUTPUT);

  // Initialize and clear the display
  gfxInit();

... more code

I wrote earlier that ArduinoTinyScreen-ugfx-config.h doesn't have to be empty, and now we know what we can put in there: The two other ugfx-related includes, so we just need to include the project-specific config header.

Summary

It's possible to separate the project-specific code from ugfx, so you can have just on ugfx library instead of one full ugfx copy for each sketch. By creating display-platform libraries it's easy to add an arduino-compatible display driver to your installation without having to modify the driver each time you create a new project, because all project-dependent code can be put into a library for the actual project.

What's next?

Using the "tag" mechanism for libraries it should be possible to have different versions of ugfx, like so:

~/Arduino/libraries/ugfx-2.4/
├── src/...
├── other folders/
├── ugfx-2.4.h
├── gfx.h
├── other headers

The same would be done for ugfx-arduino and then the project-specifc library can include a specific version of ugfx.

Discussions