Pinball: Driving the OLED using the U8G2 Library

In the previous Pinball post, I wrote about getting the OLED going and getting the footprint onto my printed circuit board.  Now I need to make PSoC firmware to drive the display.  I turns out that there are a number of different driver chips out there including at least SSD1306, SH1106, LD7032, SSD1325, and ST7920 that handle multiplexing the columns/rows, managing frame buffers, power management, etc.  To make matters more fun, these chips support I2C, 3&4 wire SPI and a couple of different parallel interfaces (6800, 8080).  I certainly didn’t want to go down the rathole of building up a complete driver library.  But I didn’t have to, as it turns out that that Oliver Kraus built and open-sourced a very nice library that you can get at  This library (and its predecessor u8glib) seem to be in pretty wide use in Arduino and Raspberry Pi.

In order to make the library work with the PSoC I had to do several things

  1. Download it from GitHub (git clone
  2. Created a new PSoC4200M project for the CY8CKIT-044 (which was the devkit that I happened to have sitting next to my computer)
  3. Change the build settings (right click on the project and select building settings) then add the directory in “Additional Include Directories” and include the “u8g2/csrc” directory.
  4. Add the header files to the project by right clicking and selecting “Add->Existing item” so that the project can f
  5. Add the U8G2 C-Files to the project (same as step 4 but add the C files)
  6. Build a schematic which has an I2C (for the display) and a debugging UART.  The I2C is configured as a master with 400kbs data rate.  The UART uses the default configuration.
  7. Assign the pins

Now I am ready to build some firmware that will drive the display.  In order to use the library with a PSoC I need to create two functions for the U8G2 HAL to use as an interface to the PSoC hardware.  You initialize the U8G2 system with a call to the u8x8_Setup function.  In that call you need to provide function pointers too the two HAL functions

  1. The GPIO and Delay Interface
  2. The byte oriented communication interface

This is an example of the setup required:

The GPIO and Delay interface is used by the byte oriented communication functions to read/write the GPIOs and provide delays.  This function provides the underpinnings of a bit-banged I2C, UART, SPI etc.  Because I am only going to use PSoC Hardware to provide the I2C interface I will only respond to the delay messages.  All of the delay functions are implemented as busy wait loops, which I am not a big fan of.  The input to the function is a “message” that is one of a sprawling list of #defines in the file u8x8.h.  I believe that I found all of the possible cases, but I am not sure.

The first message, UX8X8_MSG_GPIO_AND_DELAY_INIT doesnt need to do anything because the GPIOs are configured correctly by the default.

I did not respond to the messages of the form U8X8_MSG_GPIO_X which are the read and write of the GPIOs as I am not going to use the bit-banged interface.

The other function that needs to be provided is the byte-oriented communication function.  This function needs to respond to the messages to start, send, and end communication.  I just mapped those messages onto the PSoC hardware APIs.  While I was trying to understand what was happening with the system I implemented a debugging UART which you can see in the #ifdef DEBUG_UART sections.

You can find all of the source code and files at the IOTEXPERT site on github.

Index Description
Pinball: Newton's Attic Pinball An introduction to the project and the goals
Pinball: Lotsa Blinking LEDs Everyone needs a bunch of LEDs on their Pinball Machine
Pinball: Matrix LEDs (Part 1) Saving PSoC pins by using a matrix scheme
Pinball: Matrix LEDs (Part 2) Solving some problems with the matrix
Pinball: Matrix LEDs Component How to turn the Matrix LED into a component
Pinball: A Switch Matrix Implementing a bunch of switches
Pinball: Switch Matrix Component (Part 1) The switch matrix component implementation
Pinball: Switch Matrix Component (Part 2) The firmware for matrix component
Pinball: Switch Matrix Component (Part 3) Test firmware for the matrix component
Pinball: The Music Player (Part 1) The schematic and symbol for a Music Player component
Pinball: The Music Player (Part 2) The Public API for the Music Player component
Pinball: The Music Player (Part 3) The firmware to make the sweet sweet music
Pinball: The Music Player (Part 4) The test program for the music player
Pinball: The Motors + HBridge Using an Bridge to control DC Motors
Pinball: The Eagle Schematic All of the circuits into an Eagle schematic
Pinball: The Printed Circuit Board 1.0 The first Eagle PCB layout of the printed circuit board
Pinball: The PCB Version 1.0 Fail Problems with the first version of the Eagle PCB layout
Pinball: PCB Layout 1.2 Updates using Eagle Fixing the errors on the first two versions of the Eagle PCB
Pinball: Assemble and Reflow the 1.2 PCB Assembling the Eagle PCB
Pinball: Testing the Eagle PCB Firmware to test the newly built Pinball printed circuit board
Pinball: Debugging the Motor Driver Fixing the motor driver PSoC project
Pinball: Hot-Air Reworking the Accelerometer Solder Using a Hot-Air Rework tool to reflow a QFN
Pinball: Debugging the LM317 Power Supply- A Tale of Getting Lucky Debugging the LM317/LM117 power supply