Benny Andersen / microbitOLED

Dependencies:   microbit

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers OLED.cpp Source File

OLED.cpp

00001 
00002 #include "MicroBit.h"
00003 #include "MicroBitI2C.h"
00004 
00005 #include "OLED.h"
00006 #include "cppNorm.h"
00007 
00008 OLED::OLED() : 
00009      i2c(I2C_SDA0,I2C_SCL0)
00010     ,charX(0)
00011     ,charY(0)
00012     ,displayWidth(128)
00013     ,displayHeight(64 / 8)
00014     ,screenSize(0) 
00015     ,pendingNewline(false)
00016     {}
00017 
00018 void OLED::command(uint8_t cmd) {
00019     char buf[2];
00020     buf[0] = '\0';
00021     buf[1] = cmd;
00022     i2c.write(chipAdress,buf,2);
00023 }
00024 
00025 void OLED::init() {
00026     init(128, 64);
00027     }
00028     
00029 
00030 void OLED::init(uint8_t width, uint8_t height) {
00031     command(SSD1306_DISPLAYOFF);
00032     command(SSD1306_SETDISPLAYCLOCKDIV);
00033     command(0x80);                                  // the suggested ratio 0x80
00034     command(SSD1306_SETMULTIPLEX);
00035     command(0x3F);
00036     command(SSD1306_SETDISPLAYOFFSET);
00037     command(0x0);                                   // no offset
00038     command(SSD1306_SETSTARTLINE | 0x0);            // line #0
00039     command(SSD1306_CHARGEPUMP);
00040     command(0x14);
00041     command(SSD1306_MEMORYMODE);
00042     command(0x00);                                  // 0x0 act like ks0108
00043     command(SSD1306_SEGREMAP | 0x1);
00044     command(SSD1306_COMSCANDEC);
00045     command(SSD1306_SETCOMPINS);
00046     command(0x12);
00047     command(SSD1306_SETCONTRAST);
00048     command(0xCF);
00049     command(SSD1306_SETPRECHARGE);
00050     command(0xF1);
00051     command(SSD1306_SETVCOMDETECT);
00052     command(0x40);
00053     command(SSD1306_DISPLAYALLON_RESUME);
00054     command(SSD1306_NORMALDISPLAY);
00055     command(SSD1306_DISPLAYON);
00056     displayWidth = width;
00057     displayHeight = height / 8;
00058     screenSize = displayWidth * displayHeight;
00059     charX = xOffset;
00060     charY = yOffset;
00061     loadStarted = false;
00062     loadPercent = 0;
00063     clear();
00064 }
00065 
00066 void OLED::clear() {
00067     loadStarted = false;
00068     loadPercent = 0;
00069     command(SSD1306_SETCOLUMNADRESS);
00070     command(0x00);
00071     command(displayWidth - 1);
00072     command(SSD1306_SETPAGEADRESS);
00073     command(0x00);
00074     command(displayHeight - 1);
00075     char data[17];
00076     data[0] = 0x40;
00077     for (int8_t i = 1; i < 17; i++) 
00078         data[i] = 0x00;
00079     for (int16_t  i = 0; i < screenSize; i += 16) { 
00080         i2c.write(chipAdress, data, 17,false);
00081     }
00082     charX = xOffset;
00083     charY = yOffset;
00084     setTextArea(32,true);
00085 }
00086 
00087 void OLED::drawChar(uint8_t x, uint8_t y, uint8_t chr ) {
00088     command(SSD1306_SETCOLUMNADRESS);
00089     command(x);
00090     command(x + 5);
00091     command(SSD1306_SETPAGEADRESS);
00092     command(y);
00093     command(y + 1);
00094     textArea[x/6][y]=chr;
00095     char line[2];
00096     line[0] = 0x40;
00097     for (int8_t i = 0; i < 6; i++) {
00098         if (i == 5) 
00099             line[1] = 0x00;
00100         else 
00101             line[1] = font[chr][i];
00102         i2c.write(chipAdress, line, 2, false);
00103     }
00104 }
00105 
00106 
00107 void OLED::setTextArea(uint8_t chr, bool setLine8=false) {
00108     for (int8_t line = 0; line <= 8; line++)
00109         if (line < 8 || setLine8)
00110             for (int8_t xPos = 0; xPos < 22; xPos++)
00111                 textArea[xPos][line]=chr;
00112 }
00113 
00114 void OLED::scroll() {
00115     for (int8_t line = 1; line <= 8; line++)
00116         for (int8_t xPos = 0; xPos < 22; xPos++)
00117             drawChar(6*xPos,line-1,textArea[xPos][line]);
00118 }    
00119 
00120 void OLED::newLine() {
00121     charY++;
00122     charX = xOffset;
00123     if (charY == 8) {
00124         charY = 7;
00125         scroll();
00126        }
00127     pendingNewline=false;
00128 }
00129             
00130 void OLED::puts(string str) {
00131     for (uint16_t i = 0; i < str.length(); i++) {
00132         if (str.charAt(i) == '\r')
00133             charX = xOffset;
00134         else if (str.charAt(i) == '\n') {
00135             if (pendingNewline)
00136                 newLine();
00137             pendingNewline=true;
00138         } else {
00139             if (pendingNewline || charX > displayWidth - 6)
00140                 newLine();
00141             drawChar(charX, charY, (uint8_t)str.charAt(i));
00142             charX += 6;
00143             }
00144     }
00145 }
00146 
00147 uint8_t OLED::printf(const char * fmt, ...) {
00148     va_list args;
00149     va_start(args, fmt);
00150     uint8_t len = min(vsnprintf(printf_text, printf_textSize, fmt, args), printf_textSize);
00151     va_end(args);
00152     printf_text[len] = '\0'; 
00153     puts(printf_text);
00154     return len;
00155 }