displaying on SSD1306, 128x64 pixels OLED

Dependencies:   microbit

OLED.cpp

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

File content as of revision 12:b4d5e007640e:


#include "MicroBit.h"
#include "MicroBitI2C.h"

#include "OLED.h"
#include "cppNorm.h"

OLED::OLED() : 
     i2c(I2C_SDA0,I2C_SCL0)
    ,charX(0)
    ,charY(0)
    ,displayWidth(128)
    ,displayHeight(64 / 8)
    ,screenSize(0) 
    ,pendingNewline(false)
    {}

void OLED::command(uint8_t cmd) {
    char buf[2];
    buf[0] = '\0';
    buf[1] = cmd;
    i2c.write(chipAdress,buf,2);
}

void OLED::init() {
    init(128, 64);
    }
    

void OLED::init(uint8_t width, uint8_t height) {
    command(SSD1306_DISPLAYOFF);
    command(SSD1306_SETDISPLAYCLOCKDIV);
    command(0x80);                                  // the suggested ratio 0x80
    command(SSD1306_SETMULTIPLEX);
    command(0x3F);
    command(SSD1306_SETDISPLAYOFFSET);
    command(0x0);                                   // no offset
    command(SSD1306_SETSTARTLINE | 0x0);            // line #0
    command(SSD1306_CHARGEPUMP);
    command(0x14);
    command(SSD1306_MEMORYMODE);
    command(0x00);                                  // 0x0 act like ks0108
    command(SSD1306_SEGREMAP | 0x1);
    command(SSD1306_COMSCANDEC);
    command(SSD1306_SETCOMPINS);
    command(0x12);
    command(SSD1306_SETCONTRAST);
    command(0xCF);
    command(SSD1306_SETPRECHARGE);
    command(0xF1);
    command(SSD1306_SETVCOMDETECT);
    command(0x40);
    command(SSD1306_DISPLAYALLON_RESUME);
    command(SSD1306_NORMALDISPLAY);
    command(SSD1306_DISPLAYON);
    displayWidth = width;
    displayHeight = height / 8;
    screenSize = displayWidth * displayHeight;
    charX = xOffset;
    charY = yOffset;
    loadStarted = false;
    loadPercent = 0;
    clear();
}

void OLED::clear() {
    loadStarted = false;
    loadPercent = 0;
    command(SSD1306_SETCOLUMNADRESS);
    command(0x00);
    command(displayWidth - 1);
    command(SSD1306_SETPAGEADRESS);
    command(0x00);
    command(displayHeight - 1);
    char data[17];
    data[0] = 0x40;
    for (int8_t i = 1; i < 17; i++) 
        data[i] = 0x00;
    for (int16_t  i = 0; i < screenSize; i += 16) { 
        i2c.write(chipAdress, data, 17,false);
    }
    charX = xOffset;
    charY = yOffset;
    setTextArea(32,true);
}

void OLED::drawChar(uint8_t x, uint8_t y, uint8_t chr ) {
    command(SSD1306_SETCOLUMNADRESS);
    command(x);
    command(x + 5);
    command(SSD1306_SETPAGEADRESS);
    command(y);
    command(y + 1);
    textArea[x/6][y]=chr;
    char line[2];
    line[0] = 0x40;
    for (int8_t i = 0; i < 6; i++) {
        if (i == 5) 
            line[1] = 0x00;
        else 
            line[1] = font[chr][i];
        i2c.write(chipAdress, line, 2, false);
    }
}


void OLED::setTextArea(uint8_t chr, bool setLine8=false) {
    for (int8_t line = 0; line <= 8; line++)
        if (line < 8 || setLine8)
            for (int8_t xPos = 0; xPos < 22; xPos++)
                textArea[xPos][line]=chr;
}

void OLED::scroll() {
    for (int8_t line = 1; line <= 8; line++)
        for (int8_t xPos = 0; xPos < 22; xPos++)
            drawChar(6*xPos,line-1,textArea[xPos][line]);
}    

void OLED::newLine() {
    charY++;
    charX = xOffset;
    if (charY == 8) {
        charY = 7;
        scroll();
       }
    pendingNewline=false;
}
            
void OLED::puts(string str) {
    for (uint16_t i = 0; i < str.length(); i++) {
        if (str.charAt(i) == '\r')
            charX = xOffset;
        else if (str.charAt(i) == '\n') {
            if (pendingNewline)
                newLine();
            pendingNewline=true;
        } else {
            if (pendingNewline || charX > displayWidth - 6)
                newLine();
            drawChar(charX, charY, (uint8_t)str.charAt(i));
            charX += 6;
            }
    }
}

uint8_t OLED::printf(const char * fmt, ...) {
    va_list args;
    va_start(args, fmt);
    uint8_t len = min(vsnprintf(printf_text, printf_textSize, fmt, args), printf_textSize);
    va_end(args);
    printf_text[len] = '\0'; 
    puts(printf_text);
    return len;
}