UniGraphic-Fork for ST7920-LCD-controller and SH1106. Tested with 128x64 LCD with SPI and 128x64-OLED with IIC

Dependents:   UniGraphic-St7920-Test AfficheurUTILECO

Fork of UniGraphic by GraphicsDisplay

Fork of the UniGraphic-Library for monochrome LCDs with ST7920 controller and 128x64-IIC-OLED-Display with SH1106-Controller

/media/uploads/charly/20170522_210344.jpg

/media/uploads/charly/20180425_230623.jpg

Had to adapt LCD for following reasons:

  • Give access to screenbuffer buffer[] to parent class
  • pixel() and pixel_read() as they are hardware-dependent
  • added reset-pin to IIC-Interface

GraphicDisplay:: sends buffer to LCD when auto_update is set to true.

Testprogram for ST7920 can be found here:

https://developer.mbed.org/users/charly/code/UniGraphic-St7920-Test/

Files at this revision

API Documentation at this revision

Comitter:
charly
Date:
Sun Apr 22 21:41:24 2018 +0000
Parent:
35:b8d3f1e68000
Child:
37:5de028b08308
Commit message:
Added SH1106 for OLED Display 128x64 via IIC

Changed in this revision

Display/LCD.cpp Show annotated file Show diff for this revision Revisions of this file
Display/LCD.h Show annotated file Show diff for this revision Revisions of this file
Inits/SH1106.cpp Show annotated file Show diff for this revision Revisions of this file
Inits/SH1106.h Show annotated file Show diff for this revision Revisions of this file
Inits/SSD1306.cpp Show annotated file Show diff for this revision Revisions of this file
Inits/SSD1306.h Show annotated file Show diff for this revision Revisions of this file
Protocols/I2C_bus.cpp Show annotated file Show diff for this revision Revisions of this file
Protocols/I2C_bus.h Show annotated file Show diff for this revision Revisions of this file
--- a/Display/LCD.cpp	Sun May 21 20:50:09 2017 +0000
+++ b/Display/LCD.cpp	Sun Apr 22 21:41:24 2018 +0000
@@ -94,11 +94,11 @@
     tftID=0;
   //  locate(0,0);
 }
-LCD::LCD(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char* name)
+LCD::LCD(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, PinName reset, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char* name)
     : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y), _LCDPAGES(lcdsize_y>>3), _IC_X_SEGS(ic_x_segs), _IC_Y_COMS(ic_y_coms), _IC_PAGES(ic_y_coms>>3) 
 {
     if(displayproto==I2C_){
-        proto = new I2C_bus(Hz,address,sda,scl);
+        proto = new I2C_bus(Hz,address,sda,scl, reset);
         useNOP=false;
         }
     buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES);
--- a/Display/LCD.h	Sun May 21 20:50:09 2017 +0000
+++ b/Display/LCD.h	Sun Apr 22 21:41:24 2018 +0000
@@ -55,7 +55,7 @@
     /** Create a monochrome LCD I2C interface
     * @param name The name used by the parent class to access the interface
     */
-    LCD(proto_t displayproto, int Hz, int address,PinName sda, PinName scl, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char* name);
+    LCD(proto_t displayproto, int Hz, int address,PinName sda, PinName scl, PinName reset, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char* name);
     
     
     /** Destructor
@@ -237,7 +237,8 @@
     int draw_mode;
     int contrast;
     
-private:
+//private:
+protected:
 
     Protocols* proto;
     const int screensize_X;
@@ -259,8 +260,7 @@
     int win_y2;
     int orientation;
     bool useNOP;
-
-public:    
+  
     unsigned char *buffer;
     unsigned short *buffer16;   
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Inits/SH1106.cpp	Sun Apr 22 21:41:24 2018 +0000
@@ -0,0 +1,225 @@
+/* mbed UniGraphic library - Device specific class
+ * SH1106 by Karl Zweimüller
+ * SSD1306 by Copyright (c) 2015 Peter Drescher
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+#include "Protocols.h"
+#include "SH1106.h"
+
+//////////////////////////////////////////////////////////////////////////////////
+// display settings ///////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+
+#define IC_X_SEGS    132 // 132 SEG
+#define IC_Y_COMS    64  // 64  COM
+
+#define SH1106_SETCONTRAST         0x81
+#define SH1106_DISPLAYALLON_RESUME 0xA4
+#define SH1106_DISPLAYALLON        0xA5
+#define SH1106_NORMALDISPLAY       0xA6
+#define SH1106_INVERTDISPLAY       0xA7
+#define SH1106_DISPLAYOFF          0xAE
+#define SH1106_DISPLAYON           0xAF
+#define SH1106_SETDISPLAYOFFSET    0xD3
+#define SH1106_SETCOMPINS          0xDA
+#define SH1106_SETVCOMDETECT       0xDB
+#define SH1106_SETDISPLAYCLOCKDIV  0xD5
+#define SH1106_SETPRECHARGE        0xD9
+#define SH1106_SETMULTIPLEX        0xA8
+#define SH1106_SETLOWCOLUMN        0x00
+#define SH1106_SETHIGHCOLUMN       0x10
+#define SH1106_SETSTARTLINE        0x40
+#define SH1106_MEMORYMODE          0x20
+#define SH1106_COMSCANINC          0xC0
+#define SH1106_COMSCANDEC          0xC8
+#define SH1106_SEGREMAP            0xA0
+#define SH1106_CHARGEPUMP          0x8D
+
+SH1106::SH1106(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char *name , unsigned int LCDSIZE_X, unsigned  int LCDSIZE_Y)
+    : LCD(displayproto, port, CS, reset, DC, WR, RD, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
+{
+    hw_reset();
+    BusEnable(true);
+    init();
+    cls();
+    set_orientation(1);
+    locate(0,0);
+}
+SH1106::SH1106(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char *name, unsigned int LCDSIZE_X, unsigned  int LCDSIZE_Y)
+    : LCD(displayproto, Hz, mosi, miso, sclk, CS, reset, DC, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
+{
+    hw_reset();
+    BusEnable(true);
+    init();
+    cls();
+    set_orientation(1);
+    locate(0,0);
+}
+
+SH1106::SH1106(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, PinName reset, const char* name , unsigned int LCDSIZE_X, unsigned  int LCDSIZE_Y)
+    : LCD(displayproto, Hz, address, sda, scl,reset, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
+{
+    hw_reset();
+    init();
+    cls();
+    set_orientation(1);
+    locate(0,0);
+}
+
+
+// reset and init the lcd controller
+void SH1106::init()
+{
+    /* Start Initial Sequence ----------------------------------------------------*/
+    /* SH1106
+     //  wr_cmd8(0xE2);   //  sw reset
+       wait_ms(15);
+
+       wr_cmd8(SH1106_DISPLAYOFF);    // no problem in SPI_16 for single byte cmds
+       wr_cmd16((SH1106_SETDISPLAYCLOCKDIV<<8)|0x80);   // wr_cmd16 for multibyte cmds issue in SPI16 mode
+     //  wr_cmd8(0x80); // in SPI_16 it would become 0xE380 and will break things up
+       wr_cmd16((SH1106_SETMULTIPLEX<<8)|63);
+    //   wr_cmd8(63);
+
+       wr_cmd16((SH1106_SETDISPLAYOFFSET<<8)|0x00);
+    //   wr_cmd8(0x0);
+
+       wr_cmd8(SH1106_SETSTARTLINE | 0x0);            // line #0
+
+       wr_cmd16((SH1106_CHARGEPUMP<<8)|0x14);
+     //  wr_cmd8(0x14);                         // 0x10
+
+       wr_cmd16((SH1106_MEMORYMODE<<8)|0x00);
+    //   wr_cmd8(0x00);                                  // 0x0 act like ks0108
+
+       wr_cmd8(SH1106_SEGREMAP ); //| 0x1);
+
+       wr_cmd8(SH1106_COMSCANDEC);
+
+       wr_cmd16((SH1106_SETCOMPINS<<8)|0x12);
+     //  wr_cmd8(0x12);                           //        LCDSIZE_Y == 32 ? 0x02 : 0x12);
+
+       wr_cmd16((SH1106_SETCONTRAST<<8)|0xCF);
+    //   wr_cmd8(0xCF);                              //  _rawHeight == 32 ? 0x8F : ((vccstate == SH1106_EXTERNALVCC) ? 0x9F : 0xCF) );
+
+       wr_cmd16((SH1106_SETPRECHARGE<<8)|0xF1);
+    //   wr_cmd8(0xF1);                               // : 0x22);
+
+       wr_cmd16((SH1106_SETVCOMDETECT<<8)|0x40);
+    //   wr_cmd8(0x40);
+
+       wr_cmd8(SH1106_DISPLAYALLON_RESUME);
+
+       //wr_cmd8(SH1106_NORMALDISPLAY);
+       wr_cmd8(SH1106_INVERTDISPLAY);
+
+       wr_cmd8(SH1106_DISPLAYON);
+    */
+
+//SH1106
+    wr_cmd8(0xAE);//--turn off oled panel
+    wr_cmd8(0x02);//---set low column address
+    wr_cmd8(0x10);//---set high column address
+    wr_cmd8(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
+    wr_cmd8(0x81);//--set contrast control register
+    wr_cmd8(0xA0);//--Set contrast
+    wr_cmd8(0xA8);//--set multiplex ratio(1 to 64)
+    wr_cmd8(0x3F);//--1/64 duty
+    wr_cmd8(0xD3);//-set display offset    Shift Mapping RAM Counter (0x00~0x3F)
+    wr_cmd8(0x00);//-not offset
+    wr_cmd8(0xd5);//--set display clock divide ratio/oscillator frequency
+    wr_cmd8(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
+    wr_cmd8(0xD9);//--set pre-charge period
+    wr_cmd8(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
+    wr_cmd8(0xDA);//--set com pins hardware configuration
+    wr_cmd8(0x12); // or 0x02
+    wr_cmd8(0xDB);//--set vcomh
+    wr_cmd8(0x40);//Set VCOM Deselect Level
+    //wr_cmd8(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02) // not on SH1106
+    wr_cmd8(0xA4);// Disable Entire Display On (0xa4/0xa5)
+    wr_cmd8(0xA6);// Disable Inverse Display On (0xa6/a7)
+
+    wr_cmd8(0xA1); // reverse order
+    //wr_cmd8(0xC0);//Set COM/Row Scan Direction
+    wr_cmd8(0xC8); //reverse direction
+    wr_cmd8(0xAF);//--turn on oled panel
+}
+
+////////////////////////////////////////////////////////////////////
+// functions that overrides the standard ones implemented in LCD.cpp
+////////////////////////////////////////////////////////////////////
+
+void SH1106::copy_to_lcd(void)
+{
+
+    for(int page=0; page<8 /*_LCDPAGES */; page++) {
+        wr_cmd8(0x02);             // set column low nibble
+        wr_cmd8(0x10);             // set column hi  nibble
+        wr_cmd8(0xB0+page);        // set page
+        wr_grambuf(buffer16+(page*screensize_X>>1), screensize_X>>1);   // send whole page pixels as shorts(16bit) not bytes!
+    }
+}
+
+void SH1106::cls(void)
+{
+    unsigned short tmp = _background^0xFFFF;
+    //memset(buffer,tmp,/*screensize_X*_LCDPAGES*/ 128*64/8);  // clear display buffer
+    memset(buffer,0x00,screensize_X*(screensize_Y>>3));  // clear display buffer
+    copy_to_lcd();
+}
+
+void SH1106::mirrorXY(mirror_t mode)
+{
+    switch (mode) {
+        case(NONE):
+            wr_cmd16(0xA0C0);
+            break;
+        case(X):
+            wr_cmd16(0xA1C0);
+            break;
+        case(Y):
+            wr_cmd16(0xA0C8);
+            break;
+        case(XY):
+            wr_cmd16(0xA1C8);
+            break;
+    }
+}
+
+void SH1106::set_contrast(int o)
+{
+    contrast = o;
+
+    wr_cmd16(0x8100|(o&0xFF));
+}
+
+void SH1106::pixel(int x, int y, unsigned short color)
+{
+    // first check parameter
+    if((x >= screensize_X) || (y >= screensize_Y) || (x<0) || (y<0)) return;
+
+    //Buffer[(Xpoint + (Ypoint / 8) * sOLED_DIS.OLED_Dis_Column)] |= 1 << (Ypoint % 8);
+    //Buffer[(Xpoint + (Ypoint / 8) * sOLED_DIS.OLED_Dis_Column)] |= 0 << (Ypoint % 8);
+    if (color) {
+        buffer[x+((y>>3)*screensize_X)] |=  0 << (y % 8);
+    } else       {
+        buffer[x+((y>>3)*screensize_X)] |=  1 << (y % 8);
+    }
+
+
+}
+
+
+unsigned short SH1106::pixelread(int x, int y)
+{
+    // first check parameter
+    if((x >= screensize_X) || (y >= screensize_Y) || (x<0) || (y<0)) return 0;
+
+    //Buffer[(Xpoint + (Ypoint / 8) * sOLED_DIS.OLED_Dis_Column)] |= 1 << (Ypoint % 8);
+    //Buffer[(Xpoint + (Ypoint / 8) * sOLED_DIS.OLED_Dis_Column)] |= 0 << (Ypoint % 8);
+    if (buffer[x+((y>>3)*screensize_X)] &  1 << (y % 8) == 0)
+        return 0xFFFF ;  // pixel not set, White
+    else return 0; // pixel set, Black
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Inits/SH1106.h	Sun Apr 22 21:41:24 2018 +0000
@@ -0,0 +1,109 @@
+#ifndef MBED_SH1106_H
+#define MBED_SH1106_H
+
+#include "mbed.h"
+#include "LCD.h"
+
+/** Class for SH1106 display controller
+* to be copypasted and adapted for other controllers
+*/
+class SH1106 : public LCD
+{
+
+public:
+
+    /** Create a PAR display interface
+    * @param displayproto only supports PAR_8
+    * @param port GPIO port name to use
+    * @param CS pin connected to CS of display
+    * @param reset pin connected to RESET of display
+    * @param DC pin connected to data/command of display
+    * @param WR pin connected to SDI of display
+    * @param RD pin connected to RS of display
+    * @param name The name used by the parent class to access the interface
+    * @param LCDSIZE_X x size in pixel - optional
+    * @param LCDSIZE_Y y size in pixel - optional
+    */
+    SH1106(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char* name, unsigned int LCDSIZE_X = 128, unsigned  int LCDSIZE_Y = 64);
+
+    /** Create an SPI display interface
+    * @param displayproto SPI_8 or SPI_16
+    * @param Hz SPI speed in Hz
+    * @param mosi SPI pin
+    * @param miso SPI pin
+    * @param sclk SPI pin
+    * @param CS pin connected to CS of display
+    * @param reset pin connected to RESET of display
+    * @param DC pin connected to data/command of display
+    * @param name The name used by the parent class to access the interface
+    * @param LCDSIZE_X x size in pixel - optional
+    * @param LCDSIZE_Y y size in pixel - optional
+    */
+    SH1106(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char* name , unsigned int LCDSIZE_X = 128, unsigned  int LCDSIZE_Y = 64);
+
+    /** Create an I2C display interface
+    * @param displayproto I2C_
+    * @param Hz I2C speed in Hz
+    * @param address I2C address
+    * @param sda I2C pin
+    * @param scl I2C pin
+    * @param reset pin connected to RESET of display
+    * @param name The name used by the parent class to access the interface
+    * @param LCDSIZE_X x size in pixel - optional
+    * @param LCDSIZE_Y y size in pixel - optional
+    */
+    SH1106(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, PinName reset, const char* name , unsigned int LCDSIZE_X = 128, unsigned  int LCDSIZE_Y = 64);
+
+
+
+    /** set the contrast of the screen
+      * @note here overrided because of not standard value range
+      * @param o contrast 0-255
+      */
+    virtual void set_contrast(int o);
+
+    /** set automatc horizontal scroll mode
+     * @param l_r direction - left = 0, right = 1
+     * @param s_page start page
+     * @param e_page end page
+     * @param speed time between horizontal shift. 0 slow .. 7 fast
+     */
+
+    /** Framebuffer is used, it needs to be sent to LCD from time to time
+    */
+    virtual void copy_to_lcd();
+
+    /** clear the entire screen
+    */
+    virtual void cls();
+
+    /** Draw a pixel in the specified color.
+    * @param x is the horizontal offset to this pixel.
+    * @param y is the vertical offset to this pixel.
+    * @param color defines the color for the pixel.
+    */
+    virtual void pixel(int x, int y, unsigned short color);
+
+    /** Read pixel color at location
+    * @param x is the horizontal offset to this pixel.
+    * @param y is the vertical offset to this pixel.
+    * @returns 16bit color, 0000=Black(pixel set), FFFF=White(pixel clear).
+    */
+    virtual unsigned short pixelread(int x, int y);
+protected:
+
+
+    /** Init command sequence
+    */
+    void init();
+
+    /** set mirror mode
+      * @note here overriding the LCD class default one because of not standard commands
+      * @param mode NONE, X, Y, XY
+      */
+    virtual void mirrorXY(mirror_t mode);
+
+};
+
+
+#endif
\ No newline at end of file
--- a/Inits/SSD1306.cpp	Sun May 21 20:50:09 2017 +0000
+++ b/Inits/SSD1306.cpp	Sun Apr 22 21:41:24 2018 +0000
@@ -11,8 +11,8 @@
 /////////////////////////////////////////////////////////////////////////
 
 
-#define IC_X_SEGS    128 // UC1608 SEG has range 0-239 (239-0 if MX=1), check your datasheet, important for the orientation
-#define IC_Y_COMS    64  // UC1608 COM has range 0-127 (127-0 if MY=1), check your datasheet, important for the orientation
+#define IC_X_SEGS    132 // 132 SEG
+#define IC_Y_COMS    64  // 64  COM
 
 #define SSD1306_SETCONTRAST         0x81
 #define SSD1306_DISPLAYALLON_RESUME 0xA4
@@ -57,9 +57,10 @@
     locate(0,0);
 }
 
-SSD1306::SSD1306(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, const char* name , unsigned int LCDSIZE_X, unsigned  int LCDSIZE_Y)
-    : LCD(displayproto, Hz, address, sda, scl, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
+SSD1306::SSD1306(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, PinName reset, const char* name , unsigned int LCDSIZE_X, unsigned  int LCDSIZE_Y)
+    : LCD(displayproto, Hz, address, sda, scl,reset, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
 {
+    hw_reset();
     init();
     cls();
     set_orientation(1);
@@ -71,7 +72,7 @@
 void SSD1306::init()
 {
     /* Start Initial Sequence ----------------------------------------------------*/
-    
+ /* SSD1306   
   //  wr_cmd8(0xE2);   //  sw reset
     wait_ms(15);
     
@@ -114,12 +115,61 @@
     wr_cmd8(SSD1306_INVERTDISPLAY);
     
     wr_cmd8(SSD1306_DISPLAYON);
+*/    
+
+//SH1106    
+    wr_cmd8(0xAE);//--turn off oled panel
+    wr_cmd8(0x02);//---set low column address
+    wr_cmd8(0x10);//---set high column address
+    wr_cmd8(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
+    wr_cmd8(0x81);//--set contrast control register
+     wr_cmd8(0xA0);//--Set contrast
+    wr_cmd8(0xA8);//--set multiplex ratio(1 to 64)
+     wr_cmd8(0x3F);//--1/64 duty
+    wr_cmd8(0xD3);//-set display offset    Shift Mapping RAM Counter (0x00~0x3F)
+     wr_cmd8(0x00);//-not offset
+    wr_cmd8(0xd5);//--set display clock divide ratio/oscillator frequency
+     wr_cmd8(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
+    wr_cmd8(0xD9);//--set pre-charge period
+     wr_cmd8(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
+    wr_cmd8(0xDA);//--set com pins hardware configuration
+     wr_cmd8(0x12); // or 0x02
+    wr_cmd8(0xDB);//--set vcomh
+     wr_cmd8(0x40);//Set VCOM Deselect Level
+    //wr_cmd8(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02) // not on SH1106
+    wr_cmd8(0xA4);// Disable Entire Display On (0xa4/0xa5)
+    wr_cmd8(0xA6);// Disable Inverse Display On (0xa6/a7)
+
+    wr_cmd8(0xA1); // reverse order
+    //wr_cmd8(0xC0);//Set COM/Row Scan Direction
+    wr_cmd8(0xC8); //reverse direction    
+    wr_cmd8(0xAF);//--turn on oled panel
 }
 
 ////////////////////////////////////////////////////////////////////
 // functions that overrides the standard ones implemented in LCD.cpp
 ////////////////////////////////////////////////////////////////////
 
+void SSD1306::copy_to_lcd(void)
+{
+
+    for(int page=0; page<8 /*_LCDPAGES */; page++)
+    {
+        wr_cmd8(0x02);             // set column low nibble
+        wr_cmd8(0x10);             // set column hi  nibble
+        wr_cmd8(0xB0+page);        // set page
+        wr_grambuf(buffer16+(page*screensize_X>>1), /*screensize_X*/ 128>>1);   // send whole page pixels as shorts(16bit) not bytes!
+    }
+}
+
+void SSD1306::cls(void)
+{
+    unsigned short tmp = _background^0xFFFF;
+    //memset(buffer,tmp,/*screensize_X*_LCDPAGES*/ 128*64/8);  // clear display buffer
+    memset(buffer,0x00,screensize_X*(screensize_Y>>3));  // clear display buffer
+    copy_to_lcd();
+}
+
 void SSD1306::mirrorXY(mirror_t mode)
 {
     switch (mode)
@@ -146,9 +196,18 @@
     wr_cmd16(0x8100|(o&0xFF));
 }
 
-////////////////////////////////////////////////////////////////////
-// functions that overrides the standard ones implemented in LCD.cpp
-////////////////////////////////////////////////////////////////////
+void SSD1306::pixel(int x, int y, unsigned short color)
+{
+    // first check parameter
+    if((x >= screensize_X) || (y >= screensize_Y) || (x<0) || (y<0)) return;
+
+    //Buffer[(Xpoint + (Ypoint / 8) * sOLED_DIS.OLED_Dis_Column)] |= 1 << (Ypoint % 8);
+    //Buffer[(Xpoint + (Ypoint / 8) * sOLED_DIS.OLED_Dis_Column)] |= 0 << (Ypoint % 8);
+    if (color) {buffer[x+((y>>3)*screensize_X)] |=  0 << (y % 8);}
+    else       {buffer[x+((y>>3)*screensize_X)] |=  1 << (y % 8);}
+    
+
+}
 
 
 const uint8_t scroll_speed[8]={3,2,1,6,0,5,4,7};
--- a/Inits/SSD1306.h	Sun May 21 20:50:09 2017 +0000
+++ b/Inits/SSD1306.h	Sun Apr 22 21:41:24 2018 +0000
@@ -47,11 +47,12 @@
     * @param address I2C address
     * @param sda I2C pin
     * @param scl I2C pin
+    * @param reset pin connected to RESET of display    
     * @param name The name used by the parent class to access the interface
     * @param LCDSIZE_X x size in pixel - optional
     * @param LCDSIZE_Y y size in pixel - optional
     */ 
-    SSD1306(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, const char* name , unsigned int LCDSIZE_X = 128, unsigned  int LCDSIZE_Y = 64);
+    SSD1306(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, PinName reset, const char* name , unsigned int LCDSIZE_X = 128, unsigned  int LCDSIZE_Y = 64);
 
 
 
@@ -67,6 +68,22 @@
      * @param e_page end page
      * @param speed time between horizontal shift. 0 slow .. 7 fast
      */
+     
+    /** Framebuffer is used, it needs to be sent to LCD from time to time
+    */
+    virtual void copy_to_lcd();
+
+    /** clear the entire screen
+    */
+    virtual void cls();   
+
+    /** Draw a pixel in the specified color.
+    * @param x is the horizontal offset to this pixel.
+    * @param y is the vertical offset to this pixel.
+    * @param color defines the color for the pixel.
+    */    
+    virtual void pixel(int x, int y, unsigned short color);
+    
     void horizontal_scroll(int l_r,int s_page,int e_page,int speed);
 
     /** automatic horizontal + vertical scroll mode
--- a/Protocols/I2C_bus.cpp	Sun May 21 20:50:09 2017 +0000
+++ b/Protocols/I2C_bus.cpp	Sun Apr 22 21:41:24 2018 +0000
@@ -13,12 +13,13 @@
  
 #include "I2C_bus.h"
 
-I2C_bus::I2C_bus(int Hz, int address, PinName sda, PinName scl)
-    : _i2c(sda,scl)
+I2C_bus::I2C_bus(int Hz, int address, PinName sda, PinName scl, PinName reset)
+    : _i2c(sda,scl), _reset(reset)
 {
     _i2c.frequency(Hz);
     _address = address;
-    //hw_reset();    
+    _reset = 1;
+    hw_reset();    
 }
 
 void I2C_bus::wr_cmd8(unsigned char cmd)
@@ -30,7 +31,10 @@
 }
 void I2C_bus::wr_data8(unsigned char data)
 {
-    _i2c.write(data);    // write 8bit
+    char tmp[2];
+    tmp[0] = 0x40;  //data mode
+    tmp[1] = data;
+    _i2c.write(_address,tmp,2);    // write 
 }
 void I2C_bus::wr_cmd16(unsigned short cmd)
 {     
@@ -83,8 +87,9 @@
     _i2c.write(0x40);          // data continue
     while(lenght)
     {
-        _i2c.write((*data)>>8);    // write 8bit
-        _i2c.write((*data)&0xFF);    // write 8bit
+        //_i2c.write((*data)>>8);      // write high 8bit
+        _i2c.write((*data)&0xFF);    // write low 8bit
+        _i2c.write((*data)>>8);      // write high 8bit
         data++;
         lenght--;
     }
@@ -93,7 +98,11 @@
 
 void I2C_bus::hw_reset()
 {
-    
+    wait_ms(15);
+    _reset = 0;                        // display reset
+    wait_ms(2);
+    _reset = 1;                       // end reset
+    wait_ms(100);
 }
 void I2C_bus::BusEnable(bool enable)
 {
--- a/Protocols/I2C_bus.h	Sun May 21 20:50:09 2017 +0000
+++ b/Protocols/I2C_bus.h	Sun Apr 22 21:41:24 2018 +0000
@@ -16,8 +16,9 @@
     * @param I2C address
     * @param I2C pin sda
     * @param I2C pin scl
+    * @param reset pin connected to RESET of display
     */ 
-    I2C_bus(int Hz, int address,PinName sda, PinName scl);
+    I2C_bus(int Hz, int address,PinName sda, PinName scl, PinName reset=NC);
  
 protected:
    
@@ -132,6 +133,7 @@
 
     I2C _i2c;
     int _address;
+    DigitalOut _reset;
     
 };