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:
Sat May 20 21:12:05 2017 +0000
Parent:
33:f87f06292637
Child:
35:b8d3f1e68000
Commit message:
First working Version with 128x64LCD with ST7920-COntroller;

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/ST7920.cpp Show annotated file Show diff for this revision Revisions of this file
Inits/ST7920.h Show annotated file Show diff for this revision Revisions of this file
--- a/Display/LCD.cpp	Mon Feb 06 12:29:33 2017 +0000
+++ b/Display/LCD.cpp	Sat May 20 21:12:05 2017 +0000
@@ -290,8 +290,19 @@
     // first check parameter
     if((x >= screensize_X) || (y >= screensize_Y)) return;
 
-    if(color) buffer[(x + ((y>>3)*screensize_X))^1] &= ~(1 << (y&7));  // erase pixel
-    else buffer[(x + ((y>>3)*screensize_X))^1] |= (1 << (y&7));   //Black=0000, set pixel
+    //if(color) buffer[(x + ((y>>3)*screensize_X))^1] &= ~(1 << (y&7));   // erase pixel
+    //else      buffer[(x + ((y>>3)*screensize_X))^1] |=  (1 << (y&7));   //Black=0000, set pixel
+    
+    //if(color) buffer[(x + y*16)] &= ~(1 << (7-(x&7)));  // erase pixel
+    //else      buffer[(x + y*16)] |=  (1 << (7-(x&7)));   //Black=0000, set pixel
+    
+    if (color) {buffer[(x>>3)+(y*16)]&=  ~(1 << (7-(x&7)));}
+    else       {buffer[(x>>3)+(y*16)]|=   (1 << (7-(x&7)));}
+    
+    //buffer[0]=0xFF;
+    //buffer[16]=0xAA;
+    //buffer[1023]=0xFF;
+
 }
 unsigned short LCD::pixelread(int x, int y)
 {
--- a/Display/LCD.h	Mon Feb 06 12:29:33 2017 +0000
+++ b/Display/LCD.h	Sat May 20 21:12:05 2017 +0000
@@ -240,8 +240,6 @@
 private:
 
     Protocols* proto;
-    unsigned char *buffer;
-    unsigned short *buffer16;
     const int screensize_X;
     const int screensize_Y;
     const int _LCDPAGES;
@@ -261,6 +259,10 @@
     int win_y2;
     int orientation;
     bool useNOP;
+
+public:    
+    unsigned char *buffer;
+    unsigned short *buffer16;   
 };
 
 #endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Inits/ST7920.cpp	Sat May 20 21:12:05 2017 +0000
@@ -0,0 +1,272 @@
+/* mbed UniGraphic library - Device specific class
+* Copyright (c) 2015 Giuliano Dianda
+* Released under the MIT License: http://mbed.org/license/mit
+*/
+#include "Protocols.h"
+#include "ST7920.h"
+
+/*this is a quite standard config for ST7920 and similars*/
+
+//////////////////////////////////////////////////////////////////////////////////
+// display settings ///////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+//#define IC_X_SEGS    132 // ST7920 SEG has range 0-131 (131-0 if ADC=1), check your datasheet, important for the orientation
+//#define IC_Y_COMS    64  // ST7920 COM has range 0-63 (63-0 if SHL=1), check your datasheet, important for the orientation
+#define IC_X_SEGS    256 // ST7920 SEG has range 0-131 (131-0 if ADC=1), check your datasheet, important for the orientation
+#define IC_Y_COMS    32  // ST7920 COM has range 0-63 (63-0 if SHL=1), check your datasheet, important for the orientation
+
+// put in constructor
+//#define LCDSIZE_X       128 // display X pixels
+//#define LCDSIZE_Y       64  // display Y pixels
+
+
+
+ST7920::ST7920(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);
+}
+ST7920::ST7920(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char *name, unsigned int LCDSIZE_X, unsigned  int LCDSIZE_Y)
+    : LCD(displayproto, buspins, 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);
+}
+ST7920::ST7920(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);
+}
+
+//WriteInstructionRegister IR
+void ST7920::wir(unsigned char data)
+{
+
+    /*
+    Timing Diagram of Serial Mode Data Transfer on p.20
+
+    |-------------------|------------------------|------------------------|
+    |  Synchronizing    | 1-st Byte Higher data  |  2-nd Byte Lower data  |
+    |-------------------|------------------------|------------------------|
+    | 1 1 1 1 1 RW RS 0 | D7 D6 D5 D4  0  0  0  0| D3 D2 D1 D0  0  0  0  0|
+    |-------------------|------------------------|------------------------|
+    */
+
+    wr_data8(0xf8);        // Sync.    - 1  1  1  1  1  0  0  0  RW=0,RS=0
+    wr_data8(data & 0xf0); // HighData - D7 D6 D5 D4 0  0  0  0
+    wr_data8(data << 4);   // LowData  - D3 D2 D1 D0 0  0  0  0
+    if (data == 0x01) {
+        // Display Clear
+        wait_ms(1.6);
+    } else {
+        //everything else
+        wait_us(72);
+    }
+}
+
+//WriteDataRegister DR
+void ST7920::wdr(unsigned char data)
+{
+    wr_data8(0xfa);        // Sync.    - 1  1  1  1  1  0  1  0 RW=0 RS=1
+    wr_data8(data & 0xf0); // HighData - D7 D6 D5 D4 0  0  0  0
+    wr_data8(data << 4);   // LowData  - D3 D2 D1 D0 0  0  0  0
+    wait_us(72);
+}
+
+
+// reset and init the lcd controller
+// init sequence is manufacturer specific
+void ST7920::init()
+{
+    /* Start Initial Sequence ----------------------------------------------------*/
+    wait_ms(40);
+
+    //Function set [DL=1 8-bit interface; DL=0 4-bit interface;
+    //              RE=1: extended instruction; RE=0: basic instruction]
+    // RS RW DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
+    //  0  0   0   0   1  DL   X  RE   0   0
+    // DisplayClear
+    wir(0x01);
+    // ReturnHome
+    wir(0x02);
+    // FunctionSet: BasicIR
+    wir(0x30);
+    // FunctionSet: ExtendedIR
+    //wir(0x34);
+
+    //Function set [DL=1 8-bit interface; DL=0 4-bit interface;
+    //              RE=1: extended instruction; RE=0: basic instruction]
+    // RS RW DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
+    //  0  0   0   0   1  DL   X  RE   0   0
+    //
+    // ExtFunctionSet Display OFF
+    //wir(0x30);
+
+    // DisplayControl [D=1: Display ON; C=1: Cursor ON; B=1: Character Blink ON]
+    // RS RW DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
+    //  0  0   0   0   0   0   1   D   C   B
+    // DisplayControl: Display ON CharacterBlink ON Cursor=On
+    //wir(0x0f);
+    // DisplayControl: Display ON CharacterBlink OFF Cursor=Off
+    wir(0x0c);
+
+    // Display Clear
+    wir(0x01);
+    //wait_ms(10);
+    //Set cursor position and display shift when doing write or read operation
+    // RS RW DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
+    //  0  0   0   0   0   0   0   1 I/D   S
+    // EntryModeSet: Increase, Shift right
+    wir(0x06);
+
+}
+
+void ST7920::mirrorXY(mirror_t mode)
+{
+}
+
+void ST7920::cls(void)
+{
+    //DisplayClear
+    wir(0x01);
+    //ReturnHome
+    wir(0x02);
+    
+    memset(buffer,0x00,sizeX()*(sizeY()>>3));  // clear display buffer
+}
+
+void ST7920::copy_to_lcd(void)
+{
+    int i,j;
+
+    // Change to Extended InstructionSet
+    //FunctionSet: Extended
+    wir(0x36);
+    for(i=0; i<32; i++) { //32 Doppelzeilen
+        // SetGDRAM-Adress AC: 0
+        //Vertical-Adr
+        wir(0x80+i);
+        //Horizontal-Adr
+        wir(0x80);
+
+        //write 16 Double-Bytes of data
+        //upper part
+        for (j=0; j<8; j++) {
+            wdr(buffer[(i*16) + (j*2)]);
+            wdr(buffer[(i*16) + (j*2) +1]);
+            //if (i==0) {wdr(0xAA); wdr(0xAA);}else {wdr(0x00); wdr(0x00);};
+        }
+        //lower part
+        for (j=0; j<8; j++) {
+            wdr(buffer[(i*16)+512 + (j*2)]);
+            wdr(buffer[(i*16)+512 + (j*2) +1]);
+            //if (i==31) {wdr(0xAA); wdr(0xAA);}else {wdr(0x00); wdr(0x00);};
+        }
+        
+
+        /*
+        //obere Displayhälfte
+        wdr(0xFF);
+        wdr(0x00);
+        wdr(0x00);
+        wdr(0xAA);
+        wdr(0xF0);
+        wdr(0xAA);
+        wdr(0xF0);
+        wdr(0xAA);
+        wdr(0xF0);
+        wdr(0xAA);
+        wdr(0xF0);
+        wdr(0xAA);
+        wdr(0xF0);
+        wdr(0xAA);
+        wdr(0xFF);
+
+        //Zeile fertig
+
+        // untere Displayhälfte
+
+        wdr(0x00);
+        wdr(0x00);
+        wdr(0xFF);
+        wdr(0xFF);
+        wdr(0xAA);
+        wdr(0xF0);
+        wdr(0xAA);
+        wdr(0xF0);
+        wdr(0xAA);
+        wdr(0xF0);
+        wdr(0xAA);
+        wdr(0xF0);
+        wdr(0xAA);
+        wdr(0xF0);
+        wdr(0x00);
+        wdr(0xFF);
+        */
+    }
+
+    //back to BasicInstructionSet
+    wir(0x30);
+
+}
+
+void ST7920::set_contrast(int o)
+{
+}
+
+void ST7920::invert(unsigned char o)
+{
+}
+
+void ST7920::wr_grambuf(unsigned short* data, unsigned int lenght)
+{
+}
+
+void ST7920::wr_gram(unsigned short data)
+{
+}
+
+void ST7920::wr_gram(unsigned short data, unsigned int count)
+{
+}
+
+void ST7920::wr_data16(unsigned short data)
+{
+}
+
+void ST7920::wr_cmd16(unsigned short cmd)
+{
+}
+
+void ST7920::wr_cmd8(unsigned char cmd)
+{
+}
+
+unsigned short ST7920::rd_gram(bool convert)
+{
+    return(0);
+}
+
+unsigned int ST7920::rd_reg_data32(unsigned char reg)
+{
+    return(0);
+}
+
+unsigned int ST7920::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd)
+{
+    return(0);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Inits/ST7920.h	Sat May 20 21:12:05 2017 +0000
@@ -0,0 +1,104 @@
+#ifndef MBED_ST7920_H
+#define MBED_ST7920_H
+
+#include "mbed.h"
+#include "LCD.h"
+
+/** Class for ST7920 and similar display controllers
+* to be copypasted and adapted for other controllers
+*/
+class ST7920 : 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
+    */
+    ST7920(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char* name, unsigned int LCDSIZE_X = 132, unsigned  int LCDSIZE_Y = 64);
+
+    /** Create a BUS display interface
+    * @param displayproto only supports BUS_8
+    * @param buspins array of PinName to group as Bus
+    * @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
+    */
+    ST7920(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char* name, unsigned int LCDSIZE_X = 132, 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
+    */
+    ST7920(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char* name, unsigned int LCDSIZE_X = 132, unsigned  int LCDSIZE_Y = 64);
+
+
+
+protected:
+
+    //WriteInstructionRegister IR
+    void wir(unsigned char data);
+
+    //WriteDataRegister DR
+    void wdr(unsigned char data);
+
+    /** Init command sequence
+    */
+    void init();
+
+public:
+    /** Mirror
+    */
+    virtual void mirrorXY(mirror_t mode);
+
+    virtual void cls(void);
+
+    virtual void copy_to_lcd(void);
+    
+    virtual void set_contrast(int o);
+    
+    void invert(unsigned char o);
+    
+    virtual void wr_grambuf(unsigned short* data, unsigned int lenght);
+    
+    virtual void wr_gram(unsigned short data);
+    
+    virtual void wr_gram(unsigned short data, unsigned int count);
+    
+    virtual void wr_data16(unsigned short data);
+    
+    virtual void wr_cmd16(unsigned short cmd);
+    
+    virtual void wr_cmd8(unsigned char cmd);
+    
+    virtual unsigned short rd_gram(bool convert);
+    
+    virtual unsigned int rd_reg_data32(unsigned char reg);
+    
+    virtual unsigned int rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd);
+
+};
+#endif
\ No newline at end of file