SPKDisplay - A mbed display class and processing imaging tools for 128x64 OLEDs using the SSD1305 driver, connected via SPI. This variant drives a Unigraphics oled on the same driver but in page mode. Includes a simple 5x7 ascii font

Dependents:   univision_oled

Fork of spk_oled_ssd1305 by Toby Harris

OLED driver and demo for Univision oled display 128x64.

/media/uploads/pegcjs/_scaled_20130128_133126.jpg

Modified Toby Harris' code to run page mode addressing in 4 wire SPI on the Univision UG-2864HSWEG01 128X64 unit - often found for sale on ebay. That's where I got mine anyhow.

Wiring this was fairly straightforward but you really do have to ground all the unused pins EXCEPT for number 8 to get it to work.

Here's the layout - I made a little carrier using a 2x8 connector and a couple of headers mounted on a small piece of stripboard. You can see all the wire links that are used to ground the unused pins. It was pretty awkward setting the display to run in 4 wire spi - had to desolder and resolder three smd o ohm links on the back o fhte pcb - ended up using a microscope to see them.

/media/uploads/pegcjs/_scaled_layout.jpg

Here is the output of the demo code.

/media/uploads/pegcjs/_scaled_itworks.jpg.jpg

In page mode the display is effectively divided up into 8 horizontal strips, each 8 pixels high so lends itself nicley to displaying text in a 5x7 font. I've included the 5x7 lcd font in the code below.

Code

Import programunivision_oled

driver demo for univision oled dispaly

#include "mbed.h"
#include "4spi_oled_ssd1305.h"

/* re writtten to cope with teh ssd1306 driven oled UG-2864HSWEG01 from univision
wiring for test circuit
OLED pins -FUNCTION-------MBED PINns
1 ----3.3V--- Vout (p40)
2 ----0.0V--- GND (p1)
3 ----------- GND (p1)
4 ----------- GND (p1)
5 ----------- GND (p1)
6 ----------- GND (p1)
7 ----------- GND (p1)
8 ----------- N/C
9 ----D1---- mosi (p5)
10 ---D0------sck(p7)
11 ----------- GND (p1)
12 ----------- GND (p1)
13 ---DC------ p10
14 ---RES----- p9
15 ---CS------ p8
*/



DigitalOut myled(LED1);

// Create object and load font
//SPKDisplay( mosiPin, clkPin,  csPin,  dcPin, resPin, Serial *debugSerial)
SPKDisplay screen(p5, p7, p8, p10, p9);
int main()
{
    char msg[22];
    sprintf(msg,"                      ");
//           01234567890abcdefghij

    int i=0;
    while(1==1) {
        myled=1;
        // nice logo output
        screen.welcome();
        wait(3);

        wait(2);
        for(i=0; i<5; i++) {
            myled=0;
            screen.inverse();
            wait(1);
            screen.normal();
            myled=1;
            wait(1);
        }

        screen.fontdemo();
        myled=0;
        wait(5);
        screen.clearBuffer();
        screen.sendBuffer();
        myled=1;
        wait(0.5);
        myled=0;
        wait(0.5);

        for(i=0; i<8; i++) {
            sprintf(msg,"HELLO WORLD %d",i);
            screen.textToBuffer(msg, i);
            screen.sendBuffer();
            screen.clearBuffer();
            myled=1;
            wait(1);
        }
    }


}

4spi_oled_ssd1305.cpp

Committer:
pegcjs
Date:
2013-01-29
Revision:
5:6d2aded0cf41

File content as of revision 5:6d2aded0cf41:

// OLED display using SSD1305 driver
// A library by *spark audio-visual

/* Copyright (c) 2011 Toby Harris, MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "4spi_oled_ssd1305.h"
#include "mbed.h"

// re written to handle page mode on ssd1305 128x64 unit CJS 2013

// nice logo - note the typo....
static unsigned char logo_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x04, 0x06,
0x06, 0xFC, 0xF8, 0x00, 0x04, 0x06, 0x06, 0xFC, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00,
0x04, 0x06, 0x06, 0x04, 0xFC, 0x60, 0x00, 0x60, 0xF8, 0x6C, 0x64, 0x66, 0x66, 0x64, 0x64, 0x78,
0x60, 0x00, 0x60, 0xFC, 0x04, 0x06, 0x06, 0x04, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00,
0x00, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00,
0x02, 0x06, 0x06, 0x02, 0x03, 0x00, 0x00, 0x00, 0x01, 0x03, 0x02, 0x06, 0x06, 0x06, 0x02, 0x02,
0x02, 0x00, 0x00, 0x03, 0x02, 0x06, 0x06, 0x02, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0xF0, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x30, 0x20, 0x20, 0xE0, 0x80, 0x00, 0x00, 0x00,
0x80, 0xE0, 0x20, 0x30, 0x30, 0x20, 0x20, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xC0, 0x60, 0x20, 0x30, 0x30, 0x20, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x40, 0x60, 0x20, 0x30, 0x30, 0x30, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00,
0x80, 0xE0, 0x20, 0x20, 0x30, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xFF, 0xFF,
0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xB0, 0x98, 0x8C, 0x87, 0x81, 0x00, 0x00, 0x00,
0x01, 0x87, 0x84, 0x8C, 0x8C, 0x84, 0xC0, 0x7F, 0x0E, 0x00, 0x00, 0x00, 0x81, 0xC3, 0x34, 0x00,
0x10, 0x34, 0xC3, 0x80, 0x00, 0x00, 0x0E, 0x7F, 0x80, 0x84, 0x86, 0x86, 0x84, 0xFC, 0x30, 0x00,
0x00, 0x30, 0x38, 0x32, 0x31, 0x30, 0x30, 0xFF, 0xFF, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x3F,
0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
0x80, 0x83, 0x82, 0x86, 0x84, 0x84, 0x84, 0xF8, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x0F, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


static unsigned char font[]= {
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
    0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
    0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
    0x18, 0x3C, 0x7E, 0x3C, 0x18,
    0x1C, 0x57, 0x7D, 0x57, 0x1C,
    0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
    0x00, 0x18, 0x3C, 0x18, 0x00,
    0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
    0x00, 0x18, 0x24, 0x18, 0x00,
    0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
    0x30, 0x48, 0x3A, 0x06, 0x0E,
    0x26, 0x29, 0x79, 0x29, 0x26,
    0x40, 0x7F, 0x05, 0x05, 0x07,
    0x40, 0x7F, 0x05, 0x25, 0x3F,
    0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
    0x7F, 0x3E, 0x1C, 0x1C, 0x08,
    0x08, 0x1C, 0x1C, 0x3E, 0x7F,
    0x14, 0x22, 0x7F, 0x22, 0x14,
    0x5F, 0x5F, 0x00, 0x5F, 0x5F,
    0x06, 0x09, 0x7F, 0x01, 0x7F,
    0x00, 0x66, 0x89, 0x95, 0x6A,
    0x60, 0x60, 0x60, 0x60, 0x60,
    0x94, 0xA2, 0xFF, 0xA2, 0x94,
    0x08, 0x04, 0x7E, 0x04, 0x08,
    0x10, 0x20, 0x7E, 0x20, 0x10,
    0x08, 0x08, 0x2A, 0x1C, 0x08,
    0x08, 0x1C, 0x2A, 0x08, 0x08,
    0x1E, 0x10, 0x10, 0x10, 0x10,
    0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
    0x30, 0x38, 0x3E, 0x38, 0x30,
    0x06, 0x0E, 0x3E, 0x0E, 0x06,
    0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x5F, 0x00, 0x00,
    0x00, 0x07, 0x00, 0x07, 0x00,
    0x14, 0x7F, 0x14, 0x7F, 0x14,
    0x24, 0x2A, 0x7F, 0x2A, 0x12,
    0x23, 0x13, 0x08, 0x64, 0x62,
    0x36, 0x49, 0x56, 0x20, 0x50,
    0x00, 0x08, 0x07, 0x03, 0x00,
    0x00, 0x1C, 0x22, 0x41, 0x00,
    0x00, 0x41, 0x22, 0x1C, 0x00,
    0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
    0x08, 0x08, 0x3E, 0x08, 0x08,
    0x00, 0x80, 0x70, 0x30, 0x00,
    0x08, 0x08, 0x08, 0x08, 0x08,
    0x00, 0x00, 0x60, 0x60, 0x00,
    0x20, 0x10, 0x08, 0x04, 0x02,
    0x3E, 0x51, 0x49, 0x45, 0x3E,
    0x00, 0x42, 0x7F, 0x40, 0x00,
    0x72, 0x49, 0x49, 0x49, 0x46,
    0x21, 0x41, 0x49, 0x4D, 0x33,
    0x18, 0x14, 0x12, 0x7F, 0x10,
    0x27, 0x45, 0x45, 0x45, 0x39,
    0x3C, 0x4A, 0x49, 0x49, 0x31,
    0x41, 0x21, 0x11, 0x09, 0x07,
    0x36, 0x49, 0x49, 0x49, 0x36,
    0x46, 0x49, 0x49, 0x29, 0x1E,
    0x00, 0x00, 0x14, 0x00, 0x00,
    0x00, 0x40, 0x34, 0x00, 0x00,
    0x00, 0x08, 0x14, 0x22, 0x41,
    0x14, 0x14, 0x14, 0x14, 0x14,
    0x00, 0x41, 0x22, 0x14, 0x08,
    0x02, 0x01, 0x59, 0x09, 0x06,
    0x3E, 0x41, 0x5D, 0x59, 0x4E,
    0x7C, 0x12, 0x11, 0x12, 0x7C,
    0x7F, 0x49, 0x49, 0x49, 0x36,
    0x3E, 0x41, 0x41, 0x41, 0x22,
    0x7F, 0x41, 0x41, 0x41, 0x3E,
    0x7F, 0x49, 0x49, 0x49, 0x41,
    0x7F, 0x09, 0x09, 0x09, 0x01,
    0x3E, 0x41, 0x41, 0x51, 0x73,
    0x7F, 0x08, 0x08, 0x08, 0x7F,
    0x00, 0x41, 0x7F, 0x41, 0x00,
    0x20, 0x40, 0x41, 0x3F, 0x01,
    0x7F, 0x08, 0x14, 0x22, 0x41,
    0x7F, 0x40, 0x40, 0x40, 0x40,
    0x7F, 0x02, 0x1C, 0x02, 0x7F,
    0x7F, 0x04, 0x08, 0x10, 0x7F,
    0x3E, 0x41, 0x41, 0x41, 0x3E,
    0x7F, 0x09, 0x09, 0x09, 0x06,
    0x3E, 0x41, 0x51, 0x21, 0x5E,
    0x7F, 0x09, 0x19, 0x29, 0x46,
    0x26, 0x49, 0x49, 0x49, 0x32,
    0x03, 0x01, 0x7F, 0x01, 0x03,
    0x3F, 0x40, 0x40, 0x40, 0x3F,
    0x1F, 0x20, 0x40, 0x20, 0x1F,
    0x3F, 0x40, 0x38, 0x40, 0x3F,
    0x63, 0x14, 0x08, 0x14, 0x63,
    0x03, 0x04, 0x78, 0x04, 0x03,
    0x61, 0x59, 0x49, 0x4D, 0x43,
    0x00, 0x7F, 0x41, 0x41, 0x41,
    0x02, 0x04, 0x08, 0x10, 0x20,
    0x00, 0x41, 0x41, 0x41, 0x7F,
    0x04, 0x02, 0x01, 0x02, 0x04,
    0x40, 0x40, 0x40, 0x40, 0x40,
    0x00, 0x03, 0x07, 0x08, 0x00,
    0x20, 0x54, 0x54, 0x78, 0x40,
    0x7F, 0x28, 0x44, 0x44, 0x38,
    0x38, 0x44, 0x44, 0x44, 0x28,
    0x38, 0x44, 0x44, 0x28, 0x7F,
    0x38, 0x54, 0x54, 0x54, 0x18,
    0x00, 0x08, 0x7E, 0x09, 0x02,
    0x18, 0xA4, 0xA4, 0x9C, 0x78,
    0x7F, 0x08, 0x04, 0x04, 0x78,
    0x00, 0x44, 0x7D, 0x40, 0x00,
    0x20, 0x40, 0x40, 0x3D, 0x00,
    0x7F, 0x10, 0x28, 0x44, 0x00,
    0x00, 0x41, 0x7F, 0x40, 0x00,
    0x7C, 0x04, 0x78, 0x04, 0x78,
    0x7C, 0x08, 0x04, 0x04, 0x78,
    0x38, 0x44, 0x44, 0x44, 0x38,
    0xFC, 0x18, 0x24, 0x24, 0x18,
    0x18, 0x24, 0x24, 0x18, 0xFC,
    0x7C, 0x08, 0x04, 0x04, 0x08,
    0x48, 0x54, 0x54, 0x54, 0x24,
    0x04, 0x04, 0x3F, 0x44, 0x24,
    0x3C, 0x40, 0x40, 0x20, 0x7C,
    0x1C, 0x20, 0x40, 0x20, 0x1C,
    0x3C, 0x40, 0x30, 0x40, 0x3C,
    0x44, 0x28, 0x10, 0x28, 0x44,
    0x4C, 0x90, 0x90, 0x90, 0x7C,
    0x44, 0x64, 0x54, 0x4C, 0x44,
    0x00, 0x08, 0x36, 0x41, 0x00,
    0x00, 0x00, 0x77, 0x00, 0x00,
    0x00, 0x41, 0x36, 0x08, 0x00,
    0x02, 0x01, 0x02, 0x04, 0x02,
    0x3C, 0x26, 0x23, 0x26, 0x3C,
    0x1E, 0xA1, 0xA1, 0x61, 0x12,
    0x3A, 0x40, 0x40, 0x20, 0x7A,
    0x38, 0x54, 0x54, 0x55, 0x59,
    0x21, 0x55, 0x55, 0x79, 0x41,
    0x21, 0x54, 0x54, 0x78, 0x41,
    0x21, 0x55, 0x54, 0x78, 0x40,
    0x20, 0x54, 0x55, 0x79, 0x40,
    0x0C, 0x1E, 0x52, 0x72, 0x12,
    0x39, 0x55, 0x55, 0x55, 0x59,
    0x39, 0x54, 0x54, 0x54, 0x59,
    0x39, 0x55, 0x54, 0x54, 0x58,
    0x00, 0x00, 0x45, 0x7C, 0x41,
    0x00, 0x02, 0x45, 0x7D, 0x42,
    0x00, 0x01, 0x45, 0x7C, 0x40,
    0xF0, 0x29, 0x24, 0x29, 0xF0,
    0xF0, 0x28, 0x25, 0x28, 0xF0,
    0x7C, 0x54, 0x55, 0x45, 0x00,
    0x20, 0x54, 0x54, 0x7C, 0x54,
    0x7C, 0x0A, 0x09, 0x7F, 0x49,
    0x32, 0x49, 0x49, 0x49, 0x32,
    0x32, 0x48, 0x48, 0x48, 0x32,
    0x32, 0x4A, 0x48, 0x48, 0x30,
    0x3A, 0x41, 0x41, 0x21, 0x7A,
    0x3A, 0x42, 0x40, 0x20, 0x78,
    0x00, 0x9D, 0xA0, 0xA0, 0x7D,
    0x39, 0x44, 0x44, 0x44, 0x39,
    0x3D, 0x40, 0x40, 0x40, 0x3D,
    0x3C, 0x24, 0xFF, 0x24, 0x24,
    0x48, 0x7E, 0x49, 0x43, 0x66,
    0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
    0xFF, 0x09, 0x29, 0xF6, 0x20,
    0xC0, 0x88, 0x7E, 0x09, 0x03,
    0x20, 0x54, 0x54, 0x79, 0x41,
    0x00, 0x00, 0x44, 0x7D, 0x41,
    0x30, 0x48, 0x48, 0x4A, 0x32,
    0x38, 0x40, 0x40, 0x22, 0x7A,
    0x00, 0x7A, 0x0A, 0x0A, 0x72,
    0x7D, 0x0D, 0x19, 0x31, 0x7D,
    0x26, 0x29, 0x29, 0x2F, 0x28,
    0x26, 0x29, 0x29, 0x29, 0x26,
    0x30, 0x48, 0x4D, 0x40, 0x20,
    0x38, 0x08, 0x08, 0x08, 0x08,
    0x08, 0x08, 0x08, 0x08, 0x38,
    0x2F, 0x10, 0xC8, 0xAC, 0xBA,
    0x2F, 0x10, 0x28, 0x34, 0xFA,
    0x00, 0x00, 0x7B, 0x00, 0x00,
    0x08, 0x14, 0x2A, 0x14, 0x22,
    0x22, 0x14, 0x2A, 0x14, 0x08,
    0xAA, 0x00, 0x55, 0x00, 0xAA,
    0xAA, 0x55, 0xAA, 0x55, 0xAA,
    0x00, 0x00, 0x00, 0xFF, 0x00,
    0x10, 0x10, 0x10, 0xFF, 0x00,
    0x14, 0x14, 0x14, 0xFF, 0x00,
    0x10, 0x10, 0xFF, 0x00, 0xFF,
    0x10, 0x10, 0xF0, 0x10, 0xF0,
    0x14, 0x14, 0x14, 0xFC, 0x00,
    0x14, 0x14, 0xF7, 0x00, 0xFF,
    0x00, 0x00, 0xFF, 0x00, 0xFF,
    0x14, 0x14, 0xF4, 0x04, 0xFC,
    0x14, 0x14, 0x17, 0x10, 0x1F,
    0x10, 0x10, 0x1F, 0x10, 0x1F,
    0x14, 0x14, 0x14, 0x1F, 0x00,
    0x10, 0x10, 0x10, 0xF0, 0x00,
    0x00, 0x00, 0x00, 0x1F, 0x10,
    0x10, 0x10, 0x10, 0x1F, 0x10,
    0x10, 0x10, 0x10, 0xF0, 0x10,
    0x00, 0x00, 0x00, 0xFF, 0x10,
    0x10, 0x10, 0x10, 0x10, 0x10,
    0x10, 0x10, 0x10, 0xFF, 0x10,
    0x00, 0x00, 0x00, 0xFF, 0x14,
    0x00, 0x00, 0xFF, 0x00, 0xFF,
    0x00, 0x00, 0x1F, 0x10, 0x17,
    0x00, 0x00, 0xFC, 0x04, 0xF4,
    0x14, 0x14, 0x17, 0x10, 0x17,
    0x14, 0x14, 0xF4, 0x04, 0xF4,
    0x00, 0x00, 0xFF, 0x00, 0xF7,
    0x14, 0x14, 0x14, 0x14, 0x14,
    0x14, 0x14, 0xF7, 0x00, 0xF7,
    0x14, 0x14, 0x14, 0x17, 0x14,
    0x10, 0x10, 0x1F, 0x10, 0x1F,
    0x14, 0x14, 0x14, 0xF4, 0x14,
    0x10, 0x10, 0xF0, 0x10, 0xF0,
    0x00, 0x00, 0x1F, 0x10, 0x1F,
    0x00, 0x00, 0x00, 0x1F, 0x14,
    0x00, 0x00, 0x00, 0xFC, 0x14,
    0x00, 0x00, 0xF0, 0x10, 0xF0,
    0x10, 0x10, 0xFF, 0x10, 0xFF,
    0x14, 0x14, 0x14, 0xFF, 0x14,
    0x10, 0x10, 0x10, 0x1F, 0x00,
    0x00, 0x00, 0x00, 0xF0, 0x10,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
    0xFF, 0xFF, 0xFF, 0x00, 0x00,
    0x00, 0x00, 0x00, 0xFF, 0xFF,
    0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
    0x38, 0x44, 0x44, 0x38, 0x44,
    0x7C, 0x2A, 0x2A, 0x3E, 0x14,
    0x7E, 0x02, 0x02, 0x06, 0x06,
    0x02, 0x7E, 0x02, 0x7E, 0x02,
    0x63, 0x55, 0x49, 0x41, 0x63,
    0x38, 0x44, 0x44, 0x3C, 0x04,
    0x40, 0x7E, 0x20, 0x1E, 0x20,
    0x06, 0x02, 0x7E, 0x02, 0x02,
    0x99, 0xA5, 0xE7, 0xA5, 0x99,
    0x1C, 0x2A, 0x49, 0x2A, 0x1C,
    0x4C, 0x72, 0x01, 0x72, 0x4C,
    0x30, 0x4A, 0x4D, 0x4D, 0x30,
    0x30, 0x48, 0x78, 0x48, 0x30,
    0xBC, 0x62, 0x5A, 0x46, 0x3D,
    0x3E, 0x49, 0x49, 0x49, 0x00,
    0x7E, 0x01, 0x01, 0x01, 0x7E,
    0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
    0x44, 0x44, 0x5F, 0x44, 0x44,
    0x40, 0x51, 0x4A, 0x44, 0x40,
    0x40, 0x44, 0x4A, 0x51, 0x40,
    0x00, 0x00, 0xFF, 0x01, 0x03,
    0xE0, 0x80, 0xFF, 0x00, 0x00,
    0x08, 0x08, 0x6B, 0x6B, 0x08,
    0x36, 0x12, 0x36, 0x24, 0x36,
    0x06, 0x0F, 0x09, 0x0F, 0x06,
    0x00, 0x00, 0x18, 0x18, 0x00,
    0x00, 0x00, 0x10, 0x10, 0x00,
    0x30, 0x40, 0xFF, 0x01, 0x01,
    0x00, 0x1F, 0x01, 0x01, 0x1E,
    0x00, 0x19, 0x1D, 0x17, 0x12,
    0x00, 0x3C, 0x3C, 0x3C, 0x3C,
    0x00, 0x00, 0x00, 0x00, 0x00,
};


SPKDisplay::SPKDisplay(PinName mosiPin, PinName clkPin, PinName csPin, PinName dcPin, PinName resPin, Serial *debugSerial)
{
    bufferHasChanged = false;

    fontStartCharacter = NULL;
    fontEndCharacter = NULL;
    fontCharacters = NULL;

    spi = new SPI(mosiPin, NC, clkPin);
    spi->format(8,3);
    // changed to 9600 to test
    spi->frequency(1000000);

    cs = new DigitalOut(csPin);
    dc = new DigitalOut(dcPin);
    res = new DigitalOut(resPin);

    // Link up debug Serial object
    // Passing in shared object as debugging is shared between all DVI mixer functions
    debug = debugSerial;

    setup();

    clearBuffer();

    if (debug) debug->printf("SPKDisplay loaded\n\r");
}

// set display for black on white
void SPKDisplay::inverse()
{
    *dc=0;
    *cs=0;
    spi->write(0xA7);
    *dc=1;
    *cs=1;
}

//set display for white on black (normal state after reset)
void SPKDisplay::normal()
{
    *dc=0;
    *cs=0;
    spi->write(0xA6);
    *dc=1;
    *cs=1;
}

void SPKDisplay::displayPower(int P)
{
    *dc=0;
    *cs=0;
    if(P==0) spi->write(0xAE);
    else spi->write(0xAF);
    *dc=1;
    *cs=1;

}


void SPKDisplay::clearBuffer()
{
    memset(buffer, 0, bufferCount);
    bufferHasChanged = true;
}

void SPKDisplay::imageToBuffer(const uint8_t* image)
{
    memcpy(buffer, image, bufferCount);
    bufferHasChanged = true;
}

void SPKDisplay::clearBufferRow(int row)
{
    // Range check
    if (row >= 8) {
        if (debug) debug->printf("SPKDisplay::clearBufferRow sent out of bounds row");
        return;
    }
    int bStart = row*bufferWidth;
    int bEnd = bStart + pixelWidth;

    for (int bPos = bStart; bPos <= bEnd; bPos++) {
        buffer[bPos] = 0x00;
    }

    bufferHasChanged = true;
}

void SPKDisplay::horizLineToBuffer(int y)
{
    if (y >= pixelHeight) {
        if (debug) debug->printf("SPKDisplay::clearBufferRow sent out of bounds y");
        return;
    }

    int row = (y*pixInPage) / pixelHeight;
    int posInRow = y % pixInPage;

    int bStart = row*bufferWidth;
    int bEnd = bStart + pixelWidth;

    for (int bPos = bStart; bPos <= bEnd; bPos++) {
        // Need to bitwise OR as setting single bit (the line) in byte (the row)
        buffer[bPos] = buffer[bPos] | 0x01 << posInRow;
    }

    bufferHasChanged = true;
}


void SPKDisplay::textToBuffer(char *message, int row)
{
   char character;
    // Range check
    if (row >= 8) row = 7;
    int bStart = row*bufferWidth;
    int bEnd = bStart + pixelWidth;
 
    int bPos = bStart;
    for (int i = 0; i < 21; i++)
    {
       character=message[i];
         
            // Shift into our array's indexing
      //      character -= *fontStartCharacter;
            
            // Write each byte's vertical column of 8bits into the buffer.
            for (int j = 0; j < 5;j++)
            {
                if (bPos >= bEnd) break;
                buffer[bPos++] = font[character*5+j];
            }
            
            // Put 1px letter spacing at end
            if (bPos >= bEnd) break;
            buffer[bPos++] = 0x00; // 1 px letter spacing
        
    }
    
    bufferHasChanged = true;
}


// rewritten to cope with the paging
void SPKDisplay::sendBuffer()
{
    if (bufferHasChanged) {
        // Select the device by seting chip select low
        *cs = 0; // select chip
        *dc = 0; // comand mode


        unsigned char i=0,j=0;
        for(i=0; i<8; i++) {
            *dc=0; // command mode
            spi->write(0xB0+i); //Set display position - paged display
            spi->write(0x00); //Set display position - low column address
            spi->write(0x10);//Set the display position - high column address

            *dc=1; // data mode
            for(j=0; j<128; j++) {
                spi->write(buffer[i*128+j]); //copy buffer into ram

            }

        }

        *cs = 1;

        bufferHasChanged = false;
    }
}

// display a welcome message encoded in tab0 in  spk_ole_ssd1305.h
void SPKDisplay::welcome()
{
// Select the device by seting chip select low
    *cs = 0; // select chip
    *dc = 0; // comand mode


    unsigned char i=0,j=0;
    for(i=0; i<8; i++) {
        *dc=0; // command mode
        spi->write(0xB0+i); //Set display position - paged display
        spi->write(0x00); //Set display position - low column address
        spi->write(0x10);//Set the display position - high column address

        *dc=1; // data mode
        for(j=0; j<128; j++) {
            // spi->write(tab0[i*128+j]); //copy buffer into ram
            spi->write(logo_bits[i*128+j]); //copy buffer into ram
        }

    }

    *cs = 1;

}



//================
// display a welcome message encoded in tab0 in  spk_ole_ssd1305.h
void SPKDisplay::fontdemo()
{
// Select the device by seting chip select low
    *cs = 0; // select chip
    *dc = 0; // comand mode


    unsigned char i=0,j=0;
    for(i=0; i<8; i++) {
        *dc=0; // command mode
        spi->write(0xB0+i); //Set display position - paged display
        spi->write(0x00); //Set display position - low column address
        spi->write(0x10);//Set the display position - high column address

        *dc=1; // data mode
        for(j=0; j<128; j++) {
            // spi->write(tab0[i*128+j]); //copy buffer into ram
            spi->write(font[i*128+j]); //copy buffer into ram
        }

    }

    *cs = 1;

}
//=================

void SPKDisplay::setup()
{
    // TASK: SCREEN OFF, Run pre-flight

    // Hard reset the OLED
    *res=1;
    wait_ms(1);
    *res = 0;
    wait_ms(1);
    *res = 1;

    // Select the device by seting chip select low
    *cs = 0;

    // Set to receive COMMANDS not data
    *dc = 0;
//=======ALL THESE TAKEN FROM THE UNIVISION DATASHEET UNCHANGED==========

    spi->write(0x20); // set addressing mode
    spi->write(0x10); // paged adressign mode

    spi->write(0x00); // set lower nyble column address
    spi->write(0x10); // set higher column adress
    spi->write(0x40);  //set display start line to 0
    spi->write(0x81); // set contrast control register
    spi->write(0xFF); // set contrast to maximum

    spi->write(0xA0); // [A0]:column address 0 is map to SEG0 ,
    //[A1]: columnaddress 131 is map to SEG0*/

    spi->write(0xA4); // entire display ON - means that dispaly constaly matched to RAM content

    spi->write(0xA6); //normal display - white on black

    spi->write(0xA8); // set MUX ratio command
    spi->write(0x3F); // MUX set to 36

    spi->write(0x8D); //set DC-DC
    spi->write(0x14);   // 0x14=ON

    spi->write(0xAE); // set display off - sleep mode

    spi->write(0xD3); // set display offset
    spi->write(0x00); // to no offset

    spi->write(0xD5); //set clock divide
    spi->write(0x20); // to get clock at 80Hz

//spi->write(0xD8); // set area color
//spi->write(0x00);

    spi->write(0xDA); // set pins configuration
    spi->write(0x12); // com left - right remap , alternaitve com config - realtes to hardware settings on board

    spi->write(0xDB); // set VCOMHH level
    spi->write(0x00); // to 0.65*Vcc

    spi->write(0xD9); // set pre charge period
    spi->write(0x22); // P1=2, P2=2

    spi->write(0xC0); // set COM ouptut scan normal

//INI_DIS - initialise the display as per manufacturers example prog

    unsigned char i=0,j=0;
    for(i=0; i<8; i++) {
        *dc=0; // command mode
        spi->write(0xB0+i); //Set display position - paged display
        spi->write(0x02); //Set display position - low column address
        spi->write(0x10);//Set the display position - high column address

        *dc=1; // set to receive data no commands

        for(j=0; j<128; j++) {
            spi->write(0x00); //Screen display initial setting

        }
        *dc=0;
        spi->write(0xaf); // screen on
    }



}