displaying on SSD1306, 128x64 pixels OLED

Dependencies:   microbit

OLED.h

Committer:
bvirk
Date:
2020-02-25
Revision:
12:b4d5e007640e
Parent:
11:77aaf68a180b

File content as of revision 12:b4d5e007640e:

#include "MicroBit.h"
#include <vector>
#include "stdarg.h"
#include "cppNorm.h"

#ifndef microbitOLED_OLED
#define microbitOLED_OLED

#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYON 0xAF
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_SETCOLUMNADRESS 0x21
#define SSD1306_SETVCOMDETECT 0xDB
#define SSD1306_SETCOMPINS 0xDA
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETHIGHCOLUMN 0x10
#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETPAGEADRESS 0x22
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETMULTIPLEX 0xA8
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETSTARTLINE 0x40

/**
  * Access to bitfields under different names.
  * Access to bit 0-7, named  by0 or x, and bit 8-15, named by1 or y \n  
  * of 16 bit named that16. Can be consructed with either two \n  
  * uint8_t or a uint16_t
  */
union uint16 {
    struct {
    uint8_t by0;
    uint8_t by1;
    };
    struct {
    uint8_t x;
    uint8_t y;
    };
    uint16_t that16;
    uint16(uint16_t all) : that16(all) {}
    uint16(uint8_t byte1,uint8_t  byte0) : by1(byte1),by0(byte0) {}
    };

const unsigned char font[][5] = {
    {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}};

/**
  * Representation of a 128x64 pixels, SSD1306 compatibel OLED display.
  */ 
class OLED {
    
    static const uint8_t chipAdress = 0x78; 
    static const uint8_t xOffset = 0;
    static const uint8_t yOffset = 0;
    
    const uint8_t printf_textSize=0x3f;
    char printf_text[0x40];
    
    unsigned char textArea[22][9];
    uint8_t charX;
    uint8_t charY;
    uint8_t displayWidth;
    uint8_t displayHeight;
    uint16_t screenSize;
    bool loadStarted;
    float loadPercent;
    bool pendingNewline;
    
    MicroBitI2C i2c;
    
    void init(uint8_t width, uint8_t height);
    void command(uint8_t cmd);
    void setTextArea(uint8_t chr, bool setLine8);
    
    
public:

    /**
      * ssd1306 compatible device of 128x64 pixels OLED display.
      * Init() must be called after construction. \n 
      * Works for some untraced circumstances not in fibers
      */
    OLED();

    /**
      * Initialisere display and clears it. 
      * A buffer representing charaters are filled with space characters.
      */ 
    void init();
    
    /**
      * Clears the display.
      */
    void clear();

    /** 
      * Makes a newline by incrementing charY and assigning xOffset to charX \n 
      * if charY becomes 8 the display screen is scrolled one line and charY \n 
      * is decremented to 7. pendingNewline=false is done at last.
      */
    void newLine();
    
    /**
      * Put a char on display. 
      * The font represent display characters as 6x8 pixels areas (6 horizontal). \n 
      * The font does actual contain 5 colums - the six'd makes characters \n 
      * seperation. Character values 0, 0x20, and 0xff are bitpatterns with \n
      * all null pixels (like space)
      *
      * @param x horizontal pixelwise position, range [0,displayWidth - 6]
      * @param y vertical position, range [0,7]
      * @param chr character to put on display
      */
    void drawChar(uint8_t x, uint8_t y, uint8_t chr );
    
  /** 
    * Writes a string at charX, charY position. Afterwards are \n 
    * charX, charY set to the next starting point for writting to display \n 
    * \\n and \\r is processed - \\n includes \\r  functionality. \n 
    *
    * @param str to be displayed at (charX, charY).   
    */
    void puts(string str);
    
    /**
      * printf - the old classic. \\n and \\r is processed. \n 
      * \\n includes \\r  functionality. \n    
      * This function is the main reason to that OLED not works in fibers. \n
      */
    uint8_t printf(const char * frmt, ...);   
    
    /**
     *  Scroll the display one line
     */
    void scroll();
    
};
#endif