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:
Geremia
Date:
Mon Feb 16 00:52:24 2015 +0000
Parent:
4:12ba0ecc2c1f
Child:
6:8356d48a07db
Commit message:
Added pixelread for TFTs

Changed in this revision

Display/TFT.cpp Show annotated file Show diff for this revision Revisions of this file
Display/TFT.h Show annotated file Show diff for this revision Revisions of this file
Graphics/GraphicsDisplay.h Show annotated file Show diff for this revision Revisions of this file
Protocols/PAR16.cpp Show annotated file Show diff for this revision Revisions of this file
Protocols/PAR16.h Show annotated file Show diff for this revision Revisions of this file
Protocols/PAR8.cpp Show annotated file Show diff for this revision Revisions of this file
Protocols/PAR8.h Show annotated file Show diff for this revision Revisions of this file
Protocols/Protocols.h Show annotated file Show diff for this revision Revisions of this file
Protocols/SPI16.cpp Show annotated file Show diff for this revision Revisions of this file
Protocols/SPI16.h Show annotated file Show diff for this revision Revisions of this file
Protocols/SPI8.cpp Show annotated file Show diff for this revision Revisions of this file
Protocols/SPI8.h Show annotated file Show diff for this revision Revisions of this file
--- a/Display/TFT.cpp	Sun Feb 15 20:06:07 2015 +0000
+++ b/Display/TFT.cpp	Mon Feb 16 00:52:24 2015 +0000
@@ -83,6 +83,14 @@
     {
         proto->wr_grambuf(data, lenght);
     }
+unsigned int TFT::rd_data32_wdummy()
+    {
+        return proto->rd_data32_wdummy();
+    }
+unsigned short TFT::rd_gram()
+    {
+        return (proto->rd_gram());
+    }
 //for TFT, just send data, position counters are in hw
 void TFT::window_pushpixel(unsigned short color)
 {
@@ -141,7 +149,6 @@
 {
     //ili9486 does not like truncated 2A/2B cmds, at least in par mode
     //setting only start column/page would speedup, but needs a windowmax() before, maybe implement later
-    //fixme for PAR_16: // cmd 2A/2B expects 8bit parameters
     wr_cmd8(0x2A);
     wr_data16(x);   //start column
     wr_data16(x+w-1);//end column
@@ -152,12 +159,33 @@
     
     wr_cmd8(0x2C);  //write mem, just send pixels color next
 }
+void TFT::window4read(int x, int y, int w, int h)
+{
+    wr_cmd8(0x2A);
+    wr_data16(x);   //start column
+    wr_data16(x+w-1);//end column
+
+    wr_cmd8(0x2B);
+    wr_data16(y);   //start page
+    wr_data16(y+h-1);//end page
+    
+    wr_cmd8(0x2E);  //read mem, just pixelread next
+}
 void TFT::pixel(int x, int y, unsigned short color)
 {
     window(x,y,1,1);
   //  proto->wr_gram(color);   // 2C expects 16bit parameters
     wr_gram(color);
 }
+unsigned short TFT::pixelread(int x, int y)
+{
+    unsigned short color;
+    window4read(x,y,1,1);
+  //  proto->wr_gram(color);   // 2C expects 16bit parameters
+    color = rd_gram();
+    if(mipistd) color = BGR2RGB(color); // in case, convert BGR to RGB (should depend on cmd36 bit3) but maybe is device specific
+    return color;
+}
 void TFT::cls (void)
 {
     WindowMax();
--- a/Display/TFT.h	Sun Feb 15 20:06:07 2015 +0000
+++ b/Display/TFT.h	Mon Feb 16 00:52:24 2015 +0000
@@ -50,6 +50,21 @@
     * @param h is the window height in pixels.
     */
     virtual void window(int x, int y, int w, int h);
+    
+    /** Read pixel color at current location
+    * @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 unsigned short pixelread(int x, int y);
+    
+    /** Set the window from which gram is read from. Autoincrements row/column
+    * @param x is the left edge in pixels.
+    * @param y is the top edge in pixels.
+    * @param w is the window width in pixels.
+    * @param h is the window height in pixels.
+    */
+    virtual void window4read(int x, int y, int w, int h);
 
     /** Push a single pixel into the window and increment position.
     * You must first call window() then push pixels.
@@ -154,6 +169,19 @@
     */   
     virtual void wr_grambuf(unsigned short* data, unsigned int lenght);
     
+    /** Read 4x8bit data from display controller (with dummy cycle)
+    *
+    * @returns data as uint
+    *
+    */ 
+    virtual unsigned int rd_data32_wdummy();
+    
+    /** Read 16bit pixeldata from display controller (with dummy cycle)
+    *
+    * @returns 16bit color
+    */ 
+    virtual unsigned short rd_gram();
+    
     /** HW reset sequence (without display init commands)   
     */
     void hw_reset();
--- a/Graphics/GraphicsDisplay.h	Sun Feb 15 20:06:07 2015 +0000
+++ b/Graphics/GraphicsDisplay.h	Mon Feb 16 00:52:24 2015 +0000
@@ -17,8 +17,7 @@
 #include "TextDisplay.h"
 #include "Terminal6x8.h"
 
-#define RGB(r,g,b)  (((r&0xF8)<<8)|((g&0xFC)<<3)|((b&0xF8)>>3)) //5 red | 6 green | 5 blue
-#define BGR2RGB(color) (((color&0x1F)<<11) | (color&0x7E0) | ((color&0xF800)>>11))
+
 
 /* some RGB color definitions                                                 */
 #define Black           0x0000      /*   0,   0,   0 */
--- a/Protocols/PAR16.cpp	Sun Feb 15 20:06:07 2015 +0000
+++ b/Protocols/PAR16.cpp	Mon Feb 16 00:52:24 2015 +0000
@@ -150,7 +150,73 @@
     _CS = 1;
 #endif
 }
-
+unsigned int PAR16::rd_data32_wdummy()
+{
+#ifdef USE_CS
+    _CS = 0;
+#endif
+    unsigned int r=0;
+    _DC = 1; // 1=data
+   _port.input();
+   
+    _RD = 0;
+    _port.read(); //dummy read
+    _RD = 1;
+    
+    _RD = 0;
+//    _RD = 0; // add wait
+    r |= (_port.read()&0xFF);
+    r <<= 8;
+    _RD = 1;
+    
+    _RD = 0;
+//    _RD = 0; // add wait
+    r |= (_port.read()&0xFF);
+    r <<= 8;
+    _RD = 1;
+    
+    _RD = 0;
+//    _RD = 0; // add wait
+    r |= (_port.read()&0xFF);
+    r <<= 8;
+    _RD = 1;
+    
+    _RD = 0;
+//    _RD = 0; // add wait
+    r |= (_port.read()&0xFF);
+    _RD = 1;
+    
+    _CS = 1; // force CS HIG to interupt the cmd in case was not supported
+#ifndef USE_CS //if CS is not used, force fixed LOW again
+    _CS = 0;
+#endif
+    _port.output();
+    return r;
+}
+unsigned short PAR16::rd_gram()
+{
+#ifdef USE_CS
+    _CS = 0;
+#endif
+    unsigned short r=0;
+    _DC = 1; // 1=data
+   _port.input();
+   
+    _RD = 0;
+    _port.read(); //dummy read
+    _RD = 1;
+    
+    _RD = 0;
+//    _RD = 0; // add wait
+    r |= _port.read();
+    _RD = 1;
+    
+#ifdef USE_CS
+    _CS = 1;
+#endif
+    _port.output();
+    return r;
+}
 void PAR16::hw_reset()
 {
     wait_ms(15);
--- a/Protocols/PAR16.h	Sun Feb 15 20:06:07 2015 +0000
+++ b/Protocols/PAR16.h	Mon Feb 16 00:52:24 2015 +0000
@@ -73,6 +73,19 @@
     */   
     virtual void wr_grambuf(unsigned short* data, unsigned int lenght);
     
+    /** Read 4x8bit data from display controller (with dummy cycle)
+    *
+    * @returns data as uint
+    *
+    */ 
+    virtual unsigned int rd_data32_wdummy();
+    
+    /** Read 16bit pixeldata from display controller (with dummy cycle)
+    *
+    * @returns 16bit color
+    */ 
+    virtual unsigned short rd_gram();
+    
     /** HW reset sequence (without display init commands)   
     */
     virtual void hw_reset();
--- a/Protocols/PAR8.cpp	Sun Feb 15 20:06:07 2015 +0000
+++ b/Protocols/PAR8.cpp	Mon Feb 16 00:52:24 2015 +0000
@@ -174,7 +174,79 @@
     _CS = 1;
 #endif
 }
-
+unsigned int PAR8::rd_data32_wdummy()
+{
+#ifdef USE_CS
+    _CS = 0;
+#endif
+    unsigned int r=0;
+    _DC = 1; // 1=data
+   _port.input();
+   
+    _RD = 0;
+    _port.read(); //dummy read
+    _RD = 1;
+    
+    _RD = 0;
+ //   _RD = 0; // add wait
+    r |= (_port.read()&0xFF);
+    r <<= 8;
+    _RD = 1;
+    
+    _RD = 0;
+ //   _RD = 0; // add wait
+    r |= (_port.read()&0xFF);
+    r <<= 8;
+    _RD = 1;
+    
+    _RD = 0;
+//    _RD = 0; // add wait
+    r |= (_port.read()&0xFF);
+    r <<= 8;
+    _RD = 1;
+    
+    _RD = 0;
+ //   _RD = 0; // add wait
+    r |= (_port.read()&0xFF);
+    _RD = 1;
+    
+    _CS = 1; // force CS HIG to interupt the cmd in case was not supported
+#ifndef USE_CS //if CS is not used, force fixed LOW again
+    _CS = 0;
+#endif
+    _port.output();
+    return r;
+}
+unsigned short PAR8::rd_gram()
+{
+#ifdef USE_CS
+    _CS = 0;
+#endif
+    unsigned short r=0;
+    _DC = 1; // 1=data
+   _port.input();
+   
+    _RD = 0;
+    _port.read(); //dummy read
+    _RD = 1;
+    
+    _RD = 0;
+//    _RD = 0; // add wait
+    r |= (_port.read()&0xFF);
+    r <<= 8;
+    _RD = 1;
+    
+    _RD = 0;
+//    _RD = 0; // add wait
+    r |= (_port.read()&0xFF);
+    _RD = 1;
+    
+#ifdef USE_CS
+    _CS = 1;
+#endif
+    _port.output();
+    return r;
+}
 void PAR8::hw_reset()
 {
     wait_ms(15);
--- a/Protocols/PAR8.h	Sun Feb 15 20:06:07 2015 +0000
+++ b/Protocols/PAR8.h	Mon Feb 16 00:52:24 2015 +0000
@@ -73,6 +73,19 @@
     */   
     virtual void wr_grambuf(unsigned short* data, unsigned int lenght);
     
+    /** Read 4x8bit data from display controller (with dummy cycle)
+    *
+    * @returns data as uint
+    *
+    */ 
+    virtual unsigned int rd_data32_wdummy();
+    
+    /** Read 16bit pixeldata from display controller (with dummy cycle)
+    *
+    * @returns 16bit color
+    */ 
+    virtual unsigned short rd_gram();
+    
     /** HW reset sequence (without display init commands)   
     */
     virtual void hw_reset();
--- a/Protocols/Protocols.h	Sun Feb 15 20:06:07 2015 +0000
+++ b/Protocols/Protocols.h	Mon Feb 16 00:52:24 2015 +0000
@@ -10,6 +10,9 @@
 
 #include "mbed.h"
 
+#define RGB18to16(r,g,b)  (((r&0xF8)<<8)|((g&0xFC)<<3)|((b&0xF8)>>3)) //5 red | 6 green | 5 blue
+#define BGR2RGB(color) (((color&0x1F)<<11) | (color&0x7E0) | ((color&0xF800)>>11))
+
 //#define USE_CS
 
 /** Protocol types
@@ -79,6 +82,19 @@
     */   
     virtual void wr_grambuf(unsigned short* data, unsigned int lenght) = 0;
     
+    /** Read 4x8bit data from display controller (with dummy cycle)
+    *
+    * @returns data as uint
+    *
+    */ 
+    virtual unsigned int rd_data32_wdummy() = 0;
+    
+    /** Read 16bit pixeldata from display controller (with dummy cycle)
+    *
+    * @returns 16bit color
+    */ 
+    virtual unsigned short rd_gram() = 0;
+    
     /** HW reset sequence (without display init commands)   
     */
     virtual void hw_reset() = 0;
--- a/Protocols/SPI16.cpp	Sun Feb 15 20:06:07 2015 +0000
+++ b/Protocols/SPI16.cpp	Mon Feb 16 00:52:24 2015 +0000
@@ -121,6 +121,45 @@
     _CS = 1;
 #endif
 }
+unsigned int SPI16::rd_data32_wdummy()
+{
+#ifdef USE_CS
+    _CS = 0;
+#endif
+    unsigned int r=0;
+    _DC.write(1);; // 1=data
+   
+    r |= _spi.write(0); // we get only 15bit valid, first bit was the dummy cycle
+    r <<= 16;
+    r |= _spi.write(0);
+    r <<= 1; // 32bits are aligned, now collecting bit_0
+    r |= (_spi.write(0) >> 15);
+    // we clocked 15 more bit so ILI waiting for 16th, we need to reset spi bus
+    _CS = 1; // force CS HIG to interupt the cmd
+#ifndef USE_CS //if CS is not used, force fixed LOW again
+    _CS = 0;
+#endif
+    return r;
+}
+unsigned short SPI16::rd_gram()
+{
+#ifdef USE_CS
+    _CS = 0;
+#endif
+    unsigned int r=0;
+    _DC.write(1); // 1=data
+    r |= _spi.write(0); // 16bit, whole first byte is dummy, second is red
+    r <<= 16;
+    r |= _spi.write(0);  
+_CS = 1; // force CS HIG to interupt the "read state"
+#ifndef USE_CS //if CS is not used, force fixed LOW again
+    _CS = 0;
+#endif
+    // gram is 18bit/pixel, if you set 16bit/pixel (cmd 3A), during writing the 16bits are expanded to 18bit
+    // during reading, you read the raw 18bit gram
+    r = RGB18to16((r&0xFC0000)>>16, (r&0xFC00)>>8, r&0xFC);// 18bit pixel, rrrrrr00_gggggg00_bbbbbb00, converted to 16bit
+    return (unsigned short)r;
+}
 void SPI16::hw_reset()
 {
     wait_ms(15);
--- a/Protocols/SPI16.h	Sun Feb 15 20:06:07 2015 +0000
+++ b/Protocols/SPI16.h	Mon Feb 16 00:52:24 2015 +0000
@@ -75,6 +75,19 @@
     */   
     virtual void wr_grambuf(unsigned short* data, unsigned int lenght);
     
+    /** Read 4x8bit data from display controller (with dummy cycle)
+    *
+    * @returns data as uint
+    *
+    */ 
+    virtual unsigned int rd_data32_wdummy();
+    
+    /** Read 16bit pixeldata from display controller (with dummy cycle)
+    *
+    * @returns 16bit color
+    */ 
+    virtual unsigned short rd_gram();
+    
     /** HW reset sequence (without display init commands)   
     */
     virtual void hw_reset();
--- a/Protocols/SPI8.cpp	Sun Feb 15 20:06:07 2015 +0000
+++ b/Protocols/SPI8.cpp	Mon Feb 16 00:52:24 2015 +0000
@@ -135,6 +135,52 @@
     _CS = 1;
 #endif
 }
+unsigned int SPI8::rd_data32_wdummy()
+{
+#ifdef USE_CS
+    _CS = 0;
+#endif
+    unsigned int r=0;
+    _DC.write(1); // 1=data
+   
+    r |= _spi.write(0); // we get only 7bit valid, first bit was the dummy cycle
+    r <<= 8;
+    r |= _spi.write(0);
+    r <<= 8;
+    r |= _spi.write(0);
+    r <<= 8;
+    r |= _spi.write(0);
+    r <<= 1; // 32bits are aligned, now collecting bit_0
+    r |= (_spi.write(0) >> 7);
+    // we clocked 7 more bit so ILI waiting for 8th, we need to reset spi bus
+    _CS = 1; // force CS HIG to interupt the cmd
+#ifndef USE_CS //if CS is not used, force fixed LOW again
+    _CS = 0;
+#endif
+    return r;
+}
+unsigned short SPI8::rd_gram()
+{
+#ifdef USE_CS
+    _CS = 0;
+#endif
+    unsigned int r=0;
+    _DC.write(1); // 1=data
+    _spi.write(0); // whole first byte is dummy
+    r |= _spi.write(0);
+    r <<= 8;
+    r |= _spi.write(0);
+    r <<= 8;
+    r |= _spi.write(0);  
+    _CS = 1; // force CS HIG to interupt the "read state"
+#ifndef USE_CS //if CS is not used, force fixed LOW again
+    _CS = 0;
+#endif
+    // gram is 18bit/pixel, if you set 16bit/pixel (cmd 3A), during writing the 16bits are expanded to 18bit
+    // during reading, you read the raw 18bit gram
+    r = RGB18to16((r&0xFC0000)>>16, (r&0xFC00)>>8, r&0xFC);// 18bit pixel, rrrrrr00_gggggg00_bbbbbb00, converted to 16bit
+    return (unsigned short)r;
+}
 void SPI8::hw_reset()
 {
     wait_ms(15);
--- a/Protocols/SPI8.h	Sun Feb 15 20:06:07 2015 +0000
+++ b/Protocols/SPI8.h	Mon Feb 16 00:52:24 2015 +0000
@@ -72,6 +72,19 @@
     */   
     virtual void wr_grambuf(unsigned short* data, unsigned int lenght);
     
+    /** Read 4x8bit data from display controller (with dummy cycle)
+    *
+    * @returns data as uint
+    *
+    */ 
+    virtual unsigned int rd_data32_wdummy();
+    
+    /** Read 16bit pixeldata from display controller (with dummy cycle)
+    *
+    * @returns 16bit color
+    */ 
+    virtual unsigned short rd_gram();
+    
     /** HW reset sequence (without display init commands)   
     */
     virtual void hw_reset();