In part one of this series we explored how to generate resources for the SSD1322 OLED driver chip from Solomon Systech. In this post we’ll dive deeper into the inner workings of the SSD1322 OLED driver chip. We’ll also utilize the resources we generated in the previous post in a simple example. We’ll use a display manufactured by NewHaven Display to test our code. However our code should work for other displays based on the SSD1322. Let’s dive in!

Inside The SSD1322 Driver Chip

The SSD1322 driver chip controls the OLED pixels using segment and common drivers which are basically transistors switches.

OLED segment and common drivers

OLED segment and common drivers

All OLED pixels on the same row share a common cathode and all the OLED pixels on the same column share a segment driver. Hence the OLED driver scans the commons sequentially, row by row while manipulating (turning on and off) the segment drivers to show the appropriate image for the row. By scanning the rows at a fast pace our eyes are fooled into believing a static image resides on the screen.

Each oled pixel is modelled as an LED in parallel with a parasitic capacitance, requiring four phases/steps to turn on. First the previous data is cleared, this is because the parasitic capacitance could still hold a charge (data) from being previously turned on. The length of time required for this phase depends on the size of the parasitic capacitance. Next the pixel is pre-charged to a certain voltage level, Vp. In phase 3 the pixel is driven to the final driving voltage via a second pre-charge. Finally a constant current is applied to the pixel.

After going through this cycle, the chip goes back to phase 1 and repeats the cycle for the next row of image data, hence running continuously to refresh data on the screen. We can better visualize this process from the image below which is taken from the datasheet. In summary the segment voltage turns the pixel on or off while the common voltage selects the row to display the segment  data.

OLED segment and common driving waveforms

OLED segment and common driving waveforms

Varying the pulse width of the segment voltage enables the grayscale control of an OLED pixel. We can see this from the image below.

OLED pixel turn-on phases and grayscale control

OLED pixel turn-on phases and grayscale control

Driving The Driver

Let’s write some code to control the SSD1322 driver chip. We’ll go by the sequence described in an earlier post.

Understanding the hardware interface

The SSD1322 displays data directly from GDDRAM. Our goal here is to understand how the SSD1322 represents the image data we send it. Every pixel requires 4 bits of data and can display 16 grayscale levels. As such each byte sent will contain two pixels.

OLED data bus to RAM mapping

OLED data bus to RAM mapping

Each column address corresponds to four pixels as shown in the address map. In view of this we’ll have to send two bytes for each column address. We’ll configure the address increment mode to horizontal address increment.

We’ll also have to set the column start and end addresses as well as the row start and end addresses. Hence the GDDRAM address is automatically increased by one to access the next location after writing 4 pixels of data. This movement is made along our column and row start and end addresses.

OLED RAM in horizontal address increment mode

OLED RAM in horizontal address increment mode

As for a physical interface, the SSD1322 gives us a number of options including serial and parallel options. We’ll go with the 4-Wire SPI serial version for convenience and speed. By examining the datasheet we see that the SSD1322 supports SPI mode zero. Therefore we’ll configure our MCU for SPI mode zero.

SPI timing diagram for the SSD1322 driver chip

SPI timing diagram

A problem of character spacing

Once we’ve initialized our display, we can start displaying data. We’ll add functions for drawing bitmaps and outputting text.

But wait! The structure of the SSD1322 memory forces an update of 4 pixels at once. This is because each column address corresponds to 4 pixels. This will make displaying text a bit difficult because the width of a character may not align on a 4 pixel boundary. To circumvent such problems with text and images we’ll pad the resources with dummy data to ensure they align on a 4 pixel boundary. However, glyphs may have different widths of data padded which creates weird character spacing. The solution requires the use of a frame buffer.

How does a frame buffer solve this issue? The answer lies in a little more flexibility. A frame buffer provides a temporary space for drawing and manipulating data before finally outputting them to the SSD1322. We’ll provide even spacing by doing some bit shifting on the incoming character to be displayed based on the amount of padding applied to the previous character.

So before we output a character on the screen we’ll look at the padding of the previous character. A previous padding of one gives us a pixel of spacing already. Hence we’ll shift the incoming character by one pixel to the right to provide a spacing of two pixels between the previous and incoming characters. If a character is not padded we can simply manipulate the x coordinate to create spacing. We’ll take care of other scenarios by making them similar to these two base cases. Note that applying a one pixel shift to the right adds an extra pad to the incoming data.

Creating the header file

As usual our header file will contain definitions, hardware abstraction macros, data structures and function prototypes. I discussed the data structures required for the SSD1322 driver in my previous post. An excerpt from the header file shows the hardware abstraction macros and some SSD1322 commands.

Creating the source file

Now let’s write some code. Let’s start by writing a function to talk to the SSD1322.

We’ll initialize the display with the “ssd1322_initialize” function. This function is based on the application note provided by NewHaven Display. There is a link to the NewHaven Display app note at the end of the post.

Let’s look at how to get interesting things unto the display. We’ll start by creating a function to display resources like text and images into a frame buffer, let’s call this function “ssd1322_put_resource_fb”. This function tries to maintain a spacing of 2 pixels while displaying text.

From here we can make various calls to “ssd13322_put_resource_fb” to display text and images. Displaying a bitmap is straightforward, we just have to call “ssd1322_put_resource_fb” and pass the bitmap info. Bitmaps don’t require any spacing unlike text and hence any padded data is assumed as part of the bitmap.

Displaying text is also fairly straightforward from here. All we have to do is unpack the glyph metadata from the font table and make a call to “ssd1322_put_resource_fb”.

Now that we can display characters, handling strings should be a breeze. We’ll create a function to display text based on our character displaying function.

So far we can put text and images into a frame buffer but we need a function to send the data to the SSD1322. Finally let’s create the “ssd1322_display_fb” function to dump the contents of the frame buffer to the display.

Displaying Text And Images

To display text and images we’ll first have to generate C code for the text and images we want to display. I’ve put together a python script for converting resource files into source code and a tutorial to go along with it. After generating code for the text and images, we’ll have to add the resources to our microcontroller project. We can create a source code folder for our driver code and resources. We just have to remember to update the include paths when building the project.

Let’s go ahead and include the header files of the resources in our “main.c” file.

We’ll create a frame buffer by allocating 8192 bytes of memory, we need this much because of the display size (256 x 64 x 4 bits).

Now let’s initialize the SSD1322 driver and delay routines.

Finally we’ll go ahead and make calls to SSD1322 driver functions to display images and text.

The image below shows how the bitmaps displayed appear on screen.

Displaying bitmaps on the SSD1322 OLED display

Displaying bitmaps on the SSD1322 OLED display

The banner image of this post shows how displayed text looks like. All the code for this project is available on Github.

References

This work is based on the example code provided by NewHaven Display. You can check it out using the link below: https://www.newhavendisplay.com/appnotes/excode/txt/OLED/OLED_25664.txt